mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 02:36:19 +02:00
[New Utility]Mouse Without Borders
* Integrate Mouse Without Borders into PowerToys --------- Co-authored-by: Jaime Bernardo <jaime@janeasystems.com>
This commit is contained in:
committed by
Jaime Bernardo
parent
a0b9af039d
commit
29eebe16a4
@@ -182,6 +182,22 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
}
|
||||
}
|
||||
|
||||
private bool mouseWithoutBorders = true;
|
||||
|
||||
[JsonPropertyName("MouseWithoutBorders")]
|
||||
public bool MouseWithoutBorders
|
||||
{
|
||||
get => mouseWithoutBorders;
|
||||
set
|
||||
{
|
||||
if (mouseWithoutBorders != value)
|
||||
{
|
||||
LogTelemetryEvent(value);
|
||||
mouseWithoutBorders = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool findMyMouse = true;
|
||||
|
||||
[JsonPropertyName("FindMyMouse")]
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// 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;
|
||||
|
||||
@@ -29,5 +30,15 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
return JsonSerializer.Serialize(this);
|
||||
}
|
||||
|
||||
public static implicit operator IntProperty(int v)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public static implicit operator IntProperty(uint v)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
// 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
#pragma warning disable SA1649 // File name should match first type name
|
||||
public struct ConnectionRequest
|
||||
#pragma warning restore SA1649 // File name should match first type name
|
||||
{
|
||||
public string PCName;
|
||||
public string SecurityKey;
|
||||
}
|
||||
|
||||
public struct NewKeyGenerationRequest
|
||||
{
|
||||
}
|
||||
|
||||
public class MouseWithoutBordersProperties : ICloneable
|
||||
{
|
||||
public StringProperty SecurityKey { get; set; }
|
||||
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
public bool UseService { get; set; }
|
||||
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
public bool ShowOriginalUI { get; set; }
|
||||
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
public bool WrapMouse { get; set; }
|
||||
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
public bool ShareClipboard { get; set; }
|
||||
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
public bool TransferFile { get; set; }
|
||||
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
public bool HideMouseAtScreenEdge { get; set; }
|
||||
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
public bool DrawMouseCursor { get; set; }
|
||||
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
public bool ValidateRemoteMachineIP { get; set; }
|
||||
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
public bool SameSubnetOnly { get; set; }
|
||||
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
public bool BlockScreenSaverOnOtherMachines { get; set; }
|
||||
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
public bool MoveMouseRelatively { get; set; }
|
||||
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
public bool BlockMouseAtScreenCorners { get; set; }
|
||||
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
public bool ShowClipboardAndNetworkStatusMessages { get; set; }
|
||||
|
||||
public List<string> MachineMatrixString { get; set; }
|
||||
|
||||
public StringProperty MachinePool { get; set; }
|
||||
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
public bool MatrixOneRow { get; set; }
|
||||
|
||||
public IntProperty EasyMouse { get; set; }
|
||||
|
||||
public IntProperty MachineID { get; set; }
|
||||
|
||||
public IntProperty LastX { get; set; }
|
||||
|
||||
public IntProperty LastY { get; set; }
|
||||
|
||||
public IntProperty PackageID { get; set; }
|
||||
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
public bool FirstRun { get; set; }
|
||||
|
||||
public IntProperty HotKeySwitchMachine { get; set; }
|
||||
|
||||
public IntProperty HotKeyToggleEasyMouse { get; set; }
|
||||
|
||||
public IntProperty HotKeyLockMachine { get; set; }
|
||||
|
||||
public IntProperty HotKeyReconnect { get; set; }
|
||||
|
||||
public IntProperty HotKeySwitch2AllPC { get; set; }
|
||||
|
||||
public IntProperty TCPPort { get; set; }
|
||||
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
public bool DrawMouseEx { get; set; }
|
||||
|
||||
public StringProperty Name2IP { get; set; }
|
||||
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
public bool UseVKMap { get; set; }
|
||||
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
public bool FirstCtrlShiftS { get; set; }
|
||||
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
public bool StealFocusWhenSwitchingMachine { get; set; }
|
||||
|
||||
public StringProperty DeviceID { get; set; }
|
||||
|
||||
public MouseWithoutBordersProperties()
|
||||
{
|
||||
SecurityKey = new StringProperty(string.Empty);
|
||||
WrapMouse = true;
|
||||
ShareClipboard = true;
|
||||
TransferFile = true;
|
||||
HideMouseAtScreenEdge = true;
|
||||
DrawMouseCursor = true;
|
||||
ValidateRemoteMachineIP = false;
|
||||
SameSubnetOnly = false;
|
||||
BlockScreenSaverOnOtherMachines = true;
|
||||
MoveMouseRelatively = false;
|
||||
BlockMouseAtScreenCorners = false;
|
||||
ShowClipboardAndNetworkStatusMessages = false;
|
||||
EasyMouse = new IntProperty(1);
|
||||
MachineMatrixString = new List<string>();
|
||||
DeviceID = new StringProperty(string.Empty);
|
||||
ShowOriginalUI = false;
|
||||
UseService = false;
|
||||
|
||||
HotKeySwitchMachine = new IntProperty(0x70); // VK.F1
|
||||
HotKeyToggleEasyMouse = new IntProperty(0x45); // VK.E
|
||||
HotKeyLockMachine = new IntProperty(0x4C); // VK.L
|
||||
HotKeyReconnect = new IntProperty(0x52); // VK.R
|
||||
HotKeySwitch2AllPC = new IntProperty(0); // Disabled
|
||||
|
||||
// These are internal, i.e. cannot be edited directly from UI
|
||||
MachinePool = ":,:,:,:";
|
||||
MatrixOneRow = true;
|
||||
MachineID = new IntProperty(0);
|
||||
LastX = new IntProperty(0);
|
||||
LastY = new IntProperty(0);
|
||||
PackageID = new IntProperty(0);
|
||||
FirstRun = false;
|
||||
TCPPort = new IntProperty(15100);
|
||||
DrawMouseEx = true;
|
||||
Name2IP = new StringProperty(string.Empty);
|
||||
UseVKMap = false;
|
||||
FirstCtrlShiftS = false;
|
||||
StealFocusWhenSwitchingMachine = false;
|
||||
}
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
var clone = new MouseWithoutBordersProperties();
|
||||
clone = this;
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
// 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.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public class MouseWithoutBordersSettings : BasePTModuleSettings, ISettingsConfig
|
||||
{
|
||||
public const string ModuleName = "MouseWithoutBorders";
|
||||
|
||||
[JsonPropertyName("properties")]
|
||||
public MouseWithoutBordersProperties Properties { get; set; }
|
||||
|
||||
public MouseWithoutBordersSettings()
|
||||
{
|
||||
Name = ModuleName;
|
||||
Properties = new MouseWithoutBordersProperties();
|
||||
Version = "1.0";
|
||||
}
|
||||
|
||||
public string GetModuleName()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
// This can be utilized in the future if the settings.json file is to be modified/deleted.
|
||||
public bool UpgradeSettingsConfiguration()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual void Save(ISettingsUtils settingsUtils)
|
||||
{
|
||||
// Save settings to file
|
||||
var options = new JsonSerializerOptions
|
||||
{
|
||||
WriteIndented = true,
|
||||
MaxDepth = 0,
|
||||
IncludeFields = true,
|
||||
};
|
||||
|
||||
if (settingsUtils == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(settingsUtils));
|
||||
}
|
||||
|
||||
settingsUtils.SaveSettings(JsonSerializer.Serialize(this, options), ModuleName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.IO.Abstractions;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
@@ -23,22 +24,17 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
|
||||
public bool SettingsFolderExists(string powertoy)
|
||||
{
|
||||
return _directory.Exists(System.IO.Path.Combine(LocalApplicationDataFolder(), $"Microsoft\\PowerToys\\{powertoy}"));
|
||||
return _directory.Exists(System.IO.Path.Combine(Helper.LocalApplicationDataFolder(), $"Microsoft\\PowerToys\\{powertoy}"));
|
||||
}
|
||||
|
||||
public void CreateSettingsFolder(string powertoy)
|
||||
{
|
||||
_directory.CreateDirectory(System.IO.Path.Combine(LocalApplicationDataFolder(), $"Microsoft\\PowerToys\\{powertoy}"));
|
||||
_directory.CreateDirectory(System.IO.Path.Combine(Helper.LocalApplicationDataFolder(), $"Microsoft\\PowerToys\\{powertoy}"));
|
||||
}
|
||||
|
||||
public void DeleteSettings(string powertoy = "")
|
||||
{
|
||||
_directory.Delete(System.IO.Path.Combine(LocalApplicationDataFolder(), $"Microsoft\\PowerToys\\{powertoy}"));
|
||||
}
|
||||
|
||||
private static string LocalApplicationDataFolder()
|
||||
{
|
||||
return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
||||
_directory.Delete(System.IO.Path.Combine(Helper.LocalApplicationDataFolder(), $"Microsoft\\PowerToys\\{powertoy}"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -50,12 +46,12 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
if (string.IsNullOrWhiteSpace(powertoy))
|
||||
{
|
||||
return _path.Combine(
|
||||
LocalApplicationDataFolder(),
|
||||
Helper.LocalApplicationDataFolder(),
|
||||
$"Microsoft\\PowerToys\\{fileName}");
|
||||
}
|
||||
|
||||
return _path.Combine(
|
||||
LocalApplicationDataFolder(),
|
||||
Helper.LocalApplicationDataFolder(),
|
||||
$"Microsoft\\PowerToys\\{powertoy}\\{fileName}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +150,9 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
// This, while not totally ideal, does work around the problem by trimming the end.
|
||||
// The file itself did write the content correctly but something is off with the actual end of the file, hence the 0x00 bug
|
||||
var jsonSettingsString = _file.ReadAllText(_settingsPath.GetSettingsPath(powertoyFolderName, fileName)).Trim('\0');
|
||||
return JsonSerializer.Deserialize<T>(jsonSettingsString);
|
||||
|
||||
var options = new JsonSerializerOptions { MaxDepth = 0, IncludeFields = true };
|
||||
return JsonSerializer.Deserialize<T>(jsonSettingsString, options);
|
||||
}
|
||||
|
||||
// Save settings to a json file.
|
||||
|
||||
@@ -7,6 +7,8 @@ using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Linq;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Security.Principal;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.CustomAction;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library.Utilities
|
||||
@@ -15,6 +17,8 @@ namespace Microsoft.PowerToys.Settings.UI.Library.Utilities
|
||||
{
|
||||
public static readonly IFileSystem FileSystem = new FileSystem();
|
||||
|
||||
public static string UserLocalAppDataPath { get; set; } = string.Empty;
|
||||
|
||||
public static bool AllowRunnerToForeground()
|
||||
{
|
||||
var result = false;
|
||||
@@ -69,9 +73,20 @@ namespace Microsoft.PowerToys.Settings.UI.Library.Utilities
|
||||
return watcher;
|
||||
}
|
||||
|
||||
private static string LocalApplicationDataFolder()
|
||||
public static string LocalApplicationDataFolder()
|
||||
{
|
||||
return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
||||
WindowsIdentity currentUser = WindowsIdentity.GetCurrent();
|
||||
SecurityIdentifier currentUserSID = currentUser.User;
|
||||
|
||||
SecurityIdentifier localSystemSID = new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null);
|
||||
if (currentUserSID.Equals(localSystemSID) && UserLocalAppDataPath != string.Empty)
|
||||
{
|
||||
return UserLocalAppDataPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetPowerToysInstallationFolder()
|
||||
|
||||
@@ -14,6 +14,13 @@
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- TODO: fix issues and reenable -->
|
||||
<!-- These are caused by streamjsonrpc dependency on Microsoft.VisualStudio.Threading.Analyzers -->
|
||||
<!-- We might want to add that to the project and fix the issues as well -->
|
||||
<NoWarn>VSTHRD002;VSTHRD110;VSTHRD100;VSTHRD200;VSTHRD101</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutputPath>..\..\..\x64\Release\SettingsTest\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -359,6 +359,7 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
case "ImageResizer": return typeof(ImageResizerPage);
|
||||
case "KBM": return typeof(KeyboardManagerPage);
|
||||
case "MouseUtils": return typeof(MouseUtilsPage);
|
||||
case "MouseWithoutBorders": return typeof(MouseWithoutBordersPage);
|
||||
case "PowerRename": return typeof(PowerRenamePage);
|
||||
case "QuickAccent": return typeof(PowerAccentPage);
|
||||
case "FileExplorer": return typeof(PowerPreviewPage);
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 86 KiB |
@@ -0,0 +1,29 @@
|
||||
// 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.Globalization;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Converters
|
||||
{
|
||||
public class NegativeBoolToVisibilityConverter : IValueConverter
|
||||
{
|
||||
object IValueConverter.Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if ((bool)value)
|
||||
{
|
||||
return Visibility.Collapsed;
|
||||
}
|
||||
|
||||
return Visibility.Visible;
|
||||
}
|
||||
|
||||
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
42
src/settings-ui/Settings.UI/Helpers/AsyncCommand.cs
Normal file
42
src/settings-ui/Settings.UI/Helpers/AsyncCommand.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
// 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Helpers
|
||||
{
|
||||
internal sealed class AsyncCommand : ICommand
|
||||
{
|
||||
private readonly Func<Task> _execute;
|
||||
private readonly Func<bool> _canExecute;
|
||||
|
||||
public event EventHandler CanExecuteChanged;
|
||||
|
||||
public AsyncCommand(Func<Task> execute, Func<bool> canExecute = null)
|
||||
{
|
||||
_execute = execute;
|
||||
_canExecute = canExecute;
|
||||
}
|
||||
|
||||
public bool CanExecute(object parameter)
|
||||
{
|
||||
return _canExecute == null || _canExecute();
|
||||
}
|
||||
|
||||
public async void Execute(object parameter)
|
||||
{
|
||||
await _execute();
|
||||
}
|
||||
|
||||
public void RaiseCanExecuteChanged()
|
||||
{
|
||||
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
// 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.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Helpers
|
||||
{
|
||||
#pragma warning disable SA1649 // File name should match first type name
|
||||
public class IndexedItem<T>
|
||||
#pragma warning restore SA1649 // File name should match first type name
|
||||
{
|
||||
public T Item { get; set; }
|
||||
|
||||
public int Index { get; set; }
|
||||
|
||||
public IndexedItem(T item, int index)
|
||||
{
|
||||
Item = item;
|
||||
Index = index;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning disable SA1402 // File may only contain a single type
|
||||
public class IndexedObservableCollection<T> : ObservableCollection<IndexedItem<T>>
|
||||
#pragma warning restore SA1402 // File may only contain a single type
|
||||
{
|
||||
public IndexedObservableCollection(IEnumerable<T> items)
|
||||
{
|
||||
int index = 0;
|
||||
foreach (var item in items)
|
||||
{
|
||||
Add(new IndexedItem<T>(item, index++));
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<T> ToEnumerable()
|
||||
{
|
||||
return this.Select(x => x.Item);
|
||||
}
|
||||
|
||||
public void Swap(int index1, int index2)
|
||||
{
|
||||
var temp = this[index1];
|
||||
this[index1] = this[index2];
|
||||
this[index2] = temp;
|
||||
|
||||
// Update the original index of the items
|
||||
this[index1].Index = index1;
|
||||
this[index2].Index = index2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
// 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.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Helpers
|
||||
{
|
||||
public class Observable : INotifyPropertyChanged
|
||||
{
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
protected void Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
|
||||
{
|
||||
if (Equals(storage, value))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
storage = value;
|
||||
OnPropertyChanged(propertyName);
|
||||
}
|
||||
|
||||
protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
@@ -125,6 +125,9 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
case "MousePointerCrosshairs":
|
||||
needToUpdate = generalSettingsConfig.Enabled.MousePointerCrosshairs != isEnabled;
|
||||
generalSettingsConfig.Enabled.MousePointerCrosshairs = isEnabled; break;
|
||||
case "MouseWithoutBorders":
|
||||
needToUpdate = generalSettingsConfig.Enabled.MouseWithoutBorders != isEnabled;
|
||||
generalSettingsConfig.Enabled.MouseWithoutBorders = isEnabled; break;
|
||||
case "PastePlain":
|
||||
needToUpdate = generalSettingsConfig.Enabled.PastePlain != isEnabled;
|
||||
generalSettingsConfig.Enabled.PastePlain = isEnabled; break;
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Enums
|
||||
ImageResizer,
|
||||
KBM,
|
||||
MouseUtils,
|
||||
MouseWithoutBorders,
|
||||
Peek,
|
||||
PowerRename,
|
||||
Run,
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
<Page
|
||||
x:Class="Microsoft.PowerToys.Settings.UI.OOBE.Views.OobeMouseWithoutBorders"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:Microsoft.PowerToys.Settings.UI.OOBE.Views"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:toolkitcontrols="using:CommunityToolkit.WinUI.UI.Controls"
|
||||
mc:Ignorable="d">
|
||||
<controls:OOBEPageControl
|
||||
x:Uid="Oobe_MouseWithoutBorders"
|
||||
HeroImage="ms-appx:///Assets/Modules/OOBE/MouseWithoutBorders.png">
|
||||
|
||||
<controls:OOBEPageControl.PageContent>
|
||||
<StackPanel Orientation="Vertical">
|
||||
|
||||
<TextBlock
|
||||
x:Uid="Oobe_HowToUse"
|
||||
Style="{ThemeResource OobeSubtitleStyle}" />
|
||||
|
||||
<toolkitcontrols:MarkdownTextBlock
|
||||
x:Uid="Oobe_MouseWithoutBorders_HowToUse"
|
||||
Background="Transparent" />
|
||||
|
||||
<TextBlock
|
||||
x:Uid="Oobe_TipsAndTricks"
|
||||
Style="{ThemeResource OobeSubtitleStyle}" />
|
||||
|
||||
<toolkitcontrols:MarkdownTextBlock
|
||||
x:Uid="Oobe_MouseWithoutBorders_TipsAndTricks"
|
||||
Background="Transparent" />
|
||||
|
||||
<StackPanel
|
||||
Margin="0,24,0,0"
|
||||
Orientation="Horizontal"
|
||||
Spacing="12">
|
||||
<Button
|
||||
x:Uid="OOBE_Settings"
|
||||
Click="SettingsLaunchButton_Click" />
|
||||
<HyperlinkButton
|
||||
NavigateUri="https://aka.ms/PowerToysOverview_MouseWithoutBorders"
|
||||
Style="{StaticResource TextButtonStyle}">
|
||||
<TextBlock
|
||||
x:Uid="LearnMore_MouseWithoutBorders"
|
||||
TextWrapping="Wrap" />
|
||||
</HyperlinkButton>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</controls:OOBEPageControl.PageContent>
|
||||
</controls:OOBEPageControl>
|
||||
</Page>
|
||||
@@ -0,0 +1,47 @@
|
||||
// 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 Microsoft.PowerToys.Settings.UI.OOBE.Enums;
|
||||
using Microsoft.PowerToys.Settings.UI.OOBE.ViewModel;
|
||||
using Microsoft.PowerToys.Settings.UI.Views;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Navigation;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||
/// </summary>
|
||||
public sealed partial class OobeMouseWithoutBorders : Page
|
||||
{
|
||||
public OobePowerToysModule ViewModel { get; set; }
|
||||
|
||||
public OobeMouseWithoutBorders()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.MouseWithoutBorders]);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(MouseWithoutBordersPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
}
|
||||
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
ViewModel.LogOpeningModuleEvent();
|
||||
}
|
||||
|
||||
protected override void OnNavigatedFrom(NavigationEventArgs e)
|
||||
{
|
||||
ViewModel.LogClosingModuleEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -68,6 +68,10 @@
|
||||
x:Uid="Shell_MouseUtilities"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/FluentIcons/FluentIconsMouseUtils.png}"
|
||||
Tag="MouseUtils" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_MouseWithoutBorders"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/FluentIcons/FluentIconsMouseWithoutBorders.png}"
|
||||
Tag="MouseWithoutBorders" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_PastePlain"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/FluentIcons/FluentIconsPastePlain.png}"
|
||||
|
||||
@@ -115,6 +115,11 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
ModuleName = "MouseUtils",
|
||||
IsNew = false,
|
||||
});
|
||||
Modules.Insert((int)PowerToysModules.MouseWithoutBorders, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "MouseWithoutBorders",
|
||||
IsNew = true,
|
||||
});
|
||||
Modules.Insert((int)PowerToysModules.Peek, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "Peek",
|
||||
@@ -249,6 +254,7 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
case "TextExtractor": NavigationFrame.Navigate(typeof(OobePowerOCR)); break;
|
||||
case "VideoConference": NavigationFrame.Navigate(typeof(OobeVideoConference)); break;
|
||||
case "MouseUtils": NavigationFrame.Navigate(typeof(OobeMouseUtils)); break;
|
||||
case "MouseWithoutBorders": NavigationFrame.Navigate(typeof(OobeMouseWithoutBorders)); break;
|
||||
case "MeasureTool": NavigationFrame.Navigate(typeof(OobeMeasureTool)); break;
|
||||
case "Hosts": NavigationFrame.Navigate(typeof(OobeHosts)); break;
|
||||
case "RegistryPreview": NavigationFrame.Navigate(typeof(OobeRegistryPreview)); break;
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" />
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.WinUI.Managed" />
|
||||
<PackageReference Include="StreamJsonRpc" />
|
||||
<Manifest Include="$(ApplicationManifest)" />
|
||||
</ItemGroup>
|
||||
<!-- Defining the "Msix" ProjectCapability here allows the Single-project MSIX Packaging
|
||||
@@ -108,6 +109,13 @@
|
||||
<ProjectReference Include="..\Settings.UI.Library\Settings.UI.Library.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- TODO: fix issues and reenable -->
|
||||
<!-- These are caused by streamjsonrpc dependency on Microsoft.VisualStudio.Threading.Analyzers -->
|
||||
<!-- We might want to add that to the project and fix the issues as well -->
|
||||
<NoWarn>VSTHRD002;VSTHRD110;VSTHRD100;VSTHRD200;VSTHRD101</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="FlyoutWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
|
||||
@@ -216,6 +216,275 @@
|
||||
<value>Enable Screen Ruler</value>
|
||||
<comment>"Screen Ruler" is the name of the utility</comment>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_ActivationSettings.Header" xml:space="preserve">
|
||||
<value>Activation</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_DeviceLayoutSettings.Header" xml:space="preserve">
|
||||
<value>Device layout</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_DeviceLayoutSettings.Description" xml:space="preserve">
|
||||
<value>Drag and drop a machine to rearrange the order.</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_CannotDragDropAsAdmin.Title" xml:space="preserve">
|
||||
<value>It is not possible to use drag and drop while running PowerToys elevated. As a workaround, please restart PowerToys without elevation to edit the device layout.</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_KeySettings.Header" xml:space="preserve">
|
||||
<value>Encryption Key</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_SecurityKey.Header" xml:space="preserve">
|
||||
<value>Security key</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_SecurityKey.Description" xml:space="preserve">
|
||||
<value>The key must be auto generated in one machine by click on New Key, then typed in other machines</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_NewKey.Content" xml:space="preserve">
|
||||
<value>New key</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_CopyMachineName.Text" xml:space="preserve">
|
||||
<value>Copy this PC name to the clipboard</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_ReconnectButton.Text" xml:space="preserve">
|
||||
<value>Refresh connections</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_ReconnectTooltip.Text" xml:space="preserve">
|
||||
<value>Reestablishes connections with other devices if you are experiencing issues.</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_ThisMachineNameLabel.Header" xml:space="preserve">
|
||||
<value>The local machine's host name is:</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_Connect.Content" xml:space="preserve">
|
||||
<value>Connect</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_UninstallService.Header" xml:space="preserve">
|
||||
<value>Uninstall service</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_UninstallService.Description" xml:space="preserve">
|
||||
<value>Removes the service from the computer. Needs to run as administrator.</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_Settings.Header" xml:space="preserve">
|
||||
<value>Behavior</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_TroubleShooting.Header" xml:space="preserve">
|
||||
<value>Troubleshooting</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_AddFirewallRuleButtonControl.Header" xml:space="preserve">
|
||||
<value>Add a firewall rule for Mouse Without Borders</value>
|
||||
<comment>"Mouse Without Borders" is a product name</comment>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_AddFirewallRuleButtonControl.Description" xml:space="preserve">
|
||||
<value>Adding a firewall rule might help solve connection issues.</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_RunAsAdminText.Title" xml:space="preserve">
|
||||
<value>You need to run as administrator to modify this setting.</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_ServiceUserUninstallWarning.Title" xml:space="preserve">
|
||||
<value>If PowerToys is installed as a user, uninstalling/upgrading may require the Mouse Without Borders service to be removed manually later.</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_ServiceSettings.Header" xml:space="preserve">
|
||||
<value>Service</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_Toggle_Enable.Header" xml:space="preserve">
|
||||
<value>Enable Mouse Without Borders</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders.SecondaryLinksHeader" xml:space="preserve">
|
||||
<value>Attribution</value>
|
||||
<comment>giving credit to the projects this utility was based on</comment>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders.ModuleDescription" xml:space="preserve">
|
||||
<value>Mouse Without Borders is a quick and easy way to move your cursor across multiple devices.</value>
|
||||
<comment>"Mouse Without Borders" is the name of the utility</comment>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders.ModuleTitle" xml:space="preserve">
|
||||
<value>Mouse Without Borders</value>
|
||||
<comment>"Mouse Without Borders" is the name of the utility</comment>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_UseService.Header" xml:space="preserve">
|
||||
<value>Use Service</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_UseService.Description"
|
||||
xml:space="preserve">
|
||||
<value>Runs in service mode, that allows MWB to control remote machines when they're locked. Also allows control of system and administrator applications.</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_MatrixOneRow.Header" xml:space="preserve">
|
||||
<value>Devices in a single row</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_MatrixOneRow.Description" xml:space="preserve">
|
||||
<value>Sets whether the devices should are aligned on a single row. A two by two matrix is considered otherwise.</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_WrapMouse.Header" xml:space="preserve">
|
||||
<value>Wrap mouse</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_WrapMouse.Description"
|
||||
xml:space="preserve">
|
||||
<value>Move control back to the first machine when mouse moves past the last one.</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_ShareClipboard.Header" xml:space="preserve">
|
||||
<value>Share clipboard</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_TransferFile.Header" xml:space="preserve">
|
||||
<value>Transfer file</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_HideMouseAtScreenEdge.Header" xml:space="preserve">
|
||||
<value>Hide mouse at the screen edge</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_DrawMouseCursor.Header" xml:space="preserve">
|
||||
<value>Draw mouse cursor</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_ValidateRemoteMachineIP.Header" xml:space="preserve">
|
||||
<value>Validate remote machine IP</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_SameSubnetOnly.Header" xml:space="preserve">
|
||||
<value>Same subnet only</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_BlockScreenSaverOnOtherMachines.Header" xml:space="preserve">
|
||||
<value>Block screen saver on other machines</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_MoveMouseRelatively.Header" xml:space="preserve">
|
||||
<value>Move mouse relatively</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_BlockMouseAtScreenCorners.Header" xml:space="preserve">
|
||||
<value>Block mouse at screen corners</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_ShowClipboardAndNetworkStatusMessages.Header" xml:space="preserve">
|
||||
<value>Show clipboard and network status messages</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_ShowOriginalUI.Header" xml:space="preserve">
|
||||
<value>Show the original Mouse Without Borders UI</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_ShowOriginalUI.Description" xml:space="preserve">
|
||||
<value>This is accessible from the system tray and requires a restart.</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_ShareClipboard.Description"
|
||||
xml:space="preserve">
|
||||
<value>If share clipboard stops working, Ctrl+Alt+Del then Esc may solve the problem.</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_TransferFile.Description"
|
||||
xml:space="preserve">
|
||||
<value>If a file (<100MB) is copied, it will be transferred to the remote machine clipboard.</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_HideMouseAtScreenEdge.Description"
|
||||
xml:space="preserve">
|
||||
<value>Hide the mouse cursor at the top edge of the screen when switching to other machine. This option also steals the focus from any full-screen app to ensure the keyboard input is redirected.</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_DrawMouseCursor.Description"
|
||||
xml:space="preserve">
|
||||
<value>Mouse cursor may not be visible in Windows 10 and later versions of Windows when there is no physical mouse attached.</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_ValidateRemoteMachineIP.Description"
|
||||
xml:space="preserve">
|
||||
<value>Reverse DNS lookup to validate machine IP Address.</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_SameSubnetOnly.Description"
|
||||
xml:space="preserve">
|
||||
<value>Only connect to machines in the same intranet NNN.NNN.*.* (only works when both machines have IPv4 enabled)</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_BlockScreenSaverOnOtherMachines.Description"
|
||||
xml:space="preserve">
|
||||
<value>Prevent screen saver from starting on other machines when user is actively working on this machine.</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_MoveMouseRelatively.Description"
|
||||
xml:space="preserve">
|
||||
<value>Use this option when remote machine's monitor settings are different, or remote machine has multiple monitors.</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_BlockMouseAtScreenCorners.Description"
|
||||
xml:space="preserve">
|
||||
<value>To avoid accident machine-switch at screen corners.</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_ShowClipboardAndNetworkStatusMessages.Description"
|
||||
xml:space="preserve">
|
||||
<value>Show clipboard activities and network status in system tray notifications</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_KeyboardShortcuts_Group.Header" xml:space="preserve">
|
||||
<value>Keyboard Shortcuts</value>
|
||||
<comment>keyboard is the hardware peripheral</comment>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_EasyMouseOption.Header" xml:space="preserve">
|
||||
<value>Easy Mouse: Move between machines by moving the mouse pointer to the screen edges.</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_EasyMouseOption.Description" xml:space="preserve">
|
||||
<value>Can also be set to move only when pressing Shift or Ctrl.</value>
|
||||
<comment>Shift and Ctrl are the keyboard keys</comment>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_EasyMouseOption_Disabled.Content" xml:space="preserve">
|
||||
<value>Disabled</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_EasyMouseOption_Enabled.Content" xml:space="preserve">
|
||||
<value>Enabled</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_EasyMouseOption_Ctrl.Content" xml:space="preserve">
|
||||
<value>Ctrl</value>
|
||||
<comment>This is the Ctrl keyboard key</comment>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_EasyMouseOption_Shift.Content" xml:space="preserve">
|
||||
<value>Shift</value>
|
||||
<comment>This is the Shift keyboard key</comment>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_ToggleEasyMouseShortcut.Header" xml:space="preserve">
|
||||
<value>Shortcut to toggle Easy Mouse. Ctrl+Alt+:</value>
|
||||
<comment>Ctrl and Alt are the keyboard keys</comment>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_ToggleEasyMouseShortcut.Description" xml:space="preserve">
|
||||
<value>Only works if EasyMouse is set to Enabled or Disabled.</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_ToggleEasyMouseShortcut_Disabled.Content" xml:space="preserve">
|
||||
<value>Disabled</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_SwitchBetweenMachineShortcut.Header" xml:space="preserve">
|
||||
<value>Shortcut to switch between machines. Ctrl+Alt+:</value>
|
||||
<comment>Ctrl and Alt are the keyboard keys</comment>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_SwitchBetweenMachineShortcut.Description" xml:space="preserve">
|
||||
<value>Click on Ctrl+Alt+ the chosen option to switch between machines.</value>
|
||||
<comment>Ctrl and Alt are the keyboard keys</comment>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_SwitchBetweenMachineShortcut_F1.Content" xml:space="preserve">
|
||||
<value>F1, F2, F3, F4</value>
|
||||
<comment>Don't localize. These are keyboard keys</comment>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_SwitchBetweenMachineShortcut_1.Content" xml:space="preserve">
|
||||
<value>1, 2, 3, 4</value>
|
||||
<comment>Don't localize. These are keyboard keys</comment>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_SwitchBetweenMachineShortcut_Disabled.Content" xml:space="preserve">
|
||||
<value>Disabled</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_LockMachinesShortcut.Header" xml:space="preserve">
|
||||
<value>Shortcut to press twice quickly to lock all machines. Ctrl+Alt+:</value>
|
||||
<comment>Ctrl and Alt are the keyboard keys</comment>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_LockMachinesShortcut.Description" xml:space="preserve">
|
||||
<value>Click on Ctrl+Alt+ the chosen option twice quickly to lock all machines. Note: Only the machines which have the same shortcut configured will be locked.</value>
|
||||
<comment>Ctrl and Alt are the keyboard keys</comment>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_LockMachinesShortcut_Disabled.Content" xml:space="preserve">
|
||||
<value>Disabled</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_ReconnectShortcut.Header" xml:space="preserve">
|
||||
<value>Shortcut to try reconnecting. Ctrl+Alt+:</value>
|
||||
<comment>Ctrl and Alt are the keyboard keys</comment>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_ReconnectShortcut.Description" xml:space="preserve">
|
||||
<value>Click on Ctrl+Alt+ the chosen option to reconnect.</value>
|
||||
<comment>Ctrl and Alt are the keyboard keys</comment>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_ReconnectShortcut_Disabled.Content" xml:space="preserve">
|
||||
<value>Disabled</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_Switch2AllPcShortcut.Header" xml:space="preserve">
|
||||
<value>Shortcut to switch to multiple machine mode. Ctrl+Alt+:</value>
|
||||
<comment>Ctrl and Alt are the keyboard keys</comment>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_Switch2AllPcShortcut.Description" xml:space="preserve">
|
||||
<value>Allows controlling all computers at once. Pressing Ctrl three times is also an option.</value>
|
||||
<comment>This is the Ctrl keyboard key</comment>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_Switch2AllPcShortcut_Disabled.Content" xml:space="preserve">
|
||||
<value>Disabled</value>
|
||||
</data>
|
||||
<data name="MouseWithoutBorders_Switch2AllPcShortcut_Ctrl3.Content" xml:space="preserve">
|
||||
<value>Ctrl three times</value>
|
||||
<comment>This is the Ctrl keyboard key</comment>
|
||||
</data>
|
||||
<data name="VideoConference_Enable.Header" xml:space="preserve">
|
||||
<value>Enable Video Conference Mute</value>
|
||||
</data>
|
||||
@@ -364,6 +633,10 @@
|
||||
<value>Keyboard Manager</value>
|
||||
<comment>Product name: Navigation view item name for Keyboard Manager</comment>
|
||||
</data>
|
||||
<data name="Shell_MouseWithoutBorders.Content" xml:space="preserve">
|
||||
<value>Mouse Without Borders</value>
|
||||
<comment>Product name: Navigation view item name for Mouse Without Borders</comment>
|
||||
</data>
|
||||
<data name="Shell_MouseUtilities.Content" xml:space="preserve">
|
||||
<value>Mouse utilities</value>
|
||||
<comment>Product name: Navigation view item name for Mouse utilities</comment>
|
||||
@@ -1674,6 +1947,9 @@ Made with 💗 by Microsoft and the PowerToys community.</value>
|
||||
<data name="Oobe_KBM.Description" xml:space="preserve">
|
||||
<value>Keyboard Manager allows you to customize the keyboard to be more productive by remapping keys and creating your own keyboard shortcuts.</value>
|
||||
</data>
|
||||
<data name="Oobe_MouseWithoutBorders.Description" xml:space="preserve">
|
||||
<value>Mouse Without Borders enables using the mouse pointer, keyboard, clipboard and drag and drop between machines in the same local network.</value>
|
||||
</data>
|
||||
<data name="Oobe_PowerRename.Description" xml:space="preserve">
|
||||
<value>PowerRename enables you to perform simple bulk renaming, searching and replacing file names.</value>
|
||||
</data>
|
||||
@@ -1753,6 +2029,12 @@ From there, simply click on one of the supported files in the File Explorer and
|
||||
<data name="Oobe_KBM_TipsAndTricks.Text" xml:space="preserve">
|
||||
<value>Want to only have a shortcut work for a single application? Use the Target App field when creating the shortcut remapping.</value>
|
||||
</data>
|
||||
<data name="Oobe_MouseWithoutBorders_HowToUse.Text" xml:space="preserve">
|
||||
<value>Use the Settings screen on each machine to connect to the other machines using the same key. If a connection is not working, it may be necessary to add an exception to the Windows Firewall.</value>
|
||||
</data>
|
||||
<data name="Oobe_MouseWithoutBorders_TipsAndTricks.Text" xml:space="preserve">
|
||||
<value>Use the service option in Settings to install a service enabling Mouse Without Borders to function even in the lock screen.</value>
|
||||
</data>
|
||||
<data name="Oobe_PowerRename_HowToUse.Text" xml:space="preserve">
|
||||
<value>In File Explorer, right-click one or more selected files and select **PowerRename** from the context menu.</value>
|
||||
</data>
|
||||
@@ -1812,6 +2094,10 @@ From there, simply click on one of the supported files in the File Explorer and
|
||||
<value>Keyboard Manager</value>
|
||||
<comment>Do not localize this string</comment>
|
||||
</data>
|
||||
<data name="Oobe_MouseWithoutBorders.Title" xml:space="preserve">
|
||||
<value>Mouse Without Borders</value>
|
||||
<comment>Product name. Do not localize this string</comment>
|
||||
</data>
|
||||
<data name="Oobe_PowerRename.Title" xml:space="preserve">
|
||||
<value>PowerRename</value>
|
||||
<comment>Do not localize this string</comment>
|
||||
|
||||
@@ -93,6 +93,11 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
FlyoutMenuItems.Add(new FlyoutMenuItem() { Label = resourceLoader.GetString("MouseUtils_MousePointerCrosshairs/Header"), IsEnabled = generalSettingsConfig.Enabled.MousePointerCrosshairs, Tag = "MousePointerCrosshairs", Icon = "ms-appx:///Assets/FluentIcons/FluentIconsMouseCrosshairs.png", EnabledChangedCallback = EnabledChangedOnUI });
|
||||
}
|
||||
|
||||
if ((gpo = GPOWrapper.GetConfiguredMouseWithoutBordersEnabledValue()) != GpoRuleConfigured.Disabled && gpo != GpoRuleConfigured.Enabled)
|
||||
{
|
||||
FlyoutMenuItems.Add(new FlyoutMenuItem() { Label = resourceLoader.GetString("MouseWithoutBorders/ModuleTitle"), IsEnabled = generalSettingsConfig.Enabled.MouseWithoutBorders, Tag = "MouseWithoutBorders", Icon = "ms-appx:///Assets/FluentIcons/FluentIconsMouseWithoutBorders.png", EnabledChangedCallback = EnabledChangedOnUI });
|
||||
}
|
||||
|
||||
if ((gpo = GPOWrapper.GetConfiguredPastePlainEnabledValue()) != GpoRuleConfigured.Disabled && gpo != GpoRuleConfigured.Enabled)
|
||||
{
|
||||
FlyoutMenuItems.Add(new FlyoutMenuItem() { Label = resourceLoader.GetString("PastePlain/ModuleTitle"), IsEnabled = generalSettingsConfig.Enabled.PastePlain, Tag = "PastePlain", Icon = "ms-appx:///Assets/FluentIcons/FluentIconsPastePlain.png", EnabledChangedCallback = EnabledChangedOnUI });
|
||||
@@ -170,6 +175,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
case "MouseHighlighter": item.IsEnabled = generalSettingsConfig.Enabled.MouseHighlighter; break;
|
||||
case "MouseJump": item.IsEnabled = generalSettingsConfig.Enabled.MouseJump; break;
|
||||
case "MousePointerCrosshairs": item.IsEnabled = generalSettingsConfig.Enabled.MousePointerCrosshairs; break;
|
||||
case "MouseWithoutBorders": item.IsEnabled = generalSettingsConfig.Enabled.MouseWithoutBorders; break;
|
||||
case "PastePlain": item.IsEnabled = generalSettingsConfig.Enabled.PastePlain; break;
|
||||
case "Peek": item.IsEnabled = generalSettingsConfig.Enabled.Peek; break;
|
||||
case "PowerRename": item.IsEnabled = generalSettingsConfig.Enabled.PowerRename; break;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -10,7 +10,7 @@ using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Microsoft.PowerToys.Settings.UI.Helpers;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Helpers;
|
||||
using Microsoft.PowerToys.Settings.UI.Services;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
|
||||
443
src/settings-ui/Settings.UI/Views/MouseWithoutBordersPage.xaml
Normal file
443
src/settings-ui/Settings.UI/Views/MouseWithoutBordersPage.xaml
Normal file
@@ -0,0 +1,443 @@
|
||||
<Page x:Class="Microsoft.PowerToys.Settings.UI.Views.MouseWithoutBordersPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:labs="using:CommunityToolkit.Labs.WinUI" mc:Ignorable="d"
|
||||
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
|
||||
xmlns:converters="using:Microsoft.PowerToys.Settings.UI.Converters"
|
||||
xmlns:toolkitConverters="using:CommunityToolkit.WinUI.UI.Converters"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI.UI"
|
||||
AutomationProperties.LandmarkType="Main">
|
||||
<Page.Resources>
|
||||
<converters:NegativeBoolToVisibilityConverter
|
||||
x:Key="negativeBoolToVisibilityConverter" />
|
||||
<toolkitConverters:BoolToObjectConverter
|
||||
x:Key="OneRowMatrixBoolToNumberOfRowsConverter" TrueValue="4"
|
||||
FalseValue="2" />
|
||||
</Page.Resources>
|
||||
<controls:SettingsPageControl x:Uid="MouseWithoutBorders"
|
||||
ModuleImageSource="ms-appx:///Assets/Modules/MouseWithoutBorders.png">
|
||||
<controls:SettingsPageControl.ModuleContent>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<controls:SettingsGroup
|
||||
x:Uid="MouseWithoutBorders_ActivationSettings">
|
||||
<labs:SettingsCard x:Uid="MouseWithoutBorders_Toggle_Enable"
|
||||
HeaderIcon="{ui:BitmapIcon Source=/Assets/FluentIcons/FluentIconsMouseWithoutBorders.png}"
|
||||
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
|
||||
<ToggleSwitch x:Uid="ToggleSwitch"
|
||||
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.CanBeEnabled}"
|
||||
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.IsEnabled}" />
|
||||
</labs:SettingsCard>
|
||||
<InfoBar x:Uid="GPO_IsSettingForced" IsClosable="False"
|
||||
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
|
||||
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
|
||||
Severity="Informational" />
|
||||
</controls:SettingsGroup>
|
||||
<controls:SettingsGroup x:Uid="MouseWithoutBorders_KeySettings"
|
||||
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
|
||||
<labs:SettingsExpander
|
||||
x:Uid="MouseWithoutBorders_SecurityKey"
|
||||
x:Name="MouseWithoutBorders_ConnectSettings"
|
||||
IsExpanded="{x:Bind Mode=TwoWay, Path=ViewModel.ConnectFieldsVisible}">
|
||||
<labs:SettingsExpander.Items>
|
||||
<labs:SettingsCard ContentAlignment="Right">
|
||||
<StackPanel Orientation="Horizontal" Spacing="4">
|
||||
<TextBox x:Name="ConnectSecurityKeyTextBox"
|
||||
Width="250"
|
||||
PlaceholderText="Security Key" />
|
||||
<TextBox x:Name="ConnectPCNameTextBox"
|
||||
Width="250"
|
||||
PlaceholderText="PC Name" />
|
||||
<Button x:Uid="MouseWithoutBorders_Connect"
|
||||
Command="{x:Bind Mode=OneTime, Path=ConnectCommand}"
|
||||
Style="{StaticResource AccentButtonStyle}" />
|
||||
</StackPanel>
|
||||
</labs:SettingsCard>
|
||||
</labs:SettingsExpander.Items>
|
||||
<StackPanel Orientation="Horizontal" Spacing="4">
|
||||
<TextBox IsReadOnly="True"
|
||||
Text="{x:Bind Mode=TwoWay, Path=ViewModel.SecurityKey}" />
|
||||
<Button x:Uid="MouseWithoutBorders_NewKey"
|
||||
Command="{x:Bind Mode=OneTime, Path=GenerateNewKeyCommand}"
|
||||
Style="{StaticResource AccentButtonStyle}" />
|
||||
<Button x:Uid="MouseWithoutBorders_Connect"
|
||||
Command="{x:Bind Mode=OneTime, Path=ShowConnectFieldsCommand}"
|
||||
Visibility="{x:Bind Path=ViewModel.ConnectFieldsVisible, Mode=OneWay, Converter={StaticResource negativeBoolToVisibilityConverter}}"
|
||||
Style="{StaticResource AccentButtonStyle}" />
|
||||
</StackPanel>
|
||||
</labs:SettingsExpander>
|
||||
</controls:SettingsGroup>
|
||||
<controls:SettingsGroup
|
||||
x:Uid="MouseWithoutBorders_ThisMachineNameLabel"
|
||||
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
|
||||
<Button
|
||||
Command="{x:Bind Mode=OneTime, Path=CopyPCNameCommand}"
|
||||
Style="{StaticResource AccentButtonStyle}">
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock
|
||||
x:Uid="MouseWithoutBorders_CopyMachineName" />
|
||||
</ToolTipService.ToolTip>
|
||||
<TextBlock
|
||||
Text="{x:Bind Mode=OneTime, Path=ViewModel.MachineHostName}" />
|
||||
</Button>
|
||||
</controls:SettingsGroup>
|
||||
<controls:SettingsGroup
|
||||
x:Uid="MouseWithoutBorders_DeviceLayoutSettings"
|
||||
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
|
||||
<InfoBar x:Uid="MouseWithoutBorders_CannotDragDropAsAdmin"
|
||||
IsClosable="True"
|
||||
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsElevated}"
|
||||
IsTabStop="True" Severity="Informational" />
|
||||
<StackPanel Orientation="Vertical"
|
||||
HorizontalAlignment="Center">
|
||||
<StackPanel HorizontalAlignment="Center"
|
||||
Orientation="Horizontal">
|
||||
<ItemsControl x:Name="DevicesItemsControl"
|
||||
ItemsSource="{Binding MachineMatrixString, Mode=TwoWay}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<WrapGrid Orientation="Horizontal"
|
||||
MaximumRowsOrColumns="{Binding MatrixOneRow, Mode=OneWay, Converter={StaticResource OneRowMatrixBoolToNumberOfRowsConverter}}" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<!--TODO: colors?-->
|
||||
<!--BorderBrush="#DFDFDF"
|
||||
Background="#d4d4d4"-->
|
||||
<!-- Dragging while elevated crashes on WinUI3: https://github.com/microsoft/microsoft-ui-xaml/issues/7690 -->
|
||||
<Border
|
||||
BorderBrush="{Binding Item.StatusBrush}"
|
||||
Background="{ThemeResource SubtleButtonBackgroundDisabled}"
|
||||
Width="90" Height="90"
|
||||
BorderThickness="2" Margin="3"
|
||||
CanDrag="{Binding Mode=OneWay, Path=Item.CanDragDrop}"
|
||||
AllowDrop="{Binding Mode=OneWay, Path=Item.CanDragDrop}"
|
||||
CornerRadius="4"
|
||||
DragStarting="Device_DragStarting"
|
||||
DragOver="Device_DragOver"
|
||||
DataContext="{Binding}"
|
||||
ToolTipService.ToolTip="{Binding Item.Name, Mode=OneWay}"
|
||||
Drop="Device_Drop">
|
||||
<StackPanel
|
||||
VerticalAlignment="Center"
|
||||
Orientation="Vertical"
|
||||
Opacity="0.5">
|
||||
<FontIcon FontSize="39"
|
||||
Width="50" Height="50"
|
||||
FontFamily="Segoe MDL2 Assets"
|
||||
Glyph="" />
|
||||
<TextBlock Tag="DeviceName"
|
||||
HorizontalAlignment="Center"
|
||||
Text="{Binding Item.Name}" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</StackPanel>
|
||||
<Button
|
||||
HorizontalAlignment="Center"
|
||||
Command="{x:Bind Mode=OneTime, Path=ReconnectCommand}"
|
||||
Style="{StaticResource AccentButtonStyle}">
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock
|
||||
x:Uid="MouseWithoutBorders_ReconnectTooltip" />
|
||||
</ToolTipService.ToolTip>
|
||||
<TextBlock
|
||||
x:Uid="MouseWithoutBorders_ReconnectButton" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<labs:SettingsCard x:Uid="MouseWithoutBorders_MatrixOneRow">
|
||||
<ToggleSwitch
|
||||
x:Uid="MouseWithoutBorders_MatrixOneRow_ToggleSwitch"
|
||||
IsOn="{x:Bind ViewModel.MatrixOneRow, Mode=TwoWay}" />
|
||||
</labs:SettingsCard>
|
||||
</controls:SettingsGroup>
|
||||
<controls:SettingsGroup
|
||||
x:Uid="MouseWithoutBorders_ServiceSettings"
|
||||
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.CanToggleUseService}">
|
||||
<labs:SettingsCard x:Uid="MouseWithoutBorders_UseService">
|
||||
<ToggleSwitch
|
||||
x:Uid="MouseWithoutBorders_UseService_ToggleSwitch"
|
||||
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}"
|
||||
IsOn="{x:Bind ViewModel.UseService, Mode=TwoWay}" />
|
||||
</labs:SettingsCard>
|
||||
<InfoBar x:Uid="MouseWithoutBorders_RunAsAdminText"
|
||||
IsClosable="False"
|
||||
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.CanToggleUseService, Converter={StaticResource BoolNegationConverter}}"
|
||||
IsTabStop="True" Severity="Informational" />
|
||||
<InfoBar
|
||||
x:Uid="MouseWithoutBorders_ServiceUserUninstallWarning"
|
||||
IsOpen="True" IsClosable="True" IsTabStop="True"
|
||||
Severity="Warning" />
|
||||
<labs:SettingsCard
|
||||
x:Uid="MouseWithoutBorders_UninstallService" ActionIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
|
||||
FontSize=14,
|
||||
Glyph=}"
|
||||
Command="{x:Bind ViewModel.UninstallServiceEventHandler}"
|
||||
IsClickEnabled="{x:Bind Mode=OneWay, Path=ViewModel.CanUninstallService}" />
|
||||
</controls:SettingsGroup>
|
||||
<controls:SettingsGroup x:Uid="MouseWithoutBorders_Settings"
|
||||
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
|
||||
<labs:SettingsCard x:Uid="MouseWithoutBorders_WrapMouse">
|
||||
<ToggleSwitch
|
||||
x:Uid="MouseWithoutBorders_WrapMouse_ToggleSwitch"
|
||||
IsOn="{x:Bind ViewModel.WrapMouse, Mode=TwoWay}" />
|
||||
</labs:SettingsCard>
|
||||
<labs:SettingsCard
|
||||
x:Uid="MouseWithoutBorders_ShareClipboard">
|
||||
<ToggleSwitch
|
||||
x:Uid="MouseWithoutBorders_ShareClipboard_ToggleSwitch"
|
||||
IsOn="{x:Bind ViewModel.ShareClipboard, Mode=TwoWay}" />
|
||||
</labs:SettingsCard>
|
||||
<labs:SettingsCard x:Uid="MouseWithoutBorders_TransferFile">
|
||||
<ToggleSwitch
|
||||
x:Uid="MouseWithoutBorders_TransferFile_ToggleSwitch"
|
||||
IsOn="{x:Bind ViewModel.TransferFile, Mode=TwoWay}" />
|
||||
</labs:SettingsCard>
|
||||
<labs:SettingsCard
|
||||
x:Uid="MouseWithoutBorders_HideMouseAtScreenEdge">
|
||||
<ToggleSwitch
|
||||
x:Uid="MouseWithoutBorders_HideMouseAtScreenEdge_ToggleSwitch"
|
||||
IsOn="{x:Bind ViewModel.HideMouseAtScreenEdge, Mode=TwoWay}" />
|
||||
</labs:SettingsCard>
|
||||
<labs:SettingsCard
|
||||
x:Uid="MouseWithoutBorders_DrawMouseCursor">
|
||||
<ToggleSwitch
|
||||
x:Uid="MouseWithoutBorders_DrawMouseCursor_ToggleSwitch"
|
||||
IsOn="{x:Bind ViewModel.DrawMouseCursor, Mode=TwoWay}" />
|
||||
</labs:SettingsCard>
|
||||
<labs:SettingsCard
|
||||
x:Uid="MouseWithoutBorders_ValidateRemoteMachineIP">
|
||||
<ToggleSwitch
|
||||
x:Uid="MouseWithoutBorders_ValidateRemoteMachineIP_ToggleSwitch"
|
||||
IsOn="{x:Bind ViewModel.ValidateRemoteMachineIP, Mode=TwoWay}" />
|
||||
</labs:SettingsCard>
|
||||
<labs:SettingsCard
|
||||
x:Uid="MouseWithoutBorders_SameSubnetOnly">
|
||||
<ToggleSwitch
|
||||
x:Uid="MouseWithoutBorders_SameSubnetOnly_ToggleSwitch"
|
||||
IsOn="{x:Bind ViewModel.SameSubnetOnly, Mode=TwoWay}" />
|
||||
</labs:SettingsCard>
|
||||
<labs:SettingsCard
|
||||
x:Uid="MouseWithoutBorders_BlockScreenSaverOnOtherMachines">
|
||||
<ToggleSwitch
|
||||
x:Uid="MouseWithoutBorders_BlockScreenSaverOnOtherMachines_ToggleSwitch"
|
||||
IsOn="{x:Bind ViewModel.BlockScreenSaverOnOtherMachines, Mode=TwoWay}" />
|
||||
</labs:SettingsCard>
|
||||
<labs:SettingsCard
|
||||
x:Uid="MouseWithoutBorders_MoveMouseRelatively">
|
||||
<ToggleSwitch
|
||||
x:Uid="MouseWithoutBorders_MoveMouseRelatively_ToggleSwitch"
|
||||
IsOn="{x:Bind ViewModel.MoveMouseRelatively, Mode=TwoWay}" />
|
||||
</labs:SettingsCard>
|
||||
<labs:SettingsCard
|
||||
x:Uid="MouseWithoutBorders_BlockMouseAtScreenCorners">
|
||||
<ToggleSwitch
|
||||
x:Uid="MouseWithoutBorders_BlockMouseAtScreenCorners_ToggleSwitch"
|
||||
IsOn="{x:Bind ViewModel.BlockMouseAtScreenCorners, Mode=TwoWay}" />
|
||||
</labs:SettingsCard>
|
||||
<labs:SettingsCard
|
||||
x:Uid="MouseWithoutBorders_ShowClipboardAndNetworkStatusMessages">
|
||||
<ToggleSwitch
|
||||
x:Uid="MouseWithoutBorders_ShowClipboardAndNetworkStatusMessages_ToggleSwitch"
|
||||
IsOn="{x:Bind ViewModel.ShowClipboardAndNetworkStatusMessages, Mode=TwoWay}" />
|
||||
</labs:SettingsCard>
|
||||
</controls:SettingsGroup>
|
||||
<controls:SettingsGroup x:Uid="MouseWithoutBorders_KeyboardShortcuts_Group"
|
||||
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
|
||||
<labs:SettingsCard x:Uid="MouseWithoutBorders_EasyMouseOption">
|
||||
<ComboBox
|
||||
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
||||
SelectedIndex="{x:Bind Path=ViewModel.EasyMouseOptionIndex, Mode=TwoWay}">
|
||||
<ComboBoxItem x:Uid="MouseWithoutBorders_EasyMouseOption_Disabled" />
|
||||
<ComboBoxItem x:Uid="MouseWithoutBorders_EasyMouseOption_Enabled" />
|
||||
<ComboBoxItem x:Uid="MouseWithoutBorders_EasyMouseOption_Ctrl" />
|
||||
<ComboBoxItem x:Uid="MouseWithoutBorders_EasyMouseOption_Shift" />
|
||||
</ComboBox>
|
||||
</labs:SettingsCard>
|
||||
<labs:SettingsCard x:Uid="MouseWithoutBorders_ToggleEasyMouseShortcut">
|
||||
<ComboBox
|
||||
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
||||
SelectedIndex="{x:Bind Path=ViewModel.ToggleEasyMouseShortcutIndex, Mode=TwoWay}"
|
||||
>
|
||||
<ComboBoxItem x:Uid="MouseWithoutBorders_ToggleEasyMouseShortcut_Disabled" />
|
||||
<ComboBoxItem>A</ComboBoxItem>
|
||||
<ComboBoxItem>B</ComboBoxItem>
|
||||
<ComboBoxItem>C</ComboBoxItem>
|
||||
<ComboBoxItem>D</ComboBoxItem>
|
||||
<ComboBoxItem>E</ComboBoxItem>
|
||||
<ComboBoxItem>F</ComboBoxItem>
|
||||
<ComboBoxItem>G</ComboBoxItem>
|
||||
<ComboBoxItem>H</ComboBoxItem>
|
||||
<ComboBoxItem>I</ComboBoxItem>
|
||||
<ComboBoxItem>J</ComboBoxItem>
|
||||
<ComboBoxItem>K</ComboBoxItem>
|
||||
<ComboBoxItem>L</ComboBoxItem>
|
||||
<ComboBoxItem>M</ComboBoxItem>
|
||||
<ComboBoxItem>N</ComboBoxItem>
|
||||
<ComboBoxItem>O</ComboBoxItem>
|
||||
<ComboBoxItem>P</ComboBoxItem>
|
||||
<ComboBoxItem>Q</ComboBoxItem>
|
||||
<ComboBoxItem>R</ComboBoxItem>
|
||||
<ComboBoxItem>S</ComboBoxItem>
|
||||
<ComboBoxItem>T</ComboBoxItem>
|
||||
<ComboBoxItem>U</ComboBoxItem>
|
||||
<ComboBoxItem>V</ComboBoxItem>
|
||||
<ComboBoxItem>W</ComboBoxItem>
|
||||
<ComboBoxItem>X</ComboBoxItem>
|
||||
<ComboBoxItem>Y</ComboBoxItem>
|
||||
<ComboBoxItem>Z</ComboBoxItem>
|
||||
</ComboBox>
|
||||
</labs:SettingsCard>
|
||||
<labs:SettingsCard x:Uid="MouseWithoutBorders_LockMachinesShortcut">
|
||||
<ComboBox
|
||||
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
||||
SelectedIndex="{x:Bind Path=ViewModel.LockMachinesShortcutIndex, Mode=TwoWay}"
|
||||
>
|
||||
<ComboBoxItem x:Uid="MouseWithoutBorders_LockMachinesShortcut_Disabled" />
|
||||
<ComboBoxItem>A</ComboBoxItem>
|
||||
<ComboBoxItem>B</ComboBoxItem>
|
||||
<ComboBoxItem>C</ComboBoxItem>
|
||||
<ComboBoxItem>D</ComboBoxItem>
|
||||
<ComboBoxItem>E</ComboBoxItem>
|
||||
<ComboBoxItem>F</ComboBoxItem>
|
||||
<ComboBoxItem>G</ComboBoxItem>
|
||||
<ComboBoxItem>H</ComboBoxItem>
|
||||
<ComboBoxItem>I</ComboBoxItem>
|
||||
<ComboBoxItem>J</ComboBoxItem>
|
||||
<ComboBoxItem>K</ComboBoxItem>
|
||||
<ComboBoxItem>L</ComboBoxItem>
|
||||
<ComboBoxItem>M</ComboBoxItem>
|
||||
<ComboBoxItem>N</ComboBoxItem>
|
||||
<ComboBoxItem>O</ComboBoxItem>
|
||||
<ComboBoxItem>P</ComboBoxItem>
|
||||
<ComboBoxItem>Q</ComboBoxItem>
|
||||
<ComboBoxItem>R</ComboBoxItem>
|
||||
<ComboBoxItem>S</ComboBoxItem>
|
||||
<ComboBoxItem>T</ComboBoxItem>
|
||||
<ComboBoxItem>U</ComboBoxItem>
|
||||
<ComboBoxItem>V</ComboBoxItem>
|
||||
<ComboBoxItem>W</ComboBoxItem>
|
||||
<ComboBoxItem>X</ComboBoxItem>
|
||||
<ComboBoxItem>Y</ComboBoxItem>
|
||||
<ComboBoxItem>Z</ComboBoxItem>
|
||||
</ComboBox>
|
||||
</labs:SettingsCard>
|
||||
<labs:SettingsCard x:Uid="MouseWithoutBorders_ReconnectShortcut">
|
||||
<ComboBox
|
||||
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
||||
SelectedIndex="{x:Bind Path=ViewModel.ReconnectShortcutIndex, Mode=TwoWay}"
|
||||
>
|
||||
<ComboBoxItem x:Uid="MouseWithoutBorders_ReconnectShortcut_Disabled" />
|
||||
<ComboBoxItem>A</ComboBoxItem>
|
||||
<ComboBoxItem>B</ComboBoxItem>
|
||||
<ComboBoxItem>C</ComboBoxItem>
|
||||
<ComboBoxItem>D</ComboBoxItem>
|
||||
<ComboBoxItem>E</ComboBoxItem>
|
||||
<ComboBoxItem>F</ComboBoxItem>
|
||||
<ComboBoxItem>G</ComboBoxItem>
|
||||
<ComboBoxItem>H</ComboBoxItem>
|
||||
<ComboBoxItem>I</ComboBoxItem>
|
||||
<ComboBoxItem>J</ComboBoxItem>
|
||||
<ComboBoxItem>K</ComboBoxItem>
|
||||
<ComboBoxItem>L</ComboBoxItem>
|
||||
<ComboBoxItem>M</ComboBoxItem>
|
||||
<ComboBoxItem>N</ComboBoxItem>
|
||||
<ComboBoxItem>O</ComboBoxItem>
|
||||
<ComboBoxItem>P</ComboBoxItem>
|
||||
<ComboBoxItem>Q</ComboBoxItem>
|
||||
<ComboBoxItem>R</ComboBoxItem>
|
||||
<ComboBoxItem>S</ComboBoxItem>
|
||||
<ComboBoxItem>T</ComboBoxItem>
|
||||
<ComboBoxItem>U</ComboBoxItem>
|
||||
<ComboBoxItem>V</ComboBoxItem>
|
||||
<ComboBoxItem>W</ComboBoxItem>
|
||||
<ComboBoxItem>X</ComboBoxItem>
|
||||
<ComboBoxItem>Y</ComboBoxItem>
|
||||
<ComboBoxItem>Z</ComboBoxItem>
|
||||
</ComboBox>
|
||||
</labs:SettingsCard>
|
||||
<labs:SettingsCard x:Uid="MouseWithoutBorders_Switch2AllPcShortcut">
|
||||
<ComboBox
|
||||
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
||||
SelectedIndex="{x:Bind Path=ViewModel.Switch2AllPcShortcutIndex, Mode=TwoWay}"
|
||||
>
|
||||
<ComboBoxItem x:Uid="MouseWithoutBorders_Switch2AllPcShortcut_Disabled" />
|
||||
<ComboBoxItem x:Uid="MouseWithoutBorders_Switch2AllPcShortcut_Ctrl3" />
|
||||
<ComboBoxItem>A</ComboBoxItem>
|
||||
<ComboBoxItem>B</ComboBoxItem>
|
||||
<ComboBoxItem>C</ComboBoxItem>
|
||||
<ComboBoxItem>D</ComboBoxItem>
|
||||
<ComboBoxItem>E</ComboBoxItem>
|
||||
<ComboBoxItem>F</ComboBoxItem>
|
||||
<ComboBoxItem>G</ComboBoxItem>
|
||||
<ComboBoxItem>H</ComboBoxItem>
|
||||
<ComboBoxItem>I</ComboBoxItem>
|
||||
<ComboBoxItem>J</ComboBoxItem>
|
||||
<ComboBoxItem>K</ComboBoxItem>
|
||||
<ComboBoxItem>L</ComboBoxItem>
|
||||
<ComboBoxItem>M</ComboBoxItem>
|
||||
<ComboBoxItem>N</ComboBoxItem>
|
||||
<ComboBoxItem>O</ComboBoxItem>
|
||||
<ComboBoxItem>P</ComboBoxItem>
|
||||
<ComboBoxItem>Q</ComboBoxItem>
|
||||
<ComboBoxItem>R</ComboBoxItem>
|
||||
<ComboBoxItem>S</ComboBoxItem>
|
||||
<ComboBoxItem>T</ComboBoxItem>
|
||||
<ComboBoxItem>U</ComboBoxItem>
|
||||
<ComboBoxItem>V</ComboBoxItem>
|
||||
<ComboBoxItem>W</ComboBoxItem>
|
||||
<ComboBoxItem>X</ComboBoxItem>
|
||||
<ComboBoxItem>Y</ComboBoxItem>
|
||||
<ComboBoxItem>Z</ComboBoxItem>
|
||||
</ComboBox>
|
||||
</labs:SettingsCard>
|
||||
<labs:SettingsCard
|
||||
x:Uid="MouseWithoutBorders_SwitchBetweenMachineShortcut"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
|
||||
Glyph=}">
|
||||
<ComboBox
|
||||
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
||||
SelectedIndex="{x:Bind Path=ViewModel.SelectedSwitchBetweenMachineShortcutOptionsIndex, Mode=TwoWay}">
|
||||
<!-- These should be in the same order as the array items in MouseWithoutBordersViewModel.cs -->
|
||||
<ComboBoxItem x:Uid="MouseWithoutBorders_SwitchBetweenMachineShortcut_F1" />
|
||||
<ComboBoxItem x:Uid="MouseWithoutBorders_SwitchBetweenMachineShortcut_1"/>
|
||||
<ComboBoxItem x:Uid="MouseWithoutBorders_SwitchBetweenMachineShortcut_Disabled" />
|
||||
</ComboBox>
|
||||
</labs:SettingsCard>
|
||||
</controls:SettingsGroup>
|
||||
<controls:SettingsGroup
|
||||
x:Uid="MouseWithoutBorders_TroubleShooting"
|
||||
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
|
||||
<labs:SettingsCard
|
||||
x:Uid="MouseWithoutBorders_AddFirewallRuleButtonControl" ActionIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
|
||||
FontSize=14,
|
||||
Glyph=}"
|
||||
Command="{x:Bind ViewModel.AddFirewallRuleEventHandler}"
|
||||
IsClickEnabled="True" />
|
||||
<labs:SettingsCard
|
||||
x:Uid="MouseWithoutBorders_ShowOriginalUI">
|
||||
<ToggleSwitch
|
||||
x:Uid="MouseWithoutBorders_ShowOriginalUI_ToggleSwitch"
|
||||
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}"
|
||||
IsOn="{x:Bind ViewModel.ShowOriginalUI, Mode=TwoWay}" />
|
||||
</labs:SettingsCard>
|
||||
</controls:SettingsGroup>
|
||||
</StackPanel>
|
||||
</controls:SettingsPageControl.ModuleContent>
|
||||
<controls:SettingsPageControl.PrimaryLinks>
|
||||
<controls:PageLink x:Uid="LearnMore_MouseWithoutBorders"
|
||||
Link="https://aka.ms/PowerToysOverview_MouseWithoutBorders" />
|
||||
</controls:SettingsPageControl.PrimaryLinks>
|
||||
<controls:SettingsPageControl.SecondaryLinks>
|
||||
<controls:PageLink Text="Mouse without Borders"
|
||||
Link="http://aka.ms/mm" />
|
||||
<controls:PageLink
|
||||
Link="https://github.com/microsoft/PowerToys/blob/main/COMMUNITY.md#mouse-without-borders-original-contributors"
|
||||
Text="Truong Do (Đỗ Đức Trường) and other original contributors" />
|
||||
</controls:SettingsPageControl.SecondaryLinks>
|
||||
</controls:SettingsPageControl>
|
||||
</Page>
|
||||
@@ -0,0 +1,176 @@
|
||||
// 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.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO.Abstractions;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using System.Xml.Linq;
|
||||
using CommunityToolkit.Labs.WinUI;
|
||||
using Microsoft.PowerToys.Settings.UI.Helpers;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
|
||||
using Microsoft.PowerToys.Settings.UI.ViewModels;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using Windows.ApplicationModel.DataTransfer;
|
||||
using WinRT;
|
||||
using static Microsoft.PowerToys.Settings.UI.ViewModels.MouseWithoutBordersViewModel;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
{
|
||||
public sealed partial class MouseWithoutBordersPage : Page, IRefreshablePage
|
||||
{
|
||||
private const string MouseWithoutBordersDragDropCheckString = "MWB Device Drag Drop";
|
||||
|
||||
private const string PowerToyName = "MouseWithoutBorders";
|
||||
|
||||
private MouseWithoutBordersViewModel ViewModel { get; set; }
|
||||
|
||||
private readonly IFileSystemWatcher watcher;
|
||||
|
||||
public MouseWithoutBordersPage()
|
||||
{
|
||||
var settingsUtils = new SettingsUtils();
|
||||
ViewModel = new MouseWithoutBordersViewModel(
|
||||
settingsUtils,
|
||||
SettingsRepository<GeneralSettings>.GetInstance(settingsUtils),
|
||||
ShellPage.SendDefaultIPCMessage,
|
||||
DispatcherQueue);
|
||||
|
||||
watcher = Helper.GetFileWatcher(
|
||||
PowerToyName,
|
||||
"settings.json",
|
||||
OnConfigFileUpdate);
|
||||
|
||||
DataContext = ViewModel;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void OnConfigFileUpdate()
|
||||
{
|
||||
// Note: FileSystemWatcher raise notification multiple times for single update operation.
|
||||
// Todo: Handle duplicate events either by somehow suppress them or re-read the configuration everytime since we will be updating the UI only if something is changed.
|
||||
this.DispatcherQueue.TryEnqueue(() =>
|
||||
{
|
||||
if (ViewModel.LoadUpdatedSettings())
|
||||
{
|
||||
ViewModel.NotifyUpdatedSettings();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static T GetChildOfType<T>(DependencyObject depObj, string tag)
|
||||
where T : FrameworkElement
|
||||
{
|
||||
if (depObj == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
|
||||
{
|
||||
var child = VisualTreeHelper.GetChild(depObj, i);
|
||||
|
||||
var result = (child as T) ?? GetChildOfType<T>(child, tag);
|
||||
if (result != null && (string)result.Tag == tag)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private int GetDeviceIndex(Border b)
|
||||
{
|
||||
return b.DataContext.As<IndexedItem<DeviceViewModel>>().Index;
|
||||
}
|
||||
|
||||
private void Device_DragStarting(UIElement sender, DragStartingEventArgs args)
|
||||
{
|
||||
args.Data.RequestedOperation = DataPackageOperation.Move;
|
||||
args.Data.Properties.Add("check-usage", MouseWithoutBordersDragDropCheckString);
|
||||
args.Data.Properties.Add("index", GetDeviceIndex((Border)sender));
|
||||
}
|
||||
|
||||
private void Device_Drop(object sender, DragEventArgs e)
|
||||
{
|
||||
if (e.DataView.Properties.TryGetValue("check-usage", out object checkUsage))
|
||||
{
|
||||
// Guard against values dragged from somewhere else
|
||||
if (!((string)checkUsage).Equals(MouseWithoutBordersDragDropCheckString, StringComparison.Ordinal))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!e.DataView.Properties.TryGetValue("index", out object boxIndex))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var draggedDeviceIndex = (int)boxIndex;
|
||||
|
||||
if (draggedDeviceIndex < 0 || draggedDeviceIndex >= ViewModel.MachineMatrixString.Count)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var targetDeviceIndex = GetDeviceIndex((Border)e.OriginalSource);
|
||||
|
||||
ViewModel.MachineMatrixString.Swap(draggedDeviceIndex, targetDeviceIndex);
|
||||
var itemsControl = (ItemsControl)FindName("DevicesItemsControl");
|
||||
var binding = itemsControl.GetBindingExpression(ItemsControl.ItemsSourceProperty);
|
||||
binding.UpdateSource();
|
||||
}
|
||||
|
||||
private void Device_DragOver(object sender, DragEventArgs e)
|
||||
{
|
||||
e.AcceptedOperation = DataPackageOperation.Move;
|
||||
}
|
||||
|
||||
public ICommand ShowConnectFieldsCommand => new RelayCommand(ShowConnectFields);
|
||||
|
||||
public ICommand ConnectCommand => new AsyncCommand(Connect);
|
||||
|
||||
public ICommand GenerateNewKeyCommand => new AsyncCommand(ViewModel.SubmitNewKeyRequestAsync);
|
||||
|
||||
public ICommand CopyPCNameCommand => new RelayCommand(ViewModel.CopyMachineNameToClipboard);
|
||||
|
||||
public ICommand ReconnectCommand => new AsyncCommand(ViewModel.SubmitReconnectRequestAsync);
|
||||
|
||||
private void ShowConnectFields()
|
||||
{
|
||||
ViewModel.ConnectFieldsVisible = true;
|
||||
}
|
||||
|
||||
private async Task Connect()
|
||||
{
|
||||
if (ConnectPCNameTextBox.Text.Length != 0 && ConnectSecurityKeyTextBox.Text.Length != 0)
|
||||
{
|
||||
string pcName = ConnectPCNameTextBox.Text;
|
||||
string securityKey = ConnectSecurityKeyTextBox.Text.Trim();
|
||||
|
||||
await ViewModel.SubmitConnectionRequestAsync(pcName, securityKey);
|
||||
|
||||
ConnectPCNameTextBox.Text = string.Empty;
|
||||
ConnectSecurityKeyTextBox.Text = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public void RefreshEnabledState()
|
||||
{
|
||||
ViewModel.RefreshEnabledState();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,6 +94,11 @@
|
||||
helpers:NavHelper.NavigateTo="views:MouseUtilsPage"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/FluentIcons/FluentIconsMouseUtils.png}" />
|
||||
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_MouseWithoutBorders"
|
||||
helpers:NavHelper.NavigateTo="views:MouseWithoutBordersPage"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/FluentIcons/FluentIconsMouseWithoutBorders.png}" />
|
||||
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_PastePlain"
|
||||
helpers:NavHelper.NavigateTo="views:PastePlainPage"
|
||||
|
||||
Reference in New Issue
Block a user