Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wlserver: Create a keyboard group to keep all externally connected keyboards in sync #1726

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 32 additions & 34 deletions src/wlserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_compositor.h>
#include <wlr/types/wlr_keyboard.h>
#include <wlr/types/wlr_keyboard_group.h>
#include <wlr/types/wlr_pointer.h>
#include <wlr/types/wlr_seat.h>
#include <wlr/types/wlr_touch.h>
Expand Down Expand Up @@ -282,21 +283,21 @@ static void bump_input_counter()

static void wlserver_handle_modifiers(struct wl_listener *listener, void *data)
{
struct wlserver_keyboard *keyboard = wl_container_of( listener, keyboard, modifiers );
struct wlr_keyboard *keyboard = &wlserver.keyboard_group->keyboard;

wlr_seat_set_keyboard( wlserver.wlr.seat, keyboard->wlr );
wlr_seat_keyboard_notify_modifiers( wlserver.wlr.seat, &keyboard->wlr->modifiers );
wlr_seat_set_keyboard( wlserver.wlr.seat, keyboard );
wlr_seat_keyboard_notify_modifiers( wlserver.wlr.seat, &keyboard->modifiers );

bump_input_counter();
}

static void wlserver_handle_key(struct wl_listener *listener, void *data)
{
struct wlserver_keyboard *keyboard = wl_container_of( listener, keyboard, key );
struct wlr_keyboard *keyboard = &wlserver.keyboard_group->keyboard;
struct wlr_keyboard_key_event *event = (struct wlr_keyboard_key_event *) data;

xkb_keycode_t keycode = event->keycode + 8;
xkb_keysym_t keysym = xkb_state_key_get_one_sym(keyboard->wlr->xkb_state, keycode);
xkb_keysym_t keysym = xkb_state_key_get_one_sym(keyboard->xkb_state, keycode);

#if HAVE_SESSION
if (wlserver.wlr.session && event->state == WL_KEYBOARD_KEY_STATE_PRESSED && keysym >= XKB_KEY_XF86Switch_VT_1 && keysym <= XKB_KEY_XF86Switch_VT_12) {
Expand All @@ -318,14 +319,14 @@ static void wlserver_handle_key(struct wl_listener *listener, void *data)
if ( new_kb_surf )
{
wlserver_keyboardfocus( new_kb_surf, false );
wlr_seat_set_keyboard( wlserver.wlr.seat, keyboard->wlr );
wlr_seat_set_keyboard( wlserver.wlr.seat, keyboard );
wlr_seat_keyboard_notify_key( wlserver.wlr.seat, event->time_msec, event->keycode, event->state );
wlserver_keyboardfocus( old_kb_surf, false );
return;
}
}

wlr_seat_set_keyboard( wlserver.wlr.seat, keyboard->wlr );
wlr_seat_set_keyboard( wlserver.wlr.seat, keyboard );
wlr_seat_keyboard_notify_key( wlserver.wlr.seat, event->time_msec, event->keycode, event->state );

bump_input_counter();
Expand Down Expand Up @@ -434,32 +435,11 @@ static void wlserver_new_input(struct wl_listener *listener, void *data)
{
case WLR_INPUT_DEVICE_KEYBOARD:
{
struct wlserver_keyboard *keyboard = (struct wlserver_keyboard *) calloc( 1, sizeof( struct wlserver_keyboard ) );

keyboard->wlr = (struct wlr_keyboard *)device;

struct xkb_rule_names rules = { 0 };
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
rules.rules = getenv("XKB_DEFAULT_RULES");
rules.model = getenv("XKB_DEFAULT_MODEL");
rules.layout = getenv("XKB_DEFAULT_LAYOUT");
rules.variant = getenv("XKB_DEFAULT_VARIANT");
rules.options = getenv("XKB_DEFAULT_OPTIONS");
struct xkb_keymap *keymap = xkb_keymap_new_from_names(context, &rules,
XKB_KEYMAP_COMPILE_NO_FLAGS);

wlr_keyboard_set_keymap(keyboard->wlr, keymap);
xkb_keymap_unref(keymap);
xkb_context_unref(context);
wlr_keyboard_set_repeat_info(keyboard->wlr, 25, 600);

keyboard->wlr->data = keyboard;

keyboard->modifiers.notify = wlserver_handle_modifiers;
wl_signal_add( &keyboard->wlr->events.modifiers, &keyboard->modifiers );

keyboard->key.notify = wlserver_handle_key;
wl_signal_add( &keyboard->wlr->events.key, &keyboard->key );
struct wlr_keyboard *keyboard = wlr_keyboard_from_input_device(device);
wlr_keyboard_set_keymap(keyboard, wlserver.keyboard_group->keyboard.keymap);
if (!wlr_keyboard_group_add_keyboard(wlserver.keyboard_group, keyboard)) {
wl_log.errorf("failed to add physical keyboard %s", device->name);
}
}
break;
case WLR_INPUT_DEVICE_POINTER:
Expand Down Expand Up @@ -1735,9 +1715,27 @@ bool wlserver_init( void ) {
// We need to wait for the backend to be started before adding the device
struct wlr_keyboard *kbd = (struct wlr_keyboard *) calloc(1, sizeof(*kbd));
wlr_keyboard_init(kbd, nullptr, "virtual");

wlserver.wlr.virtual_keyboard_device = kbd;

// Create a keyboard group to keep all externally connected keyboards
// in sync (one single layout and a shared state)
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
struct xkb_rule_names rules = { 0 };
rules.rules = getenv("XKB_DEFAULT_RULES");
rules.model = getenv("XKB_DEFAULT_MODEL");
rules.layout = getenv("XKB_DEFAULT_LAYOUT");
rules.variant = getenv("XKB_DEFAULT_VARIANT");
rules.options = getenv("XKB_DEFAULT_OPTIONS");
struct xkb_keymap *keymap = xkb_keymap_new_from_names(context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
wlserver.keyboard_group = wlr_keyboard_group_create();
struct wlr_keyboard *keyboard = &wlserver.keyboard_group->keyboard;
wlr_keyboard_set_repeat_info(keyboard, 25, 600);
wlr_keyboard_set_keymap(keyboard, keymap);
wlserver.keyboard_group_modifiers.notify = wlserver_handle_modifiers;
wl_signal_add(&keyboard->events.modifiers, &wlserver.keyboard_group_modifiers);
wlserver.keyboard_group_key.notify = wlserver_handle_key;
wl_signal_add(&keyboard->events.key, &wlserver.keyboard_group_key);

wlserver.wlr.renderer = vulkan_renderer_create();

wlr_renderer_init_wl_display(wlserver.wlr.renderer, wlserver.display);
Expand Down
12 changes: 5 additions & 7 deletions src/wlserver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,19 +187,17 @@ struct wlserver_t {
std::vector<wl_resource*> gamescope_controls;

std::atomic<bool> bWaylandServerRunning = { false };

// Share one single keymap and state between all connected physical keyboards
struct wlr_keyboard_group *keyboard_group;
struct wl_listener keyboard_group_modifiers;
struct wl_listener keyboard_group_key;
};

extern struct wlserver_t wlserver;

std::vector<ResListEntry_t> wlserver_xdg_commit_queue();

struct wlserver_keyboard {
struct wlr_keyboard *wlr;

struct wl_listener modifiers;
struct wl_listener key;
};

struct wlserver_pointer {
struct wlr_pointer *wlr;

Expand Down