aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--river/InputManager.zig9
-rw-r--r--river/Seat.zig20
-rw-r--r--river/View.zig33
-rw-r--r--river/XdgToplevel.zig5
-rw-r--r--river/XwaylandView.zig5
5 files changed, 31 insertions, 41 deletions
diff --git a/river/InputManager.zig b/river/InputManager.zig
index 2ec46f5..85e4dae 100644
--- a/river/InputManager.zig
+++ b/river/InputManager.zig
@@ -161,15 +161,6 @@ pub fn defaultSeat(self: Self) *Seat {
return &self.seats.first.?.data;
}
-/// Must be called whenever a view is unmapped.
-pub fn handleViewUnmap(self: Self, view: *View) void {
- var it = self.seats.first;
- while (it) |node| : (it = node.next) {
- const seat = &node.data;
- seat.handleViewUnmap(view);
- }
-}
-
/// Returns true if input is currently allowed on the passed surface.
pub fn inputAllowed(self: Self, wlr_surface: *wlr.Surface) bool {
return if (self.exclusive_client) |exclusive_client|
diff --git a/river/Seat.zig b/river/Seat.zig
index 95a5e3f..7b61827 100644
--- a/river/Seat.zig
+++ b/river/Seat.zig
@@ -149,27 +149,22 @@ pub fn focus(self: *Self, _target: ?*View) void {
} else null;
}
+ // Focus the target view or clear the focus if target is null
if (target) |view| {
- // Find or allocate a new node in the focus stack for the target view
+ // Find the node for this view in the focus stack and move it to the top.
var it = self.focus_stack.first;
while (it) |node| : (it = node.next) {
- // If the view is found, move it to the top of the stack
if (node.view == view) {
const new_focus_node = self.focus_stack.remove(node);
self.focus_stack.push(node);
break;
}
} else {
- // The view is not in the stack, so allocate a new node and prepend it
- const new_focus_node = util.gpa.create(ViewStack(*View).Node) catch return;
- new_focus_node.view = view;
- self.focus_stack.push(new_focus_node);
+ // A node is added when new Views are mapped in Seat.handleViewMap()
+ unreachable;
}
-
- // Focus the target view
self.setFocusRaw(.{ .view = view });
} else {
- // Otherwise clear the focus
self.setFocusRaw(.{ .none = {} });
}
}
@@ -288,6 +283,13 @@ pub fn handleActivity(self: Self) void {
server.input_manager.idle.notifyActivity(self.wlr_seat);
}
+pub fn handleViewMap(self: *Self, view: *View) !void {
+ const new_focus_node = try util.gpa.create(ViewStack(*View).Node);
+ new_focus_node.view = view;
+ self.focus_stack.append(new_focus_node);
+ self.focus(view);
+}
+
/// Handle the unmapping of a view, removing it from the focus stack and
/// setting the focus if needed.
pub fn handleViewUnmap(self: *Self, view: *View) void {
diff --git a/river/View.zig b/river/View.zig
index bd5fd13..c3148b2 100644
--- a/river/View.zig
+++ b/river/View.zig
@@ -429,36 +429,30 @@ pub fn shouldTrackConfigure(self: Self) bool {
}
/// Called by the impl when the surface is ready to be displayed
-pub fn map(self: *Self) void {
+pub fn map(self: *Self) !void {
log.debug("view '{s}' mapped", .{self.getTitle()});
if (self.foreign_toplevel_handle == null) {
- self.foreign_toplevel_handle = wlr.ForeignToplevelHandleV1.create(
- server.foreign_toplevel_manager,
- ) catch {
- log.crit("out of memory", .{});
- self.surface.?.resource.getClient().postNoMemory();
- return;
- };
+ const handle = try wlr.ForeignToplevelHandleV1.create(server.foreign_toplevel_manager);
+ self.foreign_toplevel_handle = handle;
- self.foreign_toplevel_handle.?.events.request_activate.add(&self.foreign_activate);
- self.foreign_toplevel_handle.?.events.request_fullscreen.add(&self.foreign_fullscreen);
- self.foreign_toplevel_handle.?.events.request_close.add(&self.foreign_close);
+ handle.events.request_activate.add(&self.foreign_activate);
+ handle.events.request_fullscreen.add(&self.foreign_fullscreen);
+ handle.events.request_close.add(&self.foreign_close);
- if (self.getTitle()) |s| self.foreign_toplevel_handle.?.setTitle(s);
- if (self.getAppId()) |s| self.foreign_toplevel_handle.?.setAppId(s);
+ if (self.getTitle()) |s| handle.setTitle(s);
+ if (self.getAppId()) |s| handle.setAppId(s);
- self.foreign_toplevel_handle.?.outputEnter(self.output.wlr_output);
+ handle.outputEnter(self.output.wlr_output);
}
// Add the view to the stack of its output
const node = @fieldParentPtr(ViewStack(Self).Node, "view", self);
self.output.views.attach(node, server.config.attach_mode);
- // Focus the new view, assuming the seat is focusing the proper output
- // and there isn't something else like a fullscreen view grabbing focus.
+ // Inform all seats that the view has been mapped so they can handle focus
var it = server.input_manager.seats.first;
- while (it) |seat_node| : (it = seat_node.next) seat_node.data.focus(self);
+ while (it) |seat_node| : (it = seat_node.next) try seat_node.data.handleViewMap(self);
self.surface.?.sendEnter(self.output.wlr_output);
@@ -480,10 +474,7 @@ pub fn unmap(self: *Self) void {
// Inform all seats that the view has been unmapped so they can handle focus
var it = server.input_manager.seats.first;
- while (it) |node| : (it = node.next) {
- const seat = &node.data;
- seat.handleViewUnmap(self);
- }
+ while (it) |seat_node| : (it = seat_node.next) seat_node.data.handleViewUnmap(self);
self.output.sendViewTags();
diff --git a/river/XdgToplevel.zig b/river/XdgToplevel.zig
index baddfb8..454ce77 100644
--- a/river/XdgToplevel.zig
+++ b/river/XdgToplevel.zig
@@ -231,7 +231,10 @@ fn handleMap(listener: *wl.Listener(*wlr.XdgSurface), xdg_surface: *wlr.XdgSurfa
_ = toplevel.setTiled(.{ .top = true, .bottom = true, .left = true, .right = true });
}
- view.map();
+ view.map() catch {
+ log.crit("out of memory", .{});
+ xdg_surface.resource.getClient().postNoMemory();
+ };
}
/// Called when the surface is unmapped and will no longer be displayed.
diff --git a/river/XwaylandView.zig b/river/XwaylandView.zig
index b25e689..e467dc2 100644
--- a/river/XwaylandView.zig
+++ b/river/XwaylandView.zig
@@ -207,7 +207,10 @@ fn handleMap(listener: *wl.Listener(*wlr.XwaylandSurface), xwayland_surface: *wl
}
}
- view.map();
+ view.map() catch {
+ std.log.crit("out of memory", .{});
+ surface.resource.getClient().postNoMemory();
+ };
}
/// Called when the surface is unmapped and will no longer be displayed.