From b5f7e1e1b523fbc6e74f4e480b0b7f6f314c3ddd Mon Sep 17 00:00:00 2001 From: rkla Date: Thu, 30 Dec 2021 16:37:47 +0100 Subject: [PATCH 1/7] adds optional menu to rename workspaces --- extension.js | 134 +++++++++++++++++- metadata.json | 4 +- prefs.js | 51 +++++++ ...nome.shell.extensions.example1.gschema.xml | 9 ++ 4 files changed, 194 insertions(+), 4 deletions(-) create mode 100644 prefs.js create mode 100644 schemas/org.gnome.shell.extensions.example1.gschema.xml diff --git a/extension.js b/extension.js index 1cb31c7..729cfbd 100644 --- a/extension.js +++ b/extension.js @@ -7,12 +7,16 @@ const { Clutter, Gio, GObject, Shell, St } = imports.gi; +const Lang = imports.lang +const PopupMenu = imports.ui.popupMenu; const Main = imports.ui.main; const PanelMenu = imports.ui.panelMenu; +const ExtensionUtils = imports.misc.extensionUtils; var WORKSPACES_SCHEMA = "org.gnome.desktop.wm.preferences"; var WORKSPACES_KEY = "workspace-names"; +const WORKSPACES_BAR_SCHEMA = 'org.gnome.shell.extensions.workspaces-bar'; var WorkspacesBar = GObject.registerClass( @@ -37,6 +41,28 @@ class WorkspacesBar extends PanelMenu.Button { this._ws_number_changed = global.workspace_manager.connect('notify::n-workspaces', this._update_ws.bind(this)); this._restacked = global.display.connect('restacked', this._update_ws.bind(this)); this._windows_changed = Shell.WindowTracker.get_default().connect('tracked-windows-changed', this._update_ws.bind(this)); + + // setup settings + this._renaming = false; + + this._gsettings = ExtensionUtils.getSettings(WORKSPACES_BAR_SCHEMA); + this._gsettings.connect("changed::renaming", this._renaming_changed.bind(this)); + this._renaming_changed(); + + // if enabled, make popup menu only open on right click + var click_handler = function(origin, event) { + const key = event.get_button(); + if (this._renaming) { + if (key == 1) { + this.menu.close(); + } else if (key == 3) { + this.menu.open(); + } + } else { + this.menu.close(); + } + }; + this.connect('button-press-event', Lang.bind(this, click_handler)); } // remove signals, restore Activities button, destroy workspaces bar @@ -60,6 +86,64 @@ class WorkspacesBar extends PanelMenu.Button { this.ws_bar.destroy(); super.destroy(); } + + // build a context popup menu with the workspace name entries + _buildMenu() { + // remove all menu items + this.menu.removeAll(); + + // array of entry widgets + let entries = []; + + // add a menu item for each workspace + for (let ws_index = 0; ws_index < this.ws_count; ++ws_index) { + let menu_item = new PopupMenu.PopupBaseMenuItem({ + reactive: false, + can_focus: false + }); + let ws_name_entry = new St.Entry({ + name: 'ws_entry' + (ws_index + 1), + style_class: 'workspace-name-entry', + can_focus: true, + hint_text: _('Workspace name...'), + track_hover: true, + x_expand: true, + y_expand: true + }); + + // set the text to workspace names + if (this.workspaces_names[ws_index]) { + ws_name_entry.set_text("" + this.workspaces_names[ws_index] + ""); + } else { + ws_name_entry.set_text(" " + (ws_index + 1) + " "); + } + + // make entry trigger rename of this workspace on pressing enter + var enter_handler = function(origin, event) { + const key = event.get_key_symbol(); + if (key == Clutter.KEY_Return || key == Clutter.KEY_KP_Enter || key == Clutter.KEY_ISO_Enter) { + this._rename_ws(ws_index, origin.get_text()); + } + }; + ws_name_entry.get_clutter_text().connect( + 'key-press-event', Lang.bind(this, enter_handler) + ); + + // add menu item + menu_item.add(ws_name_entry); + this.menu.addMenuItem(menu_item); + + // keep track of entry widget + entries.push(ws_name_entry); + } + + // add menu item for renaming all workspaces at once + let rename_menu_item = new PopupMenu.PopupMenuItem(_('Rename')); + this.menu.addMenuItem(rename_menu_item); + rename_menu_item.connect('activate', this._rename_all.bind(this))); + + this.menu_entries = entries; + } // hide Activities button _show_activities(show) { @@ -77,6 +161,10 @@ class WorkspacesBar extends PanelMenu.Button { _update_workspaces_names() { this.workspaces_names = this.workspaces_settings.get_strv(WORKSPACES_KEY); this._update_ws(); + // build the menu + //if (this._renaming) { + this._buildMenu(); + //} } // update the workspaces bar @@ -106,12 +194,23 @@ class WorkspacesBar extends PanelMenu.Button { } } if (this.workspaces_names[ws_index]) { - this.ws_box.label.set_text(" " + this.workspaces_names[ws_index] + " "); + this.ws_box.label.set_text("" + this.workspaces_names[ws_index] + ""); } else { this.ws_box.label.set_text(" " + (ws_index + 1) + " "); } this.ws_box.set_child(this.ws_box.label); - this.ws_box.connect('button-release-event', () => this._toggle_ws(ws_index) ); + + // only switch to workspace on left click + this.ws_box.connect('button-press-event', (origin, event) => { + if (this._renaming) { + if (event.get_button() == 1) { + this._toggle_ws(ws_index); + } + } else { + this._toggle_ws(ws_index); + } + }); + this.ws_bar.add_actor(this.ws_box); } } @@ -124,6 +223,37 @@ class WorkspacesBar extends PanelMenu.Button { global.workspace_manager.get_workspace_by_index(ws_index).activate(global.get_current_time()); } } + + // rename all workspaces + _rename_all() { + // check if menu and workspace number match + if (this.menu_entries.length != this.workspaces_names.length) {return;} + + // build array of new workspace names + let new_workspaces_names = []; + for (let i = 0; i < this.menu_entries.length; i++) { + let new_name = this.menu_entries[i].get_text(); + new_workspaces_names.push(new_name); + } + + // set workspace names + this.workspaces_settings.set_strv(WORKSPACES_KEY, new_workspaces_names); + } + + // rename workspace with given index + _rename_ws(ws_index, ws_name) { + // build array with altered workspace name + let new_workspaces_names = Array.from(this.workspaces_names); + new_workspaces_names[ws_index] = ws_name; + + // set workspace names + this.workspaces_settings.set_strv(WORKSPACES_KEY, new_workspaces_names); + } + + // handle (de)activation of renaming + _renaming_changed() { + this._renaming = this._gsettings.get_boolean('renaming'); + } }); class Extension { diff --git a/metadata.json b/metadata.json index 05472df..44e6a8c 100644 --- a/metadata.json +++ b/metadata.json @@ -10,5 +10,5 @@ ], "url": "https://github.com/fthx/workspaces-bar", "uuid": "workspaces-bar@fthx", - "version": 11 -} + "version": 12 +} \ No newline at end of file diff --git a/prefs.js b/prefs.js new file mode 100644 index 0000000..71b4c91 --- /dev/null +++ b/prefs.js @@ -0,0 +1,51 @@ +const Gtk = imports.gi.Gtk; + +const ExtensionUtils = imports.misc.extensionUtils; + +const SCHEMA_NAME = 'org.gnome.shell.extensions.workspaces-bar'; + +function init() { +} + +function buildPrefsWidget() { + let widget = new PrefsWidget(); + return widget.widget; +} + +class PrefsWidget { + constructor() { + this.gsettings = ExtensionUtils.getSettings(SCHEMA_NAME); + + this.widget = new Gtk.Box({ + orientation: Gtk.Orientation.VERTICAL, + margin_top: 10, + margin_bottom: 10, + margin_start: 10, + margin_end: 10, + }); + + this.vbox = new Gtk.Box({ + orientation: Gtk.Orientation.VERTICAL, + margin_top: 0, + hexpand: true, + }); + this.vbox.set_size_request(550, 250); + + this.vbox.append(this.addRenaming()); + this.widget.append(this.vbox); + } + + addRenaming() { + let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL, margin_top: 5 }); + let setting_label = new Gtk.Label({ label: "Enable renaming menu", xalign: 0, hexpand: true }); + this.setting_switch = new Gtk.Switch({ active: this.gsettings.get_boolean('renaming') }); + + this.setting_switch.connect('notify::active', (button) => { this.gsettings.set_boolean('renaming', button.active); }); + + hbox.append(setting_label); + hbox.append(this.setting_switch); + + return hbox; + } +} + diff --git a/schemas/org.gnome.shell.extensions.example1.gschema.xml b/schemas/org.gnome.shell.extensions.example1.gschema.xml new file mode 100644 index 0000000..9b6df6e --- /dev/null +++ b/schemas/org.gnome.shell.extensions.example1.gschema.xml @@ -0,0 +1,9 @@ + + + + true + Enables a popup menu to rename workspaces. + Enables a popup menu to rename workspaces. + + + From bb86f5997ef7fcb9b3fed0be46e5cd21afe758d2 Mon Sep 17 00:00:00 2001 From: rkla Date: Sat, 1 Jan 2022 16:58:52 +0100 Subject: [PATCH 2/7] improves interaction with popup menu --- extension.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/extension.js b/extension.js index 729cfbd..590d7e7 100644 --- a/extension.js +++ b/extension.js @@ -56,7 +56,11 @@ class WorkspacesBar extends PanelMenu.Button { if (key == 1) { this.menu.close(); } else if (key == 3) { - this.menu.open(); + if (!this.menu.isOpen) { + this.menu.close(); + } else { + this.menu.open(); + } } } else { this.menu.close(); @@ -88,7 +92,7 @@ class WorkspacesBar extends PanelMenu.Button { } // build a context popup menu with the workspace name entries - _buildMenu() { + _build_menu() { // remove all menu items this.menu.removeAll(); @@ -162,9 +166,7 @@ class WorkspacesBar extends PanelMenu.Button { this.workspaces_names = this.workspaces_settings.get_strv(WORKSPACES_KEY); this._update_ws(); // build the menu - //if (this._renaming) { - this._buildMenu(); - //} + this._build_menu(); } // update the workspaces bar @@ -200,10 +202,10 @@ class WorkspacesBar extends PanelMenu.Button { } this.ws_box.set_child(this.ws_box.label); - // only switch to workspace on left click + // if renaming is enabled, only switch to workspace on left click when popup menu is not open this.ws_box.connect('button-press-event', (origin, event) => { if (this._renaming) { - if (event.get_button() == 1) { + if (event.get_button() == 1 && !this.menu.isOpen) { this._toggle_ws(ws_index); } } else { From c571c57a506dda328c79db10f40edaf5e2934d8e Mon Sep 17 00:00:00 2001 From: rkla Date: Sat, 1 Jan 2022 16:59:28 +0100 Subject: [PATCH 3/7] add third option for setting workspace names --- metadata.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/metadata.json b/metadata.json index 44e6a8c..74030c4 100644 --- a/metadata.json +++ b/metadata.json @@ -1,6 +1,6 @@ { "_generated": "Generated by SweetTooth, do not edit", - "description": "Replace 'Activities' button by all current workspaces buttons. Switch workspace or toggle overview by clicking on these buttons.\n\n You can use names for workspaces: there are two ways for that. 1) Edit the string array 'org.gnome.desktop.wm.preferences.workspace-names' gsettings key (through dconf editor, e.g.). 2) Use official GNOME extension Workspaces Indicator's settings. You don't have to write a long enough list: numbers are displayed if no workspace name is defined.", + "description": "Replace 'Activities' button by all current workspaces buttons. Switch workspace or toggle overview by clicking on these buttons.\n\n You can use names for workspaces: there are two ways for that. 1) Edit the string array 'org.gnome.desktop.wm.preferences.workspace-names' gsettings key (through dconf editor, e.g.). 2) Use official GNOME extension Workspaces Indicator's settings. You don't have to write a long enough list: numbers are displayed if no workspace name is defined. 3) Enable direct renaming via context menu in the preferences of this extension.", "name": "Workspaces Bar", "shell-version": [ "3.36", @@ -11,4 +11,4 @@ "url": "https://github.com/fthx/workspaces-bar", "uuid": "workspaces-bar@fthx", "version": 12 -} \ No newline at end of file +} From c90c4125573897cdc52352a7c458ed65e4fd2af8 Mon Sep 17 00:00:00 2001 From: rkla Date: Sat, 1 Jan 2022 17:19:39 +0100 Subject: [PATCH 4/7] fixes tabs --- extension.js | 210 +++++++++++++++++++++++++-------------------------- 1 file changed, 105 insertions(+), 105 deletions(-) diff --git a/extension.js b/extension.js index 590d7e7..9d8d81a 100644 --- a/extension.js +++ b/extension.js @@ -1,8 +1,8 @@ /* - Workspaces Bar - Copyright Francois Thirioux 2021 - GitHub contributors: @fthx - License GPL v3 + Workspaces Bar + Copyright Francois Thirioux 2021 + GitHub contributors: @fthx + License GPL v3 */ @@ -21,26 +21,26 @@ const WORKSPACES_BAR_SCHEMA = 'org.gnome.shell.extensions.workspaces-bar'; var WorkspacesBar = GObject.registerClass( class WorkspacesBar extends PanelMenu.Button { - _init() { - super._init(0.0, 'Workspaces bar'); - - // define gsettings schema for workspaces names, get workspaces names, signal for settings key changed - this.workspaces_settings = new Gio.Settings({ schema: WORKSPACES_SCHEMA }); - this.workspaces_names_changed = this.workspaces_settings.connect(`changed::${WORKSPACES_KEY}`, this._update_workspaces_names.bind(this)); - - // hide Activities button - this._show_activities(false); - - // bar creation - this.ws_bar = new St.BoxLayout({}); + _init() { + super._init(0.0, 'Workspaces bar'); + + // define gsettings schema for workspaces names, get workspaces names, signal for settings key changed + this.workspaces_settings = new Gio.Settings({ schema: WORKSPACES_SCHEMA }); + this.workspaces_names_changed = this.workspaces_settings.connect(`changed::${WORKSPACES_KEY}`, this._update_workspaces_names.bind(this)); + + // hide Activities button + this._show_activities(false); + + // bar creation + this.ws_bar = new St.BoxLayout({}); this._update_workspaces_names(); this.add_child(this.ws_bar); // signals for workspaces state: active workspace, number of workspaces - this._ws_active_changed = global.workspace_manager.connect('active-workspace-changed', this._update_ws.bind(this)); - this._ws_number_changed = global.workspace_manager.connect('notify::n-workspaces', this._update_ws.bind(this)); - this._restacked = global.display.connect('restacked', this._update_ws.bind(this)); - this._windows_changed = Shell.WindowTracker.get_default().connect('tracked-windows-changed', this._update_ws.bind(this)); + this._ws_active_changed = global.workspace_manager.connect('active-workspace-changed', this._update_ws.bind(this)); + this._ws_number_changed = global.workspace_manager.connect('notify::n-workspaces', this._update_ws.bind(this)); + this._restacked = global.display.connect('restacked', this._update_ws.bind(this)); + this._windows_changed = Shell.WindowTracker.get_default().connect('tracked-windows-changed', this._update_ws.bind(this)); // setup settings this._renaming = false; @@ -67,29 +67,29 @@ class WorkspacesBar extends PanelMenu.Button { } }; this.connect('button-press-event', Lang.bind(this, click_handler)); - } - - // remove signals, restore Activities button, destroy workspaces bar - _destroy() { - this._show_activities(true); - if (this._ws_active_changed) { - global.workspace_manager.disconnect(this._ws_active_changed); - } - if (this._ws_number_changed) { - global.workspace_manager.disconnect(this._ws_number_changed); - } - if (this._restacked) { - global.display.disconnect(this._restacked); - } - if (this._windows_changed) { - Shell.WindowTracker.get_default().disconnect(this._windows_changed); - } - if (this.workspaces_names_changed) { - this.workspaces_settings.disconnect(this.workspaces_names_changed); - } - this.ws_bar.destroy(); - super.destroy(); - } + } + + // remove signals, restore Activities button, destroy workspaces bar + _destroy() { + this._show_activities(true); + if (this._ws_active_changed) { + global.workspace_manager.disconnect(this._ws_active_changed); + } + if (this._ws_number_changed) { + global.workspace_manager.disconnect(this._ws_number_changed); + } + if (this._restacked) { + global.display.disconnect(this._restacked); + } + if (this._windows_changed) { + Shell.WindowTracker.get_default().disconnect(this._windows_changed); + } + if (this.workspaces_names_changed) { + this.workspaces_settings.disconnect(this.workspaces_names_changed); + } + this.ws_bar.destroy(); + super.destroy(); + } // build a context popup menu with the workspace name entries _build_menu() { @@ -117,10 +117,10 @@ class WorkspacesBar extends PanelMenu.Button { // set the text to workspace names if (this.workspaces_names[ws_index]) { - ws_name_entry.set_text("" + this.workspaces_names[ws_index] + ""); - } else { - ws_name_entry.set_text(" " + (ws_index + 1) + " "); - } + ws_name_entry.set_text("" + this.workspaces_names[ws_index] + ""); + } else { + ws_name_entry.set_text(" " + (ws_index + 1) + " "); + } // make entry trigger rename of this workspace on pressing enter var enter_handler = function(origin, event) { @@ -148,62 +148,62 @@ class WorkspacesBar extends PanelMenu.Button { this.menu_entries = entries; } - - // hide 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(); - } - } - } - - // update workspaces names - _update_workspaces_names() { - this.workspaces_names = this.workspaces_settings.get_strv(WORKSPACES_KEY); - this._update_ws(); + + // hide 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(); + } + } + } + + // update workspaces names + _update_workspaces_names() { + this.workspaces_names = this.workspaces_settings.get_strv(WORKSPACES_KEY); + this._update_ws(); // build the menu this._build_menu(); - } + } - // update the workspaces bar + // update the workspaces bar _update_ws() { - // destroy old workspaces bar buttons - this.ws_bar.destroy_all_children(); - - // get number of workspaces + // destroy old workspaces bar buttons + this.ws_bar.destroy_all_children(); + + // get number of workspaces this.ws_count = global.workspace_manager.get_n_workspaces(); this.active_ws_index = global.workspace_manager.get_active_workspace_index(); - - // display all current workspaces buttons + + // display all current workspaces buttons for (let ws_index = 0; ws_index < this.ws_count; ++ws_index) { - this.ws_box = new St.Bin({visible: true, reactive: true, can_focus: true, track_hover: true}); - this.ws_box.label = new St.Label({y_align: Clutter.ActorAlign.CENTER}); - if (ws_index == this.active_ws_index) { - if (global.workspace_manager.get_workspace_by_index(ws_index).n_windows > 0) { - this.ws_box.label.style_class = 'desktop-label-nonempty-active'; - } else { - this.ws_box.label.style_class = 'desktop-label-empty-active'; - } - } else { - if (global.workspace_manager.get_workspace_by_index(ws_index).n_windows > 0) { - this.ws_box.label.style_class = 'desktop-label-nonempty-inactive'; - } else { - this.ws_box.label.style_class = 'desktop-label-empty-inactive'; - } - } - if (this.workspaces_names[ws_index]) { - this.ws_box.label.set_text("" + this.workspaces_names[ws_index] + ""); - } else { - this.ws_box.label.set_text(" " + (ws_index + 1) + " "); - } - this.ws_box.set_child(this.ws_box.label); + this.ws_box = new St.Bin({visible: true, reactive: true, can_focus: true, track_hover: true}); + this.ws_box.label = new St.Label({y_align: Clutter.ActorAlign.CENTER}); + if (ws_index == this.active_ws_index) { + if (global.workspace_manager.get_workspace_by_index(ws_index).n_windows > 0) { + this.ws_box.label.style_class = 'desktop-label-nonempty-active'; + } else { + this.ws_box.label.style_class = 'desktop-label-empty-active'; + } + } else { + if (global.workspace_manager.get_workspace_by_index(ws_index).n_windows > 0) { + this.ws_box.label.style_class = 'desktop-label-nonempty-inactive'; + } else { + this.ws_box.label.style_class = 'desktop-label-empty-inactive'; + } + } + if (this.workspaces_names[ws_index]) { + this.ws_box.label.set_text("" + this.workspaces_names[ws_index] + ""); + } else { + this.ws_box.label.set_text(" " + (ws_index + 1) + " "); + } + this.ws_box.set_child(this.ws_box.label); // if renaming is enabled, only switch to workspace on left click when popup menu is not open - this.ws_box.connect('button-press-event', (origin, event) => { + this.ws_box.connect('button-press-event', (origin, event) => { if (this._renaming) { if (event.get_button() == 1 && !this.menu.isOpen) { this._toggle_ws(ws_index); @@ -213,17 +213,17 @@ class WorkspacesBar extends PanelMenu.Button { } }); - this.ws_bar.add_actor(this.ws_box); - } + this.ws_bar.add_actor(this.ws_box); + } } // activate workspace or show overview _toggle_ws(ws_index) { - if (global.workspace_manager.get_active_workspace_index() == ws_index) { - Main.overview.toggle(); - } else { - global.workspace_manager.get_workspace_by_index(ws_index).activate(global.get_current_time()); - } + if (global.workspace_manager.get_active_workspace_index() == ws_index) { + Main.overview.toggle(); + } else { + global.workspace_manager.get_workspace_by_index(ws_index).activate(global.get_current_time()); + } } // rename all workspaces @@ -263,16 +263,16 @@ class Extension { } enable() { - this.workspaces_bar = new WorkspacesBar(); - Main.panel.addToStatusArea('workspaces-bar', this.workspaces_bar, 0, 'left'); + this.workspaces_bar = new WorkspacesBar(); + Main.panel.addToStatusArea('workspaces-bar', this.workspaces_bar, 0, 'left'); } disable() { - this.workspaces_bar._destroy(); + this.workspaces_bar._destroy(); } } function init() { - return new Extension(); + return new Extension(); } From 0d9f6ec3d025b143349efe981bd30c8eb5d88d1a Mon Sep 17 00:00:00 2001 From: rkla Date: Sat, 1 Jan 2022 21:23:32 +0100 Subject: [PATCH 5/7] removes unnecessary code in click handler --- extension.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/extension.js b/extension.js index 9d8d81a..2ea7712 100644 --- a/extension.js +++ b/extension.js @@ -49,18 +49,12 @@ class WorkspacesBar extends PanelMenu.Button { this._gsettings.connect("changed::renaming", this._renaming_changed.bind(this)); this._renaming_changed(); - // if enabled, make popup menu only open on right click + // if enabled, make popup menu only open on right/middle click var click_handler = function(origin, event) { const key = event.get_button(); if (this._renaming) { if (key == 1) { this.menu.close(); - } else if (key == 3) { - if (!this.menu.isOpen) { - this.menu.close(); - } else { - this.menu.open(); - } } } else { this.menu.close(); From 37dc791f16175084d41789f45d2a92fadac10982 Mon Sep 17 00:00:00 2001 From: rkla Date: Mon, 3 Jan 2022 21:01:56 +0100 Subject: [PATCH 6/7] do menu building on ws number changed --- extension.js | 248 ++++++++++++++++++++++++--------------------------- 1 file changed, 118 insertions(+), 130 deletions(-) diff --git a/extension.js b/extension.js index 2ea7712..48547b7 100644 --- a/extension.js +++ b/extension.js @@ -1,13 +1,12 @@ /* - Workspaces Bar - Copyright Francois Thirioux 2021 - GitHub contributors: @fthx - License GPL v3 + Workspaces Bar + Copyright Francois Thirioux 2021 + GitHub contributors: @fthx + License GPL v3 */ const { Clutter, Gio, GObject, Shell, St } = imports.gi; -const Lang = imports.lang const PopupMenu = imports.ui.popupMenu; const Main = imports.ui.main; @@ -16,31 +15,31 @@ const ExtensionUtils = imports.misc.extensionUtils; var WORKSPACES_SCHEMA = "org.gnome.desktop.wm.preferences"; var WORKSPACES_KEY = "workspace-names"; -const WORKSPACES_BAR_SCHEMA = 'org.gnome.shell.extensions.workspaces-bar'; +const WORKSPACES_BAR_SCHEMA = 'org.gnome.shell.extensions.example1'; var WorkspacesBar = GObject.registerClass( class WorkspacesBar extends PanelMenu.Button { - _init() { - super._init(0.0, 'Workspaces bar'); - - // define gsettings schema for workspaces names, get workspaces names, signal for settings key changed - this.workspaces_settings = new Gio.Settings({ schema: WORKSPACES_SCHEMA }); - this.workspaces_names_changed = this.workspaces_settings.connect(`changed::${WORKSPACES_KEY}`, this._update_workspaces_names.bind(this)); - - // hide Activities button - this._show_activities(false); - - // bar creation - this.ws_bar = new St.BoxLayout({}); + _init() { + super._init(0.0, 'Workspaces bar'); + + // define gsettings schema for workspaces names, get workspaces names, signal for settings key changed + this.workspaces_settings = new Gio.Settings({ schema: WORKSPACES_SCHEMA }); + this.workspaces_names_changed = this.workspaces_settings.connect(`changed::${WORKSPACES_KEY}`, this._update_workspaces_names.bind(this)); + + // hide Activities button + this._show_activities(false); + + // bar creation + this.ws_bar = new St.BoxLayout({}); this._update_workspaces_names(); this.add_child(this.ws_bar); // signals for workspaces state: active workspace, number of workspaces - this._ws_active_changed = global.workspace_manager.connect('active-workspace-changed', this._update_ws.bind(this)); - this._ws_number_changed = global.workspace_manager.connect('notify::n-workspaces', this._update_ws.bind(this)); - this._restacked = global.display.connect('restacked', this._update_ws.bind(this)); - this._windows_changed = Shell.WindowTracker.get_default().connect('tracked-windows-changed', this._update_ws.bind(this)); + this._ws_active_changed = global.workspace_manager.connect('active-workspace-changed', this._update_ws.bind(this)); + this._ws_number_changed = global.workspace_manager.connect('notify::n-workspaces', this._update_ws.bind(this)); + this._restacked = global.display.connect('restacked', this._update_ws.bind(this)); + this._windows_changed = Shell.WindowTracker.get_default().connect('tracked-windows-changed', this._update_ws.bind(this)); // setup settings this._renaming = false; @@ -49,7 +48,7 @@ class WorkspacesBar extends PanelMenu.Button { this._gsettings.connect("changed::renaming", this._renaming_changed.bind(this)); this._renaming_changed(); - // if enabled, make popup menu only open on right/middle click + // make popup menu only open on right click var click_handler = function(origin, event) { const key = event.get_button(); if (this._renaming) { @@ -60,32 +59,32 @@ class WorkspacesBar extends PanelMenu.Button { this.menu.close(); } }; - this.connect('button-press-event', Lang.bind(this, click_handler)); - } - - // remove signals, restore Activities button, destroy workspaces bar - _destroy() { - this._show_activities(true); - if (this._ws_active_changed) { - global.workspace_manager.disconnect(this._ws_active_changed); - } - if (this._ws_number_changed) { - global.workspace_manager.disconnect(this._ws_number_changed); - } - if (this._restacked) { - global.display.disconnect(this._restacked); - } - if (this._windows_changed) { - Shell.WindowTracker.get_default().disconnect(this._windows_changed); - } - if (this.workspaces_names_changed) { - this.workspaces_settings.disconnect(this.workspaces_names_changed); - } - this.ws_bar.destroy(); - super.destroy(); - } - - // build a context popup menu with the workspace name entries + this.connect('button-press-event', click_handler.bind(this)); + } + + // remove signals, restore Activities button, destroy workspaces bar + _destroy() { + this._show_activities(true); + if (this._ws_active_changed) { + global.workspace_manager.disconnect(this._ws_active_changed); + } + if (this._ws_number_changed) { + global.workspace_manager.disconnect(this._ws_number_changed); + } + if (this._restacked) { + global.display.disconnect(this._restacked); + } + if (this._windows_changed) { + Shell.WindowTracker.get_default().disconnect(this._windows_changed); + } + if (this.workspaces_names_changed) { + this.workspaces_settings.disconnect(this.workspaces_names_changed); + } + this.ws_bar.destroy(); + super.destroy(); + } + + // build a context menu with the workspace name entries _build_menu() { // remove all menu items this.menu.removeAll(); @@ -111,21 +110,20 @@ class WorkspacesBar extends PanelMenu.Button { // set the text to workspace names if (this.workspaces_names[ws_index]) { - ws_name_entry.set_text("" + this.workspaces_names[ws_index] + ""); - } else { - ws_name_entry.set_text(" " + (ws_index + 1) + " "); - } + ws_name_entry.set_text("" + this.workspaces_names[ws_index] + ""); + } else { + ws_name_entry.set_text(" " + (ws_index + 1) + " "); + } // make entry trigger rename of this workspace on pressing enter var enter_handler = function(origin, event) { const key = event.get_key_symbol(); if (key == Clutter.KEY_Return || key == Clutter.KEY_KP_Enter || key == Clutter.KEY_ISO_Enter) { - this._rename_ws(ws_index, origin.get_text()); + //this._rename_ws(ws_index, origin.get_text()); + this._rename_all() } }; - ws_name_entry.get_clutter_text().connect( - 'key-press-event', Lang.bind(this, enter_handler) - ); + ws_name_entry.get_clutter_text().connect('key-press-event', enter_handler.bind(this)); // add menu item menu_item.add(ws_name_entry); @@ -135,69 +133,67 @@ class WorkspacesBar extends PanelMenu.Button { entries.push(ws_name_entry); } - // add menu item for renaming all workspaces at once + // add menu item for rename action let rename_menu_item = new PopupMenu.PopupMenuItem(_('Rename')); this.menu.addMenuItem(rename_menu_item); - rename_menu_item.connect('activate', this._rename_all.bind(this))); + rename_menu_item.connect('activate', this._rename_all.bind(this)); this.menu_entries = entries; } - - // hide 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(); - } - } - } - - // update workspaces names - _update_workspaces_names() { - this.workspaces_names = this.workspaces_settings.get_strv(WORKSPACES_KEY); - this._update_ws(); - // build the menu - this._build_menu(); - } - - // update the workspaces bar + + // hide 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(); + } + } + } + + // update workspaces names + _update_workspaces_names() { + this.workspaces_names = this.workspaces_settings.get_strv(WORKSPACES_KEY); + this._update_ws(); + } + + // update the workspaces bar _update_ws() { - // destroy old workspaces bar buttons - this.ws_bar.destroy_all_children(); - - // get number of workspaces + // destroy old workspaces bar buttons + this.ws_bar.destroy_all_children(); + + // get number of workspaces this.ws_count = global.workspace_manager.get_n_workspaces(); this.active_ws_index = global.workspace_manager.get_active_workspace_index(); - - // display all current workspaces buttons + + // display all current workspaces buttons for (let ws_index = 0; ws_index < this.ws_count; ++ws_index) { - this.ws_box = new St.Bin({visible: true, reactive: true, can_focus: true, track_hover: true}); - this.ws_box.label = new St.Label({y_align: Clutter.ActorAlign.CENTER}); - if (ws_index == this.active_ws_index) { - if (global.workspace_manager.get_workspace_by_index(ws_index).n_windows > 0) { - this.ws_box.label.style_class = 'desktop-label-nonempty-active'; - } else { - this.ws_box.label.style_class = 'desktop-label-empty-active'; - } - } else { - if (global.workspace_manager.get_workspace_by_index(ws_index).n_windows > 0) { - this.ws_box.label.style_class = 'desktop-label-nonempty-inactive'; - } else { - this.ws_box.label.style_class = 'desktop-label-empty-inactive'; - } - } - if (this.workspaces_names[ws_index]) { - this.ws_box.label.set_text("" + this.workspaces_names[ws_index] + ""); - } else { - this.ws_box.label.set_text(" " + (ws_index + 1) + " "); - } - this.ws_box.set_child(this.ws_box.label); + this.ws_box = new St.Bin({visible: true, reactive: true, can_focus: true, track_hover: true}); + this.ws_box.label = new St.Label({y_align: Clutter.ActorAlign.CENTER}); + if (ws_index == this.active_ws_index) { + if (global.workspace_manager.get_workspace_by_index(ws_index).n_windows > 0) { + this.ws_box.label.style_class = 'desktop-label-nonempty-active'; + } else { + this.ws_box.label.style_class = 'desktop-label-empty-active'; + } + } else { + if (global.workspace_manager.get_workspace_by_index(ws_index).n_windows > 0) { + this.ws_box.label.style_class = 'desktop-label-nonempty-inactive'; + } else { + this.ws_box.label.style_class = 'desktop-label-empty-inactive'; + } + } + if (this.workspaces_names[ws_index]) { + this.ws_box.label.set_text("" + this.workspaces_names[ws_index] + ""); + } else { + this.ws_box.label.set_text(" " + (ws_index + 1) + " "); + } + this.ws_box.set_child(this.ws_box.label); // if renaming is enabled, only switch to workspace on left click when popup menu is not open - this.ws_box.connect('button-press-event', (origin, event) => { + this.ws_box.connect('button-press-event', (origin, event) => { if (this._renaming) { if (event.get_button() == 1 && !this.menu.isOpen) { this._toggle_ws(ws_index); @@ -207,17 +203,19 @@ class WorkspacesBar extends PanelMenu.Button { } }); - this.ws_bar.add_actor(this.ws_box); - } + this.ws_bar.add_actor(this.ws_box); + } + // (re)build the menu + this._build_menu(); } // activate workspace or show overview _toggle_ws(ws_index) { - if (global.workspace_manager.get_active_workspace_index() == ws_index) { - Main.overview.toggle(); - } else { - global.workspace_manager.get_workspace_by_index(ws_index).activate(global.get_current_time()); - } + if (global.workspace_manager.get_active_workspace_index() == ws_index) { + Main.overview.toggle(); + } else { + global.workspace_manager.get_workspace_by_index(ws_index).activate(global.get_current_time()); + } } // rename all workspaces @@ -236,16 +234,6 @@ class WorkspacesBar extends PanelMenu.Button { this.workspaces_settings.set_strv(WORKSPACES_KEY, new_workspaces_names); } - // rename workspace with given index - _rename_ws(ws_index, ws_name) { - // build array with altered workspace name - let new_workspaces_names = Array.from(this.workspaces_names); - new_workspaces_names[ws_index] = ws_name; - - // set workspace names - this.workspaces_settings.set_strv(WORKSPACES_KEY, new_workspaces_names); - } - // handle (de)activation of renaming _renaming_changed() { this._renaming = this._gsettings.get_boolean('renaming'); @@ -257,16 +245,16 @@ class Extension { } enable() { - this.workspaces_bar = new WorkspacesBar(); - Main.panel.addToStatusArea('workspaces-bar', this.workspaces_bar, 0, 'left'); + this.workspaces_bar = new WorkspacesBar(); + Main.panel.addToStatusArea('workspaces-bar', this.workspaces_bar, 0, 'left'); } disable() { - this.workspaces_bar._destroy(); + this.workspaces_bar._destroy(); } } function init() { - return new Extension(); + return new Extension(); } From c80afceffd7bb9fba7448c824baaf4fc9fa2bc68 Mon Sep 17 00:00:00 2001 From: rkla Date: Sun, 6 Feb 2022 11:44:35 +0100 Subject: [PATCH 7/7] Fixes for changeing num ws, whitespace handling - ws name array is updated according to num ws - when renaming whitespaces are trimmed - only small names are padded in ws bar --- extension.js | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/extension.js b/extension.js index 48547b7..3d72f6e 100644 --- a/extension.js +++ b/extension.js @@ -43,6 +43,8 @@ class WorkspacesBar extends PanelMenu.Button { // setup settings this._renaming = false; + this._max_word_length_for_padding = 3; + this._spaces_padding = 2; this._gsettings = ExtensionUtils.getSettings(WORKSPACES_BAR_SCHEMA); this._gsettings.connect("changed::renaming", this._renaming_changed.bind(this)); @@ -110,9 +112,9 @@ class WorkspacesBar extends PanelMenu.Button { // set the text to workspace names if (this.workspaces_names[ws_index]) { - ws_name_entry.set_text("" + this.workspaces_names[ws_index] + ""); + ws_name_entry.set_text(this.workspaces_names[ws_index].trim()); } else { - ws_name_entry.set_text(" " + (ws_index + 1) + " "); + ws_name_entry.set_text((ws_index + 1).toString()); } // make entry trigger rename of this workspace on pressing enter @@ -156,6 +158,11 @@ class WorkspacesBar extends PanelMenu.Button { // update workspaces names _update_workspaces_names() { this.workspaces_names = this.workspaces_settings.get_strv(WORKSPACES_KEY); + this.ws_count = global.workspace_manager.get_n_workspaces(); + // if the workspace names array is too large, delete the trailing entries + if (this.workspaces_names.length > this.ws_count) { + this.workspaces_settings.set_strv(WORKSPACES_KEY, this.workspaces_names.slice(0, this.ws_count)); + } // else if(this.workspaces_names.length < this.ws_count) -> needs handling? this._update_ws(); } @@ -186,9 +193,13 @@ class WorkspacesBar extends PanelMenu.Button { } } if (this.workspaces_names[ws_index]) { - this.ws_box.label.set_text("" + this.workspaces_names[ws_index] + ""); + if (this.workspaces_names[ws_index].length <= this._max_word_length_for_padding) { // space padding for small names + this.ws_box.label.set_text(" ".repeat(this._spaces_padding) + this.workspaces_names[ws_index] + " ".repeat(this._spaces_padding)); + } else { + this.ws_box.label.set_text(this.workspaces_names[ws_index]); + } } else { - this.ws_box.label.set_text(" " + (ws_index + 1) + " "); + this.ws_box.label.set_text(" ".repeat(this._spaces_padding) + (ws_index + 1) + " ".repeat(this._spaces_padding)); } this.ws_box.set_child(this.ws_box.label); @@ -220,13 +231,13 @@ class WorkspacesBar extends PanelMenu.Button { // rename all workspaces _rename_all() { - // check if menu and workspace number match - if (this.menu_entries.length != this.workspaces_names.length) {return;} + // check if number menu entries matches workspace number + if (this.menu_entries.length != this.ws_count) { return; } // build array of new workspace names let new_workspaces_names = []; - for (let i = 0; i < this.menu_entries.length; i++) { - let new_name = this.menu_entries[i].get_text(); + for (let i = 0; i < this.ws_count; i++) { + let new_name = this.menu_entries[i].get_text().trim(); new_workspaces_names.push(new_name); }