|
|
|
@ -2,7 +2,6 @@
|
|
|
|
|
#include <limits.h>
|
|
|
|
|
#include <wlr/types/wlr_cursor.h>
|
|
|
|
|
#include <wlr/util/edges.h>
|
|
|
|
|
#include "sway/desktop.h"
|
|
|
|
|
#include "sway/desktop/transaction.h"
|
|
|
|
|
#include "sway/input/cursor.h"
|
|
|
|
|
#include "sway/input/seat.h"
|
|
|
|
@ -24,28 +23,17 @@ struct seatop_move_tiling_event {
|
|
|
|
|
struct sway_container *con;
|
|
|
|
|
struct sway_node *target_node;
|
|
|
|
|
enum wlr_edges target_edge;
|
|
|
|
|
struct wlr_box drop_box;
|
|
|
|
|
double ref_lx, ref_ly; // cursor's x/y at start of op
|
|
|
|
|
bool threshold_reached;
|
|
|
|
|
bool split_target;
|
|
|
|
|
bool insert_after_target;
|
|
|
|
|
struct wlr_scene_rect *indicator_rect;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void handle_render(struct sway_seat *seat, struct render_context *ctx) {
|
|
|
|
|
static void handle_end(struct sway_seat *seat) {
|
|
|
|
|
struct seatop_move_tiling_event *e = seat->seatop_data;
|
|
|
|
|
if (!e->threshold_reached) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (e->target_node && node_get_output(e->target_node) == ctx->output) {
|
|
|
|
|
float color[4];
|
|
|
|
|
memcpy(&color, config->border_colors.focused.indicator,
|
|
|
|
|
sizeof(float) * 4);
|
|
|
|
|
premultiply_alpha(color, 0.5);
|
|
|
|
|
struct wlr_box box;
|
|
|
|
|
memcpy(&box, &e->drop_box, sizeof(struct wlr_box));
|
|
|
|
|
scale_box(&box, ctx->output->wlr_output->scale);
|
|
|
|
|
render_rect(ctx, &box, color);
|
|
|
|
|
}
|
|
|
|
|
wlr_scene_node_destroy(&e->indicator_rect->node);
|
|
|
|
|
e->indicator_rect = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void handle_motion_prethreshold(struct sway_seat *seat) {
|
|
|
|
@ -66,6 +54,7 @@ static void handle_motion_prethreshold(struct sway_seat *seat) {
|
|
|
|
|
|
|
|
|
|
// If the threshold has been exceeded, start the actual drag
|
|
|
|
|
if ((cx - sx) * (cx - sx) + (cy - sy) * (cy - sy) > threshold) {
|
|
|
|
|
wlr_scene_node_set_enabled(&e->indicator_rect->node, true);
|
|
|
|
|
e->threshold_reached = true;
|
|
|
|
|
cursor_set_image(seat->cursor, "grab", NULL);
|
|
|
|
|
}
|
|
|
|
@ -164,6 +153,11 @@ static bool split_titlebar(struct sway_node *node, struct sway_container *avoid,
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void update_indicator(struct seatop_move_tiling_event *e, struct wlr_box *box) {
|
|
|
|
|
wlr_scene_node_set_position(&e->indicator_rect->node, box->x, box->y);
|
|
|
|
|
wlr_scene_rect_set_size(e->indicator_rect, box->width, box->height);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void handle_motion_postthreshold(struct sway_seat *seat) {
|
|
|
|
|
struct seatop_move_tiling_event *e = seat->seatop_data;
|
|
|
|
|
e->split_target = false;
|
|
|
|
@ -172,8 +166,6 @@ static void handle_motion_postthreshold(struct sway_seat *seat) {
|
|
|
|
|
struct sway_cursor *cursor = seat->cursor;
|
|
|
|
|
struct sway_node *node = node_at_coords(seat,
|
|
|
|
|
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
|
|
|
|
// Damage the old location
|
|
|
|
|
desktop_damage_box(&e->drop_box);
|
|
|
|
|
|
|
|
|
|
if (!node) {
|
|
|
|
|
// Eg. hovered over a layer surface such as swaybar
|
|
|
|
@ -186,8 +178,10 @@ static void handle_motion_postthreshold(struct sway_seat *seat) {
|
|
|
|
|
// Empty workspace
|
|
|
|
|
e->target_node = node;
|
|
|
|
|
e->target_edge = WLR_EDGE_NONE;
|
|
|
|
|
workspace_get_box(node->sway_workspace, &e->drop_box);
|
|
|
|
|
desktop_damage_box(&e->drop_box);
|
|
|
|
|
|
|
|
|
|
struct wlr_box drop_box;
|
|
|
|
|
workspace_get_box(node->sway_workspace, &drop_box);
|
|
|
|
|
update_indicator(e, &drop_box);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -200,11 +194,18 @@ static void handle_motion_postthreshold(struct sway_seat *seat) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct wlr_box drop_box = {
|
|
|
|
|
.x = con->pending.content_x,
|
|
|
|
|
.y = con->pending.content_y,
|
|
|
|
|
.width = con->pending.content_width,
|
|
|
|
|
.height = con->pending.content_height,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Check if the cursor is over a tilebar only if the destination
|
|
|
|
|
// container is not a descendant of the source container.
|
|
|
|
|
if (!surface && !container_has_ancestor(con, e->con) &&
|
|
|
|
|
split_titlebar(node, e->con, cursor->cursor,
|
|
|
|
|
&e->drop_box, &e->insert_after_target)) {
|
|
|
|
|
&drop_box, &e->insert_after_target)) {
|
|
|
|
|
// Don't allow dropping over the source container's titlebar
|
|
|
|
|
// to give users a chance to cancel a drag operation.
|
|
|
|
|
if (con == e->con) {
|
|
|
|
@ -214,6 +215,7 @@ static void handle_motion_postthreshold(struct sway_seat *seat) {
|
|
|
|
|
e->split_target = true;
|
|
|
|
|
}
|
|
|
|
|
e->target_edge = WLR_EDGE_NONE;
|
|
|
|
|
update_indicator(e, &drop_box);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -255,8 +257,7 @@ static void handle_motion_postthreshold(struct sway_seat *seat) {
|
|
|
|
|
e->target_node = node_get_parent(e->target_node);
|
|
|
|
|
}
|
|
|
|
|
e->target_edge = edge;
|
|
|
|
|
e->drop_box = box;
|
|
|
|
|
desktop_damage_box(&e->drop_box);
|
|
|
|
|
update_indicator(e, &box);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
con = con->pending.parent;
|
|
|
|
@ -298,12 +299,8 @@ static void handle_motion_postthreshold(struct sway_seat *seat) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
e->target_node = node;
|
|
|
|
|
e->drop_box.x = con->pending.content_x;
|
|
|
|
|
e->drop_box.y = con->pending.content_y;
|
|
|
|
|
e->drop_box.width = con->pending.content_width;
|
|
|
|
|
e->drop_box.height = con->pending.content_height;
|
|
|
|
|
resize_box(&e->drop_box, e->target_edge, thickness);
|
|
|
|
|
desktop_damage_box(&e->drop_box);
|
|
|
|
|
resize_box(&drop_box, e->target_edge, thickness);
|
|
|
|
|
update_indicator(e, &drop_box);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void handle_pointer_motion(struct sway_seat *seat, uint32_t time_msec) {
|
|
|
|
@ -438,7 +435,7 @@ static const struct sway_seatop_impl seatop_impl = {
|
|
|
|
|
.pointer_motion = handle_pointer_motion,
|
|
|
|
|
.tablet_tool_tip = handle_tablet_tool_tip,
|
|
|
|
|
.unref = handle_unref,
|
|
|
|
|
.render = handle_render,
|
|
|
|
|
.end = handle_end,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void seatop_begin_move_tiling_threshold(struct sway_seat *seat,
|
|
|
|
@ -450,6 +447,20 @@ void seatop_begin_move_tiling_threshold(struct sway_seat *seat,
|
|
|
|
|
if (!e) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const float *indicator = config->border_colors.focused.indicator;
|
|
|
|
|
float color[4] = {
|
|
|
|
|
indicator[0] * .5,
|
|
|
|
|
indicator[1] * .5,
|
|
|
|
|
indicator[2] * .5,
|
|
|
|
|
indicator[3] * .5,
|
|
|
|
|
};
|
|
|
|
|
e->indicator_rect = wlr_scene_rect_create(seat->scene_tree, 0, 0, color);
|
|
|
|
|
if (!e->indicator_rect) {
|
|
|
|
|
free(e);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
e->con = con;
|
|
|
|
|
e->ref_lx = seat->cursor->cursor->x;
|
|
|
|
|
e->ref_ly = seat->cursor->cursor->y;
|
|
|
|
|