wayland: Get rid of GdkWaylandSelection

Move data source handling into the DND code instead.
This commit is contained in:
Benjamin Otte 2018-05-30 04:37:47 +02:00
parent 4eb3a9faaa
commit 7afa0badd8
5 changed files with 148 additions and 267 deletions

View File

@ -666,8 +666,6 @@ _gdk_wayland_display_open (const gchar *display_name)
return NULL;
}
display_wayland->selection = gdk_wayland_selection_new ();
gdk_display_emit_opened (display);
return display;
@ -693,12 +691,6 @@ gdk_wayland_display_dispose (GObject *object)
display_wayland->event_source = NULL;
}
if (display_wayland->selection)
{
gdk_wayland_selection_free (display_wayland->selection);
display_wayland->selection = NULL;
}
g_list_free_full (display_wayland->async_roundtrips, (GDestroyNotify) wl_callback_destroy);
if (display_wayland->known_globals)
@ -1356,15 +1348,6 @@ _gdk_wayland_is_shm_surface (cairo_surface_t *surface)
return cairo_surface_get_user_data (surface, &gdk_wayland_shm_surface_cairo_key) != NULL;
}
GdkWaylandSelection *
gdk_wayland_display_get_selection (GdkDisplay *display)
{
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
return display_wayland->selection;
}
typedef enum
{
GSD_FONT_ANTIALIASING_MODE_NONE,

View File

@ -139,8 +139,6 @@ struct _GdkWaylandDisplay
struct xkb_context *xkb_context;
GdkWaylandSelection *selection;
GPtrArray *monitors;
gint64 last_bell_time_ms;

View File

@ -77,10 +77,7 @@ gdk_wayland_drag_context_finalize (GObject *object)
contexts = g_list_remove (contexts, context);
if (context->is_source)
{
gdk_drag_context_set_cursor (context, NULL);
}
gdk_drag_context_set_cursor (context, NULL);
g_clear_pointer (&wayland_context->data_source, (GDestroyNotify) wl_data_source_destroy);
g_clear_pointer (&wayland_context->offer, (GDestroyNotify) wl_data_offer_destroy);
@ -240,19 +237,157 @@ create_dnd_surface (GdkDisplay *display)
return surface;
}
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_source_target (void *data,
struct wl_data_source *source,
const char *mime_type)
{
GDK_NOTE (EVENTS,
g_message ("data source target, source = %p, mime_type = %s",
source, mime_type));
}
static void
gdk_wayland_drag_context_write_done (GObject *context,
GAsyncResult *result,
gpointer user_data)
{
GError *error = NULL;
if (!gdk_drag_context_write_finish (GDK_DRAG_CONTEXT (context), result, &error))
{
GDK_DISPLAY_NOTE (gdk_drag_context_get_display (GDK_DRAG_CONTEXT (context)), DND, g_message ("%p: failed to write stream: %s", context, error->message));
g_error_free (error);
}
}
static void
data_source_send (void *data,
struct wl_data_source *source,
const char *mime_type,
int32_t fd)
{
GdkDragContext *context = data;
GOutputStream *stream;
GDK_DISPLAY_NOTE (gdk_drag_context_get_display (context), DND, g_message ("%p: data source send request for %s on fd %d\n",
source, mime_type, fd));
//mime_type = gdk_intern_mime_type (mime_type);
mime_type = g_intern_string (mime_type);
stream = g_unix_output_stream_new (fd, TRUE);
gdk_drag_context_write_async (context,
mime_type,
stream,
G_PRIORITY_DEFAULT,
NULL,
gdk_wayland_drag_context_write_done,
context);
g_object_unref (stream);
}
static void
data_source_cancelled (void *data,
struct wl_data_source *source)
{
GdkDragContext *context = data;
GDK_DISPLAY_NOTE (gdk_drag_context_get_display (context), EVENTS,
g_message ("data source cancelled, source = %p", source));
gdk_drag_context_cancel (context, GDK_DRAG_CANCEL_ERROR);
}
static void
data_source_dnd_drop_performed (void *data,
struct wl_data_source *source)
{
GdkDragContext *context = data;
g_signal_emit_by_name (context, "drop-performed", GDK_CURRENT_TIME);
}
static void
data_source_dnd_finished (void *data,
struct wl_data_source *source)
{
GdkDragContext *context = data;
g_signal_emit_by_name (context, "dnd-finished");
}
static void
data_source_action (void *data,
struct wl_data_source *source,
uint32_t action)
{
GdkDragContext *context = data;
GDK_DISPLAY_NOTE (gdk_drag_context_get_display (context), EVENTS,
g_message ("data source action, source = %p action=%x",
source, action));
context->action = _wl_to_gdk_actions (action);
g_signal_emit_by_name (context, "action-changed", context->action);
}
static const struct wl_data_source_listener data_source_listener = {
data_source_target,
data_source_send,
data_source_cancelled,
data_source_dnd_drop_performed,
data_source_dnd_finished,
data_source_action,
};
static void
gdk_wayland_drag_context_create_data_source (GdkDragContext *context)
{
GdkWaylandDragContext *context_wayland = GDK_WAYLAND_DRAG_CONTEXT (context);
GdkDisplay *display = gdk_drag_context_get_display (context);
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
const char *const *mimetypes;
gsize i, n_mimetypes;
context_wayland->data_source = wl_data_device_manager_create_data_source (display_wayland->data_device_manager);
wl_data_source_add_listener (context_wayland->data_source,
&data_source_listener,
context);
mimetypes = gdk_content_formats_get_mime_types (gdk_drag_context_get_formats (context), &n_mimetypes);
for (i = 0; i < n_mimetypes; i++)
{
wl_data_source_offer (context_wayland->data_source, mimetypes[i]);
}
}
GdkDragContext *
_gdk_wayland_surface_drag_begin (GdkSurface *surface,
GdkDevice *device,
GdkContentProvider *content,
GdkDragAction actions,
gint dx,
gint dy)
GdkDevice *device,
GdkContentProvider *content,
GdkDragAction actions,
gint dx,
gint dy)
{
GdkWaylandDragContext *context_wayland;
GdkDragContext *context;
GdkWaylandDisplay *display_wayland;
const char *const *mimetypes;
gsize i, n_mimetypes;
display_wayland = GDK_WAYLAND_DISPLAY (gdk_device_get_display (device));
@ -266,13 +401,8 @@ _gdk_wayland_surface_drag_begin (GdkSurface *surface,
context_wayland->dnd_surface = create_dnd_surface (gdk_surface_get_display (surface));
context_wayland->dnd_wl_surface = gdk_wayland_surface_get_wl_surface (context_wayland->dnd_surface);
context_wayland->data_source = gdk_wayland_selection_get_data_source (surface);
mimetypes = gdk_content_formats_get_mime_types (gdk_drag_context_get_formats (context), &n_mimetypes);
for (i = 0; i < n_mimetypes; i++)
{
wl_data_source_offer (context_wayland->data_source, mimetypes[i]);
}
gdk_wayland_drag_context_create_data_source (context);
if (display_wayland->data_device_manager_version >=
WL_DATA_SOURCE_SET_ACTIONS_SINCE_VERSION)
@ -302,19 +432,3 @@ _gdk_wayland_drag_context_set_source_surface (GdkDragContext *context,
context->source_surface = surface ? g_object_ref (surface) : NULL;
}
GdkDragContext *
gdk_wayland_drag_context_lookup_by_data_source (struct wl_data_source *source)
{
GList *l;
for (l = contexts; l; l = l->next)
{
GdkWaylandDragContext *wayland_context = l->data;
if (wayland_context->data_source == source)
return l->data;
}
return NULL;
}

View File

@ -117,8 +117,6 @@ void gdk_wayland_drop_set_action (GdkDrop
void _gdk_wayland_drag_context_set_source_surface (GdkDragContext *context,
GdkSurface *surface);
GdkDragContext * gdk_wayland_drag_context_lookup_by_data_source (struct wl_data_source *source);
void _gdk_wayland_display_create_surface_impl (GdkDisplay *display,
GdkSurface *surface,
GdkSurface *real_parent,
@ -185,14 +183,6 @@ cairo_surface_t * _gdk_wayland_display_create_shm_surface (GdkWaylandDisplay *di
struct wl_buffer *_gdk_wayland_shm_surface_get_wl_buffer (cairo_surface_t *surface);
gboolean _gdk_wayland_is_shm_surface (cairo_surface_t *surface);
GdkWaylandSelection * gdk_wayland_display_get_selection (GdkDisplay *display);
GdkWaylandSelection * gdk_wayland_selection_new (void);
void gdk_wayland_selection_free (GdkWaylandSelection *selection);
struct wl_data_source * gdk_wayland_selection_get_data_source (GdkSurface *owner);
void gdk_wayland_selection_unset_data_source (GdkDisplay *display);
EGLSurface gdk_wayland_surface_get_egl_surface (GdkSurface *surface,
EGLConfig config);
EGLSurface gdk_wayland_surface_get_dummy_egl_surface (GdkSurface *surface,

View File

@ -33,210 +33,6 @@
#include <string.h>
struct _GdkWaylandSelection
{
struct wl_data_source *dnd_source; /* Owned by the GdkDragContext */
};
GdkWaylandSelection *
gdk_wayland_selection_new (void)
{
GdkWaylandSelection *selection;
selection = g_new0 (GdkWaylandSelection, 1);
return selection;
}
void
gdk_wayland_selection_free (GdkWaylandSelection *selection)
{
if (selection->dnd_source)
wl_data_source_destroy (selection->dnd_source);
g_free (selection);
}
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_source_target (void *data,
struct wl_data_source *source,
const char *mime_type)
{
GDK_NOTE (EVENTS,
g_message ("data source target, source = %p, mime_type = %s",
source, mime_type));
}
static void
gdk_wayland_drag_context_write_done (GObject *context,
GAsyncResult *result,
gpointer user_data)
{
GError *error = NULL;
if (!gdk_drag_context_write_finish (GDK_DRAG_CONTEXT (context), result, &error))
{
GDK_DISPLAY_NOTE (gdk_drag_context_get_display (GDK_DRAG_CONTEXT (context)), DND, g_message ("%p: failed to write stream: %s", context, error->message));
g_error_free (error);
}
}
static void
data_source_send (void *data,
struct wl_data_source *source,
const char *mime_type,
int32_t fd)
{
GdkDragContext *context;
GOutputStream *stream;
context = gdk_wayland_drag_context_lookup_by_data_source (source);
if (!context)
return;
GDK_DISPLAY_NOTE (gdk_drag_context_get_display (context), DND, g_message ("%p: data source send request for %s on fd %d\n",
source, mime_type, fd));
//mime_type = gdk_intern_mime_type (mime_type);
mime_type = g_intern_string (mime_type);
stream = g_unix_output_stream_new (fd, TRUE);
gdk_drag_context_write_async (context,
mime_type,
stream,
G_PRIORITY_DEFAULT,
NULL,
gdk_wayland_drag_context_write_done,
context);
g_object_unref (stream);
}
static void
data_source_cancelled (void *data,
struct wl_data_source *source)
{
GdkWaylandSelection *wayland_selection = data;
GdkDragContext *context;
GdkDisplay *display;
display = gdk_display_get_default ();
GDK_DISPLAY_NOTE (display, EVENTS,
g_message ("data source cancelled, source = %p", source));
if (source != wayland_selection->dnd_source)
return;
context = gdk_wayland_drag_context_lookup_by_data_source (source);
if (context)
gdk_drag_context_cancel (context, GDK_DRAG_CANCEL_ERROR);
gdk_wayland_selection_unset_data_source (display);
}
static void
data_source_dnd_drop_performed (void *data,
struct wl_data_source *source)
{
GdkDragContext *context;
context = gdk_wayland_drag_context_lookup_by_data_source (source);
if (!context)
return;
g_signal_emit_by_name (context, "drop-performed", GDK_CURRENT_TIME);
}
static void
data_source_dnd_finished (void *data,
struct wl_data_source *source)
{
GdkDragContext *context;
context = gdk_wayland_drag_context_lookup_by_data_source (source);
if (!context)
return;
g_signal_emit_by_name (context, "dnd-finished");
}
static void
data_source_action (void *data,
struct wl_data_source *source,
uint32_t action)
{
GdkDragContext *context;
context = gdk_wayland_drag_context_lookup_by_data_source (source);
if (!context)
return;
GDK_DISPLAY_NOTE (gdk_drag_context_get_display (context), EVENTS,
g_message ("data source action, source = %p action=%x",
source, action));
context->action = _wl_to_gdk_actions (action);
g_signal_emit_by_name (context, "action-changed", context->action);
}
static const struct wl_data_source_listener data_source_listener = {
data_source_target,
data_source_send,
data_source_cancelled,
data_source_dnd_drop_performed,
data_source_dnd_finished,
data_source_action,
};
struct wl_data_source *
gdk_wayland_selection_get_data_source (GdkSurface *owner)
{
GdkDisplay *display = gdk_surface_get_display (owner);
GdkWaylandSelection *wayland_selection = gdk_wayland_display_get_selection (display);
gpointer source = NULL;
GdkWaylandDisplay *display_wayland;
if (wayland_selection->dnd_source)
return wayland_selection->dnd_source;
display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (owner));
source = wl_data_device_manager_create_data_source (display_wayland->data_device_manager);
wl_data_source_add_listener (source,
&data_source_listener,
wayland_selection);
wayland_selection->dnd_source = source;
return source;
}
void
gdk_wayland_selection_unset_data_source (GdkDisplay *display)
{
GdkWaylandSelection *wayland_selection = gdk_wayland_display_get_selection (display);
wayland_selection->dnd_source = NULL;
}
gint
_gdk_wayland_display_text_property_to_utf8_list (GdkDisplay *display,
GdkAtom encoding,