[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
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
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.
using System;
using System.Threading.Tasks;
using AdvancedPaste.Helpers;
using AdvancedPaste.Settings;
using AdvancedPaste.ViewModels;
using ManagedCommon;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml;
using Windows.ApplicationModel.DataTransfer;
using Windows.Graphics;
using WinUIEx;
using static AdvancedPaste.Helpers.NativeMethods;
@ -47,6 +46,7 @@ namespace AdvancedPaste
Host = Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder().UseContentRoot(AppContext.BaseDirectory).ConfigureServices((context, services) =>
{
services.AddSingleton<OptionsViewModel>();
services.AddSingleton<IUserSettings, UserSettings>();
}).Build();
viewModel = GetService<OptionsViewModel>();

View File

@ -2,7 +2,6 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Net;
using System.Threading.Tasks;
using AdvancedPaste.Helpers;
@ -20,14 +19,13 @@ namespace AdvancedPaste.Controls
public sealed partial class PromptBox : Microsoft.UI.Xaml.Controls.UserControl
{
private readonly DispatcherQueue _dispatcherQueue = DispatcherQueue.GetForCurrentThread();
private UserSettings _userSettings;
private readonly IUserSettings _userSettings;
public static readonly DependencyProperty PromptProperty = DependencyProperty.Register(
nameof(Prompt),
typeof(string),
typeof(PromptBox),
new PropertyMetadata(defaultValue: string.Empty));
nameof(Prompt),
typeof(string),
typeof(PromptBox),
new PropertyMetadata(defaultValue: string.Empty));
public OptionsViewModel ViewModel { get; private set; }
@ -38,10 +36,10 @@ namespace AdvancedPaste.Controls
}
public static readonly DependencyProperty PlaceholderTextProperty = DependencyProperty.Register(
nameof(PlaceholderText),
typeof(string),
typeof(PromptBox),
new PropertyMetadata(defaultValue: string.Empty));
nameof(PlaceholderText),
typeof(string),
typeof(PromptBox),
new PropertyMetadata(defaultValue: string.Empty));
public string PlaceholderText
{
@ -50,10 +48,10 @@ namespace AdvancedPaste.Controls
}
public static readonly DependencyProperty FooterProperty = DependencyProperty.Register(
nameof(Footer),
typeof(object),
typeof(PromptBox),
new PropertyMetadata(defaultValue: null));
nameof(Footer),
typeof(object),
typeof(PromptBox),
new PropertyMetadata(defaultValue: null));
public object Footer
{
@ -65,7 +63,7 @@ namespace AdvancedPaste.Controls
{
this.InitializeComponent();
_userSettings = new UserSettings();
_userSettings = App.GetService<IUserSettings>();
ViewModel = App.GetService<OptionsViewModel>();
}

View File

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

View File

@ -9,5 +9,7 @@ namespace AdvancedPaste.Settings
public bool ShowCustomPreview { 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 CloseAfterLosingFocus { get; private set; }
public UserSettings()
{
_settingsUtils = new SettingsUtils();
ShowCustomPreview = true;
SendPasteKeyCombination = true;
CloseAfterLosingFocus = false;
LoadSettingsFromJson();
@ -61,6 +64,7 @@ namespace AdvancedPaste.Settings
{
ShowCustomPreview = settings.Properties.ShowCustomPreview;
SendPasteKeyCombination = settings.Properties.SendPasteKeyCombination;
CloseAfterLosingFocus = settings.Properties.CloseAfterLosingFocus;
}
retry = false;

View File

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

View File

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

View File

@ -81,7 +81,7 @@
Severity="Informational" />
</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
x:Uid="AdvancedPaste_Clipboard_History_Enabled_SettingsCard"
HeaderIcon="{ui:FontIcon Glyph=&#xF0E3;}"
@ -94,6 +94,9 @@
IsOpen="{x:Bind ViewModel.ShowClipboardHistoryIsGpoConfiguredInfoBar, Mode=OneWay}"
IsTabStop="{x:Bind ViewModel.ShowClipboardHistoryIsGpoConfiguredInfoBar, Mode=OneWay}"
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 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;}">
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind ViewModel.AlwaysRunNotElevated, Mode=TwoWay}" />
</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}" />
</tkcontrols:SettingsCard>
</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">
<value>Paste with AI</value>
</data>
<data name="AdvancedPaste_ClipboardHistorySettingsGroup.Header" xml:space="preserve">
<value>Clipboard history</value>
<data name="AdvancedPaste_BehaviorSettingsGroup.Header" xml:space="preserve">
<value>Behavior</value>
</data>
<data name="AdvancedPaste_ShowCustomPreviewSettingsCard.Header" xml:space="preserve">
<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">
<value>If you do not have credits you will see an 'API key quota exceeded' error</value>
</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>

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
{
get
@ -328,11 +341,11 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
{
// Using InvariantCulture as this is an IPC message
SendConfigMSG(
string.Format(
CultureInfo.InvariantCulture,
"{{ \"powertoys\": {{ \"{0}\": {1} }} }}",
AdvancedPasteSettings.ModuleName,
JsonSerializer.Serialize(_advancedPasteSettings)));
string.Format(
CultureInfo.InvariantCulture,
"{{ \"powertoys\": {{ \"{0}\": {1} }} }}",
AdvancedPasteSettings.ModuleName,
JsonSerializer.Serialize(_advancedPasteSettings)));
}
public void RefreshEnabledState()