From fefeae79de28446d46dc21e193aa34fcd4fe9002 Mon Sep 17 00:00:00 2001 From: Jochen Keil Date: Wed, 22 Aug 2012 20:52:52 +0200 Subject: Make it possible to delay Hide, Reveal and Toggle signals Previously Hide, Reveal and Toggle were immediate actions. This is the same behaviour as if called now with 0 as parameter. If the parameter is a positive non zero value it is taken as a delay for the requested action. After the delay (implemented using threadDelay) a new signal is sent with zero with no timeout being effective immediately. This is necessary to evaluate the persistency flag after the delay because it might have changed in the meantime. Effectively this means that it is possible to cancel the delayed operation by calling TogglePersistent. --- readme.md | 3 ++- src/Plugins/BufferedPipeReader.hs | 4 ++-- src/Signal.hs | 6 +++--- src/Xmobar.hs | 25 ++++++++++++++++++------- 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/readme.md b/readme.md index 7bb7adb..f727c07 100644 --- a/readme.md +++ b/readme.md @@ -340,9 +340,10 @@ An example using the `dbus-send` command line utility: "string:Toggle" It is also possible to send multiple signals at once: + # send to another screen, reveal and toggle the persistent flag dbus-send [..] \ - "string:ChangeScreen" "string:Reveal" "string:TogglePersistent" + "string:ChangeScreen" "string:Reveal 0" "string:TogglePersistent" ## The Output Template diff --git a/src/Plugins/BufferedPipeReader.hs b/src/Plugins/BufferedPipeReader.hs index 04512e4..a2ea2a3 100644 --- a/src/Plugins/BufferedPipeReader.hs +++ b/src/Plugins/BufferedPipeReader.hs @@ -60,7 +60,7 @@ instance Exec BufferedPipeReader where writer tc ts otb = do (to, tg, dt, ntb) <- update cb dt - when tg $ putMVar signal Reveal + when tg $ putMVar signal $ Reveal 0 when (to /= 0) $ sfork $ reset to tg ts ntb writer tc ts ntb @@ -80,5 +80,5 @@ instance Exec BufferedPipeReader where reset to tg ts tb = do threadDelay ( to * 100 * 1000 ) readTVarIO tb >>= \b -> when b $ do - when tg $ putMVar signal Hide + when tg $ putMVar signal $ Hide 0 atomically (readTVar ts) >>= maybe (return ()) cb diff --git a/src/Signal.hs b/src/Signal.hs index 44fe4f9..8b3b325 100644 --- a/src/Signal.hs +++ b/src/Signal.hs @@ -36,9 +36,9 @@ instance Exception WakeUp data SignalType = Wakeup | Reposition | ChangeScreen - | Hide - | Reveal - | Toggle + | Hide Int + | Reveal Int + | Toggle Int | TogglePersistent deriving (Read, Show) diff --git a/src/Xmobar.hs b/src/Xmobar.hs index 79234d2..f531cb4 100644 --- a/src/Xmobar.hs +++ b/src/Xmobar.hs @@ -146,9 +146,9 @@ eventLoop tv xc@(XConf d _ w fs cfg) signal = do ncfg <- updateConfigPosition cfg reposWindow ncfg - Hide -> hide - Reveal -> reveal - Toggle -> toggle + Hide t -> hide (t*100*1000) + Reveal t -> reveal (t*100*1000) + Toggle t -> toggle (t*100*1000) TogglePersistent -> eventLoop tv xc { config = cfg { persistent = not $ persistent cfg } } signal @@ -156,16 +156,27 @@ eventLoop tv xc@(XConf d _ w fs cfg) signal = do where isPersistent = not $ persistent cfg - hide = when isPersistent (hideWindow d w) >> eventLoop tv xc signal + hide t | t == 0 = do + when isPersistent $ hideWindow d w + eventLoop tv xc signal + | otherwise = do + void $ forkIO + $ threadDelay t >> atomically (putTMVar signal $ Hide 0) + eventLoop tv xc signal - reveal = if isPersistent - then do + reveal t | t == 0 = + if isPersistent + then do r' <- repositionWin d w fs cfg showWindow d w eventLoop tv (XConf d r' w fs cfg) signal else eventLoop tv xc signal + | otherwise = do + void $ forkIO + $ threadDelay t >> atomically (putTMVar signal $ Reveal 0) + eventLoop tv xc signal - toggle = isMapped d w >>= \b -> if b then hide else reveal + toggle t = isMapped d w >>= \b -> if b then hide t else reveal t reposWindow rcfg = do r' <- repositionWin d w fs rcfg -- cgit v1.2.3 From a05c57f7aed141a8d6dc9038be177712be432b9d Mon Sep 17 00:00:00 2001 From: Jochen Keil Date: Wed, 22 Aug 2012 21:27:57 +0200 Subject: Configuration example for XMonad using the DBus interface Mainly code from my config which does the following: When I press my modifier key (which is xK_Alt_L) then xmobar appears. When I keep the key pressed for longer than 400ms (which is often the when tabbing through windows, changing workspaces, etc), then upon release xmobar will be hidden immediately. If I press xK_Alt_L for less than 400ms (very briefly), then xmobar pops up, and will automatically disappear after 2 seconds. --- readme.md | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/readme.md b/readme.md index f727c07..c69466e 100644 --- a/readme.md +++ b/readme.md @@ -345,6 +345,67 @@ It is also possible to send multiple signals at once: dbus-send [..] \ "string:ChangeScreen" "string:Reveal 0" "string:TogglePersistent" +### Example for using the DBus IPC interface with XMonad + +Bind the key which should {,un}map xmobar to a dummy value. This is necessary +for {,un}grabKey in xmonad. + + ((0, xK_Alt_L ), return ()) + +Also, install `avoidStruts` layout modifier from `XMonad.Hooks.ManageDocks` + +Finally, install these two event hooks (`handleEventHook` in `XConfig`) +`myDocksEventHook` is a replacement for `docksEventHook` which reacts on unmap +events as well (which `docksEventHook` doesn't). + + import qualified XMonad.Util.ExtensibleState as XS + + data DockToggleTime = DTT { lastTime :: Time } deriving (Eq, Show, Typeable) + + instance ExtensionClass DockToggleTime where + initialValue = DTT 0 + + toggleDocksHook :: Int -> KeySym -> Event -> X All + toggleDocksHook to ks ( KeyEvent { ev_event_display = d + , ev_event_type = et + , ev_keycode = ekc + , ev_time = etime + } ) = + io (keysymToKeycode d ks) >>= toggleDocks >> return (All True) + where + toggleDocks kc + | ekc == kc && et == keyPress = do + safeSendSignal ["Reveal 0", "TogglePersistent"] + XS.put ( DTT etime ) + | ekc == kc && et == keyRelease = do + gap <- XS.gets ( (-) etime . lastTime ) + safeSendSignal [ "TogglePersistent" + , "Hide " ++ show (if gap < 400 then to else 0) + ] + | otherwise = return () + + safeSendSignal s = catchX (io $ sendSignal s) (return ()) + sendSignal = withSession . callSignal + withSession mc = connectSession >>= \c -> callNoReply c mc >> disconnect c + callSignal :: [String] -> MethodCall + callSignal s = ( methodCall + ( objectPath_ "/org/Xmobar/Control" ) + ( interfaceName_ "org.Xmobar.Control" ) + ( memberName_ "SendSignal" ) + ) { methodCallDestination = Just $ busName_ "org.Xmobar.Control" + , methodCallBody = map toVariant s + } + + toggleDocksHook _ _ _ = return (All True) + + myDocksEventHook :: Event -> X All + myDocksEventHook e = do + when (et == mapNotify || et == unmapNotify) $ + whenX ((not `fmap` (isClient w)) <&&> runQuery checkDock w) refresh + return (All True) + where w = ev_window e + et = ev_event_type e + ## The Output Template -- cgit v1.2.3