Add some more comments

This commit is contained in:
speedie 2023-07-16 02:57:38 +02:00
parent 8e33d4c667
commit 7b7c1a56f4
4 changed files with 104 additions and 65 deletions

View file

@ -4,14 +4,17 @@ void moveleft(Arg *arg) {
int i, offscreen = 0;
int argu = arg->i ? arg->i : 1;
// If we cannot move left because !lines, moving left should move to the next item. Calling moveup() does this.
if (!lines) {
moveup(arg);
return;
}
if (columns > 1) {
if (!sel)
if (!sel) {
return;
}
tmpsel = sel;
for (i = 0; i < lines; i++) {
if (!tmpsel->left || tmpsel->left->right != tmpsel) {
@ -40,7 +43,7 @@ void moveright(Arg *arg) {
int i, offscreen = 0;
int argu = arg->i ? arg->i : 1;
if (!lines) {
if (!lines) { // If we cannot move right because !lines, moving right should move to the previous item. Calling down() does this.
movedown(arg);
return;
}
@ -75,7 +78,7 @@ void movedown(Arg *arg) {
for (int j = 0; j < argu; j++) {
if (sel && sel->right && (sel = sel->right) == next) {
curr = next;
curr = next; // Current item is now the next item
}
}
@ -88,7 +91,7 @@ void moveup(Arg *arg) {
for (int j = 0; j < argu; j++) {
if (sel && sel->left && (sel = sel->left)->right == curr) {
curr = prev;
curr = prev; // Current item is now the previous item
}
}

View file

@ -9,8 +9,8 @@ int draw_icon(struct item *item, int x, int y, int w, int h) {
int slen = 0, i;
unsigned int digest_len = EVP_MD_size(EVP_md5());
unsigned char *digest = (unsigned char *)OPENSSL_malloc(digest_len);
char *xdg_cache, *home = NULL, *dsize, *buf = NULL;
struct passwd *pw = NULL;
char *xdg_cache, *home = NULL, *cachesize, *buf = NULL;
struct passwd *user_id = NULL;
if (hideimage) {
return x;
@ -19,15 +19,17 @@ int draw_icon(struct item *item, int x, int y, int w, int h) {
if (item->image) {
if (generatecache) {
if(!(xdg_cache = getenv("XDG_CACHE_HOME"))) {
if(!(home = getenv("HOME")) && (pw = getpwuid(getuid())))
home = pw->pw_dir;
if(!home) {
if(!(home = getenv("HOME")) && (user_id = getpwuid(getuid()))) {
home = user_id->pw_dir;
}
if(!home) { // no home directory.. somehow
fprintf(stderr, "spmenu: could not find home directory");
return x;
}
}
dsize = "icon";
cachesize = "icon";
slen = snprintf(NULL, 0, "file://%s", item->image)+1;
@ -46,34 +48,34 @@ int draw_icon(struct item *item, int x, int y, int w, int h) {
free(buf);
char md5[digest_len*2+1];
char md5sum[digest_len*2+1];
for (i = 0; i < digest_len; ++i)
sprintf(&md5[i*2], "%02x", (unsigned int)digest[i]);
sprintf(&md5sum[i*2], "%02x", (unsigned int)digest[i]);
if (!cachedir || !strcmp(cachedir, "default")) {
if (!cachedir || !strcmp(cachedir, "default")) { // "default" here is from the config file
if (xdg_cache || !strcmp(cachedir, "xdg"))
slen = snprintf(NULL, 0, "%s/thumbnails/%s/%s.png", xdg_cache, dsize, md5)+1;
slen = snprintf(NULL, 0, "%s/thumbnails/%s/%s.png", xdg_cache, cachesize, md5sum)+1;
else
slen = snprintf(NULL, 0, "%s/.cache/thumbnails/%s/%s.png", home, dsize, md5)+1;
slen = snprintf(NULL, 0, "%s/.cache/thumbnails/%s/%s.png", home, cachesize, md5sum)+1;
} else {
slen = snprintf(NULL, 0, "%s/%s/%s.png", cachedir, dsize, md5)+1;
slen = snprintf(NULL, 0, "%s/%s/%s.png", cachedir, cachesize, md5sum)+1;
}
if(!(buf = malloc(slen))) {
return x;
}
if (!cachedir || !strcmp(cachedir, "default")) {
if (!cachedir || !strcmp(cachedir, "default")) { // "default" here is from the config file
if (xdg_cache)
sprintf(buf, "%s/thumbnails/%s/%s.png", xdg_cache, dsize, md5);
sprintf(buf, "%s/thumbnails/%s/%s.png", xdg_cache, cachesize, md5sum);
else
sprintf(buf, "%s/.cache/thumbnails/%s/%s.png", home, dsize, md5);
sprintf(buf, "%s/.cache/thumbnails/%s/%s.png", home, cachesize, md5sum);
} else {
sprintf(buf, "%s/%s/%s.png", cachedir, dsize, md5);
sprintf(buf, "%s/%s/%s.png", cachedir, cachesize, md5sum);
}
image = imlib_load_image(buf);
image = imlib_load_image(buf); // attempt to load image from path
if (image) {
imlib_context_set_image(image);
@ -83,10 +85,15 @@ int draw_icon(struct item *item, int x, int y, int w, int h) {
}
}
/* If passed w or h has changed, cache is invalid and has to be regenerated. This prevents flickering.
* It could change if sp.bh has changed in some way, such as font size being changed after cache has
* been generated.
*/
if (ich != h || icw != w) {
image = NULL;
}
// load regular image, because an image was not loaded from cache
if (!image || !generatecache) {
image = imlib_load_image(item->image);
@ -107,19 +114,21 @@ int draw_icon(struct item *item, int x, int y, int w, int h) {
imlib_free_image();
imlib_context_set_image(image);
// get new width/height
icw = imlib_image_get_width();
ich = imlib_image_get_height();
}
imlib_image_set_format("png");
// create directory and write cache file
if (buf && generatecache && image) {
createifnexist_rec(buf);
imlib_save_image(buf);
free(buf);
}
// Draw the image
// draw the image
draw_set_img(draw, imlib_image_get_data(), w, h);
draw_img(draw, x, y);

View file

@ -190,8 +190,8 @@ void loadimagecache(const char *file, int *width, int *height) {
int slen = 0, i;
unsigned int digest_len = EVP_MD_size(EVP_md5());
unsigned char *digest = (unsigned char *)OPENSSL_malloc(digest_len);
char *xdg_cache, *home = NULL, *dsize, *buf = NULL;
struct passwd *pw = NULL;
char *xdg_cache, *home = NULL, *cachesize, *buf = NULL;
struct passwd *user_id = NULL;
// just load and don't store or try cache
if (img.longestedge > maxcache) {
@ -204,18 +204,20 @@ void loadimagecache(const char *file, int *width, int *height) {
if (generatecache) {
// try find image from cache first
if(!(xdg_cache = getenv("XDG_CACHE_HOME"))) {
if(!(home = getenv("HOME")) && (pw = getpwuid(getuid())))
home = pw->pw_dir;
if(!home) {
if(!(home = getenv("HOME")) && (user_id = getpwuid(getuid()))) {
home = user_id->pw_dir;
}
if(!home) { // no home directory could be grabbed.. somehow
fprintf(stderr, "spmenu: could not find home directory");
return;
}
}
// which cache do we try?
dsize = "normal";
cachesize = "normal";
if (img.longestedge > 128)
dsize = "large";
cachesize = "large";
slen = snprintf(NULL, 0, "file://%s", file)+1;
@ -243,11 +245,11 @@ void loadimagecache(const char *file, int *width, int *height) {
// path for cached thumbnail
if (!cachedir || !strcmp(cachedir, "default")) {
if (xdg_cache || !strcmp(cachedir, "xdg"))
slen = snprintf(NULL, 0, "%s/thumbnails/%s/%s.png", xdg_cache, dsize, md5)+1;
slen = snprintf(NULL, 0, "%s/thumbnails/%s/%s.png", xdg_cache, cachesize, md5)+1;
else
slen = snprintf(NULL, 0, "%s/.cache/thumbnails/%s/%s.png", home, dsize, md5)+1;
slen = snprintf(NULL, 0, "%s/.cache/thumbnails/%s/%s.png", home, cachesize, md5)+1;
} else {
slen = snprintf(NULL, 0, "%s/%s/%s.png", cachedir, dsize, md5)+1;
slen = snprintf(NULL, 0, "%s/%s/%s.png", cachedir, cachesize, md5)+1;
}
if(!(buf = malloc(slen))) {
@ -256,11 +258,11 @@ void loadimagecache(const char *file, int *width, int *height) {
if (!cachedir || !strcmp(cachedir, "default")) {
if (xdg_cache)
sprintf(buf, "%s/thumbnails/%s/%s.png", xdg_cache, dsize, md5);
sprintf(buf, "%s/thumbnails/%s/%s.png", xdg_cache, cachesize, md5);
else
sprintf(buf, "%s/.cache/thumbnails/%s/%s.png", home, dsize, md5);
sprintf(buf, "%s/.cache/thumbnails/%s/%s.png", home, cachesize, md5);
} else {
sprintf(buf, "%s/%s/%s.png", cachedir, dsize, md5);
sprintf(buf, "%s/%s/%s.png", cachedir, cachesize, md5);
}
loadimage(buf, width, height);
@ -298,7 +300,7 @@ void jumptoindex(unsigned int index) {
calcoffsets();
for (i = 1; i < index; ++i) {
for (i = 1; i < index; ++i) { // move to item index
if(sel && sel->right && (sel = sel->right) == next) {
curr = next;
calcoffsets();

View file

@ -95,7 +95,7 @@
// include macros and other defines
#include "libs/define.c"
enum {
enum { // click enum
ClickWindow,
ClickPrompt,
ClickInput,
@ -159,7 +159,7 @@ struct mo {
struct img {
int setlines; // actual lines
int flip; // %=
int longestedge; // MAX(imagewidth, imagheight)
int longestedge; // MAX(imagewidth, imageheight)
int imagewidth; // current image width
int imageheight; // current image height
int imagegaps; // current image gaps
@ -206,12 +206,12 @@ static struct item *prev, *curr, *next, *sel;
#include "libs/stream.h"
#include "libs/schemes.h"
#include "libs/arg.h"
#include "libs/x11/inc.h" // include x11
#include "libs/wl/inc.h" // include wayland
#include "libs/x11/inc.h"
#include "libs/wl/inc.h"
#include "libs/sort.h"
#include "libs/history.h"
static Draw_t *draw;
static Draw_t *draw; // Draw_t type, see libs/draw/draw.c
// high priority
static int hplength = 0;
@ -243,13 +243,15 @@ static void handle(void);
static void appenditem(struct item *item, struct item **list, struct item **last);
static int max_textw(void);
static size_t nextrune(int inc);
// matching
static char * cistrstr(const char *s, const char *sub);
static int (*fstrncmp)(const char *, const char *, size_t) = strncasecmp;
static char *(*fstrstr)(const char *, const char *) = cistrstr;
#if USEX
static void pastesel(void);
static void grabfocus(void);
static void pastesel(void); // TODO: wayland clipboard
static void grabfocus(void); // focus doesn't need to be grabbed on wayland
#endif
static char **list;
@ -298,7 +300,7 @@ static char *fonts[] = { font };
int is_selected(size_t index) {
for (int i = 0; i < sel_size; i++) {
if (sel_index[i] == index) {
return 1;
return 1; // selected item index is size_t index
}
}
@ -319,6 +321,7 @@ void appenditem(struct item *item, struct item **list, struct item **last) {
void recalculatenumbers(void) {
unsigned int numer = 0, denom = 0, selected = 0;
struct item *item;
if (matchend) {
numer++;
@ -328,8 +331,9 @@ void recalculatenumbers(void) {
}
// walk through all items, matching or not and add to denom
for (item = items; item && item->text; item++)
for (item = items; item && item->text; item++) {
denom++;
}
for (int i = 0; i < sel_size; i++) {
if (sel_index[i] == -1) {
@ -347,37 +351,38 @@ void recalculatenumbers(void) {
}
void calcoffsets(void) {
int i, n;
int i, offset;
if (lines > 0)
n = lines * columns * sp.bh;
else { // no lines, therefore the size of items must be decreased to fit the menu elements
if (lines > 0) {
offset = lines * columns * sp.bh;
} else { // no lines, therefore the size of items must be decreased to fit the menu elements
int numberw = 0;
int modeWidth = 0;
int modew = 0;
int larroww = 0;
int rarrowWidth = 0;
int rarroww = 0;
int capsw = 0;
if (!hidematchcount) numberw = pango_numbers ? TEXTWM(tx.numbers) : TEXTW(tx.numbers);
if (!hidemode) modeWidth = pango_mode ? TEXTWM(tx.modetext) : TEXTW(tx.modetext);
if (!hidemode) modew = pango_mode ? TEXTWM(tx.modetext) : TEXTW(tx.modetext);
if (!hidelarrow) larroww = pango_leftarrow ? TEXTWM(leftarrow) : TEXTW(leftarrow);
if (!hiderarrow) rarrowWidth = pango_rightarrow ? TEXTWM(rightarrow) : TEXTW(rightarrow);
if (!hiderarrow) rarroww = pango_rightarrow ? TEXTWM(rightarrow) : TEXTW(rightarrow);
if (!hidecaps) capsw = pango_caps ? TEXTWM(tx.capstext) : TEXTW(tx.capstext);
if (!strcmp(tx.capstext, ""))
if (!strcmp(tx.capstext, "")) {
capsw = 0;
}
n = sp.mw - (sp.promptw + sp.inputw + larroww + rarrowWidth + modeWidth + numberw + capsw + menumarginh);
offset = sp.mw - (sp.promptw + sp.inputw + larroww + rarroww + modew + numberw + capsw + menumarginh);
}
// calculate which items will begin the next page
for (i = 0, next = curr; next; next = next->right)
if ((i += (lines > 0) ? sp.bh : MIN(TEXTWM(next->text) + (powerlineitems ? !lines ? 2 * sp.plw : 0 : 0), n)) > n)
if ((i += (lines > 0) ? sp.bh : MIN(TEXTWM(next->text) + (powerlineitems ? !lines ? 2 * sp.plw : 0 : 0), offset)) > offset)
break;
// calculate which items will begin the previous page
for (i = 0, prev = curr; prev && prev->left; prev = prev->left)
if ((i += (lines > 0) ? sp.bh : MIN(TEXTWM(prev->left->text) + (powerlineitems ? !lines ? 2 * sp.plw : 0 : 0), n)) > n)
if ((i += (lines > 0) ? sp.bh : MIN(TEXTWM(prev->left->text) + (powerlineitems ? !lines ? 2 * sp.plw : 0 : 0), offset)) > offset)
break;
}
@ -413,6 +418,7 @@ void cleanup(void) {
free(sel_index);
}
// This function handles case insensitive matching
char * cistrstr(const char *h, const char *n) {
size_t i;
@ -438,17 +444,25 @@ void grabfocus(void) {
void insert(const char *str, ssize_t n) {
if (strlen(tx.text) + n > sizeof tx.text - 1)
return;
return; // length of text should not exceed size
static char l[BUFSIZ] = "";
if (requirematch) memcpy(l, tx.text, BUFSIZ);
if (requirematch) {
memcpy(l, tx.text, BUFSIZ);
}
// move existing text out of the way, insert new text, and update cursor
memmove(&tx.text[sp.cursor + n], &tx.text[sp.cursor], sizeof tx.text - sp.cursor - MAX(n, 0));
memmove(
&tx.text[sp.cursor + n],
&tx.text[sp.cursor],
sizeof tx.text - sp.cursor - MAX(n, 0)
);
// update cursor
if (n > 0 && str && n)
if (n > 0 && str && n) {
memcpy(&tx.text[sp.cursor], str, n);
}
// add to cursor position and continue matching
sp.cursor += n;
@ -460,6 +474,7 @@ void insert(const char *str, ssize_t n) {
match();
}
// output on insertion
if (incremental) {
puts(tx.text);
fflush(stdout);
@ -467,12 +482,13 @@ void insert(const char *str, ssize_t n) {
}
size_t nextrune(int inc) {
ssize_t n;
ssize_t rune;
// return location of next utf8 rune in the given direction (+1 or -1)
for (n = sp.cursor + inc; n + inc >= 0 && (tx.text[n] & 0xc0) == 0x80; n += inc)
for (rune = sp.cursor + inc; rune + inc >= 0 && (tx.text[rune] & 0xc0) == 0x80; rune += inc)
;
return n;
return rune;
}
#if USEX
@ -497,6 +513,10 @@ void resizeclient(void) {
#endif
}
/* Width reserved for input when !lines is a fixed size of the menu width / 3
* This is reasonable, but in rare cases may cause input text to overlap
* items.
*/
void get_width(void) {
sp.inputw = sp.mw / 3;
}
@ -507,12 +527,14 @@ void get_mh(void) {
sp.mh = (lines + 1) * sp.bh;
sp.mh += 2 * menumarginv;
// subtract 1 line if there's nothing to draw on the top line
if ((hideprompt && hideinput && hidemode && hidematchcount && hidecaps) && lines) {
sp.mh -= sp.bh;
}
epad = 2 * menupaddingv;
// the spmenu window should not exceed the screen resolution height
if (mo.output_height && !xpos && !ypos) {
sp.mh = MIN(sp.mh, mo.output_height - epad);
@ -540,6 +562,7 @@ void set_mode(void) {
sp_strncpy(tx.modetext, normtext, sizeof(tx.modetext));
}
// normal mode disabled
if (sp.forceinsertmode) {
sp.mode = 1;
sp.allowkeys = 1;
@ -608,7 +631,9 @@ void handle(void) {
int main(int argc, char *argv[]) {
readargs(argc, argv); // start by reading arguments
// pledge limits what programs can do, so here we specify what spmenu should be allowed to do
/* pledge limits what programs can do, so here we specify what spmenu should be allowed to do
* TODO: test this on a openbsd operating system
*/
#ifdef __OpenBSD__
if (pledge("stdio rpath wpath cpath", NULL) == -1)
die("pledge");