const std = @import("std"); const posix = std.posix; const sys = @import("sys.zig"); const Wm = @import("Wm.zig"); pub const std_options: std.Options = .{ .log_level = if (@import("builtin").mode == .Debug) .debug else .info, }; const version = "0.1.0"; const usage = \\att_wm - a dwm-like window manager for the river Wayland compositor \\ \\Usage: att_wm [options] \\ \\att_wm is a river-window-management-v1 client and must be started by river \\0.4 or newer: \\ \\ river -c att_wm \\ \\Options: \\ -h, --help Show this help \\ -v, --version Show the version \\ ; pub fn main(init: std.process.Init) !u8 { const gpa = init.gpa; var args = init.minimal.args.iterate(); _ = args.next(); while (args.next()) |arg| { if (std.mem.eql(u8, arg, "-h") or std.mem.eql(u8, arg, "--help")) { sys.writeAllBestEffort(1, usage); return 0; } if (std.mem.eql(u8, arg, "-v") or std.mem.eql(u8, arg, "--version")) { sys.writeAllBestEffort(1, version ++ "\n"); return 0; } std.log.err("unknown argument: {s}", .{arg}); sys.writeAllBestEffort(2, usage); return 1; } // Spawned children are double-forked and reparented to init, so we never // wait on them. Ignoring SIGPIPE keeps a bar disconnecting mid-write from // taking the window manager down with it. const ignore: posix.Sigaction = .{ .handler = .{ .handler = posix.SIG.IGN }, .mask = posix.sigemptyset(), .flags = 0, }; posix.sigaction(posix.SIG.PIPE, &ignore, null); const wm = Wm.init(gpa, init.minimal.environ) catch |err| switch (err) { error.NoWindowManagerGlobal => return 1, else => { std.log.err("failed to start: {s}", .{@errorName(err)}); return 1; }, }; defer wm.deinit(); wm.run() catch |err| { std.log.err("event loop failed: {s}", .{@errorName(err)}); return 1; }; return 0; }