Xwayland: handle override redirect state changes
This commit is contained in:
parent
8a8dd9ff65
commit
6ef97eea24
@ -193,7 +193,7 @@ fn handleNewXdgSurface(listener: *wl.Listener(*wlr.XdgSurface), xdg_surface: *wl
|
||||
xdg_surface.resource.postNoMemory();
|
||||
return;
|
||||
};
|
||||
node.view.init(output, getNewViewTags(output), xdg_surface);
|
||||
node.view.init(output, xdg_surface);
|
||||
}
|
||||
|
||||
/// This event is raised when the layer_shell recieves a new surface from a client.
|
||||
@ -259,10 +259,5 @@ fn handleNewXwaylandSurface(listener: *wl.Listener(*wlr.XwaylandSurface), wlr_xw
|
||||
// The View will add itself to the output's view stack on map
|
||||
const output = self.input_manager.defaultSeat().focused_output;
|
||||
const node = util.gpa.create(ViewStack(View).Node) catch return;
|
||||
node.view.init(output, getNewViewTags(output), wlr_xwayland_surface);
|
||||
}
|
||||
|
||||
fn getNewViewTags(output: *Output) u32 {
|
||||
const tags = output.current.tags & output.spawn_tagmask;
|
||||
return if (tags != 0) tags else output.current.tags;
|
||||
node.view.init(output, wlr_xwayland_surface);
|
||||
}
|
||||
|
@ -126,11 +126,16 @@ foreign_close: wl.Listener(*wlr.ForeignToplevelHandleV1) =
|
||||
request_activate: wl.Listener(*wlr.XdgActivationV1.event.RequestActivate) =
|
||||
wl.Listener(*wlr.XdgActivationV1.event.RequestActivate).init(handleRequestActivate),
|
||||
|
||||
pub fn init(self: *Self, output: *Output, tags: u32, surface: anytype) void {
|
||||
pub fn init(self: *Self, output: *Output, surface: anytype) void {
|
||||
const initial_tags = blk: {
|
||||
const tags = output.current.tags & output.spawn_tagmask;
|
||||
break :blk if (tags != 0) tags else output.current.tags;
|
||||
};
|
||||
|
||||
self.* = .{
|
||||
.output = output,
|
||||
.current = .{ .tags = tags },
|
||||
.pending = .{ .tags = tags },
|
||||
.current = .{ .tags = initial_tags },
|
||||
.pending = .{ .tags = initial_tags },
|
||||
.saved_buffers = std.ArrayList(SavedBuffer).init(util.gpa),
|
||||
};
|
||||
|
||||
|
@ -17,6 +17,8 @@
|
||||
const Self = @This();
|
||||
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
const wlr = @import("wlroots");
|
||||
const wl = @import("wayland").server.wl;
|
||||
|
||||
@ -24,6 +26,11 @@ const server = &@import("main.zig").server;
|
||||
const util = @import("util.zig");
|
||||
|
||||
const Box = @import("Box.zig");
|
||||
const View = @import("View.zig");
|
||||
const XwaylandView = @import("XwaylandView.zig");
|
||||
const ViewStack = @import("view_stack.zig").ViewStack;
|
||||
|
||||
const log = std.log.scoped(.xwayland);
|
||||
|
||||
/// The corresponding wlroots object
|
||||
xwayland_surface: *wlr.XwaylandSurface,
|
||||
@ -34,6 +41,10 @@ request_configure: wl.Listener(*wlr.XwaylandSurface.event.Configure) =
|
||||
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),
|
||||
set_override_redirect: wl.Listener(*wlr.XwaylandSurface) =
|
||||
wl.Listener(*wlr.XwaylandSurface).init(handleSetOverrideRedirect),
|
||||
|
||||
// Listeners that are only active while mapped
|
||||
commit: wl.Listener(*wlr.Surface) = wl.Listener(*wlr.Surface).init(handleCommit),
|
||||
|
||||
pub fn init(self: *Self, xwayland_surface: *wlr.XwaylandSurface) void {
|
||||
@ -69,7 +80,7 @@ fn handleDestroy(listener: *wl.Listener(*wlr.XwaylandSurface), _: *wlr.XwaylandS
|
||||
}
|
||||
|
||||
/// Called when the xwayland surface is mapped, or ready to display on-screen.
|
||||
fn handleMap(listener: *wl.Listener(*wlr.XwaylandSurface), xwayland_surface: *wlr.XwaylandSurface) void {
|
||||
pub fn handleMap(listener: *wl.Listener(*wlr.XwaylandSurface), xwayland_surface: *wlr.XwaylandSurface) void {
|
||||
const self = @fieldParentPtr(Self, "map", listener);
|
||||
|
||||
// Add self to the list of unmanaged views in the root
|
||||
@ -110,3 +121,29 @@ fn handleCommit(_: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void {
|
||||
var it = server.root.outputs.first;
|
||||
while (it) |node| : (it = node.next) node.data.damage.addWhole();
|
||||
}
|
||||
|
||||
fn handleSetOverrideRedirect(
|
||||
listener: *wl.Listener(*wlr.XwaylandSurface),
|
||||
xwayland_surface: *wlr.XwaylandSurface,
|
||||
) void {
|
||||
const self = @fieldParentPtr(Self, "set_override_redirect", listener);
|
||||
|
||||
log.debug("xwayland surface unset override redirect, switching to managed", .{});
|
||||
|
||||
assert(!xwayland_surface.override_redirect);
|
||||
|
||||
if (xwayland_surface.mapped) handleUnmap(&self.unmap, xwayland_surface);
|
||||
handleDestroy(&self.destroy, xwayland_surface);
|
||||
|
||||
// The View will add itself to the output's view stack on map
|
||||
const output = server.input_manager.defaultSeat().focused_output;
|
||||
const node = util.gpa.create(ViewStack(View).Node) catch {
|
||||
log.err("out of memory", .{});
|
||||
return;
|
||||
};
|
||||
node.view.init(output, xwayland_surface);
|
||||
|
||||
if (xwayland_surface.mapped) {
|
||||
XwaylandView.handleMap(&node.view.impl.xwayland_view.map, xwayland_surface);
|
||||
}
|
||||
}
|
||||
|
@ -17,16 +17,22 @@
|
||||
const Self = @This();
|
||||
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
const math = std.math;
|
||||
|
||||
const wlr = @import("wlroots");
|
||||
const wl = @import("wayland").server.wl;
|
||||
|
||||
const server = &@import("main.zig").server;
|
||||
const util = @import("util.zig");
|
||||
|
||||
const Box = @import("Box.zig");
|
||||
const View = @import("View.zig");
|
||||
const ViewStack = @import("view_stack.zig").ViewStack;
|
||||
const XdgPopup = @import("XdgPopup.zig");
|
||||
const XwaylandUnmanaged = @import("XwaylandUnmanaged.zig");
|
||||
|
||||
const log = std.log.scoped(.xwayland);
|
||||
|
||||
/// The view this xwayland view implements
|
||||
view: *View,
|
||||
@ -45,6 +51,8 @@ map: wl.Listener(*wlr.XwaylandSurface) = wl.Listener(*wlr.XwaylandSurface).init(
|
||||
unmap: wl.Listener(*wlr.XwaylandSurface) = wl.Listener(*wlr.XwaylandSurface).init(handleUnmap),
|
||||
request_configure: wl.Listener(*wlr.XwaylandSurface.event.Configure) =
|
||||
wl.Listener(*wlr.XwaylandSurface.event.Configure).init(handleRequestConfigure),
|
||||
set_override_redirect: wl.Listener(*wlr.XwaylandSurface) =
|
||||
wl.Listener(*wlr.XwaylandSurface).init(handleSetOverrideRedirect),
|
||||
|
||||
// Listeners that are only active while the view is mapped
|
||||
commit: wl.Listener(*wlr.Surface) = wl.Listener(*wlr.Surface).init(handleCommit),
|
||||
@ -176,7 +184,7 @@ fn handleDestroy(listener: *wl.Listener(*wlr.XwaylandSurface), _: *wlr.XwaylandS
|
||||
}
|
||||
|
||||
/// Called when the xwayland surface is mapped, or ready to display on-screen.
|
||||
fn handleMap(listener: *wl.Listener(*wlr.XwaylandSurface), xwayland_surface: *wlr.XwaylandSurface) void {
|
||||
pub fn handleMap(listener: *wl.Listener(*wlr.XwaylandSurface), xwayland_surface: *wlr.XwaylandSurface) void {
|
||||
const self = @fieldParentPtr(Self, "map", listener);
|
||||
const view = self.view;
|
||||
|
||||
@ -223,7 +231,7 @@ fn handleMap(listener: *wl.Listener(*wlr.XwaylandSurface), xwayland_surface: *wl
|
||||
}
|
||||
|
||||
view.map() catch {
|
||||
std.log.err("out of memory", .{});
|
||||
log.err("out of memory", .{});
|
||||
surface.resource.getClient().postNoMemory();
|
||||
};
|
||||
}
|
||||
@ -262,6 +270,32 @@ fn handleRequestConfigure(
|
||||
self.configure();
|
||||
}
|
||||
|
||||
fn handleSetOverrideRedirect(
|
||||
listener: *wl.Listener(*wlr.XwaylandSurface),
|
||||
xwayland_surface: *wlr.XwaylandSurface,
|
||||
) void {
|
||||
const self = @fieldParentPtr(Self, "set_override_redirect", listener);
|
||||
|
||||
log.debug("xwayland surface set override redirect, switching to unmanaged", .{});
|
||||
|
||||
assert(xwayland_surface.override_redirect);
|
||||
|
||||
if (xwayland_surface.mapped) handleUnmap(&self.unmap, xwayland_surface);
|
||||
handleDestroy(&self.destroy, xwayland_surface);
|
||||
|
||||
// The unmanged surface will add itself to the list of unmanaged views
|
||||
// in Root when it is mapped.
|
||||
const node = util.gpa.create(std.TailQueue(XwaylandUnmanaged).Node) catch {
|
||||
log.err("out of memory", .{});
|
||||
return;
|
||||
};
|
||||
node.data.init(xwayland_surface);
|
||||
|
||||
if (xwayland_surface.mapped) {
|
||||
XwaylandUnmanaged.handleMap(&node.data.map, xwayland_surface);
|
||||
}
|
||||
}
|
||||
|
||||
fn handleCommit(listener: *wl.Listener(*wlr.Surface), surface: *wlr.Surface) void {
|
||||
const self = @fieldParentPtr(Self, "commit", listener);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user