summaryrefslogtreecommitdiff
path: root/Servers
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-04-05 22:32:00 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-04-05 22:32:00 +0200
commitf6ca94605ce08af9acfc79dae2c01cc2ab66ec45 (patch)
treefee3eeee5c58b71697853fb5b8c6c52025cad30d /Servers
parent0fc3ccaa5281c4e895cb0d0d96bfe25360bcea32 (diff)
downloadserenity-f6ca94605ce08af9acfc79dae2c01cc2ab66ec45.zip
WindowServer: Add a window minimization button.
The window is simply ignored in the painting and hit testing traversal when in minimized state, same as we do for invisible windows. The WM_SetActiveWindow message (sent by Taskbar) brings it back into the non-minimized state. :^)
Diffstat (limited to 'Servers')
-rw-r--r--Servers/WindowServer/WSClientConnection.cpp1
-rw-r--r--Servers/WindowServer/WSWindow.cpp8
-rw-r--r--Servers/WindowServer/WSWindow.h4
-rw-r--r--Servers/WindowServer/WSWindowFrame.cpp24
-rw-r--r--Servers/WindowServer/WSWindowManager.cpp11
-rw-r--r--Servers/WindowServer/WSWindowManager.h4
6 files changed, 49 insertions, 3 deletions
diff --git a/Servers/WindowServer/WSClientConnection.cpp b/Servers/WindowServer/WSClientConnection.cpp
index cd08b3e54e..202810ba66 100644
--- a/Servers/WindowServer/WSClientConnection.cpp
+++ b/Servers/WindowServer/WSClientConnection.cpp
@@ -532,6 +532,7 @@ void WSClientConnection::handle_request(const WSWMAPISetActiveWindowRequest& req
return;
}
auto& window = *(*it).value;
+ window.set_minimized(false);
WSWindowManager::the().move_to_front_and_make_active(window);
}
diff --git a/Servers/WindowServer/WSWindow.cpp b/Servers/WindowServer/WSWindow.cpp
index c186ac510d..397ac952ab 100644
--- a/Servers/WindowServer/WSWindow.cpp
+++ b/Servers/WindowServer/WSWindow.cpp
@@ -112,6 +112,14 @@ static WSAPI_WindowType to_api(WSWindowType ws_type)
}
}
+void WSWindow::set_minimized(bool minimized)
+{
+ if (m_minimized == minimized)
+ return;
+ m_minimized = minimized;
+ invalidate();
+}
+
void WSWindow::on_message(const WSMessage& message)
{
if (m_internal_owner)
diff --git a/Servers/WindowServer/WSWindow.h b/Servers/WindowServer/WSWindow.h
index abf8d009ec..d1f4f61504 100644
--- a/Servers/WindowServer/WSWindow.h
+++ b/Servers/WindowServer/WSWindow.h
@@ -19,6 +19,9 @@ public:
WSWindow(WSMessageReceiver&, WSWindowType);
virtual ~WSWindow() override;
+ bool is_minimized() const { return m_minimized; }
+ void set_minimized(bool);
+
WSWindowFrame& frame() { return m_frame; }
const WSWindowFrame& frame() const { return m_frame; }
@@ -139,6 +142,7 @@ private:
bool m_modal { false };
bool m_resizable { false };
bool m_listens_to_wm_events { false };
+ bool m_minimized { false };
RetainPtr<GraphicsBitmap> m_backing_store;
RetainPtr<GraphicsBitmap> m_last_backing_store;
int m_window_id { -1 };
diff --git a/Servers/WindowServer/WSWindowFrame.cpp b/Servers/WindowServer/WSWindowFrame.cpp
index ec08641d8d..6e9b8726f2 100644
--- a/Servers/WindowServer/WSWindowFrame.cpp
+++ b/Servers/WindowServer/WSWindowFrame.cpp
@@ -26,15 +26,39 @@ static CharacterBitmap* s_close_button_bitmap;
static const int s_close_button_bitmap_width = 8;
static const int s_close_button_bitmap_height = 9;
+static const char* s_minimize_button_bitmap_data = {
+ " "
+ " "
+ "## ##"
+ "### ###"
+ " ###### "
+ " #### "
+ " ## "
+ " "
+ " "
+};
+
+static CharacterBitmap* s_minimize_button_bitmap;
+static const int s_minimize_button_bitmap_width = 8;
+static const int s_minimize_button_bitmap_height = 9;
+
+
WSWindowFrame::WSWindowFrame(WSWindow& window)
: m_window(window)
{
if (!s_close_button_bitmap)
s_close_button_bitmap = &CharacterBitmap::create_from_ascii(s_close_button_bitmap_data, s_close_button_bitmap_width, s_close_button_bitmap_height).leak_ref();
+ if (!s_minimize_button_bitmap)
+ s_minimize_button_bitmap = &CharacterBitmap::create_from_ascii(s_minimize_button_bitmap_data, s_minimize_button_bitmap_width, s_minimize_button_bitmap_height).leak_ref();
+
m_buttons.append(make<WSButton>(*this, *s_close_button_bitmap, [this] {
m_window.on_message(WSMessage(WSMessage::WindowCloseRequest));
}));
+
+ m_buttons.append(make<WSButton>(*this, *s_minimize_button_bitmap, [this] {
+ m_window.set_minimized(true);
+ }));
}
WSWindowFrame::~WSWindowFrame()
diff --git a/Servers/WindowServer/WSWindowManager.cpp b/Servers/WindowServer/WSWindowManager.cpp
index da4f2026ca..6df3fb053d 100644
--- a/Servers/WindowServer/WSWindowManager.cpp
+++ b/Servers/WindowServer/WSWindowManager.cpp
@@ -624,6 +624,7 @@ void WSWindowManager::process_mouse_event(const WSMouseEvent& event, WSWindow*&
if (!window->global_cursor_tracking())
continue;
ASSERT(window->is_visible()); // Maybe this should be supported? Idk. Let's catch it and think about it later.
+ ASSERT(!window->is_minimized()); // Maybe this should also be supported? Idk.
windows_who_received_mouse_event_due_to_cursor_tracking.set(window);
window->on_message(event.translated(-window->position()));
}
@@ -688,6 +689,8 @@ void WSWindowManager::compose()
for (auto* window = m_windows_in_order.head(); window; window = window->next()) {
if (!window->is_visible())
continue;
+ if (window->is_minimized())
+ continue;
if (window->opacity() < 1.0f)
continue;
if (window->has_alpha_channel()) {
@@ -712,11 +715,13 @@ void WSWindowManager::compose()
if (!checking)
return IterationDecision::Continue;
if (!window.is_visible())
- return IterationDecision::Continue;;
+ return IterationDecision::Continue;
+ if (window.is_minimized())
+ return IterationDecision::Continue;
if (window.opacity() < 1.0f)
- return IterationDecision::Continue;;
+ return IterationDecision::Continue;
if (window.has_alpha_channel())
- return IterationDecision::Continue;;
+ return IterationDecision::Continue;
if (window.frame().rect().contains(rect)) {
found = true;
return IterationDecision::Abort;
diff --git a/Servers/WindowServer/WSWindowManager.h b/Servers/WindowServer/WSWindowManager.h
index 1b0d152b79..e6f89648d8 100644
--- a/Servers/WindowServer/WSWindowManager.h
+++ b/Servers/WindowServer/WSWindowManager.h
@@ -214,6 +214,8 @@ IterationDecision WSWindowManager::for_each_visible_window_of_type_from_back_to_
for (auto* window = m_windows_in_order.head(); window; window = window->next()) {
if (!window->is_visible())
continue;
+ if (window->is_minimized())
+ continue;
if (window->type() != type)
continue;
if (m_highlight_window.ptr() == window) {
@@ -253,6 +255,8 @@ IterationDecision WSWindowManager::for_each_visible_window_of_type_from_front_to
for (auto* window = m_windows_in_order.tail(); window; window = window->prev()) {
if (!window->is_visible())
continue;
+ if (window->is_minimized())
+ continue;
if (window->type() != type)
continue;
if (window == m_highlight_window.ptr())