viewById works again, layer still ontop of other things

This commit is contained in:
Harrison DiAmbrosio 2025-12-04 23:50:39 -05:00
parent 3ccf47e0be
commit 9186aeecd3
23 changed files with 282 additions and 181 deletions

View file

@ -8,10 +8,9 @@ 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 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;
@ -30,12 +29,13 @@ hold_end: wl.Listener(*wlr.Pointer.event.HoldEnd) = .init(handleHoldEnd),
mode: enum { passthrough, move, resize } = .passthrough,
// Drag information
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,
drag_view_width: c_int = 0,
drag_view_height: c_int = 0,
drag: struct {
start_x: c_int,
start_y: c_int,
view: ?*View,
view_offset_x: ?c_int,
view_offset_y: ?c_int,
},
pub fn init(self: *Cursor) void {
errdefer Utils.oomPanic();
@ -43,6 +43,13 @@ pub fn init(self: *Cursor) void {
self.* = .{
.wlr_cursor = try wlr.Cursor.create(),
.x_cursor_manager = try wlr.XcursorManager.create(null, 24),
.drag = .{
.start_x = 0,
.start_y = 0,
.view = null,
.view_offset_x = null,
.view_offset_y = null,
}
};
try self.x_cursor_manager.load(1);
@ -72,27 +79,37 @@ pub fn deinit(self: *Cursor) void {
}
pub fn processCursorMotion(self: *Cursor, time_msec: u32) void {
server.events.exec("PointerMotion", .{self.wlr_cursor.x, self.wlr_cursor.y});
switch (self.mode) {
.passthrough => {
if (server.root.viewAt(self.wlr_cursor.x, self.wlr_cursor.y)) |res| {
res.view.setFocused();
const output = server.seat.focused_output;
// Exit the switch if no focused output exists
if (output == null) return;
server.seat.wlr_seat.pointerNotifyEnter(res.surface, res.sx, res.sy);
server.seat.wlr_seat.pointerNotifyMotion(time_msec, res.sx, res.sy);
} else {
const viewAtResult = output.?.viewAt(self.wlr_cursor.x, self.wlr_cursor.y);
if (viewAtResult == null) {
self.wlr_cursor.setXcursor(self.x_cursor_manager, "default");
server.seat.wlr_seat.pointerClearFocus();
}
},
.move => {
const focused_view = server.seat.focused_view;
if(focused_view) |view| {
// This is gonna be fun
// server.seat.wlr_seat.keyboardSendKey(time_msec: u32, key: u32, state: u32);
// server.seat.wlr_seat.pointerSendMotion(time_msec: u32, sx: f64, sy: f64)
// server.seat.wlr_seat.pointerSendButton(time_msec: u32, button: u32, state: ButtonState)
return;
}
server.events.exec("ViewPointerMotion", .{viewAtResult.?.view.id, self.wlr_cursor.x, self.wlr_cursor.y});
server.seat.wlr_seat.pointerNotifyEnter(viewAtResult.?.surface, viewAtResult.?.sx, viewAtResult.?.sy);
server.seat.wlr_seat.pointerNotifyMotion(time_msec, viewAtResult.?.sx, viewAtResult.?.sy);
},
.move => { // TODO: Have these behave more like pointer motion
if(self.drag.view) |view| {
view.scene_tree.node.setPosition(
// TODO: add a lua option to configure the behavior of this, by
// default it will be the following:
@as(c_int, @intFromFloat(self.wlr_cursor.x)) - self.drag_view_offset_x,
@as(c_int, @intFromFloat(self.wlr_cursor.y)) - self.drag_view_offset_y
@as(c_int, @intFromFloat(self.wlr_cursor.x)) - self.drag.view_offset_x.?,
@as(c_int, @intFromFloat(self.wlr_cursor.y)) - self.drag.view_offset_y.?
// and the user should be able to configure if it clamps or not
);
}
@ -141,18 +158,24 @@ fn handleButton(
view.setFocused();
}
// @hook PointerButtonPress // TODO Probably change this name
// @param button string // TODO Translate a button to a string or smth
// @param state string - "pressed" or "released"
// @param time_msecs number // TODO idk what the hell msecs is
const state = if (event.state == .pressed) "pressed" else "released";
server.events.exec("PointerButtonPress", .{event.button, state, event.time_msec});
switch (event.state) {
.pressed => {
if(server.seat.keyboard_group.keyboard.getModifiers().alt) {
// Can be BTN_RIGHT, BTN_LEFT, or BTN_MIDDLE
cursor.drag.start_x = @as(c_int, @intFromFloat(cursor.wlr_cursor.x));
cursor.drag.start_y = @as(c_int, @intFromFloat(cursor.wlr_cursor.y));
if(server.seat.focused_view) |view| {
// Keep track of where the drag started
cursor.drag_start_x = @as(c_int, @intFromFloat(cursor.wlr_cursor.x));
cursor.drag_start_y = @as(c_int, @intFromFloat(cursor.wlr_cursor.y));
cursor.drag_view_offset_x = cursor.drag_start_x - view.scene_tree.node.x;
cursor.drag_view_offset_y = cursor.drag_start_y - view.scene_tree.node.y;
cursor.drag_view_width = view.xdg_toplevel.base.geometry.width;
cursor.drag_view_height = view.xdg_toplevel.base.geometry.height;
cursor.drag.view = view;
cursor.drag.view_offset_x = cursor.drag.start_x - view.scene_tree.node.x;
cursor.drag.view_offset_y = cursor.drag.start_y - view.scene_tree.node.y;
// Maybe comptime this for later reference
if(event.button == c.libevdev_event_code_from_name(c.EV_KEY, "BTN_LEFT")) {
@ -167,9 +190,13 @@ fn handleButton(
.released => {
cursor.mode = .passthrough;
if(server.seat.focused_view) |view| {
if(cursor.drag.view) |view| {
_ = view.xdg_toplevel.setResizing(false);
}
cursor.drag.view = null;
cursor.drag.view_offset_x = null;
cursor.drag.view_offset_y = null;
},
else => {
std.log.err("Invalid/Unimplemented pointer button event type", .{});

View file

@ -6,8 +6,8 @@ const Keyboard = @This();
const std = @import("std");
const gpa = std.heap.c_allocator;
const server = &@import("main.zig").server;
const Keymap = @import("types/keymap.zig");
const Utils = @import("utils.zig");
const Keymap = @import("types/Keymap.zig");
const Utils = @import("Utils.zig");
const wl = @import("wayland").server.wl;
const wlr = @import("wlroots");

View file

@ -4,8 +4,8 @@ const std = @import("std");
const wl = @import("wayland").server.wl;
const wlr = @import("wlroots");
const Utils = @import("utils.zig");
const Output = @import("output.zig");
const Utils = @import("Utils.zig");
const Output = @import("Output.zig");
const gpa = std.heap.c_allocator;
const server = &@import("main.zig").server;
@ -28,8 +28,21 @@ pub fn init(wlr_layer_surface: *wlr.LayerSurfaceV1) *LayerSurface {
self.* = .{
.output = @ptrCast(@alignCast(wlr_layer_surface.output.?.data)),
.wlr_layer_surface = wlr_layer_surface,
.scene_layer_surface = try server.root.scene.tree.createSceneLayerSurfaceV1(wlr_layer_surface)
.scene_layer_surface = undefined,
};
// try server.root.scene.tree.createSceneLayerSurfaceV1(wlr_layer_surface)
if(server.seat.focused_output) |output| {
self.scene_layer_surface = switch (wlr_layer_surface.current.layer) {
.background => try output.layers.background.createSceneLayerSurfaceV1(wlr_layer_surface),
.bottom => try output.layers.background.createSceneLayerSurfaceV1(wlr_layer_surface),
.top => try output.layers.background.createSceneLayerSurfaceV1(wlr_layer_surface),
.overlay => try output.layers.background.createSceneLayerSurfaceV1(wlr_layer_surface),
else => {
std.log.err("New layer surface of unidentified type", .{});
unreachable;
}
};
}
self.wlr_layer_surface.surface.data = &self.scene_layer_surface.tree.node;
@ -78,5 +91,10 @@ fn handleCommit(
) void {
const layer_surface: *LayerSurface = @fieldParentPtr("commit", listener);
var width: c_int = undefined;
var height: c_int = undefined;
layer_surface.output.wlr_output.effectiveResolution(&width, &height);
_ = layer_surface.wlr_layer_surface.configure(@intCast(width), @intCast(height));
layer_surface.scene_layer_surface.tree.node.reparent(&layer_surface.output.scene_output.scene.tree);
}

View file

@ -1,10 +1,15 @@
const Output = @This();
const wl = @import("wayland").server.wl;
const zwlr = @import("wayland").server.zwlr;
const wlr = @import("wlroots");
const std = @import("std");
const Server = @import("server.zig");
const Utils = @import("utils.zig");
const Server = @import("Server.zig");
const Utils = @import("Utils.zig");
const View = @import("View.zig");
const posix = std.posix;
const gpa = std.heap.c_allocator;
@ -15,12 +20,23 @@ id: u64,
wlr_output: *wlr.Output,
state: wlr.Output.State,
tree: *wlr.SceneTree,
scene_output: *wlr.SceneOutput,
layers: struct {
background: *wlr.SceneTree,
bottom: *wlr.SceneTree,
content: *wlr.SceneTree,
top: *wlr.SceneTree,
fullscreen: *wlr.SceneTree,
overlay: *wlr.SceneTree
},
frame: wl.Listener(*wlr.Output) = .init(handleFrame),
request_state: wl.Listener(*wlr.Output.event.RequestState) = .init(handleRequestState),
destroy: wl.Listener(*wlr.Output) = .init(handleDestroy),
// The wlr.Output should be destroyed by the caller on failure to trigger cleanup.
pub fn init(wlr_output: *wlr.Output) ?*Output {
errdefer Utils.oomPanic();
@ -31,6 +47,15 @@ pub fn init(wlr_output: *wlr.Output) ?*Output {
.focused = false,
.id = @intFromPtr(wlr_output),
.wlr_output = wlr_output,
.tree = try server.root.scene.tree.createSceneTree(),
.layers = .{
.background = try self.tree.createSceneTree(),
.bottom = try self.tree.createSceneTree(),
.content = try self.tree.createSceneTree(),
.top = try self.tree.createSceneTree(),
.fullscreen = try self.tree.createSceneTree(),
.overlay = try self.tree.createSceneTree(),
},
.scene_output = try server.root.scene.createSceneOutput(wlr_output),
.state = wlr.Output.State.init()
};
@ -87,6 +112,72 @@ pub fn setFocused(self: *Output) void {
self.focused = true;
}
pub fn configureLayers(self: *Output) void {
var output_box: wlr.Box = .{
.x = 0,
.y = 0,
.width = undefined,
.height = undefined,
};
self.wlr_output.effectiveResolution(&output_box.width, &output_box.height);
// Should calculate usable area here for LUA view positioning
for ([_]zwlr.LayerShellV1.Layer{ .background, .bottom, .top, .overlay }) |layer| {
const tree = blk: {
const trees = [_]*wlr.SceneTree{
self.layers.background,
self.layers.bottom,
self.layers.top,
self.layers.overlay,
};
break :blk trees[@intCast(@intFromEnum(layer))];
};
var it = tree.children.iterator(.forward);
while(it.next()) |node| {
if(node.data == null) continue;
const layer_surface: *wlr.LayerSurfaceV1 = @ptrCast(@alignCast(node.data.?));
_ = layer_surface.configure(@intCast(output_box.width), @intCast(output_box.height));
}
}
}
const ViewAtResult = struct {
view: *View,
surface: *wlr.Surface,
sx: f64,
sy: f64,
};
pub fn viewAt(self: *Output, lx: f64, ly: f64) ?ViewAtResult {
var sx: f64 = undefined;
var sy: f64 = undefined;
if(self.layers.content.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 (n.node.data == null) continue;
const view: *View = @ptrCast(@alignCast(n.node.data.?));
return ViewAtResult{
.view = view,
.surface = scene_surface.surface,
.sx = sx,
.sy = sy,
};
}
}
return null;
}
// --------- WlrOutput Event Handlers ---------
fn handleRequestState(
listener: *wl.Listener(*wlr.Output.event.RequestState),

View file

@ -7,9 +7,9 @@ const std = @import("std");
const wl = @import("wayland").server.wl;
const wlr = @import("wlroots");
const Output = @import("output.zig");
const View = @import("view.zig");
const Utils = @import("utils.zig");
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;
@ -17,6 +17,7 @@ const gpa = std.heap.c_allocator;
xdg_toplevel_decoration_manager: *wlr.XdgDecorationManagerV1,
scene: *wlr.Scene,
waiting_room: *wlr.SceneTree,
scene_output_layout: *wlr.SceneOutputLayout,
output_layout: *wlr.OutputLayout,
@ -34,6 +35,7 @@ pub fn init(self: *Root) void {
self.* = .{
.scene = scene,
.waiting_room = try scene.tree.createSceneTree(),
.output_layout = output_layout,
.xdg_toplevel_decoration_manager = try wlr.XdgDecorationManagerV1.create(server.wl_server),
.scene_output_layout = try scene.attachOutputLayout(output_layout),
@ -54,14 +56,21 @@ pub fn deinit(self: *Root) void {
self.scene.tree.node.destroy();
}
// Search output_layout's ouputs, and each outputs views
pub fn viewById(self: *Root, id: u64) ?*View {
var it = self.scene.tree.children.iterator(.forward);
var output_it = self.output_layout.outputs.iterator(.forward);
while(it.next()) |node| {
if(node.data == null) continue;
while(output_it.next()) |o| {
if(o.output.data == null) continue;
const output: *Output = @ptrCast(@alignCast(o.output.data.?));
var node_it = output.layers.content.children.iterator(.forward);
const view: *View = @as(*View, @ptrCast(@alignCast(node.data.?)));
if(view.id == id) return view;
while(node_it.next()) |node| {
if(node.data == null) continue;
const view: *View = @as(*View, @ptrCast(@alignCast(node.data.?)));
if(view.id == id) return view;
}
}
return null;
@ -79,37 +88,3 @@ pub fn outputById(self: *Root, id: u64) ?*Output {
return null;
}
const ViewAtResult = struct {
view: *View,
surface: *wlr.Surface,
sx: f64,
sy: f64,
};
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;
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| {
return ViewAtResult{
.view = view,
.surface = scene_surface.surface,
.sx = sx,
.sy = sy,
};
}
}
}
}
return null;
}

View file

@ -5,9 +5,9 @@ const wlr = @import("wlroots");
const wl = @import("wayland").server.wl;
const xkb = @import("xkbcommon");
const Utils = @import("utils.zig");
const View = @import("view.zig");
const Output = @import("output.zig");
const Utils = @import("Utils.zig");
const View = @import("View.zig");
const Output = @import("Output.zig");
const server = &@import("main.zig").server;

View file

@ -4,17 +4,17 @@ const std = @import("std");
const wl = @import("wayland").server.wl;
const wlr = @import("wlroots");
const Root = @import("root.zig");
const Seat = @import("seat.zig");
const Cursor = @import("cursor.zig");
const Keyboard = @import("keyboard.zig");
const LayerSurface = @import("layer_surface.zig");
const Output = @import("output.zig");
const View = @import("view.zig");
const Utils = @import("utils.zig");
const Keymap = @import("types/keymap.zig");
const Hook = @import("types/hook.zig");
const Events = @import("types/events.zig");
const Root = @import("Root.zig");
const Seat = @import("Seat.zig");
const Cursor = @import("Cursor.zig");
const Keyboard = @import("Keyboard.zig");
const LayerSurface = @import("LayerSurface.zig");
const Output = @import("Output.zig");
const View = @import("View.zig");
const Utils = @import("Utils.zig");
const Keymap = @import("types/Keymap.zig");
const Hook = @import("types/Hook.zig");
const Events = @import("types/Events.zig");
const gpa = std.heap.c_allocator;
const server = &@import("main.zig").server;

View file

@ -4,7 +4,7 @@ const std = @import("std");
const wl = @import("wayland").server.wl;
const wlr = @import("wlroots");
const Utils = @import("utils.zig");
const Utils = @import("Utils.zig");
const gpa = std.heap.c_allocator;
const server = &@import("main.zig").server;
@ -64,7 +64,15 @@ pub fn initFromTopLevel(xdg_toplevel: *wlr.XdgToplevel) *View {
// Add new Toplevel to root of the tree
// Later add to spesified output
self.scene_tree = try server.root.scene.tree.createSceneXdgSurface(xdg_toplevel.base);
if(server.seat.focused_output) |output| {
std.log.debug("adding new view to content layer", .{});
self.scene_tree = try output.layers.content.createSceneXdgSurface(xdg_toplevel.base);
// _ = output;
// self.scene_tree = try server.root.scene.tree.createSceneXdgSurface(xdg_toplevel.base);
} else {
self.scene_tree = try server.root.waiting_room.createSceneXdgSurface(xdg_toplevel.base);
std.log.err("No output to attach new view to", .{});
}
self.scene_tree.node.data = self;
self.xdg_toplevel.base.data = self.scene_tree;
@ -153,8 +161,6 @@ fn handleMap(listener: *wl.Listener(void)) void {
_ = decoration.setMode(wlr.XdgToplevelDecorationV1.Mode.server_side);
}
// Here is where we should tile and set size
view.mapped = true;
server.events.exec("ViewMapPost", .{view.id});
@ -216,40 +222,19 @@ fn handleNewPopup(listener: *wl.Listener(*wlr.XdgPopup), popup: *wlr.XdgPopup) v
}
fn handleRequestMove(
_: *wl.Listener(*wlr.XdgToplevel.event.Move),
listener: *wl.Listener(*wlr.XdgToplevel.event.Move),
_: *wlr.XdgToplevel.event.Move
) void {
// const view: *View = @fieldParentPtr("request_move", listener);
// server.cursor.moveView(view);
// 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));
const view: *View = @fieldParentPtr("request_move", listener);
server.events.exec("ViewRequestMove", .{view.id});
}
fn handleRequestResize(
_: *wl.Listener(*wlr.XdgToplevel.event.Resize),
listener: *wl.Listener(*wlr.XdgToplevel.event.Resize),
_: *wlr.XdgToplevel.event.Resize
) void {
// const view: *View = @fieldParentPtr("request_resize", listener);
std.log.debug("The clients should not be request moves", .{});
// 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;
const view: *View = @fieldParentPtr("request_resize", listener);
server.events.exec("ViewRequestResize", .{view.id});
}
fn handleAckConfigure(
@ -265,30 +250,26 @@ fn handleRequestFullscreen(
listener: *wl.Listener(void)
) void {
const view: *View = @fieldParentPtr("request_fullscreen", listener);
_ = view;
std.log.err("Unimplemented request fullscreen", .{});
server.events.exec("ViewRequestFullscreen", .{view.id});
}
fn handleRequestMinimize(
listener: *wl.Listener(void)
) void {
const view: *View = @fieldParentPtr("request_fullscreen", listener);
_ = view;
std.log.err("Unimplemented request minimize", .{});
const view: *View = @fieldParentPtr("request_minimize", listener);
server.events.exec("ViewRequestFullscreen", .{view.id});
}
fn handleSetAppId(
listener: *wl.Listener(void)
) void {
const view: *View = @fieldParentPtr("set_app_id", listener);
_ = view;
std.log.err("Unimplemented set appid", .{});
server.events.exec("ViewAppIdUpdate", .{view.id});
}
fn handleSetTitle(
listener: *wl.Listener(void)
) void {
const view: *View = @fieldParentPtr("set_title", listener);
_ = view;
std.log.err("Unimplemented set title", .{});
server.events.exec("ViewTitleUpdate", .{view.id});
}

View file

@ -1,7 +1,7 @@
const Bridge = @This();
const std = @import("std");
const Lua = @import("lua.zig");
const Lua = @import("Lua.zig");
const gpa = std.heap.c_allocator;

View file

@ -3,7 +3,7 @@ const Fs = @This();
const std = @import("std");
const zlua = @import("zlua");
const Lua = @import("lua.zig");
const Lua = @import("Lua.zig");
const gpa = std.heap.c_allocator;

View file

@ -3,8 +3,8 @@ const Hook = @This();
const std = @import("std");
const zlua = @import("zlua");
const THook = @import("../types/hook.zig");
const Utils = @import("../utils.zig");
const THook = @import("../types/Hook.zig");
const Utils = @import("../Utils.zig");
const gpa = std.heap.c_allocator;
const server = &@import("../main.zig").server;

View file

@ -5,8 +5,8 @@ const zlua = @import("zlua");
const xkb = @import("xkbcommon");
const wlr = @import("wlroots");
const Keymap = @import("../types/keymap.zig");
const Utils = @import("../utils.zig");
const Keymap = @import("../types/Keymap.zig");
const Utils = @import("../Utils.zig");
const server = &@import("../main.zig").server;

View file

@ -4,13 +4,13 @@ const std = @import("std");
const config = @import("config");
const zlua = @import("zlua");
const Bridge = @import("bridge.zig");
const Fs = @import("fs.zig");
const Input = @import("input.zig");
const Api = @import("api.zig");
const Hook = @import("hook.zig");
const View = @import("view.zig");
const Output = @import("output.zig");
const Bridge = @import("Bridge.zig");
const Fs = @import("Fs.zig");
const Input = @import("Input.zig");
const Api = @import("Api.zig");
const Hook = @import("Hook.zig");
const View = @import("View.zig");
const Output = @import("Output.zig");
const gpa = std.heap.c_allocator;

View file

@ -1,7 +1,7 @@
const std = @import("std");
const zlua = @import("zlua");
const Output = @import("../output.zig");
const Output = @import("../Output.zig");
const server = &@import("../main.zig").server;

View file

@ -1,7 +1,7 @@
const std = @import("std");
const zlua = @import("zlua");
const View = @import("../view.zig");
const View = @import("../View.zig");
const server = &@import("../main.zig").server;
@ -104,9 +104,11 @@ pub fn set_size(L: *zlua.Lua) i32 {
pub fn set_focused(L: *zlua.Lua) i32 {
const view_id: ?c_longlong = L.optInteger(1);
if(view_id == null and server.seat.focused_view != null) {
server.seat.focused_view.?.focused = false;
server.seat.focused_view = null;
if(view_id == null) {
if(server.seat.focused_view != null) {
server.seat.focused_view.?.focused = false;
server.seat.focused_view = null;
}
L.pushNil();
return 1;
}

View file

@ -1,8 +1,8 @@
const std = @import("std");
const wlr = @import("wlroots");
const Server = @import("server.zig");
const Lua = @import("lua/lua.zig");
const Server = @import("Server.zig");
const Lua = @import("lua/Lua.zig");
const gpa = std.heap.c_allocator;

View file

@ -2,7 +2,7 @@ pub const Events = @This();
const std = @import("std");
const Hook = @import("hook.zig");
const Hook = @import("Hook.zig");
const Node = struct {
hook: *const Hook,

View file

@ -7,7 +7,7 @@ const xkb = @import("xkbcommon");
const wlr = @import("wlroots");
const zlua = @import("zlua");
const Event = @import("events.zig");
const Event = @import("Events.zig");
const Lua = &@import("../main.zig").lua;
events: std.ArrayList([]const u8), // a list of events