summaryrefslogtreecommitdiff
path: root/Servers/WindowServer/WSMenuManager.cpp
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-12-05 19:36:01 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-12-05 19:36:01 +0100
commit44d5388e786e53c8719a9209beb38bdb0930f0b7 (patch)
treec47843ef3afa1b121b4e1b7cdeaa0f84fd79269e /Servers/WindowServer/WSMenuManager.cpp
parent2d18fc8052eefbbee04b61d6308b5400118209f1 (diff)
downloadserenity-44d5388e786e53c8719a9209beb38bdb0930f0b7.zip
WindowServer: Add basic menu applet concept
It's now possible to create a little applet window that sits inside the system's menubar. This is done using the new CreateMenuApplet IPC call. So far, it's possible to assign a backing store ID, and to invalidate rects for repaint. There is no way to get the events from inside the applet just yet. This will allow us to move the CPU graph and audio thingy to separate applet processes. :^)
Diffstat (limited to 'Servers/WindowServer/WSMenuManager.cpp')
-rw-r--r--Servers/WindowServer/WSMenuManager.cpp45
1 files changed, 45 insertions, 0 deletions
diff --git a/Servers/WindowServer/WSMenuManager.cpp b/Servers/WindowServer/WSMenuManager.cpp
index 5be1a6c5a1..7712bedaf6 100644
--- a/Servers/WindowServer/WSMenuManager.cpp
+++ b/Servers/WindowServer/WSMenuManager.cpp
@@ -129,6 +129,12 @@ void WSMenuManager::draw()
auto& audio_bitmap = m_audio_muted ? *m_muted_bitmap : *m_unmuted_bitmap;
painter.blit(m_audio_rect.location(), audio_bitmap, audio_bitmap.rect());
+
+ for (auto& applet : m_applets) {
+ if (!applet)
+ continue;
+ draw_applet(*applet);
+ }
}
void WSMenuManager::tick_clock()
@@ -282,3 +288,42 @@ void WSMenuManager::close_bar()
close_everyone();
m_bar_open = false;
}
+
+void WSMenuManager::add_applet(WSMenuApplet& applet)
+{
+ int right_edge_x = m_audio_rect.x() - 4;
+ for (auto& existing_applet : m_applets) {
+ if (existing_applet)
+ right_edge_x = existing_applet->rect_in_menubar().x() - 4;
+ }
+
+ Rect new_applet_rect(right_edge_x - applet.size().width(), 0, applet.size().width(), applet.size().height());
+ Rect dummy_menubar_rect(0, 0, 0, 18);
+ new_applet_rect.center_vertically_within(dummy_menubar_rect);
+
+ applet.set_rect_in_menubar(new_applet_rect);
+ m_applets.append(applet.make_weak_ptr());
+}
+
+void WSMenuManager::remove_applet(WSMenuApplet& applet)
+{
+ m_applets.remove_first_matching([&](auto& entry) {
+ return &applet == entry.ptr();
+ });
+}
+
+void WSMenuManager::draw_applet(const WSMenuApplet& applet)
+{
+ if (!applet.bitmap())
+ return;
+ Painter painter(*window().backing_store());
+ painter.blit(applet.rect_in_menubar().location(), *applet.bitmap(), applet.bitmap()->rect());
+}
+
+void WSMenuManager::invalidate_applet(WSMenuApplet& applet, const Rect& rect)
+{
+ // FIXME: This should only invalidate the applet's own rect, not the whole menubar.
+ (void)rect;
+ draw_applet(applet);
+ window().invalidate();
+}