diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 9e11302fd0..221c7732e9 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -20,7 +20,7 @@ jobs:
- { name: win-x64, os: windows-latest, zip_os_name: win_x64 }
- { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
- { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
- - { name: osx-x64, os: macOS-latest, zip_os_name: osx_x64 }
+ - { name: osx-x64, os: macos-13, zip_os_name: osx_x64 }
fail-fast: false
steps:
@@ -41,12 +41,12 @@ jobs:
- name: Change config filename
run: sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/PRConfig\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
shell: bash
- if: github.event_name == 'pull_request' && matrix.platform.os != 'macOS-latest'
+ if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13'
- name: Change config filename for macOS
run: sed -r -i '' 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/PRConfig\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
shell: bash
- if: github.event_name == 'pull_request' && matrix.platform.os == 'macOS-latest'
+ if: github.event_name == 'pull_request' && matrix.platform.os == 'macos-13'
- name: Build
run: dotnet build -c "${{ matrix.configuration }}" -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER
@@ -61,15 +61,15 @@ jobs:
- name: Publish Ryujinx
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx --self-contained true
- if: github.event_name == 'pull_request' && matrix.platform.os != 'macOS-latest'
+ if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13'
- name: Publish Ryujinx.Headless.SDL2
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish_sdl2_headless -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx.Headless.SDL2 --self-contained true
- if: github.event_name == 'pull_request' && matrix.platform.os != 'macOS-latest'
+ if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13'
- name: Publish Ryujinx.Gtk3
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish_gtk -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx.Gtk3 --self-contained true
- if: github.event_name == 'pull_request' && matrix.platform.os != 'macOS-latest'
+ if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13'
- name: Set executable bit
run: |
@@ -83,21 +83,21 @@ jobs:
with:
name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.platform.zip_os_name }}
path: publish
- if: github.event_name == 'pull_request' && matrix.platform.os != 'macOS-latest'
+ if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13'
- name: Upload Ryujinx.Headless.SDL2 artifact
uses: actions/upload-artifact@v4
with:
name: sdl2-ryujinx-headless-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.platform.zip_os_name }}
path: publish_sdl2_headless
- if: github.event_name == 'pull_request' && matrix.platform.os != 'macOS-latest'
+ if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13'
- name: Upload Ryujinx.Gtk3 artifact
uses: actions/upload-artifact@v4
with:
name: gtk-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.platform.zip_os_name }}
path: publish_gtk
- if: github.event_name == 'pull_request' && matrix.platform.os != 'macOS-latest'
+ if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13'
build_macos:
name: macOS Universal (${{ matrix.configuration }})
diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/HidDevices/MouseDevice.cs b/src/Ryujinx.HLE/HOS/Services/Hid/HidDevices/MouseDevice.cs
index b2dd3feaf0..2e62d206b5 100644
--- a/src/Ryujinx.HLE/HOS/Services/Hid/HidDevices/MouseDevice.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Hid/HidDevices/MouseDevice.cs
@@ -23,8 +23,8 @@ namespace Ryujinx.HLE.HOS.Services.Hid
newState.Buttons = (MouseButton)buttons;
newState.X = mouseX;
newState.Y = mouseY;
- newState.DeltaX = mouseX - previousEntry.DeltaX;
- newState.DeltaY = mouseY - previousEntry.DeltaY;
+ newState.DeltaX = mouseX - previousEntry.X;
+ newState.DeltaY = mouseY - previousEntry.Y;
newState.WheelDeltaX = scrollX;
newState.WheelDeltaY = scrollY;
newState.Attributes = connected ? MouseAttribute.IsConnected : MouseAttribute.None;
diff --git a/src/Ryujinx.Input/HLE/NpadController.cs b/src/Ryujinx.Input/HLE/NpadController.cs
index cde20f5d07..3807452838 100644
--- a/src/Ryujinx.Input/HLE/NpadController.cs
+++ b/src/Ryujinx.Input/HLE/NpadController.cs
@@ -487,38 +487,35 @@ namespace Ryujinx.Input.HLE
return value;
}
- public KeyboardInput? GetHLEKeyboardInput()
+ public static KeyboardInput GetHLEKeyboardInput(IGamepadDriver KeyboardDriver)
{
- if (_gamepad is IKeyboard keyboard)
+ var keyboard = KeyboardDriver.GetGamepad("0") as IKeyboard;
+
+ KeyboardStateSnapshot keyboardState = keyboard.GetKeyboardStateSnapshot();
+
+ KeyboardInput hidKeyboard = new()
{
- KeyboardStateSnapshot keyboardState = keyboard.GetKeyboardStateSnapshot();
+ Modifier = 0,
+ Keys = new ulong[0x4],
+ };
- KeyboardInput hidKeyboard = new()
- {
- Modifier = 0,
- Keys = new ulong[0x4],
- };
+ foreach (HLEKeyboardMappingEntry entry in _keyMapping)
+ {
+ ulong value = keyboardState.IsPressed(entry.TargetKey) ? 1UL : 0UL;
- foreach (HLEKeyboardMappingEntry entry in _keyMapping)
- {
- ulong value = keyboardState.IsPressed(entry.TargetKey) ? 1UL : 0UL;
-
- hidKeyboard.Keys[entry.Target / 0x40] |= (value << (entry.Target % 0x40));
- }
-
- foreach (HLEKeyboardMappingEntry entry in _keyModifierMapping)
- {
- int value = keyboardState.IsPressed(entry.TargetKey) ? 1 : 0;
-
- hidKeyboard.Modifier |= value << entry.Target;
- }
-
- return hidKeyboard;
+ hidKeyboard.Keys[entry.Target / 0x40] |= (value << (entry.Target % 0x40));
}
- return null;
- }
+ foreach (HLEKeyboardMappingEntry entry in _keyModifierMapping)
+ {
+ int value = keyboardState.IsPressed(entry.TargetKey) ? 1 : 0;
+ hidKeyboard.Modifier |= value << entry.Target;
+ }
+
+ return hidKeyboard;
+
+ }
protected virtual void Dispose(bool disposing)
{
diff --git a/src/Ryujinx.Input/HLE/NpadManager.cs b/src/Ryujinx.Input/HLE/NpadManager.cs
index 5ae73bda19..4c7bb8b7a4 100644
--- a/src/Ryujinx.Input/HLE/NpadManager.cs
+++ b/src/Ryujinx.Input/HLE/NpadManager.cs
@@ -231,11 +231,6 @@ namespace Ryujinx.Input.HLE
var altMotionState = isJoyconPair ? controller.GetHLEMotionState(true) : default;
motionState = (controller.GetHLEMotionState(), altMotionState);
-
- if (_enableKeyboard)
- {
- hleKeyboardInput = controller.GetHLEKeyboardInput();
- }
}
else
{
@@ -257,6 +252,11 @@ namespace Ryujinx.Input.HLE
}
}
+ if (!_blockInputUpdates && _enableKeyboard)
+ {
+ hleKeyboardInput = NpadController.GetHLEKeyboardInput(_keyboardDriver);
+ }
+
_device.Hid.Npads.Update(hleInputStates);
_device.Hid.Npads.UpdateSixAxis(hleMotionStates);
diff --git a/src/Ryujinx.UI.Common/Configuration/ConfigurationFileFormat.cs b/src/Ryujinx.UI.Common/Configuration/ConfigurationFileFormat.cs
index 3387e1be13..af3ad0a1da 100644
--- a/src/Ryujinx.UI.Common/Configuration/ConfigurationFileFormat.cs
+++ b/src/Ryujinx.UI.Common/Configuration/ConfigurationFileFormat.cs
@@ -15,7 +15,7 @@ namespace Ryujinx.UI.Common.Configuration
///
/// The current version of the file format
///
- public const int CurrentVersion = 50;
+ public const int CurrentVersion = 51;
///
/// Version of the configuration file format
@@ -162,6 +162,11 @@ namespace Ryujinx.UI.Common.Configuration
///
public bool ShowConfirmExit { get; set; }
+ ///
+ /// Enables or disables save window size, position and state on close.
+ ///
+ public bool RememberWindowState { get; set; }
+
///
/// Enables hardware-accelerated rendering for Avalonia
///
diff --git a/src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs b/src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs
index 2609dc9baa..01c60a5e23 100644
--- a/src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs
+++ b/src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs
@@ -626,6 +626,11 @@ namespace Ryujinx.UI.Common.Configuration
///
public ReactiveObject ShowConfirmExit { get; private set; }
+ ///
+ /// Enables or disables save window size, position and state on close.
+ ///
+ public ReactiveObject RememberWindowState { get; private set; }
+
///
/// Enables hardware-accelerated rendering for Avalonia
///
@@ -647,6 +652,7 @@ namespace Ryujinx.UI.Common.Configuration
EnableDiscordIntegration = new ReactiveObject();
CheckUpdatesOnStart = new ReactiveObject();
ShowConfirmExit = new ReactiveObject();
+ RememberWindowState = new ReactiveObject();
EnableHardwareAcceleration = new ReactiveObject();
HideCursor = new ReactiveObject();
}
@@ -684,6 +690,7 @@ namespace Ryujinx.UI.Common.Configuration
EnableDiscordIntegration = EnableDiscordIntegration,
CheckUpdatesOnStart = CheckUpdatesOnStart,
ShowConfirmExit = ShowConfirmExit,
+ RememberWindowState = RememberWindowState,
EnableHardwareAcceleration = EnableHardwareAcceleration,
HideCursor = HideCursor,
EnableVsync = Graphics.EnableVsync,
@@ -792,6 +799,7 @@ namespace Ryujinx.UI.Common.Configuration
EnableDiscordIntegration.Value = true;
CheckUpdatesOnStart.Value = true;
ShowConfirmExit.Value = true;
+ RememberWindowState.Value = true;
EnableHardwareAcceleration.Value = true;
HideCursor.Value = HideCursorMode.OnIdle;
Graphics.EnableVsync.Value = true;
@@ -1459,6 +1467,15 @@ namespace Ryujinx.UI.Common.Configuration
configurationFileUpdated = true;
}
+ if (configurationFileFormat.Version < 51)
+ {
+ Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 51.");
+
+ configurationFileFormat.RememberWindowState = true;
+
+ configurationFileUpdated = true;
+ }
+
Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog;
Graphics.ResScale.Value = configurationFileFormat.ResScale;
Graphics.ResScaleCustom.Value = configurationFileFormat.ResScaleCustom;
@@ -1489,6 +1506,7 @@ namespace Ryujinx.UI.Common.Configuration
EnableDiscordIntegration.Value = configurationFileFormat.EnableDiscordIntegration;
CheckUpdatesOnStart.Value = configurationFileFormat.CheckUpdatesOnStart;
ShowConfirmExit.Value = configurationFileFormat.ShowConfirmExit;
+ RememberWindowState.Value = configurationFileFormat.RememberWindowState;
EnableHardwareAcceleration.Value = configurationFileFormat.EnableHardwareAcceleration;
HideCursor.Value = configurationFileFormat.HideCursor;
Graphics.EnableVsync.Value = configurationFileFormat.EnableVsync;
diff --git a/src/Ryujinx/AppHost.cs b/src/Ryujinx/AppHost.cs
index 43e7a79ebb..d405f32050 100644
--- a/src/Ryujinx/AppHost.cs
+++ b/src/Ryujinx/AppHost.cs
@@ -94,6 +94,17 @@ namespace Ryujinx.Ava
private long _lastCursorMoveTime;
private bool _isCursorInRenderer = true;
+ private bool _ignoreCursorState = false;
+
+ private enum CursorStates
+ {
+ CursorIsHidden,
+ CursorIsVisible,
+ ForceChangeCursor
+ };
+
+ private CursorStates _cursorState = !ConfigurationState.Instance.Hid.EnableMouse.Value ?
+ CursorStates.CursorIsVisible : CursorStates.CursorIsHidden;
private bool _isStopped;
private bool _isActive;
@@ -201,23 +212,65 @@ namespace Ryujinx.Ava
private void TopLevel_PointerEnteredOrMoved(object sender, PointerEventArgs e)
{
+ if (!_viewModel.IsActive)
+ {
+ _isCursorInRenderer = false;
+ _ignoreCursorState = false;
+ return;
+ }
+
if (sender is MainWindow window)
{
- _lastCursorMoveTime = Stopwatch.GetTimestamp();
+ if (ConfigurationState.Instance.HideCursor.Value == HideCursorMode.OnIdle)
+ {
+ _lastCursorMoveTime = Stopwatch.GetTimestamp();
+ }
var point = e.GetCurrentPoint(window).Position;
var bounds = RendererHost.EmbeddedWindow.Bounds;
+ var windowYOffset = bounds.Y + window.MenuBarHeight;
+ var windowYLimit = (int)window.Bounds.Height - window.StatusBarHeight - 1;
+
+ if (!_viewModel.ShowMenuAndStatusBar)
+ {
+ windowYOffset -= window.MenuBarHeight;
+ windowYLimit += window.StatusBarHeight + 1;
+ }
_isCursorInRenderer = point.X >= bounds.X &&
- point.X <= bounds.Width + bounds.X &&
- point.Y >= bounds.Y &&
- point.Y <= bounds.Height + bounds.Y;
+ Math.Ceiling(point.X) <= (int)window.Bounds.Width &&
+ point.Y >= windowYOffset &&
+ point.Y <= windowYLimit &&
+ !_viewModel.IsSubMenuOpen;
+
+ _ignoreCursorState = false;
}
}
private void TopLevel_PointerExited(object sender, PointerEventArgs e)
{
_isCursorInRenderer = false;
+
+ if (sender is MainWindow window)
+ {
+ var point = e.GetCurrentPoint(window).Position;
+ var bounds = RendererHost.EmbeddedWindow.Bounds;
+ var windowYOffset = bounds.Y + window.MenuBarHeight;
+ var windowYLimit = (int)window.Bounds.Height - window.StatusBarHeight - 1;
+
+ if (!_viewModel.ShowMenuAndStatusBar)
+ {
+ windowYOffset -= window.MenuBarHeight;
+ windowYLimit += window.StatusBarHeight + 1;
+ }
+
+ _ignoreCursorState = (point.X == bounds.X ||
+ Math.Ceiling(point.X) == (int)window.Bounds.Width) &&
+ point.Y >= windowYOffset &&
+ point.Y <= windowYLimit;
+ }
+
+ _cursorState = CursorStates.ForceChangeCursor;
}
private void UpdateScalingFilterLevel(object sender, ReactiveEventArgs e)
@@ -245,9 +298,14 @@ namespace Ryujinx.Ava
if (OperatingSystem.IsWindows())
{
- SetCursor(_defaultCursorWin);
+ if (_cursorState != CursorStates.CursorIsHidden && !_ignoreCursorState)
+ {
+ SetCursor(_defaultCursorWin);
+ }
}
});
+
+ _cursorState = CursorStates.CursorIsVisible;
}
private void HideCursor()
@@ -261,6 +319,8 @@ namespace Ryujinx.Ava
SetCursor(_invisibleCursorWin);
}
});
+
+ _cursorState = CursorStates.CursorIsHidden;
}
private void SetRendererWindowSize(Size size)
@@ -523,6 +583,8 @@ namespace Ryujinx.Ava
{
_lastCursorMoveTime = Stopwatch.GetTimestamp();
}
+
+ _cursorState = CursorStates.ForceChangeCursor;
}
public async Task LoadGuestApplication()
@@ -1037,38 +1099,32 @@ namespace Ryujinx.Ava
if (_viewModel.IsActive)
{
- if (_isCursorInRenderer)
+ bool isCursorVisible = true;
+
+ if (_isCursorInRenderer && !_viewModel.ShowLoadProgress)
{
- if (ConfigurationState.Instance.Hid.EnableMouse)
+ if (ConfigurationState.Instance.Hid.EnableMouse.Value)
{
- HideCursor();
+ isCursorVisible = ConfigurationState.Instance.HideCursor.Value == HideCursorMode.Never;
}
else
{
- switch (ConfigurationState.Instance.HideCursor.Value)
- {
- case HideCursorMode.Never:
- ShowCursor();
- break;
- case HideCursorMode.OnIdle:
- if (Stopwatch.GetTimestamp() - _lastCursorMoveTime >= CursorHideIdleTime * Stopwatch.Frequency)
- {
- HideCursor();
- }
- else
- {
- ShowCursor();
- }
- break;
- case HideCursorMode.Always:
- HideCursor();
- break;
- }
+ isCursorVisible = ConfigurationState.Instance.HideCursor.Value == HideCursorMode.Never ||
+ (ConfigurationState.Instance.HideCursor.Value == HideCursorMode.OnIdle &&
+ Stopwatch.GetTimestamp() - _lastCursorMoveTime < CursorHideIdleTime * Stopwatch.Frequency);
}
}
- else
+
+ if (_cursorState != (isCursorVisible ? CursorStates.CursorIsVisible : CursorStates.CursorIsHidden))
{
- ShowCursor();
+ if (isCursorVisible)
+ {
+ ShowCursor();
+ }
+ else
+ {
+ HideCursor();
+ }
}
Dispatcher.UIThread.Post(() =>
@@ -1154,7 +1210,7 @@ namespace Ryujinx.Ava
// Touchscreen.
bool hasTouch = false;
- if (_viewModel.IsActive && !ConfigurationState.Instance.Hid.EnableMouse)
+ if (_viewModel.IsActive && !ConfigurationState.Instance.Hid.EnableMouse.Value)
{
hasTouch = TouchScreenManager.Update(true, (_inputManager.MouseDriver as AvaloniaMouseDriver).IsButtonPressed(MouseButton.Button1), ConfigurationState.Instance.Graphics.AspectRatio.Value.ToFloat());
}
diff --git a/src/Ryujinx/Assets/Locales/en_US.json b/src/Ryujinx/Assets/Locales/en_US.json
index 77ad7d1f8c..2299d9e665 100644
--- a/src/Ryujinx/Assets/Locales/en_US.json
+++ b/src/Ryujinx/Assets/Locales/en_US.json
@@ -30,6 +30,10 @@
"MenuBarToolsManageFileTypes": "Manage file types",
"MenuBarToolsInstallFileTypes": "Install file types",
"MenuBarToolsUninstallFileTypes": "Uninstall file types",
+ "MenuBarView": "_View",
+ "MenuBarViewWindow": "Window Size",
+ "MenuBarViewWindow720": "720p",
+ "MenuBarViewWindow1080": "1080p",
"MenuBarHelp": "_Help",
"MenuBarHelpCheckForUpdates": "Check for Updates",
"MenuBarHelpAbout": "About",
@@ -92,6 +96,7 @@
"SettingsTabGeneralEnableDiscordRichPresence": "Enable Discord Rich Presence",
"SettingsTabGeneralCheckUpdatesOnLaunch": "Check for Updates on Launch",
"SettingsTabGeneralShowConfirmExitDialog": "Show \"Confirm Exit\" Dialog",
+ "SettingsTabGeneralRememberWindowState": "Remember Window Size/Position",
"SettingsTabGeneralHideCursor": "Hide Cursor:",
"SettingsTabGeneralHideCursorNever": "Never",
"SettingsTabGeneralHideCursorOnIdle": "On Idle",
diff --git a/src/Ryujinx/UI/Helpers/KeyValueConverter.cs b/src/Ryujinx/UI/Helpers/KeyValueConverter.cs
index cbcf16ab32..5b0d6ee1c0 100644
--- a/src/Ryujinx/UI/Helpers/KeyValueConverter.cs
+++ b/src/Ryujinx/UI/Helpers/KeyValueConverter.cs
@@ -19,8 +19,8 @@ namespace Ryujinx.Ava.UI.Helpers
{ Key.ShiftRight, LocaleKeys.KeyShiftRight },
{ Key.ControlLeft, LocaleKeys.KeyControlLeft },
{ Key.ControlRight, LocaleKeys.KeyControlRight },
- { Key.AltLeft, LocaleKeys.KeyControlLeft },
- { Key.AltRight, LocaleKeys.KeyControlRight },
+ { Key.AltLeft, LocaleKeys.KeyAltLeft },
+ { Key.AltRight, LocaleKeys.KeyAltRight },
{ Key.WinLeft, LocaleKeys.KeyWinLeft },
{ Key.WinRight, LocaleKeys.KeyWinRight },
{ Key.Up, LocaleKeys.KeyUp },
diff --git a/src/Ryujinx/UI/Helpers/Win32NativeInterop.cs b/src/Ryujinx/UI/Helpers/Win32NativeInterop.cs
index fce2d518ac..01478cb3de 100644
--- a/src/Ryujinx/UI/Helpers/Win32NativeInterop.cs
+++ b/src/Ryujinx/UI/Helpers/Win32NativeInterop.cs
@@ -111,8 +111,5 @@ namespace Ryujinx.Ava.UI.Helpers
[LibraryImport("user32.dll", SetLastError = true)]
public static partial IntPtr SetWindowLongPtrW(IntPtr hWnd, int nIndex, IntPtr value);
-
- [LibraryImport("user32.dll", SetLastError = true)]
- public static partial IntPtr SetWindowLongW(IntPtr hWnd, int nIndex, int value);
}
}
diff --git a/src/Ryujinx/UI/Renderer/EmbeddedWindow.cs b/src/Ryujinx/UI/Renderer/EmbeddedWindow.cs
index 8c5e31fff4..0930e77950 100644
--- a/src/Ryujinx/UI/Renderer/EmbeddedWindow.cs
+++ b/src/Ryujinx/UI/Renderer/EmbeddedWindow.cs
@@ -157,7 +157,7 @@ namespace Ryujinx.Ava.UI.Renderer
lpfnWndProc = Marshal.GetFunctionPointerForDelegate(_wndProcDelegate),
style = ClassStyles.CsOwndc,
lpszClassName = Marshal.StringToHGlobalUni(_className),
- hCursor = CreateArrowCursor(),
+ hCursor = CreateArrowCursor()
};
RegisterClassEx(ref wndClassEx);
diff --git a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs
index 130e708c77..549eebf14d 100644
--- a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs
@@ -104,6 +104,7 @@ namespace Ryujinx.Ava.UI.ViewModels
private double _windowHeight;
private bool _isActive;
+ private bool _isSubMenuOpen;
public ApplicationData ListSelectedApplication;
public ApplicationData GridSelectedApplication;
@@ -317,6 +318,17 @@ namespace Ryujinx.Ava.UI.ViewModels
}
}
+ public bool IsSubMenuOpen
+ {
+ get => _isSubMenuOpen;
+ set
+ {
+ _isSubMenuOpen = value;
+
+ OnPropertyChanged();
+ }
+ }
+
public bool ShowAll
{
get => _showAll;
diff --git a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs
index 6074a5fdb3..0f43d0f7fc 100644
--- a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs
@@ -131,6 +131,7 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool EnableDiscordIntegration { get; set; }
public bool CheckUpdatesOnStart { get; set; }
public bool ShowConfirmExit { get; set; }
+ public bool RememberWindowState { get; set; }
public int HideCursor { get; set; }
public bool EnableDockedMode { get; set; }
public bool EnableKeyboard { get; set; }
@@ -390,6 +391,7 @@ namespace Ryujinx.Ava.UI.ViewModels
EnableDiscordIntegration = config.EnableDiscordIntegration;
CheckUpdatesOnStart = config.CheckUpdatesOnStart;
ShowConfirmExit = config.ShowConfirmExit;
+ RememberWindowState = config.RememberWindowState;
HideCursor = (int)config.HideCursor.Value;
GameDirectories.Clear();
@@ -410,10 +412,11 @@ namespace Ryujinx.Ava.UI.ViewModels
Language = (int)config.System.Language.Value;
TimeZone = config.System.TimeZone;
- DateTime currentDateTime = DateTime.Now;
-
+ DateTime currentHostDateTime = DateTime.Now;
+ TimeSpan systemDateTimeOffset = TimeSpan.FromSeconds(config.System.SystemTimeOffset);
+ DateTime currentDateTime = currentHostDateTime.Add(systemDateTimeOffset);
CurrentDate = currentDateTime.Date;
- CurrentTime = currentDateTime.TimeOfDay.Add(TimeSpan.FromSeconds(config.System.SystemTimeOffset));
+ CurrentTime = currentDateTime.TimeOfDay;
EnableVsync = config.Graphics.EnableVsync;
EnableFsIntegrityChecks = config.System.EnableFsIntegrityChecks;
@@ -474,6 +477,7 @@ namespace Ryujinx.Ava.UI.ViewModels
config.EnableDiscordIntegration.Value = EnableDiscordIntegration;
config.CheckUpdatesOnStart.Value = CheckUpdatesOnStart;
config.ShowConfirmExit.Value = ShowConfirmExit;
+ config.RememberWindowState.Value = RememberWindowState;
config.HideCursor.Value = (HideCursorMode)HideCursor;
if (_directoryChanged)
diff --git a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml
index 30358adabf..ac37361106 100644
--- a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml
+++ b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml
@@ -1,4 +1,4 @@
-
+ HorizontalAlignment="Left"
+ IsOpen="{Binding IsSubMenuOpen, Mode=OneWayToSource}">
@@ -185,6 +186,12 @@
+
+ {
+ ViewModel.WindowState = WindowState.Normal;
+
+ height += (int)Window.StatusBarHeight + (int)Window.MenuBarHeight;
+
+ Window.Arrange(new Rect(Window.Position.X, Window.Position.Y, width, height));
+ });
+ }
+ }
+
public async void CheckForUpdates(object sender, RoutedEventArgs e)
{
if (Updater.CanUpdate(true))
diff --git a/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml
index 6504637e6c..b60058fcbf 100644
--- a/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml
+++ b/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml
@@ -36,6 +36,9 @@
+
+
+