Seat: ignore virtual keyboards until keymap set
The wlr-virtual-keyboard-v1 protocol fails to make keyboard creation atomic. There is nothing a client can do with a virtual keyboard that has no keymap except for destroy it, so we can completely ignore them until a keymap is set. This fixes a regression with fcitx caused by river sending the null keymap of a new virtual keyboard to fcitx.
This commit is contained in:
@ -185,10 +185,46 @@ fn handleNewVirtualKeyboard(
|
|||||||
_: *wl.Listener(*wlr.VirtualKeyboardV1),
|
_: *wl.Listener(*wlr.VirtualKeyboardV1),
|
||||||
virtual_keyboard: *wlr.VirtualKeyboardV1,
|
virtual_keyboard: *wlr.VirtualKeyboardV1,
|
||||||
) void {
|
) void {
|
||||||
const seat: *Seat = @alignCast(@ptrCast(virtual_keyboard.seat.data));
|
const no_keymap = util.gpa.create(NoKeymapVirtKeyboard) catch {
|
||||||
seat.addDevice(&virtual_keyboard.keyboard.base, true);
|
log.err("out of memory", .{});
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
errdefer util.gpa.destroy(no_keymap);
|
||||||
|
|
||||||
|
no_keymap.* = .{
|
||||||
|
.virtual_keyboard = virtual_keyboard,
|
||||||
|
};
|
||||||
|
virtual_keyboard.keyboard.base.events.destroy.add(&no_keymap.destroy);
|
||||||
|
virtual_keyboard.keyboard.events.keymap.add(&no_keymap.keymap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Ignore virtual keyboards completely until the client sets a keymap
|
||||||
|
/// Yes, wlroots should probably do this for us.
|
||||||
|
const NoKeymapVirtKeyboard = struct {
|
||||||
|
virtual_keyboard: *wlr.VirtualKeyboardV1,
|
||||||
|
destroy: wl.Listener(*wlr.InputDevice) = .init(handleDestroy),
|
||||||
|
keymap: wl.Listener(*wlr.Keyboard) = .init(handleKeymap),
|
||||||
|
|
||||||
|
fn handleDestroy(listener: *wl.Listener(*wlr.InputDevice), _: *wlr.InputDevice) void {
|
||||||
|
const no_keymap: *NoKeymapVirtKeyboard = @fieldParentPtr("destroy", listener);
|
||||||
|
|
||||||
|
no_keymap.destroy.link.remove();
|
||||||
|
no_keymap.keymap.link.remove();
|
||||||
|
|
||||||
|
util.gpa.destroy(no_keymap);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handleKeymap(listener: *wl.Listener(*wlr.Keyboard), _: *wlr.Keyboard) void {
|
||||||
|
const no_keymap: *NoKeymapVirtKeyboard = @fieldParentPtr("keymap", listener);
|
||||||
|
const virtual_keyboard = no_keymap.virtual_keyboard;
|
||||||
|
|
||||||
|
handleDestroy(&no_keymap.destroy, &virtual_keyboard.keyboard.base);
|
||||||
|
|
||||||
|
const seat: *Seat = @alignCast(@ptrCast(virtual_keyboard.seat.data));
|
||||||
|
seat.addDevice(&virtual_keyboard.keyboard.base, true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
fn handleNewConstraint(
|
fn handleNewConstraint(
|
||||||
_: *wl.Listener(*wlr.PointerConstraintV1),
|
_: *wl.Listener(*wlr.PointerConstraintV1),
|
||||||
wlr_constraint: *wlr.PointerConstraintV1,
|
wlr_constraint: *wlr.PointerConstraintV1,
|
||||||
|
Reference in New Issue
Block a user