[AdvPaste]Add option to hide the window when it loses focus (#33239)

This commit is contained in:
Davide Giacometti
2024-06-24 16:03:46 +02:00
committed by GitHub
parent 62c7b0a66d
commit 6e141f89c9
11 changed files with 79 additions and 37 deletions

View File

@@ -3,15 +3,14 @@
// See the LICENSE file in the project root for more information. // See the LICENSE file in the project root for more information.
using System; using System;
using System.Threading.Tasks;
using AdvancedPaste.Helpers; using AdvancedPaste.Helpers;
using AdvancedPaste.Settings;
using AdvancedPaste.ViewModels; using AdvancedPaste.ViewModels;
using ManagedCommon; using ManagedCommon;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.UI.Windowing; using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml; using Microsoft.UI.Xaml;
using Windows.ApplicationModel.DataTransfer;
using Windows.Graphics; using Windows.Graphics;
using WinUIEx; using WinUIEx;
using static AdvancedPaste.Helpers.NativeMethods; using static AdvancedPaste.Helpers.NativeMethods;
@@ -47,6 +46,7 @@ namespace AdvancedPaste
Host = Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder().UseContentRoot(AppContext.BaseDirectory).ConfigureServices((context, services) => Host = Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder().UseContentRoot(AppContext.BaseDirectory).ConfigureServices((context, services) =>
{ {
services.AddSingleton<OptionsViewModel>(); services.AddSingleton<OptionsViewModel>();
services.AddSingleton<IUserSettings, UserSettings>();
}).Build(); }).Build();
viewModel = GetService<OptionsViewModel>(); viewModel = GetService<OptionsViewModel>();

View File

@@ -2,7 +2,6 @@
// The Microsoft Corporation licenses this file to you under the MIT license. // The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. // See the LICENSE file in the project root for more information.
using System;
using System.Net; using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
using AdvancedPaste.Helpers; using AdvancedPaste.Helpers;
@@ -20,8 +19,7 @@ namespace AdvancedPaste.Controls
public sealed partial class PromptBox : Microsoft.UI.Xaml.Controls.UserControl public sealed partial class PromptBox : Microsoft.UI.Xaml.Controls.UserControl
{ {
private readonly DispatcherQueue _dispatcherQueue = DispatcherQueue.GetForCurrentThread(); private readonly DispatcherQueue _dispatcherQueue = DispatcherQueue.GetForCurrentThread();
private readonly IUserSettings _userSettings;
private UserSettings _userSettings;
public static readonly DependencyProperty PromptProperty = DependencyProperty.Register( public static readonly DependencyProperty PromptProperty = DependencyProperty.Register(
nameof(Prompt), nameof(Prompt),
@@ -65,7 +63,7 @@ namespace AdvancedPaste.Controls
{ {
this.InitializeComponent(); this.InitializeComponent();
_userSettings = new UserSettings(); _userSettings = App.GetService<IUserSettings>();
ViewModel = App.GetService<OptionsViewModel>(); ViewModel = App.GetService<OptionsViewModel>();
} }

View File

@@ -3,21 +3,20 @@
// See the LICENSE file in the project root for more information. // See the LICENSE file in the project root for more information.
using System; using System;
using System.Runtime.CompilerServices;
using AdvancedPaste.Helpers; using AdvancedPaste.Helpers;
using AdvancedPaste.Settings;
using ManagedCommon; using ManagedCommon;
using Microsoft.UI.Windowing; using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml; using Microsoft.UI.Xaml;
using Windows.Graphics;
using WinUIEx; using WinUIEx;
using WinUIEx.Messaging; using WinUIEx.Messaging;
using static AdvancedPaste.Helpers.NativeMethods;
namespace AdvancedPaste namespace AdvancedPaste
{ {
public sealed partial class MainWindow : WindowEx, IDisposable public sealed partial class MainWindow : WindowEx, IDisposable
{ {
private WindowMessageMonitor _msgMonitor; private readonly WindowMessageMonitor _msgMonitor;
private readonly IUserSettings _userSettings;
private bool _disposedValue; private bool _disposedValue;
@@ -25,6 +24,8 @@ namespace AdvancedPaste
{ {
this.InitializeComponent(); this.InitializeComponent();
_userSettings = App.GetService<IUserSettings>();
AppWindow.SetIcon("Assets/AdvancedPaste/AdvancedPaste.ico"); AppWindow.SetIcon("Assets/AdvancedPaste/AdvancedPaste.ico");
this.ExtendsContentIntoTitleBar = true; this.ExtendsContentIntoTitleBar = true;
this.SetTitleBar(titleBar); this.SetTitleBar(titleBar);
@@ -32,6 +33,8 @@ namespace AdvancedPaste
var loader = ResourceLoaderInstance.ResourceLoader; var loader = ResourceLoaderInstance.ResourceLoader;
Title = loader.GetString("WindowTitle"); Title = loader.GetString("WindowTitle");
Activated += OnActivated;
_msgMonitor = new WindowMessageMonitor(this); _msgMonitor = new WindowMessageMonitor(this);
_msgMonitor.WindowMessageReceived += (_, e) => _msgMonitor.WindowMessageReceived += (_, e) =>
{ {
@@ -47,6 +50,14 @@ namespace AdvancedPaste
WindowHelpers.BringToForeground(this.GetWindowHandle()); WindowHelpers.BringToForeground(this.GetWindowHandle());
} }
private void OnActivated(object sender, WindowActivatedEventArgs args)
{
if (_userSettings.CloseAfterLosingFocus && args.WindowActivationState == WindowActivationState.Deactivated)
{
Hide();
}
}
private void Dispose(bool disposing) private void Dispose(bool disposing)
{ {
if (!_disposedValue) if (!_disposedValue)
@@ -66,11 +77,15 @@ namespace AdvancedPaste
private void WindowEx_Closed(object sender, Microsoft.UI.Xaml.WindowEventArgs args) private void WindowEx_Closed(object sender, Microsoft.UI.Xaml.WindowEventArgs args)
{ {
Windows.Win32.PInvoke.ShowWindow((Windows.Win32.Foundation.HWND)this.GetWindowHandle(), Windows.Win32.UI.WindowsAndMessaging.SHOW_WINDOW_CMD.SW_HIDE); Hide();
args.Handled = true; args.Handled = true;
} }
private void Hide()
{
Windows.Win32.PInvoke.ShowWindow(new Windows.Win32.Foundation.HWND(this.GetWindowHandle()), Windows.Win32.UI.WindowsAndMessaging.SHOW_WINDOW_CMD.SW_HIDE);
}
public void SetFocus() public void SetFocus()
{ {
MainPage.CustomFormatTextBox.InputTxtBox.Focus(FocusState.Programmatic); MainPage.CustomFormatTextBox.InputTxtBox.Focus(FocusState.Programmatic);

View File

@@ -9,5 +9,7 @@ namespace AdvancedPaste.Settings
public bool ShowCustomPreview { get; } public bool ShowCustomPreview { get; }
public bool SendPasteKeyCombination { get; } public bool SendPasteKeyCombination { get; }
public bool CloseAfterLosingFocus { get; }
} }
} }

View File

@@ -24,12 +24,15 @@ namespace AdvancedPaste.Settings
public bool SendPasteKeyCombination { get; private set; } public bool SendPasteKeyCombination { get; private set; }
public bool CloseAfterLosingFocus { get; private set; }
public UserSettings() public UserSettings()
{ {
_settingsUtils = new SettingsUtils(); _settingsUtils = new SettingsUtils();
ShowCustomPreview = true; ShowCustomPreview = true;
SendPasteKeyCombination = true; SendPasteKeyCombination = true;
CloseAfterLosingFocus = false;
LoadSettingsFromJson(); LoadSettingsFromJson();
@@ -61,6 +64,7 @@ namespace AdvancedPaste.Settings
{ {
ShowCustomPreview = settings.Properties.ShowCustomPreview; ShowCustomPreview = settings.Properties.ShowCustomPreview;
SendPasteKeyCombination = settings.Properties.SendPasteKeyCombination; SendPasteKeyCombination = settings.Properties.SendPasteKeyCombination;
CloseAfterLosingFocus = settings.Properties.CloseAfterLosingFocus;
} }
retry = false; retry = false;

View File

@@ -25,13 +25,12 @@ namespace AdvancedPaste.ViewModels
public partial class OptionsViewModel : ObservableObject public partial class OptionsViewModel : ObservableObject
{ {
private readonly DispatcherQueue _dispatcherQueue = DispatcherQueue.GetForCurrentThread(); private readonly DispatcherQueue _dispatcherQueue = DispatcherQueue.GetForCurrentThread();
private readonly IUserSettings _userSettings;
private App app = App.Current as App; private App app = App.Current as App;
private AICompletionsHelper aiHelper; private AICompletionsHelper aiHelper;
private UserSettings _userSettings;
public DataPackageView ClipboardData { get; set; } public DataPackageView ClipboardData { get; set; }
[ObservableProperty] [ObservableProperty]
@@ -50,10 +49,10 @@ namespace AdvancedPaste.ViewModels
[NotifyPropertyChangedFor(nameof(InputTxtBoxErrorText))] [NotifyPropertyChangedFor(nameof(InputTxtBoxErrorText))]
private int _apiRequestStatus; private int _apiRequestStatus;
public OptionsViewModel() public OptionsViewModel(IUserSettings userSettings)
{ {
aiHelper = new AICompletionsHelper(); aiHelper = new AICompletionsHelper();
_userSettings = new UserSettings(); _userSettings = userSettings;
IsCustomAIEnabled = IsClipboardDataText && aiHelper.IsAIEnabled; IsCustomAIEnabled = IsClipboardDataText && aiHelper.IsAIEnabled;

View File

@@ -22,6 +22,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
PasteAsJsonShortcut = new(); PasteAsJsonShortcut = new();
ShowCustomPreview = true; ShowCustomPreview = true;
SendPasteKeyCombination = true; SendPasteKeyCombination = true;
CloseAfterLosingFocus = false;
} }
[JsonConverter(typeof(BoolPropertyJsonConverter))] [JsonConverter(typeof(BoolPropertyJsonConverter))]
@@ -31,6 +32,9 @@ namespace Microsoft.PowerToys.Settings.UI.Library
[CmdConfigureIgnore] [CmdConfigureIgnore]
public bool SendPasteKeyCombination { get; set; } public bool SendPasteKeyCombination { get; set; }
[JsonConverter(typeof(BoolPropertyJsonConverter))]
public bool CloseAfterLosingFocus { get; set; }
[JsonPropertyName("advanced-paste-ui-hotkey")] [JsonPropertyName("advanced-paste-ui-hotkey")]
public HotkeySettings AdvancedPasteUIShortcut { get; set; } public HotkeySettings AdvancedPasteUIShortcut { get; set; }

View File

@@ -81,7 +81,7 @@
Severity="Informational" /> Severity="Informational" />
</controls:SettingsGroup> </controls:SettingsGroup>
<controls:SettingsGroup x:Uid="AdvancedPaste_ClipboardHistorySettingsGroup" IsEnabled="{x:Bind ViewModel.IsEnabled, Mode=OneWay}"> <controls:SettingsGroup x:Uid="AdvancedPaste_BehaviorSettingsGroup" IsEnabled="{x:Bind ViewModel.IsEnabled, Mode=OneWay}">
<tkcontrols:SettingsCard <tkcontrols:SettingsCard
x:Uid="AdvancedPaste_Clipboard_History_Enabled_SettingsCard" x:Uid="AdvancedPaste_Clipboard_History_Enabled_SettingsCard"
HeaderIcon="{ui:FontIcon Glyph=&#xF0E3;}" HeaderIcon="{ui:FontIcon Glyph=&#xF0E3;}"
@@ -94,6 +94,9 @@
IsOpen="{x:Bind ViewModel.ShowClipboardHistoryIsGpoConfiguredInfoBar, Mode=OneWay}" IsOpen="{x:Bind ViewModel.ShowClipboardHistoryIsGpoConfiguredInfoBar, Mode=OneWay}"
IsTabStop="{x:Bind ViewModel.ShowClipboardHistoryIsGpoConfiguredInfoBar, Mode=OneWay}" IsTabStop="{x:Bind ViewModel.ShowClipboardHistoryIsGpoConfiguredInfoBar, Mode=OneWay}"
Severity="Informational" /> Severity="Informational" />
<tkcontrols:SettingsCard x:Uid="AdvancedPaste_CloseAfterLosingFocus" HeaderIcon="{ui:FontIcon Glyph=&#xED1A;}">
<ToggleSwitch IsOn="{x:Bind ViewModel.CloseAfterLosingFocus, Mode=TwoWay}" />
</tkcontrols:SettingsCard>
</controls:SettingsGroup> </controls:SettingsGroup>
<controls:SettingsGroup x:Uid="AdvancedPaste_Direct_Access_Hotkeys_GroupSettings" IsEnabled="{x:Bind ViewModel.IsEnabled, Mode=OneWay}"> <controls:SettingsGroup x:Uid="AdvancedPaste_Direct_Access_Hotkeys_GroupSettings" IsEnabled="{x:Bind ViewModel.IsEnabled, Mode=OneWay}">

View File

@@ -35,7 +35,7 @@
<tkcontrols:SettingsCard x:Uid="Peek_AlwaysRunNotElevated" HeaderIcon="{ui:FontIcon Glyph=&#xE7EF;}"> <tkcontrols:SettingsCard x:Uid="Peek_AlwaysRunNotElevated" HeaderIcon="{ui:FontIcon Glyph=&#xE7EF;}">
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind ViewModel.AlwaysRunNotElevated, Mode=TwoWay}" /> <ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind ViewModel.AlwaysRunNotElevated, Mode=TwoWay}" />
</tkcontrols:SettingsCard> </tkcontrols:SettingsCard>
<tkcontrols:SettingsCard x:Uid="Peek_CloseAfterLosingFocus"> <tkcontrols:SettingsCard x:Uid="Peek_CloseAfterLosingFocus" HeaderIcon="{ui:FontIcon Glyph=&#xED1A;}">
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind ViewModel.CloseAfterLosingFocus, Mode=TwoWay}" /> <ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind ViewModel.CloseAfterLosingFocus, Mode=TwoWay}" />
</tkcontrols:SettingsCard> </tkcontrols:SettingsCard>
</controls:SettingsGroup> </controls:SettingsGroup>

View File

@@ -3763,8 +3763,8 @@ Activate by holding the key for the character you want to add an accent to, then
<data name="AdvancedPaste_EnableAISettingsGroup.Header" xml:space="preserve"> <data name="AdvancedPaste_EnableAISettingsGroup.Header" xml:space="preserve">
<value>Paste with AI</value> <value>Paste with AI</value>
</data> </data>
<data name="AdvancedPaste_ClipboardHistorySettingsGroup.Header" xml:space="preserve"> <data name="AdvancedPaste_BehaviorSettingsGroup.Header" xml:space="preserve">
<value>Clipboard history</value> <value>Behavior</value>
</data> </data>
<data name="AdvancedPaste_ShowCustomPreviewSettingsCard.Header" xml:space="preserve"> <data name="AdvancedPaste_ShowCustomPreviewSettingsCard.Header" xml:space="preserve">
<value>Custom format preview</value> <value>Custom format preview</value>
@@ -4192,4 +4192,8 @@ Activate by holding the key for the character you want to add an accent to, then
<data name="AdvancedPaste_EnableAIDialog_NoteAICreditsErrorText.Text" xml:space="preserve"> <data name="AdvancedPaste_EnableAIDialog_NoteAICreditsErrorText.Text" xml:space="preserve">
<value>If you do not have credits you will see an 'API key quota exceeded' error</value> <value>If you do not have credits you will see an 'API key quota exceeded' error</value>
</data> </data>
<data name="AdvancedPaste_CloseAfterLosingFocus.Header" xml:space="preserve">
<value>Automatically close the AdvancedPaste window after it loses focus</value>
<comment>AdvancedPaste is a product name, do not loc</comment>
</data>
</root> </root>

View File

@@ -304,6 +304,19 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
} }
} }
public bool CloseAfterLosingFocus
{
get => _advancedPasteSettings.Properties.CloseAfterLosingFocus;
set
{
if (value != _advancedPasteSettings.Properties.CloseAfterLosingFocus)
{
_advancedPasteSettings.Properties.CloseAfterLosingFocus = value;
NotifySettingsChanged();
}
}
}
public bool IsConflictingCopyShortcut public bool IsConflictingCopyShortcut
{ {
get get