Compare commits

...

9 Commits

Author SHA1 Message Date
Niels Laute
081cd3b017 [FLS] Icon and UI fixes (#21732)
* Fixes

* Additional fixes

* Uncomment TextBlock that's needed

* Remove ItemsPanelTemplate that was turning off virtualization
2022-11-07 16:51:41 +00:00
Heiko
d1794e284a [GPO] Fix the admx file by removing obsolete dependency(#21813)
* fix admx file

* add version info file

* Add PowerToys version in admx instead
2022-11-07 16:51:34 +00:00
Seraphima Zykova
0bb1a95b46 [WPF]Downgrade ModernWPF to 0.9.4 (#21842) 2022-11-07 16:51:26 +00:00
Niels Laute
4dd712008e [HostsFileEditor]Update plus icon (#21833) 2022-11-07 16:51:16 +00:00
Laszlo Nemeth
38b19096e2 [ColorPicker]Avoid endless loop on property change (#21566)
Blocking endless loop on property change
2022-11-07 16:51:05 +00:00
Andrey Nekrasov
5bc07a1329 [VCM] update deprecation warning message (#21725) 2022-11-07 16:50:55 +00:00
Jaime Bernardo
676b56a73f [FileLocksmith]Query system processes if elevated (#21688)
* [FileLocksmith]Query system processes if elevated

* Show warning if user is a system user

* Make text in the file list selectable

* Update src/modules/FileLocksmith/FileLocksmithLibInterop/NtdllExtensions.cpp

Co-authored-by: Andrey Nekrasov <yuyoyuppe@users.noreply.github.com>

* Trim \0 no longer required

* Correct elevation detection logic

* Use theme approppriate colors

Co-authored-by: Andrey Nekrasov <yuyoyuppe@users.noreply.github.com>
2022-11-07 16:50:42 +00:00
Davide Giacometti
37ef90103c [Hosts]Add scrollbar to additional lines (#21704) 2022-11-07 16:50:30 +00:00
Seraphima Zykova
220f27a2a9 [FancyZones] Fix: 'Space around zones' toggle does not turn off spacing (#21658) 2022-11-07 16:50:18 +00:00
21 changed files with 308 additions and 198 deletions

View File

@@ -4,9 +4,8 @@
<policyDefinitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" revision="1.0" schemaVersion="1.0" xmlns="http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions"> <policyDefinitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" revision="1.0" schemaVersion="1.0" xmlns="http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions">
<policyNamespaces> <policyNamespaces>
<target prefix="powertoys" namespace="Microsoft.Policies.PowerToys" /> <target prefix="powertoys" namespace="Microsoft.Policies.PowerToys" />
<using prefix="windows" namespace="Microsoft.Policies.Windows" />
</policyNamespaces> </policyNamespaces>
<resources minRequiredRevision="1.0"/> <resources minRequiredRevision="1.0"/><!-- PowerToys v0.64.0 -->
<supportedOn> <supportedOn>
<definitions> <definitions>
<definition name="SUPPORTED_POWERTOYS_0_64_0" displayName="$(string.SUPPORTED_POWERTOYS_0_64_0)"/> <definition name="SUPPORTED_POWERTOYS_0_64_0" displayName="$(string.SUPPORTED_POWERTOYS_0_64_0)"/>

View File

@@ -103,6 +103,7 @@ std::vector<ProcessResult> find_processes_recursive(const std::vector<std::wstri
{ {
process_info.name, process_info.name,
process_info.pid, process_info.pid,
process_info.user,
std::vector(it->second.begin(), it->second.end()) std::vector(it->second.begin(), it->second.end())
}); });
} }
@@ -111,50 +112,6 @@ std::vector<ProcessResult> find_processes_recursive(const std::vector<std::wstri
return result; return result;
} }
std::wstring pid_to_user(DWORD pid)
{
HANDLE process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
if (process == NULL)
{
return {};
}
std::wstring user = L"";
std::wstring domain = L"";
HANDLE token = NULL;
if (OpenProcessToken(process, TOKEN_QUERY, &token))
{
DWORD token_size = 0;
GetTokenInformation(token, TokenUser, NULL, 0, &token_size);
if (token_size > 0)
{
std::vector<BYTE> token_buffer(token_size);
GetTokenInformation(token, TokenUser, token_buffer.data(), token_size, &token_size);
TOKEN_USER* user_ptr = (TOKEN_USER*)token_buffer.data();
PSID psid = user_ptr->User.Sid;
DWORD user_size = 0;
DWORD domain_size = 0;
SID_NAME_USE sid_name;
LookupAccountSidW(NULL, psid, NULL, &user_size, NULL, &domain_size, &sid_name);
user.resize(user_size + 1);
domain.resize(domain_size + 1);
LookupAccountSidW(NULL, psid, user.data(), &user_size, domain.data(), &domain_size, &sid_name);
user[user_size] = L'\0';
domain[domain_size] = L'\0';
}
CloseHandle(token);
}
CloseHandle(process);
return user;
}
constexpr size_t LongMaxPathSize = 65536; constexpr size_t LongMaxPathSize = 65536;
std::wstring pid_to_full_path(DWORD pid) std::wstring pid_to_full_path(DWORD pid)

View File

@@ -6,14 +6,12 @@ struct ProcessResult
{ {
std::wstring name; std::wstring name;
DWORD pid; DWORD pid;
std::wstring user;
std::vector<std::wstring> files; std::vector<std::wstring> files;
}; };
// Second version, checks handles towards files and all subfiles and folders of given dirs, if any. // Second version, checks handles towards files and all subfiles and folders of given dirs, if any.
std::vector<ProcessResult> find_processes_recursive(const std::vector<std::wstring>& paths); std::vector<ProcessResult> find_processes_recursive(const std::vector<std::wstring>& paths);
// Gives the user name of the account running this process
std::wstring pid_to_user(DWORD pid);
// Gives the full path of the executable, given the process id // Gives the full path of the executable, given the process id
std::wstring pid_to_full_path(DWORD pid); std::wstring pid_to_full_path(DWORD pid);

View File

@@ -128,46 +128,6 @@
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\FileLocksmith\</OutDir> <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\FileLocksmith\</OutDir>
<TargetName>PowerToys.FileLocksmithLib.Interop</TargetName> <TargetName>PowerToys.FileLocksmithLib.Interop</TargetName>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;FILELOCKSMITHLIBINTEROP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader>
<CompileAsManaged>NetCore</CompileAsManaged>
<LanguageStandard>stdcpp17</LanguageStandard>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<AdditionalOptions>/Zc:twoPhase-</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;FILELOCKSMITHLIBINTEROP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader>
<CompileAsManaged>NetCore</CompileAsManaged>
<LanguageStandard>stdcpp17</LanguageStandard>
<AdditionalOptions>/Zc:twoPhase-</AdditionalOptions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile> <ClCompile>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>

View File

@@ -238,6 +238,57 @@ std::vector<NtdllExtensions::HandleInfo> NtdllExtensions::handles() noexcept
// Returns the list of all processes. // Returns the list of all processes.
// On failure, returns an empty vector. // On failure, returns an empty vector.
std::wstring NtdllExtensions::pid_to_user(DWORD pid)
{
HANDLE process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
std::wstring user;
std::wstring domain;
if (process == nullptr)
{
return user;
}
HANDLE token = nullptr;
if (!OpenProcessToken(process, TOKEN_QUERY, &token))
{
return user;
}
DWORD token_size = 0;
GetTokenInformation(token, TokenUser, nullptr, 0, &token_size);
if (token_size < 0)
{
return user;
}
std::vector<BYTE> token_buffer(token_size);
GetTokenInformation(token, TokenUser, token_buffer.data(), token_size, &token_size);
TOKEN_USER* user_ptr = (TOKEN_USER*)token_buffer.data();
PSID psid = user_ptr->User.Sid;
DWORD user_buf_size = 0;
DWORD domain_buf_size = 0;
SID_NAME_USE sid_name;
LookupAccountSidW(nullptr, psid, nullptr, &user_buf_size, nullptr, &domain_buf_size, &sid_name);
if (!user_buf_size || !domain_buf_size)
{
return user;
}
user.resize(user_buf_size);
domain.resize(domain_buf_size);
LookupAccountSidW(nullptr, psid, user.data(), &user_buf_size, domain.data(), &domain_buf_size, &sid_name);
user.resize(user.size() - 1);
domain.resize(domain.size() - 1);
CloseHandle(token);
CloseHandle(process);
return user;
}
std::vector<NtdllExtensions::ProcessInfo> NtdllExtensions::processes() noexcept std::vector<NtdllExtensions::ProcessInfo> NtdllExtensions::processes() noexcept
{ {
auto get_info_result = NtQuerySystemInformationMemoryLoop(SystemProcessInformation); auto get_info_result = NtQuerySystemInformationMemoryLoop(SystemProcessInformation);
@@ -258,6 +309,7 @@ std::vector<NtdllExtensions::ProcessInfo> NtdllExtensions::processes() noexcept
item.name = unicode_to_str(info_ptr->ImageName); item.name = unicode_to_str(info_ptr->ImageName);
item.pid = (DWORD)(uintptr_t)info_ptr->UniqueProcessId; item.pid = (DWORD)(uintptr_t)info_ptr->UniqueProcessId;
item.modules = process_modules(item.pid); item.modules = process_modules(item.pid);
item.user = pid_to_user(item.pid);
result.push_back(item); result.push_back(item);
} }

View File

@@ -29,6 +29,7 @@ public:
{ {
DWORD pid; DWORD pid;
std::wstring name; std::wstring name;
std::wstring user;
std::vector<std::wstring> modules; std::vector<std::wstring> modules;
}; };
@@ -44,6 +45,9 @@ public:
std::wstring path_to_kernel_name(LPCWSTR path); std::wstring path_to_kernel_name(LPCWSTR path);
// Gives the user name of the account running this process
std::wstring pid_to_user(DWORD pid);
std::vector<HandleInfo> handles() noexcept; std::vector<HandleInfo> handles() noexcept;
// Returns the list of all processes. // Returns the list of all processes.

View File

@@ -10,6 +10,7 @@ namespace FileLocksmith::Interop
{ {
System::String^ name; System::String^ name;
System::UInt32 pid; System::UInt32 pid;
System::String^ user;
array<System::String^>^ files; array<System::String^>^ files;
}; };
@@ -69,6 +70,7 @@ namespace FileLocksmith::Interop
item->name = from_wstring_view(result_cpp[i].name); item->name = from_wstring_view(result_cpp[i].name);
item->pid = result_cpp[i].pid; item->pid = result_cpp[i].pid;
item->user = from_wstring_view(result_cpp[i].user);
const int n_files = static_cast<int>(result_cpp[i].files.size()); const int n_files = static_cast<int>(result_cpp[i].files.size());
item->files = gcnew array<System::String ^>(n_files); item->files = gcnew array<System::String ^>(n_files);
@@ -83,12 +85,6 @@ namespace FileLocksmith::Interop
return result; return result;
} }
static System::String^ PidToUser(System::UInt32 pid)
{
auto user_cpp = pid_to_user(pid);
return from_wstring_view(user_cpp);
}
static System::String^ PidToFullPath(System::UInt32 pid) static System::String^ PidToFullPath(System::UInt32 pid)
{ {
auto path_cpp = pid_to_full_path(pid); auto path_cpp = pid_to_full_path(pid);
@@ -180,5 +176,72 @@ namespace FileLocksmith::Interop
return false; return false;
} }
/* Adapted from "https://learn.microsoft.com/en-us/windows/win32/secauthz/enabling-and-disabling-privileges-in-c--" */
static System::Boolean SetDebugPrivilege()
{
HANDLE hToken;
TOKEN_PRIVILEGES tp;
LUID luid;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken) != 0)
{
if (!LookupPrivilegeValue(
NULL, // lookup privilege on local system
SE_DEBUG_NAME, // privilege to lookup
&luid)) // receives LUID of privilege
{
CloseHandle(hToken);
return false;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(
hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES)NULL,
(PDWORD)NULL))
{
CloseHandle(hToken);
return false;
}
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
CloseHandle(hToken);
return false;
}
CloseHandle(hToken);
return true;
}
return false;
}
// adapted from common/utils/elevation.h. No need to bring all dependencies to this project, though.
// TODO: Make elevation.h lighter so that this function can be used without bringing dependencies like spdlog in.
static System::Boolean IsProcessElevated()
{
HANDLE token = nullptr;
bool elevated = false;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
{
TOKEN_ELEVATION elevation;
DWORD size;
if (GetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation), &size))
{
elevated = (elevation.TokenIsElevated != 0);
}
}
if (token)
{
CloseHandle(token);
}
return elevated;
}
}; };
} }

