Bug 549898 - workaround for legacy actions sets init for CPD

Don't init/set all actions sets in WorkbenchWindow on startup, this
triggers code activation for invisible action sets. Instead, populate
all legacy actions sets into the model before opening Customize
Perspective Dialog.

Change-Id: Ida27af57f44d56fb52db92bfb3e0c0f23d81e3a3
Signed-off-by: Andrey Loskutov <loskutov@gmx.de>
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchWindow.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchWindow.java
index 93557d1..dd6f64d 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchWindow.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchWindow.java
@@ -187,7 +187,6 @@
 import org.eclipse.ui.internal.misc.UIListenerLogging;
 import org.eclipse.ui.internal.progress.ProgressRegion;
 import org.eclipse.ui.internal.provisional.application.IActionBarConfigurer2;
-import org.eclipse.ui.internal.registry.ActionSetRegistry;
 import org.eclipse.ui.internal.registry.IActionSetDescriptor;
 import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
 import org.eclipse.ui.internal.registry.UIExtensionTracker;
@@ -874,10 +873,6 @@
 			page.setPerspective(perspective);
 			firePageActivated();
 
-			// Populate all legacy actionsets into the model, see Bug 549898
-			ActionSetRegistry registry = application.getContext().get(ActionSetRegistry.class);
-			getActionPresentation().setActionSets(registry.getActionSets());
-
 			if (newWindow) {
 				page.fireInitialPartVisibilityEvents();
 			} else {
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/cpd/CustomizePerspectiveDialog.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/cpd/CustomizePerspectiveDialog.java
index eefc16d..3b462b7 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/cpd/CustomizePerspectiveDialog.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/cpd/CustomizePerspectiveDialog.java
@@ -146,6 +146,10 @@
  */
 public class CustomizePerspectiveDialog extends TrayDialog {
 
+	/**
+	 * Flag showing that we have initialized all legacy action sets for given window
+	 */
+	private static final String ALL_SETS_INITIALIZED = "ALL_SETS_INITIALIZED"; //$NON-NLS-1$
 	private static final String TOOLBAR_ICON = "$nl$/icons/full/obj16/toolbar.png"; //$NON-NLS-1$
 	private static final String SUBMENU_ICON = "$nl$/icons/full/obj16/submenu.png"; //$NON-NLS-1$
 	private static final String MENU_ICON = "$nl$/icons/full/obj16/menu.png"; //$NON-NLS-1$
@@ -1330,10 +1334,22 @@
 	}
 
 	private void initializeActionSetInput() {
-		// Just get the action sets at this point. Do not load the action set
-		// until it is actually selected in the dialog.
+		// Just get the action sets at this point.
 		ActionSetRegistry reg = WorkbenchPlugin.getDefault().getActionSetRegistry();
 		IActionSetDescriptor[] sets = reg.getActionSets();
+
+		// Populate all legacy actionsets into the model, see bug 549898
+		// Note: all (also invisible) actions sets will be loaded here and
+		// respective actions will be created. This is not good ("invisible"
+		// actions will live from this moment on till shutdown) and we need
+		// a better solution.
+		Object initDone = context.get(ALL_SETS_INITIALIZED);
+		if (initDone == null) {
+			context.set(ALL_SETS_INITIALIZED, Boolean.TRUE);
+			window.getActionPresentation().setActionSets(sets);
+			window.updateActionSets();
+		}
+
 		IActionSetDescriptor[] actionSetDescriptors = ((WorkbenchPage) window.getActivePage()).getActionSets();
 		List<IActionSetDescriptor> initiallyAvailableActionSets = Arrays.asList(actionSetDescriptors);
 
diff --git a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/api/IWorkbenchWindowActionDelegateTest.java b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/api/IWorkbenchWindowActionDelegateTest.java
index aa3589e..45f1a26 100644
--- a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/api/IWorkbenchWindowActionDelegateTest.java
+++ b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/api/IWorkbenchWindowActionDelegateTest.java
@@ -45,6 +45,15 @@
 		assertEquals(Arrays.toString(testNames), Arrays.toString(delegate.callHistory.verifyAndReturnOrder(testNames)));
 	}
 
+	public void testLazyInit() {
+		// Action set shouldn't be shown / initialized on startup
+		int count = NotInitializedWorkbenchWindowActionDelegate.INIT_COUNT.intValue();
+		assertEquals("Expected to see zero inits of invisible delegates", 0, count);
+		// So far we don't have tests for that, so let assume this is also true
+		count = NotInitializedWorkbenchWindowActionDelegate.INSTANCE_COUNT.intValue();
+		assertEquals("Expected to see zero instances of invisible delegates", 0, count);
+	}
+
 	/**
 	 * Returns the last mock action delegate which was created.
 	 */
diff --git a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/api/NotInitializedWorkbenchWindowActionDelegate.java b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/api/NotInitializedWorkbenchWindowActionDelegate.java
new file mode 100644
index 0000000..2205177
--- /dev/null
+++ b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/api/NotInitializedWorkbenchWindowActionDelegate.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Andrey Loskutov.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Andrey Loskutov - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ui.tests.api;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class NotInitializedWorkbenchWindowActionDelegate extends MockWorkbenchWindowActionDelegate {
+
+	public static AtomicInteger INSTANCE_COUNT = new AtomicInteger(0);
+	public static AtomicInteger INIT_COUNT = new AtomicInteger(0);
+
+	public NotInitializedWorkbenchWindowActionDelegate() {
+		INIT_COUNT.incrementAndGet();
+		INSTANCE_COUNT.incrementAndGet();
+	}
+
+	@Override
+	public void dispose() {
+		INSTANCE_COUNT.decrementAndGet();
+		super.dispose();
+	}
+}
diff --git a/tests/org.eclipse.ui.tests/plugin.xml b/tests/org.eclipse.ui.tests/plugin.xml
index 142c56d..2b13011 100644
--- a/tests/org.eclipse.ui.tests/plugin.xml
+++ b/tests/org.eclipse.ui.tests/plugin.xml
@@ -4129,6 +4129,19 @@
                style="push">
          </action>
       </actionSet>
+      <actionSet
+            id="org.eclipse.ui.tests.notInitializedActionSet"
+            label="actionSet for testing lazy loading of invisible action sets"
+            visible="false">
+         <action
+               class="org.eclipse.ui.tests.api.NotInitializedWorkbenchWindowActionDelegate"
+               id="org.eclipse.ui.tests.do_not_init"
+               label="Simply do not init me"
+               menubarPath="window/additions"
+               toolbarPath="window/additions"
+               style="push">
+         </action>
+      </actionSet>
    </extension>
    <extension
          point="org.eclipse.ui.commandImages">