add plenty of comments to spmenu

This commit is contained in:
speedie 2023-03-31 12:42:15 +02:00
parent 4e01d87818
commit 6ac2afb240
15 changed files with 252 additions and 189 deletions

1
TODO
View file

@ -7,3 +7,4 @@
- Use cairo for text drawing over Xft
- MAYBE wayland support, but only if it doesn't require writing any extra code which as of now seems unlikely
- Write documentation about profiles
- FIFO, used to dynamically refresh

View file

@ -509,6 +509,6 @@ setcolumns(const Arg *arg)
void
setprofile(const Arg *arg)
{
int ax = system("command -v spmenu_profile > /dev/null && spmenu_profile --spmenu-set-profile > /dev/null");
exit(ax);
// this just runs an external shell script to set the profile
exit(system("command -v spmenu_profile > /dev/null && spmenu_profile --spmenu-set-profile > /dev/null"));
}

View file

@ -1,8 +1,8 @@
typedef union {
int i;
unsigned int ui;
float f;
const void *v;
int i; // integer
unsigned int ui; // unsigned int
float f; // float
const void *v; // void
} Arg;
// declare keybind functions

View file

@ -6,7 +6,8 @@ readargs(int argc, char *argv[])
int cxrdb = 0;
// check if we should load the xrdb/config, because it needs to be loaded before arguments are checked (internal -> xresources -> arguments)
// check if we should load the xrdb/config, because it needs to be loaded before arguments are checked
// priority: internal -> xresources -> arguments
for (j = 1; j < argc; j++) {
if (!strcmp(argv[j], "-xrdb") || (!strcmp(argv[j], "--xrdb"))) {
xresources = 1;
@ -23,16 +24,19 @@ readargs(int argc, char *argv[])
}
}
// TODO: improve this function significantly
// init/read xrdb
if (xresources) {
XrmInitialize();
// also load config/profile if .Xresources
if (loadconfig) {
cxrdb = system("command -v spmenu_profile > /dev/null && spmenu_profile --spmenu-load-default-profile > /dev/null");
}
// avoid an annoying warning gcc will spit out when you don't care about the result
if (!cxrdb || cxrdb || xresources) load_xresources();
if (!cxrdb||cxrdb) // load .Xresources, cxrdb is only here to avoid an annoying gcc warning
load_xresources();
}
// no arguments

View file

