Skip to content

Commit fd0eb6c

Browse files
fix: shouldn't send WM_COMMAND if TPM_RETURNCMD
close #308 close #198 close #243 close #264 #313
1 parent b61e240 commit fd0eb6c

1 file changed

Lines changed: 55 additions & 18 deletions

File tree

src/shell/contextmenu/hooks.cc

Lines changed: 55 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
#include "Windows.h"
22
#include "shlobj_core.h"
33

4-
#include "hooks.h"
54
#include "blook/memo.h"
65
#include "breeze-js/quickjspp.hpp"
76
#include "contextmenu.h"
7+
#include "hooks.h"
88
#include "menu_render.h"
99
#include "menu_widget.h"
1010
#include "nanovg.h"
@@ -15,13 +15,13 @@
1515
#include "blook/blook.h"
1616
#include <atlcomcli.h>
1717
#include <atomic>
18-
#include <mutex>
1918
#include <memory>
19+
#include <mutex>
2020
#include <shobjidl_core.h>
2121
#include <spdlog/spdlog.h>
2222
#include <string>
2323
#include <thread>
24-
24+
#include <unordered_map>
2525

2626
std::atomic_int mb_shell::context_menu_hooks::block_js_reload = 0;
2727

@@ -90,9 +90,8 @@ query_native_menu_item_identity(HMENU hMenu, UINT item, BOOL fByPosition) {
9090
auto text_length = GetMenuStringW(hMenu, item, nullptr, 0, flags);
9191
if (text_length > 0) {
9292
std::wstring buffer(text_length + 1, L'\0');
93-
auto copied =
94-
GetMenuStringW(hMenu, item, buffer.data(),
95-
static_cast<int>(buffer.size()), flags);
93+
auto copied = GetMenuStringW(hMenu, item, buffer.data(),
94+
static_cast<int>(buffer.size()), flags);
9695
buffer.resize(std::max(0, copied));
9796
if (!buffer.empty()) {
9897
result.origin_name = mb_shell::wstring_to_utf8(buffer);
@@ -126,8 +125,7 @@ collect_matching_menu_items(
126125
return matches;
127126
}
128127

129-
std::shared_ptr<mb_shell::menu_item_widget>
130-
find_menu_item_widget_by_identity(
128+
std::shared_ptr<mb_shell::menu_item_widget> find_menu_item_widget_by_identity(
131129
const std::shared_ptr<mb_shell::menu_widget> &menu,
132130
const native_menu_item_identity &identity) {
133131
if (identity.wid) {
@@ -141,10 +139,11 @@ find_menu_item_widget_by_identity(
141139
}
142140
}
143141

144-
const auto matches_name = [&](const mb_shell::menu_item_widget &item_widget)
145-
-> bool {
142+
const auto matches_name =
143+
[&](const mb_shell::menu_item_widget &item_widget) -> bool {
146144
if (identity.origin_name && item_widget.item.origin_name &&
147-
item_widget.item.origin_name.value() == identity.origin_name.value()) {
145+
item_widget.item.origin_name.value() ==
146+
identity.origin_name.value()) {
148147
return true;
149148
}
150149

@@ -154,10 +153,9 @@ find_menu_item_widget_by_identity(
154153
}
155154

156155
if (identity.name && item_widget.item.origin_name) {
157-
auto stripped =
158-
mb_shell::wstring_to_utf8(strip_menu_item_text(
159-
mb_shell::utf8_to_wstring(
160-
item_widget.item.origin_name.value())));
156+
auto stripped = mb_shell::wstring_to_utf8(
157+
strip_menu_item_text(mb_shell::utf8_to_wstring(
158+
item_widget.item.origin_name.value())));
161159
return stripped == identity.name.value();
162160
}
163161

@@ -380,10 +378,12 @@ mb_shell::track_popup_menu(mb_shell::menu menu, int x, int y,
380378
explicit live_menu_guard(HMENU hMenu) {
381379
current_live_menu_handle.store(hMenu,
382380
std::memory_order_relaxed);
383-
mb_shell::context_menu_hooks::clear_active_root_menu_widget();
381+
mb_shell::context_menu_hooks::
382+
clear_active_root_menu_widget();
384383
}
385384
~live_menu_guard() {
386-
mb_shell::context_menu_hooks::clear_active_root_menu_widget();
385+
mb_shell::context_menu_hooks::
386+
clear_active_root_menu_widget();
387387
current_live_menu_handle.store(nullptr,
388388
std::memory_order_relaxed);
389389
}
@@ -458,6 +458,42 @@ void mb_shell::context_menu_hooks::install_NtUserTrackPopupMenuEx_hook() {
458458
y, hWnd, lptpm);
459459
}
460460

461+
static std::unordered_map<int, std::string_view> FLAGS_MAP{
462+
{TPM_CENTERALIGN, "TPM_CENTERALIGN"},
463+
{TPM_LEFTALIGN, "TPM_LEFTALIGN"},
464+
{TPM_RIGHTALIGN, "TPM_RIGHTALIGN"},
465+
{TPM_BOTTOMALIGN, "TPM_BOTTOMALIGN"},
466+
{TPM_TOPALIGN, "TPM_TOPALIGN"},
467+
{TPM_VCENTERALIGN, "TPM_VCENTERALIGN"},
468+
{TPM_NONOTIFY, "TPM_NONOTIFY"},
469+
{TPM_RETURNCMD, "TPM_RETURNCMD"},
470+
{TPM_LEFTBUTTON, "TPM_LEFTBUTTON"},
471+
{TPM_RIGHTBUTTON, "TPM_RIGHTBUTTON"},
472+
{TPM_HORNEGANIMATION, "TPM_HORNEGANIMATION"},
473+
{TPM_HORPOSANIMATION, "TPM_HORPOSANIMATION"},
474+
{TPM_NOANIMATION, "TPM_NOANIMATION"},
475+
{TPM_VERNEGANIMATION, "TPM_VERNEGANIMATION"},
476+
{TPM_VERPOSANIMATION, "TPM_VERPOSANIMATION"},
477+
};
478+
479+
spdlog::info(
480+
"TrackPopupMenuEx called (hMenu={}, flags=0x{:x}({}), x={}, y={}, "
481+
"hWnd={}, lptpm={})",
482+
(void *)hMenu, uFlags,
483+
[](int64_t flags) {
484+
std::string result;
485+
for (const auto &[flag, name] : FLAGS_MAP) {
486+
if (flags & flag) {
487+
if (!result.empty()) {
488+
result += " | ";
489+
}
490+
result += name;
491+
}
492+
}
493+
return result;
494+
}(uFlags),
495+
x, y, (void *)hWnd, lptpm);
496+
461497
entry::main_window_loop_hook.install(hWnd);
462498
block_js_reload.fetch_add(1);
463499

@@ -466,7 +502,8 @@ void mb_shell::context_menu_hooks::install_NtUserTrackPopupMenuEx_hook() {
466502
perf.end("construct_with_hmenu");
467503

468504
auto selected_menu = track_popup_menu(menu, x, y);
469-
if (selected_menu && !(uFlags & TPM_NONOTIFY)) {
505+
if (selected_menu && !(uFlags & TPM_NONOTIFY) &&
506+
!(uFlags & TPM_RETURNCMD) && hWnd) {
470507
PostMessageW(hWnd, WM_COMMAND, *selected_menu, 0);
471508
PostMessageW(hWnd, WM_NULL, 0, 0);
472509
}

0 commit comments

Comments
 (0)