commit 006b5b56e2366cdee5933cb09411eef814430c05
parent c6023c571894e1eeb9852664cadad0fd935363b2
Author: Michail Konstantinos Dimopoulos <mk@mcdim.xyz>
Date: Tue, 1 Sep 2026 08:15:48 +0300
Multi monitor support & click-based returns
Diffstat:
| M | sxalert.c | | | 109 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------- |
| M | sxalert.h | | | 6 | ++++++ |
2 files changed, 92 insertions(+), 23 deletions(-)
diff --git a/sxalert.c b/sxalert.c
@@ -14,6 +14,7 @@
#include <time.h>
#include <poll.h>
#include <X11/Xft/Xft.h>
+#include <X11/extensions/Xrandr.h>
#include "config.h"
@@ -97,37 +98,74 @@ get_width(Display *dpy, XftFont *font, struct alert *a)
return width;
}
+static int
+find_window(struct xwin *windows, int count, Window id)
+{
+ for (int i = 0; i < count; ++i) {
+ if (windows[i].win == id)
+ return i;
+ }
+
+ return -1;
+}
+
static void
-write_text(Display *dpy, Window w, XftDraw *draw, XftColor color,
- XftFont *font, struct alert *a)
+write_text(Display *dpy, struct xwin *windows, int count,
+ XftColor color, XftFont *font, struct alert *a)
{
while (1) {
- struct pollfd pfd = {
- .fd = ConnectionNumber(dpy),
- .events = POLLIN,
- };
- int pending = XPending(dpy) > 0 || poll(&pfd, 1, a->duration) > 0;
+ struct pollfd pfd = {
+ .fd = ConnectionNumber(dpy),
+ .events = POLLIN,
+ };
+
+ int pending = XPending(dpy) > 0 ||
+ poll(&pfd, 1, a->duration) > 0;
if (!pending)
- break;
-
+ break;
+
XEvent ev;
- XSelectInput(dpy, w, ExposureMask | ButtonPressMask);
XNextEvent(dpy, &ev);
-
+ for (int i = 0; i < count; i++) {
+ XSelectInput(dpy, windows[i].win,
+ ExposureMask | ButtonPressMask);
+ }
+
+ int i = find_window( windows, count, ev.xany.window);
+
+ if (i < 0)
+ continue;
+
if (ev.type == Expose) {
- int spacing = a->text_height * 2;
- for (int i = 0; i < a->lines_len; i++) {
- if (a->lines_len != 0)
- XftDrawStringUtf8(draw, &color, font, a->text_x_padding, spacing, (XftChar8 *)a->lines[i], strlen(a->lines[i]));
- spacing += a->text_height * 2;
+ int spacing = a->text_height * 2;
+
+ for (int line = 0; line < a->lines_len; ++line) {
+ XftDrawStringUtf8( windows[i].draw, &color,
+ font, a->text_x_padding, spacing,
+ (XftChar8 *)a->lines[line],
+ (int)strlen(a->lines[line])
+ );
+
+ spacing += a->text_height * 2;
}
} else if (ev.type == ButtonPress) {
- return;
+ switch (ev.xbutton.button) {
+ case Button1: /* left click */
+ exit(0);
+ break;
+ case Button2: /* middle click */
+ exit(1);
+ break;
+ case Button3: /* right click */
+ exit(3);
+ break;
+ }
}
}
}
+
static void
init_render(Display *dpy, struct xrender *r, struct alert *a)
{
@@ -155,14 +193,19 @@ get_display(void)
}
static void
-init_window(Display *dpy, struct xrender *r, struct xwin *w, struct alert *a)
+init_window(Display *dpy, struct xrender *r, struct xwin *w, struct alert *a,
+ XRRMonitorInfo * monitor)
{
w->width = get_width(dpy, r->font, a);
w->height = a->lines_len * (a->text_height * 2) + a->text_height;
//int count_screens = ScreenCount(dpy);
Screen *screen = ScreenOfDisplay(dpy, 0);
- w->x = screen->width - w->width - a->x_offset;
+ //w->x = screen->width - w->width - a->x_offset;
+ //w->x = screen->height - w->height
+ w->x = monitor->x + monitor->width - w->width - a->x_offset;
+ w->y = monitor->y + a->y_offset;
+
w->win = XCreateSimpleWindow(dpy, RootWindow(dpy, r->scr), w->x,
a->y_offset, w->width, w->height, a->border_width,
@@ -195,12 +238,32 @@ draw(struct alert a)
struct xrender r;
init_render(dpy, &r, &a);
- struct xwin w;
- init_window(dpy, &r, &w, &a);
+/**/
+ struct mon m;
+ m.monitor_count = 1;
+ m.monitors = XRRGetMonitors(dpy, RootWindow(dpy, r.scr), True, &m.monitor_count);
+
+ /* Print monitor info */
+
+ printf("Found %d monitors\n", m.monitor_count);
+ for (int i = 0; i < m.monitor_count; i++) {
+ printf("Monitor %d: x=%d y=%d width=%d height=%d primary=%d\n",
+ i, m.monitors[i].x, m.monitors[i].y, m.monitors[i].width, m.monitors[i].height, m.monitors[i].primary);
+ }
+
+ //Window *windows = calloc(m.monitor_count, sizeof(Window));
+ struct xwin *w = calloc(m.monitor_count, sizeof(struct xwin));
+ if (!w)
+ die("Cannot allocate window array\n", EXIT_FAILURE);
+/**/
+ for (int i = 0; i < m.monitor_count; i++) {
+ init_window(dpy, &r, &w[i], &a, &m.monitors[i]);
+
+ }
- write_text(dpy, w.win, w.draw, r.color, r.font, &a);
+ write_text(dpy, w, m.monitor_count, r.color, r.font, &a);
- cleanup(dpy, &r, &w, &a);
+ //cleanup(dpy, &r, &w, &a); /* TODO */
}
int
diff --git a/sxalert.h b/sxalert.h
@@ -36,8 +36,14 @@ struct xwin {
int width;
int height;
int x;
+ int y;
XftDraw *draw;
Window win;
};
+struct mon {
+ int monitor_count;
+ XRRMonitorInfo *monitors;
+};
+
#endif