View File

@@ -40,7 +40,17 @@ namespace FileLocksmithUI
return; return;
} }
_window = new MainWindow(Environment.GetCommandLineArgs().Contains("--elevated")); bool isElevated = FileLocksmith.Interop.NativeMethods.IsProcessElevated();
if (isElevated)
{
if (!FileLocksmith.Interop.NativeMethods.SetDebugPrivilege())
{
Logger.LogWarning("Couldn't set debug privileges to see system processes.");
}
}
_window = new MainWindow(isElevated);
_window.Activate(); _window.Activate();
} }

View File

@@ -5,19 +5,29 @@
namespace PowerToys.FileLocksmithUI.Converters namespace PowerToys.FileLocksmithUI.Converters
{ {
using System; using System;
using System.Globalization;
using FileLocksmith.Interop; using FileLocksmith.Interop;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Data; using Microsoft.UI.Xaml.Data;
public sealed class PidToUserConverter : IValueConverter public sealed class UserToSystemWarningVisibilityConverter : IValueConverter
{ {
public object Convert(object value, Type targetType, object parameter, string language) public object Convert(object value, Type targetType, object parameter, string language)
{ {
return NativeMethods.PidToUser((uint)value); string user = ((string)value).ToUpperInvariant().Trim();
if (user.Equals("SYSTEM", StringComparison.Ordinal) || user.Equals("LOCALSYSTEM", StringComparison.Ordinal))
{
return Visibility.Visible;
}
else
{
return Visibility.Collapsed;
}
} }
public object ConvertBack(object value, Type targetType, object parameter, string language) public object ConvertBack(object value, Type targetType, object parameter, string language)
{ {
return value; throw new NotSupportedException();
} }
} }
} }

