From 5c2557b42116dd6d0f86c90b2cf04cd43f80a36e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Fri, 19 Nov 2021 15:02:48 +0100 Subject: [PATCH 1/3] terminal: Make seat xcursor update focus aware When term_xcursor_update_for_seat() was called on e.g. keyboard focus loss, it'd update the curret xcursor to 'text' even if it was e.g. on top of the window title, or resize areas. This makes the function a bit more focus aware, and will not be so eager to set the text xcursor. --- input.c | 2 +- input.h | 2 ++ terminal.c | 43 +++++++++++++++++++++++++++++++++++-------- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/input.c b/input.c index 0aef43cc..5f864a8d 100644 --- a/input.c +++ b/input.c @@ -1372,7 +1372,7 @@ is_bottom_right(const struct terminal *term, int x, int y) (term->active_surface == TERM_SURF_BORDER_BOTTOM && x > term->width + 1 * csd_border_size * term->scale - 10 * term->scale))); } -static const char * +const char * xcursor_for_csd_border(struct terminal *term, int x, int y) { if (is_top_left(term, x, y)) return XCURSOR_TOP_LEFT_CORNER; diff --git a/input.h b/input.h index 68b8719d..5a2c7a67 100644 --- a/input.h +++ b/input.h @@ -26,3 +26,5 @@ extern const struct wl_keyboard_listener keyboard_listener; extern const struct wl_pointer_listener pointer_listener; void input_repeat(struct seat *seat, uint32_t key); + +const char * xcursor_for_csd_border(struct terminal *term, int x, int y); diff --git a/terminal.c b/terminal.c index df8128fc..83204675 100644 --- a/terminal.c +++ b/terminal.c @@ -3015,14 +3015,41 @@ term_mouse_motion(struct terminal *term, int button, int row, int col, void term_xcursor_update_for_seat(struct terminal *term, struct seat *seat) { - const char *xcursor - = seat->pointer.hidden ? XCURSOR_HIDDEN - : term->is_searching ? XCURSOR_LEFT_PTR - : (seat->mouse.col >= 0 && - seat->mouse.row >= 0 && - term_mouse_grabbed(term, seat)) ? XCURSOR_TEXT - : term->is_searching ? XCURSOR_TEXT - : XCURSOR_LEFT_PTR; + const char *xcursor; + + switch (term->active_surface) { + case TERM_SURF_GRID: { + xcursor = seat->pointer.hidden ? XCURSOR_HIDDEN + : term->is_searching ? XCURSOR_LEFT_PTR + : (seat->mouse.col >= 0 && + seat->mouse.row >= 0 && + term_mouse_grabbed(term, seat)) ? XCURSOR_TEXT + : term->is_searching ? XCURSOR_TEXT + : 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: + case TERM_SURF_BUTTON_CLOSE: + xcursor = XCURSOR_LEFT_PTR; + break; + + case TERM_SURF_BORDER_LEFT: + case TERM_SURF_BORDER_RIGHT: + case TERM_SURF_BORDER_TOP: + case TERM_SURF_BORDER_BOTTOM: + xcursor = xcursor_for_csd_border(term, seat->mouse.x, seat->mouse.y); + break; + + case TERM_SURF_NONE: + default: + return; + } render_xcursor_set(seat, term, xcursor); } From c0ce131f1a4195585cc89f58ab65cfd7658ca0b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Fri, 19 Nov 2021 15:04:51 +0100 Subject: [PATCH 2/3] input: Update mouse x/y coordinates on wl_pointer_enter Otherwise if you don't receive motion event before e.g. button pressed, the coordinates will be incorrect. This happens when e.g. you get alt-tabbed so that the mouse cursor ends up on top of the terminal window, but the mouse never actually moved. --- input.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/input.c b/input.c index 5f864a8d..35baf3d4 100644 --- a/input.c +++ b/input.c @@ -1405,11 +1405,18 @@ wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, struct wl_window *win = wl_surface_get_user_data(surface); struct terminal *term = win->term; + int x = wl_fixed_to_int(surface_x) * term->scale; + int y = wl_fixed_to_int(surface_y) * term->scale; + seat->pointer.serial = serial; seat->pointer.hidden = false; + seat->mouse.x = x; + seat->mouse.y = y; - LOG_DBG("pointer-enter: pointer=%p, serial=%u, surface = %p, new-moused = %p", - (void *)wl_pointer, serial, (void *)surface, (void *)term); + LOG_DBG("pointer-enter: pointer=%p, serial=%u, surface = %p, new-moused = %p, " + "x=%d, y=%d", + (void *)wl_pointer, serial, (void *)surface, (void *)term, + x, y); xassert(tll_length(seat->mouse.buttons) == 0); @@ -1418,9 +1425,6 @@ wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, seat->mouse_focus = term; - int x = wl_fixed_to_int(surface_x) * term->scale; - int y = wl_fixed_to_int(surface_y) * term->scale; - switch ((term->active_surface = term_surface_kind(term, surface))) { case TERM_SURF_GRID: { /* From 38741baf9afc2697c7e508cb87c3b2983de9f0af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Fri, 19 Nov 2021 15:08:46 +0100 Subject: [PATCH 3/3] input: Add support for xdg_toplevl.show_window_menu() This makes, if the compositor supports it, the window menu appear when right clicking on the title bar. --- input.c | 10 ++++++++++ render.c | 9 +-------- render.h | 9 +++++++++ 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/input.c b/input.c index 35baf3d4..7e0cde75 100644 --- a/input.c +++ b/input.c @@ -1924,6 +1924,16 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, close(fd); } } + + if (button == BTN_RIGHT && tll_length(seat->mouse.buttons) == 1) { + struct csd_data info; + info = get_csd_data(term, CSD_SURF_TITLE); + xdg_toplevel_show_window_menu( + win->xdg_toplevel, + seat->wl_seat, + seat->pointer.serial, + seat->mouse.x + info.x, seat->mouse.y + info.y); + } } else if (state == WL_POINTER_BUTTON_STATE_RELEASED) { diff --git a/render.c b/render.c index 46cc0f75..76fe7c95 100644 --- a/render.c +++ b/render.c @@ -1521,14 +1521,7 @@ render_worker_thread(void *_ctx) return -1; } -struct csd_data { - int x; - int y; - int width; - int height; -}; - -static struct csd_data +struct csd_data get_csd_data(const struct terminal *term, enum csd_surface surf_idx) { xassert(term->window->csd_mode == CSD_YES); diff --git a/render.h b/render.h index 1179a5dc..145aaba8 100644 --- a/render.h +++ b/render.h @@ -24,3 +24,12 @@ struct render_worker_context { struct terminal *term; }; int render_worker_thread(void *_ctx); + +struct csd_data { + int x; + int y; + int width; + int height; +}; + +struct csd_data get_csd_data(const struct terminal *term, enum csd_surface surf_idx);