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.
This commit is contained in:
tiosgz 2022-07-14 14:15:51 +00:00
parent cf01588a82
commit 30f8469da0
6 changed files with 124 additions and 4 deletions

View file

@ -12,6 +12,7 @@
struct kiwmi_input { struct kiwmi_input {
struct wl_list keyboards; // struct kiwmi_keyboard::link struct wl_list keyboards; // struct kiwmi_keyboard::link
struct wl_list pointers; // struct kiwmi_pointer::link
struct wl_listener new_input; struct wl_listener new_input;
struct kiwmi_cursor *cursor; struct kiwmi_cursor *cursor;
struct kiwmi_seat *seat; struct kiwmi_seat *seat;

27
include/input/pointer.h Normal file
View file

@ -0,0 +1,27 @@
/* Copyright (c), Charlotte Meyer <dev@buffet.sh>
*
* 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 <wayland-server.h>
#include <wlr/types/wlr_input_device.h>
#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 */

View file

@ -27,6 +27,7 @@
#include "desktop/view.h" #include "desktop/view.h"
#include "input/cursor.h" #include "input/cursor.h"
#include "input/input.h" #include "input/input.h"
#include "input/pointer.h"
#include "server.h" #include "server.h"
static void static void
@ -355,9 +356,17 @@ new_output_notify(struct wl_listener *listener, void *data)
wlr_output->data = output; wlr_output->data = output;
struct kiwmi_cursor *cursor = server->input.cursor; struct kiwmi_cursor *cursor = server->input.cursor;
wlr_xcursor_manager_load(cursor->xcursor_manager, wlr_output->scale); 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); wl_list_insert(&desktop->outputs, &output->link);
wlr_output_layout_add_auto(desktop->output_layout, wlr_output); wlr_output_layout_add_auto(desktop->output_layout, wlr_output);

View file

@ -19,13 +19,21 @@
#include "desktop/desktop.h" #include "desktop/desktop.h"
#include "input/cursor.h" #include "input/cursor.h"
#include "input/keyboard.h" #include "input/keyboard.h"
#include "input/pointer.h"
#include "input/seat.h" #include "input/seat.h"
#include "server.h" #include "server.h"
static void static void
new_pointer(struct kiwmi_input *input, struct wlr_input_device *device) 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 static void
@ -86,6 +94,7 @@ input_init(struct kiwmi_input *input)
} }
wl_list_init(&input->keyboards); wl_list_init(&input->keyboards);
wl_list_init(&input->pointers);
input->new_input.notify = new_input_notify; input->new_input.notify = new_input_notify;
wl_signal_add(&server->backend->events.new_input, &input->new_input); wl_signal_add(&server->backend->events.new_input, &input->new_input);
@ -99,11 +108,17 @@ void
input_fini(struct kiwmi_input *input) input_fini(struct kiwmi_input *input)
{ {
struct kiwmi_keyboard *keyboard; struct kiwmi_keyboard *keyboard;
struct kiwmi_keyboard *tmp; struct kiwmi_keyboard *tmp_keyboard;
wl_list_for_each_safe (keyboard, tmp, &input->keyboards, link) { wl_list_for_each_safe (keyboard, tmp_keyboard, &input->keyboards, link) {
keyboard_destroy(keyboard); 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); seat_destroy(input->seat);
cursor_destroy(input->cursor); cursor_destroy(input->cursor);

67
kiwmi/input/pointer.c Normal file
View file

@ -0,0 +1,67 @@
/* Copyright (c), Charlotte Meyer <dev@buffet.sh>
*
* 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 <stdlib.h>
#include <string.h>
#include <wayland-server.h>
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_input_device.h>
#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);
}

View file

@ -10,6 +10,7 @@ kiwmi_sources = files(
'input/cursor.c', 'input/cursor.c',
'input/input.c', 'input/input.c',
'input/keyboard.c', 'input/keyboard.c',
'input/pointer.c',
'input/seat.c', 'input/seat.c',
'luak/ipc.c', 'luak/ipc.c',
'luak/kiwmi_cursor.c', 'luak/kiwmi_cursor.c',