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
((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.
>>, which is of type (check with
:t (>>) in
(>>) :: Monad m => m a -> m b -> m b
(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.
) in the code line with
xmonad.hs hopefully works.
(Why not learn you a Haskell for great good?)