mirror of
https://github.com/MezzalunaWM/Mezzaluna.git
synced 2026-03-08 04:57:32 -04:00
added process spawning
This commit is contained in:
parent
23ef0049f7
commit
2e2cfeebae
5 changed files with 47 additions and 249 deletions
244
2
244
2
|
|
@ -1,244 +0,0 @@
|
||||||
//! Maintains state related to cursor position, rendering, and
|
|
||||||
//! events such as button presses and dragging
|
|
||||||
|
|
||||||
pub const Cursor = @This();
|
|
||||||
|
|
||||||
const std = @import("std");
|
|
||||||
const wl = @import("wayland").server.wl;
|
|
||||||
const wlr = @import("wlroots");
|
|
||||||
const xkb = @import("xkbcommon");
|
|
||||||
|
|
||||||
const View = @import("view.zig");
|
|
||||||
const Utils = @import("utils.zig");
|
|
||||||
|
|
||||||
const c = @import("c.zig").c;
|
|
||||||
|
|
||||||
const server = &@import("main.zig").server;
|
|
||||||
const linux = std.os.linux;
|
|
||||||
|
|
||||||
wlr_cursor: *wlr.Cursor,
|
|
||||||
x_cursor_manager: *wlr.XcursorManager,
|
|
||||||
|
|
||||||
motion: wl.Listener(*wlr.Pointer.event.Motion) = .init(handleMotion),
|
|
||||||
motion_absolute: wl.Listener(*wlr.Pointer.event.MotionAbsolute) = .init(handleMotionAbsolute),
|
|
||||||
button: wl.Listener(*wlr.Pointer.event.Button) = .init(handleButton),
|
|
||||||
axis: wl.Listener(*wlr.Pointer.event.Axis) = .init(handleAxis),
|
|
||||||
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),
|
|
||||||
|
|
||||||
mode: enum { passthrough, move, resize } = .passthrough,
|
|
||||||
|
|
||||||
// Drag information
|
|
||||||
selected_view: ?*View = null,
|
|
||||||
drag_start_x: c_int = 0,
|
|
||||||
drag_start_y: c_int = 0,
|
|
||||||
drag_view_offset_x: c_int = 0,
|
|
||||||
drag_view_offset_y: c_int = 0,
|
|
||||||
|
|
||||||
pub fn init(self: *Cursor) void {
|
|
||||||
errdefer Utils.oomPanic();
|
|
||||||
|
|
||||||
self.* = .{
|
|
||||||
.wlr_cursor = try wlr.Cursor.create(),
|
|
||||||
.x_cursor_manager = try wlr.XcursorManager.create(null, 24),
|
|
||||||
};
|
|
||||||
|
|
||||||
try self.x_cursor_manager.load(1);
|
|
||||||
|
|
||||||
self.wlr_cursor.attachOutputLayout(server.root.output_layout);
|
|
||||||
|
|
||||||
self.wlr_cursor.events.motion.add(&self.motion);
|
|
||||||
self.wlr_cursor.events.motion_absolute.add(&self.motion_absolute);
|
|
||||||
self.wlr_cursor.events.button.add(&self.button);
|
|
||||||
self.wlr_cursor.events.axis.add(&self.axis);
|
|
||||||
self.wlr_cursor.events.frame.add(&self.frame);
|
|
||||||
self.wlr_cursor.events.hold_begin.add(&self.hold_begin);
|
|
||||||
self.wlr_cursor.events.hold_end.add(&self.hold_end);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deinit(self: *Cursor) void {
|
|
||||||
self.wlr_cursor.destroy();
|
|
||||||
self.x_cursor_manager.destroy();
|
|
||||||
|
|
||||||
self.motion.link.remove();
|
|
||||||
self.motion_absolute.link.remove();
|
|
||||||
self.button.link.remove();
|
|
||||||
self.axis.link.remove();
|
|
||||||
self.frame.link.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn updateDrag(self: *Cursor) void {
|
|
||||||
self.drag_box.width = @as(c_int, @intFromFloat(self.wlr_cursor.x)) - self.drag_box.x;
|
|
||||||
self.drag_box.height = @as(c_int, @intFromFloat(self.wlr_cursor.y)) - self.drag_box.y;
|
|
||||||
|
|
||||||
std.log.debug("{d}, {d}, {d}, {d}", .{self.drag_box.x, self.drag_box.y, self.drag_box.width, self.drag_box.height});
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn processCursorMotion(self: *Cursor, time_msec: u32) void {
|
|
||||||
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.selected_view.?;
|
|
||||||
self.updateDrag();
|
|
||||||
|
|
||||||
// const half_width = @divFloor(view.xdg_surface.geometry.width, 2);
|
|
||||||
// const half_height = @divFloor(view.xdg_surface.geometry.width, 2);
|
|
||||||
|
|
||||||
view.scene_tree.node.setPosition(
|
|
||||||
self.drag_box.x + @divFloor(self.drag_box.width, 2),
|
|
||||||
self.drag_box.y + @divFloor(self.drag_box.height, 2)
|
|
||||||
);
|
|
||||||
},
|
|
||||||
.resize => {
|
|
||||||
self.updateDrag();
|
|
||||||
// Fix this resize
|
|
||||||
//
|
|
||||||
// REDOING RESIZING AND MOVING TOPLEVELS
|
|
||||||
// REDOING RESIZING AND MOVING TOPLEVELS
|
|
||||||
// REDOING RESIZING AND MOVING TOPLEVELS
|
|
||||||
// REDOING RESIZING AND MOVING TOPLEVELS
|
|
||||||
//
|
|
||||||
// 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);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------- WLR Cursor event handlers ---------
|
|
||||||
fn handleMotion(
|
|
||||||
_: *wl.Listener(*wlr.Pointer.event.Motion),
|
|
||||||
event: *wlr.Pointer.event.Motion,
|
|
||||||
) void {
|
|
||||||
server.cursor.wlr_cursor.move(event.device, event.delta_x, event.delta_y);
|
|
||||||
server.cursor.processCursorMotion(event.time_msec);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handleMotionAbsolute(
|
|
||||||
_: *wl.Listener(*wlr.Pointer.event.MotionAbsolute),
|
|
||||||
event: *wlr.Pointer.event.MotionAbsolute,
|
|
||||||
) void {
|
|
||||||
server.cursor.wlr_cursor.warpAbsolute(event.device, event.x, event.y);
|
|
||||||
server.cursor.processCursorMotion(event.time_msec);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handleButton(
|
|
||||||
listener: *wl.Listener(*wlr.Pointer.event.Button),
|
|
||||||
event: *wlr.Pointer.event.Button
|
|
||||||
) void {
|
|
||||||
const cursor: *Cursor = @fieldParentPtr("button", listener);
|
|
||||||
|
|
||||||
_ = server.seat.wlr_seat.pointerNotifyButton(event.time_msec, event.button, event.state);
|
|
||||||
|
|
||||||
const view_at_result = server.root.viewAt(cursor.wlr_cursor.x, cursor.wlr_cursor.y);
|
|
||||||
if (view_at_result) |res| {
|
|
||||||
server.root.focusView(res.view);
|
|
||||||
}
|
|
||||||
|
|
||||||
std.log.debug("Button pressed {}", .{event.button});
|
|
||||||
|
|
||||||
switch (event.state) {
|
|
||||||
.pressed => {
|
|
||||||
if(server.keyboard.wlr_keyboard.getModifiers().alt) {
|
|
||||||
// Can be BTN_RIGHT, BTN_LEFT, or BTN_MIDDLE
|
|
||||||
if(view_at_result) |res| {
|
|
||||||
// Keep track of where the drag started
|
|
||||||
cursor.selected_view = res.view;
|
|
||||||
cursor.drag_box.x = @as(c_int, @intFromFloat(cursor.wlr_cursor.x));
|
|
||||||
cursor.drag_box.y = @as(c_int, @intFromFloat(cursor.wlr_cursor.y));
|
|
||||||
|
|
||||||
// Maybe comptime this for later reference
|
|
||||||
if(event.button == c.libevdev_event_code_from_name(c.EV_KEY, "BTN_LEFT")) {
|
|
||||||
cursor.mode = .move;
|
|
||||||
} else if(event.button == c.libevdev_event_code_from_name(c.EV_KEY, "BTN_RIGHT")) {
|
|
||||||
cursor.mode = .resize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
.released => {
|
|
||||||
cursor.mode = .passthrough;
|
|
||||||
},
|
|
||||||
else => {
|
|
||||||
std.log.err("Invalid/Unimplemented pointer button event type", .{});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handleHoldBegin(
|
|
||||||
listener: *wl.Listener(*wlr.Pointer.event.HoldBegin),
|
|
||||||
event: *wlr.Pointer.event.HoldBegin
|
|
||||||
) void {
|
|
||||||
_ = listener;
|
|
||||||
_ = event;
|
|
||||||
std.log.err("Unimplemented cursor start hold", .{});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handleHoldEnd(
|
|
||||||
listener: *wl.Listener(*wlr.Pointer.event.HoldEnd),
|
|
||||||
event: *wlr.Pointer.event.HoldEnd
|
|
||||||
) void {
|
|
||||||
_ = listener;
|
|
||||||
_ = event;
|
|
||||||
std.log.err("Unimplemented cursor end hold", .{});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handleAxis(
|
|
||||||
_: *wl.Listener(*wlr.Pointer.event.Axis),
|
|
||||||
event: *wlr.Pointer.event.Axis,
|
|
||||||
) void {
|
|
||||||
server.seat.wlr_seat.pointerNotifyAxis(
|
|
||||||
event.time_msec,
|
|
||||||
event.orientation,
|
|
||||||
event.delta,
|
|
||||||
event.delta_discrete,
|
|
||||||
event.source,
|
|
||||||
event.relative_direction,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handleFrame(_: *wl.Listener(*wlr.Cursor), _: *wlr.Cursor) void {
|
|
||||||
server.seat.wlr_seat.pointerNotifyFrame();
|
|
||||||
}
|
|
||||||
|
|
@ -14,3 +14,13 @@ package.path = package.path..";"..mez.fs.joinpath(env_conf, "mez", "lua", "?.lua
|
||||||
mez.api.add_keymap("alt", "a", function()
|
mez.api.add_keymap("alt", "a", function()
|
||||||
print("hello from my keymap")
|
print("hello from my keymap")
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
mez.api.add_keymap("alt", "t", function()
|
||||||
|
print("spawning foot")
|
||||||
|
mez.api.spawn("foot")
|
||||||
|
end)
|
||||||
|
|
||||||
|
mez.api.add_keymap("alt", "p", function()
|
||||||
|
print("spawning foot")
|
||||||
|
mez.api.spawn("wmenu-run")
|
||||||
|
end)
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,10 @@ pub fn callback(self: *const Keymap) void {
|
||||||
const t = Lua.state.rawGetIndex(zlua.registry_index, self.lua_ref_idx);
|
const t = Lua.state.rawGetIndex(zlua.registry_index, self.lua_ref_idx);
|
||||||
if (t != zlua.LuaType.function) {
|
if (t != zlua.LuaType.function) {
|
||||||
std.log.err("Failed to call keybind, it doesn't have a callback.", .{});
|
std.log.err("Failed to call keybind, it doesn't have a callback.", .{});
|
||||||
|
Lua.state.pop(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Lua.state.pushValue(1);
|
|
||||||
Lua.state.call(.{ .args = 0, .results = 0 });
|
Lua.state.call(.{ .args = 0, .results = 0 });
|
||||||
Lua.state.pop(-1);
|
Lua.state.pop(-1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
const Api = @This();
|
const Api = @This();
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const server = &@import("../main.zig").server;
|
|
||||||
const Keymap = @import("../keymap.zig");
|
const Keymap = @import("../keymap.zig");
|
||||||
|
|
||||||
const zlua = @import("zlua");
|
const zlua = @import("zlua");
|
||||||
|
|
@ -9,9 +8,12 @@ const xkb = @import("xkbcommon");
|
||||||
const wlr = @import("wlroots");
|
const wlr = @import("wlroots");
|
||||||
|
|
||||||
const gpa = std.heap.c_allocator;
|
const gpa = std.heap.c_allocator;
|
||||||
|
const server = &@import("../main.zig").server;
|
||||||
|
const env_map = &@import("../main.zig").env_map;
|
||||||
|
|
||||||
pub fn add_keymap(L: *zlua.Lua) i32 {
|
pub fn add_keymap(L: *zlua.Lua) i32 {
|
||||||
const nargs: i32 = L.getTop();
|
const nargs: i32 = L.getTop();
|
||||||
|
|
||||||
if (nargs < 3) {
|
if (nargs < 3) {
|
||||||
L.raiseErrorStr("Expected at least three arguments", .{});
|
L.raiseErrorStr("Expected at least three arguments", .{});
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -23,6 +25,9 @@ pub fn add_keymap(L: *zlua.Lua) i32 {
|
||||||
L.checkType(3, .function);
|
L.checkType(3, .function);
|
||||||
|
|
||||||
var keymap: Keymap = undefined;
|
var keymap: Keymap = undefined;
|
||||||
|
keymap.options = .{
|
||||||
|
.on_release = false,
|
||||||
|
};
|
||||||
|
|
||||||
const mod = L.toString(1) catch {
|
const mod = L.toString(1) catch {
|
||||||
L.raiseErrorStr("Lua error check your config", .{});
|
L.raiseErrorStr("Lua error check your config", .{});
|
||||||
|
|
@ -89,3 +94,27 @@ pub fn get_keybind(L: *zlua.Lua) i32 {
|
||||||
_ = L;
|
_ = L;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn spawn(L: *zlua.Lua) i32 {
|
||||||
|
const nargs: i32 = L.getTop();
|
||||||
|
|
||||||
|
if (nargs < 1) {
|
||||||
|
L.raiseErrorStr("Expected at least one arguments", .{});
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
L.checkType(1, .string);
|
||||||
|
|
||||||
|
const cmd = L.toString(1) catch {
|
||||||
|
L.raiseErrorStr("Lua error check your config", .{});
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
var child = std.process.Child.init(&[_][]const u8{ "/bin/sh", "-c", cmd }, gpa);
|
||||||
|
child.env_map = env_map;
|
||||||
|
child.spawn() catch {
|
||||||
|
std.log.err("Unable to spawn process \"{s}\"", .{cmd});
|
||||||
|
};
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ const gpa = std.heap.c_allocator;
|
||||||
|
|
||||||
pub var server: Server = undefined;
|
pub var server: Server = undefined;
|
||||||
pub var lua: Lua = undefined;
|
pub var lua: Lua = undefined;
|
||||||
|
pub var env_map: std.process.EnvMap = undefined;
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
wlr.log.init(.err, null);
|
wlr.log.init(.err, null);
|
||||||
|
|
@ -21,15 +22,16 @@ pub fn main() !void {
|
||||||
var buf: [11]u8 = undefined;
|
var buf: [11]u8 = undefined;
|
||||||
const socket = try server.wl_server.addSocketAuto(&buf);
|
const socket = try server.wl_server.addSocketAuto(&buf);
|
||||||
|
|
||||||
|
env_map = try std.process.getEnvMap(gpa);
|
||||||
|
try env_map.put("WAYLAND_DISPLAY", socket);
|
||||||
|
|
||||||
if (std.os.argv.len >= 2) {
|
if (std.os.argv.len >= 2) {
|
||||||
const cmd = std.mem.span(std.os.argv[1]);
|
const cmd = std.mem.span(std.os.argv[1]);
|
||||||
var child = std.process.Child.init(&[_][]const u8{ "/bin/sh", "-c", cmd }, gpa);
|
var child = std.process.Child.init(&[_][]const u8{ "/bin/sh", "-c", cmd }, gpa);
|
||||||
var env_map = try std.process.getEnvMap(gpa);
|
|
||||||
defer env_map.deinit();
|
|
||||||
try env_map.put("WAYLAND_DISPLAY", socket);
|
|
||||||
child.env_map = &env_map;
|
child.env_map = &env_map;
|
||||||
try child.spawn();
|
try child.spawn();
|
||||||
}
|
}
|
||||||
|
defer env_map.deinit();
|
||||||
|
|
||||||
std.log.info("Starting backend", .{});
|
std.log.info("Starting backend", .{});
|
||||||
server.backend.start() catch |err| {
|
server.backend.start() catch |err| {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue