Skip to content

Commit a3ab178

Browse files
committed
feat: Improvements to UX for stack tabs
1 parent 4cf9e14 commit a3ab178

File tree

2 files changed

+85
-11
lines changed

2 files changed

+85
-11
lines changed

src/mod.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,4 +303,12 @@ declare namespace St {
303303
get_clutter_text(): Clutter.Text;
304304
set_hint_text(hint: string): void;
305305
}
306+
307+
interface Icon extends Widget {
308+
icon_name: string;
309+
}
310+
311+
interface Label extends Widget {
312+
text: string;
313+
}
306314
}

src/stack.ts

Lines changed: 77 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import * as a from 'arena';
1010
import * as utils from 'utils';
1111

1212
const Arena = a.Arena;
13-
const { St } = imports.gi;
13+
const { Clutter, GObject, St } = imports.gi;
1414

1515
const ACTIVE_TAB = 'pop-shell-tab pop-shell-tab-active';
1616
const INACTIVE_TAB = 'pop-shell-tab pop-shell-tab-inactive';
@@ -42,6 +42,78 @@ function stack_widgets_new(): StackWidgets {
4242
return { tabs };
4343
}
4444

45+
const ContainerButton = GObject.registerClass({
46+
Signals: { 'activate': {} },
47+
}, class ImageButton extends St.Button {
48+
_init(icon: St.Icon) {
49+
super._init({
50+
child: icon,
51+
x_expand: true,
52+
y_expand: true,
53+
})
54+
}
55+
})
56+
57+
interface TabButton extends St.Button {
58+
set_title: (title: string) => void;
59+
}
60+
61+
const TabButton = GObject.registerClass({
62+
Signals: { 'activate': {} },
63+
}, class TabButton extends St.Button {
64+
_init(window: ShellWindow) {
65+
const icon = window.icon(window.ext, 24)
66+
icon.set_x_align(Clutter.ActorAlign.START)
67+
68+
const label = new St.Label({
69+
y_expand: true,
70+
x_align: Clutter.ActorAlign.START,
71+
y_align: Clutter.ActorAlign.CENTER,
72+
style: "padding-left: 8px"
73+
})
74+
75+
label.text = window.title()
76+
77+
const container = new St.BoxLayout({
78+
y_expand: true,
79+
y_align: Clutter.ActorAlign.CENTER,
80+
})
81+
82+
const close_button = new ContainerButton(new St.Icon({
83+
icon_name: 'window-close-symbolic',
84+
icon_size: 24,
85+
y_align: Clutter.ActorAlign.CENTER,
86+
}))
87+
88+
close_button.connect('clicked', () => {
89+
window.meta.delete(global.get_current_time())
90+
})
91+
92+
close_button.set_x_align(Clutter.ActorAlign.END)
93+
close_button.set_y_align(Clutter.ActorAlign.CENTER)
94+
95+
container.add_actor(icon)
96+
container.add_actor(label)
97+
container.add_actor(close_button)
98+
99+
super._init({
100+
child: container,
101+
x_expand: true,
102+
y_expand: true,
103+
y_align: Clutter.ActorAlign.CENTER,
104+
})
105+
106+
107+
this._title = label
108+
}
109+
110+
set_title(text: string) {
111+
if (this._title) {
112+
this._title.text = text
113+
}
114+
}
115+
})
116+
45117
export class Stack {
46118
ext: Ext;
47119

@@ -60,7 +132,7 @@ export class Stack {
60132

61133
workspace: number;
62134

63-
buttons: a.Arena<St.Button> = new Arena();
135+
buttons: a.Arena<TabButton> = new Arena();
64136

65137
tabs_height: number = TAB_HEIGHT;
66138

@@ -95,15 +167,9 @@ export class Stack {
95167
if (!this.widgets) return;
96168

97169
const entity = window.entity;
98-
const label = window.title()
99170
const active = Ecs.entity_eq(entity, this.active);
100171

101-
const button: St.Button = new St.Button({
102-
label,
103-
x_expand: true,
104-
style_class: active ? ACTIVE_TAB : INACTIVE_TAB
105-
});
106-
172+
const button = new TabButton(window)
107173
const id = this.buttons.insert(button);
108174

109175
let tab: Tab = { active, entity, signals: [], button: id, button_signal: null };
@@ -443,7 +509,7 @@ export class Stack {
443509
}
444510

445511
this.watch_signals(this.active_id, c.button, window);
446-
this.buttons.get(c.button)?.set_label(window.title());
512+
this.buttons.get(c.button)?.set_title(window.title());
447513
this.activate(window.entity);
448514
}
449515
}
@@ -598,7 +664,7 @@ export class Stack {
598664
this.tabs[comp].signals = [
599665
window.meta.connect('notify::title', () => {
600666
this.window_exec(comp, entity, (window) => {
601-
this.buttons.get(button)?.set_label(window.title())
667+
this.buttons.get(button)?.set_title(window.title())
602668
});
603669
}),
604670

0 commit comments

Comments
 (0)