git.lucas.co / cce-compositor
Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git

commit37f268dc9e4696134358eeed2540fbdb6d2b5919
parenta2d20cf60f
authorIsaac Freund <[email protected]>
date2021-07-23 19:18
cursor: avoid sending unnecessary pointer motion events

If the current Cursor.maybeResetState() function is called while in
passthrough mode, it will send a pointer motion event. This is
unnecessary as we have already sent the same pointer motion event at
least once.

Also refactor the code slightly and improve naming.

 river/Cursor.zig       | 39 ++++++++++++++++++---------------------
 river/InputManager.zig |  4 ++--
 river/Root.zig         |  2 +-
 river/XdgToplevel.zig  |  2 +-
 4 files changed, 22 insertions(+), 25 deletions(-)

diff --git a/river/Cursor.zig b/river/Cursor.zig
index 24896c1..bb94e7a 100644
--- a/river/Cursor.zig
+++ b/river/Cursor.zig
@@ -774,35 +774,32 @@ fn processMotion(self: *Self, device: *wlr.InputDevice, time: u32, delta_x: f64,
 /// Handle potential change in location of views on the output, as well as
 /// the target view of a cursor operation potentially being moved to a non-visible tag,
 /// becoming fullscreen, etc.
-pub fn maybeResetState(self: *Self) void {
+pub fn updateState(self: *Self) void {
+    if (self.shouldExitMode()) {
+        self.mode = .passthrough;
+        var now: os.timespec = undefined;
+        os.clock_gettime(os.CLOCK_MONOTONIC, &now) catch @panic("CLOCK_MONOTONIC not supported");
+        const msec = @intCast(u32, now.tv_sec * std.time.ms_per_s +
+            @divFloor(now.tv_nsec, std.time.ns_per_ms));
+        self.passthrough(msec);
+    }
+}
+
+fn shouldExitMode(self: Self) bool {
     switch (self.mode) {
-        .passthrough => {},
+        .passthrough => return false,
         .down => |target| {
-            // If the target view is no longer visible, abort the operation.
-            if (target.current.tags & target.output.current.tags == 0) {
-                self.mode = .passthrough;
-            }
+            // The target view is no longer visible
+            return target.current.tags & target.output.current.tags == 0;
         },
         .resize, .move => {
-            // If the target view is no longer visible, or now fullscreen or no
-            // longer floating, abort the operation.
             const target = if (self.mode == .resize) self.mode.resize.view else self.mode.move;
-            if (target.current.tags & target.output.current.tags == 0 or
+            // The target view is no longer visible, is part of the layout, or is fullscreen.
+            return target.current.tags & target.output.current.tags == 0 or
                 (!target.current.float and target.output.current.layout != null) or
-                target.current.fullscreen)
-            {
-                self.mode = .passthrough;
-            }
+                target.current.fullscreen;
         },
     }
-
-    if (self.mode == .passthrough) {
-        var now: os.timespec = undefined;
-        os.clock_gettime(os.CLOCK_MONOTONIC, &now) catch @panic("CLOCK_MONOTONIC not supported");
-        const msec = @intCast(u32, now.tv_sec * std.time.ms_per_s +
-            @divFloor(now.tv_nsec, std.time.ns_per_ms));
-        self.passthrough(msec);
-    }
 }
 
 /// Pass an event on to the surface under the cursor, if any.
diff --git a/river/InputManager.zig b/river/InputManager.zig
index 886d86c..2ec46f5 100644
--- a/river/InputManager.zig
+++ b/river/InputManager.zig
@@ -178,9 +178,9 @@ pub fn inputAllowed(self: Self, wlr_surface: *wlr.Surface) bool {
         true;
 }
 
-pub fn maybeResetCursorState(self: Self) void {
+pub fn updateCursorState(self: Self) void {
     var it = self.seats.first;
-    while (it) |node| : (it = node.next) node.data.cursor.maybeResetState();
+    while (it) |node| : (it = node.next) node.data.cursor.updateState();
 }
 
 fn handleInhibitActivate(
diff --git a/river/Root.zig b/river/Root.zig
index 4384159..79e1d49 100644
--- a/river/Root.zig
+++ b/river/Root.zig
@@ -405,7 +405,7 @@ fn commitTransaction(self: *Self) void {
 
         output.damage.addWhole();
     }
-    server.input_manager.maybeResetCursorState();
+    server.input_manager.updateCursorState();
 }
 
 /// Send the new output configuration to all wlr-output-manager clients
diff --git a/river/XdgToplevel.zig b/river/XdgToplevel.zig
index f3cda8c..45bfcc8 100644
--- a/river/XdgToplevel.zig
+++ b/river/XdgToplevel.zig
@@ -273,7 +273,7 @@ fn handleCommit(listener: *wl.Listener(*wlr.Surface), surface: *wlr.Surface) voi
                 view.current = view.pending;
                 if (self_tags_changed) view.output.sendViewTags();
                 view.output.damage.addWhole();
-                server.input_manager.maybeResetCursorState();
+                server.input_manager.updateCursorState();
             }
         } else {
             // If the client has not yet acked our configure, we need to send a