diff --git a/blacklayer.c b/blacklayer.c index 72c7682..eff8ebd 100644 --- a/blacklayer.c +++ b/blacklayer.c @@ -5,19 +5,39 @@ #include #include +/* ---------- default black color ---------- */ +static const GdkRGBA DEFAULT_COLOR = { 0.0, 0.0, 0.0, 1.0 }; + static GdkPixbufAnimation *anim; static GdkPixbufAnimationIter *iter; static int SW, SH; /* ---------- draw callback ---------- */ static gboolean draw_cb(GtkWidget *w, cairo_t *cr, gpointer data) { + + /* background black */ + cairo_set_source_rgba( + cr, + DEFAULT_COLOR.red, + DEFAULT_COLOR.green, + DEFAULT_COLOR.blue, + DEFAULT_COLOR.alpha + ); + cairo_paint(cr); + + if (!iter) + return FALSE; + GdkPixbuf *frame = gdk_pixbuf_animation_iter_get_pixbuf(iter); + if (!frame) + return FALSE; + 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; + double scale = (scale_w > scale_h) ? scale_w : scale_h; int NW = RW * scale; int NH = RH * scale; @@ -25,16 +45,21 @@ static gboolean draw_cb(GtkWidget *w, cairo_t *cr, gpointer data) { int x = (SW - NW) / 2; int y = (SH - NH) / 2; + cairo_save(cr); cairo_translate(cr, x, y); cairo_scale(cr, scale, scale); gdk_cairo_set_source_pixbuf(cr, frame, 0, 0); cairo_paint(cr); + cairo_restore(cr); return FALSE; } /* ---------- frame timer ---------- */ static gboolean tick_cb(gpointer data) { + if (!iter) + return TRUE; + gdk_pixbuf_animation_iter_advance(iter, NULL); gtk_widget_queue_draw(GTK_WIDGET(data)); return TRUE; @@ -45,8 +70,10 @@ static int get_monitor_id(const char *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; + int id = -1; fscanf(fp, "%d", &id); pclose(fp); @@ -57,16 +84,19 @@ static int get_monitor_id(const char *name) { static char *get_resource(void) { static char line[512]; char path[512]; + snprintf(path, sizeof(path), "%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; + return (*r) ? r : NULL; } } fclose(f); @@ -86,7 +116,7 @@ int main(int argc, char **argv) { 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); - /* monitor */ + /* ---------- monitor ---------- */ GdkRectangle geo = {0}; if (argc > 1) { int id = get_monitor_id(argv[1]); @@ -100,7 +130,7 @@ int main(int argc, char **argv) { } } - if (!geo.width) { + if (!geo.width || !geo.height) { GdkScreen *s = gdk_screen_get_default(); geo.width = gdk_screen_get_width(s); geo.height = gdk_screen_get_height(s); @@ -109,23 +139,27 @@ int main(int argc, char **argv) { 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 - ); + /* ---------- resource load ---------- */ + char *res = get_resource(); + if (res) { + anim = gdk_pixbuf_animation_new_from_file(res, NULL); + if (anim) + iter = gdk_pixbuf_animation_get_iter(anim, NULL); + + if (iter) { + g_timeout_add( + gdk_pixbuf_animation_iter_get_delay_time(iter), + tick_cb, + area + ); + } + } gtk_widget_show_all(win); gtk_main();