2021-05-20 15:07:34 +03:00
|
|
|
// dllmain.cpp : Defines the entry point for the DLL application.
|
|
|
|
|
#include "pch.h"
|
|
|
|
|
|
|
|
|
|
#include <mutex>
|
|
|
|
|
#include <common/SettingsAPI/settings_helpers.h>
|
|
|
|
|
#include <common/utils/winapi_error.h>
|
|
|
|
|
#include <common/utils/logger_helper.h>
|
|
|
|
|
#include <common/interop/shared_constants.h>
|
|
|
|
|
|
|
|
|
|
#include "../interface/powertoy_module_interface.h"
|
|
|
|
|
#include "Generated Files/resource.h"
|
|
|
|
|
#include <common/SettingsAPI/settings_objects.h>
|
|
|
|
|
|
2022-11-09 14:41:14 +00:00
|
|
|
BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD /*ul_reason_for_call*/, LPVOID /*lpReserved*/)
|
2021-05-20 15:07:34 +03:00
|
|
|
{
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class ShortcutGuideModule : public PowertoyModuleIface
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
ShortcutGuideModule()
|
|
|
|
|
{
|
|
|
|
|
app_name = GET_RESOURCE_STRING(IDS_SHORTCUT_GUIDE);
|
|
|
|
|
app_key = L"Shortcut Guide";
|
|
|
|
|
LoggerHelpers::init_logger(app_key, L"ModuleInterface", LogSettings::shortcutGuideLoggerName);
|
|
|
|
|
|
|
|
|
|
std::filesystem::path oldLogPath(PTSettingsHelper::get_module_save_folder_location(app_key));
|
|
|
|
|
oldLogPath.append("ShortcutGuideLogs");
|
|
|
|
|
LoggerHelpers::delete_old_log_folder(oldLogPath);
|
|
|
|
|
|
|
|
|
|
exitEvent = CreateEvent(nullptr, false, false, CommonSharedConstants::SHORTCUT_GUIDE_EXIT_EVENT);
|
|
|
|
|
if (!exitEvent)
|
|
|
|
|
{
|
|
|
|
|
Logger::warn(L"Failed to create {} event. {}", CommonSharedConstants::SHORTCUT_GUIDE_EXIT_EVENT, get_last_error_or_default(GetLastError()));
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-31 00:00:11 +01:00
|
|
|
triggerEvent = CreateEvent(nullptr, false, false, CommonSharedConstants::SHORTCUT_GUIDE_TRIGGER_EVENT);
|
Shortcut Guide: Replace dual windows with single transparent overlay and add holding windows button (#48683)
## Summary
Refactors Shortcut Guide from two separate `WindowEx` instances
(`MainWindow` + `TaskbarWindow`) into a single full-monitor transparent
`OverlayWindow` that hosts both surfaces as XAML UserControls. This
enables shared animations and a more polished visual experience, and
makes the taskbar shortcut indicators **edge-aware** for Windows 11's
top/bottom/left/right taskbar positioning.
https://github.com/user-attachments/assets/e40a25f6-4ab3-4073-b1a8-906ef7782877
<img width="507" height="968" alt="image"
src="https://github.com/user-attachments/assets/2e06a3d9-32d9-482e-90fe-1f0f8a7d7598"
/>
## Changes
Closes: #48435
Closes #48491
Closes: #49200
Closes: #48552 (theme flash on Light/System theme + shortcut-list scroll
flutter)
Closes: #48773
### Architecture
- **OverlayWindow**: Single transparent host covering the full monitor
work area, using `TransparentTintBackdrop`
- **MainPaneControl**: The shortcut list pseudo-window, reusing the
shared `TransientSurface` control for chrome (acrylic backdrop, theme
shadow, rounded corners)
- **TaskbarPaneControl + TaskbarIndicator**: Tooltip-style indicators
with triangle tails, positioned above taskbar buttons
### Edge-aware taskbar indicators (Windows 11 top/bottom/left/right)
- Detects the taskbar edge via the public, documented `SHAppBarMessage`
/ `ABM_GETTASKBARPOS` API (the same API CmdPal Dock uses)
- Indicators lay out along the correct axis — horizontally for a
top/bottom taskbar, vertically for a left/right taskbar — with the
triangle tail always pointing toward the taskbar (4-direction tail +
per-edge slide-in animation)
- For a left/right taskbar, the main pane is inset so the order reads
**taskbar | indicators | pane**
- **Adaptive sizing**: each indicator's body size is derived from the
actual measured UIA taskbar button rect, so the bubbles shrink when
Windows uses small icons or combines buttons (many apps open). Uses the
smallest button slot (clamped to a readable range) so neighbouring
bubbles never overlap; the font scales with it
### Visual polish
- Windows 11 system flyout entry/exit animations (slide + fade, ~367ms
entrance / ~200ms exit with cubic easing)
- Animation direction is position-aware (slides from left when
left-aligned, from right when right-aligned)
- Taskbar indicators slide in from the taskbar edge with the same timing
- Close button on the main flyout title bar
### Robustness
- Multi-monitor DPI handling via WM_DPICHANGED suppression (prevents
double-scaling on cross-monitor moves)
- Win11 phantom border elimination (comprehensive DWM/style stripping)
- Click-outside-to-close with animated exit transition
- Process lifetime fix (`Application.Current.Exit()` on close)
## Validation
- Build clean (x64 Debug, exit 0, empty errors log)
- Tested on multi-monitor mixed-DPI setup (150% + 100%)
- Tested with the taskbar docked to each edge (top/bottom/left/right)
and with small/combined taskbar icons
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Noraa Junker <noraa.junker@outlook.com>
Co-authored-by: Clint Rutkas <clint@rutkas.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-07-27 12:21:35 +02:00
|
|
|
if (!triggerEvent)
|
|
|
|
|
{
|
|
|
|
|
Logger::warn(L"Failed to create {} event. {}", CommonSharedConstants::SHORTCUT_GUIDE_TRIGGER_EVENT, get_last_error_or_default(GetLastError()));
|
|
|
|
|
}
|
2023-01-31 00:00:11 +01:00
|
|
|
|
2021-05-20 15:07:34 +03:00
|
|
|
InitSettings();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual const wchar_t* get_name() override
|
|
|
|
|
{
|
|
|
|
|
return app_name.c_str();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual const wchar_t* get_key() override
|
|
|
|
|
{
|
|
|
|
|
return app_key.c_str();
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-26 14:02:31 +01:00
|
|
|
// Return the configured status for the gpo policy for the module
|
|
|
|
|
virtual powertoys_gpo::gpo_rule_configured_t gpo_policy_enabled_configuration() override
|
|
|
|
|
{
|
|
|
|
|
return powertoys_gpo::getConfiguredShortcutGuideEnabledValue();
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-20 15:07:34 +03:00
|
|
|
virtual bool get_config(wchar_t* buffer, int* buffer_size) override
|
|
|
|
|
{
|
|
|
|
|
HINSTANCE hinstance = reinterpret_cast<HINSTANCE>(&__ImageBase);
|
|
|
|
|
PowerToysSettings::Settings settings(hinstance, get_name());
|
|
|
|
|
return settings.serialize_to_buffer(buffer, buffer_size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void set_config(const wchar_t* config) override
|
|
|
|
|
{
|
|
|
|
|
Logger::trace("set_config()");
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// Parse the input JSON string.
|
|
|
|
|
PowerToysSettings::PowerToyValues values =
|
|
|
|
|
PowerToysSettings::PowerToyValues::from_json_string(config, get_key());
|
|
|
|
|
|
2021-09-23 14:23:22 +01:00
|
|
|
ParseSettings(values);
|
2021-05-20 15:07:34 +03:00
|
|
|
}
|
2022-09-11 19:50:13 +03:00
|
|
|
catch (std::exception& ex)
|
2021-05-20 15:07:34 +03:00
|
|
|
{
|
|
|
|
|
Logger::error("Failed to parse settings. {}", ex.what());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void enable() override
|
|
|
|
|
{
|
|
|
|
|
Logger::info("Shortcut Guide is enabling");
|
|
|
|
|
|
|
|
|
|
if (!_enabled)
|
|
|
|
|
{
|
|
|
|
|
_enabled = true;
|
Shortcut Guide: Replace dual windows with single transparent overlay and add holding windows button (#48683)
## Summary
Refactors Shortcut Guide from two separate `WindowEx` instances
(`MainWindow` + `TaskbarWindow`) into a single full-monitor transparent
`OverlayWindow` that hosts both surfaces as XAML UserControls. This
enables shared animations and a more polished visual experience, and
makes the taskbar shortcut indicators **edge-aware** for Windows 11's
top/bottom/left/right taskbar positioning.
https://github.com/user-attachments/assets/e40a25f6-4ab3-4073-b1a8-906ef7782877
<img width="507" height="968" alt="image"
src="https://github.com/user-attachments/assets/2e06a3d9-32d9-482e-90fe-1f0f8a7d7598"
/>
## Changes
Closes: #48435
Closes #48491
Closes: #49200
Closes: #48552 (theme flash on Light/System theme + shortcut-list scroll
flutter)
Closes: #48773
### Architecture
- **OverlayWindow**: Single transparent host covering the full monitor
work area, using `TransparentTintBackdrop`
- **MainPaneControl**: The shortcut list pseudo-window, reusing the
shared `TransientSurface` control for chrome (acrylic backdrop, theme
shadow, rounded corners)
- **TaskbarPaneControl + TaskbarIndicator**: Tooltip-style indicators
with triangle tails, positioned above taskbar buttons
### Edge-aware taskbar indicators (Windows 11 top/bottom/left/right)
- Detects the taskbar edge via the public, documented `SHAppBarMessage`
/ `ABM_GETTASKBARPOS` API (the same API CmdPal Dock uses)
- Indicators lay out along the correct axis — horizontally for a
top/bottom taskbar, vertically for a left/right taskbar — with the
triangle tail always pointing toward the taskbar (4-direction tail +
per-edge slide-in animation)
- For a left/right taskbar, the main pane is inset so the order reads
**taskbar | indicators | pane**
- **Adaptive sizing**: each indicator's body size is derived from the
actual measured UIA taskbar button rect, so the bubbles shrink when
Windows uses small icons or combines buttons (many apps open). Uses the
smallest button slot (clamped to a readable range) so neighbouring
bubbles never overlap; the font scales with it
### Visual polish
- Windows 11 system flyout entry/exit animations (slide + fade, ~367ms
entrance / ~200ms exit with cubic easing)
- Animation direction is position-aware (slides from left when
left-aligned, from right when right-aligned)
- Taskbar indicators slide in from the taskbar edge with the same timing
- Close button on the main flyout title bar
### Robustness
- Multi-monitor DPI handling via WM_DPICHANGED suppression (prevents
double-scaling on cross-monitor moves)
- Win11 phantom border elimination (comprehensive DWM/style stripping)
- Click-outside-to-close with animated exit transition
- Process lifetime fix (`Application.Current.Exit()` on close)
## Validation
- Build clean (x64 Debug, exit 0, empty errors log)
- Tested on multi-monitor mixed-DPI setup (150% + 100%)
- Tested with the taskbar docked to each edge (top/bottom/left/right)
and with small/combined taskbar icons
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Noraa Junker <noraa.junker@outlook.com>
Co-authored-by: Clint Rutkas <clint@rutkas.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-07-27 12:21:35 +02:00
|
|
|
StartProcess();
|
2021-05-20 15:07:34 +03:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Logger::warn("Shortcut guide is already enabled");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void disable() override
|
|
|
|
|
{
|
|
|
|
|
Logger::info("ShortcutGuideModule::disable()");
|
|
|
|
|
if (_enabled)
|
|
|
|
|
{
|
|
|
|
|
_enabled = false;
|
2026-05-21 17:27:52 +02:00
|
|
|
if (IsProcessActive())
|
|
|
|
|
{
|
|
|
|
|
TerminateProcess(m_hProcess, 0);
|
|
|
|
|
}
|
2021-05-20 15:07:34 +03:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Logger::warn("Shortcut Guide is already disabled");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual bool is_enabled() override
|
|
|
|
|
{
|
|
|
|
|
return _enabled;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void destroy() override
|
|
|
|
|
{
|
|
|
|
|
this->disable();
|
|
|
|
|
if (exitEvent)
|
|
|
|
|
{
|
|
|
|
|
CloseHandle(exitEvent);
|
|
|
|
|
}
|
Shortcut Guide: Replace dual windows with single transparent overlay and add holding windows button (#48683)
## Summary
Refactors Shortcut Guide from two separate `WindowEx` instances
(`MainWindow` + `TaskbarWindow`) into a single full-monitor transparent
`OverlayWindow` that hosts both surfaces as XAML UserControls. This
enables shared animations and a more polished visual experience, and
makes the taskbar shortcut indicators **edge-aware** for Windows 11's
top/bottom/left/right taskbar positioning.
https://github.com/user-attachments/assets/e40a25f6-4ab3-4073-b1a8-906ef7782877
<img width="507" height="968" alt="image"
src="https://github.com/user-attachments/assets/2e06a3d9-32d9-482e-90fe-1f0f8a7d7598"
/>
## Changes
Closes: #48435
Closes #48491
Closes: #49200
Closes: #48552 (theme flash on Light/System theme + shortcut-list scroll
flutter)
Closes: #48773
### Architecture
- **OverlayWindow**: Single transparent host covering the full monitor
work area, using `TransparentTintBackdrop`
- **MainPaneControl**: The shortcut list pseudo-window, reusing the
shared `TransientSurface` control for chrome (acrylic backdrop, theme
shadow, rounded corners)
- **TaskbarPaneControl + TaskbarIndicator**: Tooltip-style indicators
with triangle tails, positioned above taskbar buttons
### Edge-aware taskbar indicators (Windows 11 top/bottom/left/right)
- Detects the taskbar edge via the public, documented `SHAppBarMessage`
/ `ABM_GETTASKBARPOS` API (the same API CmdPal Dock uses)
- Indicators lay out along the correct axis — horizontally for a
top/bottom taskbar, vertically for a left/right taskbar — with the
triangle tail always pointing toward the taskbar (4-direction tail +
per-edge slide-in animation)
- For a left/right taskbar, the main pane is inset so the order reads
**taskbar | indicators | pane**
- **Adaptive sizing**: each indicator's body size is derived from the
actual measured UIA taskbar button rect, so the bubbles shrink when
Windows uses small icons or combines buttons (many apps open). Uses the
smallest button slot (clamped to a readable range) so neighbouring
bubbles never overlap; the font scales with it
### Visual polish
- Windows 11 system flyout entry/exit animations (slide + fade, ~367ms
entrance / ~200ms exit with cubic easing)
- Animation direction is position-aware (slides from left when
left-aligned, from right when right-aligned)
- Taskbar indicators slide in from the taskbar edge with the same timing
- Close button on the main flyout title bar
### Robustness
- Multi-monitor DPI handling via WM_DPICHANGED suppression (prevents
double-scaling on cross-monitor moves)
- Win11 phantom border elimination (comprehensive DWM/style stripping)
- Click-outside-to-close with animated exit transition
- Process lifetime fix (`Application.Current.Exit()` on close)
## Validation
- Build clean (x64 Debug, exit 0, empty errors log)
- Tested on multi-monitor mixed-DPI setup (150% + 100%)
- Tested with the taskbar docked to each edge (top/bottom/left/right)
and with small/combined taskbar icons
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Noraa Junker <noraa.junker@outlook.com>
Co-authored-by: Clint Rutkas <clint@rutkas.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-07-27 12:21:35 +02:00
|
|
|
if (triggerEvent)
|
|
|
|
|
{
|
|
|
|
|
CloseHandle(triggerEvent);
|
|
|
|
|
}
|
2021-05-20 15:07:34 +03:00
|
|
|
|
|
|
|
|
delete this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual std::optional<HotkeyEx> GetHotkeyEx() override
|
|
|
|
|
{
|
|
|
|
|
Logger::trace("GetHotkeyEx()");
|
|
|
|
|
return m_hotkey;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void OnHotkeyEx() override
|
|
|
|
|
{
|
|
|
|
|
Logger::trace("OnHotkeyEx()");
|
|
|
|
|
if (!_enabled)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
Shortcut Guide: Replace dual windows with single transparent overlay and add holding windows button (#48683)
## Summary
Refactors Shortcut Guide from two separate `WindowEx` instances
(`MainWindow` + `TaskbarWindow`) into a single full-monitor transparent
`OverlayWindow` that hosts both surfaces as XAML UserControls. This
enables shared animations and a more polished visual experience, and
makes the taskbar shortcut indicators **edge-aware** for Windows 11's
top/bottom/left/right taskbar positioning.
https://github.com/user-attachments/assets/e40a25f6-4ab3-4073-b1a8-906ef7782877
<img width="507" height="968" alt="image"
src="https://github.com/user-attachments/assets/2e06a3d9-32d9-482e-90fe-1f0f8a7d7598"
/>
## Changes
Closes: #48435
Closes #48491
Closes: #49200
Closes: #48552 (theme flash on Light/System theme + shortcut-list scroll
flutter)
Closes: #48773
### Architecture
- **OverlayWindow**: Single transparent host covering the full monitor
work area, using `TransparentTintBackdrop`
- **MainPaneControl**: The shortcut list pseudo-window, reusing the
shared `TransientSurface` control for chrome (acrylic backdrop, theme
shadow, rounded corners)
- **TaskbarPaneControl + TaskbarIndicator**: Tooltip-style indicators
with triangle tails, positioned above taskbar buttons
### Edge-aware taskbar indicators (Windows 11 top/bottom/left/right)
- Detects the taskbar edge via the public, documented `SHAppBarMessage`
/ `ABM_GETTASKBARPOS` API (the same API CmdPal Dock uses)
- Indicators lay out along the correct axis — horizontally for a
top/bottom taskbar, vertically for a left/right taskbar — with the
triangle tail always pointing toward the taskbar (4-direction tail +
per-edge slide-in animation)
- For a left/right taskbar, the main pane is inset so the order reads
**taskbar | indicators | pane**
- **Adaptive sizing**: each indicator's body size is derived from the
actual measured UIA taskbar button rect, so the bubbles shrink when
Windows uses small icons or combines buttons (many apps open). Uses the
smallest button slot (clamped to a readable range) so neighbouring
bubbles never overlap; the font scales with it
### Visual polish
- Windows 11 system flyout entry/exit animations (slide + fade, ~367ms
entrance / ~200ms exit with cubic easing)
- Animation direction is position-aware (slides from left when
left-aligned, from right when right-aligned)
- Taskbar indicators slide in from the taskbar edge with the same timing
- Close button on the main flyout title bar
### Robustness
- Multi-monitor DPI handling via WM_DPICHANGED suppression (prevents
double-scaling on cross-monitor moves)
- Win11 phantom border elimination (comprehensive DWM/style stripping)
- Click-outside-to-close with animated exit transition
- Process lifetime fix (`Application.Current.Exit()` on close)
## Validation
- Build clean (x64 Debug, exit 0, empty errors log)
- Tested on multi-monitor mixed-DPI setup (150% + 100%)
- Tested with the taskbar docked to each edge (top/bottom/left/right)
and with small/combined taskbar icons
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Noraa Junker <noraa.junker@outlook.com>
Co-authored-by: Clint Rutkas <clint@rutkas.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-07-27 12:21:35 +02:00
|
|
|
if (!IsProcessActive())
|
2021-05-20 15:07:34 +03:00
|
|
|
{
|
Shortcut Guide: Replace dual windows with single transparent overlay and add holding windows button (#48683)
## Summary
Refactors Shortcut Guide from two separate `WindowEx` instances
(`MainWindow` + `TaskbarWindow`) into a single full-monitor transparent
`OverlayWindow` that hosts both surfaces as XAML UserControls. This
enables shared animations and a more polished visual experience, and
makes the taskbar shortcut indicators **edge-aware** for Windows 11's
top/bottom/left/right taskbar positioning.
https://github.com/user-attachments/assets/e40a25f6-4ab3-4073-b1a8-906ef7782877
<img width="507" height="968" alt="image"
src="https://github.com/user-attachments/assets/2e06a3d9-32d9-482e-90fe-1f0f8a7d7598"
/>
## Changes
Closes: #48435
Closes #48491
Closes: #49200
Closes: #48552 (theme flash on Light/System theme + shortcut-list scroll
flutter)
Closes: #48773
### Architecture
- **OverlayWindow**: Single transparent host covering the full monitor
work area, using `TransparentTintBackdrop`
- **MainPaneControl**: The shortcut list pseudo-window, reusing the
shared `TransientSurface` control for chrome (acrylic backdrop, theme
shadow, rounded corners)
- **TaskbarPaneControl + TaskbarIndicator**: Tooltip-style indicators
with triangle tails, positioned above taskbar buttons
### Edge-aware taskbar indicators (Windows 11 top/bottom/left/right)
- Detects the taskbar edge via the public, documented `SHAppBarMessage`
/ `ABM_GETTASKBARPOS` API (the same API CmdPal Dock uses)
- Indicators lay out along the correct axis — horizontally for a
top/bottom taskbar, vertically for a left/right taskbar — with the
triangle tail always pointing toward the taskbar (4-direction tail +
per-edge slide-in animation)
- For a left/right taskbar, the main pane is inset so the order reads
**taskbar | indicators | pane**
- **Adaptive sizing**: each indicator's body size is derived from the
actual measured UIA taskbar button rect, so the bubbles shrink when
Windows uses small icons or combines buttons (many apps open). Uses the
smallest button slot (clamped to a readable range) so neighbouring
bubbles never overlap; the font scales with it
### Visual polish
- Windows 11 system flyout entry/exit animations (slide + fade, ~367ms
entrance / ~200ms exit with cubic easing)
- Animation direction is position-aware (slides from left when
left-aligned, from right when right-aligned)
- Taskbar indicators slide in from the taskbar edge with the same timing
- Close button on the main flyout title bar
### Robustness
- Multi-monitor DPI handling via WM_DPICHANGED suppression (prevents
double-scaling on cross-monitor moves)
- Win11 phantom border elimination (comprehensive DWM/style stripping)
- Click-outside-to-close with animated exit transition
- Process lifetime fix (`Application.Current.Exit()` on close)
## Validation
- Build clean (x64 Debug, exit 0, empty errors log)
- Tested on multi-monitor mixed-DPI setup (150% + 100%)
- Tested with the taskbar docked to each edge (top/bottom/left/right)
and with small/combined taskbar icons
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Noraa Junker <noraa.junker@outlook.com>
Co-authored-by: Clint Rutkas <clint@rutkas.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-07-27 12:21:35 +02:00
|
|
|
StartProcess();
|
2021-05-20 15:07:34 +03:00
|
|
|
}
|
|
|
|
|
|
Shortcut Guide: Replace dual windows with single transparent overlay and add holding windows button (#48683)
## Summary
Refactors Shortcut Guide from two separate `WindowEx` instances
(`MainWindow` + `TaskbarWindow`) into a single full-monitor transparent
`OverlayWindow` that hosts both surfaces as XAML UserControls. This
enables shared animations and a more polished visual experience, and
makes the taskbar shortcut indicators **edge-aware** for Windows 11's
top/bottom/left/right taskbar positioning.
https://github.com/user-attachments/assets/e40a25f6-4ab3-4073-b1a8-906ef7782877
<img width="507" height="968" alt="image"
src="https://github.com/user-attachments/assets/2e06a3d9-32d9-482e-90fe-1f0f8a7d7598"
/>
## Changes
Closes: #48435
Closes #48491
Closes: #49200
Closes: #48552 (theme flash on Light/System theme + shortcut-list scroll
flutter)
Closes: #48773
### Architecture
- **OverlayWindow**: Single transparent host covering the full monitor
work area, using `TransparentTintBackdrop`
- **MainPaneControl**: The shortcut list pseudo-window, reusing the
shared `TransientSurface` control for chrome (acrylic backdrop, theme
shadow, rounded corners)
- **TaskbarPaneControl + TaskbarIndicator**: Tooltip-style indicators
with triangle tails, positioned above taskbar buttons
### Edge-aware taskbar indicators (Windows 11 top/bottom/left/right)
- Detects the taskbar edge via the public, documented `SHAppBarMessage`
/ `ABM_GETTASKBARPOS` API (the same API CmdPal Dock uses)
- Indicators lay out along the correct axis — horizontally for a
top/bottom taskbar, vertically for a left/right taskbar — with the
triangle tail always pointing toward the taskbar (4-direction tail +
per-edge slide-in animation)
- For a left/right taskbar, the main pane is inset so the order reads
**taskbar | indicators | pane**
- **Adaptive sizing**: each indicator's body size is derived from the
actual measured UIA taskbar button rect, so the bubbles shrink when
Windows uses small icons or combines buttons (many apps open). Uses the
smallest button slot (clamped to a readable range) so neighbouring
bubbles never overlap; the font scales with it
### Visual polish
- Windows 11 system flyout entry/exit animations (slide + fade, ~367ms
entrance / ~200ms exit with cubic easing)
- Animation direction is position-aware (slides from left when
left-aligned, from right when right-aligned)
- Taskbar indicators slide in from the taskbar edge with the same timing
- Close button on the main flyout title bar
### Robustness
- Multi-monitor DPI handling via WM_DPICHANGED suppression (prevents
double-scaling on cross-monitor moves)
- Win11 phantom border elimination (comprehensive DWM/style stripping)
- Click-outside-to-close with animated exit transition
- Process lifetime fix (`Application.Current.Exit()` on close)
## Validation
- Build clean (x64 Debug, exit 0, empty errors log)
- Tested on multi-monitor mixed-DPI setup (150% + 100%)
- Tested with the taskbar docked to each edge (top/bottom/left/right)
and with small/combined taskbar icons
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Noraa Junker <noraa.junker@outlook.com>
Co-authored-by: Clint Rutkas <clint@rutkas.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-07-27 12:21:35 +02:00
|
|
|
SetEvent(triggerEvent);
|
2021-05-20 15:07:34 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void send_settings_telemetry() override
|
|
|
|
|
{
|
|
|
|
|
Logger::trace("Send settings telemetry");
|
|
|
|
|
if (!StartProcess(L"telemetry"))
|
|
|
|
|
{
|
|
|
|
|
Logger::error("Failed to create a process to send settings telemetry");
|
|
|
|
|
}
|
|
|
|
|
}
|
Shortcut Guide: Replace dual windows with single transparent overlay and add holding windows button (#48683)
## Summary
Refactors Shortcut Guide from two separate `WindowEx` instances
(`MainWindow` + `TaskbarWindow`) into a single full-monitor transparent
`OverlayWindow` that hosts both surfaces as XAML UserControls. This
enables shared animations and a more polished visual experience, and
makes the taskbar shortcut indicators **edge-aware** for Windows 11's
top/bottom/left/right taskbar positioning.
https://github.com/user-attachments/assets/e40a25f6-4ab3-4073-b1a8-906ef7782877
<img width="507" height="968" alt="image"
src="https://github.com/user-attachments/assets/2e06a3d9-32d9-482e-90fe-1f0f8a7d7598"
/>
## Changes
Closes: #48435
Closes #48491
Closes: #49200
Closes: #48552 (theme flash on Light/System theme + shortcut-list scroll
flutter)
Closes: #48773
### Architecture
- **OverlayWindow**: Single transparent host covering the full monitor
work area, using `TransparentTintBackdrop`
- **MainPaneControl**: The shortcut list pseudo-window, reusing the
shared `TransientSurface` control for chrome (acrylic backdrop, theme
shadow, rounded corners)
- **TaskbarPaneControl + TaskbarIndicator**: Tooltip-style indicators
with triangle tails, positioned above taskbar buttons
### Edge-aware taskbar indicators (Windows 11 top/bottom/left/right)
- Detects the taskbar edge via the public, documented `SHAppBarMessage`
/ `ABM_GETTASKBARPOS` API (the same API CmdPal Dock uses)
- Indicators lay out along the correct axis — horizontally for a
top/bottom taskbar, vertically for a left/right taskbar — with the
triangle tail always pointing toward the taskbar (4-direction tail +
per-edge slide-in animation)
- For a left/right taskbar, the main pane is inset so the order reads
**taskbar | indicators | pane**
- **Adaptive sizing**: each indicator's body size is derived from the
actual measured UIA taskbar button rect, so the bubbles shrink when
Windows uses small icons or combines buttons (many apps open). Uses the
smallest button slot (clamped to a readable range) so neighbouring
bubbles never overlap; the font scales with it
### Visual polish
- Windows 11 system flyout entry/exit animations (slide + fade, ~367ms
entrance / ~200ms exit with cubic easing)
- Animation direction is position-aware (slides from left when
left-aligned, from right when right-aligned)
- Taskbar indicators slide in from the taskbar edge with the same timing
- Close button on the main flyout title bar
### Robustness
- Multi-monitor DPI handling via WM_DPICHANGED suppression (prevents
double-scaling on cross-monitor moves)
- Win11 phantom border elimination (comprehensive DWM/style stripping)
- Click-outside-to-close with animated exit transition
- Process lifetime fix (`Application.Current.Exit()` on close)
## Validation
- Build clean (x64 Debug, exit 0, empty errors log)
- Tested on multi-monitor mixed-DPI setup (150% + 100%)
- Tested with the taskbar docked to each edge (top/bottom/left/right)
and with small/combined taskbar icons
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Noraa Junker <noraa.junker@outlook.com>
Co-authored-by: Clint Rutkas <clint@rutkas.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-07-27 12:21:35 +02:00
|
|
|
virtual bool keep_track_of_pressed_win_key() override { return true; }
|
[Shortcut Guide] Add Windows key hold activation options (#49661)
## Summary of the Pull Request
Adds configurable Windows-key hold activation to Shortcut Guide while
keeping the regular activation shortcut independent.
Users can choose to disable Windows-key activation, show taskbar
indicators, or open the full Shortcut Guide. Full-guide mode also
supports a configurable hold duration and optional close-on-release
behavior.
<img width="1099" height="611" alt="image"
src="https://github.com/user-attachments/assets/e0fe4c0f-3bef-43f8-a526-d22caf9e484e"
/>
## PR Checklist
- [ ] Closes: N/A
- [x] **Communication:** The UX and behavior were discussed before
implementation
- [x] **Tests:** Added/updated and all pass
- [x] **Localization:** All end-user-facing strings can be localized
- [x] **Dev docs:** Added/updated
- [ ] **New binaries:** Not applicable
- [ ] **Documentation updated:** Not applicable
## Detailed Description of the Pull Request / Additional comments
- Adds Off, taskbar-indicator, and full-guide Windows-key actions to
Settings.
- Adds a 100–5,000 ms hold-duration setting and a full-guide
close-on-release option.
- Handles left and right Windows keys and suppresses Start after an
activated hold.
- Routes Windows-key holds through a dedicated event so custom
activation shortcuts remain independent.
- Clears previous pressed-key registrations before refreshing them to
prevent duplicate long-press callbacks.
- Preserves compatibility with the existing `press_time` setting and
documents the new options.
## Validation Steps Performed
- Built the affected ARM64 Debug Settings, Runner, Shortcut Guide
module-interface, and Shortcut Guide UI projects.
- `ShortcutGuide.UnitTests`: 7/7 passed.
- Targeted Settings tests: 12/12 passed.
- Manually verified Off, taskbar-indicator, full-guide close-on-release,
and full-guide persistent modes.
- Verified configured hold thresholds, both Windows keys, Start
suppression, and regular-shortcut independence.
- Validated the final Settings XAML layout in the running Settings app.
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Muyuan Li (from Dev Box) <muyuanli@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2b3acca3-e49b-4936-8fb9-6f669bd449db
2026-08-13 22:27:39 +02:00
|
|
|
virtual UINT milliseconds_win_key_must_be_pressed() override { return m_millisecondsWinKeyPressTimeForGlobalWindowsShortcuts; }
|
2021-05-20 15:07:34 +03:00
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
std::wstring app_name;
|
|
|
|
|
//contains the non localized key of the powertoy
|
|
|
|
|
std::wstring app_key;
|
|
|
|
|
bool _enabled = false;
|
|
|
|
|
HANDLE m_hProcess = nullptr;
|
2022-11-09 14:41:14 +00:00
|
|
|
|
2021-05-20 15:07:34 +03:00
|
|
|
// Hotkey to invoke the module
|
|
|
|
|
HotkeyEx m_hotkey;
|
2021-09-23 14:23:22 +01:00
|
|
|
|
|
|
|
|
// If the module should be activated through the legacy pressing windows key behavior.
|
2022-11-18 22:22:40 +08:00
|
|
|
const UINT DEFAULT_MILLISECONDS_WIN_KEY_PRESS_TIME_FOR_GLOBAL_WINDOWS_SHORTCUTS = 900;
|
|
|
|
|
const UINT DEFAULT_MILLISECONDS_WIN_KEY_PRESS_TIME_FOR_TASKBAR_ICON_SHORTCUTS = 900;
|
|
|
|
|
UINT m_millisecondsWinKeyPressTimeForGlobalWindowsShortcuts = DEFAULT_MILLISECONDS_WIN_KEY_PRESS_TIME_FOR_GLOBAL_WINDOWS_SHORTCUTS;
|
|
|
|
|
UINT m_millisecondsWinKeyPressTimeForTaskbarIconShortcuts = DEFAULT_MILLISECONDS_WIN_KEY_PRESS_TIME_FOR_TASKBAR_ICON_SHORTCUTS;
|
2021-09-23 14:23:22 +01:00
|
|
|
|
2023-01-31 00:00:11 +01:00
|
|
|
HANDLE triggerEvent;
|
2021-05-20 15:07:34 +03:00
|
|
|
HANDLE exitEvent;
|
|
|
|
|
|
|
|
|
|
bool StartProcess(std::wstring args = L"")
|
|
|
|
|
{
|
|
|
|
|
if (exitEvent)
|
|
|
|
|
{
|
|
|
|
|
ResetEvent(exitEvent);
|
|
|
|
|
}
|
|
|
|
|
|
Shortcut Guide: Replace dual windows with single transparent overlay and add holding windows button (#48683)
## Summary
Refactors Shortcut Guide from two separate `WindowEx` instances
(`MainWindow` + `TaskbarWindow`) into a single full-monitor transparent
`OverlayWindow` that hosts both surfaces as XAML UserControls. This
enables shared animations and a more polished visual experience, and
makes the taskbar shortcut indicators **edge-aware** for Windows 11's
top/bottom/left/right taskbar positioning.
https://github.com/user-attachments/assets/e40a25f6-4ab3-4073-b1a8-906ef7782877
<img width="507" height="968" alt="image"
src="https://github.com/user-attachments/assets/2e06a3d9-32d9-482e-90fe-1f0f8a7d7598"
/>
## Changes
Closes: #48435
Closes #48491
Closes: #49200
Closes: #48552 (theme flash on Light/System theme + shortcut-list scroll
flutter)
Closes: #48773
### Architecture
- **OverlayWindow**: Single transparent host covering the full monitor
work area, using `TransparentTintBackdrop`
- **MainPaneControl**: The shortcut list pseudo-window, reusing the
shared `TransientSurface` control for chrome (acrylic backdrop, theme
shadow, rounded corners)
- **TaskbarPaneControl + TaskbarIndicator**: Tooltip-style indicators
with triangle tails, positioned above taskbar buttons
### Edge-aware taskbar indicators (Windows 11 top/bottom/left/right)
- Detects the taskbar edge via the public, documented `SHAppBarMessage`
/ `ABM_GETTASKBARPOS` API (the same API CmdPal Dock uses)
- Indicators lay out along the correct axis — horizontally for a
top/bottom taskbar, vertically for a left/right taskbar — with the
triangle tail always pointing toward the taskbar (4-direction tail +
per-edge slide-in animation)
- For a left/right taskbar, the main pane is inset so the order reads
**taskbar | indicators | pane**
- **Adaptive sizing**: each indicator's body size is derived from the
actual measured UIA taskbar button rect, so the bubbles shrink when
Windows uses small icons or combines buttons (many apps open). Uses the
smallest button slot (clamped to a readable range) so neighbouring
bubbles never overlap; the font scales with it
### Visual polish
- Windows 11 system flyout entry/exit animations (slide + fade, ~367ms
entrance / ~200ms exit with cubic easing)
- Animation direction is position-aware (slides from left when
left-aligned, from right when right-aligned)
- Taskbar indicators slide in from the taskbar edge with the same timing
- Close button on the main flyout title bar
### Robustness
- Multi-monitor DPI handling via WM_DPICHANGED suppression (prevents
double-scaling on cross-monitor moves)
- Win11 phantom border elimination (comprehensive DWM/style stripping)
- Click-outside-to-close with animated exit transition
- Process lifetime fix (`Application.Current.Exit()` on close)
## Validation
- Build clean (x64 Debug, exit 0, empty errors log)
- Tested on multi-monitor mixed-DPI setup (150% + 100%)
- Tested with the taskbar docked to each edge (top/bottom/left/right)
and with small/combined taskbar icons
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Noraa Junker <noraa.junker@outlook.com>
Co-authored-by: Clint Rutkas <clint@rutkas.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-07-27 12:21:35 +02:00
|
|
|
if (triggerEvent)
|
|
|
|
|
{
|
|
|
|
|
ResetEvent(triggerEvent);
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-20 15:07:34 +03:00
|
|
|
unsigned long powertoys_pid = GetCurrentProcessId();
|
|
|
|
|
std::wstring executable_args = L"";
|
|
|
|
|
executable_args.append(std::to_wstring(powertoys_pid));
|
|
|
|
|
if (!args.empty())
|
|
|
|
|
{
|
|
|
|
|
executable_args.append(L" ");
|
|
|
|
|
executable_args.append(args);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SHELLEXECUTEINFOW sei{ sizeof(sei) };
|
|
|
|
|
sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI };
|
2026-05-21 17:27:52 +02:00
|
|
|
sei.lpFile = L"WinUI3Apps\\PowerToys.ShortcutGuide.exe";
|
2021-05-20 15:07:34 +03:00
|
|
|
sei.nShow = SW_SHOWNORMAL;
|
|
|
|
|
sei.lpParameters = executable_args.data();
|
|
|
|
|
if (ShellExecuteExW(&sei) == false)
|
|
|
|
|
{
|
|
|
|
|
Logger::error(L"Failed to start SG process. {}", get_last_error_or_default(GetLastError()));
|
|
|
|
|
auto message = get_last_error_message(GetLastError());
|
|
|
|
|
if (message.has_value())
|
|
|
|
|
{
|
|
|
|
|
Logger::error(message.value());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Logger::trace(L"Started SG process with pid={}", GetProcessId(sei.hProcess));
|
|
|
|
|
m_hProcess = sei.hProcess;
|
2022-11-09 14:41:14 +00:00
|
|
|
return true;
|
2021-05-20 15:07:34 +03:00
|
|
|
}
|
|
|
|
|
|
2026-05-21 17:27:52 +02:00
|
|
|
bool IsProcessActive()
|
2021-05-20 15:07:34 +03:00
|
|
|
{
|
2026-05-21 17:27:52 +02:00
|
|
|
if (!m_hProcess)
|
2021-05-20 15:07:34 +03:00
|
|
|
{
|
2026-05-21 17:27:52 +02:00
|
|
|
return false;
|
2021-05-20 15:07:34 +03:00
|
|
|
}
|
2026-05-21 17:27:52 +02:00
|
|
|
auto result = WaitForSingleObject(m_hProcess, 0);
|
|
|
|
|
if (result == WAIT_FAILED)
|
|
|
|
|
{
|
|
|
|
|
Logger::error("Failed to wait for SG process.");
|
|
|
|
|
}
|
|
|
|
|
return result == WAIT_TIMEOUT;
|
2021-05-20 15:07:34 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void InitSettings()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
PowerToysSettings::PowerToyValues settings =
|
|
|
|
|
PowerToysSettings::PowerToyValues::load_from_settings_file(app_key);
|
|
|
|
|
|
2021-09-23 14:23:22 +01:00
|
|
|
ParseSettings(settings);
|
2021-05-20 15:07:34 +03:00
|
|
|
}
|
2022-09-11 19:50:13 +03:00
|
|
|
catch (std::exception& ex)
|
2021-05-20 15:07:34 +03:00
|
|
|
{
|
|
|
|
|
Logger::error("Failed to init settings. {}", ex.what());
|
|
|
|
|
}
|
2022-11-09 14:41:14 +00:00
|
|
|
catch (...)
|
2021-05-20 15:07:34 +03:00
|
|
|
{
|
|
|
|
|
Logger::error("Failed to init settings");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-23 14:23:22 +01:00
|
|
|
void ParseSettings(PowerToysSettings::PowerToyValues& settings)
|
2021-05-20 15:07:34 +03:00
|
|
|
{
|
|
|
|
|
auto settingsObject = settings.get_raw_json();
|
|
|
|
|
if (settingsObject.GetView().Size())
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2021-09-23 14:23:22 +01:00
|
|
|
// Parse HotKey
|
2021-05-20 15:07:34 +03:00
|
|
|
auto jsonHotkeyObject = settingsObject.GetNamedObject(L"properties").GetNamedObject(L"open_shortcutguide");
|
|
|
|
|
auto hotkey = PowerToysSettings::HotkeyObject::from_json(jsonHotkeyObject);
|
|
|
|
|
m_hotkey = HotkeyEx();
|
|
|
|
|
if (hotkey.win_pressed())
|
|
|
|
|
{
|
|
|
|
|
m_hotkey.modifiersMask |= MOD_WIN;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (hotkey.ctrl_pressed())
|
|
|
|
|
{
|
|
|
|
|
m_hotkey.modifiersMask |= MOD_CONTROL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (hotkey.shift_pressed())
|
|
|
|
|
{
|
|
|
|
|
m_hotkey.modifiersMask |= MOD_SHIFT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (hotkey.alt_pressed())
|
|
|
|
|
{
|
|
|
|
|
m_hotkey.modifiersMask |= MOD_ALT;
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-17 16:24:56 +00:00
|
|
|
m_hotkey.vkCode = static_cast<WORD>(hotkey.get_code());
|
2021-05-20 15:07:34 +03:00
|
|
|
}
|
|
|
|
|
catch (...)
|
|
|
|
|
{
|
|
|
|
|
Logger::warn("Failed to initialize Shortcut Guide start shortcut");
|
|
|
|
|
}
|
[Shortcut Guide] Add Windows key hold activation options (#49661)
## Summary of the Pull Request
Adds configurable Windows-key hold activation to Shortcut Guide while
keeping the regular activation shortcut independent.
Users can choose to disable Windows-key activation, show taskbar
indicators, or open the full Shortcut Guide. Full-guide mode also
supports a configurable hold duration and optional close-on-release
behavior.
<img width="1099" height="611" alt="image"
src="https://github.com/user-attachments/assets/e0fe4c0f-3bef-43f8-a526-d22caf9e484e"
/>
## PR Checklist
- [ ] Closes: N/A
- [x] **Communication:** The UX and behavior were discussed before
implementation
- [x] **Tests:** Added/updated and all pass
- [x] **Localization:** All end-user-facing strings can be localized
- [x] **Dev docs:** Added/updated
- [ ] **New binaries:** Not applicable
- [ ] **Documentation updated:** Not applicable
## Detailed Description of the Pull Request / Additional comments
- Adds Off, taskbar-indicator, and full-guide Windows-key actions to
Settings.
- Adds a 100–5,000 ms hold-duration setting and a full-guide
close-on-release option.
- Handles left and right Windows keys and suppresses Start after an
activated hold.
- Routes Windows-key holds through a dedicated event so custom
activation shortcuts remain independent.
- Clears previous pressed-key registrations before refreshing them to
prevent duplicate long-press callbacks.
- Preserves compatibility with the existing `press_time` setting and
documents the new options.
## Validation Steps Performed
- Built the affected ARM64 Debug Settings, Runner, Shortcut Guide
module-interface, and Shortcut Guide UI projects.
- `ShortcutGuide.UnitTests`: 7/7 passed.
- Targeted Settings tests: 12/12 passed.
- Manually verified Off, taskbar-indicator, full-guide close-on-release,
and full-guide persistent modes.
- Verified configured hold thresholds, both Windows keys, Start
suppression, and regular-shortcut independence.
- Validated the final Settings XAML layout in the running Settings app.
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Muyuan Li (from Dev Box) <muyuanli@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2b3acca3-e49b-4936-8fb9-6f669bd449db
2026-08-13 22:27:39 +02:00
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
auto propertiesObject = settingsObject.GetNamedObject(L"properties");
|
|
|
|
|
if (propertiesObject.HasKey(L"press_time"))
|
|
|
|
|
{
|
|
|
|
|
auto jsonDurationObject = propertiesObject.GetNamedObject(L"press_time");
|
|
|
|
|
if (jsonDurationObject.HasKey(L"value"))
|
|
|
|
|
{
|
|
|
|
|
auto pressTime = static_cast<UINT>(jsonDurationObject.GetNamedNumber(L"value"));
|
|
|
|
|
if (pressTime < 100)
|
|
|
|
|
{
|
|
|
|
|
pressTime = 100;
|
|
|
|
|
}
|
|
|
|
|
else if (pressTime > 5000)
|
|
|
|
|
{
|
|
|
|
|
pressTime = 5000;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_millisecondsWinKeyPressTimeForGlobalWindowsShortcuts = pressTime;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (...) { /* Keep defaults */ }
|
2021-05-20 15:07:34 +03:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Logger::info("Shortcut Guide settings are empty");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!m_hotkey.modifiersMask)
|
|
|
|
|
{
|
|
|
|
|
Logger::info("Shortcut Guide is going to use default shortcut");
|
|
|
|
|
m_hotkey.modifiersMask = MOD_SHIFT | MOD_WIN;
|
|
|
|
|
m_hotkey.vkCode = VK_OEM_2;
|
|
|
|
|
}
|
|
|
|
|
}
|
Shortcut Guide: Replace dual windows with single transparent overlay and add holding windows button (#48683)
## Summary
Refactors Shortcut Guide from two separate `WindowEx` instances
(`MainWindow` + `TaskbarWindow`) into a single full-monitor transparent
`OverlayWindow` that hosts both surfaces as XAML UserControls. This
enables shared animations and a more polished visual experience, and
makes the taskbar shortcut indicators **edge-aware** for Windows 11's
top/bottom/left/right taskbar positioning.
https://github.com/user-attachments/assets/e40a25f6-4ab3-4073-b1a8-906ef7782877
<img width="507" height="968" alt="image"
src="https://github.com/user-attachments/assets/2e06a3d9-32d9-482e-90fe-1f0f8a7d7598"
/>
## Changes
Closes: #48435
Closes #48491
Closes: #49200
Closes: #48552 (theme flash on Light/System theme + shortcut-list scroll
flutter)
Closes: #48773
### Architecture
- **OverlayWindow**: Single transparent host covering the full monitor
work area, using `TransparentTintBackdrop`
- **MainPaneControl**: The shortcut list pseudo-window, reusing the
shared `TransientSurface` control for chrome (acrylic backdrop, theme
shadow, rounded corners)
- **TaskbarPaneControl + TaskbarIndicator**: Tooltip-style indicators
with triangle tails, positioned above taskbar buttons
### Edge-aware taskbar indicators (Windows 11 top/bottom/left/right)
- Detects the taskbar edge via the public, documented `SHAppBarMessage`
/ `ABM_GETTASKBARPOS` API (the same API CmdPal Dock uses)
- Indicators lay out along the correct axis — horizontally for a
top/bottom taskbar, vertically for a left/right taskbar — with the
triangle tail always pointing toward the taskbar (4-direction tail +
per-edge slide-in animation)
- For a left/right taskbar, the main pane is inset so the order reads
**taskbar | indicators | pane**
- **Adaptive sizing**: each indicator's body size is derived from the
actual measured UIA taskbar button rect, so the bubbles shrink when
Windows uses small icons or combines buttons (many apps open). Uses the
smallest button slot (clamped to a readable range) so neighbouring
bubbles never overlap; the font scales with it
### Visual polish
- Windows 11 system flyout entry/exit animations (slide + fade, ~367ms
entrance / ~200ms exit with cubic easing)
- Animation direction is position-aware (slides from left when
left-aligned, from right when right-aligned)
- Taskbar indicators slide in from the taskbar edge with the same timing
- Close button on the main flyout title bar
### Robustness
- Multi-monitor DPI handling via WM_DPICHANGED suppression (prevents
double-scaling on cross-monitor moves)
- Win11 phantom border elimination (comprehensive DWM/style stripping)
- Click-outside-to-close with animated exit transition
- Process lifetime fix (`Application.Current.Exit()` on close)
## Validation
- Build clean (x64 Debug, exit 0, empty errors log)
- Tested on multi-monitor mixed-DPI setup (150% + 100%)
- Tested with the taskbar docked to each edge (top/bottom/left/right)
and with small/combined taskbar icons
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Noraa Junker <noraa.junker@outlook.com>
Co-authored-by: Clint Rutkas <clint@rutkas.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-07-27 12:21:35 +02:00
|
|
|
|
|
|
|
|
void WindowsKeyPressBehavior()
|
|
|
|
|
{
|
|
|
|
|
if (IsProcessActive())
|
|
|
|
|
{
|
|
|
|
|
TerminateProcess(m_hProcess, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-05-20 15:07:34 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
extern "C" __declspec(dllexport) PowertoyModuleIface* __cdecl powertoy_create()
|
|
|
|
|
{
|
|
|
|
|
return new ShortcutGuideModule();
|
|
|
|
|
}
|