aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--river/Output.zig36
-rw-r--r--river/View.zig10
-rw-r--r--river/VoidView.zig4
-rw-r--r--river/XdgToplevel.zig4
-rw-r--r--river/XwaylandView.zig4
-rw-r--r--river/command.zig1
-rw-r--r--river/command/toggle_fullscreen.zig36
7 files changed, 79 insertions, 16 deletions
diff --git a/river/Output.zig b/river/Output.zig
index 5b6855e..e4e688a 100644
--- a/river/Output.zig
+++ b/river/Output.zig
@@ -297,29 +297,33 @@ fn layoutExternal(self: *Self, visible_count: u32, output_tags: u32) !void {
/// pending state, the changes are not appplied until a transaction is started
/// and completed.
pub fn arrangeViews(self: *Self) void {
- // If the output has a zero dimension, trying to arrange would cause
- // an underflow and is pointless anyway.
- if (self.usable_box.width == 0 or self.usable_box.height == 0) return;
-
const output_tags = if (self.pending_focused_tags) |tags|
tags
else
self.current_focused_tags;
- const visible_count = blk: {
- var count: u32 = 0;
- var it = ViewStack(View).pendingIterator(self.views.first, output_tags);
- while (it.next()) |node| {
- if (!node.view.pending.float and !node.view.pending.fullscreen) count += 1;
+ const full_area = Box.fromWlrBox(c.wlr_output_layout_get_box(self.root.wlr_output_layout, self.wlr_output).*);
+
+ // Make fullscreen views take the full area, count up views that will be
+ // arranged by the layout.
+ var layout_count: u32 = 0;
+ var it = ViewStack(View).pendingIterator(self.views.first, output_tags);
+ while (it.next()) |node| {
+ const view = &node.view;
+ if (view.pending.fullscreen) {
+ view.pending.box = full_area;
+ } else if (!view.pending.float) {
+ layout_count += 1;
}
- break :blk count;
- };
+ }
- if (visible_count == 0) return;
+ // If the usable area has a zero dimension, trying to arrange the layout
+ // would cause an underflow and is pointless anyway.
+ if (layout_count == 0 or self.usable_box.width == 0 or self.usable_box.height == 0) return;
- if (std.mem.eql(u8, self.layout, "full")) return layoutFull(self, visible_count, output_tags);
+ if (std.mem.eql(u8, self.layout, "full")) return layoutFull(self, layout_count, output_tags);
- layoutExternal(self, visible_count, output_tags) catch |err| {
+ layoutExternal(self, layout_count, output_tags) catch |err| {
switch (err) {
LayoutError.BadExitCode => log.err(.layout, "layout command exited with non-zero return code", .{}),
LayoutError.BadWindowConfiguration => log.err(.layout, "invalid window configuration", .{}),
@@ -327,11 +331,11 @@ pub fn arrangeViews(self: *Self) void {
else => log.err(.layout, "'{}' error while trying to use external layout", .{err}),
}
log.err(.layout, "falling back to internal layout", .{});
- layoutFull(self, visible_count, output_tags);
+ layoutFull(self, layout_count, output_tags);
};
}
-/// Arrange all layer surfaces of this output and addjust the usable aread
+/// Arrange all layer surfaces of this output and adjust the usable area
pub fn arrangeLayers(self: *Self) void {
const full_box = blk: {
var width: c_int = undefined;
diff --git a/river/View.zig b/river/View.zig
index 5d9cd52..e3995a8 100644
--- a/river/View.zig
+++ b/river/View.zig
@@ -197,6 +197,16 @@ pub fn setFocused(self: *Self, focused: bool) void {
}
}
+/// Set the pending state to fullscren and inform the client. Should be
+/// followed by starting a transaction to apply the pending state.
+pub fn setFullscreen(self: *Self, fullscreen: bool) void {
+ self.pending.fullscreen = fullscreen;
+ switch (self.impl) {
+ .xdg_toplevel => |xdg_toplevel| xdg_toplevel.setFullscreen(fullscreen),
+ .xwayland_view => |xwayland_view| xwayland_view.setFullscreen(fullscreen),
+ }
+}
+
/// Move a view from one output to another, sending the required enter/leave
/// events.
pub fn sendToOutput(self: *Self, destination_output: *Output) void {
diff --git a/river/VoidView.zig b/river/VoidView.zig
index 81392ff..d9bd3d4 100644
--- a/river/VoidView.zig
+++ b/river/VoidView.zig
@@ -35,6 +35,10 @@ pub fn setActivated(self: Self, activated: bool) void {
unreachable;
}
+pub fn setFullscreen(self: Self, fullscreen: bool) void {
+ unreachable;
+}
+
pub fn close(self: Self) void {
unreachable;
}
diff --git a/river/XdgToplevel.zig b/river/XdgToplevel.zig
index 7243454..647c85e 100644
--- a/river/XdgToplevel.zig
+++ b/river/XdgToplevel.zig
@@ -88,6 +88,10 @@ pub fn setActivated(self: Self, activated: bool) void {
_ = c.wlr_xdg_toplevel_set_activated(self.wlr_xdg_surface, activated);
}
+pub fn setFullscreen(self: Self, fullscreen: bool) void {
+ _ = c.wlr_xdg_toplevel_set_fullscreen(self.wlr_xdg_surface, fullscreen);
+}
+
/// Close the view. This will lead to the unmap and destroy events being sent
pub fn close(self: Self) void {
c.wlr_xdg_toplevel_send_close(self.wlr_xdg_surface);
diff --git a/river/XwaylandView.zig b/river/XwaylandView.zig
index 1cd0143..0f6cc82 100644
--- a/river/XwaylandView.zig
+++ b/river/XwaylandView.zig
@@ -83,6 +83,10 @@ pub fn setActivated(self: Self, activated: bool) void {
c.wlr_xwayland_surface_activate(self.wlr_xwayland_surface, activated);
}
+pub fn setFullscreen(self: Self, fullscreen: bool) void {
+ c.wlr_xwayland_surface_set_fullscreen(self.wlr_xwayland_surface, fullscreen);
+}
+
/// Close the view. This will lead to the unmap and destroy events being sent
pub fn close(self: Self) void {
c.wlr_xwayland_surface_close(self.wlr_xwayland_surface);
diff --git a/river/command.zig b/river/command.zig
index d5e0b6e..f71f18f 100644
--- a/river/command.zig
+++ b/river/command.zig
@@ -81,6 +81,7 @@ const str_to_impl_fn = [_]struct {
.{ .name = "toggle-focused-tags", .impl = impl.toggleFocusedTags },
.{ .name = "toggle-view-tags", .impl = impl.toggleViewTags },
.{ .name = "zoom", .impl = impl.zoom },
+ .{ .name = "toggle-fullscreen", .impl = impl.toggleFullscreen },
};
// zig fmt: on
diff --git a/river/command/toggle_fullscreen.zig b/river/command/toggle_fullscreen.zig
new file mode 100644
index 0000000..0b3acc7
--- /dev/null
+++ b/river/command/toggle_fullscreen.zig
@@ -0,0 +1,36 @@
+// This file is part of river, a dynamic tiling wayland compositor.
+//
+// Copyright 2020 Isaac Freund
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+const std = @import("std");
+
+const Error = @import("../command.zig").Error;
+const Seat = @import("../Seat.zig");
+
+/// Toggle fullscreen state of the currently focused view
+pub fn toggleFullscreen(
+ allocator: *std.mem.Allocator,
+ seat: *Seat,
+ args: []const []const u8,
+ out: *?[]const u8,
+) Error!void {
+ if (args.len > 1) return Error.TooManyArguments;
+
+ if (seat.focused_view) |view| {
+ view.setFullscreen(!view.pending.fullscreen);
+ view.output.root.arrange();
+ }
+}