~goleo/wio

1c1a5baff2808e8d27af1c630bd3c7f0842ec9d5 — Drew DeVault 2 years ago 8c9fb27
Pass pointer events through to clients
6 files changed, 71 insertions(+), 5 deletions(-)

M include/server.h
M include/view.h
M input.c
M main.c
M output.c
M view.c
M include/server.h => include/server.h +2 -0
@@ 35,6 35,7 @@ struct wio_server {
	struct wl_listener cursor_motion_absolute;
	struct wl_listener cursor_button;
	struct wl_listener cursor_axis;
	struct wl_listener cursor_frame;

	struct wl_listener new_xdg_surface;



@@ 70,5 71,6 @@ void server_cursor_motion(struct wl_listener *listener, void *data);
void server_cursor_motion_absolute(struct wl_listener *listener, void *data);
void server_cursor_button(struct wl_listener *listener, void *data);
void server_cursor_axis(struct wl_listener *listener, void *data);
void server_cursor_frame(struct wl_listener *listener, void *data);

#endif

M include/view.h => include/view.h +2 -0
@@ 17,5 17,7 @@ struct wio_view {
void server_new_xdg_surface(struct wl_listener *listener, void *data);

void wio_view_focus(struct wio_view *view, struct wlr_surface *surface);
struct wio_view *wio_view_at(struct wio_server *server, double lx, double ly,
		struct wlr_surface **surface, double *sx, double *sy);

#endif

M input.c => input.c +32 -4
@@ 6,6 6,7 @@
#include <wlr/types/wlr_pointer.h>
#include <xkbcommon/xkbcommon.h>
#include "server.h"
#include "view.h"

static void server_new_keyboard(
		struct wio_server *server, struct wlr_input_device *device) {


@@ 58,9 59,24 @@ void server_new_input(struct wl_listener *listener, void *data) {
}

static void process_cursor_motion(struct wio_server *server, uint32_t time) {
	// TODO: Resize/move/passthrough/etc
	wlr_xcursor_manager_set_cursor_image(
			server->cursor_mgr, "left_ptr", server->cursor);
	double sx, sy;
	struct wlr_seat *seat = server->seat;
	struct wlr_surface *surface = NULL;
	struct wio_view *view = wio_view_at(
			server, server->cursor->x, server->cursor->y, &surface, &sx, &sy);
	if (!view) {
		wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
				"left_ptr", server->cursor);
	}
	if (surface) {
		bool focus_changed = seat->pointer_state.focused_surface != surface;
		wlr_seat_pointer_notify_enter(seat, surface, sx, sy);
		if (!focus_changed) {
			wlr_seat_pointer_notify_motion(seat, time, sx, sy);
		}
	} else {
		wlr_seat_pointer_clear_focus(seat);
	}
}

void server_cursor_motion(struct wl_listener *listener, void *data) {


@@ 86,7 102,13 @@ void server_cursor_button(struct wl_listener *listener, void *data) {
		wl_container_of(listener, server, cursor_button);
	struct wlr_event_pointer_button *event = data;
	// TODO: Internal button processing (e.g. resize, menus, etc)
	// TODO: Bring client under the cursor to the front when pressed
	double sx, sy;
	struct wlr_surface *surface = NULL;
	struct wio_view *view = wio_view_at(
			server, server->cursor->x, server->cursor->y, &surface, &sx, &sy);
	if (view) {
		wio_view_focus(view, surface);
	}
	wlr_seat_pointer_notify_button(server->seat,
			event->time_msec, event->button, event->state);
}


@@ 98,3 120,9 @@ void server_cursor_axis(struct wl_listener *listener, void *data) {
			event->time_msec, event->orientation, event->delta,
			event->delta_discrete, event->source);
}

void server_cursor_frame(struct wl_listener *listener, void *data) {
	struct wio_server *server =
		wl_container_of(listener, server, cursor_frame);
	wlr_seat_pointer_notify_frame(server->seat);
}

M main.c => main.c +2 -0
@@ 96,6 96,8 @@ int main(int argc, char **argv) {
	wl_signal_add(&server.cursor->events.button, &server.cursor_button);
	server.cursor_axis.notify = server_cursor_axis;
	wl_signal_add(&server.cursor->events.axis, &server.cursor_axis);
	server.cursor_frame.notify = server_cursor_frame;
	wl_signal_add(&server.cursor->events.frame, &server.cursor_frame);

	wl_list_init(&server.inputs);
	server.new_input.notify = server_new_input;

M output.c => output.c +1 -1
@@ 64,7 64,7 @@ static void render_menu(struct wio_output *output) {
			text_width = width;
		}
	}
	text_width += border * 2;
	text_width += border * 2 + margin;
	text_height += border * 2 - margin;

	double ox = 0, oy = 0;

M view.c => view.c +32 -0
@@ 58,3 58,35 @@ void wio_view_focus(struct wio_view *view, struct wlr_surface *surface) {
	wl_list_remove(&view->link);
	wl_list_insert(&view->server->views, &view->link);
}

static bool view_at(struct wio_view *view,
		double lx, double ly, struct wlr_surface **surface,
		double *sx, double *sy) {
	double view_sx = lx - view->x;
	double view_sy = ly - view->y;

	double _sx, _sy;
	struct wlr_surface *_surface = NULL;
	_surface = wlr_xdg_surface_surface_at(
			view->xdg_surface, view_sx, view_sy, &_sx, &_sy);

	if (_surface != NULL) {
		*sx = _sx;
		*sy = _sy;
		*surface = _surface;
		return true;
	}

	return false;
}

struct wio_view *wio_view_at(struct wio_server *server, double lx, double ly,
		struct wlr_surface **surface, double *sx, double *sy) {
	struct wio_view *view;
	wl_list_for_each(view, &server->views, link) {
		if (view_at(view, lx, ly, surface, sx, sy)) {
			return view;
		}
	}
	return NULL;
}