From a12e670657d7c09aeb5066c535b36297dc6bb810 Mon Sep 17 00:00:00 2001 From: tiosgz Date: Thu, 14 Jul 2022 14:15:51 +0000 Subject: [PATCH] input: map pointer to output if possible This is needed in order for wlroots to interpret some values (mostly coords of absolute input events) correctly. It for example fixes how the pointer behaves with WLR_WL_OUTPUTS=2. In order to also map the pointer/output pair when the pointer is created before the output, a list of pointers has to be managed, which wasn't needed until now. --- include/input/input.h | 1 + include/input/pointer.h | 27 +++++++++++++++++ kiwmi/desktop/output.c | 11 ++++++- kiwmi/input/input.c | 21 +++++++++++-- kiwmi/input/pointer.c | 67 +++++++++++++++++++++++++++++++++++++++++ kiwmi/meson.build | 1 + 6 files changed, 124 insertions(+), 4 deletions(-) create mode 100644 include/input/pointer.h create mode 100644 kiwmi/input/pointer.c diff --git a/include/input/input.h b/include/input/input.h index cbaa60d..0889d34 100644 --- a/include/input/input.h +++ b/include/input/input.h @@ -12,6 +12,7 @@ struct kiwmi_input { struct wl_list keyboards; // struct kiwmi_keyboard::link + struct wl_list pointers; // struct kiwmi_pointer::link struct wl_listener new_input; struct kiwmi_cursor *cursor; struct kiwmi_seat *seat; diff --git a/include/input/pointer.h b/include/input/pointer.h new file mode 100644 index 0000000..121442a --- /dev/null +++ b/include/input/pointer.h @@ -0,0 +1,27 @@ +/* Copyright (c), Niclas Meyer + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#ifndef KIWMI_INPUT_POINTER_H +#define KIWMI_INPUT_POINTER_H + +#include +#include + +#include "server.h" + +struct kiwmi_pointer { + struct wlr_input_device *device; + struct wl_list link; + + struct wl_listener device_destroy; +}; + +struct kiwmi_pointer * +pointer_create(struct kiwmi_server *server, struct wlr_input_device *device); +void pointer_destroy(struct kiwmi_pointer *pointer); + +#endif /* KIWMI_INPUT_POINTER_H */ diff --git a/kiwmi/desktop/output.c b/kiwmi/desktop/output.c index 6db8f62..afeadee 100644 --- a/kiwmi/desktop/output.c +++ b/kiwmi/desktop/output.c @@ -27,6 +27,7 @@ #include "desktop/view.h" #include "input/cursor.h" #include "input/input.h" +#include "input/pointer.h" #include "server.h" static void @@ -355,9 +356,17 @@ new_output_notify(struct wl_listener *listener, void *data) wlr_output->data = output; struct kiwmi_cursor *cursor = server->input.cursor; - wlr_xcursor_manager_load(cursor->xcursor_manager, wlr_output->scale); + struct kiwmi_pointer *pointer; + wl_list_for_each (pointer, &server->input.pointers, link) { + if (pointer->device->output_name + && strcmp(pointer->device->output_name, wlr_output->name) == 0) { + wlr_cursor_map_input_to_output( + cursor->cursor, pointer->device, wlr_output); + } + } + wl_list_insert(&desktop->outputs, &output->link); wlr_output_layout_add_auto(desktop->output_layout, wlr_output); diff --git a/kiwmi/input/input.c b/kiwmi/input/input.c index e70159f..1e3f27b 100644 --- a/kiwmi/input/input.c +++ b/kiwmi/input/input.c @@ -19,13 +19,21 @@ #include "desktop/desktop.h" #include "input/cursor.h" #include "input/keyboard.h" +#include "input/pointer.h" #include "input/seat.h" #include "server.h" static void new_pointer(struct kiwmi_input *input, struct wlr_input_device *device) { - wlr_cursor_attach_input_device(input->cursor->cursor, device); + struct kiwmi_server *server = wl_container_of(input, server, input); + + struct kiwmi_pointer *pointer = pointer_create(server, device); + if (!pointer) { + return; + } + + wl_list_insert(&input->pointers, &pointer->link); } static void @@ -86,6 +94,7 @@ input_init(struct kiwmi_input *input) } wl_list_init(&input->keyboards); + wl_list_init(&input->pointers); input->new_input.notify = new_input_notify; wl_signal_add(&server->backend->events.new_input, &input->new_input); @@ -99,11 +108,17 @@ void input_fini(struct kiwmi_input *input) { struct kiwmi_keyboard *keyboard; - struct kiwmi_keyboard *tmp; - wl_list_for_each_safe (keyboard, tmp, &input->keyboards, link) { + struct kiwmi_keyboard *tmp_keyboard; + wl_list_for_each_safe (keyboard, tmp_keyboard, &input->keyboards, link) { keyboard_destroy(keyboard); } + struct kiwmi_pointer *pointer; + struct kiwmi_pointer *tmp_pointer; + wl_list_for_each_safe (pointer, tmp_pointer, &input->pointers, link) { + pointer_destroy(pointer); + } + seat_destroy(input->seat); cursor_destroy(input->cursor); diff --git a/kiwmi/input/pointer.c b/kiwmi/input/pointer.c new file mode 100644 index 0000000..ba8cce9 --- /dev/null +++ b/kiwmi/input/pointer.c @@ -0,0 +1,67 @@ +/* Copyright (c), Niclas Meyer + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include "input/pointer.h" + +#include +#include + +#include +#include +#include + +#include "desktop/output.h" +#include "input/cursor.h" +#include "input/input.h" +#include "server.h" + +static void +pointer_destroy_notify(struct wl_listener *listener, void *UNUSED(data)) +{ + struct kiwmi_pointer *pointer = + wl_container_of(listener, pointer, device_destroy); + + pointer_destroy(pointer); +} + +struct kiwmi_pointer * +pointer_create(struct kiwmi_server *server, struct wlr_input_device *device) +{ + wlr_cursor_attach_input_device(server->input.cursor->cursor, device); + + struct kiwmi_pointer *pointer = malloc(sizeof(*pointer)); + if (!pointer) { + return NULL; + } + + pointer->device = device; + + pointer->device_destroy.notify = pointer_destroy_notify; + wl_signal_add(&device->events.destroy, &pointer->device_destroy); + + if (device->output_name) { + struct kiwmi_output *output; + wl_list_for_each (output, &server->desktop.outputs, link) { + if (strcmp(device->output_name, output->wlr_output->name) == 0) { + wlr_cursor_map_input_to_output( + server->input.cursor->cursor, device, output->wlr_output); + break; + } + } + } + + return pointer; +} + +void +pointer_destroy(struct kiwmi_pointer *pointer) +{ + wl_list_remove(&pointer->device_destroy.link); + wl_list_remove(&pointer->link); + + free(pointer); +} diff --git a/kiwmi/meson.build b/kiwmi/meson.build index a212eea..13f7c9b 100644 --- a/kiwmi/meson.build +++ b/kiwmi/meson.build @@ -10,6 +10,7 @@ kiwmi_sources = files( 'input/cursor.c', 'input/input.c', 'input/keyboard.c', + 'input/pointer.c', 'input/seat.c', 'luak/ipc.c', 'luak/kiwmi_cursor.c',