mirror of
https://github.com/Lime3DS/Lime3DS.git
synced 2026-04-08 02:11:29 -06:00
updated secondary menu with functionality to switch external displays
Conflicts: src/android/app/src/main/java/org/citra/citra_emu/display/SecondaryDisplay.kt
This commit is contained in:
parent
7e78498b33
commit
d5c95ac3d8
@ -63,7 +63,7 @@ class EmulationActivity : AppCompatActivity() {
|
||||
private lateinit var binding: ActivityEmulationBinding
|
||||
private lateinit var screenAdjustmentUtil: ScreenAdjustmentUtil
|
||||
private lateinit var hotkeyUtility: HotkeyUtility
|
||||
private lateinit var secondaryDisplay: SecondaryDisplay
|
||||
lateinit var secondaryDisplay: SecondaryDisplay
|
||||
|
||||
private val onShutdown = Runnable {
|
||||
if (intent.getBooleanExtra("launched_from_shortcut", false)) {
|
||||
|
||||
@ -6,21 +6,28 @@ package org.citra.citra_emu.display
|
||||
|
||||
import android.app.Presentation
|
||||
import android.content.Context
|
||||
import android.graphics.SurfaceTexture
|
||||
import android.hardware.display.DisplayManager
|
||||
import android.hardware.display.VirtualDisplay
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.Display
|
||||
import android.view.MotionEvent
|
||||
import android.view.Surface
|
||||
import android.view.SurfaceHolder
|
||||
import android.view.SurfaceView
|
||||
import android.view.WindowManager
|
||||
import org.citra.citra_emu.features.settings.model.IntSetting
|
||||
import org.citra.citra_emu.display.SecondaryDisplayLayout
|
||||
import org.citra.citra_emu.NativeLibrary
|
||||
|
||||
class SecondaryDisplay(val context: Context) : DisplayManager.DisplayListener {
|
||||
private var pres: SecondaryDisplayPresentation? = null
|
||||
private val displayManager = context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
|
||||
private val vd: VirtualDisplay
|
||||
var preferredDisplayId = -1
|
||||
var currentDisplayId = -1
|
||||
|
||||
init {
|
||||
vd = displayManager.createVirtualDisplay(
|
||||
@ -42,24 +49,26 @@ class SecondaryDisplay(val context: Context) : DisplayManager.DisplayListener {
|
||||
NativeLibrary.secondarySurfaceDestroyed()
|
||||
}
|
||||
|
||||
private fun getExternalDisplay(context: Context): Display? {
|
||||
val dm = context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
|
||||
val currentDisplayId = context.display.displayId
|
||||
fun getSecondaryDisplays(context: Context): List<Display> {
|
||||
val dm = context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
|
||||
val currentDisplayId = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
context.display.displayId
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
(context.getSystemService(Context.WINDOW_SERVICE) as WindowManager)
|
||||
.defaultDisplay.displayId
|
||||
}
|
||||
val displays = dm.displays
|
||||
val presDisplays = dm.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
|
||||
val extDisplays = displays.filter {
|
||||
return displays.filter {
|
||||
val isPresentable = presDisplays.any { pd -> pd.displayId == it.displayId }
|
||||
val isNotDefaultOrPresentable = it.displayId != Display.DEFAULT_DISPLAY || isPresentable
|
||||
isNotDefaultOrPresentable &&
|
||||
val isNotDefaultOrPresentable = it != null && it.displayId != Display.DEFAULT_DISPLAY || isPresentable
|
||||
isNotDefaultOrPresentable &&
|
||||
it.displayId != currentDisplayId &&
|
||||
it.name != "HiddenDisplay" &&
|
||||
it.state != Display.STATE_OFF &&
|
||||
it.isValid
|
||||
}
|
||||
// if there is a display called Built-In Display or Built-In Screen, prioritize the OTHER screen
|
||||
val selected = extDisplays.firstOrNull { ! it.name.contains("Built",true) }
|
||||
?: extDisplays.firstOrNull()
|
||||
return selected
|
||||
}
|
||||
|
||||
fun updateDisplay() {
|
||||
@ -67,12 +76,20 @@ class SecondaryDisplay(val context: Context) : DisplayManager.DisplayListener {
|
||||
if (context is android.app.Activity && (context.isFinishing || context.isDestroyed)) {
|
||||
return
|
||||
}
|
||||
val displays = getSecondaryDisplays(context)
|
||||
val display = if (displays.isEmpty() ||
|
||||
IntSetting.SECONDARY_DISPLAY_LAYOUT.int == SecondaryDisplayLayout.NONE.int
|
||||
) {
|
||||
currentDisplayId = -1
|
||||
vd.display
|
||||
} else if (preferredDisplayId >=0 && displays.any { it.displayId == preferredDisplayId }) {
|
||||
|
||||
// decide if we are going to the external display or the internal one
|
||||
var display = getExternalDisplay(context)
|
||||
if (display == null ||
|
||||
IntSetting.SECONDARY_DISPLAY_LAYOUT.int == SecondaryDisplayLayout.NONE.int) {
|
||||
display = vd.display
|
||||
currentDisplayId = preferredDisplayId
|
||||
displays.first { it.displayId == preferredDisplayId }
|
||||
} else {
|
||||
//TODO: re-enable the filter of "built-in displays" odin style to pick default
|
||||
currentDisplayId = displays[0].displayId
|
||||
displays[0]
|
||||
}
|
||||
|
||||
// if our presentation is already on the right display, ignore
|
||||
@ -137,16 +154,18 @@ class SecondaryDisplayPresentation(
|
||||
surfaceView = SurfaceView(context)
|
||||
surfaceView.holder.addCallback(object : SurfaceHolder.Callback {
|
||||
override fun surfaceCreated(holder: SurfaceHolder) {
|
||||
|
||||
Log.d("SecondaryDisplay", "Surface created")
|
||||
}
|
||||
|
||||
override fun surfaceChanged(
|
||||
holder: SurfaceHolder, format: Int, width: Int, height: Int
|
||||
) {
|
||||
Log.d("SecondaryDisplay", "Surface changed: ${width}x${height}")
|
||||
parent.updateSurface()
|
||||
}
|
||||
|
||||
override fun surfaceDestroyed(holder: SurfaceHolder) {
|
||||
Log.d("SecondaryDisplay", "Surface destroyed")
|
||||
parent.destroySurface()
|
||||
}
|
||||
})
|
||||
|
||||
@ -70,7 +70,6 @@ import org.citra.citra_emu.display.ScreenLayout
|
||||
import org.citra.citra_emu.display.SecondaryDisplayLayout
|
||||
import org.citra.citra_emu.features.settings.model.BooleanSetting
|
||||
import org.citra.citra_emu.features.settings.model.IntSetting
|
||||
import org.citra.citra_emu.features.settings.model.Settings
|
||||
import org.citra.citra_emu.features.settings.model.SettingsViewModel
|
||||
import org.citra.citra_emu.features.settings.ui.SettingsActivity
|
||||
import org.citra.citra_emu.features.settings.utils.SettingsFile
|
||||
@ -108,8 +107,8 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
||||
private val settingsViewModel: SettingsViewModel by viewModels()
|
||||
private val settings get() = settingsViewModel.settings
|
||||
|
||||
private val onPause = Runnable{ togglePause() }
|
||||
private val onShutdown = Runnable{ emulationState.stop() }
|
||||
private val onPause = Runnable { togglePause() }
|
||||
private val onShutdown = Runnable { emulationState.stop() }
|
||||
|
||||
// Only used if a game is passed through intent on google play variant
|
||||
private var gameFd: Int? = null
|
||||
@ -182,7 +181,8 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
||||
retainInstance = true
|
||||
emulationState = EmulationState(game.path)
|
||||
emulationActivity = requireActivity() as EmulationActivity
|
||||
screenAdjustmentUtil = ScreenAdjustmentUtil(requireContext(), requireActivity().windowManager, settings)
|
||||
screenAdjustmentUtil =
|
||||
ScreenAdjustmentUtil(requireContext(), requireActivity().windowManager, settings)
|
||||
EmulationLifecycleUtil.addPauseResumeHook(onPause)
|
||||
EmulationLifecycleUtil.addShutdownHook(onShutdown)
|
||||
}
|
||||
@ -624,17 +624,21 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
||||
}
|
||||
|
||||
add(text).setEnabled(enableClick).setOnMenuItemClickListener {
|
||||
if(isSaving) {
|
||||
if (isSaving) {
|
||||
NativeLibrary.saveState(slot)
|
||||
Toast.makeText(context,
|
||||
Toast.makeText(
|
||||
context,
|
||||
getString(R.string.saving),
|
||||
Toast.LENGTH_SHORT).show()
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
} else {
|
||||
NativeLibrary.loadState(slot)
|
||||
binding.drawerLayout.close()
|
||||
Toast.makeText(context,
|
||||
Toast.makeText(
|
||||
context,
|
||||
getString(R.string.loading),
|
||||
Toast.LENGTH_SHORT).show()
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
true
|
||||
}
|
||||
@ -643,9 +647,9 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
||||
|
||||
savestates?.forEach {
|
||||
var enableClick = true
|
||||
val text = if(it.slot == NativeLibrary.QUICKSAVE_SLOT) {
|
||||
val text = if (it.slot == NativeLibrary.QUICKSAVE_SLOT) {
|
||||
getString(R.string.emulation_occupied_quicksave_slot, it.time)
|
||||
} else{
|
||||
} else {
|
||||
getString(R.string.emulation_occupied_state_slot, it.slot, it.time)
|
||||
}
|
||||
popupMenu.menu.getItem(it.slot).setTitle(text).setEnabled(enableClick)
|
||||
@ -727,8 +731,12 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
||||
}
|
||||
|
||||
R.id.menu_performance_overlay_show -> {
|
||||
BooleanSetting.PERF_OVERLAY_ENABLE.boolean = !BooleanSetting.PERF_OVERLAY_ENABLE.boolean
|
||||
settings.saveSetting(BooleanSetting.PERF_OVERLAY_ENABLE, SettingsFile.FILE_NAME_CONFIG)
|
||||
BooleanSetting.PERF_OVERLAY_ENABLE.boolean =
|
||||
!BooleanSetting.PERF_OVERLAY_ENABLE.boolean
|
||||
settings.saveSetting(
|
||||
BooleanSetting.PERF_OVERLAY_ENABLE,
|
||||
SettingsFile.FILE_NAME_CONFIG
|
||||
)
|
||||
updateShowPerformanceOverlay()
|
||||
true
|
||||
}
|
||||
@ -999,10 +1007,13 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
||||
val layoutOptionMenuItem = when (IntSetting.PORTRAIT_SCREEN_LAYOUT.int) {
|
||||
PortraitScreenLayout.TOP_FULL_WIDTH.int ->
|
||||
R.id.menu_portrait_layout_top_full
|
||||
|
||||
PortraitScreenLayout.ORIGINAL.int ->
|
||||
R.id.menu_portrait_layout_original
|
||||
|
||||
PortraitScreenLayout.CUSTOM_PORTRAIT_LAYOUT.int ->
|
||||
R.id.menu_portrait_layout_custom
|
||||
|
||||
else ->
|
||||
R.id.menu_portrait_layout_top_full
|
||||
|
||||
@ -1044,35 +1055,82 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
||||
requireContext(),
|
||||
binding.inGameMenu.findViewById(R.id.menu_secondary_screen_layout)
|
||||
)
|
||||
|
||||
popupMenu.menuInflater.inflate(R.menu.menu_secondary_screen_layout, popupMenu.menu)
|
||||
|
||||
val layoutOptionMenuItem = when (IntSetting.SECONDARY_DISPLAY_LAYOUT.int) {
|
||||
SecondaryDisplayLayout.NONE.int ->
|
||||
R.id.menu_secondary_layout_none
|
||||
var selectedLayout = IntSetting.SECONDARY_DISPLAY_LAYOUT.int
|
||||
val chooserMenu = popupMenu.menu.findItem(R.id.menu_secondary_choose)
|
||||
val enableSecondaryCheckbox = popupMenu.menu.findItem(R.id.menu_secondary_layout_none)
|
||||
chooserMenu?.subMenu?.removeGroup(R.id.menu_secondary_management_display_group)
|
||||
val displays =
|
||||
emulationActivity.secondaryDisplay.getSecondaryDisplays(emulationActivity)
|
||||
|
||||
if (selectedLayout == SecondaryDisplayLayout.NONE.int) {
|
||||
enableSecondaryCheckbox.isChecked = false
|
||||
chooserMenu.isVisible = false
|
||||
popupMenu.menu.setGroupEnabled(R.id.menu_secondary_layout_group, false)
|
||||
selectedLayout = SecondaryDisplayLayout.REVERSE_PRIMARY.int
|
||||
} else {
|
||||
popupMenu.menu.setGroupEnabled(R.id.menu_secondary_layout_group, true)
|
||||
chooserMenu.isVisible = (displays.size > 1)
|
||||
}
|
||||
val layoutOptionMenuItem = when (selectedLayout) {
|
||||
SecondaryDisplayLayout.NONE.int -> {
|
||||
R.id.menu_secondary_layout_reverse_primary
|
||||
}
|
||||
|
||||
SecondaryDisplayLayout.REVERSE_PRIMARY.int ->
|
||||
R.id.menu_secondary_layout_reverse_primary
|
||||
|
||||
SecondaryDisplayLayout.TOP_SCREEN.int ->
|
||||
R.id.menu_secondary_layout_top
|
||||
|
||||
SecondaryDisplayLayout.BOTTOM_SCREEN.int ->
|
||||
R.id.menu_secondary_layout_bottom
|
||||
|
||||
SecondaryDisplayLayout.HYBRID.int ->
|
||||
R.id.menu_secondary_layout_hybrid
|
||||
|
||||
SecondaryDisplayLayout.LARGE_SCREEN.int ->
|
||||
R.id.menu_secondary_layout_largescreen
|
||||
|
||||
SecondaryDisplayLayout.ORIGINAL.int ->
|
||||
R.id.menu_secondary_layout_original
|
||||
|
||||
else ->
|
||||
R.id.menu_secondary_layout_side_by_side
|
||||
|
||||
}
|
||||
popupMenu.menu.findItem(layoutOptionMenuItem).isChecked = true
|
||||
|
||||
popupMenu.menu.findItem(layoutOptionMenuItem).setChecked(true)
|
||||
if (displays.size > 1 && selectedLayout != SecondaryDisplayLayout.NONE.int) {
|
||||
val current = emulationActivity.secondaryDisplay.currentDisplayId
|
||||
chooserMenu.isVisible = true
|
||||
displays.forEachIndexed { index, display ->
|
||||
chooserMenu?.subMenu?.add(
|
||||
R.id.menu_secondary_management_display_group,
|
||||
display.displayId,
|
||||
index,
|
||||
"Display ${display.displayId} - ${display.name}"
|
||||
)?.apply {
|
||||
isChecked = (display.displayId == current)
|
||||
}
|
||||
}
|
||||
chooserMenu.subMenu?.setGroupCheckable(
|
||||
R.id.menu_secondary_management_display_group,
|
||||
true,
|
||||
true
|
||||
)
|
||||
}
|
||||
|
||||
popupMenu.setOnMenuItemClickListener {
|
||||
when (it.itemId) {
|
||||
R.id.menu_secondary_layout_none -> {
|
||||
screenAdjustmentUtil.changeSecondaryOrientation(SecondaryDisplayLayout.NONE.int)
|
||||
if (!it.isChecked) {
|
||||
screenAdjustmentUtil.changeSecondaryOrientation(selectedLayout)
|
||||
} else {
|
||||
screenAdjustmentUtil.changeSecondaryOrientation(SecondaryDisplayLayout.NONE.int)
|
||||
}
|
||||
emulationActivity.secondaryDisplay.updateDisplay()
|
||||
showSecondaryScreenLayoutMenu() // reopen menu to get new behaviors
|
||||
true
|
||||
}
|
||||
|
||||
@ -1080,38 +1138,52 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
||||
screenAdjustmentUtil.changeSecondaryOrientation(SecondaryDisplayLayout.REVERSE_PRIMARY.int)
|
||||
true
|
||||
}
|
||||
|
||||
R.id.menu_secondary_layout_top -> {
|
||||
screenAdjustmentUtil.changeSecondaryOrientation(SecondaryDisplayLayout.TOP_SCREEN.int)
|
||||
true
|
||||
}
|
||||
|
||||
R.id.menu_secondary_layout_bottom -> {
|
||||
screenAdjustmentUtil.changeSecondaryOrientation(SecondaryDisplayLayout.BOTTOM_SCREEN.int)
|
||||
true
|
||||
}
|
||||
|
||||
R.id.menu_secondary_layout_side_by_side -> {
|
||||
screenAdjustmentUtil.changeSecondaryOrientation(SecondaryDisplayLayout.SIDE_BY_SIDE.int)
|
||||
true
|
||||
}
|
||||
|
||||
R.id.menu_secondary_layout_hybrid -> {
|
||||
screenAdjustmentUtil.changeSecondaryOrientation(SecondaryDisplayLayout.HYBRID.int)
|
||||
true
|
||||
}
|
||||
|
||||
R.id.menu_secondary_layout_original -> {
|
||||
screenAdjustmentUtil.changeSecondaryOrientation(SecondaryDisplayLayout.ORIGINAL.int)
|
||||
true
|
||||
}
|
||||
|
||||
R.id.menu_secondary_layout_largescreen -> {
|
||||
screenAdjustmentUtil.changeSecondaryOrientation(SecondaryDisplayLayout.LARGE_SCREEN.int)
|
||||
true
|
||||
}
|
||||
|
||||
R.id.menu_secondary_choose -> {
|
||||
true
|
||||
}
|
||||
|
||||
else -> true
|
||||
else -> {
|
||||
// display ID selection
|
||||
emulationActivity.secondaryDisplay.preferredDisplayId = it.itemId
|
||||
emulationActivity.secondaryDisplay.updateDisplay()
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
popupMenu.show()
|
||||
}
|
||||
|
||||
private fun editControlsPlacement() {
|
||||
if (binding.surfaceInputOverlay.isInEditMode) {
|
||||
binding.doneControlConfig.visibility = View.GONE
|
||||
@ -1168,7 +1240,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
||||
slider.valueFrom = 0f
|
||||
slider.value = preferences.getInt(target, 50).toFloat()
|
||||
textValue.setText((slider.value + 50).toInt().toString())
|
||||
textValue.addTextChangedListener( object : TextWatcher {
|
||||
textValue.addTextChangedListener(object : TextWatcher {
|
||||
override fun afterTextChanged(s: Editable) {
|
||||
val value = s.toString().toIntOrNull()
|
||||
if (value == null || value < 50 || value > 150) {
|
||||
@ -1178,6 +1250,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
||||
slider.value = value.toFloat() - 50
|
||||
}
|
||||
}
|
||||
|
||||
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
})
|
||||
@ -1218,7 +1291,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
||||
slider.value = preferences.getInt("controlOpacity", 50).toFloat()
|
||||
textValue.setText(slider.value.toInt().toString())
|
||||
|
||||
textValue.addTextChangedListener( object : TextWatcher {
|
||||
textValue.addTextChangedListener(object : TextWatcher {
|
||||
override fun afterTextChanged(s: Editable) {
|
||||
val value = s.toString().toIntOrNull()
|
||||
if (value == null || value < slider.valueFrom || value > slider.valueTo) {
|
||||
@ -1228,6 +1301,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
||||
slider.value = value.toFloat()
|
||||
}
|
||||
}
|
||||
|
||||
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
})
|
||||
@ -1236,11 +1310,11 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
||||
slider.addOnChangeListener { _: Slider, value: Float, _: Boolean ->
|
||||
|
||||
if (textValue.text.toString() != slider.value.toInt().toString()) {
|
||||
textValue.setText(slider.value.toInt().toString())
|
||||
textValue.setSelection(textValue.length())
|
||||
setControlOpacity(slider.value.toInt())
|
||||
}
|
||||
textValue.setText(slider.value.toInt().toString())
|
||||
textValue.setSelection(textValue.length())
|
||||
setControlOpacity(slider.value.toInt())
|
||||
}
|
||||
}
|
||||
|
||||
textInput.suffixText = "%"
|
||||
}
|
||||
@ -1425,7 +1499,8 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
||||
}
|
||||
|
||||
private fun updateStatsPosition(position: Int) {
|
||||
val params = binding.performanceOverlayShowText.layoutParams as CoordinatorLayout.LayoutParams
|
||||
val params =
|
||||
binding.performanceOverlayShowText.layoutParams as CoordinatorLayout.LayoutParams
|
||||
val padding = (20 * resources.displayMetrics.density).toInt() // 20dp
|
||||
params.setMargins(padding, 0, padding, 0)
|
||||
|
||||
@ -1460,7 +1535,8 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
||||
|
||||
private fun getBatteryTemperature(): Float {
|
||||
try {
|
||||
val batteryIntent = requireContext().registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
|
||||
val batteryIntent =
|
||||
requireContext().registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
|
||||
// Temperature in tenths of a degree Celsius
|
||||
val temperature = batteryIntent?.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0) ?: 0
|
||||
// Convert to degrees Celsius
|
||||
|
||||
@ -157,7 +157,7 @@ void Config::ReadValues() {
|
||||
ReadSetting("Renderer", Settings::values.turbo_limit);
|
||||
// Workaround to map Android setting for enabling the frame limiter to the format Citra expects
|
||||
if (android_config->GetBoolean("Renderer", "use_frame_limit", true)) {
|
||||
ReadSetting("Renderer", Settings::values.frame_limit);
|
||||
ReadSetting("Renderer", Settings::values.frame_limit);
|
||||
} else {
|
||||
Settings::values.frame_limit = 0;
|
||||
}
|
||||
|
||||
@ -18,10 +18,13 @@
|
||||
#include "video_core/renderer_base.h"
|
||||
|
||||
bool EmuWindow_Android::OnSurfaceChanged(ANativeWindow* surface) {
|
||||
if (render_window == surface) {
|
||||
int w = ANativeWindow_getWidth(surface);
|
||||
int h = ANativeWindow_getHeight(surface);
|
||||
if (render_window == surface && w == window_width && h == window_height) {
|
||||
return false;
|
||||
}
|
||||
|
||||
window_width = w;
|
||||
window_height = h;
|
||||
render_window = surface;
|
||||
window_info.type = Frontend::WindowSystemType::Android;
|
||||
window_info.render_surface = surface;
|
||||
@ -47,15 +50,9 @@ void EmuWindow_Android::OnTouchMoved(int x, int y) {
|
||||
}
|
||||
|
||||
void EmuWindow_Android::OnFramebufferSizeChanged() {
|
||||
const bool is_portrait_mode{IsPortraitMode()};
|
||||
const bool is_portrait_mode = IsPortraitMode() && !is_secondary;
|
||||
|
||||
const int bigger{window_width > window_height ? window_width : window_height};
|
||||
const int smaller{window_width < window_height ? window_width : window_height};
|
||||
if (is_portrait_mode && !is_secondary) {
|
||||
UpdateCurrentFramebufferLayout(smaller, bigger, is_portrait_mode);
|
||||
} else {
|
||||
UpdateCurrentFramebufferLayout(bigger, smaller, is_portrait_mode);
|
||||
}
|
||||
UpdateCurrentFramebufferLayout(window_width,window_height,is_portrait_mode);
|
||||
}
|
||||
|
||||
EmuWindow_Android::EmuWindow_Android(ANativeWindow* surface, bool is_secondary)
|
||||
|
||||
@ -391,6 +391,11 @@ void Java_org_citra_citra_1emu_NativeLibrary_secondarySurfaceChanged(JNIEnv* env
|
||||
if (secondary_window) {
|
||||
// Second window already created, so update it
|
||||
notify = secondary_window->OnSurfaceChanged(s_secondary_surface);
|
||||
|
||||
// Log the dimensions for debugging
|
||||
int32_t width = ANativeWindow_getWidth(s_secondary_surface);
|
||||
int32_t height = ANativeWindow_getHeight(s_secondary_surface);
|
||||
LOG_INFO(Frontend, "Secondary Surface changed to {}x{}", width, height);
|
||||
} else {
|
||||
LOG_WARNING(Frontend,
|
||||
"Second Window does not exist in native.cpp but surface changed. Ignoring.");
|
||||
|
||||
@ -35,7 +35,7 @@
|
||||
<item
|
||||
android:id="@+id/menu_secondary_screen_layout"
|
||||
android:icon="@drawable/ic_secondary_fit_screen"
|
||||
android:title="@string/emulation_switch_secondary_layout" />
|
||||
android:title="@string/emulation_secondary_display_management" />
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_swap_screens"
|
||||
|
||||
@ -1,12 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<group android:checkableBehavior="single">
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_secondary_layout_none"
|
||||
android:title="@string/emulation_secondary_display_default" />
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_secondary_layout_none"
|
||||
android:title="@string/emulation_secondary_display_enable"
|
||||
android:checkable="true"
|
||||
android:checked="true"/>
|
||||
<item
|
||||
android:id="@+id/menu_secondary_choose"
|
||||
android:title="@string/emulation_select_secondary_display">
|
||||
<menu>
|
||||
<group
|
||||
android:id="@+id/menu_secondary_management_display_group"
|
||||
android:checkableBehavior="single">
|
||||
</group>
|
||||
</menu>
|
||||
</item>
|
||||
<item
|
||||
android:title="@string/preferences_layout"
|
||||
android:enabled="false"/>
|
||||
<group
|
||||
android:checkableBehavior="single"
|
||||
android:id="@+id/menu_secondary_layout_group">
|
||||
<item
|
||||
android:id="@+id/menu_secondary_layout_reverse_primary"
|
||||
android:title="@string/emulation_secondary_display_reverse_primary" />
|
||||
|
||||
@ -467,7 +467,10 @@
|
||||
<string name="emulation_aspect_ratio">Aspect Ratio</string>
|
||||
<string name="emulation_switch_screen_layout">Landscape Screen Layout</string>
|
||||
<string name="emulation_switch_portrait_layout">Portrait Screen Layout</string>
|
||||
<string name="emulation_secondary_display_enable">Enable Secondary Display</string>
|
||||
<string name="emulation_switch_secondary_layout">Secondary Display Layout</string>
|
||||
<string name="emulation_secondary_display_management">Secondary Display</string>
|
||||
<string name="emulation_select_secondary_display">Choose Display</string>
|
||||
<string name="emulation_switch_secondary_layout_description">The layout used by a connected secondary screen, wired or wireless (Chromecast, Miracast)</string>
|
||||
<string name="emulation_screen_layout_largescreen">Large Screen</string>
|
||||
<string name="emulation_screen_layout_portrait">Portrait</string>
|
||||
@ -476,7 +479,7 @@
|
||||
<string name="emulation_screen_layout_hybrid">Hybrid Screens</string>
|
||||
<string name="emulation_screen_layout_original">Original</string>
|
||||
<string name="emulation_portrait_layout_top_full">Default</string>
|
||||
<string name="emulation_secondary_display_default">System Default (mirror)</string>
|
||||
<string name="emulation_secondary_display_default">None (system default)</string>
|
||||
<string name="emulation_secondary_display_reverse_primary">Opposite of Primary Display</string>
|
||||
<string name="emulation_screen_layout_custom">Custom Layout</string>
|
||||
<string name="bg_color">Background Color</string>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user