Reputation: 432
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.
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:
ManageHook
works, and my logic (modify the window followed by idHook
) should be OK.className =? "firefox" --> ask >>= liftX . float >> idHook
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.
Tested the following (found it here) but it doesn't work, same as my code (Attempt A).
className =? "firefox" --> ask >>= liftX . toggleBorder >> idHook
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
.
Does Xmonad set border after ManageHook
so my code in Attempt A is nullified?
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?
If Q2 is true, do I need to specify a layout and which layoutHook
I can use?
Upvotes: 1
Views: 1099
Reputation: 432
I think I find the answers to my questions.
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:
ManageHook
,ManageHook
with runQuery()
,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.
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?
No. Another possibility besides LayoutHook
is logHook
.
If Q2 is true, do I need to specify a layout and which layoutHook I can use?
Yes. However, if logHook
is used, there is no need to overwrite the default layouts.
Solution
Let's put up a new XMonad extension to achieve this functionality that people asked 12 years ago.
Upvotes: 0
Reputation: 36068
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.
Upvotes: 2