mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 20:37:35 +00:00
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.
This commit is contained in:
parent
4ec77ba929
commit
503aebaefc
3 changed files with 64 additions and 14 deletions
|
@ -598,19 +598,53 @@ void Window::set_fullscreen(bool fullscreen)
|
||||||
Gfx::IntRect Window::tiled_rect(WindowTileType tiled) const
|
Gfx::IntRect Window::tiled_rect(WindowTileType tiled) const
|
||||||
{
|
{
|
||||||
int frame_width = (m_frame.rect().width() - m_rect.width()) / 2;
|
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) {
|
switch (tiled) {
|
||||||
case WindowTileType::None:
|
case WindowTileType::None:
|
||||||
return m_untiled_rect;
|
return m_untiled_rect;
|
||||||
case WindowTileType::Left:
|
case WindowTileType::Left:
|
||||||
return Gfx::IntRect(0,
|
return Gfx::IntRect(0,
|
||||||
WindowManager::the().maximized_window_rect(*this).y(),
|
menu_height,
|
||||||
Screen::the().width() / 2 - frame_width,
|
Screen::the().width() / 2 - frame_width,
|
||||||
WindowManager::the().maximized_window_rect(*this).height());
|
max_height);
|
||||||
case WindowTileType::Right:
|
case WindowTileType::Right:
|
||||||
return Gfx::IntRect(Screen::the().width() / 2 + frame_width,
|
return Gfx::IntRect(Screen::the().width() / 2 + frame_width,
|
||||||
WindowManager::the().maximized_window_rect(*this).y(),
|
menu_height,
|
||||||
Screen::the().width() / 2 - frame_width,
|
Screen::the().width() / 2 - frame_width,
|
||||||
WindowManager::the().maximized_window_rect(*this).height());
|
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,
|
||||||
|
(max_height - title_bar_height) / 2);
|
||||||
default:
|
default:
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,12 @@ enum class WindowTileType {
|
||||||
None = 0,
|
None = 0,
|
||||||
Left,
|
Left,
|
||||||
Right,
|
Right,
|
||||||
|
Top,
|
||||||
|
Bottom,
|
||||||
|
TopLeft,
|
||||||
|
TopRight,
|
||||||
|
BottomLeft,
|
||||||
|
BottomRight
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class PopupMenuItem {
|
enum class PopupMenuItem {
|
||||||
|
|
|
@ -528,7 +528,8 @@ bool WindowManager::process_ongoing_window_move(MouseEvent& event, Window*& hove
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const int maximization_deadzone = 2;
|
const int tiling_deadzone = 10;
|
||||||
|
const int secondary_deadzone = 2;
|
||||||
|
|
||||||
if (m_move_window->is_maximized()) {
|
if (m_move_window->is_maximized()) {
|
||||||
auto pixels_moved_from_start = event.position().pixels_moved(m_move_origin);
|
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) {
|
if (pixels_moved_from_start > 5) {
|
||||||
// dbg() << "[WM] de-maximizing window";
|
// dbg() << "[WM] de-maximizing window";
|
||||||
m_move_origin = event.position();
|
m_move_origin = event.position();
|
||||||
if (m_move_origin.y() <= maximization_deadzone)
|
if (m_move_origin.y() <= secondary_deadzone)
|
||||||
return true;
|
return true;
|
||||||
auto width_before_resize = m_move_window->width();
|
auto width_before_resize = m_move_window->width();
|
||||||
m_move_window->set_maximized(false);
|
m_move_window->set_maximized(false);
|
||||||
|
@ -546,17 +547,26 @@ bool WindowManager::process_ongoing_window_move(MouseEvent& event, Window*& hove
|
||||||
} else {
|
} else {
|
||||||
bool is_resizable = m_move_window->is_resizable();
|
bool is_resizable = m_move_window->is_resizable();
|
||||||
auto pixels_moved_from_start = event.position().pixels_moved(m_move_origin);
|
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) {
|
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) {
|
} 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) {
|
} else if (pixels_moved_from_start > 5 || m_move_window->tiled() == WindowTileType::None) {
|
||||||
m_move_window->set_tiled(WindowTileType::None);
|
m_move_window->set_tiled(WindowTileType::None);
|
||||||
Gfx::IntPoint pos = m_move_window_origin.translated(event.position() - m_move_origin);
|
Gfx::IntPoint pos = m_move_window_origin.translated(event.position() - m_move_origin);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue