From 4e97cd6ea7b9f430d60d8e6acee0bec034f9ad9a Mon Sep 17 00:00:00 2001 From: Michael Gratton Date: Sun, 4 Apr 2021 14:30:19 +1000 Subject: [PATCH] client: Decouple folder list entry DND from both main and GDK windows Pass an instance of the owning `Sidebar.Tree` through to `Sidebar.Entry` when calling `internal_drop_received` instead of a `Application.MainWindow` to remove a bidi relationship between the two. Use the high level GTK API for determining the DnD action in `FolderList.Entry`'s implementation of this method, rather than attempt, to divine it from keyboard modifiers via the associated GDK window, since under Wayland that will be null. Fixes #1163 --- .../folder-list/folder-list-folder-entry.vala | 31 ++++++++++++------- src/client/sidebar/sidebar-entry.vala | 2 +- src/client/sidebar/sidebar-tree.vala | 12 ++----- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/client/folder-list/folder-list-folder-entry.vala b/src/client/folder-list/folder-list-folder-entry.vala index ae78c1ff..1a00ca3c 100644 --- a/src/client/folder-list/folder-list-folder-entry.vala +++ b/src/client/folder-list/folder-list-folder-entry.vala @@ -80,20 +80,29 @@ public class FolderList.FolderEntry : entry_changed(); } - public bool internal_drop_received(Application.MainWindow main_window, + public bool internal_drop_received(Sidebar.Tree parent, Gdk.DragContext context, Gtk.SelectionData data) { - // Copy or move? - Gdk.ModifierType mask; - double[] axes = new double[2]; - context.get_device().get_state(context.get_dest_window(), axes, out mask); - if ((mask & Gdk.ModifierType.CONTROL_MASK) != 0) { - main_window.folder_list.copy_conversation(folder); - } else { - main_window.folder_list.move_conversation(folder); - } + var handled = false; + var folders = parent as FolderList.Tree; + if (folders != null) { + switch (context.get_selected_action()) { + case MOVE: + folders.move_conversation(folder); + handled = true; + break; - return true; + case COPY: + folders.copy_conversation(folder); + handled = true; + break; + + default: + // noop + break; + } + } + return handled; } public override int get_count() { diff --git a/src/client/sidebar/sidebar-entry.vala b/src/client/sidebar/sidebar-entry.vala index efbc5905..750d5a7f 100644 --- a/src/client/sidebar/sidebar-entry.vala +++ b/src/client/sidebar/sidebar-entry.vala @@ -51,7 +51,7 @@ public interface Sidebar.DestroyableEntry : Sidebar.Entry { public interface Sidebar.InternalDropTargetEntry : Sidebar.Entry { // Returns true if drop was successful - public abstract bool internal_drop_received(Application.MainWindow main, + public abstract bool internal_drop_received(Sidebar.Tree parent, Gdk.DragContext context, Gtk.SelectionData data); } diff --git a/src/client/sidebar/sidebar-tree.vala b/src/client/sidebar/sidebar-tree.vala index 90db9bbd..989d8793 100644 --- a/src/client/sidebar/sidebar-tree.vala +++ b/src/client/sidebar/sidebar-tree.vala @@ -1002,15 +1002,9 @@ public class Sidebar.Tree : Gtk.TreeView { return; } - bool success = false; - - var main = get_toplevel() as Application.MainWindow; - if (main != null) { - success = targetable.internal_drop_received( - main, context, selection_data - ); - } - + bool success = targetable.internal_drop_received( + this, context, selection_data + ); Gtk.drag_finish(context, success, false, time); }