Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 58 additions & 3 deletions plugins/grid/grid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "wayfire/plugin.hpp"
#include "wayfire/signal-definitions.hpp"
#include <wayfire/plugins/common/geometry-animation.hpp>
#include <wayfire/plugins/common/preview-indication.hpp>
#include "wayfire/plugins/grid.hpp"
#include "wayfire/plugins/crossfade.hpp"
#include <wayfire/window-manager.hpp>
Expand Down Expand Up @@ -55,6 +56,13 @@ class wayfire_grid : public wf::plugin_interface_t, public wf::per_output_tracke
std::vector<std::string> slots = {"unused", "bl", "b", "br", "l", "c", "r", "tl", "t", "tr"};
wf::ipc_activator_t bindings[10];
wf::ipc_activator_t restore{"grid/restore"};
wf::option_wrapper_t<int> snap_threshold{"move/snap_threshold"};
wf::option_wrapper_t<int> quarter_snap_threshold{"move/quarter_snap_threshold"};
struct
{
std::shared_ptr<wf::preview_indication_t> preview;
wf::grid::slot_t slot_id = wf::grid::SLOT_NONE;
} slot;

wf::plugin_activation_data_t grab_interface{
.name = "grid",
Expand Down Expand Up @@ -102,13 +110,60 @@ class wayfire_grid : public wf::plugin_interface_t, public wf::per_output_tracke
});
}

wf::get_core().connect(&grid_request_signal_cb);
wf::get_core().connect(&grid_handle_move_signal_cb);
}

wf::signal::connection_t<wf::grid::grid_request_signal> grid_request_signal_cb =
[=] (wf::grid::grid_request_signal *ev)
wf::signal::connection_t<wf::grid::grid_handle_move_signal> grid_handle_move_signal_cb =
[=] (wf::grid::grid_handle_move_signal *ev)
{
ev->carried_out = true;
wf::grid::slot_t new_slot_id = ev->operation == wf::grid::MOVE_OP_CLEAR_PREVIEW ?
wf::grid::slot_t::SLOT_NONE :
wf::grid::calc_slot(ev->output, ev->input, snap_threshold, quarter_snap_threshold);

if ((ev->operation == wf::grid::MOVE_OP_DROP) && new_slot_id)
{
ev->view->toplevel()->pending().tiled_edges = wf::grid::get_tiled_edges_for_slot(new_slot_id);
auto desired_size = wf::grid::get_slot_dimensions(ev->view->get_output(), new_slot_id);
ev->view->get_data_safe<wf_grid_slot_data>()->slot = new_slot_id;
ensure_grid_view(ev->view)->adjust_target_geometry(
adjust_for_workspace(ev->view->get_wset(), desired_size,
ev->view->get_output()->wset()->get_current_workspace()),
ev->view->toplevel()->pending().tiled_edges);
new_slot_id = wf::grid::slot_t::SLOT_NONE;
}

/* No changes in the slot, just return */
if (slot.slot_id == new_slot_id)
{
return;
}

/* Destroy previous preview */
if (slot.preview)
{
auto input = ev->input;
slot.preview->set_target_geometry({input.x, input.y, 1, 1}, 0, true);
slot.preview = nullptr;
}

slot.slot_id = new_slot_id;

/* Show a preview overlay */
if (new_slot_id)
{
wf::geometry_t slot_geometry = wf::grid::get_slot_dimensions(ev->output, new_slot_id);
/* Unknown slot geometry, can't show a preview */
if ((slot_geometry.width <= 0) || (slot_geometry.height <= 0))
{
return;
}

auto input = ev->input;
slot.preview = std::make_shared<wf::preview_indication_t>(
wf::geometry_t{input.x, input.y, 1, 1}, ev->output, "move");
slot.preview->set_target_geometry(slot_geometry, 1);
}
};

void handle_new_output(wf::output_t *output) override
Expand Down
64 changes: 63 additions & 1 deletion plugins/grid/wayfire/plugins/grid.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,28 @@ namespace wf
{
namespace grid
{
enum move_op_t
{
MOVE_OP_CLEAR_PREVIEW = 0,
MOVE_OP_UPDATE_PREVIEW = 1,
MOVE_OP_DROP = 2,
};

/**
* name: request
* on: core
* when: Emitted before move renders a grid indicator and sets the slot.
* carried_out: true if a plugin can handle move request to grid.
*/
struct grid_request_signal
struct grid_handle_move_signal
{
/* True if a plugin handled this signal */
bool carried_out = false;
move_op_t operation;
wf::output_t *output;
/* input coordinates in output-local space */
wf::point_t input;
wayfire_toplevel_view view;
};

/**
Expand Down Expand Up @@ -118,5 +130,55 @@ inline wf::geometry_t get_slot_dimensions(wf::output_t *output, int n)

return area;
}

/* Calculate the slot to which the view would be snapped if the input
* is released at output-local coordinates (x, y) */
inline wf::grid::slot_t calc_slot(wf::output_t *output, wf::point_t point, int snap_threshold,
int quarter_snap_threshold)
{
auto g = output->workarea->get_workarea();

int threshold = snap_threshold;

bool is_left = point.x - g.x <= threshold;
bool is_right = g.x + g.width - point.x <= threshold;
bool is_top = point.y - g.y < threshold;
bool is_bottom = g.x + g.height - point.y < threshold;

bool is_far_left = point.x - g.x <= quarter_snap_threshold;
bool is_far_right = g.x + g.width - point.x <= quarter_snap_threshold;
bool is_far_top = point.y - g.y < quarter_snap_threshold;
bool is_far_bottom = g.x + g.height - point.y < quarter_snap_threshold;

wf::grid::slot_t slot = wf::grid::SLOT_NONE;
if ((is_left && is_far_top) || (is_far_left && is_top))
{
slot = wf::grid::SLOT_TL;
} else if ((is_right && is_far_top) || (is_far_right && is_top))
{
slot = wf::grid::SLOT_TR;
} else if ((is_right && is_far_bottom) || (is_far_right && is_bottom))
{
slot = wf::grid::SLOT_BR;
} else if ((is_left && is_far_bottom) || (is_far_left && is_bottom))
{
slot = wf::grid::SLOT_BL;
} else if (is_right)
{
slot = wf::grid::SLOT_RIGHT;
} else if (is_left)
{
slot = wf::grid::SLOT_LEFT;
} else if (is_top)
{
// Maximize when dragging to the top
slot = wf::grid::SLOT_CENTER;
} else if (is_bottom)
{
slot = wf::grid::SLOT_BOTTOM;
}

return slot;
}
}
}
Loading