aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hosts/mercury/hjem.nix1
-rw-r--r--modules/desktop/hjem/wm/default.nix148
-rw-r--r--modules/desktop/hjem/wm/sway.nix14
-rw-r--r--pkgs/util/default.nix44
-rw-r--r--pkgs/util/util.lua35
-rw-r--r--pkgs/util/util/brightness.lua40
-rw-r--r--pkgs/util/util/music.lua124
-rw-r--r--pkgs/util/util/volume.lua47
8 files changed, 301 insertions, 152 deletions
diff --git a/hosts/mercury/hjem.nix b/hosts/mercury/hjem.nix
index cc6034d..a9d6d08 100644
--- a/hosts/mercury/hjem.nix
+++ b/hosts/mercury/hjem.nix
@@ -24,6 +24,7 @@
inputs.glide-browser.packages."x86_64-linux".default
(pkgs.callPackage ../../pkgs/yoshi.nix {inherit inputs;})
+ (pkgs.callPackage ../../pkgs/yo.nix {inherit inputs;})
];
files.".config/captive-browser.toml".text = ''
diff --git a/modules/desktop/hjem/wm/default.nix b/modules/desktop/hjem/wm/default.nix
index a5575ad..6b8aeed 100644
--- a/modules/desktop/hjem/wm/default.nix
+++ b/modules/desktop/hjem/wm/default.nix
@@ -1,147 +1,5 @@
{pkgs, ...}: {
- files.".config/util.lua" = {
- text = let
- lua = pkgs.lua.withPackages (p: [p.lua-subprocess]);
- in
- # lua
- ''
- #!${lua}/bin/lua
- local subprocess = require("subprocess")
-
- local function get_volume()
- local proc, err = subprocess.popen({
- "wpctl", "get-volume", "@DEFAULT_AUDIO_SINK@",
- stdout = subprocess.PIPE,
- stderr = subprocess.PIPE
- })
- if not proc then
- error("Failed to run wpctl get-volume: " .. tostring(err))
- end
-
- local out = proc.stdout:read("*a") or ""
- local _, _, code = proc:wait()
- if (code or 0) ~= 0 then
- local errout = proc.stderr and proc.stderr:read("*a") or ""
- error(("wpctl get-volume failed (code %d): %s"):format(code, errout))
- end
-
- local num = out:match("^Volume:%s*([%d%.]+)")
- if not num then
- error("Unexpected wpctl output: " .. out)
- end
-
- return tonumber(num) * 100
- end
-
- local function notify_volume()
- local ok, reason, code = subprocess.call({
- "dunstify", "-t", "300",
- "-h", "string:x-canonical-private-synchronous:audio",
- "Volume:", "-h", "int:value:"..get_volume()
- })
- if not ok then
- io.stderr:write(("dunstify failed (%s, code %s)\n"):format(reason or "?", code or "?"))
- end
- end
-
- local function set_volume(vol)
- local ok, reason, code = subprocess.call({
- "wpctl", "set-volume", "@DEFAULT_AUDIO_SINK@", vol
- })
- if not ok then
- io.stderr:write(("wpctl set-volume failed (%s, code %s)\n"):format(reason or "?", code or "?"))
- end
- end
-
- local function get_brightness()
- local proc = subprocess.popen({
- "${pkgs.brightnessctl}/bin/brightnessctl", "-e", "get",
- stdout = subprocess.PIPE
- })
- if not proc then error("Failed to run brightnessctl get") end
- local cur = tonumber(proc.stdout:read("*a"))
- proc:wait()
- if not cur then error("Failed to parse brightnessctl get output") end
-
- local proc2 = subprocess.popen({
- "${pkgs.brightnessctl}/bin/brightnessctl", "-e", "max",
- stdout = subprocess.PIPE
- })
- if not proc2 then error("Failed to run brightnessctl max") end
- local max = tonumber(proc2.stdout:read("*a"))
- proc2:wait()
- if not max or max == 0 then error("Failed to parse brightnessctl max output") end
-
- return (cur / max) * 100
- end
-
- local function notify_brightness()
- local ok, reason, code = subprocess.call({
- "dunstify", "-t", "300",
- "-h", "string:x-canonical-private-synchronous:brightness",
- "Brightness", "-h", "int:value:"..get_brightness()
- })
- if not ok then
- io.stderr:write(("dunstify failed (%s, code %s)\n"):format(reason or "?", code or "?"))
- end
- end
-
- local function set_brightness(brightness)
- local ok, reason, code = subprocess.call({
- "${pkgs.brightnessctl}/bin/brightnessctl", "-e", "set", brightness
- })
- if not ok then
- io.stderr:write(("brightnessctl set failed (%s, code %s)\n"):format(reason or "?", code or "?"))
- end
- end
-
- local function list_music_players()
- local proc = subprocess.popen({
- "${pkgs.playerctl}/bin/playerctl", "-l",
- stdout = subprocess.PIPE
- })
- if not proc then error("Failed to run playerctl -l") end
-
- local cur = proc.stdout:lines()
-
- local out = {}
- for i in cur do
- table.insert(out, i)
- end
-
- return out
- end
-
- local function toggle_music()
- local ok, reason, code = subprocess.call({
- "${pkgs.playerctl}/bin/playerctl", "play-pause",
- })
- if not ok then
- io.stderr:write(("playerctl play-pause failed (%s, code %s)\n"):format(reason or "?", code or "?"))
- end
- end
-
- -- main logic
- if arg[2] and arg[2]:match("^(%d+)%%([%+%-])$") then
- if arg[1] == "vol" then
- set_volume(arg[2])
- notify_volume()
- elseif arg[1] == "brightness" then
- set_brightness(arg[2])
- notify_brightness()
- else
- error(("arg[2] '%s' incorrect format. Should look like 5%%+ or 10%%-"):format(tostring(arg[2])))
- end
- elseif arg[1] and arg[1] == "music" then
- if arg[2] == "play" then
- toggle_music()
- else
- error(("Invalid arg[2]: '%s'. should be `play`"):format(arg[3]))
- end
- else
- error("Unknown command: " .. tostring(arg[1]))
- end
- '';
- executable = true;
- };
+ packages = [
+ (pkgs.callPackage ../../../../pkgs/util {}) # util.lua
+ ];
}
diff --git a/modules/desktop/hjem/wm/sway.nix b/modules/desktop/hjem/wm/sway.nix
index f3a544f..4cecdea 100644
--- a/modules/desktop/hjem/wm/sway.nix
+++ b/modules/desktop/hjem/wm/sway.nix
@@ -82,15 +82,15 @@
bindsym Mod4+Shift+s exec '${pkgs.grim}/bin/grim -g "$(${pkgs.slurp}/bin/slurp)" ~/Pictures/$(date +"%s_grim.png")'
bindsym Mod4+Alt+s exec '${pkgs.hyprpicker}/bin/hyprpicker'
- bindsym XF86AudioRaiseVolume exec 'wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+; dunstify -t 300 -h string:x-canonical-private-synchronous:audio "Volume: " -h "int:value:$(dec=$(wpctl get-volume @DEFAULT_AUDIO_SINK@ | cut -d\" \" -f2);echo "$dec * 100" | ${pkgs.bc}/bin/bc)"'
- bindsym XF86AudioLowerVolume exec 'wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-; dunstify -t 300 -h string:x-canonical-private-synchronous:audio "Volume: " -h "int:value:$(dec=$(wpctl get-volume @DEFAULT_AUDIO_SINK@ | cut -d\" \" -f2);echo "$dec * 100" | ${pkgs.bc}/bin/bc)"'
+ bindsym XF86AudioRaiseVolume exec 'util.lua volume up'
+ bindsym XF86AudioLowerVolume exec 'util.lua volume down'
- bindsym XF86MonBrightnessUp exec 'brightnessctl set 5%+; dunstify -t 300 -h string:x-canonical-private-synchronous:brightness "Brightness: " -h "int:value:$(g=$(brightnessctl get);m=$(brightnessctl max);echo $((g * 100 / m)))"'
- bindsym XF86MonBrightnessDown exec 'brightnessctl set 5%-; dunstify -t 300 -h string:x-canonical-private-synchronous:brightness "Brightness: " -h "int:value:$(g=$(brightnessctl get);m=$(brightnessctl max);echo $((g * 100 / m)))"'
+ bindsym XF86MonBrightnessUp exec 'util.lua brightness up'
+ bindsym XF86MonBrightnessDown exec 'util.lua brightness down'
- bindsym Home exec 'playerctl previous'
- bindsym End exec 'playerctl play-pause'
- bindsym Insert exec 'playerctl next'
+ bindsym Home exec 'util.lua music prev'
+ bindsym End exec 'util.lua music toggle'
+ bindsym Insert exec 'util.lua music next'
default_border pixel 2
smart_borders on
diff --git a/pkgs/util/default.nix b/pkgs/util/default.nix
new file mode 100644
index 0000000..9dbe067
--- /dev/null
+++ b/pkgs/util/default.nix
@@ -0,0 +1,44 @@
+{pkgs ? import <nixpkgs> {system = "x86_64-linux";}, ...}: let
+ lsdbus-src = pkgs.fetchFromGitHub {
+ owner = "kmarkus";
+ repo = "lsdbus";
+ rev = "6f80930248110927d1f898966544eec202ea3550";
+ hash = "sha256-N/VCjrI7RolHV0ya1U+YTLGAWv8+WNz2nobaGxdR1wQ=";
+ };
+
+ lsdbus = pkgs.stdenv.mkDerivation {
+ pname = "lsdbus";
+ version = "scm-3";
+ src = lsdbus-src;
+ nativeBuildInputs = with pkgs; [cmake gnumake pkg-config systemdLibs minixml lua5_4];
+ cmakeFlags = ["-DCONFIG_LUA_VER=5.4"];
+ };
+
+ lua =
+ pkgs.runCommand "lua-env" {
+ buildInputs = with pkgs; [lua5_4];
+ nativeBuildInputs = [pkgs.makeWrapper];
+ } ''
+ mkdir -p $out/bin
+ install -D -m 755 ${pkgs.lua5_4}/bin/lua $out/bin/lua
+ wrapProgram $out/bin/lua \
+ --prefix LUA_PATH \; '?.lua;?/init.lua' \
+ --prefix LUA_PATH \; '${lsdbus}/share/lua/5.4/?.lua' \
+ --prefix LUA_PATH \; '${lsdbus}/share/lua/5.4/?/init.lua' \
+ --prefix LUA_CPATH \; '${lsdbus}/lib/lua/5.4/?.so'
+ '';
+in
+ pkgs.stdenv.mkDerivation {
+ pname = "util.lua";
+ version = "1.0.0";
+ src = ./.;
+ buildInputs = [pkgs.brightnessctl];
+ nativeBuildInputs = [pkgs.makeWrapper];
+
+ buildPhase = ''
+ mkdir -p $out/{bin,lib}
+ substitute $src/util.lua $out/bin/util.lua --replace-fail @lua@ ${lua} --replace-fail @out@ $out
+ cp -r $src/util $out/lib/util
+ chmod +x $out/bin/util.lua
+ '';
+ }
diff --git a/pkgs/util/util.lua b/pkgs/util/util.lua
new file mode 100644
index 0000000..ade7019
--- /dev/null
+++ b/pkgs/util/util.lua
@@ -0,0 +1,35 @@
+#!@lua@/bin/lua
+local lsdbus = require("lsdbus")
+
+local music = dofile"@out@/lib/util/music.lua"
+local brightness = dofile"@out@/lib/util/brightness.lua"
+local volume = dofile"@out@/lib/util/volume.lua"
+
+local b = lsdbus.open()
+local s = lsdbus.open("system")
+
+if arg[1] == "music" then
+ if arg[2] == "toggle" then
+ music.toggle_play(b)
+ elseif arg[2] == "next" then
+ music.next_song(b)
+ elseif arg[2] == "prev" then
+ music.prev_song(b)
+ end
+elseif arg[1] == "brightness" then
+ if arg[2] == "up" then
+ brightness.brightness_up(s)
+ elseif arg[2] == "down" then
+ brightness.brightness_down(s)
+ else
+ error(("arg[2] '%s' incorrect format. Should be `up` or `down`"):format(tostring(arg[2])))
+ end
+elseif arg[1] == "volume" then
+ if arg[2] == "up" then
+ volume.volume_up()
+ elseif arg[2] == "down" then
+ volume.volume_down()
+ else
+ error(("arg[2] '%s' incorrect format. Should be `up` or `down`"):format(tostring(arg[2])))
+ end
+end
diff --git a/pkgs/util/util/brightness.lua b/pkgs/util/util/brightness.lua
new file mode 100644
index 0000000..13a7974
--- /dev/null
+++ b/pkgs/util/util/brightness.lua
@@ -0,0 +1,40 @@
+local lsdbus = require("lsdbus")
+
+local function get_brightness()
+ local proc = io.open("/sys/class/backlight/intel_backlight/brightness")
+ local cur_brightness = tonumber(proc:read("*l"))
+ return cur_brightness
+end
+
+local function get_max_brightness()
+ local proc = io.open("/sys/class/backlight/intel_backlight/max_brightness")
+ local max_brightness = tonumber(proc:read("*l"))
+ return max_brightness
+end
+
+local function notify_brightness()
+ local brightness_percent = math.floor((get_brightness() / get_max_brightness()) * 100)
+ os.execute(string.format(
+ "dunstify -t 2000 -h string:x-canonical-private-synchronous:brightness 'Brightness' -h int:value:%d",
+ brightness_percent
+ ))
+end
+
+local M = {}
+
+function set_brightness(s, brightness)
+ local brightness_proxy = lsdbus.proxy.new(s, 'org.freedesktop.login1', '/org/freedesktop/login1/session/1', "org.freedesktop.login1.Session")
+ brightness_proxy("SetBrightness", "backlight", "intel_backlight", brightness)
+end
+
+function M.brightness_down(s, brightness)
+ set_brightness(s, get_brightness() - 5*(get_max_brightness() / 100))
+ notify_brightness()
+end
+
+function M.brightness_up(s, brightness)
+ set_brightness(s, get_brightness() + 5*(get_max_brightness() / 100))
+ notify_brightness()
+end
+
+return M
diff --git a/pkgs/util/util/music.lua b/pkgs/util/util/music.lua
new file mode 100644
index 0000000..c9dd726
--- /dev/null
+++ b/pkgs/util/util/music.lua
@@ -0,0 +1,124 @@
+local lsdbus = require("lsdbus")
+
+function list_players(b)
+ local dbus = lsdbus.proxy.new(b,
+ 'org.freedesktop.DBus',
+ '/org/freedesktop/DBus',
+ 'org.freedesktop.DBus'
+ )
+ local all_services = dbus("ListNames")
+
+ local players = {}
+ for _, name in ipairs(all_services) do
+ if name:match("^org.mpris.MediaPlayer2") then
+ table.insert(players, name)
+ end
+ end
+ return players
+end
+
+local function get_player_proxy(b, player)
+ local ok, res = pcall(function() return lsdbus.proxy.new(b,
+ player,
+ '/org/mpris/MediaPlayer2',
+ 'org.mpris.MediaPlayer2.Player'
+ ) end)
+ if ok then
+ return res
+ end
+end
+
+local function list_playing_players(b)
+ local playing = {}
+ for _, player in ipairs(list_players(b)) do
+ local proxy = get_player_proxy(b, player)
+ if proxy and proxy.PlaybackStatus == "Playing" then
+ -- print(player)
+ table.insert(playing, player)
+ end
+ end
+ return playing
+end
+
+local function solo_player(b, player)
+ for _, i in list_playing_players(b) do
+ if i ~= player then
+ get_player_proxy(b, player)"Pause"
+ end
+ end
+end
+
+local STATE_FILE = os.getenv("HOME") .. "/.local/state/music_player_paused"
+local function write_state(state_file, player)
+ local f, _ = io.open(state_file, "w")
+ f:write(player.."\n")
+ f:close()
+end
+
+local function read_state(state_file)
+ local f, _ = io.open(state_file, "r")
+ local read = f:read("*l")
+ f:close()
+ return read
+end
+
+local M = {}
+
+local function notify_music(b, player)
+ local player_proxy = lsdbus.proxy.new(b, player, '/org/mpris/MediaPlayer2', 'org.mpris.MediaPlayer2.Player')
+ local meta = player_proxy.Metadata
+
+ os.execute(string.format(
+ "dunstify -t 2000 -h string:x-canonical-private-synchronous:music -i '%s' '%s' '%s' -h int:value:%d",
+ meta["mpris:artUrl"] or "",
+ player_proxy.PlaybackStatus .. " " .. meta["xesam:title"] or "",
+ "by " .. meta["xesam:artist"][1],
+ math.floor(player_proxy.Position / meta["mpris:length"])
+ ))
+end
+
+function M.toggle_play(b)
+ local current_playing = list_playing_players(b)
+ local state = read_state(STATE_FILE)
+
+ if #current_playing == 0 and state ~= "" then
+ local p = get_player_proxy(b, state)
+ if p then
+ p("Play")
+ notify_music(b, state)
+ end
+ return
+ end
+
+ if #current_playing == 1 then
+ local c = current_playing[1]
+ write_state(STATE_FILE, c)
+ get_player_proxy(b, c)("Pause")
+ notify_music(b, c)
+ return
+ end
+
+ if #current_playing > 1 then
+ for _, player in ipairs(current_playing) do
+ get_player_proxy(b, player)"Pause"
+ end
+ end
+end
+
+function M.next_song(b)
+ local currently_playing = list_playing_players(b)
+ if #currently_playing ~= 0 then
+ local player_proxy = lsdbus.proxy.new(b, currently_playing[1], '/org/mpris/MediaPlayer2', 'org.mpris.MediaPlayer2.Player')
+ player_proxy("Next")
+ end
+end
+
+function M.prev_song(b)
+ local currently_playing = list_playing_players(b)
+ if #currently_playing ~= 0 then
+ local player_proxy = lsdbus.proxy.new(b, currently_playing[1], '/org/mpris/MediaPlayer2', 'org.mpris.MediaPlayer2.Player')
+ player_proxy("Previous")
+ end
+end
+
+return M
diff --git a/pkgs/util/util/volume.lua b/pkgs/util/util/volume.lua
new file mode 100644
index 0000000..750f67c
--- /dev/null
+++ b/pkgs/util/util/volume.lua
@@ -0,0 +1,47 @@
+local function get_volume()
+ local handle = io.popen("wpctl get-volume @DEFAULT_AUDIO_SINK@")
+ local out = handle:read("*a")
+ handle:close()
+
+ local num = out:match("^Volume:%s*([%d%.]+)")
+ if not num then
+ error("Unexpected wpctl output: " .. out)
+ end
+
+ return tonumber(num) * 100
+end
+
+local function notify_volume()
+ os.execute(string.format(
+ "dunstify -t 2000 -h string:x-canonical-private-synchronous:audio 'Volume' -h int:value:%d",
+ math.floor(get_volume())
+ ))
+end
+
+local M = {}
+
+function M.set_volume(vol)
+ os.execute(string.format("wpctl set-volume @DEFAULT_AUDIO_SINK@ %.2f", vol / 100))
+ notify_volume()
+end
+
+function M.volume_up(step)
+ step = step or 5
+ local current = get_volume()
+ local new_volume = math.min(150, current + step)
+ M.set_volume(new_volume)
+end
+
+function M.volume_down(step)
+ step = step or 5
+ local current = get_volume()
+ local new_volume = math.max(0, current - step)
+ M.set_volume(new_volume)
+end
+
+function M.toggle_mute()
+ os.execute("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle")
+ notify_volume()
+end
+
+return M