From anarcat at orangeseeds.org Fri Apr 14 01:26:11 2017 From: anarcat at orangeseeds.org (Antoine Beaupre) Date: Thu, 13 Apr 2017 21:26:11 -0400 Subject: [xmonad] emacs making itself sticky and copyToAllToggle Message-ID: <87zifjlqz0.fsf@curie.anarc.at> Hi, I've been working on improving the integration between the great [writeroom-mode][] and Xmonad here, in what is probably the worst case of procrastination, yak-shaving level. Writeroom is a "distraction-free writing" mode for emacs. It turns out the "sticky" signal it sends is not recognized by Xmonad, a known limitation which I will not expand on here - other people more familiar with Xmonad may fix or talk about this better than me. [writeroom-mode]: https://github.com/joostkremers/writeroom-mode/ But, needing to scratch that particular itch, and with the help of clever people from the IRC channel, I was able to basically accomplish what I needed. This involved creating a new function which I think could be useful in the CopyWindow library: -- | Toggle between "copyToAll" or "killAllOtherCopies". Copies to all -- workspaces, or remove from all other workspaces, depending on -- previous state (checked with "wsContainingCopies"). copyToAllToggle :: X () copyToAllToggle = do -- check which workspaces have copies copies <- wsContainingCopies if null copies then windows copyToAll -- no workspaces, make sticky else killAllOtherCopies -- already other workspaces, unstick There are probably better ways of implementing this directly in the CopyWindow code - wsContainingCopies, in particular, is probably overkill. But it's all I can use directly from my xmonad.hs, so that's what I did. The other bit I needed was something to trigger that function from the outside. I rejected the ServerMode hook because it looked a bit too complicated and there is a built-in facility within X that works without this, which, from Emacs' point of view, is the `x-send-client-message` function. So I made up a new message identifier and wrote a event hook handler to process it: -- | handle X client messages that tell Xmonad to make a window appear -- on all workspaces -- -- this should really be using _NET_WM_STATE and -- _NET_WM_STATE_STICKY. but that's more complicated: then we'd need -- to inspect a window and figure out the current state and act -- accordingly. I am not good enough with Xmonad to figure out that -- part yet. -- -- Instead, just check for the relevant message and check if the -- focused window is already on all workspaces and toggle based on -- that. -- -- this is designed to interoperate with Emacs's writeroom-mode module -- and called be called from elisp with: -- -- (x-send-client-message nil 0 nil "XMONAD_COPY_ALL_SELF" 8 '(0)) myClientMessageEventHook :: Event -> X All myClientMessageEventHook (ClientMessageEvent {ev_message_type = mt, ev_data = dt}) = do dpy <- asks display -- the client message we're expecting copyAllMsg <- io $ internAtom dpy "XMONAD_COPY_ALL_SELF" False -- if the event matches the message we expect, toggle sticky state when (mt == copyAllMsg && dt /= []) $ do copyToAllToggle -- we processed the event completely return $ All True All that was left was to hook that into emacs, and I was done! Whoohoo! Full screen total domination, distraction free work! :) Attached is the patch to my configuration files that accomplished the whole thing. I would love to hear from others what they think of that approach, if they have improvements or if the above copyToAllToggle function could be merged in. Ideally, Xmonad would just parse the STICKY client messages and do the right thing - maybe even directly in CopyWindow - but I have found this enough Haskell for one day.. :) Thanks for your attention, A. -- Instead of worrying about what somebody else is going to do, which is not under your control, the important thing is, what are you going to decide about what is under your control? - Richard Stallman -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-hook-writeroom-mode-into-sticky-xmonad-desktops.patch Type: text/x-diff Size: 6667 bytes Desc: not available URL: