From a2ef687e51db3a16a18fdcd0ba6ece0af7e4b53d Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Fri, 1 Jan 2021 13:29:57 +0100 Subject: [PATCH] view: fix handling of title/app_id change --- river/View.zig | 5 ++--- river/XdgToplevel.zig | 9 +++++++++ river/XwaylandView.zig | 35 +++++++++++++++++------------------ 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/river/View.zig b/river/View.zig index b20f702..0bbe5bc 100644 --- a/river/View.zig +++ b/river/View.zig @@ -365,8 +365,7 @@ pub fn getTitle(self: Self) ?[*:0]const u8 { pub fn getAppId(self: Self) ?[*:0]const u8 { return switch (self.impl) { .xdg_toplevel => |xdg_toplevel| xdg_toplevel.getAppId(), - // X11 clients don't have an app_id but the class serves a similar role - .xwayland_view => |xwayland_view| xwayland_view.getClass(), + .xwayland_view => |xwayland_view| xwayland_view.getAppId(), }; } @@ -513,7 +512,7 @@ pub fn notifyTitle(self: Self) void { // Send title to all status listeners attached to a seat which focuses this view var seat_it = self.output.root.server.input_manager.seats.first; while (seat_it) |seat_node| : (seat_it = seat_node.next) { - if (seat_node.data.focused == .view and seat_node.data.focused.view == self) { + if (seat_node.data.focused == .view and seat_node.data.focused.view == &self) { var client_it = seat_node.data.status_trackers.first; while (client_it) |client_node| : (client_it = client_node.next) { client_node.data.sendFocusedView(); diff --git a/river/XdgToplevel.zig b/river/XdgToplevel.zig index a517769..ddbee00 100644 --- a/river/XdgToplevel.zig +++ b/river/XdgToplevel.zig @@ -53,6 +53,7 @@ request_resize: wl.Listener(*wlr.XdgToplevel.event.Resize) = wl.Listener(*wlr.XdgToplevel.event.Resize).init(handleRequestResize), // zig fmt: on set_title: wl.Listener(*wlr.XdgSurface) = wl.Listener(*wlr.XdgSurface).init(handleSetTitle), +set_app_id: wl.Listener(*wlr.XdgSurface) = wl.Listener(*wlr.XdgSurface).init(handleSetAppId), pub fn init(self: *Self, view: *View, xdg_surface: *wlr.XdgSurface) void { self.* = .{ .view = view, .xdg_surface = xdg_surface }; @@ -165,6 +166,7 @@ fn handleMap(listener: *wl.Listener(*wlr.XdgSurface), xdg_surface: *wlr.XdgSurfa toplevel.events.request_move.add(&self.request_move); toplevel.events.request_resize.add(&self.request_resize); toplevel.events.set_title.add(&self.set_title); + toplevel.events.set_app_id.add(&self.set_app_id); view.surface = self.xdg_surface.surface; @@ -304,4 +306,11 @@ fn handleRequestResize(listener: *wl.Listener(*wlr.XdgToplevel.event.Resize), ev /// Called when the client sets / updates its title fn handleSetTitle(listener: *wl.Listener(*wlr.XdgSurface), xdg_surface: *wlr.XdgSurface) void { const self = @fieldParentPtr(Self, "set_title", listener); + self.view.notifyTitle(); +} + +/// Called when the client sets / updates its app_id +fn handleSetAppId(listener: *wl.Listener(*wlr.XdgSurface), xdg_surface: *wlr.XdgSurface) void { + const self = @fieldParentPtr(Self, "set_app_id", listener); + self.view.notifyAppId(); } diff --git a/river/XwaylandView.zig b/river/XwaylandView.zig index 07e54a9..58ac8a6 100644 --- a/river/XwaylandView.zig +++ b/river/XwaylandView.zig @@ -37,7 +37,8 @@ xwayland_surface: *wlr.XwaylandSurface, destroy: wl.Listener(*wlr.XwaylandSurface) = wl.Listener(*wlr.XwaylandSurface).init(handleDestroy), map: wl.Listener(*wlr.XwaylandSurface) = wl.Listener(*wlr.XwaylandSurface).init(handleMap), unmap: wl.Listener(*wlr.XwaylandSurface) = wl.Listener(*wlr.XwaylandSurface).init(handleUnmap), -title: wl.Listener(*wlr.XwaylandSurface) = wl.Listener(*wlr.XwaylandSurface).init(handleTitle), +set_title: wl.Listener(*wlr.XwaylandSurface) = wl.Listener(*wlr.XwaylandSurface).init(handleSetTitle), +set_class: wl.Listener(*wlr.XwaylandSurface) = wl.Listener(*wlr.XwaylandSurface).init(handleSetClass), // Listeners that are only active while the view is mapped commit: wl.Listener(*wlr.Surface) = wl.Listener(*wlr.Surface).init(handleCommit), @@ -50,7 +51,6 @@ pub fn init(self: *Self, view: *View, xwayland_surface: *wlr.XwaylandSurface) vo xwayland_surface.events.destroy.add(&self.destroy); xwayland_surface.events.map.add(&self.map); xwayland_surface.events.unmap.add(&self.unmap); - xwayland_surface.events.set_title.add(&self.title); } pub fn deinit(self: *Self) void { @@ -59,7 +59,6 @@ pub fn deinit(self: *Self) void { self.destroy.link.remove(); self.map.link.remove(); self.unmap.link.remove(); - self.title.link.remove(); } } @@ -113,9 +112,9 @@ pub fn surfaceAt(self: Self, ox: f64, oy: f64, sx: *f64, sy: *f64) ?*wlr.Surface pub fn getTitle(self: Self) ?[*:0]const u8 { return self.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 getClass(self: Self) ?[*:0]const u8 { +pub fn getAppId(self: Self) ?[*:0]const u8 { return self.xwayland_surface.class; } @@ -158,6 +157,8 @@ fn handleMap(listener: *wl.Listener(*wlr.XwaylandSurface), xwayland_surface: *wl // Add listeners that are only active while mapped xwayland_surface.surface.?.events.commit.add(&self.commit); + xwayland_surface.events.set_title.add(&self.set_title); + xwayland_surface.events.set_class.add(&self.set_class); view.surface = self.xwayland_surface.surface; @@ -206,6 +207,8 @@ fn handleUnmap(listener: *wl.Listener(*wlr.XwaylandSurface), xwayland_surface: * // Remove listeners that are only active while mapped self.commit.link.remove(); + self.set_title.link.remove(); + self.set_class.link.remove(); } /// Called when the surface is comitted @@ -221,17 +224,13 @@ fn handleCommit(listener: *wl.Listener(*wlr.Surface), surface: *wlr.Surface) voi } /// Called then the window updates its title -fn handleTitle(listener: *wl.Listener(*wlr.XwaylandSurface), xwayland_surface: *wlr.XwaylandSurface) void { - const self = @fieldParentPtr(Self, "title", listener); - - // Send title to all status listeners attached to a seat which focuses this view - var seat_it = self.view.output.root.server.input_manager.seats.first; - while (seat_it) |seat_node| : (seat_it = seat_node.next) { - if (seat_node.data.focused == .view and seat_node.data.focused.view == self.view) { - var client_it = seat_node.data.status_trackers.first; - while (client_it) |client_node| : (client_it = client_node.next) { - client_node.data.sendFocusedView(); - } - } - } +fn handleSetTitle(listener: *wl.Listener(*wlr.XwaylandSurface), xwayland_surface: *wlr.XwaylandSurface) void { + const self = @fieldParentPtr(Self, "set_title", listener); + self.view.notifyTitle(); +} + +/// Called then the window updates its class +fn handleSetClass(listener: *wl.Listener(*wlr.XwaylandSurface), xwayland_surface: *wlr.XwaylandSurface) void { + const self = @fieldParentPtr(Self, "set_class", listener); + self.view.notifyAppId(); }