From 99956cd5301ad1c19e3a3d07e022c942ca8b312d Mon Sep 17 00:00:00 2001 From: Dominique Martinet Date: Tue, 18 May 2021 08:52:06 +0900 Subject: [PATCH 1/2] seat: add wlr_virtual_keyboard_manager_v1 --- seat.c | 43 ++++++++++++++++++++++++++++++++++++------- seat.h | 4 ++++ 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/seat.c b/seat.c index 08f25a3..d8556f6 100644 --- a/seat.c +++ b/seat.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #if CAGE_HAS_XWAYLAND @@ -294,10 +295,16 @@ handle_keyboard_group_modifiers(struct wl_listener *listener, void *data) } static void -cg_keyboard_group_add(struct wlr_input_device *device, struct cg_seat *seat) +cg_keyboard_group_add(struct wlr_input_device *device, struct cg_seat *seat, bool virtual) { struct wlr_keyboard *wlr_keyboard = device->keyboard; + if (virtual) + /* We apparently should not group virtual keyboards, + * so create a new group with it + */ + goto create_new; + struct cg_keyboard_group *group; wl_list_for_each (group, &seat->keyboard_groups, link) { struct wlr_keyboard_group *wlr_group = group->wlr_group; @@ -309,7 +316,9 @@ cg_keyboard_group_add(struct wlr_input_device *device, struct cg_seat *seat) /* This is reached if and only if the keyboard could not be inserted into * any group */ - struct cg_keyboard_group *cg_group = calloc(1, sizeof(struct cg_keyboard_group)); + struct cg_keyboard_group *cg_group; +create_new: + cg_group = calloc(1, sizeof(struct cg_keyboard_group)); if (cg_group == NULL) { wlr_log(WLR_ERROR, "Failed to allocate keyboard group."); return; @@ -322,7 +331,7 @@ cg_keyboard_group_add(struct wlr_input_device *device, struct cg_seat *seat) } cg_group->wlr_group->data = cg_group; - wlr_keyboard_set_keymap(&cg_group->wlr_group->keyboard, device->keyboard->keymap); + wlr_keyboard_set_keymap(&cg_group->wlr_group->keyboard, wlr_keyboard->keymap); wlr_keyboard_set_repeat_info(&cg_group->wlr_group->keyboard, wlr_keyboard->repeat_info.rate, wlr_keyboard->repeat_info.delay); @@ -330,7 +339,10 @@ cg_keyboard_group_add(struct wlr_input_device *device, struct cg_seat *seat) wlr_log(WLR_DEBUG, "Created keyboard group"); wlr_keyboard_group_add_keyboard(cg_group->wlr_group, wlr_keyboard); - wl_list_insert(&seat->keyboard_groups, &cg_group->link); + if (!virtual) + wl_list_insert(&seat->keyboard_groups, &cg_group->link); + else + wl_list_init(&cg_group->link); wl_signal_add(&cg_group->wlr_group->keyboard.events.key, &cg_group->key); cg_group->key.notify = handle_keyboard_group_key; @@ -347,7 +359,7 @@ cg_keyboard_group_add(struct wlr_input_device *device, struct cg_seat *seat) } static void -handle_new_keyboard(struct cg_seat *seat, struct wlr_input_device *device) +handle_new_keyboard(struct cg_seat *seat, struct wlr_input_device *device, bool virtual) { struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); if (!context) { @@ -374,11 +386,24 @@ handle_new_keyboard(struct cg_seat *seat, struct wlr_input_device *device) xkb_context_unref(context); wlr_keyboard_set_repeat_info(device->keyboard, 25, 600); - cg_keyboard_group_add(device, seat); + cg_keyboard_group_add(device, seat, virtual); wlr_seat_set_keyboard(seat->seat, device); } +static void +handle_virtual_keyboard(struct wl_listener *listener, void *data) +{ + struct cg_seat *seat = wl_container_of(listener, seat, new_virtual_keyboard); + struct wlr_virtual_keyboard_v1 *keyboard = data; + struct wlr_input_device *device = &keyboard->input_device; + + /* If multiple seats are supported, check keyboard->seat + * to select the appropriate one */ + + handle_new_keyboard(seat, device, true); +} + static void handle_new_input(struct wl_listener *listener, void *data) { @@ -387,7 +412,7 @@ handle_new_input(struct wl_listener *listener, void *data) switch (device->type) { case WLR_INPUT_DEVICE_KEYBOARD: - handle_new_keyboard(seat, device); + handle_new_keyboard(seat, device, false); break; case WLR_INPUT_DEVICE_POINTER: handle_new_pointer(seat, device); @@ -818,6 +843,10 @@ seat_create(struct cg_server *server, struct wlr_backend *backend) seat->start_drag.notify = handle_start_drag; wl_signal_add(&seat->seat->events.start_drag, &seat->start_drag); + seat->virtual_keyboard = wlr_virtual_keyboard_manager_v1_create(server->wl_display); + wl_signal_add(&seat->virtual_keyboard->events.new_virtual_keyboard, &seat->new_virtual_keyboard); + seat->new_virtual_keyboard.notify = handle_virtual_keyboard; + return seat; } diff --git a/seat.h b/seat.h index 188543d..428801a 100644 --- a/seat.h +++ b/seat.h @@ -25,6 +25,10 @@ struct cg_seat { struct wl_list touch; struct wl_listener new_input; + // These belong to higher level if multiple seats are allowed + struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard; + struct wl_listener new_virtual_keyboard; + struct wlr_cursor *cursor; struct wlr_xcursor_manager *xcursor_manager; struct wl_listener cursor_motion; From 9d2e1c2131c27fd656f37580689fce92a663dad0 Mon Sep 17 00:00:00 2001 From: Dominique Martinet Date: Tue, 18 May 2021 08:52:22 +0900 Subject: [PATCH 2/2] seat: add wlr_virtual_pointer_manager_v1 together with the previous patch, wayvnc can now be used with cage: $ cage something # figure out which wayland socket cage used $ WAYLAND_DISPLAY=wayland-0 wayvnc Note this does not appear to work with headless backend, e.g. starting cage with WLR_BACKENDS=headless WLR_LIBINPUT_NO_DEVICES=1 cage something does start and wayvnc connects/displays output, but there are tons of errors and input does not work --- seat.c | 17 +++++++++++++++++ seat.h | 2 ++ 2 files changed, 19 insertions(+) diff --git a/seat.c b/seat.c index d8556f6..9bf6672 100644 --- a/seat.c +++ b/seat.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #if CAGE_HAS_XWAYLAND @@ -216,6 +217,18 @@ handle_new_pointer(struct cg_seat *seat, struct wlr_input_device *device) map_input_device_to_output(seat, device); } +static void +handle_virtual_pointer(struct wl_listener *listener, void *data) +{ + struct cg_seat *seat = wl_container_of(listener, seat, new_virtual_pointer); + 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; + + /* event->suggested_seat should be checked if we handle multiple seats */ + handle_new_pointer(seat, device); +} + static void handle_modifier_event(struct wlr_input_device *device, struct cg_seat *seat) { @@ -847,6 +860,10 @@ seat_create(struct cg_server *server, struct wlr_backend *backend) wl_signal_add(&seat->virtual_keyboard->events.new_virtual_keyboard, &seat->new_virtual_keyboard); seat->new_virtual_keyboard.notify = handle_virtual_keyboard; + seat->virtual_pointer = wlr_virtual_pointer_manager_v1_create(server->wl_display); + wl_signal_add(&seat->virtual_pointer->events.new_virtual_pointer, &seat->new_virtual_pointer); + seat->new_virtual_pointer.notify = handle_virtual_pointer; + return seat; } diff --git a/seat.h b/seat.h index 428801a..0f6de59 100644 --- a/seat.h +++ b/seat.h @@ -27,7 +27,9 @@ struct cg_seat { // These belong to higher level if multiple seats are allowed struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard; + struct wlr_virtual_pointer_manager_v1 *virtual_pointer; struct wl_listener new_virtual_keyboard; + struct wl_listener new_virtual_pointer; struct wlr_cursor *cursor; struct wlr_xcursor_manager *xcursor_manager;