summaryrefslogtreecommitdiff
path: root/Servers/WindowServer/WSWindowManager.cpp
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-08-28 21:11:53 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-08-29 06:36:29 +0200
commit63e6b09816c5d144e83138d3fd471b800d29a52a (patch)
tree7daa439cf56e3c9e6131aa7a52fb7432ca0e32e6 /Servers/WindowServer/WSWindowManager.cpp
parentd3ebd8897f27c75ddf0bb75d401a6ea55761b1bd (diff)
downloadserenity-63e6b09816c5d144e83138d3fd471b800d29a52a.zip
WindowServer+LibGUI: Add support for nested menus
It's now possible to add a GMenu as a submenu of another GMenu. Simply use the GMenu::add_submenu(NonnullOwnPtr<GMenu>) API :^) The WindowServer now keeps track of a stack of open menus rather than just one "current menu". This code needs a bit more work, but the basic functionality is now here!
Diffstat (limited to 'Servers/WindowServer/WSWindowManager.cpp')
-rw-r--r--Servers/WindowServer/WSWindowManager.cpp29
1 files changed, 27 insertions, 2 deletions
diff --git a/Servers/WindowServer/WSWindowManager.cpp b/Servers/WindowServer/WSWindowManager.cpp
index 04dcb9022a..56074469de 100644
--- a/Servers/WindowServer/WSWindowManager.cpp
+++ b/Servers/WindowServer/WSWindowManager.cpp
@@ -211,14 +211,22 @@ int WSWindowManager::menubar_menu_margin() const
return 16;
}
-void WSWindowManager::set_current_menu(WSMenu* menu)
+void WSWindowManager::set_current_menu(WSMenu* menu, bool is_submenu)
{
if (m_current_menu == menu)
return;
- if (m_current_menu)
+ if (!is_submenu && m_current_menu)
m_current_menu->close();
if (menu)
m_current_menu = menu->make_weak_ptr();
+
+ if (!is_submenu) {
+ m_menu_manager.open_menu_stack().clear();
+ if (menu)
+ m_menu_manager.open_menu_stack().append(menu->make_weak_ptr());
+ } else {
+ m_menu_manager.open_menu_stack().append(menu->make_weak_ptr());
+ }
}
void WSWindowManager::set_current_menubar(WSMenuBar* menubar)
@@ -393,6 +401,11 @@ void WSWindowManager::close_current_menu()
if (m_current_menu && m_current_menu->menu_window())
m_current_menu->menu_window()->set_visible(false);
m_current_menu = nullptr;
+ for (auto& menu : m_menu_manager.open_menu_stack()) {
+ if (menu)
+ menu->menu_window()->set_visible(false);
+ }
+ m_menu_manager.open_menu_stack().clear();
m_menu_manager.refresh();
}
@@ -696,6 +709,18 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event, WSWindow*& hovere
m_current_menu->clear_hovered_item();
if (event.type() == WSEvent::MouseDown || event.type() == WSEvent::MouseUp)
close_current_menu();
+ if (event.type() == WSEvent::MouseMove) {
+ for (auto& menu : m_menu_manager.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;
+ }
+ }
} else {
hovered_window = &window;
auto translated_event = event.translated(-window.position());