mirror of
https://github.com/MezzalunaWM/Mezzaluna.git
synced 2026-03-07 19:49:53 -05:00
some basic xdg surface stuff
This commit is contained in:
parent
f500937b96
commit
f10906f0fc
4 changed files with 104 additions and 38 deletions
|
|
@ -3,13 +3,13 @@ const Output = @This();
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const posix = std.posix;
|
const posix = std.posix;
|
||||||
const gpa = std.heap.c_allocator;
|
const gpa = std.heap.c_allocator;
|
||||||
|
const server = &@import("main.zig").server;
|
||||||
|
|
||||||
const wl = @import("wayland").server.wl;
|
const wl = @import("wayland").server.wl;
|
||||||
const wlr = @import("wlroots");
|
const wlr = @import("wlroots");
|
||||||
|
|
||||||
const Server = @import("server.zig");
|
const Server = @import("server.zig");
|
||||||
|
|
||||||
server: *Server,
|
|
||||||
wlr_output: *wlr.Output,
|
wlr_output: *wlr.Output,
|
||||||
|
|
||||||
frame: wl.Listener(*wlr.Output) = .init(handleFrame),
|
frame: wl.Listener(*wlr.Output) = .init(handleFrame),
|
||||||
|
|
@ -17,11 +17,10 @@ request_state: wl.Listener(*wlr.Output.event.RequestState) = .init(handleRequest
|
||||||
destroy: wl.Listener(*wlr.Output) = .init(handleDestroy),
|
destroy: wl.Listener(*wlr.Output) = .init(handleDestroy),
|
||||||
|
|
||||||
// The wlr.Output should be destroyed by the caller on failure to trigger cleanup.
|
// The wlr.Output should be destroyed by the caller on failure to trigger cleanup.
|
||||||
pub fn create(server: *Server, wlr_output: *wlr.Output) !*Output {
|
pub fn create(wlr_output: *wlr.Output) !*Output {
|
||||||
const output = try gpa.create(Output);
|
const output = try gpa.create(Output);
|
||||||
|
|
||||||
output.* = .{
|
output.* = .{
|
||||||
.server = server,
|
|
||||||
.wlr_output = wlr_output,
|
.wlr_output = wlr_output,
|
||||||
};
|
};
|
||||||
wlr_output.events.frame.add(&output.frame);
|
wlr_output.events.frame.add(&output.frame);
|
||||||
|
|
@ -42,6 +41,7 @@ pub fn handleRequestState(
|
||||||
listener: *wl.Listener(*wlr.Output.event.RequestState),
|
listener: *wl.Listener(*wlr.Output.event.RequestState),
|
||||||
event: *wlr.Output.event.RequestState,
|
event: *wlr.Output.event.RequestState,
|
||||||
) void {
|
) void {
|
||||||
|
std.log.debug("Handling request state", .{});
|
||||||
const output: *Output = @fieldParentPtr("request_state", listener);
|
const output: *Output = @fieldParentPtr("request_state", listener);
|
||||||
|
|
||||||
if (!output.wlr_output.commitState(event.state)) {
|
if (!output.wlr_output.commitState(event.state)) {
|
||||||
|
|
@ -49,13 +49,13 @@ event: *wlr.Output.event.RequestState,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handleFrame(listener: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output) void {
|
pub fn handleFrame(_: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output) void {
|
||||||
const output: *Output = @fieldParentPtr("destroy", listener);
|
std.log.debug("Handling frame for {s}", .{wlr_output.name});
|
||||||
|
|
||||||
const scene_output = output.*.server.*.scene.*.getSceneOutput(wlr_output);
|
const scene_output = server.scene.*.getSceneOutput(wlr_output);
|
||||||
|
|
||||||
if(scene_output) |so| {
|
if(scene_output) |so| {
|
||||||
std.log.info("Rendering commitin scene output\n", .{});
|
std.log.info("Rendering commited scene output\n", .{});
|
||||||
_ = so.commit(null);
|
_ = so.commit(null);
|
||||||
|
|
||||||
var now = posix.clock_gettime(posix.CLOCK.MONOTONIC) catch @panic("CLOCK_MONOTONIC not supported");
|
var now = posix.clock_gettime(posix.CLOCK.MONOTONIC) catch @panic("CLOCK_MONOTONIC not supported");
|
||||||
|
|
@ -65,6 +65,7 @@ pub fn handleFrame(listener: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handleDestroy(listener: *wl.Listener(*wlr.Output), _: *wlr.Output) void {
|
pub fn handleDestroy(listener: *wl.Listener(*wlr.Output), _: *wlr.Output) void {
|
||||||
|
std.log.debug("Handling destroy", .{});
|
||||||
const output: *Output = @fieldParentPtr("destroy", listener);
|
const output: *Output = @fieldParentPtr("destroy", listener);
|
||||||
|
|
||||||
std.log.debug("removing output: {s}", .{output.*.wlr_output.*.name});
|
std.log.debug("removing output: {s}", .{output.*.wlr_output.*.name});
|
||||||
|
|
|
||||||
69
src/root.zig
69
src/root.zig
|
|
@ -1,50 +1,58 @@
|
||||||
const std = @import("std");
|
const Root = @This();
|
||||||
|
|
||||||
|
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 Output = @import("output.zig");
|
const Output = @import("output.zig");
|
||||||
|
const TopLevel = @import("toplevel.zig");
|
||||||
|
|
||||||
const server = &@import("main.zig").server;
|
const server = &@import("main.zig").server;
|
||||||
|
const gpa = std.heap.c_allocator;
|
||||||
|
|
||||||
pub const Root = struct {
|
scene: *wlr.Scene,
|
||||||
scene: *wlr.Scene,
|
|
||||||
|
|
||||||
output_layout: *wlr.OutputLayout,
|
output_layout: *wlr.OutputLayout,
|
||||||
|
|
||||||
new_output: wl.Listener(*wlr.Output),
|
new_output: wl.Listener(*wlr.Output),
|
||||||
|
|
||||||
pub fn init(root: *Root) !void {
|
all_top_levels: std.ArrayList(*TopLevel),
|
||||||
std.log.info("Creating root of mezzaluna\n", .{});
|
|
||||||
|
|
||||||
const output_layout = try wlr.OutputLayout.create(server.wl_server);
|
pub fn init(root: *Root) !void {
|
||||||
errdefer output_layout.destroy();
|
std.log.info("Creating root of mezzaluna\n", .{});
|
||||||
|
|
||||||
const scene = try wlr.Scene.create();
|
const output_layout = try wlr.OutputLayout.create(server.wl_server);
|
||||||
errdefer scene.tree.node.destroy();
|
errdefer output_layout.destroy();
|
||||||
|
|
||||||
root.* = .{
|
const scene = try wlr.Scene.create();
|
||||||
.scene = scene,
|
errdefer scene.tree.node.destroy();
|
||||||
.output_layout = output_layout,
|
|
||||||
|
|
||||||
.new_output = .init(handleNewOutput),
|
root.* = .{
|
||||||
};
|
.scene = scene,
|
||||||
|
.output_layout = output_layout,
|
||||||
|
|
||||||
server.backend.events.new_output.add(&root.new_output);
|
.new_output = .init(handleNewOutput),
|
||||||
}
|
|
||||||
|
|
||||||
pub fn addOutput(self: *Root, new_output: *Output) void {
|
.all_top_levels = try .initCapacity(gpa, 10),
|
||||||
_ = self.output_layout.addAuto(new_output.wlr_output) catch {
|
};
|
||||||
std.log.err("failed to add new output to output layout\n", .{});
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
// _ = self.scene.createSceneOutput(new_output.wlr_output) catch {
|
server.backend.events.new_output.add(&root.new_output);
|
||||||
// std.log.err("failed to create scene output for new output", .{});
|
}
|
||||||
// return;
|
|
||||||
// };
|
pub fn addOutput(self: *Root, new_output: *Output) void {
|
||||||
}
|
_ = self.output_layout.addAuto(new_output.wlr_output) catch {
|
||||||
};
|
std.log.err("failed to add new output to output layout\n", .{});
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn addTopLevel(self: *Root, top_level: *TopLevel) void {
|
||||||
|
self.all_top_levels.append(gpa, top_level) catch {
|
||||||
|
std.log.err("Out of memory to append top level", .{});
|
||||||
|
};
|
||||||
|
|
||||||
|
// self.scene.tree.children.append(wlr.SceneNode)
|
||||||
|
}
|
||||||
|
|
||||||
fn handleNewOutput(_: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output) void {
|
fn handleNewOutput(_: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output) void {
|
||||||
std.log.info("Handling a new output - {s}", .{wlr_output.name});
|
std.log.info("Handling a new output - {s}", .{wlr_output.name});
|
||||||
|
|
@ -61,7 +69,7 @@ fn handleNewOutput(_: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output) void {
|
||||||
}
|
}
|
||||||
if (!wlr_output.commitState(&state)) return;
|
if (!wlr_output.commitState(&state)) return;
|
||||||
|
|
||||||
const new_output = Output.create(server, wlr_output) catch {
|
const new_output = Output.create(wlr_output) catch {
|
||||||
std.log.err("failed to allocate new output", .{});
|
std.log.err("failed to allocate new output", .{});
|
||||||
wlr_output.destroy();
|
wlr_output.destroy();
|
||||||
return;
|
return;
|
||||||
|
|
@ -69,3 +77,4 @@ fn handleNewOutput(_: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output) void {
|
||||||
|
|
||||||
server.root.addOutput(new_output);
|
server.root.addOutput(new_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,8 @@ const wlr = @import("wlroots");
|
||||||
|
|
||||||
const Output = @import("output.zig");
|
const Output = @import("output.zig");
|
||||||
const Keyboard = @import("keyboard.zig");
|
const Keyboard = @import("keyboard.zig");
|
||||||
const Root = @import("root.zig").Root;
|
const TopLevel = @import("toplevel.zig");
|
||||||
|
const Root = @import("root.zig");
|
||||||
|
|
||||||
allocator: *wlr.Allocator,
|
allocator: *wlr.Allocator,
|
||||||
backend: *wlr.Backend,
|
backend: *wlr.Backend,
|
||||||
|
|
@ -32,6 +33,9 @@ cursor_mgr: *wlr.XcursorManager,
|
||||||
|
|
||||||
// Listeners
|
// Listeners
|
||||||
new_input: wl.Listener(*wlr.InputDevice) = .init(newInput),
|
new_input: wl.Listener(*wlr.InputDevice) = .init(newInput),
|
||||||
|
|
||||||
|
new_xdg_surface: wl.Listener(*wlr.XdgSurface) = .init(handleNewXdgSurface),
|
||||||
|
|
||||||
cursor_motion: wl.Listener(*wlr.Pointer.event.Motion) = .init(cursorMotion),
|
cursor_motion: wl.Listener(*wlr.Pointer.event.Motion) = .init(cursorMotion),
|
||||||
cursor_motion_absolute: wl.Listener(*wlr.Pointer.event.MotionAbsolute) = .init(cursorMotionAbsolute),
|
cursor_motion_absolute: wl.Listener(*wlr.Pointer.event.MotionAbsolute) = .init(cursorMotionAbsolute),
|
||||||
cursor_button: wl.Listener(*wlr.Pointer.event.Button) = .init(cursorButton),
|
cursor_button: wl.Listener(*wlr.Pointer.event.Button) = .init(cursorButton),
|
||||||
|
|
@ -75,9 +79,13 @@ pub fn init(server: *Server) !void {
|
||||||
try server.renderer.initServer(wl_server);
|
try server.renderer.initServer(wl_server);
|
||||||
try Root.init(&server.root);
|
try Root.init(&server.root);
|
||||||
|
|
||||||
|
server.xdg_shell.events.new_surface.add(&server.new_xdg_surface);
|
||||||
|
|
||||||
server.backend.events.new_input.add(&server.new_input);
|
server.backend.events.new_input.add(&server.new_input);
|
||||||
|
|
||||||
server.seat.events.request_set_cursor.add(&server.request_set_cursor);
|
server.seat.events.request_set_cursor.add(&server.request_set_cursor);
|
||||||
server.seat.events.request_set_selection.add(&server.request_set_selection);
|
server.seat.events.request_set_selection.add(&server.request_set_selection);
|
||||||
|
|
||||||
server.keyboards.init();
|
server.keyboards.init();
|
||||||
|
|
||||||
server.cursor.attachOutputLayout(server.output_layout);
|
server.cursor.attachOutputLayout(server.output_layout);
|
||||||
|
|
@ -237,3 +245,16 @@ fn requestSetSelection(
|
||||||
const server: *Server = @fieldParentPtr("request_set_selection", listener);
|
const server: *Server = @fieldParentPtr("request_set_selection", listener);
|
||||||
server.seat.setSelection(event.source, event.serial);
|
server.seat.setSelection(event.source, event.serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handleNewXdgSurface(listener: *wl.Listener(*wlr.XdgSurface), xdg_surface: *wlr.XdgSurface) void {
|
||||||
|
const server: *Server = @fieldParentPtr("new_xdg_surface", listener);
|
||||||
|
|
||||||
|
std.log.info("New xdg_toplevel added", .{});
|
||||||
|
|
||||||
|
const top_level = TopLevel.init(xdg_surface) catch {
|
||||||
|
std.log.err("Unable to allocate a top level", .{});
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
server.root.addTopLevel(top_level);
|
||||||
|
}
|
||||||
|
|
|
||||||
35
src/toplevel.zig
Normal file
35
src/toplevel.zig
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
const TopLevel = @This();
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const wl = @import("wayland").server.wl;
|
||||||
|
const wlr = @import("wlroots");
|
||||||
|
|
||||||
|
const gpa = std.heap.c_allocator;
|
||||||
|
const server = &@import("main.zig").server;
|
||||||
|
|
||||||
|
xdg_toplevel: *wlr.XdgToplevel,
|
||||||
|
box: *wlr.Box,
|
||||||
|
|
||||||
|
pub fn init(xdg_surface: *wlr.XdgSurface) !*TopLevel {
|
||||||
|
const top_level = gpa.create(TopLevel) catch |err| {
|
||||||
|
std.log.err("Unable to allocate memory for new XdgTopLevel", .{});
|
||||||
|
return err;
|
||||||
|
};
|
||||||
|
|
||||||
|
if(xdg_surface.role_data.toplevel) |xgd_toplevel| {
|
||||||
|
top_level.* = .{
|
||||||
|
.xdg_toplevel = xgd_toplevel,
|
||||||
|
.box = undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
top_level.box.x = 0;
|
||||||
|
top_level.box.y = 0;
|
||||||
|
top_level.box.width = 640;
|
||||||
|
top_level.box.height = 360;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen to important toplevel events
|
||||||
|
// top_level.xdg_toplevel.events.set_title.add(listener: *Listener(void))
|
||||||
|
|
||||||
|
return top_level;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue