From 91a97f7a4214b0e271a1b27098b82f73fdcc3b04 Mon Sep 17 00:00:00 2001 From: Shannon Booth Date: Wed, 12 Feb 2020 19:22:52 +1300 Subject: [PATCH] WindowServer: Move some menu related code into MenuManager Shuffle around some menu related code from window manager into menu manager. This still is not perfect, and results in a little more of the window manager to be publically exposed - but this is another step towards better seperation of concerns between menu and window manager. We also move the mouse_event handling into a new function in menu manager as event handling was beginning to become a bit chunky. --- Servers/WindowServer/MenuManager.cpp | 80 ++++++++++++++++++++++---- Servers/WindowServer/MenuManager.h | 4 +- Servers/WindowServer/WindowManager.cpp | 49 +--------------- Servers/WindowServer/WindowManager.h | 5 +- 4 files changed, 74 insertions(+), 64 deletions(-) diff --git a/Servers/WindowServer/MenuManager.cpp b/Servers/WindowServer/MenuManager.cpp index e3b9f2162f..922e74fc31 100644 --- a/Servers/WindowServer/MenuManager.cpp +++ b/Servers/WindowServer/MenuManager.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2018-2020, Andreas Kling + * Copyright (c) 2020, Shannon Booth * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -258,18 +259,9 @@ void MenuManager::event(Core::Event& event) if (WindowManager::the().active_window_is_modal()) return Core::Object::event(event); - if (event.type() == Event::MouseMove || event.type() == Event::MouseUp || event.type() == Event::MouseDown || event.type() == Event::MouseWheel) { - - auto& mouse_event = static_cast(event); - for_each_active_menubar_menu([&](Menu& menu) { - if (menu.rect_in_menubar().contains(mouse_event.position())) { - handle_menu_mouse_event(menu, mouse_event); - return IterationDecision::Break; - } - return IterationDecision::Continue; - }); - - AppletManager::the().event(event); + if (static_cast(event).is_mouse_event()) { + handle_mouse_event(static_cast(event)); + return; } if (static_cast(event).is_key_event()) { @@ -292,6 +284,70 @@ void MenuManager::event(Core::Event& event) return Core::Object::event(event); } +void MenuManager::handle_mouse_event(MouseEvent& mouse_event) +{ + bool handled_menubar_event = false; + for_each_active_menubar_menu([&](Menu& menu) { + if (menu.rect_in_menubar().contains(mouse_event.position())) { + handle_menu_mouse_event(menu, mouse_event); + handled_menubar_event = true; + return IterationDecision::Break; + } + return IterationDecision::Continue; + }); + if (handled_menubar_event) + return; + + if (!open_menu_stack().is_empty()) { + auto* topmost_menu = open_menu_stack().last().ptr(); + ASSERT(topmost_menu); + auto* window = topmost_menu->menu_window(); + ASSERT(window); + + bool event_is_inside_current_menu = window->rect().contains(mouse_event.position()); + if (event_is_inside_current_menu) { + WindowManager::the().set_hovered_window(window); + auto translated_event = mouse_event.translated(-window->position()); + WindowManager::the().deliver_mouse_event(*window, translated_event); + return; + } + + if (topmost_menu->hovered_item()) + topmost_menu->clear_hovered_item(); + if (mouse_event.type() == Event::MouseDown || mouse_event.type() == Event::MouseUp) { + auto* window_menu_of = topmost_menu->window_menu_of(); + if (window_menu_of) { + bool event_is_inside_taskbar_button = window_menu_of->taskbar_rect().contains(mouse_event.position()); + if (event_is_inside_taskbar_button && !topmost_menu->is_window_menu_open()) { + topmost_menu->set_window_menu_open(true); + return; + } + } + + if (mouse_event.type() == Event::MouseDown) { + close_bar(); + topmost_menu->set_window_menu_open(false); + } + } + + if (mouse_event.type() == Event::MouseMove) { + for (auto& menu : open_menu_stack()) { + if (!menu) + continue; + if (!menu->menu_window()->rect().contains(mouse_event.position())) + continue; + WindowManager::the().set_hovered_window(menu->menu_window()); + auto translated_event = mouse_event.translated(-menu->menu_window()->position()); + WindowManager::the().deliver_mouse_event(*menu->menu_window(), translated_event); + break; + } + } + return; + } + + AppletManager::the().dispatch_event(static_cast(mouse_event)); +} + void MenuManager::handle_menu_mouse_event(Menu& menu, const MouseEvent& event) { bool is_hover_with_any_menu_open = event.type() == MouseEvent::MouseMove diff --git a/Servers/WindowServer/MenuManager.h b/Servers/WindowServer/MenuManager.h index 78c6bc5ab1..0b7bfefa95 100644 --- a/Servers/WindowServer/MenuManager.h +++ b/Servers/WindowServer/MenuManager.h @@ -44,8 +44,6 @@ public: void refresh(); - virtual void event(Core::Event&) override; - bool is_open(const Menu&) const; Vector>& open_menu_stack() { return m_open_menu_stack; } @@ -95,6 +93,8 @@ private: const Window& window() const { return *m_window; } + virtual void event(Core::Event&) override; + void handle_mouse_event(MouseEvent&); void handle_menu_mouse_event(Menu&, const MouseEvent&); void draw(); diff --git a/Servers/WindowServer/WindowManager.cpp b/Servers/WindowServer/WindowManager.cpp index 220251c905..2a7d7383b1 100644 --- a/Servers/WindowServer/WindowManager.cpp +++ b/Servers/WindowServer/WindowManager.cpp @@ -732,58 +732,11 @@ void WindowManager::process_mouse_event(MouseEvent& event, Window*& hovered_wind } // FIXME: Now that the menubar has a dedicated window, is this special-casing really necessary? - if (!active_window_is_modal() && menubar_rect().contains(event.position())) { + if (!MenuManager::the().open_menu_stack().is_empty() || (!active_window_is_modal() && menubar_rect().contains(event.position()))) { MenuManager::the().dispatch_event(event); return; } - if (!MenuManager::the().open_menu_stack().is_empty()) { - auto* topmost_menu = MenuManager::the().open_menu_stack().last().ptr(); - ASSERT(topmost_menu); - auto* window = topmost_menu->menu_window(); - ASSERT(window); - - bool event_is_inside_current_menu = window->rect().contains(event.position()); - if (event_is_inside_current_menu) { - hovered_window = window; - auto translated_event = event.translated(-window->position()); - deliver_mouse_event(*window, translated_event); - return; - } - - if (topmost_menu->hovered_item()) - topmost_menu->clear_hovered_item(); - if (event.type() == Event::MouseDown || event.type() == Event::MouseUp) { - auto* window_menu_of = topmost_menu->window_menu_of(); - if (window_menu_of) { - bool event_is_inside_taskbar_button = window_menu_of->taskbar_rect().contains(event.position()); - if (event_is_inside_taskbar_button && !topmost_menu->is_window_menu_open()) { - topmost_menu->set_window_menu_open(true); - return; - } - } - - if (event.type() == Event::MouseDown) { - MenuManager::the().close_bar(); - topmost_menu->set_window_menu_open(false); - } - } - - if (event.type() == Event::MouseMove) { - for (auto& menu : MenuManager::the().open_menu_stack()) { - if (!menu) - continue; - if (!menu->menu_window()->rect().contains(event.position())) - continue; - hovered_window = menu->menu_window(); - auto translated_event = event.translated(-menu->menu_window()->position()); - deliver_mouse_event(*menu->menu_window(), translated_event); - break; - } - } - return; - } - Window* event_window_with_frame = nullptr; if (m_active_input_window) { diff --git a/Servers/WindowServer/WindowManager.h b/Servers/WindowServer/WindowManager.h index c1567cb96f..a09fdd0941 100644 --- a/Servers/WindowServer/WindowManager.h +++ b/Servers/WindowServer/WindowManager.h @@ -168,18 +168,19 @@ public: void update_theme(String theme_path, String theme_name); + void set_hovered_window(Window*); + void deliver_mouse_event(Window& window, MouseEvent& event); + private: NonnullRefPtr get_cursor(const String& name); NonnullRefPtr get_cursor(const String& name, const Gfx::Point& hotspot); void process_mouse_event(MouseEvent&, Window*& hovered_window); void process_event_for_doubleclick(Window& window, MouseEvent& event); - void deliver_mouse_event(Window& window, MouseEvent& event); bool process_ongoing_window_resize(const MouseEvent&, Window*& hovered_window); bool process_ongoing_window_move(MouseEvent&, Window*& hovered_window); bool process_ongoing_drag(MouseEvent&, Window*& hovered_window); void start_window_move(Window&, const MouseEvent&); - void set_hovered_window(Window*); template IterationDecision for_each_visible_window_of_type_from_back_to_front(WindowType, Callback, bool ignore_highlight = false); template