Get things compiling again

This commit is contained in:
Isaac Freund
2020-03-23 16:50:20 +01:00
parent 50494add40
commit 523d629fe0
10 changed files with 187 additions and 159 deletions

View File

@ -1,6 +1,9 @@
const std = @import("std");
const c = @import("c.zig").c;
const Seat = @import("seat.zig").Seat;
const View = @import("view.zig").View;
const CursorMode = enum {
Passthrough,
Move,
@ -19,9 +22,9 @@ pub const Cursor = struct {
listen_axis: c.wl_listener,
listen_frame: c.wl_listener,
listen_request_cursor: c.wl_listener,
listen_request_set_cursor: c.wl_listener,
cursor_mode: CursorMode,
mode: CursorMode,
grabbed_view: ?*View,
grab_x: f64,
grab_y: f64,
@ -31,7 +34,6 @@ pub const Cursor = struct {
pub fn init(seat: *Seat) !@This() {
var cursor = @This(){
.server = seat.server,
.seat = seat,
// Creates a wlroots utility for tracking the cursor image shown on screen.
@ -81,8 +83,8 @@ pub const Cursor = struct {
.resize_edges = 0,
};
c.wlr_cursor_attach_output_layout(cursor.wlr_cursor, seat.*.server.*.output_layout);
_ = c.wlr_xcursor_manager_load(server.cursor_mgr, 1);
c.wlr_cursor_attach_output_layout(cursor.wlr_cursor, seat.server.wlr_output_layout);
_ = c.wlr_xcursor_manager_load(cursor.wlr_xcursor_manager, 1);
// wlr_cursor *only* displays an image on screen. It does not move around
// when the pointer moves. However, we can attach input devices to it, and
@ -97,18 +99,18 @@ pub const Cursor = struct {
c.wl_signal_add(&cursor.wlr_cursor.*.events.frame, &cursor.listen_frame);
// This listens for clients requesting a specific cursor image
c.wl_signal_add(&server.seat.*.events.request_set_cursor, &cursor.listen_request_set_cursor);
c.wl_signal_add(&seat.wlr_seat.events.request_set_cursor, &cursor.listen_request_set_cursor);
return cursor;
}
fn process_cursor_move(server: *Server, time: u32) void {
fn process_move(self: *@This(), time: u32) void {
// Move the grabbed view to the new position.
server.*.grabbed_view.?.*.x = @floatToInt(c_int, server.*.cursor.*.x - server.*.grab_x);
server.*.grabbed_view.?.*.y = @floatToInt(c_int, server.*.cursor.*.y - server.*.grab_y);
self.grabbed_view.?.*.x = @floatToInt(c_int, self.wlr_cursor.x - self.grab_x);
self.grabbed_view.?.*.y = @floatToInt(c_int, self.wlr_cursor.y - self.grab_y);
}
fn process_cursor_resize(server: *Server, time: u32) void {
fn process_resize(self: *@This(), time: u32) void {
// Resizing the grabbed view can be a little bit complicated, because we
// could be resizing from any corner or edge. This not only resizes the view
// on one or two axes, but can also move the view if you resize from the top
@ -117,61 +119,61 @@ pub const Cursor = struct {
// Note that I took some shortcuts here. In a more fleshed-out compositor,
// you'd wait for the client to prepare a buffer at the new size, then
// commit any movement that was prepared.
var view = server.*.grabbed_view;
var dx: f64 = (server.*.cursor.*.x - server.*.grab_x);
var dy: f64 = (server.*.cursor.*.y - server.*.grab_y);
var x: f64 = @intToFloat(f64, view.?.*.x);
var y: f64 = @intToFloat(f64, view.?.*.y);
// TODO: Handle null view
var view = self.grabbed_view;
var width = @intToFloat(f64, server.*.grab_width);
var height = @intToFloat(f64, server.*.grab_height);
if (server.*.resize_edges & @intCast(u32, c.WLR_EDGE_TOP) != 0) {
y = server.*.grab_y + dy;
var dx: f64 = self.wlr_cursor.x - self.grab_x;
var dy: f64 = self.wlr_cursor.y - self.grab_y;
var x: f64 = @intToFloat(f64, view.?.x);
var y: f64 = @intToFloat(f64, view.?.y);
var width = @intToFloat(f64, self.grab_width);
var height = @intToFloat(f64, self.grab_height);
if (self.resize_edges & @intCast(u32, c.WLR_EDGE_TOP) != 0) {
y = self.grab_y + dy;
height -= dy;
if (height < 1) {
y += height;
}
} else if (server.*.resize_edges & @intCast(u32, c.WLR_EDGE_BOTTOM) != 0) {
} else if (self.resize_edges & @intCast(u32, c.WLR_EDGE_BOTTOM) != 0) {
height += dy;
}
if (server.*.resize_edges & @intCast(u32, c.WLR_EDGE_LEFT) != 0) {
x = server.*.grab_x + dx;
if (self.resize_edges & @intCast(u32, c.WLR_EDGE_LEFT) != 0) {
x = self.grab_x + dx;
width -= dx;
if (width < 1) {
x += width;
}
} else if (server.*.resize_edges & @intCast(u32, c.WLR_EDGE_RIGHT) != 0) {
} else if (self.resize_edges & @intCast(u32, c.WLR_EDGE_RIGHT) != 0) {
width += dx;
}
view.?.*.x = @floatToInt(c_int, x);
view.?.*.y = @floatToInt(c_int, y);
view.?.x = @floatToInt(c_int, x);
view.?.y = @floatToInt(c_int, y);
_ = c.wlr_xdg_toplevel_set_size(
view.?.*.xdg_surface,
view.?.wlr_xdg_surface,
@floatToInt(u32, width),
@floatToInt(u32, height),
);
}
fn process_cursor_motion(server: *Server, time: u32) void {
fn process_motion(self: *@This(), time: u32) void {
// If the mode is non-passthrough, delegate to those functions.
if (server.*.cursor_mode == CursorMode.Move) {
process_cursor_move(server, time);
if (self.mode == CursorMode.Move) {
self.process_move(time);
return;
} else if (server.*.cursor_mode == CursorMode.Resize) {
process_cursor_resize(server, time);
} else if (self.mode == CursorMode.Resize) {
self.process_resize(time);
return;
}
// Otherwise, find the view under the pointer and send the event along.
var sx: f64 = undefined;
var sy: f64 = undefined;
var seat = server.*.seat;
var opt_surface: ?*c.wlr_surface = null;
var view = desktop_view_at(
server,
server.*.cursor.*.x,
server.*.cursor.*.y,
var view = self.seat.server.desktop_view_at(
self.wlr_cursor.x,
self.wlr_cursor.y,
&opt_surface,
&sx,
&sy,
@ -182,37 +184,38 @@ pub const Cursor = struct {
// default. This is what makes the cursor image appear when you move it
// around the screen, not over any views.
c.wlr_xcursor_manager_set_cursor_image(
server.*.cursor_mgr,
self.wlr_xcursor_manager,
"left_ptr",
server.*.cursor,
self.wlr_cursor,
);
}
var wlr_seat = self.seat.wlr_seat;
if (opt_surface) |surface| {
const focus_changed = seat.*.pointer_state.focused_surface != surface;
const focus_changed = wlr_seat.pointer_state.focused_surface != surface;
// "Enter" the surface if necessary. This lets the client know that the
// cursor has entered one of its surfaces.
//
// Note that this gives the surface "pointer focus", which is distinct
// from keyboard focus. You get pointer focus by moving the pointer over
// a window.
c.wlr_seat_pointer_notify_enter(seat, surface, sx, sy);
c.wlr_seat_pointer_notify_enter(wlr_seat, surface, sx, sy);
if (!focus_changed) {
// The enter event contains coordinates, so we only need to notify
// on motion if the focus did not change.
c.wlr_seat_pointer_notify_motion(seat, time, sx, sy);
c.wlr_seat_pointer_notify_motion(wlr_seat, time, sx, sy);
}
} else {
// 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(seat);
c.wlr_seat_pointer_clear_focus(wlr_seat);
}
}
fn handle_motion(listener: [*c]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)
var server = @fieldParentPtr(Server, "cursor_motion", listener);
var cursor = @fieldParentPtr(Cursor, "listen_motion", listener);
var event = @ptrCast(
*c.wlr_event_pointer_motion,
@alignCast(@alignOf(*c.wlr_event_pointer_motion), data),
@ -222,8 +225,8 @@ pub const Cursor = struct {
// special configuration applied for the specific input device which
// generated the event. You can pass NULL for the device if you want to move
// the cursor around without any input.
c.wlr_cursor_move(server.*.cursor, event.*.device, event.*.delta_x, event.*.delta_y);
process_cursor_motion(server, event.*.time_msec);
c.wlr_cursor_move(cursor.wlr_cursor, event.device, event.delta_x, event.delta_y);
cursor.process_motion(event.time_msec);
}
fn handle_motion_absolute(listener: [*c]c.wl_listener, data: ?*c_void) callconv(.C) void {
@ -233,39 +236,38 @@ pub const Cursor = struct {
// move the mouse over the window. You could enter the window from any edge,
// so we have to warp the mouse there. There is also some hardware which
// emits these events.
var server = @fieldParentPtr(Server, "cursor_motion_absolute", listener);
var cursor = @fieldParentPtr(Cursor, "listen_motion_absolute", listener);
var event = @ptrCast(
*c.wlr_event_pointer_motion_absolute,
@alignCast(@alignOf(*c.wlr_event_pointer_motion_absolute), data),
);
c.wlr_cursor_warp_absolute(server.*.cursor, event.*.device, event.*.x, event.*.y);
process_cursor_motion(server, event.*.time_msec);
c.wlr_cursor_warp_absolute(cursor.wlr_cursor, event.device, event.x, event.y);
cursor.process_motion(event.time_msec);
}
fn handle_button(listener: [*c]c.wl_listener, data: ?*c_void) callconv(.C) void {
// This event is forwarded by the cursor when a pointer emits a button
// event.
var server = @fieldParentPtr(Server, "cursor_button", listener);
var cursor = @fieldParentPtr(Cursor, "listen_button", listener);
var event = @ptrCast(
*c.wlr_event_pointer_button,
@alignCast(@alignOf(*c.wlr_event_pointer_button), data),
);
// Notify the client with pointer focus that a button press has occurred
_ = c.wlr_seat_pointer_notify_button(
server.*.seat,
event.*.time_msec,
event.*.button,
event.*.state,
cursor.seat.wlr_seat,
event.time_msec,
event.button,
event.state,
);
var sx: f64 = undefined;
var sy: f64 = undefined;
var surface: ?*c.wlr_surface = null;
var view = desktop_view_at(
server,
server.*.cursor.*.x,
server.*.cursor.*.y,
var view = cursor.seat.server.desktop_view_at(
cursor.wlr_cursor.x,
cursor.wlr_cursor.y,
&surface,
&sx,
&sy,
@ -273,11 +275,11 @@ pub const Cursor = struct {
if (event.*.state == c.enum_wlr_button_state.WLR_BUTTON_RELEASED) {
// If you released any buttons, we exit interactive move/resize mode.
server.*.cursor_mode = CursorMode.Passthrough;
cursor.mode = CursorMode.Passthrough;
} else {
// Focus that client if the button was _pressed_
if (view) |v| {
focus_view(v, surface.?);
v.focus(surface.?);
}
}
}
@ -285,19 +287,20 @@ pub const Cursor = struct {
fn handle_axis(listener: [*c]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.
var server = @fieldParentPtr(Server, "cursor_axis", listener);
var cursor = @fieldParentPtr(Cursor, "listen_axis", listener);
var event = @ptrCast(
*c.wlr_event_pointer_axis,
@alignCast(@alignOf(*c.wlr_event_pointer_axis), data),
);
// Notify the client with pointer focus of the axis event.
c.wlr_seat_pointer_notify_axis(
server.*.seat,
event.*.time_msec,
event.*.orientation,
event.*.delta,
event.*.delta_discrete,
event.*.source,
cursor.seat.wlr_seat,
event.time_msec,
event.orientation,
event.delta,
event.delta_discrete,
event.source,
);
}
@ -306,19 +309,19 @@ pub const Cursor = struct {
// event. Frame events are sent after regular pointer events to group
// multiple events together. For instance, two axis events may happen at the
// same time, in which case a frame event won't be sent in between.
var server = @fieldParentPtr(Server, "cursor_frame", listener);
var cursor = @fieldParentPtr(Cursor, "listen_frame", listener);
// Notify the client with pointer focus of the frame event.
c.wlr_seat_pointer_notify_frame(server.*.seat);
c.wlr_seat_pointer_notify_frame(cursor.seat.wlr_seat);
}
fn handle_request_set_cursor(listener: [*c]c.wl_listener, data: ?*c_void) callconv(.C) void {
// This event is rasied by the seat when a client provides a cursor image
var server = @fieldParentPtr(Server, "request_cursor", listener);
var cursor = @fieldParentPtr(Cursor, "listen_request_set_cursor", listener);
var event = @ptrCast(
*c.wlr_seat_pointer_request_set_cursor_event,
@alignCast(@alignOf(*c.wlr_seat_pointer_request_set_cursor_event), data),
);
var focused_client = server.*.seat.*.pointer_state.focused_client;
const focused_client = cursor.seat.wlr_seat.pointer_state.focused_client;
// This can be sent by any client, so we check to make sure this one is
// actually has pointer focus first.
@ -328,10 +331,10 @@ pub const Cursor = struct {
// on the output that it's currently on and continue to do so as the
// cursor moves between outputs.
c.wlr_cursor_set_surface(
server.*.cursor,
event.*.surface,
event.*.hotspot_x,
event.*.hotspot_y,
cursor.wlr_cursor,
event.surface,
event.hotspot_x,
event.hotspot_y,
);
}
}