Skip to content

Commit

Permalink
feature: exclusion zones are working to an extent
Browse files Browse the repository at this point in the history
  • Loading branch information
mattkae committed Dec 28, 2023
1 parent a979277 commit 23ef5cb
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 11 deletions.
50 changes: 43 additions & 7 deletions src/miracle_window_management_policy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <mir_toolkit/events/enums.h>
#include <miral/toolkit_event.h>
#include <miral/application_info.h>
#include <miral/zone.h>
#include <mir/log.h>
#include <linux/input.h>
#include <iostream>
Expand All @@ -24,11 +25,13 @@ const int MODIFIER_MASK =

const std::string TERMINAL = "konsole";

auto pointer_position(MirPointerEvent const* event) -> mir::geometry::Point
template <typename T>
bool is_tileable(T& requested_specification)
{
return {
miral::toolkit::mir_pointer_event_axis_value(event, mir_pointer_axis_x),
miral::toolkit::mir_pointer_event_axis_value(event, mir_pointer_axis_y)};
return (requested_specification.type() == mir_window_type_normal || requested_specification.type() == mir_window_type_freestyle)
&& !requested_specification.parent()
&& (requested_specification.state() == mir_window_state_restored || requested_specification.state() == mir_window_state_maximized)
&& !requested_specification.exclusive_rect().is_set();
}
}

Expand Down Expand Up @@ -145,13 +148,28 @@ auto MiracleWindowManagementPolicy::place_new_window(
const miral::ApplicationInfo &app_info,
const miral::WindowSpecification &requested_specification) -> miral::WindowSpecification
{
// In this step, we'll ask the WindowTree where we should place the window on the display
// We will also resize the adjacent windows accordingly in this step.
return active_tree->tree.allocate_position(requested_specification);
if (is_tileable(requested_specification))
{
// In this step, we'll ask the WindowTree where we should place the window on the display
// We will also resize the adjacent windows accordingly in this step.
return active_tree->tree.allocate_position(requested_specification);
}

return requested_specification;
}

void MiracleWindowManagementPolicy::advise_new_window(const miral::WindowInfo &window_info)
{

}

void MiracleWindowManagementPolicy::handle_window_ready(miral::WindowInfo &window_info)
{
if (!is_tileable(window_info))
{
return;
}

miral::WindowSpecification mods;
constrain_window(mods, window_info);
window_manager_tools.modify_window(window_info.window(), mods);
Expand Down Expand Up @@ -306,3 +324,21 @@ void MiracleWindowManagementPolicy::constrain_window(miral::WindowSpecification&
set_if_needed(mods.max_width(), window_info.max_width(), geom::Width{std::numeric_limits<int>::max()});
set_if_needed(mods.max_height(), window_info.max_height(), geom::Height{std::numeric_limits<int>::max()});
}

void MiracleWindowManagementPolicy::advise_application_zone_create(miral::Zone const& application_zone)
{
for (auto tree : tree_list)
tree->tree.advise_application_zone_create(application_zone);
}

void MiracleWindowManagementPolicy::advise_application_zone_update(miral::Zone const& updated, miral::Zone const& original)
{
for (auto tree : tree_list)
tree->tree.advise_application_zone_update(updated, original);
}

void MiracleWindowManagementPolicy::advise_application_zone_delete(miral::Zone const& application_zone)
{
for (auto tree : tree_list)
tree->tree.advise_application_zone_delete(application_zone);
}
5 changes: 5 additions & 0 deletions src/miracle_window_management_policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class MiracleWindowManagementPolicy : public miral::WindowManagementPolicy
auto place_new_window(
miral::ApplicationInfo const& app_info,
miral::WindowSpecification const& requested_specification) -> miral::WindowSpecification override;
void advise_new_window(miral::WindowInfo const& window_info) override;
void handle_window_ready(
miral::WindowInfo& window_info) override;
void advise_focus_gained(miral::WindowInfo const& window_info) override;
Expand Down Expand Up @@ -67,6 +68,10 @@ class MiracleWindowManagementPolicy : public miral::WindowManagementPolicy
const miral::WindowInfo &window_info,
mir::geometry::Displacement movement) -> mir::geometry::Rectangle override;

