Implement support for drag 'n drop icons

Fixes #8.
This commit is contained in:
Jente Hidskes 2019-01-11 15:20:13 +01:00
parent 1f85e1061b
commit 112a662ebc
3 changed files with 100 additions and 0 deletions

View file

@ -15,6 +15,7 @@
#include <wayland-server.h>
#include <wlr/backend.h>
#include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_matrix.h>
#include <wlr/types/wlr_output.h>
#include <wlr/types/wlr_output_layout.h>
@ -78,6 +79,25 @@ render_surface(struct wlr_surface *surface, int sx, int sy, void *data)
wlr_surface_send_frame_done(surface, rdata->when);
}
static void
drag_icons_for_each_surface(struct cg_server *server, wlr_surface_iterator_func_t iterator,
void *data)
{
struct render_data *rdata = data;
struct cg_drag_icon *drag_icon;
wl_list_for_each(drag_icon, &server->seat->drag_icons, link) {
if (!drag_icon->wlr_drag_icon->mapped) {
continue;
}
rdata->x = drag_icon->x;
rdata->y = drag_icon->y;
wlr_surface_for_each_surface(drag_icon->wlr_drag_icon->surface,
iterator,
data);
}
}
static void
handle_output_frame(struct wl_listener *listener, void *data)
{
@ -119,6 +139,8 @@ handle_output_frame(struct wl_listener *listener, void *data)
}
}
drag_icons_for_each_surface(output->server, render_surface, &rdata);
wlr_renderer_end(renderer);
wlr_output_swap_buffers(output->wlr_output, NULL, NULL);
}

63
seat.c
View file

@ -13,6 +13,7 @@
#include <wayland-server.h>
#include <wlr/backend.h>
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_idle.h>
#include <wlr/types/wlr_seat.h>
#include <wlr/types/wlr_surface.h>
@ -27,6 +28,8 @@
#include "server.h"
#include "view.h"
static void drag_icon_update_position(struct cg_drag_icon *drag_icon);
bool
have_dialogs_open(struct cg_server *server)
{
@ -496,6 +499,11 @@ process_cursor_motion(struct cg_seat *seat, uint32_t time)
}
}
struct cg_drag_icon *drag_icon;
wl_list_for_each(drag_icon, &seat->drag_icons, link) {
drag_icon_update_position(drag_icon);
}
wlr_idle_notify_activity(seat->server->idle, seat->seat);
}
@ -521,6 +529,57 @@ handle_cursor_motion(struct wl_listener *listener, void *data)
wlr_idle_notify_activity(seat->server->idle, seat->seat);
}
static void
drag_icon_update_position(struct cg_drag_icon *drag_icon)
{
struct wlr_drag_icon *wlr_icon = drag_icon->wlr_drag_icon;
struct cg_seat *seat = drag_icon->seat;
if (wlr_icon->is_pointer) {
drag_icon->x = seat->cursor->x;
drag_icon->y = seat->cursor->y;
} else {
struct wlr_touch_point *point =
wlr_seat_touch_get_point(seat->seat, wlr_icon->touch_id);
if (!point) {
return;
}
drag_icon->x = seat->touch_x;
drag_icon->y = seat->touch_y;
}
}
static void
handle_drag_icon_destroy(struct wl_listener *listener, void *data)
{
struct cg_drag_icon *drag_icon = wl_container_of(listener, drag_icon, destroy);
wl_list_remove(&drag_icon->link);
wl_list_remove(&drag_icon->destroy.link);
free(drag_icon);
}
static void
handle_new_drag_icon(struct wl_listener *listener, void *data)
{
struct cg_seat *seat = wl_container_of(listener, seat, new_drag_icon);
struct wlr_drag_icon *wlr_drag_icon = data;
struct cg_drag_icon *drag_icon = calloc(1, sizeof(struct cg_drag_icon));
if (!drag_icon) {
return;
}
drag_icon->seat = seat;
drag_icon->wlr_drag_icon = wlr_drag_icon;
drag_icon->destroy.notify = handle_drag_icon_destroy;
wl_signal_add(&wlr_drag_icon->events.destroy, &drag_icon->destroy);
wl_list_insert(&seat->drag_icons, &drag_icon->link);
drag_icon_update_position(drag_icon);
}
static void
handle_destroy(struct wl_listener *listener, void *data)
{
@ -620,6 +679,10 @@ cg_seat_create(struct cg_server *server)
seat->new_input.notify = handle_new_input;
wl_signal_add(&server->backend->events.new_input, &seat->new_input);
wl_list_init(&seat->drag_icons);
seat->new_drag_icon.notify = handle_new_drag_icon;
wl_signal_add(&seat->seat->events.new_drag_icon, &seat->new_drag_icon);
return seat;
}

15
seat.h
View file

@ -3,6 +3,7 @@
#include <wayland-server.h>
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_input_device.h>
#include <wlr/types/wlr_seat.h>
#include <wlr/types/wlr_xcursor_manager.h>
@ -37,6 +38,9 @@ struct cg_seat {
struct wl_listener touch_up;
struct wl_listener touch_motion;
struct wl_list drag_icons;
struct wl_listener new_drag_icon;
struct wl_listener request_set_cursor;
};
@ -66,6 +70,17 @@ struct cg_touch {
struct wl_listener destroy;
};
struct cg_drag_icon {
struct wl_list link; // seat::drag_icons
struct cg_seat *seat;
struct wlr_drag_icon *wlr_drag_icon;
double x;
double y;
struct wl_listener surface_commit;
struct wl_listener destroy;
};
struct cg_seat *cg_seat_create(struct cg_server *server);
void cg_seat_destroy(struct cg_seat *seat);
struct cg_view *seat_get_focus(struct cg_seat *seat);