Add custom refresh rate mode to VSync option

This commit is contained in:
jcm
2024-11-09 15:13:48 -06:00
committed by KeatonTheBot
parent 86f2327468
commit 5d24fd119d
30 changed files with 718 additions and 132 deletions
+32 -6
View File
@@ -5,13 +5,13 @@ namespace Ryujinx.Ava.UI.Models.Input
{
public class HotkeyConfig : BaseModel
{
private Key _toggleVsync;
public Key ToggleVsync
private Key _toggleVSyncMode;
public Key ToggleVSyncMode
{
get => _toggleVsync;
get => _toggleVSyncMode;
set
{
_toggleVsync = value;
_toggleVSyncMode = value;
OnPropertyChanged();
}
}
@@ -104,11 +104,33 @@ namespace Ryujinx.Ava.UI.Models.Input
}
}
private Key _customVSyncIntervalIncrement;
public Key CustomVSyncIntervalIncrement
{
get => _customVSyncIntervalIncrement;
set
{
_customVSyncIntervalIncrement = value;
OnPropertyChanged();
}
}
private Key _customVSyncIntervalDecrement;
public Key CustomVSyncIntervalDecrement
{
get => _customVSyncIntervalDecrement;
set
{
_customVSyncIntervalDecrement = value;
OnPropertyChanged();
}
}
public HotkeyConfig(KeyboardHotkeys config)
{
if (config != null)
{
ToggleVsync = config.ToggleVsync;
ToggleVSyncMode = config.ToggleVSyncMode;
Screenshot = config.Screenshot;
ShowUI = config.ShowUI;
Pause = config.Pause;
@@ -117,6 +139,8 @@ namespace Ryujinx.Ava.UI.Models.Input
ResScaleDown = config.ResScaleDown;
VolumeUp = config.VolumeUp;
VolumeDown = config.VolumeDown;
CustomVSyncIntervalIncrement = config.CustomVSyncIntervalIncrement;
CustomVSyncIntervalDecrement = config.CustomVSyncIntervalDecrement;
}
}
@@ -124,7 +148,7 @@ namespace Ryujinx.Ava.UI.Models.Input
{
var config = new KeyboardHotkeys
{
ToggleVsync = ToggleVsync,
ToggleVSyncMode = ToggleVSyncMode,
Screenshot = Screenshot,
ShowUI = ShowUI,
Pause = Pause,
@@ -133,6 +157,8 @@ namespace Ryujinx.Ava.UI.Models.Input
ResScaleDown = ResScaleDown,
VolumeUp = VolumeUp,
VolumeDown = VolumeDown,
CustomVSyncIntervalIncrement = CustomVSyncIntervalIncrement,
CustomVSyncIntervalDecrement = CustomVSyncIntervalDecrement,
};
return config;
@@ -4,16 +4,16 @@ namespace Ryujinx.Ava.UI.Models
{
internal class StatusUpdatedEventArgs : EventArgs
{
public bool VSyncEnabled { get; }
public string VSyncMode { get; }
public string VolumeStatus { get; }
public string AspectRatio { get; }
public string DockedMode { get; }
public string FifoStatus { get; }
public string GameStatus { get; }
public StatusUpdatedEventArgs(bool vSyncEnabled, string volumeStatus, string dockedMode, string aspectRatio, string gameStatus, string fifoStatus)
public StatusUpdatedEventArgs(string vSyncMode, string volumeStatus, string dockedMode, string aspectRatio, string gameStatus, string fifoStatus)
{
VSyncEnabled = vSyncEnabled;
VSyncMode = vSyncMode;
VolumeStatus = volumeStatus;
DockedMode = dockedMode;
AspectRatio = aspectRatio;
@@ -60,6 +60,7 @@ namespace Ryujinx.Ava.UI.ViewModels
private string _searchText;
private Timer _searchTimer;
private string _dockedStatusText;
private string _vSyncModeText;
private string _fifoStatusText;
private string _gameStatusText;
private string _volumeStatusText;
@@ -75,7 +76,7 @@ namespace Ryujinx.Ava.UI.ViewModels
private bool _showStatusSeparator;
private Brush _progressBarForegroundColor;
private Brush _progressBarBackgroundColor;
private Brush _vsyncColor;
private Brush _vSyncModeColor;
private byte[] _selectedIcon;
private bool _isAppletMenuActive;
private int _statusBarProgressMaximum;
@@ -105,6 +106,8 @@ namespace Ryujinx.Ava.UI.ViewModels
private WindowState _windowState;
private double _windowWidth;
private double _windowHeight;
private int _customVSyncInterval;
private int _customVSyncIntervalPercentageProxy;
private bool _isActive;
private bool _isSubMenuOpen;
@@ -131,6 +134,7 @@ namespace Ryujinx.Ava.UI.ViewModels
Volume = ConfigurationState.Instance.System.AudioVolume;
}
CustomVSyncInterval = ConfigurationState.Instance.Graphics.CustomVSyncInterval.Value;
}
public void Initialize(
@@ -420,17 +424,87 @@ namespace Ryujinx.Ava.UI.ViewModels
}
}
public Brush VsyncColor
public Brush VSyncModeColor
{
get => _vsyncColor;
get => _vSyncModeColor;
set
{
_vsyncColor = value;
_vSyncModeColor = value;
OnPropertyChanged();
}
}
public bool ShowCustomVSyncIntervalPicker
{
get
{
if (_isGameRunning)
{
return AppHost.Device.VSyncMode ==
VSyncMode.Custom;
}
else
{
return false;
}
}
set
{
OnPropertyChanged();
}
}
public int CustomVSyncIntervalPercentageProxy
{
get => _customVSyncIntervalPercentageProxy;
set
{
int newInterval = (int)((value / 100f) * 60);
_customVSyncInterval = newInterval;
_customVSyncIntervalPercentageProxy = value;
if (_isGameRunning)
{
AppHost.Device.CustomVSyncInterval = newInterval;
AppHost.Device.UpdateVSyncInterval();
}
OnPropertyChanged((nameof(CustomVSyncInterval)));
OnPropertyChanged((nameof(CustomVSyncIntervalPercentageText)));
}
}
public string CustomVSyncIntervalPercentageText
{
get
{
string text = CustomVSyncIntervalPercentageProxy.ToString() + "%";
return text;
}
set
{
}
}
public int CustomVSyncInterval
{
get => _customVSyncInterval;
set
{
_customVSyncInterval = value;
int newPercent = (int)((value / 60f) * 100);
_customVSyncIntervalPercentageProxy = newPercent;
if (_isGameRunning)
{
AppHost.Device.CustomVSyncInterval = value;
AppHost.Device.UpdateVSyncInterval();
}
OnPropertyChanged(nameof(CustomVSyncIntervalPercentageProxy));
OnPropertyChanged(nameof(CustomVSyncIntervalPercentageText));
OnPropertyChanged();
}
}
public byte[] SelectedIcon
{
get => _selectedIcon;
@@ -541,6 +615,17 @@ namespace Ryujinx.Ava.UI.ViewModels
}
}
public string VSyncModeText
{
get => _vSyncModeText;
set
{
_vSyncModeText = value;
OnPropertyChanged();
}
}
public string DockedStatusText
{
get => _dockedStatusText;
@@ -1255,17 +1340,18 @@ namespace Ryujinx.Ava.UI.ViewModels
{
Dispatcher.UIThread.InvokeAsync(() =>
{
Application.Current.Styles.TryGetResource(args.VSyncEnabled
? "VsyncEnabled"
: "VsyncDisabled",
Application.Current.ActualThemeVariant,
Application.Current.Styles.TryGetResource(args.VSyncMode,
Avalonia.Application.Current.ActualThemeVariant,
out object color);
if (color is not null)
{
VsyncColor = new SolidColorBrush((Color)color);
VSyncModeColor = new SolidColorBrush((Color)color);
}
VSyncModeText = args.VSyncMode == "Custom" ? "Custom" : "VSync";
ShowCustomVSyncIntervalPicker =
args.VSyncMode == VSyncMode.Custom.ToString();
DockedStatusText = args.DockedMode;
AspectRatioStatusText = args.AspectRatio;
GameStatusText = args.GameStatus;
@@ -1422,6 +1508,27 @@ namespace Ryujinx.Ava.UI.ViewModels
}
}
public void ToggleVSyncMode()
{
AppHost.VSyncModeToggle();
OnPropertyChanged(nameof(ShowCustomVSyncIntervalPicker));
}
public void VSyncModeSettingChanged()
{
if (_isGameRunning)
{
AppHost.Device.CustomVSyncInterval = ConfigurationState.Instance.Graphics.CustomVSyncInterval.Value;
AppHost.Device.UpdateVSyncInterval();
}
CustomVSyncInterval = ConfigurationState.Instance.Graphics.CustomVSyncInterval.Value;
OnPropertyChanged(nameof(ShowCustomVSyncIntervalPicker));
OnPropertyChanged(nameof(CustomVSyncIntervalPercentageProxy));
OnPropertyChanged(nameof(CustomVSyncIntervalPercentageText));
OnPropertyChanged(nameof(CustomVSyncInterval));
}
public async Task ExitCurrentState()
{
if (WindowState == WindowState.FullScreen)
+80 -4
View File
@@ -50,6 +50,10 @@ namespace Ryujinx.Ava.UI.ViewModels
private int _graphicsBackendIndex;
private int _scalingFilter;
private int _scalingFilterLevel;
private int _customVSyncInterval;
private bool _enableCustomVSyncInterval;
private int _customVSyncIntervalPercentageProxy;
private VSyncMode _vSyncMode;
public event Action CloseWindow;
public event Action SaveSettingsEvent;
@@ -138,7 +142,74 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool EnableDockedMode { get; set; }
public bool EnableKeyboard { get; set; }
public bool EnableMouse { get; set; }
public bool EnableVsync { get; set; }
public VSyncMode VSyncMode
{
get => _vSyncMode;
set
{
if (value == VSyncMode.Custom ||
value == VSyncMode.Switch ||
value == VSyncMode.Unbounded)
{
_vSyncMode = value;
OnPropertyChanged();
}
}
}
public int CustomVSyncIntervalPercentageProxy
{
get => _customVSyncIntervalPercentageProxy;
set
{
int newInterval = (int)((value / 100f) * 60);
_customVSyncInterval = newInterval;
_customVSyncIntervalPercentageProxy = value;
OnPropertyChanged((nameof(CustomVSyncInterval)));
OnPropertyChanged((nameof(CustomVSyncIntervalPercentageText)));
}
}
public string CustomVSyncIntervalPercentageText
{
get
{
string text = CustomVSyncIntervalPercentageProxy.ToString() + "%";
return text;
}
}
public bool EnableCustomVSyncInterval
{
get => _enableCustomVSyncInterval;
set
{
_enableCustomVSyncInterval = value;
if (_vSyncMode == VSyncMode.Custom && !value)
{
VSyncMode = VSyncMode.Switch;
}
else if (value)
{
VSyncMode = VSyncMode.Custom;
}
OnPropertyChanged();
}
}
public int CustomVSyncInterval
{
get => _customVSyncInterval;
set
{
_customVSyncInterval = value;
int newPercent = (int)((value / 60f) * 100);
_customVSyncIntervalPercentageProxy = newPercent;
OnPropertyChanged(nameof(CustomVSyncIntervalPercentageProxy));
OnPropertyChanged(nameof(CustomVSyncIntervalPercentageText));
OnPropertyChanged();
}
}
public bool EnablePptc { get; set; }
public bool EnableLowPowerPptc { get; set; }
public bool EnableInternetAccess { get; set; }
@@ -428,7 +499,9 @@ namespace Ryujinx.Ava.UI.ViewModels
CurrentDate = currentDateTime.Date;
CurrentTime = currentDateTime.TimeOfDay;
EnableVsync = config.Graphics.EnableVsync;
EnableCustomVSyncInterval = config.Graphics.EnableCustomVSyncInterval.Value;
CustomVSyncInterval = config.Graphics.CustomVSyncInterval;
VSyncMode = config.Graphics.VSyncMode;
EnableFsIntegrityChecks = config.System.EnableFsIntegrityChecks;
DramSize = config.System.DramSize;
IgnoreMissingServices = config.System.IgnoreMissingServices;
@@ -441,7 +514,7 @@ namespace Ryujinx.Ava.UI.ViewModels
// Graphics
GraphicsBackendIndex = (int)config.Graphics.GraphicsBackend.Value;
// Physical devices are queried asynchronously hence the prefered index config value is loaded in LoadAvailableGpus().
// Physical devices are queried asynchronously hence the preferred index config value is loaded in LoadAvailableGpus().
EnableShaderCache = config.Graphics.EnableShaderCache;
EnableTextureRecompression = config.Graphics.EnableTextureRecompression;
EnableMacroHLE = config.Graphics.EnableMacroHLE;
@@ -524,7 +597,9 @@ namespace Ryujinx.Ava.UI.ViewModels
}
config.System.SystemTimeOffset.Value = Convert.ToInt64((CurrentDate.ToUnixTimeSeconds() + CurrentTime.TotalSeconds) - DateTimeOffset.Now.ToUnixTimeSeconds());
config.Graphics.EnableVsync.Value = EnableVsync;
config.Graphics.VSyncMode.Value = VSyncMode;
config.Graphics.EnableCustomVSyncInterval.Value = EnableCustomVSyncInterval;
config.Graphics.CustomVSyncInterval.Value = CustomVSyncInterval;
config.System.EnableFsIntegrityChecks.Value = EnableFsIntegrityChecks;
config.System.DramSize.Value = DramSize;
config.System.IgnoreMissingServices.Value = IgnoreMissingServices;
@@ -591,6 +666,7 @@ namespace Ryujinx.Ava.UI.ViewModels
config.ToFileFormat().SaveConfig(Program.ConfigurationPath);
MainWindow.UpdateGraphicsConfig();
MainWindow.MainWindowViewModel.VSyncModeSettingChanged();
SaveSettingsEvent?.Invoke();
@@ -1,4 +1,4 @@
<UserControl
<UserControl
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
@@ -88,15 +88,69 @@
MaxHeight="18"
Orientation="Horizontal">
<TextBlock
Name="VsyncStatus"
Name="VSyncMode"
Margin="5,0,5,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Foreground="{Binding VsyncColor}"
Foreground="{Binding VSyncModeColor}"
IsVisible="{Binding !ShowLoadProgress}"
PointerReleased="VsyncStatus_PointerReleased"
Text="VSync"
TextAlignment="Start" />
PointerReleased="VSyncMode_PointerReleased"
Text="{Binding VSyncModeText}"
TextAlignment="Start"/>
<Button MinWidth="0"
Width="20"
IsVisible="{Binding ShowCustomVSyncIntervalPicker}"
Margin="-5,0,5,0"
Background="Transparent"
BorderThickness="0">
<ui:SymbolIcon Symbol="Settings"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Width="14"
Height="14"/>
<Button.Styles>
<Style Selector=":checked">
<Style Selector="^:checked ContentPresenter">
<Setter Property="Foreground" Value="{DynamicResource ThemeForegroundColor}" />
</Style>
</Style>
<Style Selector="Border#SeparatorBorder">
<Setter Property="Opacity" Value="0" />
</Style>
</Button.Styles>
<Button.Flyout>
<Flyout Placement="Top" ShowMode="TransientWithDismissOnPointerMoveAway">
<StackPanel Margin="0,0,0,10"
Orientation="Horizontal">
<ui:NumberBox ToolTip.Tip="{locale:Locale SettingsTabSystemCustomVSyncIntervalValueTooltip}"
Value="{Binding CustomVSyncInterval}"
Width="175"
SmallChange="1.0"
LargeChange="10"
SimpleNumberFormat="F0"
SpinButtonPlacementMode="Hidden"
Minimum="10"
Maximum="1000" />
<Slider Value="{Binding CustomVSyncIntervalPercentageProxy}"
ToolTip.Tip="{locale:Locale SettingsTabSystemCustomVSyncIntervalSliderTooltip}"
MinWidth="175"
Margin="10,-3,0,0"
Height="32"
Padding="0,-5"
TickFrequency="1"
IsSnapToTickEnabled="True"
LargeChange="10"
SmallChange="1"
VerticalAlignment="Center"
Minimum="10"
Maximum="400" />
<TextBlock Margin="5,0"
Width="40"
Text="{Binding CustomVSyncIntervalPercentageText}"/>
</StackPanel>
</Flyout>
</Button.Flyout>
</Button>
<Border
Width="2"
Height="12"
@@ -31,11 +31,10 @@ namespace Ryujinx.Ava.UI.Views.Main
DataContext = Window.ViewModel;
}
private void VsyncStatus_PointerReleased(object sender, PointerReleasedEventArgs e)
private void VSyncMode_PointerReleased(object sender, PointerReleasedEventArgs e)
{
Window.ViewModel.AppHost.ToggleVSync();
Logger.Info?.Print(LogClass.Application, $"VSync toggled to: {Window.ViewModel.AppHost.Device.EnableDeviceVsync}");
Window.ViewModel.ToggleVSyncMode();
Logger.Info?.Print(LogClass.Application, $"VSync Mode toggled to: {Window.ViewModel.AppHost.Device.VSyncMode}");
}
private void DockedStatus_PointerReleased(object sender, PointerReleasedEventArgs e)
@@ -1,4 +1,4 @@
<UserControl
<UserControl
x:Class="Ryujinx.Ava.UI.Views.Settings.SettingsHotkeysView"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
@@ -50,9 +50,9 @@
Classes="h1"
Text="{locale:Locale SettingsTabHotkeysHotkeys}" />
<StackPanel>
<TextBlock Text="{locale:Locale SettingsTabHotkeysToggleVsyncHotkey}" />
<ToggleButton Name="ToggleVsync">
<TextBlock Text="{Binding KeyboardHotkey.ToggleVsync, Converter={StaticResource Key}}" />
<TextBlock Text="{locale:Locale SettingsTabHotkeysToggleVSyncModeHotkey}" />
<ToggleButton Name="ToggleVSyncMode">
<TextBlock Text="{Binding KeyboardHotkey.ToggleVSyncMode, Converter={StaticResource Key}}" />
</ToggleButton>
</StackPanel>
<StackPanel>
@@ -103,6 +103,18 @@
<TextBlock Text="{Binding KeyboardHotkey.VolumeDown, Converter={StaticResource Key}}" />
</ToggleButton>
</StackPanel>
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
<TextBlock Text="{locale:Locale SettingsTabHotkeysIncrementCustomVSyncIntervalHotkey}" />
<ToggleButton Name="CustomVSyncIntervalIncrement">
<TextBlock Text="{Binding KeyboardHotkey.CustomVSyncIntervalIncrement, Converter={StaticResource Key}}" />
</ToggleButton>
</StackPanel>
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
<TextBlock Text="{locale:Locale SettingsTabHotkeysDecrementCustomVSyncIntervalHotkey}" />
<ToggleButton Name="CustomVSyncIntervalDecrement">
<TextBlock Text="{Binding KeyboardHotkey.CustomVSyncIntervalDecrement, Converter={StaticResource Key}}" />
</ToggleButton>
</StackPanel>
</StackPanel>
</Border>
</ScrollViewer>
@@ -82,8 +82,8 @@ namespace Ryujinx.Ava.UI.Views.Settings
switch (button.Name)
{
case "ToggleVsync":
viewModel.KeyboardHotkey.ToggleVsync = buttonValue.AsHidType<Key>();
case "ToggleVSyncMode":
viewModel.KeyboardHotkey.ToggleVSyncMode = buttonValue.AsHidType<Key>();
break;
case "Screenshot":
viewModel.KeyboardHotkey.Screenshot = buttonValue.AsHidType<Key>();
@@ -109,6 +109,12 @@ namespace Ryujinx.Ava.UI.Views.Settings
case "VolumeDown":
viewModel.KeyboardHotkey.VolumeDown = buttonValue.AsHidType<Key>();
break;
case "CustomVSyncIntervalIncrement":
viewModel.KeyboardHotkey.CustomVSyncIntervalIncrement = buttonValue.AsHidType<Key>();
break;
case "CustomVSyncIntervalDecrement":
viewModel.KeyboardHotkey.CustomVSyncIntervalDecrement = buttonValue.AsHidType<Key>();
break;
}
}
};
@@ -4,6 +4,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
@@ -181,11 +182,78 @@
Width="350"
ToolTip.Tip="{locale:Locale TimeTooltip}" />
</StackPanel>
<CheckBox IsChecked="{Binding EnableVsync}">
<StackPanel Margin="0,0,0,10"
Orientation="Horizontal">
<TextBlock
Text="{locale:Locale SettingsTabSystemEnableVsync}"
ToolTip.Tip="{locale:Locale VSyncToggleTooltip}" />
</CheckBox>
VerticalAlignment="Center"
Text="{locale:Locale SettingsTabSystemVSyncMode}"
ToolTip.Tip="{locale:Locale SettingsTabSystemVSyncModeTooltip}"
Width="250" />
<ComboBox
IsVisible="{Binding EnableCustomVSyncInterval}"
SelectedIndex="{Binding VSyncMode}"
ToolTip.Tip="{locale:Locale SettingsTabSystemVSyncModeTooltipCustom}"
HorizontalContentAlignment="Left"
Width="350">
<ComboBoxItem>
<TextBlock Text="{locale:Locale SettingsTabSystemVSyncModeSwitch}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{locale:Locale SettingsTabSystemVSyncModeUnbounded}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{locale:Locale SettingsTabSystemVSyncModeCustom}" />
</ComboBoxItem>
</ComboBox>
<ComboBox
IsVisible="{Binding !EnableCustomVSyncInterval}"
SelectedIndex="{Binding VSyncMode}"
ToolTip.Tip="{locale:Locale SettingsTabSystemVSyncModeTooltip}"
HorizontalContentAlignment="Left"
Width="350">
<ComboBoxItem>
<TextBlock Text="{locale:Locale SettingsTabSystemVSyncModeSwitch}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{locale:Locale SettingsTabSystemVSyncModeUnbounded}" />
</ComboBoxItem>
</ComboBox>
</StackPanel>
<StackPanel IsVisible="{Binding EnableCustomVSyncInterval}"
Margin="0,0,0,10"
Orientation="Horizontal">
<TextBlock
VerticalAlignment="Center"
Text="{locale:Locale SettingsTabSystemCustomVSyncIntervalValue}"
ToolTip.Tip="{locale:Locale SettingsTabSystemCustomVSyncIntervalValueTooltip}"
Width="250" />
<ui:NumberBox IsVisible="{Binding EnableCustomVSyncInterval}"
ToolTip.Tip="{locale:Locale SettingsTabSystemCustomVSyncIntervalValueTooltip}"
Value="{Binding CustomVSyncInterval}"
Width="165"
SmallChange="1.0"
LargeChange="10"
SimpleNumberFormat="F0"
SpinButtonPlacementMode="Hidden"
Minimum="6"
Maximum="1000" />
<Slider Value="{Binding CustomVSyncIntervalPercentageProxy}"
ToolTip.Tip="{locale:Locale SettingsTabSystemCustomVSyncIntervalSliderTooltip}"
MinWidth="175"
Margin="10,-3,0,0"
Height="32"
Padding="0,-5"
TickFrequency="1"
IsSnapToTickEnabled="True"
LargeChange="10"
SmallChange="1"
VerticalAlignment="Center"
Minimum="10"
Maximum="400" />
<TextBlock Margin="5,0"
Width="40"
Text="{Binding CustomVSyncIntervalPercentageText}"/>
</StackPanel>
<CheckBox IsChecked="{Binding EnableFsIntegrityChecks}">
<TextBlock
Text="{locale:Locale SettingsTabSystemEnableFsIntegrityChecks}"
@@ -241,6 +309,11 @@
<CheckBox IsChecked="{Binding IgnoreApplet}">
<TextBlock Text="{locale:Locale SettingsTabSystemIgnoreApplet}" />
</CheckBox>
<CheckBox
IsChecked="{Binding EnableCustomVSyncInterval}"
ToolTip.Tip="{locale:Locale SettingsTabSystemEnableCustomVSyncIntervalTooltip}">
<TextBlock Text="{locale:Locale SettingsTabSystemEnableCustomVSyncInterval}" />
</CheckBox>
</StackPanel>
</StackPanel>
</Border>