river: implement toggle-fullscreen
The command works, but behaves a little strangely. Also, fullscreen views are not yet rendered on an opqaue backdrop.
This commit is contained in:
parent
82a444a7c0
commit
3cbd95fadc
@ -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
|
/// pending state, the changes are not appplied until a transaction is started
|
||||||
/// and completed.
|
/// and completed.
|
||||||
pub fn arrangeViews(self: *Self) void {
|
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|
|
const output_tags = if (self.pending_focused_tags) |tags|
|
||||||
tags
|
tags
|
||||||
else
|
else
|
||||||
self.current_focused_tags;
|
self.current_focused_tags;
|
||||||
|
|
||||||
const visible_count = blk: {
|
const full_area = Box.fromWlrBox(c.wlr_output_layout_get_box(self.root.wlr_output_layout, self.wlr_output).*);
|
||||||
var count: u32 = 0;
|
|
||||||
|
// 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);
|
var it = ViewStack(View).pendingIterator(self.views.first, output_tags);
|
||||||
while (it.next()) |node| {
|
while (it.next()) |node| {
|
||||||
if (!node.view.pending.float and !node.view.pending.fullscreen) count += 1;
|
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) {
|
switch (err) {
|
||||||
LayoutError.BadExitCode => log.err(.layout, "layout command exited with non-zero return code", .{}),
|
LayoutError.BadExitCode => log.err(.layout, "layout command exited with non-zero return code", .{}),
|
||||||
LayoutError.BadWindowConfiguration => log.err(.layout, "invalid window configuration", .{}),
|
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}),
|
else => log.err(.layout, "'{}' error while trying to use external layout", .{err}),
|
||||||
}
|
}
|
||||||
log.err(.layout, "falling back to internal layout", .{});
|
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 {
|
pub fn arrangeLayers(self: *Self) void {
|
||||||
const full_box = blk: {
|
const full_box = blk: {
|
||||||
var width: c_int = undefined;
|
var width: c_int = undefined;
|
||||||
|
@ -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
|
/// Move a view from one output to another, sending the required enter/leave
|
||||||
/// events.
|
/// events.
|
||||||
pub fn sendToOutput(self: *Self, destination_output: *Output) void {
|
pub fn sendToOutput(self: *Self, destination_output: *Output) void {
|
||||||
|
@ -35,6 +35,10 @@ pub fn setActivated(self: Self, activated: bool) void {
|
|||||||
unreachable;
|
unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn setFullscreen(self: Self, fullscreen: bool) void {
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn close(self: Self) void {
|
pub fn close(self: Self) void {
|
||||||
unreachable;
|
unreachable;
|
||||||
}
|
}
|
||||||
|
@ -88,6 +88,10 @@ pub fn setActivated(self: Self, activated: bool) void {
|
|||||||
_ = c.wlr_xdg_toplevel_set_activated(self.wlr_xdg_surface, activated);
|
_ = 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
|
/// Close the view. This will lead to the unmap and destroy events being sent
|
||||||
pub fn close(self: Self) void {
|
pub fn close(self: Self) void {
|
||||||
c.wlr_xdg_toplevel_send_close(self.wlr_xdg_surface);
|
c.wlr_xdg_toplevel_send_close(self.wlr_xdg_surface);
|
||||||
|
@ -83,6 +83,10 @@ pub fn setActivated(self: Self, activated: bool) void {
|
|||||||
c.wlr_xwayland_surface_activate(self.wlr_xwayland_surface, activated);
|
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
|
/// Close the view. This will lead to the unmap and destroy events being sent
|
||||||
pub fn close(self: Self) void {
|
pub fn close(self: Self) void {
|
||||||
c.wlr_xwayland_surface_close(self.wlr_xwayland_surface);
|
c.wlr_xwayland_surface_close(self.wlr_xwayland_surface);
|
||||||
|
@ -81,6 +81,7 @@ const str_to_impl_fn = [_]struct {
|
|||||||
.{ .name = "toggle-focused-tags", .impl = impl.toggleFocusedTags },
|
.{ .name = "toggle-focused-tags", .impl = impl.toggleFocusedTags },
|
||||||
.{ .name = "toggle-view-tags", .impl = impl.toggleViewTags },
|
.{ .name = "toggle-view-tags", .impl = impl.toggleViewTags },
|
||||||
.{ .name = "zoom", .impl = impl.zoom },
|
.{ .name = "zoom", .impl = impl.zoom },
|
||||||
|
.{ .name = "toggle-fullscreen", .impl = impl.toggleFullscreen },
|
||||||
};
|
};
|
||||||
// zig fmt: on
|
// zig fmt: on
|
||||||
|
|
||||||
|
36
river/command/toggle_fullscreen.zig
Normal file
36
river/command/toggle_fullscreen.zig
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user