1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
#include "wayfire/signal-provider.hpp"
#include "wayfire/toplevel-view.hpp"
#include <wayfire/per-output-plugin.hpp>
#include <wayfire/view.hpp>
#include <wayfire/core.hpp>
#include <wayfire/workarea.hpp>
#include <wayfire/window-manager.hpp>
#include <wayfire/signal-definitions.hpp>
class wayfire_place_window : public wf::per_output_plugin_instance_t
{
wf::signal::connection_t<wf::view_mapped_signal> on_view_mapped = [=] (wf::view_mapped_signal *ev)
{
auto toplevel = wf::toplevel_cast(ev->view);
if (!toplevel || toplevel->parent || toplevel->pending_fullscreen() ||
toplevel->pending_tiled_edges() || ev->is_positioned)
{
return;
}
ev->is_positioned = true;
auto workarea = output->workarea->get_workarea();
std::string mode = placement_mode;
if (mode == "cascade")
{
cascade(toplevel, workarea);
} else if (mode == "maximize")
{
maximize(toplevel, workarea);
} else if (mode == "random")
{
random(toplevel, workarea);
} else
{
center(toplevel, workarea);
}
};
wf::signal::connection_t<wf::workarea_changed_signal> workarea_changed_cb = [=] (auto)
{
auto workarea = output->workarea->get_workarea();
if ((cascade_x < workarea.x) ||
(cascade_x > workarea.x + workarea.width))
{
cascade_x = workarea.x;
}
if ((cascade_y < workarea.y) ||
(cascade_y > workarea.y + workarea.height))
{
cascade_y = workarea.y;
}
};
wf::option_wrapper_t<std::string> placement_mode{"place/mode"};
int cascade_x, cascade_y;
public:
void init() override
{
auto workarea = output->workarea->get_workarea();
cascade_x = workarea.x;
cascade_y = workarea.y;
output->connect(&workarea_changed_cb);
output->connect(&on_view_mapped);
}
void cascade(wayfire_toplevel_view & view, wf::geometry_t workarea)
{
wf::geometry_t window = view->get_pending_geometry();
if ((cascade_x + window.width > workarea.x + workarea.width) ||
(cascade_y + window.height > workarea.y + workarea.height))
{
cascade_x = workarea.x;
cascade_y = workarea.y;
}
view->move(cascade_x, cascade_y);
cascade_x += workarea.width * .03;
cascade_y += workarea.height * .03;
}
void random(wayfire_toplevel_view & view, wf::geometry_t workarea)
{
wf::geometry_t window = view->get_pending_geometry();
wf::geometry_t area;
int pos_x, pos_y;
area.x = workarea.x;
area.y = workarea.y;
area.width = workarea.width - window.width;
area.height = workarea.height - window.height;
if ((area.width <= 0) || (area.height <= 0))
{
center(view, workarea);
return;
}
pos_x = rand() % area.width + area.x;
pos_y = rand() % area.height + area.y;
view->move(pos_x, pos_y);
}
void center(wayfire_toplevel_view & view, wf::geometry_t workarea)
{
wf::geometry_t window = view->get_pending_geometry();
window.x = workarea.x + (workarea.width / 2) - (window.width / 2);
window.y = workarea.y + (workarea.height / 2) - (window.height / 2);
view->move(window.x, window.y);
}
void maximize(wayfire_toplevel_view & view, wf::geometry_t workarea)
{
wf::get_core().default_wm->tile_request(view, wf::TILED_EDGES_ALL);
}
};
DECLARE_WAYFIRE_PLUGIN(wf::per_output_plugin_t<wayfire_place_window>);
|