From 6d5cf02abd9c3db7d407445725e7df1b978c35d5 Mon Sep 17 00:00:00 2001 From: Samuel Attard Date: Thu, 8 Oct 2020 15:45:05 -0700 Subject: [PATCH] feat: add support for preventing the system context menu (#25795) --- docs/api/browser-window.md | 14 ++++++++++++++ shell/browser/api/electron_api_base_window.cc | 6 ++++++ shell/browser/api/electron_api_base_window.h | 1 + shell/browser/native_window.cc | 7 +++++++ shell/browser/native_window.h | 1 + shell/browser/native_window_observer.h | 1 + shell/browser/native_window_views_win.cc | 6 ++++++ 7 files changed, 36 insertions(+) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index e4ff8712e613..5c754618d6d0 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -667,6 +667,20 @@ Emitted when the window has closed a sheet. Emitted when the native new tab button is clicked. +#### Event: 'system-context-menu' _Windows_ + +Returns: + +* `event` Event +* `point` [Point](structures/point.md) - The screen coordinates the context menu was triggered at + +Emitted when the system context menu is triggered on the window, this is +normally only triggered when the user right clicks on the non-client area +of your window. This is the window titlebar or any area you have declared +as `-webkit-app-region: drag` in a frameless window. + +Calling `event.preventDefault()` will prevent the menu from being displayed. + ### Static Methods The `BrowserWindow` class has the following static methods: diff --git a/shell/browser/api/electron_api_base_window.cc b/shell/browser/api/electron_api_base_window.cc index 8a6756d44382..b93f7498c329 100644 --- a/shell/browser/api/electron_api_base_window.cc +++ b/shell/browser/api/electron_api_base_window.cc @@ -294,6 +294,12 @@ void BaseWindow::OnNewWindowForTab() { Emit("new-window-for-tab"); } +void BaseWindow::OnSystemContextMenu(int x, int y, bool* prevent_default) { + if (Emit("system-context-menu", gfx::Point(x, y))) { + *prevent_default = true; + } +} + #if defined(OS_WIN) void BaseWindow::OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) { if (IsWindowMessageHooked(message)) { diff --git a/shell/browser/api/electron_api_base_window.h b/shell/browser/api/electron_api_base_window.h index 9ca22f164721..a714e1017e39 100644 --- a/shell/browser/api/electron_api_base_window.h +++ b/shell/browser/api/electron_api_base_window.h @@ -82,6 +82,7 @@ class BaseWindow : public gin_helper::TrackableObject, void OnTouchBarItemResult(const std::string& item_id, const base::DictionaryValue& details) override; void OnNewWindowForTab() override; + void OnSystemContextMenu(int x, int y, bool* prevent_default) override; #if defined(OS_WIN) void OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) override; #endif diff --git a/shell/browser/native_window.cc b/shell/browser/native_window.cc index 152663f4f24e..9767c3a6f9dd 100644 --- a/shell/browser/native_window.cc +++ b/shell/browser/native_window.cc @@ -579,6 +579,13 @@ void NativeWindow::NotifyNewWindowForTab() { observer.OnNewWindowForTab(); } +void NativeWindow::NotifyWindowSystemContextMenu(int x, + int y, + bool* prevent_default) { + for (NativeWindowObserver& observer : observers_) + observer.OnSystemContextMenu(x, y, prevent_default); +} + #if defined(OS_WIN) void NativeWindow::NotifyWindowMessage(UINT message, WPARAM w_param, diff --git a/shell/browser/native_window.h b/shell/browser/native_window.h index a3a4babd1000..804e737f67b5 100644 --- a/shell/browser/native_window.h +++ b/shell/browser/native_window.h @@ -288,6 +288,7 @@ class NativeWindow : public base::SupportsUserData, void NotifyTouchBarItemInteraction(const std::string& item_id, const base::DictionaryValue& details); void NotifyNewWindowForTab(); + void NotifyWindowSystemContextMenu(int x, int y, bool* prevent_default); #if defined(OS_WIN) void NotifyWindowMessage(UINT message, WPARAM w_param, LPARAM l_param); diff --git a/shell/browser/native_window_observer.h b/shell/browser/native_window_observer.h index 92cada74f1c1..058c42084147 100644 --- a/shell/browser/native_window_observer.h +++ b/shell/browser/native_window_observer.h @@ -92,6 +92,7 @@ class NativeWindowObserver : public base::CheckedObserver { virtual void OnTouchBarItemResult(const std::string& item_id, const base::DictionaryValue& details) {} virtual void OnNewWindowForTab() {} + virtual void OnSystemContextMenu(int x, int y, bool* prevent_default) {} // Called when window message received #if defined(OS_WIN) diff --git a/shell/browser/native_window_views_win.cc b/shell/browser/native_window_views_win.cc index ac9d7fd2a4dc..66464e26bb83 100644 --- a/shell/browser/native_window_views_win.cc +++ b/shell/browser/native_window_views_win.cc @@ -306,6 +306,12 @@ 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; + } default: return false; }