eclipse-platform / eclipse.platform.ui

Eclipse Platform
https://projects.eclipse.org/projects/eclipse.platform
Eclipse Public License 2.0
71 stars 155 forks source link

Onboarding information (and primary data stack) lost when splitting editor area #1773

Closed HeikoKlare closed 3 months ago

HeikoKlare commented 3 months ago

Let's make sure issue is not already fixed in latest builds first.

Steps to reproduce

From a fresh installation and clean workspace (Java IDE product):

  1. You start seeing the onboarding information in the shared area. image
  2. Open any two files and show them side-by-side by splitting the shared area. image
  3. Close the left editor first, then close the remaining (originally right) editor. Now the onboarding information is lost. image

It is expected to still have the onboarding information in the shared area after closing all editors, even if the area has been split before.

Workaround

Opening a new workbench window (and closing the existing one) restores the shared area with the onboarding information.

Tested under this environment

Issue is independent from environment. Lost onboarding information can be seen since 2023-06 release (i.e., since introduction of onboarding information), but underlying problem has been existing before. The screenshots are taken from the following system.

Community

Technical analysis

Whenever you split the shared area, so that it contains multiple part stacks, and then close the last editor in the original part stack (which is the "primaryDataStack"), the "primaryDataStack" will be lost.

The code that removes a part stack is this, precisely the call ensureComposite(areaModel, stacks): https://github.com/eclipse-platform/eclipse.platform.ui/blob/e6309193420f45895654d404d9f2adf875ca9432/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/AreaRenderer.java#L218-L231

When you close the last editor in the primary data stack, that part stack will simply be removed. Then no part stack being the primary and potentially also no part stack being tagged as EditorStack remains.

Interestingly, the part stacks with element id PartStack@XXX are no dangling references, That's just the result of some fallback code to ensure that every part stack has an element id: https://github.com/eclipse-platform/eclipse.platform.ui/blob/e6309193420f45895654d404d9f2adf875ca9432/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/StackRenderer.java#L701-L704

Expected technical behavior

I would expect the following behavior:

The creation of a new part stack by splitting an area via drag & drop is handled in SplitDropAgend2#drop(): https://github.com/eclipse-platform/eclipse.platform.ui/blob/e6309193420f45895654d404d9f2adf875ca9432/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/dndaddon/SplitDropAgent2.java#L293-L298 You can see that this new part stack will never be tagged as "EditorStack". When such a part stack becomes the last remaining in the shared area, without any editor open, the onboarding information is not shown as this depends on presence of exactly that tag: https://github.com/eclipse-platform/eclipse.platform.ui/blob/e6309193420f45895654d404d9f2adf875ca9432/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/StackRenderer.java#L709-L711

This issue has been detected when analyzing #1570. Once this issue has been addressed, #1570 should be revisited.

HeikoKlare commented 3 months ago

For documentation purposes, this is a preliminary solution to avoid that the primary data stack gets lost, which I had already shared here: https://github.com/eclipse-platform/eclipse.platform.ui/issues/1570#issuecomment-1961015165

With the following adaptation of AreaRenderer#synchCTFState(), the current removal of the primary data stack can be avoided by passing it to the first remaining part stack. However, this is not a clean solution yet, which is why I do not propose it in a PR:

    private void synchCTFState(MArea areaModel) {
        final String primaryDataStackId = "org.eclipse.e4.primaryDataStack"; //$NON-NLS-1$
        List<MPartStack> stacks = findDirectStacks(areaModel);
        List<MPartStack> visibleStacks = new ArrayList<>();
        boolean removingPrimaryDataStack = false;
        for (MPartStack stack : stacks) {
            if (stack.isToBeRendered()) {
                visibleStacks.add(stack);
            } else {
                if (primaryDataStackId.equals(stack.getElementId())) {
                    removingPrimaryDataStack = true;
                }
            }
        }

        if (removingPrimaryDataStack && !visibleStacks.isEmpty()) {
            MPartStack newEditorStack = visibleStacks.get(0);
            newEditorStack.setElementId(primaryDataStackId);
            newEditorStack.getTags().add(primaryDataStackId);
            newEditorStack.getTags().add("EditorStack"); //$NON-NLS-1$
        }
        // If there's more than one stack visible we use a CTF
        if (visibleStacks.size() > 1)
            ensureCTF(areaModel, stacks);
        else {
            ensureComposite(areaModel, stacks);
        }
    }