Copyright | Devin Mullins <me@twifkak.com> |
---|---|
License | BSD3-style (see LICENSE) |
Maintainer | Devin Mullins <me@twifkak.com> |
Stability | unstable |
Portability | unportable |
Safe Haskell | None |
Language | Haskell2010 |
UrgencyHook lets you configure an action to occur when a window demands your attention. (In traditional WMs, this takes the form of "flashing" on your "taskbar." Blech.)
Synopsis
- withUrgencyHook :: (LayoutClass l Window, UrgencyHook h) => h -> XConfig l -> XConfig l
- withUrgencyHookC :: (LayoutClass l Window, UrgencyHook h) => h -> UrgencyConfig -> XConfig l -> XConfig l
- data UrgencyConfig = UrgencyConfig {}
- urgencyConfig :: UrgencyConfig
- data SuppressWhen
- data RemindWhen
- focusUrgent :: X ()
- clearUrgents :: X ()
- dzenUrgencyHook :: DzenUrgencyHook
- data DzenUrgencyHook = DzenUrgencyHook {}
- data NoUrgencyHook = NoUrgencyHook
- newtype BorderUrgencyHook = BorderUrgencyHook {}
- data FocusHook = FocusHook
- filterUrgencyHook :: [WorkspaceId] -> Window -> X ()
- filterUrgencyHook' :: Query Bool -> Window -> X ()
- minutes :: Rational -> Rational
- seconds :: Rational -> Int
- askUrgent :: Window -> X ()
- doAskUrgent :: ManageHook
- readUrgents :: X [Window]
- withUrgents :: ([Window] -> X a) -> X a
- clearUrgents' :: [Window] -> X ()
- data StdoutUrgencyHook = StdoutUrgencyHook
- newtype SpawnUrgencyHook = SpawnUrgencyHook String
- class UrgencyHook h where
- urgencyHook :: h -> Window -> X ()
- type Interval = Rational
- borderUrgencyHook :: String -> Window -> X ()
- focusHook :: Window -> X ()
- spawnUrgencyHook :: String -> Window -> X ()
- stdoutUrgencyHook :: Window -> X ()
Usage
To wire this up, first add:
import XMonad.Hooks.UrgencyHook
to your import list in your config file. Now, you have a decision to make: When a window deems itself urgent, do you want to pop up a temporary dzen bar telling you so, or do you have an existing dzen wherein you would like to highlight urgent workspaces?
Pop up a temporary dzen
Enable your urgency hook by wrapping your config record in a call to
withUrgencyHook
. For example:
main = xmonad $ withUrgencyHook dzenUrgencyHook { args = ["-bg", "darkgreen", "-xs", "1"] } $ def
This will pop up a dzen bar for five seconds telling you you've got an urgent window.
Highlight in existing dzen
In order for xmonad to track urgent windows, you must install an urgency hook.
You can use the above dzenUrgencyHook
, or if you're not interested in the
extra popup, install NoUrgencyHook, as so:
main = xmonad $ withUrgencyHook NoUrgencyHook $ def
Now, your XMonad.Hooks.StatusBar.PP must be set up to display the urgent
windows. If you're using the dzen
(from XMonad.Hooks.DynamicLog) or
dzenPP
functions from that module, then you should be good. Otherwise,
you want to figure out how to set ppUrgent
.
Useful keybinding
You can set up a keybinding to jump to the window that was recently marked
urgent. See an example at focusUrgent
.
Troubleshooting
There are three steps to get right:
The X client must set the UrgencyHint flag. How to configure this depends on the application. If you're using a terminal app, this is in two parts:
- The console app must send a ^G (bell). In bash, a helpful trick is
sleep 1; echo -e '\a'
. - The terminal must convert the bell into UrgencyHint.
- The console app must send a ^G (bell). In bash, a helpful trick is
- XMonad must be configured to notice UrgencyHints. If you've added withUrgencyHook, you may need to hit mod-shift-space to reset the layout.
- The dzen must run when told. Run
dzen2 -help
and make sure that it supports all of the arguments you told DzenUrgencyHook to pass it. Also, set up a keybinding to thedzen
action in XMonad.Util.Dzen to test if that works.
As best you can, try to isolate which one(s) of those is failing.
Example: Setting up irssi + rxvt-unicode
This is a commonly asked example. By default, the window doesn't get flagged urgent when somebody messages you in irssi. You will have to configure some things. If you're using different tools than this, your mileage will almost certainly vary. (For example, in Xchat2, it's just a simple checkbox.)
Configuring irssi
Irssi
is not an X11 app, so it can't set the UrgencyHint
flag on XWMHints
.
However, on all console applications is bestown the greatest of all notification
systems: the bell. That's right, Ctrl+G, ASCII code 7, echo -e 'a'
, your
friend, the bell. To configure irssi
to send a bell when you receive a message:
/set beep_msg_level MSGS NOTICES INVITES DCC DCCMSGS HILIGHT
Consult your local irssi
documentation for more detail.
Configuring screen
A common way to run irssi
is within the lovable giant, screen
. Some distros
(e.g. Ubuntu) like to configure screen
to trample on your poor console
applications -- in particular, to turn bell characters into evil, smelly
"visual bells." To turn this off, add:
vbell off # or remove the existing 'vbell on' line
to your .screenrc, or hit C-a C-g
within a running screen
session for an
immediate but temporary fix.
Configuring rxvt-unicode
Rubber, meet road. Urxvt is the gateway between console apps and X11. To tell
urxvt to set an UrgencyHint
when it receives a bell character, first, have
an urxvt version 8.3 or newer, and second, set the following in your
.Xdefaults
:
urxvt.urgentOnBell: true
Depending on your setup, you may need to xrdb
that.
Configuring xmonad
Hopefully you already read the section on how to configure xmonad. If not, hopefully you know where to find it.
Stuff for your config file:
withUrgencyHook :: (LayoutClass l Window, UrgencyHook h) => h -> XConfig l -> XConfig l Source #
This is the method to enable an urgency hook. It uses the default
urgencyConfig
to control behavior. To change this, use withUrgencyHookC
instead.
withUrgencyHookC :: (LayoutClass l Window, UrgencyHook h) => h -> UrgencyConfig -> XConfig l -> XConfig l Source #
This lets you modify the defaults set in urgencyConfig
. An example:
withUrgencyHookC dzenUrgencyHook { ... } urgencyConfig { suppressWhen = Focused }
(Don't type the ...
, you dolt.) See UrgencyConfig
for details on configuration.
data UrgencyConfig Source #
Global configuration, applied to all types of UrgencyHook
. See
urgencyConfig
for the defaults.
UrgencyConfig | |
|
Instances
Read UrgencyConfig Source # | |
Defined in XMonad.Hooks.UrgencyHook readsPrec :: Int -> ReadS UrgencyConfig # readList :: ReadS [UrgencyConfig] # | |
Show UrgencyConfig Source # | |
Defined in XMonad.Hooks.UrgencyHook showsPrec :: Int -> UrgencyConfig -> ShowS # show :: UrgencyConfig -> String # showList :: [UrgencyConfig] -> ShowS # |
urgencyConfig :: UrgencyConfig Source #
The default UrgencyConfig
. suppressWhen = Visible, remindWhen = Dont.
Use a variation of this in your config just as you use a variation of
def
for your xmonad definition.
data SuppressWhen Source #
A set of choices as to when you should (or rather, shouldn't) be notified of an urgent window.
The default is Visible
. Prefix each of the following with "don't bug me when":
Visible | the window is currently visible |
OnScreen | the window is on the currently focused physical screen |
Focused | the window is currently focused |
Never | ... aww, heck, go ahead and bug me, just in case. |
Instances
Read SuppressWhen Source # | |
Defined in XMonad.Hooks.UrgencyHook readsPrec :: Int -> ReadS SuppressWhen # readList :: ReadS [SuppressWhen] # | |
Show SuppressWhen Source # | |
Defined in XMonad.Hooks.UrgencyHook showsPrec :: Int -> SuppressWhen -> ShowS # show :: SuppressWhen -> String # showList :: [SuppressWhen] -> ShowS # |
data RemindWhen Source #
A set of choices as to when you want to be re-notified of an urgent window. Perhaps you focused on something and you miss the dzen popup bar. Or you're AFK. Or you feel the need to be more distracted. I don't care.
The interval arguments are in seconds. See the minutes
helper.
Dont | triggering once is enough |
Repeatedly Int Interval | |
Every Interval | repeat every arg1 until the urgency hint is cleared |
Instances
Read RemindWhen Source # | |
Defined in XMonad.Hooks.UrgencyHook readsPrec :: Int -> ReadS RemindWhen # readList :: ReadS [RemindWhen] # readPrec :: ReadPrec RemindWhen # readListPrec :: ReadPrec [RemindWhen] # | |
Show RemindWhen Source # | |
Defined in XMonad.Hooks.UrgencyHook showsPrec :: Int -> RemindWhen -> ShowS # show :: RemindWhen -> String # showList :: [RemindWhen] -> ShowS # |
focusUrgent :: X () Source #
Focuses the most recently urgent window. Good for what ails ya -- I mean, your keybindings. Example keybinding:
, ((modm , xK_BackSpace), focusUrgent)
clearUrgents :: X () Source #
Just makes the urgents go away. Example keybinding:
, ((modm .|. shiftMask, xK_BackSpace), clearUrgents)
dzenUrgencyHook :: DzenUrgencyHook Source #
Flashes when a window requests your attention and you can't see it.
Defaults to a duration of five seconds, and no extra args to dzen.
See DzenUrgencyHook
.
data DzenUrgencyHook Source #
Your set of options for configuring a dzenUrgencyHook.
Instances
Read DzenUrgencyHook Source # | |
Defined in XMonad.Hooks.UrgencyHook | |
Show DzenUrgencyHook Source # | |
Defined in XMonad.Hooks.UrgencyHook showsPrec :: Int -> DzenUrgencyHook -> ShowS # show :: DzenUrgencyHook -> String # showList :: [DzenUrgencyHook] -> ShowS # | |
UrgencyHook DzenUrgencyHook Source # | |
Defined in XMonad.Hooks.UrgencyHook urgencyHook :: DzenUrgencyHook -> Window -> X () Source # |
data NoUrgencyHook Source #
Instances
Read NoUrgencyHook Source # | |
Defined in XMonad.Hooks.UrgencyHook readsPrec :: Int -> ReadS NoUrgencyHook # readList :: ReadS [NoUrgencyHook] # | |
Show NoUrgencyHook Source # | |
Defined in XMonad.Hooks.UrgencyHook showsPrec :: Int -> NoUrgencyHook -> ShowS # show :: NoUrgencyHook -> String # showList :: [NoUrgencyHook] -> ShowS # | |
UrgencyHook NoUrgencyHook Source # | |
Defined in XMonad.Hooks.UrgencyHook urgencyHook :: NoUrgencyHook -> Window -> X () Source # |
newtype BorderUrgencyHook Source #
Instances
Read BorderUrgencyHook Source # | |
Defined in XMonad.Hooks.UrgencyHook | |
Show BorderUrgencyHook Source # | |
Defined in XMonad.Hooks.UrgencyHook showsPrec :: Int -> BorderUrgencyHook -> ShowS # show :: BorderUrgencyHook -> String # showList :: [BorderUrgencyHook] -> ShowS # | |
UrgencyHook BorderUrgencyHook Source # | |
Defined in XMonad.Hooks.UrgencyHook urgencyHook :: BorderUrgencyHook -> Window -> X () Source # |
filterUrgencyHook :: [WorkspaceId] -> Window -> X () Source #
urgencyhook such that windows on certain workspaces never get urgency set.
Useful for scratchpad workspaces perhaps:
main = xmonad (withUrgencyHook (filterUrgencyHook ["NSP", "SP"]) def)
filterUrgencyHook' :: Query Bool -> Window -> X () Source #
filterUrgencyHook
that takes a generic Query
to select which windows
should never be marked urgent.
minutes :: Rational -> Rational Source #
A prettified way of multiplying by 60. Use like: (5
.minutes
)
seconds :: Rational -> Int Source #
Multiplies by ONE MILLION, for functions that take microseconds.
Use like:
(5.5 `seconds`)
In GHC 7 and later, you must either enable the PostfixOperators extension (by adding
{-# LANGUAGE PostfixOperators #-}
to the top of your file) or use seconds in prefix form:
seconds 5.5
askUrgent :: Window -> X () Source #
Mark the given window urgent.
(The implementation is a bit hacky: send a _NET_WM_STATE ClientMessage to
ourselves. This is so that we respect the SuppressWhen
of the configured
urgency hooks. If this module if ever migrated to the ExtensibleConf
infrastrcture, we'll then invoke markUrgent directly.)
doAskUrgent :: ManageHook Source #
Helper for ManageHook
that marks the window as urgent (unless
suppressed, see SuppressWhen
). Useful in
setEwmhActivateHook
and also in combination
with XMonad.Hooks.InsertPosition, XMonad.Hooks.Focus.
Stuff for developers:
readUrgents :: X [Window] Source #
X action that returns a list of currently urgent windows. You might use
it, or withUrgents
, in your custom logHook, to display the workspaces that
contain urgent windows.
withUrgents :: ([Window] -> X a) -> X a Source #
An HOF version of readUrgents
, for those who prefer that sort of thing.
clearUrgents' :: [Window] -> X () Source #
Clear urgency status of selected windows.
data StdoutUrgencyHook Source #
Instances
Read StdoutUrgencyHook Source # | |
Defined in XMonad.Hooks.UrgencyHook | |
Show StdoutUrgencyHook Source # | |
Defined in XMonad.Hooks.UrgencyHook showsPrec :: Int -> StdoutUrgencyHook -> ShowS # show :: StdoutUrgencyHook -> String # showList :: [StdoutUrgencyHook] -> ShowS # | |
UrgencyHook StdoutUrgencyHook Source # | |
Defined in XMonad.Hooks.UrgencyHook urgencyHook :: StdoutUrgencyHook -> Window -> X () Source # |
newtype SpawnUrgencyHook Source #
Instances
Read SpawnUrgencyHook Source # | |
Defined in XMonad.Hooks.UrgencyHook | |
Show SpawnUrgencyHook Source # | |
Defined in XMonad.Hooks.UrgencyHook showsPrec :: Int -> SpawnUrgencyHook -> ShowS # show :: SpawnUrgencyHook -> String # showList :: [SpawnUrgencyHook] -> ShowS # | |
UrgencyHook SpawnUrgencyHook Source # | |
Defined in XMonad.Hooks.UrgencyHook urgencyHook :: SpawnUrgencyHook -> Window -> X () Source # |
class UrgencyHook h where Source #
The class definition, and some pre-defined instances.
urgencyHook :: h -> Window -> X () Source #
Instances
UrgencyHook StdoutUrgencyHook Source # | |
Defined in XMonad.Hooks.UrgencyHook urgencyHook :: StdoutUrgencyHook -> Window -> X () Source # | |
UrgencyHook SpawnUrgencyHook Source # | |
Defined in XMonad.Hooks.UrgencyHook urgencyHook :: SpawnUrgencyHook -> Window -> X () Source # | |
UrgencyHook BorderUrgencyHook Source # | |
Defined in XMonad.Hooks.UrgencyHook urgencyHook :: BorderUrgencyHook -> Window -> X () Source # | |
UrgencyHook FocusHook Source # | |
Defined in XMonad.Hooks.UrgencyHook | |
UrgencyHook DzenUrgencyHook Source # | |
Defined in XMonad.Hooks.UrgencyHook urgencyHook :: DzenUrgencyHook -> Window -> X () Source # | |
UrgencyHook NoUrgencyHook Source # | |
Defined in XMonad.Hooks.UrgencyHook urgencyHook :: NoUrgencyHook -> Window -> X () Source # | |
UrgencyHook (Window -> X ()) Source # | |
Defined in XMonad.Hooks.UrgencyHook |
borderUrgencyHook :: String -> Window -> X () Source #
A hook that sets the border color of an urgent window. The color will remain until the next time the window gains or loses focus, at which point the standard border color from the XConfig will be applied. You may want to use suppressWhen = Never with this:
withUrgencyHookC BorderUrgencyHook { urgencyBorderColor = "#ff0000" } urgencyConfig { suppressWhen = Never } ...
(This should be urgentBorderColor
but that breaks XMonad.Layout.Decoration.
borderColor
breaks anyone using XPConfig
from XMonad.Prompt. We need to
think a bit more about namespacing issues, maybe.)
focusHook :: Window -> X () Source #
A hook which will automatically send you to anything which sets the urgent flag (as opposed to printing some sort of message. You would use this as usual, eg.
withUrgencyHook FocusHook $ myconfig { ...
spawnUrgencyHook :: String -> Window -> X () Source #
Spawn a commandline thing, appending the window id to the prefix string you provide. (Make sure to add a space if you need it.) Do your crazy xcompmgr thing.
stdoutUrgencyHook :: Window -> X () Source #
For debugging purposes, really.