summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-12-16 15:33:42 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-12-16 15:33:42 +0100
commite1940f365be62435c815b3cd6a022356840edb10 (patch)
treeaf85f767a0c887f593acbd3b933c7f882bc99b29
parentdf129bbe0e3d300a9a35a966af4ee323ced90cda (diff)
downloadserenity-e1940f365be62435c815b3cd6a022356840edb10.zip
WindowServer+MenuApplets: Move the "Audio" applet to its own program
This patch introduces the second MenuApplet: Audio. To make this work, menu applet windows now also receive mouse events. There's still some problem with mute/unmute via clicking not actually working, but the call goes from the applet program over IPC to the AudioServer, where something goes wrong with the state change message. Need to look at that separately. Anyways, it's pretty cool to have more applets running in their own separate processes. :^)
-rw-r--r--Base/etc/SystemServer.ini4
-rwxr-xr-xKernel/build-root-filesystem.sh1
-rwxr-xr-xKernel/makeall.sh1
-rwxr-xr-xMenuApplets/Audio/Audio.MenuAppletbin0 -> 1410124 bytes
-rwxr-xr-xMenuApplets/Audio/Makefile7
-rw-r--r--MenuApplets/Audio/main.cpp65
-rw-r--r--Servers/WindowServer/WSMenuBar.h2
-rw-r--r--Servers/WindowServer/WSMenuManager.cpp52
-rw-r--r--Servers/WindowServer/WSMenuManager.h7
-rw-r--r--Servers/WindowServer/WSWindowManager.cpp2
-rw-r--r--Servers/WindowServer/WSWindowManager.h3
11 files changed, 98 insertions, 46 deletions
diff --git a/Base/etc/SystemServer.ini b/Base/etc/SystemServer.ini
index 342c67a6d4..f46923f0fd 100644
--- a/Base/etc/SystemServer.ini
+++ b/Base/etc/SystemServer.ini
@@ -28,6 +28,10 @@ User=anon
KeepAlive=1
User=anon
+[Audio.MenuApplet]
+KeepAlive=1
+User=anon
+
[AudioServer]
Socket=/tmp/portal/audio
# TODO: we may want to start it lazily, but right now WindowServer connects to it immediately on startup
diff --git a/Kernel/build-root-filesystem.sh b/Kernel/build-root-filesystem.sh
index 769d0ca5df..d9a6f34e44 100755
--- a/Kernel/build-root-filesystem.sh
+++ b/Kernel/build-root-filesystem.sh
@@ -109,6 +109,7 @@ cp ../Servers/TTYServer/TTYServer mnt/bin/TTYServer
cp ../Servers/TelnetServer/TelnetServer mnt/bin/TelnetServer
cp ../Servers/ProtocolServer/ProtocolServer mnt/bin/ProtocolServer
cp ../Shell/Shell mnt/bin/Shell
+cp ../MenuApplets/Audio/Audio.MenuApplet mnt/bin/
cp ../MenuApplets/CPUGraph/CPUGraph.MenuApplet mnt/bin/
echo "done"
diff --git a/Kernel/makeall.sh b/Kernel/makeall.sh
index d0d8879251..d89464eb36 100755
--- a/Kernel/makeall.sh
+++ b/Kernel/makeall.sh
@@ -93,6 +93,7 @@ build_targets="$build_targets ../Shell"
build_targets="$build_targets ../Userland"
+build_targets="$build_targets ../MenuApplets/Audio"
build_targets="$build_targets ../MenuApplets/CPUGraph"
build_targets="$build_targets ." # the kernel
diff --git a/MenuApplets/Audio/Audio.MenuApplet b/MenuApplets/Audio/Audio.MenuApplet
new file mode 100755
index 0000000000..dd4c89fcf9
--- /dev/null
+++ b/MenuApplets/Audio/Audio.MenuApplet
Binary files differ
diff --git a/MenuApplets/Audio/Makefile b/MenuApplets/Audio/Makefile
new file mode 100755
index 0000000000..cd0292e1ef
--- /dev/null
+++ b/MenuApplets/Audio/Makefile
@@ -0,0 +1,7 @@
+include ../../Makefile.common
+
+OBJS = main.o
+
+APP = Audio.MenuApplet
+
+include ../Makefile.common
diff --git a/MenuApplets/Audio/main.cpp b/MenuApplets/Audio/main.cpp
new file mode 100644
index 0000000000..bbd55f750c
--- /dev/null
+++ b/MenuApplets/Audio/main.cpp
@@ -0,0 +1,65 @@
+#include <LibAudio/AClientConnection.h>
+#include <LibGUI/GApplication.h>
+#include <LibGUI/GPainter.h>
+#include <LibGUI/GWidget.h>
+#include <LibGUI/GWindow.h>
+
+class AudioWidget final : public GWidget {
+ C_OBJECT(AudioWidget)
+public:
+ AudioWidget()
+ : GWidget(nullptr)
+ {
+ m_audio_client = make<AClientConnection>();
+ m_audio_client->on_muted_state_change = [this](bool muted) {
+ dbg() << "Muted state changed: " << muted;
+ if (m_audio_muted == muted)
+ return;
+ m_audio_muted = muted;
+ update();
+ };
+ m_unmuted_bitmap = GraphicsBitmap::load_from_file("/res/icons/audio-unmuted.png");
+ m_muted_bitmap = GraphicsBitmap::load_from_file("/res/icons/audio-muted.png");
+ }
+
+ virtual ~AudioWidget() override {}
+
+private:
+ virtual void mousedown_event(GMouseEvent& event) override
+ {
+ if (event.button() != GMouseButton::Left)
+ return;
+ dbg() << "set_muted: " << !m_audio_muted;
+ m_audio_client->set_muted(!m_audio_muted);
+ update();
+ }
+
+ virtual void paint_event(GPaintEvent& event) override
+ {
+ GPainter painter(*this);
+ painter.add_clip_rect(event.rect());
+ painter.clear_rect(event.rect(), Color::from_rgba(0));
+ auto& audio_bitmap = m_audio_muted ? *m_muted_bitmap : *m_unmuted_bitmap;
+ painter.blit({}, audio_bitmap, audio_bitmap.rect());
+ }
+
+ OwnPtr<AClientConnection> m_audio_client;
+ RefPtr<GraphicsBitmap> m_muted_bitmap;
+ RefPtr<GraphicsBitmap> m_unmuted_bitmap;
+ bool m_audio_muted { false };
+};
+
+int main(int argc, char** argv)
+{
+ GApplication app(argc, argv);
+
+ auto window = GWindow::construct();
+ window->set_has_alpha_channel(true);
+ window->set_window_type(GWindowType::MenuApplet);
+ window->resize(12, 16);
+
+ auto widget = AudioWidget::construct();
+ window->set_main_widget(widget);
+ window->show();
+ return app.exec();
+}
diff --git a/Servers/WindowServer/WSMenuBar.h b/Servers/WindowServer/WSMenuBar.h
index c26a3447b0..57dffef118 100644
--- a/Servers/WindowServer/WSMenuBar.h
+++ b/Servers/WindowServer/WSMenuBar.h
@@ -23,7 +23,7 @@ public:
void for_each_menu(Callback callback)
{
for (auto& menu : m_menus) {
- if (!callback(*menu))
+ if (callback(*menu) == IterationDecision::Break)
return;
}
}
diff --git a/Servers/WindowServer/WSMenuManager.cpp b/Servers/WindowServer/WSMenuManager.cpp
index 730c7e841b..cccb76782c 100644
--- a/Servers/WindowServer/WSMenuManager.cpp
+++ b/Servers/WindowServer/WSMenuManager.cpp
@@ -1,4 +1,3 @@
-#include <LibAudio/AClientConnection.h>
#include <LibCore/CTimer.h>
#include <LibDraw/Font.h>
#include <LibDraw/Painter.h>
@@ -10,20 +9,6 @@
WSMenuManager::WSMenuManager()
{
- m_audio_client = make<AClientConnection>();
- m_audio_client->on_muted_state_change = [this](bool muted) {
- if (m_audio_muted == muted)
- return;
- m_audio_muted = muted;
- if (m_window) {
- draw();
- m_window->invalidate();
- }
- };
-
- m_unmuted_bitmap = GraphicsBitmap::load_from_file("/res/icons/audio-unmuted.png");
- m_muted_bitmap = GraphicsBitmap::load_from_file("/res/icons/audio-muted.png");
-
m_username = getlogin();
m_needs_window_resize = true;
@@ -71,7 +56,6 @@ void WSMenuManager::draw()
menubar_rect.height()
};
-
int time_width = Font::default_font().width("2222-22-22 22:22:22");
m_time_rect = {
m_username_rect.left() - menubar_menu_margin() / 2 - time_width,
@@ -80,18 +64,16 @@ void WSMenuManager::draw()
menubar_rect.height()
};
- m_audio_rect = { m_time_rect.right() - time_width - 20, m_time_rect.y() + 1, 12, 16 };
-
- int right_edge_x = m_audio_rect.x() - 4;
+ int right_edge_x = m_time_rect.left() - 4;
for (auto& existing_applet : m_applets) {
- if (! existing_applet)
+ if (!existing_applet)
continue;
-
+
Rect new_applet_rect(right_edge_x - existing_applet->size().width(), 0, existing_applet->size().width(), existing_applet->size().height());
Rect dummy_menubar_rect(0, 0, 0, 18);
new_applet_rect.center_vertically_within(dummy_menubar_rect);
- existing_applet->set_rect_in_menubar(new_applet_rect);
+ existing_applet->set_rect_in_menubar(new_applet_rect);
right_edge_x = existing_applet->rect_in_menubar().x() - 4;
}
@@ -118,7 +100,7 @@ void WSMenuManager::draw()
TextAlignment::CenterLeft,
text_color);
++index;
- return true;
+ return IterationDecision::Continue;
});
painter.draw_text(m_username_rect, m_username, Font::default_bold_font(), TextAlignment::CenterRight, Color::Black);
@@ -133,12 +115,8 @@ void WSMenuManager::draw()
tm->tm_min,
tm->tm_sec);
-
painter.draw_text(m_time_rect, time_text, wm.font(), TextAlignment::CenterRight, Color::Black);
- 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;
@@ -165,21 +143,23 @@ void WSMenuManager::event(CEvent& event)
return CObject::event(event);
if (event.type() == WSEvent::MouseMove || event.type() == WSEvent::MouseUp || event.type() == WSEvent::MouseDown || event.type() == WSEvent::MouseWheel) {
+
auto& mouse_event = static_cast<WSMouseEvent&>(event);
WSWindowManager::the().for_each_active_menubar_menu([&](WSMenu& menu) {
if (menu.rect_in_menubar().contains(mouse_event.position())) {
handle_menu_mouse_event(menu, mouse_event);
- return false;
+ return IterationDecision::Break;
}
- return true;
+ return IterationDecision::Continue;
});
- if (mouse_event.type() == WSEvent::MouseDown
- && mouse_event.button() == MouseButton::Left
- && m_audio_rect.contains(mouse_event.position())) {
- m_audio_client->set_muted(!m_audio_muted);
- draw();
- m_window->invalidate();
+ for (auto& applet : m_applets) {
+ if (!applet)
+ continue;
+ if (!applet->rect_in_menubar().contains(mouse_event.position()))
+ continue;
+ auto local_event = mouse_event.translated(-applet->rect_in_menubar().location());
+ applet->event(local_event);
}
}
return CObject::event(event);
@@ -300,7 +280,7 @@ void WSMenuManager::close_bar()
void WSMenuManager::add_applet(WSWindow& applet)
{
- int right_edge_x = m_audio_rect.x() - 4;
+ int right_edge_x = m_time_rect.left() - 4;
for (auto& existing_applet : m_applets) {
if (existing_applet)
right_edge_x = existing_applet->rect_in_menubar().x() - 4;
diff --git a/Servers/WindowServer/WSMenuManager.h b/Servers/WindowServer/WSMenuManager.h
index 740cd3be1a..24c3adf15e 100644
--- a/Servers/WindowServer/WSMenuManager.h
+++ b/Servers/WindowServer/WSMenuManager.h
@@ -58,18 +58,11 @@ private:
WeakPtr<WSMenu> m_current_menu;
Vector<WeakPtr<WSMenu>> m_open_menu_stack;
- RefPtr<GraphicsBitmap> m_muted_bitmap;
- RefPtr<GraphicsBitmap> m_unmuted_bitmap;
-
Vector<WeakPtr<WSWindow>> m_applets;
- OwnPtr<AClientConnection> m_audio_client;
-
- Rect m_audio_rect;
Rect m_username_rect;
Rect m_time_rect;
bool m_needs_window_resize { false };
bool m_bar_open { false };
- bool m_audio_muted { false };
};
diff --git a/Servers/WindowServer/WSWindowManager.cpp b/Servers/WindowServer/WSWindowManager.cpp
index ea750907d9..99498344a8 100644
--- a/Servers/WindowServer/WSWindowManager.cpp
+++ b/Servers/WindowServer/WSWindowManager.cpp
@@ -260,7 +260,7 @@ void WSWindowManager::set_current_menubar(WSMenuBar* menubar)
menu.set_text_rect_in_menubar({ next_menu_location, { text_width, menubar_rect().height() } });
next_menu_location.move_by(menu.rect_in_menubar().width(), 0);
++index;
- return true;
+ return IterationDecision::Continue;
});
m_menu_manager.refresh();
}
diff --git a/Servers/WindowServer/WSWindowManager.h b/Servers/WindowServer/WSWindowManager.h
index 88e8bc7d87..b7c6531a94 100644
--- a/Servers/WindowServer/WSWindowManager.h
+++ b/Servers/WindowServer/WSWindowManager.h
@@ -149,7 +149,8 @@ public:
template<typename Callback>
void for_each_active_menubar_menu(Callback callback)
{
- callback(*m_system_menu);
+ if (callback(*m_system_menu) == IterationDecision::Break)
+ return;
if (m_current_menubar)
m_current_menubar->for_each_menu(callback);
}