Fix WM after switching TTYs and back
When all outputs are removed, an "orphan" list is created for any remaining windows. I was accidentally just immediately re-assigning the orphan windows back to the final output being removed, because I was checking the seat's focused output to early. This correctly checks if the seat is changing focus *before* checking the seat's current focus. Fixes: #3
This commit is contained in:
parent
440d58c8d8
commit
3af39def4a
1 changed files with 30 additions and 13 deletions
|
|
@ -162,28 +162,45 @@ fn manage(wm: *WindowManager) void {
|
||||||
const seat = wm.seats.first();
|
const seat = wm.seats.first();
|
||||||
// We want the seat's focused output if one exists, but otherwise just
|
// We want the seat's focused output if one exists, but otherwise just
|
||||||
// whatever output is hanging around is fine.
|
// whatever output is hanging around is fine.
|
||||||
const output = if (seat) |s|
|
const output = if (seat) |s| blk: {
|
||||||
s.focused_output orelse if (s.pending_manage.output) |pending_output|
|
if (s.pending_manage.output) |pending_output| {
|
||||||
switch (pending_output) {
|
// We need to check the pending manage first because the seat doesn't get managed
|
||||||
|
// until later in this function.
|
||||||
|
break :blk switch (pending_output) {
|
||||||
.output => |output| output,
|
.output => |output| output,
|
||||||
.clear_focus => null,
|
.clear_focus => null,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// If there's not a pending change for output focus, we can use the currently
|
||||||
|
// focused output. This still works if it's null, because null is handled in the
|
||||||
|
// next block.
|
||||||
|
break :blk s.focused_output;
|
||||||
}
|
}
|
||||||
else
|
} else blk: {
|
||||||
null
|
// If there's no seat, we just try get the first output in the wm's output list. This
|
||||||
else
|
// is null if there are no outputs, which is handled correctly in the next block.
|
||||||
wm.outputs.first();
|
break :blk wm.outputs.first();
|
||||||
|
};
|
||||||
|
|
||||||
if (output) |o| {
|
if (output) |o| {
|
||||||
var it = wm.orphan_windows.iterator(.forward);
|
var it = wm.orphan_windows.iterator(.forward);
|
||||||
while (it.next()) |window| {
|
while (it.next()) |window| {
|
||||||
window.pending_manage.pending_output = .{ .output = o };
|
window.pending_manage.pending_output = .{ .output = o };
|
||||||
}
|
}
|
||||||
if (seat) |s| {
|
if (seat) |s| blk: {
|
||||||
|
// If we don't have a focused window, iterate through the orphans and try see if any
|
||||||
|
// have matching tags. For now, that's always only 0x8000, but maybe I'll had output
|
||||||
|
// caching later so it can keep track of focused tags when the last output is destroyed.
|
||||||
|
// We set focus to the first window we find on the matching tagmask.
|
||||||
if (s.focused_window == null) {
|
if (s.focused_window == null) {
|
||||||
if (wm.orphan_windows.first()) |first| {
|
var window_it = wm.orphan_windows.iterator(.forward);
|
||||||
s.pending_manage.window = .{ .window = first };
|
while (window_it.next()) |window| {
|
||||||
|
if (o.tags & window.tags != 0) {
|
||||||
|
s.pending_manage.window = .{ .window = window };
|
||||||
s.pending_manage.should_warp_pointer = true;
|
s.pending_manage.should_warp_pointer = true;
|
||||||
} else unreachable;
|
break :blk;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
o.windows.appendList(&wm.orphan_windows);
|
o.windows.appendList(&wm.orphan_windows);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue