Bug 548801 - [Tip of the day] Avoid initial Layout Shell call during
startup

This mitigates the hack to layout the Shell to show the update icon in
the toolbar.

We do no layout call if the workbench starts up, that avoids UI freezes
in case the WS needs to be build.

New tips still trigger a layout call but
muliple calls arriving within 5 secs will be combined

Tests done:

Preference: Indicate new tips in the status bar

Test scenario: new tips are present at startup
-> Toolbar icon is shown to the user

Test scenerio: tips are read by the user
--> Toolbar icon is hidden

For this test I removed the SWTTips from plugin.xml as they provide
infinite tips.

Test scenario: delay tip provider and check if icon is still shown

Using
private void load(TipProvider provider) {
		try {
			Thread.sleep(20000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

Also works.

Change-Id: If470cc10cdade32132c4695796b4b74a64cf55ba
Signed-off-by: Lars Vogel <Lars.Vogel@vogella.com>
diff --git a/org.eclipse.tips.ide/src/org/eclipse/tips/ide/internal/TipSourceProvider.java b/org.eclipse.tips.ide/src/org/eclipse/tips/ide/internal/TipSourceProvider.java
index b4d50f2..6eb9c5a 100644
--- a/org.eclipse.tips.ide/src/org/eclipse/tips/ide/internal/TipSourceProvider.java
+++ b/org.eclipse.tips.ide/src/org/eclipse/tips/ide/internal/TipSourceProvider.java
@@ -19,6 +19,8 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
+import org.eclipse.core.runtime.jobs.JobChangeAdapter;
 import org.eclipse.tips.core.ITipManager;
 import org.eclipse.tips.core.internal.LogUtil;
 import org.eclipse.ui.AbstractSourceProvider;
@@ -35,6 +37,8 @@
 public class TipSourceProvider extends AbstractSourceProvider {
 	private boolean fNewTips;
 	private ITipManager fManager;
+	private UIJob job;
+	private boolean startup = true;
 
 	public TipSourceProvider(ITipManager manager) {
 		fManager = manager;
@@ -71,13 +75,29 @@
 		layoutWorkbench(changed);
 	}
 
-	private void layoutWorkbench(boolean changed) {
-		UIJob job = new UIJob(PlatformUI.getWorkbench().getDisplay(), Messages.TipSourceProvider_0) {
+	private synchronized void layoutWorkbench(boolean changed) {
+		// prevent multiple jobs running and don't use Display if it is disposed during
+		// shutdown
+		if (job != null || PlatformUI.getWorkbench().getDisplay() == null
+				|| PlatformUI.getWorkbench().getDisplay().isDisposed()) {
+			return;
+		}
+		job = new UIJob(PlatformUI.getWorkbench().getDisplay(), Messages.TipSourceProvider_0) {
 			@Override
 			public IStatus runInUIThread(IProgressMonitor monitor) {
 				if (changed) {
 					fireSourceChanged(ISources.ACTIVE_WORKBENCH_WINDOW, getCurrentState());
 				}
+				// TODO remove this ugly hack to ensure the tips icon becomes visibile
+				// in the toolbar
+				// after the update of the toolitem
+				// The whole logic to layout can be removed once Bug 552737 is fixed
+
+				if (startup) {
+					// no need to layout the Shell during startup
+					startup = false;
+					return Status.OK_STATUS;
+				}
 				for (IWorkbenchWindow window : PlatformUI.getWorkbench().getWorkbenchWindows()) {
 					fManager.log(LogUtil.info(Messages.TipSourceProvider_1 + window + " -> " + fNewTips)); //$NON-NLS-1$
 					window.getShell().layout(true, true);
@@ -85,6 +105,14 @@
 				return Status.OK_STATUS;
 			}
 		};
+		job.addJobChangeListener(new JobChangeAdapter() {
+			@Override
+			public void done(IJobChangeEvent event) {
+				// ensure the job is recycled so that the next update triggers again a job
+				job = null;
+			}
+
+		});
 		job.schedule(5000); // allow the workbench to settle in.
 	}
 }
\ No newline at end of file