View File

@@ -54,7 +54,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Windows.CsWinRT" Version="2.0.0" /> <PackageReference Include="Microsoft.Windows.CsWinRT" Version="2.0.0" />
<PackageReference Include="CommunityToolkit.Labs.WinUI.SettingsControls" Version="0.0.2" /> <PackageReference Include="CommunityToolkit.Labs.WinUI.SettingsControls" Version="0.0.7" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.0.0" /> <PackageReference Include="CommunityToolkit.Mvvm" Version="8.0.0" />
<PackageReference Include="CommunityToolkit.WinUI.UI" Version="7.1.2" /> <PackageReference Include="CommunityToolkit.WinUI.UI" Version="7.1.2" />
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.1.5" /> <PackageReference Include="Microsoft.WindowsAppSDK" Version="1.1.5" />

View File

@@ -136,6 +136,9 @@
<value>Click to see the entire list of paths.</value> <value>Click to see the entire list of paths.</value>
<comment>Paths as in file paths that were selected for the utility to check.</comment> <comment>Paths as in file paths that were selected for the utility to check.</comment>
</data> </data>
<data name="ProcessIsSystemUserWarning.Text" xml:space="preserve">
<value>The process belongs to a system user. Closing it may cause the system to malfunction.</value>
</data>
<data name="SelectedFilesListDialog.Title" xml:space="preserve"> <data name="SelectedFilesListDialog.Title" xml:space="preserve">
<value>Selected file paths</value> <value>Selected file paths</value>
<comment>Paths as in file paths that were selected for the utility to check.</comment> <comment>Paths as in file paths that were selected for the utility to check.</comment>

