From 168756cbe83c68d931039bd886a37390703cc0ba Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Fri, 27 Jan 2023 19:51:56 +0100 Subject: [PATCH] render: remove damage tracking This will be handled by wlr_scene shortly. --- river/DragIcon.zig | 37 +------ river/LayerSurface.zig | 30 +----- river/LockManager.zig | 10 -- river/LockSurface.zig | 23 ----- river/Output.zig | 25 +---- river/Root.zig | 4 - river/Subsurface.zig | 160 ----------------------------- river/View.zig | 7 -- river/XdgPopup.zig | 149 --------------------------- river/XdgToplevel.zig | 25 ----- river/XwaylandOverrideRedirect.zig | 14 +-- river/XwaylandView.zig | 3 - river/command/config.zig | 12 --- river/render.zig | 11 +- 14 files changed, 7 insertions(+), 503 deletions(-) delete mode 100644 river/Subsurface.zig delete mode 100644 river/XdgPopup.zig diff --git a/river/DragIcon.zig b/river/DragIcon.zig index 7500e62..11683ea 100644 --- a/river/DragIcon.zig +++ b/river/DragIcon.zig @@ -24,7 +24,6 @@ const server = &@import("main.zig").server; const util = @import("util.zig"); const Seat = @import("Seat.zig"); -const Subsurface = @import("Subsurface.zig"); seat: *Seat, wlr_drag_icon: *wlr.Drag.Icon, @@ -35,63 +34,29 @@ sy: i32 = 0, // Always active 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), -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 { drag_icon.* = .{ .seat = seat, .wlr_drag_icon = wlr_drag_icon }; 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.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); drag_icon.seat.drag_icon = null; drag_icon.destroy.link.remove(); - drag_icon.map.link.remove(); - drag_icon.unmap.link.remove(); drag_icon.commit.link.remove(); - drag_icon.new_subsurface.link.remove(); - - Subsurface.destroySubsurfaces(wlr_drag_icon.surface); 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 { const drag_icon = @fieldParentPtr(DragIcon, "commit", listener); drag_icon.sx += surface.current.dx; 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 }); } diff --git a/river/LayerSurface.zig b/river/LayerSurface.zig index 9a56a73..16e50df 100644 --- a/river/LayerSurface.zig +++ b/river/LayerSurface.zig @@ -26,8 +26,6 @@ const server = &@import("main.zig").server; const util = @import("util.zig"); const Output = @import("Output.zig"); -const Subsurface = @import("Subsurface.zig"); -const XdgPopup = @import("XdgPopup.zig"); 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), map: wl.Listener(*wlr.LayerSurfaceV1) = wl.Listener(*wlr.LayerSurfaceV1).init(handleMap), 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), 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.map.add(&self.map); 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.new_subsurface.add(&self.new_subsurface); // wlroots only informs us of the new surface after the first commit, // 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. 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); 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.map.link.remove(); self.unmap.link.remove(); - self.new_popup.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); util.gpa.destroy(node); @@ -163,16 +147,4 @@ fn handleCommit(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void { self.output.arrangeLayers(.mapped); 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 }); } diff --git a/river/LockManager.zig b/river/LockManager.zig index 0c108fc..eab3c4a 100644 --- a/river/LockManager.zig +++ b/river/LockManager.zig @@ -130,16 +130,6 @@ fn handleLockSurfacesTimeout(manager: *LockManager) c_int { assert(manager.state == .waiting_for_lock_surfaces); 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. manager.maybeLock(); diff --git a/river/LockSurface.zig b/river/LockSurface.zig index 2ce8a63..541944f 100644 --- a/river/LockSurface.zig +++ b/river/LockSurface.zig @@ -25,7 +25,6 @@ const util = @import("util.zig"); const Output = @import("Output.zig"); const Seat = @import("Seat.zig"); -const Subsurface = @import("Subsurface.zig"); wlr_lock_surface: *wlr.SessionLockSurfaceV1, lock: *wlr.SessionLockV1, @@ -33,8 +32,6 @@ lock: *wlr.SessionLockV1, output_mode: wl.Listener(*wlr.Output) = wl.Listener(*wlr.Output).init(handleOutputMode), map: wl.Listener(void) = wl.Listener(void).init(handleMap), 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 { 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.events.map.add(&lock_surface.map); 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); - - Subsurface.handleExisting(wlr_lock_surface.surface, .{ .lock_surface = lock_surface }); } pub fn destroy(lock_surface: *LockSurface) void { lock_surface.output().lock_surface = null; - if (lock_surface.output().damage) |damage| damage.addWhole(); { 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.map.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); } @@ -126,14 +114,3 @@ fn handleDestroy(listener: *wl.Listener(void)) void { 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 }); -} diff --git a/river/Output.zig b/river/Output.zig index b654193..0c7b462 100644 --- a/river/Output.zig +++ b/river/Output.zig @@ -55,7 +55,6 @@ const State = struct { }; wlr_output: *wlr.Output, -damage: ?*wlr.OutputDamage, /// All layer surfaces on the output, indexed by the layer enum. 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), enable: wl.Listener(*wlr.Output) = wl.Listener(*wlr.Output).init(handleEnable), 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), -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 { if (!wlr_output.initRender(server.allocator, server.renderer)) return; @@ -146,7 +144,6 @@ pub fn init(self: *Self, wlr_output: *wlr.Output) !void { self.* = .{ .wlr_output = wlr_output, - .damage = try wlr.OutputDamage.create(wlr_output), .usable_box = undefined, }; 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.enable.add(&self.enable); wlr_output.events.mode.add(&self.mode); + wlr_output.events.frame.add(&self.frame); 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 // for each seat. 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 { 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 { - // This function is called every time an output is ready to display a frame, - // generally at the output's refresh rate (e.g. 60Hz). +fn handleFrame(listener: *wl.Listener(*wlr.Output), _: *wlr.Output) void { const self = @fieldParentPtr(Self, "frame", listener); render.renderOutput(self); } @@ -552,7 +534,6 @@ fn handlePresent( .pending_blank, .pending_lock_surface => { if (!event.presented) { self.lock_render_state = .unlocked; - self.damage.?.addWhole(); return; } diff --git a/river/Root.zig b/river/Root.zig index 6418203..b0229ad 100644 --- a/river/Root.zig +++ b/river/Root.zig @@ -91,8 +91,6 @@ pub fn init(self: *Self) !void { .transaction_timer = transaction_timer, .noop_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 }, }, }; @@ -390,8 +388,6 @@ fn commitTransaction(self: *Self) void { if (view_tags_changed) output.sendViewTags(); if (urgent_tags_dirty) output.sendUrgentTags(); - - output.damage.?.addWhole(); } server.input_manager.updateCursorState(); server.idle_inhibitor_manager.idleInhibitCheckActive(); diff --git a/river/Subsurface.zig b/river/Subsurface.zig deleted file mode 100644 index 58b9380..0000000 --- a/river/Subsurface.zig +++ /dev/null @@ -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 . - -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); -} diff --git a/river/View.zig b/river/View.zig index e666265..5993ee3 100644 --- a/river/View.zig +++ b/river/View.zig @@ -462,13 +462,6 @@ pub fn fromWlrSurface(surface: *wlr.Surface) ?*Self { const xwayland_surface = wlr.XwaylandSurface.fromWlrSurface(surface) orelse return null; return @intToPtr(?*Self, xwayland_surface.data); } - if (surface.isSubsurface()) { - if (wlr.Subsurface.fromWlrSurface(surface)) |ss| { - if (ss.parent) |s| { - return fromWlrSurface(s); - } - } - } return null; } diff --git a/river/XdgPopup.zig b/river/XdgPopup.zig deleted file mode 100644 index 3471181..0000000 --- a/river/XdgPopup.zig +++ /dev/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 . - -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); -} diff --git a/river/XdgToplevel.zig b/river/XdgToplevel.zig index 1475464..0e06e1f 100644 --- a/river/XdgToplevel.zig +++ b/river/XdgToplevel.zig @@ -26,10 +26,8 @@ const util = @import("util.zig"); const Output = @import("Output.zig"); const Seat = @import("Seat.zig"); -const Subsurface = @import("Subsurface.zig"); const View = @import("View.zig"); const ViewStack = @import("view_stack.zig").ViewStack; -const XdgPopup = @import("XdgPopup.zig"); 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), 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), // Listeners that are only active while the view is mapped 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.map.add(&self.map); 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 @@ -164,11 +156,6 @@ fn handleDestroy(listener: *wl.Listener(void)) void { self.destroy.link.remove(); self.map.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(); } @@ -296,7 +283,6 @@ fn handleCommit(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void { // before some change occured that caused shouldTrackConfigure() to return false. view.dropSavedBuffers(); - view.output.damage.?.addWhole(); server.input_manager.updateCursorState(); } } else { @@ -307,7 +293,6 @@ fn handleCommit(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void { view.sendFrameDone(); } } else { - view.output.damage.?.addWhole(); const size_changed = !std.meta.eql(view.surface_box, new_box); view.surface_box = new_box; // 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 /// for now, perhaps it should be denied in some cases in the future. fn handleRequestFullscreen(listener: *wl.Listener(void)) void { diff --git a/river/XwaylandOverrideRedirect.zig b/river/XwaylandOverrideRedirect.zig index ad604ba..1da6bf3 100644 --- a/river/XwaylandOverrideRedirect.zig +++ b/river/XwaylandOverrideRedirect.zig @@ -43,9 +43,6 @@ unmap: wl.Listener(*wlr.XwaylandSurface) = wl.Listener(*wlr.XwaylandSurface).ini set_override_redirect: wl.Listener(*wlr.XwaylandSurface) = 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. pub fn create(xwayland_surface: *wlr.XwaylandSurface) error{OutOfMemory}!*Self { 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. -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 node = @fieldParentPtr(std.TailQueue(Self).Node, "data", self); server.root.xwayland_override_redirect_views.prepend(node); - xwayland_surface.surface.?.events.commit.add(&self.commit); - self.focusIfDesired(); } @@ -129,8 +124,6 @@ fn handleUnmap(listener: *wl.Listener(*wlr.XwaylandSurface), _: *wlr.XwaylandSur const node = @fieldParentPtr(std.TailQueue(Self).Node, "data", self); server.root.xwayland_override_redirect_views.remove(node); - self.commit.link.remove(); - // If the unmapped surface is currently focused, pass keyboard focus // to the most appropriate surface. var seat_it = server.input_manager.seats.first; @@ -151,11 +144,6 @@ fn handleUnmap(listener: *wl.Listener(*wlr.XwaylandSurface), _: *wlr.XwaylandSur 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( listener: *wl.Listener(*wlr.XwaylandSurface), xwayland_surface: *wlr.XwaylandSurface, diff --git a/river/XwaylandView.zig b/river/XwaylandView.zig index 0eef7a4..c1be61e 100644 --- a/river/XwaylandView.zig +++ b/river/XwaylandView.zig @@ -29,7 +29,6 @@ const util = @import("util.zig"); const Output = @import("Output.zig"); const View = @import("View.zig"); const ViewStack = @import("view_stack.zig").ViewStack; -const XdgPopup = @import("XdgPopup.zig"); const XwaylandOverrideRedirect = @import("XwaylandOverrideRedirect.zig"); const log = std.log.scoped(.xwayland); @@ -297,8 +296,6 @@ fn handleSetOverrideRedirect( fn handleCommit(listener: *wl.Listener(*wlr.Surface), surface: *wlr.Surface) void { const self = @fieldParentPtr(Self, "commit", listener); - self.view.output.damage.?.addWhole(); - self.view.surface_box = .{ .x = 0, .y = 0, diff --git a/river/command/config.zig b/river/command/config.zig index fc56daa..145743f 100644 --- a/river/command/config.zig +++ b/river/command/config.zig @@ -46,9 +46,6 @@ pub fn backgroundColor( if (args.len > 2) return Error.TooManyArguments; 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( @@ -60,9 +57,6 @@ pub fn borderColorFocused( if (args.len > 2) return Error.TooManyArguments; 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( @@ -74,9 +68,6 @@ pub fn borderColorUnfocused( if (args.len > 2) return Error.TooManyArguments; 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( @@ -88,9 +79,6 @@ pub fn borderColorUrgent( if (args.len > 2) return Error.TooManyArguments; 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( diff --git a/river/render.zig b/river/render.zig index f441ff3..b992e84 100644 --- a/river/render.zig +++ b/river/render.zig @@ -47,20 +47,11 @@ pub fn renderOutput(output: *Output) void { var now: os.timespec = undefined; os.clock_gettime(os.CLOCK.MONOTONIC, &now) catch @panic("CLOCK_MONOTONIC not supported"); - var needs_frame: bool = undefined; - var damage_region: pixman.Region32 = undefined; - damage_region.init(); - defer damage_region.deinit(); - output.damage.?.attachRender(&needs_frame, &damage_region) catch { + output.wlr_output.attachRender(null) catch { log.err("failed to attach renderer", .{}); return; }; - if (!needs_frame) { - output.wlr_output.rollback(); - return; - } - 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