1 Commits
main ... ARMv8

Author SHA1 Message Date
Klein
5ed169c4cb Initial ARMv8 commit 2024-08-19 21:00:48 -04:00
105 changed files with 772 additions and 1830 deletions

View File

@@ -1,34 +0,0 @@
static const char col_gray1[] = "#0f161e";
static const char col_gray3[] = "#fff7d0";
static const char col_gray4[] = "#FF609A";
static const char col_gray2[] = "#282A2E";
static const char col_cyan[] = "#0f161e";
static const char tag1[] = "#bf8427";
static const char tag2[] = "#5865F2";
static const char tag3[] = "#FF5500";
static const char tag4[] = "#FF609A";
static const char tag5[] = "#842291";
static const char tag6[] = "#900C3F";
static const char tag7[] = "#67AFA5";
static const char tag8[] = "#1DB954";
static const char tag9[] = "#FFFFFF";
static const char *colors[][3] = {
/* fg bg border */
[SchemeNorm] = { col_gray3, col_gray1, col_cyan },
[SchemeSel] = { col_gray4, col_cyan, col_gray2 },
[SchemeTitle] = { col_gray4, col_cyan, col_cyan },
};
static const char *tagsel[][2] = {
{ tag1, col_gray1 },
{ tag2, col_gray1 },
{ tag3, col_gray1 },
{ tag4, col_gray1 },
{ tag5, col_gray1 },
{ tag6, col_gray1 },
{ tag7, col_gray1 },
{ tag8, col_gray1 },
{ tag9, col_gray1 },
};

Binary file not shown.

Binary file not shown.

View File

@@ -1,515 +0,0 @@
#!/usr/bin/env bash
#
# Please be aware that I only run debian. Idk if this script will work for all
# Name: dwm-deps-installer.sh
# Purpose: Attempt to install dependencies for dwm (with multiple patches)
# across a wide range of Operating Systems and distributions.
# Author: ChatGPT (with users requirements)
# ---------------------------------------------------------------------
set -Eeuo pipefail
#----------------------------------------------
# Helper Functions
#----------------------------------------------
# Colored echo helpers (optional, remove if you dont want colors):
RED="$(tput setaf 1 || true)"
GREEN="$(tput setaf 2 || true)"
YELLOW="$(tput setaf 3 || true)"
BLUE="$(tput setaf 4 || true)"
BOLD="$(tput bold || true)"
RESET="$(tput sgr0 || true)"
info() { echo -e "${BLUE}[INFO]${RESET} $*"; }
warn() { echo -e "${YELLOW}[WARN]${RESET} $*"; }
error() { echo -e "${RED}[ERROR]${RESET} $*" >&2; }
success() { echo -e "${GREEN}[OK]${RESET} $*"; }
# Ensure the user is either root or can use sudo (for distros that require it).
check_root_or_sudo() {
if (( $EUID == 0 )); then
info "Running as root."
else
# Check if sudo is present
if ! command -v sudo &>/dev/null; then
error "You need 'sudo' installed or to run this script as root!"
exit 1
fi
fi
}
#----------------------------------------------
# Detect Operating System
#----------------------------------------------
# Strategy:
# 1. Check `uname -s` for high-level OS detection (e.g., "Linux", "Darwin", "FreeBSD", "OpenBSD", "NetBSD", "SunOS", "CYGWIN_NT-10.0", "MSYS_NT-10.0", etc.).
# 2. If Linux, parse /etc/os-release for distribution ID.
# 3. If *BSD, parse `uname -s` or other known markers.
# 4. If Windows (Cygwin, MSYS, etc.), note that direct DWM usage is limited unless WSL is used.
# 5. If macOS (Darwin), note that you can't replace the system WM. We'll still do a brew-based install for X-related libs.
# 6. If illumos/Solaris (SunOS), attempt typical "pkg" or "pkgutil" usage, but this can vary widely.
detect_os() {
local unameOut
unameOut="$(uname -s 2>/dev/null || true)"
case "${unameOut}" in
Linux*) echo "Linux";;
Darwin*) echo "macOS";;
FreeBSD*) echo "FreeBSD";;
OpenBSD*) echo "OpenBSD";;
NetBSD*) echo "NetBSD";;
DragonFly*) echo "DragonFlyBSD";;
SunOS*) echo "SunOS";; # Could be illumos or Solaris
CYGWIN*|MINGW*|MSYS*) echo "Windows";;
*)
# unknown
echo "UnknownOS"
;;
esac
}
#----------------------------------------------
# Install function for Linux distributions
#----------------------------------------------
install_deps_linux() {
# We'll attempt to parse /etc/os-release to get the distribution ID
local distro="Unknown"
if [[ -f /etc/os-release ]]; then
# shellcheck source=/dev/null
. /etc/os-release
distro="${ID:-Unknown}"
# Some distros (like Pop!_OS) might have ID=ubuntu but ID_LIKE=debian
# We might also check $ID_LIKE to refine guesses
fi
info "Detected distro ID: $distro"
# Lowercase just in case
distro="${distro,,}"
# Basic note: We need dev packages for:
# - X11 (libx11, dev headers)
# - Xft (libxft, dev)
# - Xinerama (libxinerama, dev)
# - Yajl (libyajl, dev) for certain patches
# - xinit
# - xorg/xserver
case "$distro" in
# ---------------------------------------------------------------
# Debian / Ubuntu / Mint / etc. (apt-based)
# ---------------------------------------------------------------
debian|ubuntu|linuxmint|pop|neon|elementary|zorin|kali|parrot|\
raspbian|devuan|galliumos|lite|sparkylinux|peppermint|bunsenlabs|\
bodhi|pureos|siduction)
info "Using apt-get/apt to install dependencies..."
sudo apt-get update
sudo apt-get install -y \
libx11-dev libxft-dev libxinerama-dev libyajl-dev \
xorg xinit
;;
# ---------------------------------------------------------------
# Arch / Manjaro / Endeavour / Artix / etc. (pacman-based)
# ---------------------------------------------------------------
arch|manjaro|endeavouros|arco|artix|garuda)
info "Using pacman to install dependencies..."
sudo pacman -Syu --noconfirm --needed \
xorg-server xorg-xinit libx11 libxft libxinerama yajl
;;
# ---------------------------------------------------------------
# Fedora (dnf)
# ---------------------------------------------------------------
fedora)
info "Using dnf to install dependencies..."
sudo dnf install -y \
libX11-devel libXft-devel libXinerama-devel yajl-devel \
xorg-x11-server-Xorg xorg-x11-xinit
;;
# ---------------------------------------------------------------
# RHEL / CentOS / Rocky / Alma (dnf/yum)
# ---------------------------------------------------------------
rhel|centos|rocky|alma)
info "Using dnf (or yum) to install dependencies..."
sudo dnf install -y \
libX11-devel libXft-devel libXinerama-devel yajl-devel \
xorg-x11-server-Xorg xorg-x11-xinit
;;
# ---------------------------------------------------------------
# openSUSE / SUSE (zypper)
# ---------------------------------------------------------------
opensuse*|suse|sle*)
info "Using zypper to install dependencies..."
sudo zypper refresh
sudo zypper install -y \
libX11-devel libXft-devel libXinerama-devel libyajl-devel \
xorg-x11-server xinit
;;
# ---------------------------------------------------------------
# Mageia / OpenMandriva (urpmi or dnf in some versions)
# ---------------------------------------------------------------
mageia|openmandriva)
# Mageia uses urpmi
if command -v urpmi &>/dev/null; then
info "Using urpmi to install dependencies..."
sudo urpmi.update -a
sudo urpmi --auto \
lib64x11-devel lib64xft-devel lib64xinerama-devel lib64yajl-devel \
xinit x11-server-xorg
else
# Some derivatives might use dnf
warn "urpmi not found. Trying dnf..."
sudo dnf install -y \
libX11-devel libXft-devel libXinerama-devel yajl-devel \
xorg-x11-server-Xorg xorg-x11-xinit
fi
;;
# ---------------------------------------------------------------
# PCLinuxOS (apt-rpm? Synaptic? Hard to detect. Possibly uses urpmi.)
# ---------------------------------------------------------------
pclinuxos)
warn "PCLinuxOS uses apt-rpm or Synaptic. Attempting apt-get..."
sudo apt-get update || true
sudo apt-get install -y \
libx11-dev libxft-dev libxinerama-dev libyajl-dev \
xorg xinit || {
error "Failed apt-get on PCLinuxOS. Please install manually."
exit 1
}
;;
# ---------------------------------------------------------------
# Slackware (slackpkg)
# Slackware typically includes dev headers by default, but let's try:
# slackpkg update
# slackpkg install xorg x11 x11-devel etc.
# Slackware doesnt always break them into separate -dev packages.
# If you have the Slackware DVD, you may need to install the "X"
# series and "D" (development) series fully.
# We'll attempt partial coverage:
# ---------------------------------------------------------------
slackware)
warn "Slackware detection. Attempting 'slackpkg' usage..."
# Well do a best-effort. Might require manual steps:
sudo slackpkg update || true
# There might not be exact package naming for dev libs.
warn "Please ensure X, x11 dev, xinerama dev, xft dev, and yajl dev are installed from Slackware's 'X' and 'D' series. Attempting partial installation..."
# Slackpkg might not have granularity for these. We'll try:
sudo slackpkg install x11 xorg || true
# Yajl might be in SlackBuilds or might already be included.
success "Slackware can be tricky. Check your installed packages or SlackBuild for Yajl if needed."
;;
# ---------------------------------------------------------------
# Gentoo / Funtoo / Sabayon / Calculate (emerge or equo for Sabayon)
# ---------------------------------------------------------------
gentoo|funtoo)
info "Using emerge for Gentoo/Funtoo..."
sudo emerge --sync
# On Gentoo, you might set USE flags. We'll do a minimal approach:
# The relevant packages might be x11-libs/libX11, x11-libs/libXft,
# x11-libs/libXinerama, dev-libs/yajl, x11-base/xorg-server, x11-apps/xinit
sudo emerge -n \
x11-libs/libX11 x11-libs/libXft x11-libs/libXinerama dev-libs/yajl \
x11-base/xorg-server x11-apps/xinit
;;
sabayon)
info "Sabayon (now part of MocaccinoOS?), using 'equo' or 'emerge'..."
if command -v equo &>/dev/null; then
sudo equo update
sudo equo install \
x11-libs/libX11 x11-libs/libXft x11-libs/libXinerama dev-libs/yajl \
xorg-server xinit
else
warn "No 'equo'. Trying emerge..."
sudo emerge -n \
x11-libs/libX11 x11-libs/libXft x11-libs/libXinerama dev-libs/yajl \
x11-base/xorg-server x11-apps/xinit
fi
;;
# ---------------------------------------------------------------
# Void (xbps)
# ---------------------------------------------------------------
void)
info "Using xbps-install for Void..."
sudo xbps-install -S
sudo xbps-install -y \
libX11-devel libXft-devel libXinerama-devel yajl-devel \
xorg xorg-server xinit
;;
# ---------------------------------------------------------------
# Alpine (apk)
# ---------------------------------------------------------------
alpine)
info "Using apk for Alpine..."
sudo apk update
sudo apk add \
libx11-dev libxft-dev libxinerama-dev yajl-dev \
xorg-server xinit
;;
# ---------------------------------------------------------------
# NixOS
# On NixOS, you generally manage environment/system packages in
# configuration.nix or use `nix-env -iA`.
# ---------------------------------------------------------------
nixos)
warn "NixOS detected. Attempting 'nix-env -iA nixpkgs.packageName'..."
warn "You may want to manage this in /etc/nixos/configuration.nix."
nix-env -iA nixpkgs.libX11 nixpkgs.libXft nixpkgs.libXinerama nixpkgs.yajl nixpkgs.xorg.xorgserver nixpkgs.xorg.xinit
;;
# ---------------------------------------------------------------
# Clear Linux (swupd)
# ---------------------------------------------------------------
clear-linux*|clearlinux)
info "Clear Linux detected. Using swupd..."
sudo swupd update
sudo swupd bundle-add \
x11-tools os-core-dev C-basic libsdl devpkg-yajl # best guess
warn "Ensure xorg-server and xinit equivalents are installed in Clear Linux (bundles)."
;;
# ---------------------------------------------------------------
# Solus (eopkg)
# ---------------------------------------------------------------
solus)
info "Solus detected. Using eopkg..."
sudo eopkg update-repo
sudo eopkg install -y \
libx11-devel libxft-devel libxinerama-devel yajl-devel \
xorg-server xorg-xinit
;;
# ---------------------------------------------------------------
# If we get here, we don't have a recognized distro or ID is missing
# We'll attempt a generic approach or just print instructions.
# ---------------------------------------------------------------
*)
error "Unrecognized or unsupported Linux distro: '$distro'"
echo
echo "Please manually install the following packages for your distro's package manager:"
echo " * X11 development libraries (libX11, dev headers)"
echo " * Xft (libXft) with dev headers"
echo " * Xinerama (libXinerama) with dev headers"
echo " * Yajl (libyajl) with dev headers"
echo " * xorg-server / xinit"
echo "Then you can compile dwm."
exit 1
;;
esac
success "Dependency installation complete for distro: $distro"
}
#----------------------------------------------
# Install function for BSD
#----------------------------------------------
install_deps_bsd() {
local bsdName="$1"
info "Detected $bsdName..."
case "$bsdName" in
FreeBSD)
# FreeBSD typically uses pkg
sudo pkg update
sudo pkg install -y \
libX11 libXft libXinerama yajl xorg xorg-server xinit
;;
OpenBSD)
# OpenBSD uses pkg_add. Checking package names can be tricky,
# they might be named slightly differently, e.g., "xbase" might
# be part of the OS sets. We'll do a best effort here:
# Usually X is part of base for OpenBSD. We'll just do the libs:
# Some packages might be named e.g. `xenocara-libX11`, etc. This is approximate.
sudo pkg_add xbase xfont xserv # might already be installed
sudo pkg_add xorg # might include many components
# For dev libraries:
sudo pkg_add x11 x11-fmw xft # approximate
# Yajl is often just "yajl"
sudo pkg_add yajl
;;
NetBSD)
# NetBSD might use pkgin or pkg_add from pkgsrc
if command -v pkgin &>/dev/null; then
sudo pkgin update
sudo pkgin -y install libX11 libXft libXinerama yajl xorg
else
# fallback to pkg_add
warn "pkgin not found, trying pkg_add for NetBSD..."
# Typically you set PKG_PATH, etc. This is a best guess
sudo pkg_add libX11 libXft libXinerama yajl xorg
fi
;;
DragonFlyBSD)
# DragonFly also uses pkg (like FreeBSD).
# Some packages might differ in naming:
sudo pkg update
sudo pkg install -y \
xorg libX11 libXft libXinerama yajl
;;
*)
warn "Generic BSD fallback: Please install X11 dev, Xft dev, Xinerama dev, Yajl dev, xinit, xserver from your BSD's packages/ports."
;;
esac
success "Finished (attempted) dependency installation on $bsdName."
}
#----------------------------------------------
# Install function for macOS
#----------------------------------------------
install_deps_macos() {
info "Detected macOS (Darwin)."
# You cannot truly replace the macOS window manager with dwm.
# You *can* compile it and run it under an X server (e.g. XQuartz).
# So well attempt to install the relevant libraries via Homebrew.
if ! command -v brew &>/dev/null; then
error "Homebrew is not installed. Please install Homebrew from https://brew.sh."
exit 1
fi
# Install XQuartz from cask (optional), plus libs
brew update
brew install pkg-config xorg libx11 libxft libxinerama yajl
# For an X server, often you can do:
brew install --cask xquartz
success "macOS libs installed via Homebrew. Remember: you cant fully replace the macOS WM with dwm!"
}
#----------------------------------------------
# Install function for SunOS / Solaris / illumos
#----------------------------------------------
install_deps_sunos() {
info "Detected SunOS (Solaris/illumos)."
# This can vary widely. Some illumos-based distros use "pkg" (OpenIndiana),
# some use "pkgin" (SmartOS), some use "pkgutil" (OpenCSW on Solaris),
# or "apt-like" commands in certain forks.
# We'll guess for OpenIndiana (pkg):
# "pfexec" is typically used in place of sudo for Solaris derivatives.
# This is extremely approximate:
if command -v pfexec &>/dev/null; then
# Attempt OpenIndiana approach:
pfexec pkg refresh
pfexec pkg install x11/header x11/library/libx11 x11/library/libxft \
x11/library/libxinerama library/yajl \
x11/server/xorg x11/session/xinit
else
# fallback approach
warn "No pfexec found. Trying 'sudo pkg' or 'sudo pkgutil'."
if command -v pkg &>/dev/null; then
sudo pkg refresh || true
sudo pkg install x11/header x11/library/libx11 x11/library/libxft \
x11/library/libxinerama library/yajl \
x11/server/xorg x11/session/xinit || {
error "Solaris/illumos install attempt failed. Install these packages manually."
}
elif command -v pkgutil &>/dev/null; then
# Possibly using OpenCSW on Solaris
sudo pkgutil -U
sudo pkgutil -i \
libx11_dev libxft_dev libxinerama_dev yajl_dev xorg xinit || {
error "Could not install via pkgutil. Please do it manually."
}
else
error "No recognized pkg tool on Solaris/illumos. Please install manually."
exit 1
fi
fi
success "Finished attempted install on SunOS/illumos. This might require manual verification."
}
#----------------------------------------------
# Windows approach
#----------------------------------------------
install_deps_windows() {
info "Detected Windows environment (Cygwin/Mingw/MSYS)."
# You cannot replace the Windows manager with dwm. You can compile and run it
# in an X server environment (like VcXsrv or Xming or MobaXterm).
#
# Option 1: WSL (Windows Subsystem for Linux):
# If running in WSL, youre effectively on a Linux environment, so you'd want
# to detect that as "Linux" (some older WSL might say "Microsoft" in /etc/os-release).
# In that case, the user can do the standard Linux approach above.
#
# Option 2: MSYS2 / Cygwin with X packages:
# For MSYS2: pacman -S xorg-server xorg-xinit xorgproto libX11-devel ...
# For Cygwin: setup-x86_64.exe or "apt-cyg" might be used
#
# We'll attempt a best guess for MSYS2 (since it also uses pacman).
# If it fails, we instruct manual steps.
if command -v pacman &>/dev/null; then
# Probably MSYS2
info "MSYS2 environment detected. Using pacman for MSYS2..."
pacman -Syu --noconfirm --needed \
mingw-w64-x86_64-xorgproto mingw-w64-x86_64-libx11 \
mingw-w64-x86_64-libxft mingw-w64-x86_64-libxinerama \
mingw-w64-x86_64-yajl
success "MSYS2 pacman approach done. You still need to run an X server separately."
else
warn "No MSYS2 pacman found. Possibly Cygwin or something else. Please install X11 dev libs, X server, X init, Yajl manually using Cygwin setup or chocolatey, etc."
warn "You CANNOT replace the Windows shell with dwm, only run it under an X server."
fi
}
#----------------------------------------------
# Main script logic
#----------------------------------------------
main() {
check_root_or_sudo
local OS
OS="$(detect_os)"
info "Operating System detected as: $OS"
case "$OS" in
Linux)
install_deps_linux
;;
FreeBSD|OpenBSD|NetBSD|DragonFlyBSD)
install_deps_bsd "$OS"
;;
macOS)
install_deps_macos
;;
SunOS)
install_deps_sunos
;;
Windows)
install_deps_windows
;;
*)
error "Unsupported or unknown OS: $OS"
echo "If youre on an unsupported Linux distro, you can manually install these packages:"
echo " libx11-dev, libxft-dev, libxinerama-dev, libyajl-dev, xserver, xinit"
echo "If youre on another BSD or obscure system, install the equivalents from your package manager."
exit 1
;;
esac
success "Script completed successfully!"
echo "You should now have the libraries required to build dwm with your patches (where possible)."
echo
}
main "$@"

