From a1ec212049d5593f38c3f89cc0986f30e489c211 Mon Sep 17 00:00:00 2001 From: "trop[bot]" <37223003+trop[bot]@users.noreply.github.com> Date: Fri, 14 Mar 2025 09:54:21 -0500 Subject: [PATCH] fix: emit `context-menu` event in Windows draggable regions (#46032) fix: emit context-menu event in Windows draggable regions Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com> Co-authored-by: Shelley Vohr --- shell/browser/native_window_views_win.cc | 20 +++++++++++++++---- .../electron_desktop_window_tree_host_win.cc | 7 +++++++ spec/api-web-contents-spec.ts | 7 ++++++- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/shell/browser/native_window_views_win.cc b/shell/browser/native_window_views_win.cc index a08d347c3b19..04016b304c88 100644 --- a/shell/browser/native_window_views_win.cc +++ b/shell/browser/native_window_views_win.cc @@ -10,6 +10,7 @@ #include "base/win/scoped_handle.h" #include "base/win/windows_version.h" #include "content/public/browser/browser_accessibility_state.h" +#include "shell/browser/api/electron_api_web_contents.h" #include "shell/browser/browser.h" #include "shell/browser/native_window_views.h" #include "shell/browser/ui/views/root_view.h" @@ -288,6 +289,11 @@ bool NativeWindowViews::PreHandleMSG(UINT message, return false; } + case WM_RBUTTONUP: { + if (!has_frame()) + electron::api::WebContents::SetDisableDraggableRegions(false); + return false; + } case WM_GETMINMAXINFO: { WINDOWPLACEMENT wp; wp.length = sizeof(WINDOWPLACEMENT); @@ -411,10 +417,16 @@ bool NativeWindowViews::PreHandleMSG(UINT message, return false; } case WM_CONTEXTMENU: { - bool prevent_default = false; - NotifyWindowSystemContextMenu(GET_X_LPARAM(l_param), - GET_Y_LPARAM(l_param), &prevent_default); - return prevent_default; + // We don't want to trigger system-context-menu here if we have a + // frameless window as it'll already be emitted in + // ElectronDesktopWindowTreeHostWin::HandleMouseEvent. + if (has_frame()) { + bool prevent_default = false; + NotifyWindowSystemContextMenu(GET_X_LPARAM(l_param), + GET_Y_LPARAM(l_param), &prevent_default); + return prevent_default; + } + return false; } case WM_SYSCOMMAND: { // Mask is needed to account for double clicking title bar to maximize diff --git a/shell/browser/ui/win/electron_desktop_window_tree_host_win.cc b/shell/browser/ui/win/electron_desktop_window_tree_host_win.cc index b2c5f07ccf50..ac4ffc26e0dd 100644 --- a/shell/browser/ui/win/electron_desktop_window_tree_host_win.cc +++ b/shell/browser/ui/win/electron_desktop_window_tree_host_win.cc @@ -6,6 +6,7 @@ #include "base/win/windows_version.h" #include "electron/buildflags/buildflags.h" +#include "shell/browser/api/electron_api_web_contents.h" #include "shell/browser/native_window_views.h" #include "shell/browser/ui/views/win_frame_view.h" #include "shell/browser/win/dark_mode.h" @@ -113,6 +114,12 @@ bool ElectronDesktopWindowTreeHostWin::HandleMouseEvent(ui::MouseEvent* event) { bool prevent_default = false; native_window_view_->NotifyWindowSystemContextMenu(event->x(), event->y(), &prevent_default); + // If the user prevents default behavior, emit contextmenu event to + // allow bringing up the custom menu. + if (prevent_default) { + electron::api::WebContents::SetDisableDraggableRegions(true); + views::DesktopWindowTreeHostWin::HandleMouseEvent(event); + } return prevent_default; } diff --git a/spec/api-web-contents-spec.ts b/spec/api-web-contents-spec.ts index aa2c7d529745..52883991d32c 100644 --- a/spec/api-web-contents-spec.ts +++ b/spec/api-web-contents-spec.ts @@ -2896,8 +2896,13 @@ describe('webContents module', () => { expect(contextMenuEmitCount).to.equal(1); }); - ifit(process.platform !== 'win32')('emits when right-clicked in page in a draggable region', async () => { + it('emits when right-clicked in page in a draggable region', async () => { const w = new BrowserWindow({ show: false }); + + if (process.platform === 'win32') { + w.on('system-context-menu', (event) => { event.preventDefault(); }); + } + await w.loadFile(path.join(fixturesPath, 'pages', 'draggable-page.html')); const promise = once(w.webContents, 'context-menu') as Promise<[any, Electron.ContextMenuParams]>;