mirror of
https://github.com/MezzalunaWM/Mezzaluna.git
synced 2026-03-08 04:57:32 -04:00
fullscreen
This commit is contained in:
commit
49e0875a85
12 changed files with 488 additions and 150 deletions
|
|
@ -1,4 +1,5 @@
|
|||
local env_conf = os.getenv("XDG_CONFIG_HOME")
|
||||
|
||||
if not env_conf then
|
||||
env_conf = os.getenv("HOME")
|
||||
if not env_conf then
|
||||
|
|
@ -11,7 +12,7 @@ end
|
|||
package.path = package.path..";"..mez.fs.joinpath(mez.path.runtime, "?.lua")
|
||||
mez.inspect = require("inspect").inspect
|
||||
|
||||
mez.path.base_config = mez.fs.joinpath(mez.path.runtime, "base_config.lua")
|
||||
mez.path.base_config = mez.fs.joinpath(mez.path.runtime, "master.lua")
|
||||
|
||||
if not mez.path.config then
|
||||
mez.path.config = mez.fs.joinpath(env_conf, "mez", "init.lua")
|
||||
|
|
|
|||
|
|
@ -1,3 +1,11 @@
|
|||
mez.input.add_keymap("alt", "g", {
|
||||
press = function ()
|
||||
for _, id in ipairs(mez.view.get_all_ids()) do
|
||||
print(id)
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
local master = function()
|
||||
local config = {
|
||||
tag_count = 5,
|
||||
|
|
@ -6,7 +14,7 @@ local master = function()
|
|||
local ctx = {
|
||||
master_ratio = 0.5,
|
||||
tags = {},
|
||||
tag_id = 1
|
||||
tag_id = 1,
|
||||
}
|
||||
|
||||
local tile_onscreen = function(tag_id, res)
|
||||
|
|
@ -124,9 +132,10 @@ local master = function()
|
|||
end
|
||||
})
|
||||
|
||||
mez.hook.add("ViewPointerMotion", {
|
||||
callback = function (view_id, cursor_x, cursor_y)
|
||||
mez.view.set_focused(view_id)
|
||||
|
||||
mez.hook.add("ViewRequestFullscreen", {
|
||||
callback = function (view_id)
|
||||
mez.view.toggle_fullscreen(view_id)
|
||||
end
|
||||
})
|
||||
|
||||
|
|
@ -248,6 +257,29 @@ local master = function()
|
|||
end
|
||||
})
|
||||
|
||||
local fullscreen = function (view_id)
|
||||
print("Fullscreen")
|
||||
mez.view.toggle_fullscreen(view_id)
|
||||
mez.view.set_position(view_id, 0, 0)
|
||||
local res = mez.output.get_resolution(0)
|
||||
mez.view.set_size(view_id, res.width, res.height)
|
||||
tile_all()
|
||||
end
|
||||
|
||||
mez.input.add_keymap("alt|shift", "F", {
|
||||
press = function() fullscreen(0) end
|
||||
})
|
||||
|
||||
mez.hook.add("ViewRequestFullscreen", {
|
||||
callback = fullscreen
|
||||
})
|
||||
|
||||
mez.hook.add("ViewPointerMotion", {
|
||||
callback = function (view_id, cursor_x, cursor_y)
|
||||
mez.view.set_focused(view_id)
|
||||
end
|
||||
})
|
||||
|
||||
for i = 1, 12 do
|
||||
mez.input.add_keymap("ctrl|alt", "XF86Switch_VT_"..i, {
|
||||
press = function() mez.api.change_vt(i) end
|
||||
|
|
@ -282,4 +314,3 @@ function print_table(tbl, indent, seen)
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ mode: enum { passthrough, move, resize } = .passthrough,
|
|||
drag: struct {
|
||||
start_x: c_int,
|
||||
start_y: c_int,
|
||||
view: ?*View,
|
||||
view: ?*View,
|
||||
view_offset_x: ?c_int,
|
||||
view_offset_y: ?c_int,
|
||||
},
|
||||
|
|
@ -86,8 +86,8 @@ pub fn processCursorMotion(self: *Cursor, time_msec: u32) void {
|
|||
// Exit the switch if no focused output exists
|
||||
if (output == null) return;
|
||||
|
||||
const viewAtResult = output.?.viewAt(self.wlr_cursor.x, self.wlr_cursor.y);
|
||||
if (viewAtResult == null) {
|
||||
const surfaceAtResult = output.?.surfaceAt(self.wlr_cursor.x, self.wlr_cursor.y);
|
||||
if (surfaceAtResult == null) {
|
||||
self.wlr_cursor.setXcursor(self.x_cursor_manager, "default");
|
||||
server.seat.wlr_seat.pointerClearFocus();
|
||||
|
||||
|
|
@ -98,10 +98,16 @@ pub fn processCursorMotion(self: *Cursor, time_msec: u32) void {
|
|||
return;
|
||||
}
|
||||
|
||||
server.events.exec("ViewPointerMotion", .{viewAtResult.?.view.id, self.wlr_cursor.x, self.wlr_cursor.y});
|
||||
switch (surfaceAtResult.?.scene_node_data.*) {
|
||||
.view => {
|
||||
server.events.exec("ViewPointerMotion", .{surfaceAtResult.?.scene_node_data.view.id, self.wlr_cursor.x, self.wlr_cursor.y});
|
||||
},
|
||||
.layer_surface => { },
|
||||
else => unreachable
|
||||
}
|
||||
|
||||
server.seat.wlr_seat.pointerNotifyEnter(viewAtResult.?.surface, viewAtResult.?.sx, viewAtResult.?.sy);
|
||||
server.seat.wlr_seat.pointerNotifyMotion(time_msec, viewAtResult.?.sx, viewAtResult.?.sy);
|
||||
server.seat.wlr_seat.pointerNotifyEnter(surfaceAtResult.?.surface, surfaceAtResult.?.sx, surfaceAtResult.?.sy);
|
||||
server.seat.wlr_seat.pointerNotifyMotion(time_msec, surfaceAtResult.?.sx, surfaceAtResult.?.sy);
|
||||
},
|
||||
.move => { // TODO: Have these behave more like pointer motion
|
||||
if(self.drag.view) |view| {
|
||||
|
|
|
|||
127
src/Debug.zig
Normal file
127
src/Debug.zig
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
const Debug = @This();
|
||||
|
||||
const std = @import("std");
|
||||
const wlr = @import("wlroots");
|
||||
|
||||
const server = &@import("main.zig").server;
|
||||
const gpa = std.heap.c_allocator;
|
||||
|
||||
const Utils = @import("Utils.zig");
|
||||
const SceneNodeData = @import("SceneNodeData.zig").SceneNodeData;
|
||||
|
||||
pub fn debugPrintSceneTree() void {
|
||||
std.log.debug("=== SCENE TREE DEBUG ===", .{});
|
||||
printNode(&server.root.scene.tree.node, 0);
|
||||
std.log.debug("=== END SCENE TREE ===", .{});
|
||||
}
|
||||
|
||||
fn printNode(node: *wlr.SceneNode, depth: usize) void {
|
||||
errdefer Utils.oomPanic();
|
||||
|
||||
var buffer: std.ArrayList(u8) = try .initCapacity(gpa, 512);
|
||||
defer buffer.deinit(gpa);
|
||||
const writer = buffer.writer(gpa);
|
||||
|
||||
// Add indentation
|
||||
for (0..depth) |_| {
|
||||
writer.writeAll(" ") catch unreachable;
|
||||
}
|
||||
|
||||
// Print node type and position
|
||||
const type_name = switch (node.type) {
|
||||
.tree => "TREE",
|
||||
.rect => "RECT",
|
||||
.buffer => "BUFFER"
|
||||
};
|
||||
|
||||
writer.print("{s} @ ({d}, {d}) enabled={}", .{
|
||||
type_name,
|
||||
node.x,
|
||||
node.y,
|
||||
node.enabled
|
||||
}) catch unreachable;
|
||||
|
||||
// Add associated data if present
|
||||
if (node.data) |data| {
|
||||
const scene_node_data: *SceneNodeData = @ptrCast(@alignCast(data));
|
||||
switch (scene_node_data.*) {
|
||||
.root => {
|
||||
writer.print(" → Root Scene Tree", .{}) catch unreachable;
|
||||
},
|
||||
.output => |output| {
|
||||
writer.print(" → Output: {s} (focused={}, id={})", .{
|
||||
output.wlr_output.name,
|
||||
output.focused,
|
||||
output.id,
|
||||
}) catch unreachable;
|
||||
},
|
||||
.output_layer => {
|
||||
writer.print(" → Output Layer", .{}) catch unreachable;
|
||||
},
|
||||
.view => |view| {
|
||||
writer.print(" → View: id={} mapped={} focused={}", .{
|
||||
view.id,
|
||||
view.xdg_toplevel.base.surface.mapped,
|
||||
view.focused,
|
||||
}) catch unreachable;
|
||||
if (view.xdg_toplevel.title) |title| {
|
||||
writer.print(" title=\"{s}\"", .{title}) catch unreachable;
|
||||
}
|
||||
},
|
||||
.layer_surface => |layer| {
|
||||
const layer_name = switch (layer.wlr_layer_surface.current.layer) {
|
||||
.background => "background",
|
||||
.bottom => "bottom",
|
||||
.top => "top",
|
||||
.overlay => "overlay",
|
||||
else => "unknown",
|
||||
};
|
||||
writer.print(" → LayerSurface: layer={s} mapped={}", .{
|
||||
layer_name,
|
||||
layer.wlr_layer_surface.surface.mapped,
|
||||
}) catch unreachable;
|
||||
const namespace = std.mem.span(layer.wlr_layer_surface.namespace);
|
||||
if (namespace.len > 0) {
|
||||
writer.print(" namespace=\"{s}\"", .{namespace}) catch unreachable;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add buffer-specific info
|
||||
if (node.type == .buffer) {
|
||||
const scene_buffer = wlr.SceneBuffer.fromNode(node);
|
||||
writer.print(" buffer: {d}x{d}", .{
|
||||
if (scene_buffer.buffer == null) -1 else scene_buffer.buffer.?.width,
|
||||
if (scene_buffer.buffer == null) -1 else scene_buffer.buffer.?.height,
|
||||
}) catch unreachable;
|
||||
|
||||
// Check if it's a surface
|
||||
if (wlr.SceneSurface.tryFromBuffer(scene_buffer)) |scene_surface| {
|
||||
writer.print(" → Surface: {*}", .{scene_surface.surface}) catch unreachable;
|
||||
}
|
||||
}
|
||||
|
||||
// Print the complete line
|
||||
std.log.debug("{s}", .{buffer.items});
|
||||
|
||||
// Recursively print children if this is a tree
|
||||
if (node.type == .tree) {
|
||||
const tree = wlr.SceneTree.fromNode(node);
|
||||
var it = tree.children.iterator(.forward);
|
||||
var child_count: usize = 0;
|
||||
while (it.next()) |child| {
|
||||
child_count += 1;
|
||||
printNode(child, depth + 1);
|
||||
}
|
||||
if (child_count == 0) {
|
||||
var empty_buffer: std.ArrayList(u8) = try .initCapacity(gpa, 512);
|
||||
defer empty_buffer.deinit(gpa);
|
||||
for (0..depth) |_| {
|
||||
empty_buffer.writer(gpa).writeAll("\t") catch unreachable;
|
||||
}
|
||||
empty_buffer.writer(gpa).writeAll(" (no children)") catch unreachable;
|
||||
std.log.debug("{s}", .{empty_buffer.items});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,12 +6,13 @@ const wlr = @import("wlroots");
|
|||
|
||||
const Utils = @import("Utils.zig");
|
||||
const Output = @import("Output.zig");
|
||||
const SceneNodeData = @import("SceneNodeData.zig");
|
||||
const SceneNodeData = @import("SceneNodeData.zig").SceneNodeData;
|
||||
|
||||
const gpa = std.heap.c_allocator;
|
||||
const server = &@import("main.zig").server;
|
||||
|
||||
output: *Output,
|
||||
scene_node_data: SceneNodeData,
|
||||
wlr_layer_surface: *wlr.LayerSurfaceV1,
|
||||
scene_layer_surface: *wlr.SceneLayerSurfaceV1,
|
||||
|
||||
|
|
@ -27,9 +28,22 @@ pub fn init(wlr_layer_surface: *wlr.LayerSurfaceV1) *LayerSurface {
|
|||
const self = try gpa.create(LayerSurface);
|
||||
|
||||
self.* = .{
|
||||
.output = @ptrCast(@alignCast(wlr_layer_surface.output.?.data)),
|
||||
.output = blk: {
|
||||
// These block things are dangerous
|
||||
// There was no need for this
|
||||
// But I cannot be stopped
|
||||
// - Powerhungry programmer
|
||||
const data = wlr_layer_surface.output.?.data;
|
||||
if(data == null) unreachable;
|
||||
const scene_node_data: *SceneNodeData = @ptrCast(@alignCast(wlr_layer_surface.output.?.data.?));
|
||||
break :blk switch(scene_node_data.*) {
|
||||
.output => @fieldParentPtr("scene_node_data", scene_node_data),
|
||||
else => unreachable
|
||||
};
|
||||
},
|
||||
.wlr_layer_surface = wlr_layer_surface,
|
||||
.scene_layer_surface = undefined,
|
||||
.scene_node_data = .{ .layer_surface = self }
|
||||
};
|
||||
|
||||
if(server.seat.focused_output) |output| {
|
||||
|
|
@ -45,11 +59,8 @@ pub fn init(wlr_layer_surface: *wlr.LayerSurfaceV1) *LayerSurface {
|
|||
};
|
||||
}
|
||||
|
||||
try SceneNodeData.setData(
|
||||
&self.scene_layer_surface.tree.node,
|
||||
.{ .layer_surface = self },
|
||||
);
|
||||
self.wlr_layer_surface.surface.data = &self.scene_layer_surface.tree.node;
|
||||
self.wlr_layer_surface.surface.data = &self.scene_node_data;
|
||||
self.scene_layer_surface.tree.node.data = &self.scene_node_data;
|
||||
|
||||
self.wlr_layer_surface.events.destroy.add(&self.destroy);
|
||||
self.wlr_layer_surface.surface.events.map.add(&self.map);
|
||||
|
|
@ -93,8 +104,10 @@ fn handleDestroy(
|
|||
fn handleMap(
|
||||
listener: *wl.Listener(void)
|
||||
) void {
|
||||
const layer: *LayerSurface = @fieldParentPtr("map", listener);
|
||||
layer.allowKeyboard();
|
||||
const layer_suraface: *LayerSurface = @fieldParentPtr("map", listener);
|
||||
std.log.debug("layer surface mapped", .{});
|
||||
layer_suraface.output.arrangeLayers();
|
||||
layer_suraface.allowKeyboard();
|
||||
}
|
||||
|
||||
fn handleUnmap(listener: *wl.Listener(void)) void {
|
||||
|
|
@ -102,6 +115,8 @@ fn handleUnmap(listener: *wl.Listener(void)) void {
|
|||
|
||||
// FIXME: this crashes mez when killing mez
|
||||
layer_surface.output.arrangeLayers();
|
||||
|
||||
// TODO: Idk if this should be deiniting the layer surface entirely
|
||||
layer_surface.deinit();
|
||||
}
|
||||
|
||||
|
|
|
|||
132
src/Output.zig
132
src/Output.zig
|
|
@ -5,11 +5,13 @@ 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 View = @import("View.zig");
|
||||
const LayerSurface = @import("LayerSurface.zig");
|
||||
const SceneNodeData = @import("SceneNodeData.zig");
|
||||
|
||||
const SceneNodeData = @import("SceneNodeData.zig").SceneNodeData;
|
||||
|
||||
const posix = std.posix;
|
||||
const gpa = std.heap.c_allocator;
|
||||
|
|
@ -21,6 +23,7 @@ id: u64,
|
|||
wlr_output: *wlr.Output,
|
||||
state: wlr.Output.State,
|
||||
tree: *wlr.SceneTree,
|
||||
scene_node_data: SceneNodeData,
|
||||
scene_output: *wlr.SceneOutput,
|
||||
|
||||
layers: struct {
|
||||
|
|
@ -32,6 +35,15 @@ layers: struct {
|
|||
overlay: *wlr.SceneTree
|
||||
},
|
||||
|
||||
layer_scene_node_data: struct {
|
||||
background: SceneNodeData,
|
||||
bottom: SceneNodeData,
|
||||
content: SceneNodeData,
|
||||
top: SceneNodeData,
|
||||
fullscreen: SceneNodeData,
|
||||
overlay: SceneNodeData
|
||||
},
|
||||
|
||||
frame: wl.Listener(*wlr.Output) = .init(handleFrame),
|
||||
request_state: wl.Listener(*wlr.Output.event.RequestState) = .init(handleRequestState),
|
||||
destroy: wl.Listener(*wlr.Output) = .init(handleDestroy),
|
||||
|
|
@ -45,6 +57,7 @@ pub fn init(wlr_output: *wlr.Output) ?*Output {
|
|||
|
||||
const self = try gpa.create(Output);
|
||||
|
||||
|
||||
self.* = .{
|
||||
.focused = false,
|
||||
.id = @intFromPtr(wlr_output),
|
||||
|
|
@ -58,10 +71,21 @@ pub fn init(wlr_output: *wlr.Output) ?*Output {
|
|||
.fullscreen = try self.tree.createSceneTree(),
|
||||
.overlay = try self.tree.createSceneTree(),
|
||||
},
|
||||
.layer_scene_node_data = .{
|
||||
.background = .{ .output_layer = self.layers.background },
|
||||
.bottom = .{ .output_layer = self.layers.bottom },
|
||||
.content = .{ .output_layer = self.layers.content },
|
||||
.top = .{ .output_layer = self.layers.top },
|
||||
.fullscreen = .{ .output_layer = self.layers.fullscreen },
|
||||
.overlay = .{ .output_layer = self.layers.overlay }
|
||||
},
|
||||
.scene_output = try server.root.scene.createSceneOutput(wlr_output),
|
||||
.scene_node_data = SceneNodeData{ .output = self },
|
||||
.state = wlr.Output.State.init()
|
||||
};
|
||||
|
||||
|
||||
|
||||
wlr_output.events.frame.add(&self.frame);
|
||||
wlr_output.events.request_state.add(&self.request_state);
|
||||
wlr_output.events.destroy.add(&self.destroy);
|
||||
|
|
@ -88,7 +112,15 @@ pub fn init(wlr_output: *wlr.Output) ?*Output {
|
|||
server.root.scene_output_layout.addOutput(layout_output, self.scene_output);
|
||||
self.setFocused();
|
||||
|
||||
wlr_output.data = self;
|
||||
self.wlr_output.data = &self.scene_node_data;
|
||||
self.tree.node.data = &self.scene_node_data;
|
||||
|
||||
self.layers.background.node.data = &self.layer_scene_node_data.background;
|
||||
self.layers.bottom.node.data = &self.layer_scene_node_data.bottom;
|
||||
self.layers.content.node.data = &self.layer_scene_node_data.content;
|
||||
self.layers.top.node.data = &self.layer_scene_node_data.top;
|
||||
self.layers.fullscreen.node.data = &self.layer_scene_node_data.fullscreen;
|
||||
self.layers.overlay.node.data = &self.layer_scene_node_data.overlay;
|
||||
|
||||
server.events.exec("OutputInitPost", .{self.id});
|
||||
|
||||
|
|
@ -130,7 +162,6 @@ pub fn configureLayers(self: *Output) void {
|
|||
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{
|
||||
|
|
@ -146,43 +177,85 @@ pub fn configureLayers(self: *Output) void {
|
|||
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 scene_node_data: *SceneNodeData = @ptrCast(@alignCast(node.data.?));
|
||||
switch (scene_node_data.*) {
|
||||
.layer_surface => {
|
||||
_ = scene_node_data.layer_surface.wlr_layer_surface.configured(
|
||||
@intCast(output_box.width),
|
||||
@intCast(output_box.height)
|
||||
);
|
||||
},
|
||||
else => {
|
||||
std.log.err("Something other than a layer surface found in layer surface scene trees", .{});
|
||||
unreachable;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const ViewAtResult = struct {
|
||||
view: *View,
|
||||
const SurfaceAtResult = struct {
|
||||
scene_node_data: *SceneNodeData,
|
||||
surface: *wlr.Surface,
|
||||
sx: f64,
|
||||
sy: f64,
|
||||
};
|
||||
|
||||
pub fn viewAt(self: *Output, lx: f64, ly: f64) ?ViewAtResult {
|
||||
pub fn surfaceAt(self: *Output, lx: f64, ly: f64) ?SurfaceAtResult {
|
||||
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;
|
||||
const layers = [_]*wlr.SceneTree{
|
||||
self.layers.top,
|
||||
self.layers.overlay,
|
||||
self.layers.fullscreen,
|
||||
self.layers.content,
|
||||
self.layers.bottom,
|
||||
self.layers.background
|
||||
};
|
||||
|
||||
var it: ?*wlr.SceneTree = node.parent;
|
||||
for(layers) |layer| {
|
||||
const node = layer.node.at(lx, ly, &sx, &sy);
|
||||
if(node == null) continue;
|
||||
|
||||
while (it) |n| : (it = n.node.parent) {
|
||||
if (n.node.data == null) continue;
|
||||
const surface: ?*wlr.Surface = blk: {
|
||||
if (node.?.type == .buffer) {
|
||||
const scene_buffer = wlr.SceneBuffer.fromNode(node.?);
|
||||
if (wlr.SceneSurface.tryFromBuffer(scene_buffer)) |scene_surface| {
|
||||
break :blk scene_surface.surface;
|
||||
}
|
||||
}
|
||||
break :blk null;
|
||||
};
|
||||
if(surface == null) continue;
|
||||
|
||||
const view: *View = @ptrCast(@alignCast(n.node.data.?));
|
||||
const scene_node_data: *SceneNodeData = blk: {
|
||||
var n = node.?;
|
||||
while (true) {
|
||||
if (@as(?*SceneNodeData, @ptrCast(@alignCast(n.data)))) |snd| {
|
||||
break :blk snd;
|
||||
}
|
||||
if (n.parent) |parent_tree| {
|
||||
n = &parent_tree.node;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return ViewAtResult{
|
||||
.view = view,
|
||||
.surface = scene_surface.surface,
|
||||
.sx = sx,
|
||||
.sy = sy,
|
||||
};
|
||||
switch (scene_node_data.*) {
|
||||
.layer_surface, .view => {
|
||||
return SurfaceAtResult{
|
||||
.scene_node_data = scene_node_data,
|
||||
.surface = surface.?,
|
||||
.sx = sx,
|
||||
.sy = sy,
|
||||
};
|
||||
},
|
||||
else => continue
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -246,9 +319,17 @@ pub fn arrangeLayers(self: *Output) void {
|
|||
inline for (@typeInfo(zwlr.LayerShellV1.Layer).@"enum".fields) |comptime_layer| {
|
||||
const layer: *wlr.SceneTree = @field(self.layers, comptime_layer.name);
|
||||
var it = layer.children.safeIterator(.forward);
|
||||
|
||||
while (it.next()) |node| {
|
||||
if (@as(?*SceneNodeData, @alignCast(@ptrCast(node.data)))) |node_data| {
|
||||
const layer_surface = node_data.data.layer_surface;
|
||||
if(node.data == null) continue;
|
||||
|
||||
// if (@as(?*SceneNodeData, @alignCast(@ptrCast(node.data)))) |node_data| {
|
||||
const scene_node_data: *SceneNodeData = @ptrCast(@alignCast(node.data.?));
|
||||
|
||||
const layer_surface: *LayerSurface = switch(scene_node_data.*) {
|
||||
.layer_surface => @fieldParentPtr("scene_node_data", scene_node_data),
|
||||
else => continue
|
||||
};
|
||||
|
||||
if (!layer_surface.wlr_layer_surface.initialized) continue;
|
||||
|
||||
|
|
@ -263,7 +344,6 @@ pub fn arrangeLayers(self: *Output) void {
|
|||
// const x = layer_surface.scene_layer_surface.tree.node.x;
|
||||
// const y = layer_surface.scene_layer_surface.tree.node.y;
|
||||
// layer_surface.scene_layer_surface.tree.node.setPosition(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
52
src/Root.zig
52
src/Root.zig
|
|
@ -1,22 +1,26 @@
|
|||
/// The root of Mezzaluna is, you guessed it, the root of many of the systems mez needs:
|
||||
/// - Managing outputs
|
||||
/// -
|
||||
|
||||
const Root = @This();
|
||||
|
||||
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 server = &@import("main.zig").server;
|
||||
const gpa = std.heap.c_allocator;
|
||||
|
||||
const Output = @import("Output.zig");
|
||||
const View = @import("View.zig");
|
||||
const LayerSurface = @import("LayerSurface.zig");
|
||||
const SceneNodeData = @import("SceneNodeData.zig").SceneNodeData;
|
||||
|
||||
const Utils = @import("Utils.zig");
|
||||
|
||||
xdg_toplevel_decoration_manager: *wlr.XdgDecorationManagerV1,
|
||||
|
||||
scene: *wlr.Scene,
|
||||
scene_node_data: SceneNodeData,
|
||||
|
||||
waiting_room: *wlr.SceneTree,
|
||||
scene_output_layout: *wlr.SceneOutputLayout,
|
||||
|
||||
|
|
@ -35,11 +39,14 @@ pub fn init(self: *Root) void {
|
|||
|
||||
self.* = .{
|
||||
.scene = scene,
|
||||
.scene_node_data = .{ .root = self },
|
||||
.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),
|
||||
};
|
||||
|
||||
self.scene.tree.node.data = &self.scene_node_data;
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Root) void {
|
||||
|
|
@ -48,8 +55,16 @@ pub fn deinit(self: *Root) void {
|
|||
while(it.next()) |node| {
|
||||
if(node.data == null) continue;
|
||||
|
||||
const view: *View = @ptrCast(@alignCast(node.data.?));
|
||||
view.deinit();
|
||||
const scene_node_data: *SceneNodeData = @ptrCast(@alignCast(node.data.?));
|
||||
switch(scene_node_data.*) {
|
||||
.output => {
|
||||
scene_node_data.output.deinit();
|
||||
},
|
||||
else => {
|
||||
std.log.debug("The root has a child that is not an output", .{});
|
||||
unreachable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.output_layout.destroy();
|
||||
|
|
@ -62,14 +77,29 @@ pub fn viewById(self: *Root, id: u64) ?*View {
|
|||
|
||||
while(output_it.next()) |o| {
|
||||
if(o.output.data == null) continue;
|
||||
const output: *Output = @ptrCast(@alignCast(o.output.data.?));
|
||||
|
||||
const output_snd: *SceneNodeData = @ptrCast(@alignCast(o.output.data.?));
|
||||
const output: *Output = switch (output_snd.*) {
|
||||
.output => |output_ptr| output_ptr,
|
||||
else => {
|
||||
std.log.err("Incorrect scene node type found", .{});
|
||||
unreachable;
|
||||
}
|
||||
};
|
||||
|
||||
var node_it = output.layers.content.children.iterator(.forward);
|
||||
|
||||
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;
|
||||
const view_snd: *SceneNodeData = @ptrCast(@alignCast(node.data.?));
|
||||
|
||||
// TODO: Should we assert that we want only views to be here
|
||||
// -- Basically should we use switch statements for snd interactions
|
||||
// -- Or if statements, for simplicity
|
||||
if(view_snd.* == .view and view_snd.view.id == id) {
|
||||
return view_snd.view;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,54 +1,22 @@
|
|||
const SceneNodeData = @This();
|
||||
|
||||
const std = @import("std");
|
||||
const wlr = @import("wlroots");
|
||||
const wl = @import("wayland").server.wl;
|
||||
|
||||
const View = @import("View.zig");
|
||||
const LayerSurface = @import("LayerSurface.zig");
|
||||
const Output = @import("Output.zig");
|
||||
const Root = @import("Root.zig");
|
||||
|
||||
const gpa = std.heap.c_allocator;
|
||||
|
||||
pub const Data = union(enum) {
|
||||
view: *View,
|
||||
layer_surface: *LayerSurface,
|
||||
const SceneNodeType = enum {
|
||||
view,
|
||||
layer_surface,
|
||||
output,
|
||||
output_layer,
|
||||
root
|
||||
};
|
||||
|
||||
node: *wlr.SceneNode,
|
||||
data: Data,
|
||||
destroy: wl.Listener(void) = wl.Listener(void).init(handleDestroy),
|
||||
|
||||
pub fn setData(node: *wlr.SceneNode, data: Data) !void {
|
||||
const scene_node_data = try gpa.create(SceneNodeData);
|
||||
|
||||
scene_node_data.* = .{
|
||||
.node = node,
|
||||
.data = data,
|
||||
};
|
||||
node.data = scene_node_data;
|
||||
|
||||
node.events.destroy.add(&scene_node_data.destroy);
|
||||
}
|
||||
|
||||
fn handleDestroy(listener: *wl.Listener(void)) void {
|
||||
const scene_node_data: *SceneNodeData = @fieldParentPtr("destroy", listener);
|
||||
|
||||
scene_node_data.destroy.link.remove();
|
||||
scene_node_data.node.data = null;
|
||||
|
||||
gpa.destroy(scene_node_data);
|
||||
}
|
||||
|
||||
pub fn getFromNode(node: *wlr.SceneNode) ?*SceneNodeData {
|
||||
var n = node;
|
||||
while (true) {
|
||||
if (@as(?*SceneNodeData, @alignCast(@ptrCast(n.data)))) |scene_node_data| {
|
||||
return scene_node_data;
|
||||
}
|
||||
if (n.parent) |parent_tree| {
|
||||
n = &parent_tree.node;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
pub const SceneNodeData = union(SceneNodeType) {
|
||||
view: *View,
|
||||
layer_surface: *LayerSurface,
|
||||
output: *Output,
|
||||
output_layer: *wlr.SceneTree,
|
||||
root: *Root
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,20 +4,21 @@ 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("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 Popup = @import("Popup.zig");
|
||||
const RemoteLua = @import("RemoteLua.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 Keymap = @import("types/Keymap.zig");
|
||||
const Hook = @import("types/Hook.zig");
|
||||
const Events = @import("types/Events.zig");
|
||||
const Popup = @import("Popup.zig");
|
||||
const RemoteLua = @import("RemoteLua.zig");
|
||||
const RemoteLuaManager = @import("RemoteLuaManager.zig");
|
||||
const Utils = @import("Utils.zig");
|
||||
const SceneNodeData = @import("SceneNodeData.zig").SceneNodeData;
|
||||
|
||||
const gpa = std.heap.c_allocator;
|
||||
const server = &@import("main.zig").server;
|
||||
|
|
@ -34,8 +35,7 @@ shm: *wlr.Shm,
|
|||
xdg_shell: *wlr.XdgShell,
|
||||
layer_shell: *wlr.LayerShellV1,
|
||||
xdg_toplevel_decoration_manager: *wlr.XdgDecorationManagerV1,
|
||||
|
||||
// Input
|
||||
xdg_activation: *wlr.XdgActivationV1,
|
||||
|
||||
allocator: *wlr.Allocator,
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ root: Root,
|
|||
seat: Seat,
|
||||
cursor: Cursor,
|
||||
|
||||
// lua data
|
||||
// Lua data
|
||||
keymaps: std.AutoHashMap(u64, Keymap),
|
||||
hooks: std.ArrayList(*Hook),
|
||||
events: Events,
|
||||
|
|
@ -53,14 +53,11 @@ remote_lua_clients: std.DoublyLinkedList,
|
|||
new_input: wl.Listener(*wlr.InputDevice) = .init(handleNewInput),
|
||||
new_output: wl.Listener(*wlr.Output) = .init(handleNewOutput),
|
||||
// backend.events.destroy
|
||||
|
||||
// XdgShell listeners
|
||||
new_xdg_toplevel: wl.Listener(*wlr.XdgToplevel) = .init(handleNewXdgToplevel),
|
||||
new_xdg_popup: wl.Listener(*wlr.XdgPopup) = .init(handleNewXdgPopup),
|
||||
new_xdg_toplevel_decoration: wl.Listener(*wlr.XdgToplevelDecorationV1) = .init(handleNewXdgToplevelDecoration),
|
||||
|
||||
// LayerShell Listeners
|
||||
new_layer_surface: wl.Listener(*wlr.LayerSurfaceV1) = .init(handleNewLayerSurface),
|
||||
request_activate: wl.Listener(*wlr.XdgActivationV1.event.RequestActivate) = .init(handleRequestActivate),
|
||||
|
||||
pub fn init(self: *Server) void {
|
||||
errdefer Utils.oomPanic();
|
||||
|
|
@ -94,6 +91,7 @@ pub fn init(self: *Server) void {
|
|||
.xdg_shell = try wlr.XdgShell.create(wl_server, 2),
|
||||
.layer_shell = try wlr.LayerShellV1.create(wl_server, 4),
|
||||
.xdg_toplevel_decoration_manager = try wlr.XdgDecorationManagerV1.create(self.wl_server),
|
||||
.xdg_activation = try wlr.XdgActivationV1.create(self.wl_server),
|
||||
.event_loop = event_loop,
|
||||
.session = session,
|
||||
.compositor = try wlr.Compositor.create(wl_server, 6, renderer),
|
||||
|
|
@ -133,19 +131,13 @@ pub fn init(self: *Server) void {
|
|||
self.root.scene.setGammaControlManagerV1(try wlr.GammaControlManagerV1.create(self.wl_server));
|
||||
|
||||
// Add event listeners to events
|
||||
// Backedn events
|
||||
self.backend.events.new_input.add(&self.new_input);
|
||||
self.backend.events.new_output.add(&self.new_output);
|
||||
|
||||
// XdgShell events
|
||||
self.xdg_shell.events.new_toplevel.add(&self.new_xdg_toplevel);
|
||||
self.xdg_shell.events.new_popup.add(&self.new_xdg_popup);
|
||||
|
||||
// XdgDecorationManagerV1 events
|
||||
self.xdg_toplevel_decoration_manager.events.new_toplevel_decoration.add(&self.new_xdg_toplevel_decoration);
|
||||
|
||||
// LayerShell events
|
||||
self.layer_shell.events.new_surface.add(&self.new_layer_surface);
|
||||
self.xdg_activation.events.request_activate.add(&self.request_activate);
|
||||
|
||||
self.events.exec("ServerStartPost", .{});
|
||||
}
|
||||
|
|
@ -217,14 +209,15 @@ fn handleNewXdgToplevelDecoration(
|
|||
}
|
||||
}
|
||||
|
||||
fn handleNewXdgPopup(_: *wl.Listener(*wlr.XdgPopup), xdg_popup: *wlr.XdgPopup) void {
|
||||
_ = xdg_popup;
|
||||
fn handleNewXdgPopup(_: *wl.Listener(*wlr.XdgPopup), _: *wlr.XdgPopup) void {
|
||||
std.log.debug("Unimplemented Server.handleNewXdgPopup\n", .{});
|
||||
}
|
||||
|
||||
fn handleNewLayerSurface(
|
||||
_: *wl.Listener(*wlr.LayerSurfaceV1),
|
||||
layer_surface: *wlr.LayerSurfaceV1
|
||||
) void {
|
||||
std.log.debug("requested layer shell\n", .{});
|
||||
if (layer_surface.output == null) {
|
||||
if (server.seat.focused_output == null) {
|
||||
std.log.err("No output available for new layer surface", .{});
|
||||
|
|
@ -237,3 +230,17 @@ fn handleNewLayerSurface(
|
|||
|
||||
_ = LayerSurface.init(layer_surface);
|
||||
}
|
||||
|
||||
fn handleRequestActivate(
|
||||
_: *wl.Listener(*wlr.XdgActivationV1.event.RequestActivate),
|
||||
event: *wlr.XdgActivationV1.event.RequestActivate,
|
||||
) void {
|
||||
if(event.surface.data == null) return;
|
||||
|
||||
const scene_node_data: *SceneNodeData = @ptrCast(@alignCast(event.surface.data.?));
|
||||
if(scene_node_data.* == .view) {
|
||||
scene_node_data.view.setFocused();
|
||||
} else {
|
||||
std.log.warn("Ignoring request to activate non-view", .{});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
31
src/View.zig
31
src/View.zig
|
|
@ -6,6 +6,8 @@ const wlr = @import("wlroots");
|
|||
|
||||
const Popup = @import("Popup.zig");
|
||||
const Output = @import("Output.zig");
|
||||
const SceneNodeData = @import("SceneNodeData.zig").SceneNodeData;
|
||||
|
||||
const Utils = @import("Utils.zig");
|
||||
|
||||
const gpa = std.heap.c_allocator;
|
||||
|
|
@ -13,6 +15,7 @@ const server = &@import("main.zig").server;
|
|||
|
||||
mapped: bool,
|
||||
focused: bool,
|
||||
fullscreen: bool,
|
||||
id: u64,
|
||||
|
||||
// workspace: Workspace,
|
||||
|
|
@ -20,6 +23,7 @@ output: ?*Output,
|
|||
xdg_toplevel: *wlr.XdgToplevel,
|
||||
xdg_toplevel_decoration: ?*wlr.XdgToplevelDecorationV1,
|
||||
scene_tree: *wlr.SceneTree,
|
||||
scene_node_data: SceneNodeData,
|
||||
|
||||
// Surface Listeners
|
||||
map: wl.Listener(void) = .init(handleMap),
|
||||
|
|
@ -56,12 +60,15 @@ pub fn initFromTopLevel(xdg_toplevel: *wlr.XdgToplevel) *View {
|
|||
self.* = .{
|
||||
.focused = false,
|
||||
.mapped = false,
|
||||
.fullscreen = false,
|
||||
.id = @intFromPtr(xdg_toplevel),
|
||||
.output = null,
|
||||
|
||||
.xdg_toplevel = xdg_toplevel,
|
||||
.scene_tree = undefined,
|
||||
.xdg_toplevel_decoration = null,
|
||||
|
||||
.scene_node_data = .{ .view = self }
|
||||
};
|
||||
|
||||
self.xdg_toplevel.base.surface.events.unmap.add(&self.unmap);
|
||||
|
|
@ -76,8 +83,8 @@ pub fn initFromTopLevel(xdg_toplevel: *wlr.XdgToplevel) *View {
|
|||
self.scene_tree = try server.root.waiting_room.createSceneXdgSurface(xdg_toplevel.base);
|
||||
}
|
||||
|
||||
self.scene_tree.node.data = self;
|
||||
self.xdg_toplevel.base.data = self.scene_tree;
|
||||
self.scene_tree.node.data = &self.scene_node_data;
|
||||
self.xdg_toplevel.base.data = &self.scene_node_data;
|
||||
|
||||
self.xdg_toplevel.events.destroy.add(&self.destroy);
|
||||
self.xdg_toplevel.base.surface.events.map.add(&self.map);
|
||||
|
|
@ -123,11 +130,27 @@ pub fn setFocused(self: *View) void {
|
|||
}
|
||||
|
||||
pub fn close(self: *View) void {
|
||||
self.xdg_toplevel.sendClose();
|
||||
if(self.focused) {
|
||||
server.seat.focused_view = null;
|
||||
}
|
||||
}
|
||||
|
||||
self.xdg_toplevel.sendClose();
|
||||
pub fn toFullscreen(self: *View) void {
|
||||
// TODO: What should the final behaviour of this be
|
||||
if(server.seat.focused_output) |output| {
|
||||
self.scene_tree.node.reparent(output.layers.fullscreen);
|
||||
}
|
||||
self.fullscreen = true;
|
||||
_ = self.xdg_toplevel.setFullscreen(true);
|
||||
}
|
||||
|
||||
pub fn toContent(self: *View) void {
|
||||
if(server.seat.focused_output) |output| {
|
||||
self.scene_tree.node.reparent(output.layers.content);
|
||||
}
|
||||
self.fullscreen = false;
|
||||
_ = self.xdg_toplevel.setFullscreen(false);
|
||||
}
|
||||
|
||||
pub fn setPosition(self: *View, x: i32, y: i32) void {
|
||||
|
|
@ -258,7 +281,7 @@ fn handleRequestMinimize(
|
|||
listener: *wl.Listener(void)
|
||||
) void {
|
||||
const view: *View = @fieldParentPtr("request_minimize", listener);
|
||||
server.events.exec("ViewRequestFullscreen", .{view.id});
|
||||
server.events.exec("ViewRequestMinimize", .{view.id});
|
||||
}
|
||||
|
||||
fn handleSetAppId(
|
||||
|
|
|
|||
|
|
@ -55,3 +55,11 @@ pub fn change_vt(L: *zlua.Lua) i32 {
|
|||
L.pushNil();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// --- Print the scene tree for debugging
|
||||
pub fn print_scene(L: *zlua.Lua) i32 {
|
||||
@import("../Debug.zig").debugPrintSceneTree();
|
||||
|
||||
L.pushNil();
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
const std = @import("std");
|
||||
const zlua = @import("zlua");
|
||||
const wlr = @import("wlroots");
|
||||
|
||||
const Output = @import("../Output.zig");
|
||||
const View = @import("../View.zig");
|
||||
const SceneNodeData = @import("../SceneNodeData.zig").SceneNodeData;
|
||||
const LuaUtils = @import("LuaUtils.zig");
|
||||
|
||||
const server = &@import("../main.zig").server;
|
||||
|
|
@ -15,24 +18,48 @@ fn view_id_err(L: *zlua.Lua) noreturn {
|
|||
// ---Get the ids for all available views
|
||||
// ---@return view_id[]?
|
||||
pub fn get_all_ids(L: *zlua.Lua) i32 {
|
||||
var it = server.root.scene.tree.children.iterator(.forward);
|
||||
var index: usize = 1;
|
||||
var output_it = server.root.output_layout.outputs.iterator(.forward);
|
||||
var index: i32 = 1;
|
||||
|
||||
L.newTable();
|
||||
|
||||
while(it.next()) |node| : (index += 1) {
|
||||
if(node.data == null) continue;
|
||||
while(output_it.next()) |o| {
|
||||
if(o.output.data == null) continue;
|
||||
const output: *Output = @ptrCast(@alignCast(o.output.data.?));
|
||||
|
||||
const view = @as(*View, @ptrCast(@alignCast(node.data.?)));
|
||||
const layers = [_]*wlr.SceneTree{
|
||||
output.layers.content,
|
||||
output.layers.fullscreen,
|
||||
};
|
||||
|
||||
L.pushInteger(@intCast(index));
|
||||
L.pushInteger(@intCast(view.id));
|
||||
L.setTable(-3);
|
||||
for(layers) |layer| {
|
||||
if(layer.children.length() == 0) continue;
|
||||
if(@intFromPtr(layer) == 0) {
|
||||
std.log.debug("ts is literally a null ptr", .{});
|
||||
continue;
|
||||
}
|
||||
|
||||
var view_it = layer.children.iterator(.forward);
|
||||
|
||||
while(view_it.next()) |v| {
|
||||
if(v.data == null) continue;
|
||||
const scene_node_data: *SceneNodeData = @ptrCast(@alignCast(v.data.?));
|
||||
|
||||
if(scene_node_data.* == .view) {
|
||||
L.pushInteger(@intCast(index));
|
||||
L.pushInteger(@intCast(scene_node_data.view.id));
|
||||
L.setTable(-3);
|
||||
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// TODO: What is this?
|
||||
pub fn check(L: *zlua.Lua) i32 {
|
||||
L.pushNil();
|
||||
return 1;
|
||||
|
|
@ -69,14 +96,10 @@ pub fn close(L: *zlua.Lua) i32 {
|
|||
// ---@param x number x position for view
|
||||
// ---@param y number y position for view
|
||||
pub fn set_position(L: *zlua.Lua) i32 {
|
||||
std.log.debug("repositioning", .{});
|
||||
|
||||
const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L);
|
||||
const x = LuaUtils.coerceNumber(i32, L.checkNumber(2)) catch L.raiseErrorStr("The x must be > -inf and < inf", .{});
|
||||
const y = LuaUtils.coerceNumber(i32, L.checkNumber(3)) catch L.raiseErrorStr("The y must be > -inf and < inf", .{});
|
||||
|
||||
std.log.debug("position to set: ({d}, {d})", .{x, y});
|
||||
|
||||
const view: ?*View = if (view_id == 0) server.seat.focused_view else server.root.viewById(view_id);
|
||||
if(view) |v| {
|
||||
v.setPosition(x, y);
|
||||
|
|
@ -158,6 +181,25 @@ pub fn set_focused(L: *zlua.Lua) i32 {
|
|||
return 1;
|
||||
}
|
||||
|
||||
// ---Resize the view by it's top left corner
|
||||
// ---@param view_id view_id 0 maps to focused view
|
||||
pub fn toggle_fullscreen(L: *zlua.Lua) i32 {
|
||||
const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L);
|
||||
|
||||
const view: ?*View = if (view_id == 0) server.seat.focused_view else server.root.viewById(view_id);
|
||||
if(view) |v| {
|
||||
std.log.debug("toggling fullscreen", .{});
|
||||
if(v.fullscreen) {
|
||||
v.toContent();
|
||||
} else {
|
||||
v.toFullscreen();
|
||||
}
|
||||
}
|
||||
|
||||
L.pushNil();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ---Get the title of the view
|
||||
// ---@param view_id view_id 0 maps to focused view
|
||||
// ---@return string?
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue