summaryrefslogtreecommitdiff
path: root/sway/input/seatop_default.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/input/seatop_default.c')
-rw-r--r--sway/input/seatop_default.c135
1 files changed, 89 insertions, 46 deletions
diff --git a/sway/input/seatop_default.c b/sway/input/seatop_default.c
index 84acefdf..1dce6dae 100644
--- a/sway/input/seatop_default.c
+++ b/sway/input/seatop_default.c
@@ -2,6 +2,7 @@
#include <float.h>
#include <libevdev/libevdev.h>
#include <wlr/types/wlr_cursor.h>
+#include <wlr/types/wlr_subcompositor.h>
#include <wlr/types/wlr_tablet_v2.h>
#include <wlr/types/wlr_xcursor_manager.h>
#include "gesture.h"
@@ -9,6 +10,7 @@
#include "sway/input/cursor.h"
#include "sway/input/seat.h"
#include "sway/input/tablet.h"
+#include "sway/layers.h"
#include "sway/output.h"
#include "sway/tree/view.h"
#include "sway/tree/workspace.h"
@@ -228,14 +230,15 @@ static void handle_tablet_tool_tip(struct sway_seat *seat,
struct sway_container *cont = node && node->type == N_CONTAINER ?
node->sway_container : NULL;
- if (wlr_surface_is_layer_surface(surface)) {
+ struct wlr_layer_surface_v1 *layer;
+#if HAVE_XWAYLAND
+ struct wlr_xwayland_surface *xsurface;
+#endif
+ if ((layer = wlr_layer_surface_v1_try_from_wlr_surface(surface)) &&
+ layer->current.keyboard_interactive) {
// Handle tapping a layer surface
- struct wlr_layer_surface_v1 *layer =
- wlr_layer_surface_v1_from_wlr_surface(surface);
- if (layer->current.keyboard_interactive) {
- seat_set_focus_layer(seat, layer);
- transaction_commit_dirty();
- }
+ seat_set_focus_layer(seat, layer);
+ transaction_commit_dirty();
} else if (cont) {
bool is_floating_or_child = container_is_floating_or_child(cont);
bool is_fullscreen_or_child = container_is_fullscreen_or_child(cont);
@@ -260,20 +263,17 @@ static void handle_tablet_tool_tip(struct sway_seat *seat,
// Handle tapping on a container surface
seat_set_focus_container(seat, cont);
- seatop_begin_down(seat, node->sway_container, time_msec, sx, sy);
+ seatop_begin_down(seat, node->sway_container, sx, sy);
}
#if HAVE_XWAYLAND
// Handle tapping on an xwayland unmanaged view
- else if (wlr_surface_is_xwayland_surface(surface)) {
- struct wlr_xwayland_surface *xsurface =
- wlr_xwayland_surface_from_wlr_surface(surface);
- if (xsurface->override_redirect &&
- wlr_xwayland_or_surface_wants_focus(xsurface)) {
- struct wlr_xwayland *xwayland = server.xwayland.wlr_xwayland;
- wlr_xwayland_set_seat(xwayland, seat->wlr_seat);
- seat_set_focus_surface(seat, xsurface->surface, false);
- transaction_commit_dirty();
- }
+ else if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(surface)) &&
+ xsurface->override_redirect &&
+ wlr_xwayland_or_surface_wants_focus(xsurface)) {
+ struct wlr_xwayland *xwayland = server.xwayland.wlr_xwayland;
+ wlr_xwayland_set_seat(xwayland, seat->wlr_seat);
+ seat_set_focus_surface(seat, xsurface->surface, false);
+ transaction_commit_dirty();
}
#endif
@@ -367,16 +367,15 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
return;
}
- // Handle clicking a layer surface
- if (surface && wlr_surface_is_layer_surface(surface)) {
- struct wlr_layer_surface_v1 *layer =
- wlr_layer_surface_v1_from_wlr_surface(surface);
+ // Handle clicking a layer surface and its popups/subsurfaces
+ struct wlr_layer_surface_v1 *layer = NULL;
+ if ((layer = toplevel_layer_surface_from_surface(surface))) {
if (layer->current.keyboard_interactive) {
seat_set_focus_layer(seat, layer);
transaction_commit_dirty();
}
if (state == WLR_BUTTON_PRESSED) {
- seatop_begin_down_on_surface(seat, surface, time_msec, sx, sy);
+ seatop_begin_down_on_surface(seat, surface, sx, sy);
}
seat_pointer_notify_button(seat, time_msec, button, state);
return;
@@ -501,7 +500,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
// Handle mousedown on a container surface
if (surface && cont && state == WLR_BUTTON_PRESSED) {
- seatop_begin_down(seat, cont, time_msec, sx, sy);
+ seatop_begin_down(seat, cont, sx, sy);
seat_pointer_notify_button(seat, time_msec, button, WLR_BUTTON_PRESSED);
return;
}
@@ -514,18 +513,16 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
#if HAVE_XWAYLAND
// Handle clicking on xwayland unmanaged view
- if (surface && wlr_surface_is_xwayland_surface(surface)) {
- struct wlr_xwayland_surface *xsurface =
- wlr_xwayland_surface_from_wlr_surface(surface);
- if (xsurface->override_redirect &&
- wlr_xwayland_or_surface_wants_focus(xsurface)) {
- struct wlr_xwayland *xwayland = server.xwayland.wlr_xwayland;
- wlr_xwayland_set_seat(xwayland, seat->wlr_seat);
- seat_set_focus_surface(seat, xsurface->surface, false);
- transaction_commit_dirty();
- seat_pointer_notify_button(seat, time_msec, button, state);
- return;
- }
+ struct wlr_xwayland_surface *xsurface;
+ if (surface &&
+ (xsurface = wlr_xwayland_surface_try_from_wlr_surface(surface)) &&
+ xsurface->override_redirect &&
+ wlr_xwayland_or_surface_wants_focus(xsurface)) {
+ struct wlr_xwayland *xwayland = server.xwayland.wlr_xwayland;
+ wlr_xwayland_set_seat(xwayland, seat->wlr_seat);
+ seat_set_focus_surface(seat, xsurface->surface, false);
+ transaction_commit_dirty();
+ seat_pointer_notify_button(seat, time_msec, button, state);
}
#endif
@@ -548,6 +545,21 @@ static void check_focus_follows_mouse(struct sway_seat *seat,
if (wlr_output == NULL) {
return;
}
+
+ struct wlr_surface *surface = NULL;
+ double sx, sy;
+ node_at_coords(seat, seat->cursor->cursor->x, seat->cursor->cursor->y,
+ &surface, &sx, &sy);
+
+ // Focus topmost layer surface
+ struct wlr_layer_surface_v1 *layer = NULL;
+ if ((layer = toplevel_layer_surface_from_surface(surface)) &&
+ layer->current.keyboard_interactive) {
+ seat_set_focus_layer(seat, layer);
+ transaction_commit_dirty();
+ return;
+ }
+
struct sway_output *hovered_output = wlr_output->data;
if (focus && hovered_output != node_get_output(focus)) {
struct sway_workspace *ws = output_get_active_workspace(hovered_output);
@@ -653,6 +665,36 @@ static void handle_tablet_tool_motion(struct sway_seat *seat,
e->previous_node = node;
}
+static void handle_touch_down(struct sway_seat *seat,
+ struct wlr_touch_down_event *event, double lx, double ly) {
+ struct wlr_surface *surface = NULL;
+ struct wlr_seat *wlr_seat = seat->wlr_seat;
+ struct sway_cursor *cursor = seat->cursor;
+ double sx, sy;
+ node_at_coords(seat, seat->touch_x, seat->touch_y, &surface, &sx, &sy);
+
+ if (surface && wlr_surface_accepts_touch(wlr_seat, surface)) {
+ if (seat_is_input_allowed(seat, surface)) {
+ cursor->simulating_pointer_from_touch = false;
+ seatop_begin_touch_down(seat, surface, event, sx, sy, lx, ly);
+ }
+ } else if (!cursor->simulating_pointer_from_touch &&
+ (!surface || seat_is_input_allowed(seat, surface))) {
+ // Fallback to cursor simulation.
+ // The pointer_touch_id state is needed, so drags are not aborted when over
+ // a surface supporting touch and multi touch events don't interfere.
+ cursor->simulating_pointer_from_touch = true;
+ cursor->pointer_touch_id = seat->touch_id;
+ double dx, dy;
+ dx = seat->touch_x - cursor->cursor->x;
+ dy = seat->touch_y - cursor->cursor->y;
+ pointer_motion(cursor, event->time_msec, &event->touch->base, dx, dy,
+ dx, dy);
+ dispatch_cursor_button(cursor, &event->touch->base, event->time_msec,
+ BTN_LEFT, WLR_BUTTON_PRESSED);
+ }
+}
+
/*----------------------------------------\
* Functions used by handle_pointer_axis /
*--------------------------------------*/
@@ -726,7 +768,7 @@ static void handle_pointer_axis(struct sway_seat *seat,
seat_get_active_tiling_child(seat, tabcontainer);
list_t *siblings = container_get_siblings(cont);
int desired = list_find(siblings, active->sway_container) +
- round(scroll_factor * event->delta_discrete / WLR_POINTER_AXIS_DISCRETE_STEP);
+ roundf(scroll_factor * event->delta_discrete / WLR_POINTER_AXIS_DISCRETE_STEP);
if (desired < 0) {
desired = 0;
} else if (desired >= siblings->length) {
@@ -761,7 +803,7 @@ static void handle_pointer_axis(struct sway_seat *seat,
if (!handled) {
wlr_seat_pointer_notify_axis(cursor->seat->wlr_seat, event->time_msec,
event->orientation, scroll_factor * event->delta,
- round(scroll_factor * event->delta_discrete), event->source);
+ roundf(scroll_factor * event->delta_discrete), event->source);
}
}
@@ -907,7 +949,7 @@ static void handle_hold_begin(struct sway_seat *seat,
// ... otherwise forward to client
struct sway_cursor *cursor = seat->cursor;
wlr_pointer_gestures_v1_send_hold_begin(
- cursor->pointer_gestures, cursor->seat->wlr_seat,
+ server.input->pointer_gestures, cursor->seat->wlr_seat,
event->time_msec, event->fingers);
}
}
@@ -919,7 +961,7 @@ static void handle_hold_end(struct sway_seat *seat,
if (!gesture_tracker_check(&seatop->gestures, GESTURE_TYPE_HOLD)) {
struct sway_cursor *cursor = seat->cursor;
wlr_pointer_gestures_v1_send_hold_end(
- cursor->pointer_gestures, cursor->seat->wlr_seat,
+ server.input->pointer_gestures, cursor->seat->wlr_seat,
event->time_msec, event->cancelled);
return;
}
@@ -952,7 +994,7 @@ static void handle_pinch_begin(struct sway_seat *seat,
// ... otherwise forward to client
struct sway_cursor *cursor = seat->cursor;
wlr_pointer_gestures_v1_send_pinch_begin(
- cursor->pointer_gestures, cursor->seat->wlr_seat,
+ server.input->pointer_gestures, cursor->seat->wlr_seat,
event->time_msec, event->fingers);
}
}
@@ -968,7 +1010,7 @@ static void handle_pinch_update(struct sway_seat *seat,
// ... otherwise forward to client
struct sway_cursor *cursor = seat->cursor;
wlr_pointer_gestures_v1_send_pinch_update(
- cursor->pointer_gestures,
+ server.input->pointer_gestures,
cursor->seat->wlr_seat,
event->time_msec, event->dx, event->dy,
event->scale, event->rotation);
@@ -982,7 +1024,7 @@ static void handle_pinch_end(struct sway_seat *seat,
if (!gesture_tracker_check(&seatop->gestures, GESTURE_TYPE_PINCH)) {
struct sway_cursor *cursor = seat->cursor;
wlr_pointer_gestures_v1_send_pinch_end(
- cursor->pointer_gestures, cursor->seat->wlr_seat,
+ server.input->pointer_gestures, cursor->seat->wlr_seat,
event->time_msec, event->cancelled);
return;
}
@@ -1015,7 +1057,7 @@ static void handle_swipe_begin(struct sway_seat *seat,
// ... otherwise forward to client
struct sway_cursor *cursor = seat->cursor;
wlr_pointer_gestures_v1_send_swipe_begin(
- cursor->pointer_gestures, cursor->seat->wlr_seat,
+ server.input->pointer_gestures, cursor->seat->wlr_seat,
event->time_msec, event->fingers);
}
}
@@ -1032,7 +1074,7 @@ static void handle_swipe_update(struct sway_seat *seat,
// ... otherwise forward to client
struct sway_cursor *cursor = seat->cursor;
wlr_pointer_gestures_v1_send_swipe_update(
- cursor->pointer_gestures, cursor->seat->wlr_seat,
+ server.input->pointer_gestures, cursor->seat->wlr_seat,
event->time_msec, event->dx, event->dy);
}
}
@@ -1043,7 +1085,7 @@ static void handle_swipe_end(struct sway_seat *seat,
struct seatop_default_event *seatop = seat->seatop_data;
if (!gesture_tracker_check(&seatop->gestures, GESTURE_TYPE_SWIPE)) {
struct sway_cursor *cursor = seat->cursor;
- wlr_pointer_gestures_v1_send_swipe_end(cursor->pointer_gestures,
+ wlr_pointer_gestures_v1_send_swipe_end(server.input->pointer_gestures,
cursor->seat->wlr_seat, event->time_msec, event->cancelled);
return;
}
@@ -1100,6 +1142,7 @@ static const struct sway_seatop_impl seatop_impl = {
.swipe_begin = handle_swipe_begin,
.swipe_update = handle_swipe_update,
.swipe_end = handle_swipe_end,
+ .touch_down = handle_touch_down,
.rebase = handle_rebase,
.allow_set_cursor = true,
};