forked from AuroraMiddleware/gtk
wayland: Split drop context into GdkWaylandDrop
GdkWaylandDrop no longer inherits from GdkDragContext now.
This commit is contained in:
parent
81e1dc9a66
commit
4eb3a9faaa
@ -246,7 +246,7 @@ struct _GdkWaylandSeat
|
||||
GdkClipboard *clipboard;
|
||||
GdkClipboard *primary_clipboard;
|
||||
struct wl_data_device *data_device;
|
||||
GdkDragContext *drop_context;
|
||||
GdkDrop *drop;
|
||||
|
||||
/* Source/dest for non-local dnd */
|
||||
GdkSurface *foreign_dnd_surface;
|
||||
@ -1140,8 +1140,6 @@ data_offer_source_actions (void *data,
|
||||
uint32_t source_actions)
|
||||
{
|
||||
GdkWaylandSeat *seat = data;
|
||||
GdkDragContext *drop_context;
|
||||
GdkDevice *device;
|
||||
|
||||
if (offer == seat->pending_offer)
|
||||
{
|
||||
@ -1149,16 +1147,12 @@ data_offer_source_actions (void *data,
|
||||
return;
|
||||
}
|
||||
|
||||
device = gdk_seat_get_pointer (GDK_SEAT (seat));
|
||||
drop_context = gdk_wayland_device_get_drop_context (device);
|
||||
if (drop_context == NULL)
|
||||
if (seat->drop == NULL)
|
||||
return;
|
||||
|
||||
gdk_drag_context_set_actions (drop_context,
|
||||
gdk_wayland_actions_to_gdk_actions (source_actions),
|
||||
gdk_drag_context_get_suggested_action (drop_context));
|
||||
gdk_wayland_drop_set_source_actions (seat->drop, source_actions);
|
||||
|
||||
gdk_drop_emit_motion_event (GDK_DROP (seat->drop_context),
|
||||
gdk_drop_emit_motion_event (seat->drop,
|
||||
FALSE,
|
||||
seat->pointer_info.surface_x,
|
||||
seat->pointer_info.surface_y,
|
||||
@ -1171,8 +1165,6 @@ data_offer_action (void *data,
|
||||
uint32_t action)
|
||||
{
|
||||
GdkWaylandSeat *seat = data;
|
||||
GdkDragContext *drop_context;
|
||||
GdkDevice *device;
|
||||
|
||||
if (offer == seat->pending_offer)
|
||||
{
|
||||
@ -1180,16 +1172,12 @@ data_offer_action (void *data,
|
||||
return;
|
||||
}
|
||||
|
||||
device = gdk_seat_get_pointer (GDK_SEAT (seat));
|
||||
drop_context = gdk_wayland_device_get_drop_context (device);
|
||||
if (drop_context == NULL)
|
||||
if (seat->drop == NULL)
|
||||
return;
|
||||
|
||||
gdk_drag_context_set_actions (drop_context,
|
||||
gdk_drag_context_get_actions (drop_context),
|
||||
gdk_wayland_actions_to_gdk_actions (action));
|
||||
gdk_wayland_drop_set_action (seat->drop, action);
|
||||
|
||||
gdk_drop_emit_motion_event (GDK_DROP (seat->drop_context),
|
||||
gdk_drop_emit_motion_event (seat->drop,
|
||||
FALSE,
|
||||
seat->pointer_info.surface_x,
|
||||
seat->pointer_info.surface_y,
|
||||
@ -1235,7 +1223,7 @@ data_device_enter (void *data,
|
||||
struct wl_data_offer *offer)
|
||||
{
|
||||
GdkWaylandSeat *seat = data;
|
||||
GdkSurface *dest_surface, *dnd_owner;
|
||||
GdkSurface *dest_surface;
|
||||
GdkContentFormats *formats;
|
||||
GdkDevice *device;
|
||||
|
||||
@ -1275,15 +1263,11 @@ data_device_enter (void *data,
|
||||
seat->pending_builder = NULL;
|
||||
seat->pending_offer = NULL;
|
||||
|
||||
seat->drop_context = _gdk_wayland_drop_context_new (device, formats, dest_surface, offer, serial);
|
||||
|
||||
dnd_owner = seat->foreign_dnd_surface;
|
||||
|
||||
_gdk_wayland_drag_context_set_source_surface (seat->drop_context, dnd_owner);
|
||||
seat->drop = gdk_wayland_drop_new (device, formats, dest_surface, offer, serial);
|
||||
|
||||
gdk_wayland_seat_discard_pending_offer (seat);
|
||||
|
||||
gdk_drop_emit_enter_event (GDK_DROP (seat->drop_context),
|
||||
gdk_drop_emit_enter_event (seat->drop,
|
||||
FALSE,
|
||||
GDK_CURRENT_TIME);
|
||||
}
|
||||
@ -1297,17 +1281,17 @@ data_device_leave (void *data,
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
g_message ("data device leave, data device %p", data_device));
|
||||
|
||||
if (seat->drop_context == NULL)
|
||||
if (seat->drop == NULL)
|
||||
return;
|
||||
|
||||
g_object_unref (seat->pointer_info.focus);
|
||||
seat->pointer_info.focus = NULL;
|
||||
|
||||
gdk_drop_emit_leave_event (GDK_DROP (seat->drop_context),
|
||||
gdk_drop_emit_leave_event (seat->drop,
|
||||
FALSE,
|
||||
GDK_CURRENT_TIME);
|
||||
|
||||
g_clear_object (&seat->drop_context);
|
||||
g_clear_object (&seat->drop);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1323,14 +1307,14 @@ data_device_motion (void *data,
|
||||
g_message ("data device motion, data_device = %p, time = %d, x = %f, y = %f",
|
||||
data_device, time, wl_fixed_to_double (x), wl_fixed_to_double (y)));
|
||||
|
||||
if (seat->drop_context == NULL)
|
||||
if (seat->drop == NULL)
|
||||
return;
|
||||
|
||||
/* Update pointer state, so device state queries work during DnD */
|
||||
seat->pointer_info.surface_x = wl_fixed_to_double (x);
|
||||
seat->pointer_info.surface_y = wl_fixed_to_double (y);
|
||||
|
||||
gdk_drop_emit_motion_event (GDK_DROP (seat->drop_context),
|
||||
gdk_drop_emit_motion_event (seat->drop,
|
||||
FALSE,
|
||||
seat->pointer_info.surface_x,
|
||||
seat->pointer_info.surface_y,
|
||||
@ -1346,7 +1330,7 @@ data_device_drop (void *data,
|
||||
GDK_DISPLAY_NOTE (seat->display, EVENTS,
|
||||
g_message ("data device drop, data device %p", data_device));
|
||||
|
||||
gdk_drop_emit_drop_event (GDK_DROP (seat->drop_context),
|
||||
gdk_drop_emit_drop_event (seat->drop,
|
||||
FALSE,
|
||||
seat->pointer_info.surface_x,
|
||||
seat->pointer_info.surface_y,
|
||||
@ -4613,7 +4597,7 @@ gdk_wayland_seat_finalize (GObject *object)
|
||||
gdk_wayland_pointer_data_finalize (&seat->pointer_info);
|
||||
/* FIXME: destroy data_device */
|
||||
g_clear_object (&seat->keyboard_settings);
|
||||
g_clear_object (&seat->drop_context);
|
||||
g_clear_object (&seat->drop);
|
||||
g_clear_object (&seat->clipboard);
|
||||
g_clear_object (&seat->primary_clipboard);
|
||||
g_hash_table_destroy (seat->touches);
|
||||
@ -5196,14 +5180,6 @@ gdk_wayland_seat_get_wl_seat (GdkSeat *seat)
|
||||
return GDK_WAYLAND_SEAT (seat)->wl_seat;
|
||||
}
|
||||
|
||||
GdkDragContext *
|
||||
gdk_wayland_device_get_drop_context (GdkDevice *device)
|
||||
{
|
||||
GdkSeat *seat = gdk_device_get_seat (device);
|
||||
|
||||
return GDK_WAYLAND_SEAT (seat)->drop_context;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_wayland_device_get_node_path:
|
||||
* @device: a #GdkDevice
|
||||
|
@ -120,159 +120,6 @@ gdk_wayland_drag_context_drag_drop (GdkDragContext *context,
|
||||
{
|
||||
}
|
||||
|
||||
/* Destination side */
|
||||
|
||||
static void
|
||||
gdk_wayland_drop_context_set_status (GdkWaylandDragContext *context_wayland,
|
||||
gboolean accepted)
|
||||
{
|
||||
if (accepted)
|
||||
{
|
||||
const char *const *mimetypes;
|
||||
gsize i, n_mimetypes;
|
||||
|
||||
mimetypes = gdk_content_formats_get_mime_types (gdk_drop_get_formats (GDK_DROP (context_wayland)), &n_mimetypes);
|
||||
for (i = 0; i < n_mimetypes; i++)
|
||||
{
|
||||
if (mimetypes[i] != g_intern_static_string ("DELETE"))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < n_mimetypes)
|
||||
{
|
||||
wl_data_offer_accept (context_wayland->offer, context_wayland->serial, mimetypes[i]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
wl_data_offer_accept (context_wayland->offer, context_wayland->serial, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_context_commit_status (GdkWaylandDragContext *wayland_context)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
uint32_t dnd_actions;
|
||||
|
||||
display = gdk_drop_get_display (GDK_DROP (wayland_context));
|
||||
|
||||
dnd_actions = gdk_to_wl_actions (wayland_context->selected_action);
|
||||
|
||||
if (GDK_WAYLAND_DISPLAY (display)->data_device_manager_version >=
|
||||
WL_DATA_OFFER_SET_ACTIONS_SINCE_VERSION)
|
||||
{
|
||||
if (gdk_drag_action_is_unique (wayland_context->selected_action))
|
||||
{
|
||||
wl_data_offer_set_actions (wayland_context->offer, dnd_actions, dnd_actions);
|
||||
}
|
||||
else
|
||||
{
|
||||
wl_data_offer_set_actions (wayland_context->offer,
|
||||
dnd_actions | WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK,
|
||||
WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK);
|
||||
}
|
||||
}
|
||||
|
||||
gdk_wayland_drop_context_set_status (wayland_context, wayland_context->selected_action != 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_context_status (GdkDrop *drop,
|
||||
GdkDragAction action)
|
||||
{
|
||||
GdkWaylandDragContext *wayland_context;
|
||||
|
||||
wayland_context = GDK_WAYLAND_DRAG_CONTEXT (drop);
|
||||
wayland_context->selected_action = action;
|
||||
|
||||
gdk_wayland_drag_context_commit_status (wayland_context);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_context_finish (GdkDrop *drop,
|
||||
GdkDragAction action)
|
||||
{
|
||||
GdkWaylandDragContext *wayland_context = GDK_WAYLAND_DRAG_CONTEXT (drop);
|
||||
GdkDisplay *display = gdk_drop_get_display (drop);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
|
||||
wayland_context->selected_action = action;
|
||||
|
||||
if (action)
|
||||
{
|
||||
gdk_wayland_drag_context_commit_status (wayland_context);
|
||||
|
||||
if (display_wayland->data_device_manager_version >=
|
||||
WL_DATA_OFFER_FINISH_SINCE_VERSION)
|
||||
wl_data_offer_finish (wayland_context->offer);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_context_read_async (GdkDrop *drop,
|
||||
GdkContentFormats *formats,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkWaylandDragContext *wayland_context = GDK_WAYLAND_DRAG_CONTEXT (drop);
|
||||
GdkDisplay *display;
|
||||
GInputStream *stream;
|
||||
const char *mime_type;
|
||||
int pipe_fd[2];
|
||||
GError *error = NULL;
|
||||
GTask *task;
|
||||
|
||||
display = gdk_drop_get_display (drop),
|
||||
task = g_task_new (drop, cancellable, callback, user_data);
|
||||
g_task_set_priority (task, io_priority);
|
||||
g_task_set_source_tag (task, gdk_wayland_drag_context_read_async);
|
||||
|
||||
GDK_DISPLAY_NOTE (display, DND, char *s = gdk_content_formats_to_string (formats);
|
||||
g_message ("%p: read for %s", drop, s);
|
||||
g_free (s); );
|
||||
mime_type = gdk_content_formats_match_mime_type (formats,
|
||||
gdk_drop_get_formats (drop));
|
||||
if (mime_type == NULL)
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("No compatible transfer format found"));
|
||||
return;
|
||||
}
|
||||
|
||||
g_task_set_task_data (task, (gpointer) mime_type, NULL);
|
||||
|
||||
if (!g_unix_open_pipe (pipe_fd, FD_CLOEXEC, &error))
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
return;
|
||||
}
|
||||
|
||||
wl_data_offer_receive (wayland_context->offer, mime_type, pipe_fd[1]);
|
||||
stream = g_unix_input_stream_new (pipe_fd[0], TRUE);
|
||||
close (pipe_fd[1]);
|
||||
g_task_return_pointer (task, stream, g_object_unref);
|
||||
}
|
||||
|
||||
static GInputStream *
|
||||
gdk_wayland_drag_context_read_finish (GdkDrop *drop,
|
||||
const char **out_mime_type,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
GTask *task;
|
||||
|
||||
g_return_val_if_fail (g_task_is_valid (result, G_OBJECT (drop)), NULL);
|
||||
task = G_TASK (result);
|
||||
g_return_val_if_fail (g_task_get_source_tag (task) == gdk_wayland_drag_context_read_async, NULL);
|
||||
|
||||
if (out_mime_type)
|
||||
*out_mime_type = g_task_get_task_data (task);
|
||||
|
||||
return g_task_propagate_pointer (task, error);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_context_init (GdkWaylandDragContext *context_wayland)
|
||||
{
|
||||
@ -361,16 +208,10 @@ static void
|
||||
gdk_wayland_drag_context_class_init (GdkWaylandDragContextClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkDropClass *drop_class = GDK_DROP_CLASS (klass);
|
||||
GdkDragContextClass *context_class = GDK_DRAG_CONTEXT_CLASS (klass);
|
||||
|
||||
object_class->finalize = gdk_wayland_drag_context_finalize;
|
||||
|
||||
drop_class->status = gdk_wayland_drag_context_status;
|
||||
drop_class->finish = gdk_wayland_drag_context_finish;
|
||||
drop_class->read_async = gdk_wayland_drag_context_read_async;
|
||||
drop_class->read_finish = gdk_wayland_drag_context_read_finish;
|
||||
|
||||
context_class->drag_abort = gdk_wayland_drag_context_drag_abort;
|
||||
context_class->drag_drop = gdk_wayland_drag_context_drag_drop;
|
||||
context_class->get_drag_surface = gdk_wayland_drag_context_get_drag_surface;
|
||||
@ -451,31 +292,6 @@ _gdk_wayland_surface_drag_begin (GdkSurface *surface,
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
GdkDragContext *
|
||||
_gdk_wayland_drop_context_new (GdkDevice *device,
|
||||
GdkContentFormats *formats,
|
||||
GdkSurface *surface,
|
||||
struct wl_data_offer *offer,
|
||||
uint32_t serial)
|
||||
|
||||
{
|
||||
GdkWaylandDragContext *context_wayland;
|
||||
GdkDragContext *context;
|
||||
|
||||
context_wayland = g_object_new (GDK_TYPE_WAYLAND_DRAG_CONTEXT,
|
||||
"device", device,
|
||||
"formats", formats,
|
||||
"surface", surface,
|
||||
NULL);
|
||||
context = GDK_DRAG_CONTEXT (context_wayland);
|
||||
context->is_source = FALSE;
|
||||
context_wayland->offer = offer;
|
||||
context_wayland->serial = serial;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_wayland_drag_context_set_source_surface (GdkDragContext *context,
|
||||
GdkSurface *surface)
|
||||
|
323
gdk/wayland/gdkdrop-wayland.c
Normal file
323
gdk/wayland/gdkdrop-wayland.c
Normal file
@ -0,0 +1,323 @@
|
||||
/*
|
||||
* Copyright © 2010 Intel Corporation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkdndprivate.h"
|
||||
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkproperty.h"
|
||||
#include "gdkprivate-wayland.h"
|
||||
#include "gdkcontentformats.h"
|
||||
#include "gdkdisplay-wayland.h"
|
||||
#include "gdkintl.h"
|
||||
#include "gdkseat-wayland.h"
|
||||
|
||||
#include "gdkdeviceprivate.h"
|
||||
|
||||
#include <glib-unix.h>
|
||||
#include <gio/gunixinputstream.h>
|
||||
#include <gio/gunixoutputstream.h>
|
||||
#include <string.h>
|
||||
|
||||
#define GDK_TYPE_WAYLAND_DROP (gdk_wayland_drop_get_type ())
|
||||
#define GDK_WAYLAND_DROP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_DROP, GdkWaylandDrop))
|
||||
#define GDK_WAYLAND_DROP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WAYLAND_DROP, GdkWaylandDropClass))
|
||||
#define GDK_IS_WAYLAND_DROP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_DROP))
|
||||
#define GDK_IS_WAYLAND_DROP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_WAYLAND_DROP))
|
||||
#define GDK_WAYLAND_DROP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WAYLAND_DROP, GdkWaylandDropClass))
|
||||
|
||||
typedef struct _GdkWaylandDrop GdkWaylandDrop;
|
||||
typedef struct _GdkWaylandDropClass GdkWaylandDropClass;
|
||||
|
||||
struct _GdkWaylandDrop
|
||||
{
|
||||
GdkDrop drop;
|
||||
|
||||
struct wl_data_offer *offer;
|
||||
uint32_t source_actions;
|
||||
uint32_t action;
|
||||
GdkDragAction selected_action;
|
||||
uint32_t serial;
|
||||
};
|
||||
|
||||
struct _GdkWaylandDropClass
|
||||
{
|
||||
GdkDropClass parent_class;
|
||||
};
|
||||
|
||||
GType gdk_wayland_drop_get_type (void);
|
||||
|
||||
G_DEFINE_TYPE (GdkWaylandDrop, gdk_wayland_drop, GDK_TYPE_DROP)
|
||||
|
||||
static void
|
||||
gdk_wayland_drop_finalize (GObject *object)
|
||||
{
|
||||
GdkWaylandDrop *wayland_drop = GDK_WAYLAND_DROP (object);
|
||||
|
||||
g_clear_pointer (&wayland_drop->offer, (GDestroyNotify) wl_data_offer_destroy);
|
||||
|
||||
G_OBJECT_CLASS (gdk_wayland_drop_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
gdk_to_wl_actions (GdkDragAction action)
|
||||
{
|
||||
uint32_t dnd_actions = 0;
|
||||
|
||||
if (action & (GDK_ACTION_COPY | GDK_ACTION_LINK))
|
||||
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;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drop_drop_set_status (GdkWaylandDrop *drop_wayland,
|
||||
gboolean accepted)
|
||||
{
|
||||
if (accepted)
|
||||
{
|
||||
const char *const *mimetypes;
|
||||
gsize i, n_mimetypes;
|
||||
|
||||
mimetypes = gdk_content_formats_get_mime_types (gdk_drop_get_formats (GDK_DROP (drop_wayland)), &n_mimetypes);
|
||||
for (i = 0; i < n_mimetypes; i++)
|
||||
{
|
||||
if (mimetypes[i] != g_intern_static_string ("DELETE"))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < n_mimetypes)
|
||||
{
|
||||
wl_data_offer_accept (drop_wayland->offer, drop_wayland->serial, mimetypes[i]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
wl_data_offer_accept (drop_wayland->offer, drop_wayland->serial, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drop_commit_status (GdkWaylandDrop *wayland_drop)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
uint32_t dnd_actions;
|
||||
|
||||
display = gdk_drop_get_display (GDK_DROP (wayland_drop));
|
||||
|
||||
dnd_actions = gdk_to_wl_actions (wayland_drop->selected_action);
|
||||
|
||||
if (GDK_WAYLAND_DISPLAY (display)->data_device_manager_version >=
|
||||
WL_DATA_OFFER_SET_ACTIONS_SINCE_VERSION)
|
||||
{
|
||||
if (gdk_drag_action_is_unique (wayland_drop->selected_action))
|
||||
{
|
||||
wl_data_offer_set_actions (wayland_drop->offer, dnd_actions, dnd_actions);
|
||||
}
|
||||
else
|
||||
{
|
||||
wl_data_offer_set_actions (wayland_drop->offer,
|
||||
dnd_actions | WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK,
|
||||
WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK);
|
||||
}
|
||||
}
|
||||
|
||||
gdk_wayland_drop_drop_set_status (wayland_drop, wayland_drop->selected_action != 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drop_status (GdkDrop *drop,
|
||||
GdkDragAction action)
|
||||
{
|
||||
GdkWaylandDrop *wayland_drop;
|
||||
|
||||
wayland_drop = GDK_WAYLAND_DROP (drop);
|
||||
wayland_drop->selected_action = action;
|
||||
|
||||
gdk_wayland_drop_commit_status (wayland_drop);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drop_finish (GdkDrop *drop,
|
||||
GdkDragAction action)
|
||||
{
|
||||
GdkWaylandDrop *wayland_drop = GDK_WAYLAND_DROP (drop);
|
||||
GdkDisplay *display = gdk_drop_get_display (drop);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
|
||||
wayland_drop->selected_action = action;
|
||||
|
||||
if (action)
|
||||
{
|
||||
gdk_wayland_drop_commit_status (wayland_drop);
|
||||
|
||||
if (display_wayland->data_device_manager_version >=
|
||||
WL_DATA_OFFER_FINISH_SINCE_VERSION)
|
||||
wl_data_offer_finish (wayland_drop->offer);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drop_read_async (GdkDrop *drop,
|
||||
GdkContentFormats *formats,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkWaylandDrop *wayland_drop = GDK_WAYLAND_DROP (drop);
|
||||
GdkDisplay *display;
|
||||
GInputStream *stream;
|
||||
const char *mime_type;
|
||||
int pipe_fd[2];
|
||||
GError *error = NULL;
|
||||
GTask *task;
|
||||
|
||||
display = gdk_drop_get_display (drop),
|
||||
task = g_task_new (drop, cancellable, callback, user_data);
|
||||
g_task_set_priority (task, io_priority);
|
||||
g_task_set_source_tag (task, gdk_wayland_drop_read_async);
|
||||
|
||||
GDK_DISPLAY_NOTE (display, DND, char *s = gdk_content_formats_to_string (formats);
|
||||
g_message ("%p: read for %s", drop, s);
|
||||
g_free (s); );
|
||||
mime_type = gdk_content_formats_match_mime_type (formats,
|
||||
gdk_drop_get_formats (drop));
|
||||
if (mime_type == NULL)
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("No compatible transfer format found"));
|
||||
return;
|
||||
}
|
||||
|
||||
g_task_set_task_data (task, (gpointer) mime_type, NULL);
|
||||
|
||||
if (!g_unix_open_pipe (pipe_fd, FD_CLOEXEC, &error))
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
return;
|
||||
}
|
||||
|
||||
wl_data_offer_receive (wayland_drop->offer, mime_type, pipe_fd[1]);
|
||||
stream = g_unix_input_stream_new (pipe_fd[0], TRUE);
|
||||
close (pipe_fd[1]);
|
||||
g_task_return_pointer (task, stream, g_object_unref);
|
||||
}
|
||||
|
||||
static GInputStream *
|
||||
gdk_wayland_drop_read_finish (GdkDrop *drop,
|
||||
const char **out_mime_type,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
GTask *task;
|
||||
|
||||
g_return_val_if_fail (g_task_is_valid (result, G_OBJECT (drop)), NULL);
|
||||
task = G_TASK (result);
|
||||
g_return_val_if_fail (g_task_get_source_tag (task) == gdk_wayland_drop_read_async, NULL);
|
||||
|
||||
if (out_mime_type)
|
||||
*out_mime_type = g_task_get_task_data (task);
|
||||
|
||||
return g_task_propagate_pointer (task, error);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drop_class_init (GdkWaylandDropClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkDropClass *drop_class = GDK_DROP_CLASS (klass);
|
||||
|
||||
object_class->finalize = gdk_wayland_drop_finalize;
|
||||
|
||||
drop_class->status = gdk_wayland_drop_status;
|
||||
drop_class->finish = gdk_wayland_drop_finish;
|
||||
drop_class->read_async = gdk_wayland_drop_read_async;
|
||||
drop_class->read_finish = gdk_wayland_drop_read_finish;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drop_init (GdkWaylandDrop *drop)
|
||||
{
|
||||
}
|
||||
|
||||
GdkDrop *
|
||||
gdk_wayland_drop_new (GdkDevice *device,
|
||||
GdkContentFormats *formats,
|
||||
GdkSurface *surface,
|
||||
struct wl_data_offer *offer,
|
||||
uint32_t serial)
|
||||
|
||||
{
|
||||
GdkWaylandDrop *drop;
|
||||
|
||||
drop = g_object_new (GDK_TYPE_WAYLAND_DROP,
|
||||
"device", device,
|
||||
"formats", formats,
|
||||
"surface", surface,
|
||||
NULL);
|
||||
drop->offer = offer;
|
||||
drop->serial = serial;
|
||||
|
||||
return GDK_DROP (drop);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drop_update_actions (GdkWaylandDrop *drop)
|
||||
{
|
||||
GdkDragAction gdk_actions = 0;
|
||||
uint32_t wl_actions;
|
||||
|
||||
if (drop->action & WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
|
||||
wl_actions = drop->source_actions;
|
||||
else
|
||||
wl_actions = drop->action;
|
||||
|
||||
if (wl_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY)
|
||||
gdk_actions |= GDK_ACTION_COPY;
|
||||
if (wl_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE)
|
||||
gdk_actions |= GDK_ACTION_MOVE;
|
||||
|
||||
gdk_drop_set_actions (GDK_DROP (drop), gdk_actions);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_wayland_drop_set_source_actions (GdkDrop *drop,
|
||||
uint32_t source_actions)
|
||||
{
|
||||
GdkWaylandDrop *wayland_drop = GDK_WAYLAND_DROP (drop);
|
||||
|
||||
wayland_drop->source_actions = source_actions;
|
||||
|
||||
gdk_wayland_drop_update_actions (wayland_drop);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_wayland_drop_set_action (GdkDrop *drop,
|
||||
uint32_t action)
|
||||
{
|
||||
GdkWaylandDrop *wayland_drop = GDK_WAYLAND_DROP (drop);
|
||||
|
||||
wayland_drop->action = action;
|
||||
|
||||
gdk_wayland_drop_update_actions (wayland_drop);
|
||||
}
|
||||
|
@ -104,11 +104,16 @@ GdkDragContext *_gdk_wayland_surface_drag_begin (GdkSurface *surface,
|
||||
void _gdk_wayland_surface_offset_next_wl_buffer (GdkSurface *surface,
|
||||
int x,
|
||||
int y);
|
||||
GdkDragContext * _gdk_wayland_drop_context_new (GdkDevice *device,
|
||||
GdkContentFormats *formats,
|
||||
GdkSurface *surface,
|
||||
struct wl_data_offer *offer,
|
||||
uint32_t serial);
|
||||
GdkDrop * gdk_wayland_drop_new (GdkDevice *device,
|
||||
GdkContentFormats *formats,
|
||||
GdkSurface *surface,
|
||||
struct wl_data_offer *offer,
|
||||
uint32_t serial);
|
||||
void gdk_wayland_drop_set_source_actions (GdkDrop *drop,
|
||||
uint32_t source_actions);
|
||||
void gdk_wayland_drop_set_action (GdkDrop *drop,
|
||||
uint32_t action);
|
||||
|
||||
void _gdk_wayland_drag_context_set_source_surface (GdkDragContext *context,
|
||||
GdkSurface *surface);
|
||||
|
||||
|
@ -6,6 +6,7 @@ gdk_wayland_sources = files([
|
||||
'gdkdevice-wayland.c',
|
||||
'gdkdisplay-wayland.c',
|
||||
'gdkdnd-wayland.c',
|
||||
'gdkdrop-wayland.c',
|
||||
'gdkeventsource.c',
|
||||
'gdkglcontext-wayland.c',
|
||||
'gdkkeys-wayland.c',
|
||||
|
Loading…
Reference in New Issue
Block a user