From c7fae8e42c92f7ca98ae1a7bc43878e20b934bfb Mon Sep 17 00:00:00 2001 From: Jack Wickham Date: Sat, 1 Jul 2017 15:25:26 +0100 Subject: [PATCH 1/3] Add middle click to close on window previews --- windowPreview.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/windowPreview.js b/windowPreview.js index 80b65d7..315342c 100644 --- a/windowPreview.js +++ b/windowPreview.js @@ -750,6 +750,17 @@ const thumbnailPreview = new Lang.Class({ })); } } + }, + + _onButtonReleaseEvent: function(actor, event) { + this.actor.remove_style_pseudo_class ('active'); + if (event.get_button() == 2) { + // Middle click + this._closeWindow(); + } else { + this.activate(event); + } + return Clutter.EVENT_STOP; } }); From 9860a9f9dfce86736729a90ae88301fac30dddea Mon Sep 17 00:00:00 2001 From: Jack Wickham Date: Sat, 1 Jul 2017 19:02:17 +0100 Subject: [PATCH 2/3] Added window context menu on right click of preview --- windowPreview.js | 98 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 93 insertions(+), 5 deletions(-) diff --git a/windowPreview.js b/windowPreview.js index 315342c..c3dcdd8 100644 --- a/windowPreview.js +++ b/windowPreview.js @@ -22,6 +22,7 @@ */ +const BoxPointer = imports.ui.boxpointer; const Clutter = imports.gi.Clutter; const GLib = imports.gi.GLib; const Gtk = imports.gi.Gtk; @@ -30,9 +31,12 @@ const Main = imports.ui.main; const Mainloop = imports.mainloop; const Meta = imports.gi.Meta; const PopupMenu = imports.ui.popupMenu; +const RemoteMenu = imports.ui.remoteMenu; const Signals = imports.signals; +const Shell = imports.gi.Shell; const St = imports.gi.St; const Tweener = imports.ui.tweener; +const WindowMenu = imports.ui.windowMenu; const Workspace = imports.ui.workspace; const Me = imports.misc.extensionUtils.getCurrentExtension(); @@ -530,6 +534,8 @@ const thumbnailPreview = new Lang.Class({ Lang.bind(this, this._onLeave)); this.actor.connect('motion-event', Lang.bind(this, this._onMotionEvent)); + + this._previewMenuPopupManager = new previewMenuPopupManager(window, this.actor); }, _onEnter: function(actor, event) { @@ -754,13 +760,31 @@ const thumbnailPreview = new Lang.Class({ _onButtonReleaseEvent: function(actor, event) { this.actor.remove_style_pseudo_class ('active'); - if (event.get_button() == 2) { - // Middle click - this._closeWindow(); - } else { - this.activate(event); + switch (event.get_button()) { + case 1: + // Left click + this.activate(event); + break; + case 2: + // Middle click + this._closeWindow(); + break; + case 3: + // Right click + this.showContextMenu(event); + break; } return Clutter.EVENT_STOP; + }, + + showContextMenu: function(event) { + let coords = event.get_coords(); + this._previewMenuPopupManager.showWindowMenuForWindow({ + x: coords[0], + y: coords[1], + width: 0, + height: 0 + }); } }); @@ -1025,3 +1049,67 @@ const thumbnailPreviewList = new Lang.Class({ return windowA.get_stable_sequence() > windowB.get_stable_sequence(); } }); + +const previewMenuPopup = new Lang.Class({ + Name: 'previewMenuPopup', + Extends: WindowMenu.WindowMenu, + + _init: function(window, sourceActor) { + this.parent(window, sourceActor); + + let side = Taskbar.getPosition(); + this._arrowSide = side; + this._boxPointer._arrowSide = side; + this._boxPointer._userArrowSide = side; + } + + // Otherwise, just let the parent do its thing? +}); + +const previewMenuPopupManager = new Lang.Class({ + Name: 'previewMenuPopupManagerTest', + + _init: function(window, source) { + this._manager = new PopupMenu.PopupMenuManager({ actor: Main.layoutManager.dummyCursor }); + + this._sourceActor = new St.Widget({ reactive: true, visible: false }); + this._sourceActor.connect('button-press-event', Lang.bind(this, + function() { + this._manager.activeMenu.toggle(); + })); + Main.uiGroup.add_actor(this._sourceActor); + + this.window = window; + }, + + showWindowMenuForWindow: function(rect) { + let menu = new previewMenuPopup(this.window, this._sourceActor); + let window = this.window; + + this._manager.addMenu(menu); + + menu.connect('activate', function() { + window.check_alive(global.get_current_time()); + }); + let destroyId = window.connect('unmanaged', + function() { + menu.close(); + }); + + this._sourceActor.set_size(Math.max(1, rect.width), Math.max(1, rect.height)); + this._sourceActor.set_position(rect.x, rect.y); + + this._sourceActor.show(); + + menu.open(BoxPointer.PopupAnimation.NONE); + menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false); + menu.connect('open-state-changed', Lang.bind(this, function(menu_, isOpen) { + if (isOpen) + return; + + this._sourceActor.hide(); + menu.destroy(); + window.disconnect(destroyId); + })); + } +}); \ No newline at end of file From d04015f71e47ddbd7ba9d9dcc5e1af4262d8fc47 Mon Sep 17 00:00:00 2001 From: Jack Wickham Date: Wed, 27 Sep 2017 17:44:44 +0100 Subject: [PATCH 3/3] Added setting for middle click to close --- Settings.ui | 64 +++++++++++++++++++ prefs.js | 5 ++ ...shell.extensions.dash-to-panel.gschema.xml | 5 ++ windowPreview.js | 4 +- 4 files changed, 77 insertions(+), 1 deletion(-) diff --git a/Settings.ui b/Settings.ui index c7baa2b..8bfb97c 100644 --- a/Settings.ui +++ b/Settings.ui @@ -1263,6 +1263,70 @@ + + + 100 + 80 + True + True + + + True + False + 12 + 12 + 12 + 12 + 32 + + + True + False + True + Middle click to close window + True + 0 + + + 0 + 0 + + + + + True + True + end + center + + + 1 + 0 + + + + + True + False + True + Middle click on the preview to close the window. + True + 40 + 0 + + + + 0 + 1 + 2 + + + + + + diff --git a/prefs.js b/prefs.js index ff4090d..679cf19 100644 --- a/prefs.js +++ b/prefs.js @@ -439,6 +439,10 @@ const Settings = new Lang.Class({ this._builder.get_object('listboxrow_peek_mode_opacity'), 'sensitive', Gio.SettingsBindFlags.DEFAULT); + this._settings.bind('preview-middle-click-close', + this._builder.get_object('preview_middle_click_close_switch'), + 'active', + Gio.SettingsBindFlags.DEFAULT); this._builder.get_object('enter_peek_mode_timeout_spinbutton').set_value(this._settings.get_int('enter-peek-mode-timeout')); @@ -463,6 +467,7 @@ const Settings = new Lang.Class({ this._builder.get_object('enter_peek_mode_timeout_spinbutton').set_value(this._settings.get_int('enter-peek-mode-timeout')); this._settings.set_value('peek-mode-opacity', this._settings.get_default_value('peek-mode-opacity')); this._builder.get_object('peek_mode_opacity_spinbutton').set_value(this._settings.get_int('peek-mode-opacity')); + this._settings.set_value('preview-middle-click-close', this._settings.get_default_value('preview-middle-click-close')); } else { // remove the settings box so it doesn't get destroyed; diff --git a/schemas/org.gnome.shell.extensions.dash-to-panel.gschema.xml b/schemas/org.gnome.shell.extensions.dash-to-panel.gschema.xml index b46f8f5..bbd1d47 100644 --- a/schemas/org.gnome.shell.extensions.dash-to-panel.gschema.xml +++ b/schemas/org.gnome.shell.extensions.dash-to-panel.gschema.xml @@ -225,6 +225,11 @@ Window peeking mode opacity All windows except for the peeked one have their opacity set to the same value. + + false + Middle click preview to close window + Middle click on the window preview to close that window + 0 Tray font size diff --git a/windowPreview.js b/windowPreview.js index c3dcdd8..83f98c1 100644 --- a/windowPreview.js +++ b/windowPreview.js @@ -767,7 +767,9 @@ const thumbnailPreview = new Lang.Class({ break; case 2: // Middle click - this._closeWindow(); + if (this._getTopMenu()._dtpSettings.get_boolean('preview-middle-click-close')) { + this._closeWindow(); + } break; case 3: // Right click