From 2a6e8b132f89f9f600fa8dcb338d623aeb4697f4 Mon Sep 17 00:00:00 2001 From: nguyentiendung Date: Fri, 7 Aug 2026 20:03:03 +0700 Subject: [PATCH] Fix window not resizing to fit content, causing clipped Apply dialog GTK3 toplevel windows on Wayland don't grow to accommodate new content once mapped, so when heads are (re)populated asynchronously after the window is shown, or when switching to the "Apply Changes?" header, the window can keep its stale (too small) size and clip the settings panel (Apply/Cancel buttons, Transform, Flipped, etc). This matches #5. - main.c: explicitly resize the window to its natural size after rebuilding the head list and after switching the header stack page. - head.ui: bound the head description label with max-width-chars so a long EDID description string can't force the layout wider than intended even when wrap/ellipsize are set. --- resources/head.ui | 1 + src/main.c | 21 +++++++++++++++++++++ src/wdisplays.h | 1 + 3 files changed, 23 insertions(+) diff --git a/resources/head.ui b/resources/head.ui index c16ffaa..2efbefc 100644 --- a/resources/head.ui +++ b/resources/head.ui @@ -66,6 +66,7 @@ True word-char end + 40 0 diff --git a/src/main.c b/src/main.c index 2484a63..7372aa0 100644 --- a/src/main.c +++ b/src/main.c @@ -296,6 +296,24 @@ static void queue_canvas_draw(struct wd_state *state) { gtk_gl_area_queue_render(GTK_GL_AREA(state->canvas)); } +// GTK toplevels on Wayland don't grow to fit new content once mapped, so +// force a resize whenever a layout change may need more space than the +// window currently has (https://github.com/artizirk/wdisplays/issues/5). +static void resize_to_fit(struct wd_state *state) { + if (state->window == NULL) { + return; + } + GtkRequisition natural; + gtk_widget_get_preferred_size(state->window, NULL, &natural); + gint cur_width, cur_height; + gtk_window_get_size(GTK_WINDOW(state->window), &cur_width, &cur_height); + gint new_width = MAX(cur_width, natural.width); + gint new_height = MAX(cur_height, natural.height); + if (new_width != cur_width || new_height != cur_height) { + gtk_window_resize(GTK_WINDOW(state->window), new_width, new_height); + } +} + static void show_apply(struct wd_state *state) { const gchar *page = "title"; if (has_changes(state)) { @@ -306,6 +324,7 @@ static void show_apply(struct wd_state *state) { } } gtk_stack_set_visible_child_name(GTK_STACK(state->header_stack), page); + resize_to_fit(state); } static void update_ui(WdHeadForm *form, enum wd_head_fields fields, @@ -350,6 +369,7 @@ void wd_ui_reset_heads(struct wd_state *state) { } update_canvas_size(state); queue_canvas_draw(state); + resize_to_fit(state); } void wd_ui_reset_head(const struct wd_head *head, enum wd_head_fields fields) { @@ -938,6 +958,7 @@ static void activate(GtkApplication* app, gpointer user_data) { GtkBuilder *builder = gtk_builder_new_from_resource( WDISPLAYS_RESOURCE_PREFIX "/wdisplays.ui"); GtkWidget *window = GTK_WIDGET(gtk_builder_get_object(builder, "heads_window")); + state->window = window; state->main_box = GTK_WIDGET(gtk_builder_get_object(builder, "main_box")); state->header_stack = GTK_WIDGET(gtk_builder_get_object(builder, "header_stack")); state->stack_switcher = GTK_WIDGET(gtk_builder_get_object(builder, "heads_stack_switcher")); diff --git a/src/wdisplays.h b/src/wdisplays.h index 4824017..f0c919f 100644 --- a/src/wdisplays.h +++ b/src/wdisplays.h @@ -200,6 +200,7 @@ struct wd_state { bool panning; struct wd_point pan_start; + GtkWidget *window; GtkWidget *main_box; GtkWidget *header_stack; GtkWidget *stack_switcher;