Home > Net >  Config No Border For Specific Windows in Xmonad
Config No Border For Specific Windows in Xmonad

Time:10-30

The Goal

Set no border for specific windows in Xmonad.

Concrete example: I'd like firefox and feh always have no border. I want to set this not only for specific layout (e.g., single window) or specific window mode like float.

Attempt A

The most straight forward idea I have is to add a line in manageHook, which supposes to handle window creation. So I put a line in my customized ManageHook:

className =? "firefox" --> ask >>= \w -> liftX $ withDisplay $ \d -> io $ setWindowBorderWidth d w 0 >> idHook

It compiles, but unfortunately nothing happens when I start firefox.

Then I try to debug it:

  1. Tested the following and it works (new firefox window is floated), which indicates my customized ManageHook works, and my logic (modify the window followed by idHook) should be OK.
className =? "firefox" --> ask >>= liftX . float >> idHook
  1. Tested setWindowBorderWidth function by trying toggleBorder in XMonad.Actions.NoBorders. toggleBorder does something similarly calling setWindowBorderWidth. I used a key binding to invoke toggleBorder and it works. So setWindowBorderWidth works well during a Xmonad session after the window is created.

  2. Tested the following (found it here) but it doesn't work, same as my code (Attempt A).

className =? "firefox" --> ask >>= liftX . toggleBorder >> idHook

Attempt B

I find the hasBorder function in XMonad.Layout.NoBorders and also this answer, but I did not succeed.

If I only put className =? "firefox" --> hasBorder False in ManageHook but does not use layoutHook, nothing happens. I checked the source code of hasBorder and found it only broadcast a message but not set the border. I think I may need to invoke a layoutHook from XMonad.Layout.NoBorders to really set the border but I am not sure which one I should use. And I am also not sure if I need to specify any layout to use XMonad.Layout.NoBorders.

Questions

  1. Does Xmonad set border after ManageHook so my code in Attempt A is nullified?

  2. If Q1 is true, does it mean I can only set no border at LayoutHook (likely using XMonad.Layout.NoBorders) when the window is drawn on the screen?

  3. If Q2 is true, do I need to specify a layout and which layoutHook I can use?

CodePudding user response:

I'd go with attempt B:

Import the NoBorders module from xmonad-contrib:

import XMonad.Layout.NoBorders

Define your constraints in your manageHook:

className =? "feh"     --> hasBorder False
className =? "firefox" --> hasBorder False

And apply one of the module's layout modifiers, e.g. smartBorders to all of your layouts at once:

layoutHook = smartBorders $ Full ||| ResizableTall 1 (3/100) (1/2) [] ||| ...

Note: This will only affect windows created after recompiling and restarting XMonad. Already existing instances of firefox and feh would still have their borders until closed and restarted.

CodePudding user response:

I think I find the answer to my first question.

Does Xmonad set border after ManageHook so my code in Attempt A is nullified?

Yes.

Looks like xmonad window init logic is in XMonad/Operations.hs. When a window is created, the function manage() is called. The last three lines of the function:

  1. load ManageHook,
  2. apply ManageHook with runQuery(),
  3. run the windows() function, which loads border information from config and applies setInitialProperties() function to set borders according to the border config.

The last step setInitialProperties() calls setWindowBorderWidth() with border width loaded from config, which nullifies my setWindowBorderWidth() as a ManageHook step.

If I do not change this logic in XMonad/Operations.hs, it looks like I can only go with Attempt B. However, I really find the windows jumping issue annoying. This does not only occur in Full layout, I am using Tall with a single window. When I switch between two workspaces, both of which have a single window with no border, I see this jumping. The visual effect affects all pixels on screen since it needs to scale the entire window. Need to find a solution for this.

  • Related