Visual hints for XMonad actions

Hi XMonad users, I'm playing a little bit with XMonad and its primitives to see how the core works. One idea is to create a set of visible hints that the user can display when an action is taken. For example, when the user changes the workspace to the previous workspace, then a left arrow appears in the centre of the screen. Those hints are very similar to what happen on other WMs and personally very useful. With this idea in mind I started to think about requirements: they should be always visible (on top of the stack) such that the user can see them but they should be not-intrusive so that they don't disturb the work of the user. They should be removed automatically after sometime. One last thing, I would like to stick to the XMonad color configuration. I started with the left arrow. I get the code idea from XMonad.Actions.GridSelect because it shows a grid of windows or workspace using XMonad draw primitives. I created the code below which draws a left arrow in the centre of the screen and set it in my configuration such that when I move the the prev workspace, the arrow is showed and then deleted (using ((modMask, xK_Left ), drawArrow xpConfig 10 (Arrow 200 200) >> prevWS) as configuration in XMonad.hs). Before I show the code, let me say that the code (almost) works and let me make my questions: 1) is the code correct or I'm doing it in a wrong way? 2) how to put the window on top of the stack such that it is always visible. For now, for some reason the arrow is not visible when the layout is MouseResizableTile (the window is under all the not-floating windows) but it is visible with ThreeCol and Full. That's a mistery for me and I can't make any progress on that 3) how to ignore the input such that it pass trough the created window 4) the way that I use to kill the window using thread is correct? Can I do something better? 5) an open question: is there any way to use composite such that the windows can be transparent? I don't think XMonad supports composite, that's why it's an open question, but I really would like to add it and obtain some of the effects available in WM like Compiz. It's more general than what I want to do, I really would like to see the transition between screens as in compiz. Thank you, Mario data Arrow = Arrow { head_w :: Integer, head_h :: Integer } drawArrow :: XPConfig -> Integer -> Arrow -> X () drawArrow conf span (Arrow { head_w = head_w, head_h = head_h }) = gets (screenRect . W.screenDetail . W.current . windowset) >>= \s -> let half_w = div head_w 2 half_h = div head_h 2 cx = div (fromIntegral $ rect_width s) 2 cy = div (fromIntegral $ rect_height s) 2 x0 = fromIntegral $ cx - half_w - span y0 = fromIntegral $ cy - half_h - span p1 = Point (fromIntegral span) (fromIntegral $ half_h) p2 = Point (fromIntegral head_w) (fromIntegral span) p3 = Point (fromIntegral head_w) (fromIntegral head_h) in withDisplay $ \dpy -> do let dflt = defaultScreen dpy let scr = defaultScreenOfDisplay dpy rootw <- asks theRoot win <- liftIO $ mkUnmanagedWindow dpy scr rootw x0 y0 (fromInteger $ head_w + span) (fromInteger $ head_h + span) liftIO $ mapWindow dpy win gc <- liftIO $ createGC dpy win bordergc <- liftIO $ createGC dpy win liftIO $ do Just fgcolor <- initColor dpy $ fgColor conf Just bgcolor <- initColor dpy $ bgColor conf Just bordercolor <- initColor dpy $ borderColor conf setForeground dpy gc bgcolor setBackground dpy gc bgcolor fillRectangle dpy win gc 0 0 (fromIntegral $ head_w + span) (fromIntegral $ head_h + span) setForeground dpy gc fgcolor setBackground dpy gc bgcolor setForeground dpy bordergc bordercolor fillPolygon dpy win gc [p1,p2,p3] convex coordModeOrigin freeGC dpy gc freeGC dpy bordergc -- kill the window forkIO $ do threadDelay(1 * 1000000) unmapWindow dpy win destroyWindow dpy win sync dpy False return ()

On Fri, Dec 14, 2012 at 6:21 PM, Mario Pastorelli < pastorelli.mario@gmail.com> wrote:
workspace to the previous workspace, then a left arrow appears in the centre of the screen. Those hints are very similar to what happen on other WMs and personally very useful. With this idea in mind I started to think about requirements: they should be always visible (on top of the stack) such that the user can see them but they should be not-intrusive so that they don't disturb the work of the user. They should be removed automatically after sometime. One last thing, I would like to stick to the XMonad color configuration.
The place-and-remove stuff you can crib from XMonad.Layout.ShowWName. What you would place is a shaped override-redirect window (you may need to find X11 Shape extension bindings; I think these already exist somewhere but may not be in the Haskell X11 package) so that *only* the arrow will be drawn; ideally it would also have an alpha channel so it can be translucent, but that will only work if the user is also running a compositing manager. 2) how to put the window on top of the stack such that it is always
visible. For now, for some reason the arrow is
You want an override-redirect window, not a window that goes into the stack. Since you're already using mkUnmanagedWindow, this should already be true; you may also want to explicitly raiseWindow it to put it on top, and possibly something in the logHook to re-raise it as needed. 3) how to ignore the input such that it pass trough the created window
Set a zero event mask and do-not-propagate mask, so the events are passed on. 5) an open question: is there any way to use composite such that the
windows can be transparent? I don't think
You must run a separate compositing manager for this. compton is the one that seems to work best for most people. That said, just using a shaped window constrained to the arrow might be good enough. Note that you won't be able to reproduce Compiz's behavior perfectly, because it relies on OpenGL and there don't seem to be any decent standalone OpenGL compositing managers. -- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net

