diff --git a/Servers/WindowServer/WSWindow.cpp b/Servers/WindowServer/WSWindow.cpp index 05506a5531..5d30d596cb 100644 --- a/Servers/WindowServer/WSWindow.cpp +++ b/Servers/WindowServer/WSWindow.cpp @@ -340,3 +340,33 @@ void WSWindow::set_fullscreen(bool fullscreen) CEventLoop::current().post_event(*this, make(m_rect, new_window_rect)); set_rect(new_window_rect); } + +void WSWindow::set_tiled(WindowTileType tiled) +{ + if (m_tiled == tiled) + return; + m_tiled = tiled; + auto old_rect = m_rect; + + auto frame_width = m_frame.rect().width() - m_rect.width(); + switch (tiled) { + case WindowTileType::None : + set_rect(m_untiled_rect); + break; + case WindowTileType::Left : + m_untiled_rect = m_rect; + set_rect(0, + WSWindowManager::the().maximized_window_rect(*this).y(), + WSScreen::the().width() / 2, + WSWindowManager::the().maximized_window_rect(*this).height()); + break; + case WindowTileType::Right : + m_untiled_rect = m_rect; + set_rect(WSScreen::the().width() / 2 + frame_width, + WSWindowManager::the().maximized_window_rect(*this).y(), + (WSScreen::the().width() / 2), + WSWindowManager::the().maximized_window_rect(*this).height()); + break; + } + CEventLoop::current().post_event(*this, make(old_rect, m_rect)); +} diff --git a/Servers/WindowServer/WSWindow.h b/Servers/WindowServer/WSWindow.h index 1957f2b32f..951a11f349 100644 --- a/Servers/WindowServer/WSWindow.h +++ b/Servers/WindowServer/WSWindow.h @@ -21,6 +21,12 @@ enum WSWMEventMask { WindowRemovals = 1 << 3, }; +enum class WindowTileType { + None = 0, + Left, + Right, +}; + class WSWindow final : public CObject , public InlineLinkedListNode { C_OBJECT(WSWindow) @@ -44,6 +50,9 @@ public: bool is_fullscreen() const { return m_fullscreen; } void set_fullscreen(bool); + WindowTileType tiled() const { return m_tiled; } + void set_tiled(WindowTileType); + bool is_occluded() const { return m_occluded; } void set_occluded(bool); @@ -194,6 +203,8 @@ private: bool m_minimized { false }; bool m_maximized { false }; bool m_fullscreen { false }; + WindowTileType m_tiled { WindowTileType::None }; + Rect m_untiled_rect; bool m_occluded { false }; bool m_show_titlebar { true }; RefPtr m_backing_store; diff --git a/Servers/WindowServer/WSWindowManager.cpp b/Servers/WindowServer/WSWindowManager.cpp index 41fec072ab..c38e9a5acd 100644 --- a/Servers/WindowServer/WSWindowManager.cpp +++ b/Servers/WindowServer/WSWindowManager.cpp @@ -543,6 +543,7 @@ bool WSWindowManager::process_ongoing_window_move(WSMouseEvent& event, WSWindow* #ifdef MOVE_DEBUG dbg() << "[WM] Finish moving WSWindow{" << m_move_window << "}"; #endif + invalidate(*m_move_window); if (m_move_window->rect().contains(event.position())) hovered_window = m_move_window; @@ -565,7 +566,9 @@ bool WSWindowManager::process_ongoing_window_move(WSMouseEvent& event, WSWindow* if (m_move_window->is_maximized()) { dbg() << " [!] The window is still maximized. Not moving yet."; } + #endif + if (m_move_window->is_maximized()) { auto pixels_moved_from_start = event.position().pixels_moved(m_move_origin); // dbg() << "[WM] " << pixels_moved_from_start << " moved since start of window move"; @@ -578,10 +581,20 @@ bool WSWindowManager::process_ongoing_window_move(WSMouseEvent& event, WSWindow* m_move_window_origin = m_move_window->position(); } } else { - Point pos = m_move_window_origin.translated(event.position() - m_move_origin); - m_move_window->set_position_without_repaint(pos); - if (m_move_window->rect().contains(event.position())) - hovered_window = m_move_window; + auto pixels_moved_from_start = event.position().pixels_moved(m_move_origin); + const int tiling_deadzone = 5; + + if (event.x() <= tiling_deadzone) { + m_move_window->set_tiled(WindowTileType::Left); + } else if (event.x() >= WSScreen::the().width() - tiling_deadzone) { + m_move_window->set_tiled(WindowTileType::Right); + } else if (pixels_moved_from_start > 5 || m_move_window->tiled() == WindowTileType::None) { + m_move_window->set_tiled(WindowTileType::None); + Point pos = m_move_window_origin.translated(event.position() - m_move_origin); + m_move_window->set_position_without_repaint(pos); + if (m_move_window->rect().contains(event.position())) + hovered_window = m_move_window; + } return true; } }