From 8b29fbc29e4714680ed957c1f0a0b200092dbae3 Mon Sep 17 00:00:00 2001 From: TitanE Date: Thu, 28 Sep 2023 01:05:58 +0300 Subject: [PATCH] new patches and stuff --- config.def.h | 11 +- config.def.h.orig | 11 +- config.def.h.rej | 18 +- config.h | 9 +- config.h.bak | 23 +++ config.mk | 2 +- config.mk.orig | 2 +- dmenu | Bin 42936 -> 43400 bytes dmenu.1 | 16 +- dmenu.1.orig | 199 +++++++++++++++++++++++ dmenu.c | 166 ++++++++++++++++--- dmenu.c.orig | 171 +++++++++++++------ dmenu.c.rej | 6 +- dmenu.o | Bin 33400 -> 37904 bytes patch/dmenu-border-20230512-0fe460d.diff | 36 ++++ patch/dmenu-center-5.2.diff | 104 ++++++++++++ patch/dmenu-dracula.diff | 28 ---- patch/dmenu-grid-4.9.diff | 107 ++++++++++++ patch/dmenu-highlight-4.9.diff | 94 ----------- stest | Bin 16408 -> 16408 bytes 20 files changed, 782 insertions(+), 221 deletions(-) create mode 100644 config.h.bak create mode 100644 dmenu.1.orig create mode 100644 patch/dmenu-border-20230512-0fe460d.diff create mode 100644 patch/dmenu-center-5.2.diff delete mode 100644 patch/dmenu-dracula.diff create mode 100644 patch/dmenu-grid-4.9.diff delete mode 100644 patch/dmenu-highlight-4.9.diff diff --git a/config.def.h b/config.def.h index e688388..d46beeb 100644 --- a/config.def.h +++ b/config.def.h @@ -2,6 +2,7 @@ /* Default settings; can be overriden by command line. */ static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ +static int fuzzy = 1; /* -F option; if 0, dmenu doesn't use fuzzy matching */ /* -fn option overrides fonts[0]; default X11 font or font set */ static const char *fonts[] = { "monospace:size=10" @@ -9,15 +10,19 @@ static const char *fonts[] = { static const char *prompt = NULL; /* -p option; prompt to the left of input field */ static const char *colors[SchemeLast][2] = { /* fg bg */ - [SchemeNorm] = { "#f8f8f2", "#282a36" }, - [SchemeSel] = { "#f8f8f2", "#6272a4" }, + [SchemeNorm] = { "#bbbbbb", "#222222" }, + [SchemeSel] = { "#eeeeee", "#005577" }, [SchemeOut] = { "#000000", "#00ffff" }, }; -/* -l option; if nonzero, dmenu uses vertical list with given number of lines */ +/* -l and -g options; controls number of lines and columns in grid if > 0 */ static unsigned int lines = 0; +static unsigned int columns = 0; /* * Characters not considered part of a word while deleting words * for example: " /?\"&[]" */ static const char worddelimiters[] = " "; + +/* Size of the window border */ +static unsigned int border_width = 0; diff --git a/config.def.h.orig b/config.def.h.orig index e688388..d46beeb 100644 --- a/config.def.h.orig +++ b/config.def.h.orig @@ -2,6 +2,7 @@ /* Default settings; can be overriden by command line. */ static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ +static int fuzzy = 1; /* -F option; if 0, dmenu doesn't use fuzzy matching */ /* -fn option overrides fonts[0]; default X11 font or font set */ static const char *fonts[] = { "monospace:size=10" @@ -9,15 +10,19 @@ static const char *fonts[] = { static const char *prompt = NULL; /* -p option; prompt to the left of input field */ static const char *colors[SchemeLast][2] = { /* fg bg */ - [SchemeNorm] = { "#f8f8f2", "#282a36" }, - [SchemeSel] = { "#f8f8f2", "#6272a4" }, + [SchemeNorm] = { "#bbbbbb", "#222222" }, + [SchemeSel] = { "#eeeeee", "#005577" }, [SchemeOut] = { "#000000", "#00ffff" }, }; -/* -l option; if nonzero, dmenu uses vertical list with given number of lines */ +/* -l and -g options; controls number of lines and columns in grid if > 0 */ static unsigned int lines = 0; +static unsigned int columns = 0; /* * Characters not considered part of a word while deleting words * for example: " /?\"&[]" */ static const char worddelimiters[] = " "; + +/* Size of the window border */ +static unsigned int border_width = 0; diff --git a/config.def.h.rej b/config.def.h.rej index aae7dcc..bc7150a 100644 --- a/config.def.h.rej +++ b/config.def.h.rej @@ -1,11 +1,11 @@ --- config.def.h +++ config.def.h -@@ -11,8 +11,6 @@ static const char *colors[SchemeLast][2] = { - /* fg bg */ - [SchemeNorm] = { "#bbbbbb", "#222222" }, - [SchemeSel] = { "#eeeeee", "#005577" }, -- [SchemeSelHighlight] = { "#ffc978", "#005577" }, -- [SchemeNormHighlight] = { "#ffc978", "#222222" }, - [SchemeOut] = { "#000000", "#00ffff" }, - }; - /* -l option; if nonzero, dmenu uses vertical list with given number of lines */ +@@ -2,6 +2,8 @@ + /* Default settings; can be overriden by command line. */ + + static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ ++static int centered = 0; /* -c option; centers dmenu on screen */ ++static int min_width = 500; /* minimum width when centered */ + /* -fn option overrides fonts[0]; default X11 font or font set */ + static const char *fonts[] = { + "monospace:size=10" diff --git a/config.h b/config.h index 1edb647..c314599 100644 --- a/config.h +++ b/config.h @@ -2,6 +2,11 @@ /* Default settings; can be overriden by command line. */ static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ +static int fuzzy = 1; /* -F option; if 0, dmenu doesn't use fuzzy matching */ +static int border_width = 2; /* -F option; if 0, dmenu doesn't use fuzzy matching */ +static int columns = 2; /* -F option; if 0, dmenu doesn't use fuzzy matching */ +static int centered; /* -F option; if 0, dmenu doesn't use fuzzy matching */ +static int min_width = 1000; /* -F option; if 0, dmenu doesn't use fuzzy matching */ /* -fn option overrides fonts[0]; default X11 font or font set */ static const char *fonts[] = { "monospace:size=10" @@ -9,8 +14,8 @@ static const char *fonts[] = { 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" }, + [SchemeNorm] = { "#f8f8f2", "#282a36" }, + [SchemeSel] = { "#282a36", "#bd93f9" }, [SchemeOut] = { "#000000", "#00ffff" }, }; /* -l option; if nonzero, dmenu uses vertical list with given number of lines */ diff --git a/config.h.bak b/config.h.bak new file mode 100644 index 0000000..f99950f --- /dev/null +++ b/config.h.bak @@ -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=12" +}; +static const char *prompt = NULL; /* -p option; prompt to the left of input field */ +static const char *colors[SchemeLast][2] = { + /* fg bg */ + [SchemeNorm] = { "#f8f8f2", "#282a36" }, + [SchemeSel] = { "#282a36", "#bd93f9" }, + [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/config.mk b/config.mk index 566348b..fd6ff05 100644 --- a/config.mk +++ b/config.mk @@ -21,7 +21,7 @@ FREETYPEINC = /usr/include/freetype2 # includes and libs INCS = -I$(X11INC) -I$(FREETYPEINC) -LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) +LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) -lm # flags CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS) diff --git a/config.mk.orig b/config.mk.orig index fd6ff05..566348b 100644 --- a/config.mk.orig +++ b/config.mk.orig @@ -21,7 +21,7 @@ FREETYPEINC = /usr/include/freetype2 # includes and libs INCS = -I$(X11INC) -I$(FREETYPEINC) -LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) -lm +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) diff --git a/dmenu b/dmenu index 71c0e8d5fab7caca9251c04975cdf807a28c8e6c..b86e216ca830782019f651d93c3d96d02b37aaa3 100755 GIT binary patch delta 16382 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

)n%p<>SL z;!=TgCzn(dSI!nniYrQHO`Td*X0O7Rq%+H^gpyem)s-{Zon*U59sOYPG(9bdjg4CeZk#rBeEtmKU;0otdnY|9%rL+~YRc8iZ$ z-&;}jzrL7_dGkMF82?iCAu=U{MZDz>EtypbFUuyEmRH$}XO@(0TJ_c`zfI4rnj(rd z?DXo?u%h-_zawn#+) delta 14070 zcmaKT3tUvyzW?3>8v%s@1ZPkYP*hNPjEaFe%IKgQ8wwQ@UkM5(hL3|oc}g7&IH%n> zX|77`X=d8G+T1G*7QRm zLTifvLAa}zXzjMJLDKMzY?)|ET&Z)lg$V|YD}ikjcP0)j(^~%vk}+HZ*;>PciES<2 zYwNnISxA5@`uh{<3;uO}OP@ovcjqQ;{kHnj6B)tmm4M{f=}_c%UJw(6YC+(F)7f_c zL)fBFGcyO8#s16^Xkx{Ivgl;j15M%}whQeeA!czi+UepgYKx3$tU!{*RL&L5xz0%$ zVh55JU0h2}PzGBgnZ;Vpy)MWsCUfbZs9e>~ERN*D6S(k7w2N3tyL9$;JM*g0*uVfm z=*~VebQI6B>+RCT&MYx_wD@<<+Zb$SYl6+p#iM z9UQ-c>&XZ-$Ic5Bgh(M)$f?0-;tJM)u!LE{O!dWKAB*+9jNgkaB(hh`^yxDfl}w*i zKCh&r{E0GQp|f)4?8^GFk-f#BnQ05>rww8(Dvj-qN@B$wqdSVo2JQBj0jy)klvt5t z19|D^Fn~9JP3+j)B>}H-=t+oHpl}0T>eEHo`rM0{E|PFZ$3>TyhY8>b#ylaOj=UWp zMCt9S&gCJLnO*gHiFa~_*C|nXj4e0PQ`SKHidmkJ;X&TP87Qn zZHkTMZLMf*MNML=dCgzCk5SGvi+lS@HP8ZYJ2cVq=t)Lan zQvY3SyeJN1cRHI`zb+lZ8d?!^SZWuOXsgfdGT*=s#&rl=_tc-Zrm;hDCiX{Mhx&@i zpBh#rv=`r~?~qU{u_HaR+Q%CNA#dhh*^^nrI`-=BnmJey)C>Ri`MiG#6$IHmGzp|4 zLcV&(=c{X|GUi$i*p;vkrwW4i3-KOH7O_0RS&X%>|B3HG_!*jLqU@HYPlAXdorE}A zf6-c%q-+6%a$TOqNn&pH9b>KIPaTz{BVN-HCA$~*4OVS`_$Y!ns1gm8<;WjrdbzFXBC<@rKK8d*5LA^eXsV&HvQZwIi1I+OTvXgIjeDZ#FoT zHXKKhOwFrwj<1O05sf3#Z)OuXymNg%pU(6yF^$lfTz;;Xh)e#HOChefHmc?lQ;$EH zW)st`-+2h`*;@&py?5`zp2zw!76VIzI;St346^M&Km?m_ulFQkYXLp;Nf-6{Cd|l) zVvOw0oB|UNj3Uh+A}yLj)HS!sfb)XIr%po^k^6+0AkYDvfy5aK1F}2rHNv~CMtC64 ztT_j3inN|^yUw+f18P(tWcTa{SxK$n8hll*5HyO=XpXTQv$UxBFbM;rI2ktK(O{~3 zo=<8dY2|zM-&%h=f)vk5))&!B_31vOJSG|_cV-$9;0S=-U7K_qqVDBMM*!6E-2`Df z1p?h4J{fC+tn7!yFD8SQ9*?HpuZ5&^AXh4_15tM8WVv&K6{!o9=GL`1O^CnX0n;cjS&qTyKX8UqKcz6atrkD>I*{lDwbfU&5XO;K zxAY@fCf5ss-O>kW)a*9+8jK(AR$?9jhf9$rX^c(8m@OR!FxJ(;7wA7mIFB=_pDMS| zxa>o4jJ2~g;>RF5Jf%s=4o^i=hC{jFP_C$(Z~1)gxMzz5q3+D04weH$rY7|>F7M7~ zqCF`C1|EZ$v%LdaljNFP?1R3hhi?Byz0t_IL{68p_c;5=?x~RQ6eeZmE7u*07Y?O! zoA#s}#7kX|jv_Dj(FC=|fI?YPK&C+4cbj$Y_eQS?6A@IS(txt=fU)jVK(5hNfb_A# zO^6OFV(0sHcI}4ia?RcZsC2oVNnPEGlM-Z4exT)y-CdZ}&+Zu|+C2}7cH_=iE_?Q6yD|T=J>{J3a~KtDMtQGYJZ;b3 z4eAklb`z*g_LS4M&vdHm8w?6^FVMHA`4xHQ8TrvO9b~cDxN~Hnap(9TBuiIILyfiK zA@Em)0v*~{I*Zj=u1ZYc%4Yj56m$B@C4-JZbyiWH0Lwg525NS`9N94VNdWap)Fcm(=IWiy77#9Jkj2PURQ&HcJBLyiaCj4jr0^Z}$Ckr?RYeFLd9Ka_z zJeV@-))qF{($o4|A!Zmx-x{dtNf6Y@P|$o#W!HT^H4Vp7cT6E@?#ywTo_a{AUz<^+ zvR5p9;x|%zEaHRJpl%2bm@xSSaJ0dx%CGE_CCiXr$m09=HB|nKIr=YmZ5^LNp)TG`C4j|lChiw8tWb>)c8n*&!<*_g25j}QrWdh^nhlpdmUSv+8+!%DHEDc z*Lpdd3|2D{xYtpT7BgHsYIa9gho83)}vNhO8*hxrEb?9}rYQXTQj{U(uGjN$KHu}yvJl6K(>wg#!E4muT0`H0O0(=>0 z5Y+B)&-)a1R~UaENNln2_cee)EQXFLydpm3Kj(8#S9iPXsls=2Aer(q-#_LSY`%3C5uOV=VYso zLR)u)4jgXDK-N4lJpihQ8W3_7E4rqCHs%o~#<>Tn&(bM?eA;^UgMosWN7D>}YQUUT zk3_@StsFf}K`~db>W8ItJ$C98( zF+h9!kgXbPFzSL6M_FkaT9Nmek}5c zwj`%CHMghZwG-BJA)if{GnoF2h-fys5Vx^%a2no6mE!da{8_+%*K&|nz z_Jg|^TAEq%;E`iLLbCZ{ejhCe|C*I%jIV_hSUuLf`w2)R2xQ-K;-oEo0w!`L#COgZ zUrl^_bO`=f&Yu}|Kl>cYmyBko2FLZiGX_jm112DUCPNr;z2ppoAESWx#mGRZGhzNq z>G&9yIHXTl%p%e<6O&SU@qV^qNHUvf&2*W-E#t8(n9gg@@ZRsk1ojzgSCdZP9!K^M zm05Yq_R@|E?I*yWul$&|>qp6{UL}- zs{)X5vhp34t>=gzu?=>~yDmv;JpwG({F0C-UddB}ND)0tOd%~xxE84d0+trVnQYb{ ziy*6ZP$~XWu4WvaS59M@+I2yal@1YZNy&qe?31!_^d3c8ObvKrE|vQR_Dn|KoRa#e zmn|FC#}G7zeK0J+FgK4K9@fuw7|viIx>{Orlu}F3@_kjc4gSy}23veBw!Z(RX*;=6 zvp0Flv_0dMUzHoOau>lmD5D3Tm;@m}%7gvvlW=9q9@|5<3AVxsPS(_7pQqNX(4Q+`NkPT7OUq$NODevy@!3K?&Y(O%>wdB_0fAU9mba=NZ$)wY5 zJvE9z=57FIbj_1yYJ7o4743x^P*K-}QAD!AK1WclY@=1cH^A0#S+S{cSyX9>;+;7SmX;4>0mGnPQNv>eqrkk&lPJd{g0Aw2^udFA>MZJf8m<^W+i zMviq37ldiHsmh)j>nk7%RgqXl(m;k>&(VNYp{R^P#g=jwCYOT=nqCF4eL>yElWP{J zY6Z6+hUy%_uAHZiMWdlKk>Pp7e)En?v$=_P$vT--VXcXXCY70AX`1cCip5yGqTa-@ z#5UPBMcL(+J_dR%RM?9_VHjI~=abndXLsAG!$3_y=yO?Ks{lvAqAPk(bG znvWvDZ-Pc)?8n8HK+NGuU7vvE!4>xoaI^#;j-u6qp@rvbw=@|Q?I?hLXPzC&<$nQC z4}?;`=YWn}Y~o$zc~t=n1-}tYH*YImE%*Y)Y0|@3c|$-Jn_)K( zGgpaoq^K*X^zTS_L71_04#n7khW8DiFT4Z?xT7t6=9n9}@(KD*Y+M_$>$qqc`$;uw}8S;}(Ink>wi3Tz6R)a-_(T$K1jlZ0s1{vuqIM+x48miuxeNdk zW>P-@JYfao)V5T84T~!w0(8uuXlDX#_&-w=uordIv^+*GDAJW2_Qa?(!^U&$-BIc7 zKhD82@{q%m`DRykaa3QI4>EM}K`f)m33@g5i?a-`zJ`MlkJ}=m_XO(MdzSR~?NQ<$ zL!I90?D`>qUQg}hLQ)Z7=@bPVI(4WEIu*iCp^_COSg`oUDE-dm`Sz;slbg!E<`*r# z+%d{!882vpbL%cTqtT~G(&Nrj-}#PsFgs{lw4MPr*K#qJ&NZ3j7_DJS=5o|j7ja@{ z4QD4u_m2K>7|9QjG1c)Zec%ya%pEK1DEBc$4rjwF8yvI7{6+v$VZKxr&WWR!-g6Fl8Eg@FdJ@dcCKyEc%V?QEpp~IXsf1 z8~W)98`F)Qa#&4ir^wAAvU_2K`V`fb@27aToo1=|5639*6pJT3;UQ1398>>xhONtw zGh9B+cIIaq8qTto{2qqi&$2ELOmlT5PieJAZsjTat2!eY8wVpIp3Jv#y2g?ACAjQ; z6C=Q%vS@+-lsciyRH1X$)tbOMO`x2UpTtAMUG>ljtRCg`n#;NcRCOHIxE;w*rcI!s z?B)ZnCB}0f7ADK?Cxg}9CrSB}S?U**0o1XKlkAfRb0Y47fc(eUQ~tkcWT5cTpuxr$(VMQdr9;{E*udva`!K{?637~9YA@(I>F_M)Nc zTXu9@Ps79CvRmW28~U7NUB}1vzB`Hc6E82T;%@E}(ZKVUCv!;*Wf@+`NLaU})05cL z@du3uacCTq-L=t`iH9avCw5<9x#9UDw!Uz<;hSUZhr&~a*+07L z*jh0p6$bn=M+EmGvw9j_G#YsSo!JZYJS;F+Yif@BeEuIVOhCJkaq9GAI0hd>df?3& z`-T$bs`?(F&HZ>pp4){X`-$ETma4OklG4RV8F_eXqCko`MOdO&OhyOXOyJ7BCva-l zBwN%(Xd>$vB`gh@7c7)U)(zPIu&xBC1CFwqi9-x6hgrkKK87*l+0PSG4QCFsE=5BO zX-8R6(N;szAr?Lkzsv0+d8R#m)C%<9)hWxS(=WK>4)r)6(1j$Y`Xl zi0W5ylQKcawN{*}<63lsN>QKM;PWjG6oloJplH`20ha@Q4!92RF6O{Rz<0j&`8r_E{5K%IL;e{HL@A&f ztJ8A8U@R>M0U1`V*#Uyk18Zn4VAm#}?|r~|fENSs^c#z_P6iCV3fK>e!3n?|z`zSW z-&DX2fExgR2Rsg#a}n+b!BN1WfXe}k051YA0-SQm=i3Ze2Dle+KHy0}Gagq9aLO77 zxES!i0pD+j_oE|zf#G05SP19<`~c7i_$%N#z{o2;-{*j#SD`4FZJgCTE(;;;g`f%c zb`b=Ua1X>?z0K!az%I?|5qljR_YnzK4(DvrkOS4P zo7k$keS#LF+Ua|?d+rmx{y;Sx35{(4;}9M(CfqzSJmG%sNfJ<9k=XH<*o=AIgY2kU zF0p6k^%}MS)iIF5!ATFw_~s&eYs7WzSN=%&&=ADpaHzV;8#&02ch`nOuMRC2NWE?OGb2n1!PSUGSb?Ie5WA7tJxcZZXl7Zn=gHoGu)R<`eWg ze@$;E>-5`tyFDA*ZG~aw60Dq^wp4F6uzwiLog1GbQB4?%d|FEo3Pysh+hG4!T>h`N z{2yugKg#ldgq1o&6ZC&}g=KSG&BK;$SsL2EkdQ|rf{<0K;r$(&iwq)sF*{#lioK>w zjnI44Lzl{6k+r6jV0d`c9Wh z)TPGh{GYbr$IrOj!yMgnzxAoQp1ZmpzLo(uTjTF66t)p~R995M#5$8pZbPlosrEMb zB|5%%11h)9oQtxZWomxy4Ip7lEZJzb!k9>k}0pZ$Fa*YGZ(x=m+dIKeEm{n#>2 z$NRrJ^ba@vfJTPty)j*S?}b#I|HxAs-fwuIjz7-vNJ&2-ODANsacG#17j!(|M4&U5 z<70(eZF)urFB-igZS*|E-gw$%nW9tGHq>Gr-_QnM%0$KFngc3z@~GZP|E~F0E)^jp zmua0urtxc;j!$iaS9Cq?M{9h1r$zO7&L1n}P!8kr$K)+d&j_5zG(xflg!gp=4W<7t zzTU6sEuB$MgPqh3c1^Dyq}k2c{z=jl~l&oLR%C9+@LSly>xZjXXp{`ppM~! zd5ng9T&KOk<+rjo+$QlLyS~EA+sCP78G%wigHg~oKfiCnWrTywJf=?@eiQ)p4=x(c z#N}PtzQB%RCjY>@0bkRP;~#Ms^Ku@Qu}cFq9a;JquG6(EoaaS0)?*U4@cMqve+K-K zbbu+=82w|*zoBPG@acFk|A;&R-`V%(pO0tpax^c;QYn>Eu<5ZQb}4ER{~_#d;z{YwI)1G_9R4F3 zeeV6AK5S28B`fH^5U9-MWdW6zX~b_Z-}?|=vw~BpuK%vy2YN1{tCGvsQJJ?!=h>u> zqrac^x=#PmLX*U~Q0G6XkJ&_>@Di(4X6=Vn{xD3MprIu;2J*WECb>Z$zTxGHh(y7C=;~s5;{2Hd?|K^XTj(?D(#9}Jh%2j6ZN#1^zmm7Gw zo0rF^WLeA{dkdP#cX^YpLI-!)Se7oD*fM6qm*iAtQJI&I9fBgUqD`Jm)$t8_KZ@1ZO@1xqI-ld^tGxV(m-~2mhL_D$#@>Yp&5gFvm6-Sf{j&&4c5S&iwp)ni z*?B#Ca&=3ooNov(i>Qp9sdMJ)qv_wBA0et`p-x@dQ&W%_rNKpnH{d{?pexqFQj%hg zFUICqmX(w)be5LS6Uv=sa~BE~<@3rG3XfEl%y_iyuQTSCRF(>5b7z#53Z)DFDmcp) zIUk=sv!Z0~0-?0>aiOAeK}o4Fv!r6?{8_UWmN{Ac>NGZQbtSvJI-y(nyoF_zPQf{U z!HkkhVeb5S!mRo8oC}4S^DE|8F08k$St+u!YfD(cOP84a<;wc~FW(l~u~(PZ&wuSi zK)t-aSQO3doj21X1^)wt4wIP|SpUJ^4|lVa4e4?I#{oYq&^wHb5kywCp+}_uF~SdT zv3EA4NBSQ&{4j!fH@L(Fto*I?D1T7>aDN(m_pP*0|B7Bz$S%A!3jgesvN1iU~{zM(7W2Pj;tLRg=7 R28DLl551j4HfMde{{ag8qiX;F diff --git a/dmenu.1 b/dmenu.1 index 3e3b31b..57ea184 100644 --- a/dmenu.1 +++ b/dmenu.1 @@ -3,7 +3,9 @@ dmenu \- dynamic menu .SH SYNOPSIS .B dmenu -.RB [ \-bfsv ] +.RB [ \-bfiv ] +.RB [ \-g +.IR columns ] .RB [ \-l .IR lines ] .RB [ \-m @@ -40,15 +42,21 @@ which lists programs in the user's $PATH and runs the result in their $SHELL. .B \-b dmenu appears at the bottom of the screen. .TP +.B \-c +dmenu appears centered on the screen. +.TP .B \-f dmenu grabs the keyboard before reading stdin if not reading from a tty. This is faster, but will lock up X until stdin reaches end\-of\-file. .TP -.B \-s -dmenu matches menu items case sensitively. +.B \-i +dmenu matches menu items case insensitively. +.TP +.BI \-g " columns" +dmenu lists items in a grid with the given number of columns. .TP .BI \-l " lines" -dmenu lists items vertically, with the given number of lines. +dmenu lists items in a grid with the given number of lines. .TP .BI \-m " monitor" dmenu is displayed on the monitor number supplied. Monitor numbers are starting diff --git a/dmenu.1.orig b/dmenu.1.orig new file mode 100644 index 0000000..d0a734a --- /dev/null +++ b/dmenu.1.orig @@ -0,0 +1,199 @@ +.TH DMENU 1 dmenu\-VERSION +.SH NAME +dmenu \- dynamic menu +.SH SYNOPSIS +.B dmenu +.RB [ \-bfiv ] +.RB [ \-g +.IR columns ] +.RB [ \-l +.IR lines ] +.RB [ \-m +.IR monitor ] +.RB [ \-p +.IR prompt ] +.RB [ \-fn +.IR font ] +.RB [ \-nb +.IR color ] +.RB [ \-nf +.IR color ] +.RB [ \-sb +.IR color ] +.RB [ \-sf +.IR color ] +.RB [ \-w +.IR windowid ] +.P +.BR dmenu_run " ..." +.SH DESCRIPTION +.B dmenu +is a dynamic menu for X, which reads a list of newline\-separated items from +stdin. When the user selects an item and presses Return, their choice is printed +to stdout and dmenu terminates. Entering text will narrow the items to those +matching the tokens in the input. +.P +.B dmenu_run +is a script used by +.IR dwm (1) +which lists programs in the user's $PATH and runs the result in their $SHELL. +.SH OPTIONS +.TP +.B \-b +dmenu appears at the bottom of the screen. +.TP +.B \-f +dmenu grabs the keyboard before reading stdin if not reading from a tty. This +is faster, but will lock up X until stdin reaches end\-of\-file. +.TP +.B \-i +dmenu matches menu items case insensitively. +.TP +.BI \-g " columns" +dmenu lists items in a grid with the given number of columns. +.TP +.BI \-l " lines" +dmenu lists items in a grid with the given number of lines. +.TP +.BI \-m " monitor" +dmenu is displayed on the monitor number supplied. Monitor numbers are starting +from 0. +.TP +.BI \-p " prompt" +defines the prompt to be displayed to the left of the input field. +.TP +.BI \-fn " font" +defines the font or font set used. +.TP +.BI \-nb " color" +defines the normal background color. +.IR #RGB , +.IR #RRGGBB , +and X color names are supported. +.TP +.BI \-nf " color" +defines the normal foreground color. +.TP +.BI \-sb " color" +defines the selected background color. +.TP +.BI \-sf " color" +defines the selected foreground color. +.TP +.B \-v +prints version information to stdout, then exits. +.TP +.BI \-w " windowid" +embed into windowid. +.SH USAGE +dmenu is completely controlled by the keyboard. Items are selected using the +arrow keys, page up, page down, home, and end. +.TP +.B Tab +Copy the selected item to the input field. +.TP +.B Return +Confirm selection. Prints the selected item to stdout and exits, returning +success. +.TP +.B Ctrl-Return +Confirm selection. Prints the selected item to stdout and continues. +.TP +.B Shift\-Return +Confirm input. Prints the input text to stdout and exits, returning success. +.TP +.B Escape +Exit without selecting an item, returning failure. +.TP +.B Ctrl-Left +Move cursor to the start of the current word +.TP +.B Ctrl-Right +Move cursor to the end of the current word +.TP +.B C\-a +Home +.TP +.B C\-b +Left +.TP +.B C\-c +Escape +.TP +.B C\-d +Delete +.TP +.B C\-e +End +.TP +.B C\-f +Right +.TP +.B C\-g +Escape +.TP +.B C\-h +Backspace +.TP +.B C\-i +Tab +.TP +.B C\-j +Return +.TP +.B C\-J +Shift-Return +.TP +.B C\-k +Delete line right +.TP +.B C\-m +Return +.TP +.B C\-M +Shift-Return +.TP +.B C\-n +Down +.TP +.B C\-p +Up +.TP +.B C\-u +Delete line left +.TP +.B C\-w +Delete word left +.TP +.B C\-y +Paste from primary X selection +.TP +.B C\-Y +Paste from X clipboard +.TP +.B M\-b +Move cursor to the start of the current word +.TP +.B M\-f +Move cursor to the end of the current word +.TP +.B M\-g +Home +.TP +.B M\-G +End +.TP +.B M\-h +Up +.TP +.B M\-j +Page down +.TP +.B M\-k +Page up +.TP +.B M\-l +Down +.SH SEE ALSO +.IR dwm (1), +.IR stest (1) diff --git a/dmenu.c b/dmenu.c index f658b10..7a43296 100644 --- a/dmenu.c +++ b/dmenu.c @@ -1,6 +1,7 @@ /* See LICENSE file for copyright and license details. */ #include #include +#include #include #include #include @@ -33,6 +34,7 @@ struct item { char *text; struct item *left, *right; int out; + double distance; }; static char numbers[NUMBERSBUFSIZE] = ""; @@ -57,9 +59,8 @@ static Clr *scheme[SchemeLast]; #include "config.h" -static char * cistrstr(const char *s, const char *sub); -static int (*fstrncmp)(const char *, const char *, size_t) = strncasecmp; -static char *(*fstrstr)(const char *, const char *) = cistrstr; +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) @@ -87,7 +88,7 @@ calcoffsets(void) int i, n; if (lines > 0) - n = lines * bh; + n = lines * columns * bh; else n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">") + TEXTW(numbers)); /* calculate which items will begin the next page and previous page */ @@ -99,6 +100,15 @@ calcoffsets(void) break; } +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; +} + static void cleanup(void) { @@ -188,9 +198,15 @@ drawmenu(void) recalculatenumbers(); if (lines > 0) { - /* draw vertical list */ - for (item = curr; item != next; item = item->right) - drawitem(item, x, y += bh, mw - x); + /* draw grid */ + int i = 0; + for (item = curr; item != next; item = item->right, i++) + drawitem( + item, + x + ((i / lines) * ((mw - x) / columns)), + y + (((i % lines) + 1) * bh), + (mw - x) / columns + ); } else if (matches) { /* draw horizontal list */ x += inputw; @@ -248,9 +264,94 @@ grabkeyboard(void) die("cannot grab keyboard"); } +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; + + 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; + } + /* 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]) { + appenditem(it, &matches, &matchend); + } + free(fuzzymatches); + } + curr = sel = matches; + calcoffsets(); +} + static void match(void) { + if (fuzzy) { + fuzzymatch(); + return; + } static char **tokv = NULL; static int tokn = 0; @@ -658,6 +759,7 @@ setup(void) bh = drw->fonts->h + 2; lines = MAX(lines, 0); mh = (lines + 1) * bh; + promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; #ifdef XINERAMA i = 0; if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) { @@ -684,9 +786,16 @@ setup(void) if (INTERSECT(x, y, 1, 1, info[i]) != 0) break; - x = info[i].x_org; - y = info[i].y_org + (topbar ? 0 : info[i].height - mh); - mw = info[i].width; + if (centered) { + mw = MIN(MAX(max_textw() + promptw, min_width), info[i].width); + x = info[i].x_org + ((info[i].width - mw) / 2); + y = info[i].y_org + ((info[i].height - mh) / 2); + } else { + x = info[i].x_org; + y = info[i].y_org + (topbar ? 0 : info[i].height - mh); + mw = info[i].width; + } + XFree(info); } else #endif @@ -694,9 +803,16 @@ setup(void) if (!XGetWindowAttributes(dpy, parentwin, &wa)) die("could not get embedding window attributes: 0x%lx", parentwin); - x = 0; - y = topbar ? 0 : wa.height - mh; - mw = wa.width; + + if (centered) { + mw = MIN(MAX(max_textw() + promptw, min_width), wa.width); + x = (wa.width - mw) / 2; + y = (wa.height - mh) / 2; + } else { + x = 0; + y = topbar ? 0 : wa.height - mh; + mw = wa.width; + } } promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; inputw = mw / 3; /* input width: ~33% of monitor width */ @@ -706,9 +822,11 @@ setup(void) swa.override_redirect = True; swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; - win = XCreateWindow(dpy, root, x, y, mw, mh, 0, + win = XCreateWindow(dpy, root, x, y, mw, mh, border_width, CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); + if (border_width) + XSetWindowBorder(dpy, win, scheme[SchemeSel][ColBg].pixel); XSetClassHint(dpy, win, &ch); @@ -756,15 +874,23 @@ main(int argc, char *argv[]) topbar = 0; else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ fast = 1; - else if (!strcmp(argv[i], "-s")) { /* case-sensitive item matching */ - fstrncmp = strncmp; - fstrstr = strstr; + else if (!strcmp(argv[i], "-c")) /* centers dmenu on screen */ + centered = 1; + else if (!strcmp(argv[i], "-F")) /* grabs keyboard before reading stdin */ + fuzzy = 0; + else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ + fstrncmp = strncasecmp; + fstrstr = cistrstr; } else if (i + 1 == argc) usage(); /* these options take one argument */ - else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */ + else if (!strcmp(argv[i], "-g")) { /* number of columns in grid */ + columns = atoi(argv[++i]); + if (lines == 0) lines = 1; + } else if (!strcmp(argv[i], "-l")) { /* number of lines in grid */ lines = atoi(argv[++i]); - else if (!strcmp(argv[i], "-m")) + if (columns == 0) columns = 1; + } else if (!strcmp(argv[i], "-m")) mon = atoi(argv[++i]); else if (!strcmp(argv[i], "-p")) /* adds prompt to left of input field */ prompt = argv[++i]; @@ -780,6 +906,8 @@ main(int argc, char *argv[]) colors[SchemeSel][ColFg] = argv[++i]; else if (!strcmp(argv[i], "-w")) /* embedding window id */ embed = argv[++i]; + else if (!strcmp(argv[i], "-bw")) + border_width = atoi(argv[++i]); /* border width */ else usage(); diff --git a/dmenu.c.orig b/dmenu.c.orig index 9cb5c01..45ec60c 100644 --- a/dmenu.c.orig +++ b/dmenu.c.orig @@ -1,6 +1,7 @@ /* See LICENSE file for copyright and license details. */ #include #include +#include #include #include #include @@ -27,12 +28,13 @@ #define NUMBERSBUFSIZE (NUMBERSMAXDIGITS * 2) + 1 /* enums */ -enum { SchemeNorm, SchemeSel, SchemeOut, SchemeNormHighlight, SchemeSelHighlight, SchemeLast }; /* color schemes */ +enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ struct item { char *text; struct item *left, *right; int out; + double distance; }; static char numbers[NUMBERSBUFSIZE] = ""; @@ -57,9 +59,8 @@ static Clr *scheme[SchemeLast]; #include "config.h" -static char * cistrstr(const char *s, const char *sub); -static int (*fstrncmp)(const char *, const char *, size_t) = strncasecmp; -static char *(*fstrstr)(const char *, const char *) = cistrstr; +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) @@ -87,7 +88,7 @@ calcoffsets(void) int i, n; if (lines > 0) - n = lines * bh; + n = lines * columns * bh; else n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">") + TEXTW(numbers)); /* calculate which items will begin the next page and previous page */ @@ -133,43 +134,6 @@ cistrstr(const char *h, const char *n) return NULL; } -static void -drawhighlights(struct item *item, int x, int y, int maxw) -{ - char restorechar, tokens[sizeof text], *highlight, *token; - int indentx, highlightlen; - - drw_setscheme(drw, scheme[item == sel ? SchemeSelHighlight : SchemeNormHighlight]); - strcpy(tokens, text); - for (token = strtok(tokens, " "); token; token = strtok(NULL, " ")) { - highlight = fstrstr(item->text, token); - while (highlight) { - // Move item str end, calc width for highlight indent, & restore - highlightlen = highlight - item->text; - restorechar = *highlight; - item->text[highlightlen] = '\0'; - indentx = TEXTW(item->text); - item->text[highlightlen] = restorechar; - - // Move highlight str end, draw highlight, & restore - restorechar = highlight[strlen(token)]; - highlight[strlen(token)] = '\0'; - if (indentx - (lrpad / 2) - 1 < maxw) - drw_text( - drw, - x + indentx - (lrpad / 2) - 1, - y, - MIN(maxw - indentx, TEXTW(highlight) - lrpad), - bh, 0, highlight, 0 - ); - highlight[strlen(token)] = restorechar; - - if (strlen(highlight) - strlen(token) < strlen(token)) break; - highlight = fstrstr(highlight + strlen(token), token); - } - } -} - static int drawitem(struct item *item, int x, int y, int w) { @@ -180,9 +144,7 @@ drawitem(struct item *item, int x, int y, int w) else drw_setscheme(drw, scheme[SchemeNorm]); - int r = drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0); - drawhighlights(item, x, y, w); - return r; + return drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0); } static void @@ -227,9 +189,15 @@ drawmenu(void) recalculatenumbers(); if (lines > 0) { - /* draw vertical list */ - for (item = curr; item != next; item = item->right) - drawitem(item, x, y += bh, mw - x); + /* draw grid */ + int i = 0; + for (item = curr; item != next; item = item->right, i++) + drawitem( + item, + x + ((i / lines) * ((mw - x) / columns)), + y + (((i % lines) + 1) * bh), + (mw - x) / columns + ); } else if (matches) { /* draw horizontal list */ x += inputw; @@ -287,9 +255,94 @@ grabkeyboard(void) die("cannot grab keyboard"); } +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; + + 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; + } + /* 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]) { + appenditem(it, &matches, &matchend); + } + free(fuzzymatches); + } + curr = sel = matches; + calcoffsets(); +} + static void match(void) { + if (fuzzy) { + fuzzymatch(); + return; + } static char **tokv = NULL; static int tokn = 0; @@ -745,9 +798,11 @@ setup(void) swa.override_redirect = True; swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; - win = XCreateWindow(dpy, root, x, y, mw, mh, 0, + win = XCreateWindow(dpy, root, x, y, mw, mh, border_width, CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); + if (border_width) + XSetWindowBorder(dpy, win, scheme[SchemeSel][ColBg].pixel); XSetClassHint(dpy, win, &ch); @@ -795,15 +850,21 @@ main(int argc, char *argv[]) topbar = 0; else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ fast = 1; - else if (!strcmp(argv[i], "-s")) { /* case-sensitive item matching */ - fstrncmp = strncmp; - fstrstr = strstr; + else if (!strcmp(argv[i], "-F")) /* grabs keyboard before reading stdin */ + fuzzy = 0; + else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ + fstrncmp = strncasecmp; + fstrstr = cistrstr; } else if (i + 1 == argc) usage(); /* these options take one argument */ - else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */ + else if (!strcmp(argv[i], "-g")) { /* number of columns in grid */ + columns = atoi(argv[++i]); + if (lines == 0) lines = 1; + } else if (!strcmp(argv[i], "-l")) { /* number of lines in grid */ lines = atoi(argv[++i]); - else if (!strcmp(argv[i], "-m")) + if (columns == 0) columns = 1; + } else if (!strcmp(argv[i], "-m")) mon = atoi(argv[++i]); else if (!strcmp(argv[i], "-p")) /* adds prompt to left of input field */ prompt = argv[++i]; @@ -819,6 +880,8 @@ main(int argc, char *argv[]) colors[SchemeSel][ColFg] = argv[++i]; else if (!strcmp(argv[i], "-w")) /* embedding window id */ embed = argv[++i]; + else if (!strcmp(argv[i], "-bw")) + border_width = atoi(argv[++i]); /* border width */ else usage(); diff --git a/dmenu.c.rej b/dmenu.c.rej index 61ff7c2..c8ad233 100644 --- a/dmenu.c.rej +++ b/dmenu.c.rej @@ -1,11 +1,11 @@ --- dmenu.c +++ dmenu.c -@@ -702,8 +615,6 @@ main(int argc, char *argv[]) +@@ -757,6 +781,8 @@ main(int argc, char *argv[]) topbar = 0; else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ fast = 1; -- else if (!strcmp(argv[i], "-F")) /* grabs keyboard before reading stdin */ -- fuzzy = 0; ++ else if (!strcmp(argv[i], "-c")) /* centers dmenu on screen */ ++ centered = 1; else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ fstrncmp = strncasecmp; fstrstr = cistrstr; diff --git a/dmenu.o b/dmenu.o index 29a7bfc6ba99a53581df63be536211b104f86bb3..f66b857cc4644fd6444154a074387b0017b07c7a 100644 GIT binary patch literal 37904 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

hBv8dKoR^zVip)r;U8p)7bjhj%AcFw2ShTEOx0 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 literal 33400 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 yZa#j)JO4B<7zz6e;Un|oO?G?^4text; item++) ++ len = MAX(TEXTW(item->text), len); ++ return len; ++} ++ + static void + cleanup(void) + { +@@ -636,6 +645,7 @@ setup(void) + bh = drw->fonts->h + 2; + lines = MAX(lines, 0); + mh = (lines + 1) * bh; ++ promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; + #ifdef XINERAMA + i = 0; + if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) { +@@ -662,9 +672,16 @@ setup(void) + if (INTERSECT(x, y, 1, 1, info[i]) != 0) + break; + +- x = info[i].x_org; +- y = info[i].y_org + (topbar ? 0 : info[i].height - mh); +- mw = info[i].width; ++ if (centered) { ++ mw = MIN(MAX(max_textw() + promptw, min_width), info[i].width); ++ x = info[i].x_org + ((info[i].width - mw) / 2); ++ y = info[i].y_org + ((info[i].height - mh) / 2); ++ } else { ++ x = info[i].x_org; ++ y = info[i].y_org + (topbar ? 0 : info[i].height - mh); ++ mw = info[i].width; ++ } ++ + XFree(info); + } else + #endif +@@ -672,9 +689,16 @@ setup(void) + if (!XGetWindowAttributes(dpy, parentwin, &wa)) + die("could not get embedding window attributes: 0x%lx", + parentwin); +- x = 0; +- y = topbar ? 0 : wa.height - mh; +- mw = wa.width; ++ ++ if (centered) { ++ mw = MIN(MAX(max_textw() + promptw, min_width), wa.width); ++ x = (wa.width - mw) / 2; ++ y = (wa.height - mh) / 2; ++ } else { ++ x = 0; ++ y = topbar ? 0 : wa.height - mh; ++ mw = wa.width; ++ } + } + promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; + inputw = mw / 3; /* input width: ~33% of monitor width */ +@@ -733,6 +757,8 @@ main(int argc, char *argv[]) + topbar = 0; + else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ + fast = 1; ++ else if (!strcmp(argv[i], "-c")) /* centers dmenu on screen */ ++ centered = 1; + else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ + fstrncmp = strncasecmp; + fstrstr = cistrstr; diff --git a/patch/dmenu-dracula.diff b/patch/dmenu-dracula.diff deleted file mode 100644 index 6c871c3..0000000 --- a/patch/dmenu-dracula.diff +++ /dev/null @@ -1,28 +0,0 @@ -From f16313b64965d74e6cbb30fa41d53aaf09b9ad49 Mon Sep 17 00:00:00 2001 -From: David Lima -Date: Sun, 28 Nov 2021 17:02:43 -0300 -Subject: [PATCH] apply dracula theme to dmenu - ---- - config.def.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/config.def.h b/config.def.h -index 1edb647..e688388 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -9,8 +9,8 @@ static const char *fonts[] = { - 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" }, -+ [SchemeNorm] = { "#f8f8f2", "#282a36" }, -+ [SchemeSel] = { "#f8f8f2", "#6272a4" }, - [SchemeOut] = { "#000000", "#00ffff" }, - }; - /* -l option; if nonzero, dmenu uses vertical list with given number of lines */ --- -2.34.1 - - diff --git a/patch/dmenu-grid-4.9.diff b/patch/dmenu-grid-4.9.diff new file mode 100644 index 0000000..c27689b --- /dev/null +++ b/patch/dmenu-grid-4.9.diff @@ -0,0 +1,107 @@ +From 39ab9676914bd0d8105d0f96bbd7611a53077438 Mon Sep 17 00:00:00 2001 +From: Miles Alan +Date: Sat, 4 Jul 2020 11:19:04 -0500 +Subject: [PATCH] Add -g option to display entries in the given number of grid + columns + +This option can be used in conjunction with -l to format dmenu's options in +arbitrary size grids. For example, to create a 4 column by 6 line grid, you +could use: dmenu -g 4 -l 6 +--- + config.def.h | 3 ++- + dmenu.1 | 7 ++++++- + dmenu.c | 22 ++++++++++++++++------ + 3 files changed, 24 insertions(+), 8 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 1edb647..96cf3c9 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -13,8 +13,9 @@ static const char *colors[SchemeLast][2] = { + [SchemeSel] = { "#eeeeee", "#005577" }, + [SchemeOut] = { "#000000", "#00ffff" }, + }; +-/* -l option; if nonzero, dmenu uses vertical list with given number of lines */ ++/* -l and -g options; controls number of lines and columns in grid if > 0 */ + static unsigned int lines = 0; ++static unsigned int columns = 0; + + /* + * Characters not considered part of a word while deleting words +diff --git a/dmenu.1 b/dmenu.1 +index 323f93c..d0a734a 100644 +--- a/dmenu.1 ++++ b/dmenu.1 +@@ -4,6 +4,8 @@ dmenu \- dynamic menu + .SH SYNOPSIS + .B dmenu + .RB [ \-bfiv ] ++.RB [ \-g ++.IR columns ] + .RB [ \-l + .IR lines ] + .RB [ \-m +@@ -47,8 +49,11 @@ is faster, but will lock up X until stdin reaches end\-of\-file. + .B \-i + dmenu matches menu items case insensitively. + .TP ++.BI \-g " columns" ++dmenu lists items in a grid with the given number of columns. ++.TP + .BI \-l " lines" +-dmenu lists items vertically, with the given number of lines. ++dmenu lists items in a grid with the given number of lines. + .TP + .BI \-m " monitor" + dmenu is displayed on the monitor number supplied. Monitor numbers are starting +diff --git a/dmenu.c b/dmenu.c +index 6b8f51b..d79b6bb 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -77,7 +77,7 @@ calcoffsets(void) + int i, n; + + if (lines > 0) +- n = lines * bh; ++ n = lines * columns * bh; + else + n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">")); + /* calculate which items will begin the next page and previous page */ +@@ -152,9 +152,15 @@ drawmenu(void) + } + + if (lines > 0) { +- /* draw vertical list */ +- for (item = curr; item != next; item = item->right) +- drawitem(item, x, y += bh, mw - x); ++ /* draw grid */ ++ int i = 0; ++ for (item = curr; item != next; item = item->right, i++) ++ drawitem( ++ item, ++ x + ((i / lines) * ((mw - x) / columns)), ++ y + (((i % lines) + 1) * bh), ++ (mw - x) / columns ++ ); + } else if (matches) { + /* draw horizontal list */ + x += inputw; +@@ -708,9 +714,13 @@ main(int argc, char *argv[]) + } else if (i + 1 == argc) + usage(); + /* these options take one argument */ +- else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */ ++ else if (!strcmp(argv[i], "-g")) { /* number of columns in grid */ ++ columns = atoi(argv[++i]); ++ if (lines == 0) lines = 1; ++ } else if (!strcmp(argv[i], "-l")) { /* number of lines in grid */ + lines = atoi(argv[++i]); +- else if (!strcmp(argv[i], "-m")) ++ if (columns == 0) columns = 1; ++ } else if (!strcmp(argv[i], "-m")) + mon = atoi(argv[++i]); + else if (!strcmp(argv[i], "-p")) /* adds prompt to left of input field */ + prompt = argv[++i]; +-- +2.23.1 + diff --git a/patch/dmenu-highlight-4.9.diff b/patch/dmenu-highlight-4.9.diff deleted file mode 100644 index 8eb784b..0000000 --- a/patch/dmenu-highlight-4.9.diff +++ /dev/null @@ -1,94 +0,0 @@ -From a06d0d3d7bbb3c0f5bad44934dbbf1e88e7d9558 Mon Sep 17 00:00:00 2001 -From: Miles Alan -Date: Sat, 4 Jul 2020 11:49:04 -0500 -Subject: [PATCH] Highlight matched text in a different color scheme - ---- - config.def.h | 2 ++ - dmenu.c | 43 +++++++++++++++++++++++++++++++++++++++++-- - 2 files changed, 43 insertions(+), 2 deletions(-) - -diff --git a/config.def.h b/config.def.h -index 1edb647..64eab2a 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -11,6 +11,8 @@ static const char *colors[SchemeLast][2] = { - /* fg bg */ - [SchemeNorm] = { "#bbbbbb", "#222222" }, - [SchemeSel] = { "#eeeeee", "#005577" }, -+ [SchemeSelHighlight] = { "#ffc978", "#005577" }, -+ [SchemeNormHighlight] = { "#ffc978", "#222222" }, - [SchemeOut] = { "#000000", "#00ffff" }, - }; - /* -l option; if nonzero, dmenu uses vertical list with given number of lines */ -diff --git a/dmenu.c b/dmenu.c -index 6b8f51b..d5e1991 100644 ---- a/dmenu.c -+++ b/dmenu.c -@@ -26,7 +26,7 @@ - #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) - - /* enums */ --enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ -+enum { SchemeNorm, SchemeSel, SchemeOut, SchemeNormHighlight, SchemeSelHighlight, SchemeLast }; /* color schemes */ - - struct item { - char *text; -@@ -113,6 +113,43 @@ cistrstr(const char *s, const char *sub) - return NULL; - } - -+static void -+drawhighlights(struct item *item, int x, int y, int maxw) -+{ -+ char restorechar, tokens[sizeof text], *highlight, *token; -+ int indentx, highlightlen; -+ -+ drw_setscheme(drw, scheme[item == sel ? SchemeSelHighlight : SchemeNormHighlight]); -+ strcpy(tokens, text); -+ for (token = strtok(tokens, " "); token; token = strtok(NULL, " ")) { -+ highlight = fstrstr(item->text, token); -+ while (highlight) { -+ // Move item str end, calc width for highlight indent, & restore -+ highlightlen = highlight - item->text; -+ restorechar = *highlight; -+ item->text[highlightlen] = '\0'; -+ indentx = TEXTW(item->text); -+ item->text[highlightlen] = restorechar; -+ -+ // Move highlight str end, draw highlight, & restore -+ restorechar = highlight[strlen(token)]; -+ highlight[strlen(token)] = '\0'; -+ if (indentx - (lrpad / 2) - 1 < maxw) -+ drw_text( -+ drw, -+ x + indentx - (lrpad / 2) - 1, -+ y, -+ MIN(maxw - indentx, TEXTW(highlight) - lrpad), -+ bh, 0, highlight, 0 -+ ); -+ highlight[strlen(token)] = restorechar; -+ -+ if (strlen(highlight) - strlen(token) < strlen(token)) break; -+ highlight = fstrstr(highlight + strlen(token), token); -+ } -+ } -+} -+ - static int - drawitem(struct item *item, int x, int y, int w) - { -@@ -123,7 +160,9 @@ drawitem(struct item *item, int x, int y, int w) - else - drw_setscheme(drw, scheme[SchemeNorm]); - -- return drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0); -+ int r = drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0); -+ drawhighlights(item, x, y, w); -+ return r; - } - - static void --- -2.23.1 - diff --git a/stest b/stest index b48e0712c53b10417b1346683084b9a3c66e57d7..7aff7d8edc94b8bba19a00c358fc4bf241587c52 100755 GIT binary patch delta 458 zcmZ{hze~eV5XbM5+U5yDh2k%e;?%|bD59aQL2$8~I68tcu+rc6K zfwa%TLczhsO;@+BPR6O!$=bXQ4&HM2IqrKuxE9A2NB@l#r(tZx#(RB*>k)A0uh-Ow zExN>cD&YdN6qylSH1S^{mt~xodXefi*Iw2u-=$|>`_!AYSMPqiC+^f6HGX28of;do znmBe5Vvs?AWHbOC8n20(=!$+aby0VuFH;$NHGqD2UmR1|mu zwLzkje$SaKk=yT O*mUG1(Go)^t^5G%_+9+~ delta 439 zcmY+Au}cDB7{=fC&bs@8-~`DMM4f8!PJI^`Ejey7J&_Ii$@R&Z- z=t