Wow, one of the fastest and most accurate answer I have ever had. Thank you Brandon! I'll read the docs and eventually the code of XMonad.Layout.ShowWName. On 12/15/2012 12:39 AM, Brandon Allbery wrote:
On Fri, Dec 14, 2012 at 6:21 PM, Mario Pastorelli
mailto:pastorelli.mario@gmail.com> wrote: workspace to the previous workspace, then a left arrow appears in the centre of the screen. Those hints are very similar to what happen on other WMs and personally very useful. With this idea in mind I started to think about requirements: they should be always visible (on top of the stack) such that the user can see them but they should be not-intrusive so that they don't disturb the work of the user. They should be removed automatically after sometime. One last thing, I would like to stick to the XMonad color configuration.
The place-and-remove stuff you can crib from XMonad.Layout.ShowWName. What you would place is a shaped override-redirect window (you may need to find X11 Shape extension bindings; I think these already exist somewhere but may not be in the Haskell X11 package) so that *only* the arrow will be drawn; ideally it would also have an alpha channel so it can be translucent, but that will only work if the user is also running a compositing manager.
2) how to put the window on top of the stack such that it is always visible. For now, for some reason the arrow is
You want an override-redirect window, not a window that goes into the stack. Since you're already using mkUnmanagedWindow, this should already be true; you may also want to explicitly raiseWindow it to put it on top, and possibly something in the logHook to re-raise it as needed.
3) how to ignore the input such that it pass trough the created window
Set a zero event mask and do-not-propagate mask, so the events are passed on.
5) an open question: is there any way to use composite such that the windows can be transparent? I don't think
You must run a separate compositing manager for this. compton is the one that seems to work best for most people. That said, just using a shaped window constrained to the arrow might be good enough.
Note that you won't be able to reproduce Compiz's behavior perfectly, because it relies on OpenGL and there don't seem to be any decent standalone OpenGL compositing managers.
-- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com mailto:allbery.b@gmail.com ballbery@sinenomine.net mailto:ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net

I wrote a patch for xmonad-contrib 0.10.1 to include an action to show some text in the centre of the screen. The patch is based on XMonad.Layout.ShowWName (thank you again Brandon Allbery) but it is an action and not a layout modifier. In this way it could be used to show some text when a key is pressed, for example. It includes an event handler to destroy the window after the timeout.

This 1-patch bundle was just applied to http://code.haskell.org/XMonadContrib: 20121225202635 pastorelli.mario@gmail.com * Add XMonad.Actions.ShowText -- This message was brought to you by DarcsWatch http://darcswatch.nomeata.de/repo_http:__code.haskell.org_XMonadContrib.html...

On Tue, Dec 25, 2012 at 3:51 PM, Mario Pastorelli
I wrote a patch for xmonad-contrib 0.10.1 to include an action to show some text in the centre of the screen. The patch is based on XMonad.Layout.ShowWName (thank you again Brandon Allbery) but it is an action and not a layout modifier. In this way it could be used to show some text when a key is pressed, for example. It includes an event handler to destroy the window after the timeout.
Hi Mario, I applied your patch. I also changed the type of handleTimerEvent to get the example code to typecheck: probably it will also work if the first mempty I added were a `return (All False)'. Maybe it's useful to put more (all?) arguments of flashText into the ShowTextConfig? -- Adam

Quoting Mario Pastorelli
I wrote a patch for xmonad-contrib 0.10.1 to include an action to show some text in the centre of the screen. The patch is based on XMonad.Layout.ShowWName (thank you again Brandon Allbery) but it is an action and not a layout modifier. In this way it could be used to show some text when a key is pressed, for example. It includes an event handler to destroy the window after the timeout.
Isn't this pretty much the exact use-case dzen was designed for? Just use spawn "dzen" manually, or, if you're into that kind of thing, try the module X.U.Dzen[1]. ~d [1] http://hackage.haskell.org/packages/archive/xmonad-contrib/0.10/doc/html/XMo...

Quoting Mario Pastorelli
forkIO $ do threadDelay(1 * 1000000) unmapWindow dpy win destroyWindow dpy win sync dpy False
Naively, this looks un-thread-safe to me. Only one thread is allowed to access a Display at a time; can you guarantee that the main xmonad-core thread won't be accessing dpy for some reason at the time this code runs? If not, you need to open a new display yourself in the forked thread. You might be okay by accident -- I don't think xmonad is typically linked with GHC's threaded runtime -- but I'm not sure it's a good idea to rely on that staying true in the future. ~d
participants (5)
-
adam vogt
-
Brandon Allbery
-
darcswatch@nomeata.de
-
Mario Pastorelli
-
wagnerdm@seas.upenn.edu