Skip to content

Commit

Permalink
Edge: Implement ICoreWebView2Controller#add_AcceleratorKeyPressed()
Browse files Browse the repository at this point in the history
The ICoreWebView2AcceleratorKeyPressedEvent does not give us all key
events and is therefore much less complete than the IE.handleDOMEvent()
equivalent.

But at least this allows us to react on VK_ESCAPE (allowing e.g. element
info popups to be closed via ESC) and other typical key combos like
Ctrl-N, etc.
  • Loading branch information
sratz committed Aug 15, 2024
1 parent 8aec5fc commit 248ab17
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,9 @@ public void create(Composite parent, int style) {
handler = newCallback(this::handleGotFocus);
controller.add_GotFocus(handler, token);
handler.Release();
handler = newCallback(this::handleAcceleratorKeyPressed);
controller.add_AcceleratorKeyPressed(handler, token);
handler.Release();
if (webView_2 != null) {
handler = newCallback(this::handleDOMContentLoaded);
webView_2.add_DOMContentLoaded(handler, token);
Expand Down Expand Up @@ -794,6 +797,63 @@ int handleGotFocus(long pView, long pArg) {
return COM.S_OK;
}

/**
* Events are not fired for all keyboard shortcuts.
* <ul>
* <li>Events for ctrl, alt modifiers are sent, but not for shift. So we use
* GetKeyState() to read modifier keys consistently and don't send out any
* events for the modifier-only events themselves.
* <li>We are missing some other keys (e.g. VK_TAB or VK_RETURN, unless modified
* by ctrl or alt).
* </ul>
* This is a best-effort implementation oriented towards
* {@link IE#handleDOMEvent(org.eclipse.swt.ole.win32.OleEvent)}.
*
* @see <a href=
* "https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2controller">https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2controller</a>
*/
int handleAcceleratorKeyPressed(long pView, long pArgs) {
ICoreWebView2AcceleratorKeyPressedEventArgs args = new ICoreWebView2AcceleratorKeyPressedEventArgs(pArgs);
int[] virtualKey = new int[1];
args.get_VirtualKey(virtualKey);
int[] lparam = new int[1];
args.get_KeyEventLParam(lparam);
long flags = Integer.toUnsignedLong(lparam[0]) >> 16;
boolean isDown = (flags & 0x8000) == 0;

if (virtualKey[0] == OS.VK_SHIFT || virtualKey[0] == OS.VK_CONTROL || virtualKey[0] == OS.VK_MENU) {
return COM.S_OK;
}

Event keyEvent = new Event ();
keyEvent.widget = browser;
keyEvent.keyCode = translateKey(virtualKey[0]);
if (OS.GetKeyState (OS.VK_MENU) < 0) keyEvent.stateMask |= SWT.ALT;
if (OS.GetKeyState (OS.VK_SHIFT) < 0) keyEvent.stateMask |= SWT.SHIFT;
if (OS.GetKeyState (OS.VK_CONTROL) < 0) keyEvent.stateMask |= SWT.CONTROL;

if (isDown) {
keyEvent.type = SWT.KeyDown;
// Ignore repeated events while key is pressed
boolean isRepeat = (flags & 0x4000) != 0;
if (isRepeat) {
return COM.S_OK;
}

if (!sendKeyEvent(keyEvent)) {
args.put_Handled(true);
}
} else {
keyEvent.type = SWT.KeyUp;
browser.notifyListeners (keyEvent.type, keyEvent);
if (!keyEvent.doit) {
args.put_Handled(true);
}
}

return COM.S_OK;
}

int handleMoveFocusRequested(long pView, long pArgs) {
ICoreWebView2MoveFocusRequestedEventArgs args = new ICoreWebView2MoveFocusRequestedEventArgs(pArgs);
int[] pReason = new int[1];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*******************************************************************************
* Copyright (c) 2024 SAP SE and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* SAP SE - initial implementation
*******************************************************************************/
package org.eclipse.swt.internal.ole.win32;

public class ICoreWebView2AcceleratorKeyPressedEventArgs extends IUnknown {

public ICoreWebView2AcceleratorKeyPressedEventArgs(long address) {
super(address);
}

public int get_KeyEventKind(long[] value) {
return COM.VtblCall(3, address, value);
}

public int get_VirtualKey(int[] value) {
return COM.VtblCall(4, address, value);
}

public int get_KeyEventLParam(int[] value) {
return COM.VtblCall(5, address, value);
}

public int get_PhysicalKeyStatus(long[] value) {
return COM.VtblCall(6, address, value);
}

public int get_Handled(int[] value) {
return COM.VtblCall(7, address, value);
}

public int put_Handled(boolean value) {
return COM.VtblCall(8, address, value ? 1 : 0);
}

}

0 comments on commit 248ab17

Please sign in to comment.