View File

@@ -8,7 +8,6 @@
xmlns:interactivity="using:Microsoft.Xaml.Interactivity" xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:interop="using:FileLocksmith.Interop" xmlns:interop="using:FileLocksmith.Interop"
xmlns:labs="using:CommunityToolkit.Labs.WinUI" xmlns:labs="using:CommunityToolkit.Labs.WinUI"
xmlns:local="using:PowerToys.FileLocksmithUI.Views"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:toolkitConverters="using:CommunityToolkit.WinUI.UI.Converters" xmlns:toolkitConverters="using:CommunityToolkit.WinUI.UI.Converters"
mc:Ignorable="d"> mc:Ignorable="d">
@@ -25,7 +24,7 @@
TrueValue="Collapsed" /> TrueValue="Collapsed" />
<converters:FileCountConverter x:Key="fileCountConverter" /> <converters:FileCountConverter x:Key="fileCountConverter" />
<converters:PidToIconConverter x:Key="pidToIconConverter" /> <converters:PidToIconConverter x:Key="pidToIconConverter" />
<converters:PidToUserConverter x:Key="pidToUserConverter" /> <converters:UserToSystemWarningVisibilityConverter x:Key="userToSystemWarningVisibilityConverter" />
<converters:FileListToDescriptionConverter x:Key="fileListToDescriptionConverter" /> <converters:FileListToDescriptionConverter x:Key="fileListToDescriptionConverter" />
</Page.Resources> </Page.Resources>
@@ -41,23 +40,28 @@
<RowDefinition Height="*" /> <RowDefinition Height="*" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid Padding="18,0,18,4" VerticalAlignment="Bottom"> <Grid
<!--<TextBlock Margin="0,2,0,0" Text="Current proccesses:" Style="{ThemeResource BodyStrongTextBlockStyle}"/>--> Padding="18,0,18,4"
<Button Content="{x:Bind ViewModel.Paths, Converter={StaticResource fileListToDescriptionConverter}}" Click="ShowSelectedPathsButton_Click"> VerticalAlignment="Bottom">
<Button
Click="ShowSelectedPathsButton_Click"
Content="{x:Bind ViewModel.Paths, Converter={StaticResource fileListToDescriptionConverter}}">
<Button.Template> <Button.Template>
<ControlTemplate TargetType="Button"> <ControlTemplate TargetType="Button">
<TextBlock Margin="0,8,0,0" <TextBlock
Margin="0,8,0,0"
HorizontalAlignment="Left" HorizontalAlignment="Left"
Style="{ThemeResource BodyStrongTextBlockStyle}" Style="{ThemeResource BodyStrongTextBlockStyle}"
Text="{TemplateBinding Content}" > Text="{TemplateBinding Content}" />
</TextBlock>
</ControlTemplate> </ControlTemplate>
</Button.Template> </Button.Template>
<ToolTipService.ToolTip> <ToolTipService.ToolTip>
<TextBlock x:Uid="PathsTooltipDescription" TextWrapping="WrapWholeWords"/> <TextBlock
x:Uid="PathsTooltipDescription"
TextWrapping="WrapWholeWords" />
</ToolTipService.ToolTip> </ToolTipService.ToolTip>
</Button> </Button>
<StackPanel <StackPanel
HorizontalAlignment="Right" HorizontalAlignment="Right"
VerticalAlignment="Bottom" VerticalAlignment="Bottom"
@@ -71,7 +75,7 @@
<FontIcon <FontIcon
FontFamily="{ThemeResource SymbolThemeFontFamily}" FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="16" FontSize="16"
Glyph="&#xE149;" /> Glyph="&#xe72c;" />
<ToolTipService.ToolTip> <ToolTipService.ToolTip>
<TextBlock x:Uid="Reload" /> <TextBlock x:Uid="Reload" />
</ToolTipService.ToolTip> </ToolTipService.ToolTip>
@@ -85,7 +89,7 @@
<FontIcon <FontIcon
FontFamily="{ThemeResource SymbolThemeFontFamily}" FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="16" FontSize="16"
Glyph="&#xE1A7;" /> Glyph="&#xe7ef;" />
<ToolTipService.ToolTip> <ToolTipService.ToolTip>
<TextBlock x:Uid="RestartAsAdmin" /> <TextBlock x:Uid="RestartAsAdmin" />
</ToolTipService.ToolTip> </ToolTipService.ToolTip>
@@ -98,75 +102,101 @@
<ListView <ListView
x:Name="ProcessesListView" x:Name="ProcessesListView"
Grid.Row="1" Grid.Row="1"
ItemsSource="{x:Bind ViewModel.Processes}"
IncrementalLoadingThreshold="10" IncrementalLoadingThreshold="10"
ItemsSource="{x:Bind ViewModel.Processes}"
SelectionMode="None"> SelectionMode="None">
<ListView.ItemTemplate> <ListView.ItemTemplate>
<DataTemplate x:DataType="interop:ProcessResult"> <DataTemplate x:DataType="interop:ProcessResult">
<labs:SettingsExpander Margin="0,3,0,0"> <labs:SettingsExpander Margin="0,3,0,0">
<labs:SettingsExpander.Header> <labs:SettingsExpander.Resources>
<!-- We can't use the HeaderIcon because it only support a BitmapIcon, which only supports UriSource - not a direct BitmapImage --> <x:Double x:Key="SettingsCardWrapThreshold">0</x:Double>
<StackPanel Orientation="Horizontal"> </labs:SettingsExpander.Resources>
<Image <labs:SettingsExpander.Header>
Width="16" <!-- We can't use the HeaderIcon because it only support a BitmapIcon, which only supports UriSource - not a direct BitmapImage -->
Height="16" <StackPanel Orientation="Horizontal">
Margin="2,0,24,0" <Image
Source="{x:Bind pid, Converter={StaticResource pidToIconConverter}}" /> Width="16"
<TextBlock IsTextSelectionEnabled="True" Text="{x:Bind name}" /> Height="16"
</StackPanel> Margin="2,0,24,0"
</labs:SettingsExpander.Header> Source="{x:Bind pid, Converter={StaticResource pidToIconConverter}}" />
<labs:SettingsExpander.Content> <TextBlock
<Button Command="{Binding Path=DataContext.EndTaskCommand, ElementName=ProcessesListView}" CommandParameter="{Binding}"> IsTextSelectionEnabled="True"
<StackPanel Orientation="Horizontal" Spacing="6"> Text="{x:Bind name}" />
</StackPanel>
</labs:SettingsExpander.Header>
<labs:SettingsExpander.Content>
<StackPanel
Orientation="Horizontal"
Spacing="8">
<FontIcon
Foreground="{ThemeResource InfoBarWarningSeverityIconBackground}"
Glyph="&#xE7BA;"
Visibility="{x:Bind user, Mode=OneTime, Converter={StaticResource userToSystemWarningVisibilityConverter}}">
<ToolTipService.ToolTip>
<TextBlock
x:Uid="ProcessIsSystemUserWarning"
TextWrapping="Wrap" />
</ToolTipService.ToolTip>
</FontIcon>
<Button
MinWidth="132"
Command="{Binding Path=DataContext.EndTaskCommand, ElementName=ProcessesListView}"
CommandParameter="{Binding}">
<StackPanel
Orientation="Horizontal"
Spacing="6">
<FontIcon <FontIcon
FontFamily="{ThemeResource SymbolThemeFontFamily}" FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="14" FontSize="14"
Glyph="&#xf140;" /> Glyph="&#xf140;" />
<TextBlock x:Uid="EndTask" /> <TextBlock
x:Uid="EndTask"
FontSize="14" />
</StackPanel> </StackPanel>
</Button> </Button>
</labs:SettingsExpander.Content> </StackPanel>
<labs:SettingsExpander.Items> </labs:SettingsExpander.Content>
<labs:SettingsCard x:Uid="ProcessID"> <labs:SettingsExpander.Items>
<TextBlock <labs:SettingsCard x:Uid="ProcessID">
Foreground="{ThemeResource TextFillColorSecondaryBrush}" <TextBlock
IsTextSelectionEnabled="True" Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="{x:Bind pid}" /> IsTextSelectionEnabled="True"
</labs:SettingsCard> Text="{x:Bind pid}" />
<labs:SettingsCard x:Uid="User"> </labs:SettingsCard>
<TextBlock <labs:SettingsCard x:Uid="User">
Foreground="{ThemeResource TextFillColorSecondaryBrush}" <TextBlock
IsTextSelectionEnabled="True" Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="{x:Bind pid, Converter={StaticResource pidToUserConverter}}" /> IsTextSelectionEnabled="True"
</labs:SettingsCard> Text="{x:Bind user}" />
<labs:SettingsCard ContentAlignment="Vertical"> </labs:SettingsCard>
<labs:SettingsCard.Header> <labs:SettingsCard ContentAlignment="Vertical">
<TextBlock> <labs:SettingsCard.Header>
<Run x:Uid="Files" /> <TextBlock>
<Run Text="(" /><Run Text="{x:Bind files, Converter={StaticResource fileCountConverter}}" /><Run Text=")" /> <Run x:Uid="Files" />
</TextBlock> <Run Text="(" /><Run Text="{x:Bind files, Converter={StaticResource fileCountConverter}}" /><Run Text=")" />
</labs:SettingsCard.Header> </TextBlock>
<ListView </labs:SettingsCard.Header>
Margin="-16,0,0,0" <ItemsRepeater
ItemsSource="{x:Bind files}" Margin="-16,0,0,0"
SelectionMode="None"> ItemsSource="{x:Bind files}">
<ListView.ItemTemplate> <ItemsRepeater.ItemTemplate>
<DataTemplate x:DataType="x:String"> <DataTemplate x:DataType="x:String">
<TextBlock <TextBlock
FontSize="12" Margin="16,0,0,4"
Foreground="{ThemeResource TextFillColorSecondaryBrush}" FontSize="12"
IsTextSelectionEnabled="True" Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Style="{StaticResource CaptionTextBlockStyle}" IsTextSelectionEnabled="True"
Text="{Binding}" Style="{StaticResource CaptionTextBlockStyle}"
TextTrimming="CharacterEllipsis" Text="{Binding}"
TextWrapping="NoWrap" TextTrimming="CharacterEllipsis"
ToolTipService.ToolTip="{Binding}" /> TextWrapping="NoWrap"
</DataTemplate> ToolTipService.ToolTip="{Binding}" />
</ListView.ItemTemplate> </DataTemplate>
</ListView> </ItemsRepeater.ItemTemplate>
</labs:SettingsCard> </ItemsRepeater>
</labs:SettingsExpander.Items> </labs:SettingsCard>
</labs:SettingsExpander> </labs:SettingsExpander.Items>
</labs:SettingsExpander>
</DataTemplate> </DataTemplate>
</ListView.ItemTemplate> </ListView.ItemTemplate>
</ListView> </ListView>
@@ -176,17 +206,23 @@
Orientation="Vertical" Orientation="Vertical"
Spacing="8" Spacing="8"
Visibility="{x:Bind ViewModel.Processes.Count, Mode=OneWay, Converter={StaticResource doubleToVisibilityConverter}}"> Visibility="{x:Bind ViewModel.Processes.Count, Mode=OneWay, Converter={StaticResource doubleToVisibilityConverter}}">
<Button HorizontalAlignment="Center" Command="{Binding LoadProcessesCommand}" > <Button
HorizontalAlignment="Center"
Command="{Binding LoadProcessesCommand}">
<Button.Template> <Button.Template>
<ControlTemplate TargetType="Button"> <ControlTemplate TargetType="Button">
<FontIcon FontSize="32" Glyph="&#xE9F3;" /> <FontIcon
FontSize="32"
Glyph="&#xE9F3;" />
</ControlTemplate> </ControlTemplate>
</Button.Template> </Button.Template>
<ToolTipService.ToolTip> <ToolTipService.ToolTip>
<TextBlock x:Uid="Reload" /> <TextBlock x:Uid="Reload" />
</ToolTipService.ToolTip> </ToolTipService.ToolTip>
</Button> </Button>
<TextBlock x:Uid="EmptyListDescription" Foreground="{ThemeResource TextFillColorSecondaryBrush}" /> <TextBlock
x:Uid="EmptyListDescription"
Foreground="{ThemeResource TextFillColorSecondaryBrush}" />
</StackPanel> </StackPanel>
</Grid> </Grid>
<ProgressRing <ProgressRing
@@ -196,10 +232,15 @@
</Grid> </Grid>
<ContentDialog <ContentDialog
x:Name="SelectedFilesListDialog" x:Name="SelectedFilesListDialog"
x:Uid="SelectedFilesListDialog" x:Uid="SelectedFilesListDialog">
> <ScrollViewer
<ScrollViewer HorizontalScrollBarVisibility="Auto" HorizontalScrollMode="Auto" VerticalScrollBarVisibility="Auto" VerticalScrollMode="Auto"> HorizontalScrollBarVisibility="Auto"
<TextBlock Text="{x:Bind ViewModel.PathsToString, Mode=OneWay}"/> HorizontalScrollMode="Auto"
VerticalScrollBarVisibility="Auto"
VerticalScrollMode="Auto">
<TextBlock
IsTextSelectionEnabled="True"
Text="{x:Bind ViewModel.PathsToString, Mode=OneWay}" />
</ScrollViewer> </ScrollViewer>
</ContentDialog> </ContentDialog>
</Grid> </Grid>

