mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-28 14:31:10 +00:00
wayland: Get rid of GdkWaylandSelection
Move data source handling into the DND code instead.
This commit is contained in:
parent
4eb3a9faaa
commit
7afa0badd8
@ -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,
|
||||
|
@ -139,8 +139,6 @@ struct _GdkWaylandDisplay
|
||||
|
||||
struct xkb_context *xkb_context;
|
||||
|
||||
GdkWaylandSelection *selection;
|
||||
|
||||
GPtrArray *monitors;
|
||||
|
||||
gint64 last_bell_time_ms;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
g_clear_pointer (&wayland_context->data_source, (GDestroyNotify) wl_data_source_destroy);
|
||||
g_clear_pointer (&wayland_context->offer, (GDestroyNotify) wl_data_offer_destroy);
|
||||
@ -240,6 +237,146 @@ 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,
|
||||
@ -251,8 +388,6 @@ _gdk_wayland_surface_drag_begin (GdkSurface *surface,
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user