Compare commits

...

4 Commits

Author SHA1 Message Date
ranidspace
153d632ee2 Fix the canary CI breaking caused by #110 (#121)
whoops

Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/121
2026-05-30 21:02:30 +00:00
Babib3l
824643e143 Fix : Fix controller Stick visualizer perfomance (#119)
This PR aims to fix a bug inside the settings window that caused the Controller Stick visualizer to run at extremely degraded performance when the selected profile had a rainbow LED configuration:
Old behaviour : <video src="/attachments/1915ab74-6e1b-4e2f-9182-820cbed5359b" title="Screen Recording 2026-05-30 105859" controls></video>
New / updated behaviour : <video src="/attachments/dd293402-19e7-439e-8aa6-114d4ee22404" title="Screen Recording 2026-05-30 110338" controls></video>

The issue was that the input settings page automatically subscribed controllers to rainbow LED updates when a saved profile with rainbow LEDs enabled was loaded.
Reopening input settings on a non-default controller profile could immediately start the rainbow LED update loop from the settings UI, which caused the stick visualizer to become sluggish or jittery on affected controllers. The preview handler is now only registered when the rainbow LED option is changed in the settings UI, and it uses a stable handler so duplicate callbacks are not stacked.

Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/119
2026-05-30 20:33:50 +00:00
ranidspace
7be1708146 AppImage fixes and improvements (#110)
Currently the appimages work fine, however I realized there's some room to improve on following the standards and a bit of cleaning.

AppImages now follow the linux FHS and a `.DirIcon` to follow the Spec closer, along with changing the icon and desktop file names (the resulting AppImage will have the same name, it's only used internally)

Metadata has been added, it helps with applications meant to manage appimages, as well as a future possible auto-updater.

The icon has been replaced temporarily as we wait for the updated one, just taken from the windows .ico. The `.DirIcon` needs to be a PNG, however `app.ryujinx.Ryujinx.png` can be an svg as well for some reason.

The launcher script may not need to exist (gamemode and envvars), but as to not break anything the important things have been kept.

The commits messages of this PR contain information as to why each change was made.

Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/110
2026-05-30 20:31:49 +00:00
Babib3l
279c4cf3b4 Fix hotkey labels (#118)
Fixes the hotkeys settings page after https://git.ryujinx.app/projects/Ryubing/pulls/13 broke it

Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/118
2026-05-30 20:27:44 +00:00
11 changed files with 86 additions and 55 deletions

View File

@@ -68,7 +68,7 @@ jobs:
sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place '/^Name=Ryujinx$/s/Name=Ryujinx/Name=Ryujinx-Canary/' distribution/linux/Ryujinx.desktop
sed -r --in-place '/^Name=Ryujinx$/s/Name=Ryujinx/Name=Ryujinx-Canary/' distribution/linux/app.ryujinx.Ryujinx.desktop
shell: bash
- name: Create output dir

View File

@@ -1,23 +1,11 @@
#!/bin/sh
#!/usr/bin/env sh
SCRIPT_DIR=$(dirname "$(realpath "$0")")
if [ -f "$SCRIPT_DIR/Ryujinx.Headless.SDL3" ]; then
RYUJINX_BIN="Ryujinx.Headless.SDL3"
fi
if [ -f "$SCRIPT_DIR/Ryujinx" ]; then
RYUJINX_BIN="Ryujinx"
fi
if [ -z "$RYUJINX_BIN" ]; then
exit 1
fi
COMMAND="env LANG=C.UTF-8 DOTNET_EnableAlternateStackCheck=1"
if command -v gamemoderun > /dev/null 2>&1; then
COMMAND="$COMMAND gamemoderun"
fi
exec $COMMAND "$SCRIPT_DIR/$RYUJINX_BIN" "$@"
exec $COMMAND "$SCRIPT_DIR/Ryujinx" "$@"

View File

@@ -1,14 +1,12 @@
[Desktop Entry]
Version=1.0
Version=1.5
Name=Ryujinx
Type=Application
Icon=Ryujinx
Icon=app.ryujinx.Ryujinx
Exec=Ryujinx.sh %f
Comment=A Nintendo Switch Emulator
GenericName=Nintendo Switch Emulator
Terminal=false
Categories=Game;Emulator;
MimeType=application/x-nx-nca;application/x-nx-nro;application/x-nx-nso;application/x-nx-nsp;application/x-nx-xci;
Keywords=Switch;Nintendo;Emulator;
StartupWMClass=Ryujinx
PrefersNonDefaultGPU=true

View File

@@ -1,3 +0,0 @@
#!/bin/sh
CURRENTDIR="$(readlink -f "$(dirname "$0")")"
exec "$CURRENTDIR"/usr/bin/Ryujinx.sh "$@"

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop-application">
<id>app.ryujinx.Ryujinx</id>
<metadata_license>MIT</metadata_license>
<project_license>MIT</project_license>
<name>Ryujinx</name>
<summary>Nintendo Switch 1 emulator written in C#</summary>
<description>
<p>Ryujinx is an open-source Nintendo Switch emulator, originally created by gdkchan, written in C#.</p>
</description>
<launchable type="desktop-id">app.ryujinx.Ryujinx.desktop</launchable>
<url type="homepage">https://ryujinx.app/</url>
<developer id="app.ryujinx">
<name>Ryubing</name>
</developer>
<screenshots>
<screenshot type="default">
<image>https://git.ryujinx.app/projects/Ryubing/raw/branch/master/docs/shell.png</image>
</screenshot>
</screenshots>
<provides>
<id>app.ryujinx.Ryujinx.desktop</id>
</provides>
<content_rating type="oars-1.1" />
</component>

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/usr/bin/env sh
set -eu
ROOTDIR="$(readlink -f "$(dirname "$0")")"/../../../
@@ -7,20 +7,33 @@ cd "$ROOTDIR"
BUILDDIR=${BUILDDIR:-publish}
OUTDIR=${OUTDIR:-publish_appimage}
# AppStream
rm -rf AppDir
mkdir -p AppDir/usr/bin
mkdir -p AppDir/usr/lib AppDir/usr/bin
mkdir -p AppDir/usr/share/metainfo AppDir/usr/share/applications
mkdir -p AppDir/usr/share/icons/hicolor/256x256/apps/
cp distribution/linux/Ryujinx.desktop AppDir/Ryujinx.desktop
cp distribution/linux/appimage/AppRun AppDir/AppRun
cp distribution/misc/Logo.svg AppDir/Ryujinx.svg
cp -r "$BUILDDIR"/* AppDir/usr/lib/
cp distribution/linux/appimage/app.ryujinx.Ryujinx.appdata.xml AppDir/usr/share/metainfo/app.ryujinx.Ryujinx.appdata.xml
cp distribution/linux/app.ryujinx.Ryujinx.desktop AppDir/usr/share/applications/app.ryujinx.Ryujinx.desktop
cp distribution/misc/Logo.png AppDir/usr/share/icons/hicolor/256x256/apps/app.ryujinx.Ryujinx.png
ln -s ../lib/Ryujinx AppDir/usr/bin/Ryujinx
cp -r "$BUILDDIR"/* AppDir/usr/bin/
# AppImage Root
ln -s ./usr/share/applications/app.ryujinx.Ryujinx.desktop AppDir/app.ryujinx.Ryujinx.desktop
ln -s ./usr/share/icons/hicolor/256x256/apps/app.ryujinx.Ryujinx.png AppDir/.DirIcon
ln -s ./usr/share/icons/hicolor/256x256/apps/app.ryujinx.Ryujinx.png AppDir/app.ryujinx.Ryujinx.png
ln -s ./usr/lib/Ryujinx.sh AppDir/AppRun
# Ensure necessary bins are set as executable
chmod +x AppDir/AppRun AppDir/usr/bin/Ryujinx*
mkdir -p "$OUTDIR"
# The "-n" flag removes the appstream checks during build, in case the main website is down.
# Run "appstreamcli validate --explain AppDir/usr/share/metainfo/app.ryujinx.Ryujinx.appdata.xml" to check manually
appimagetool --appimage-extract-and-run -n --comp zstd --mksquashfs-opt -Xcompression-level --mksquashfs-opt 21 \
AppDir "$OUTDIR"/Ryujinx.AppImage
AppDir "$OUTDIR"/Ryujinx.AppImage

BIN
distribution/misc/Logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 1.2 MiB

View File

@@ -6,6 +6,7 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using Key = Ryujinx.Input.Key;
using HidKey = Ryujinx.Common.Configuration.Hid.Key;
namespace Ryujinx.Ava.UI.Helpers
{
@@ -55,6 +56,9 @@ namespace Ryujinx.Ava.UI.Helpers
Key key => KeyboardLayoutLocaleHelper.TryGetSemanticLabel(key, out string localizedKeyLabel)
? localizedKeyLabel
: key.ToString(),
HidKey key => KeyboardLayoutLocaleHelper.TryGetSemanticLabel((Key)(int)key, out string localizedHidKeyLabel)
? localizedHidKeyLabel
: key.ToString(),
PhysicalKey physicalKey => PhysicalKeyLabelHelper.GetDisplayString(physicalKey),
GamepadInputId gamepadInputId => GetLocalizedMappedValue(gamepadInputId, _gamepadInputIdMap),
StickInputId stickInputId => GetLocalizedMappedValue(stickInputId, _stickInputIdMap),

View File

@@ -2,6 +2,7 @@ using Avalonia.Svg.Skia;
using CommunityToolkit.Mvvm.ComponentModel;
using Ryujinx.Ava.UI.Models.Input;
using Ryujinx.Ava.UI.Views.Input;
using Ryujinx.Common.Helper;
using Ryujinx.Common.Utilities;
using Ryujinx.UI.Views.Input;
@@ -59,32 +60,46 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
public partial SvgImage Image { get; set; }
public InputViewModel ParentModel { get; }
private readonly RefEvent<System.Drawing.Color>.Handler _rainbowLedHandler;
public ControllerInputViewModel(InputViewModel model, GamepadInputConfig config, StickVisualizer visualizer)
{
ParentModel = model;
Visualizer = visualizer;
_rainbowLedHandler = SetRainbowLed;
model.NotifyChangesEvent += OnParentModelChanged;
OnParentModelChanged();
config.PropertyChanged += (_, args) =>
{
if (args.PropertyName is nameof(Config.UseRainbowLed))
{
if (Config is { UseRainbowLed: true, TurnOffLed: false, EnableLedChanging: true })
Rainbow.Updated += (ref color) => ParentModel.SelectedGamepad.SetLed((uint)color.ToArgb());
else
{
Rainbow.Reset();
if (Config.TurnOffLed)
ParentModel.SelectedGamepad.ClearLed();
else
ParentModel.SelectedGamepad.SetLed(Config.LedColor.ToUInt32());
}
}
};
config.PropertyChanged += OnConfigPropertyChanged;
Config = config;
}
private void OnConfigPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs args)
{
if (args.PropertyName is nameof(Config.UseRainbowLed))
{
if (Config is { UseRainbowLed: true, TurnOffLed: false, EnableLedChanging: true })
{
Rainbow.Updated -= _rainbowLedHandler;
Rainbow.Updated += _rainbowLedHandler;
}
else
{
Rainbow.Reset();
if (Config.TurnOffLed)
ParentModel.SelectedGamepad.ClearLed();
else
ParentModel.SelectedGamepad.SetLed(Config.LedColor.ToUInt32());
}
}
}
private void SetRainbowLed(ref System.Drawing.Color color)
{
ParentModel.SelectedGamepad.SetLed((uint)color.ToArgb());
}
public async void ShowMotionConfig()
{
await MotionInputView.Show(this);

View File

@@ -23,7 +23,6 @@ using Ryujinx.Input.SDL3;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text.Json;
@@ -81,10 +80,6 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
field = value;
if ((field?.Features & GamepadFeaturesFlag.Led) != 0 &&
ConfigViewModel is ControllerInputViewModel { Config.UseRainbowLed: true })
Rainbow.Updated += (ref Color color) => field.SetLed((uint)color.ToArgb());
OnPropertiesChanged(nameof(HasLed), nameof(CanClearLed));
}
}