View File

@@ -41,7 +41,9 @@
Height="36" Height="36"
Margin="16,0,0,0" Margin="16,0,0,0"
Command="{x:Bind NewDialogCommand}"> Command="{x:Bind NewDialogCommand}">
<StackPanel Orientation="Horizontal" Spacing="12"> <StackPanel
Orientation="Horizontal"
Spacing="12">
<TextBlock <TextBlock
x:Name="Icon" x:Name="Icon"
Margin="0,0,0,0" Margin="0,0,0,0"
@@ -49,7 +51,7 @@
FontFamily="{ThemeResource SymbolThemeFontFamily}" FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="16" FontSize="16"
Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}" Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}"
Text="&#xE109;" /> Text="&#xe710;" />
<TextBlock x:Uid="AddEntry" /> <TextBlock x:Uid="AddEntry" />
</StackPanel> </StackPanel>
</Button> </Button>
@@ -124,7 +126,7 @@
</Flyout> </Flyout>
</Button.Flyout> </Button.Flyout>
</Button> </Button>
<Button <Button
x:Uid="OpenHostsFileBtn" x:Uid="OpenHostsFileBtn"
Height="36" Height="36"
@@ -135,7 +137,7 @@
FontSize="14" FontSize="14"
Glyph="&#xe8a7;" /> Glyph="&#xe8a7;" />
</Button> </Button>
<Button <Button
x:Uid="SettingsBtn" x:Uid="SettingsBtn"
Height="36" Height="36"
@@ -165,7 +167,9 @@
IsOpen="{x:Bind ViewModel.FileChanged, Mode=TwoWay}" IsOpen="{x:Bind ViewModel.FileChanged, Mode=TwoWay}"
Severity="Informational"> Severity="Informational">
<InfoBar.ActionButton> <InfoBar.ActionButton>
<Button x:Uid="Reload" Command="{x:Bind ViewModel.ReadHostsCommand}" /> <Button
x:Uid="Reload"
Command="{x:Bind ViewModel.ReadHostsCommand}" />
</InfoBar.ActionButton> </InfoBar.ActionButton>
</InfoBar> </InfoBar>
</StackPanel> </StackPanel>
@@ -177,8 +181,8 @@
CanReorderItems="{x:Bind ViewModel.Filtered, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}" CanReorderItems="{x:Bind ViewModel.Filtered, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}"
--> -->
<ListView <ListView
x:Uid="Entries"
x:Name="Entries" x:Name="Entries"
x:Uid="Entries"
Grid.Row="1" Grid.Row="1"
Margin="16,8,16,16" Margin="16,8,16,16"
Background="{ThemeResource LayerFillColorDefaultBrush}" Background="{ThemeResource LayerFillColorDefaultBrush}"
@@ -253,8 +257,8 @@
x:Name="PingIcon" x:Name="PingIcon"
Grid.Column="2" Grid.Column="2"
Margin="0,0,8,0" Margin="0,0,8,0"
FontSize="18"
FontFamily="{ThemeResource SymbolThemeFontFamily}" FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="18"
Visibility="Collapsed"> Visibility="Collapsed">
<i:Interaction.Behaviors> <i:Interaction.Behaviors>
<ic:DataTriggerBehavior <ic:DataTriggerBehavior
@@ -324,7 +328,9 @@
<ContentDialog.DataContext> <ContentDialog.DataContext>
<models:Entry /> <models:Entry />
</ContentDialog.DataContext> </ContentDialog.DataContext>
<ScrollViewer HorizontalScrollMode="Auto" HorizontalScrollBarVisibility="Auto"> <ScrollViewer
HorizontalScrollBarVisibility="Auto"
HorizontalScrollMode="Auto">
<StackPanel <StackPanel
MinWidth="480" MinWidth="480"
Margin="0,12,0,0" Margin="0,12,0,0"
@@ -372,6 +378,9 @@
Margin="0,12,0,0" Margin="0,12,0,0"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
AcceptsReturn="True" AcceptsReturn="True"
ScrollViewer.IsVerticalRailEnabled="True"
ScrollViewer.VerticalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollMode="Enabled"
TextWrapping="Wrap" /> TextWrapping="Wrap" />
</ContentDialog> </ContentDialog>

View File

@@ -41,7 +41,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Windows.CsWinRT" Version="2.0.0" /> <PackageReference Include="Microsoft.Windows.CsWinRT" Version="2.0.0" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" /> <PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="ModernWpfUI" Version="0.9.6" /> <PackageReference Include="ModernWpfUI" Version="0.9.4" />
<PackageReference Include="System.ComponentModel.Composition" Version="6.0.0" /> <PackageReference Include="System.ComponentModel.Composition" Version="6.0.0" />
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" /> <PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
<PackageReference Include="System.IO.Abstractions" Version="17.2.3" /> <PackageReference Include="System.IO.Abstractions" Version="17.2.3" />

View File

@@ -56,7 +56,9 @@ namespace ColorPicker.Settings
if (!_loadingColorsHistory) if (!_loadingColorsHistory)
{ {
var settings = _settingsUtils.GetSettingsOrDefault<ColorPickerSettings>(ColorPickerModuleName); var settings = _settingsUtils.GetSettingsOrDefault<ColorPickerSettings>(ColorPickerModuleName);
ColorHistory.CollectionChanged -= ColorHistory_CollectionChanged;
settings.Properties.ColorHistory = ColorHistory.ToList(); settings.Properties.ColorHistory = ColorHistory.ToList();
ColorHistory.CollectionChanged += ColorHistory_CollectionChanged;
settings.Save(_settingsUtils); settings.Save(_settingsUtils);
} }
} }

