Guix, XIM, Emacs, Multi_key, Shft+SPC
— Describe in single words only the good things that come into your mind about…
<Multi_key>
.—
<Multi_key>
?— Yeah.
— Let me tell you about
<Multi_key>
….
"<Multi_key> is undefined"
A bit out of order, but things tangle, a problem I’m having on my Guix machine with Emacs.
It’s connected with the Lucid toolkit1, but only in an indirect causal sort of way:— I’m using the standard GTK3 toolkit on this particular build of Emacs on Guix. (A custom build, admittedly, which might be part of the issue, but where exactly, I’m not sure.) I’ll probably say some other things connected to this later, but for the moment forgot about Lucid. It’s just a GTK3 toolkit build.2
So, skipping over large swathes of story, I’ve got a seemingly
mostly-functioning build of Emacs 30.0.93 running on my Guix laptop
(which finally has a functioning StumpWM environment again), and I go
to type æ or þ or á or λ or something using Right_Alt
as a compose key
(defined by xmodmap
) and Emacs, without blinking an eye, flashes at
me, saying "<Multi_key> is undefined"
.
I try various things to do with XIM and environment variables3 and
none of it works. I finally come across a post on a FreeBSD bugs
tracker4 which suggests a possible fix of setting (setq x-gtk-use-native-input 't)
.
And, though it feels like a hack for something that’s gone wrong in a deeper way, it seems to work, and I can type ɔ and Þ and γ and so on.
But then I’m reading a PDF (using PDF Tools) and I go to page back up to read an earlier bit by pressing Shift and SPACE and I find myself paging down to the end of the document instead.
The “native input” method apparently won’t recognise Shft+SPACE, but just sees SPACE and so pages down.
So if x-gtk-use-native-input
is nil
, I can’t use the compose key in
Emacs, and if it’s t
then I can’t scroll properly in PDFs.
I thought vaguely about writing a macro to process the ‘kragen’ XCompose definitions into a bunch of things of the form:
(define-key global-map [(Multi_key) (s) (s)] (lambda ()
(interactive)
(insert 223)))
and then have my init.el load the whole thing in. But I don’t think that would quite work anyway, since sometimes I want to say insert a special character as part of a search and not insert it into a text buffer.
So I came up with a different stupid solution. It’s not perfect, but it’s at least somewhat working while I try to figure out what went wrong in the first place.
Here it is:
(when (equal (system-name) "guix-laptop")
;; on this Guix/StumpWM machine's Emacs, xcompose doesn't work:
;; Emacs says "I don't know what <Multi_key> means"
;; (well, it actually says "<Multi_key> is undefined").
;; As per https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=278167
;; we can 'fix' this if we set (setq x-gtk-use-native-input 't).
;; Then xcompose will will work again ... but now Shift-SPACE won't
;; So...
(setq x-gtk-use-native-input 'nil) ;; make sure Shift-SPACE works...
;; So, Emacs says "<Multi_key> is undefined".
;; Well, then, we can define it.
;; Namely as a function which sets `x-gtk-use-native-input' to `t',
;; and then calls an external shell-command to input <Multi_key>
;; (so that it acts like Right_Alt was pressed), and then sets a timer running
;; that turns `x-gtk-use-native-input' to `nil' after 10 seconds
;; (so that Shift-SPACE will work again).
(defun bms/xinput-hack ()
(interactive)
;; stop the timer if there is one running already:
(when bms/xinput-timer-running
(cancel-timer bms/xinput-timer-running))
;; set the input method to allow xcompose to work:
(setq x-gtk-use-native-input 't)
;; must have `xdotool' installed:
(shell-command "xdotool key Multi_key")
;; record the name of the timer to stop it,
;; so we don't end up with tonnes of timers somehow
(setq bms/xinput-timer-running
(run-at-time 10 nil
;; this sets it for 10 secs; maybe could be shorter,
;; but you don't want it turning off in the middle of sequences
(lambda ()
(setq x-gtk-use-native-input 'nil)))))
;; And then we bind <Multi_key> to that function.
;; (There, now it's not undefined anymore.)
(define-key global-map (kbd "<Multi_key>") #'bms/xinput-hack))
;; A stupid solution to a stupid problem.
-
See Emacs Using the Lucid toolkit is blazingly fast | r/emacs for why this might be interesting. This is the whole “out of order” thing, but it’s not directly relevant for this particular post. ↩︎
-
Though, on the plain, boring, ordinary GTK3 toolkit and its relation to Emacs see “Buttery Smooth Emacs”. ↩︎
-
And I’ve already got
(setf (getenv "GTK_IM_MODULE") "xim")
and(setf (getenv "QT_IM_MODULE") "xim"
setting environment variables in myinit.lisp
config for StumpWM here anyway. ↩︎