Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm using a few key mappings in my xmonad.hs configuration file:

    , modMask = mod4Mask     -- Rebind Mod to the Windows key
 [ ((controlMask, xK_Print), spawn "sleep 0.2; scrot -s")
 , ((0, xK_Print), spawn "scrot")
 , ((controlMask, xK_f), spawn "firefox")

The third mapping runs firefox when pressing ctrl+f. I'd like to do something more complex:

if (firefox is running):
  focus and maximize firefox window:
  run firefox

And I'd like to change ctrl+f to win+f. How can I do that?

share|improve this question
Is crossposting like this (here and on stackoverflow) really an usual business? – ДМИТРИЙ МАЛИКОВ Nov 11 '11 at 19:55
No: it is actively discouraged... – jasonwryan Nov 11 '11 at 19:58
It's off-topic on SO, so I asked them to get rid of their copy – Michael Mrozek Nov 11 '11 at 20:04
@dmitry.malikov This seems to be better place for the question. – xralf Nov 11 '11 at 20:04
Even better; xralf deleted the SO copy. Many thanks – Michael Mrozek Nov 11 '11 at 20:06
up vote 6 down vote accepted

Looking at XMonad's contrib packages, you'll find XMonad.Actions.WindowGo, which exports the following function:

runOrRaiseMaster :: String -> Query Bool -> X ()

which takes a string argument of the program to run, e.g. "firefox"; and a boolean query that is used to find out if it is already running, via X11 properties, e.g. (className =? "Firefox") (see top of the XMonad.Actions.WindowGo page for variants).

So, all you need is to bind runOrRaiseMaster "firefox" (className =? "Firefox") to the key you want, as explained in XMonad.Doc.Extending, via

((modMask, xK_f ), runOrRaiseMaster "firefox" (className =? "Firefox"))

as part of the key bindings Data.Map of your configuration (details differ with your way of settings this up, i.e, the whole of your xmonad.hs, see Adding Keybindings).

Note that there is no real sense in maximizing a window in XMonad. When you set things up as explained, you'll have Mod4+f act as follows:

  • if there's a window with a classname matching "Firefox", it will be focused and set to master, i.e., depending on your recent layout, will be the big window
  • if no window matches, Firefox will be spawned and set to master.

Maximizing can be emulated by choosing the Full layout after calling runOrRaiseMaster, as is described here:

("M-<F1>", sendMessage $ JumpToLayout "Full")

(note that this example also demonstrates XMonad.Util.EZConfig allowing easier keybinding definitions)

Combining these two things is possible, too. Both are of type X (), i.e., they are in the X Monad. Using >>, which is of type (check with :t (>>) in ghci)

(>>) :: Monad m => m a -> m b -> m b

we have (runOrRaiseMaster "firefox" (className =? "Firefox")) >> (sendMessage $ JumpToLayout "Full") as a combination of two X () types of type X (), too, and it can thus be bound to a key.

EDIT Missing ) in the code line with >>

Edit2 modm -> modMask.

Edit3 This xmonad.hs hopefully works.

(Why not learn you a Haskell for great good?)

share|improve this answer
Thank you for working answer and other information and Haskell tutorial. I like Haskell syntax and functional paradigm. The only thing that doesn't work is the part >> (sendMessage $ JumptoLayout "Full") there is some error with constructor. Maybe it's something easy, that I will solve after learning Haskell. – xralf Nov 24 '11 at 13:08
I forgot : Yet the modm doesn't work, I'm still using controlMask. – xralf Nov 24 '11 at 13:10
@xralf, (1) there was a missing bracket - does it work now? (2) I'd need your whole xmonad.hs to fix this; better just have a look around here, the config archive and see how others do it or use the mentioned EZConfig. – sr_ Nov 24 '11 at 14:17
The bracket did not helped. Here is the xmonad.hs file I'm using. – xralf Nov 24 '11 at 16:13
(1) The brackets are still wrong, the action of type X () to bind to the key should be (runOrRaiseMaster ...) >> (sendMessage ...), resulting in ,((...,...), (runOrR...) >> (send...) ) (a ( before run...) – sr_ Nov 24 '11 at 16:44

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.