From d3a5efacd35a363755e3b38597b21e8e86fdaac2 Mon Sep 17 00:00:00 2001 From: fredcw Date: Mon, 15 May 2023 04:22:27 +0100 Subject: [PATCH 1/5] Add class to make applets resizable with mouse When applet can be resized on opposite edges, i.e. when the applet is not in a corner of the workspace, then resizing from either of those edges leads the mouse pointer to not match up with the applet edge. This is a minor visual issue that maybe should be fixed in the future. --- js/ui/applet.js | 306 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 306 insertions(+) diff --git a/js/ui/applet.js b/js/ui/applet.js index 292c5bf22d..e7771a15cc 100644 --- a/js/ui/applet.js +++ b/js/ui/applet.js @@ -16,6 +16,7 @@ const ModalDialog = imports.ui.modalDialog; const Signals = imports.signals; const Gettext = imports.gettext; const Cinnamon = imports.gi.Cinnamon; +const SignalManager = imports.misc.signalManager; var AllowedLayout = { // the panel layout that an applet is suitable for VERTICAL: 'vertical', @@ -970,3 +971,308 @@ var TextIconApplet = class TextIconApplet extends IconApplet { } } + +const ZONE_SIZE = 10; + +/** + * #PopupResizeHandler: + * @short_description: Class that allows an applet to be resized using the mouse. + * @inhibit_resizing (Boolean): Set to false to prevent resizing + * @resizingInProgress (Boolean): True when resizing is in progress + * + * Parameters - actor: The actor to be resized + * get_orientation: Function that returns the current orientation of the applet. (St.Side) + * resized_callback: Function that is called while resizing is in progress with the new width + * and height as parameters. This function should actually change the applet size. This is + * also called once when resizing has ended (resizingInProgress == false) so that the + * applet can store the final size instead of doing so continuously whilst resizing + * is in progress. + * get_user_width: Function that returns the current applet width. This is called only + * when resizing begins so does not have to return the correct width while resizing is in + * progress. Note: This value does not necessarily have to be the applet width. It could + * be the width of a container inside the applet used for sizing the applet. + * get_user_height: As get_user_width but for height + * + * Example - + * this.menu = new Applet.AppletPopupMenu(this, this.orientation); + * this.settings.bind("popup-width", "popup_width"); + * this.settings.bind("popup-height", "popup_height"); + * + * this._resizer = new Applet.PopupResizeHandler( + * this.menu.actor, + * () => this.orientation, + * (w,h) => this._onBoxResized(w,h), + * () => this.popup_width * global.ui_scale, + * () => this.popup_height * global.ui_scale); + * + * ... + * + * _onBoxResized(width, height) { + * this.popup_width = Math.max(width / global.ui_scale, 300); + * this.popup_height = Math.max(height / global.ui_scale, 400); + * this.menu.actor.set_width(this.popup_width * global.ui_scale); + * this.menu.actor.set_height(this.popup_height * global.ui_scale); + * } + */ +var PopupResizeHandler = class PopupResizeHandler { + constructor(actor, get_orientation, resized_callback, get_user_width, get_user_height) { + this.actor = actor; + this._get_orientation = get_orientation; + this._resized_callback = resized_callback; + this._get_user_width = get_user_width; + this._get_user_height = get_user_height; + + this._signals = new SignalManager.SignalManager(null); + + this._signals.connect(this.actor, 'motion-event', (...args) => this._motion_event(...args)); + this._signals.connect(this.actor, 'leave-event', (...args) => this._leave_event(...args)); + this._signals.connect(this.actor, 'button-press-event', (...args) => this._onButtonPress(...args)); + + this._no_edges_draggable = true; + this.inhibit_resizing = false; + + this._drag_start_position = null; + this._drag_start_size = null; + this._scaled_zone_size = null; + + this._edges = { top: 0, + bottom: 0, + left: 0, + right: 0 }; + + this.resizingInProgress = false; + this._workAreaHeight = null; + this._workAreaWidth = null; + } + + _onButtonPress(actor, event) { + if (this.inhibit_resizing || this._no_edges_draggable) + return false; + + if (event.get_button() != Clutter.BUTTON_PRIMARY) + return false; + + //---Start drag------ + + this._grabEvents(event); + this.resizingInProgress = true; + + let [stageX, stageY] = event.get_coords(); + this._drag_start_position = {x: stageX, y: stageY}; + this._drag_start_size = {width: this.actor.width, height: this.actor.height}; + this._init_user_width = this._get_user_width(); + this._init_user_height = this._get_user_height(); + + return true; + } + + _grabEvents(event) { + this._eventsGrabbed = true; + + this._drag_device = event.get_device(); + this._drag_device.grab(this.actor); + + this._onEventId = this.actor.connect('event', (...args) => this._onEvent(...args)); + } + + _ungrabEvents(event) { + if (!this._eventsGrabbed) + return; + + if (this._drag_device) { + this._drag_device.ungrab(); + this._drag_device = null; + } else if (event) {//this shouldn't arise + event.get_device().ungrab(); + } + this._eventsGrabbed = false; + + this.actor.disconnect(this._onEventId); + this._onEventId = null; + } + + _stop_drag(event) { + if (!this.resizingInProgress) { + return; + } + global.unset_cursor(); + this._ungrabEvents(event); + + this.actor.queue_relayout(); + + this._drag_start_position = null; + this._drag_start_size = null; + this.resizingInProgress = false; + //update position again while this.resizingInProgress === false so that applet can update settings + this._resized_callback(this.new_user_width, this.new_user_height); + } + + _onEvent(actor, event) { + if (event.type() == Clutter.EventType.BUTTON_RELEASE) { + this._stop_drag(); + return true; + } else if (event.type() == Clutter.EventType.MOTION) { + if (this.resizingInProgress) { + this._updateDragPosition(event); + return true; + } + } else if (event.type() == Clutter.EventType.KEY_RELEASE && this.resizingInProgress) { + const symbol = event.get_key_symbol(); + if (symbol === Clutter.KEY_Escape) { + this._stop_drag(); + return Clutter.EVENT_STOP; + } + return Clutter.EVENT_STOP; + } + return false; + } + + _collect_work_area_edges() { + const monitor = Main.layoutManager.findMonitorForActor(this.actor); + const ws = global.screen.get_active_workspace(); + const area = ws.get_work_area_for_monitor(monitor.index); + + this._edges.top = area.y; + this._edges.bottom = area.y + area.height; + this._edges.left = area.x; + this._edges.right = area.x + area.width; + + this._workAreaHeight = area.height; + this._workAreaWidth = area.width; + } + + _motion_event(box, event) { + if (this.inhibit_resizing) { + return Clutter.EVENT_PROPAGATE; + } + this._collect_work_area_edges(); + this._scaled_zone_size = ZONE_SIZE * global.ui_scale; + + let cursor = 0; + + let [x, y] = event.get_coords(); + + //Immediately resize actor if greater than work area. This can happen after a + //change of resolution or monitor scaling. + if (this.actor.height > this._workAreaHeight) { + const overHeight = this.actor.height - this._workAreaHeight; + this._resized_callback(this._get_user_width(), this._get_user_height() - overHeight); + return Clutter.EVENT_PROPAGATE; + } + if (this.actor.width > this._workAreaWidth) { + const overWidth = this.actor.width - this._workAreaWidth; + this._resized_callback(this._get_user_width() - overWidth, this._get_user_height()); + return Clutter.EVENT_PROPAGATE; + } + + this._top_edge_draggable = this._in_top_resize_zone (x, y); + this._bottom_edge_draggable = this._in_bottom_resize_zone (x, y); + this._left_edge_draggable = this._in_left_resize_zone (x, y,); + this._right_edge_draggable = this._in_right_resize_zone (x, y); + + this._no_edges_draggable = false; + if (this._top_edge_draggable && this._left_edge_draggable) { + cursor = Cinnamon.Cursor.RESIZE_TOP_LEFT; + } else if (this._top_edge_draggable && this._right_edge_draggable) { + cursor = Cinnamon.Cursor.RESIZE_TOP_RIGHT; + } else if (this._bottom_edge_draggable && this._left_edge_draggable) { + cursor = Cinnamon.Cursor.RESIZE_BOTTOM_LEFT; + } else if (this._bottom_edge_draggable && this._right_edge_draggable) { + cursor = Cinnamon.Cursor.RESIZE_BOTTOM_RIGHT; + } else if (this._top_edge_draggable) { + cursor = Cinnamon.Cursor.RESIZE_TOP; + } else if (this._bottom_edge_draggable) { + cursor = Cinnamon.Cursor.RESIZE_BOTTOM; + } else if (this._left_edge_draggable) { + cursor = Cinnamon.Cursor.RESIZE_LEFT; + } else if (this._right_edge_draggable) { + cursor = Cinnamon.Cursor.RESIZE_RIGHT; + } else { + global.unset_cursor(); + this._no_edges_draggable = true; + return Clutter.EVENT_PROPAGATE; + } + + global.set_cursor (cursor); + return Clutter.EVENT_PROPAGATE; + } + + _updateDragPosition(event) { + let [stageX, stageY] = event.get_coords(); + let delta_width = 0; + let delta_height = 0; + + const start_w = this._drag_start_size.width; + const start_h = this._drag_start_size.height; + + if (this._left_edge_draggable) { + const x_diff = this._drag_start_position.x - stageX; + const new_width = (start_w + x_diff).clamp(0, this._workAreaWidth); + delta_width = new_width - start_w; + } else if (this._right_edge_draggable) { + const x_diff = stageX - this._drag_start_position.x; + const new_width = (start_w + x_diff).clamp(0, this._workAreaWidth); + delta_width = new_width - start_w; + } + + if (this._top_edge_draggable) { + const y_diff = this._drag_start_position.y - stageY; + const new_height = (start_h + y_diff).clamp(0, this._workAreaHeight); + delta_height = new_height - start_h; + } else if (this._bottom_edge_draggable) { + const y_diff = stageY - this._drag_start_position.y; + const new_height = (start_h + y_diff).clamp(0, this._workAreaHeight); + delta_height = new_height - start_h; + } + + this.new_user_width = this._init_user_width + delta_width; + this.new_user_height = this._init_user_height + delta_height; + this._resized_callback(this.new_user_width, this.new_user_height); + + return true; + } + + _leave_event(box, event) { + if (!this.resizingInProgress) { + global.unset_cursor(); + } + return Clutter.EVENT_PROPAGATE; + } + + _in_top_resize_zone(x, y) { + if (x < this.actor.x || x > this.actor.x + this.actor.width || this._get_orientation() === St.Side.TOP) { + return false; + } + + return y <= this.actor.y + this._scaled_zone_size && y >= this.actor.y && + this.actor.y >= this._edges.top; + } + + _in_bottom_resize_zone(x, y) { + if (x < this.actor.x || x > this.actor.x + this.actor.width || this._get_orientation() === St.Side.BOTTOM) { + return false; + } + + return y >= this.actor.y + this.actor.height - this._scaled_zone_size && + y <= this.actor.y + this.actor.height && this.actor.y + this.actor.height <= this._edges.bottom; + } + + _in_left_resize_zone(x, y) { + if (y < this.actor.y || y > this.actor.y + this.actor.height || this._get_orientation() === St.Side.LEFT) { + return false; + } + + return x <= this.actor.x + this._scaled_zone_size && + x >= this.actor.x && this.actor.x >= this._edges.left; + } + + _in_right_resize_zone(x, y) { + if (y < this.actor.y || y > this.actor.y + this.actor.height || this._get_orientation() === St.Side.RIGHT) { + return false; + } + + return x >= this.actor.x + this.actor.width - this._scaled_zone_size && + x <= this.actor.x + this.actor.width && this.actor.x + this.actor.width <= this._edges.right; + } +} + From 3e323b2d5a93b204c1324877d2eace7a7e3abf69 Mon Sep 17 00:00:00 2001 From: fredcw Date: Mon, 15 May 2023 04:33:34 +0100 Subject: [PATCH 2/5] Make menu applet resizable with mouse Add Applet.PopupResizeHandler class to applet to make it resizable. --- .../applets/menu@cinnamon.org/applet.js | 56 +++++++++---------- .../menu@cinnamon.org/settings-schema.json | 26 +++------ 2 files changed, 37 insertions(+), 45 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 899e36f242..8b38c87cb6 100644 --- a/files/usr/share/cinnamon/applets/menu@cinnamon.org/applet.js +++ b/files/usr/share/cinnamon/applets/menu@cinnamon.org/applet.js @@ -39,7 +39,10 @@ const AppUtils = require('./appUtils'); let appsys = Cinnamon.AppSystem.get_default(); -const MAX_BUTTON_WIDTH = "max-width: 20em;"; +const POPUP_MIN_WIDTH = 500; +const POPUP_MAX_WIDTH = 900; +const POPUP_MIN_HEIGHT = 400; +const POPUP_MAX_HEIGHT = 1400; const RefreshFlags = Object.freeze({ APP: 0b000001, @@ -177,7 +180,6 @@ class SimpleMenuItem { this._signals = new SignalManager.SignalManager(); this.actor = new St.BoxLayout({ style_class: params.styleClass, - style: MAX_BUTTON_WIDTH, reactive: params.reactive, accessible_role: Atk.Role.MENU_ITEM }); @@ -1184,6 +1186,12 @@ class CinnamonMenuApplet extends Applet.TextIconApplet { this._size_dirty = true; }); + this._resizer = new Applet.PopupResizeHandler(this.menu.actor, + () => this._orientation, + (w,h) => this._onBoxResized(w,h), + () => this.popup_width * global.ui_scale, + () => this.popup_height * global.ui_scale); + this.settings.bind("show-favorites", "showFavorites", () => this.queueRefresh(RefreshFlags.FAV_DOC)); this.settings.bind("show-places", "showPlaces", () => this.queueRefresh(RefreshFlags.PLACE)); this.settings.bind("show-recents", "showRecents", () => this.queueRefresh(RefreshFlags.RECENT)); @@ -1216,8 +1224,8 @@ class CinnamonMenuApplet extends Applet.TextIconApplet { this.settings.bind("favbox-show", "favBoxShow", this._favboxtoggle); this.settings.bind("fav-icon-size", "favIconSize", () => this.queueRefresh(RefreshFlags.FAV_APP | RefreshFlags.SYSTEM)); this.settings.bind("enable-animation", "enableAnimation", null); - this.settings.bind("restrict-menu-height", "restrictMenuHeight", null); - this.settings.bind("menu-height", "menuHeight", null); + this.settings.bind("popup-width", "popup_width"); + this.settings.bind("popup-height", "popup_height"); this._updateKeybinding(); @@ -1294,6 +1302,12 @@ class CinnamonMenuApplet extends Applet.TextIconApplet { }) } + _onBoxResized(width, height) { + this.popup_width = (width / global.ui_scale).clamp(POPUP_MIN_WIDTH, POPUP_MAX_WIDTH); + this.popup_height = (height / global.ui_scale).clamp(POPUP_MIN_HEIGHT, POPUP_MAX_HEIGHT); + this._setMenuSize(); + } + _updateKeybinding() { Main.keybindingManager.addHotKey("overlay-key-" + this.instance_id, this.overlayKey, Lang.bind(this, function() { if (!Main.overview.visible && !Main.expo.visible) @@ -1406,25 +1420,21 @@ class CinnamonMenuApplet extends Applet.TextIconApplet { }); } - _recalc_sizes() { - Util.each(this.applicationsBox.get_children(), c => c.hide()); + _setMenuSize() { + //this.selectedAppBox.natural_width_set = false; + //this.selectedAppBox.minimum_width_set = false; + this.main_container.natural_height = (this.popup_height * global.ui_scale); + this.main_container.natural_width = (this.popup_width * global.ui_scale); - this.main_container.natural_height = 0; - this.main_container.natural_height_set = false; - this.selectedAppBox.natural_width_set = false; - this.selectedAppBox.minimum_width_set = false; + this.menu.actor.set_width(this.popup_width * global.ui_scale); + this.menu.actor.set_height(this.popup_height * global.ui_scale); - if (this.restrictMenuHeight) { - this.main_container.natural_height = this.menuHeight * global.ui_scale; - } else { - this.main_container.natural_height = this.main_container.get_preferred_height(-1)[1]; - } + //this.main_container.natural_height = this.main_container.get_preferred_height(-1)[1]; this._update_scroll_policy(this.favoritesBox, this.favoritesScrollBox); this._update_scroll_policy(this.categoriesBox, this.categoriesScrollBox); - this._resizeApplicationsBox(); - this.selectedAppBox.width = this.selectedAppBox.width; + //this.selectedAppBox.width = this.selectedAppBox.width; this._size_dirty = false; } @@ -1440,16 +1450,6 @@ class CinnamonMenuApplet extends Applet.TextIconApplet { } } - _resizeApplicationsBox() { - let width = -1; - Util.each(this.applicationsBox.get_children(), c => { - let [min, nat] = c.get_preferred_width(-1.0); - if (nat > width) - width = nat; - }); - this.applicationsBox.set_width(width + 42); // The answer to life... - } - on_orientation_changed (orientation) { this._updateIconAndLabel(); this._size_dirty = true; @@ -1478,7 +1478,7 @@ class CinnamonMenuApplet extends Applet.TextIconApplet { this.lastSelectedCategory = null; if (this._size_dirty) { - this._recalc_sizes(); + this._setMenuSize(); } let n = Math.min(this._applicationsButtons.length, 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 46f58a7dc8..1ec39d4800 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 @@ -25,7 +25,7 @@ "menu-layout" : { "type" : "section", "title" : "Layout and content", - "keys" : ["restrict-menu-height", "menu-height", "show-category-icons", + "keys" : ["show-category-icons", "category-icon-size", "show-application-icons", "application-icon-size", "favbox-show", "fav-icon-size", "show-places", "show-recents", "menu-editor-button"] }, @@ -71,22 +71,6 @@ "tooltip" : "Enter custom text to show in the panel.", "dependency" : "menu-custom" }, - "restrict-menu-height" : { - "type": "switch", - "default" : false, - "description" : "Use a fixed menu height", - "tooltip" : "Keep the size of the menu the same no matter how many favorites or categories there are." - }, - "menu-height" : { - "type": "spinbutton", - "default" : 550, - "min" : 300, - "max" : 2000, - "step" : 10, - "units" : "px", - "description" : "Menu height", - "dependency" : "restrict-menu-height" - }, "show-category-icons" : { "type" : "switch", "default" : true, @@ -205,5 +189,13 @@ "description" : "Open the menu editor", "callback" : "_launch_editor", "tooltip" : "Press this button to customize your menu entries." + }, + "popup-width" : { + "type" : "generic", + "default" : 650 + }, + "popup-height" : { + "type" : "generic", + "default" : 650 } } From d5932d01903f503f60335fec57ff2a9b00b97141 Mon Sep 17 00:00:00 2001 From: fredcw Date: Mon, 15 May 2023 10:13:16 +0100 Subject: [PATCH 3/5] Menu applet: Only update settings when resizing is completed... ...to avoid excessive disk writes. + remove some commented out lines. --- .../applets/menu@cinnamon.org/applet.js | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 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 8b38c87cb6..be6fc8a677 100644 --- a/files/usr/share/cinnamon/applets/menu@cinnamon.org/applet.js +++ b/files/usr/share/cinnamon/applets/menu@cinnamon.org/applet.js @@ -1303,9 +1303,16 @@ class CinnamonMenuApplet extends Applet.TextIconApplet { } _onBoxResized(width, height) { - this.popup_width = (width / global.ui_scale).clamp(POPUP_MIN_WIDTH, POPUP_MAX_WIDTH); - this.popup_height = (height / global.ui_scale).clamp(POPUP_MIN_HEIGHT, POPUP_MAX_HEIGHT); - this._setMenuSize(); + width = (width / global.ui_scale).clamp(POPUP_MIN_WIDTH, POPUP_MAX_WIDTH); + height = (height / global.ui_scale).clamp(POPUP_MIN_HEIGHT, POPUP_MAX_HEIGHT); + + //Only update settings when resizing is completed to avoid excessive disk writes. + if (!this._resizer.resizingInProgress) { + this.popup_width = width; + this.popup_height = height; + } + + this._setMenuSize(width, height); } _updateKeybinding() { @@ -1420,22 +1427,16 @@ class CinnamonMenuApplet extends Applet.TextIconApplet { }); } - _setMenuSize() { - //this.selectedAppBox.natural_width_set = false; - //this.selectedAppBox.minimum_width_set = false; - this.main_container.natural_height = (this.popup_height * global.ui_scale); - this.main_container.natural_width = (this.popup_width * global.ui_scale); + _setMenuSize(width, height) { + this.main_container.natural_height = (height * global.ui_scale); + this.main_container.natural_width = (width * global.ui_scale); - this.menu.actor.set_width(this.popup_width * global.ui_scale); - this.menu.actor.set_height(this.popup_height * global.ui_scale); - - //this.main_container.natural_height = this.main_container.get_preferred_height(-1)[1]; + this.menu.actor.set_width(width * global.ui_scale); + this.menu.actor.set_height(height * global.ui_scale); this._update_scroll_policy(this.favoritesBox, this.favoritesScrollBox); this._update_scroll_policy(this.categoriesBox, this.categoriesScrollBox); - //this.selectedAppBox.width = this.selectedAppBox.width; - this._size_dirty = false; } @@ -1478,7 +1479,7 @@ class CinnamonMenuApplet extends Applet.TextIconApplet { this.lastSelectedCategory = null; if (this._size_dirty) { - this._setMenuSize(); + this._setMenuSize(this.popup_width, this.popup_height); } let n = Math.min(this._applicationsButtons.length, From e3386a519d09bfa66757af2409fb9290f9e716c2 Mon Sep 17 00:00:00 2001 From: fredcw Date: Sun, 21 May 2023 10:09:57 +0100 Subject: [PATCH 4/5] applet.js: fix typo + rename some variables --- js/ui/applet.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/js/ui/applet.js b/js/ui/applet.js index e7771a15cc..8c7342c99c 100644 --- a/js/ui/applet.js +++ b/js/ui/applet.js @@ -977,10 +977,11 @@ const ZONE_SIZE = 10; /** * #PopupResizeHandler: * @short_description: Class that allows an applet to be resized using the mouse. - * @inhibit_resizing (Boolean): Set to false to prevent resizing + * @inhibit_resizing (Boolean): Set to true to prevent resizing * @resizingInProgress (Boolean): True when resizing is in progress * - * Parameters - actor: The actor to be resized + * Parameters - + * actor: The actor to be resized * get_orientation: Function that returns the current orientation of the applet. (St.Side) * resized_callback: Function that is called while resizing is in progress with the new width * and height as parameters. This function should actually change the applet size. This is @@ -1104,7 +1105,7 @@ var PopupResizeHandler = class PopupResizeHandler { this._drag_start_size = null; this.resizingInProgress = false; //update position again while this.resizingInProgress === false so that applet can update settings - this._resized_callback(this.new_user_width, this.new_user_height); + this._resized_callback(this._new_user_width, this._new_user_height); } _onEvent(actor, event) { @@ -1225,9 +1226,9 @@ var PopupResizeHandler = class PopupResizeHandler { delta_height = new_height - start_h; } - this.new_user_width = this._init_user_width + delta_width; - this.new_user_height = this._init_user_height + delta_height; - this._resized_callback(this.new_user_width, this.new_user_height); + this._new_user_width = this._init_user_width + delta_width; + this._new_user_height = this._init_user_height + delta_height; + this._resized_callback(this._new_user_width, this._new_user_height); return true; } From f4378d5cea28e911f1681f74ee3e006fdf232244 Mon Sep 17 00:00:00 2001 From: fredcw Date: Mon, 22 May 2023 20:15:54 +0100 Subject: [PATCH 5/5] Ungrab pointer in dnd.js when resizing applet ...as workaround to issue #11123 --- js/ui/applet.js | 5 +++++ js/ui/dnd.js | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/js/ui/applet.js b/js/ui/applet.js index 8c7342c99c..10783a5ff9 100644 --- a/js/ui/applet.js +++ b/js/ui/applet.js @@ -17,6 +17,7 @@ const Signals = imports.signals; const Gettext = imports.gettext; const Cinnamon = imports.gi.Cinnamon; const SignalManager = imports.misc.signalManager; +const Dnd = imports.ui.dnd; var AllowedLayout = { // the panel layout that an applet is suitable for VERTICAL: 'vertical', @@ -1055,6 +1056,10 @@ var PopupResizeHandler = class PopupResizeHandler { //---Start drag------ + if (Dnd.currentGrabActor != null) { //workaround for issue github.com/linuxmint/cinnamon/issues/11123 + Dnd.currentGrabActor.fakeRelease(); + } + this._grabEvents(event); this.resizingInProgress = true; diff --git a/js/ui/dnd.js b/js/ui/dnd.js index 35cd2c3fc6..51aaade42c 100644 --- a/js/ui/dnd.js +++ b/js/ui/dnd.js @@ -46,6 +46,8 @@ var currentDraggable = null; var dragMonitors = []; var targetMonitors = []; +var currentGrabActor = null; //This is used by class PopupResizeHandler in ui/applet.js as a workaround to issue github.com/linuxmint/cinnamon/issues/11123 + function _getEventHandlerActor() { if (!eventHandlerActor) { eventHandlerActor = new Clutter.Actor({ width: 0, height: 0 }); @@ -154,6 +156,7 @@ var _Draggable = new Lang.Class({ this.drag_device.grab(this.actor); this._onEventId = this.actor.connect('event', Lang.bind(this, this._onEvent)); + currentGrabActor = this; }, _ungrabActor: function(event) { @@ -168,6 +171,7 @@ var _Draggable = new Lang.Class({ this.actor.disconnect(this._onEventId); this._onEventId = null; + currentGrabActor = null; }, _grabEvents: function(event) {