Skip to content

Instantly share code, notes, and snippets.

@matyklug18
Created September 18, 2021 18:09
Show Gist options
  • Save matyklug18/71d4b7009e893387cee90d95dd2ea637 to your computer and use it in GitHub Desktop.
Save matyklug18/71d4b7009e893387cee90d95dd2ea637 to your computer and use it in GitHub Desktop.
// --------------
// TextBar v0.1.0
// --------------
// Usage: <text generator> | textbar | <input handler>
//
// Shows the last two lines from stdin on a bar
// Every odd line is on the left
// Every even line is on the right
// Updating one side at a time is not possible
// Line buffered
// Prints all mouse clicks to stdout
// In the format of `X Y` (without the '`')
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <stdbool.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <cairo.h>
#include <cairo-xlib.h>
Display* dpy;
Window win;
cairo_surface_t* sfc;
cairo_t* ctx;
char text[256] = {0};
char text_other[256] = {0};
int width;
//extern int errno;
// CONFIG
#define POSITION TOP
#define FONT "FiraCode Nerd Font"
#define FONT_SIZE 16
#define BG_COLOR 0.157, 0.165, 0.212
#define FG_COLOR 0.973, 0.973, 0.949
// COMPUTATION
#define HEIGHT FONT_SIZE*2
#define FONT_POS FONT_SIZE*1.4
void init() {
XInitThreads();
dpy = XOpenDisplay(NULL);
int screen = DefaultScreen(dpy);
width = DisplayWidth(dpy, screen);
win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, width, HEIGHT, 0, 0, 0);
XSelectInput(dpy, win, ButtonPressMask | StructureNotifyMask | ExposureMask);
Atom type = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
long value = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", False);
XChangeProperty(dpy, win, type,
XA_ATOM, 32, PropModeReplace, (unsigned char *) &value, 1);
#if POSITION==BOTTOM
XMoveWindow(dpy, win, 0, DisplayHeight(dpy, screen));
#elif POSITION==TOP
XMoveWindow(dpy, win, 0, 0);
#endif
XMapWindow(dpy, win);
sfc = cairo_xlib_surface_create(dpy, win, DefaultVisual(dpy, screen), DisplayWidth(dpy, screen), HEIGHT);
ctx = cairo_create(sfc);
}
pthread_mutex_t do_paint;
void paint() {
pthread_mutex_lock(&do_paint);
cairo_push_group(ctx);
cairo_set_source_rgb(ctx, BG_COLOR);
cairo_paint(ctx);
cairo_move_to(ctx, FONT_SIZE / 2, FONT_POS);
cairo_select_font_face(ctx, FONT, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size(ctx, FONT_SIZE);
cairo_set_source_rgb(ctx, FG_COLOR);
cairo_show_text(ctx, text);
cairo_text_extents_t extents;
cairo_text_extents (ctx, text_other, &extents);
cairo_move_to(ctx, (width-extents.width) - FONT_SIZE / 2, FONT_POS);
cairo_show_text(ctx, text_other);
cairo_pop_group_to_source(ctx);
cairo_paint(ctx);
cairo_surface_flush(sfc);
XFlush(dpy);
pthread_mutex_unlock(&do_paint);
}
void update() {
while(1) {
fgets(text, 256, stdin);
fgets(text_other, 256, stdin);
text[strcspn(text, "\n")] = 0;
text_other[strcspn(text_other, "\n")] = 0;
paint();
}
}
int main() {
init();
pthread_mutex_init(&do_paint, NULL);
pthread_t update_thread_id;
if(pthread_create(&update_thread_id, NULL, update, NULL)) {
perror("pthread failed");
}
while(1) {
XEvent e;
XNextEvent(dpy, &e);
if(e.type == ButtonPress) {
printf("%d %d\n", e.xbutton.x, e.xbutton.y);
fflush(stdout);
} else
if(e.type == ConfigureNotify) {
pthread_mutex_lock(&do_paint);
cairo_xlib_surface_set_size(sfc, e.xconfigure.width, e.xconfigure.height);
pthread_mutex_unlock(&do_paint);
} else
if(e.type == Expose) {
paint();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment