mirror of
https://github.com/swaywm/sway.git
synced 2026-04-23 06:46:27 -04:00
Merge bfc22725b8 into b40c6448e6
This commit is contained in:
commit
ed722d14fc
5 changed files with 82 additions and 48 deletions
|
|
@ -22,6 +22,15 @@ struct sway_cursor {
|
||||||
double x, y;
|
double x, y;
|
||||||
struct sway_node *node;
|
struct sway_node *node;
|
||||||
} previous;
|
} previous;
|
||||||
|
|
||||||
|
// Not to be confused with `previous` above; they store entirely unrelated
|
||||||
|
// data.
|
||||||
|
struct {
|
||||||
|
double sx, sy;
|
||||||
|
struct sway_node *node;
|
||||||
|
struct wlr_surface *surface;
|
||||||
|
} current;
|
||||||
|
|
||||||
struct wlr_xcursor_manager *xcursor_manager;
|
struct wlr_xcursor_manager *xcursor_manager;
|
||||||
struct wl_list tablets;
|
struct wl_list tablets;
|
||||||
struct wl_list tablet_pads;
|
struct wl_list tablet_pads;
|
||||||
|
|
@ -79,10 +88,6 @@ struct sway_cursor {
|
||||||
|
|
||||||
struct sway_node;
|
struct sway_node;
|
||||||
|
|
||||||
struct sway_node *node_at_coords(
|
|
||||||
struct sway_seat *seat, double lx, double ly,
|
|
||||||
struct wlr_surface **surface, double *sx, double *sy);
|
|
||||||
|
|
||||||
void sway_cursor_destroy(struct sway_cursor *cursor);
|
void sway_cursor_destroy(struct sway_cursor *cursor);
|
||||||
struct sway_cursor *sway_cursor_create(struct sway_seat *seat);
|
struct sway_cursor *sway_cursor_create(struct sway_seat *seat);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -618,11 +618,7 @@ void seat_execute_command(struct sway_seat *seat, struct sway_binding *binding)
|
||||||
struct sway_container *con = NULL;
|
struct sway_container *con = NULL;
|
||||||
if (binding->type == BINDING_MOUSESYM
|
if (binding->type == BINDING_MOUSESYM
|
||||||
|| binding->type == BINDING_MOUSECODE) {
|
|| binding->type == BINDING_MOUSECODE) {
|
||||||
struct wlr_surface *surface = NULL;
|
struct sway_node *node = seat->cursor->current.node;
|
||||||
double sx, sy;
|
|
||||||
struct sway_node *node = node_at_coords(seat,
|
|
||||||
seat->cursor->cursor->x, seat->cursor->cursor->y,
|
|
||||||
&surface, &sx, &sy);
|
|
||||||
if (node && node->type == N_CONTAINER) {
|
if (node && node->type == N_CONTAINER) {
|
||||||
con = node->sway_container;
|
con = node->sway_container;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ static struct wlr_surface *layer_surface_popup_at(struct sway_output *output,
|
||||||
* Returns the node at the cursor's position. If there is a surface at that
|
* Returns the node at the cursor's position. If there is a surface at that
|
||||||
* location, it is stored in **surface (it may not be a view).
|
* location, it is stored in **surface (it may not be a view).
|
||||||
*/
|
*/
|
||||||
struct sway_node *node_at_coords(
|
static struct sway_node *node_at_coords(
|
||||||
struct sway_seat *seat, double lx, double ly,
|
struct sway_seat *seat, double lx, double ly,
|
||||||
struct wlr_surface **surface, double *sx, double *sy) {
|
struct wlr_surface **surface, double *sx, double *sy) {
|
||||||
// check for unmanaged views first
|
// check for unmanaged views first
|
||||||
|
|
@ -340,6 +340,50 @@ void cursor_unhide(struct sway_cursor *cursor) {
|
||||||
wl_event_source_timer_update(cursor->hide_source, cursor_get_timeout(cursor));
|
wl_event_source_timer_update(cursor->hide_source, cursor_get_timeout(cursor));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool cursor_motion_is_constrained(struct sway_cursor *cursor,
|
||||||
|
enum wlr_input_device_type type) {
|
||||||
|
// Only apply pointer constraints to real pointer input.
|
||||||
|
return cursor->active_constraint && type == WLR_INPUT_DEVICE_POINTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cursor_update_current_node(struct sway_cursor *cursor,
|
||||||
|
enum wlr_input_device_type type) {
|
||||||
|
struct sway_node *node = NULL;
|
||||||
|
struct wlr_surface *surface = NULL;
|
||||||
|
double sx = 0, sy = 0;
|
||||||
|
|
||||||
|
if (cursor_motion_is_constrained(cursor, type)) {
|
||||||
|
struct wlr_pointer_constraint_v1 *constraint = cursor->active_constraint;
|
||||||
|
struct sway_view *view = view_from_wlr_surface(constraint->surface);
|
||||||
|
|
||||||
|
if (view) {
|
||||||
|
struct sway_container *con = view->container;
|
||||||
|
sx = cursor->cursor->x - con->pending.content_x + view->geometry.x;
|
||||||
|
sy = cursor->cursor->y - con->pending.content_y + view->geometry.y;
|
||||||
|
|
||||||
|
if (pixman_region32_contains_point(&constraint->region, floor(sx),
|
||||||
|
floor(sy), NULL)) {
|
||||||
|
node = &view->container->node;
|
||||||
|
surface = constraint->surface;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is subtle: this means that if an actively constrained surface is
|
||||||
|
// partially occluded by another node (say, by a floating node), the cursor
|
||||||
|
// shall remain constrained and pass "under" the floating node. Need to
|
||||||
|
// check both `node` and `surface` since neither implies the other.
|
||||||
|
if (!node && !surface) {
|
||||||
|
node = node_at_coords(cursor->seat, cursor->cursor->x, cursor->cursor->y,
|
||||||
|
&surface, &sx, &sy);
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor->current.sx = sx;
|
||||||
|
cursor->current.sy = sy;
|
||||||
|
cursor->current.node = node;
|
||||||
|
cursor->current.surface = surface;
|
||||||
|
}
|
||||||
|
|
||||||
static void pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
|
static void pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
|
||||||
struct wlr_input_device *device, double dx, double dy,
|
struct wlr_input_device *device, double dx, double dy,
|
||||||
double dx_unaccel, double dy_unaccel) {
|
double dx_unaccel, double dy_unaccel) {
|
||||||
|
|
@ -348,17 +392,12 @@ static void pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
|
||||||
cursor->seat->wlr_seat, (uint64_t)time_msec * 1000,
|
cursor->seat->wlr_seat, (uint64_t)time_msec * 1000,
|
||||||
dx, dy, dx_unaccel, dy_unaccel);
|
dx, dy, dx_unaccel, dy_unaccel);
|
||||||
|
|
||||||
// Only apply pointer constraints to real pointer input.
|
cursor_update_current_node(cursor, device->type);
|
||||||
if (cursor->active_constraint && device->type == WLR_INPUT_DEVICE_POINTER) {
|
|
||||||
struct wlr_surface *surface = NULL;
|
|
||||||
double sx, sy;
|
|
||||||
node_at_coords(cursor->seat,
|
|
||||||
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
|
||||||
|
|
||||||
if (cursor->active_constraint->surface != surface) {
|
if (cursor_motion_is_constrained(cursor, device->type)) {
|
||||||
return;
|
assert(cursor->active_constraint->surface == cursor->current.surface);
|
||||||
}
|
|
||||||
|
|
||||||
|
double sx = cursor->current.sx, sy = cursor->current.sy;
|
||||||
double sx_confined, sy_confined;
|
double sx_confined, sy_confined;
|
||||||
if (!wlr_region_confine(&cursor->confine, sx, sy, sx + dx, sy + dy,
|
if (!wlr_region_confine(&cursor->confine, sx, sy, sx + dx, sy + dy,
|
||||||
&sx_confined, &sy_confined)) {
|
&sx_confined, &sy_confined)) {
|
||||||
|
|
@ -370,6 +409,7 @@ static void pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_cursor_move(cursor->cursor, device, dx, dy);
|
wlr_cursor_move(cursor->cursor, device, dx, dy);
|
||||||
|
cursor_update_current_node(cursor, device->type);
|
||||||
|
|
||||||
seatop_pointer_motion(cursor->seat, time_msec);
|
seatop_pointer_motion(cursor->seat, time_msec);
|
||||||
}
|
}
|
||||||
|
|
@ -608,10 +648,8 @@ static void handle_tablet_tool_position(struct sway_cursor *cursor,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
double sx, sy;
|
struct wlr_surface *surface = cursor->current.surface;
|
||||||
struct wlr_surface *surface = NULL;
|
|
||||||
struct sway_seat *seat = cursor->seat;
|
struct sway_seat *seat = cursor->seat;
|
||||||
node_at_coords(seat, cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
|
||||||
|
|
||||||
// The logic for whether we should send a tablet event or an emulated pointer
|
// The logic for whether we should send a tablet event or an emulated pointer
|
||||||
// event is tricky. It comes down to:
|
// event is tricky. It comes down to:
|
||||||
|
|
@ -626,6 +664,7 @@ static void handle_tablet_tool_position(struct sway_cursor *cursor,
|
||||||
if (!cursor->simulating_pointer_from_tool_tip &&
|
if (!cursor->simulating_pointer_from_tool_tip &&
|
||||||
((surface && wlr_surface_accepts_tablet_v2(tablet->tablet_v2, surface)) ||
|
((surface && wlr_surface_accepts_tablet_v2(tablet->tablet_v2, surface)) ||
|
||||||
wlr_tablet_tool_v2_has_implicit_grab(tool->tablet_v2_tool))) {
|
wlr_tablet_tool_v2_has_implicit_grab(tool->tablet_v2_tool))) {
|
||||||
|
cursor_update_current_node(cursor, input_device->wlr_device->type);
|
||||||
seatop_tablet_tool_motion(seat, tool, time_msec);
|
seatop_tablet_tool_motion(seat, tool, time_msec);
|
||||||
} else {
|
} else {
|
||||||
wlr_tablet_v2_tablet_tool_notify_proximity_out(tool->tablet_v2_tool);
|
wlr_tablet_v2_tablet_tool_notify_proximity_out(tool->tablet_v2_tool);
|
||||||
|
|
@ -839,8 +878,11 @@ static void check_constraint_region(struct sway_cursor *cursor) {
|
||||||
sx + con->pending.content_x - view->geometry.x,
|
sx + con->pending.content_x - view->geometry.x,
|
||||||
sy + con->pending.content_y - view->geometry.y);
|
sy + con->pending.content_y - view->geometry.y);
|
||||||
|
|
||||||
|
cursor_update_current_node(cursor, WLR_INPUT_DEVICE_POINTER);
|
||||||
cursor_rebase(cursor);
|
cursor_rebase(cursor);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
cursor_update_current_node(cursor, WLR_INPUT_DEVICE_POINTER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1279,6 +1321,7 @@ static void warp_to_constraint_cursor_hint(struct sway_cursor *cursor) {
|
||||||
// Warp the pointer as well, so that on the next pointer rebase we don't
|
// Warp the pointer as well, so that on the next pointer rebase we don't
|
||||||
// send an unexpected synthetic motion event to clients.
|
// send an unexpected synthetic motion event to clients.
|
||||||
wlr_seat_pointer_warp(constraint->seat, sx, sy);
|
wlr_seat_pointer_warp(constraint->seat, sx, sy);
|
||||||
|
cursor_update_current_node(cursor, WLR_INPUT_DEVICE_POINTER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -213,10 +213,9 @@ static void handle_tablet_tool_tip(struct sway_seat *seat,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sway_cursor *cursor = seat->cursor;
|
struct sway_cursor *cursor = seat->cursor;
|
||||||
struct wlr_surface *surface = NULL;
|
struct wlr_surface *surface = cursor->current.surface;
|
||||||
double sx, sy;
|
double sx = cursor->current.sx, sy = cursor->current.sy;
|
||||||
struct sway_node *node = node_at_coords(seat,
|
struct sway_node *node = cursor->current.node;
|
||||||
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
|
||||||
|
|
||||||
if (!sway_assert(surface,
|
if (!sway_assert(surface,
|
||||||
"Expected null-surface tablet input to route through pointer emulation")) {
|
"Expected null-surface tablet input to route through pointer emulation")) {
|
||||||
|
|
@ -328,10 +327,9 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
|
||||||
struct sway_cursor *cursor = seat->cursor;
|
struct sway_cursor *cursor = seat->cursor;
|
||||||
|
|
||||||
// Determine what's under the cursor
|
// Determine what's under the cursor
|
||||||
struct wlr_surface *surface = NULL;
|
struct wlr_surface *surface = cursor->current.surface;
|
||||||
double sx, sy;
|
double sx = cursor->current.sx, sy = cursor->current.sy;
|
||||||
struct sway_node *node = node_at_coords(seat,
|
struct sway_node *node = cursor->current.node;
|
||||||
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
|
||||||
|
|
||||||
struct sway_container *cont = node && node->type == N_CONTAINER ?
|
struct sway_container *cont = node && node->type == N_CONTAINER ?
|
||||||
node->sway_container : NULL;
|
node->sway_container : NULL;
|
||||||
|
|
@ -574,10 +572,9 @@ static void handle_pointer_motion(struct sway_seat *seat, uint32_t time_msec) {
|
||||||
struct seatop_default_event *e = seat->seatop_data;
|
struct seatop_default_event *e = seat->seatop_data;
|
||||||
struct sway_cursor *cursor = seat->cursor;
|
struct sway_cursor *cursor = seat->cursor;
|
||||||
|
|
||||||
struct wlr_surface *surface = NULL;
|
struct wlr_surface *surface = cursor->current.surface;
|
||||||
double sx, sy;
|
double sx = cursor->current.sx, sy = cursor->current.sy;
|
||||||
struct sway_node *node = node_at_coords(seat,
|
struct sway_node *node = cursor->current.node;
|
||||||
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
|
||||||
|
|
||||||
if (config->focus_follows_mouse != FOLLOWS_NO) {
|
if (config->focus_follows_mouse != FOLLOWS_NO) {
|
||||||
check_focus_follows_mouse(seat, e, node);
|
check_focus_follows_mouse(seat, e, node);
|
||||||
|
|
@ -608,10 +605,9 @@ static void handle_tablet_tool_motion(struct sway_seat *seat,
|
||||||
struct seatop_default_event *e = seat->seatop_data;
|
struct seatop_default_event *e = seat->seatop_data;
|
||||||
struct sway_cursor *cursor = seat->cursor;
|
struct sway_cursor *cursor = seat->cursor;
|
||||||
|
|
||||||
struct wlr_surface *surface = NULL;
|
struct wlr_surface *surface = cursor->current.surface;
|
||||||
double sx, sy;
|
double sx = cursor->current.sx, sy = cursor->current.sy;
|
||||||
struct sway_node *node = node_at_coords(seat,
|
struct sway_node *node = cursor->current.node;
|
||||||
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
|
||||||
|
|
||||||
if (config->focus_follows_mouse != FOLLOWS_NO) {
|
if (config->focus_follows_mouse != FOLLOWS_NO) {
|
||||||
check_focus_follows_mouse(seat, e, node);
|
check_focus_follows_mouse(seat, e, node);
|
||||||
|
|
@ -664,10 +660,8 @@ static void handle_pointer_axis(struct sway_seat *seat,
|
||||||
struct seatop_default_event *e = seat->seatop_data;
|
struct seatop_default_event *e = seat->seatop_data;
|
||||||
|
|
||||||
// Determine what's under the cursor
|
// Determine what's under the cursor
|
||||||
struct wlr_surface *surface = NULL;
|
struct wlr_surface *surface = cursor->current.surface;
|
||||||
double sx, sy;
|
struct sway_node *node = cursor->current.node;
|
||||||
struct sway_node *node = node_at_coords(seat,
|
|
||||||
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
|
||||||
struct sway_container *cont = node && node->type == N_CONTAINER ?
|
struct sway_container *cont = node && node->type == N_CONTAINER ?
|
||||||
node->sway_container : NULL;
|
node->sway_container : NULL;
|
||||||
enum wlr_edges edge = cont ? find_edge(cont, surface, cursor) : WLR_EDGE_NONE;
|
enum wlr_edges edge = cont ? find_edge(cont, surface, cursor) : WLR_EDGE_NONE;
|
||||||
|
|
@ -756,8 +750,7 @@ static void handle_rebase(struct sway_seat *seat, uint32_t time_msec) {
|
||||||
struct sway_cursor *cursor = seat->cursor;
|
struct sway_cursor *cursor = seat->cursor;
|
||||||
struct wlr_surface *surface = NULL;
|
struct wlr_surface *surface = NULL;
|
||||||
double sx = 0.0, sy = 0.0;
|
double sx = 0.0, sy = 0.0;
|
||||||
e->previous_node = node_at_coords(seat,
|
e->previous_node = cursor->current.node;
|
||||||
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
|
||||||
|
|
||||||
if (surface) {
|
if (surface) {
|
||||||
if (seat_is_input_allowed(seat, surface)) {
|
if (seat_is_input_allowed(seat, surface)) {
|
||||||
|
|
|
||||||
|
|
@ -94,11 +94,8 @@ static void resize_box(struct wlr_box *box, enum wlr_edges edge,
|
||||||
|
|
||||||
static void handle_motion_postthreshold(struct sway_seat *seat) {
|
static void handle_motion_postthreshold(struct sway_seat *seat) {
|
||||||
struct seatop_move_tiling_event *e = seat->seatop_data;
|
struct seatop_move_tiling_event *e = seat->seatop_data;
|
||||||
struct wlr_surface *surface = NULL;
|
|
||||||
double sx, sy;
|
|
||||||
struct sway_cursor *cursor = seat->cursor;
|
struct sway_cursor *cursor = seat->cursor;
|
||||||
struct sway_node *node = node_at_coords(seat,
|
struct sway_node *node = cursor->current.node;
|
||||||
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
|
||||||
// Damage the old location
|
// Damage the old location
|
||||||
desktop_damage_box(&e->drop_box);
|
desktop_damage_box(&e->drop_box);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue