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.
This commit is contained in:
Isaac Freund 2021-12-21 03:50:12 +00:00
parent 4d19621f1e
commit f2fc9aca18
No known key found for this signature in database
GPG Key ID: 86DED400DDFD7A11

View File

@ -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");
},
}
}