diff options
author | thankyouverycool <66646555+thankyouverycool@users.noreply.github.com> | 2022-02-07 13:46:07 -0500 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-02-08 16:37:46 +0100 |
commit | ee637b44fbc44d8453a720776a18a413c796a874 (patch) | |
tree | a4dcd1222a26b514011371722380c740848e8271 | |
parent | 32be05957a1d000c18364f1fce52b59fcde6ff68 (diff) | |
download | serenity-ee637b44fbc44d8453a720776a18a413c796a874.zip |
WindowServer: Add Vertically/HorizontallyMaximized WindowTileTypes
VerticallyMaximized tiling replaces set_vertically_maximized() to
take advantage of tiling ergonomics.
Middle-clicking a window's maximize button now tiles vertically;
secondary-clicking tiles horizontally.
Adds Super+Alt+Arrow shortcuts for both. Super+Left/Right tiling
shortcuts now let windows shift between tile types directly.
-rw-r--r-- | Userland/Services/WindowServer/Window.cpp | 35 | ||||
-rw-r--r-- | Userland/Services/WindowServer/Window.h | 6 | ||||
-rw-r--r-- | Userland/Services/WindowServer/WindowFrame.cpp | 13 | ||||
-rw-r--r-- | Userland/Services/WindowServer/WindowManager.cpp | 52 |
4 files changed, 74 insertions, 32 deletions
diff --git a/Userland/Services/WindowServer/Window.cpp b/Userland/Services/WindowServer/Window.cpp index 304a60a179..5c9ade0825 100644 --- a/Userland/Services/WindowServer/Window.cpp +++ b/Userland/Services/WindowServer/Window.cpp @@ -499,6 +499,7 @@ void Window::set_maximized(bool maximized, Optional<Gfx::IntPoint> fixed_point) Core::EventLoop::current().post_event(*this, make<ResizeEvent>(m_rect)); set_default_positioned(false); } + void Window::set_always_on_top(bool always_on_top) { if (m_always_on_top == always_on_top) @@ -510,21 +511,7 @@ void Window::set_always_on_top(bool always_on_top) window_stack().move_always_on_top_windows_to_front(); Compositor::the().invalidate_occlusions(); } -void Window::set_vertically_maximized() -{ - if (m_maximized) - return; - if (!is_resizable() || resize_aspect_ratio().has_value()) - return; - - auto max_rect = WindowManager::the().maximized_window_rect(*this); - auto new_rect = Gfx::IntRect( - Gfx::IntPoint(rect().x(), max_rect.y()), - Gfx::IntSize(rect().width(), max_rect.height())); - set_rect(new_rect); - Core::EventLoop::current().post_event(*this, make<ResizeEvent>(new_rect)); -} void Window::set_resizable(bool resizable) { if (m_resizable == resizable) @@ -1021,6 +1008,26 @@ Gfx::IntRect Window::tiled_rect(Screen* target_screen, WindowTileType tile_type) { screen.width() - location.x(), screen.height() - location.y() }) .translated(screen_location); } + case WindowTileType::VerticallyMaximized: { + Gfx::IntPoint location { + floating_rect().location().x(), + menu_height + }; + return Gfx::IntRect( + location, + { floating_rect().width(), max_height }) + .translated(screen_location); + } + case WindowTileType::HorizontallyMaximized: { + Gfx::IntPoint location { + 0, + floating_rect().location().y() + }; + return Gfx::IntRect( + location, + { screen.width(), floating_rect().height() }) + .translated(screen_location); + } default: VERIFY_NOT_REACHED(); } diff --git a/Userland/Services/WindowServer/Window.h b/Userland/Services/WindowServer/Window.h index 89796a99ca..b595605dcb 100644 --- a/Userland/Services/WindowServer/Window.h +++ b/Userland/Services/WindowServer/Window.h @@ -48,7 +48,9 @@ enum class WindowTileType { TopLeft, TopRight, BottomLeft, - BottomRight + BottomRight, + VerticallyMaximized, + HorizontallyMaximized, }; enum class WindowMenuAction { @@ -111,8 +113,6 @@ public: bool is_always_on_top() const { return m_always_on_top; } void set_always_on_top(bool); - void set_vertically_maximized(); - bool is_fullscreen() const { return m_fullscreen; } void set_fullscreen(bool); diff --git a/Userland/Services/WindowServer/WindowFrame.cpp b/Userland/Services/WindowServer/WindowFrame.cpp index b77bd51a2c..751038f981 100644 --- a/Userland/Services/WindowServer/WindowFrame.cpp +++ b/Userland/Services/WindowServer/WindowFrame.cpp @@ -84,7 +84,18 @@ void WindowFrame::window_was_constructed(Badge<Window>) m_window.handle_window_menu_action(WindowMenuAction::MaximizeOrRestore); }); button->on_middle_click = [&](auto&) { - m_window.set_vertically_maximized(); + auto& window_screen = Screen::closest_to_location(m_window.rect().location()); + if (m_window.tile_type() == WindowTileType::VerticallyMaximized) + m_window.set_untiled(); + else + m_window.set_tiled(&window_screen, WindowTileType::VerticallyMaximized); + }; + button->on_secondary_click = [&](auto&) { + auto& window_screen = Screen::closest_to_location(m_window.rect().location()); + if (m_window.tile_type() == WindowTileType::HorizontallyMaximized) + m_window.set_untiled(); + else + m_window.set_tiled(&window_screen, WindowTileType::HorizontallyMaximized); }; m_maximize_button = button.ptr(); m_buttons.append(move(button)); diff --git a/Userland/Services/WindowServer/WindowManager.cpp b/Userland/Services/WindowServer/WindowManager.cpp index e77452a415..1899b6e60c 100644 --- a/Userland/Services/WindowServer/WindowManager.cpp +++ b/Userland/Services/WindowServer/WindowManager.cpp @@ -825,25 +825,27 @@ bool WindowManager::process_ongoing_window_resize(MouseEvent const& event) if (!m_resize_window) return false; - if (event.type() == Event::MouseUp && event.button() == m_resizing_mouse_button) { - dbgln_if(RESIZE_DEBUG, "[WM] Finish resizing Window({})", m_resize_window); - - if (!m_resize_window->is_tiled() && !m_resize_window->is_maximized()) - m_resize_window->set_floating_rect(m_resize_window->rect()); - + if (event.type() == Event::MouseMove) { const int vertical_maximize_deadzone = 5; auto& cursor_screen = ScreenInput::the().cursor_location_screen(); if (&cursor_screen == &Screen::closest_to_rect(m_resize_window->rect())) { auto desktop_rect = this->desktop_rect(cursor_screen); if (event.y() >= desktop_rect.bottom() - vertical_maximize_deadzone + 1 || event.y() <= desktop_rect.top() + vertical_maximize_deadzone - 1) { - dbgln_if(RESIZE_DEBUG, "Should Maximize vertically"); - m_resize_window->set_vertically_maximized(); + dbgln_if(RESIZE_DEBUG, "Should tile as VerticallyMaximized"); + m_resize_window->set_tiled(&cursor_screen, WindowTileType::VerticallyMaximized); m_resize_window = nullptr; m_geometry_overlay = nullptr; m_resizing_mouse_button = MouseButton::None; return true; } } + } + + if (event.type() == Event::MouseUp && event.button() == m_resizing_mouse_button) { + dbgln_if(RESIZE_DEBUG, "[WM] Finish resizing Window({})", m_resize_window); + + if (!m_resize_window->is_tiled() && !m_resize_window->is_maximized()) + m_resize_window->set_floating_rect(m_resize_window->rect()); Core::EventLoop::current().post_event(*m_resize_window, make<ResizeEvent>(m_resize_window->rect())); m_resize_window->invalidate(true, true); @@ -1646,9 +1648,7 @@ void WindowManager::process_key_event(KeyEvent& event) return; } if (event.key() == Key_Left) { - if (active_input_window->tile_type() == WindowTileType::Left) - return; - if (active_input_window->is_tiled()) { + if (active_input_window->tile_type() == WindowTileType::Left) { active_input_window->set_untiled(); return; } @@ -1658,9 +1658,7 @@ void WindowManager::process_key_event(KeyEvent& event) return; } if (event.key() == Key_Right) { - if (active_input_window->tile_type() == WindowTileType::Right) - return; - if (active_input_window->is_tiled()) { + if (active_input_window->tile_type() == WindowTileType::Right) { active_input_window->set_untiled(); return; } @@ -1671,6 +1669,32 @@ void WindowManager::process_key_event(KeyEvent& event) } } } + + if (event.type() == Event::KeyDown && event.modifiers() == (Mod_Super | Mod_Alt) && active_input_window->type() != WindowType::Desktop) { + if (active_input_window->is_resizable()) { + if (event.key() == Key_Right || event.key() == Key_Left) { + if (active_input_window->tile_type() == WindowTileType::HorizontallyMaximized) { + active_input_window->set_untiled(); + return; + } + if (active_input_window->is_maximized()) + maximize_windows(*active_input_window, false); + active_input_window->set_tiled(nullptr, WindowTileType::HorizontallyMaximized); + return; + } + if (event.key() == Key_Up || event.key() == Key_Down) { + if (active_input_window->tile_type() == WindowTileType::VerticallyMaximized) { + active_input_window->set_untiled(); + return; + } + if (active_input_window->is_maximized()) + maximize_windows(*active_input_window, false); + active_input_window->set_tiled(nullptr, WindowTileType::VerticallyMaximized); + return; + } + } + } + active_input_window->dispatch_event(event); } |