Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ if enableEmptyView
endif

nemo_deps = [ cinnamon, gail, glib, gtk, math,
egg, nemo_extension, nemo_private, xapp ]
egg, nemo_extension, nemo_private, x11, xapp ]

if exempi_enabled
nemo_deps += exempi
Expand Down
87 changes: 87 additions & 0 deletions src/nemo-icon-view.c
Original file line number Diff line number Diff line change
Expand Up @@ -2399,6 +2399,83 @@ icon_container_activate_filter_cb (NemoIconContainer *container,
return nemo_view_activate_filter (NEMO_VIEW (icon_view), (GdkEventKey *) event);
}

static void
icon_container_drag_begin_callback (GtkWidget *widget,
GdkDragContext *context,
NemoIconView *icon_view)
{
GtkWidget *toplevel;

toplevel = gtk_widget_get_toplevel (widget);
if (NEMO_IS_WINDOW (toplevel)) {
nemo_window_dnd_step_aside (NEMO_WINDOW (toplevel));
}
}

static void
icon_container_drag_end_callback (GtkWidget *widget,
GdkDragContext *context,
NemoIconView *icon_view)
{
GtkWidget *toplevel;

toplevel = gtk_widget_get_toplevel (widget);
if (NEMO_IS_WINDOW (toplevel)) {
nemo_window_dnd_source_end (NEMO_WINDOW (toplevel));
}
}

static gboolean
icon_container_dnd_press_callback (GtkWidget *widget,
GdkEventButton *event,
NemoIconView *icon_view)
{
GtkWidget *toplevel;

if (event->button != 1)
return GDK_EVENT_PROPAGATE;

toplevel = gtk_widget_get_toplevel (widget);
if (NEMO_IS_WINDOW (toplevel)) {
nemo_window_dnd_source_press (NEMO_WINDOW (toplevel));
}

return GDK_EVENT_PROPAGATE;
}

static gboolean
icon_container_dnd_release_callback (GtkWidget *widget,
GdkEventButton *event,
NemoIconView *icon_view)
{
GtkWidget *toplevel;

if (event->button != 1)
return GDK_EVENT_PROPAGATE;

toplevel = gtk_widget_get_toplevel (widget);
if (NEMO_IS_WINDOW (toplevel)) {
nemo_window_dnd_source_release (NEMO_WINDOW (toplevel));
}

return GDK_EVENT_PROPAGATE;
}

/* Pressing empty space draws a selection rectangle instead of starting a
* drag; the raise that the press undid has to be put back, and this signal
* is emitted while that same press is still being dispatched. */
static void
icon_container_band_select_started_callback (NemoIconContainer *container,
NemoIconView *icon_view)
{
GtkWidget *toplevel;

toplevel = gtk_widget_get_toplevel (GTK_WIDGET (container));
if (NEMO_IS_WINDOW (toplevel)) {
nemo_window_dnd_source_release (NEMO_WINDOW (toplevel));
}
}

static NemoIconContainer *
create_icon_container (NemoIconView *icon_view)
{
Expand Down Expand Up @@ -2470,6 +2547,16 @@ create_icon_container (NemoIconView *icon_view)
G_CALLBACK (store_layout_timestamp), icon_view, 0);
g_signal_connect_object (icon_container, "check-filter-event",
G_CALLBACK (icon_container_activate_filter_cb), icon_view, 0);
g_signal_connect_object (icon_container, "drag_begin",
G_CALLBACK (icon_container_drag_begin_callback), icon_view, 0);
g_signal_connect_object (icon_container, "drag_end",
G_CALLBACK (icon_container_drag_end_callback), icon_view, 0);
g_signal_connect_object (icon_container, "button_press_event",
G_CALLBACK (icon_container_dnd_press_callback), icon_view, 0);
g_signal_connect_object (icon_container, "button_release_event",
G_CALLBACK (icon_container_dnd_release_callback), icon_view, 0);
g_signal_connect_object (icon_container, "band_select_started",
G_CALLBACK (icon_container_band_select_started_callback), icon_view, 0);

gtk_container_add (GTK_CONTAINER (icon_view),
GTK_WIDGET (icon_container));
Expand Down
65 changes: 64 additions & 1 deletion src/nemo-list-view.c
Original file line number Diff line number Diff line change
Expand Up @@ -606,9 +606,14 @@ drag_begin_callback (GtkWidget *widget,
NemoListView *view)
{
GList *ref_list;

GtkWidget *toplevel;
cairo_surface_t *surface;

toplevel = gtk_widget_get_toplevel (widget);
if (NEMO_IS_WINDOW (toplevel)) {
nemo_window_dnd_step_aside (NEMO_WINDOW (toplevel));
}

surface = get_drag_surface (view);
if (surface) {
gtk_drag_set_icon_surface (context, surface);
Expand All @@ -632,7 +637,61 @@ drag_end_callback (GtkWidget *widget,
GdkDragContext *context,
NemoListView *view)
{
GtkWidget *toplevel;

view->details->drag_started = FALSE;

toplevel = gtk_widget_get_toplevel (widget);
if (NEMO_IS_WINDOW (toplevel)) {
nemo_window_dnd_source_end (NEMO_WINDOW (toplevel));
}
}

static gboolean
list_view_dnd_press_callback (GtkWidget *widget,
GdkEventButton *event,
NemoListView *view)
{
GtkWidget *toplevel;
GtkTreePath *path = NULL;

if (event->button != 1)
return GDK_EVENT_PROPAGATE;

/* Only a press on a row can turn into a drag of that row. A press on
* empty space starts a selection rectangle instead, and the window must
* stay where the window manager put it. */
gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget),
event->x, event->y, &path, NULL, NULL, NULL);
if (path == NULL)
return GDK_EVENT_PROPAGATE;

gtk_tree_path_free (path);

toplevel = gtk_widget_get_toplevel (widget);
if (NEMO_IS_WINDOW (toplevel)) {
nemo_window_dnd_source_press (NEMO_WINDOW (toplevel));
}

return GDK_EVENT_PROPAGATE;
}

static gboolean
list_view_dnd_release_callback (GtkWidget *widget,
GdkEventButton *event,
NemoListView *view)
{
GtkWidget *toplevel;

if (event->button != 1)
return GDK_EVENT_PROPAGATE;

toplevel = gtk_widget_get_toplevel (widget);
if (NEMO_IS_WINDOW (toplevel)) {
nemo_window_dnd_source_release (NEMO_WINDOW (toplevel));
}

return GDK_EVENT_PROPAGATE;
}

static gboolean
Expand Down Expand Up @@ -2624,6 +2683,10 @@ create_and_set_up_tree_view (NemoListView *view)
G_CALLBACK (drag_begin_callback), view, 0);
g_signal_connect_object (view->details->tree_view, "drag-end",
G_CALLBACK (drag_end_callback), view, 0);
g_signal_connect_object (view->details->tree_view, "button_press_event",
G_CALLBACK (list_view_dnd_press_callback), view, 0);
g_signal_connect_object (view->details->tree_view, "button_release_event",
G_CALLBACK (list_view_dnd_release_callback), view, 0);
g_signal_connect_object (view->details->tree_view, "drag_data_get",
G_CALLBACK (drag_data_get_callback), view, 0);
g_signal_connect_object (view->details->tree_view, "motion_notify_event",
Expand Down
25 changes: 25 additions & 0 deletions src/nemo-window-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,31 @@ struct NemoWindowDetails
gint ignore_meta_sort_direction;

gboolean dynamic_menu_entries_current;

/* TRUE when a click on this window would raise it, i.e. the window
* does not currently have the toplevel focus. Sampled by the
* window's enter-notify/focus-out handlers and consumed by
* nemo_window_dnd_step_aside().
*/
gboolean dnd_raised_by_click;

/* TRUE while the window is sitting lower than it was because a drag
* started from it (see nemo_window_dnd_step_aside()). Consumed by
* nemo_window_dnd_source_end().
*/
gboolean dnd_stepped_aside;

/* TRUE between the press that started the current interaction and
* its release / drag end, i.e. a drag may still start from it.
*/
gboolean dnd_drag_started;

/* XID of the window stacked directly above this one at the moment the
* pointer arrived (0 when there was none), i.e. where this window sat
* before the click raised it. Used to put it back exactly there
* instead of on the bottom of the stack. X11 only.
*/
guint64 dnd_stack_sibling;
};

/* window geometry */
Expand Down
Loading