From 086c63b6af99f5c700a18625147a789e4cd176ef Mon Sep 17 00:00:00 2001
From: Shawn Yuan <128874481+shuaiyuanxx@users.noreply.github.com>
Date: Fri, 23 Jan 2026 14:47:35 +0800
Subject: [PATCH] [Settings] Fix right click menu display issue (#44982)
## Summary of the Pull Request
This pull request updates the tray icon context menu logic to better
reflect the state of the "Quick Access" feature. The menu now
dynamically updates its items and labels based on whether Quick Access
is enabled or disabled, improving clarity for users.
**Menu behavior improvements:**
* The tray icon menu now reloads itself when the Quick Access setting
changes, ensuring the menu always matches the current state.
* The "Settings" menu item label changes to "Settings\tLeft-click" when
Quick Access is disabled, providing clearer instructions to users.
[[1]](diffhunk://#diff-e5efbda4c356e159a6ca82a425db84438ab4014d1d90377b98a2eb6d9632d32dR176-R179)
[[2]](diffhunk://#diff-7139ecb2cf76e472c574a155268c19e919e2cce05d9d345c50c1f1bffc939e1aR198-R248)
* The Quick Access menu item is removed from the context menu when the
feature is disabled, preventing confusion.
**Internal state tracking:**
* Added a new variable `last_quick_access_state` to track the previous
Quick Access state and trigger menu reloads only when necessary.
## PR Checklist
- [x] Closes: #44810
- [x] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [x] **Tests:** Added/updated and all pass
- [x] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx
## Detailed Description of the Pull Request / Additional comments
- When Quick Access is disabled
- When Quick Access is enabled
## Validation Steps Performed
---
.github/actions/spell-check/expect.txt | 1 +
src/runner/Resources.resx | 4 +++
src/runner/tray_icon.cpp | 37 +++++++++++++++++++++++++-
3 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt
index e8a15d52d2..b622870905 100644
--- a/.github/actions/spell-check/expect.txt
+++ b/.github/actions/spell-check/expect.txt
@@ -886,6 +886,7 @@ Ldr
LEFTALIGN
LEFTSCROLLBAR
LEFTTEXT
+leftclick
LError
LEVELID
LExit
diff --git a/src/runner/Resources.resx b/src/runner/Resources.resx
index c8eb5f25cc..b94f84714e 100644
--- a/src/runner/Resources.resx
+++ b/src/runner/Resources.resx
@@ -173,6 +173,10 @@
Settings\tDouble-click
Don't localize "\t" as that is what separates the click portion to be right aligned in the menu.
+
+ Settings\tLeft-click
+ Don't localize "\t" as that is what separates the click portion to be right aligned in the menu. This is shown when Quick Access is disabled.
+
Documentation
diff --git a/src/runner/tray_icon.cpp b/src/runner/tray_icon.cpp
index 8fa892e312..d8684da5d0 100644
--- a/src/runner/tray_icon.cpp
+++ b/src/runner/tray_icon.cpp
@@ -40,6 +40,7 @@ namespace
bool double_click_timer_running = false;
bool double_clicked = false;
POINT tray_icon_click_point;
+ std::optional last_quick_access_state; // Track the last known Quick Access state
static ThemeListener theme_listener;
static bool theme_adaptive_enabled = false;
@@ -195,6 +196,18 @@ LRESULT __stdcall tray_icon_window_proc(HWND window, UINT message, WPARAM wparam
case WM_RBUTTONUP:
case WM_CONTEXTMENU:
{
+ bool quick_access_enabled = get_general_settings().enableQuickAccess;
+
+ // Reload menu if Quick Access state has changed or is first time
+ if (h_menu && (!last_quick_access_state.has_value() || quick_access_enabled != last_quick_access_state.value()))
+ {
+ DestroyMenu(h_menu);
+ h_menu = nullptr;
+ h_sub_menu = nullptr;
+ }
+
+ last_quick_access_state = quick_access_enabled;
+
if (!h_menu)
{
h_menu = LoadMenu(reinterpret_cast(&__ImageBase), MAKEINTRESOURCE(ID_TRAY_MENU));
@@ -202,17 +215,39 @@ LRESULT __stdcall tray_icon_window_proc(HWND window, UINT message, WPARAM wparam
if (h_menu)
{
static std::wstring settings_menuitem_label = GET_RESOURCE_STRING(IDS_SETTINGS_MENU_TEXT);
+ static std::wstring settings_menuitem_label_leftclick = GET_RESOURCE_STRING(IDS_SETTINGS_MENU_TEXT_LEFTCLICK);
static std::wstring close_menuitem_label = GET_RESOURCE_STRING(IDS_CLOSE_MENU_TEXT);
static std::wstring submit_bug_menuitem_label = GET_RESOURCE_STRING(IDS_SUBMIT_BUG_TEXT);
static std::wstring documentation_menuitem_label = GET_RESOURCE_STRING(IDS_DOCUMENTATION_MENU_TEXT);
static std::wstring quick_access_menuitem_label = GET_RESOURCE_STRING(IDS_QUICK_ACCESS_MENU_TEXT);
- change_menu_item_text(ID_SETTINGS_MENU_COMMAND, settings_menuitem_label.data());
+
+ // Update Settings menu text based on Quick Access state
+ if (quick_access_enabled)
+ {
+ change_menu_item_text(ID_SETTINGS_MENU_COMMAND, settings_menuitem_label.data());
+ }
+ else
+ {
+ change_menu_item_text(ID_SETTINGS_MENU_COMMAND, settings_menuitem_label_leftclick.data());
+ }
+
change_menu_item_text(ID_CLOSE_MENU_COMMAND, close_menuitem_label.data());
change_menu_item_text(ID_REPORT_BUG_COMMAND, submit_bug_menuitem_label.data());
bool bug_report_disabled = is_bug_report_running();
EnableMenuItem(h_sub_menu, ID_REPORT_BUG_COMMAND, MF_BYCOMMAND | (bug_report_disabled ? MF_GRAYED : MF_ENABLED));
change_menu_item_text(ID_DOCUMENTATION_MENU_COMMAND, documentation_menuitem_label.data());
change_menu_item_text(ID_QUICK_ACCESS_MENU_COMMAND, quick_access_menuitem_label.data());
+
+ // Hide or show Quick Access menu item based on setting
+ if (!h_sub_menu)
+ {
+ h_sub_menu = GetSubMenu(h_menu, 0);
+ }
+ if (!quick_access_enabled)
+ {
+ // Remove Quick Access menu item when disabled
+ DeleteMenu(h_sub_menu, ID_QUICK_ACCESS_MENU_COMMAND, MF_BYCOMMAND);
+ }
}
if (!h_sub_menu)
{