From 31c3382577808e406b920fefa70abaea3c15c570 Mon Sep 17 00:00:00 2001 From: Tom Date: Tue, 27 Apr 2021 21:24:32 -0600 Subject: [PATCH] WindowServer: Use window menu actions when clicking frame buttons This keeps the minimize/maximize/restore/close implementation consistent with the window menu actions. --- Userland/Services/WindowServer/Menu.h | 23 ++++++-- Userland/Services/WindowServer/Window.cpp | 53 +++++++++++-------- Userland/Services/WindowServer/Window.h | 1 + .../Services/WindowServer/WindowFrame.cpp | 6 +-- 4 files changed, 54 insertions(+), 29 deletions(-) diff --git a/Userland/Services/WindowServer/Menu.h b/Userland/Services/WindowServer/Menu.h index 70deeee414..e3dac4b1b6 100644 --- a/Userland/Services/WindowServer/Menu.h +++ b/Userland/Services/WindowServer/Menu.h @@ -41,15 +41,32 @@ public: const MenuItem& item(int index) const { return m_items.at(index); } MenuItem& item(int index) { return m_items.at(index); } + MenuItem* item_by_identifier(unsigned identifier) + { + MenuItem* found_item = nullptr; + for_each_item([&](auto& item) { + if (item.identifier() == identifier) { + found_item = &item; + return IterationDecision::Break; + } + return IterationDecision::Continue; + }); + return found_item; + } + void add_item(NonnullOwnPtr); String name() const { return m_name; } template - void for_each_item(Callback callback) const + IterationDecision for_each_item(Callback callback) { - for (auto& item : m_items) - callback(item); + for (auto& item : m_items) { + IterationDecision decision = callback(item); + if (decision != IterationDecision::Continue) + return decision; + } + return IterationDecision::Continue; } Gfx::IntRect rect_in_window_menubar() const { return m_rect_in_window_menubar; } diff --git a/Userland/Services/WindowServer/Window.cpp b/Userland/Services/WindowServer/Window.cpp index 146248f2ce..36607c7a87 100644 --- a/Userland/Services/WindowServer/Window.cpp +++ b/Userland/Services/WindowServer/Window.cpp @@ -656,33 +656,40 @@ void Window::ensure_window_menu() m_window_menu->item((int)PopupMenuItem::Maximize).set_enabled(m_resizable); m_window_menu->on_item_activation = [&](auto& item) { - switch (static_cast(item.identifier())) { - case WindowMenuAction::MinimizeOrUnminimize: - WindowManager::the().minimize_windows(*this, !m_minimized); - if (!m_minimized) - WindowManager::the().move_to_front_and_make_active(*this); - break; - case WindowMenuAction::MaximizeOrRestore: - WindowManager::the().maximize_windows(*this, !m_maximized); - WindowManager::the().move_to_front_and_make_active(*this); - break; - case WindowMenuAction::Close: - request_close(); - break; - case WindowMenuAction::ToggleMenubarVisibility: - frame().invalidate(); - item.set_checked(!item.is_checked()); - m_should_show_menubar = item.is_checked(); - frame().invalidate(); - recalculate_rect(); - Compositor::the().invalidate_occlusions(); - Compositor::the().invalidate_screen(); - break; - } + handle_window_menu_action(static_cast(item.identifier())); }; } } +void Window::handle_window_menu_action(WindowMenuAction action) +{ + switch (action) { + case WindowMenuAction::MinimizeOrUnminimize: + WindowManager::the().minimize_windows(*this, !m_minimized); + if (!m_minimized) + WindowManager::the().move_to_front_and_make_active(*this); + break; + case WindowMenuAction::MaximizeOrRestore: + WindowManager::the().maximize_windows(*this, !m_maximized); + WindowManager::the().move_to_front_and_make_active(*this); + break; + case WindowMenuAction::Close: + request_close(); + break; + case WindowMenuAction::ToggleMenubarVisibility: { + auto& item = *m_window_menu->item_by_identifier((unsigned)action); + frame().invalidate(); + item.set_checked(!item.is_checked()); + m_should_show_menubar = item.is_checked(); + frame().invalidate(); + recalculate_rect(); + Compositor::the().invalidate_occlusions(); + Compositor::the().invalidate_screen(); + break; + } + } +} + void Window::popup_window_menu(const Gfx::IntPoint& position, WindowMenuDefaultAction default_action) { ensure_window_menu(); diff --git a/Userland/Services/WindowServer/Window.h b/Userland/Services/WindowServer/Window.h index a36b2d3258..4d44fe290b 100644 --- a/Userland/Services/WindowServer/Window.h +++ b/Userland/Services/WindowServer/Window.h @@ -77,6 +77,7 @@ public: virtual ~Window() override; void popup_window_menu(const Gfx::IntPoint&, WindowMenuDefaultAction); + void handle_window_menu_action(WindowMenuAction); void window_menu_activate_default(); void request_close(); diff --git a/Userland/Services/WindowServer/WindowFrame.cpp b/Userland/Services/WindowServer/WindowFrame.cpp index 1eaa48b6fd..8f2ba5c798 100644 --- a/Userland/Services/WindowServer/WindowFrame.cpp +++ b/Userland/Services/WindowServer/WindowFrame.cpp @@ -65,14 +65,14 @@ WindowFrame::WindowFrame(Window& window) : m_window(window) { auto button = make