Binary file not shown.

Binary file not shown.

View File

@@ -1,57 +0,0 @@
From 286ca3bb1af08b452bf8140abcc23d4ef61baaa2 Mon Sep 17 00:00:00 2001
From: bakkeby <bakkeby@gmail.com>
Date: Tue, 7 Apr 2020 12:33:04 +0200
Subject: [PATCH] Activate a window in response to _NET_ACTIVE_WINDOW
By default, dwm response to client requests to _NET_ACTIVE_WINDOW client
messages by setting the urgency bit on the named window.
This patch activates the window instead.
Both behaviours are legitimate according to
https://specifications.freedesktop.org/wm-spec/wm-spec-latest.html#idm140200472702304
One should decide which of these one should perform based on the message
senders' untestable claims that it represents the end-user. Setting the
urgency bit is the conservative decision. This patch implements the more
trusting alternative.
It also allows dwm to work with `wmctrl -a` and other external window
management utilities
---
dwm.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/dwm.c b/dwm.c
index 4465af1..3919d47 100644
--- a/dwm.c
+++ b/dwm.c
@@ -514,6 +514,7 @@ clientmessage(XEvent *e)
{
XClientMessageEvent *cme = &e->xclient;
Client *c = wintoclient(cme->window);
+ unsigned int i;
if (!c)
return;
@@ -523,8 +524,14 @@ clientmessage(XEvent *e)
setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */
|| (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen)));
} else if (cme->message_type == netatom[NetActiveWindow]) {
- if (c != selmon->sel && !c->isurgent)
- seturgent(c, 1);
+ for (i = 0; i < LENGTH(tags) && !((1 << i) & c->tags); i++);
+ if (i < LENGTH(tags)) {
+ const Arg a = {.ui = 1 << i};
+ selmon = c->mon;
+ view(&a);
+ focus(c);
+ restack(selmon);
+ }
}
}
--
2.17.1

View File

@@ -3,10 +3,11 @@
#include "colors/space.h"
#include "keys.h"
#define TERMINAL "alacritty" // default terminal appearance */
#define ICONSIZE 20 /* icon size */
#define ICONSPACING 5 /* space between icon and title */
static const unsigned int borderpx = 2; /* border pixel of windows */
static const unsigned int gappx = 5; /* gaps between windows */
static const unsigned int gappx = 10; /* gaps between windows */
static const unsigned int snap = 32; /* snap pixel */
static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */
static const unsigned int systrayonleft = 0; /* 0: systray in the right corner, >0: systray on left of status text */
@@ -22,9 +23,7 @@ static const int user_bh = 8; /* 2 is the default spacing arou
//static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
//static const char *tags[] = { " \u2680 ", " \u2681 ", " \u2682 ", " \u2683 ", " \u2684 ", " \u2685 ", " \u2661 ", " \u2665 ", "\u266c" }; // Dice Faces
// tag1 tag2 tag3 tag4 tag5 tag6 tag7 tag8 tag9
//static const char *tags[] = { " \uf17c ", " \uf1d8 ", " \uf0ac ", " \uf109 ", " \uf09b ", " \uf02d ", " \uf044 ", " \uf1bc ", " \uf120 " };
static const char *tags[] = { "\uf17c", "\uf1d8", "\uf0ac", "\uf109", "\uf09b", "\uf02d", "\uf044", "\uf1bc", "\uf120" };
static const char *tags[] = { " \uf17c ", " \uf1d8 ", " \uf0ac ", " \uf109 ", " \uf09b ", " \uf02d ", " \uf044 ", " \uf1bc ", " \uf120 " };
static const Rule rules[] = {
/* xprop(1):

View File

@@ -31,7 +31,7 @@ LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} ${YAJLLIBS} -lXrender -
# flags
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS}
CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os -march=armv8-a ${INCS} ${CPPFLAGS}
LDFLAGS = ${LIBS}
# Solaris

BIN
KleinDwm/source/drw.o Normal file

Binary file not shown.

BIN
KleinDwm/source/dwm Executable file

Binary file not shown.

View File

@@ -33,7 +33,6 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/epoll.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>
#include <X11/Xatom.h>
@@ -87,21 +86,9 @@ enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms *
enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
typedef struct TagState TagState;
struct TagState {
int selected;
int occupied;
int urgent;
};
typedef struct ClientState ClientState;
struct ClientState {
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
};
typedef union {
long i;
unsigned long ui;
int i;
unsigned int ui;
float f;
const void *v;
} Arg;
@@ -130,7 +117,6 @@ struct Client {
Client *snext;
Monitor *mon;
Window win;
ClientState prevstate;
};
typedef struct {
@@ -149,7 +135,6 @@ typedef struct {
typedef struct Pertag Pertag;
struct Monitor {
char ltsymbol[16];
char lastltsymbol[16];
float mfact;
int nmaster;
int num;
@@ -160,17 +145,14 @@ struct Monitor {
unsigned int seltags;
unsigned int sellt;
unsigned int tagset[2];
TagState tagstate;
int showbar;
int topbar;
Client *clients;
Client *sel;
Client *lastsel;
Client *stack;
Monitor *next;
Window barwin;
const Layout *lt[2];
const Layout *lastlt;
Pertag *pertag;
};
@@ -229,7 +211,6 @@ static unsigned int getsystraywidth();
static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
static void grabbuttons(Client *c, int focused);
static void grabkeys(void);
static int handlexevent(struct epoll_event *ev);
static void incnmaster(const Arg *arg);
static void keypress(XEvent *e);
static void killclient(const Arg *arg);
@@ -260,10 +241,8 @@ static void setclientstate(Client *c, long state);
static void setfocus(Client *c);
static void setfullscreen(Client *c, int fullscreen);
static void setlayout(const Arg *arg);
static void setlayoutsafe(const Arg *arg);
static void setmfact(const Arg *arg);
static void setup(void);
static void setupepoll(void);
static void seturgent(Client *c, int urg);
static void showhide(Client *c);
static void sigchld(int unused);
@@ -338,8 +317,6 @@ static void (*handler[LASTEvent]) (XEvent *) = {
[UnmapNotify] = unmapnotify
};
static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast];
static int epoll_fd;
static int dpy_fd;
static int restart = 0;
static int running = 1;
static Cur *cursor[CurLast];
@@ -347,20 +324,13 @@ static Clr **scheme;
static Clr **tagscheme;
static Display *dpy;
static Drw *drw;
static Monitor *mons, *selmon, *lastselmon;
static Monitor *mons, *selmon;
static Window root, wmcheckwin;
static KeySym keychain = -1;
#include "ipc.h"
/* configuration, allows nested code to access above variables */
#include "config.h"
#ifdef VERSION
#include "IPCClient.c"
#include "yajl_dumps.c"
#include "ipc.c"
#endif
struct Pertag {
unsigned int curtag, prevtag; /* current and previous tag */
int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */
@@ -602,12 +572,6 @@ cleanup(void)
XSync(dpy, False);
XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
ipc_cleanup();
if (close(epoll_fd) < 0) {
fprintf(stderr, "Failed to close epoll file descriptor\n");
}
}
void
@@ -633,7 +597,6 @@ clientmessage(XEvent *e)
XSetWindowAttributes swa;
XClientMessageEvent *cme = &e->xclient;
Client *c = wintoclient(cme->window);
unsigned int i;
if (showsystray && cme->window == systray->win && cme->message_type == netatom[NetSystemTrayOP]) {
/* add systray icons */
@@ -690,14 +653,8 @@ clientmessage(XEvent *e)
setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */
|| cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */));
} else if (cme->message_type == netatom[NetActiveWindow]) {
for (i = 0; i < LENGTH(tags) && !((1 << i) & c->tags); i++);
if (i < LENGTH(tags)) {
const Arg a = {.ui = 1 << i};
selmon = c->mon;
view(&a);
focus(c);
restack(selmon);
}
if (c != selmon->sel && !c->isurgent)
seturgent(c, 1);
}
}
@@ -1380,25 +1337,6 @@ grabkeys(void)
}
}
int
handlexevent(struct epoll_event *ev)
{
if (ev->events & EPOLLIN) {
XEvent ev;
while (running && XPending(dpy)) {
XNextEvent(dpy, &ev);
if (handler[ev.type]) {
handler[ev.type](&ev); /* call handler */
ipc_send_events(mons, &lastselmon, selmon);
}
}
} else if (ev-> events & EPOLLHUP) {
return -1;
}
return 0;
}
void
incnmaster(const Arg *arg)
{
@@ -1883,40 +1821,12 @@ restack(Monitor *m)
void
run(void)
{
int event_count = 0;
const int MAX_EVENTS = 10;
struct epoll_event events[MAX_EVENTS];
XSync(dpy, False);
XEvent ev;
/* main event loop */
while (running) {
event_count = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
for (int i = 0; i < event_count; i++) {
int event_fd = events[i].data.fd;
DEBUG("Got event from fd %d\n", event_fd);
if (event_fd == dpy_fd) {
// -1 means EPOLLHUP
if (handlexevent(events + i) == -1)
return;
} else if (event_fd == ipc_get_sock_fd()) {
ipc_handle_socket_epoll_event(events + i);
} else if (ipc_is_client_registered(event_fd)){
if (ipc_handle_client_epoll_event(events + i, mons, &lastselmon, selmon,
tags, LENGTH(tags), layouts, LENGTH(layouts)) < 0) {
fprintf(stderr, "Error handling IPC event on fd %d\n", event_fd);
}
} else {
fprintf(stderr, "Got event from unknown fd %d, ptr %p, u32 %d, u64 %lu",
event_fd, events[i].data.ptr, events[i].data.u32,
events[i].data.u64);
fprintf(stderr, " with events %d\n", events[i].events);
return;
}
}
}
XSync(dpy, False);
while (running && !XNextEvent(dpy, &ev))
if (handler[ev.type])
handler[ev.type](&ev); /* call handler */
}
void
@@ -2134,18 +2044,6 @@ setlayout(const Arg *arg)
drawbar(selmon);
}
void
setlayoutsafe(const Arg *arg)
{
const Layout *ltptr = (Layout *)arg->v;
if (ltptr == 0)
setlayout(arg);
for (int i = 0; i < LENGTH(layouts); i++) {
if (ltptr == &layouts[i])
setlayout(arg);
}
}
/* arg > 1.0 will set mfact absolutely */
void
setmfact(const Arg *arg)
@@ -2248,36 +2146,6 @@ setup(void)
XSelectInput(dpy, root, wa.event_mask);
grabkeys();
focus(NULL);
setupepoll();
}
void
setupepoll(void)
{
epoll_fd = epoll_create1(0);
dpy_fd = ConnectionNumber(dpy);
struct epoll_event dpy_event;
// Initialize struct to 0
memset(&dpy_event, 0, sizeof(dpy_event));
DEBUG("Display socket is fd %d\n", dpy_fd);
if (epoll_fd == -1) {
fputs("Failed to create epoll file descriptor", stderr);
}
dpy_event.events = EPOLLIN;
dpy_event.data.fd = dpy_fd;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, dpy_fd, &dpy_event)) {
fputs("Failed to add display file descriptor to epoll", stderr);
close(epoll_fd);
exit(1);
}
if (ipc_init(ipcsockpath, epoll_fd, ipccommands, LENGTH(ipccommands)) < 0) {
fputs("Failed to initialize IPC\n", stderr);
}
}
void
@@ -2881,18 +2749,10 @@ updatesystray(void)
void
updatetitle(Client *c)
{
char oldname[sizeof(c->name)];
strcpy(oldname, c->name);
if (!gettextprop(c->win, netatom[NetWMName], c->name, sizeof c->name))
gettextprop(c->win, XA_WM_NAME, c->name, sizeof c->name);
if (c->name[0] == '\0') /* hack to mark broken clients */
strcpy(c->name, broken);
for (Monitor *m = mons; m; m = m->next) {
if (m->sel == c && strcmp(oldname, c->name) != 0)
ipc_focused_title_change_event(m->num, c->win, oldname, c->name);
}
}
void

BIN
KleinDwm/source/dwm.o Normal file

Binary file not shown.

View File

