mirror of
https://github.com/Cloudef/bemenu
synced 2025-02-21 17:36:48 +00:00
Merge pull request #70 from lheckemann/hidpi
Handle HiDPI scaling on Wayland
This commit is contained in:
commit
c9d9bcdaf5
@ -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, ">");
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user