mirror of
https://mzte.de/git/LordMZTE/dotfiles.git
synced 2024-12-14 05:43:47 +01:00
add openbrowser script
This commit is contained in:
parent
bab46a305a
commit
b64d5befe3
6 changed files with 174 additions and 0 deletions
1
justfile
1
justfile
|
@ -21,6 +21,7 @@ install-scripts target=(`echo $HOME` + "/.local"):
|
|||
cd scripts/randomwallpaper && zig build -Drelease-fast -p {{target}}
|
||||
cd scripts/vinput && zig build -Drelease-fast -p {{target}}
|
||||
cd scripts/playtwitch && zig build -Drelease-fast -p {{target}}
|
||||
cd scripts/openbrowser && zig build -Drelease-fast -p {{target}}
|
||||
cd scripts/prompt && gyro build -Drelease-fast -p {{target}}
|
||||
cd scripts/mzteinit && gyro build -Drelease-fast -p {{target}}
|
||||
|
||||
|
|
5
scripts/openbrowser/.gitignore
vendored
Normal file
5
scripts/openbrowser/.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
zig-cache/
|
||||
zig-out/
|
||||
deps.zig
|
||||
gyro.lock
|
||||
.gyro
|
7
scripts/openbrowser/assets/openbrowser.desktop
Normal file
7
scripts/openbrowser/assets/openbrowser.desktop
Normal file
|
@ -0,0 +1,7 @@
|
|||
[Desktop Entry]
|
||||
Name=Open Browser
|
||||
Comment=Opens the best browser given a link
|
||||
Exec=openbrowser %u
|
||||
Type=Application
|
||||
Categories=Network
|
||||
MimeType=text/html;text/xml;application/xhtml+xml;x-scheme-handler/http;x-scheme-handler/https;
|
40
scripts/openbrowser/build.zig
Normal file
40
scripts/openbrowser/build.zig
Normal file
|
@ -0,0 +1,40 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.build.Builder) void {
|
||||
// Standard target options allows the person running `zig build` to choose
|
||||
// what target to build for. Here we do not override the defaults, which
|
||||
// means any target is allowed, and the default is native. Other options
|
||||
// for restricting supported target set are available.
|
||||
const target = b.standardTargetOptions(.{});
|
||||
|
||||
// Standard release options allow the person running `zig build` to select
|
||||
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
|
||||
const mode = b.standardReleaseOptions();
|
||||
|
||||
const exe = b.addExecutable("openbrowser", "src/main.zig");
|
||||
exe.setTarget(target);
|
||||
exe.setBuildMode(mode);
|
||||
exe.install();
|
||||
|
||||
const desktop_install_step = b.addInstallFile(
|
||||
.{ .path = "assets/openbrowser.desktop" },
|
||||
"share/applications/openbrowser.desktop",
|
||||
);
|
||||
b.getInstallStep().dependOn(&desktop_install_step.step);
|
||||
|
||||
const run_cmd = exe.run();
|
||||
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);
|
||||
|
||||
const exe_tests = b.addTest("src/main.zig");
|
||||
exe_tests.setTarget(target);
|
||||
exe_tests.setBuildMode(mode);
|
||||
|
||||
const test_step = b.step("test", "Run unit tests");
|
||||
test_step.dependOn(&exe_tests.step);
|
||||
}
|
67
scripts/openbrowser/src/ProcessInfo.zig
Normal file
67
scripts/openbrowser/src/ProcessInfo.zig
Normal file
|
@ -0,0 +1,67 @@
|
|||
const std = @import("std");
|
||||
|
||||
running: bool,
|
||||
exepath: ?[]const u8,
|
||||
|
||||
const Self = @This();
|
||||
|
||||
/// Frees the data of this ProcessInfo.
|
||||
/// `alloc` must be the same allocator that was supplied to `get`!
|
||||
pub fn deinit(self: *Self, alloc: std.mem.Allocator) void {
|
||||
if (self.exepath) |exepath|
|
||||
alloc.free(exepath);
|
||||
self.* = undefined;
|
||||
}
|
||||
|
||||
/// Gets information about a process given it's name
|
||||
pub fn get(
|
||||
name: []const u8,
|
||||
alloc: std.mem.Allocator,
|
||||
) !Self {
|
||||
var proc_dir = try std.fs.openIterableDirAbsolute("/proc", .{});
|
||||
defer proc_dir.close();
|
||||
|
||||
var proc_iter = proc_dir.iterate();
|
||||
procs: while (try proc_iter.next()) |proc| {
|
||||
// Filter directories that aren't PIDs
|
||||
for (std.fs.path.basename(proc.name)) |letter|
|
||||
if (!std.ascii.isDigit(letter))
|
||||
continue :procs;
|
||||
|
||||
var buf: [512]u8 = undefined;
|
||||
const cmdline_f = std.fs.openFileAbsolute(
|
||||
try std.fmt.bufPrint(&buf, "/proc/{s}/cmdline", .{proc.name}),
|
||||
.{},
|
||||
) catch |e| {
|
||||
// This just happens when we're dealing with another user's process.
|
||||
if (e == error.AccessDenied)
|
||||
continue;
|
||||
|
||||
return e;
|
||||
};
|
||||
|
||||
defer cmdline_f.close();
|
||||
|
||||
const cmdline_data = try cmdline_f.readToEndAlloc(alloc, std.math.maxInt(usize));
|
||||
defer alloc.free(cmdline_data);
|
||||
|
||||
var cmdline_splits = std.mem.split(u8, cmdline_data, &.{0});
|
||||
const exepath = cmdline_splits.next() orelse return error.InvalidCmdline;
|
||||
|
||||
// this is a startsWith instead of an eql because the arguments in the
|
||||
// cmdline file are sometimes (and only sometimes!) separated by spaces
|
||||
// and not null bytes.
|
||||
if (!std.mem.startsWith(u8, std.fs.path.basename(exepath), name))
|
||||
continue;
|
||||
|
||||
return .{
|
||||
.running = true,
|
||||
.exepath = try alloc.dupe(u8, exepath),
|
||||
};
|
||||
}
|
||||
|
||||
return .{
|
||||
.running = false,
|
||||
.exepath = null,
|
||||
};
|
||||
}
|
54
scripts/openbrowser/src/main.zig
Normal file
54
scripts/openbrowser/src/main.zig
Normal file
|
@ -0,0 +1,54 @@
|
|||
const std = @import("std");
|
||||
const ProcessInfo = @import("ProcessInfo.zig");
|
||||
|
||||
pub const log_level = .debug;
|
||||
|
||||
const browsers = &[_][]const u8{
|
||||
"luakit",
|
||||
"waterfox-g4",
|
||||
"firefox",
|
||||
"chromium",
|
||||
};
|
||||
|
||||
pub fn main() !void {
|
||||
if (std.os.argv.len < 2) {
|
||||
std.log.err("need >=1 argument", .{});
|
||||
return error.WrongArgs;
|
||||
}
|
||||
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
defer _ = gpa.deinit();
|
||||
const alloc = gpa.allocator();
|
||||
|
||||
for (browsers) |browser| {
|
||||
var info = try ProcessInfo.get(browser, alloc);
|
||||
defer info.deinit(alloc);
|
||||
|
||||
if (!info.running)
|
||||
continue;
|
||||
|
||||
std.log.info("found running browser {s}", .{info.exepath.?});
|
||||
|
||||
try start(browser, alloc);
|
||||
return;
|
||||
}
|
||||
|
||||
std.log.info("no running browser, using first choice", .{});
|
||||
try start(browsers[0], alloc);
|
||||
}
|
||||
|
||||
fn start(browser: []const u8, alloc: std.mem.Allocator) !void {
|
||||
// args to browser will be same length as argv
|
||||
const argv = try alloc.alloc([]const u8, std.os.argv.len);
|
||||
defer alloc.free(argv);
|
||||
argv[0] = browser;
|
||||
|
||||
for (std.os.argv[1..]) |arg, i| {
|
||||
argv[i + 1] = std.mem.span(arg);
|
||||
}
|
||||
|
||||
std.log.info("child argv: {s}", .{argv});
|
||||
|
||||
var child = std.ChildProcess.init(argv, alloc);
|
||||
_ = try child.spawnAndWait();
|
||||
}
|
Loading…
Reference in a new issue