From e87aa19066e5dae6ddfe1f4c5d4537474083436a Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Sun, 29 May 2022 18:34:25 +0200 Subject: [PATCH] Fix dynamic output based scaling for menu and SSD wlr_scene_buffers need an additional wlr_scene_buffer_set_source_box() to be scaled correctly by wlroots based on the output scale. With this commit the buffers are now scaled correctly but, especially on higher scale factors, may be a bit blurry. In the future we likely want a dynamic font label generator based on the maximal scale of all the outputs the specific buffer is currently on. Some inspiration for that could be https://github.com/Nefsen402/sway/blob/scene-graph/sway/sway_text_buffer.c Fixes #348 --- src/menu/menu.c | 19 +++++++++++++++---- src/ssd/ssd_part.c | 6 +++++- src/ssd/ssd_titlebar.c | 13 +++++++++++-- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/menu/menu.c b/src/menu/menu.c index 50bc9724..5f814077 100644 --- a/src/menu/menu.c +++ b/src/menu/menu.c @@ -75,6 +75,17 @@ menu_get_by_id(const char *id) return NULL; } +static struct wlr_scene_node * +create_scaling_buffer(struct wlr_scene_node *parent, struct wlr_buffer *buffer) +{ + struct wlr_scene_buffer *scene_buffer = + wlr_scene_buffer_create(parent, buffer); + /* Make sure output scaling works correctly */ + struct wlr_fbox source_box = { 0, 0, buffer->width, buffer->height }; + wlr_scene_buffer_set_source_box(scene_buffer, &source_box); + return &scene_buffer->node; +} + static struct menuitem * item_create(struct menu *menu, const char *text) { @@ -126,10 +137,10 @@ item_create(struct menu *menu, const char *text) theme->menu_items_active_bg_color)->node; /* Font nodes */ - menuitem->normal.text = &wlr_scene_buffer_create( - menuitem->normal.background, &menuitem->normal.buffer->base)->node; - menuitem->selected.text = &wlr_scene_buffer_create( - menuitem->selected.background, &menuitem->selected.buffer->base)->node; + menuitem->normal.text = create_scaling_buffer( + menuitem->normal.background, &menuitem->normal.buffer->base); + menuitem->selected.text = create_scaling_buffer( + menuitem->selected.background, &menuitem->selected.buffer->base); /* Node descriptors for top scene nodes of menuitem */ node_descriptor_create(menuitem->normal.background, diff --git a/src/ssd/ssd_part.c b/src/ssd/ssd_part.c index ec754697..fa8b6ac1 100644 --- a/src/ssd/ssd_part.c +++ b/src/ssd/ssd_part.c @@ -40,7 +40,11 @@ add_scene_buffer(struct wl_list *list, enum ssd_part_type type, int x, int y) { struct ssd_part *part = add_scene_part(list, type); - part->node = &wlr_scene_buffer_create(parent, buffer)->node; + struct wlr_scene_buffer *scene_buffer = + wlr_scene_buffer_create(parent, buffer); + part->node = &scene_buffer->node; + struct wlr_fbox source_box = { 0, 0, buffer->width, buffer->height }; + wlr_scene_buffer_set_source_box(scene_buffer, &source_box); wlr_scene_node_set_position(part->node, x, y); return part; } diff --git a/src/ssd/ssd_titlebar.c b/src/ssd/ssd_titlebar.c index 7a80a0a7..4183e9a1 100644 --- a/src/ssd/ssd_titlebar.c +++ b/src/ssd/ssd_titlebar.c @@ -221,6 +221,7 @@ ssd_update_title(struct view *view) struct ssd_part *parent_part; struct ssd_sub_tree *subtree; struct ssd_state_title_width *dstate; + struct wlr_scene_buffer *scene_buffer; FOR_EACH_STATE(view, subtree) { parent_part = ssd_get_part(&subtree->parts, LAB_SSD_PART_TITLEBAR); assert(parent_part); @@ -259,11 +260,19 @@ ssd_update_title(struct view *view) wlr_log(WLR_ERROR, "Failed to create title buffer"); } + scene_buffer = wlr_scene_buffer_from_node(part->node); + /* (Re)set the buffer */ - wlr_scene_buffer_set_buffer( - wlr_scene_buffer_from_node(part->node), + wlr_scene_buffer_set_buffer(scene_buffer, part->buffer ? &part->buffer->base : NULL); + /* Make sure output scaling works correctly */ + if (part->buffer) { + struct wlr_fbox source_box = {0, 0, + part->buffer->base.width, part->buffer->base.height }; + wlr_scene_buffer_set_source_box(scene_buffer, &source_box); + } + /* And finally update the cache */ dstate->width = part->buffer ? part->buffer->base.width : 0; dstate->truncated = rect->width <= dstate->width;