1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 19:17:44 +00:00

Plumb menu item activation events from WindowServer to clients.

GMenu now has an "on_item_activation" callback that fires whenever one
of its items are activated. The menu item identifier is used to distinguish
between items.

Use this to implement font switching in Terminal. :^)
This commit is contained in:
Andreas Kling 2019-02-12 10:08:35 +01:00
parent 9c1c885483
commit db98327bdc
10 changed files with 93 additions and 3 deletions

View file

@ -3,6 +3,7 @@
#include "GObject.h"
#include "GWindow.h"
#include <LibGUI/GNotifier.h>
#include <LibGUI/GMenu.h>
#include <LibC/unistd.h>
#include <LibC/stdio.h>
#include <LibC/fcntl.h>
@ -147,6 +148,21 @@ void GEventLoop::handle_mouse_event(const GUI_Event& event, GWindow& window)
post_event(&window, make<GMouseEvent>(type, event.mouse.position, event.mouse.buttons, button));
}
void GEventLoop::handle_menu_event(const GUI_Event& event)
{
if (event.type == GUI_Event::Type::MenuItemActivated) {
auto* menu = GMenu::from_menu_id(event.menu.menu_id);
if (!menu) {
dbgprintf("GEventLoop received event for invalid window ID %d\n", event.window_id);
return;
}
if (menu->on_item_activation)
menu->on_item_activation(event.menu.identifier);
return;
}
ASSERT_NOT_REACHED();
}
void GEventLoop::wait_for_event()
{
fd_set rfds;
@ -219,6 +235,13 @@ void GEventLoop::wait_for_event()
if (nread == 0)
break;
assert(nread == sizeof(event));
switch (event.type) {
case GUI_Event::MenuItemActivated:
handle_menu_event(event);
continue;
}
auto* window = GWindow::from_window_id(event.window_id);
if (!window) {
dbgprintf("GEventLoop received event for invalid window ID %d\n", event.window_id);
@ -244,6 +267,8 @@ void GEventLoop::wait_for_event()
case GUI_Event::Type::KeyUp:
handle_key_event(event, *window);
break;
default:
break;
}
}
}

View file

@ -41,6 +41,7 @@ private:
void handle_key_event(const GUI_Event&, GWindow&);
void handle_window_activation_event(const GUI_Event&, GWindow&);
void handle_window_close_request_event(const GUI_Event&, GWindow&);
void handle_menu_event(const GUI_Event&);
void get_next_timer_expiration(timeval&);

View file

@ -1,5 +1,22 @@
#include <LibGUI/GMenu.h>
#include <LibC/gui.h>
#include <AK/HashMap.h>
static HashMap<int, GMenu*>& all_menus()
{
static HashMap<int, GMenu*>* map;
if (!map)
map = new HashMap<int, GMenu*>();
return *map;
}
GMenu* GMenu::from_menu_id(int menu_id)
{
auto it = all_menus().find(menu_id);
if (it == all_menus().end())
return nullptr;
return (*it).value;
}
GMenu::GMenu(const String& name)
: m_name(name)
@ -9,6 +26,7 @@ GMenu::GMenu(const String& name)
GMenu::~GMenu()
{
if (m_menu_id) {
all_menus().remove(m_menu_id);
gui_menu_destroy(m_menu_id);
m_menu_id = 0;
}
@ -34,5 +52,6 @@ int GMenu::realize_menu()
else if (item.type() == GMenuItem::Text)
gui_menu_add_item(m_menu_id, item.identifier(), item.text().characters());
}
all_menus().set(m_menu_id, this);
return m_menu_id;
}

View file

@ -1,6 +1,7 @@
#pragma once
#include <LibGUI/GMenuItem.h>
#include <AK/Function.h>
#include <AK/Vector.h>
class GMenu {
@ -8,9 +9,13 @@ public:
explicit GMenu(const String& name);
~GMenu();
static GMenu* from_menu_id(int);
void add_item(unsigned identifier, const String& text);
void add_separator();
Function<void(unsigned)> on_item_activation;
private:
friend class GMenuBar;
int menu_id() const { return m_menu_id; }

View file

@ -234,6 +234,7 @@ void GWidget::set_font(RetainPtr<Font>&& font)
m_font = Font::default_font();
else
m_font = move(font);
update();
}
void GWidget::set_global_cursor_tracking(bool enabled)