From 771d0b405910c4971123ffb46b09b9693d10af4e Mon Sep 17 00:00:00 2001
From: fedejeanne <Federico.Jeanne@vector.com>
Date: Tue, 12 Dec 2023 14:12:47 +0100
Subject: [PATCH] Allow asynchronous creation of menus in
 ActionContributionItem

Add a listener that copies and shows the resulting menu once it has been
completely populated.
---
 .../jface/action/ActionContributionItem.java    | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/action/ActionContributionItem.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/action/ActionContributionItem.java
index 86658a03a55..4cf97d6044e 100644
--- a/bundles/org.eclipse.jface/src/org/eclipse/jface/action/ActionContributionItem.java
+++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/action/ActionContributionItem.java
@@ -15,6 +15,8 @@
  *******************************************************************************/
 package org.eclipse.jface.action;
 
+import java.util.Arrays;
+
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.commands.NotEnabledException;
 import org.eclipse.jface.action.ExternalActionManager.IBindingManagerCallback;
@@ -1168,7 +1170,22 @@ private void handleShowProxy(Menu proxy) {
 		if (holdMenu == null) {
 			return;
 		}
+
+		// for backwards compatibility (in case the menu is NOT calculated asynchronously)
 		copyMenu(holdMenu, proxy);
+
+		// in case the menu is populated asynchronously by the menu creator, this listener will update it once it's complete
+		holdMenu.addListener(SWT.Show, evt -> {
+			// This one is (currently) being triggered from ContextuaLaunchAction
+			if (evt.data == null || evt.data != holdMenu)
+				return;
+
+			// remove all items in the proxy...
+			Arrays.stream(proxy.getItems()).forEach(Widget::dispose);
+
+			// ... and replace them with the new content
+			copyMenu(holdMenu, proxy);
+		});
 	}
 
 	/**