diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-04-05 22:32:00 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-04-05 22:32:00 +0200 |
commit | f6ca94605ce08af9acfc79dae2c01cc2ab66ec45 (patch) | |
tree | fee3eeee5c58b71697853fb5b8c6c52025cad30d /Servers | |
parent | 0fc3ccaa5281c4e895cb0d0d96bfe25360bcea32 (diff) | |
download | serenity-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.cpp | 1 | ||||
-rw-r--r-- | Servers/WindowServer/WSWindow.cpp | 8 | ||||
-rw-r--r-- | Servers/WindowServer/WSWindow.h | 4 | ||||
-rw-r--r-- | Servers/WindowServer/WSWindowFrame.cpp | 24 | ||||
-rw-r--r-- | Servers/WindowServer/WSWindowManager.cpp | 11 | ||||
-rw-r--r-- | Servers/WindowServer/WSWindowManager.h | 4 |
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()) |