aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--river/Seat.zig33
-rw-r--r--river/View.zig23
-rw-r--r--river/VoidView.zig8
-rw-r--r--river/XdgToplevel.zig26
-rw-r--r--river/XwaylandView.zig9
5 files changed, 72 insertions, 27 deletions
diff --git a/river/Seat.zig b/river/Seat.zig
index d71ac1a..b91a309 100644
--- a/river/Seat.zig
+++ b/river/Seat.zig
@@ -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 => {},
diff --git a/river/View.zig b/river/View.zig
index 71707ba..a8b9c63 100644
--- a/river/View.zig
+++ b/river/View.zig
@@ -209,6 +209,7 @@ pub fn applyPending(self: *Self) void {
// If switching to fullscreen set the dimensions to the full area of the output
// and turn the view fully opaque
if (!self.current.fullscreen and self.pending.fullscreen) {
+ self.setFullscreen(true);
self.post_fullscreen_box = self.current.box;
self.pending.target_opacity = 1.0;
@@ -222,6 +223,7 @@ pub fn applyPending(self: *Self) void {
}
if (self.current.fullscreen and !self.pending.fullscreen) {
+ self.setFullscreen(false);
self.pending.box = self.post_fullscreen_box;
// Restore configured opacity
@@ -244,10 +246,6 @@ pub fn needsConfigure(self: Self) bool {
}
pub fn configure(self: Self) void {
- if (self.foreign_toplevel_handle) |handle| {
- handle.setActivated(self.pending.focus != 0);
- handle.setFullscreen(self.pending.fullscreen);
- }
switch (self.impl) {
.xdg_toplevel => |xdg_toplevel| xdg_toplevel.configure(),
.xwayland_view => |xwayland_view| xwayland_view.configure(),
@@ -322,6 +320,23 @@ pub fn close(self: Self) void {
.xwayland_view => |xwayland_view| xwayland_view.close(),
}
}
+
+pub fn setActivated(self: Self, activated: bool) void {
+ if (self.foreign_toplevel_handle) |handle| handle.setActivated(activated);
+ switch (self.impl) {
+ .xdg_toplevel => |xdg_toplevel| xdg_toplevel.setActivated(activated),
+ .xwayland_view => |xwayland_view| xwayland_view.setActivated(activated),
+ }
+}
+
+pub fn setFullscreen(self: Self, fullscreen: bool) void {
+ if (self.foreign_toplevel_handle) |handle| handle.setFullscreen(fullscreen);
+ switch (self.impl) {
+ .xdg_toplevel => |xdg_toplevel| xdg_toplevel.setFullscreen(fullscreen),
+ .xwayland_view => |xwayland_view| xwayland_view.setFullscreen(fullscreen),
+ }
+}
+
pub inline fn forEachPopupSurface(
self: Self,
comptime T: type,
diff --git a/river/VoidView.zig b/river/VoidView.zig
index 4fe4d7d..e0d6edd 100644
--- a/river/VoidView.zig
+++ b/river/VoidView.zig
@@ -39,6 +39,14 @@ pub fn close(self: Self) void {
unreachable;
}
+pub fn setActivated(self: Self, activated: bool) void {
+ unreachable;
+}
+
+pub fn setFullscreen(self: Self, fullscreen: bool) void {
+ unreachable;
+}
+
pub fn surfaceAt(self: Self, ox: f64, oy: f64, sx: *f64, sy: *f64) ?*wlr.Surface {
unreachable;
}
diff --git a/river/XdgToplevel.zig b/river/XdgToplevel.zig
index 3870fa7..91664d8 100644
--- a/river/XdgToplevel.zig
+++ b/river/XdgToplevel.zig
@@ -85,8 +85,8 @@ pub fn deinit(self: *Self) void {
}
}
-/// Returns true if a configure must be sent to ensure the dimensions of the
-/// pending_box are applied.
+/// Returns true if a configure must be sent to ensure that the pending
+/// dimensions are applied.
pub fn needsConfigure(self: Self) bool {
const server_pending = &self.xdg_surface.role_data.toplevel.server_pending;
const state = &self.view.pending;
@@ -95,8 +95,10 @@ pub fn needsConfigure(self: Self) bool {
// sync with the current dimensions or be the dimensions sent with the
// most recent configure. In both cases server_pending has the values we
// want to check against.
- return (state.focus != 0) != server_pending.activated or
- state.box.width != server_pending.width or
+ // Furthermore, we avoid a special case for newly mapped views which we
+ // have not yet configured by setting server_pending.width/height to the
+ // initial width/height of the view in handleMap().
+ return state.box.width != server_pending.width or
state.box.height != server_pending.height;
}
@@ -104,8 +106,6 @@ pub fn needsConfigure(self: Self) bool {
pub fn configure(self: Self) void {
const toplevel = self.xdg_surface.role_data.toplevel;
const state = &self.view.pending;
- _ = toplevel.setActivated(state.focus != 0);
- _ = toplevel.setFullscreen(state.fullscreen);
self.view.pending_serial = toplevel.setSize(state.box.width, state.box.height);
}
@@ -113,6 +113,15 @@ pub fn configure(self: Self) void {
pub fn close(self: Self) void {
self.xdg_surface.role_data.toplevel.sendClose();
}
+
+pub fn setActivated(self: Self, activated: bool) void {
+ _ = self.xdg_surface.role_data.toplevel.setActivated(activated);
+}
+
+pub fn setFullscreen(self: Self, fullscreen: bool) void {
+ _ = self.xdg_surface.role_data.toplevel.setFullscreen(fullscreen);
+}
+
pub inline fn forEachPopupSurface(
self: Self,
comptime T: type,
@@ -189,6 +198,11 @@ fn handleMap(listener: *wl.Listener(*wlr.XdgSurface), xdg_surface: *wlr.XdgSurfa
view.float_box.y = std.math.max(0, @divTrunc(@intCast(i32, view.output.usable_box.height) -
@intCast(i32, view.float_box.height), 2));
+ // We initialize these to avoid special-casing newly mapped views in
+ // the check preformed in needsConfigure().
+ toplevel.server_pending.width = @intCast(u32, initial_box.width);
+ toplevel.server_pending.height = @intCast(u32, initial_box.height);
+
// Also use the view's "natural" size as the initial regular dimensions,
// for the case that it does not get arranged by a lyaout.
view.pending.box = view.float_box;
diff --git a/river/XwaylandView.zig b/river/XwaylandView.zig
index 4f9cfab..c474be6 100644
--- a/river/XwaylandView.zig
+++ b/river/XwaylandView.zig
@@ -84,7 +84,6 @@ pub fn configure(self: Self) void {
const output_box = server.root.output_layout.getBox(output.wlr_output).?;
const state = &self.view.pending;
- self.xwayland_surface.setFullscreen(state.fullscreen);
self.xwayland_surface.configure(
@intCast(i16, state.box.x + output_box.x),
@intCast(i16, state.box.y + output_box.y),
@@ -98,6 +97,14 @@ pub fn close(self: Self) void {
self.xwayland_surface.close();
}
+pub fn setActivated(self: Self, activated: bool) void {
+ self.xwayland_surface.activate(activated);
+}
+
+pub fn setFullscreen(self: Self, fullscreen: bool) void {
+ self.xwayland_surface.setFullscreen(fullscreen);
+}
+
/// Return the surface at output coordinates ox, oy and set sx, sy to the
/// corresponding surface-relative coordinates, if there is a surface.
pub fn surfaceAt(self: Self, ox: f64, oy: f64, sx: *f64, sy: *f64) ?*wlr.Surface {