From d5bc46f333523353fb9c84865a025b03c94417b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 21 Aug 2019 17:53:52 +0200 Subject: [PATCH] render: reload cursor theme when scale (may) have changed --- main.c | 25 ++++++++++--------------- render.c | 42 ++++++++++++++++++++++++++++++++++++++++++ render.h | 4 +++- terminal.h | 2 ++ 4 files changed, 57 insertions(+), 16 deletions(-) diff --git a/main.c b/main.c index 9f90caf8..5b750f35 100644 --- a/main.c +++ b/main.c @@ -128,6 +128,7 @@ output_scale(void *data, struct wl_output *wl_output, int32_t factor) { struct monitor *mon = data; mon->scale = factor; + render_reload_cursor_theme(mon->term); render_resize(mon->term, mon->term->width, mon->term->height); } @@ -259,6 +260,7 @@ surface_enter(void *data, struct wl_surface *wl_surface, tll_push_back(term->wl.on_outputs, &it->item); /* Resize, since scale-to-use may have changed */ + render_reload_cursor_theme(term); render_resize(term, term->width, term->height); return; } @@ -280,6 +282,7 @@ surface_leave(void *data, struct wl_surface *wl_surface, tll_remove(term->wl.on_outputs, it); /* Resize, since scale-to-use may have changed */ + render_reload_cursor_theme(term); render_resize(term, term->width, term->height); return; } @@ -669,12 +672,6 @@ main(int argc, char *const *argv) term.wl.primary_selection_device, &primary_selection_device_listener, &term); /* Cursor */ - term.wl.pointer.surface = wl_compositor_create_surface(term.wl.compositor); - if (term.wl.pointer.surface == NULL) { - LOG_ERR("failed to create cursor surface"); - goto out; - } - unsigned cursor_size = 24; const char *cursor_theme = getenv("XCURSOR_THEME"); @@ -687,20 +684,17 @@ main(int argc, char *const *argv) } } + /* Note: theme is (re)loaded on scale and output changes */ LOG_INFO("cursor theme: %s, size: %u", cursor_theme, cursor_size); + term.wl.pointer.size = cursor_size; + term.wl.pointer.theme_name = cursor_theme != NULL ? strdup(cursor_theme) : NULL; - term.wl.pointer.theme = wl_cursor_theme_load( - cursor_theme, cursor_size * term.scale, term.wl.shm); - if (term.wl.pointer.theme == NULL) { - LOG_ERR("failed to load cursor theme"); + term.wl.pointer.surface = wl_compositor_create_surface(term.wl.compositor); + if (term.wl.pointer.surface == NULL) { + LOG_ERR("failed to create cursor surface"); goto out; } - term.wl.pointer.cursor = wl_cursor_theme_get_cursor( - term.wl.pointer.theme, "left_ptr"); - assert(term.wl.pointer.cursor != NULL); - render_update_cursor_surface(&term); - term.wl.surface = wl_compositor_create_surface(term.wl.compositor); if (term.wl.surface == NULL) { LOG_ERR("failed to create wayland surface"); @@ -999,6 +993,7 @@ out: xdg_toplevel_destroy(term.wl.xdg_toplevel); if (term.wl.xdg_surface != NULL) xdg_surface_destroy(term.wl.xdg_surface); + free(term.wl.pointer.theme_name); if (term.wl.pointer.theme != NULL) wl_cursor_theme_destroy(term.wl.pointer.theme); if (term.wl.pointer.pointer != NULL) diff --git a/render.c b/render.c index 92558d42..22f428f7 100644 --- a/render.c +++ b/render.c @@ -812,6 +812,48 @@ render_set_title(struct terminal *term, const char *title) xdg_toplevel_set_title(term->wl.xdg_toplevel, title); } +bool +render_reload_cursor_theme(struct terminal *term) +{ + if (term->wl.pointer.size == 0) + return true; + + int scale = -1; + tll_foreach(term->wl.on_outputs, it) { + if (it->item->scale > scale) + scale = it->item->scale; + } + + if (scale == -1) { + /* Haven't 'entered' an output yet? */ + LOG_WARN("unknown scale, using '1'"); + scale = 1; + } + + if (term->wl.pointer.theme != NULL) { + wl_cursor_theme_destroy(term->wl.pointer.theme); + term->wl.pointer.theme = NULL; + term->wl.pointer.cursor = NULL; + } + + LOG_DBG("reloading cursor theme: %s@%d", + term->wl.pointer.theme_name, term->wl.pointer.size); + + term->wl.pointer.theme = wl_cursor_theme_load( + term->wl.pointer.theme_name, term->wl.pointer.size * scale, term->wl.shm); + if (term->wl.pointer.theme == NULL) { + LOG_ERR("failed to load cursor theme"); + return false; + } + + term->wl.pointer.cursor = wl_cursor_theme_get_cursor( + term->wl.pointer.theme, "left_ptr"); + assert(term->wl.pointer.cursor != NULL); + render_update_cursor_surface(term); + + return true; +} + void render_update_cursor_surface(struct terminal *term) { diff --git a/render.h b/render.h index 0b7a40ca..a3620665 100644 --- a/render.h +++ b/render.h @@ -8,9 +8,11 @@ struct font *attrs_to_font( void grid_render(struct terminal *term); void render_resize(struct terminal *term, int width, int height); void render_set_title(struct terminal *term, const char *title); -void render_update_cursor_surface(struct terminal *term); void render_refresh(struct terminal *term); +bool render_reload_cursor_theme(struct terminal *term); +void render_update_cursor_surface(struct terminal *term); + struct render_worker_context { int my_id; struct terminal *term; diff --git a/terminal.h b/terminal.h index b205a0a7..02caec6b 100644 --- a/terminal.h +++ b/terminal.h @@ -57,6 +57,8 @@ struct wayland { struct wl_surface *surface; struct wl_cursor_theme *theme; struct wl_cursor *cursor; + int size; + char *theme_name; } pointer; struct xdg_wm_base *shell; struct xdg_surface *xdg_surface;