aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/root.zig36
-rw-r--r--src/server.zig7
2 files changed, 38 insertions, 5 deletions
diff --git a/src/root.zig b/src/root.zig
index 4246838..9598f6f 100644
--- a/src/root.zig
+++ b/src/root.zig
@@ -31,6 +31,9 @@ pub const Root = struct {
// A value of 0 means there is no current transaction.
pending_count: u32,
+ /// Handles timeout of transactions
+ transaction_timer: ?*c.wl_event_source,
+
pub fn init(self: *Self, server: *Server) !void {
self.server = server;
@@ -216,7 +219,27 @@ pub const Root = struct {
}
}
- // TODO: start a timer and handle timeout waiting for all clients to ack
+ if (self.pending_count > 0) {
+ // TODO: log failure to create timer and commit immediately
+ self.transaction_timer = c.wl_event_loop_add_timer(
+ self.server.wl_event_loop,
+ handle_timeout,
+ self,
+ );
+ // Set timeout to 200ms
+ if (c.wl_event_source_timer_update(self.transaction_timer, 200) == -1) {
+ // TODO: handle failure
+ }
+ }
+ }
+
+ fn handle_timeout(data: ?*c_void) callconv(.C) c_int {
+ const root = @ptrCast(*Root, @alignCast(@alignOf(*Root), data));
+
+ // TODO: log warning
+ root.commitTransaction();
+
+ return 0;
}
pub fn notifyConfigured(self: *Self) void {
@@ -228,15 +251,20 @@ pub const Root = struct {
/// Apply the pending state and drop stashed buffers. This means that
/// the next frame drawn will be the post-transaction state of the
- /// layout. Must only be called after all clients have configured for
- /// the new layout.
+ /// layout. Should only be called after all clients have configured for
+ /// the new layout. If called early imperfect frames may be drawn.
fn commitTransaction(self: *Self) void {
// TODO: apply damage properly
+
+ // Ensure this is set to 0 to avoid entering invalid state (e.g. if called due to timeout)
+ self.pending_count = 0;
+
var it = self.views.first;
while (it) |node| : (it = node.next) {
const view = &node.data;
- // TODO: handle views that timed out
+ // Ensure that all pending state is cleared
+ view.pending_serial = null;
view.current_state = view.pending_state;
view.dropStashedBuffer();
}
diff --git a/src/server.zig b/src/server.zig
index 266640f..c83c2d8 100644
--- a/src/server.zig
+++ b/src/server.zig
@@ -14,6 +14,7 @@ pub const Server = struct {
allocator: *std.mem.Allocator,
wl_display: *c.wl_display,
+ wl_event_loop: *c.wl_event_loop,
wlr_backend: *c.wlr_backend,
wlr_renderer: *c.wlr_renderer,
@@ -30,11 +31,15 @@ pub const Server = struct {
self.allocator = allocator;
// The Wayland display is managed by libwayland. It handles accepting
- // clients from the Unix socket, manging Wayland globals, and so on.
+ // clients from the Unix socket, managing Wayland globals, and so on.
self.wl_display = c.wl_display_create() orelse
return error.CantCreateWlDisplay;
errdefer c.wl_display_destroy(self.wl_display);
+ // Should never return null if the display was created successfully
+ self.wl_event_loop = c.wl_display_get_event_loop(self.wl_display) orelse
+ return error.CantGetEventLoop;
+
// The wlr_backend abstracts the input/output hardware. Autocreate chooses
// the best option based on the environment, for example DRM when run from
// a tty or wayland if WAYLAND_DISPLAY is set.