swaybar: fix cursor scale

This fixes a few issues with swaybar's cursor scaling:
1. The cursor scale is now changed when the output scale changes
2. The cursor scale is no longer bound by the max output scale when
swaybar is launched
3. Related to the previous item, the cursor is no longer tiny on low
scale outputs after the max output scale has changed

This also bumps up `wl_compositor` to version 4 to allow usage of
`wl_surface_damage_buffer`.
master
Brian Ashworth 6 years ago committed by emersion
parent cd714cc12a
commit 35a82a8693

@ -4,6 +4,7 @@
#include <wayland-client.h> #include <wayland-client.h>
#include "list.h" #include "list.h"
struct swaybar;
struct swaybar_output; struct swaybar_output;
struct swaybar_pointer { struct swaybar_pointer {
@ -13,6 +14,7 @@ struct swaybar_pointer {
struct wl_surface *cursor_surface; struct wl_surface *cursor_surface;
struct swaybar_output *current; struct swaybar_output *current;
int x, y; int x, y;
uint32_t serial;
}; };
enum x11_button { enum x11_button {
@ -45,6 +47,8 @@ struct swaybar_hotspot {
extern const struct wl_seat_listener seat_listener; extern const struct wl_seat_listener seat_listener;
void update_cursor(struct swaybar *bar);
void free_hotspots(struct wl_list *list); void free_hotspots(struct wl_list *list);
#endif #endif

@ -196,6 +196,10 @@ static void output_scale(void *data, struct wl_output *wl_output,
int32_t factor) { int32_t factor) {
struct swaybar_output *output = data; struct swaybar_output *output = data;
output->scale = factor; output->scale = factor;
if (output == output->bar->pointer.current) {
update_cursor(output->bar);
render_frame(output);
}
} }
struct wl_output_listener output_listener = { struct wl_output_listener output_listener = {
@ -273,7 +277,7 @@ static void handle_global(void *data, struct wl_registry *registry,
struct swaybar *bar = data; struct swaybar *bar = data;
if (strcmp(interface, wl_compositor_interface.name) == 0) { if (strcmp(interface, wl_compositor_interface.name) == 0) {
bar->compositor = wl_registry_bind(registry, name, bar->compositor = wl_registry_bind(registry, name,
&wl_compositor_interface, 3); &wl_compositor_interface, 4);
} else if (strcmp(interface, wl_seat_interface.name) == 0) { } else if (strcmp(interface, wl_seat_interface.name) == 0) {
bar->seat = wl_registry_bind(registry, name, bar->seat = wl_registry_bind(registry, name,
&wl_seat_interface, 3); &wl_seat_interface, 3);
@ -355,22 +359,6 @@ bool bar_setup(struct swaybar *bar, const char *socket_path) {
wl_display_roundtrip(bar->display); wl_display_roundtrip(bar->display);
struct swaybar_pointer *pointer = &bar->pointer; 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); pointer->cursor_surface = wl_compositor_create_surface(bar->compositor);
assert(pointer->cursor_surface); assert(pointer->cursor_surface);

@ -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, static void wl_pointer_enter(void *data, struct wl_pointer *wl_pointer,
uint32_t serial, struct wl_surface *surface, uint32_t serial, struct wl_surface *surface,
wl_fixed_t surface_x, wl_fixed_t surface_y) { wl_fixed_t surface_x, wl_fixed_t surface_y) {
struct swaybar *bar = data; struct swaybar *bar = data;
struct swaybar_pointer *pointer = &bar->pointer; struct swaybar_pointer *pointer = &bar->pointer;
pointer->serial = serial;
struct swaybar_output *output; struct swaybar_output *output;
wl_list_for_each(output, &bar->outputs, link) { wl_list_for_each(output, &bar->outputs, link) {
if (output->surface == surface) { if (output->surface == surface) {
@ -67,20 +90,7 @@ static void wl_pointer_enter(void *data, struct wl_pointer *wl_pointer,
break; break;
} }
} }
int max_scale = 1; update_cursor(bar);
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);
} }
static void wl_pointer_leave(void *data, struct wl_pointer *wl_pointer, static void wl_pointer_leave(void *data, struct wl_pointer *wl_pointer,

Loading…
Cancel
Save