mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 19:57:57 +01:00
[Peek]Add setting to close after losing focus (#26364)
* [Peek] WindowActivationState checks are added for focus and close after losing focus. * Add setting to activate the behavior --------- Co-authored-by: Jaime Bernardo <jaime@janeasystems.com>
This commit is contained in:
@@ -46,6 +46,7 @@ namespace Peek.UI
|
|||||||
{
|
{
|
||||||
// Core Services
|
// Core Services
|
||||||
services.AddTransient<NeighboringItemsQuery>();
|
services.AddTransient<NeighboringItemsQuery>();
|
||||||
|
services.AddSingleton<IUserSettings, UserSettings>();
|
||||||
|
|
||||||
// Views and ViewModels
|
// Views and ViewModels
|
||||||
services.AddTransient<TitleBar>();
|
services.AddTransient<TitleBar>();
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using System;
|
|||||||
using interop;
|
using interop;
|
||||||
using Microsoft.PowerToys.Telemetry;
|
using Microsoft.PowerToys.Telemetry;
|
||||||
using Microsoft.UI.Windowing;
|
using Microsoft.UI.Windowing;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
using Microsoft.UI.Xaml.Input;
|
using Microsoft.UI.Xaml.Input;
|
||||||
using Peek.Common.Constants;
|
using Peek.Common.Constants;
|
||||||
using Peek.FilePreviewer.Models;
|
using Peek.FilePreviewer.Models;
|
||||||
@@ -28,6 +29,7 @@ namespace Peek.UI
|
|||||||
public MainWindow()
|
public MainWindow()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
this.Activated += PeekWindow_Activated;
|
||||||
|
|
||||||
ViewModel = App.GetService<MainWindowViewModel>();
|
ViewModel = App.GetService<MainWindowViewModel>();
|
||||||
|
|
||||||
@@ -38,6 +40,23 @@ namespace Peek.UI
|
|||||||
AppWindow.Closing += AppWindow_Closing;
|
AppWindow.Closing += AppWindow_Closing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void PeekWindow_Activated(object sender, Microsoft.UI.Xaml.WindowActivatedEventArgs args)
|
||||||
|
{
|
||||||
|
if (args.WindowActivationState == Microsoft.UI.Xaml.WindowActivationState.CodeActivated)
|
||||||
|
{
|
||||||
|
this.BringToForeground();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.WindowActivationState == Microsoft.UI.Xaml.WindowActivationState.Deactivated)
|
||||||
|
{
|
||||||
|
var userSettings = App.GetService<IUserSettings>();
|
||||||
|
if (userSettings.CloseAfterLosingFocus)
|
||||||
|
{
|
||||||
|
Uninitialize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handle Peek hotkey, by toggling the window visibility and querying files when necessary.
|
/// Handle Peek hotkey, by toggling the window visibility and querying files when necessary.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
13
src/modules/peek/Peek.UI/Services/IUserSettings.cs
Normal file
13
src/modules/peek/Peek.UI/Services/IUserSettings.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
namespace Peek.UI
|
||||||
|
{
|
||||||
|
public interface IUserSettings
|
||||||
|
{
|
||||||
|
public bool CloseAfterLosingFocus { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
85
src/modules/peek/Peek.UI/Services/UserSettings.cs
Normal file
85
src/modules/peek/Peek.UI/Services/UserSettings.cs
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// 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.IO;
|
||||||
|
using System.IO.Abstractions;
|
||||||
|
using System.Threading;
|
||||||
|
using ManagedCommon;
|
||||||
|
using Microsoft.PowerToys.Settings.UI.Library;
|
||||||
|
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
|
||||||
|
|
||||||
|
namespace Peek.UI
|
||||||
|
{
|
||||||
|
public class UserSettings : IUserSettings
|
||||||
|
{
|
||||||
|
private const string PeekModuleName = "Peek";
|
||||||
|
private const int MaxNumberOfRetry = 5;
|
||||||
|
|
||||||
|
private readonly ISettingsUtils _settingsUtils;
|
||||||
|
private readonly IFileSystemWatcher _watcher;
|
||||||
|
private readonly object _loadingSettingsLock = new object();
|
||||||
|
|
||||||
|
public bool CloseAfterLosingFocus { get; private set; }
|
||||||
|
|
||||||
|
public UserSettings()
|
||||||
|
{
|
||||||
|
_settingsUtils = new SettingsUtils();
|
||||||
|
CloseAfterLosingFocus = false;
|
||||||
|
|
||||||
|
LoadSettingsFromJson();
|
||||||
|
|
||||||
|
_watcher = Helper.GetFileWatcher(PeekModuleName, "settings.json", () => LoadSettingsFromJson());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadSettingsFromJson()
|
||||||
|
{
|
||||||
|
lock (_loadingSettingsLock)
|
||||||
|
{
|
||||||
|
var retry = true;
|
||||||
|
var retryCount = 0;
|
||||||
|
|
||||||
|
while (retry)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
retryCount++;
|
||||||
|
|
||||||
|
if (!_settingsUtils.SettingsExists(PeekModuleName))
|
||||||
|
{
|
||||||
|
Logger.LogInfo("Hosts settings.json was missing, creating a new one");
|
||||||
|
var defaultSettings = new PeekSettings();
|
||||||
|
defaultSettings.Save(_settingsUtils);
|
||||||
|
}
|
||||||
|
|
||||||
|
var settings = _settingsUtils.GetSettingsOrDefault<PeekSettings>(PeekModuleName);
|
||||||
|
if (settings != null)
|
||||||
|
{
|
||||||
|
CloseAfterLosingFocus = settings.Properties.CloseAfterLosingFocus.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
retry = false;
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
if (retryCount > MaxNumberOfRetry)
|
||||||
|
{
|
||||||
|
retry = false;
|
||||||
|
Logger.LogError($"Failed to Deserialize PowerToys settings, Retrying {e.Message}", e);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Thread.Sleep(500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
retry = false;
|
||||||
|
Logger.LogError("Failed to read changed settings", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,12 +12,15 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
|||||||
{
|
{
|
||||||
ActivationShortcut = new HotkeySettings(false, true, false, false, 0x20);
|
ActivationShortcut = new HotkeySettings(false, true, false, false, 0x20);
|
||||||
AlwaysRunNotElevated = new BoolProperty(true);
|
AlwaysRunNotElevated = new BoolProperty(true);
|
||||||
|
CloseAfterLosingFocus = new BoolProperty(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HotkeySettings ActivationShortcut { get; set; }
|
public HotkeySettings ActivationShortcut { get; set; }
|
||||||
|
|
||||||
public BoolProperty AlwaysRunNotElevated { get; set; }
|
public BoolProperty AlwaysRunNotElevated { get; set; }
|
||||||
|
|
||||||
|
public BoolProperty CloseAfterLosingFocus { get; set; }
|
||||||
|
|
||||||
public override string ToString() => JsonSerializer.Serialize(this);
|
public override string ToString() => JsonSerializer.Serialize(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
// 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.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
|
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
|
||||||
|
|
||||||
@@ -31,5 +33,21 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void Save(ISettingsUtils settingsUtils)
|
||||||
|
{
|
||||||
|
// Save settings to file
|
||||||
|
var options = new JsonSerializerOptions
|
||||||
|
{
|
||||||
|
WriteIndented = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (settingsUtils == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(settingsUtils));
|
||||||
|
}
|
||||||
|
|
||||||
|
settingsUtils.SaveSettings(JsonSerializer.Serialize(this, options), ModuleName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2843,6 +2843,10 @@ From there, simply click on one of the supported files in the File Explorer and
|
|||||||
<value>Tries to run Peek without elevated permissions, to fix access to network shares. You need to disable and re-enable Peek for changes to this value to take effect.</value>
|
<value>Tries to run Peek without elevated permissions, to fix access to network shares. You need to disable and re-enable Peek for changes to this value to take effect.</value>
|
||||||
<comment>Peek is a product name, do not loc</comment>
|
<comment>Peek is a product name, do not loc</comment>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Peek_CloseAfterLosingFocus.Header" xml:space="preserve">
|
||||||
|
<value>Automatically close the Peek window after it loses focus</value>
|
||||||
|
<comment>Peek is a product name, do not loc</comment>
|
||||||
|
</data>
|
||||||
<data name="FancyZones_DisableRoundCornersOnWindowSnap.Content" xml:space="preserve">
|
<data name="FancyZones_DisableRoundCornersOnWindowSnap.Content" xml:space="preserve">
|
||||||
<value>Disable round corners when window is snapped</value>
|
<value>Disable round corners when window is snapped</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -123,6 +123,20 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool CloseAfterLosingFocus
|
||||||
|
{
|
||||||
|
get => _peekSettings.Properties.CloseAfterLosingFocus.Value;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_peekSettings.Properties.CloseAfterLosingFocus.Value != value)
|
||||||
|
{
|
||||||
|
_peekSettings.Properties.CloseAfterLosingFocus.Value = value;
|
||||||
|
OnPropertyChanged(nameof(CloseAfterLosingFocus));
|
||||||
|
NotifySettingsChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void NotifySettingsChanged()
|
private void NotifySettingsChanged()
|
||||||
{
|
{
|
||||||
// Using InvariantCulture as this is an IPC message
|
// Using InvariantCulture as this is an IPC message
|
||||||
|
|||||||
@@ -37,6 +37,11 @@
|
|||||||
x:Uid="ToggleSwitch"
|
x:Uid="ToggleSwitch"
|
||||||
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.AlwaysRunNotElevated}" />
|
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.AlwaysRunNotElevated}" />
|
||||||
</labs:SettingsCard>
|
</labs:SettingsCard>
|
||||||
|
<labs:SettingsCard x:Uid="Peek_CloseAfterLosingFocus">
|
||||||
|
<ToggleSwitch
|
||||||
|
x:Uid="ToggleSwitch"
|
||||||
|
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.CloseAfterLosingFocus}" />
|
||||||
|
</labs:SettingsCard>
|
||||||
</controls:SettingsGroup>
|
</controls:SettingsGroup>
|
||||||
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|||||||
Reference in New Issue
Block a user