summaryrefslogtreecommitdiff
path: root/Servers/WindowServer/WSMenu.cpp
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-11-11 10:43:03 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-11-11 13:13:08 +0100
commit74be54cce801464d8f791444659962700937b2a7 (patch)
treeffb64c26ddf3a61d1a47cccc91a0b9e1f8f5da3d /Servers/WindowServer/WSMenu.cpp
parent3a71c018bfd2f015d459462177188e06db2af567 (diff)
downloadserenity-74be54cce801464d8f791444659962700937b2a7.zip
WindowServer: Organize system menu app shortcuts into categories
If the .af file for an app contains the App/Category key, we'll now put it in a submenu of the system menu, together with all the other apps in that same category. This is pretty neat! :^)
Diffstat (limited to 'Servers/WindowServer/WSMenu.cpp')
-rw-r--r--Servers/WindowServer/WSMenu.cpp40
1 files changed, 27 insertions, 13 deletions
diff --git a/Servers/WindowServer/WSMenu.cpp b/Servers/WindowServer/WSMenu.cpp
index 710332df2d..927f247852 100644
--- a/Servers/WindowServer/WSMenu.cpp
+++ b/Servers/WindowServer/WSMenu.cpp
@@ -198,6 +198,17 @@ void WSMenu::draw()
}
}
+void close_everyone_not_in_lineage(WSMenu& menu)
+{
+ for (auto& open_menu : WSWindowManager::the().menu_manager().open_menu_stack()) {
+ if (!open_menu)
+ continue;
+ if (&menu == open_menu.ptr() || open_menu->is_menu_ancestor_of(menu))
+ continue;
+ open_menu->menu_window()->set_visible(false);
+ }
+}
+
void WSMenu::event(CEvent& event)
{
if (event.type() == WSEvent::MouseMove) {
@@ -207,21 +218,10 @@ void WSMenu::event(CEvent& event)
return;
m_hovered_item = item;
if (m_hovered_item->is_submenu()) {
+ close_everyone_not_in_lineage(*m_hovered_item->submenu());
m_hovered_item->submenu()->popup(m_hovered_item->rect().top_right().translated(menu_window()->rect().location()), true);
} else {
- bool close_remaining_menus = false;
- for (auto& open_menu : WSWindowManager::the().menu_manager().open_menu_stack()) {
- if (!open_menu)
- continue;
- if (close_remaining_menus) {
- open_menu->menu_window()->set_visible(false);
- continue;
- }
- if (open_menu == this) {
- close_remaining_menus = true;
- continue;
- }
- }
+ close_everyone_not_in_lineage(*this);
}
redraw();
return;
@@ -307,3 +307,17 @@ void WSMenu::popup(const Point& position, bool is_submenu)
window.set_visible(true);
WSWindowManager::the().set_current_menu(this, is_submenu);
}
+
+bool WSMenu::is_menu_ancestor_of(const WSMenu& other) const
+{
+ for (auto& item : m_items) {
+ if (!item.is_submenu())
+ continue;
+ auto& submenu = *const_cast<WSMenuItem&>(item).submenu();
+ if (&submenu == &other)
+ return true;
+ if (submenu.is_menu_ancestor_of(other))
+ return true;
+ }
+ return false;
+}