From f028bc93db3d51072c8a019c3bf6c56077c39e0b Mon Sep 17 00:00:00 2001 From: Haoyu Qiu Date: Mon, 9 Jun 2025 15:12:54 +0800 Subject: [PATCH] Fix window title drawn outside the title bar --- doc/classes/TextServer.xml | 2 ++ doc/classes/Window.xml | 4 ++-- scene/main/viewport.cpp | 25 ++++++++++++++----------- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/doc/classes/TextServer.xml b/doc/classes/TextServer.xml index 6023cd23665..aef75e549f7 100644 --- a/doc/classes/TextServer.xml +++ b/doc/classes/TextServer.xml @@ -1400,6 +1400,7 @@ Draw shaped text into a canvas item at a given position, with [param color]. [param pos] specifies the leftmost point of the baseline (for horizontal layout) or topmost point of the baseline (for vertical layout). If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used. + [param clip_l] and [param clip_r] are offsets relative to [param pos], going to the right in horizontal layout and downward in vertical layout. If [param clip_l] is not negative, glyphs starting before the offset are clipped. If [param clip_r] is not negative, glyphs ending after the offset are clipped. @@ -1414,6 +1415,7 @@ Draw the outline of the shaped text into a canvas item at a given position, with [param color]. [param pos] specifies the leftmost point of the baseline (for horizontal layout) or topmost point of the baseline (for vertical layout). If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used. + [param clip_l] and [param clip_r] are offsets relative to [param pos], going to the right in horizontal layout and downward in vertical layout. If [param clip_l] is not negative, glyphs starting before the offset are clipped. If [param clip_r] is not negative, glyphs ending after the offset are clipped. diff --git a/doc/classes/Window.xml b/doc/classes/Window.xml index c1c744a0745..d02d5be6442 100644 --- a/doc/classes/Window.xml +++ b/doc/classes/Window.xml @@ -991,10 +991,10 @@ The color of the title's text outline. - Horizontal position offset of the close button. + Horizontal position offset of the close button, relative to the end of the title bar, towards the beginning of the title bar. - Vertical position offset of the close button. + Vertical position offset of the close button, relative to the bottom of the title bar, towards the top of the title bar. Defines the outside margin at which the window border can be grabbed with mouse and resized. diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index f57cc3cfffe..f35ecdc2033 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -337,7 +337,7 @@ void Viewport::_sub_window_update(Window *p_window) { sw.pending_window_update = false; RS::get_singleton()->canvas_item_clear(sw.canvas_item); - Rect2i r = Rect2i(p_window->get_position(), p_window->get_size()); + const Rect2i r = Rect2i(p_window->get_position(), p_window->get_size()); if (!p_window->get_flag(Window::FLAG_BORDERLESS)) { Ref panel = gui.subwindow_focused == p_window ? p_window->theme_cache.embedded_border : p_window->theme_cache.embedded_unfocused_border; @@ -351,18 +351,21 @@ void Viewport::_sub_window_update(Window *p_window) { int close_h_ofs = p_window->theme_cache.close_h_offset; int close_v_ofs = p_window->theme_cache.close_v_offset; - TextLine title_text = TextLine(p_window->get_translated_title(), title_font, font_size); - title_text.set_width(r.size.width - panel->get_minimum_size().x - close_h_ofs); - title_text.set_direction(p_window->is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR); - int x = (r.size.width - title_text.get_size().x) / 2; - int y = (-title_height - title_text.get_size().y) / 2; + const real_t title_space = r.size.width - panel->get_minimum_size().x - close_h_ofs; + if (title_space > 0) { + TextLine title_text = TextLine(p_window->get_translated_title(), title_font, font_size); + title_text.set_width(title_space); + title_text.set_direction(p_window->is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR); + int x = (r.size.width - title_text.get_size().x) / 2; + int y = (-title_height - title_text.get_size().y) / 2; - Color font_outline_color = p_window->theme_cache.title_outline_modulate; - int outline_size = p_window->theme_cache.title_outline_size; - if (outline_size > 0 && font_outline_color.a > 0) { - title_text.draw_outline(sw.canvas_item, r.position + Point2(x, y), outline_size, font_outline_color); + Color font_outline_color = p_window->theme_cache.title_outline_modulate; + int outline_size = p_window->theme_cache.title_outline_size; + if (outline_size > 0 && font_outline_color.a > 0) { + title_text.draw_outline(sw.canvas_item, r.position + Point2(x, y), outline_size, font_outline_color); + } + title_text.draw(sw.canvas_item, r.position + Point2(x, y), title_color); } - title_text.draw(sw.canvas_item, r.position + Point2(x, y), title_color); bool pressed = gui.subwindow_focused == sw.window && gui.subwindow_drag == SUB_WINDOW_DRAG_CLOSE && gui.subwindow_drag_close_inside; Ref close_icon = pressed ? p_window->theme_cache.close_pressed : p_window->theme_cache.close;