mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-02-23 19:49:43 +01:00
Compare commits
10 Commits
user/yeela
...
v0.67.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d986d2e421 | ||
|
|
5e30d1e5aa | ||
|
|
9ffaa0328b | ||
|
|
ca3b2563a8 | ||
|
|
e24f6849d5 | ||
|
|
cedb51bdad | ||
|
|
1856052014 | ||
|
|
91998ef875 | ||
|
|
6668ec40fc | ||
|
|
2e27cac8c8 |
1
.github/actions/spell-check/expect.txt
vendored
1
.github/actions/spell-check/expect.txt
vendored
@@ -1479,6 +1479,7 @@ rescap
|
|||||||
resgen
|
resgen
|
||||||
resheader
|
resheader
|
||||||
resizers
|
resizers
|
||||||
|
RESIZETOFIT
|
||||||
resmimetype
|
resmimetype
|
||||||
RESOURCEID
|
RESOURCEID
|
||||||
resourcemanager
|
resourcemanager
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
<DirectoryRef Id="INSTALLFOLDER" FileSource="$(var.BinDir)">
|
<DirectoryRef Id="INSTALLFOLDER" FileSource="$(var.BinDir)">
|
||||||
<Component Id="powertoys_toast_clsid" Win64="yes">
|
<Component Id="powertoys_toast_clsid" Win64="yes">
|
||||||
<RemoveFolder Id='Remove_powertoys_toast_clsid' On='uninstall' />
|
<RemoveFolder Id='Remove_powertoys_toast_clsid' On='uninstall' />
|
||||||
<RegistryKey Root="HKCU" Key="Software\Classes\CLSID\{DD5CACDA-7C2E-4997-A62A-04A597B58F76}">
|
<RegistryKey Root="HKCR" Key="Software\Classes\CLSID\{DD5CACDA-7C2E-4997-A62A-04A597B58F76}">
|
||||||
<RegistryValue Type="string" Value="PowerToys Toast Notifications Background Activator" />
|
<RegistryValue Type="string" Value="PowerToys Toast Notifications Background Activator" />
|
||||||
<RegistryValue Type="string" Key="LocalServer32" Value="[INSTALLFOLDER]PowerToys.exe -ToastActivated" />
|
<RegistryValue Type="string" Key="LocalServer32" Value="[INSTALLFOLDER]PowerToys.exe -ToastActivated" />
|
||||||
<RegistryValue Type="string" Key="LocalServer32" Name="ThreadingModel" Value="Apartment" />
|
<RegistryValue Type="string" Key="LocalServer32" Name="ThreadingModel" Value="Apartment" />
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
</Component>
|
</Component>
|
||||||
<Component Id="powertoys_exe" Win64="yes" Guid="30261594-41A6-4509-AD09-FBC4E692F441">
|
<Component Id="powertoys_exe" Win64="yes" Guid="30261594-41A6-4509-AD09-FBC4E692F441">
|
||||||
<File Id="PowerToys.exe" Checksum="yes" />
|
<File Id="PowerToys.exe" Checksum="yes" />
|
||||||
<RegistryKey Root="HKCU" Key="Software\Classes\powertoys">
|
<RegistryKey Root="HKLM" Key="Software\Classes\powertoys">
|
||||||
<RegistryValue Type="string" Name="URL Protocol" Value="" KeyPath="yes"/>
|
<RegistryValue Type="string" Name="URL Protocol" Value="" KeyPath="yes"/>
|
||||||
<RegistryValue Type="string" Value="URL:PowerToys custom internal URI protocol"/>
|
<RegistryValue Type="string" Value="URL:PowerToys custom internal URI protocol"/>
|
||||||
<RegistryKey Key="DefaultIcon">
|
<RegistryKey Key="DefaultIcon">
|
||||||
@@ -89,12 +89,12 @@
|
|||||||
|
|
||||||
<DirectoryRef Id="ModulesInstallFolder" FileSource="$(var.BinDir)modules\">
|
<DirectoryRef Id="ModulesInstallFolder" FileSource="$(var.BinDir)modules\">
|
||||||
<Component Id="Module_PowerPreview_Registry" Win64="yes">
|
<Component Id="Module_PowerPreview_Registry" Win64="yes">
|
||||||
<!-- Update Key to use IE11 for prevhost.exe -->
|
<!-- TODO: Remove this - Update Key to use IE11 for prevhost.exe -->
|
||||||
<RegistryKey Root="HKCU" Key="Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION">
|
<RegistryKey Root="HKLM" Key="Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION">
|
||||||
<RegistryValue Type="integer" Name="prevhost.exe" Value="11000" />
|
<RegistryValue Type="integer" Name="prevhost.exe" Value="11000" />
|
||||||
</RegistryKey>
|
</RegistryKey>
|
||||||
<!-- Update Key to use IE11 for dllhost.exe -->
|
<!-- TODO: Remove this - Update Key to use IE11 for dllhost.exe -->
|
||||||
<RegistryKey Root="HKCU" Key="Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION">
|
<RegistryKey Root="HKLM" Key="Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION">
|
||||||
<RegistryValue Type="integer" Name="dllhost.exe" Value="11000" />
|
<RegistryValue Type="integer" Name="dllhost.exe" Value="11000" />
|
||||||
</RegistryKey>
|
</RegistryKey>
|
||||||
</Component>
|
</Component>
|
||||||
|
|||||||
@@ -17,16 +17,16 @@
|
|||||||
<?endforeach?>
|
<?endforeach?>
|
||||||
<!-- !Warning! Make sure to change Component Guid if you update something here -->
|
<!-- !Warning! Make sure to change Component Guid if you update something here -->
|
||||||
<Component Id="Module_FileLocksmith" Guid="108D3EC1-E6E0-4E81-88EF-25966133CB41" Win64="yes">
|
<Component Id="Module_FileLocksmith" Guid="108D3EC1-E6E0-4E81-88EF-25966133CB41" Win64="yes">
|
||||||
<RegistryKey Root="HKCU" Key="Software\Classes\CLSID\{84D68575-E186-46AD-B0CB-BAEB45EE29C0}">
|
<RegistryKey Root="HKLM" Key="Software\Classes\CLSID\{84D68575-E186-46AD-B0CB-BAEB45EE29C0}">
|
||||||
<RegistryValue Type="string" Value="File Locksmith Shell Extension" />
|
<RegistryValue Type="string" Value="File Locksmith Shell Extension" />
|
||||||
<RegistryValue Type="string" Name="ContextMenuOptIn" Value="" />
|
<RegistryValue Type="string" Name="ContextMenuOptIn" Value="" />
|
||||||
<RegistryValue Type="string" Key="InprocServer32" Value="[FileLocksmithInstallFolder]PowerToys.FileLocksmithExt.dll" />
|
<RegistryValue Type="string" Key="InprocServer32" Value="[FileLocksmithInstallFolder]PowerToys.FileLocksmithExt.dll" />
|
||||||
<RegistryValue Type="string" Key="InprocServer32" Name="ThreadingModel" Value="Apartment" />
|
<RegistryValue Type="string" Key="InprocServer32" Name="ThreadingModel" Value="Apartment" />
|
||||||
</RegistryKey>
|
</RegistryKey>
|
||||||
<RegistryKey Root="HKCU" Key="Software\Classes\AllFileSystemObjects\ShellEx\ContextMenuHandlers\FileLocksmithExt">
|
<RegistryKey Root="HKLM" Key="Software\Classes\AllFileSystemObjects\ShellEx\ContextMenuHandlers\FileLocksmithExt">
|
||||||
<RegistryValue Type="string" Value="{84D68575-E186-46AD-B0CB-BAEB45EE29C0}"/>
|
<RegistryValue Type="string" Value="{84D68575-E186-46AD-B0CB-BAEB45EE29C0}"/>
|
||||||
</RegistryKey>
|
</RegistryKey>
|
||||||
<RegistryKey Root="HKCU" Key="Software\Classes\Drive\ShellEx\ContextMenuHandlers\FileLocksmithExt">
|
<RegistryKey Root="HKLM" Key="Software\Classes\Drive\ShellEx\ContextMenuHandlers\FileLocksmithExt">
|
||||||
<RegistryValue Type="string" Value="{84D68575-E186-46AD-B0CB-BAEB45EE29C0}"/>
|
<RegistryValue Type="string" Value="{84D68575-E186-46AD-B0CB-BAEB45EE29C0}"/>
|
||||||
</RegistryKey>
|
</RegistryKey>
|
||||||
</Component>
|
</Component>
|
||||||
|
|||||||
@@ -17,73 +17,66 @@
|
|||||||
<?endforeach?>
|
<?endforeach?>
|
||||||
|
|
||||||
<Component Id="Module_ImageResizer_Registry" Win64="yes">
|
<Component Id="Module_ImageResizer_Registry" Win64="yes">
|
||||||
<RegistryKey Root="HKCU" Key="Software\Classes\CLSID\{51B4D7E5-7568-4234-B4BB-47FB3C016A69}\InprocServer32">
|
<RegistryKey Root="HKLM" Key="Software\Classes\CLSID\{51B4D7E5-7568-4234-B4BB-47FB3C016A69}\InprocServer32">
|
||||||
<RegistryValue Value="[ImageResizerInstallFolder]PowerToys.ImageResizerExt.dll" Type="string" />
|
<RegistryValue Value="[ImageResizerInstallFolder]PowerToys.ImageResizerExt.dll" Type="string" />
|
||||||
<RegistryValue Name="ThreadingModel" Value="Apartment" Type="string" />
|
<RegistryValue Name="ThreadingModel" Value="Apartment" Type="string" />
|
||||||
</RegistryKey>
|
</RegistryKey>
|
||||||
|
|
||||||
<!-- Registry Key for the drag and drop handler -->
|
<RegistryValue Root="HKCR"
|
||||||
<!-- To use later on when we want to install per user.
|
|
||||||
<RegistryValue Root="HKCU"
|
|
||||||
Key="Software\Classes\Directory\ShellEx\DragDropHandlers\ImageResizer"
|
|
||||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
|
||||||
Type="string" />
|
|
||||||
-->
|
|
||||||
<RegistryValue Root="HKCU"
|
|
||||||
Key="SOFTWARE\Classes\Directory\ShellEx\DragDropHandlers\ImageResizer"
|
Key="SOFTWARE\Classes\Directory\ShellEx\DragDropHandlers\ImageResizer"
|
||||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||||
Type="string" />
|
Type="string" />
|
||||||
<!-- Registry Keys for the context menu handler for each of the following image formats: bmp, dib, gif, jfif, jpe, jpeg, jpg, jxr, png, rle, tif, tiff, wdp -->
|
<!-- Registry Keys for the context menu handler for each of the following image formats: bmp, dib, gif, jfif, jpe, jpeg, jpg, jxr, png, rle, tif, tiff, wdp -->
|
||||||
<RegistryValue Root="HKCU"
|
<RegistryValue Root="HKCR"
|
||||||
Key="SOFTWARE\Classes\SystemFileAssociations\.bmp\ShellEx\ContextMenuHandlers\ImageResizer"
|
Key="SystemFileAssociations\.bmp\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||||
Type="string" />
|
Type="string" />
|
||||||
<RegistryValue Root="HKCU"
|
<RegistryValue Root="HKCR"
|
||||||
Key="SOFTWARE\Classes\SystemFileAssociations\.dib\ShellEx\ContextMenuHandlers\ImageResizer"
|
Key="SystemFileAssociations\.dib\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||||
Type="string" />
|
Type="string" />
|
||||||
<RegistryValue Root="HKCU"
|
<RegistryValue Root="HKCR"
|
||||||
Key="SOFTWARE\Classes\SystemFileAssociations\.gif\ShellEx\ContextMenuHandlers\ImageResizer"
|
Key="SystemFileAssociations\.gif\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||||
Type="string" />
|
Type="string" />
|
||||||
<RegistryValue Root="HKCU"
|
<RegistryValue Root="HKCR"
|
||||||
Key="SOFTWARE\Classes\SystemFileAssociations\.jfif\ShellEx\ContextMenuHandlers\ImageResizer"
|
Key="SystemFileAssociations\.jfif\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||||
Type="string" />
|
Type="string" />
|
||||||
<RegistryValue Root="HKCU"
|
<RegistryValue Root="HKCR"
|
||||||
Key="SOFTWARE\Classes\SystemFileAssociations\.jpe\ShellEx\ContextMenuHandlers\ImageResizer"
|
Key="SystemFileAssociations\.jpe\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||||
Type="string" />
|
Type="string" />
|
||||||
<RegistryValue Root="HKCU"
|
<RegistryValue Root="HKCR"
|
||||||
Key="SOFTWARE\Classes\SystemFileAssociations\.jpeg\ShellEx\ContextMenuHandlers\ImageResizer"
|
Key="SystemFileAssociations\.jpeg\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||||
Type="string" />
|
Type="string" />
|
||||||
<RegistryValue Root="HKCU"
|
<RegistryValue Root="HKCR"
|
||||||
Key="SOFTWARE\Classes\SystemFileAssociations\.jpg\ShellEx\ContextMenuHandlers\ImageResizer"
|
Key="SystemFileAssociations\.jpg\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||||
Type="string" />
|
Type="string" />
|
||||||
<RegistryValue Root="HKCU"
|
<RegistryValue Root="HKCR"
|
||||||
Key="SOFTWARE\Classes\SystemFileAssociations\.jxr\ShellEx\ContextMenuHandlers\ImageResizer"
|
Key="SystemFileAssociations\.jxr\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||||
Type="string" />
|
Type="string" />
|
||||||
<RegistryValue Root="HKCU"
|
<RegistryValue Root="HKCR"
|
||||||
Key="SOFTWARE\Classes\SystemFileAssociations\.png\ShellEx\ContextMenuHandlers\ImageResizer"
|
Key="SystemFileAssociations\.png\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||||
Type="string" />
|
Type="string" />
|
||||||
<RegistryValue Root="HKCU"
|
<RegistryValue Root="HKCR"
|
||||||
Key="SOFTWARE\Classes\SystemFileAssociations\.rle\ShellEx\ContextMenuHandlers\ImageResizer"
|
Key="SystemFileAssociations\.rle\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||||
Type="string" />
|
Type="string" />
|
||||||
<RegistryValue Root="HKCU"
|
<RegistryValue Root="HKCR"
|
||||||
Key="SOFTWARE\Classes\SystemFileAssociations\.tif\ShellEx\ContextMenuHandlers\ImageResizer"
|
Key="SystemFileAssociations\.tif\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||||
Type="string" />
|
Type="string" />
|
||||||
<RegistryValue Root="HKCU"
|
<RegistryValue Root="HKCR"
|
||||||
Key="SOFTWARE\Classes\SystemFileAssociations\.tiff\ShellEx\ContextMenuHandlers\ImageResizer"
|
Key="SystemFileAssociations\.tiff\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||||
Type="string" />
|
Type="string" />
|
||||||
<RegistryValue Root="HKCU"
|
<RegistryValue Root="HKCR"
|
||||||
Key="SOFTWARE\Classes\SystemFileAssociations\.wdp\ShellEx\ContextMenuHandlers\ImageResizer"
|
Key="SystemFileAssociations\.wdp\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||||
Type="string" />
|
Type="string" />
|
||||||
</Component>
|
</Component>
|
||||||
|
|||||||
@@ -19,13 +19,13 @@
|
|||||||
<?endforeach?>
|
<?endforeach?>
|
||||||
<!-- !Warning! Make sure to change Component Guid if you update something here -->
|
<!-- !Warning! Make sure to change Component Guid if you update something here -->
|
||||||
<Component Id="Module_PowerRename" Guid="40D43079-240E-402D-8CE8-571BFFA71175" Win64="yes">
|
<Component Id="Module_PowerRename" Guid="40D43079-240E-402D-8CE8-571BFFA71175" Win64="yes">
|
||||||
<RegistryKey Root="HKCU" Key="Software\Classes\CLSID\{0440049F-D1DC-4E46-B27B-98393D79486B}">
|
<RegistryKey Root="HKLM" Key="Software\Classes\CLSID\{0440049F-D1DC-4E46-B27B-98393D79486B}">
|
||||||
<RegistryValue Type="string" Value="PowerRename Shell Extension" />
|
<RegistryValue Type="string" Value="PowerRename Shell Extension" />
|
||||||
<RegistryValue Type="string" Name="ContextMenuOptIn" Value="" />
|
<RegistryValue Type="string" Name="ContextMenuOptIn" Value="" />
|
||||||
<RegistryValue Type="string" Key="InprocServer32" Value="[PowerRenameInstallFolder]PowerToys.PowerRenameExt.dll" />
|
<RegistryValue Type="string" Key="InprocServer32" Value="[PowerRenameInstallFolder]PowerToys.PowerRenameExt.dll" />
|
||||||
<RegistryValue Type="string" Key="InprocServer32" Name="ThreadingModel" Value="Apartment" />
|
<RegistryValue Type="string" Key="InprocServer32" Name="ThreadingModel" Value="Apartment" />
|
||||||
</RegistryKey>
|
</RegistryKey>
|
||||||
<RegistryKey Root="HKCU" Key="SOFTWARE\Classes\AllFileSystemObjects\ShellEx\ContextMenuHandlers\PowerRenameExt">
|
<RegistryKey Root="HKLM" Key="SOFTWARE\Classes\AllFileSystemObjects\ShellEx\ContextMenuHandlers\PowerRenameExt">
|
||||||
<RegistryValue Type="string" Value="{0440049F-D1DC-4E46-B27B-98393D79486B}"/>
|
<RegistryValue Type="string" Value="{0440049F-D1DC-4E46-B27B-98393D79486B}"/>
|
||||||
</RegistryKey>
|
</RegistryKey>
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
<ComponentGroup Id="RunComponentGroup">
|
<ComponentGroup Id="RunComponentGroup">
|
||||||
<Component Id="launcherShortcutComponent" Directory="LauncherInstallFolder" >
|
<Component Id="launcherShortcutComponent" Directory="LauncherInstallFolder" >
|
||||||
<!-- Toast Notification AUMID -->
|
<!-- Toast Notification AUMID -->
|
||||||
<RegistryKey Root="HKCU" Key="SOFTWARE\Classes\AppUserModelId\PowerToysRun">
|
<RegistryKey Root="HKLM" Key="SOFTWARE\Classes\AppUserModelId\PowerToysRun">
|
||||||
<RegistryValue Type="string" Name="DisplayName" Value="PowerToys Run" />
|
<RegistryValue Type="string" Name="DisplayName" Value="PowerToys Run" />
|
||||||
<RegistryValue Type="string" Name="IconUri" Value="[LauncherImagesFolder]RunAsset.ico" />
|
<RegistryValue Type="string" Name="IconUri" Value="[LauncherImagesFolder]RunAsset.ico" />
|
||||||
</RegistryKey>
|
</RegistryKey>
|
||||||
|
|||||||
@@ -118,13 +118,13 @@ public:
|
|||||||
|
|
||||||
LRESULT WndProc(HWND, UINT, WPARAM, LPARAM) noexcept;
|
LRESULT WndProc(HWND, UINT, WPARAM, LPARAM) noexcept;
|
||||||
void OnDisplayChange(DisplayChangeType changeType) noexcept;
|
void OnDisplayChange(DisplayChangeType changeType) noexcept;
|
||||||
void AddWorkArea(HMONITOR monitor, const FancyZonesDataTypes::WorkAreaId& id) noexcept;
|
void AddWorkArea(HMONITOR monitor, const FancyZonesDataTypes::WorkAreaId& id, bool updateWindowsPositions) noexcept;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static LRESULT CALLBACK s_WndProc(HWND, UINT, WPARAM, LPARAM) noexcept;
|
static LRESULT CALLBACK s_WndProc(HWND, UINT, WPARAM, LPARAM) noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void UpdateWorkAreas() noexcept;
|
void UpdateWorkAreas(bool updateWindowPositions) noexcept;
|
||||||
void CycleWindows(bool reverse) noexcept;
|
void CycleWindows(bool reverse) noexcept;
|
||||||
bool OnSnapHotkeyBasedOnZoneNumber(HWND window, DWORD vkCode) noexcept;
|
bool OnSnapHotkeyBasedOnZoneNumber(HWND window, DWORD vkCode) noexcept;
|
||||||
bool OnSnapHotkeyBasedOnPosition(HWND window, DWORD vkCode) noexcept;
|
bool OnSnapHotkeyBasedOnPosition(HWND window, DWORD vkCode) noexcept;
|
||||||
@@ -139,8 +139,7 @@ private:
|
|||||||
void MoveWindowIntoZone(HWND window, WorkArea* const workArea, const ZoneIndexSet& zoneIndexSet) noexcept;
|
void MoveWindowIntoZone(HWND window, WorkArea* const workArea, const ZoneIndexSet& zoneIndexSet) noexcept;
|
||||||
bool MoveToAppLastZone(HWND window, HMONITOR active, HMONITOR primary) noexcept;
|
bool MoveToAppLastZone(HWND window, HMONITOR active, HMONITOR primary) noexcept;
|
||||||
|
|
||||||
void OnEditorExitEvent() noexcept;
|
void UpdateActiveLayouts() noexcept;
|
||||||
void UpdateZoneSets() noexcept;
|
|
||||||
bool ShouldProcessSnapHotkey(DWORD vkCode) noexcept;
|
bool ShouldProcessSnapHotkey(DWORD vkCode) noexcept;
|
||||||
void ApplyQuickLayout(int key) noexcept;
|
void ApplyQuickLayout(int key) noexcept;
|
||||||
void FlashZones() noexcept;
|
void FlashZones() noexcept;
|
||||||
@@ -618,15 +617,8 @@ LRESULT FancyZones::WndProc(HWND window, UINT message, WPARAM wparam, LPARAM lpa
|
|||||||
}
|
}
|
||||||
else if (message == WM_PRIV_EDITOR)
|
else if (message == WM_PRIV_EDITOR)
|
||||||
{
|
{
|
||||||
if (lparam == static_cast<LPARAM>(EditorExitKind::Exit))
|
// Clean up the event either way
|
||||||
{
|
m_terminateEditorEvent.release();
|
||||||
OnEditorExitEvent();
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
// Clean up the event either way
|
|
||||||
m_terminateEditorEvent.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (message == WM_PRIV_MOVESIZESTART)
|
else if (message == WM_PRIV_MOVESIZESTART)
|
||||||
{
|
{
|
||||||
@@ -667,7 +659,7 @@ LRESULT FancyZones::WndProc(HWND window, UINT message, WPARAM wparam, LPARAM lpa
|
|||||||
else if (message == WM_PRIV_APPLIED_LAYOUTS_FILE_UPDATE)
|
else if (message == WM_PRIV_APPLIED_LAYOUTS_FILE_UPDATE)
|
||||||
{
|
{
|
||||||
AppliedLayouts::instance().LoadData();
|
AppliedLayouts::instance().LoadData();
|
||||||
UpdateZoneSets();
|
UpdateActiveLayouts();
|
||||||
}
|
}
|
||||||
else if (message == WM_PRIV_DEFAULT_LAYOUTS_FILE_UPDATE)
|
else if (message == WM_PRIV_DEFAULT_LAYOUTS_FILE_UPDATE)
|
||||||
{
|
{
|
||||||
@@ -711,10 +703,12 @@ void FancyZones::OnDisplayChange(DisplayChangeType changeType) noexcept
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateWorkAreas();
|
bool updateWindowsPositionsOnResolutionChange = FancyZonesSettings::settings().displayChange_moveWindows && changeType == DisplayChangeType::DisplayChange;
|
||||||
|
bool updateWindowsPositionsOnStart = FancyZonesSettings::settings().zoneSetChange_moveWindows && changeType == DisplayChangeType::Initialization;
|
||||||
|
UpdateWorkAreas(updateWindowsPositionsOnResolutionChange || updateWindowsPositionsOnStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FancyZones::AddWorkArea(HMONITOR monitor, const FancyZonesDataTypes::WorkAreaId& id) noexcept
|
void FancyZones::AddWorkArea(HMONITOR monitor, const FancyZonesDataTypes::WorkAreaId& id, bool updateWindowsPositions) noexcept
|
||||||
{
|
{
|
||||||
wil::unique_cotaskmem_string virtualDesktopIdStr;
|
wil::unique_cotaskmem_string virtualDesktopIdStr;
|
||||||
if (!SUCCEEDED(StringFromCLSID(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), &virtualDesktopIdStr)))
|
if (!SUCCEEDED(StringFromCLSID(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), &virtualDesktopIdStr)))
|
||||||
@@ -722,13 +716,6 @@ void FancyZones::AddWorkArea(HMONITOR monitor, const FancyZonesDataTypes::WorkAr
|
|||||||
Logger::debug(L"Add new work area on virtual desktop {}", virtualDesktopIdStr.get());
|
Logger::debug(L"Add new work area on virtual desktop {}", virtualDesktopIdStr.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
FancyZonesDataTypes::WorkAreaId parentId{};
|
|
||||||
auto parentArea = m_workAreaHandler.GetWorkArea(monitor);
|
|
||||||
if (parentArea)
|
|
||||||
{
|
|
||||||
parentId = parentArea->UniqueId();
|
|
||||||
}
|
|
||||||
|
|
||||||
FancyZonesUtils::Rect rect{};
|
FancyZonesUtils::Rect rect{};
|
||||||
if (monitor)
|
if (monitor)
|
||||||
{
|
{
|
||||||
@@ -739,11 +726,15 @@ void FancyZones::AddWorkArea(HMONITOR monitor, const FancyZonesDataTypes::WorkAr
|
|||||||
rect = FancyZonesUtils::GetAllMonitorsCombinedRect<&MONITORINFO::rcWork>();
|
rect = FancyZonesUtils::GetAllMonitorsCombinedRect<&MONITORINFO::rcWork>();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto workArea = WorkArea::Create(m_hinstance, id, parentId, rect);
|
auto workArea = WorkArea::Create(m_hinstance, id, m_workAreaHandler.GetParent(monitor), rect);
|
||||||
if (workArea)
|
if (workArea)
|
||||||
{
|
{
|
||||||
|
if (updateWindowsPositions)
|
||||||
|
{
|
||||||
|
workArea->UpdateWindowPositions();
|
||||||
|
}
|
||||||
|
|
||||||
m_workAreaHandler.AddWorkArea(monitor, std::move(workArea));
|
m_workAreaHandler.AddWorkArea(monitor, std::move(workArea));
|
||||||
AppliedLayouts::instance().SaveData();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -761,8 +752,9 @@ LRESULT CALLBACK FancyZones::s_WndProc(HWND window, UINT message, WPARAM wparam,
|
|||||||
DefWindowProc(window, message, wparam, lparam);
|
DefWindowProc(window, message, wparam, lparam);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FancyZones::UpdateWorkAreas() noexcept
|
void FancyZones::UpdateWorkAreas(bool updateWindowPositions) noexcept
|
||||||
{
|
{
|
||||||
|
m_workAreaHandler.SaveParentIds();
|
||||||
m_workAreaHandler.Clear();
|
m_workAreaHandler.Clear();
|
||||||
|
|
||||||
if (FancyZonesSettings::settings().spanZonesAcrossMonitors)
|
if (FancyZonesSettings::settings().spanZonesAcrossMonitors)
|
||||||
@@ -771,7 +763,7 @@ void FancyZones::UpdateWorkAreas() noexcept
|
|||||||
workAreaId.virtualDesktopId = VirtualDesktop::instance().GetCurrentVirtualDesktopId();
|
workAreaId.virtualDesktopId = VirtualDesktop::instance().GetCurrentVirtualDesktopId();
|
||||||
workAreaId.monitorId = { .deviceId = { .id = ZonedWindowProperties::MultiMonitorName, .instanceId = ZonedWindowProperties::MultiMonitorInstance } };
|
workAreaId.monitorId = { .deviceId = { .id = ZonedWindowProperties::MultiMonitorName, .instanceId = ZonedWindowProperties::MultiMonitorInstance } };
|
||||||
|
|
||||||
AddWorkArea(nullptr, workAreaId);
|
AddWorkArea(nullptr, workAreaId, updateWindowPositions);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -782,7 +774,7 @@ void FancyZones::UpdateWorkAreas() noexcept
|
|||||||
workAreaId.virtualDesktopId = VirtualDesktop::instance().GetCurrentVirtualDesktopId();
|
workAreaId.virtualDesktopId = VirtualDesktop::instance().GetCurrentVirtualDesktopId();
|
||||||
workAreaId.monitorId = monitor;
|
workAreaId.monitorId = monitor;
|
||||||
|
|
||||||
AddWorkArea(monitor.monitor, workAreaId);
|
AddWorkArea(monitor.monitor, workAreaId, updateWindowPositions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -896,7 +888,7 @@ bool FancyZones::OnSnapHotkeyBasedOnPosition(HWND window, DWORD vkCode) noexcept
|
|||||||
|
|
||||||
// If that didn't work, extract zones from all other monitors and target one of them
|
// If that didn't work, extract zones from all other monitors and target one of them
|
||||||
std::vector<RECT> zoneRects;
|
std::vector<RECT> zoneRects;
|
||||||
std::vector<std::pair<ZoneIndex, std::shared_ptr<WorkArea>>> zoneRectsInfo;
|
std::vector<std::pair<ZoneIndex, WorkArea*>> zoneRectsInfo;
|
||||||
RECT currentMonitorRect{ .top = 0, .bottom = -1 };
|
RECT currentMonitorRect{ .top = 0, .bottom = -1 };
|
||||||
|
|
||||||
for (const auto& [monitor, monitorRect] : allMonitors)
|
for (const auto& [monitor, monitorRect] : allMonitors)
|
||||||
@@ -1117,19 +1109,18 @@ void FancyZones::SettingsUpdate(SettingId id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FancyZones::OnEditorExitEvent() noexcept
|
void FancyZones::UpdateActiveLayouts() noexcept
|
||||||
{
|
|
||||||
// Collect information about changes in zone layout after editor exited.
|
|
||||||
UpdateZoneSets();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FancyZones::UpdateZoneSets() noexcept
|
|
||||||
{
|
{
|
||||||
for (const auto& [_, workArea] : m_workAreaHandler.GetAllWorkAreas())
|
for (const auto& [_, workArea] : m_workAreaHandler.GetAllWorkAreas())
|
||||||
{
|
{
|
||||||
if (workArea)
|
if (workArea)
|
||||||
{
|
{
|
||||||
workArea->UpdateActiveZoneSet();
|
workArea->UpdateActiveZoneSet();
|
||||||
|
|
||||||
|
if (FancyZonesSettings::settings().zoneSetChange_moveWindows)
|
||||||
|
{
|
||||||
|
workArea->UpdateWindowPositions();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1197,7 +1188,7 @@ void FancyZones::ApplyQuickLayout(int key) noexcept
|
|||||||
{
|
{
|
||||||
AppliedLayouts::instance().ApplyLayout(workArea->UniqueId(), layout.value());
|
AppliedLayouts::instance().ApplyLayout(workArea->UniqueId(), layout.value());
|
||||||
AppliedLayouts::instance().SaveData();
|
AppliedLayouts::instance().SaveData();
|
||||||
UpdateZoneSets();
|
UpdateActiveLayouts();
|
||||||
FlashZones();
|
FlashZones();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,6 +69,11 @@ void LayoutAssignedWindows::Dismiss(HWND window)
|
|||||||
FancyZonesWindowProperties::SetTabSortKeyWithinZone(window, std::nullopt);
|
FancyZonesWindowProperties::SetTabSortKeyWithinZone(window, std::nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::map<HWND, ZoneIndexSet> LayoutAssignedWindows::SnappedWindows() const noexcept
|
||||||
|
{
|
||||||
|
return m_windowIndexSet;
|
||||||
|
}
|
||||||
|
|
||||||
ZoneIndexSet LayoutAssignedWindows::GetZoneIndexSetFromWindow(HWND window) const noexcept
|
ZoneIndexSet LayoutAssignedWindows::GetZoneIndexSetFromWindow(HWND window) const noexcept
|
||||||
{
|
{
|
||||||
auto it = m_windowIndexSet.find(window);
|
auto it = m_windowIndexSet.find(window);
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ public :
|
|||||||
void Extend(HWND window, const ZoneIndexSet& zones);
|
void Extend(HWND window, const ZoneIndexSet& zones);
|
||||||
void Dismiss(HWND window);
|
void Dismiss(HWND window);
|
||||||
|
|
||||||
|
std::map<HWND, ZoneIndexSet> SnappedWindows() const noexcept;
|
||||||
ZoneIndexSet GetZoneIndexSetFromWindow(HWND window) const noexcept;
|
ZoneIndexSet GetZoneIndexSetFromWindow(HWND window) const noexcept;
|
||||||
bool IsZoneEmpty(ZoneIndex zoneIndex) const noexcept;
|
bool IsZoneEmpty(ZoneIndex zoneIndex) const noexcept;
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,28 @@ void MonitorWorkAreaMap::AddWorkArea(HMONITOR monitor, std::unique_ptr<WorkArea>
|
|||||||
m_workAreaMap.insert({ monitor, std::move(workArea) });
|
m_workAreaMap.insert({ monitor, std::move(workArea) });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FancyZonesDataTypes::WorkAreaId MonitorWorkAreaMap::GetParent(HMONITOR monitor) const
|
||||||
|
{
|
||||||
|
if (m_workAreaParents.contains(monitor))
|
||||||
|
{
|
||||||
|
return m_workAreaParents.at(monitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FancyZonesDataTypes::WorkAreaId{};
|
||||||
|
}
|
||||||
|
|
||||||
|
void MonitorWorkAreaMap::SaveParentIds()
|
||||||
|
{
|
||||||
|
m_workAreaParents.clear();
|
||||||
|
for (const auto& [monitor, workArea] : m_workAreaMap)
|
||||||
|
{
|
||||||
|
if (workArea)
|
||||||
|
{
|
||||||
|
m_workAreaParents.insert({ monitor, workArea->UniqueId() });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MonitorWorkAreaMap::Clear() noexcept
|
void MonitorWorkAreaMap::Clear() noexcept
|
||||||
{
|
{
|
||||||
m_workAreaMap.clear();
|
m_workAreaMap.clear();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "GuidUtils.h"
|
#include "GuidUtils.h"
|
||||||
|
#include <FancyZonesLib/FancyZonesDataTypes.h>
|
||||||
|
|
||||||
class WorkArea;
|
class WorkArea;
|
||||||
|
|
||||||
@@ -48,6 +49,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
void AddWorkArea(HMONITOR monitor, std::unique_ptr<WorkArea> workArea);
|
void AddWorkArea(HMONITOR monitor, std::unique_ptr<WorkArea> workArea);
|
||||||
|
|
||||||
|
FancyZonesDataTypes::WorkAreaId GetParent(HMONITOR monitor) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saving current work area IDs as parents for later use.
|
||||||
|
*/
|
||||||
|
void SaveParentIds();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear all persisted work area related data.
|
* Clear all persisted work area related data.
|
||||||
*/
|
*/
|
||||||
@@ -55,4 +63,5 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::unordered_map<HMONITOR, std::unique_ptr<WorkArea>> m_workAreaMap;
|
std::unordered_map<HMONITOR, std::unique_ptr<WorkArea>> m_workAreaMap;
|
||||||
|
std::unordered_map<HMONITOR, FancyZonesDataTypes::WorkAreaId> m_workAreaParents{};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -56,13 +56,15 @@ bool WindowDrag::MoveSizeStart(HMONITOR monitor, bool isSnapping)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSnapping)
|
m_currentWorkArea = iter->second.get();
|
||||||
{
|
|
||||||
m_currentWorkArea = iter->second.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
SwitchSnappingMode(isSnapping);
|
SwitchSnappingMode(isSnapping);
|
||||||
|
|
||||||
|
if (m_currentWorkArea)
|
||||||
|
{
|
||||||
|
m_currentWorkArea->UnsnapWindow(m_window);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,7 +171,6 @@ void WindowDrag::SwitchSnappingMode(bool isSnapping)
|
|||||||
|
|
||||||
if (m_currentWorkArea)
|
if (m_currentWorkArea)
|
||||||
{
|
{
|
||||||
m_currentWorkArea->UnsnapWindow(m_window);
|
|
||||||
Trace::WorkArea::MoveOrResizeStarted(m_currentWorkArea->GetLayout().get(), m_currentWorkArea->GetLayoutWindows().get());
|
Trace::WorkArea::MoveOrResizeStarted(m_currentWorkArea->GetLayout().get(), m_currentWorkArea->GetLayoutWindows().get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -213,22 +214,30 @@ void WindowDrag::SetWindowTransparency()
|
|||||||
if (!SetLayeredWindowAttributes(m_window, 0, (255 * 50) / 100, LWA_ALPHA))
|
if (!SetLayeredWindowAttributes(m_window, 0, (255 * 50) / 100, LWA_ALPHA))
|
||||||
{
|
{
|
||||||
Logger::error(L"Window transparency: SetLayeredWindowAttributes failed, {}", get_last_error_or_default(GetLastError()));
|
Logger::error(L"Window transparency: SetLayeredWindowAttributes failed, {}", get_last_error_or_default(GetLastError()));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_windowProperties.transparencySet = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowDrag::ResetWindowTransparency()
|
void WindowDrag::ResetWindowTransparency()
|
||||||
{
|
{
|
||||||
if (FancyZonesSettings::settings().makeDraggedWindowTransparent)
|
if (FancyZonesSettings::settings().makeDraggedWindowTransparent && m_windowProperties.transparencySet)
|
||||||
{
|
{
|
||||||
|
bool reset = true;
|
||||||
if (!SetLayeredWindowAttributes(m_window, m_windowProperties.crKey, m_windowProperties.alpha, m_windowProperties.dwFlags))
|
if (!SetLayeredWindowAttributes(m_window, m_windowProperties.crKey, m_windowProperties.alpha, m_windowProperties.dwFlags))
|
||||||
{
|
{
|
||||||
Logger::error(L"Window transparency: SetLayeredWindowAttributes failed");
|
Logger::error(L"Window transparency: SetLayeredWindowAttributes failed, {}", get_last_error_or_default(GetLastError()));
|
||||||
|
reset = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SetWindowLong(m_window, GWL_EXSTYLE, m_windowProperties.exstyle) == 0)
|
if (SetWindowLong(m_window, GWL_EXSTYLE, m_windowProperties.exstyle) == 0)
|
||||||
{
|
{
|
||||||
Logger::error(L"Window transparency: SetWindowLong failed, {}", get_last_error_or_default(GetLastError()));
|
Logger::error(L"Window transparency: SetWindowLong failed, {}", get_last_error_or_default(GetLastError()));
|
||||||
|
reset = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_windowProperties.transparencySet = !reset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ private:
|
|||||||
COLORREF crKey = RGB(0, 0, 0);
|
COLORREF crKey = RGB(0, 0, 0);
|
||||||
DWORD dwFlags = 0;
|
DWORD dwFlags = 0;
|
||||||
BYTE alpha = 0;
|
BYTE alpha = 0;
|
||||||
|
bool transparencySet{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
const HWND m_window;
|
const HWND m_window;
|
||||||
|
|||||||
@@ -144,8 +144,11 @@ void WorkArea::MoveWindowIntoZoneByIndexSet(HWND window, const ZoneIndexSet& ind
|
|||||||
if (updatePosition)
|
if (updatePosition)
|
||||||
{
|
{
|
||||||
const auto rect = m_layout->GetCombinedZonesRect(indexSet);
|
const auto rect = m_layout->GetCombinedZonesRect(indexSet);
|
||||||
const auto adjustedRect = FancyZonesWindowUtils::AdjustRectForSizeWindowToRect(window, rect, m_window);
|
if (rect.bottom - rect.top > 0 && rect.right - rect.left > 0)
|
||||||
FancyZonesWindowUtils::SizeWindowToRect(window, adjustedRect);
|
{
|
||||||
|
const auto adjustedRect = FancyZonesWindowUtils::AdjustRectForSizeWindowToRect(window, rect, m_window);
|
||||||
|
FancyZonesWindowUtils::SizeWindowToRect(window, adjustedRect);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SnapWindow(window, indexSet);
|
SnapWindow(window, indexSet);
|
||||||
@@ -351,9 +354,7 @@ bool WorkArea::ExtendWindowByDirectionAndPosition(HWND window, DWORD vkCode)
|
|||||||
const auto adjustedRect = FancyZonesWindowUtils::AdjustRectForSizeWindowToRect(window, rect, m_window);
|
const auto adjustedRect = FancyZonesWindowUtils::AdjustRectForSizeWindowToRect(window, rect, m_window);
|
||||||
FancyZonesWindowUtils::SizeWindowToRect(window, adjustedRect);
|
FancyZonesWindowUtils::SizeWindowToRect(window, adjustedRect);
|
||||||
|
|
||||||
m_layoutWindows->Extend(window, resultIndexSet);
|
SnapWindow(window, resultIndexSet, true);
|
||||||
|
|
||||||
SnapWindow(window, resultIndexSet);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -361,15 +362,22 @@ bool WorkArea::ExtendWindowByDirectionAndPosition(HWND window, DWORD vkCode)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorkArea::SnapWindow(HWND window, const ZoneIndexSet& zones)
|
void WorkArea::SnapWindow(HWND window, const ZoneIndexSet& zones, bool extend)
|
||||||
{
|
{
|
||||||
if (!m_layoutWindows || !m_layout)
|
if (!m_layoutWindows || !m_layout)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_layoutWindows->Assign(window, zones);
|
if (extend)
|
||||||
|
{
|
||||||
|
m_layoutWindows->Extend(window, zones);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_layoutWindows->Assign(window, zones);
|
||||||
|
}
|
||||||
|
|
||||||
auto guidStr = FancyZonesUtils::GuidToString(m_layout->Id());
|
auto guidStr = FancyZonesUtils::GuidToString(m_layout->Id());
|
||||||
if (guidStr.has_value())
|
if (guidStr.has_value())
|
||||||
{
|
{
|
||||||
@@ -462,6 +470,20 @@ void WorkArea::UpdateActiveZoneSet()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WorkArea::UpdateWindowPositions()
|
||||||
|
{
|
||||||
|
if (!m_layoutWindows)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& snappedWindows = m_layoutWindows->SnappedWindows();
|
||||||
|
for (const auto& [window, zones] : snappedWindows)
|
||||||
|
{
|
||||||
|
MoveWindowIntoZoneByIndexSet(window, zones, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void WorkArea::CycleWindows(HWND window, bool reverse)
|
void WorkArea::CycleWindows(HWND window, bool reverse)
|
||||||
{
|
{
|
||||||
if (m_layoutWindows)
|
if (m_layoutWindows)
|
||||||
@@ -507,8 +529,7 @@ void WorkArea::InitLayout(const FancyZonesDataTypes::WorkAreaId& parentUniqueId)
|
|||||||
|
|
||||||
void WorkArea::InitSnappedWindows()
|
void WorkArea::InitSnappedWindows()
|
||||||
{
|
{
|
||||||
static bool updatePositionOnceOnStartFlag = true;
|
Logger::info(L"Init work area windows");
|
||||||
Logger::info(L"Init work area windows, update positions = {}", updatePositionOnceOnStartFlag);
|
|
||||||
|
|
||||||
for (const auto& window : VirtualDesktop::instance().GetWindowsFromCurrentDesktop())
|
for (const auto& window : VirtualDesktop::instance().GetWindowsFromCurrentDesktop())
|
||||||
{
|
{
|
||||||
@@ -520,19 +541,17 @@ void WorkArea::InitSnappedWindows()
|
|||||||
|
|
||||||
if (!m_uniqueId.monitorId.monitor) // one work area across monitors
|
if (!m_uniqueId.monitorId.monitor) // one work area across monitors
|
||||||
{
|
{
|
||||||
MoveWindowIntoZoneByIndexSet(window, zoneIndexSet, updatePositionOnceOnStartFlag);
|
MoveWindowIntoZoneByIndexSet(window, zoneIndexSet, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const auto monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONULL);
|
const auto monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONULL);
|
||||||
if (monitor && m_uniqueId.monitorId.monitor == monitor)
|
if (monitor && m_uniqueId.monitorId.monitor == monitor)
|
||||||
{
|
{
|
||||||
MoveWindowIntoZoneByIndexSet(window, zoneIndexSet, updatePositionOnceOnStartFlag);
|
MoveWindowIntoZoneByIndexSet(window, zoneIndexSet, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updatePositionOnceOnStartFlag = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorkArea::CalculateZoneSet()
|
void WorkArea::CalculateZoneSet()
|
||||||
|
|||||||
@@ -51,10 +51,11 @@ public:
|
|||||||
bool MoveWindowIntoZoneByDirectionAndPosition(HWND window, DWORD vkCode, bool cycle);
|
bool MoveWindowIntoZoneByDirectionAndPosition(HWND window, DWORD vkCode, bool cycle);
|
||||||
bool ExtendWindowByDirectionAndPosition(HWND window, DWORD vkCode);
|
bool ExtendWindowByDirectionAndPosition(HWND window, DWORD vkCode);
|
||||||
|
|
||||||
void SnapWindow(HWND window, const ZoneIndexSet& zones);
|
void SnapWindow(HWND window, const ZoneIndexSet& zones, bool extend = false);
|
||||||
void UnsnapWindow(HWND window);
|
void UnsnapWindow(HWND window);
|
||||||
|
|
||||||
void UpdateActiveZoneSet();
|
void UpdateActiveZoneSet();
|
||||||
|
void UpdateWindowPositions();
|
||||||
|
|
||||||
void ShowZonesOverlay(const ZoneIndexSet& highlight, HWND draggedWindow = nullptr);
|
void ShowZonesOverlay(const ZoneIndexSet& highlight, HWND draggedWindow = nullptr);
|
||||||
void HideZonesOverlay();
|
void HideZonesOverlay();
|
||||||
|
|||||||
@@ -180,10 +180,17 @@ namespace Wox.Infrastructure.Image
|
|||||||
image = WindowsThumbnailProvider.GetThumbnail(path, Constant.ThumbnailSize, Constant.ThumbnailSize, ThumbnailOptions.ThumbnailOnly);
|
image = WindowsThumbnailProvider.GetThumbnail(path, Constant.ThumbnailSize, Constant.ThumbnailSize, ThumbnailOptions.ThumbnailOnly);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (extension == ".pdf" && WindowsThumbnailProvider.DoesPdfUseAcrobatAsProvider())
|
||||||
|
{
|
||||||
|
// The PDF thumbnail provider from Adobe Reader and Acrobat Pro lets crash PT Run with an Dispatcher exception. (https://github.com/microsoft/PowerToys/issues/18166)
|
||||||
|
// To not run into the crash, we only request the icon of PDF files if the PDF thumbnail handler is set to Adobe Reader/Acrobat Pro.
|
||||||
|
type = ImageType.File;
|
||||||
|
image = WindowsThumbnailProvider.GetThumbnail(path, Constant.ThumbnailSize, Constant.ThumbnailSize, ThumbnailOptions.IconOnly);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
type = ImageType.File;
|
type = ImageType.File;
|
||||||
image = WindowsThumbnailProvider.GetThumbnail(path, Constant.ThumbnailSize, Constant.ThumbnailSize, ThumbnailOptions.None);
|
image = WindowsThumbnailProvider.GetThumbnail(path, Constant.ThumbnailSize, Constant.ThumbnailSize, ThumbnailOptions.RESIZETOFIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -4,17 +4,20 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO.Abstractions;
|
using System.IO.Abstractions;
|
||||||
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Interop;
|
using System.Windows.Interop;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
|
using Microsoft.Win32;
|
||||||
|
using Wox.Plugin.Logger;
|
||||||
|
|
||||||
namespace Wox.Infrastructure.Image
|
namespace Wox.Infrastructure.Image
|
||||||
{
|
{
|
||||||
[Flags]
|
[Flags]
|
||||||
public enum ThumbnailOptions
|
public enum ThumbnailOptions
|
||||||
{
|
{
|
||||||
None = 0x00,
|
RESIZETOFIT = 0x00,
|
||||||
BiggerSizeOk = 0x01,
|
BiggerSizeOk = 0x01,
|
||||||
InMemoryOnly = 0x02,
|
InMemoryOnly = 0x02,
|
||||||
IconOnly = 0x04,
|
IconOnly = 0x04,
|
||||||
@@ -125,5 +128,97 @@ namespace Wox.Infrastructure.Image
|
|||||||
|
|
||||||
throw new InvalidComObjectException($"Error while extracting thumbnail for {fileName}", Marshal.GetExceptionForHR((int)hr));
|
throw new InvalidComObjectException($"Error while extracting thumbnail for {fileName}", Marshal.GetExceptionForHR((int)hr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool logReportedAdobeReaderDetected; // Keep track if Adobe Reader detection has been logged yet.
|
||||||
|
private static bool logReportedErrorInDetectingAdobeReader; // Keep track if we reported an exception while trying to detect Adobe Reader yet.
|
||||||
|
private static bool adobeReaderDetectionLastResult; // The last result when Adobe Reader detection has read the registry.
|
||||||
|
private static DateTime adobeReaderDetectionLastTime; // The last time when Adobe Reader detection has read the registry.
|
||||||
|
|
||||||
|
// We have to evaluate this in real time to not crash, if the user switches to Adobe Reader/Acrobat Pro after starting PT Run.
|
||||||
|
// Adobe registers its thumbnail handler always in "HKCR\Acrobat.Document.*\shellex\{BB2E617C-0920-11d1-9A0B-00C04FC2D6C1}".
|
||||||
|
public static bool DoesPdfUseAcrobatAsProvider()
|
||||||
|
{
|
||||||
|
// If the last run is not more than five seconds ago use its result.
|
||||||
|
// Doing this we minimize the amount of Registry queries, if more than one new PDF file is shown in the results.
|
||||||
|
if ((DateTime.Now - adobeReaderDetectionLastTime).TotalSeconds < 5)
|
||||||
|
{
|
||||||
|
return adobeReaderDetectionLastResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If cache condition is false, then query the registry.
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// First detect if there is a provider other than Adobe. For example PowerToys.
|
||||||
|
// Generic GUIDs used by Explorer to identify the configured provider types: {E357FCCD-A995-4576-B01F-234630154E96} = File thumbnail, {BB2E617C-0920-11d1-9A0B-00C04FC2D6C1} = Image thumbnail.
|
||||||
|
RegistryKey key1 = Registry.ClassesRoot.OpenSubKey(".pdf\\shellex\\{E357FCCD-A995-4576-B01F-234630154E96}", false);
|
||||||
|
string value1 = (string)key1?.GetValue(string.Empty);
|
||||||
|
key1?.Close();
|
||||||
|
RegistryKey key2 = Registry.ClassesRoot.OpenSubKey(".pdf\\shellex\\{BB2E617C-0920-11d1-9A0B-00C04FC2D6C1}", false);
|
||||||
|
string value2 = (string)key2?.GetValue(string.Empty);
|
||||||
|
key2?.Close();
|
||||||
|
if (!string.IsNullOrEmpty(value1) || !string.IsNullOrEmpty(value2))
|
||||||
|
{
|
||||||
|
// A provider other than Adobe is used. (For example the PowerToys PDF Thumbnail provider.)
|
||||||
|
logReportedAdobeReaderDetected = false; // Reset log marker to report when Adobe is reused. (Example: Adobe -> Test PowerToys. -> Back to Adobe.)
|
||||||
|
adobeReaderDetectionLastResult = false;
|
||||||
|
adobeReaderDetectionLastTime = DateTime.Now;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then detect if Adobe is the default PDF application.
|
||||||
|
// The global config can be found under "HKCR\.pdf", but the "UserChoice" key under HKCU has precedence.
|
||||||
|
RegistryKey pdfKeyUser = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\.pdf\\UserChoice", false);
|
||||||
|
string pdfAppUser = (string)pdfKeyUser?.GetValue("ProgId");
|
||||||
|
pdfKeyUser?.Close();
|
||||||
|
RegistryKey pdfKeyGlobal = Registry.ClassesRoot.OpenSubKey(".pdf", false);
|
||||||
|
string pdfAppGlobal = (string)pdfKeyGlobal?.GetValue(string.Empty);
|
||||||
|
pdfKeyGlobal?.Close();
|
||||||
|
string pdfApp = !string.IsNullOrEmpty(pdfAppUser) ? pdfAppUser : pdfAppGlobal; // User choice has precedence.
|
||||||
|
if (string.IsNullOrEmpty(pdfApp) || !pdfApp.StartsWith("Acrobat.Document.", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
// Adobe is not used as PDF application.
|
||||||
|
logReportedAdobeReaderDetected = false; // Reset log marker to report when Adobe is reused. (Example: Adobe -> Test PowerToys. -> Back to Adobe.)
|
||||||
|
adobeReaderDetectionLastResult = false;
|
||||||
|
adobeReaderDetectionLastTime = DateTime.Now;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect if the thumbnail handler from Adobe is disabled.
|
||||||
|
RegistryKey adobeAppKey = Registry.ClassesRoot.OpenSubKey(pdfApp + "\\shellex\\{BB2E617C-0920-11d1-9A0B-00C04FC2D6C1}", false);
|
||||||
|
string adobeAppProvider = (string)adobeAppKey?.GetValue(string.Empty);
|
||||||
|
adobeAppKey?.Close();
|
||||||
|
if (string.IsNullOrEmpty(adobeAppProvider))
|
||||||
|
{
|
||||||
|
// No Adobe handler.
|
||||||
|
logReportedAdobeReaderDetected = false; // Reset log marker to report when Adobe is reused. (Example: Adobe -> Test PowerToys. -> Back to Adobe.)
|
||||||
|
adobeReaderDetectionLastResult = false;
|
||||||
|
adobeReaderDetectionLastTime = DateTime.Now;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Thumbnail handler from Adobe is enabled and used.
|
||||||
|
if (!logReportedAdobeReaderDetected)
|
||||||
|
{
|
||||||
|
logReportedAdobeReaderDetected = true;
|
||||||
|
Log.Info("Adobe Reader / Adobe Acrobat Pro has been detected as the PDF thumbnail provider.", MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
}
|
||||||
|
|
||||||
|
adobeReaderDetectionLastResult = true;
|
||||||
|
adobeReaderDetectionLastTime = DateTime.Now;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (System.Exception ex)
|
||||||
|
{
|
||||||
|
if (!logReportedErrorInDetectingAdobeReader)
|
||||||
|
{
|
||||||
|
logReportedErrorInDetectingAdobeReader = true;
|
||||||
|
Log.Exception("Got an exception while trying to detect Adobe Reader / Adobe Acrobat Pro as PDF thumbnail provider. To prevent PT Run from a Dispatcher crash, we report that Adobe Reader / Adobe Acrobat Pro is used and show only the PDF icon in the results.", ex, MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we fail to detect it, we return that Adobe is used. Otherwise we could run into the Dispatcher crash.
|
||||||
|
// (This only results in showing the icon instead of a thumbnail. It has no other functional impact.)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -159,12 +159,10 @@ namespace Microsoft.PowerToys.ThumbnailHandler.Gcode
|
|||||||
|
|
||||||
using (var reader = new StreamReader(this.Stream))
|
using (var reader = new StreamReader(this.Stream))
|
||||||
{
|
{
|
||||||
using (Bitmap thumbnail = GetThumbnail(reader, cx))
|
Bitmap thumbnail = GetThumbnail(reader, cx);
|
||||||
|
if (thumbnail != null && thumbnail.Size.Width > 0 && thumbnail.Size.Height > 0)
|
||||||
{
|
{
|
||||||
if (thumbnail != null && thumbnail.Size.Width > 0 && thumbnail.Size.Height > 0)
|
return thumbnail;
|
||||||
{
|
|
||||||
return (Bitmap)thumbnail.Clone();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,8 +26,11 @@ namespace Microsoft.PowerToys.ThumbnailHandler.Gcode
|
|||||||
|
|
||||||
_thumbnailProvider = new GcodeThumbnailProvider(filePath);
|
_thumbnailProvider = new GcodeThumbnailProvider(filePath);
|
||||||
Bitmap thumbnail = _thumbnailProvider.GetThumbnail(cx);
|
Bitmap thumbnail = _thumbnailProvider.GetThumbnail(cx);
|
||||||
filePath = filePath.Replace(".gcode", ".bmp");
|
if (thumbnail != null)
|
||||||
thumbnail.Save(filePath, System.Drawing.Imaging.ImageFormat.Bmp);
|
{
|
||||||
|
filePath = filePath.Replace(".gcode", ".bmp");
|
||||||
|
thumbnail.Save(filePath, System.Drawing.Imaging.ImageFormat.Bmp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -159,11 +159,19 @@ IFACEMETHODIMP GcodeThumbnailProvider::GetThumbnail(UINT cx, HBITMAP* phbmp, WTS
|
|||||||
WaitForSingleObject(m_process, INFINITE);
|
WaitForSingleObject(m_process, INFINITE);
|
||||||
std::filesystem::remove(fileName);
|
std::filesystem::remove(fileName);
|
||||||
|
|
||||||
|
|
||||||
std::wstring fileNameBmp = filePath + guid + L".bmp";
|
std::wstring fileNameBmp = filePath + guid + L".bmp";
|
||||||
*phbmp = (HBITMAP)LoadImage(NULL, fileNameBmp.c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
|
if (std::filesystem::exists(fileNameBmp))
|
||||||
*pdwAlpha = WTS_ALPHATYPE::WTSAT_ARGB;
|
{
|
||||||
|
*phbmp = (HBITMAP)LoadImage(NULL, fileNameBmp.c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
|
||||||
std::filesystem::remove(fileNameBmp);
|
*pdwAlpha = WTS_ALPHATYPE::WTSAT_ARGB;
|
||||||
|
std::filesystem::remove(fileNameBmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger::info(L"Bmp file not generated.");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public:
|
|||||||
// IInitializeWithStream
|
// IInitializeWithStream
|
||||||
IFACEMETHODIMP Initialize(IStream* pstream, DWORD grfMode);
|
IFACEMETHODIMP Initialize(IStream* pstream, DWORD grfMode);
|
||||||
|
|
||||||
// IPreviewHandler
|
// IThumbnailProvider
|
||||||
IFACEMETHODIMP GetThumbnail(UINT cx, HBITMAP* phbmp, WTS_ALPHATYPE* pdwAlpha);
|
IFACEMETHODIMP GetThumbnail(UINT cx, HBITMAP* phbmp, WTS_ALPHATYPE* pdwAlpha);
|
||||||
|
|
||||||
GcodeThumbnailProvider();
|
GcodeThumbnailProvider();
|
||||||
|
|||||||
@@ -1,14 +1,8 @@
|
|||||||
// Copyright (c) Microsoft Corporation
|
// Copyright (c) Microsoft Corporation
|
||||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
// See the LICENSE file in the project root for more information.
|
// See the LICENSE file in the project root for more information.
|
||||||
using System;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.IO;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Runtime.InteropServices.ComTypes;
|
|
||||||
using Common.ComInterlop;
|
|
||||||
using Common.Utilities;
|
|
||||||
using Windows.Data.Pdf;
|
using Windows.Data.Pdf;
|
||||||
|
using Windows.Storage;
|
||||||
using Windows.Storage.Streams;
|
using Windows.Storage.Streams;
|
||||||
|
|
||||||
namespace Microsoft.PowerToys.ThumbnailHandler.Pdf
|
namespace Microsoft.PowerToys.ThumbnailHandler.Pdf
|
||||||
@@ -21,7 +15,6 @@ namespace Microsoft.PowerToys.ThumbnailHandler.Pdf
|
|||||||
public PdfThumbnailProvider(string filePath)
|
public PdfThumbnailProvider(string filePath)
|
||||||
{
|
{
|
||||||
FilePath = filePath;
|
FilePath = filePath;
|
||||||
Stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -29,11 +22,6 @@ namespace Microsoft.PowerToys.ThumbnailHandler.Pdf
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string FilePath { get; private set; }
|
public string FilePath { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the stream object to access file.
|
|
||||||
/// </summary>
|
|
||||||
public Stream Stream { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The maximum dimension (width or height) thumbnail we will generate.
|
/// The maximum dimension (width or height) thumbnail we will generate.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -45,6 +33,16 @@ namespace Microsoft.PowerToys.ThumbnailHandler.Pdf
|
|||||||
/// <param name="cx">Maximum thumbnail size, in pixels.</param>
|
/// <param name="cx">Maximum thumbnail size, in pixels.</param>
|
||||||
/// <returns>Generated bitmap</returns>
|
/// <returns>Generated bitmap</returns>
|
||||||
public Bitmap GetThumbnail(uint cx)
|
public Bitmap GetThumbnail(uint cx)
|
||||||
|
{
|
||||||
|
return DoGetThumbnail(cx).Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generate thumbnail bitmap for provided Pdf file/stream.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cx">Maximum thumbnail size, in pixels.</param>
|
||||||
|
/// <returns>Generated bitmap</returns>
|
||||||
|
private async Task<Bitmap> DoGetThumbnail(uint cx)
|
||||||
{
|
{
|
||||||
if (cx == 0 || cx > MaxThumbnailSize)
|
if (cx == 0 || cx > MaxThumbnailSize)
|
||||||
{
|
{
|
||||||
@@ -57,26 +55,27 @@ namespace Microsoft.PowerToys.ThumbnailHandler.Pdf
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
using var memStream = new MemoryStream();
|
Bitmap thumbnail = null;
|
||||||
|
try
|
||||||
this.Stream.CopyTo(memStream);
|
|
||||||
memStream.Position = 0;
|
|
||||||
|
|
||||||
// AsRandomAccessStream() extension method from System.Runtime.WindowsRuntime
|
|
||||||
var pdf = PdfDocument.LoadFromStreamAsync(memStream.AsRandomAccessStream()).GetAwaiter().GetResult();
|
|
||||||
|
|
||||||
if (pdf.PageCount > 0)
|
|
||||||
{
|
{
|
||||||
using var page = pdf.GetPage(0);
|
var file = await StorageFile.GetFileFromPathAsync(FilePath);
|
||||||
|
var pdf = await PdfDocument.LoadFromFileAsync(file);
|
||||||
|
|
||||||
var image = PageToImage(page, cx);
|
if (pdf.PageCount > 0)
|
||||||
|
{
|
||||||
|
using var page = pdf.GetPage(0);
|
||||||
|
|
||||||
using Bitmap thumbnail = new Bitmap(image);
|
var image = PageToImage(page, cx);
|
||||||
|
|
||||||
return (Bitmap)thumbnail.Clone();
|
thumbnail = new Bitmap(image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// TODO: add logger
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return thumbnail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -26,8 +26,11 @@ namespace Microsoft.PowerToys.ThumbnailHandler.Pdf
|
|||||||
|
|
||||||
_thumbnailProvider = new PdfThumbnailProvider(filePath);
|
_thumbnailProvider = new PdfThumbnailProvider(filePath);
|
||||||
Bitmap thumbnail = _thumbnailProvider.GetThumbnail(cx);
|
Bitmap thumbnail = _thumbnailProvider.GetThumbnail(cx);
|
||||||
filePath = filePath.Replace(".pdf", ".bmp");
|
if (thumbnail != null)
|
||||||
thumbnail.Save(filePath, System.Drawing.Imaging.ImageFormat.Bmp);
|
{
|
||||||
|
filePath = filePath.Replace(".pdf", ".bmp");
|
||||||
|
thumbnail.Save(filePath, System.Drawing.Imaging.ImageFormat.Bmp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -158,10 +158,18 @@ IFACEMETHODIMP PdfThumbnailProvider::GetThumbnail(UINT cx, HBITMAP* phbmp, WTS_A
|
|||||||
std::filesystem::remove(fileName);
|
std::filesystem::remove(fileName);
|
||||||
|
|
||||||
std::wstring fileNameBmp = filePath + guid + L".bmp";
|
std::wstring fileNameBmp = filePath + guid + L".bmp";
|
||||||
*phbmp = (HBITMAP)LoadImage(NULL, fileNameBmp.c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
|
if (std::filesystem::exists(fileNameBmp))
|
||||||
*pdwAlpha = WTS_ALPHATYPE::WTSAT_ARGB;
|
{
|
||||||
|
*phbmp = (HBITMAP)LoadImage(NULL, fileNameBmp.c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
|
||||||
|
*pdwAlpha = WTS_ALPHATYPE::WTSAT_ARGB;
|
||||||
|
std::filesystem::remove(fileNameBmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger::info(L"Bmp file not generated.");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
std::filesystem::remove(fileNameBmp);
|
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public:
|
|||||||
// IInitializeWithStream
|
// IInitializeWithStream
|
||||||
IFACEMETHODIMP Initialize(IStream* pstream, DWORD grfMode);
|
IFACEMETHODIMP Initialize(IStream* pstream, DWORD grfMode);
|
||||||
|
|
||||||
// IPreviewHandler
|
// IThumbnailProvider
|
||||||
IFACEMETHODIMP GetThumbnail(UINT cx, HBITMAP* phbmp, WTS_ALPHATYPE* pdwAlpha);
|
IFACEMETHODIMP GetThumbnail(UINT cx, HBITMAP* phbmp, WTS_ALPHATYPE* pdwAlpha);
|
||||||
|
|
||||||
PdfThumbnailProvider();
|
PdfThumbnailProvider();
|
||||||
|
|||||||
@@ -25,8 +25,11 @@ namespace Microsoft.PowerToys.ThumbnailHandler.Stl
|
|||||||
|
|
||||||
_thumbnailProvider = new StlThumbnailProvider(filePath);
|
_thumbnailProvider = new StlThumbnailProvider(filePath);
|
||||||
Bitmap thumbnail = _thumbnailProvider.GetThumbnail(cx);
|
Bitmap thumbnail = _thumbnailProvider.GetThumbnail(cx);
|
||||||
filePath = filePath.Replace(".stl", ".bmp");
|
if (thumbnail != null)
|
||||||
thumbnail.Save(filePath, System.Drawing.Imaging.ImageFormat.Bmp);
|
{
|
||||||
|
filePath = filePath.Replace(".stl", ".bmp");
|
||||||
|
thumbnail.Save(filePath, System.Drawing.Imaging.ImageFormat.Bmp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -130,19 +130,10 @@ namespace Microsoft.PowerToys.ThumbnailHandler.Stl
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var memStream = new MemoryStream())
|
Bitmap thumbnail = GetThumbnail(this.Stream, cx);
|
||||||
|
if (thumbnail != null && thumbnail.Size.Width > 0 && thumbnail.Size.Height > 0)
|
||||||
{
|
{
|
||||||
this.Stream.CopyTo(memStream);
|
return thumbnail;
|
||||||
|
|
||||||
memStream.Position = 0;
|
|
||||||
|
|
||||||
using (Bitmap thumbnail = GetThumbnail(memStream, cx))
|
|
||||||
{
|
|
||||||
if (thumbnail != null && thumbnail.Size.Width > 0 && thumbnail.Size.Height > 0)
|
|
||||||
{
|
|
||||||
return (Bitmap)thumbnail.Clone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -158,10 +158,17 @@ IFACEMETHODIMP StlThumbnailProvider::GetThumbnail(UINT cx, HBITMAP* phbmp, WTS_A
|
|||||||
std::filesystem::remove(fileName);
|
std::filesystem::remove(fileName);
|
||||||
|
|
||||||
std::wstring fileNameBmp = filePath + guid + L".bmp";
|
std::wstring fileNameBmp = filePath + guid + L".bmp";
|
||||||
*phbmp = (HBITMAP)LoadImage(NULL, fileNameBmp.c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
|
if (std::filesystem::exists(fileNameBmp))
|
||||||
*pdwAlpha = WTS_ALPHATYPE::WTSAT_ARGB;
|
{
|
||||||
|
*phbmp = (HBITMAP)LoadImage(NULL, fileNameBmp.c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
|
||||||
std::filesystem::remove(fileNameBmp);
|
*pdwAlpha = WTS_ALPHATYPE::WTSAT_ARGB;
|
||||||
|
std::filesystem::remove(fileNameBmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger::info(L"Bmp file not generated.");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public:
|
|||||||
// IInitializeWithStream
|
// IInitializeWithStream
|
||||||
IFACEMETHODIMP Initialize(IStream* pstream, DWORD grfMode);
|
IFACEMETHODIMP Initialize(IStream* pstream, DWORD grfMode);
|
||||||
|
|
||||||
// IPreviewHandler
|
// IThumbnailProvider
|
||||||
IFACEMETHODIMP GetThumbnail(UINT cx, HBITMAP* phbmp, WTS_ALPHATYPE* pdwAlpha);
|
IFACEMETHODIMP GetThumbnail(UINT cx, HBITMAP* phbmp, WTS_ALPHATYPE* pdwAlpha);
|
||||||
|
|
||||||
StlThumbnailProvider();
|
StlThumbnailProvider();
|
||||||
|
|||||||
@@ -26,8 +26,11 @@ namespace Microsoft.PowerToys.ThumbnailHandler.Svg
|
|||||||
|
|
||||||
_thumbnailProvider = new SvgThumbnailProvider(filePath);
|
_thumbnailProvider = new SvgThumbnailProvider(filePath);
|
||||||
Bitmap thumbnail = _thumbnailProvider.GetThumbnail(cx);
|
Bitmap thumbnail = _thumbnailProvider.GetThumbnail(cx);
|
||||||
filePath = filePath.Replace(".svg", ".bmp");
|
if (thumbnail != null )
|
||||||
thumbnail.Save(filePath, System.Drawing.Imaging.ImageFormat.Bmp);
|
{
|
||||||
|
filePath = filePath.Replace(".svg", ".bmp");
|
||||||
|
thumbnail.Save(filePath, System.Drawing.Imaging.ImageFormat.Bmp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -158,10 +158,18 @@ IFACEMETHODIMP SvgThumbnailProvider::GetThumbnail(UINT cx, HBITMAP* phbmp, WTS_A
|
|||||||
std::filesystem::remove(fileName);
|
std::filesystem::remove(fileName);
|
||||||
|
|
||||||
std::wstring fileNameBmp = filePath + guid + L".bmp";
|
std::wstring fileNameBmp = filePath + guid + L".bmp";
|
||||||
*phbmp = (HBITMAP)LoadImage(NULL, fileNameBmp.c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
|
|
||||||
*pdwAlpha = WTS_ALPHATYPE::WTSAT_ARGB;
|
|
||||||
|
|
||||||
std::filesystem::remove(fileNameBmp);
|
if (std::filesystem::exists(fileNameBmp))
|
||||||
|
{
|
||||||
|
*phbmp = (HBITMAP)LoadImage(NULL, fileNameBmp.c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
|
||||||
|
*pdwAlpha = WTS_ALPHATYPE::WTSAT_ARGB;
|
||||||
|
std::filesystem::remove(fileNameBmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger::info(L"Bmp file not generated.");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public:
|
|||||||
// IInitializeWithStream
|
// IInitializeWithStream
|
||||||
IFACEMETHODIMP Initialize(IStream* pstream, DWORD grfMode);
|
IFACEMETHODIMP Initialize(IStream* pstream, DWORD grfMode);
|
||||||
|
|
||||||
// IPreviewHandler
|
// IThumbnailProvider
|
||||||
IFACEMETHODIMP GetThumbnail(UINT cx, HBITMAP* phbmp, WTS_ALPHATYPE* pdwAlpha);
|
IFACEMETHODIMP GetThumbnail(UINT cx, HBITMAP* phbmp, WTS_ALPHATYPE* pdwAlpha);
|
||||||
|
|
||||||
SvgThumbnailProvider();
|
SvgThumbnailProvider();
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace PdfThumbnailProviderUnitTests
|
|||||||
public void GetThumbnailValidStreamPDF()
|
public void GetThumbnailValidStreamPDF()
|
||||||
{
|
{
|
||||||
// Act
|
// Act
|
||||||
var filePath = "HelperFiles/sample.pdf";
|
var filePath = System.IO.Path.GetFullPath("HelperFiles/sample.pdf");
|
||||||
|
|
||||||
PdfThumbnailProvider provider = new PdfThumbnailProvider(filePath);
|
PdfThumbnailProvider provider = new PdfThumbnailProvider(filePath);
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ namespace PdfThumbnailProviderUnitTests
|
|||||||
public void GetThumbnailInValidSizePDF()
|
public void GetThumbnailInValidSizePDF()
|
||||||
{
|
{
|
||||||
// Act
|
// Act
|
||||||
var filePath = "HelperFiles/sample.pdf";
|
var filePath = System.IO.Path.GetFullPath("HelperFiles/sample.pdf");
|
||||||
|
|
||||||
PdfThumbnailProvider provider = new PdfThumbnailProvider(filePath);
|
PdfThumbnailProvider provider = new PdfThumbnailProvider(filePath);
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ namespace PdfThumbnailProviderUnitTests
|
|||||||
public void GetThumbnailToBigPDF()
|
public void GetThumbnailToBigPDF()
|
||||||
{
|
{
|
||||||
// Act
|
// Act
|
||||||
var filePath = "HelperFiles/sample.pdf";
|
var filePath = System.IO.Path.GetFullPath("HelperFiles/sample.pdf");
|
||||||
|
|
||||||
PdfThumbnailProvider provider = new PdfThumbnailProvider(filePath);
|
PdfThumbnailProvider provider = new PdfThumbnailProvider(filePath);
|
||||||
|
|
||||||
|
|||||||
@@ -316,7 +316,7 @@ BOOL run_settings_non_elevated(LPCWSTR executable_path, LPWSTR executable_args,
|
|||||||
|
|
||||||
DWORD g_settings_process_id = 0;
|
DWORD g_settings_process_id = 0;
|
||||||
|
|
||||||
void run_settings_window(bool show_oobe_window, bool show_scoobe_window, std::optional<std::wstring> settings_window, bool show_flyout = false)
|
void run_settings_window(bool show_oobe_window, bool show_scoobe_window, std::optional<std::wstring> settings_window, bool show_flyout = false, const std::optional<POINT>& flyout_position = std::nullopt)
|
||||||
{
|
{
|
||||||
g_isLaunchInProgress = true;
|
g_isLaunchInProgress = true;
|
||||||
|
|
||||||
@@ -389,21 +389,31 @@ void run_settings_window(bool show_oobe_window, bool show_scoobe_window, std::op
|
|||||||
// Arg 10: should flyout be shown
|
// Arg 10: should flyout be shown
|
||||||
std::wstring settings_showFlyout = show_flyout ? L"true" : L"false";
|
std::wstring settings_showFlyout = show_flyout ? L"true" : L"false";
|
||||||
|
|
||||||
|
// Arg 11: contains if there's a settings window argument. If true, will add one extra argument with the value to the call.
|
||||||
|
std::wstring settings_containsSettingsWindow = settings_window.has_value() ? L"true" : L"false";
|
||||||
|
|
||||||
|
// Arg 12: contains if there's flyout coordinates. If true, will add two extra arguments to the call containing the x and y coordinates.
|
||||||
|
std::wstring settings_containsFlyoutPosition = flyout_position.has_value() ? L"true" : L"false";
|
||||||
|
|
||||||
|
// Args 13, .... : Optional arguments depending on the options presented before. All by the same value.
|
||||||
|
|
||||||
// create general settings file to initialize the settings file with installation configurations like :
|
// create general settings file to initialize the settings file with installation configurations like :
|
||||||
// 1. Run on start up.
|
// 1. Run on start up.
|
||||||
PTSettingsHelper::save_general_settings(save_settings.to_json());
|
PTSettingsHelper::save_general_settings(save_settings.to_json());
|
||||||
|
|
||||||
std::wstring executable_args = fmt::format(L"\"{}\" {} {} {} {} {} {} {} {} {}",
|
std::wstring executable_args = fmt::format(L"\"{}\" {} {} {} {} {} {} {} {} {} {} {}",
|
||||||
executable_path,
|
executable_path,
|
||||||
powertoys_pipe_name,
|
powertoys_pipe_name,
|
||||||
settings_pipe_name,
|
settings_pipe_name,
|
||||||
std::to_wstring(powertoys_pid),
|
std::to_wstring(powertoys_pid),
|
||||||
settings_theme,
|
settings_theme,
|
||||||
settings_elevatedStatus,
|
settings_elevatedStatus,
|
||||||
settings_isUserAnAdmin,
|
settings_isUserAnAdmin,
|
||||||
settings_showOobe,
|
settings_showOobe,
|
||||||
settings_showScoobe,
|
settings_showScoobe,
|
||||||
settings_showFlyout);
|
settings_showFlyout,
|
||||||
|
settings_containsSettingsWindow,
|
||||||
|
settings_containsFlyoutPosition);
|
||||||
|
|
||||||
if (settings_window.has_value())
|
if (settings_window.has_value())
|
||||||
{
|
{
|
||||||
@@ -411,6 +421,14 @@ void run_settings_window(bool show_oobe_window, bool show_scoobe_window, std::op
|
|||||||
executable_args.append(settings_window.value());
|
executable_args.append(settings_window.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flyout_position)
|
||||||
|
{
|
||||||
|
executable_args.append(L" ");
|
||||||
|
executable_args.append(std::to_wstring(flyout_position.value().x));
|
||||||
|
executable_args.append(L" ");
|
||||||
|
executable_args.append(std::to_wstring(flyout_position.value().y));
|
||||||
|
}
|
||||||
|
|
||||||
BOOL process_created = false;
|
BOOL process_created = false;
|
||||||
|
|
||||||
// Commented out to fix #22659
|
// Commented out to fix #22659
|
||||||
@@ -550,7 +568,7 @@ void bring_settings_to_front()
|
|||||||
EnumWindows(callback, 0);
|
EnumWindows(callback, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void open_settings_window(std::optional<std::wstring> settings_window, bool show_flyout = false)
|
void open_settings_window(std::optional<std::wstring> settings_window, bool show_flyout = false, const std::optional<POINT>& flyout_position)
|
||||||
{
|
{
|
||||||
if (g_settings_process_id != 0)
|
if (g_settings_process_id != 0)
|
||||||
{
|
{
|
||||||
@@ -558,7 +576,14 @@ void open_settings_window(std::optional<std::wstring> settings_window, bool show
|
|||||||
{
|
{
|
||||||
if (current_settings_ipc)
|
if (current_settings_ipc)
|
||||||
{
|
{
|
||||||
current_settings_ipc->send(L"{\"ShowYourself\":\"flyout\"}");
|
if (!flyout_position.has_value())
|
||||||
|
{
|
||||||
|
current_settings_ipc->send(L"{\"ShowYourself\":\"flyout\"}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
current_settings_ipc->send(fmt::format(L"{{\"ShowYourself\":\"flyout\", \"x_position\":{}, \"y_position\":{} }}", std::to_wstring(flyout_position.value().x), std::to_wstring(flyout_position.value().y)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -575,8 +600,8 @@ void open_settings_window(std::optional<std::wstring> settings_window, bool show
|
|||||||
{
|
{
|
||||||
if (!g_isLaunchInProgress)
|
if (!g_isLaunchInProgress)
|
||||||
{
|
{
|
||||||
std::thread([settings_window, show_flyout]() {
|
std::thread([settings_window, show_flyout, flyout_position]() {
|
||||||
run_settings_window(false, false, settings_window, show_flyout);
|
run_settings_window(false, false, settings_window, show_flyout, flyout_position);
|
||||||
}).detach();
|
}).detach();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -608,13 +633,6 @@ void open_scoobe_window()
|
|||||||
}).detach();
|
}).detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
void open_flyout()
|
|
||||||
{
|
|
||||||
std::thread([]() {
|
|
||||||
run_settings_window(false, false, std::nullopt, true);
|
|
||||||
}).detach();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ESettingsWindowNames_to_string(ESettingsWindowNames value)
|
std::string ESettingsWindowNames_to_string(ESettingsWindowNames value)
|
||||||
{
|
{
|
||||||
switch (value)
|
switch (value)
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ enum class ESettingsWindowNames
|
|||||||
std::string ESettingsWindowNames_to_string(ESettingsWindowNames value);
|
std::string ESettingsWindowNames_to_string(ESettingsWindowNames value);
|
||||||
ESettingsWindowNames ESettingsWindowNames_from_string(std::string value);
|
ESettingsWindowNames ESettingsWindowNames_from_string(std::string value);
|
||||||
|
|
||||||
void open_settings_window(std::optional<std::wstring> settings_window, bool show_flyout);
|
void open_settings_window(std::optional<std::wstring> settings_window, bool show_flyout, const std::optional<POINT>& flyout_position);
|
||||||
void close_settings_window();
|
void close_settings_window();
|
||||||
|
|
||||||
void open_oobe_window();
|
void open_oobe_window();
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ namespace
|
|||||||
HMENU h_sub_menu = nullptr;
|
HMENU h_sub_menu = nullptr;
|
||||||
bool double_click_timer_running = false;
|
bool double_click_timer_running = false;
|
||||||
bool double_clicked = false;
|
bool double_clicked = false;
|
||||||
|
POINT tray_icon_click_point;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Struct to fill with callback and the data. The window_proc is responsible for cleaning it.
|
// Struct to fill with callback and the data. The window_proc is responsible for cleaning it.
|
||||||
@@ -123,7 +125,7 @@ void click_timer_elapsed()
|
|||||||
double_click_timer_running = false;
|
double_click_timer_running = false;
|
||||||
if (!double_clicked)
|
if (!double_clicked)
|
||||||
{
|
{
|
||||||
open_settings_window(std::nullopt, true);
|
open_settings_window(std::nullopt, true, tray_icon_click_point);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,6 +214,9 @@ LRESULT __stdcall tray_icon_window_proc(HWND window, UINT message, WPARAM wparam
|
|||||||
// ignore event if this is the second click of a double click
|
// ignore event if this is the second click of a double click
|
||||||
if (!double_click_timer_running)
|
if (!double_click_timer_running)
|
||||||
{
|
{
|
||||||
|
// save the cursor position for sending where to show the popup.
|
||||||
|
GetCursorPos(&tray_icon_click_point);
|
||||||
|
|
||||||
// start timer for detecting single or double click
|
// start timer for detecting single or double click
|
||||||
double_click_timer_running = true;
|
double_click_timer_running = true;
|
||||||
double_clicked = false;
|
double_clicked = false;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ void start_tray_icon();
|
|||||||
// Stop the Tray Icon
|
// Stop the Tray Icon
|
||||||
void stop_tray_icon();
|
void stop_tray_icon();
|
||||||
// Open the Settings Window
|
// Open the Settings Window
|
||||||
void open_settings_window(std::optional<std::wstring> settings_window, bool show_flyout);
|
void open_settings_window(std::optional<std::wstring> settings_window, bool show_flyout, const std::optional<POINT>& flyout_position = std::nullopt);
|
||||||
// Callback type to be called by the tray icon loop
|
// Callback type to be called by the tray icon loop
|
||||||
typedef void (*main_loop_callback_function)(PVOID);
|
typedef void (*main_loop_callback_function)(PVOID);
|
||||||
// Calls a callback in _callback
|
// Calls a callback in _callback
|
||||||
|
|||||||
@@ -37,12 +37,12 @@ namespace Microsoft.PowerToys.Settings.UI
|
|||||||
ShowOobeWindow,
|
ShowOobeWindow,
|
||||||
ShowScoobeWindow,
|
ShowScoobeWindow,
|
||||||
ShowFlyout,
|
ShowFlyout,
|
||||||
SettingsWindow,
|
ContainsSettingsWindow,
|
||||||
|
ContainsFlyoutPosition,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Quantity of arguments
|
// Quantity of arguments
|
||||||
private const int RequiredArgumentsQty = 10;
|
private const int RequiredArgumentsQty = 12;
|
||||||
private const int RequiredAndOptionalArgumentsQty = 11;
|
|
||||||
|
|
||||||
// Create an instance of the IPC wrapper.
|
// Create an instance of the IPC wrapper.
|
||||||
private static TwoWayPipeMessageIPCManaged ipcmanager;
|
private static TwoWayPipeMessageIPCManaged ipcmanager;
|
||||||
@@ -122,11 +122,16 @@ namespace Microsoft.PowerToys.Settings.UI
|
|||||||
ShowOobe = cmdArgs[(int)Arguments.ShowOobeWindow] == "true";
|
ShowOobe = cmdArgs[(int)Arguments.ShowOobeWindow] == "true";
|
||||||
ShowScoobe = cmdArgs[(int)Arguments.ShowScoobeWindow] == "true";
|
ShowScoobe = cmdArgs[(int)Arguments.ShowScoobeWindow] == "true";
|
||||||
ShowFlyout = cmdArgs[(int)Arguments.ShowFlyout] == "true";
|
ShowFlyout = cmdArgs[(int)Arguments.ShowFlyout] == "true";
|
||||||
|
bool containsSettingsWindow = cmdArgs[(int)Arguments.ContainsSettingsWindow] == "true";
|
||||||
|
bool containsFlyoutPosition = cmdArgs[(int)Arguments.ContainsFlyoutPosition] == "true";
|
||||||
|
|
||||||
if (cmdArgs.Length == RequiredAndOptionalArgumentsQty)
|
// To keep track of variable arguments
|
||||||
|
int currentArgumentIndex = RequiredArgumentsQty;
|
||||||
|
|
||||||
|
if (containsSettingsWindow)
|
||||||
{
|
{
|
||||||
// open specific window
|
// open specific window
|
||||||
switch (cmdArgs[(int)Arguments.SettingsWindow])
|
switch (cmdArgs[currentArgumentIndex])
|
||||||
{
|
{
|
||||||
case "Overview": StartupPage = typeof(Views.GeneralPage); break;
|
case "Overview": StartupPage = typeof(Views.GeneralPage); break;
|
||||||
case "AlwaysOnTop": StartupPage = typeof(Views.AlwaysOnTopPage); break;
|
case "AlwaysOnTop": StartupPage = typeof(Views.AlwaysOnTopPage); break;
|
||||||
@@ -148,6 +153,17 @@ namespace Microsoft.PowerToys.Settings.UI
|
|||||||
case "Hosts": StartupPage = typeof(Views.HostsPage); break;
|
case "Hosts": StartupPage = typeof(Views.HostsPage); break;
|
||||||
default: Debug.Assert(false, "Unexpected SettingsWindow argument value"); break;
|
default: Debug.Assert(false, "Unexpected SettingsWindow argument value"); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
currentArgumentIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int flyout_x = 0;
|
||||||
|
int flyout_y = 0;
|
||||||
|
if (containsFlyoutPosition)
|
||||||
|
{
|
||||||
|
// get the flyout position arguments
|
||||||
|
int.TryParse(cmdArgs[currentArgumentIndex++], out flyout_x);
|
||||||
|
int.TryParse(cmdArgs[currentArgumentIndex++], out flyout_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
RunnerHelper.WaitForPowerToysRunner(PowerToysPID, () =>
|
RunnerHelper.WaitForPowerToysRunner(PowerToysPID, () =>
|
||||||
@@ -193,7 +209,13 @@ namespace Microsoft.PowerToys.Settings.UI
|
|||||||
}
|
}
|
||||||
else if (ShowFlyout)
|
else if (ShowFlyout)
|
||||||
{
|
{
|
||||||
ShellPage.OpenFlyoutCallback();
|
POINT? p = null;
|
||||||
|
if (containsFlyoutPosition)
|
||||||
|
{
|
||||||
|
p = new POINT(flyout_x, flyout_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
ShellPage.OpenFlyoutCallback(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
// Copyright (c) Microsoft Corporation
|
// Copyright (c) Microsoft Corporation
|
||||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
// See the LICENSE file in the project root for more information.
|
// See the LICENSE file in the project root for more information.
|
||||||
|
using Microsoft.PowerToys.Settings.UI.Helpers;
|
||||||
using Microsoft.PowerToys.Settings.UI.Library.Telemetry.Events;
|
using Microsoft.PowerToys.Settings.UI.Library.Telemetry.Events;
|
||||||
using Microsoft.PowerToys.Settings.UI.ViewModels.Flyout;
|
using Microsoft.PowerToys.Settings.UI.ViewModels.Flyout;
|
||||||
using Microsoft.PowerToys.Telemetry;
|
using Microsoft.PowerToys.Telemetry;
|
||||||
using Microsoft.UI;
|
using Microsoft.UI;
|
||||||
using Microsoft.UI.Windowing;
|
using Microsoft.UI.Windowing;
|
||||||
|
using Windows.Graphics;
|
||||||
using WinUIEx;
|
using WinUIEx;
|
||||||
|
|
||||||
namespace Microsoft.PowerToys.Settings.UI
|
namespace Microsoft.PowerToys.Settings.UI
|
||||||
@@ -21,23 +23,65 @@ namespace Microsoft.PowerToys.Settings.UI
|
|||||||
|
|
||||||
public FlyoutViewModel ViewModel { get; set; }
|
public FlyoutViewModel ViewModel { get; set; }
|
||||||
|
|
||||||
public FlyoutWindow()
|
public POINT? FlyoutAppearPosition { get; set; }
|
||||||
|
|
||||||
|
public FlyoutWindow(POINT? initialPosition)
|
||||||
{
|
{
|
||||||
this.InitializeComponent();
|
this.InitializeComponent();
|
||||||
this.Activated += FlyoutWindow_Activated;
|
this.Activated += FlyoutWindow_Activated;
|
||||||
var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
|
FlyoutAppearPosition = initialPosition;
|
||||||
WindowId windowId = Win32Interop.GetWindowIdFromWindow(hwnd);
|
|
||||||
DisplayArea displayArea = DisplayArea.GetFromWindowId(windowId, DisplayAreaFallback.Nearest);
|
|
||||||
double dpiScale = (float)this.GetDpiForWindow() / 96;
|
|
||||||
double x = displayArea.WorkArea.Width - (dpiScale * (WindowWidth + WindowMargin));
|
|
||||||
double y = displayArea.WorkArea.Height - (dpiScale * (WindowHeight + WindowMargin));
|
|
||||||
this.MoveAndResize(x, y, WindowWidth, WindowHeight);
|
|
||||||
ViewModel = new FlyoutViewModel();
|
ViewModel = new FlyoutViewModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FlyoutWindow_Activated(object sender, Microsoft.UI.Xaml.WindowActivatedEventArgs args)
|
private void FlyoutWindow_Activated(object sender, Microsoft.UI.Xaml.WindowActivatedEventArgs args)
|
||||||
{
|
{
|
||||||
PowerToysTelemetry.Log.WriteEvent(new TrayFlyoutActivatedEvent());
|
PowerToysTelemetry.Log.WriteEvent(new TrayFlyoutActivatedEvent());
|
||||||
|
if (args.WindowActivationState == Microsoft.UI.Xaml.WindowActivationState.CodeActivated)
|
||||||
|
{
|
||||||
|
var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
|
||||||
|
WindowId windowId = Win32Interop.GetWindowIdFromWindow(hwnd);
|
||||||
|
if (!FlyoutAppearPosition.HasValue)
|
||||||
|
{
|
||||||
|
DisplayArea displayArea = DisplayArea.GetFromWindowId(windowId, DisplayAreaFallback.Nearest);
|
||||||
|
double dpiScale = (float)this.GetDpiForWindow() / 96;
|
||||||
|
double x = displayArea.WorkArea.Width - (dpiScale * (WindowWidth + WindowMargin));
|
||||||
|
double y = displayArea.WorkArea.Height - (dpiScale * (WindowHeight + WindowMargin));
|
||||||
|
this.MoveAndResize(x, y, WindowWidth, WindowHeight);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DisplayArea displayArea = DisplayArea.GetFromPoint(new PointInt32(FlyoutAppearPosition.Value.X, FlyoutAppearPosition.Value.Y), DisplayAreaFallback.Nearest);
|
||||||
|
|
||||||
|
// Move the window to the correct screen as a little blob, so we can get the accurate dpi for the screen to calculate the best position to show it.
|
||||||
|
this.MoveAndResize(FlyoutAppearPosition.Value.X, FlyoutAppearPosition.Value.Y, 1, 1);
|
||||||
|
double dpiScale = (float)this.GetDpiForWindow() / 96;
|
||||||
|
|
||||||
|
// Position the window so that it's inside the display are closest to the point.
|
||||||
|
POINT newPosition = new POINT(FlyoutAppearPosition.Value.X - (int)(dpiScale * WindowWidth / 2), FlyoutAppearPosition.Value.Y - (int)(dpiScale * WindowHeight / 2));
|
||||||
|
if (newPosition.X < displayArea.WorkArea.X)
|
||||||
|
{
|
||||||
|
newPosition.X = displayArea.WorkArea.X;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newPosition.Y < displayArea.WorkArea.Y)
|
||||||
|
{
|
||||||
|
newPosition.Y = displayArea.WorkArea.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newPosition.X + (dpiScale * WindowWidth) > displayArea.WorkArea.X + displayArea.WorkArea.Width)
|
||||||
|
{
|
||||||
|
newPosition.X = (int)(displayArea.WorkArea.X + displayArea.WorkArea.Width - (dpiScale * WindowWidth));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newPosition.Y + (dpiScale * WindowHeight) > displayArea.WorkArea.Y + displayArea.WorkArea.Height)
|
||||||
|
{
|
||||||
|
newPosition.Y = (int)(displayArea.WorkArea.Y + displayArea.WorkArea.Height - (dpiScale * WindowHeight));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.MoveAndResize(newPosition.X, newPosition.Y, WindowWidth, WindowHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (args.WindowActivationState == Microsoft.UI.Xaml.WindowActivationState.Deactivated)
|
if (args.WindowActivationState == Microsoft.UI.Xaml.WindowActivationState.Deactivated)
|
||||||
{
|
{
|
||||||
if (ViewModel.CanHide)
|
if (ViewModel.CanHide)
|
||||||
|
|||||||
@@ -171,16 +171,17 @@ namespace Microsoft.PowerToys.Settings.UI
|
|||||||
});
|
});
|
||||||
|
|
||||||
// open flyout
|
// open flyout
|
||||||
ShellPage.SetOpenFlyoutCallback(() =>
|
ShellPage.SetOpenFlyoutCallback((POINT? p) =>
|
||||||
{
|
{
|
||||||
this.DispatcherQueue.TryEnqueue(Microsoft.UI.Dispatching.DispatcherQueuePriority.Normal, () =>
|
this.DispatcherQueue.TryEnqueue(Microsoft.UI.Dispatching.DispatcherQueuePriority.Normal, () =>
|
||||||
{
|
{
|
||||||
if (App.GetFlyoutWindow() == null)
|
if (App.GetFlyoutWindow() == null)
|
||||||
{
|
{
|
||||||
App.SetFlyoutWindow(new FlyoutWindow());
|
App.SetFlyoutWindow(new FlyoutWindow(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
FlyoutWindow flyout = App.GetFlyoutWindow();
|
FlyoutWindow flyout = App.GetFlyoutWindow();
|
||||||
|
flyout.FlyoutAppearPosition = p;
|
||||||
flyout.Activate();
|
flyout.Activate();
|
||||||
|
|
||||||
// https://github.com/microsoft/microsoft-ui-xaml/issues/7595 - Activate doesn't bring window to the foreground
|
// https://github.com/microsoft/microsoft-ui-xaml/issues/7595 - Activate doesn't bring window to the foreground
|
||||||
@@ -196,7 +197,7 @@ namespace Microsoft.PowerToys.Settings.UI
|
|||||||
{
|
{
|
||||||
if (App.GetFlyoutWindow() == null)
|
if (App.GetFlyoutWindow() == null)
|
||||||
{
|
{
|
||||||
App.SetFlyoutWindow(new FlyoutWindow());
|
App.SetFlyoutWindow(new FlyoutWindow(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
App.GetFlyoutWindow().ViewModel.DisableHiding();
|
App.GetFlyoutWindow().ViewModel.DisableHiding();
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
xmlns:ui="using:CommunityToolkit.WinUI.UI"
|
xmlns:ui="using:CommunityToolkit.WinUI.UI"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
|
|
||||||
<controls:SettingsPageControl x:Uid="Hosts" ModuleImageSource="ms-appx:///Assets/Modules/AlwaysOnTop.png">
|
<controls:SettingsPageControl x:Uid="Hosts" ModuleImageSource="ms-appx:///Assets/Modules/HostsFileEditor.png">
|
||||||
<controls:SettingsPageControl.ModuleContent>
|
<controls:SettingsPageControl.ModuleContent>
|
||||||
<StackPanel Orientation="Vertical" ChildrenTransitions="{StaticResource SettingsCardsAnimations}">
|
<StackPanel Orientation="Vertical" ChildrenTransitions="{StaticResource SettingsCardsAnimations}">
|
||||||
<labs:SettingsCard
|
<labs:SettingsCard
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Declaration for the opening flyout window callback function.
|
/// Declaration for the opening flyout window callback function.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public delegate void FlyoutOpeningCallback();
|
public delegate void FlyoutOpeningCallback(POINT? point);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Declaration for the disabling hide of flyout window callback function.
|
/// Declaration for the disabling hide of flyout window callback function.
|
||||||
@@ -330,13 +330,28 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
|||||||
{
|
{
|
||||||
if (json != null)
|
if (json != null)
|
||||||
{
|
{
|
||||||
if (json.ToString().StartsWith("{\"ShowYourself\":"))
|
IJsonValue whatToShowJson;
|
||||||
|
if (json.TryGetValue("ShowYourself", out whatToShowJson))
|
||||||
{
|
{
|
||||||
if (json.ToString().EndsWith("\"flyout\"}"))
|
if (whatToShowJson.ValueType == JsonValueType.String && whatToShowJson.GetString().Equals("flyout"))
|
||||||
{
|
{
|
||||||
OpenFlyoutCallback();
|
POINT? p = null;
|
||||||
|
|
||||||
|
IJsonValue flyoutPointX;
|
||||||
|
IJsonValue flyoutPointY;
|
||||||
|
if (json.TryGetValue("x_position", out flyoutPointX) && json.TryGetValue("y_position", out flyoutPointY))
|
||||||
|
{
|
||||||
|
if (flyoutPointX.ValueType == JsonValueType.Number && flyoutPointY.ValueType == JsonValueType.Number)
|
||||||
|
{
|
||||||
|
int flyout_x = (int)flyoutPointX.GetNumber();
|
||||||
|
int flyout_y = (int)flyoutPointY.GetNumber();
|
||||||
|
p = new POINT(flyout_x, flyout_y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenFlyoutCallback(p);
|
||||||
}
|
}
|
||||||
else if (json.ToString().EndsWith("\"main_page\"}"))
|
else if (whatToShowJson.ValueType == JsonValueType.String && whatToShowJson.GetString().Equals("main_page"))
|
||||||
{
|
{
|
||||||
OpenMainWindowCallback();
|
OpenMainWindowCallback();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user