microsoft / vscode

Visual Studio Code
https://code.visualstudio.com
MIT License
163.18k stars 28.84k forks source link

Include the name of the currently focused view in the window title #97790

Closed mrob95 closed 1 year ago

mrob95 commented 4 years ago

Hi, would it be possible to add a setting to modify the title of the VSCode window to include the currently focused panel (editor, terminal, explorer etc)?

I use dictation software for all coding and the easiest way to activate and deactivate sets of commands is by matching on the window title, so for example .py in the window title activates Python commands. It would be useful to be able to activate a certain set of commands for editing code and a different set of commands when using the integrated terminal.

isidorn in the accessibility Gitter channel suggested this be implemented by allowing something like ${focusedView} in the window.title setting, and I think this would work well.

Thanks

isidorn commented 4 years ago

Thanks for filling this. I think it is a fair feature request. @bpasero let me know what you think, and maybe we open this to PRs?

auphofBSF commented 4 years ago

I as a user of dictation software and contributor to TalonVoice , particularly a set of cross platform VSCODE voice commands, know that showing the focused view in the title bar would be a simple welcome addition to context management. Thank you for considering this feature-request, I hope we can see it soon

isidorn commented 4 years ago

I am opening this up for PRs. We should tackle this by adding a new variable ${focusedView} to the window.title setting Code pointer https://github.com/microsoft/vscode/blob/cb29362cc79fa0c64d29857aa3becd787176203b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts#L235

daniel-j-davis commented 4 years ago

I'd like to take this one, @isidorn. I've had a skim through the code already, and have a pretty good idea on the work that has to be done, but just wanted to ask for a pointer on where I would get an instance of the focused panel. I did some digging and saw that there's a panel service, that isn't currently used in the TilebarPart class at all, but wasn't sure if it's possible to get the panel from one of the existing services used?

EDIT: dug some more, and seems like it probably isn't the panel service that I'm looking for, so instead just hoping for a pointer on the best way to figure out what's focused.

isidorn commented 4 years ago

@daniel-j-davis great, thanks for offering to look into this. I would start by trying to use the FocusedViewContext Code pointer https://github.com/microsoft/vscode/blob/1b65c639c2a45ce27c350cd98a6d22cd3664c4ff/src/vs/workbench/common/views.ts#L499

You can see how other people are using it. I was expecting that the viewsService has some nicer api to get the focused view, but there does not seem to be anything like that. @sbatten can correct me if I missed something

daniel-j-davis commented 4 years ago

Yeah, I tried using FocusedViewContext but unless I'm doing something wrong, it doesn't always seem to return what the focused view is. It definitely returns workbench.explorer.fileView when you're clicking through to preview files, and workbench.view.search when you're clicking through search results, but getting an empty string when tabbing between editors, and nothing at all when terminal is focused. I'll keep digging to see if there's a better way to get the focused view, or if I'm missing something with my implementation of FocusedViewContext, but I'm wondering if the optimal approach is to spin another issue up to add a method to the viewsService to get the focused view. Thoughts? @isidorn

isidorn commented 4 years ago

@daniel-j-davis we might be missing a method to get the active part. @sbatten and @sandy081 would know more, I think it is missing.

sandy081 commented 4 years ago

Not sure if it is a good idea to use FocusedViewContext as this is set and unset when a view is focused or not. Also getting a focused view is very difficult but you might ask for visible views just like visible editors.

You can use IViewsService and IViewDescriptorService to get visible view container and thereby visible views.

daniel-j-davis commented 4 years ago

It seems like (at least with the current implementation), it's not going to be possible to determine the focused view, I guess. I don't think that getting visible views would be able to solve this issue, because (at least as I understand it), if the terminal and explorer are both visible, those will constitute "visible views" but only one of them will be in focus.

I'll definitely keep thinking to see if there's some other reasonable approach to implementation that I'm missing, but judging by our discussion so far, it seems like this would require somewhat of a refactor in other services before we'd be able to satisfy the ask in this issue. Let me know if I misunderstood or I'm missing something here. @isidorn @sandy081

isidorn commented 4 years ago

@daniel-j-davis I think you got the state of things quite well. There simple is missing API to get the focused view. Last chance idea: there is the workbenchLayoutService for which you can pass a part and figure out if it is focused. Code pointer https://github.com/microsoft/vscode/blob/6a7a91bc8cfc3fbd44c8ae7bb2249610ea7ce883/src/vs/workbench/services/layout/browser/layoutService.ts#L94

daniel-j-davis commented 4 years ago

