Output of awesome --version:
awesome v4.0 (Harder, Better, Faster, Stronger)
• Compiled against Lua 5.3.3 (running with Lua 5.3)
• D-Bus support: ✔
• execinfo support: ✔
• RandR 1.5 support: ✘
• LGI version: 0.9.1
How to reproduce the issue:
On my machine:
Actual result:
All clients have disappeared and all tags are empty.
Expected result:
Clients remain in the tags/positions they were in previously.
Other potentially relevant information:
This may not be broken on other machines. I think the issue is that my laptop's display is being removed just prior to the machine being put to sleep, and is being restored just after the machine is woken up. This is supported by the fact that connect_for_each_screen is fired when I open the lid, with a new screen object each time. Everything functions as I would expect (ie. clients remain visible and in the correct tags/positions) if I put the system to sleep without closing the lid (eg. by pressing the power button).
All the clients still exist after they have disappeared, and can be brought back by restarting awesome.
This line in the news file:
echo 'for _,c in ipairs(client.get()) do require("awful.placement").no_offscreen(c) end' | awesome-client
doesn't bring the clients back, but using this:
echo 'for _,c in ipairs(client.get()) do c:move_to_screen(1) end' | awesome-client
brings them all back.
Could you compare output of xrandr --verbose before and after closing the lid? I.e: xrandr --verbose > before.txt, close and reopen xrandr --verbose > after.txt ; diff -Nurp before.txt after.txt.
Also, to see what exactly is going on, add the following to your rc.lua and find the output:
screen.connect_signal("added", function(s) print(os.date(), "added", s, require("gears.debug").dump_return(s.outputs) end)
screen.connect_signal("removed", function(s) print(os.date(), "removed", s, require("gears.debug").dump_return(s.outputs) end)
screen.connect_signal("property::geometry", function(s) print(os.date(), "geometry", s, require("gears.debug").dump_return(s.outputs) end)
screen.connect_signal("property::outputs", function(s) print(os.date(), "outputs", s, require("gears.debug").dump_return(s.outputs) end)
screen.connect_signal("primary_changed", function(s) print(os.date(), "primary_changed", s, require("gears.debug").dump_return(s.outputs) end)
(Any other ideas for what signals might be interesting? I am not after something specific, I am just trying to list all signals so that we see what is going on. The os.date() is so that you can tell us what happens when closing the lid and what happens when opening (keep it closed for a few seconds so that this really helps))
Disclaimer: Consider the above pseudo-code. I have not actually tested it. :-)
Only the "removed" signal seems to be firing. I closed my computer and opened it again twice and got this output (I added newlines between things):
Sun Jan 1 23:31:59 2017
removed
screen: 0x18e3b58
table: 0x23db670
LVDS1 : table: 0x23db6e0
mm_width : 344 (number)
mm_height : 193 (number)
Sun Jan 1 23:32:16 2017
removed
screen: 0x1fe2018
table: 0x2b51a60
LVDS1 : table: 0x2b51ad0
mm_width : 344 (number)
mm_height : 193 (number)
With the xrandr output, the only difference is the timestamp for each display. For example, but it's the same for each of the displays:
Identifier: 0x89
- Timestamp: 28613
+ Timestamp: 1601117
Subpixel: horizontal rgb
Gamma: 1.0:1.3:1.8
Brightness: 1.0
Ok... So far, no really good ideas. The following is a bad idea: Let's just ignore the removal of the last screen (something similar is needed in fake_remove, or do we just allow people to shoot themselves into their foot?):
diff --git a/objects/screen.c b/objects/screen.c
index 93ce2288f..0da47e362 100644
--- a/objects/screen.c
+++ b/objects/screen.c
@@ -670,7 +670,7 @@ screen_refresh(void)
}
/* Remove screens which are gone */
- for(int i = 0; i < globalconf.screens.len; i++) {
+ for(int i = 0; i < globalconf.screens.len && globalconf.screens.len > 1; i++) {
screen_t *old_screen = globalconf.screens.tab[i];
bool found = false;
foreach(new_screen, new_screens)
Perhaps it is a good idea to change Lua-side of things to recover all clients when we go from zero to one screens?
Also: Wow, I am happy that nothing crashed when a client's screen became nil.
So, what's a good plan?
I just tested this patch and it's fixed my issue.
With the above patch, could it happen that you get two screens, although there is only one? (i.e. the screen gets removed, but we keep it; and then it gets re-added)
@blueyed Nope. We internally store the id that the X server assigns to a CRTC/MONITOR (a number). On any RandR event we then build a list on "how things should be" and use the id to know which screens to copy from the existing set of screens. Any unmatched screens are removed.
In your scenario, the id allows to match the screen to its "old being".
The only case where the above patch makes a difference is when RandR says that there are no CRTCs/MONITORs. In this case some "random" screen (the one with highest index) is kept.
Same thing happening here on v4.0. In my case, it's switching to/from an external monitor with my laptop:
I confirm that I have this issue as well. I found small workaround, when you restore and there is no windows, when you restart awesome (menu->restart) all windows reappear again, all on the second tag.
Happening here as well, would love to see a fix. A pkill -HUP awesome will bring awesome back into a sane state, but doing that on every resume gets old pretty quick...
@squisher You can always use the proposed fix:
screen.connect_signal("list", awesome.restart)
Or fixes recommended by some other users:
Fixed by #2223 for me, all my clients are kept and restored with their proper tag, but I need this (stupid copypasting without understanding what it does) in rc.lua:
tag.connect_signal("request::screen", function(t)
for s in screen do
if s ~= t.screen then
local t2 = awful.tag.find_by_name(s, t.name)
if t2 then
t:swap(t2)
else
t.screen = s
end
return
end
end
end)
Closing as per last comment: this appears to have been fixed in #2223.
Most helpful comment
I confirm that I have this issue as well. I found small workaround, when you restore and there is no windows, when you restart awesome (menu->restart) all windows reappear again, all on the second tag.