-
Notifications
You must be signed in to change notification settings - Fork 29.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add output.showQuietly
to stop extensions activating Output view (fix #105270)
#205225
base: main
Are you sure you want to change the base?
Conversation
/assign @sandy081 Please consider this. Feedback welcome. |
I am wondering why this is output only feature. An extension can open any view in the panel for eg., terminal and should we have a setting per view? Please consider a general solution. |
CC @sbatten |
@sandy081 AFAIK these are the API classes with methods an extension can use and which could cause a view container to change what it is presenting to the user:
I didn't find any built-in commands that could have this kind of effect. My PR currently addresses the first two, which both act on the Output view. One idea for a generalized approach would be a "workbench.view.showQuietly": {
"workbench.panel.output": true, // the PR's current extent
"terminal": true,
"foo.bar.tree": true,
"foo.bar.webview": true,
...
} What do you think? |
I would ask @sbatten for his opinion here. |
It certainly makes sense that some of these could be covered as well, as noted by the other feature request. One thing: I'm not sure if |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code looks good to me. Not sure if my approval counts for anything here but I'd like to move this along if I can. :)
EDIT: As I suspected mine doesn't count for collaborator approvals. Really hope the VS Code team doesn't ignore this like they've ignored the years of bug reports leading up to it. 🙄
Sorry for the wait @gjsjohnmurray. As this is adding a new Setting, I'd like to make sure this is actually something we should be fixing as it is actually caused by extensions. The issue currently only mentions one extension and the output view. If this is the main problem then we should make sure the problem is solved by the extension. If the problem needs to be in core, we need to understand if it is an output problem or a view revealing problem. I'll continue the conversation in the issue first. |
It's definitely an issue with multiple extensions - it's particularly frustrating with dev containers as each extension initializes with slightly different timing and the net user experience is stolen focus to open the Output pane several times. I think more broadly, trying to fix a distributed problem is going to perpetuate this bad UX. I don't want anything stealing focus out of my editor, and I'd love a setting to enforce that instead of trying to convince a half dozen extension maintainers to do the right thing 😅 |
@gjsjohnmurray I would suggest to rebase and cleanup the commits instead of adding all those merge commits, apart from that it looks good. I hope a compromise will be found and wish this gets merged 🙌🏻 |
@phaberest GH tells me it can't be rebased due to conflicts. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are still unsure if this should be only for the output view or a general solution for all kind of view revealing. Let's start off with having this for the output view only and we can expand it to all if needed. As this should only block extensions from revealing, lets move the logic a layer up.
@benibenj I will try and work on this next week. |
@benibenj I have pushed changes to implement what you suggested. I put the indicator next to the notifications bell because it serves a similar purpose and users are probably used to keeping half an eye on that corner. Hovered: |
Here's one way to test this PR:
Now build VS Code from this PR's branch, run it, and follow these steps:
Set |
@benibenj does this PR still stand a chance of being approved in time for next week's edngame? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested it, I like the way it behaves. I think it is likely that this will also be adopted to other views so I wonder if we should already consider using a setting name which is not specific to output. Maybe "workbench.view.showQuietly"
as you suggested before. It could be boolean for now and then later be expanded to boolean | object
(obect with view IDs)
private readonly _configurationService: IConfigurationService; | ||
private readonly _statusbarService: IStatusbarService; | ||
|
||
private _outputStatusItem: IStatusbarEntryAccessor | undefined; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about making this a MutableDisposable
of type IStatusbarEntryAccessor
and registering it here so it gets disposed when MainThreadOutputService
gets disposed.
|
||
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostOutputService); | ||
|
||
const setVisibleChannel = () => { | ||
const visibleChannel = this._viewsService.isViewVisible(OUTPUT_VIEW_ID) ? this._outputService.getActiveChannel() : undefined; | ||
this._proxy.$setVisibleChannel(visibleChannel ? visibleChannel.id : null); | ||
this._outputStatusItem?.dispose(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would then be this._outputStatusItem.value = undefined;
public async $reveal(channelId: string, preserveFocus: boolean): Promise<void> { | ||
const channel = this._getChannel(channelId); | ||
if (channel) { | ||
this._outputService.showChannel(channel.id, preserveFocus); | ||
if (this._viewsService.isViewVisible(OUTPUT_VIEW_ID) || !this._configurationService.getValue('output.showQuietly')) { | ||
this._outputService.showChannel(channel.id, preserveFocus); | ||
return; | ||
} | ||
|
||
// Show status bar indicator | ||
const statusProperties: IStatusbarEntry = { | ||
name: localize('status.showOutput', "Show Output"), | ||
text: '$(output)', | ||
ariaLabel: localize('status.showOutputAria', "Show {0} Output Channel", channel.label), | ||
command: `workbench.action.output.show.${channel.id}`, | ||
tooltip: localize('status.showOutputTooltip', "Show {0} Output Channel", channel.label), | ||
kind: 'prominent' | ||
}; | ||
if (!this._outputStatusItem) { | ||
this._outputStatusItem = this._statusbarService.addEntry( | ||
statusProperties, | ||
'status.showOutput', | ||
StatusbarAlignment.RIGHT, | ||
{ id: 'status.notifications', alignment: StatusbarAlignment.LEFT }, | ||
); | ||
} else { | ||
this._outputStatusItem.update(statusProperties); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just for readability:
- Can we do
if (!channel)
and return to remove nesting - Have a private method called
_showChannelQuietly(channel)
- Change the if statement to
if (!this._viewsService.isViewVisible(OUTPUT_VIEW_ID) && this._configurationService.getValue('output.showQuietly'))
then callthis._showChannelQuietly(channel)
and return and havethis._outputService.showChannel
at the end outside any if statement
This PR fixes #105270
When the new
output.showQuietly
setting is true calls toOutputChannel.show
orLogOutputChannel.show
when Output view is not visible will produce a silent notification rather than showing the view.Like all silent notifications this will add a dot to the bell icon at the right-hand end of the status bar. Clicking on this will show the notification which includes a button to show the Output view and the channel.