From 55c6b608038e354fda44767974df5386e38e52ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Hedin=20Br=C3=B8nner?= Date: Sun, 8 Jul 2018 17:13:18 +0200 Subject: [PATCH] Add settings UI with workspace controls and gap and margin spinners `Settings.ui` is built with and can be inpsected with Glade. --- Settings.ui | 722 ++++++++++++++++++++++++++++++++++++++++++++++++++++ prefs.js | 233 +++++++++++++++++ settings.js | 23 +- tiling.js | 34 ++- 4 files changed, 998 insertions(+), 14 deletions(-) create mode 100644 Settings.ui create mode 100644 prefs.js diff --git a/Settings.ui b/Settings.ui new file mode 100644 index 0000000..b1f46b6 --- /dev/null +++ b/Settings.ui @@ -0,0 +1,722 @@ + + + + + + 100 + 1 + 10 + + + 100 + 1 + 10 + + + 99 + 1 + 10 + + + True + True + + + True + False + 24 + vertical + + + True + False + 0 + in + + + True + False + none + + + True + True + + + True + False + 12 + 12 + 32 + + + True + False + True + Gap between windows + 0 + + + 0 + 0 + + + + + True + True + 2 + 2 + 1 + number + window_gap + True + True + if-valid + + + 1 + 0 + + + + + + + + + True + True + + + True + False + 12 + 12 + 32 + + + True + False + True + Horizontal margin + 0 + + + 0 + 0 + + + + + True + True + 2 + 2 + 0 + 1 + number + horizontal_margin + True + True + if-valid + + + 1 + 0 + + + + + + + + + True + True + + + True + False + 12 + 12 + 32 + + + True + False + True + Vertical margin + 0 + + + 0 + 0 + + + + + True + True + 2 + 2 + 0 + 1 + number + vertical_margin + True + True + if-valid + + + 1 + 0 + + + + + + + + + + + + + + False + True + 0 + + + + + + + + + + True + False + _General + True + + + False + + + + + True + False + 24 + 24 + vertical + 24 + + + True + False + 0 + in + + + True + False + none + + + True + True + + + True + False + 12 + 12 + 12 + 12 + 32 + + + True + False + True + Configure workspace + 0 + + + 0 + 0 + + + + + True + False + center + + + 1 + 0 + + + + + + + + + + + + + + False + True + 0 + + + + + True + False + + + + + + False + True + 1 + + + + + 1 + + + + + True + False + _Workspaces + True + + + 1 + False + + + + + True + False + 24 + vertical + + + True + False + 0 + in + + + True + False + none + + + True + True + + + True + False + 32 + + + True + False + True + Switch next + 0 + + + 0 + 0 + + + + + True + False + + + + + True + True + True + True + + + False + True + 0 + + + + + True + False + True + + + False + + + + + False + True + 1 + + + + + - + True + True + True + True + + + False + True + 2 + + + + + 1 + 0 + + + + + + + + + True + True + + + True + False + 32 + + + True + False + True + Switch previous + 0 + + + 0 + 0 + + + + + True + False + + + + + True + True + True + True + + + False + True + 0 + + + + + True + False + True + + + True + + + + + False + True + 1 + + + + + - + True + True + True + True + + + False + True + 2 + + + + + 1 + 0 + + + + + + + + + True + True + + + True + False + 32 + + + True + False + True + Switch left + 0 + + + 0 + 0 + + + + + True + False + + + + + True + True + True + True + + + False + True + 0 + + + + + True + False + True + + + True + + + + + False + True + 1 + + + + + - + True + True + True + True + + + False + True + 2 + + + + + 1 + 0 + + + + + + + + + True + True + + + True + False + 32 + + + True + False + True + Switch right + 0 + + + 0 + 0 + + + + + True + False + + + + + True + True + True + True + + + False + True + 0 + + + + + True + False + True + + + True + + + + + False + True + 1 + + + + + - + True + True + True + True + + + False + True + 2 + + + + + 1 + 0 + + + + + + + + + + + + + + False + True + 0 + + + + + + + + + + + + + + 2 + + + + + True + False + _Keybindings + True + + + 2 + False + + + + + True + False + vertical + + + + + + + + + + + + 3 + + + + + True + False + _About + True + + + 3 + False + + + + diff --git a/prefs.js b/prefs.js new file mode 100644 index 0000000..1455e8a --- /dev/null +++ b/prefs.js @@ -0,0 +1,233 @@ + +const Gio = imports.gi.Gio; +const GLib = imports.gi.GLib; +const GObject = imports.gi.GObject; +const Gtk = imports.gi.Gtk; +const Gdk = imports.gi.Gdk; +const Lang = imports.lang; +const Mainloop = imports.mainloop; + +const ExtensionUtils = imports.misc.extensionUtils; +const Me = ExtensionUtils.getCurrentExtension(); +const Convenience = Me.imports.convenience; + +const WORKSPACE_KEY = 'org.gnome.Shell.Extensions.PaperWM.Workspace'; +const WORKSPACE_LIST_KEY = 'org.gnome.Shell.Extensions.PaperWM.WorkspaceList'; + +const wmSettings = new Gio.Settings({ schema_id: + 'org.gnome.desktop.wm.preferences'}); + +const schemaSource = Gio.SettingsSchemaSource.new_from_directory( + GLib.build_filenamev([Me.path, "schemas"]), + Gio.SettingsSchemaSource.get_default(), + false +); + +const workspaceList = new Gio.Settings({ + settings_schema: schemaSource.lookup(WORKSPACE_LIST_KEY, true) +}); + +function getWorkspaceSettingsByUUID(uuid) { + return new Gio.Settings({ + settings_schema: schemaSource.lookup(WORKSPACE_KEY, true), + path: `/org/gnome/shell/extensions/paperwm/workspaces/${uuid}/`}); +} + +function getWorkspaceSettings(index) { + let list = workspaceList.get_strv('list'); + for (let uuid of list) { + let settings = getWorkspaceSettingsByUUID(uuid); + if (settings.get_int('index') === index) { + return [uuid, settings]; + } + } + return getNewWorkspaceSettings(index); +} + +function getNewWorkspaceSettings(index) { + let uuid = GLib.uuid_string_random(); + let settings = getWorkspaceSettingsByUUID(uuid); + let id = settings.connect('changed', () => { + settings.disconnect(id); + + if (settings.get_int('index') === -1) { + settings.set_int('index', index); + } + + let list = workspaceList.get_strv('list'); + list.push(uuid); + workspaceList.set_strv('list', list); + + }); + return [uuid, settings]; +} + +class SettingsWidget { + constructor() { + this._settings = Convenience.getSettings(); + this._workspaceList = workspaceList; + + this.builder = new Gtk.Builder(); + this.builder.add_from_file(Me.path + '/Settings.ui'); + + this.widget = new Gtk.ScrolledWindow({ hscrollbar_policy: Gtk.PolicyType.NEVER }); + this._notebook = this.builder.get_object('paperwm_settings'); + this.widget.add(this._notebook); + + // General + + let windowGap = this.builder.get_object('window_gap_spin'); + let gap = this._settings.get_int('window-gap'); + + windowGap.set_value(gap); + windowGap.connect('value-changed', () => { + this._settings.set_int('window-gap', windowGap.get_value()); + }); + + let hMargin = this.builder.get_object('hmargin_spinner'); + hMargin.set_value(this._settings.get_int('horizontal-margin')); + hMargin.connect('value-changed', () => { + this._settings.set_int('horizontal-margin', hMargin.get_value()); + }); + + let vMargin = this.builder.get_object('vmargin_spinner'); + vMargin.set_value(this._settings.get_int('vertical-margin')); + vMargin.connect('value-changed', () => { + this._settings.set_int('vertical-margin', vMargin.get_value()); + }); + + // Workspaces + const workspaceCombo = this.builder.get_object('worskpace_combo_text'); + const workspaceStack = this.builder.get_object('workspace_stack'); + + const nWorkspaces = wmSettings.get_int('num-workspaces'); + this.workspaceNames = wmSettings.get_strv('workspace-names'); + + for (let i=0; i < nWorkspaces; i++) { + let [uuid, settings] = getWorkspaceSettings(i); + let view = this.createWorkspacePage(settings, i); + + workspaceStack.add_named(view, i.toString()); + let name = this.getWorkspaceName(settings, i); + workspaceCombo.append_text(name); + } + + workspaceCombo.connect('changed', () => { + if (this._updatingName) + return; + + let active = workspaceCombo.get_active(); + log(`active ${active}`); + let page = workspaceStack.get_child_by_name(active.toString()); + workspaceStack.set_visible_child(page); + }); + + workspaceCombo.set_active(0); + + + createRow('foo', new Gtk.ColorButton()); + + } + + createWorkspacePage(settings, index) { + + let view = new Gtk.Frame(); + let list = new Gtk.ListBox(); + view.add(list); + + let nameEntry = new Gtk.Entry(); + let colorButton = new Gtk.ColorButton(); + let background = new Gtk.FileChooserButton(); + + list.add(createRow('Name', nameEntry)); + list.add(createRow('Color', colorButton)); + list.add(createRow('Background', background)); + + let rgba = new Gdk.RGBA(); + let color = settings.get_string('color'); + let palette = this._settings.get_strv('workspace-colors'); + if (color === '') + color = palette[index % palette.length]; + + rgba.parse(color); + colorButton.set_rgba(rgba); + + let filename = settings.get_string('background'); + if (filename === '') + background.unselect_all(); + else + background.set_filename(filename); + + nameEntry.set_text(this.getWorkspaceName(settings, index)); + + let workspace_combo = this.builder.get_object('worskpace_combo_text'); + + nameEntry.connect('changed', () => { + let active = workspace_combo.get_active(); + let name = nameEntry.get_text(); + + this._updatingName = true; + workspace_combo.remove(active); + workspace_combo.insert_text(active, name); + + workspace_combo.set_active(active); + this._updatingName = false; + + settings.set_string('name', name); + }); + + colorButton.connect('color-set', () => { + let color = colorButton.get_rgba().to_string(); + settings.set_string('color', color); + settings.set_string('background', ''); + background.unselect_all(); + }); + + background.connect('file-set', () => { + let filename = background.get_filename(); + settings.set_string('background', filename); + }); + + return view; + } + + getWorkspaceName(settings, index) { + let name = settings.get_string('name'); + if (name === '') + name = this.workspaceNames[index]; + if (name === undefined) + name = `Workspace ${index}`; + return name; + } + +} + +function createRow(text, widget, signal, handler) { + let margin = 12; + let row = new Gtk.ListBoxRow({selectable: false}); + let box = new Gtk.Box({ + margin_start: margin, margin_end: margin, + orientation: Gtk.Orientation.HORIZONTAL + }); + let label = new Gtk.Label({ + label: text, hexpand: true, xalign: 0 + }); + + box.add(label); + box.add(widget); + + row.add(box); + + return row; + +} + +function init() { +} + +function buildPrefsWidget() { + let settings = new SettingsWidget(); + let widget = settings.widget; + widget.show_all(); + return widget; +} diff --git a/settings.js b/settings.js index b468bab..42f37cd 100644 --- a/settings.js +++ b/settings.js @@ -1,10 +1,13 @@ var Extension = imports.misc.extensionUtils.extensions['paperwm@hedning:matrix.org']; var Gio = imports.gi.Gio; var GLib = imports.gi.GLib; + var settings = Extension.imports.convenience.getSettings(); -var Tiling = Extension.imports.tiling; var utils = Extension.imports.utils; +var Tiling = Extension.imports.tiling; + var debug = utils.debug; +var screen = global.screen; var WORKSPACE_KEY = 'org.gnome.Shell.Extensions.PaperWM.Workspace'; var WORKSPACE_LIST_KEY = 'org.gnome.Shell.Extensions.PaperWM.WorkspaceList'; @@ -44,6 +47,7 @@ function init() { settings.connect('changed::workspace-colors', setState); } +var id; function enable() { schemaSource = Gio.SettingsSchemaSource.new_from_directory( GLib.build_filenamev([Extension.path, "schemas"]), @@ -54,6 +58,23 @@ function enable() { workspaceList = new Gio.Settings({ settings_schema: schemaSource.lookup(WORKSPACE_LIST_KEY, true) }); + + // Update workspace settings if it's changed from the preference UI + id = workspaceList.connect('changed::list', () => { + for (let uuid of workspaceList.get_strv('list')) { + let settings = getWorkspaceSettingsByUUID(uuid); + let index = settings.get_int('index'); + let workspace = screen.get_workspace_by_index(index); + if (!workspace) + continue; + let space = Tiling.spaces.spaceOf(workspace); + space.setSettings([uuid, settings]); + } + }); +} + +function disable() { + workspaceList.disconnect(id); } function getWorkspaceSettings(space) { diff --git a/tiling.js b/tiling.js index 77d2599..f058d50 100644 --- a/tiling.js +++ b/tiling.js @@ -145,19 +145,7 @@ class Space extends Array { } this.setMonitor(monitor, false); - [this.uuid, this.settings] = - Settings.getWorkspaceSettings(this); - - this.updateColor(); - this.updateBackground(); - this.updateName(); - this.signals.connect(this.settings, 'changed::name', - this.updateName.bind(this)); - this.signals.connect(this.settings, 'changed::color', - this.updateColor.bind(this)); - this.signals.connect(this.settings, 'changed::background', - this.updateBackground.bind(this)); - + this.setSettings(Settings.getWorkspaceSettings(this)); actor.set_pivot_point(0.5, 0); @@ -478,6 +466,22 @@ class Space extends Array { }); } + setSettings([uuid, settings]) { + this.signals.disconnect(this.settings); + + this.settings = settings; + this.uuid = uuid; + this.updateColor(); + this.updateBackground(); + this.updateName(); + this.signals.connect(this.settings, 'changed::name', + this.updateName.bind(this)); + this.signals.connect(this.settings, 'changed::color', + this.updateColor.bind(this)); + this.signals.connect(this.settings, 'changed::background', + this.updateBackground.bind(this)); + } + updateColor() { let color = this.settings.get_string('color'); if (color === '') { @@ -506,6 +510,10 @@ class Space extends Array { Meta.prefs_change_workspace_name(this.workspace.index(), name); this.label.text = name; this.name = name; + + if (this.workspace === screen.get_active_workspace()) { + TopBar.setWorkspaceName(this.name); + } } setMonitor(monitor, animate) {