diff --git a/.config/hypr/prog-keybinds.conf.cgt b/.config/hypr/prog-keybinds.conf.cgt index faa58e7..2eb0338 100644 --- a/.config/hypr/prog-keybinds.conf.cgt +++ b/.config/hypr/prog-keybinds.conf.cgt @@ -6,5 +6,4 @@ bind = SUPER CTRL, B, exec, <% opt.commands.browser %> bind = SUPER SHIFT, P, exec, gpower2 bind = ,PRINT, exec, grim -g "$(slurp; sleep 1)" ~/Downloads/screenshot.png bind = SHIFT, PRINT, exec, grim -g "$(slurp; sleep 1)" - | feh - -bind = SUPER SHIFT, W, exec, randomwallpaper bind = SUPER CTRL, V, exec, vinput md diff --git a/.config/river/init.cgt b/.config/river/init.cgt deleted file mode 100755 index 4ed28ab..0000000 --- a/.config/river/init.cgt +++ /dev/null @@ -1,182 +0,0 @@ -#!/bin/sh - -# This is the example configuration file for river. -# -# If you wish to edit this, you will probably want to copy it to -# $XDG_CONFIG_HOME/river/init or $HOME/.config/river/init first. -# -# See the river(1), riverctl(1), and rivertile(1) man pages for complete -# documentation. - -# Note: the "Super" modifier is also known as Logo, GUI, Windows, Mod4, etc. - -# Super+Return to start a terminal -riverctl map normal Super+Shift Return spawn <% opt.term.command %> - -# Super+Q to close the focused view -riverctl map normal Super Q close - -# Super+Shift+E to exit river -riverctl map normal Super+Shift E exit - -# Super+J and Super+K to focus the next/previous view in the layout stack -riverctl map normal Super J focus-view next -riverctl map normal Super K focus-view previous - -# Super+Shift+J and Super+Shift+K to swap the focused view with the next/previous -# view in the layout stack -riverctl map normal Super+Shift J swap next -riverctl map normal Super+Shift K swap previous - -# Super+Period and Super+Comma to focus the next/previous output -riverctl map normal Super Period focus-output next -riverctl map normal Super Comma focus-output previous - -# Super+Shift+{Period,Comma} to send the focused view to the next/previous output -riverctl map normal Super+Shift Period send-to-output next -riverctl map normal Super+Shift Comma send-to-output previous - -# Super+Return to bump the focused view to the top of the layout stack -riverctl map normal Super Return zoom - -# Super+H and Super+L to decrease/increase the main ratio of rivertile(1) -riverctl map normal Super H send-layout-cmd rivertile "main-ratio -0.05" -riverctl map normal Super L send-layout-cmd rivertile "main-ratio +0.05" - -# Super+Shift+H and Super+Shift+L to increment/decrement the main count of rivertile(1) -riverctl map normal Super+Shift H send-layout-cmd rivertile "main-count +1" -riverctl map normal Super+Shift L send-layout-cmd rivertile "main-count -1" - -# Super+Alt+{H,J,K,L} to move views -riverctl map normal Super+Alt H move left 100 -riverctl map normal Super+Alt J move down 100 -riverctl map normal Super+Alt K move up 100 -riverctl map normal Super+Alt L move right 100 - -# Super+Alt+Control+{H,J,K,L} to snap views to screen edges -riverctl map normal Super+Alt+Control H snap left -riverctl map normal Super+Alt+Control J snap down -riverctl map normal Super+Alt+Control K snap up -riverctl map normal Super+Alt+Control L snap right - -# Super+Alt+Shif+{H,J,K,L} to resize views -riverctl map normal Super+Alt+Shift H resize horizontal -100 -riverctl map normal Super+Alt+Shift J resize vertical 100 -riverctl map normal Super+Alt+Shift K resize vertical -100 -riverctl map normal Super+Alt+Shift L resize horizontal 100 - -# Super + Left Mouse Button to move views -riverctl map-pointer normal Super BTN_LEFT move-view - -# Super + Right Mouse Button to resize views -riverctl map-pointer normal Super BTN_RIGHT resize-view - -for i in $(seq 1 9) -do - tags=$((1 << ($i - 1))) - - # Super+[1-9] to focus tag [0-8] - riverctl map normal Super $i set-focused-tags $tags - - # Super+Shift+[1-9] to tag focused view with tag [0-8] - riverctl map normal Super+Shift $i set-view-tags $tags - - # Super+Ctrl+[1-9] to toggle focus of tag [0-8] - riverctl map normal Super+Control $i toggle-focused-tags $tags - - # Super+Shift+Ctrl+[1-9] to toggle tag [0-8] of focused view - riverctl map normal Super+Shift+Control $i toggle-view-tags $tags -done - -# Super+0 to focus all tags -# Super+Shift+0 to tag focused view with all tags -all_tags=$(((1 << 32) - 1)) -riverctl map normal Super 0 set-focused-tags $all_tags -riverctl map normal Super+Shift 0 set-view-tags $all_tags - -# Super+Space to toggle float -riverctl map normal Super Space toggle-float - -# Super+F to toggle fullscreen -riverctl map normal Super F toggle-fullscreen - -# Super+{Up,Right,Down,Left} to change layout orientation -riverctl map normal Super Up send-layout-cmd rivertile "main-location top" -riverctl map normal Super Right send-layout-cmd rivertile "main-location right" -riverctl map normal Super Down send-layout-cmd rivertile "main-location bottom" -riverctl map normal Super Left send-layout-cmd rivertile "main-location left" - -# Declare a passthrough mode. This mode has only a single mapping to return to -# normal mode. This makes it useful for testing a nested wayland compositor -riverctl declare-mode passthrough - -# Super+F11 to enter passthrough mode -riverctl map normal Super F11 enter-mode passthrough - -# Super+F11 to return to normal mode -riverctl map passthrough Super F11 enter-mode normal - -# Various media key mapping examples for both normal and locked mode which do -# not have a modifier -for mode in normal locked -do - # Eject the optical drive (well if you still have one that is) - riverctl map $mode None XF86Eject spawn 'eject -T' - - # Control pulse audio volume with pamixer (https://github.com/cdemoulins/pamixer) - riverctl map $mode None XF86AudioRaiseVolume spawn 'pamixer -i 5' - riverctl map $mode None XF86AudioLowerVolume spawn 'pamixer -d 5' - riverctl map $mode None XF86AudioMute spawn 'pamixer --toggle-mute' - - # Control MPRIS aware media players with playerctl (https://github.com/altdesktop/playerctl) - riverctl map $mode None XF86AudioMedia spawn 'playerctl play-pause' - riverctl map $mode None XF86AudioPlay spawn 'playerctl play-pause' - riverctl map $mode None XF86AudioPrev spawn 'playerctl previous' - riverctl map $mode None XF86AudioNext spawn 'playerctl next' - - # Control screen backlight brighness with light (https://github.com/haikarainen/light) - riverctl map $mode None XF86MonBrightnessUp spawn 'light -A 5' - riverctl map $mode None XF86MonBrightnessDown spawn 'light -U 5' - - # screenshot - riverctl map $mode None Print spawn 'grim -g "$(slurp -o)" - | wl-copy' -done - -# Set background and border color -riverctl background-color 0x002b36 -riverctl border-color-focused 0x93a1a1 -riverctl border-color-unfocused 0x586e75 - -# Set keyboard repeat rate -riverctl set-repeat 50 300 - -# Make certain views start floating -riverctl float-filter-add app-id float -riverctl float-filter-add title "popup title with spaces" - -# Set app-ids and titles of views which should use client side decorations -riverctl csd-filter-add app-id "gedit" - -# Alt+Space to show wofi -riverctl map normal Alt Space spawn 'wofi --show run' - -# cursor theme -riverctl xcursor-theme <% opt.cursor.theme %> - -# power dialog -riverctl map normal Super+Shift P spawn gpower2 - -# screen locker -riverctl map normal Super+Control L spawn 'swaylock --color 600000' - -# Set and exec into the default layout generator, rivertile. -# River will send the process group of the init executable SIGTERM on exit. -riverctl default-layout rivertile - -waybar & - -# needed for some dbus stuff to work -dbus-update-activation-environment DISPLAY XAUTHORITY WAYLAND_DISPLAY -systemctl --user import-environment DISPLAY XAUTHORITY WAYLAND_DISPLAY XDG_CURRENT_DESKTOP - -exec rivertile -view-padding 6 -outer-padding 6 diff --git a/.config/waybar/style.css.cgt b/.config/waybar/style.css.cgt index 7a5d69a..4630f24 100644 --- a/.config/waybar/style.css.cgt +++ b/.config/waybar/style.css.cgt @@ -33,7 +33,7 @@ window#waybar.PCSX2 #window { background: @surface0; } -#workspaces { +#workspaces, #tags { margin-top: 8px; margin-left: 12px; margin-bottom: 0; @@ -41,19 +41,25 @@ window#waybar.PCSX2 #window { transition: none; } -#workspaces button { +#workspaces button, #tags button { transition: none; color: @text; background: @crust; font-size: 16px; + padding: 0; } -#workspaces button.active { - color: @lavender; +#tags button.occupied { + color: @sky; background: @base; } -#workspaces button:hover { +#workspaces button.active, #tags button.focused { + color: @lavender; + background: @surface0; +} + +#workspaces button:hover, #tags button:hover { transition: none; box-shadow: inherit; text-shadow: inherit; diff --git a/cg_opts.lua b/cg_opts.lua index 8de7307..3485357 100644 --- a/cg_opts.lua +++ b/cg_opts.lua @@ -1,7 +1,7 @@ local opts = {} opts.mzteinit_entries = { - { key = "x", label = "startx", cmd = { "startx" } }, + { key = "r", label = "river", cmd = { "mzteriver" } }, { key = "h", label = "hyprland", cmd = { "Hyprland" } }, { key = "s", label = "shell", cmd = { "fish" } }, { key = "l", label = "logout", cmd = { "!quit" } }, diff --git a/scripts/alecor/src/main.zig b/scripts/alecor/src/main.zig index b797ed5..8af58eb 100644 --- a/scripts/alecor/src/main.zig +++ b/scripts/alecor/src/main.zig @@ -39,7 +39,7 @@ pub fn main() !void { null, (try cache_file.stat()).size, std.os.PROT.READ, - std.os.MAP.PRIVATE, + .{ .TYPE = .PRIVATE }, cache_file.handle, 0, ); diff --git a/scripts/mzteriver/.gitignore b/scripts/mzteriver/.gitignore new file mode 100644 index 0000000..e73c965 --- /dev/null +++ b/scripts/mzteriver/.gitignore @@ -0,0 +1,2 @@ +zig-cache/ +zig-out/ diff --git a/scripts/mzteriver/build.zig b/scripts/mzteriver/build.zig new file mode 100644 index 0000000..bf4bee9 --- /dev/null +++ b/scripts/mzteriver/build.zig @@ -0,0 +1,62 @@ +const std = @import("std"); +const common = @import("build_common.zig"); + +const Scanner = @import("wayland").Scanner; + +pub fn build(b: *std.Build) !void { + const target = b.standardTargetOptions(.{}); + const optimize = b.standardOptimizeOption(.{}); + + const cg_opt = try common.confgenGet(struct { + nvidia: bool = false, + term: struct { command: [:0]const u8 }, + commands: struct { + file_manager: [:0]const u8, + browser: [:0]const u8, + }, + cursor: struct { + theme: [:0]const u8, + size: u32, + } + }, "../..", b.allocator); + + const opts = b.addOptions(); + opts.addOption(bool, "nvidia", cg_opt.nvidia); + opts.addOption([:0]const u8, "term_command", cg_opt.term.command); + opts.addOption([:0]const u8, "file_manager_command", cg_opt.commands.file_manager); + opts.addOption([:0]const u8, "browser_command", cg_opt.commands.browser); + opts.addOption([:0]const u8, "cursor_theme", cg_opt.cursor.theme); + opts.addOption(u32, "cursor_size", cg_opt.cursor.size); + + const scanner = Scanner.create(b, .{}); + + const exe = b.addExecutable(.{ + .name = "mzteriver", + .root_source_file = .{ .path = "src/main.zig" }, + .target = target, + .optimize = optimize, + }); + + exe.root_module.addImport("opts", opts.createModule()); + exe.root_module.addImport("wayland", scanner.mod); + + scanner.addCustomProtocol("river-control-unstable-v1.xml"); + + scanner.generate("zriver_control_v1", 1); + scanner.generate("wl_seat", 7); + + exe.root_module.linkSystemLibrary("wayland-client", .{}); + + 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); +} diff --git a/scripts/mzteriver/build.zig.zon b/scripts/mzteriver/build.zig.zon new file mode 100644 index 0000000..2a01606 --- /dev/null +++ b/scripts/mzteriver/build.zig.zon @@ -0,0 +1,13 @@ +.{ + .name = "mzteriver", + .version = "0.0.0", + + .dependencies = .{ + .wayland = .{ + .url = "git+https://git.mzte.de/LordMZTE/zig-wayland#4de9f2d6d5fddae1fbb29e21fd1dae69e646ab7d", + .hash = "1220d6448c277e5c41348aa95ce2ba2fc92a92cb7a9e9783edf0f816cd0260122d31", + }, + }, + + .paths = .{""}, +} diff --git a/scripts/mzteriver/build_common.zig b/scripts/mzteriver/build_common.zig new file mode 120000 index 0000000..821d564 --- /dev/null +++ b/scripts/mzteriver/build_common.zig @@ -0,0 +1 @@ +../../build_common.zig \ No newline at end of file diff --git a/scripts/mzteriver/river-control-unstable-v1.xml b/scripts/mzteriver/river-control-unstable-v1.xml new file mode 100644 index 0000000..aa5fc4d --- /dev/null +++ b/scripts/mzteriver/river-control-unstable-v1.xml @@ -0,0 +1,85 @@ + + + + Copyright 2020 The River Developers + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + + + + This interface allows clients to run compositor commands and receive a + success/failure response with output or a failure message respectively. + + Each command is built up in a series of add_argument requests and + executed with a run_command request. The first argument is the command + to be run. + + A complete list of commands should be made available in the man page of + the compositor. + + + + + This request indicates that the client will not use the + river_control object any more. Objects that have been created + through this instance are not affected. + + + + + + Arguments are stored by the server in the order they were sent until + the run_command request is made. + + + + + + + Execute the command built up using the add_argument request for the + given seat. + + + + + + + + + This object is created by the run_command request. Exactly one of the + success or failure events will be sent. This object will be destroyed + by the compositor after one of the events is sent. + + + + + Sent when the command has been successfully received and executed by + the compositor. Some commands may produce output, in which case the + output argument will be a non-empty string. + + + + + + + Sent when the command could not be carried out. This could be due to + sending a non-existent command, no command, not enough arguments, too + many arguments, invalid arguments, etc. + + + + + diff --git a/scripts/mzteriver/src/Connection.zig b/scripts/mzteriver/src/Connection.zig new file mode 100644 index 0000000..1fa9f79 --- /dev/null +++ b/scripts/mzteriver/src/Connection.zig @@ -0,0 +1,96 @@ +const std = @import("std"); +const wayland = @import("wayland"); + +const wl = wayland.client.wl; +const zriver = wayland.client.zriver; + +dpy: *wl.Display, +seat: ?*wl.Seat, +ctl: ?*zriver.ControlV1, + +const Connection = @This(); + +pub fn init() !Connection { + const dpy = try wl.Display.connect(null); + errdefer dpy.disconnect(); + + const reg = try dpy.getRegistry(); + defer reg.destroy(); + + var self = Connection{ + .dpy = dpy, + .seat = null, + .ctl = null, + }; + + reg.setListener(*Connection, registryListener, &self); + + if (dpy.roundtrip() != .SUCCESS) return error.RoundtripFailed; + if (self.seat == null or self.ctl == null) return error.MissingGlobals; + + std.log.info("successfully initialized wayland connection", .{}); + + return self; +} + +pub fn deinit(self: Connection) void { + self.seat.?.destroy(); + self.ctl.?.destroy(); + self.dpy.disconnect(); +} + +pub fn runCommand(self: Connection, args: []const [:0]const u8) !void { + std.log.debug("running command: {s}", .{args}); + for (args) |arg| self.ctl.?.addArgument(arg.ptr); + + var success: ?bool = null; + const cb = try self.ctl.?.runCommand(self.seat.?); + cb.setListener(*?bool, cmdCallbackListener, &success); + + while (success == null) { + if (self.dpy.dispatch() != .SUCCESS) return error.RoundtripFailed; + } + + if (!success.?) return error.CommandFailed; +} + +fn cmdCallbackListener( + _: *zriver.CommandCallbackV1, + ev: zriver.CommandCallbackV1.Event, + success: *?bool, +) void { + switch (ev) { + .success => |suc| { + success.* = true; + const output = std.mem.span(suc.output); + + if (output.len != 0) + std.log.info("cmd output: {s}", .{output}); + }, + .failure => |fail| { + success.* = false; + std.log.err("cmd fail: {s}", .{fail.failure_message}); + }, + } +} + +fn registryListener(reg: *wl.Registry, ev: wl.Registry.Event, self: *Connection) void { + switch (ev) { + .global => |glob| { + if (std.mem.orderZ(u8, glob.interface, wl.Seat.getInterface().name) == .eq) { + self.seat = reg.bind( + glob.name, + wl.Seat, + wl.Seat.generated_version, + ) catch @panic("OOM"); + } else if (std.mem.orderZ(u8, glob.interface, zriver.ControlV1.getInterface().name) == .eq) { + self.ctl = reg.bind( + glob.name, + zriver.ControlV1, + zriver.ControlV1.generated_version, + ) catch @panic("OOM"); + } + }, + .global_remove => {}, + } +} diff --git a/scripts/mzteriver/src/init.zig b/scripts/mzteriver/src/init.zig new file mode 100644 index 0000000..e649c48 --- /dev/null +++ b/scripts/mzteriver/src/init.zig @@ -0,0 +1,190 @@ +const std = @import("std"); +const opts = @import("opts"); + +const Connection = @import("Connection.zig"); + +pub fn init(alloc: std.mem.Allocator) !void { + const con = try Connection.init(); + defer con.deinit(); + + // Normal-Mode keyboard mappings + inline for (.{ + // "run command" maps + .{ "Super", "Return", "spawn", opts.term_command }, + .{ "Super+Control", "E", "spawn", opts.file_manager_command }, + .{ "Super+Control", "B", "spawn", opts.browser_command }, + .{ "Super+Control", "V", "spawn", "vinput md" }, + .{ "Super+Control", "L", "spawn", "swaylock --color 660000" }, + .{ "Super+Shift", "P", "spawn", "gpower2" }, + .{ "Alt", "Space", "spawn", "rofi -show combi" }, + .{ "Super+Alt", "Space", "spawn", "rofi -show emoji" }, + .{ "None", "Print", "spawn", "grim -g \"$(slurp; sleep 1)\" ~/Downloads/screenshot.png" }, + .{ "Shift", "Print", "spawn", "grim -g \"$(slurp; sleep 1)\" - | feh -" }, + + // media keys + .{ "None", "XF86Eject", "spawn", "eject -T" }, + .{ "None", "XF86AudioRaiseVolume", "spawn", "pactl set-sink-volume @DEFAULT_SINK@ +5%" }, + .{ "None", "XF86AudioLowerVolume", "spawn", "pactl set-sink-volume @DEFAULT_SINK@ -5%" }, + .{ "None", "XF86AudioMute", "spawn", "pactl set-sink-mute @DEFAULT_SINK@ toggle" }, + .{ "None", "XF86AudioMicMute", "spawn", "pactl set-source-mute @DEFAULT_SINK@ toggle" }, + .{ "None", "XF86AudioMedia", "spawn", "playerctl play-pause" }, + .{ "None", "XF86AudioPlay", "spawn", "playerctl play-pause" }, + .{ "None", "XF86AudioPrev", "spawn", "playerctl previous" }, + .{ "None", "XF86AudioNext", "spawn", "playerctl next" }, + + // control maps + .{ "Super+Shift", "E", "exit" }, + .{ "Super", "Space", "toggle-float" }, + .{ "Super", "F", "toggle-fullscreen" }, + .{ "Super+Shift", "Q", "close" }, + + // screenshot + + // "irregular" focus & move maps + // (that is, they don't exist for all 4 directions) + .{ "Super", "J", "focus-view", "next" }, + .{ "Super", "K", "focus-view", "previous" }, + .{ "Super+Shift", "J", "swap", "next" }, + .{ "Super+Shift", "K", "swap", "previous" }, + .{ "Super", "Period", "focus-output", "next" }, + .{ "Super", "Comma", "focus-output", "previous" }, + .{ "Super+Shift", "Period", "send-to-output", "next" }, + .{ "Super+Shift", "Comma", "send-to-output", "previous" }, + .{ "Super+Shift", "Return", "zoom" }, + .{ "Super", "H", "send-layout-cmd", "rivertile", "main-ratio -0.05" }, + .{ "Super", "L", "send-layout-cmd", "rivertile", "main-ratio +0.05" }, + .{ "Super+Shift", "H", "send-layout-cmd", "rivertile", "main-count -1" }, + .{ "Super+Shift", "L", "send-layout-cmd", "rivertile", "main-count +1" }, + }) |map_cmd| { + try con.runCommand(&(.{ "map", "normal" } ++ map_cmd)); + } + + inline for (.{ + .{ .H, "left" }, + .{ .J, "down" }, + .{ .K, "up" }, + .{ .L, "right" }, + }) |kd| { + const key = kd.@"0"; + const dir = kd.@"1"; + + // moving floating views + try con.runCommand(&.{ "map", "normal", "Super+Alt", @tagName(key), "move", dir, "100" }); + + // snapping floating views + try con.runCommand(&.{ "map", "normal", "Super+Alt+Control", @tagName(key), "snap", dir }); + + // resizing floating views + try con.runCommand(&.{ "map", "normal", "Super+Alt+Shift", @tagName(key), switch (key) { + .H, .L => "horizontal", + .J, .K => "vertical", + else => unreachable, + }, switch (key) { + .J, .L => "100", + .H, .K => "-100", + else => unreachable, + } }); + } + + // change layout orientation with arrow keys + inline for (.{ + .{ "Up", "top" }, + .{ "Right", "right" }, + .{ "Down", "bottom" }, + .{ "Left", "left" }, + }) |kv| { + try con.runCommand(&.{ + "map", + "normal", + "Super", + kv.@"0", + "send-layout-cmd", + "rivertile", + std.fmt.comptimePrint("main-location {s}", .{kv.@"1"}), + }); + } + + // moving & resizing with the mouse + try con.runCommand(&.{ "map-pointer", "normal", "Super", "BTN_LEFT", "move-view" }); + try con.runCommand(&.{ "map-pointer", "normal", "Super", "BTN_RIGHT", "resize-view" }); + + // tag config + for (0..9) |i| { + var key_buf: [16]u8 = undefined; + var tags_buf: [16]u8 = undefined; + const key = try std.fmt.bufPrintZ(&key_buf, "{}", .{i + 1}); + const tags = try std.fmt.bufPrintZ(&tags_buf, "{}", .{@as(u32, 1) << @intCast(i)}); + + try con.runCommand(&.{ "map", "normal", "Super", key, "set-focused-tags", tags }); + try con.runCommand(&.{ "map", "normal", "Super+Shift", key, "set-view-tags", tags }); + try con.runCommand(&.{ "map", "normal", "Super+Control", key, "toggle-focused-tags", tags }); + try con.runCommand(&.{ "map", "normal", "Super+Shift+Control", key, "toggle-view-tags", tags }); + } + + // "0" acts as "all tags" + const all_tags_s = std.fmt.comptimePrint("{}", .{std.math.maxInt(u32)}); + try con.runCommand(&.{ "map", "normal", "Super", "0", "set-focused-tags", all_tags_s }); + try con.runCommand(&.{ "map", "normal", "Super+Shift", "0", "set-view-tags", all_tags_s }); + + // passthrough mode + const passthr_mode = "passthrough"; + try con.runCommand(&.{ "declare-mode", passthr_mode }); + try con.runCommand(&.{ "map", "normal", "Super", "F12", "enter-mode", passthr_mode }); + try con.runCommand(&.{ "map", passthr_mode, "Super", "F12", "enter-mode", "normal" }); + + try con.runCommand(&.{ "set-repeat", "50", "300" }); + + try con.runCommand(&.{ "border-color-focused", "0x880000" }); + try con.runCommand(&.{ "border-color-unfocused", "0x660000" }); + + try con.runCommand(&.{ + "xcursor-theme", + opts.cursor_theme, + std.fmt.comptimePrint("{}", .{opts.cursor_size}), + }); + + try con.runCommand(&.{ "float-filter-add", "app-id", "vinput-editor" }); + + try con.runCommand(&.{ "default-layout", "rivertile" }); + + const home = std.os.getenv("HOME") orelse return error.HomeNotSet; + const init_path = try std.fs.path.join( + alloc, + &.{ home, ".config", "mzte_localconf", "river_init" }, + ); + defer alloc.free(init_path); + + var init_child = std.process.Child.init(&.{init_path}, alloc); + const term = init_child.spawnAndWait() catch |e| switch (e) { + error.FileNotFound => b: { + std.log.info("no river_init", .{}); + break :b std.process.Child.Term{ .Exited = 0 }; + }, + else => return e, + }; + + if (!std.meta.eql(term, .{ .Exited = 0 })) { + std.log.err("river_init borked: {}", .{term}); + return error.InitBorked; + } + + std.log.info("configuration finished, spawning processes", .{}); + + var child_arena = std.heap.ArenaAllocator.init(alloc); + defer child_arena.deinit(); + + // spawn background processes + inline for (.{ + .{"wlbg"}, + .{"waybar"}, + .{ "dbus-update-activation-environment", "DISPLAY", "XAUTHORITY", "WAYLAND_DISPLAY" }, + .{ "systemctl", "--user", "import-environment", "DISPLAY", "XAUTHORITY", "WAYLAND_DISPLAY", "XDG_CURRENT_DESKTOP" }, + .{ "rivertile", "-view-padding", "6", "-outer-padding", "6" }, + }) |argv| { + // TODO: wonk + // We use an arena here to prevent leaks because process.Child apparently doesn't support + // detaching. + var child = std.process.Child.init(&argv, child_arena.allocator()); + try child.spawn(); + } +} diff --git a/scripts/mzteriver/src/main.zig b/scripts/mzteriver/src/main.zig new file mode 100644 index 0000000..d4577f0 --- /dev/null +++ b/scripts/mzteriver/src/main.zig @@ -0,0 +1,46 @@ +const std = @import("std"); +const opts = @import("opts"); + +pub const std_options = struct { + pub const log_level = switch (@import("builtin").mode) { + .Debug => .debug, + else => .info, + }; +}; + +pub fn main() !void { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + defer _ = gpa.deinit(); + const alloc = gpa.allocator(); + + if (std.mem.endsWith(u8, std.mem.span(std.os.argv[0]), "init") or + (std.os.argv.len >= 2 and std.mem.orderZ(u8, std.os.argv[1], "init") == .eq)) + { + std.log.info("running in init mode", .{}); + try @import("init.zig").init(alloc); + } else { + std.log.info("running in launch mode", .{}); + + const envp = env: { + var env = try std.ArrayList(?[*:0]const u8) + .initCapacity(alloc, std.os.environ.len + 16); + errdefer env.deinit(); + try env.appendSlice(std.os.environ); + + try env.append("XKB_DEFAULT_LAYOUT=de"); + try env.append("QT_QPA_PLATFORM=wayland"); + try env.append("XDG_CURRENT_DESKTOP=river"); + + if (opts.nvidia) { + try env.append("WLR_NO_HARDWARE_CURSORS=1"); + } + + break :env try env.toOwnedSliceSentinel(null); + }; + + // techncially unreachable + defer alloc.free(envp); + + return std.os.execvpeZ("river", &[_:null]?[*:0]const u8{"river"}, envp); + } +} diff --git a/scripts/playtwitch/src/launch.zig b/scripts/playtwitch/src/launch.zig index 9126a0c..d23f44a 100644 --- a/scripts/playtwitch/src/launch.zig +++ b/scripts/playtwitch/src/launch.zig @@ -96,7 +96,7 @@ fn streamlinkThread(state: *State, channel: []const u8) !void { null, size, std.os.PROT.READ, - std.os.MAP.PRIVATE, + .{ .TYPE = .PRIVATE }, memfd, 0, ); diff --git a/scripts/startriver.sh b/scripts/startriver.sh deleted file mode 100755 index eedfc11..0000000 --- a/scripts/startriver.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -# keyboard config -export XKB_DEFAULT_OPTIONS="caps:swapescape" -export XKB_DEFAULT_LAYOUT="de" - -# other stuff -export QT_QPA_PLATFORM="wayland" - -# this is necessary for tray icons -export XDG_CURRENT_DESKTOP="river" - -exec river diff --git a/scripts/vinput/build.zig b/scripts/vinput/build.zig index 6eaffaa..c716349 100644 --- a/scripts/vinput/build.zig +++ b/scripts/vinput/build.zig @@ -24,7 +24,7 @@ pub fn build(b: *std.Build) void { scanner.generate("wl_data_device_manager", 3); scanner.generate("wl_compositor", 4); scanner.generate("wl_shm", 1); - scanner.generate("xdg_wm_base", 3); + scanner.generate("xdg_wm_base", 2); exe.root_module.linkSystemLibrary("wayland-client", .{}); diff --git a/scripts/vinput/src/main.zig b/scripts/vinput/src/main.zig index 5cef5b6..ee87524 100644 --- a/scripts/vinput/src/main.zig +++ b/scripts/vinput/src/main.zig @@ -86,7 +86,7 @@ pub fn main() !void { null, stat.size, std.os.PROT.READ, - std.os.MAP.PRIVATE, + .{ .TYPE = .PRIVATE }, tempfile.handle, 0, ); diff --git a/setup/commands/install-scripts.rkt b/setup/commands/install-scripts.rkt index e129344..a4eb155 100644 --- a/setup/commands/install-scripts.rkt +++ b/setup/commands/install-scripts.rkt @@ -11,7 +11,6 @@ ;; Symlink interpreted scripts (install-link "scripts/brightness.rkt" (bin-path "brightness")) (install-link "scripts/map-touch-display.rkt" (bin-path "map-touch-display")) - (install-link "scripts/startriver.sh" (bin-path "startriver")) (install-link "scripts/sysupdate.rkt" (bin-path "sysupdate")) (install-link "scripts/update-nvim-plugins.rkt" (bin-path "update-nvim-plugins")) (install-link "scripts/use-country-mirrors.sh" (bin-path "use-country-mirrors")) @@ -22,6 +21,7 @@ (install-zig "scripts/hyprtool") (install-rust "scripts/i3status") (install-zig "scripts/mzteinit") + (install-zig "scripts/mzteriver") (install-zig "scripts/openbrowser") (install-zig "scripts/playtwitch") (install-zig "scripts/prompt")