-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathextension.js
913 lines (777 loc) · 29.7 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
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
/*
BaBar
(c) Francois Thirioux 2021
Contributors: @fthx, @wooque, @frandieguez, @kenoh, @justperfection
License GPL v3
*/
import Clutter from 'gi://Clutter';
import Gio from 'gi://Gio';
import GLib from 'gi://GLib';
import GObject from 'gi://GObject';
import Meta from 'gi://Meta';
import Shell from 'gi://Shell';
import St from 'gi://St';
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
import * as DND from 'resource:///org/gnome/shell/ui/dnd.js';
import * as PanelMenu from 'resource:///org/gnome/shell/ui/panelMenu.js';
import * as PopupMenu from 'resource:///org/gnome/shell/ui/popupMenu.js';
import * as Dash from 'resource:///org/gnome/shell/ui/dash.js';
import * as AppDisplay from 'resource:///org/gnome/shell/ui/appDisplay.js';
import * as AppFavorites from 'resource:///org/gnome/shell/ui/appFavorites.js';
//const AppMenu = Main.panel.statusArea.appMenu;
const PanelBox = Main.layoutManager.panelBox;
const WM = global.workspace_manager;
import * as Util from 'resource:///org/gnome/shell/misc/util.js';
import {Extension, gettext as _} from 'resource:///org/gnome/shell/extensions/extension.js';
// translation needed to restore Places label, if any
const N_ = x => x;
// workspaces names from native schema
var WORKSPACES_SCHEMA = "org.gnome.desktop.wm.preferences";
var WORKSPACES_KEY = "workspace-names";
// initial fallback settings
var WORKSPACES_RIGHT_CLICK = false;
var RIGHT_CLICK = true;
var MIDDLE_CLICK = true;
var REDUCE_PADDING = true;
var APP_GRID_ICON_NAME = 'view-app-grid-symbolic';
var PLACES_ICON_NAME = 'folder-symbolic';
var FAVORITES_ICON_NAME = 'starred-symbolic';
var FALLBACK_ICON_NAME = 'applications-system-symbolic';
var ICON_SIZE = 18;
var ROUNDED_WORKSPACES_BUTTONS = false;
var PLAIN_WORKSPACES_BUTTONS = false;
var TOOLTIP_VERTICAL_PADDING = 10;
var THUMBNAIL_MAX_SIZE = 25;
var HIDDEN_OPACITY = 127;
var UNFOCUSED_OPACITY = 255;
var FOCUSED_OPACITY = 255;
var DESATURATE_ICONS = false;
var BOTTOM_PANEL = false;
var FAVORITES_FIRST = false;
var DISPLAY_ACTIVITIES = false;
var DISPLAY_APP_GRID = true;
var DISPLAY_PLACES_ICON = true;
var DISPLAY_FAVORITES = true;
var DISPLAY_WORKSPACES = true;
var DISPLAY_TASKS = true;
var DISPLAY_APP_MENU = false;
var DISPLAY_DASH = true;
var DISPLAY_WORKSPACES_THUMBNAILS = true;
let extension;
var AppGridButton = GObject.registerClass(
class AppGridButton extends PanelMenu.Button {
_init() {
super._init(0.0, 'Babar-AppGrid');
this.app_grid_button = new St.BoxLayout({visible: true, reactive: true, can_focus: true, track_hover: true});
this.app_grid_button.icon = new St.Icon({icon_name: APP_GRID_ICON_NAME, style_class: 'system-status-icon'});
this.app_grid_button.add_child(this.app_grid_button.icon);
this.app_grid_button.connect('button-release-event', this._show_apps_page.bind(this));
this.add_child(this.app_grid_button);
}
_show_apps_page() {
if (Main.overview.visible) {
Main.overview.hide();
} else {
Main.overview.showApps();
}
}
_destroy() {
super.destroy();
}
});
var FavoritesMenu = GObject.registerClass(
class FavoritesMenu extends PanelMenu.Button {
_init() {
super._init(0.0, 'Babar-Favorites');
this.fav_changed = AppFavorites.getAppFavorites().connect('changed', this._display_favorites.bind(this));
this.fav_menu_button = new St.BoxLayout({});
this.fav_menu_icon = new St.Icon({icon_name: FAVORITES_ICON_NAME, style_class: 'system-status-icon'});
this.fav_menu_button.add_child(this.fav_menu_icon);
this.add_child(this.fav_menu_button);
this._display_favorites();
}
// display favorites menu
_display_favorites() {
// destroy old menu items
if (this.menu) {
this.menu.removeAll();
}
// get favorites list
this.list_fav = AppFavorites.getAppFavorites().getFavorites();
// create favorites items
for (let fav_index = 0; fav_index < this.list_fav.length; ++fav_index) {
this.fav = this.list_fav[fav_index];
this.fav_icon = this.fav.create_icon_texture(64);
this.item = new PopupMenu.PopupImageMenuItem(this.fav.get_name(), this.fav_icon.get_gicon());
this.item.connect('activate', () => this._activate_fav(fav_index));
this.menu.addMenuItem(this.item);
// drag and drop
this.item.fav_index = fav_index;
this.item.is_babar_favorite = true;
this.item._delegate = this.item;
this.item._draggable = DND.makeDraggable(this.item, {dragActorOpacity: HIDDEN_OPACITY});
this.item._draggable.connect('drag-end', this._on_drag_end.bind(this));
this.item._draggable.connect('drag-cancelled', this._on_drag_end.bind(this));
}
}
// on drag cancelled or ended
_on_drag_end() {
this.menu.close();
this._display_favorites();
}
// activate favorite
_activate_fav(fav_index) {
AppFavorites.getAppFavorites().getFavorites()[fav_index].open_new_window(-1);
}
// remove signals, destroy workspaces bar
_destroy() {
if (this.fav_changed) {
AppFavorites.getAppFavorites().disconnect(this.fav_changed);
}
super.destroy();
}
});
var WorkspacesBar = GObject.registerClass(
class WorkspacesBar extends PanelMenu.Button {
_init() {
super._init(0.0, 'Babar-Tasks');
// tracker for windows
this.window_tracker = Shell.WindowTracker.get_default();
// define gsettings schema for workspaces names, get workspaces names, signal for settings key changed
this.ws_settings = new Gio.Settings({schema: WORKSPACES_SCHEMA});
this.ws_names_changed = this.ws_settings.connect(`changed::${WORKSPACES_KEY}`, this._update_ws_names.bind(this));
// define windows that need an icon (see https://www.roojs.org/seed/gir-1.2-gtk-3.0/seed/Meta.WindowType.html)
this.window_type_whitelist = [Meta.WindowType.NORMAL, Meta.WindowType.DIALOG];
// bar creation
this.ws_bar = new St.BoxLayout({});
this._update_ws_names();
this.add_child(this.ws_bar);
// window thumbnail
if (RIGHT_CLICK) {
this.window_thumbnail = new WindowThumbnail();
this.window_thumbnail.overview = Main.overview.connect('showing', () => this.window_thumbnail._remove());
}
// window button tooltip
this.window_tooltip = new WindowTooltip();
// signals
this._ws_number_changed = WM.connect('notify::n-workspaces', this._update_ws.bind(this));
this._active_ws_changed = WM.connect('active-workspace-changed', this._update_ws.bind(this));
this._windows_changed = this.window_tracker.connect('tracked-windows-changed', this._update_ws.bind(this));
this._restacked = global.display.connect('restacked', this._update_ws.bind(this));
//this._window_left_monitor = global.display.connect('window-left-monitor', this._update_ws.bind(this));
//this._window_entered_monitor = global.display.connect('window-entered-monitor', this._update_ws.bind(this));
}
// remove signals, restore Activities button, destroy workspaces bar
_destroy() {
if (this.ws_settings && this.ws_names_changed) {
this.ws_settings.disconnect(this.ws_names_changed);
}
if (this._ws_number_changed) {
WM.disconnect(this._ws_number_changed);
}
if (this._active_ws_changed) {
WM.disconnect(this._active_ws_changed);
}
if (this.window_tracker && this._windows_changed) {
this.window_tracker.disconnect(this._windows_changed);
}
if (this._restacked) {
global.display.disconnect(this._restacked);
}
//if (this._window_left_monitor) {
// global.display.disconnect(this._window_left_monitor);
//}
//if (this._window_entered_monitor) {
// global.display.disconnect(this._window_entered_monitor);
//}
if (this.hide_tooltip_timeout) {
GLib.source_remove(this.hide_tooltip_timeout);
}
if (this.window_tooltip) {
this.window_tooltip.destroy();
}
if (this.window_thumbnail) {
Main.overview.disconnect(this.window_thumbnail.overview);
if (this.window_thumbnail.timeout) {
GLib.source_remove(this.window_thumbnail.timeout);
}
this.window_thumbnail.destroy();
}
this.ws_bar.destroy();
super.destroy();
}
// update workspaces names
_update_ws_names() {
this.ws_names = this.ws_settings.get_strv(WORKSPACES_KEY);
this._update_ws();
}
// update the workspaces bar
_update_ws() {
// destroy old workspaces bar buttons and signals
this.ws_bar.destroy_all_children();
// get number of workspaces
this.ws_count = WM.get_n_workspaces();
this.active_ws_index = WM.get_active_workspace_index();
// display all current workspaces and tasks buttons
for (let ws_index = 0; ws_index < this.ws_count; ++ws_index) {
// workspace
let ws_box = new WorkspaceButton();
ws_box.number = ws_index;
let ws_box_label = new St.Label({y_align: Clutter.ActorAlign.CENTER});
// plain buttons option
if (PLAIN_WORKSPACES_BUTTONS) {
if (ws_index == this.active_ws_index) {
ws_box_label.style_class = 'workspace-active-plain';
} else {
ws_box_label.style_class = 'workspace-inactive-plain';
}
} else {
// rounded buttons option
if (!ROUNDED_WORKSPACES_BUTTONS) {
if (ws_index == this.active_ws_index) {
ws_box_label.style_class = 'workspace-active-squared';
} else {
ws_box_label.style_class = 'workspace-inactive-squared';
}
} else {
if (ws_index == this.active_ws_index) {
ws_box_label.style_class = 'workspace-active-rounded';
} else {
ws_box_label.style_class = 'workspace-inactive-rounded';
}
}
}
// workspace numbered label
if (this.ws_names[ws_index]) {
ws_box_label.set_text(" " + this.ws_names[ws_index] + " ");
} else {
ws_box_label.set_text(" " + (ws_index + 1) + " ");
}
ws_box.set_child(ws_box_label);
// signal
ws_box.connect('button-release-event', (widget, event) => this._toggle_ws(widget, event, ws_index));
// add in task bar
if (DISPLAY_WORKSPACES) {
this.ws_bar.add_child(ws_box);
}
// tasks
this.ws_current = WM.get_workspace_by_index(ws_index);
if (FAVORITES_FIRST) {
this.favorites_list = AppFavorites.getAppFavorites().getFavorites();
this.ws_current.windows = this.ws_current.list_windows().sort(this._sort_windows_favorites_first.bind(this));
} else {
this.ws_current.windows = this.ws_current.list_windows().sort(this._sort_windows);
}
for (let window_index = 0; window_index < this.ws_current.windows.length; ++window_index) {
this.window = this.ws_current.windows[window_index];
if (this.window && !this.window.is_skip_taskbar() && this.window_type_whitelist.includes(this.window.get_window_type())) {
this._create_window_button(ws_index, this.window);
}
}
}
}
// create window button ; ws = workspace, w = window
_create_window_button(ws_index, w) {
// windows on all workspaces have to be displayed only once
if (!w.is_on_all_workspaces() || ws_index == 0) {
// create button
let w_box = new WindowButton();
w_box.window = w;
w_box.workspace_number = ws_index;
let w_box_app = this.window_tracker.get_window_app(w);
// create w button and its icon
let w_box_icon = this._create_window_icon(w_box_app, w_box.window);
w_box.set_child(w_box_icon);
// signals
w_box.connect('button-release-event', (widget, event) => this._on_button_press(widget, event, w_box, ws_index, w));
w_box.connect('notify::hover', () => this._on_button_hover(w_box, w.title));
// desaturate option
if (DESATURATE_ICONS) {
this.desaturate = new Clutter.DesaturateEffect();
w_box_icon.add_effect(this.desaturate);
}
// set icon style and opacity following window state
if (w.is_hidden()) {
w_box.style_class = 'window-hidden';
w_box_icon.set_opacity(HIDDEN_OPACITY);
} else {
if (w.has_focus()) {
w_box.style_class = 'window-focused';
w_box_icon.set_opacity(FOCUSED_OPACITY);
} else {
w_box.style_class = 'window-unfocused';
w_box_icon.set_opacity(UNFOCUSED_OPACITY);
}
}
// add in task bar
if (w.is_on_all_workspaces()) {
this.ws_bar.insert_child_at_index(w_box, 0);
} else {
this.ws_bar.add_child(w_box);
}
}
}
// create window icon with fallbacks; app = app, w = metawindow
_create_window_icon(app, w) {
let icon;
if (app) {
icon = app.create_icon_texture(ICON_SIZE);
}
// sometimes no icon is defined or icon is void, at least for a short time
if (!icon || icon.get_style_class_name() == 'fallback-app-icon') {
icon = new St.Icon({icon_name: FALLBACK_ICON_NAME, icon_size: ICON_SIZE});
// Attempt to use the window icon in place of the app's icon.
let textureCache = St.TextureCache.get_default();
icon.set_gicon(textureCache.bind_cairo_surface_property(w, 'icon'));
}
return icon;
}
// on window w button press
_on_button_press(widget, event, w_box, ws_index, w) {
// left-click: toggle window
if (event.get_button() == 1) {
this.window_tooltip.hide();
if (w.has_focus() && !Main.overview.visible) {
if (w.can_minimize()) {
w.minimize();
}
} else {
w.activate(global.get_current_time());
}
if (Main.overview.visible) {
Main.overview.hide();
}
if (!w.is_on_all_workspaces()) {
WM.get_workspace_by_index(ws_index).activate(global.get_current_time());
}
}
// right-click: display window thumbnail
if (RIGHT_CLICK && event.get_button() == 3) {
if (!this.window_thumbnail.visible || this.window_thumbnail.window_id !== w.get_id()) {
this.window_tooltip.hide();
this.window_thumbnail.window = w.get_compositor_private();
if (this.window_thumbnail.window && this.window_thumbnail.window.get_size()[0] && this.window_thumbnail.window.get_texture()) {
[this.window_thumbnail.width, this.window_thumbnail.height] = this.window_thumbnail.window.get_size();
this.window_thumbnail.max_width = THUMBNAIL_MAX_SIZE / 100 * global.display.get_size()[0];
this.window_thumbnail.max_height = THUMBNAIL_MAX_SIZE / 100 * global.display.get_size()[1];
this.window_thumbnail.scale = Math.min(1.0, this.window_thumbnail.max_width / this.window_thumbnail.width, this.window_thumbnail.max_height / this.window_thumbnail.height);
this.window_thumbnail.clone.set_source(this.window_thumbnail.window);
this.window_thumbnail.clone.set_size(this.window_thumbnail.scale * this.window_thumbnail.width, this.window_thumbnail.scale * this.window_thumbnail.height);
this.window_thumbnail.set_size(this.window_thumbnail.scale * this.window_thumbnail.width, this.window_thumbnail.scale * this.window_thumbnail.height);
this.window_thumbnail.set_position(w_box.get_transformed_position()[0], Main.layoutManager.primaryMonitor.y + Main.panel.height + TOOLTIP_VERTICAL_PADDING);
this.window_thumbnail.show();
this.window_thumbnail.window_id = w.get_id();
// remove thumbnail content and hide thumbnail if its window is destroyed
this.window_thumbnail.destroy_signal = this.window_thumbnail.window.connect('destroy', () => {
if (this.window_thumbnail) {
this.window_thumbnail._remove();
}
});
}
} else {
this.window_thumbnail._remove();
}
}
// middle-click: close window
if (MIDDLE_CLICK && event.get_button() == 2 && w.can_close()) {
w.delete(global.get_current_time());
this.window_tooltip.hide();
}
}
// sort windows by creation date
_sort_windows(w1, w2) {
return w1.get_id() - w2.get_id();
}
// sort windows by favorite order first then by creation date
_sort_windows_favorites_first(w1, w2) {
this.w1_app = this.window_tracker.get_window_app(w1);
this.w2_app = this.window_tracker.get_window_app(w2);
if (!this.w1_app || !this.w2_app) {
return 0;
}
this.w1_is_favorite = AppFavorites.getAppFavorites().isFavorite(this.w1_app.get_id());
this.w2_is_favorite = AppFavorites.getAppFavorites().isFavorite(this.w2_app.get_id());
if (!this.w1_is_favorite && !this.w2_is_favorite) {
return this._sort_windows(w1, w2);
}
if (this.w1_is_favorite && this.w2_is_favorite) {
if (this.w1_app == this.w2_app) {
return this._sort_windows(w1, w2);
} else {
return this.favorites_list.indexOf(this.w1_app) - this.favorites_list.indexOf(this.w2_app);
}
}
if (this.w1_is_favorite && !this.w2_is_favorite) {
return -1;
}
if (!this.w1_is_favorite && this.w2_is_favorite) {
return 1;
}
}
// toggle or show overview
_toggle_ws(widget, event, ws_index) {
if (WORKSPACES_RIGHT_CLICK) {
// left click: show workspace
if (event.get_button() == 1) {
WM.get_workspace_by_index(ws_index).activate(global.get_current_time());
Main.overview.hide();
}
// right click: show workspace's overview
if (event.get_button() == 3) {
if (ws_index == WM.get_active_workspace_index()) {
Main.overview.toggle();
} else {
WM.get_workspace_by_index(ws_index).activate(global.get_current_time());
Main.overview.show();
}
}
} else {
if (ws_index == WM.get_active_workspace_index()) {
Main.overview.toggle();
} else {
WM.get_workspace_by_index(ws_index).activate(global.get_current_time());
Main.overview.show();
}
}
}
// on w button hover: toggle tooltip
_on_button_hover(w_box, window_title) {
if (window_title && w_box && w_box.get_hover()) {
this.window_tooltip.set_position(w_box.get_transformed_position()[0], Main.layoutManager.primaryMonitor.y + Main.panel.height + TOOLTIP_VERTICAL_PADDING);
this.window_tooltip.label.set_text(window_title);
this.window_tooltip.show();
this.hide_tooltip_timeout = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 2, () => {
if (!Main.panel.statusArea['babar-workspaces-bar'].get_hover()) {
this.window_tooltip.hide()
}
});
} else {
this.window_tooltip.hide();
}
}
});
var WindowTooltip = GObject.registerClass(
class WindowTooltip extends St.BoxLayout {
_init() {
super._init({style_class: 'window-tooltip'});
this.label = new St.Label({y_align: Clutter.ActorAlign.CENTER, text: ""});
this.add_child(this.label);
this.hide();
Main.layoutManager.addChrome(this);
}
});
var WindowThumbnail = GObject.registerClass(
class WindowThumbnail extends St.Bin {
_init() {
super._init({visible: true, reactive: true, can_focus: true, track_hover: true, style_class: 'window-thumbnail'});
this.connect('button-release-event', this._remove.bind(this));
this._delegate = this;
this._draggable = DND.makeDraggable(this, {dragActorOpacity: HIDDEN_OPACITY});
this.saved_snap_back_animation_time = DND.SNAP_BACK_ANIMATION_TIME;
this._draggable.connect('drag-end', this._end_drag.bind(this));
this._draggable.connect('drag-cancelled', this._end_drag.bind(this));
this.clone = new Clutter.Clone({reactive: true});
this.set_child(this.clone);
this._remove();
Main.layoutManager.addChrome(this);
}
_remove() {
if (this.clone) {
this.clone.set_source(null);
}
this.hide();
}
_end_drag() {
this.set_position(this._draggable._dragOffsetX + this._draggable._dragX, this._draggable._dragOffsetY + this._draggable._dragY);
DND.SNAP_BACK_ANIMATION_TIME = 0;
this.timeout = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 0, () => {
DND.SNAP_BACK_ANIMATION_TIME = this.saved_snap_back_animation_time;
});
}
});
var WorkspaceButton = GObject.registerClass(
class WorkspaceButton extends St.Bin {
_init() {
super._init({visible: true, reactive: true, can_focus: true, track_hover: true});
this._delegate = this;
}
acceptDrop(source) {
// favorite menu item
if (source.is_babar_favorite) {
WM.get_workspace_by_index(this.number).activate(global.get_current_time());
AppFavorites.getAppFavorites().getFavorites()[source.fav_index].open_new_window(-1);
}
// window button
if (source.is_babar_task && source.workspace_number !== this.number) {
source.window.change_workspace_by_index(this.number, false);
if (source.window.has_focus()) {
source.window.activate(global.get_current_time());
}
return true;
}
// dash button
if (source instanceof Dash.DashIcon) {
Main.overview.hide();
WM.get_workspace_by_index(this.number).activate(global.get_current_time());
source.app.open_new_window(-1);
return true;
}
// app grid button
if (source instanceof AppDisplay.AppIcon) {
Main.overview.hide();
WM.get_workspace_by_index(this.number).activate(global.get_current_time());
source.app.open_new_window(-1);
return true;
}
return false;
}
});
var WindowButton = GObject.registerClass(
class WindowButton extends St.Bin {
_init() {
super._init({visible: true, reactive: true, can_focus: true, track_hover: true});
this.is_babar_task = true;
this._delegate = this;
this._draggable = DND.makeDraggable(this, {dragActorOpacity: HIDDEN_OPACITY});
this._draggable.connect('drag-end', this._cancel_drag.bind(this));
this._draggable.connect('drag-cancelled', this._cancel_drag.bind(this));
}
_cancel_drag() {
global.display.emit('restacked');
}
acceptDrop(source) {
// favorite menu item
if (source.is_babar_favorite) {
WM.get_workspace_by_index(this.workspace_number).activate(global.get_current_time());
AppFavorites.getAppFavorites().getFavorites()[source.fav_index].open_new_window(-1);
}
// window button
if (source.is_babar_task && source.workspace_number !== this.workspace_number) {
source.window.change_workspace_by_index(this.workspace_number, false);
if (source.window.has_focus()) {
source.window.activate(global.get_current_time());
}
return true;
}
// dash button
if (source instanceof Dash.DashIcon) {
Main.overview.hide();
WM.get_workspace_by_index(this.workspace_number).activate(global.get_current_time());
source.app.open_new_window(-1);
return true;
}
// app grid button
if (source instanceof AppDisplay.AppIcon) {
Main.overview.hide();
WM.get_workspace_by_index(this.workspace_number).activate(global.get_current_time());
source.app.open_new_window(-1);
return true;
}
return false;
}
});
export default class BBExtension extends Extension {
constructor(metadata) {
super(metadata);
extension = this;
// Register callbacks to be notified about changes
//HGS Changed to use internal wrapper for MonitorManager.get to work under Gnome 44
let monitorManager = getMonitorManager();
this._monitorsChanged = monitorManager.connect('monitors-changed', () => this.set_panel_position());
this._panelHeightChanged = PanelBox.connect("notify::height", () => this.set_panel_position());
}
destroy() {
//HGS Fix for G44
let monitorManager = getMonitorManager();
monitorManager.disconnect(this._monitorsChanged);
PanelBox.disconnect(this._panelHeightChanged)
}
// get settings
_get_settings() {
this.settings = this.getSettings('org.gnome.shell.extensions.babar');
this.settings_already_changed = false;
this.settings_changed = this.settings.connect('changed', this._settings_changed.bind(this));
WORKSPACES_RIGHT_CLICK = this.settings.get_boolean('workspaces-right-click');
RIGHT_CLICK = this.settings.get_boolean('right-click');
MIDDLE_CLICK = this.settings.get_boolean('middle-click');
REDUCE_PADDING = this.settings.get_boolean('reduce-padding');
APP_GRID_ICON_NAME = this.settings.get_string('app-grid-icon-name');
PLACES_ICON_NAME = this.settings.get_string('places-icon-name');
FAVORITES_ICON_NAME = this.settings.get_string('favorites-icon-name');
FALLBACK_ICON_NAME = this.settings.get_string('fallback-icon-name');
ICON_SIZE = this.settings.get_int('icon-size');
THUMBNAIL_MAX_SIZE = this.settings.get_int('thumbnail-max-size');
ROUNDED_WORKSPACES_BUTTONS = this.settings.get_boolean('rounded-workspaces-buttons');
PLAIN_WORKSPACES_BUTTONS = this.settings.get_boolean('plain-workspaces-buttons');
TOOLTIP_VERTICAL_PADDING = this.settings.get_int('tooltip-vertical-padding');
HIDDEN_OPACITY = this.settings.get_int('hidden-opacity');
UNFOCUSED_OPACITY = this.settings.get_int('unfocused-opacity');
FOCUSED_OPACITY = this.settings.get_int('focused-opacity');
DESATURATE_ICONS = this.settings.get_boolean('desaturate-icons');
BOTTOM_PANEL = this.settings.get_boolean('bottom-panel');
FAVORITES_FIRST = this.settings.get_boolean('favorites-first');
DISPLAY_ACTIVITIES = this.settings.get_boolean('display-activities');
DISPLAY_APP_GRID = this.settings.get_boolean('display-app-grid');
DISPLAY_PLACES_ICON = this.settings.get_boolean('display-places-icon');
DISPLAY_FAVORITES = this.settings.get_boolean('display-favorites');
DISPLAY_WORKSPACES = this.settings.get_boolean('display-workspaces');
DISPLAY_TASKS = this.settings.get_boolean('display-tasks');
DISPLAY_APP_MENU = this.settings.get_boolean('display-app-menu');
DISPLAY_DASH = this.settings.get_boolean('display-dash');
DISPLAY_WORKSPACES_THUMBNAILS = this.settings.get_boolean('display-workspaces-thumbnails');
}
// restart extension after settings changed
_settings_changed() {
extension.disable();
extension.enable();
/*if (!this.settings_already_changed) {
Main.notify("Please restart BaBar extension to apply changes.");
this.settings_already_changed = true;
}*/
}
// toggle Activities button
_show_activities(show) {
this.activities_button = Main.panel.statusArea['activities'];
if (this.activities_button) {
if (show && !Main.sessionMode.isLocked) {
this.activities_button.container.show();
} else {
this.activities_button.container.hide();
}
}
}
// toggle Places Status Indicator extension label to folder
_show_places_icon(show_icon) {
this.places_indicator = Main.panel.statusArea['places-menu'];
if (this.places_indicator) {
this.places_indicator.remove_child(this.places_indicator.get_first_child());
if (show_icon) {
this.places_icon = new St.Icon({icon_name: PLACES_ICON_NAME, style_class: 'system-status-icon'});
this.places_indicator.add_child(this.places_icon);
} else {
this.places_label = new St.Label({text: _('Places'), y_expand: true, y_align: Clutter.ActorAlign.CENTER});
this.places_indicator.add_child(this.places_label);
}
}
}
// toggle dash in overview
_show_dash(show) {
if (show) {
Main.overview.dash.show();
} else {
Main.overview.dash.hide();
}
}
// set panel poistion according to the settings
set_panel_position() {
if (BOTTOM_PANEL) {
let monitor = Main.layoutManager.primaryMonitor;
PanelBox.set_position(monitor.x, (monitor.x + monitor.height - PanelBox.height));
} else {
this.reset_panel_position()
}
}
// restore panel position to the top
reset_panel_position() {
let monitor = Main.layoutManager.primaryMonitor;
PanelBox.set_position(monitor.x, monitor.y);
}
// toggle workspaces thumbnails in overview
_hide_ws_thumbnails() {
Main.overview._overview._controls._thumbnailsBox.hide();
}
enable() {
// get settings
this._get_settings();
// adjust panel position to top or bottom edge of the screen
this.set_panel_position();
// top panel left box padding
if (REDUCE_PADDING) {
Main.panel._leftBox.add_style_class_name('leftbox-reduced-padding');
}
// Activities button
if (!DISPLAY_ACTIVITIES) {
this._show_activities(false);
}
// app grid
if (DISPLAY_APP_GRID) {
this.app_grid = new AppGridButton();
Main.panel.addToStatusArea('babar-app-grid-button', this.app_grid, 0, 'left');
}
// Places label to icon
if (DISPLAY_PLACES_ICON) {
this._show_places_icon(true);
this.extensions_changed = Main.extensionManager.connect('extension-state-changed', () => this._show_places_icon(true));
}
// favorites
if (DISPLAY_FAVORITES) {
this.favorites_menu = new FavoritesMenu();
Main.panel.addToStatusArea('babar-favorites-menu', this.favorites_menu, 3, 'left');
}
// tasks
if (DISPLAY_TASKS) {
this.workspaces_bar = new WorkspacesBar();
Main.panel.addToStatusArea('babar-workspaces-bar', this.workspaces_bar, 5, 'left');
}
// AppMenu
// if (!DISPLAY_APP_MENU) {
// AppMenu.container.hide();
// }
// dash
if (!DISPLAY_DASH) {
this._show_dash(false);
}
// workspaces thumbnails
if (!DISPLAY_WORKSPACES_THUMBNAILS) {
this.showing_overview = Main.overview.connect('showing', this._hide_ws_thumbnails.bind(this));
}
}
disable() {
// app grid
if (DISPLAY_APP_GRID && this.app_grid) {
this.app_grid._destroy();
}
// favorites
if (DISPLAY_FAVORITES && this.favorites_menu) {
this.favorites_menu._destroy();
}
// workspaces bar
if (DISPLAY_TASKS && this.workspaces_bar) {
this.workspaces_bar._destroy();
}
// top panel left box padding
if (REDUCE_PADDING) {
Main.panel._leftBox.remove_style_class_name('leftbox-reduced-padding');
}
// restore panel position
this.reset_panel_position();
// Places label and unwatch extensions changes
if (DISPLAY_PLACES_ICON && this.places_indicator) {
this._show_places_icon(false);
Main.extensionManager.disconnect(this.extensions_changed);
}
// Activities button
this._show_activities(true);
// AppMenu icon
// if (!Main.overview.visible && !Main.sessionMode.isLocked) {
// AppMenu.container.show();
// }
// dash
this._show_dash(true);
// workspaces thumbnails
if (!DISPLAY_WORKSPACES_THUMBNAILS && this.showing_overview) {
Main.overview.disconnect(this.showing_overview);
}
// unwatch settings
this.settings.disconnect(this.settings_changed);
}
}
//HGS Added to circumvent Meta.MonitorManager
// Provide internal wrapper for MonitorManager.get to work under Gnome 44
// Copied from https://github.com/micheleg/dash-to-dock/commit/ec2ba66febd2195b7ae1cd25b413b6da2a17f6a8
function getMonitorManager() {
if (global.backend.get_monitor_manager !== undefined)
return global.backend.get_monitor_manager();
else
return Meta.MonitorManager.get();
}