summaryrefslogtreecommitdiff
path: root/Services
diff options
context:
space:
mode:
authorJulian Offenhäuser <metalvoidzz@gmail.com>2020-12-05 02:26:21 +0100
committerAndreas Kling <kling@serenityos.org>2020-12-06 00:19:04 +0100
commit503aebaefc7fbda98c3411b927f3c2bea56170aa (patch)
tree7195e2288806c7d7995cffa8a6fa82e1578a88b2 /Services
parent4ec77ba929ed13ed639b803aebb9aa61b1353443 (diff)
downloadserenity-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.cpp42
-rw-r--r--Services/WindowServer/Window.h6
-rw-r--r--Services/WindowServer/WindowManager.cpp30
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);