Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
Output: remove wm_stack
river/Cursor.zig | 29 +-----
river/ForeignToplevelHandle.zig | 8 +-
river/InputPopup.zig | 2 +-
river/Output.zig | 35 +------
river/Root.zig | 209 ++++++++--------------------------------
river/View.zig | 101 +++----------------
river/XdgPopup.zig | 2 +-
river/XwaylandView.zig | 20 ++--
8 files changed, 66 insertions(+), 340 deletions(-)
diff --git a/river/Cursor.zig b/river/Cursor.zig
index 6e1778c..10a3327 100644
--- a/river/Cursor.zig
+++ b/river/Cursor.zig
@@ -704,9 +704,6 @@ fn handleRequestSetCursor(
}
pub fn startMove(cursor: *Cursor, view: *View) void {
- // Guard against assertion in enterMode()
- if (view.current.output == null) return;
-
if (cursor.constraint) |constraint| {
if (constraint.state == .active) constraint.deactivate();
}
@@ -720,9 +717,6 @@ pub fn startMove(cursor: *Cursor, view: *View) void {
}
pub fn startResize(cursor: *Cursor, view: *View, proposed_edges: ?wlr.Edges) void {
- // Guard against assertions in computeEdges() and enterMode()
- if (view.current.output == null) return;
-
if (cursor.constraint) |constraint| {
if (constraint.state == .active) constraint.deactivate();
}
@@ -759,11 +753,8 @@ fn computeEdges(cursor: *const Cursor, view: *const View) wlr.Edges {
const min_handle_size = 20;
const box = &view.current.box;
- var output_box: wlr.Box = undefined;
- server.root.output_layout.getBox(view.current.output.?.wlr_output, &output_box);
-
- const sx = @as(i32, @intFromFloat(cursor.wlr_cursor.x)) - output_box.x - box.x;
- const sy = @as(i32, @intFromFloat(cursor.wlr_cursor.y)) - output_box.y - box.y;
+ const sx = @as(i32, @intFromFloat(cursor.wlr_cursor.x)) - box.x;
+ const sy = @as(i32, @intFromFloat(cursor.wlr_cursor.y)) - box.y;
var edges: wlr.Edges = .{};
@@ -878,19 +869,9 @@ fn processMotion(cursor: *Cursor, device: *wlr.InputDevice, time: u32, delta_x:
// based on the dimensions actually committed by the client.
const border_width = if (data.view.pending.ssd) server.config.border_width else 0;
- const output = data.view.current.output orelse {
- data.view.pending.resizing = false;
-
- cursor.mode = .passthrough;
- cursor.passthrough(time);
-
- server.root.applyPending();
- return;
- };
-
- var output_width: i32 = undefined;
- var output_height: i32 = undefined;
- output.wlr_output.effectiveResolution(&output_width, &output_height);
+ // TODO
+ const output_width: i32 = 1920;
+ const output_height: i32 = 1080;
const constraints = &data.view.constraints;
const box = &data.view.pending.box;
diff --git a/river/ForeignToplevelHandle.zig b/river/ForeignToplevelHandle.zig
index a49c8a1..97a1c90 100644
--- a/river/ForeignToplevelHandle.zig
+++ b/river/ForeignToplevelHandle.zig
@@ -71,14 +71,8 @@ pub fn update(handle: *ForeignToplevelHandle) void {
const wlr_handle = handle.wlr_handle orelse return;
- if (view.inflight.output != view.current.output) {
- if (view.current.output) |output| wlr_handle.outputLeave(output.wlr_output);
- if (view.inflight.output) |output| wlr_handle.outputEnter(output.wlr_output);
- }
-
wlr_handle.setActivated(view.inflight.focus != 0);
- wlr_handle.setFullscreen(view.inflight.output != null and
- view.inflight.output.?.inflight.fullscreen == view);
+ wlr_handle.setFullscreen(view.inflight.fullscreen);
}
/// Only honors the request if the view is already visible on the seat's
diff --git a/river/InputPopup.zig b/river/InputPopup.zig
index 0e35753..6503ddf 100644
--- a/river/InputPopup.zig
+++ b/river/InputPopup.zig
@@ -108,7 +108,7 @@ pub fn update(input_popup: *InputPopup) void {
const focused = SceneNodeData.fromSurface(focused_surface) orelse return;
const output = switch (focused.data) {
- .view => |view| view.current.output orelse return,
+ .view => @panic("TODO"),
.layer_surface => |layer_surface| layer_surface.output,
.lock_surface => |lock_surface| lock_surface.getOutput(),
// Xwayland doesn't use the text-input protocol
diff --git a/river/Output.zig b/river/Output.zig
index 4072609..d8994bd 100644
--- a/river/Output.zig
+++ b/river/Output.zig
@@ -38,12 +38,6 @@ const Config = @import("Config.zig");
const log = std.log.scoped(.output);
-pub const PendingState = struct {
- /// The stack of views acted upon by window management commands such
- /// as focus-view, zoom, etc.
- wm_stack: wl.list.Head(View, .pending_wm_stack_link),
-};
-
wlr_output: *wlr.Output,
scene_output: *wlr.SceneOutput,
@@ -108,30 +102,15 @@ lock_render_state: enum {
/// This request is handled while rendering the next frame in handleFrame().
gamma_dirty: bool = false,
-/// The state of the output that is directly acted upon/modified through user input.
-///
-/// Pending state will be copied to the inflight state and communicated to clients
-/// to be applied as a single atomic transaction across all clients as soon as any
-/// in progress transaction has been completed.
-///
-/// Any time pending state is modified Root.applyPending() must be called
-/// before yielding back to the event loop.
-pending: PendingState,
-
/// The state most recently sent to the layout generator and clients.
/// This state is immutable until all clients have replied and the transaction
/// is completed, at which point this inflight state is copied to current.
inflight: struct {
- /// See pending.wm_stack
- wm_stack: wl.list.Head(View, .inflight_wm_stack_link),
/// The view to be made fullscreen, if any.
fullscreen: ?*View = null,
-},
+} = .{},
/// The current state represented by the scene graph.
-/// There is no need to have a current wm_stack copy as this
-/// information is transferred from the inflight state to the scene graph
-/// as an inflight transaction completes.
current: struct {
/// The currently fullscreen view, if any.
fullscreen: ?*View = null,
@@ -221,12 +200,6 @@ pub fn create(wlr_output: *wlr.Output) !void {
.overlay = try normal_content.createSceneTree(),
.popups = try normal_content.createSceneTree(),
},
- .pending = .{
- .wm_stack = undefined,
- },
- .inflight = .{
- .wm_stack = undefined,
- },
.usable_box = .{
.x = 0,
.y = 0,
@@ -236,9 +209,6 @@ pub fn create(wlr_output: *wlr.Output) !void {
};
wlr_output.data = @intFromPtr(output);
- output.pending.wm_stack.init();
- output.inflight.wm_stack.init();
-
_ = try output.layers.fullscreen.createSceneRect(width, height, &[_]f32{ 0, 0, 0, 1.0 });
output.layers.fullscreen.node.setEnabled(false);
@@ -344,9 +314,6 @@ fn handleDestroy(listener: *wl.Listener(*wlr.Output), _: *wlr.Output) void {
// Remove the destroyed output from root if it wasn't already removed
server.root.deactivateOutput(output);
- assert(output.pending.wm_stack.empty());
- assert(output.inflight.wm_stack.empty());
-
output.all_link.remove();
output.destroy.link.remove();
diff --git a/river/Root.zig b/river/Root.zig
index 82e9839..22bd4f3 100644
--- a/river/Root.zig
+++ b/river/Root.zig
@@ -52,28 +52,30 @@ layers: struct {
override_redirect: if (build_options.xwayland) *wlr.SceneTree else void,
},
+wm: struct {
+ pending: struct {
+ render_list: wl.list.Head(View, .pending_render_list_link),
+ },
+
+ inflight: struct {
+ render_list: wl.list.Head(View, .inflight_render_list_link),
+ },
+},
+
/// This is kind of like an imaginary output where views start and end their life.
hidden: struct {
/// This tree is always disabled.
tree: *wlr.SceneTree,
pending: struct {
- wm_stack: wl.list.Head(View, .pending_wm_stack_link),
+ render_list: wl.list.Head(View, .pending_render_list_link),
},
inflight: struct {
- wm_stack: wl.list.Head(View, .inflight_wm_stack_link),
+ render_list: wl.list.Head(View, .inflight_render_list_link),
},
},
-/// This is used to store views when no actual outputs are available.
-/// This must be separate from hidden to ensure we don't mix views that are
-/// in the process of being mapped/unmapped with the mapped views in these lists.
-/// There is no need for inflight lists, instead the inflight links of views are
-/// remove()'d from their current list and init()'d so they may be remove()'d again
-/// when an output becomes available and they are moved to the output's inflight lists.
-fallback_pending: Output.PendingState,
-
views: wl.list.Head(View, .link),
new_output: wl.Listener(*wlr.Output) = wl.Listener(*wlr.Output).init(handleNewOutput),
@@ -139,18 +141,23 @@ pub fn init(root: *Root) !void {
.outputs = outputs,
.override_redirect = override_redirect,
},
+ .wm = .{
+ .pending = .{
+ .render_list = undefined,
+ },
+ .inflight = .{
+ .render_list = undefined,
+ },
+ },
.hidden = .{
.tree = hidden_tree,
.pending = .{
- .wm_stack = undefined,
+ .render_list = undefined,
},
.inflight = .{
- .wm_stack = undefined,
+ .render_list = undefined,
},
},
- .fallback_pending = .{
- .wm_stack = undefined,
- },
.views = undefined,
.output_layout = output_layout,
.all_outputs = undefined,
@@ -163,10 +170,10 @@ pub fn init(root: *Root) !void {
.gamma_control_manager = try wlr.GammaControlManagerV1.create(server.wl_server),
.transaction_timeout = transaction_timeout,
};
- root.hidden.pending.wm_stack.init();
- root.hidden.inflight.wm_stack.init();
-
- root.fallback_pending.wm_stack.init();
+ root.wm.pending.render_list.init();
+ root.wm.inflight.render_list.init();
+ root.hidden.pending.render_list.init();
+ root.hidden.inflight.render_list.init();
root.views.init();
root.all_outputs.init();
@@ -259,47 +266,6 @@ pub fn deactivateOutput(root: *Root, output: *Output) void {
output.active_link.remove();
output.active_link.init();
- {
- var it = output.inflight.wm_stack.safeIterator(.forward);
- while (it.next()) |view| {
- view.inflight.output = null;
- view.current.output = null;
-
- view.tree.node.reparent(root.hidden.tree);
- view.popup_tree.node.reparent(root.hidden.tree);
-
- view.inflight_wm_stack_link.remove();
- view.inflight_wm_stack_link.init();
-
- if (view.inflight_transaction) {
- view.commitTransaction();
- }
-
- // Store outputs connector name so that views can be moved back to
- // reconnecting outputs. Skip if there is already a connector name
- // stored to better handle the case of multiple outputs being
- // removed sequentially.
- if (view.output_before_evac == null) {
- const name = mem.span(output.wlr_output.name);
- view.output_before_evac = util.gpa.dupe(u8, name) catch null;
- }
- }
- }
- // Use the first output in the list as fallback. If the last real output
- // is being removed, store the views in Root.fallback_pending.
- const fallback_output = blk: {
- var it = root.active_outputs.iterator(.forward);
- break :blk it.next();
- };
- if (fallback_output) |fallback| {
- var it = output.pending.wm_stack.safeIterator(.reverse);
- while (it.next()) |view| view.setPendingOutput(fallback);
- } else {
- var it = output.pending.wm_stack.iterator(.forward);
- while (it.next()) |view| view.pending.output = null;
- root.fallback_pending.wm_stack.prependList(&output.pending.wm_stack);
- }
-
// Close all layer surfaces on the removed output
for ([_]zwlr.LayerShellV1.Layer{ .overlay, .top, .bottom, .background }) |layer| {
const tree = output.layerSurfaceTree(layer);
@@ -326,8 +292,6 @@ pub fn activateOutput(root: *Root, output: *Output) void {
while (it.next()) |o| if (o == output) return;
}
- const first = root.active_outputs.empty();
-
root.active_outputs.append(output);
// This arranges outputs from left-to-right in the order they appear. The
@@ -341,35 +305,6 @@ pub fn activateOutput(root: *Root, output: *Output) void {
// possible to handle after updating to 0.17.
@panic("TODO handle allocation failure here");
};
-
- // If we previously had no outputs, move all views to the new output and focus it.
- if (first) {
- const log = std.log.scoped(.output_manager);
- log.debug("moving views from fallback stacks to new output", .{});
-
- {
- var it = root.fallback_pending.wm_stack.safeIterator(.reverse);
- while (it.next()) |view| view.setPendingOutput(output);
- }
- } else {
- // Otherwise check if any views were previously evacuated from an output
- // with the same (connector-)name and move them back.
- var it = root.views.iterator(.forward);
- while (it.next()) |view| {
- const name = view.output_before_evac orelse continue;
- if (mem.eql(u8, name, mem.span(output.wlr_output.name))) {
- if (view.pending.output != output) {
- view.setPendingOutput(output);
- }
- util.gpa.free(name);
- view.output_before_evac = null;
- }
- }
- }
- assert(root.fallback_pending.wm_stack.empty());
-
- // Enforce map-to-output configuration for the newly active output.
- server.input_manager.reconfigureDevices();
}
/// Trigger asynchronous application of pending state for all outputs and views.
@@ -394,45 +329,10 @@ pub fn applyPending(root: *Root) void {
root.pending_state_dirty = false;
{
- var it = root.hidden.pending.wm_stack.iterator(.forward);
+ var it = root.hidden.pending.render_list.iterator(.forward);
while (it.next()) |view| {
- assert(view.pending.output == null);
- view.inflight.output = null;
- view.inflight_wm_stack_link.remove();
- root.hidden.inflight.wm_stack.append(view);
- }
- }
-
- {
- var output_it = root.active_outputs.iterator(.forward);
- while (output_it.next()) |output| {
- // Iterate the focus stack in order to ensure the currently focused/most
- // recently focused view that requests fullscreen is given fullscreen.
- output.inflight.fullscreen = null;
- {
- var it = output.pending.wm_stack.iterator(.forward);
- while (it.next()) |view| {
- assert(view.pending.output == output);
-
- if (!view.current.fullscreen and view.pending.fullscreen) {
- view.post_fullscreen_box = view.pending.box;
- view.pending.box = .{ .x = 0, .y = 0, .width = undefined, .height = undefined };
- output.wlr_output.effectiveResolution(&view.pending.box.width, &view.pending.box.height);
- } else if (view.current.fullscreen and !view.pending.fullscreen) {
- view.pending.box = view.post_fullscreen_box;
- view.pending.clampToOutput();
- }
-
- if (output.inflight.fullscreen == null and view.pending.fullscreen) {
- output.inflight.fullscreen = view;
- }
-
- view.inflight_wm_stack_link.remove();
- output.inflight.wm_stack.append(view);
-
- view.inflight = view.pending;
- }
- }
+ view.inflight_render_list_link.remove();
+ root.hidden.inflight.render_list.append(view);
}
}
@@ -444,9 +344,7 @@ pub fn applyPending(root: *Root) void {
switch (cursor.mode) {
.passthrough, .down => {},
inline .move, .resize => |data| {
- if (data.view.inflight.output == null or
- data.view.inflight.fullscreen)
- {
+ if (data.view.inflight.fullscreen) {
cursor.mode = .passthrough;
data.view.pending.resizing = false;
data.view.inflight.resizing = false;
@@ -464,11 +362,9 @@ pub fn applyPending(root: *Root) void {
fn sendConfigures(root: *Root) void {
assert(root.inflight_configures == 0);
- // Iterate over all views of all outputs
- var output_it = root.active_outputs.iterator(.forward);
- while (output_it.next()) |output| {
- var wm_stack_it = output.inflight.wm_stack.iterator(.forward);
- while (wm_stack_it.next()) |view| {
+ {
+ var it = root.wm.inflight.render_list.iterator(.forward);
+ while (it.next()) |view| {
assert(!view.inflight_transaction);
view.inflight_transaction = true;
@@ -527,49 +423,20 @@ fn commitTransaction(root: *Root) void {
std.log.scoped(.transaction).debug("commiting transaction", .{});
{
- var it = root.hidden.inflight.wm_stack.safeIterator(.forward);
+ var it = root.hidden.inflight.render_list.safeIterator(.forward);
while (it.next()) |view| {
- assert(view.inflight.output == null);
- view.current.output = null;
-
view.tree.node.reparent(root.hidden.tree);
view.popup_tree.node.reparent(root.hidden.tree);
}
}
- var output_it = root.active_outputs.iterator(.forward);
- while (output_it.next()) |output| {
- var wm_stack_it = output.inflight.wm_stack.iterator(.forward);
- while (wm_stack_it.next()) |view| {
- assert(view.inflight.output == output);
-
- if (view.current.output != view.inflight.output or
- (output.current.fullscreen == view and output.inflight.fullscreen != view))
- {
- view.tree.node.reparent(output.layers.wm);
- view.popup_tree.node.reparent(output.layers.popups);
- }
-
- view.tree.node.reparent(output.layers.wm);
-
+ {
+ var it = root.wm.inflight.render_list.iterator(.forward);
+ while (it.next()) |view| {
view.commitTransaction();
view.tree.node.setEnabled(true);
view.popup_tree.node.setEnabled(true);
- if (output.inflight.fullscreen != view) {
- // TODO this approach for syncing the order will likely cause over-damaging.
- view.tree.node.lowerToBottom();
- }
- }
-
- if (output.inflight.fullscreen != output.current.fullscreen) {
- if (output.inflight.fullscreen) |view| {
- assert(view.inflight.output == output);
- assert(view.current.output == output);
- view.tree.node.reparent(output.layers.fullscreen);
- }
- output.current.fullscreen = output.inflight.fullscreen;
- output.layers.fullscreen.node.setEnabled(output.current.fullscreen != null);
}
}
@@ -580,7 +447,7 @@ fn commitTransaction(root: *Root) void {
{
// This must be done after updating cursor state in case the view was the target of move/resize.
- var it = root.hidden.inflight.wm_stack.safeIterator(.forward);
+ var it = root.hidden.inflight.render_list.safeIterator(.forward);
while (it.next()) |view| {
view.dropSavedSurfaceTree();
if (view.destroying) view.destroy(.assert);
diff --git a/river/View.zig b/river/View.zig
index 67d147f..883e059 100644
--- a/river/View.zig
+++ b/river/View.zig
@@ -55,11 +55,6 @@ const Impl = union(enum) {
};
pub const State = struct {
- /// The output the view is currently assigned to.
- /// May be null if there are no outputs or for newly created views.
- /// Must be set using setPendingOutput()
- output: ?*Output = null,
-
/// The output-relative coordinates of the view and dimensions requested by river.
box: wlr.Box = .{ .x = 0, .y = 0, .width = 0, .height = 0 },
@@ -76,11 +71,8 @@ pub const State = struct {
pub fn move(state: *State, delta_x: i32, delta_y: i32) void {
const border_width = if (state.ssd) server.config.border_width else 0;
- var output_width: i32 = math.maxInt(i32);
- var output_height: i32 = math.maxInt(i32);
- if (state.output) |output| {
- output.wlr_output.effectiveResolution(&output_width, &output_height);
- }
+ const output_width = math.maxInt(i32);
+ const output_height = math.maxInt(i32);
const max_x = output_width - state.box.width - border_width;
state.box.x += delta_x;
@@ -142,13 +134,13 @@ destroying: bool = false,
/// Any time pending state is modified Root.applyPending() must be called
/// before yielding back to the event loop.
pending: State = .{},
-pending_wm_stack_link: wl.list.Link,
+pending_render_list_link: wl.list.Link,
/// The state most recently sent to the layout generator and clients.
/// This state is immutable until all clients have replied and the transaction
/// is completed, at which point this inflight state is copied to current.
inflight: State = .{},
-inflight_wm_stack_link: wl.list.Link,
+inflight_render_list_link: wl.list.Link,
/// The current state represented by the scene graph.
current: State = .{},
@@ -192,13 +184,13 @@ pub fn create(impl: Impl) error{OutOfMemory}!*View {
},
.popup_tree = popup_tree,
- .pending_wm_stack_link = undefined,
- .inflight_wm_stack_link = undefined,
+ .pending_render_list_link = undefined,
+ .inflight_render_list_link = undefined,
};
server.root.views.prepend(view);
- server.root.hidden.pending.wm_stack.prepend(view);
- server.root.hidden.inflight.wm_stack.prepend(view);
+ server.root.hidden.pending.render_list.prepend(view);
+ server.root.hidden.inflight.render_list.prepend(view);
view.tree.node.setEnabled(false);
view.popup_tree.node.setEnabled(false);
@@ -227,8 +219,8 @@ pub fn destroy(view: *View, when: enum { lazy, assert }) void {
view.popup_tree.node.destroy();
view.link.remove();
- view.pending_wm_stack_link.remove();
- view.inflight_wm_stack_link.remove();
+ view.pending_render_list_link.remove();
+ view.inflight_render_list_link.remove();
if (view.output_before_evac) |name| util.gpa.free(name);
@@ -354,31 +346,6 @@ pub fn updateSceneState(view: *View) void {
view.tree.node.setPosition(box.x, box.y);
view.popup_tree.node.setPosition(box.x, box.y);
- var output_box: wlr.Box = .{ .x = 0, .y = 0, .width = 0, .height = 0 };
- if (view.current.output) |output| {
- output.wlr_output.effectiveResolution(&output_box.width, &output_box.height);
- }
-
- {
- var surface_clip: wlr.Box = output_box;
-
- // The clip is applied relative to the root node of the subsurface tree.
- surface_clip.x -= box.x;
- surface_clip.y -= box.y;
-
- switch (view.impl) {
- .toplevel => |toplevel| {
- surface_clip.x += toplevel.geometry.x;
- surface_clip.y += toplevel.geometry.y;
- },
- .xwayland_view, .none => {},
- }
-
- if (!view.surface_tree.children.empty()) {
- view.surface_tree.node.subsurfaceTreeSetClip(&surface_clip);
- }
- }
-
{
const config = &server.config;
const border_width: c_int = config.border_width;
@@ -414,12 +381,6 @@ pub fn updateSceneState(view: *View) void {
};
for (&view.borders, &border_boxes) |border, *border_box| {
- border_box.x += box.x;
- border_box.y += box.y;
- _ = border_box.intersection(border_box, &output_box);
- border_box.x -= box.x;
- border_box.y -= box.y;
-
border.node.setEnabled(view.current.ssd and !view.current.fullscreen);
border.node.setPosition(border_box.x, border_box.y);
border.setSize(border_box.width, border_box.height);
@@ -493,18 +454,6 @@ fn saveSurfaceTreeIter(
saved.setTransform(buffer.transform);
}
-pub fn setPendingOutput(view: *View, output: *Output) void {
- view.pending.output = output;
- view.pending_wm_stack_link.remove();
-
- output.pending.wm_stack.prepend(view);
-
- if (view.pending.fullscreen) {
- view.pending.box = .{ .x = 0, .y = 0, .width = undefined, .height = undefined };
- output.wlr_output.effectiveResolution(&view.pending.box.width, &view.pending.box.height);
- }
-}
-
pub fn close(view: View) void {
switch (view.impl) {
.toplevel => |toplevel| toplevel.wlr_toplevel.sendClose(),
@@ -556,31 +505,6 @@ pub fn map(view: *View) !void {
view.foreign_toplevel_handle.map();
- if (true) @panic("TODO");
- const output = undefined;
-
- if (output) |o| {
- // Center the initial pending box on the output
- view.pending.box.x = @divTrunc(@max(0, o.usable_box.width - view.pending.box.width), 2);
- view.pending.box.y = @divTrunc(@max(0, o.usable_box.height - view.pending.box.height), 2);
- }
-
- if (output) |o| {
- view.setPendingOutput(o);
-
- var it = server.input_manager.seats.first;
- while (it) |seat_node| : (it = seat_node.next) seat_node.data.focus(view);
- } else {
- log.debug("no output available for newly mapped view, adding to fallback stacks", .{});
-
- view.pending_wm_stack_link.remove();
-
- server.root.fallback_pending.wm_stack.prepend(view);
-
- view.inflight_wm_stack_link.remove();
- view.inflight_wm_stack_link.init();
- }
-
view.float_box = view.pending.box;
server.root.applyPending();
@@ -593,9 +517,8 @@ pub fn unmap(view: *View) void {
if (!view.saved_surface_tree.node.enabled) view.saveSurfaceTree();
{
- view.pending.output = null;
- view.pending_wm_stack_link.remove();
- server.root.hidden.pending.wm_stack.prepend(view);
+ view.pending_render_list_link.remove();
+ server.root.hidden.pending.render_list.prepend(view);
}
assert(view.mapped and !view.destroying);
diff --git a/river/XdgPopup.zig b/river/XdgPopup.zig
index 3467210..911f8d4 100644
--- a/river/XdgPopup.zig
+++ b/river/XdgPopup.zig
@@ -96,7 +96,7 @@ fn handleReposition(listener: *wl.Listener(void)) void {
const xdg_popup: *XdgPopup = @fieldParentPtr("reposition", listener);
const output = switch (SceneNodeData.fromNode(&xdg_popup.root.node).?.data) {
- .view => |view| view.current.output orelse return,
+ .view => |_| @panic("TODO"),
.layer_surface => |layer_surface| layer_surface.output,
else => unreachable,
};
diff --git a/river/XwaylandView.zig b/river/XwaylandView.zig
index c70d03f..c4e6662 100644
--- a/river/XwaylandView.zig
+++ b/river/XwaylandView.zig
@@ -86,35 +86,29 @@ pub fn create(xwayland_surface: *wlr.XwaylandSurface) error{OutOfMemory}!void {
/// Always returns false as we do not care about frame perfection for Xwayland views.
pub fn configure(xwayland_view: XwaylandView) bool {
- const output = xwayland_view.view.inflight.output orelse return false;
-
- var output_box: wlr.Box = undefined;
- server.root.output_layout.getBox(output.wlr_output, &output_box);
-
const inflight = &xwayland_view.view.inflight;
const current = &xwayland_view.view.current;
- if (xwayland_view.xwayland_surface.x == inflight.box.x + output_box.x and
- xwayland_view.xwayland_surface.y == inflight.box.y + output_box.y and
+ if (xwayland_view.xwayland_surface.x == inflight.box.x and
+ xwayland_view.xwayland_surface.y == inflight.box.y and
xwayland_view.xwayland_surface.width == inflight.box.width and
xwayland_view.xwayland_surface.height == inflight.box.height and
- (inflight.focus != 0) == (current.focus != 0) and
- (output.inflight.fullscreen == xwayland_view.view) ==
- (current.output != null and current.output.?.current.fullscreen == xwayland_view.view))
+ (inflight.focus != 0) == (current.focus != 0))
+ // TODO fullscreen
{
return false;
}
xwayland_view.xwayland_surface.configure(
- math.lossyCast(i16, inflight.box.x + output_box.x),
- math.lossyCast(i16, inflight.box.y + output_box.y),
+ math.lossyCast(i16, inflight.box.x),
+ math.lossyCast(i16, inflight.box.y),
math.lossyCast(u16, inflight.box.width),
math.lossyCast(u16, inflight.box.height),
);
xwayland_view.setActivated(inflight.focus != 0);
- xwayland_view.xwayland_surface.setFullscreen(output.inflight.fullscreen == xwayland_view.view);
+ if (false) xwayland_view.xwayland_surface.setFullscreen();
return false;
}