Skip to content

Commit b9d396e

Browse files
committed
nemo-list-view: Restrict drag-into-folder actions to be triggered
only over text-covered regions of a given row. Dropping onto blank area of a folder row will now be considered a background drop (added/moved to the current location), the same as non-folder rows.
1 parent 9c0bdaa commit b9d396e

8 files changed

+121
-5
lines changed

eel/eel-gdk-extensions.c

+14
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,17 @@ eel_gdk_parse_geometry (const char *string, int *x_return, int *y_return,
7373

7474
return gdk_flags;
7575
}
76+
77+
GdkDevice *
78+
eel_gdk_get_pointer_device (void)
79+
{
80+
GdkSeat *seat;
81+
82+
seat = gdk_display_get_default_seat (gdk_display_get_default ());
83+
84+
if (seat != NULL) {
85+
return gdk_seat_get_pointer (seat);
86+
}
87+
88+
return NULL;
89+
}

eel/eel-gdk-extensions.h

+1
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,5 @@ EelGdkGeometryFlags eel_gdk_parse_geometry (const char
4747
guint *width_return,
4848
guint *height_return);
4949

50+
GdkDevice *eel_gdk_get_pointer_device (void);
5051
#endif /* EEL_GDK_EXTENSIONS_H */

eel/eel-gtk-extensions.c

+61
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
#include "eel-glib-extensions.h"
3333
#include "eel-gnome-extensions.h"
34+
#include "eel-gdk-extensions.h"
3435
#include "eel-string.h"
3536

3637
#include <X11/Xlib.h>
@@ -376,3 +377,63 @@ eel_gtk_get_window_xid (GtkWindow *window)
376377

377378
return gdk_x11_window_get_xid (gdkw);
378379
}
380+
381+
gboolean
382+
eel_gtk_get_treeview_pointer_location (GtkTreeView *treeview,
383+
gint *x, gint *y)
384+
{
385+
GdkWindow *bin_window;
386+
387+
gint out_x, out_y;
388+
389+
*x = *y = 0;
390+
391+
bin_window = gtk_tree_view_get_bin_window (treeview);
392+
393+
if (bin_window != NULL) {
394+
GdkDevice *device = eel_gdk_get_pointer_device ();
395+
if (device != NULL) {
396+
gdk_window_get_device_position (bin_window, device, &out_x, &out_y, NULL);
397+
398+
*x = out_x;
399+
*y = out_y;
400+
401+
return TRUE;
402+
}
403+
}
404+
405+
return FALSE;
406+
}
407+
408+
gboolean
409+
eel_gtk_get_treeview_row_text_is_under_pointer (GtkTreeView *tree_view)
410+
{
411+
gint x, y;
412+
413+
if (eel_gtk_get_treeview_pointer_location (tree_view, &x, &y)) {
414+
GdkRectangle area;
415+
GtkTreePath *path;
416+
GtkTreeViewColumn *column;
417+
418+
// A positive is_blank_at_pos is a reliable result.
419+
if (gtk_tree_view_is_blank_at_pos (tree_view, x, y, &path, &column, NULL, NULL)) {
420+
return FALSE;
421+
}
422+
423+
// If not, there's an additional check to do, as the small gap (1px?) between rows
424+
// can cause is_blank_at_pos to incorrectly return FALSE when that's not actually the case.
425+
// Make sure the pointer position is actually inside the cell's bounds, and ignore edge
426+
// events.
427+
gtk_tree_view_get_cell_area (tree_view, path, column, &area);
428+
if (x > area.x && x < area.x + area.width &&
429+
y > area.y && y < area.y + area.height) {
430+
return TRUE;
431+
}
432+
433+
return FALSE;
434+
}
435+
436+
// If we can't figure out the location, we need to default to allowing the operation. The highlighting will
437+
// be accurate, so the user knows.
438+
return TRUE;
439+
}

eel/eel-gtk-extensions.h

+3
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,7 @@ void eel_gtk_message_dialog_set_details_label (GtkMessag
5555
const gchar *details_text);
5656

5757
XID eel_gtk_get_window_xid (GtkWindow *window);
58+
gboolean eel_gtk_get_treeview_pointer_location (GtkTreeView *treeview,
59+
gint *x, gint *y);
60+
gboolean eel_gtk_get_treeview_row_text_is_under_pointer (GtkTreeView *tree_view);
5861
#endif /* EEL_GTK_EXTENSIONS_H */

libnemo-private/nemo-tree-view-drag-dest.c

+13-2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "nemo-link.h"
3939

4040
#include <gtk/gtk.h>
41+
#include <eel/eel-gtk-extensions.h>
4142

4243
#include <stdio.h>
4344
#include <string.h>
@@ -67,6 +68,7 @@ struct _NemoTreeViewDragDestDetails {
6768
gboolean desktop_dnd_can_delete_source;
6869

6970
char *direct_save_uri;
71+
gboolean strict_drop;
7072
};
7173

