view: send activated/fullscreen configures immediately

The transaction system exists to coordinate size changes of all views
in a layout in order to achieve frame perfection. Since many clients
do not need to commit a new buffer in response to a activated state
change alone, this breaks things when such a configure event is tracked
by the transaction system. Instead, simply send activated and fullscreen
configures right away but still track this state in a double-buffered
way so that e.g. border color changes based on focus are frame-perfect.

This also fixes a related issue with the transaction system where views
that did not need to commit in response to our first configure were not
rendered until their next frame.
This commit is contained in:
Isaac Freund
2021-06-08 04:38:08 +00:00
parent 021fd8f376
commit e90474657f
5 changed files with 72 additions and 27 deletions

View File

@ -196,29 +196,30 @@ pub fn setFocusRaw(self: *Self, new_focus: FocusTarget) void {
// still clear the focus.
if (if (target_surface) |wlr_surface| server.input_manager.inputAllowed(wlr_surface) else true) {
// First clear the current focus
if (self.focused == .view) {
self.focused.view.pending.focus -= 1;
// This is needed because xwayland views don't double buffer
// activated state.
if (build_options.xwayland and self.focused.view.impl == .xwayland_view)
self.focused.view.impl.xwayland_view.xwayland_surface.activate(false);
if (self.focused.view.pending.focus == 0 and !self.focused.view.pending.fullscreen) {
self.focused.view.pending.target_opacity = server.config.opacity.unfocused;
}
switch (self.focused) {
.view => |view| {
view.pending.focus -= 1;
if (view.pending.focus == 0) {
view.setActivated(false);
if (!view.pending.fullscreen) {
view.pending.target_opacity = server.config.opacity.unfocused;
}
}
},
.layer, .none => {},
}
// Set the new focus
switch (new_focus) {
.view => |target_view| {
std.debug.assert(self.focused_output == target_view.output);
target_view.pending.focus += 1;
// This is needed because xwayland views don't double buffer
// activated state.
if (build_options.xwayland and target_view.impl == .xwayland_view)
target_view.impl.xwayland_view.xwayland_surface.activate(true);
if (!target_view.pending.fullscreen) {
target_view.pending.target_opacity = server.config.opacity.focused;
if (target_view.pending.focus == 0) {
target_view.setActivated(true);
if (!target_view.pending.fullscreen) {
target_view.pending.target_opacity = server.config.opacity.focused;
}
}
target_view.pending.focus += 1;
},
.layer => |target_layer| std.debug.assert(self.focused_output == target_layer.output),
.none => {},