@@ -2,7 +2,7 @@
#include "movestack.c"
#include <X11/XF86keysym.h>
#define TERMINAL "st" // default terminal
#define TERMINAL "alacritty" // default terminal
/* key definitions */
#define MODKEY Mod4Mask
@@ -28,6 +28,8 @@ static const char *termcmd[] = { TERMINAL, NULL };
static const char *inc_light[] = { "brightness", "-a", "up", NULL};
static const char *dec_light[] = { "brightness", "-a", "down", NULL };
/*xrandr control gui wrapper*/
static const char *xrandrwrap[] = { "xrandrwrap", NULL };
/* screenshot command */
static const char *scrotselcmd[] = { "scrot", "-s", "/home/klein/Pictures/screenshots/Screenshot_%Y-%m-%d_%H-%M-%S.png", NULL };
@@ -77,7 +79,7 @@ static const Key keys[] = {
{ MODKEY, XK_c, XK_b, spawn, SHCMD("xdotool key Super_L+3 && qutebrowser") },
{ MODKEY, XK_c, XK_f, spawn, SHCMD("xdotool key Super_L+4 && freetube") },
{ MODKEY, XK_c, XK_g, spawn, SHCMD("xdotool key Super_L+5 && qutebrowser github.com") },
{ MODKEY, XK_c, XK_n, spawn, SHCMD("xdotool key Super_L+7 && st nvim") },
{ MODKEY, XK_c, XK_n, spawn, SHCMD("xdotool key Super_L+7 && nvim") },
{ MODKEY, XK_c, XK_s, spawn, SHCMD("xdotool key Super_L+8 && spotube") },
{ MODKEY, XK_c, XK_z, spawn, SHCMD("xdotool key Super_L+9 && alacritty") },
{ MODKEY, XK_n, XK_v, spawn, {.v = nvimcmd } },
@@ -98,8 +100,7 @@ static const Key keys[] = {
{ 0, -1, XK_F10, spawn, { .v = scrotselcmd } },
{ 0, -1, XF86XK_MonBrightnessUp, spawn, { .v = inc_light } },
{ 0, -1, XF86XK_MonBrightnessDown, spawn, { .v = dec_light } },
{ MODKEY|ShiftMask, -1, XK_l, spawn, SHCMD("slock") }
{ 0, -1, XK_F8, spawn, { .v = xrandrwrap } },
};
/* button definitions */

BIN
KleinDwm/source/util.o Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -1,9 +1,3 @@
# Custom Suckless Dynamic Window Manager with added patches.
## Includes
- The DWM source.
- Statusbar with bash using status2d patches
- slstatus
- st (simple terminal with changes)
- pinentry-dmenu
- dmen
# Suckless Installs - Programs associated with my window manager, and my window manager.
## Purpose
I pretty much use this as my backup system.

View File

@@ -1,55 +0,0 @@
#!/usr/bin/env bash
# Function to check if a command exists
command_exists() {
command -v "$1" >/dev/null 2>&1
}
# DWM dependency check (uncomment if necessary)
# if ! pgrep -x "dwm" > /dev/null; then
# echo "DWM is not running. Please ensure that DWM is installed and is your window manager."
# exit 1
# fi
# Check for the status2D dependency
if command_exists dwm; then
echo "DWM is installed. Make sure you have the status2D patch applied for proper rendering."
fi
# Required packages list
required_packages=("grep" "gawk" "procps" "coreutils" "lm-sensors" "network-manager" "x11-xserver-utils")
# Install required packages
for pkg in "${required_packages[@]}"; do
if ! dpkg -s "$pkg" >/dev/null 2>&1; then
echo "Package $pkg is not installed. Installing..."
sudo apt update
sudo apt install -y "$pkg"
if [ $? -ne 0 ]; then
echo "Failed to install $pkg. Please install it manually, or its equivalent, and edit the source code."
exit 1
fi
else
echo "Package $pkg is already installed."
fi
done
# Copy statusbar.sh to /usr/local/bin and make it executable
sudo cp statusbar.sh /usr/local/bin/statusbar
sudo chmod +x /usr/local/bin/statusbar
# Create the directory and copy colorvars.sh
PREFIX="$HOME/.local/share/statusbar"
mkdir -p "$PREFIX"
cp colorvars.sh "$PREFIX"
# Setup the systemd service
SERVICE_DIR="$HOME/.config/systemd/user"
mkdir -p "$SERVICE_DIR"
cp statusbar.service "$SERVICE_DIR"
# Enable and restart the service
systemctl --user enable statusbar.service
systemctl --user restart statusbar.service
echo "Installation completed successfully. The statusbar is installed and the service has been enabled and restarted."

View File

@@ -1,14 +0,0 @@
[Unit]
Description=SystemBar for DWM from suckless
After=default.target
[Service]
Type=simple
ExecStart=/usr/local/bin/statusbar
User=klein
Restart=on-failure
Environment=DISPLAY=:0
Environment=XAUTHORITY=/home/klein/.Xauthority
[Install]
WantedBy=default.target

View File

@@ -1,310 +0,0 @@
#!/usr/bin/env bash
# Source color vars
source "$HOME/.local/share/statusbar/colorvars.sh"
# Define Basic Dimentions
base_x=0
base_y=2
max_height=23
bar_width=5
gap=5
clock() {
# Adjusted dimensions for the clock icon
local icon_width=18
local icon_height=$((max_height - 2))
# Determine the center of the icon (for the dial)
local center_x=$((base_x + icon_width / 2))
local center_y=$(((base_y + 2) + icon_height / 2))
# Begin drawing the clock icon.
# Outer border (clock frame) in medium gray.
local clock_icon=""
clock_icon+="^c#888888^"
clock_icon+="^r${base_x},$((base_y + 2)),${icon_width},${icon_height}^"
# Inner dial (face), inset by 3 pixels on all sides.
clock_icon+="^c#000000^"
clock_icon+="^r$((base_x + 3)),$((base_y + 5)),$((icon_width - 6)),$((icon_height - 6))^"
# Get current time details.
local hour=$(date +%H)
local minute=$(date +%M)
hour=$((10#$hour))
minute=$((10#$minute))
# Calculate angles in radians.
# Hour hand: each hour is 30° plus half a degree per minute.
local hour_angle
hour_angle=$(awk -v h="$hour" -v m="$minute" 'BEGIN {
printf "%.2f", ((-((h % 12) * 30 + m * 0.5) + 90) * 3.14159265 / 180)
}')
# Minute hand: each minute represents 6°.
local minute_angle
minute_angle=$(awk -v m="$minute" 'BEGIN {
printf "%.2f", ((-(m * 6) + 90) * 3.14159265 / 180)
}')
# Define inner radius from inner dial (the dial drawn is (icon_width-6) wide).
local inner_radius=$(( (icon_width - 6) / 2 ))
# Define hand lengths as fractions of the inner radius.
local hour_hand_length
hour_hand_length=$(awk -v r="$inner_radius" 'BEGIN { printf "%d", r * 0.6 }')
local minute_hand_length
minute_hand_length=$(awk -v r="$inner_radius" 'BEGIN { printf "%d", r * 0.9 }')
# Function to draw a hand from the center to a given length with specified angle and color.
# It draws a series of 1x1 pixel rectangles along the hand's path.
draw_hand() {
local length=$1
local angle=$2
local color=$3
local hand_line=""
for (( i=0; i<=length; i++ )); do
# Compute x and y offset using AWK's cosine and sine functions.
local dx
dx=$(awk -v i="$i" -v a="$angle" 'BEGIN { printf "%d", i * cos(a) }')
local dy
dy=$(awk -v i="$i" -v a="$angle" 'BEGIN { printf "%d", i * sin(a) }')
# Note: subtract dy because screen y coordinates increase downward.
local px=$(( center_x + dx ))
local py=$(( center_y - dy ))
hand_line+="^c${color}^"
hand_line+="^r${px},${py},1,1^"
done
echo -n "${hand_line}"
}
# Draw the hour hand (white) and the minute hand (light gray).
local hour_line
hour_line=$(draw_hand "$hour_hand_length" "$hour_angle" "#FFFFFF")
local minute_line
minute_line=$(draw_hand "$minute_hand_length" "$minute_angle" "#AAAAAA")
# Append the hand drawings to the clock icon.
clock_icon+="${hour_line}${minute_line}"
# Decrease the gap between the icon and the time text by forwarding the drawing cursor by a smaller amount.
# Here, we move the cursor by icon_width + gap - 2 pixels.
clock_icon+="^d^^f$(( icon_width + gap - 2 ))^"
# Fetch the current time (military format HH:MM) with no background.
local time_str
time_str=$(date +%H:%M:%S)
local time_text="^c#FFFFFF^ ${time_str} ^d^"
# Output the complete clock icon and time text without any label.
echo "${clock_icon}${time_text}"
}
cpu() {
local cpu_line1=$(grep '^cpu ' /proc/stat)
sleep 2
local cpu_line2=$(grep '^cpu ' /proc/stat)
local -a cpu1=(${cpu_line1//cpu/})
local -a cpu2=(${cpu_line2//cpu/})
local total1=0
local total2=0
local idle1=${cpu1[3]}
local idle2=${cpu2[3]}
for i in "${cpu1[@]}"; do
total1=$((total1 + i))
done
for i in "${cpu2[@]}"; do
total2=$((total2 + i))
done
local total_delta=$((total2 - total1))
local idle_delta=$((idle2 - idle1))
local usage=$((100 * (total_delta - idle_delta) / total_delta))
local usage_height=$(( (max_height * usage) / 100 ))
local usage_y=$((base_y + max_height - usage_height))
local color=$white
if [ $usage -gt 50 ]; then
color=$red
fi
local status_line=""
status_line+="^c${grey}^^r${base_x},${base_y},${bar_width},${max_height}^"
status_line+="^c${color}^^r${base_x},${usage_y},${bar_width},${usage_height}^"
status_line+="^d^^f7^"
local topcon=$( ps -eo %cpu,comm --sort=-%cpu | head -n 2 | tail -n 1 | awk '{print $2}')
topcon="${topcon:0:5}" # trunkate output
echo "{CPU:${status_line}${usage}% : ${topcon}}"
}
ram() {
local m_mem=$(free -m)
local t_mem=$(echo "$m_mem" | awk '/^Mem:/ {print $2}')
local u_mem=$(echo "$m_mem" | awk '/^Mem:/ {print $3}')
local p_mem=$(awk "BEGIN {printf \"%.0f\", ($u_mem/$t_mem)*100}")
local usage_height=$((max_height * p_mem / 100))
local usage_y=$((base_y + max_height - usage_height))
local status_line=""
status_line+="^c$grey^^r$base_x,${base_y},${bar_width},${max_height}^"
status_line+="^c$white^^r${base_x},${usage_y},${bar_width},${usage_height}^"
status_line+="^d^^f7^"
status_line+="${p_mem}%"
echo "{Mem:$status_line}"
}
swap() {
local m_swap=$(free -m)
local t_swap=$(echo "$m_swap" | awk '/^Swap:/ {print $2}')
local u_swap=$(echo "$m_swap" | awk '/^Swap:/ {print $3}')
if [[ "$u_swap" -eq 0 ]]; then
return
fi
local p_swap=$(awk "BEGIN {printf \"%.0f\", ($u_swap/$t_swap)*100}")
local usage_height=$((max_height * p_swap / 100))
local usage_y=$((base_y + max_height - usage_height))
local status_line=""
status_line+="^c$grey^^r$base_x,${base_y},${bar_width},${max_height}^"
status_line+="^c$white^^r${base_x},${usage_y},${bar_width},${usage_height}^"
status_line+="^d^^f7^"
status_line+="${p_swap}%"
echo "{Swap:$status_line}|"
}
disk() {
local usage_p2=$(df -h | grep '/dev/nvme0n1p2' | awk '{print $5}' | tr -d '%')
local usage_p4=$(df -h | grep '/dev/nvme0n1p4' | awk '{print $5}' | tr -d '%')
if [[ ! "$usage_p2" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
usage_p2=0
fi
if [[ ! "$usage_p4" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
usage_p4=0
fi
local status_line=""
local -A usages=(
[p2]=$usage_p2
[p4]=$usage_p4
)
for partition in p2 p4; do
local percentage=${usages[$partition]}
local usage_height=$(($percentage * $max_height / 100))
local usage_y=$((base_y + max_height - usage_height))
status_line+="^c$grey^^r${base_x},${base_y},${bar_width},${max_height}^"
status_line+="^c$white^^r${base_x},${usage_y},${bar_width},${usage_height}^"
base_x=$((base_x + bar_width +2))
done
status_line+="^d^^f15^"
echo "{Disk:${status_line}R:${usage_p2}%|U:${usage_p4}%}"
}
cpu_temperature(){
local temp=$(sensors | awk '/Package id 0/ {gsub(/[^0-9.]/, "", $4); print int($4)}')
local max_temp=70
local color=$white
if [ "$temp" -gt "$max_temp" ]; then
color=$red
elif [ "$temp" -lt "$max_temp" ]; then
color=$green
fi
local adj_y=5
local usage_height=$(($temp * 10 / $max_temp))
local usage_y=$((adj_y + 10 - usage_height))
local temp_icon="^c$black^"
temp_icon+="^r7,${base_y},5,15^" #Bar behind the fill
temp_icon+="^c$color^"
temp_icon+="^r8,${usage_y},3,${usage_height}^" # Fill Bar
temp_icon+="^c$black^"
temp_icon+="^r4,17,11,5^"
temp_icon+="^r5,19,9,6^"
temp_icon+="^d^^f15^"
echo "^c$white^{^d^$temp_icon $temp°C^c$white^}^d^"
}
battery() {
local status=$(cat /sys/class/power_supply/BAT0/status)
local capacity=$(cat /sys/class/power_supply/BAT0/capacity)
local color=$white
if [[ "$capacity" -le 15 ]]; then
color=$red
elif [[ "$capacity" -le 25 ]]; then
color=$yellow
else
color=$green
fi
local adj_y=7
local fill_width=$(($capacity * 20 / 100))
local battery_icon="^c$white^"
battery_icon+="^r2,10,24,12^"
battery_icon+="^c$grey^"
battery_icon+="^r4,12,20,8^"
battery_icon+="^c$color^"
battery_icon+="^r4,12,$fill_width,8^"
battery_icon+="^c$white^"
battery_icon+="^r26,13,4,6^"
battery_icon+="^d^^f35^"
local color_status=$white
if [[ "$status" == "Full" ]]; then
color_status=$green
elif [[ "$status" == "Charging" ]]; then
color_status=$green
elif [[ "$status" == "Discharging" ]]; then
color_status=$grey
elif [[ "$status" == "Not charging" ]]; then
color_status=$white
else
status="NA"
fi
local volt=$(sensors | awk '/BAT0-acpi-0/ {getline; getline; print $2}')
echo "{${battery_icon}^c${color_status}^${capacity}^d^% ${volt}V}"
}
wifi() {
local iface=$(ip -o link show | grep -v "lo:" | awk -F': ' '{print $2}')
local ssid=$(nmcli -t -f active,ssid dev wifi | grep '^yes' | cut -d':' -f2)
ssid="${ssid:-No WiFi}"
ssid="${ssid:0:15}"
local dwm=$(grep "$iface" /proc/net/wireless | awk '{ print int($4) }')
if [ "$ssid" = "No WiFi" ]; then
local signal=0
else
local signal_normalized=$(( (dwm + 90) * 100 / 60 ))
if [ $signal_normalized -gt 100 ]; then
signal=100
elif [ $signal_normalized -lt 0 ]; then
signal=0
else
signal=$signal_normalized
fi
fi
local color=$white
if [ $signal -ge 66 ]; then
color=$green
elif [ $signal -le 33 ]; then
color=$red
elif [ $signal -gt 33 ] && [ $signal -lt 66 ]; then
color=$yellow
fi
local max_bars=5
local bars_filled=$((signal / 20))
local wifi_icon="^c$color^"
for i in 1 2 3 4 5; do
local width=$((3 * i + 1))
local height=$((3 * i + 1))
local adj_y=$((max_height - height))
if [ $i -le $bars_filled ]; then
wifi_icon+="^c$color^"
else
wifi_icon+="^c$grey^"
fi
wifi_icon+="^r$((base_x + 4 * (i - 2))),$adj_y,$width,$height^"
done
wifi_icon+="^d^^f17^"
echo "{ $wifi_icon$ssid : $signal% }"
}
status(){
echo "$(clock)|$(cpu)|$(ram)|$(swap)$(disk)|$(cpu_temperature)|$(battery)|$(wifi)"
}
while true; do
xsetroot -name "$(status)"
done

View File

@@ -0,0 +1,38 @@
#!/usr/bin/env bash
#Check if command exits
command_exists() {
command -v "$1" >/dev/null 2>&1
}
#DWM dependency is running
if ! pgrep -x "dwm" > /dev/null; then
echo "DWM is not running. Please ensure that you got that shit installed and its your window manager."
exit 1
fi
#status2d dependency (update later if you find out how)
if command_exists dwm; then
echo "DWM is installed. Make sure you got status2D patch applied for properrendering."
fi
#Package dependcies
requires_packages=("grep" "gawk" "procps" "coreutils" "lm-sensors" "network-manager" "x11-xserver-utils")
for pkg in "${requires_packages[@]}"; do
if ! dpkg -s "$pkg" >/dev/null 2>&1; then
echo "Package $pkg is not installed. Installing..."
sudo apt update
sudo apt install -y "$pkg"
if [ $? -ne 0 ]; then
echo "Failed to install $pkg. Install it manually, or its equivalent and edit source code"
exit 1
fi
else
echo "Package $pkg is installed already. YAY"
fi
done
sudo chmod +x /home/klein/DynamicWindowManager/customstatusbar/statusbars/statusbar.sh
sudo ln -s /home/klein/DynamicWindowManager/customstatusbar/statusbars/statusbar.sh /usr/local/bin/statusbar
echo "Installation done. Run statusbar in shell. Installed to local bin"

View File

@@ -0,0 +1,328 @@
#!/bin/bash
# This is a relic of the old. Shit sucks
##Global Definitions
#Color definitions
color_black="#000000" #outline
color_white="#ffffff" #default
color_green="#00ff00"
color_yellow="#ffff00"
color_red="#ff0000"
color_grey="#555555"
#Primary scheme - medium orchid
color_scheme_1="#c067dd" #background
color_scheme_2="#a656c2"
color_scheme_3="#8B45A7"
color_scheme_4="#71348C" #highlight
color_scheme_5="#572371"
color_scheme_6="#3C1256"
color_scheme_7="#22013B" #default text color
#Complimentary scheme - pastel green
c_color_scheme_1="#84dd67" #Complimentary background color
c_color_scheme_2="#72c059"
c_color_scheme_3="#60a44b"
c_color_scheme_4="#4f883d" #Complimentary highlight
c_color_scheme_5="#3f6e30"
c_color_scheme_6="#2f5523"
c_color_scheme_7="#203d17" #Complimentary txt color
#GLobal basics
basic_y=27
basic_x=0
get_cpu() {
local cpu_stats=$(top -bn1 | rep "%pu(s)")
local us=$(echo $cpu_stats | awk '{print $2}' | tr -d '%')
local sy=$(echo $cpu_stats | awk '{print $4}' | tr -d '%')
local ni=$(echo $cpu_stats | awk '{print $6}' | tr -d '%')
local id=$(echo $cpu_stats | awk '{print $8}' | tr -d '%')
local wa=$(echo $cpu_stats | awk '{print $10}' | tr -d '%')
local hi=$(echo $cpu_stats | awk '{print $12}' | tr -d '%')
local si=$(echo $cpu_stats | awk '{print $14}' | tr -d '%')
local st=$(echo $cpu_stats | awk '{print $16}' | tr -d '%')
local top_cpu_consumer=$(ps -eo %cpu,comm --sort=-%cpu | head -n 2 | tail -n 1 | awk '{print $2}')
top_cpu_consumer="${top_cpu_consumer:0:8}"
local base_x=$basic_x
local base_y=$basic_y
local max_height=16
local bar_width=3
local status_line=""
local bg=$color_grey
declare -A colors=( [us]="#ffd700" [sy]="#ff4500" [ni]="#ff8c00" [id]="#008000"
[wa]="#0000ff" [hi]="#4b0082" [si]="#800080" [st]="#a0522d" )
for state in us sy ni id wa hi si st; do
local percentage=$(echo ${!state})
if [[ ! "$percentage" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
percentage=0
fi
local bar_height=$(echo "$percentage * $max_height / 100" | bc)
status_line+="^c$bg^^r${base_x},$((base_y - max_height)),${bar_width},${max_height}^"
local upper_y=$((base_y - bar_height))
status_line+="^c${colors[$state]}^^r$base_x,$upper_y,$bar_width,$bar_height^"
base_x=$((base_x + bar_width + 2))
done
status_line+="^d^^f30^"
echo "{[$status_line][User:$us|Sys:$sy]$top_cpu_consumer]}"
}
get_ram() {
local mem_info=$(free -m)
local total_mem=$(echo "$mem_info" | awk '/^Mem:/ {print $2}')
local used_mem=$(echo "$mem_info" | awk '/^Mem:/ {print $3}')
local mem_usage=$(awk "BEGIN {printf \"%.0f\", ($used_mem/$total_mem)*100}")
local max_height=20
local bar_height=$((max_height * mem_usage / 100))
local bar_width=5
local base_x=$basic_x
local base_y=$basic_y
local color=$color_white
local border=$color_black
local bg=$color_grey
local status_line=""
status_line+="^c$bg^"
status_line+="^r$base_x,$((base_y - max_height)),$((bar_width + 2)),$((max_height + 2))^"
status_line+="^c$color^"
status_line+="^r$((base_x + 1)),$((base_y - bar_height - 1)),${bar_width},${bar_height}^"
status_line+="^d^^f8^"
status_line+="${mem_usage}%"
echo "{[$status_line]}"
}
get_df() {
# Fetch disk usage data
local usage_p2=$(df -h | grep '/dev/nvme0n1p2' | awk '{print $5}' | tr -d '%')
local usage_p4=$(df -h | grep '/dev/nvme0n1p4' | awk '{print $5}' | tr -d '%')
# Safeguard against malformed input
if [[ ! "$usage_p2" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
usage_p2=0
fi
if [[ ! "$usage_p4" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
usage_p4=0
fi
# Base settings for drawing
local base_x=$basic_x
local base_y=$basic_y
local max_height=20
local bar_width=3
local status_line=""
local bg=$color_grey
# Define colors for each partition
declare -A colors=(
[p2]="#FFD700"
[p4]="#FF4500"
)
# Define percentages
local -A usages=(
[p2]=$usage_p2
[p4]=$usage_p4
)
# Create a vertical bar for each partition
for partition in p2 p4; do
local percentage=${usages[$partition]}
local bar_height=$(echo "$percentage * $max_height / 100" | bc)
# Draw the background rectangle for 100% capacity
status_line+="^c$bg^^r${base_x},$((base_y - max_height)),${bar_width},${max_height}^"
# Draw the usage bar on top of the background
local upper_y=$((base_y - bar_height))
status_line+="^c${colors[$partition]}^^r$base_x,$upper_y,$bar_width,$bar_height^"
base_x=$((base_x + bar_width + 2))
done
# Reset formatting and move forward
status_line+="^d^^f10^"
echo "{[$status_line][Sys:$usage_p2%|User:$usage_p4%]}"
}
get_temperature() {
local temp=$(sensors | awk '/Package id 0/ {gsub(/[^0-9.]/, "", $4); print int($4)}')
local max_temp=70
local color=$color_white
local bg=$color_scheme_1
local outline=$color_white
if [ "$temp" -gt "$max_temp" ]; then
color=$color_red
elif [ "$temp" -lt "$max_temp" ]; then
color=$color_green
fi
local fill_height=$(($temp * 10 / $max_temp))
local base_y=$((basic_y - 22))
local temp_icon="^c$outline^"
temp_icon+="^r5,$base_y,4,11^"
temp_icon+="^c$bg^"
temp_icon+="^r6,$((base_y + 4)),2,9^"
temp_icon+="^c$color^"
temp_icon+="^r6,$((base_y + 7 - fill_height)),2,$fill_height^"
temp_icon+="^c$outline^"
temp_icon+="^r4,$((base_y + 8)),7,4^"
temp_icon+="^r5,$((base_y + 9)),5,4^"
temp_icon+="^d^^f10^"
echo "^c$color_white^{[^d^$temp_icon $temp°C^c$color_white^]}^d^"
}
get_battery() {
local status=$(cat /sys/class/power_supply/BAT0/status)
local capacity=$(cat /sys/class/power_supply/BAT0/capacity)
local current_now=$(cat /sys/class/power_supply/BAT0/current_now)
local voltage_now=$(cat /sys/class/power_supply/BAT0/voltage_now)
local power_consumption=$(awk "BEGIN {printf \"%.2f\n\", ($current_now/1000000)*($voltage_now/1000000)}")
local color=$color_scheme_7
local bg=$color_scheme_1
local outline=$color_black
local color_status=$color_white
if [[ "$capacity" -le 15 ]]; then
color=$color_red
shutdown -h now
elif [[ "$capacity" -le 25 ]]; then
color=$color_yellow
else
color=$color_green
fi
local fill_width=$(($capacity * 20 / 100))
local base_y=$((basic_y - 20))
local battery_icon="^c$outline^"
battery_icon+="^r2,$base_y,22,10^"
battery_icon+="^c$bg^"
battery_icon+="^r3,$((base_y +1)),20,8^"
battery_icon+="^c$color^"
battery_icon+="^r3,$((base_y + 1)),$fill_width,8^"
battery_icon+="^c$outline^"
battery_icon+="^r0,$((base_y + 3)),2,4^"
battery_icon+="^d^^f24^"
if [[ "$status" == "Full" ]]; then
status="F"
color_status=$color_green
elif [[ "$status" == "Charging" ]]; then
status="C"
color_status=$c_color_scheme_1
elif [[ "$status" == "Discharging" ]]; then
status="D"
color_status=$color_yellow
elif [[ "$status" == "Not charging" ]]; then
status="NC"
color_status=$color_scheme_4
else
status="NA"
fi
echo "{[$battery_icon^c$color^$capacity^d^%]}"
}
get_wifi() {
local color=$color_black
local bg=$color_grey
local ssid=$(nmcli -t -f active,ssid dev wifi | grep '^yes' | cut -d':' -f2)
ssid="${ssid:-No WiFi}"
ssid="${ssid:0:15}"
local dwm=$(grep wlp0s20f3 /proc/net/wireless | awk '{ print int($4) }')
local signal_normalized=$(( (dwm + 90) * 100 / 60 ))
local signal
if [ $signal_normalized -gt 100 ]; then
signal=100
elif [ $signal_normalized -lt 0 ]; then
signal=0
else
signal=$signal_normalized
fi
local color=$color_white
if [ $signal -ge 66 ]; then
color=$color_green
elif [ $signal -le 33 ]; then
color=$color_red
elif [ $signal -gt 33 ] && [ $signal -lt 66 ]; then
color=$color_yellow
fi
local base_x=$basic_x
local base_y=$((basic_y - 7))
local max_bars=5
local bars_filled=$((signal / 20))
local wifi_icon="^c$color^"
for i in 1 2 3 4 5; do
local width=$((3 * i + 1))
local height=$((3 * i + 1))
local height_placement=$((base_y - height))
if [ $i -le $bars_filled ]; then
wifi_icon+="^c$color^"
else
wifi_icon+="^c$bg^"
fi
wifi_icon+="^r$((base_x + 3 * (i - 1))),$height_placement,$width,$height^"
done
wifi_icon+="^d^^f18^"
echo "{[$wifi_icon$ssid[$signal%]]}"
}
get_screen_width() {
local screen_width_px=$(xdpyinfo | awk '/dimensions:/ {print $2}' | cut -dx -f1)
echo $((screen_width_px / 1))
}
get_status() {
local screen_width=$(get_screen_width)
declare -A components=(
[cpu]="$(get_cpu)"
[ram]="$(get_ram)"
[df]="$(get_df)"
[temperature]="$(get_temperature)"
[battery]="$(get_battery)"
[wifi]="$(get_wifi)"
)
local status_line=""
local separator=""
local total_length=0
local sep_length=${#separator}
for component in date wifi battery temperature df ram cpu; do
local component_output="${components[$component]}"
local component_length=$(( ${#component_output} + sep_length ))
if [[ $((total_length + component_length)) -le $screen_width ]]; then
status_line="${component_output}${status_line}"
total_length=$((total_length + component_length))
else
echo "Skipped: $component due to space constraints"
fi
done
echo "$status_line"
}
while true; do
xsetroot -name "$(get_status)"
sleep 1
done

View File

@@ -0,0 +1,233 @@
#!/usr/bin/env bash
# Source color vars
source /home/klein/DynamicWindowManager/customstatusbar/statusbars/colorvars.sh
# Define Basic Dimentions
base_x=0
base_y=2
max_height=15
bar_width=3
gap=1
cpu() {
local cpu_line1=$(grep '^cpu ' /proc/stat)
sleep 2
local cpu_line2=$(grep '^cpu ' /proc/stat)
local -a cpu1=(${cpu_line1//cpu/})
local -a cpu2=(${cpu_line2//cpu/})
local total1=0
local total2=0
local idle1=${cpu1[3]}
local idle2=${cpu2[3]}
for i in "${cpu1[@]}"; do
total1=$((total1 + i))
done
for i in "${cpu2[@]}"; do
total2=$((total2 + i))
done
local total_delta=$((total2 - total1))
local idle_delta=$((idle2 - idle1))
local usage=$((100 * (total_delta - idle_delta) / total_delta))
local usage_height=$(( (max_height * usage) / 100 ))
local usage_y=$((base_y + max_height - usage_height))
local color=$white
if [ $usage -gt 50 ]; then
color=$red
fi
local status_line=""
status_line+="^c${grey}^^r${base_x},${base_y},${bar_width},${max_height}^"
status_line+="^c${color}^^r${base_x},${usage_y},${bar_width},${usage_height}^"
status_line+="^d^^f4^" # buffer of 1
# local topcon=$( ps -eo %cpu,comm --sort=-%cpu | head -n 2 | tail -n 1 | awk '{print $2}')
# topcon="${topcon:0:5}" # trunkate output
echo "{CPU:${status_line}${usage}%"
}
ram() {
local m_mem=$(free -m)
local t_mem=$(echo "$m_mem" | awk '/^Mem:/ {print $2}')
local u_mem=$(echo "$m_mem" | awk '/^Mem:/ {print $3}')
local p_mem=$(awk "BEGIN {printf \"%.0f\", ($u_mem/$t_mem)*100}")
local usage_height=$((max_height * p_mem / 100))
local usage_y=$((base_y + max_height - usage_height))
local status_line=""
status_line+="^c$grey^^r$base_x,${base_y},${bar_width},${max_height}^"
status_line+="^c$white^^r${base_x},${usage_y},${bar_width},${usage_height}^"
status_line+="^d^^f4^" # buffer of 1
status_line+="${p_mem}%"
echo "M:$status_line"
}
swap() {
local m_swap=$(free -m)
local t_swap=$(echo "$m_swap" | awk '/^Swap:/ {print $2}')
local u_swap=$(echo "$m_swap" | awk '/^Swap:/ {print $3}')
if [[ "$u_swap" -eq 0 ]]; then
return
fi
local p_swap=$(awk "BEGIN {printf \"%.0f\", ($u_swap/$t_swap)*100}")
local usage_height=$((max_height * u_swap / 100))
local usage_y=$((base_y + max_height - usage_height))
local status_line=""
status_line+="^c$grey^^r$base_x,${base_y},${bar_width},${max_height}^"
status_line+="^c$white^^r${base_x},${usage_y},${bar_width},${usage_height}^"
status_line+="^d^^f4^" # buffer of 1
status_line+="${p_swap}%"
echo "|S:$status_line"
}
disk() {
local usage_p2=$(df -h | grep '/dev/mmcblk0p2' | awk '{print $5}' | tr -d '%')
local usage_p4=$(df -h | grep '/dev/mmcblk0p1' | awk '{print $5}' | tr -d '%')
if [[ ! "$usage_p2" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
usage_p2=0
fi
if [[ ! "$usage_p4" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
usage_p4=0
fi
local status_line=""
local -A usages=(
[p2]=$usage_p2
[p4]=$usage_p4
)
for partition in p2 p4; do
local percentage=${usages[$partition]}
local usage_height=$(($percentage * $max_height / 100))
local usage_y=$((base_y + max_height - usage_height))
status_line+="^c$grey^^r${base_x},${base_y},${bar_width},${max_height}^"
status_line+="^c$white^^r${base_x},${usage_y},${bar_width},${usage_height}^"
base_x=$((base_x + bar_width + gap))
done
status_line+="^d^^f8^" #Buffer of 1
echo "DF:${status_line}R:${usage_p2}%-U:${usage_p4}%"
}
cpu_temperature(){
local temp=$(awk '{print int($1 / 1000)}' /sys/class/thermal/thermal_zone0/temp)
local max_temp=80
local color=$white
if [ "$temp" -gt "$max_temp" ]; then
color=$red
elif [ "$temp" -lt "$max_temp" ]; then
color=$green
fi
local adj_y=5
local usage_height=$(($temp * $max_height / $max_temp))
local usage_y=$((adj_y + 10 - usage_height))
local temp_icon="^c$black^"
temp_icon+="^r5,14,8,5^" #two rectangles
temp_icon+="^r6,16,6,5^" #to mimic a circle
temp_icon+="^r7,${base_y},4,${max_height}^" #BG bar
temp_icon+="^c$color^"
temp_icon+="^r8,${usage_y},2,${usage_height}^" #C bar
temp_icon+="^d^^f16^" #Buffer of 1
echo "${temp_icon}${temp}°C"
}
battery() {
local throttled=$(cat /sys/devices/platform/soc/soc:firmware/get_throttled)
local capacity=0
local status=""
if [ $((throttled & 0x1)) -ne 0 ]; then
status+="Under-voltage detected"
fi
if [ $((throttled & 0x2)) -ne 0 ]; then
status+="ARM frequency capped"
fi
if [ $((throttled & 0x4)) -ne 0 ]; then
status+="Currently throttled"
fi
if [ $((throttled & 0x8)) -ne 0 ]; then
status+="Soft temperature limit active"
fi
if [ $((throttled & 0x10000)) -ne 0 ]; then
status+="Under-voltage has occurred since last reboot"
fi
if [ $((throttled & 0x20000)) -ne 0 ]; then
status+="ARM frequency capped has occurred since last reboot"
fi
if [ $((throttled & 0x40000)) -ne 0 ]; then
status+="Throttling has occurred since last reboot"
fi
if [ $((throttled & 0x80000)) -ne 0 ]; then
status+="Soft temperature limit has occurred since last reboot"
fi
if [ "$throttled" -eq 0 ]; then
status+="No issues detected"
capacity=100
fi
# Check the core voltage using vcgencmd
local volt=$(vcgencmd measure_volts core | awk -F'=' '{print $2}')
local fill_width=$(($capacity * 9 / 100)) # corresponds to width of bar
local battery_icon="^c$black^"
battery_icon+="^r1,8,13,8^"
battery_icon+="^c$grey^"
battery_icon+="^r3,10,9,4^"
battery_icon+="^c$green^"
battery_icon+="^r3,10,$fill_width,4^"
battery_icon+="^c$black^"
battery_icon+="^r14,9,2,4^"
battery_icon+="^d^^f17^" #Buffer of 1
echo "${battery_icon}${volt}"
}
wifi() {
local iface=$(ip -o link show | grep -v "lo:" | awk -F': ' '{print $2}');
local ssid=$(nmcli -t -f active,ssid dev wifi | grep '^yes' | cut -d':' -f2)
ssid="${ssid:-No WiFi}"
ssid="${ssid:0:5}"
local dwm=$(grep "$iface" /proc/net/wireless | awk '{ print int($4) }')
if [ "$ssid" = "No WiFi" ]; then
local signal=0
else
local signal_normalized=$(( (dwm + 90) * 100 / 60 ))
if [ $signal_normalized -gt 100 ]; then
signal=100
elif [ $signal_normalized -lt 0 ]; then
signal=0
else
signal=$signal_normalized
fi
fi
local color=$white
if [ $signal -ge 66 ]; then
color=$green
elif [ $signal -le 33 ]; then
color=$red
elif [ $signal -gt 33 ] && [ $signal -lt 66 ]; then
color=$yellow
fi
local max_bars=5
local bars_filled=$((signal / 20))
local wifi_icon="^c$color^"
for i in 1 2 3 4 5; do
local width=$(( (3 * i) ))
local height=$(( (3 * i) ))
local adj_y=$((max_height - height + 2))
if [ $i -le $bars_filled ]; then
wifi_icon+="^c$color^"
else
wifi_icon+="^c$grey^"
fi
wifi_icon+="^r$((base_x + 2 * ( i - 3 ))),$((adj_y + 2)),$width,$height^"
done
wifi_icon+="^d^^f7^"
echo " ${wifi_icon}${ssid} ${signal}%}"
}
status(){
echo "$(cpu)|$(ram)|$(swap)$(disk)|$(cpu_temperature)|$(battery)|$(wifi)"
}
while true; do
DISPLAY=:0
xsetroot -name "$(status)"
done

View File

@@ -0,0 +1,51 @@
#!/bin/bash
icon_name="/usr/share/icons/Adwaita/16x16/status/display-brightness-symbolic.symbolic.png"
# Persistent loop to handle the system tray icon
while true
do
# Command to keep the icon in the systray and open the dialog on click
yad --notification --image="$icon_name" \
--command="bash -c '\
while : ; do \
current_brightness=\$(brightnessctl get 2>/dev/null); \
max_brightness=\$(brightnessctl max 2>/dev/null); \
brightness_percent=\$((current_brightness * 100 / max_brightness)); \
command_output=\$(yad --title \"Brightness Control\" --width=300 --height=150 --posx=810 --posy=575 \
--form --separator=\",\" --field=\"Set Brightness (0-100):NUM\" \"\$brightness_percent\"!0..100!1 \
--scale --value=\$brightness_percent --min-value=0 --max-value=100 --step=1 \
--button=\"Increase Brightness\":1 --button=\"Decrease Brightness\":2 --button=gtk-ok:0 --button=gtk-cancel:3 \
--fixed --undecorated --on-top --skip-taskbar --skip-pager 2>/dev/null); \
ret=\$?; \
case \$ret in \
0) \
new_brightness=\$(echo \$command_output | cut -d ',' -f 1); \
brightnessctl set \$new_brightness% > /dev/null 2>&1; \
break;; \
1) \
current_brightness=\$(brightnessctl get 2>/dev/null); \
max_brightness=\$(brightnessctl max 2>/dev/null); \
brightness_percent=\$((current_brightness * 100 / max_brightness)); \
new_brightness=\$((brightness_percent + 10)); \
[ \$new_brightness -gt 100 ] && new_brightness=100; \
brightnessctl set \$new_brightness% > /dev/null 2>&1; \
continue;; \
2) \
current_brightness=\$(brightnessctl get 2>/dev/null); \
max_brightness=\$(brightnessctl max 2>/dev/null); \
brightness_percent=\$((current_brightness * 100 / max_brightness)); \
new_brightness=\$((brightness_percent - 10)); \
[ \$new_brightness -lt 0 ] && new_brightness=0; \
brightnessctl set \$new_brightness% > /dev/null 2>&1; \
continue;; \
3) \
break;; \
*) \
break;; \
esac; \
done'"
# Sleep to ensure it doesn't respawn too quickly if closed
sleep 0.5
done

View File

@@ -0,0 +1,37 @@
#!/bin/bash
icon_name="/usr/share/icons/Adwaita/16x16/status/display-brightness-symbolic.symbolic.png"
# Persistent loop to handle the system tray icon
while true
do
# Command to keep the icon in the systray and open the dialog on click
yad --notification --image="$icon_name" \
--command="bash -c '\
while : ; do \
current_brightness=\$(brightnessctl get 2>/dev/null); \
max_brightness=\$(brightnessctl max 2>/dev/null); \
brightness_percent=\$((current_brightness * 100 / max_brightness)); \
command_output=\$(yad --title \"Brightness Control\" --width=300 --height=50 --posx=810 --posy=575 \
--form --separator=\",\" --field=\"Set Brightness (0-100):NUM\" \"\$brightness_percent\"!0..100!1 \
--button=\"Apply\":0 --button=\"Increase Brightness:1\" --button=\"Decrease Brightness:2\" --button=gtk-cancel:3 \
--fixed --undecorated --on-top --skip-taskbar --skip-pager 2>/dev/null); \
ret=\$?; \
case \$ret in \
0) \
new_brightness=\$(echo \$command_output | cut -d ',' -f 1); \
brightnessctl set \$new_brightness% > /dev/null 2>&1;; \
1) \
brightnessctl set +10% > /dev/null 2>&1;; \
2) \
brightnessctl set 10%- > /dev/null 2>&1;; \
3) \
break;; \
*) \
break;; \
esac; \
done'"
# Sleep to ensure it doesn't respawn too quickly if closed
sleep 0.5
done

View File

@@ -0,0 +1,17 @@
#!/usr/bin/env bash
# Icon path
icon_path="/usr/share/icons/Adwaita/16x16/devices/display-symbolic.symbolic.png"
# Persistent loop to handle the system tray icon
while true; do
yad --notification --image="$icon_path" \
--command="bash -c 'if pgrep -x conky > /dev/null; then killall conky; else conky & disown; fi'" &
# Wait for the tray icon to be closed
wait $!
# Sleep to ensure it doesn't respawn too quickly if closed
sleep 2
done

View File

@@ -0,0 +1,43 @@
#!/bin/bash
# Icon path
icon_path="/usr/share/icons/Adwaita/16x16/devices/camera-photo-symbolic.symbolic.png"
# Directory to save screenshots
screenshot_dir="/home/klein/Pictures/screenshots"
export screenshot_dir # Export the directory path
# Ensure directory exists
mkdir -p "$screenshot_dir"
# Persistent loop to handle the system tray icon
while true; do
yad --notification --image="$icon_path" \
--command="bash -c '\
while :; do \
yad --title \"Screenshot Tool\" --width=300 --height=50 \
--button=\"Full Screen:0\" --button=\"Select Window:1\" --button=\"Cancel:2\" \
--center; \
ret=\$?; \
counter=1; \
while true; do \
file_path=\"\$screenshot_dir/Screenshot_\${counter}.png\"; \
if [[ ! -f \"\$file_path\" ]]; then \
break; \
fi; \
((counter++)); \
done; \
case \$ret in \
0) \
scrot \"\$file_path\"; \
break; ;; \
1) \
scrot -s \"\$file_path\"; \
break; ;; \
2|*) \
break; ;; \
esac; \
done'" \
# Sleep to ensure it doesn't respawn too quickly if closed
sleep 2
done

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,25 +0,0 @@
MIT/X Consortium License
© 2015-2016 Markus Teich <markus.teich@stusta.mhn.de>
© 2014 Dimitris Papastamos <sin@2f30.org>
© 2006-2014 Anselm R Garbe <anselm@garbe.us>
© 2014-2016 Laslo Hunhold <dev@frign.de>
© 2016-2023 Hiltjo Posthuma <hiltjo@codemadness.org>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@@ -1,46 +0,0 @@
# slock - simple screen locker
# See LICENSE file for copyright and license details.
include config.mk
SRC = slock.c ${COMPATSRC}
OBJ = ${SRC:.c=.o}
all: slock
.c.o:
${CC} -c ${CFLAGS} $<
${OBJ}: config.h config.mk arg.h util.h
config.h:
cp config.def.h $@
slock: ${OBJ}
${CC} -o $@ ${OBJ} ${LDFLAGS}
clean:
rm -f slock ${OBJ} slock-${VERSION}.tar.gz
dist: clean
mkdir -p slock-${VERSION}
cp -R LICENSE Makefile README slock.1 config.mk \
${SRC} config.def.h arg.h util.h slock-${VERSION}
tar -cf slock-${VERSION}.tar slock-${VERSION}
gzip slock-${VERSION}.tar
rm -rf slock-${VERSION}
install: all
mkdir -p ${DESTDIR}${PREFIX}/bin
cp -f slock ${DESTDIR}${PREFIX}/bin
chmod 755 ${DESTDIR}${PREFIX}/bin/slock
chmod u+s ${DESTDIR}${PREFIX}/bin/slock
mkdir -p ${DESTDIR}${MANPREFIX}/man1
sed "s/VERSION/${VERSION}/g" <slock.1 >${DESTDIR}${MANPREFIX}/man1/slock.1
chmod 644 ${DESTDIR}${MANPREFIX}/man1/slock.1
uninstall:
rm -f ${DESTDIR}${PREFIX}/bin/slock
rm -f ${DESTDIR}${MANPREFIX}/man1/slock.1
.PHONY: all clean dist install uninstall

View File

@@ -1,24 +0,0 @@
slock - simple screen locker
============================
simple screen locker utility for X.
Requirements
------------
In order to build slock you need the Xlib header files.
Installation
------------
Edit config.mk to match your local setup (slock is installed into
the /usr/local namespace by default).
Afterwards enter the following command to build and install slock
(if necessary as root):
make clean install
Running slock
-------------
Simply invoke the 'slock' command. To get out of it, enter your password.

View File

@@ -1,65 +0,0 @@
/*
* Copy me if you can.
* by 20h
*/
#ifndef ARG_H__
#define ARG_H__
extern char *argv0;
/* use main(int argc, char *argv[]) */
#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\
argv[0] && argv[0][0] == '-'\
&& argv[0][1];\
argc--, argv++) {\
char argc_;\
char **argv_;\
int brk_;\
if (argv[0][1] == '-' && argv[0][2] == '\0') {\
argv++;\
argc--;\
break;\
}\
for (brk_ = 0, argv[0]++, argv_ = argv;\
argv[0][0] && !brk_;\
argv[0]++) {\
if (argv_ != argv)\
break;\
argc_ = argv[0][0];\
switch (argc_)
/* Handles obsolete -NUM syntax */
#define ARGNUM case '0':\
case '1':\
case '2':\
case '3':\
case '4':\
case '5':\
case '6':\
case '7':\
case '8':\
case '9'
#define ARGEND }\
}
#define ARGC() argc_
#define ARGNUMF() (brk_ = 1, estrtonum(argv[0], 0, INT_MAX))
#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\
((x), abort(), (char *)0) :\
(brk_ = 1, (argv[0][1] != '\0')?\
(&argv[0][1]) :\
(argc--, argv++, argv[0])))
#define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\
(char *)0 :\
(brk_ = 1, (argv[0][1] != '\0')?\
(&argv[0][1]) :\
(argc--, argv++, argv[0])))
#define LNGARG() &argv[0][0]
#endif

View File

@@ -1,12 +0,0 @@
/* user and group to drop privileges to */
static const char *user = "nobody";
static const char *group = "nogroup";
static const char *colorname[NUMCOLS] = {
[INIT] = "black", /* after initialization */
[INPUT] = "#005577", /* during input */
[FAILED] = "#CC3333", /* wrong password */
};
/* treat a cleared input like a wrong password (color) */
static const int failonclear = 1;

View File

@@ -1,12 +0,0 @@
/* user and group to drop privileges to */
static const char *user = "nobody";
static const char *group = "nogroup";
static const char *colorname[NUMCOLS] = {
[INIT] = "black", /* after initialization */
[INPUT] = "#005577", /* during input */
[FAILED] = "#CC3333", /* wrong password */
};
/* treat a cleared input like a wrong password (color) */
static const int failonclear = 1;

View File

@@ -1,29 +0,0 @@
# slock version
VERSION = 1.5
# Customize below to fit your system
# paths
PREFIX = /usr/local
MANPREFIX = ${PREFIX}/share/man
X11INC = /usr/X11R6/include
X11LIB = /usr/X11R6/lib
# includes and libs
INCS = -I. -I/usr/include -I${X11INC}
LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr
# flags
CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H
CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
LDFLAGS = -s ${LIBS}
COMPATSRC = explicit_bzero.c
# On OpenBSD and Darwin remove -lcrypt from LIBS
#LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -lXext -lXrandr
# On *BSD remove -DHAVE_SHADOW_H from CPPFLAGS
# On NetBSD add -D_NETBSD_SOURCE to CPPFLAGS
#CPPFLAGS = -DVERSION=\"${VERSION}\" -D_BSD_SOURCE -D_NETBSD_SOURCE
# On OpenBSD set COMPATSRC to empty
#COMPATSRC =

View File

@@ -1,19 +0,0 @@
/* $OpenBSD: explicit_bzero.c,v 1.3 2014/06/21 02:34:26 matthew Exp $ */
/*
* Public domain.
* Written by Matthew Dempsky.
*/
#include <string.h>
__attribute__((weak)) void
__explicit_bzero_hook(void *buf, size_t len)
{
}
void
explicit_bzero(void *buf, size_t len)
{
memset(buf, 0, len);
__explicit_bzero_hook(buf, len);
}

Binary file not shown.

Binary file not shown.

View File

@@ -1,45 +0,0 @@
.Dd October 6, 2023
.Dt SLOCK 1
.Os
.Sh NAME
.Nm slock
.Nd simple X screen locker
.Sh SYNOPSIS
.Nm
.Op Fl v
.Op Ar cmd Op Ar arg ...
.Sh DESCRIPTION
.Nm
is a simple X screen locker.
If provided,
.Ar cmd
is executed after the screen has been locked.
.Pp
The options are as follows:
.Bl -tag -width Ds
.It Fl v
Print version information to stdout and exit.
.El
.Sh EXIT STATUS
.Ex -std
.Sh EXAMPLES
$
.Nm
/usr/sbin/s2ram
.Sh SECURITY CONSIDERATIONS
To make sure a locked screen can not be bypassed by switching VTs
or killing the X server with Ctrl+Alt+Backspace, it is recommended
to disable both in
.Xr xorg.conf 5
for maximum security:
.Bd -literal
Section "ServerFlags"
Option "DontVTSwitch" "True"
Option "DontZap" "True"
EndSection
.Ed
.Sh CUSTOMIZATION
.Nm
can be customized by creating a custom config.h from config.def.h and
(re)compiling the source code.
This keeps it fast, secure and simple.

View File

@@ -1,395 +0,0 @@
/* See LICENSE file for license details. */
#define _XOPEN_SOURCE 500
#if HAVE_SHADOW_H
#include <shadow.h>
#endif
#include <ctype.h>
#include <errno.h>
#include <grp.h>
#include <pwd.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <X11/extensions/Xrandr.h>
#include <X11/keysym.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "arg.h"
#include "util.h"
char *argv0;
enum {
INIT,
INPUT,
FAILED,
NUMCOLS
};
struct lock {
int screen;
Window root, win;
Pixmap pmap;
unsigned long colors[NUMCOLS];
};
struct xrandr {
int active;
int evbase;
int errbase;
};
#include "config.h"
static void
die(const char *errstr, ...)
{
va_list ap;
va_start(ap, errstr);
vfprintf(stderr, errstr, ap);
va_end(ap);
exit(1);
}
#ifdef __linux__
#include <fcntl.h>
#include <linux/oom.h>
static void
dontkillme(void)
{
FILE *f;
const char oomfile[] = "/proc/self/oom_score_adj";
if (!(f = fopen(oomfile, "w"))) {
if (errno == ENOENT)
return;
die("slock: fopen %s: %s\n", oomfile, strerror(errno));
}
fprintf(f, "%d", OOM_SCORE_ADJ_MIN);
if (fclose(f)) {
if (errno == EACCES)
die("slock: unable to disable OOM killer. "
"Make sure to suid or sgid slock.\n");
else
die("slock: fclose %s: %s\n", oomfile, strerror(errno));
}
}
#endif
static const char *
gethash(void)
{
const char *hash;
struct passwd *pw;
/* Check if the current user has a password entry */
errno = 0;
if (!(pw = getpwuid(getuid()))) {
if (errno)
die("slock: getpwuid: %s\n", strerror(errno));
else
die("slock: cannot retrieve password entry\n");
}
hash = pw->pw_passwd;
#if HAVE_SHADOW_H
if (!strcmp(hash, "x")) {
struct spwd *sp;
if (!(sp = getspnam(pw->pw_name)))
die("slock: getspnam: cannot retrieve shadow entry. "
"Make sure to suid or sgid slock.\n");
hash = sp->sp_pwdp;
}
#else
if (!strcmp(hash, "*")) {
#ifdef __OpenBSD__
if (!(pw = getpwuid_shadow(getuid())))
die("slock: getpwnam_shadow: cannot retrieve shadow entry. "
"Make sure to suid or sgid slock.\n");
hash = pw->pw_passwd;
#else
die("slock: getpwuid: cannot retrieve shadow entry. "
"Make sure to suid or sgid slock.\n");
#endif /* __OpenBSD__ */
}
#endif /* HAVE_SHADOW_H */
return hash;
}
static void
readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
const char *hash)
{
XRRScreenChangeNotifyEvent *rre;
char buf[32], passwd[256], *inputhash;
int num, screen, running, failure, oldc;
unsigned int len, color;
KeySym ksym;
XEvent ev;
len = 0;
running = 1;
failure = 0;
oldc = INIT;
while (running && !XNextEvent(dpy, &ev)) {
if (ev.type == KeyPress) {
explicit_bzero(&buf, sizeof(buf));
num = XLookupString(&ev.xkey, buf, sizeof(buf), &ksym, 0);
if (IsKeypadKey(ksym)) {
if (ksym == XK_KP_Enter)
ksym = XK_Return;
else if (ksym >= XK_KP_0 && ksym <= XK_KP_9)
ksym = (ksym - XK_KP_0) + XK_0;
}
if (IsFunctionKey(ksym) ||
IsKeypadKey(ksym) ||
IsMiscFunctionKey(ksym) ||
IsPFKey(ksym) ||
IsPrivateKeypadKey(ksym))
continue;
switch (ksym) {
case XK_Return:
passwd[len] = '\0';
errno = 0;
if (!(inputhash = crypt(passwd, hash)))
fprintf(stderr, "slock: crypt: %s\n", strerror(errno));
else
running = !!strcmp(inputhash, hash);
if (running) {
XBell(dpy, 100);
failure = 1;
}
explicit_bzero(&passwd, sizeof(passwd));
len = 0;
break;
case XK_Escape:
explicit_bzero(&passwd, sizeof(passwd));
len = 0;
break;
case XK_BackSpace:
if (len)
passwd[--len] = '\0';
break;
default:
if (num && !iscntrl((int)buf[0]) &&
(len + num < sizeof(passwd))) {
memcpy(passwd + len, buf, num);
len += num;
}
break;
}
color = len ? INPUT : ((failure || failonclear) ? FAILED : INIT);
if (running && oldc != color) {
for (screen = 0; screen < nscreens; screen++) {
XSetWindowBackground(dpy,
locks[screen]->win,
locks[screen]->colors[color]);
XClearWindow(dpy, locks[screen]->win);
}
oldc = color;
}
} else if (rr->active && ev.type == rr->evbase + RRScreenChangeNotify) {
rre = (XRRScreenChangeNotifyEvent*)&ev;
for (screen = 0; screen < nscreens; screen++) {
if (locks[screen]->win == rre->window) {
if (rre->rotation == RR_Rotate_90 ||
rre->rotation == RR_Rotate_270)
XResizeWindow(dpy, locks[screen]->win,
rre->height, rre->width);
else
XResizeWindow(dpy, locks[screen]->win,
rre->width, rre->height);
XClearWindow(dpy, locks[screen]->win);
break;
}
}
} else {
for (screen = 0; screen < nscreens; screen++)
XRaiseWindow(dpy, locks[screen]->win);
}
}
}
static struct lock *
lockscreen(Display *dpy, struct xrandr *rr, int screen)
{
char curs[] = {0, 0, 0, 0, 0, 0, 0, 0};
int i, ptgrab, kbgrab;
struct lock *lock;
XColor color, dummy;
XSetWindowAttributes wa;
Cursor invisible;
if (dpy == NULL || screen < 0 || !(lock = malloc(sizeof(struct lock))))
return NULL;
lock->screen = screen;
lock->root = RootWindow(dpy, lock->screen);
for (i = 0; i < NUMCOLS; i++) {
XAllocNamedColor(dpy, DefaultColormap(dpy, lock->screen),
colorname[i], &color, &dummy);
lock->colors[i] = color.pixel;
}
/* init */
wa.override_redirect = 1;
wa.background_pixel = lock->colors[INIT];
lock->win = XCreateWindow(dpy, lock->root, 0, 0,
DisplayWidth(dpy, lock->screen),
DisplayHeight(dpy, lock->screen),
0, DefaultDepth(dpy, lock->screen),
CopyFromParent,
DefaultVisual(dpy, lock->screen),
CWOverrideRedirect | CWBackPixel, &wa);
lock->pmap = XCreateBitmapFromData(dpy, lock->win, curs, 8, 8);
invisible = XCreatePixmapCursor(dpy, lock->pmap, lock->pmap,
&color, &color, 0, 0);
XDefineCursor(dpy, lock->win, invisible);
/* Try to grab mouse pointer *and* keyboard for 600ms, else fail the lock */
for (i = 0, ptgrab = kbgrab = -1; i < 6; i++) {
if (ptgrab != GrabSuccess) {
ptgrab = XGrabPointer(dpy, lock->root, False,
ButtonPressMask | ButtonReleaseMask |
PointerMotionMask, GrabModeAsync,
GrabModeAsync, None, invisible, CurrentTime);
}
if (kbgrab != GrabSuccess) {
kbgrab = XGrabKeyboard(dpy, lock->root, True,
GrabModeAsync, GrabModeAsync, CurrentTime);
}
/* input is grabbed: we can lock the screen */
if (ptgrab == GrabSuccess && kbgrab == GrabSuccess) {
XMapRaised(dpy, lock->win);
if (rr->active)
XRRSelectInput(dpy, lock->win, RRScreenChangeNotifyMask);
XSelectInput(dpy, lock->root, SubstructureNotifyMask);
return lock;
}
/* retry on AlreadyGrabbed but fail on other errors */
if ((ptgrab != AlreadyGrabbed && ptgrab != GrabSuccess) ||
(kbgrab != AlreadyGrabbed && kbgrab != GrabSuccess))
break;
usleep(100000);
}
/* we couldn't grab all input: fail out */
if (ptgrab != GrabSuccess)
fprintf(stderr, "slock: unable to grab mouse pointer for screen %d\n",
screen);
if (kbgrab != GrabSuccess)
fprintf(stderr, "slock: unable to grab keyboard for screen %d\n",
screen);
return NULL;
}
static void
usage(void)
{
die("usage: slock [-v] [cmd [arg ...]]\n");
}
int
main(int argc, char **argv) {
struct xrandr rr;
struct lock **locks;
struct passwd *pwd;
struct group *grp;
uid_t duid;
gid_t dgid;
const char *hash;
Display *dpy;
int s, nlocks, nscreens;
ARGBEGIN {
case 'v':
puts("slock-"VERSION);
return 0;
default:
usage();
} ARGEND
/* validate drop-user and -group */
errno = 0;
if (!(pwd = getpwnam(user)))
die("slock: getpwnam %s: %s\n", user,
errno ? strerror(errno) : "user entry not found");
duid = pwd->pw_uid;
errno = 0;
if (!(grp = getgrnam(group)))
die("slock: getgrnam %s: %s\n", group,
errno ? strerror(errno) : "group entry not found");
dgid = grp->gr_gid;
#ifdef __linux__
dontkillme();
#endif
hash = gethash();
errno = 0;
if (!crypt("", hash))
die("slock: crypt: %s\n", strerror(errno));
if (!(dpy = XOpenDisplay(NULL)))
die("slock: cannot open display\n");
/* drop privileges */
if (setgroups(0, NULL) < 0)
die("slock: setgroups: %s\n", strerror(errno));
if (setgid(dgid) < 0)
die("slock: setgid: %s\n", strerror(errno));
if (setuid(duid) < 0)
die("slock: setuid: %s\n", strerror(errno));
/* check for Xrandr support */
rr.active = XRRQueryExtension(dpy, &rr.evbase, &rr.errbase);
/* get number of screens in display "dpy" and blank them */
nscreens = ScreenCount(dpy);
if (!(locks = calloc(nscreens, sizeof(struct lock *))))
die("slock: out of memory\n");
for (nlocks = 0, s = 0; s < nscreens; s++) {
if ((locks[s] = lockscreen(dpy, &rr, s)) != NULL)
nlocks++;
else
break;
}
XSync(dpy, 0);
/* did we manage to lock everything? */
if (nlocks != nscreens)
return 1;
/* run post-lock command */
if (argc > 0) {
switch (fork()) {
case -1:
die("slock: fork failed: %s\n", strerror(errno));
case 0:
if (close(ConnectionNumber(dpy)) < 0)
die("slock: close: %s\n", strerror(errno));
execvp(argv[0], argv);
fprintf(stderr, "slock: execvp %s: %s\n", argv[0], strerror(errno));
_exit(1);
}
}
/* everything is now blank. Wait for the correct password */
readpw(dpy, &rr, locks, nscreens, hash);
return 0;
}

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More