From b35dfc8914e5152ed4b85ba286312dd3afc6cacb Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Thu, 8 Jun 2017 16:49:20 +0200 Subject: [PATCH] windowManager: Add a switcher for mutter's switch-monitor keybinding https://bugzilla.gnome.org/show_bug.cgi?id=783550 --- js/js-resources.gresource.xml | 1 + js/ui/switchMonitor.js | 101 ++++++++++++++++++++++++++++++++++ js/ui/windowManager.js | 8 +++ po/POTFILES.in | 1 + 4 files changed, 111 insertions(+) create mode 100644 js/ui/switchMonitor.js diff --git a/js/js-resources.gresource.xml b/js/js-resources.gresource.xml index 79a200e91..c9ffb4d34 100644 --- a/js/js-resources.gresource.xml +++ b/js/js-resources.gresource.xml @@ -95,6 +95,7 @@ ui/shellMountOperation.js ui/slider.js ui/switcherPopup.js + ui/switchMonitor.js ui/tweener.js ui/unlockDialog.js ui/userWidget.js diff --git a/js/ui/switchMonitor.js b/js/ui/switchMonitor.js new file mode 100644 index 000000000..0a05d4360 --- /dev/null +++ b/js/ui/switchMonitor.js @@ -0,0 +1,101 @@ +// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- + +const Clutter = imports.gi.Clutter; +const Lang = imports.lang; +const Meta = imports.gi.Meta; +const St = imports.gi.St; + +const SwitcherPopup = imports.ui.switcherPopup; + +var APP_ICON_SIZE = 96; + +var SwitchMonitorPopup = new Lang.Class({ + Name: 'SwitchMonitorPopup', + Extends: SwitcherPopup.SwitcherPopup, + + _init: function() { + let items = [{ icon: 'view-mirror-symbolic', + /* Translators: this is for display mirroring i.e. cloning. + * Try to keep it under around 15 characters. + */ + label: _('Mirror') }, + { icon: 'video-joined-displays-symbolic', + /* Translators: this is for the desktop spanning displays. + * Try to keep it under around 15 characters. + */ + label: _('Join Displays') }, + { icon: 'video-single-display-symbolic', + /* Translators: this is for using only an external display. + * Try to keep it under around 15 characters. + */ + label: _('External Only') }, + { icon: 'computer-symbolic', + /* Translators: this is for using only the laptop display. + * Try to keep it under around 15 characters. + */ + label: _('Built-in Only') }]; + + this.parent(items); + + this._switcherList = new SwitchMonitorSwitcher(items); + }, + + show: function(backward, binding, mask) { + if (!Meta.MonitorManager.get().can_switch_config()) + return false; + + return this.parent(backward, binding, mask); + }, + + _initialSelection: function() { + let currentConfig = Meta.MonitorManager.get().get_switch_config(); + currentConfig %= Meta.MonitorSwitchConfigType.UNKNOWN; + this._select(currentConfig); + }, + + _keyPressHandler: function(keysym, action) { + if (action == Meta.KeyBindingAction.SWITCH_MONITOR) + this._select(this._next()); + else if (keysym == Clutter.Left) + this._select(this._previous()); + else if (keysym == Clutter.Right) + this._select(this._next()); + else + return Clutter.EVENT_PROPAGATE; + + return Clutter.EVENT_STOP; + }, + + _finish : function() { + this.parent(); + + Meta.MonitorManager.get().switch_config(this._selectedIndex); + }, +}); + +var SwitchMonitorSwitcher = new Lang.Class({ + Name: 'SwitchMonitorSwitcher', + Extends: SwitcherPopup.SwitcherList, + + _init: function(items) { + this.parent(true); + + for (let i = 0; i < items.length; i++) + this._addIcon(items[i]); + }, + + _addIcon: function(item) { + let box = new St.BoxLayout({ style_class: 'alt-tab-app', + vertical: true }); + + let icon = new St.Icon({ icon_name: item.icon, + icon_size: APP_ICON_SIZE }); + box.add(icon, { x_fill: false, y_fill: false } ); + + let text = new St.Label({ text: item.label }); + box.add(text, { x_fill: false }); + + this.addItem(box, text); + } +}); + diff --git a/js/ui/windowManager.js b/js/ui/windowManager.js index 04599b7b5..16e55fbe9 100644 --- a/js/ui/windowManager.js +++ b/js/ui/windowManager.js @@ -22,6 +22,7 @@ const WindowMenu = imports.ui.windowMenu; const PadOsd = imports.ui.padOsd; const EdgeDragAction = imports.ui.edgeDragAction; const CloseDialog = imports.ui.closeDialog; +const SwitchMonitor = imports.ui.switchMonitor; const SHELL_KEYBINDINGS_SCHEMA = 'org.gnome.shell.keybindings'; var MINIMIZE_WINDOW_ANIMATION_TIME = 0.2; @@ -898,6 +899,10 @@ var WindowManager = new Lang.Class({ Shell.ActionMode.UNLOCK_SCREEN | Shell.ActionMode.LOGIN_SCREEN, Lang.bind(this, this._startA11ySwitcher)); + this.setCustomKeybindingHandler('switch-monitor', + Shell.ActionMode.NORMAL | + Shell.ActionMode.OVERVIEW, + Lang.bind(this, this._startSwitcher)); this.addKeybinding('pause-resume-tweens', new Gio.Settings({ schema_id: SHELL_KEYBINDINGS_SCHEMA }), @@ -1838,6 +1843,9 @@ var WindowManager = new Lang.Class({ case 'cycle-group-backward': constructor = AltTab.GroupCyclerPopup; break; + case 'switch-monitor': + constructor = SwitchMonitor.SwitchMonitorPopup; + break; } if (!constructor) diff --git a/po/POTFILES.in b/po/POTFILES.in index d564cb00c..fe31315b7 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -59,6 +59,7 @@ js/ui/status/power.js js/ui/status/rfkill.js js/ui/status/system.js js/ui/status/volume.js +js/ui/switchMonitor.js js/ui/unlockDialog.js js/ui/viewSelector.js js/ui/windowAttentionHandler.js