Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
View: fix assertion failure if focused while destroying
Also clean up this code a bit, it's no longer necessary to split these
one line functions out into separate files as Zig's conditional
compilation support has improved since these functions were originally
written.
river/View.zig | 34 +++++++++++++++++-----------------
river/XdgToplevel.zig | 19 -------------------
river/XwaylandView.zig | 19 -------------------
3 files changed, 17 insertions(+), 55 deletions(-)
diff --git a/river/View.zig b/river/View.zig
index a11bd92..84a0214 100644
--- a/river/View.zig
+++ b/river/View.zig
@@ -453,12 +453,14 @@ pub fn configure(view: *View) bool {
}
}
-pub fn rootSurface(view: View) *wlr.Surface {
- assert(view.mapped and !view.destroying);
+/// Returns null if the view is currently being destroyed and no longer has
+/// an associated surface.
+/// May also return null for Xwayland views that are not currently mapped.
+pub fn rootSurface(view: View) ?*wlr.Surface {
return switch (view.impl) {
- .toplevel => |toplevel| toplevel.rootSurface(),
- .xwayland_view => |xwayland_view| xwayland_view.rootSurface(),
- .none => unreachable,
+ .toplevel => |toplevel| toplevel.wlr_toplevel.base.surface,
+ .xwayland_view => |xwayland_view| xwayland_view.xwayland_surface.surface,
+ .none => null,
};
}
@@ -466,7 +468,7 @@ pub fn sendFrameDone(view: View) void {
assert(view.mapped and !view.destroying);
var now: os.timespec = undefined;
os.clock_gettime(os.CLOCK.MONOTONIC, &now) catch @panic("CLOCK_MONOTONIC not supported");
- view.rootSurface().sendFrameDone(&now);
+ view.rootSurface().?.sendFrameDone(&now);
}
pub fn dropSavedSurfaceTree(view: *View) void {
@@ -528,20 +530,17 @@ pub fn setPendingOutput(view: *View, output: *Output) void {
}
pub fn close(view: View) void {
- assert(!view.destroying);
switch (view.impl) {
- .toplevel => |toplevel| toplevel.close(),
- .xwayland_view => |xwayland_view| xwayland_view.close(),
- .none => unreachable,
+ .toplevel => |toplevel| toplevel.wlr_toplevel.sendClose(),
+ .xwayland_view => |xwayland_view| xwayland_view.xwayland_surface.close(),
+ .none => {},
}
}
pub fn destroyPopups(view: View) void {
- assert(!view.destroying);
switch (view.impl) {
.toplevel => |toplevel| toplevel.destroyPopups(),
- .xwayland_view => {},
- .none => unreachable,
+ .xwayland_view, .none => {},
}
}
@@ -549,8 +548,8 @@ pub fn destroyPopups(view: View) void {
pub fn getTitle(view: View) ?[*:0]const u8 {
assert(!view.destroying);
return switch (view.impl) {
- .toplevel => |toplevel| toplevel.getTitle(),
- .xwayland_view => |xwayland_view| xwayland_view.getTitle(),
+ .toplevel => |toplevel| toplevel.wlr_toplevel.title,
+ .xwayland_view => |xwayland_view| xwayland_view.xwayland_surface.title,
.none => unreachable,
};
}
@@ -559,8 +558,9 @@ pub fn getTitle(view: View) ?[*:0]const u8 {
pub fn getAppId(view: View) ?[*:0]const u8 {
assert(!view.destroying);
return switch (view.impl) {
- .toplevel => |toplevel| toplevel.getAppId(),
- .xwayland_view => |xwayland_view| xwayland_view.getAppId(),
+ .toplevel => |toplevel| toplevel.wlr_toplevel.app_id,
+ // X11 clients don't have an app_id but the class serves a similar role.
+ .xwayland_view => |xwayland_view| xwayland_view.xwayland_surface.class,
.none => unreachable,
};
}
diff --git a/river/XdgToplevel.zig b/river/XdgToplevel.zig
index 3e28933..b307f26 100644
--- a/river/XdgToplevel.zig
+++ b/river/XdgToplevel.zig
@@ -194,25 +194,6 @@ pub fn configure(toplevel: *XdgToplevel) bool {
return true;
}
-pub fn rootSurface(toplevel: XdgToplevel) *wlr.Surface {
- return toplevel.wlr_toplevel.base.surface;
-}
-
-/// Close the view. This will lead to the unmap and destroy events being sent
-pub fn close(toplevel: XdgToplevel) void {
- toplevel.wlr_toplevel.sendClose();
-}
-
-/// Return the current title of the toplevel if any.
-pub fn getTitle(toplevel: XdgToplevel) ?[*:0]const u8 {
- return toplevel.wlr_toplevel.title;
-}
-
-/// Return the current app_id of the toplevel if any .
-pub fn getAppId(toplevel: XdgToplevel) ?[*:0]const u8 {
- return toplevel.wlr_toplevel.app_id;
-}
-
pub fn destroyPopups(toplevel: XdgToplevel) void {
var it = toplevel.wlr_toplevel.base.popups.safeIterator(.forward);
while (it.next()) |wlr_xdg_popup| wlr_xdg_popup.destroy();
diff --git a/river/XwaylandView.zig b/river/XwaylandView.zig
index 57bcb58..9aa5b63 100644
--- a/river/XwaylandView.zig
+++ b/river/XwaylandView.zig
@@ -119,15 +119,6 @@ pub fn configure(xwayland_view: XwaylandView) bool {
return false;
}
-pub fn rootSurface(xwayland_view: XwaylandView) *wlr.Surface {
- return xwayland_view.xwayland_surface.surface.?;
-}
-
-/// Close the view. This will lead to the unmap and destroy events being sent
-pub fn close(xwayland_view: XwaylandView) void {
- xwayland_view.xwayland_surface.close();
-}
-
fn setActivated(xwayland_view: XwaylandView, activated: bool) void {
// See comment on handleRequestMinimize() for details
if (activated and xwayland_view.xwayland_surface.minimized) {
@@ -139,16 +130,6 @@ fn setActivated(xwayland_view: XwaylandView, activated: bool) void {
}
}
-/// Get the current title of the xwayland surface if any.
-pub fn getTitle(xwayland_view: XwaylandView) ?[*:0]const u8 {
- return xwayland_view.xwayland_surface.title;
-}
-/// X11 clients don't have an app_id but the class serves a similar role.
-/// Get the current class of the xwayland surface if any.
-pub fn getAppId(xwayland_view: XwaylandView) ?[*:0]const u8 {
- return xwayland_view.xwayland_surface.class;
-}
-
fn handleDestroy(listener: *wl.Listener(void)) void {
const xwayland_view = @fieldParentPtr(XwaylandView, "destroy", listener);