0
0
Fork 0

GUI: Add option to register file types (#4250)

* Add FileAssociationHelper.cs

* Add register file types option to gtk

* Add register file types option to avalonia

* Add Windows support to FileAssociationHelper.cs

* linux: Add uninstall support for file types

* Ignore .glade~ backup files

* Rename Register/Unregister methods

* gtk: Add manage file types submenu

* ava: Add manage file types submenu

* windows: Add uninstall support for file types

* Don't invert uninstall condition (formatting change)

Co-authored-by: gdkchan <gab.dark.100@gmail.com>

* Add IsTypesRegisteredWindows & Fix Windows install function

* Add AreMimeTypesRegisteredLinux()

* Fix wrong indention

Co-authored-by: AcK77 <acoustik666@gmail.com>
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
This commit is contained in:
TSRBerry 2023-01-22 18:39:00 +01:00 committed by GitHub
parent dc30d94852
commit ad6ff6ce99
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 506 additions and 308 deletions

3
.gitignore vendored
View file

@ -170,3 +170,6 @@ launchSettings.json
# NetCore Publishing Profiles # NetCore Publishing Profiles
PublishProfiles/ PublishProfiles/
# Glade backup files
*.glade~

View file

@ -26,6 +26,9 @@
"MenuBarToolsInstallFirmware": "Install Firmware", "MenuBarToolsInstallFirmware": "Install Firmware",
"MenuBarFileToolsInstallFirmwareFromFile": "Install a firmware from XCI or ZIP", "MenuBarFileToolsInstallFirmwareFromFile": "Install a firmware from XCI or ZIP",
"MenuBarFileToolsInstallFirmwareFromDirectory": "Install a firmware from a directory", "MenuBarFileToolsInstallFirmwareFromDirectory": "Install a firmware from a directory",
"MenuBarToolsManageFileTypes": "Manage file types",
"MenuBarToolsInstallFileTypes": "Install file types",
"MenuBarToolsUninstallFileTypes": "Uninstall file types",
"MenuBarHelp": "Help", "MenuBarHelp": "Help",
"MenuBarHelpCheckForUpdates": "Check for Updates", "MenuBarHelpCheckForUpdates": "Check for Updates",
"MenuBarHelpAbout": "About", "MenuBarHelpAbout": "About",
@ -339,6 +342,10 @@
"DialogFirmwareInstallEmbeddedSuccessMessage": "No installed firmware was found but Ryujinx was able to install firmware {0} from the provided game.\\nThe emulator will now start.", "DialogFirmwareInstallEmbeddedSuccessMessage": "No installed firmware was found but Ryujinx was able to install firmware {0} from the provided game.\\nThe emulator will now start.",
"DialogFirmwareNoFirmwareInstalledMessage": "No Firmware Installed", "DialogFirmwareNoFirmwareInstalledMessage": "No Firmware Installed",
"DialogFirmwareInstalledMessage": "Firmware {0} was installed", "DialogFirmwareInstalledMessage": "Firmware {0} was installed",
"DialogInstallFileTypesSuccessMessage": "Successfully installed file types!",
"DialogInstallFileTypesErrorMessage": "Failed to install file types.",
"DialogUninstallFileTypesSuccessMessage": "Successfully uninstalled file types!",
"DialogUninstallFileTypesErrorMessage": "Failed to uninstall file types.",
"DialogOpenSettingsWindowLabel": "Open Settings Window", "DialogOpenSettingsWindowLabel": "Open Settings Window",
"DialogControllerAppletTitle": "Controller Applet", "DialogControllerAppletTitle": "Controller Applet",
"DialogMessageDialogErrorExceptionMessage": "Error displaying Message Dialog: {0}", "DialogMessageDialogErrorExceptionMessage": "Error displaying Message Dialog: {0}",

View file

@ -14,10 +14,8 @@ using Ryujinx.Ui.Common;
using Ryujinx.Ui.Common.Configuration; using Ryujinx.Ui.Common.Configuration;
using Ryujinx.Ui.Common.Helper; using Ryujinx.Ui.Common.Helper;
using System; using System;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Ryujinx.Ava namespace Ryujinx.Ava
@ -35,48 +33,6 @@ namespace Ryujinx.Ava
private const uint MB_ICONWARNING = 0x30; private const uint MB_ICONWARNING = 0x30;
[SupportedOSPlatform("linux")]
static void RegisterMimeTypes()
{
if (ReleaseInformation.IsFlatHubBuild())
{
return;
}
string mimeDbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".local", "share", "mime");
if (!File.Exists(Path.Combine(mimeDbPath, "packages", "Ryujinx.xml")))
{
string mimeTypesFile = Path.Combine(ReleaseInformation.GetBaseApplicationDirectory(), "mime", "Ryujinx.xml");
using Process mimeProcess = new();
mimeProcess.StartInfo.FileName = "xdg-mime";
mimeProcess.StartInfo.Arguments = $"install --novendor --mode user {mimeTypesFile}";
mimeProcess.Start();
mimeProcess.WaitForExit();
if (mimeProcess.ExitCode != 0)
{
Logger.Error?.PrintMsg(LogClass.Application, $"Unable to install mime types. Make sure xdg-utils is installed. Process exited with code: {mimeProcess.ExitCode}");
return;
}
using Process updateMimeProcess = new();
updateMimeProcess.StartInfo.FileName = "update-mime-database";
updateMimeProcess.StartInfo.Arguments = mimeDbPath;
updateMimeProcess.Start();
updateMimeProcess.WaitForExit();
if (updateMimeProcess.ExitCode != 0)
{
Logger.Error?.PrintMsg(LogClass.Application, $"Could not update local mime database. Process exited with code: {updateMimeProcess.ExitCode}");
}
}
}
public static void Main(string[] args) public static void Main(string[] args)
{ {
Version = ReleaseInformation.GetVersion(); Version = ReleaseInformation.GetVersion();
@ -139,12 +95,6 @@ namespace Ryujinx.Ava
// Initialize the logger system. // Initialize the logger system.
LoggerModule.Initialize(); LoggerModule.Initialize();
// Register mime types on linux.
if (OperatingSystem.IsLinux())
{
RegisterMimeTypes();
}
// Initialize Discord integration. // Initialize Discord integration.
DiscordIntegrationModule.Initialize(); DiscordIntegrationModule.Initialize();

View file

@ -683,6 +683,11 @@ namespace Ryujinx.Ava.UI.ViewModels
get => ConsoleHelper.SetConsoleWindowStateSupported; get => ConsoleHelper.SetConsoleWindowStateSupported;
} }
public bool ManageFileTypesVisible
{
get => FileAssociationHelper.IsTypeAssociationSupported;
}
public ObservableCollection<ApplicationData> Applications public ObservableCollection<ApplicationData> Applications
{ {
get => _applications; get => _applications;

View file

@ -77,8 +77,7 @@
</MenuItem.Icon> </MenuItem.Icon>
</MenuItem> </MenuItem>
<Separator /> <Separator />
<MenuItem Name="ChangeLanguageMenuItem" Header="{locale:Locale MenuBarOptionsChangeLanguage}"> <MenuItem Name="ChangeLanguageMenuItem" Header="{locale:Locale MenuBarOptionsChangeLanguage}" />
</MenuItem>
<Separator /> <Separator />
<MenuItem <MenuItem
Click="OpenSettings" Click="OpenSettings"
@ -141,6 +140,10 @@
<MenuItem Command="{ReflectionBinding InstallFirmwareFromFile}" Header="{locale:Locale MenuBarFileToolsInstallFirmwareFromFile}" /> <MenuItem Command="{ReflectionBinding InstallFirmwareFromFile}" Header="{locale:Locale MenuBarFileToolsInstallFirmwareFromFile}" />
<MenuItem Command="{ReflectionBinding InstallFirmwareFromFolder}" Header="{locale:Locale MenuBarFileToolsInstallFirmwareFromDirectory}" /> <MenuItem Command="{ReflectionBinding InstallFirmwareFromFolder}" Header="{locale:Locale MenuBarFileToolsInstallFirmwareFromDirectory}" />
</MenuItem> </MenuItem>
<MenuItem Header="{locale:Locale MenuBarToolsManageFileTypes}" IsVisible="{Binding ManageFileTypesVisible}">
<MenuItem Header="{locale:Locale MenuBarToolsInstallFileTypes}" Click="InstallFileTypes_Click"/>
<MenuItem Header="{locale:Locale MenuBarToolsUninstallFileTypes}" Click="UninstallFileTypes_Click"/>
</MenuItem>
</MenuItem> </MenuItem>
<MenuItem VerticalAlignment="Center" Header="{locale:Locale MenuBarHelp}"> <MenuItem VerticalAlignment="Center" Header="{locale:Locale MenuBarHelp}">
<MenuItem <MenuItem

View file

@ -3,6 +3,7 @@ using Avalonia.Controls;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using LibHac.FsSystem; using LibHac.FsSystem;
using LibHac.Ncm; using LibHac.Ncm;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.UI.Windows;
@ -10,6 +11,7 @@ using Ryujinx.Common;
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using Ryujinx.HLE.HOS; using Ryujinx.HLE.HOS;
using Ryujinx.Modules; using Ryujinx.Modules;
using Ryujinx.Ui.Common.Helper;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@ -163,6 +165,32 @@ namespace Ryujinx.Ava.UI.Views.Main
} }
} }
private async void InstallFileTypes_Click(object sender, RoutedEventArgs e)
{
if (FileAssociationHelper.Install())
{
await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance[LocaleKeys.DialogInstallFileTypesSuccessMessage],
string.Empty, LocaleManager.Instance[LocaleKeys.InputDialogOk], string.Empty, string.Empty);
}
else
{
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogInstallFileTypesErrorMessage]);
}
}
private async void UninstallFileTypes_Click(object sender, RoutedEventArgs e)
{
if (FileAssociationHelper.Uninstall())
{
await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance[LocaleKeys.DialogUninstallFileTypesSuccessMessage],
string.Empty, LocaleManager.Instance[LocaleKeys.InputDialogOk], string.Empty, string.Empty);
}
else
{
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogUninstallFileTypesErrorMessage]);
}
}
public async void CheckForUpdates(object sender, RoutedEventArgs e) public async void CheckForUpdates(object sender, RoutedEventArgs e)
{ {
if (Updater.CanUpdate(true)) if (Updater.CanUpdate(true))

View file

@ -0,0 +1,198 @@
using Microsoft.Win32;
using Ryujinx.Common;
using Ryujinx.Common.Logging;
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
namespace Ryujinx.Ui.Common.Helper
{
public static partial class FileAssociationHelper
{
private static string[] _fileExtensions = new string[] { ".nca", ".nro", ".nso", ".nsp", ".xci" };
[SupportedOSPlatform("linux")]
private static string _mimeDbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".local", "share", "mime");
private const int SHCNE_ASSOCCHANGED = 0x8000000;
private const int SHCNF_FLUSH = 0x1000;
[LibraryImport("shell32.dll", SetLastError = true)]
public static partial void SHChangeNotify(uint wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2);
public static bool IsTypeAssociationSupported => (OperatingSystem.IsLinux() || OperatingSystem.IsWindows()) && !ReleaseInformation.IsFlatHubBuild();
[SupportedOSPlatform("linux")]
private static bool AreMimeTypesRegisteredLinux() => File.Exists(Path.Combine(_mimeDbPath, "packages", "Ryujinx.xml"));
[SupportedOSPlatform("linux")]
private static bool InstallLinuxMimeTypes(bool uninstall = false)
{
string installKeyword = uninstall ? "uninstall" : "install";
if (!AreMimeTypesRegisteredLinux())
{
string mimeTypesFile = Path.Combine(ReleaseInformation.GetBaseApplicationDirectory(), "mime", "Ryujinx.xml");
string additionalArgs = !uninstall ? "--novendor" : "";
using Process mimeProcess = new();
mimeProcess.StartInfo.FileName = "xdg-mime";
mimeProcess.StartInfo.Arguments = $"{installKeyword} {additionalArgs} --mode user {mimeTypesFile}";
mimeProcess.Start();
mimeProcess.WaitForExit();
if (mimeProcess.ExitCode != 0)
{
Logger.Error?.PrintMsg(LogClass.Application, $"Unable to {installKeyword} mime types. Make sure xdg-utils is installed. Process exited with code: {mimeProcess.ExitCode}");
return false;
}
using Process updateMimeProcess = new();
updateMimeProcess.StartInfo.FileName = "update-mime-database";
updateMimeProcess.StartInfo.Arguments = _mimeDbPath;
updateMimeProcess.Start();
updateMimeProcess.WaitForExit();
if (updateMimeProcess.ExitCode != 0)
{
Logger.Error?.PrintMsg(LogClass.Application, $"Could not update local mime database. Process exited with code: {updateMimeProcess.ExitCode}");
}
}
return true;
}
[SupportedOSPlatform("windows")]
private static bool AreMimeTypesRegisteredWindows()
{
static bool CheckRegistering(string ext)
{
RegistryKey key = Registry.CurrentUser.OpenSubKey(@$"Software\Classes\{ext}");
if (key is null)
{
return false;
}
key.OpenSubKey(@"shell\open\command");
string keyValue = (string)key.GetValue("");
return keyValue is not null && (keyValue.Contains("Ryujinx") || keyValue.Contains(AppDomain.CurrentDomain.FriendlyName));
}
bool registered = false;
foreach (string ext in _fileExtensions)
{
registered |= CheckRegistering(ext);
}
return registered;
}
[SupportedOSPlatform("windows")]
private static bool InstallWindowsMimeTypes(bool uninstall = false)
{
static bool RegisterExtension(string ext, bool uninstall = false)
{
string keyString = @$"Software\Classes\{ext}";
if (uninstall)
{
if (!AreMimeTypesRegisteredWindows())
{
return false;
}
Registry.CurrentUser.DeleteSubKeyTree(keyString);
}
else
{
RegistryKey key = Registry.CurrentUser.CreateSubKey(keyString);
if (key is null)
{
return false;
}
key.CreateSubKey(@"shell\open\command");
key.SetValue("", $"\"{Environment.ProcessPath}\" \"%1\"");
key.Close();
}
// Notify Explorer the file association has been changed.
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSH, IntPtr.Zero, IntPtr.Zero);
return true;
}
bool registered = false;
foreach (string ext in _fileExtensions)
{
registered |= RegisterExtension(ext, uninstall);
}
return registered;
}
public static bool AreMimeTypesRegistered()
{
if (OperatingSystem.IsLinux())
{
return AreMimeTypesRegisteredLinux();
}
if (OperatingSystem.IsWindows())
{
return AreMimeTypesRegisteredWindows();
}
// TODO: Add macOS support.
return false;
}
public static bool Install()
{
if (OperatingSystem.IsLinux())
{
return InstallLinuxMimeTypes();
}
if (OperatingSystem.IsWindows())
{
return InstallWindowsMimeTypes();
}
// TODO: Add macOS support.
return false;
}
public static bool Uninstall()
{
if (OperatingSystem.IsLinux())
{
return InstallLinuxMimeTypes(true);
}
if (OperatingSystem.IsWindows())
{
return InstallWindowsMimeTypes(true);
}
// TODO: Add macOS support.
return false;
}
}
}

View file

@ -18,7 +18,6 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Ryujinx namespace Ryujinx
@ -73,48 +72,6 @@ namespace Ryujinx
} }
} }
[SupportedOSPlatform("linux")]
static void RegisterMimeTypes()
{
if (ReleaseInformation.IsFlatHubBuild())
{
return;
}
string mimeDbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".local", "share", "mime");
if (!File.Exists(Path.Combine(mimeDbPath, "packages", "Ryujinx.xml")))
{
string mimeTypesFile = Path.Combine(ReleaseInformation.GetBaseApplicationDirectory(), "mime", "Ryujinx.xml");
using Process mimeProcess = new();
mimeProcess.StartInfo.FileName = "xdg-mime";
mimeProcess.StartInfo.Arguments = $"install --novendor --mode user {mimeTypesFile}";
mimeProcess.Start();
mimeProcess.WaitForExit();
if (mimeProcess.ExitCode != 0)
{
Logger.Error?.PrintMsg(LogClass.Application, $"Unable to install mime types. Make sure xdg-utils is installed. Process exited with code: {mimeProcess.ExitCode}");
return;
}
using Process updateMimeProcess = new();
updateMimeProcess.StartInfo.FileName = "update-mime-database";
updateMimeProcess.StartInfo.Arguments = mimeDbPath;
updateMimeProcess.Start();
updateMimeProcess.WaitForExit();
if (updateMimeProcess.ExitCode != 0)
{
Logger.Error?.PrintMsg(LogClass.Application, $"Could not update local mime database. Process exited with code: {updateMimeProcess.ExitCode}");
}
}
}
static void Main(string[] args) static void Main(string[] args)
{ {
Version = ReleaseInformation.GetVersion(); Version = ReleaseInformation.GetVersion();
@ -189,12 +146,6 @@ namespace Ryujinx
// Initialize the logger system. // Initialize the logger system.
LoggerModule.Initialize(); LoggerModule.Initialize();
// Register mime types on linux.
if (OperatingSystem.IsLinux())
{
RegisterMimeTypes();
}
// Initialize Discord integration. // Initialize Discord integration.
DiscordIntegrationModule.Initialize(); DiscordIntegrationModule.Initialize();

View file

@ -44,7 +44,6 @@ using System.IO;
using System.Reflection; using System.Reflection;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using GUI = Gtk.Builder.ObjectAttribute; using GUI = Gtk.Builder.ObjectAttribute;
using ShaderCacheLoadingState = Ryujinx.Graphics.Gpu.Shader.ShaderCacheState; using ShaderCacheLoadingState = Ryujinx.Graphics.Gpu.Shader.ShaderCacheState;
@ -109,6 +108,7 @@ namespace Ryujinx.Ui
[GUI] CheckMenuItem _favToggle; [GUI] CheckMenuItem _favToggle;
[GUI] MenuItem _firmwareInstallDirectory; [GUI] MenuItem _firmwareInstallDirectory;
[GUI] MenuItem _firmwareInstallFile; [GUI] MenuItem _firmwareInstallFile;
[GUI] MenuItem _fileTypesSubMenu;
[GUI] Label _fifoStatus; [GUI] Label _fifoStatus;
[GUI] CheckMenuItem _iconToggle; [GUI] CheckMenuItem _iconToggle;
[GUI] CheckMenuItem _developerToggle; [GUI] CheckMenuItem _developerToggle;
@ -220,6 +220,8 @@ namespace Ryujinx.Ui
_pauseEmulation.Sensitive = false; _pauseEmulation.Sensitive = false;
_resumeEmulation.Sensitive = false; _resumeEmulation.Sensitive = false;
_fileTypesSubMenu.Visible = FileAssociationHelper.IsTypeAssociationSupported;
if (ConfigurationState.Instance.Ui.GuiColumns.FavColumn) _favToggle.Active = true; if (ConfigurationState.Instance.Ui.GuiColumns.FavColumn) _favToggle.Active = true;
if (ConfigurationState.Instance.Ui.GuiColumns.IconColumn) _iconToggle.Active = true; if (ConfigurationState.Instance.Ui.GuiColumns.IconColumn) _iconToggle.Active = true;
if (ConfigurationState.Instance.Ui.GuiColumns.AppColumn) _appToggle.Active = true; if (ConfigurationState.Instance.Ui.GuiColumns.AppColumn) _appToggle.Active = true;
@ -1500,6 +1502,30 @@ namespace Ryujinx.Ui
}); });
} }
private void InstallFileTypes_Pressed(object sender, EventArgs e)
{
if (FileAssociationHelper.Install())
{
GtkDialog.CreateInfoDialog("Install file types", "File types successfully installed!");
}
else
{
GtkDialog.CreateErrorDialog("Failed to install file types.");
}
}
private void UninstallFileTypes_Pressed(object sender, EventArgs e)
{
if (FileAssociationHelper.Uninstall())
{
GtkDialog.CreateInfoDialog("Uninstall file types", "File types successfully uninstalled!");
}
else
{
GtkDialog.CreateErrorDialog("Failed to uninstall file types.");
}
}
private void HandleRelaunch() private void HandleRelaunch()
{ {
if (_userChannelPersistence.PreviousIndex != -1 && _userChannelPersistence.ShouldRestart) if (_userChannelPersistence.PreviousIndex != -1 && _userChannelPersistence.ShouldRestart)

View file

@ -1,67 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.21.0 --> <!-- Generated with glade 3.40.0 -->
<interface> <interface>
<requires lib="gtk+" version="3.20"/> <requires lib="gtk+" version="3.20"/>
<object class="GtkApplicationWindow" id="_mainWin"> <object class="GtkApplicationWindow" id="_mainWin">
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="title" translatable="yes">Ryujinx</property> <property name="title" translatable="yes">Ryujinx</property>
<property name="window_position">center</property> <property name="window-position">center</property>
<child> <child>
<object class="GtkBox" id="_box"> <object class="GtkBox" id="_box">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="GtkMenuBar" id="_menuBar"> <object class="GtkMenuBar" id="_menuBar">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<child> <child>
<object class="GtkMenuItem" id="_fileMenu"> <object class="GtkMenuItem" id="_fileMenu">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="label" translatable="yes">File</property> <property name="label" translatable="yes">File</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
<child type="submenu"> <child type="submenu">
<object class="GtkMenu"> <object class="GtkMenu">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<child> <child>
<object class="GtkMenuItem" id="_loadApplicationFile"> <object class="GtkMenuItem" id="_loadApplicationFile">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="tooltip_text" translatable="yes">Open a file explorer to choose a Switch compatible file to load</property> <property name="tooltip-text" translatable="yes">Open a file explorer to choose a Switch compatible file to load</property>
<property name="label" translatable="yes">Load Application from File</property> <property name="label" translatable="yes">Load Application from File</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
<signal name="activate" handler="Load_Application_File" swapped="no"/> <signal name="activate" handler="Load_Application_File" swapped="no"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem" id="_loadApplicationFolder"> <object class="GtkMenuItem" id="_loadApplicationFolder">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="tooltip_text" translatable="yes">Open a file explorer to choose a Switch compatible, unpacked application to load</property> <property name="tooltip-text" translatable="yes">Open a file explorer to choose a Switch compatible, unpacked application to load</property>
<property name="label" translatable="yes">Load Unpacked Game</property> <property name="label" translatable="yes">Load Unpacked Game</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
<signal name="activate" handler="Load_Application_Folder" swapped="no"/> <signal name="activate" handler="Load_Application_Folder" swapped="no"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem" id="_appletMenu"> <object class="GtkMenuItem" id="_appletMenu">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="label" translatable="yes">Load Applet</property> <property name="label" translatable="yes">Load Applet</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
<child type="submenu"> <child type="submenu">
<object class="GtkMenu"> <object class="GtkMenu">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<child> <child>
<object class="GtkMenuItem" id="LoadMiiEditApplet"> <object class="GtkMenuItem" id="LoadMiiEditApplet">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="tooltip_text" translatable="yes">Open Mii Editor Applet in Standalone mode</property> <property name="tooltip-text" translatable="yes">Open Mii Editor Applet in Standalone mode</property>
<property name="label" translatable="yes">Mii Editor</property> <property name="label" translatable="yes">Mii Editor</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
<signal name="activate" handler="Load_Mii_Edit_Applet" swapped="no"/> <signal name="activate" handler="Load_Mii_Edit_Applet" swapped="no"/>
</object> </object>
</child> </child>
@ -72,42 +72,42 @@
<child> <child>
<object class="GtkSeparatorMenuItem"> <object class="GtkSeparatorMenuItem">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem" id="OpenRyuFolder"> <object class="GtkMenuItem" id="OpenRyuFolder">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="tooltip_text" translatable="yes">Open Ryujinx filesystem folder</property> <property name="tooltip-text" translatable="yes">Open Ryujinx filesystem folder</property>
<property name="label" translatable="yes">Open Ryujinx Folder</property> <property name="label" translatable="yes">Open Ryujinx Folder</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
<signal name="activate" handler="Open_Ryu_Folder" swapped="no"/> <signal name="activate" handler="Open_Ryu_Folder" swapped="no"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem" id="OpenLogsFolder"> <object class="GtkMenuItem" id="OpenLogsFolder">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="tooltip_text" translatable="yes">Opens the folder where logs are written to.</property> <property name="tooltip-text" translatable="yes">Opens the folder where logs are written to.</property>
<property name="label" translatable="yes">Open Logs Folder</property> <property name="label" translatable="yes">Open Logs Folder</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
<signal name="activate" handler="OpenLogsFolder_Pressed" swapped="no"/> <signal name="activate" handler="OpenLogsFolder_Pressed" swapped="no"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkSeparatorMenuItem"> <object class="GtkSeparatorMenuItem">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem" id="ExitMenuItem"> <object class="GtkMenuItem" id="ExitMenuItem">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="tooltip_text" translatable="yes">Exit Ryujinx</property> <property name="tooltip-text" translatable="yes">Exit Ryujinx</property>
<property name="label" translatable="yes">Exit</property> <property name="label" translatable="yes">Exit</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
<signal name="activate" handler="Exit_Pressed" swapped="no"/> <signal name="activate" handler="Exit_Pressed" swapped="no"/>
</object> </object>
</child> </child>
@ -118,144 +118,144 @@
<child> <child>
<object class="GtkMenuItem" id="_optionMenu"> <object class="GtkMenuItem" id="_optionMenu">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="label" translatable="yes">Options</property> <property name="label" translatable="yes">Options</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
<child type="submenu"> <child type="submenu">
<object class="GtkMenu"> <object class="GtkMenu">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<child> <child>
<object class="GtkMenuItem" id="_fullScreen"> <object class="GtkMenuItem" id="_fullScreen">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="label" translatable="yes">Enter Fullscreen</property> <property name="label" translatable="yes">Enter Fullscreen</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkCheckMenuItem" id="_startFullScreen"> <object class="GtkCheckMenuItem" id="_startFullScreen">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="label" translatable="yes">Start Games in Fullscreen Mode</property> <property name="label" translatable="yes">Start Games in Fullscreen Mode</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
<signal name="toggled" handler="StartFullScreen_Toggled" swapped="no"/> <signal name="toggled" handler="StartFullScreen_Toggled" swapped="no"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkCheckMenuItem" id="_showConsole"> <object class="GtkCheckMenuItem" id="_showConsole">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="label" translatable="yes">Show Log Console</property> <property name="label" translatable="yes">Show Log Console</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
<signal name="toggled" handler="ShowConsole_Toggled" swapped="no"/> <signal name="toggled" handler="ShowConsole_Toggled" swapped="no"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkSeparatorMenuItem"> <object class="GtkSeparatorMenuItem">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem" id="GUIColumns"> <object class="GtkMenuItem" id="GUIColumns">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="tooltip_text" translatable="yes">Select which GUI columns to enable</property> <property name="tooltip-text" translatable="yes">Select which GUI columns to enable</property>
<property name="label" translatable="yes">Enable GUI Columns</property> <property name="label" translatable="yes">Enable GUI Columns</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
<child type="submenu"> <child type="submenu">
<object class="GtkMenu"> <object class="GtkMenu">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<child> <child>
<object class="GtkCheckMenuItem" id="_favToggle"> <object class="GtkCheckMenuItem" id="_favToggle">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="tooltip_text" translatable="yes">Enable or Disable Favorite Games Column in the game list</property> <property name="tooltip-text" translatable="yes">Enable or Disable Favorite Games Column in the game list</property>
<property name="label" translatable="yes">Enable Favorite Games Column</property> <property name="label" translatable="yes">Enable Favorite Games Column</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkCheckMenuItem" id="_iconToggle"> <object class="GtkCheckMenuItem" id="_iconToggle">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="tooltip_text" translatable="yes">Enable or Disable Icon Column in the game list</property> <property name="tooltip-text" translatable="yes">Enable or Disable Icon Column in the game list</property>
<property name="label" translatable="yes">Enable Icon Column</property> <property name="label" translatable="yes">Enable Icon Column</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkCheckMenuItem" id="_appToggle"> <object class="GtkCheckMenuItem" id="_appToggle">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="tooltip_text" translatable="yes">Enable or Disable Title Name/ID Column in the game list</property> <property name="tooltip-text" translatable="yes">Enable or Disable Title Name/ID Column in the game list</property>
<property name="label" translatable="yes">Enable Title Name/ID Column</property> <property name="label" translatable="yes">Enable Title Name/ID Column</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkCheckMenuItem" id="_developerToggle"> <object class="GtkCheckMenuItem" id="_developerToggle">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="tooltip_text" translatable="yes">Enable or Disable Developer Column in the game list</property> <property name="tooltip-text" translatable="yes">Enable or Disable Developer Column in the game list</property>
<property name="label" translatable="yes">Enable Developer Column</property> <property name="label" translatable="yes">Enable Developer Column</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkCheckMenuItem" id="_versionToggle"> <object class="GtkCheckMenuItem" id="_versionToggle">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="tooltip_text" translatable="yes">Enable or Disable Version Column in the game list</property> <property name="tooltip-text" translatable="yes">Enable or Disable Version Column in the game list</property>
<property name="label" translatable="yes">Enable Version Column</property> <property name="label" translatable="yes">Enable Version Column</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkCheckMenuItem" id="_timePlayedToggle"> <object class="GtkCheckMenuItem" id="_timePlayedToggle">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="tooltip_text" translatable="yes">Enable or Disable Time Played Column in the game list</property> <property name="tooltip-text" translatable="yes">Enable or Disable Time Played Column in the game list</property>
<property name="label" translatable="yes">Enable Time Played Column</property> <property name="label" translatable="yes">Enable Time Played Column</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkCheckMenuItem" id="_lastPlayedToggle"> <object class="GtkCheckMenuItem" id="_lastPlayedToggle">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="tooltip_text" translatable="yes">Enable or Disable Last Played Column in the game list</property> <property name="tooltip-text" translatable="yes">Enable or Disable Last Played Column in the game list</property>
<property name="label" translatable="yes">Enable Last Played Column</property> <property name="label" translatable="yes">Enable Last Played Column</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkCheckMenuItem" id="_fileExtToggle"> <object class="GtkCheckMenuItem" id="_fileExtToggle">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="tooltip_text" translatable="yes">Enable or Disable file extension column in the game list</property> <property name="tooltip-text" translatable="yes">Enable or Disable file extension column in the game list</property>
<property name="label" translatable="yes">Enable File Ext Column</property> <property name="label" translatable="yes">Enable File Ext Column</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkCheckMenuItem" id="_fileSizeToggle"> <object class="GtkCheckMenuItem" id="_fileSizeToggle">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="tooltip_text" translatable="yes">Enable or Disable File Size Column in the game list</property> <property name="tooltip-text" translatable="yes">Enable or Disable File Size Column in the game list</property>
<property name="label" translatable="yes">Enable File Size Column</property> <property name="label" translatable="yes">Enable File Size Column</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkCheckMenuItem" id="_pathToggle"> <object class="GtkCheckMenuItem" id="_pathToggle">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="tooltip_text" translatable="yes">Enable or Disable Path Column in the game list</property> <property name="tooltip-text" translatable="yes">Enable or Disable Path Column in the game list</property>
<property name="label" translatable="yes">Enable Path Column</property> <property name="label" translatable="yes">Enable Path Column</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
</object> </object>
</child> </child>
</object> </object>
@ -265,26 +265,26 @@
<child> <child>
<object class="GtkSeparatorMenuItem"> <object class="GtkSeparatorMenuItem">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem" id="SettingsMenu"> <object class="GtkMenuItem" id="SettingsMenu">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="tooltip_text" translatable="yes">Open settings window</property> <property name="tooltip-text" translatable="yes">Open settings window</property>
<property name="label" translatable="yes">Settings</property> <property name="label" translatable="yes">Settings</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
<signal name="activate" handler="Settings_Pressed" swapped="no"/> <signal name="activate" handler="Settings_Pressed" swapped="no"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem" id="_manageUserProfiles"> <object class="GtkMenuItem" id="_manageUserProfiles">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="tooltip_text" translatable="yes">Open User Profiles Manager window</property> <property name="tooltip-text" translatable="yes">Open User Profiles Manager window</property>
<property name="label" translatable="yes">Manage User Profiles</property> <property name="label" translatable="yes">Manage User Profiles</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
<signal name="activate" handler="ManageUserProfiles_Pressed" swapped="no"/> <signal name="activate" handler="ManageUserProfiles_Pressed" swapped="no"/>
</object> </object>
</child> </child>
@ -295,74 +295,74 @@
<child> <child>
<object class="GtkMenuItem" id="_actionMenu"> <object class="GtkMenuItem" id="_actionMenu">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="label" translatable="yes">Actions</property> <property name="label" translatable="yes">Actions</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
<child type="submenu"> <child type="submenu">
<object class="GtkMenu"> <object class="GtkMenu">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<child> <child>
<object class="GtkMenuItem" id="_pauseEmulation"> <object class="GtkMenuItem" id="_pauseEmulation">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="tooltip_text" translatable="yes">Pause emulation</property> <property name="tooltip-text" translatable="yes">Pause emulation</property>
<property name="label" translatable="yes">Pause Emulation</property> <property name="label" translatable="yes">Pause Emulation</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
<signal name="activate" handler="PauseEmulation_Pressed" swapped="no"/> <signal name="activate" handler="PauseEmulation_Pressed" swapped="no"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem" id="_resumeEmulation"> <object class="GtkMenuItem" id="_resumeEmulation">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="tooltip_text" translatable="yes">Resume emulation</property> <property name="tooltip-text" translatable="yes">Resume emulation</property>
<property name="label" translatable="yes">Resume Emulation</property> <property name="label" translatable="yes">Resume Emulation</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
<signal name="activate" handler="ResumeEmulation_Pressed" swapped="no"/> <signal name="activate" handler="ResumeEmulation_Pressed" swapped="no"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem" id="_stopEmulation"> <object class="GtkMenuItem" id="_stopEmulation">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="tooltip_text" translatable="yes">Stop emulation of the current game and return to game selection</property> <property name="tooltip-text" translatable="yes">Stop emulation of the current game and return to game selection</property>
<property name="label" translatable="yes">Stop Emulation</property> <property name="label" translatable="yes">Stop Emulation</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
<signal name="activate" handler="StopEmulation_Pressed" swapped="no"/> <signal name="activate" handler="StopEmulation_Pressed" swapped="no"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkSeparatorMenuItem"> <object class="GtkSeparatorMenuItem">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem" id="_simulateWakeUpMessage"> <object class="GtkMenuItem" id="_simulateWakeUpMessage">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="tooltip_text" translatable="yes">Simulate a Wake-up Message</property> <property name="tooltip-text" translatable="yes">Simulate a Wake-up Message</property>
<property name="label" translatable="yes">Simulate Wake-up Message</property> <property name="label" translatable="yes">Simulate Wake-up Message</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
<signal name="activate" handler="Simulate_WakeUp_Message_Pressed" swapped="no"/> <signal name="activate" handler="Simulate_WakeUp_Message_Pressed" swapped="no"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem" id="_scanAmiibo"> <object class="GtkMenuItem" id="_scanAmiibo">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="tooltip_text" translatable="yes">Scan an Amiibo</property> <property name="tooltip-text" translatable="yes">Scan an Amiibo</property>
<property name="label" translatable="yes">Scan an Amiibo</property> <property name="label" translatable="yes">Scan an Amiibo</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
<signal name="activate" handler="Scan_Amiibo" swapped="no"/> <signal name="activate" handler="Scan_Amiibo" swapped="no"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem" id="_takeScreenshot"> <object class="GtkMenuItem" id="_takeScreenshot">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="tooltip_text" translatable="yes">Take a screenshot</property> <property name="tooltip-text" translatable="yes">Take a screenshot</property>
<property name="label" translatable="yes">Take Screenshot</property> <property name="label" translatable="yes">Take Screenshot</property>
<signal name="activate" handler="Take_Screenshot" swapped="no"/> <signal name="activate" handler="Take_Screenshot" swapped="no"/>
</object> </object>
@ -370,16 +370,16 @@
<child> <child>
<object class="GtkMenuItem" id="_hideUi"> <object class="GtkMenuItem" id="_hideUi">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="label" translatable="yes">Hide UI (SHOWUIKEY to show)</property> <property name="label" translatable="yes">Hide UI (SHOWUIKEY to show)</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
<signal name="activate" handler="HideUi_Pressed" swapped="no"/> <signal name="activate" handler="HideUi_Pressed" swapped="no"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem" id="_manageCheats"> <object class="GtkMenuItem" id="_manageCheats">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="label" translatable="yes">Manage Cheats</property> <property name="label" translatable="yes">Manage Cheats</property>
<signal name="activate" handler="ManageCheats_Pressed" swapped="no"/> <signal name="activate" handler="ManageCheats_Pressed" swapped="no"/>
</object> </object>
@ -391,38 +391,38 @@
<child> <child>
<object class="GtkMenuItem" id="_toolsMenu"> <object class="GtkMenuItem" id="_toolsMenu">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="label" translatable="yes">Tools</property> <property name="label" translatable="yes">Tools</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
<child type="submenu"> <child type="submenu">
<object class="GtkMenu"> <object class="GtkMenu">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<child> <child>
<object class="GtkMenuItem" id="FirmwareSubMenu"> <object class="GtkMenuItem" id="FirmwareSubMenu">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="label" translatable="yes">Install Firmware</property> <property name="label" translatable="yes">Install Firmware</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
<child type="submenu"> <child type="submenu">
<object class="GtkMenu"> <object class="GtkMenu">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<child> <child>
<object class="GtkMenuItem" id="_firmwareInstallFile"> <object class="GtkMenuItem" id="_firmwareInstallFile">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="label" translatable="yes">Install a firmware from XCI or ZIP</property> <property name="label" translatable="yes">Install a firmware from XCI or ZIP</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
<signal name="activate" handler="Installer_File_Pressed" swapped="no"/> <signal name="activate" handler="Installer_File_Pressed" swapped="no"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem" id="_firmwareInstallDirectory"> <object class="GtkMenuItem" id="_firmwareInstallDirectory">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="label" translatable="yes">Install a firmware from a directory</property> <property name="label" translatable="yes">Install a firmware from a directory</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
<signal name="activate" handler="Installer_Directory_Pressed" swapped="no"/> <signal name="activate" handler="Installer_Directory_Pressed" swapped="no"/>
</object> </object>
</child> </child>
@ -430,6 +430,36 @@
</child> </child>
</object> </object>
</child> </child>
<child>
<object class="GtkMenuItem" id="_fileTypesSubMenu">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Manage file types</property>
<property name="use-underline">True</property>
<child type="submenu">
<object class="GtkMenu">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkMenuItem" id="_installFileTypes">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Install file types</property>
<signal name="activate" handler="InstallFileTypes_Pressed" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="_uninstallFileTypes">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Uninstall file types</property>
<signal name="activate" handler="UninstallFileTypes_Pressed" swapped="no"/>
</object>
</child>
</object>
</child>
</object>
</child>
</object> </object>
</child> </child>
</object> </object>
@ -437,36 +467,36 @@
<child> <child>
<object class="GtkMenuItem" id="HelpMenu"> <object class="GtkMenuItem" id="HelpMenu">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="label" translatable="yes">Help</property> <property name="label" translatable="yes">Help</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
<child type="submenu"> <child type="submenu">
<object class="GtkMenu"> <object class="GtkMenu">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<child> <child>
<object class="GtkMenuItem" id="UpdateMenuItem"> <object class="GtkMenuItem" id="UpdateMenuItem">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="tooltip_text" translatable="yes">Check for updates to Ryujinx</property> <property name="tooltip-text" translatable="yes">Check for updates to Ryujinx</property>
<property name="label" translatable="yes">Check for Updates</property> <property name="label" translatable="yes">Check for Updates</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
<signal name="activate" handler="Update_Pressed" swapped="no"/> <signal name="activate" handler="Update_Pressed" swapped="no"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkSeparatorMenuItem"> <object class="GtkSeparatorMenuItem">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem" id="About"> <object class="GtkMenuItem" id="About">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="tooltip_text" translatable="yes">Open about window</property> <property name="tooltip-text" translatable="yes">Open about window</property>
<property name="label" translatable="yes">About</property> <property name="label" translatable="yes">About</property>
<property name="use_underline">True</property> <property name="use-underline">True</property>
<signal name="activate" handler="About_Pressed" swapped="no"/> <signal name="activate" handler="About_Pressed" swapped="no"/>
</object> </object>
</child> </child>
@ -484,24 +514,24 @@
<child> <child>
<object class="GtkBox" id="_mainBox"> <object class="GtkBox" id="_mainBox">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="GtkBox" id="_viewBox"> <object class="GtkBox" id="_viewBox">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="GtkScrolledWindow" id="_gameTableWindow"> <object class="GtkScrolledWindow" id="_gameTableWindow">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can-focus">True</property>
<property name="shadow_type">in</property> <property name="shadow-type">in</property>
<child> <child>
<object class="GtkTreeView" id="_gameTable"> <object class="GtkTreeView" id="_gameTable">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can-focus">True</property>
<property name="reorderable">True</property> <property name="reorderable">True</property>
<property name="hover_selection">True</property> <property name="hover-selection">True</property>
<signal name="row-activated" handler="Row_Activated" swapped="no"/> <signal name="row-activated" handler="Row_Activated" swapped="no"/>
<child internal-child="selection"> <child internal-child="selection">
<object class="GtkTreeSelection" id="_gameTableSelection"/> <object class="GtkTreeSelection" id="_gameTableSelection"/>
@ -524,24 +554,24 @@
</child> </child>
<child> <child>
<object class="GtkBox" id="_footerBox"> <object class="GtkBox" id="_footerBox">
<property name="height_request">19</property> <property name="height-request">19</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<child> <child>
<object class="GtkBox" id="_listStatusBox"> <object class="GtkBox" id="_listStatusBox">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<child> <child>
<object class="GtkEventBox"> <object class="GtkEventBox">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="margin_left">5</property> <property name="margin-left">5</property>
<signal name="button-release-event" handler="RefreshList_Pressed" swapped="no"/> <signal name="button-release-event" handler="RefreshList_Pressed" swapped="no"/>
<child> <child>
<object class="GtkImage"> <object class="GtkImage">
<property name="name">RefreshList</property> <property name="name">RefreshList</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="stock">gtk-refresh</property> <property name="stock">gtk-refresh</property>
</object> </object>
</child> </child>
@ -555,11 +585,11 @@
<child> <child>
<object class="GtkLabel" id="_progressLabel"> <object class="GtkLabel" id="_progressLabel">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="margin_left">10</property> <property name="margin-left">10</property>
<property name="margin_right">5</property> <property name="margin-right">5</property>
<property name="margin_top">2</property> <property name="margin-top">2</property>
<property name="margin_bottom">2</property> <property name="margin-bottom">2</property>
<property name="label" translatable="yes">0/0 Games Loaded</property> <property name="label" translatable="yes">0/0 Games Loaded</property>
</object> </object>
<packing> <packing>
@ -570,13 +600,13 @@
</child> </child>
<child> <child>
<object class="GtkProgressBar" id="_progressBar"> <object class="GtkProgressBar" id="_progressBar">
<property name="width_request">200</property> <property name="width-request">200</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="halign">start</property> <property name="halign">start</property>
<property name="margin_left">10</property> <property name="margin-left">10</property>
<property name="margin_right">5</property> <property name="margin-right">5</property>
<property name="margin_bottom">6</property> <property name="margin-bottom">6</property>
</object> </object>
<packing> <packing>
<property name="expand">True</property> <property name="expand">True</property>
@ -594,19 +624,19 @@
<child> <child>
<object class="GtkBox" id="_statusBar"> <object class="GtkBox" id="_statusBar">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<child> <child>
<object class="GtkEventBox"> <object class="GtkEventBox">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<signal name="button-release-event" handler="VSyncStatus_Clicked" swapped="no"/> <signal name="button-release-event" handler="VSyncStatus_Clicked" swapped="no"/>
<child> <child>
<object class="GtkLabel" id="_vSyncStatus"> <object class="GtkLabel" id="_vSyncStatus">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="halign">start</property> <property name="halign">start</property>
<property name="margin_left">5</property> <property name="margin-left">5</property>
<property name="margin_right">5</property> <property name="margin-right">5</property>
<property name="label" translatable="yes">VSync</property> <property name="label" translatable="yes">VSync</property>
</object> </object>
</child> </child>
@ -620,7 +650,7 @@
<child> <child>
<object class="GtkSeparator"> <object class="GtkSeparator">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@ -631,15 +661,15 @@
<child> <child>
<object class="GtkEventBox"> <object class="GtkEventBox">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<signal name="button-release-event" handler="DockedMode_Clicked" swapped="no"/> <signal name="button-release-event" handler="DockedMode_Clicked" swapped="no"/>
<child> <child>
<object class="GtkLabel" id="_dockedMode"> <object class="GtkLabel" id="_dockedMode">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="halign">start</property> <property name="halign">start</property>
<property name="margin_left">5</property> <property name="margin-left">5</property>
<property name="margin_right">5</property> <property name="margin-right">5</property>
</object> </object>
</child> </child>
</object> </object>
@ -652,7 +682,7 @@
<child> <child>
<object class="GtkSeparator"> <object class="GtkSeparator">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@ -663,15 +693,15 @@
<child> <child>
<object class="GtkEventBox"> <object class="GtkEventBox">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<signal name="button-release-event" handler="VolumeStatus_Clicked" swapped="no"/> <signal name="button-release-event" handler="VolumeStatus_Clicked" swapped="no"/>
<child> <child>
<object class="GtkLabel" id="_volumeStatus"> <object class="GtkLabel" id="_volumeStatus">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="halign">start</property> <property name="halign">start</property>
<property name="margin_left">5</property> <property name="margin-left">5</property>
<property name="margin_right">5</property> <property name="margin-right">5</property>
</object> </object>
</child> </child>
</object> </object>
@ -684,7 +714,7 @@
<child> <child>
<object class="GtkSeparator"> <object class="GtkSeparator">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@ -695,15 +725,15 @@
<child> <child>
<object class="GtkEventBox"> <object class="GtkEventBox">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<signal name="button-release-event" handler="AspectRatio_Clicked" swapped="no"/> <signal name="button-release-event" handler="AspectRatio_Clicked" swapped="no"/>
<child> <child>
<object class="GtkLabel" id="_aspectRatio"> <object class="GtkLabel" id="_aspectRatio">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="halign">start</property> <property name="halign">start</property>
<property name="margin_left">5</property> <property name="margin-left">5</property>
<property name="margin_right">5</property> <property name="margin-right">5</property>
</object> </object>
</child> </child>
</object> </object>
@ -716,7 +746,7 @@
<child> <child>
<object class="GtkSeparator"> <object class="GtkSeparator">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@ -727,10 +757,10 @@
<child> <child>
<object class="GtkLabel" id="_gameStatus"> <object class="GtkLabel" id="_gameStatus">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="halign">start</property> <property name="halign">start</property>
<property name="margin_left">5</property> <property name="margin-left">5</property>
<property name="margin_right">5</property> <property name="margin-right">5</property>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@ -741,7 +771,7 @@
<child> <child>
<object class="GtkSeparator"> <object class="GtkSeparator">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@ -752,10 +782,10 @@
<child> <child>
<object class="GtkLabel" id="_fifoStatus"> <object class="GtkLabel" id="_fifoStatus">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="halign">start</property> <property name="halign">start</property>
<property name="margin_left">5</property> <property name="margin-left">5</property>
<property name="margin_right">5</property> <property name="margin-right">5</property>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@ -766,7 +796,7 @@
<child> <child>
<object class="GtkSeparator"> <object class="GtkSeparator">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@ -777,10 +807,10 @@
<child> <child>
<object class="GtkLabel" id="_gpuBackend"> <object class="GtkLabel" id="_gpuBackend">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="halign">start</property> <property name="halign">start</property>
<property name="margin_left">5</property> <property name="margin-left">5</property>
<property name="margin_right">5</property> <property name="margin-right">5</property>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@ -791,7 +821,7 @@
<child> <child>
<object class="GtkSeparator"> <object class="GtkSeparator">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@ -802,10 +832,10 @@
<child> <child>
<object class="GtkLabel" id="_gpuName"> <object class="GtkLabel" id="_gpuName">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="halign">start</property> <property name="halign">start</property>
<property name="margin_left">5</property> <property name="margin-left">5</property>
<property name="margin_right">5</property> <property name="margin-right">5</property>
</object> </object>
<packing> <packing>
<property name="expand">True</property> <property name="expand">True</property>
@ -823,12 +853,12 @@
<child> <child>
<object class="GtkBox"> <object class="GtkBox">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="margin_left">5</property> <property name="margin-left">5</property>
<child> <child>
<object class="GtkLabel"> <object class="GtkLabel">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="label" translatable="yes">System Version</property> <property name="label" translatable="yes">System Version</property>
</object> </object>
<packing> <packing>
@ -839,16 +869,16 @@
</child> </child>
<child> <child>
<object class="GtkLabel" id="_firmwareVersionLabel"> <object class="GtkLabel" id="_firmwareVersionLabel">
<property name="width_request">50</property> <property name="width-request">50</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="margin_left">5</property> <property name="margin-left">5</property>
<property name="margin_right">5</property> <property name="margin-right">5</property>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">True</property>
<property name="pack_type">end</property> <property name="pack-type">end</property>
<property name="position">1</property> <property name="position">1</property>
</packing> </packing>
</child> </child>
@ -856,15 +886,15 @@
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">True</property>
<property name="pack_type">end</property> <property name="pack-type">end</property>
<property name="position">4</property> <property name="position">4</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkLabel" id="_loadingStatusLabel"> <object class="GtkLabel" id="_loadingStatusLabel">
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="margin_left">5</property> <property name="margin-left">5</property>
<property name="margin_right">5</property> <property name="margin-right">5</property>
<property name="label" translatable="yes">0/0 </property> <property name="label" translatable="yes">0/0 </property>
</object> </object>
<packing> <packing>
@ -875,11 +905,11 @@
</child> </child>
<child> <child>
<object class="GtkProgressBar" id="_loadingStatusBar"> <object class="GtkProgressBar" id="_loadingStatusBar">
<property name="width_request">200</property> <property name="width-request">200</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="margin_left">5</property> <property name="margin-left">5</property>
<property name="margin_right">5</property> <property name="margin-right">5</property>
<property name="margin_bottom">6</property> <property name="margin-bottom">6</property>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@ -903,8 +933,5 @@
</child> </child>
</object> </object>
</child> </child>
<child type="titlebar">
<placeholder/>
</child>
</object> </object>
</interface> </interface>