Fix for Bug 379024 - Missing @Focus causes Selection not propagated in
conjunction with the Part service
diff --git a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/ContributedPartRenderer.java b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/ContributedPartRenderer.java
index 2b70ac8..7e18d70 100644
--- a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/ContributedPartRenderer.java
+++ b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/ContributedPartRenderer.java
@@ -11,12 +11,10 @@
package org.eclipse.e4.ui.workbench.renderers.swt;
import javax.inject.Inject;
-import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.core.services.contributions.IContributionFactory;
import org.eclipse.e4.core.services.log.Logger;
-import org.eclipse.e4.ui.di.Focus;
import org.eclipse.e4.ui.model.application.ui.MUIElement;
import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
@@ -94,12 +92,14 @@
try {
// we are currently asking the part to take focus
beingFocused = true;
+
// delegate an attempt to set the focus here to the
// part's implementation (if there is one)
Object object = part.getObject();
if (object != null) {
- ContextInjectionFactory.invoke(object, Focus.class,
- part.getContext(), null);
+ IPresentationEngine pe = part.getContext().get(
+ IPresentationEngine.class);
+ pe.focusGui(part);
return true;
}
return super.setFocus();
diff --git a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/SWTPartRenderer.java b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/SWTPartRenderer.java
index bacf1e4..0342643 100644
--- a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/SWTPartRenderer.java
+++ b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/SWTPartRenderer.java
@@ -282,4 +282,20 @@
return getModelElement(ctrl.getParent());
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer#forceFocus
+ * (org.eclipse.e4.ui.model.application.ui.MUIElement)
+ */
+ @Override
+ public void forceFocus(MUIElement element) {
+ if (element.getWidget() instanceof Control) {
+ // Have SWT set the focus
+ Control ctrl = (Control) element.getWidget();
+ if (!ctrl.isDisposed())
+ ctrl.forceFocus();
+ }
+ }
}
diff --git a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/StackRenderer.java b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/StackRenderer.java
index 10976b9..a67d495 100644
--- a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/StackRenderer.java
+++ b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/StackRenderer.java
@@ -18,10 +18,8 @@
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Named;
-import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.services.events.IEventBroker;
-import org.eclipse.e4.ui.di.Focus;
import org.eclipse.e4.ui.internal.workbench.renderers.swt.BasicPartList;
import org.eclipse.e4.ui.internal.workbench.renderers.swt.SWTRenderersMessages;
import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer;
@@ -898,8 +896,7 @@
if ((stackElement instanceof MPart)
&& (ctf.isFocusControl())) {
MPart thePart = (MPart) stackElement;
- ContextInjectionFactory.invoke(thePart.getObject(),
- Focus.class, thePart.getContext(), null);
+ renderer.focusGui(thePart);
}
}
}
diff --git a/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/internal/workbench/swt/AbstractPartRenderer.java b/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/internal/workbench/swt/AbstractPartRenderer.java
index d782fa8..f1fbb2f7 100644
--- a/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/internal/workbench/swt/AbstractPartRenderer.java
+++ b/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/internal/workbench/swt/AbstractPartRenderer.java
@@ -27,8 +27,7 @@
public void init(IEclipseContext context) {
this.context = context;
- modelService = (EModelService) context.get(EModelService.class
- .getName());
+ modelService = context.get(EModelService.class);
}
public abstract Object createWidget(MUIElement element, Object parent);
@@ -123,4 +122,15 @@
return null;
}
+
+ /**
+ * Force the UI focus into the element if possible. This method should not
+ * be called directly, it will be called by the IPresentationEngine#focusGui
+ * method if the normal process used to set the focus cannot be performed.
+ *
+ * @param element
+ */
+ public void forceFocus(MUIElement element) {
+ // Do nothing by default
+ }
}
diff --git a/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/internal/workbench/swt/PartRenderingEngine.java b/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/internal/workbench/swt/PartRenderingEngine.java
index 2024cc5..8734862 100644
--- a/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/internal/workbench/swt/PartRenderingEngine.java
+++ b/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/internal/workbench/swt/PartRenderingEngine.java
@@ -28,6 +28,7 @@
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.EclipseContextFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.core.di.InjectionException;
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.core.services.contributions.IContributionFactory;
import org.eclipse.e4.core.services.events.IEventBroker;
@@ -39,6 +40,7 @@
import org.eclipse.e4.ui.css.swt.engine.CSSSWTEngineImpl;
import org.eclipse.e4.ui.css.swt.theme.IThemeEngine;
import org.eclipse.e4.ui.css.swt.theme.IThemeManager;
+import org.eclipse.e4.ui.di.Focus;
import org.eclipse.e4.ui.di.PersistState;
import org.eclipse.e4.ui.internal.workbench.Activator;
import org.eclipse.e4.ui.internal.workbench.E4Workbench;
@@ -729,6 +731,55 @@
return safeCreateGui(element, parent, parentContext);
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.e4.ui.workbench.IPresentationEngine#focusGui(org.eclipse.
+ * e4.ui.model.application.ui.MUIElement)
+ */
+ public void focusGui(MUIElement element) {
+ AbstractPartRenderer renderer = (AbstractPartRenderer) element
+ .getRenderer();
+ if (renderer == null || element.getWidget() == null)
+ return;
+
+ Object implementation = element instanceof MContribution ? ((MContribution) element)
+ .getObject() : null;
+
+ // If there is no class to call @Focus on then revert to the default
+ if (!(element instanceof MContribution)) {
+ renderer.forceFocus(element);
+ return;
+ }
+
+ try {
+ IEclipseContext context = getContext(element);
+ Object defaultValue = new Object();
+ Object returnValue = ContextInjectionFactory.invoke(implementation,
+ Focus.class, context, defaultValue);
+ if (returnValue == defaultValue) {
+ // No @Focus method, force the focus
+ renderer.forceFocus(element);
+ }
+ } catch (InjectionException e) {
+ log("Failed to grant focus to element", "Failed to grant focus to element ({0})", //$NON-NLS-1$ //$NON-NLS-2$
+ element.getElementId(), e);
+ } catch (RuntimeException e) {
+ log("Failed to grant focus to element via DI", //$NON-NLS-1$
+ "Failed to grant focus via DI to element ({0})", element.getElementId(), e); //$NON-NLS-1$
+ }
+ }
+
+ private void log(String unidentifiedMessage, String identifiedMessage,
+ String id, Exception e) {
+ if (id == null || id.length() == 0) {
+ logger.error(e, unidentifiedMessage);
+ } else {
+ logger.error(e, NLS.bind(identifiedMessage, id));
+ }
+ }
+
private Shell getLimboShell() {
if (limbo == null) {
limbo = new Shell(Display.getCurrent(), SWT.NONE);
diff --git a/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartServiceImpl.java b/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartServiceImpl.java
index ea87aee..c0a0cd6 100644
--- a/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartServiceImpl.java
+++ b/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartServiceImpl.java
@@ -28,7 +28,6 @@
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.core.services.log.Logger;
-import org.eclipse.e4.ui.di.Focus;
import org.eclipse.e4.ui.di.Persist;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptor;
@@ -581,18 +580,11 @@
partActivationHistory.activate(part, activateBranch);
- Object object = part.getObject();
- if (object != null && requiresFocus) {
- try {
- ContextInjectionFactory.invoke(object, Focus.class, part.getContext(), null);
- } catch (InjectionException e) {
- log("Failed to grant focus to part", "Failed to grant focus to part ({0})", //$NON-NLS-1$ //$NON-NLS-2$
- part.getElementId(), e);
- } catch (RuntimeException e) {
- log("Failed to grant focus to part via DI", //$NON-NLS-1$
- "Failed to grant focus via DI to part ({0})", part.getElementId(), e); //$NON-NLS-1$
- }
+ if (requiresFocus) {
+ IPresentationEngine pe = part.getContext().get(IPresentationEngine.class);
+ pe.focusGui(part);
}
+
firePartActivated(part);
UIEvents.publishEvent(UIEvents.UILifeCycle.ACTIVATE, part);
} finally {
diff --git a/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/workbench/IPresentationEngine.java b/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/workbench/IPresentationEngine.java
index 3962b9d..0f172e9 100644
--- a/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/workbench/IPresentationEngine.java
+++ b/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/workbench/IPresentationEngine.java
@@ -157,6 +157,15 @@
public void removeGui(MUIElement element);
/**
+ * Attempts to set the UI focus onto the given element. By default we delegate this to the
+ * elements implementation's @Focus method (if any). If no such method exists we delegate the
+ * the renderer's 'forceFocus' method.
+ *
+ * @param element
+ */
+ public void focusGui(MUIElement element);
+
+ /**
* Run the UI. This method is responsible for creating the initial UI and (if necessary)
* spinning the event loop for the life of the application.
*
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/SearchField.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/SearchField.java
index 0422176..93587ec 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/SearchField.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/SearchField.java
@@ -24,12 +24,11 @@
import org.eclipse.core.expressions.ExpressionInfo;
import org.eclipse.core.expressions.IEvaluationContext;
import org.eclipse.core.runtime.Assert;
-import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
-import org.eclipse.e4.ui.di.Focus;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
+import org.eclipse.e4.ui.workbench.IPresentationEngine;
import org.eclipse.e4.ui.workbench.modeling.EPartService;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.layout.GridDataFactory;
@@ -171,8 +170,9 @@
if (text.isFocusControl()) {
MPart activePart = partService.getActivePart();
if (activePart != null) {
- ContextInjectionFactory.invoke(activePart.getObject(), Focus.class,
- activePart.getContext(), null);
+ IPresentationEngine pe = activePart.getContext().get(
+ IPresentationEngine.class);
+ pe.focusGui(activePart);
}
}
}