xmonad/xmonad

[ISSUE] Fix Tabs and Decoration spacing using a common Spacing Raw for layouts

Opened this issue · 15 comments

Hi
referring to #474

I require a fix for Tabs and Decorations behavior with a common setted spacing in myLayoutHook

Assuming that the following are the pertinent parts of my configuration:

import XMonad.Layout.Tabbed
import XMonad.Layout.SubLayouts
import XMonad.Layout.Spacing
import XMonad.Layout.Gaps
.......
......
......
myDefaults =  def {
......
......
manageHook = myManageHook
}

.........
........
-- Makes setting the spacingRaw simpler to write. The spacingRaw module adds a configurable amount of space around windows.
mySpacing :: Integer -> l a -> XMonad.Layout.LayoutModifier.ModifiedLayout Spacing l a
mySpacing i = spacingRaw False (Border i i i i) True (Border i i i i) True

 grid           = renamed [Replace "grid"]
                   ............
                  $ addTabs shrinkText myTabTheme                              
                  $ subLayout [] (Simplest)                                                           
                  $ GridRatio (3/2)                       
threeColMid    = renamed [Replace "threeColMid"]
                  $ avoidFloats                                                                 
                   ..........
                  $ addTabs shrinkText myTabTheme                                
                  $ subLayout [] (Simplest)                                       
                  $ ResizableThreeColMid 1 (3/100) (1/2)  []               

tabs           = renamed [Replace "tabs"]
                  $ avoidFloats                                            
                  .....
                  $ addTabs shrinkText myTabTheme                                
                  $ subLayout [] Simplest                                                                                      
                  $ noBorders Simplest                                        

simpleFloat    = renamed [Replace "simpleFloat"]                        
                  $ addTabs shrinkText myTabTheme                                  
                  $ smartBorders                                                  
                  $ subLayout [] Simplest                                                                                 
                  $ simplestFloat                                                

.......
.......
-- Layours common settings
myLayoutHook = avoidStruts                                           
               ......
  
         $ mySpacing 5                ----->   SPACING FOR ALL THE LAYOUTS   
            ......
            ......

The result is tabs and decoration with spacing between the tabs and the window

Screenshot-2023-10-13-1697225715_screenshot_1920x1080

The result should be no space between tabs and windows, as it happens setting individual spacing for each layout

Screenshot-2023-10-14-1697303188_screenshot_1920x1080

I think that, in the case I use a declared spacing for each layout, this issue can be fixed by writing a function , a transformer or a layout modifier that toggles on/off spacing and gaps, hiding the bar , that must still persistent even if I switch layout in the same workspace

I'm trying this from weeks, without success .

I require help from people more experienced than me , I hope that guys like @geekosaur or other guys can help me. This could be also a great improvement for xmonad in general

I'm currently using this function , but when I switch layout in the current workspace, spacing & gaps reappears

toggleSpacingGaps :: X ()
toggleSpacingGaps = do
    sendMessage ToggleStruts
    toggleScreenSpacingEnabled
    toggleWindowSpacingEnabled
    sendMessage ToggleGaps

I hope you could help me. Please tell me also if I've to move that in a new issue (closing this one) or not

Thank you all in advance

I think what you want is a custom MultiToggle which is applied to your layout; MultiToggle is a bit painful to use, but it supports switching layout modifiers (see MIRROR and NOBORDERS in https://hackage.haskell.org/package/xmonad-contrib-0.17.1/docs/src/XMonad.Layout.MultiToggle.Instances.html#StdTransformers). The new instance would look something like

{-# LANGUAGE TypeSynonymInstances, MultiParamTypeClasses #-}
import XMonad
import XMonad.Layout.MultiToggle
…
data SpacingGaps = SPACINGGAPS
  deriving (Read, Show, Eq)
instance Transformer SpacingGaps Window where
  transform SPACINGGAPS _ k = k (\(ModifiedLayout _ x) -> noBorders x) (\(ModifiedLayout _ x) -> spacingRaw … x)

(replace the second "" with your spacingRaw parameters). You then use mkToggle (single SPACINGGAPS) (…list of layouts…) in your layout, and bind a key to sendMessage $ Toggle SPACINGGAPS.

Sorry, I got this backwards and possibly wrong (I need to make sure spacingRaw uses ModifiedLayout; if it doesn't your layout will crash / become Full), plus you need to put your spacingRaw just before the mkToggle in your layoutHook. I'm kinda falling-down tired right now, so I'll expand on this and fix it tomorrow.

Sorry, I got this backwards and possibly wrong (I need to make sure spacingRaw uses ModifiedLayout; if it doesn't your layout will crash / become Full), plus you need to put your spacingRaw just before the mkToggle in your layoutHook. I'm kinda falling-down tired right now, so I'll expand on this and fix it tomorrow.

Thank you for your kindness and your support.
Please keep me informed about

If this can be helpful to you, the code above give me the following error:

   • Couldn't match expected type: ModifiedLayout m1 l1 Window
                  with actual type: ModifiedLayout m0 l0 Window
                                    -> ModifiedLayout WithBorder l0 Window
    • The lambda expression ‘\ (ModifiedLayout _ x) -> noBorders x’
      has one value argument,
        but its type ‘ModifiedLayout m1 l1 Window’ has none
      In the first argument of ‘k’, namely
        ‘(\ (ModifiedLayout _ x) -> noBorders x)’
      In the expression:
        k (\ (ModifiedLayout _ x) -> noBorders x)
          (\ (ModifiedLayout _ x) -> mySpacing 5 x)
    |
520 |   transform SPACINGGAPS _ k = k (\(ModifiedLayout _ x) -> noBorders x) (\(ModifiedLayout _ x) -> mySpacing 5 x)
    |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

I used the following code for a test , this toggle on/of an increment of 5 pixel to mySpacing . This works, but only increment/decrement the spacing (if I already started with a 5px spacing, the spacing will increment of + 5px, becoming 10px)

mySpacing :: Integer -> l a -> XMonad.Layout.LayoutModifier.ModifiedLayout Spacing l a
mySpacing i = spacingRaw False (Border i i i i) True (Border i i i i) True

data SPACING = SPACING deriving (Read, Show, Eq, Typeable)
instance Transformer SPACING Window where
    transform SPACING x k = k (mySpacing 5 x) (\(ModifiedLayout _ x') -> x')

myLayoutHook = avoidStruts            
               $ T.toggleLayouts simplestFloat     
               $ mouseResize                                             
               $ mkToggle (NBFULL ?? NOBORDERS ?? SPACING ?? EOT) myDefaultLayouts    -- Set Toggles

Sigh. It looks like this isn't flexible enough for what you want; toggling a modifier on can only add modifiers, not remove them. It may be possible to "edit" the modifier that is passed in, but I doubt it because I think that puts the modifier in the wrong place.

Sigh. It looks like this isn't flexible enough for what you want; toggling a modifier on can only add modifiers, not remove them. It may be possible to "edit" the modifier that is passed in, but I doubt it because I think that puts the modifier in the wrong place.

Thank you so much !

So , in this case , can I feature-request a "toggle custom function" functionality ?

In the mean time , I' ll continue to try, searching for a workaround

Oh, you can write it, it would just need to be its own layout modifier. I think. I'm still thinking about the above and how it might be doable without that.

Oh, you can write it, it would just need to be its own layout modifier. I think. I'm still thinking about the above and how it might be doable without that.

If you find a solution, please keep me informed

Thank you again!

Let's try this:

data SpacingGaps = SPACINGGAPS
  deriving (Read, Show, Eq)
instance Transformer SpacingGaps Window where
  transform SPACINGGAPS (ModifiedLayout _ x) k = k (noBorders x) (const (mySpacing x))

and put your initial mySpacing after the mkToggle (single SPACINGGAPS).

Also you were seeing an increment because the initial mySpacing wasn't being removed, since I had it in the wrong place. And you weren't removing yours either, so you just got a stack of mySpacings piling up.

Let's try this:

data SpacingGaps = SPACINGGAPS
  deriving (Read, Show, Eq)
instance Transformer SpacingGaps Window where
  transform SPACINGGAPS _ (ModifiedLayout _ x) k = k (noBorders x) (const (mySpacing x))

and put your initial mySpacing after the mkToggle (single SPACINGGAPS).

Also you were seeing an increment because the initial mySpacing wasn't being removed, since I had it in the wrong place. And you weren't removing yours either, so you just got a stack of mySpacings piling up.

If I add as following

data SpacingGaps = SPACINGGAPS
  deriving (Read, Show, Eq)
instance Transformer SpacingGaps Window where
  transform SPACINGGAPS _ (ModifiedLayout _ x) k = k (noBorders x) (const (mySpacing 5  x))

I have the following error during recompliling

xmonad.hs:521:28: error:
    • Couldn't match expected type: l'0 Window
                                    -> (l'0 Window -> l Window) -> b
                  with actual type: ModifiedLayout m0 l0 Window
    • In the pattern: ModifiedLayout _ x
      In an equation for ‘transform’:
          transform SPACINGGAPS _ (ModifiedLayout _ x) k
            = k (noBorders x) (const (mySpacing 5 x))
      The equation(s) for ‘transform’ have four value arguments,
        but its type ‘SpacingGaps
                      -> l Window
                      -> (forall (l' :: * -> *).
                          LayoutClass l' Window =>
                          l' Window -> (l' Window -> l Window) -> b)
                      -> b’
        has only three
    • Relevant bindings include
        transform :: SpacingGaps
                     -> l Window
                     -> (forall (l' :: * -> *).
                         LayoutClass l' Window =>
                         l' Window -> (l' Window -> l Window) -> b)
                     -> b
          (bound at xmonad.hs:521:3)
    |
521 |   transform SPACINGGAPS _ (ModifiedLayout _ x) k = k (noBorders x) (const (mySpacing 5 x))
    |                            ^^^^^^^^^^^^^^^^^^

Please check the file for errors.

Sorry, looks like I stuck an extra _ in there. Remove the one just after SPACINGGAPS. I'm editing the original message.

Let's try this:

data SpacingGaps = SPACINGGAPS
  deriving (Read, Show, Eq)
instance Transformer SpacingGaps Window where
  transform SPACINGGAPS (ModifiedLayout _ x) k = k (noBorders x) (const (mySpacing x))

and put your initial mySpacing after the mkToggle (single SPACINGGAPS).

Also you were seeing an increment because the initial mySpacing wasn't being removed, since I had it in the wrong place. And you weren't removing yours either, so you just got a stack of mySpacings piling up.


xmonad.hs:521:67: error:
    • Couldn't match type ‘l’ with ‘ModifiedLayout Spacing l0’
      Expected: ModifiedLayout WithBorder l0 Window -> l Window
        Actual: ModifiedLayout WithBorder l0 Window
                -> ModifiedLayout Spacing l0 Window
      ‘l’ is a rigid type variable bound by
        the type signature for:
          transform :: forall (l :: * -> *) b.
                       LayoutClass l Window =>
                       SpacingGaps
                       -> l Window
                       -> (forall (l' :: * -> *).
                           LayoutClass l' Window =>
                           l' Window -> (l' Window -> l Window) -> b)
                       -> b
        at xmonad.hs:521:3-11
    • In the second argument of ‘k’, namely ‘(const (mySpacing 5 x))’
      In the expression: k (noBorders x) (const (mySpacing 5 x))
      In an equation for ‘transform’:
          transform SPACINGGAPS (ModifiedLayout _ x) k
            = k (noBorders x) (const (mySpacing 5 x))
    • Relevant bindings include
        k :: forall (l' :: * -> *).
             LayoutClass l' Window =>
             l' Window -> (l' Window -> l Window) -> b
          (bound at xmonad.hs:521:46)
        x :: l0 Window (bound at xmonad.hs:521:43)
        transform :: SpacingGaps
                     -> l Window
                     -> (forall (l' :: * -> *).
                         LayoutClass l' Window =>
                         l' Window -> (l' Window -> l Window) -> b)
                     -> b
          (bound at xmonad.hs:521:3)
    |
521 |   transform SPACINGGAPS (ModifiedLayout _ x) k = k (noBorders x) (const (mySpacing 5 x))
    |                                                                                                                             ^^^^^^^^^^^^^^^^^^^^^

Please check the file for errors.

I'm using mySpacing 5 as value

☹ Looks like it insists that the "remove" clause only does a remove, not an add. So it's still not flexible enough to do this.

☹ Looks like it insists that the "remove" clause only does a remove, not an add. So it's still not flexible enough to do this.

Thank you for your support! I'll try to find other solutions , and , if I'll have good news, I'll report here