<div dir="ltr"><div dir="ltr">Following up on this:<div><br></div><div>> 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.</div><div><br></div><div>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).</div><div><br></div><div>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.</div><div><br></div><div>For now, I'll revisit my initial approach.</div><div><br></div><div>Thanks again!</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Mar 25, 2023 at 8:15 AM ivan <<a href="mailto:ivan.brennan@gmail.com">ivan.brennan@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Amazing! Thank you so much for the clear explanation.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Mar 25, 2023 at 4:26 AM Platon Pronko <<a href="mailto:platon7pronko@gmail.com" target="_blank">platon7pronko@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi!<br>
<br>
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.<br>
<br>
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.<br>
<br>
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.<br>
<br>
Here's a reproducer (should work on all configs that have a workspace with id "4"):<br>
<br>
```<br>
-- necessary language pragmas<br>
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}<br>
<br>
-- imports<br>
import qualified XMonad.StackSet as W<br>
import XMonad.Layout.LayoutModifier(ModifiedLayout(..), LayoutModifier(handleMess))<br>
import XMonad(Message, X, windows, sendMessage, fromMessage)<br>
<br>
-- Example LayoutModifier that showcases the issue.<br>
-- It does nothing except calling `greedyView "4"` upon reciept of SwitchWorkspace message<br>
data BadLayoutModifier a = BadLayoutModifier deriving (Read, Show)<br>
<br>
data SwitchWorkspace = SwitchWorkspace<br>
instance Message SwitchWorkspace<br>
<br>
instance LayoutModifier BadLayoutModifier a where<br>
   handleMess BadLayoutModifier m = do<br>
     case fromMessage m of<br>
       Just SwitchWorkspace -> do<br>
         windows $ W.greedyView "4"<br>
         return $ Just BadLayoutModifier<br>
       Nothing -> return Nothing<br>
<br>
-- add to keys (tweak the keybinding to your taste)<br>
   , ((modm, xK_v), sendMessage SwitchWorkspace)<br>
<br>
-- prepend BadLayoutModifier to layoutHook<br>
layoutHook =<br>
   ModifiedLayout BadLayoutModifier $<br>
   (Tall 1 (3/100) (1/2) ||| Full)<br>
```<br>
<br>
Steps to reproduce:<br>
<br>
1. Recompile and restart Xmonad.<br>
2. Toggle workspace "2" to "Tall" layout, toggle workspace "4" to "Full" layout.<br>
3. Switch to workspace "2".<br>
4. Press keybinding to send the SwitchWorkspace message (Super-v in my case).<br>
5. Observe that Xmonad switches to workspace "4", and layout on that workspace is now "Tall" instead of "Full" as set up originally.<br>
<br>
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.<br>
<br>
--<br>
Best regards,<br>
Platon Pronko<br>
PGP 2A62D77A7A2CB94E<br>
<br>
On 2023-03-24 23:27, Brandon Allbery wrote:<br>
> My guess is that MultiToggle doesn't and can't know about<br>
> WorkspaceCursors, and WorkspaceCursors doesn't and can't know that it<br>
> needs to duplicate the layout state for each group it introduces, so<br>
> any layout state change applies to all groups.<br>
> <br>
> On Fri, Mar 24, 2023 at 11:22 AM ivan <<a href="mailto:ivan.brennan@gmail.com" target="_blank">ivan.brennan@gmail.com</a>> wrote:<br>
>><br>
>> Hi, I'm trying to get MultiToggle and WorkspaceCursors to play nicely with each other.<br>
>><br>
>> 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.<br>
>><br>
>> 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.<br>
>><br>
>> 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.<br>
>><br>
>> 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.<br>
>><br>
>> I put together a minimal config to reproduce the problem:<br>
>> <a href="https://github.com/ivanbrennan/xmonad-testing/commit/2e9541b0937eee31ae7f300e130dc55a9c5933af#diff-61bfccbc988708bd118b33f9299c64aa8b3e532e25cc8eaa3b716f53215fb196" rel="noreferrer" target="_blank">https://github.com/ivanbrennan/xmonad-testing/commit/2e9541b0937eee31ae7f300e130dc55a9c5933af#diff-61bfccbc988708bd118b33f9299c64aa8b3e532e25cc8eaa3b716f53215fb196</a><br>
>><br>
>> The config provides two groups (A and B) of nine workspaces.<br>
>><br>
>>      group A: 1A 2A 3A 4A 5A 6A 7A 8A 9A<br>
>>      group B: 1B 2B 3B 4B 5B 6B 7B 8B 9B<br>
>><br>
>> Its layoutHook consists of:<br>
>><br>
>>      myLayoutHook =<br>
>>        workspaceCursors cursors<br>
>>          . avoidStruts<br>
>>          . mkToggle1 FULL<br>
>>          $ Tall 1 (3/100) (1/2)<br>
>><br>
>> Keys super+1 .. super+9 use WorkspaceCursors functions to switch between workspaces within the currently active group.<br>
>><br>
>> Keys super+ctrl+1 .. super+ctrl+2 use WorkspaceCursors functions to switch between groups A and B.<br>
>><br>
>> 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.<br>
>><br>
>> I can't figure out the root cause. I suspect the most relevant pieces of code from WorkspaceCursors and MultiToggle are the following:<br>
>><br>
>> <a href="https://github.com/xmonad/xmonad-contrib/blob/e60805bd45ca2feb9ef3335d023daae5d02dbf4f/XMonad/Actions/WorkspaceCursors.hs#L204-L215" rel="noreferrer" target="_blank">https://github.com/xmonad/xmonad-contrib/blob/e60805bd45ca2feb9ef3335d023daae5d02dbf4f/XMonad/Actions/WorkspaceCursors.hs#L204-L215</a><br>
>><br>
>> <a href="https://github.com/xmonad/xmonad-contrib/blob/e60805bd45ca2feb9ef3335d023daae5d02dbf4f/XMonad/Layout/MultiToggle.hs#L193-L218" rel="noreferrer" target="_blank">https://github.com/xmonad/xmonad-contrib/blob/e60805bd45ca2feb9ef3335d023daae5d02dbf4f/XMonad/Layout/MultiToggle.hs#L193-L218</a><br>
>><br>
>> Does anyone know what I might be missing, or how I could debug further to get to the root of the problem?<br>
>><br>
>> Thanks!<br>
>> Ivan<br>
>> _______________________________________________<br>
>> xmonad mailing list<br>
>> <a href="mailto:xmonad@haskell.org" target="_blank">xmonad@haskell.org</a><br>
>> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/xmonad" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/xmonad</a><br>
> <br>
> <br>
> <br>
</blockquote></div>
</blockquote></div></div>