mirror of
https://github.com/MezzalunaWM/Mezzaluna.git
synced 2026-03-08 04:57:32 -04:00
Create popups when a view recieves an event...
This is currently incomplete and needs work to make sure that popups stay inside their parents current output. fixing popups, wip
This commit is contained in:
parent
3203839a58
commit
814daf0f2e
4 changed files with 122 additions and 9 deletions
97
src/Popup.zig
Normal file
97
src/Popup.zig
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
@ -38,3 +38,17 @@ fn handleDestroy(listener: *wl.Listener(void)) void {
|
||||||
|
|
||||||
gpa.destroy(scene_node_data);
|
gpa.destroy(scene_node_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn getFromNode(node: *wlr.SceneNode) ?*SceneNodeData {
|
||||||
|
var n = node;
|
||||||
|
while (true) {
|
||||||
|
if (@as(?*SceneNodeData, @alignCast(@ptrCast(n.data)))) |scene_node_data| {
|
||||||
|
return scene_node_data;
|
||||||
|
}
|
||||||
|
if (n.parent) |parent_tree| {
|
||||||
|
n = &parent_tree.node;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ const Utils = @import("Utils.zig");
|
||||||
const Keymap = @import("types/Keymap.zig");
|
const Keymap = @import("types/Keymap.zig");
|
||||||
const Hook = @import("types/Hook.zig");
|
const Hook = @import("types/Hook.zig");
|
||||||
const Events = @import("types/Events.zig");
|
const Events = @import("types/Events.zig");
|
||||||
|
const Popup = @import("Popup.zig");
|
||||||
|
|
||||||
const gpa = std.heap.c_allocator;
|
const gpa = std.heap.c_allocator;
|
||||||
const server = &@import("main.zig").server;
|
const server = &@import("main.zig").server;
|
||||||
|
|
@ -199,11 +200,8 @@ fn handleNewXdgToplevelDecoration(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handleNewXdgPopup(
|
fn handleNewXdgPopup(_: *wl.Listener(*wlr.XdgPopup), xdg_popup: *wlr.XdgPopup) void {
|
||||||
_: *wl.Listener(*wlr.XdgPopup),
|
_ = xdg_popup;
|
||||||
_: *wlr.XdgPopup
|
|
||||||
) void {
|
|
||||||
std.log.err("Unimplemented handle new xdg popup", .{});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handleNewLayerSurface(
|
fn handleNewLayerSurface(
|
||||||
|
|
|
||||||
12
src/View.zig
12
src/View.zig
|
|
@ -4,6 +4,8 @@ const std = @import("std");
|
||||||
const wl = @import("wayland").server.wl;
|
const wl = @import("wayland").server.wl;
|
||||||
const wlr = @import("wlroots");
|
const wlr = @import("wlroots");
|
||||||
|
|
||||||
|
const Popup = @import("Popup.zig");
|
||||||
|
const Output = @import("Output.zig");
|
||||||
const Utils = @import("Utils.zig");
|
const Utils = @import("Utils.zig");
|
||||||
|
|
||||||
const gpa = std.heap.c_allocator;
|
const gpa = std.heap.c_allocator;
|
||||||
|
|
@ -14,6 +16,7 @@ focused: bool,
|
||||||
id: u64,
|
id: u64,
|
||||||
|
|
||||||
// workspace: Workspace,
|
// workspace: Workspace,
|
||||||
|
output: ?*Output,
|
||||||
xdg_toplevel: *wlr.XdgToplevel,
|
xdg_toplevel: *wlr.XdgToplevel,
|
||||||
xdg_toplevel_decoration: ?*wlr.XdgToplevelDecorationV1,
|
xdg_toplevel_decoration: ?*wlr.XdgToplevelDecorationV1,
|
||||||
scene_tree: *wlr.SceneTree,
|
scene_tree: *wlr.SceneTree,
|
||||||
|
|
@ -54,6 +57,7 @@ pub fn initFromTopLevel(xdg_toplevel: *wlr.XdgToplevel) *View {
|
||||||
.focused = false,
|
.focused = false,
|
||||||
.mapped = false,
|
.mapped = false,
|
||||||
.id = @intFromPtr(xdg_toplevel),
|
.id = @intFromPtr(xdg_toplevel),
|
||||||
|
.output = null,
|
||||||
|
|
||||||
.xdg_toplevel = xdg_toplevel,
|
.xdg_toplevel = xdg_toplevel,
|
||||||
.scene_tree = undefined,
|
.scene_tree = undefined,
|
||||||
|
|
@ -66,6 +70,7 @@ pub fn initFromTopLevel(xdg_toplevel: *wlr.XdgToplevel) *View {
|
||||||
// Later add to spesified output
|
// Later add to spesified output
|
||||||
if(server.seat.focused_output) |output| {
|
if(server.seat.focused_output) |output| {
|
||||||
self.scene_tree = try output.layers.content.createSceneXdgSurface(xdg_toplevel.base);
|
self.scene_tree = try output.layers.content.createSceneXdgSurface(xdg_toplevel.base);
|
||||||
|
self.output = output;
|
||||||
} else {
|
} else {
|
||||||
std.log.err("No output to attach new view to", .{});
|
std.log.err("No output to attach new view to", .{});
|
||||||
self.scene_tree = try server.root.waiting_room.createSceneXdgSurface(xdg_toplevel.base);
|
self.scene_tree = try server.root.waiting_room.createSceneXdgSurface(xdg_toplevel.base);
|
||||||
|
|
@ -212,10 +217,9 @@ fn handleCommit(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void {
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------- XdgToplevel Event Handlers ---------
|
// --------- XdgToplevel Event Handlers ---------
|
||||||
fn handleNewPopup(listener: *wl.Listener(*wlr.XdgPopup), popup: *wlr.XdgPopup) void {
|
fn handleNewPopup(listener: *wl.Listener(*wlr.XdgPopup), xdg_popup: *wlr.XdgPopup) void {
|
||||||
_ = listener;
|
const view: *View = @fieldParentPtr("new_popup", listener);
|
||||||
_ = popup;
|
_ = Popup.init(xdg_popup, view.scene_tree);
|
||||||
std.log.err("Unimplemented view handle new popup", .{});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handleRequestMove(
|
fn handleRequestMove(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue