From oneself at gmail.com Mon Mar 13 17:40:32 2023 From: oneself at gmail.com (Eyal Erez) Date: Mon, 13 Mar 2023 19:40:32 +0200 Subject: [xmonad] xmobar dynamic spacing Message-ID: Hi, I hope that this is the right place to ask. If not, please let me know. I use xmonad with xmobar and trayer. Trayer is set in the upper right corner, and xmobar fills the remainder of the top of the screen. I have several right-aligned widgets, including date/time, CPU, memory, network, etc., and two left-aligned widgets, which are the active workspace name and the name of the active window. Currently, I set the name of the active window to "shorten 200" in my xmonad.hs file. However, I use several monitors with varying screen sizes, so it is challenging to set an absolute value. When the screen is narrow, and the window title is long, it pushes some widgets out of the right side of xmobar. I would like the window title to take up as much space as possible but leave the other right-aligned widgets where they are. Is there any way to do that? Short window title [image: image.png] Long window title [image: image.png] -- There are 10 types of people, those who know binary and those who don't. -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image.png Type: image/png Size: 8383 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image.png Type: image/png Size: 8203 bytes Desc: not available URL: From sasoiliev+xmonad at mamul.org Tue Mar 14 22:03:55 2023 From: sasoiliev+xmonad at mamul.org (Alexander Iliev) Date: Wed, 15 Mar 2023 00:03:55 +0200 Subject: [xmonad] Resize NamedScratchpad with respect to screen size Message-ID: <41226223-4634-43fb-6e2c-757fea025035@mamul.org> Hi all, I have several NamedScratchpads defined in my XMonad configuration, and so far I've been using a manage hook like: customFloating $ W.RationalRect (1/2) (1/8) (1/2) (3/4) This made sense while I had monitors with similar resolution. I recently got a new monitor and now my two monitors have vastly different resolutions - one is 1920x1080, the other one is 3840x1600. So here's my issue - the RationalRect above doesn't make sense for both monitors. It still works fine on the smaller one, on the larger however it results in ridiculously a wide window. My question is - can I resize the scratchpad window I'm pulling into the current workspace with respect to the size of the screen that this workspace is displayed on? Thank you! Kind regards, -- alexander iliev From allbery.b at gmail.com Tue Mar 14 22:07:21 2023 From: allbery.b at gmail.com (Brandon Allbery) Date: Tue, 14 Mar 2023 18:07:21 -0400 Subject: [xmonad] Resize NamedScratchpad with respect to screen size In-Reply-To: <41226223-4634-43fb-6e2c-757fea025035@mamul.org> References: <41226223-4634-43fb-6e2c-757fea025035@mamul.org> Message-ID: On Tue, Mar 14, 2023 at 6:04 PM Alexander Iliev wrote: > My question is - can I resize the scratchpad window I'm pulling into the > current workspace with respect to the size of the screen that this > workspace is displayed on? Currently there is no control over this. It's not impossible, but would require a `handleEventHook` to catch the `MapNotifyEvent` for the `NamedScratchpad` window and resize it. -- brandon s allbery kf8nh allbery.b at gmail.com From soliditsallgood at mailbox.org Tue Mar 14 22:17:09 2023 From: soliditsallgood at mailbox.org (Tony Zorman) Date: Tue, 14 Mar 2023 23:17:09 +0100 Subject: [xmonad] Resize NamedScratchpad with respect to screen size In-Reply-To: References: <41226223-4634-43fb-6e2c-757fea025035@mamul.org> Message-ID: <87lejzvuze.fsf@hyperspace> On Tue, Mar 14 2023 18:07, Brandon Allbery wrote: > On Tue, Mar 14, 2023 at 6:04 PM Alexander Iliev > wrote: >> My question is - can I resize the scratchpad window I'm pulling into the >> current workspace with respect to the size of the screen that this >> workspace is displayed on? > > Currently there is no control over this. It's not impossible, but > would require a `handleEventHook` to catch the `MapNotifyEvent` for > the `NamedScratchpad` window and resize it. Alternatively, it should also be possible to check the currently focused window in a logHook and do this based on that. See `X.U.NamedScratchpad.nsHideOnFocusLoss` for inspiration. -- Tony Zorman | https://tony-zorman.com/ From sasoiliev+xmonad at mamul.org Tue Mar 14 22:18:52 2023 From: sasoiliev+xmonad at mamul.org (Alexander Iliev) Date: Wed, 15 Mar 2023 00:18:52 +0200 Subject: [xmonad] Resize NamedScratchpad with respect to screen size In-Reply-To: References: <41226223-4634-43fb-6e2c-757fea025035@mamul.org> Message-ID: On 3/15/23 00:07, Brandon Allbery wrote: > Currently there is no control over this. It's not impossible, but > would require a `handleEventHook` to catch the `MapNotifyEvent` for > the `NamedScratchpad` window and resize it. > I see. I'll have a look, although I doubt that both my Haskell and my XMonad skills will be sufficient for me to successfully accomplish this. Thanks, Brandon. -- alexander iliev From allbery.b at gmail.com Tue Mar 14 22:21:00 2023 From: allbery.b at gmail.com (Brandon Allbery) Date: Tue, 14 Mar 2023 18:21:00 -0400 Subject: [xmonad] Resize NamedScratchpad with respect to screen size In-Reply-To: References: <41226223-4634-43fb-6e2c-757fea025035@mamul.org> Message-ID: You might be able to glean some inspiration from https://github.com/geekosaur/xmonad.hs/blob/skkukuk/xmonad.hs#L301-L313 which is hackily catching my notification windows currently. On Tue, Mar 14, 2023 at 6:18 PM Alexander Iliev wrote: > > On 3/15/23 00:07, Brandon Allbery wrote: > > Currently there is no control over this. It's not impossible, but > > would require a `handleEventHook` to catch the `MapNotifyEvent` for > > the `NamedScratchpad` window and resize it. > > > > I see. I'll have a look, although I doubt that both my Haskell and my > XMonad skills will be sufficient for me to successfully accomplish this. > > Thanks, Brandon. > > -- > alexander iliev > -- brandon s allbery kf8nh allbery.b at gmail.com From rdiaz02 at gmail.com Fri Mar 24 12:30:07 2023 From: rdiaz02 at gmail.com (Ramon Diaz-Uriarte) Date: Fri, 24 Mar 2023 13:30:07 +0100 Subject: [xmonad] XM.A.UpdatePointer interferes with XM.A.TiledWindowDragging? Message-ID: <87lejm9vpn.fsf@gmail.com> Dear All, When I use XMonad.Actions.UpdatePointer, window dragging no longer works. If I do not use XM.A.UpdatePointer, window dragging works. Details: These are (what I think are) the relevant pieces from my xmonad.hs: (...) import XMonad.Actions.UpdatePointer import XMonad.Actions.TiledWindowDragging import XMonad.Layout.DraggingVisualizer (...) myConfig myWorkspaces = def { (...) , logHook = refocusLastLogHook <+> logHook def >> updatePointer (0.5, 0.5) (0.1, 0.1) } `additionalKeysP` myKeys2 `additionalMouseBindings` [((mod4Mask, 2), dragWindow)] --drag with mod + center button With the above, window dragging no longer works. However, if I comment out ">> updatePointer (0.5, 0.5) (0.1, 0.1)" window dragging works again. Am I doing something wrong? I've searched, and have not seen this mentioned (TiledWindowDragging is mentioned in relation to UpdatePointer here: https://github.com/xmonad/xmonad-contrib/issues/566#issuecomment-869240906, but it seemed a different issue) I am using xmonad and xmonad-contrib, both from master branches, updated as of today (2023-03-24): latest commits are 386d4e and e60805b for xmonad and xmonad-contrib, respectively. Best, -- Ramon Diaz-Uriarte Department of Biochemistry, Lab B-31 Facultad de Medicina Universidad Autónoma de Madrid Arzobispo Morcillo, 4 28029 Madrid Spain Phone: +34-91-497-2412 Email: rdiaz02 at gmail.com r.diaz at uam.es ramon.diaz at iib.uam.es https://ligarto.org/rdiaz From allbery.b at gmail.com Fri Mar 24 14:04:35 2023 From: allbery.b at gmail.com (Brandon Allbery) Date: Fri, 24 Mar 2023 10:04:35 -0400 Subject: [xmonad] XM.A.UpdatePointer interferes with XM.A.TiledWindowDragging? In-Reply-To: <87lejm9vpn.fsf@gmail.com> References: <87lejm9vpn.fsf@gmail.com> Message-ID: I think that would not be surprising; we needed to update xmonad's internal state, including running the `logHook`, during drags to avoid other bugs. (https://github.com/xmonad/xmonad/commit/4565e2c90ef522d23d3afc2cf95b9f0b423d8de4) Not sure what to do about this. On Fri, Mar 24, 2023 at 8:32 AM Ramon Diaz-Uriarte wrote: > > Dear All, > > When I use XMonad.Actions.UpdatePointer, window dragging no longer works. If I do not use XM.A.UpdatePointer, window dragging works. > > > Details: > > These are (what I think are) the relevant pieces from my xmonad.hs: > > > (...) > import XMonad.Actions.UpdatePointer > import XMonad.Actions.TiledWindowDragging > import XMonad.Layout.DraggingVisualizer > > (...) > > myConfig myWorkspaces = def { > (...) > , logHook = refocusLastLogHook <+> logHook def >> updatePointer (0.5, 0.5) (0.1, 0.1) > } `additionalKeysP` myKeys2 > `additionalMouseBindings` > [((mod4Mask, 2), dragWindow)] --drag with mod + center button > > > > With the above, window dragging no longer works. However, if I comment out ">> updatePointer (0.5, 0.5) (0.1, 0.1)" window dragging works again. > > > Am I doing something wrong? I've searched, and have not seen this mentioned (TiledWindowDragging is mentioned in relation to UpdatePointer here: https://github.com/xmonad/xmonad-contrib/issues/566#issuecomment-869240906, but it seemed a different issue) > > > I am using xmonad and xmonad-contrib, both from master branches, updated as of today (2023-03-24): latest commits are 386d4e and e60805b for xmonad and xmonad-contrib, respectively. > > > Best, > > > > > -- > Ramon Diaz-Uriarte > Department of Biochemistry, Lab B-31 > Facultad de Medicina > Universidad Autónoma de Madrid > Arzobispo Morcillo, 4 > 28029 Madrid > Spain > > Phone: +34-91-497-2412 > > Email: rdiaz02 at gmail.com > r.diaz at uam.es > ramon.diaz at iib.uam.es > > https://ligarto.org/rdiaz > > > _______________________________________________ > xmonad mailing list > xmonad at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/xmonad -- brandon s allbery kf8nh allbery.b at gmail.com From oneself at gmail.com Fri Mar 24 14:06:41 2023 From: oneself at gmail.com (Eyal Erez) Date: Fri, 24 Mar 2023 17:06:41 +0300 Subject: [xmonad] xmobar dynamic spacing Message-ID: Spam detection software, running on the system "mail.haskell.org", has identified this incoming email as possible spam. The original message has been attached to this so you can view it (if it isn't spam) or label similar future email. If you have any questions, see @@CONTACT_ADDRESS@@ for details. Content preview: Any advice would be greatly appreciated. Also, are there any recommended alternatives to xmobar? On Mon, Mar 13, 2023 at 7:40 PM Eyal Erez wrote: > Hi, > > I hope that this is the right place to ask. If not, please let me know. > > I use xmonad with xmobar and trayer. Trayer is set in the upper right > corner, and xmobar fills the remainder of the top of the screen. I have > several right-aligned widgets, including date/time, CPU, memory, network, > etc., and two left-aligned widgets, which are the active workspace name and > the name of the active window. Currently, I set the name of the active > window to "shorten 200" in my xmonad.hs file. However, I use several > monitors with varying screen sizes, so it is challenging to set an > absolute value. When the screen is narrow, and the window title is long, it > pushes some widgets out of the right side of xmobar. I would like the > window title to take up as much space as possible but leave the other > right-aligned widgets where they are. Is there any way to do that? > > Short window title > [image: image.png] > > Long window title > [image: image.png] > > -- > There are 10 types of people, those who know binary and those who don't. > > [...] Content analysis details: (5.1 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (oneself[at]gmail.com) -0.0 SPF_PASS SPF: sender matches SPF record 1.4 HTML_IMAGE_ONLY_28 BODY: HTML: images with 2400-2800 bytes of words 0.0 HTML_MESSAGE BODY: HTML included in message 1.0 HTML_FONT_FACE_BAD BODY: HTML font face is not a word 0.8 BAYES_50 BODY: Bayes spam probability is 40 to 60% [score: 0.5000] 0.0 T_DKIM_INVALID DKIM-Signature header exists but is not valid 1.9 FREEMAIL_REPLY From and body contain different freemails The original message was not completely plain text, and may be unsafe to open with some email clients; in particular, it may contain a virus, or confirm that your address can receive spam. If you wish to view it, it may be safer to save it to a file and open it with an editor. -------------- next part -------------- An embedded message was scrubbed... From: Eyal Erez Subject: Re: xmobar dynamic spacing Date: Fri, 24 Mar 2023 17:06:41 +0300 Size: 29926 URL: From allbery.b at gmail.com Fri Mar 24 14:11:56 2023 From: allbery.b at gmail.com (Brandon Allbery) Date: Fri, 24 Mar 2023 10:11:56 -0400 Subject: [xmonad] xmobar dynamic spacing In-Reply-To: References: Message-ID: Polybar is a popular alternative. I'll have to dig the rest of your message out of the spamtrap :/ (or more likely let someone more familiar with xmobar do it) but xmobar isn't really good at dynamic spacing. On Fri, Mar 24, 2023 at 10:07 AM Eyal Erez wrote: > > Spam detection software, running on the system "mail.haskell.org", has > identified this incoming email as possible spam. The original message > has been attached to this so you can view it (if it isn't spam) or label > similar future email. If you have any questions, see > @@CONTACT_ADDRESS@@ for details. > > Content preview: Any advice would be greatly appreciated. Also, are there any > recommended alternatives to xmobar? On Mon, Mar 13, 2023 at 7:40 PM Eyal > Erez wrote: > Hi, > > I hope that this is the right place to ask. If not, > please let me know. > > I use xmonad with xmobar and trayer. Trayer is set > in the upper right > corner, and xmobar fills the remainder of the top of > the screen. I have > several right-aligned widgets, including date/time, > CPU, memory, network, > etc., and two left-aligned widgets, which are the > active workspace name and > the name of the active window. Currently, I set > the name of the active > window to "shorten 200" in my xmonad.hs file. However, > I use several > monitors with varying screen sizes, so it is challenging > to set an > absolute value. When the screen is narrow, and the window title > is long, it > pushes some widgets out of the right side of xmobar. I would > like the > window title to take up as much space as possible but leave the > other > right-aligned widgets where they are. Is there any way to do that? > > > Short window title > [image: image.png] > > Long window title > [image: > image.png] > > -- > There are 10 types of people, those who know binary and > those who don't. > > [...] > > Content analysis details: (5.1 points, 5.0 required) > > pts rule name description > ---- ---------------------- -------------------------------------------------- > 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider > (oneself[at]gmail.com) > -0.0 SPF_PASS SPF: sender matches SPF record > 1.4 HTML_IMAGE_ONLY_28 BODY: HTML: images with 2400-2800 bytes of words > 0.0 HTML_MESSAGE BODY: HTML included in message > 1.0 HTML_FONT_FACE_BAD BODY: HTML font face is not a word > 0.8 BAYES_50 BODY: Bayes spam probability is 40 to 60% > [score: 0.5000] > 0.0 T_DKIM_INVALID DKIM-Signature header exists but is not valid > 1.9 FREEMAIL_REPLY From and body contain different freemails > > The original message was not completely plain text, and may be unsafe to > open with some email clients; in particular, it may contain a virus, > or confirm that your address can receive spam. If you wish to view > it, it may be safer to save it to a file and open it with an editor. > > _______________________________________________ > xmonad mailing list > xmonad at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/xmonad -- brandon s allbery kf8nh allbery.b at gmail.com From platon7pronko at gmail.com Fri Mar 24 14:23:41 2023 From: platon7pronko at gmail.com (Platon Pronko) Date: Fri, 24 Mar 2023 22:23:41 +0800 Subject: [xmonad] XM.A.UpdatePointer interferes with XM.A.TiledWindowDragging? In-Reply-To: References: <87lejm9vpn.fsf@gmail.com> Message-ID: <754f9f08-8e6c-870c-3db6-40acd8d360c6@gmail.com> Hi! Seems the issue is that the pointer is warped back to the initial dragged window position before TiledWindowDragging updates the focused window, and thus no window switching is happening (because from the point of view of TiledWindowDragging the window was never dragged anywhere). As Brandon said, logHook is called on every internal state update, so UpdatePointer tries to update the pointer all the time, even in-between drag end and focus change. `updatePointer` contains some guards that are trying to detect common scenarios and prevent updating in such cases, but as we see it doesn't work perfectly. I suppose `updatePointer` should run only when it explicitly detects the window focus change event, instead of running all the time (maybe some manageHook wrapper?). That said, I found a (quite hacky) way to achieve what you want without rewriting UpdatePointer. The idea is to make a variable that stores if the drag is currently happening, and disable `updatePointer` while this variable is true: ``` -- necessary imports import XMonad.Prelude import Data.IORef (IORef, newIORef, readIORef, writeIORef) import System.IO.Unsafe import XMonad.Actions.AfterDrag -- the hacky code updatePointerEnabled :: IORef Bool updatePointerEnabled = unsafePerformIO (newIORef True) enableUpdatePointer :: X () enableUpdatePointer = io $ writeIORef updatePointerEnabled True disableUpdatePointer :: X () disableUpdatePointer = io $ writeIORef updatePointerEnabled False dragWindowMod :: Window -> X () dragWindowMod w = do disableUpdatePointer dragWindow w afterDrag $ do enableUpdatePointer updatePointerMod refPos ratio = do enabled <- io $ readIORef updatePointerEnabled when enabled $ do updatePointer refPos ratio -- use dragWindowMod and updatePointerMod instead of original functions ``` -- Best regards, Platon Pronko PGP 2A62D77A7A2CB94E On 2023-03-24 22:04, Brandon Allbery wrote: > I think that would not be surprising; we needed to update xmonad's > internal state, including running the `logHook`, during drags to avoid > other bugs. (https://github.com/xmonad/xmonad/commit/4565e2c90ef522d23d3afc2cf95b9f0b423d8de4) > Not sure what to do about this. > > On Fri, Mar 24, 2023 at 8:32 AM Ramon Diaz-Uriarte wrote: >> >> Dear All, >> >> When I use XMonad.Actions.UpdatePointer, window dragging no longer works. If I do not use XM.A.UpdatePointer, window dragging works. >> >> >> Details: >> >> These are (what I think are) the relevant pieces from my xmonad.hs: >> >> >> (...) >> import XMonad.Actions.UpdatePointer >> import XMonad.Actions.TiledWindowDragging >> import XMonad.Layout.DraggingVisualizer >> >> (...) >> >> myConfig myWorkspaces = def { >> (...) >> , logHook = refocusLastLogHook <+> logHook def >> updatePointer (0.5, 0.5) (0.1, 0.1) >> } `additionalKeysP` myKeys2 >> `additionalMouseBindings` >> [((mod4Mask, 2), dragWindow)] --drag with mod + center button >> >> >> >> With the above, window dragging no longer works. However, if I comment out ">> updatePointer (0.5, 0.5) (0.1, 0.1)" window dragging works again. >> >> >> Am I doing something wrong? I've searched, and have not seen this mentioned (TiledWindowDragging is mentioned in relation to UpdatePointer here: https://github.com/xmonad/xmonad-contrib/issues/566#issuecomment-869240906, but it seemed a different issue) >> >> >> I am using xmonad and xmonad-contrib, both from master branches, updated as of today (2023-03-24): latest commits are 386d4e and e60805b for xmonad and xmonad-contrib, respectively. >> >> >> Best, >> >> >> >> >> -- >> Ramon Diaz-Uriarte >> Department of Biochemistry, Lab B-31 >> Facultad de Medicina >> Universidad Autónoma de Madrid >> Arzobispo Morcillo, 4 >> 28029 Madrid >> Spain >> >> Phone: +34-91-497-2412 >> >> Email: rdiaz02 at gmail.com >> r.diaz at uam.es >> ramon.diaz at iib.uam.es >> >> https://ligarto.org/rdiaz >> >> >> _______________________________________________ >> xmonad mailing list >> xmonad at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/xmonad > > > From platon7pronko at gmail.com Fri Mar 24 14:37:27 2023 From: platon7pronko at gmail.com (Platon Pronko) Date: Fri, 24 Mar 2023 22:37:27 +0800 Subject: [xmonad] xmobar dynamic spacing In-Reply-To: References: Message-ID: Maybe you can customize the value you provide to `shorten` depending on the screen size? (a bit crumbesome, but might be easier than switching between bar applications, especially since polybar seems to have difficulties with displaying Xmonad workspaces info) -- Best regards, Platon Pronko PGP 2A62D77A7A2CB94E On 2023-03-24 22:11, Brandon Allbery wrote: > Polybar is a popular alternative. I'll have to dig the rest of your > message out of the spamtrap :/ (or more likely let someone more > familiar with xmobar do it) but xmobar isn't really good at dynamic > spacing. > > On Fri, Mar 24, 2023 at 10:07 AM Eyal Erez wrote: >> >> Spam detection software, running on the system "mail.haskell.org", has >> identified this incoming email as possible spam. The original message >> has been attached to this so you can view it (if it isn't spam) or label >> similar future email. If you have any questions, see >> @@CONTACT_ADDRESS@@ for details. >> >> Content preview: Any advice would be greatly appreciated. Also, are there any >> recommended alternatives to xmobar? On Mon, Mar 13, 2023 at 7:40 PM Eyal >> Erez wrote: > Hi, > > I hope that this is the right place to ask. If not, >> please let me know. > > I use xmonad with xmobar and trayer. Trayer is set >> in the upper right > corner, and xmobar fills the remainder of the top of >> the screen. I have > several right-aligned widgets, including date/time, >> CPU, memory, network, > etc., and two left-aligned widgets, which are the >> active workspace name and > the name of the active window. Currently, I set >> the name of the active > window to "shorten 200" in my xmonad.hs file. However, >> I use several > monitors with varying screen sizes, so it is challenging >> to set an > absolute value. When the screen is narrow, and the window title >> is long, it > pushes some widgets out of the right side of xmobar. I would >> like the > window title to take up as much space as possible but leave the >> other > right-aligned widgets where they are. Is there any way to do that? >> > > Short window title > [image: image.png] > > Long window title > [image: >> image.png] > > -- > There are 10 types of people, those who know binary and >> those who don't. > > [...] >> >> Content analysis details: (5.1 points, 5.0 required) >> >> pts rule name description >> ---- ---------------------- -------------------------------------------------- >> 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider >> (oneself[at]gmail.com) >> -0.0 SPF_PASS SPF: sender matches SPF record >> 1.4 HTML_IMAGE_ONLY_28 BODY: HTML: images with 2400-2800 bytes of words >> 0.0 HTML_MESSAGE BODY: HTML included in message >> 1.0 HTML_FONT_FACE_BAD BODY: HTML font face is not a word >> 0.8 BAYES_50 BODY: Bayes spam probability is 40 to 60% >> [score: 0.5000] >> 0.0 T_DKIM_INVALID DKIM-Signature header exists but is not valid >> 1.9 FREEMAIL_REPLY From and body contain different freemails >> >> The original message was not completely plain text, and may be unsafe to >> open with some email clients; in particular, it may contain a virus, >> or confirm that your address can receive spam. If you wish to view >> it, it may be safer to save it to a file and open it with an editor. >> >> _______________________________________________ >> xmonad mailing list >> xmonad at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/xmonad > > > From ivan.brennan at gmail.com Fri Mar 24 15:21:36 2023 From: ivan.brennan at gmail.com (ivan) Date: Fri, 24 Mar 2023 11:21:36 -0400 Subject: [xmonad] MultiToggle with WorkspaceCursors Message-ID: Hi, I'm trying to get MultiToggle and WorkspaceCursors to play nicely with each other. Ordinarily, MultiToggle lets you apply a layout transformation to the current workspace without affecting the layouts of other workspaces. E.g. if I toggle workspace 1 to Full layout, it won't impact the layouts being used on workspaces 2, 3, etc. I've started using WorkspaceCursors (XMonad.Actions.WorkspaceCursors) to manage independent groups of workspaces, and noticed that if I use it's functions (e.g. modifyLayer) to navigate between workspaces, layout toggle states seem to bleed across workspaces rather than remaining independent per workspace. For example, starting on workspace 1 with my regular Tall layout, I navigate to workspace 2 and toggle it to Full layout. Then I go back to workspace 1 and see that it, too, has been toggled to Full layout. I can't figure out exactly what's causing this, or how to fix it so that workspace layouts toggle independently. I'm hoping someone here sees what I'm missing. I put together a minimal config to reproduce the problem: https://github.com/ivanbrennan/xmonad-testing/commit/2e9541b0937eee31ae7f300e130dc55a9c5933af#diff-61bfccbc988708bd118b33f9299c64aa8b3e532e25cc8eaa3b716f53215fb196 The config provides two groups (A and B) of nine workspaces. group A: 1A 2A 3A 4A 5A 6A 7A 8A 9A group B: 1B 2B 3B 4B 5B 6B 7B 8B 9B Its layoutHook consists of: myLayoutHook = workspaceCursors cursors . avoidStruts . mkToggle1 FULL $ Tall 1 (3/100) (1/2) Keys super+1 .. super+9 use WorkspaceCursors functions to switch between workspaces within the currently active group. Keys super+ctrl+1 .. super+ctrl+2 use WorkspaceCursors functions to switch between groups A and B. Additionally, keys super+meta+1 .. super+meta+9 use traditional StackSet functions to switch between workspaces 1A .. 9A. I added these for comparison, showing that MultiToggle state is recognized per-workspace when using this form of navigation. I can't figure out the root cause. I suspect the most relevant pieces of code from WorkspaceCursors and MultiToggle are the following: https://github.com/xmonad/xmonad-contrib/blob/e60805bd45ca2feb9ef3335d023daae5d02dbf4f/XMonad/Actions/WorkspaceCursors.hs#L204-L215 https://github.com/xmonad/xmonad-contrib/blob/e60805bd45ca2feb9ef3335d023daae5d02dbf4f/XMonad/Layout/MultiToggle.hs#L193-L218 Does anyone know what I might be missing, or how I could debug further to get to the root of the problem? Thanks! Ivan -------------- next part -------------- An HTML attachment was scrubbed... URL: From allbery.b at gmail.com Fri Mar 24 15:27:28 2023 From: allbery.b at gmail.com (Brandon Allbery) Date: Fri, 24 Mar 2023 11:27:28 -0400 Subject: [xmonad] MultiToggle with WorkspaceCursors In-Reply-To: References: Message-ID: My guess is that MultiToggle doesn't and can't know about WorkspaceCursors, and WorkspaceCursors doesn't and can't know that it needs to duplicate the layout state for each group it introduces, so any layout state change applies to all groups. On Fri, Mar 24, 2023 at 11:22 AM ivan wrote: > > Hi, I'm trying to get MultiToggle and WorkspaceCursors to play nicely with each other. > > Ordinarily, MultiToggle lets you apply a layout transformation to the current workspace without affecting the layouts of other workspaces. E.g. if I toggle workspace 1 to Full layout, it won't impact the layouts being used on workspaces 2, 3, etc. > > I've started using WorkspaceCursors (XMonad.Actions.WorkspaceCursors) to manage independent groups of workspaces, and noticed that if I use it's functions (e.g. modifyLayer) to navigate between workspaces, layout toggle states seem to bleed across workspaces rather than remaining independent per workspace. > > For example, starting on workspace 1 with my regular Tall layout, I navigate to workspace 2 and toggle it to Full layout. Then I go back to workspace 1 and see that it, too, has been toggled to Full layout. > > I can't figure out exactly what's causing this, or how to fix it so that workspace layouts toggle independently. I'm hoping someone here sees what I'm missing. > > I put together a minimal config to reproduce the problem: > https://github.com/ivanbrennan/xmonad-testing/commit/2e9541b0937eee31ae7f300e130dc55a9c5933af#diff-61bfccbc988708bd118b33f9299c64aa8b3e532e25cc8eaa3b716f53215fb196 > > The config provides two groups (A and B) of nine workspaces. > > group A: 1A 2A 3A 4A 5A 6A 7A 8A 9A > group B: 1B 2B 3B 4B 5B 6B 7B 8B 9B > > Its layoutHook consists of: > > myLayoutHook = > workspaceCursors cursors > . avoidStruts > . mkToggle1 FULL > $ Tall 1 (3/100) (1/2) > > Keys super+1 .. super+9 use WorkspaceCursors functions to switch between workspaces within the currently active group. > > Keys super+ctrl+1 .. super+ctrl+2 use WorkspaceCursors functions to switch between groups A and B. > > Additionally, keys super+meta+1 .. super+meta+9 use traditional StackSet functions to switch between workspaces 1A .. 9A. I added these for comparison, showing that MultiToggle state is recognized per-workspace when using this form of navigation. > > I can't figure out the root cause. I suspect the most relevant pieces of code from WorkspaceCursors and MultiToggle are the following: > > https://github.com/xmonad/xmonad-contrib/blob/e60805bd45ca2feb9ef3335d023daae5d02dbf4f/XMonad/Actions/WorkspaceCursors.hs#L204-L215 > > https://github.com/xmonad/xmonad-contrib/blob/e60805bd45ca2feb9ef3335d023daae5d02dbf4f/XMonad/Layout/MultiToggle.hs#L193-L218 > > Does anyone know what I might be missing, or how I could debug further to get to the root of the problem? > > Thanks! > Ivan > _______________________________________________ > xmonad mailing list > xmonad at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/xmonad -- brandon s allbery kf8nh allbery.b at gmail.com From rdiaz02 at gmail.com Fri Mar 24 16:41:52 2023 From: rdiaz02 at gmail.com (Ramon Diaz-Uriarte) Date: Fri, 24 Mar 2023 17:41:52 +0100 Subject: [xmonad] XM.A.UpdatePointer interferes with XM.A.TiledWindowDragging? In-Reply-To: <754f9f08-8e6c-870c-3db6-40acd8d360c6@gmail.com> References: <87lejm9vpn.fsf@gmail.com> <754f9f08-8e6c-870c-3db6-40acd8d360c6@gmail.com> Message-ID: <87o7oiaxjn.fsf@gmail.com> Thanks a lot! This works perfectly. For completeness, I noticed some corner cases if I enable focusFollowsMouse = False . Suppose the following: - Two windows: Firefox and Emacs. - Emacs has two buffers with different names If the focused window is Firefox, and I move the mouse over Emacs, as soon as I cross to the other buffer in Emacs, the mouse pointer jumps back to Firefox. Now, however, this might not be very relevant as I don't see why I would use updatePointer with focusFollowsMouse = False. Thanks again, R. On Fri, 24-March-2023, at 15:23:41, Platon Pronko wrote: > Hi! > > Seems the issue is that the pointer is warped back to the initial dragged window position before TiledWindowDragging updates the focused window, and thus no window switching is happening (because from the point of view of TiledWindowDragging the window was never dragged anywhere). > > As Brandon said, logHook is called on every internal state update, so UpdatePointer tries to update the pointer all the time, even in-between drag end and focus change. `updatePointer` contains some guards that are trying to detect common scenarios and prevent updating in such cases, but as we see it doesn't work perfectly. > > I suppose `updatePointer` should run only when it explicitly detects the window focus change event, instead of running all the time (maybe some manageHook wrapper?). > > That said, I found a (quite hacky) way to achieve what you want without rewriting UpdatePointer. The idea is to make a variable that stores if the drag is currently happening, and disable `updatePointer` while this variable is true: > > ``` > -- necessary imports > import XMonad.Prelude > import Data.IORef (IORef, newIORef, readIORef, writeIORef) > import System.IO.Unsafe > import XMonad.Actions.AfterDrag > > -- the hacky code > updatePointerEnabled :: IORef Bool > updatePointerEnabled = unsafePerformIO (newIORef True) > enableUpdatePointer :: X () > enableUpdatePointer = io $ writeIORef updatePointerEnabled True > disableUpdatePointer :: X () > disableUpdatePointer = io $ writeIORef updatePointerEnabled False > dragWindowMod :: Window -> X () > dragWindowMod w = do > disableUpdatePointer > dragWindow w > afterDrag $ do > enableUpdatePointer > updatePointerMod refPos ratio = do > enabled <- io $ readIORef updatePointerEnabled > when enabled $ do > updatePointer refPos ratio > > -- use dragWindowMod and updatePointerMod instead of original functions > ``` -- Ramon Diaz-Uriarte Department of Biochemistry, Lab B-31 Facultad de Medicina Universidad Autónoma de Madrid Arzobispo Morcillo, 4 28029 Madrid Spain Phone: +34-91-497-2412 Email: rdiaz02 at gmail.com r.diaz at uam.es ramon.diaz at iib.uam.es https://ligarto.org/rdiaz From platon7pronko at gmail.com Sat Mar 25 08:26:31 2023 From: platon7pronko at gmail.com (Platon Pronko) Date: Sat, 25 Mar 2023 16:26:31 +0800 Subject: [xmonad] MultiToggle with WorkspaceCursors In-Reply-To: References: Message-ID: <9e50a7c9-cd86-621f-3063-0a5fe3fd38f3@gmail.com> Hi! WorkspaceCursors doesn't introduce any groups, it's just a glorified workspace switcher - underneath all the chrome it uses the standard flat workspaces list. In essense it just defines some helper functions that allow user to imagine that workspaces are arranged as a multidimensional cube and navigate along axes of said cube. But it still does it using the usual StackSet.greedyView function. MultiToggle is irrelevant in this case, the same effect can be seen with the boring Choose layout combinator (i.e. `Tall ||| Full`) - the layout state is "spilling" over to other workspaces. It seems that the problem arises because WorspaceCursors calls `windows $ greedyView` inside LayoutClass.handleMessage function - current workspace is switched at the same time as layout is updated, and Xmonad assigns the updated layout to the new workspace. Here's a reproducer (should work on all configs that have a workspace with id "4"): ``` -- necessary language pragmas {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} -- imports import qualified XMonad.StackSet as W import XMonad.Layout.LayoutModifier(ModifiedLayout(..), LayoutModifier(handleMess)) import XMonad(Message, X, windows, sendMessage, fromMessage) -- Example LayoutModifier that showcases the issue. -- It does nothing except calling `greedyView "4"` upon reciept of SwitchWorkspace message data BadLayoutModifier a = BadLayoutModifier deriving (Read, Show) data SwitchWorkspace = SwitchWorkspace instance Message SwitchWorkspace instance LayoutModifier BadLayoutModifier a where handleMess BadLayoutModifier m = do case fromMessage m of Just SwitchWorkspace -> do windows $ W.greedyView "4" return $ Just BadLayoutModifier Nothing -> return Nothing -- add to keys (tweak the keybinding to your taste) , ((modm, xK_v), sendMessage SwitchWorkspace) -- prepend BadLayoutModifier to layoutHook layoutHook = ModifiedLayout BadLayoutModifier $ (Tall 1 (3/100) (1/2) ||| Full) ``` Steps to reproduce: 1. Recompile and restart Xmonad. 2. Toggle workspace "2" to "Tall" layout, toggle workspace "4" to "Full" layout. 3. Switch to workspace "2". 4. Press keybinding to send the SwitchWorkspace message (Super-v in my case). 5. Observe that Xmonad switches to workspace "4", and layout on that workspace is now "Tall" instead of "Full" as set up originally. In my opinion WorkspaceCursors doesn't need to be a LayoutModifier at all - current state can be derived from the list of cursors and currently focused workspace, no need to store it somewhere. This will sidestep the problem of calling `greedyView` during layout update. -- Best regards, Platon Pronko PGP 2A62D77A7A2CB94E On 2023-03-24 23:27, Brandon Allbery wrote: > My guess is that MultiToggle doesn't and can't know about > WorkspaceCursors, and WorkspaceCursors doesn't and can't know that it > needs to duplicate the layout state for each group it introduces, so > any layout state change applies to all groups. > > On Fri, Mar 24, 2023 at 11:22 AM ivan wrote: >> >> Hi, I'm trying to get MultiToggle and WorkspaceCursors to play nicely with each other. >> >> Ordinarily, MultiToggle lets you apply a layout transformation to the current workspace without affecting the layouts of other workspaces. E.g. if I toggle workspace 1 to Full layout, it won't impact the layouts being used on workspaces 2, 3, etc. >> >> I've started using WorkspaceCursors (XMonad.Actions.WorkspaceCursors) to manage independent groups of workspaces, and noticed that if I use it's functions (e.g. modifyLayer) to navigate between workspaces, layout toggle states seem to bleed across workspaces rather than remaining independent per workspace. >> >> For example, starting on workspace 1 with my regular Tall layout, I navigate to workspace 2 and toggle it to Full layout. Then I go back to workspace 1 and see that it, too, has been toggled to Full layout. >> >> I can't figure out exactly what's causing this, or how to fix it so that workspace layouts toggle independently. I'm hoping someone here sees what I'm missing. >> >> I put together a minimal config to reproduce the problem: >> https://github.com/ivanbrennan/xmonad-testing/commit/2e9541b0937eee31ae7f300e130dc55a9c5933af#diff-61bfccbc988708bd118b33f9299c64aa8b3e532e25cc8eaa3b716f53215fb196 >> >> The config provides two groups (A and B) of nine workspaces. >> >> group A: 1A 2A 3A 4A 5A 6A 7A 8A 9A >> group B: 1B 2B 3B 4B 5B 6B 7B 8B 9B >> >> Its layoutHook consists of: >> >> myLayoutHook = >> workspaceCursors cursors >> . avoidStruts >> . mkToggle1 FULL >> $ Tall 1 (3/100) (1/2) >> >> Keys super+1 .. super+9 use WorkspaceCursors functions to switch between workspaces within the currently active group. >> >> Keys super+ctrl+1 .. super+ctrl+2 use WorkspaceCursors functions to switch between groups A and B. >> >> Additionally, keys super+meta+1 .. super+meta+9 use traditional StackSet functions to switch between workspaces 1A .. 9A. I added these for comparison, showing that MultiToggle state is recognized per-workspace when using this form of navigation. >> >> I can't figure out the root cause. I suspect the most relevant pieces of code from WorkspaceCursors and MultiToggle are the following: >> >> https://github.com/xmonad/xmonad-contrib/blob/e60805bd45ca2feb9ef3335d023daae5d02dbf4f/XMonad/Actions/WorkspaceCursors.hs#L204-L215 >> >> https://github.com/xmonad/xmonad-contrib/blob/e60805bd45ca2feb9ef3335d023daae5d02dbf4f/XMonad/Layout/MultiToggle.hs#L193-L218 >> >> Does anyone know what I might be missing, or how I could debug further to get to the root of the problem? >> >> Thanks! >> Ivan >> _______________________________________________ >> xmonad mailing list >> xmonad at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/xmonad > > > From ivan.brennan at gmail.com Sat Mar 25 12:15:43 2023 From: ivan.brennan at gmail.com (ivan) Date: Sat, 25 Mar 2023 08:15:43 -0400 Subject: [xmonad] MultiToggle with WorkspaceCursors In-Reply-To: <9e50a7c9-cd86-621f-3063-0a5fe3fd38f3@gmail.com> References: <9e50a7c9-cd86-621f-3063-0a5fe3fd38f3@gmail.com> Message-ID: Amazing! Thank you so much for the clear explanation. On Sat, Mar 25, 2023 at 4:26 AM Platon Pronko wrote: > Hi! > > WorkspaceCursors doesn't introduce any groups, it's just a glorified > workspace switcher - underneath all the chrome it uses the standard flat > workspaces list. In essense it just defines some helper functions that > allow user to imagine that workspaces are arranged as a multidimensional > cube and navigate along axes of said cube. But it still does it using the > usual StackSet.greedyView function. > > MultiToggle is irrelevant in this case, the same effect can be seen with > the boring Choose layout combinator (i.e. `Tall ||| Full`) - the layout > state is "spilling" over to other workspaces. > > It seems that the problem arises because WorspaceCursors calls `windows $ > greedyView` inside LayoutClass.handleMessage function - current workspace > is switched at the same time as layout is updated, and Xmonad assigns the > updated layout to the new workspace. > > Here's a reproducer (should work on all configs that have a workspace with > id "4"): > > ``` > -- necessary language pragmas > {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} > > -- imports > import qualified XMonad.StackSet as W > import XMonad.Layout.LayoutModifier(ModifiedLayout(..), > LayoutModifier(handleMess)) > import XMonad(Message, X, windows, sendMessage, fromMessage) > > -- Example LayoutModifier that showcases the issue. > -- It does nothing except calling `greedyView "4"` upon reciept of > SwitchWorkspace message > data BadLayoutModifier a = BadLayoutModifier deriving (Read, Show) > > data SwitchWorkspace = SwitchWorkspace > instance Message SwitchWorkspace > > instance LayoutModifier BadLayoutModifier a where > handleMess BadLayoutModifier m = do > case fromMessage m of > Just SwitchWorkspace -> do > windows $ W.greedyView "4" > return $ Just BadLayoutModifier > Nothing -> return Nothing > > -- add to keys (tweak the keybinding to your taste) > , ((modm, xK_v), sendMessage SwitchWorkspace) > > -- prepend BadLayoutModifier to layoutHook > layoutHook = > ModifiedLayout BadLayoutModifier $ > (Tall 1 (3/100) (1/2) ||| Full) > ``` > > Steps to reproduce: > > 1. Recompile and restart Xmonad. > 2. Toggle workspace "2" to "Tall" layout, toggle workspace "4" to "Full" > layout. > 3. Switch to workspace "2". > 4. Press keybinding to send the SwitchWorkspace message (Super-v in my > case). > 5. Observe that Xmonad switches to workspace "4", and layout on that > workspace is now "Tall" instead of "Full" as set up originally. > > In my opinion WorkspaceCursors doesn't need to be a LayoutModifier at all > - current state can be derived from the list of cursors and currently > focused workspace, no need to store it somewhere. This will sidestep the > problem of calling `greedyView` during layout update. > > -- > Best regards, > Platon Pronko > PGP 2A62D77A7A2CB94E > > On 2023-03-24 23:27, Brandon Allbery wrote: > > My guess is that MultiToggle doesn't and can't know about > > WorkspaceCursors, and WorkspaceCursors doesn't and can't know that it > > needs to duplicate the layout state for each group it introduces, so > > any layout state change applies to all groups. > > > > On Fri, Mar 24, 2023 at 11:22 AM ivan wrote: > >> > >> Hi, I'm trying to get MultiToggle and WorkspaceCursors to play nicely > with each other. > >> > >> Ordinarily, MultiToggle lets you apply a layout transformation to the > current workspace without affecting the layouts of other workspaces. E.g. > if I toggle workspace 1 to Full layout, it won't impact the layouts being > used on workspaces 2, 3, etc. > >> > >> I've started using WorkspaceCursors (XMonad.Actions.WorkspaceCursors) > to manage independent groups of workspaces, and noticed that if I use it's > functions (e.g. modifyLayer) to navigate between workspaces, layout toggle > states seem to bleed across workspaces rather than remaining independent > per workspace. > >> > >> For example, starting on workspace 1 with my regular Tall layout, I > navigate to workspace 2 and toggle it to Full layout. Then I go back to > workspace 1 and see that it, too, has been toggled to Full layout. > >> > >> I can't figure out exactly what's causing this, or how to fix it so > that workspace layouts toggle independently. I'm hoping someone here sees > what I'm missing. > >> > >> I put together a minimal config to reproduce the problem: > >> > https://github.com/ivanbrennan/xmonad-testing/commit/2e9541b0937eee31ae7f300e130dc55a9c5933af#diff-61bfccbc988708bd118b33f9299c64aa8b3e532e25cc8eaa3b716f53215fb196 > >> > >> The config provides two groups (A and B) of nine workspaces. > >> > >> group A: 1A 2A 3A 4A 5A 6A 7A 8A 9A > >> group B: 1B 2B 3B 4B 5B 6B 7B 8B 9B > >> > >> Its layoutHook consists of: > >> > >> myLayoutHook = > >> workspaceCursors cursors > >> . avoidStruts > >> . mkToggle1 FULL > >> $ Tall 1 (3/100) (1/2) > >> > >> Keys super+1 .. super+9 use WorkspaceCursors functions to switch > between workspaces within the currently active group. > >> > >> Keys super+ctrl+1 .. super+ctrl+2 use WorkspaceCursors functions to > switch between groups A and B. > >> > >> Additionally, keys super+meta+1 .. super+meta+9 use traditional > StackSet functions to switch between workspaces 1A .. 9A. I added these for > comparison, showing that MultiToggle state is recognized per-workspace when > using this form of navigation. > >> > >> I can't figure out the root cause. I suspect the most relevant pieces > of code from WorkspaceCursors and MultiToggle are the following: > >> > >> > https://github.com/xmonad/xmonad-contrib/blob/e60805bd45ca2feb9ef3335d023daae5d02dbf4f/XMonad/Actions/WorkspaceCursors.hs#L204-L215 > >> > >> > https://github.com/xmonad/xmonad-contrib/blob/e60805bd45ca2feb9ef3335d023daae5d02dbf4f/XMonad/Layout/MultiToggle.hs#L193-L218 > >> > >> Does anyone know what I might be missing, or how I could debug further > to get to the root of the problem? > >> > >> Thanks! > >> Ivan > >> _______________________________________________ > >> xmonad mailing list > >> xmonad at haskell.org > >> http://mail.haskell.org/cgi-bin/mailman/listinfo/xmonad > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ivan.brennan at gmail.com Sun Mar 26 01:49:12 2023 From: ivan.brennan at gmail.com (ivan) Date: Sat, 25 Mar 2023 21:49:12 -0400 Subject: [xmonad] MultiToggle with WorkspaceCursors In-Reply-To: References: <9e50a7c9-cd86-621f-3063-0a5fe3fd38f3@gmail.com> Message-ID: Following up on this: > In my opinion WorkspaceCursors doesn't need to be a LayoutModifier at all - current state can be derived from the list of cursors and currently focused workspace, no need to store it somewhere. I've been using WorkspaceCursors to switch between (simulated) groups of workspaces, relying on the Cursors state to remember which workspace has focus within each group. So switching to group G will focus whichever workspace was focused last time I visited that group. (Or, if it's the first time I've visited that group, its first workspace gets focus). The Cursors state feels like a natural way to implement that, but it's not the only way. My initial implementation treated StackSet.workspaces as a recency list, and switching to group G meant finding the first workspace in that list that was a member of G. When I started using Cursors state instead, I ran into the problem you explained. For now, I'll revisit my initial approach. Thanks again! On Sat, Mar 25, 2023 at 8:15 AM ivan wrote: > Amazing! Thank you so much for the clear explanation. > > On Sat, Mar 25, 2023 at 4:26 AM Platon Pronko > wrote: > >> Hi! >> >> WorkspaceCursors doesn't introduce any groups, it's just a glorified >> workspace switcher - underneath all the chrome it uses the standard flat >> workspaces list. In essense it just defines some helper functions that >> allow user to imagine that workspaces are arranged as a multidimensional >> cube and navigate along axes of said cube. But it still does it using the >> usual StackSet.greedyView function. >> >> MultiToggle is irrelevant in this case, the same effect can be seen with >> the boring Choose layout combinator (i.e. `Tall ||| Full`) - the layout >> state is "spilling" over to other workspaces. >> >> It seems that the problem arises because WorspaceCursors calls `windows $ >> greedyView` inside LayoutClass.handleMessage function - current workspace >> is switched at the same time as layout is updated, and Xmonad assigns the >> updated layout to the new workspace. >> >> Here's a reproducer (should work on all configs that have a workspace >> with id "4"): >> >> ``` >> -- necessary language pragmas >> {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} >> >> -- imports >> import qualified XMonad.StackSet as W >> import XMonad.Layout.LayoutModifier(ModifiedLayout(..), >> LayoutModifier(handleMess)) >> import XMonad(Message, X, windows, sendMessage, fromMessage) >> >> -- Example LayoutModifier that showcases the issue. >> -- It does nothing except calling `greedyView "4"` upon reciept of >> SwitchWorkspace message >> data BadLayoutModifier a = BadLayoutModifier deriving (Read, Show) >> >> data SwitchWorkspace = SwitchWorkspace >> instance Message SwitchWorkspace >> >> instance LayoutModifier BadLayoutModifier a where >> handleMess BadLayoutModifier m = do >> case fromMessage m of >> Just SwitchWorkspace -> do >> windows $ W.greedyView "4" >> return $ Just BadLayoutModifier >> Nothing -> return Nothing >> >> -- add to keys (tweak the keybinding to your taste) >> , ((modm, xK_v), sendMessage SwitchWorkspace) >> >> -- prepend BadLayoutModifier to layoutHook >> layoutHook = >> ModifiedLayout BadLayoutModifier $ >> (Tall 1 (3/100) (1/2) ||| Full) >> ``` >> >> Steps to reproduce: >> >> 1. Recompile and restart Xmonad. >> 2. Toggle workspace "2" to "Tall" layout, toggle workspace "4" to "Full" >> layout. >> 3. Switch to workspace "2". >> 4. Press keybinding to send the SwitchWorkspace message (Super-v in my >> case). >> 5. Observe that Xmonad switches to workspace "4", and layout on that >> workspace is now "Tall" instead of "Full" as set up originally. >> >> In my opinion WorkspaceCursors doesn't need to be a LayoutModifier at all >> - current state can be derived from the list of cursors and currently >> focused workspace, no need to store it somewhere. This will sidestep the >> problem of calling `greedyView` during layout update. >> >> -- >> Best regards, >> Platon Pronko >> PGP 2A62D77A7A2CB94E >> >> On 2023-03-24 23:27, Brandon Allbery wrote: >> > My guess is that MultiToggle doesn't and can't know about >> > WorkspaceCursors, and WorkspaceCursors doesn't and can't know that it >> > needs to duplicate the layout state for each group it introduces, so >> > any layout state change applies to all groups. >> > >> > On Fri, Mar 24, 2023 at 11:22 AM ivan wrote: >> >> >> >> Hi, I'm trying to get MultiToggle and WorkspaceCursors to play nicely >> with each other. >> >> >> >> Ordinarily, MultiToggle lets you apply a layout transformation to the >> current workspace without affecting the layouts of other workspaces. E.g. >> if I toggle workspace 1 to Full layout, it won't impact the layouts being >> used on workspaces 2, 3, etc. >> >> >> >> I've started using WorkspaceCursors (XMonad.Actions.WorkspaceCursors) >> to manage independent groups of workspaces, and noticed that if I use it's >> functions (e.g. modifyLayer) to navigate between workspaces, layout toggle >> states seem to bleed across workspaces rather than remaining independent >> per workspace. >> >> >> >> For example, starting on workspace 1 with my regular Tall layout, I >> navigate to workspace 2 and toggle it to Full layout. Then I go back to >> workspace 1 and see that it, too, has been toggled to Full layout. >> >> >> >> I can't figure out exactly what's causing this, or how to fix it so >> that workspace layouts toggle independently. I'm hoping someone here sees >> what I'm missing. >> >> >> >> I put together a minimal config to reproduce the problem: >> >> >> https://github.com/ivanbrennan/xmonad-testing/commit/2e9541b0937eee31ae7f300e130dc55a9c5933af#diff-61bfccbc988708bd118b33f9299c64aa8b3e532e25cc8eaa3b716f53215fb196 >> >> >> >> The config provides two groups (A and B) of nine workspaces. >> >> >> >> group A: 1A 2A 3A 4A 5A 6A 7A 8A 9A >> >> group B: 1B 2B 3B 4B 5B 6B 7B 8B 9B >> >> >> >> Its layoutHook consists of: >> >> >> >> myLayoutHook = >> >> workspaceCursors cursors >> >> . avoidStruts >> >> . mkToggle1 FULL >> >> $ Tall 1 (3/100) (1/2) >> >> >> >> Keys super+1 .. super+9 use WorkspaceCursors functions to switch >> between workspaces within the currently active group. >> >> >> >> Keys super+ctrl+1 .. super+ctrl+2 use WorkspaceCursors functions to >> switch between groups A and B. >> >> >> >> Additionally, keys super+meta+1 .. super+meta+9 use traditional >> StackSet functions to switch between workspaces 1A .. 9A. I added these for >> comparison, showing that MultiToggle state is recognized per-workspace when >> using this form of navigation. >> >> >> >> I can't figure out the root cause. I suspect the most relevant pieces >> of code from WorkspaceCursors and MultiToggle are the following: >> >> >> >> >> https://github.com/xmonad/xmonad-contrib/blob/e60805bd45ca2feb9ef3335d023daae5d02dbf4f/XMonad/Actions/WorkspaceCursors.hs#L204-L215 >> >> >> >> >> https://github.com/xmonad/xmonad-contrib/blob/e60805bd45ca2feb9ef3335d023daae5d02dbf4f/XMonad/Layout/MultiToggle.hs#L193-L218 >> >> >> >> Does anyone know what I might be missing, or how I could debug further >> to get to the root of the problem? >> >> >> >> Thanks! >> >> Ivan >> >> _______________________________________________ >> >> xmonad mailing list >> >> xmonad at haskell.org >> >> http://mail.haskell.org/cgi-bin/mailman/listinfo/xmonad >> > >> > >> > >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From platon7pronko at gmail.com Sun Mar 26 04:20:57 2023 From: platon7pronko at gmail.com (Platon Pronko) Date: Sun, 26 Mar 2023 12:20:57 +0800 Subject: [xmonad] MultiToggle with WorkspaceCursors In-Reply-To: References: <9e50a7c9-cd86-621f-3063-0a5fe3fd38f3@gmail.com> Message-ID: Yes, you are right, my original analysis was incorrect. WorkspaceCursors does indeed store a tree of cursors, and that is not derivable from the current workspace id. However I still think that storing cursors state in LayoutModifier is incorrect - layout information is local for every workspace, while cursors state should be global, not duplicated per every workspace (I can't prove it, but I definitely feel that there are bugs lurking in WorkspaceCursors because of that duplication). I think you can achieve what you need without using WorkspaceCursors as a layout modifier. You can store cursors state in a global variable and work with it yourself. Something like: cursors = unsafePerformIO $ newIORef $ makeCursors [nominalIds, groupIds] (if you don't like unsafePerformIO, you also store cursors inside XMonad's XState.extensibleState) Unfortunately you won't be able to reuse most of WorkspaceCursors stack management functions, because they are either private or call modifyCursors directly or indirectly. You'll have to copy them and adapt them to work on your cursors state. -- Best regards, Platon Pronko PGP 2A62D77A7A2CB94E On 2023-03-26 09:49, ivan wrote: > Following up on this: > >> In my opinion WorkspaceCursors doesn't need to be a LayoutModifier at all > - current state can be derived from the list of cursors and currently > focused workspace, no need to store it somewhere. > > I've been using WorkspaceCursors to switch between (simulated) groups of > workspaces, relying on the Cursors state to remember which workspace has > focus within each group. So switching to group G will focus whichever > workspace was focused last time I visited that group. (Or, if it's the > first time I've visited that group, its first workspace gets focus). > > The Cursors state feels like a natural way to implement that, but it's not > the only way. My initial implementation treated StackSet.workspaces as a > recency list, and switching to group G meant finding the first workspace in > that list that was a member of G. When I started using Cursors state > instead, I ran into the problem you explained. > > For now, I'll revisit my initial approach. > > Thanks again! > > On Sat, Mar 25, 2023 at 8:15 AM ivan wrote: > >> Amazing! Thank you so much for the clear explanation. >> >> On Sat, Mar 25, 2023 at 4:26 AM Platon Pronko >> wrote: >> >>> Hi! >>> >>> WorkspaceCursors doesn't introduce any groups, it's just a glorified >>> workspace switcher - underneath all the chrome it uses the standard flat >>> workspaces list. In essense it just defines some helper functions that >>> allow user to imagine that workspaces are arranged as a multidimensional >>> cube and navigate along axes of said cube. But it still does it using the >>> usual StackSet.greedyView function. >>> >>> MultiToggle is irrelevant in this case, the same effect can be seen with >>> the boring Choose layout combinator (i.e. `Tall ||| Full`) - the layout >>> state is "spilling" over to other workspaces. >>> >>> It seems that the problem arises because WorspaceCursors calls `windows $ >>> greedyView` inside LayoutClass.handleMessage function - current workspace >>> is switched at the same time as layout is updated, and Xmonad assigns the >>> updated layout to the new workspace. >>> >>> Here's a reproducer (should work on all configs that have a workspace >>> with id "4"): >>> >>> ``` >>> -- necessary language pragmas >>> {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} >>> >>> -- imports >>> import qualified XMonad.StackSet as W >>> import XMonad.Layout.LayoutModifier(ModifiedLayout(..), >>> LayoutModifier(handleMess)) >>> import XMonad(Message, X, windows, sendMessage, fromMessage) >>> >>> -- Example LayoutModifier that showcases the issue. >>> -- It does nothing except calling `greedyView "4"` upon reciept of >>> SwitchWorkspace message >>> data BadLayoutModifier a = BadLayoutModifier deriving (Read, Show) >>> >>> data SwitchWorkspace = SwitchWorkspace >>> instance Message SwitchWorkspace >>> >>> instance LayoutModifier BadLayoutModifier a where >>> handleMess BadLayoutModifier m = do >>> case fromMessage m of >>> Just SwitchWorkspace -> do >>> windows $ W.greedyView "4" >>> return $ Just BadLayoutModifier >>> Nothing -> return Nothing >>> >>> -- add to keys (tweak the keybinding to your taste) >>> , ((modm, xK_v), sendMessage SwitchWorkspace) >>> >>> -- prepend BadLayoutModifier to layoutHook >>> layoutHook = >>> ModifiedLayout BadLayoutModifier $ >>> (Tall 1 (3/100) (1/2) ||| Full) >>> ``` >>> >>> Steps to reproduce: >>> >>> 1. Recompile and restart Xmonad. >>> 2. Toggle workspace "2" to "Tall" layout, toggle workspace "4" to "Full" >>> layout. >>> 3. Switch to workspace "2". >>> 4. Press keybinding to send the SwitchWorkspace message (Super-v in my >>> case). >>> 5. Observe that Xmonad switches to workspace "4", and layout on that >>> workspace is now "Tall" instead of "Full" as set up originally. >>> >>> In my opinion WorkspaceCursors doesn't need to be a LayoutModifier at all >>> - current state can be derived from the list of cursors and currently >>> focused workspace, no need to store it somewhere. This will sidestep the >>> problem of calling `greedyView` during layout update. >>> >>> -- >>> Best regards, >>> Platon Pronko >>> PGP 2A62D77A7A2CB94E >>> >>> On 2023-03-24 23:27, Brandon Allbery wrote: >>>> My guess is that MultiToggle doesn't and can't know about >>>> WorkspaceCursors, and WorkspaceCursors doesn't and can't know that it >>>> needs to duplicate the layout state for each group it introduces, so >>>> any layout state change applies to all groups. >>>> >>>> On Fri, Mar 24, 2023 at 11:22 AM ivan wrote: >>>>> >>>>> Hi, I'm trying to get MultiToggle and WorkspaceCursors to play nicely >>> with each other. >>>>> >>>>> Ordinarily, MultiToggle lets you apply a layout transformation to the >>> current workspace without affecting the layouts of other workspaces. E.g. >>> if I toggle workspace 1 to Full layout, it won't impact the layouts being >>> used on workspaces 2, 3, etc. >>>>> >>>>> I've started using WorkspaceCursors (XMonad.Actions.WorkspaceCursors) >>> to manage independent groups of workspaces, and noticed that if I use it's >>> functions (e.g. modifyLayer) to navigate between workspaces, layout toggle >>> states seem to bleed across workspaces rather than remaining independent >>> per workspace. >>>>> >>>>> For example, starting on workspace 1 with my regular Tall layout, I >>> navigate to workspace 2 and toggle it to Full layout. Then I go back to >>> workspace 1 and see that it, too, has been toggled to Full layout. >>>>> >>>>> I can't figure out exactly what's causing this, or how to fix it so >>> that workspace layouts toggle independently. I'm hoping someone here sees >>> what I'm missing. >>>>> >>>>> I put together a minimal config to reproduce the problem: >>>>> >>> https://github.com/ivanbrennan/xmonad-testing/commit/2e9541b0937eee31ae7f300e130dc55a9c5933af#diff-61bfccbc988708bd118b33f9299c64aa8b3e532e25cc8eaa3b716f53215fb196 >>>>> >>>>> The config provides two groups (A and B) of nine workspaces. >>>>> >>>>> group A: 1A 2A 3A 4A 5A 6A 7A 8A 9A >>>>> group B: 1B 2B 3B 4B 5B 6B 7B 8B 9B >>>>> >>>>> Its layoutHook consists of: >>>>> >>>>> myLayoutHook = >>>>> workspaceCursors cursors >>>>> . avoidStruts >>>>> . mkToggle1 FULL >>>>> $ Tall 1 (3/100) (1/2) >>>>> >>>>> Keys super+1 .. super+9 use WorkspaceCursors functions to switch >>> between workspaces within the currently active group. >>>>> >>>>> Keys super+ctrl+1 .. super+ctrl+2 use WorkspaceCursors functions to >>> switch between groups A and B. >>>>> >>>>> Additionally, keys super+meta+1 .. super+meta+9 use traditional >>> StackSet functions to switch between workspaces 1A .. 9A. I added these for >>> comparison, showing that MultiToggle state is recognized per-workspace when >>> using this form of navigation. >>>>> >>>>> I can't figure out the root cause. I suspect the most relevant pieces >>> of code from WorkspaceCursors and MultiToggle are the following: >>>>> >>>>> >>> https://github.com/xmonad/xmonad-contrib/blob/e60805bd45ca2feb9ef3335d023daae5d02dbf4f/XMonad/Actions/WorkspaceCursors.hs#L204-L215 >>>>> >>>>> >>> https://github.com/xmonad/xmonad-contrib/blob/e60805bd45ca2feb9ef3335d023daae5d02dbf4f/XMonad/Layout/MultiToggle.hs#L193-L218 >>>>> >>>>> Does anyone know what I might be missing, or how I could debug further >>> to get to the root of the problem? >>>>> >>>>> Thanks! >>>>> Ivan >>>>> _______________________________________________ >>>>> xmonad mailing list >>>>> xmonad at haskell.org >>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/xmonad >>>> >>>> >>>> >>> >> > From ivan.brennan at gmail.com Sun Mar 26 12:59:53 2023 From: ivan.brennan at gmail.com (ivan) Date: Sun, 26 Mar 2023 08:59:53 -0400 Subject: [xmonad] MultiToggle with WorkspaceCursors In-Reply-To: References: <9e50a7c9-cd86-621f-3063-0a5fe3fd38f3@gmail.com> Message-ID: That makes sense, thanks again. I've revisited my initial approach, but might also take a stab at storing a cursors-like tree in extensibleState. In case it's of interest, this is a somewhat minimal config demonstrating the approach I'm revisiting: https://github.com/ivanbrennan/xmonad-testing/commit/8ff9e594d55885b0b2915fee71b1cd5f61598aa0#diff-74b618a2356f7943b297a5769de732a94848295a4bd563c68f998eafb843dd36 On Sun, Mar 26, 2023 at 12:21 AM Platon Pronko wrote: > Yes, you are right, my original analysis was incorrect. WorkspaceCursors > does indeed store a tree of cursors, and that is not derivable from the > current workspace id. > > However I still think that storing cursors state in LayoutModifier is > incorrect - layout information is local for every workspace, while cursors > state should be global, not duplicated per every workspace (I can't prove > it, but I definitely feel that there are bugs lurking in WorkspaceCursors > because of that duplication). > > I think you can achieve what you need without using WorkspaceCursors as a > layout modifier. You can store cursors state in a global variable and work > with it yourself. Something like: > > cursors = unsafePerformIO $ newIORef $ makeCursors [nominalIds, groupIds] > > (if you don't like unsafePerformIO, you also store cursors inside XMonad's > XState.extensibleState) > > Unfortunately you won't be able to reuse most of WorkspaceCursors stack > management functions, because they are either private or call modifyCursors > directly or indirectly. You'll have to copy them and adapt them to work on > your cursors state. > > -- > Best regards, > Platon Pronko > PGP 2A62D77A7A2CB94E > > On 2023-03-26 09:49, ivan wrote: > > Following up on this: > > > >> In my opinion WorkspaceCursors doesn't need to be a LayoutModifier at > all > > - current state can be derived from the list of cursors and currently > > focused workspace, no need to store it somewhere. > > > > I've been using WorkspaceCursors to switch between (simulated) groups of > > workspaces, relying on the Cursors state to remember which workspace has > > focus within each group. So switching to group G will focus whichever > > workspace was focused last time I visited that group. (Or, if it's the > > first time I've visited that group, its first workspace gets focus). > > > > The Cursors state feels like a natural way to implement that, but it's > not > > the only way. My initial implementation treated StackSet.workspaces as a > > recency list, and switching to group G meant finding the first workspace > in > > that list that was a member of G. When I started using Cursors state > > instead, I ran into the problem you explained. > > > > For now, I'll revisit my initial approach. > > > > Thanks again! > > > > On Sat, Mar 25, 2023 at 8:15 AM ivan wrote: > > > >> Amazing! Thank you so much for the clear explanation. > >> > >> On Sat, Mar 25, 2023 at 4:26 AM Platon Pronko > >> wrote: > >> > >>> Hi! > >>> > >>> WorkspaceCursors doesn't introduce any groups, it's just a glorified > >>> workspace switcher - underneath all the chrome it uses the standard > flat > >>> workspaces list. In essense it just defines some helper functions that > >>> allow user to imagine that workspaces are arranged as a > multidimensional > >>> cube and navigate along axes of said cube. But it still does it using > the > >>> usual StackSet.greedyView function. > >>> > >>> MultiToggle is irrelevant in this case, the same effect can be seen > with > >>> the boring Choose layout combinator (i.e. `Tall ||| Full`) - the layout > >>> state is "spilling" over to other workspaces. > >>> > >>> It seems that the problem arises because WorspaceCursors calls > `windows $ > >>> greedyView` inside LayoutClass.handleMessage function - current > workspace > >>> is switched at the same time as layout is updated, and Xmonad assigns > the > >>> updated layout to the new workspace. > >>> > >>> Here's a reproducer (should work on all configs that have a workspace > >>> with id "4"): > >>> > >>> ``` > >>> -- necessary language pragmas > >>> {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} > >>> > >>> -- imports > >>> import qualified XMonad.StackSet as W > >>> import XMonad.Layout.LayoutModifier(ModifiedLayout(..), > >>> LayoutModifier(handleMess)) > >>> import XMonad(Message, X, windows, sendMessage, fromMessage) > >>> > >>> -- Example LayoutModifier that showcases the issue. > >>> -- It does nothing except calling `greedyView "4"` upon reciept of > >>> SwitchWorkspace message > >>> data BadLayoutModifier a = BadLayoutModifier deriving (Read, Show) > >>> > >>> data SwitchWorkspace = SwitchWorkspace > >>> instance Message SwitchWorkspace > >>> > >>> instance LayoutModifier BadLayoutModifier a where > >>> handleMess BadLayoutModifier m = do > >>> case fromMessage m of > >>> Just SwitchWorkspace -> do > >>> windows $ W.greedyView "4" > >>> return $ Just BadLayoutModifier > >>> Nothing -> return Nothing > >>> > >>> -- add to keys (tweak the keybinding to your taste) > >>> , ((modm, xK_v), sendMessage SwitchWorkspace) > >>> > >>> -- prepend BadLayoutModifier to layoutHook > >>> layoutHook = > >>> ModifiedLayout BadLayoutModifier $ > >>> (Tall 1 (3/100) (1/2) ||| Full) > >>> ``` > >>> > >>> Steps to reproduce: > >>> > >>> 1. Recompile and restart Xmonad. > >>> 2. Toggle workspace "2" to "Tall" layout, toggle workspace "4" to > "Full" > >>> layout. > >>> 3. Switch to workspace "2". > >>> 4. Press keybinding to send the SwitchWorkspace message (Super-v in my > >>> case). > >>> 5. Observe that Xmonad switches to workspace "4", and layout on that > >>> workspace is now "Tall" instead of "Full" as set up originally. > >>> > >>> In my opinion WorkspaceCursors doesn't need to be a LayoutModifier at > all > >>> - current state can be derived from the list of cursors and currently > >>> focused workspace, no need to store it somewhere. This will sidestep > the > >>> problem of calling `greedyView` during layout update. > >>> > >>> -- > >>> Best regards, > >>> Platon Pronko > >>> PGP 2A62D77A7A2CB94E > >>> > >>> On 2023-03-24 23:27, Brandon Allbery wrote: > >>>> My guess is that MultiToggle doesn't and can't know about > >>>> WorkspaceCursors, and WorkspaceCursors doesn't and can't know that it > >>>> needs to duplicate the layout state for each group it introduces, so > >>>> any layout state change applies to all groups. > >>>> > >>>> On Fri, Mar 24, 2023 at 11:22 AM ivan wrote: > >>>>> > >>>>> Hi, I'm trying to get MultiToggle and WorkspaceCursors to play nicely > >>> with each other. > >>>>> > >>>>> Ordinarily, MultiToggle lets you apply a layout transformation to the > >>> current workspace without affecting the layouts of other workspaces. > E.g. > >>> if I toggle workspace 1 to Full layout, it won't impact the layouts > being > >>> used on workspaces 2, 3, etc. > >>>>> > >>>>> I've started using WorkspaceCursors (XMonad.Actions.WorkspaceCursors) > >>> to manage independent groups of workspaces, and noticed that if I use > it's > >>> functions (e.g. modifyLayer) to navigate between workspaces, layout > toggle > >>> states seem to bleed across workspaces rather than remaining > independent > >>> per workspace. > >>>>> > >>>>> For example, starting on workspace 1 with my regular Tall layout, I > >>> navigate to workspace 2 and toggle it to Full layout. Then I go back to > >>> workspace 1 and see that it, too, has been toggled to Full layout. > >>>>> > >>>>> I can't figure out exactly what's causing this, or how to fix it so > >>> that workspace layouts toggle independently. I'm hoping someone here > sees > >>> what I'm missing. > >>>>> > >>>>> I put together a minimal config to reproduce the problem: > >>>>> > >>> > https://github.com/ivanbrennan/xmonad-testing/commit/2e9541b0937eee31ae7f300e130dc55a9c5933af#diff-61bfccbc988708bd118b33f9299c64aa8b3e532e25cc8eaa3b716f53215fb196 > >>>>> > >>>>> The config provides two groups (A and B) of nine workspaces. > >>>>> > >>>>> group A: 1A 2A 3A 4A 5A 6A 7A 8A 9A > >>>>> group B: 1B 2B 3B 4B 5B 6B 7B 8B 9B > >>>>> > >>>>> Its layoutHook consists of: > >>>>> > >>>>> myLayoutHook = > >>>>> workspaceCursors cursors > >>>>> . avoidStruts > >>>>> . mkToggle1 FULL > >>>>> $ Tall 1 (3/100) (1/2) > >>>>> > >>>>> Keys super+1 .. super+9 use WorkspaceCursors functions to switch > >>> between workspaces within the currently active group. > >>>>> > >>>>> Keys super+ctrl+1 .. super+ctrl+2 use WorkspaceCursors functions to > >>> switch between groups A and B. > >>>>> > >>>>> Additionally, keys super+meta+1 .. super+meta+9 use traditional > >>> StackSet functions to switch between workspaces 1A .. 9A. I added > these for > >>> comparison, showing that MultiToggle state is recognized per-workspace > when > >>> using this form of navigation. > >>>>> > >>>>> I can't figure out the root cause. I suspect the most relevant pieces > >>> of code from WorkspaceCursors and MultiToggle are the following: > >>>>> > >>>>> > >>> > https://github.com/xmonad/xmonad-contrib/blob/e60805bd45ca2feb9ef3335d023daae5d02dbf4f/XMonad/Actions/WorkspaceCursors.hs#L204-L215 > >>>>> > >>>>> > >>> > https://github.com/xmonad/xmonad-contrib/blob/e60805bd45ca2feb9ef3335d023daae5d02dbf4f/XMonad/Layout/MultiToggle.hs#L193-L218 > >>>>> > >>>>> Does anyone know what I might be missing, or how I could debug > further > >>> to get to the root of the problem? > >>>>> > >>>>> Thanks! > >>>>> Ivan > >>>>> _______________________________________________ > >>>>> xmonad mailing list > >>>>> xmonad at haskell.org > >>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/xmonad > >>>> > >>>> > >>>> > >>> > >> > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: