Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Peek] WindowActivationState checks are added for focus and close aft… #26364

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/modules/peek/Peek.UI/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public App()
{
// Core Services
services.AddTransient<NeighboringItemsQuery>();
services.AddSingleton<IUserSettings, UserSettings>();

// Views and ViewModels
services.AddTransient<TitleBar>();
Expand Down
19 changes: 19 additions & 0 deletions src/modules/peek/Peek.UI/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using interop;
using Microsoft.PowerToys.Telemetry;
using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Input;
using Peek.Common.Constants;
using Peek.FilePreviewer.Models;
Expand All @@ -28,6 +29,7 @@ public sealed partial class MainWindow : WindowEx
public MainWindow()
{
InitializeComponent();
this.Activated += PeekWindow_Activated;

ViewModel = App.GetService<MainWindowViewModel>();

Expand All @@ -38,6 +40,23 @@ public MainWindow()
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>
/// Handle Peek hotkey, by toggling the window visibility and querying files when necessary.
/// </summary>
Expand Down
13 changes: 13 additions & 0 deletions src/modules/peek/Peek.UI/Services/IUserSettings.cs
Original file line number Diff line number Diff line change
@@ -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 changes: 85 additions & 0 deletions src/modules/peek/Peek.UI/Services/UserSettings.cs
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
}
}
}
3 changes: 3 additions & 0 deletions src/settings-ui/Settings.UI.Library/PeekProperties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@ public PeekProperties()
{
ActivationShortcut = new HotkeySettings(false, true, false, false, 0x20);
AlwaysRunNotElevated = new BoolProperty(true);
CloseAfterLosingFocus = new BoolProperty(false);
}

public HotkeySettings ActivationShortcut { get; set; }

public BoolProperty AlwaysRunNotElevated { get; set; }

public BoolProperty CloseAfterLosingFocus { get; set; }

public override string ToString() => JsonSerializer.Serialize(this);
}
}
18 changes: 18 additions & 0 deletions src/settings-ui/Settings.UI.Library/PeekSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// 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.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;

Expand Down Expand Up @@ -31,5 +33,21 @@ public bool UpgradeSettingsConfiguration()
{
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);
}
}
}
4 changes: 4 additions & 0 deletions src/settings-ui/Settings.UI/Strings/en-us/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -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>
<comment>Peek is a product name, do not loc</comment>
</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">
<value>Disable round corners when window is snapped</value>
</data>
Expand Down
14 changes: 14 additions & 0 deletions src/settings-ui/Settings.UI/ViewModels/PeekViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,20 @@ public bool AlwaysRunNotElevated
}
}

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()
{
// Using InvariantCulture as this is an IPC message
Expand Down
5 changes: 5 additions & 0 deletions src/settings-ui/Settings.UI/Views/PeekPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@
x:Uid="ToggleSwitch"
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.AlwaysRunNotElevated}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="Peek_CloseAfterLosingFocus">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.CloseAfterLosingFocus}" />
</labs:SettingsCard>
</controls:SettingsGroup>

</StackPanel>
Expand Down