From 61f65a2e24fb7ac9739db934baa6e9fa53641c5f Mon Sep 17 00:00:00 2001 From: Federico Angelilli Date: Sat, 25 Nov 2023 11:11:15 +0100 Subject: Change redraw scheduling and use posix timer in date_update --- src/comet.c | 61 ++++++++++++++++++++++++++++++++++++++++++++----------------- src/draw.c | 15 --------------- src/state.c | 13 +++++++++++++ src/state.h | 2 ++ 4 files changed, 59 insertions(+), 32 deletions(-) diff --git a/src/comet.c b/src/comet.c index a3a9167..98beb74 100644 --- a/src/comet.c +++ b/src/comet.c @@ -1,6 +1,8 @@ #include #include #include +#include +#include #include "window.h" #include "log.h" @@ -16,13 +18,13 @@ static gboolean mainloop_quit(gpointer data) return G_SOURCE_CONTINUE; } -static gboolean mainloop_draw(gpointer data) -{ - State *state = data; - draw_compute_layout(state->draw, state->win, state->btns); - draw_paint(state->draw, state->win); - return G_SOURCE_CONTINUE; -} +//static gboolean mainloop_draw(gpointer data) +//{ +// State *state = data; +// draw_compute_layout(state->draw, state->win, state->btns); +// draw_paint(state->draw, state->win); +// return G_SOURCE_CONTINUE; +//} static void log_handler(const char *log_domain, GLogLevelFlags level, @@ -40,17 +42,34 @@ static void log_handler(const char *log_domain, g_print("%s\n", message); } -static gboolean date_update(gpointer data) +typedef struct { + State *state; + Button *btn; + timer_t timer; +} Date_Handler; + +static gboolean date_update(Date_Handler *date_ctx) { - Button *btn = data; - g_free(btn->text); + g_free(date_ctx->btn->text); GDateTime *time = g_date_time_new_now_local(); - btn->text = g_date_time_format(time, "%A %d %H:%M"); - g_assert(btn->text != NULL); + char *date = g_date_time_format(time, "%A %d %H:%M"); + g_assert(date != NULL); + date_ctx->btn->text = date; + log_debug("Updated date"); + state_redraw(date_ctx->state); + + struct timespec current; + clock_gettime(CLOCK_REALTIME, ¤t); + + struct itimerspec its = { 0 }; + its.it_value.tv_sec = 60 - (current.tv_sec % 60); + timer_settime(date_ctx->timer, 0, &its, NULL); + return G_SOURCE_CONTINUE; } + static void show_action(Button *btn) { log_info("Called action: %s", btn->text); @@ -109,8 +128,13 @@ int main(int argc, char **argv) button_set_action(date_btn, show_action, NULL); state_add_button(state, date_btn); - date_update(date_btn); - g_timeout_add(30 * 1000, date_update, date_btn); + struct sigevent sev = { 0 }; + sev.sigev_notify = SIGEV_SIGNAL; + sev.sigev_signo = SIGUSR1; + + Date_Handler date_ctx = { state, date_btn, 0 }; + g_assert(timer_create(CLOCK_REALTIME, &sev, &date_ctx.timer) == 0); + date_update(&date_ctx); // purple Color background2 = { 0.502, 0.168, 0.886, 1 }; @@ -119,16 +143,16 @@ int main(int argc, char **argv) button_set_action(q_btn, quit_action, mainloop); state_add_button(state, q_btn); - draw_compute_layout(draw, win, state->btns); - connect_attach_state(con, state); connect_attach_source(con); + guint source_alrm = g_unix_signal_add(SIGUSR1, (void *)date_update, &date_ctx); guint source_term = g_unix_signal_add(SIGTERM, mainloop_quit, mainloop); guint source_int = g_unix_signal_add(SIGINT, mainloop_quit, mainloop); // TODO: Redraw only when needed (dirty flag) - guint id = g_timeout_add(1000, mainloop_draw, state); + //guint id = g_timeout_add(1000, mainloop_draw, state); + state_redraw(state); log_debug("Starting main loop"); g_main_loop_run(mainloop); @@ -136,9 +160,12 @@ int main(int argc, char **argv) log_debug("Cleaning main loop"); g_clear_pointer(&mainloop, g_main_loop_unref); + g_source_remove(source_alrm); g_source_remove(source_term); g_source_remove(source_int); + timer_delete(date_ctx.timer); + state_destroy(state); draw_destroy(draw); window_destroy(win); diff --git a/src/draw.c b/src/draw.c index 9328bed..42c22bd 100644 --- a/src/draw.c +++ b/src/draw.c @@ -8,10 +8,6 @@ #include "button.h" #include "log.h" -// Idea: Either make a to_draw queue where we put things we schedule to redraw -// (this will also work for animations in the future) -// or use some flags to trigger drawing - static void layout_destroy(Layout *layout) { g_object_unref(layout->pl); @@ -118,13 +114,6 @@ void draw_paint(Drawable *draw, Window *win) pango_cairo_show_layout(cr, layout->pl); } - // Draw midpoint line - //cairo_set_source_rgba(cr, 1, 1, 1, 1); - //cairo_set_line_width(cr, 3); - //cairo_move_to(cr, width / 2, 0); - //cairo_line_to(cr, width / 2, height); - //cairo_stroke(cr); - cairo_destroy(cr); // TODO: Move these somewhere else @@ -230,10 +219,6 @@ void draw_compute_layout(Drawable *draw, Window *win, GList *btns) MAX(end_xs[1], end_xs[0]), }; - log_info("e1 = %d, e2 = %d, e3 = %d", end_xs[0], end_xs[1], end_xs[2]); - log_info("s1 = %d, s2 = %d, s3 = %d", start_xs[0], start_xs[1], start_xs[2]); - log_info("w1 = %d, w2 = %d, w3 = %d", widths[0], widths[1], widths[2]); - int center = round(width / 2); int center_off = (center - widths[1] / 2) - start_xs[1]; log_debug("Aligning center layout [x=%d, off=%d]", center, center_off); diff --git a/src/state.c b/src/state.c index c2f2a4a..64c479b 100644 --- a/src/state.c +++ b/src/state.c @@ -19,6 +19,19 @@ void state_add_button(State *state, Button *btn) state->btns = g_list_append(state->btns, btn); } +static gboolean redraw(gpointer data) +{ + State *state = data; + draw_compute_layout(state->draw, state->win, state->btns); + draw_paint(state->draw, state->win); + return G_SOURCE_REMOVE; +} + +void state_redraw(State *state) +{ + g_idle_add_full(G_PRIORITY_HIGH_IDLE, redraw, state, NULL); +} + void state_destroy(State *state) { g_list_free_full(state->btns, (void *)button_destroy); diff --git a/src/state.h b/src/state.h index 38cc63f..329b6a3 100644 --- a/src/state.h +++ b/src/state.h @@ -19,6 +19,8 @@ State *state_create(Window *win, Drawable *draw); void state_add_button(State *state, Button *btn); +void state_redraw(State *state); + void state_destroy(State *state); #endif -- cgit v1.2.3