Bug: click areas out of menu would triggers `MBTN_LEFT`
dyphire opened this issue · comments
I can't find a regular way to resolve it well.
Although I can set a flag before menu open, but it's pretty tricky.
- The event that trigger menu close may be mouse click(inside window or outside the window) or a key (
ESC
), or other? - TrackPopupMenuEx will not return until menu close (should be running it's own event loop), there's no good way to distinguish the event source.
As a workaround you can include an empty command in the menu, clicking it closes the menu.
Keyboard is the usual way to dismiss the menu with Esc or Alt.
I can't find a regular way to resolve it well.
Although I can set a flag before menu open, but it's pretty tricky.
- The event that trigger menu close may be mouse click(inside window or outside the window) or a key (), or other?
ESC
- TrackPopupMenuEx will not return until menu close (should be running it's own event loop), there's no good way to distinguish the event source.
The real problem here is that it blocks the mpv keybinding when the menu is opened, and triggers the event of closing the menu when the left mouse button is clicked; After the menu is closed, it will continue to forward mouse events to trigger the mpv predetermined keybinding function. If we can prevent forwarding left mouse button events when the menu is closed, it will fix this issue.
I've checked on native windows video players, and the way they handle it is: when menu is open: block player left-click command and bind it to dismiss menu.
I use left-click to toggle play/pause.
How about replacing MBTN event's command when menu open and reversing it when menu closing?
Well, it's working now (EDIT: not always working, because script message is async).
--- a/lua/dyn_menu.lua
+++ b/lua/dyn_menu.lua
@@ -477,6 +477,14 @@ mp.register_script_message('update', function(keyword, json)
menu_items_dirty = true
end)
+mp.register_script_message('menu-open', function()
+ mp.add_forced_key_binding('MBTN_LEFT', 'click_ignore')
+end)
+
+mp.register_script_message('menu-close', function()
+ mp.remove_key_binding('click_ignore')
+end)
+
-- commit menu items when idle, this reduces the update frequency
mp.register_idle(function()
if menu_items_dirty then
diff --git a/src/menu.c b/src/menu.c
index 8cc553d..665d5df 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -266,8 +266,10 @@ void show_menu(plugin_ctx *ctx, POINT *pt) {
if (!PtInRect(&rc, *pt)) return;
ClientToScreen(ctx->hwnd, pt);
+ mpv_command(ctx->mpv, (const char *[]){"script-message", "menu-open", NULL});
TrackPopupMenuEx(ctx->hmenu, TPM_LEFTALIGN | TPM_LEFTBUTTON, pt->x, pt->y,
ctx->hwnd, NULL);
+ mpv_command(ctx->mpv, (const char *[]){"script-message", "menu-close", NULL});
}
because script message is async
I think the reason is that the event is deferred. Works fine to me with additional timeout.
because script message is async
I think the reason is that the event is deferred. Works fine to me with additional timeout.
I can confirm that it works.
I've added the menu-open
and menu-close
message to the C plugin, you may want to patch it yourself.