diff --git a/menu/.gitignore b/menu/.gitignore deleted file mode 100644 index 3ef527d..0000000 --- a/menu/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -*.o -config.h -patches.h -dmenu -stest diff --git a/menu/Makefile b/menu/Makefile index a71a856..458c524 100644 --- a/menu/Makefile +++ b/menu/Makefile @@ -14,10 +14,7 @@ all: dmenu stest config.h: cp config.def.h $@ -patches.h: - cp patches.def.h $@ - -$(OBJ): arg.h config.h config.mk drw.h patches.h +$(OBJ): arg.h config.h config.mk drw.h dmenu: dmenu.o drw.o util.o $(CC) -o $@ dmenu.o drw.o util.o $(LDFLAGS) diff --git a/menu/README.md b/menu/README.md deleted file mode 100644 index 1af8833..0000000 --- a/menu/README.md +++ /dev/null @@ -1,272 +0,0 @@ -Similar to [dwm-flexipatch](https://github.com/bakkeby/dwm-flexipatch) this dmenu 5.3 (b1e217b, -2025-03-17) project has a different take on patching. It uses preprocessor directives to decide -whether or not to include a patch during build time. Essentially this means that this build, for -better or worse, contains both the patched _and_ the original code. The aim being that you can -select which patches to include and the build will contain that code and nothing more. - -For example to include the `alpha` patch then you would only need to flip this setting from 0 -to 1 in [patches.h](https://github.com/bakkeby/dmenu-flexipatch/blob/master/patches.def.h): -```c -#define ALPHA_PATCH 1 -``` - -Once you have found out what works for you and what doesn't then you should be in a better position -to choose patches should you want to start patching from scratch. - -Alternatively if you have found the patches you want, but don't want the rest of the flexipatch -entanglement on your plate then you may want to have a look at -[flexipatch-finalizer](https://github.com/bakkeby/flexipatch-finalizer); a custom pre-processor -tool that removes all the unused flexipatch code leaving you with a build that contains the patches -you selected. - -Refer to [https://tools.suckless.org/dmenu/](https://tools.suckless.org/dmenu/) for details on -dmenu, how to install it and how it works. - -Browsing patches? There is a [map of patches](https://coggle.it/diagram/YjT2DD6jBM9dayf3) diagram which tries to organise patches into categories. - ---- - -### Changelog: - -2024-07-17 - Added the input method patch - -2024-07-16 - Added the mouse motion support patch - -2023-06-15 - Added the caret width patch - -2022-09-05 - Removed the json patch due to maintenance and compatibility reasons, added the - separator patch - -2022-09-04 - Added the fzfexpect patch - -2022-06-21 - Adding barpadding patch and relative input width patch - -2022-03-02 - Bump to 5.1 - -2021-05-23 - Adding support for `ctrl+v` to paste and adding emoji-highlight patch - -2021-05-17 - Added the restrict return, no sort, gridnav and plain-prompt (listfullwidth) patches - -2021-05-15 - Added the tsv and printindex patches - -2020-08-08 - Added the json, symbols, managed, morecolor, multi-selection and preselect patches - -2020-08-05 - Added the grid, highlight, highpriority, dynamic options and numbers patches - -2020-06-13 - Added the pango patch - -2020-06-10 - Added the case-insensitive patch - -2020-05-29 - Added the alpha patch (derived from Baitinq's [build](https://github.com/Baitinq/dmenu)) - and the color emoji patch - -2020-04-05 - Added fuzzyhighlight patch - -2020-02-09 - Added revised border patch (adding command line parameter for setting border width) - -2019-12-29 - Added xresources patch - -2019-10-16 - Introduced [flexipatch-finalizer](https://github.com/bakkeby/flexipatch-finalizer) - -2019-09-18 - Added border, center, fuzzymatch, incremental, initialtext, instant, line-height, - mouse-support, navhistory, non-blocking-stdin, password, pipeout, printinputtext, - rejectnomatch, scroll, vertfull, wmtype and xyw patches - -### Patches included: - - - [alpha](https://github.com/bakkeby/patches/blob/master/dmenu/dmenu-alpha-5.0_20210725_523aa08.diff) - - adds transparency for the dmenu window - - - [barpadding](https://github.com/bakkeby/patches/wiki/barpadding) - - adds padding for dmenu in similar fashion to the [barpadding](https://dwm.suckless.org/patches/barpadding/) - patch for dwm - - - [border](http://tools.suckless.org/dmenu/patches/border/) - - adds a border around the dmenu window - - - [caret-width](https://github.com/DarkSamus669/dmenu-patches/blob/main/dmenu-caretwidth-5.2.diff) - - makes the caret width configurable and overridable via a command line option - - - [case-insensitive](http://tools.suckless.org/dmenu/patches/case-insensitive/) - - makes dmenu case-insensitive by default, replacing the case-insensitive `-i` option with a - case sensitive `-s` option - - - [center](https://tools.suckless.org/dmenu/patches/center/) - - this patch centers dmenu in the middle of the screen - - - color_emoji - - enables color emoji in dmenu by removing a workaround for a BadLength error in the Xft - library when color glyphs are used - - enabling this will crash dmenu on encountering such glyphs unless you also have an updated - Xft library that can handle them - - - [dynamic_options](https://tools.suckless.org/dmenu/patches/dynamicoptions/) - - adds a flag (`-dy`) which makes dmenu run the command given to it whenever input is changed - with the current input as the last argument and update the option list according to the - output of that command - - - [emoji-highlight](https://tools.suckless.org/dmenu/patches/emoji-highlight/) - - this patch will allow for emojis on the left side with a colored background when selected - - - [fuzzyhighlight](https://tools.suckless.org/dmenu/patches/fuzzyhighlight/) - - intended to be combined with the fuzzymatch patch, this makes it so that fuzzy matches are - highlighted - - - [fuzzymatch](https://tools.suckless.org/dmenu/patches/fuzzymatch/) - - adds support for fuzzy-matching to dmenu, allowing users to type non-consecutive portions - of the string to be matched - - - [fzfexpect](https://github.com/DAFF0D11/dafmenu/blob/master/patches/dmenu-fzfexpect-5.1.diff) - - adds fzf expect functionality in dmenu - - - [grid](https://tools.suckless.org/dmenu/patches/grid/) - - allows dmenu's entries to be rendered in a grid by adding a new `-g` flag to specify the - number of grid columns - - the `-g` and `-l` options can be used together to create a G columns * L lines grid - - - [gridnav](https://tools.suckless.org/dmenu/patches/gridnav/) - - adds the ability to move left and right through a grid (when using the grid patch) - - - [highlight](https://tools.suckless.org/dmenu/patches/highlight/) - - this patch highlights the individual characters of matched text for each dmenu list entry - - - [highpriority](https://tools.suckless.org/dmenu/patches/highpriority/) - - this patch will automatically sort the search result so that high priority items are shown - first - - - [incremental](https://tools.suckless.org/dmenu/patches/incremental/) - - this patch causes dmenu to print out the current text each time a key is pressed - - - [initialtext](https://tools.suckless.org/dmenu/patches/initialtext/) - - adds an option to provide preselected text - - - input-method - - adds support for input methods (fctix, ibus, etc.) - - - [instant](https://tools.suckless.org/dmenu/patches/instant/) - - adds a flag that will cause dmenu to select an item immediately if there is only one - matching option left - - - [~json~](https://tools.suckless.org/dmenu/patches/json/) - - ~adds basic support for json files~ - - - [line-height](http://tools.suckless.org/dmenu/patches/line-height/) - - adds a `-h` option which sets the minimum height of a dmenu line - - this helps integrate dmenu with other UI elements that require a particular vertical size - - - [managed](https://tools.suckless.org/dmenu/patches/managed/) - - adds a `-wm` flag which sets override_redirect to false; thus letting your window manager - manage the dmenu window - - this may be helpful in contexts where you don't want to exclusively bind dmenu or want to - treat dmenu more as a "window" rather than as an overlay - - - [morecolor](https://tools.suckless.org/dmenu/patches/morecolor/) - - adds an additional color scheme for highlighting entries adjacent to the current selection - - - [mouse-support](https://tools.suckless.org/dmenu/patches/mouse-support/) - - adds basic mouse support for dmenu - - - [multi-selection](https://tools.suckless.org/dmenu/patches/multi-selection/) - - without this patch when you press `Ctrl+Enter` dmenu just outputs current item and it is - not possible to undo that - - with this patch dmenu will output all selected items only on exit - - it is also possible to deselect any selected item - - - [navhistory](https://tools.suckless.org/dmenu/patches/navhistory/) - - provides dmenu the ability for history navigation similar to that of bash - - - [no-sort](https://tools.suckless.org/dmenu/patches/no-sort/) - - adds the `-S` option to disable sorting menu items after matching - - useful, for example, when menu items are sorted by their frequency of use (using an - external cache) and the most frequently selected items should always appear first regardless - of how they were exact, prefix, or substring matches - - - [non-blocking-stdin](https://tools.suckless.org/dmenu/patches/non_blocking_stdin/) - - this is a patch to have dmenu read stdin in a non blocking way, making it wait for input - both from stdin and from X - - this means that you can continue feeding dmenu while you type - - the patch is meant to be used along with the incremental patch in order to use stdout to - feed stdin - - - [numbers](https://tools.suckless.org/dmenu/patches/numbers/) - - adds text which displays the number of matched and total items in the top right corner of - dmenu - - - [pango](https://github.com/StillANixRookie/dmenu-pango/) - - adds simple markup for dmenu using pango markup - - - [password](https://tools.suckless.org/dmenu/patches/password/) - - with this patch dmenu will not directly display the keyboard input, but instead replace it - with dots - - all data from stdin will be ignored - - - [pipeout](https://tools.suckless.org/dmenu/patches/pipeout/) - - this patch allows the selected text to be piped back out with dmenu - - this can be useful if you want to display the output of a command on the screen - - - [plain-prompt](https://tools.suckless.org/dmenu/patches/listfullwidth/) - - simple change that avoids colors for the prompt by making it use the same style as the - rest of the input field - - - [prefix-completion](https://tools.suckless.org/dmenu/patches/prefix-completion/) - - changes the behaviour of matched items and the Tab key to allow tab completion - - - [preselect](https://tools.suckless.org/dmenu/patches/preselect/) - - adds an option `-ps` to preselect an item by providing the index that should be pre-selected - - - [printindex](https://tools.suckless.org/dmenu/patches/printindex/) - - allows dmenu to print out the 0-based index of matched text instead of the matched text - itself - - this can be useful in cases where you would like to select entries from one array of text - but index into another, or when you are selecting from an ordered list of non-unique items - - - [printinputtext](https://tools.suckless.org/dmenu/patches/printinputtext/) - - this patch adds a flag `-t` which makes Return key ignore selection and print the input - text to stdout - - the flag basically swaps the functions of Return and Shift+Return hotkeys - - - [rejectnomatch](https://tools.suckless.org/dmenu/patches/reject-no-match/) - - adds a new flag to dmenu with which text input will be rejected if it would result in no - matching item - - - relative_input_width - - prior to commit [e1e1de7](https://git.suckless.org/dmenu/commit/e1e1de7b3b8399cba90ddca9613f837b2dbef7b9.html) - the input width was calculated based on the input options - - this feature was removed in favour of hardcoding the input width to always take up 1/3rd of - the available space - - this patch adds that feature back in with some bespoke performance optimisations at the cost - of accuracy and correctness - - - [restrict-return](https://tools.suckless.org/dmenu/patches/restrict-return/) - - adds a `-1` option which disables Shift-Return and Ctrl-Return - - this guarantees that dmenu will only output one item, and that item was read from stdin - - - [scroll](https://tools.suckless.org/dmenu/patches/scroll/) - - this patch adds support for text scrolling - - it doesn't append `...` for long input anymore as it can handle long text - - - [separator](https://tools.suckless.org/dmenu/patches/separator/) - - adds `-d` and `-D` flags which separates the input into two halves; one half to be - displayed in dmenu and the other to be printed to stdout - - - [symbols](https://tools.suckless.org/dmenu/patches/symbols/) - - allows the symbols, which are printed in dmenu to indicate that either the input is too - long or there are too many options to be shown in dmenu in one line, to be defined - - - [tsv](https://tools.suckless.org/dmenu/patches/tsv/) - - makes dmenu split input lines at first tab character and only display first part, but it - will perform matching on and output full lines as usual - - can be useful if you want to separate data and representation - - - [vertfull](https://tools.suckless.org/dmenu/patches/vertfull/) - - prevents dmenu from indenting items at the same level as the prompt length - - - [wmtype](https://github.com/Baitinq/dmenu/blob/master/patches/dmenu-wm_type.diff) - - adds extended window manager hints such as \_NET_WM_WINDOW_TYPE and \_NET_WM_WINDOW_TYPE_DOCK - - - [xresources](https://tools.suckless.org/dmenu/patches/xresources/) - - allows dmenu to read font and colors from Xresources - - note that with this patch the Xresources settings takes precedence over command line arguments - - - [xyw](https://tools.suckless.org/dmenu/patches/xyw/) - - adds options for specifying dmenu window position and width diff --git a/menu/config.def.h b/menu/config.def.h index a30957a..1edb647 100644 --- a/menu/config.def.h +++ b/menu/config.def.h @@ -1,153 +1,23 @@ /* See LICENSE file for copyright and license details. */ /* Default settings; can be overriden by command line. */ -static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ -#if ALPHA_PATCH -static int opacity = 1; /* -o option; if 0, then alpha is disabled */ -#endif // ALPHA_PATCH -#if CARET_WIDTH_PATCH -static int caret_width = 2; /* -cw option; set default caret width */ -#endif // CARET_WIDTH_PATCH -#if FUZZYMATCH_PATCH -static int fuzzy = 1; /* -F option; if 0, dmenu doesn't use fuzzy matching */ -#endif // FUZZYMATCH_PATCH -#if INCREMENTAL_PATCH -static int incremental = 0; /* -r option; if 1, outputs text each time a key is pressed */ -#endif // INCREMENTAL_PATCH -#if INSTANT_PATCH -static int instant = 0; /* -n option; if 1, selects matching item without the need to press enter */ -#endif // INSTANT_PATCH -#if CENTER_PATCH -static int center = 0; /* -c option; if 0, dmenu won't be centered on the screen */ -static int min_width = 500; /* minimum width when centered */ -#endif // CENTER_PATCH -#if BARPADDING_PATCH -static const int vertpad = 10; /* vertical padding of bar */ -static const int sidepad = 10; /* horizontal padding of bar */ -#endif // BARPADDING_PATCH -#if RESTRICT_RETURN_PATCH -static int restrict_return = 0; /* -1 option; if 1, disables shift-return and ctrl-return */ -#endif // RESTRICT_RETURN_PATCH +static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ /* -fn option overrides fonts[0]; default X11 font or font set */ -#if PANGO_PATCH -static char *font = "monospace 10"; -#else -#if XRESOURCES_PATCH -static char *fonts[] = -#else -static const char *fonts[] = -#endif // XRESOURCES_PATCH -{ +static const char *fonts[] = { "monospace:size=10" }; -#endif // PANGO_PATCH -#if MANAGED_PATCH -static char *prompt = NULL; /* -p option; prompt to the left of input field */ -#else static const char *prompt = NULL; /* -p option; prompt to the left of input field */ -#endif // MANAGED_PATCH -#if DYNAMIC_OPTIONS_PATCH -static const char *dynamic = NULL; /* -dy option; dynamic command to run on input change */ -#endif // DYNAMIC_OPTIONS_PATCH -#if SYMBOLS_PATCH -static const char *symbol_1 = "<"; -static const char *symbol_2 = ">"; -#endif // SYMBOLS_PATCH - -#if ALPHA_PATCH -static const unsigned int baralpha = 0xd0; -static const unsigned int borderalpha = OPAQUE; -static const unsigned int alphas[][3] = { - /* fg bg border */ - [SchemeNorm] = { OPAQUE, baralpha, borderalpha }, - [SchemeSel] = { OPAQUE, baralpha, borderalpha }, - #if BORDER_PATCH - [SchemeBorder] = { OPAQUE, OPAQUE, OPAQUE }, - #endif // BORDER_PATCH - #if MORECOLOR_PATCH - [SchemeMid] = { OPAQUE, baralpha, borderalpha }, - #endif // MORECOLOR_PATCH - #if HIGHLIGHT_PATCH - [SchemeSelHighlight] = { OPAQUE, baralpha, borderalpha }, - [SchemeNormHighlight] = { OPAQUE, baralpha, borderalpha }, - #endif // HIGHLIGHT_PATCH - #if HIGHPRIORITY_PATCH - [SchemeHp] = { OPAQUE, baralpha, borderalpha }, - #endif // HIGHPRIORITY_PATCH - #if EMOJI_HIGHLIGHT_PATCH - [SchemeHover] = { OPAQUE, baralpha, borderalpha }, - [SchemeGreen] = { OPAQUE, baralpha, borderalpha }, - [SchemeRed] = { OPAQUE, baralpha, borderalpha }, - [SchemeYellow] = { OPAQUE, baralpha, borderalpha }, - [SchemeBlue] = { OPAQUE, baralpha, borderalpha }, - [SchemePurple] = { OPAQUE, baralpha, borderalpha }, - #endif // EMOJI_HIGHLIGHT_PATCH -}; -#endif // ALPHA_PATCH - -static -#if !XRESOURCES_PATCH -const -#endif // XRESOURCES_PATCH -char *colors[][2] = { - /* fg bg */ +static const char *colors[SchemeLast][2] = { + /* fg bg */ [SchemeNorm] = { "#bbbbbb", "#222222" }, - [SchemeSel] = { "#eeeeee", "#005577" }, - [SchemeOut] = { "#000000", "#00ffff" }, - #if BORDER_PATCH - [SchemeBorder] = { "#000000", "#005577" }, - #endif // BORDER_PATCH - #if MORECOLOR_PATCH - [SchemeMid] = { "#eeeeee", "#770000" }, - #endif // MORECOLOR_PATCH - #if HIGHLIGHT_PATCH - [SchemeSelHighlight] = { "#ffc978", "#005577" }, - [SchemeNormHighlight] = { "#ffc978", "#222222" }, - #endif // HIGHLIGHT_PATCH - #if HIGHPRIORITY_PATCH - [SchemeHp] = { "#bbbbbb", "#333333" }, - #endif // HIGHPRIORITY_PATCH - #if EMOJI_HIGHLIGHT_PATCH - [SchemeHover] = { "#ffffff", "#353D4B" }, - [SchemeGreen] = { "#ffffff", "#52E067" }, - [SchemeRed] = { "#ffffff", "#e05252" }, - [SchemeYellow] = { "#ffffff", "#e0c452" }, - [SchemeBlue] = { "#ffffff", "#5280e0" }, - [SchemePurple] = { "#ffffff", "#9952e0" }, - #endif // EMOJI_HIGHLIGHT_PATCH + [SchemeSel] = { "#eeeeee", "#005577" }, + [SchemeOut] = { "#000000", "#00ffff" }, }; /* -l option; if nonzero, dmenu uses vertical list with given number of lines */ static unsigned int lines = 0; -#if GRID_PATCH -/* -g option; if nonzero, dmenu uses a grid comprised of columns and lines */ -static unsigned int columns = 0; -#endif // GRID_PATCH -#if LINE_HEIGHT_PATCH -static unsigned int lineheight = 0; /* -h option; minimum height of a menu line */ -static unsigned int min_lineheight = 8; -#endif // LINE_HEIGHT_PATCH -#if NAVHISTORY_PATCH -static unsigned int maxhist = 15; -static int histnodup = 1; /* if 0, record repeated histories */ -#endif // NAVHISTORY_PATCH /* * Characters not considered part of a word while deleting words * for example: " /?\"&[]" */ -#if PIPEOUT_PATCH -static const char startpipe[] = "#"; -#endif // PIPEOUT_PATCH static const char worddelimiters[] = " "; - -#if BORDER_PATCH -/* Size of the window border */ -static unsigned int border_width = 0; -#endif // BORDER_PATCH - -#if PREFIXCOMPLETION_PATCH -/* - * Use prefix matching by default; can be inverted with the -x flag. - */ -static int use_prefix = 1; -#endif // PREFIXCOMPLETION_PATCH diff --git a/menu/config.h b/menu/config.h new file mode 100644 index 0000000..1edb647 --- /dev/null +++ b/menu/config.h @@ -0,0 +1,23 @@ +/* See LICENSE file for copyright and license details. */ +/* Default settings; can be overriden by command line. */ + +static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ +/* -fn option overrides fonts[0]; default X11 font or font set */ +static const char *fonts[] = { + "monospace:size=10" +}; +static const char *prompt = NULL; /* -p option; prompt to the left of input field */ +static const char *colors[SchemeLast][2] = { + /* fg bg */ + [SchemeNorm] = { "#bbbbbb", "#222222" }, + [SchemeSel] = { "#eeeeee", "#005577" }, + [SchemeOut] = { "#000000", "#00ffff" }, +}; +/* -l option; if nonzero, dmenu uses vertical list with given number of lines */ +static unsigned int lines = 0; + +/* + * Characters not considered part of a word while deleting words + * for example: " /?\"&[]" + */ +static const char worddelimiters[] = " "; diff --git a/menu/config.mk b/menu/config.mk index 9d94f27..137f7c8 100644 --- a/menu/config.mk +++ b/menu/config.mk @@ -19,22 +19,12 @@ FREETYPEINC = /usr/include/freetype2 #FREETYPEINC = $(X11INC)/freetype2 #MANPREFIX = ${PREFIX}/man -# uncomment on RHEL for strcasecmp -#EXTRAFLAGS=-D_GNU_SOURCE - -# Uncomment this for the alpha patch / ALPHA_PATCH -XRENDER = -lXrender - -# Uncomment for the pango patch / PANGO_PATCH -#PANGOINC = `pkg-config --cflags xft pango pangoxft` -#PANGOLIB = `pkg-config --libs xft pango pangoxft` - # includes and libs -INCS = -I$(X11INC) -I$(FREETYPEINC) ${PANGOINC} -LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) -lm $(XRENDER) ${PANGOLIB} +INCS = -I$(X11INC) -I$(FREETYPEINC) +LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) # flags -CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS) $(EXTRAFLAGS) +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS) CFLAGS = -std=c99 -pedantic -Wall -Os $(INCS) $(CPPFLAGS) LDFLAGS = $(LIBS) diff --git a/menu/dmenu.c b/menu/dmenu.c index b99c6fe..fd49549 100644 --- a/menu/dmenu.c +++ b/menu/dmenu.c @@ -16,168 +16,47 @@ #endif #include -#include "patches.h" -/* Patch incompatibility overrides */ -#if MULTI_SELECTION_PATCH -#undef NON_BLOCKING_STDIN_PATCH -#undef PIPEOUT_PATCH -#undef PRINTINPUTTEXT_PATCH -#endif // MULTI_SELECTION_PATCH - #include "drw.h" #include "util.h" -#if GRIDNAV_PATCH -#include -#endif // GRIDNAV_PATCH /* macros */ #define INTERSECT(x,y,w,h,r) (MAX(0, MIN((x)+(w),(r).x_org+(r).width) - MAX((x),(r).x_org)) \ * MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org))) -#if PANGO_PATCH -#define TEXTW(X) (drw_font_getwidth(drw, (X), False) + lrpad) -#define TEXTWM(X) (drw_font_getwidth(drw, (X), True) + lrpad) -#else #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) -#endif // PANGO_PATCH -#if ALPHA_PATCH -#define OPAQUE 0xffU -#define OPACITY "_NET_WM_WINDOW_OPACITY" -#endif // ALPHA_PATCH /* enums */ -enum { - SchemeNorm, - SchemeSel, - SchemeOut, - #if BORDER_PATCH - SchemeBorder, - #endif // BORDER_PATCH - #if MORECOLOR_PATCH - SchemeMid, - #endif // MORECOLOR_PATCH - #if HIGHLIGHT_PATCH - SchemeNormHighlight, - SchemeSelHighlight, - #endif // HIGHLIGHT_PATCH - #if HIGHPRIORITY_PATCH - SchemeHp, - #endif // HIGHPRIORITY_PATCH - #if EMOJI_HIGHLIGHT_PATCH - SchemeHover, - SchemeGreen, - SchemeYellow, - SchemeBlue, - SchemePurple, - SchemeRed, - #endif // EMOJI_HIGHLIGHT_PATCH - SchemeLast, -}; /* color schemes */ +enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ struct item { char *text; - #if SEPARATOR_PATCH - char *text_output; - #elif TSV_PATCH - char *stext; - #endif // SEPARATOR_PATCH | TSV_PATCH struct item *left, *right; - #if NON_BLOCKING_STDIN_PATCH - struct item *next; - #endif // NON_BLOCKING_STDIN_PATCH - #if MULTI_SELECTION_PATCH - int id; /* for multiselect */ - #else int out; - #endif // MULTI_SELECTION_PATCH - #if HIGHPRIORITY_PATCH - int hp; - #endif // HIGHPRIORITY_PATCH - #if FUZZYMATCH_PATCH - double distance; - #endif // FUZZYMATCH_PATCH - #if PRINTINDEX_PATCH - int index; - #endif // PRINTINDEX_PATCH }; static char text[BUFSIZ] = ""; -#if PIPEOUT_PATCH -static char pipeout[8] = " | dmenu"; -#endif // PIPEOUT_PATCH static char *embed; -#if SEPARATOR_PATCH -static char separator; -static int separator_greedy; -static int separator_reverse; -#endif // SEPARATOR_PATCH static int bh, mw, mh; -#if XYW_PATCH -static int dmx = 0, dmy = 0; /* put dmenu at these x and y offsets */ -static unsigned int dmw = 0; /* make dmenu this wide */ -#endif // XYW_PATCH static int inputw = 0, promptw; -#if PASSWORD_PATCH -static int passwd = 0; -#endif // PASSWORD_PATCH static int lrpad; /* sum of left and right padding */ -#if BARPADDING_PATCH -static int vp; /* vertical padding for bar */ -static int sp; /* side padding for bar */ -#endif // BARPADDING_PATCH -#if REJECTNOMATCH_PATCH -static int reject_no_match = 0; -#endif // REJECTNOMATCH_PATCH static size_t cursor; static struct item *items = NULL; static struct item *matches, *matchend; static struct item *prev, *curr, *next, *sel; static int mon = -1, screen; -#if PRINTINDEX_PATCH -static int print_index = 0; -#endif // PRINTINDEX_PATCH -#if MANAGED_PATCH -static int managed = 0; -#endif // MANAGED_PATCH -#if MULTI_SELECTION_PATCH -static int *selid = NULL; -static unsigned int selidsize = 0; -#endif // MULTI_SELECTION_PATCH -#if NO_SORT_PATCH -static unsigned int sortmatches = 1; -#endif // NO_SORT_PATCH -#if PRINTINPUTTEXT_PATCH -static int use_text_input = 0; -#endif // PRINTINPUTTEXT_PATCH -#if PRESELECT_PATCH -static unsigned int preselected = 0; -#endif // PRESELECT_PATCH -#if EMOJI_HIGHLIGHT_PATCH -static int commented = 0; -static int animated = 0; -#endif // EMOJI_HIGHLIGHT_PATCH static Atom clip, utf8; -#if WMTYPE_PATCH -static Atom type, dock; -#endif // WMTYPE_PATCH static Display *dpy; static Window root, parentwin, win; static XIC xic; -#if ALPHA_PATCH -static int useargb = 0; -static Visual *visual; -static int depth; -static Colormap cmap; -#endif // ALPHA_PATCH - static Drw *drw; static Clr *scheme[SchemeLast]; -#include "patch/include.h" - #include "config.h" +static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; +static char *(*fstrstr)(const char *, const char *) = strstr; + static unsigned int textw_clamp(const char *str, unsigned int n) { @@ -185,38 +64,6 @@ textw_clamp(const char *str, unsigned int n) return MIN(w, n); } -static void appenditem(struct item *item, struct item **list, struct item **last); -static void calcoffsets(void); -static void cleanup(void); -static char * cistrstr(const char *s, const char *sub); -static int drawitem(struct item *item, int x, int y, int w); -static void drawmenu(void); -static void grabfocus(void); -static void grabkeyboard(void); -static void match(void); -static void insert(const char *str, ssize_t n); -static size_t nextrune(int inc); -static void movewordedge(int dir); -static void keypress(XKeyEvent *ev); -static void paste(void); -#if ALPHA_PATCH -static void xinitvisual(void); -#endif // ALPHA_PATCH -static void readstdin(void); -static void run(void); -static void setup(void); -static void usage(void); - -#if CASEINSENSITIVE_PATCH -static int (*fstrncmp)(const char *, const char *, size_t) = strncasecmp; -static char *(*fstrstr)(const char *, const char *) = cistrstr; -#else -static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; -static char *(*fstrstr)(const char *, const char *) = strstr; -#endif // CASEINSENSITIVE_PATCH - -#include "patch/include.c" - static void appenditem(struct item *item, struct item **list, struct item **last) { @@ -233,27 +80,12 @@ appenditem(struct item *item, struct item **list, struct item **last) static void calcoffsets(void) { - int i, n, rpad = 0; + int i, n; - if (lines > 0) { - #if GRID_PATCH - if (columns) - n = lines * columns * bh; - else - n = lines * bh; - #else + if (lines > 0) n = lines * bh; - #endif // GRID_PATCH - } else { - #if NUMBERS_PATCH - rpad = TEXTW(numbers); - #endif // NUMBERS_PATCH - #if SYMBOLS_PATCH - n = mw - (promptw + inputw + TEXTW(symbol_1) + TEXTW(symbol_2) + rpad); - #else - n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">") + rpad); - #endif // SYMBOLS_PATCH - } + else + n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">")); /* calculate which items will begin the next page and previous page */ for (i = 0, next = curr; next; next = next->right) if ((i += (lines > 0) ? bh : textw_clamp(next->text, n)) > n) @@ -269,452 +101,94 @@ cleanup(void) size_t i; XUngrabKeyboard(dpy, CurrentTime); - #if INPUTMETHOD_PATCH - XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); - #endif // INPUTMETHOD_PATCH for (i = 0; i < SchemeLast; i++) free(scheme[i]); - for (i = 0; items && items[i].text; ++i) { - #if SEPARATOR_PATCH - free(separator_reverse ? items[i].text_output : items[i].text); - #else + for (i = 0; items && items[i].text; ++i) free(items[i].text); - #endif // SEPARATOR_PATCH - } free(items); - #if HIGHPRIORITY_PATCH - for (i = 0; i < hplength; ++i) - free(hpitems[i]); - free(hpitems); - #endif // HIGHPRIORITY_PATCH drw_free(drw); XSync(dpy, False); XCloseDisplay(dpy); - #if MULTI_SELECTION_PATCH - free(selid); - #endif // MULTI_SELECTION_PATCH } static char * -cistrstr(const char *s, const char *sub) +cistrstr(const char *h, const char *n) { - size_t len; + size_t i; - for (len = strlen(sub); *s; s++) - if (!strncasecmp(s, sub, len)) - return (char *)s; + if (!n[0]) + return (char *)h; + + for (; *h; ++h) { + for (i = 0; n[i] && tolower((unsigned char)n[i]) == + tolower((unsigned char)h[i]); ++i) + ; + if (n[i] == '\0') + return (char *)h; + } return NULL; } static int drawitem(struct item *item, int x, int y, int w) { - int r; - #if TSV_PATCH && !SEPARATOR_PATCH - char *text = item->stext; - #else - char *text = item->text; - #endif // TSV_PATCH - - #if EMOJI_HIGHLIGHT_PATCH - int iscomment = 0; - if (text[0] == '>') { - if (text[1] == '>') { - iscomment = 3; - switch (text[2]) { - case 'r': - drw_setscheme(drw, scheme[SchemeRed]); - break; - case 'g': - drw_setscheme(drw, scheme[SchemeGreen]); - break; - case 'y': - drw_setscheme(drw, scheme[SchemeYellow]); - break; - case 'b': - drw_setscheme(drw, scheme[SchemeBlue]); - break; - case 'p': - drw_setscheme(drw, scheme[SchemePurple]); - break; - #if HIGHLIGHT_PATCH - case 'h': - drw_setscheme(drw, scheme[SchemeNormHighlight]); - break; - #endif // HIGHLIGHT_PATCH - case 's': - drw_setscheme(drw, scheme[SchemeSel]); - break; - default: - iscomment = 1; - drw_setscheme(drw, scheme[SchemeNorm]); - break; - } - } else { - drw_setscheme(drw, scheme[SchemeNorm]); - iscomment = 1; - } - } else if (text[0] == ':') { - iscomment = 2; - if (item == sel) { - switch (text[1]) { - case 'r': - drw_setscheme(drw, scheme[SchemeRed]); - break; - case 'g': - drw_setscheme(drw, scheme[SchemeGreen]); - break; - case 'y': - drw_setscheme(drw, scheme[SchemeYellow]); - break; - case 'b': - drw_setscheme(drw, scheme[SchemeBlue]); - break; - case 'p': - drw_setscheme(drw, scheme[SchemePurple]); - break; - #if HIGHLIGHT_PATCH - case 'h': - drw_setscheme(drw, scheme[SchemeNormHighlight]); - break; - #endif // HIGHLIGHT_PATCH - case 's': - drw_setscheme(drw, scheme[SchemeSel]); - break; - default: - drw_setscheme(drw, scheme[SchemeSel]); - iscomment = 0; - break; - } - } else { - drw_setscheme(drw, scheme[SchemeNorm]); - } - } - #endif // EMOJI_HIGHLIGHT_PATCH - - #if EMOJI_HIGHLIGHT_PATCH - int temppadding = 0; - if (iscomment == 2) { - if (text[2] == ' ') { - #if PANGO_PATCH - temppadding = drw->font->h * 3; - #else - temppadding = drw->fonts->h * 3; - #endif // PANGO_PATCH - animated = 1; - char dest[1000]; - strcpy(dest, text); - dest[6] = '\0'; - drw_text(drw, x, y - , temppadding - #if LINE_HEIGHT_PATCH - , MAX(lineheight, bh) - #else - , bh - #endif // LINE_HEIGHT_PATCH - , temppadding / 2.6 - , dest + 3 - , 0 - #if PANGO_PATCH - , True - #endif // PANGO_PATCH - ); - iscomment = 6; - drw_setscheme(drw, sel == item ? scheme[SchemeHover] : scheme[SchemeNorm]); - } - } - - char *output; - if (commented) { - static char onestr[2]; - onestr[0] = text[0]; - onestr[1] = '\0'; - output = onestr; - } else { - output = text; - } - #endif // EMOJI_HIGHLIGHT_PATCH - if (item == sel) drw_setscheme(drw, scheme[SchemeSel]); - #if HIGHPRIORITY_PATCH - else if (item->hp) - drw_setscheme(drw, scheme[SchemeHp]); - #endif // HIGHPRIORITY_PATCH - #if MORECOLOR_PATCH - else if (item->left == sel || item->right == sel) - drw_setscheme(drw, scheme[SchemeMid]); - #endif // MORECOLOR_PATCH - #if MULTI_SELECTION_PATCH - else if (issel(item->id)) - #else else if (item->out) - #endif // MULTI_SELECTION_PATCH drw_setscheme(drw, scheme[SchemeOut]); else drw_setscheme(drw, scheme[SchemeNorm]); - r = drw_text(drw - #if EMOJI_HIGHLIGHT_PATCH - , x + ((iscomment == 6) ? temppadding : 0) - #else - , x - #endif // EMOJI_HIGHLIGHT_PATCH - , y - , w - , bh - #if EMOJI_HIGHLIGHT_PATCH - , commented ? (bh - TEXTW(output) - lrpad) / 2 : lrpad / 2 - #else - , lrpad / 2 - #endif // EMOJI_HIGHLIGHT_PATCH - #if EMOJI_HIGHLIGHT_PATCH - , output + iscomment - #else - , text - #endif // EMOJI_HIGHLIGHT_PATCH - , 0 - #if PANGO_PATCH - , True - #endif // PANGO_PATCH - ); - #if HIGHLIGHT_PATCH - #if EMOJI_HIGHLIGHT_PATCH - drawhighlights(item, output + iscomment, x + ((iscomment == 6) ? temppadding : 0), y, w); - #else - drawhighlights(item, x, y, w); - #endif // EMOJI_HIGHLIGHT_PATCH - #endif // HIGHLIGHT_PATCH - return r; + return drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0); } static void drawmenu(void) { - #if SCROLL_PATCH - static int curpos, oldcurlen; - int curlen, rcurlen; - #else unsigned int curpos; - #endif // SCROLL_PATCH struct item *item; - int x = 0, y = 0, w, rpad = 0, itw = 0, stw = 0; - #if LINE_HEIGHT_PATCH && PANGO_PATCH - int fh = drw->font->h; - #elif LINE_HEIGHT_PATCH - int fh = drw->fonts->h; - #endif // LINE_HEIGHT_PATCH - #if PASSWORD_PATCH - char *censort; - #endif // PASSWORD_PATCH + int x = 0, y = 0, w; drw_setscheme(drw, scheme[SchemeNorm]); drw_rect(drw, 0, 0, mw, mh, 1, 1); if (prompt && *prompt) { - #if !PLAIN_PROMPT_PATCH drw_setscheme(drw, scheme[SchemeSel]); - #endif // PLAIN_PROMPT_PATCH - x = drw_text(drw, x, 0, promptw, bh, lrpad / 2, prompt, 0 - #if PANGO_PATCH - , True - #endif // PANGO_PATCH - ); + x = drw_text(drw, x, 0, promptw, bh, lrpad / 2, prompt, 0); } /* draw input field */ w = (lines > 0 || !matches) ? mw - x : inputw; - - #if SCROLL_PATCH - w -= lrpad / 2; - x += lrpad / 2; - rcurlen = TEXTW(text + cursor) - lrpad; - curlen = TEXTW(text) - lrpad - rcurlen; - curpos += curlen - oldcurlen; - curpos = MIN(w, MAX(0, curpos)); - curpos = MAX(curpos, w - rcurlen); - curpos = MIN(curpos, curlen); - oldcurlen = curlen; - drw_setscheme(drw, scheme[SchemeNorm]); - #if PASSWORD_PATCH - if (passwd) { - censort = ecalloc(1, sizeof(text)); - memset(censort, '.', strlen(text)); - drw_text_align(drw, x, 0, curpos, bh, censort, cursor, AlignR); - drw_text_align(drw, x + curpos, 0, w - curpos, bh, censort + cursor, strlen(censort) - cursor, AlignL); - free(censort); - } else { - drw_text_align(drw, x, 0, curpos, bh, text, cursor, AlignR); - drw_text_align(drw, x + curpos, 0, w - curpos, bh, text + cursor, strlen(text) - cursor, AlignL); - } - #else - drw_text_align(drw, x, 0, curpos, bh, text, cursor, AlignR); - drw_text_align(drw, x + curpos, 0, w - curpos, bh, text + cursor, strlen(text) - cursor, AlignL); - #endif // PASSWORD_PATCH - #if LINE_HEIGHT_PATCH - drw_rect(drw, x + curpos - 1, 2 + (bh-fh)/2, 2, fh - 4, 1, 0); - #else - drw_rect(drw, x + curpos - 1, 2, 2, bh - 4, 1, 0); - #endif // LINE_HEIGHT_PATCH - #else // !SCROLL_PATCH - drw_setscheme(drw, scheme[SchemeNorm]); - #if PASSWORD_PATCH - if (passwd) { - censort = ecalloc(1, sizeof(text)); - memset(censort, '.', strlen(text)); - drw_text(drw, x, 0, w, bh, lrpad / 2, censort, 0 - #if PANGO_PATCH - , False - #endif // PANGO_PATCH - ); - drw_text(drw, x, 0, w, bh, lrpad / 2, censort, 0 - #if PANGO_PATCH - , False - #endif // PANGO_PATCH - ); - free(censort); - } else { - drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0 - #if PANGO_PATCH - , False - #endif // PANGO_PATCH - ); - } - #else - drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0 - #if PANGO_PATCH - , False - #endif // PANGO_PATCH - ); - #endif // PASSWORD_PATCH + drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0); curpos = TEXTW(text) - TEXTW(&text[cursor]); if ((curpos += lrpad / 2 - 1) < w) { drw_setscheme(drw, scheme[SchemeNorm]); - #if CARET_WIDTH_PATCH && LINE_HEIGHT_PATCH - drw_rect(drw, x + curpos, 2 + (bh-fh)/2, caret_width, fh - 4, 1, 0); - #elif CARET_WIDTH_PATCH - drw_rect(drw, x + curpos, 2, caret_width, bh - 4, 1, 0); - #elif LINE_HEIGHT_PATCH - drw_rect(drw, x + curpos, 2 + (bh-fh)/2, 2, fh - 4, 1, 0); - #else drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0); - #endif // LINE_HEIGHT_PATCH } - #endif // SCROLL_PATCH - #if NUMBERS_PATCH - recalculatenumbers(); - rpad = TEXTW(numbers); - #if BARPADDING_PATCH - rpad += 2 * sp; - #endif // BARPADDING_PATCH - #if BORDER_PATCH - rpad += border_width; - #endif // BORDER_PATCH - #endif // NUMBERS_PATCH if (lines > 0) { - #if GRID_PATCH - /* draw grid */ - int i = 0; - for (item = curr; item != next; item = item->right, i++) - if (columns) - #if VERTFULL_PATCH - drawitem( - item, - 0 + ((i / lines) * (mw / columns)), - y + (((i % lines) + 1) * bh), - mw / columns - ); - #else - drawitem( - item, - x + ((i / lines) * ((mw - x) / columns)), - y + (((i % lines) + 1) * bh), - (mw - x) / columns - ); - #endif // VERTFULL_PATCH - else - #if VERTFULL_PATCH - drawitem(item, 0, y += bh, mw); - #else - drawitem(item, x, y += bh, mw - x); - #endif // VERTFULL_PATCH - #else /* draw vertical list */ for (item = curr; item != next; item = item->right) - #if VERTFULL_PATCH - drawitem(item, 0, y += bh, mw); - #else drawitem(item, x, y += bh, mw - x); - #endif // VERTFULL_PATCH - #endif // GRID_PATCH } else if (matches) { /* draw horizontal list */ x += inputw; - #if SYMBOLS_PATCH - w = TEXTW(symbol_1); - #else w = TEXTW("<"); - #endif // SYMBOLS_PATCH if (curr->left) { drw_setscheme(drw, scheme[SchemeNorm]); - #if SYMBOLS_PATCH - drw_text(drw, x, 0, w, bh, lrpad / 2, symbol_1, 0 - #else - drw_text(drw, x, 0, w, bh, lrpad / 2, "<", 0 - #endif // SYMBOLS_PATCH - #if PANGO_PATCH - , True - #endif // PANGO_PATCH - ); + drw_text(drw, x, 0, w, bh, lrpad / 2, "<", 0); } x += w; - for (item = curr; item != next; item = item->right) { - #if SYMBOLS_PATCH - stw = TEXTW(symbol_2); - #else - stw = TEXTW(">"); - #endif // SYMBOLS_PATCH - #if TSV_PATCH && !SEPARATOR_PATCH - itw = textw_clamp(item->stext, mw - x - stw - rpad); - #else - itw = textw_clamp(item->text, mw - x - stw - rpad); - #endif // TSV_PATCH - x = drawitem(item, x, 0, itw); - } + for (item = curr; item != next; item = item->right) + x = drawitem(item, x, 0, textw_clamp(item->text, mw - x - TEXTW(">"))); if (next) { - #if SYMBOLS_PATCH - w = TEXTW(symbol_2); - #else w = TEXTW(">"); - #endif // SYMBOLS_PATCH drw_setscheme(drw, scheme[SchemeNorm]); - drw_text(drw, mw - w - rpad, 0, w, bh, lrpad / 2 - #if SYMBOLS_PATCH - , symbol_2 - #else - , ">" - #endif // SYMBOLS_PATCH - , 0 - #if PANGO_PATCH - , True - #endif // PANGO_PATCH - ); + drw_text(drw, mw - w, 0, w, bh, lrpad / 2, ">", 0); } } - #if NUMBERS_PATCH - drw_setscheme(drw, scheme[SchemeNorm]); - #if PANGO_PATCH - drw_text(drw, mw - rpad, 0, TEXTW(numbers), bh, lrpad / 2, numbers, 0, False); - #else - drw_text(drw, mw - rpad, 0, TEXTW(numbers), bh, lrpad / 2, numbers, 0); - #endif // PANGO_PATCH - #endif // NUMBERS_PATCH drw_map(drw, win, 0, 0, mw, mh); - #if NON_BLOCKING_STDIN_PATCH - XFlush(dpy); - #endif // NON_BLOCKING_STDIN_PATCH } static void @@ -728,9 +202,7 @@ grabfocus(void) XGetInputFocus(dpy, &focuswin, &revertwin); if (focuswin == win) return; - #if !MANAGED_PATCH XSetInputFocus(dpy, win, RevertToParent, CurrentTime); - #endif // MANAGED_PATCH nanosleep(&ts, NULL); } die("cannot grab focus"); @@ -742,23 +214,13 @@ grabkeyboard(void) struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 }; int i; - #if MANAGED_PATCH - if (embed || managed) - #else if (embed) - #endif // MANAGED_PATCH return; /* try to grab keyboard, we may have to wait for another process to ungrab */ for (i = 0; i < 1000; i++) { if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync, - GrabModeAsync, CurrentTime) == GrabSuccess) { - #if MOUSE_SUPPORT_PATCH - /* one off attempt at grabbing the mouse pointer to avoid interactions - * with other windows while dmenu is active */ - XGrabPointer(dpy, DefaultRootWindow(dpy), True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); - #endif // MOUSE_SUPPORT_PATCH + GrabModeAsync, CurrentTime) == GrabSuccess) return; - } nanosleep(&ts, NULL); } die("cannot grab keyboard"); @@ -767,17 +229,6 @@ grabkeyboard(void) static void match(void) { - #if DYNAMIC_OPTIONS_PATCH - if (dynamic && *dynamic) - refreshoptions(); - #endif // DYNAMIC_OPTIONS_PATCH - - #if FUZZYMATCH_PATCH - if (fuzzy) { - fuzzymatch(); - return; - } - #endif static char **tokv = NULL; static int tokn = 0; @@ -785,12 +236,6 @@ match(void) int i, tokc = 0; size_t len, textsize; struct item *item, *lprefix, *lsubstr, *prefixend, *substrend; - #if HIGHPRIORITY_PATCH - struct item *lhpprefix, *hpprefixend; - #endif // HIGHPRIORITY_PATCH - #if NON_BLOCKING_STDIN_PATCH - int preserve = 0; - #endif // NON_BLOCKING_STDIN_PATCH strcpy(buf, text); /* separate input text into tokens to be matched individually */ @@ -799,78 +244,22 @@ match(void) die("cannot realloc %zu bytes:", tokn * sizeof *tokv); len = tokc ? strlen(tokv[0]) : 0; - #if PREFIXCOMPLETION_PATCH - if (use_prefix) { - matches = lprefix = matchend = prefixend = NULL; - textsize = strlen(text); - } else { - matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL; - textsize = strlen(text) + 1; - } - #else matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL; textsize = strlen(text) + 1; - #endif // PREFIXCOMPLETION_PATCH - #if HIGHPRIORITY_PATCH - lhpprefix = hpprefixend = NULL; - #endif // HIGHPRIORITY_PATCH - #if NON_BLOCKING_STDIN_PATCH && DYNAMIC_OPTIONS_PATCH - for (item = items; item && (!(dynamic && *dynamic) || item->text); item = (dynamic && *dynamic) ? item + 1 : item->next) - #elif NON_BLOCKING_STDIN_PATCH - for (item = items; item; item = item->next) - #else - for (item = items; item && item->text; item++) - #endif - { + for (item = items; item && item->text; item++) { for (i = 0; i < tokc; i++) if (!fstrstr(item->text, tokv[i])) break; - #if DYNAMIC_OPTIONS_PATCH - if (i != tokc && !(dynamic && *dynamic)) /* not all tokens match */ - continue; - #else if (i != tokc) /* not all tokens match */ continue; - #endif // DYNAMIC_OPTIONS_PATCH - #if HIGHPRIORITY_PATCH - /* exact matches go first, then prefixes with high priority, then prefixes, then substrings */ - #else /* exact matches go first, then prefixes, then substrings */ - #endif // HIGHPRIORITY_PATCH - #if NO_SORT_PATCH - if (!sortmatches) - appenditem(item, &matches, &matchend); - else - #endif // NO_SORT_PATCH if (!tokc || !fstrncmp(text, item->text, textsize)) appenditem(item, &matches, &matchend); - #if HIGHPRIORITY_PATCH - else if (item->hp && !fstrncmp(tokv[0], item->text, len)) - appenditem(item, &lhpprefix, &hpprefixend); - #endif // HIGHPRIORITY_PATCH else if (!fstrncmp(tokv[0], item->text, len)) appenditem(item, &lprefix, &prefixend); - #if PREFIXCOMPLETION_PATCH - else if (!use_prefix) - #else else - #endif // PREFIXCOMPLETION_PATCH appenditem(item, &lsubstr, &substrend); - #if NON_BLOCKING_STDIN_PATCH - if (sel == item) - preserve = 1; - #endif // NON_BLOCKING_STDIN_PATCH } - #if HIGHPRIORITY_PATCH - if (lhpprefix) { - if (matches) { - matchend->right = lhpprefix; - lhpprefix->left = matchend; - } else - matches = lhpprefix; - matchend = hpprefixend; - } - #endif // HIGHPRIORITY_PATCH if (lprefix) { if (matches) { matchend->right = lprefix; @@ -879,12 +268,7 @@ match(void) matches = lprefix; matchend = prefixend; } - #if PREFIXCOMPLETION_PATCH - if (!use_prefix && lsubstr) - #else - if (lsubstr) - #endif // PREFIXCOMPLETION_PATCH - { + if (lsubstr) { if (matches) { matchend->right = lsubstr; lsubstr->left = matchend; @@ -892,19 +276,7 @@ match(void) matches = lsubstr; matchend = substrend; } - #if NON_BLOCKING_STDIN_PATCH - if (!preserve) - #endif // NON_BLOCKING_STDIN_PATCH curr = sel = matches; - - #if INSTANT_PATCH - if (instant && matches && matches==matchend && !lsubstr) { - puts(matches->text); - cleanup(); - exit(0); - } - #endif // INSTANT_PATCH - calcoffsets(); } @@ -913,30 +285,12 @@ insert(const char *str, ssize_t n) { if (strlen(text) + n > sizeof text - 1) return; - - #if REJECTNOMATCH_PATCH - static char last[BUFSIZ] = ""; - if (reject_no_match) { - /* store last text value in case we need to revert it */ - memcpy(last, text, BUFSIZ); - } - #endif // REJECTNOMATCH_PATCH - /* 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)); if (n > 0) memcpy(&text[cursor], str, n); cursor += n; match(); - - #if REJECTNOMATCH_PATCH - if (!matches && reject_no_match) { - /* revert to last text value if theres no match */ - memcpy(text, last, BUFSIZ); - cursor -= n; - match(); - } - #endif // REJECTNOMATCH_PATCH } static size_t @@ -971,16 +325,8 @@ keypress(XKeyEvent *ev) { char buf[64]; int len; - #if PREFIXCOMPLETION_PATCH - struct item * item; - #endif // PREFIXCOMPLETION_PATCH KeySym ksym = NoSymbol; Status status; - #if GRID_PATCH && GRIDNAV_PATCH - int i; - struct item *tmpsel; - bool offscreen = false; - #endif // GRIDNAV_PATCH len = XmbLookupString(xic, ev, buf, sizeof buf, &ksym, &status); switch (status) { @@ -995,30 +341,6 @@ keypress(XKeyEvent *ev) if (ev->state & ControlMask) { switch(ksym) { - #if FZFEXPECT_PATCH - case XK_a: expect("ctrl-a", ev); ksym = XK_Home; break; - case XK_b: expect("ctrl-b", ev); ksym = XK_Left; break; - case XK_c: expect("ctrl-c", ev); ksym = XK_Escape; break; - case XK_d: expect("ctrl-d", ev); ksym = XK_Delete; break; - case XK_e: expect("ctrl-e", ev); ksym = XK_End; break; - case XK_f: expect("ctrl-f", ev); ksym = XK_Right; break; - case XK_g: expect("ctrl-g", ev); ksym = XK_Escape; break; - case XK_h: expect("ctrl-h", ev); ksym = XK_BackSpace; break; - case XK_i: expect("ctrl-i", ev); ksym = XK_Tab; break; - case XK_j: expect("ctrl-j", ev); ksym = XK_Down; break; - case XK_J:/* fallthrough */ - case XK_l: expect("ctrl-l", ev); break; - case XK_m: expect("ctrl-m", ev); /* fallthrough */ - case XK_M: ksym = XK_Return; ev->state &= ~ControlMask; break; - case XK_n: expect("ctrl-n", ev); ksym = XK_Down; break; - case XK_p: expect("ctrl-p", ev); ksym = XK_Up; break; - case XK_o: expect("ctrl-o", ev); break; - case XK_q: expect("ctrl-q", ev); break; - case XK_r: expect("ctrl-r", ev); break; - case XK_s: expect("ctrl-s", ev); break; - case XK_t: expect("ctrl-t", ev); break; - case XK_k: expect("ctrl-k", ev); ksym = XK_Up; break; - #else case XK_a: ksym = XK_Home; break; case XK_b: ksym = XK_Left; break; case XK_c: ksym = XK_Escape; break; @@ -1039,47 +361,20 @@ keypress(XKeyEvent *ev) text[cursor] = '\0'; match(); break; - #endif // FZFEXPECT_PATCH - #if FZFEXPECT_PATCH - case XK_u: expect("ctrl-u", ev); /* delete left */ - #else case XK_u: /* delete left */ - #endif // FZFEXPECT_PATCH insert(NULL, 0 - cursor); break; - #if FZFEXPECT_PATCH - case XK_w: expect("ctrl-w", ev); /* delete word */ - #else case XK_w: /* delete word */ - #endif // FZFEXPECT_PATCH while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)])) insert(NULL, nextrune(-1) - cursor); while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)])) insert(NULL, nextrune(-1) - cursor); break; - #if FZFEXPECT_PATCH || CTRL_V_TO_PASTE_PATCH - case XK_v: - #if FZFEXPECT_PATCH - expect("ctrl-v", ev); - #endif // FZFEXPECT_PATCH - case XK_V: - XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY, - utf8, utf8, win, CurrentTime); - return; - #endif // FZFEXPECT_PATCH | CTRL_V_TO_PASTE_PATCH - #if FZFEXPECT_PATCH - case XK_y: expect("ctrl-y", ev); /* paste selection */ - #else case XK_y: /* paste selection */ - #endif // FZFEXPECT_PATCH case XK_Y: XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY, utf8, utf8, win, CurrentTime); return; - #if FZFEXPECT_PATCH - case XK_x: expect("ctrl-x", ev); break; - case XK_z: expect("ctrl-z", ev); break; - #endif // FZFEXPECT_PATCH case XK_Left: case XK_KP_Left: movewordedge(-1); @@ -1090,13 +385,6 @@ keypress(XKeyEvent *ev) goto draw; case XK_Return: case XK_KP_Enter: - #if RESTRICT_RETURN_PATCH - if (restrict_return) - break; - #endif // RESTRICT_RETURN_PATCH - #if MULTI_SELECTION_PATCH - selsel(); - #endif // MULTI_SELECTION_PATCH break; case XK_bracketleft: cleanup(); @@ -1118,16 +406,6 @@ keypress(XKeyEvent *ev) case XK_j: ksym = XK_Next; break; case XK_k: ksym = XK_Prior; break; case XK_l: ksym = XK_Down; break; - #if NAVHISTORY_PATCH - case XK_p: - navhistory(-1); - buf[0]=0; - break; - case XK_n: - navhistory(1); - buf[0]=0; - break; - #endif // NAVHISTORY_PATCH default: return; } @@ -1181,26 +459,6 @@ insert: break; case XK_Left: case XK_KP_Left: - #if GRID_PATCH && GRIDNAV_PATCH - if (columns > 1) { - if (!sel) - return; - tmpsel = sel; - for (i = 0; i < lines; i++) { - if (!tmpsel->left || tmpsel->left->right != tmpsel) - return; - if (tmpsel == curr) - offscreen = true; - tmpsel = tmpsel->left; - } - sel = tmpsel; - if (offscreen) { - curr = prev; - calcoffsets(); - } - break; - } - #endif // GRIDNAV_PATCH if (cursor > 0 && (!sel || !sel->left || lines > 0)) { cursor = nextrune(-1); break; @@ -1231,118 +489,16 @@ insert: break; case XK_Return: case XK_KP_Enter: - #if RESTRICT_RETURN_PATCH - if (restrict_return && (!sel || ev->state & (ShiftMask | ControlMask))) - break; - #endif // RESTRICT_RETURN_PATCH - #if !MULTI_SELECTION_PATCH - #if PIPEOUT_PATCH - #if PRINTINPUTTEXT_PATCH - if (sel && ( - (use_text_input && (ev->state & ShiftMask)) || - (!use_text_input && !(ev->state & ShiftMask)) - )) - #else - if (sel && !(ev->state & ShiftMask)) - #endif // PRINTINPUTTEXT_PATCH - { - if (sel->text[0] == startpipe[0]) { - strncpy(sel->text + strlen(sel->text),pipeout,8); - puts(sel->text+1); - } - #if PRINTINDEX_PATCH - if (print_index) - printf("%d\n", sel->index); - else - #if SEPARATOR_PATCH - puts(sel->text_output); - #else - puts(sel->text); - #endif // SEPARATOR_PATCH - #elif SEPARATOR_PATCH - puts(sel->text_output); - #else - puts(sel->text); - #endif // PRINTINDEX_PATCH | SEPARATOR_PATCH - } else { - if (text[0] == startpipe[0]) { - strncpy(text + strlen(text),pipeout,8); - puts(text+1); - } - puts(text); - } - #elif PRINTINPUTTEXT_PATCH - if (use_text_input) { - #if SEPARATOR_PATCH - puts((sel && (ev->state & ShiftMask)) ? sel->text_output : text); - #else - puts((sel && (ev->state & ShiftMask)) ? sel->text : text); - #endif // SEPARATOR_PATCH - #if PRINTINDEX_PATCH - } else if (print_index) { - printf("%d\n", (sel && !(ev->state & ShiftMask)) ? sel->index : -1); - #endif // PRINTINDEX_PATCH - } else { - #if SEPARATOR_PATCH - puts((sel && !(ev->state & ShiftMask)) ? sel->text_output : text); - #else - puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); - #endif // SEPARATOR_PATCH - } - #elif PRINTINDEX_PATCH - if (print_index) { - printf("%d\n", (sel && !(ev->state & ShiftMask)) ? sel->index : -1); - } else { - #if SEPARATOR_PATCH - puts((sel && !(ev->state & ShiftMask)) ? sel->text_output : text); - #else - puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); - #endif // SEPARATOR_PATCH - } - #elif SEPARATOR_PATCH - puts((sel && !(ev->state & ShiftMask)) ? sel->text_output : text); - #else puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); - #endif // PIPEOUT_PATCH | PRINTINPUTTEXT_PATCH | PRINTINDEX_PATCH - #endif // MULTI_SELECTION_PATCH if (!(ev->state & ControlMask)) { - #if NAVHISTORY_PATCH - savehistory((sel && !(ev->state & ShiftMask)) - ? sel->text : text); - #endif // NAVHISTORY_PATCH - #if MULTI_SELECTION_PATCH - printsel(ev->state); - #endif // MULTI_SELECTION_PATCH cleanup(); exit(0); } - #if !MULTI_SELECTION_PATCH if (sel) sel->out = 1; - #endif // MULTI_SELECTION_PATCH break; case XK_Right: case XK_KP_Right: - #if GRID_PATCH && GRIDNAV_PATCH - if (columns > 1) { - if (!sel) - return; - tmpsel = sel; - for (i = 0; i < lines; i++) { - if (!tmpsel->right || tmpsel->right->left != tmpsel) - return; - tmpsel = tmpsel->right; - if (tmpsel == next) - offscreen = true; - } - sel = tmpsel; - if (offscreen) { - curr = next; - calcoffsets(); - } - break; - } - #endif // GRIDNAV_PATCH if (text[cursor] != '\0') { cursor = nextrune(+1); break; @@ -1358,43 +514,16 @@ insert: } break; case XK_Tab: - #if PREFIXCOMPLETION_PATCH - if (!matches) - break; /* cannot complete no matches */ - #if FUZZYMATCH_PATCH - /* only do tab completion if all matches start with prefix */ - for (item = matches; item && item->text; item = item->right) - if (item->text[0] != text[0]) - goto draw; - #endif // FUZZYMATCH_PATCH - strncpy(text, matches->text, sizeof text - 1); - text[sizeof text - 1] = '\0'; - len = cursor = strlen(text); /* length of longest common prefix */ - for (item = matches; item && item->text; item = item->right) { - cursor = 0; - while (cursor < len && text[cursor] == item->text[cursor]) - cursor++; - len = cursor; - } - memset(text + len, '\0', strlen(text) - len); - #else if (!sel) return; cursor = strnlen(sel->text, sizeof text - 1); memcpy(text, sel->text, cursor); text[cursor] = '\0'; match(); - #endif // PREFIXCOMPLETION_PATCH break; } draw: - #if INCREMENTAL_PATCH - if (incremental) { - puts(text); - fflush(stdout); - } - #endif // INCREMENTAL_PATCH drawmenu(); } @@ -1416,66 +545,13 @@ paste(void) drawmenu(); } -#if ALPHA_PATCH -static void -xinitvisual(void) -{ - XVisualInfo *infos; - XRenderPictFormat *fmt; - int nitems; - int i; - - XVisualInfo tpl = { - .screen = screen, - .depth = 32, - .class = TrueColor - }; - long masks = VisualScreenMask | VisualDepthMask | VisualClassMask; - - infos = XGetVisualInfo(dpy, masks, &tpl, &nitems); - visual = NULL; - for(i = 0; i < nitems; i ++) { - fmt = XRenderFindVisualFormat(dpy, infos[i].visual); - if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) { - visual = infos[i].visual; - depth = infos[i].depth; - cmap = XCreateColormap(dpy, root, visual, AllocNone); - useargb = 1; - break; - } - } - - XFree(infos); - - if (!visual || !opacity) { - visual = DefaultVisual(dpy, screen); - depth = DefaultDepth(dpy, screen); - cmap = DefaultColormap(dpy, screen); - } -} -#endif // ALPHA_PATCH - -#if !NON_BLOCKING_STDIN_PATCH static void readstdin(void) { char *line = NULL; - #if SEPARATOR_PATCH - char *p; - #elif TSV_PATCH - char *buf, *p; - #endif // SEPARATOR_PATCH | TSV_PATCH - - size_t i, linesiz, itemsiz = 0; + size_t i, itemsiz = 0, linesiz = 0; ssize_t len; - #if PASSWORD_PATCH - if (passwd) { - inputw = lines = 0; - return; - } - #endif // PASSWORD_PATCH - /* read each line from stdin and add it to the item list */ for (i = 0; (len = getline(&line, &linesiz, stdin)) != -1; i++) { if (i + 1 >= itemsiz) { @@ -1485,95 +561,26 @@ readstdin(void) } if (line[len - 1] == '\n') line[len - 1] = '\0'; - if (!(items[i].text = strdup(line))) die("strdup:"); - #if SEPARATOR_PATCH - if (separator && (p = separator_greedy ? - strrchr(items[i].text, separator) : strchr(items[i].text, separator))) { - *p = '\0'; - items[i].text_output = ++p; - } else { - items[i].text_output = items[i].text; - } - if (separator_reverse) { - p = items[i].text; - items[i].text = items[i].text_output; - items[i].text_output = p; - } - #elif TSV_PATCH - if (!(buf = strdup(line))) - die("cannot strdup %u bytes:", strlen(line) + 1); - if ((p = strchr(buf, '\t'))) - *p = '\0'; - items[i].stext = buf; - #endif // SEPARATOR_PATCH | TSV_PATCH - #if MULTI_SELECTION_PATCH - items[i].id = i; /* for multiselect */ - #if PRINTINDEX_PATCH - items[i].index = i; - #endif // PRINTINDEX_PATCH - #elif PRINTINDEX_PATCH - items[i].index = i; - #else - items[i].out = 0; - #endif // MULTI_SELECTION_PATCH | PRINTINDEX_PATCH - #if HIGHPRIORITY_PATCH - items[i].hp = arrayhas(hpitems, hplength, items[i].text); - #endif // HIGHPRIORITY_PATCH + items[i].out = 0; } free(line); if (items) items[i].text = NULL; lines = MIN(lines, i); } -#endif // NON_BLOCKING_STDIN_PATCH static void -#if NON_BLOCKING_STDIN_PATCH -readevent(void) -#else run(void) -#endif // NON_BLOCKING_STDIN_PATCH { XEvent ev; - #if PRESELECT_PATCH - int i; - #endif // PRESELECT_PATCH + while (!XNextEvent(dpy, &ev)) { - #if PRESELECT_PATCH - if (preselected) { - for (i = 0; i < preselected; i++) { - if (sel && sel->right && (sel = sel->right) == next) { - curr = next; - calcoffsets(); - } - } - drawmenu(); - preselected = 0; - } - #endif // PRESELECT_PATCH - #if INPUTMETHOD_PATCH - if (XFilterEvent(&ev, None)) - continue; - if (composing) - continue; - #else if (XFilterEvent(&ev, win)) continue; - #endif // INPUTMETHOD_PATCH switch(ev.type) { - #if MOUSE_SUPPORT_PATCH - case ButtonPress: - buttonpress(&ev); - break; - #if MOTION_SUPPORT_PATCH - case MotionNotify: - motionevent(&ev.xbutton); - break; - #endif // MOTION_SUPPORT_PATCH - #endif // MOUSE_SUPPORT_PATCH case DestroyNotify: if (ev.xdestroywindow.window != win) break; @@ -1608,11 +615,6 @@ setup(void) { int x, y, i, j; unsigned int du; - #if RELATIVE_INPUT_WIDTH_PATCH - unsigned int tmp, minstrlen = 0, curstrlen = 0; - int numwidthchecks = 100; - struct item *item; - #endif // RELATIVE_INPUT_WIDTH_PATCH XSetWindowAttributes swa; XIM xim; Window w, dw, *dws; @@ -1624,45 +626,16 @@ setup(void) int a, di, n, area = 0; #endif /* init appearance */ - #if XRESOURCES_PATCH for (j = 0; j < SchemeLast; j++) - #if ALPHA_PATCH - scheme[j] = drw_scm_create(drw, (const char**)colors[j], alphas[j], 2); - #else - scheme[j] = drw_scm_create(drw, (const char**)colors[j], 2); - #endif // ALPHA_PATCH - #else - for (j = 0; j < SchemeLast; j++) - #if ALPHA_PATCH - scheme[j] = drw_scm_create(drw, colors[j], alphas[j], 2); - #else scheme[j] = drw_scm_create(drw, colors[j], 2); - #endif // ALPHA_PATCH - #endif // XRESOURCES_PATCH clip = XInternAtom(dpy, "CLIPBOARD", False); utf8 = XInternAtom(dpy, "UTF8_STRING", False); - #if WMTYPE_PATCH - type = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); - dock = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", False); - #endif // WMTYPE_PATCH /* calculate menu geometry */ - #if PANGO_PATCH - bh = drw->font->h + 2; - #else bh = drw->fonts->h + 2; - #endif // PANGO_PATCH - #if LINE_HEIGHT_PATCH - bh = MAX(bh,lineheight); /* make a menu line AT LEAST 'lineheight' tall */ - #endif // LINE_HEIGHT_PATCH lines = MAX(lines, 0); mh = (lines + 1) * bh; - #if CENTER_PATCH && PANGO_PATCH - promptw = (prompt && *prompt) ? TEXTWM(prompt) - lrpad / 4 : 0; - #elif CENTER_PATCH - promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; - #endif // CENTER_PATCH #ifdef XINERAMA i = 0; if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) { @@ -1689,35 +662,9 @@ setup(void) if (INTERSECT(x, y, 1, 1, info[i]) != 0) break; - #if CENTER_PATCH - if (center) { - #if XYW_PATCH - mw = (dmw>0 ? dmw : MIN(MAX(max_textw() + promptw, min_width), info[i].width)); - #else - mw = MIN(MAX(max_textw() + promptw, min_width), info[i].width); - #endif // XYW_PATCH - x = info[i].x_org + ((info[i].width - mw) / 2); - y = info[i].y_org + ((info[i].height - mh) / 2); - } else { - #if XYW_PATCH - x = info[i].x_org + dmx; - y = info[i].y_org + (topbar ? dmy : info[i].height - mh - dmy); - mw = (dmw>0 ? dmw : info[i].width); - #else - x = info[i].x_org; - y = info[i].y_org + (topbar ? 0 : info[i].height - mh); - mw = info[i].width; - #endif // XYW_PATCH - } - #elif XYW_PATCH - x = info[i].x_org + dmx; - y = info[i].y_org + (topbar ? dmy : info[i].height - mh - dmy); - mw = (dmw>0 ? dmw : info[i].width); - #else x = info[i].x_org; y = info[i].y_org + (topbar ? 0 : info[i].height - mh); mw = info[i].width; - #endif // CENTER_PATCH / XYW_PATCH XFree(info); } else #endif @@ -1725,131 +672,29 @@ setup(void) if (!XGetWindowAttributes(dpy, parentwin, &wa)) die("could not get embedding window attributes: 0x%lx", parentwin); - #if CENTER_PATCH - if (center) { - #if XYW_PATCH - mw = (dmw>0 ? dmw : MIN(MAX(max_textw() + promptw, min_width), wa.width)); - #else - mw = MIN(MAX(max_textw() + promptw, min_width), wa.width); - #endif // XYW_PATCH - x = (wa.width - mw) / 2; - y = (wa.height - mh) / 2; - } else { - #if XYW_PATCH - x = dmx; - y = topbar ? dmy : wa.height - mh - dmy; - mw = (dmw>0 ? dmw : wa.width); - #else - x = 0; - y = topbar ? 0 : wa.height - mh; - mw = wa.width; - #endif // XYW_PATCH - } - #elif XYW_PATCH - x = dmx; - y = topbar ? dmy : wa.height - mh - dmy; - mw = (dmw>0 ? dmw : wa.width); - #else x = 0; y = topbar ? 0 : wa.height - mh; mw = wa.width; - #endif // CENTER_PATCH / XYW_PATCH } - #if !CENTER_PATCH - #if PANGO_PATCH - promptw = (prompt && *prompt) ? TEXTWM(prompt) - lrpad / 4 : 0; - #else promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; - #endif // PANGO_PATCH - #endif // CENTER_PATCH - #if RELATIVE_INPUT_WIDTH_PATCH - for (item = items; !lines && item && item->text; ++item) { - curstrlen = strlen(item->text); - if (numwidthchecks || minstrlen < curstrlen) { - numwidthchecks = MAX(numwidthchecks - 1, 0); - minstrlen = MAX(minstrlen, curstrlen); - if ((tmp = textw_clamp(item->text, mw/3)) > inputw) { - inputw = tmp; - if (tmp == mw/3) - break; - } - } - } - #else - inputw = mw / 3; /* input width: ~33.33% of monitor width */ - #endif // RELATIVE_INPUT_WIDTH_PATCH + inputw = mw / 3; /* input width: ~33% of monitor width */ match(); /* create menu window */ - #if MANAGED_PATCH - swa.override_redirect = managed ? False : True; - #else swa.override_redirect = True; - #endif // MANAGED_PATCH - #if ALPHA_PATCH - swa.background_pixel = 0; - swa.colormap = cmap; - #else swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; - #endif // ALPHA_PATCH - swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask - #if MOUSE_SUPPORT_PATCH - | ButtonPressMask - #if MOTION_SUPPORT_PATCH - | PointerMotionMask - #endif // MOTION_SUPPORT_PATCH - #endif // MOUSE_SUPPORT_PATCH - ; - win = XCreateWindow( - dpy, root, - #if BARPADDING_PATCH && BORDER_PATCH - x + sp, y + vp - (topbar ? 0 : border_width * 2), mw - 2 * sp - border_width * 2, mh, border_width, - #elif BARPADDING_PATCH - x + sp, y + vp, mw - 2 * sp, mh, 0, - #elif BORDER_PATCH - x, y - (topbar ? 0 : border_width * 2), mw - border_width * 2, mh, border_width, - #else - x, y, mw, mh, 0, - #endif // BORDER_PATCH | BARPADDING_PATCH - #if ALPHA_PATCH - depth, InputOutput, visual, - CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &swa - #else - CopyFromParent, CopyFromParent, CopyFromParent, - CWOverrideRedirect | CWBackPixel | CWEventMask, &swa - #endif // ALPHA_PATCH - ); - #if BORDER_PATCH - if (border_width) - XSetWindowBorder(dpy, win, scheme[SchemeBorder][ColBg].pixel); - #endif // BORDER_PATCH + swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; + win = XCreateWindow(dpy, root, x, y, mw, mh, 0, + CopyFromParent, CopyFromParent, CopyFromParent, + CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); XSetClassHint(dpy, win, &ch); - #if WMTYPE_PATCH - XChangeProperty(dpy, win, type, XA_ATOM, 32, PropModeReplace, - (unsigned char *) &dock, 1); - #endif // WMTYPE_PATCH /* input methods */ if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL) die("XOpenIM failed: could not open input device"); - #if INPUTMETHOD_PATCH - init_input_method(xim); - #else xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, win, XNFocusWindow, win, NULL); - #endif // INPUTMETHOD_PATCH - - #if MANAGED_PATCH - if (managed) { - XTextProperty prop; - char *windowtitle = prompt != NULL ? prompt : "dmenu"; - Xutf8TextListToTextProperty(dpy, &windowtitle, 1, XUTF8StringStyle, &prop); - XSetWMName(dpy, win, &prop); - XSetTextProperty(dpy, win, &prop, XInternAtom(dpy, "_NET_WM_NAME", False)); - XFree(prop.value); - } - #endif // MANAGED_PATCH XMapRaised(dpy, win); if (embed) { @@ -1860,13 +705,8 @@ setup(void) XSelectInput(dpy, dws[i], FocusChangeMask); XFree(dws); } - #if !INPUTMETHOD_PATCH grabfocus(); - #endif // INPUTMETHOD_PATCH } - #if INPUTMETHOD_PATCH - grabfocus(); - #endif // INPUTMETHOD_PATCH drw_resize(drw, mw, mh); drawmenu(); } @@ -1874,275 +714,39 @@ setup(void) static void usage(void) { - die("usage: dmenu [-bv" - #if CENTER_PATCH - "c" - #endif - #if !NON_BLOCKING_STDIN_PATCH - "f" - #endif // NON_BLOCKING_STDIN_PATCH - #if INCREMENTAL_PATCH - "r" - #endif // INCREMENTAL_PATCH - #if CASEINSENSITIVE_PATCH - "s" - #else - "i" - #endif // CASEINSENSITIVE_PATCH - #if INSTANT_PATCH - "n" - #endif // INSTANT_PATCH - #if PRINTINPUTTEXT_PATCH - "t" - #endif // PRINTINPUTTEXT_PATCH - #if PREFIXCOMPLETION_PATCH - "x" - #endif // PREFIXCOMPLETION_PATCH - #if FUZZYMATCH_PATCH - "F" - #endif // FUZZYMATCH_PATCH - #if PASSWORD_PATCH - "P" - #endif // PASSWORD_PATCH - #if NO_SORT_PATCH - "S" - #endif // NO_SORT_PATCH - #if REJECTNOMATCH_PATCH - "R" // (changed from r to R due to conflict with INCREMENTAL_PATCH) - #endif // REJECTNOMATCH_PATCH - #if RESTRICT_RETURN_PATCH - "1" - #endif // RESTRICT_RETURN_PATCH - "] " - #if CARET_WIDTH_PATCH - "[-cw caret_width] " - #endif // CARET_WIDTH_PATCH - #if MANAGED_PATCH - "[-wm] " - #endif // MANAGED_PATCH - #if GRID_PATCH - "[-g columns] " - #endif // GRID_PATCH - "[-l lines] [-p prompt] [-fn font] [-m monitor]" - "\n [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]" - #if DYNAMIC_OPTIONS_PATCH || FZFEXPECT_PATCH || ALPHA_PATCH || BORDER_PATCH || HIGHPRIORITY_PATCH - "\n " - #endif - #if DYNAMIC_OPTIONS_PATCH - " [-dy command]" - #endif // DYNAMIC_OPTIONS_PATCH - #if FZFEXPECT_PATCH - " [-ex expectkey]" - #endif // FZFEXPECT_PATCH - #if ALPHA_PATCH - " [-o opacity]" - #endif // ALPHA_PATCH - #if BORDER_PATCH - " [-bw width]" - #endif // BORDER_PATCH - #if HIGHPRIORITY_PATCH - " [-hb color] [-hf color] [-hp items]" - #endif // HIGHPRIORITY_PATCH - #if INITIALTEXT_PATCH || LINE_HEIGHT_PATCH || PRESELECT_PATCH || NAVHISTORY_PATCH || XYW_PATCH - "\n " - #endif - #if INITIALTEXT_PATCH - " [-it text]" - #endif // INITIALTEXT_PATCH - #if LINE_HEIGHT_PATCH - " [-h height]" - #endif // LINE_HEIGHT_PATCH - #if PRESELECT_PATCH - " [-ps index]" - #endif // PRESELECT_PATCH - #if NAVHISTORY_PATCH - " [-H histfile]" - #endif // NAVHISTORY_PATCH - #if XYW_PATCH - " [-X xoffset] [-Y yoffset] [-W width]" // (arguments made upper case due to conflicts) - #endif // XYW_PATCH - #if HIGHLIGHT_PATCH - "\n [-nhb color] [-nhf color] [-shb color] [-shf color]" // highlight colors - #endif // HIGHLIGHT_PATCH - #if SEPARATOR_PATCH - "\n [-d separator] [-D separator]" - #endif // SEPARATOR_PATCH - "\n"); + die("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" + " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]"); } int main(int argc, char *argv[]) { XWindowAttributes wa; - int i; - #if !NON_BLOCKING_STDIN_PATCH - int fast = 0; - #endif // NON_BLOCKING_STDIN_PATCH - - #if XRESOURCES_PATCH - if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) - fputs("warning: no locale support\n", stderr); - #if INPUTMETHOD_PATCH - if (!XSetLocaleModifiers("")) - fputs("warning: could not set locale modifiers", stderr); - #endif // INPUTMETHOD_PATCH - if (!(dpy = XOpenDisplay(NULL))) - die("cannot open display"); - - /* These need to be checked before we init the visuals and read X resources. */ - for (i = 1; i < argc; i++) { - if (!strcmp(argv[i], "-v")) { /* prints version information */ - puts("dmenu-"VERSION); - exit(0); - } else if (!strcmp(argv[i], "-w")) { - argv[i][0] = '\0'; - embed = strdup(argv[++i]); - #if ALPHA_PATCH - } else if (!strcmp(argv[i], "-o")) { /* opacity, pass -o 0 to disable alpha */ - opacity = atoi(argv[++i]); - #endif // ALPHA_PATCH - } else { - continue; - } - argv[i][0] = '\0'; // mark as used - } - - screen = DefaultScreen(dpy); - root = RootWindow(dpy, screen); - if (!embed || !(parentwin = strtol(embed, NULL, 0))) - parentwin = root; - if (!XGetWindowAttributes(dpy, parentwin, &wa)) - die("could not get embedding window attributes: 0x%lx", - parentwin); - - #if ALPHA_PATCH - xinitvisual(); - drw = drw_create(dpy, screen, root, wa.width, wa.height, visual, depth, cmap); - #else - drw = drw_create(dpy, screen, root, wa.width, wa.height); - #endif // ALPHA_PATCH - readxresources(); - #endif // XRESOURCES_PATCH - - for (i = 1; i < argc; i++) { - if (argv[i][0] == '\0') - continue; + int i, fast = 0; + for (i = 1; i < argc; i++) /* these options take no arguments */ if (!strcmp(argv[i], "-v")) { /* prints version information */ puts("dmenu-"VERSION); exit(0); - } else if (!strcmp(argv[i], "-b")) { /* appears at the bottom of the screen */ + } else if (!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */ topbar = 0; - #if CENTER_PATCH - } else if (!strcmp(argv[i], "-c")) { /* toggles centering of dmenu window on screen */ - center = !center; - #endif // CENTER_PATCH - #if !NON_BLOCKING_STDIN_PATCH - } else if (!strcmp(argv[i], "-f")) { /* grabs keyboard before reading stdin */ + else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ fast = 1; - #endif // NON_BLOCKING_STDIN_PATCH - #if INCREMENTAL_PATCH - } else if (!strcmp(argv[i], "-r")) { /* incremental */ - incremental = !incremental; - #endif // INCREMENTAL_PATCH - #if CASEINSENSITIVE_PATCH - } else if (!strcmp(argv[i], "-s")) { /* case-sensitive item matching */ - fstrncmp = strncmp; - fstrstr = strstr; - #else - } else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ + else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ fstrncmp = strncasecmp; fstrstr = cistrstr; - #endif // CASEINSENSITIVE_PATCH - #if MANAGED_PATCH - } else if (!strcmp(argv[i], "-wm")) { /* display as managed wm window */ - managed = 1; - #endif // MANAGED_PATCH - #if INSTANT_PATCH - } else if (!strcmp(argv[i], "-n")) { /* instant select only match */ - instant = !instant; - #endif // INSTANT_PATCH - #if PRINTINPUTTEXT_PATCH - } else if (!strcmp(argv[i], "-t")) { /* favors text input over selection */ - use_text_input = 1; - #endif // PRINTINPUTTEXT_PATCH - #if PREFIXCOMPLETION_PATCH - } else if (!strcmp(argv[i], "-x")) { /* invert use_prefix */ - use_prefix = !use_prefix; - #endif // PREFIXCOMPLETION_PATCH - #if FUZZYMATCH_PATCH - } else if (!strcmp(argv[i], "-F")) { /* disable/enable fuzzy matching, depends on default */ - fuzzy = !fuzzy; - #endif // FUZZYMATCH_PATCH - #if PASSWORD_PATCH - } else if (!strcmp(argv[i], "-P")) { /* is the input a password */ - passwd = 1; - #endif // PASSWORD_PATCH - #if FZFEXPECT_PATCH - } else if (!strcmp(argv[i], "-ex")) { /* expect key */ - expected = argv[++i]; - #endif // FZFEXPECT_PATCH - #if REJECTNOMATCH_PATCH - } else if (!strcmp(argv[i], "-R")) { /* reject input which results in no match */ - reject_no_match = 1; - #endif // REJECTNOMATCH_PATCH - #if NO_SORT_PATCH - } else if (!strcmp(argv[i], "-S")) { /* do not sort matches */ - sortmatches = 0; - #endif // NO_SORT_PATCH - #if PRINTINDEX_PATCH - } else if (!strcmp(argv[i], "-ix")) { /* adds ability to return index in list */ - print_index = 1; - #endif // PRINTINDEX_PATCH - #if RESTRICT_RETURN_PATCH - } else if (!strcmp(argv[i], "-1")) { - restrict_return = 1; - #endif // RESTRICT_RETURN_PATCH } else if (i + 1 == argc) usage(); /* these options take one argument */ - #if NAVHISTORY_PATCH - else if (!strcmp(argv[i], "-H")) - histfile = argv[++i]; - #endif // NAVHISTORY_PATCH - #if GRID_PATCH - else if (!strcmp(argv[i], "-g")) { /* number of columns in grid */ - columns = atoi(argv[++i]); - if (columns && lines == 0) - lines = 1; - } - #endif // GRID_PATCH else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */ lines = atoi(argv[++i]); - #if XYW_PATCH - else if (!strcmp(argv[i], "-X")) /* window x offset */ - dmx = atoi(argv[++i]); - else if (!strcmp(argv[i], "-Y")) /* window y offset (from bottom up if -b) */ - dmy = atoi(argv[++i]); - else if (!strcmp(argv[i], "-W")) /* make dmenu this wide */ - dmw = atoi(argv[++i]); - #endif // XYW_PATCH else if (!strcmp(argv[i], "-m")) mon = atoi(argv[++i]); - #if ALPHA_PATCH && !XRESOURCES_PATCH - else if (!strcmp(argv[i], "-o")) /* opacity, pass -o 0 to disable alpha */ - opacity = atoi(argv[++i]); - #endif // ALPHA_PATCH else if (!strcmp(argv[i], "-p")) /* adds prompt to left of input field */ prompt = argv[++i]; else if (!strcmp(argv[i], "-fn")) /* font or font set */ - #if PANGO_PATCH - font = argv[++i]; - #else fonts[0] = argv[++i]; - #endif // PANGO_PATCH - #if LINE_HEIGHT_PATCH - else if(!strcmp(argv[i], "-h")) { /* minimum height of one menu line */ - lineheight = atoi(argv[++i]); - lineheight = MAX(lineheight, min_lineheight); /* reasonable default in case of value too small/negative */ - } - #endif // LINE_HEIGHT_PATCH else if (!strcmp(argv[i], "-nb")) /* normal background color */ colors[SchemeNorm][ColBg] = argv[++i]; else if (!strcmp(argv[i], "-nf")) /* normal foreground color */ @@ -2151,77 +755,13 @@ main(int argc, char *argv[]) colors[SchemeSel][ColBg] = argv[++i]; else if (!strcmp(argv[i], "-sf")) /* selected foreground color */ colors[SchemeSel][ColFg] = argv[++i]; - #if HIGHPRIORITY_PATCH - else if (!strcmp(argv[i], "-hb")) /* high priority background color */ - colors[SchemeHp][ColBg] = argv[++i]; - else if (!strcmp(argv[i], "-hf")) /* low priority background color */ - colors[SchemeHp][ColFg] = argv[++i]; - else if (!strcmp(argv[i], "-hp")) - hpitems = tokenize(argv[++i], ",", &hplength); - #endif // HIGHPRIORITY_PATCH - #if HIGHLIGHT_PATCH - else if (!strcmp(argv[i], "-nhb")) /* normal hi background color */ - colors[SchemeNormHighlight][ColBg] = argv[++i]; - else if (!strcmp(argv[i], "-nhf")) /* normal hi foreground color */ - colors[SchemeNormHighlight][ColFg] = argv[++i]; - else if (!strcmp(argv[i], "-shb")) /* selected hi background color */ - colors[SchemeSelHighlight][ColBg] = argv[++i]; - else if (!strcmp(argv[i], "-shf")) /* selected hi foreground color */ - colors[SchemeSelHighlight][ColFg] = argv[++i]; - #endif // HIGHLIGHT_PATCH - #if CARET_WIDTH_PATCH - else if (!strcmp(argv[i], "-cw")) /* sets caret witdth */ - caret_width = atoi(argv[++i]); - #endif // CARET_WIDTH_PATCH - #if !XRESOURCES_PATCH else if (!strcmp(argv[i], "-w")) /* embedding window id */ embed = argv[++i]; - #endif // XRESOURCES_PATCH - #if SEPARATOR_PATCH - else if (!strcmp(argv[i], "-d") || /* field separator */ - (separator_greedy = !strcmp(argv[i], "-D"))) { - separator = argv[++i][0]; - separator_reverse = argv[i][1] == '|'; - } - #endif // SEPARATOR_PATCH - #if PRESELECT_PATCH - else if (!strcmp(argv[i], "-ps")) /* preselected item */ - preselected = atoi(argv[++i]); - #endif // PRESELECT_PATCH - #if DYNAMIC_OPTIONS_PATCH - else if (!strcmp(argv[i], "-dy")) /* dynamic command to run */ - dynamic = argv[++i]; - #endif // DYNAMIC_OPTIONS_PATCH - #if BORDER_PATCH - else if (!strcmp(argv[i], "-bw")) /* border width around dmenu */ - border_width = atoi(argv[++i]); - #endif // BORDER_PATCH - #if INITIALTEXT_PATCH - else if (!strcmp(argv[i], "-it")) { /* adds initial text */ - const char * text = argv[++i]; - insert(text, strlen(text)); - } - #endif // INITIALTEXT_PATCH - else { + else usage(); - } - } - #if XRESOURCES_PATCH - #if PANGO_PATCH - if (!drw_font_create(drw, font)) - die("no fonts could be loaded."); - #else - if (!drw_fontset_create(drw, (const char**)fonts, LENGTH(fonts))) - die("no fonts could be loaded."); - #endif // PANGO_PATCH - #else // !XRESOURCES_PATCH if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) fputs("warning: no locale support\n", stderr); - #if INPUTMETHOD_PATCH - if (!XSetLocaleModifiers("")) - fputs("warning: could not set locale modifiers", stderr); - #endif // INPUTMETHOD_PATCH if (!(dpy = XOpenDisplay(NULL))) die("cannot open display"); screen = DefaultScreen(dpy); @@ -2231,72 +771,23 @@ main(int argc, char *argv[]) if (!XGetWindowAttributes(dpy, parentwin, &wa)) die("could not get embedding window attributes: 0x%lx", parentwin); - - #if ALPHA_PATCH - xinitvisual(); - drw = drw_create(dpy, screen, root, wa.width, wa.height, visual, depth, cmap); - #else drw = drw_create(dpy, screen, root, wa.width, wa.height); - #endif // ALPHA_PATCH - - #if PANGO_PATCH - if (!drw_font_create(drw, font)) - die("no fonts could be loaded."); - #else if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) die("no fonts could be loaded."); - #endif // PANGO_PATCH - #endif // XRESOURCES_PATCH - - #if PANGO_PATCH - lrpad = drw->font->h; - #else lrpad = drw->fonts->h; - #endif // PANGO_PATCH - - #if BARPADDING_PATCH - sp = sidepad; - vp = (topbar ? vertpad : - vertpad); - #endif // BARPADDING_PATCH - - #if LINE_HEIGHT_PATCH - if (lineheight == -1) - #if PANGO_PATCH - lineheight = drw->font->h * 2.5; - #else - lineheight = drw->fonts->h * 2.5; - #endif // PANGO_PATCH - #endif // LINE_HEIGHT_PATCH #ifdef __OpenBSD__ if (pledge("stdio rpath", NULL) == -1) die("pledge"); #endif - #if NAVHISTORY_PATCH - loadhistory(); - #endif // NAVHISTORY_PATCH - #if NON_BLOCKING_STDIN_PATCH - grabkeyboard(); - #else if (fast && !isatty(0)) { grabkeyboard(); - #if DYNAMIC_OPTIONS_PATCH - if (!(dynamic && *dynamic)) - readstdin(); - #else readstdin(); - #endif // DYNAMIC_OPTIONS_PATCH } else { - #if DYNAMIC_OPTIONS_PATCH - if (!(dynamic && *dynamic)) - readstdin(); - #else readstdin(); - #endif // DYNAMIC_OPTIONS_PATCH grabkeyboard(); } - #endif // NON_BLOCKING_STDIN_PATCH setup(); run(); diff --git a/menu/dmenu_run b/menu/dmenu_run index e6d1355..834ede5 100755 --- a/menu/dmenu_run +++ b/menu/dmenu_run @@ -1,6 +1,2 @@ #!/bin/sh -export _JAVA_AWT_WM_NONREPARENTING=1 dmenu_path | dmenu "$@" | ${SHELL:-"/bin/sh"} & - -# Uncomment for the NAVHISTORY patch (and remove the exec above) -#dmenu_path | dmenu -H "${XDG_CACHE_HOME:-$HOME/.cache/}/dmenu_run.hist" "$@" | ${SHELL:-"/bin/sh"} & \ No newline at end of file diff --git a/menu/drw.c b/menu/drw.c index 5c8f726..c41e6af 100644 --- a/menu/drw.c +++ b/menu/drw.c @@ -5,11 +5,9 @@ #include #include -#include "patches.h" #include "drw.h" #include "util.h" -#if !PANGO_PATCH || HIGHLIGHT_PATCH #define UTF_INVALID 0xFFFD static int @@ -48,23 +46,8 @@ utf8decode(const char *s_in, long *u, int *err) return len; } -#if HIGHLIGHT_PATCH -int -utf8len(const char *c) -{ - long utf8codepoint = 0; - int utf8err = 0; - return utf8decode(c, &utf8codepoint, &utf8err); -} -#endif // HIGHLIGHT_PATCH -#endif // PANGO_PATCH - Drw * -#if ALPHA_PATCH -drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap) -#else drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) -#endif // ALPHA_PATCH { Drw *drw = ecalloc(1, sizeof(Drw)); @@ -73,16 +56,8 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h drw->root = root; drw->w = w; drw->h = h; - #if ALPHA_PATCH - drw->visual = visual; - drw->depth = depth; - drw->cmap = cmap; - drw->drawable = XCreatePixmap(dpy, root, w, h, depth); - drw->gc = XCreateGC(dpy, drw->drawable, 0, NULL); - #else drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen)); drw->gc = XCreateGC(dpy, root, 0, NULL); - #endif // ALPHA_PATCH XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); return drw; @@ -98,11 +73,7 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h) drw->h = h; if (drw->drawable) XFreePixmap(drw->dpy, drw->drawable); - #if ALPHA_PATCH - drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, drw->depth); - #else drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen)); - #endif // ALPHA_PATCH } void @@ -110,49 +81,10 @@ drw_free(Drw *drw) { XFreePixmap(drw->dpy, drw->drawable); XFreeGC(drw->dpy, drw->gc); - #if PANGO_PATCH - drw_font_free(drw->font); - #else drw_fontset_free(drw->fonts); - #endif // PANGO_PATCH free(drw); } -#if PANGO_PATCH -/* This function is an implementation detail. Library users should use - * drw_font_create instead. - */ -static Fnt * -xfont_create(Drw *drw, const char *fontname) -{ - Fnt *font; - PangoFontMap *fontmap; - PangoContext *context; - PangoFontDescription *desc; - PangoFontMetrics *metrics; - - if (!fontname) { - die("no font specified."); - } - - font = ecalloc(1, sizeof(Fnt)); - font->dpy = drw->dpy; - - fontmap = pango_xft_get_font_map(drw->dpy, drw->screen); - context = pango_font_map_create_context(fontmap); - desc = pango_font_description_from_string(fontname); - font->layout = pango_layout_new(context); - pango_layout_set_font_description(font->layout, desc); - - metrics = pango_context_get_metrics(context, desc, pango_language_from_string ("en-us")); - font->h = pango_font_metrics_get_height(metrics) / PANGO_SCALE; - - pango_font_metrics_unref(metrics); - g_object_unref(context); - - return font; -} -#else /* This function is an implementation detail. Library users should use * drw_fontset_create instead. */ @@ -187,21 +119,6 @@ xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern) die("no font specified."); } - #if NO_COLOR_EMOJI_PATCH - /* Do not allow using color fonts. This is a workaround for a BadLength - * error from Xft with color glyphs. Modelled on the Xterm workaround. See - * https://bugzilla.redhat.com/show_bug.cgi?id=1498269 - * https://lists.suckless.org/dev/1701/30932.html - * https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916349 - * and lots more all over the internet. - */ - FcBool iscol; - if (FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) { - XftFontClose(drw->dpy, xfont); - return NULL; - } - #endif // NO_COLOR_EMOJI_PATCH - font = ecalloc(1, sizeof(Fnt)); font->xfont = xfont; font->pattern = pattern; @@ -210,38 +127,18 @@ xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern) return font; } -#endif // PANGO_PATCH static void xfont_free(Fnt *font) { if (!font) return; - #if PANGO_PATCH - if (font->layout) - g_object_unref(font->layout); - #else if (font->pattern) FcPatternDestroy(font->pattern); XftFontClose(font->dpy, font->xfont); - #endif // PANGO_PATCH free(font); } -#if PANGO_PATCH -Fnt* -drw_font_create(Drw* drw, const char *font) -{ - Fnt *fnt = NULL; - - if (!drw || !font) - return NULL; - - fnt = xfont_create(drw, font); - - return (drw->font = fnt); -} -#else Fnt* drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount) { @@ -259,16 +156,7 @@ drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount) } return (drw->fonts = ret); } -#endif // PANGO_PATCH -#if PANGO_PATCH -void -drw_font_free(Fnt *font) -{ - if (font) - xfont_free(font); -} -#else void drw_fontset_free(Fnt *font) { @@ -277,40 +165,23 @@ drw_fontset_free(Fnt *font) xfont_free(font); } } -#endif // PANGO_PATCH void -#if ALPHA_PATCH -drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha) -#else drw_clr_create(Drw *drw, Clr *dest, const char *clrname) -#endif // ALPHA_PATCH { if (!drw || !dest || !clrname) return; - #if ALPHA_PATCH - if (!XftColorAllocName(drw->dpy, drw->visual, drw->cmap, - clrname, dest)) - die("error, cannot allocate color '%s'", clrname); - - dest->pixel = (dest->pixel & 0x00ffffffU) | (alpha << 24); - #else if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), DefaultColormap(drw->dpy, drw->screen), clrname, dest)) die("error, cannot allocate color '%s'", clrname); - #endif // ALPHA_PATCH } /* Wrapper to create color schemes. The caller has to call free(3) on the * returned color scheme when done using it. */ Clr * -#if ALPHA_PATCH -drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount) -#else drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) -#endif // ALPHA_PATCH { size_t i; Clr *ret; @@ -320,22 +191,16 @@ drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) return NULL; for (i = 0; i < clrcount; i++) - #if ALPHA_PATCH - drw_clr_create(drw, &ret[i], clrnames[i], alphas[i]); - #else drw_clr_create(drw, &ret[i], clrnames[i]); - #endif // ALPHA_PATCH return ret; } -#if !PANGO_PATCH void drw_setfontset(Drw *drw, Fnt *set) { if (drw) drw->fonts = set; } -#endif // PANGO_PATCH void drw_setscheme(Drw *drw, Clr *scm) @@ -356,77 +221,6 @@ drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1); } -#if PANGO_PATCH -int -drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert, Bool markup) -{ - char buf[1024]; - int i, ty, th; - unsigned int ew, eh; - XftDraw *d = NULL; - size_t len; - int render = x || y || w || h; - - if (!drw || (render && !drw->scheme) || !text || !drw->font) - return 0; - - if (!render) { - w = invert ? invert : ~invert; - } else { - XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); - XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); - #if ALPHA_PATCH - d = XftDrawCreate(drw->dpy, drw->drawable, drw->visual, drw->cmap); - #else - d = XftDrawCreate(drw->dpy, drw->drawable, - DefaultVisual(drw->dpy, drw->screen), - DefaultColormap(drw->dpy, drw->screen)); - #endif // ALPHA_PATCH - x += lpad; - w -= lpad; - } - - len = strlen(text); - - if (len) { - drw_font_getexts(drw->font, text, len, &ew, &eh, markup); - th = eh; - /* shorten text if necessary */ - for (len = MIN(len, sizeof(buf) - 1); len && ew > w; len--) { - drw_font_getexts(drw->font, text, len, &ew, &eh, markup); - if (eh > th) - th = eh; - } - - if (len) { - memcpy(buf, text, len); - buf[len] = '\0'; - if (len < strlen(text)) - for (i = len; i && i > len - 3; buf[--i] = '.') - ; /* NOP */ - - if (render) { - ty = y + (h - th) / 2; - if (markup) - pango_layout_set_markup(drw->font->layout, buf, len); - else - pango_layout_set_text(drw->font->layout, buf, len); - pango_xft_render_layout(d, &drw->scheme[invert ? ColBg : ColFg], - drw->font->layout, x * PANGO_SCALE, ty * PANGO_SCALE); - if (markup) /* clear markup attributes */ - pango_layout_set_attributes(drw->font->layout, NULL); - } - x += ew; - w -= ew; - } - } - - if (d) - XftDrawDestroy(d); - - return x + (render ? w : 0); -} -#else int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert) { @@ -445,7 +239,6 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp /* keep track of a couple codepoints for which we have no match. */ static unsigned int nomatches[128], ellipsis_width, invalid_width; static const char invalid[] = "�"; - const char *ellipsis = "..."; if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts) return 0; @@ -455,24 +248,22 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp } else { XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); - #if ALPHA_PATCH - d = XftDrawCreate(drw->dpy, drw->drawable, drw->visual, drw->cmap); - #else + if (w < lpad) + return x + w; d = XftDrawCreate(drw->dpy, drw->drawable, DefaultVisual(drw->dpy, drw->screen), DefaultColormap(drw->dpy, drw->screen)); - #endif // ALPHA_PATCH x += lpad; w -= lpad; } usedfont = drw->fonts; if (!ellipsis_width && render) - ellipsis_width = drw_fontset_getwidth(drw, ellipsis); + ellipsis_width = drw_fontset_getwidth(drw, "..."); if (!invalid_width && render) invalid_width = drw_fontset_getwidth(drw, invalid); while (1) { - ew = ellipsis_len = utf8err = utf8strlen = 0; + ew = ellipsis_len = utf8err = utf8charlen = utf8strlen = 0; utf8str = text; nextfont = NULL; while (*text) { @@ -498,12 +289,12 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp else utf8strlen = ellipsis_len; } else if (curfont == usedfont) { - text += utf8charlen; + text += utf8charlen; utf8strlen += utf8err ? 0 : utf8charlen; ew += utf8err ? 0 : tmpw; - } else { - nextfont = curfont; - } + } else { + nextfont = curfont; + } break; } } @@ -519,7 +310,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg], usedfont->xfont, x, ty, (XftChar8 *)utf8str, utf8strlen); - } + } x += ew; w -= ew; } @@ -529,8 +320,8 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp x += invalid_width; w -= invalid_width; } - if (render && overflow && ellipsis_w) - drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, ellipsis, invert); + if (render && overflow) + drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert); if (!*text || overflow) { break; @@ -562,9 +353,6 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp fcpattern = FcPatternDuplicate(drw->fonts->pattern); FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset); FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue); - #if NO_COLOR_EMOJI_PATCH - FcPatternAddBool(fcpattern, FC_COLOR, FcFalse); - #endif // NO_COLOR_EMOJI_PATCH FcConfigSubstitute(NULL, fcpattern, FcMatchPattern); FcDefaultSubstitute(fcpattern); @@ -593,7 +381,6 @@ no_match: return x + (render ? w : 0); } -#endif // PANGO_PATCH void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) @@ -605,24 +392,6 @@ drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) XSync(drw->dpy, False); } -#if PANGO_PATCH -unsigned int -drw_font_getwidth(Drw *drw, const char *text, Bool markup) -{ - if (!drw || !drw->font || !text) - return 0; - return drw_text(drw, 0, 0, 0, 0, 0, text, 0, markup); -} - -unsigned int -drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n) -{ - unsigned int tmp = 0; - if (drw && drw->font && text && n) - tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n, True); - return MIN(n, tmp); -} -#else unsigned int drw_fontset_getwidth(Drw *drw, const char *text) { @@ -639,29 +408,7 @@ drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n) tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n); return MIN(n, tmp); } -#endif // PANGO_PATCH -#if PANGO_PATCH -void -drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h, Bool markup) -{ - if (!font || !text) - return; - - PangoRectangle r; - if (markup) - pango_layout_set_markup(font->layout, text, len); - else - pango_layout_set_text(font->layout, text, len); - pango_layout_get_extents(font->layout, 0, &r); - if (markup) /* clear markup attributes */ - pango_layout_set_attributes(font->layout, NULL); - if (w) - *w = r.width / PANGO_SCALE; - if (h) - *h = r.height / PANGO_SCALE; -} -#else void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h) { @@ -676,7 +423,6 @@ drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, if (h) *h = font->h; } -#endif // PANGO_PATCH Cur * drw_cur_create(Drw *drw, int shape) @@ -700,7 +446,3 @@ drw_cur_free(Drw *drw, Cur *cursor) XFreeCursor(drw->dpy, cursor->cursor); free(cursor); } - -#if SCROLL_PATCH -#include "patch/scroll.c" -#endif diff --git a/menu/drw.h b/menu/drw.h index af54557..fd7631b 100644 --- a/menu/drw.h +++ b/menu/drw.h @@ -1,10 +1,5 @@ /* See LICENSE file for copyright and license details. */ -#if PANGO_PATCH -#include -#include -#endif // PANGO_PATCH - typedef struct { Cursor cursor; } Cur; @@ -12,13 +7,9 @@ typedef struct { typedef struct Fnt { Display *dpy; unsigned int h; - #if PANGO_PATCH - PangoLayout *layout; - #else XftFont *xfont; FcPattern *pattern; struct Fnt *next; - #endif // PANGO_PATCH } Fnt; enum { ColFg, ColBg }; /* Clr scheme index */ @@ -29,79 +20,39 @@ typedef struct { Display *dpy; int screen; Window root; - #if ALPHA_PATCH - Visual *visual; - unsigned int depth; - Colormap cmap; - #endif // ALPHA_PATCH Drawable drawable; GC gc; Clr *scheme; - #if PANGO_PATCH - Fnt *font; - #else Fnt *fonts; - #endif // PANGO_PATCH } Drw; /* Drawable abstraction */ -#if ALPHA_PATCH -Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap); -#else Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h); -#endif // ALPHA_PATCH void drw_resize(Drw *drw, unsigned int w, unsigned int h); void drw_free(Drw *drw); /* Fnt abstraction */ -#if PANGO_PATCH -Fnt *drw_font_create(Drw* drw, const char *font); -void drw_font_free(Fnt* set); -unsigned int drw_font_getwidth(Drw *drw, const char *text, Bool markup); -unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n); -void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h, Bool markup); -#else Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount); void drw_fontset_free(Fnt* set); unsigned int drw_fontset_getwidth(Drw *drw, const char *text); unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n); void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h); -#endif // PANGO_PATCH - -#if HIGHLIGHT_PATCH -int utf8len(const char *c); -#endif // HIGHLIGHT_PATCH /* Colorscheme abstraction */ -#if ALPHA_PATCH -void drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha); -Clr *drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount); -#else void drw_clr_create(Drw *drw, Clr *dest, const char *clrname); Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount); -#endif // ALPHA_PATCH /* Cursor abstraction */ Cur *drw_cur_create(Drw *drw, int shape); void drw_cur_free(Drw *drw, Cur *cursor); /* Drawing context manipulation */ -#if !PANGO_PATCH void drw_setfontset(Drw *drw, Fnt *set); -#endif // PANGO_PATCH void drw_setscheme(Drw *drw, Clr *scm); /* Drawing functions */ void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert); -#if PANGO_PATCH -int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert, Bool markup); -#else int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert); -#endif // PANGO_PATCH /* Map functions */ void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h); - -#if SCROLL_PATCH -#include "patch/scroll.h" -#endif diff --git a/menu/patch/center.c b/menu/patch/center.c deleted file mode 100644 index 09b0f9a..0000000 --- a/menu/patch/center.c +++ /dev/null @@ -1,8 +0,0 @@ -static int -max_textw(void) -{ - int len = 0; - for (struct item *item = items; item && item->text; item++) - len = MAX(TEXTW(item->text), len); - return len; -} diff --git a/menu/patch/dynamicoptions.c b/menu/patch/dynamicoptions.c deleted file mode 100644 index 2c942fa..0000000 --- a/menu/patch/dynamicoptions.c +++ /dev/null @@ -1,91 +0,0 @@ -static void -refreshoptions(void) -{ - int dynlen = strlen(dynamic); - char* cmd= malloc(dynlen + strlen(text) + 2); - if (cmd == NULL) - die("malloc:"); - sprintf(cmd, "%s %s", dynamic, text); - FILE *stream = popen(cmd, "r"); - if (!stream) - die("popen(%s):", cmd); - readstream(stream); - int pc = pclose(stream); - if (pc == -1) - die("pclose:"); - free(cmd); - curr = sel = items; -} - -static void -readstream(FILE* stream) -{ - char buf[sizeof text], *p; - size_t i, imax = 0, size = 0; - unsigned int tmpmax = 0; - - /* read each line from stdin and add it to the item list */ - for (i = 0; fgets(buf, sizeof buf, stream); i++) { - if (i + 1 >= size / sizeof *items) - if (!(items = realloc(items, (size += BUFSIZ)))) - die("cannot realloc %u bytes:", size); - if ((p = strchr(buf, '\n'))) - *p = '\0'; - if (!(items[i].text = strdup(buf))) - die("cannot strdup %u bytes:", strlen(buf) + 1); - #if SEPARATOR_PATCH - if (separator && (p = separator_greedy ? - strrchr(items[i].text, separator) : strchr(items[i].text, separator))) { - *p = '\0'; - items[i].text_output = ++p; - } else { - items[i].text_output = items[i].text; - } - if (separator_reverse) { - p = items[i].text; - items[i].text = items[i].text_output; - items[i].text_output = p; - } - #elif TSV_PATCH - if ((p = strchr(buf, '\t'))) - *p = '\0'; - if (!(items[i].stext = strdup(buf))) - die("cannot strdup %u bytes:", strlen(buf) + 1); - #endif // TSV_PATCH - #if MULTI_SELECTION_PATCH - items[i].id = i; - #else - items[i].out = 0; - #endif // MULTI_SELECTION_PATCH - #if HIGHPRIORITY_PATCH - items[i].hp = arrayhas(hpitems, hplength, items[i].text); - #endif // HIGHPRIORITY_PATCH - #if PANGO_PATCH - drw_font_getexts(drw->font, buf, strlen(buf), &tmpmax, NULL, True); - #else - drw_font_getexts(drw->fonts, buf, strlen(buf), &tmpmax, NULL); - #endif // PANGO_PATCH - if (tmpmax > inputw) { - inputw = tmpmax; - imax = i; - } - } - - /* If the command did not give any output at all, then do not clear the existing items */ - if (!i) - return; - - if (items) - items[i].text = NULL; - #if PANGO_PATCH - inputw = items ? TEXTWM(items[imax].text) : 0; - #else - inputw = items ? TEXTW(items[imax].text) : 0; - #endif // PANGO_PATCH - if (!dynamic || !*dynamic) - lines = MIN(lines, i); - else { - text[0] = '\0'; - cursor = 0; - } -} diff --git a/menu/patch/dynamicoptions.h b/menu/patch/dynamicoptions.h deleted file mode 100644 index cf1c684..0000000 --- a/menu/patch/dynamicoptions.h +++ /dev/null @@ -1,2 +0,0 @@ -static void refreshoptions(void); -static void readstream(FILE* stream); diff --git a/menu/patch/fuzzymatch.c b/menu/patch/fuzzymatch.c deleted file mode 100644 index 459cbd0..0000000 --- a/menu/patch/fuzzymatch.c +++ /dev/null @@ -1,115 +0,0 @@ -#include - -int -compare_distance(const void *a, const void *b) -{ - struct item *da = *(struct item **) a; - struct item *db = *(struct item **) b; - - if (!db) - return 1; - if (!da) - return -1; - - return da->distance == db->distance ? 0 : da->distance < db->distance ? -1 : 1; -} - -void -fuzzymatch(void) -{ - /* bang - we have so much memory */ - struct item *it; - struct item **fuzzymatches = NULL; - char c; - int number_of_matches = 0, i, pidx, sidx, eidx; - int text_len = strlen(text), itext_len; - #if HIGHPRIORITY_PATCH - struct item *lhpprefix, *hpprefixend; - lhpprefix = hpprefixend = NULL; - #endif // HIGHPRIORITY_PATCH - matches = matchend = NULL; - - /* walk through all items */ - for (it = items; it && it->text; it++) { - if (text_len) { - itext_len = strlen(it->text); - pidx = 0; /* pointer */ - sidx = eidx = -1; /* start of match, end of match */ - /* walk through item text */ - for (i = 0; i < itext_len && (c = it->text[i]); i++) { - /* fuzzy match pattern */ - if (!fstrncmp(&text[pidx], &c, 1)) { - if (sidx == -1) - sidx = i; - pidx++; - if (pidx == text_len) { - eidx = i; - break; - } - } - } - /* build list of matches */ - if (eidx != -1) { - /* compute distance */ - /* add penalty if match starts late (log(sidx+2)) - * add penalty for long a match without many matching characters */ - it->distance = log(sidx + 2) + (double)(eidx - sidx - text_len); - /* fprintf(stderr, "distance %s %f\n", it->text, it->distance); */ - appenditem(it, &matches, &matchend); - number_of_matches++; - } - } else { - appenditem(it, &matches, &matchend); - } - } - - if (number_of_matches) { - /* initialize array with matches */ - if (!(fuzzymatches = realloc(fuzzymatches, number_of_matches * sizeof(struct item*)))) - die("cannot realloc %u bytes:", number_of_matches * sizeof(struct item*)); - for (i = 0, it = matches; it && i < number_of_matches; i++, it = it->right) { - fuzzymatches[i] = it; - } - - #if NO_SORT_PATCH - if (sortmatches) - #endif // NO_SORT_PATCH - /* sort matches according to distance */ - qsort(fuzzymatches, number_of_matches, sizeof(struct item*), compare_distance); - /* rebuild list of matches */ - matches = matchend = NULL; - for (i = 0, it = fuzzymatches[i]; i < number_of_matches && it && \ - it->text; i++, it = fuzzymatches[i]) { - #if HIGHPRIORITY_PATCH - #if NO_SORT_PATCH - if (sortmatches && it->hp) - #else - if (it->hp) - #endif // NO_SORT_PATCH - appenditem(it, &lhpprefix, &hpprefixend); - else - appenditem(it, &matches, &matchend); - #else - appenditem(it, &matches, &matchend); - #endif // HIGHPRIORITY_PATCH - } - free(fuzzymatches); - } - #if HIGHPRIORITY_PATCH - if (lhpprefix) { - hpprefixend->right = matches; - matches = lhpprefix; - } - #endif // HIGHPRIORITY_PATCH - curr = sel = matches; - - #if INSTANT_PATCH - if (instant && matches && matches==matchend) { - puts(matches->text); - cleanup(); - exit(0); - } - #endif // INSTANT_PATCH - - calcoffsets(); -} diff --git a/menu/patch/fzfexpect.c b/menu/patch/fzfexpect.c deleted file mode 100644 index b497164..0000000 --- a/menu/patch/fzfexpect.c +++ /dev/null @@ -1,39 +0,0 @@ -static char *expected; -#if MULTI_SELECTION_PATCH -void -expect(char *expect, XKeyEvent *ev) -{ - if (sel && expected && strstr(expected, expect)) { - if (expected && sel && !(ev->state & ShiftMask)) - puts(expect); - for (int i = 0; i < selidsize; i++) - if (selid[i] != -1 && (!sel || sel->id != selid[i])) - puts(items[selid[i]].text); - if (sel && !(ev->state & ShiftMask)) { - puts(sel->text); - } else - puts(text); - cleanup(); - exit(1); - } else if (!sel && expected && strstr(expected, expect)) { - puts(expect); - cleanup(); - exit(1); - } -} -#else -void -expect(char *expect, XKeyEvent *ignored) -{ - if (sel && expected && strstr(expected, expect)) { - puts(expect); - puts(sel->text); - cleanup(); - exit(1); - } else if (!sel && expected && strstr(expected, expect)){ - puts(expect); - cleanup(); - exit(1); - } -} -#endif // MULTI_SELECTION_PATCH diff --git a/menu/patch/fzfexpect.h b/menu/patch/fzfexpect.h deleted file mode 100644 index 95c1dad..0000000 --- a/menu/patch/fzfexpect.h +++ /dev/null @@ -1 +0,0 @@ -static void expect(char *expect, XKeyEvent *ev); diff --git a/menu/patch/highlight.c b/menu/patch/highlight.c deleted file mode 100644 index 11ccd9c..0000000 --- a/menu/patch/highlight.c +++ /dev/null @@ -1,107 +0,0 @@ -static void -#if EMOJI_HIGHLIGHT_PATCH -drawhighlights(struct item *item, char *output, int x, int y, int maxw) -#else -drawhighlights(struct item *item, int x, int y, int maxw) -#endif // EMOJI_HIGHLIGHT_PATCH -{ - char restorechar, tokens[sizeof text], *highlight, *token; - int indent, highlightlen; - - #if FUZZYMATCH_PATCH - int i; - #endif // FUZZYMATCH_PATCH - - #if EMOJI_HIGHLIGHT_PATCH - char *itemtext = output; - #elif TSV_PATCH && !SEPARATOR_PATCH - char *itemtext = item->stext; - #else - char *itemtext = item->text; - #endif // EMOJI_HIGHLIGHT_PATCH | TSV_PATCH - - if (!(strlen(itemtext) && strlen(text))) - return; - - /* Do not highlight items scheduled for output */ - #if MULTI_SELECTION_PATCH - if (issel(item->id)) - return; - #else - if (item->out) - return; - #endif // MULTI_SELECTION_PATCH - - drw_setscheme(drw, scheme[item == sel ? SchemeSelHighlight : SchemeNormHighlight]); - - #if FUZZYMATCH_PATCH - if (fuzzy) { - for (i = 0, highlight = itemtext; *highlight && text[i];) { - highlightlen = utf8len(highlight); - #if FUZZYMATCH_PATCH - if (!fstrncmp(&(*highlight), &text[i], highlightlen)) - #else - if (*highlight == text[i]) - #endif // FUZZYMATCH_PATCH - { - /* get indentation */ - restorechar = *highlight; - *highlight = '\0'; - indent = TEXTW(itemtext) - lrpad; - *highlight = restorechar; - - /* highlight character */ - restorechar = highlight[highlightlen]; - highlight[highlightlen] = '\0'; - drw_text( - drw, - x + indent + (lrpad / 2), - y, - MIN(maxw - indent - lrpad, TEXTW(highlight) - lrpad), - bh, 0, highlight, 0 - #if PANGO_PATCH - , True - #endif // PANGO_PATCH - ); - highlight[highlightlen] = restorechar; - i += highlightlen; - } - highlight++; - } - return; - } - #endif // FUZZYMATCH_PATCH - - strcpy(tokens, text); - for (token = strtok(tokens, " "); token; token = strtok(NULL, " ")) { - highlight = fstrstr(itemtext, token); - while (highlight) { - // Move item str end, calc width for highlight indent, & restore - highlightlen = highlight - itemtext; - restorechar = *highlight; - itemtext[highlightlen] = '\0'; - indent = TEXTW(itemtext); - itemtext[highlightlen] = restorechar; - - // Move highlight str end, draw highlight, & restore - restorechar = highlight[strlen(token)]; - highlight[strlen(token)] = '\0'; - if (indent - (lrpad / 2) - 1 < maxw) - drw_text( - drw, - x + indent - (lrpad / 2) - 1, - y, - MIN(maxw - indent, TEXTW(highlight) - lrpad), - bh, 0, highlight, 0 - #if PANGO_PATCH - , True - #endif // PANGO_PATCH - ); - highlight[strlen(token)] = restorechar; - - if (strlen(highlight) - strlen(token) < strlen(token)) - break; - highlight = fstrstr(highlight + strlen(token), token); - } - } -} diff --git a/menu/patch/highpriority.c b/menu/patch/highpriority.c deleted file mode 100644 index a8f16e7..0000000 --- a/menu/patch/highpriority.c +++ /dev/null @@ -1,35 +0,0 @@ -static char **hpitems = NULL; -static int hplength = 0; - -static char ** -tokenize(char *source, const char *delim, int *llen) -{ - int listlength = 0, list_size = 0; - char **list = NULL, *token; - - token = strtok(source, delim); - while (token) { - if (listlength + 1 >= list_size) { - if (!(list = realloc(list, (list_size += 8) * sizeof(*list)))) - die("Unable to realloc %zu bytes\n", list_size * sizeof(*list)); - } - if (!(list[listlength] = strdup(token))) - die("Unable to strdup %zu bytes\n", strlen(token) + 1); - token = strtok(NULL, delim); - listlength++; - } - - *llen = listlength; - return list; -} - -static int -arrayhas(char **list, int length, char *item) { - for (int i = 0; i < length; i++) { - int len1 = strlen(list[i]); - int len2 = strlen(item); - if (fstrncmp(list[i], item, len1 > len2 ? len2 : len1) == 0) - return 1; - } - return 0; -} diff --git a/menu/patch/highpriority.h b/menu/patch/highpriority.h deleted file mode 100644 index 890763d..0000000 --- a/menu/patch/highpriority.h +++ /dev/null @@ -1 +0,0 @@ -static int arrayhas(char **list, int length, char *item); diff --git a/menu/patch/include.c b/menu/patch/include.c deleted file mode 100644 index 27144f0..0000000 --- a/menu/patch/include.c +++ /dev/null @@ -1,39 +0,0 @@ -#if CENTER_PATCH -#include "center.c" -#endif -#if HIGHLIGHT_PATCH -#include "highlight.c" -#endif -#if FUZZYMATCH_PATCH -#include "fuzzymatch.c" -#endif -#if FZFEXPECT_PATCH -#include "fzfexpect.c" -#endif -#if HIGHPRIORITY_PATCH -#include "highpriority.c" -#endif -#if INPUTMETHOD_PATCH -#include "inputmethod.c" -#endif -#if DYNAMIC_OPTIONS_PATCH -#include "dynamicoptions.c" -#endif -#if MULTI_SELECTION_PATCH -#include "multiselect.c" -#endif -#if MOUSE_SUPPORT_PATCH -#include "mousesupport.c" -#endif -#if NAVHISTORY_PATCH -#include "navhistory.c" -#endif -#if NON_BLOCKING_STDIN_PATCH -#include "nonblockingstdin.c" -#endif -#if NUMBERS_PATCH -#include "numbers.c" -#endif -#if XRESOURCES_PATCH -#include "xresources.c" -#endif diff --git a/menu/patch/include.h b/menu/patch/include.h deleted file mode 100644 index 8ae0ebb..0000000 --- a/menu/patch/include.h +++ /dev/null @@ -1,27 +0,0 @@ -#if DYNAMIC_OPTIONS_PATCH -#include "dynamicoptions.h" -#endif -#if FZFEXPECT_PATCH -#include "fzfexpect.h" -#endif -#if INPUTMETHOD_PATCH -#include "inputmethod.h" -#endif -#if MOUSE_SUPPORT_PATCH -#include "mousesupport.h" -#endif -#if MULTI_SELECTION_PATCH -#include "multiselect.h" -#endif -#if NAVHISTORY_PATCH -#include "navhistory.h" -#endif -#if HIGHPRIORITY_PATCH -#include "highpriority.h" -#endif -#if NON_BLOCKING_STDIN_PATCH -#include "nonblockingstdin.h" -#endif -#if NUMBERS_PATCH -#include "numbers.h" -#endif diff --git a/menu/patch/inputmethod.c b/menu/patch/inputmethod.c deleted file mode 100644 index 42a41c5..0000000 --- a/menu/patch/inputmethod.c +++ /dev/null @@ -1,196 +0,0 @@ -static size_t nextrunetext(const char *text, size_t position, int inc) -{ - ssize_t n; - - /* return location of next utf8 rune in the given direction (+1 or -1) */ - for (n = position + inc; n + inc >= 0 && (text[n] & 0xc0) == 0x80; n += inc) - ; - return n; -} - -/* return bytes from beginning of text to nth utf8 rune to the right */ -static size_t runebytes(const char *text, size_t n) -{ - size_t ret; - - ret = 0; - while (n-- > 0) - ret += nextrunetext(text + ret, 0, 1); - return ret; -} - -/* return number of characters from beginning of text to nth byte to the right - */ -static size_t runechars(const char *text, size_t n) -{ - size_t ret, i; - - ret = i = 0; - while (i < n) { - i += nextrunetext(text + i, 0, 1); - ret++; - } - return ret; -} - -/* move caret on pre-edit text */ -static void preeditcaret(XIC xic, XPointer clientdata, XPointer calldata) -{ - XIMPreeditCaretCallbackStruct *pcaret; - - (void)xic; - pcaret = (XIMPreeditCaretCallbackStruct *)calldata; - if (!pcaret) - return; - switch (pcaret->direction) { - case XIMForwardChar: - cursor = nextrune(+1); - break; - case XIMBackwardChar: - cursor = nextrune(-1); - break; - case XIMForwardWord: - movewordedge(+1); - break; - case XIMBackwardWord: - movewordedge(-1); - break; - case XIMLineStart: - cursor = 0; - break; - case XIMLineEnd: - if (preview[cursor] != '\0') - cursor = strlen(preview); - break; - case XIMAbsolutePosition: - cursor = runebytes(text, pcaret->position); - break; - case XIMDontChange: - /* do nothing */ - break; - case XIMCaretUp: - case XIMCaretDown: - case XIMNextLine: - case XIMPreviousLine: - /* not implemented */ - break; - } - pcaret->position = runechars(preview, cursor); -} - -/* start input method pre-editing */ -static int preeditstart(XIC xic, XPointer clientdata, XPointer calldata) -{ - (void)xic; - (void)calldata; - (void)clientdata; - composing = 1; - printf("PREEDIT\n"); - return BUFSIZ; -} - -/* end input method pre-editing */ -static void preeditdone(XIC xic, XPointer clientdata, XPointer calldata) -{ - (void)xic; - (void)clientdata; - (void)calldata; - printf("DONE\n"); - - composing = 0; -} - -/* draw input method pre-edit text */ -static void preeditdraw(XIC xic, XPointer clientdata, XPointer calldata) -{ - XIMPreeditDrawCallbackStruct *pdraw; - size_t beg, dellen, inslen, endlen; - - printf("DRAW\n"); - - (void)xic; - pdraw = (XIMPreeditDrawCallbackStruct *)calldata; - if (!pdraw) - return; - - /* we do not support wide characters */ - if (pdraw->text && pdraw->text->encoding_is_wchar == True) { - fputs("warning: wchar is not supportecd; use utf8", stderr); - return; - } - - beg = runebytes(text, pdraw->chg_first); - dellen = runebytes(preview + beg, pdraw->chg_length); - inslen = pdraw->text ? runebytes(pdraw->text->string.multi_byte, pdraw->text->length) : 0; - endlen = 0; - if (beg + dellen < strlen(preview)) - endlen = strlen(preview + beg + dellen); - - /* we cannot change text past the end of our pre-edit string */ - - if (beg + dellen >= BUFSIZ || beg + inslen >= BUFSIZ) - return; - - /* get space for text to be copied, and copy it */ - memmove(preview + beg + inslen, preview + beg + dellen, endlen + 1); - if (pdraw->text && pdraw->text->length) - memcpy(preview + beg, pdraw->text->string.multi_byte, inslen); - (preview + beg + inslen + endlen)[0] = '\0'; - - /* get caret position */ - cursor = runebytes(text, pdraw->caret); -} - -static void init_input_method(XIM xim) -{ - XVaNestedList preedit = NULL; - XICCallback start, done, draw, caret; - XIMStyle preeditstyle; - XIMStyle statusstyle; - XIMStyles *imstyles; - int i; - - /* get styles supported by input method */ - if (XGetIMValues(xim, XNQueryInputStyle, &imstyles, NULL) != NULL) - fputs("XGetIMValues: could not obtain input method values", stderr); - - /* check whether input method support on-the-spot pre-editing */ - preeditstyle = XIMPreeditNothing; - statusstyle = XIMStatusNothing; - for (i = 0; i < imstyles->count_styles; i++) { - if (imstyles->supported_styles[i] & XIMPreeditCallbacks) { - preeditstyle = XIMPreeditCallbacks; - break; - } - } - - /* create callbacks for the input context */ - start.client_data = NULL; - done.client_data = NULL; - draw.client_data = (XPointer)text; - caret.client_data = (XPointer)text; - start.callback = (XICProc)preeditstart; - done.callback = (XICProc)preeditdone; - draw.callback = (XICProc)preeditdraw; - caret.callback = (XICProc)preeditcaret; - - /* create list of values for input context */ - preedit = XVaCreateNestedList(0, XNPreeditStartCallback, &start, XNPreeditDoneCallback, - &done, XNPreeditDrawCallback, &draw, XNPreeditCaretCallback, - &caret, NULL); - if (preedit == NULL) - fputs("XVaCreateNestedList: could not create nested list", stderr); - - xic = XCreateIC(xim, XNInputStyle, preeditstyle | statusstyle, XNPreeditAttributes, preedit, - XNClientWindow, win, XNFocusWindow, win, NULL); - XFree(preedit); - - long eventmask; - /* get events the input method is interested in */ - if (XGetICValues(xic, XNFilterEvents, &eventmask, NULL)) - fputs("XGetICValues: could not obtain input context values", stderr); - - XSelectInput(dpy, win, - ExposureMask | KeyPressMask | VisibilityChangeMask | ButtonPressMask | - PointerMotionMask | eventmask); -} diff --git a/menu/patch/inputmethod.h b/menu/patch/inputmethod.h deleted file mode 100644 index 21dd4c0..0000000 --- a/menu/patch/inputmethod.h +++ /dev/null @@ -1,11 +0,0 @@ -static int composing; -static char preview[512] = ""; - -static size_t nextrunetext(const char *text, size_t position, int inc); -static size_t runebytes(const char *text, size_t n); -static size_t runechars(const char *text, size_t n); -static void preeditcaret(XIC xic, XPointer clientdata, XPointer calldata); -static int preeditstart(XIC xic, XPointer clientdata, XPointer calldata); -static void preeditdone(XIC xic, XPointer clientdata, XPointer calldata); -static void preeditdraw(XIC xic, XPointer clientdata, XPointer calldata); -static void init_input_method(XIM xim); diff --git a/menu/patch/mousesupport.c b/menu/patch/mousesupport.c deleted file mode 100644 index b5d1a65..0000000 --- a/menu/patch/mousesupport.c +++ /dev/null @@ -1,294 +0,0 @@ -void -buttonpress(XEvent *e) -{ - struct item *item; - XButtonPressedEvent *ev = &e->xbutton; - int x = 0, y = 0, h = bh, w; - #if GRID_PATCH - int i, cols; - #endif // GRID_PATCH - - if (ev->window != win) { - /* automatically close dmenu if the user clicks outside of dmenu, but - * ignore the scroll wheel and buttons above that */ - if (ev->button <= Button3) { - exit(1); - } - return; - } - - /* right-click: exit */ - if (ev->button == Button3) - exit(1); - - if (prompt && *prompt) - x += promptw; - - /* input field */ - w = (lines > 0 || !matches) ? mw - x : inputw; - - /* left-click on input: clear input, - * NOTE: if there is no left-arrow the space for < is reserved so - * add that to the input width */ - #if SYMBOLS_PATCH - if (ev->button == Button1 && - ((lines <= 0 && ev->x >= 0 && ev->x <= x + w + - ((!prev || !curr->left) ? TEXTW(symbol_1) : 0)) || - (lines > 0 && ev->y >= y && ev->y <= y + h))) { - insert(NULL, -cursor); - drawmenu(); - return; - } - #else - if (ev->button == Button1 && - ((lines <= 0 && ev->x >= 0 && ev->x <= x + w + - ((!prev || !curr->left) ? TEXTW("<") : 0)) || - (lines > 0 && ev->y >= y && ev->y <= y + h))) { - insert(NULL, -cursor); - drawmenu(); - return; - } - #endif // SYMBOLS_PATCH - /* middle-mouse click: paste selection */ - if (ev->button == Button2) { - XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY, - utf8, utf8, win, CurrentTime); - drawmenu(); - return; - } - /* scroll up */ - if (ev->button == Button4 && prev) { - sel = curr = prev; - calcoffsets(); - drawmenu(); - return; - } - /* scroll down */ - if (ev->button == Button5 && next) { - sel = curr = next; - calcoffsets(); - drawmenu(); - return; - } - if (ev->button != Button1) - return; - if (ev->state & ~ControlMask) - return; - if (lines > 0) { - #if GRID_PATCH - cols = columns ? columns : 1; - for (i = 0, item = curr; item != next; item = item->right, i++) { - if ( - (ev->y >= y + ((i % lines) + 1) * bh) && // line y start - (ev->y <= y + ((i % lines) + 2) * bh) && // line y end - (ev->x >= x + ((i / lines) * (w / cols))) && // column x start - (ev->x <= x + ((i / lines + 1) * (w / cols))) // column x end - ) { - clickitem(item, ev); - return; - } - } - #else - /* vertical list: (ctrl)left-click on item */ - for (item = curr; item != next; item = item->right) { - y += h; - if (ev->y >= y && ev->y <= (y + h)) { - clickitem(item, ev); - return; - } - } - #endif // GRID_PATCH - } else if (matches) { - /* left-click on left arrow */ - x += inputw; - #if SYMBOLS_PATCH - w = TEXTW(symbol_1); - #else - w = TEXTW("<"); - #endif // SYMBOLS_PATCH - if (prev && curr->left) { - if (ev->x >= x && ev->x <= x + w) { - sel = curr = prev; - calcoffsets(); - drawmenu(); - return; - } - } - /* horizontal list: (ctrl)left-click on item */ - for (item = curr; item != next; item = item->right) { - x += w; - #if SYMBOLS_PATCH - w = MIN(TEXTW(item->text), mw - x - TEXTW(symbol_2)); - #else - w = MIN(TEXTW(item->text), mw - x - TEXTW(">")); - #endif // SYMBOLS_PATCH - if (ev->x >= x && ev->x <= x + w) { - clickitem(item, ev); - return; - } - } - /* left-click on right arrow */ - #if SYMBOLS_PATCH - w = TEXTW(symbol_2); - #else - w = TEXTW(">"); - #endif // SYMBOLS_PATCH - x = mw - w; - if (next && ev->x >= x && ev->x <= x + w) { - sel = curr = next; - calcoffsets(); - drawmenu(); - return; - } - } -} - -static void -clickitem(struct item *item, XButtonEvent *ev) -{ - #if RESTRICT_RETURN_PATCH - if (restrict_return && (ev->state & (ShiftMask | ControlMask))) - return; - #endif // RESTRICT_RETURN_PATCH - - #if !MULTI_SELECTION_PATCH - #if PIPEOUT_PATCH - if (item && !(ev->state & ShiftMask)) - { - if (item->text[0] == startpipe[0]) { - strncpy(item->text + strlen(item->text),pipeout,8); - puts(item->text+1); - } - #if PRINTINDEX_PATCH - if (print_index) { - printf("%d\n", item->index); - } else { - #if SEPARATOR_PATCH - puts(item->text_output); - #else - puts(item->text); - #endif // SEPARATOR_PATCH - } - #else - puts(item->text); - #endif // PRINTINDEX_PATCH - } else { - if (text[0] == startpipe[0]) { - strncpy(text + strlen(text),pipeout,8); - puts(text+1); - } - puts(text); - } - #elif PRINTINDEX_PATCH - if (print_index) { - printf("%d\n", item->index); - } else { - #if SEPARATOR_PATCH - puts(item->text_output); - #else - puts(item->text); - #endif // SEPARATOR_PATCH - } - #elif SEPARATOR_PATCH - puts(item->text_output); - #else - puts(item->text); - #endif // PIPEOUT_PATCH | PRINTINDEX_PATCH - #endif // MULTI_SELECTION_PATCH - - sel = item; - if (!(ev->state & ControlMask)) { - #if NAVHISTORY_PATCH - savehistory(item->text); - #endif // NAVHISTORY_PATCH - #if MULTI_SELECTION_PATCH - selsel(); - printsel(ev->state); - #endif // MULTI_SELECTION_PATCH - cleanup(); - exit(0); - } - - #if MULTI_SELECTION_PATCH - selsel(); - #else - sel->out = 1; - #endif // MULTI_SELECTION_PATCH - drawmenu(); -} - -#if MOTION_SUPPORT_PATCH -void -motionevent(XButtonEvent *ev) -{ - struct item *item; - int x = 0, y = 0, w; - #if GRID_PATCH - int i, cols; - #endif // GRID_PATCH - - if (ev->window != win || matches == 0) - return; - - if (prompt && *prompt) - x += promptw; - - if (lines > 0) { - /* input field */ - w = mw - x; - #if GRID_PATCH - cols = columns ? columns : 1; - /* grid view or vertical list */ - for (i = 0, item = curr; item != next; item = item->right, i++) { - if ( - (ev->y >= y + ((i % lines) + 1) * bh) && // line y start - (ev->y <= y + ((i % lines) + 2) * bh) && // line y end - (ev->x >= x + ((i / lines) * (w / cols))) && // column x start - (ev->x <= x + ((i / lines + 1) * (w / cols))) // column x end - ) { - sel = item; - calcoffsets(); - drawmenu(); - break; - } - } - #else - /* vertical list */ - w = mw - x; - for (item = curr; item != next; item = item->right) { - y += bh; - if (ev->y >= y && ev->y <= (y + bh)) { - sel = item; - calcoffsets(); - drawmenu(); - break; - } - } - #endif // GRID_PATCH - return; - } - - /* left-click on left arrow */ - x += inputw; - #if SYMBOLS_PATCH - w = TEXTW(symbol_1); - #else - w = TEXTW("<"); - #endif // SYMBOLS_PATCH - /* horizontal list */ - for (item = curr; item != next; item = item->right) { - x += w; - #if SYMBOLS_PATCH - w = MIN(TEXTW(item->text), mw - x - TEXTW(symbol_2)); - #else - w = MIN(TEXTW(item->text), mw - x - TEXTW(">")); - #endif // SYMBOLS_PATCH - if (ev->x >= x && ev->x <= x + w) { - sel = item; - calcoffsets(); - drawmenu(); - break; - } - } -} -#endif diff --git a/menu/patch/mousesupport.h b/menu/patch/mousesupport.h deleted file mode 100644 index bdf0795..0000000 --- a/menu/patch/mousesupport.h +++ /dev/null @@ -1,5 +0,0 @@ -static void buttonpress(XEvent *e); -static void clickitem(struct item *item, XButtonEvent *ev); -#if MOTION_SUPPORT_PATCH -static void motionevent(XButtonEvent *ev); -#endif // MOTION_SUPPORT_PATCH diff --git a/menu/patch/multiselect.c b/menu/patch/multiselect.c deleted file mode 100644 index 8ed2a46..0000000 --- a/menu/patch/multiselect.c +++ /dev/null @@ -1,69 +0,0 @@ -static int -issel(size_t id) -{ - for (int i = 0;i < selidsize;i++) - if (selid[i] == id) - return 1; - return 0; -} - -static void -printsel(unsigned int state) -{ - for (int i = 0;i < selidsize;i++) - if (selid[i] != -1 && (!sel || sel->id != selid[i])) { - #if PRINTINDEX_PATCH - if (print_index) - printf("%d\n", selid[i]); - else - #if SEPARATOR_PATCH - puts(items[selid[i]].text_output); - #else - puts(items[selid[i]].text); - #endif // SEPARATOR_PATCH - #elif SEPARATOR_PATCH - puts(items[selid[i]].text_output); - #else - puts(items[selid[i]].text); - #endif // PRINTINDEX_PATCH | SEPARATOR_PATCH - } - if (sel && !(state & ShiftMask)) { - #if PRINTINDEX_PATCH - if (print_index) - printf("%d\n", sel->index); - else - #if SEPARATOR_PATCH - puts(sel->text_output); - #else - puts(sel->text); - #endif // SEPARATOR_PATCH - #elif SEPARATOR_PATCH - puts(sel->text_output); - #else - puts(sel->text); - #endif // PRINTINDEX_PATCH | SEPARATOR_PATCH - } else - puts(text); - -} - -static void -selsel(void) -{ - if (!sel) - return; - if (issel(sel->id)) { - for (int i = 0; i < selidsize; i++) - if (selid[i] == sel->id) - selid[i] = -1; - } else { - for (int i = 0; i < selidsize; i++) - if (selid[i] == -1) { - selid[i] = sel->id; - return; - } - selidsize++; - selid = realloc(selid, (selidsize + 1) * sizeof(int)); - selid[selidsize - 1] = sel->id; - } -} diff --git a/menu/patch/multiselect.h b/menu/patch/multiselect.h deleted file mode 100644 index 03aa328..0000000 --- a/menu/patch/multiselect.h +++ /dev/null @@ -1 +0,0 @@ -static int issel(size_t id); diff --git a/menu/patch/navhistory.c b/menu/patch/navhistory.c deleted file mode 100644 index 6bd77c2..0000000 --- a/menu/patch/navhistory.c +++ /dev/null @@ -1,126 +0,0 @@ -static char *histfile; -static char **history; -static size_t histsz, histpos; - -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 -navhistory(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); - strncpy(text, p, len); - text[len] = '\0'; - cursor = len; - match(); -} - -void -savehistory(char *input) -{ - unsigned int i; - FILE *fp; - - if (!histfile || - 0 == maxhist || - 0 == strlen(input)) { - goto out; - } - - fp = fopen(histfile, "w"); - if (!fp) { - die("failed to open %s", histfile); - } - for (i = histsz < maxhist ? 0 : histsz - maxhist; i < histsz; i++) { - if (0 >= fprintf(fp, "%s\n", history[i])) { - die("failed to write to %s", histfile); - } - } - if (histsz == 0 || !histnodup || (histsz > 0 && strcmp(input, history[histsz-1]) != 0)) { /* TODO */ - if (0 >= fputs(input, fp)) { - die("failed to write to %s", histfile); - } - } - if (fclose(fp)) { - die("failed to close file %s", histfile); - } - -out: - for (i = 0; i < histsz; i++) { - free(history[i]); - } - free(history); -} diff --git a/menu/patch/navhistory.h b/menu/patch/navhistory.h deleted file mode 100644 index 7b8c245..0000000 --- a/menu/patch/navhistory.h +++ /dev/null @@ -1,3 +0,0 @@ -static void loadhistory(void); -static void navhistory(int dir); -static void savehistory(char *input); diff --git a/menu/patch/nonblockingstdin.c b/menu/patch/nonblockingstdin.c deleted file mode 100644 index e504ef4..0000000 --- a/menu/patch/nonblockingstdin.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include -#include - -static void -readstdin(void) -{ - static size_t max = 0; - static struct item **end = &items; - - char buf[sizeof text], *p, *maxstr; - struct item *item; - - #if PASSWORD_PATCH - if (passwd) { - inputw = lines = 0; - return; - } - #endif // PASSWORD_PATCH - - /* read each line from stdin and add it to the item list */ - while (fgets(buf, sizeof buf, stdin)) { - if (!(item = malloc(sizeof *item))) - die("cannot malloc %u bytes:", sizeof *item); - if ((p = strchr(buf, '\n'))) - *p = '\0'; - if (!(item->text = strdup(buf))) - die("cannot strdup %u bytes:", strlen(buf)+1); - if (strlen(item->text) > max) { - max = strlen(maxstr = item->text); - #if PANGO_PATCH - inputw = maxstr ? TEXTWM(maxstr) : 0; - #else - inputw = maxstr ? TEXTW(maxstr) : 0; - #endif // PANGO_PATCH - } - *end = item; - end = &item->next; - item->next = NULL; - item->out = 0; - } - match(); - drawmenu(); -} - -static void -run(void) -{ - fd_set fds; - int flags, xfd = XConnectionNumber(dpy); - - if ((flags = fcntl(0, F_GETFL)) == -1) - die("cannot get stdin control flags:"); - if (fcntl(0, F_SETFL, flags | O_NONBLOCK) == -1) - die("cannot set stdin control flags:"); - for (;;) { - FD_ZERO(&fds); - FD_SET(xfd, &fds); - if (!feof(stdin)) - FD_SET(0, &fds); - if (select(xfd + 1, &fds, NULL, NULL, NULL) == -1) - die("cannot multiplex input:"); - if (FD_ISSET(xfd, &fds)) - readevent(); - if (FD_ISSET(0, &fds)) - readstdin(); - } -} diff --git a/menu/patch/nonblockingstdin.h b/menu/patch/nonblockingstdin.h deleted file mode 100644 index 828d1ec..0000000 --- a/menu/patch/nonblockingstdin.h +++ /dev/null @@ -1 +0,0 @@ -static void readevent(); diff --git a/menu/patch/numbers.c b/menu/patch/numbers.c deleted file mode 100644 index ed220bd..0000000 --- a/menu/patch/numbers.c +++ /dev/null @@ -1,16 +0,0 @@ -static char numbers[NUMBERSBUFSIZE] = ""; - -static void -recalculatenumbers(void) -{ - unsigned int numer = 0, denom = 0; - struct item *item; - if (matchend) { - numer++; - for (item = matchend; item && item->left; item = item->left) - numer++; - } - for (item = items; item && item->text; item++) - denom++; - snprintf(numbers, NUMBERSBUFSIZE, "%d/%d", numer, denom); -} diff --git a/menu/patch/numbers.h b/menu/patch/numbers.h deleted file mode 100644 index c739872..0000000 --- a/menu/patch/numbers.h +++ /dev/null @@ -1,4 +0,0 @@ -#define NUMBERSMAXDIGITS 100 -#define NUMBERSBUFSIZE (NUMBERSMAXDIGITS * 2) + 1 - -static void recalculatenumbers(void); diff --git a/menu/patch/scroll.c b/menu/patch/scroll.c deleted file mode 100644 index 46f597f..0000000 --- a/menu/patch/scroll.c +++ /dev/null @@ -1,173 +0,0 @@ -int -utf8nextchar(const char *str, int len, int i, int inc) -{ - int n; - - for (n = i + inc; n + inc >= 0 && n + inc <= len - && (str[n] & 0xc0) == 0x80; n += inc) - ; - return n; -} - -int -drw_text_align(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *text, int textlen, int align) -{ - int ty; - unsigned int ew; - XftDraw *d = NULL; - Fnt *usedfont, *curfont, *nextfont; - size_t len; - int utf8strlen, utf8charlen, render = x || y || w || h; - long utf8codepoint = 0; - const char *utf8str; - FcCharSet *fccharset; - FcPattern *fcpattern; - FcPattern *match; - XftResult result; - int charexists = 0; - int utf8err = 0; - int i, n; - - if (!drw || (render && !drw->scheme) || !text || !drw->fonts || textlen <= 0 - || (align != AlignL && align != AlignR)) - return 0; - - if (!render) { - w = ~w; - } else { - XSetForeground(drw->dpy, drw->gc, drw->scheme[ColBg].pixel); - XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); - #if ALPHA_PATCH - d = XftDrawCreate(drw->dpy, drw->drawable, drw->visual, drw->cmap); - #else - d = XftDrawCreate(drw->dpy, drw->drawable, - DefaultVisual(drw->dpy, drw->screen), - DefaultColormap(drw->dpy, drw->screen)); - #endif // ALPHA_PATCH - } - - usedfont = drw->fonts; - i = align == AlignL ? 0 : textlen; - x = align == AlignL ? x : x + w; - while (1) { - utf8strlen = 0; - nextfont = NULL; - /* if (align == AlignL) */ - utf8str = text + i; - - while ((align == AlignL && i < textlen) || (align == AlignR && i > 0)) { - if (align == AlignL) { - utf8charlen = utf8decode(text + i, &utf8codepoint, &utf8err); - if (!utf8charlen) { - textlen = i; - break; - } - } else { - n = utf8nextchar(text, textlen, i, -1); - utf8charlen = utf8decode(text + n, &utf8codepoint, &utf8err); - if (!utf8charlen) { - textlen -= i; - text += i; - i = 0; - break; - } - } - for (curfont = drw->fonts; curfont; curfont = curfont->next) { - charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); - if (charexists) { - if (curfont == usedfont) { - utf8strlen += utf8charlen; - i += align == AlignL ? utf8charlen : -utf8charlen; - } else { - nextfont = curfont; - } - break; - } - } - - if (!charexists || nextfont) - break; - else - charexists = 0; - } - - if (align == AlignR) - utf8str = text + i; - - if (utf8strlen) { - drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL); - /* shorten text if necessary */ - if (align == AlignL) { - for (len = utf8strlen; len && ew > w; ) { - len = utf8nextchar(utf8str, len, len, -1); - drw_font_getexts(usedfont, utf8str, len, &ew, NULL); - } - } else { - for (len = utf8strlen; len && ew > w; ) { - n = utf8nextchar(utf8str, len, 0, +1); - utf8str += n; - len -= n; - drw_font_getexts(usedfont, utf8str, len, &ew, NULL); - } - } - - if (len) { - if (render) { - ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; - XftDrawStringUtf8(d, &drw->scheme[ColFg], - usedfont->xfont, align == AlignL ? x : x - ew, ty, (XftChar8 *)utf8str, len); - } - x += align == AlignL ? ew : -ew; - w -= ew; - } - if (len < utf8strlen) - break; - } - - if ((align == AlignR && i <= 0) || (align == AlignL && i >= textlen)) { - break; - } else if (nextfont) { - charexists = 0; - usedfont = nextfont; - } else { - /* Regardless of whether or not a fallback font is found, the - * character must be drawn. */ - charexists = 1; - - fccharset = FcCharSetCreate(); - FcCharSetAddChar(fccharset, utf8codepoint); - - if (!drw->fonts->pattern) { - /* Refer to the comment in xfont_create for more information. */ - die("the first font in the cache must be loaded from a font string."); - } - - fcpattern = FcPatternDuplicate(drw->fonts->pattern); - FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset); - FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue); - - FcConfigSubstitute(NULL, fcpattern, FcMatchPattern); - FcDefaultSubstitute(fcpattern); - match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result); - - FcCharSetDestroy(fccharset); - FcPatternDestroy(fcpattern); - - if (match) { - usedfont = xfont_create(drw, NULL, match); - if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) { - for (curfont = drw->fonts; curfont->next; curfont = curfont->next) - ; /* NOP */ - curfont->next = usedfont; - } else { - xfont_free(usedfont); - usedfont = drw->fonts; - } - } - } - } - if (d) - XftDrawDestroy(d); - - return x; -} diff --git a/menu/patch/scroll.h b/menu/patch/scroll.h deleted file mode 100644 index 2d0c494..0000000 --- a/menu/patch/scroll.h +++ /dev/null @@ -1,3 +0,0 @@ -enum { AlignL, AlignR }; - -int drw_text_align(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *text, int textlen, int align); diff --git a/menu/patch/xresources.c b/menu/patch/xresources.c deleted file mode 100644 index 6ab60bb..0000000 --- a/menu/patch/xresources.c +++ /dev/null @@ -1,90 +0,0 @@ -#include - -void -readxresources(void) -{ - XrmInitialize(); - - char* xrm; - if ((xrm = XResourceManagerString(drw->dpy))) { - char *type; - XrmDatabase xdb = XrmGetStringDatabase(xrm); - XrmValue xval; - - if (XrmGetResource(xdb, "dmenu.font", "*", &type, &xval)) - #if PANGO_PATCH - strcpy(font, xval.addr); - #else - fonts[0] = strdup(xval.addr); - #endif // PANGO_PATCH - #if !PANGO_PATCH - else - fonts[0] = strdup(fonts[0]); - #endif // PANGO_PATCH - if (XrmGetResource(xdb, "dmenu.background", "*", &type, &xval)) - colors[SchemeNorm][ColBg] = strdup(xval.addr); - if (XrmGetResource(xdb, "dmenu.foreground", "*", &type, &xval)) - colors[SchemeNorm][ColFg] = strdup(xval.addr); - if (XrmGetResource(xdb, "dmenu.selbackground", "*", &type, &xval)) - colors[SchemeSel][ColBg] = strdup(xval.addr); - if (XrmGetResource(xdb, "dmenu.selforeground", "*", &type, &xval)) - colors[SchemeSel][ColFg] = strdup(xval.addr); - if (XrmGetResource(xdb, "dmenu.outbackground", "*", &type, &xval)) - colors[SchemeOut][ColBg] = strdup(xval.addr); - if (XrmGetResource(xdb, "dmenu.outforeground", "*", &type, &xval)) - colors[SchemeOut][ColFg] = strdup(xval.addr); - #if MORECOLOR_PATCH - if (XrmGetResource(xdb, "dmenu.midbackground", "*", &type, &xval)) - colors[SchemeMid][ColBg] = strdup(xval.addr); - if (XrmGetResource(xdb, "dmenu.midforeground", "*", &type, &xval)) - colors[SchemeMid][ColFg] = strdup(xval.addr); - #endif // MORECOLOR_PATCH - #if BORDER_PATCH - if (XrmGetResource(xdb, "dmenu.bordercolor", "*", &type, &xval)) - colors[SchemeBorder][ColBg] = strdup(xval.addr); - #endif // BORDER_PATCH - #if HIGHLIGHT_PATCH - if (XrmGetResource(xdb, "dmenu.selhlbackground", "*", &type, &xval)) - colors[SchemeSelHighlight][ColBg] = strdup(xval.addr); - if (XrmGetResource(xdb, "dmenu.selhlforeground", "*", &type, &xval)) - colors[SchemeSelHighlight][ColFg] = strdup(xval.addr); - if (XrmGetResource(xdb, "dmenu.hlbackground", "*", &type, &xval)) - colors[SchemeNormHighlight][ColBg] = strdup(xval.addr); - if (XrmGetResource(xdb, "dmenu.hlforeground", "*", &type, &xval)) - colors[SchemeNormHighlight][ColFg] = strdup(xval.addr); - #endif // HIGHLIGHT_PATCH - #if HIGHPRIORITY_PATCH - if (XrmGetResource(xdb, "dmenu.hpbackground", "*", &type, &xval)) - colors[SchemeHp][ColBg] = strdup(xval.addr); - if (XrmGetResource(xdb, "dmenu.hpforeground", "*", &type, &xval)) - colors[SchemeHp][ColFg] = strdup(xval.addr); - #endif // HIGHPRIORITY_PATCH - #if EMOJI_HIGHLIGHT_PATCH - if (XrmGetResource(xdb, "dmenu.hoverbackground", "*", &type, &xval)) - colors[SchemeHover][ColBg] = strdup(xval.addr); - if (XrmGetResource(xdb, "dmenu.hoverforeground", "*", &type, &xval)) - colors[SchemeHover][ColFg] = strdup(xval.addr); - if (XrmGetResource(xdb, "dmenu.greenbackground", "*", &type, &xval)) - colors[SchemeGreen][ColBg] = strdup(xval.addr); - if (XrmGetResource(xdb, "dmenu.greenforeground", "*", &type, &xval)) - colors[SchemeGreen][ColFg] = strdup(xval.addr); - if (XrmGetResource(xdb, "dmenu.yellowbackground", "*", &type, &xval)) - colors[SchemeYellow][ColBg] = strdup(xval.addr); - if (XrmGetResource(xdb, "dmenu.yellowforeground", "*", &type, &xval)) - colors[SchemeYellow][ColFg] = strdup(xval.addr); - if (XrmGetResource(xdb, "dmenu.bluebackground", "*", &type, &xval)) - colors[SchemeBlue][ColBg] = strdup(xval.addr); - if (XrmGetResource(xdb, "dmenu.blueforeground", "*", &type, &xval)) - colors[SchemeBlue][ColFg] = strdup(xval.addr); - if (XrmGetResource(xdb, "dmenu.purplebackground", "*", &type, &xval)) - colors[SchemePurple][ColBg] = strdup(xval.addr); - if (XrmGetResource(xdb, "dmenu.purpleforeground", "*", &type, &xval)) - colors[SchemePurple][ColFg] = strdup(xval.addr); - if (XrmGetResource(xdb, "dmenu.redbackground", "*", &type, &xval)) - colors[SchemeRed][ColBg] = strdup(xval.addr); - if (XrmGetResource(xdb, "dmenu.redforeground", "*", &type, &xval)) - colors[SchemeRed][ColFg] = strdup(xval.addr); - #endif // EMOJI_HIGHLIGHT_PATCH - XrmDestroyDatabase(xdb); - } -} diff --git a/menu/patches.def.h b/menu/patches.def.h deleted file mode 100644 index d3076bf..0000000 --- a/menu/patches.def.h +++ /dev/null @@ -1,370 +0,0 @@ -/* Patches */ - -/* The alpha patch adds transparency for the dmenu window. - * You need to uncomment the corresponding line in config.mk to use the -lXrender library - * when including this patch. - * https://github.com/bakkeby/patches/blob/master/dmenu/dmenu-alpha-5.0_20210725_523aa08.diff - */ -#define ALPHA_PATCH 0 - -/* This adds padding for dmenu in similar fashion to the similarly named patch for dwm. The idea - * is to have dmenu appear on top of the bar when using said patch in dwm. - * https://github.com/bakkeby/patches/wiki/barpadding - */ -#define BARPADDING_PATCH 0 - -/* This patch adds a border around the dmenu window. It is intended to be used with the center - * or xyw patches, to make the menu stand out from similarly coloured windows. - * http://tools.suckless.org/dmenu/patches/border/ - */ -#define BORDER_PATCH 0 - -/* By default the caret in dmenu has a width of 2 pixels. This patch makes that configurable - * as well as overridable via a command line option. - * https://github.com/DarkSamus669/dmenu-patches/blob/main/dmenu-caretwidth-5.2.diff - */ -#define CARET_WIDTH_PATCH 0 - -/* This patch makes dmenu case-insensitive by default, replacing the - * case-insensitive -i option with a case sensitive -s option. - * http://tools.suckless.org/dmenu/patches/case-insensitive/ - */ -#define CASEINSENSITIVE_PATCH 0 - -/* This patch centers dmenu in the middle of the screen. - * https://tools.suckless.org/dmenu/patches/center/ - */ -#define CENTER_PATCH 0 - -/* Minor patch to enable the use of Ctrl+v (XA_PRIMARY) and Ctrl+Shift+v (CLIPBOARD) to paste. - * By default dmenu only supports Ctrl+y and Ctrl+Shift+y to paste. - */ -#define CTRL_V_TO_PASTE_PATCH 0 - -/* This patch adds a flag (-dy) which makes dmenu run the command given to it whenever input - * is changed with the current input as the last argument and update the option list according - * to the output of that command. - * https://tools.suckless.org/dmenu/patches/dynamicoptions/ - */ -#define DYNAMIC_OPTIONS_PATCH 0 - -/* This patch will allow for emojis on the left side with a colored background when selected. - * To test this try running: - * $ echo -e ":b here\n:p there\n:r and here" | ./dmenu -p "Search..." -W 400 -l 20 -i -h -1 - * NB: the original patch came embedded with the the xyw patch, the morecolors patch and the - * line height patch and as such is intended to be combined with these. - * https://tools.suckless.org/dmenu/patches/emoji-highlight/ - */ -#define EMOJI_HIGHLIGHT_PATCH 0 - -/* This patch adds support for fuzzy-matching to dmenu, allowing users to type non-consecutive - * portions of the string to be matched. - * https://tools.suckless.org/dmenu/patches/fuzzymatch/ - */ -#define FUZZYMATCH_PATCH 0 - -/* Adds fzf-like functionality for dmenu. - * Refer to https://github.com/DAFF0D11/dafmenu/ for documentation and example use cases. - * https://github.com/DAFF0D11/dafmenu/blob/master/patches/dmenu-fzfexpect-5.1.diff - */ -#define FZFEXPECT_PATCH 0 - -/* Allows dmenu's entries to be rendered in a grid by adding a new -g flag to specify - * the number of grid columns. The -g and -l options can be used together to create a - * G columns * L lines grid. - * https://tools.suckless.org/dmenu/patches/grid/ - */ -#define GRID_PATCH 0 - -/* This patch adds the ability to move left and right through a grid. - * This patch depends on the grid patch. - * https://tools.suckless.org/dmenu/patches/gridnav/ - */ -#define GRIDNAV_PATCH 0 - -/* This patch highlights the individual characters of matched text for each dmenu list entry. - * If combined with the fuzzymatch patch then fuzzy highlight will be used for highlighting - * depending on whether fuzzy matching is enabled. - * - * Known issue: highlighting does not work properly when pango markup is used - * - * https://tools.suckless.org/dmenu/patches/highlight/ - * https://tools.suckless.org/dmenu/patches/fuzzyhighlight/ - */ -#define HIGHLIGHT_PATCH 0 - -/* This will automatically sort the search result so that high priority items are shown first. - * https://tools.suckless.org/dmenu/patches/highpriority/ - */ -#define HIGHPRIORITY_PATCH 0 - -/* This patch causes dmenu to print out the current text each time a key is pressed. - * https://tools.suckless.org/dmenu/patches/incremental/ - */ -#define INCREMENTAL_PATCH 0 - -/* This patch adds an option to provide preselected text. - * https://tools.suckless.org/dmenu/patches/initialtext/ - */ -#define INITIALTEXT_PATCH 0 - -/* Adds support for input methods (fctix, ibus, etc.) allowing the user to change the - * keyboard layout while dmenu is open. - * https://github.com/bakkeby/dmenu-flexipatch/pull/22 - */ -#define INPUTMETHOD_PATCH 0 - -/* This patch adds a flag which will cause dmenu to select an item immediately if there - * is only one matching option left. - * https://tools.suckless.org/dmenu/patches/instant/ - */ -#define INSTANT_PATCH 0 - -/* This patch adds a '-h' option which sets the minimum height of a dmenu line. This helps - * integrate dmenu with other UI elements that require a particular vertical size. - * http://tools.suckless.org/dmenu/patches/line-height/ - */ -#define LINE_HEIGHT_PATCH 0 - -/* This patch adds a -wm flag which sets override_redirect to false; thus letting your window - * manager manage the dmenu window. - * - * This may be helpful in contexts where you don't want to exclusively bind dmenu or want to - * treat dmenu more as a "window" rather than as an overlay. - * https://tools.suckless.org/dmenu/patches/managed/ - */ -#define MANAGED_PATCH 0 - -/* This patch adds an additional color scheme for highlighting entries adjacent to the current - * selection. - * https://tools.suckless.org/dmenu/patches/morecolor/ - */ -#define MORECOLOR_PATCH 0 - -/* This patch adds basic mouse support for dmenu. - * https://tools.suckless.org/dmenu/patches/mouse-support/ - */ -#define MOUSE_SUPPORT_PATCH 0 - -/* Expands the above to support mouse hovering. - * https://tools.suckless.org/dmenu/patches/mouse-support/ - */ -#define MOTION_SUPPORT_PATCH 0 - -/* Without this patch when you press Ctrl+Enter dmenu just outputs current item and it is not - * possible to undo that. - * With this patch dmenu will output all selected items only on exit. It is also possible to - * deselect any selected item. - * Also refer to the dmenu_run replacement on the below URL that supports multiple selections. - * - * This patch is not compatible with, and takes precedence over, the json, printinputtext, - * pipeout and non-blocking stdin patches. - * - * https://tools.suckless.org/dmenu/patches/multi-selection/ - */ -#define MULTI_SELECTION_PATCH 0 - -/* This patch provides dmenu the ability for history navigation similar to that of bash. - * - * If you take this patch then it is recommended that you also uncomment the line in the - * dmenu_run script which replaces the exec command. - * - * https://tools.suckless.org/dmenu/patches/navhistory/ - */ -#define NAVHISTORY_PATCH 0 - -/* This patch adds back in the workaround for a BadLength error in the Xft library when color - * glyphs are used. This is for systems that do not have an updated version of the Xft library - * (or generally prefer monochrome fonts). - */ -#define NO_COLOR_EMOJI_PATCH 0 - -/* Adds the -S option to disable sorting menu items after matching. Useful, for example, when menu - * items are sorted by their frequency of use (using an external cache) and the most frequently - * selected items should always appear first regardless of how they were exact, prefix, or - * substring matches. - * https://tools.suckless.org/dmenu/patches/no-sort/ - */ -#define NO_SORT_PATCH 0 - -/* This is a patch to have dmenu read stdin in a non blocking way, making it wait for input both - * from stdin and from X. This means that you can continue feeding dmenu while you type. - * This patch is meant to be used along with the incremental patch, so that you can use stdout - * to feed stdin. - * - * This patch is not compatible with the json and multi-selection patches, both of which takes - * precedence over this patch. - * - * https://tools.suckless.org/dmenu/patches/non_blocking_stdin/ - */ -#define NON_BLOCKING_STDIN_PATCH 0 - -/* Adds text which displays the number of matched and total items in the top right corner of dmenu. - * https://tools.suckless.org/dmenu/patches/numbers/ - */ -#define NUMBERS_PATCH 0 - -/* This patch adds simple markup for dmenu using pango markup. - * This depends on the pango library v1.44 or greater. - * You need to uncomment the corresponding lines in config.mk to use the pango libraries - * when including this patch. - * - * Note that the pango patch is incompatible with the scroll patch and will result in - * compilation errors if both are enabled. - * - * Note that the pango patch does not protect against the BadLength error from Xft - * when color glyphs are used, which means that dmenu will crash if color emoji is used. - * - * If you need color emoji then you may want to install this patched library from the AUR: - * https://aur.archlinux.org/packages/libxft-bgra/ - * - * A long term fix for the libXft library is pending approval of this pull request: - * https://gitlab.freedesktop.org/xorg/lib/libxft/-/merge_requests/1 - * - * Known issue: not compatible with the scroll patch - * - * Also see: - * https://developer.gnome.org/pygtk/stable/pango-markup-language.html - * https://github.com/StillANixRookie/dmenu-pango - */ -#define PANGO_PATCH 0 - -/* With this patch dmenu will not directly display the keyboard input, but instead replace - * it with dots. All data from stdin will be ignored. - * https://tools.suckless.org/dmenu/patches/password/ - */ -#define PASSWORD_PATCH 0 - -/* This patch allows the selected text to be piped back out with dmenu. This can be useful if you - * want to display the output of a command on the screen. - * Only text starting with the character '#' is piped out by default. - * - * This patch is not compatible with the json and multi-select patches, both of which takes - * precedence over this one. - * - * https://tools.suckless.org/dmenu/patches/pipeout/ - */ -#define PIPEOUT_PATCH 0 - -/* Lifted from the listfullwidth patch this simple change just avoids colors for the prompt (with - * the -p option or in config.h) by making it use the same style as the rest of the input field. - * The rest of the listfullwidth patch is covered by the vertfull patch. - * https://tools.suckless.org/dmenu/patches/listfullwidth/ - */ -#define PLAIN_PROMPT_PATCH 0 - -/* This patch changes the behaviour of matched items and the Tab key to allow tab completion. - * https://tools.suckless.org/dmenu/patches/prefix-completion/ - */ -#define PREFIXCOMPLETION_PATCH 0 - -/* This patch adds an option -ps to specify an item by providing the index that should be - * pre-selected. - * https://tools.suckless.org/dmenu/patches/preselect/ - */ -#define PRESELECT_PATCH 0 - -/* This patch allows dmenu to print out the 0-based index of matched text instead of the matched - * text itself. This can be useful in cases where you would like to select entries from one array - * of text but index into another, or when you are selecting from an ordered list of non-unique - * items. - * https://tools.suckless.org/dmenu/patches/printindex/ - */ -#define PRINTINDEX_PATCH 0 - -/* This patch adds a flag (-t) which makes Return key to ignore selection and print the input - * text to stdout. The flag basically swaps the functions of Return and Shift+Return hotkeys. - * - * This patch is not compatible with the multi-select and json patches, both of which takes - * precedence over this one. - * - * https://tools.suckless.org/dmenu/patches/printinputtext/ - */ -#define PRINTINPUTTEXT_PATCH 0 - -/* This patch adds a new flag to dmenu with which text input will be rejected if it would - * result in no matching item. - * https://tools.suckless.org/dmenu/patches/reject-no-match/ - */ -#define REJECTNOMATCH_PATCH 0 - -/* The input width used to be relative to the input options prior to commit e1e1de7: - * https://git.suckless.org/dmenu/commit/e1e1de7b3b8399cba90ddca9613f837b2dbef7b9.html - * - * This had a performance hit when using large data sets and was removed in favour of having the - * input width take up 1/3rd of the available space. - * - * This option adds that feature back in with some performance optimisations at the cost of - * accuracy and correctness. - */ -#define RELATIVE_INPUT_WIDTH_PATCH 0 - -/* This patch adds a '-1' option which disables Shift-Return and Ctrl-Return. - * This guarantees that dmenu will only output one item, and that item was read from stdin. - * The original patch used '-r'. This was changed to '-1' to avoid conflict with the incremental - * patch. - * https://tools.suckless.org/dmenu/patches/restrict-return/ - */ -#define RESTRICT_RETURN_PATCH 0 - -/* This patch adds support for text scrolling and no longer appends '...' for long input as - * it can handle long text. - * - * Known issue: not compatible with the pango patch - * - * https://tools.suckless.org/dmenu/patches/scroll/ - */ -#define SCROLL_PATCH 0 - -/* This patch adds -d and -D flags which separates the input into two halves; one half to be - * displayed in dmenu and the other to be printed to stdout. This patch takes precedence over - * the TSV patch. - * https://tools.suckless.org/dmenu/patches/separator/ - */ -#define SEPARATOR_PATCH 0 - -/* This patch allows the symbols, which are printed in dmenu to indicate that either the input - * is too long or there are too many options to be shown in dmenu in one line, to be defined. - * https://tools.suckless.org/dmenu/patches/symbols/ - */ -#define SYMBOLS_PATCH 0 - -/* With this patch dmenu will split input lines at first tab character and only display first - * part, but it will perform matching on and output full lines as usual. - * - * This can be useful if you want to separate data and representation, for example, a music - * player wrapper can display only a track title to user, but still supply full filename to - * the underlying script. - * https://tools.suckless.org/dmenu/patches/tsv/ - */ -#define TSV_PATCH 0 - -/* This patch prevents dmenu from indenting items at the same level as the prompt length. - * https://tools.suckless.org/dmenu/patches/vertfull/ - */ -#define VERTFULL_PATCH 0 - -/* Adds extended window manager hints such as _NET_WM_WINDOW_TYPE and _NET_WM_WINDOW_TYPE_DOCK. - * https://github.com/Baitinq/dmenu/blob/master/patches/dmenu-wm_type.diff - */ -#define WMTYPE_PATCH 0 - -/* This patch adds the ability to configure dmenu via Xresources. At startup, dmenu will read and - * apply the resources named below: - * dmenu.font : font or font set - * dmenu.background : normal background color - * dmenu.foreground : normal foreground color - * dmenu.selbackground : selected background color - * dmenu.selforeground : selected foreground color - * - * See patch/xresources.c for more color settings. - * - * https://tools.suckless.org/dmenu/patches/xresources/ - */ -#define XRESOURCES_PATCH 0 - -/* This patch adds options for specifying dmenu window position and width. - * The center patch takes precedence over the XYW patch if enabled. - * https://tools.suckless.org/dmenu/patches/xyw/ - */ -#define XYW_PATCH 0 diff --git a/menu/util.c b/menu/util.c index 96b82c9..8e26a51 100644 --- a/menu/util.c +++ b/menu/util.c @@ -1,4 +1,5 @@ /* See LICENSE file for copyright and license details. */ +#include #include #include #include @@ -10,17 +11,17 @@ void die(const char *fmt, ...) { va_list ap; + int saved_errno; + + saved_errno = errno; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); - if (fmt[0] && fmt[strlen(fmt)-1] == ':') { - fputc(' ', stderr); - perror(NULL); - } else { - fputc('\n', stderr); - } + if (fmt[0] && fmt[strlen(fmt)-1] == ':') + fprintf(stderr, " %s", strerror(saved_errno)); + fputc('\n', stderr); exit(1); } diff --git a/menu/util.h b/menu/util.h index 2922d77..c0a50d4 100644 --- a/menu/util.h +++ b/menu/util.h @@ -1,11 +1,7 @@ /* See LICENSE file for copyright and license details. */ -#ifndef MAX #define MAX(A, B) ((A) > (B) ? (A) : (B)) -#endif -#ifndef MIN #define MIN(A, B) ((A) < (B) ? (A) : (B)) -#endif #define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B)) #define LENGTH(X) (sizeof (X) / sizeof (X)[0])