Skip to content

Commit

Permalink
Change placement of new floating windows
Browse files Browse the repository at this point in the history
  • Loading branch information
hbatagelo committed Jan 12, 2024
1 parent a632621 commit ff77f3f
Showing 1 changed file with 86 additions and 0 deletions.
86 changes: 86 additions & 0 deletions src/miral/basic_window_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
#include <boost/throw_exception.hpp>

#include <algorithm>
#include <random>
#include <unordered_set>

using namespace mir;
using namespace mir::geometry;
Expand Down Expand Up @@ -2016,6 +2018,90 @@ auto miral::BasicWindowManager::place_new_surface(WindowSpecification parameters

if (parameters.top_left().value().y < display_area.top_left.y)
parameters.top_left() = Point{parameters.top_left().value().x, display_area.top_left.y};

if (parameters.state() == mir_window_state_restored)
{
Displacement const cascading_offset{48, 48};
Displacement const position_tolerance{12, 12};

auto unique_window_positions{[&]()
{
struct PointHash
{
std::size_t operator() (Point const& point) const
{
std::size_t seed{};
boost::hash_combine(seed, point.x.as_value());
boost::hash_combine(seed, point.y.as_value());
return seed;
}
};
std::unordered_set<Point, PointHash> unique_positions;
for_each_application([&](ApplicationInfo& info)
{
for (auto const& window : info.windows())
{
unique_positions.insert(window.top_left());
}
});
return unique_positions;
}()};

auto const find_near_window_position{[&](Point const& point, Displacement const& tolerance)
{
return std::find_if(
unique_window_positions.begin(),
unique_window_positions.end(),
[&](auto const& it)
{
return std::abs(it.x.as_value() - point.x.as_value()) <= tolerance.dx.as_value() &&
std::abs(it.y.as_value() - point.y.as_value()) <= tolerance.dy.as_value();
});
}};

auto new_position{parameters.top_left().value()};

auto near_window_position{find_near_window_position(new_position, position_tolerance)};
while (near_window_position != unique_window_positions.end())
{
unique_window_positions.erase(near_window_position);
new_position += cascading_offset;
near_window_position = find_near_window_position(new_position, position_tolerance);
}

if (!display_area.contains(new_position + as_displacement(parameters.size().value())))
{
Rectangle const placement_region{
display_area.top_left,
as_size(display_area.bottom_right() -
as_displacement(parameters.size().value()) -
as_displacement(display_area.top_left) + Displacement{1, 1})};
if (placement_region.size.width.as_value() > 0 && placement_region.size.height.as_value() > 0)
{
std::random_device rd;
std::default_random_engine gen(rd());
std::uniform_int_distribution<int> dist_x(0, placement_region.size.width.as_value() - 1);
std::uniform_int_distribution<int> dist_y(0, placement_region.size.height.as_value() - 1);
new_position = placement_region.top_left + as_displacement(Point{dist_x(gen), dist_y(gen)});
}
else
{
if(placement_region.size.width.as_value() <= 0)
{
new_position = Point{display_area.left(), new_position.y};
parameters.size().value().width = display_area.size.width;
}
if(placement_region.size.height.as_value() <= 0)
{
new_position = Point{new_position.x, display_area.top()};
parameters.size().value().height = display_area.size.height;
}
}

}

parameters.top_left() = new_position;
}
}

return parameters;
Expand Down

0 comments on commit ff77f3f

Please sign in to comment.