render: remove damage tracking
This will be handled by wlr_scene shortly.
This commit is contained in:
parent
b7ac5becfb
commit
168756cbe8
@ -24,7 +24,6 @@ const server = &@import("main.zig").server;
|
|||||||
const util = @import("util.zig");
|
const util = @import("util.zig");
|
||||||
|
|
||||||
const Seat = @import("Seat.zig");
|
const Seat = @import("Seat.zig");
|
||||||
const Subsurface = @import("Subsurface.zig");
|
|
||||||
|
|
||||||
seat: *Seat,
|
seat: *Seat,
|
||||||
wlr_drag_icon: *wlr.Drag.Icon,
|
wlr_drag_icon: *wlr.Drag.Icon,
|
||||||
@ -35,63 +34,29 @@ sy: i32 = 0,
|
|||||||
|
|
||||||
// Always active
|
// Always active
|
||||||
destroy: wl.Listener(*wlr.Drag.Icon) = wl.Listener(*wlr.Drag.Icon).init(handleDestroy),
|
destroy: wl.Listener(*wlr.Drag.Icon) = wl.Listener(*wlr.Drag.Icon).init(handleDestroy),
|
||||||
map: wl.Listener(*wlr.Drag.Icon) = wl.Listener(*wlr.Drag.Icon).init(handleMap),
|
|
||||||
unmap: wl.Listener(*wlr.Drag.Icon) = wl.Listener(*wlr.Drag.Icon).init(handleUnmap),
|
|
||||||
commit: wl.Listener(*wlr.Surface) = wl.Listener(*wlr.Surface).init(handleCommit),
|
commit: wl.Listener(*wlr.Surface) = wl.Listener(*wlr.Surface).init(handleCommit),
|
||||||
new_subsurface: wl.Listener(*wlr.Subsurface) = wl.Listener(*wlr.Subsurface).init(handleNewSubsurface),
|
|
||||||
|
|
||||||
pub fn init(drag_icon: *DragIcon, seat: *Seat, wlr_drag_icon: *wlr.Drag.Icon) void {
|
pub fn init(drag_icon: *DragIcon, seat: *Seat, wlr_drag_icon: *wlr.Drag.Icon) void {
|
||||||
drag_icon.* = .{ .seat = seat, .wlr_drag_icon = wlr_drag_icon };
|
drag_icon.* = .{ .seat = seat, .wlr_drag_icon = wlr_drag_icon };
|
||||||
|
|
||||||
wlr_drag_icon.events.destroy.add(&drag_icon.destroy);
|
wlr_drag_icon.events.destroy.add(&drag_icon.destroy);
|
||||||
wlr_drag_icon.events.map.add(&drag_icon.map);
|
|
||||||
wlr_drag_icon.events.unmap.add(&drag_icon.unmap);
|
|
||||||
wlr_drag_icon.surface.events.commit.add(&drag_icon.commit);
|
wlr_drag_icon.surface.events.commit.add(&drag_icon.commit);
|
||||||
wlr_drag_icon.surface.events.new_subsurface.add(&drag_icon.new_subsurface);
|
|
||||||
|
|
||||||
if (wlr_drag_icon.mapped) handleMap(&drag_icon.map, wlr_drag_icon);
|
|
||||||
|
|
||||||
Subsurface.handleExisting(wlr_drag_icon.surface, .{ .drag_icon = drag_icon });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handleDestroy(listener: *wl.Listener(*wlr.Drag.Icon), wlr_drag_icon: *wlr.Drag.Icon) void {
|
fn handleDestroy(listener: *wl.Listener(*wlr.Drag.Icon), _: *wlr.Drag.Icon) void {
|
||||||
const drag_icon = @fieldParentPtr(DragIcon, "destroy", listener);
|
const drag_icon = @fieldParentPtr(DragIcon, "destroy", listener);
|
||||||
|
|
||||||
drag_icon.seat.drag_icon = null;
|
drag_icon.seat.drag_icon = null;
|
||||||
|
|
||||||
drag_icon.destroy.link.remove();
|
drag_icon.destroy.link.remove();
|
||||||
drag_icon.map.link.remove();
|
|
||||||
drag_icon.unmap.link.remove();
|
|
||||||
drag_icon.commit.link.remove();
|
drag_icon.commit.link.remove();
|
||||||
drag_icon.new_subsurface.link.remove();
|
|
||||||
|
|
||||||
Subsurface.destroySubsurfaces(wlr_drag_icon.surface);
|
|
||||||
|
|
||||||
util.gpa.destroy(drag_icon);
|
util.gpa.destroy(drag_icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handleMap(_: *wl.Listener(*wlr.Drag.Icon), _: *wlr.Drag.Icon) void {
|
|
||||||
var it = server.root.outputs.first;
|
|
||||||
while (it) |node| : (it = node.next) node.data.damage.?.addWhole();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handleUnmap(_: *wl.Listener(*wlr.Drag.Icon), _: *wlr.Drag.Icon) void {
|
|
||||||
var it = server.root.outputs.first;
|
|
||||||
while (it) |node| : (it = node.next) node.data.damage.?.addWhole();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handleCommit(listener: *wl.Listener(*wlr.Surface), surface: *wlr.Surface) void {
|
fn handleCommit(listener: *wl.Listener(*wlr.Surface), surface: *wlr.Surface) void {
|
||||||
const drag_icon = @fieldParentPtr(DragIcon, "commit", listener);
|
const drag_icon = @fieldParentPtr(DragIcon, "commit", listener);
|
||||||
|
|
||||||
drag_icon.sx += surface.current.dx;
|
drag_icon.sx += surface.current.dx;
|
||||||
drag_icon.sy += surface.current.dy;
|
drag_icon.sy += surface.current.dy;
|
||||||
|
|
||||||
var it = server.root.outputs.first;
|
|
||||||
while (it) |node| : (it = node.next) node.data.damage.?.addWhole();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handleNewSubsurface(listener: *wl.Listener(*wlr.Subsurface), wlr_subsurface: *wlr.Subsurface) void {
|
|
||||||
const drag_icon = @fieldParentPtr(DragIcon, "new_subsurface", listener);
|
|
||||||
|
|
||||||
Subsurface.create(wlr_subsurface, .{ .drag_icon = drag_icon });
|
|
||||||
}
|
}
|
||||||
|
@ -26,8 +26,6 @@ const server = &@import("main.zig").server;
|
|||||||
const util = @import("util.zig");
|
const util = @import("util.zig");
|
||||||
|
|
||||||
const Output = @import("Output.zig");
|
const Output = @import("Output.zig");
|
||||||
const Subsurface = @import("Subsurface.zig");
|
|
||||||
const XdgPopup = @import("XdgPopup.zig");
|
|
||||||
|
|
||||||
const log = std.log.scoped(.layer_shell);
|
const log = std.log.scoped(.layer_shell);
|
||||||
|
|
||||||
@ -40,8 +38,6 @@ layer: zwlr.LayerShellV1.Layer,
|
|||||||
destroy: wl.Listener(*wlr.LayerSurfaceV1) = wl.Listener(*wlr.LayerSurfaceV1).init(handleDestroy),
|
destroy: wl.Listener(*wlr.LayerSurfaceV1) = wl.Listener(*wlr.LayerSurfaceV1).init(handleDestroy),
|
||||||
map: wl.Listener(*wlr.LayerSurfaceV1) = wl.Listener(*wlr.LayerSurfaceV1).init(handleMap),
|
map: wl.Listener(*wlr.LayerSurfaceV1) = wl.Listener(*wlr.LayerSurfaceV1).init(handleMap),
|
||||||
unmap: wl.Listener(*wlr.LayerSurfaceV1) = wl.Listener(*wlr.LayerSurfaceV1).init(handleUnmap),
|
unmap: wl.Listener(*wlr.LayerSurfaceV1) = wl.Listener(*wlr.LayerSurfaceV1).init(handleUnmap),
|
||||||
new_popup: wl.Listener(*wlr.XdgPopup) = wl.Listener(*wlr.XdgPopup).init(handleNewPopup),
|
|
||||||
new_subsurface: wl.Listener(*wlr.Subsurface) = wl.Listener(*wlr.Subsurface).init(handleNewSubsurface),
|
|
||||||
commit: wl.Listener(*wlr.Surface) = wl.Listener(*wlr.Surface).init(handleCommit),
|
commit: wl.Listener(*wlr.Surface) = wl.Listener(*wlr.Surface).init(handleCommit),
|
||||||
|
|
||||||
pub fn init(self: *Self, output: *Output, wlr_layer_surface: *wlr.LayerSurfaceV1) void {
|
pub fn init(self: *Self, output: *Output, wlr_layer_surface: *wlr.LayerSurfaceV1) void {
|
||||||
@ -56,19 +52,15 @@ pub fn init(self: *Self, output: *Output, wlr_layer_surface: *wlr.LayerSurfaceV1
|
|||||||
wlr_layer_surface.events.destroy.add(&self.destroy);
|
wlr_layer_surface.events.destroy.add(&self.destroy);
|
||||||
wlr_layer_surface.events.map.add(&self.map);
|
wlr_layer_surface.events.map.add(&self.map);
|
||||||
wlr_layer_surface.events.unmap.add(&self.unmap);
|
wlr_layer_surface.events.unmap.add(&self.unmap);
|
||||||
wlr_layer_surface.events.new_popup.add(&self.new_popup);
|
|
||||||
wlr_layer_surface.surface.events.commit.add(&self.commit);
|
wlr_layer_surface.surface.events.commit.add(&self.commit);
|
||||||
wlr_layer_surface.surface.events.new_subsurface.add(&self.new_subsurface);
|
|
||||||
|
|
||||||
// wlroots only informs us of the new surface after the first commit,
|
// wlroots only informs us of the new surface after the first commit,
|
||||||
// so our listener does not get called for this first commit. However,
|
// so our listener does not get called for this first commit. However,
|
||||||
// we do want our listener called in order to send the initial configure.
|
// we do want our listener called in order to send the initial configure.
|
||||||
handleCommit(&self.commit, wlr_layer_surface.surface);
|
handleCommit(&self.commit, wlr_layer_surface.surface);
|
||||||
|
|
||||||
Subsurface.handleExisting(wlr_layer_surface.surface, .{ .layer_surface = self });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handleDestroy(listener: *wl.Listener(*wlr.LayerSurfaceV1), wlr_layer_surface: *wlr.LayerSurfaceV1) void {
|
fn handleDestroy(listener: *wl.Listener(*wlr.LayerSurfaceV1), _: *wlr.LayerSurfaceV1) void {
|
||||||
const self = @fieldParentPtr(Self, "destroy", listener);
|
const self = @fieldParentPtr(Self, "destroy", listener);
|
||||||
|
|
||||||
log.debug("layer surface '{s}' destroyed", .{self.wlr_layer_surface.namespace});
|
log.debug("layer surface '{s}' destroyed", .{self.wlr_layer_surface.namespace});
|
||||||
@ -77,15 +69,7 @@ fn handleDestroy(listener: *wl.Listener(*wlr.LayerSurfaceV1), wlr_layer_surface:
|
|||||||
self.destroy.link.remove();
|
self.destroy.link.remove();
|
||||||
self.map.link.remove();
|
self.map.link.remove();
|
||||||
self.unmap.link.remove();
|
self.unmap.link.remove();
|
||||||
self.new_popup.link.remove();
|
|
||||||
self.commit.link.remove();
|
self.commit.link.remove();
|
||||||
self.new_subsurface.link.remove();
|
|
||||||
|
|
||||||
Subsurface.destroySubsurfaces(self.wlr_layer_surface.surface);
|
|
||||||
var it = wlr_layer_surface.popups.iterator(.forward);
|
|
||||||
while (it.next()) |wlr_xdg_popup| {
|
|
||||||
if (@intToPtr(?*XdgPopup, wlr_xdg_popup.base.data)) |xdg_popup| xdg_popup.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
const node = @fieldParentPtr(std.TailQueue(Self).Node, "data", self);
|
const node = @fieldParentPtr(std.TailQueue(Self).Node, "data", self);
|
||||||
util.gpa.destroy(node);
|
util.gpa.destroy(node);
|
||||||
@ -163,16 +147,4 @@ fn handleCommit(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void {
|
|||||||
self.output.arrangeLayers(.mapped);
|
self.output.arrangeLayers(.mapped);
|
||||||
server.root.startTransaction();
|
server.root.startTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.output.damage.?.addWhole();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handleNewPopup(listener: *wl.Listener(*wlr.XdgPopup), wlr_xdg_popup: *wlr.XdgPopup) void {
|
|
||||||
const self = @fieldParentPtr(Self, "new_popup", listener);
|
|
||||||
XdgPopup.create(wlr_xdg_popup, .{ .layer_surface = self });
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handleNewSubsurface(listener: *wl.Listener(*wlr.Subsurface), new_wlr_subsurface: *wlr.Subsurface) void {
|
|
||||||
const self = @fieldParentPtr(Self, "new_subsurface", listener);
|
|
||||||
Subsurface.create(new_wlr_subsurface, .{ .layer_surface = self });
|
|
||||||
}
|
}
|
||||||
|
@ -130,16 +130,6 @@ fn handleLockSurfacesTimeout(manager: *LockManager) c_int {
|
|||||||
assert(manager.state == .waiting_for_lock_surfaces);
|
assert(manager.state == .waiting_for_lock_surfaces);
|
||||||
manager.state = .waiting_for_blank;
|
manager.state = .waiting_for_blank;
|
||||||
|
|
||||||
{
|
|
||||||
var it = server.root.outputs.first;
|
|
||||||
while (it) |node| : (it = node.next) {
|
|
||||||
const output = &node.data;
|
|
||||||
if (output.lock_render_state == .unlocked) {
|
|
||||||
output.damage.?.addWhole();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This call is necessary in the case that all outputs in the layout are disabled.
|
// This call is necessary in the case that all outputs in the layout are disabled.
|
||||||
manager.maybeLock();
|
manager.maybeLock();
|
||||||
|
|
||||||
|
@ -25,7 +25,6 @@ const util = @import("util.zig");
|
|||||||
|
|
||||||
const Output = @import("Output.zig");
|
const Output = @import("Output.zig");
|
||||||
const Seat = @import("Seat.zig");
|
const Seat = @import("Seat.zig");
|
||||||
const Subsurface = @import("Subsurface.zig");
|
|
||||||
|
|
||||||
wlr_lock_surface: *wlr.SessionLockSurfaceV1,
|
wlr_lock_surface: *wlr.SessionLockSurfaceV1,
|
||||||
lock: *wlr.SessionLockV1,
|
lock: *wlr.SessionLockV1,
|
||||||
@ -33,8 +32,6 @@ lock: *wlr.SessionLockV1,
|
|||||||
output_mode: wl.Listener(*wlr.Output) = wl.Listener(*wlr.Output).init(handleOutputMode),
|
output_mode: wl.Listener(*wlr.Output) = wl.Listener(*wlr.Output).init(handleOutputMode),
|
||||||
map: wl.Listener(void) = wl.Listener(void).init(handleMap),
|
map: wl.Listener(void) = wl.Listener(void).init(handleMap),
|
||||||
surface_destroy: wl.Listener(void) = wl.Listener(void).init(handleDestroy),
|
surface_destroy: wl.Listener(void) = wl.Listener(void).init(handleDestroy),
|
||||||
commit: wl.Listener(*wlr.Surface) = wl.Listener(*wlr.Surface).init(handleCommit),
|
|
||||||
new_subsurface: wl.Listener(*wlr.Subsurface) = wl.Listener(*wlr.Subsurface).init(handleSubsurface),
|
|
||||||
|
|
||||||
pub fn create(wlr_lock_surface: *wlr.SessionLockSurfaceV1, lock: *wlr.SessionLockV1) void {
|
pub fn create(wlr_lock_surface: *wlr.SessionLockSurfaceV1, lock: *wlr.SessionLockV1) void {
|
||||||
const lock_surface = util.gpa.create(LockSurface) catch {
|
const lock_surface = util.gpa.create(LockSurface) catch {
|
||||||
@ -51,17 +48,12 @@ pub fn create(wlr_lock_surface: *wlr.SessionLockSurfaceV1, lock: *wlr.SessionLoc
|
|||||||
wlr_lock_surface.output.events.mode.add(&lock_surface.output_mode);
|
wlr_lock_surface.output.events.mode.add(&lock_surface.output_mode);
|
||||||
wlr_lock_surface.events.map.add(&lock_surface.map);
|
wlr_lock_surface.events.map.add(&lock_surface.map);
|
||||||
wlr_lock_surface.events.destroy.add(&lock_surface.surface_destroy);
|
wlr_lock_surface.events.destroy.add(&lock_surface.surface_destroy);
|
||||||
wlr_lock_surface.surface.events.commit.add(&lock_surface.commit);
|
|
||||||
wlr_lock_surface.surface.events.new_subsurface.add(&lock_surface.new_subsurface);
|
|
||||||
|
|
||||||
handleOutputMode(&lock_surface.output_mode, wlr_lock_surface.output);
|
handleOutputMode(&lock_surface.output_mode, wlr_lock_surface.output);
|
||||||
|
|
||||||
Subsurface.handleExisting(wlr_lock_surface.surface, .{ .lock_surface = lock_surface });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn destroy(lock_surface: *LockSurface) void {
|
pub fn destroy(lock_surface: *LockSurface) void {
|
||||||
lock_surface.output().lock_surface = null;
|
lock_surface.output().lock_surface = null;
|
||||||
if (lock_surface.output().damage) |damage| damage.addWhole();
|
|
||||||
|
|
||||||
{
|
{
|
||||||
var surface_it = lock_surface.lock.surfaces.iterator(.forward);
|
var surface_it = lock_surface.lock.surfaces.iterator(.forward);
|
||||||
@ -83,10 +75,6 @@ pub fn destroy(lock_surface: *LockSurface) void {
|
|||||||
lock_surface.output_mode.link.remove();
|
lock_surface.output_mode.link.remove();
|
||||||
lock_surface.map.link.remove();
|
lock_surface.map.link.remove();
|
||||||
lock_surface.surface_destroy.link.remove();
|
lock_surface.surface_destroy.link.remove();
|
||||||
lock_surface.commit.link.remove();
|
|
||||||
lock_surface.new_subsurface.link.remove();
|
|
||||||
|
|
||||||
Subsurface.destroySubsurfaces(lock_surface.wlr_lock_surface.surface);
|
|
||||||
|
|
||||||
util.gpa.destroy(lock_surface);
|
util.gpa.destroy(lock_surface);
|
||||||
}
|
}
|
||||||
@ -126,14 +114,3 @@ fn handleDestroy(listener: *wl.Listener(void)) void {
|
|||||||
|
|
||||||
lock_surface.destroy();
|
lock_surface.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handleCommit(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void {
|
|
||||||
const lock_surface = @fieldParentPtr(LockSurface, "commit", listener);
|
|
||||||
|
|
||||||
lock_surface.output().damage.?.addWhole();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handleSubsurface(listener: *wl.Listener(*wlr.Subsurface), subsurface: *wlr.Subsurface) void {
|
|
||||||
const lock_surface = @fieldParentPtr(LockSurface, "new_subsurface", listener);
|
|
||||||
Subsurface.create(subsurface, .{ .lock_surface = lock_surface });
|
|
||||||
}
|
|
||||||
|
@ -55,7 +55,6 @@ const State = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
wlr_output: *wlr.Output,
|
wlr_output: *wlr.Output,
|
||||||
damage: ?*wlr.OutputDamage,
|
|
||||||
|
|
||||||
/// All layer surfaces on the output, indexed by the layer enum.
|
/// All layer surfaces on the output, indexed by the layer enum.
|
||||||
layers: [4]std.TailQueue(LayerSurface) = [1]std.TailQueue(LayerSurface){.{}} ** 4,
|
layers: [4]std.TailQueue(LayerSurface) = [1]std.TailQueue(LayerSurface){.{}} ** 4,
|
||||||
@ -115,9 +114,8 @@ status_trackers: std.SinglyLinkedList(OutputStatus) = .{},
|
|||||||
destroy: wl.Listener(*wlr.Output) = wl.Listener(*wlr.Output).init(handleDestroy),
|
destroy: wl.Listener(*wlr.Output) = wl.Listener(*wlr.Output).init(handleDestroy),
|
||||||
enable: wl.Listener(*wlr.Output) = wl.Listener(*wlr.Output).init(handleEnable),
|
enable: wl.Listener(*wlr.Output) = wl.Listener(*wlr.Output).init(handleEnable),
|
||||||
mode: wl.Listener(*wlr.Output) = wl.Listener(*wlr.Output).init(handleMode),
|
mode: wl.Listener(*wlr.Output) = wl.Listener(*wlr.Output).init(handleMode),
|
||||||
|
frame: wl.Listener(*wlr.Output) = wl.Listener(*wlr.Output).init(handleFrame),
|
||||||
present: wl.Listener(*wlr.Output.event.Present) = wl.Listener(*wlr.Output.event.Present).init(handlePresent),
|
present: wl.Listener(*wlr.Output.event.Present) = wl.Listener(*wlr.Output.event.Present).init(handlePresent),
|
||||||
frame: wl.Listener(*wlr.OutputDamage) = wl.Listener(*wlr.OutputDamage).init(handleFrame),
|
|
||||||
damage_destroy: wl.Listener(*wlr.OutputDamage) = wl.Listener(*wlr.OutputDamage).init(handleDamageDestroy),
|
|
||||||
|
|
||||||
pub fn init(self: *Self, wlr_output: *wlr.Output) !void {
|
pub fn init(self: *Self, wlr_output: *wlr.Output) !void {
|
||||||
if (!wlr_output.initRender(server.allocator, server.renderer)) return;
|
if (!wlr_output.initRender(server.allocator, server.renderer)) return;
|
||||||
@ -146,7 +144,6 @@ pub fn init(self: *Self, wlr_output: *wlr.Output) !void {
|
|||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.wlr_output = wlr_output,
|
.wlr_output = wlr_output,
|
||||||
.damage = try wlr.OutputDamage.create(wlr_output),
|
|
||||||
.usable_box = undefined,
|
.usable_box = undefined,
|
||||||
};
|
};
|
||||||
wlr_output.data = @ptrToInt(self);
|
wlr_output.data = @ptrToInt(self);
|
||||||
@ -154,11 +151,9 @@ pub fn init(self: *Self, wlr_output: *wlr.Output) !void {
|
|||||||
wlr_output.events.destroy.add(&self.destroy);
|
wlr_output.events.destroy.add(&self.destroy);
|
||||||
wlr_output.events.enable.add(&self.enable);
|
wlr_output.events.enable.add(&self.enable);
|
||||||
wlr_output.events.mode.add(&self.mode);
|
wlr_output.events.mode.add(&self.mode);
|
||||||
|
wlr_output.events.frame.add(&self.frame);
|
||||||
wlr_output.events.present.add(&self.present);
|
wlr_output.events.present.add(&self.present);
|
||||||
|
|
||||||
self.damage.?.events.frame.add(&self.frame);
|
|
||||||
self.damage.?.events.destroy.add(&self.damage_destroy);
|
|
||||||
|
|
||||||
// Ensure that a cursor image at the output's scale factor is loaded
|
// Ensure that a cursor image at the output's scale factor is loaded
|
||||||
// for each seat.
|
// for each seat.
|
||||||
var it = server.input_manager.seats.first;
|
var it = server.input_manager.seats.first;
|
||||||
@ -458,17 +453,6 @@ fn arrangeLayer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handleDamageDestroy(listener: *wl.Listener(*wlr.OutputDamage), _: *wlr.OutputDamage) void {
|
|
||||||
const self = @fieldParentPtr(Self, "damage_destroy", listener);
|
|
||||||
// The wlr.OutputDamage is only destroyed by wlroots when the output is
|
|
||||||
// destroyed and is never destroyed manually by river.
|
|
||||||
self.frame.link.remove();
|
|
||||||
// Ensure that it is safe to call remove() again in handleDestroy()
|
|
||||||
self.frame.link = .{ .prev = &self.frame.link, .next = &self.frame.link };
|
|
||||||
|
|
||||||
self.damage = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handleDestroy(listener: *wl.Listener(*wlr.Output), _: *wlr.Output) void {
|
fn handleDestroy(listener: *wl.Listener(*wlr.Output), _: *wlr.Output) void {
|
||||||
const self = @fieldParentPtr(Self, "destroy", listener);
|
const self = @fieldParentPtr(Self, "destroy", listener);
|
||||||
|
|
||||||
@ -527,9 +511,7 @@ fn handleEnable(listener: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output) vo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handleFrame(listener: *wl.Listener(*wlr.OutputDamage), _: *wlr.OutputDamage) void {
|
fn handleFrame(listener: *wl.Listener(*wlr.Output), _: *wlr.Output) void {
|
||||||
// This function is called every time an output is ready to display a frame,
|
|
||||||
// generally at the output's refresh rate (e.g. 60Hz).
|
|
||||||
const self = @fieldParentPtr(Self, "frame", listener);
|
const self = @fieldParentPtr(Self, "frame", listener);
|
||||||
render.renderOutput(self);
|
render.renderOutput(self);
|
||||||
}
|
}
|
||||||
@ -552,7 +534,6 @@ fn handlePresent(
|
|||||||
.pending_blank, .pending_lock_surface => {
|
.pending_blank, .pending_lock_surface => {
|
||||||
if (!event.presented) {
|
if (!event.presented) {
|
||||||
self.lock_render_state = .unlocked;
|
self.lock_render_state = .unlocked;
|
||||||
self.damage.?.addWhole();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,8 +91,6 @@ pub fn init(self: *Self) !void {
|
|||||||
.transaction_timer = transaction_timer,
|
.transaction_timer = transaction_timer,
|
||||||
.noop_output = .{
|
.noop_output = .{
|
||||||
.wlr_output = noop_wlr_output,
|
.wlr_output = noop_wlr_output,
|
||||||
// TODO: find a good way to not create a wlr.OutputDamage for the noop output
|
|
||||||
.damage = try wlr.OutputDamage.create(noop_wlr_output),
|
|
||||||
.usable_box = .{ .x = 0, .y = 0, .width = 0, .height = 0 },
|
.usable_box = .{ .x = 0, .y = 0, .width = 0, .height = 0 },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -390,8 +388,6 @@ fn commitTransaction(self: *Self) void {
|
|||||||
|
|
||||||
if (view_tags_changed) output.sendViewTags();
|
if (view_tags_changed) output.sendViewTags();
|
||||||
if (urgent_tags_dirty) output.sendUrgentTags();
|
if (urgent_tags_dirty) output.sendUrgentTags();
|
||||||
|
|
||||||
output.damage.?.addWhole();
|
|
||||||
}
|
}
|
||||||
server.input_manager.updateCursorState();
|
server.input_manager.updateCursorState();
|
||||||
server.idle_inhibitor_manager.idleInhibitCheckActive();
|
server.idle_inhibitor_manager.idleInhibitCheckActive();
|
||||||
|
@ -1,160 +0,0 @@
|
|||||||
// This file is part of river, a dynamic tiling wayland compositor.
|
|
||||||
//
|
|
||||||
// Copyright 2021 The River Developers
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, version 3.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
const Subsurface = @This();
|
|
||||||
|
|
||||||
const std = @import("std");
|
|
||||||
const assert = std.debug.assert;
|
|
||||||
const wlr = @import("wlroots");
|
|
||||||
const wl = @import("wayland").server.wl;
|
|
||||||
|
|
||||||
const server = &@import("main.zig").server;
|
|
||||||
const util = @import("util.zig");
|
|
||||||
|
|
||||||
const DragIcon = @import("DragIcon.zig");
|
|
||||||
const LayerSurface = @import("LayerSurface.zig");
|
|
||||||
const LockSurface = @import("LockSurface.zig");
|
|
||||||
const XdgToplevel = @import("XdgToplevel.zig");
|
|
||||||
|
|
||||||
pub const Parent = union(enum) {
|
|
||||||
xdg_toplevel: *XdgToplevel,
|
|
||||||
layer_surface: *LayerSurface,
|
|
||||||
lock_surface: *LockSurface,
|
|
||||||
drag_icon: *DragIcon,
|
|
||||||
|
|
||||||
pub fn damageWholeOutput(parent: Parent) void {
|
|
||||||
switch (parent) {
|
|
||||||
.xdg_toplevel => |xdg_toplevel| xdg_toplevel.view.output.damage.?.addWhole(),
|
|
||||||
.layer_surface => |layer_surface| layer_surface.output.damage.?.addWhole(),
|
|
||||||
.lock_surface => |lock_surface| lock_surface.output().damage.?.addWhole(),
|
|
||||||
.drag_icon => |_| {
|
|
||||||
var it = server.root.outputs.first;
|
|
||||||
while (it) |node| : (it = node.next) node.data.damage.?.addWhole();
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/// The parent at the root of this surface tree
|
|
||||||
parent: Parent,
|
|
||||||
wlr_subsurface: *wlr.Subsurface,
|
|
||||||
|
|
||||||
// Always active
|
|
||||||
subsurface_destroy: wl.Listener(*wlr.Subsurface) = wl.Listener(*wlr.Subsurface).init(handleDestroy),
|
|
||||||
map: wl.Listener(*wlr.Subsurface) = wl.Listener(*wlr.Subsurface).init(handleMap),
|
|
||||||
unmap: wl.Listener(*wlr.Subsurface) = wl.Listener(*wlr.Subsurface).init(handleUnmap),
|
|
||||||
new_subsurface: wl.Listener(*wlr.Subsurface) = wl.Listener(*wlr.Subsurface).init(handleNewSubsurface),
|
|
||||||
|
|
||||||
// Only active while mapped
|
|
||||||
commit: wl.Listener(*wlr.Surface) = wl.Listener(*wlr.Surface).init(handleCommit),
|
|
||||||
|
|
||||||
pub fn create(wlr_subsurface: *wlr.Subsurface, parent: Parent) void {
|
|
||||||
const subsurface = util.gpa.create(Subsurface) catch {
|
|
||||||
std.log.err("out of memory", .{});
|
|
||||||
wlr_subsurface.resource.getClient().postNoMemory();
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
subsurface.* = .{ .wlr_subsurface = wlr_subsurface, .parent = parent };
|
|
||||||
assert(wlr_subsurface.data == 0);
|
|
||||||
wlr_subsurface.data = @ptrToInt(subsurface);
|
|
||||||
|
|
||||||
wlr_subsurface.events.destroy.add(&subsurface.subsurface_destroy);
|
|
||||||
wlr_subsurface.events.map.add(&subsurface.map);
|
|
||||||
wlr_subsurface.events.unmap.add(&subsurface.unmap);
|
|
||||||
wlr_subsurface.surface.events.new_subsurface.add(&subsurface.new_subsurface);
|
|
||||||
|
|
||||||
if (wlr_subsurface.mapped) wlr_subsurface.surface.events.commit.add(&subsurface.commit);
|
|
||||||
|
|
||||||
Subsurface.handleExisting(wlr_subsurface.surface, parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create Subsurface structs to track subsurfaces already present on the
|
|
||||||
/// given surface when river becomes aware of the surface as we won't
|
|
||||||
/// recieve a new_subsurface event for them.
|
|
||||||
pub fn handleExisting(surface: *wlr.Surface, parent: Parent) void {
|
|
||||||
var below_it = surface.current.subsurfaces_below.iterator(.forward);
|
|
||||||
while (below_it.next()) |parent_state| {
|
|
||||||
const subsurface = @fieldParentPtr(wlr.Subsurface, "current", parent_state);
|
|
||||||
Subsurface.create(subsurface, parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
var above_it = surface.current.subsurfaces_above.iterator(.forward);
|
|
||||||
while (above_it.next()) |parent_state| {
|
|
||||||
const subsurface = @fieldParentPtr(wlr.Subsurface, "current", parent_state);
|
|
||||||
Subsurface.create(subsurface, parent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Destroy this Subsurface and all of its children
|
|
||||||
pub fn destroy(subsurface: *Subsurface) void {
|
|
||||||
subsurface.subsurface_destroy.link.remove();
|
|
||||||
subsurface.map.link.remove();
|
|
||||||
subsurface.unmap.link.remove();
|
|
||||||
subsurface.new_subsurface.link.remove();
|
|
||||||
|
|
||||||
if (subsurface.wlr_subsurface.mapped) subsurface.commit.link.remove();
|
|
||||||
|
|
||||||
Subsurface.destroySubsurfaces(subsurface.wlr_subsurface.surface);
|
|
||||||
|
|
||||||
subsurface.wlr_subsurface.data = 0;
|
|
||||||
util.gpa.destroy(subsurface);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn destroySubsurfaces(surface: *wlr.Surface) void {
|
|
||||||
var below_it = surface.current.subsurfaces_below.iterator(.forward);
|
|
||||||
while (below_it.next()) |parent_state| {
|
|
||||||
const wlr_subsurface = @fieldParentPtr(wlr.Subsurface, "current", parent_state);
|
|
||||||
if (@intToPtr(?*Subsurface, wlr_subsurface.data)) |s| s.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
var above_it = surface.current.subsurfaces_above.iterator(.forward);
|
|
||||||
while (above_it.next()) |parent_state| {
|
|
||||||
const wlr_subsurface = @fieldParentPtr(wlr.Subsurface, "current", parent_state);
|
|
||||||
if (@intToPtr(?*Subsurface, wlr_subsurface.data)) |s| s.destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handleDestroy(listener: *wl.Listener(*wlr.Subsurface), _: *wlr.Subsurface) void {
|
|
||||||
const subsurface = @fieldParentPtr(Subsurface, "subsurface_destroy", listener);
|
|
||||||
|
|
||||||
subsurface.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handleMap(listener: *wl.Listener(*wlr.Subsurface), wlr_subsurface: *wlr.Subsurface) void {
|
|
||||||
const subsurface = @fieldParentPtr(Subsurface, "map", listener);
|
|
||||||
|
|
||||||
wlr_subsurface.surface.events.commit.add(&subsurface.commit);
|
|
||||||
subsurface.parent.damageWholeOutput();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handleUnmap(listener: *wl.Listener(*wlr.Subsurface), _: *wlr.Subsurface) void {
|
|
||||||
const subsurface = @fieldParentPtr(Subsurface, "unmap", listener);
|
|
||||||
|
|
||||||
subsurface.commit.link.remove();
|
|
||||||
subsurface.parent.damageWholeOutput();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handleCommit(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void {
|
|
||||||
const subsurface = @fieldParentPtr(Subsurface, "commit", listener);
|
|
||||||
|
|
||||||
subsurface.parent.damageWholeOutput();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handleNewSubsurface(listener: *wl.Listener(*wlr.Subsurface), new_wlr_subsurface: *wlr.Subsurface) void {
|
|
||||||
const subsurface = @fieldParentPtr(Subsurface, "new_subsurface", listener);
|
|
||||||
|
|
||||||
Subsurface.create(new_wlr_subsurface, subsurface.parent);
|
|
||||||
}
|
|
@ -462,13 +462,6 @@ pub fn fromWlrSurface(surface: *wlr.Surface) ?*Self {
|
|||||||
const xwayland_surface = wlr.XwaylandSurface.fromWlrSurface(surface) orelse return null;
|
const xwayland_surface = wlr.XwaylandSurface.fromWlrSurface(surface) orelse return null;
|
||||||
return @intToPtr(?*Self, xwayland_surface.data);
|
return @intToPtr(?*Self, xwayland_surface.data);
|
||||||
}
|
}
|
||||||
if (surface.isSubsurface()) {
|
|
||||||
if (wlr.Subsurface.fromWlrSurface(surface)) |ss| {
|
|
||||||
if (ss.parent) |s| {
|
|
||||||
return fromWlrSurface(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,149 +0,0 @@
|
|||||||
// This file is part of river, a dynamic tiling wayland compositor.
|
|
||||||
//
|
|
||||||
// Copyright 2020 The River Developers
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, version 3.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
const XdgPopup = @This();
|
|
||||||
|
|
||||||
const std = @import("std");
|
|
||||||
const assert = std.debug.assert;
|
|
||||||
const wlr = @import("wlroots");
|
|
||||||
const wl = @import("wayland").server.wl;
|
|
||||||
|
|
||||||
const util = @import("util.zig");
|
|
||||||
|
|
||||||
const Subsurface = @import("Subsurface.zig");
|
|
||||||
const Parent = Subsurface.Parent;
|
|
||||||
|
|
||||||
/// The parent at the root of this surface tree
|
|
||||||
parent: Parent,
|
|
||||||
wlr_xdg_popup: *wlr.XdgPopup,
|
|
||||||
|
|
||||||
// Always active
|
|
||||||
surface_destroy: wl.Listener(void) = wl.Listener(void).init(handleDestroy),
|
|
||||||
map: wl.Listener(void) = wl.Listener(void).init(handleMap),
|
|
||||||
unmap: wl.Listener(void) = wl.Listener(void).init(handleUnmap),
|
|
||||||
new_popup: wl.Listener(*wlr.XdgPopup) = wl.Listener(*wlr.XdgPopup).init(handleNewPopup),
|
|
||||||
new_subsurface: wl.Listener(*wlr.Subsurface) = wl.Listener(*wlr.Subsurface).init(handleNewSubsurface),
|
|
||||||
|
|
||||||
// Only active while mapped
|
|
||||||
commit: wl.Listener(*wlr.Surface) = wl.Listener(*wlr.Surface).init(handleCommit),
|
|
||||||
|
|
||||||
pub fn create(wlr_xdg_popup: *wlr.XdgPopup, parent: Parent) void {
|
|
||||||
const xdg_popup = util.gpa.create(XdgPopup) catch {
|
|
||||||
std.log.err("out of memory", .{});
|
|
||||||
wlr_xdg_popup.resource.postNoMemory();
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
xdg_popup.* = .{
|
|
||||||
.parent = parent,
|
|
||||||
.wlr_xdg_popup = wlr_xdg_popup,
|
|
||||||
};
|
|
||||||
assert(wlr_xdg_popup.base.data == 0);
|
|
||||||
wlr_xdg_popup.base.data = @ptrToInt(xdg_popup);
|
|
||||||
|
|
||||||
switch (parent) {
|
|
||||||
.xdg_toplevel => |xdg_toplevel| {
|
|
||||||
// The output box relative to the parent of the xdg_popup
|
|
||||||
var box = wlr.Box{
|
|
||||||
.x = xdg_toplevel.view.surface_box.x - xdg_toplevel.view.pending.box.x,
|
|
||||||
.y = xdg_toplevel.view.surface_box.y - xdg_toplevel.view.pending.box.y,
|
|
||||||
.width = undefined,
|
|
||||||
.height = undefined,
|
|
||||||
};
|
|
||||||
xdg_toplevel.view.output.wlr_output.effectiveResolution(&box.width, &box.height);
|
|
||||||
wlr_xdg_popup.unconstrainFromBox(&box);
|
|
||||||
},
|
|
||||||
.layer_surface => |layer_surface| {
|
|
||||||
// The output box relative to the parent of the xdg_popup
|
|
||||||
var box = wlr.Box{
|
|
||||||
.x = -layer_surface.box.x,
|
|
||||||
.y = -layer_surface.box.y,
|
|
||||||
.width = undefined,
|
|
||||||
.height = undefined,
|
|
||||||
};
|
|
||||||
layer_surface.output.wlr_output.effectiveResolution(&box.width, &box.height);
|
|
||||||
wlr_xdg_popup.unconstrainFromBox(&box);
|
|
||||||
},
|
|
||||||
.drag_icon, .lock_surface => unreachable,
|
|
||||||
}
|
|
||||||
|
|
||||||
wlr_xdg_popup.base.events.destroy.add(&xdg_popup.surface_destroy);
|
|
||||||
wlr_xdg_popup.base.events.map.add(&xdg_popup.map);
|
|
||||||
wlr_xdg_popup.base.events.unmap.add(&xdg_popup.unmap);
|
|
||||||
wlr_xdg_popup.base.events.new_popup.add(&xdg_popup.new_popup);
|
|
||||||
wlr_xdg_popup.base.surface.events.new_subsurface.add(&xdg_popup.new_subsurface);
|
|
||||||
|
|
||||||
Subsurface.handleExisting(wlr_xdg_popup.base.surface, parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn destroy(xdg_popup: *XdgPopup) void {
|
|
||||||
xdg_popup.surface_destroy.link.remove();
|
|
||||||
xdg_popup.map.link.remove();
|
|
||||||
xdg_popup.unmap.link.remove();
|
|
||||||
xdg_popup.new_popup.link.remove();
|
|
||||||
xdg_popup.new_subsurface.link.remove();
|
|
||||||
|
|
||||||
if (xdg_popup.wlr_xdg_popup.base.mapped) xdg_popup.commit.link.remove();
|
|
||||||
|
|
||||||
Subsurface.destroySubsurfaces(xdg_popup.wlr_xdg_popup.base.surface);
|
|
||||||
XdgPopup.destroyPopups(xdg_popup.wlr_xdg_popup.base);
|
|
||||||
|
|
||||||
xdg_popup.wlr_xdg_popup.base.data = 0;
|
|
||||||
util.gpa.destroy(xdg_popup);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn destroyPopups(wlr_xdg_surface: *wlr.XdgSurface) void {
|
|
||||||
var it = wlr_xdg_surface.popups.iterator(.forward);
|
|
||||||
while (it.next()) |wlr_xdg_popup| {
|
|
||||||
if (@intToPtr(?*XdgPopup, wlr_xdg_popup.base.data)) |xdg_popup| xdg_popup.destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handleDestroy(listener: *wl.Listener(void)) void {
|
|
||||||
const xdg_popup = @fieldParentPtr(XdgPopup, "surface_destroy", listener);
|
|
||||||
xdg_popup.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handleMap(listener: *wl.Listener(void)) void {
|
|
||||||
const xdg_popup = @fieldParentPtr(XdgPopup, "map", listener);
|
|
||||||
|
|
||||||
xdg_popup.wlr_xdg_popup.base.surface.events.commit.add(&xdg_popup.commit);
|
|
||||||
xdg_popup.parent.damageWholeOutput();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handleUnmap(listener: *wl.Listener(void)) void {
|
|
||||||
const xdg_popup = @fieldParentPtr(XdgPopup, "unmap", listener);
|
|
||||||
|
|
||||||
xdg_popup.commit.link.remove();
|
|
||||||
xdg_popup.parent.damageWholeOutput();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handleCommit(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void {
|
|
||||||
const xdg_popup = @fieldParentPtr(XdgPopup, "commit", listener);
|
|
||||||
|
|
||||||
xdg_popup.parent.damageWholeOutput();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handleNewPopup(listener: *wl.Listener(*wlr.XdgPopup), wlr_xdg_popup: *wlr.XdgPopup) void {
|
|
||||||
const xdg_popup = @fieldParentPtr(XdgPopup, "new_popup", listener);
|
|
||||||
|
|
||||||
XdgPopup.create(wlr_xdg_popup, xdg_popup.parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handleNewSubsurface(listener: *wl.Listener(*wlr.Subsurface), new_wlr_subsurface: *wlr.Subsurface) void {
|
|
||||||
const xdg_popup = @fieldParentPtr(XdgPopup, "new_subsurface", listener);
|
|
||||||
|
|
||||||
Subsurface.create(new_wlr_subsurface, xdg_popup.parent);
|
|
||||||
}
|
|
@ -26,10 +26,8 @@ const util = @import("util.zig");
|
|||||||
|
|
||||||
const Output = @import("Output.zig");
|
const Output = @import("Output.zig");
|
||||||
const Seat = @import("Seat.zig");
|
const Seat = @import("Seat.zig");
|
||||||
const Subsurface = @import("Subsurface.zig");
|
|
||||||
const View = @import("View.zig");
|
const View = @import("View.zig");
|
||||||
const ViewStack = @import("view_stack.zig").ViewStack;
|
const ViewStack = @import("view_stack.zig").ViewStack;
|
||||||
const XdgPopup = @import("XdgPopup.zig");
|
|
||||||
|
|
||||||
const log = std.log.scoped(.xdg_shell);
|
const log = std.log.scoped(.xdg_shell);
|
||||||
|
|
||||||
@ -46,8 +44,6 @@ acked_pending_serial: bool = false,
|
|||||||
destroy: wl.Listener(void) = wl.Listener(void).init(handleDestroy),
|
destroy: wl.Listener(void) = wl.Listener(void).init(handleDestroy),
|
||||||
map: wl.Listener(void) = wl.Listener(void).init(handleMap),
|
map: wl.Listener(void) = wl.Listener(void).init(handleMap),
|
||||||
unmap: wl.Listener(void) = wl.Listener(void).init(handleUnmap),
|
unmap: wl.Listener(void) = wl.Listener(void).init(handleUnmap),
|
||||||
new_popup: wl.Listener(*wlr.XdgPopup) = wl.Listener(*wlr.XdgPopup).init(handleNewPopup),
|
|
||||||
new_subsurface: wl.Listener(*wlr.Subsurface) = wl.Listener(*wlr.Subsurface).init(handleNewSubsurface),
|
|
||||||
|
|
||||||
// Listeners that are only active while the view is mapped
|
// Listeners that are only active while the view is mapped
|
||||||
ack_configure: wl.Listener(*wlr.XdgSurface.Configure) =
|
ack_configure: wl.Listener(*wlr.XdgSurface.Configure) =
|
||||||
@ -78,10 +74,6 @@ pub fn create(output: *Output, xdg_toplevel: *wlr.XdgToplevel) error{OutOfMemory
|
|||||||
xdg_toplevel.base.events.destroy.add(&self.destroy);
|
xdg_toplevel.base.events.destroy.add(&self.destroy);
|
||||||
xdg_toplevel.base.events.map.add(&self.map);
|
xdg_toplevel.base.events.map.add(&self.map);
|
||||||
xdg_toplevel.base.events.unmap.add(&self.unmap);
|
xdg_toplevel.base.events.unmap.add(&self.unmap);
|
||||||
xdg_toplevel.base.events.new_popup.add(&self.new_popup);
|
|
||||||
xdg_toplevel.base.surface.events.new_subsurface.add(&self.new_subsurface);
|
|
||||||
|
|
||||||
Subsurface.handleExisting(xdg_toplevel.base.surface, .{ .xdg_toplevel = self });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if a configure must be sent to ensure that the pending
|
/// Returns true if a configure must be sent to ensure that the pending
|
||||||
@ -164,11 +156,6 @@ fn handleDestroy(listener: *wl.Listener(void)) void {
|
|||||||
self.destroy.link.remove();
|
self.destroy.link.remove();
|
||||||
self.map.link.remove();
|
self.map.link.remove();
|
||||||
self.unmap.link.remove();
|
self.unmap.link.remove();
|
||||||
self.new_popup.link.remove();
|
|
||||||
self.new_subsurface.link.remove();
|
|
||||||
|
|
||||||
Subsurface.destroySubsurfaces(self.xdg_toplevel.base.surface);
|
|
||||||
XdgPopup.destroyPopups(self.xdg_toplevel.base);
|
|
||||||
|
|
||||||
self.view.destroy();
|
self.view.destroy();
|
||||||
}
|
}
|
||||||
@ -296,7 +283,6 @@ fn handleCommit(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void {
|
|||||||
// before some change occured that caused shouldTrackConfigure() to return false.
|
// before some change occured that caused shouldTrackConfigure() to return false.
|
||||||
view.dropSavedBuffers();
|
view.dropSavedBuffers();
|
||||||
|
|
||||||
view.output.damage.?.addWhole();
|
|
||||||
server.input_manager.updateCursorState();
|
server.input_manager.updateCursorState();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -307,7 +293,6 @@ fn handleCommit(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void {
|
|||||||
view.sendFrameDone();
|
view.sendFrameDone();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
view.output.damage.?.addWhole();
|
|
||||||
const size_changed = !std.meta.eql(view.surface_box, new_box);
|
const size_changed = !std.meta.eql(view.surface_box, new_box);
|
||||||
view.surface_box = new_box;
|
view.surface_box = new_box;
|
||||||
// If the client has decided to resize itself and the view is floating,
|
// If the client has decided to resize itself and the view is floating,
|
||||||
@ -320,16 +305,6 @@ fn handleCommit(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handleNewPopup(listener: *wl.Listener(*wlr.XdgPopup), wlr_xdg_popup: *wlr.XdgPopup) void {
|
|
||||||
const self = @fieldParentPtr(Self, "new_popup", listener);
|
|
||||||
XdgPopup.create(wlr_xdg_popup, .{ .xdg_toplevel = self });
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handleNewSubsurface(listener: *wl.Listener(*wlr.Subsurface), new_wlr_subsurface: *wlr.Subsurface) void {
|
|
||||||
const self = @fieldParentPtr(Self, "new_subsurface", listener);
|
|
||||||
Subsurface.create(new_wlr_subsurface, .{ .xdg_toplevel = self });
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Called when the client asks to be fullscreened. We always honor the request
|
/// Called when the client asks to be fullscreened. We always honor the request
|
||||||
/// for now, perhaps it should be denied in some cases in the future.
|
/// for now, perhaps it should be denied in some cases in the future.
|
||||||
fn handleRequestFullscreen(listener: *wl.Listener(void)) void {
|
fn handleRequestFullscreen(listener: *wl.Listener(void)) void {
|
||||||
|
@ -43,9 +43,6 @@ unmap: wl.Listener(*wlr.XwaylandSurface) = wl.Listener(*wlr.XwaylandSurface).ini
|
|||||||
set_override_redirect: wl.Listener(*wlr.XwaylandSurface) =
|
set_override_redirect: wl.Listener(*wlr.XwaylandSurface) =
|
||||||
wl.Listener(*wlr.XwaylandSurface).init(handleSetOverrideRedirect),
|
wl.Listener(*wlr.XwaylandSurface).init(handleSetOverrideRedirect),
|
||||||
|
|
||||||
// Listeners that are only active while mapped
|
|
||||||
commit: wl.Listener(*wlr.Surface) = wl.Listener(*wlr.Surface).init(handleCommit),
|
|
||||||
|
|
||||||
/// The override redirect surface will add itself to the list in Root when it is mapped.
|
/// The override redirect surface will add itself to the list in Root when it is mapped.
|
||||||
pub fn create(xwayland_surface: *wlr.XwaylandSurface) error{OutOfMemory}!*Self {
|
pub fn create(xwayland_surface: *wlr.XwaylandSurface) error{OutOfMemory}!*Self {
|
||||||
const node = try util.gpa.create(std.TailQueue(Self).Node);
|
const node = try util.gpa.create(std.TailQueue(Self).Node);
|
||||||
@ -89,14 +86,12 @@ fn handleDestroy(listener: *wl.Listener(*wlr.XwaylandSurface), _: *wlr.XwaylandS
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Called when the xwayland surface is mapped, or ready to display on-screen.
|
/// Called when the xwayland surface is mapped, or ready to display on-screen.
|
||||||
pub fn handleMap(listener: *wl.Listener(*wlr.XwaylandSurface), xwayland_surface: *wlr.XwaylandSurface) void {
|
pub fn handleMap(listener: *wl.Listener(*wlr.XwaylandSurface), _: *wlr.XwaylandSurface) void {
|
||||||
const self = @fieldParentPtr(Self, "map", listener);
|
const self = @fieldParentPtr(Self, "map", listener);
|
||||||
|
|
||||||
const node = @fieldParentPtr(std.TailQueue(Self).Node, "data", self);
|
const node = @fieldParentPtr(std.TailQueue(Self).Node, "data", self);
|
||||||
server.root.xwayland_override_redirect_views.prepend(node);
|
server.root.xwayland_override_redirect_views.prepend(node);
|
||||||
|
|
||||||
xwayland_surface.surface.?.events.commit.add(&self.commit);
|
|
||||||
|
|
||||||
self.focusIfDesired();
|
self.focusIfDesired();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,8 +124,6 @@ fn handleUnmap(listener: *wl.Listener(*wlr.XwaylandSurface), _: *wlr.XwaylandSur
|
|||||||
const node = @fieldParentPtr(std.TailQueue(Self).Node, "data", self);
|
const node = @fieldParentPtr(std.TailQueue(Self).Node, "data", self);
|
||||||
server.root.xwayland_override_redirect_views.remove(node);
|
server.root.xwayland_override_redirect_views.remove(node);
|
||||||
|
|
||||||
self.commit.link.remove();
|
|
||||||
|
|
||||||
// If the unmapped surface is currently focused, pass keyboard focus
|
// If the unmapped surface is currently focused, pass keyboard focus
|
||||||
// to the most appropriate surface.
|
// to the most appropriate surface.
|
||||||
var seat_it = server.input_manager.seats.first;
|
var seat_it = server.input_manager.seats.first;
|
||||||
@ -151,11 +144,6 @@ fn handleUnmap(listener: *wl.Listener(*wlr.XwaylandSurface), _: *wlr.XwaylandSur
|
|||||||
server.root.startTransaction();
|
server.root.startTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handleCommit(_: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void {
|
|
||||||
var it = server.root.outputs.first;
|
|
||||||
while (it) |node| : (it = node.next) node.data.damage.?.addWhole();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handleSetOverrideRedirect(
|
fn handleSetOverrideRedirect(
|
||||||
listener: *wl.Listener(*wlr.XwaylandSurface),
|
listener: *wl.Listener(*wlr.XwaylandSurface),
|
||||||
xwayland_surface: *wlr.XwaylandSurface,
|
xwayland_surface: *wlr.XwaylandSurface,
|
||||||
|
@ -29,7 +29,6 @@ const util = @import("util.zig");
|
|||||||
const Output = @import("Output.zig");
|
const Output = @import("Output.zig");
|
||||||
const View = @import("View.zig");
|
const View = @import("View.zig");
|
||||||
const ViewStack = @import("view_stack.zig").ViewStack;
|
const ViewStack = @import("view_stack.zig").ViewStack;
|
||||||
const XdgPopup = @import("XdgPopup.zig");
|
|
||||||
const XwaylandOverrideRedirect = @import("XwaylandOverrideRedirect.zig");
|
const XwaylandOverrideRedirect = @import("XwaylandOverrideRedirect.zig");
|
||||||
|
|
||||||
const log = std.log.scoped(.xwayland);
|
const log = std.log.scoped(.xwayland);
|
||||||
@ -297,8 +296,6 @@ fn handleSetOverrideRedirect(
|
|||||||
fn handleCommit(listener: *wl.Listener(*wlr.Surface), surface: *wlr.Surface) void {
|
fn handleCommit(listener: *wl.Listener(*wlr.Surface), surface: *wlr.Surface) void {
|
||||||
const self = @fieldParentPtr(Self, "commit", listener);
|
const self = @fieldParentPtr(Self, "commit", listener);
|
||||||
|
|
||||||
self.view.output.damage.?.addWhole();
|
|
||||||
|
|
||||||
self.view.surface_box = .{
|
self.view.surface_box = .{
|
||||||
.x = 0,
|
.x = 0,
|
||||||
.y = 0,
|
.y = 0,
|
||||||
|
@ -46,9 +46,6 @@ pub fn backgroundColor(
|
|||||||
if (args.len > 2) return Error.TooManyArguments;
|
if (args.len > 2) return Error.TooManyArguments;
|
||||||
|
|
||||||
server.config.background_color = try parseRgba(args[1]);
|
server.config.background_color = try parseRgba(args[1]);
|
||||||
|
|
||||||
var it = server.root.outputs.first;
|
|
||||||
while (it) |node| : (it = node.next) node.data.damage.?.addWhole();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn borderColorFocused(
|
pub fn borderColorFocused(
|
||||||
@ -60,9 +57,6 @@ pub fn borderColorFocused(
|
|||||||
if (args.len > 2) return Error.TooManyArguments;
|
if (args.len > 2) return Error.TooManyArguments;
|
||||||
|
|
||||||
server.config.border_color_focused = try parseRgba(args[1]);
|
server.config.border_color_focused = try parseRgba(args[1]);
|
||||||
|
|
||||||
var it = server.root.outputs.first;
|
|
||||||
while (it) |node| : (it = node.next) node.data.damage.?.addWhole();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn borderColorUnfocused(
|
pub fn borderColorUnfocused(
|
||||||
@ -74,9 +68,6 @@ pub fn borderColorUnfocused(
|
|||||||
if (args.len > 2) return Error.TooManyArguments;
|
if (args.len > 2) return Error.TooManyArguments;
|
||||||
|
|
||||||
server.config.border_color_unfocused = try parseRgba(args[1]);
|
server.config.border_color_unfocused = try parseRgba(args[1]);
|
||||||
|
|
||||||
var it = server.root.outputs.first;
|
|
||||||
while (it) |node| : (it = node.next) node.data.damage.?.addWhole();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn borderColorUrgent(
|
pub fn borderColorUrgent(
|
||||||
@ -88,9 +79,6 @@ pub fn borderColorUrgent(
|
|||||||
if (args.len > 2) return Error.TooManyArguments;
|
if (args.len > 2) return Error.TooManyArguments;
|
||||||
|
|
||||||
server.config.border_color_urgent = try parseRgba(args[1]);
|
server.config.border_color_urgent = try parseRgba(args[1]);
|
||||||
|
|
||||||
var it = server.root.outputs.first;
|
|
||||||
while (it) |node| : (it = node.next) node.data.damage.?.addWhole();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setCursorWarp(
|
pub fn setCursorWarp(
|
||||||
|
@ -47,20 +47,11 @@ pub fn renderOutput(output: *Output) void {
|
|||||||
var now: os.timespec = undefined;
|
var now: os.timespec = undefined;
|
||||||
os.clock_gettime(os.CLOCK.MONOTONIC, &now) catch @panic("CLOCK_MONOTONIC not supported");
|
os.clock_gettime(os.CLOCK.MONOTONIC, &now) catch @panic("CLOCK_MONOTONIC not supported");
|
||||||
|
|
||||||
var needs_frame: bool = undefined;
|
output.wlr_output.attachRender(null) catch {
|
||||||
var damage_region: pixman.Region32 = undefined;
|
|
||||||
damage_region.init();
|
|
||||||
defer damage_region.deinit();
|
|
||||||
output.damage.?.attachRender(&needs_frame, &damage_region) catch {
|
|
||||||
log.err("failed to attach renderer", .{});
|
log.err("failed to attach renderer", .{});
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!needs_frame) {
|
|
||||||
output.wlr_output.rollback();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
server.renderer.begin(@intCast(u32, output.wlr_output.width), @intCast(u32, output.wlr_output.height));
|
server.renderer.begin(@intCast(u32, output.wlr_output.width), @intCast(u32, output.wlr_output.height));
|
||||||
|
|
||||||
// In order to avoid flashing a blank black screen as the session is locked
|
// In order to avoid flashing a blank black screen as the session is locked
|
||||||
|
Loading…
Reference in New Issue
Block a user