Skip to content

Commit f83f776

Browse files
Revert "fix: do not use CONTEXT_MENU flag for tray menu (electron#23897)" (electron#24080)
This reverts commit 91dfa1e.
1 parent c77c902 commit f83f776

File tree

2 files changed

+40
-6
lines changed

2 files changed

+40
-6
lines changed

shell/browser/ui/win/notify_icon.cc

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,16 @@
1717
#include "ui/gfx/geometry/rect.h"
1818
#include "ui/gfx/image/image.h"
1919
#include "ui/views/controls/menu/menu_runner.h"
20+
#include "ui/views/widget/widget.h"
2021

2122
namespace electron {
2223

2324
NotifyIcon::NotifyIcon(NotifyIconHost* host, UINT id, HWND window, UINT message)
24-
: host_(host), icon_id_(id), window_(window), message_id_(message) {
25+
: host_(host),
26+
icon_id_(id),
27+
window_(window),
28+
message_id_(message),
29+
weak_factory_(this) {
2530
NOTIFYICONDATA icon_data;
2631
InitIconData(&icon_data);
2732
icon_data.uFlags |= NIF_MESSAGE;
@@ -155,10 +160,26 @@ void NotifyIcon::PopUpContextMenu(const gfx::Point& pos,
155160
if (pos.IsOrigin())
156161
rect.set_origin(display::Screen::GetScreen()->GetCursorScreenPoint());
157162

158-
menu_runner_.reset(
159-
new views::MenuRunner(menu_model != nullptr ? menu_model : menu_model_,
160-
views::MenuRunner::HAS_MNEMONICS));
161-
menu_runner_->RunMenuAt(nullptr, nullptr, rect,
163+
// Create a widget for the menu, otherwise we get no keyboard events, which
164+
// is required for accessibility.
165+
widget_.reset(new views::Widget());
166+
views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
167+
params.ownership =
168+
views::Widget::InitParams::Ownership::WIDGET_OWNS_NATIVE_WIDGET;
169+
params.bounds = gfx::Rect(0, 0, 0, 0);
170+
params.force_software_compositing = true;
171+
params.z_order = ui::ZOrderLevel::kFloatingUIElement;
172+
173+
widget_->Init(std::move(params));
174+
175+
widget_->Show();
176+
widget_->Activate();
177+
menu_runner_.reset(new views::MenuRunner(
178+
menu_model != nullptr ? menu_model : menu_model_,
179+
views::MenuRunner::CONTEXT_MENU | views::MenuRunner::HAS_MNEMONICS,
180+
base::BindRepeating(&NotifyIcon::OnContextMenuClosed,
181+
weak_factory_.GetWeakPtr())));
182+
menu_runner_->RunMenuAt(widget_.get(), NULL, rect,
162183
views::MenuAnchorPosition::kTopLeft,
163184
ui::MENU_SOURCE_MOUSE);
164185
}
@@ -186,4 +207,8 @@ void NotifyIcon::InitIconData(NOTIFYICONDATA* icon_data) {
186207
icon_data->uID = icon_id_;
187208
}
188209

210+
void NotifyIcon::OnContextMenuClosed() {
211+
widget_->Close();
212+
}
213+
189214
} // namespace electron

shell/browser/ui/win/notify_icon.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "base/compiler_specific.h"
1616
#include "base/macros.h"
17+
#include "base/memory/weak_ptr.h"
1718
#include "base/win/scoped_gdi_object.h"
1819
#include "shell/browser/ui/tray_icon.h"
1920

@@ -23,7 +24,8 @@ class Point;
2324

2425
namespace views {
2526
class MenuRunner;
26-
}
27+
class Widget;
28+
} // namespace views
2729

2830
namespace electron {
2931

@@ -66,6 +68,7 @@ class NotifyIcon : public TrayIcon {
6668

6769
private:
6870
void InitIconData(NOTIFYICONDATA* icon_data);
71+
void OnContextMenuClosed();
6972

7073
// The tray that owns us. Weak.
7174
NotifyIconHost* host_;
@@ -88,6 +91,12 @@ class NotifyIcon : public TrayIcon {
8891
// Context menu associated with this icon (if any).
8992
std::unique_ptr<views::MenuRunner> menu_runner_;
9093

94+
// Temporary widget for the context menu, needed for keyboard event capture.
95+
std::unique_ptr<views::Widget> widget_;
96+
97+
// WeakPtrFactory for CloseClosure safety.
98+
base::WeakPtrFactory<NotifyIcon> weak_factory_;
99+
91100
DISALLOW_COPY_AND_ASSIGN(NotifyIcon);
92101
};
93102

0 commit comments

Comments
 (0)