diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..6eec1d52 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,31 @@ +--- +name: Bug report +about: Create a report to help us improve Libation +title: '' +labels: bug +assignees: '' +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: + +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Platform** + +[e.g. Windows 10, Windows 11, Mac, Linux (State distribution)] + +**Log Files** +Attach your Libation log file here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..5f0a04ce --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,19 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: enhancement +assignees: '' +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/Source/LibationAvalonia/AvaloniaThreadUtils.cs b/Source/LibationAvalonia/AvaloniaThreadUtils.cs new file mode 100644 index 00000000..b5683223 --- /dev/null +++ b/Source/LibationAvalonia/AvaloniaThreadUtils.cs @@ -0,0 +1,30 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Avalonia.Threading +{ + internal static class AvaloniaThreadUtils + { + public static TResult Invoke(this Dispatcher dispatcher, Func function, DispatcherPriority dispatcherPriority = DispatcherPriority.Normal) + => WaitOnDispatcherAndGetResult(dispatcher.InvokeAsync(function, dispatcherPriority), dispatcher); + + public static void Invoke(this Dispatcher dispatcher, Action action, DispatcherPriority dispatcherPriority = DispatcherPriority.Normal) + => WaitOnDispatcher(dispatcher.InvokeAsync(action, dispatcherPriority), dispatcher); + + public static TResult WaitOnDispatcherAndGetResult(this Task task, Dispatcher dispatcher) + { + using var source = new CancellationTokenSource(); + task.ContinueWith(t => source.Cancel(), TaskScheduler.FromCurrentSynchronizationContext()); + dispatcher.MainLoop(source.Token); + return task.Result; + } + + public static void WaitOnDispatcher(this Task task, Dispatcher dispatcher) + { + using var source = new CancellationTokenSource(); + task.ContinueWith(t => source.Cancel(), TaskScheduler.FromCurrentSynchronizationContext()); + dispatcher.MainLoop(source.Token); + } + } +} diff --git a/Source/LibationAvalonia/AvaloniaUtils.cs b/Source/LibationAvalonia/AvaloniaUtils.cs index 7ade8b9a..906bfe61 100644 --- a/Source/LibationAvalonia/AvaloniaUtils.cs +++ b/Source/LibationAvalonia/AvaloniaUtils.cs @@ -1,4 +1,5 @@ using Avalonia.Media; +using Avalonia.Threading; using System; using System.Threading; using System.Threading.Tasks; @@ -18,11 +19,7 @@ namespace LibationAvalonia public static T ShowDialogSynchronously(this Avalonia.Controls.Window window, Avalonia.Controls.Window owner) { - using var source = new CancellationTokenSource(); - var dialogTask = window.ShowDialog(owner); - dialogTask.ContinueWith(t => source.Cancel(), TaskScheduler.FromCurrentSynchronizationContext()); - Avalonia.Threading.Dispatcher.UIThread.MainLoop(source.Token); - return dialogTask.Result; + return window.ShowDialog(owner).WaitOnDispatcherAndGetResult(Dispatcher.UIThread); } } } diff --git a/Source/LibationAvalonia/MessageBox.cs b/Source/LibationAvalonia/MessageBox.cs index f92eedde..26de6e0f 100644 --- a/Source/LibationAvalonia/MessageBox.cs +++ b/Source/LibationAvalonia/MessageBox.cs @@ -9,6 +9,8 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using System.Threading; +using Avalonia.Threading; namespace LibationAvalonia { @@ -147,13 +149,15 @@ Libation. DisplayWindow(form, owner); } - private static DialogResult ShowCoreAsync(Window owner, string message, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton, bool saveAndRestorePosition = true) - => Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() => ShowCoreAsync2(owner, message, caption, buttons, icon, defaultButton, saveAndRestorePosition)).GetAwaiter().GetResult(); - - private static DialogResult ShowCoreAsync2(Window owner, string message, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton, bool saveAndRestorePosition = true) { + var dialog = Dispatcher.UIThread.Invoke(() => CreateMessageBox(owner, message, caption, buttons, icon, defaultButton, saveAndRestorePosition)); + return DisplayWindow(dialog, owner); + } + + private static MessageBoxWindow CreateMessageBox(Window owner, string message, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton, bool saveAndRestorePosition = true) + { owner ??= (Application.Current.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime).MainWindow; var dialog = new MessageBoxWindow(saveAndRestorePosition); @@ -186,8 +190,7 @@ Libation. dialog.MaxWidth = dialog.MinWidth; dialog.Height = dialog.MinHeight; dialog.Width = dialog.MinWidth; - - return DisplayWindow(dialog, owner); + return dialog; } private static DialogResult DisplayWindow(Window toDisplay, Window owner) {