summaryrefslogtreecommitdiff
path: root/sway/input
diff options
context:
space:
mode:
Diffstat (limited to 'sway/input')
-rw-r--r--sway/input/cursor.c195
-rw-r--r--sway/input/input-manager.c27
-rw-r--r--sway/input/keyboard.c128
-rw-r--r--sway/input/libinput.c23
-rw-r--r--sway/input/seat.c141
-rw-r--r--sway/input/seatop_default.c369
-rw-r--r--sway/input/seatop_down.c4
-rw-r--r--sway/input/switch.c28
-rw-r--r--sway/input/tablet.c23
-rw-r--r--sway/input/text_input.c2
10 files changed, 695 insertions, 245 deletions
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index 6fddee90..449aa430 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -386,28 +386,29 @@ static void pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
static void handle_pointer_motion_relative(
struct wl_listener *listener, void *data) {
struct sway_cursor *cursor = wl_container_of(listener, cursor, motion);
- struct wlr_event_pointer_motion *e = data;
- cursor_handle_activity_from_device(cursor, e->device);
+ struct wlr_pointer_motion_event *e = data;
+ cursor_handle_activity_from_device(cursor, &e->pointer->base);
- pointer_motion(cursor, e->time_msec, e->device, e->delta_x, e->delta_y,
- e->unaccel_dx, e->unaccel_dy);
+ pointer_motion(cursor, e->time_msec, &e->pointer->base, e->delta_x,
+ e->delta_y, e->unaccel_dx, e->unaccel_dy);
}
static void handle_pointer_motion_absolute(
struct wl_listener *listener, void *data) {
struct sway_cursor *cursor =
wl_container_of(listener, cursor, motion_absolute);
- struct wlr_event_pointer_motion_absolute *event = data;
- cursor_handle_activity_from_device(cursor, event->device);
+ struct wlr_pointer_motion_absolute_event *event = data;
+ cursor_handle_activity_from_device(cursor, &event->pointer->base);
double lx, ly;
- wlr_cursor_absolute_to_layout_coords(cursor->cursor, event->device,
+ wlr_cursor_absolute_to_layout_coords(cursor->cursor, &event->pointer->base,
event->x, event->y, &lx, &ly);
double dx = lx - cursor->cursor->x;
double dy = ly - cursor->cursor->y;
- pointer_motion(cursor, event->time_msec, event->device, dx, dy, dx, dy);
+ pointer_motion(cursor, event->time_msec, &event->pointer->base, dx, dy,
+ dx, dy);
}
void dispatch_cursor_button(struct sway_cursor *cursor,
@@ -422,7 +423,7 @@ void dispatch_cursor_button(struct sway_cursor *cursor,
static void handle_pointer_button(struct wl_listener *listener, void *data) {
struct sway_cursor *cursor = wl_container_of(listener, cursor, button);
- struct wlr_event_pointer_button *event = data;
+ struct wlr_pointer_button_event *event = data;
if (event->state == WLR_BUTTON_PRESSED) {
cursor->pressed_button_count++;
@@ -434,20 +435,20 @@ static void handle_pointer_button(struct wl_listener *listener, void *data) {
}
}
- cursor_handle_activity_from_device(cursor, event->device);
- dispatch_cursor_button(cursor, event->device,
+ cursor_handle_activity_from_device(cursor, &event->pointer->base);
+ dispatch_cursor_button(cursor, &event->pointer->base,
event->time_msec, event->button, event->state);
}
void dispatch_cursor_axis(struct sway_cursor *cursor,
- struct wlr_event_pointer_axis *event) {
+ struct wlr_pointer_axis_event *event) {
seatop_pointer_axis(cursor->seat, event);
}
static void handle_pointer_axis(struct wl_listener *listener, void *data) {
struct sway_cursor *cursor = wl_container_of(listener, cursor, axis);
- struct wlr_event_pointer_axis *event = data;
- cursor_handle_activity_from_device(cursor, event->device);
+ struct wlr_pointer_axis_event *event = data;
+ cursor_handle_activity_from_device(cursor, &event->pointer->base);
dispatch_cursor_axis(cursor, event);
}
@@ -458,8 +459,8 @@ static void handle_pointer_frame(struct wl_listener *listener, void *data) {
static void handle_touch_down(struct wl_listener *listener, void *data) {
struct sway_cursor *cursor = wl_container_of(listener, cursor, touch_down);
- struct wlr_event_touch_down *event = data;
- cursor_handle_activity_from_device(cursor, event->device);
+ struct wlr_touch_down_event *event = data;
+ cursor_handle_activity_from_device(cursor, &event->touch->base);
cursor_hide(cursor);
struct sway_seat *seat = cursor->seat;
@@ -467,7 +468,7 @@ static void handle_touch_down(struct wl_listener *listener, void *data) {
struct wlr_surface *surface = NULL;
double lx, ly;
- wlr_cursor_absolute_to_layout_coords(cursor->cursor, event->device,
+ wlr_cursor_absolute_to_layout_coords(cursor->cursor, &event->touch->base,
event->x, event->y, &lx, &ly);
double sx, sy;
struct sway_node *focused_node = node_at_coords(seat, lx, ly, &surface, &sx, &sy);
@@ -495,24 +496,25 @@ static void handle_touch_down(struct wl_listener *listener, void *data) {
double dx, dy;
dx = lx - cursor->cursor->x;
dy = ly - cursor->cursor->y;
- pointer_motion(cursor, event->time_msec, event->device, dx, dy, dx, dy);
- dispatch_cursor_button(cursor, event->device, event->time_msec,
+ 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);
}
}
static void handle_touch_up(struct wl_listener *listener, void *data) {
struct sway_cursor *cursor = wl_container_of(listener, cursor, touch_up);
- struct wlr_event_touch_up *event = data;
- cursor_handle_activity_from_device(cursor, event->device);
+ struct wlr_touch_up_event *event = data;
+ cursor_handle_activity_from_device(cursor, &event->touch->base);
struct wlr_seat *wlr_seat = cursor->seat->wlr_seat;
if (cursor->simulating_pointer_from_touch) {
if (cursor->pointer_touch_id == cursor->seat->touch_id) {
cursor->pointer_touch_up = true;
- dispatch_cursor_button(cursor, event->device, event->time_msec,
- BTN_LEFT, WLR_BUTTON_RELEASED);
+ dispatch_cursor_button(cursor, &event->touch->base,
+ event->time_msec, BTN_LEFT, WLR_BUTTON_RELEASED);
}
} else {
wlr_seat_touch_notify_up(wlr_seat, event->time_msec, event->touch_id);
@@ -522,15 +524,15 @@ static void handle_touch_up(struct wl_listener *listener, void *data) {
static void handle_touch_motion(struct wl_listener *listener, void *data) {
struct sway_cursor *cursor =
wl_container_of(listener, cursor, touch_motion);
- struct wlr_event_touch_motion *event = data;
- cursor_handle_activity_from_device(cursor, event->device);
+ struct wlr_touch_motion_event *event = data;
+ cursor_handle_activity_from_device(cursor, &event->touch->base);
struct sway_seat *seat = cursor->seat;
struct wlr_seat *wlr_seat = seat->wlr_seat;
struct wlr_surface *surface = NULL;
double lx, ly;
- wlr_cursor_absolute_to_layout_coords(cursor->cursor, event->device,
+ wlr_cursor_absolute_to_layout_coords(cursor->cursor, &event->touch->base,
event->x, event->y, &lx, &ly);
double sx, sy;
node_at_coords(cursor->seat, lx, ly, &surface, &sx, &sy);
@@ -552,7 +554,8 @@ static void handle_touch_motion(struct wl_listener *listener, void *data) {
double dx, dy;
dx = lx - cursor->cursor->x;
dy = ly - cursor->cursor->y;
- pointer_motion(cursor, event->time_msec, event->device, dx, dy, dx, dy);
+ pointer_motion(cursor, event->time_msec, &event->touch->base,
+ dx, dy, dx, dy);
}
} else if (surface) {
wlr_seat_touch_notify_motion(wlr_seat, event->time_msec,
@@ -591,14 +594,15 @@ static void apply_mapping_from_region(struct wlr_input_device *device,
double x1 = region->x1, x2 = region->x2;
double y1 = region->y1, y2 = region->y2;
- if (region->mm) {
- if (device->width_mm == 0 || device->height_mm == 0) {
+ if (region->mm && device->type == WLR_INPUT_DEVICE_TABLET_TOOL) {
+ struct wlr_tablet *tablet = wlr_tablet_from_input_device(device);
+ if (tablet->width_mm == 0 || tablet->height_mm == 0) {
return;
}
- x1 /= device->width_mm;
- x2 /= device->width_mm;
- y1 /= device->height_mm;
- y2 /= device->height_mm;
+ x1 /= tablet->width_mm;
+ x2 /= tablet->width_mm;
+ y1 /= tablet->height_mm;
+ y2 /= tablet->height_mm;
}
*x = apply_mapping_from_coord(x1, x2, *x);
@@ -660,8 +664,8 @@ static void handle_tablet_tool_position(struct sway_cursor *cursor,
static void handle_tool_axis(struct wl_listener *listener, void *data) {
struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_axis);
- struct wlr_event_tablet_tool_axis *event = data;
- cursor_handle_activity_from_device(cursor, event->device);
+ struct wlr_tablet_tool_axis_event *event = data;
+ cursor_handle_activity_from_device(cursor, &event->tablet->base);
struct sway_tablet_tool *sway_tool = event->tool->data;
if (!sway_tool) {
@@ -716,8 +720,8 @@ static void handle_tool_axis(struct wl_listener *listener, void *data) {
static void handle_tool_tip(struct wl_listener *listener, void *data) {
struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_tip);
- struct wlr_event_tablet_tool_tip *event = data;
- cursor_handle_activity_from_device(cursor, event->device);
+ struct wlr_tablet_tool_tip_event *event = data;
+ cursor_handle_activity_from_device(cursor, &event->tablet->base);
struct sway_tablet_tool *sway_tool = event->tool->data;
struct wlr_tablet_v2_tablet *tablet_v2 = sway_tool->tablet->tablet_v2;
@@ -732,7 +736,7 @@ static void handle_tool_tip(struct wl_listener *listener, void *data) {
if (cursor->simulating_pointer_from_tool_tip &&
event->state == WLR_TABLET_TOOL_TIP_UP) {
cursor->simulating_pointer_from_tool_tip = false;
- dispatch_cursor_button(cursor, event->device, event->time_msec,
+ dispatch_cursor_button(cursor, &event->tablet->base, event->time_msec,
BTN_LEFT, WLR_BUTTON_RELEASED);
wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat);
} else if (!surface || !wlr_surface_accepts_tablet_v2(tablet_v2, surface)) {
@@ -744,8 +748,8 @@ static void handle_tool_tip(struct wl_listener *listener, void *data) {
WLR_TABLET_TOOL_TIP_UP);
} else {
cursor->simulating_pointer_from_tool_tip = true;
- dispatch_cursor_button(cursor, event->device, event->time_msec,
- BTN_LEFT, WLR_BUTTON_PRESSED);
+ dispatch_cursor_button(cursor, &event->tablet->base,
+ event->time_msec, BTN_LEFT, WLR_BUTTON_PRESSED);
wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat);
}
} else {
@@ -767,12 +771,13 @@ static struct sway_tablet *get_tablet_for_device(struct sway_cursor *cursor,
static void handle_tool_proximity(struct wl_listener *listener, void *data) {
struct sway_cursor *cursor =
wl_container_of(listener, cursor, tool_proximity);
- struct wlr_event_tablet_tool_proximity *event = data;
- cursor_handle_activity_from_device(cursor, event->device);
+ struct wlr_tablet_tool_proximity_event *event = data;
+ cursor_handle_activity_from_device(cursor, &event->tablet->base);
struct wlr_tablet_tool *tool = event->tool;
if (!tool->data) {
- struct sway_tablet *tablet = get_tablet_for_device(cursor, event->device);
+ struct sway_tablet *tablet = get_tablet_for_device(cursor,
+ &event->tablet->base);
if (!tablet) {
sway_log(SWAY_ERROR, "no tablet for tablet tool");
return;
@@ -797,8 +802,8 @@ static void handle_tool_proximity(struct wl_listener *listener, void *data) {
static void handle_tool_button(struct wl_listener *listener, void *data) {
struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_button);
- struct wlr_event_tablet_tool_button *event = data;
- cursor_handle_activity_from_device(cursor, event->device);
+ struct wlr_tablet_tool_button_event *event = data;
+ cursor_handle_activity_from_device(cursor, &event->tablet->base);
struct sway_tablet_tool *sway_tool = event->tool->data;
if (!sway_tool) {
@@ -819,14 +824,14 @@ static void handle_tool_button(struct wl_listener *listener, void *data) {
switch (event->state) {
case WLR_BUTTON_PRESSED:
if (cursor->tool_buttons == 0) {
- dispatch_cursor_button(cursor, event->device,
+ dispatch_cursor_button(cursor, &event->tablet->base,
event->time_msec, BTN_RIGHT, event->state);
}
cursor->tool_buttons++;
break;
case WLR_BUTTON_RELEASED:
if (cursor->tool_buttons == 1) {
- dispatch_cursor_button(cursor, event->device,
+ dispatch_cursor_button(cursor, &event->tablet->base,
event->time_msec, BTN_RIGHT, event->state);
}
cursor->tool_buttons--;
@@ -923,65 +928,68 @@ static void handle_request_pointer_set_cursor(struct wl_listener *listener,
event->hotspot_y, focused_client);
}
+static void handle_pointer_hold_begin(struct wl_listener *listener, void *data) {
+ struct sway_cursor *cursor = wl_container_of(
+ listener, cursor, hold_begin);
+ struct wlr_pointer_hold_begin_event *event = data;
+ cursor_handle_activity_from_device(cursor, &event->pointer->base);
+ seatop_hold_begin(cursor->seat, event);
+}
+
+static void handle_pointer_hold_end(struct wl_listener *listener, void *data) {
+ struct sway_cursor *cursor = wl_container_of(
+ listener, cursor, hold_end);
+ struct wlr_pointer_hold_end_event *event = data;
+ cursor_handle_activity_from_device(cursor, &event->pointer->base);
+ seatop_hold_end(cursor->seat, event);
+}
+
static void handle_pointer_pinch_begin(struct wl_listener *listener, void *data) {
struct sway_cursor *cursor = wl_container_of(
listener, cursor, pinch_begin);
- struct wlr_event_pointer_pinch_begin *event = data;
- cursor_handle_activity_from_device(cursor, event->device);
- wlr_pointer_gestures_v1_send_pinch_begin(
- cursor->pointer_gestures, cursor->seat->wlr_seat,
- event->time_msec, event->fingers);
+ struct wlr_pointer_pinch_begin_event *event = data;
+ cursor_handle_activity_from_device(cursor, &event->pointer->base);
+ seatop_pinch_begin(cursor->seat, event);
}
static void handle_pointer_pinch_update(struct wl_listener *listener, void *data) {
struct sway_cursor *cursor = wl_container_of(
listener, cursor, pinch_update);
- struct wlr_event_pointer_pinch_update *event = data;
- cursor_handle_activity_from_device(cursor, event->device);
- wlr_pointer_gestures_v1_send_pinch_update(
- cursor->pointer_gestures, cursor->seat->wlr_seat,
- event->time_msec, event->dx, event->dy,
- event->scale, event->rotation);
+ struct wlr_pointer_pinch_update_event *event = data;
+ cursor_handle_activity_from_device(cursor, &event->pointer->base);
+ seatop_pinch_update(cursor->seat, event);
}
static void handle_pointer_pinch_end(struct wl_listener *listener, void *data) {
struct sway_cursor *cursor = wl_container_of(
listener, cursor, pinch_end);
- struct wlr_event_pointer_pinch_end *event = data;
- cursor_handle_activity_from_device(cursor, event->device);
- wlr_pointer_gestures_v1_send_pinch_end(
- cursor->pointer_gestures, cursor->seat->wlr_seat,
- event->time_msec, event->cancelled);
+ struct wlr_pointer_pinch_end_event *event = data;
+ cursor_handle_activity_from_device(cursor, &event->pointer->base);
+ seatop_pinch_end(cursor->seat, event);
}
static void handle_pointer_swipe_begin(struct wl_listener *listener, void *data) {
struct sway_cursor *cursor = wl_container_of(
listener, cursor, swipe_begin);
- struct wlr_event_pointer_swipe_begin *event = data;
- cursor_handle_activity_from_device(cursor, event->device);
- wlr_pointer_gestures_v1_send_swipe_begin(
- cursor->pointer_gestures, cursor->seat->wlr_seat,
- event->time_msec, event->fingers);
+ struct wlr_pointer_swipe_begin_event *event = data;
+ cursor_handle_activity_from_device(cursor, &event->pointer->base);
+ seatop_swipe_begin(cursor->seat, event);
}
static void handle_pointer_swipe_update(struct wl_listener *listener, void *data) {
struct sway_cursor *cursor = wl_container_of(
listener, cursor, swipe_update);
- struct wlr_event_pointer_swipe_update *event = data;
- cursor_handle_activity_from_device(cursor, event->device);
- wlr_pointer_gestures_v1_send_swipe_update(
- cursor->pointer_gestures, cursor->seat->wlr_seat,
- event->time_msec, event->dx, event->dy);
+ struct wlr_pointer_swipe_update_event *event = data;
+ cursor_handle_activity_from_device(cursor, &event->pointer->base);
+ seatop_swipe_update(cursor->seat, event);
}
static void handle_pointer_swipe_end(struct wl_listener *listener, void *data) {
struct sway_cursor *cursor = wl_container_of(
listener, cursor, swipe_end);
- struct wlr_event_pointer_swipe_end *event = data;
- cursor_handle_activity_from_device(cursor, event->device);
- wlr_pointer_gestures_v1_send_swipe_end(
- cursor->pointer_gestures, cursor->seat->wlr_seat,
- event->time_msec, event->cancelled);
+ struct wlr_pointer_swipe_end_event *event = data;
+ cursor_handle_activity_from_device(cursor, &event->pointer->base);
+ seatop_swipe_end(cursor->seat, event);
}
static void handle_image_surface_destroy(struct wl_listener *listener,
@@ -1055,6 +1063,8 @@ void sway_cursor_destroy(struct sway_cursor *cursor) {
wl_event_source_remove(cursor->hide_source);
wl_list_remove(&cursor->image_surface_destroy.link);
+ wl_list_remove(&cursor->hold_begin.link);
+ wl_list_remove(&cursor->hold_end.link);
wl_list_remove(&cursor->pinch_begin.link);
wl_list_remove(&cursor->pinch_update.link);
wl_list_remove(&cursor->pinch_end.link);
@@ -1104,19 +1114,27 @@ struct sway_cursor *sway_cursor_create(struct sway_seat *seat) {
wl_list_init(&cursor->image_surface_destroy.link);
cursor->image_surface_destroy.notify = handle_image_surface_destroy;
+ // gesture events
cursor->pointer_gestures = wlr_pointer_gestures_v1_create(server.wl_display);
- cursor->pinch_begin.notify = handle_pointer_pinch_begin;
+
+ wl_signal_add(&wlr_cursor->events.hold_begin, &cursor->hold_begin);
+ cursor->hold_begin.notify = handle_pointer_hold_begin;
+ wl_signal_add(&wlr_cursor->events.hold_end, &cursor->hold_end);
+ cursor->hold_end.notify = handle_pointer_hold_end;
+
wl_signal_add(&wlr_cursor->events.pinch_begin, &cursor->pinch_begin);
- cursor->pinch_update.notify = handle_pointer_pinch_update;
+ cursor->pinch_begin.notify = handle_pointer_pinch_begin;
wl_signal_add(&wlr_cursor->events.pinch_update, &cursor->pinch_update);
- cursor->pinch_end.notify = handle_pointer_pinch_end;
+ cursor->pinch_update.notify = handle_pointer_pinch_update;
wl_signal_add(&wlr_cursor->events.pinch_end, &cursor->pinch_end);
- cursor->swipe_begin.notify = handle_pointer_swipe_begin;
+ cursor->pinch_end.notify = handle_pointer_pinch_end;
+
wl_signal_add(&wlr_cursor->events.swipe_begin, &cursor->swipe_begin);
- cursor->swipe_update.notify = handle_pointer_swipe_update;
+ cursor->swipe_begin.notify = handle_pointer_swipe_begin;
wl_signal_add(&wlr_cursor->events.swipe_update, &cursor->swipe_update);
- cursor->swipe_end.notify = handle_pointer_swipe_end;
+ cursor->swipe_update.notify = handle_pointer_swipe_update;
wl_signal_add(&wlr_cursor->events.swipe_end, &cursor->swipe_end);
+ cursor->swipe_end.notify = handle_pointer_swipe_end;
// input events
wl_signal_add(&wlr_cursor->events.motion, &cursor->motion);
@@ -1354,12 +1372,9 @@ void handle_pointer_constraint(struct wl_listener *listener, void *data) {
sway_constraint->destroy.notify = handle_constraint_destroy;
wl_signal_add(&constraint->events.destroy, &sway_constraint->destroy);
- struct sway_node *focus = seat_get_focus(seat);
- if (focus && node_is_view(focus)) {
- struct wlr_surface *surface = focus->sway_container->view->surface;
- if (surface == constraint->surface) {
- sway_cursor_constrain(seat->cursor, constraint);
- }
+ struct wlr_surface *surface = seat->wlr_seat->keyboard_state.focused_surface;
+ if (surface && surface == constraint->surface) {
+ sway_cursor_constrain(seat->cursor, constraint);
}
}
diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c
index f04a8ce0..39f4b795 100644
--- a/sway/input/input-manager.c
+++ b/sway/input/input-manager.c
@@ -236,7 +236,7 @@ static void handle_new_input(struct wl_listener *listener, void *data) {
apply_input_type_config(input_device);
- sway_input_configure_libinput_device(input_device);
+ bool config_changed = sway_input_configure_libinput_device(input_device);
wl_signal_add(&device->events.destroy, &input_device->device_destroy);
input_device->device_destroy.notify = handle_device_destroy;
@@ -274,6 +274,10 @@ static void handle_new_input(struct wl_listener *listener, void *data) {
}
ipc_event_input("added", input_device);
+
+ if (config_changed) {
+ ipc_event_input("libinput_config", input_device);
+ }
}
static void handle_inhibit_activate(struct wl_listener *listener, void *data) {
@@ -289,6 +293,10 @@ static void handle_inhibit_deactivate(struct wl_listener *listener, void *data)
struct sway_input_manager *input_manager = wl_container_of(
listener, input_manager, inhibit_deactivate);
struct sway_seat *seat;
+ if (server.session_lock.locked) {
+ // Don't deactivate the grab of a screenlocker
+ return;
+ }
wl_list_for_each(seat, &input_manager->seats, link) {
seat_set_exclusive_client(seat, NULL);
struct sway_node *previous = seat_get_focus(seat);
@@ -377,7 +385,7 @@ void handle_virtual_keyboard(struct wl_listener *listener, void *data) {
struct sway_input_manager *input_manager =
wl_container_of(listener, input_manager, virtual_keyboard_new);
struct wlr_virtual_keyboard_v1 *keyboard = data;
- struct wlr_input_device *device = &keyboard->input_device;
+ struct wlr_input_device *device = &keyboard->keyboard.base;
// TODO: Amend protocol to allow NULL seat
struct sway_seat *seat = keyboard->seat ?
@@ -410,7 +418,7 @@ void handle_virtual_pointer(struct wl_listener *listener, void *data) {
wl_container_of(listener, input_manager, virtual_pointer_new);
struct wlr_virtual_pointer_v1_new_pointer_event *event = data;
struct wlr_virtual_pointer_v1 *pointer = event->new_pointer;
- struct wlr_input_device *device = &pointer->input_device;
+ struct wlr_input_device *device = &pointer->pointer.base;
struct sway_seat *seat = event->suggested_seat ?
input_manager_sway_seat_from_wlr_seat(event->suggested_seat) :
@@ -524,11 +532,14 @@ static void retranslate_keysyms(struct input_config *input_config) {
static void input_manager_configure_input(
struct sway_input_device *input_device) {
- sway_input_configure_libinput_device(input_device);
+ bool config_changed = sway_input_configure_libinput_device(input_device);
struct sway_seat *seat = NULL;
wl_list_for_each(seat, &server.input->seats, link) {
seat_configure_device(seat, input_device);
}
+ if (config_changed) {
+ ipc_event_input("libinput_config", input_device);
+ }
}
void input_manager_configure_all_inputs(void) {
@@ -564,6 +575,13 @@ void input_manager_reset_input(struct sway_input_device *input_device) {
}
void input_manager_reset_all_inputs(void) {
+ // Set the active keyboard to NULL to avoid spamming configuration updates
+ // for all keyboard devices.
+ struct sway_seat *seat;
+ wl_list_for_each(seat, &server.input->seats, link) {
+ wlr_seat_set_keyboard(seat->wlr_seat, NULL);
+ }
+
struct sway_input_device *input_device = NULL;
wl_list_for_each(input_device, &server.input->devices, link) {
input_manager_reset_input(input_device);
@@ -572,7 +590,6 @@ void input_manager_reset_all_inputs(void) {
// If there is at least one keyboard using the default keymap, repeat delay,
// and repeat rate, then it is possible that there is a keyboard group that
// need their keyboard disarmed.
- struct sway_seat *seat;
wl_list_for_each(seat, &server.input->seats, link) {
struct sway_keyboard_group *group;
wl_list_for_each(group, &seat->keyboard_groups, link) {
diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c
index f258ac7d..c5a646c4 100644
--- a/sway/input/keyboard.c
+++ b/sway/input/keyboard.c
@@ -291,14 +291,12 @@ static bool keyboard_execute_compositor_binding(struct sway_keyboard *keyboard,
static size_t keyboard_keysyms_translated(struct sway_keyboard *keyboard,
xkb_keycode_t keycode, const xkb_keysym_t **keysyms,
uint32_t *modifiers) {
- struct wlr_input_device *device =
- keyboard->seat_device->input_device->wlr_device;
- *modifiers = wlr_keyboard_get_modifiers(device->keyboard);
+ *modifiers = wlr_keyboard_get_modifiers(keyboard->wlr);
xkb_mod_mask_t consumed = xkb_state_key_get_consumed_mods2(
- device->keyboard->xkb_state, keycode, XKB_CONSUMED_MODE_XKB);
+ keyboard->wlr->xkb_state, keycode, XKB_CONSUMED_MODE_XKB);
*modifiers = *modifiers & ~consumed;
- return xkb_state_key_get_syms(device->keyboard->xkb_state,
+ return xkb_state_key_get_syms(keyboard->wlr->xkb_state,
keycode, keysyms);
}
@@ -314,13 +312,11 @@ static size_t keyboard_keysyms_translated(struct sway_keyboard *keyboard,
static size_t keyboard_keysyms_raw(struct sway_keyboard *keyboard,
xkb_keycode_t keycode, const xkb_keysym_t **keysyms,
uint32_t *modifiers) {
- struct wlr_input_device *device =
- keyboard->seat_device->input_device->wlr_device;
- *modifiers = wlr_keyboard_get_modifiers(device->keyboard);
+ *modifiers = wlr_keyboard_get_modifiers(keyboard->wlr);
xkb_layout_index_t layout_index = xkb_state_key_get_layout(
- device->keyboard->xkb_state, keycode);
- return xkb_keymap_key_get_syms_by_level(device->keyboard->keymap,
+ keyboard->wlr->xkb_state, keycode);
+ return xkb_keymap_key_get_syms_by_level(keyboard->wlr->keymap,
keycode, layout_index, 0, keysyms);
}
@@ -360,8 +356,7 @@ static void update_keyboard_state(struct sway_keyboard *keyboard,
keyinfo->keycode, &keyinfo->translated_keysyms,
&keyinfo->translated_modifiers);
- keyinfo->code_modifiers = wlr_keyboard_get_modifiers(
- keyboard->seat_device->input_device->wlr_device->keyboard);
+ keyinfo->code_modifiers = wlr_keyboard_get_modifiers(keyboard->wlr);
// Update shortcut model keyinfo
update_shortcut_state(&keyboard->state_keycodes, raw_keycode, keystate,
@@ -401,15 +396,16 @@ static struct wlr_input_method_keyboard_grab_v2 *keyboard_get_im_grab(
}
static void handle_key_event(struct sway_keyboard *keyboard,
- struct wlr_event_keyboard_key *event) {
+ struct wlr_keyboard_key_event *event) {
struct sway_seat *seat = keyboard->seat_device->sway_seat;
struct wlr_seat *wlr_seat = seat->wlr_seat;
struct wlr_input_device *wlr_device =
keyboard->seat_device->input_device->wlr_device;
char *device_identifier = input_device_get_identifier(wlr_device);
- bool exact_identifier = wlr_device->keyboard->group != NULL;
+ bool exact_identifier = keyboard->wlr->group != NULL;
seat_idle_notify_activity(seat, IDLE_SOURCE_KEYBOARD);
- bool input_inhibited = seat->exclusive_client != NULL;
+ bool input_inhibited = seat->exclusive_client != NULL ||
+ server.session_lock.locked;
struct sway_keyboard_shortcuts_inhibitor *sway_inhibitor =
keyboard_shortcuts_inhibitor_get_for_focused_surface(seat);
bool shortcuts_inhibited = sway_inhibitor && sway_inhibitor->inhibitor->active;
@@ -477,10 +473,10 @@ static void handle_key_event(struct sway_keyboard *keyboard,
// Set up (or clear) keyboard repeat for a pressed binding. Since the
// binding may remove the keyboard, the timer needs to be updated first
if (binding && !(binding->flags & BINDING_NOREPEAT) &&
- wlr_device->keyboard->repeat_info.delay > 0) {
+ keyboard->wlr->repeat_info.delay > 0) {
keyboard->repeat_binding = binding;
if (wl_event_source_timer_update(keyboard->key_repeat_source,
- wlr_device->keyboard->repeat_info.delay) < 0) {
+ keyboard->wlr->repeat_info.delay) < 0) {
sway_log(SWAY_DEBUG, "failed to set key repeat timer");
}
} else if (keyboard->repeat_binding) {
@@ -492,7 +488,7 @@ static void handle_key_event(struct sway_keyboard *keyboard,
handled = true;
}
- if (!handled && wlr_device->keyboard->group) {
+ if (!handled && keyboard->wlr->group) {
// Only handle device specific bindings for keyboards in a group
free(device_identifier);
return;
@@ -517,7 +513,7 @@ static void handle_key_event(struct sway_keyboard *keyboard,
&keyboard->state_pressed_sent, event->keycode,
event->state, keyinfo.keycode, 0);
if (pressed_sent) {
- wlr_seat_set_keyboard(wlr_seat, wlr_device);
+ wlr_seat_set_keyboard(wlr_seat, keyboard->wlr);
wlr_seat_keyboard_notify_key(wlr_seat, event->time_msec,
event->keycode, event->state);
handled = true;
@@ -528,8 +524,7 @@ static void handle_key_event(struct sway_keyboard *keyboard,
struct wlr_input_method_keyboard_grab_v2 *kb_grab = keyboard_get_im_grab(keyboard);
if (kb_grab) {
- wlr_input_method_keyboard_grab_v2_set_keyboard(kb_grab,
- wlr_device->keyboard);
+ wlr_input_method_keyboard_grab_v2_set_keyboard(kb_grab, keyboard->wlr);
wlr_input_method_keyboard_grab_v2_send_key(kb_grab,
event->time_msec, event->keycode, event->state);
handled = true;
@@ -542,7 +537,7 @@ static void handle_key_event(struct sway_keyboard *keyboard,
update_shortcut_state(
&keyboard->state_pressed_sent, event->keycode, event->state,
keyinfo.keycode, 0);
- wlr_seat_set_keyboard(wlr_seat, wlr_device);
+ wlr_seat_set_keyboard(wlr_seat, keyboard->wlr);
wlr_seat_keyboard_notify_key(wlr_seat, event->time_msec,
event->keycode, event->state);
}
@@ -618,14 +613,12 @@ static void handle_keyboard_group_leave(struct wl_listener *listener,
}
static int handle_keyboard_repeat(void *data) {
- struct sway_keyboard *keyboard = (struct sway_keyboard *)data;
- struct wlr_keyboard *wlr_device =
- keyboard->seat_device->input_device->wlr_device->keyboard;
+ struct sway_keyboard *keyboard = data;
if (keyboard->repeat_binding) {
- if (wlr_device->repeat_info.rate > 0) {
+ if (keyboard->wlr->repeat_info.rate > 0) {
// We queue the next event first, as the command might cancel it
if (wl_event_source_timer_update(keyboard->key_repeat_source,
- 1000 / wlr_device->repeat_info.rate) < 0) {
+ 1000 / keyboard->wlr->repeat_info.rate) < 0) {
sway_log(SWAY_DEBUG, "failed to update key repeat timer");
}
}
@@ -658,31 +651,28 @@ static void determine_bar_visibility(uint32_t modifiers) {
}
static void handle_modifier_event(struct sway_keyboard *keyboard) {
- struct wlr_input_device *wlr_device =
- keyboard->seat_device->input_device->wlr_device;
- if (!wlr_device->keyboard->group) {
+ if (!keyboard->wlr->group) {
struct wlr_input_method_keyboard_grab_v2 *kb_grab = keyboard_get_im_grab(keyboard);
if (kb_grab) {
- wlr_input_method_keyboard_grab_v2_set_keyboard(kb_grab,
- wlr_device->keyboard);
+ wlr_input_method_keyboard_grab_v2_set_keyboard(kb_grab, keyboard->wlr);
wlr_input_method_keyboard_grab_v2_send_modifiers(kb_grab,
- &wlr_device->keyboard->modifiers);
+ &keyboard->wlr->modifiers);
} else {
struct wlr_seat *wlr_seat = keyboard->seat_device->sway_seat->wlr_seat;
- wlr_seat_set_keyboard(wlr_seat, wlr_device);
+ wlr_seat_set_keyboard(wlr_seat, keyboard->wlr);
wlr_seat_keyboard_notify_modifiers(wlr_seat,
- &wlr_device->keyboard->modifiers);
+ &keyboard->wlr->modifiers);
}
- uint32_t modifiers = wlr_keyboard_get_modifiers(wlr_device->keyboard);
+ uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->wlr);
determine_bar_visibility(modifiers);
}
- if (wlr_device->keyboard->modifiers.group != keyboard->effective_layout) {
- keyboard->effective_layout = wlr_device->keyboard->modifiers.group;
+ if (keyboard->wlr->modifiers.group != keyboard->effective_layout) {
+ keyboard->effective_layout = keyboard->wlr->modifiers.group;
- if (!wlr_keyboard_group_from_wlr_keyboard(wlr_device->keyboard)) {
+ if (!wlr_keyboard_group_from_wlr_keyboard(keyboard->wlr)) {
ipc_event_input("xkb_layout", keyboard->seat_device->input_device);
}
}
@@ -711,6 +701,7 @@ struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat,
}
keyboard->seat_device = device;
+ keyboard->wlr = wlr_keyboard_from_input_device(device->input_device->wlr_device);
device->keyboard = keyboard;
wl_list_init(&keyboard->keyboard_key.link);
@@ -819,13 +810,12 @@ static void destroy_empty_wlr_keyboard_group(void *data) {
static void sway_keyboard_group_remove(struct sway_keyboard *keyboard) {
struct sway_input_device *device = keyboard->seat_device->input_device;
- struct wlr_keyboard *wlr_keyboard = device->wlr_device->keyboard;
- struct wlr_keyboard_group *wlr_group = wlr_keyboard->group;
+ struct wlr_keyboard_group *wlr_group = keyboard->wlr->group;
sway_log(SWAY_DEBUG, "Removing keyboard %s from group %p",
device->identifier, wlr_group);
- wlr_keyboard_group_remove_keyboard(wlr_keyboard->group, wlr_keyboard);
+ wlr_keyboard_group_remove_keyboard(keyboard->wlr->group, keyboard->wlr);
if (wl_list_empty(&wlr_group->devices)) {
sway_log(SWAY_DEBUG, "Destroying empty keyboard group %p",
@@ -850,9 +840,7 @@ static void sway_keyboard_group_remove(struct sway_keyboard *keyboard) {
}
static void sway_keyboard_group_remove_invalid(struct sway_keyboard *keyboard) {
- struct sway_input_device *device = keyboard->seat_device->input_device;
- struct wlr_keyboard *wlr_keyboard = device->wlr_device->keyboard;
- if (!wlr_keyboard->group) {
+ if (!keyboard->wlr->group) {
return;
}
@@ -868,7 +856,7 @@ static void sway_keyboard_group_remove_invalid(struct sway_keyboard *keyboard) {
break;
case KEYBOARD_GROUP_DEFAULT: /* fallthrough */
case KEYBOARD_GROUP_SMART:;
- struct wlr_keyboard_group *group = wlr_keyboard->group;
+ struct wlr_keyboard_group *group = keyboard->wlr->group;
if (!wlr_keyboard_keymaps_match(keyboard->keymap, group->keyboard.keymap) ||
!repeat_info_match(keyboard, &group->keyboard)) {
sway_keyboard_group_remove(keyboard);
@@ -879,7 +867,6 @@ static void sway_keyboard_group_remove_invalid(struct sway_keyboard *keyboard) {
static void sway_keyboard_group_add(struct sway_keyboard *keyboard) {
struct sway_input_device *device = keyboard->seat_device->input_device;
- struct wlr_keyboard *wlr_keyboard = device->wlr_device->keyboard;
struct sway_seat *seat = keyboard->seat_device->sway_seat;
struct seat_config *sc = seat_get_config(seat);
@@ -911,7 +898,7 @@ static void sway_keyboard_group_add(struct sway_keyboard *keyboard) {
repeat_info_match(keyboard, &wlr_group->keyboard)) {
sway_log(SWAY_DEBUG, "Adding keyboard %s to group %p",
device->identifier, wlr_group);
- wlr_keyboard_group_add_keyboard(wlr_group, wlr_keyboard);
+ wlr_keyboard_group_add_keyboard(wlr_group, keyboard->wlr);
return;
}
break;
@@ -950,7 +937,7 @@ static void sway_keyboard_group_add(struct sway_keyboard *keyboard) {
goto cleanup;
}
sway_group->seat_device->input_device->wlr_device =
- sway_group->wlr_group->input_device;
+ &sway_group->wlr_group->keyboard.base;
if (!sway_keyboard_create(seat, sway_group->seat_device)) {
sway_log(SWAY_ERROR, "Failed to allocate sway_keyboard for group");
@@ -959,7 +946,7 @@ static void sway_keyboard_group_add(struct sway_keyboard *keyboard) {
sway_log(SWAY_DEBUG, "Adding keyboard %s to group %p",
device->identifier, sway_group->wlr_group);
- wlr_keyboard_group_add_keyboard(sway_group->wlr_group, wlr_keyboard);
+ wlr_keyboard_group_add_keyboard(sway_group->wlr_group, keyboard->wlr);
wl_list_insert(&seat->keyboard_groups, &sway_group->link);
@@ -991,10 +978,8 @@ cleanup:
void sway_keyboard_configure(struct sway_keyboard *keyboard) {
struct input_config *input_config =
input_device_get_config(keyboard->seat_device->input_device);
- struct wlr_input_device *wlr_device =
- keyboard->seat_device->input_device->wlr_device;
- if (!sway_assert(!wlr_keyboard_group_from_wlr_keyboard(wlr_device->keyboard),
+ if (!sway_assert(!wlr_keyboard_group_from_wlr_keyboard(keyboard->wlr),
"sway_keyboard_configure should not be called with a "
"keyboard group's keyboard")) {
return;
@@ -1036,11 +1021,11 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) {
sway_keyboard_group_remove_invalid(keyboard);
- wlr_keyboard_set_keymap(wlr_device->keyboard, keyboard->keymap);
- wlr_keyboard_set_repeat_info(wlr_device->keyboard,
+ wlr_keyboard_set_keymap(keyboard->wlr, keyboard->keymap);
+ wlr_keyboard_set_repeat_info(keyboard->wlr,
keyboard->repeat_rate, keyboard->repeat_delay);
- if (!wlr_device->keyboard->group) {
+ if (!keyboard->wlr->group) {
sway_keyboard_group_add(keyboard);
}
@@ -1060,40 +1045,42 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) {
}
}
if (locked_mods) {
- wlr_keyboard_notify_modifiers(wlr_device->keyboard, 0, 0,
+ wlr_keyboard_notify_modifiers(keyboard->wlr, 0, 0,
locked_mods, 0);
uint32_t leds = 0;
for (uint32_t i = 0; i < WLR_LED_COUNT; ++i) {
- if (xkb_state_led_index_is_active(
- wlr_device->keyboard->xkb_state,
- wlr_device->keyboard->led_indexes[i])) {
+ if (xkb_state_led_index_is_active(keyboard->wlr->xkb_state,
+ keyboard->wlr->led_indexes[i])) {
leds |= (1 << i);
}
}
- if (wlr_device->keyboard->group) {
- wlr_keyboard_led_update(
- &wlr_device->keyboard->group->keyboard, leds);
+ if (keyboard->wlr->group) {
+ wlr_keyboard_led_update(&keyboard->wlr->group->keyboard, leds);
} else {
- wlr_keyboard_led_update(wlr_device->keyboard, leds);
+ wlr_keyboard_led_update(keyboard->wlr, leds);
}
}
} else {
xkb_keymap_unref(keymap);
sway_keyboard_group_remove_invalid(keyboard);
- if (!wlr_device->keyboard->group) {
+ if (!keyboard->wlr->group) {
sway_keyboard_group_add(keyboard);
}
}
+ // If the seat has no active keyboard, set this one
struct wlr_seat *seat = keyboard->seat_device->sway_seat->wlr_seat;
- wlr_seat_set_keyboard(seat, wlr_device);
+ struct wlr_keyboard *current_keyboard = seat->keyboard_state.keyboard;
+ if (current_keyboard == NULL) {
+ wlr_seat_set_keyboard(seat, keyboard->wlr);
+ }
wl_list_remove(&keyboard->keyboard_key.link);
- wl_signal_add(&wlr_device->keyboard->events.key, &keyboard->keyboard_key);
+ wl_signal_add(&keyboard->wlr->events.key, &keyboard->keyboard_key);
keyboard->keyboard_key.notify = handle_keyboard_key;
wl_list_remove(&keyboard->keyboard_modifiers.link);
- wl_signal_add(&wlr_device->keyboard->events.modifiers,
+ wl_signal_add(&keyboard->wlr->events.modifiers,
&keyboard->keyboard_modifiers);
keyboard->keyboard_modifiers.notify = handle_keyboard_modifiers;
@@ -1110,12 +1097,11 @@ void sway_keyboard_destroy(struct sway_keyboard *keyboard) {
if (!keyboard) {
return;
}
- if (keyboard->seat_device->input_device->wlr_device->keyboard->group) {
+ if (keyboard->wlr->group) {
sway_keyboard_group_remove(keyboard);
}
struct wlr_seat *wlr_seat = keyboard->seat_device->sway_seat->wlr_seat;
- struct sway_input_device *device = keyboard->seat_device->input_device;
- if (wlr_seat_get_keyboard(wlr_seat) == device->wlr_device->keyboard) {
+ if (wlr_seat_get_keyboard(wlr_seat) == keyboard->wlr) {
wlr_seat_set_keyboard(wlr_seat, NULL);
}
if (keyboard->keymap) {
diff --git a/sway/input/libinput.c b/sway/input/libinput.c
index 3c0f359d..53019301 100644
--- a/sway/input/libinput.c
+++ b/sway/input/libinput.c
@@ -166,6 +166,16 @@ static bool set_dwt(struct libinput_device *device, bool dwt) {
return true;
}
+static bool set_dwtp(struct libinput_device *device, bool dwtp) {
+ if (!libinput_device_config_dwtp_is_available(device) ||
+ libinput_device_config_dwtp_get_enabled(device) == dwtp) {
+ return false;
+ }
+ sway_log(SWAY_DEBUG, "dwtp_set_enabled(%d)", dwtp);
+ log_status(libinput_device_config_dwtp_set_enabled(device, dwtp));
+ return true;
+}
+
static bool set_calibration_matrix(struct libinput_device *dev, float mat[6]) {
if (!libinput_device_config_calibration_has_matrix(dev)) {
return false;
@@ -187,10 +197,10 @@ static bool set_calibration_matrix(struct libinput_device *dev, float mat[6]) {
return changed;
}
-void sway_input_configure_libinput_device(struct sway_input_device *input_device) {
+bool sway_input_configure_libinput_device(struct sway_input_device *input_device) {
struct input_config *ic = input_device_get_config(input_device);
if (!ic || !wlr_input_device_is_libinput(input_device->wlr_device)) {
- return;
+ return false;
}
struct libinput_device *device =
@@ -255,13 +265,14 @@ void sway_input_configure_libinput_device(struct sway_input_device *input_device
if (ic->dwt != INT_MIN) {
changed |= set_dwt(device, ic->dwt);
}
+ if (ic->dwtp != INT_MIN) {
+ changed |= set_dwtp(device, ic->dwtp);
+ }
if (ic->calibration_matrix.configured) {
changed |= set_calibration_matrix(device, ic->calibration_matrix.matrix);
}
- if (changed) {
- ipc_event_input("libinput_config", input_device);
- }
+ return changed;
}
void sway_input_reset_libinput_device(struct sway_input_device *input_device) {
@@ -304,6 +315,8 @@ void sway_input_reset_libinput_device(struct sway_input_device *input_device) {
libinput_device_config_scroll_get_default_button(device));
changed |= set_dwt(device,
libinput_device_config_dwt_get_default_enabled(device));
+ changed |= set_dwtp(device,
+ libinput_device_config_dwtp_get_default_enabled(device));
float matrix[6];
libinput_device_config_calibration_get_default_matrix(device, matrix);
diff --git a/sway/input/seat.c b/sway/input/seat.c
index ce933b66..646f3866 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -7,10 +7,12 @@
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_idle.h>
+#include <wlr/types/wlr_idle_notify_v1.h>
#include <wlr/types/wlr_keyboard_group.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_primary_selection.h>
#include <wlr/types/wlr_tablet_v2.h>
+#include <wlr/types/wlr_touch.h>
#include <wlr/types/wlr_xcursor_manager.h>
#include "config.h"
#include "list.h"
@@ -42,6 +44,7 @@ static void seat_device_destroy(struct sway_seat_device *seat_device) {
sway_keyboard_destroy(seat_device->keyboard);
sway_tablet_destroy(seat_device->tablet);
sway_tablet_pad_destroy(seat_device->tablet_pad);
+ sway_switch_destroy(seat_device->switch_device);
wlr_cursor_detach_input_device(seat_device->sway_seat->cursor->cursor,
seat_device->input_device->wlr_device);
wl_list_remove(&seat_device->link);
@@ -110,6 +113,7 @@ void seat_idle_notify_activity(struct sway_seat *seat,
}
if ((source & mask) > 0) {
wlr_idle_notify_activity(server.idle, seat->wlr_seat);
+ wlr_idle_notifier_v1_notify_activity(server.idle_notifier_v1, seat->wlr_seat);
}
}
@@ -140,7 +144,7 @@ static struct sway_keyboard *sway_keyboard_for_wlr_keyboard(
if (input_device->wlr_device->type != WLR_INPUT_DEVICE_KEYBOARD) {
continue;
}
- if (input_device->wlr_device->keyboard == wlr_keyboard) {
+ if (input_device->wlr_device == &wlr_keyboard->base) {
return seat_device->keyboard;
}
}
@@ -148,7 +152,7 @@ static struct sway_keyboard *sway_keyboard_for_wlr_keyboard(
wl_list_for_each(group, &seat->keyboard_groups, link) {
struct sway_input_device *input_device =
group->seat_device->input_device;
- if (input_device->wlr_device->keyboard == wlr_keyboard) {
+ if (input_device->wlr_device == &wlr_keyboard->base) {
return group->seat_device->keyboard;
}
}
@@ -245,7 +249,7 @@ static void handle_seat_node_destroy(struct wl_listener *listener, void *data) {
seat_node_destroy(seat_node);
// If an unmanaged or layer surface is focused when an output gets
// disabled and an empty workspace on the output was focused by the
- // seat, the seat needs to refocus it's focus inactive to update the
+ // seat, the seat needs to refocus its focus inactive to update the
// value of seat->workspace.
if (seat->workspace == node->sway_workspace) {
struct sway_node *node = seat_get_focus_inactive(seat, &root->node);
@@ -378,8 +382,8 @@ void drag_icon_update_position(struct sway_drag_icon *icon) {
case WLR_DRAG_GRAB_KEYBOARD:
return;
case WLR_DRAG_GRAB_KEYBOARD_POINTER:
- icon->x = cursor->x;
- icon->y = cursor->y;
+ icon->x = cursor->x + wlr_icon->surface->sx;
+ icon->y = cursor->y + wlr_icon->surface->sy;
break;
case WLR_DRAG_GRAB_KEYBOARD_TOUCH:;
struct wlr_touch_point *point =
@@ -387,8 +391,8 @@ void drag_icon_update_position(struct sway_drag_icon *icon) {
if (point == NULL) {
return;
}
- icon->x = seat->touch_x;
- icon->y = seat->touch_y;
+ icon->x = seat->touch_x + wlr_icon->surface->sx;
+ icon->y = seat->touch_y + wlr_icon->surface->sy;
}
drag_icon_damage_whole(icon);
@@ -724,14 +728,25 @@ static void seat_apply_input_config(struct sway_seat *seat,
ic == NULL ? MAPPED_TO_DEFAULT : ic->mapped_to;
switch (mapped_to) {
- case MAPPED_TO_DEFAULT:
+ case MAPPED_TO_DEFAULT:;
/*
* If the wlroots backend provides an output name, use that.
*
- * Otherwise, try to map built-in touch and tablet tool devices to the
+ * Otherwise, try to map built-in touch and pointer devices to the
* built-in output.
*/
- mapped_to_output = sway_device->input_device->wlr_device->output_name;
+ struct wlr_input_device *dev = sway_device->input_device->wlr_device;
+ switch (dev->type) {
+ case WLR_INPUT_DEVICE_POINTER:
+ mapped_to_output = wlr_pointer_from_input_device(dev)->output_name;
+ break;
+ case WLR_INPUT_DEVICE_TOUCH:
+ mapped_to_output = wlr_touch_from_input_device(dev)->output_name;
+ break;
+ default:
+ mapped_to_output = NULL;
+ break;
+ }
if (mapped_to_output == NULL && is_touch_or_tablet_tool(sway_device) &&
sway_libinput_device_is_builtin(sway_device->input_device)) {
mapped_to_output = get_builtin_output_name();
@@ -799,13 +814,22 @@ static void seat_configure_keyboard(struct sway_seat *seat,
sway_keyboard_create(seat, seat_device);
}
sway_keyboard_configure(seat_device->keyboard);
- wlr_seat_set_keyboard(seat->wlr_seat,
- seat_device->input_device->wlr_device);
- struct sway_node *focus = seat_get_focus(seat);
- if (focus && node_is_view(focus)) {
- // force notify reenter to pick up the new configuration
+
+ // We only need to update the current keyboard, as the rest will be updated
+ // as they are activated.
+ struct wlr_keyboard *wlr_keyboard =
+ wlr_keyboard_from_input_device(seat_device->input_device->wlr_device);
+ struct wlr_keyboard *current_keyboard = seat->wlr_seat->keyboard_state.keyboard;
+ if (wlr_keyboard != current_keyboard) {
+ return;
+ }
+
+ // force notify reenter to pick up the new configuration. This reuses
+ // the current focused surface to avoid breaking input grabs.
+ struct wlr_surface *surface = seat->wlr_seat->keyboard_state.focused_surface;
+ if (surface) {
wlr_seat_keyboard_notify_clear_focus(seat->wlr_seat);
- seat_keyboard_notify_enter(seat, focus->sway_container->view->surface);
+ seat_keyboard_notify_enter(seat, surface);
}
}
@@ -1057,7 +1081,8 @@ void seat_configure_xcursor(struct sway_seat *seat) {
bool seat_is_input_allowed(struct sway_seat *seat,
struct wlr_surface *surface) {
struct wl_client *client = wl_resource_get_client(surface->resource);
- return !seat->exclusive_client || seat->exclusive_client == client;
+ return seat->exclusive_client == client ||
+ (seat->exclusive_client == NULL && !server.session_lock.locked);
}
static void send_unfocus(struct sway_container *con, void *data) {
@@ -1116,15 +1141,7 @@ void seat_set_raw_focus(struct sway_seat *seat, struct sway_node *node) {
}
}
-void seat_set_focus(struct sway_seat *seat, struct sway_node *node) {
- if (seat->focused_layer) {
- struct wlr_layer_surface_v1 *layer = seat->focused_layer;
- seat_set_focus_layer(seat, NULL);
- seat_set_focus(seat, node);
- seat_set_focus_layer(seat, layer);
- return;
- }
-
+static void seat_set_workspace_focus(struct sway_seat *seat, struct sway_node *node) {
struct sway_node *last_focus = seat_get_focus(seat);
if (last_focus == node) {
return;
@@ -1257,6 +1274,20 @@ void seat_set_focus(struct sway_seat *seat, struct sway_node *node) {
}
}
+void seat_set_focus(struct sway_seat *seat, struct sway_node *node) {
+ if (seat->focused_layer) {
+ struct wlr_layer_surface_v1 *layer = seat->focused_layer;
+ seat_set_focus_layer(seat, NULL);
+ seat_set_workspace_focus(seat, node);
+ seat_set_focus_layer(seat, layer);
+ } else {
+ seat_set_workspace_focus(seat, node);
+ }
+ if (server.session_lock.locked) {
+ seat_set_focus_surface(seat, server.session_lock.focused, false);
+ }
+}
+
void seat_set_focus_container(struct sway_seat *seat,
struct sway_container *con) {
seat_set_focus(seat, con ? &con->node : NULL);
@@ -1561,7 +1592,7 @@ void seatop_pointer_motion(struct sway_seat *seat, uint32_t time_msec) {
}
void seatop_pointer_axis(struct sway_seat *seat,
- struct wlr_event_pointer_axis *event) {
+ struct wlr_pointer_axis_event *event) {
if (seat->seatop_impl->pointer_axis) {
seat->seatop_impl->pointer_axis(seat, event);
}
@@ -1584,6 +1615,62 @@ void seatop_tablet_tool_motion(struct sway_seat *seat,
}
}
+void seatop_hold_begin(struct sway_seat *seat,
+ struct wlr_pointer_hold_begin_event *event) {
+ if (seat->seatop_impl->hold_begin) {
+ seat->seatop_impl->hold_begin(seat, event);
+ }
+}
+
+void seatop_hold_end(struct sway_seat *seat,
+ struct wlr_pointer_hold_end_event *event) {
+ if (seat->seatop_impl->hold_end) {
+ seat->seatop_impl->hold_end(seat, event);
+ }
+}
+
+void seatop_pinch_begin(struct sway_seat *seat,
+ struct wlr_pointer_pinch_begin_event *event) {
+ if (seat->seatop_impl->pinch_begin) {
+ seat->seatop_impl->pinch_begin(seat, event);
+ }
+}
+
+void seatop_pinch_update(struct sway_seat *seat,
+ struct wlr_pointer_pinch_update_event *event) {
+ if (seat->seatop_impl->pinch_update) {
+ seat->seatop_impl->pinch_update(seat, event);
+ }
+}
+
+void seatop_pinch_end(struct sway_seat *seat,
+ struct wlr_pointer_pinch_end_event *event) {
+ if (seat->seatop_impl->pinch_end) {
+ seat->seatop_impl->pinch_end(seat, event);
+ }
+}
+
+void seatop_swipe_begin(struct sway_seat *seat,
+ struct wlr_pointer_swipe_begin_event *event) {
+ if (seat->seatop_impl->swipe_begin) {
+ seat->seatop_impl->swipe_begin(seat, event);
+ }
+}
+
+void seatop_swipe_update(struct sway_seat *seat,
+ struct wlr_pointer_swipe_update_event *event) {
+ if (seat->seatop_impl->swipe_update) {
+ seat->seatop_impl->swipe_update(seat, event);
+ }
+}
+
+void seatop_swipe_end(struct sway_seat *seat,
+ struct wlr_pointer_swipe_end_event *event) {
+ if (seat->seatop_impl->swipe_end) {
+ seat->seatop_impl->swipe_end(seat, event);
+ }
+}
+
void seatop_rebase(struct sway_seat *seat, uint32_t time_msec) {
if (seat->seatop_impl->rebase) {
seat->seatop_impl->rebase(seat, time_msec);
diff --git a/sway/input/seatop_default.c b/sway/input/seatop_default.c
index 4320a3b4..84acefdf 100644
--- a/sway/input/seatop_default.c
+++ b/sway/input/seatop_default.c
@@ -4,6 +4,7 @@
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_tablet_v2.h>
#include <wlr/types/wlr_xcursor_manager.h>
+#include "gesture.h"
#include "sway/desktop/transaction.h"
#include "sway/input/cursor.h"
#include "sway/input/seat.h"
@@ -20,6 +21,7 @@ struct seatop_default_event {
struct sway_node *previous_node;
uint32_t pressed_buttons[SWAY_CURSOR_PRESSED_BUTTONS_CAP];
size_t pressed_button_count;
+ struct gesture_tracker gestures;
};
/*-----------------------------------------\
@@ -427,13 +429,31 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
}
}
+ // Handle changing focus when clicking on a container
+ if (cont && state == WLR_BUTTON_PRESSED) {
+ // Default case: focus the container that was just clicked.
+ node = &cont->node;
+
+ // If the container is a tab/stacked container and the click happened
+ // on a tab, switch to the tab. If the tab contents were already
+ // focused, focus the tab container itself. If the tab container was
+ // already focused, cycle back to focusing the tab contents.
+ if (on_titlebar) {
+ struct sway_container *focus = seat_get_focused_container(seat);
+ if (focus == cont || !container_has_ancestor(focus, cont)) {
+ node = seat_get_focus_inactive(seat, &cont->node);
+ }
+ }
+
+ seat_set_focus(seat, node);
+ transaction_commit_dirty();
+ }
+
// Handle beginning floating move
if (cont && is_floating_or_child && !is_fullscreen_or_child &&
state == WLR_BUTTON_PRESSED) {
uint32_t btn_move = config->floating_mod_inverse ? BTN_RIGHT : BTN_LEFT;
if (button == btn_move && (mod_pressed || on_titlebar)) {
- seat_set_focus_container(seat,
- seat_get_focus_inactive_view(seat, &cont->node));
seatop_begin_move_floating(seat, container_toplevel_ancestor(cont));
return;
}
@@ -444,6 +464,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
state == WLR_BUTTON_PRESSED) {
// Via border
if (button == BTN_LEFT && resize_edge != WLR_EDGE_NONE) {
+ seat_set_focus_container(seat, cont);
seatop_begin_resize_floating(seat, cont, resize_edge);
return;
}
@@ -458,6 +479,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
WLR_EDGE_RIGHT : WLR_EDGE_LEFT;
edge |= cursor->cursor->y > floater->pending.y + floater->pending.height / 2 ?
WLR_EDGE_BOTTOM : WLR_EDGE_TOP;
+ seat_set_focus_container(seat, floater);
seatop_begin_resize_floating(seat, floater, edge);
return;
}
@@ -467,25 +489,18 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
if (config->tiling_drag && (mod_pressed || on_titlebar) &&
state == WLR_BUTTON_PRESSED && !is_floating_or_child &&
cont && cont->pending.fullscreen_mode == FULLSCREEN_NONE) {
- struct sway_container *focus = seat_get_focused_container(seat);
- bool focused = focus == cont || container_has_ancestor(focus, cont);
- if (on_titlebar && !focused) {
- node = seat_get_focus_inactive(seat, &cont->node);
- seat_set_focus(seat, node);
- }
-
- // If moving a container by it's title bar, use a threshold for the drag
+ // If moving a container by its title bar, use a threshold for the drag
if (!mod_pressed && config->tiling_drag_threshold > 0) {
seatop_begin_move_tiling_threshold(seat, cont);
} else {
seatop_begin_move_tiling(seat, cont);
}
+
return;
}
// Handle mousedown on a container surface
if (surface && cont && state == WLR_BUTTON_PRESSED) {
- seat_set_focus_container(seat, cont);
seatop_begin_down(seat, cont, time_msec, sx, sy);
seat_pointer_notify_button(seat, time_msec, button, WLR_BUTTON_PRESSED);
return;
@@ -493,9 +508,6 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
// Handle clicking a container surface or decorations
if (cont && state == WLR_BUTTON_PRESSED) {
- node = seat_get_focus_inactive(seat, &cont->node);
- seat_set_focus(seat, node);
- transaction_commit_dirty();
seat_pointer_notify_button(seat, time_msec, button, state);
return;
}
@@ -645,7 +657,7 @@ static void handle_tablet_tool_motion(struct sway_seat *seat,
* Functions used by handle_pointer_axis /
*--------------------------------------*/
-static uint32_t wl_axis_to_button(struct wlr_event_pointer_axis *event) {
+static uint32_t wl_axis_to_button(struct wlr_pointer_axis_event *event) {
switch (event->orientation) {
case WLR_AXIS_ORIENTATION_VERTICAL:
return event->delta < 0 ? SWAY_SCROLL_UP : SWAY_SCROLL_DOWN;
@@ -658,9 +670,9 @@ static uint32_t wl_axis_to_button(struct wlr_event_pointer_axis *event) {
}
static void handle_pointer_axis(struct sway_seat *seat,
- struct wlr_event_pointer_axis *event) {
+ struct wlr_pointer_axis_event *event) {
struct sway_input_device *input_device =
- event->device ? event->device->data : NULL;
+ event->pointer ? event->pointer->base.data : NULL;
struct input_config *ic =
input_device ? input_device_get_config(input_device) : NULL;
struct sway_cursor *cursor = seat->cursor;
@@ -706,6 +718,7 @@ static void handle_pointer_axis(struct sway_seat *seat,
// Scrolling on a tabbed or stacked title bar (handled as press event)
if (!handled && (on_titlebar || on_titlebar_border)) {
+ struct sway_node *new_focus;
enum sway_container_layout layout = container_parent_layout(cont);
if (layout == L_TABBED || layout == L_STACKED) {
struct sway_node *tabcontainer = node_get_parent(node);
@@ -713,7 +726,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);
+ round(scroll_factor * event->delta_discrete / WLR_POINTER_AXIS_DISCRETE_STEP);
if (desired < 0) {
desired = 0;
} else if (desired >= siblings->length) {
@@ -722,14 +735,16 @@ static void handle_pointer_axis(struct sway_seat *seat,
struct sway_container *new_sibling_con = siblings->items[desired];
struct sway_node *new_sibling = &new_sibling_con->node;
- struct sway_node *new_focus =
- seat_get_focus_inactive(seat, new_sibling);
// Use the focused child of the tabbed/stacked container, not the
// container the user scrolled on.
- seat_set_focus(seat, new_focus);
- transaction_commit_dirty();
- handled = true;
+ new_focus = seat_get_focus_inactive(seat, new_sibling);
+ } else {
+ new_focus = seat_get_focus_inactive(seat, &cont->node);
}
+
+ seat_set_focus(seat, new_focus);
+ transaction_commit_dirty();
+ handled = true;
}
// Handle mouse bindings - x11 mouse buttons 4-7 - release event
@@ -750,6 +765,304 @@ static void handle_pointer_axis(struct sway_seat *seat,
}
}
+/*------------------------------------\
+ * Functions used by gesture support /
+ *----------------------------------*/
+
+/**
+ * Check gesture binding for a specific gesture type and finger count.
+ * Returns true if binding is present, false otherwise
+ */
+static bool gesture_binding_check(list_t *bindings, enum gesture_type type,
+ uint8_t fingers, struct sway_input_device *device) {
+ char *input =
+ device ? input_device_get_identifier(device->wlr_device) : strdup("*");
+
+ for (int i = 0; i < bindings->length; ++i) {
+ struct sway_gesture_binding *binding = bindings->items[i];
+
+ // Check type and finger count
+ if (!gesture_check(&binding->gesture, type, fingers)) {
+ continue;
+ }
+
+ // Check that input matches
+ if (strcmp(binding->input, "*") != 0 &&
+ strcmp(binding->input, input) != 0) {
+ continue;
+ }
+
+ free(input);
+
+ return true;
+ }
+
+ free(input);
+
+ return false;
+}
+
+/**
+ * Return the gesture binding which matches gesture type, finger count
+ * and direction, otherwise return null.
+ */
+static struct sway_gesture_binding* gesture_binding_match(
+ list_t *bindings, struct gesture *gesture, const char *input) {
+ struct sway_gesture_binding *current = NULL;
+
+ // Find best matching binding
+ for (int i = 0; i < bindings->length; ++i) {
+ struct sway_gesture_binding *binding = bindings->items[i];
+ bool exact = binding->flags & BINDING_EXACT;
+
+ // Check gesture matching
+ if (!gesture_match(&binding->gesture, gesture, exact)) {
+ continue;
+ }
+
+ // Check input matching
+ if (strcmp(binding->input, "*") != 0 &&
+ strcmp(binding->input, input) != 0) {
+ continue;
+ }
+
+ // If we already have a match ...
+ if (current) {
+ // ... check if input matching is equivalent
+ if (strcmp(current->input, binding->input) == 0) {
+
+ // ... - do not override an exact binding
+ if (!exact && current->flags & BINDING_EXACT) {
+ continue;
+ }
+
+ // ... - and ensure direction matching is better or equal
+ if (gesture_compare(&current->gesture, &binding->gesture) > 0) {
+ continue;
+ }
+ } else if (strcmp(binding->input, "*") == 0) {
+ // ... do not accept worse input match
+ continue;
+ }
+ }
+
+ // Accept newer or better match
+ current = binding;
+
+ // If exact binding and input is found, quit search
+ if (strcmp(current->input, input) == 0 &&
+ gesture_compare(&current->gesture, gesture) == 0) {
+ break;
+ }
+ } // for all gesture bindings
+
+ return current;
+}
+
+// Wrapper around gesture_tracker_end to use tracker with sway bindings
+static struct sway_gesture_binding* gesture_tracker_end_and_match(
+ struct gesture_tracker *tracker, struct sway_input_device* device) {
+ // Determine name of input that received gesture
+ char *input = device
+ ? input_device_get_identifier(device->wlr_device)
+ : strdup("*");
+
+ // Match tracking result to binding
+ struct gesture *gesture = gesture_tracker_end(tracker);
+ struct sway_gesture_binding *binding = gesture_binding_match(
+ config->current_mode->gesture_bindings, gesture, input);
+ free(gesture);
+ free(input);
+
+ return binding;
+}
+
+// Small wrapper around seat_execute_command to work on gesture bindings
+static void gesture_binding_execute(struct sway_seat *seat,
+ struct sway_gesture_binding *binding) {
+ struct sway_binding *dummy_binding =
+ calloc(1, sizeof(struct sway_binding));
+ dummy_binding->type = BINDING_GESTURE;
+ dummy_binding->command = binding->command;
+
+ char *description = gesture_to_string(&binding->gesture);
+ sway_log(SWAY_DEBUG, "executing gesture binding: %s", description);
+ free(description);
+
+ seat_execute_command(seat, dummy_binding);
+
+ free(dummy_binding);
+}
+
+static void handle_hold_begin(struct sway_seat *seat,
+ struct wlr_pointer_hold_begin_event *event) {
+ // Start tracking gesture if there is a matching binding ...
+ struct sway_input_device *device =
+ event->pointer ? event->pointer->base.data : NULL;
+ list_t *bindings = config->current_mode->gesture_bindings;
+ if (gesture_binding_check(bindings, GESTURE_TYPE_HOLD, event->fingers, device)) {
+ struct seatop_default_event *seatop = seat->seatop_data;
+ gesture_tracker_begin(&seatop->gestures, GESTURE_TYPE_HOLD, event->fingers);
+ } else {
+ // ... otherwise forward to client
+ struct sway_cursor *cursor = seat->cursor;
+ wlr_pointer_gestures_v1_send_hold_begin(
+ cursor->pointer_gestures, cursor->seat->wlr_seat,
+ event->time_msec, event->fingers);
+ }
+}
+
+static void handle_hold_end(struct sway_seat *seat,
+ struct wlr_pointer_hold_end_event *event) {
+ // Ensure that gesture is being tracked and was not cancelled
+ struct seatop_default_event *seatop = seat->seatop_data;
+ 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,
+ event->time_msec, event->cancelled);
+ return;
+ }
+ if (event->cancelled) {
+ gesture_tracker_cancel(&seatop->gestures);
+ return;
+ }
+
+ // End gesture tracking and execute matched binding
+ struct sway_input_device *device =
+ event->pointer ? event->pointer->base.data : NULL;
+ struct sway_gesture_binding *binding = gesture_tracker_end_and_match(
+ &seatop->gestures, device);
+
+ if (binding) {
+ gesture_binding_execute(seat, binding);
+ }
+}
+
+static void handle_pinch_begin(struct sway_seat *seat,
+ struct wlr_pointer_pinch_begin_event *event) {
+ // Start tracking gesture if there is a matching binding ...
+ struct sway_input_device *device =
+ event->pointer ? event->pointer->base.data : NULL;
+ list_t *bindings = config->current_mode->gesture_bindings;
+ if (gesture_binding_check(bindings, GESTURE_TYPE_PINCH, event->fingers, device)) {
+ struct seatop_default_event *seatop = seat->seatop_data;
+ gesture_tracker_begin(&seatop->gestures, GESTURE_TYPE_PINCH, event->fingers);
+ } else {
+ // ... otherwise forward to client
+ struct sway_cursor *cursor = seat->cursor;
+ wlr_pointer_gestures_v1_send_pinch_begin(
+ cursor->pointer_gestures, cursor->seat->wlr_seat,
+ event->time_msec, event->fingers);
+ }
+}
+
+static void handle_pinch_update(struct sway_seat *seat,
+ struct wlr_pointer_pinch_update_event *event) {
+ // Update any ongoing tracking ...
+ struct seatop_default_event *seatop = seat->seatop_data;
+ if (gesture_tracker_check(&seatop->gestures, GESTURE_TYPE_PINCH)) {
+ gesture_tracker_update(&seatop->gestures, event->dx, event->dy,
+ event->scale, event->rotation);
+ } else {
+ // ... otherwise forward to client
+ struct sway_cursor *cursor = seat->cursor;
+ wlr_pointer_gestures_v1_send_pinch_update(
+ cursor->pointer_gestures,
+ cursor->seat->wlr_seat,
+ event->time_msec, event->dx, event->dy,
+ event->scale, event->rotation);
+ }
+}
+
+static void handle_pinch_end(struct sway_seat *seat,
+ struct wlr_pointer_pinch_end_event *event) {
+ // Ensure that gesture is being tracked and was not cancelled
+ struct seatop_default_event *seatop = seat->seatop_data;
+ 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,
+ event->time_msec, event->cancelled);
+ return;
+ }
+ if (event->cancelled) {
+ gesture_tracker_cancel(&seatop->gestures);
+ return;
+ }
+
+ // End gesture tracking and execute matched binding
+ struct sway_input_device *device =
+ event->pointer ? event->pointer->base.data : NULL;
+ struct sway_gesture_binding *binding = gesture_tracker_end_and_match(
+ &seatop->gestures, device);
+
+ if (binding) {
+ gesture_binding_execute(seat, binding);
+ }
+}
+
+static void handle_swipe_begin(struct sway_seat *seat,
+ struct wlr_pointer_swipe_begin_event *event) {
+ // Start tracking gesture if there is a matching binding ...
+ struct sway_input_device *device =
+ event->pointer ? event->pointer->base.data : NULL;
+ list_t *bindings = config->current_mode->gesture_bindings;
+ if (gesture_binding_check(bindings, GESTURE_TYPE_SWIPE, event->fingers, device)) {
+ struct seatop_default_event *seatop = seat->seatop_data;
+ gesture_tracker_begin(&seatop->gestures, GESTURE_TYPE_SWIPE, event->fingers);
+ } else {
+ // ... otherwise forward to client
+ struct sway_cursor *cursor = seat->cursor;
+ wlr_pointer_gestures_v1_send_swipe_begin(
+ cursor->pointer_gestures, cursor->seat->wlr_seat,
+ event->time_msec, event->fingers);
+ }
+}
+
+static void handle_swipe_update(struct sway_seat *seat,
+ struct wlr_pointer_swipe_update_event *event) {
+
+ // Update any ongoing tracking ...
+ struct seatop_default_event *seatop = seat->seatop_data;
+ if (gesture_tracker_check(&seatop->gestures, GESTURE_TYPE_SWIPE)) {
+ gesture_tracker_update(&seatop->gestures,
+ event->dx, event->dy, NAN, NAN);
+ } else {
+ // ... otherwise forward to client
+ struct sway_cursor *cursor = seat->cursor;
+ wlr_pointer_gestures_v1_send_swipe_update(
+ cursor->pointer_gestures, cursor->seat->wlr_seat,
+ event->time_msec, event->dx, event->dy);
+ }
+}
+
+static void handle_swipe_end(struct sway_seat *seat,
+ struct wlr_pointer_swipe_end_event *event) {
+ // Ensure gesture is being tracked and was not cancelled
+ 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,
+ cursor->seat->wlr_seat, event->time_msec, event->cancelled);
+ return;
+ }
+ if (event->cancelled) {
+ gesture_tracker_cancel(&seatop->gestures);
+ return;
+ }
+
+ // End gesture tracking and execute matched binding
+ struct sway_input_device *device =
+ event->pointer ? event->pointer->base.data : NULL;
+ struct sway_gesture_binding *binding = gesture_tracker_end_and_match(
+ &seatop->gestures, device);
+
+ if (binding) {
+ gesture_binding_execute(seat, binding);
+ }
+}
+
/*----------------------------------\
* Functions used by handle_rebase /
*--------------------------------*/
@@ -779,6 +1092,14 @@ static const struct sway_seatop_impl seatop_impl = {
.pointer_axis = handle_pointer_axis,
.tablet_tool_tip = handle_tablet_tool_tip,
.tablet_tool_motion = handle_tablet_tool_motion,
+ .hold_begin = handle_hold_begin,
+ .hold_end = handle_hold_end,
+ .pinch_begin = handle_pinch_begin,
+ .pinch_update = handle_pinch_update,
+ .pinch_end = handle_pinch_end,
+ .swipe_begin = handle_swipe_begin,
+ .swipe_update = handle_swipe_update,
+ .swipe_end = handle_swipe_end,
.rebase = handle_rebase,
.allow_set_cursor = true,
};
@@ -789,8 +1110,8 @@ void seatop_begin_default(struct sway_seat *seat) {
struct seatop_default_event *e =
calloc(1, sizeof(struct seatop_default_event));
sway_assert(e, "Unable to allocate seatop_default_event");
+
seat->seatop_impl = &seatop_impl;
seat->seatop_data = e;
-
seatop_rebase(seat, 0);
}
diff --git a/sway/input/seatop_down.c b/sway/input/seatop_down.c
index ecc34fea..b40773d0 100644
--- a/sway/input/seatop_down.c
+++ b/sway/input/seatop_down.c
@@ -18,9 +18,9 @@ struct seatop_down_event {
};
static void handle_pointer_axis(struct sway_seat *seat,
- struct wlr_event_pointer_axis *event) {
+ struct wlr_pointer_axis_event *event) {
struct sway_input_device *input_device =
- event->device ? event->device->data : NULL;
+ event->pointer ? event->pointer->base.data : NULL;
struct input_config *ic =
input_device ? input_device_get_config(input_device) : NULL;
float scroll_factor =
diff --git a/sway/input/switch.c b/sway/input/switch.c
index 9ea87a1a..fc7dfaff 100644
--- a/sway/input/switch.c
+++ b/sway/input/switch.c
@@ -11,6 +11,7 @@ struct sway_switch *sway_switch_create(struct sway_seat *seat,
return NULL;
}
device->switch_device = switch_device;
+ switch_device->wlr = wlr_switch_from_input_device(device->input_device->wlr_device);
switch_device->seat_device = device;
switch_device->state = WLR_SWITCH_STATE_OFF;
wl_list_init(&switch_device->switch_toggle.link);
@@ -19,9 +20,23 @@ struct sway_switch *sway_switch_create(struct sway_seat *seat,
return switch_device;
}
+static bool sway_switch_trigger_test(enum sway_switch_trigger trigger,
+ enum wlr_switch_state state) {
+ switch (trigger) {
+ case SWAY_SWITCH_TRIGGER_ON:
+ return state == WLR_SWITCH_STATE_ON;
+ case SWAY_SWITCH_TRIGGER_OFF:
+ return state == WLR_SWITCH_STATE_OFF;
+ case SWAY_SWITCH_TRIGGER_TOGGLE:
+ return true;
+ }
+ abort(); // unreachable
+}
+
static void execute_binding(struct sway_switch *sway_switch) {
struct sway_seat* seat = sway_switch->seat_device->sway_seat;
- bool input_inhibited = seat->exclusive_client != NULL;
+ bool input_inhibited = seat->exclusive_client != NULL ||
+ server.session_lock.locked;
list_t *bindings = config->current_mode->switch_bindings;
struct sway_switch_binding *matched_binding = NULL;
@@ -30,11 +45,10 @@ static void execute_binding(struct sway_switch *sway_switch) {
if (binding->type != sway_switch->type) {
continue;
}
- if (binding->state != WLR_SWITCH_STATE_TOGGLE &&
- binding->state != sway_switch->state) {
+ if (!sway_switch_trigger_test(binding->trigger, sway_switch->state)) {
continue;
}
- if (config->reloading && (binding->state == WLR_SWITCH_STATE_TOGGLE
+ if (config->reloading && (binding->trigger == SWAY_SWITCH_TRIGGER_TOGGLE
|| (binding->flags & BINDING_RELOAD) == 0)) {
continue;
}
@@ -65,7 +79,7 @@ static void execute_binding(struct sway_switch *sway_switch) {
static void handle_switch_toggle(struct wl_listener *listener, void *data) {
struct sway_switch *sway_switch =
wl_container_of(listener, sway_switch, switch_toggle);
- struct wlr_event_switch_toggle *event = data;
+ struct wlr_switch_toggle_event *event = data;
struct sway_seat *seat = sway_switch->seat_device->sway_seat;
seat_idle_notify_activity(seat, IDLE_SOURCE_SWITCH);
@@ -82,10 +96,8 @@ static void handle_switch_toggle(struct wl_listener *listener, void *data) {
}
void sway_switch_configure(struct sway_switch *sway_switch) {
- struct wlr_input_device *wlr_device =
- sway_switch->seat_device->input_device->wlr_device;
wl_list_remove(&sway_switch->switch_toggle.link);
- wl_signal_add(&wlr_device->switch_device->events.toggle,
+ wl_signal_add(&sway_switch->wlr->events.toggle,
&sway_switch->switch_toggle);
sway_switch->switch_toggle.notify = handle_switch_toggle;
sway_log(SWAY_DEBUG, "Configured switch for device");
diff --git a/sway/input/tablet.c b/sway/input/tablet.c
index 26e86e36..92ede3fa 100644
--- a/sway/input/tablet.c
+++ b/sway/input/tablet.c
@@ -196,7 +196,7 @@ static void handle_tablet_pad_attach(struct wl_listener *listener,
static void handle_tablet_pad_ring(struct wl_listener *listener, void *data) {
struct sway_tablet_pad *pad = wl_container_of(listener, pad, ring);
- struct wlr_event_tablet_pad_ring *event = data;
+ struct wlr_tablet_pad_ring_event *event = data;
if (!pad->current_surface) {
return;
@@ -210,7 +210,7 @@ static void handle_tablet_pad_ring(struct wl_listener *listener, void *data) {
static void handle_tablet_pad_strip(struct wl_listener *listener, void *data) {
struct sway_tablet_pad *pad = wl_container_of(listener, pad, strip);
- struct wlr_event_tablet_pad_strip *event = data;
+ struct wlr_tablet_pad_strip_event *event = data;
if (!pad->current_surface) {
return;
@@ -224,7 +224,7 @@ static void handle_tablet_pad_strip(struct wl_listener *listener, void *data) {
static void handle_tablet_pad_button(struct wl_listener *listener, void *data) {
struct sway_tablet_pad *pad = wl_container_of(listener, pad, button);
- struct wlr_event_tablet_pad_button *event = data;
+ struct wlr_tablet_pad_button_event *event = data;
if (!pad->current_surface) {
return;
@@ -246,6 +246,7 @@ struct sway_tablet_pad *sway_tablet_pad_create(struct sway_seat *seat,
return NULL;
}
+ tablet_pad->wlr = wlr_tablet_pad_from_input_device(device->input_device->wlr_device);
tablet_pad->seat_device = device;
wl_list_init(&tablet_pad->attach.link);
wl_list_init(&tablet_pad->button.link);
@@ -260,40 +261,40 @@ struct sway_tablet_pad *sway_tablet_pad_create(struct sway_seat *seat,
}
void sway_configure_tablet_pad(struct sway_tablet_pad *tablet_pad) {
- struct wlr_input_device *device =
+ struct wlr_input_device *wlr_device =
tablet_pad->seat_device->input_device->wlr_device;
struct sway_seat *seat = tablet_pad->seat_device->sway_seat;
if (!tablet_pad->tablet_v2_pad) {
tablet_pad->tablet_v2_pad =
- wlr_tablet_pad_create(server.tablet_v2, seat->wlr_seat, device);
+ wlr_tablet_pad_create(server.tablet_v2, seat->wlr_seat, wlr_device);
}
wl_list_remove(&tablet_pad->attach.link);
tablet_pad->attach.notify = handle_tablet_pad_attach;
- wl_signal_add(&device->tablet_pad->events.attach_tablet,
+ wl_signal_add(&tablet_pad->wlr->events.attach_tablet,
&tablet_pad->attach);
wl_list_remove(&tablet_pad->button.link);
tablet_pad->button.notify = handle_tablet_pad_button;
- wl_signal_add(&device->tablet_pad->events.button, &tablet_pad->button);
+ wl_signal_add(&tablet_pad->wlr->events.button, &tablet_pad->button);
wl_list_remove(&tablet_pad->strip.link);
tablet_pad->strip.notify = handle_tablet_pad_strip;
- wl_signal_add(&device->tablet_pad->events.strip, &tablet_pad->strip);
+ wl_signal_add(&tablet_pad->wlr->events.strip, &tablet_pad->strip);
wl_list_remove(&tablet_pad->ring.link);
tablet_pad->ring.notify = handle_tablet_pad_ring;
- wl_signal_add(&device->tablet_pad->events.ring, &tablet_pad->ring);
+ wl_signal_add(&tablet_pad->wlr->events.ring, &tablet_pad->ring);
/* Search for a sibling tablet */
- if (!wlr_input_device_is_libinput(device)) {
+ if (!wlr_input_device_is_libinput(wlr_device)) {
/* We can only do this on libinput devices */
return;
}
struct libinput_device_group *group =
- libinput_device_get_device_group(wlr_libinput_get_device_handle(device));
+ libinput_device_get_device_group(wlr_libinput_get_device_handle(wlr_device));
struct sway_tablet *tool;
wl_list_for_each(tool, &seat->cursor->tablets, link) {
struct wlr_input_device *tablet =
diff --git a/sway/input/text_input.c b/sway/input/text_input.c
index b8c19c17..58911c2d 100644
--- a/sway/input/text_input.c
+++ b/sway/input/text_input.c
@@ -77,8 +77,6 @@ static void handle_im_grab_keyboard(struct wl_listener *listener, void *data) {
struct wlr_keyboard *active_keyboard = wlr_seat_get_keyboard(relay->seat->wlr_seat);
wlr_input_method_keyboard_grab_v2_set_keyboard(keyboard_grab,
active_keyboard);
- wlr_input_method_keyboard_grab_v2_send_modifiers(keyboard_grab,
- &active_keyboard->modifiers);
wl_signal_add(&keyboard_grab->events.destroy,
&relay->input_method_keyboard_grab_destroy);