From 30f8469da0dc272a2e8d32ec425c4f3f04dc7b7c 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 7c47c99..37381e5 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..0694889 --- /dev/null +++ b/include/input/pointer.h @@ -0,0 +1,27 @@ +/* Copyright (c), Charlotte 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 432cd67..a5a7cd5 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 d49ff9f..04254b0 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..54983a8 --- /dev/null +++ b/kiwmi/input/pointer.c @@ -0,0 +1,67 @@ +/* Copyright (c), Charlotte 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',