Bug 494026 - Switching perspective during restoring of the window state breaks the restored perspective
Summary: Switching perspective during restoring of the window state breaks the restore...
Status: CLOSED WONTFIX
Alias: None
Product: Platform
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 4.4.2   Edit
Hardware: PC Mac OS X
: P3 normal with 1 vote (vote)
Target Milestone: ---   Edit
Assignee: Platform UI Triaged CLA
QA Contact:
URL:
Whiteboard: stalebug
Keywords: helpwanted
Depends on:
Blocks:
 
Reported: 2016-05-19 10:08 EDT by Andreas Pakulat CLA
Modified: 2020-03-02 08:40 EST (History)
2 users (show)

See Also:


Attachments
RCP application example reproducing the problem (134.77 KB, application/zip)
2016-05-20 05:49 EDT, Andreas Pakulat CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Andreas Pakulat CLA 2016-05-19 10:08:59 EDT
In an RCP product we want to ensure that after startup a particular perspective (lets call it Management) is active. This is currently done from the postWindowCreate callback in the ApplicationWorkbenchWindowAdvisor subclass via a call to IWorkbench.showPerspective. It has worked just fine while basing our product on Eclipse 3, however since we switched to using Eclipse 4 as target platform (leveraging the compatibility layer) this can break other perspectives.

The problem happens when the product is being shut down with a different perspective (lets call it Spy) being active. In that case the postWindowCreate function and our showPerspective call seem to interrupt the restoring of that Spy perspective causing the various widgets belonging to views and editors of the perspective to be not created in the Eclipse 4 UI Model. In turn this means once the user switches to the Spy perspective later on he's going to be greeted with a nearly empty window, since many or all of the views and editors are not shown. The logfile indicates why this happens, LazyStackRenderer.showElementRecursive gets a null reference from its call to ph.getRef().getWidget().

Its not quite clear to me at the moment wether the usage of the postWindowCreate hook is considered a misuse, but it seems there's not really any other option if I want to ensure a nice startup procedure but keep the enforcement of the Management perspective. I've experimented with various window-change and perspective-change listeners, but the only working option is an asyncExec from the first IPerspectiveListener.perspectiveChanged notification. That seems to run the showPerspective late enough for the restoring to be completed, but it causes a rather visible flickering of the UI at startup as the Spy perspective is fully setup and then the other one is created.

I hope that based on this the compatibility layer can be improved such that postWindowCreate is called at a point where switching the perspective does not break the restoring of the UI but also does not cause such visual flickering of the window.

The full stacktrace from the LazyStackRenderer NPE is:

!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/ui/ElementContainer/selectedElement/SET] to handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@6a909132
!STACK 0
java.lang.NullPointerException
        at org.eclipse.e4.ui.workbench.renderers.swt.LazyStackRenderer.showElementRecursive(LazyStackRenderer.java:233)
        at org.eclipse.e4.ui.workbench.renderers.swt.LazyStackRenderer.showElementRecursive(LazyStackRenderer.java:276)
        at org.eclipse.e4.ui.workbench.renderers.swt.LazyStackRenderer.showElementRecursive(LazyStackRenderer.java:282)
        at org.eclipse.e4.ui.workbench.renderers.swt.LazyStackRenderer.showElementRecursive(LazyStackRenderer.java:282)
        at org.eclipse.e4.ui.workbench.renderers.swt.LazyStackRenderer.showElementRecursive(LazyStackRenderer.java:282)
        at org.eclipse.e4.ui.workbench.renderers.swt.LazyStackRenderer.showElementRecursive(LazyStackRenderer.java:282)
        at org.eclipse.e4.ui.workbench.renderers.swt.LazyStackRenderer.showTab(LazyStackRenderer.java:162)
        at org.eclipse.e4.ui.workbench.renderers.swt.PerspectiveStackRenderer.showTab(PerspectiveStackRenderer.java:109)
        at org.eclipse.e4.ui.workbench.renderers.swt.LazyStackRenderer$1.handleEvent(LazyStackRenderer.java:69)
        at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:40)
        at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:187)
        at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:156)
        at org.eclipse.swt.widgets.Display.syncExec(Display.java:4732)
        at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:218)
        at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:36)
        at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:197)
        at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197)
        at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1)
        at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
        at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
        at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135)
        at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78)
        at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39)
        at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:81)
        at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:59)
        at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374)
        at org.eclipse.e4.ui.model.application.ui.advanced.impl.PerspectiveStackImpl.setSelectedElement(PerspectiveStackImpl.java:135)
        at org.eclipse.e4.ui.model.application.ui.advanced.impl.PerspectiveStackImpl.setSelectedElement(PerspectiveStackImpl.java:1)
        at org.eclipse.e4.ui.workbench.addons.perspectiveswitcher.PerspectiveSwitcher$16.widgetSelected(PerspectiveSwitcher.java:622)
        at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:248)
        at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
        at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4199)
        at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1467)
        at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1490)
        at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1475)