void advise_application_zone_create(miral::Zone const& application_zone) override;
void advise_application_zone_update(miral::Zone const& updated, miral::Zone const& original) override;
void advise_application_zone_delete(miral::Zone const& application_zone) override;

private:
std::shared_ptr<OutputTreePair> active_tree;
std::vector<std::shared_ptr<OutputTreePair>> tree_list;
Expand Down
45 changes: 41 additions & 4 deletions src/window_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,15 +87,16 @@ void WindowTree::set_output_area(geom::Rectangle new_area)
{
double x_scale = static_cast<double>(new_area.size.width.as_int()) / static_cast<double>(area.size.width.as_int());
double y_scale = static_cast<double>(new_area.size.height.as_int()) / static_cast<double>(area.size.height.as_int());
root_lane->scale_area(x_scale, y_scale);

int position_diff_x = new_area.top_left.x.as_int() - area.top_left.x.as_int();
int position_diff_y = new_area.top_left.y.as_int() - area.top_left.y.as_int();
area.top_left = new_area.top_left;
area.size = geom::Size{
geom::Width{ceil(area.size.width.as_int() * x_scale)},
geom::Height {ceil(area.size.height.as_int() * y_scale)}};

int position_diff_x = new_area.top_left.x.as_int() - area.top_left.x.as_int();
int position_diff_y = new_area.top_left.y.as_int() - area.top_left.y.as_int();
root_lane->scale_area(x_scale, y_scale);
root_lane->translate_by(position_diff_x, position_diff_y);
area.top_left = new_area.top_left;
}

bool WindowTree::point_is_in_output(int x, int y)
Expand Down Expand Up @@ -184,6 +185,7 @@ void WindowTree::advise_focus_lost(miral::Window&)

void WindowTree::advise_delete_window(miral::Window& window)
{
// TODO: This is an algorithm that is prone to breaking
// Resize the other nodes in the lane accordingly
auto window_node = root_lane->find_node_for_window(window);
if (!window_node)
Expand Down Expand Up @@ -420,3 +422,38 @@ void WindowTree::resize_node_in_direction(
}
}
}

void WindowTree::advise_application_zone_create(miral::Zone const& application_zone)
{
application_zone_list.push_back(application_zone);
recalculate_root_node_area();
}

void WindowTree::advise_application_zone_update(miral::Zone const& updated, miral::Zone const& original)
{
for (auto& zone : application_zone_list)
if (zone == original)
{
zone = updated;
recalculate_root_node_area();
break;
}
}

void WindowTree::advise_application_zone_delete(miral::Zone const& application_zone)
{
std::remove(application_zone_list.begin(), application_zone_list.end(), application_zone);
recalculate_root_node_area();
}

void WindowTree::recalculate_root_node_area()
{
// TODO: We don't take care of multiple application zones, so maybe that has to do with multiple outputs?
for (auto const& zone : application_zone_list)
{
root_lane->set_rectangle(zone.extents());
break;
}


}
7 changes: 7 additions & 0 deletions src/window_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <mir/geometry/rectangle.h>
#include <mir/geometry/rectangle.h>
#include <miral/window_manager_tools.h>
#include <miral/zone.h>

namespace geom = mir::geometry;

Expand Down Expand Up @@ -78,20 +79,26 @@ class WindowTree

bool select_window_from_point(int x, int y);

void advise_application_zone_create(miral::Zone const& application_zone);
void advise_application_zone_update(miral::Zone const& updated, miral::Zone const& original);
void advise_application_zone_delete(miral::Zone const& application_zone);

private:
miral::WindowManagerTools tools;
WindowTreeOptions options;
std::shared_ptr<Node> root_lane;
std::shared_ptr<Node> active_window;
geom::Rectangle area;
bool is_resizing = false;
std::vector<miral::Zone> application_zone_list;

std::shared_ptr<Node> get_active_lane();
void handle_direction_request(NodeLayoutDirection direction);
void resize_node_in_direction(std::shared_ptr<Node> 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<Node> traverse(std::shared_ptr<Node> from, Direction direction);
void recalculate_root_node_area();
};

}
Expand Down

0 comments on commit 23ef5cb

Please sign in to comment.