From fb2639a2264a279f20fef2ac385ef1e885026576 Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Sat, 18 Apr 2020 16:21:26 +0200 Subject: [PATCH] Send surface enter/leave events --- src/command/send_to_output.zig | 17 ++++++----------- src/output.zig | 5 ++--- src/view.zig | 16 ++++++++++++++++ 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/command/send_to_output.zig b/src/command/send_to_output.zig index 09ce7ad..b626f93 100644 --- a/src/command/send_to_output.zig +++ b/src/command/send_to_output.zig @@ -4,8 +4,6 @@ const std = @import("std"); const Arg = @import("../command.zig").Arg; const Output = @import("../output.zig").Output; const Seat = @import("../seat.zig").Seat; -const ViewStack = @import("../view_stack.zig").ViewStack; -const View = @import("../view.zig").View; /// Send the focused view to the the next or the previous output, depending on /// the bool passed. Does nothing if there is only one output. @@ -17,23 +15,20 @@ pub fn sendToOutput(seat: *Seat, arg: Arg) void { if (seat.focused_view) |view| { // If the noop output is focused, there is nowhere to send the view - if (seat.focused_output == &root.noop_output) { + if (view.output == &root.noop_output) { std.debug.assert(root.outputs.len == 0); return; } // Send to the next/preg output in the list if there is one, else wrap - const focused_node = @fieldParentPtr(std.TailQueue(Output).Node, "data", seat.focused_output); - const target_output = switch (direction) { - .Next => if (focused_node.next) |node| &node.data else &root.outputs.first.?.data, - .Prev => if (focused_node.prev) |node| &node.data else &root.outputs.last.?.data, + const current_node = @fieldParentPtr(std.TailQueue(Output).Node, "data", view.output); + const destination_output = switch (direction) { + .Next => if (current_node.next) |node| &node.data else &root.outputs.first.?.data, + .Prev => if (current_node.prev) |node| &node.data else &root.outputs.last.?.data, }; // Move the view to the target output - const view_node = @fieldParentPtr(ViewStack(View).Node, "view", view); - seat.focused_output.views.remove(view_node); - target_output.views.push(view_node); - view.output = target_output; + view.sendToOutput(destination_output); // Handle the change and focus whatever's next in the focus stack root.arrange(); diff --git a/src/output.zig b/src/output.zig index bb88156..4baf8a8 100644 --- a/src/output.zig +++ b/src/output.zig @@ -406,9 +406,8 @@ pub const Output = struct { // Move all views from the destroyed output to the fallback one while (destroyed_output.views.last) |node| { - destroyed_output.views.remove(node); - fallback_output.views.push(node); - node.view.output = fallback_output; + const view = &node.view; + view.sendToOutput(fallback_output); } // Close all layer surfaces on the destroyed output diff --git a/src/view.zig b/src/view.zig index ea6fdc0..f805acc 100644 --- a/src/view.zig +++ b/src/view.zig @@ -122,6 +122,20 @@ pub const View = struct { } } + /// Move a view from one output to another, sending the required enter/leave + /// events. + pub fn sendToOutput(self: *Self, destination_output: *Output) void { + const node = @fieldParentPtr(ViewStack(View).Node, "view", self); + + self.output.views.remove(node); + destination_output.views.push(node); + + c.wlr_surface_send_leave(self.wlr_xdg_surface.surface, self.output.wlr_output); + c.wlr_surface_send_enter(self.wlr_xdg_surface.surface, destination_output.wlr_output); + + self.output = destination_output; + } + /// Send a close event to the view's client pub fn close(self: Self) void { // Note: we don't call arrange() here as it will be called @@ -162,6 +176,8 @@ pub const View = struct { seat_node.data.focus(view); } + c.wlr_surface_send_enter(view.wlr_xdg_surface.surface, view.output.wlr_output); + view.output.root.arrange(); }