forked from tbranyen/gnome-shell-extension-undecorate
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathextension.js
118 lines (101 loc) · 3.54 KB
/
extension.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// Forked from sunwxg/gnome-shell-extension-undecorate
// Apps preferences handling borrowed from https://github.com/eonpatapon/gnome-shell-extension-
import GLib from 'gi://GLib';
import Meta from 'gi://Meta';
import Shell from 'gi://Shell';
import * as PopupMenu from 'resource:///org/gnome/shell/ui/popupMenu.js';
import * as WindowMenu from 'resource:///org/gnome/shell/ui/windowMenu.js';
import { Extension, InjectionManager, gettext as _ } from 'resource:///org/gnome/shell/extensions/extension.js';
let windowCreatedId;
export default class UndecorateExtension extends Extension {
enable() {
// Overwrite the buildMenu method to hook our menu item into.
this._injectionManager = new InjectionManager();
this._injectionManager.overrideMethod(WindowMenu.WindowMenu.prototype, '_buildMenu',
old_buildMenu => {
return function (...args) {
old_buildMenu.call(this, ...args);
newBuildMenu.call(this, ...args)
}
})
const settings = this.getSettings();
windowCreatedId = global.display.connect('window-created', (_, window) => {
// Automatically set this window up
// Set defaults
let done = false;
const appSystem = Shell.AppSystem.get_default();
settings.get_strv('inhibit-apps').forEach(appId => {
//const window = global.display.focus_window;
if (done) {
return;
}
const app = appSystem.lookup_app(appId);
if (app.get_windows().includes(window)) {
undecorate(window);
windowGetFocus(window);
done = true;
}
});
});
}
disable() {
this._injectionManager.clear();
this._injectionManager = null;
global.display.disconnect(windowCreatedId);
}
}
function undecorate(window) {
try {
GLib.spawn_command_line_sync('xprop -id ' + activeWindowId(window)
+ ' -f _MOTIF_WM_HINTS 32c -set'
+ ' _MOTIF_WM_HINTS "0x2, 0x0, 0x0, 0x0, 0x0"');
} catch(e) {
log(e);
}
}
function decorate(window) {
try {
GLib.spawn_command_line_sync('xprop -id ' + activeWindowId(window)
+ ' -f _MOTIF_WM_HINTS 32c -set'
+ ' _MOTIF_WM_HINTS "0x2, 0x0, 0x1, 0x0, 0x0"');
} catch(e) {
log(e);
}
}
function activeWindowId(window) {
try {
return parseInt(window.get_description(), 16);
} catch(e) {
log(e);
return;
}
}
function windowGetFocus(window) {
Meta.later_add(Meta.LaterType.IDLE, function() {
if (window.focus) {
window.focus(global.get_current_time());
} else {
window.activate(global.get_current_time());
}
});
}
// Cannot use an arrow function here, as the function will be treated as a
// class method when invoked and we rely on `this`.
function newBuildMenu(window) {
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
let item = {};
if (window.decorated) {
item = this.addAction(_('Undecorate'), event => {
undecorate(window);
windowGetFocus(window);
});
} else {
item = this.addAction(_('Decorate'), event => {
decorate(window);
windowGetFocus(window);
});
}
if (window.get_window_type() == Meta.WindowType.DESKTOP) {
item.setSensitive(false);
}
}