mirror of
https://github.com/labwc/labwc.git
synced 2025-11-02 09:01:47 -05:00
implement basic drag and drop
This commit is contained in:
parent
23f28e5082
commit
6bf3bb97f5
3 changed files with 70 additions and 1 deletions
|
|
@ -61,6 +61,7 @@ struct seat {
|
||||||
struct wlr_keyboard_group *keyboard_group;
|
struct wlr_keyboard_group *keyboard_group;
|
||||||
struct wlr_cursor *cursor;
|
struct wlr_cursor *cursor;
|
||||||
struct wlr_xcursor_manager *xcursor_manager;
|
struct wlr_xcursor_manager *xcursor_manager;
|
||||||
|
struct wlr_drag_icon *drag_icon;
|
||||||
|
|
||||||
/* if set, views cannot receive focus */
|
/* if set, views cannot receive focus */
|
||||||
struct wlr_layer_surface_v1 *focused_layer;
|
struct wlr_layer_surface_v1 *focused_layer;
|
||||||
|
|
@ -81,6 +82,10 @@ struct seat {
|
||||||
|
|
||||||
struct wl_listener keyboard_key;
|
struct wl_listener keyboard_key;
|
||||||
struct wl_listener keyboard_modifiers;
|
struct wl_listener keyboard_modifiers;
|
||||||
|
|
||||||
|
struct wl_listener request_start_drag;
|
||||||
|
struct wl_listener start_drag;
|
||||||
|
struct wl_listener destroy_drag;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct server {
|
struct server {
|
||||||
|
|
|
||||||
43
src/cursor.c
43
src/cursor.c
|
|
@ -57,6 +57,19 @@ request_set_primary_selection_notify(struct wl_listener *listener, void *data)
|
||||||
event->serial);
|
event->serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
request_start_drag_notify(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct seat *seat = wl_container_of(
|
||||||
|
listener, seat, request_start_drag);
|
||||||
|
struct wlr_seat_request_start_drag_event *event = data;
|
||||||
|
if (wlr_seat_validate_pointer_grab_serial(seat->seat, event->origin, event->serial)) {
|
||||||
|
wlr_seat_start_pointer_drag(seat->seat, event->drag, event->serial);
|
||||||
|
} else {
|
||||||
|
wlr_data_source_destroy(event->drag->source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
process_cursor_move(struct server *server, uint32_t time)
|
process_cursor_move(struct server *server, uint32_t time)
|
||||||
{
|
{
|
||||||
|
|
@ -190,7 +203,7 @@ process_cursor_motion(struct server *server, uint32_t time)
|
||||||
* the pointer over a window.
|
* the pointer over a window.
|
||||||
*/
|
*/
|
||||||
wlr_seat_pointer_notify_enter(wlr_seat, surface, sx, sy);
|
wlr_seat_pointer_notify_enter(wlr_seat, surface, sx, sy);
|
||||||
if (!focus_changed) {
|
if (!focus_changed || server->seat.drag_icon) {
|
||||||
/*
|
/*
|
||||||
* The enter event contains coordinates, so we only need
|
* The enter event contains coordinates, so we only need
|
||||||
* to notify on motion if the focus did not change.
|
* to notify on motion if the focus did not change.
|
||||||
|
|
@ -206,6 +219,15 @@ process_cursor_motion(struct server *server, uint32_t time)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
start_drag(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct seat *seat = wl_container_of(listener, seat, start_drag);
|
||||||
|
struct wlr_drag *wlr_drag = data;
|
||||||
|
seat->drag_icon = wlr_drag->icon;
|
||||||
|
wl_signal_add(&seat->drag_icon->events.destroy, &seat->destroy_drag);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cursor_motion(struct wl_listener *listener, void *data)
|
cursor_motion(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
|
|
@ -228,6 +250,18 @@ cursor_motion(struct wl_listener *listener, void *data)
|
||||||
process_cursor_motion(seat->server, event->time_msec);
|
process_cursor_motion(seat->server, event->time_msec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
destroy_drag(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct seat *seat = wl_container_of(listener, seat, destroy_drag);
|
||||||
|
|
||||||
|
if (!seat->drag_icon) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
seat->drag_icon = NULL;
|
||||||
|
desktop_focus_topmost_mapped_view(seat->server);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cursor_motion_absolute(struct wl_listener *listener, void *data)
|
cursor_motion_absolute(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
|
|
@ -442,6 +476,13 @@ cursor_init(struct seat *seat)
|
||||||
seat->request_set_selection.notify = request_set_selection_notify;
|
seat->request_set_selection.notify = request_set_selection_notify;
|
||||||
wl_signal_add(&seat->seat->events.request_set_selection,
|
wl_signal_add(&seat->seat->events.request_set_selection,
|
||||||
&seat->request_set_selection);
|
&seat->request_set_selection);
|
||||||
|
seat->request_start_drag.notify = request_start_drag_notify;
|
||||||
|
wl_signal_add(&seat->seat->events.request_start_drag,
|
||||||
|
&seat->request_start_drag);
|
||||||
|
seat->start_drag.notify = start_drag;
|
||||||
|
wl_signal_add(&seat->seat->events.start_drag,
|
||||||
|
&seat->start_drag);
|
||||||
|
seat->destroy_drag.notify = destroy_drag;
|
||||||
|
|
||||||
seat->request_set_primary_selection.notify =
|
seat->request_set_primary_selection.notify =
|
||||||
request_set_primary_selection_notify;
|
request_set_primary_selection_notify;
|
||||||
|
|
|
||||||
23
src/output.c
23
src/output.c
|
|
@ -179,6 +179,26 @@ render_surface_iterator(struct output *output, struct wlr_surface *surface,
|
||||||
render_texture(wlr_output, output_damage, texture, box, matrix);
|
render_texture(wlr_output, output_damage, texture, box, matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
output_drag_icon_for_each_surface(struct output *output, struct seat *seat,
|
||||||
|
surface_iterator_func_t iterator, void *user_data)
|
||||||
|
{
|
||||||
|
if (!seat->drag_icon || !seat->drag_icon->mapped) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
output_surface_for_each_surface(output, seat->drag_icon->surface,
|
||||||
|
seat->cursor->x, seat->cursor->y, iterator, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
render_drag_icon(struct output *output, pixman_region32_t *damage)
|
||||||
|
{
|
||||||
|
struct render_data data = {
|
||||||
|
.damage = damage,
|
||||||
|
};
|
||||||
|
output_drag_icon_for_each_surface(output, &output->server->seat, render_surface_iterator, &data);
|
||||||
|
}
|
||||||
|
|
||||||
#if HAVE_XWAYLAND
|
#if HAVE_XWAYLAND
|
||||||
void
|
void
|
||||||
output_unmanaged_for_each_surface(struct output *output,
|
output_unmanaged_for_each_surface(struct output *output,
|
||||||
|
|
@ -290,6 +310,7 @@ output_for_each_surface(struct output *output, surface_iterator_func_t iterator,
|
||||||
output_layer_for_each_surface(output,
|
output_layer_for_each_surface(output,
|
||||||
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
|
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
|
||||||
iterator, user_data);
|
iterator, user_data);
|
||||||
|
output_drag_icon_for_each_surface(output, &output->server->seat, iterator, user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct send_frame_done_data {
|
struct send_frame_done_data {
|
||||||
|
|
@ -707,6 +728,8 @@ output_render(struct output *output, pixman_region32_t *damage)
|
||||||
render_osd(output, damage, output->server);
|
render_osd(output, damage, output->server);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
render_drag_icon(output, damage);
|
||||||
|
|
||||||
render_layer_toplevel(output, damage,
|
render_layer_toplevel(output, damage,
|
||||||
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]);
|
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]);
|
||||||
render_layer_toplevel(output, damage,
|
render_layer_toplevel(output, damage,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue