dnd: Implement DnD handling code in Wayland
No XDnD events which notify DnD status change comes in Wayland. To emulate XDnD behavior, MetaDnd checks whether there is a grab or not when the modal window starts showing. When there is a grab, it processes the raw events from compositor, and emits DnD signals for plugin. https://bugzilla.gnome.org/show_bug.cgi?id=765003
This commit is contained in:
parent
5fafaf92df
commit
65e9c89ed9
@ -27,4 +27,8 @@ gboolean meta_dnd_handle_xdnd_event (MetaBackend *backend,
|
|||||||
MetaDisplay *display,
|
MetaDisplay *display,
|
||||||
XEvent *xev);
|
XEvent *xev);
|
||||||
|
|
||||||
|
#ifdef HAVE_WAYLAND
|
||||||
|
void meta_dnd_wayland_handle_begin_modal (MetaCompositor *compositor);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* META_DND_PRIVATE_H */
|
#endif /* META_DND_PRIVATE_H */
|
||||||
|
@ -71,6 +71,7 @@
|
|||||||
#include "window-private.h" /* to check window->hidden */
|
#include "window-private.h" /* to check window->hidden */
|
||||||
#include "display-private.h" /* for meta_display_lookup_x_window() and meta_display_cancel_touch() */
|
#include "display-private.h" /* for meta_display_lookup_x_window() and meta_display_cancel_touch() */
|
||||||
#include "util-private.h"
|
#include "util-private.h"
|
||||||
|
#include "backends/meta-dnd-private.h"
|
||||||
#include "frame.h"
|
#include "frame.h"
|
||||||
#include <X11/extensions/shape.h>
|
#include <X11/extensions/shape.h>
|
||||||
#include <X11/extensions/Xcomposite.h>
|
#include <X11/extensions/Xcomposite.h>
|
||||||
@ -386,6 +387,8 @@ meta_begin_modal_for_plugin (MetaCompositor *compositor,
|
|||||||
{
|
{
|
||||||
meta_display_sync_wayland_input_focus (display);
|
meta_display_sync_wayland_input_focus (display);
|
||||||
meta_display_cancel_touch (display);
|
meta_display_cancel_touch (display);
|
||||||
|
|
||||||
|
meta_dnd_wayland_handle_begin_modal (compositor);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -33,12 +33,34 @@ struct _MetaDndClass
|
|||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef HAVE_WAYLAND
|
||||||
|
#include "wayland/meta-wayland-private.h"
|
||||||
|
#include "wayland/meta-wayland-data-device.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct _MetaDndPrivate MetaDndPrivate;
|
||||||
|
|
||||||
|
struct _MetaDndPrivate
|
||||||
|
{
|
||||||
|
#ifdef HAVE_WAYLAND
|
||||||
|
gulong handler_id[3];
|
||||||
|
|
||||||
|
MetaCompositor *compositor;
|
||||||
|
MetaWaylandCompositor *wl_compositor;
|
||||||
|
#else
|
||||||
|
/* to avoid warnings (g_type_class_add_private: assertion `private_size > 0' failed) */
|
||||||
|
gchar dummy;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
struct _MetaDnd
|
struct _MetaDnd
|
||||||
{
|
{
|
||||||
GObject parent;
|
GObject parent;
|
||||||
|
|
||||||
|
MetaDndPrivate *priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (MetaDnd, meta_dnd, G_TYPE_OBJECT);
|
G_DEFINE_TYPE_WITH_PRIVATE (MetaDnd, meta_dnd, G_TYPE_OBJECT);
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@ -169,3 +191,99 @@ meta_dnd_handle_xdnd_event (MetaBackend *backend,
|
|||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_WAYLAND
|
||||||
|
static void
|
||||||
|
meta_dnd_wayland_on_motion_event (ClutterActor *actor,
|
||||||
|
ClutterEvent *event,
|
||||||
|
MetaDnd *dnd)
|
||||||
|
{
|
||||||
|
MetaDndPrivate *priv = meta_dnd_get_instance_private (dnd);
|
||||||
|
MetaWaylandDragGrab *current_grab;
|
||||||
|
gfloat event_x, event_y;
|
||||||
|
|
||||||
|
g_return_if_fail (event != NULL);
|
||||||
|
|
||||||
|
clutter_event_get_coords (event, &event_x, &event_y);
|
||||||
|
meta_dnd_notify_dnd_position_change (dnd, (int)event_x, (int)event_y);
|
||||||
|
|
||||||
|
current_grab = meta_wayland_data_device_get_current_grab (&priv->wl_compositor->seat->data_device);
|
||||||
|
if (current_grab)
|
||||||
|
meta_wayland_drag_grab_update_feedback_actor (current_grab, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_dnd_wayland_end_notify (ClutterActor *actor,
|
||||||
|
ClutterEvent *event,
|
||||||
|
MetaDnd *dnd)
|
||||||
|
{
|
||||||
|
MetaDndPrivate *priv = meta_dnd_get_instance_private (dnd);
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
meta_wayland_data_device_end_drag (&priv->wl_compositor->seat->data_device);
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (priv->handler_id); i++)
|
||||||
|
{
|
||||||
|
g_signal_handler_disconnect (priv->compositor->stage, priv->handler_id[i]);
|
||||||
|
priv->handler_id[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->compositor = NULL;
|
||||||
|
priv->wl_compositor = NULL;
|
||||||
|
|
||||||
|
meta_dnd_notify_dnd_leave (dnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_dnd_wayland_on_button_released (ClutterActor *actor,
|
||||||
|
ClutterEvent *event,
|
||||||
|
MetaDnd *dnd)
|
||||||
|
{
|
||||||
|
meta_dnd_wayland_end_notify (actor, event, dnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_dnd_wayland_on_key_pressed (ClutterActor *actor,
|
||||||
|
ClutterEvent *event,
|
||||||
|
MetaDnd *dnd)
|
||||||
|
{
|
||||||
|
guint key = clutter_event_get_key_symbol (event);
|
||||||
|
|
||||||
|
if (key != CLUTTER_KEY_Escape)
|
||||||
|
return;
|
||||||
|
|
||||||
|
meta_dnd_wayland_end_notify (actor, event, dnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_dnd_wayland_handle_begin_modal (MetaCompositor *compositor)
|
||||||
|
{
|
||||||
|
MetaWaylandCompositor *wl_compositor = meta_wayland_compositor_get_default ();
|
||||||
|
MetaDnd *dnd = meta_backend_get_dnd (meta_get_backend ());
|
||||||
|
MetaDndPrivate *priv = meta_dnd_get_instance_private (dnd);
|
||||||
|
|
||||||
|
if (priv->handler_id[0] == 0 &&
|
||||||
|
meta_wayland_data_device_get_current_grab (&wl_compositor->seat->data_device) != NULL)
|
||||||
|
{
|
||||||
|
priv->compositor = compositor;
|
||||||
|
priv->wl_compositor = wl_compositor;
|
||||||
|
|
||||||
|
priv->handler_id[0] = g_signal_connect (compositor->stage,
|
||||||
|
"motion-event",
|
||||||
|
G_CALLBACK (meta_dnd_wayland_on_motion_event),
|
||||||
|
dnd);
|
||||||
|
|
||||||
|
priv->handler_id[1] = g_signal_connect (compositor->stage,
|
||||||
|
"button-release-event",
|
||||||
|
G_CALLBACK (meta_dnd_wayland_on_button_released),
|
||||||
|
dnd);
|
||||||
|
|
||||||
|
priv->handler_id[2] = g_signal_connect (compositor->stage,
|
||||||
|
"key-press-event",
|
||||||
|
G_CALLBACK (meta_dnd_wayland_on_key_pressed),
|
||||||
|
dnd);
|
||||||
|
|
||||||
|
meta_dnd_notify_dnd_enter (dnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@ -816,6 +816,14 @@ meta_wayland_drag_grab_get_focus (MetaWaylandDragGrab *drag_grab)
|
|||||||
return drag_grab->drag_focus;
|
return drag_grab->drag_focus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_drag_grab_update_feedback_actor (MetaWaylandDragGrab *drag_grab,
|
||||||
|
ClutterEvent *event)
|
||||||
|
{
|
||||||
|
meta_feedback_actor_update (META_FEEDBACK_ACTOR (drag_grab->feedback_actor),
|
||||||
|
event);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
drag_grab_focus (MetaWaylandPointerGrab *grab,
|
drag_grab_focus (MetaWaylandPointerGrab *grab,
|
||||||
MetaWaylandSurface *surface)
|
MetaWaylandSurface *surface)
|
||||||
@ -1899,6 +1907,12 @@ meta_wayland_data_device_is_dnd_surface (MetaWaylandDataDevice *data_device,
|
|||||||
data_device->current_grab->drag_surface == surface;
|
data_device->current_grab->drag_surface == surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MetaWaylandDragGrab *
|
||||||
|
meta_wayland_data_device_get_current_grab (MetaWaylandDataDevice *data_device)
|
||||||
|
{
|
||||||
|
return data_device->current_grab;
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
meta_wayland_data_source_has_mime_type (const MetaWaylandDataSource *source,
|
meta_wayland_data_source_has_mime_type (const MetaWaylandDataSource *source,
|
||||||
const gchar *mime_type)
|
const gchar *mime_type)
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
|
|
||||||
#include "meta-wayland-types.h"
|
#include "meta-wayland-types.h"
|
||||||
|
#include "clutter/clutter.h"
|
||||||
|
|
||||||
typedef struct _MetaWaylandDragGrab MetaWaylandDragGrab;
|
typedef struct _MetaWaylandDragGrab MetaWaylandDragGrab;
|
||||||
typedef struct _MetaWaylandDataSourceFuncs MetaWaylandDataSourceFuncs;
|
typedef struct _MetaWaylandDataSourceFuncs MetaWaylandDataSourceFuncs;
|
||||||
@ -79,6 +80,9 @@ void meta_wayland_data_device_set_keyboard_focus (MetaWaylandDataDevice *data_de
|
|||||||
gboolean meta_wayland_data_device_is_dnd_surface (MetaWaylandDataDevice *data_device,
|
gboolean meta_wayland_data_device_is_dnd_surface (MetaWaylandDataDevice *data_device,
|
||||||
MetaWaylandSurface *surface);
|
MetaWaylandSurface *surface);
|
||||||
|
|
||||||
|
MetaWaylandDragGrab *
|
||||||
|
meta_wayland_data_device_get_current_grab (MetaWaylandDataDevice *data_device);
|
||||||
|
|
||||||
void meta_wayland_data_device_set_dnd_source (MetaWaylandDataDevice *data_device,
|
void meta_wayland_data_device_set_dnd_source (MetaWaylandDataDevice *data_device,
|
||||||
MetaWaylandDataSource *source);
|
MetaWaylandDataSource *source);
|
||||||
void meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device,
|
void meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device,
|
||||||
@ -133,5 +137,7 @@ void meta_wayland_drag_grab_set_focus (MetaWaylandDragGrab
|
|||||||
MetaWaylandSurface *surface);
|
MetaWaylandSurface *surface);
|
||||||
MetaWaylandSurface *
|
MetaWaylandSurface *
|
||||||
meta_wayland_drag_grab_get_focus (MetaWaylandDragGrab *drag_grab);
|
meta_wayland_drag_grab_get_focus (MetaWaylandDragGrab *drag_grab);
|
||||||
|
void meta_wayland_drag_grab_update_feedback_actor (MetaWaylandDragGrab *drag_grab,
|
||||||
|
ClutterEvent *event);
|
||||||
|
|
||||||
#endif /* META_WAYLAND_DATA_DEVICE_H */
|
#endif /* META_WAYLAND_DATA_DEVICE_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user