aboutsummaryrefslogtreecommitdiffstats
path: root/sway/input/input-manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/input/input-manager.c')
-rw-r--r--sway/input/input-manager.c112
1 files changed, 63 insertions, 49 deletions
diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c
index f04a8ce0..c1bbdde0 100644
--- a/sway/input/input-manager.c
+++ b/sway/input/input-manager.c
@@ -3,10 +3,9 @@
3#include <stdio.h> 3#include <stdio.h>
4#include <string.h> 4#include <string.h>
5#include <math.h> 5#include <math.h>
6#include <wlr/backend/libinput.h> 6#include <wlr/config.h>
7#include <wlr/types/wlr_cursor.h> 7#include <wlr/types/wlr_cursor.h>
8#include <wlr/types/wlr_keyboard_group.h> 8#include <wlr/types/wlr_keyboard_group.h>
9#include <wlr/types/wlr_input_inhibitor.h>
10#include <wlr/types/wlr_virtual_keyboard_v1.h> 9#include <wlr/types/wlr_virtual_keyboard_v1.h>
11#include <wlr/types/wlr_virtual_pointer_v1.h> 10#include <wlr/types/wlr_virtual_pointer_v1.h>
12#include "sway/config.h" 11#include "sway/config.h"
@@ -22,6 +21,10 @@
22#include "list.h" 21#include "list.h"
23#include "log.h" 22#include "log.h"
24 23
24#if WLR_HAS_LIBINPUT_BACKEND
25#include <wlr/backend/libinput.h>
26#endif
27
25#define DEFAULT_SEAT "seat0" 28#define DEFAULT_SEAT "seat0"
26 29
27struct input_config *current_input_config = NULL; 30struct input_config *current_input_config = NULL;
@@ -76,20 +79,13 @@ char *input_device_get_identifier(struct wlr_input_device *device) {
76 } 79 }
77 } 80 }
78 81
79 const char *fmt = "%d:%d:%s"; 82 char *identifier = format_str("%d:%d:%s", vendor, product, name);
80 int len = snprintf(NULL, 0, fmt, vendor, product, name) + 1;
81 char *identifier = malloc(len);
82 if (!identifier) {
83 sway_log(SWAY_ERROR, "Unable to allocate unique input device name");
84 return NULL;
85 }
86
87 snprintf(identifier, len, fmt, vendor, product, name);
88 free(name); 83 free(name);
89 return identifier; 84 return identifier;
90} 85}
91 86
92static bool device_is_touchpad(struct sway_input_device *device) { 87static bool device_is_touchpad(struct sway_input_device *device) {
88#if WLR_HAS_LIBINPUT_BACKEND
93 if (device->wlr_device->type != WLR_INPUT_DEVICE_POINTER || 89 if (device->wlr_device->type != WLR_INPUT_DEVICE_POINTER ||
94 !wlr_input_device_is_libinput(device->wlr_device)) { 90 !wlr_input_device_is_libinput(device->wlr_device)) {
95 return false; 91 return false;
@@ -99,6 +95,9 @@ static bool device_is_touchpad(struct sway_input_device *device) {
99 wlr_libinput_get_device_handle(device->wlr_device); 95 wlr_libinput_get_device_handle(device->wlr_device);
100 96
101 return libinput_device_config_tap_get_finger_count(libinput_device) > 0; 97 return libinput_device_config_tap_get_finger_count(libinput_device) > 0;
98#else
99 return false;
100#endif
102} 101}
103 102
104const char *input_device_get_type(struct sway_input_device *device) { 103const char *input_device_get_type(struct sway_input_device *device) {
@@ -236,7 +235,11 @@ static void handle_new_input(struct wl_listener *listener, void *data) {
236 235
237 apply_input_type_config(input_device); 236 apply_input_type_config(input_device);
238 237
239 sway_input_configure_libinput_device(input_device); 238#if WLR_HAS_LIBINPUT_BACKEND
239 bool config_changed = sway_input_configure_libinput_device(input_device);
240#else
241 bool config_changed = false;
242#endif
240 243
241 wl_signal_add(&device->events.destroy, &input_device->device_destroy); 244 wl_signal_add(&device->events.destroy, &input_device->device_destroy);
242 input_device->device_destroy.notify = handle_device_destroy; 245 input_device->device_destroy.notify = handle_device_destroy;
@@ -274,29 +277,9 @@ static void handle_new_input(struct wl_listener *listener, void *data) {
274 } 277 }
275 278
276 ipc_event_input("added", input_device); 279 ipc_event_input("added", input_device);
277}
278 280
279static void handle_inhibit_activate(struct wl_listener *listener, void *data) { 281 if (config_changed) {
280 struct sway_input_manager *input_manager = wl_container_of( 282 ipc_event_input("libinput_config", input_device);
281 listener, input_manager, inhibit_activate);
282 struct sway_seat *seat;
283 wl_list_for_each(seat, &input_manager->seats, link) {
284 seat_set_exclusive_client(seat, input_manager->inhibit->active_client);
285 }
286}
287
288static void handle_inhibit_deactivate(struct wl_listener *listener, void *data) {
289 struct sway_input_manager *input_manager = wl_container_of(
290 listener, input_manager, inhibit_deactivate);
291 struct sway_seat *seat;
292 wl_list_for_each(seat, &input_manager->seats, link) {
293 seat_set_exclusive_client(seat, NULL);
294 struct sway_node *previous = seat_get_focus(seat);
295 if (previous) {
296 // Hack to get seat to re-focus the return value of get_focus
297 seat_set_focus(seat, NULL);
298 seat_set_focus(seat, previous);
299 }
300 } 283 }
301} 284}
302 285
@@ -377,7 +360,7 @@ void handle_virtual_keyboard(struct wl_listener *listener, void *data) {
377 struct sway_input_manager *input_manager = 360 struct sway_input_manager *input_manager =
378 wl_container_of(listener, input_manager, virtual_keyboard_new); 361 wl_container_of(listener, input_manager, virtual_keyboard_new);
379 struct wlr_virtual_keyboard_v1 *keyboard = data; 362 struct wlr_virtual_keyboard_v1 *keyboard = data;
380 struct wlr_input_device *device = &keyboard->input_device; 363 struct wlr_input_device *device = &keyboard->keyboard.base;
381 364
382 // TODO: Amend protocol to allow NULL seat 365 // TODO: Amend protocol to allow NULL seat
383 struct sway_seat *seat = keyboard->seat ? 366 struct sway_seat *seat = keyboard->seat ?
@@ -410,7 +393,7 @@ void handle_virtual_pointer(struct wl_listener *listener, void *data) {
410 wl_container_of(listener, input_manager, virtual_pointer_new); 393 wl_container_of(listener, input_manager, virtual_pointer_new);
411 struct wlr_virtual_pointer_v1_new_pointer_event *event = data; 394 struct wlr_virtual_pointer_v1_new_pointer_event *event = data;
412 struct wlr_virtual_pointer_v1 *pointer = event->new_pointer; 395 struct wlr_virtual_pointer_v1 *pointer = event->new_pointer;
413 struct wlr_input_device *device = &pointer->input_device; 396 struct wlr_input_device *device = &pointer->pointer.base;
414 397
415 struct sway_seat *seat = event->suggested_seat ? 398 struct sway_seat *seat = event->suggested_seat ?
416 input_manager_sway_seat_from_wlr_seat(event->suggested_seat) : 399 input_manager_sway_seat_from_wlr_seat(event->suggested_seat) :
@@ -468,14 +451,6 @@ struct sway_input_manager *input_manager_create(struct sway_server *server) {
468 &input->virtual_pointer_new); 451 &input->virtual_pointer_new);
469 input->virtual_pointer_new.notify = handle_virtual_pointer; 452 input->virtual_pointer_new.notify = handle_virtual_pointer;
470 453
471 input->inhibit = wlr_input_inhibit_manager_create(server->wl_display);
472 input->inhibit_activate.notify = handle_inhibit_activate;
473 wl_signal_add(&input->inhibit->events.activate,
474 &input->inhibit_activate);
475 input->inhibit_deactivate.notify = handle_inhibit_deactivate;
476 wl_signal_add(&input->inhibit->events.deactivate,
477 &input->inhibit_deactivate);
478
479 input->keyboard_shortcuts_inhibit = 454 input->keyboard_shortcuts_inhibit =
480 wlr_keyboard_shortcuts_inhibit_v1_create(server->wl_display); 455 wlr_keyboard_shortcuts_inhibit_v1_create(server->wl_display);
481 input->keyboard_shortcuts_inhibit_new_inhibitor.notify = 456 input->keyboard_shortcuts_inhibit_new_inhibitor.notify =
@@ -483,6 +458,8 @@ struct sway_input_manager *input_manager_create(struct sway_server *server) {
483 wl_signal_add(&input->keyboard_shortcuts_inhibit->events.new_inhibitor, 458 wl_signal_add(&input->keyboard_shortcuts_inhibit->events.new_inhibitor,
484 &input->keyboard_shortcuts_inhibit_new_inhibitor); 459 &input->keyboard_shortcuts_inhibit_new_inhibitor);
485 460
461 input->pointer_gestures = wlr_pointer_gestures_v1_create(server->wl_display);
462
486 return input; 463 return input;
487} 464}
488 465
@@ -520,21 +497,50 @@ static void retranslate_keysyms(struct input_config *input_config) {
520 return; 497 return;
521 } 498 }
522 } 499 }
500
501 for (int i = 0; i < config->input_type_configs->length; ++i) {
502 struct input_config *ic = config->input_type_configs->items[i];
503 if (ic->xkb_layout || ic->xkb_file) {
504 // this is the first config with xkb_layout or xkb_file
505 if (ic->identifier == input_config->identifier) {
506 translate_keysyms(ic);
507 }
508
509 return;
510 }
511 }
523} 512}
524 513
525static void input_manager_configure_input( 514static void input_manager_configure_input(
526 struct sway_input_device *input_device) { 515 struct sway_input_device *input_device) {
527 sway_input_configure_libinput_device(input_device); 516#if WLR_HAS_LIBINPUT_BACKEND
517 bool config_changed = sway_input_configure_libinput_device(input_device);
518#else
519 bool config_changed = false;
520#endif
528 struct sway_seat *seat = NULL; 521 struct sway_seat *seat = NULL;
529 wl_list_for_each(seat, &server.input->seats, link) { 522 wl_list_for_each(seat, &server.input->seats, link) {
530 seat_configure_device(seat, input_device); 523 seat_configure_device(seat, input_device);
531 } 524 }
525 if (config_changed) {
526 ipc_event_input("libinput_config", input_device);
527 }
532} 528}
533 529
534void input_manager_configure_all_inputs(void) { 530void input_manager_configure_all_input_mappings(void) {
535 struct sway_input_device *input_device = NULL; 531 struct sway_input_device *input_device;
536 wl_list_for_each(input_device, &server.input->devices, link) { 532 wl_list_for_each(input_device, &server.input->devices, link) {
537 input_manager_configure_input(input_device); 533 struct sway_seat *seat;
534 wl_list_for_each(seat, &server.input->seats, link) {
535 seat_configure_device_mapping(seat, input_device);
536 }
537
538#if WLR_HAS_LIBINPUT_BACKEND
539 // Input devices mapped to unavailable outputs get their libinput
540 // send_events setting switched to false. We need to re-enable this
541 // when the output appears.
542 sway_input_configure_libinput_device_send_events(input_device);
543#endif
538 } 544 }
539} 545}
540 546
@@ -556,7 +562,9 @@ void input_manager_apply_input_config(struct input_config *input_config) {
556} 562}
557 563
558void input_manager_reset_input(struct sway_input_device *input_device) { 564void input_manager_reset_input(struct sway_input_device *input_device) {
565#if WLR_HAS_LIBINPUT_BACKEND
559 sway_input_reset_libinput_device(input_device); 566 sway_input_reset_libinput_device(input_device);
567#endif
560 struct sway_seat *seat = NULL; 568 struct sway_seat *seat = NULL;
561 wl_list_for_each(seat, &server.input->seats, link) { 569 wl_list_for_each(seat, &server.input->seats, link) {
562 seat_reset_device(seat, input_device); 570 seat_reset_device(seat, input_device);
@@ -564,6 +572,13 @@ void input_manager_reset_input(struct sway_input_device *input_device) {
564} 572}
565 573
566void input_manager_reset_all_inputs(void) { 574void input_manager_reset_all_inputs(void) {
575 // Set the active keyboard to NULL to avoid spamming configuration updates
576 // for all keyboard devices.
577 struct sway_seat *seat;
578 wl_list_for_each(seat, &server.input->seats, link) {
579 wlr_seat_set_keyboard(seat->wlr_seat, NULL);
580 }
581
567 struct sway_input_device *input_device = NULL; 582 struct sway_input_device *input_device = NULL;
568 wl_list_for_each(input_device, &server.input->devices, link) { 583 wl_list_for_each(input_device, &server.input->devices, link) {
569 input_manager_reset_input(input_device); 584 input_manager_reset_input(input_device);
@@ -572,7 +587,6 @@ void input_manager_reset_all_inputs(void) {
572 // If there is at least one keyboard using the default keymap, repeat delay, 587 // If there is at least one keyboard using the default keymap, repeat delay,
573 // and repeat rate, then it is possible that there is a keyboard group that 588 // and repeat rate, then it is possible that there is a keyboard group that
574 // need their keyboard disarmed. 589 // need their keyboard disarmed.
575 struct sway_seat *seat;
576 wl_list_for_each(seat, &server.input->seats, link) { 590 wl_list_for_each(seat, &server.input->seats, link) {
577 struct sway_keyboard_group *group; 591 struct sway_keyboard_group *group;
578 wl_list_for_each(group, &seat->keyboard_groups, link) { 592 wl_list_for_each(group, &seat->keyboard_groups, link) {