Hyprland & Clojure

I’m shopping for the next WM on my Linux box and I’m currently evaluating Hyprland. This is my first Wayland compositor; before, I’ve used only X11 WMs — exwm, stump, awesome. And every one of them has some limitations:

  • AwesomeWM — my current runner. It’s good, my favorite thing about it (why I chose it) - it is Lua-based, meaning I can easily use Fennel. Although I’ve never figured out how to get the “proper” REPL for it, and without the REPL, a Clojure-like language feels like a Ferrari without an engine — you have to pedal to get around. I should’ve probably tried figuring out that part first, but that proved to be not so simple, besides … I just got bored with it. Also, after using it long enough, I’ve grown annoyed by small bugs, like rules inexplicably stopping working.

  • EXWM — very cool, everything in Emacs, easy to use (for Elisp users), but not being able to easily kill and restart Emacs without restarting the WM session is problematic.

  • Stump — very cool, Common Lisp-based, everything doable via REPL. It lacks a few key features expected from a WM, like floating windows over tiled ones. But it mostly works and feels nice — I’m tempted to revisit this old friend, if this current experiment doesn’t go too far.

Like I said, I’m currently trying out Hyprland, which looks and feels very cool. Yet almost immediately, I started rolling my eyes. The config is “declarative”, meaning I can’t easily do anything more complex than basic “boring” stuff. But then I discovered I can execute external scripts. That made me think: “Hey, what if… I just use Babashka? That could work, right?” Then I wondered: “Surely I’m not the first to think like this,” so I Googled, GitHub-searched, and dug beyond Google’s first page — nothing. I found a Hyprland IPC wrapper in Common Lisp, and little else.

So, here’s my question: Do you madlads know any interesting Hyprland configs done in Clojure, Fennel, or other Lisps? Maybe you’ve seen someone use it? Or tried it yourself and hit roadblocks? Share your thoughts! I’m about to dive into a time sink of questionable payoff — or… maybe not. Right now, I don’t know.

1 Like

Just wanted to address this bit - I’ve also been bitten by it a few times, and every single time the explanation was very simple. The apps that produced the windows that should be controlled by the rules were updated and changed some window class names or something else that the rules targeted.

Wow, Hyprland supports socket IPC, turned out it’s pretty trivial to work with it directly from Clojure, here’s my dirty babashka tidbit:

(ns scripts
  (:require [babashka.process :as p]
            [clojure.java.io :as io]
            [babashka.fs :as fs])
  (:import [java.net StandardProtocolFamily UnixDomainSocketAddress]
           [java.nio ByteBuffer]
           [java.nio.channels SocketChannel]))

(def HIS (System/getenv "HYPRLAND_INSTANCE_SIGNATURE"))

(def runtime-dir (System/getenv "XDG_RUNTIME_DIR"))

(def hyprctl-socket
  (UnixDomainSocketAddress/of
   (-> (fs/file (format "%s/hypr/%s/.socket.sock" runtime-dir HIS))
       str)))

#_(def hyprctl-event-socket
  (UnixDomainSocketAddress/of
   (-> (doto (fs/file (format "%s/hypr/%s/.socket2.sock" runtime-dir HIS))
         (.deleteOnExit))
       str)))

(defn send-hyprctl-command [cmd]
  (with-open [ch (SocketChannel/open StandardProtocolFamily/UNIX)]
    (.connect ch hyprctl-socket)
    (let [buf (ByteBuffer/wrap (.getBytes cmd "UTF-8"))]
      (.write ch buf)
      (let [reply (ByteBuffer/allocate 1024)]
        (when (pos? (.read ch reply))
          (.flip reply)
          (println "Response:" (String. (.array reply) "UTF-8")))))))

(comment
 (send-hyprctl-command "dispatch exec kitty")
 (send-hyprctl-command "dispatch fullscreen 1")
 (send-hyprctl-command "dispatch fullscreen 0")
 (send-hyprctl-command "notify 1 90000 rgb(ff1ea3) Yo")
 (send-hyprctl-command "version")
 (send-hyprctl-command "devices")
 (send-hyprctl-command "monitors"))

And then one can pretty much do tons of interesting things and logic in Clojure. I am honestly a bit shocked nobody has done it before.

3 Likes

This looks quite nice! :slight_smile: