From be2490022d445bef2c5c00336aecf2bd9dd25ee7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 8 Jul 2020 18:08:39 +0200 Subject: [PATCH] multi-seat: enable xcursor theme support again --- input.c | 8 ++-- render.c | 90 ++++++++++++++++++--------------------- render.h | 2 +- terminal.c | 21 +++++---- wayland.c | 122 +++++++++++++++++++---------------------------------- wayland.h | 4 +- 6 files changed, 104 insertions(+), 143 deletions(-) diff --git a/input.c b/input.c index 75a80b2f..176d9809 100644 --- a/input.c +++ b/input.c @@ -861,7 +861,7 @@ wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, case TERM_SURF_SEARCH: case TERM_SURF_TITLE: term->xcursor = "left_ptr"; - render_xcursor_set(term); + render_xcursor_set(seat, term); break; case TERM_SURF_BORDER_LEFT: @@ -869,14 +869,14 @@ wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, case TERM_SURF_BORDER_TOP: case TERM_SURF_BORDER_BOTTOM: term->xcursor = xcursor_for_csd_border(term, x, y); - render_xcursor_set(term); + render_xcursor_set(seat, term); break; case TERM_SURF_BUTTON_MINIMIZE: case TERM_SURF_BUTTON_MAXIMIZE: case TERM_SURF_BUTTON_CLOSE: term->xcursor = "left_ptr"; - render_xcursor_set(term); + render_xcursor_set(seat, term); render_refresh_csd(term); break; @@ -994,7 +994,7 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, case TERM_SURF_BORDER_TOP: case TERM_SURF_BORDER_BOTTOM: term->xcursor = xcursor_for_csd_border(term, x, y); - render_xcursor_set(term); + render_xcursor_set(seat, term); break; case TERM_SURF_GRID: { diff --git a/render.c b/render.c index 2a8869ee..8fb0fd6f 100644 --- a/render.c +++ b/render.c @@ -1938,77 +1938,72 @@ render_resize_force(struct terminal *term, int width, int height) { return maybe_resize(term, width, height, true); } -#if 0 + static void xcursor_callback( void *data, struct wl_callback *wl_callback, uint32_t callback_data); static const struct wl_callback_listener xcursor_listener = { .done = &xcursor_callback, }; -#endif -#if 0 static void -render_xcursor_update(struct wayland *wayl, const struct terminal *term) +render_xcursor_update(struct seat *seat, const struct terminal *term) { /* If called from a frame callback, we may no longer have mouse focus */ - if (wayl->mouse_focus != term) + if (seat->mouse_focus != term) return; - wayl->pointer.cursor = wl_cursor_theme_get_cursor(wayl->pointer.theme, term->xcursor); - if (wayl->pointer.cursor == NULL) { + seat->pointer.cursor = wl_cursor_theme_get_cursor(seat->pointer.theme, term->xcursor); + if (seat->pointer.cursor == NULL) { LOG_ERR("%s: failed to load xcursor pointer '%s'", - wayl->pointer.theme_name, term->xcursor); + seat->pointer.theme_name, term->xcursor); return; } - wayl->pointer.xcursor = term->xcursor; + seat->pointer.xcursor = term->xcursor; const int scale = term->scale; - struct wl_cursor_image *image = wayl->pointer.cursor->images[0]; + struct wl_cursor_image *image = seat->pointer.cursor->images[0]; wl_surface_attach( - wayl->pointer.surface, wl_cursor_image_get_buffer(image), 0, 0); + seat->pointer.surface, wl_cursor_image_get_buffer(image), 0, 0); wl_pointer_set_cursor( - wayl->pointer.pointer, wayl->pointer.serial, - wayl->pointer.surface, + seat->wl_pointer, seat->pointer.serial, + seat->pointer.surface, image->hotspot_x / scale, image->hotspot_y / scale); wl_surface_damage_buffer( - wayl->pointer.surface, 0, 0, INT32_MAX, INT32_MAX); + seat->pointer.surface, 0, 0, INT32_MAX, INT32_MAX); - wl_surface_set_buffer_scale(wayl->pointer.surface, scale); + wl_surface_set_buffer_scale(seat->pointer.surface, scale); - assert(wayl->pointer.xcursor_callback == NULL); - wayl->pointer.xcursor_callback = wl_surface_frame(wayl->pointer.surface); - wl_callback_add_listener(wayl->pointer.xcursor_callback, &xcursor_listener, wayl); + assert(seat->pointer.xcursor_callback == NULL); + seat->pointer.xcursor_callback = wl_surface_frame(seat->pointer.surface); + wl_callback_add_listener(seat->pointer.xcursor_callback, &xcursor_listener, seat); - wl_surface_commit(wayl->pointer.surface); + wl_surface_commit(seat->pointer.surface); } -#endif -#if 0 static void xcursor_callback(void *data, struct wl_callback *wl_callback, uint32_t callback_data) { - struct wayland *wayl = data; + struct seat *seat = data; - assert(wayl->pointer.xcursor_callback == wl_callback); + assert(seat->pointer.xcursor_callback == wl_callback); wl_callback_destroy(wl_callback); - wayl->pointer.xcursor_callback = NULL; + seat->pointer.xcursor_callback = NULL; - if (wayl->pointer.pending_terminal != NULL) { - render_xcursor_update(wayl, wayl->pointer.pending_terminal); - wayl->pointer.pending_terminal = NULL; + if (seat->pointer.pending_terminal != NULL) { + render_xcursor_update(seat, seat->pointer.pending_terminal); + seat->pointer.pending_terminal = NULL; } } -#endif static void fdm_hook_refresh_pending_terminals(struct fdm *fdm, void *data) { struct renderer *renderer = data; - //struct wayland *wayl = renderer->wayl; + struct wayland *wayl = renderer->wayl; tll_foreach(renderer->wayl->terms, it) { struct terminal *term = it->item; @@ -2065,16 +2060,16 @@ fdm_hook_refresh_pending_terminals(struct fdm *fdm, void *data) } } -#if 0 - if (wayl->pointer.pending_terminal != NULL) { - if (wayl->pointer.xcursor_callback == NULL) { - render_xcursor_update(wayl, wayl->pointer.pending_terminal); - wayl->pointer.pending_terminal = NULL; - } else { - /* Frame callback will call render_xcursor_update() */ + tll_foreach(wayl->seats, it) { + if (it->item.pointer.pending_terminal != NULL) { + if (it->item.pointer.xcursor_callback == NULL) { + render_xcursor_update(&it->item, it->item.pointer.pending_terminal); + it->item.pointer.pending_terminal = NULL; + } else { + /* Frame callback will call render_xcursor_update() */ + } } } -#endif } void @@ -2104,31 +2099,26 @@ render_refresh_search(struct terminal *term) } bool -render_xcursor_set(struct terminal *term) +render_xcursor_set(struct seat *seat, struct terminal *term) { -#if 0 - struct wayland *wayl = term->wl; - - if (wayl->pointer.theme == NULL) + if (seat->pointer.theme == NULL) return false; - if (wayl->mouse_focus == NULL) { - wayl->pointer.xcursor = NULL; - wayl->pointer.pending_terminal = NULL; + if (seat->mouse_focus == NULL) { + seat->pointer.xcursor = NULL; + seat->pointer.pending_terminal = NULL; return true; } - if (wayl->mouse_focus != term) { + if (seat->mouse_focus != term) { /* This terminal doesn't have mouse focus */ return true; } - if (wayl->pointer.xcursor == term->xcursor) + if (seat->pointer.xcursor == term->xcursor) return true; /* FDM hook takes care of actual rendering */ - wayl->pointer.pending_terminal = term; - return true; -#endif + seat->pointer.pending_terminal = term; return true; } diff --git a/render.h b/render.h index 0c03f125..4640145b 100644 --- a/render.h +++ b/render.h @@ -16,7 +16,7 @@ void render_refresh(struct terminal *term); void render_refresh_csd(struct terminal *term); void render_refresh_search(struct terminal *term); void render_refresh_title(struct terminal *term); -bool render_xcursor_set(struct terminal *term); +bool render_xcursor_set(struct seat *seat, struct terminal *term); struct render_worker_context { int my_id; diff --git a/terminal.c b/terminal.c index ec46bb76..add0d199 100644 --- a/terminal.c +++ b/terminal.c @@ -2071,13 +2071,17 @@ term_mouse_grabbed(const struct terminal *term) /* * Mouse is grabbed by us, regardless of whether mouse tracking has been enabled or not. */ -#if 0 - return - term->wl->kbd_focus == term && - term->wl->kbd.shift && - !term->wl->kbd.alt && /*!term->wl->kbd.ctrl &&*/ !term->wl->kbd.meta; -#endif - return true; + tll_foreach(term->wl->seats, it) { + const struct seat *seat = &it->item; + + if (seat->kbd_focus == term && + seat->kbd.shift && + !seat->kbd.alt && /*!seat->kbd.ctrl &&*/ !seat->kbd.meta) + { + return true; + } + } + return false; } void @@ -2227,7 +2231,8 @@ term_xcursor_update(struct terminal *term) selection_enabled(term) ? XCURSOR_TEXT : XCURSOR_LEFT_PTR; - render_xcursor_set(term); + tll_foreach(term->wl->seats, it) + render_xcursor_set(&it->item, term); } void diff --git a/wayland.c b/wayland.c index da4f658f..19f8ce3e 100644 --- a/wayland.c +++ b/wayland.c @@ -30,8 +30,7 @@ #include "selection.h" #include "util.h" -static bool wayl_reload_cursor_theme( - struct wayland *wayl, struct terminal *term); +static bool wayl_reload_cursor_theme(struct seat *seat, struct terminal *term); static void csd_instantiate(struct wl_window *win) @@ -202,7 +201,9 @@ update_term_for_output_change(struct terminal *term) render_resize(term, term->width / term->scale, term->height / term->scale); term_font_dpi_changed(term); term_font_subpixel_changed(term); - wayl_reload_cursor_theme(term->wl, term); + + tll_foreach(term->wl->seats, it) + wayl_reload_cursor_theme(&it->item, term); } static void @@ -697,6 +698,9 @@ handle_global(void *data, struct wl_registry *registry, } else primary_selection_device = NULL; + struct wl_surface *pointer_surf + = wl_compositor_create_surface(wayl->compositor); + tll_push_back(wayl->seats, ((struct seat){ .wayl = wayl, .wl_seat = wl_seat, @@ -706,6 +710,11 @@ handle_global(void *data, struct wl_registry *registry, .fd = repeat_fd, }, }, + .pointer = { + .surface = pointer_surf, + .size = wayl->xcursor_size, + .theme_name = wayl->xcursor_theme != NULL ? strdup(wayl->xcursor_theme) : NULL, + }, .data_device = data_device, .primary_selection_device = primary_selection_device, })); @@ -882,6 +891,24 @@ wayl_init(const struct config *conf, struct fdm *fdm) wayl->fdm = fdm; wayl->fd = -1; + /* XCursor */ + const char *xcursor_theme = getenv("XCURSOR_THEME"); + if (xcursor_theme != NULL) + wayl->xcursor_theme = strdup(xcursor_theme); + wayl->xcursor_size = 24; + + { + const char *env_cursor_size = getenv("XCURSOR_SIZE"); + if (env_cursor_size != NULL) { + unsigned size; + if (sscanf(env_cursor_size, "%u", &size) == 1) + wayl->xcursor_size = size; + } + } + + LOG_INFO("cursor theme: %s, size: %u", + wayl->xcursor_theme, wayl->xcursor_size); + if (!fdm_hook_add(fdm, &fdm_hook, wayl, FDM_HOOK_PRIORITY_LOW)) { LOG_ERR("failed to add FDM hook"); goto out; @@ -950,45 +977,7 @@ wayl_init(const struct config *conf, struct fdm *fdm) } #if 0 - /* Clipboard */ - wayl->data_device = wl_data_device_manager_get_data_device( - wayl->data_device_manager, wayl->seat); - wl_data_device_add_listener(wayl->data_device, &data_device_listener, wayl); - - /* Primary selection */ - if (wayl->primary_selection_device_manager != NULL) { - wayl->primary_selection_device = zwp_primary_selection_device_manager_v1_get_device( - wayl->primary_selection_device_manager, wayl->seat); - zwp_primary_selection_device_v1_add_listener( - wayl->primary_selection_device, &primary_selection_device_listener, wayl); - } - - /* Cursor */ - unsigned cursor_size = 24; - const char *cursor_theme = getenv("XCURSOR_THEME"); - - { - const char *env_cursor_size = getenv("XCURSOR_SIZE"); - if (env_cursor_size != NULL) { - unsigned size; - if (sscanf(env_cursor_size, "%u", &size) == 1) - cursor_size = size; - } - } - - /* Note: theme is (re)loaded on scale and output changes */ - LOG_INFO("cursor theme: %s, size: %u", cursor_theme, cursor_size); - wayl->pointer.size = cursor_size; - wayl->pointer.theme_name = cursor_theme != NULL ? strdup(cursor_theme) : NULL; - - wayl->pointer.surface = wl_compositor_create_surface(wayl->compositor); - if (wayl->pointer.surface == NULL) { - LOG_ERR("failed to create cursor surface"); - goto out; - } #endif - /* All wayland initialization done - make it so */ - wl_display_roundtrip(wayl->display); wayl->fd = wl_display_get_fd(wayl->display); if (fcntl(wayl->fd, F_SETFL, fcntl(wayl->fd, F_GETFL) | O_NONBLOCK) < 0) { @@ -1043,34 +1032,12 @@ wayl_destroy(struct wayland *wayl) zxdg_output_manager_v1_destroy(wayl->xdg_output_manager); if (wayl->shell != NULL) xdg_wm_base_destroy(wayl->shell); - if (wayl->xdg_decoration_manager != NULL) zxdg_decoration_manager_v1_destroy(wayl->xdg_decoration_manager); - if (wayl->presentation != NULL) wp_presentation_destroy(wayl->presentation); - -#if 0 - if (wayl->clipboard.data_source != NULL) - wl_data_source_destroy(wayl->clipboard.data_source); - if (wayl->clipboard.data_offer != NULL) - wl_data_offer_destroy(wayl->clipboard.data_offer); - free(wayl->clipboard.text); - if (wayl->primary.data_source != NULL) - zwp_primary_selection_source_v1_destroy(wayl->primary.data_source); - if (wayl->primary.data_offer != NULL) - zwp_primary_selection_offer_v1_destroy(wayl->primary.data_offer); - free(wayl->primary.text); - - if (wayl->data_device != NULL) - wl_data_device_destroy(wayl->data_device); -#endif if (wayl->data_device_manager != NULL) wl_data_device_manager_destroy(wayl->data_device_manager); -#if 0 - if (wayl->primary_selection_device != NULL) - zwp_primary_selection_device_v1_destroy(wayl->primary_selection_device); -#endif if (wayl->primary_selection_device_manager != NULL) zwp_primary_selection_device_manager_v1_destroy(wayl->primary_selection_device_manager); if (wayl->shm != NULL) @@ -1083,10 +1050,10 @@ wayl_destroy(struct wayland *wayl) wl_registry_destroy(wayl->registry); if (wayl->fd != -1) fdm_del_no_close(wayl->fdm, wayl->fd); - if (wayl->display != NULL) { + if (wayl->display != NULL) wl_display_disconnect(wayl->display); - } + free(wayl->xcursor_theme); free(wayl); } @@ -1222,32 +1189,29 @@ wayl_win_destroy(struct wl_window *win) } static bool -wayl_reload_cursor_theme(struct wayland *wayl, struct terminal *term) +wayl_reload_cursor_theme(struct seat *seat, struct terminal *term) { -#if 0 - if (wayl->pointer.size == 0) + if (seat->pointer.size == 0) return true; - if (wayl->pointer.theme != NULL) { - wl_cursor_theme_destroy(wayl->pointer.theme); - wayl->pointer.theme = NULL; - wayl->pointer.cursor = NULL; + if (seat->pointer.theme != NULL) { + wl_cursor_theme_destroy(seat->pointer.theme); + seat->pointer.theme = NULL; + seat->pointer.cursor = NULL; } LOG_DBG("reloading cursor theme: %s@%d", - wayl->pointer.theme_name, wayl->pointer.size); + seat->pointer.theme_name, seat->pointer.size); - wayl->pointer.theme = wl_cursor_theme_load( - wayl->pointer.theme_name, wayl->pointer.size * term->scale, wayl->shm); + seat->pointer.theme = wl_cursor_theme_load( + seat->pointer.theme_name, seat->pointer.size * term->scale, seat->wayl->shm); - if (wayl->pointer.theme == NULL) { + if (seat->pointer.theme == NULL) { LOG_ERR("failed to load cursor theme"); return false; } - return render_xcursor_set(term); -#endif - return true; + return render_xcursor_set(seat, term); } void diff --git a/wayland.h b/wayland.h index 15dc6057..1232563f 100644 --- a/wayland.h +++ b/wayland.h @@ -311,12 +311,14 @@ struct wayland { struct wp_presentation *presentation; uint32_t presentation_clock_id; - bool have_argb8888; tll(struct monitor) monitors; /* All available outputs */ tll(struct seat) seats; tll(struct terminal *) terms; + + char *xcursor_theme; + unsigned xcursor_size; }; struct wayland *wayl_init(const struct config *conf, struct fdm *fdm);