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
This commit is contained in:
Michael Gratton 2021-04-04 14:30:19 +10:00
parent 43c2fa4342
commit 4e97cd6ea7
3 changed files with 24 additions and 21 deletions

View file

@ -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() {

View file

@ -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);
}

View file

@ -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);
}