Merge branch 'bouncing' into dev

This commit is contained in:
Harrison DiAmbrosio 2025-12-15 23:15:49 -05:00
commit d4a0abe762
11 changed files with 270 additions and 123 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

View file

@ -20,8 +20,6 @@ pub fn build(b: *std.Build) void {
// subprocessing your CLI tool. // subprocessing your CLI tool.
// The below is copied from tinywl // The below is copied from tinywl
// TODO: Ensure versioning is correct
// TODO: Ensure paths for system protocols are correct
const scanner = Scanner.create(b, .{}); const scanner = Scanner.create(b, .{});
scanner.addSystemProtocol("stable/xdg-shell/xdg-shell.xml"); scanner.addSystemProtocol("stable/xdg-shell/xdg-shell.xml");
scanner.addSystemProtocol("stable/tablet/tablet-v2.xml"); scanner.addSystemProtocol("stable/tablet/tablet-v2.xml");

View file

@ -6,6 +6,43 @@ mez.input.add_keymap("alt", "g", {
end end
}) })
mez.input.add_keymap("alt", "i", {
press = function ()
local coroutine = require("coroutine")
print(coroutine)
local co = coroutine.create(function ()
print("starting coroutine")
local view_id = mez.view.get_focused_id()
local size = mez.view.get_size(view_id)
local pos = mez.view.get_position(view_id)
local res = mez.output.get_resolution(0)
local x_pos = pos.x
local y_pos = pos.y
local x_vel = 10
local y_vel = 10
while true do
x_pos = x_pos + x_vel
y_pos = y_pos + y_vel
if x_pos + size.width > res.width or x_pos < 0 then
x_vel = x_vel * -1
end
if y_pos + size.height > res.height or y_pos < 0 then
y_vel = y_vel * -1
end
print("(" .. x_pos .. ", " .. y_pos .. ")")
mez.view.set_position(view_id, x_pos, y_pos)
end
end)
coroutine.resume(co)
end
})
local master = function() local master = function()
local config = { local config = {
tag_count = 5, tag_count = 5,
@ -132,13 +169,6 @@ local master = function()
end end
}) })
mez.hook.add("ViewRequestFullscreen", {
callback = function (view_id)
mez.view.toggle_fullscreen(view_id)
end
})
mez.input.add_keymap("alt", "p", { mez.input.add_keymap("alt", "p", {
press = function() press = function()
mez.api.spawn("wmenu-run") mez.api.spawn("wmenu-run")
@ -258,11 +288,7 @@ local master = function()
}) })
local fullscreen = function (view_id) local fullscreen = function (view_id)
print("Fullscreen")
mez.view.toggle_fullscreen(view_id) 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() tile_all()
end end

View file

@ -122,15 +122,18 @@ pub fn processCursorMotion(self: *Cursor, time_msec: u32) void {
}, },
.resize => { .resize => {
// Fix this resize // Fix this resize
const focused_view = server.seat.focused_view; const view: *View = blk: {
if(server.seat.focused_surface) |fs| {
if(fs != .view) return;
break :blk fs.view;
} else { return; }
};
if(focused_view) |view| {
_ = view.xdg_toplevel.setSize( _ = view.xdg_toplevel.setSize(
// TODO: configure the min and max using lua? // TODO: configure the min and max using lua?
std.math.clamp(@as(c_int, @as(i32, @intFromFloat(self.wlr_cursor.x)) - view.scene_tree.node.x), 10, std.math.maxInt(i32)), std.math.clamp(@as(c_int, @as(i32, @intFromFloat(self.wlr_cursor.x)) - view.scene_tree.node.x), 10, std.math.maxInt(i32)),
std.math.clamp(@as(c_int, @as(i32, @intFromFloat(self.wlr_cursor.y)) - view.scene_tree.node.y), 10, std.math.maxInt(i32)) std.math.clamp(@as(c_int, @as(i32, @intFromFloat(self.wlr_cursor.y)) - view.scene_tree.node.y), 10, std.math.maxInt(i32))
); );
}
}, },
} }
} }
@ -160,10 +163,6 @@ fn handleButton(
_ = server.seat.wlr_seat.pointerNotifyButton(event.time_msec, event.button, event.state); _ = server.seat.wlr_seat.pointerNotifyButton(event.time_msec, event.button, event.state);
if (server.seat.focused_view) |view| {
view.setFocused();
}
// @hook PointerButtonPress // TODO Probably change this name // @hook PointerButtonPress // TODO Probably change this name
// @param button string // TODO Translate a button to a string or smth // @param button string // TODO Translate a button to a string or smth
// @param state string - "pressed" or "released" // @param state string - "pressed" or "released"
@ -177,18 +176,23 @@ fn handleButton(
// Can be BTN_RIGHT, BTN_LEFT, or BTN_MIDDLE // Can be BTN_RIGHT, BTN_LEFT, or BTN_MIDDLE
cursor.drag.start_x = @as(c_int, @intFromFloat(cursor.wlr_cursor.x)); 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.start_y = @as(c_int, @intFromFloat(cursor.wlr_cursor.y));
if(server.seat.focused_view) |view| { if(server.seat.focused_surface) |fs| {
// Keep track of where the drag started // Keep track of where the drag started
cursor.drag.view = view;
cursor.drag.view_offset_x = cursor.drag.start_x - view.scene_tree.node.x; if(fs == .view) {
cursor.drag.view_offset_y = cursor.drag.start_y - view.scene_tree.node.y; cursor.drag.view = fs.view;
cursor.drag.view_offset_x = cursor.drag.start_x - fs.view.scene_tree.node.x;
cursor.drag.view_offset_y = cursor.drag.start_y - fs.view.scene_tree.node.y;
}
// Maybe comptime this for later reference // Maybe comptime this for later reference
if(event.button == c.libevdev_event_code_from_name(c.EV_KEY, "BTN_LEFT")) { if(event.button == c.libevdev_event_code_from_name(c.EV_KEY, "BTN_LEFT")) {
cursor.mode = .move; cursor.mode = .move;
} else if(event.button == c.libevdev_event_code_from_name(c.EV_KEY, "BTN_RIGHT")) { } else if(event.button == c.libevdev_event_code_from_name(c.EV_KEY, "BTN_RIGHT")) {
if(fs == .view) {
cursor.mode = .resize; cursor.mode = .resize;
_ = view.xdg_toplevel.setResizing(true); _ = fs.view.xdg_toplevel.setResizing(true);
}
} }
} }
} }

View file

@ -19,6 +19,7 @@ const server = &@import("main.zig").server;
focused: bool, focused: bool,
id: u64, id: u64,
fullscreen: ?*View,
wlr_output: *wlr.Output, wlr_output: *wlr.Output,
state: wlr.Output.State, state: wlr.Output.State,
@ -63,6 +64,7 @@ pub fn init(wlr_output: *wlr.Output) ?*Output {
.id = @intFromPtr(wlr_output), .id = @intFromPtr(wlr_output),
.wlr_output = wlr_output, .wlr_output = wlr_output,
.tree = try server.root.scene.tree.createSceneTree(), .tree = try server.root.scene.tree.createSceneTree(),
.fullscreen = null,
.layers = .{ .layers = .{
.background = try self.tree.createSceneTree(), .background = try self.tree.createSceneTree(),
.bottom = try self.tree.createSceneTree(), .bottom = try self.tree.createSceneTree(),
@ -84,8 +86,6 @@ pub fn init(wlr_output: *wlr.Output) ?*Output {
.state = wlr.Output.State.init() .state = wlr.Output.State.init()
}; };
wlr_output.events.frame.add(&self.frame); wlr_output.events.frame.add(&self.frame);
wlr_output.events.request_state.add(&self.request_state); wlr_output.events.request_state.add(&self.request_state);
wlr_output.events.destroy.add(&self.destroy); wlr_output.events.destroy.add(&self.destroy);
@ -259,6 +259,21 @@ pub fn surfaceAt(self: *Output, lx: f64, ly: f64) ?SurfaceAtResult {
return null; return null;
} }
pub fn getFullscreenedView(self: *Output) ?*View {
if(self.layers.fullscreen.children.length() != 1) {
return null;
}
var it = self.layers.fullscreen.children.iterator(.forward);
if(it.next().?.data) |data| {
const scene_node_data: *SceneNodeData = @ptrCast(@alignCast(data));
if(scene_node_data.* == .view) {
return scene_node_data.view;
}
}
return null;
}
// --------- WlrOutput Event Handlers --------- // --------- WlrOutput Event Handlers ---------
fn handleRequestState( fn handleRequestState(
listener: *wl.Listener(*wlr.Output.event.RequestState), listener: *wl.Listener(*wlr.Output.event.RequestState),

View file

@ -101,6 +101,10 @@ pub fn viewById(self: *Root, id: u64) ?*View {
return view_snd.view; return view_snd.view;
} }
} }
if(output.fullscreen) |fullscreen| {
if(fullscreen.id == id) return fullscreen;
}
} }
return null; return null;

