git.lucas.co / cce-compositor
Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git

commit88de6ff9c1da937ffc57200b3a047f11fdeb001d
parente8804d0464
authorIsaac Freund <[email protected]>
date2020-06-29 11:52
xdg-shell: honor fullscreen requests

 river/View.zig                      |  3 +++
 river/XdgToplevel.zig               | 19 +++++++++++++++----
 river/command/toggle_fullscreen.zig |  3 ---
 3 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/river/View.zig b/river/View.zig
index 06baf04..8b99481 100644
--- a/river/View.zig
+++ b/river/View.zig
@@ -200,6 +200,9 @@ 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 {
+    // If transitionng from fullscreen -> float, return to the saved
+    // floating dimensions.
+    if (self.pending.fullscreen and self.pending.float) self.pending.box = self.float_box;
     self.pending.fullscreen = fullscreen;
     switch (self.impl) {
         .xdg_toplevel => |xdg_toplevel| xdg_toplevel.setFullscreen(fullscreen),
diff --git a/river/XdgToplevel.zig b/river/XdgToplevel.zig
index 02ab1b6..b818bbb 100644
--- a/river/XdgToplevel.zig
+++ b/river/XdgToplevel.zig
@@ -42,6 +42,7 @@ listen_unmap: c.wl_listener,
 // Listeners that are only active while the view is mapped
 listen_commit: c.wl_listener,
 listen_new_popup: c.wl_listener,
+listen_request_fullscreen: c.wl_listener,
 
 pub fn init(self: *Self, view: *View, wlr_xdg_surface: *c.wlr_xdg_surface) void {
     self.view = view;
@@ -145,6 +146,7 @@ fn handleMap(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
     const self = @fieldParentPtr(Self, "listen_map", listener.?);
     const view = self.view;
     const root = view.output.root;
+    const wlr_xdg_toplevel: *c.wlr_xdg_toplevel = @field(self.wlr_xdg_surface, c.wlr_xdg_surface_union).toplevel;
 
     // Add listeners that are only active while mapped
     self.listen_commit.notify = handleCommit;
@@ -153,6 +155,9 @@ fn handleMap(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
     self.listen_new_popup.notify = handleNewPopup;
     c.wl_signal_add(&self.wlr_xdg_surface.events.new_popup, &self.listen_new_popup);
 
+    self.listen_request_fullscreen.notify = handleRequestFullscreen;
+    c.wl_signal_add(&wlr_xdg_toplevel.events.request_fullscreen, &self.listen_request_fullscreen);
+
     view.wlr_surface = self.wlr_xdg_surface.surface;
 
     // Use the view's "natural" size centered on the output as the default
@@ -164,10 +169,6 @@ fn handleMap(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
     view.float_box.y = std.math.max(0, @divTrunc(@intCast(i32, view.output.usable_box.height) -
         @intCast(i32, view.float_box.height), 2));
 
-    const wlr_xdg_toplevel: *c.wlr_xdg_toplevel = @field(
-        self.wlr_xdg_surface,
-        c.wlr_xdg_surface_union,
-    ).toplevel;
     const state = &wlr_xdg_toplevel.current;
     const has_fixed_size = state.min_width != 0 and state.min_height != 0 and
         (state.min_width == state.max_width or state.min_height == state.max_height);
@@ -209,6 +210,7 @@ fn handleUnmap(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
     // Remove listeners that are only active while mapped
     c.wl_list_remove(&self.listen_commit.link);
     c.wl_list_remove(&self.listen_new_popup.link);
+    c.wl_list_remove(&self.listen_request_fullscreen.link);
 }
 
 /// Called when the surface is comitted
@@ -254,3 +256,12 @@ fn handleNewPopup(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
     var xdg_popup = util.gpa.create(XdgPopup) catch unreachable;
     xdg_popup.init(self.view.output, &self.view.current.box, wlr_xdg_popup);
 }
+
+/// Called when the client asks to be fullscreened. We always honor the request
+/// for now, perhaps it should be denied in some cases in the future.
+fn handleRequestFullscreen(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
+    const self = @fieldParentPtr(Self, "listen_request_fullscreen", listener.?);
+    const event = util.voidCast(c.wlr_xdg_toplevel_set_fullscreen_event, data.?);
+    self.view.setFullscreen(event.fullscreen);
+    self.view.output.root.arrange();
+}
diff --git a/river/command/toggle_fullscreen.zig b/river/command/toggle_fullscreen.zig
index 13e4296..0b3acc7 100644
--- a/river/command/toggle_fullscreen.zig
+++ b/river/command/toggle_fullscreen.zig
@@ -30,9 +30,6 @@ pub fn toggleFullscreen(
     if (args.len > 1) return Error.TooManyArguments;
 
     if (seat.focused_view) |view| {
-        // If transitionng from fullscreen -> float, return to the saved
-        // floating dimensions.
-        if (view.pending.fullscreen and view.pending.float) view.pending.box = view.float_box;
         view.setFullscreen(!view.pending.fullscreen);
         view.output.root.arrange();
     }