aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsaac Freund <mail@isaacfreund.com>2021-12-21 03:50:12 +0000
committerIsaac Freund <mail@isaacfreund.com>2021-12-21 03:50:12 +0000
commitf2fc9aca183dc4e724826660b79fe0d7b9103d27 (patch)
tree473122ce8ae3b02a6be486ea6b12cc2daf517e19
parent4d19621f1ecb2f41b4d117ad42a2003b70a31262 (diff)
downloadriver-f2fc9aca183dc4e724826660b79fe0d7b9103d27.tar.gz
river-f2fc9aca183dc4e724826660b79fe0d7b9103d27.tar.xz
Cursor: dedup XcursorManager.setCursorImage() calls
wlroots doesn't avoid re-setting the same cursor image so this is relatively expensive to call repeatedly if nothing has changed.
-rw-r--r--river/Cursor.zig31
1 files changed, 25 insertions, 6 deletions
diff --git a/river/Cursor.zig b/river/Cursor.zig
index 74f586e..be1c459 100644
--- a/river/Cursor.zig
+++ b/river/Cursor.zig
@@ -64,6 +64,13 @@ const Mode = union(enum) {
},
};
+const Image = enum {
+ none,
+ left_ptr,
+ move,
+ @"se-resize",
+};
+
const default_size = 24;
const log = std.log.scoped(.cursor);
@@ -76,6 +83,8 @@ wlr_cursor: *wlr.Cursor,
pointer_gestures: *wlr.PointerGesturesV1,
xcursor_manager: *wlr.XcursorManager,
+image: Image = .none,
+
constraint: ?*wlr.PointerConstraintV1 = null,
/// Number of distinct buttons currently pressed
@@ -204,8 +213,21 @@ pub fn handleViewUnmap(self: *Self, view: *View) void {
}
}
-fn clearFocus(self: Self) void {
- self.xcursor_manager.setCursorImage("left_ptr", self.wlr_cursor);
+/// It seems that setCursorImage is actually fairly expensive to call repeatedly
+/// as it does no checks to see if the the given image is already set. Therefore,
+/// do that check here.
+fn setImage(self: *Self, image: Image) void {
+ if (image == self.image) return;
+ self.image = image;
+
+ // TODO: this is a workaround until updating to zig 0.9.0
+ const image_z = util.gpa.dupeZ(u8, @tagName(image)) catch return;
+ defer util.gpa.free(image_z);
+ self.xcursor_manager.setCursorImage(image_z, self.wlr_cursor);
+}
+
+fn clearFocus(self: *Self) void {
+ self.setImage(.left_ptr);
self.seat.wlr_seat.pointerNotifyClearFocus();
}
@@ -699,10 +721,7 @@ pub fn enterMode(self: *Self, mode: std.meta.Tag((Mode)), view: *View) void {
// Clear cursor focus, so that the surface does not receive events
self.seat.wlr_seat.pointerNotifyClearFocus();
- self.xcursor_manager.setCursorImage(
- if (mode == .move) "move" else "se-resize",
- self.wlr_cursor,
- );
+ self.setImage(if (mode == .move) .move else .@"se-resize");
},
}
}