
Hiya everyone. So as I've long mused about, I've gotten around to seeing how difficult it'd be to do a Ratpoison style keymap for XMonad. It went reasonably well, but I've run into a number of Ratpoison commands where I can't see what to bind them to (or whether the functionality is implemented in XMC somewhere I just don't know about), so I thought I'd demonstrate what I have and see whether anyone has any suggestions. The code is as follows: {- Not implemented: C-t C-t Switch to the last window. C-t t Sometimes you need to send a C-t to the current window. This keystroke does just that. C-t A C-t C-A Rename the current window. The window's new name will prevail for the rest of its lifetime. C-t ' C-t C-' Go to a window by name. You will usually only need to type the first few characters of the window name. C-t a C-t C-a Display the current time of day. C-t : This allows you to execute a single ratpoison command. C-t i C-t C-i Display information about the current window. C-t m C-t C-m Display the last message. C-t V C-t C-V Display ratpoison's license. C-t w C-t C-w Display the list of managed windows. The current window is highlighted. C-t M-tab Switch to the last focused frame. C-t Q Kill all frames but the current one. C-t R Kill the current frame. This is a no-op if there is only one frame. C-t r C-t C-r Resize the current frame. C-t ? Display a help screen. C-t f C-t C-f select a frame by number. C-t F Indicate which frame is the current frame. C-t x C-t C-x Choose a frame and exchange the window in the current frame with the window in the chosen frame. -} -- | This list, duplicates and all is based off of -- <http://www.nongnu.org/ratpoison/doc/Default-Key-Bindings.html#Default Key Bindings>. ratpoisonKeys :: XConfig t -> Map (KeyMask, KeySym) (X ()) ratpoisonKeys conf@(XConfig {XMonad.modMask = m}) = M.fromList $ [ -- rebind standard -- actions -- this defines our root-key - mod-t ((m, xK_t), submap . M.fromList $ -- OK, now we can begin to list all -- the actual Ratpoison bindings -- which live in this submap. [ ((0, xK_n), next) , ((m, xK_n), next) , ((0, xK_space), next) , ((m, xK_space), next) , ((0, xK_Return), next) , ((m, xK_Return), next) , ((0, xK_p), previous) , ((m, xK_p), previous) , ((0, xK_k), kill) , ((m, xK_k), kill) , ((0, xK_K), kill) , ((m, xK_K), kill) , ((0, xK_c), spawn term) , ((m, xK_c), spawn term) , ((m, xK_exclam), prompt (term ++ " -e") defaultXPConfig) , ((0, xK_exclam), prompt ("/bin/sh" ++ " -c") defaultXPConfig) -- We call out to the shell because -- we can't use Main.hs's trick of -- "showVersion version" - we don't -- see Paths_xmonad , ((0, xK_v), version) , ((m, xK_v), version) , ((0, xK_l), refresh) , ((m, xK_l), refresh) -- This is wrong. , ((0, xK_s), sendMessage NextLayout) , ((m, xK_s), sendMessage NextLayout) , ((0 .|. shiftMask, xK_s), sendMessage NextLayout) , ((m .|. shiftMask, xK_s), sendMessage NextLayout) , ((0, xK_b), banish) , ((m, xK_b), banish) , ((0, xK_Right), sendMessage $ Go R) , ((0, xK_Left ), sendMessage $ Go L) , ((0, xK_Up ), sendMessage $ Go U) , ((0, xK_Down ), sendMessage $ Go D) , ((m, xK_Right), sendMessage $ Swap R) , ((m, xK_Left ), sendMessage $ Swap L) , ((m, xK_Up ), sendMessage $ Swap U) , ((m, xK_Down ), sendMessage $ Swap D) ] ++ [((0, k), windows $ f i) | (i, k) <- zip (XMonad.workspaces conf) [xK_1 .. xK_9] , (f, _) <- [(W.greedyView, 0), (W.shift, shiftMask)]] )] where next = windows W.focusDown previous = windows W.focusUp term = XMonad.terminal conf version = spawn "xmessage `xmonad --version`" banish :: X () banish = warpToWindow 1 1 -- lower right -- gwern Al E.O.D. Freedom Inmarsat 6 B43 ^X STARLAN FOSS NSRB

On Sun, Jun 29, 2008 at 08:38:57AM -0400, Gwern Branwen wrote:
Hiya everyone. So as I've long mused about, I've gotten around to seeing how difficult it'd be to do a Ratpoison style keymap for XMonad. It went reasonably well, but I've run into a number of Ratpoison commands where I can't see what to bind them to (or whether the functionality is implemented in XMC somewhere I just don't know about), so I thought I'd demonstrate what I have and see whether anyone has any suggestions.
The code is as follows:
{- Not implemented: […] C-t t Sometimes you need to send a C-t to the current window. This keystroke does just that.
If you ever want to implement this, here's a function that might be useful: sendKey :: Window -> KeyMask -> KeySym -> X () sendKey w mods key = withDisplay $ \d -> do rootw <- asks theRoot keycode <- io $ keysymToKeycode d key io $ allocaXEvent $ \ev -> do setEventType ev keyPress setKeyEvent ev w rootw none mods keycode True sendEvent d w True keyPressMask ev setEventType ev keyRelease sendEvent d w True keyReleaseMask ev It works fine in my own xmonad.hs (which I unfortunately never found the time to turn into a proper extension). Cheers, -- Jérémy Bobbio .''`. lunar@debian.org : :Ⓐ : # apt-get install anarchism `. `'` `-

On 2008.07.04 01:46:12 +0200, Jérémy Bobbio
On Sun, Jun 29, 2008 at 08:38:57AM -0400, Gwern Branwen wrote:
Hiya everyone. So as I've long mused about, I've gotten around to seeing how difficult it'd be to do a Ratpoison style keymap for XMonad. It went reasonably well, but I've run into a number of Ratpoison commands where I can't see what to bind them to (or whether the functionality is implemented in XMC somewhere I just don't know about), so I thought I'd demonstrate what I have and see whether anyone has any suggestions.
The code is as follows:
{- Not implemented: […] C-t t Sometimes you need to send a C-t to the current window. This keystroke does just that.
If you ever want to implement this, here's a function that might be useful:
sendKey :: Window -> KeyMask -> KeySym -> X () sendKey w mods key = withDisplay $ \d -> do rootw <- asks theRoot keycode <- io $ keysymToKeycode d key io $ allocaXEvent $ \ev -> do setEventType ev keyPress setKeyEvent ev w rootw none mods keycode True sendEvent d w True keyPressMask ev setEventType ev keyRelease sendEvent d w True keyReleaseMask ev
It works fine in my own xmonad.hs (which I unfortunately never found the time to turn into a proper extension).
Cheers, -- Jérémy Bobbio .''`.
Thanks for the code, Jeremy; I've long wanted a function to send keys to windows. I was thinking of adding it to XSelection, but what limits does this function have, do you know? X is often difficult to deal with. Does it handle odd characters? -- gwern Undercover burhop World 757 William BECCA Psyops veggie 3M Treasury

On Sat, Jul 12, 2008 at 12:34:18AM -0400, Gwern Branwen wrote:
Thanks for the code, Jeremy; I've long wanted a function to send keys to windows. I was thinking of adding it to XSelection, but what limits does this function have, do you know? X is often difficult to deal with. Does it handle odd characters?
I use it to send "xK_3" with "mod1Mask .|. controlMask" to an urxvt. This shortcut is bound to changing the terminal font size. I don't know how odd it is in your definition, but for me, it does the trick! :) Cheers, -- Jérémy Bobbio .''`. lunar@debian.org : :Ⓐ : # apt-get install anarchism `. `'` `-

On 2008.07.13 17:26:55 +0200, Jérémy Bobbio
On Sat, Jul 12, 2008 at 12:34:18AM -0400, Gwern Branwen wrote:
Thanks for the code, Jeremy; I've long wanted a function to send keys to windows. I was thinking of adding it to XSelection, but what limits does this function have, do you know? X is often difficult to deal with. Does it handle odd characters?
I use it to send "xK_3" with "mod1Mask .|. controlMask" to an urxvt. This shortcut is bound to changing the terminal font size.
I don't know how odd it is in your definition, but for me, it does the trick! :)
Cheers, -- Jérémy Bobbio .''`.
Oh. Hmm, it still sounds useful. Incidentally, how exactly does one use it? I gave it a desultorily try, but I was unsure how exactly one gets the Window argument - I tried using withWindowSet, but got bogged down extracting the Window parameter from it. -- gwern NSOF Tess 2E781 B28RE Consul 03 e95 Compsec hate Banner

On Fri, Sep 12, 2008 at 10:56:47PM -0400, Gwern Branwen wrote:
Oh. Hmm, it still sounds useful. Incidentally, how exactly does one use it? I gave it a desultorily try, but I was unsure how exactly one gets the Window argument - I tried using withWindowSet, but got bogged down extracting the Window parameter from it.
You're probably looking for withFocused. You can see its definition in Operations.hs -- it uses withWindowSet.

On 2008.09.12 20:57:08 -0700, Devin Mullins
On Fri, Sep 12, 2008 at 10:56:47PM -0400, Gwern Branwen wrote:
Oh. Hmm, it still sounds useful. Incidentally, how exactly does one use it? I gave it a desultorily try, but I was unsure how exactly one gets the Window argument - I tried using withWindowSet, but got bogged down extracting the Window parameter from it.
You're probably looking for withFocused. You can see its definition in Operations.hs -- it uses withWindowSet.
Ah, I see. I was searching for the wrong type signature after all. So I've been working up a basic XPaste module, and here's what I have thus far" -------------------------------- sendSelection :: KeyMask -> X () sendSelection m = getSelection >>= (sendString m) sendString :: KeyMask -> String -> X () sendString mo = mapM_ (sendChar mo) sendChar :: KeyMask -> Char -> X () sendChar modm c = sendKeyScreen modm (stringToKeysym [c]) sendKeyScreen :: KeyMask -> KeySym -> X () sendKeyScreen modmk key = withFocused (sendKeysym modmk key) sendKeysym :: KeyMask -> KeySym -> Window -> X () sendKeysym mods key w = withDisplay $ \d -> do rootw <- asks theRoot keycode <- io $ keysymToKeycode d key io $ allocaXEvent $ \ev -> do setEventType ev keyPress setKeyEvent ev w rootw none mods keycode True sendEvent d w True keyPressMask ev setEventType ev keyRelease sendEvent d w True keyReleaseMask ev -------------------------------- My first question is, is there any way to scrap all the KeyMask plumbing? I looked at the X11 docs, but there doesn't seem to be any null modmask - mod1Mask is Alt, Shift is Shift, and so on. My second question is, why does 'keysymToKeycode' take a String? I manually played around with it in GHCi and it seems every String which isn't a Char always gets evaluated to '0'. -- gwern Scully .375 PLA TWA Active White dog Amherst WISDIM rita

On Fri, Sep 19, 2008 at 02:33:00PM -0400, Gwern Branwen wrote:
Ah, I see. I was searching for the wrong type signature after all.
So I've been working up a basic XPaste module, and here's what I have thus far"
-------------------------------- sendSelection :: KeyMask -> X () sendSelection m = getSelection >>= (sendString m)
sendString :: KeyMask -> String -> X () sendString mo = mapM_ (sendChar mo)
sendChar :: KeyMask -> Char -> X () sendChar modm c = sendKeyScreen modm (stringToKeysym [c])
sendKeyScreen :: KeyMask -> KeySym -> X () sendKeyScreen modmk key = withFocused (sendKeysym modmk key)
sendKeysym :: KeyMask -> KeySym -> Window -> X () sendKeysym mods key w = withDisplay $ \d -> do rootw <- asks theRoot keycode <- io $ keysymToKeycode d key io $ allocaXEvent $ \ev -> do setEventType ev keyPress setKeyEvent ev w rootw none mods keycode True sendEvent d w True keyPressMask ev setEventType ev keyRelease sendEvent d w True keyReleaseMask ev --------------------------------
If I might suggest a few name changes: - change sendKeyScreen to sendKey - change sendKeysym to sendKeyWindow
My first question is, is there any way to scrap all the KeyMask plumbing? I looked at the X11 docs, but there doesn't seem to be any null modmask - mod1Mask is Alt, Shift is Shift, and so on.
KeyMask is a bitmask, so 0 is the no modifiers pressed state. I'd also leave the KeyMask argument on sendKeysym and sendKeyscreen -- some users want to send keys with modifiers (eg. the person that started this thread).
My second question is, why does 'keysymToKeycode' take a String? I manually played around with it in GHCi and it seems every String which isn't a Char always gets evaluated to '0'.
I assume you mean stringToKeysym. Try: stringToKeysym "F1". You should probably filter out the 0 results when sending a string, or perhaps throw an error. Cheers, Spencer Janssen

On 2008.09.19 15:40:25 -0500, Spencer Janssen
On Fri, Sep 19, 2008 at 02:33:00PM -0400, Gwern Branwen wrote: ... If I might suggest a few name changes: - change sendKeyScreen to sendKey - change sendKeysym to sendKeyWindow
Good suggestions. I've done so. I also did a copy-replace of 'paste' for 'send', to assist people in searching. I suspect many more people will think 'paste' than 'send', even if the low-level X functions are named in terms of the latter.
My first question is, is there any way to scrap all the KeyMask plumbing? I looked at the X11 docs, but there doesn't seem to be any null modmask - mod1Mask is Alt, Shift is Shift, and so on.
KeyMask is a bitmask, so 0 is the no modifiers pressed state. I'd also leave the KeyMask argument on sendKeysym and sendKeyscreen -- some users want to send keys with modifiers (eg. the person that started this thread).
Ah. I feel a little guilty bypassing the Mod* types to plug in in a 0, but it works, it seems.
My second question is, why does 'keysymToKeycode' take a String? I manually played around with it in GHCi and it seems every String which isn't a Char always gets evaluated to '0'.
I assume you mean stringToKeysym. Try: stringToKeysym "F1". You should probably filter out the 0 results when sending a string, or perhaps throw an error.
Cheers, Spencer Janssen
Maybe. It's not really an issue for this code, is it? Since the type only takes Char, one cannot make it run stringToKeysym on a invalid string like "foo". And the functions lower down are in terms of Keysyms. (Although I wonder if perhaps that bit of functionality should be explored in the X11 haddocks. I didn't notice anything in particular.) ---- Well, anyway. I've sent in a module if people want to look at it. -- gwern Bluebird 5707 Kosovo Zemin XM Guppy Internet NVD ABC SGI

On 2008 Sep 20, at 11:37, Gwern Branwen wrote:
On 2008.09.19 15:40:25 -0500, Spencer Janssen
scribbled 2.0K characters: On Fri, Sep 19, 2008 at 02:33:00PM -0400, Gwern Branwen wrote:
My first question is, is there any way to scrap all the KeyMask plumbing? I looked at the X11 docs, but there doesn't seem to be any null modmask - mod1Mask is Alt, Shift is Shift, and so on.
KeyMask is a bitmask, so 0 is the no modifiers pressed state. I'd also leave the KeyMask argument on sendKeysym and sendKeyscreen -- some users want to send keys with modifiers (eg. the person that started this thread).
Ah. I feel a little guilty bypassing the Mod* types to plug in in a 0, but it works, it seems.
You might export a noModMask = 0. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

On 2008.09.20 12:31:22 -0400, "Brandon S. Allbery KF8NH"
On 2008 Sep 20, at 11:37, Gwern Branwen wrote:
On 2008.09.19 15:40:25 -0500, Spencer Janssen
scribbled 2.0K characters: On Fri, Sep 19, 2008 at 02:33:00PM -0400, Gwern Branwen wrote:
My first question is, is there any way to scrap all the KeyMask plumbing? I looked at the X11 docs, but there doesn't seem to be any null modmask - mod1Mask is Alt, Shift is Shift, and so on.
KeyMask is a bitmask, so 0 is the no modifiers pressed state. I'd also leave the KeyMask argument on sendKeysym and sendKeyscreen -- some users want to send keys with modifiers (eg. the person that started this thread).
Ah. I feel a little guilty bypassing the Mod* types to plug in in a 0, but it works, it seems.
You might export a noModMask = 0.
-- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com
That would work, certainly. But isn't that really the X11 library's job? Intuitively, defining noModMask in XPaste.hs feels wrong & completely out of place. -- gwern Shayet-13 fake Freedom Recce b Richard DSNET2 Ortega MI6 CMW

On 2008 Sep 20, at 13:14, Gwern Branwen wrote:
On 2008.09.20 12:31:22 -0400, "Brandon S. Allbery KF8NH"
scribbled 0.9K characters: On 2008 Sep 20, at 11:37, Gwern Branwen wrote:
On 2008.09.19 15:40:25 -0500, Spencer Janssen
scribbled 2.0K characters: On Fri, Sep 19, 2008 at 02:33:00PM -0400, Gwern Branwen wrote:
My first question is, is there any way to scrap all the KeyMask plumbing? I looked at the X11 docs, but there doesn't seem to be any null modmask - mod1Mask is Alt, Shift is Shift, and so on.
KeyMask is a bitmask, so 0 is the no modifiers pressed state. I'd also leave the KeyMask argument on sendKeysym and sendKeyscreen -- some users want to send keys with modifiers (eg. the person that started this thread).
Ah. I feel a little guilty bypassing the Mod* types to plug in in a 0, but it works, it seems.
You might export a noModMask = 0.
That would work, certainly. But isn't that really the X11 library's job? Intuitively, defining noModMask in XPaste.hs feels wrong & completely out of place.
Yes, ideally it'd be in XPaste.hs; the likely reason it's not there is that it's a straight port of the C code so it's using a C-style bit mask instead of something more Haskelly like a list or set of an Enum a => a type. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

On Sat, Sep 20, 2008 at 11:37:56AM -0400, Gwern Branwen wrote:
Maybe. It's not really an issue for this code, is it? Since the type only takes Char, one cannot make it run stringToKeysym on a invalid string like "foo". And the functions lower down are in terms of Keysyms. (Although I wonder if perhaps that bit of functionality should be explored in the X11 haddocks. I didn't notice anything in particular.)
stringToKeysym will have trouble with characters outside the ASCII range. In any case, there's no sense in sending '0' KeySyms to windows. Cheers, Spencer Janssen

On 2008.09.21 01:35:08 -0500, Spencer Janssen
On Sat, Sep 20, 2008 at 11:37:56AM -0400, Gwern Branwen wrote:
Maybe. It's not really an issue for this code, is it? Since the type only takes Char, one cannot make it run stringToKeysym on a invalid string like "foo". And the functions lower down are in terms of Keysyms. (Although I wonder if perhaps that bit of functionality should be explored in the X11 haddocks. I didn't notice anything in particular.)
stringToKeysym will have trouble with characters outside the ASCII range. In any case, there's no sense in sending '0' KeySyms to windows.
Cheers, Spencer Janssen
Hm. I'd better add a warning to that effect then. -- gwern
participants (5)
-
Brandon S. Allbery KF8NH
-
Devin Mullins
-
Gwern Branwen
-
Jérémy Bobbio
-
Spencer Janssen