forked from simonthechipmunk/turnoffdisplay
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathextension.js
324 lines (216 loc) · 7.64 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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
/*
* extension.js
* Gnome3 Turn off Display Extension
*
* Adds a button to the status menu to turn off the screen. This extension is here to continue "Blank Screen" by l300lvl which is updated to GS3.6
* https://extensions.gnome.org/extension/242/blank-screen/ *** https://github.com/l300lvl/Blank-Screen-Extension
*
*
* Author: Simon Junga (simonthechipmunk at gmx.de)
* Original Author: l300lvl
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
*/
//***// imports:
// icons and labels
const St = imports.gi.St;
// main functionality
const Main = imports.ui.main;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const Mainloop = imports.mainloop;
// menu items
const PopupMenu = imports.ui.popupMenu;
// utilities for external programs and command line
const Config = imports.misc.config;
const ShellVersion = Config.PACKAGE_VERSION.split('.');
const Util = imports.misc.util;
const GLib = imports.gi.GLib;
// clutter and Gtk
const Gtk = imports.gi.Gtk;
// translations
const Gettext = imports.gettext.domain('turnoffdisplay');
const _ = Gettext.gettext;
// own imports
const Me = imports.misc.extensionUtils.getCurrentExtension();
const Prefs = Me.imports.prefs;
const Utils = Me.imports.utils;
const CSSadjust = Me.imports.css_adjust;
const Xinput = Me.imports.xinput_mouse;
const Settings = Utils._getSettingsSchema();
// define global variables
let menuitem, button, systemMenu, menuSettings, keybindSettings, handlemenumodeSettings, fixmenuwidthSettings;
let eventKeybind=null;
let eventXsetwatch=null;
let eventStartup=null;
//***// basic extension functions
function init() {
// initialize preferences
Prefs.init();
// get extension icons
Gtk.IconTheme.get_default().append_search_path(Me.dir.get_child('icons').get_path());
}
function enable() {
// create the menu entry
_MenuEntry(true);
// set keybinding
_SetKeybinding(true);
// start menu width adjustment
CSSadjust.handle_aggregate_menu(Prefs._getHandleMenuMode(), Prefs._getFixMenuWidth() );
// TODO:BUG something is really screwed up here... the get_width() method of any system-area button will return wrong values until
// the shell is running for at least a few seconds. For now calling the adjustment method 5 seconds into operation is the only thing
// that actually helps. Since I'm already 2 weeks late for the 3.20 release because of that this shit is now going upstream...*sigh*
//eventStartup = GLib.idle_add(GLib.PRIORITY_LOW, function() {
eventStartup = GLib.timeout_add(0, 5000, function() {
if(Prefs._getHandleMenuMode() == "auto" && ShellVersion[1] <= 16) CSSadjust.checkAggregatemenuwidth();
return false;
});
// connect to signals "preference changed"
menuSettings = Settings.connect('changed::integrate', function() {
_MenuEntry(false);
_MenuEntry(true);
});
keybindSettings = Settings.connect('changed::turnoffdisplay-keybinding', function() {
_SetKeybinding(false);
_SetKeybinding(true);
});
handlemenumodeSettings = Settings.connect('changed::handlemenumode', function() {
CSSadjust.handle_aggregate_menu(Prefs._getHandleMenuMode(), Prefs._getFixMenuWidth() );
});
fixmenuwidthSettings = Settings.connect('changed::fixmenuwidth', function() {
if(Prefs._getHandleMenuMode() == "fixed") {
CSSadjust.handle_aggregate_menu("fixed", Prefs._getFixMenuWidth() );
}
});
}
function disable() {
// disable the menu entry
_MenuEntry(false);
// remove keybinding
_SetKeybinding(false);
// disconnect from signals "preference changed"
Settings.disconnect(menuSettings);
Settings.disconnect(keybindSettings);
Settings.disconnect(handlemenumodeSettings);
Settings.disconnect(fixmenuwidthSettings);
// remove timer event
if(eventKeybind) {
Mainloop.source_remove(eventKeybind);
}
if(eventXsetwatch) {
Mainloop.source_remove(eventXsetwatch);
}
if(eventStartup) {
Mainloop.source_remove(eventStartup);
}
// disable menu width adjustment
CSSadjust.handle_aggregate_menu("off");
}
//***// extension functions
function _MenuEntry(set) {
// create/destroy the menu entry
// enable the entry
if(set) {
// create the menu entry according to preference settings
if(!Prefs._getIntegrate()) {
systemMenu = Main.panel.statusArea['aggregateMenu'];
// create separate menu button
menuitem = new PopupMenu.PopupBaseMenuItem({ activate: true });
let icon = new St.Icon({ icon_name: 'disable-display-symbolic', style_class: 'popup-menu-icon' });
let text = new St.Label({ text: _("Display Off"), style_class: "sm-label" });
menuitem.actor.add(icon);
menuitem.actor.add(text);
menuitem.connect('activate', _DisplayOff);
// add the menuentry to the menu
systemMenu.menu.addMenuItem(menuitem, 0);
}
else {
systemMenu = Main.panel.statusArea['aggregateMenu']._system;
// create round button in system control area
button = systemMenu._createActionButton('disable-display-symbolic', _("Display Off"));
button.connect('clicked', _DisplayOff);
// add the menuentry to the menu
//systemMenu._actionsItem.actor.insert_child_at_index(button, 4);
systemMenu.buttonGroup.add(button, { expand: true, x_fill: false });
}
}
// disable the entry
else {
if(menuitem) {
// remove the menuitem
menuitem.destroy();
}
else {
// remove the button
systemMenu.buttonGroup.remove_child(button);
}
// reset menuitem/button variable
menuitem = null;
button = null;
}
}
function _DisplayOff() {
// turn off the display
//close the menu
systemMenu.menu.itemActivated();
if (GLib.getenv('XDG_SESSION_TYPE') == 'wayland') {
_DisplayOffWayland();
} else {
_DisplayOffXWindows();
// disable external mice if set in the preferences
if(Prefs._getHandleMouse() && Xinput.xinput_is_installed) {
disable_mouse();
}
}
}
function _DisplayOffXWindows() {
//use xset to disable the screen
Util.spawn(['xset','dpms','force','off']);
}
function _DisplayOffWayland() {
Util.spawn(['dbus-send', '--session', '--dest=org.gnome.ScreenSaver',
'--type=method_call', '/org/gnome/ScreenSaver',
'org.gnome.ScreenSaver.SetActive', 'boolean:true']);
}
function _SetKeybinding(set) {
// enable keybinding to turn off the display
if (Prefs._getKeybinding() != "" && set) {
// Shell version management
let mode;
if (ShellVersion[1] <= 14 ) {
mode = Shell.KeyBindingMode.NORMAL;
}
else{
mode = Shell.ActionMode.NORMAL;
}
Main.wm.addKeybinding('turnoffdisplay-keybinding', Settings, Meta.KeyBindingFlags.NONE, mode, function() {
// turn off display after 500ms (workaround! - needs something like 'key-release-event')
eventKeybind = GLib.timeout_add(0, 500, _DisplayOff);
}, null, null);
}
else {
Main.wm.removeKeybinding('turnoffdisplay-keybinding');
}
}
function disable_mouse() {
// disable mouse pointers and watch for display revoke
let mousepointerIDs = Xinput.get_mouse_ids();
Xinput.switch_devices("off", mousepointerIDs);
// check monitor status periodically
eventXsetwatch = GLib.timeout_add(0, 500, function() {
let lines = GLib.spawn_command_line_sync('xset -q');
if (lines) {
// check for "Monitor is On"
lines = lines.toString();
if (lines.indexOf('Monitor is On') != -1) {
Xinput.switch_devices("on", mousepointerIDs);
return false;
}
}
return true;
});
}