view: fix handling of title/app_id change

This commit is contained in:
Isaac Freund 2021-01-01 13:29:57 +01:00
parent 0b4f7779f2
commit a2ef687e51
No known key found for this signature in database
GPG Key ID: 86DED400DDFD7A11
3 changed files with 28 additions and 21 deletions

View File

@ -365,8 +365,7 @@ pub fn getTitle(self: Self) ?[*:0]const u8 {
pub fn getAppId(self: Self) ?[*:0]const u8 { pub fn getAppId(self: Self) ?[*:0]const u8 {
return switch (self.impl) { return switch (self.impl) {
.xdg_toplevel => |xdg_toplevel| xdg_toplevel.getAppId(), .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.getAppId(),
.xwayland_view => |xwayland_view| xwayland_view.getClass(),
}; };
} }
@ -513,7 +512,7 @@ pub fn notifyTitle(self: Self) void {
// Send title to all status listeners attached to a seat which focuses this view // 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; var seat_it = self.output.root.server.input_manager.seats.first;
while (seat_it) |seat_node| : (seat_it = seat_node.next) { 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; var client_it = seat_node.data.status_trackers.first;
while (client_it) |client_node| : (client_it = client_node.next) { while (client_it) |client_node| : (client_it = client_node.next) {
client_node.data.sendFocusedView(); client_node.data.sendFocusedView();

View File

@ -53,6 +53,7 @@ request_resize: wl.Listener(*wlr.XdgToplevel.event.Resize) =
wl.Listener(*wlr.XdgToplevel.event.Resize).init(handleRequestResize), wl.Listener(*wlr.XdgToplevel.event.Resize).init(handleRequestResize),
// zig fmt: on // zig fmt: on
set_title: wl.Listener(*wlr.XdgSurface) = wl.Listener(*wlr.XdgSurface).init(handleSetTitle), 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 { pub fn init(self: *Self, view: *View, xdg_surface: *wlr.XdgSurface) void {
self.* = .{ .view = view, .xdg_surface = xdg_surface }; 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_move.add(&self.request_move);
toplevel.events.request_resize.add(&self.request_resize); toplevel.events.request_resize.add(&self.request_resize);
toplevel.events.set_title.add(&self.set_title); toplevel.events.set_title.add(&self.set_title);
toplevel.events.set_app_id.add(&self.set_app_id);
view.surface = self.xdg_surface.surface; 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 /// Called when the client sets / updates its title
fn handleSetTitle(listener: *wl.Listener(*wlr.XdgSurface), xdg_surface: *wlr.XdgSurface) void { fn handleSetTitle(listener: *wl.Listener(*wlr.XdgSurface), xdg_surface: *wlr.XdgSurface) void {
const self = @fieldParentPtr(Self, "set_title", listener); 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();
} }

View File

@ -37,7 +37,8 @@ xwayland_surface: *wlr.XwaylandSurface,
destroy: wl.Listener(*wlr.XwaylandSurface) = wl.Listener(*wlr.XwaylandSurface).init(handleDestroy), destroy: wl.Listener(*wlr.XwaylandSurface) = wl.Listener(*wlr.XwaylandSurface).init(handleDestroy),
map: wl.Listener(*wlr.XwaylandSurface) = wl.Listener(*wlr.XwaylandSurface).init(handleMap), map: wl.Listener(*wlr.XwaylandSurface) = wl.Listener(*wlr.XwaylandSurface).init(handleMap),
unmap: wl.Listener(*wlr.XwaylandSurface) = wl.Listener(*wlr.XwaylandSurface).init(handleUnmap), 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 // Listeners that are only active while the view is mapped
commit: wl.Listener(*wlr.Surface) = wl.Listener(*wlr.Surface).init(handleCommit), 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.destroy.add(&self.destroy);
xwayland_surface.events.map.add(&self.map); xwayland_surface.events.map.add(&self.map);
xwayland_surface.events.unmap.add(&self.unmap); xwayland_surface.events.unmap.add(&self.unmap);
xwayland_surface.events.set_title.add(&self.title);
} }
pub fn deinit(self: *Self) void { pub fn deinit(self: *Self) void {
@ -59,7 +59,6 @@ pub fn deinit(self: *Self) void {
self.destroy.link.remove(); self.destroy.link.remove();
self.map.link.remove(); self.map.link.remove();
self.unmap.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 { pub fn getTitle(self: Self) ?[*:0]const u8 {
return self.xwayland_surface.title; 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. /// 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; 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 // Add listeners that are only active while mapped
xwayland_surface.surface.?.events.commit.add(&self.commit); 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; 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 // Remove listeners that are only active while mapped
self.commit.link.remove(); self.commit.link.remove();
self.set_title.link.remove();
self.set_class.link.remove();
} }
/// Called when the surface is comitted /// 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 /// Called then the window updates its title
fn handleTitle(listener: *wl.Listener(*wlr.XwaylandSurface), xwayland_surface: *wlr.XwaylandSurface) void { fn handleSetTitle(listener: *wl.Listener(*wlr.XwaylandSurface), xwayland_surface: *wlr.XwaylandSurface) void {
const self = @fieldParentPtr(Self, "title", listener); const self = @fieldParentPtr(Self, "set_title", listener);
self.view.notifyTitle();
// 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) { /// Called then the window updates its class
if (seat_node.data.focused == .view and seat_node.data.focused.view == self.view) { fn handleSetClass(listener: *wl.Listener(*wlr.XwaylandSurface), xwayland_surface: *wlr.XwaylandSurface) void {
var client_it = seat_node.data.status_trackers.first; const self = @fieldParentPtr(Self, "set_class", listener);
while (client_it) |client_node| : (client_it = client_node.next) { self.view.notifyAppId();
client_node.data.sendFocusedView();
}
}
}
} }