From 129deaffa82650a1383f5816aa46f4a78a73b2ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 16 Apr 2022 17:41:14 +0200 Subject: [PATCH] wayland: optionally disable pointer input on subsurfaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have a number of sub-surfaces for which we are *not* interrested in pointer (or touch) input. Up until now, we’ve manually dealt with these, by recognizing these surfaces in all pointer events, and ignoring them. But, lo and behold, there are better ways of doing this. By clearing the subsurface’s input region, the compositor will do this for us - when a pointer is outside a surface’s input region, the event is passed to the next surface underneath it. This is exactly what we want! Do this for all subsurfaces, *except* the CSDs. --- input.c | 18 ------------------ render.c | 4 +++- search.c | 3 ++- terminal.c | 17 +---------------- terminal.h | 4 ---- url-mode.c | 2 +- wayland.c | 23 +++++++++++++++++------ wayland.h | 5 +++-- 8 files changed, 27 insertions(+), 49 deletions(-) diff --git a/input.c b/input.c index ba45a59d..29ac80ae 100644 --- a/input.c +++ b/input.c @@ -1904,10 +1904,6 @@ wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, break; } - case TERM_SURF_SEARCH: - case TERM_SURF_SCROLLBACK_INDICATOR: - case TERM_SURF_RENDER_TIMER: - case TERM_SURF_JUMP_LABEL: case TERM_SURF_TITLE: case TERM_SURF_BORDER_LEFT: case TERM_SURF_BORDER_RIGHT: @@ -1993,10 +1989,6 @@ wl_pointer_leave(void *data, struct wl_pointer *wl_pointer, break; case TERM_SURF_NONE: - case TERM_SURF_SEARCH: - case TERM_SURF_SCROLLBACK_INDICATOR: - case TERM_SURF_RENDER_TIMER: - case TERM_SURF_JUMP_LABEL: case TERM_SURF_TITLE: case TERM_SURF_BORDER_LEFT: case TERM_SURF_BORDER_RIGHT: @@ -2044,10 +2036,6 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, switch (surf_kind) { case TERM_SURF_NONE: - case TERM_SURF_SEARCH: - case TERM_SURF_SCROLLBACK_INDICATOR: - case TERM_SURF_RENDER_TIMER: - case TERM_SURF_JUMP_LABEL: case TERM_SURF_BUTTON_MINIMIZE: case TERM_SURF_BUTTON_MAXIMIZE: case TERM_SURF_BUTTON_CLOSE: @@ -2463,12 +2451,6 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, term_shutdown(term); break; - case TERM_SURF_SEARCH: - case TERM_SURF_SCROLLBACK_INDICATOR: - case TERM_SURF_RENDER_TIMER: - case TERM_SURF_JUMP_LABEL: - break; - case TERM_SURF_GRID: { search_cancel(term); urls_reset(term); diff --git a/render.c b/render.c index 7ad8704d..d3cc2ab9 100644 --- a/render.c +++ b/render.c @@ -2159,7 +2159,9 @@ render_scrollback_position(struct terminal *term) } if (win->scrollback_indicator.surf == NULL) { - if (!wayl_win_subsurface_new(win, &win->scrollback_indicator)) { + if (!wayl_win_subsurface_new( + win, &win->scrollback_indicator, false)) + { LOG_ERR("failed to create scrollback indicator surface"); return; } diff --git a/search.c b/search.c index d6bd0d42..69dbcccd 100644 --- a/search.c +++ b/search.c @@ -136,7 +136,8 @@ search_begin(struct terminal *term) } /* On-demand instantiate wayland surface */ - bool ret = wayl_win_subsurface_new(term->window, &term->window->search); + bool ret = wayl_win_subsurface_new( + term->window, &term->window->search, false); xassert(ret); const struct grid *grid = term->grid; diff --git a/terminal.c b/terminal.c index b78279e4..87c14b58 100644 --- a/terminal.c +++ b/terminal.c @@ -3008,10 +3008,6 @@ term_xcursor_update_for_seat(struct terminal *term, struct seat *seat) : XCURSOR_LEFT_PTR; break; } - case TERM_SURF_SEARCH: - case TERM_SURF_SCROLLBACK_INDICATOR: - case TERM_SURF_RENDER_TIMER: - case TERM_SURF_JUMP_LABEL: case TERM_SURF_TITLE: case TERM_SURF_BUTTON_MINIMIZE: case TERM_SURF_BUTTON_MAXIMIZE: @@ -3389,12 +3385,6 @@ term_surface_kind(const struct terminal *term, const struct wl_surface *surface) { if (likely(surface == term->window->surface)) return TERM_SURF_GRID; - else if (surface == term->window->search.surf) - return TERM_SURF_SEARCH; - else if (surface == term->window->scrollback_indicator.surf) - return TERM_SURF_SCROLLBACK_INDICATOR; - else if (surface == term->window->render_timer.surf) - return TERM_SURF_RENDER_TIMER; else if (surface == term->window->csd.surface[CSD_SURF_TITLE].surf) return TERM_SURF_TITLE; else if (surface == term->window->csd.surface[CSD_SURF_LEFT].surf) @@ -3411,13 +3401,8 @@ term_surface_kind(const struct terminal *term, const struct wl_surface *surface) return TERM_SURF_BUTTON_MAXIMIZE; else if (surface == term->window->csd.surface[CSD_SURF_CLOSE].surf) return TERM_SURF_BUTTON_CLOSE; - else { - tll_foreach(term->window->urls, it) { - if (surface == it->item.surf.surf) - return TERM_SURF_JUMP_LABEL; - } + else return TERM_SURF_NONE; - } } static bool diff --git a/terminal.h b/terminal.h index 5b7d6d07..c80424c3 100644 --- a/terminal.h +++ b/terminal.h @@ -272,10 +272,6 @@ struct ptmx_buffer { enum term_surface { TERM_SURF_NONE, TERM_SURF_GRID, - TERM_SURF_SEARCH, - TERM_SURF_SCROLLBACK_INDICATOR, - TERM_SURF_RENDER_TIMER, - TERM_SURF_JUMP_LABEL, TERM_SURF_TITLE, TERM_SURF_BORDER_LEFT, TERM_SURF_BORDER_RIGHT, diff --git a/url-mode.c b/url-mode.c index 409053b5..a283c27e 100644 --- a/url-mode.c +++ b/url-mode.c @@ -718,7 +718,7 @@ urls_render(struct terminal *term) xassert(tll_length(win->urls) == 0); tll_foreach(win->term->urls, it) { struct wl_url url = {.url = &it->item}; - wayl_win_subsurface_new(win, &url.surf); + wayl_win_subsurface_new(win, &url.surf, false); tll_push_back(win->urls, url); tag_cells_for_url(term, &it->item, true); diff --git a/wayland.c b/wayland.c index c788849f..23483327 100644 --- a/wayland.c +++ b/wayland.c @@ -67,13 +67,14 @@ csd_instantiate(struct wl_window *win) xassert(wayl != NULL); for (size_t i = 0; i < CSD_SURF_MINIMIZE; i++) { - bool ret = wayl_win_subsurface_new(win, &win->csd.surface[i]); + bool ret = wayl_win_subsurface_new(win, &win->csd.surface[i], true); xassert(ret); } for (size_t i = CSD_SURF_MINIMIZE; i < CSD_SURF_COUNT; i++) { bool ret = wayl_win_subsurface_new_with_custom_parent( - win, win->csd.surface[CSD_SURF_TITLE].surf, &win->csd.surface[i]); + win, win->csd.surface[CSD_SURF_TITLE].surf, &win->csd.surface[i], + true); xassert(ret); } @@ -1478,7 +1479,7 @@ wayl_win_init(struct terminal *term, const char *token) switch (conf->tweak.render_timer) { case RENDER_TIMER_OSD: case RENDER_TIMER_BOTH: - if (!wayl_win_subsurface_new(win, &win->render_timer)) { + if (!wayl_win_subsurface_new(win, &win->render_timer, false)) { LOG_ERR("failed to create render timer surface"); goto out; } @@ -1783,7 +1784,7 @@ wayl_win_csd_borders_visible(const struct wl_window *win) bool wayl_win_subsurface_new_with_custom_parent( struct wl_window *win, struct wl_surface *parent, - struct wl_surf_subsurf *surf) + struct wl_surf_subsurf *surf, bool allow_pointer_input) { struct wayland *wayl = win->term->wl; @@ -1807,15 +1808,25 @@ wayl_win_subsurface_new_with_custom_parent( wl_surface_set_user_data(main_surface, win); wl_subsurface_set_sync(sub); + /* Disable pointer and touch events */ + if (!allow_pointer_input) { + struct wl_region *empty = + wl_compositor_create_region(wayl->compositor); + wl_surface_set_input_region(main_surface, empty); + wl_region_destroy(empty); + } + surf->surf = main_surface; surf->sub = sub; return true; } bool -wayl_win_subsurface_new(struct wl_window *win, struct wl_surf_subsurf *surf) +wayl_win_subsurface_new(struct wl_window *win, struct wl_surf_subsurf *surf, + bool allow_pointer_input) { - return wayl_win_subsurface_new_with_custom_parent(win, win->surface, surf); + return wayl_win_subsurface_new_with_custom_parent( + win, win->surface, surf, allow_pointer_input); } void diff --git a/wayland.h b/wayland.h index 62ab1d5f..3e7e7aeb 100644 --- a/wayland.h +++ b/wayland.h @@ -515,10 +515,11 @@ bool wayl_win_csd_titlebar_visible(const struct wl_window *win); bool wayl_win_csd_borders_visible(const struct wl_window *win); bool wayl_win_subsurface_new( - struct wl_window *win, struct wl_surf_subsurf *surf); + struct wl_window *win, struct wl_surf_subsurf *surf, + bool allow_pointer_input); bool wayl_win_subsurface_new_with_custom_parent( struct wl_window *win, struct wl_surface *parent, - struct wl_surf_subsurf *surf); + struct wl_surf_subsurf *surf, bool allow_pointer_input); void wayl_win_subsurface_destroy(struct wl_surf_subsurf *surf); void wayl_bindings_reset(struct seat *seat);