From 624385c20c3c38bbec798b034a4dc0e33d632f79 Mon Sep 17 00:00:00 2001 From: Amartya Parijat Date: Mon, 29 Dec 2025 14:39:25 +0100 Subject: [PATCH] Process KeyBinding Command Asyncly for Browser This commit adapts how KeyBindingDispatcher processed Key events in case of Browser. If the trigger of the event is a browser, it processes the command asynchronously to avoid any possible deadlocks. Contributes to https://github.com/eclipse-platform/eclipse.platform.ui/issues/3104 --- .../bindings/keys/KeyBindingDispatcher.java | 62 +++++++++++-------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/bundles/org.eclipse.e4.ui.bindings/src/org/eclipse/e4/ui/bindings/keys/KeyBindingDispatcher.java b/bundles/org.eclipse.e4.ui.bindings/src/org/eclipse/e4/ui/bindings/keys/KeyBindingDispatcher.java index 1bb5122ff1c..cc1b44a33a1 100644 --- a/bundles/org.eclipse.e4.ui.bindings/src/org/eclipse/e4/ui/bindings/keys/KeyBindingDispatcher.java +++ b/bundles/org.eclipse.e4.ui.bindings/src/org/eclipse/e4/ui/bindings/keys/KeyBindingDispatcher.java @@ -295,32 +295,42 @@ public final boolean executeCommand(final ParameterizedCommand parameterizedComm final EHandlerService handlerService = getHandlerService(); final Command command = parameterizedCommand.getCommand(); - final IEclipseContext staticContext = createContext(trigger); - final boolean commandDefined = command.isDefined(); // boolean commandEnabled; boolean commandHandled = false; - try { - // commandEnabled = handlerService.canExecute(parameterizedCommand, staticContext); - Object obj = HandlerServiceImpl.lookUpHandler(context, command.getId()); - if (obj != null) { - if (obj instanceof IHandler) { - commandHandled = ((IHandler) obj).isHandled(); - } else { - commandHandled = true; - } + // commandEnabled = handlerService.canExecute(parameterizedCommand, + // staticContext); + Object obj = HandlerServiceImpl.lookUpHandler(context, command.getId()); + if (obj != null) { + if (obj instanceof IHandler handler) { + commandHandled = handler.isHandled(); + } else { + commandHandled = true; } + } - if (isTracingEnabled()) { - logger.trace("Command " + parameterizedCommand + ", defined: " + commandDefined + ", handled: " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - + commandHandled + " in " + describe(context)); //$NON-NLS-1$ - } + if (isTracingEnabled()) { + logger.trace("Command " + parameterizedCommand + ", defined: " + commandDefined + ", handled: " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + commandHandled + " in " + describe(context)); //$NON-NLS-1$ + } + final IEclipseContext staticContext = createContext(trigger); + if (trigger.widget instanceof Browser) { + getDisplay() + .asyncExec(() -> handleCommandExecution(parameterizedCommand, handlerService, staticContext, obj)); + } else { + handleCommandExecution(parameterizedCommand, handlerService, staticContext, obj); + } + return (commandDefined && commandHandled); + } + + private void handleCommandExecution(final ParameterizedCommand parameterizedCommand, + final EHandlerService handlerService, final IEclipseContext staticContext, Object handler) { + try { handlerService.executeHandler(parameterizedCommand, staticContext); final Object commandException = staticContext.get(HandlerServiceImpl.HANDLER_EXCEPTION); if (commandException instanceof CommandException) { - commandHandled = false; if (commandException instanceof ExecutionException) { if (logger != null) { logger.error((Throwable) commandException, @@ -328,8 +338,7 @@ public final boolean executeCommand(final ParameterizedCommand parameterizedComm + describe(context)); } } else if (isTracingEnabled()) { - logger.trace((Throwable) commandException, - "Command exception for: " + parameterizedCommand + " in " //$NON-NLS-1$ //$NON-NLS-2$ + logger.trace((Throwable) commandException, "Command exception for: " + parameterizedCommand + " in " //$NON-NLS-1$ //$NON-NLS-2$ + describe(context)); if (handlerService instanceof HandlerServiceImpl serviceImpl) { IEclipseContext serviceContext = serviceImpl.getContext(); @@ -337,7 +346,7 @@ public final boolean executeCommand(final ParameterizedCommand parameterizedComm StringBuilder sb = new StringBuilder("\n\tExecution context: "); //$NON-NLS-1$ sb.append(describe(serviceContext)); sb.append("\n\tHandler: "); //$NON-NLS-1$ - sb.append(obj); + sb.append(handler); logger.trace(sb.toString()); } } @@ -352,17 +361,16 @@ public final boolean executeCommand(final ParameterizedCommand parameterizedComm } } } - /* - * Now that the command has executed (and had the opportunity to use the remembered - * state of the dialog), it is safe to delete that information. - */ - if (keyAssistDialog != null) { - keyAssistDialog.clearRememberedState(); - } } finally { staticContext.dispose(); } - return (commandDefined && commandHandled); + /* + * Now that the command has executed (and had the opportunity to use the + * remembered state of the dialog), it is safe to delete that information. + */ + if (keyAssistDialog != null) { + keyAssistDialog.clearRememberedState(); + } } private boolean isTracingEnabled() {