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);
 						}
 					}
 				}