diff --git a/assets/Locales/Root.json b/assets/Locales/Root.json index a11aad25a..0b1115cdc 100644 --- a/assets/Locales/Root.json +++ b/assets/Locales/Root.json @@ -21425,6 +21425,31 @@ "zh_TW": "需要重新啟動 Ryujinx" } }, + { + "ID": "SettingsShowConsoleRestartMessage", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "The console will be available the next time Ryujinx starts.", + "es_ES": "La consola estará disponible la próxima vez que se inicie Ryujinx.", + "fr_FR": "La console sera disponible au prochain démarrage de Ryujinx.", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "", + "ru_RU": "", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" + } + }, { "ID": "SettingsGpuBackendRestartMessage", "Translations": { diff --git a/src/Ryujinx.Common/Helpers/ConsoleHelper.cs b/src/Ryujinx.Common/Helpers/ConsoleHelper.cs index 2b3c11b1e..75954110c 100644 --- a/src/Ryujinx.Common/Helpers/ConsoleHelper.cs +++ b/src/Ryujinx.Common/Helpers/ConsoleHelper.cs @@ -12,20 +12,12 @@ namespace Ryujinx.Common.Helper private static partial nint GetConsoleWindow(); [SupportedOSPlatform("windows")] - [LibraryImport("user32")] + [LibraryImport("kernel32", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] - private static partial bool ShowWindow(nint hWnd, int nCmdShow); - - [SupportedOSPlatform("windows")] - [LibraryImport("user32")] - private static partial nint GetForegroundWindow(); - - [SupportedOSPlatform("windows")] - [LibraryImport("user32")] - [return: MarshalAs(UnmanagedType.Bool)] - private static partial bool SetForegroundWindow(nint hWnd); + private static partial bool FreeConsole(); public static bool SetConsoleWindowStateSupported => OperatingSystem.IsWindows(); + public static bool HasConsoleWindow => OperatingSystem.IsWindows() && GetConsoleWindow() != nint.Zero; public static void SetConsoleWindowState(bool show) { @@ -42,22 +34,31 @@ namespace Ryujinx.Common.Helper [SupportedOSPlatform("windows")] private static void SetConsoleWindowStateWindows(bool show) { - const int SW_HIDE = 0; - const int SW_SHOW = 5; - - nint hWnd = GetConsoleWindow(); - - if (hWnd == nint.Zero) + if (show) { - Logger.Warning?.Print(LogClass.Application, "Attempted to show/hide console window but console window does not exist"); + if (GetConsoleWindow() != nint.Zero) + { + Logger.SetConsoleTargetEnabled(true); + } return; } - SetForegroundWindow(hWnd); + Logger.SetConsoleTargetEnabled(false); + DetachConsole(); + } - hWnd = GetForegroundWindow(); + [SupportedOSPlatform("windows")] + private static void DetachConsole() + { + if (GetConsoleWindow() == nint.Zero) + { + return; + } - ShowWindow(hWnd, show ? SW_SHOW : SW_HIDE); + if (!FreeConsole()) + { + Logger.Warning?.Print(LogClass.Application, "Attempted to detach console window but the operation failed"); + } } } } diff --git a/src/Ryujinx.Common/Logging/Logger.cs b/src/Ryujinx.Common/Logging/Logger.cs index 64a76a3e4..b5450c94b 100644 --- a/src/Ryujinx.Common/Logging/Logger.cs +++ b/src/Ryujinx.Common/Logging/Logger.cs @@ -136,11 +136,7 @@ namespace Ryujinx.Common.Logging _time = Stopwatch.StartNew(); - // Logger should log to console by default - AddTarget(new AsyncLogTargetWrapper( - new ConsoleLogTarget("console"), - 1000, - AsyncLogTargetOverflowAction.Discard)); + SetConsoleTargetEnabled(true); Notice = new Log(LogLevel.Notice); @@ -173,6 +169,21 @@ namespace Ryujinx.Common.Logging Updated += target.Log; } + public static void SetConsoleTargetEnabled(bool enabled) + { + if (enabled) + { + AddTarget(new AsyncLogTargetWrapper( + new ConsoleLogTarget("console"), + 1000, + AsyncLogTargetOverflowAction.Discard)); + } + else + { + RemoveTarget("console"); + } + } + public static void RemoveTarget(string target) { ILogTarget logTarget = GetTarget(target); diff --git a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs index 9e139c186..57fd825b3 100644 --- a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs @@ -656,10 +656,19 @@ namespace Ryujinx.Ava.UI.ViewModels get => ConfigurationState.Instance.UI.ShowConsole; set { + bool restartRequired = value && !ConsoleHelper.HasConsoleWindow; + ConfigurationState.Instance.UI.ShowConsole.Value = value; ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath); + if (restartRequired) + { + NotificationHelper.ShowInformation( + LocaleManager.Instance[LocaleKeys.SettingsAppRequiredRestartMessage], + LocaleManager.Instance[LocaleKeys.SettingsShowConsoleRestartMessage]); + } + OnPropertyChanged(); } }