Skip to content

Commit 450ece0

Browse files
committed
Edge: Ignore multiple gotFocus events if we were the one who caused them
Follow-up on #1849 / #1848.
1 parent 5d4df79 commit 450ece0

2 files changed

Lines changed: 42 additions & 4 deletions

File tree

bundles/org.eclipse.swt/Eclipse SWT Browser/win32/org/eclipse/swt/browser/Edge.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public WebViewEnvironment(ICoreWebView2Environment environment) {
8787
HashMap<Long, LocationEvent> navigations = new HashMap<>();
8888
/** Maps BrowserFunction index to the script ID from AddScriptToExecuteOnDocumentCreated. */
8989
private final Map<Integer, String> functionScriptIds = new HashMap<>();
90-
private boolean ignoreGotFocus;
90+
private int ignoreGotFocus;
9191
private boolean ignoreFocusIn;
9292
private String lastCustomText;
9393

@@ -898,7 +898,15 @@ void browserFocusIn(Event event) {
898898
// We need to ignore that next event, as in the meantime the user might
899899
// have moved focus to some other control and reacting on that event
900900
// would bring us back to the Browser.
901-
ignoreGotFocus = true;
901+
// https://github.com/eclipse-platform/eclipse.platform.swt/pull/1849#issuecomment-4753007036
902+
// There can be multiple focus-in events within the same event loop iteration,
903+
// e.g.,
904+
// other.setFocus();
905+
// browser.setFocus();
906+
// other.setFocus();
907+
// browser.setFocus();
908+
// We need to apply the ignore handling to all of them, so a counter is used.
909+
ignoreGotFocus++;
902910

903911
controller.MoveFocus(COM.COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC);
904912
}
@@ -1506,8 +1514,8 @@ private void asyncExec(Runnable r) {
15061514
}
15071515

15081516
int handleGotFocus(long pView, long pArg) {
1509-
if (ignoreGotFocus) {
1510-
ignoreGotFocus = false;
1517+
if (ignoreGotFocus > 0) {
1518+
ignoreGotFocus--;
15111519
return COM.S_OK;
15121520
}
15131521
// https://github.com/eclipse-platform/eclipse.platform.swt/issues/1139

tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_browser_Browser.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3095,6 +3095,36 @@ public void test_TimerRegression_Issue2806() {
30953095

30963096
}
30973097

3098+
/**
3099+
* https://github.com/eclipse-platform/eclipse.platform.swt/issues/1848
3100+
* https://github.com/eclipse-platform/eclipse.platform.swt/pull/1849
3101+
*
3102+
* Send two focus events to the browser within the same event loop iteration.
3103+
* Edge uses
3104+
* controller.MoveFocus(COM.COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC); //
3105+
* which triggers then asynchronoulsy. BOTH WebView2 events must then be handled
3106+
* (ignored) internally and not cause another call to browserFocusIn(). So we
3107+
* expect a total of 2 SWT events (not 3).
3108+
*/
3109+
@Test
3110+
public void test_EdgeAsyncFocusHandling() {
3111+
assumeTrue(isEdge, "This test is intended for Edge only");
3112+
3113+
shell.open();
3114+
Text otherControl = new Text(shell, SWT.NONE);
3115+
processUiEvents();
3116+
List<Event> focusInEvents = new ArrayList<>();
3117+
browser.addListener(SWT.FocusIn, focusInEvents::add);
3118+
3119+
otherControl.setFocus();
3120+
browser.setFocus();
3121+
otherControl.setFocus();
3122+
browser.setFocus();
3123+
processUiEvents();
3124+
3125+
assertEquals(2, focusInEvents.size());
3126+
}
3127+
30983128
/* custom */
30993129
/**
31003130
* Wait for passTest to return true. Timeout otherwise.

0 commit comments

Comments
 (0)