1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 13:47:35 +00:00

WindowServer+LibGUI: Notify GUI clients about menu item enter/leave

We now send out MenuItemEntered and MenuItemLeft messages to the client
when the user hovers/unhovers menu items.

On the client side, these become GUI::ActionEvent, with one of two
types: ActionEnter or ActionLeave. They are sent to the Application.

This will allow GUI applications to react to these events.
This commit is contained in:
Andreas Kling 2021-04-17 18:16:54 +02:00
parent f8c2beec7c
commit ba7e1ca2fb
7 changed files with 91 additions and 19 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -26,6 +26,7 @@
#include <AK/StringBuilder.h>
#include <LibCore/MimeData.h>
#include <LibGUI/Action.h>
#include <LibGUI/Event.h>
namespace GUI {
@ -69,4 +70,14 @@ String KeyEvent::to_string() const
return builder.to_string();
}
ActionEvent::ActionEvent(Type type, Action& action)
: Event(type)
, m_action(action)
{
}
ActionEvent::~ActionEvent()
{
}
}

View file

@ -31,6 +31,7 @@
#include <Kernel/API/KeyCode.h>
#include <LibCore/Event.h>
#include <LibGUI/FocusSource.h>
#include <LibGUI/Forward.h>
#include <LibGUI/WindowType.h>
#include <LibGfx/Bitmap.h>
#include <LibGfx/Point.h>
@ -72,6 +73,8 @@ public:
Drop,
ThemeChange,
ScreenRectChange,
ActionEnter,
ActionLeave,
__Begin_WM_Events,
WM_WindowRemoved,
@ -428,4 +431,16 @@ private:
FocusSource m_source { FocusSource::Programmatic };
};
class ActionEvent final : public Event {
public:
ActionEvent(Type, Action&);
~ActionEvent();
Action const& action() const { return *m_action; }
Action& action() { return *m_action; }
private:
NonnullRefPtr<Action> m_action;
};
}

View file

@ -273,6 +273,38 @@ void WindowServerConnection::handle(const Messages::WindowClient::MenuItemActiva
action->activate(menu);
}
void WindowServerConnection::handle(Messages::WindowClient::MenuItemEntered const& message)
{
auto* menu = Menu::from_menu_id(message.menu_id());
if (!menu) {
dbgln("WindowServerConnection received MenuItemEntered for invalid menu ID {}", message.menu_id());
return;
}
auto* action = menu->action_at(message.identifier());
if (!action)
return;
auto* app = Application::the();
if (!app)
return;
Core::EventLoop::current().post_event(*app, make<ActionEvent>(GUI::Event::ActionEnter, *action));
}
void WindowServerConnection::handle(Messages::WindowClient::MenuItemLeft const& message)
{
auto* menu = Menu::from_menu_id(message.menu_id());
if (!menu) {
dbgln("WindowServerConnection received MenuItemLeft for invalid menu ID {}", message.menu_id());
return;
}
auto* action = menu->action_at(message.identifier());
if (!action)
return;
auto* app = Application::the();
if (!app)
return;
Core::EventLoop::current().post_event(*app, make<ActionEvent>(GUI::Event::ActionLeave, *action));
}
void WindowServerConnection::handle(const Messages::WindowClient::ScreenRectChanged& message)
{
Desktop::the().did_receive_screen_rect({}, message.rect());

View file

@ -64,6 +64,8 @@ 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::MenuItemEntered&) override;
virtual void handle(const Messages::WindowClient::MenuItemLeft&) override;
virtual void handle(const Messages::WindowClient::MenuVisibilityDidChange&) override;
virtual void handle(const Messages::WindowClient::ScreenRectChanged&) override;
virtual void handle(const Messages::WindowClient::AsyncSetWallpaperFinished&) override;