diff options
Diffstat (limited to 'sway/input')
-rw-r--r-- | sway/input/cursor.c | 195 | ||||
-rw-r--r-- | sway/input/input-manager.c | 27 | ||||
-rw-r--r-- | sway/input/keyboard.c | 128 | ||||
-rw-r--r-- | sway/input/libinput.c | 23 | ||||
-rw-r--r-- | sway/input/seat.c | 141 | ||||
-rw-r--r-- | sway/input/seatop_default.c | 369 | ||||
-rw-r--r-- | sway/input/seatop_down.c | 4 | ||||
-rw-r--r-- | sway/input/switch.c | 28 | ||||
-rw-r--r-- | sway/input/tablet.c | 23 | ||||
-rw-r--r-- | sway/input/text_input.c | 2 |
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(¤t->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(¤t->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); |