Root: fix more fullscreen bugs

Moving fullscreen views between outputs now works properly.
A case in which we did not inform the client that it is no longer
fullscreen has been fixed as well.
This commit is contained in:
Isaac Freund 2023-03-01 12:16:53 +01:00
parent 5f0af38992
commit c1c72e23a3
No known key found for this signature in database
GPG Key ID: 86DED400DDFD7A11
2 changed files with 39 additions and 28 deletions

View File

@ -119,6 +119,9 @@ pending: struct {
///
/// This includes both floating/fullscreen views and those arranged in the layout.
wm_stack: wl.list.Head(View, .pending_wm_stack_link),
/// The view to be made fullscreen, if any.
/// This state should only be read/written inside Root.applyPending()
fullscreen: ?*View = null,
},
/// The state most recently sent to the layout generator and clients.

View File

@ -391,7 +391,7 @@ pub fn applyPending(root: *Self) void {
// Iterate the focus stack in order to ensure the currently focused/most
// recently focused view that requests fullscreen is given fullscreen.
var fullscreen_found = false;
output.pending.fullscreen = null;
{
var it = output.pending.focus_stack.iterator(.forward);
while (it.next()) |view| {
@ -405,33 +405,10 @@ pub fn applyPending(root: *Self) void {
view.pending.box = view.float_box;
}
if (!fullscreen_found and view.pending.fullscreen and
if (output.pending.fullscreen == null and view.pending.fullscreen and
view.pending.tags & output.pending.tags != 0)
{
fullscreen_found = true;
if (output.inflight.fullscreen != view) {
if (output.inflight.fullscreen) |old| {
old.setFullscreen(false);
old.pending.box = old.post_fullscreen_box;
old.inflight.box = old.pending.box;
}
output.inflight.fullscreen = view;
view.setFullscreen(true);
view.post_fullscreen_box = view.pending.box;
view.pending.box = .{
.x = 0,
.y = 0,
.width = undefined,
.height = undefined,
};
output.wlr_output.effectiveResolution(
&view.pending.box.width,
&view.pending.box.height,
);
view.inflight.box = view.pending.box;
}
output.pending.fullscreen = view;
}
view.inflight_focus_stack_link.remove();
@ -440,8 +417,12 @@ pub fn applyPending(root: *Self) void {
view.inflight = view.pending;
}
}
if (!fullscreen_found) {
output.inflight.fullscreen = null;
if (output.pending.fullscreen != output.inflight.fullscreen) {
if (output.inflight.fullscreen) |view| {
view.setFullscreen(false);
view.pending.box = view.post_fullscreen_box;
view.inflight.box = view.pending.box;
}
}
{
@ -456,6 +437,33 @@ pub fn applyPending(root: *Self) void {
}
}
{
// This must be done after the original loop completes to handle the
// case where a fullscreen is moved between outputs.
var output_it = root.outputs.first;
while (output_it) |node| : (output_it = node.next) {
const output = &node.data;
if (output.pending.fullscreen != output.inflight.fullscreen) {
if (output.pending.fullscreen) |view| {
view.setFullscreen(true);
view.post_fullscreen_box = view.pending.box;
view.pending.box = .{
.x = 0,
.y = 0,
.width = undefined,
.height = undefined,
};
output.wlr_output.effectiveResolution(
&view.pending.box.width,
&view.pending.box.height,
);
view.inflight.box = view.pending.box;
}
output.inflight.fullscreen = output.pending.fullscreen;
}
}
}
{
// Layout demands can't be sent until after the inflight stacks of
// all outputs have been updated.