Skip to content

Commit

Permalink
stash
Browse files Browse the repository at this point in the history
Signed-off-by: Shinyzenith <aakashsensharma@gmail.com>
  • Loading branch information
Shinyzenith committed Aug 6, 2023
1 parent 0cc9389 commit 07f1da3
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 4 deletions.
23 changes: 21 additions & 2 deletions next/Server.zig
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const Cursor = @import("input/Cursor.zig");
const DecorationManager = @import("desktop/DecorationManager.zig");
const InputManager = @import("input/InputManager.zig");
const Keyboard = @import("input/Keyboard.zig");
const LayerSurface = @import("desktop/LayerSurface.zig");
const Output = @import("desktop/Output.zig");
const OutputLayout = @import("desktop/OutputLayout.zig");
const Seat = @import("input/Seat.zig");
Expand Down Expand Up @@ -380,13 +381,15 @@ fn newXdgSurface(listener: *wl.Listener(*wlr.XdgSurface), xdg_surface: *wlr.XdgS
};
} else {
log.err("No focused wlr_output found. Skipping xdg_toplevel.", .{});
xdg_surface.resource.destroy();
return;
}
}
}

// This callback is called when a new layer surface is created.
pub fn newLayerSurface(_: *wl.Listener(*wlr.LayerSurfaceV1), wlr_layer_surface: *wlr.LayerSurfaceV1) void {
pub fn newLayerSurface(listener: *wl.Listener(*wlr.LayerSurfaceV1), wlr_layer_surface: *wlr.LayerSurfaceV1) void {
const self = @fieldParentPtr(Self, "new_layer_surface", listener);
log.debug("Signal: wlr_layer_shell_new_surface", .{});
log.debug(
"New layer surface: namespace {s}, layer {s}, anchor {b:0>4}, size {},{}, margin {},{},{},{}, exclusive_zone {}",
Expand All @@ -403,7 +406,23 @@ pub fn newLayerSurface(_: *wl.Listener(*wlr.LayerSurfaceV1), wlr_layer_surface:
wlr_layer_surface.pending.exclusive_zone,
},
);
// TODO: Finish this.

if (wlr_layer_surface.output == null) {
const output = self.seat.focused_output orelse {
log.err("No focused output found for surface: {s}", .{wlr_layer_surface.namespace});
wlr_layer_surface.destroy();
return;
};

log.debug("Null output layer surface assigned to output: {s}", .{output.wlr_output.name});
wlr_layer_surface.output = output.wlr_output;
}

LayerSurface.init(wlr_layer_surface) catch {
log.err("Failed to allocate memory", .{});
wlr_layer_surface.resource.postNoMemory();
return;
};
}

// This callback is called when a new xwayland surface is created.
Expand Down
114 changes: 114 additions & 0 deletions next/desktop/LayerSurface.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// SPDX-License-Identifier: BSD 2-Clause "Simplified" License
//
// next/desktop/LayerSurface.zig
//
// Created by: Aakash Sen Sharma, August 2023
// Copyright: (C) 2023, Aakash Sen Sharma & Contributors

const Self = @This();

const allocator = @import("../utils/allocator.zig").allocator;
const log = std.log.scoped(.LayerSurface);
const server = &@import("../next.zig").server;
const std = @import("std");

const wl = @import("wayland").server.wl;
const wlr = @import("wlroots");

const Output = @import("Output.zig");

output: *Output,
mapped: bool = false,

wlr_layer_surface: *wlr.LayerSurfaceV1,
scene_layer_surface: *wlr.SceneLayerSurfaceV1,
scene_tree: *wlr.SceneTree,
popup_scene_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 init(wlr_layer_surface: *wlr.LayerSurfaceV1) error{OutOfMemory}!void {
const layer_surface_output = @intToPtr(*Output, wlr_layer_surface.output.?.data);

const self = try allocator.create(Self);
errdefer allocator.destroy(self);

var layer_tree: *wlr.SceneTree = undefined;
switch (wlr_layer_surface.current.layer) {
.background => {
layer_tree = server.layer_bg;
},
.bottom => {
layer_tree = server.layer_bottom;
},
.top => {
layer_tree = server.layer_top;
},
.overlay => {
layer_tree = server.layer_overlay;
},
else => {},
}

const scene_layer_surface = try layer_tree.createSceneLayerSurfaceV1(wlr_layer_surface);
const popup_scene_tree = try layer_tree.createSceneTree();
wlr_layer_surface.surface.data = @ptrToInt(popup_scene_tree);

self.* = .{
.output = layer_surface_output,
.wlr_layer_surface = wlr_layer_surface,
.scene_layer_surface = scene_layer_surface,
.scene_tree = scene_layer_surface.tree,
.popup_scene_tree = popup_scene_tree,
};

self.scene_tree.node.data = @ptrToInt(self);

wlr_layer_surface.data = @ptrToInt(self);

wlr_layer_surface.events.destroy.add(&self.destroy);
wlr_layer_surface.events.map.add(&self.map);
wlr_layer_surface.events.unmap.add(&self.unmap);

handleCommit(&self.commit, wlr_layer_surface.surface);

// Temporarily set layers state to pending so we can arrange it easily.
const previous_state = wlr_layer_surface.current;
wlr_layer_surface.current = wlr_layer_surface.pending;
self.mapped = true;
//TODO: arrangelayers.
wlr_layer_surface.current = previous_state;
}

fn handleMap(listener: *wl.Listener(*wlr.LayerSurfaceV1), wlr_layer_surface: *wlr.LayerSurfaceV1) void {
const self = @fieldParentPtr(Self, "map", listener);
log.debug("Signal: wlr_layer_surface_v1_map", .{});
log.debug("Layer surface '{s}' mapped", .{wlr_layer_surface.namespace});

_ = self;
}

fn handleUnmap(_: *wl.Listener(*wlr.LayerSurfaceV1), _: *wlr.LayerSurfaceV1) void {}
fn handleDestroy(listener: *wl.Listener(*wlr.LayerSurfaceV1), _: *wlr.LayerSurfaceV1) void {
const self = @fieldParentPtr(Self, "destroy", listener);
log.debug("Signal: wlr_layer_surface_v1_destroy", .{});

self.destroy.link.remove();
self.map.link.remove();
self.unmap.link.remove();

//TODO: Destroy all popups here.

allocator.destroy(self);
}

fn handleCommit(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void {
const self = @fieldParentPtr(Self, "commit", listener);
log.debug("Signal: wlr_surface_commit", .{});

_ = self;
}
29 changes: 28 additions & 1 deletion next/desktop/Output.zig
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub const WallpaperMode = enum {
};

server: *Server,
usable_box: wlr.Box, // The output space remaining after respecting layer-shelll exclusive zones.

wlr_output: *wlr.Output,

Expand Down Expand Up @@ -67,9 +68,19 @@ pub fn init(self: *Self, wlr_output: *wlr.Output) !void {

//TODO: self.wlr_output.enableAdaptiveSync(true); if config states it.

var width: c_int = undefined;
var height: c_int = undefined;
self.wlr_output.effectiveResolution(&width, &height);

self.* = .{
.server = server,
.wlr_output = wlr_output,
.usable_box = .{
.x = 0,
.y = 0,
.width = width,
.height = height,
},
};

self.wlr_output.data = @ptrToInt(&self);
Expand All @@ -96,7 +107,7 @@ pub fn init(self: *Self, wlr_output: *wlr.Output) !void {
}

// If focused_output is null, we become the new focused_output :)
if (self.server.seat.focused_output) |_| {} else {
if (self.server.seat.focused_output == null) {
self.server.seat.focusOutput(self);
}
}
Expand Down Expand Up @@ -251,3 +262,19 @@ pub fn getName(self: *Self) []const u8 {
const name = self.wlr_output.name;
return std.mem.span(name);
}

pub fn arrangeLayers(self: *Self) void {
var box: wlr.Box = .{
.x = 0,
.y = 0,
.width = undefined,
.height = undefined,
};
self.wlr_output.effectiveResolution(&box.width, &box.height);

var usable_box = box;

//TODO: Finish this.

self.usable_box = usable_box;
}
2 changes: 1 addition & 1 deletion next/desktop/OutputLayout.zig
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ fn layoutChange(listener: *wl.Listener(*wlr.OutputLayout), _: *wlr.OutputLayout)
// Everytime an output is resized / added / removed, we redo wallpaper rendering.
// This is probably not efficient but without it in nested sessions, if wlr_output is resized, the wallpaper doesn't get resized accordingly.
for (self.server.outputs.items) |output| {
if (self.server.seat.focused_output) |_| {} else {
if (self.server.seat.focused_output == null) {
self.server.seat.focusOutput(output);
}

Expand Down

0 comments on commit 07f1da3

Please sign in to comment.