From 6dbcdfea47e60aadefd59a75e43549793481f853 Mon Sep 17 00:00:00 2001
From: TSRBerry <20988865+TSRBerry@users.noreply.github.com>
Date: Sun, 16 Apr 2023 09:09:02 +0200
Subject: [PATCH] Ava: Fix nca extraction window never closing & minor cleanup
(#4569)
* ava: Remove unused doWhileDeferred parameters
* ava: Minimally improve swkbd dialog
It's currently impossible to get the dialog to redirect focus to the InputBox.
* ava: Fix nca extraction dialog never closing
Also contains some minor cleanup
---
Ryujinx.Ava/Common/ApplicationHelper.cs | 29 +++++-----
Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml | 3 +-
.../UI/Applet/SwkbdAppletDialog.axaml.cs | 45 +++------------
Ryujinx.Ava/UI/Controls/InputDialog.axaml | 32 -----------
Ryujinx.Ava/UI/Controls/InputDialog.axaml.cs | 57 -------------------
.../UI/Controls/UpdateWaitWindow.axaml.cs | 11 ++++
Ryujinx.Ava/UI/Helpers/ContentDialogHelper.cs | 32 +----------
.../UI/ViewModels/MainWindowViewModel.cs | 2 +-
.../Windows/ContentDialogOverlayWindow.axaml | 18 +++---
9 files changed, 45 insertions(+), 184 deletions(-)
delete mode 100644 Ryujinx.Ava/UI/Controls/InputDialog.axaml
delete mode 100644 Ryujinx.Ava/UI/Controls/InputDialog.axaml.cs
diff --git a/Ryujinx.Ava/Common/ApplicationHelper.cs b/Ryujinx.Ava/Common/ApplicationHelper.cs
index 161ef859..8c36a636 100644
--- a/Ryujinx.Ava/Common/ApplicationHelper.cs
+++ b/Ryujinx.Ava/Common/ApplicationHelper.cs
@@ -13,6 +13,7 @@ using LibHac.Tools.Fs;
using LibHac.Tools.FsSystem;
using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Ava.Common.Locale;
+using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Windows;
using Ryujinx.Common.Logging;
@@ -152,25 +153,17 @@ namespace Ryujinx.Ava.Common
string destination = await folderDialog.ShowAsync(_owner);
var cancellationToken = new CancellationTokenSource();
+ UpdateWaitWindow waitingDialog = new(
+ LocaleManager.Instance[LocaleKeys.DialogNcaExtractionTitle],
+ LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogNcaExtractionMessage, ncaSectionType, Path.GetFileName(titleFilePath)),
+ cancellationToken);
+
if (!string.IsNullOrWhiteSpace(destination))
{
Thread extractorThread = new(() =>
{
- Dispatcher.UIThread.Post(async () =>
- {
- UserResult result = await ContentDialogHelper.CreateConfirmationDialog(
- LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogNcaExtractionMessage, ncaSectionType, Path.GetFileName(titleFilePath)),
- "",
- "",
- LocaleManager.Instance[LocaleKeys.InputDialogCancel],
- LocaleManager.Instance[LocaleKeys.DialogNcaExtractionTitle]);
+ Dispatcher.UIThread.Post(waitingDialog.Show);
- if (result == UserResult.Cancel)
- {
- cancellationToken.Cancel();
- }
- });
-
using FileStream file = new(titleFilePath, FileMode.Open, FileAccess.Read);
Nca mainNca = null;
@@ -222,6 +215,8 @@ namespace Ryujinx.Ava.Common
Dispatcher.UIThread.InvokeAsync(async () =>
{
+ waitingDialog.Close();
+
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogNcaExtractionMainNcaNotFoundErrorMessage]);
});
@@ -263,11 +258,15 @@ namespace Ryujinx.Ava.Common
Dispatcher.UIThread.InvokeAsync(async () =>
{
+ waitingDialog.Close();
+
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogNcaExtractionCheckLogErrorMessage]);
});
}
else if (resultCode.Value.IsSuccess())
{
+ Dispatcher.UIThread.Post(waitingDialog.Close);
+
NotificationHelper.Show(
LocaleManager.Instance[LocaleKeys.DialogNcaExtractionTitle],
$"{titleName}\n\n{LocaleManager.Instance[LocaleKeys.DialogNcaExtractionSuccessMessage]}",
@@ -284,6 +283,8 @@ namespace Ryujinx.Ava.Common
Dispatcher.UIThread.InvokeAsync(async () =>
{
+ waitingDialog.Close();
+
await ContentDialogHelper.CreateErrorDialog(ex.Message);
});
}
diff --git a/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml b/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml
index 43ccf9e7..65504569 100644
--- a/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml
+++ b/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml
@@ -48,6 +48,7 @@
Grid.Column="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
+ Focusable="True"
KeyUp="Message_KeyUp"
Text="{Binding Message}"
TextInput="Message_TextInput"
@@ -61,4 +62,4 @@
HorizontalAlignment="Stretch"
TextWrapping="Wrap" />
-
\ No newline at end of file
+
diff --git a/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml.cs b/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml.cs
index fb689ec2..cb69e96b 100644
--- a/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml.cs
+++ b/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml.cs
@@ -45,6 +45,13 @@ namespace Ryujinx.Ava.UI.Controls
InitializeComponent();
}
+ protected override void OnGotFocus(GotFocusEventArgs e)
+ {
+ // FIXME: This does not work. Might be a bug in Avalonia with DialogHost
+ // Currently focus will be redirected to the overlay window instead.
+ Input.Focus();
+ }
+
public string Message { get; set; } = "";
public string MainText { get; set; } = "";
public string SecondaryText { get; set; } = "";
@@ -59,24 +66,6 @@ namespace Ryujinx.Ava.UI.Controls
string input = string.Empty;
- var overlay = new ContentDialogOverlayWindow()
- {
- Height = window.Bounds.Height,
- Width = window.Bounds.Width,
- Position = window.PointToScreen(new Point())
- };
-
- window.PositionChanged += OverlayOnPositionChanged;
-
- void OverlayOnPositionChanged(object sender, PixelPointEventArgs e)
- {
- overlay.Position = window.PointToScreen(new Point());
- }
-
- contentDialog = overlay.ContentDialog;
-
- bool opened = false;
-
content.SetInputLengthValidation(args.StringLengthMin, args.StringLengthMax);
content._host = contentDialog;
@@ -97,25 +86,7 @@ namespace Ryujinx.Ava.UI.Controls
};
contentDialog.Closed += handler;
- overlay.Opened += OverlayOnActivated;
-
- async void OverlayOnActivated(object sender, EventArgs e)
- {
- if (opened)
- {
- return;
- }
-
- opened = true;
-
- overlay.Position = window.PointToScreen(new Point());
-
- await contentDialog.ShowAsync(overlay);
- contentDialog.Closed -= handler;
- overlay.Close();
- };
-
- await overlay.ShowDialog(window);
+ await ContentDialogHelper.ShowAsync(contentDialog);
return (result, input);
}
diff --git a/Ryujinx.Ava/UI/Controls/InputDialog.axaml b/Ryujinx.Ava/UI/Controls/InputDialog.axaml
deleted file mode 100644
index ed1ceda3..00000000
--- a/Ryujinx.Ava/UI/Controls/InputDialog.axaml
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Ryujinx.Ava/UI/Controls/InputDialog.axaml.cs b/Ryujinx.Ava/UI/Controls/InputDialog.axaml.cs
deleted file mode 100644
index 8dba5e2b..00000000
--- a/Ryujinx.Ava/UI/Controls/InputDialog.axaml.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-using Avalonia.Controls;
-using FluentAvalonia.UI.Controls;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.Ava.UI.Models;
-using System.Threading.Tasks;
-
-namespace Ryujinx.Ava.UI.Controls
-{
- public partial class InputDialog : UserControl
- {
- public string Message { get; set; }
- public string Input { get; set; }
- public string SubMessage { get; set; }
-
- public uint MaxLength { get; }
-
- public InputDialog(string message, string input = "", string subMessage = "", uint maxLength = int.MaxValue)
- {
- Message = message;
- Input = input;
- SubMessage = subMessage;
- MaxLength = maxLength;
-
- DataContext = this;
- }
-
- public InputDialog()
- {
- InitializeComponent();
- }
-
- public static async Task<(UserResult Result, string Input)> ShowInputDialog(string title, string message,
- string input = "", string subMessage = "", uint maxLength = int.MaxValue)
- {
- UserResult result = UserResult.Cancel;
-
- InputDialog content = new InputDialog(message, input, subMessage, maxLength);
- ContentDialog contentDialog = new ContentDialog
- {
- Title = title,
- PrimaryButtonText = LocaleManager.Instance[LocaleKeys.InputDialogOk],
- SecondaryButtonText = "",
- CloseButtonText = LocaleManager.Instance[LocaleKeys.InputDialogCancel],
- Content = content,
- PrimaryButtonCommand = MiniCommand.Create(() =>
- {
- result = UserResult.Ok;
- input = content.Input;
- })
- };
- await contentDialog.ShowAsync();
-
- return (result, input);
- }
- }
-}
\ No newline at end of file
diff --git a/Ryujinx.Ava/UI/Controls/UpdateWaitWindow.axaml.cs b/Ryujinx.Ava/UI/Controls/UpdateWaitWindow.axaml.cs
index 9db7b5d4..80a437e3 100644
--- a/Ryujinx.Ava/UI/Controls/UpdateWaitWindow.axaml.cs
+++ b/Ryujinx.Ava/UI/Controls/UpdateWaitWindow.axaml.cs
@@ -1,15 +1,26 @@
using Avalonia.Controls;
using Ryujinx.Ava.UI.Windows;
+using System.Threading;
namespace Ryujinx.Ava.UI.Controls
{
public partial class UpdateWaitWindow : StyleableWindow
{
+ public UpdateWaitWindow(string primaryText, string secondaryText, CancellationTokenSource cancellationToken) : this(primaryText, secondaryText)
+ {
+ SystemDecorations = SystemDecorations.Full;
+ ShowInTaskbar = true;
+
+ Closing += (_, _) => cancellationToken.Cancel();
+ }
+
public UpdateWaitWindow(string primaryText, string secondaryText) : this()
{
PrimaryText.Text = primaryText;
SecondaryText.Text = secondaryText;
WindowStartupLocation = WindowStartupLocation.CenterOwner;
+ SystemDecorations = SystemDecorations.BorderOnly;
+ ShowInTaskbar = false;
}
public UpdateWaitWindow()
diff --git a/Ryujinx.Ava/UI/Helpers/ContentDialogHelper.cs b/Ryujinx.Ava/UI/Helpers/ContentDialogHelper.cs
index 8f0c670e..cb474506 100644
--- a/Ryujinx.Ava/UI/Helpers/ContentDialogHelper.cs
+++ b/Ryujinx.Ava/UI/Helpers/ContentDialogHelper.cs
@@ -27,7 +27,6 @@ namespace Ryujinx.Ava.UI.Helpers
string closeButton,
UserResult primaryButtonResult = UserResult.Ok,
ManualResetEvent deferResetEvent = null,
- Func doWhileDeferred = null,
TypedEventHandler deferCloseAction = null)
{
UserResult result = UserResult.None;
@@ -78,12 +77,11 @@ namespace Ryujinx.Ava.UI.Helpers
int iconSymbol,
UserResult primaryButtonResult = UserResult.Ok,
ManualResetEvent deferResetEvent = null,
- Func doWhileDeferred = null,
TypedEventHandler deferCloseAction = null)
{
Grid content = CreateTextDialogContent(primaryText, secondaryText, iconSymbol);
- return await ShowContentDialog(title, content, primaryButton, secondaryButton, closeButton, primaryButtonResult, deferResetEvent, doWhileDeferred, deferCloseAction);
+ return await ShowContentDialog(title, content, primaryButton, secondaryButton, closeButton, primaryButtonResult, deferResetEvent, deferCloseAction);
}
public async static Task ShowDeferredContentDialog(
@@ -111,7 +109,6 @@ namespace Ryujinx.Ava.UI.Helpers
iconSymbol,
primaryButton == LocaleManager.Instance[LocaleKeys.InputDialogYes] ? UserResult.Yes : UserResult.Ok,
deferResetEvent,
- doWhileDeferred,
DeferClose);
async void DeferClose(ContentDialog sender, ContentDialogButtonClickEventArgs args)
@@ -236,11 +233,6 @@ namespace Ryujinx.Ava.UI.Helpers
primaryButtonResult);
}
- internal static UpdateWaitWindow CreateWaitingDialog(string mainText, string secondaryText)
- {
- return new(mainText, secondaryText);
- }
-
internal static async Task CreateUpdaterInfoDialog(string primary, string secondaryText)
{
await ShowTextDialog(
@@ -319,28 +311,6 @@ namespace Ryujinx.Ava.UI.Helpers
LocaleManager.Instance[LocaleKeys.DialogExitSubMessage]);
}
- internal static async Task CreateInputDialog(
- string title,
- string mainText,
- string subText,
- uint maxLength = int.MaxValue,
- string input = "")
- {
- var result = await InputDialog.ShowInputDialog(
- title,
- mainText,
- input,
- subText,
- maxLength);
-
- if (result.Result == UserResult.Ok)
- {
- return result.Input;
- }
-
- return string.Empty;
- }
-
public static async Task ShowAsync(ContentDialog contentDialog)
{
ContentDialogResult result;
diff --git a/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs b/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs
index da211526..14d7a0fe 100644
--- a/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs
+++ b/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs
@@ -972,7 +972,7 @@ namespace Ryujinx.Ava.UI.ViewModels
LocaleManager.Instance[LocaleKeys.InputDialogNo],
LocaleManager.Instance[LocaleKeys.RyujinxConfirm]);
- UpdateWaitWindow waitingDialog = ContentDialogHelper.CreateWaitingDialog(dialogTitle, LocaleManager.Instance[LocaleKeys.DialogFirmwareInstallerFirmwareInstallWaitMessage]);
+ UpdateWaitWindow waitingDialog = new(dialogTitle, LocaleManager.Instance[LocaleKeys.DialogFirmwareInstallerFirmwareInstallWaitMessage]);
if (result == UserResult.Yes)
{
diff --git a/Ryujinx.Ava/UI/Windows/ContentDialogOverlayWindow.axaml b/Ryujinx.Ava/UI/Windows/ContentDialogOverlayWindow.axaml
index 6cdcae2b..8b52bade 100644
--- a/Ryujinx.Ava/UI/Windows/ContentDialogOverlayWindow.axaml
+++ b/Ryujinx.Ava/UI/Windows/ContentDialogOverlayWindow.axaml
@@ -1,4 +1,4 @@
-
+ Focusable="False">
-
-
-
+