river: ext-foreign-toplevel-image-capture-source
This commit is contained in:
@@ -46,6 +46,7 @@ const XdgDecoration = @import("XdgDecoration.zig");
|
||||
const XdgToplevel = @import("XdgToplevel.zig");
|
||||
const XwaylandOverrideRedirect = @import("XwaylandOverrideRedirect.zig");
|
||||
const XwaylandView = @import("XwaylandView.zig");
|
||||
const View = @import("View.zig");
|
||||
|
||||
const log = std.log.scoped(.server);
|
||||
|
||||
@@ -93,6 +94,7 @@ screencopy_manager: *wlr.ScreencopyManagerV1,
|
||||
|
||||
image_copy_capture_manager: *wlr.ExtImageCopyCaptureManagerV1,
|
||||
output_image_capture_source_manager: *wlr.ExtOutputImageCaptureSourceManagerV1,
|
||||
foreign_toplevel_image_capture_source_manager: *wlr.ExtForeignToplevelImageCaptureSourceManagerV1,
|
||||
|
||||
foreign_toplevel_manager: *wlr.ForeignToplevelManagerV1,
|
||||
|
||||
@@ -127,6 +129,8 @@ request_activate: wl.Listener(*wlr.XdgActivationV1.event.RequestActivate) =
|
||||
wl.Listener(*wlr.XdgActivationV1.event.RequestActivate).init(handleRequestActivate),
|
||||
request_set_cursor_shape: wl.Listener(*wlr.CursorShapeManagerV1.event.RequestSetShape) =
|
||||
wl.Listener(*wlr.CursorShapeManagerV1.event.RequestSetShape).init(handleRequestSetCursorShape),
|
||||
new_foreign_toplevel_capture_request: wl.Listener(*wlr.ExtForeignToplevelImageCaptureSourceManagerV1.Request) =
|
||||
wl.Listener(*wlr.ExtForeignToplevelImageCaptureSourceManagerV1.Request).init(handleNewForeignToplevelCaptureRequest),
|
||||
|
||||
pub fn init(server: *Server, runtime_xwayland: bool) !void {
|
||||
// We intentionally don't try to prevent memory leaks on error in this function
|
||||
@@ -181,6 +185,7 @@ pub fn init(server: *Server, runtime_xwayland: bool) !void {
|
||||
|
||||
.image_copy_capture_manager = try wlr.ExtImageCopyCaptureManagerV1.create(wl_server, 1),
|
||||
.output_image_capture_source_manager = try wlr.ExtOutputImageCaptureSourceManagerV1.create(wl_server, 1),
|
||||
.foreign_toplevel_image_capture_source_manager = try wlr.ExtForeignToplevelImageCaptureSourceManagerV1.create(wl_server, 1),
|
||||
|
||||
.foreign_toplevel_manager = try wlr.ForeignToplevelManagerV1.create(wl_server),
|
||||
|
||||
@@ -392,6 +397,7 @@ fn blocklist(server: *Server, global: *const wl.Global) bool {
|
||||
global == server.screencopy_manager.global or
|
||||
global == server.image_copy_capture_manager.global or
|
||||
global == server.output_image_capture_source_manager.global or
|
||||
global == server.foreign_toplevel_image_capture_source_manager.global or
|
||||
global == server.export_dmabuf_manager.global or
|
||||
global == server.data_control_manager.global or
|
||||
global == server.layout_manager.global or
|
||||
@@ -597,3 +603,24 @@ fn handleRequestSetCursorShape(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handleNewForeignToplevelCaptureRequest(
|
||||
listener: *wl.Listener(*wlr.ExtForeignToplevelImageCaptureSourceManagerV1.Request),
|
||||
request: *wlr.ExtForeignToplevelImageCaptureSourceManagerV1.Request,
|
||||
) void {
|
||||
const server: *Server = @fieldParentPtr("new_foreign_toplevel_capture_request", listener);
|
||||
if (request.toplevel_handle.data) |opaque_view| {
|
||||
const view: *View = @ptrCast(@alignCast(opaque_view));
|
||||
const capture_source = view.image_capture_source orelse wlr.ExtImageCaptureSourceV1.createWithSceneNode(
|
||||
&view.image_capture_scene.tree.node,
|
||||
server.wl_server.getEventLoop(),
|
||||
server.allocator,
|
||||
server.renderer,
|
||||
) catch {
|
||||
log.err("failed to create ext image capture source", .{});
|
||||
return;
|
||||
};
|
||||
|
||||
_ = request.accept(capture_source);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,6 +140,9 @@ saved_surface_tree: *wlr.SceneTree,
|
||||
borders: [4]*wlr.SceneRect,
|
||||
popup_tree: *wlr.SceneTree,
|
||||
|
||||
image_capture_scene: *wlr.Scene,
|
||||
image_capture_source: ?*wlr.ExtImageCaptureSourceV1,
|
||||
|
||||
/// Bounds on the width/height of the view, set by the toplevel/xwayland_view implementation.
|
||||
constraints: Constraints = .{},
|
||||
|
||||
@@ -215,6 +218,9 @@ pub fn create(impl: Impl) error{OutOfMemory}!*View {
|
||||
},
|
||||
.popup_tree = popup_tree,
|
||||
|
||||
.image_capture_scene = try wlr.Scene.create(),
|
||||
.image_capture_source = null,
|
||||
|
||||
.pending_wm_stack_link = undefined,
|
||||
.pending_focus_stack_link = undefined,
|
||||
.inflight_wm_stack_link = undefined,
|
||||
@@ -230,6 +236,7 @@ pub fn create(impl: Impl) error{OutOfMemory}!*View {
|
||||
view.tree.node.setEnabled(false);
|
||||
view.popup_tree.node.setEnabled(false);
|
||||
view.saved_surface_tree.node.setEnabled(false);
|
||||
view.image_capture_scene.restack_xwayland_surfaces = false;
|
||||
|
||||
try SceneNodeData.attach(&view.tree.node, .{ .view = view });
|
||||
try SceneNodeData.attach(&view.popup_tree.node, .{ .view = view });
|
||||
@@ -250,6 +257,7 @@ pub fn destroy(view: *View, when: enum { lazy, assert }) void {
|
||||
// around until the current transaction completes. This function will be
|
||||
// called again in Root.commitTransaction()
|
||||
if (!view.saved_surface_tree.node.enabled) {
|
||||
view.image_capture_scene.tree.node.destroy();
|
||||
view.tree.node.destroy();
|
||||
view.popup_tree.node.destroy();
|
||||
|
||||
@@ -665,6 +673,7 @@ pub fn map(view: *View) !void {
|
||||
.app_id = view.getAppId(),
|
||||
})) |handle| {
|
||||
view.ext_foreign_toplevel_handle = handle;
|
||||
handle.data = view;
|
||||
} else |_| {
|
||||
log.err("failed to create ext foreign toplevel handle", .{});
|
||||
}
|
||||
|
||||
@@ -97,6 +97,7 @@ pub fn create(wlr_toplevel: *wlr.XdgToplevel) error{OutOfMemory}!void {
|
||||
errdefer toplevel.unmap.link.remove();
|
||||
|
||||
_ = try view.surface_tree.createSceneXdgSurface(wlr_toplevel.base);
|
||||
_ = try view.image_capture_scene.tree.createSceneXdgSurface(wlr_toplevel.base);
|
||||
|
||||
toplevel.view = view;
|
||||
|
||||
|
||||
@@ -179,6 +179,12 @@ pub fn handleMap(listener: *wl.Listener(void)) void {
|
||||
return;
|
||||
};
|
||||
|
||||
_ = view.image_capture_scene.tree.createSceneSurface(surface) catch {
|
||||
log.err("out of memory", .{});
|
||||
surface.resource.getClient().postNoMemory();
|
||||
return;
|
||||
};
|
||||
|
||||
view.pending.box = .{
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
|
||||
Reference in New Issue
Block a user