@isidorn I just trialled implementation using the workbenchLayoutService like you suggested, and while it gets us closer to where we want to be, it still doesn't seem to do the job. this.layoutService.hasFocus(Parts.EDITOR_PART) returns true when you're typing in the editor, and this.layoutService.hasFocus(Parts.SIDEBAR_PART) returns true when you're clicking through the file explorer, but there's two concerns here from what I can tell:

  1. I don't think there's going to be a reliable way to determine what panel is focused, I guess the terminal is considered a panel, but there can also be a bunch of other panels in the layout at the same time, and this only seems to return whether or not any panel is focused.
  2. Similarly to my first concern, I guess the sidebar houses a lot more than just the file explorer, so we'd only be able to reliably that whether or not the sidebar is focused, but not which element of the sidebar has focus.
isidorn commented 4 years ago

@daniel-j-davis correct. It would have to be used in the cominbation with the view service. i.e what is focus from the layoutService + what is visible from teh view service. Though this might be too clunky.

daniel-j-davis commented 4 years ago

@isidorn to keep you updated, I just tried a solution where I would check what part has focus:

const isEditorFocus = this.layoutService.hasFocus(Parts.EDITOR_PART); const isSidebarFocus = this.layoutService.hasFocus(Parts.SIDEBAR_PART); const isPanelFocus = this.layoutService.hasFocus(Parts.PANEL_PART);

And if the editor is focused, then we know it's an editor that's active, if the sidebar is focused, then I check to see what viewlet is active, and if a panel has focus, then I check to see what panel is active — but long story short, it's pretty clunky with what it spits out, and I'm having some difficulty with determining whether or not the terminal/debug panel is active. I'm eager to see if there's some other way that I could determine whether or not the terminal is being used because we're on the right track but echoing your concerns that this might be too clunky.

sandy081 commented 4 years ago

Please feel free to add an API in IViewsService to get the focused view. I think that might solve this easily.

daniel-j-davis commented 4 years ago

I'll take a look at adding that API in IViewsService, do you want me to create another issue, something like Add API to get currently focused view in views service so that there's separation of tasks here? @sandy081

isidorn commented 4 years ago

@daniel-j-davis if adding this APi turns out to be simple feel free to just create one PR with everything and I can review it all.

daniel-j-davis commented 4 years ago

Seems like it's going to be a little bit more complicated than I hoped to add this API method, and not sure it's something that I'll be able to do with my (limited) knowledge of the code base. I'd still like to fulfil the original issue once the API method has been added, but it may be better if somebody else who is more familiar with the code base could take the API method work item. @isidorn

isidorn commented 4 years ago

@daniel-j-davis makes sense. Thanks for giving it a try!

NotWearingPants commented 4 years ago

@isidorn I'm happy to tackle this, but I think this requires a lot of help from you guys.

If you put a logpoint in the only place that FocusedViewContext is being changed: https://github.com/microsoft/vscode/blob/e0d4a2fe2d57019a5b3709ff16e2331e46a612df/src/vs/workbench/browser/parts/views/viewPaneContainer.ts#L270 that prints {this.id}, and then try to focus different parts of vscode, you will see that many things don't even trigger a change to this value, and also that the outline and timeline views are only called "outline" and "timeline" instead of having fully qualified names, and also focusing an editor doesn't change this value at all.

Also, IViewsService can only tell what is currently being shown in the panel or sidebar, not which of them is actually focused. Also it only knows about view "containers", so it can only say things like "explorer" but not "outline".

This looks like it requires a change in how views are handled, the whole thing looks like a mess. Please help :P (@sbatten, @sandy081)

sandy081 commented 4 years ago

then try to focus different parts of vscode, you will see that many things don't even trigger a change to this value

We use focus tracker for this and it shall trigger it when the view is focused or blurred

https://github.com/microsoft/vscode/blob/5eb21f5767e37339f473b1b9a876b9290f4253b6/src/vs/workbench/browser/parts/views/viewPaneContainer.ts#L267-L267

and also that the outline and timeline views are only called "outline" and "timeline" instead of having fully qualified names,

They do not have fully qualified names as they got registered with these ids.

Also, IViewsService can only tell what is currently being shown in the panel or sidebar, not which of them is actually focused.

Yes, that's what I mentioned before 😄 and this need to be added.

Also it only knows about view "containers", so it can only say things like "explorer" but not "outline".

It also knows about views.

I understand that it is not easy code to go through. @isidorn Do you still think you want this to be help-wanted ?

isidorn commented 4 years ago

@sandy081 thanks for providing more details. Yeah let's remove help-wanted for now.

LexiconCode commented 4 years ago

As a possible alternative is to use "when" expressions from the keyboard shortcuts. This would allow us to have much more fine-grained contexts then simply using focused view in the window title.

  "key": "ctrl+alt+up",
  "command": "editor.action.insertCursorAbove",
  "when": "editorTextFocus"
}

The downside is they can become quite long.

editorTextFocus && inputFocus && notebookEditorFocused && notebookEditorCursorAtBoundary != 'none' && notebookEditorCursorAtBoundary != 'top'

Either way this enhances accessibility for voice coding. Thank you!

isidorn commented 1 year ago

This is awesome Megan! Let's make sure to include it in our release notes. And maybe also have a mini test plan item for it?