summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Applications/Terminal/Terminal.cpp8
-rw-r--r--Applications/Terminal/Terminal.h1
-rw-r--r--Applications/Terminal/main.cpp20
-rw-r--r--Kernel/GUITypes.h5
-rw-r--r--LibGUI/GEventLoop.cpp25
-rw-r--r--LibGUI/GEventLoop.h1
-rw-r--r--LibGUI/GMenu.cpp19
-rw-r--r--LibGUI/GMenu.h5
-rw-r--r--LibGUI/GWidget.cpp1
-rw-r--r--WindowServer/WSMenu.cpp11
10 files changed, 93 insertions, 3 deletions
diff --git a/Applications/Terminal/Terminal.cpp b/Applications/Terminal/Terminal.cpp
index 3f68b193b8..3e169505f4 100644
--- a/Applications/Terminal/Terminal.cpp
+++ b/Applications/Terminal/Terminal.cpp
@@ -749,3 +749,11 @@ void Terminal::flush_dirty_lines()
}
update(rect);
}
+
+void Terminal::force_repaint()
+{
+ for (int i = 0; i < m_rows; ++i)
+ line(i).dirty = true;
+ m_need_full_flush = true;
+ update();
+}
diff --git a/Applications/Terminal/Terminal.h b/Applications/Terminal/Terminal.h
index a3a4ac018e..298596a479 100644
--- a/Applications/Terminal/Terminal.h
+++ b/Applications/Terminal/Terminal.h
@@ -19,6 +19,7 @@ public:
void on_char(byte);
void flush_dirty_lines();
+ void force_repaint();
private:
virtual void event(GEvent&) override;
diff --git a/Applications/Terminal/main.cpp b/Applications/Terminal/main.cpp
index 50e4a7010b..c539a882f2 100644
--- a/Applications/Terminal/main.cpp
+++ b/Applications/Terminal/main.cpp
@@ -80,9 +80,23 @@ int main(int argc, char** argv)
menubar->add_menu(move(app_menu));
auto font_menu = make<GMenu>("Font");
- font_menu->add_item(30, "Liza 8x10");
- font_menu->add_item(31, "LizaRegular 8x10");
- font_menu->add_item(32, "LizaBold 8x10");
+ font_menu->add_item(30, "Liza Thin");
+ font_menu->add_item(31, "Liza Regular");
+ font_menu->add_item(32, "Liza Bold");
+ font_menu->on_item_activation = [&terminal] (unsigned identifier) {
+ switch (identifier) {
+ case 30:
+ terminal.set_font(Font::load_from_file("/res/fonts/Liza8x10.font"));
+ break;
+ case 31:
+ terminal.set_font(Font::load_from_file("/res/fonts/LizaRegular8x10.font"));
+ break;
+ case 32:
+ terminal.set_font(Font::load_from_file("/res/fonts/LizaBold8x10.font"));
+ break;
+ }
+ terminal.force_repaint();
+ };
menubar->add_menu(move(font_menu));
auto help_menu = make<GMenu>("Help");
diff --git a/Kernel/GUITypes.h b/Kernel/GUITypes.h
index 61aa6587eb..263cca0145 100644
--- a/Kernel/GUITypes.h
+++ b/Kernel/GUITypes.h
@@ -67,6 +67,7 @@ struct GUI_Event {
WindowActivated,
WindowDeactivated,
WindowCloseRequest,
+ MenuItemActivated,
};
Type type { Invalid };
int window_id { -1 };
@@ -88,6 +89,10 @@ struct GUI_Event {
bool alt : 1;
bool shift : 1;
} key;
+ struct {
+ int menu_id;
+ unsigned identifier;
+ } menu;
};
};
diff --git a/LibGUI/GEventLoop.cpp b/LibGUI/GEventLoop.cpp
index e3db469230..70f38eb9ea 100644
--- a/LibGUI/GEventLoop.cpp
+++ b/LibGUI/GEventLoop.cpp
@@ -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;
}
}
}
diff --git a/LibGUI/GEventLoop.h b/LibGUI/GEventLoop.h
index 02d1066770..e68df0dc10 100644
--- a/LibGUI/GEventLoop.h
+++ b/LibGUI/GEventLoop.h
@@ -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&);
diff --git a/LibGUI/GMenu.cpp b/LibGUI/GMenu.cpp
index de56467485..923fb784f9 100644
--- a/LibGUI/GMenu.cpp
+++ b/LibGUI/GMenu.cpp
@@ -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;
}
diff --git a/LibGUI/GMenu.h b/LibGUI/GMenu.h
index 5582049563..3eeed3527f 100644
--- a/LibGUI/GMenu.h
+++ b/LibGUI/GMenu.h
@@ -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; }
diff --git a/LibGUI/GWidget.cpp b/LibGUI/GWidget.cpp
index 9d05141f3d..58bdd25a59 100644
--- a/LibGUI/GWidget.cpp
+++ b/LibGUI/GWidget.cpp
@@ -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)
diff --git a/WindowServer/WSMenu.cpp b/WindowServer/WSMenu.cpp
index e8bd9361ae..0e93ab893d 100644
--- a/WindowServer/WSMenu.cpp
+++ b/WindowServer/WSMenu.cpp
@@ -137,7 +137,18 @@ void WSMenu::did_activate(WSMenuItem& item)
{
if (on_item_activation)
on_item_activation(item);
+
close();
+
+ GUI_Event gui_event;
+ gui_event.type = GUI_Event::Type::MenuItemActivated;
+ gui_event.menu.menu_id = m_menu_id;
+ gui_event.menu.identifier = item.identifier();
+
+ if (!m_process)
+ return;
+ LOCKER(m_process->gui_events_lock());
+ m_process->gui_events().append(move(gui_event));
}
WSMenuItem* WSMenu::item_at(const Point& position)