wayland/xdg-toplevel-drag: Plumb xdg-toplevel-drag to core/compositor
- Event stream adaptations. When there is a toplevel-drag in place, do: - Send wl_data_source.dnd_finished and end the session successfully - Send wl_data_source.cancelled and end the MetaWindowDrag when ESC key is pressed. - Modify MetaWaylandDataDevice such that, when a toplevel-drag is running, it does: - Propagate motion events, so that they can be processed further by MetaWindowDrag. - Ends the associated MetaWindowDrag upon release event. - Hook up the window mapping process in MetaWindowWayand, such that: - the initial position of the window attached to the ongoing toplevel-drag instance can be calculated and set. - the appropriate gravity and flags can be set when calling MetaWindow's meta_window_move_resize_internal, which allows it for example to be moved freely (unconstrained) as per current dragging cursor. Status: - [x] Basic window drag triggering - [x] Exclude the dragged window from event targets - [x] Event forwarding (window drag vs wayland grabs) - [x] Offset calc relative to toplevel geometry - [x] Attach already mapped windows - [x] Properly support not-yet-mapped windows - [x] Disable visibility change animations - [x] Dnd events stream adaptations Signed-off-by: Nick Diego Yamane <nickdiego@igalia.com> Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4107>
This commit is contained in:
parent
66cfbf03c9
commit
0111f0de14
@ -36,14 +36,20 @@
|
|||||||
|
|
||||||
#include "backends/meta-dnd-private.h"
|
#include "backends/meta-dnd-private.h"
|
||||||
#include "compositor/meta-dnd-actor-private.h"
|
#include "compositor/meta-dnd-actor-private.h"
|
||||||
|
#include "compositor/meta-surface-actor.h"
|
||||||
|
#include "compositor/meta-window-drag.h"
|
||||||
#include "core/meta-selection-private.h"
|
#include "core/meta-selection-private.h"
|
||||||
|
#include "meta/meta-debug.h"
|
||||||
#include "meta/meta-selection-source-memory.h"
|
#include "meta/meta-selection-source-memory.h"
|
||||||
|
#include "meta/meta-wayland-surface.h"
|
||||||
#include "wayland/meta-selection-source-wayland-private.h"
|
#include "wayland/meta-selection-source-wayland-private.h"
|
||||||
|
#include "wayland/meta-wayland-data-source.h"
|
||||||
#include "wayland/meta-wayland-dnd-surface.h"
|
#include "wayland/meta-wayland-dnd-surface.h"
|
||||||
#include "wayland/meta-wayland-pointer.h"
|
#include "wayland/meta-wayland-pointer.h"
|
||||||
#include "wayland/meta-wayland-private.h"
|
#include "wayland/meta-wayland-private.h"
|
||||||
#include "wayland/meta-wayland-seat.h"
|
#include "wayland/meta-wayland-seat.h"
|
||||||
#include "wayland/meta-wayland-toplevel-drag.h"
|
#include "wayland/meta-wayland-toplevel-drag.h"
|
||||||
|
#include "wayland/meta-wayland-types.h"
|
||||||
|
|
||||||
#define ROOTWINDOW_DROP_MIME "application/x-rootwindow-drop"
|
#define ROOTWINDOW_DROP_MIME "application/x-rootwindow-drop"
|
||||||
|
|
||||||
@ -510,6 +516,12 @@ data_device_update_position (MetaWaylandDragGrab *drag_grab,
|
|||||||
meta_wayland_surface_set_main_monitor (drag_grab->drag_surface, monitor);
|
meta_wayland_surface_set_main_monitor (drag_grab->drag_surface, monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
is_dragging_window (MetaWaylandSeat *seat)
|
||||||
|
{
|
||||||
|
return meta_wayland_data_device_get_toplevel_drag (&seat->data_device) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
drag_grab_motion (MetaWaylandEventHandler *handler,
|
drag_grab_motion (MetaWaylandEventHandler *handler,
|
||||||
const ClutterEvent *event,
|
const ClutterEvent *event,
|
||||||
@ -540,7 +552,7 @@ drag_grab_motion (MetaWaylandEventHandler *handler,
|
|||||||
|
|
||||||
meta_dnd_wayland_on_motion_event (meta_backend_get_dnd (backend), event);
|
meta_dnd_wayland_on_motion_event (meta_backend_get_dnd (backend), event);
|
||||||
|
|
||||||
return CLUTTER_EVENT_STOP;
|
return !is_dragging_window (drag_grab->seat);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -551,6 +563,7 @@ drag_grab_release (MetaWaylandEventHandler *handler,
|
|||||||
MetaWaylandDragGrab *drag_grab = user_data;
|
MetaWaylandDragGrab *drag_grab = user_data;
|
||||||
MetaWaylandSeat *seat = drag_grab->seat;
|
MetaWaylandSeat *seat = drag_grab->seat;
|
||||||
MetaWaylandDataSource *source = drag_grab->drag_data_source;
|
MetaWaylandDataSource *source = drag_grab->drag_data_source;
|
||||||
|
MetaWaylandToplevelDrag *toplevel_drag;
|
||||||
gboolean success;
|
gboolean success;
|
||||||
|
|
||||||
if (drag_grab->device != clutter_event_get_device (event) ||
|
if (drag_grab->device != clutter_event_get_device (event) ||
|
||||||
@ -565,12 +578,22 @@ drag_grab_release (MetaWaylandEventHandler *handler,
|
|||||||
CLUTTER_BUTTON5_MASK)) > 1)
|
CLUTTER_BUTTON5_MASK)) > 1)
|
||||||
return CLUTTER_EVENT_STOP;
|
return CLUTTER_EVENT_STOP;
|
||||||
|
|
||||||
|
toplevel_drag = meta_wayland_data_device_get_toplevel_drag (&seat->data_device);
|
||||||
|
if (toplevel_drag)
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_WAYLAND, "Will end xdg_toplevel_drag#%u.",
|
||||||
|
wl_resource_get_id (toplevel_drag->resource));
|
||||||
|
meta_wayland_data_source_notify_drop_performed (source);
|
||||||
|
meta_wayland_toplevel_drag_end (toplevel_drag);
|
||||||
|
}
|
||||||
|
|
||||||
if (drag_grab->drag_focus && source &&
|
if (drag_grab->drag_focus && source &&
|
||||||
meta_wayland_data_source_has_target (source) &&
|
meta_wayland_data_source_has_target (source) &&
|
||||||
meta_wayland_data_source_get_current_action (source))
|
meta_wayland_data_source_get_current_action (source))
|
||||||
{
|
{
|
||||||
meta_wayland_surface_drag_dest_drop (drag_grab->drag_focus);
|
meta_wayland_surface_drag_dest_drop (drag_grab->drag_focus);
|
||||||
meta_wayland_data_source_notify_drop_performed (source);
|
if (!meta_wayland_data_source_get_drop_performed (source))
|
||||||
|
meta_wayland_data_source_notify_drop_performed (source);
|
||||||
|
|
||||||
meta_wayland_data_source_update_in_ask (source);
|
meta_wayland_data_source_update_in_ask (source);
|
||||||
success = TRUE;
|
success = TRUE;
|
||||||
@ -609,11 +632,20 @@ drag_grab_key (MetaWaylandEventHandler *handler,
|
|||||||
const ClutterEvent *event,
|
const ClutterEvent *event,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
|
MetaWaylandToplevelDrag *toplevel_drag;
|
||||||
MetaWaylandDragGrab *drag_grab = user_data;
|
MetaWaylandDragGrab *drag_grab = user_data;
|
||||||
ClutterModifierType modifiers;
|
ClutterModifierType modifiers;
|
||||||
|
|
||||||
if (clutter_event_get_key_symbol (event) == CLUTTER_KEY_Escape)
|
if (clutter_event_get_key_symbol (event) == CLUTTER_KEY_Escape)
|
||||||
{
|
{
|
||||||
|
toplevel_drag = meta_wayland_data_device_get_toplevel_drag (&drag_grab->seat->data_device);
|
||||||
|
if (toplevel_drag)
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_WAYLAND, "Will cancel xdg_toplevel_drag#%u.",
|
||||||
|
wl_resource_get_id (toplevel_drag->resource));
|
||||||
|
meta_wayland_toplevel_drag_end (toplevel_drag);
|
||||||
|
}
|
||||||
|
|
||||||
meta_wayland_data_device_set_dnd_source (&drag_grab->seat->data_device,
|
meta_wayland_data_device_set_dnd_source (&drag_grab->seat->data_device,
|
||||||
NULL);
|
NULL);
|
||||||
unset_selection_source (&drag_grab->seat->data_device, META_SELECTION_DND);
|
unset_selection_source (&drag_grab->seat->data_device, META_SELECTION_DND);
|
||||||
@ -1309,3 +1341,12 @@ meta_wayland_data_device_unset_dnd_selection (MetaWaylandDataDevice *data_device
|
|||||||
{
|
{
|
||||||
unset_selection_source (data_device, META_SELECTION_DND);
|
unset_selection_source (data_device, META_SELECTION_DND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MetaWaylandToplevelDrag *
|
||||||
|
meta_wayland_data_device_get_toplevel_drag (MetaWaylandDataDevice *data_device)
|
||||||
|
{
|
||||||
|
if (!data_device->current_grab || !data_device->current_grab->drag_data_source)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return meta_wayland_data_source_get_toplevel_drag (data_device->current_grab->drag_data_source);
|
||||||
|
}
|
||||||
|
@ -87,6 +87,9 @@ void meta_wayland_data_device_start_drag (MetaWaylandDataDevice *data_
|
|||||||
|
|
||||||
void meta_wayland_data_device_end_drag (MetaWaylandDataDevice *data_device);
|
void meta_wayland_data_device_end_drag (MetaWaylandDataDevice *data_device);
|
||||||
|
|
||||||
|
MetaWaylandToplevelDrag *
|
||||||
|
meta_wayland_data_device_get_toplevel_drag (MetaWaylandDataDevice *data_device);
|
||||||
|
|
||||||
void meta_wayland_drag_grab_set_focus (MetaWaylandDragGrab *drag_grab,
|
void meta_wayland_drag_grab_set_focus (MetaWaylandDragGrab *drag_grab,
|
||||||
MetaWaylandSurface *surface);
|
MetaWaylandSurface *surface);
|
||||||
MetaWaylandSurface *
|
MetaWaylandSurface *
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
#include "wayland/meta-wayland-actor-surface.h"
|
#include "wayland/meta-wayland-actor-surface.h"
|
||||||
#include "wayland/meta-wayland-private.h"
|
#include "wayland/meta-wayland-private.h"
|
||||||
#include "wayland/meta-wayland-surface-private.h"
|
#include "wayland/meta-wayland-surface-private.h"
|
||||||
|
#include "wayland/meta-wayland-toplevel-drag.h"
|
||||||
#include "wayland/meta-wayland-window-configuration.h"
|
#include "wayland/meta-wayland-window-configuration.h"
|
||||||
#include "wayland/meta-wayland-xdg-shell.h"
|
#include "wayland/meta-wayland-xdg-shell.h"
|
||||||
|
|
||||||
@ -732,6 +733,21 @@ on_window_shown (MetaWindow *window)
|
|||||||
meta_compositor_sync_updates_frozen (window->display->compositor, window);
|
meta_compositor_sync_updates_frozen (window->display->compositor, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MetaWaylandToplevelDrag *
|
||||||
|
get_toplevel_drag (MetaWindow *window)
|
||||||
|
{
|
||||||
|
MetaWaylandToplevelDrag *toplevel_drag;
|
||||||
|
MetaWindowWayland *wl_window = META_WINDOW_WAYLAND (window);
|
||||||
|
MetaDisplay *display = meta_window_get_display (window);
|
||||||
|
MetaContext *context = meta_display_get_context (display);
|
||||||
|
MetaWaylandCompositor *compositor = meta_context_get_wayland_compositor (context);
|
||||||
|
|
||||||
|
toplevel_drag = meta_wayland_data_device_get_toplevel_drag (&compositor->seat->data_device);
|
||||||
|
if (!toplevel_drag || toplevel_drag->dragged_surface != wl_window->surface)
|
||||||
|
return NULL;
|
||||||
|
return toplevel_drag;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_window_wayland_init (MetaWindowWayland *wl_window)
|
meta_window_wayland_init (MetaWindowWayland *wl_window)
|
||||||
{
|
{
|
||||||
@ -1179,6 +1195,8 @@ meta_window_wayland_finish_move_resize (MetaWindow *window,
|
|||||||
gboolean is_client_resize;
|
gboolean is_client_resize;
|
||||||
MetaWindowDrag *window_drag;
|
MetaWindowDrag *window_drag;
|
||||||
MtkRectangle frame_rect;
|
MtkRectangle frame_rect;
|
||||||
|
MetaWindowActor *window_actor;
|
||||||
|
MetaWaylandToplevelDrag *toplevel_drag;
|
||||||
|
|
||||||
/* new_geom is in the logical pixel coordinate space, but MetaWindow wants its
|
/* new_geom is in the logical pixel coordinate space, but MetaWindow wants its
|
||||||
* rects to represent what in turn will end up on the stage, i.e. we need to
|
* rects to represent what in turn will end up on the stage, i.e. we need to
|
||||||
@ -1263,6 +1281,14 @@ meta_window_wayland_finish_move_resize (MetaWindow *window,
|
|||||||
calculate_position (acked_configuration, &new_geom, &rect);
|
calculate_position (acked_configuration, &new_geom, &rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toplevel_drag = get_toplevel_drag (window);
|
||||||
|
if (toplevel_drag && !is_window_being_resized && !window->mapped &&
|
||||||
|
rect.width > 0 && rect.height > 0)
|
||||||
|
{
|
||||||
|
meta_wayland_toplevel_drag_calc_origin_for_dragged_window (toplevel_drag,
|
||||||
|
&rect);
|
||||||
|
}
|
||||||
|
|
||||||
rect.x += dx;
|
rect.x += dx;
|
||||||
rect.y += dy;
|
rect.y += dy;
|
||||||
|
|
||||||
@ -1295,6 +1321,15 @@ meta_window_wayland_finish_move_resize (MetaWindow *window,
|
|||||||
gravity = meta_resize_gravity_from_grab_op (meta_window_drag_get_grab_op (window_drag));
|
gravity = meta_resize_gravity_from_grab_op (meta_window_drag_get_grab_op (window_drag));
|
||||||
else
|
else
|
||||||
gravity = META_GRAVITY_STATIC;
|
gravity = META_GRAVITY_STATIC;
|
||||||
|
|
||||||
|
/* Force unconstrained move + northwest gravity when running toplevel drags */
|
||||||
|
if (toplevel_drag && surface == toplevel_drag->dragged_surface)
|
||||||
|
{
|
||||||
|
gravity = META_GRAVITY_NORTH_WEST;
|
||||||
|
window_actor = meta_window_actor_from_window (window);
|
||||||
|
meta_window_actor_set_tied_to_drag (window_actor, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
meta_window_move_resize_internal (window,
|
meta_window_move_resize_internal (window,
|
||||||
flags,
|
flags,
|
||||||
META_PLACE_FLAG_NONE,
|
META_PLACE_FLAG_NONE,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user