diff --git a/builds/statusbar/default.nix b/builds/statusbar/default.nix new file mode 100644 index 0000000..469c3f9 --- /dev/null +++ b/builds/statusbar/default.nix @@ -0,0 +1,2 @@ +{ pkgs ? import {} }: +pkgs.callPackage ./derivation.nix {} diff --git a/builds/statusbar/derivation.nix b/builds/statusbar/derivation.nix new file mode 100644 index 0000000..435b546 --- /dev/null +++ b/builds/statusbar/derivation.nix @@ -0,0 +1,10 @@ +{ lib, python3Packages }: +with python3Packages; +buildPythonApplication { + pname = "statusbar"; + version = "1.0"; + + propagatedBuildInputs = [ ]; + + src = ./.; +} diff --git a/builds/statusbar/setup.py b/builds/statusbar/setup.py new file mode 100644 index 0000000..493b970 --- /dev/null +++ b/builds/statusbar/setup.py @@ -0,0 +1,23 @@ +from setuptools import setup, find_packages + +setup( + name = 'pystatus', + version = '1.0.0', + author = 'stupidcomputer', + author_email = 'ryan@beepboop.systems', + url = 'https://git.beepboop.systems/stupidcomputer/dot_testing', + description = 'simple statusbar content program', + license = 'MIT', + entry_points = { + 'console_scripts': [ + 'statusbar = statusbar.statusbar:main' + ] + }, + classifiers = ( + "Programming Language :: Python :: 3", + "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", + "Operating System :: POSIX :: Linux", + "Environment :: Console" + ), + zip_safe = False +) diff --git a/builds/statusbar/statusbar/__init__.py b/builds/statusbar/statusbar/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/builds/statusbar/statusbar/statusbar.py b/builds/statusbar/statusbar/statusbar.py new file mode 100644 index 0000000..2fef7ed --- /dev/null +++ b/builds/statusbar/statusbar/statusbar.py @@ -0,0 +1,160 @@ +from multiprocessing import Process, Queue +from collections import defaultdict +from sys import argv +from sys import stdout +from math import floor +import datetime +import signal +import subprocess +import re + +import os, socket, time + +def find_all_belonging_to_monitor(splitted, monitor): + splitted = [i[1:] if i[1:] == monitor else i for i in splitted] + our_monitor = splitted.index(monitor) + next_monitor = None + for i in range(our_monitor, len(splitted)): + if splitted[i][0].lower() == "m": + next_monitor = i + break + + if not next_monitor: + next_monitor = len(splitted) - 1 + + return splitted[our_monitor:next_monitor] + +def generate_desktop_string(monitor_array): + output = [] + for i in monitor_array: + if i[0] == "O": + output.append("*{}".format(i[1:])) + + if i[0] == "o": + output.append("{}".format(i[1:])) + + if i[0] == "F": + output.append("*{}".format(i[1:])) + + return ' '.join(output) + +def bspwm(queue, monitor): + client = socket.socket( + socket.AF_UNIX, + socket.SOCK_STREAM + ) + client.connect("/tmp/bspwm_1_0-socket") + + message = "subscribe\0".encode() + client.send(message) + while True: + resp = client.recv(1024).decode().rstrip() + splitted = resp[1:].split(":") + if not monitor == "all": + monitor_array = find_all_belonging_to_monitor(splitted, monitor) + else: + monitor_array = splitted + queue.put({ + "module": "bspwm", + "data": generate_desktop_string(monitor_array) + }) + + client.close() + +def clock(queue, _): + while True: + queue.put({ + "module": "clock", + "data": datetime.datetime.now().strftime("%d/%m | %H:%M") + }) + + time.sleep(60) + +def filecheckerfactory(filename: str, modname: str, timeout=60): + def filechecker(queue, _): + while True: + try: + file = open(filename) + buf = file.read(128).rstrip() + queue.put({ + "module": modname, + "data": buf + }) + + except FileNotFoundError: + pass + + time.sleep(timeout) + + return filechecker + +battery = filecheckerfactory("/sys/class/power_supply/BAT0/capacity", "bat") +batterystatus = filecheckerfactory("/sys/class/power_supply/BAT0/status", "batstat") + +def render(modules) -> str: + columns, _ = os.get_terminal_size(0) + + left = "{} | {}".format(modules["clock"], modules["bspwm"]) + right = "{}({})".format(modules["bat"], modules["batstat"]) + padding = " " * (columns - len(left) - len(right) - 0) + + output = left + padding + right + + # special battery trickery + try: + batt_percentage = int(modules["bat"]) / 100 + except ValueError: + batt_percentage = 1 + + highlighted = floor(columns * batt_percentage) + + output = "\033[?25l\033[2J\033[H\033[4m" + \ + output[:highlighted] + \ + "\033[24m" + \ + output[highlighted:] + + print(output, end='') + stdout.flush() + +def main(): + if argv[1] == "start_statusbars": +# signal.signal(signal.SIGINT, signal.SIG_IGN) +# os.system("pkill statusbar") +# signal.signal(signal.SIGINT, signal.SIG_DFL) + # get the monitors + xrandr = subprocess.Popen(['xrandr'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + output = list(xrandr.stdout) + output = [i.decode("utf-8") for i in output if " connected" in i.decode("utf-8")] + serialized = [] + for i in output: + splitted = i.split(' ') + print(splitted) + displayname = splitted[0] + geometry = splitted[2] + if geometry == "primary": + geometry = splitted[3] + + try: + geometry_splitted = [int(i) for i in geometry.replace('x', '+').split('+')] + except ValueError: + continue + geometry_splitted[1] = 20 + print(displayname, geometry_splitted) + os.system("st -c statusbar -p -g {}x{}+{}+{} -e statusbar {} & disown".format( + *map(str, geometry_splitted), + displayname + )) + return + queue = Queue() + modules = [bspwm, clock, battery, batterystatus] + [Process(target=module, args=(queue, argv[1])).start() for module in modules] + + module_outputs = defaultdict(lambda: "") + + while True: + result = queue.get() + module_outputs[result["module"]] = result["data"] + render(module_outputs) + +if __name__ == "__main__": + main() diff --git a/builds/utils.nix b/builds/utils.nix index c175d33..8fd47e9 100644 --- a/builds/utils.nix +++ b/builds/utils.nix @@ -1,8 +1,6 @@ { stdenv , lib -# for statusbar -, pkg-config -, libxcb +, pkgs # shell scripts stuff , makeWrapper , sshuttle @@ -16,6 +14,7 @@ , figlet , curl , ytfzf +, herbe , xrandr , svkbd , xkbset @@ -30,13 +29,8 @@ stdenv.mkDerivation rec { src = ./utils; - nativeBuildInputs = [ makeWrapper pkg-config libxcb ]; - buildInputs = [ libxcb bash feh xrandr jq curl fzy ytfzf ffmpeg sshuttle svkbd scrcpy xkbset rbw xclip libsForQt5.kolourpaint ]; - - buildPhase = '' - ls - make - ''; + nativeBuildInputs = [ makeWrapper ]; + buildInputs = [ bash feh xrandr jq curl fzy ytfzf ffmpeg sshuttle svkbd scrcpy xkbset rbw xclip libsForQt5.kolourpaint ]; installPhase = '' mkdir -p $out/bin @@ -44,9 +38,7 @@ stdenv.mkDerivation rec { for i in $(ls $src/sh); do cp $src/sh/$i $out/bin ln -sf $out/bin/tmenu_run $out/bin/regenerate - wrapProgram $out/bin/$i --prefix PATH : ${lib.makeBinPath [ sxhkd bash feh xrandr jq figlet curl fzy ytfzf ffmpeg sshuttle svkbd scrcpy libsForQt5.kolourpaint ]} + wrapProgram $out/bin/$i --prefix PATH : ${lib.makeBinPath [ sxhkd bash feh xrandr jq figlet curl fzy ytfzf herbe ffmpeg sshuttle svkbd scrcpy libsForQt5.kolourpaint ]} done - - cp c/status/main $out/bin/statusbar ''; } diff --git a/builds/utils/Makefile b/builds/utils/Makefile deleted file mode 100644 index c7422f8..0000000 --- a/builds/utils/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -.PHONY: main -main: - make -C c/status -f Makefile diff --git a/builds/utils/c/status/.gitignore b/builds/utils/c/status/.gitignore deleted file mode 100644 index 87e54c2..0000000 --- a/builds/utils/c/status/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -main -*.o diff --git a/builds/utils/c/status/Makefile b/builds/utils/c/status/Makefile deleted file mode 100644 index 15d17f7..0000000 --- a/builds/utils/c/status/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -LDFLAGS=`pkg-config --cflags --libs xcb` -CFLAGS=-ggdb -fsanitize=address -main: battery.o bspwm.o time.o battstatus.o message.o - -clean: - rm *.o main - -run: - ./main diff --git a/builds/utils/c/status/README b/builds/utils/c/status/README deleted file mode 100644 index 25c36dd..0000000 --- a/builds/utils/c/status/README +++ /dev/null @@ -1,4 +0,0 @@ -status ------- - -a simple statusbar script thing (tm) diff --git a/builds/utils/c/status/battery.c b/builds/utils/c/status/battery.c deleted file mode 100644 index 987ee0e..0000000 --- a/builds/utils/c/status/battery.c +++ /dev/null @@ -1,38 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "battery.h" -#include "common.h" - -/* config contains a path to the battery */ -int mod_battery(char *config, char *name, char *pipename) { - struct message msg; - strcpy(msg.name, name); - - int fd = open(pipename, O_WRONLY); - int battery; - int recvd; - - chdir("/sys/class/power_supply"); - chdir(config); - - for(;;) { - battery = open("capacity", O_RDONLY); - recvd = read(battery, msg.content, 3); - msg.content[3] = '\0'; - if (msg.content[2] == '\n') { - msg.content[2] = '\0'; - } - close(battery); - write(fd, &msg, sizeof(msg)); - - sleep(30); - } - - return 0; -} diff --git a/builds/utils/c/status/battery.h b/builds/utils/c/status/battery.h deleted file mode 100644 index ee7eeed..0000000 --- a/builds/utils/c/status/battery.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef STATUS_BATTERY_H -#define STATUS_BATTERY_H - -int mod_battery(char *config, char *name, char *pipename); - -#endif diff --git a/builds/utils/c/status/battstatus.c b/builds/utils/c/status/battstatus.c deleted file mode 100644 index 3646ccb..0000000 --- a/builds/utils/c/status/battstatus.c +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include -#include -#include - -#include "battstatus.h" -#include "common.h" - -int mod_battstatus(char *config, char *name, char *pipename) { - char status; - int battery; - struct message msg; - strcpy(msg.name, name); - - int fd = open(pipename, O_WRONLY); - - chdir("/sys/class/power_supply"); - chdir(config); - - for(;;) { - battery = open("status", O_RDONLY); - read(battery, msg.content, 1); - switch(msg.content[0]) { - case 'N': /* not charging */ - msg.content[0] = '-'; - break; - case 'C': /* charging */ - msg.content[0] = '^'; - break; - case 'D': /* discharging */ - msg.content[0] = 'U'; - break; - case 'U': /* unknown */ - msg.content[0] = '?'; - break; - default: /* what's going on? */ - msg.content[0] = '!'; - break; - } - msg.content[1] = '\0'; - close(battery); - write(fd, &msg, sizeof(msg)); - - sleep(30); - } - - return 0; -} diff --git a/builds/utils/c/status/battstatus.h b/builds/utils/c/status/battstatus.h deleted file mode 100644 index 0c5366c..0000000 --- a/builds/utils/c/status/battstatus.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef STATUS_BATTSTAT_H -#define STATUS_BATTSTAT_H - -int mod_battstatus(char *config, char *name, char *pipename); - -#endif diff --git a/builds/utils/c/status/bspwm.c b/builds/utils/c/status/bspwm.c deleted file mode 100644 index aa72e8d..0000000 --- a/builds/utils/c/status/bspwm.c +++ /dev/null @@ -1,73 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "bspwm.h" -#include "common.h" - -const char subscribe[] = "subscribe"; - -int get_socket(void) { - struct sockaddr_un sock; - char *host; - int displaynumber, screennumber; - int fd; - - xcb_parse_display(NULL, &host, &displaynumber, &screennumber); - - sock.sun_family = AF_UNIX; - snprintf( - sock.sun_path, - sizeof(sock.sun_path), "/tmp/bspwm%s_%i_%i-socket", - host, displaynumber, screennumber - ); - - free(host); - - fd = socket(AF_UNIX, SOCK_STREAM, 0); - if (connect( - fd, - (struct sockaddr *) &sock, - sizeof(sock) - ) == -1) { - return -1; - } else { - return fd; - } -} - -int should_be_shown(char c) { - return c == 'O' || c == 'o' || c == 'F' || c == 'U' || c == 'u'; -} - -int is_a_desktop(char c) { - return c == 'O' || c == 'o' || c == 'F' || c == 'f' || c == 'U' || c == 'u'; -} - -int mod_bspwm(char *config, char *name, char *pipename) { - struct message msg; - int fd, bspcfd; - char in[BUFFER_SIZE]; - - strcpy(msg.name, name); - msg.flags = 0; - - fd = open(pipename, O_WRONLY); - bspcfd = get_socket(); - - send(bspcfd, subscribe, sizeof(subscribe), 0); - - for(;;) { - int recvd = recv(bspcfd, msg.content, sizeof(msg.content), 0); - msg.content[recvd - 1] = '\0'; - write(fd, &msg, sizeof(msg)); - memset(msg.content, 0, 512); - } - - return 0; -} diff --git a/builds/utils/c/status/bspwm.h b/builds/utils/c/status/bspwm.h deleted file mode 100644 index cd4df4e..0000000 --- a/builds/utils/c/status/bspwm.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef STATUS_BSPWM_H -#define STATUS_BSPWM_H - -int mod_bspwm(char *config, char *name, char *pipename); - -#endif diff --git a/builds/utils/c/status/common.h b/builds/utils/c/status/common.h deleted file mode 100644 index 48af44c..0000000 --- a/builds/utils/c/status/common.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef STATUS_COMMON_H -#define STATUS_COMMON_H - -#define LENGTH(x) sizeof(x) / sizeof(x[0]) -#define BUFFER_SIZE 512 - -struct module { - int (*fork_callback)(char *config, char *name, char *pipename); - char name[16]; - char config[512]; - char buffer[512]; - int buflen; -}; - -struct message { - int flags; - char name[16]; - char content[512]; -}; - -#endif diff --git a/builds/utils/c/status/main.c b/builds/utils/c/status/main.c deleted file mode 100644 index 94a7d7d..0000000 --- a/builds/utils/c/status/main.c +++ /dev/null @@ -1,88 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include "common.h" -#include "battery.h" -#include "battstatus.h" -#include "bspwm.h" -#include "time.h" -#include "message.h" - -struct module mods[] = { - {mod_battery, "battery", "BAT0", { '\0' }}, - {mod_battstatus, "battstatus", "BAT0", { '\0' }}, - {mod_time, "time", "", { '\0' }}, - {mod_bspwm, "bspwm", "", { '\0' }}, -/* {mod_message, "message", "/home/usr/.cache/statusbar_notification", { '\0' }}, */ -}; - -void create_module_proc(int index, char *pipename) { - pid_t pid = fork(); - - if (pid == 0) { /* we're the child */ - mods[index].fork_callback( - mods[index].config, - mods[index].name, - pipename - ); - } -} - -void create_module_procs(char *pipename) { - for(int i = 0; i < LENGTH(mods); i++) { - create_module_proc(i, pipename); - } -} - -void redraw() { - /* get the progress' module's value, convert it to int, and then - * figure out how much of the screen should be shaded in */ - - printf("\033[H\033[2J"); - for(int i = 0; i < LENGTH(mods); i++) { - if (i == 0) printf("%s ", mods[i].buffer); - else printf("| %s ", mods[i].buffer); - } - - fflush(stdout); -} - -static char NAMED_PIPE[] = "/home/usr/.cache/statusbar_pipe"; - -int main(void) { - srand(time(NULL)); - mkfifo(&NAMED_PIPE, 0666); /* it's okay if this fails */ - int fd = open(&NAMED_PIPE, O_RDWR); - struct message msg; - - create_module_procs(&NAMED_PIPE); - - for (;;) { - int ret = read(fd, &msg, sizeof(msg)); - if(ret < 0) { - printf("error while reading message from child\n"); - } - - for(int i = 0; i < LENGTH(mods); i++) { - if(strcmp(mods[i].name, msg.name) == 0) { - mods[i].buflen = strlen(msg.content); - strcpy(mods[i].buffer, msg.content); - redraw(); - break; - } - } - } - - return 0; -} diff --git a/builds/utils/c/status/message.c b/builds/utils/c/status/message.c deleted file mode 100644 index 7a88663..0000000 --- a/builds/utils/c/status/message.c +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include -#include -#include -#include - -#include "message.h" -#include "common.h" - -int mod_message(char *config, char *name, char *pipename) { - struct message msg; - struct inotify_event buf; - strcpy(msg.name, name); - - int fd = inotify_init(); - int outfd = open(pipename, O_WRONLY); - - for(;;) { - int watchdesc = inotify_add_watch(fd, config, IN_MODIFY); -read: - int watchread = read(fd, &buf, sizeof(struct inotify_event)); - - /* the file's changed, so reread it */ - int filefd = open(config, O_RDONLY, 0); - int read_in = read(filefd, msg.content, sizeof(msg.content)); - msg.content[read_in - 1] = '\0'; - close(filefd); - - /* write the new */ - write(outfd, &msg, sizeof(msg)); - inotify_rm_watch(fd, watchdesc); /* not sure why this is needed */ - } - - return 0; -} diff --git a/builds/utils/c/status/message.h b/builds/utils/c/status/message.h deleted file mode 100644 index e23be77..0000000 --- a/builds/utils/c/status/message.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef STATUS_MESSAGE_H -#define STATUS_MESSAGE_H - -int mod_message(char *config, char *name, char *pipename); - -#endif diff --git a/builds/utils/c/status/shell.nix b/builds/utils/c/status/shell.nix deleted file mode 100644 index b0645c3..0000000 --- a/builds/utils/c/status/shell.nix +++ /dev/null @@ -1,9 +0,0 @@ -with import {}; - pkgs.mkShell { - nativeBuildInputs = [ - gdb - gnumake - pkg-config - xorg.libxcb - ]; - } diff --git a/builds/utils/c/status/time.c b/builds/utils/c/status/time.c deleted file mode 100644 index b8a81ec..0000000 --- a/builds/utils/c/status/time.c +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include -#include -#include - -#include "common.h" -#include "time.h" - -int mod_time(char *config, char *name, char *pipename) { - struct message msg; - time_t now; - struct tm *tm; - int fd; - - strcpy(msg.name, name); - msg.flags = 0; - fd = open(pipename, O_WRONLY); - - for(;;) { - time(&now); - tm = localtime(&now); - strftime(msg.content, 512, "%H:%M", tm); - write(fd, &msg, sizeof(msg)); - - sleep(60); - } -} diff --git a/builds/utils/c/status/time.h b/builds/utils/c/status/time.h deleted file mode 100644 index ca7463a..0000000 --- a/builds/utils/c/status/time.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef STATUS_TIME_H -#define STATUS_TIME_H - -int mod_time(char *config, char *name, char *pipename); - -#endif diff --git a/builds/utils/sh/disp b/builds/utils/sh/disp index 5941105..5d7f04b 100755 --- a/builds/utils/sh/disp +++ b/builds/utils/sh/disp @@ -138,7 +138,7 @@ esac # initial post-wm setup keyboard -statuswrap +statusbar start_statusbars set_walls screensaver diff --git a/builds/utils/sh/statuswrap b/builds/utils/sh/statuswrap deleted file mode 100755 index e75379c..0000000 --- a/builds/utils/sh/statuswrap +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -geos=$( - xrandr | \ - grep ' connected' | \ - grep -o '[0-9]*x[0-9]*+[0-9]*+[0-9]*' | \ - awk -F'[x+]' '{print $1 "x20+" $3 "+" $4}' -) - -pkill statusbar - -for i in $geos; do - st -c statusbar -p -g "$i" -e statusbar & disown -done diff --git a/modules/common.nix b/modules/common.nix index e495338..825e83f 100644 --- a/modules/common.nix +++ b/modules/common.nix @@ -9,6 +9,7 @@ (pkgs.callPackage ../builds/rebuild.nix {}) (pkgs.callPackage ../builds/st.nix {}) (pkgs.callPackage ../builds/utils.nix {}) + (pkgs.callPackage ../builds/statusbar {}) pkgs.man-pages ];