XdgPopup: reimplement using the scene graph
xdg-shell version 3 is now implemented, supporting popup repositioning.
This commit is contained in:
@ -27,37 +27,42 @@ const util = @import("util.zig");
|
||||
|
||||
const Output = @import("Output.zig");
|
||||
const SceneNodeData = @import("SceneNodeData.zig");
|
||||
const XdgPopup = @import("XdgPopup.zig");
|
||||
|
||||
const log = std.log.scoped(.layer_shell);
|
||||
|
||||
output: *Output,
|
||||
scene_layer_surface: *wlr.SceneLayerSurfaceV1,
|
||||
popup_tree: *wlr.SceneTree,
|
||||
|
||||
destroy: wl.Listener(*wlr.LayerSurfaceV1) = wl.Listener(*wlr.LayerSurfaceV1).init(handleDestroy),
|
||||
map: wl.Listener(*wlr.LayerSurfaceV1) = wl.Listener(*wlr.LayerSurfaceV1).init(handleMap),
|
||||
unmap: wl.Listener(*wlr.LayerSurfaceV1) = wl.Listener(*wlr.LayerSurfaceV1).init(handleUnmap),
|
||||
commit: wl.Listener(*wlr.Surface) = wl.Listener(*wlr.Surface).init(handleCommit),
|
||||
new_popup: wl.Listener(*wlr.XdgPopup) = wl.Listener(*wlr.XdgPopup).init(handleNewPopup),
|
||||
|
||||
pub fn create(wlr_layer_surface: *wlr.LayerSurfaceV1) error{OutOfMemory}!void {
|
||||
const output = @intToPtr(*Output, wlr_layer_surface.output.?.data);
|
||||
const layer_surface = try util.gpa.create(LayerSurface);
|
||||
errdefer util.gpa.destroy(layer_surface);
|
||||
|
||||
const tree = output.layerSurfaceTree(wlr_layer_surface.current.layer);
|
||||
const scene_layer_surface = try tree.createSceneLayerSurfaceV1(wlr_layer_surface);
|
||||
|
||||
try SceneNodeData.attach(&scene_layer_surface.tree.node, .{ .layer_surface = layer_surface });
|
||||
const layer_tree = output.layerSurfaceTree(wlr_layer_surface.current.layer);
|
||||
|
||||
layer_surface.* = .{
|
||||
.output = output,
|
||||
.scene_layer_surface = scene_layer_surface,
|
||||
.scene_layer_surface = try layer_tree.createSceneLayerSurfaceV1(wlr_layer_surface),
|
||||
.popup_tree = try output.layers.popups.createSceneTree(),
|
||||
};
|
||||
wlr_layer_surface.data = @ptrToInt(layer_surface);
|
||||
|
||||
try SceneNodeData.attach(&layer_surface.scene_layer_surface.tree.node, .{ .layer_surface = layer_surface });
|
||||
try SceneNodeData.attach(&layer_surface.popup_tree.node, .{ .layer_surface = layer_surface });
|
||||
|
||||
wlr_layer_surface.events.destroy.add(&layer_surface.destroy);
|
||||
wlr_layer_surface.events.map.add(&layer_surface.map);
|
||||
wlr_layer_surface.events.unmap.add(&layer_surface.unmap);
|
||||
wlr_layer_surface.surface.events.commit.add(&layer_surface.commit);
|
||||
wlr_layer_surface.events.new_popup.add(&layer_surface.new_popup);
|
||||
|
||||
// wlroots only informs us of the new surface after the first commit,
|
||||
// so our listener does not get called for this first commit. However,
|
||||
@ -65,6 +70,11 @@ pub fn create(wlr_layer_surface: *wlr.LayerSurfaceV1) error{OutOfMemory}!void {
|
||||
handleCommit(&layer_surface.commit, wlr_layer_surface.surface);
|
||||
}
|
||||
|
||||
pub fn destroyPopups(layer_surface: *LayerSurface) void {
|
||||
var it = layer_surface.scene_layer_surface.layer_surface.popups.safeIterator(.forward);
|
||||
while (it.next()) |wlr_xdg_popup| wlr_xdg_popup.destroy();
|
||||
}
|
||||
|
||||
fn handleDestroy(listener: *wl.Listener(*wlr.LayerSurfaceV1), wlr_layer_surface: *wlr.LayerSurfaceV1) void {
|
||||
const layer_surface = @fieldParentPtr(LayerSurface, "destroy", listener);
|
||||
|
||||
@ -75,6 +85,8 @@ fn handleDestroy(listener: *wl.Listener(*wlr.LayerSurfaceV1), wlr_layer_surface:
|
||||
layer_surface.unmap.link.remove();
|
||||
layer_surface.commit.link.remove();
|
||||
|
||||
layer_surface.destroyPopups();
|
||||
|
||||
util.gpa.destroy(layer_surface);
|
||||
}
|
||||
|
||||
@ -163,3 +175,17 @@ fn handleKeyboardInteractiveExclusive(output: *Output) void {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handleNewPopup(listener: *wl.Listener(*wlr.XdgPopup), wlr_xdg_popup: *wlr.XdgPopup) void {
|
||||
const layer_surface = @fieldParentPtr(LayerSurface, "new_popup", listener);
|
||||
|
||||
XdgPopup.create(
|
||||
wlr_xdg_popup,
|
||||
layer_surface.popup_tree,
|
||||
layer_surface.popup_tree,
|
||||
&layer_surface.output,
|
||||
) catch {
|
||||
wlr_xdg_popup.resource.postNoMemory();
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user