Skip to content

Commit df54c1c

Browse files
CleoMenezesJrjardon
authored andcommitted
refactor: remove X11 support and legacy window decoration code
Removes all X11-specific functionality including xprop dependency, window decoration control, and X11-specific window property handling. The extension is now Wayland-only.
1 parent 3541333 commit df54c1c

File tree

5 files changed

+12
-315
lines changed

5 files changed

+12
-315
lines changed

README.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,12 +122,18 @@ There is file `$XDG_CONFIG_HOME/gnome-mosaic/config.json` where you can add the
122122

123123
```json
124124
{
125-
"class": "<WM_CLASS String from xprop>",
125+
"class": "<WM_CLASS String>",
126126
"title": "<Optional Window Title>"
127127
}
128128
```
129129

130-
For example, doing `xprop` on GNOME Settings (or GNOME Control Center), the WM_CLASS values are `gnome-control-center` and `Gnome-control-center`. Use the second value (Gnome-control-center), which gnome-mosaic will read. The `title` field is optional.
130+
To find the WM_CLASS of a window, you can:
131+
132+
1. Use the extension's built-in exception dialog (accessible from the panel menu)
133+
2. Check the output of `journalctl -f -o cat /usr/bin/gnome-shell` when focusing the window
134+
3. Use `gdbus call --session --dest org.gnome.Shell --object-path /org/gnome/Shell --method org.gnome.Shell.Eval 'global.get_window_actors().map(a => a.meta_window.get_wm_class()).join(", ")'`
135+
136+
For example, for GNOME Settings (or GNOME Control Center), the WM_CLASS values are `gnome-control-center` and `Gnome-control-center`. Use the second value (Gnome-control-center), which gnome-mosaic will read. The `title` field is optional.
131137

132138
After applying changes in `config.json`, you can reload the tiling if it doesn't work the first time.
133139

@@ -141,7 +147,7 @@ Please install the following as dependencies when developing:
141147
- Latest `npm` (comes with NodeJS)
142148
- `npm install typescript@latest`
143149

144-
While working on the shell, you can recompile, reconfigure, reinstall, and restart GNOME Shell with logging with `make debug`. Note that this only works reliably in X11 sessions, since Wayland will exit to the login screen on restarting the shell.
150+
While working on the shell, you can recompile, reconfigure, reinstall, and restart GNOME Shell with logging with `make debug`. Note that this only works reliably on Wayland sessions when using nested mode, since restarting the shell on Wayland will exit to the login screen.
145151

146152
## License
147153

src/extension.ts

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,8 +1024,7 @@ export class Ext extends Ecs.System<ExtEvent> {
10241024
` monitor: ${win.meta.get_monitor()},\n` +
10251025
` name: ${win.name(this)},\n` +
10261026
` rect: ${win.rect().fmt()},\n` +
1027-
` workspace: ${win.workspace_id()},\n` +
1028-
` xid: ${win.xid()},\n`;
1027+
` workspace: ${win.workspace_id()},\n`;
10291028

10301029
if (this.auto_tiler) {
10311030
msg += ` fork: (${this.auto_tiler.attached.get(win.entity)}),\n`;
@@ -1934,24 +1933,6 @@ export class Ext extends Ecs.System<ExtEvent> {
19341933
this.unset_grab_op();
19351934
}
19361935

1937-
on_show_window_titles() {
1938-
const show_title = this.settings.show_title();
1939-
1940-
if (indicator) {
1941-
indicator.toggle_titles.setToggleState(show_title);
1942-
}
1943-
1944-
for (const window of this.windows.values()) {
1945-
if (window.is_client_decorated()) continue;
1946-
1947-
if (show_title) {
1948-
window.decoration_show(this);
1949-
} else {
1950-
window.decoration_hide(this);
1951-
}
1952-
}
1953-
}
1954-
19551936
on_smart_gap() {
19561937
if (this.auto_tiler) {
19571938
const smart_gaps = this.settings.smart_gaps();
@@ -2197,9 +2178,6 @@ export class Ext extends Ecs.System<ExtEvent> {
21972178
case 'gap-outer':
21982179
this.on_gap_outer();
21992180
break;
2200-
case 'show-title':
2201-
this.on_show_window_titles();
2202-
break;
22032181
case 'smart-gaps':
22042182
this.on_smart_gap();
22052183
this.show_border_on_focused();
@@ -3306,6 +3284,8 @@ function _show_skip_taskbar_windows(ext: Ext) {
33063284
};
33073285
}
33083286

3287+
// Handle the workspace thumbnail
3288+
33093289
// Handle the workspace thumbnail
33103290
if (!default_isoverviewwindow_ws_thumbnail) {
33113291
default_isoverviewwindow_ws_thumbnail =

src/settings.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ const EDGE_TILING = 'edge-tiling';
7070
const GAP_INNER = 'gap-inner';
7171
const GAP_OUTER = 'gap-outer';
7272
const ROW_SIZE = 'row-size';
73-
const SHOW_TITLE = 'show-title';
7473
const SMART_GAPS = 'smart-gaps';
7574
const SNAP_TO_GRID = 'snap-to-grid';
7675
const TILE_BY_DEFAULT = 'tile-by-default';
@@ -148,10 +147,6 @@ export class ExtensionSettings {
148147
return this.ext.get_uint(ROW_SIZE);
149148
}
150149

151-
show_title(): boolean {
152-
return this.ext.get_boolean(SHOW_TITLE);
153-
}
154-
155150
smart_gaps(): boolean {
156151
return this.ext.get_boolean(SMART_GAPS);
157152
}
@@ -232,10 +227,6 @@ export class ExtensionSettings {
232227
this.ext.set_uint(ROW_SIZE, size);
233228
}
234229

235-
set_show_title(set: boolean) {
236-
this.ext.set_boolean(SHOW_TITLE, set);
237-
}
238-
239230
set_smart_gaps(set: boolean) {
240231
this.ext.set_boolean(SMART_GAPS, set);
241232
}

src/window.ts

Lines changed: 0 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import * as lib from './lib.js';
22
import * as log from './log.js';
3-
import * as once_cell from './once_cell.js';
43
import * as Rect from './rectangle.js';
54
import * as Tags from './tags.js';
65
import * as utils from './utils.js';
7-
import * as xprop from './xprop.js';
86
import type {Entity} from './ecs.js';
97
import type {Ext} from './extension.js';
108
import type {Rectangle} from './rectangle.js';
@@ -18,20 +16,6 @@ import Gio from 'gi://Gio';
1816
import Mtk from 'gi://Mtk';
1917
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
2018

21-
const {OnceCell} = once_cell;
22-
23-
const WM_TITLE_BLACKLIST: Array<string> = [
24-
'Firefox',
25-
'Nightly', // Firefox Nightly
26-
'Tor Browser',
27-
];
28-
29-
interface X11Info {
30-
normal_hints: once_cell.OnceCell<lib.SizeHint | null>;
31-
wm_role_: once_cell.OnceCell<string | null>;
32-
xid_: once_cell.OnceCell<string | null>;
33-
}
34-
3519
export class ShellWindow {
3620
entity: Entity;
3721
meta: Meta.Window;
@@ -57,14 +41,6 @@ export class ShellWindow {
5741

5842
window_app: any;
5943

60-
private was_hidden: boolean = false;
61-
62-
private extra: X11Info = {
63-
normal_hints: new OnceCell(),
64-
wm_role_: new OnceCell(),
65-
xid_: new OnceCell(),
66-
};
67-
6844
// Cache last border rect to avoid redundant updates
6945
private last_border_rect: {
7046
x: number;
@@ -94,8 +70,6 @@ export class ShellWindow {
9470
ext.add_tag(entity, Tags.Floating);
9571
}
9672

97-
this.decorate(ext);
98-
9973
this.bind_window_events(ext);
10074
this.bind_hint_events(ext);
10175

@@ -210,46 +184,6 @@ export class ShellWindow {
210184
return out;
211185
}
212186

213-
private async decorate(ext: Ext) {
214-
if (await this.may_decorate()) {
215-
if (!this.is_client_decorated()) {
216-
if (ext.settings.show_title()) {
217-
this.decoration_show(ext);
218-
} else {
219-
this.decoration_hide(ext);
220-
}
221-
}
222-
}
223-
}
224-
225-
private async decoration(
226-
_ext: Ext,
227-
callback: (xid: string) => void
228-
): Promise<void> {
229-
if (await this.may_decorate()) {
230-
const xid = this.xid();
231-
if (xid) callback(xid);
232-
}
233-
}
234-
235-
decoration_hide(ext: Ext): void {
236-
if (this.ignore_decoration()) return;
237-
238-
this.was_hidden = true;
239-
240-
this.decoration(ext, xid =>
241-
xprop.set_hint(xid, xprop.MOTIF_HINTS, xprop.HIDE_FLAGS)
242-
);
243-
}
244-
245-
decoration_show(ext: Ext): void {
246-
if (!this.was_hidden) return;
247-
248-
this.decoration(ext, xid =>
249-
xprop.set_hint(xid, xprop.MOTIF_HINTS, xprop.SHOW_FLAGS)
250-
);
251-
}
252-
253187
icon(_ext: Ext, size: number): any {
254188
let icon = this.window_app.create_icon_texture(size);
255189

@@ -264,22 +198,6 @@ export class ShellWindow {
264198
return icon;
265199
}
266200

267-
ignore_decoration(): boolean {
268-
const name = this.meta.get_wm_class();
269-
if (name === null) return true;
270-
return WM_TITLE_BLACKLIST.findIndex(n => name.startsWith(n)) !== -1;
271-
}
272-
273-
is_client_decorated(): boolean {
274-
// look I guess I'll hack something together in here if at all possible
275-
// Because Meta.Window.is_client_decorated() was removed in Meta 15, using it breaks the extension in gnome 47 or higher
276-
//return this.meta.window_type == Meta.WindowType.META_WINDOW_OVERRIDE_OTHER;
277-
const xid = this.xid();
278-
const extents = xid ? xprop.get_frame_extents(xid) : false;
279-
if (!extents) return false;
280-
return true;
281-
}
282-
283201
is_maximized(): boolean {
284202
return this.meta.is_maximized
285203
? this.meta.is_maximized()
@@ -368,11 +286,6 @@ export class ShellWindow {
368286
return this.meta.get_transient_for() !== null;
369287
}
370288

371-
async may_decorate(): Promise<boolean> {
372-
const xid = this.xid();
373-
return xid ? await xprop.may_decorate(xid) : false;
374-
}
375-
376289
move(ext: Ext, rect: Rectangular, on_complete?: () => void) {
377290
if (!this.same_workspace() && this.is_maximized()) {
378291
return;
@@ -426,12 +339,6 @@ export class ShellWindow {
426339
return Rect.Rectangle.from_meta(this.meta.get_frame_rect());
427340
}
428341

429-
async size_hint(): Promise<lib.SizeHint | null> {
430-
const xid = this.xid();
431-
const hint = xid ? await xprop.get_size_hints(xid) : null;
432-
return this.extra.normal_hints.get_or_init(() => hint);
433-
}
434-
435342
swap(ext: Ext, other: ShellWindow): void {
436343
let ar = this.rect().clone();
437344
let br = other.rect().clone();
@@ -445,12 +352,6 @@ export class ShellWindow {
445352
return title ? title : this.name(ext);
446353
}
447354

448-
async wm_role(): Promise<string | null> {
449-
const xid = this.xid();
450-
const role = xid ? await xprop.get_window_role(xid) : null;
451-
return this.extra.wm_role_.get_or_init(() => role);
452-
}
453-
454355
workspace_id(): number {
455356
const workspace = this.meta.get_workspace();
456357
if (workspace) {
@@ -461,13 +362,6 @@ export class ShellWindow {
461362
}
462363
}
463364

464-
xid(): string | null {
465-
return this.extra.xid_.get_or_init(() => {
466-
if (utils.is_wayland()) return null;
467-
return xprop.get_xid(this.meta);
468-
});
469-
}
470-
471365
show_border(ext: Ext) {
472366
if (!this.border) return;
473367

0 commit comments

Comments
 (0)