View file

@ -6,13 +6,23 @@ const wl = @import("wayland").server.wl;
const xkb = @import("xkbcommon"); const xkb = @import("xkbcommon");
const Utils = @import("Utils.zig"); const Utils = @import("Utils.zig");
const Popup = @import("Popup.zig");
const View = @import("View.zig"); const View = @import("View.zig");
const LayerSurface = @import("LayerSurface.zig");
const Output = @import("Output.zig"); const Output = @import("Output.zig");
const server = &@import("main.zig").server; const server = &@import("main.zig").server;
const FocusDataType = enum { view, popup, layer_surface };
pub const FocusData = union(FocusDataType) {
view: *View,
popup: *Popup,
layer_surface: *LayerSurface
};
wlr_seat: *wlr.Seat, wlr_seat: *wlr.Seat,
focused_view: ?*View,
focused_surface: ?FocusData,
focused_output: ?*Output, focused_output: ?*Output,
keyboard_group: *wlr.KeyboardGroup, keyboard_group: *wlr.KeyboardGroup,
@ -40,7 +50,7 @@ pub fn init(self: *Seat) void {
self.* = .{ self.* = .{
.wlr_seat = try wlr.Seat.create(server.wl_server, "default"), .wlr_seat = try wlr.Seat.create(server.wl_server, "default"),
.focused_view = null, .focused_surface = null,
.focused_output = null, .focused_output = null,
.keyboard_group = try wlr.KeyboardGroup.create(), .keyboard_group = try wlr.KeyboardGroup.create(),
.keymap = keymap.ref(), .keymap = keymap.ref(),
@ -65,6 +75,85 @@ pub fn deinit(self: *Seat) void {
self.wlr_seat.destroy(); self.wlr_seat.destroy();
} }
pub fn focusSurface(self: *Seat, to_focus: ?FocusData) void {
const surface: ?*wlr.Surface = blk: {
if (to_focus != null) {
break :blk switch (to_focus.?) {
.view => to_focus.?.view.xdg_toplevel.base.surface,
.layer_surface => to_focus.?.layer_surface.wlr_layer_surface.surface,
.popup => to_focus.?.popup.xdg_popup.base.surface
};
} else {
break :blk null;
}
};
// Remove focus from the current surface unless:
// - current and to focus are the same surface
// - current layer has exclusive keyboard interactivity
// - current is fullscreen and to focus is content
// - current is fullscreen and layer is bottom or background
if (self.focused_surface) |current_focus| {
const current_surface = switch(current_focus) {
.view => current_focus.view.xdg_toplevel.base.surface,
.layer_surface => current_focus.layer_surface.wlr_layer_surface.surface,
.popup => current_focus.popup.xdg_popup.base.surface
};
if (current_surface == surface) return; // Same surface
if(to_focus != null) {
switch (current_focus) {
.layer_surface => |*current_layer_surface| {
if(current_layer_surface.*.wlr_layer_surface.current.keyboard_interactive == .exclusive) return;
},
.view => |*current_view| {
if(current_view.*.fullscreen) {
switch (to_focus.?) {
.layer_surface => |*layer_surface| {
const layer = layer_surface.*.wlr_layer_surface.current.layer;
if(layer == .background or layer == .bottom) return;
},
.view => |*view| {
if(!view.*.fullscreen) return;
},
else => {}
}
}
},
else => {}
}
} else if(current_focus == .view and current_focus.view.fullscreen){
return;
}
// Clear the focus if applicable
switch (current_focus) {
.layer_surface => {}, // IDK if we actually have to clear any focus here
else => {
if(wlr.XdgSurface.tryFromWlrSurface(current_surface)) |xdg_surface| {
_ = xdg_surface.role_data.toplevel.?.setActivated(false);
}
}
}
}
if(to_focus != null) {
server.seat.wlr_seat.keyboardNotifyEnter(
surface.?,
&server.seat.wlr_seat.keyboard_state.keyboard.?.keycodes,
null
);
if(to_focus.? != .layer_surface) {
if(to_focus.? == .view) to_focus.?.view.focused = true;
if(wlr.XdgSurface.tryFromWlrSurface(surface.?)) |xdg_surface| {
_ = xdg_surface.role_data.toplevel.?.setActivated(true);
}
}
}
self.focused_surface = to_focus;
}
pub fn focusOutput(self: *Seat, output: *Output) void { pub fn focusOutput(self: *Seat, output: *Output) void {
if(server.seat.focused_output) |prev_output| { if(server.seat.focused_output) |prev_output| {
prev_output.focused = false; prev_output.focused = false;

View file

@ -238,8 +238,15 @@ fn handleRequestActivate(
if(event.surface.data == null) return; if(event.surface.data == null) return;
const scene_node_data: *SceneNodeData = @ptrCast(@alignCast(event.surface.data.?)); const scene_node_data: *SceneNodeData = @ptrCast(@alignCast(event.surface.data.?));
if(scene_node_data.* == .view) { if(scene_node_data.* == .view) {
scene_node_data.view.setFocused(); if(server.seat.focused_output) |output| {
if(output.fullscreen) |fullscreen| {
server.seat.focusSurface(.{ .view = fullscreen });
return;
}
}
server.seat.focusSurface(Seat.FocusData{ .view = scene_node_data.view });
} else { } else {
std.log.warn("Ignoring request to activate non-view", .{}); std.log.warn("Ignoring request to activate non-view", .{});
} }

View file

@ -104,53 +104,35 @@ pub fn deinit(self: *View) void {
self.request_resize.link.remove(); self.request_resize.link.remove();
} }
pub fn setFocused(self: *View) void {
if (server.seat.wlr_seat.keyboard_state.focused_surface) |previous_surface| {
if (previous_surface == self.xdg_toplevel.base.surface) return;
if (wlr.XdgSurface.tryFromWlrSurface(previous_surface)) |xdg_surface| {
_ = xdg_surface.role_data.toplevel.?.setActivated(false);
}
}
self.scene_tree.node.raiseToTop();
_ = self.xdg_toplevel.setActivated(true);
const wlr_keyboard = server.seat.wlr_seat.getKeyboard() orelse return;
server.seat.wlr_seat.keyboardNotifyEnter(
self.xdg_toplevel.base.surface,
wlr_keyboard.keycodes[0..wlr_keyboard.num_keycodes],
&wlr_keyboard.modifiers,
);
if(server.seat.focused_view) |prev_view| {
prev_view.focused = false;
}
server.seat.focused_view = self;
self.focused = true;
}
pub fn close(self: *View) void { pub fn close(self: *View) void {
self.xdg_toplevel.sendClose();
if(self.focused) { if(self.focused) {
server.seat.focused_view = null; if(self.fullscreen) self.toggleFullscreen();
} self.focused = false;
server.seat.focusSurface(null);
} }
pub fn toFullscreen(self: *View) void { self.xdg_toplevel.sendClose();
// TODO: What should the final behaviour of this be }
pub fn toggleFullscreen(self: *View) void {
self.fullscreen = !self.fullscreen;
if(server.seat.focused_output) |output| { if(server.seat.focused_output) |output| {
if(self.fullscreen and output.fullscreen != self) {
// Check to see if another fullscreened view exists, if so replace it
if(output.getFullscreenedView()) |view| {
view.toggleFullscreen();
}
self.scene_tree.node.reparent(output.layers.fullscreen); self.scene_tree.node.reparent(output.layers.fullscreen);
} self.setPosition(0, 0);
self.fullscreen = true; self.setSize(output.wlr_output.width, output.wlr_output.height);
_ = self.xdg_toplevel.setFullscreen(true); output.fullscreen = self;
} } else {
pub fn toContent(self: *View) void {
if(server.seat.focused_output) |output| {
self.scene_tree.node.reparent(output.layers.content); self.scene_tree.node.reparent(output.layers.content);
output.fullscreen = null;
} }
self.fullscreen = false; }
_ = self.xdg_toplevel.setFullscreen(false); _ = self.xdg_toplevel.setFullscreen(self.fullscreen);
} }
pub fn setPosition(self: *View, x: i32, y: i32) void { pub fn setPosition(self: *View, x: i32, y: i32) void {
@ -282,6 +264,7 @@ fn handleRequestMinimize(
) void { ) void {
const view: *View = @fieldParentPtr("request_minimize", listener); const view: *View = @fieldParentPtr("request_minimize", listener);
server.events.exec("ViewRequestMinimize", .{view.id}); server.events.exec("ViewRequestMinimize", .{view.id});
std.log.debug("request_minimize unimplemented", .{});
} }
fn handleSetAppId( fn handleSetAppId(
@ -289,6 +272,7 @@ fn handleSetAppId(
) void { ) void {
const view: *View = @fieldParentPtr("set_app_id", listener); const view: *View = @fieldParentPtr("set_app_id", listener);
server.events.exec("ViewAppIdUpdate", .{view.id}); server.events.exec("ViewAppIdUpdate", .{view.id});
std.log.debug("request_set_app_id unimplemented", .{});
} }
fn handleSetTitle( fn handleSetTitle(
@ -296,4 +280,5 @@ fn handleSetTitle(
) void { ) void {
const view: *View = @fieldParentPtr("set_title", listener); const view: *View = @fieldParentPtr("set_title", listener);
server.events.exec("ViewTitleUpdate", .{view.id}); server.events.exec("ViewTitleUpdate", .{view.id});
std.log.debug("request_set_title unimplemented", .{});
} }

View file

@ -3,6 +3,10 @@ const LuaUtils = @This();
const std = @import("std"); const std = @import("std");
const zlua = @import("zlua"); const zlua = @import("zlua");
const View = @import("../View.zig");
const server = &@import("../main.zig").server;
pub fn coerceNumber(comptime x: type, number: zlua.Number) error{InvalidNumber}!x { pub fn coerceNumber(comptime x: type, number: zlua.Number) error{InvalidNumber}!x {
if (number < std.math.minInt(x) or number > std.math.maxInt(x) or std.math.isNan(number)) { if (number < std.math.minInt(x) or number > std.math.maxInt(x) or std.math.isNan(number)) {
return error.InvalidNumber; return error.InvalidNumber;
@ -43,3 +47,14 @@ pub fn toStringEx(L: *zlua.Lua) [:0]const u8 {
L.protectedCall(.{ .args = 1, .results = 1 }) catch return errstr; L.protectedCall(.{ .args = 1, .results = 1 }) catch return errstr;
return L.toString(-1) catch errstr; return L.toString(-1) catch errstr;
} }
pub fn viewById(view_id: u64) ?*View {
if (view_id == 0) {
if(server.seat.focused_surface) |fs| {
if(fs == .view) return fs.view;
}
} else {
return server.root.viewById(view_id);
}
return null;
}

View file

@ -68,10 +68,12 @@ pub fn check(L: *zlua.Lua) i32 {
// ---Get the id for the focused view // ---Get the id for the focused view
// ---@return view_id? // ---@return view_id?
pub fn get_focused_id(L: *zlua.Lua) i32 { pub fn get_focused_id(L: *zlua.Lua) i32 {
if(server.seat.focused_view) |view| { if(server.seat.focused_surface) |fs| {
L.pushInteger(@intCast(view.id)); if(fs == .view) {
L.pushInteger(@intCast(fs.view.id));
return 1; return 1;
} }
}
L.pushNil(); L.pushNil();
return 1; return 1;
@ -82,8 +84,7 @@ pub fn get_focused_id(L: *zlua.Lua) i32 {
pub fn close(L: *zlua.Lua) i32 { pub fn close(L: *zlua.Lua) i32 {
const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); 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(LuaUtils.viewById(view_id)) |v| {
if(view) |v| {
v.close(); v.close();
} }
@ -100,8 +101,7 @@ pub fn set_position(L: *zlua.Lua) i32 {
const x = LuaUtils.coerceNumber(i32, L.checkNumber(2)) catch L.raiseErrorStr("The x must be > -inf and < inf", .{}); 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", .{}); const y = LuaUtils.coerceNumber(i32, L.checkNumber(3)) catch L.raiseErrorStr("The y must be > -inf and < inf", .{});
const view: ?*View = if (view_id == 0) server.seat.focused_view else server.root.viewById(view_id); if(LuaUtils.viewById(view_id)) |v| {
if(view) |v| {
v.setPosition(x, y); v.setPosition(x, y);
} }
@ -109,10 +109,33 @@ pub fn set_position(L: *zlua.Lua) i32 {
return 1; return 1;
} }
// ---Resize the view by it's top left corner // ---Get the position of the view
// ---@param view_id view_id 0 maps to focused view // ---@param view_id view_id 0 maps to focused view
// ---@param width number width for view // ---@return { x: integer, y: integer }? Position of the view
// ---@param height number height for view pub fn get_position(L: *zlua.Lua) i32 {
const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L);
if (LuaUtils.viewById(view_id)) |v| {
L.newTable();
_ = L.pushString("x");
L.pushInteger(@intCast(v.xdg_toplevel.base.geometry.x));
L.setTable(-3);
_ = L.pushString("y");
L.pushInteger(@intCast(v.xdg_toplevel.base.geometry.y));
L.setTable(-3);
return 1;
}
L.pushNil();
return 1;
}
// ---Set the size of the spesified view. Will be resized relative to
// the view's top left corner.
// ---@param view_id view_id 0 maps to focused view
// ---@return
pub fn set_size(L: *zlua.Lua) i32 { pub fn set_size(L: *zlua.Lua) i32 {
const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L);
// We use u32s here to enforce a minimum size of zero. The call to resize a // We use u32s here to enforce a minimum size of zero. The call to resize a
@ -122,8 +145,7 @@ pub fn set_size(L: *zlua.Lua) i32 {
const width = LuaUtils.coerceNumber(u32, L.checkNumber(2)) catch L.raiseErrorStr("The width must be >= 0 and < inf", .{}); const width = LuaUtils.coerceNumber(u32, L.checkNumber(2)) catch L.raiseErrorStr("The width must be >= 0 and < inf", .{});
const height = LuaUtils.coerceNumber(u32, L.checkNumber(3)) catch L.raiseErrorStr("The height must be >= 0 and < inf", .{}); const height = LuaUtils.coerceNumber(u32, L.checkNumber(3)) catch L.raiseErrorStr("The height must be >= 0 and < inf", .{});
const view: ?*View = if (view_id == 0) server.seat.focused_view else server.root.viewById(view_id); if(LuaUtils.viewById(view_id)) |v| {
if(view) |v| {
v.setSize(@intCast(width), @intCast(height)); v.setSize(@intCast(width), @intCast(height));
} }
@ -131,10 +153,12 @@ pub fn set_size(L: *zlua.Lua) i32 {
return 1; return 1;
} }
// ---Get the size of the view
// ---@param view_id view_id 0 maps to focused view
// ---@return { width: integer, height: integer }? Size of the view
pub fn get_size(L: *zlua.Lua) i32 { pub fn get_size(L: *zlua.Lua) i32 {
const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); 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 (LuaUtils.viewById(view_id)) |v| {
if (view) |v| {
L.newTable(); L.newTable();
_ = L.pushString("width"); _ = L.pushString("width");
@ -158,23 +182,9 @@ pub fn set_focused(L: *zlua.Lua) i32 {
const view_id: ?c_longlong = L.optInteger(1); const view_id: ?c_longlong = L.optInteger(1);
if(view_id == null) { if(view_id == null) {
if(server.seat.focused_view != null) { server.seat.focusSurface(null);
server.seat.focused_view.?.focused = false; } else if(server.root.viewById(@intCast(view_id.?))) |view| {
server.seat.focused_view = null; server.seat.focusSurface(.{ .view = view });
}
L.pushNil();
return 1;
}
if (view_id == null) {
L.pushNil();
return 1;
}
if(server.root.viewById(@intCast(view_id.?))) |view| {
view.setFocused();
L.pushNil();
return 1;
} }
L.pushNil(); L.pushNil();
@ -186,14 +196,10 @@ pub fn set_focused(L: *zlua.Lua) i32 {
pub fn toggle_fullscreen(L: *zlua.Lua) i32 { pub fn toggle_fullscreen(L: *zlua.Lua) i32 {
const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); 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); std.log.debug("fullscreen view {d}", .{view_id});
if(view) |v| { if(LuaUtils.viewById(view_id)) |v| {
std.log.debug("toggling fullscreen", .{}); std.log.debug("toggling fullscreen", .{});
if(v.fullscreen) { v.toggleFullscreen();
v.toContent();
} else {
v.toFullscreen();
}
} }
L.pushNil(); L.pushNil();
@ -206,8 +212,7 @@ pub fn toggle_fullscreen(L: *zlua.Lua) i32 {
pub fn get_title(L: *zlua.Lua) i32 { pub fn get_title(L: *zlua.Lua) i32 {
const view_id: u64 = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); const view_id: u64 = 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(LuaUtils.viewById(view_id)) |v| {
if(view) |v| {
if(v.xdg_toplevel.title == null) { if(v.xdg_toplevel.title == null) {
L.pushNil(); L.pushNil();
return 1; return 1;
@ -227,8 +232,7 @@ pub fn get_title(L: *zlua.Lua) i32 {
pub fn get_app_id(L: *zlua.Lua) i32 { pub fn get_app_id(L: *zlua.Lua) i32 {
const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); 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(LuaUtils.viewById(view_id)) |v| {
if(view) |v| {
if(v.xdg_toplevel.app_id == null) { if(v.xdg_toplevel.app_id == null) {
L.pushNil(); L.pushNil();
return 1; return 1;