implement hyprtool and fullerscreen

This commit is contained in:
LordMZTE 2023-08-31 23:06:31 +02:00
parent 66cc1fdcdd
commit 7be35ac67a
Signed by: LordMZTE
GPG key ID: B64802DC33A64FF6
6 changed files with 155 additions and 0 deletions

View file

@ -15,6 +15,7 @@ bind = SUPER SHIFT, SPACE, togglefloating,
bind = SUPER, P, pseudo, # dwindle
bind = SUPER, R, togglesplit, # dwindle
bind = SUPER, F, fullscreen,
bind = SUPER SHIFT, F, exec, hyprtool fullerscreen
# Move focus with mainMod + arrow keys
bind = SUPER, left, movefocus, l

1
scripts/hyprtool/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/zig-*

View file

@ -0,0 +1,23 @@
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.name = "hyprtool",
.root_source_file = .{ .path = "src/main.zig" },
.target = target,
.optimize = optimize,
});
b.installArtifact(exe);
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
}

View file

@ -0,0 +1,107 @@
const std = @import("std");
const Monitor = struct {
width: u32,
height: u32,
x: u32,
y: u32,
};
const Window = struct {
address: []const u8,
floating: bool,
size: [2]u32,
};
pub fn doFullerscreen(alloc: std.mem.Allocator, sockpath: []const u8) !void {
var json_arena = std.heap.ArenaAllocator.init(alloc);
defer json_arena.deinit();
const parsed = request: {
const stream = try std.net.connectUnixSocket(sockpath);
defer stream.close();
try stream.writeAll("[[BATCH]][-j]/monitors;[-j]/activewindow;");
var json_reader = std.json.reader(json_arena.allocator(), stream.reader());
const json_options = std.json.ParseOptions{
.ignore_unknown_fields = true,
.max_value_len = std.json.default_max_value_len,
.allocate = .alloc_if_needed,
};
const monitors = try std.json.innerParse(
[]Monitor,
json_arena.allocator(),
&json_reader,
json_options,
);
json_reader.scanner.state = .value;
const active_window = try std.json.innerParse(
Window,
json_arena.allocator(),
&json_reader,
json_options,
);
break :request .{ .monitors = monitors, .active_window = active_window };
};
var bottom_right_monitor: ?Monitor = null;
for (parsed.monitors) |mon| {
if (bottom_right_monitor == null or
mon.x > bottom_right_monitor.?.x or
mon.y > bottom_right_monitor.?.y)
bottom_right_monitor = mon;
}
std.debug.assert(bottom_right_monitor != null);
std.log.info("active window address: {s}", .{parsed.active_window.address});
const new_width = bottom_right_monitor.?.x + bottom_right_monitor.?.width;
const new_height = bottom_right_monitor.?.y + bottom_right_monitor.?.height;
std.log.info("new window size: {}x{}", .{ new_width, new_height });
const stream = try std.net.connectUnixSocket(sockpath);
defer stream.close();
var buf_writer = std.io.bufferedWriter(stream.writer());
const writer = buf_writer.writer();
try writer.writeAll("[[BATCH]]");
// window is already fullerscreen
if (parsed.active_window.floating and
parsed.active_window.size[0] == new_width and
parsed.active_window.size[1] == new_height)
{
std.log.info("already fullerscreen, tiling window", .{});
// disable floating
try writer.print("/dispatch togglefloating address:{s};", .{parsed.active_window.address});
} else {
// ensure window is floating
if (!parsed.active_window.floating) {
try writer.print("/dispatch togglefloating address:{s};", .{parsed.active_window.address});
}
// set pos to 0/0
try writer.print(
"/dispatch movewindowpixel exact 0 0,address:{s};",
.{parsed.active_window.address},
);
// resize
try writer.print(
"/dispatch resizewindowpixel exact {} {},address:{s};",
.{ new_width, new_height, parsed.active_window.address },
);
}
try buf_writer.flush();
var fifo = std.fifo.LinearFifo(u8, .{ .Static = 1024 * 4 }).init();
try fifo.pump(stream.reader(), std.io.getStdOut().writer());
}

View file

@ -0,0 +1,22 @@
const std = @import("std");
pub const std_options = struct {
pub const log_level = .debug;
};
pub fn main() !void {
if (std.os.argv.len != 2 or !std.mem.eql(u8, std.mem.span(std.os.argv[1]), "fullerscreen"))
return error.InvalidArgs;
const inst_sig = std.os.getenv("HYPRLAND_INSTANCE_SIGNATURE") orelse
return error.MissingInstanceSignature;
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const alloc = gpa.allocator();
const socket_path = try std.fs.path.join(alloc, &.{ "/tmp", "hypr", inst_sig, ".socket.sock" });
defer alloc.free(socket_path);
try @import("fullerscreen.zig").doFullerscreen(alloc, socket_path);
}

View file

@ -21,6 +21,7 @@
;; Compile scripts
(install-zig "scripts/alecor")
(install-zig "scripts/hyprtool")
(install-rust "scripts/i3status")
(install-zig "scripts/mzteinit")
(install-zig "scripts/openbrowser")