aboutsummaryrefslogtreecommitdiff
path: root/modules/desktop/hjem/wm/default.nix
blob: a5575adf0e07b760f7e6bba5d6d77c3c520fbe93 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
{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;
  };
}