7274
enum {
@@ -506,7 +508,15 @@ drag_motion_callback (GtkWidget *widget,
506508
NULL);
507509

508510
if (action) {
509-
set_drag_dest_row (dest, drop_path);
511+
if (dest->details->strict_drop) {
512+
if (eel_gtk_get_treeview_row_text_is_under_pointer (GTK_TREE_VIEW (widget))) {
513+
set_drag_dest_row (dest, drop_path);
514+
} else {
515+
clear_drag_dest_row (dest);
516+
}
517+
} else {
518+
set_drag_dest_row (dest, drop_path);
519+
}
510520
model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
511521
if (drop_path == NULL || (old_drop_path != NULL &&
512522
gtk_tree_path_compare (old_drop_path, drop_path) != 0)) {
@@ -1154,7 +1164,7 @@ nemo_tree_view_drag_dest_class_init (NemoTreeViewDragDestClass *class)
11541164

11551165

11561166
NemoTreeViewDragDest *
1157-
nemo_tree_view_drag_dest_new (GtkTreeView *tree_view)
1167+
nemo_tree_view_drag_dest_new (GtkTreeView *tree_view, gboolean strict_drop)
11581168
{
11591169
NemoTreeViewDragDest *dest;
11601170
GtkTargetList *targets;
@@ -1164,6 +1174,7 @@ nemo_tree_view_drag_dest_new (GtkTreeView *tree_view)
11641174
dest->details->tree_view = tree_view;
11651175
dest->details->desktop_dnd_source_fs = NULL;
11661176
dest->details->desktop_dnd_can_delete_source = FALSE;
1177+
dest->details->strict_drop = strict_drop;
11671178
g_object_weak_ref (G_OBJECT (dest->details->tree_view),
11681179
tree_view_weak_notify, dest);
11691180

libnemo-private/nemo-tree-view-drag-dest.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ struct _NemoTreeViewDragDestClass {
9393
};
9494

9595
GType nemo_tree_view_drag_dest_get_type (void);
96-
NemoTreeViewDragDest *nemo_tree_view_drag_dest_new (GtkTreeView *tree_view);
96+
NemoTreeViewDragDest *nemo_tree_view_drag_dest_new (GtkTreeView *tree_view, gboolean strict_drop);
9797

9898
G_END_DECLS
9999

src/nemo-list-view.c

+27-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include <string.h>
3939
#include <eel/eel-vfs-extensions.h>
4040
#include <eel/eel-gdk-extensions.h>
41+
#include <eel/eel-gtk-extensions.h>
4142
#include <eel/eel-glib-extensions.h>
4243
#include <gdk/gdk.h>
4344
#include <gdk/gdkkeysyms.h>
@@ -1776,6 +1777,25 @@ get_root_uri_callback (NemoTreeViewDragDest *dest,
17761777
return nemo_view_get_uri (NEMO_VIEW (view));
17771778
}
17781779

1780+
// this is confusing... so rename them.
1781+
#define ALLOW_EXPAND FALSE
1782+
#define PREVENT_EXPAND TRUE
1783+
1784+
static gboolean
1785+
test_expand_row_callback (GtkTreeView *treeview,
1786+
GtkTreeIter *iter,
1787+
GtkTreePath *path,
1788+
gpointer user_data)
1789+
{
1790+
NemoListView *view = NEMO_LIST_VIEW (user_data);
1791+
1792+
if (eel_gtk_get_treeview_row_text_is_under_pointer (view->details->tree_view)) {
1793+
return ALLOW_EXPAND;
1794+
}
1795+
1796+
return PREVENT_EXPAND;
1797+
}
1798+
17791799
static NemoFile *
17801800
get_file_for_path_callback (NemoTreeViewDragDest *dest,
17811801
GtkTreePath *path,
@@ -1785,6 +1805,10 @@ get_file_for_path_callback (NemoTreeViewDragDest *dest,
17851805

17861806
view = NEMO_LIST_VIEW (user_data);
17871807

1808+
if (!eel_gtk_get_treeview_row_text_is_under_pointer (view->details->tree_view)) {
1809+
return NULL;
1810+
}
1811+
17881812
return nemo_list_model_file_for_path (view->details->model, path);
17891813
}
17901814

@@ -2490,7 +2514,7 @@ create_and_set_up_tree_view (NemoListView *view)
24902514
gtk_binding_entry_remove (binding_set, GDK_KEY_BackSpace, 0);
24912515

24922516
view->details->drag_dest =
2493-
nemo_tree_view_drag_dest_new (view->details->tree_view);
2517+
nemo_tree_view_drag_dest_new (view->details->tree_view, TRUE);
24942518

24952519
g_signal_connect_object (view->details->drag_dest,
24962520
"get_root_uri",
@@ -2546,6 +2570,8 @@ create_and_set_up_tree_view (NemoListView *view)
25462570
G_CALLBACK (row_collapsed_callback), view, 0);
25472571
g_signal_connect_object (view->details->tree_view, "row-activated",
25482572
G_CALLBACK (row_activated_callback), view, 0);
2573+
g_signal_connect_object (view->details->tree_view, "test-expand-row",
2574+
G_CALLBACK (test_expand_row_callback), view, 0);
25492575

25502576
g_signal_connect_object (view->details->tree_view, "focus_in_event",
25512577
G_CALLBACK(focus_in_event_callback), view, 0);

src/nemo-tree-sidebar.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1645,7 +1645,7 @@ create_tree (FMTreeView *view)
16451645
gtk_tree_view_set_headers_visible (view->details->tree_widget, FALSE);
16461646

16471647
view->details->drag_dest =
1648-
nemo_tree_view_drag_dest_new (view->details->tree_widget);
1648+
nemo_tree_view_drag_dest_new (view->details->tree_widget, FALSE);
16491649
g_signal_connect_object (view->details->drag_dest,
16501650
"get_root_uri",
16511651
G_CALLBACK (get_root_uri_callback),

0 commit comments

Comments
 (0)