From db15ab77b49954ec315642279d9c2fc70555c9ef Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sun, 8 Oct 2017 12:33:39 -0400 Subject: [PATCH] use input bounds for pointer events --- include/rootston/view.h | 2 -- rootston/desktop.c | 58 ++++++++++++++++++++--------------------- types/wlr_surface.c | 9 +++---- 3 files changed, 33 insertions(+), 36 deletions(-) diff --git a/include/rootston/view.h b/include/rootston/view.h index 64aad45e..8c899ed8 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -62,14 +62,12 @@ struct roots_view { // If not then this should follow the typical type/impl pattern we use // elsewhere void (*get_size)(struct roots_view *view, struct wlr_box *box); - void (*get_input_bounds)(struct roots_view *view, struct wlr_box *box); void (*activate)(struct roots_view *view, bool active); void (*resize)(struct roots_view *view, uint32_t width, uint32_t height); void (*close)(struct roots_view *view); }; void view_get_size(struct roots_view *view, struct wlr_box *box); -void view_get_input_bounds(struct roots_view *view, struct wlr_box *box); void view_activate(struct roots_view *view, bool active); void view_resize(struct roots_view *view, uint32_t width, uint32_t height); void view_close(struct roots_view *view); diff --git a/rootston/desktop.c b/rootston/desktop.c index 3d9b2120..1d382136 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -46,25 +46,6 @@ void view_get_size(struct roots_view *view, struct wlr_box *box) { box->height = view->wlr_surface->current->height; } -void view_get_input_bounds(struct roots_view *view, struct wlr_box *box) { - if (view->get_input_bounds) { - view->get_input_bounds(view, box); - return; - } - - if (view->type == ROOTS_XDG_SHELL_V6_VIEW) { - box->x = view->xdg_surface_v6->geometry->x; - box->y = view->xdg_surface_v6->geometry->y; - box->width = view->xdg_surface_v6->geometry->width; - box->height = view->xdg_surface_v6->geometry->height; - return; - } - - box->x = box->y = 0; - box->width = view->wlr_surface->current->width; - box->height = view->wlr_surface->current->height; -} - void view_activate(struct roots_view *view, bool activate) { if (view->activate) { view->activate(view, activate); @@ -93,7 +74,8 @@ static struct wlr_subsurface *subsurface_at(struct wlr_surface *surface, subsurface_at(subsurface->surface, _sub_x + sx, _sub_y + sy, sub_x, sub_y); if (sub) { - // TODO: convert sub_x and sub_y to the parent coordinate system + // TODO: This won't work for nested subsurfaces. Convert sub_x and + // sub_y to the parent coordinate system return sub; } @@ -101,9 +83,13 @@ static struct wlr_subsurface *subsurface_at(struct wlr_surface *surface, int sub_height = subsurface->surface->current->buffer_height; if ((sx > _sub_x && sx < _sub_x + sub_width) && (sy > _sub_y && sy < _sub_y + sub_height)) { - *sub_x = _sub_x; - *sub_y = _sub_y; - return subsurface; + if (pixman_region32_contains_point( + &subsurface->surface->current->input, + sx - _sub_x, sy - _sub_y, NULL)) { + *sub_x = _sub_x; + *sub_y = _sub_y; + return subsurface; + } } } @@ -113,6 +99,9 @@ static struct wlr_subsurface *subsurface_at(struct wlr_surface *surface, static struct wlr_xdg_surface_v6 *xdg_v6_popup_at( struct wlr_xdg_surface_v6 *surface, double sx, double sy, double *popup_sx, double *popup_sy) { + // XXX: I think this is so complicated because we're mixing geometry + // coordinates with surface coordinates. Input handling should only deal + // with surface coordinates. struct wlr_xdg_surface_v6 *popup; wl_list_for_each(popup, &surface->popups, popup_link) { double _popup_sx = surface->geometry->x + popup->popup_state->geometry.x; @@ -131,9 +120,13 @@ static struct wlr_xdg_surface_v6 *xdg_v6_popup_at( if ((sx > _popup_sx && sx < _popup_sx + popup_width) && (sy > _popup_sy && sy < _popup_sy + popup_height)) { - *popup_sx = _popup_sx - popup->geometry->x; - *popup_sy = _popup_sy - popup->geometry->y; - return popup; + if (pixman_region32_contains_point(&popup->surface->current->input, + sx - _popup_sx + popup->geometry->x, + sy - _popup_sy + popup->geometry->y, NULL)) { + *popup_sx = _popup_sx - popup->geometry->x; + *popup_sy = _popup_sy - popup->geometry->y; + return popup; + } } } @@ -148,8 +141,12 @@ struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, double view_sx = lx - view->x; double view_sy = ly - view->y; - struct wlr_box box; - view_get_input_bounds(view, &box); + struct wlr_box box = { + .x = 0, + .y = 0, + .width = view->wlr_surface->current->buffer_width, + .height = view->wlr_surface->current->buffer_height, + }; if (view->rotation != 0.0) { // Coordinates relative to the center of the view double ox = view_sx - (double)box.width/2, @@ -186,7 +183,10 @@ struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, return view; } - if (wlr_box_contains_point(&box, view_sx, view_sy)) { + if (wlr_box_contains_point(&box, view_sx, view_sy) && + pixman_region32_contains_point( + &view->wlr_surface->current->input, + view_sx, view_sy, NULL)) { *sx = view_sx; *sy = view_sy; *surface = view->wlr_surface; diff --git a/types/wlr_surface.c b/types/wlr_surface.c index 45b51363..8fd8baaa 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -121,9 +121,6 @@ static void surface_set_input_region(struct wl_client *client, struct wl_resource *resource, struct wl_resource *region_resource) { struct wlr_surface *surface = wl_resource_get_user_data(resource); - if ((surface->pending->invalid & WLR_SURFACE_INVALID_INPUT_REGION)) { - pixman_region32_clear(&surface->pending->input); - } surface->pending->invalid |= WLR_SURFACE_INVALID_INPUT_REGION; if (region_resource) { pixman_region32_t *region = wl_resource_get_user_data(region_resource); @@ -304,7 +301,7 @@ static void wlr_surface_move_state(struct wlr_surface *surface, struct wlr_surfa } if ((next->invalid & WLR_SURFACE_INVALID_INPUT_REGION)) { // TODO: process buffer - pixman_region32_clear(&next->input); + pixman_region32_copy(&state->input, &next->input); } if ((next->invalid & WLR_SURFACE_INVALID_SUBSURFACE_POSITION)) { state->subsurface_position.x = next->subsurface_position.x; @@ -546,7 +543,9 @@ static struct wlr_surface_state *wlr_surface_state_create() { pixman_region32_init(&state->surface_damage); pixman_region32_init(&state->buffer_damage); pixman_region32_init(&state->opaque); - pixman_region32_init(&state->input); + pixman_region32_init_rect(&state->input, + INT32_MIN, INT32_MIN, UINT32_MAX, UINT32_MAX); + return state; }