[PT Run] Run dialog now has monitor positioning options (#9492)

* Run dialog now has monitor positioning options

* add monitor index validation in window position calculation

* correct path in page

* change how radio buttons are declared to resolve them not being set based on setting

* Change "follow mouse" wording

Co-authored-by: htcfreek <61519853+htcfreek@users.noreply.github.com>

* PowerLauncher -> PowerToysRun for new variables/resources

* correct header label id and update wording to PowerToys Run

* only enable custom index if BOTH custom position radio checked and Run is enabled

* retrieve list count of detected monitors to limit selection of MonitorToDisplayOn

* add a link to Windows Display settings

* fix display settings link

* change how we get the number of connected monitors so we're not relying on presentation core, windowsbase etc which seem to fail the build

* combine position and appearance headers

* change references for custom position to "focus"

* restore accidentally removed files

* remove unused directives

* hook up "active window" position with the launcher window

* remove left overs

* remove uneeded itemgroup

* make resource prefixes consistent; using "Run_"

* add etcoreapp to spell check

* undo change to file not modified in the end

* remove unused checkbox post rebase

* remove change to reduce diff size

* changes according to review

* revert whitespace changes post rebase

* revert resources

* add changes back

* Update src/settings-ui/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw

Add comment

Co-authored-by: Enrico Giordani <enricogior@users.noreply.github.com>

* remove unneeded resource string

Co-authored-by: htcfreek <61519853+htcfreek@users.noreply.github.com>
Co-authored-by: Enrico Giordani <enricogior@users.noreply.github.com>
This commit is contained in:
Adam Short 2021-03-09 17:20:49 +00:00 committed by GitHub
parent 964286ab99
commit 5c45f2c7b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 160 additions and 4 deletions

View File

@ -663,6 +663,7 @@ ERRORTITLE
esize esize
estdir estdir
etcore etcore
etcoreapp
etl etl
etw etw
EUQ EUQ

View 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.
namespace ManagedCommon
{
public enum StartupPosition
{
Cursor,
PrimaryMonitor,
Focus,
}
}

View File

@ -207,7 +207,7 @@ namespace PowerLauncher
/// <returns>X co-ordinate of main window top left corner</returns> /// <returns>X co-ordinate of main window top left corner</returns>
private double WindowLeft() private double WindowLeft()
{ {
var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position); var screen = GetScreen();
var dip1 = WindowsInteropHelper.TransformPixelsToDIP(this, screen.WorkingArea.X, 0); var dip1 = WindowsInteropHelper.TransformPixelsToDIP(this, screen.WorkingArea.X, 0);
var dip2 = WindowsInteropHelper.TransformPixelsToDIP(this, screen.WorkingArea.Width, 0); var dip2 = WindowsInteropHelper.TransformPixelsToDIP(this, screen.WorkingArea.Width, 0);
var left = ((dip2.X - ActualWidth) / 2) + dip1.X; var left = ((dip2.X - ActualWidth) / 2) + dip1.X;
@ -216,13 +216,30 @@ namespace PowerLauncher
private double WindowTop() private double WindowTop()
{ {
var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position); var screen = GetScreen();
var dip1 = WindowsInteropHelper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Y); var dip1 = WindowsInteropHelper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Y);
var dip2 = WindowsInteropHelper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Height); var dip2 = WindowsInteropHelper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Height);
var top = ((dip2.Y - SearchBox.ActualHeight) / 4) + dip1.Y; var top = ((dip2.Y - SearchBox.ActualHeight) / 4) + dip1.Y;
return top; return top;
} }
private Screen GetScreen()
{
ManagedCommon.StartupPosition position = _settings.StartupPosition;
switch (position)
{
case ManagedCommon.StartupPosition.PrimaryMonitor:
return Screen.PrimaryScreen;
case ManagedCommon.StartupPosition.Focus:
IntPtr foregroundWindowHandle = NativeMethods.GetForegroundWindow();
Screen activeScreen = Screen.FromHandle(foregroundWindowHandle);
return activeScreen;
case ManagedCommon.StartupPosition.Cursor:
default:
return Screen.FromPoint(System.Windows.Forms.Cursor.Position);
}
}
private void Launcher_KeyDown(object sender, KeyEventArgs e) private void Launcher_KeyDown(object sender, KeyEventArgs e)
{ {
if (e.Key == Key.Tab && Keyboard.IsKeyDown(Key.LeftShift)) if (e.Key == Key.Tab && Keyboard.IsKeyDown(Key.LeftShift))

View File

@ -126,6 +126,11 @@ namespace PowerLauncher
_themeManager.ChangeTheme(_settings.Theme, true); _themeManager.ChangeTheme(_settings.Theme, true);
} }
if (_settings.StartupPosition != overloadSettings.Properties.Position)
{
_settings.StartupPosition = overloadSettings.Properties.Position;
}
retry = false; retry = false;
} }

