From d7ec1156e25aa4f93a7f117f5bdaacad64804aac Mon Sep 17 00:00:00 2001 From: Julian Schacher Date: Tue, 24 Jan 2023 18:33:15 +0100 Subject: [PATCH] Refactor: Setup and handle all of DND scroll. in `#setupDNDScroll` func. Also handle drag events in this function so connecting to "drag-end" in widgets with "GtkDragSource" and a `globalThis` `ScrollManager` instance aren't needed. --- data/ui/prefs-box-order-item-row.ui | 1 - src/prefsModules/PrefsBoxOrderItemRow.js | 5 --- src/prefsModules/PrefsPage.js | 56 +++++++++++++++++++----- 3 files changed, 46 insertions(+), 16 deletions(-) diff --git a/data/ui/prefs-box-order-item-row.ui b/data/ui/prefs-box-order-item-row.ui index e576862..86bf461 100644 --- a/data/ui/prefs-box-order-item-row.ui +++ b/data/ui/prefs-box-order-item-row.ui @@ -31,7 +31,6 @@ move - diff --git a/src/prefsModules/PrefsBoxOrderItemRow.js b/src/prefsModules/PrefsBoxOrderItemRow.js index e6ba06c..5ca3e7a 100644 --- a/src/prefsModules/PrefsBoxOrderItemRow.js +++ b/src/prefsModules/PrefsBoxOrderItemRow.js @@ -81,11 +81,6 @@ var PrefsBoxOrderItemRow = GObject.registerClass({ drag.set_hotspot(this._drag_starting_point_x, this._drag_starting_point_y); } - onDragEnd() { - // Stop all scrolling, which is due to this DND operation. - scrollManager.stopScrollAll(); - } - // Handle a new drop on `this` properly. // `value` is the thing getting dropped. onDrop(_target, value, _x, _y) { diff --git a/src/prefsModules/PrefsPage.js b/src/prefsModules/PrefsPage.js index a7f64ff..18122af 100644 --- a/src/prefsModules/PrefsPage.js +++ b/src/prefsModules/PrefsPage.js @@ -20,28 +20,64 @@ var PrefsPage = GObject.registerClass({ constructor(params = {}) { super(params); - // Scroll up or down, when a Drag-and-Drop operation is in progress and - // the user has their cursor either in the upper or lower 10% of this - // widget respectively. + this.#setupDNDScroll(); + } + + /** + * This function sets up Drag-and-Drop scrolling. + * This means that scroll up or down is happening when a Drag-and-Drop + * operation is in progress and the user has their cursor either in the + * upper or lower 10% of this widget respectively. + */ + #setupDNDScroll() { // Pass `this.get_first_child()` to the ScrollManager, since this // `PrefsPage` extends an `Adw.PreferencesPage` and the first child of // an `Adw.PreferencesPage` is the built-in `Gtk.ScrolledWindow`. - globalThis.scrollManager = new ScrollManager.ScrollManager(this.get_first_child()); + this._scrollManager = new ScrollManager.ScrollManager(this.get_first_child()); + + /// Setup GtkDropControllerMotion event controller and make use of its + /// events. let controller = new Gtk.DropControllerMotion(); - controller.connect("motion", (_, x, y) => { + + // Scroll, when the pointer is in the right places. + controller.connect("motion", (_, _x, y) => { // If the pointer is currently in the upper ten percent of this // widget, then scroll up. - if (y <= this.get_allocated_height() * 0.1) scrollManager.startScrollUp(); + if (y <= this.get_allocated_height() * 0.1) this._scrollManager.startScrollUp(); // If the pointer is currently in the lower ten percent of this // widget, then scroll down. - else if (y >= this.get_allocated_height() * 0.9) scrollManager.startScrollDown(); + else if (y >= this.get_allocated_height() * 0.9) this._scrollManager.startScrollDown(); // Otherwise stop scrolling. - else scrollManager.stopScrollAll(); + else this._scrollManager.stopScrollAll(); }); + + // Make sure scrolling stops, when DND operation ends. + this._dndEnded = true; + const stopScrollAllAtDNDEnd = () => { + this._scrollManager.stopScrollAll(); + this._dndEnded = true; + } controller.connect("leave", () => { - // Stop scrolling on leave. - scrollManager.stopScrollAll(); + stopScrollAllAtDNDEnd(); }); + controller.connect("enter", () => { + // Make use of `this._dndEnded` to setup stopScrollAtDNDEnd only + // once per DND operation. + if (this._dndEnded) { + let drag = controller.get_drop().get_drag(); + drag.connect("drop-performed", () => { + stopScrollAllAtDNDEnd(); + }); + drag.connect("dnd-finished", () => { + stopScrollAllAtDNDEnd(); + }); + drag.connect("cancel", () => { + stopScrollAllAtDNDEnd(); + }); + this._dndEnded = false; + } + }); + this.add_controller(controller); } });