mirror of
https://github.com/MezzalunaWM/Mezzaluna.git
synced 2026-03-07 19:49:53 -05:00
cleaning up code, adding support for workspaces, and handling errors
This commit is contained in:
parent
6bfebb0e37
commit
609ee42d66
10 changed files with 204 additions and 137 deletions
20
.vscode/launch.json
vendored
20
.vscode/launch.json
vendored
|
|
@ -1,20 +0,0 @@
|
|||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "(lldb) Launch",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/zig-out/bin/mez",
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"internalConsoleOptions": "openOnSessionStart",
|
||||
"MIMode": "lldb",
|
||||
"MIDebuggerPath": "/bin/lldb",
|
||||
"preLaunchTask": "build",
|
||||
}
|
||||
]
|
||||
}
|
||||
15
.vscode/tasks.json
vendored
15
.vscode/tasks.json
vendored
|
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "build",
|
||||
"type": "shell",
|
||||
"command": "zig build",
|
||||
"problemMatcher": [],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
# Mezzaluna
|
||||
|
||||
WIP wayland compositor.
|
||||
A utensil for chopping herbs, vegetables, or pizza, with a large semicircular blade and a handle at each end.
|
||||
|
||||
The idea is that Mezzaluna takes care of the hardwork while leaving configuration, tiling behaviour and general exstensability to be done with easy to write Lua.
|
||||
|
|
|
|||
|
|
@ -19,11 +19,12 @@ frame: wl.Listener(*wlr.Cursor) = .init(handleFrame),
|
|||
hold_begin: wl.Listener(*wlr.Pointer.event.HoldBegin) = .init(handleHoldBegin),
|
||||
hold_end: wl.Listener(*wlr.Pointer.event.HoldEnd) = .init(handleHoldEnd),
|
||||
|
||||
cursor_mode: enum { passthrough, move, resize } = .passthrough,
|
||||
mode: enum { passthrough, move, resize } = .passthrough,
|
||||
grabbed_view: ?*View = null,
|
||||
grab_x: f64 = 0,
|
||||
grab_y: f64 = 0,
|
||||
grab_box: wlr.Box = undefined,
|
||||
resize_edges: wlr.Edges = .{},
|
||||
|
||||
pub fn init(self: *Cursor) !void {
|
||||
self.* = .{
|
||||
|
|
@ -56,14 +57,62 @@ pub fn deinit(self: *Cursor) void {
|
|||
}
|
||||
|
||||
pub fn processCursorMotion(self: *Cursor, time_msec: u32) void {
|
||||
if (server.root.viewAt(self.wlr_cursor.x, self.wlr_cursor.y)) |res| {
|
||||
std.log.debug("we found a view", .{});
|
||||
server.seat.wlr_seat.pointerNotifyEnter(res.surface, res.sx, res.sy);
|
||||
server.seat.wlr_seat.pointerNotifyMotion(time_msec, res.sx, res.sy);
|
||||
} else {
|
||||
std.log.debug("no view found", .{});
|
||||
self.wlr_cursor.setXcursor(self.x_cursor_manager, "default");
|
||||
server.seat.wlr_seat.pointerClearFocus();
|
||||
switch (self.mode) {
|
||||
.passthrough => {
|
||||
if (server.root.viewAt(self.wlr_cursor.x, self.wlr_cursor.y)) |res| {
|
||||
server.seat.wlr_seat.pointerNotifyEnter(res.surface, res.sx, res.sy);
|
||||
server.seat.wlr_seat.pointerNotifyMotion(time_msec, res.sx, res.sy);
|
||||
} else {
|
||||
self.wlr_cursor.setXcursor(self.x_cursor_manager, "default");
|
||||
server.seat.wlr_seat.pointerClearFocus();
|
||||
}
|
||||
},
|
||||
.move => {
|
||||
const view = self.grabbed_view.?;
|
||||
// Should we modify the XdgSurface geometry directly???
|
||||
view.geometry.x = @as(i32, @intFromFloat(self.wlr_cursor.x - self.grab_x));
|
||||
view.geometry.y = @as(i32, @intFromFloat(self.wlr_cursor.y - self.grab_y));
|
||||
view.scene_tree.node.setPosition(view.geometry.x, view.geometry.y);
|
||||
},
|
||||
.resize => {
|
||||
// Fix this resize
|
||||
const view = self.grabbed_view.?;
|
||||
const border_x = @as(i32, @intFromFloat(self.wlr_cursor.x - self.grab_x));
|
||||
const border_y = @as(i32, @intFromFloat(self.wlr_cursor.y - self.grab_y));
|
||||
|
||||
var new_left = self.grab_box.x;
|
||||
var new_right = self.grab_box.x + self.grab_box.width;
|
||||
var new_top = self.grab_box.y;
|
||||
var new_bottom = self.grab_box.y + self.grab_box.height;
|
||||
|
||||
if (self.resize_edges.top) {
|
||||
new_top = border_y;
|
||||
if (new_top >= new_bottom)
|
||||
new_top = new_bottom - 1;
|
||||
} else if (self.resize_edges.bottom) {
|
||||
new_bottom = border_y;
|
||||
if (new_bottom <= new_top)
|
||||
new_bottom = new_top + 1;
|
||||
}
|
||||
|
||||
if (self.resize_edges.left) {
|
||||
new_left = border_x;
|
||||
if (new_left >= new_right)
|
||||
new_left = new_right - 1;
|
||||
} else if (self.resize_edges.right) {
|
||||
new_right = border_x;
|
||||
if (new_right <= new_left)
|
||||
new_right = new_left + 1;
|
||||
}
|
||||
|
||||
// view.x = new_left - view.xdg_toplevel.base.geometry.x;
|
||||
// view.y = new_top - view.xdg_toplevel.base.geometry.y;
|
||||
view.scene_tree.node.setPosition(view.geometry.x, view.geometry.y);
|
||||
|
||||
const new_width = new_right - new_left;
|
||||
const new_height = new_bottom - new_top;
|
||||
_ = view.xdg_toplevel.setSize(new_width, new_height);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -88,9 +137,20 @@ fn handleButton(
|
|||
_: *wl.Listener(*wlr.Pointer.event.Button),
|
||||
event: *wlr.Pointer.event.Button,
|
||||
) void {
|
||||
_ = server.seat.wlr_seat.pointerNotifyButton(event.time_msec, event.button, event.state);
|
||||
if (server.root.viewAt(server.cursor.wlr_cursor.x, server.cursor.wlr_cursor.y)) |res| {
|
||||
server.root.focusView(res.view);
|
||||
switch (event.state) {
|
||||
.pressed => {
|
||||
_ = server.seat.wlr_seat.pointerNotifyButton(event.time_msec, event.button, event.state);
|
||||
if (server.root.viewAt(server.cursor.wlr_cursor.x, server.cursor.wlr_cursor.y)) |res| {
|
||||
server.root.focusView(res.view);
|
||||
}
|
||||
},
|
||||
.released => {
|
||||
std.log.debug("Button released", .{});
|
||||
server.cursor.mode = .passthrough;
|
||||
},
|
||||
else => {
|
||||
std.log.err("Unexpected button state", .{});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,14 @@
|
|||
const Output = @This();
|
||||
|
||||
const std = @import("std");
|
||||
const posix = std.posix;
|
||||
const gpa = std.heap.c_allocator;
|
||||
const server = &@import("main.zig").server;
|
||||
|
||||
const wl = @import("wayland").server.wl;
|
||||
const wlr = @import("wlroots");
|
||||
|
||||
const std = @import("std");
|
||||
const Server = @import("server.zig");
|
||||
|
||||
const posix = std.posix;
|
||||
const gpa = std.heap.c_allocator;
|
||||
const server = &@import("main.zig").server;
|
||||
|
||||
wlr_output: *wlr.Output,
|
||||
scene_output: *wlr.SceneOutput,
|
||||
|
||||
|
|
|
|||
39
src/root.zig
39
src/root.zig
|
|
@ -6,6 +6,7 @@ const wlr = @import("wlroots");
|
|||
|
||||
const Output = @import("output.zig");
|
||||
const View = @import("view.zig");
|
||||
const Utils = @import("utils.zig");
|
||||
|
||||
const server = &@import("main.zig").server;
|
||||
const gpa = std.heap.c_allocator;
|
||||
|
|
@ -15,11 +16,14 @@ scene_output_layout: *wlr.SceneOutputLayout,
|
|||
|
||||
output_layout: *wlr.OutputLayout,
|
||||
|
||||
all_views: std.ArrayList(*View),
|
||||
views: std.ArrayList(View) = undefined,
|
||||
workspaces: std.ArrayList(*wlr.SceneTree) = undefined,
|
||||
|
||||
pub fn init(self: *Root) !void {
|
||||
pub fn init(self: *Root) void {
|
||||
std.log.info("Creating root of mezzaluna\n", .{});
|
||||
|
||||
errdefer Utils.oomPanic();
|
||||
|
||||
const output_layout = try wlr.OutputLayout.create(server.wl_server);
|
||||
errdefer output_layout.destroy();
|
||||
|
||||
|
|
@ -30,21 +34,28 @@ pub fn init(self: *Root) !void {
|
|||
.scene = scene,
|
||||
.output_layout = output_layout,
|
||||
.scene_output_layout = try scene.attachOutputLayout(output_layout),
|
||||
|
||||
.all_views = try .initCapacity(gpa, 10),
|
||||
};
|
||||
|
||||
self.views = std.ArrayList(View).initCapacity(gpa, 10); // Should consider number better, prolly won't matter that much though
|
||||
// Even though I would never use a changing amount of workspaces, opens more extensibility
|
||||
self.workspaces = std.ArrayList(*wlr.SceneTree).initCapacity(gpa, 10); // TODO: change to a configured number of workspaces
|
||||
|
||||
// TODO: Make configurable
|
||||
for(0..9) |_| {
|
||||
self.workspaces.append(gpa, try self.scene.tree.createSceneTree());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Root) void {
|
||||
self.workspaces.deinit(gpa);
|
||||
self.views.deinit(gpa);
|
||||
|
||||
self.output_layout.destroy();
|
||||
self.scene.tree.node.destroy();
|
||||
}
|
||||
|
||||
pub fn addOutput(self: *Root, new_output: *Output) void {
|
||||
_ = self.output_layout.addAuto(new_output.wlr_output) catch {
|
||||
std.log.err("failed to add new output to output layout\n", .{});
|
||||
return;
|
||||
};
|
||||
_ = self.output_layout.addAuto(new_output.wlr_output) catch Utils.oomPanic();
|
||||
}
|
||||
|
||||
const ViewAtResult = struct {
|
||||
|
|
@ -57,19 +68,17 @@ const ViewAtResult = struct {
|
|||
pub fn viewAt(self: *Root, lx: f64, ly: f64) ?ViewAtResult {
|
||||
var sx: f64 = undefined;
|
||||
var sy: f64 = undefined;
|
||||
|
||||
if (self.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;
|
||||
|
||||
std.log.debug("Starting parent walk from buffer node", .{});
|
||||
var it: ?*wlr.SceneTree = node.parent;
|
||||
|
||||
while (it) |n| : (it = n.node.parent) {
|
||||
if (n.node.data) |data_ptr| {
|
||||
if (@as(?*View, @ptrCast(@alignCast(data_ptr)))) |view| {
|
||||
std.log.debug("View found", .{});
|
||||
|
||||
return ViewAtResult{
|
||||
.view = view,
|
||||
.surface = scene_surface.surface,
|
||||
|
|
@ -92,10 +101,10 @@ pub fn focusView(_: *Root, view: *View) void {
|
|||
}
|
||||
|
||||
view.scene_tree.node.raiseToTop();
|
||||
// view.link.remove();
|
||||
_ = server.root.all_views.append(gpa, view) catch {
|
||||
unreachable;
|
||||
};
|
||||
|
||||
// _ = server.root.all_views.append(gpa, view) catch {
|
||||
// unreachable;
|
||||
// };
|
||||
|
||||
_ = view.xdg_toplevel.setActivated(true);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
const Seat = @This();
|
||||
|
||||
const std = @import("std");
|
||||
const server = &@import("main.zig").server;
|
||||
|
||||
const wlr = @import("wlroots");
|
||||
const wl = @import("wayland").server.wl;
|
||||
|
||||
const server = &@import("main.zig").server;
|
||||
|
||||
wlr_seat: *wlr.Seat,
|
||||
|
||||
request_set_cursor: wl.Listener(*wlr.Seat.event.RequestSetCursor) = .init(handleRequestSetCursor),
|
||||
|
|
@ -23,10 +23,10 @@ pub fn init(self: *Seat) !void {
|
|||
}
|
||||
|
||||
pub fn deinit(self: *Seat) void {
|
||||
self.wlr_seat.destroy();
|
||||
|
||||
self.request_set_cursor.link.remove();
|
||||
self.request_set_selection.link.remove();
|
||||
|
||||
self.wlr_seat.destroy();
|
||||
}
|
||||
|
||||
fn handleRequestSetCursor(
|
||||
|
|
|
|||
|
|
@ -47,18 +47,32 @@ new_xdg_popup: wl.Listener(*wlr.XdgPopup) = .init(handleNewXdgPopup),
|
|||
// Seat listeners
|
||||
|
||||
pub fn init(self: *Server) !void {
|
||||
const wl_server = try wl.Server.create();
|
||||
const wl_server = wl.Server.create() catch {
|
||||
std.err.log("Server create failed, exiting with 2", .{});
|
||||
std.process.exit(2);
|
||||
};
|
||||
|
||||
const event_loop = wl_server.getEventLoop();
|
||||
|
||||
var session: ?*wlr.Session = undefined;
|
||||
const backend = try wlr.Backend.autocreate(event_loop, &session);
|
||||
const renderer = try wlr.Renderer.autocreate(backend);
|
||||
const backend = wlr.Backend.autocreate(event_loop, &session) catch {
|
||||
std.log.err("Backend create failed, exiting with 3", .{});
|
||||
std.process.exit(3);
|
||||
};
|
||||
|
||||
const renderer = wlr.Renderer.autocreate(backend) catch {
|
||||
std.log.err("Renderer create failed, exiting with 4", .{});
|
||||
std.process.exit(4);
|
||||
};
|
||||
|
||||
self.* = .{
|
||||
.wl_server = wl_server,
|
||||
.backend = backend,
|
||||
.renderer = renderer,
|
||||
.allocator = try wlr.Allocator.autocreate(backend, renderer),
|
||||
.allocator = wlr.Allocator.autocreate(backend, renderer) catch {
|
||||
std.log.err("Allocator create failed, exiting with 5", .{});
|
||||
std.process.exit(5);
|
||||
},
|
||||
.xdg_shell = try wlr.XdgShell.create(wl_server, 2),
|
||||
.event_loop = event_loop,
|
||||
.session = session,
|
||||
|
|
@ -71,9 +85,12 @@ pub fn init(self: *Server) !void {
|
|||
.keyboard = undefined,
|
||||
};
|
||||
|
||||
try self.renderer.initServer(wl_server);
|
||||
try self.renderer.initServer(wl_server) catch {
|
||||
std.log.err("Renderer init failed, exiting with 6", .{});
|
||||
std.process.exit(6);
|
||||
};
|
||||
|
||||
try self.root.init();
|
||||
self.root.init();
|
||||
try self.seat.init();
|
||||
try self.cursor.init();
|
||||
|
||||
|
|
@ -91,16 +108,18 @@ pub fn init(self: *Server) !void {
|
|||
}
|
||||
|
||||
pub fn deinit(self: *Server) void {
|
||||
self.new_input.link.remove();
|
||||
self.new_output.link.remove();
|
||||
self.new_xdg_toplevel.link.remove();
|
||||
self.new_xdg_popup.link.remove();
|
||||
|
||||
self.seat.deinit();
|
||||
self.root.deinit();
|
||||
self.cursor.deinit();
|
||||
|
||||
self.new_input.link.remove();
|
||||
self.new_output.link.remove();
|
||||
self.backend.destroy();
|
||||
|
||||
self.wl_server.destroyClients();
|
||||
|
||||
self.backend.destroy();
|
||||
self.wl_server.destroy();
|
||||
}
|
||||
|
||||
|
|
|
|||
8
src/utils.zig
Normal file
8
src/utils.zig
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
const Utils = @This();
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
pub fn oomPanic() noreturn {
|
||||
std.log.err("Out of memory error, exiting with 1", .{});
|
||||
std.process.exit(1);
|
||||
}
|
||||
113
src/view.zig
113
src/view.zig
|
|
@ -1,47 +1,50 @@
|
|||
const View = @This();
|
||||
|
||||
|
||||
const std = @import("std");
|
||||
const wl = @import("wayland").server.wl;
|
||||
const wlr = @import("wlroots");
|
||||
|
||||
const Utils = @import("utils.zig");
|
||||
|
||||
const gpa = std.heap.c_allocator;
|
||||
const server = &@import("main.zig").server;
|
||||
|
||||
link: wl.list.Link = undefined,
|
||||
geometry: *wlr.Box = undefined,
|
||||
|
||||
xdg_toplevel: *wlr.XdgToplevel,
|
||||
xdg_surface: *wlr.XdgSurface,
|
||||
scene_tree: *wlr.SceneTree,
|
||||
|
||||
// Surface Listeners
|
||||
map: wl.Listener(void) = wl.Listener(void).init(handleMap),
|
||||
unmap: wl.Listener(void) = wl.Listener(void).init(handleUnmap),
|
||||
commit: wl.Listener(*wlr.Surface) = wl.Listener(*wlr.Surface).init(handleCommit),
|
||||
map: wl.Listener(void) = .init(handleMap),
|
||||
unmap: wl.Listener(void) = .init(handleUnmap),
|
||||
commit: wl.Listener(*wlr.Surface) = .init(handleCommit),
|
||||
|
||||
// XdgTopLevel Listeners
|
||||
destroy: wl.Listener(void) = wl.Listener(void).init(handleDestroy),
|
||||
request_resize: wl.Listener(*wlr.XdgToplevel.event.Resize) = wl.Listener(handleRequestResize),
|
||||
request_move: wl.Listener(*wlr.XdgToplevel.event.Move) = wl.Listener(handleRequestMove),
|
||||
destroy: wl.Listener(void) = .init(handleDestroy),
|
||||
request_resize: wl.Listener(*wlr.XdgToplevel.event.Resize) = .init(handleRequestResize),
|
||||
request_move: wl.Listener(*wlr.XdgToplevel.event.Move) = .init(handleRequestMove),
|
||||
|
||||
// Not yet silly
|
||||
// new_popup: wl.Listener(*wlr.XdgPopup) = wl.Listener(*wlr.XdgPopup).init(handleNewPopup),
|
||||
|
||||
pub fn initFromTopLevel(xdg_toplevel: *wlr.XdgToplevel) ?*View {
|
||||
const self = gpa.create(View) catch {
|
||||
std.log.err("Unable to allocate memory for new XdgTopLevel", .{});
|
||||
return null;
|
||||
};
|
||||
errdefer Utils.oomPanic();
|
||||
|
||||
const xdg_surface = xdg_toplevel.base;
|
||||
const self = gpa.create(View) catch Utils.oomPanic();
|
||||
errdefer gpa.destroy(self);
|
||||
|
||||
self.* = .{
|
||||
.xdg_toplevel = xdg_toplevel,
|
||||
.scene_tree = server.root.scene.tree.createSceneXdgSurface(xdg_surface) catch {
|
||||
gpa.destroy(self);
|
||||
std.log.err("failed to allocate new toplevel", .{});
|
||||
return null;
|
||||
},
|
||||
.xdg_surface = xdg_toplevel.base,
|
||||
.geometry = &xdg_toplevel.base.geometry,
|
||||
.scene_tree = try server.root.scene.tree.createSceneXdgSurface(xdg_toplevel.base)
|
||||
};
|
||||
|
||||
self.scene_tree.node.data = self;
|
||||
xdg_surface.data = self.scene_tree;
|
||||
self.xdg_surface.data = self.scene_tree;
|
||||
|
||||
// Attach listeners
|
||||
xdg_surface.surface.events.map.add(&self.map);
|
||||
|
|
@ -65,33 +68,15 @@ pub fn initFromTopLevel(xdg_toplevel: *wlr.XdgToplevel) ?*View {
|
|||
return self;
|
||||
}
|
||||
|
||||
pub fn init(xdg_surface: *wlr.XdgSurface) ?*View {
|
||||
const self = gpa.create(View) catch {
|
||||
std.log.err("Unable to allocate memory for new XdgTopLevel", .{});
|
||||
return null;
|
||||
};
|
||||
|
||||
if(xdg_surface.role_data.toplevel) |xdg_toplevel| {
|
||||
self.xdg_toplevel = xdg_toplevel;
|
||||
} else {
|
||||
std.log.err("Unable to get top_level from new surface", .{});
|
||||
return null;
|
||||
}
|
||||
|
||||
self.xdg_toplevel.base.surface.events.map.add(&self.map);
|
||||
self.xdg_toplevel.base.surface.events.unmap.add(&self.unmap);
|
||||
self.xdg_toplevel.base.surface.events.commit.add(&self.commit);
|
||||
|
||||
self.xdg_toplevel.events.destroy.add(&self.destroy);
|
||||
self.xdg_toplevel.events.request_move.add(&self.request_move);
|
||||
self.xdg_toplevel.events.request_resize.add(&self.request_resize);
|
||||
// self.xdg_toplevel.events.request_move.add(&self.request_move);
|
||||
// self.xdg_toplevel.events.request_resize.add(&self.request_resize);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn deinit(self: *View) void {
|
||||
self.map.link.remove();
|
||||
self.unmap.link.remove();
|
||||
self.commit.link.remove();
|
||||
|
||||
self.destroy.link.remove();
|
||||
self.request_move.link.remove();
|
||||
self.request_resize.link.remove();
|
||||
|
||||
gpa.free(self);
|
||||
}
|
||||
|
||||
|
|
@ -138,7 +123,7 @@ fn handleCommit(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void {
|
|||
|
||||
// On the first commit, send a configure to tell the client it can proceed
|
||||
if (view.xdg_toplevel.base.initial_commit) {
|
||||
_ = view.xdg_toplevel.setSize(0, 0); // 0,0 means "you decide the size"
|
||||
_ = view.xdg_toplevel.setSize(640, 360); // 0,0 means "you decide the size"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -148,16 +133,36 @@ fn handleNewPopup(listener: *wl.Listener(*wlr.XdgPopup), popup: *wlr.XdgPopup) v
|
|||
std.log.err("Unimplemented view handle new popup", .{});
|
||||
}
|
||||
|
||||
fn handleRequestResize(listener: *wl.Listener(*wlr.XdgToplevel.event.Resize), resize: *wlr.XdgToplevel.event.Resize) void {
|
||||
// const view: *View = @fieldParentPtr("request_resize", listener);
|
||||
_ = listener;
|
||||
_ = resize;
|
||||
std.log.err("Unimplemented view handle resize", .{});
|
||||
fn handleRequestMove(
|
||||
listener: *wl.Listener(*wlr.XdgToplevel.event.Move),
|
||||
_: *wlr.XdgToplevel.event.Move
|
||||
) void {
|
||||
const view: *View = @fieldParentPtr("request_move", listener);
|
||||
|
||||
server.cursor.grabbed_view = view;
|
||||
server.cursor.mode = .move;
|
||||
server.cursor.grab_x = server.cursor.wlr_cursor.x - @as(f64, @floatFromInt(view.geometry.x));
|
||||
server.cursor.grab_y = server.cursor.wlr_cursor.y - @as(f64, @floatFromInt(view.geometry.y));
|
||||
}
|
||||
|
||||
fn handleRequestMove(listener: *wl.Listener(*wlr.XdgToplevel.event.Move), move: *wlr.XdgToplevel.event.Move) void {
|
||||
// const view: *View = @fieldParentPtr("request_move", listener);
|
||||
_ = listener;
|
||||
_ = move;
|
||||
std.log.err("Unimplemented view handle move", .{});
|
||||
fn handleRequestResize(
|
||||
listener: *wl.Listener(*wlr.XdgToplevel.event.Resize),
|
||||
event: *wlr.XdgToplevel.event.Resize
|
||||
) void {
|
||||
const view: *View = @fieldParentPtr("request_resize", listener);
|
||||
|
||||
server.cursor.grabbed_view = view;
|
||||
server.cursor.mode = .resize;
|
||||
server.cursor.resize_edges = event.edges;
|
||||
|
||||
const box = view.xdg_toplevel.base.geometry;
|
||||
|
||||
const border_x = view.geometry.x + box.x + if (event.edges.right) box.width else 0;
|
||||
const border_y = view.geometry.y + box.y + if (event.edges.bottom) box.height else 0;
|
||||
server.cursor.grab_x = server.cursor.wlr_cursor.x - @as(f64, @floatFromInt(border_x));
|
||||
server.cursor.grab_y = server.cursor.wlr_cursor.y - @as(f64, @floatFromInt(border_y));
|
||||
|
||||
server.cursor.grab_box = box;
|
||||
server.cursor.grab_box.x += view.geometry.x;
|
||||
server.cursor.grab_box.y += view.geometry.y;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue