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.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
EXTENSION_ID = alternate-tab
|
||||
|
||||
EXTRA_MODULES = settings.js
|
||||
EXTRA_MODULES = prefs.js
|
||||
|
||||
include ../../extension.mk
|
||||
include ../../settings.mk
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -9,11 +9,6 @@
|
||||
<_summary>The alt tab behaviour.</_summary>
|
||||
<_description>Sets the Alt-Tab behaviour. Possible values are: native, all_thumbnails and workspace_icons.</_description>
|
||||
</key>
|
||||
<key type="b" name="first-time">
|
||||
<default>true</default>
|
||||
<_summary>Indicates if Alternate Tab is newly installed</_summary>
|
||||
<_description>Ask the user for a default behaviour if true.</_description>
|
||||
</key>
|
||||
<key type="b" name="highlight-selected">
|
||||
<default>false</default>
|
||||
<summary>Bring each selected window to the front.</summary>
|
||||
|
||||
124
extensions/alternate-tab/prefs.js
Normal file
124
extensions/alternate-tab/prefs.js
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user