commit 2ea859e1c31d6071fd9597628f53439b46b679a4
parent da5b823adc490bc9c91f8acdd3fa5ba624000332
Author: Christos Margiolis <christos@margiolis.net>
Date: Wed, 27 Jan 2021 01:52:12 +0200
added Xrandr(3) support to handle multiple screens, improved padding window sizes
Diffstat:
7 files changed, 77 insertions(+), 42 deletions(-)
diff --git a/LICENSE b/LICENSE
@@ -1,6 +1,6 @@
BSD 3-Clause License
-Copyright (c) 2020-present, Christos Margiolis.
+Copyright (c) 2021-present, Christos Margiolis.
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/Makefile b/Makefile
@@ -1,5 +1,5 @@
# See LICENSE file for copyright and license details.
-# nfy - minimal notification program
+# nfy - a minimal and daemonless notification program for X
.POSIX:
include config.mk
diff --git a/README b/README
@@ -1,16 +1,22 @@
-nfy - a minimal notification program for X
-==========================================
+nfy - a minimal and daemonless notification program for X
+=========================================================
nfy creates a temporary notification popup window and displays
all the arguments that were passed to it.
+Dependencies:
+-------------
+- Xlib
+- libXft
+- libXrandr
+
Usage:
-----
-First of all, edit config.mk and config.h to match your particular
+Edit config.mk and config.h to match your particular
setup and preferences.
$ make
- # make install
- nfy str...
+ # make install clean
+ $ nfy str...
nfy will be installed in /usr/local/bin by default.
Configuration is done by editing config.h and recompiling
diff --git a/config.h b/config.h
@@ -1,11 +1,14 @@
+/* See LICENSE file for copyright and license details. */
enum { TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT }; /* Window positions */
static const char *bgcol = "#453588"; /* Background color */
static const char *bordercol = "#282828"; /* Border color */
static const char *fontcol = "#ebdbb2"; /* Font color */
static const char *fonts = "monospace:size=15"; /* Font */
-static const int borderw = 2; /* Border width */
+static const int padding = 15; /* Padding (pixels) */
+static const int borderw = 2; /* Border width (pixels) */
static const int duration = 3; /* Notification duration (seconds) */
static const int pos = TOP_RIGHT; /* Window position */
-static const int mx = 10; /* Margin X */
-static const int my = 25; /* Margin Y */
+static const int mx = 10; /* Margin X (pixels) */
+static const int my = 25; /* Margin Y (pixels) */
static const int maxlen = 250; /* Max window length (pixels) */
+static const int linespace = 10; /* Line spacing (pixels) */
diff --git a/config.mk b/config.mk
@@ -8,23 +8,23 @@ MAN_DIR = ${PREFIX}/share/man/man1
BIN_DIR = ${PREFIX}/bin
# includes and libs
-#X11INC = /usr/local/include
-#X11LIB = /usr/local/lib
+X11INC = /usr/local/include
+X11LIB = /usr/local/lib
# Linux
-X11INC = /usr/X11R6/include
-X11LIB = /usr/X11R6/lib
+#X11INC = /usr/X11R6/include
+#X11LIB = /usr/X11R6/lib
FREETYPELIBS = -lfontconfig -lXft
-#FREETYPEINC = ${X11INC}/freetype2
+FREETYPEINC = ${X11INC}/freetype2
# Linux
-FREETYPEINC = /usr/include/freetype2
+#FREETYPEINC = /usr/include/freetype2
# flags
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L \
-D_XOPEN_SOURCE=700 -DVERSION=\"${VERSION}\"
CFLAGS = -std=c99 -pedantic -Wall -Os -I${X11INC} -I${FREETYPEINC} ${CPPFLAGS}
-LDFLAGS = -L${X11LIB} ${FREETYPELIBS} -lX11
+LDFLAGS = -L${X11LIB} ${FREETYPELIBS} -lX11 -lXrandr
# utils
CP = cp -f
diff --git a/nfy.1 b/nfy.1
@@ -3,13 +3,30 @@
.Os
.Sh NAME
.Nm nfy
-.Nd a minimal notification program for X
+.Nd a minimal and daemonless notification program for X
.Sh SYNOPSIS
.Nm
.Ar str...
.Sh DESCRIPTION
.Nm
creates a temporary notification popup window and displays
-all the arguments that were passed to it.
+all the arguments that were passed to it. It uses the
+.Xr Xft 3
+library to render fonts and colors, and
+.Xr Xrandr 3
+to handle screen sizes. All configuration is done by
+editing the 'config.h' file in the source code.
+.Sh USAGE
+If the string is not surrounded in quotes,
+.Nm
+will print one line for each word.
+.Sh SIGNALS
+.Nm
+handles only SIGALRM, SIGTERM and SIGINT. It receives a
+SIGALRM signal by default after the specified duration
+of the notification.
+.Sh SEE ALSO
+.Xr signal 3 ,
+.Xr alarm 3
.Sh AUTHORS
.An Christos Margiolis Aq Mt christos@christosmarg.xyz
diff --git a/nfy.c b/nfy.c
@@ -1,3 +1,4 @@
+/* See LICENSE file for copyright and license details. */
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
@@ -7,6 +8,7 @@
#include <X11/Xlib.h>
#include <X11/Xft/Xft.h>
+#include <X11/extensions/Xrandr.h>
#include "config.h"
@@ -51,6 +53,8 @@ main(int argc, char *argv[])
XftColor color;
XftFont *font;
XftDraw *drw;
+ XRRScreenResources *screens;
+ XRRCrtcInfo *info = NULL;
struct sigaction sig;
int scr, scrw, scrh;
int x, y, w, h, th;
@@ -61,10 +65,15 @@ main(int argc, char *argv[])
if (!(dpy = XOpenDisplay(NULL)))
die("cannot open display");
+
scr = DefaultScreen(dpy);
+ screens = XRRGetScreenResources(dpy, RootWindow(dpy, scr));
+ info = XRRGetCrtcInfo(dpy, screens, screens->crtcs[0]);
+ scrw = info->width;
+ scrh = info->height;
+
vis = DefaultVisual(dpy, scr);
colormap = DefaultColormap(dpy, scr);
-
XftColorAllocName(dpy, vis, colormap, bgcol, &color);
attrs.background_pixel = color.pixel;
XftColorAllocName(dpy, vis, colormap, bordercol, &color);
@@ -85,29 +94,27 @@ main(int argc, char *argv[])
w = len;
}
- w = w * (font->descent << 1) + borderw;
- h = (th + (borderw << 2)) * argc;
- scrw = DisplayWidth(dpy, scr);
- scrh = DisplayHeight(dpy, scr);
+ w *= th + borderw;
+ h = th * (argc - 1) + (linespace * (argc - 2)) + (padding << 1);
switch (pos) {
- case TOP_LEFT:
- x = mx;
- y = my;
- break;
- case TOP_RIGHT:
- default:
- x = scrw - w - my;
- y = my;
- break;
- case BOTTOM_LEFT:
- x = mx;
- y = scrh - h - my;
- break;
- case BOTTOM_RIGHT:
- x = scrw - w - mx;
- y = scrh - h - my;
- break;
+ case TOP_LEFT:
+ x = mx;
+ y = my;
+ break;
+ case TOP_RIGHT:
+ default:
+ x = scrw - w - my;
+ y = my;
+ break;
+ case BOTTOM_LEFT:
+ x = mx;
+ y = scrh - h - my;
+ break;
+ case BOTTOM_RIGHT:
+ x = scrw - w - mx;
+ y = scrh - h - my;
+ break;
}
win = XCreateWindow(dpy, RootWindow(dpy, scr), x, y, w, h, borderw,
@@ -137,7 +144,7 @@ main(int argc, char *argv[])
XClearWindow(dpy, win);
for (i = 1; i < argc; i++)
XftDrawStringUtf8(drw, &color, font,
- borderw, (th + (borderw << 2)) * i,
+ w >> 3, linespace * (i - 1) + th * i + padding,
(FcChar8 *)argv[i], strlen(argv[i]));
} else if (ev.type == ButtonPress)
break;
@@ -146,6 +153,8 @@ main(int argc, char *argv[])
XftDrawDestroy(drw);
XftColorFree(dpy, vis, colormap, &color);
XftFontClose(dpy, font);
+ XRRFreeCrtcInfo(info);
+ XRRFreeScreenResources(screens);
XCloseDisplay(dpy);
return 0;