From 97035106820481c7c914d266da8c708def7018d6 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Tue, 16 Jan 2024 16:12:56 +0000 Subject: [PATCH] NotificationServer: Manually calculate the text label height The layout system can't currently answer the question "what height does this Label want to be, if it has a certain width available?" Instead it relies on counting newlines, which doesn't work in a lot of cases. This made the notification windows look and behave in a funky way when their text wraps onto multiple lines. This patch uses TextLayout to measure how many lines we need, and then manually sets the Label and Window heights to match. It's a bit hacky, hence the FIXME, but it does make things behave the way they are supposed to. --- .../NotificationServer/NotificationWidget.gml | 4 +++- .../NotificationServer/NotificationWindow.cpp | 15 ++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/Userland/Services/NotificationServer/NotificationWidget.gml b/Userland/Services/NotificationServer/NotificationWidget.gml index b54f351d167..afc6d821def 100644 --- a/Userland/Services/NotificationServer/NotificationWidget.gml +++ b/Userland/Services/NotificationServer/NotificationWidget.gml @@ -17,11 +17,13 @@ name: "title" font_weight: "Bold" text_alignment: "CenterLeft" + preferred_height: "shrink" + max_height: "shrink" } @GUI::Label { name: "text" - text_alignment: "CenterLeft" + text_alignment: "TopLeft" } } } diff --git a/Userland/Services/NotificationServer/NotificationWindow.cpp b/Userland/Services/NotificationServer/NotificationWindow.cpp index c31ecfde9af..47167ff7357 100644 --- a/Userland/Services/NotificationServer/NotificationWindow.cpp +++ b/Userland/Services/NotificationServer/NotificationWindow.cpp @@ -17,6 +17,7 @@ #include #include #include +#include namespace NotificationServer { @@ -100,11 +101,15 @@ RefPtr NotificationWindow::get_window_by_id(i32 id) void NotificationWindow::resize_to_fit_text() { - auto line_height = m_text_label->font().pixel_size_rounded_up(); - auto total_height = m_text_label->text_calculated_preferred_height(); + // FIXME: It would be good if Labels could size themselves based on their available width, but for now, we have to + // do the calculation manually. + Gfx::TextLayout text_layout { m_text_label->font(), Utf8View { m_text_label->text() }, m_text_label->rect().to_type() }; + auto line_count = text_layout.lines(Gfx::TextElision::None, m_text_label->text_wrapping()).size(); - m_text_label->set_fixed_height(total_height); - set_height(40 - line_height + total_height); + auto line_height = m_text_label->font().preferred_line_height(); + auto text_height = line_height * line_count; + m_text_label->set_height(text_height); + set_height(m_title_label->height() + GUI::Layout::default_spacing + text_height + main_widget()->layout()->margins().vertical_total()); } void NotificationWindow::enter_event(Core::Event&) @@ -118,7 +123,7 @@ void NotificationWindow::enter_event(Core::Event&) void NotificationWindow::leave_event(Core::Event&) { m_hovering = false; - m_text_label->set_preferred_height(GUI::SpecialDimension::Grow); + m_text_label->set_height(40 - (m_title_label->height() + GUI::Layout::default_spacing + main_widget()->layout()->margins().vertical_total())); set_height(40); update_notification_window_locations(GUI::Desktop::the().rect()); }