~sircmpwn/sedna

314a5d40917608bfc9a7db7891ebd20a1b60f717 — Drew DeVault a month ago 2b3371e
Rig up cursor events
5 files changed, 122 insertions(+), 0 deletions(-)

A include/desktop.h
M src/cursor.c
A src/desktop.c
M src/meson.build
M src/xdg-shell.c
A include/desktop.h => include/desktop.h +12 -0
@@ 0,0 1,12 @@
#ifndef _SEDNA_DESKTOP_H
#define _SEDNA_DESKTOP_H
#include <wlr/types/wlr_surface.h>

struct sedna_view;
struct sedna_server;

struct sedna_view *sedna_view_at(struct sedna_server *server,
		double lx, double ly, struct wlr_surface **surface,
		double *sx, double *sy);

#endif

M src/cursor.c => src/cursor.c +57 -0
@@ 1,30 1,87 @@
#include <stdint.h>
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_seat.h>
#include <wlr/types/wlr_xcursor_manager.h>
#include "desktop.h"
#include "input.h"

static void
seat_process_cursor_motion(struct sedna_seat *seat, uint32_t time)
{
	/* TODO: Other processing modes (interactive move & resize) */
	double sx, sy;
	struct wlr_surface *surface = NULL;
	struct wlr_seat *wlr_seat = seat->seat;
	struct sedna_view *view = sedna_view_at(seat->server,
			seat->cursor->x, seat->cursor->y,
			&surface, &sx, &sy);
	if (!view) {
		wlr_xcursor_manager_set_cursor_image(seat->xcursor_manager,
				"left_ptr", seat->cursor);
	}
	if (surface) {
		bool focus_changed =
			wlr_seat->pointer_state.focused_surface != surface;
		wlr_seat_pointer_notify_enter(wlr_seat, surface, sx, sy);
		if (!focus_changed) {
			wlr_seat_pointer_notify_motion(wlr_seat, time, sx, sy);
		}
	} else {
		wlr_seat_pointer_clear_focus(seat->seat);
	}
}

static void
seat_motion(struct wl_listener *listener, void *data)
{
	struct sedna_seat *seat = wl_container_of(listener, seat, motion);
	struct wlr_event_pointer_motion *ev = data;
	wlr_cursor_move(seat->cursor, ev->device, ev->delta_x, ev->delta_y);
	seat_process_cursor_motion(seat, ev->time_msec);
}

static void
seat_motion_absolute(struct wl_listener *listener, void *data)
{
	struct sedna_seat *seat =
		wl_container_of(listener, seat, motion_absolute);
	struct wlr_event_pointer_motion_absolute *ev = data;
	wlr_cursor_warp_absolute(seat->cursor, ev->device, ev->x, ev->y);
	seat_process_cursor_motion(seat, ev->time_msec);
}

static void
seat_button(struct wl_listener *listener, void *data)
{
	struct sedna_seat *seat = wl_container_of(listener, seat, button);
	struct wlr_event_pointer_button *ev = data;
	wlr_seat_pointer_notify_button(seat->seat,
			ev->time_msec, ev->button, ev->state);
	/* TODO: Focus view & bring to front */
	/*
	double sx, sy;
	struct wlr_surface *surface;
	struct sedna_view *view = sedna_view_at(seat->server,
			seat->cursor->x, seat->cursor->y,
			&surface, &sx, &sy);
	*/
}

static void
seat_axis(struct wl_listener *listener, void *data)
{
	struct sedna_seat *seat = wl_container_of(listener, seat, axis);
	struct wlr_event_pointer_axis *ev = data;
	wlr_seat_pointer_notify_axis(seat->seat,
			ev->time_msec, ev->orientation, ev->delta,
			ev->delta_discrete, ev->source);
}

static void
seat_frame(struct wl_listener *listener, void *data)
{
	struct sedna_seat *seat = wl_container_of(listener, seat, frame);
	wlr_seat_pointer_notify_frame(seat->seat);
}

void

A src/desktop.c => src/desktop.c +50 -0
@@ 0,0 1,50 @@
#include <assert.h>
#include <wayland-util.h>
#include <wlr/types/wlr_surface.h>
#include "config.h"
#include "desktop.h"
#include "server.h"
#include "view.h"

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

	switch (view->type) {
	case SEDNA_VIEW_XDG_TOPLEVEL:
		_surface = wlr_xdg_surface_surface_at(view->wlr_xdg_surface,
				view_sx, view_sy, &_sx, &_sy);

		if (_surface != NULL) {
			*sx = _sx;
			*sy = _sy;
			*surface = _surface;
			return true;
		}
		break;
#if HAVE_XWAYLAND
	case SEDNA_VIEW_XWAYLAND:
		assert(0);
#endif
	}

	return false;
}

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

M src/meson.build => src/meson.build +1 -0
@@ 9,6 9,7 @@ executable(
	'sedna',
	files(
		'cursor.c',
		'desktop.c',
		'main.c',
		'input.c',
		'output.c',

M src/xdg-shell.c => src/xdg-shell.c +2 -0
@@ 131,6 131,8 @@ new_surface_notify(struct wl_listener *listener, void *data)

	toplevel->destroy.notify = xdg_toplevel_destroy;
	wl_signal_add(&xdg_surface->events.destroy, &toplevel->destroy);
	/* TEMP */
	wlr_xdg_toplevel_set_activated(view->wlr_xdg_surface, true);
}

void