Repository: electron/electron
Pull request: fix: updated Alt detection to explicitly exclude AltGraph/AltGr

Backport of #49778

See that PR for details.


Notes: Fixed an issue where pressing AltGr could activate or focus the menu bar. 

Changed files:
filename: shell/browser/ui/views/root_view.cc
patch: @@ -9,6 +9,7 @@
 #include "components/input/native_web_keyboard_event.h"
 #include "shell/browser/native_window.h"
 #include "shell/browser/ui/views/menu_bar.h"
+#include "ui/events/keycodes/dom/keycode_converter.h"
 #include "ui/views/layout/box_layout.h"
 
 namespace electron {
@@ -21,9 +22,21 @@ bool IsAltKey(const input::NativeWebKeyboardEvent& event) {
 
 bool IsAltModifier(const input::NativeWebKeyboardEvent& event) {
   using Mods = input::NativeWebKeyboardEvent::Modifiers;
+
+  // AltGraph (AltGr) should not be treated as a single Alt keypress for
+  // menu-bar toggling.
+  if (event.windows_key_code == ui::VKEY_ALTGR ||
+      ui::KeycodeConverter::DomKeyToKeyString(event.dom_key) == "AltGraph") {
+    return false;
+  }
+
   return (event.GetModifiers() & Mods::kKeyModifiers) == Mods::kAltKey;
 }
 
+bool IsSingleAltKey(const input::NativeWebKeyboardEvent& event) {
+  return IsAltKey(event) && IsAltModifier(event);
+}
+
 }  // namespace
 
 RootView::RootView(NativeWindow* window)
@@ -98,7 +111,7 @@ void RootView::HandleKeyEvent(const input::NativeWebKeyboardEvent& event) {
     return;
 
   // Show accelerator when "Alt" is pressed.
-  if (menu_bar_visible_ && IsAltKey(event))
+  if (menu_bar_visible_ && IsSingleAltKey(event))
     menu_bar_->SetAcceleratorVisibility(
         event.GetType() == blink::WebInputEvent::Type::kRawKeyDown);
 
@@ -121,11 +134,11 @@ void RootView::HandleKeyEvent(const input::NativeWebKeyboardEvent& event) {
 
   // Toggle the menu bar only when a single Alt is released.
   if (event.GetType() == blink::WebInputEvent::Type::kRawKeyDown &&
-      IsAltKey(event)) {
+      IsSingleAltKey(event)) {
     // When a single Alt is pressed:
     menu_bar_alt_pressed_ = true;
   } else if (event.GetType() == blink::WebInputEvent::Type::kKeyUp &&
-             IsAltKey(event) && menu_bar_alt_pressed_) {
+             IsSingleAltKey(event) && menu_bar_alt_pressed_) {
     // When a single Alt is released right after a Alt is pressed:
     menu_bar_alt_pressed_ = false;
     if (menu_bar_autohide_)

filename: spec/api-browser-window-spec.ts
patch: @@ -5888,6 +5888,23 @@ describe('BrowserWindow module', () => {
       });
     });
 
+    ifdescribe(process.platform === 'linux')('menu bar AltGr behavior', () => {
+      it('does not toggle auto-hide menu bar visibility', async () => {
+        const w = new BrowserWindow({ show: false, autoHideMenuBar: true });
+        w.setMenuBarVisibility(false);
+        expect(w.isMenuBarVisible()).to.be.false('isMenuBarVisible');
+
+        w.show();
+        await once(w, 'show');
+        w.webContents.focus();
+        w.webContents.sendInputEvent({ type: 'keyDown', keyCode: 'AltGr' });
+        w.webContents.sendInputEvent({ type: 'keyUp', keyCode: 'AltGr' });
+        await setTimeout();
+
+        expect(w.isMenuBarVisible()).to.be.false('isMenuBarVisible');
+      });
+    });
+
     ifdescribe(process.platform !== 'darwin')('when fullscreen state is changed', () => {
       it('correctly remembers state prior to fullscreen change', async () => {
         const w = new BrowserWindow({ show: false });