mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
fix: dispatch ALT+SPACE keydown to renderer on Windows
Chromium's DesktopWindowTreeHostWin::HandleKeyEvent() intentionally drops ALT+SPACE keydown events so that the subsequent WM_SYSCHAR message can open the system menu. This means that when an Electron app listens for 'system-context-menu' and calls preventDefault(), the ALT+SPACE keydown never reaches the renderer and 'before-input-event' never fires. Override HandleKeyEvent() to intercept ALT+SPACE keydown and dispatch it via SendEventToSink() so it flows through the normal input pipeline to the renderer. The subsequent WM_SYSCHAR is still handled by HandleIMEMessage() to emit 'system-context-menu', preserving existing behavior for apps that don't prevent default.
This commit is contained in:
@@ -175,6 +175,24 @@ bool ElectronDesktopWindowTreeHostWin::HandleIMEMessage(UINT message,
|
||||
l_param, result);
|
||||
}
|
||||
|
||||
void ElectronDesktopWindowTreeHostWin::HandleKeyEvent(ui::KeyEvent* event) {
|
||||
// views::DesktopWindowTreeHostWin::HandleKeyEvent() discards ALT+SPACE
|
||||
// keydown events so WM_SYSCHAR can show the system menu. In Electron,
|
||||
// we want ALT+SPACE to be dispatched to the renderer so it fires keydown
|
||||
// events, particularly when the 'system-context-menu' event is
|
||||
// default-prevented. The subsequent WM_SYSCHAR is still handled by
|
||||
// HandleIMEMessage() to emit 'system-context-menu'.
|
||||
if ((event->type() == ui::EventType::kKeyPressed) &&
|
||||
(event->key_code() == ui::VKEY_SPACE) &&
|
||||
(event->flags() & ui::EF_ALT_DOWN) &&
|
||||
!(event->flags() & ui::EF_CONTROL_DOWN)) {
|
||||
SendEventToSink(event);
|
||||
return;
|
||||
}
|
||||
|
||||
views::DesktopWindowTreeHostWin::HandleKeyEvent(event);
|
||||
}
|
||||
|
||||
void ElectronDesktopWindowTreeHostWin::HandleVisibilityChanged(bool visible) {
|
||||
if (native_window_view_->widget())
|
||||
native_window_view_->widget()->OnNativeWidgetVisibilityChanged(visible);
|
||||
|
||||
@@ -48,6 +48,7 @@ class ElectronDesktopWindowTreeHostWin : public views::DesktopWindowTreeHostWin,
|
||||
WPARAM w_param,
|
||||
LPARAM l_param,
|
||||
LRESULT* result) override;
|
||||
void HandleKeyEvent(ui::KeyEvent* event) override;
|
||||
void HandleVisibilityChanged(bool visible) override;
|
||||
void SetAllowScreenshots(bool allow) override;
|
||||
void Restore() override;
|
||||
|
||||
@@ -2568,6 +2568,32 @@ describe('BrowserWindow module', () => {
|
||||
});
|
||||
});
|
||||
|
||||
ifdescribe(process.platform === 'win32')('BrowserWindow system-context-menu', () => {
|
||||
it('dispatches the keyboard event to the renderer if prevented', async () => {
|
||||
const w = new BrowserWindow({
|
||||
show: false,
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
contextIsolation: false
|
||||
}
|
||||
});
|
||||
|
||||
w.once('system-context-menu', (evt) => {
|
||||
evt.preventDefault();
|
||||
});
|
||||
|
||||
await w.loadFile(path.join(fixtures, 'pages', 'keydown-alt-space.html'));
|
||||
|
||||
const altSpace = once(ipcMain, 'alt-space-renderer');
|
||||
|
||||
// Simulate Alt+Space to create system-context-menu event.
|
||||
w.webContents.sendInputEvent({ type: 'keyDown', keyCode: 'Space', modifiers: ['alt'] });
|
||||
w.webContents.sendInputEvent({ type: 'keyUp', keyCode: 'Space', modifiers: ['alt'] });
|
||||
|
||||
await altSpace;
|
||||
});
|
||||
});
|
||||
|
||||
ifdescribe(process.platform === 'win32')('BrowserWindow.{get|set}AccentColor', () => {
|
||||
afterEach(closeAllWindows);
|
||||
|
||||
|
||||
15
spec/fixtures/pages/keydown-alt-space.html
vendored
Normal file
15
spec/fixtures/pages/keydown-alt-space.html
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<html>
|
||||
|
||||
<body>
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
const { ipcRenderer } = require('electron');
|
||||
|
||||
document.addEventListener("keydown", (e) => {
|
||||
if (e.key === " " && e.altKey) {
|
||||
ipcRenderer.send('alt-space-renderer');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user