diff --git a/lib/renderers/cairo.h b/lib/renderers/cairo.h index c5a3be4..4c1bd86 100644 --- a/lib/renderers/cairo.h +++ b/lib/renderers/cairo.h @@ -12,6 +12,7 @@ struct cairo { cairo_t *cr; cairo_surface_t *surface; PangoContext *pango; + int scale; }; struct cairo_color { @@ -129,6 +130,10 @@ bm_cairo_draw_line(struct cairo *cairo, struct cairo_paint *paint, struct cairo_ if (!ret) return false; + + assert(cairo->scale > 0); + cairo_scale(cairo->cr, cairo->scale, cairo->scale); + PangoLayout *layout = bm_pango_get_layout(cairo, paint, buffer); pango_cairo_update_layout(cairo->cr, layout); @@ -152,6 +157,8 @@ bm_cairo_draw_line(struct cairo *cairo, struct cairo_paint *paint, struct cairo_ result->x_advance = width + paint->box.rx; result->height = height + paint->box.by + paint->box.ty; + + cairo_identity_matrix(cairo->cr); return true; } @@ -293,7 +300,7 @@ bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t max_height, const s cl += result.x_advance + 1; } - for (uint32_t i = menu->index; i < count && cl < width; ++i) { + for (uint32_t i = menu->index; i < count && cl < (width/cairo->scale); ++i) { bool highlighted = (items[i] == bm_menu_get_highlighted_item(menu)); if (highlighted) { @@ -319,7 +326,7 @@ bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t max_height, const s bm_cairo_color_from_menu_color(menu, BM_COLOR_FILTER_FG, &paint.fg); bm_cairo_color_from_menu_color(menu, BM_COLOR_FILTER_BG, &paint.bg); bm_pango_get_text_extents(cairo, &paint, &result, ">"); - paint.pos = (struct pos){ width - result.x_advance - 2, vpadding }; + paint.pos = (struct pos){ width/cairo->scale - result.x_advance - 2, vpadding }; paint.box = (struct box){ 1, 2, vpadding, vpadding, 0, ascii_height }; bm_cairo_draw_line(cairo, &paint, &result, ">"); } diff --git a/lib/renderers/wayland/registry.c b/lib/renderers/wayland/registry.c index 726ed94..7ab5d2a 100644 --- a/lib/renderers/wayland/registry.c +++ b/lib/renderers/wayland/registry.c @@ -243,7 +243,11 @@ display_handle_done(void *data, struct wl_output *wl_output) static void display_handle_scale(void *data, struct wl_output *wl_output, int32_t scale) { - (void)data, (void)wl_output, (void)scale; + (void)wl_output; + struct output *output = data; + + assert(scale > 0); + output->scale = scale; } static void @@ -271,7 +275,7 @@ registry_handle_global(void *data, struct wl_registry *registry, uint32_t id, co struct wayland *wayland = data; if (strcmp(interface, "wl_compositor") == 0) { - wayland->compositor = wl_registry_bind(registry, id, &wl_compositor_interface, 1); + wayland->compositor = wl_registry_bind(registry, id, &wl_compositor_interface, 3); } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { wayland->layer_shell = wl_registry_bind(registry, id, &zwlr_layer_shell_v1_interface, 1); } else if (strcmp(interface, "wl_seat") == 0) { @@ -284,6 +288,7 @@ registry_handle_global(void *data, struct wl_registry *registry, uint32_t id, co struct wl_output *wl_output = wl_registry_bind(registry, id, &wl_output_interface, 2); struct output *output = calloc(1, sizeof(struct output)); output->output = wl_output; + output->scale = 1; wl_list_insert(&wayland->outputs, &output->link); wl_output_add_listener(wl_output, &output_listener, output); } diff --git a/lib/renderers/wayland/wayland.c b/lib/renderers/wayland/wayland.c index 94fcfd5..572b994 100644 --- a/lib/renderers/wayland/wayland.c +++ b/lib/renderers/wayland/wayland.c @@ -278,8 +278,12 @@ constructor(struct bm_menu *menu) struct wl_surface *surface; if (!(surface = wl_compositor_create_surface(wayland->compositor))) goto fail; + + wl_surface_set_buffer_scale(surface, output->scale); + struct window *window = calloc(1, sizeof(struct window)); window->bottom = menu->bottom; + window->scale = output->scale; if (!bm_wl_window_create(window, wayland->display, wayland->shm, output->output, wayland->layer_shell, surface)) goto fail; window->notify.render = bm_cairo_paint; diff --git a/lib/renderers/wayland/wayland.h b/lib/renderers/wayland/wayland.h index 752f095..3e9f869 100644 --- a/lib/renderers/wayland/wayland.h +++ b/lib/renderers/wayland/wayland.h @@ -81,6 +81,7 @@ struct window { struct wl_shm *shm; struct buffer buffers[2]; uint32_t width, height, max_height; + int32_t scale; uint32_t displayed; struct wl_list link; bool bottom; @@ -95,6 +96,7 @@ struct output { struct wl_output *output; struct wl_list link; int height; + int scale; }; struct wayland { diff --git a/lib/renderers/wayland/window.c b/lib/renderers/wayland/window.c index ef515b2..84077f5 100644 --- a/lib/renderers/wayland/window.c +++ b/lib/renderers/wayland/window.c @@ -107,7 +107,7 @@ destroy_buffer(struct buffer *buffer) } static bool -create_buffer(struct wl_shm *shm, struct buffer *buffer, int32_t width, int32_t height, uint32_t format) +create_buffer(struct wl_shm *shm, struct buffer *buffer, int32_t width, int32_t height, uint32_t format, int32_t scale) { int fd = -1; struct wl_shm_pool *pool = NULL; @@ -151,6 +151,7 @@ create_buffer(struct wl_shm *shm, struct buffer *buffer, int32_t width, int32_t goto fail; } + buffer->cairo.scale = scale; buffer->width = width; buffer->height = height; return true; @@ -181,10 +182,10 @@ next_buffer(struct window *window) if (!buffer) return NULL; - if (window->width != buffer->width || window->height != buffer->height) + if (window->width * window->scale != buffer->width || window->height * window->scale != buffer->height) destroy_buffer(buffer); - if (!buffer->buffer && !create_buffer(window->shm, buffer, window->width, window->height, WL_SHM_FORMAT_ARGB8888)) + if (!buffer->buffer && !create_buffer(window->shm, buffer, window->width * window->scale, window->height * window->scale, WL_SHM_FORMAT_ARGB8888, window->scale)) return NULL; return buffer; @@ -231,7 +232,7 @@ bm_wl_window_render(struct window *window, struct wl_display *display, const str break; struct cairo_paint_result result; - window->notify.render(&buffer->cairo, buffer->width, window->max_height, menu, &result); + window->notify.render(&buffer->cairo, buffer->width, window->max_height * window->scale, menu, &result); window->displayed = result.displayed; if (window->height == result.height) diff --git a/lib/renderers/x11/window.c b/lib/renderers/x11/window.c index cf2d986..17e62b3 100644 --- a/lib/renderers/x11/window.c +++ b/lib/renderers/x11/window.c @@ -25,6 +25,7 @@ create_buffer(struct window *window, struct buffer *buffer, int32_t width, int32 goto fail; } + buffer->cairo.scale = 1; buffer->width = width; buffer->height = height; buffer->created = true;