Outdated egg!

This is an egg for CHICKEN 4, the unsupported old release. You're almost certainly looking for the CHICKEN 5 version of this egg, if it exists.

If it does not exist, there may be equivalent functionality provided by another egg; have a look at the egg index. Otherwise, please consider porting this egg to the current version of CHICKEN.

i3

Extends the i3 window manager via its IPC interface.

  1. Outdated egg!
  2. i3
    1. i3
    2. connect
    3. cmd
      1. Examples
    4. subscribe
    5. tree
      1. Examples
    6. workspaces
    7. filter-containers
      1. Examples
    8. descend-focused
    9. focused-con
      1. Examples
    10. About this egg
      1. Author
      2. Colophon

i3

[module] i3

Note that there are more examples than what is documented here at http://code.stapelberg.de/git/i3-egg/tree/examples. That repository is also the canonical location for this egg’s source code.

connect

[procedure] (connect) → connection

Connects to i3 running on the display specified by the environment variable DISPLAY.

(define (connect)
  (let ((cmd-fd (socket af/unix sock/stream))
        (event-fd (socket af/unix sock/stream)))
    (socket-connect cmd-fd (unix-address (i3-socket-path)))
    (socket-connect event-fd (unix-address (i3-socket-path)))
    (let ((conn (make-i3-conn cmd-fd event-fd (make-mutex) #f '())))
      (i3-conn-event-thread-set!
        conn
        (thread-start! (lambda () (read-events conn))))
      conn)))

cmd

[procedure] (cmd conn msg #!optional (type 0)) → reply + reply-type

Sends the given MSG to i3, by default as command.

conn
A connection to i3, created with (connect).
msg
The payload of the message, e.g. a command when type is 0.
type
The numeric message type, “COMMAND” (0) by default. See also http://i3wm.org/docs/ipc.html#_sending_messages_to_i3 for message types.
(define (cmd conn msg #!optional (type 0))
  (let ((sock (i3-conn-cmd-fd conn)))
    (socket-send-all sock (i3-format-ipc-message msg type))
    (i3-read-one-message sock)))

Examples

Change focus to the window to the right:

(cmd (connect) "focus right")

subscribe

[procedure] (subscribe conn event thunk) → unspecified

Subscribes to the specified EVENT (e.g. "workspace") and calls THUNK when an event arrives.

(define (subscribe conn event thunk)
  (i3-conn-callbacks-set!
    conn
    (alist-update!
      (alist-ref event i3-event-name-to-type string=?)
      thunk
      (i3-conn-callbacks conn)))
  (let ((sock (i3-conn-event-fd conn)) (mutex (i3-conn-evmutex conn)))
    (mutex-lock! mutex)
    (socket-send-all
      sock
      (i3-format-ipc-message (json->string (vector event)) 2))
    (i3-read-one-message sock)
    (mutex-unlock! mutex)))

tree

[procedure] (tree conn) → reply + reply-type

Convenience function to get the layout tree from i3.

See http://i3wm.org/docs/ipc.html#_tree_reply for the reply format.

conn
A connection to i3, created with (connect).
(define (tree conn) (cmd conn "" 4))

Examples

Return a list of all Chrome windows:

(filter-containers
 (lambda (con) (string-suffix? " - Google Chrome" (alist-ref 'name con)))
 (tree (connect)))

workspaces

[procedure] (workspaces conn) → reply + reply-type

Convenience function to get the workspaces from i3.

See http://i3wm.org/docs/ipc.html#_workspaces_reply for the reply format.

conn
A connection to i3, created with (connect)
(define (workspaces conn) (cmd conn "" 1))

filter-containers

[procedure] (filter-containers predicate tree) → list

Returns a list containing all containers for which the given predicate returns #t.

predicate
Predicate which is evaluated for each i3 container. Only containers for which the predicate returns #t are included in the return list
tree
(Part of) a list of containers as returned by (tree).
(define (filter-containers predicate tree)
  (if (null? tree)
    '()
    (append
      (if (predicate tree) (list tree) (list))
      (apply append
             (filter-map
               (lambda (node) (filter-containers predicate node))
               (cdr (assoc 'nodes tree)))))))

Examples

Return a list of all Chrome windows:

(filter-containers
 (lambda (con) (string-suffix? " - Google Chrome" (alist-ref 'name con)))
 (tree (connect)))

descend-focused

[procedure] (descend-focused stop-predicate tree) → alist

Descends the focused containers of the given TREE, stopping at the first container which satisfies STOP-PREDICATE.

stop-predicate
Processing stops when this predicate first returns true. The return value is the container with which this predicate was evaluated.
tree
(Part of) a list of containers as returned by (tree).
(define (descend-focused stop-predicate tree)
  (if (stop-predicate tree)
    tree
    (if (null? (alist-ref 'focus tree))
      tree
      (descend-focused
        stop-predicate
        (let ((focused-id (first (alist-ref 'focus tree))))
          (find (lambda (con) (= (alist-ref 'id con) focused-id))
                (append
                  (alist-ref 'nodes tree)
                  (alist-ref 'floating_nodes tree))))))))

focused-con

[procedure] (focused-con tree) → alist

Returns the currently focused container.

tree
(Part of) a list of containers as returned by (tree).
(define (focused-con tree)
  (descend-focused (lambda (con) (null? (alist-ref 'nodes con))) tree))

Examples

Print the name of the currently focused window:

(format #t "~A~N" (alist-ref 'name (focused-con (tree (connect)))))

Print the name of the focused window of workspace 1:

(let ((ws-1
       (first
        (filter-containers
         (lambda (con)
           (and (= (alist-ref 'type con) 4)
                (string= (alist-ref 'name con) "1")))
         (tree (connect))))))
  (format #t "~A~N" (focused-con ws-1)))

About this egg

Author

Michael Stapelberg

Colophon

Documented by cock.