View File

@ -47,6 +47,8 @@ namespace Wox.Infrastructure.UserSettings
public Theme Theme { get; set; } = Theme.System; public Theme Theme { get; set; } = Theme.System;
public StartupPosition StartupPosition { get; set; } = StartupPosition.Cursor;
public string QueryBoxFont { get; set; } = FontFamily.GenericSansSerif.Name; public string QueryBoxFont { get; set; } = FontFamily.GenericSansSerif.Name;
public string QueryBoxFontStyle { get; set; } public string QueryBoxFontStyle { get; set; }

View File

@ -45,6 +45,9 @@ namespace Microsoft.PowerToys.Settings.UI.Library
[JsonPropertyName("theme")] [JsonPropertyName("theme")]
public Theme Theme { get; set; } public Theme Theme { get; set; }
[JsonPropertyName("startupPosition")]
public StartupPosition Position { get; set; }
public PowerLauncherProperties() public PowerLauncherProperties()
{ {
OpenPowerLauncher = new HotkeySettings(false, false, true, false, 32); OpenPowerLauncher = new HotkeySettings(false, false, true, false, 32);
@ -57,6 +60,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
ClearInputOnLaunch = false; ClearInputOnLaunch = false;
MaximumNumberOfResults = 4; MaximumNumberOfResults = 4;
Theme = Theme.System; Theme = Theme.System;
Position = StartupPosition.Cursor;
} }
} }
} }

View File

