This is a set of notes that are being compiled as a part of the Hack Sessions series of streams!
Here are the official EXWM repo links:
If you'd like to contribute to my fork, you can check it out here:
https://github.com/daviwil/exwm
The files:
exwm-init is the entrypoint for setting up EXWM and connecting to the X Window System server.
Many update functions used internally
Part of the initialization process is to initialize modules like ICCCM and EWMH via functions like xcb:ewmh:init, these seem to be focused around fetching the IDs for well-known Atoms. Once they've been fetched, those subsystems are considered to be initialized.
BUG_HUNT.org README.md exwm-cm.el exwm-config.el exwm-core.el exwm-floating.el exwm-input.el exwm-layout.el exwm-manage.el exwm-randr.el exwm-systemtray.el exwm-workspace.el exwm-xim.el xinitrc
Generates elisp libraries for the X11 protocol with the el_client.el file, driven by the Makefile
A small portion of the files are generated but many are helper libraries for specific parts of the X11 protocol.
https://xcb.freedesktop.org/ xcb tutorial XML-XCB format for describing the X Window System protocol
This is the client/server system which handles drawing to the screen, mouse/keyboard input, etc.
You communicate with it via an XML-based protocol.
This seems to be a set of conventions for commuication between clients in the X Window System
Describes window manager interactions at a low level
https://www.x.org/releases/current/doc/xorg-docs/icccm/icccm.html#Introduction
Extended Window Manager Hints
An extended set of conventions for modern desktop environments (see Non-ICCCM features section)
https://specifications.freedesktop.org/wm-spec/wm-spec-1.3.html
Assumption: the window manager is the "root window" and anything in this document that describes messages handled by the root window are actually handled by the window manager.
Docs: https://cgit.freedesktop.org/xorg/xserver/tree/hw/kdrive/ephyr/README
Here's a simple script that can help with testing:
#!/bin/sh
Xephyr :1 -ac -dpi 180 -screen 1920x1080 &
DISPLAY=:1 emacs
pkill Xephyr
I'm also using this Emacs configuration for testing purposes:
(add-to-list 'load-path (expand-file-name "/home/daviwil/Projects/Code/xelb"))
(add-to-list 'load-path (expand-file-name "/home/daviwil/Projects/Code/exwm"))
(load-theme 'deeper-blue t)
(require 'exwm)
;; Allow C+lmb to move windows
(setq exwm-input-move-event 'C-down-mouse-1)
;; Set some global keys
(setq exwm-input-global-keys
`(([?\C-c ?x ?r] . exwm-reset)
([?\C-c ?x ?i] . exwm-input-toggle-keyboard)
([?\C-c ?x ?f] . exwm-layout-toggle-fullscreen)
([?\C-c ?x ?l] . (lambda (command)
(interactive (list (read-shell-command "$ ")))
(start-process-shell-command command nil command)))
([?\C-c ?x ?k] . (lambda () (interactive) (kill-buffer)))
,@(mapcar (lambda (i)
`(,(kbd (format "C-c x %d" i)) .
(lambda ()
(interactive)
(exwm-workspace-switch-create ,i))))
(number-sequence 0 9))))
;; Initialize EXWM
(exwm-init)
;; Turn EXWM and XELB logging (check *XELB-DEBUG* buffer)
(exwm-debug)
;; Enter the debugger when an error is encountered
(toggle-debug-on-error)
(defun dw/exwm-fake-command-wrapper (orig-fn &rest args)
(debug-on-variable-change 'last-command)
(apply orig-fn args)
(cancel-debug-on-variable-change 'last-command))
;; NOTE: This isn't being used now, leaving it here for reference
;; (advice-add 'exwm-input--fake-last-command :around #'dw/exwm-fake-command-wrapper)
;; Kudos to Timor for this suggestion:
(defun xcb-debug:message (format-string &rest objects)
"Print a message to `xcb-debug:buffer'.
The FORMAT-STRING argument follows the speficies how to print each of
the passed OBJECTS. See `format' for details."
(let ((str (apply #'format format-string objects)))
(xcb-debug:-with-debug-buffer
(insert str))
(princ str 'external-debugging-output)))
;; NOTE: To save logs to a file, use:
;;
;; emacs 2>exwm.log
;;
;; Log each window that get opened
(add-hook 'exwm-manage-finish-hook
(lambda ()
(exwm--log "WINDOW DISPLAYED: %s (%s)" exwm-class-name exwm-title)))
(split-window-right)
(other-window 1)
;; (start-process-shell-command "gnome-mahjongg" nil "gnome-mahjongg")
;; (start-process-shell-command "calibre" nil "calibre")
Link: https://github.com/ch11ng/exwm/issues/842
Notes
This was caused by a misbehaving function in isearch which was being added to the pre-command-hook that gets invoked by exwm-input--fake-last-command. We fixed the issue by wrapping the run-hooks calls with a condition-case macro to prevent errors from breaking the EXWM session.