Compare commits
4 Commits
sort-list-
...
wip/waylan
Author | SHA1 | Date | |
---|---|---|---|
|
fd3e02c7c2 | ||
|
86c18a807a | ||
|
0aeebf691f | ||
|
69f3b7dbc5 |
@@ -2247,3 +2247,14 @@ gdk_wayland_device_unset_grab (GdkDevice *gdk_device)
|
||||
|
||||
_gdk_wayland_display_deliver_event (gdk_device_get_display (gdk_device), event);
|
||||
}
|
||||
|
||||
GdkDragContext *
|
||||
gdk_wayland_device_get_drop_context (GdkDevice *gdk_device)
|
||||
{
|
||||
GdkWaylandDeviceData *device;
|
||||
|
||||
g_return_if_fail (GDK_IS_WAYLAND_DEVICE (gdk_device));
|
||||
device = GDK_WAYLAND_DEVICE (gdk_device)->device;
|
||||
|
||||
return device->drop_context;
|
||||
}
|
||||
|
@@ -350,7 +350,7 @@ gdk_registry_handle_global (void *data,
|
||||
else if (strcmp (interface, "wl_data_device_manager") == 0)
|
||||
{
|
||||
display_wayland->data_device_manager =
|
||||
wl_registry_bind (display_wayland->wl_registry, id, &wl_data_device_manager_interface, 1);
|
||||
wl_registry_bind (display_wayland->wl_registry, id, &wl_data_device_manager_interface, 3);
|
||||
}
|
||||
else if (strcmp (interface, "wl_subcompositor") == 0)
|
||||
{
|
||||
|
@@ -43,6 +43,7 @@ struct _GdkWaylandDragContext
|
||||
GdkWindow *dnd_window;
|
||||
struct wl_surface *dnd_surface;
|
||||
struct wl_data_source *data_source;
|
||||
GdkDragAction selected_action;
|
||||
uint32_t serial;
|
||||
gdouble x;
|
||||
gdouble y;
|
||||
@@ -143,11 +144,30 @@ gdk_wayland_drag_context_find_window (GdkDragContext *context,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_wayland_drag_context_set_action (GdkDragContext *context,
|
||||
GdkDragAction action)
|
||||
static inline uint32_t
|
||||
gdk_to_wl_actions (GdkDragAction action)
|
||||
{
|
||||
context->suggested_action = context->action = action;
|
||||
uint32_t dnd_actions = 0;
|
||||
|
||||
if (action & (GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_PRIVATE))
|
||||
dnd_actions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
|
||||
if (action & GDK_ACTION_MOVE)
|
||||
dnd_actions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
|
||||
if (action & GDK_ACTION_ASK)
|
||||
dnd_actions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK;
|
||||
|
||||
return dnd_actions;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_wayland_drag_context_set_actions (GdkDragContext *context,
|
||||
GdkDragAction actions)
|
||||
{
|
||||
GdkWaylandDragContext *wayland_context = GDK_WAYLAND_DRAG_CONTEXT (context);
|
||||
|
||||
context->actions = actions;
|
||||
wl_data_source_set_actions (wayland_context->data_source,
|
||||
gdk_to_wl_actions (actions));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -167,7 +187,7 @@ gdk_wayland_drag_context_drag_motion (GdkDragContext *context,
|
||||
_gdk_wayland_drag_context_emit_event (context, GDK_DRAG_STATUS, time);
|
||||
}
|
||||
|
||||
gdk_wayland_drag_context_set_action (context, suggested_action);
|
||||
gdk_wayland_drag_context_set_actions (context, possible_actions);
|
||||
|
||||
return context->dest_window != NULL;
|
||||
}
|
||||
@@ -196,6 +216,9 @@ gdk_wayland_drop_context_set_status (GdkDragContext *context,
|
||||
|
||||
context_wayland = GDK_WAYLAND_DRAG_CONTEXT (context);
|
||||
|
||||
if (!context->dest_window)
|
||||
return;
|
||||
|
||||
display = gdk_device_get_display (gdk_drag_context_get_device (context));
|
||||
wl_offer = gdk_wayland_selection_get_offer (display,
|
||||
gdk_drag_get_selection (context));
|
||||
@@ -231,7 +254,11 @@ gdk_wayland_drag_context_drag_status (GdkDragContext *context,
|
||||
GdkDragAction action,
|
||||
guint32 time_)
|
||||
{
|
||||
gdk_wayland_drop_context_set_status (context, action != 0);
|
||||
|
||||
GdkWaylandDragContext *wayland_context;
|
||||
|
||||
wayland_context = GDK_WAYLAND_DRAG_CONTEXT (context);
|
||||
wayland_context->selected_action = action;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -485,3 +512,19 @@ gdk_wayland_drag_context_get_dnd_window (GdkDragContext *context)
|
||||
wayland_context = GDK_WAYLAND_DRAG_CONTEXT (context);
|
||||
return wayland_context->dnd_window;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_wayland_drag_context_commit_status (GdkDragContext *context)
|
||||
{
|
||||
GdkWaylandDragContext *wayland_context;
|
||||
GdkDisplay *display;
|
||||
uint32_t dnd_actions;
|
||||
|
||||
wayland_context = GDK_WAYLAND_DRAG_CONTEXT (context);
|
||||
display = gdk_device_get_display (gdk_drag_context_get_device (context));
|
||||
|
||||
dnd_actions = gdk_to_wl_actions (wayland_context->selected_action);
|
||||
gdk_wayland_selection_set_current_offer_actions (display, dnd_actions);
|
||||
|
||||
gdk_wayland_drop_context_set_status (context, wayland_context->selected_action != 0);
|
||||
}
|
||||
|
@@ -118,8 +118,8 @@ void _gdk_wayland_drag_context_set_coords (GdkDragContext *context,
|
||||
gdouble x,
|
||||
gdouble y);
|
||||
|
||||
void gdk_wayland_drag_context_set_action (GdkDragContext *context,
|
||||
GdkDragAction action);
|
||||
void gdk_wayland_drag_context_set_actions (GdkDragContext *context,
|
||||
GdkDragAction actions);
|
||||
|
||||
GdkDragContext * gdk_wayland_drag_context_lookup_by_data_source (struct wl_data_source *source);
|
||||
GdkDragContext * gdk_wayland_drag_context_lookup_by_source_window (GdkWindow *window);
|
||||
@@ -184,6 +184,7 @@ uint32_t _gdk_wayland_device_get_last_implicit_grab_serial (GdkWaylandDevice *d
|
||||
struct wl_data_device * gdk_wayland_device_get_data_device (GdkDevice *gdk_device);
|
||||
void gdk_wayland_device_set_selection (GdkDevice *gdk_device,
|
||||
struct wl_data_source *source);
|
||||
GdkDragContext * gdk_wayland_device_get_drop_context (GdkDevice *gdk_device);
|
||||
|
||||
void gdk_wayland_device_unset_grab (GdkDevice *device);
|
||||
|
||||
@@ -255,6 +256,8 @@ void gdk_wayland_selection_store (GdkWindow *window,
|
||||
struct wl_data_source * gdk_wayland_selection_get_data_source (GdkWindow *owner,
|
||||
GdkAtom selection);
|
||||
void gdk_wayland_selection_unset_data_source (GdkDisplay *display, GdkAtom selection);
|
||||
gboolean gdk_wayland_selection_set_current_offer_actions (GdkDisplay *display,
|
||||
uint32_t actions);
|
||||
|
||||
EGLSurface gdk_wayland_window_get_egl_surface (GdkWindow *window,
|
||||
EGLConfig config);
|
||||
|
@@ -350,8 +350,69 @@ data_offer_offer (void *data,
|
||||
info->targets = g_list_prepend (info->targets, atom);
|
||||
}
|
||||
|
||||
static inline GdkDragAction
|
||||
_wl_to_gdk_actions (uint32_t dnd_actions)
|
||||
{
|
||||
GdkDragAction actions = 0;
|
||||
|
||||
if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY)
|
||||
actions |= GDK_ACTION_COPY;
|
||||
if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE)
|
||||
actions |= GDK_ACTION_MOVE;
|
||||
if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
|
||||
actions |= GDK_ACTION_ASK;
|
||||
|
||||
return actions;
|
||||
}
|
||||
|
||||
static void
|
||||
data_offer_source_actions (void *data,
|
||||
struct wl_data_offer *wl_data_offer,
|
||||
uint32_t source_actions)
|
||||
{
|
||||
GdkDeviceManager *device_manager;
|
||||
GdkDragContext *drop_context;
|
||||
GdkDisplay *display;
|
||||
GdkDevice *device;
|
||||
|
||||
display = gdk_display_get_default ();
|
||||
device_manager = gdk_display_get_device_manager (display);
|
||||
device = gdk_device_manager_get_client_pointer (device_manager);
|
||||
drop_context = gdk_wayland_device_get_drop_context (device);
|
||||
|
||||
drop_context->actions = _wl_to_gdk_actions (source_actions);
|
||||
|
||||
if (gdk_drag_context_get_dest_window (drop_context))
|
||||
_gdk_wayland_drag_context_emit_event (drop_context, GDK_DRAG_MOTION,
|
||||
GDK_CURRENT_TIME);
|
||||
}
|
||||
|
||||
static void
|
||||
data_offer_action (void *data,
|
||||
struct wl_data_offer *wl_data_offer,
|
||||
uint32_t action)
|
||||
{
|
||||
GdkDeviceManager *device_manager;
|
||||
GdkDragContext *drop_context;
|
||||
GdkDisplay *display;
|
||||
GdkDevice *device;
|
||||
|
||||
display = gdk_display_get_default ();
|
||||
device_manager = gdk_display_get_device_manager (display);
|
||||
device = gdk_device_manager_get_client_pointer (device_manager);
|
||||
drop_context = gdk_wayland_device_get_drop_context (device);
|
||||
|
||||
drop_context->action = _wl_to_gdk_actions (action);
|
||||
|
||||
if (gdk_drag_context_get_dest_window (drop_context))
|
||||
_gdk_wayland_drag_context_emit_event (drop_context, GDK_DRAG_MOTION,
|
||||
GDK_CURRENT_TIME);
|
||||
}
|
||||
|
||||
static const struct wl_data_offer_listener data_offer_listener = {
|
||||
data_offer_offer,
|
||||
data_offer_source_actions,
|
||||
data_offer_action
|
||||
};
|
||||
|
||||
DataOfferData *
|
||||
@@ -406,7 +467,6 @@ gdk_wayland_selection_set_offer (GdkDisplay *display,
|
||||
else if (selection_atom == atoms[ATOM_DND])
|
||||
selection->dnd_offer = info;
|
||||
|
||||
/* Clear all buffers */
|
||||
g_hash_table_remove_all (selection->selection_buffers);
|
||||
}
|
||||
|
||||
@@ -569,6 +629,9 @@ gdk_wayland_selection_store (GdkWindow *window,
|
||||
GdkWaylandSelection *selection = gdk_wayland_display_get_selection (display);
|
||||
GArray *array;
|
||||
|
||||
if (type == gdk_atom_intern_static_string ("NULL"))
|
||||
return;
|
||||
|
||||
array = g_array_new (TRUE, FALSE, sizeof (guchar));
|
||||
g_array_append_vals (array, data, len);
|
||||
|
||||
@@ -715,18 +778,15 @@ data_source_target (void *data,
|
||||
if (!mime_type)
|
||||
{
|
||||
if (context)
|
||||
{
|
||||
gdk_wayland_drag_context_set_action (context, 0);
|
||||
_gdk_wayland_drag_context_emit_event (context, GDK_DRAG_STATUS,
|
||||
GDK_CURRENT_TIME);
|
||||
}
|
||||
_gdk_wayland_drag_context_emit_event (context, GDK_DRAG_STATUS,
|
||||
GDK_CURRENT_TIME);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (source == wayland_selection->dnd_source)
|
||||
{
|
||||
window = wayland_selection->dnd_owner;
|
||||
gdk_wayland_drag_context_set_action (context, GDK_ACTION_COPY);
|
||||
_gdk_wayland_drag_context_emit_event (context, GDK_DRAG_STATUS,
|
||||
GDK_CURRENT_TIME);
|
||||
}
|
||||
@@ -748,7 +808,6 @@ data_source_send (void *data,
|
||||
int32_t fd)
|
||||
{
|
||||
GdkWaylandSelection *wayland_selection = data;
|
||||
GdkDragContext *context;
|
||||
GdkWindow *window;
|
||||
|
||||
g_debug (G_STRLOC ": %s source = %p, mime_type = %s, fd = %d",
|
||||
@@ -760,8 +819,6 @@ data_source_send (void *data,
|
||||
return;
|
||||
}
|
||||
|
||||
context = gdk_wayland_drag_context_lookup_by_data_source (source);
|
||||
|
||||
if (source == wayland_selection->dnd_source)
|
||||
window = wayland_selection->dnd_owner;
|
||||
else if (source == wayland_selection->clipboard_source)
|
||||
@@ -779,13 +836,6 @@ data_source_send (void *data,
|
||||
gdk_atom_intern (mime_type, FALSE),
|
||||
fd))
|
||||
gdk_wayland_selection_check_write (wayland_selection);
|
||||
|
||||
if (context)
|
||||
{
|
||||
gdk_wayland_device_unset_grab (gdk_drag_context_get_device (context));
|
||||
_gdk_wayland_drag_context_emit_event (context, GDK_DROP_FINISHED,
|
||||
GDK_CURRENT_TIME);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -814,10 +864,62 @@ data_source_cancelled (void *data,
|
||||
gdk_wayland_selection_unset_data_source (display, atoms[ATOM_CLIPBOARD]);
|
||||
}
|
||||
|
||||
static void
|
||||
data_source_action (void *data,
|
||||
struct wl_data_source *source,
|
||||
uint32_t action)
|
||||
{
|
||||
GdkDragContext *context;
|
||||
|
||||
g_debug (G_STRLOC ": %s source = %p action=%x",
|
||||
G_STRFUNC, source, action);
|
||||
|
||||
context = gdk_wayland_drag_context_lookup_by_data_source (source);
|
||||
|
||||
if (context)
|
||||
{
|
||||
context->action = _wl_to_gdk_actions (action);
|
||||
_gdk_wayland_drag_context_emit_event (context, GDK_DRAG_STATUS,
|
||||
GDK_CURRENT_TIME);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
data_source_drop_performed (void *data,
|
||||
struct wl_data_source *source)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
data_source_drag_finished (void *data,
|
||||
struct wl_data_source *source)
|
||||
{
|
||||
GdkDragContext *context;
|
||||
|
||||
context = gdk_wayland_drag_context_lookup_by_data_source (source);
|
||||
|
||||
if (!context)
|
||||
return;
|
||||
|
||||
if (context->action == GDK_ACTION_MOVE)
|
||||
{
|
||||
gdk_wayland_selection_emit_request (context->source_window,
|
||||
atoms[ATOM_DND],
|
||||
gdk_atom_intern_static_string ("DELETE"));
|
||||
}
|
||||
|
||||
gdk_wayland_device_unset_grab (gdk_drag_context_get_device (context));
|
||||
_gdk_wayland_drag_context_emit_event (context, GDK_DROP_FINISHED,
|
||||
GDK_CURRENT_TIME);
|
||||
}
|
||||
|
||||
static const struct wl_data_source_listener data_source_listener = {
|
||||
data_source_target,
|
||||
data_source_send,
|
||||
data_source_cancelled
|
||||
data_source_cancelled,
|
||||
data_source_action,
|
||||
data_source_drop_performed,
|
||||
data_source_drag_finished
|
||||
};
|
||||
|
||||
struct wl_data_source *
|
||||
@@ -1015,7 +1117,7 @@ _gdk_wayland_display_convert_selection (GdkDisplay *display,
|
||||
offer = gdk_wayland_selection_get_offer (display, selection);
|
||||
target_list = gdk_wayland_selection_get_targets (display, selection);
|
||||
|
||||
if (!offer)
|
||||
if (!offer || target == gdk_atom_intern_static_string ("DELETE"))
|
||||
{
|
||||
GdkEvent *event;
|
||||
|
||||
@@ -1192,3 +1294,24 @@ gdk_wayland_selection_clear_targets (GdkDisplay *display,
|
||||
g_array_set_size (wayland_selection->source_targets, 0);
|
||||
gdk_wayland_selection_unset_data_source (display, selection);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_wayland_selection_set_current_offer_actions (GdkDisplay *display,
|
||||
uint32_t action)
|
||||
{
|
||||
struct wl_data_offer *offer;
|
||||
uint32_t all_actions = 0;
|
||||
|
||||
offer = gdk_wayland_selection_get_offer (display, atoms[ATOM_DND]);
|
||||
|
||||
if (!offer)
|
||||
return FALSE;
|
||||
|
||||
if (action != 0)
|
||||
all_actions = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY |
|
||||
WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE |
|
||||
WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK;
|
||||
|
||||
wl_data_offer_set_actions (offer, all_actions, action);
|
||||
return TRUE;
|
||||
}
|
||||
|
@@ -52,6 +52,11 @@ GDK_AVAILABLE_IN_ALL
|
||||
GdkWindow *
|
||||
gdk_wayland_drag_context_get_dnd_window (GdkDragContext *context);
|
||||
|
||||
#define gdk_wayland_drag_context_commit_status gdk_wayland_drag_context_commit_status_libgtk_only
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void
|
||||
gdk_wayland_drag_context_commit_status (GdkDragContext *context);
|
||||
|
||||
#endif
|
||||
|
||||
G_END_DECLS
|
||||
|
30
gtk/gtkdnd.c
30
gtk/gtkdnd.c
@@ -786,7 +786,7 @@ gtk_drag_can_use_rgba_cursor (GdkDisplay *display,
|
||||
gint height)
|
||||
{
|
||||
guint max_width, max_height;
|
||||
|
||||
|
||||
if (!gdk_display_supports_cursor_color (display))
|
||||
return FALSE;
|
||||
|
||||
@@ -805,6 +805,25 @@ gtk_drag_can_use_rgba_cursor (GdkDisplay *display,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_drag_cursor_can_merge_drag_icon (GdkDisplay *display,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
/* On wayland all benefits from merging the drag icon into
|
||||
* the cursor are moot, and furthermore the compositor is
|
||||
* responsible of running any "drag cancelled" animations,
|
||||
* which we won't get for free unless we use the drag
|
||||
* surface.
|
||||
*/
|
||||
if (GDK_IS_WAYLAND_DISPLAY (display))
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
return gtk_drag_can_use_rgba_cursor (display, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_drag_cursor_pixbuf (int i)
|
||||
{
|
||||
@@ -927,7 +946,7 @@ gtk_drag_get_cursor (GtkWidget *widget,
|
||||
width = ref_x + MAX (cursor_width - hot_x, icon_width - icon_x);
|
||||
height = ref_y + MAX (cursor_height - hot_y, icon_height - icon_y);
|
||||
|
||||
if (gtk_drag_can_use_rgba_cursor (display, width * scale, height * scale))
|
||||
if (gtk_drag_cursor_can_merge_drag_icon (display, width * scale, height * scale))
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
@@ -1696,6 +1715,11 @@ _gtk_drag_dest_handle_event (GtkWidget *toplevel,
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
if (GDK_IS_WAYLAND_DISPLAY (gtk_widget_get_display (toplevel)))
|
||||
gdk_wayland_drag_context_commit_status (context);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3128,7 +3152,7 @@ set_icon_helper (GdkDragContext *context,
|
||||
&width, &height);
|
||||
|
||||
if (!force_window &&
|
||||
gtk_drag_can_use_rgba_cursor (display, width + 2, height + 2))
|
||||
gtk_drag_cursor_can_merge_drag_icon (display, width + 2, height + 2))
|
||||
{
|
||||
GtkDragSourceInfo *info;
|
||||
|
||||
|
Reference in New Issue
Block a user