Add cursor events

This commit is contained in:
2023-12-31 01:06:36 +01:00
parent 4488fe0895
commit 4cf23a5575
3 changed files with 99 additions and 58 deletions
+41 -1
View File
@@ -5,6 +5,7 @@ const wl = @import("wayland").server.wl;
const wlr = @import("wlroots");
const Server = @import("server.zig").Server;
const Api = @import("../commands.zig");
pub const Cursor = struct {
server: *Server,
@@ -17,11 +18,14 @@ pub const Cursor = struct {
axis: wl.Listener(*wlr.Pointer.event.Axis) = wl.Listener(*wlr.Pointer.event.Axis).init(onAxis),
frame: wl.Listener(*wlr.Cursor) = wl.Listener(*wlr.Cursor).init(onFrame),
request_set_cursor_l: wl.Listener(*wlr.Seat.event.RequestSetCursor) = wl.Listener(*wlr.Seat.event.RequestSetCursor).init(onRequestSetCursor),
request_set_selection_l: wl.Listener(*wlr.Seat.event.RequestSetSelection) = wl.Listener(*wlr.Seat.event.RequestSetSelection).init(onRequestSetSelection),
pub fn onNewPointer(self: *Cursor, device: *wlr.InputDevice) void {
self.cursor.attachInputDevice(device);
}
pub fn create(server: *Server, output_layout: *wlr.OutputLayout) !*Cursor {
pub fn create(server: *Server, output_layout: *wlr.OutputLayout, seat: *wlr.Seat) !*Cursor {
const self = try gpa.create(Cursor);
errdefer gpa.destroy(self);
self.* = .{
@@ -38,24 +42,42 @@ pub const Cursor = struct {
self.cursor.events.button.add(&self.button);
self.cursor.events.axis.add(&self.axis);
self.cursor.events.frame.add(&self.frame);
seat.events.request_set_cursor.add(&self.request_set_cursor_l);
seat.events.request_set_selection.add(&self.request_set_selection_l);
return self;
}
pub fn destroy(self: *Cursor) void {
self.request_set_cursor_l.link.remove();
self.request_set_selection_l.link.remove();
self.motion.link.remove();
self.motion_absolute.link.remove();
self.button.link.remove();
self.axis.link.remove();
self.frame.link.remove();
gpa.destroy(self);
}
fn handleMotion(self: *Cursor, time_msec: u32) void {
if (Api.clientAt(self.server, self.cursor.x, self.cursor.y)) |res| {
self.server.seat.pointerNotifyEnter(res.surface, res.x, res.y);
self.server.seat.pointerNotifyMotion(time_msec, res.x, res.y);
} else {
self.cursor.setXcursor(self.cursor_mgr, "default");
self.server.seat.pointerClearFocus();
}
}
fn onMotion(
listener: *wl.Listener(*wlr.Pointer.event.Motion),
event: *wlr.Pointer.event.Motion,
) void {
const self = @fieldParentPtr(Cursor, "motion", listener);
self.cursor.move(event.device, event.delta_x, event.delta_y);
self.handleMotion(event.time_msec);
}
fn onMotionAbsolute(
@@ -64,6 +86,7 @@ pub const Cursor = struct {
) void {
const self = @fieldParentPtr(Cursor, "motion_absolute", listener);
self.cursor.warpAbsolute(event.device, event.x, event.y);
self.handleMotion(event.time_msec);
}
fn onButton(
@@ -92,4 +115,21 @@ pub const Cursor = struct {
const self = @fieldParentPtr(Cursor, "frame", listener);
self.server.seat.pointerNotifyFrame();
}
fn onRequestSetCursor(
listener: *wl.Listener(*wlr.Seat.event.RequestSetCursor),
event: *wlr.Seat.event.RequestSetCursor,
) void {
const self = @fieldParentPtr(Cursor, "request_set_cursor_l", listener);
if (event.seat_client == self.server.seat.pointer_state.focused_client)
self.cursor.setSurface(event.surface, event.hotspot_x, event.hotspot_y);
}
fn onRequestSetSelection(
listener: *wl.Listener(*wlr.Seat.event.RequestSetSelection),
event: *wlr.Seat.event.RequestSetSelection,
) void {
const self = @fieldParentPtr(Cursor, "request_set_selection_l", listener);
self.server.seat.setSelection(event.source, event.serial);
}
};
+3 -2
View File
@@ -38,6 +38,7 @@ pub const Server = struct {
const renderer = try wlr.Renderer.autocreate(backend);
const output_layout = try wlr.OutputLayout.create();
const scene = try wlr.Scene.create();
const seat = try wlr.Seat.create(wl_server, "default");
self.* = Server{
.wl_server = wl_server,
@@ -48,8 +49,8 @@ pub const Server = struct {
.output_layout = output_layout,
.scene_output_layout = try scene.attachOutputLayout(output_layout),
.xdg_shell = try wlr.XdgShell.create(wl_server, 2),
.seat = try wlr.Seat.create(wl_server, "default"),
.cursor = try Cursor.create(self, output_layout),
.seat = seat,
.cursor = try Cursor.create(self, output_layout, seat),
.events = undefined,
.socket = try wl_server.addSocketAuto(&socket_buf),
};
+55 -55
View File
@@ -51,8 +51,8 @@ const Server = struct {
seat: *wlr.Seat,
// new_input: wl.Listener(*wlr.InputDevice) = wl.Listener(*wlr.InputDevice).init(newInput),
request_set_cursor: wl.Listener(*wlr.Seat.event.RequestSetCursor) = wl.Listener(*wlr.Seat.event.RequestSetCursor).init(requestSetCursor),
request_set_selection: wl.Listener(*wlr.Seat.event.RequestSetSelection) = wl.Listener(*wlr.Seat.event.RequestSetSelection).init(requestSetSelection),
// request_set_cursor: wl.Listener(*wlr.Seat.event.RequestSetCursor) = wl.Listener(*wlr.Seat.event.RequestSetCursor).init(requestSetCursor),
// request_set_selection: wl.Listener(*wlr.Seat.event.RequestSetSelection) = wl.Listener(*wlr.Seat.event.RequestSetSelection).init(requestSetSelection),
// keyboards: wl.list.Head(Keyboard, .link) = undefined,
// cursor: *wlr.Cursor,
@@ -99,11 +99,11 @@ const Server = struct {
// server.backend.events.new_output.add(&server.new_output);
// server.xdg_shell.events.new_surface.add(&server.new_xdg_surface);
server.views.init();
// server.views.init();
// server.backend.events.new_input.add(&server.new_input);
server.seat.events.request_set_cursor.add(&server.request_set_cursor);
server.seat.events.request_set_selection.add(&server.request_set_selection);
// server.seat.events.request_set_cursor.add(&server.request_set_cursor);
// server.seat.events.request_set_selection.add(&server.request_set_selection);
server.keyboards.init();
// server.cursor.attachOutputLayout(server.output_layout);
@@ -188,35 +188,35 @@ const Server = struct {
}
}
const ViewAtResult = struct {
view: *View,
surface: *wlr.Surface,
sx: f64,
sy: f64,
};
// const ViewAtResult = struct {
// view: *View,
// surface: *wlr.Surface,
// sx: f64,
// sy: f64,
// };
fn viewAt(server: *Server, lx: f64, ly: f64) ?ViewAtResult {
var sx: f64 = undefined;
var sy: f64 = undefined;
if (server.scene.tree.node.at(lx, ly, &sx, &sy)) |node| {
if (node.type != .buffer) return null;
const scene_buffer = wlr.SceneBuffer.fromNode(node);
const scene_surface = wlr.SceneSurface.tryFromBuffer(scene_buffer) orelse return null;
var it: ?*wlr.SceneTree = node.parent;
while (it) |n| : (it = n.node.parent) {
if (@as(?*View, @ptrFromInt(n.node.data))) |view| {
return ViewAtResult{
.view = view,
.surface = scene_surface.surface,
.sx = sx,
.sy = sy,
};
}
}
}
return null;
}
// fn viewAt(server: *Server, lx: f64, ly: f64) ?ViewAtResult {
// var sx: f64 = undefined;
// var sy: f64 = undefined;
// if (server.scene.tree.node.at(lx, ly, &sx, &sy)) |node| {
// if (node.type != .buffer) return null;
// const scene_buffer = wlr.SceneBuffer.fromNode(node);
// const scene_surface = wlr.SceneSurface.tryFromBuffer(scene_buffer) orelse return null;
//
// var it: ?*wlr.SceneTree = node.parent;
// while (it) |n| : (it = n.node.parent) {
// if (@as(?*View, @ptrFromInt(n.node.data))) |view| {
// return ViewAtResult{
// .view = view,
// .surface = scene_surface.surface,
// .sx = sx,
// .sy = sy,
// };
// }
// }
// }
// return null;
// }
// fn focusView(server: *Server, view: *View, surface: *wlr.Surface) void {
// if (server.seat.keyboard_state.focused_surface) |previous_surface| {
@@ -258,22 +258,22 @@ const Server = struct {
// });
// }
fn requestSetCursor(
listener: *wl.Listener(*wlr.Seat.event.RequestSetCursor),
event: *wlr.Seat.event.RequestSetCursor,
) void {
const server = @fieldParentPtr(Server, "request_set_cursor", listener);
if (event.seat_client == server.seat.pointer_state.focused_client)
server.cursor.setSurface(event.surface, event.hotspot_x, event.hotspot_y);
}
// fn requestSetCursor(
// listener: *wl.Listener(*wlr.Seat.event.RequestSetCursor),
// event: *wlr.Seat.event.RequestSetCursor,
// ) void {
// const server = @fieldParentPtr(Server, "request_set_cursor", listener);
// if (event.seat_client == server.seat.pointer_state.focused_client)
// server.cursor.setSurface(event.surface, event.hotspot_x, event.hotspot_y);
// }
fn requestSetSelection(
listener: *wl.Listener(*wlr.Seat.event.RequestSetSelection),
event: *wlr.Seat.event.RequestSetSelection,
) void {
const server = @fieldParentPtr(Server, "request_set_selection", listener);
server.seat.setSelection(event.source, event.serial);
}
// fn requestSetSelection(
// listener: *wl.Listener(*wlr.Seat.event.RequestSetSelection),
// event: *wlr.Seat.event.RequestSetSelection,
// ) void {
// const server = @fieldParentPtr(Server, "request_set_selection", listener);
// server.seat.setSelection(event.source, event.serial);
// }
// fn cursorMotion(
// listener: *wl.Listener(*wlr.Pointer.event.Motion),
@@ -295,13 +295,13 @@ const Server = struct {
fn processCursorMotion(server: *Server, time_msec: u32) void {
switch (server.cursor_mode) {
.passthrough => if (server.viewAt(server.cursor.x, server.cursor.y)) |res| {
server.seat.pointerNotifyEnter(res.surface, res.sx, res.sy);
server.seat.pointerNotifyMotion(time_msec, res.sx, res.sy);
} else {
server.cursor.setXcursor(server.cursor_mgr, "default");
server.seat.pointerClearFocus();
},
// .passthrough => if (server.viewAt(server.cursor.x, server.cursor.y)) |res| {
// server.seat.pointerNotifyEnter(res.surface, res.sx, res.sy);
// server.seat.pointerNotifyMotion(time_msec, res.sx, res.sy);
// } else {
// server.cursor.setXcursor(server.cursor_mgr, "default");
// server.seat.pointerClearFocus();
// },
.move => {
const view = server.grabbed_view.?;
view.x = @as(i32, @intFromFloat(server.cursor.x - server.grab_x));