diff --git a/src/miracle_window_management_policy.cpp b/src/miracle_window_management_policy.cpp
index 217281a..6752fb9 100644
--- a/src/miracle_window_management_policy.cpp
+++ b/src/miracle_window_management_policy.cpp
@@ -135,9 +135,7 @@ auto MiracleWindowManagementPolicy::place_new_window(
void MiracleWindowManagementPolicy::handle_window_ready(miral::WindowInfo &window_info)
{
- // The new placement has been confirmed. We can now add the window into the pending position
- // in the tree. This comes _after_ place_new_window has been called.
- tree.confirm(window_info.window());
+ tree.confirm_new_window(window_info.window());
}
void MiracleWindowManagementPolicy::advise_focus_gained(const miral::WindowInfo &window_info)
diff --git a/src/protocols/xdg-shell-unstable-v6.xml b/src/protocols/xdg-shell-unstable-v6.xml
index cf5ddc3..ea12f79 100644
--- a/src/protocols/xdg-shell-unstable-v6.xml
+++ b/src/protocols/xdg-shell-unstable-v6.xml
@@ -721,7 +721,7 @@
Client window decorations should be painted as if the window is
- active_lane. Do not assume this means that the window actually has
+ get_active_lane. Do not assume this means that the window actually has
keyboard or pointer focus.
@@ -1013,7 +1013,7 @@
will follow the same dismissing order as required from the client.
The parent of a grabbing popup must either be another xdg_popup with an
- active_lane explicit grab, or an xdg_popup or xdg_toplevel, if there are no
+ get_active_lane explicit grab, or an xdg_popup or xdg_toplevel, if there are no
explicit grabs already taken.
If the topmost grabbing popup is destroyed, the grab will be returned to
diff --git a/src/window_tree.cpp b/src/window_tree.cpp
index d29e7bf..36ee72d 100644
--- a/src/window_tree.cpp
+++ b/src/window_tree.cpp
@@ -32,17 +32,17 @@ WindowTree::WindowTree(geom::Size default_size, const miral::WindowManagerTools
miral::WindowSpecification WindowTree::allocate_position(const miral::WindowSpecification &requested_specification)
{
miral::WindowSpecification new_spec = requested_specification;
- auto rect = active_lane()->new_node_position();
+ auto rect = get_active_lane()->new_node_position();
new_spec.size() = rect.size;
new_spec.top_left() = rect.top_left;
return new_spec;
}
-void WindowTree::confirm(miral::Window &window)
+void WindowTree::confirm_new_window(miral::Window &window)
{
- active_lane()->add_node(std::make_shared(
+ get_active_lane()->add_node(std::make_shared(
geom::Rectangle{window.top_left(), window.size()},
- active_lane(),
+ get_active_lane(),
window));
tools.select_active_window(window);
}
@@ -67,76 +67,10 @@ bool WindowTree::try_resize_active_window(miracle::Direction direction)
return false;
// TODO: We have a hardcoded resize amount
- resize_node_internal(active_window, direction, 50);
+ resize_node_in_direction(active_window, direction, 50);
return true;
}
-void WindowTree::resize_node_internal(
- std::shared_ptr node,
- Direction direction,
- int amount)
-{
- auto parent = node->parent;
- if (parent == nullptr)
- {
- // Can't resize, most likely the root
- return;
- }
-
- bool is_vertical = direction == Direction::up || direction == Direction::down;
- bool is_main_axis_movement = (is_vertical && parent->get_direction() == NodeLayoutDirection::vertical)
- || (!is_vertical && parent->get_direction() == NodeLayoutDirection::horizontal);
- if (!is_main_axis_movement)
- {
- resize_node_internal(parent, direction, amount);
- return;
- }
-
- bool is_negative = direction == Direction::left || direction == Direction::up;
- auto resize_amount = is_negative ? -amount : amount;
- auto nodes = parent->get_sub_nodes();
- if (is_vertical)
- {
- int height_for_others = floor(-resize_amount / static_cast(nodes.size() - 1));
- for (size_t i = 0; i < nodes.size(); i++)
- {
- auto other_node = nodes[i];
- auto other_rect = other_node->get_rectangle();
- if (node == other_node)
- other_rect.size.height = geom::Height{other_rect.size.height.as_int() + resize_amount};
- else
- other_rect.size.height = geom::Height{other_rect.size.height.as_int() + height_for_others};
-
- if (i != 0)
- {
- auto prev_rect = nodes[i - 1]->get_rectangle();
- other_rect.top_left.y = geom::Y{prev_rect.top_left.y.as_int() + prev_rect.size.height.as_int()};
- }
- other_node->set_rectangle(other_rect);
- }
- }
- else
- {
- int width_for_others = floor(-resize_amount / static_cast(nodes.size() - 1));
- for (size_t i = 0; i < nodes.size(); i++)
- {
- auto other_node = nodes[i];
- auto other_rect = other_node->get_rectangle();
- if (node == other_node)
- other_rect.size.width = geom::Width {other_rect.size.width.as_int() + resize_amount};
- else
- other_rect.size.width = geom::Width {other_rect.size.width.as_int() + width_for_others};
-
- if (i != 0)
- {
- auto prev_rect = nodes[i - 1]->get_rectangle();
- other_rect.top_left.x = geom::X{prev_rect.top_left.x.as_int() + prev_rect.size.width.as_int()};
- }
- other_node->set_rectangle(other_rect);
- }
- }
-}
-
bool WindowTree::try_select_next(miracle::Direction direction)
{
if (!active_window)
@@ -149,9 +83,10 @@ bool WindowTree::try_select_next(miracle::Direction direction)
return true;
}
-void WindowTree::resize(geom::Size new_size)
+void WindowTree::resize_display(geom::Size new_size)
{
size = new_size;
+ root_lane->redistribute_size();
// TODO: Resize all windows
}
@@ -198,7 +133,7 @@ void WindowTree::handle_direction_request(NodeLayoutDirection direction)
if (active_window->parent->get_sub_nodes().size() != 1)
active_window = active_window->to_lane();
- active_lane()->set_direction(direction);
+ get_active_lane()->set_direction(direction);
}
void WindowTree::advise_focus_gained(miral::Window& window)
@@ -220,7 +155,7 @@ void WindowTree::advise_focus_lost(miral::Window&)
void WindowTree::advise_delete_window(miral::Window& window)
{
// Resize the other nodes in the lane accordingly
- auto parent = active_lane();
+ auto parent = get_active_lane();
if (parent->get_sub_nodes().size() == 1)
{
@@ -333,10 +268,76 @@ grandparent_route:
return nullptr;
}
-std::shared_ptr WindowTree::active_lane()
+std::shared_ptr WindowTree::get_active_lane()
{
if (!active_window)
return root_lane;
return active_window->parent;
+}
+
+void WindowTree::resize_node_in_direction(
+ std::shared_ptr node,
+ Direction direction,
+ int amount)
+{
+ auto parent = node->parent;
+ if (parent == nullptr)
+ {
+ // Can't resize, most likely the root
+ return;
+ }
+
+ bool is_vertical = direction == Direction::up || direction == Direction::down;
+ bool is_main_axis_movement = (is_vertical && parent->get_direction() == NodeLayoutDirection::vertical)
+ || (!is_vertical && parent->get_direction() == NodeLayoutDirection::horizontal);
+ if (!is_main_axis_movement)
+ {
+ resize_node_in_direction(parent, direction, amount);
+ return;
+ }
+
+ bool is_negative = direction == Direction::left || direction == Direction::up;
+ auto resize_amount = is_negative ? -amount : amount;
+ auto nodes = parent->get_sub_nodes();
+ if (is_vertical)
+ {
+ int height_for_others = floor(-resize_amount / static_cast(nodes.size() - 1));
+ for (size_t i = 0; i < nodes.size(); i++)
+ {
+ auto other_node = nodes[i];
+ auto other_rect = other_node->get_rectangle();
+ if (node == other_node)
+ other_rect.size.height = geom::Height{other_rect.size.height.as_int() + resize_amount};
+ else
+ other_rect.size.height = geom::Height{other_rect.size.height.as_int() + height_for_others};
+
+ if (i != 0)
+ {
+ auto prev_rect = nodes[i - 1]->get_rectangle();
+ other_rect.top_left.y = geom::Y{prev_rect.top_left.y.as_int() + prev_rect.size.height.as_int()};
+ }
+ other_node->set_rectangle(other_rect);
+ }
+ }
+ else
+ {
+ int width_for_others = floor(-resize_amount / static_cast(nodes.size() - 1));
+ for (size_t i = 0; i < nodes.size(); i++)
+ {
+ auto other_node = nodes[i];
+ auto other_rect = other_node->get_rectangle();
+ if (node == other_node)
+ other_rect.size.width = geom::Width {other_rect.size.width.as_int() + resize_amount};
+ else
+ other_rect.size.width = geom::Width {other_rect.size.width.as_int() + width_for_others};
+
+ if (i != 0)
+ {
+ auto prev_rect = nodes[i - 1]->get_rectangle();
+ other_rect.top_left.x = geom::X{prev_rect.top_left.x.as_int() + prev_rect.size.width.as_int()};
+ }
+ other_node->set_rectangle(other_rect);
+ }
+ }
}
\ No newline at end of file
diff --git a/src/window_tree.h b/src/window_tree.h
index 7bdd55e..8e2228b 100644
--- a/src/window_tree.h
+++ b/src/window_tree.h
@@ -51,16 +51,18 @@ public:
miral::WindowSpecification allocate_position(const miral::WindowSpecification &requested_specification);
/// Confirms the position of this window in the previously allocated position.
- void confirm(miral::Window&);
+ void confirm_new_window(miral::Window&);
/// Places us into resize mode. Other operations are prohibited while we are in resize mode.
void toggle_resize_mode();
/// Try to resize the current active window in the provided direction
bool try_resize_active_window(Direction direction);
- void resize(geom::Size new_size);
+ /// Move the active window in the provided direction
bool try_move_active_window(Direction direction);
+
+ /// Select the next window in the provided direction
bool try_select_next(Direction direction);
// Request a change to vertical window placement
@@ -69,10 +71,18 @@ public:
// Request a change to horizontal window placement
void request_horizontal();
+ /// Advises us to focus the provided window.
void advise_focus_gained(miral::Window&);
+
+ /// Advises us to lose focus on the provided window.
void advise_focus_lost(miral::Window&);
+
+ /// Called when the window was deleted.
void advise_delete_window(miral::Window&);
+ /// Called when the physical display is resized.
+ void resize_display(geom::Size new_size);
+
private:
miral::WindowManagerTools tools;
std::shared_ptr root_lane;
@@ -80,9 +90,9 @@ private:
geom::Size size;
bool is_resizing = false;
- std::shared_ptr active_lane();
+ std::shared_ptr get_active_lane();
void handle_direction_request(NodeLayoutDirection direction);
- void resize_node_internal(std::shared_ptr node, Direction direction, int amount);
+ void resize_node_in_direction(std::shared_ptr node, Direction direction, int amount);
/// From the provided node, find the next node in the provided direction.
/// This method is guaranteed to return a Window node, not a Lane.
std::shared_ptr traverse(std::shared_ptr from, Direction direction);