[gnome-shell-extensions] Revert "Remove alternate-tab extension"
- From: Giovanni Campagna <gcampagna src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell-extensions] Revert "Remove alternate-tab extension"
- Date: Mon, 10 Dec 2012 23:10:47 +0000 (UTC)
commit 9900ae19dc2734a0d42df2635901d46ea0d409c6
Author: Giovanni Campagna <gcampagna src gnome org>
Date: Tue Dec 11 00:10:00 2012 +0100
Revert "Remove alternate-tab extension"
This reverts commit 0b7c3e3dbb0f44a4e8b4b501698d591b1befbf41.
Pushed by mistake, and we actually want the alternate-tab extension,
just in a different form.
configure.ac | 5 +-
extensions/alternate-tab/Makefile.am | 6 +
extensions/alternate-tab/extension.js | 448 ++++++++++++++++++++
extensions/alternate-tab/metadata.json.in | 11 +
...e.shell.extensions.alternate-tab.gschema.xml.in | 26 ++
extensions/alternate-tab/prefs.js | 84 ++++
extensions/alternate-tab/stylesheet.css | 1 +
po/POTFILES.in | 3 +
8 files changed, 582 insertions(+), 2 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 7d2d477..90f14bc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -27,7 +27,7 @@ fi
AC_SUBST([SHELL_VERSION])
dnl keep this in alphabetic order
-CLASSIC_EXTENSIONS="apps-menu places-menu default-min-max"
+CLASSIC_EXTENSIONS="apps-menu places-menu alternate-tab default-min-max"
DEFAULT_EXTENSIONS="$CLASSIC_EXTENSIONS alternative-status-menu drive-menu windowsNavigator workspace-indicator"
ALL_EXTENSIONS="$DEFAULT_EXTENSIONS auto-move-windows example native-window-placement systemMonitor user-theme xrandr-indicator"
AC_SUBST(CLASSIC_EXTENSIONS, [$CLASSIC_EXTENSIONS])
@@ -62,7 +62,7 @@ for e in $enable_extensions; do
[AC_MSG_WARN([gnome-desktop-3.0 not found, disabling xrandr-indicator])])
;;
dnl keep this in alphabetic order
- alternative-status-menu|apps-menu|auto-move-windows|default-min-max|drive-menu|example|native-window-placement|places-menu|user-theme|windowsNavigator|workspace-indicator)
+ alternate-tab|alternative-status-menu|apps-menu|auto-move-windows|default-min-max|drive-menu|example|native-window-placement|places-menu|user-theme|windowsNavigator|workspace-indicator)
ENABLED_EXTENSIONS="$ENABLED_EXTENSIONS $e"
;;
*)
@@ -75,6 +75,7 @@ AC_SUBST(ENABLED_EXTENSIONS, [$ENABLED_EXTENSIONS])
dnl Please keep this sorted alphabetically
AC_CONFIG_FILES([
data/Makefile
+ extensions/alternate-tab/Makefile
extensions/alternative-status-menu/Makefile
extensions/apps-menu/Makefile
extensions/auto-move-windows/Makefile
diff --git a/extensions/alternate-tab/Makefile.am b/extensions/alternate-tab/Makefile.am
new file mode 100644
index 0000000..1f35392
--- /dev/null
+++ b/extensions/alternate-tab/Makefile.am
@@ -0,0 +1,6 @@
+EXTENSION_ID = alternate-tab
+
+EXTRA_MODULES = prefs.js
+
+include ../../extension.mk
+include ../../settings.mk
diff --git a/extensions/alternate-tab/extension.js b/extensions/alternate-tab/extension.js
new file mode 100644
index 0000000..bfd3015
--- /dev/null
+++ b/extensions/alternate-tab/extension.js
@@ -0,0 +1,448 @@
+/* -*- mode: js; js-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 ExtensionUtils = imports.misc.extensionUtils;
+const Me = ExtensionUtils.getCurrentExtension();
+const Convenience = Me.imports.convenience;
+
+let settings;
+
+const AppIconMode = {
+ THUMBNAIL_ONLY: 1,
+ APP_ICON_ONLY: 2,
+ BOTH: 3,
+};
+
+const SETTINGS_APP_ICON_MODE = 'app-icon-mode';
+const SETTINGS_CURRENT_WORKSPACE_ONLY = 'current-workspace-only';
+
+function mod(a, b) {
+ return ((a+b) % b);
+}
+
+const AltTabPopup = new Lang.Class({
+ Name: 'AlternateTab.AltTabPopup',
+
+ _init : function(settings) {
+ this._settings = settings;
+
+ this.actor = new Shell.GenericContainer({ name: 'altTabPopup',
+ reactive: true });
+
+ this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
+ this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
+ this.actor.connect('allocate', Lang.bind(this, this._allocate));
+
+ this._haveModal = false;
+
+ this._currentWindow = 0;
+ this._motionTimeoutId = 0;
+ this._initialDelayTimeoutId = 0;
+
+ // Initially disable hover so we ignore the enter-event if
+ // the switcher appears underneath the current pointer location
+ this._disableHover();
+
+ Main.uiGroup.add_actor(this.actor);
+ },
+
+ _getPreferredWidth: function (actor, forHeight, alloc) {
+ alloc.min_size = global.screen_width;
+ alloc.natural_size = global.screen_width;
+ },
+
+ _getPreferredHeight: function (actor, forWidth, alloc) {
+ alloc.min_size = global.screen_height;
+ alloc.natural_size = global.screen_height;
+ },
+
+ _allocate: function (actor, box, flags) {
+ let childBox = new Clutter.ActorBox();
+ let primary = Main.layoutManager.primaryMonitor;
+
+ let leftPadding = this.actor.get_theme_node().get_padding(St.Side.LEFT);
+ let rightPadding = this.actor.get_theme_node().get_padding(St.Side.RIGHT);
+ let bottomPadding = this.actor.get_theme_node().get_padding(St.Side.BOTTOM);
+ let vPadding = this.actor.get_theme_node().get_vertical_padding();
+ let hPadding = leftPadding + rightPadding;
+
+ // Allocate the appSwitcher
+ // We select a size based on an icon size that does not overflow the screen
+ let [childMinHeight, childNaturalHeight] = this._appSwitcher.actor.get_preferred_height(primary.width - hPadding);
+ let [childMinWidth, childNaturalWidth] = this._appSwitcher.actor.get_preferred_width(childNaturalHeight);
+ childBox.x1 = Math.max(primary.x + leftPadding, primary.x + Math.floor((primary.width - childNaturalWidth) / 2));
+ childBox.x2 = Math.min(primary.x + primary.width - rightPadding, childBox.x1 + childNaturalWidth);
+ childBox.y1 = primary.y + Math.floor((primary.height - childNaturalHeight) / 2);
+ childBox.y2 = childBox.y1 + childNaturalHeight;
+ this._appSwitcher.actor.allocate(childBox, flags);
+ },
+
+ show : function(backward, binding, mask) {
+ let windows;
+
+ if (!settings.get_boolean(SETTINGS_CURRENT_WORKSPACE_ONLY)) {
+ // This is roughly what meta_display_get_tab_list does, except
+ // that it doesn't filter on workspace
+ // See in particular src/core/window-private.h for the filters
+ windows = global.get_window_actors().map(function(actor) {
+ return actor.meta_window;
+ }).filter(function(win) {
+ return !win.is_override_redirect() &&
+ win.get_window_type() != Meta.WindowType.DESKTOP &&
+ win.get_window_type() != Meta.WindowType.DOCK;
+ }).sort(function(one, two) {
+ return two.get_user_time() - one.get_user_time();
+ });
+ } else {
+ windows = global.display.get_tab_list(Meta.TabList.NORMAL_ALL, global.screen,
+ global.screen.get_active_workspace());
+ }
+
+ // Filter away attached modal dialogs (switch to their parents instead)
+ windows = windows.filter(function(win) { return !win.is_attached_dialog(); });
+
+ if (windows.length == 0)
+ return false;
+
+ if (!Main.pushModal(this.actor)) {
+ // Probably someone else has a pointer grab, try again with keyboard only
+ if (!Main.pushModal(this.actor, global.get_current_time(), Meta.ModalOptions.POINTER_ALREADY_GRABBED)) {
+ return false;
+ }
+ }
+ this._haveModal = true;
+ this._modifierMask = AltTab.primaryModifier(mask);
+
+ this.actor.connect('key-press-event', Lang.bind(this, this._keyPressEvent));
+ this.actor.connect('key-release-event', Lang.bind(this, this._keyReleaseEvent));
+
+ this.actor.connect('button-press-event', Lang.bind(this, this._clickedOutside));
+ this.actor.connect('scroll-event', Lang.bind(this, this._onScroll));
+
+ this._appSwitcher = new WindowList(windows, this._settings);
+ this.actor.add_actor(this._appSwitcher.actor);
+ this._appSwitcher.connect('item-activated', Lang.bind(this, this._windowActivated));
+ this._appSwitcher.connect('item-entered', Lang.bind(this, this._windowEntered));
+
+ // make the initial selection
+ this._currentWindow = 0;
+ if (backward)
+ this._select(this._previousWindow());
+ else
+ this._select(this._nextWindow());
+
+ this.actor.opacity = 0;
+ this.actor.show();
+
+ // There's a race condition; if the user released Alt before
+ // we got the grab, then we won't be notified. (See
+ // https://bugzilla.gnome.org/show_bug.cgi?id=596695 for
+ // details.) So we check now. (Have to do this after updating
+ // selection.)
+ let [x, y, mods] = global.get_pointer();
+ if (!(mods & this._modifierMask)) {
+ this._finish();
+ return false;
+ }
+
+ // We delay showing the popup so that fast Alt+Tab users aren't
+ // disturbed by the popup briefly flashing.
+ this._initialDelayTimeoutId = Mainloop.timeout_add(AltTab.POPUP_DELAY_TIMEOUT,
+ Lang.bind(this, function () {
+ this.actor.opacity = 255;
+ this._initialDelayTimeoutId = 0;
+ }));
+
+ return true
+ },
+
+ _windowActivated : function(thumbnailList, n) {
+ let win = this._appSwitcher.windows[n];
+ Main.activateWindow(win);
+ this.destroy();
+ },
+
+ _finish : function() {
+ let win = this._appSwitcher.windows[this._currentWindow];
+ Main.activateWindow(win);
+ this.destroy();
+ },
+
+ _keyPressEvent : function(actor, event) {
+ let keysym = event.get_key_symbol();
+ let event_state = event.get_state();
+ let backwards = event_state & Clutter.ModifierType.SHIFT_MASK;
+ let action = global.display.get_keybinding_action(event.get_key_code(), event_state);
+
+ this._disableHover();
+
+ if (keysym == Clutter.Escape) {
+ this.destroy();
+ } else if (action == Meta.KeyBindingAction.SWITCH_WINDOWS ||
+ action == Meta.KeyBindingAction.SWITCH_GROUP) {
+ this._select(backwards ? this._previousWindow() : this._nextWindow());
+ } else if (action == Meta.KeyBindingAction.SWITCH_WINDOWS_BACKWARD ||
+ action == Meta.KeyBindingAction.SWITCH_GROUP_BACKWARD) {
+ this._select(this._previousWindow());
+ } else {
+ if (keysym == Clutter.Left)
+ this._select(this._previousWindow());
+ else if (keysym == Clutter.Right)
+ this._select(this._nextWindow());
+ }
+
+ return true;
+ },
+
+ _keyReleaseEvent : function(actor, event) {
+ let [x, y, mods] = global.get_pointer();
+ let state = mods & this._modifierMask;
+
+ if (state == 0)
+ this._finish();
+
+ return true;
+ },
+
+ _onScroll : function(actor, event) {
+ let direction = event.get_scroll_direction();
+ if (direction == Clutter.ScrollDirection.UP)
+ this._select(this._previousWindow());
+ else if (direction == Clutter.ScrollDirection.DOWN)
+ this._select(this._nextWindow());
+
+ return true;
+ },
+
+ _clickedOutside : function(actor, event) {
+ this.destroy();
+ },
+
+ _windowEntered : function(windowSwitcher, n) {
+ if (!this._mouseActive)
+ return;
+
+ this._select(n);
+ },
+
+ _disableHover : function() {
+ this._mouseActive = false;
+
+ if (this._motionTimeoutId != 0)
+ Mainloop.source_remove(this._motionTimeoutId);
+
+ this._motionTimeoutId = Mainloop.timeout_add(AltTab.DISABLE_HOVER_TIMEOUT, Lang.bind(this, this._mouseTimedOut));
+ },
+
+ _mouseTimedOut : function() {
+ this._motionTimeoutId = 0;
+ this._mouseActive = true;
+ },
+
+ _popModal: function() {
+ if (this._haveModal) {
+ Main.popModal(this.actor);
+ this._haveModal = false;
+ }
+ },
+
+ destroy : function() {
+ this._popModal();
+ if (this.actor.visible) {
+ Tweener.addTween(this.actor,
+ { opacity: 0,
+ time: AltTab.POPUP_FADE_OUT_TIME,
+ transition: 'easeOutQuad',
+ onComplete: Lang.bind(this, this._finishDestroy),
+ });
+ } else
+ this._finishDestroy();
+ },
+
+ _finishDestroy : function() {
+ if (this._motionTimeoutId != 0) {
+ Mainloop.source_remove(this._motionTimeoutId);
+ this._motionTimeoutId = 0;
+ }
+
+ if (this._initialDelayTimeoutId != 0) {
+ Mainloop.source_remove(this._initialDelayTimeoutId);
+ this._initialDelayTimeoutId = 0;
+ }
+
+ this.actor.destroy();
+ },
+
+ _select : function(window) {
+ this._currentWindow = window;
+ this._appSwitcher.highlight(window);
+ },
+
+ _nextWindow: function() {
+ return mod(this._currentWindow + 1, this._appSwitcher.windows.length);
+ },
+
+ _previousWindow: function() {
+ return mod(this._currentWindow - 1, this._appSwitcher.windows.length);
+ },
+});
+
+const WindowIcon = new Lang.Class({
+ Name: 'AlternateTab.WindowIcon',
+
+ _init: function(window, settings) {
+ this.window = window;
+ this._settings = settings;
+
+ this.actor = new St.BoxLayout({ style_class: 'alt-tab-app',
+ vertical: true });
+ this.icon = null;
+ this._iconBin = new St.Widget({ layout_manager: new Clutter.BinLayout() });
+
+ this.actor.add(this._iconBin, { x_fill: false, y_fill: false } );
+ this.label = new St.Label({ text: window.get_title() });
+ this.actor.add(this.label, { x_fill: false });
+
+ let tracker = Shell.WindowTracker.get_default();
+ this.app = tracker.get_window_app(window);
+
+ let mutterWindow = this.window.get_compositor_private();
+ let windowTexture = mutterWindow.get_texture();
+ let [width, height] = windowTexture.get_size();
+ let scale, size;
+
+ this._iconBin.destroy_all_children();
+
+ switch (this._settings.get_enum(SETTINGS_APP_ICON_MODE)) {
+ case AppIconMode.THUMBNAIL_ONLY:
+ scale = Math.min(1.0, 128 / width, 128 / height);
+ size = 128;
+ this.clone = new Clutter.Clone({ source: windowTexture,
+ width: width * scale,
+ height: height * scale,
+ x_align: Clutter.ActorAlign.CENTER,
+ y_align: Clutter.ActorAlign.CENTER,
+ // usual hack for the usual bug in ClutterBinLayout...
+ x_expand: true,
+ y_expand: true });
+ this._iconBin.add_actor(this.clone);
+ break;
+
+ case AppIconMode.BOTH:
+ scale = Math.min(1.0, 128 / width, 128 / height);
+ size = 128;
+ this.clone = new Clutter.Clone({ source: windowTexture,
+ width: width * scale,
+ height: height * scale,
+ x_align: Clutter.ActorAlign.CENTER,
+ y_align: Clutter.ActorAlign.CENTER,
+ // usual hack for the usual bug in ClutterBinLayout...
+ x_expand: true,
+ y_expand: true });
+ this._iconBin.add_actor(this.clone);
+
+ if (this.app) {
+ this.appIcon = this.app.create_icon_texture(size / 2);
+ this.appIcon.x_expand = this.appIcon.y_expand = true;
+ this.appIcon.x_align = Clutter.ActorAlign.END;
+ this.appIcon.y_align = Clutter.ActorAlign.END;
+ this._iconBin.add_actor(this.appIcon);
+ }
+ break;
+
+ case AppIconMode.APP_ICON_ONLY:
+ size = 96;
+ if (this.app) {
+ this.appIcon = this.app.create_icon_texture(size);
+ this.appIcon.x_expand = this.appIcon.y_expand = true;
+ } else {
+ this.appIcon = new St.Icon({ icon_name: 'icon-missing',
+ icon_size: size,
+ x_expand: true,
+ y_expand: true });
+ }
+ this._iconBin.add_actor(this.appIcon);
+ }
+
+ this._iconBin.set_size(size, size);
+ }
+});
+
+const WindowList = new Lang.Class({
+ Name: 'AlternateTab.WindowList',
+ Extends: AltTab.SwitcherList,
+
+ _init : function(windows, settings) {
+ this.parent(true);
+
+ this.windows = windows;
+ this.icons = [];
+
+ for (let i = 0; i < windows.length; i++) {
+ let win = windows[i];
+ let icon = new WindowIcon(win, settings);
+
+ this.addItem(icon.actor, icon.label);
+ this.icons.push(icon);
+ }
+ }
+});
+
+function doAltTab(display, screen, window, binding) {
+ if (Main.wm._workspaceSwitcherPopup)
+ Main.wm._workspaceSwitcherPopup.actor.hide();
+
+ let modifiers = binding.get_modifiers()
+ let backwards = modifiers & Meta.VirtualModifier.SHIFT_MASK;
+
+ let popup = new AltTabPopup(settings);
+ if (!popup.show(backwards, binding.get_name(), binding.get_mask()))
+ popup.destroy();
+}
+
+function init(metadata) {
+ Convenience.initTranslations();
+ settings = Convenience.getSettings();
+}
+
+function setKeybinding(name, func) {
+ Main.wm.setCustomKeybindingHandler(name, Main.KeybindingMode.NORMAL, func);
+}
+
+function enable() {
+ setKeybinding('switch-windows', doAltTab);
+ setKeybinding('switch-group', doAltTab);
+ setKeybinding('switch-windows-backward', doAltTab);
+ setKeybinding('switch-group-backward', doAltTab);
+}
+
+function disable() {
+ setKeybinding('switch-windows', Lang.bind(Main.wm, Main.wm._startAppSwitcher));
+ setKeybinding('switch-group', Lang.bind(Main.wm, Main.wm._startAppSwitcher));
+ setKeybinding('switch-windows-backward', Lang.bind(Main.wm, Main.wm._startAppSwitcher));
+ setKeybinding('switch-group-backward', Lang.bind(Main.wm, Main.wm._startAppSwitcher));
+}
diff --git a/extensions/alternate-tab/metadata.json.in b/extensions/alternate-tab/metadata.json.in
new file mode 100644
index 0000000..4d2f63e
--- /dev/null
+++ b/extensions/alternate-tab/metadata.json.in
@@ -0,0 +1,11 @@
+{
+"extension-id": "@extension_id@",
+"uuid": "@uuid@",
+"settings-schema": "@gschemaname@",
+"gettext-domain": "@gettext_domain@",
+"name": "AlternateTab",
+"description": "A replacement for Alt-Tab, allows to cycle between windows and does not group by application",
+"original-authors": [ "jw bargsten org", "thomas bouffon gmail com" ],
+"shell-version": [ "@shell_current@" ],
+"url": "@url@"
+}
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
new file mode 100644
index 0000000..88ac798
--- /dev/null
+++ b/extensions/alternate-tab/org.gnome.shell.extensions.alternate-tab.gschema.xml.in
@@ -0,0 +1,26 @@
+<schemalist gettext-domain="gnome-shell-extensions">
+ <enum id="org.gnome.shell.extensions.alternate-tab.AppIconMode">
+ <value value="1" nick="thumbnail_only"/>
+ <value value="2" nick="app_icon_only"/>
+ <value value="3" nick="both"/>
+ </enum>
+ <schema id="org.gnome.shell.extensions.alternate-tab" path="/org/gnome/shell/extensions/alternate-tab/">
+ <key name="app-icon-mode" enum="org.gnome.shell.extensions.alternate-tab.AppIconMode">
+ <default>'both'</default>
+ <_summary>The application icon mode.</_summary>
+ <_description>
+ Configures how the windows are shown in the switcher. Valid possibilities
+ are 'thumbnail-only' (shows a thumbnail of the window), 'app-icon-only'
+ (shows only the application icon) or 'both'.
+ </_description>
+ </key>
+ <key type="b" name="current-workspace-only">
+ <default>false</default>
+ <summary>Limit switcher to current workspace.</summary>
+ <description>
+ If true, only windows from the current workspace are shown in the switcher.
+ Otherwise, all windows are included.
+ </description>
+ </key>
+ </schema>
+</schemalist>
diff --git a/extensions/alternate-tab/prefs.js b/extensions/alternate-tab/prefs.js
new file mode 100644
index 0000000..6f1856b
--- /dev/null
+++ b/extensions/alternate-tab/prefs.js
@@ -0,0 +1,84 @@
+/* -*- 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_APP_ICON_MODE = 'app-icon-mode';
+const SETTINGS_CURRENT_WORKSPACE_ONLY = 'current-workspace-only';
+
+const MODES = {
+ thumbnail_only: N_("Thumbnail only"),
+ app_icon_only: N_("Application icon only"),
+ both: N_("Thumbnail and application icon"),
+};
+
+const AltTabSettingsWidget = new GObject.Class({
+ Name: 'AlternateTab.Prefs.AltTabSettingsWidget',
+ GTypeName: 'AltTabSettingsWidget',
+ Extends: Gtk.Grid,
+
+ _init : function(params) {
+ this.parent(params);
+ this.margin = 10;
+ this.orientation = Gtk.Orientation.VERTICAL;
+
+ this._settings = Convenience.getSettings();
+
+ let presentLabel = _("Present windows as");
+ this.add(new Gtk.Label({ label: presentLabel, sensitive: true,
+ margin_bottom: 10, margin_top: 5 }));
+
+ let top = 1;
+ let radio = null;
+ let currentMode = this._settings.get_string(SETTINGS_APP_ICON_MODE);
+ 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 name = Gettext.gettext(MODES[mode]);
+
+ 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_APP_ICON_MODE, modeCapture);
+ }));
+ this.add(radio);
+
+ if (mode == currentMode)
+ radio.active = true;
+ top += 1;
+ }
+
+ let check = new Gtk.CheckButton({ label: _("Show only windows in the current workspace"),
+ margin_top: 12 });
+ this._settings.bind(SETTINGS_CURRENT_WORKSPACE_ONLY, check, 'active', Gio.SettingsBindFlags.DEFAULT);
+ this.add(check);
+ },
+});
+
+function init() {
+ Convenience.initTranslations();
+}
+
+function buildPrefsWidget() {
+ let widget = new AltTabSettingsWidget();
+ widget.show_all();
+
+ return widget;
+}
diff --git a/extensions/alternate-tab/stylesheet.css b/extensions/alternate-tab/stylesheet.css
new file mode 100644
index 0000000..25134b6
--- /dev/null
+++ b/extensions/alternate-tab/stylesheet.css
@@ -0,0 +1 @@
+/* This extensions requires no special styling */
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 2db1d80..01b6d6d 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,6 +1,9 @@
data/gnome-classic.desktop.in
data/gnome-classic.session.desktop.in.in
data/gnome-shell-classic.desktop.in.in
+extensions/alternate-tab/extension.js
+extensions/alternate-tab/org.gnome.shell.extensions.alternate-tab.gschema.xml.in
+extensions/alternate-tab/prefs.js
extensions/alternative-status-menu/extension.js
extensions/alternative-status-menu/org.gnome.shell.extensions.alternative-status-menu.gschema.xml.in
extensions/apps-menu/extension.js
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]