eclipse-theia / theia

Eclipse Theia is a cloud & desktop IDE framework implemented in TypeScript.
http://theia-ide.org
Eclipse Public License 2.0
19.99k stars 2.5k forks source link

Bug in editor/title when opening editors side by side #8921

Open avishaik opened 3 years ago

avishaik commented 3 years ago

Bug Description:

There is a bug that when using an extension that adds a button in the editor/title and opening editors side by side. When opening editors side by side it will add the button also to the other editor that does not fulfil the condition to show the button. This bug happens for new extensions, and not for built in extensions. It happens in Theia.

I used a simple extension to reproduce the bug. I created an extension that adds a button on the editor/title when a file have .json extension. See example:

        "menus": {
            "editor/title": [
                {
                    "**when": "resourceExtname == .json**",
                    "command": "sbasbug.start",
                    "group": "navigation"
                }
            ]
        }

When having a side by side editors, the button appears (marked in yellow) in the 'test.json' file but also in the 'read.md' file, see in the example blow: image

When pressing back on the 'read.md' file it disappears for both of them. See below: image

The button should not appear on the read.md file (or any file without .json extension)

Steps to Reproduce:

I have a simple extension, that shows a button in the editor/title when the file is with a JSON extension. To reproduce it, please use the extension I supply and do the example with a readme (.md extension file) and a .json file. Because I debugged it and have some findings. The .md file is an example of a built in extension that shows a button and it works correctly (buttons on the .md files appears only on them), but it will be reproduced with other files that will be side by side with the .json file.

  1. Clone https://github.com/avishaik/vscode-editor-btn-bug
  2. Build it npm run package and add it as extension to theia
  3. Open a file with .md extension and press on the 'Open preview to the side' button
  4. To the right side panel open a file with a .json extension
  5. When pressing on the JSON file tab, the button shows both in the JSON file and in the readme file (.md extension)
  6. When pressing on the readme file tab, the button disappears from both the readme and the .json file

I debugged this code have some findings:

So I'm not sure if the issue is because it for some reason checks the editor twice in tab-bars.ts or because the parent in the context in monaco-context-key-service.ts is a different file from what it should be.

Adding item (button) on editor/title flow

It starts in tab-bars.ts in functionupdateToolbar, it will check to update 'read.md' file twice, 'test.json' once: image

Then we enter visibleItems function in tab-bar-toolbar.ts that checks which item should appear on the widget (editor/title): image

The issue happens in monaco-context-key-service.ts file in line 47, in what the keyContext now holds: image

The value itself does not contain the resourceExtNamebut we can see it belongs to the read.md, because the editorLangId is markdown: image

But when we go to the parent, we see values for the test.json file: image

What happens is the contextMatchesRules function search for the resourceExtName in the value, when it does not find it there is searches in the _parent, and in the _parent it's the .json, so it concludes the condition to be true and shows the button on the read.md editor.

Additional Information

avishaik commented 3 years ago

There is currently a workaround for this, to add editorFocus == true in the when clause. For example for the .json extesion:

        "menus": {
            "editor/title": [
                {
                    "when": "resourceExtname == .json && editorFocus == true",
                    "command": "sbasbug.start",
                    "group": "navigation"
                }
            ]
        }

In this case the button will appear only when the file with json extension is in focus, and won't appear in the other editor.