From 9080971cc4bbc0c8da1e1f950e914d989490eb6d Mon Sep 17 00:00:00 2001 From: FURK4NGG <105324908+FURK4NGG@users.noreply.github.com> Date: Mon, 19 Jan 2026 15:58:15 +0300 Subject: [PATCH] Update blacklayer.c --- blacklayer.c | 186 +++++++++++++++++++++++++++------------------------ 1 file changed, 99 insertions(+), 87 deletions(-) diff --git a/blacklayer.c b/blacklayer.c index 156ff93..72c7682 100644 --- a/blacklayer.c +++ b/blacklayer.c @@ -1,121 +1,133 @@ #include -#include -#include -#include +#include +#include #include +#include +#include -/* ------------------------------------------------- - * Hyprland monitor name -> ID - * ------------------------------------------------- */ +static GdkPixbufAnimation *anim; +static GdkPixbufAnimationIter *iter; +static int SW, SH; + +/* ---------- draw callback ---------- */ +static gboolean draw_cb(GtkWidget *w, cairo_t *cr, gpointer data) { + GdkPixbuf *frame = gdk_pixbuf_animation_iter_get_pixbuf(iter); + int RW = gdk_pixbuf_get_width(frame); + int RH = gdk_pixbuf_get_height(frame); + + double scale_w = (double)SW / RW; + double scale_h = (double)SH / RH; + double scale = scale_w > scale_h ? scale_w : scale_h; + + int NW = RW * scale; + int NH = RH * scale; + + int x = (SW - NW) / 2; + int y = (SH - NH) / 2; + + cairo_translate(cr, x, y); + cairo_scale(cr, scale, scale); + gdk_cairo_set_source_pixbuf(cr, frame, 0, 0); + cairo_paint(cr); + + return FALSE; +} + +/* ---------- frame timer ---------- */ +static gboolean tick_cb(gpointer data) { + gdk_pixbuf_animation_iter_advance(iter, NULL); + gtk_widget_queue_draw(GTK_WIDGET(data)); + return TRUE; +} + +/* ---------- monitor id ---------- */ static int get_monitor_id(const char *name) { - char cmd[512]; - snprintf( - cmd, - sizeof(cmd), - "hyprctl -j monitors | jq -r '.[] | select(.name==\"%s\") | .id'", - name - ); - + char cmd[256]; + snprintf(cmd, sizeof(cmd), + "hyprctl -j monitors | jq -r '.[] | select(.name==\"%s\") | .id'", name); FILE *fp = popen(cmd, "r"); - if (!fp) - return -1; - + if (!fp) return -1; int id = -1; fscanf(fp, "%d", &id); pclose(fp); - return id; } -/* ------------------------------------------------- - * Read resource from blacklayer.conf - * ------------------------------------------------- */ -static char *get_resource_path(void) { - const char *home = getenv("HOME"); - if (!home) - return NULL; - +/* ---------- resource ---------- */ +static char *get_resource(void) { + static char line[512]; char path[512]; snprintf(path, sizeof(path), - "%s/.config/blacklayer/blacklayer.conf", home); - - FILE *fp = fopen(path, "r"); - if (!fp) - return NULL; - - static char line[1024]; - while (fgets(line, sizeof(line), fp)) { - if (strncmp(line, "resource=", 9) == 0) { - char *res = line + 9; - res[strcspn(res, "\n")] = 0; - fclose(fp); - return (*res) ? res : NULL; + "%s/.config/blacklayer/blacklayer.conf", getenv("HOME")); + FILE *f = fopen(path, "r"); + if (!f) return NULL; + while (fgets(line, sizeof(line), f)) { + if (!strncmp(line, "resource=", 9)) { + char *r = line + 9; + r[strcspn(r, "\n")] = 0; + fclose(f); + return r; } } - - fclose(fp); + fclose(f); return NULL; } int main(int argc, char **argv) { gtk_init(&argc, &argv); - GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_decorated(GTK_WINDOW(window), FALSE); - gtk_window_set_resizable(GTK_WINDOW(window), FALSE); + GtkWidget *win = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_decorated(GTK_WINDOW(win), FALSE); - gtk_layer_init_for_window(GTK_WINDOW(window)); - gtk_layer_set_layer(GTK_WINDOW(window), - GTK_LAYER_SHELL_LAYER_OVERLAY); + gtk_layer_init_for_window(GTK_WINDOW(win)); + gtk_layer_set_layer(GTK_WINDOW(win), GTK_LAYER_SHELL_LAYER_OVERLAY); + gtk_layer_set_anchor(GTK_WINDOW(win), GTK_LAYER_SHELL_EDGE_TOP, TRUE); + gtk_layer_set_anchor(GTK_WINDOW(win), GTK_LAYER_SHELL_EDGE_BOTTOM, TRUE); + gtk_layer_set_anchor(GTK_WINDOW(win), GTK_LAYER_SHELL_EDGE_LEFT, TRUE); + gtk_layer_set_anchor(GTK_WINDOW(win), GTK_LAYER_SHELL_EDGE_RIGHT, TRUE); - gtk_layer_set_anchor(GTK_WINDOW(window), - GTK_LAYER_SHELL_EDGE_TOP, TRUE); - gtk_layer_set_anchor(GTK_WINDOW(window), - GTK_LAYER_SHELL_EDGE_BOTTOM, TRUE); - gtk_layer_set_anchor(GTK_WINDOW(window), - GTK_LAYER_SHELL_EDGE_LEFT, TRUE); - gtk_layer_set_anchor(GTK_WINDOW(window), - GTK_LAYER_SHELL_EDGE_RIGHT, TRUE); - - /* Monitor selection */ + /* monitor */ + GdkRectangle geo = {0}; if (argc > 1) { int id = get_monitor_id(argv[1]); if (id >= 0) { - GdkDisplay *display = gdk_display_get_default(); - GdkMonitor *monitor = - gdk_display_get_monitor(display, id); - if (monitor) - gtk_layer_set_monitor(GTK_WINDOW(window), monitor); + GdkMonitor *m = + gdk_display_get_monitor(gdk_display_get_default(), id); + if (m) { + gtk_layer_set_monitor(GTK_WINDOW(win), m); + gdk_monitor_get_geometry(m, &geo); + } } } - GtkWidget *overlay = gtk_overlay_new(); - gtk_container_add(GTK_CONTAINER(window), overlay); - - char *resource = get_resource_path(); - - if (resource) { - GtkWidget *image = gtk_image_new_from_file(resource); - gtk_widget_set_hexpand(image, TRUE); - gtk_widget_set_vexpand(image, TRUE); - gtk_overlay_add_overlay(GTK_OVERLAY(overlay), image); - } else { - GtkCssProvider *css = gtk_css_provider_new(); - gtk_css_provider_load_from_data( - css, - "window { background-color: black; }", - -1, - NULL - ); - - gtk_style_context_add_provider_for_screen( - gdk_screen_get_default(), - GTK_STYLE_PROVIDER(css), - GTK_STYLE_PROVIDER_PRIORITY_APPLICATION - ); + if (!geo.width) { + GdkScreen *s = gdk_screen_get_default(); + geo.width = gdk_screen_get_width(s); + geo.height = gdk_screen_get_height(s); } - gtk_widget_show_all(window); + SW = geo.width; + SH = geo.height; + + char *res = get_resource(); + if (!res) return 0; + + anim = gdk_pixbuf_animation_new_from_file(res, NULL); + iter = gdk_pixbuf_animation_get_iter(anim, NULL); + + GtkWidget *area = gtk_drawing_area_new(); + gtk_widget_set_size_request(area, SW, SH); + gtk_container_add(GTK_CONTAINER(win), area); + + g_signal_connect(area, "draw", G_CALLBACK(draw_cb), NULL); + + g_timeout_add( + gdk_pixbuf_animation_iter_get_delay_time(iter), + tick_cb, + area + ); + + gtk_widget_show_all(win); gtk_main(); return 0; }