@@ -28,7 +28,14 @@ const enum DecorationSelector {
28
28
ErrorColor = 'error' ,
29
29
DefaultColor = 'default' ,
30
30
Codicon = 'codicon' ,
31
- XtermDecoration = 'xterm-decoration'
31
+ XtermDecoration = 'xterm-decoration' ,
32
+ FirstSplitContainer = '.pane-body.integrated-terminal .terminal-group .monaco-split-view2.horizontal .split-view-view:first-child .xterm'
33
+ }
34
+
35
+ const enum DecorationStyles {
36
+ DefaultDimension = 16 ,
37
+ MarginLeftFirstSplit = - 17 ,
38
+ MarginLeft = - 12
32
39
}
33
40
34
41
interface IDisposableDecoration { decoration : IDecoration ; disposables : IDisposable [ ] ; exitCode ?: number }
@@ -57,28 +64,36 @@ export class DecorationAddon extends Disposable implements ITerminalAddon {
57
64
this . _register ( this . _contextMenuService . onDidShowContextMenu ( ( ) => this . _contextMenuVisible = true ) ) ;
58
65
this . _register ( this . _contextMenuService . onDidHideContextMenu ( ( ) => this . _contextMenuVisible = false ) ) ;
59
66
this . _hoverDelayer = this . _register ( new Delayer ( this . _configurationService . getValue ( 'workbench.hover.delay' ) ) ) ;
67
+
60
68
this . _configurationService . onDidChangeConfiguration ( e => {
61
69
if ( e . affectsConfiguration ( TerminalSettingId . ShellIntegrationDecorationIcon ) ||
62
70
e . affectsConfiguration ( TerminalSettingId . ShellIntegrationDecorationIconSuccess ) ||
63
71
e . affectsConfiguration ( TerminalSettingId . ShellIntegrationDecorationIconError ) ) {
64
- if ( this . _placeholderDecoration ?. element ) {
65
- this . _applyStyles ( this . _placeholderDecoration . element ) ;
66
- }
67
- for ( const decoration of this . _decorations ) {
68
- if ( decoration [ 1 ] . decoration ?. element ) {
69
- this . _applyStyles ( decoration [ 1 ] . decoration . element , decoration [ 1 ] . exitCode ) ;
70
- }
71
- }
72
- } else if ( e . affectsConfiguration ( TerminalSettingId . ShellIntegrationDecorationsEnabled ) ) {
73
- if ( ! this . _configurationService . getValue ( TerminalSettingId . ShellIntegrationDecorationsEnabled ) ) {
74
- this . _commandStartedListener ?. dispose ( ) ;
75
- this . _commandFinishedListener ?. dispose ( ) ;
76
- this . _clearDecorations ( ) ;
77
- }
72
+ this . _refreshClasses ( ) ;
73
+ } else if ( e . affectsConfiguration ( TerminalSettingId . FontSize ) || e . affectsConfiguration ( TerminalSettingId . LineHeight ) ) {
74
+ this . refreshLayouts ( ) ;
75
+ } else if ( e . affectsConfiguration ( TerminalSettingId . ShellIntegrationDecorationsEnabled ) && ! this . _configurationService . getValue ( TerminalSettingId . ShellIntegrationDecorationsEnabled ) ) {
76
+ this . _commandStartedListener ?. dispose ( ) ;
77
+ this . _commandFinishedListener ?. dispose ( ) ;
78
+ this . _clearDecorations ( ) ;
78
79
}
79
80
} ) ;
80
81
}
81
82
83
+ public refreshLayouts ( ) : void {
84
+ this . _updateLayout ( this . _placeholderDecoration ?. element ) ;
85
+ for ( const decoration of this . _decorations ) {
86
+ this . _updateLayout ( decoration [ 1 ] . decoration . element ) ;
87
+ }
88
+ }
89
+
90
+ private _refreshClasses ( ) : void {
91
+ this . _updateClasses ( this . _placeholderDecoration ?. element ) ;
92
+ for ( const decoration of this . _decorations . values ( ) ) {
93
+ this . _updateClasses ( decoration . decoration . element , decoration . exitCode ) ;
94
+ }
95
+ }
96
+
82
97
private _clearDecorations ( ) : void {
83
98
this . _placeholderDecoration ?. dispose ( ) ;
84
99
this . _placeholderDecoration ?. marker . dispose ( ) ;
@@ -153,55 +168,82 @@ export class DecorationAddon extends Disposable implements ITerminalAddon {
153
168
if ( ! decoration ) {
154
169
return undefined ;
155
170
}
156
- decoration . onRender ( target => {
157
- if ( target ) {
158
- const disposables = command . exitCode === undefined ? [ ] : [ this . _createContextMenu ( target , command ) , ...this . _createHover ( target , command ) ] ;
159
- if ( ! beforeCommandExecution ) {
160
- this . _decorations . set ( decoration . marker . id , { decoration, disposables, exitCode : command . exitCode } ) ;
161
- }
171
+ decoration . onRender ( element => {
172
+ if ( beforeCommandExecution ) {
173
+ this . _placeholderDecoration = decoration ;
174
+ } else {
175
+ this . _decorations . set ( decoration . marker . id ,
176
+ {
177
+ decoration,
178
+ disposables : command . exitCode === undefined ? [ ] : [ this . _createContextMenu ( element , command ) , ...this . _createHover ( element , command ) ] ,
179
+ exitCode : command . exitCode
180
+ } ) ;
162
181
}
163
- if ( ! target . classList . contains ( DecorationSelector . Codicon ) ) {
164
- // must be inlined to override the inlined styles from xterm
165
- target . style . width = '16px' ;
166
- target . style . height = '16px' ;
167
- this . _applyStyles ( target , command . exitCode ) ;
182
+
183
+ if ( ! element . classList . contains ( DecorationSelector . Codicon ) ) {
184
+ // first render
185
+ this . _updateLayout ( element ) ;
186
+ this . _updateClasses ( element , command . exitCode ) ;
168
187
}
169
188
} ) ;
170
- if ( beforeCommandExecution ) {
171
- this . _placeholderDecoration = decoration ;
172
- }
173
189
return decoration ;
174
190
}
175
191
176
- private _applyStyles ( target : HTMLElement , exitCode ?: number ) : void {
177
- for ( const classes of target . classList ) {
178
- target . classList . remove ( classes ) ;
192
+ private _updateLayout ( element ?: HTMLElement ) : void {
193
+ if ( ! element ) {
194
+ return ;
195
+ }
196
+ const fontSize = this . _configurationService . inspect ( TerminalSettingId . FontSize ) . value ;
197
+ const defaultFontSize = this . _configurationService . inspect ( TerminalSettingId . FontSize ) . defaultValue ;
198
+ if ( typeof fontSize === 'number' && typeof defaultFontSize === 'number' ) {
199
+ const scalar = ( fontSize / defaultFontSize ) <= 1 ? ( fontSize / defaultFontSize ) : 1 ;
200
+
201
+ // must be inlined to override the inlined styles from xterm
202
+ element . style . width = `${ scalar * DecorationStyles . DefaultDimension } px` ;
203
+ element . style . height = `${ scalar * DecorationStyles . DefaultDimension } px` ;
204
+ element . style . fontSize = `${ scalar * DecorationStyles . DefaultDimension } px` ;
205
+
206
+ // the first split terminal in the panel has more room
207
+ if ( element . closest ( DecorationSelector . FirstSplitContainer ) ) {
208
+ element . style . marginLeft = `${ scalar * DecorationStyles . MarginLeftFirstSplit } px` ;
209
+ } else {
210
+ element . style . marginLeft = `${ scalar * DecorationStyles . MarginLeft } px` ;
211
+ }
212
+ }
213
+ }
214
+
215
+ private _updateClasses ( element ?: HTMLElement , exitCode ?: number ) : void {
216
+ if ( ! element ) {
217
+ return ;
218
+ }
219
+ for ( const classes of element . classList ) {
220
+ element . classList . remove ( classes ) ;
179
221
}
180
- target . classList . add ( DecorationSelector . CommandDecoration , DecorationSelector . Codicon , DecorationSelector . XtermDecoration ) ;
222
+ element . classList . add ( DecorationSelector . CommandDecoration , DecorationSelector . Codicon , DecorationSelector . XtermDecoration ) ;
181
223
if ( exitCode === undefined ) {
182
- target . classList . add ( DecorationSelector . DefaultColor ) ;
183
- target . classList . add ( `codicon-${ this . _configurationService . getValue ( TerminalSettingId . ShellIntegrationDecorationIcon ) } ` ) ;
224
+ element . classList . add ( DecorationSelector . DefaultColor ) ;
225
+ element . classList . add ( `codicon-${ this . _configurationService . getValue ( TerminalSettingId . ShellIntegrationDecorationIcon ) } ` ) ;
184
226
} else if ( exitCode ) {
185
- target . classList . add ( DecorationSelector . ErrorColor ) ;
186
- target . classList . add ( `codicon-${ this . _configurationService . getValue ( TerminalSettingId . ShellIntegrationDecorationIconError ) } ` ) ;
227
+ element . classList . add ( DecorationSelector . ErrorColor ) ;
228
+ element . classList . add ( `codicon-${ this . _configurationService . getValue ( TerminalSettingId . ShellIntegrationDecorationIconError ) } ` ) ;
187
229
} else {
188
- target . classList . add ( `codicon-${ this . _configurationService . getValue ( TerminalSettingId . ShellIntegrationDecorationIconSuccess ) } ` ) ;
230
+ element . classList . add ( `codicon-${ this . _configurationService . getValue ( TerminalSettingId . ShellIntegrationDecorationIconSuccess ) } ` ) ;
189
231
}
190
232
}
191
233
192
- private _createContextMenu ( target : HTMLElement , command : ITerminalCommand ) : IDisposable {
234
+ private _createContextMenu ( element : HTMLElement , command : ITerminalCommand ) : IDisposable {
193
235
// When the xterm Decoration gets disposed of, its element gets removed from the dom
194
236
// along with its listeners
195
- return dom . addDisposableListener ( target , dom . EventType . CLICK , async ( ) => {
237
+ return dom . addDisposableListener ( element , dom . EventType . CLICK , async ( ) => {
196
238
this . _hideHover ( ) ;
197
239
const actions = await this . _getCommandActions ( command ) ;
198
- this . _contextMenuService . showContextMenu ( { getAnchor : ( ) => target , getActions : ( ) => actions } ) ;
240
+ this . _contextMenuService . showContextMenu ( { getAnchor : ( ) => element , getActions : ( ) => actions } ) ;
199
241
} ) ;
200
242
}
201
243
202
- private _createHover ( target : HTMLElement , command : ITerminalCommand ) : IDisposable [ ] {
244
+ private _createHover ( element : HTMLElement , command : ITerminalCommand ) : IDisposable [ ] {
203
245
return [
204
- dom . addDisposableListener ( target , dom . EventType . MOUSE_ENTER , ( ) => {
246
+ dom . addDisposableListener ( element , dom . EventType . MOUSE_ENTER , ( ) => {
205
247
if ( this . _contextMenuVisible ) {
206
248
return ;
207
249
}
@@ -217,11 +259,11 @@ export class DecorationAddon extends Disposable implements ITerminalAddon {
217
259
} else {
218
260
hoverContent += localize ( 'terminalPromptCommandSuccess' , 'Command executed {0}' , fromNow ( command . timestamp , true ) ) ;
219
261
}
220
- this . _hoverService . showHover ( { content : new MarkdownString ( hoverContent ) , target } ) ;
262
+ this . _hoverService . showHover ( { content : new MarkdownString ( hoverContent ) , target : element } ) ;
221
263
} ) ;
222
264
} ) ,
223
- dom . addDisposableListener ( target , dom . EventType . MOUSE_LEAVE , ( ) => this . _hideHover ( ) ) ,
224
- dom . addDisposableListener ( target , dom . EventType . MOUSE_OUT , ( ) => this . _hideHover ( ) )
265
+ dom . addDisposableListener ( element , dom . EventType . MOUSE_LEAVE , ( ) => this . _hideHover ( ) ) ,
266
+ dom . addDisposableListener ( element , dom . EventType . MOUSE_OUT , ( ) => this . _hideHover ( ) )
225
267
] ;
226
268
}
227
269
0 commit comments