Repository: qtile/qtile

Issue:
Bar moves when screen wakes up
<!--
Please do not ask general questions here! There are [community
contact](https://github.com/qtile/qtile#community) options for that.
-->

# Issue description

<!--
A brief discussion of what failed and how it failed. A description of
what you tried is helpful, i.e. "When I use lazy.kill() on a window I get
the following stack trace" instead of "Closing windows doesn't work".
-->

When my screen goes to sleep (screen blank) and I wake it up by moving the mouse, my bar has moved up a few pixels.
This only happens when the bar is configured to have a gap `margin=[15, 0, 0, 0]`

IMPORTANT: The screen has to actually go to sleep for this to happen. (give it some time after screen blank)

# Qtile version

<!--
Please include the exact commit hash of the version of Qtile that failed.
-->

0.18.1.dev0+g8e7ecc0a.d20210719

# Stack traces

<!--
Please attach any stack traces found in:

* `~/.xsession-errors`
* `~/.local/share/qtile/qtile.log`
-->

Nothing is written to `qtile.log` or `.xsession-errors`.

# Configuration

<!--
Please include a link or attach your configuration to the issue.
-->

This can be reproduced with a minor change to the default config.
Just add some margin to the default bottom bar `margin=[15, 0, 0, 0]`

Reload the configuration.
To force a screen blank run `xset dpms force off`.
Wait until the screen actually goes to sleep.
Move the mouse to wake it up again.

The bar should now have moved up a few pixels.



Discussion:
It also happens when switching modes with `xrandr`.
A possible workaround is setting `reconfigure_screens = False`.
But then I have to restart `qtile` manually, after changing the screen resolution (which I do ocassionally).
Interesting. Thanks for the report. I'll see if I can recreate here.

I can't immediately see why the position would change on a reconfigure but I can do some digging.
Restarting `qtile` can be done in the `subscribe.screen_change` hook.
So I have a satisfying workaround for now.
I have another finding:
If I just use the margin inside the layout and don't add any margin to the bar, the issue doesn't occur.
I can't recreate this. Setting the margin, running `picom -b`, turning the display off and on did not result in the bar moving for me.

Could you try something for me. In your config, add this function:
``` python
def log_bar_position(*args):
    logger.warning(f"{qtile.current_screen.bottom.info()=}")
```

and add a key binding to call that function:
```
    Key([mod, "shift"], "a",  #  Choose your own key
        lazy.function(log_bar_position))
```

Then start qtile, press the key combo, trigger the bar moving and press the combo again. Finally, copy the relevant lines from your log and post them here.
`2021-07-21 20:50:31,384 WARNING libqtile config.py:log_bar_position():L40 qtile.current_screen.bottom.info()={'size': 39, 'length': 2560, 'width': 2560, 'height': 24, 'position': 'bottom', 'widgets': [{'name': 'groupbox', 'offset': 0, 'length': 47, 'width': 47, 'height': 39, 'foreground': 'ffffff', 'text': ' '}, {'name': 'windowname', 'offset': 47, 'length': 2360, 'width': 2360, 'height': 39, 'foreground': 'ffffff', 'text': 'zsh'}, {'name': '<no name>', 'x': -1, 'y': -1, 'width': 1, 'height': 1, 'group': None, 'id': 4194465, 'floating': False, 'float_info': {'x': None, 'y': None, 'width': 1, 'height': 1}, 'maximized': False, 'minimized': False, 'fullscreen': False}, {'name': 'clock', 'offset': 2430, 'length': 130, 'width': 130, 'height': 39, 'foreground': 'ffffff', 'text': 'Wed 21.07.2021 20:50'}], 'window': 4194461}`

`2021-07-21 20:51:19,568 WARNING libqtile config.py:log_bar_position():L40 qtile.current_screen.bottom.info()={'size': 39, 'length': 2560, 'width': 2560, 'height': 24, 'position': 'bottom', 'widgets': [{'name': 'groupbox', 'offset': 0, 'length': 47, 'width': 47, 'height': 39, 'foreground': 'ffffff', 'text': ' '}, {'name': 'windowname', 'offset': 47, 'length': 2360, 'width': 2360, 'height': 39, 'foreground': 'ffffff', 'text': 'zsh'}, {'name': '<no name>', 'x': -1, 'y': -1, 'width': 1, 'height': 1, 'group': None, 'id': 4194465, 'floating': False, 'float_info': {'x': None, 'y': None, 'width': 1, 'height': 1}, 'maximized': False, 'minimized': False, 'fullscreen': False}, {'name': 'clock', 'offset': 2430, 'length': 130, 'width': 130, 'height': 39, 'foreground': 'ffffff', 'text': 'Wed 21.07.2021 20:51'}], 'window': 4194461}`

As far as I can tell both outputs are the same.
But I can still see, that the bar moved up:

![2021-07-21-210146_2560x1080_scrot](https://user-images.githubusercontent.com/65959608/126545087-2c0f0b54-75b9-452c-a3c3-ba652de24682.png)

By the way, I think `picom` has nothing to do with it. I'm having the same issue without it.

Sorry, realised that `info()` doesn't include the y position which is what we're checking. Try changing function to:
```
def log_bar_position(*args):
    logger.warning(f"{qtile.current_screen.bottom.y=}")
```
```
2021-07-21 21:12:25,412 WARNING libqtile config.py:log_bar_position():L40 qtile.current_screen.bottom.y=1056
2021-07-21 21:13:02,836 WARNING libqtile config.py:log_bar_position():L40 qtile.current_screen.bottom.y=1041
```

Yep, there it is!
I have the feeling, that the upper and lower margins of the bar were swapped.
I've tested with `margin=[15, 0, 5, 0]` to see if they actually swap. But as it turns out the upper margin just gets moved to the lower margin.
OK - that gives me something to look for.

Does it happen on every layout?
I've now checked them all. The issue persists on every layout.
But it was a nice chance to explore them all! ;-)
Ok - I can now recreate this. Set margin on the bar as per your example and then, in a python shell, run:
``` python
from libqtile.command.client import InteractiveCommandClient
c = InteractiveCommandClient()
c.reconfigure_screens()
```
Bar moves up.

Now I just need to trace the steps from there...

Resolving patch:
diff --git a/libqtile/bar.py b/libqtile/bar.py
--- a/libqtile/bar.py
+++ b/libqtile/bar.py
@@ -65,6 +65,7 @@ def __init__(self, size):
     def _configure(self, qtile, screen):
         self.qtile = qtile
         self.screen = screen
+        self.size = self.initial_size
         # If both horizontal and vertical gaps are present, screen corners are
         # given to the horizontal ones
         if screen.top is self:


Test patch: