diff --git a/src/server/cursor.zig b/src/server/cursor.zig index ad610a1..2f5a155 100644 --- a/src/server/cursor.zig +++ b/src/server/cursor.zig @@ -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); + } }; diff --git a/src/server/server.zig b/src/server/server.zig index aef3684..315e16a 100644 --- a/src/server/server.zig +++ b/src/server/server.zig @@ -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), }; diff --git a/src/tinywl-missing.zig b/src/tinywl-missing.zig index 5b49448..1eefacd 100644 --- a/src/tinywl-missing.zig +++ b/src/tinywl-missing.zig @@ -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));