From d571e755e1fe81ff3a8439ba09269d22053f275e Mon Sep 17 00:00:00 2001 From: franglais125 Date: Thu, 13 Jul 2017 17:28:41 -0400 Subject: [PATCH 01/11] Move preview menus creation to its own function. This is in preparation for the previews on hover work. --- appIcons.js | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/appIcons.js b/appIcons.js index 53c633ec6..593f0a027 100644 --- a/appIcons.js +++ b/appIcons.js @@ -526,26 +526,28 @@ var MyAppIcon = new Lang.Class({ (!this._previewMenu || !this._previewMenu.isOpen); }, - _windowPreviews: function() { - if (!this._previewMenu) { - this._previewMenuManager = new PopupMenu.PopupMenuManager(this); + _createPreviewMenus: function() { + this._previewMenuManager = new PopupMenu.PopupMenuManager(this); - this._previewMenu = new WindowPreview.WindowPreviewMenu(this, this._dtdSettings); + this._previewMenu = new WindowPreview.WindowPreviewMenu(this, this._dtdSettings); - this._previewMenuManager.addMenu(this._previewMenu); + this._previewMenuManager.addMenu(this._previewMenu); + this._previewMenu.connect('open-state-changed', Lang.bind(this, function(menu, isPoppedUp) { + if (!isPoppedUp) + this._onMenuPoppedDown(); + })); - this._previewMenu.connect('open-state-changed', Lang.bind(this, function(menu, isPoppedUp) { - if (!isPoppedUp) - this._onMenuPoppedDown(); - })); - let id = Main.overview.connect('hiding', Lang.bind(this, function() { - this._previewMenu.close(); - })); - this._previewMenu.actor.connect('destroy', function() { - Main.overview.disconnect(id); - }); + let id = Main.overview.connect('hiding', Lang.bind(this, function() { + this._previewMenu.close(); + })); + this._previewMenu.actor.connect('destroy', function() { + Main.overview.disconnect(id); + }); + }, - } + _windowPreviews: function() { + if (!this._previewMenu) + this._createPreviewMenus(); if (this._previewMenu.isOpen) this._previewMenu.close(); From 3b46a7e0a870233747ae60f2c2e786e7cac9cd91 Mon Sep 17 00:00:00 2001 From: franglais125 Date: Thu, 13 Jul 2017 14:56:55 -0400 Subject: [PATCH 02/11] Previews on hover: add option to settings, prefs, schema. --- Settings.ui | 73 +++++++++++++++++++ prefs.js | 5 ++ ....shell.extensions.dash-to-dock.gschema.xml | 5 ++ 3 files changed, 83 insertions(+) diff --git a/Settings.ui b/Settings.ui index 2b164a8b8..a78c92fe5 100644 --- a/Settings.ui +++ b/Settings.ui @@ -1719,6 +1719,79 @@ 3 + + + True + False + 0 + in + + + True + False + none + + + True + True + + + True + False + 12 + 12 + 12 + 12 + 32 + + + True + False + True + 0 + Show window previews on mouse hover + + + 0 + 0 + + + + + True + False + 6 + + + True + True + end + center + + + + + 1 + 0 + 2 + + + + + + + + + + + + + + False + True + 4 + + 2 diff --git a/prefs.js b/prefs.js index d8d8b9418..9167dbd86 100644 --- a/prefs.js +++ b/prefs.js @@ -524,6 +524,11 @@ const Settings = new Lang.Class({ })); + this._settings.bind('show-previews-hover', + this._builder.get_object('preview_hover_switch'), + 'active', + Gio.SettingsBindFlags.DEFAULT); + // Appearance Panel this._settings.bind('apply-custom-theme', this._builder.get_object('customize_theme'), 'sensitive', Gio.SettingsBindFlags.INVERT_BOOLEAN | Gio.SettingsBindFlags.GET); diff --git a/schemas/org.gnome.shell.extensions.dash-to-dock.gschema.xml b/schemas/org.gnome.shell.extensions.dash-to-dock.gschema.xml index 765a397f1..a452bdbe2 100644 --- a/schemas/org.gnome.shell.extensions.dash-to-dock.gschema.xml +++ b/schemas/org.gnome.shell.extensions.dash-to-dock.gschema.xml @@ -536,5 +536,10 @@ Enable unity7 like glossy backlit items Emulate the unity7 backlit glossy items behaviour + + false + Show window previews on mouse hover + + From 25d375dbc50cc445bae352a17a87a7d02f6e3427 Mon Sep 17 00:00:00 2001 From: franglais125 Date: Thu, 13 Jul 2017 17:05:29 -0400 Subject: [PATCH 03/11] Previews on hover: enable basic functionality. Most of the functions are imported from dash-to-panel, and are adapted where appropriate. --- appIcons.js | 19 ++++++++ dash.js | 28 ++++++++++++ windowPreview.js | 114 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 161 insertions(+) diff --git a/appIcons.js b/appIcons.js index 593f0a027..145becc64 100644 --- a/appIcons.js +++ b/appIcons.js @@ -557,6 +557,25 @@ var MyAppIcon = new Lang.Class({ return false; }, + enableHover: function(appIcons) { + if (this._hoverIsEnabled) + return; + this._hoverIsEnabled = true; + + if (!this._previewMenu) + this._createPreviewMenus(); + + this._previewMenu.enableHover(); + }, + + disableHover: function() { + this._hoverIsEnabled = false; + + this._signalsHandler.removeWithLabel('preview-hover'); + if (this._previewMenu) + this._previewMenu.disableHover(); + }, + // Try to do the right thing when attempting to launch a new window of an app. In // particular, if the application doens't allow to launch a new window, activate // the existing window instead. diff --git a/dash.js b/dash.js index 4cf5aa2a5..c0d2c2677 100644 --- a/dash.js +++ b/dash.js @@ -304,6 +304,10 @@ var MyDash = new Lang.Class({ Main.overview, 'item-drag-cancelled', Lang.bind(this, this._onDragCancelled) + ], [ + this._dtdSettings, + 'changed::show-previews-hover', + Lang.bind(this, this._togglePreviewHover) ]); }, @@ -503,6 +507,27 @@ var MyDash = new Lang.Class({ return item; }, + _togglePreviewHover: function() { + if (this._dtdSettings.get_boolean('show-previews-hover')) + this._enableHover(); + else + this._disableHover(); + }, + + _enableHover: function() { + let appIcons = this.getAppIcons(); + appIcons.forEach(function (appIcon) { + appIcon.enableHover(appIcons); + }); + }, + + _disableHover: function() { + let appIcons = this.getAppIcons(); + appIcons.forEach(function (appIcon) { + appIcon.disableHover(); + }); + }, + /** * Return an array with the "proper" appIcons currently in the dash */ @@ -857,6 +882,9 @@ var MyDash = new Lang.Class({ // This will update the size, and the corresponding number for each icon this._updateNumberOverlay(); + + // Connect windows previews to hover events + this._togglePreviewHover(); }, _updateNumberOverlay: function() { diff --git a/windowPreview.js b/windowPreview.js index 09253b9b3..76245a777 100644 --- a/windowPreview.js +++ b/windowPreview.js @@ -23,6 +23,13 @@ const Utils = Me.imports.utils; const PREVIEW_MAX_WIDTH = 250; const PREVIEW_MAX_HEIGHT = 150; +/* + * Timeouts for the hovering events + */ +const HOVER_ENTER_TIMEOUT = 100; +const HOVER_LEAVE_TIMEOUT = 100; +const HOVER_MENU_LEAVE_TIMEOUT = 500; + const WindowPreviewMenu = new Lang.Class({ Name: 'WindowPreviewMenu', Extends: PopupMenu.PopupMenu, @@ -80,6 +87,8 @@ const WindowPreviewMenu = new Lang.Class({ }, destroy: function () { + this.disableHover(); + if (this._mappedId) this._source.actor.disconnect(this._mappedId); @@ -87,6 +96,111 @@ const WindowPreviewMenu = new Lang.Class({ this._source.actor.disconnect(this._destroyId); this.parent(); + }, + + enableHover: function() { + // Show window previews on mouse hover + this._enterSourceId = this._source.actor.connect('enter-event', Lang.bind(this, this._onEnter)); + this._leaveSourceId = this._source.actor.connect('leave-event', Lang.bind(this, this._onLeave)); + + this._enterMenuId = this.actor.connect('enter-event', Lang.bind(this, this._onMenuEnter)); + this._leaveMenuId = this.actor.connect('leave-event', Lang.bind(this, this._onMenuLeave)); + }, + + disableHover: function() { + if (this._enterSourceId) { + this._source.actor.disconnect(this._enterSourceId); + this._enterSourceId = 0; + } + if (this._leaveSourceId) { + this._source.actor.disconnect(this._leaveSourceId); + this._leaveSourceId = 0; + } + + if (this._enterMenuId) { + this.actor.disconnect(this._enterMenuId); + this._enterMenuId = 0; + } + if (this._leaveMenuId) { + this.actor.disconnect(this._leaveMenuId); + this._leaveMenuId = 0; + } + }, + + _onEnter: function () { + this.cancelOpen(); + this.cancelClose(); + + this._hoverOpenTimeoutId = Mainloop.timeout_add( + HOVER_ENTER_TIMEOUT, + Lang.bind(this, this.hoverOpen) + ); + }, + + _onLeave: function () { + this.cancelOpen(); + this.cancelClose(); + + // grabHelper.grab() is usually called when the menu is opened. However, there seems to be a bug in the + // underlying gnome-shell that causes all window contents to freeze if the grab and ungrab occur + // in quick succession in timeouts from the Mainloop (for example, clicking the icon as the preview window is opening) + // So, instead wait until the mouse is leaving the icon (and might be moving toward the open window) to trigger the grab + if (this.isOpen) { + this._source._previewMenuManager._grabHelper.grab({ + actor: this.actor, + focus: this.sourceActor, + }); + } + + this._hoverCloseTimeoutId = Mainloop.timeout_add( + HOVER_LEAVE_TIMEOUT, + Lang.bind(this, this.hoverClose) + ); + }, + + cancelOpen: function () { + if (this._hoverOpenTimeoutId) { + Mainloop.source_remove(this._hoverOpenTimeoutId); + this._hoverOpenTimeoutId = null; + } + }, + + cancelClose: function () { + if (this._hoverCloseTimeoutId) { + Mainloop.source_remove(this._hoverCloseTimeoutId); + this._hoverCloseTimeoutId = null; + } + + if (this._hoverUngrabTimeoutId) { + Mainloop.source_remove(this._hoverUngrabTimeoutId); + this._hoverUngrabTimeoutId = null; + } + }, + + hoverOpen: function () { + this._hoverOpenTimeoutId = null; + if (!this.isOpen) + this.popup(); + }, + + hoverClose: function () { + this._hoverCloseTimeoutId = null; + if (this.isOpen) + this.close(~0); + }, + + _onMenuEnter: function () { + this.cancelClose(); + }, + + _onMenuLeave: function () { + this.cancelOpen(); + this.cancelClose(); + + this._hoverCloseTimeoutId = Mainloop.timeout_add( + HOVER_MENU_LEAVE_TIMEOUT, + Lang.bind(this, this.hoverClose) + ); } }); From 709a9a814ee6c9c89fa3a062bd0fa5e3b6f8a8a1 Mon Sep 17 00:00:00 2001 From: franglais125 Date: Thu, 13 Jul 2017 17:08:31 -0400 Subject: [PATCH 04/11] Previews on hover: close the menu when activating with click. --- appIcons.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/appIcons.js b/appIcons.js index 145becc64..5ecdac4aa 100644 --- a/appIcons.js +++ b/appIcons.js @@ -327,6 +327,10 @@ var MyAppIcon = new Lang.Class({ this._menu.actor.style = ('max-height: ' + Math.round(workArea.height - additional_margin - verticalMargins) + 'px;' + 'max-width: 400px'); } + + // Close the window previews + if (this._previewMenu && this._previewMenu.isOpen) + this._previewMenu.close(~0); })); let id = Main.overview.connect('hiding', Lang.bind(this, function() { this._menu.close(); @@ -397,6 +401,8 @@ var MyAppIcon = new Lang.Class({ // This variable keeps track of this let shouldHideOverview = true; + let shouldClosePreview = true; + // We customize the action only when the application is already running if (appIsRunning) { switch (buttonAction) { @@ -470,8 +476,11 @@ var MyAppIcon = new Lang.Class({ if (windows.length == 1 && !modifiers && button == 1) { let w = windows[0]; Main.activateWindow(w); - } else + } + else { this._windowPreviews(); + shouldClosePreview = false; + } } else { this.app.activate(); @@ -515,6 +524,9 @@ var MyAppIcon = new Lang.Class({ this.launchNewWindow(); } + if (this._previewMenu && this._previewMenu.isOpen && shouldClosePreview) + this._previewMenu.hoverClose(~0); + // Hide overview except when action mode requires it if(shouldHideOverview) { Main.overview.hide(); From 9c12fe3529a965cddf1f813d6d4262a9ee08a692 Mon Sep 17 00:00:00 2001 From: franglais125 Date: Thu, 13 Jul 2017 17:31:59 -0400 Subject: [PATCH 05/11] Previews on hover: manually set keybord navigation. This is so that this is not triggered when hovering. --- appIcons.js | 7 +++++-- windowPreview.js | 1 - 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/appIcons.js b/appIcons.js index 5ecdac4aa..e75dea878 100644 --- a/appIcons.js +++ b/appIcons.js @@ -561,10 +561,13 @@ var MyAppIcon = new Lang.Class({ if (!this._previewMenu) this._createPreviewMenus(); - if (this._previewMenu.isOpen) + if (this._previewMenu.isOpen) { this._previewMenu.close(); - else + } + else { this._previewMenu.popup(); + this._previewMenu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false); + } return false; }, diff --git a/windowPreview.js b/windowPreview.js index 76245a777..5634bc8de 100644 --- a/windowPreview.js +++ b/windowPreview.js @@ -81,7 +81,6 @@ const WindowPreviewMenu = new Lang.Class({ if (windows.length > 0) { this._redisplay(); this.open(); - this.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false); this._source.emit('sync-tooltip'); } }, From 09f7aad235ec128bb1324338432f373b7b8af7e7 Mon Sep 17 00:00:00 2001 From: franglais125 Date: Thu, 13 Jul 2017 17:35:43 -0400 Subject: [PATCH 06/11] Previews on hover: better handling of menu-leave events. We add a timeout to ungrab the actor, and we manually trigger 'enter-event' for appIcons. When moving from the (open) menu to the dock, the grabHandler is still active, and hover notifications are not properly propagated. Idea imported from dash-to-panel and adapted. --- appIcons.js | 33 +++++++++++++++++++++++++++++++++ windowPreview.js | 11 +++-------- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/appIcons.js b/appIcons.js index e75dea878..38b779e16 100644 --- a/appIcons.js +++ b/appIcons.js @@ -61,6 +61,9 @@ let recentlyClickedAppWindows = null; let recentlyClickedAppIndex = 0; let recentlyClickedAppMonitor = -1; +// Icon list might change over time, so we keep a global variable +let appIconsHoverList = null; + /** * Extend AppIcon * @@ -573,6 +576,7 @@ var MyAppIcon = new Lang.Class({ }, enableHover: function(appIcons) { + appIconsHoverList = appIcons; if (this._hoverIsEnabled) return; this._hoverIsEnabled = true; @@ -580,6 +584,35 @@ var MyAppIcon = new Lang.Class({ if (!this._previewMenu) this._createPreviewMenus(); + this._signalsHandler.addWithLabel('preview-hover', [ + this._previewMenu, + 'menu-closed', + function(menu) { + // enter-event doesn't fire on an app icon when the popup menu from a previously + // hovered app icon is still open, so when a preview menu closes we need to + // see if a new app icon is hovered and open its preview menu now. + // also, for some reason actor doesn't report being hovered by get_hover() + // if the hover started when a popup was opened. So, look for the actor by mouse position. + let [x, y,] = global.get_pointer(); + let hoveredActor = global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE, x, y); + let appIconToOpen; + appIconsHoverList.forEach(function (appIcon) { + if(appIcon.actor == hoveredActor) { + appIconToOpen = appIcon; + } else if(appIcon._previewMenu && appIcon._previewMenu.isOpen) { + appIcon._previewMenu.close(); + } + }); + + if (appIconToOpen) { + appIconToOpen.actor.sync_hover(); + if (appIconToOpen._previewMenu && appIconToOpen._previewMenu != menu) + appIconToOpen._previewMenu._onEnter(); + } + return GLib.SOURCE_REMOVE; + } + ]); + this._previewMenu.enableHover(); }, diff --git a/windowPreview.js b/windowPreview.js index 5634bc8de..08c500b45 100644 --- a/windowPreview.js +++ b/windowPreview.js @@ -41,9 +41,6 @@ const WindowPreviewMenu = new Lang.Class({ this.parent(source.actor, 0.5, side); - // We want to keep the item hovered while the menu is up - this.blockSourceEvents = true; - this._source = source; this._app = this._source.app; let monitorIndex = this._source.monitorIndex; @@ -148,6 +145,9 @@ const WindowPreviewMenu = new Lang.Class({ this._source._previewMenuManager._grabHelper.grab({ actor: this.actor, focus: this.sourceActor, + onUngrab: Lang.bind(this, function() { + this.close(~0); + }) }); } @@ -169,11 +169,6 @@ const WindowPreviewMenu = new Lang.Class({ Mainloop.source_remove(this._hoverCloseTimeoutId); this._hoverCloseTimeoutId = null; } - - if (this._hoverUngrabTimeoutId) { - Mainloop.source_remove(this._hoverUngrabTimeoutId); - this._hoverUngrabTimeoutId = null; - } }, hoverOpen: function () { From 3cc0de6cd11823b9455d3326e0ce7ab387e8f96f Mon Sep 17 00:00:00 2001 From: franglais125 Date: Thu, 13 Jul 2017 17:40:20 -0400 Subject: [PATCH 07/11] Previews on hover: change the openStateChangeId behavior. We need to adapt the MenuManager behavior with respect to 'open-state-changed' handling. The behavior depends on whether the menu was opened on click or on hover. --- appIcons.js | 26 ++++++++++++++++++++++++++ windowPreview.js | 17 ++++++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/appIcons.js b/appIcons.js index 38b779e16..5676fc4e3 100644 --- a/appIcons.js +++ b/appIcons.js @@ -568,6 +568,7 @@ var MyAppIcon = new Lang.Class({ this._previewMenu.close(); } else { + this._previewMenu.fromHover = false; this._previewMenu.popup(); this._previewMenu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false); } @@ -613,6 +614,31 @@ var MyAppIcon = new Lang.Class({ } ]); + let windowPreviewMenuData = this._previewMenuManager._menus[this._previewMenuManager._findMenu(this._previewMenu)]; + this._previewMenu.disconnect(windowPreviewMenuData.openStateChangeId); + windowPreviewMenuData.openStateChangeId = this._previewMenu.connect( + 'open-state-changed', + Lang.bind(this._previewMenuManager, function(menu, open) { + if (menu.fromHover) { + if (open) { + if (this.activeMenu) + this.activeMenu.close(BoxPointer.PopupAnimation.FADE); + + // don't grab here, we are grabbing in onLeave in windowPreview.js + // this._grabHelper.grab({ + // actor: menu.actor, + // focus: menu.sourceActor, + // onUngrab: Lang.bind(this, this._closeMenu, menu) + // }); + } else { + this._grabHelper.ungrab({ actor: menu.actor }); + } + } + else + this._onMenuOpenState(menu, open); + }) + ); + this._previewMenu.enableHover(); }, diff --git a/windowPreview.js b/windowPreview.js index 08c500b45..a26f3c18c 100644 --- a/windowPreview.js +++ b/windowPreview.js @@ -66,6 +66,8 @@ const WindowPreviewMenu = new Lang.Class({ this._previewBox = new WindowPreviewList(this._source, this._dtdSettings); this.addMenuItem(this._previewBox); + + this.fromHover = false; }, _redisplay: function() { @@ -173,21 +175,34 @@ const WindowPreviewMenu = new Lang.Class({ hoverOpen: function () { this._hoverOpenTimeoutId = null; - if (!this.isOpen) + if (!this.isOpen) { + this.fromHover = true; this.popup(); + } }, hoverClose: function () { this._hoverCloseTimeoutId = null; + + if (!this.fromHover) + return; + if (this.isOpen) this.close(~0); + this.fromHover = false; }, _onMenuEnter: function () { + if (!this.fromHover) + return; + this.cancelClose(); }, _onMenuLeave: function () { + if (!this.fromHover) + return; + this.cancelOpen(); this.cancelClose(); From 1a2d5cc074a964016a1e1ebbcbe6671ed228be6f Mon Sep 17 00:00:00 2001 From: franglais125 Date: Wed, 19 Jul 2017 15:42:33 -0400 Subject: [PATCH 08/11] Previews on hover: fix autohide --- docking.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/docking.js b/docking.js index 2e0c2b4c9..719e575b9 100644 --- a/docking.js +++ b/docking.js @@ -366,6 +366,7 @@ const DockedDash = new Lang.Class({ // sync hover after a popupmenu is closed this.dash.connect('menu-closed', Lang.bind(this, function() { this._box.sync_hover(); + this._hoverChanged(); })); // Load optional features that need to be activated for one dock only @@ -684,7 +685,13 @@ const DockedDash = new Lang.Class({ }, _hoverChanged: function() { - if (!this._ignoreHover) { + let dontClose = false; + this.dash.getAppIcons().forEach(function(appIcon) { + if (appIcon._previewMenu && appIcon._previewMenu.isOpen) + dontClose = true; + }); + + if (!this._ignoreHover && !dontClose) { // Skip if dock is not in autohide mode for instance because it is shown // by intellihide. if (this._autohideIsEnabled) { From f481b79705ec9a4f3ab0975ca45cbeef640c6d65 Mon Sep 17 00:00:00 2001 From: franglais125 Date: Fri, 14 Jul 2017 12:37:44 -0400 Subject: [PATCH 09/11] Window previews: set max size based on monitor dimensions. --- appIcons.js | 9 +++++---- windowPreview.js | 18 ++++++++++-------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/appIcons.js b/appIcons.js index 5676fc4e3..d770ac55e 100644 --- a/appIcons.js +++ b/appIcons.js @@ -318,8 +318,7 @@ var MyAppIcon = new Lang.Class({ else { // Setting the max-height is s useful if part of the menu is // scrollable so the minimum height is smaller than the natural height. - let monitor_index = Main.layoutManager.findIndexForActor(this.actor); - let workArea = Main.layoutManager.getWorkAreaForMonitor(monitor_index); + let workArea = Main.layoutManager.getWorkAreaForMonitor(this.monitorIndex); let position = Utils.getPosition(this._dtdSettings); this._isHorizontal = ( position == St.Side.TOP || position == St.Side.BOTTOM); @@ -327,8 +326,10 @@ var MyAppIcon = new Lang.Class({ let additional_margin = this._isHorizontal && !this._dtdSettings.get_boolean('dock-fixed') ? Main.overview._dash.actor.height : 0; let verticalMargins = this._menu.actor.margin_top + this._menu.actor.margin_bottom; // Also set a max width to the menu, so long labels (long windows title) get truncated + let monitor = Main.layoutManager.monitors[this.monitorIndex]; + let max_width = Math.round(monitor.width / 3); this._menu.actor.style = ('max-height: ' + Math.round(workArea.height - additional_margin - verticalMargins) + 'px;' + - 'max-width: 400px'); + 'max-width: ' + max_width + 'px'); } // Close the window previews @@ -1049,7 +1050,7 @@ const MyAppIconMenu = new Lang.Class({ separatorShown = true; } - let item = new WindowPreview.WindowPreviewMenuItem(window); + let item = new WindowPreview.WindowPreviewMenuItem(window, this._source); this._allWindowsMenuItem.menu.addMenuItem(item); item.connect('activate', Lang.bind(this, function() { this.emit('activate-window', window); diff --git a/windowPreview.js b/windowPreview.js index a26f3c18c..f740dd622 100644 --- a/windowPreview.js +++ b/windowPreview.js @@ -20,9 +20,6 @@ const Workspace = imports.ui.workspace; const Me = imports.misc.extensionUtils.getCurrentExtension(); const Utils = Me.imports.utils; -const PREVIEW_MAX_WIDTH = 250; -const PREVIEW_MAX_HEIGHT = 150; - /* * Timeouts for the hovering events */ @@ -306,7 +303,7 @@ const WindowPreviewList = new Lang.Class({ }, _createPreviewItem: function(window) { - let preview = new WindowPreviewMenuItem(window); + let preview = new WindowPreviewMenuItem(window, this._source); return preview; }, @@ -488,7 +485,7 @@ const WindowPreviewMenuItem = new Lang.Class({ Name: 'WindowPreviewMenuItem', Extends: PopupMenu.PopupBaseMenuItem, - _init: function(window, params) { + _init: function(window, source, params) { this._window = window; this._destroyId = 0; this._windowAddedId = 0; @@ -498,8 +495,13 @@ const WindowPreviewMenuItem = new Lang.Class({ this.actor.remove_child(this._ornamentLabel); this.actor.add_style_class_name('dashtodock-app-well-preview-menu-item'); + let monitorIndex = source.monitorIndex; + let monitor = Main.layoutManager.monitors[monitorIndex]; + this._preview_max_width = Math.round(monitor.width / 5); + this._preview_max_height = Math.round(monitor.height / 5); + this._cloneBin = new St.Bin(); - this._cloneBin.set_size(PREVIEW_MAX_WIDTH, PREVIEW_MAX_HEIGHT); + this._cloneBin.set_size(this._preview_max_width, this._preview_max_height); // TODO: improve the way the closebutton is layout. Just use some padding // for the moment. @@ -521,7 +523,7 @@ const WindowPreviewMenuItem = new Lang.Class({ overlayGroup.add_actor(this.closeButton); let label = new St.Label({ text: window.get_title()}); - label.set_style('max-width: '+PREVIEW_MAX_WIDTH +'px'); + label.set_style('max-width: ' + this._preview_max_width + 'px'); let labelBin = new St.Bin({ child: label, x_align: St.Align.MIDDLE}); @@ -572,7 +574,7 @@ const WindowPreviewMenuItem = new Lang.Class({ let windowTexture = mutterWindow.get_texture(); let [width, height] = windowTexture.get_size(); - let scale = Math.min(1.0, PREVIEW_MAX_WIDTH/width, PREVIEW_MAX_HEIGHT/height); + let scale = Math.min(1.0, this._preview_max_width / width, this._preview_max_height / height); let clone = new Clutter.Clone ({ source: windowTexture, reactive: true, From 6d30a69e4169a8367a918a1431daf527e905f0dc Mon Sep 17 00:00:00 2001 From: franglais125 Date: Sat, 21 Oct 2017 15:49:28 -0400 Subject: [PATCH 10/11] windowPreview.js: use 'var' instead of 'const' for class. --- windowPreview.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/windowPreview.js b/windowPreview.js index f740dd622..f05364165 100644 --- a/windowPreview.js +++ b/windowPreview.js @@ -27,7 +27,7 @@ const HOVER_ENTER_TIMEOUT = 100; const HOVER_LEAVE_TIMEOUT = 100; const HOVER_MENU_LEAVE_TIMEOUT = 500; -const WindowPreviewMenu = new Lang.Class({ +var WindowPreviewMenu = new Lang.Class({ Name: 'WindowPreviewMenu', Extends: PopupMenu.PopupMenu, From 342034316caf33e91dcf91946eb997088a034ec0 Mon Sep 17 00:00:00 2001 From: franglais125 Date: Sun, 1 Apr 2018 23:34:28 -0400 Subject: [PATCH 11/11] Previews: ensure they don't come up if quickly opening the right-click menu. --- appIcons.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/appIcons.js b/appIcons.js index d770ac55e..75177aa5a 100644 --- a/appIcons.js +++ b/appIcons.js @@ -333,8 +333,11 @@ var MyAppIcon = new Lang.Class({ } // Close the window previews - if (this._previewMenu && this._previewMenu.isOpen) - this._previewMenu.close(~0); + if (this._previewMenu) { + this._previewMenu.cancelOpen(); + if (this._previewMenu.isOpen) + this._previewMenu.close(~0); + } })); let id = Main.overview.connect('hiding', Lang.bind(this, function() { this._menu.close();