@ -22,6 +22,10 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels
private bool _isLightThemeRadioButtonChecked; private bool _isLightThemeRadioButtonChecked;
private bool _isSystemThemeRadioButtonChecked; private bool _isSystemThemeRadioButtonChecked;
private bool _isCursorPositionRadioButtonChecked;
private bool _isPrimaryMonitorPositionRadioButtonChecked;
private bool _isFocusPositionRadioButtonChecked;
private GeneralSettings GeneralSettingsConfig { get; set; } private GeneralSettings GeneralSettingsConfig { get; set; }
private readonly ISettingsUtils _settingsUtils; private readonly ISettingsUtils _settingsUtils;
@ -89,6 +93,19 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels
break; break;
} }
switch (settings.Properties.Position)
{
case StartupPosition.Cursor:
_isCursorPositionRadioButtonChecked = true;
break;
case StartupPosition.PrimaryMonitor:
_isPrimaryMonitorPositionRadioButtonChecked = true;
break;
case StartupPosition.Focus:
_isFocusPositionRadioButtonChecked = true;
break;
}
foreach (var plugin in Plugins) foreach (var plugin in Plugins)
{ {
plugin.PropertyChanged += OnPluginInfoChange; plugin.PropertyChanged += OnPluginInfoChange;
@ -243,6 +260,66 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels
} }
} }
public bool IsCursorPositionRadioButtonChecked
{
get
{
return _isCursorPositionRadioButtonChecked;
}
set
{
if (value == true)
{
settings.Properties.Position = StartupPosition.Cursor;
}
_isCursorPositionRadioButtonChecked = value;
UpdateSettings();
}
}
public bool IsPrimaryMonitorPositionRadioButtonChecked
{
get
{
return _isPrimaryMonitorPositionRadioButtonChecked;
}
set
{
if (value == true)
{
settings.Properties.Position = StartupPosition.PrimaryMonitor;
}
_isPrimaryMonitorPositionRadioButtonChecked = value;
UpdateSettings();
}
}
public bool IsFocusPositionRadioButtonChecked
{
get
{
return _isFocusPositionRadioButtonChecked;
}
set
{
if (value == true)
{
settings.Properties.Position = StartupPosition.Focus;
}
_isFocusPositionRadioButtonChecked = value;
UpdateSettings();
}
}
public HotkeySettings OpenPowerLauncher public HotkeySettings OpenPowerLauncher
{ {
get get

View File

@ -1151,4 +1151,20 @@ Win + Shift + O to toggle your video</value>
<data name="SettingsWindow_Title" xml:space="preserve"> <data name="SettingsWindow_Title" xml:space="preserve">
<value>PowerToys Settings</value> <value>PowerToys Settings</value>
</data> </data>
</root> <data name="Run_PositionAppearance_GroupSettings.Text" xml:space="preserve">
<value>Position &amp; appearance</value>
</data>
<data name="Run_PositionHeader.Text" xml:space="preserve">
<value>Show PowerToys Run on</value>
<comment>as in Show PowerToys Run on primary monitor</comment>
</data>
<data name="Run_Radio_Position_Cursor.Content" xml:space="preserve">
<value>Monitor with mouse cursor</value>
</data>
<data name="Run_Radio_Position_Focus.Content" xml:space="preserve">
<value>Monitor with focused window</value>
</data>
<data name="Run_Radio_Position_Primary_Monitor.Content" xml:space="preserve">
<value>Primary monitor</value>
</data>
</root>

View File

@ -148,9 +148,30 @@
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.EnablePowerLauncher}" IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.EnablePowerLauncher}"
/> />
<TextBlock x:Uid="Appearance_GroupSettings" <TextBlock x:Uid="Run_PositionAppearance_GroupSettings"
Style="{StaticResource SettingsGroupTitleStyle}" Style="{StaticResource SettingsGroupTitleStyle}"
Foreground="{x:Bind Mode=OneWay, Path=ViewModel.EnablePowerLauncher, Converter={StaticResource ModuleEnabledToForegroundConverter}}" /> Foreground="{x:Bind Mode=OneWay, Path=ViewModel.EnablePowerLauncher, Converter={StaticResource ModuleEnabledToForegroundConverter}}" />
<TextBlock x:Uid="Run_PositionHeader"
x:Name="RadioButtons_Name_Position"
Margin="{StaticResource SmallTopMargin}"
Foreground="{x:Bind Mode=OneWay, Path=ViewModel.EnablePowerLauncher, Converter={StaticResource ModuleEnabledToForegroundConverter}}" />
<RadioButton x:Uid="Run_Radio_Position_Primary_Monitor"
GroupName="Run_Position"
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.IsPrimaryMonitorPositionRadioButtonChecked}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.EnablePowerLauncher}"/>
<RadioButton x:Uid="Run_Radio_Position_Cursor"
GroupName="Run_Position"
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.IsCursorPositionRadioButtonChecked}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.EnablePowerLauncher}"/>
<RadioButton x:Uid="Run_Radio_Position_Focus"
GroupName="Run_Position"
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.IsFocusPositionRadioButtonChecked}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.EnablePowerLauncher}"/>
<!-- We cannot navigate to all the radio buttons using the arrow keys because of an XYNavigation issue in the RadioButtons control. <!-- We cannot navigate to all the radio buttons using the arrow keys because of an XYNavigation issue in the RadioButtons control.
The screen reader does not read the heading when we tab into a radio button, even though the LabeledBy automation property is set. The screen reader does not read the heading when we tab into a radio button, even though the LabeledBy automation property is set.
Link to the issue in the winui repository - https://github.com/microsoft/microsoft-ui-xaml/issues/3156 --> Link to the issue in the winui repository - https://github.com/microsoft/microsoft-ui-xaml/issues/3156 -->