diff options
author | Tom <tomut@yahoo.com> | 2021-06-25 09:18:20 -0600 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-06-25 20:38:13 +0200 |
commit | 84cab29c59259fc2fdbcc7003ecfcd5880c95898 (patch) | |
tree | e64f0619e6006c3dd1fb54705ba132d179584337 | |
parent | 8b26debda1e486532f068d0916512bbb198d22bb (diff) | |
download | serenity-84cab29c59259fc2fdbcc7003ecfcd5880c95898.zip |
WindowServer: Change window geometry label to use the Overlay class
This enables flicker-free rendering.
-rw-r--r-- | Userland/Services/WindowServer/Compositor.cpp | 50 | ||||
-rw-r--r-- | Userland/Services/WindowServer/Compositor.h | 2 | ||||
-rw-r--r-- | Userland/Services/WindowServer/Overlays.cpp | 48 | ||||
-rw-r--r-- | Userland/Services/WindowServer/Overlays.h | 19 | ||||
-rw-r--r-- | Userland/Services/WindowServer/Window.cpp | 2 | ||||
-rw-r--r-- | Userland/Services/WindowServer/WindowManager.cpp | 18 | ||||
-rw-r--r-- | Userland/Services/WindowServer/WindowManager.h | 4 |
7 files changed, 93 insertions, 50 deletions
diff --git a/Userland/Services/WindowServer/Compositor.cpp b/Userland/Services/WindowServer/Compositor.cpp index 191166fffa..e519f2b926 100644 --- a/Userland/Services/WindowServer/Compositor.cpp +++ b/Userland/Services/WindowServer/Compositor.cpp @@ -157,13 +157,8 @@ void Compositor::compose() auto dirty_screen_rects = move(m_dirty_screen_rects); auto* dnd_client = wm.dnd_client(); - if (!m_last_geometry_label_damage_rect.is_empty() || !m_last_dnd_rect.is_empty() || (m_invalidated_cursor && dnd_client)) { + if (!m_last_dnd_rect.is_empty() || (m_invalidated_cursor && dnd_client)) { Screen::for_each([&](auto& screen) { - if (!m_last_geometry_label_damage_rect.is_empty()) { - auto rect = m_last_geometry_label_damage_rect.intersected(screen.rect()); - if (!rect.is_empty()) - dirty_screen_rects.add(rect); - } if (!m_last_dnd_rect.is_empty()) { auto rect = m_last_dnd_rect.intersected(screen.rect()); if (!rect.is_empty()) @@ -542,8 +537,6 @@ void Compositor::compose() screen_data.m_back_painter->blit(rect.location(), *screen_data.m_temp_bitmap, rect.translated(-screen_rect.location())); return IterationDecision::Continue; }); - - draw_geometry_label(cursor_screen); } m_invalidated_any = false; @@ -869,46 +862,6 @@ void Compositor::invalidate_cursor(bool compose_immediately) start_compose_async_timer(); } -void Compositor::draw_geometry_label(Screen& screen) -{ - auto& wm = WindowManager::the(); - auto* window_being_moved_or_resized = wm.m_move_window ? wm.m_move_window.ptr() : (wm.m_resize_window ? wm.m_resize_window.ptr() : nullptr); - if (!window_being_moved_or_resized) { - m_last_geometry_label_damage_rect = {}; - return; - } - auto geometry_string = window_being_moved_or_resized->rect().to_string(); - if (!window_being_moved_or_resized->size_increment().is_null()) { - int width_steps = (window_being_moved_or_resized->width() - window_being_moved_or_resized->base_size().width()) / window_being_moved_or_resized->size_increment().width(); - int height_steps = (window_being_moved_or_resized->height() - window_being_moved_or_resized->base_size().height()) / window_being_moved_or_resized->size_increment().height(); - geometry_string = String::formatted("{} ({}x{})", geometry_string, width_steps, height_steps); - } - - auto geometry_label_rect = Gfx::IntRect { 0, 0, wm.font().width(geometry_string) + 16, wm.font().glyph_height() + 10 }; - geometry_label_rect.center_within(window_being_moved_or_resized->rect()); - auto desktop_rect = wm.desktop_rect(screen); - if (geometry_label_rect.left() < desktop_rect.left()) - geometry_label_rect.set_left(desktop_rect.left()); - if (geometry_label_rect.top() < desktop_rect.top()) - geometry_label_rect.set_top(desktop_rect.top()); - if (geometry_label_rect.right() > desktop_rect.right()) - geometry_label_rect.set_right_without_resize(desktop_rect.right()); - if (geometry_label_rect.bottom() > desktop_rect.bottom()) - geometry_label_rect.set_bottom_without_resize(desktop_rect.bottom()); - - auto& screen_data = m_screen_data[screen.index()]; - auto& back_painter = *screen_data.m_back_painter; - auto geometry_label_damage_rect = geometry_label_rect.inflated(2, 2); - Gfx::PainterStateSaver saver(back_painter); - back_painter.add_clip_rect(geometry_label_damage_rect); - - back_painter.fill_rect(geometry_label_rect.translated(1, 1), Color(Color::Black).with_alpha(80)); - Gfx::StylePainter::paint_button(back_painter, geometry_label_rect.translated(-1, -1), wm.palette(), Gfx::ButtonStyle::Normal, false); - back_painter.draw_text(geometry_label_rect.translated(-1, -1), geometry_string, Gfx::TextAlignment::Center, wm.palette().window_text()); - - m_last_geometry_label_damage_rect = geometry_label_damage_rect; -} - void Compositor::change_cursor(const Cursor* cursor) { if (m_current_cursor == cursor) @@ -1103,6 +1056,7 @@ void Compositor::overlay_rects_changed() { if (m_overlay_rects_changed) return; + m_overlay_rects_changed = true; m_invalidated_any = true; invalidate_occlusions(); diff --git a/Userland/Services/WindowServer/Compositor.h b/Userland/Services/WindowServer/Compositor.h index 6e91afd11e..0a34a64c67 100644 --- a/Userland/Services/WindowServer/Compositor.h +++ b/Userland/Services/WindowServer/Compositor.h @@ -113,7 +113,6 @@ private: void recompute_occlusions(); bool any_opaque_window_above_this_one_contains_rect(const Window&, const Gfx::IntRect&); void change_cursor(const Cursor*); - void draw_geometry_label(Screen&); void flush(Screen&); RefPtr<Core::Timer> m_compose_timer; @@ -183,7 +182,6 @@ private: Gfx::DisjointRectSet m_opaque_wallpaper_rects; Gfx::IntRect m_last_dnd_rect; - Gfx::IntRect m_last_geometry_label_damage_rect; String m_wallpaper_path { "" }; WallpaperMode m_wallpaper_mode { WallpaperMode::Unchecked }; diff --git a/Userland/Services/WindowServer/Overlays.cpp b/Userland/Services/WindowServer/Overlays.cpp index b751784b7c..1cf9f58a33 100644 --- a/Userland/Services/WindowServer/Overlays.cpp +++ b/Userland/Services/WindowServer/Overlays.cpp @@ -205,4 +205,52 @@ Gfx::IntRect ScreenNumberOverlay::calculate_content_rect_for_screen(Screen& scre return calculate_frame_rect(content_rect); } +WindowGeometryOverlay::WindowGeometryOverlay(Window& window) + : m_window(window) +{ + update_rect(); +} + +void WindowGeometryOverlay::update_rect() +{ + if (auto* window = m_window.ptr()) { + auto& wm = WindowManager::the(); + if (!window->size_increment().is_null()) { + int width_steps = (window->width() - window->base_size().width()) / window->size_increment().width(); + int height_steps = (window->height() - window->base_size().height()) / window->size_increment().height(); + m_label = String::formatted("{} ({}x{})", window->rect(), width_steps, height_steps); + } else { + m_label = window->rect().to_string(); + } + m_label_rect = Gfx::IntRect { 0, 0, wm.font().width(m_label) + 16, wm.font().glyph_height() + 10 }; + + auto rect = calculate_frame_rect(m_label_rect); + rect.center_within(window->frame().rect()); + auto desktop_rect = wm.desktop_rect(ScreenInput::the().cursor_location_screen()); + if (rect.left() < desktop_rect.left()) + rect.set_left(desktop_rect.left()); + if (rect.top() < desktop_rect.top()) + rect.set_top(desktop_rect.top()); + if (rect.right() > desktop_rect.right()) + rect.set_right_without_resize(desktop_rect.right()); + if (rect.bottom() > desktop_rect.bottom()) + rect.set_bottom_without_resize(desktop_rect.bottom()); + + set_rect(rect); + } else { + set_enabled(false); + } +} + +void WindowGeometryOverlay::render_overlay_bitmap(Gfx::Painter& painter) +{ + painter.draw_text({ {}, rect().size() }, m_label, WindowManager::the().font(), Gfx::TextAlignment::Center, Color::White); +} + +void WindowGeometryOverlay::window_rect_changed() +{ + update_rect(); + invalidate(); +} + } diff --git a/Userland/Services/WindowServer/Overlays.h b/Userland/Services/WindowServer/Overlays.h index 8514b1e6b5..a97d797075 100644 --- a/Userland/Services/WindowServer/Overlays.h +++ b/Userland/Services/WindowServer/Overlays.h @@ -8,6 +8,7 @@ #include <AK/IntrusiveList.h> #include <AK/Vector.h> +#include <AK/WeakPtr.h> #include <LibGfx/Painter.h> #include <WindowServer/MultiScaleBitmaps.h> #include <WindowServer/Screen.h> @@ -15,6 +16,7 @@ namespace WindowServer { class Screen; +class Window; class Overlay { friend class Compositor; @@ -124,4 +126,21 @@ private: static Gfx::Font const* s_font; }; +class WindowGeometryOverlay : public RectangularOverlay { +public: + WindowGeometryOverlay(Window&); + + void window_rect_changed(); + + virtual ZOrder zorder() const override { return ZOrder::WindowGeometry; } + virtual void render_overlay_bitmap(Gfx::Painter&) override; + +private: + void update_rect(); + + WeakPtr<Window> m_window; + String m_label; + Gfx::IntRect m_label_rect; +}; + } diff --git a/Userland/Services/WindowServer/Window.cpp b/Userland/Services/WindowServer/Window.cpp index 2375061b96..3e5099a2dd 100644 --- a/Userland/Services/WindowServer/Window.cpp +++ b/Userland/Services/WindowServer/Window.cpp @@ -502,6 +502,8 @@ void Window::set_visible(bool b) return; m_visible = b; + if (!m_visible) + WindowManager::the().check_hide_geometry_overlay(*this); Compositor::the().invalidate_occlusions(); if (m_visible) invalidate(true); diff --git a/Userland/Services/WindowServer/WindowManager.cpp b/Userland/Services/WindowServer/WindowManager.cpp index 762899285c..0d33e0aba8 100644 --- a/Userland/Services/WindowServer/WindowManager.cpp +++ b/Userland/Services/WindowServer/WindowManager.cpp @@ -256,6 +256,8 @@ void WindowManager::do_move_to_front(Window& window, bool make_active, bool make void WindowManager::remove_window(Window& window) { + + check_hide_geometry_overlay(window); m_window_stack.remove(window); auto* active = active_window(); auto* active_input = active_input_window(); @@ -481,6 +483,12 @@ bool WindowManager::pick_new_active_window(Window* previous_active) return new_window_picked; } +void WindowManager::check_hide_geometry_overlay(Window& window) +{ + if (&window == m_move_window.ptr() || &window == m_resize_window.ptr()) + m_geometry_overlay = nullptr; +} + void WindowManager::start_window_move(Window& window, Gfx::IntPoint const& origin) { MenuManager::the().close_everyone(); @@ -492,6 +500,8 @@ void WindowManager::start_window_move(Window& window, Gfx::IntPoint const& origi m_move_window->set_default_positioned(false); m_move_origin = origin; m_move_window_origin = window.position(); + m_geometry_overlay = Compositor::the().create_overlay<WindowGeometryOverlay>(window); + m_geometry_overlay->set_enabled(true); window.invalidate(true, true); } @@ -531,6 +541,8 @@ void WindowManager::start_window_resize(Window& window, Gfx::IntPoint const& pos m_resize_window = window; m_resize_origin = position; m_resize_window_original_rect = window.rect(); + m_geometry_overlay = Compositor::the().create_overlay<WindowGeometryOverlay>(window); + m_geometry_overlay->set_enabled(true); m_active_input_tracking_window = nullptr; @@ -563,6 +575,7 @@ bool WindowManager::process_ongoing_window_move(MouseEvent& event) } } m_move_window = nullptr; + m_geometry_overlay = nullptr; return true; } if (event.type() == Event::MouseMove) { @@ -623,6 +636,8 @@ bool WindowManager::process_ongoing_window_move(MouseEvent& event) m_move_window_origin = m_move_window->position(); } } + + m_geometry_overlay->window_rect_changed(); } return true; } @@ -640,6 +655,7 @@ bool WindowManager::process_ongoing_window_resize(MouseEvent const& event) dbgln_if(RESIZE_DEBUG, "Should Maximize vertically"); m_resize_window->set_vertically_maximized(); m_resize_window = nullptr; + m_geometry_overlay = nullptr; m_resizing_mouse_button = MouseButton::None; return true; } @@ -647,6 +663,7 @@ bool WindowManager::process_ongoing_window_resize(MouseEvent const& event) Core::EventLoop::current().post_event(*m_resize_window, make<ResizeEvent>(m_resize_window->rect())); m_resize_window->invalidate(true, true); m_resize_window = nullptr; + m_geometry_overlay = nullptr; m_resizing_mouse_button = MouseButton::None; return true; } @@ -748,6 +765,7 @@ bool WindowManager::process_ongoing_window_resize(MouseEvent const& event) dbgln_if(RESIZE_DEBUG, "[WM] Resizing, original: {}, now: {}", m_resize_window_original_rect, new_rect); m_resize_window->set_rect(new_rect); + m_geometry_overlay->window_rect_changed(); Core::EventLoop::current().post_event(*m_resize_window, make<ResizeEvent>(new_rect)); return true; } diff --git a/Userland/Services/WindowServer/WindowManager.h b/Userland/Services/WindowServer/WindowManager.h index cb20c8ff33..b013374892 100644 --- a/Userland/Services/WindowServer/WindowManager.h +++ b/Userland/Services/WindowServer/WindowManager.h @@ -37,6 +37,7 @@ class Window; class ClientConnection; class WindowSwitcher; class Button; +class WindowGeometryOverlay; enum class ResizeDirection { None, @@ -160,6 +161,8 @@ public: bool is_active_window_or_accessory(Window&) const; + void check_hide_geometry_overlay(Window&); + void start_window_resize(Window&, Gfx::IntPoint const&, MouseButton); void start_window_resize(Window&, MouseEvent const&); void start_window_move(Window&, MouseEvent const&); @@ -319,6 +322,7 @@ private: WeakPtr<Window> m_active_input_tracking_window; WeakPtr<Window> m_window_with_active_menu; + OwnPtr<WindowGeometryOverlay> m_geometry_overlay; WeakPtr<Window> m_move_window; Gfx::IntPoint m_move_origin; Gfx::IntPoint m_move_window_origin; |