mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
[QuickAccent]Add setting to sort characters by use frequency (#22847)
* [Quick Accent] add toggle switch to sort characters by usage frequency * [Quick Accent] if enabled, then sort by frequency for all toolbar triggers * [Quick Accent] add "start selection from the left" toggle switch * [Quick Accent] fix error SA1000: The keyword 'new' should not be followed by a space * Fix C# analyzer build error
This commit is contained in:
@@ -37,6 +37,8 @@ public class PowerAccent : IDisposable
|
|||||||
|
|
||||||
private readonly KeyboardListener _keyboardListener;
|
private readonly KeyboardListener _keyboardListener;
|
||||||
|
|
||||||
|
private readonly CharactersUsageInfo _usageInfo;
|
||||||
|
|
||||||
public PowerAccent()
|
public PowerAccent()
|
||||||
{
|
{
|
||||||
LoadUnicodeInfoCache();
|
LoadUnicodeInfoCache();
|
||||||
@@ -44,6 +46,7 @@ public class PowerAccent : IDisposable
|
|||||||
_keyboardListener = new KeyboardListener();
|
_keyboardListener = new KeyboardListener();
|
||||||
_keyboardListener.InitHook();
|
_keyboardListener.InitHook();
|
||||||
_settingService = new SettingsService(_keyboardListener);
|
_settingService = new SettingsService(_keyboardListener);
|
||||||
|
_usageInfo = new CharactersUsageInfo();
|
||||||
|
|
||||||
SetEvents();
|
SetEvents();
|
||||||
}
|
}
|
||||||
@@ -88,9 +91,9 @@ public class PowerAccent : IDisposable
|
|||||||
private void ShowToolbar(LetterKey letterKey)
|
private void ShowToolbar(LetterKey letterKey)
|
||||||
{
|
{
|
||||||
_visible = true;
|
_visible = true;
|
||||||
_characters = (WindowsFunctions.IsCapsLockState() || WindowsFunctions.IsShiftState()) ? ToUpper(Languages.GetDefaultLetterKey(letterKey, _settingService.SelectedLang)) : Languages.GetDefaultLetterKey(letterKey, _settingService.SelectedLang);
|
|
||||||
_characterDescriptions = GetCharacterDescriptions(_characters);
|
|
||||||
|
|
||||||
|
_characters = GetCharacters(letterKey);
|
||||||
|
_characterDescriptions = GetCharacterDescriptions(_characters);
|
||||||
_showUnicodeDescription = _settingService.ShowUnicodeDescription;
|
_showUnicodeDescription = _settingService.ShowUnicodeDescription;
|
||||||
|
|
||||||
Task.Delay(_settingService.InputTime).ContinueWith(
|
Task.Delay(_settingService.InputTime).ContinueWith(
|
||||||
@@ -104,6 +107,28 @@ public class PowerAccent : IDisposable
|
|||||||
TaskScheduler.FromCurrentSynchronizationContext());
|
TaskScheduler.FromCurrentSynchronizationContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string[] GetCharacters(LetterKey letterKey)
|
||||||
|
{
|
||||||
|
var characters = Languages.GetDefaultLetterKey(letterKey, _settingService.SelectedLang);
|
||||||
|
if (_settingService.SortByUsageFrequency)
|
||||||
|
{
|
||||||
|
characters = characters.OrderByDescending(character => _usageInfo.GetUsageFrequency(character))
|
||||||
|
.ThenByDescending(character => _usageInfo.GetLastUsageTimestamp(character)).
|
||||||
|
ToArray<string>();
|
||||||
|
}
|
||||||
|
else if (!_usageInfo.Empty())
|
||||||
|
{
|
||||||
|
_usageInfo.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WindowsFunctions.IsCapsLockState() || WindowsFunctions.IsShiftState())
|
||||||
|
{
|
||||||
|
return ToUpper(characters);
|
||||||
|
}
|
||||||
|
|
||||||
|
return characters;
|
||||||
|
}
|
||||||
|
|
||||||
private string GetCharacterDescription(string character)
|
private string GetCharacterDescription(string character)
|
||||||
{
|
{
|
||||||
List<UnicodeCharInfo> unicodeList = new List<UnicodeCharInfo>();
|
List<UnicodeCharInfo> unicodeList = new List<UnicodeCharInfo>();
|
||||||
@@ -180,6 +205,11 @@ public class PowerAccent : IDisposable
|
|||||||
if (_selectedIndex != -1)
|
if (_selectedIndex != -1)
|
||||||
{
|
{
|
||||||
WindowsFunctions.Insert(_characters[_selectedIndex], true);
|
WindowsFunctions.Insert(_characters[_selectedIndex], true);
|
||||||
|
|
||||||
|
if (_settingService.SortByUsageFrequency)
|
||||||
|
{
|
||||||
|
_usageInfo.IncrementUsageFrequency(_characters[_selectedIndex]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -205,7 +235,7 @@ public class PowerAccent : IDisposable
|
|||||||
_selectedIndex = _characters.Length / 2;
|
_selectedIndex = _characters.Length / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (triggerKey == TriggerKey.Space)
|
if (triggerKey == TriggerKey.Space || _settingService.StartSelectionFromTheLeft)
|
||||||
{
|
{
|
||||||
_selectedIndex = 0;
|
_selectedIndex = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,6 +92,8 @@ public class SettingsService
|
|||||||
}
|
}
|
||||||
|
|
||||||
ShowUnicodeDescription = settings.Properties.ShowUnicodeDescription;
|
ShowUnicodeDescription = settings.Properties.ShowUnicodeDescription;
|
||||||
|
SortByUsageFrequency = settings.Properties.SortByUsageFrequency;
|
||||||
|
StartSelectionFromTheLeft = settings.Properties.StartSelectionFromTheLeft;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -191,6 +193,36 @@ public class SettingsService
|
|||||||
_showUnicodeDescription = value;
|
_showUnicodeDescription = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool _sortByUsageFrequency;
|
||||||
|
|
||||||
|
public bool SortByUsageFrequency
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _sortByUsageFrequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_sortByUsageFrequency = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool _startSelectionFromTheLeft;
|
||||||
|
|
||||||
|
public bool StartSelectionFromTheLeft
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _startSelectionFromTheLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_startSelectionFromTheLeft = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Position
|
public enum Position
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
// 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 PowerAccent.Core.Tools
|
||||||
|
{
|
||||||
|
public class CharactersUsageInfo
|
||||||
|
{
|
||||||
|
private Dictionary<string, uint> _characterUsageCounters = new Dictionary<string, uint>();
|
||||||
|
private Dictionary<string, long> _characterUsageTimestamp = new Dictionary<string, long>();
|
||||||
|
|
||||||
|
public bool Empty()
|
||||||
|
{
|
||||||
|
return _characterUsageCounters.Count == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
_characterUsageCounters.Clear();
|
||||||
|
_characterUsageTimestamp.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint GetUsageFrequency(string character)
|
||||||
|
{
|
||||||
|
_characterUsageCounters.TryGetValue(character, out uint frequency);
|
||||||
|
|
||||||
|
return frequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long GetLastUsageTimestamp(string character)
|
||||||
|
{
|
||||||
|
_characterUsageTimestamp.TryGetValue(character, out long timestamp);
|
||||||
|
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void IncrementUsageFrequency(string character)
|
||||||
|
{
|
||||||
|
if (_characterUsageCounters.ContainsKey(character))
|
||||||
|
{
|
||||||
|
_characterUsageCounters[character]++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_characterUsageCounters.Add(character, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
_characterUsageTimestamp[character] = DateTimeOffset.Now.ToUnixTimeSeconds();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,6 +27,12 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
|||||||
[JsonPropertyName("show_description")]
|
[JsonPropertyName("show_description")]
|
||||||
public bool ShowUnicodeDescription { get; set; }
|
public bool ShowUnicodeDescription { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("sort_by_usage_frequency")]
|
||||||
|
public bool SortByUsageFrequency { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("start_selection_from_the_left")]
|
||||||
|
public bool StartSelectionFromTheLeft { get; set; }
|
||||||
|
|
||||||
public PowerAccentProperties()
|
public PowerAccentProperties()
|
||||||
{
|
{
|
||||||
ActivationKey = PowerAccentActivationKey.Both;
|
ActivationKey = PowerAccentActivationKey.Both;
|
||||||
@@ -35,6 +41,8 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
|||||||
SelectedLang = "ALL";
|
SelectedLang = "ALL";
|
||||||
ExcludedApps = new StringProperty();
|
ExcludedApps = new StringProperty();
|
||||||
ShowUnicodeDescription = false;
|
ShowUnicodeDescription = false;
|
||||||
|
SortByUsageFrequency = false;
|
||||||
|
StartSelectionFromTheLeft = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2675,6 +2675,18 @@ Activate by holding the key for the character you want to add an accent to, then
|
|||||||
<data name="QuickAccent_Description_Indicator.Header" xml:space="preserve">
|
<data name="QuickAccent_Description_Indicator.Header" xml:space="preserve">
|
||||||
<value>Show the Unicode code and name of the currently selected character</value>
|
<value>Show the Unicode code and name of the currently selected character</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="QuickAccent_SortByUsageFrequency_Indicator.Header" xml:space="preserve">
|
||||||
|
<value>Sort characters by usage frequency</value>
|
||||||
|
</data>
|
||||||
|
<data name="QuickAccent_SortByUsageFrequency_Indicator.Description" xml:space="preserve">
|
||||||
|
<value>Track characters usage frequency and sort them accordingly</value>
|
||||||
|
</data>
|
||||||
|
<data name="QuickAccent_StartSelectionFromTheLeft_Indicator.Header" xml:space="preserve">
|
||||||
|
<value>Start selection from the left</value>
|
||||||
|
</data>
|
||||||
|
<data name="QuickAccent_StartSelectionFromTheLeft_Indicator.Description" xml:space="preserve">
|
||||||
|
<value>Start selection from the leftmost character for all activation keys, including left and right arrows</value>
|
||||||
|
</data>
|
||||||
<data name="QuickAccent_DisableFullscreen.Header" xml:space="preserve">
|
<data name="QuickAccent_DisableFullscreen.Header" xml:space="preserve">
|
||||||
<value>Disable when Game Mode is On</value>
|
<value>Disable when Game Mode is On</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -256,6 +256,42 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool SortByUsageFrequency
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _powerAccentSettings.Properties.SortByUsageFrequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _powerAccentSettings.Properties.SortByUsageFrequency)
|
||||||
|
{
|
||||||
|
_powerAccentSettings.Properties.SortByUsageFrequency = value;
|
||||||
|
OnPropertyChanged(nameof(SortByUsageFrequency));
|
||||||
|
RaisePropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool StartSelectionFromTheLeft
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _powerAccentSettings.Properties.StartSelectionFromTheLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _powerAccentSettings.Properties.StartSelectionFromTheLeft)
|
||||||
|
{
|
||||||
|
_powerAccentSettings.Properties.StartSelectionFromTheLeft = value;
|
||||||
|
OnPropertyChanged(nameof(StartSelectionFromTheLeft));
|
||||||
|
RaisePropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void RaisePropertyChanged([CallerMemberName] string propertyName = null)
|
private void RaisePropertyChanged([CallerMemberName] string propertyName = null)
|
||||||
{
|
{
|
||||||
// Notify UI of property change
|
// Notify UI of property change
|
||||||
|
|||||||
@@ -114,6 +114,12 @@
|
|||||||
<labs:SettingsCard x:Uid="QuickAccent_Description_Indicator" HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=}">
|
<labs:SettingsCard x:Uid="QuickAccent_Description_Indicator" HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=}">
|
||||||
<ToggleSwitch x:Uid="QuickAccent_UnicodeDescription_ToggleSwitch" IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.ShowUnicodeDescription}" />
|
<ToggleSwitch x:Uid="QuickAccent_UnicodeDescription_ToggleSwitch" IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.ShowUnicodeDescription}" />
|
||||||
</labs:SettingsCard>
|
</labs:SettingsCard>
|
||||||
|
<labs:SettingsCard x:Uid="QuickAccent_SortByUsageFrequency_Indicator" HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=}">
|
||||||
|
<ToggleSwitch x:Uid="QuickAccent_SortByUsageFrequency_ToggleSwitch" IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.SortByUsageFrequency}" />
|
||||||
|
</labs:SettingsCard>
|
||||||
|
<labs:SettingsCard x:Uid="QuickAccent_StartSelectionFromTheLeft_Indicator" HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=}">
|
||||||
|
<ToggleSwitch x:Uid="QuickAccent_StartSelectionFromTheLeft_ToggleSwitch" IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.StartSelectionFromTheLeft}" />
|
||||||
|
</labs:SettingsCard>
|
||||||
</controls:SettingsGroup>
|
</controls:SettingsGroup>
|
||||||
|
|
||||||
<controls:SettingsGroup
|
<controls:SettingsGroup
|
||||||
|
|||||||
Reference in New Issue
Block a user