Comment 1 Patrik Suzzi CLA 2016-05-19 12:25:31 EDT
Andreas, 

This seems a complex question that should be asked on Forums. 

IMHO, When porting the application to E4, you should consider using E4 Lifecycle events. There are several tutorials you can follow. 

So, unless you can provide steps to reproduce,
I think I should close this as worksforme. 

However, since you define your own application, in case of startup, you can: 
1. Reference your ApplicationLifecycle handler class from plugin.xml
2. write your lifecycle handler class
3. Add an hook to handle events at UILifeCycle.APP_STARTUP_COMPLETE

Does this helps ?

Below you see some references.

#1 http://www.vogella.com/tutorials/Eclipse4LifeCycle/article.html#lifecycle_implementationexample
#2 http://stackoverflow.com/questions/14061491/eclipse-e4-istartup-extension-not-working/35222525#35222525
#3 http://stackoverflow.com/questions/33755200/workbenchwindowadvisorpostwindowcreate-never-fired
Comment 2 Andreas Pakulat CLA 2016-05-19 15:07:14 EDT
We're actually not really porting our application to E4, though we indeed have a dependency to E4 code now in the plugin that defines the application as this is required with Eclipse 4.4 (can't recall the details from the top of my head though). We currently still need to be able to install most of our plugins into Eclipse 3 installations, so introducing Eclipse 4 dependencies in general is not possible yet. However for the application-defining plugin that may work as its only shipped in the product and that one is not going back to Eclipse 3 anymore, so thanks for the hints I'll have a closer look at that.

I still consider the behavior I'm experiencing a bug in the compatibility layer, either in the restoring of the E4 UI model from disk that can be 'interrupted' by a perspective switch or the point at which the postWindowCreate hook is being called. So I think its justified to open a bugreport about this.
Comment 3 Andreas Pakulat CLA 2016-05-20 05:49:19 EDT
Created attachment 261879 [details]
RCP application example reproducing the problem

Since you asked for an example, the attached eclipse application project enforces that on startup the "RCPPerspective" is being shown. If you exit the application with another perspective open and then start it again the RCPPerspective will be active. Switching back to the perspective that was open when you exited the application manually keeps showing the layout of the RCPPerspective and the NPE is logged to the metadata log. Closing the perspective and reopening it fixes that issue.
Comment 4 Andreas Pakulat CLA 2016-05-20 05:53:33 EDT
Also just tried to use the postWindowOpen hook instead of postWindowCreate, but that still seems to be called too early.
Comment 5 Patrik Suzzi CLA 2016-05-21 07:02:18 EDT
Let me try to summarize:

You're using Eclipse 4.4 as Platform. On top of it, you run your plugins using the compatibility layer. 

Your plug-ins are Eclipse 3.x, but they also have E4 dependencies. 

The bug seems in the compatibility layer, and the problem is: 
- in pure E 3.x application, the postWindowCreate was called in a way that the code attached is working
- in an E4 application with compat layer, the postWindowCreate is called in a way that results in a NullPointerException (NPE)

Tell me if this is correct. If not, please, help me complementing this information. 

Regards.
Comment 6 Andreas Pakulat CLA 2016-05-23 06:41:15 EDT
Yes, thats mostly correct. Just one thing: Our plugin's generally have no e4 dependencies, only the one that hosts the Application instance and the corresponding *Advisor classes has a dependency onto org.eclipse.e4.ui.workbench (we're importing some things from the internal classes of org.eclipse.ui.workbench and that one now uses code from org.eclipse.e4.ui.workbench in Eclipse 4.4)
Comment 7 Annika Karjakina CLA 2017-10-04 20:26:34 EDT
Any updates on this one? We're seeing this a lot, too.
Comment 8 Eclipse Genie CLA 2020-03-02 08:40:10 EST
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. As such, we're closing this bug.

If you have further information on the current state of the bug, please add it and reopen this bug. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.