wayland: Refactor DnD target functions into MetaWaylandDragDestFuncs

This will be useful in order to interact with drag dest surfaces in
its windowing-specific ways, although everything defaults to the
wayland vfuncs.

https://bugzilla.gnome.org/show_bug.cgi?id=738312
This commit is contained in:
Carlos Garnacho 2015-05-18 13:24:27 +02:00
parent b62db404ee
commit f53eea2c1c
5 changed files with 167 additions and 37 deletions

View File

@ -36,12 +36,12 @@
#include "meta-wayland-private.h" #include "meta-wayland-private.h"
#include "meta-dnd-actor-private.h" #include "meta-dnd-actor-private.h"
typedef struct struct _MetaWaylandDataOffer
{ {
struct wl_resource *resource; struct wl_resource *resource;
MetaWaylandDataSource *source; MetaWaylandDataSource *source;
struct wl_listener source_destroy_listener; struct wl_listener source_destroy_listener;
} MetaWaylandDataOffer; };
static void static void
unbind_resource (struct wl_resource *resource) unbind_resource (struct wl_resource *resource)
@ -198,18 +198,13 @@ drag_grab_focus (MetaWaylandPointerGrab *grab,
MetaWaylandSeat *seat = drag_grab->seat; MetaWaylandSeat *seat = drag_grab->seat;
struct wl_client *client; struct wl_client *client;
struct wl_resource *data_device_resource, *offer = NULL; struct wl_resource *data_device_resource, *offer = NULL;
struct wl_display *display;
guint32 serial;
wl_fixed_t sx, sy;
if (drag_grab->drag_focus == surface) if (drag_grab->drag_focus == surface)
return; return;
if (drag_grab->drag_focus_data_device) if (drag_grab->drag_focus)
{ {
wl_data_device_send_leave (drag_grab->drag_focus_data_device); meta_wayland_surface_drag_dest_focus_out (drag_grab->drag_focus);
wl_list_remove (&drag_grab->drag_focus_listener.link);
drag_grab->drag_focus_data_device = NULL;
drag_grab->drag_focus = NULL; drag_grab->drag_focus = NULL;
} }
@ -223,25 +218,16 @@ drag_grab_focus (MetaWaylandPointerGrab *grab,
client = wl_resource_get_client (surface->resource); client = wl_resource_get_client (surface->resource);
data_device_resource = wl_resource_find_for_client (&seat->data_device.resource_list, client); data_device_resource = wl_resource_find_for_client (&seat->data_device.resource_list, client);
if (!data_device_resource)
return;
display = wl_client_get_display (client); if (drag_grab->drag_data_source && data_device_resource)
serial = wl_display_next_serial (display);
if (drag_grab->drag_data_source)
offer = meta_wayland_data_source_send_offer (drag_grab->drag_data_source, offer = meta_wayland_data_source_send_offer (drag_grab->drag_data_source,
data_device_resource); data_device_resource);
meta_wayland_pointer_get_relative_coordinates (grab->pointer, surface, &sx, &sy);
wl_data_device_send_enter (data_device_resource, serial, surface->resource,
sx, sy, offer);
drag_grab->drag_focus = surface; drag_grab->drag_focus = surface;
drag_grab->drag_focus_data_device = data_device_resource; drag_grab->drag_focus_data_device = data_device_resource;
drag_grab->drag_focus_listener.notify = destroy_drag_focus;
wl_resource_add_destroy_listener (data_device_resource, &drag_grab->drag_focus_listener); meta_wayland_surface_drag_dest_focus_in (drag_grab->drag_focus,
offer ? wl_resource_get_user_data (offer) : NULL);
} }
static void static void
@ -249,17 +235,9 @@ drag_grab_motion (MetaWaylandPointerGrab *grab,
const ClutterEvent *event) const ClutterEvent *event)
{ {
MetaWaylandDragGrab *drag_grab = (MetaWaylandDragGrab*) grab; MetaWaylandDragGrab *drag_grab = (MetaWaylandDragGrab*) grab;
wl_fixed_t sx, sy;
if (drag_grab->drag_focus_data_device) if (drag_grab->drag_focus)
{ meta_wayland_surface_drag_dest_motion (drag_grab->drag_focus, event);
meta_wayland_pointer_get_relative_coordinates (grab->pointer,
drag_grab->drag_focus,
&sx, &sy);
wl_data_device_send_motion (drag_grab->drag_focus_data_device,
clutter_event_get_time (event),
sx, sy);
}
if (drag_grab->drag_surface) if (drag_grab->drag_surface)
meta_feedback_actor_update (META_FEEDBACK_ACTOR (drag_grab->feedback_actor), meta_feedback_actor_update (META_FEEDBACK_ACTOR (drag_grab->feedback_actor),
@ -269,6 +247,8 @@ drag_grab_motion (MetaWaylandPointerGrab *grab,
static void static void
data_device_end_drag_grab (MetaWaylandDragGrab *drag_grab) data_device_end_drag_grab (MetaWaylandDragGrab *drag_grab)
{ {
drag_grab_focus (&drag_grab->generic, NULL);
if (drag_grab->drag_origin) if (drag_grab->drag_origin)
{ {
drag_grab->drag_origin = NULL; drag_grab->drag_origin = NULL;
@ -292,8 +272,6 @@ data_device_end_drag_grab (MetaWaylandDragGrab *drag_grab)
drag_grab->seat->data_device.current_grab = NULL; drag_grab->seat->data_device.current_grab = NULL;
drag_grab_focus (&drag_grab->generic, NULL);
meta_wayland_pointer_end_grab (drag_grab->generic.pointer); meta_wayland_pointer_end_grab (drag_grab->generic.pointer);
g_slice_free (MetaWaylandDragGrab, drag_grab); g_slice_free (MetaWaylandDragGrab, drag_grab);
} }
@ -311,10 +289,9 @@ drag_grab_button (MetaWaylandPointerGrab *grab,
{ {
gboolean success = FALSE; gboolean success = FALSE;
if (drag_grab->drag_focus_data_device && if (drag_grab->drag_data_source->has_target)
drag_grab->drag_data_source->has_target)
{ {
wl_data_device_send_drop (drag_grab->drag_focus_data_device); meta_wayland_surface_drag_dest_drop (drag_grab->drag_focus);
success = TRUE; success = TRUE;
} }
@ -353,6 +330,7 @@ destroy_data_device_source (struct wl_listener *listener, void *data)
wl_container_of (listener, drag_grab, drag_data_source_listener); wl_container_of (listener, drag_grab, drag_data_source_listener);
drag_grab->drag_data_source = NULL; drag_grab->drag_data_source = NULL;
drag_grab->seat->data_device.dnd_data_source = NULL;
data_device_end_drag_grab (drag_grab); data_device_end_drag_grab (drag_grab);
meta_wayland_data_device_set_dnd_source (&drag_grab->seat->data_device, NULL); meta_wayland_data_device_set_dnd_source (&drag_grab->seat->data_device, NULL);
} }
@ -509,6 +487,80 @@ static const MetaWaylandDataSourceFuncs meta_wayland_source_funcs = {
meta_wayland_source_cancel meta_wayland_source_cancel
}; };
static void
meta_wayland_drag_dest_focus_in (MetaWaylandDataDevice *data_device,
MetaWaylandSurface *surface,
MetaWaylandDataOffer *offer)
{
MetaWaylandDragGrab *grab = data_device->current_grab;
struct wl_display *display;
struct wl_client *client;
wl_fixed_t sx, sy;
client = wl_resource_get_client (surface->resource);
display = wl_client_get_display (client);
grab->drag_focus_listener.notify = destroy_drag_focus;
wl_resource_add_destroy_listener (grab->drag_focus_data_device,
&grab->drag_focus_listener);
meta_wayland_pointer_get_relative_coordinates (grab->generic.pointer,
surface, &sx, &sy);
wl_data_device_send_enter (grab->drag_focus_data_device,
wl_display_next_serial (display),
surface->resource, sx, sy, offer->resource);
}
static void
meta_wayland_drag_dest_focus_out (MetaWaylandDataDevice *data_device,
MetaWaylandSurface *surface)
{
MetaWaylandDragGrab *grab = data_device->current_grab;
wl_data_device_send_leave (grab->drag_focus_data_device);
wl_list_remove (&grab->drag_focus_listener.link);
grab->drag_focus_data_device = NULL;
}
static void
meta_wayland_drag_dest_motion (MetaWaylandDataDevice *data_device,
MetaWaylandSurface *surface,
const ClutterEvent *event)
{
MetaWaylandDragGrab *grab = data_device->current_grab;
wl_fixed_t sx, sy;
meta_wayland_pointer_get_relative_coordinates (grab->generic.pointer,
grab->drag_focus,
&sx, &sy);
wl_data_device_send_motion (grab->drag_focus_data_device,
clutter_event_get_time (event),
sx, sy);
}
static void
meta_wayland_drag_dest_drop (MetaWaylandDataDevice *data_device,
MetaWaylandSurface *surface)
{
MetaWaylandDragGrab *grab = data_device->current_grab;
wl_data_device_send_drop (grab->drag_focus_data_device);
}
static const MetaWaylandDragDestFuncs meta_wayland_drag_dest_funcs = {
meta_wayland_drag_dest_focus_in,
meta_wayland_drag_dest_focus_out,
meta_wayland_drag_dest_motion,
meta_wayland_drag_dest_drop
};
const MetaWaylandDragDestFuncs *
meta_wayland_data_device_get_drag_dest_funcs (void)
{
return &meta_wayland_drag_dest_funcs;
}
void void
meta_wayland_data_device_set_dnd_source (MetaWaylandDataDevice *data_device, meta_wayland_data_device_set_dnd_source (MetaWaylandDataDevice *data_device,
MetaWaylandDataSource *source) MetaWaylandDataSource *source)

View File

@ -93,4 +93,7 @@ void meta_wayland_data_source_send (MetaWaylandDataSource *source,
const gchar *mime_type, const gchar *mime_type,
gint fd); gint fd);
const MetaWaylandDragDestFuncs *
meta_wayland_data_device_get_drag_dest_funcs (void);
#endif /* META_WAYLAND_DATA_DEVICE_H */ #endif /* META_WAYLAND_DATA_DEVICE_H */

View File

@ -748,12 +748,19 @@ sync_reactive (MetaWaylandSurface *surface)
surface_should_be_reactive (surface)); surface_should_be_reactive (surface));
} }
static void
sync_drag_dest_funcs (MetaWaylandSurface *surface)
{
surface->dnd.funcs = meta_wayland_data_device_get_drag_dest_funcs ();
}
void void
meta_wayland_surface_set_window (MetaWaylandSurface *surface, meta_wayland_surface_set_window (MetaWaylandSurface *surface,
MetaWindow *window) MetaWindow *window)
{ {
surface->window = window; surface->window = window;
sync_reactive (surface); sync_reactive (surface);
sync_drag_dest_funcs (surface);
} }
static void static void
@ -816,6 +823,8 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor,
surface->buffer_destroy_listener.notify = surface_handle_buffer_destroy; surface->buffer_destroy_listener.notify = surface_handle_buffer_destroy;
surface->surface_actor = g_object_ref_sink (meta_surface_actor_wayland_new (surface)); surface->surface_actor = g_object_ref_sink (meta_surface_actor_wayland_new (surface));
sync_drag_dest_funcs (surface);
pending_state_init (&surface->pending); pending_state_init (&surface->pending);
return surface; return surface;
} }
@ -2043,3 +2052,41 @@ meta_wayland_surface_popup_done (MetaWaylandSurface *surface)
else if (surface->wl_shell_surface) else if (surface->wl_shell_surface)
wl_shell_surface_send_popup_done (surface->wl_shell_surface); wl_shell_surface_send_popup_done (surface->wl_shell_surface);
} }
void
meta_wayland_surface_drag_dest_focus_in (MetaWaylandSurface *surface,
MetaWaylandDataOffer *offer)
{
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
MetaWaylandDataDevice *data_device = &compositor->seat->data_device;
surface->dnd.funcs->focus_in (data_device, surface, offer);
}
void
meta_wayland_surface_drag_dest_motion (MetaWaylandSurface *surface,
const ClutterEvent *event)
{
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
MetaWaylandDataDevice *data_device = &compositor->seat->data_device;
surface->dnd.funcs->motion (data_device, surface, event);
}
void
meta_wayland_surface_drag_dest_focus_out (MetaWaylandSurface *surface)
{
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
MetaWaylandDataDevice *data_device = &compositor->seat->data_device;
surface->dnd.funcs->focus_out (data_device, surface);
}
void
meta_wayland_surface_drag_dest_drop (MetaWaylandSurface *surface)
{
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
MetaWaylandDataDevice *data_device = &compositor->seat->data_device;
surface->dnd.funcs->drop (data_device, surface);
}

View File

@ -71,6 +71,20 @@ typedef struct
gboolean has_new_geometry; gboolean has_new_geometry;
} MetaWaylandPendingState; } MetaWaylandPendingState;
struct _MetaWaylandDragDestFuncs
{
void (* focus_in) (MetaWaylandDataDevice *data_device,
MetaWaylandSurface *surface,
MetaWaylandDataOffer *offer);
void (* focus_out) (MetaWaylandDataDevice *data_device,
MetaWaylandSurface *surface);
void (* motion) (MetaWaylandDataDevice *data_device,
MetaWaylandSurface *surface,
const ClutterEvent *event);
void (* drop) (MetaWaylandDataDevice *data_device,
MetaWaylandSurface *surface);
};
struct _MetaWaylandSurface struct _MetaWaylandSurface
{ {
/* Generic stuff */ /* Generic stuff */
@ -87,6 +101,10 @@ struct _MetaWaylandSurface
int32_t offset_x, offset_y; int32_t offset_x, offset_y;
GList *subsurfaces; GList *subsurfaces;
struct {
const MetaWaylandDragDestFuncs *funcs;
} dnd;
/* All the pending state that wl_surface.commit will apply. */ /* All the pending state that wl_surface.commit will apply. */
MetaWaylandPendingState pending; MetaWaylandPendingState pending;
@ -161,4 +179,12 @@ void meta_wayland_surface_delete (MetaWaylandSurface *surface);
void meta_wayland_surface_popup_done (MetaWaylandSurface *surface); void meta_wayland_surface_popup_done (MetaWaylandSurface *surface);
/* Drag dest functions */
void meta_wayland_surface_drag_dest_focus_in (MetaWaylandSurface *surface,
MetaWaylandDataOffer *offer);
void meta_wayland_surface_drag_dest_motion (MetaWaylandSurface *surface,
const ClutterEvent *event);
void meta_wayland_surface_drag_dest_focus_out (MetaWaylandSurface *surface);
void meta_wayland_surface_drag_dest_drop (MetaWaylandSurface *surface);
#endif #endif

View File

@ -30,6 +30,8 @@ typedef struct _MetaWaylandPopupGrab MetaWaylandPopupGrab;
typedef struct _MetaWaylandPopup MetaWaylandPopup; typedef struct _MetaWaylandPopup MetaWaylandPopup;
typedef struct _MetaWaylandKeyboard MetaWaylandKeyboard; typedef struct _MetaWaylandKeyboard MetaWaylandKeyboard;
typedef struct _MetaWaylandTouch MetaWaylandTouch; typedef struct _MetaWaylandTouch MetaWaylandTouch;
typedef struct _MetaWaylandDragDestFuncs MetaWaylandDragDestFuncs;
typedef struct _MetaWaylandDataOffer MetaWaylandDataOffer;
typedef struct _MetaWaylandDataSource MetaWaylandDataSource; typedef struct _MetaWaylandDataSource MetaWaylandDataSource;
typedef struct _MetaWaylandDataDevice MetaWaylandDataDevice; typedef struct _MetaWaylandDataDevice MetaWaylandDataDevice;