View File

@@ -122,29 +122,31 @@ bool Layout::Init(const FancyZonesUtils::Rect& workArea, HMONITOR monitor) noexc
return false; return false;
} }
auto spacing = m_data.showSpacing ? m_data.spacing : 0;
switch (m_data.type) switch (m_data.type)
{ {
case FancyZonesDataTypes::ZoneSetLayoutType::Focus: case FancyZonesDataTypes::ZoneSetLayoutType::Focus:
m_zones = LayoutConfigurator::Focus(workArea, m_data.zoneCount); m_zones = LayoutConfigurator::Focus(workArea, m_data.zoneCount);
break; break;
case FancyZonesDataTypes::ZoneSetLayoutType::Columns: case FancyZonesDataTypes::ZoneSetLayoutType::Columns:
m_zones = LayoutConfigurator::Columns(workArea, m_data.zoneCount, m_data.spacing); m_zones = LayoutConfigurator::Columns(workArea, m_data.zoneCount, spacing);
break; break;
case FancyZonesDataTypes::ZoneSetLayoutType::Rows: case FancyZonesDataTypes::ZoneSetLayoutType::Rows:
m_zones = LayoutConfigurator::Rows(workArea, m_data.zoneCount, m_data.spacing); m_zones = LayoutConfigurator::Rows(workArea, m_data.zoneCount, spacing);
break; break;
case FancyZonesDataTypes::ZoneSetLayoutType::Grid: case FancyZonesDataTypes::ZoneSetLayoutType::Grid:
m_zones = LayoutConfigurator::Grid(workArea, m_data.zoneCount, m_data.spacing); m_zones = LayoutConfigurator::Grid(workArea, m_data.zoneCount, spacing);
break; break;
case FancyZonesDataTypes::ZoneSetLayoutType::PriorityGrid: case FancyZonesDataTypes::ZoneSetLayoutType::PriorityGrid:
m_zones = LayoutConfigurator::PriorityGrid(workArea, m_data.zoneCount, m_data.spacing); m_zones = LayoutConfigurator::PriorityGrid(workArea, m_data.zoneCount, spacing);
break; break;
case FancyZonesDataTypes::ZoneSetLayoutType::Custom: case FancyZonesDataTypes::ZoneSetLayoutType::Custom:
{ {
const auto customLayoutData = CustomLayouts::instance().GetCustomLayoutData(m_data.uuid); const auto customLayoutData = CustomLayouts::instance().GetCustomLayoutData(m_data.uuid);
if (customLayoutData.has_value()) if (customLayoutData.has_value())
{ {
m_zones = LayoutConfigurator::Custom(workArea, monitor, customLayoutData.value(), m_data.spacing); m_zones = LayoutConfigurator::Custom(workArea, monitor, customLayoutData.value(), spacing);
} }
else else
{ {

View File

@@ -21,7 +21,7 @@ namespace FancyZonesUnitTests
{ {
.uuid = FancyZonesUtils::GuidFromString(L"{F762BAD6-DAA1-4997-9497-E11DFEB72F21}").value(), .uuid = FancyZonesUtils::GuidFromString(L"{F762BAD6-DAA1-4997-9497-E11DFEB72F21}").value(),
.type = ZoneSetLayoutType::Grid, .type = ZoneSetLayoutType::Grid,
.showSpacing = false, .showSpacing = true,
.spacing = 17, .spacing = 17,
.zoneCount = 4, .zoneCount = 4,
.sensitivityRadius = 33 .sensitivityRadius = 33
@@ -192,7 +192,7 @@ namespace FancyZonesUnitTests
const LayoutData m_data{ const LayoutData m_data{
.uuid = FancyZonesUtils::GuidFromString(L"{33A2B101-06E0-437B-A61E-CDBECF502906}").value(), .uuid = FancyZonesUtils::GuidFromString(L"{33A2B101-06E0-437B-A61E-CDBECF502906}").value(),
.type = ZoneSetLayoutType::Grid, .type = ZoneSetLayoutType::Grid,
.showSpacing = false, .showSpacing = true,
.spacing = 17, .spacing = 17,
.zoneCount = 4, .zoneCount = 4,
.sensitivityRadius = 33 .sensitivityRadius = 33

View File

@@ -47,7 +47,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Windows.CsWinRT" Version="2.0.0" /> <PackageReference Include="Microsoft.Windows.CsWinRT" Version="2.0.0" />
<PackageReference Include="ModernWpfUI" Version="0.9.6" /> <PackageReference Include="ModernWpfUI" Version="0.9.4" />
<PackageReference Include="System.IO.Abstractions" Version="17.2.3" /> <PackageReference Include="System.IO.Abstractions" Version="17.2.3" />
<PackageReference Include="System.Text.Json" Version="6.0.2" /> <PackageReference Include="System.Text.Json" Version="6.0.2" />
</ItemGroup> </ItemGroup>

View File

@@ -46,7 +46,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Windows.CsWinRT" Version="2.0.0" /> <PackageReference Include="Microsoft.Windows.CsWinRT" Version="2.0.0" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.39" /> <PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.39" />
<PackageReference Include="ModernWpfUI" Version="0.9.6" /> <PackageReference Include="ModernWpfUI" Version="0.9.4" />
<PackageReference Include="System.IO.Abstractions"> <PackageReference Include="System.IO.Abstractions">
<Version>17.2.3</Version> <Version>17.2.3</Version>
</PackageReference> </PackageReference>

View File

@@ -84,7 +84,7 @@
<PackageReference Include="Microsoft.Data.Sqlite" Version="6.0.9" /> <PackageReference Include="Microsoft.Data.Sqlite" Version="6.0.9" />
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.2" /> <PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.2" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.39" /> <PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.39" />
<PackageReference Include="ModernWpfUI" Version="0.9.6" /> <PackageReference Include="ModernWpfUI" Version="0.9.4" />
<PackageReference Include="ScipBe.Common.Office.OneNote" Version="3.0.1" /> <PackageReference Include="ScipBe.Common.Office.OneNote" Version="3.0.1" />
<PackageReference Include="System.Reactive" Version="5.0.0" /> <PackageReference Include="System.Reactive" Version="5.0.0" />
<PackageReference Include="System.Runtime" Version="4.3.1" /> <PackageReference Include="System.Runtime" Version="4.3.1" />

View File

@@ -2147,7 +2147,7 @@ From there, simply click on one of the supported files in the File Explorer and
<value>Zone appearance</value> <value>Zone appearance</value>
</data> </data>
<data name="VideoConference_DeprecationWarning.Title" xml:space="preserve"> <data name="VideoConference_DeprecationWarning.Title" xml:space="preserve">
<value>Video Conference utility is reaching its end of life and will be unavailable in one of the future releases.</value> <value>VCM is moving into legacy mode (maintenance only).</value>
</data> </data>
<data name="VideoConference_DeprecationWarningButton.Content" xml:space="preserve"> <data name="VideoConference_DeprecationWarningButton.Content" xml:space="preserve">
<value>Learn more</value> <value>Learn more</value>