summaryrefslogtreecommitdiff
path: root/Applications
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-04-23 23:14:14 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-04-23 23:14:14 +0200
commit956bd23aae947039935b01eae00f9736e6614ec9 (patch)
tree66310f6f9c1f672bb32d0532be04c03dc65b09bd /Applications
parentc5c4e54a67bc97d80616710b4d57dd34ee54a774 (diff)
downloadserenity-956bd23aae947039935b01eae00f9736e6614ec9.zip
WindowServer+TaskBar: Add a taskbar window button popup menu.
This patch only hooks up the minimize and unminimize actions.
Diffstat (limited to 'Applications')
-rw-r--r--Applications/Taskbar/Makefile1
-rw-r--r--Applications/Taskbar/TaskbarButton.cpp48
-rw-r--r--Applications/Taskbar/TaskbarButton.h18
-rw-r--r--Applications/Taskbar/TaskbarWindow.cpp15
-rw-r--r--Applications/Taskbar/TaskbarWindow.h4
-rw-r--r--Applications/Taskbar/WindowList.cpp10
-rw-r--r--Applications/Taskbar/WindowList.h34
7 files changed, 89 insertions, 41 deletions
diff --git a/Applications/Taskbar/Makefile b/Applications/Taskbar/Makefile
index 4f1ca2d20c..8e15cb6cb6 100644
--- a/Applications/Taskbar/Makefile
+++ b/Applications/Taskbar/Makefile
@@ -2,6 +2,7 @@ include ../../Makefile.common
OBJS = \
TaskbarWindow.o \
+ TaskbarButton.o \
WindowList.o \
main.o
diff --git a/Applications/Taskbar/TaskbarButton.cpp b/Applications/Taskbar/TaskbarButton.cpp
new file mode 100644
index 0000000000..0deea6309c
--- /dev/null
+++ b/Applications/Taskbar/TaskbarButton.cpp
@@ -0,0 +1,48 @@
+#include "TaskbarButton.h"
+#include <WindowServer/WSAPITypes.h>
+#include <LibGUI/GAction.h>
+#include <LibGUI/GMenu.h>
+#include <LibGUI/GEventLoop.h>
+
+static void set_window_minimized_state(const WindowIdentifier& identifier, bool minimized)
+{
+ WSAPI_ClientMessage message;
+ message.type = WSAPI_ClientMessage::Type::WM_SetWindowMinimized;
+ message.wm.client_id = identifier.client_id();
+ message.wm.window_id = identifier.window_id();
+ message.wm.minimized = minimized;
+ bool success = GEventLoop::post_message_to_server(message);
+ ASSERT(success);
+}
+
+TaskbarButton::TaskbarButton(const WindowIdentifier& identifier, GWidget* parent)
+ : GButton(parent)
+ , m_identifier(identifier)
+{
+}
+
+TaskbarButton::~TaskbarButton()
+{
+}
+
+void TaskbarButton::context_menu_event(GContextMenuEvent&)
+{
+ ensure_menu().popup(screen_relative_rect().location(), /* top_anchored */ false);
+}
+
+GMenu& TaskbarButton::ensure_menu()
+{
+ if (!m_menu) {
+ m_menu = make<GMenu>("");
+ m_menu->add_action(GAction::create("Minimize", [this] (auto&) {
+ set_window_minimized_state(m_identifier, true);
+ }));
+ m_menu->add_action(GAction::create("Unminimize", [this] (auto&) {
+ set_window_minimized_state(m_identifier, false);
+ }));
+ m_menu->add_action(GAction::create("Close", [this] (auto&) {
+ dbgprintf("FIXME: Close!\n");
+ }));
+ }
+ return *m_menu;
+}
diff --git a/Applications/Taskbar/TaskbarButton.h b/Applications/Taskbar/TaskbarButton.h
new file mode 100644
index 0000000000..6cb790521a
--- /dev/null
+++ b/Applications/Taskbar/TaskbarButton.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include <LibGUI/GButton.h>
+#include "WindowIdentifier.h"
+
+class TaskbarButton final : public GButton {
+public:
+ TaskbarButton(const WindowIdentifier&, GWidget* parent);
+ virtual ~TaskbarButton() override;
+
+private:
+ virtual void context_menu_event(GContextMenuEvent&) override;
+
+ GMenu& ensure_menu();
+
+ WindowIdentifier m_identifier;
+ OwnPtr<GMenu> m_menu;
+};
diff --git a/Applications/Taskbar/TaskbarWindow.cpp b/Applications/Taskbar/TaskbarWindow.cpp
index 562d6aad63..126a60bd73 100644
--- a/Applications/Taskbar/TaskbarWindow.cpp
+++ b/Applications/Taskbar/TaskbarWindow.cpp
@@ -1,4 +1,5 @@
#include "TaskbarWindow.h"
+#include "TaskbarButton.h"
#include <LibGUI/GWindow.h>
#include <LibGUI/GDesktop.h>
#include <LibGUI/GEventLoop.h>
@@ -30,8 +31,8 @@ TaskbarWindow::TaskbarWindow()
widget->set_frame_shadow(FrameShadow::Raised);
set_main_widget(widget);
- m_window_list.aid_create_button = [this] {
- return create_button();
+ WindowList::the().aid_create_button = [this] (auto& identifier) {
+ return create_button(identifier);
};
}
@@ -45,9 +46,9 @@ void TaskbarWindow::on_screen_rect_change(const Rect& rect)
set_rect(new_rect);
}
-GButton* TaskbarWindow::create_button()
+GButton* TaskbarWindow::create_button(const WindowIdentifier& identifier)
{
- auto* button = new GButton(main_widget());
+ auto* button = new TaskbarButton(identifier, main_widget());
button->set_size_policy(SizePolicy::Fixed, SizePolicy::Fixed);
button->set_preferred_size({ 140, 22 });
button->set_checkable(true);
@@ -72,7 +73,7 @@ void TaskbarWindow::wm_event(GWMEvent& event)
removed_event.window_id()
);
#endif
- m_window_list.remove_window(identifier);
+ WindowList::the().remove_window(identifier);
update();
break;
}
@@ -96,7 +97,7 @@ void TaskbarWindow::wm_event(GWMEvent& event)
changed_event.icon_path().characters()
);
#endif
- if (auto* window = m_window_list.window(identifier)) {
+ if (auto* window = WindowList::the().window(identifier)) {
window->set_icon_path(changed_event.icon_path());
window->button()->set_icon(window->icon());
}
@@ -117,7 +118,7 @@ void TaskbarWindow::wm_event(GWMEvent& event)
#endif
if (!should_include_window(changed_event.window_type()))
break;
- auto& window = m_window_list.ensure_window(identifier);
+ auto& window = WindowList::the().ensure_window(identifier);
window.set_title(changed_event.title());
window.set_rect(changed_event.rect());
window.set_active(changed_event.is_active());
diff --git a/Applications/Taskbar/TaskbarWindow.h b/Applications/Taskbar/TaskbarWindow.h
index 681d7b9181..856185343f 100644
--- a/Applications/Taskbar/TaskbarWindow.h
+++ b/Applications/Taskbar/TaskbarWindow.h
@@ -13,9 +13,7 @@ public:
private:
void on_screen_rect_change(const Rect&);
- GButton* create_button();
+ GButton* create_button(const WindowIdentifier&);
virtual void wm_event(GWMEvent&) override;
-
- WindowList m_window_list;
};
diff --git a/Applications/Taskbar/WindowList.cpp b/Applications/Taskbar/WindowList.cpp
index c149853ea3..35f0c1a3cb 100644
--- a/Applications/Taskbar/WindowList.cpp
+++ b/Applications/Taskbar/WindowList.cpp
@@ -2,6 +2,14 @@
#include <WindowServer/WSAPITypes.h>
#include <LibGUI/GEventLoop.h>
+WindowList& WindowList::the()
+{
+ static WindowList* s_the;
+ if (!s_the)
+ s_the = new WindowList;
+ return *s_the;
+}
+
Window* WindowList::window(const WindowIdentifier& identifier)
{
auto it = m_windows.find(identifier);
@@ -16,7 +24,7 @@ Window& WindowList::ensure_window(const WindowIdentifier& identifier)
if (it != m_windows.end())
return *it->value;
auto window = make<Window>(identifier);
- window->set_button(aid_create_button());
+ window->set_button(aid_create_button(identifier));
window->button()->on_click = [identifier] (GButton&) {
WSAPI_ClientMessage message;
message.type = WSAPI_ClientMessage::Type::WM_SetActiveWindow;
diff --git a/Applications/Taskbar/WindowList.h b/Applications/Taskbar/WindowList.h
index 458222c5b8..6ebaaa5328 100644
--- a/Applications/Taskbar/WindowList.h
+++ b/Applications/Taskbar/WindowList.h
@@ -2,37 +2,9 @@
#include <AK/AKString.h>
#include <AK/HashMap.h>
-#include <AK/Traits.h>
#include <SharedGraphics/Rect.h>
#include <LibGUI/GButton.h>
-
-class WindowIdentifier {
-public:
- WindowIdentifier(int client_id, int window_id)
- : m_client_id(client_id)
- , m_window_id(window_id)
- {
- }
-
- int client_id() const { return m_client_id; }
- int window_id() const { return m_window_id; }
-
- bool operator==(const WindowIdentifier& other) const
- {
- return m_client_id == other.m_client_id && m_window_id == other.m_window_id;
- }
-private:
- int m_client_id { -1 };
- int m_window_id { -1 };
-};
-
-namespace AK {
-template<>
-struct Traits<WindowIdentifier> {
- static unsigned hash(const WindowIdentifier& w) { return pair_int_hash(w.client_id(), w.window_id()); }
- static void dump(const WindowIdentifier& w) { kprintf("WindowIdentifier(%d, %d)", w.client_id(), w.window_id()); }
-};
-}
+#include "WindowIdentifier.h"
class Window {
public:
@@ -90,6 +62,8 @@ private:
class WindowList {
public:
+ static WindowList& the();
+
template<typename Callback> void for_each_window(Callback callback)
{
for (auto& it : m_windows)
@@ -100,7 +74,7 @@ public:
Window& ensure_window(const WindowIdentifier&);
void remove_window(const WindowIdentifier&);
- Function<GButton*()> aid_create_button;
+ Function<GButton*(const WindowIdentifier&)> aid_create_button;
private:
HashMap<WindowIdentifier, OwnPtr<Window>> m_windows;