Skip to content

Commit 47eb3d0

Browse files
author
Akos Kitta
committed
Debounced tab-bar toolbar updates.
Signed-off-by: Akos Kitta <[email protected]>
1 parent aeeac57 commit 47eb3d0

File tree

3 files changed

+81
-19
lines changed

3 files changed

+81
-19
lines changed

Diff for: arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,17 @@ import {
5050
ApplicationShell as TheiaApplicationShell,
5151
ShellLayoutRestorer as TheiaShellLayoutRestorer,
5252
CommonFrontendContribution as TheiaCommonFrontendContribution,
53+
DockPanelRenderer as TheiaDockPanelRenderer,
5354
TabBarRendererFactory,
5455
ContextMenuRenderer,
5556
createTreeContainer,
5657
TreeWidget,
5758
} from '@theia/core/lib/browser';
5859
import { MenuContribution } from '@theia/core/lib/common/menu';
59-
import { ApplicationShell } from './theia/core/application-shell';
60+
import {
61+
ApplicationShell,
62+
DockPanelRenderer,
63+
} from './theia/core/application-shell';
6064
import { FrontendApplication } from './theia/core/frontend-application';
6165
import {
6266
BoardsConfigDialog,
@@ -811,6 +815,10 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
811815
bind(StatusBarImpl).toSelf().inSingletonScope();
812816
rebind(TheiaStatusBarImpl).toService(StatusBarImpl);
813817

818+
// Debounced update for the tab-bar toolbar
819+
bind(DockPanelRenderer).toSelf();
820+
rebind(TheiaDockPanelRenderer).toService(DockPanelRenderer);
821+
814822
// Preferences
815823
bindArduinoPreferences(bind);
816824

Diff for: arduino-ide-extension/src/browser/theia/core/application-shell.ts

+49-16
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,35 @@ import {
1010
import {
1111
ApplicationShell as TheiaApplicationShell,
1212
DockPanel,
13+
DockPanelRenderer as TheiaDockPanelRenderer,
1314
Panel,
15+
TabBar,
1416
Widget,
17+
SHELL_TABBAR_CONTEXT_MENU,
1518
} from '@theia/core/lib/browser';
1619
import { Sketch } from '../../../common/protocol';
1720
import { SaveAsSketch } from '../../contributions/save-as-sketch';
18-
import { CurrentSketch, SketchesServiceClientImpl } from '../../../common/protocol/sketches-service-client-impl';
21+
import {
22+
CurrentSketch,
23+
SketchesServiceClientImpl,
24+
} from '../../../common/protocol/sketches-service-client-impl';
1925
import { nls } from '@theia/core/lib/common';
2026
import URI from '@theia/core/lib/common/uri';
27+
import { ToolbarAwareTabBar } from './tab-bars';
2128

2229
@injectable()
2330
export class ApplicationShell extends TheiaApplicationShell {
2431
@inject(CommandService)
25-
protected readonly commandService: CommandService;
32+
private readonly commandService: CommandService;
2633

2734
@inject(MessageService)
28-
protected readonly messageService: MessageService;
35+
private readonly messageService: MessageService;
2936

3037
@inject(SketchesServiceClientImpl)
31-
protected readonly sketchesServiceClient: SketchesServiceClientImpl;
38+
private readonly sketchesServiceClient: SketchesServiceClientImpl;
3239

3340
@inject(ConnectionStatusService)
34-
protected readonly connectionStatusService: ConnectionStatusService;
41+
private readonly connectionStatusService: ConnectionStatusService;
3542

3643
protected override track(widget: Widget): void {
3744
super.track(widget);
@@ -43,7 +50,7 @@ export class ApplicationShell extends TheiaApplicationShell {
4350
this.sketchesServiceClient.currentSketch().then((sketch) => {
4451
if (CurrentSketch.isValid(sketch)) {
4552
if (!this.isSketchFile(widget.editor.uri, sketch.uri)) {
46-
return;
53+
return;
4754
}
4855
if (Sketch.isInSketch(widget.editor.uri, sketch)) {
4956
widget.title.closable = false;
@@ -54,11 +61,11 @@ export class ApplicationShell extends TheiaApplicationShell {
5461
}
5562

5663
private isSketchFile(uri: URI, sketchUriString: string): boolean {
57-
const sketchUri = new URI(sketchUriString);
58-
if (uri.parent.isEqual(sketchUri)) {
59-
return true;
60-
}
61-
return false;
64+
const sketchUri = new URI(sketchUriString);
65+
if (uri.parent.isEqual(sketchUri)) {
66+
return true;
67+
}
68+
return false;
6269
}
6370

6471
override async addWidget(
@@ -120,15 +127,41 @@ export class ApplicationShell extends TheiaApplicationShell {
120127
}
121128
}
122129

130+
export class DockPanelRenderer extends TheiaDockPanelRenderer {
131+
override createTabBar(): TabBar<Widget> {
132+
const renderer = this.tabBarRendererFactory();
133+
// `ToolbarAwareTabBar` is from IDE2 and not from Theia. Check the imports.
134+
const tabBar = new ToolbarAwareTabBar(
135+
this.tabBarToolbarRegistry,
136+
this.tabBarToolbarFactory,
137+
this.breadcrumbsRendererFactory,
138+
{
139+
renderer,
140+
// Scroll bar options
141+
handlers: ['drag-thumb', 'keyboard', 'wheel', 'touch'],
142+
useBothWheelAxes: true,
143+
scrollXMarginOffset: 4,
144+
suppressScrollY: true,
145+
}
146+
);
147+
this.tabBarClasses.forEach((c) => tabBar.addClass(c));
148+
renderer.tabBar = tabBar;
149+
tabBar.disposed.connect(() => renderer.dispose());
150+
renderer.contextMenuPath = SHELL_TABBAR_CONTEXT_MENU;
151+
tabBar.currentChanged.connect(this.onCurrentTabChanged, this);
152+
return tabBar;
153+
}
154+
}
155+
123156
const originalHandleEvent = DockPanel.prototype.handleEvent;
124157

125158
DockPanel.prototype.handleEvent = function (event) {
126159
switch (event.type) {
127-
case 'p-dragenter':
128-
case 'p-dragleave':
129-
case 'p-dragover':
130-
case 'p-drop':
131-
return;
160+
case 'p-dragenter':
161+
case 'p-dragleave':
162+
case 'p-dragover':
163+
case 'p-drop':
164+
return;
132165
}
133166
originalHandleEvent.bind(this)(event);
134167
};

Diff for: arduino-ide-extension/src/browser/theia/core/tab-bars.ts

+23-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1-
import { TabBar } from '@theia/core/shared/@phosphor/widgets';
1+
import type { TabBar } from '@theia/core/shared/@phosphor/widgets';
22
import { Saveable } from '@theia/core/lib/browser/saveable';
3-
import { TabBarRenderer as TheiaTabBarRenderer } from '@theia/core/lib/browser/shell/tab-bars';
3+
import {
4+
TabBarRenderer as TheiaTabBarRenderer,
5+
ToolbarAwareTabBar as TheiaToolbarAwareTabBar,
6+
} from '@theia/core/lib/browser/shell/tab-bars';
7+
import debounce = require('lodash.debounce');
48

59
export class TabBarRenderer extends TheiaTabBarRenderer {
10+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
611
override createTabClass(data: TabBar.IRenderData<any>): string {
712
let className = super.createTabClass(data);
813
if (!data.title.closable && Saveable.isDirty(data.title.owner)) {
@@ -16,3 +21,19 @@ export class TabBarRenderer extends TheiaTabBarRenderer {
1621
// Context menus are empty, so they have been removed
1722
};
1823
}
24+
25+
export class ToolbarAwareTabBar extends TheiaToolbarAwareTabBar {
26+
protected override async updateBreadcrumbs(): Promise<void> {
27+
// NOOP
28+
// IDE2 does not use breadcrumbs.
29+
}
30+
31+
private readonly doUpdateToolbar = debounce(() => {
32+
console.log('super updating toolbar');
33+
super.updateToolbar();
34+
}, 500);
35+
protected override updateToolbar(): void {
36+
// Unlike Theia, IDE2 debounces the toolbar updates with 500ms
37+
this.doUpdateToolbar();
38+
}
39+
}

0 commit comments

Comments
 (0)