summaryrefslogtreecommitdiff
path: root/Userland/Services
diff options
context:
space:
mode:
authorthankyouverycool <66646555+thankyouverycool@users.noreply.github.com>2022-02-07 13:46:07 -0500
committerAndreas Kling <kling@serenityos.org>2022-02-08 16:37:46 +0100
commitee637b44fbc44d8453a720776a18a413c796a874 (patch)
treea4dcd1222a26b514011371722380c740848e8271 /Userland/Services
parent32be05957a1d000c18364f1fce52b59fcde6ff68 (diff)
downloadserenity-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.
Diffstat (limited to 'Userland/Services')
-rw-r--r--Userland/Services/WindowServer/Window.cpp35
-rw-r--r--Userland/Services/WindowServer/Window.h6
-rw-r--r--Userland/Services/WindowServer/WindowFrame.cpp13
-rw-r--r--Userland/Services/WindowServer/WindowManager.cpp52
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);
}