From f8de74d9b7f89c82a07a083304422c90cef14285 Mon Sep 17 00:00:00 2001 From: fredcw <58893963+fredcw@users.noreply.github.com> Date: Sat, 28 Jun 2025 14:55:10 +0100 Subject: [PATCH] Keep panel usable over fullscreened window when... ...menu applet is opened by shortcut key until fullscreened window is refocused by user. remove force-show-panel option from menu@cinnamon.org --- .../applets/menu@cinnamon.org/applet.js | 4 - .../menu@cinnamon.org/settings-schema.json | 8 +- js/ui/panel.js | 107 ++++++++++-------- 3 files changed, 58 insertions(+), 61 deletions(-) diff --git a/files/usr/share/cinnamon/applets/menu@cinnamon.org/applet.js b/files/usr/share/cinnamon/applets/menu@cinnamon.org/applet.js index 0afcbaf73e..a9797557b6 100644 --- a/files/usr/share/cinnamon/applets/menu@cinnamon.org/applet.js +++ b/files/usr/share/cinnamon/applets/menu@cinnamon.org/applet.js @@ -1280,7 +1280,6 @@ class CinnamonMenuApplet extends Applet.TextIconApplet { this.settings.bind("search-filesystem", "searchFilesystem"); this.contextMenu = null; this.lastSelectedCategory = null; - this.settings.bind("force-show-panel", "forceShowPanel"); this.orderDirty = false; @@ -1323,9 +1322,6 @@ class CinnamonMenuApplet extends Applet.TextIconApplet { _updateKeybinding() { Main.keybindingManager.addHotKey("overlay-key-" + this.instance_id, this.overlayKey, Lang.bind(this, function() { if (!Main.overview.visible && !Main.expo.visible) { - if (this.forceShowPanel && !this.isOpen) { - this.panel.peekPanel(); - } this.menu.toggle_with_options(this.enableAnimation); } })); diff --git a/files/usr/share/cinnamon/applets/menu@cinnamon.org/settings-schema.json b/files/usr/share/cinnamon/applets/menu@cinnamon.org/settings-schema.json index 509ba08afa..2ec51f90d2 100644 --- a/files/usr/share/cinnamon/applets/menu@cinnamon.org/settings-schema.json +++ b/files/usr/share/cinnamon/applets/menu@cinnamon.org/settings-schema.json @@ -20,7 +20,7 @@ "panel-behave" : { "type" : "section", "title" : "Behavior", - "keys" : ["overlay-key", "activate-on-hover", "hover-delay", "force-show-panel", "enable-animation"] + "keys" : ["overlay-key", "activate-on-hover", "hover-delay", "enable-animation"] }, "menu-layout" : { "type" : "section", @@ -155,12 +155,6 @@ "description": "Enable filesystem path entry in search box", "tooltip": "Allows path entry in the menu search box." }, - "force-show-panel" : { - "type" : "switch", - "default" : true, - "description": "Force the panel to be visible when opening the menu", - "tooltip": "Opening the menu will also show the main panel (which may be auto-hidden)." - }, "activate-on-hover" : { "type" : "switch", "default" : false, diff --git a/js/ui/panel.js b/js/ui/panel.js index bf7d47d474..670354d050 100644 --- a/js/ui/panel.js +++ b/js/ui/panel.js @@ -39,8 +39,6 @@ const TIME_DELTA = 1500; const APPLETS_DROP_ANIMATION_TIME = 0.2; -const PANEL_PEEK_TIME = 1500; - const EDIT_MODE_MIN_BOX_SIZE = 25; const VALID_ICON_SIZE_VALUES = [-1, 0, 16, 22, 24, 32, 48]; @@ -2091,6 +2089,7 @@ Panel.prototype = { this._destroyed = false; this._positionChanged = false; this._monitorsChanged = false; + this._mouseEntered = null; this._signalManager = new SignalManager.SignalManager(null); this.height = 0; this.margin_top = 0; @@ -2103,7 +2102,6 @@ Panel.prototype = { this._bottomPanelBarrier = 0; this._shadowBox = null; this._panelZoneSizes = this._createEmptyZoneSizes(); - this._peeking = false; this.themeSettings = new Gio.Settings({ schema_id: 'org.cinnamon.theme' }); @@ -2373,24 +2371,8 @@ Panel.prototype = { return; }, - + /* deprecated */ peekPanel: function() { - if (!this._hidden || this._peeking) - return; - - if (this._showHideTimer > 0) { - Mainloop.source_remove(this._showHideTimer); - this._showHideTimer = 0; - } - - this._peeking = true; - this._showPanel(); - - Mainloop.timeout_add(PANEL_PEEK_TIME, () => { - this._peeking = false; - this._updatePanelVisibility(); - return false; - }); }, /** @@ -2973,7 +2955,7 @@ Panel.prototype = { if (this._positionChanged) { panelChanged = true; this._positionChanged = false; - this._hidden = false; + this._showPanel(); } // if the monitors changed, force update in case the position needs updating @@ -3667,6 +3649,8 @@ Panel.prototype = { for (let i = 0; i < global.menuStack.length; i++) { let menu = global.menuStack[i]; + if (menu.customStyleClass && menu.customStyleClass.includes("thumbnail")) + continue; if (menu.getPanel() === this.actor) { return true; } @@ -3685,7 +3669,8 @@ Panel.prototype = { * true = autohide, false = always show, intel = Intelligent */ _updatePanelVisibility: function() { - if (this._panelEditMode || this._peeking || this._panelHasOpenMenus()) + this._mouseEntered = this._mouseOnPanel(); + if (this._panelEditMode || this._highlighted || this._panelHasOpenMenus()) this._shouldShow = true; else { switch (this._autohideSettings) { @@ -3742,6 +3727,20 @@ Panel.prototype = { } // end of switch on autohidesettings } + const focusedWindow = global.display.get_focus_window(); + if (focusedWindow && focusedWindow.is_fullscreen() && focusedWindow.get_monitor() === this.monitorIndex + && this._panelHasOpenMenus()) { + // An applet has been opened by shortcut key over a fullscreened window so remove + // focus from fullscreened window so that chrome remains visible until fullscreened + // window is focused again by user. + this._focusDesktop(); + } else if (focusedWindow && focusedWindow.get_monitor() !== this.monitorIndex + && global.display.get_monitor_in_fullscreen(this.monitorIndex) && this._panelHasOpenMenus()) { + // Focused window is on other monitor but this monitor has a fullscreened window so + // remove focus from other window so that chrome remains visible until a window is focused + this._focusDesktop(); + } + this._queueShowHidePanel(); }, @@ -3774,30 +3773,43 @@ Panel.prototype = { } }, - _enterPanel: function(actor=null, event=null) { - this._mouseEntered = true; - this._updatePanelVisibility(); - }, + _focusDesktop: function() { + const windows = global.display.list_windows(0); - _leavePanel:function(actor=null, event=null) { - if (event !== null && this._eventOnPanelStrip(...event.get_coords())) { - return; + for (let i = 0; i < windows.length; i++) { + let window = windows[i]; + if (window.get_window_type() === Meta.WindowType.DESKTOP && window.get_monitor() === this.monitorIndex) { + window.activate(global.display.get_current_time()); + return; + } } + }, - this._mouseEntered = false; - this._updatePanelVisibility(); + _mouseOnPanel: function() { + this.actor.sync_hover(); + const [x, y] = global.get_pointer(); + + return (this.actor.x <= x && x <= this.actor.x + this.actor.width && + this.actor.y <= y && y <= this.actor.y + this.actor.height); }, - _eventOnPanelStrip: function(x, y) { - switch (this.panelPosition) { - case PanelLoc.top: - return y === this.monitor.y; - case PanelLoc.bottom: - return y === this.monitor.y + this.monitor.height - 1; - case PanelLoc.left: - return x === this.monitor.x; - case PanelLoc.right: - return x === this.monitor.x + this.monitor.width - 1; + _enterPanel: function(actor=null, event=null) { + if (!this._mouseEntered) { + this._updatePanelVisibility(); + } + }, + + _leavePanel:function(actor=null, event=null) { + // Panel gives false leave-event's when mouse is still on panel so we determine this._mouseEntered + // manually with this._mouseOnPanel() in this._updatePanelVisibility() + + if (this._mouseEntered) { + this._updatePanelVisibility(); + if (this.isHideable() && event !== null && this._mouseOnPanel()) { + // Since we get false leave-event's and reported mouse position is often still + // on panel even if left, we check again a short while later to make sure. + setTimeout(this._updatePanelVisibility.bind(this), 250); + } } }, @@ -3809,7 +3821,6 @@ Panel.prototype = { */ disable: function() { this._disabled = true; - this._leavePanel(); this.actor.ease({ opacity: 0, duration: AUTOHIDE_ANIMATION_TIME * 1000, @@ -3904,18 +3915,14 @@ Panel.prototype = { /** * _hidePanel: - * @force (boolean): whether or not to force the hide. * - * This hides the panel unless this._shouldShow is false. This behaviour is - * overridden if the @force argument is set to true. However, the panel - * will always not be hidden if a menu is open, regardless of the value of - * @force. + * This hides the panel. */ - _hidePanel: function(force) { + _hidePanel: function() { if (this._destroyed) return; this._showHideTimer = 0; - if ((this._shouldShow && !force) || this._panelHasOpenMenus()) return; + if (this._hidden) return; // setup panel tween - slide out the monitor edge leaving one pixel // if horizontal panel, animation on y. if vertical, animation on x. @@ -3973,7 +3980,7 @@ Panel.prototype = { }, getIsVisible: function() { - return !this._hidden; + return !this._hidden || this._shouldShow; }, resetDNDZones: function() {