diff --git a/include/swaybar/input.h b/include/swaybar/input.h index 390309a0..f480d009 100644 --- a/include/swaybar/input.h +++ b/include/swaybar/input.h @@ -4,6 +4,7 @@ #include #include "list.h" +struct swaybar; struct swaybar_output; struct swaybar_pointer { @@ -13,6 +14,7 @@ struct swaybar_pointer { struct wl_surface *cursor_surface; struct swaybar_output *current; int x, y; + uint32_t serial; }; enum x11_button { @@ -45,6 +47,8 @@ struct swaybar_hotspot { extern const struct wl_seat_listener seat_listener; +void update_cursor(struct swaybar *bar); + void free_hotspots(struct wl_list *list); #endif diff --git a/swaybar/bar.c b/swaybar/bar.c index 47c89a39..53e798bc 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -196,6 +196,10 @@ static void output_scale(void *data, struct wl_output *wl_output, int32_t factor) { struct swaybar_output *output = data; output->scale = factor; + if (output == output->bar->pointer.current) { + update_cursor(output->bar); + render_frame(output); + } } struct wl_output_listener output_listener = { @@ -273,7 +277,7 @@ static void handle_global(void *data, struct wl_registry *registry, struct swaybar *bar = data; if (strcmp(interface, wl_compositor_interface.name) == 0) { bar->compositor = wl_registry_bind(registry, name, - &wl_compositor_interface, 3); + &wl_compositor_interface, 4); } else if (strcmp(interface, wl_seat_interface.name) == 0) { bar->seat = wl_registry_bind(registry, name, &wl_seat_interface, 3); @@ -355,22 +359,6 @@ bool bar_setup(struct swaybar *bar, const char *socket_path) { wl_display_roundtrip(bar->display); struct swaybar_pointer *pointer = &bar->pointer; - - int max_scale = 1; - struct swaybar_output *output; - wl_list_for_each(output, &bar->outputs, link) { - if (output->scale > max_scale) { - max_scale = output->scale; - } - } - - pointer->cursor_theme = - wl_cursor_theme_load(NULL, 24 * max_scale, bar->shm); - assert(pointer->cursor_theme); - struct wl_cursor *cursor; - cursor = wl_cursor_theme_get_cursor(pointer->cursor_theme, "left_ptr"); - assert(cursor); - pointer->cursor_image = cursor->images[0]; pointer->cursor_surface = wl_compositor_create_surface(bar->compositor); assert(pointer->cursor_surface); diff --git a/swaybar/input.c b/swaybar/input.c index 1f8491f6..7d219be3 100644 --- a/swaybar/input.c +++ b/swaybar/input.c @@ -55,11 +55,34 @@ static enum x11_button wl_axis_to_x11_button(uint32_t axis, wl_fixed_t value) { } } +void update_cursor(struct swaybar *bar) { + struct swaybar_pointer *pointer = &bar->pointer; + if (pointer->cursor_theme) { + wl_cursor_theme_destroy(pointer->cursor_theme); + } + int scale = pointer->current ? pointer->current->scale : 1; + pointer->cursor_theme = wl_cursor_theme_load(NULL, 24 * scale, bar->shm); + struct wl_cursor *cursor; + cursor = wl_cursor_theme_get_cursor(pointer->cursor_theme, "left_ptr"); + pointer->cursor_image = cursor->images[0]; + wl_surface_set_buffer_scale(pointer->cursor_surface, scale); + wl_surface_attach(pointer->cursor_surface, + wl_cursor_image_get_buffer(pointer->cursor_image), 0, 0); + wl_pointer_set_cursor(pointer->pointer, pointer->serial, + pointer->cursor_surface, + pointer->cursor_image->hotspot_x / scale, + pointer->cursor_image->hotspot_y / scale); + wl_surface_damage_buffer(pointer->cursor_surface, 0, 0, + INT32_MAX, INT32_MAX); + wl_surface_commit(pointer->cursor_surface); +} + static void wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t surface_x, wl_fixed_t surface_y) { struct swaybar *bar = data; struct swaybar_pointer *pointer = &bar->pointer; + pointer->serial = serial; struct swaybar_output *output; wl_list_for_each(output, &bar->outputs, link) { if (output->surface == surface) { @@ -67,20 +90,7 @@ static void wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, break; } } - int max_scale = 1; - struct swaybar_output *_output; - wl_list_for_each(_output, &bar->outputs, link) { - if (_output->scale > max_scale) { - max_scale = _output->scale; - } - } - wl_surface_set_buffer_scale(pointer->cursor_surface, max_scale); - wl_surface_attach(pointer->cursor_surface, - wl_cursor_image_get_buffer(pointer->cursor_image), 0, 0); - wl_pointer_set_cursor(wl_pointer, serial, pointer->cursor_surface, - pointer->cursor_image->hotspot_x / max_scale, - pointer->cursor_image->hotspot_y / max_scale); - wl_surface_commit(pointer->cursor_surface); + update_cursor(bar); } static void wl_pointer_leave(void *data, struct wl_pointer *wl_pointer,