Update blacklayer.c

This commit is contained in:
FURK4NGG
2026-01-19 15:58:15 +03:00
committed by GitHub
parent 451057193b
commit 9080971cc4
+99 -87
View File
@@ -1,121 +1,133 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <gtk-layer-shell.h> #include <gtk-layer-shell/gtk-layer-shell.h>
#include <stdio.h> #include <gdk-pixbuf/gdk-pixbuf.h>
#include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <stdio.h>
/* ------------------------------------------------- static GdkPixbufAnimation *anim;
* Hyprland monitor name -> ID 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) { static int get_monitor_id(const char *name) {
char cmd[512]; char cmd[256];
snprintf( snprintf(cmd, sizeof(cmd),
cmd, "hyprctl -j monitors | jq -r '.[] | select(.name==\"%s\") | .id'", name);
sizeof(cmd),
"hyprctl -j monitors | jq -r '.[] | select(.name==\"%s\") | .id'",
name
);
FILE *fp = popen(cmd, "r"); FILE *fp = popen(cmd, "r");
if (!fp) if (!fp) return -1;
return -1;
int id = -1; int id = -1;
fscanf(fp, "%d", &id); fscanf(fp, "%d", &id);
pclose(fp); pclose(fp);
return id; return id;
} }
/* ------------------------------------------------- /* ---------- resource ---------- */
* Read resource from blacklayer.conf static char *get_resource(void) {
* ------------------------------------------------- */ static char line[512];
static char *get_resource_path(void) {
const char *home = getenv("HOME");
if (!home)
return NULL;
char path[512]; char path[512];
snprintf(path, sizeof(path), snprintf(path, sizeof(path),
"%s/.config/blacklayer/blacklayer.conf", home); "%s/.config/blacklayer/blacklayer.conf", getenv("HOME"));
FILE *f = fopen(path, "r");
FILE *fp = fopen(path, "r"); if (!f) return NULL;
if (!fp) while (fgets(line, sizeof(line), f)) {
return NULL; if (!strncmp(line, "resource=", 9)) {
char *r = line + 9;
static char line[1024]; r[strcspn(r, "\n")] = 0;
while (fgets(line, sizeof(line), fp)) { fclose(f);
if (strncmp(line, "resource=", 9) == 0) { return r;
char *res = line + 9;
res[strcspn(res, "\n")] = 0;
fclose(fp);
return (*res) ? res : NULL;
} }
} }
fclose(f);
fclose(fp);
return NULL; return NULL;
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
gtk_init(&argc, &argv); gtk_init(&argc, &argv);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); GtkWidget *win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_decorated(GTK_WINDOW(window), FALSE); gtk_window_set_decorated(GTK_WINDOW(win), FALSE);
gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
gtk_layer_init_for_window(GTK_WINDOW(window)); gtk_layer_init_for_window(GTK_WINDOW(win));
gtk_layer_set_layer(GTK_WINDOW(window), gtk_layer_set_layer(GTK_WINDOW(win), GTK_LAYER_SHELL_LAYER_OVERLAY);
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), /* monitor */
GTK_LAYER_SHELL_EDGE_TOP, TRUE); GdkRectangle geo = {0};
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 */
if (argc > 1) { if (argc > 1) {
int id = get_monitor_id(argv[1]); int id = get_monitor_id(argv[1]);
if (id >= 0) { if (id >= 0) {
GdkDisplay *display = gdk_display_get_default(); GdkMonitor *m =
GdkMonitor *monitor = gdk_display_get_monitor(gdk_display_get_default(), id);
gdk_display_get_monitor(display, id); if (m) {
if (monitor) gtk_layer_set_monitor(GTK_WINDOW(win), m);
gtk_layer_set_monitor(GTK_WINDOW(window), monitor); gdk_monitor_get_geometry(m, &geo);
}
} }
} }
GtkWidget *overlay = gtk_overlay_new(); if (!geo.width) {
gtk_container_add(GTK_CONTAINER(window), overlay); GdkScreen *s = gdk_screen_get_default();
geo.width = gdk_screen_get_width(s);
char *resource = get_resource_path(); geo.height = gdk_screen_get_height(s);
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
);
} }
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(); gtk_main();
return 0; return 0;
} }