diff --git a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts index b35ef9cc087ad..ae20fb999fe28 100644 --- a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts @@ -27,7 +27,7 @@ import Constants from 'vs/workbench/contrib/markers/browser/constants'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; -import { IShellLaunchConfig, TERMINAL_PANEL_ID } from 'vs/workbench/contrib/terminal/common/terminal'; +import { IShellLaunchConfig, TERMINAL_VIEW_ID } from 'vs/workbench/contrib/terminal/common/terminal'; import { ITerminalService, ITerminalInstanceService, ITerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminal'; import { IOutputService } from 'vs/workbench/contrib/output/common/output'; import { StartStopProblemCollector, WatchingProblemCollector, ProblemCollectorEventKind, ProblemHandlingStrategy } from 'vs/workbench/contrib/tasks/common/problemCollectors'; @@ -289,7 +289,7 @@ export class TerminalTaskSystem implements ITaskSystem { return false; } const activeTerminalInstance = this.terminalService.getActiveInstance(); - const isPanelShowingTerminal = this.panelService.getActivePanel()?.getId() === TERMINAL_PANEL_ID; + const isPanelShowingTerminal = !!this.viewsService.getActiveViewWithId(TERMINAL_VIEW_ID); return isPanelShowingTerminal && (activeTerminalInstance?.id === terminalData.terminal.id); } @@ -312,7 +312,7 @@ export class TerminalTaskSystem implements ITaskSystem { this.previousTerminalInstance = undefined; } else { this.previousPanelId = this.panelService.getActivePanel()?.getId(); - if (this.previousPanelId === TERMINAL_PANEL_ID) { + if (this.previousPanelId === TERMINAL_VIEW_ID) { this.previousTerminalInstance = this.terminalService.getActiveInstance() ?? undefined; } this.terminalService.setActiveInstance(terminalData.terminal); diff --git a/src/vs/workbench/contrib/terminal/browser/media/scrollbar.css b/src/vs/workbench/contrib/terminal/browser/media/scrollbar.css index 8dcbaa4a4efa6..aaa2d80f59e27 100644 --- a/src/vs/workbench/contrib/terminal/browser/media/scrollbar.css +++ b/src/vs/workbench/contrib/terminal/browser/media/scrollbar.css @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -.monaco-workbench .panel.integrated-terminal .xterm-viewport { +.monaco-workbench .pane-body.integrated-terminal .xterm-viewport { /* Use the hack presented in http://stackoverflow.com/a/38748186/1156119 to get opacity transitions working on the scrollbar */ -webkit-background-clip: text; background-clip: text; @@ -11,31 +11,31 @@ transition: background-color 800ms linear; } -.monaco-workbench .panel.integrated-terminal .xterm-viewport::-webkit-scrollbar { +.monaco-workbench .pane-body.integrated-terminal .xterm-viewport::-webkit-scrollbar { width: 10px; } -.monaco-workbench .panel.integrated-terminal .xterm-viewport::-webkit-scrollbar-track { +.monaco-workbench .pane-body.integrated-terminal .xterm-viewport::-webkit-scrollbar-track { opacity: 0; } -.monaco-workbench .panel.integrated-terminal .xterm-viewport::-webkit-scrollbar-thumb { +.monaco-workbench .pane-body.integrated-terminal .xterm-viewport::-webkit-scrollbar-thumb { min-height: 20px; background-color: inherit; } -.monaco-workbench .panel.integrated-terminal .find-focused .xterm .xterm-viewport, -.monaco-workbench .panel.integrated-terminal .xterm.focus .xterm-viewport, -.monaco-workbench .panel.integrated-terminal .xterm:focus .xterm-viewport, -.monaco-workbench .panel.integrated-terminal .xterm:hover .xterm-viewport { +.monaco-workbench .pane-body.integrated-terminal .find-focused .xterm .xterm-viewport, +.monaco-workbench .pane-body.integrated-terminal .xterm.focus .xterm-viewport, +.monaco-workbench .pane-body.integrated-terminal .xterm:focus .xterm-viewport, +.monaco-workbench .pane-body.integrated-terminal .xterm:hover .xterm-viewport { transition: opacity 100ms linear; cursor: default; } -.monaco-workbench .panel.integrated-terminal .xterm .xterm-viewport::-webkit-scrollbar-thumb:hover { +.monaco-workbench .pane-body.integrated-terminal .xterm .xterm-viewport::-webkit-scrollbar-thumb:hover { transition: opacity 0ms linear; } -.monaco-workbench .panel.integrated-terminal .xterm .xterm-viewport::-webkit-scrollbar-thumb:window-inactive { +.monaco-workbench .pane-body.integrated-terminal .xterm .xterm-viewport::-webkit-scrollbar-thumb:window-inactive { background-color: inherit; } diff --git a/src/vs/workbench/contrib/terminal/browser/media/terminal.css b/src/vs/workbench/contrib/terminal/browser/media/terminal.css index 5ead0858d1356..1a0152f41790c 100644 --- a/src/vs/workbench/contrib/terminal/browser/media/terminal.css +++ b/src/vs/workbench/contrib/terminal/browser/media/terminal.css @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -.monaco-workbench .panel.integrated-terminal { +.monaco-workbench .pane-body.integrated-terminal { align-content: flex-start; align-items: baseline; display: flex; @@ -14,51 +14,51 @@ position: relative; } -.monaco-workbench .panel.integrated-terminal .terminal-outer-container { +.monaco-workbench .pane-body.integrated-terminal .terminal-outer-container { height: 100%; width: 100%; box-sizing: border-box; overflow: hidden; } -.monaco-workbench .panel.integrated-terminal .terminal-tab { +.monaco-workbench .pane-body.integrated-terminal .terminal-tab { height: 100%; } -.monaco-workbench .panel.integrated-terminal .terminal-wrapper { +.monaco-workbench .pane-body.integrated-terminal .terminal-wrapper { display: none; margin: 0 10px; } -.monaco-workbench .panel.integrated-terminal .terminal-wrapper.active { +.monaco-workbench .pane-body.integrated-terminal .terminal-wrapper.active { display: block; position: absolute; bottom: 2px; /* Matches padding-bottom on .terminal-outer-container */ top: 0; } -.monaco-workbench .panel.integrated-terminal .monaco-split-view2.horizontal .split-view-view:first-child .terminal-wrapper { +.monaco-workbench .pane-body.integrated-terminal .monaco-split-view2.horizontal .split-view-view:first-child .terminal-wrapper { margin-left: 20px; } -.monaco-workbench .panel.integrated-terminal .monaco-split-view2.horizontal .split-view-view:last-child .terminal-wrapper { +.monaco-workbench .pane-body.integrated-terminal .monaco-split-view2.horizontal .split-view-view:last-child .terminal-wrapper { margin-right: 20px; } -.monaco-workbench .panel.integrated-terminal .xterm a:not(.xterm-invalid-link) { +.monaco-workbench .pane-body.integrated-terminal .xterm a:not(.xterm-invalid-link) { /* To support message box sizing */ position: relative; } -.monaco-workbench .panel.integrated-terminal .terminal-wrapper > div { +.monaco-workbench .pane-body.integrated-terminal .terminal-wrapper > div { height: 100%; } -.monaco-workbench .panel.integrated-terminal .xterm-viewport { +.monaco-workbench .pane-body.integrated-terminal .xterm-viewport { margin-right: -10px; } -.monaco-workbench .panel.integrated-terminal .monaco-split-view2.horizontal .split-view-view:last-child .xterm-viewport { +.monaco-workbench .pane-body.integrated-terminal .monaco-split-view2.horizontal .split-view-view:last-child .xterm-viewport { margin-right: -20px; } -.monaco-workbench .panel.integrated-terminal canvas { +.monaco-workbench .pane-body.integrated-terminal canvas { /* Align the viewport and canvases to the bottom of the panel */ position: absolute; right: -20px; @@ -68,58 +68,58 @@ top: auto; } -.monaco-workbench .panel.integrated-terminal { +.monaco-workbench .pane-body.integrated-terminal { font-variant-ligatures: none; } -.monaco-workbench .panel.integrated-terminal .split-view-view { +.monaco-workbench .pane-body.integrated-terminal .split-view-view { box-sizing: border-box; } /* border-color is set by theme key terminal.border */ -.monaco-workbench .panel.integrated-terminal .monaco-split-view2.horizontal .split-view-view:not(:first-child) { +.monaco-workbench .pane-body.integrated-terminal .monaco-split-view2.horizontal .split-view-view:not(:first-child) { border-left-width: 1px; border-left-style: solid; } -.monaco-workbench .panel.integrated-terminal .monaco-split-view2.vertical .split-view-view:not(:first-child) { +.monaco-workbench .pane-body.integrated-terminal .monaco-split-view2.vertical .split-view-view:not(:first-child) { border-top-width: 1px; border-top-style: solid; } -.monaco-workbench .panel.integrated-terminal.enable-ligatures { +.monaco-workbench .pane-body.integrated-terminal.enable-ligatures { font-variant-ligatures: normal; } -.monaco-workbench .panel.integrated-terminal.disable-bold .xterm-bold { +.monaco-workbench .pane-body.integrated-terminal.disable-bold .xterm-bold { font-weight: normal !important; } /* Use the default cursor when alt is active to help with clicking to move cursor */ -.monaco-workbench .panel.integrated-terminal .terminal-outer-container.alt-active .xterm { +.monaco-workbench .pane-body.integrated-terminal .terminal-outer-container.alt-active .xterm { cursor: default; } -.monaco-workbench .panel.integrated-terminal .xterm { +.monaco-workbench .pane-body.integrated-terminal .xterm { position: absolute; bottom: 0; left: 0; user-select: none; -webkit-user-select: none; } -.monaco-workbench .panel.integrated-terminal .monaco-split-view2.vertical .split-view-view:not(:last-child) .xterm { +.monaco-workbench .pane-body.integrated-terminal .monaco-split-view2.vertical .split-view-view:not(:last-child) .xterm { /* When vertical and NOT the bottom terminal, align to the top instead to prevent the output jumping around erratically */ top: 0; bottom: auto; } -.monaco-workbench .panel.integrated-terminal .xterm:focus { +.monaco-workbench .pane-body.integrated-terminal .xterm:focus { /* Hide outline when focus jumps from xterm to the text area */ outline: none; } -.hc-black .monaco-workbench .panel.integrated-terminal .xterm.focus::before, -.hc-black .monaco-workbench .panel.integrated-terminal .xterm:focus::before { +.hc-black .monaco-workbench .pane-body.integrated-terminal .xterm.focus::before, +.hc-black .monaco-workbench .pane-body.integrated-terminal .xterm:focus::before { display: block; content: ""; border: 1px solid; @@ -131,23 +131,23 @@ z-index: 10; } -.hc-black .monaco-workbench .panel.integrated-terminal .monaco-split-view2.horizontal .split-view-view:not(:only-child) .xterm.focus::before, -.hc-black .monaco-workbench .panel.integrated-terminal .monaco-split-view2.horizontal .split-view-view:not(:only-child) .xterm:focus::before { +.hc-black .monaco-workbench .pane-body.integrated-terminal .monaco-split-view2.horizontal .split-view-view:not(:only-child) .xterm.focus::before, +.hc-black .monaco-workbench .pane-body.integrated-terminal .monaco-split-view2.horizontal .split-view-view:not(:only-child) .xterm:focus::before { right: 0; } -.monaco-workbench .panel.integrated-terminal .xterm .xterm-helpers { +.monaco-workbench .pane-body.integrated-terminal .xterm .xterm-helpers { position: absolute; top: 0; } -.monaco-workbench .panel.integrated-terminal .xterm .xterm-helper-textarea:focus { +.monaco-workbench .pane-body.integrated-terminal .xterm .xterm-helper-textarea:focus { /* Override the general vscode style applies `opacity:1!important` to textareas */ opacity: 0 !important; } -.vs-dark .monaco-workbench.mac .panel.integrated-terminal .terminal-outer-container:not(.alt-active) .terminal:not(.enable-mouse-events), -.hc-black .monaco-workbench.mac .panel.integrated-terminal .terminal-outer-container:not(.alt-active) .terminal:not(.enable-mouse-events) { +.vs-dark .monaco-workbench.mac .pane-body.integrated-terminal .terminal-outer-container:not(.alt-active) .terminal:not(.enable-mouse-events), +.hc-black .monaco-workbench.mac .pane-body.integrated-terminal .terminal-outer-container:not(.alt-active) .terminal:not(.enable-mouse-events) { cursor: -webkit-image-set(url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAAL0lEQVQoz2NgCD3x//9/BhBYBWdhgFVAiVW4JBFKGIa4AqD0//9D3pt4I4tAdAMAHTQ/j5Zom30AAAAASUVORK5CYII=') 1x, url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAAz0lEQVRIx2NgYGBY/R8I/vx5eelX3n82IJ9FxGf6tksvf/8FiTMQAcAGQMDvSwu09abffY8QYSAScNk45G198eX//yev73/4///701eh//kZSARckrNBRvz//+8+6ZohwCzjGNjdgQxkAg7B9WADeBjIBqtJCbhRA0YNoIkBSNmaPEMoNmA0FkYNoFKhapJ6FGyAH3nauaSmPfwI0v/3OukVi0CIZ+F25KrtYcx/CTIy0e+rC7R1Z4KMICVTQQ14feVXIbR695u14+Ir4gwAAD49E54wc1kWAAAAAElFTkSuQmCC') 2x) 5 8, text; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts index fe60ea195e663..c6f0946e123b0 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts @@ -20,10 +20,11 @@ import * as panel from 'vs/workbench/browser/panel'; import { getQuickNavigateHandler } from 'vs/workbench/browser/parts/quickopen/quickopen'; import { Extensions as QuickOpenExtensions, IQuickOpenRegistry, QuickOpenHandlerDescriptor } from 'vs/workbench/browser/quickopen'; import { Extensions as ActionExtensions, IWorkbenchActionRegistry } from 'vs/workbench/common/actions'; +import { Extensions as ViewContainerExtensions, IViewContainersRegistry, ViewContainerLocation, IViewsRegistry } from 'vs/workbench/common/views'; import { ClearSelectionTerminalAction, ClearTerminalAction, CopyTerminalSelectionAction, CreateNewInActiveWorkspaceTerminalAction, CreateNewTerminalAction, DeleteToLineStartTerminalAction, DeleteWordLeftTerminalAction, DeleteWordRightTerminalAction, FindNext, FindPrevious, FocusActiveTerminalAction, FocusNextPaneTerminalAction, FocusNextTerminalAction, FocusPreviousPaneTerminalAction, FocusPreviousTerminalAction, FocusTerminalFindWidgetAction, HideTerminalFindWidgetAction, KillTerminalAction, MoveToLineEndTerminalAction, MoveToLineStartTerminalAction, QuickOpenActionTermContributor, QuickOpenTermAction, RenameTerminalAction, ResizePaneDownTerminalAction, ResizePaneLeftTerminalAction, ResizePaneRightTerminalAction, ResizePaneUpTerminalAction, RunActiveFileInTerminalAction, RunSelectedTextInTerminalAction, ScrollDownPageTerminalAction, ScrollDownTerminalAction, ScrollToBottomTerminalAction, ScrollToNextCommandAction, ScrollToPreviousCommandAction, ScrollToTopTerminalAction, ScrollUpPageTerminalAction, ScrollUpTerminalAction, SelectAllTerminalAction, SelectDefaultShellWindowsTerminalAction, SelectToNextCommandAction, SelectToNextLineAction, SelectToPreviousCommandAction, SelectToPreviousLineAction, SplitInActiveWorkspaceTerminalAction, SplitTerminalAction, TerminalPasteAction, TERMINAL_PICKER_PREFIX, ToggleCaseSensitiveCommand, ToggleEscapeSequenceLoggingAction, ToggleRegexCommand, ToggleTerminalAction, ToggleWholeWordCommand, NavigationModeFocusPreviousTerminalAction, NavigationModeFocusNextTerminalAction, NavigationModeExitTerminalAction, ManageWorkspaceShellPermissionsTerminalCommand, CreateNewWithCwdTerminalAction, RenameWithArgTerminalAction, SendSequenceTerminalAction } from 'vs/workbench/contrib/terminal/browser/terminalActions'; -import { TerminalPanel } from 'vs/workbench/contrib/terminal/browser/terminalPanel'; +import { TerminalViewPane } from 'vs/workbench/contrib/terminal/browser/terminalView'; import { TerminalPickerHandler } from 'vs/workbench/contrib/terminal/browser/terminalQuickOpen'; -import { KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_NOT_VISIBLE, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_VISIBLE, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, TERMINAL_PANEL_ID, DEFAULT_LETTER_SPACING, DEFAULT_LINE_HEIGHT, TerminalCursorStyle, TERMINAL_ACTION_CATEGORY, KEYBINDING_CONTEXT_TERMINAL_A11Y_TREE_FOCUS, TERMINAL_COMMAND_ID } from 'vs/workbench/contrib/terminal/common/terminal'; +import { KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_NOT_VISIBLE, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_VISIBLE, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, TERMINAL_VIEW_ID, DEFAULT_LETTER_SPACING, DEFAULT_LINE_HEIGHT, TerminalCursorStyle, TERMINAL_ACTION_CATEGORY, KEYBINDING_CONTEXT_TERMINAL_A11Y_TREE_FOCUS, TERMINAL_COMMAND_ID } from 'vs/workbench/contrib/terminal/common/terminal'; import { registerColors } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; import { setupTerminalCommands } from 'vs/workbench/contrib/terminal/browser/terminalCommands'; import { setupTerminalMenu } from 'vs/workbench/contrib/terminal/common/terminalMenu'; @@ -36,6 +37,8 @@ import { registerShellConfiguration } from 'vs/workbench/contrib/terminal/common import { CONTEXT_ACCESSIBILITY_MODE_ENABLED } from 'vs/platform/accessibility/common/accessibility'; import { ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { BrowserFeatures } from 'vs/base/browser/canIUse'; +import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; +import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer'; registerSingleton(ITerminalService, TerminalService, true); @@ -362,15 +365,20 @@ registry.registerWorkbenchAction(SyncActionDescriptor.create(QuickOpenTermAction const actionBarRegistry = Registry.as(ActionBarExtensions.Actionbar); actionBarRegistry.registerActionBarContributor(Scope.VIEWER, QuickOpenActionTermContributor); -(Registry.as(panel.Extensions.Panels)).registerPanel(panel.PanelDescriptor.create( - TerminalPanel, - TERMINAL_PANEL_ID, - nls.localize('terminal', "Terminal"), - 'terminal', - 40, - TERMINAL_COMMAND_ID.TOGGLE -)); -Registry.as(panel.Extensions.Panels).setDefaultPanelId(TERMINAL_PANEL_ID); +const VIEW_CONTAINER = Registry.as(ViewContainerExtensions.ViewContainersRegistry).registerViewContainer({ + id: TERMINAL_VIEW_ID, + name: nls.localize('terminal', "Terminal"), + ctorDescriptor: new SyncDescriptor(ViewPaneContainer, [TERMINAL_VIEW_ID, TERMINAL_VIEW_ID, { mergeViewWithContainerWhenSingleView: true, donotShowContainerTitleWhenMergedWithContainer: true }]), + focusCommand: { id: TERMINAL_COMMAND_ID.FOCUS } +}, ViewContainerLocation.Panel); +Registry.as(panel.Extensions.Panels).setDefaultPanelId(TERMINAL_VIEW_ID); + +Registry.as(ViewContainerExtensions.ViewsRegistry).registerViews([{ + id: TERMINAL_VIEW_ID, + name: nls.localize('terminal', "Terminal"), + canToggleVisibility: false, + ctorDescriptor: new SyncDescriptor(TerminalViewPane) +}], VIEW_CONTAINER); // On mac cmd+` is reserved to cycle between windows, that's why the keybindings use WinCtrl const category = TERMINAL_ACTION_CATEGORY; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index be68a737b4ee8..731c1aa1a0859 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -7,7 +7,7 @@ import * as nls from 'vs/nls'; import { Action, IAction } from 'vs/base/common/actions'; import { EndOfLinePreference } from 'vs/editor/common/model'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; -import { TERMINAL_PANEL_ID, ITerminalConfigHelper, TitleEventSource, TERMINAL_COMMAND_ID } from 'vs/workbench/contrib/terminal/common/terminal'; +import { TERMINAL_VIEW_ID, ITerminalConfigHelper, TitleEventSource, TERMINAL_COMMAND_ID } from 'vs/workbench/contrib/terminal/common/terminal'; import { SelectActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar'; import { TogglePanelAction } from 'vs/workbench/browser/panel'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; @@ -78,7 +78,7 @@ export class ToggleTerminalAction extends TogglePanelAction { @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, @ITerminalService private readonly terminalService: ITerminalService ) { - super(id, label, TERMINAL_PANEL_ID, panelService, layoutService); + super(id, label, TERMINAL_VIEW_ID, panelService, layoutService); } public run(event?: any): Promise { diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index b41879ccedcff..2032be789ebc0 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -25,11 +25,10 @@ import { activeContrastBorder, scrollbarSliderActiveBackground, scrollbarSliderB import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { PANEL_BACKGROUND } from 'vs/workbench/common/theme'; import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/terminalWidgetManager'; -import { IShellLaunchConfig, ITerminalDimensions, ITerminalProcessManager, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, NEVER_MEASURE_RENDER_TIME_STORAGE_KEY, ProcessState, TERMINAL_PANEL_ID, IWindowsShellHelper, SHELL_PATH_INVALID_EXIT_CODE, SHELL_PATH_DIRECTORY_EXIT_CODE, SHELL_CWD_INVALID_EXIT_CODE, KEYBINDING_CONTEXT_TERMINAL_A11Y_TREE_FOCUS, INavigationMode, TitleEventSource, TERMINAL_COMMAND_ID, LEGACY_CONSOLE_MODE_EXIT_CODE } from 'vs/workbench/contrib/terminal/common/terminal'; +import { IShellLaunchConfig, ITerminalDimensions, ITerminalProcessManager, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, NEVER_MEASURE_RENDER_TIME_STORAGE_KEY, ProcessState, TERMINAL_VIEW_ID, IWindowsShellHelper, SHELL_PATH_INVALID_EXIT_CODE, SHELL_PATH_DIRECTORY_EXIT_CODE, SHELL_CWD_INVALID_EXIT_CODE, KEYBINDING_CONTEXT_TERMINAL_A11Y_TREE_FOCUS, INavigationMode, TitleEventSource, TERMINAL_COMMAND_ID, LEGACY_CONSOLE_MODE_EXIT_CODE } from 'vs/workbench/contrib/terminal/common/terminal'; import { ansiColorIdentifiers, TERMINAL_BACKGROUND_COLOR, TERMINAL_CURSOR_BACKGROUND_COLOR, TERMINAL_CURSOR_FOREGROUND_COLOR, TERMINAL_FOREGROUND_COLOR, TERMINAL_SELECTION_BACKGROUND_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper'; import { TerminalLinkHandler } from 'vs/workbench/contrib/terminal/browser/terminalLinkHandler'; -import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; import { ITerminalInstanceService, ITerminalInstance, TerminalShellType } from 'vs/workbench/contrib/terminal/browser/terminal'; import { TerminalProcessManager } from 'vs/workbench/contrib/terminal/browser/terminalProcessManager'; @@ -41,6 +40,7 @@ import { NavigationModeAddon } from 'vs/workbench/contrib/terminal/browser/addon import { XTermCore } from 'vs/workbench/contrib/terminal/browser/xterm-private'; import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; import { IOpenerService } from 'vs/platform/opener/common/opener'; +import { IViewsService } from 'vs/workbench/common/views'; // How long in milliseconds should an average frame take to render for a notification to appear // which suggests the fallback DOM-based renderer @@ -282,7 +282,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { @IContextKeyService private readonly _contextKeyService: IContextKeyService, @IKeybindingService private readonly _keybindingService: IKeybindingService, @INotificationService private readonly _notificationService: INotificationService, - @IPanelService private readonly _panelService: IPanelService, + @IViewsService private readonly _viewsService: IViewsService, @IInstantiationService private readonly _instantiationService: IInstantiationService, @IClipboardService private readonly _clipboardService: IClipboardService, @IThemeService private readonly _themeService: IThemeService, @@ -963,8 +963,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { } private _refreshSelectionContextKey() { - const activePanel = this._panelService.getActivePanel(); - const isActive = !!activePanel && activePanel.getId() === TERMINAL_PANEL_ID; + const isActive = !!this._viewsService.getActiveViewWithId(TERMINAL_VIEW_ID); this._terminalHasTextContextKey.set(isActive && this.hasSelection()); } @@ -1507,8 +1506,8 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const border = theme.getColor(activeContrastBorder); if (border) { collector.addRule(` - .hc-black .monaco-workbench .panel.integrated-terminal .xterm.focus::before, - .hc-black .monaco-workbench .panel.integrated-terminal .xterm:focus::before { border-color: ${border}; }` + .hc-black .monaco-workbench .pane-body.integrated-terminal .xterm.focus::before, + .hc-black .monaco-workbench .pane-body.integrated-terminal .xterm:focus::before { border-color: ${border}; }` ); } @@ -1516,20 +1515,20 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const scrollbarSliderBackgroundColor = theme.getColor(scrollbarSliderBackground); if (scrollbarSliderBackgroundColor) { collector.addRule(` - .monaco-workbench .panel.integrated-terminal .find-focused .xterm .xterm-viewport, - .monaco-workbench .panel.integrated-terminal .xterm.focus .xterm-viewport, - .monaco-workbench .panel.integrated-terminal .xterm:focus .xterm-viewport, - .monaco-workbench .panel.integrated-terminal .xterm:hover .xterm-viewport { background-color: ${scrollbarSliderBackgroundColor} !important; }` + .monaco-workbench .pane-body.integrated-terminal .find-focused .xterm .xterm-viewport, + .monaco-workbench .pane-body.integrated-terminal .xterm.focus .xterm-viewport, + .monaco-workbench .pane-body.integrated-terminal .xterm:focus .xterm-viewport, + .monaco-workbench .pane-body.integrated-terminal .xterm:hover .xterm-viewport { background-color: ${scrollbarSliderBackgroundColor} !important; }` ); } const scrollbarSliderHoverBackgroundColor = theme.getColor(scrollbarSliderHoverBackground); if (scrollbarSliderHoverBackgroundColor) { - collector.addRule(`.monaco-workbench .panel.integrated-terminal .xterm .xterm-viewport::-webkit-scrollbar-thumb:hover { background-color: ${scrollbarSliderHoverBackgroundColor}; }`); + collector.addRule(`.monaco-workbench .pane-body.integrated-terminal .xterm .xterm-viewport::-webkit-scrollbar-thumb:hover { background-color: ${scrollbarSliderHoverBackgroundColor}; }`); } const scrollbarSliderActiveBackgroundColor = theme.getColor(scrollbarSliderActiveBackground); if (scrollbarSliderActiveBackgroundColor) { - collector.addRule(`.monaco-workbench .panel.integrated-terminal .xterm .xterm-viewport::-webkit-scrollbar-thumb:active { background-color: ${scrollbarSliderActiveBackgroundColor}; }`); + collector.addRule(`.monaco-workbench .pane-body.integrated-terminal .xterm .xterm-viewport::-webkit-scrollbar-thumb:active { background-color: ${scrollbarSliderActiveBackgroundColor}; }`); } }); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 78e242801bd79..46ca86267b7e6 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import * as nls from 'vs/nls'; -import { TERMINAL_PANEL_ID, IShellLaunchConfig, ITerminalConfigHelper, ITerminalNativeService, ISpawnExtHostProcessRequest, IStartExtensionTerminalRequest, IAvailableShellsRequest, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_VISIBLE, KEYBINDING_CONTEXT_TERMINAL_IS_OPEN, ITerminalProcessExtHostProxy, IShellDefinition, LinuxDistro } from 'vs/workbench/contrib/terminal/common/terminal'; +import { TERMINAL_VIEW_ID, IShellLaunchConfig, ITerminalConfigHelper, ITerminalNativeService, ISpawnExtHostProcessRequest, IStartExtensionTerminalRequest, IAvailableShellsRequest, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_VISIBLE, KEYBINDING_CONTEXT_TERMINAL_IS_OPEN, ITerminalProcessExtHostProxy, IShellDefinition, LinuxDistro } from 'vs/workbench/contrib/terminal/common/terminal'; import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; -import { TerminalPanel } from 'vs/workbench/contrib/terminal/browser/terminalPanel'; +import { TerminalViewPane } from 'vs/workbench/contrib/terminal/browser/terminalView'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { TerminalTab } from 'vs/workbench/contrib/terminal/browser/terminalTab'; import { IInstantiationService, optional } from 'vs/platform/instantiation/common/instantiation'; @@ -29,6 +29,7 @@ import { isWindows, isMacintosh, OperatingSystem } from 'vs/base/common/platform import { basename } from 'vs/base/common/path'; import { IOpenFileRequest } from 'vs/platform/windows/common/windows'; import { find } from 'vs/base/common/arrays'; +import { IViewsService } from 'vs/workbench/common/views'; interface IExtHostReadyEntry { promise: Promise; @@ -100,6 +101,7 @@ export class TerminalService implements ITerminalService { @IRemoteAgentService private _remoteAgentService: IRemoteAgentService, @IQuickInputService private _quickInputService: IQuickInputService, @IConfigurationService private _configurationService: IConfigurationService, + @IViewsService private _viewsService: IViewsService, @optional(ITerminalNativeService) terminalNativeService: ITerminalNativeService ) { // @optional could give undefined and properly typing it breaks service registration @@ -421,9 +423,9 @@ export class TerminalService implements ITerminalService { public showPanel(focus?: boolean): Promise { return new Promise(async (complete) => { - const panel = this._panelService.getActivePanel(); - if (!panel || panel.getId() !== TERMINAL_PANEL_ID) { - await this._panelService.openPanel(TERMINAL_PANEL_ID, focus); + const pane = this._viewsService.getActiveViewWithId(TERMINAL_VIEW_ID) as TerminalViewPane; + if (!pane) { + await this._panelService.openPanel(TERMINAL_VIEW_ID, focus); if (focus) { // Do the focus call asynchronously as going through the // command palette will force editor focus @@ -655,34 +657,34 @@ export class TerminalService implements ITerminalService { public focusFindWidget(): Promise { return this.showPanel(false).then(() => { - const panel = this._panelService.getActivePanel() as TerminalPanel; - panel.focusFindWidget(); + const pane = this._viewsService.getActiveViewWithId(TERMINAL_VIEW_ID) as TerminalViewPane; + pane.focusFindWidget(); this._findWidgetVisible.set(true); }); } public hideFindWidget(): void { - const panel = this._panelService.getActivePanel() as TerminalPanel; - if (panel && panel.getId() === TERMINAL_PANEL_ID) { - panel.hideFindWidget(); + const pane = this._viewsService.getActiveViewWithId(TERMINAL_VIEW_ID) as TerminalViewPane; + if (pane) { + pane.hideFindWidget(); this._findWidgetVisible.reset(); - panel.focus(); + pane.focus(); } } public findNext(): void { - const panel = this._panelService.getActivePanel() as TerminalPanel; - if (panel && panel.getId() === TERMINAL_PANEL_ID) { - panel.showFindWidget(); - panel.getFindWidget().find(false); + const pane = this._viewsService.getActiveViewWithId(TERMINAL_VIEW_ID) as TerminalViewPane; + if (pane) { + pane.showFindWidget(); + pane.getFindWidget().find(false); } } public findPrevious(): void { - const panel = this._panelService.getActivePanel() as TerminalPanel; - if (panel && panel.getId() === TERMINAL_PANEL_ID) { - panel.showFindWidget(); - panel.getFindWidget().find(true); + const pane = this._viewsService.getActiveViewWithId(TERMINAL_VIEW_ID) as TerminalViewPane; + if (pane) { + pane.showFindWidget(); + pane.getFindWidget().find(true); } } @@ -694,7 +696,7 @@ export class TerminalService implements ITerminalService { public hidePanel(): void { const panel = this._panelService.getActivePanel(); - if (panel && panel.getId() === TERMINAL_PANEL_ID) { + if (panel && panel.getId() === TERMINAL_VIEW_ID) { this._layoutService.setPanelHidden(true); } } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalPanel.ts b/src/vs/workbench/contrib/terminal/browser/terminalView.ts similarity index 85% rename from src/vs/workbench/contrib/terminal/browser/terminalPanel.ts rename to src/vs/workbench/contrib/terminal/browser/terminalView.ts index 2c685281dc968..a1c8485172f12 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalPanel.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalView.ts @@ -12,12 +12,10 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { TERMINAL_PANEL_ID } from 'vs/workbench/contrib/terminal/common/terminal'; import { IThemeService, ITheme, registerThemingParticipant, ICssStyleCollector } from 'vs/platform/theme/common/themeService'; import { TerminalFindWidget } from 'vs/workbench/contrib/terminal/browser/terminalFindWidget'; import { editorHoverBackground, editorHoverBorder, editorHoverForeground } from 'vs/platform/theme/common/colorRegistry'; import { KillTerminalAction, SwitchTerminalAction, SwitchTerminalActionViewItem, CopyTerminalSelectionAction, TerminalPasteAction, ClearTerminalAction, SelectAllTerminalAction, CreateNewTerminalAction, SplitTerminalAction } from 'vs/workbench/contrib/terminal/browser/terminalActions'; -import { Panel } from 'vs/workbench/browser/panel'; import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; import { URI } from 'vs/base/common/uri'; import { TERMINAL_BACKGROUND_COLOR, TERMINAL_BORDER_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; @@ -25,13 +23,15 @@ import { DataTransfers } from 'vs/base/browser/dnd'; import { INotificationService, IPromptChoice, Severity } from 'vs/platform/notification/common/notification'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal'; -import { assertIsDefined } from 'vs/base/common/types'; import { BrowserFeatures } from 'vs/base/browser/canIUse'; +import { ViewPane, IViewPaneOptions } from 'vs/workbench/browser/parts/views/viewPaneContainer'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IViewDescriptorService } from 'vs/workbench/common/views'; const FIND_FOCUS_CLASS = 'find-focused'; -export class TerminalPanel extends Panel { - +export class TerminalViewPane extends ViewPane { private _actions: IAction[] | undefined; private _copyContextMenuAction: IAction | undefined; private _contextMenuActions: IAction[] | undefined; @@ -42,21 +42,24 @@ export class TerminalPanel extends Panel { private _findWidget: TerminalFindWidget | undefined; constructor( - @IConfigurationService private readonly _configurationService: IConfigurationService, + options: IViewPaneOptions, + @IKeybindingService keybindingService: IKeybindingService, + @IContextKeyService contextKeyService: IContextKeyService, + @IViewDescriptorService viewDescriptorService: IViewDescriptorService, + @IConfigurationService configurationService: IConfigurationService, @IContextMenuService private readonly _contextMenuService: IContextMenuService, @IInstantiationService private readonly _instantiationService: IInstantiationService, @ITerminalService private readonly _terminalService: ITerminalService, - @IThemeService protected readonly _themeService: IThemeService, + @IThemeService protected readonly themeService: IThemeService, @ITelemetryService telemetryService: ITelemetryService, @INotificationService private readonly _notificationService: INotificationService, @IStorageService storageService: IStorageService ) { - super(TERMINAL_PANEL_ID, telemetryService, _themeService, storageService); + super(options, keybindingService, _contextMenuService, configurationService, contextKeyService, viewDescriptorService, _instantiationService); } - public create(parent: HTMLElement): void { - super.create(parent); - this._parentDomElement = parent; + protected renderBody(container: HTMLElement): void { + this._parentDomElement = container; dom.addClass(this._parentDomElement, 'integrated-terminal'); this._fontStyleElement = document.createElement('style'); @@ -72,11 +75,10 @@ export class TerminalPanel extends Panel { this._attachEventListeners(this._parentDomElement, this._terminalContainer); - const container = assertIsDefined(this.getContainer()); this._terminalService.setContainers(container, this._terminalContainer); this._register(this.themeService.onThemeChange(theme => this._updateTheme(theme))); - this._register(this._configurationService.onDidChangeConfiguration(e => { + this._register(this.configurationService.onDidChangeConfiguration(e => { if (e.affectsConfiguration('terminal.integrated') || e.affectsConfiguration('editor.fontFamily')) { this._updateFont(); } @@ -86,7 +88,7 @@ export class TerminalPanel extends Panel { if (!configHelper.configFontIsMonospace()) { const choices: IPromptChoice[] = [{ label: nls.localize('terminal.useMonospace', "Use 'monospace'"), - run: () => this._configurationService.updateValue('terminal.integrated.fontFamily', 'monospace'), + run: () => this.configurationService.updateValue('terminal.integrated.fontFamily', 'monospace'), }]; this._notificationService.prompt(Severity.Warning, nls.localize('terminal.monospaceOnly', "The terminal only supports monospace fonts. Be sure to restart VS Code if this is a newly installed font."), choices); } @@ -95,7 +97,7 @@ export class TerminalPanel extends Panel { this._updateFont(); this._updateTheme(); - this._register(this.onDidChangeVisibility(visible => { + this._register(this.onDidChangeBodyVisibility(visible => { if (visible) { const hadTerminals = this._terminalService.terminalInstances.length > 0; if (!hadTerminals) { @@ -110,14 +112,11 @@ export class TerminalPanel extends Panel { })); // Force another layout (first is setContainers) since config has changed - this.layout(new dom.Dimension(this._terminalContainer.offsetWidth, this._terminalContainer.offsetHeight)); + this.layoutBody(this._terminalContainer.offsetWidth, this._terminalContainer.offsetHeight); } - public layout(dimension?: dom.Dimension): void { - if (!dimension) { - return; - } - this._terminalService.terminalTabs.forEach(t => t.layout(dimension.width, dimension.height)); + protected layoutBody(height: number, width: number): void { + this._terminalService.terminalTabs.forEach(t => t.layout(width, height)); } public getActions(): IAction[] { @@ -321,30 +320,30 @@ export class TerminalPanel extends Panel { } // TODO: Can we support ligatures? // dom.toggleClass(this._parentDomElement, 'enable-ligatures', this._terminalService.configHelper.config.fontLigatures); - this.layout(new dom.Dimension(this._parentDomElement.offsetWidth, this._parentDomElement.offsetHeight)); + this.layoutBody(this._parentDomElement.offsetWidth, this._parentDomElement.offsetHeight); } } registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const backgroundColor = theme.getColor(TERMINAL_BACKGROUND_COLOR); - collector.addRule(`.monaco-workbench .panel.integrated-terminal .terminal-outer-container { background-color: ${backgroundColor ? backgroundColor.toString() : ''}; }`); + collector.addRule(`.monaco-workbench .pane-body.integrated-terminal .terminal-outer-container { background-color: ${backgroundColor ? backgroundColor.toString() : ''}; }`); const borderColor = theme.getColor(TERMINAL_BORDER_COLOR); if (borderColor) { - collector.addRule(`.monaco-workbench .panel.integrated-terminal .split-view-view:not(:first-child) { border-color: ${borderColor.toString()}; }`); + collector.addRule(`.monaco-workbench .pane-body.integrated-terminal .split-view-view:not(:first-child) { border-color: ${borderColor.toString()}; }`); } // Borrow the editor's hover background for now const hoverBackground = theme.getColor(editorHoverBackground); if (hoverBackground) { - collector.addRule(`.monaco-workbench .panel.integrated-terminal .terminal-message-widget { background-color: ${hoverBackground}; }`); + collector.addRule(`.monaco-workbench .pane-body.integrated-terminal .terminal-message-widget { background-color: ${hoverBackground}; }`); } const hoverBorder = theme.getColor(editorHoverBorder); if (hoverBorder) { - collector.addRule(`.monaco-workbench .panel.integrated-terminal .terminal-message-widget { border: 1px solid ${hoverBorder}; }`); + collector.addRule(`.monaco-workbench .pane-body.integrated-terminal .terminal-message-widget { border: 1px solid ${hoverBorder}; }`); } const hoverForeground = theme.getColor(editorHoverForeground); if (hoverForeground) { - collector.addRule(`.monaco-workbench .panel.integrated-terminal .terminal-message-widget { color: ${hoverForeground}; }`); + collector.addRule(`.monaco-workbench .pane-body.integrated-terminal .terminal-message-widget { color: ${hoverForeground}; }`); } }); diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index 21522a35bd591..989e4bc4f9f15 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -12,7 +12,7 @@ import { URI } from 'vs/base/common/uri'; import { OperatingSystem } from 'vs/base/common/platform'; import { IOpenFileRequest } from 'vs/platform/windows/common/windows'; -export const TERMINAL_PANEL_ID = 'workbench.panel.terminal'; +export const TERMINAL_VIEW_ID = 'workbench.panel.terminal'; /** A context key that is set when there is at least one opened integrated terminal. */ export const KEYBINDING_CONTEXT_TERMINAL_IS_OPEN = new RawContextKey('terminalIsOpen', false); diff --git a/src/vs/workbench/workbench.common.main.ts b/src/vs/workbench/workbench.common.main.ts index 340f89e717d29..9debc489ee128 100644 --- a/src/vs/workbench/workbench.common.main.ts +++ b/src/vs/workbench/workbench.common.main.ts @@ -205,7 +205,7 @@ import 'vs/workbench/contrib/output/browser/outputView'; // Terminal import 'vs/workbench/contrib/terminal/browser/terminal.contribution'; import 'vs/workbench/contrib/terminal/browser/terminalQuickOpen'; -import 'vs/workbench/contrib/terminal/browser/terminalPanel'; +import 'vs/workbench/contrib/terminal/browser/terminalView'; // Relauncher import 'vs/workbench/contrib/relauncher/browser/relauncher.contribution';