@ -1,8 +1,11 @@
void
prepare_window_size(void)
{
// set horizontal and vertical padding
sp = menupaddingh;
vp = (menuposition == 1) ? menupaddingv : - menupaddingv;
return;
}
void
@ -13,7 +16,12 @@ create_window(int x, int y, int w, int h)
swa.override_redirect = managed ? False : True;
swa.background_pixel = 0;
swa.colormap = cmap;
swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask | ButtonPressMask | PointerMotionMask;
swa.event_mask =
ExposureMask | // mapping the drawing
KeyPressMask | // keypresses
VisibilityChangeMask | // whether or not client is visible
ButtonPressMask | // see buttonpress in libs/mouse.c for usage
PointerMotionMask; // we need pointer for selecting entries using the mouse
// create client
win = XCreateWindow(dpy, parentwin, x, y, w, h, borderwidth,
@ -29,17 +37,17 @@ set_window(void)
{
XClassHint ch = { class, class };
// set border and class
XSetWindowBorder(dpy, win, scheme[SchemeBorder][ColBg].pixel);
XSetClassHint(dpy, win, &ch);
return;
}
void
set_prop(void)
{
XChangeProperty(dpy, win, types, XA_ATOM, 32, PropModeReplace, (unsigned char *) &dock, 1);
// TODO: add toggle for this
XChangeProperty(dpy, win, types, XA_ATOM, 32, PropModeReplace, (unsigned char *) &dock, 1); // set dock property
return;
}
@ -58,17 +66,18 @@ resizeclient(void)
lines = MIN(itemCount, MAX(lines, 0));
reallines = lines;
// resize client to image height
#if USEIMAGE
if (image)
resizetoimageheight(imageheight);
if (image) resizetoimageheight(imageheight);
#endif
mh = (lines + 1) * bh;
// why have an empty line?
// why have an empty line? when there's nothing to draw there anyway?
if (hideprompt && hideinput && hidemode && hidematchcount)
mh += bh;
// no window/invalid window or menu height we had before is the same as the current window height
if (!win || omh == mh) return;
XResizeWindow(dpy, win, mw, mh);

View file

@ -1,4 +1,4 @@
// color scheme arrays
// alpha array
static unsigned int alphas[][3] = {
// fg bg border
[SchemeLArrow] = { fgalpha, bgalpha, borderalpha },
@ -18,6 +18,7 @@ static unsigned int alphas[][3] = {
[SchemeBorder] = { fgalpha, bgalpha, borderalpha },
};
// colorscheme array
static char *colors[SchemeLast][2] = {
// fg bg
[SchemeLArrow] = { col_larrowfg, col_larrowbg },
@ -37,7 +38,7 @@ static char *colors[SchemeLast][2] = {
[SchemeBorder] = { NULL, col_bordercolor },
};
// sgr colors
// sgr color array
// to enable 256 color support, append to this.
static char *textcolors[] = {
col_sgrcolor0,

View file

@ -14,7 +14,7 @@
// item
#define MAXITEMLENGTH 1024
// user friendly names for all the modifiers
// user friendly names for all the modifiers we're using, but there are many more
#define CONTROL ControlMask
#define SHIFT ShiftMask
#define ALT Mod1Mask

View file

@ -389,6 +389,8 @@ drawmenu(void)
if (!hideinput) x = drawinput(x, y, w);
if (!hidemode) modeWidth = pango_mode ? TEXTWM(modetext) : TEXTW(modetext);
// draw the items, this function also calls drawrarrow() and drawlarrow()
// TODO: Allow hiding items, without setting columns to 0
drawitem(x, y, w);
if (!hidematchcount) drawnumber(x, y, w, numberWidth, modeWidth);

View file

@ -36,10 +36,10 @@ eventloop(void)
if (ev.xfocus.window != win)
grabfocus();
break;
case KeyPress:
case KeyPress: // read key array and call functions
keypress(&ev);
break;
case SelectionNotify:
case SelectionNotify: // paste selection
if (ev.xselection.property == utf8)
pastesel();
break;

92
libs/history.c Normal file
View file

@ -0,0 +1,92 @@
void
loadhistory(void)
{
FILE *fp = NULL;
static size_t cap = 0;
size_t llen;
char *line;
// no history file, give up like i do with all things in life
if (!histfile) {
return;
}
// open history file, return if it failed
fp = fopen(histfile, "r");
if (!fp) {
fprintf(stderr, "spmenu: failed to open history file\n");
return;
}
for (;;) {
line = NULL;
llen = 0;
if (-1 == getline(&line, &llen, fp)) {
if (ferror(fp)) {
die("spmenu: failed to read history");
}
free(line);
break;
}
if (cap == histsz) {
cap += 64 * sizeof(char*);
history = realloc(history, cap);
if (!history) {
die("spmenu: failed to realloc memory");
}
}
strtok(line, "\n");
history[histsz] = line;
histsz++;
}
histpos = histsz;
if (fclose(fp)) {
die("spmenu: failed to close file %s", histfile);
}
}
void
navigatehistfile(int dir)
{
static char def[BUFSIZ];
char *p = NULL;
size_t len = 0;
if (!history || histpos + 1 == 0)
return;
if (histsz == histpos) {
strncpy(def, text, sizeof(def));
}
switch (dir) {
case 1:
if (histpos < histsz - 1) {
p = history[++histpos];
} else if (histpos == histsz - 1) {
p = def;
histpos++;
}
break;
case -1:
if (histpos > 0) {
p = history[--histpos];
}
break;
}
if (p == NULL) {
return;
}
len = MIN(strlen(p), BUFSIZ - 1);
strcpy(text, p);
text[len] = '\0';
cursor = len;
match();
}

3
libs/history.h Normal file
View file

@ -0,0 +1,3 @@
static char *histfile;
static char **history;
static size_t histsz, histpos;

View file

@ -1,6 +1,7 @@
void
setimagesize(int width, int height)
{
// don't even bother if we don't have image support
#if !USEIMAGE
return;
#endif
@ -11,6 +12,7 @@ setimagesize(int width, int height)
// this makes sure we cannot scale the image up or down too much
if ((!image && height < imageheight) || (!image && width < imagewidth) || width > mw || hideimage) return;
// original width/height
oih = imageheight;
oiw = imagewidth;
@ -33,6 +35,7 @@ setimagesize(int width, int height)
void
flipimage(void)
{
// flip image
switch (flip) {
case 1: // horizontal
imlib_image_flip_horizontal();
@ -59,7 +62,7 @@ rotateimage(void)
void
cleanupimage(void)
{
if (image) {
if (image) { // free image using imlib2
imlib_free_image();
image = NULL;
}
@ -73,29 +76,30 @@ drawimage(void)
if (!lines || !columns || hideimage) return;
// to prevent the image from being drawn multiple times
// to prevent the image from being drawn multiple times wasting resources
if (!needredraw) {
needredraw = 1;
return;
}
// load image cache
if (sel && sel->image && strcmp(sel->image, limg ? limg : "")) {
if (longestedge)
loadimagecache(sel->image, &width, &height);
} else if ((!sel || !sel->image) && image) {
imlib_free_image();
image = NULL;
} if (image && longestedge) {
} else if ((!sel || !sel->image) && image) { // free image
cleanupimage();
} if (image && longestedge) { // render the image
// rotate and flip, will return if we don't need to
rotateimage();
flipimage();
int leftmargin = imagegaps;
if(mh != bh + height + imagegaps * 2) {
if (mh != bh + height + imagegaps * 2) { // menu height cannot be smaller than image height
resizetoimageheight(height);
}
// render image
if (!imageposition) { // top mode = 0
if (height > width)
width = height;
@ -110,9 +114,9 @@ drawimage(void)
int minh = MIN(height, mh-bh-imagegaps*2);
imlib_render_image_on_drawable(leftmargin+(imagewidth-width)/2, (minh-height)/2+bh+imagegaps);
}
}
} if (sel) {
if (sel) {
limg = sel->image;
} else {
limg = NULL;
@ -135,12 +139,15 @@ setimageopts(void)
void
createifnexist(const char *dir)
{
// exists, so return
if (access(dir, F_OK) == 0)
return;
// fatal: permission denied
if (errno == EACCES)
fprintf(stderr, "spmenu: no access to create directory: %s\n", dir);
// mkdir() failure
if (mkdir(dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1)
fprintf(stderr, "spmenu: failed to create directory: %s\n", dir);
}
@ -181,21 +188,22 @@ loadimage(const char *file, int *width, int *height)
void
scaleimage(int *width, int *height)
{
int nwidth, nheight;
int new_width, new_height;
float aspect = 1.0f;
// depending on what size, we determine aspect ratio
if (imagewidth > *width)
aspect = (float)(*width)/imagewidth;
else
aspect = (float)imagewidth/(*width);
nwidth = *width * aspect;
nheight = *height * aspect;
new_width = *width * aspect;
new_height = *height * aspect;
if(nwidth == *width && nheight == *height)
if (new_width == *width && new_height == *height)
return;
image = imlib_create_cropped_scaled_image(0,0,*width,*height,nwidth,nheight);
image = imlib_create_cropped_scaled_image(0,0,*width,*height,new_width,new_height);
imlib_free_image();
@ -204,8 +212,8 @@ scaleimage(int *width, int *height)
imlib_context_set_image(image);
*width = nwidth;
*height = nheight;
*width = new_width;
*height = new_height;
return;
}
@ -343,6 +351,7 @@ resizetoimageheight(int imageheight)
struct item *item;
unsigned int i = 1;
// walk through all matches
for (item = matches; item && item != sel; item = item->right)
++i;

View file

@ -91,13 +91,13 @@ readstdin(void)
// spmenu:about
if (!strncmp("about", items[i].ex, strlen("about"))) {
int i = system("printf \"spmenu $([ -f '/usr/share/spmenu/version' ] && cat /usr/share/spmenu/version || printf unknown)\\nBased on dmenu 5.2 from https://tools.suckless.org/dmenu\\nCompiled $([ -f '/usr/share/spmenu/compile-date' ] && cat /usr/share/spmenu/compile-date || printf Unknown)\\nCFLAGS: $([ -f '/usr/share/spmenu/cflags' ] && cat /usr/share/spmenu/cflags || printf unknown)\\nCC: $([ -f '/usr/share/spmenu/cc' ] && cat /usr/share/spmenu/cc || printf unknown)\\nDistro: $([ -f '/usr/share/spmenu/pkg_arch' ] && echo Arch || echo Installed manually)\\n\" | spmenu --columns 1 --lines 10 --hide-cursor --no-allow-typing --hide-mode --hide-match-count --hide-prompt --hide-powerline --hide-input --no-indent --no-color-items > /dev/null");
if (i||!i) exit(0);
if (i||!i) exit(i);
}
// spmenu:test
if (!strncmp("test", items[i].ex, strlen("test"))) {
int i = system("command -v spmenu_test > /dev/null && spmenu_test");
if (i||!i) exit(0);
if (i||!i) exit(i);
}
}
}

View file

@ -13,9 +13,8 @@ resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst)
snprintf(fullname, sizeof(fullname), "%s.%s", "spmenu", name);
fullname[sizeof(fullname) - 1] = '\0';
XrmGetResource(db, fullname, "*", &type, &ret);
if (!(ret.addr == NULL || strncmp("String", type, 64)))
{
switch (rtype) {
if (!(ret.addr == NULL || strncmp("String", type, 64))) {
switch (rtype) { // type
case STRING:
strcpy(sdst, ret.addr);
break;

187
spmenu.c
View file

@ -99,6 +99,7 @@
#include "libs/key.h"
#include "libs/mouse.h"
#include "libs/sort.h"
#include "libs/history.h"
// misc
#include "libs/key_struct.c"
@ -182,11 +183,6 @@ static Drw *drw;
static Clr *scheme[SchemeLast];
static Clr textclrs[256];
// history
static char *histfile;
static char **history;
static size_t histsz, histpos;
// declare functions
static void calcoffsets(void);
static void recalculatenumbers(void);
@ -235,6 +231,7 @@ static char *(*fstrstr)(const char *, const char *) = cistrstr;
#include "libs/client.c"
#include "libs/match.h"
#include "libs/match.c"
#include "libs/history.c"
#include "libs/arg.c"
#include "libs/stream.c"
@ -258,11 +255,16 @@ recalculatenumbers(void)
struct item *item;
if (matchend) {
numer++;
// walk through items that match and add to numer
for (item = matchend; item && item->left; item = item->left)
numer++;
}
// walk through all items, matching or not and add to denom
for (item = items; item && item->text; item++)
denom++;
snprintf(numbers, NUMBERSBUFSIZE, "%d/%d", numer, denom);
}
@ -273,7 +275,7 @@ calcoffsets(void)
if (lines > 0)
n = lines * columns * bh;
else {
else { // no lines, therefore the size of items must be decreased to fit the menu elements
int numberWidth = 0;
int modeWidth = 0;
int larrowWidth = 0;
@ -287,10 +289,12 @@ calcoffsets(void)
n = mw - (promptw + inputw + larrowWidth + rarrowWidth + modeWidth + numberWidth);
}
// calculate which items will begin the next page and previous page
// calculate which items will begin the next page
for (i = 0, next = curr; next; next = next->right)
if ((i += (lines > 0) ? bh : MIN(TEXTWM(next->text), n)) > n)
break;
// calculate which items will begin the previous page
for (i = 0, prev = curr; prev && prev->left; prev = prev->left)
if ((i += (lines > 0) ? bh : MIN(TEXTWM(prev->left->text), n)) > n)
break;
@ -300,8 +304,10 @@ int
max_textw(void)
{
int len = 0;
for (struct item *item = items; item && item->text; item++)
len = MAX(TEXTW(item->text), len);
return len;
}
@ -311,17 +317,20 @@ cleanup(void)
size_t i;
#if USEIMAGE
cleanupimage();
cleanupimage(); // function frees images
#endif
XUngrabKey(dpy, AnyKey, AnyModifier, root);
XUngrabKey(dpy, AnyKey, AnyModifier, root); // ungrab keys
// free color scheme
for (i = 0; i < SchemeLast; i++)
free(scheme[i]);
// free high priority items
for (i = 0; i < hplength; ++i)
free(hpitems[i]);
// free drawing and close the display
drw_free(drw);
XSync(dpy, False);
XCloseDisplay(dpy);
@ -337,11 +346,12 @@ cistrstr(const char *h, const char *n)
for (; *h; ++h) {
for (i = 0; n[i] && tolower((unsigned char)n[i]) ==
tolower((unsigned char)h[i]); ++i)
;
tolower((unsigned char)h[i]); ++i);
if (n[i] == '\0')
return (char *)h;
}
return NULL;
}
@ -356,6 +366,8 @@ grabfocus(void)
XGetInputFocus(dpy, &focuswin, &revertwin);
if (focuswin == win)
return;
// if it's a client, we can't just steal all the input for ourselves
if (managed) {
XTextProperty prop;
char *windowtitle = prompt != NULL ? prompt : "spmenu";
@ -363,13 +375,14 @@ grabfocus(void)
XSetWMName(dpy, win, &prop);
XSetTextProperty(dpy, win, &prop, XInternAtom(dpy, "_NET_WM_NAME", False));
XFree(prop.value);
} else {
} else { // spmenu is not managed, and is very greedy
XSetInputFocus(dpy, win, RevertToParent, CurrentTime);
}
nanosleep(&ts, NULL);
}
die("cannot grab focus");
die("spmenu: cannot grab focus"); // not possible to grab focus, abort immediately
}
void
@ -377,10 +390,15 @@ insert(const char *str, ssize_t n)
{
if (strlen(text) + n > sizeof text - 1)
return;
// move existing text out of the way, insert new text, and update cursor
memmove(&text[cursor + n], &text[cursor], sizeof text - cursor - MAX(n, 0));
// update cursor
if (n > 0)
memcpy(&text[cursor], str, n);
// add to cursor position and continue matching
cursor += n;
match();
}
@ -396,93 +414,6 @@ nextrune(int inc)
return n;
}
void
loadhistory(void)
{
FILE *fp = NULL;
static size_t cap = 0;
size_t llen;
char *line;
if (!histfile) {
return;
}
fp = fopen(histfile, "r");
if (!fp) {
return;
}
for (;;) {
line = NULL;
llen = 0;
if (-1 == getline(&line, &llen, fp)) {
if (ferror(fp)) {
die("failed to read history");
}
free(line);
break;
}
if (cap == histsz) {
cap += 64 * sizeof(char*);
history = realloc(history, cap);
if (!history) {
die("failed to realloc memory");
}
}
strtok(line, "\n");
history[histsz] = line;
histsz++;
}
histpos = histsz;
if (fclose(fp)) {
die("failed to close file %s", histfile);
}
}
void
navigatehistfile(int dir)
{
static char def[BUFSIZ];
char *p = NULL;
size_t len = 0;
if (!history || histpos + 1 == 0)
return;
if (histsz == histpos) {
strncpy(def, text, sizeof(def));
}
switch (dir) {
case 1:
if (histpos < histsz - 1) {
p = history[++histpos];
} else if (histpos == histsz - 1) {
p = def;
histpos++;
}
break;
case -1:
if (histpos > 0) {
p = history[--histpos];
}
break;
}
if (p == NULL) {
return;
}
len = MIN(strlen(p), BUFSIZ - 1);
strcpy(text, p);
text[len] = '\0';
cursor = len;
match();
}
void
pastesel(void)
{
@ -495,9 +426,11 @@ pastesel(void)
if (XGetWindowProperty(dpy, win, utf8, 0, (sizeof text / 4) + 1, False,
utf8, &da, &di, &dl, &dl, (unsigned char **)&p)
== Success && p) {
insert(p, (q = strchr(p, '\n')) ? q - p : (ssize_t)strlen(p));
insert(p, (q = strchr(p, '\n')) ? q - p : (ssize_t)strlen(p)); // insert selection
XFree(p);
}
// draw the menu
drawmenu();
}
@ -509,7 +442,7 @@ xinitvisual()
int nitems;
int i;
// properties
// visual properties
XVisualInfo tpl = {
.screen = screen,
.depth = 32,
@ -520,6 +453,8 @@ xinitvisual()
infos = XGetVisualInfo(dpy, masks, &tpl, &nitems);
visual = NULL;
// create colormap
for(i = 0; i < nitems; i ++) {
fmt = XRenderFindVisualFormat(dpy, infos[i].visual);
if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) {
@ -542,7 +477,7 @@ xinitvisual()
}
void
setup(void)
setupdisplay(void)
{
int x, y, i;
#if USEXINERAMA
@ -563,7 +498,7 @@ setup(void)
init_appearance(); // init colorschemes by reading arrays
// properties
// set properties indicating what spmenu handles
clip = XInternAtom(dpy, "CLIPBOARD", False);
utf8 = XInternAtom(dpy, "UTF8_STRING", False);
types = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
@ -581,6 +516,7 @@ setup(void)
mh = (lines + 1) * bh; // lines + 1 * bh is the menu height
// set prompt width based on prompt size
promptw = (prompt && *prompt)
? pango_prompt ? TEXTWM(prompt) : TEXTW(prompt) - lrpad / 4 : 0; // prompt width
@ -628,11 +564,11 @@ setup(void)
break;
// calculate x/y position
if (menuposition == 2) {
if (menuposition == 2) { // centered
mw = MIN(MAX(max_textw() + promptw, minwidth), info[i].width);
x = info[i].x_org + ((info[i].width - mw) / 2);
y = info[i].y_org + ((info[i].height - mh) / 2);
} else {
} else { // top or bottom
x = info[i].x_org + dmx;
y = info[i].y_org + (menuposition ? 0 : info[i].height - mh - dmy);
mw = (dmw>0 ? dmw : info[i].width);
@ -643,14 +579,14 @@ setup(void)
#endif
{
if (!XGetWindowAttributes(dpy, parentwin, &wa))
die("could not get embedding window attributes: 0x%lx",
parentwin);
die("spmenu: could not get embedding window attributes: 0x%lx",
parentwin); // die because unable to get attributes for the parent window
if (menuposition == 2) {
if (menuposition == 2) { // centered
mw = MIN(MAX(max_textw() + promptw, minwidth), wa.width);
x = (wa.width - mw) / 2;
y = (wa.height - mh) / 2;
} else {
} else { // top or bottom
x = 0;
y = 0;
mw = wa.width;
@ -660,9 +596,9 @@ setup(void)
// might be faster in some instances, most of the time unnecessary
if (!accuratewidth) inputw = MIN(inputw, mw/3);
match();
match(); // match entries
// create menu window
// create menu window and set properties for it
create_window(x + sp, y + vp - (menuposition == 2 ? 0 : borderwidth * 2), mw - 2 * sp - borderwidth * 2, mh);
set_window();
set_prop();
@ -679,6 +615,8 @@ setup(void)
XNClientWindow, win, XNFocusWindow, win, NULL);
XMapRaised(dpy, win);
// embed spmenu inside parent window
if (embed) {
XSelectInput(dpy, parentwin, FocusChangeMask | SubstructureNotifyMask);
if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) {
@ -699,12 +637,13 @@ main(int argc, char *argv[])
{
XWindowAttributes wa;
readargs(argc, argv);
readargs(argc, argv); // start by reading arguments
#if USEIMAGE
longestedge = MAX(imagewidth, imageheight);
#endif
// set default mode, must be done before the event loop or keybindings will not work
if (mode) {
curMode = 1;
allowkeys = 1;
@ -718,36 +657,40 @@ main(int argc, char *argv[])
}
if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())
fputs("warning: no locale support\n", stderr);
fputs("warning: no locale support\n", stderr); // invalid locale, so notify the user about it
if (!(dpy = XOpenDisplay(NULL)))
die("spmenu: cannot open display");
die("spmenu: cannot open display"); // failed to open display
// set screen and root window
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);
// parent window is the root window (ie. window manager) because we're not embedding
if (!embed || !(parentwin = strtol(embed, NULL, 0)))
parentwin = root;
if (!XGetWindowAttributes(dpy, parentwin, &wa))
die("spmenu: could not get embedding window attributes: 0x%lx", parentwin);
xinitvisual();
drw = drw_create(dpy, screen, root, wa.width, wa.height, visual, depth, cmap);
xinitvisual(); // init visual and create drawable after
drw = drw_create(dpy, screen, root, wa.width, wa.height, visual, depth, cmap); // wrapper function creating a drawable
// load fonts
if (!drw_font_create(drw, fonts, LENGTH(fonts)))
die("no fonts could be loaded.");
// resize window
lrpad = drw->font->h + textpadding;
prepare_window_size();
prepare_window_size(); // this function sets padding size
// openbsd specifics, i use gnu/linux so i have no idea why this is here
#ifdef __OpenBSD__
if (pledge("stdio rpath", NULL) == -1)
die("pledge");
#endif
loadhistory();
loadhistory(); // read history entries
// fast (-f) means we grab keyboard before reading standard input
if (fast && !isatty(0)) {
@ -767,8 +710,8 @@ main(int argc, char *argv[])
}
#endif
setup();
eventloop();
setupdisplay(); // set up display and create window
eventloop(); // function is a loop which checks X11 events and calls other functions accordingly
return 1;
return 1; // should be unreachable
}