From d82b05490052354a1b3575fd145040cbb550b7c1 Mon Sep 17 00:00:00 2001 From: burningserenity Date: Mon, 30 Mar 2026 13:11:27 -0400 Subject: [PATCH] wayland gamma long transition --- ext-clight | 1 + src/modules/gamma.c | 17 +++++++------ src/modules/gamma_plugins/wl.c | 45 +++++++++++++++++++--------------- 3 files changed, 35 insertions(+), 28 deletions(-) create mode 120000 ext-clight diff --git a/ext-clight b/ext-clight new file mode 120000 index 0000000..6051a44 --- /dev/null +++ b/ext-clight @@ -0,0 +1 @@ +/home/burningserenity/.local/src/Clight \ No newline at end of file diff --git a/src/modules/gamma.c b/src/modules/gamma.c index 6bca9de..bb2d5cb 100644 --- a/src/modules/gamma.c +++ b/src/modules/gamma.c @@ -273,6 +273,8 @@ int set_gamma_brightness(const char *id, double brightness) { } double get_gamma_brightness(const char *id) { + if (!gamma_brightness || map_length(gamma_brightness) <= 0) return 1.0; + double *b = map_get(gamma_brightness, id); if (!b) { return 1.0; @@ -425,12 +427,11 @@ static int start_client(gamma_client *cl, int temp, bool is_smooth, unsigned int cl->smooth_step = smooth_step; cl->smooth_wait = smooth_wait; - // NOTE: it seems like on wayland smooth transitions are not working. - // Forcefully disable them for now. - if (cl->plugin == plugins[WL] && cl->is_smooth) { - fprintf(stderr, "Smooth transitions are not supported on wayland.\n"); - cl->is_smooth = false; - } + // If the gamma plugin can't read back the screen temperature (e.g. Wayland on + // first use, before we set it ourselves), current_temp == 0. + // Assume 6500 K (daylight) which matches the actual display state on wayland + // so smooth transitions work from the start. + if (cl->current_temp == 0) cl->current_temp = 6500; if (cl->fd == -1) { cl->fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK); @@ -446,8 +447,8 @@ static int start_client(gamma_client *cl, int temp, bool is_smooth, unsigned int #else -int set_gamma_brightness(const char *id, double brightness) { } +int set_gamma_brightness(const char *id, double brightness) { return 0; } double get_gamma_brightness(const char *id) { return 1.0; } -int clean_gamma_brightness(const char *id) { } +int clean_gamma_brightness(const char *id) { return 0; } #endif diff --git a/src/modules/gamma_plugins/wl.c b/src/modules/gamma_plugins/wl.c index 513cf1a..1b1a333 100644 --- a/src/modules/gamma_plugins/wl.c +++ b/src/modules/gamma_plugins/wl.c @@ -23,6 +23,7 @@ typedef struct { struct wl_registry *registry; struct zwlr_gamma_control_manager_v1 *gamma_control_manager; bool not_first_time; + int current_temp; } wlr_gamma_priv; static int create_gamma_table(uint32_t ramp_size, uint16_t **table); @@ -123,15 +124,17 @@ static int validate(const char **id, const char *env, void **priv_data) { } /* Check if we already have a running client for this display */ - for (stack_itr_t *itr = stack_itr_new(clients); itr; itr = stack_itr_next(itr)) { - wlr_gamma_priv *p = (wlr_gamma_priv *)stack_itr_get_data(itr); - if (p->dpy == display) { - *priv_data = p; - // this is not the first time we use this client. - // No need to register its fd - p->not_first_time = true; - free(itr); - return 0; + if (stack_length(clients) > 0) { + for (stack_itr_t *itr = stack_itr_new(clients); itr; itr = stack_itr_next(itr)) { + wlr_gamma_priv *p = (wlr_gamma_priv *)stack_itr_get_data(itr); + if (p->dpy == display) { + *priv_data = p; + // this is not the first time we use this client. + // No need to register its fd + p->not_first_time = true; + free(itr); + return 0; + } } } @@ -200,36 +203,38 @@ static int set(void *priv_data, const int temp) { output->table_fd); } wl_display_flush(priv->dpy); + priv->current_temp = temp; // Register this fd and listen on events if (!priv->not_first_time) { m_register_fd(wl_display_get_fd(priv->dpy), false, priv); stack_push(clients, priv); + priv->not_first_time = true; } return 0; } static int get(void *priv_data) { - // Unsupported ? - // Ok anyway, just return 0; - // It will be supported one day hopefully - return 0; + wlr_gamma_priv *priv = (wlr_gamma_priv *)priv_data; + return priv->current_temp; } static void dtor(void *priv_data) { if (!leaving) { /* Check if we already have a running client for this display */ - for (stack_itr_t *itr = stack_itr_new(clients); itr; itr = stack_itr_next(itr)) { - wlr_gamma_priv *p = (wlr_gamma_priv *)stack_itr_get_data(itr); - if (p == priv_data) { - // do not remove this client as we need to keep it alive; - free(itr); - return; + if (stack_length(clients) > 0) { + for (stack_itr_t *itr = stack_itr_new(clients); itr; itr = stack_itr_next(itr)) { + wlr_gamma_priv *p = (wlr_gamma_priv *)stack_itr_get_data(itr); + if (p == priv_data) { + // do not remove this client as we need to keep it alive; + free(itr); + return; + } } } } wlr_gamma_priv *priv = (wlr_gamma_priv *)priv_data; - if (priv->dpy) { + if (priv->dpy && priv->not_first_time) { m_deregister_fd(wl_display_get_fd(priv->dpy)); } struct output *output, *tmp_output;