Skip to content

Commit 3ee900a

Browse files
committed
fix animation loop delays
1 parent c25c1aa commit 3ee900a

4 files changed

Lines changed: 50 additions & 2 deletions

File tree

examples/cherry-blossom/hyprlax.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ easing = "expo"
1010
mode = "cursor"
1111

1212
[global.parallax.sources]
13-
# Cursor-only parallax; disable workspace influence to avoid jumps on switch.
14-
workspace.weight = 0.0
1513
cursor.weight = 1.0
14+
workspace.weight = 0.01
15+
window.weight = 0.1
1616

1717
[global.parallax.invert.cursor]
1818
x = false

src/core/event_loop.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ int epoll_add_fd(int epfd, int fd, uint32_t events) {
4545
return epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);
4646
}
4747

48+
int epoll_del_fd(int epfd, int fd) {
49+
if (epfd < 0 || fd < 0) return -1;
50+
/* According to epoll_ctl docs, the event pointer is ignored for DEL */
51+
return epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL);
52+
}
53+
4854
void hyprlax_setup_epoll(hyprlax_context_t *ctx) {
4955
if (!ctx) return;
5056
ctx->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
@@ -216,6 +222,9 @@ int hyprlax_run(hyprlax_context_t *ctx) {
216222
}
217223
}
218224
}
225+
/* Ensure input providers (e.g., cursor) update during continuous render
226+
windows (animations), even when we aren't blocking on epoll. */
227+
hyprlax_cursor_tick(ctx);
219228
/* Advance animations before rendering */
220229
hyprlax_update_layers(ctx, current_time);
221230
if (ctx->monitors) {

src/hyprlax_main.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,25 +51,45 @@ static void hyprlax_update_cursor_provider(hyprlax_context_t *ctx) {
5151
(ctx->input.weights[INPUT_CURSOR] > 0.0f);
5252

5353
if (need_cursor) {
54+
bool created = false;
5455
if (ctx->cursor_event_fd < 0) {
5556
ctx->cursor_event_fd = create_timerfd_monotonic();
5657
if (ctx->cursor_event_fd < 0) {
5758
LOG_WARN("Failed to create cursor timerfd");
5859
ctx->cursor_supported = false;
5960
return;
6061
}
62+
created = true;
6163
}
6264

6365
int fps = ctx->config.target_fps > 0 ? ctx->config.target_fps : 60;
6466
int interval_ms = fps > 0 ? (int)(1000.0 / (double)fps) : 16;
6567
arm_timerfd_ms(ctx->cursor_event_fd, interval_ms, interval_ms);
6668
ctx->cursor_supported = true;
69+
70+
/* If epoll is already initialized and this is a new timerfd, register it */
71+
if (created && ctx->epoll_fd >= 0) {
72+
epoll_add_fd(ctx->epoll_fd, ctx->cursor_event_fd, EPOLLIN);
73+
}
74+
75+
/* Ensure an immediate frame to prime input caches after enabling */
76+
if (ctx->frame_timer_fd >= 0) {
77+
arm_timerfd_ms(ctx->frame_timer_fd, 1, 0);
78+
}
6779
} else {
6880
if (ctx->cursor_event_fd >= 0) {
81+
if (ctx->epoll_fd >= 0) {
82+
epoll_del_fd(ctx->epoll_fd, ctx->cursor_event_fd);
83+
}
6984
close(ctx->cursor_event_fd);
7085
ctx->cursor_event_fd = -1;
7186
}
7287
ctx->cursor_supported = false;
88+
89+
/* Kick a frame so renderer applies new weights immediately */
90+
if (ctx->frame_timer_fd >= 0) {
91+
arm_timerfd_ms(ctx->frame_timer_fd, 1, 0);
92+
}
7393
}
7494
}
7595

@@ -319,6 +339,9 @@ int hyprlax_reload_config(hyprlax_context_t *ctx) {
319339
if (rc == HYPRLAX_SUCCESS) {
320340
input_manager_apply_config(&ctx->input, &ctx->config);
321341
hyprlax_update_cursor_provider(ctx);
342+
if (ctx->frame_timer_fd >= 0) {
343+
arm_timerfd_ms(ctx->frame_timer_fd, 1, 0);
344+
}
322345
return HYPRLAX_SUCCESS;
323346
}
324347
return HYPRLAX_ERROR_INVALID_ARGS;
@@ -1501,6 +1524,9 @@ int hyprlax_runtime_set_property(hyprlax_context_t *ctx, const char *property, c
15011524
}
15021525
input_manager_apply_config(&ctx->input, &ctx->config);
15031526
hyprlax_update_cursor_provider(ctx);
1527+
if (ctx->frame_timer_fd >= 0) {
1528+
arm_timerfd_ms(ctx->frame_timer_fd, 1, 0);
1529+
}
15041530
return 0;
15051531
}
15061532
if (strcmp(property, "parallax.input") == 0) {
@@ -1513,6 +1539,9 @@ int hyprlax_runtime_set_property(hyprlax_context_t *ctx, const char *property, c
15131539
input_source_selection_commit(&selection, &ctx->config);
15141540
input_manager_apply_config(&ctx->input, &ctx->config);
15151541
hyprlax_update_cursor_provider(ctx);
1542+
if (ctx->frame_timer_fd >= 0) {
1543+
arm_timerfd_ms(ctx->frame_timer_fd, 1, 0);
1544+
}
15161545
return 0;
15171546
}
15181547
if (strcmp(property, "parallax.sources.cursor.weight") == 0) {
@@ -1521,6 +1550,9 @@ int hyprlax_runtime_set_property(hyprlax_context_t *ctx, const char *property, c
15211550
if (ctx->config.parallax_cursor_weight > 1.0f) ctx->config.parallax_cursor_weight = 1.0f;
15221551
input_manager_apply_config(&ctx->input, &ctx->config);
15231552
hyprlax_update_cursor_provider(ctx);
1553+
if (ctx->frame_timer_fd >= 0) {
1554+
arm_timerfd_ms(ctx->frame_timer_fd, 1, 0);
1555+
}
15241556
return 0;
15251557
}
15261558
if (strcmp(property, "parallax.sources.workspace.weight") == 0) {
@@ -1529,13 +1561,19 @@ int hyprlax_runtime_set_property(hyprlax_context_t *ctx, const char *property, c
15291561
if (ctx->config.parallax_workspace_weight > 1.0f) ctx->config.parallax_workspace_weight = 1.0f;
15301562
input_manager_apply_config(&ctx->input, &ctx->config);
15311563
hyprlax_update_cursor_provider(ctx);
1564+
if (ctx->frame_timer_fd >= 0) {
1565+
arm_timerfd_ms(ctx->frame_timer_fd, 1, 0);
1566+
}
15321567
return 0;
15331568
}
15341569
if (strcmp(property, "parallax.sources.window.weight") == 0) {
15351570
ctx->config.parallax_window_weight = atof(value);
15361571
if (ctx->config.parallax_window_weight < 0.0f) ctx->config.parallax_window_weight = 0.0f;
15371572
if (ctx->config.parallax_window_weight > 1.0f) ctx->config.parallax_window_weight = 1.0f;
15381573
input_manager_apply_config(&ctx->input, &ctx->config);
1574+
if (ctx->frame_timer_fd >= 0) {
1575+
arm_timerfd_ms(ctx->frame_timer_fd, 1, 0);
1576+
}
15391577
return 0;
15401578
}
15411579
if (strcmp(property, "parallax.invert.cursor.x") == 0) {

src/include/hyprlax.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ int create_timerfd_monotonic(void);
154154
void disarm_timerfd(int fd);
155155
void arm_timerfd_ms(int fd, int initial_ms, int interval_ms);
156156
int epoll_add_fd(int epfd, int fd, uint32_t events);
157+
int epoll_del_fd(int epfd, int fd);
157158
void hyprlax_setup_epoll(hyprlax_context_t *ctx);
158159
void hyprlax_arm_frame_timer(hyprlax_context_t *ctx, int fps);
159160
void hyprlax_disarm_frame_timer(hyprlax_context_t *ctx);

0 commit comments

Comments
 (0)