Make Cursor a toplevel struct

This commit is contained in:
Isaac Freund 2020-05-02 16:47:10 +02:00
parent a73343c92f
commit 97d395dbfc
No known key found for this signature in database
GPG key ID: 86DED400DDFD7A11
2 changed files with 334 additions and 335 deletions

View file

@ -1,4 +1,7 @@
const Self = @This();
const std = @import("std");
const c = @import("c.zig");
const LayerSurface = @import("layer_surface.zig");
@ -14,29 +17,26 @@ const CursorMode = enum {
Resize,
};
pub const Cursor = struct {
const Self = @This();
seat: *Seat,
wlr_cursor: *c.wlr_cursor,
wlr_xcursor_manager: *c.wlr_xcursor_manager,
seat: *Seat,
wlr_cursor: *c.wlr_cursor,
wlr_xcursor_manager: *c.wlr_xcursor_manager,
mode: CursorMode,
grabbed_view: ?*View,
grab_x: f64,
grab_y: f64,
grab_width: c_int,
grab_height: c_int,
resize_edges: u32,
mode: CursorMode,
grabbed_view: ?*View,
grab_x: f64,
grab_y: f64,
grab_width: c_int,
grab_height: c_int,
resize_edges: u32,
listen_axis: c.wl_listener,
listen_button: c.wl_listener,
listen_frame: c.wl_listener,
listen_motion_absolute: c.wl_listener,
listen_motion: c.wl_listener,
listen_request_set_cursor: c.wl_listener,
listen_axis: c.wl_listener,
listen_button: c.wl_listener,
listen_frame: c.wl_listener,
listen_motion_absolute: c.wl_listener,
listen_motion: c.wl_listener,
listen_request_set_cursor: c.wl_listener,
pub fn init(self: *Self, seat: *Seat) !void {
pub fn init(self: *Self, seat: *Seat) !void {
self.seat = seat;
// Creates a wlroots utility for tracking the cursor image shown on screen.
@ -88,14 +88,14 @@ pub const Cursor = struct {
self.listen_request_set_cursor.notify = handleRequestSetCursor;
c.wl_signal_add(&self.seat.wlr_seat.events.request_set_cursor, &self.listen_request_set_cursor);
}
}
pub fn deinit(self: *Self) void {
pub fn deinit(self: *Self) void {
c.wlr_xcursor_manager_destroy(self.wlr_xcursor_manager);
c.wlr_cursor_destroy(self.wlr_cursor);
}
}
fn handleAxis(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
fn handleAxis(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
// This event is forwarded by the cursor when a pointer emits an axis event,
// for example when you move the scroll wheel.
const cursor = @fieldParentPtr(Self, "listen_axis", listener.?);
@ -113,9 +113,9 @@ pub const Cursor = struct {
event.delta_discrete,
event.source,
);
}
}
fn handleButton(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
fn handleButton(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
// This event is forwarded by the cursor when a pointer emits a button
// event.
const self = @fieldParentPtr(Self, "listen_button", listener.?);
@ -157,9 +157,9 @@ pub const Cursor = struct {
event.state,
);
}
}
}
fn handleFrame(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
fn handleFrame(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
// This event is forwarded by the cursor when a pointer emits an frame
// event. Frame events are sent after regular pointer events to group
// multiple events together. For instance, two axis events may happen at the
@ -167,9 +167,9 @@ pub const Cursor = struct {
const self = @fieldParentPtr(Self, "listen_frame", listener.?);
// Notify the client with pointer focus of the frame event.
c.wlr_seat_pointer_notify_frame(self.seat.wlr_seat);
}
}
fn handleMotionAbsolute(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
fn handleMotionAbsolute(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
// This event is forwarded by the cursor when a pointer emits an _absolute_
// motion event, from 0..1 on each axis. This happens, for example, when
// wlroots is running under a Wayland window rather than KMS+DRM, and you
@ -183,9 +183,9 @@ pub const Cursor = struct {
);
c.wlr_cursor_warp_absolute(self.wlr_cursor, event.device, event.x, event.y);
self.processMotion(event.time_msec);
}
}
fn handleMotion(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
fn handleMotion(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
// This event is forwarded by the cursor when a pointer emits a _relative_
// pointer motion event (i.e. a delta)
const self = @fieldParentPtr(Self, "listen_motion", listener.?);
@ -200,9 +200,9 @@ pub const Cursor = struct {
// the cursor around without any input.
c.wlr_cursor_move(self.wlr_cursor, event.device, event.delta_x, event.delta_y);
self.processMotion(event.time_msec);
}
}
fn handleRequestSetCursor(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
fn handleRequestSetCursor(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
// This event is rasied by the seat when a client provides a cursor image
const self = @fieldParentPtr(Self, "listen_request_set_cursor", listener.?);
const event = @ptrCast(
@ -225,9 +225,9 @@ pub const Cursor = struct {
event.hotspot_y,
);
}
}
}
fn processMotion(self: Self, time: u32) void {
fn processMotion(self: Self, time: u32) void {
var sx: f64 = undefined;
var sy: f64 = undefined;
if (self.surfaceAt(self.wlr_cursor.x, self.wlr_cursor.y, &sx, &sy)) |wlr_surface| {
@ -262,12 +262,12 @@ pub const Cursor = struct {
// Clear pointer focus so future button events and such are not sent to
// the last client to have the cursor over it.
c.wlr_seat_pointer_clear_focus(self.seat.wlr_seat);
}
}
/// Find the topmost surface under the output layout coordinates lx/ly
/// returns the surface if found and sets the sx/sy parametes to the
/// surface coordinates.
fn surfaceAt(self: Self, lx: f64, ly: f64, sx: *f64, sy: *f64) ?*c.wlr_surface {
/// Find the topmost surface under the output layout coordinates lx/ly
/// returns the surface if found and sets the sx/sy parametes to the
/// surface coordinates.
fn surfaceAt(self: Self, lx: f64, ly: f64, sx: *f64, sy: *f64) ?*c.wlr_surface {
// Find the output to check
const root = self.seat.input_manager.server.root;
const wlr_output = c.wlr_output_layout_output_at(root.wlr_output_layout, lx, ly) orelse
@ -323,11 +323,11 @@ pub const Cursor = struct {
}
return null;
}
}
/// Find the topmost surface on the given layer at ox,oy. Will only check
/// popups if popups_only is true.
fn layerSurfaceAt(
/// Find the topmost surface on the given layer at ox,oy. Will only check
/// popups if popups_only is true.
fn layerSurfaceAt(
output: Output,
layer: std.TailQueue(LayerSurface),
ox: f64,
@ -335,7 +335,7 @@ pub const Cursor = struct {
sx: *f64,
sy: *f64,
popups_only: bool,
) ?*c.wlr_surface {
) ?*c.wlr_surface {
var it = layer.first;
while (it) |node| : (it = node.next) {
const layer_surface = &node.data;
@ -358,11 +358,11 @@ pub const Cursor = struct {
}
}
return null;
}
}
/// Find the topmost visible view surface (incl. popups) at ox,oy. Will
/// check only floating views if floating is true.
fn viewSurfaceAt(output: Output, ox: f64, oy: f64, sx: *f64, sy: *f64, floating: bool) ?*c.wlr_surface {
/// Find the topmost visible view surface (incl. popups) at ox,oy. Will
/// check only floating views if floating is true.
fn viewSurfaceAt(output: Output, ox: f64, oy: f64, sx: *f64, sy: *f64, floating: bool) ?*c.wlr_surface {
var it = ViewStack(View).iterator(output.views.first, output.current_focused_tags);
while (it.next()) |node| {
const view = &node.view;
@ -383,5 +383,4 @@ pub const Cursor = struct {
}
}
return null;
}
};
}

View file

@ -3,7 +3,7 @@ const Self = @This();
const c = @import("c.zig");
const std = @import("std");
const Cursor = @import("cursor.zig").Cursor;
const Cursor = @import("cursor.zig");
const InputManager = @import("input_manager.zig");
const Keyboard = @import("keyboard.zig").Keyboard;
const LayerSurface = @import("layer_surface.zig");