mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 15:27:35 +00:00
WindowServer+LibGUI: Notify clients when menus become visible/hidden
This will allow clients to react to these events.
This commit is contained in:
parent
0315741815
commit
9b740f218b
8 changed files with 49 additions and 9 deletions
|
@ -162,4 +162,13 @@ Action* Menu::action_at(size_t index)
|
||||||
return m_items[index].action();
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,12 @@ public:
|
||||||
void popup(const Gfx::IntPoint& screen_position, const RefPtr<Action>& default_action = nullptr);
|
void popup(const Gfx::IntPoint& screen_position, const RefPtr<Action>& default_action = nullptr);
|
||||||
void dismiss();
|
void dismiss();
|
||||||
|
|
||||||
|
void visibility_did_change(Badge<WindowServerConnection>, bool visible);
|
||||||
|
|
||||||
|
Function<void(bool)> on_visibility_change;
|
||||||
|
|
||||||
|
bool is_visible() const { return m_visible; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class MenuBar;
|
friend class MenuBar;
|
||||||
|
|
||||||
|
@ -71,6 +77,7 @@ private:
|
||||||
RefPtr<Gfx::Bitmap> m_icon;
|
RefPtr<Gfx::Bitmap> m_icon;
|
||||||
NonnullOwnPtrVector<MenuItem> m_items;
|
NonnullOwnPtrVector<MenuItem> m_items;
|
||||||
WeakPtr<Action> m_last_default_action;
|
WeakPtr<Action> m_last_default_action;
|
||||||
|
bool m_visible { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()));
|
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)
|
void WindowServerConnection::handle(const Messages::WindowClient::MenuItemActivated& message)
|
||||||
{
|
{
|
||||||
auto* menu = Menu::from_menu_id(message.menu_id());
|
auto* menu = Menu::from_menu_id(message.menu_id());
|
||||||
|
|
|
@ -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.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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::WindowCloseRequest&) override;
|
||||||
virtual void handle(const Messages::WindowClient::WindowResized&) override;
|
virtual void handle(const Messages::WindowClient::WindowResized&) override;
|
||||||
virtual void handle(const Messages::WindowClient::MenuItemActivated&) 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::ScreenRectChanged&) override;
|
||||||
virtual void handle(const Messages::WindowClient::WM_WindowRemoved&) override;
|
virtual void handle(const Messages::WindowClient::WM_WindowRemoved&) override;
|
||||||
virtual void handle(const Messages::WindowClient::WM_WindowStateChanged&) override;
|
virtual void handle(const Messages::WindowClient::WM_WindowStateChanged&) override;
|
||||||
|
|
|
@ -151,10 +151,10 @@ Window& Menu::ensure_menu_window()
|
||||||
}
|
}
|
||||||
|
|
||||||
auto window = Window::construct(*this, WindowType::Menu);
|
auto window = Window::construct(*this, WindowType::Menu);
|
||||||
|
window->set_visible(false);
|
||||||
window->set_rect(0, 0, width, window_height);
|
window->set_rect(0, 0, width, window_height);
|
||||||
m_menu_window = move(window);
|
m_menu_window = move(window);
|
||||||
draw();
|
draw();
|
||||||
|
|
||||||
return *m_menu_window;
|
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);
|
hovered_item()->submenu()->do_popup(hovered_item()->rect().top_right().translated(menu_window()->rect().location()), make_input, true);
|
||||||
} else {
|
} else {
|
||||||
MenuManager::the().close_everyone_not_in_lineage(*this);
|
MenuManager::the().close_everyone_not_in_lineage(*this);
|
||||||
ensure_menu_window().set_visible(true);
|
ensure_menu_window();
|
||||||
|
set_visible(true);
|
||||||
}
|
}
|
||||||
redraw();
|
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.move_to(adjusted_pos);
|
||||||
window.set_visible(true);
|
set_visible(true);
|
||||||
MenuManager::the().open_menu(*this, make_input);
|
MenuManager::the().open_menu(*this, make_input);
|
||||||
WindowManager::the().did_popup_a_menu({});
|
WindowManager::the().did_popup_a_menu({});
|
||||||
}
|
}
|
||||||
|
@ -612,4 +613,15 @@ bool Menu::is_menu_ancestor_of(const Menu& other) const
|
||||||
return false;
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,6 +111,8 @@ public:
|
||||||
|
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
|
void set_visible(bool);
|
||||||
|
|
||||||
void popup(const Gfx::IntPoint&);
|
void popup(const Gfx::IntPoint&);
|
||||||
void do_popup(const Gfx::IntPoint&, bool make_input, bool as_submenu = false);
|
void do_popup(const Gfx::IntPoint&, bool make_input, bool as_submenu = false);
|
||||||
|
|
||||||
|
|
|
@ -242,8 +242,7 @@ void MenuManager::close_everyone()
|
||||||
{
|
{
|
||||||
for (auto& menu : m_open_menu_stack) {
|
for (auto& menu : m_open_menu_stack) {
|
||||||
VERIFY(menu);
|
VERIFY(menu);
|
||||||
if (menu->menu_window())
|
menu->set_visible(false);
|
||||||
menu->menu_window()->set_visible(false);
|
|
||||||
menu->clear_hovered_item();
|
menu->clear_hovered_item();
|
||||||
}
|
}
|
||||||
m_open_menu_stack.clear();
|
m_open_menu_stack.clear();
|
||||||
|
@ -270,8 +269,7 @@ void MenuManager::close_menus(const Vector<Menu*>& menus)
|
||||||
for (auto& menu : menus) {
|
for (auto& menu : menus) {
|
||||||
if (menu == m_current_menu)
|
if (menu == m_current_menu)
|
||||||
clear_current_menu();
|
clear_current_menu();
|
||||||
if (menu->menu_window())
|
menu->set_visible(false);
|
||||||
menu->menu_window()->set_visible(false);
|
|
||||||
menu->clear_hovered_item();
|
menu->clear_hovered_item();
|
||||||
m_open_menu_stack.remove_first_matching([&](auto& entry) {
|
m_open_menu_stack.remove_first_matching([&](auto& entry) {
|
||||||
return entry == menu;
|
return entry == menu;
|
||||||
|
@ -332,7 +330,7 @@ void MenuManager::open_menu(Menu& menu, bool as_current_menu)
|
||||||
menu.redraw_if_theme_changed();
|
menu.redraw_if_theme_changed();
|
||||||
if (!menu.menu_window())
|
if (!menu.menu_window())
|
||||||
menu.ensure_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())
|
if (m_open_menu_stack.find_if([&menu](auto& other) { return &menu == other.ptr(); }).is_end())
|
||||||
|
|
|
@ -19,6 +19,7 @@ endpoint WindowClient = 4
|
||||||
WindowResized(i32 window_id, Gfx::IntRect new_rect) =|
|
WindowResized(i32 window_id, Gfx::IntRect new_rect) =|
|
||||||
|
|
||||||
MenuItemActivated(i32 menu_id, i32 identifier) =|
|
MenuItemActivated(i32 menu_id, i32 identifier) =|
|
||||||
|
MenuVisibilityDidChange(i32 menu_id, bool visible) =|
|
||||||
|
|
||||||
ScreenRectChanged(Gfx::IntRect rect) =|
|
ScreenRectChanged(Gfx::IntRect rect) =|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue