summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-04-05 14:32:34 +0200
committerAndreas Kling <kling@serenityos.org>2021-04-05 18:09:04 +0200
commit9b740f218b103a5f3497a666b2655865266c8ff1 (patch)
tree6f94769e391237b36a57868c553458c21298fe62 /Userland
parent03157418159c75c03d0bf94108e9f6d9053835bf (diff)
downloadserenity-9b740f218b103a5f3497a666b2655865266c8ff1.zip
WindowServer+LibGUI: Notify clients when menus become visible/hidden
This will allow clients to react to these events.
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibGUI/Menu.cpp9
-rw-r--r--Userland/Libraries/LibGUI/Menu.h7
-rw-r--r--Userland/Libraries/LibGUI/WindowServerConnection.cpp10
-rw-r--r--Userland/Libraries/LibGUI/WindowServerConnection.h3
-rw-r--r--Userland/Services/WindowServer/Menu.cpp18
-rw-r--r--Userland/Services/WindowServer/Menu.h2
-rw-r--r--Userland/Services/WindowServer/MenuManager.cpp8
-rw-r--r--Userland/Services/WindowServer/WindowClient.ipc1
8 files changed, 49 insertions, 9 deletions
diff --git a/Userland/Libraries/LibGUI/Menu.cpp b/Userland/Libraries/LibGUI/Menu.cpp
index d3a4da4b57..14534d3c9c 100644
--- a/Userland/Libraries/LibGUI/Menu.cpp
+++ b/Userland/Libraries/LibGUI/Menu.cpp
@@ -162,4 +162,13 @@ Action* Menu::action_at(size_t index)
return m_items[index].action();
}
+void Menu::visibility_did_change(Badge<WindowServerConnection>, bool visible)
+{
+ if (m_visible == visible)
+ return;
+ m_visible = visible;
+ if (on_visibility_change)
+ on_visibility_change(visible);
+}
+
}
diff --git a/Userland/Libraries/LibGUI/Menu.h b/Userland/Libraries/LibGUI/Menu.h
index 1031112830..9d03823e2c 100644
--- a/Userland/Libraries/LibGUI/Menu.h
+++ b/Userland/Libraries/LibGUI/Menu.h
@@ -59,6 +59,12 @@ public:
void popup(const Gfx::IntPoint& screen_position, const RefPtr<Action>& default_action = nullptr);
void dismiss();
+ void visibility_did_change(Badge<WindowServerConnection>, bool visible);
+
+ Function<void(bool)> on_visibility_change;
+
+ bool is_visible() const { return m_visible; }
+
private:
friend class MenuBar;
@@ -71,6 +77,7 @@ private:
RefPtr<Gfx::Bitmap> m_icon;
NonnullOwnPtrVector<MenuItem> m_items;
WeakPtr<Action> m_last_default_action;
+ bool m_visible { false };
};
}
diff --git a/Userland/Libraries/LibGUI/WindowServerConnection.cpp b/Userland/Libraries/LibGUI/WindowServerConnection.cpp
index 5ce4fad6a4..563b50cfe5 100644
--- a/Userland/Libraries/LibGUI/WindowServerConnection.cpp
+++ b/Userland/Libraries/LibGUI/WindowServerConnection.cpp
@@ -252,6 +252,16 @@ void WindowServerConnection::handle(const Messages::WindowClient::MouseWheel& me
Core::EventLoop::current().post_event(*window, make<MouseEvent>(Event::MouseWheel, message.mouse_position(), message.buttons(), to_gmousebutton(message.button()), message.modifiers(), message.wheel_delta()));
}
+void WindowServerConnection::handle(const Messages::WindowClient::MenuVisibilityDidChange& message)
+{
+ auto* menu = Menu::from_menu_id(message.menu_id());
+ if (!menu) {
+ dbgln("EventLoop received visibility change event for invalid menu ID {}", message.menu_id());
+ return;
+ }
+ menu->visibility_did_change({}, message.visible());
+}
+
void WindowServerConnection::handle(const Messages::WindowClient::MenuItemActivated& message)
{
auto* menu = Menu::from_menu_id(message.menu_id());
diff --git a/Userland/Libraries/LibGUI/WindowServerConnection.h b/Userland/Libraries/LibGUI/WindowServerConnection.h
index 4e9a29e649..20e9cff10b 100644
--- a/Userland/Libraries/LibGUI/WindowServerConnection.h
+++ b/Userland/Libraries/LibGUI/WindowServerConnection.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -64,6 +64,7 @@ private:
virtual void handle(const Messages::WindowClient::WindowCloseRequest&) override;
virtual void handle(const Messages::WindowClient::WindowResized&) override;
virtual void handle(const Messages::WindowClient::MenuItemActivated&) override;
+ virtual void handle(const Messages::WindowClient::MenuVisibilityDidChange&) override;
virtual void handle(const Messages::WindowClient::ScreenRectChanged&) override;
virtual void handle(const Messages::WindowClient::WM_WindowRemoved&) override;
virtual void handle(const Messages::WindowClient::WM_WindowStateChanged&) override;
diff --git a/Userland/Services/WindowServer/Menu.cpp b/Userland/Services/WindowServer/Menu.cpp
index c30a0b81e9..7980d3810a 100644
--- a/Userland/Services/WindowServer/Menu.cpp
+++ b/Userland/Services/WindowServer/Menu.cpp
@@ -151,10 +151,10 @@ Window& Menu::ensure_menu_window()
}
auto window = Window::construct(*this, WindowType::Menu);
+ window->set_visible(false);
window->set_rect(0, 0, width, window_height);
m_menu_window = move(window);
draw();
-
return *m_menu_window;
}
@@ -291,7 +291,8 @@ void Menu::update_for_new_hovered_item(bool make_input)
hovered_item()->submenu()->do_popup(hovered_item()->rect().top_right().translated(menu_window()->rect().location()), make_input, true);
} else {
MenuManager::the().close_everyone_not_in_lineage(*this);
- ensure_menu_window().set_visible(true);
+ ensure_menu_window();
+ set_visible(true);
}
redraw();
}
@@ -593,7 +594,7 @@ void Menu::do_popup(const Gfx::IntPoint& position, bool make_input, bool as_subm
}
window.move_to(adjusted_pos);
- window.set_visible(true);
+ set_visible(true);
MenuManager::the().open_menu(*this, make_input);
WindowManager::the().did_popup_a_menu({});
}
@@ -612,4 +613,15 @@ bool Menu::is_menu_ancestor_of(const Menu& other) const
return false;
}
+void Menu::set_visible(bool visible)
+{
+ if (!menu_window())
+ return;
+ if (visible == menu_window()->is_visible())
+ return;
+ menu_window()->set_visible(visible);
+ if (m_client)
+ m_client->post_message(Messages::WindowClient::MenuVisibilityDidChange(m_menu_id, visible));
+}
+
}
diff --git a/Userland/Services/WindowServer/Menu.h b/Userland/Services/WindowServer/Menu.h
index 9ef4cc34ae..c438cf270c 100644
--- a/Userland/Services/WindowServer/Menu.h
+++ b/Userland/Services/WindowServer/Menu.h
@@ -111,6 +111,8 @@ public:
void close();
+ void set_visible(bool);
+
void popup(const Gfx::IntPoint&);
void do_popup(const Gfx::IntPoint&, bool make_input, bool as_submenu = false);
diff --git a/Userland/Services/WindowServer/MenuManager.cpp b/Userland/Services/WindowServer/MenuManager.cpp
index 77b1799018..cdff3a0460 100644
--- a/Userland/Services/WindowServer/MenuManager.cpp
+++ b/Userland/Services/WindowServer/MenuManager.cpp
@@ -242,8 +242,7 @@ void MenuManager::close_everyone()
{
for (auto& menu : m_open_menu_stack) {
VERIFY(menu);
- if (menu->menu_window())
- menu->menu_window()->set_visible(false);
+ menu->set_visible(false);
menu->clear_hovered_item();
}
m_open_menu_stack.clear();
@@ -270,8 +269,7 @@ void MenuManager::close_menus(const Vector<Menu*>& menus)
for (auto& menu : menus) {
if (menu == m_current_menu)
clear_current_menu();
- if (menu->menu_window())
- menu->menu_window()->set_visible(false);
+ menu->set_visible(false);
menu->clear_hovered_item();
m_open_menu_stack.remove_first_matching([&](auto& entry) {
return entry == menu;
@@ -332,7 +330,7 @@ void MenuManager::open_menu(Menu& menu, bool as_current_menu)
menu.redraw_if_theme_changed();
if (!menu.menu_window())
menu.ensure_menu_window();
- menu.menu_window()->set_visible(true);
+ menu.set_visible(true);
}
if (m_open_menu_stack.find_if([&menu](auto& other) { return &menu == other.ptr(); }).is_end())
diff --git a/Userland/Services/WindowServer/WindowClient.ipc b/Userland/Services/WindowServer/WindowClient.ipc
index f3a771148c..49e3b6ffb8 100644
--- a/Userland/Services/WindowServer/WindowClient.ipc
+++ b/Userland/Services/WindowServer/WindowClient.ipc
@@ -19,6 +19,7 @@ endpoint WindowClient = 4
WindowResized(i32 window_id, Gfx::IntRect new_rect) =|
MenuItemActivated(i32 menu_id, i32 identifier) =|
+ MenuVisibilityDidChange(i32 menu_id, bool visible) =|
ScreenRectChanged(Gfx::IntRect rect) =|