mirror of
https://github.com/MezzalunaWM/Mezzaluna.git
synced 2026-03-08 04:57:32 -04:00
This is currently incomplete and needs work to make sure that popups stay inside their parents current output. fixing popups, wip
97 lines
2.7 KiB
Zig
97 lines
2.7 KiB
Zig
const Popup = @This();
|
|
|
|
const std = @import("std");
|
|
const wl = @import("wayland").server.wl;
|
|
const wlr = @import("wlroots");
|
|
|
|
const Utils = @import("Utils.zig");
|
|
const Output = @import("Output.zig");
|
|
const SceneNodeData = @import("SceneNodeData.zig");
|
|
|
|
const gpa = std.heap.c_allocator;
|
|
const server = &@import("main.zig").server;
|
|
|
|
id: u64,
|
|
|
|
xdg_popup: *wlr.XdgPopup,
|
|
tree: *wlr.SceneTree,
|
|
|
|
// Surface Listeners
|
|
destroy: wl.Listener(void) = wl.Listener(void).init(handleDestroy),
|
|
commit: wl.Listener(*wlr.Surface) = wl.Listener(*wlr.Surface).init(handleCommit),
|
|
new_popup: wl.Listener(*wlr.XdgPopup) = wl.Listener(*wlr.XdgPopup).init(handleNewPopup),
|
|
reposition: wl.Listener(void) = wl.Listener(void).init(handleReposition),
|
|
|
|
pub fn init(
|
|
xdg_popup: *wlr.XdgPopup,
|
|
parent: *wlr.SceneTree,
|
|
) *Popup {
|
|
errdefer Utils.oomPanic();
|
|
|
|
const self = try gpa.create(Popup);
|
|
errdefer gpa.destroy(self);
|
|
|
|
self.* = .{
|
|
.id = @intFromPtr(xdg_popup),
|
|
.xdg_popup = xdg_popup,
|
|
.tree = try parent.createSceneXdgSurface(xdg_popup.base),
|
|
};
|
|
|
|
xdg_popup.events.destroy.add(&self.destroy);
|
|
xdg_popup.base.surface.events.commit.add(&self.commit);
|
|
xdg_popup.base.events.new_popup.add(&self.new_popup);
|
|
xdg_popup.events.reposition.add(&self.reposition);
|
|
|
|
return self;
|
|
}
|
|
|
|
fn handleDestroy(listener: *wl.Listener(void)) void {
|
|
const popup: *Popup = @fieldParentPtr("destroy", listener);
|
|
|
|
popup.destroy.link.remove();
|
|
popup.commit.link.remove();
|
|
popup.new_popup.link.remove();
|
|
popup.reposition.link.remove();
|
|
|
|
gpa.destroy(popup);
|
|
}
|
|
|
|
fn handleCommit(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void {
|
|
const popup: *Popup = @fieldParentPtr("commit", listener);
|
|
if (popup.xdg_popup.base.initial_commit) {
|
|
handleReposition(&popup.reposition);
|
|
}
|
|
}
|
|
|
|
fn handleNewPopup(listener: *wl.Listener(*wlr.XdgPopup), xdg_popup: *wlr.XdgPopup) void {
|
|
const popup: *Popup = @fieldParentPtr("new_popup", listener);
|
|
|
|
_ = Popup.init(xdg_popup, popup.tree);
|
|
}
|
|
|
|
fn handleReposition(listener: *wl.Listener(void)) void {
|
|
const popup: *Popup = @fieldParentPtr("reposition", listener);
|
|
|
|
var box: wlr.Box = undefined;
|
|
|
|
// TODO: figure this out to prevent popups from rendering outside of the
|
|
// current monitor
|
|
//
|
|
// if (SceneNodeData.getFromNode(&popup.tree.node)) |node| {
|
|
// const output = switch (node.data) {
|
|
// .view => |view| view.output orelse return,
|
|
// .layer_surface => |layer_surface| layer_surface.output,
|
|
// };
|
|
//
|
|
// server.root.output_layout.getBox(output.wlr_output, &box);
|
|
// }
|
|
|
|
var root_lx: c_int = undefined;
|
|
var root_ly: c_int = undefined;
|
|
_ = popup.tree.node.coords(&root_lx, &root_ly);
|
|
|
|
box.x -= root_lx;
|
|
box.y -= root_ly;
|
|
|
|
popup.xdg_popup.unconstrainFromBox(&box);
|
|
}
|