TextInput/InputRelay: style nits
There should be no functional changes in this commit
This commit is contained in:
parent
134a6bcfb5
commit
6f311af3b3
@ -173,48 +173,18 @@ fn handleNewConstraint(
|
||||
};
|
||||
}
|
||||
|
||||
fn handleNewInputMethod(
|
||||
_: *wl.Listener(*wlr.InputMethodV2),
|
||||
input_method: *wlr.InputMethodV2,
|
||||
) void {
|
||||
//const self = @fieldParentPtr(Self, "new_input_method", listener);
|
||||
const seat = @as(*Seat, @ptrFromInt(input_method.seat.data));
|
||||
const relay = &seat.relay;
|
||||
fn handleNewInputMethod(_: *wl.Listener(*wlr.InputMethodV2), input_method: *wlr.InputMethodV2) void {
|
||||
const seat: *Seat = @ptrFromInt(input_method.seat.data);
|
||||
|
||||
// Only one input_method can be bound to a seat.
|
||||
if (relay.input_method != null) {
|
||||
log.debug("attempted to connect second input method to a seat", .{});
|
||||
input_method.sendUnavailable();
|
||||
return;
|
||||
}
|
||||
log.debug("new input method on seat {s}", .{seat.wlr_seat.name});
|
||||
|
||||
relay.input_method = input_method;
|
||||
|
||||
input_method.events.commit.add(&relay.input_method_commit);
|
||||
input_method.events.grab_keyboard.add(&relay.grab_keyboard);
|
||||
input_method.events.destroy.add(&relay.input_method_destroy);
|
||||
|
||||
log.debug("new input method on seat {s}", .{relay.seat.wlr_seat.name});
|
||||
|
||||
if (seat.focused.surface()) |surface| {
|
||||
relay.focus(surface);
|
||||
}
|
||||
seat.relay.newInputMethod(input_method);
|
||||
}
|
||||
|
||||
fn handleNewTextInput(
|
||||
_: *wl.Listener(*wlr.TextInputV3),
|
||||
wlr_text_input: *wlr.TextInputV3,
|
||||
) void {
|
||||
//const self = @fieldParentPtr(Self, "new_text_input", listener);
|
||||
const seat = @as(*Seat, @ptrFromInt(wlr_text_input.seat.data));
|
||||
const relay = &seat.relay;
|
||||
|
||||
const text_input_node = util.gpa.create(std.TailQueue(TextInput).Node) catch {
|
||||
fn handleNewTextInput(_: *wl.Listener(*wlr.TextInputV3), wlr_text_input: *wlr.TextInputV3) void {
|
||||
TextInput.create(wlr_text_input) catch {
|
||||
log.err("out of memory", .{});
|
||||
wlr_text_input.resource.postNoMemory();
|
||||
return;
|
||||
};
|
||||
text_input_node.data.init(relay, wlr_text_input);
|
||||
relay.text_inputs.append(text_input_node);
|
||||
|
||||
log.debug("new text input on seat {s}", .{relay.seat.wlr_seat.name});
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
const Self = @This();
|
||||
const InputRelay = @This();
|
||||
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
@ -30,17 +30,18 @@ const Seat = @import("Seat.zig");
|
||||
|
||||
const log = std.log.scoped(.input_relay);
|
||||
|
||||
/// The Relay structure manages the communication between text_inputs
|
||||
/// and input_method on a given seat.
|
||||
seat: *Seat,
|
||||
|
||||
/// List of all TextInput bound to the relay.
|
||||
/// Multiple wlr_text_input interfaces can be bound to a relay,
|
||||
/// but only one at a time can receive events.
|
||||
text_inputs: std.TailQueue(TextInput) = .{},
|
||||
/// List of all text input objects for the seat.
|
||||
/// Multiple text input objects may be created per seat, even multiple from the same client.
|
||||
/// However, only one text input per seat may be enabled at a time.
|
||||
text_inputs: wl.list.Head(TextInput, .link),
|
||||
|
||||
/// The input method currently in use for this seat.
|
||||
/// Only one input method per seat may be used at a time and if one is
|
||||
/// already in use new input methods are ignored.
|
||||
/// If this is null, no text input enter events will be sent.
|
||||
input_method: ?*wlr.InputMethodV2 = null,
|
||||
/// The currently enabled text input for the currently focused surface.
|
||||
/// Always null if there is no input method.
|
||||
text_input: ?*TextInput = null,
|
||||
|
||||
input_method_commit: wl.Listener(*wlr.InputMethodV2) =
|
||||
@ -53,19 +54,44 @@ input_method_destroy: wl.Listener(*wlr.InputMethodV2) =
|
||||
grab_keyboard_destroy: wl.Listener(*wlr.InputMethodV2.KeyboardGrab) =
|
||||
wl.Listener(*wlr.InputMethodV2.KeyboardGrab).init(handleInputMethodGrabKeyboardDestroy),
|
||||
|
||||
pub fn init(self: *Self, seat: *Seat) void {
|
||||
self.* = .{ .seat = seat };
|
||||
pub fn init(relay: *InputRelay) void {
|
||||
relay.* = .{ .text_inputs = undefined };
|
||||
|
||||
relay.text_inputs.init();
|
||||
}
|
||||
|
||||
pub fn newInputMethod(relay: *InputRelay, input_method: *wlr.InputMethodV2) void {
|
||||
const seat = @fieldParentPtr(Seat, "relay", relay);
|
||||
|
||||
log.debug("new input method on seat {s}", .{seat.wlr_seat.name});
|
||||
|
||||
// Only one input_method can be bound to a seat.
|
||||
if (relay.input_method != null) {
|
||||
log.info("seat {s} already has an input method", .{seat.wlr_seat.name});
|
||||
input_method.sendUnavailable();
|
||||
return;
|
||||
}
|
||||
|
||||
relay.input_method = input_method;
|
||||
|
||||
input_method.events.commit.add(&relay.input_method_commit);
|
||||
input_method.events.grab_keyboard.add(&relay.grab_keyboard);
|
||||
input_method.events.destroy.add(&relay.input_method_destroy);
|
||||
|
||||
if (seat.focused.surface()) |surface| {
|
||||
relay.focus(surface);
|
||||
}
|
||||
}
|
||||
|
||||
fn handleInputMethodCommit(
|
||||
listener: *wl.Listener(*wlr.InputMethodV2),
|
||||
input_method: *wlr.InputMethodV2,
|
||||
) void {
|
||||
const self = @fieldParentPtr(Self, "input_method_commit", listener);
|
||||
assert(input_method == self.input_method);
|
||||
const relay = @fieldParentPtr(InputRelay, "input_method_commit", listener);
|
||||
assert(input_method == relay.input_method);
|
||||
|
||||
if (!input_method.client_active) return;
|
||||
const text_input = self.text_input orelse return;
|
||||
const text_input = relay.text_input orelse return;
|
||||
|
||||
if (input_method.current.preedit.text) |preedit_text| {
|
||||
text_input.wlr_text_input.sendPreeditString(
|
||||
@ -95,56 +121,59 @@ fn handleInputMethodDestroy(
|
||||
listener: *wl.Listener(*wlr.InputMethodV2),
|
||||
input_method: *wlr.InputMethodV2,
|
||||
) void {
|
||||
const self = @fieldParentPtr(Self, "input_method_destroy", listener);
|
||||
assert(input_method == self.input_method);
|
||||
const relay = @fieldParentPtr(InputRelay, "input_method_destroy", listener);
|
||||
assert(input_method == relay.input_method);
|
||||
|
||||
self.input_method_commit.link.remove();
|
||||
self.grab_keyboard.link.remove();
|
||||
self.input_method_destroy.link.remove();
|
||||
relay.input_method_commit.link.remove();
|
||||
relay.grab_keyboard.link.remove();
|
||||
relay.input_method_destroy.link.remove();
|
||||
|
||||
self.input_method = null;
|
||||
relay.input_method = null;
|
||||
|
||||
self.focus(null);
|
||||
relay.focus(null);
|
||||
|
||||
assert(relay.text_input == null);
|
||||
}
|
||||
|
||||
fn handleInputMethodGrabKeyboard(
|
||||
listener: *wl.Listener(*wlr.InputMethodV2.KeyboardGrab),
|
||||
keyboard_grab: *wlr.InputMethodV2.KeyboardGrab,
|
||||
) void {
|
||||
const self = @fieldParentPtr(Self, "grab_keyboard", listener);
|
||||
const relay = @fieldParentPtr(InputRelay, "grab_keyboard", listener);
|
||||
const seat = @fieldParentPtr(Seat, "relay", relay);
|
||||
|
||||
const active_keyboard = self.seat.wlr_seat.getKeyboard();
|
||||
const active_keyboard = seat.wlr_seat.getKeyboard();
|
||||
keyboard_grab.setKeyboard(active_keyboard);
|
||||
|
||||
keyboard_grab.events.destroy.add(&self.grab_keyboard_destroy);
|
||||
keyboard_grab.events.destroy.add(&relay.grab_keyboard_destroy);
|
||||
}
|
||||
|
||||
fn handleInputMethodGrabKeyboardDestroy(
|
||||
listener: *wl.Listener(*wlr.InputMethodV2.KeyboardGrab),
|
||||
keyboard_grab: *wlr.InputMethodV2.KeyboardGrab,
|
||||
) void {
|
||||
const self = @fieldParentPtr(Self, "grab_keyboard_destroy", listener);
|
||||
self.grab_keyboard_destroy.link.remove();
|
||||
const relay = @fieldParentPtr(InputRelay, "grab_keyboard_destroy", listener);
|
||||
relay.grab_keyboard_destroy.link.remove();
|
||||
|
||||
if (keyboard_grab.keyboard) |keyboard| {
|
||||
keyboard_grab.input_method.seat.keyboardNotifyModifiers(&keyboard.modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn disableTextInput(self: *Self) void {
|
||||
assert(self.text_input != null);
|
||||
pub fn disableTextInput(relay: *InputRelay) void {
|
||||
assert(relay.text_input != null);
|
||||
|
||||
if (self.input_method) |input_method| {
|
||||
if (relay.input_method) |input_method| {
|
||||
input_method.sendDeactivate();
|
||||
input_method.sendDone();
|
||||
}
|
||||
|
||||
self.text_input = null;
|
||||
relay.text_input = null;
|
||||
}
|
||||
|
||||
pub fn sendInputMethodState(self: *Self) void {
|
||||
const input_method = self.input_method.?;
|
||||
const wlr_text_input = self.text_input.?.wlr_text_input;
|
||||
pub fn sendInputMethodState(relay: *InputRelay) void {
|
||||
const input_method = relay.input_method.?;
|
||||
const wlr_text_input = relay.text_input.?.wlr_text_input;
|
||||
|
||||
// TODO Send these events only if something changed.
|
||||
// On activation all events must be sent for all active features.
|
||||
@ -171,13 +200,11 @@ pub fn sendInputMethodState(self: *Self) void {
|
||||
input_method.sendDone();
|
||||
}
|
||||
|
||||
pub fn focus(self: *Self, new_focus: ?*wlr.Surface) void {
|
||||
pub fn focus(relay: *InputRelay, new_focus: ?*wlr.Surface) void {
|
||||
// Send leave events
|
||||
{
|
||||
var it = self.text_inputs.first;
|
||||
while (it) |node| : (it = node.next) {
|
||||
const text_input = &node.data;
|
||||
|
||||
var it = relay.text_inputs.iterator(.forward);
|
||||
while (it.next()) |text_input| {
|
||||
if (text_input.wlr_text_input.focused_surface) |surface| {
|
||||
// This function should not be called unless focus changes
|
||||
assert(surface != new_focus);
|
||||
@ -187,19 +214,17 @@ pub fn focus(self: *Self, new_focus: ?*wlr.Surface) void {
|
||||
}
|
||||
|
||||
// Clear currently enabled text input
|
||||
if (self.text_input != null) {
|
||||
self.disableTextInput();
|
||||
if (relay.text_input != null) {
|
||||
relay.disableTextInput();
|
||||
}
|
||||
|
||||
// Send enter events if we have an input method.
|
||||
// No text input for the new surface should be enabled yet as the client
|
||||
// should wait until it receives an enter event.
|
||||
if (new_focus) |surface| {
|
||||
if (self.input_method != null) {
|
||||
var it = self.text_inputs.first;
|
||||
while (it) |node| : (it = node.next) {
|
||||
const text_input = &node.data;
|
||||
|
||||
if (relay.input_method != null) {
|
||||
var it = relay.text_inputs.iterator(.forward);
|
||||
while (it.next()) |text_input| {
|
||||
if (text_input.wlr_text_input.resource.getClient() == surface.resource.getClient()) {
|
||||
text_input.wlr_text_input.sendEnter(surface);
|
||||
}
|
||||
|
@ -68,7 +68,9 @@ pub const FocusTarget = union(enum) {
|
||||
wlr_seat: *wlr.Seat,
|
||||
|
||||
/// Multiple mice are handled by the same Cursor
|
||||
cursor: Cursor = undefined,
|
||||
cursor: Cursor,
|
||||
/// Input Method handling
|
||||
relay: InputRelay,
|
||||
|
||||
/// ID of the current keymap mode
|
||||
mode_id: u32 = 0,
|
||||
@ -99,9 +101,6 @@ drag: enum {
|
||||
touch,
|
||||
} = .none,
|
||||
|
||||
/// Relay for communication between text_input and input_method.
|
||||
relay: InputRelay = undefined,
|
||||
|
||||
request_set_selection: wl.Listener(*wlr.Seat.event.RequestSetSelection) =
|
||||
wl.Listener(*wlr.Seat.event.RequestSetSelection).init(handleRequestSetSelection),
|
||||
request_start_drag: wl.Listener(*wlr.Seat.event.RequestStartDrag) =
|
||||
@ -119,12 +118,14 @@ pub fn init(self: *Self, name: [*:0]const u8) !void {
|
||||
self.* = .{
|
||||
// This will be automatically destroyed when the display is destroyed
|
||||
.wlr_seat = try wlr.Seat.create(server.wl_server, name),
|
||||
.cursor = undefined,
|
||||
.relay = undefined,
|
||||
.mapping_repeat_timer = mapping_repeat_timer,
|
||||
};
|
||||
self.wlr_seat.data = @intFromPtr(self);
|
||||
|
||||
try self.cursor.init(self);
|
||||
self.relay.init(self);
|
||||
self.relay.init();
|
||||
|
||||
self.wlr_seat.events.request_set_selection.add(&self.request_set_selection);
|
||||
self.wlr_seat.events.request_start_drag.add(&self.request_start_drag);
|
||||
|
@ -15,7 +15,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
const Self = @This();
|
||||
const TextInput = @This();
|
||||
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
@ -29,7 +29,8 @@ const Seat = @import("Seat.zig");
|
||||
|
||||
const log = std.log.scoped(.text_input);
|
||||
|
||||
relay: *InputRelay,
|
||||
link: wl.list.Link,
|
||||
|
||||
wlr_text_input: *wlr.TextInputV3,
|
||||
|
||||
enable: wl.Listener(*wlr.TextInputV3) =
|
||||
@ -41,68 +42,79 @@ disable: wl.Listener(*wlr.TextInputV3) =
|
||||
destroy: wl.Listener(*wlr.TextInputV3) =
|
||||
wl.Listener(*wlr.TextInputV3).init(handleDestroy),
|
||||
|
||||
pub fn init(self: *Self, relay: *InputRelay, wlr_text_input: *wlr.TextInputV3) void {
|
||||
self.* = .{
|
||||
.relay = relay,
|
||||
pub fn create(wlr_text_input: *wlr.TextInputV3) !void {
|
||||
const seat: *Seat = @ptrFromInt(wlr_text_input.seat.data);
|
||||
|
||||
const text_input = try util.gpa.create(TextInput);
|
||||
|
||||
log.debug("new text input on seat {s}", .{seat.wlr_seat.name});
|
||||
|
||||
text_input.* = .{
|
||||
.link = undefined,
|
||||
.wlr_text_input = wlr_text_input,
|
||||
};
|
||||
|
||||
wlr_text_input.events.enable.add(&self.enable);
|
||||
wlr_text_input.events.commit.add(&self.commit);
|
||||
wlr_text_input.events.disable.add(&self.disable);
|
||||
wlr_text_input.events.destroy.add(&self.destroy);
|
||||
seat.relay.text_inputs.append(text_input);
|
||||
|
||||
wlr_text_input.events.enable.add(&text_input.enable);
|
||||
wlr_text_input.events.commit.add(&text_input.commit);
|
||||
wlr_text_input.events.disable.add(&text_input.disable);
|
||||
wlr_text_input.events.destroy.add(&text_input.destroy);
|
||||
}
|
||||
|
||||
fn handleEnable(listener: *wl.Listener(*wlr.TextInputV3), _: *wlr.TextInputV3) void {
|
||||
const self = @fieldParentPtr(Self, "enable", listener);
|
||||
const text_input = @fieldParentPtr(TextInput, "enable", listener);
|
||||
const seat: *Seat = @ptrFromInt(text_input.wlr_text_input.seat.data);
|
||||
|
||||
if (self.relay.text_input != null) {
|
||||
if (seat.relay.text_input != null) {
|
||||
log.err("client requested to enable more than one text input on a single seat, ignoring request", .{});
|
||||
return;
|
||||
}
|
||||
|
||||
self.relay.text_input = self;
|
||||
seat.relay.text_input = text_input;
|
||||
|
||||
if (self.relay.input_method) |input_method| {
|
||||
if (seat.relay.input_method) |input_method| {
|
||||
input_method.sendActivate();
|
||||
self.relay.sendInputMethodState();
|
||||
seat.relay.sendInputMethodState();
|
||||
}
|
||||
}
|
||||
|
||||
fn handleCommit(listener: *wl.Listener(*wlr.TextInputV3), _: *wlr.TextInputV3) void {
|
||||
const self = @fieldParentPtr(Self, "commit", listener);
|
||||
const text_input = @fieldParentPtr(TextInput, "commit", listener);
|
||||
const seat: *Seat = @ptrFromInt(text_input.wlr_text_input.seat.data);
|
||||
|
||||
if (self.relay.text_input != self) {
|
||||
if (seat.relay.text_input != text_input) {
|
||||
log.err("inactive text input tried to commit an update, client bug?", .{});
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.relay.input_method != null) {
|
||||
self.relay.sendInputMethodState();
|
||||
if (seat.relay.input_method != null) {
|
||||
seat.relay.sendInputMethodState();
|
||||
}
|
||||
}
|
||||
|
||||
fn handleDisable(listener: *wl.Listener(*wlr.TextInputV3), _: *wlr.TextInputV3) void {
|
||||
const self = @fieldParentPtr(Self, "disable", listener);
|
||||
const text_input = @fieldParentPtr(TextInput, "disable", listener);
|
||||
const seat: *Seat = @ptrFromInt(text_input.wlr_text_input.seat.data);
|
||||
|
||||
if (self.relay.text_input == self) {
|
||||
self.relay.disableTextInput();
|
||||
if (seat.relay.text_input == text_input) {
|
||||
seat.relay.disableTextInput();
|
||||
}
|
||||
}
|
||||
|
||||
fn handleDestroy(listener: *wl.Listener(*wlr.TextInputV3), _: *wlr.TextInputV3) void {
|
||||
const self = @fieldParentPtr(Self, "destroy", listener);
|
||||
const node = @fieldParentPtr(std.TailQueue(Self).Node, "data", self);
|
||||
const text_input = @fieldParentPtr(TextInput, "destroy", listener);
|
||||
const seat: *Seat = @ptrFromInt(text_input.wlr_text_input.seat.data);
|
||||
|
||||
if (self.relay.text_input == self) {
|
||||
self.relay.disableTextInput();
|
||||
if (seat.relay.text_input == text_input) {
|
||||
seat.relay.disableTextInput();
|
||||
}
|
||||
|
||||
self.enable.link.remove();
|
||||
self.commit.link.remove();
|
||||
self.disable.link.remove();
|
||||
self.destroy.link.remove();
|
||||
text_input.enable.link.remove();
|
||||
text_input.commit.link.remove();
|
||||
text_input.disable.link.remove();
|
||||
text_input.destroy.link.remove();
|
||||
|
||||
self.relay.text_inputs.remove(node);
|
||||
util.gpa.destroy(node);
|
||||
text_input.link.remove();
|
||||
util.gpa.destroy(text_input);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user