repositories / dotfiles
dotfiles
bugabingas dorkfiles
owned by admin
quickshell/nuguland/test-fixtures/ui/niri-integration-keyboard.c
Raw// Weston-side keyboard events reach nested Niri's native grabs. Niri's wlr
// virtual keyboard forwards to clients and cannot confirm/cancel those grabs.
#include <assert.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libweston/libweston.h>
struct controller {
struct weston_compositor *compositor;
struct wl_event_source *source;
struct wl_listener destroy;
int fd;
};
static int input(int fd, uint32_t mask, void *data) {
(void)mask;
struct controller *ctl = data;
uint32_t command[3]; // expected nested client PID, evdev key, pressed
assert(read(fd, command, sizeof(command)) == sizeof(command));
assert(command[0] > 1 && command[2] <= 1);
assert(command[1] == 1 || command[1] == 28 || command[1] == 29 || command[1] == 46);
struct weston_seat *seat;
struct weston_keyboard *keyboard = NULL;
wl_list_for_each(seat, &ctl->compositor->seat_list, link) {
struct weston_keyboard *candidate = weston_seat_get_keyboard(seat);
if (!candidate || !candidate->focus || !candidate->focus->resource) continue;
pid_t pid;
wl_client_get_credentials(wl_resource_get_client(candidate->focus->resource), &pid, NULL, NULL);
if (pid == (pid_t)command[0]) {
assert(!keyboard);
keyboard = candidate;
}
}
assert(keyboard); // Never redirect input to an unrelated surface.
struct timespec now;
weston_compositor_get_time(&now);
weston_keyboard_send_key(keyboard, &now, command[1], command[2]);
xkb_state_update_key(keyboard->xkb_state.state, command[1] + 8, command[2] ? XKB_KEY_DOWN : XKB_KEY_UP);
weston_keyboard_send_modifiers(keyboard, wl_display_next_serial(ctl->compositor->wl_display),
xkb_state_serialize_mods(keyboard->xkb_state.state, XKB_STATE_MODS_DEPRESSED),
xkb_state_serialize_mods(keyboard->xkb_state.state, XKB_STATE_MODS_LATCHED),
xkb_state_serialize_mods(keyboard->xkb_state.state, XKB_STATE_MODS_LOCKED),
xkb_state_serialize_layout(keyboard->xkb_state.state, XKB_STATE_LAYOUT_EFFECTIVE));
return 0;
}
static void destroy(struct wl_listener *listener, void *data) {
(void)data;
struct controller *ctl = wl_container_of(listener, ctl, destroy);
wl_event_source_remove(ctl->source);
wl_list_remove(&ctl->destroy.link);
close(ctl->fd);
free(ctl);
}
WL_EXPORT int wet_module_init(struct weston_compositor *compositor, int *argc, char *argv[]) {
(void)argc; (void)argv;
assert(getenv("NUGULAND_UI_SANDBOX") && !strcmp(getenv("HOME"), "/home/test"));
struct controller *ctl = calloc(1, sizeof(*ctl));
assert(ctl);
ctl->compositor = compositor;
ctl->fd = open("/run/user/1000/niri-integration-keyboard.fifo", O_RDWR | O_NONBLOCK);
assert(ctl->fd >= 0);
ctl->source = wl_event_loop_add_fd(wl_display_get_event_loop(compositor->wl_display), ctl->fd, WL_EVENT_READABLE, input, ctl);
assert(ctl->source);
weston_compositor_add_destroy_listener_once(compositor, &ctl->destroy, destroy);
return 0;
}