mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 08:37:45 +00:00
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.
This commit is contained in:
parent
32be05957a
commit
ee637b44fb
4 changed files with 74 additions and 32 deletions
|
@ -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));
|
Core::EventLoop::current().post_event(*this, make<ResizeEvent>(m_rect));
|
||||||
set_default_positioned(false);
|
set_default_positioned(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::set_always_on_top(bool always_on_top)
|
void Window::set_always_on_top(bool always_on_top)
|
||||||
{
|
{
|
||||||
if (m_always_on_top == 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();
|
window_stack().move_always_on_top_windows_to_front();
|
||||||
Compositor::the().invalidate_occlusions();
|
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)
|
void Window::set_resizable(bool resizable)
|
||||||
{
|
{
|
||||||
if (m_resizable == 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() })
|
{ screen.width() - location.x(), screen.height() - location.y() })
|
||||||
.translated(screen_location);
|
.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:
|
default:
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,9 @@ enum class WindowTileType {
|
||||||
TopLeft,
|
TopLeft,
|
||||||
TopRight,
|
TopRight,
|
||||||
BottomLeft,
|
BottomLeft,
|
||||||
BottomRight
|
BottomRight,
|
||||||
|
VerticallyMaximized,
|
||||||
|
HorizontallyMaximized,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class WindowMenuAction {
|
enum class WindowMenuAction {
|
||||||
|
@ -111,8 +113,6 @@ public:
|
||||||
bool is_always_on_top() const { return m_always_on_top; }
|
bool is_always_on_top() const { return m_always_on_top; }
|
||||||
void set_always_on_top(bool);
|
void set_always_on_top(bool);
|
||||||
|
|
||||||
void set_vertically_maximized();
|
|
||||||
|
|
||||||
bool is_fullscreen() const { return m_fullscreen; }
|
bool is_fullscreen() const { return m_fullscreen; }
|
||||||
void set_fullscreen(bool);
|
void set_fullscreen(bool);
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,18 @@ void WindowFrame::window_was_constructed(Badge<Window>)
|
||||||
m_window.handle_window_menu_action(WindowMenuAction::MaximizeOrRestore);
|
m_window.handle_window_menu_action(WindowMenuAction::MaximizeOrRestore);
|
||||||
});
|
});
|
||||||
button->on_middle_click = [&](auto&) {
|
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_maximize_button = button.ptr();
|
||||||
m_buttons.append(move(button));
|
m_buttons.append(move(button));
|
||||||
|
|
|
@ -825,25 +825,27 @@ bool WindowManager::process_ongoing_window_resize(MouseEvent const& event)
|
||||||
if (!m_resize_window)
|
if (!m_resize_window)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (event.type() == Event::MouseUp && event.button() == m_resizing_mouse_button) {
|
if (event.type() == Event::MouseMove) {
|
||||||
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());
|
|
||||||
|
|
||||||
const int vertical_maximize_deadzone = 5;
|
const int vertical_maximize_deadzone = 5;
|
||||||
auto& cursor_screen = ScreenInput::the().cursor_location_screen();
|
auto& cursor_screen = ScreenInput::the().cursor_location_screen();
|
||||||
if (&cursor_screen == &Screen::closest_to_rect(m_resize_window->rect())) {
|
if (&cursor_screen == &Screen::closest_to_rect(m_resize_window->rect())) {
|
||||||
auto desktop_rect = this->desktop_rect(cursor_screen);
|
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) {
|
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");
|
dbgln_if(RESIZE_DEBUG, "Should tile as VerticallyMaximized");
|
||||||
m_resize_window->set_vertically_maximized();
|
m_resize_window->set_tiled(&cursor_screen, WindowTileType::VerticallyMaximized);
|
||||||
m_resize_window = nullptr;
|
m_resize_window = nullptr;
|
||||||
m_geometry_overlay = nullptr;
|
m_geometry_overlay = nullptr;
|
||||||
m_resizing_mouse_button = MouseButton::None;
|
m_resizing_mouse_button = MouseButton::None;
|
||||||
return true;
|
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()));
|
Core::EventLoop::current().post_event(*m_resize_window, make<ResizeEvent>(m_resize_window->rect()));
|
||||||
m_resize_window->invalidate(true, true);
|
m_resize_window->invalidate(true, true);
|
||||||
|
@ -1646,9 +1648,7 @@ void WindowManager::process_key_event(KeyEvent& event)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (event.key() == Key_Left) {
|
if (event.key() == Key_Left) {
|
||||||
if (active_input_window->tile_type() == WindowTileType::Left)
|
if (active_input_window->tile_type() == WindowTileType::Left) {
|
||||||
return;
|
|
||||||
if (active_input_window->is_tiled()) {
|
|
||||||
active_input_window->set_untiled();
|
active_input_window->set_untiled();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1658,9 +1658,7 @@ void WindowManager::process_key_event(KeyEvent& event)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (event.key() == Key_Right) {
|
if (event.key() == Key_Right) {
|
||||||
if (active_input_window->tile_type() == WindowTileType::Right)
|
if (active_input_window->tile_type() == WindowTileType::Right) {
|
||||||
return;
|
|
||||||
if (active_input_window->is_tiled()) {
|
|
||||||
active_input_window->set_untiled();
|
active_input_window->set_untiled();
|
||||||
return;
|
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);
|
active_input_window->dispatch_event(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue