Merge pull request #70 from lheckemann/hidpi

Handle HiDPI scaling on Wayland
This commit is contained in:
Jari Vetoniemi 2019-11-05 21:04:22 +09:00 committed by GitHub
commit c9d9bcdaf5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 28 additions and 8 deletions

View File

@ -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, ">");
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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 {

View File

@ -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)

View File

@ -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;