diff options
author | Julian Offenhäuser <metalvoidzz@gmail.com> | 2020-12-05 02:26:21 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-12-06 00:19:04 +0100 |
commit | 503aebaefc7fbda98c3411b927f3c2bea56170aa (patch) | |
tree | 7195e2288806c7d7995cffa8a6fa82e1578a88b2 /Services | |
parent | 4ec77ba929ed13ed639b803aebb9aa61b1353443 (diff) | |
download | serenity-503aebaefc7fbda98c3411b927f3c2bea56170aa.zip |
WindowServer: Allow for more flexible tiling
The desktop can now be split up into halves (both vertical and
horizontal) and quarters by dragging a window into the corresponding
edge or corner.
This makes tiling behave more like you would expect from similiar
window managers.
Diffstat (limited to 'Services')
-rw-r--r-- | Services/WindowServer/Window.cpp | 42 | ||||
-rw-r--r-- | Services/WindowServer/Window.h | 6 | ||||
-rw-r--r-- | Services/WindowServer/WindowManager.cpp | 30 |
3 files changed, 64 insertions, 14 deletions
diff --git a/Services/WindowServer/Window.cpp b/Services/WindowServer/Window.cpp index 6c1c5275f3..d1c007dc6a 100644 --- a/Services/WindowServer/Window.cpp +++ b/Services/WindowServer/Window.cpp @@ -598,19 +598,53 @@ void Window::set_fullscreen(bool fullscreen) Gfx::IntRect Window::tiled_rect(WindowTileType tiled) const { int frame_width = (m_frame.rect().width() - m_rect.width()) / 2; + int title_bar_height = m_frame.title_bar_rect().height(); + int menu_height = WindowManager::the().maximized_window_rect(*this).y(); + int max_height = WindowManager::the().maximized_window_rect(*this).height(); + switch (tiled) { case WindowTileType::None: return m_untiled_rect; case WindowTileType::Left: return Gfx::IntRect(0, - WindowManager::the().maximized_window_rect(*this).y(), + menu_height, Screen::the().width() / 2 - frame_width, - WindowManager::the().maximized_window_rect(*this).height()); + max_height); case WindowTileType::Right: return Gfx::IntRect(Screen::the().width() / 2 + frame_width, - WindowManager::the().maximized_window_rect(*this).y(), + menu_height, + Screen::the().width() / 2 - frame_width, + max_height); + case WindowTileType::Top: + return Gfx::IntRect(0, + menu_height, + Screen::the().width() - frame_width, + (max_height - title_bar_height) / 2 - frame_width); + case WindowTileType::Bottom: + return Gfx::IntRect(0, + menu_height + (title_bar_height + max_height) / 2 + frame_width, + Screen::the().width() - frame_width, + (max_height - title_bar_height) / 2 - frame_width); + case WindowTileType::TopLeft: + return Gfx::IntRect(0, + menu_height, + Screen::the().width() / 2 - frame_width, + (max_height - title_bar_height) / 2 - frame_width); + case WindowTileType::TopRight: + return Gfx::IntRect(Screen::the().width() / 2 + frame_width, + menu_height, + Screen::the().width() / 2 - frame_width, + (max_height - title_bar_height) / 2 - frame_width); + case WindowTileType::BottomLeft: + return Gfx::IntRect(0, + menu_height + (title_bar_height + max_height) / 2 + frame_width, + Screen::the().width() / 2 - frame_width, + (max_height - title_bar_height) / 2); + case WindowTileType::BottomRight: + return Gfx::IntRect(Screen::the().width() / 2 + frame_width, + menu_height + (title_bar_height + max_height) / 2 + frame_width, Screen::the().width() / 2 - frame_width, - WindowManager::the().maximized_window_rect(*this).height()); + (max_height - title_bar_height) / 2); default: ASSERT_NOT_REACHED(); } diff --git a/Services/WindowServer/Window.h b/Services/WindowServer/Window.h index 2ff46c2ce9..75e7175a41 100644 --- a/Services/WindowServer/Window.h +++ b/Services/WindowServer/Window.h @@ -55,6 +55,12 @@ enum class WindowTileType { None = 0, Left, Right, + Top, + Bottom, + TopLeft, + TopRight, + BottomLeft, + BottomRight }; enum class PopupMenuItem { diff --git a/Services/WindowServer/WindowManager.cpp b/Services/WindowServer/WindowManager.cpp index 68291c016a..b25c72c82b 100644 --- a/Services/WindowServer/WindowManager.cpp +++ b/Services/WindowServer/WindowManager.cpp @@ -528,7 +528,8 @@ bool WindowManager::process_ongoing_window_move(MouseEvent& event, Window*& hove #endif - const int maximization_deadzone = 2; + const int tiling_deadzone = 10; + const int secondary_deadzone = 2; if (m_move_window->is_maximized()) { auto pixels_moved_from_start = event.position().pixels_moved(m_move_origin); @@ -536,7 +537,7 @@ bool WindowManager::process_ongoing_window_move(MouseEvent& event, Window*& hove if (pixels_moved_from_start > 5) { // dbg() << "[WM] de-maximizing window"; m_move_origin = event.position(); - if (m_move_origin.y() <= maximization_deadzone) + if (m_move_origin.y() <= secondary_deadzone) return true; auto width_before_resize = m_move_window->width(); m_move_window->set_maximized(false); @@ -546,17 +547,26 @@ bool WindowManager::process_ongoing_window_move(MouseEvent& event, Window*& hove } else { bool is_resizable = m_move_window->is_resizable(); auto pixels_moved_from_start = event.position().pixels_moved(m_move_origin); - const int tiling_deadzone = 5; + auto desktop = desktop_rect(); - if (is_resizable && event.y() <= maximization_deadzone) { - m_move_window->set_tiled(WindowTileType::None); - m_move_window->set_maximized(true); - return true; - } if (is_resizable && event.x() <= tiling_deadzone) { - m_move_window->set_tiled(WindowTileType::Left); + if (event.y() <= tiling_deadzone + desktop.top()) + m_move_window->set_tiled(WindowTileType::TopLeft); + else if (event.y() >= desktop.height() - tiling_deadzone) + m_move_window->set_tiled(WindowTileType::BottomLeft); + else + m_move_window->set_tiled(WindowTileType::Left); } else if (is_resizable && event.x() >= Screen::the().width() - tiling_deadzone) { - m_move_window->set_tiled(WindowTileType::Right); + if (event.y() <= tiling_deadzone + desktop.top()) + m_move_window->set_tiled(WindowTileType::TopRight); + else if (event.y() >= desktop.height() - tiling_deadzone) + m_move_window->set_tiled(WindowTileType::BottomRight); + else + m_move_window->set_tiled(WindowTileType::Right); + } else if (is_resizable && event.y() <= secondary_deadzone + desktop.top()) { + m_move_window->set_tiled(WindowTileType::Top); + } else if (is_resizable && event.y() >= desktop.bottom() - secondary_deadzone) { + m_move_window->set_tiled(WindowTileType::Bottom); } else if (pixels_moved_from_start > 5 || m_move_window->tiled() == WindowTileType::None) { m_move_window->set_tiled(WindowTileType::None); Gfx::IntPoint pos = m_move_window_origin.translated(event.position() - m_move_origin); |