From 245ab96a27c161b2c680c0148b60bcf1fe86fbf3 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Fri, 10 Feb 2012 18:04:56 +0100 Subject: [PATCH] alternate-tab: move to the new configuration system Since 3.3.5, gnome-shell offers an integrated configuration tool for extensions, which can be used by adding a new "prefs" module. Replace the old modal dialog with a new gtk dialog, which also allows to configure the new highlight-selected setting. --- extensions/alternate-tab/Makefile.am | 2 +- extensions/alternate-tab/extension.js | 8 -- ...ll.extensions.alternate-tab.gschema.xml.in | 5 - extensions/alternate-tab/prefs.js | 124 ++++++++++++++++++ extensions/alternate-tab/settings.js | 113 ---------------- 5 files changed, 125 insertions(+), 127 deletions(-) create mode 100644 extensions/alternate-tab/prefs.js delete mode 100644 extensions/alternate-tab/settings.js diff --git a/extensions/alternate-tab/Makefile.am b/extensions/alternate-tab/Makefile.am index da271056..1f353920 100644 --- a/extensions/alternate-tab/Makefile.am +++ b/extensions/alternate-tab/Makefile.am @@ -1,6 +1,6 @@ EXTENSION_ID = alternate-tab -EXTRA_MODULES = settings.js +EXTRA_MODULES = prefs.js include ../../extension.mk include ../../settings.mk diff --git a/extensions/alternate-tab/extension.js b/extensions/alternate-tab/extension.js index af531f98..4eb9b2db 100644 --- a/extensions/alternate-tab/extension.js +++ b/extensions/alternate-tab/extension.js @@ -28,14 +28,12 @@ const N_ = function(e) { return e }; const ExtensionUtils = imports.misc.extensionUtils; const Me = ExtensionUtils.getCurrentExtension(); const Convenience = Me.imports.convenience; -const Settings = Me.imports.settings; let settings; const POPUP_DELAY_TIMEOUT = 150; // milliseconds const SETTINGS_BEHAVIOUR_KEY = 'behaviour'; -const SETTINGS_FIRST_TIME_KEY = 'first-time'; const SETTINGS_HIGHLIGHT_SELECTED_KEY = 'highlight-selected'; const AltTabPopupWorkspaceIcons = new Lang.Class({ @@ -494,12 +492,6 @@ const MODES = { }; function doAltTab(display, screen, window, binding) { - if(settings.get_boolean(SETTINGS_FIRST_TIME_KEY)) { - let dialog = new Settings.AltTabSettingsDialog(settings); - dialog.open(); - return; - } - let behaviour = settings.get_string(SETTINGS_BEHAVIOUR_KEY); // alt-tab having no effect is unexpected, even with wrong settings diff --git a/extensions/alternate-tab/org.gnome.shell.extensions.alternate-tab.gschema.xml.in b/extensions/alternate-tab/org.gnome.shell.extensions.alternate-tab.gschema.xml.in index c93172e7..f179b11d 100644 --- a/extensions/alternate-tab/org.gnome.shell.extensions.alternate-tab.gschema.xml.in +++ b/extensions/alternate-tab/org.gnome.shell.extensions.alternate-tab.gschema.xml.in @@ -9,11 +9,6 @@ <_summary>The alt tab behaviour. <_description>Sets the Alt-Tab behaviour. Possible values are: native, all_thumbnails and workspace_icons. - - true - <_summary>Indicates if Alternate Tab is newly installed - <_description>Ask the user for a default behaviour if true. - false Bring each selected window to the front. diff --git a/extensions/alternate-tab/prefs.js b/extensions/alternate-tab/prefs.js new file mode 100644 index 00000000..f9591e4d --- /dev/null +++ b/extensions/alternate-tab/prefs.js @@ -0,0 +1,124 @@ +/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */ + +/* most of the code is borrowed from + * > js/ui/altTab.js < + * of the gnome-shell source code + */ + +const Gdk = imports.gi.Gdk; +const Gio = imports.gi.Gio; +const Gtk = imports.gi.Gtk; +const GObject = imports.gi.GObject; +const Lang = imports.lang; + +const Gettext = imports.gettext.domain('gnome-shell-extensions'); +const _ = Gettext.gettext; +const N_ = function(e) { return e }; + +const ExtensionUtils = imports.misc.extensionUtils; +const Me = ExtensionUtils.getCurrentExtension(); +const Convenience = Me.imports.convenience; + +const SETTINGS_BEHAVIOUR_KEY = 'behaviour'; +const SETTINGS_HIGHLIGHT_KEY = 'highlight-selected'; + +const MODES = { + all_thumbnails: { + name: N_("All & Thumbnails"), + description: N_("This mode presents all applications from all workspaces in one selection \ +list. Instead of using the application icon of every window, it uses small \ +thumbnails resembling the window itself."), + extra_widgets: [ ] + }, + workspace_icons: { + name: N_("Workspace & Icons"), + description: N_("This mode let's you switch between the applications of your current \ +workspace and gives you additionally the option to switch to the last used \ +application of your previous workspace. This is always the last symbol in \ +the list and is segregated by a separator/vertical line if available. \n\ +Every window is represented by its application icon."), + extra_widgets: [ + { label: N_("Move current selection to front before closing the popup"), key: SETTINGS_HIGHLIGHT_KEY } + ] + } +}; + +const AltTabSettingsWidget = new GObject.Class({ + Name: 'AlternateTab.Prefs.AltTabSettingsWidget', + GTypeName: 'AltTabSettingsWidget', + Extends: Gtk.Grid, + + _init : function(params) { + this.parent(params); + this.column_spacing = 10; + this.margin = 10; + + this._settings = Convenience.getSettings(); + + let introLabel = _("The Alternate Tab can be used in different modes, that \ +affect the way windows are chosen and presented."); + + this.attach(new Gtk.Label({ label: introLabel, wrap: true, sensitive: true, + margin_bottom: 10, margin_top: 5 }), + 0, 0, 2, 1); + + let top = 1; + let radio = null; + let currentMode = this._settings.get_string(SETTINGS_BEHAVIOUR_KEY); + for (let mode in MODES) { + // copy the mode variable because it has function scope, not block scope + // so cannot be used in a closure + let modeCapture = mode; + let obj = MODES[mode]; + let name = Gettext.gettext(obj.name); + let description = Gettext.gettext(obj.description); + let nextra = obj.extra_widgets.length; + + radio = new Gtk.RadioButton({ group: radio, label: name, valign: Gtk.Align.START }); + radio.connect('toggled', Lang.bind(this, function(widget) { + if (widget.active) + this._settings.set_string(SETTINGS_BEHAVIOUR_KEY, modeCapture); + this._updateSensitivity(widget, widget.active); + })); + this.attach(radio, 0, top, 1, nextra + 1); + + let descriptionLabel = new Gtk.Label({ label: description, wrap: true, sensitive: true, + xalign: 0.0, justify: Gtk.Justification.FILL }); + this.attach(descriptionLabel, 1, top, 1, 1); + + radio._extra = []; + for (let i = 0; i < nextra; i++) { + let key = obj.extra_widgets[i].key; + let label = Gettext.gettext(obj.extra_widgets[i].label); + + let extra = new Gtk.CheckButton({ label: label }); + this._settings.bind(key, extra, 'active', Gio.SettingsBindFlags.DEFAULT); + + radio._extra.push(extra); + this.attach(extra, 1, top + i + 1, 1, 1); + } + + if (mode == currentMode) + radio.active = true; + this._updateSensitivity(radio, radio.active); + + top += nextra + 1; + } + }, + + _updateSensitivity: function(widget, active) { + for (let i = 0; i < widget._extra.length; i++) + widget._extra[i].sensitive = active; + }, +}); + +function init() { + Convenience.initTranslations(); +} + +function buildPrefsWidget() { + let widget = new AltTabSettingsWidget(); + widget.show_all(); + + return widget; +} diff --git a/extensions/alternate-tab/settings.js b/extensions/alternate-tab/settings.js deleted file mode 100644 index 6b48b9d5..00000000 --- a/extensions/alternate-tab/settings.js +++ /dev/null @@ -1,113 +0,0 @@ -/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */ - -/* most of the code is borrowed from - * > js/ui/altTab.js < - * of the gnome-shell source code - */ - -const Clutter = imports.gi.Clutter; -const Gdk = imports.gi.Gdk; -const Gio = imports.gi.Gio; -const Gtk = imports.gi.Gtk; -const Lang = imports.lang; -const Mainloop = imports.mainloop; -const Meta = imports.gi.Meta; -const Shell = imports.gi.Shell; -const St = imports.gi.St; - -const AltTab = imports.ui.altTab; -const Main = imports.ui.main; -const ModalDialog = imports.ui.modalDialog; -const Tweener = imports.ui.tweener; -const WindowManager = imports.ui.windowManager; - -const Gettext = imports.gettext.domain('gnome-shell-extensions'); -const _ = Gettext.gettext; -const N_ = function(e) { return e }; - -const SETTINGS_BEHAVIOUR_KEY = 'behaviour'; -const SETTINGS_FIRST_TIME_KEY = 'first-time'; - -const MESSAGE = N_("This is the first time you use the Alternate Tab extension. \n\ -Please choose your preferred behaviour:\n\ -\n\ -All & Thumbnails:\n\ - This mode presents all applications from all workspaces in one selection \n\ - list. Instead of using the application icon of every window, it uses small \n\ - thumbnails resembling the window itself. \n\ -\n\ -Workspace & Icons:\n\ - This mode let's you switch between the applications of your current \n\ - workspace and gives you additionally the option to switch to the last used \n\ - application of your previous workspace. This is always the last symbol in \n\ - the list and is segregated by a separator/vertical line if available. \n\ - Every window is represented by its application icon. \n\ -\n\ -If you whish to revert to the default behavior for the Alt-Tab switcher, just\n\ -disable the extension from extensions.gnome.org or the Advanced Settings application.\ -"); - -const AltTabSettingsDialog = new Lang.Class({ - Name: 'AlternateTab.Settings.AltTabSettingsDialog', - Extends: ModalDialog.ModalDialog, - - _init : function(settings) { - this.settings = settings; - this.parent({ styleClass: null }); - - let mainContentBox = new St.BoxLayout({ style_class: 'polkit-dialog-main-layout', - vertical: false }); - this.contentLayout.add(mainContentBox, - { x_fill: true, - y_fill: true }); - - let messageBox = new St.BoxLayout({ style_class: 'polkit-dialog-message-layout', - vertical: true }); - mainContentBox.add(messageBox, - { y_align: St.Align.START }); - - this._subjectLabel = new St.Label({ style_class: 'polkit-dialog-headline', - text: _("Alt Tab Behaviour") }); - - messageBox.add(this._subjectLabel, - { y_fill: false, - y_align: St.Align.START }); - - this._descriptionLabel = new St.Label({ style_class: 'polkit-dialog-description', - text: Gettext.gettext(MESSAGE) }); - - messageBox.add(this._descriptionLabel, - { y_fill: true, - y_align: St.Align.START }); - - - this.setButtons([ - { - label: _("All & Thumbnails"), - action: Lang.bind(this, function() { - this.setBehaviour('all_thumbnails'); - this.close(); - }) - }, - { - label: _("Workspace & Icons"), - action: Lang.bind(this, function() { - this.setBehaviour('workspace_icons'); - this.close(); - }) - }, - { - label: _("Cancel"), - action: Lang.bind(this, function() { - this.close(); - }), - key: Clutter.Escape - } - ]); - }, - - setBehaviour: function(behaviour) { - this.settings.set_string(SETTINGS_BEHAVIOUR_KEY, behaviour); - this.settings.set_boolean(SETTINGS_FIRST_TIME_KEY, false); - } -});