### Eclipse Workspace Patch 1.0 #P org.eclipse.ui Index: plugin.properties =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui/plugin.properties,v retrieving revision 1.226 diff -u -r1.226 plugin.properties --- plugin.properties 8 Oct 2010 07:13:32 -0000 1.226 +++ plugin.properties 14 Dec 2010 09:10:45 -0000 @@ -283,6 +283,8 @@ context.window.description = A window is open context.actionSet.name = Action Set context.actionSet.description = Parent context for action sets +context.workbench.name = Workbench +context.workbench.description = In Workbench keyConfiguration.default.description = Default Key Configuration keyConfiguration.default.name = Default Index: plugin.xml =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui/plugin.xml,v retrieving revision 1.459 diff -u -r1.459 plugin.xml --- plugin.xml 10 Nov 2010 08:32:47 -0000 1.459 +++ plugin.xml 14 Dec 2010 09:10:45 -0000 @@ -94,6 +94,11 @@ id="org.eclipse.ui.contexts.actionSet" name="%context.actionSet.name"> + + #P org.eclipse.ui.tests Index: Eclipse JFace Tests/org/eclipse/ui/tests/RCPSessionApplication.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.tests/Eclipse JFace Tests/org/eclipse/ui/tests/RCPSessionApplication.java,v retrieving revision 1.1 diff -u -r1.1 RCPSessionApplication.java --- Eclipse JFace Tests/org/eclipse/ui/tests/RCPSessionApplication.java 23 Apr 2009 16:15:29 -0000 1.1 +++ Eclipse JFace Tests/org/eclipse/ui/tests/RCPSessionApplication.java 14 Dec 2010 09:10:47 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2009 IBM Corporation and others. + * Copyright (c) 2008, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -19,10 +19,12 @@ public class RCPSessionApplication implements IApplication { + private boolean windowlessApp = false; + public Object start(IApplicationContext context) throws Exception { Display display = PlatformUI.createDisplay(); try { - PlatformUI.createAndRunWorkbench(display, new RCPTestWorkbenchAdvisor()); + PlatformUI.createAndRunWorkbench(display, new RCPTestWorkbenchAdvisor(windowlessApp)); } finally { if (display != null) display.dispose(); @@ -42,4 +44,12 @@ } }); } + + /** + * @param windowlessApp The windowlessApp to set. + */ + public void setWindowlessApp(boolean windowlessApp) { + this.windowlessApp = windowlessApp; + } + } \ No newline at end of file Index: Eclipse JFace Tests/org/eclipse/ui/tests/WindowlessRCPApplication.java =================================================================== RCS file: Eclipse JFace Tests/org/eclipse/ui/tests/WindowlessRCPApplication.java diff -N Eclipse JFace Tests/org/eclipse/ui/tests/WindowlessRCPApplication.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Eclipse JFace Tests/org/eclipse/ui/tests/WindowlessRCPApplication.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2010 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.ui.tests; + + +public class WindowlessRCPApplication extends RCPSessionApplication { + + public WindowlessRCPApplication() { + setWindowlessApp(true); + } + +} \ No newline at end of file Index: Eclipse UI Tests/org/eclipse/ui/tests/session/SessionTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/session/SessionTests.java,v retrieving revision 1.22 diff -u -r1.22 SessionTests.java --- Eclipse UI Tests/org/eclipse/ui/tests/session/SessionTests.java 23 Apr 2009 16:15:29 -0000 1.22 +++ Eclipse UI Tests/org/eclipse/ui/tests/session/SessionTests.java 14 Dec 2010 09:10:49 -0000 @@ -17,6 +17,7 @@ import junit.framework.Test; import junit.framework.TestSuite; +import org.eclipse.jface.util.Util; import org.eclipse.ui.tests.harness.util.TweakletCheckTest; import org.eclipse.ui.tests.markers.MarkersViewColumnSizeTest; import org.eclipse.ui.tests.statushandlers.StatusHandlerConfigurationSuite; @@ -46,6 +47,20 @@ addThemeTests(); addStatusHandlingTests(); addRestoredSessionTest(); + addWindowlessSessionTest(); + } + + /** + * + */ + private void addWindowlessSessionTest() { + // Windowless apps are available only on Cocoa + if(Util.isCocoa()) { + Map arguments = new HashMap(2); + arguments.put("product", null); + arguments.put("testApplication", "org.eclipse.ui.tests.windowLessRcpApplication"); + addTest(new WorkbenchSessionTest("windowlessSessionTests",WindowlessSessionTest.class, arguments)); + } } /** Index: Eclipse UI Tests/org/eclipse/ui/tests/session/WindowlessSessionTest.java =================================================================== RCS file: Eclipse UI Tests/org/eclipse/ui/tests/session/WindowlessSessionTest.java diff -N Eclipse UI Tests/org/eclipse/ui/tests/session/WindowlessSessionTest.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Eclipse UI Tests/org/eclipse/ui/tests/session/WindowlessSessionTest.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,43 @@ +/******************************************************************************* + + * Copyright (c) 2010 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + ******************************************************************************/ +package org.eclipse.ui.tests.session; + +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.tests.harness.util.UITestCase; + + +/** + * @since 3.7 + */ +public class WindowlessSessionTest extends UITestCase { + + public WindowlessSessionTest(String name) { + super(name); + } + + public void testWindowlessWorkbench() throws Exception { + + // There should not be any windows in this app + assertTrue(fWorkbench.getWorkbenchWindowCount() == 0); + + // Now open a window + IWorkbenchWindow window = fWorkbench.openWorkbenchWindow(null); + + // window count should be 1 + assertTrue(fWorkbench.getWorkbenchWindowCount() == 1); + + window.close(); + + // now the workbench should stay without a window + assertTrue(fWorkbench.getWorkbenchWindowCount() == 0); + } +} Index: plugin.xml =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.tests/plugin.xml,v retrieving revision 1.290 diff -u -r1.290 plugin.xml --- plugin.xml 9 Nov 2010 16:59:42 -0000 1.290 +++ plugin.xml 14 Dec 2010 09:10:52 -0000 @@ -4314,4 +4314,16 @@ + + + + + + #P org.eclipse.ui.tests.harness Index: src/org/eclipse/ui/tests/harness/util/RCPTestWorkbenchAdvisor.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.tests.harness/src/org/eclipse/ui/tests/harness/util/RCPTestWorkbenchAdvisor.java,v retrieving revision 1.2 diff -u -r1.2 RCPTestWorkbenchAdvisor.java --- src/org/eclipse/ui/tests/harness/util/RCPTestWorkbenchAdvisor.java 25 May 2009 20:52:38 -0000 1.2 +++ src/org/eclipse/ui/tests/harness/util/RCPTestWorkbenchAdvisor.java 14 Dec 2010 09:10:53 -0000 @@ -50,6 +50,8 @@ /** Default value of -1 causes the option to be ignored. */ private int idleBeforeExit = -1; + private boolean windowlessApp = false; + /** * Traps whether or not calls to displayAccess in the UI thread resulted in * an exception. Should be false. @@ -62,8 +64,15 @@ this.idleBeforeExit = -1; } - public RCPTestWorkbenchAdvisor(int idleBeforeExit) { - this.idleBeforeExit = idleBeforeExit; + /** + * + * Enables the RCP application to runwithout a workbench window + * + * @param runWithoutWindow + * + */ + public RCPTestWorkbenchAdvisor(boolean windowlessApp) { + this.windowlessApp = windowlessApp; } /* @@ -87,6 +96,12 @@ prefs.setValue(IWorkbenchPreferenceConstants.SHOW_PROGRESS_ON_STARTUP, false); prefs.setValue(IWorkbenchPreferenceConstants.SHOW_INTRO, false); + + if(windowlessApp) { + configurer.setSaveAndRestore(true); + configurer.setExitOnLastWindowClose(false); + } + } /* #P org.eclipse.ui.workbench Index: Eclipse UI/org/eclipse/ui/contexts/IContextService.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/contexts/IContextService.java,v retrieving revision 1.23 diff -u -r1.23 IContextService.java --- Eclipse UI/org/eclipse/ui/contexts/IContextService.java 7 Nov 2008 17:46:46 -0000 1.23 +++ Eclipse UI/org/eclipse/ui/contexts/IContextService.java 14 Dec 2010 09:10:55 -0000 @@ -11,7 +11,6 @@ package org.eclipse.ui.contexts; import java.util.Collection; - import org.eclipse.core.commands.contexts.Context; import org.eclipse.core.commands.contexts.IContextManagerListener; import org.eclipse.core.expressions.Expression; @@ -40,6 +39,14 @@ public interface IContextService extends IServiceWithSources { /** + * The identifier for the context that is active when a workbench is active. + * + * @since 3.7 + * + */ + public static final String CONTEXT_ID_WORKBENCH = "org.eclipse.ui.contexts.workbench"; //$NON-NLS-1$ + + /** * The identifier for the context that is active when a shell registered as * a dialog. */ Index: Eclipse UI/org/eclipse/ui/internal/ApplicationMenuManager.java =================================================================== RCS file: Eclipse UI/org/eclipse/ui/internal/ApplicationMenuManager.java diff -N Eclipse UI/org/eclipse/ui/internal/ApplicationMenuManager.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Eclipse UI/org/eclipse/ui/internal/ApplicationMenuManager.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2010 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ui.internal; + +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.swt.widgets.Decorations; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.Menu; + +/** + * @since 3.7 + * + */ +class ApplicationMenuManager extends MenuManager{ + + private final Menu appMenu; + private boolean disposing; + + public ApplicationMenuManager(Menu appMenu) { + this.appMenu = appMenu; + } + + + /* (non-Javadoc) + * @see org.eclipse.jface.action.MenuManager#createMenuBar(org.eclipse.swt.widgets.Decorations) + */ + public Menu createMenuBar(Decorations parent) { + return appMenu; + } + + protected boolean menuExist() { + // our menu always exist, + // except disposing - if not dispose will be called on this menu + return !disposing; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.action.MenuManager#getMenuItemCount() + */ + protected int getMenuItemCount() { + return appMenu.getItemCount(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.action.MenuManager#getMenuItem(int) + */ + protected Item getMenuItem(int index) { + return appMenu.getItem(index); + } + /* (non-Javadoc) + * @see org.eclipse.jface.action.MenuManager#getMenuItems() + */ + protected Item[] getMenuItems() { + return appMenu.getItems(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.action.MenuManager#doItemFill(org.eclipse.jface.action.IContributionItem, int) + */ + protected void doItemFill(IContributionItem ci, int index) { + ci.fill(appMenu, index); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.action.MenuManager#dispose() + */ + public void dispose() { + disposing = true; + super.dispose(); + disposing = false; + } +} + Index: Eclipse UI/org/eclipse/ui/internal/Workbench.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/Workbench.java,v retrieving revision 1.485 diff -u -r1.485 Workbench.java --- Eclipse UI/org/eclipse/ui/internal/Workbench.java 15 Nov 2010 18:14:56 -0000 1.485 +++ Eclipse UI/org/eclipse/ui/internal/Workbench.java 14 Dec 2010 09:10:58 -0000 @@ -95,6 +95,7 @@ import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.TaskBar; import org.eclipse.swt.widgets.TaskItem; @@ -131,6 +132,7 @@ import org.eclipse.ui.commands.ICommandImageService; import org.eclipse.ui.commands.ICommandService; import org.eclipse.ui.commands.IWorkbenchCommandSupport; +import org.eclipse.ui.contexts.IContextActivation; import org.eclipse.ui.contexts.IContextService; import org.eclipse.ui.contexts.IWorkbenchContextSupport; import org.eclipse.ui.handlers.IHandlerService; @@ -189,6 +191,7 @@ import org.eclipse.ui.intro.IIntroManager; import org.eclipse.ui.keys.IBindingService; import org.eclipse.ui.menus.IMenuService; +import org.eclipse.ui.menus.MenuUtil; import org.eclipse.ui.model.IContributionService; import org.eclipse.ui.operations.IWorkbenchOperationSupport; import org.eclipse.ui.progress.IProgressService; @@ -1554,6 +1557,29 @@ } }); + StartupThreading.runWithoutExceptions(new StartupRunnable() { + + public void runWithException() { + + activateWorkbenchContext(); + + } + }); + + StartupThreading.runWithoutExceptions(new StartupRunnable() { + + public void runWithException() { + + Menu appMenu = getAppMenu(); + if (appMenu == null) + return; + + createApplicationMenu(appMenu); + } + }); + + + // attempt to restore a previous workbench state try { UIStats.start(UIStats.RESTORE_WORKBENCH, "Workbench"); //$NON-NLS-1$ @@ -1751,6 +1777,14 @@ new SaveablesList()); }}); + StartupThreading.runWithoutExceptions(new StartupRunnable() { + + public void runWithException() { + // side effect of getter is initializing + getProgressService(); + } + }); + /* * Phase 1 of the initialization of commands. When this phase completes, * all the services and managers will exist, and be accessible via the @@ -2128,8 +2162,8 @@ super.handleException(e); } }); - // ensure at least one window was opened - if (result[0].isOK() && windowManager.getWindows().length == 0) { + // ensure at least one window was opened, only when appMenu isn't there + if (shouldReturnNoWindowError(result[0])) { String msg = WorkbenchMessages.Workbench_noWindowsRestored; result[0] = new Status(IStatus.ERROR, WorkbenchPlugin.PI_WORKBENCH, IWorkbenchConfigurer.RESTORE_CODE_RESET, msg, null); @@ -2137,6 +2171,23 @@ return result[0]; } + private boolean shouldReturnNoWindowError(final IStatus result) { + + final boolean[] shouldReturn = new boolean[1]; + // first check for the result & no of windows + shouldReturn[0] = result.isOK() && windowManager.getWindows().length == 0; + if (shouldReturn[0]) { + // if result is ok and there is no window, check for appMenu + display.syncExec(new Runnable() { + public void run() { + // return error if there is no appMenu + shouldReturn[0] = display.getAppMenuBar() == null; + } + }); + } + return shouldReturn[0]; + } + /* * (non-Javadoc) Method declared on IWorkbench. */ @@ -2988,6 +3039,11 @@ ((GrabFocus) Tweaklets.get(GrabFocus.KEY)).dispose(); + deactivateWorkbenchContext(); + + if(applicationMenuMgr != null) + applicationMenuMgr.dispose(); + // Bring down all of the services. serviceLocator.dispose(); @@ -3009,6 +3065,7 @@ } } + /** * Cancels the early startup job, if it's still running. */ @@ -3709,6 +3766,9 @@ */ private MenuSourceProvider menuSourceProvider; + private IContextActivation workbenchContext; + + private ApplicationMenuManager applicationMenuMgr; /** @@ -3816,4 +3876,30 @@ }; } + private void createApplicationMenu(Menu appMenu) { + + applicationMenuMgr = new ApplicationMenuManager(appMenu); + IMenuService menuService = (IMenuService) serviceLocator.getService(IMenuService.class); + menuService.populateContributionManager(applicationMenuMgr, MenuUtil.APPLICATION_MENU); + applicationMenuMgr.update(true); + } + + private void activateWorkbenchContext() { + IContextService contextService = (IContextService) serviceLocator + .getService(IContextService.class); + workbenchContext = contextService.activateContext(IContextService.CONTEXT_ID_WORKBENCH); + } + + private void deactivateWorkbenchContext() { + if(workbenchContext == null) + return; + workbenchContext.getContextService().deactivateContext(workbenchContext); + } + + + private Menu getAppMenu() { + IWorkbench workbench = getWorkbenchConfigurer().getWorkbench(); + return workbench.getDisplay().getAppMenuBar(); + } + } Index: Eclipse UI/org/eclipse/ui/internal/WorkbenchWindow.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchWindow.java,v retrieving revision 1.419 diff -u -r1.419 WorkbenchWindow.java --- Eclipse UI/org/eclipse/ui/internal/WorkbenchWindow.java 30 Sep 2010 07:56:23 -0000 1.419 +++ Eclipse UI/org/eclipse/ui/internal/WorkbenchWindow.java 14 Dec 2010 09:10:59 -0000 @@ -722,17 +722,8 @@ updateDisabled = true; try { - // Only do the check if it is OK to close if we are not closing - // via the workbench as the workbench will check this itself. Workbench workbench = getWorkbenchImpl(); - int count = workbench.getWorkbenchWindowCount(); - // also check for starting - if the first window dies on startup - // then we'll need to open a default window. - if (!workbench.isStarting() - && !workbench.isClosing() - && count <= 1 - && workbench.getWorkbenchConfigurer() - .getExitOnLastWindowClose()) { + if (shouldCloseWorkbench(workbench)) { windowClosed = workbench.close(); } else { if (okToClose()) { @@ -755,6 +746,38 @@ } /** + * + * Checks and returns whether we should close the workbench when closing + * this window + * + * @param workbench + * @return true, if the workbench needs to be closed, + * false otherwise + */ + private boolean shouldCloseWorkbench(Workbench workbench) { + + // also check for starting - if the first window dies on startup + // then we'll need to open a default window. + + if (workbench.isStarting()) + return false; + + // Only do the check if it is OK to close if we are not closing + // via the workbench as the workbench will check this itself. + if (workbench.isClosing()) + return false; + + int count = workbench.getWorkbenchWindowCount(); + + // we have more windows apart from this. Dont' close workbench + if(count >1 ) + return false; + + // now do whatever the workbenchconfigurer says ... + return workbench.getWorkbenchConfigurer().getExitOnLastWindowClose(); + } + + /** * Opens a new page. Assumes that busy cursor is active. *

* Note: Since release 2.0, a window is limited to contain at most Index: Eclipse UI/org/eclipse/ui/menus/MenuUtil.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/menus/MenuUtil.java,v retrieving revision 1.9 diff -u -r1.9 MenuUtil.java --- Eclipse UI/org/eclipse/ui/menus/MenuUtil.java 1 Jun 2010 19:22:34 -0000 1.9 +++ Eclipse UI/org/eclipse/ui/menus/MenuUtil.java 14 Dec 2010 09:10:59 -0000 @@ -19,6 +19,14 @@ * @noinstantiate This class is not intended to be instantiated by clients. */ public class MenuUtil { + /** + * + * Application Menu + * + * @since 3.7 + * + * */ + public final static String APPLICATION_MENU = "menu:org.eclipse.ui.application.menu"; //$NON-NLS-1$ /** Main Menu */ public final static String MAIN_MENU = "menu:org.eclipse.ui.main.menu"; //$NON-NLS-1$ /** Main ToolBar (CoolBar) */