mirror of
https://mzte.de/git/LordMZTE/dotfiles.git
synced 2024-12-14 07:23:49 +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/randomwallpaper && zig build -Drelease-fast -p {{target}}
|
||||||
cd scripts/vinput && 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/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/prompt && gyro build -Drelease-fast -p {{target}}
|
||||||
cd scripts/mzteinit && 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