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(); }