sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

commit bbc1efc1c3d9755c66779b05d1883660d725ea07
parent 0c087815ae6dd5b6dc23d8f9971eae65e419fb8a
Author: Philippe Gras <philippe.gras@free.fr>
Date:   Wed,  3 Aug 2016 12:13:32 +0200

Merge remote-tracking branch 'origin/master'

Diffstat:
M.gitignore | 1+
Mcore.suckless.org/index.md | 1+
Mdwm.suckless.org/dwmstatus/index.md | 14++++++++------
Ddwm.suckless.org/dwmstatus/slstatus.tar.gz | 0
Adwm.suckless.org/dwmstatus/volume.c | 100+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdwm.suckless.org/index.md | 35++++++++++++++++++++++++++++-------
Adwm.suckless.org/patches/alpha.md | 24++++++++++++++++++++++++
Mdwm.suckless.org/patches/alwaysfullscreen.md | 14++++++++------
Ddwm.suckless.org/patches/argbcolor.md | 27---------------------------
Mdwm.suckless.org/patches/attachabove.md | 22+++++++++++-----------
Mdwm.suckless.org/patches/attachaside.md | 28+++++++++-------------------
Mdwm.suckless.org/patches/autoresize.md | 21++++++++++++++-------
Ddwm.suckless.org/patches/autostart.md | 15---------------
Ddwm.suckless.org/patches/azertykey.md | 20--------------------
Ddwm.suckless.org/patches/better-borders.md | 25-------------------------
Ddwm.suckless.org/patches/bottom_stack.md | 49-------------------------------------------------
Ddwm.suckless.org/patches/bottommargin.md | 13-------------
Adwm.suckless.org/patches/bottomstack.md | 31+++++++++++++++++++++++++++++++
Mdwm.suckless.org/patches/center.md | 13+++++++------
Ddwm.suckless.org/patches/centeredmaster.c | 91-------------------------------------------------------------------------------
Mdwm.suckless.org/patches/centeredmaster.md | 157++++++++++++++++++++++++++++++++-----------------------------------------------
Mdwm.suckless.org/patches/clientspertag.md | 2+-
Mdwm.suckless.org/patches/columns.md | 25++++++++-----------------
Mdwm.suckless.org/patches/combo.md | 6+++---
Mdwm.suckless.org/patches/current_desktop.md | 2+-
Mdwm.suckless.org/patches/dualstatus.md | 4++--
Ddwm.suckless.org/patches/dwm-10e232f9ace7-float_border_color2.diff | 84-------------------------------------------------------------------------------
Ddwm.suckless.org/patches/dwm-20151110-5ed9c48-keycode.patch | 146-------------------------------------------------------------------------------
Ddwm.suckless.org/patches/dwm-3465bed-argbcolor.diff | 269-------------------------------------------------------------------------------
Ddwm.suckless.org/patches/dwm-6.0-attachabove.diff | 63---------------------------------------------------------------
Ddwm.suckless.org/patches/dwm-6.0-attachaside.diff | 57---------------------------------------------------------
Ddwm.suckless.org/patches/dwm-6.0-autoresize.diff | 35-----------------------------------
Ddwm.suckless.org/patches/dwm-6.0-autostart.diff | 32--------------------------------
Ddwm.suckless.org/patches/dwm-6.0-bottommargin.diff | 26--------------------------
Ddwm.suckless.org/patches/dwm-6.0-bstack.diff | 91-------------------------------------------------------------------------------
Rdwm.suckless.org/patches/dwm-6.1-ispermanent.diff -> dwm.suckless.org/patches/dwm-6.0-ispermanent.diff | 0
Ddwm.suckless.org/patches/dwm-6.0-keycode.diff | 133-------------------------------------------------------------------------------
Mdwm.suckless.org/patches/dwm-6.0-pertag_without_bar.diff | 2+-
Ddwm.suckless.org/patches/dwm-6.0-single_window_no_border.diff | 97-------------------------------------------------------------------------------
Ddwm.suckless.org/patches/dwm-6.1-attachabove.diff | 63---------------------------------------------------------------
Ddwm.suckless.org/patches/dwm-6.1-better-borders.diff | 91-------------------------------------------------------------------------------
Ddwm.suckless.org/patches/dwm-6.1-centeredmaster.diff | 59-----------------------------------------------------------
Mdwm.suckless.org/patches/dwm-6.1-cfacts.diff | 49++++++++++++++++++++++++-------------------------
Ddwm.suckless.org/patches/dwm-6.1-dwmfifo.diff | 215-------------------------------------------------------------------------------
Ddwm.suckless.org/patches/dwm-6.1-htile.diff | 46----------------------------------------------
Ddwm.suckless.org/patches/dwm-6.1-monarg.diff | 30------------------------------
Ddwm.suckless.org/patches/dwm-6.1-single_window_no_border.diff | 99-------------------------------------------------------------------------------
Ddwm.suckless.org/patches/dwm-6.1-swallowing.diff | 377-------------------------------------------------------------------------------
Mdwm.suckless.org/patches/dwm-6.1-systray.diff | 58+++++++++++++++++++++++++++++-----------------------------
Adwm.suckless.org/patches/dwm-alpha-6.1.diff | 253+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rdwm.suckless.org/patches/dwm-argbcolor.png -> dwm.suckless.org/patches/dwm-alpha.png | 0
Adwm.suckless.org/patches/dwm-alwaysfullscreen-20160713-56a31dc.diff | 13+++++++++++++
Adwm.suckless.org/patches/dwm-alwaysfullscreen-6.1.diff | 13+++++++++++++
Adwm.suckless.org/patches/dwm-attachabove-20160713-56a31dc.diff | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-attachabove-6.0.diff | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-attachabove-6.1.diff | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-attachaside-20160718-56a31dc.diff | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-attachaside-6.1.diff | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-autoresize-20160718-56a31dc.diff | 35+++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-autoresize-6.0.diff | 35+++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-autoresize-6.1.diff | 35+++++++++++++++++++++++++++++++++++
Ddwm.suckless.org/patches/dwm-azertykey.diff | 44--------------------------------------------
Adwm.suckless.org/patches/dwm-bottomstack-20160719-56a31dc.diff | 101+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-bottomstack-6.1.diff | 101+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ddwm.suckless.org/patches/dwm-cdec978-alwaysfullscreen.diff | 13-------------
Adwm.suckless.org/patches/dwm-center-20160719-56a31dc.diff | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rdwm.suckless.org/patches/dwm-6.1-center.diff -> dwm.suckless.org/patches/dwm-center-6.1.diff | 0
Adwm.suckless.org/patches/dwm-centeredmaster-20160719-56a31dc.diff | 142+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-centeredmaster-6.1.diff | 142+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rdwm.suckless.org/patches/dwm-5.6.1-cpt.diff -> dwm.suckless.org/patches/dwm-clientspertag-5.6.1.diff | 0
Rdwm.suckless.org/patches/dwm-6.0-column_master.diff -> dwm.suckless.org/patches/dwm-columns-6.0.diff | 0
Rdwm.suckless.org/patches/dwm-5.9-combo.diff -> dwm.suckless.org/patches/dwm-combo-5.9.diff | 0
Rdwm.suckless.org/patches/dwm-6.0-combo.diff -> dwm.suckless.org/patches/dwm-combo-6.0.diff | 0
Rdwm.suckless.org/patches/dwm-6.1-combo.diff -> dwm.suckless.org/patches/dwm-combo-6.1.diff | 0
Rdwm.suckless.org/patches/dwm-5.8.2-current_desktop.diff -> dwm.suckless.org/patches/dwm-current_desktop-5.8.2.diff | 0
Rdwm.suckless.org/patches/dwm-6.0-dualstatus.diff -> dwm.suckless.org/patches/dwm-dualstatus-6.0.diff | 0
Rdwm.suckless.org/patches/dwm-6.1-dualstatus.diff -> dwm.suckless.org/patches/dwm-dualstatus-6.1.diff | 0
Adwm.suckless.org/patches/dwm-dwmfifo-6.1.diff | 217+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rdwm.suckless.org/patches/dwm-6.0-emptyview.diff -> dwm.suckless.org/patches/dwm-emptyview-6.0.diff | 0
Rdwm.suckless.org/patches/dwm-6.1-fancybar.diff -> dwm.suckless.org/patches/dwm-fancybar-6.1.diff | 0
Adwm.suckless.org/patches/dwm-fancybar-git-20160725-7af4d43.diff | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rdwm.suckless.org/patches/dwm-5.8.2-fibonacci.diff -> dwm.suckless.org/patches/dwm-fibonacci-5.8.2.diff | 0
Rdwm.suckless.org/patches/flextile-5.8.2.diff -> dwm.suckless.org/patches/dwm-flextile-5.8.2.diff | 0
Rdwm.suckless.org/patches/dwm-6.0-float_border_color2.diff -> dwm.suckless.org/patches/dwm-float_border_color-6.0.diff | 0
Rdwm.suckless.org/patches/dwm-6.1-float_border_color2.diff -> dwm.suckless.org/patches/dwm-float_border_color-6.1.diff | 0
Adwm.suckless.org/patches/dwm-float_border_color2-20160731-56a31dc.diff | 90+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rdwm.suckless.org/patches/dwm-6.0-focusonclick.diff -> dwm.suckless.org/patches/dwm-focusonclick-6.0.diff | 0
Adwm.suckless.org/patches/dwm-gaplessgrid-20160731-56a31dc.diff | 43+++++++++++++++++++++++++++++++++++++++++++
Rdwm.suckless.org/patches/dwm-6.1-gaplessgrid.diff -> dwm.suckless.org/patches/dwm-gaplessgrid-6.1.diff | 0
Rdwm.suckless.org/patches/dwm-6.0-gaps.diff -> dwm.suckless.org/patches/dwm-gaps-6.0.diff | 0
Rdwm.suckless.org/patches/dwm-5.8.2-gridmode.diff -> dwm.suckless.org/patches/dwm-gridmode-5.8.2.diff | 0
Rdwm.suckless.org/patches/dwm-6.1-hide_vacant_tags.diff -> dwm.suckless.org/patches/dwm-hide_vacant_tags-6.1.diff | 0
Adwm.suckless.org/patches/dwm-hide_vacant_tags-git-20160626-7af4d43.diff | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Rdwm.suckless.org/patches/dwm-6.1-horizgrid.diff -> dwm.suckless.org/patches/dwm-horizgrid-6.1.diff | 0
Adwm.suckless.org/patches/dwm-keycode-20160702-56a31dc.diff | 133+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-keycode-6.1.diff | 133+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rdwm.suckless.org/patches/dwm-6.0-keypressrelease.diff -> dwm.suckless.org/patches/dwm-keypressrelease-6.0.diff | 0
Rdwm.suckless.org/patches/dwm-6.1-mark.diff -> dwm.suckless.org/patches/dwm-mark-6.1.diff | 0
Rdwm.suckless.org/patches/dwm-6.1-mark-new.diff -> dwm.suckless.org/patches/dwm-mark-new-6.1.diff | 0
Adwm.suckless.org/patches/dwm-maximize_vert_horz-20160731-56a31dc.diff | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rdwm.suckless.org/patches/dwm-6.0-maximize_vert_horz.diff -> dwm.suckless.org/patches/dwm-maximize_vert_horz-6.0.diff | 0
Rdwm.suckless.org/patches/dwm-6.1-maximize_vert_horz.diff -> dwm.suckless.org/patches/dwm-maximize_vert_horz-6.1.diff | 0
Rdwm.suckless.org/patches/dwm-5.8.2-monocle_count.diff -> dwm.suckless.org/patches/dwm-monocle_count-5.8.2.diff | 0
Adwm.suckless.org/patches/dwm-moveresize-20160731-56a31dc.diff | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rdwm.suckless.org/patches/dwm-6.0-moveresize.diff -> dwm.suckless.org/patches/dwm-moveresize-6.0.diff | 0
Rdwm.suckless.org/patches/dwm-6.1-moveresize.diff -> dwm.suckless.org/patches/dwm-moveresize-6.1.diff | 0
Adwm.suckless.org/patches/dwm-movestack-6.1.diff | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rdwm.suckless.org/patches/dwm-5.7.2-nametag.diff -> dwm.suckless.org/patches/dwm-nametag-5.7.2.diff | 0
Rdwm.suckless.org/patches/dwm-6.1-nametag.diff -> dwm.suckless.org/patches/dwm-nametag-6.1.diff | 0
Rdwm.suckless.org/patches/dwm-6.1-nametag-prepend.diff -> dwm.suckless.org/patches/dwm-nametag-prepend-6.1.diff | 0
Adwm.suckless.org/patches/dwm-noborder-20160718-56a31dc.diff | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-noborder-6.1.diff | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ddwm.suckless.org/patches/dwm-nofullscreen.diff | 11-----------
Rdwm.suckless.org/patches/dwm-6.0-pango.diff -> dwm.suckless.org/patches/dwm-pango-6.0.diff | 0
Adwm.suckless.org/patches/dwm-pertag-20160626-7af4d43.diff | 199+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-pertag-20160731-56a31dc.diff | 205+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rdwm.suckless.org/patches/dwm-6.0-pertag.diff -> dwm.suckless.org/patches/dwm-pertag-6.0.diff | 0
Rdwm.suckless.org/patches/dwm-6.1-pertag.diff -> dwm.suckless.org/patches/dwm-pertag-6.1.diff | 0
Adwm.suckless.org/patches/dwm-push-20160731-56a31dc.diff | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rdwm.suckless.org/patches/dwm-6.0-push.diff -> dwm.suckless.org/patches/dwm-push-6.0.diff | 0
Rdwm.suckless.org/patches/dwm-6.1-push.diff -> dwm.suckless.org/patches/dwm-push-6.1.diff | 0
Rdwm.suckless.org/patches/dwm-5.9-pwkl.diff -> dwm.suckless.org/patches/dwm-pwkl-5.9.diff | 0
Ddwm.suckless.org/patches/dwm-r1580-col.diff | 60------------------------------------------------------------
Rdwm.suckless.org/patches/dwm-6.0-resizecorners.diff -> dwm.suckless.org/patches/dwm-resizecorners-6.0.diff | 0
Rdwm.suckless.org/patches/dwm-6.1-resizecorners.diff -> dwm.suckless.org/patches/dwm-resizecorners-6.1.diff | 0
Rdwm.suckless.org/patches/dwm-6.0-save_floats.diff -> dwm.suckless.org/patches/dwm-save_floats-6.0.diff | 0
Adwm.suckless.org/patches/dwm-savefloats-20160723-56a31dc.diff | 46++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-single_tagset-20160731-56a31dc.diff | 540+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rdwm.suckless.org/patches/dwm-6.0-single_tagset.diff -> dwm.suckless.org/patches/dwm-single_tagset-6.0.diff | 0
Rdwm.suckless.org/patches/dwm-5.7.2-sizehints.diff -> dwm.suckless.org/patches/dwm-sizehints-5.7.2.diff | 0
Rdwm.suckless.org/patches/dwm-6.0-stacker.diff -> dwm.suckless.org/patches/dwm-stacker-6.0.diff | 0
Adwm.suckless.org/patches/dwm-statusallmons-20160731-56a31dc.diff | 29+++++++++++++++++++++++++++++
Rdwm.suckless.org/patches/dwm-5.8.2-statusallmons.diff -> dwm.suckless.org/patches/dwm-statusallmons-5.8.2.diff | 0
Rdwm.suckless.org/patches/dwm-6.0-statusallmons.diff -> dwm.suckless.org/patches/dwm-statusallmons-6.0.diff | 0
Rdwm.suckless.org/patches/dwm-5.9-statuscolors.diff -> dwm.suckless.org/patches/dwm-statuscolors-5.9.diff | 0
Rdwm.suckless.org/patches/dwm-6.1-statuscolors.diff -> dwm.suckless.org/patches/dwm-statuscolors-6.1.diff | 0
Adwm.suckless.org/patches/dwm-swallow-20160717-56a31dc.diff | 380+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-swallow-6.1.diff | 382+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-swapfocus-20160731-56a31dc.diff | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rdwm.suckless.org/patches/dwm-6.0-swapfocus.diff -> dwm.suckless.org/patches/dwm-swapfocus-6.0.diff | 0
Adwm.suckless.org/patches/dwm-switchcol-6.1.diff | 47+++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-systray-20160731-56a31dc.diff | 725+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rdwm.suckless.org/patches/dwm-6.0-systray.diff -> dwm.suckless.org/patches/dwm-systray-6.0.diff | 0
Adwm.suckless.org/patches/dwm-systray-git-20160626-7af4d43.diff | 685+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-tagall-20160731-56a31dc.diff | 33+++++++++++++++++++++++++++++++++
Rdwm.suckless.org/patches/dwm-6.0-tagall.diff -> dwm.suckless.org/patches/dwm-tagall-6.0.diff | 0
Rdwm.suckless.org/patches/dwm-6.1-tagall.diff -> dwm.suckless.org/patches/dwm-tagall-6.1.diff | 0
Rdwm.suckless.org/patches/dwm-6.0-tilegap.diff -> dwm.suckless.org/patches/dwm-tilegap-6.0.diff | 0
Rdwm.suckless.org/patches/dwm-5.9-uselessgap.diff -> dwm.suckless.org/patches/dwm-uselessgap-5.9.diff | 0
Rdwm.suckless.org/patches/dwm-6.1-uselessgap.diff -> dwm.suckless.org/patches/dwm-uselessgap-6.1.diff | 0
Rdwm.suckless.org/patches/dwm-5.9-warp.diff -> dwm.suckless.org/patches/dwm-warp-5.9.diff | 0
Rdwm.suckless.org/patches/dwm-6.1-warp.diff -> dwm.suckless.org/patches/dwm-warp-6.1.diff | 0
Adwm.suckless.org/patches/dwm-warp-git-20160626-7af4d43.diff | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-zoomswap-20160731-56a31dc.diff | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rdwm.suckless.org/patches/dwm-6.0-zoomswap.diff -> dwm.suckless.org/patches/dwm-zoomswap-6.0.diff | 0
Mdwm.suckless.org/patches/dwmfifo.md | 2+-
Mdwm.suckless.org/patches/emptyview.md | 2+-
Mdwm.suckless.org/patches/exresize.md | 6++++--
Mdwm.suckless.org/patches/fancybar.md | 7++++---
Mdwm.suckless.org/patches/fancybarclickable.md | 2+-
Mdwm.suckless.org/patches/fibonacci.md | 2+-
Mdwm.suckless.org/patches/flextile.md | 14++++++++++----
Mdwm.suckless.org/patches/float_border_color.md | 7++++---
Mdwm.suckless.org/patches/focusadjacenttag.md | 6+++---
Mdwm.suckless.org/patches/focusonclick.md | 3+--
Mdwm.suckless.org/patches/gapless_grid.md | 3++-
Mdwm.suckless.org/patches/gaps.md | 2+-
Mdwm.suckless.org/patches/gestures.md | 5+++--
Mdwm.suckless.org/patches/gridmode.md | 2+-
Mdwm.suckless.org/patches/hide_vacant_tags.md | 4+++-
Rdwm.suckless.org/patches/ansistatuscolors.md -> dwm.suckless.org/patches/historical/ansistatuscolors.md | 0
Rdwm.suckless.org/patches/ansistatuscolors.png -> dwm.suckless.org/patches/historical/ansistatuscolors.png | 0
Rdwm.suckless.org/patches/autoresize.diff -> dwm.suckless.org/patches/historical/autoresize.diff | 0
Ddwm.suckless.org/patches/historical/dwm-5.6.1-attachabove.diff | 40----------------------------------------
Ddwm.suckless.org/patches/historical/dwm-5.6.1-attachaside.diff | 38--------------------------------------
Ddwm.suckless.org/patches/historical/dwm-5.7.2-attachaside.diff | 38--------------------------------------
Ddwm.suckless.org/patches/historical/dwm-5.8.2-bstack-alt.diff | 93-------------------------------------------------------------------------------
Ddwm.suckless.org/patches/historical/dwm-5.8.2-bstack.diff | 82-------------------------------------------------------------------------------
Ddwm.suckless.org/patches/historical/dwm-5.9-bstack-alt.diff | 98-------------------------------------------------------------------------------
Ddwm.suckless.org/patches/historical/dwm-5.9-bstack.diff | 87-------------------------------------------------------------------------------
Ddwm.suckless.org/patches/historical/dwm-cdec978-center.diff | 58----------------------------------------------------------
Rdwm.suckless.org/patches/historical/fancybar-5.6.1.diff -> dwm.suckless.org/patches/historical/dwm-fancybar-5.6.1.diff | 0
Rdwm.suckless.org/patches/historical/flextile-5.8.1.diff -> dwm.suckless.org/patches/historical/dwm-flextile-5.8.1.diff | 0
Rdwm.suckless.org/patches/movestack-5.8.2.diff -> dwm.suckless.org/patches/historical/dwm-movestack-5.8.2.diff | 0
Adwm.suckless.org/patches/historical/dwm-pertag-5.1.diff | 125+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rdwm.suckless.org/patches/historical/dwm-5.2-pertag.diff -> dwm.suckless.org/patches/historical/dwm-pertag-5.2.diff | 0
Rdwm.suckless.org/patches/historical/dwm-5.4-pertag.diff -> dwm.suckless.org/patches/historical/dwm-pertag-5.4.diff | 0
Rdwm.suckless.org/patches/historical/dwm-5.7.2-pertag.diff -> dwm.suckless.org/patches/historical/dwm-pertag-5.7.2.diff | 0
Rdwm.suckless.org/patches/historical/dwm-5.8.2-pertag.diff -> dwm.suckless.org/patches/historical/dwm-pertag-5.8.2.diff | 0
Rdwm.suckless.org/patches/multimon-1-added-monitor-marker-to-bar.diff -> dwm.suckless.org/patches/historical/multimon-1-added-monitor-marker-to-bar.diff | 0
Rdwm.suckless.org/patches/multimon-2-added-n-view-wrappers-for-unified-multi-monitor.diff -> dwm.suckless.org/patches/historical/multimon-2-added-n-view-wrappers-for-unified-multi-monitor.diff | 0
Rdwm.suckless.org/patches/multimon-3-added-reset_view-function.diff -> dwm.suckless.org/patches/historical/multimon-3-added-reset_view-function.diff | 0
Rdwm.suckless.org/patches/multimon-4-added-statusall-toggle-replacing-need-for-patch.diff -> dwm.suckless.org/patches/historical/multimon-4-added-statusall-toggle-replacing-need-for-patch.diff | 0
Rdwm.suckless.org/patches/multimon.md -> dwm.suckless.org/patches/historical/multimon.md | 0
Mdwm.suckless.org/patches/horizgrid.md | 2+-
Mdwm.suckless.org/patches/index.md | 63+++------------------------------------------------------------
Mdwm.suckless.org/patches/ispermanent.md | 2+-
Mdwm.suckless.org/patches/keycode.md | 4++--
Mdwm.suckless.org/patches/keypressrelease.md | 4++--
Mdwm.suckless.org/patches/mark.md | 8++++----
Mdwm.suckless.org/patches/maximize.md | 5+++--
Ddwm.suckless.org/patches/monarg.md | 18------------------
Mdwm.suckless.org/patches/monocle_count.md | 2+-
Mdwm.suckless.org/patches/moveresize.md | 7+++----
Mdwm.suckless.org/patches/movestack.md | 6++----
Mdwm.suckless.org/patches/nametag.md | 6+++---
Mdwm.suckless.org/patches/noborder.md | 19++++++++-----------
Ddwm.suckless.org/patches/nofullscreen.m4 | 19-------------------
Mdwm.suckless.org/patches/pango.md | 2+-
Mdwm.suckless.org/patches/pertag.md | 27+++++++++++++++------------
Mdwm.suckless.org/patches/push.md | 5+++--
Mdwm.suckless.org/patches/pwkl.md | 2+-
Mdwm.suckless.org/patches/resizecorners.md | 4++--
Mdwm.suckless.org/patches/save_floats.md | 4+++-
Mdwm.suckless.org/patches/single_tagset.md | 4+++-
Mdwm.suckless.org/patches/sizehints.md | 2+-
Mdwm.suckless.org/patches/stacker.md | 2+-
Mdwm.suckless.org/patches/statusallmons.md | 5+++--
Mdwm.suckless.org/patches/statuscolors.md | 4++--
Mdwm.suckless.org/patches/swallow.md | 61+++++++++++++++++++++++++++++++++++++++----------------------
Mdwm.suckless.org/patches/swapfocus.md | 3++-
Adwm.suckless.org/patches/switchcol.md | 20++++++++++++++++++++
Mdwm.suckless.org/patches/systray.md | 5++++-
Mdwm.suckless.org/patches/tagall.md | 5+++--
Mdwm.suckless.org/patches/tilegap.md | 2+-
Mdwm.suckless.org/patches/uselessgap.md | 4++--
Mdwm.suckless.org/patches/warp.md | 7++++---
Mdwm.suckless.org/patches/zoomswap.md | 3++-
Adwm.suckless.org/scripts/basic_collection.md | 9+++++++++
Mlibs.suckless.org/_werc/config | 2+-
Alibs.suckless.org/deprecated/index.md | 1+
Alibs.suckless.org/deprecated/libixp.md | 18++++++++++++++++++
Alibs.suckless.org/deprecated/r9p.md | 12++++++++++++
Dlibs.suckless.org/libixp.md | 19-------------------
Alibs.suckless.org/libzahl-paper-1.pdf | 0
Alibs.suckless.org/libzahl-refman.pdf | 0
Alibs.suckless.org/libzahl-refsheet.pdf | 0
Alibs.suckless.org/libzahl.md | 34++++++++++++++++++++++++++++++++++
Dlibs.suckless.org/r9p.md | 13-------------
Dst.suckless.org/faq.md | 5-----
Mst.suckless.org/index.md | 71++++++++++++++++++++++++++++++++---------------------------------------
Ast.suckless.org/patches/alpha.md | 33+++++++++++++++++++++++++++++++++
Dst.suckless.org/patches/argbbg.md | 26--------------------------
Dst.suckless.org/patches/boldcolor.md | 47-----------------------------------------------
Mst.suckless.org/patches/clipboard.md | 20++++++++++++--------
Mst.suckless.org/patches/copyurl.md | 9++++-----
Mst.suckless.org/patches/delkey.md | 8++++----
Mst.suckless.org/patches/externalpipe.md | 12++++++------
Mst.suckless.org/patches/hidecursor.md | 14+++++++-------
Mst.suckless.org/patches/index.md | 7++++---
Mst.suckless.org/patches/openbsd.md | 6+++---
Mst.suckless.org/patches/scrollback.md | 18+++++++++---------
Mst.suckless.org/patches/solarized.md | 28+++++++++++++++++-----------
Mst.suckless.org/patches/spoiler.md | 7++++---
Dst.suckless.org/patches/st-0.3-boldcolor.diff | 52----------------------------------------------------
Dst.suckless.org/patches/st-0.3-wordbreak.diff | 58----------------------------------------------------------
Dst.suckless.org/patches/st-0.4-wordbreak.diff | 58----------------------------------------------------------
Dst.suckless.org/patches/st-0.4.1-externalpipe.diff | 109-------------------------------------------------------------------------------
Dst.suckless.org/patches/st-0.4.1-wordbreak.diff | 57---------------------------------------------------------
Dst.suckless.org/patches/st-0.5-argbbg.diff | 169-------------------------------------------------------------------------------
Dst.suckless.org/patches/st-0.5-externalpipe.diff | 109-------------------------------------------------------------------------------
Dst.suckless.org/patches/st-0.5-hidecursor.diff | 82-------------------------------------------------------------------------------
Dst.suckless.org/patches/st-0.5-no-bold-colors.diff | 13-------------
Dst.suckless.org/patches/st-0.5-solarized-dark.diff | 65-----------------------------------------------------------------
Dst.suckless.org/patches/st-0.5-solarized-light.diff | 65-----------------------------------------------------------------
Dst.suckless.org/patches/st-0.5-wordbreak.diff | 52----------------------------------------------------
Dst.suckless.org/patches/st-0.6-argbbg.diff | 170-------------------------------------------------------------------------------
Dst.suckless.org/patches/st-0.6-clipboard.diff | 13-------------
Dst.suckless.org/patches/st-0.6-copyurl.diff | 88-------------------------------------------------------------------------------
Dst.suckless.org/patches/st-0.6-delkey.diff | 45---------------------------------------------
Dst.suckless.org/patches/st-0.6-externalpipe.diff | 75---------------------------------------------------------------------------
Dst.suckless.org/patches/st-0.6-hidecursor.diff | 84-------------------------------------------------------------------------------
Dst.suckless.org/patches/st-0.6-no-bold-colors.diff | 13-------------
Dst.suckless.org/patches/st-0.6-solarized-dark.diff | 65-----------------------------------------------------------------
Dst.suckless.org/patches/st-0.6-solarized-light.diff | 65-----------------------------------------------------------------
Dst.suckless.org/patches/st-0.6-spoiler.diff | 22----------------------
Rst.suckless.org/patches/st-0.4.1-argbbg.diff -> st.suckless.org/patches/st-alpha-0.4.1.diff | 0
Ast.suckless.org/patches/st-alpha-0.5.diff | 169+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ast.suckless.org/patches/st-alpha-0.6.diff | 170+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ast.suckless.org/patches/st-alpha-20160727-308bfbf.diff | 188+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ast.suckless.org/patches/st-alpha-s.png | 0
Ast.suckless.org/patches/st-alpha.png | 0
Dst.suckless.org/patches/st-argbbg-s.png | 0
Dst.suckless.org/patches/st-argbbg.png | 0
Ast.suckless.org/patches/st-clipboard-0.6.diff | 13+++++++++++++
Ast.suckless.org/patches/st-clipboard-20160727-308bfbf.diff | 13+++++++++++++
Ast.suckless.org/patches/st-copyurl-0.6.diff | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ast.suckless.org/patches/st-copyurl-20160727-308bfbf.diff | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ast.suckless.org/patches/st-delkey-0.6.diff | 45+++++++++++++++++++++++++++++++++++++++++++++
Ast.suckless.org/patches/st-delkey-20160727-308bfbf.diff | 45+++++++++++++++++++++++++++++++++++++++++++++
Ast.suckless.org/patches/st-externalpipe-0.4.1.diff | 109+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ast.suckless.org/patches/st-externalpipe-0.5.diff | 109+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ast.suckless.org/patches/st-externalpipe-0.6.diff | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ast.suckless.org/patches/st-externalpipe-20160727-308bfbf.diff | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dst.suckless.org/patches/st-git-20150917-clipboard.diff | 13-------------
Dst.suckless.org/patches/st-git-20150917-delkey.diff | 45---------------------------------------------
Dst.suckless.org/patches/st-git-20150917-hidecursor.diff | 88-------------------------------------------------------------------------------
Dst.suckless.org/patches/st-git-20150917-no-bold-colors.diff | 13-------------
Dst.suckless.org/patches/st-git-20150917-solarized-dark.diff | 65-----------------------------------------------------------------
Dst.suckless.org/patches/st-git-20150917-solarized-light.diff | 65-----------------------------------------------------------------
Dst.suckless.org/patches/st-git-20150920-openbsd.diff | 27---------------------------
Dst.suckless.org/patches/st-git-20150922-spoiler.diff | 22----------------------
Dst.suckless.org/patches/st-git-20151106-scrollback-mouse.diff | 62--------------------------------------------------------------
Dst.suckless.org/patches/st-git-20151119-solarized-dark.diff | 68--------------------------------------------------------------------
Dst.suckless.org/patches/st-git-20151119-solarized-light.diff | 68--------------------------------------------------------------------
Dst.suckless.org/patches/st-git-20151217-scrollback.diff | 388-------------------------------------------------------------------------------
Dst.suckless.org/patches/st-git-20160131-argbbg.diff | 161-------------------------------------------------------------------------------
Dst.suckless.org/patches/st-git-20160203-scrollback-mouse-altscreen.diff | 40----------------------------------------
Dst.suckless.org/patches/st-git-20160204-externalpipe.diff | 75---------------------------------------------------------------------------
Dst.suckless.org/patches/st-git-20160209-visualbell.diff | 42------------------------------------------
Dst.suckless.org/patches/st-git-20160210-copyurl.diff | 88-------------------------------------------------------------------------------
Ast.suckless.org/patches/st-hidecursor-0.5.diff | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ast.suckless.org/patches/st-hidecursor-0.6.diff | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ast.suckless.org/patches/st-hidecursor-20160727-308bfbf.diff | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ast.suckless.org/patches/st-no_bold_colors-0.5.diff | 13+++++++++++++
Ast.suckless.org/patches/st-no_bold_colors-0.6.diff | 13+++++++++++++
Ast.suckless.org/patches/st-no_bold_colors-20160727-308bfbf.diff | 13+++++++++++++
Ast.suckless.org/patches/st-openbsd-20160727-308bfbf.diff | 27+++++++++++++++++++++++++++
Ast.suckless.org/patches/st-scrollback-20160727-308bfbf.diff | 387+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ast.suckless.org/patches/st-scrollback-mouse-20160727-308bfbf.diff | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ast.suckless.org/patches/st-scrollback-mouse-altscreen-20160727-308bfbf.diff | 25+++++++++++++++++++++++++
Ast.suckless.org/patches/st-solarized-both-20160727-308bfbf.diff | 189+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ast.suckless.org/patches/st-solarized-dark-0.5.diff | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ast.suckless.org/patches/st-solarized-dark-0.6.diff | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ast.suckless.org/patches/st-solarized-dark-20160727-308bfbf.diff | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ast.suckless.org/patches/st-solarized-light-0.5.diff | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ast.suckless.org/patches/st-solarized-light-0.6.diff | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ast.suckless.org/patches/st-solarized-light-20160727-308bfbf.diff | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ast.suckless.org/patches/st-spoiler-0.6.diff | 22++++++++++++++++++++++
Ast.suckless.org/patches/st-spoiler-20160727-308bfbf.diff | 22++++++++++++++++++++++
Ast.suckless.org/patches/st-visualbell-20160727-308bfbf.diff | 42++++++++++++++++++++++++++++++++++++++++++
Mst.suckless.org/patches/visualbell.md | 5+++--
Dst.suckless.org/patches/wordbreak.md | 29-----------------------------
Ast.suckless.org/screenshots/frign-2016-s.png | 0
Ast.suckless.org/screenshots/frign-2016.png | 0
Mst.suckless.org/screenshots/index.md | 2++
Msuckless.org/coding_style.md | 2+-
Msuckless.org/conference/2015.md | 15+++++++++++++++
Msuckless.org/conference/index.md | 29++++++++++++++++++++++++++++-
Msuckless.org/donations.md | 10+++++++++-
Msuckless.org/hacking.md | 44++++++++++++++++++++++++++++++++++++++------
Msuckless.org/index.md | 14+++++++++++---
Msuckless.org/other_projects.md | 3+++
Msuckless.org/people/maandree.md | 11+++++++----
Dsuckless.org/people/more_people.md | 74--------------------------------------------------------------------------
Asuckless.org/people/quinq.md | 11+++++++++++
Asuckless.org/people/~ more_people.md | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msuckless.org/philosophy.md | 1+
Msuckless.org/project_ideas.md | 3+++
Msuckless.org/rocks.md | 6++++++
Msuckless.org/sucks/index.md | 20+++++++++++---------
Msuckless.org/sucks/systemd.md | 4++++
Msurf.suckless.org/files/bmarks.md | 2+-
Msurf.suckless.org/files/bmarks_history.md | 2+-
Dsurf.suckless.org/files/skip_streaming_limits.md | 35-----------------------------------
Asurf.suckless.org/files/surfraw_as_searchengine.md | 28++++++++++++++++++++++++++++
Msurf.suckless.org/index.md | 5+++++
Msurf.suckless.org/patches/index.md | 31+++----------------------------
Dtools.suckless.org/dmenu/patches/dmenu-4.1.1-xmms.diff | 130-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-4.2.1-tok.diff | 101-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-4.4-follow-focus.diff | 21---------------------
Dtools.suckless.org/dmenu/patches/dmenu-4.4-tok.diff | 103-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-4.4.1-multisel.diff | 60------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-4.4.1-xft.diff | 405-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-4.5-fuzzymatch.diff | 135-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-4.5-hide-single-newline.diff | 12------------
Dtools.suckless.org/dmenu/patches/dmenu-4.5-monarg.diff | 101-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-4.5-mouse-support.diff | 142-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-4.5-xft-debian.diff | 418-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-4.5-xft-improved.diff | 425-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-4.5-xft.diff | 418-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-4.6-line-height.diff | 99-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-4.6-mouse-support-msel.diff | 154-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-4.6-vertfull.diff | 20--------------------
Dtools.suckless.org/dmenu/patches/dmenu-4.6-xyw.diff | 87-------------------------------------------------------------------------------
Atools.suckless.org/dmenu/patches/dmenu-fuzzymatch-4.6.diff | 145+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dtools.suckless.org/dmenu/patches/dmenu-git-20151020-fuzzymatch.diff | 135-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-git-20160111-hide-single-newline.diff | 12------------
Dtools.suckless.org/dmenu/patches/dmenu-git-xft.diff | 450-------------------------------------------------------------------------------
Atools.suckless.org/dmenu/patches/dmenu-incremental-20160702-3c91eed.diff | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atools.suckless.org/dmenu/patches/dmenu-instant-20160702-3c91eed.diff | 72++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atools.suckless.org/dmenu/patches/dmenu-instant-4.6.diff | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dtools.suckless.org/dmenu/patches/dmenu-instant.diff | 38--------------------------------------
Atools.suckless.org/dmenu/patches/dmenu-lineheight-4.6.diff | 99+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atools.suckless.org/dmenu/patches/dmenu-mousesupport-20160702-3c91eed.diff | 156+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atools.suckless.org/dmenu/patches/dmenu-mousesupport-4.6.diff | 156+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dtools.suckless.org/dmenu/patches/dmenu-ms_nl.diff | 79-------------------------------------------------------------------------------
Atools.suckless.org/dmenu/patches/dmenu-navhistory-4.6.diff | 173+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atools.suckless.org/dmenu/patches/dmenu-nonblockingstdin-20160702-3c91eed.diff | 248+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atools.suckless.org/dmenu/patches/dmenu-pipeout-20160701-3c91eed.diff | 44++++++++++++++++++++++++++++++++++++++++++++
Dtools.suckless.org/dmenu/patches/dmenu-tip-history.diff | 149-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-tip-incremental.diff | 62--------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-tip-non-blocking-stdin.diff | 110-------------------------------------------------------------------------------
Atools.suckless.org/dmenu/patches/dmenu-vertfull-4.6.diff | 20++++++++++++++++++++
Atools.suckless.org/dmenu/patches/dmenu-xyw-4.6.diff | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dtools.suckless.org/dmenu/patches/dmenu_xmms.diff | 133-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/follow-focus.md | 12------------
Mtools.suckless.org/dmenu/patches/fuzzymatch.md | 5++---
Dtools.suckless.org/dmenu/patches/hide-single-newline.md | 19-------------------
Dtools.suckless.org/dmenu/patches/history.md | 32--------------------------------
Mtools.suckless.org/dmenu/patches/incremental.md | 2+-
Mtools.suckless.org/dmenu/patches/index.md | 30+++---------------------------
Mtools.suckless.org/dmenu/patches/instant.md | 3++-
Dtools.suckless.org/dmenu/patches/legacy/allow-kp_decimal-in-dmenu.patch | 12------------
Dtools.suckless.org/dmenu/patches/legacy/dmenu-4.0-paste.diff | 27---------------------------
Dtools.suckless.org/dmenu/patches/legacy/dmenu-4.0-vertical_meillo.diff | 221-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/legacy/dmenu_path-cls.c | 100-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/legacy/dmenu_path.c | 376-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/legacy/dmenu_path.md | 11-----------
Dtools.suckless.org/dmenu/patches/legacy/index.md | 4----
Dtools.suckless.org/dmenu/patches/legacy/kp_decimal.md | 14--------------
Dtools.suckless.org/dmenu/patches/legacy/paste.md | 23-----------------------
Dtools.suckless.org/dmenu/patches/legacy/vertical.md | 14--------------
Mtools.suckless.org/dmenu/patches/line-height.md | 4+---
Dtools.suckless.org/dmenu/patches/monarg.md | 17-----------------
Dtools.suckless.org/dmenu/patches/mouse-support-msel.md | 19-------------------
Mtools.suckless.org/dmenu/patches/mouse-support.md | 7+++++--
Dtools.suckless.org/dmenu/patches/multisel.md | 12------------
Dtools.suckless.org/dmenu/patches/multiselect_and_newline.md | 19-------------------
Atools.suckless.org/dmenu/patches/navhistory.md | 19+++++++++++++++++++
Mtools.suckless.org/dmenu/patches/non_blocking_stdin.md | 6++----
Atools.suckless.org/dmenu/patches/pipeout.md | 22++++++++++++++++++++++
Mtools.suckless.org/dmenu/patches/vertfull.md | 2+-
Dtools.suckless.org/dmenu/patches/xft.md | 29-----------------------------
Dtools.suckless.org/dmenu/patches/xmms-like_pattern_matching.md | 34----------------------------------
Dtools.suckless.org/dmenu/patches/xrdb.diff | 85-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/xrdb.md | 16----------------
Mtools.suckless.org/dmenu/patches/xyw.md | 2+-
Mtools.suckless.org/farbfeld/farbfeld.svg | 2+-
Mtools.suckless.org/farbfeld/index.md | 9++++++---
Mtools.suckless.org/farbfeld/invert.c | 55+++++++++++++++++++++++++++++--------------------------
Atools.suckless.org/ii/patches/ii-1.7-ucspi.diff | 165+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtools.suckless.org/ii/patches/index.md | 30+++---------------------------
Mtools.suckless.org/ii/patches/ssl.md | 2+-
Atools.suckless.org/ii/patches/ucspi.md | 20++++++++++++++++++++
Mtools.suckless.org/sent/index.md | 39+++++++++++++++++++--------------------
Mtools.suckless.org/sent/patches/index.md | 30+++---------------------------
Mtools.suckless.org/sic/patches/index.md | 30+++---------------------------
Mtools.suckless.org/slock/index.md | 8++++++++
Atools.suckless.org/slock/patches/control-clear.md | 20++++++++++++++++++++
Atools.suckless.org/slock/patches/index.md | 5+++++
Atools.suckless.org/slock/patches/pam_auth.md | 20++++++++++++++++++++
Atools.suckless.org/slock/patches/quickcancel.md | 28++++++++++++++++++++++++++++
Atools.suckless.org/slock/patches/slock-git-20160406-control-clear.diff | 26++++++++++++++++++++++++++
Atools.suckless.org/slock/patches/slock-pam_auth.diff | 137+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atools.suckless.org/slock/patches/slock-quickcancel-20160619-65b8d52.diff | 47+++++++++++++++++++++++++++++++++++++++++++++++
Atools.suckless.org/slock/patches/slock-terminalkeys-20160618-65b8d52.diff | 27+++++++++++++++++++++++++++
Atools.suckless.org/slock/patches/terminalkeys.md | 29+++++++++++++++++++++++++++++
Mtools.suckless.org/tabbed/patches/clientnumber.md | 4++--
Mtools.suckless.org/tabbed/patches/index.md | 31+++----------------------------
Mtools.suckless.org/tabbed/patches/keycode.md | 4++--
Dtools.suckless.org/tabbed/patches/tabbed-0.6-keycode.diff | 113-------------------------------------------------------------------------------
Atools.suckless.org/tabbed/patches/tabbed-clientnumber-0.6.diff | 23+++++++++++++++++++++++
Dtools.suckless.org/tabbed/patches/tabbed-clientnumber-20160103-eb0ff62.patch | 23-----------------------
Atools.suckless.org/tabbed/patches/tabbed-clientnumber-20160702-bc23614.diff | 23+++++++++++++++++++++++
Atools.suckless.org/tabbed/patches/tabbed-keycode-0.6.diff | 113+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dtools.suckless.org/tabbed/patches/tabbed-keycode-20160103-eb0ff62.patch | 110-------------------------------------------------------------------------------
Atools.suckless.org/tabbed/patches/tabbed-keycode-20160702-bc23614.diff | 110+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
458 files changed, 12055 insertions(+), 12179 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,2 +1,3 @@ # these files are ignored by git *.html +test diff --git a/core.suckless.org/index.md b/core.suckless.org/index.md @@ -7,3 +7,4 @@ Useful external components -------------------------- * [mksh](https://www.mirbsd.org/mksh.htm) * [musl libc](http://www.musl-libc.org/) +* [one true awk](http://www.cs.princeton.edu/~bwk/btl.mirror/) diff --git a/dwm.suckless.org/dwmstatus/index.md b/dwm.suckless.org/dwmstatus/index.md @@ -17,16 +17,17 @@ This is a barebone project you can use for changing it to your needs. User submitted versions ----------------------- -Please add your own version of dwmstatus here. +Please add your own version of dwmstatus here (keeping the list sorted). -* [dwm-bar.c](https://github.com/wifiextender/dwm-bar) - Display overall usage about: cpu and cpu temperature, ram, disk, installed packages, kernel, motherboard voltage, system fans and their speed in RPM, motherboard (name, vendor, temperature), volume and time. I've wrote the code myself, so it is unique. +* [barM](barM.c) - can display all, time/date, ram usage, output of commands (the New BarMonitor). +* [dstat](https://www.umaxx.net/dl) [Screenshot](https://www.umaxx.net/dstat.png) - displays the current network throughput, CPU usage, performance settings, battery status, temperature, volume settings, as well as the current date and time (OpenBSD only, no support for Linux). +* [pinky-bar](https://github.com/wifiextender/pinky-bar) - Display overall usage about: cpu (vendor, stepping, family, temperature) and maximum clock speed regardless of the used cpu frequency governor, ram, disk, installed packages, kernel, voltage, system fans and their speed in RPM, motherboard (name, vendor, temperature), volume, time, the name of currently played song, consumed internet bandwidth, upload and download speeds, disk I/O. * [dwmsd](https://github.com/johnko/dwmsd) - a daemon that listens on localhost tcp (may be useful as a base for asynchronous updates) +* [go-dwmstatus](https://github.com/oniichaNj/go-dwmstatus) - A Go bar that prints current MPD song, load averages, time/date and battery percentage. +* [gods](https://github.com/schachmat/gods) - implemented in Go. prints network speed, cpu, ram, date/time * [profil-dwmstatus-1.0.c](profil-dwmstatus-1.0.c) - cpufreq, battery percent and date/time +* **slstatus** - suckless alternative to Bash scripts (inefficient) and Conky (bloated for this use) - it displays various system information and can be customized via config.h - [cgit](https://git.nulltime.net/slstatus), [GitHub](https://github.com/drkh5h/slstatus) * [suspend-statusbar.c](https://github.com/akozadaev/dwm-statusbar) - loadavg, wifi, battery and date. If battery goes below threshold - run suspend command -* [gods](https://github.com/schachmat/gods) - implemented in Go. prints network speed, cpu, ram, date/time -* [go-dwmstatus](https://github.com/oniichaNj/go-dwmstatus) - A Go bar that prints current MPD song, load averages, time/date and battery percentage. -* [barM](barM.c) - can display all, time/date, ram usage, output of commands (the New BarMonitor). -* slstatus - suckless statusbar - written in pure c without any system() - includes wifi percentage, battery, cpu usage and temperature, ram usage, alsa volume and time / date - [GitHub](https://github.com/drkh5h/slstatus), [Download](slstatus.tar.gz) Helper functions ---------------- @@ -34,6 +35,7 @@ Helper functions If you have simple C functions for gathering system information, please add them here as file or as code example. +* [Basic ALSA Volume API example with error checks and handling](volume.c) * [Support for ACPI battery status Linux](new-acpi-battery.c) * [Reading out a temperature from /sys](dwmstatus-temperature.c) * [Reading up-, and downspeeds of all network interfaces from /proc/net](dwmstatus-netusage.c) diff --git a/dwm.suckless.org/dwmstatus/slstatus.tar.gz b/dwm.suckless.org/dwmstatus/slstatus.tar.gz Binary files differ. diff --git a/dwm.suckless.org/dwmstatus/volume.c b/dwm.suckless.org/dwmstatus/volume.c @@ -0,0 +1,100 @@ +/* + Copyright 07/20/2016 Aaron Caffrey https://github.com/wifiextender + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + + Compile with: + gcc -Wall -Wextra -O2 volume.c -o test -lasound +*/ + +#include <stdio.h> +#include <stdlib.h> + +#include <alsa/asoundlib.h> + +#define ALSA_ERR "Error: alsa failed" + +void exit_with_err(const char *); +void get_sound(void); + +int main(void) { + get_sound(); + return EXIT_SUCCESS; +} + +void +exit_with_err(const char *str1) { + printf("%s\n", str1); + exit(EXIT_FAILURE); +} + +void +get_sound(void) { + snd_mixer_t *handle = NULL; + snd_mixer_elem_t *elem = NULL; + snd_mixer_selem_id_t *s_elem = NULL; + long int vol, max, min; + + if (0 < (snd_mixer_open(&handle, 0))) { + exit_with_err(ALSA_ERR); + } + + if (0 < (snd_mixer_attach(handle, "default"))) { + goto error; + } + + if (0 < (snd_mixer_selem_register(handle, NULL, NULL))) { + goto error; + } + + if (0 < (snd_mixer_load(handle))) { + goto error; + } + + snd_mixer_selem_id_malloc(&s_elem); + if (NULL == s_elem) { + goto error; + } + + snd_mixer_selem_id_set_name(s_elem, "Master"); + if (NULL == (elem = snd_mixer_find_selem(handle, s_elem))) { + goto error; + } + + /* Use `set' to change the current volume value */ + if (0 < (snd_mixer_selem_get_playback_volume(elem, 0, &vol))) { + goto error; + } + snd_mixer_selem_get_playback_volume_range(elem, &min, &max); + + snd_mixer_selem_id_free(s_elem); + snd_mixer_close(handle); + + printf("%s %ld%%\n", "Volume set to", (vol * 100) / max); + return; + +/* stay cheesy no matter what */ +error: + if (NULL != s_elem) { + snd_mixer_selem_id_free(s_elem); + s_elem = NULL; + } + if (NULL != handle) { + snd_mixer_close(handle); + handle = NULL; + } + exit_with_err(ALSA_ERR); +} diff --git a/dwm.suckless.org/index.md b/dwm.suckless.org/index.md @@ -78,12 +78,9 @@ Miscellaneous Related discussion ------------------ -* <http://hashfire.com/?p=29> * <https://www.ghcif.de/tag/dynamic-window-manager/> (German) -* <http://musicmatze.wordpress.com/2012/02/04/mein-dwm-dynamic-window-manager/> (German) * [dwm blog post in Persian](http://efazati.blog.ir/post/DWM-%D8%B1%D8%A7%D9%87%DA%A9%D8%A7%D8%B1-%D9%85%D9%86%D8%A7%D8%B3%D8%A8%DB%8C-%D8%A8%D8%B1%D8%A7%DB%8C-%D9%85%D8%AF%DB%8C%D8%B1%DB%8C%D8%AA-%D9%BE%D9%86%D8%AC%D8%B1%D9%87-%D9%87%D8%A7-%D8%AF%D8%B1-%D9%84%DB%8C%D9%86%D9%88%DA%A9%D8%B3) * <http://www.gambaru.de/blog/2011/12/10/elitare-fenstermanager-sind-vielleicht-doch-einfacher-zu-bedienen-als-gedacht/> -* <http://fsk141.com/dwm-colors> * <http://www.linuxjournal.com/content/going-fast-dwm> * <http://www.linuxgoodies.com/review_dwm.html> * <http://www.iyiz.com/20-most-simple-and-cool-x-window-managers-for-linux/> @@ -91,14 +88,38 @@ Related discussion * <http://danielkaes.wordpress.com/2009/12/03/adding-a-pidgin-trayicon-to-dwm/> * <http://openmindlifestyle.wordpress.com/2009/11/28/howto-compile-and-configure-dwm-tiling-window-manager-on-ubuntu/> * <http://lsetc.wordpress.com/2009/11/27/gno-more-gnome/> -* <http://steveno.wordpress.com/2007/05/30/dwm-and-slim/> * <http://www.youtube.com/watch?v=F2sYPwuRPvc> * <http://houst0n.wordpress.com/2009/12/20/dwm-the-dynamic-window-manager-for-solaris/> * <http://the-monkeymind.blogspot.com/2007/03/dwm-dynamic-window-manager-home-page-at.html> * <http://tonytraductor.livejournal.com/120674.html> -* <http://www.halbmoendli.ch/blog/archive/2007/03/31/dwm-dynamic-window-manager.html> -* <http://peterstuifzand.nl/20060816212719.html> * <http://forums.debian.net/viewtopic.php?f=16&t=65110> * <http://wongdev.com/blog/dwm-tags-are-not-workspaces/> * [dwm usage and configuration page (french)](http://yeuxdelibad.net/Logiciel-libre/Suckless/dwm/index.html) - +* <http://www.youtube.com/watch?v=GQ5s6T25jCc> +* <https://srobb.net/dwm.html> +* <http://rhunter.org/blog/2012/04/17/dwm-a-tutorial-for-beginners/> +* <https://cannibalcandy.wordpress.com/2012/04/26/installing-and-configuring-dwm-under-ubuntu/> +* <http://blog.yjl.im/2011/07/two-weeks-with-dwm.html> +* <http://www.murga-linux.com/puppy/viewtopic.php?p=258224> +* <http://opensourceforu.com/2012/03/tiling-window-managers-getting-started-with-dwm/> + +related projects +---------------- +* [awesome](http://awesome.naquadah.org/) -- dwm fork with XCB, EWMH, Lua script, Xft, D-Bus, multihead.. support +* [awm](http://www.freaknet.org/alpt/src/alpt-wm/readme) -- (old) modified dwm with workspaces and /proc like interface +* [bwm](http://lists.suckless.org/dwm/0708/3085.html) -- (old) modified dwm with extensive mouse support +* [cons-wm](http://github.com/dharmatech/psilab/tree/master/cons-wm) -- minimalist wm in scheme (not tiled) +* [bug.n](https://github.com/fuhsjr00/bug.n) -- dwm for Windows written in AutoHotkey +* [dvtm](http://www.brain-dump.org/projects/dvtm/) -- virtual terminal manager (dwm on the console) +* [dwm-gtx](http://s01.de/~gottox/index.cgi/proj_dwm) -- dwm branch with Xinerama support, pointer movement, different layout +* [dwm-sprinkles](http://0mark.unserver.de/dwm-sprinkles/) -- dwm with colorfull bar, transparency, pre-configured pertag and more +* [dwm-win32](http://www.brain-dump.org/projects/dwm-win32/) -- dwm ported to windows +* [echinus](http://www.rootshell.be/~polachok/code/) -- dwm fork with EWMH, Xft support +* [gemini](http://gemini.digitalmediaplanet.net) -- terminal manager +* [i3](http://i3.zekjur.net/) -- wmii fork with XCB, multihead, vertical column, command mode +* [musca](http://aerosuidae.net/musca.html) -- inspired by dwm, more complex layout, configurable with commands, EWMH support +* [qtile](http://www.qtile.org/) -- pure python wm, used ideas from dwm +* [scrotwm](http://www.peereboom.us/scrotwm/html/scrotwm.html) -- dwm clone with multihead, config file, restart.. support +* [TAL/wm](http://talwm.sourceforge.net/) -- minimal tiled wm based on dwm (discontinued) +* [teslawm](http://teslawm.org/) -- dwm fork with multihead, mouse, stdin commands support (was dwm-rfigura) +* [xmonad](http://www.xmonad.org/) -- dwm clone in haskell diff --git a/dwm.suckless.org/patches/alpha.md b/dwm.suckless.org/patches/alpha.md @@ -0,0 +1,24 @@ +alpha +===== + +->[![Screenshot](dwm-alpha.png)](dwm-alpha.png)<- + +Description +----------- + +Allow dwm to have translucent bars, while keeping all the text on it opaque, +just like the [alpha-patch for st](http://st.suckless.org/patches/alpha). + + +Download +-------- + + * [dwm-alpha-6.1.diff](dwm-alpha-6.1.diff) + * [TODO] git port + + +Authors +------- + + * Eon S. Jeon - <esjeon@hyunmu.am> + * Laslo Hunhold - <dev@frign.de> (6.1 port) diff --git a/dwm.suckless.org/patches/alwaysfullscreen.md b/dwm.suckless.org/patches/alwaysfullscreen.md @@ -4,15 +4,17 @@ alwaysfullscreen Description ----------- -Do not allow focus to drift from the active fullscreen client when using -focusstack(). +Do not allow the focus to drift from the active fullscreen client when +using focusstack(). Download -------- -* [dwm-cdec978-alwaysfullscreen.diff](dwm-cdec978-alwaysfullscreen.diff) (323b) (20140220) +* [dwm-alwaysfullscreen-6.1.diff](dwm-alwaysfullscreen-6.1.diff) +* [dwm-alwaysfullscreen-20160713-56a31dc.diff](dwm-alwaysfullscreen-20160713-56a31dc.diff) -Author ------- +Authors +------- -* [Chris Down](https://chrisdown.name) (cdown) <chris@chrisdown.name> +* Chris Down - <chris@chrisdown.name> +* Laslo Hunhold - <dev@frign.de> (6.1, git ports) diff --git a/dwm.suckless.org/patches/argbcolor.md b/dwm.suckless.org/patches/argbcolor.md @@ -1,27 +0,0 @@ -ARGBColor -========== - -->[![Screenshot](dwm-argbcolor.png)](dwm-argbcolor.png)<- - -Description ------------ - -Allow dwm to have translucent bars, while keeping all the text on it opaque, -just like [ARGB patch for st][1]. - - -Download --------- - - * [dwm-3465bed-argbcolor.diff](dwm-3465bed-argbcolor.diff) (20160307) - - -Author ------- - - * Eon S. Jeon <esjeon@hyunmu.am> - - -[1]: http://st.suckless.org/patches/argbbg - - diff --git a/dwm.suckless.org/patches/attachabove.md b/dwm.suckless.org/patches/attachabove.md @@ -3,20 +3,20 @@ attachabove Description ----------- -`attachabove` makes new clients attach above the selected client (instead of -always becoming the new master) - basically how Xmonad does it. + +Make new clients attach above the selected client, instead of +always becoming the new master. This behaviour is known from Xmonad. Download -------- -Patches against different versions of dwm are available at -[dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). - * [dwm-6.1-attachabove.diff](dwm-6.1-attachabove.diff) (1829b) (20151122) - * [dwm-git-20120406-attachabove.diff](dwm-git-20120406-attachabove.diff) (1709b) - * [dwm-6.0-attachabove.diff](dwm-6.0-attachabove.diff) (1707b) (20120406) - * [dwm-5.6.1-attachabove.diff](historical/dwm-5.6.1-attachabove.diff) (1.1K) (20090817) + * [dwm-attachabove-6.0.diff](dwm-attachabove-6.0.diff) + * [dwm-attachabove-6.1.diff](dwm-attachabove-6.1.diff) + * [dwm-attachabove-20160713-56a31dc.diff](dwm-attachabove-20160713-56a31dc.diff) + +Authors +------- -Author ------- * Mate Nagy - <mnagy@port70.net> - * Rewritten by Jan Christoph Ebersbach - <jceb@e-jc.de> + * Jan Christoph Ebersbach - <jceb@e-jc.de> (6.0, 6.1 ports) + * Laslo Hunhold - <dev@frign.de> (git port) diff --git a/dwm.suckless.org/patches/attachaside.md b/dwm.suckless.org/patches/attachaside.md @@ -3,9 +3,10 @@ attachaside Description ----------- -`attachaside` makes the new client get attached and focused in the stacking + +Make new clients get attached and focused in the stacking area instead of always becoming the new master. It's basically an -[attachabove](attachabove) mod. +[attachabove](attachabove) modification. Original behaviour : +-----------------+-------+ @@ -44,23 +45,12 @@ area instead of always becoming the new master. It's basically an Download -------- -### Version updated to work with tags - -The original version of attachaside does does not attach to the stack when -windows are spawned on a tag that is not currently focused. This version is -improved to also attach to the stack on unfocused tags. - -* [dwm-6.1-attachaside-tagfix.diff](dwm-6.1-attachaside-tagfix.diff) (2.9K) (20150729) - -### Original - -* [dwm-6.0-attachaside.diff](dwm-6.0-attachaside.diff) (1,6K) (20140412) -* [dwm-5.7.2-attachaside.diff](historical/dwm-5.7.2-attachaside.diff) (1.1K) (20091215) -* [dwm-5.6.1-attachaside.diff](historical/dwm-5.6.1-attachaside.diff) (1.1K) (20090915) +* [dwm-attachaside-6.1.diff](dwm-attachaside-6.1.diff) +* [dwm-attachaside-20160718-56a31dc.diff](dwm-attachaside-20160718-56a31dc.diff) Authors ------- -* Jerome Andrieux - `<jerome at gcu dot info>` -* Version updated to work with tags by [Chris Down](https://chrisdown.name) - (cdown) <chris@chrisdown.name> -* Update to 6.0 by Vladimir Seleznev - `<me at wladmis dot org>` + +* Jerome Andrieux - <jerome@gcu.info> +* Chris Down - <chris@chrisdown.name> (6.1 port and fixes) +* Laslo Hunhold - <dev@frign.de> (git port) diff --git a/dwm.suckless.org/patches/autoresize.md b/dwm.suckless.org/patches/autoresize.md @@ -1,14 +1,21 @@ -# autoresize +autoresize +========== -## Description +Description +----------- -By default, windows that are not visible when requesting a resize/move wont get resized/moved. With this Patch, they do. +By default, windows that are not visible when requesting a resize/move +won't get resized/moved. With this patch, they will. -## Download +Download +-------- - * [autoresize.diff](autoresize.diff) autoresize.diff (07.03.2010) - * [dwm-6.0-autoresize.diff](dwm-6.0-autoresize.diff) (15.04.2013) + * [dwm-autoresize-6.0.diff](dwm-autoresize-6.0.diff) + * [dwm-autoresize-6.1.diff](dwm-autoresize-6.1.diff) + * [dwm-autoresize-20160718-56a31dc.diff](dwm-autoresize-20160718-56a31dc.diff) -## Author +Authors +------- * Stefan Mark - <0mark@unserver.de> + * Laslo Hunhold - <dev@frign.de> (6.1, git ports) diff --git a/dwm.suckless.org/patches/autostart.md b/dwm.suckless.org/patches/autostart.md @@ -1,15 +0,0 @@ -# autostart # - -## Description ## -This patch will make dwm run "~/.dwm/autostart_blocking.sh" and "~/.dwm/autostart.sh &" (in that order) before entering the handler loop. One or both of these files can be ommited. - -Be aware that dwm will not startup as long as autostart_blocking.sh is running and will stay completely unresponive until its completion. For obvious reasons it is generally a bad idea to start X-applications here :) - -## Download ## -### 6.0 - * [dwm-6.0-autostart.diff](dwm-6.0-autostart.diff) (1kb) (20121220) - * [from github](https://github.com/axelGschaider/dwm-patch-autostart.sh) - -## Author ## - * Axel Gschaider: <axel.gschaider@gmail.com> - diff --git a/dwm.suckless.org/patches/azertykey.md b/dwm.suckless.org/patches/azertykey.md @@ -1,20 +0,0 @@ -# frenchkey - -## Description - -### En français -Ce patch a pour but de remplacer les raccourcis par défaut de dwm, qui ne sont pas compatibles avec les claviers azerty (pour les français par exemple). -En somme, les chiffres 1 2 3 ... 9 0 sont remplacés par le code des touches & é ... ç à. - -La touche querty / est quand à elle remplacée par : . -Ainsi, toutes les fonctions de dwm restent accessibles malgré tout. - -Le patch est en fait une simple modification du config.h - -### English -This patch is a config.h modification to use tagging shortcuts with azerty keyboards, which have different layout for numbers and for the key / . - -## Download - - * [dwm-azertykey.diff](dwm-azertykey.diff) dwm-azertykey.diff (22.04.2011) - diff --git a/dwm.suckless.org/patches/better-borders.md b/dwm.suckless.org/patches/better-borders.md @@ -1,25 +0,0 @@ -better borders -============== - -Description ------------ - -Like [Ebersbach's patch](http://dwm.suckless.org/patches/noborder), this patch -removes the border when there is only one window visible, but this patch does -not depend on layout-specific changes and should automatically work with most -layouts. The patch also removes borders from any windows that are the same size -as the monitor and marks them full-screen even if their X properties indicate -otherwise. This eliminates nuisance borders that appear with some games and -applications while in full-screen mode. - -Thanks to Alesandar Metodiev for reporting a bug that lead to the patch being -rewritten. - -Download --------- - - * [dwm-6.1-better-borders.diff](dwm-6.1-better-borders.diff) (2015-12-27) - -Author ------- - * Eric Pruitt - `<eric dot pruitt at gmail dot com>` diff --git a/dwm.suckless.org/patches/bottom_stack.md b/dwm.suckless.org/patches/bottom_stack.md @@ -1,49 +0,0 @@ -bottom stack -============ - -Description ------------ -`bstack` and `bstackhoriz` are two bottom stack layouts for dwm. - -Bottom Stack Tiling -------------------- - - bstack (TTT) - +-----------------+ - | | - | | - | | - +-----+-----+-----+ - | | | | - | | | | - +-----+-----+-----+ - - bstackhoriz (===) - +-----------------+ - | | - | | - | | - +-----------------+ - +-----------------+ - +-----------------+ - +-----------------+ - -Download --------- - -### 6.1 - -* `tile`-like `htile` implementation, similar to `bstack` [dwm-6.1-htile.diff](dwm-6.1-htile.diff) - -### 6.0 -* Not for use with pertag patch: [dwm-6.0-bstack.diff](dwm-6.0-bstack.diff) - -### 5.9 -* Not for use with pertag patch: [dwm-5.9-bstack.diff](historical/dwm-5.9-bstack.diff) -* For use with pertag patch: [dwm-5.9-bstack-alt.diff](historical/dwm-5.9-bstack-alt.diff) - -### 5.8 -* Not for use with pertag patch: [dwm-5.8.2-bstack.diff](historical/dwm-5.8.2-bstack.diff) -* For use with pertag patch: [dwm-5.8.2-bstack-alt.diff](historical/dwm-5.8.2-bstack-alt.diff) -* see older versions in [historical patches](historical) - diff --git a/dwm.suckless.org/patches/bottommargin.md b/dwm.suckless.org/patches/bottommargin.md @@ -1,13 +0,0 @@ -# bottommargin - -## Description - -Adds a variable margin at the bottom for status or notification bars - -## Download - - * [dwm-6.0-bottommargin.diff](dwm-6.0-bottommargin.diff) dwm-6.0-bottommargin.diff (07.06.2014) - -## Author - - * Julian A. diff --git a/dwm.suckless.org/patches/bottomstack.md b/dwm.suckless.org/patches/bottomstack.md @@ -0,0 +1,31 @@ +bottomstack +=========== + +Description +----------- + +`bstack` and `bstackhoriz` are two stack layouts for dwm. + + bstack (TTT) bstackhoriz (===) + +-----------------+ +-----------------+ + | | | | + | | | | + | | | | + +-----+-----+-----+ +-----------------+ + | | | | +-----------------+ + | | | | +-----------------+ + +-----+-----+-----+ +-----------------+ + +`bstack` can be selected with [Alt]+[u], `bstackhoriz` with [Alt]+[o]. + +Download +-------- + + * [dwm-bottomstack-6.1.diff](dwm-bottomstack-6.1.diff) + * [dwm-bottomstack-20160719-56a31dc.diff](dwm-bottomstack-20160719-56a31dc.diff) + +Authors +------- + + * Anselm R Garbe - <anselm@garbe.us> + * Laslo Hunhold - <dev@frign.de> (6.1, git ports) diff --git a/dwm.suckless.org/patches/center.md b/dwm.suckless.org/patches/center.md @@ -4,16 +4,17 @@ center Description ----------- -Adds an "iscentered" rule to automatically center clients on the current +Add an `iscentered` rule to automatically center clients on the current monitor. Download -------- -* [dwm-6.1-center.diff](dwm-6.1-center.diff) (2k) (20151114) -* [dwm-cdec978-center.diff](historical/dwm-cdec978-center.diff) (2k) (20140123) + * [dwm-center-6.1.diff](dwm-center-6.1.diff) + * [dwm-center-20160719-56a31dc.diff](dwm-center-20160719-56a31dc.diff) -Author ------- +Authors +------- -* [Chris Down](https://chrisdown.name) (cdown) <chris@chrisdown.name> + * Chris Down - <chris@chrisdown.name> + * Laslo Hunhold - <dev@frign.de> (git port) diff --git a/dwm.suckless.org/patches/centeredmaster.c b/dwm.suckless.org/patches/centeredmaster.c @@ -1,91 +0,0 @@ -void -centeredfloatingmaster(Monitor *m) { - unsigned int i, n, w, mh, mw, mx, mxo, my, myo, tx; - Client *c; - - // Count number of clients in the selected monitor - for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - if(n == 0) - return; - - // initialize nmaster area - if(n > m->nmaster) { - // go mfact box in the center if more than nmaster clients - if(m->ww > m->wh) { - mw = m->nmaster ? m->ww * m->mfact : 0; - mh = m->nmaster ? m->wh * 0.9 : 0; - } else { - mh = m->nmaster ? m->wh * m->mfact : 0; - mw = m->nmaster ? m->ww * 0.9 : 0; - } - mx = mxo = (m->ww - mw) / 2; - my = myo = (m->wh - mh) / 2; - } else { - // Go fullscreen if all clients are in the master area - mh = m->wh; - mw = m->ww; - mx = mxo = 0; - my = myo = 0; - } - for(i = tx = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) - if(i < m->nmaster) { - // nmaster clients are stacked horizontally, in the center of the screen - w = (mw + mxo - mx) / (MIN(n, m->nmaster) - i); - resize(c, m->wx + mx, m->wy + my, w - (2*c->bw), mh - (2*c->bw), False); - mx += WIDTH(c); - } else { - // Stack clients are stacked horizontally - w = (m->ww - tx) / (n - i); - resize(c, m->wx + tx, m->wy, w - (2*c->bw), m->wh - (2*c->bw), False); - tx += WIDTH(c); - } -} - -void -centeredmaster(Monitor *m) { - unsigned int i, n, h, mw, mx, my, oty, ety, tw; - Client *c; - - // Count number of clients in the selected monitor - for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - if(n == 0) - return; - - // initialize areas - mw = m->ww; - mx = 0; - my = 0; - tw = mw; - - if(n > m->nmaster) { - // go mfact box in the center if more than nmaster clients - mw = m->nmaster ? m->ww * m->mfact : 0; - tw = m->ww - mw; - - if (n - m->nmaster > 1) { // only one client - mx = (m->ww - mw) / 2; - tw = (m->ww - mw) / 2; - } - } - - oty = 0; - ety = 0; - for(i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) - if(i < m->nmaster) { - // nmaster clients are stacked verticaly, in the center of the screen - h = (m->wh - my) / (MIN(n, m->nmaster) - i); - resize(c, m->wx + mx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), False); - my += HEIGHT(c); - } else { - // Stack clients are stacked verticaly - if ((i - m->nmaster) % 2 ) { - h = (m->wh - ety) / ( (1 + n - i) / 2); - resize(c, m->wx, m->wy + ety, tw - (2*c->bw), h - (2*c->bw), False); - ety += HEIGHT(c); - } else { - h = (m->wh - oty) / ((1 + n - i) / 2); - resize(c, m->wx + mx + mw, m->wy + oty, tw - (2*c->bw), h - (2*c->bw), False); - oty += HEIGHT(c); - } - } -} diff --git a/dwm.suckless.org/patches/centeredmaster.md b/dwm.suckless.org/patches/centeredmaster.md @@ -1,94 +1,63 @@ -# centeredmaster - -## `centeredmaster` - -makes the nmaster area centered -on screen, using `mfact * monitor width & height`, with the stacked windows -distributed on left and right. - -With one client in master: - - +------------------------------+ - |+--------++--------++--------+| - || || || || - || || || || - || || || || - || S2 || M || S1 || - || || || || - || || || || - || || || || - || || || || - |+--------++--------++--------+| - +------------------------------+ - -With two clients in master: - - +------------------------------+ - |+--------++--------++--------+| - || || || || - || || M1 || || - || || || || - || |+--------+| || - || |+--------+| || - || || || || - || || M2 || || - || || || || - |+--------++--------++--------+| - +------------------------------+ - -## `centeredfloatingmaster` - -makes the nmaster area centered -on screen, using `mfact * monitor width & height`, over an -horizontally tiled `stack` area, pretty much like -a "scratchpad". - -With one client in master: - - +------------------------------+ - |+--------++--------++--------+| - || || || || - || +------------------+ || - || | | || - || | | || - || | M | || - || | | || - || +------------------+ || - || || || || - |+--------++--------++--------+| - +------------------------------+ - -With two clients in master: - - +------------------------------+ - |+--------++--------++--------+| - || || || || - || +--------++--------+ || - || | || | || - || | || | || - || | M1 || M2 | || - || | || | || - || +--------++--------+ || - || || || || - |+--------++--------++--------+| - +------------------------------+ - - -I find it useful on large screens (say 1920px wide), where -`monocle` or `htile` feels either too large or makes me type in -a corner of the screen. - -With `centeredmaster`, for instance, I can set my editor in the -center, while keeping an eye on what's happening in the windows -behind (logs, tests, ...). - - - - -## Links - -* [centeredmaster.c](centeredmaster.c) - 2015/11/22 -* [dwm-6.1-centeredmaster.diff](dwm-6.1-centeredmaster.diff) - 2015/11/21 - - -[jerome](http://blog.jardinmagique.info) <jerome@gcu.info> +centeredmaster +============== + +Description +----------- + +`centeredmaster` and `centeredfloatingmaster` are two stack layouts for dwm. + +`centeredmaster` centers the nmaster area on screen, using +`mfact * monitor width & height`, with the stacked windows +distributed to the left and right. It can be selected with [Alt]+[u]. + +With one and two clients in master respectively this results in: + + +------------------------------+ +------------------------------+ + |+--------++--------++--------+| |+--------++--------++--------+| + || || || || || || || || + || || || || || || M1 || || + || || || || || || || || + || S2 || M || S1 || || |+--------+| || + || || || || || |+--------+| || + || || || || || || || || + || || || || || || M2 || || + || || || || || || || || + |+--------++--------++--------+| |+--------++--------++--------+| + +------------------------------+ +------------------------------+ + +`centeredfloatingmaster` centers the nmaster area on screen, using +`mfact * monitor width & height` over a horizontally tiled `stack` area, +comparable to a scratchpad. It can be selected with [Alt]+[o]. + +With one and two clients in master respectively this results in: + + +------------------------------+ +------------------------------+ + |+--------++--------++--------+| |+--------++--------++--------+| + || || || || || || || || + || +------------------+ || || +--------++--------+ || + || | | || || | || | || + || | | || || | || | || + || | M | || || | M1 || M2 | || + || | | || || | || | || + || +------------------+ || || +--------++--------+ || + || || || || || || || || + |+--------++--------++--------+| |+--------++--------++--------+| + +------------------------------+ +------------------------------+ + +These stack layouts can be useful on large screens, where `monocle` or +`htile` might be either too large or forcing the user to type in a corner +of the screen. +They allow for instance to center the editor while being able to keep an +eye on background processes (logs, tests,...) + +Download +-------- + + * [dwm-centeredmaster-6.1.diff](dwm-centeredmaster-6.1.diff) + * [dwm-centeredmaster-20160719-56a31dc.diff](dwm-centeredmaster-20160719-56a31dc.diff) + +Authors +------- + + * [Jérôme Andrieux](http://blog.jardinmagique.info) - <jerome@gcu.info> + * Laslo Hunhold - <dev@frign.de> (6.1, git ports) diff --git a/dwm.suckless.org/patches/clientspertag.md b/dwm.suckless.org/patches/clientspertag.md @@ -41,7 +41,7 @@ will result on swapping between the defined value and -1. ## Download - * [dwm-5.6.1-cpt.diff](dwm-5.6.1-cpt.diff) (2.9k) (20090913) + * [dwm-clientspertag-5.6.1.diff](dwm-clientspertag-5.6.1.diff) ## Maintainer diff --git a/dwm.suckless.org/patches/columns.md b/dwm.suckless.org/patches/columns.md @@ -3,27 +3,18 @@ columns Description ----------- -This patch adds an extra layout to dwm called `col` in which the windows are -arranged in colums of equal size. The number of columns is always nmaster + 1, -and the last column is a stack of leftover windows just like the normal tile -layout. + +This patch adds an extra layout to dwm called `col` in which the windows in the +master area are arranged in colums of equal size. The number of columns is +always nmaster + 1, and the last column is a stack of leftover windows just +like the normal tile layout. It effectively acts like the default tiling mode, +except provides for vertical instead of horizontal master windows. Download -------- -* [dwm-r1580-col.diff](dwm-r1580-col.diff) +* [dwm-columns-6.0.diff](dwm-columns-6.0.diff) Author ------ * Evan Gates (emg)<evan.gates@gmail.com> - -Special Version ---------------- -This patch tweaks the one above to respect the master width % (mfact in config.h) -and resizings. So instead of the entire screen divided into even columns only -the master portion is, with the remaining space becoming the last column for the -stack. It effectively acts like the default tiling mode, except provides for -vertical instead of horizontal master windows. - -* [dwm-6.0-column_master.diff](dwm-6.0-column_master.diff) - -* noah dot rosser gmail +* Noah Rosser <noah.rosser@gmail.com> diff --git a/dwm.suckless.org/patches/combo.md b/dwm.suckless.org/patches/combo.md @@ -18,9 +18,9 @@ and view so you could replace all usages if you wanted. Download -------- - * [dwm-5.9-combo.diff](dwm-5.9-combo.diff) - 2010-10-30 - * [dwm-6.0-combo.diff](dwm-6.0-combo.diff) - 2012-10-09 - * [dwm-6.1-combo.diff](dwm-6.1-combo.diff) - 2016-01-22 + * [dwm-combo-5.9.diff](dwm-combo-5.9.diff) - 2010-10-30 + * [dwm-combo-6.0.diff](dwm-combo-6.0.diff) - 2012-10-09 + * [dwm-combo-6.1.diff](dwm-combo-6.1.diff) - 2016-01-22 Author ------ diff --git a/dwm.suckless.org/patches/current_desktop.md b/dwm.suckless.org/patches/current_desktop.md @@ -23,7 +23,7 @@ ## Download - * [dwm-5.8.2-current_desktop.diff](dwm-5.8.2-current_desktop.diff) (dwm 2010604) + * [dwm-current_desktop-5.8.2.diff](dwm-current_desktop-5.8.2.diff) (dwm 2010604) ## Author diff --git a/dwm.suckless.org/patches/dualstatus.md b/dwm.suckless.org/patches/dualstatus.md @@ -11,8 +11,8 @@ xsetroot -name "top text;bottom text" Download -------- - * [dwm-6.1-dualstatus.diff](dwm-6.1-dualstatus.diff) (4683b) (20151110) - * [dwm-6.0-dualstatus.diff](dwm-6.0-dualstatus.diff) (4794b) (20130908) + * [dwm-dualstatus-6.1.diff](dwm-dualstatus-6.1.diff) (4683b) (20151110) + * [dwm-dualstatus-6.0.diff](dwm-dualstatus-6.0.diff) (4794b) (20130908) Screenshot ---------- diff --git a/dwm.suckless.org/patches/dwm-10e232f9ace7-float_border_color2.diff b/dwm.suckless.org/patches/dwm-10e232f9ace7-float_border_color2.diff @@ -1,84 +0,0 @@ -URL: http://dwm.suckless.org/patches/historical/float_border_color -float_border_color2 allows you to specify a different border color for floating -windows. - -diff -r 10e232f9ace7 config.def.h ---- a/config.def.h Sun Mar 25 17:49:35 2012 +0200 -+++ b/config.def.h Fri Apr 06 08:16:29 2012 +0200 -@@ -8,6 +8,8 @@ - static const char selbordercolor[] = "#005577"; - static const char selbgcolor[] = "#005577"; - static const char selfgcolor[] = "#eeeeee"; -+static const char floatnormbordercolor[] = "#005577"; -+static const char floatselbordercolor[] = "#005577"; - static const unsigned int borderpx = 1; /* border pixel of windows */ - static const unsigned int snap = 32; /* snap pixel */ - static const Bool showbar = True; /* False means no bar */ -diff -r 10e232f9ace7 dwm.c ---- a/dwm.c Sun Mar 25 17:49:35 2012 +0200 -+++ b/dwm.c Fri Apr 06 08:16:29 2012 +0200 -@@ -57,7 +57,7 @@ - - /* enums */ - enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ --enum { ColBorder, ColFG, ColBG, ColLast }; /* color */ -+enum { ColBorder, ColFG, ColBG, ColBorderFloat, ColLast }; /* color */ - enum { NetSupported, NetWMName, NetWMState, - NetWMFullscreen, NetActiveWindow, NetWMWindowType, - NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ -@@ -857,7 +857,10 @@ - detachstack(c); - attachstack(c); - grabbuttons(c, True); -- XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]); -+ if(c->isfloating) -+ XSetWindowBorder(dpy, c->win, dc.sel[ColBorderFloat]); -+ else -+ XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]); - setfocus(c); - } - else { -@@ -1159,6 +1162,8 @@ - c->isfloating = c->oldstate = trans != None || c->isfixed; - if(c->isfloating) - XRaiseWindow(dpy, c->win); -+ if(c->isfloating) -+ XSetWindowBorder(dpy, w, dc.norm[ColBorderFloat]); - attach(c); - attachstack(c); - XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, -@@ -1633,9 +1638,11 @@ - dc.norm[ColBorder] = getcolor(normbordercolor); - dc.norm[ColBG] = getcolor(normbgcolor); - dc.norm[ColFG] = getcolor(normfgcolor); -+ dc.norm[ColBorderFloat] = getcolor(floatnormbordercolor); - dc.sel[ColBorder] = getcolor(selbordercolor); - dc.sel[ColBG] = getcolor(selbgcolor); - dc.sel[ColFG] = getcolor(selfgcolor); -+ dc.sel[ColBorderFloat] = getcolor(floatselbordercolor); - dc.drawable = XCreatePixmap(dpy, root, DisplayWidth(dpy, screen), bh, DefaultDepth(dpy, screen)); - dc.gc = XCreateGC(dpy, root, 0, NULL); - XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); -@@ -1760,6 +1767,10 @@ - return; - selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; - if(selmon->sel->isfloating) -+ XSetWindowBorder(dpy, selmon->sel->win, dc.sel[ColBorderFloat]); -+ else -+ XSetWindowBorder(dpy, selmon->sel->win, dc.sel[ColBorder]); -+ if(selmon->sel->isfloating) - resize(selmon->sel, selmon->sel->x, selmon->sel->y, - selmon->sel->w, selmon->sel->h, False); - else if(selmon->sel->isfullscreen) -@@ -1797,7 +1808,10 @@ - if(!c) - return; - grabbuttons(c, False); -- XSetWindowBorder(dpy, c->win, dc.norm[ColBorder]); -+ if(c->isfloating) -+ XSetWindowBorder(dpy, c->win, dc.norm[ColBorderFloat]); -+ else -+ XSetWindowBorder(dpy, c->win, dc.norm[ColBorder]); - if(setfocus) { - XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); - XDeleteProperty(dpy, root, netatom[NetActiveWindow]); diff --git a/dwm.suckless.org/patches/dwm-20151110-5ed9c48-keycode.patch b/dwm.suckless.org/patches/dwm-20151110-5ed9c48-keycode.patch @@ -1,146 +0,0 @@ -From 6a9c5bc422a68a40d5eb2b873fa01d59d6c5bd50 Mon Sep 17 00:00:00 2001 -From: Quentin Rameau <quinq@fifth.space> -Date: Tue, 10 Nov 2015 19:09:20 +0100 -Subject: [PATCH] Use keycodes instead of keysyms - ---- - config.def.h | 68 ++++++++++++++++++++++++++++++------------------------------ - dwm.c | 15 +++++--------- - 2 files changed, 39 insertions(+), 44 deletions(-) - -diff --git a/config.def.h b/config.def.h -index 7054c06..f59d1eb 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -58,40 +58,40 @@ static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, - static const char *termcmd[] = { "st", NULL }; - - static Key keys[] = { -- /* modifier key function argument */ -- { MODKEY, XK_p, spawn, {.v = dmenucmd } }, -- { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, -- { MODKEY, XK_b, togglebar, {0} }, -- { MODKEY, XK_j, focusstack, {.i = +1 } }, -- { MODKEY, XK_k, focusstack, {.i = -1 } }, -- { MODKEY, XK_i, incnmaster, {.i = +1 } }, -- { MODKEY, XK_d, incnmaster, {.i = -1 } }, -- { MODKEY, XK_h, setmfact, {.f = -0.05} }, -- { MODKEY, XK_l, setmfact, {.f = +0.05} }, -- { MODKEY, XK_Return, zoom, {0} }, -- { MODKEY, XK_Tab, view, {0} }, -- { MODKEY|ShiftMask, XK_c, killclient, {0} }, -- { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, -- { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, -- { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, -- { MODKEY, XK_space, setlayout, {0} }, -- { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, -- { MODKEY, XK_0, view, {.ui = ~0 } }, -- { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, -- { MODKEY, XK_comma, focusmon, {.i = -1 } }, -- { MODKEY, XK_period, focusmon, {.i = +1 } }, -- { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, -- { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, -- TAGKEYS( XK_1, 0) -- TAGKEYS( XK_2, 1) -- TAGKEYS( XK_3, 2) -- TAGKEYS( XK_4, 3) -- TAGKEYS( XK_5, 4) -- TAGKEYS( XK_6, 5) -- TAGKEYS( XK_7, 6) -- TAGKEYS( XK_8, 7) -- TAGKEYS( XK_9, 8) -- { MODKEY|ShiftMask, XK_q, quit, {0} }, -+ /* modifier key function argument */ -+ { MODKEY, 33, spawn, {.v = dmenucmd } }, // p -+ { MODKEY|ShiftMask, 36, spawn, {.v = termcmd } }, // Return -+ { MODKEY, 56, togglebar, {0} }, // b -+ { MODKEY, 44, focusstack, {.i = +1 } }, // j -+ { MODKEY, 45, focusstack, {.i = -1 } }, // k -+ { MODKEY, 31, incnmaster, {.i = +1 } }, // i -+ { MODKEY, 40, incnmaster, {.i = -1 } }, // d -+ { MODKEY, 43, setmfact, {.f = -0.05} }, // h -+ { MODKEY, 46, setmfact, {.f = +0.05} }, // l -+ { MODKEY, 36, zoom, {0} }, // Return -+ { MODKEY, 23, view, {0} }, // Tab -+ { MODKEY|ShiftMask, 54, killclient, {0} }, // c -+ { MODKEY, 28, setlayout, {.v = &layouts[0]} }, // t -+ { MODKEY, 41, setlayout, {.v = &layouts[1]} }, // f -+ { MODKEY, 58, setlayout, {.v = &layouts[2]} }, // m -+ { MODKEY, 65, setlayout, {0} }, // space -+ { MODKEY|ShiftMask, 65, togglefloating, {0} }, // space -+ { MODKEY, 19, view, {.ui = ~0 } }, // 0 -+ { MODKEY|ShiftMask, 19, tag, {.ui = ~0 } }, // 0 -+ { MODKEY, 59, focusmon, {.i = -1 } }, // comma -+ { MODKEY, 60, focusmon, {.i = +1 } }, // period -+ { MODKEY|ShiftMask, 59, tagmon, {.i = -1 } }, // comma -+ { MODKEY|ShiftMask, 60, tagmon, {.i = +1 } }, // period -+ TAGKEYS( 10, 0) // 1 -+ TAGKEYS( 11, 1) // 2 -+ TAGKEYS( 12, 2) // 3 -+ TAGKEYS( 13, 3) // 4 -+ TAGKEYS( 14, 4) // 5 -+ TAGKEYS( 15, 5) // 6 -+ TAGKEYS( 16, 6) // 7 -+ TAGKEYS( 17, 7) // 8 -+ TAGKEYS( 18, 8) // 9 -+ { MODKEY|ShiftMask, 24, quit, {0} }, // q - }; - - /* button definitions */ -diff --git a/dwm.c b/dwm.c -index 0362114..60dd817 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -31,7 +31,6 @@ - #include <sys/types.h> - #include <sys/wait.h> - #include <X11/cursorfont.h> --#include <X11/keysym.h> - #include <X11/Xatom.h> - #include <X11/Xlib.h> - #include <X11/Xproto.h> -@@ -101,7 +100,7 @@ struct Client { - - typedef struct { - unsigned int mod; -- KeySym keysym; -+ KeyCode keycode; - void (*func)(const Arg *); - const Arg arg; - } Key; -@@ -967,14 +966,12 @@ grabkeys(void) - { - unsigned int i, j; - unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; -- KeyCode code; - - XUngrabKey(dpy, AnyKey, AnyModifier, root); - for (i = 0; i < LENGTH(keys); i++) -- if ((code = XKeysymToKeycode(dpy, keys[i].keysym))) -- for (j = 0; j < LENGTH(modifiers); j++) -- XGrabKey(dpy, code, keys[i].mod | modifiers[j], root, -- True, GrabModeAsync, GrabModeAsync); -+ for (j = 0; j < LENGTH(modifiers); j++) -+ XGrabKey(dpy, keys[i].keycode, keys[i].mod | modifiers[j], root, -+ True, GrabModeAsync, GrabModeAsync); - } - } - -@@ -1001,13 +998,11 @@ void - keypress(XEvent *e) - { - unsigned int i; -- KeySym keysym; - XKeyEvent *ev; - - ev = &e->xkey; -- keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); - for (i = 0; i < LENGTH(keys); i++) -- if (keysym == keys[i].keysym -+ if (ev->keycode == keys[i].keycode - && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) - && keys[i].func) - keys[i].func(&(keys[i].arg)); --- -2.6.2 - diff --git a/dwm.suckless.org/patches/dwm-3465bed-argbcolor.diff b/dwm.suckless.org/patches/dwm-3465bed-argbcolor.diff @@ -1,269 +0,0 @@ -From db0f6c99b236aafb33c21cc57ad4ec493ab4d3b2 Mon Sep 17 00:00:00 2001 -From: "Eon S. Jeon" <esjeon@hyunmu.am> -Date: Mon, 7 Mar 2016 20:17:24 +0900 -Subject: [PATCH] implement ARGB color support - ---- - config.def.h | 2 ++ - config.mk | 2 +- - drw.c | 22 +++++++++---------- - drw.h | 7 ++++-- - dwm.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++---------- - 5 files changed, 78 insertions(+), 25 deletions(-) - -diff --git a/config.def.h b/config.def.h -index 7054c06..4448d46 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -11,6 +11,8 @@ static const char normfgcolor[] = "#bbbbbb"; - static const char selbordercolor[] = "#005577"; - static const char selbgcolor[] = "#005577"; - static const char selfgcolor[] = "#eeeeee"; -+static unsigned int baralpha = 0xd0; -+static unsigned int borderalpha = OPAQUE; - static const unsigned int borderpx = 1; /* border pixel of windows */ - static const unsigned int snap = 32; /* snap pixel */ - static const int showbar = 1; /* 0 means no bar */ -diff --git a/config.mk b/config.mk -index 80dc936..2c62e89 100644 ---- a/config.mk -+++ b/config.mk -@@ -22,7 +22,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} -lXrender - - # flags - CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -diff --git a/drw.c b/drw.c -index f49200b..12e3ebc 100644 ---- a/drw.c -+++ b/drw.c -@@ -61,7 +61,7 @@ utf8decode(const char *c, long *u, size_t clen) - } - - Drw * --drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) -+drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap) - { - Drw *drw; - -@@ -71,8 +71,11 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h - drw->root = root; - drw->w = w; - drw->h = h; -- drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen)); -- drw->gc = XCreateGC(dpy, root, 0, NULL); -+ 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); - drw->fontcount = 0; - XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); - -@@ -86,7 +89,7 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h) - drw->h = h; - if (drw->drawable) - XFreePixmap(drw->dpy, drw->drawable); -- drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen)); -+ drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, drw->depth); - } - - void -@@ -180,16 +183,15 @@ drw_font_free(Fnt *font) - } - - Clr * --drw_clr_create(Drw *drw, const char *clrname) -+drw_clr_create(Drw *drw, const char *clrname, unsigned int alpha) - { - Clr *clr; - - clr = ecalloc(1, sizeof(Clr)); -- if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), -- DefaultColormap(drw->dpy, drw->screen), -+ if (!XftColorAllocName(drw->dpy, drw->visual, drw->cmap, - clrname, &clr->rgb)) - die("error, cannot allocate color '%s'\n", clrname); -- clr->pix = clr->rgb.pixel; -+ clr->pix = (clr->rgb.pixel & 0x00ffffffU) | (alpha << 24); - - return clr; - } -@@ -245,9 +247,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex - XSetForeground(drw->dpy, drw->gc, invert ? - drw->scheme->fg->pix : drw->scheme->bg->pix); - XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); -- d = XftDrawCreate(drw->dpy, drw->drawable, -- DefaultVisual(drw->dpy, drw->screen), -- DefaultColormap(drw->dpy, drw->screen)); -+ d = XftDrawCreate(drw->dpy, drw->drawable, drw->visual, drw->cmap); - } - - curfont = drw->fonts[0]; -diff --git a/drw.h b/drw.h -index e3b8515..1fed824 100644 ---- a/drw.h -+++ b/drw.h -@@ -30,6 +30,9 @@ typedef struct { - Display *dpy; - int screen; - Window root; -+ Visual *visual; -+ unsigned int depth; -+ Colormap cmap; - Drawable drawable; - GC gc; - ClrScheme *scheme; -@@ -43,7 +46,7 @@ typedef struct { - } Extnts; - - /* Drawable abstraction */ --Drw *drw_create(Display *, int, Window, unsigned int, unsigned int); -+Drw *drw_create(Display *, int, Window, unsigned int, unsigned int, Visual*, unsigned int, Colormap); - void drw_resize(Drw *, unsigned int, unsigned int); - void drw_free(Drw *); - -@@ -55,7 +58,7 @@ void drw_font_getexts(Fnt *, const char *, unsigned int, Extnts *); - unsigned int drw_font_getexts_width(Fnt *, const char *, unsigned int); - - /* Colour abstraction */ --Clr *drw_clr_create(Drw *, const char *); -+Clr *drw_clr_create(Drw *, const char *, unsigned int); - void drw_clr_free(Clr *); - - /* Cursor abstraction */ -diff --git a/dwm.c b/dwm.c -index ff7e096..286fb10 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -57,6 +57,8 @@ - #define TAGMASK ((1 << LENGTH(tags)) - 1) - #define TEXTW(X) (drw_text(drw, 0, 0, 0, 0, (X), 0) + drw->fonts[0]->h) - -+#define OPAQUE 0xffU -+ - /* enums */ - enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ - enum { SchemeNorm, SchemeSel, SchemeLast }; /* color schemes */ -@@ -232,6 +234,7 @@ static Monitor *wintomon(Window w); - static int xerror(Display *dpy, XErrorEvent *ee); - static int xerrordummy(Display *dpy, XErrorEvent *ee); - static int xerrorstart(Display *dpy, XErrorEvent *ee); -+static void xinitvisual(); - static void zoom(const Arg *arg); - - /* variables */ -@@ -267,6 +270,11 @@ static Drw *drw; - static Monitor *mons, *selmon; - static Window root; - -+static int useargb = 0; -+static Visual *visual; -+static int depth; -+static Colormap cmap; -+ - /* configuration, allows nested code to access above variables */ - #include "config.h" - -@@ -1561,7 +1569,8 @@ setup(void) - sw = DisplayWidth(dpy, screen); - sh = DisplayHeight(dpy, screen); - root = RootWindow(dpy, screen); -- drw = drw_create(dpy, screen, root, sw, sh); -+ xinitvisual(); -+ drw = drw_create(dpy, screen, root, sw, sh, visual, depth, cmap); - drw_load_fonts(drw, fonts, LENGTH(fonts)); - if (!drw->fontcount) - die("no fonts could be loaded.\n"); -@@ -1585,12 +1594,12 @@ setup(void) - cursor[CurResize] = drw_cur_create(drw, XC_sizing); - cursor[CurMove] = drw_cur_create(drw, XC_fleur); - /* init appearance */ -- scheme[SchemeNorm].border = drw_clr_create(drw, normbordercolor); -- scheme[SchemeNorm].bg = drw_clr_create(drw, normbgcolor); -- scheme[SchemeNorm].fg = drw_clr_create(drw, normfgcolor); -- scheme[SchemeSel].border = drw_clr_create(drw, selbordercolor); -- scheme[SchemeSel].bg = drw_clr_create(drw, selbgcolor); -- scheme[SchemeSel].fg = drw_clr_create(drw, selfgcolor); -+ scheme[SchemeNorm].border = drw_clr_create(drw, normbordercolor, borderalpha); -+ scheme[SchemeNorm].bg = drw_clr_create(drw, normbgcolor, baralpha); -+ scheme[SchemeNorm].fg = drw_clr_create(drw, normfgcolor, OPAQUE); -+ scheme[SchemeSel].border = drw_clr_create(drw, selbordercolor, borderalpha); -+ scheme[SchemeSel].bg = drw_clr_create(drw, selbgcolor, baralpha); -+ scheme[SchemeSel].fg = drw_clr_create(drw, selfgcolor, OPAQUE); - /* init bars */ - updatebars(); - updatestatus(); -@@ -1803,15 +1812,17 @@ updatebars(void) - Monitor *m; - XSetWindowAttributes wa = { - .override_redirect = True, -- .background_pixmap = ParentRelative, -+ .background_pixel = 0, -+ .border_pixel = 0, -+ .colormap = cmap, - .event_mask = ButtonPressMask|ExposureMask - }; - for (m = mons; m; m = m->next) { - if (m->barwin) - continue; -- m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen), -- CopyFromParent, DefaultVisual(dpy, screen), -- CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); -+ m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, depth, -+ InputOutput, visual, -+ CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &wa); - XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); - XMapRaised(dpy, m->barwin); - } -@@ -2112,6 +2123,43 @@ xerrorstart(Display *dpy, XErrorEvent *ee) - } - - void -+xinitvisual() -+{ -+ 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) { -+ visual = DefaultVisual(dpy, screen); -+ depth = DefaultDepth(dpy, screen); -+ cmap = DefaultColormap(dpy, screen); -+ } -+} -+ -+void - zoom(const Arg *arg) - { - Client *c = selmon->sel; --- -2.1.4 - diff --git a/dwm.suckless.org/patches/dwm-6.0-attachabove.diff b/dwm.suckless.org/patches/dwm-6.0-attachabove.diff @@ -1,63 +0,0 @@ -Author: Jan Christoph Ebersbach <jceb@e-jc.de> -URL: http://dwm.suckless.org/patches/attachabove -attachabove makes new clients attach above the selected client (instead of -always becoming the new master) – basically how Xmonad does it. - -diff -r ec4baab78314 dwm.c ---- a/dwm.c Mon Dec 19 15:38:30 2011 +0100 -+++ b/dwm.c Fri Apr 06 08:23:34 2012 +0200 -@@ -160,6 +160,7 @@ - static void arrange(Monitor *m); - static void arrangemon(Monitor *m); - static void attach(Client *c); -+static void attachabove(Client *c); - static void attachstack(Client *c); - static void buttonpress(XEvent *e); - static void checkotherwm(void); -@@ -418,6 +419,19 @@ - } - - void -+attachabove(Client *c) { -+ if(c->mon->sel == NULL || c->mon->sel == c->mon->clients || c->mon->sel->isfloating) { -+ attach(c); -+ return; -+ } -+ -+ Client *at; -+ for(at = c->mon->clients; at->next != c->mon->sel; at = at->next); -+ c->next = at->next; -+ at->next = c; -+} -+ -+void - attachstack(Client *c) { - c->snext = c->mon->stack; - c->mon->stack = c; -@@ -1155,7 +1169,7 @@ - c->isfloating = c->oldstate = trans != None || c->isfixed; - if(c->isfloating) - XRaiseWindow(dpy, c->win); -- attach(c); -+ attachabove(c); - attachstack(c); - XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */ - setclientstate(c, NormalState); -@@ -1480,7 +1494,7 @@ - detachstack(c); - c->mon = m; - c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ -- attach(c); -+ attachabove(c); - attachstack(c); - focus(NULL); - arrange(NULL); -@@ -1900,7 +1914,7 @@ - m->clients = c->next; - detachstack(c); - c->mon = mons; -- attach(c); -+ attachabove(c); - attachstack(c); - } - if(m == selmon) diff --git a/dwm.suckless.org/patches/dwm-6.0-attachaside.diff b/dwm.suckless.org/patches/dwm-6.0-attachaside.diff @@ -1,57 +0,0 @@ -diff --git a/dwm.c b/dwm.c -index 1bbb4b3..b2aa1c8 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -146,6 +146,7 @@ static Bool applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool inter - static void arrange(Monitor *m); - static void arrangemon(Monitor *m); - static void attach(Client *c); -+static void attachaside(Client *c); - static void attachstack(Client *c); - static void buttonpress(XEvent *e); - static void checkotherwm(void); -@@ -401,6 +402,17 @@ attach(Client *c) { - } - - void -+attachaside(Client *c) { -+ Client *at = nexttiled(c->mon->clients); -+ if(c->mon->sel == NULL || c->mon->sel->isfloating || !at) { -+ attach(c); -+ return; -+ } -+ c->next = at->next; -+ at->next = c; -+} -+ -+void - attachstack(Client *c) { - c->snext = c->mon->stack; - c->mon->stack = c; -@@ -1051,7 +1063,7 @@ manage(Window w, XWindowAttributes *wa) { - c->isfloating = c->oldstate = trans != None || c->isfixed; - if(c->isfloating) - XRaiseWindow(dpy, c->win); -- attach(c); -+ attachaside(c); - attachstack(c); - XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, - (unsigned char *) &(c->win), 1); -@@ -1383,7 +1395,7 @@ sendmon(Client *c, Monitor *m) { - detachstack(c); - c->mon = m; - c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ -- attach(c); -+ attachaside(c); - attachstack(c); - focus(NULL); - arrange(NULL); -@@ -1818,7 +1830,7 @@ updategeom(void) { - m->clients = c->next; - detachstack(c); - c->mon = mons; -- attach(c); -+ attachaside(c); - attachstack(c); - } - if(m == selmon) diff --git a/dwm.suckless.org/patches/dwm-6.0-autoresize.diff b/dwm.suckless.org/patches/dwm-6.0-autoresize.diff @@ -1,35 +0,0 @@ -diff --git a/dwm.c b/dwm.c -index e3bf6f4..8a2c646 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -91,7 +91,7 @@ struct Client { - int basew, baseh, incw, inch, maxw, maxh, minw, minh; - int bw, oldbw; - unsigned int tags; -- Bool isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; -+ Bool isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, needresize; - Client *next; - Client *snext; - Monitor *mon; -@@ -633,6 +633,8 @@ configurerequest(XEvent *e) { - configure(c); - if(ISVISIBLE(c)) - XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); -+ else -+ c->needresize=1; - } - else - configure(c); -@@ -1663,6 +1665,12 @@ showhide(Client *c) { - return; - if(ISVISIBLE(c)) { /* show clients top down */ - XMoveWindow(dpy, c->win, c->x, c->y); -+ if(c->needresize) { -+ c->needresize=0; -+ XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); -+ } else { -+ XMoveWindow(dpy, c->win, c->x, c->y); -+ } - if((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen) - resize(c, c->x, c->y, c->w, c->h, False); - showhide(c->snext); diff --git a/dwm.suckless.org/patches/dwm-6.0-autostart.diff b/dwm.suckless.org/patches/dwm-6.0-autostart.diff @@ -1,32 +0,0 @@ -diff -r c794a9f5ae5e dwm.c ---- a/dwm.c Sun Jul 08 09:45:53 2012 +0200 -+++ b/dwm.c Tue Oct 02 16:26:04 2012 +0200 -@@ -213,6 +213,7 @@ - static void resizemouse(const Arg *arg); - static void restack(Monitor *m); - static void run(void); -+static void runAutostart(void); - static void scan(void); - static Bool sendevent(Client *c, Atom proto); - static void sendmon(Client *c, Monitor *m); -@@ -1460,6 +1461,12 @@ - } - - void -+runAutostart(void) { -+ system("cd ~/.dwm; ./autostart_blocking.sh"); -+ system("cd ~/.dwm; ./autostart.sh &"); -+} -+ -+void - scan(void) { - unsigned int i, num; - Window d1, d2, *wins = NULL; -@@ -2178,6 +2185,7 @@ - checkotherwm(); - setup(); - scan(); -+ runAutostart(); - run(); - cleanup(); - XCloseDisplay(dpy); diff --git a/dwm.suckless.org/patches/dwm-6.0-bottommargin.diff b/dwm.suckless.org/patches/dwm-6.0-bottommargin.diff @@ -1,26 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 77ff358..203d354 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -12,6 +12,7 @@ static const unsigned int borderpx = 1; /* border pixel of windows */ - static const unsigned int snap = 32; /* snap pixel */ - static const Bool showbar = True; /* False means no bar */ - static const Bool topbar = True; /* False means bottom bar */ -+static const unsigned int bottommargin = 20; /* Margin at the bottom for another bar */ - - /* tagging */ - static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; -diff --git a/dwm.c b/dwm.c -index 1d78655..cece290 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -1841,6 +1841,9 @@ updatebarpos(Monitor *m) { - m->wh = m->mh; - if(m->showbar) { - m->wh -= bh; -+ m->wh -= marginbottom; -+ if(!m->topbar) -+ m->wy += marginbottom; - m->by = m->topbar ? m->wy : m->wy + m->wh; - m->wy = m->topbar ? m->wy + bh : m->wy; - } diff --git a/dwm.suckless.org/patches/dwm-6.0-bstack.diff b/dwm.suckless.org/patches/dwm-6.0-bstack.diff @@ -1,91 +0,0 @@ -diff -r ec4baab78314 bstack.c ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/bstack.c Tue Feb 28 11:28:54 2012 -0500 -@@ -0,0 +1,33 @@ -+static void -+bstack(Monitor *m) { -+ int w, h, mh, mx, tx, ty, tw; -+ unsigned int i, n; -+ Client *c; -+ -+ for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); -+ if(n == 0) -+ return; -+ if(n > m->nmaster) { -+ mh = m->nmaster ? m->mfact * m->wh : 0; -+ tw = m->ww / (n - m->nmaster); -+ ty = m->wy + mh; -+ } -+ else { -+ mh = m->wh; -+ tw = m->ww; -+ ty = m->wy; -+ } -+ for(i = mx = 0, tx = m->wx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { -+ if(i < m->nmaster) { -+ w = (m->ww - mx) / (MIN(n, m->nmaster) - i); -+ resize(c, m->wx + mx, m->wy, w - (2 * c->bw), mh - (2 * c->bw), False); -+ mx += WIDTH(c); -+ } -+ else { -+ h = m->wh - mh; -+ resize(c, tx, ty, tw - (2 * c->bw), h - (2 * c->bw), False); -+ if(tw != m->ww) -+ tx += WIDTH(c); -+ } -+ } -+} -diff -r ec4baab78314 bstackhoriz.c ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/bstackhoriz.c Tue Feb 28 11:28:54 2012 -0500 -@@ -0,0 +1,31 @@ -+static void -+bstackhoriz(Monitor *m) { -+ int w, mh, mx, tx, ty, th; -+ unsigned int i, n; -+ Client *c; -+ -+ for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); -+ if(n == 0) -+ return; -+ if(n > m->nmaster) { -+ mh = m->nmaster ? m->mfact * m->wh : 0; -+ th = (m->wh - mh) / (n - m->nmaster); -+ ty = m->wy + mh; -+ } -+ else { -+ th = mh = m->wh; -+ ty = m->wy; -+ } -+ for(i = mx = 0, tx = m->wx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { -+ if(i < m->nmaster) { -+ w = (m->ww - mx) / (MIN(n, m->nmaster) - i); -+ resize(c, m->wx + mx, m->wy, w - (2 * c->bw), mh - (2 * c->bw), False); -+ mx += WIDTH(c); -+ } -+ else { -+ resize(c, tx, ty, m->ww - (2 * c->bw), th - (2 * c->bw), False); -+ if(th != m->wh) -+ ty += HEIGHT(c); -+ } -+ } -+} -diff -r ec4baab78314 config.def.h ---- a/config.def.h Mon Dec 19 15:38:30 2011 +0100 -+++ b/config.def.h Tue Feb 28 11:28:54 2012 -0500 -@@ -27,11 +27,15 @@ static const float mfact = 0.55; /* - static const int nmaster = 1; /* number of clients in master area */ - static const Bool resizehints = True; /* True means respect size hints in tiled resizals */ - -+#include "bstack.c" -+#include "bstackhoriz.c" - static const Layout layouts[] = { - /* symbol arrange function */ - { "[]=", tile }, /* first entry is default */ - { "><>", NULL }, /* no layout function means floating behavior */ - { "[M]", monocle }, -+ { "TTT", bstack }, -+ { "===", bstackhoriz }, - }; - - /* key definitions */ diff --git a/dwm.suckless.org/patches/dwm-6.1-ispermanent.diff b/dwm.suckless.org/patches/dwm-6.0-ispermanent.diff diff --git a/dwm.suckless.org/patches/dwm-6.0-keycode.diff b/dwm.suckless.org/patches/dwm-6.0-keycode.diff @@ -1,133 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 875885b..2ef8679 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -55,40 +55,40 @@ static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", font, "-nb - static const char *termcmd[] = { "st", NULL }; - - static Key keys[] = { -- /* modifier key function argument */ -- { MODKEY, XK_p, spawn, {.v = dmenucmd } }, -- { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, -- { MODKEY, XK_b, togglebar, {0} }, -- { MODKEY, XK_j, focusstack, {.i = +1 } }, -- { MODKEY, XK_k, focusstack, {.i = -1 } }, -- { MODKEY, XK_i, incnmaster, {.i = +1 } }, -- { MODKEY, XK_d, incnmaster, {.i = -1 } }, -- { MODKEY, XK_h, setmfact, {.f = -0.05} }, -- { MODKEY, XK_l, setmfact, {.f = +0.05} }, -- { MODKEY, XK_Return, zoom, {0} }, -- { MODKEY, XK_Tab, view, {0} }, -- { MODKEY|ShiftMask, XK_c, killclient, {0} }, -- { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, -- { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, -- { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, -- { MODKEY, XK_space, setlayout, {0} }, -- { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, -- { MODKEY, XK_0, view, {.ui = ~0 } }, -- { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, -- { MODKEY, XK_comma, focusmon, {.i = -1 } }, -- { MODKEY, XK_period, focusmon, {.i = +1 } }, -- { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, -- { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, -- TAGKEYS( XK_1, 0) -- TAGKEYS( XK_2, 1) -- TAGKEYS( XK_3, 2) -- TAGKEYS( XK_4, 3) -- TAGKEYS( XK_5, 4) -- TAGKEYS( XK_6, 5) -- TAGKEYS( XK_7, 6) -- TAGKEYS( XK_8, 7) -- TAGKEYS( XK_9, 8) -- { MODKEY|ShiftMask, XK_q, quit, {0} }, -+ /* modifier key function argument */ -+ { MODKEY, 33, spawn, {.v = dmenucmd } }, // p -+ { MODKEY|ShiftMask, 36, spawn, {.v = termcmd } }, // Return -+ { MODKEY, 56, togglebar, {0} }, // b -+ { MODKEY, 44, focusstack, {.i = +1 } }, // j -+ { MODKEY, 45, focusstack, {.i = -1 } }, // k -+ { MODKEY, 31, incnmaster, {.i = +1 } }, // i -+ { MODKEY, 40, incnmaster, {.i = -1 } }, // d -+ { MODKEY, 43, setmfact, {.f = -0.05} }, // h -+ { MODKEY, 46, setmfact, {.f = +0.05} }, // l -+ { MODKEY, 36, zoom, {0} }, // Return -+ { MODKEY, 23, view, {0} }, // Tab -+ { MODKEY|ShiftMask, 54, killclient, {0} }, // c -+ { MODKEY, 28, setlayout, {.v = &layouts[0]} }, // t -+ { MODKEY, 41, setlayout, {.v = &layouts[1]} }, // f -+ { MODKEY, 58, setlayout, {.v = &layouts[2]} }, // m -+ { MODKEY, 65, setlayout, {0} }, // space -+ { MODKEY|ShiftMask, 65, togglefloating, {0} }, // space -+ { MODKEY, 19, view, {.ui = ~0 } }, // 0 -+ { MODKEY|ShiftMask, 19, tag, {.ui = ~0 } }, // 0 -+ { MODKEY, 59, focusmon, {.i = -1 } }, // comma -+ { MODKEY, 60, focusmon, {.i = +1 } }, // period -+ { MODKEY|ShiftMask, 59, tagmon, {.i = -1 } }, // comma -+ { MODKEY|ShiftMask, 60, tagmon, {.i = +1 } }, // period -+ TAGKEYS( 10, 0) // 1 -+ TAGKEYS( 11, 1) // 2 -+ TAGKEYS( 12, 2) // 3 -+ TAGKEYS( 13, 3) // 4 -+ TAGKEYS( 14, 4) // 5 -+ TAGKEYS( 15, 5) // 6 -+ TAGKEYS( 16, 6) // 7 -+ TAGKEYS( 17, 7) // 8 -+ TAGKEYS( 18, 8) // 9 -+ { MODKEY|ShiftMask, 24, quit, {0} }, // q - }; - - /* button definitions */ -diff --git a/dwm.c b/dwm.c -index 1bbb4b3..54ddf00 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -31,7 +31,6 @@ - #include <sys/types.h> - #include <sys/wait.h> - #include <X11/cursorfont.h> --#include <X11/keysym.h> - #include <X11/Xatom.h> - #include <X11/Xlib.h> - #include <X11/Xproto.h> -@@ -100,7 +99,7 @@ struct Client { - - typedef struct { - unsigned int mod; -- KeySym keysym; -+ KeyCode keycode; - void (*func)(const Arg *); - const Arg arg; - } Key; -@@ -945,14 +944,12 @@ grabkeys(void) { - { - unsigned int i, j; - unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; -- KeyCode code; - - XUngrabKey(dpy, AnyKey, AnyModifier, root); - for(i = 0; i < LENGTH(keys); i++) -- if((code = XKeysymToKeycode(dpy, keys[i].keysym))) -- for(j = 0; j < LENGTH(modifiers); j++) -- XGrabKey(dpy, code, keys[i].mod | modifiers[j], root, -- True, GrabModeAsync, GrabModeAsync); -+ for(j = 0; j < LENGTH(modifiers); j++) -+ XGrabKey(dpy, keys[i].keycode, keys[i].mod | modifiers[j], root, -+ True, GrabModeAsync, GrabModeAsync); - } - } - -@@ -976,13 +973,11 @@ isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) { - void - keypress(XEvent *e) { - unsigned int i; -- KeySym keysym; - XKeyEvent *ev; - - ev = &e->xkey; -- keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); - for(i = 0; i < LENGTH(keys); i++) -- if(keysym == keys[i].keysym -+ if(ev->keycode == keys[i].keycode - && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) - && keys[i].func) - keys[i].func(&(keys[i].arg)); diff --git a/dwm.suckless.org/patches/dwm-6.0-pertag_without_bar.diff b/dwm.suckless.org/patches/dwm-6.0-pertag_without_bar.diff @@ -1,7 +1,7 @@ Author: Jan Christoph Ebersbach <jceb@e-jc.de>, Troy Sankey <sankeytms@gmail.com> This modified pertag patch keeps the bar static. It is based on Jan -Christoph Ebersbach's dwm-6.0-pertag.diff. +Christoph Ebersbach's dwm-pertag-6.0.diff. diff --git a/dwm.c b/dwm.c index 1d78655..bd0a7d9 100644 diff --git a/dwm.suckless.org/patches/dwm-6.0-single_window_no_border.diff b/dwm.suckless.org/patches/dwm-6.0-single_window_no_border.diff @@ -1,97 +0,0 @@ -Author: Jan Christoph Ebersbach <jceb@e-jc.de> -URL: http://dwm.suckless.org/patches/noborder -This patch removes the border when there is just one window visible in tiled or -monocle layout. - -diff -r ec4baab78314 dwm.c ---- a/dwm.c Mon Dec 19 15:38:30 2011 +0100 -+++ b/dwm.c Fri Apr 06 08:23:31 2012 +0200 -@@ -1191,7 +1191,7 @@ - - void - monocle(Monitor *m) { -- unsigned int n = 0; -+ unsigned int n = 0, r = 0; - Client *c; - - for(c = m->clients; c; c = c->next) -@@ -1199,8 +1199,17 @@ - n++; - if(n > 0) /* override layout symbol */ - snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n); -- for(c = nexttiled(m->clients); c; c = nexttiled(c->next)) -- resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, False); -+ for(c = nexttiled(m->clients); c; c = nexttiled(c->next)) { -+ /* remove border when in monocle layout */ -+ if(c->bw) { -+ c->oldbw = c->bw; -+ c->bw = 0; -+ r = 1; -+ } -+ resize(c, m->wx, m->wy, m->ww - (2 * c->bw), m->wh - (2 * c->bw), False); -+ if(r) -+ resizeclient(c, m->wx, m->wy, m->ww - (2 * c->bw), m->wh - (2 * c->bw)); -+ } - } - - void -@@ -1703,7 +1712,7 @@ - - void - tile(Monitor *m) { -- unsigned int i, n, h, mw, my, ty; -+ unsigned int i, n, h, mw, my, ty, r; - Client *c; - - for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); -@@ -1714,17 +1723,36 @@ - mw = m->nmaster ? m->ww * m->mfact : 0; - else - mw = m->ww; -- for(i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) -+ for(i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++, r = 0) { -+ if(n == 1) { -+ if (c->bw) { -+ /* remove border when only one window is on the current tag */ -+ c->oldbw = c->bw; -+ c->bw = 0; -+ r = 1; -+ } -+ } -+ else if(!c->bw && c->oldbw) { -+ /* restore border when more than one window is displayed */ -+ c->bw = c->oldbw; -+ c->oldbw = 0; -+ r = 1; -+ } - if(i < m->nmaster) { - h = (m->wh - my) / (MIN(n, m->nmaster) - i); - resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), False); -+ if(r) -+ resizeclient(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw)); - my += HEIGHT(c); - } - else { - h = (m->wh - ty) / (n - i); - resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), False); -+ if(r) -+ resizeclient(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw)); - ty += HEIGHT(c); - } -+ } - } - - void -@@ -1741,6 +1769,12 @@ - return; - selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; - if(selmon->sel->isfloating) -+ /* restore border when moving window into floating mode */ -+ if(!selmon->sel->bw && selmon->sel->oldbw) { -+ selmon->sel->bw = selmon->sel->oldbw; -+ selmon->sel->oldbw = 0; -+ } -+ if(selmon->sel->isfloating) - resize(selmon->sel, selmon->sel->x, selmon->sel->y, - selmon->sel->w, selmon->sel->h, False); - arrange(selmon); diff --git a/dwm.suckless.org/patches/dwm-6.1-attachabove.diff b/dwm.suckless.org/patches/dwm-6.1-attachabove.diff @@ -1,63 +0,0 @@ -Author: Jan Christoph Ebersbach <jceb@e-jc.de> -URL: http://dwm.suckless.org/patches/attachabove -attachabove makes new clients attach above the selected client (instead of -always becoming the new master) - basically how Xmonad does it. - ---- dwm/dwm.c.orig 2015-11-22 10:48:28.288368772 -0700 -+++ dwm/dwm.c 2015-11-22 10:51:45.308360761 -0700 -@@ -147,6 +147,7 @@ static int applysizehints(Client *c, int - static void arrange(Monitor *m); - static void arrangemon(Monitor *m); - static void attach(Client *c); -+static void attachabove(Client *c); - static void attachstack(Client *c); - static void buttonpress(XEvent *e); - static void checkotherwm(void); -@@ -406,6 +407,20 @@ attach(Client *c) - } - - void -+attachabove(Client *c) -+{ -+ if(c->mon->sel == NULL || c->mon->sel == c->mon->clients || c->mon->sel->isfloating) { -+ attach(c); -+ return; -+ } -+ -+ Client *at; -+ for(at = c->mon->clients; at->next != c->mon->sel; at = at->next); -+ c->next = at->next; -+ at->next = c; -+} -+ -+void - attachstack(Client *c) - { - c->snext = c->mon->stack; -@@ -1076,7 +1091,7 @@ manage(Window w, XWindowAttributes *wa) - c->isfloating = c->oldstate = trans != None || c->isfixed; - if (c->isfloating) - XRaiseWindow(dpy, c->win); -- attach(c); -+ attachabove(c); - attachstack(c); - XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, - (unsigned char *) &(c->win), 1); -@@ -1434,7 +1449,7 @@ sendmon(Client *c, Monitor *m) - detachstack(c); - c->mon = m; - c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ -- attach(c); -+ attachabove(c); - attachstack(c); - focus(NULL); - arrange(NULL); -@@ -1891,7 +1906,7 @@ updategeom(void) - m->clients = c->next; - detachstack(c); - c->mon = mons; -- attach(c); -+ attachabove(c); - attachstack(c); - } - if (m == selmon) diff --git a/dwm.suckless.org/patches/dwm-6.1-better-borders.diff b/dwm.suckless.org/patches/dwm-6.1-better-borders.diff @@ -1,91 +0,0 @@ -Author: Eric Pruitt, https://github.com/ericpruitt/ -Description: This patch makes dwm remove borders when only one, non-floating -window is visible. Additionally, any windows that are the same size as the -monitor are considered full-screen and their borders removed accordingly. - -diff --git a/dwm.c b/dwm.c -index 0362114..03fddb6 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -393,9 +393,24 @@ arrange(Monitor *m) - void - arrangemon(Monitor *m) - { -+ int n = 0; -+ Client *c; - strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); -- if (m->lt[m->sellt]->arrange) -- m->lt[m->sellt]->arrange(m); -+ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); -+ if (n > 1 || !m->lt[m->sellt]->arrange) { -+ for (c = m->clients; c; c = c->next) { -+ if (ISVISIBLE(c) && (!m->lt[m->sellt]->arrange || !c->isfloating) && (c->bw != borderpx)) { -+ c->oldbw = c->oldbw; -+ c->bw = borderpx; -+ resizeclient(c, m->wx, m->wy, m->ww - (2 * c->bw), m->wh - (2 * c->bw)); -+ } -+ } -+ if (m->lt[m->sellt]->arrange) { -+ m->lt[m->sellt]->arrange(m); -+ } -+ } else { -+ monocle(m); -+ } - } - - void -@@ -1117,16 +1132,25 @@ maprequest(XEvent *e) - void - monocle(Monitor *m) - { -- unsigned int n = 0; -+ unsigned int n = 0, r = 0; - Client *c; - - for (c = m->clients; c; c = c->next) - if (ISVISIBLE(c)) - n++; -- if (n > 0) /* override layout symbol */ -+ if (n > 0 && m->lt[m->sellt]->arrange == monocle) /* override layout symbol */ - snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n); -- for (c = nexttiled(m->clients); c; c = nexttiled(c->next)) -- resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); -+ for(c = nexttiled(m->clients); c; c = nexttiled(c->next)) { -+ if (c->bw) { -+ c->oldbw = c->bw; -+ c->bw = 0; -+ r = 1; -+ } -+ resize(c, m->wx, m->wy, m->ww - (2 * c->bw), m->wh - (2 * c->bw), False); -+ if(r) { -+ resizeclient(c, m->wx, m->wy, m->ww - (2 * c->bw), m->wh - (2 * c->bw)); -+ } -+ } - } - - void -@@ -1706,9 +1730,11 @@ togglefloating(const Arg *arg) - if (selmon->sel->isfullscreen) /* no support for fullscreen windows */ - return; - selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; -- if (selmon->sel->isfloating) -- resize(selmon->sel, selmon->sel->x, selmon->sel->y, -- selmon->sel->w, selmon->sel->h, 0); -+ if (selmon->sel->isfloating) { -+ selmon->sel->oldbw = selmon->sel->bw; -+ selmon->sel->bw = borderpx; -+ resizeclient(selmon->sel, selmon->wx, selmon->wy, selmon->ww - (2 * selmon->sel->bw), selmon->wh - (2 * selmon->sel->bw)); -+ } - arrange(selmon); - } - -@@ -2003,7 +2029,8 @@ updatewindowtype(Client *c) - Atom state = getatomprop(c, netatom[NetWMState]); - Atom wtype = getatomprop(c, netatom[NetWMWindowType]); - -- if (state == netatom[NetWMFullscreen]) -+ if(state == netatom[NetWMFullscreen] || -+ (WIDTH(c) >= (c->mon->mx + c->mon->mw) && (HEIGHT(c) >= (c->mon->my + c->mon->mh)))) - setfullscreen(c, 1); - if (wtype == netatom[NetWMWindowTypeDialog]) - c->isfloating = 1; diff --git a/dwm.suckless.org/patches/dwm-6.1-centeredmaster.diff b/dwm.suckless.org/patches/dwm-6.1-centeredmaster.diff @@ -1,59 +0,0 @@ -diff --git a/dwm.c b/dwm.c -index 0362114..fa5ae4c 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -209,6 +209,7 @@ static void spawn(const Arg *arg); - static void tag(const Arg *arg); - static void tagmon(const Arg *arg); - static void tile(Monitor *); -+static void centeredmaster(Monitor *); - static void togglebar(const Arg *arg); - static void togglefloating(const Arg *arg); - static void toggletag(const Arg *arg); -@@ -1690,6 +1691,46 @@ tile(Monitor *m) - } - - void -+centeredmaster(Monitor *m) -+{ -+ unsigned int i, n, w, mh, mw, mx, mxo, my, myo, tx; -+ Client *c; -+ -+ // Count number of clients in the selected monitor -+ for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); -+ if(n == 0) -+ return; -+ -+ // initialize nmaster area -+ if(n > m->nmaster) { -+ // go mfact box in the center if more than nmaster clients -+ mw = m->nmaster ? m->ww * m->mfact : 0; -+ mh = m->nmaster ? m->wh * m->mfact : 0; -+ mx = mxo = (m->ww - mw) / 2; -+ my = myo = (m->wh - mh) / 2; -+ } else { -+ // Go fullscreen if all clients are in the master area -+ mh = m->wh; -+ mw = m->ww; -+ mx = mxo = 0; -+ my = mxo = 0; -+ } -+ -+ for(i = tx = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) -+ if(i < m->nmaster) { -+ // nmaster clients are stacked horizontally, in the center of the screen -+ w = (mw + mxo - mx) / (MIN(n, m->nmaster) - i); -+ resize(c, m->wx + mx, m->wy + my, w - (2*c->bw), mh - (2*c->bw), False); -+ mx += WIDTH(c); -+ } else { -+ // Stack clients are stacked horizontally -+ w = (m->ww - tx) / (n - i); -+ resize(c, m->wx + tx, m->wy, w - (2*c->bw), m->wh - (2*c->bw), False); -+ tx += WIDTH(c); -+ } -+} -+ -+void - togglebar(const Arg *arg) - { - selmon->showbar = !selmon->showbar; diff --git a/dwm.suckless.org/patches/dwm-6.1-cfacts.diff b/dwm.suckless.org/patches/dwm-6.1-cfacts.diff @@ -1,8 +1,8 @@ diff --git a/config.def.h b/config.def.h -index 875885b..809788b 100644 +index 7054c06..9878dbf 100644 --- a/config.def.h +++ b/config.def.h -@@ -65,6 +65,9 @@ static Key keys[] = { +@@ -68,6 +68,9 @@ static Key keys[] = { { MODKEY, XK_d, incnmaster, {.i = -1 } }, { MODKEY, XK_h, setmfact, {.f = -0.05} }, { MODKEY, XK_l, setmfact, {.f = +0.05} }, @@ -13,10 +13,10 @@ index 875885b..809788b 100644 { MODKEY, XK_Tab, view, {0} }, { MODKEY|ShiftMask, XK_c, killclient, {0} }, diff --git a/dwm.c b/dwm.c -index 1bbb4b3..4ff74cc 100644 +index 0362114..881afe6 100644 --- a/dwm.c +++ b/dwm.c -@@ -86,6 +86,7 @@ typedef struct Client Client; +@@ -87,6 +87,7 @@ typedef struct Client Client; struct Client { char name[256]; float mina, maxa; @@ -24,23 +24,23 @@ index 1bbb4b3..4ff74cc 100644 int x, y, w, h; int oldx, oldy, oldw, oldh; int basew, baseh, incw, inch, maxw, maxh, minw, minh; -@@ -200,6 +201,7 @@ static void setclientstate(Client *c, long state); +@@ -201,6 +202,7 @@ static void setclientstate(Client *c, long state); static void setfocus(Client *c); - static void setfullscreen(Client *c, Bool fullscreen); + static void setfullscreen(Client *c, int fullscreen); static void setlayout(const Arg *arg); +static void setcfact(const Arg *arg); static void setmfact(const Arg *arg); static void setup(void); static void showhide(Client *c); -@@ -1027,6 +1029,7 @@ manage(Window w, XWindowAttributes *wa) { +@@ -1052,6 +1054,7 @@ manage(Window w, XWindowAttributes *wa) c->w = c->oldw = wa->width; c->h = c->oldh = wa->height; c->oldbw = wa->border_width; + c->cfact = 1.0; - if(c->x + WIDTH(c) > c->mon->mx + c->mon->mw) + if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw) c->x = c->mon->mx + c->mon->mw - WIDTH(c); -@@ -1473,6 +1476,23 @@ setlayout(const Arg *arg) { +@@ -1528,6 +1531,23 @@ setlayout(const Arg *arg) drawbar(selmon); } @@ -63,38 +63,37 @@ index 1bbb4b3..4ff74cc 100644 + /* arg > 1.0 will set mfact absolutly */ void - setmfact(const Arg *arg) { -@@ -1602,9 +1622,15 @@ tagmon(const Arg *arg) { - void - tile(Monitor *m) { + setmfact(const Arg *arg) +@@ -1667,9 +1687,15 @@ void + tile(Monitor *m) + { unsigned int i, n, h, mw, my, ty; + float mfacts = 0, sfacts = 0; Client *c; -- for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); -+ for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) { -+ if(n < m->nmaster) +- for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); ++ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) { ++ if (n < m->nmaster) + mfacts += c->cfact; + else + sfacts += c->cfact; + } - if(n == 0) + if (n == 0) return; -@@ -1614,14 +1640,16 @@ tile(Monitor *m) { +@@ -1679,13 +1705,15 @@ tile(Monitor *m) mw = m->ww; - for(i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) - if(i < m->nmaster) { + for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) + if (i < m->nmaster) { - h = (m->wh - my) / (MIN(n, m->nmaster) - i); + h = (m->wh - my) * (c->cfact / mfacts); - resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), False); + resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); my += HEIGHT(c); + mfacts -= c->cfact; - } - else { + } else { - h = (m->wh - ty) / (n - i); -+ h = (m->wh - ty) * (c->cfact / sfacts); - resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), False); ++ h = (m->wh - ty) / (c->cfact / sfacts); + resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0); ty += HEIGHT(c); + sfacts -= c->cfact; } diff --git a/dwm.suckless.org/patches/dwm-6.1-dwmfifo.diff b/dwm.suckless.org/patches/dwm-6.1-dwmfifo.diff @@ -1,215 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 875885b..c0a01fa 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -108,3 +108,65 @@ static Button buttons[] = { - { ClkTagBar, MODKEY, Button3, toggletag, {0} }, - }; - -+static const char *dwmfifo = "/tmp/dwm.fifo"; -+static Command commands[] = { -+ { "dmenu", spawn, {.v = dmenucmd} }, -+ { "term", spawn, {.v = termcmd} }, -+ { "togglebar", togglebar, {0} }, -+ { "focusstack+", focusstack, {.i = +1} }, -+ { "focusstack-", focusstack, {.i = -1} }, -+ { "incnmaster+", incnmaster, {.i = +1} }, -+ { "incnmaster-", incnmaster, {.i = -1} }, -+ { "setmfact+", setmfact, {.f = +0.05} }, -+ { "setmfact-", setmfact, {.f = -0.05} }, -+ { "zoom", zoom, {0} }, -+ { "view", view, {0} }, -+ { "killclient", killclient, {0} }, -+ { "setlayout-tiled", setlayout, {.v = &layouts[0]} }, -+ { "setlayout-float", setlayout, {.v = &layouts[1]} }, -+ { "setlayout-mono", setlayout, {.v = &layouts[2]} }, -+ { "togglelayout", setlayout, {0} }, -+ { "togglefloating", togglefloating, {0} }, -+ { "viewall", view, {.ui = ~0} }, -+ { "tag", tag, {.ui = ~0} }, -+ { "focusmon+", focusmon, {.i = +1} }, -+ { "focusmon-", focusmon, {.i = -1} }, -+ { "tagmon+", tagmon, {.i = +1} }, -+ { "tagmon-", tagmon, {.i = -1} }, -+ { "view1", view, {.ui = 1 << 0} }, -+ { "view2", view, {.ui = 1 << 1} }, -+ { "view3", view, {.ui = 1 << 2} }, -+ { "view4", view, {.ui = 1 << 3} }, -+ { "view5", view, {.ui = 1 << 4} }, -+ { "view6", view, {.ui = 1 << 5} }, -+ { "view7", view, {.ui = 1 << 6} }, -+ { "view8", view, {.ui = 1 << 7} }, -+ { "view9", view, {.ui = 1 << 8} }, -+ { "toggleview1", toggleview, {.ui = 1 << 0} }, -+ { "toggleview2", toggleview, {.ui = 1 << 1} }, -+ { "toggleview3", toggleview, {.ui = 1 << 2} }, -+ { "toggleview4", toggleview, {.ui = 1 << 3} }, -+ { "toggleview5", toggleview, {.ui = 1 << 4} }, -+ { "toggleview6", toggleview, {.ui = 1 << 5} }, -+ { "toggleview7", toggleview, {.ui = 1 << 6} }, -+ { "toggleview8", toggleview, {.ui = 1 << 7} }, -+ { "toggleview9", toggleview, {.ui = 1 << 8} }, -+ { "tag1", tag, {.ui = 1 << 0} }, -+ { "tag2", tag, {.ui = 1 << 1} }, -+ { "tag3", tag, {.ui = 1 << 2} }, -+ { "tag4", tag, {.ui = 1 << 3} }, -+ { "tag5", tag, {.ui = 1 << 4} }, -+ { "tag6", tag, {.ui = 1 << 5} }, -+ { "tag7", tag, {.ui = 1 << 6} }, -+ { "tag8", tag, {.ui = 1 << 7} }, -+ { "tag9", tag, {.ui = 1 << 8} }, -+ { "toggletag1", toggletag, {.ui = 1 << 0} }, -+ { "toggletag2", toggletag, {.ui = 1 << 1} }, -+ { "toggletag3", toggletag, {.ui = 1 << 2} }, -+ { "toggletag4", toggletag, {.ui = 1 << 3} }, -+ { "toggletag5", toggletag, {.ui = 1 << 4} }, -+ { "toggletag6", toggletag, {.ui = 1 << 5} }, -+ { "toggletag7", toggletag, {.ui = 1 << 6} }, -+ { "toggletag8", toggletag, {.ui = 1 << 7} }, -+ { "toggletag9", toggletag, {.ui = 1 << 8} }, -+}; -diff --git a/dwm.c b/dwm.c -index 1bbb4b3..cd7ddd1 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -21,6 +21,7 @@ - * To understand everything else, start reading main(). - */ - #include <errno.h> -+#include <fcntl.h> - #include <locale.h> - #include <stdarg.h> - #include <signal.h> -@@ -28,6 +29,8 @@ - #include <stdlib.h> - #include <string.h> - #include <unistd.h> -+#include <sys/select.h> -+#include <sys/stat.h> - #include <sys/types.h> - #include <sys/wait.h> - #include <X11/cursorfont.h> -@@ -140,6 +143,12 @@ typedef struct { - int monitor; - } Rule; - -+typedef struct { -+ const char *name; -+ void (*func)(const Arg *arg); -+ const Arg arg; -+} Command; -+ - /* function declarations */ - static void applyrules(Client *c); - static Bool applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool interact); -@@ -161,9 +170,11 @@ static void destroynotify(XEvent *e); - static void detach(Client *c); - static void detachstack(Client *c); - static Monitor *dirtomon(int dir); -+static void dispatchcmd(void); - static void drawbar(Monitor *m); - static void drawbars(void); - static void enternotify(XEvent *e); -+static Bool evpredicate(); - static void expose(XEvent *e); - static void focus(Client *c); - static void focusin(XEvent *e); -@@ -266,6 +277,7 @@ static Drw *drw; - static Fnt *fnt; - static Monitor *mons, *selmon; - static Window root; -+static int fifofd; - - /* configuration, allows nested code to access above variables */ - #include "config.h" -@@ -485,6 +497,7 @@ cleanup(void) { - XSync(dpy, False); - XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); - XDeleteProperty(dpy, root, netatom[NetActiveWindow]); -+ close(fifofd); - } - - void -@@ -691,6 +704,25 @@ dirtomon(int dir) { - } - - void -+dispatchcmd(void) -+{ -+ int i; -+ char buf[BUFSIZ]; -+ ssize_t n; -+ -+ n = read(fifofd, buf, sizeof(buf) - 1); -+ if (n == -1) -+ die("Failed to read from DWM fifo\n"); -+ buf[n] = '\0'; -+ for (i = 0; i < LENGTH(commands); i++) { -+ if (strcmp(commands[i].name, buf) == 0) { -+ commands[i].func(&commands[i].arg); -+ break; -+ } -+ } -+} -+ -+void - drawbar(Monitor *m) { - int x, xx, w; - unsigned int i, occ = 0, urg = 0; -@@ -768,6 +800,12 @@ enternotify(XEvent *e) { - focus(c); - } - -+Bool -+evpredicate() -+{ -+ return True; -+} -+ - void - expose(XEvent *e) { - Monitor *m; -@@ -1341,11 +1379,30 @@ restack(Monitor *m) { - void - run(void) { - XEvent ev; -+ fd_set rfds; -+ int n; -+ int dpyfd, maxfd; - /* main event loop */ - XSync(dpy, False); -- while(running && !XNextEvent(dpy, &ev)) -- if(handler[ev.type]) -- handler[ev.type](&ev); /* call handler */ -+ dpyfd = ConnectionNumber(dpy); -+ maxfd = fifofd; -+ if (dpyfd > maxfd) -+ maxfd = dpyfd; -+ maxfd++; -+ while (running) { -+ FD_ZERO(&rfds); -+ FD_SET(fifofd, &rfds); -+ FD_SET(dpyfd, &rfds); -+ n = select(maxfd, &rfds, NULL, NULL, NULL); -+ if (n > 0) { -+ if (FD_ISSET(fifofd, &rfds)) -+ dispatchcmd(); -+ if (FD_ISSET(dpyfd, &rfds)) -+ while (XCheckIfEvent(dpy, &ev, evpredicate, NULL)) -+ if (handler[ev.type]) -+ handler[ev.type](&ev); /* call handler */ -+ } -+ } - } - - void -@@ -1543,6 +1600,9 @@ setup(void) { - XSelectInput(dpy, root, wa.event_mask); - grabkeys(); - focus(NULL); -+ fifofd = open(dwmfifo, O_RDWR | O_NONBLOCK); -+ if (fifofd < 0) -+ die("Failed to open DWM fifo\n"); - } - - void diff --git a/dwm.suckless.org/patches/dwm-6.1-htile.diff b/dwm.suckless.org/patches/dwm-6.1-htile.diff @@ -1,46 +0,0 @@ - -diff --git a/dwm.c b/dwm.c -index c9fdd49..783fcdb 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -214,6 +214,7 @@ static void spawn(const Arg *arg); - static void tag(const Arg *arg); - static void tagmon(const Arg *arg); - static void tile(Monitor *); -+static void htile(Monitor *); - static void togglebar(const Arg *arg); - static void togglefloating(const Arg *arg); - static void toggletag(const Arg *arg); -@@ -1699,6 +1722,32 @@ tile(Monitor *m) { - } - - void -+htile(Monitor *m) { -+ unsigned int i, n, w, mh, mx, tx; -+ Client *c; -+ -+ for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); -+ if(n == 0) -+ return; -+ -+ if(n > m->nmaster) -+ mh = m->nmaster ? m->wh * m->mfact : 0; -+ else -+ mh = m->wh; -+ for(i = mx = tx = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) -+ if(i < m->nmaster) { -+ w = (m->ww - mx) / (MIN(n, m->nmaster) - i); -+ resize(c, m->wx + mx, m->wy, w - (2*c->bw), mh - (2*c->bw), False); -+ mx += WIDTH(c); -+ } -+ else { -+ w = (m->ww - tx) / (n - i); -+ resize(c, m->wx + tx, m->wy + mh, w - (2*c->bw), m->wh - mh - (2*c->bw), False); -+ tx += WIDTH(c); -+ } -+} -+ -+void - togglebar(const Arg *arg) { - selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = !selmon->showbar; - updatebarpos(selmon); diff --git a/dwm.suckless.org/patches/dwm-6.1-monarg.diff b/dwm.suckless.org/patches/dwm-6.1-monarg.diff @@ -1,30 +0,0 @@ -diff --git a/dwm.c b/dwm.c -index d9443da..28528ed 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -176,6 +176,7 @@ static void destroynotify(XEvent *e); - static void detach(Client *c); - static void detachstack(Client *c); - static Monitor *dirtomon(int dir); -+static void dmenuspawn(const Arg *arg); - static void drawbar(Monitor *m); - static void drawbars(void); - static void drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]); -@@ -709,6 +710,17 @@ dirtomon(int dir) { - } - - void -+dmenuspawn(const Arg *arg) { -+ char monstr[2] = "0"; -+ const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-m", monstr, "-nb", -+ normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", -+ selfgcolor, NULL }; -+ Arg a = { .v = dmenucmd }; -+ monstr[0] = '0' + selmon->num; -+ spawn(&a); -+} -+ -+void - drawbar(Monitor *m) { - int x; - unsigned int i, occ = 0, urg = 0; diff --git a/dwm.suckless.org/patches/dwm-6.1-single_window_no_border.diff b/dwm.suckless.org/patches/dwm-6.1-single_window_no_border.diff @@ -1,99 +0,0 @@ -Author: Jan Christoph Ebersbach <jceb@e-jc.de> -URL: http://dwm.suckless.org/patches/noborder -This patch removes the border when there is just one window visible in tiled or -monocle layout. - ---- dwm/dwm.c.orig 2015-11-11 19:14:39.771079356 -0800 -+++ dwm/dwm.c 2015-11-11 19:14:42.821079144 -0800 -@@ -1117,7 +1117,7 @@ maprequest(XEvent *e) - void - monocle(Monitor *m) - { -- unsigned int n = 0; -+ unsigned int n = 0, r = 0; - Client *c; - - for (c = m->clients; c; c = c->next) -@@ -1125,8 +1125,17 @@ monocle(Monitor *m) - n++; - if (n > 0) /* override layout symbol */ - snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n); -- for (c = nexttiled(m->clients); c; c = nexttiled(c->next)) -- resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); -+ for(c = nexttiled(m->clients); c; c = nexttiled(c->next)) { -+ /* remove border when in monocle layout */ -+ if(c->bw) { -+ c->oldbw = c->bw; -+ c->bw = 0; -+ r = 1; -+ } -+ resize(c, m->wx, m->wy, m->ww - (2 * c->bw), m->wh - (2 * c->bw), False); -+ if(r) -+ resizeclient(c, m->wx, m->wy, m->ww - (2 * c->bw), m->wh - (2 * c->bw)); -+ } - } - - void -@@ -1666,7 +1675,7 @@ tagmon(const Arg *arg) - void - tile(Monitor *m) - { -- unsigned int i, n, h, mw, my, ty; -+ unsigned int i, n, h, mw, my, ty, r; - Client *c; - - for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); -@@ -1677,16 +1686,35 @@ tile(Monitor *m) - mw = m->nmaster ? m->ww * m->mfact : 0; - else - mw = m->ww; -- for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) -+ for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { -+ if(n == 1) { -+ if (c->bw) { -+ /* remove border when only one window is on the cu rrent tag */ -+ c->oldbw = c->bw; -+ c->bw = 0; -+ r = 1; -+ } -+ } -+ else if(!c->bw && c->oldbw) { -+ /* restore border when more than one window is displayed */ -+ c->bw = c->oldbw; -+ c->oldbw = 0; -+ r = 1; -+ } - if (i < m->nmaster) { - h = (m->wh - my) / (MIN(n, m->nmaster) - i); - resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); -+ if(r) -+ resizeclient(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw)); - my += HEIGHT(c); - } else { - h = (m->wh - ty) / (n - i); - resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0); -+ if(r) -+ resizeclient(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw)); - ty += HEIGHT(c); - } -+ } - } - - void -@@ -1706,9 +1734,15 @@ togglefloating(const Arg *arg) - if (selmon->sel->isfullscreen) /* no support for fullscreen windows */ - return; - selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; -- if (selmon->sel->isfloating) -+ if (selmon->sel->isfloating) { -+ /* restore border when moving window into floating mode */ -+ if(!selmon->sel->bw && selmon->sel->oldbw) { -+ selmon->sel->bw = selmon->sel->oldbw; -+ selmon->sel->oldbw = 0; -+ } - resize(selmon->sel, selmon->sel->x, selmon->sel->y, - selmon->sel->w, selmon->sel->h, 0); -+ } - arrange(selmon); - } - diff --git a/dwm.suckless.org/patches/dwm-6.1-swallowing.diff b/dwm.suckless.org/patches/dwm-6.1-swallowing.diff @@ -1,377 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 7054c06..d1140ff 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -24,9 +24,10 @@ static const Rule rules[] = { - * WM_CLASS(STRING) = instance, class - * WM_NAME(STRING) = title - */ -- /* class instance title tags mask isfloating monitor */ -- { "Gimp", NULL, NULL, 0, 1, -1 }, -- { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, -+ /* class instance title tags mask isfloating isterminal noswallow monitor */ -+ { "Gimp", NULL, NULL, 0, 1, 0, 0, -1 }, -+ { "Firefox", NULL, NULL, 1 << 8, 0, 0, 0, -1 }, -+ { "st-", NULL, NULL, 0, 0, 1, 1, -1 }, - }; - - /* layout(s) */ -diff --git a/dwm.c b/dwm.c -index ff7e096..b50436a 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -40,6 +40,10 @@ - #include <X11/extensions/Xinerama.h> - #endif /* XINERAMA */ - #include <X11/Xft/Xft.h> -+#ifdef SWALLOWING -+#include <X11/Xlib-xcb.h> -+#include <xcb/res.h> -+#endif - - #include "drw.h" - #include "util.h" -@@ -92,9 +96,11 @@ struct Client { - int basew, baseh, incw, inch, maxw, maxh, minw, minh; - int bw, oldbw; - unsigned int tags; -- int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; -+ int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isterminal, noswallow; -+ pid_t pid; - Client *next; - Client *snext; -+ Client *swallowing; - Monitor *mon; - Window win; - }; -@@ -138,6 +144,8 @@ typedef struct { - const char *title; - unsigned int tags; - int isfloating; -+ int isterminal; -+ int noswallow; - int monitor; - } Rule; - -@@ -170,12 +178,14 @@ static void focus(Client *c); - static void focusin(XEvent *e); - static void focusmon(const Arg *arg); - static void focusstack(const Arg *arg); -+static pid_t getparentprocess(pid_t p); - static int getrootptr(int *x, int *y); - static long getstate(Window w); - static int gettextprop(Window w, Atom atom, char *text, unsigned int size); - static void grabbuttons(Client *c, int focused); - static void grabkeys(void); - static void incnmaster(const Arg *arg); -+static int isdescprocess(pid_t p, pid_t c); - static void keypress(XEvent *e); - static void killclient(const Arg *arg); - static void manage(Window w, XWindowAttributes *wa); -@@ -206,8 +216,10 @@ static void setup(void); - static void showhide(Client *c); - static void sigchld(int unused); - static void spawn(const Arg *arg); -+static Client *swallowingclient(Window w); - static void tag(const Arg *arg); - static void tagmon(const Arg *arg); -+static Client *termforwin(const Client *c); - static void tile(Monitor *); - static void togglebar(const Arg *arg); - static void togglefloating(const Arg *arg); -@@ -227,6 +239,7 @@ static void updatewindowtype(Client *c); - static void updatetitle(Client *c); - static void updatewmhints(Client *c); - static void view(const Arg *arg); -+static pid_t winpid(Window w); - static Client *wintoclient(Window w); - static Monitor *wintomon(Window w); - static int xerror(Display *dpy, XErrorEvent *ee); -@@ -267,6 +280,10 @@ static Drw *drw; - static Monitor *mons, *selmon; - static Window root; - -+#ifdef SWALLOWING -+static xcb_connection_t *xcon; -+#endif /* SWALLOWING */ -+ - /* configuration, allows nested code to access above variables */ - #include "config.h" - -@@ -296,6 +313,7 @@ applyrules(Client *c) - && (!r->class || strstr(class, r->class)) - && (!r->instance || strstr(instance, r->instance))) - { -+ c->isterminal = r->isterminal; - c->isfloating = r->isfloating; - c->tags |= r->tags; - for (m = mons; m && m->num != r->monitor; m = m->next); -@@ -413,6 +431,46 @@ attachstack(Client *c) - } - - void -+swallow(Client *p, Client *c) -+{ -+ if (c->noswallow || c->isterminal) -+ return; -+ -+ detach(c); -+ detachstack(c); -+ -+ setclientstate(c, WithdrawnState); -+ XUnmapWindow(dpy, p->win); -+ -+ p->swallowing = c; -+ c->mon = p->mon; -+ -+ Window w = p->win; -+ p->win = c->win; -+ c->win = w; -+ updatetitle(p); -+ arrange(p->mon); -+ configure(p); -+ updateclientlist(); -+} -+ -+void -+unswallow(Client *c) -+{ -+ c->win = c->swallowing->win; -+ -+ free(c->swallowing); -+ c->swallowing = NULL; -+ -+ updatetitle(c); -+ arrange(c->mon); -+ XMapWindow(dpy, c->win); -+ XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); -+ configure(c); -+ setclientstate(c, NormalState); -+} -+ -+void - buttonpress(XEvent *e) - { - unsigned int i, x, click; -@@ -475,7 +533,7 @@ cleanup(void) - selmon->lt[selmon->sellt] = &foo; - for (m = mons; m; m = m->next) - while (m->stack) -- unmanage(m->stack, 0); -+ unmanage(m->stack, 0); // XXX - unmanage swallowing windows too - XUngrabKey(dpy, AnyKey, AnyModifier, root); - while (mons) - cleanupmon(mons); -@@ -666,6 +724,9 @@ destroynotify(XEvent *e) - - if ((c = wintoclient(ev->window))) - unmanage(c, 1); -+ -+ else if ((c = swallowingclient(ev->window))) -+ unmanage(c->swallowing, 1); - } - - void -@@ -1037,12 +1098,13 @@ killclient(const Arg *arg) - void - manage(Window w, XWindowAttributes *wa) - { -- Client *c, *t = NULL; -+ Client *c, *t, *term = NULL; - Window trans = None; - XWindowChanges wc; - - c = ecalloc(1, sizeof(Client)); - c->win = w; -+ c->pid = winpid(w); - updatetitle(c); - if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) { - c->mon = t->mon; -@@ -1050,7 +1112,9 @@ manage(Window w, XWindowAttributes *wa) - } else { - c->mon = selmon; - applyrules(c); -+ term = termforwin(c); - } -+ - /* geometry */ - c->x = c->oldx = wa->x; - c->y = c->oldy = wa->y; -@@ -1092,6 +1156,8 @@ manage(Window w, XWindowAttributes *wa) - c->mon->sel = c; - arrange(c->mon); - XMapWindow(dpy, c->win); -+ if (term) -+ swallow(term, c); - focus(NULL); - } - -@@ -1763,6 +1829,20 @@ unmanage(Client *c, int destroyed) - Monitor *m = c->mon; - XWindowChanges wc; - -+ if (c->swallowing) { -+ unswallow(c); -+ return; -+ } -+ -+ Client *s = swallowingclient(c->win); -+ if (s) { -+ free(s->swallowing); -+ s->swallowing = NULL; -+ arrange(m); -+ focus(NULL); -+ return; -+ } -+ - /* The server grab construct avoids race conditions. */ - detach(c); - detachstack(c); -@@ -1778,9 +1858,12 @@ unmanage(Client *c, int destroyed) - XUngrabServer(dpy); - } - free(c); -- focus(NULL); -- updateclientlist(); -- arrange(m); -+ -+ if (!s) { -+ arrange(m); -+ focus(NULL); -+ updateclientlist(); -+ } - } - - void -@@ -2045,16 +2128,118 @@ view(const Arg *arg) - arrange(selmon); - } - -+pid_t -+winpid(Window w) -+{ -+ pid_t result = 0; -+ -+#ifdef SWALLOWING -+ xcb_res_client_id_spec_t spec = {0}; -+ spec.client = w; -+ spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID; -+ -+ xcb_generic_error_t *e = NULL; -+ xcb_res_query_client_ids_cookie_t c = xcb_res_query_client_ids(xcon, 1, &spec); -+ xcb_res_query_client_ids_reply_t *r = xcb_res_query_client_ids_reply(xcon, c, &e); -+ -+ if (!r) -+ return (pid_t)0; -+ -+ xcb_res_client_id_value_iterator_t i = xcb_res_query_client_ids_ids_iterator(r); -+ for (; i.rem; xcb_res_client_id_value_next(&i)) { -+ spec = i.data->spec; -+ if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID) { -+ uint32_t *t = xcb_res_client_id_value_value(i.data); -+ result = *t; -+ break; -+ } -+ } -+ -+ free(r); -+#endif /* SWALLOWING */ -+ -+ if (result == (pid_t)-1) -+ result = 0; -+ return result; -+} -+ -+pid_t -+getparentprocess(pid_t p) -+{ -+ unsigned int v = 0; -+ -+#ifdef __linux__ -+ FILE *f; -+ char buf[256]; -+ snprintf(buf, sizeof(buf) - 1, "/proc/%u/stat", (unsigned)p); -+ -+ if (!(f = fopen(buf, "r"))) -+ return 0; -+ -+ fscanf(f, "%*u %*s %*c %u", &v); -+ fclose(f); -+#endif /* __linux__ */ -+ -+ return (pid_t)v; -+} -+ -+int -+isdescprocess(pid_t p, pid_t c) -+{ -+ while (p != c && c != 0) -+ c = getparentprocess(c); -+ -+ return (int)c; -+} -+ -+Client * -+termforwin(const Client *w) -+{ -+ Client *c; -+ Monitor *m; -+ -+ if (!w->pid || w->isterminal) -+ return NULL; -+ -+ for (m = mons; m; m = m->next) { -+ for (c = m->clients; c; c = c->next) { -+ if (c->isterminal && !c->swallowing && c->pid && isdescprocess(c->pid, w->pid)) -+ return c; -+ } -+ } -+ -+ return NULL; -+} -+ -+Client * -+swallowingclient(Window w) -+{ -+ Client *c; -+ Monitor *m; -+ -+ for (m = mons; m; m = m->next) { -+ for (c = m->clients; c; c = c->next) { -+ if (c->swallowing && c->swallowing->win == w) -+ return c; -+ } -+ } -+ -+ return NULL; -+} -+ - Client * - wintoclient(Window w) - { - Client *c; - Monitor *m; - -- for (m = mons; m; m = m->next) -- for (c = m->clients; c; c = c->next) -+ for (m = mons; m; m = m->next) { -+ for (c = m->clients; c; c = c->next) { - if (c->win == w) - return c; -+ } -+ } -+ - return NULL; - } - -@@ -2136,6 +2321,10 @@ main(int argc, char *argv[]) - fputs("warning: no locale support\n", stderr); - if (!(dpy = XOpenDisplay(NULL))) - die("dwm: cannot open display\n"); -+#ifdef SWALLOWING -+ if (!(xcon = XGetXCBConnection(dpy))) -+ die("dwm: cannot get xcb connection\n"); -+#endif - checkotherwm(); - setup(); - scan(); diff --git a/dwm.suckless.org/patches/dwm-6.1-systray.diff b/dwm.suckless.org/patches/dwm-6.1-systray.diff @@ -14,7 +14,7 @@ index 7054c06..8393a58 100644 static const int topbar = 1; /* 0 means bottom bar */ diff --git a/dwm.c b/dwm.c -index 0362114..e574573 100644 +index ff7e096..cf0b3a9 100644 --- a/dwm.c +++ b/dwm.c @@ -57,12 +57,30 @@ @@ -201,16 +201,16 @@ index 0362114..e574573 100644 if (!c) return; if (cme->message_type == netatom[NetWMState]) { -@@ -577,7 +660,7 @@ configurenotify(XEvent *e) - drw_resize(drw, sw, bh); - updatebars(); - for (m = mons; m; m = m->next) +@@ -581,7 +664,7 @@ configurenotify(XEvent *e) + for (c = m->clients; c; c = c->next) + if (c->isfullscreen) + resizeclient(c, m->mx, m->my, m->mw, m->mh); - XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); + resizebarwin(m); + } focus(NULL); arrange(NULL); - } -@@ -661,6 +744,11 @@ destroynotify(XEvent *e) +@@ -666,6 +749,11 @@ destroynotify(XEvent *e) if ((c = wintoclient(ev->window))) unmanage(c, 1); @@ -222,7 +222,7 @@ index 0362114..e574573 100644 } void -@@ -710,6 +798,7 @@ drawbar(Monitor *m) +@@ -715,6 +803,7 @@ drawbar(Monitor *m) dx = (drw->fonts[0]->ascent + drw->fonts[0]->descent + 2) / 4; @@ -230,7 +230,7 @@ index 0362114..e574573 100644 for (c = m->clients; c; c = c->next) { occ |= c->tags; if (c->isurgent) -@@ -732,6 +821,9 @@ drawbar(Monitor *m) +@@ -737,6 +826,9 @@ drawbar(Monitor *m) if (m == selmon) { /* status is only drawn on selected monitor */ w = TEXTW(stext); x = m->ww - w; @@ -240,7 +240,7 @@ index 0362114..e574573 100644 if (x < xx) { x = xx; w = m->ww - xx; -@@ -760,6 +852,7 @@ drawbars(void) +@@ -765,6 +857,7 @@ drawbars(void) for (m = mons; m; m = m->next) drawbar(m); @@ -248,7 +248,7 @@ index 0362114..e574573 100644 } void -@@ -787,8 +880,11 @@ expose(XEvent *e) +@@ -792,8 +885,11 @@ expose(XEvent *e) Monitor *m; XExposeEvent *ev = &e->xexpose; @@ -261,7 +261,7 @@ index 0362114..e574573 100644 } void -@@ -875,10 +971,17 @@ getatomprop(Client *c, Atom prop) +@@ -880,10 +976,17 @@ getatomprop(Client *c, Atom prop) unsigned long dl; unsigned char *p = NULL; Atom da, atom = None; @@ -280,7 +280,7 @@ index 0362114..e574573 100644 XFree(p); } return atom; -@@ -912,6 +1015,15 @@ getstate(Window w) +@@ -917,6 +1020,15 @@ getstate(Window w) return result; } @@ -296,7 +296,7 @@ index 0362114..e574573 100644 int gettextprop(Window w, Atom atom, char *text, unsigned int size) { -@@ -1018,7 +1130,7 @@ killclient(const Arg *arg) +@@ -1023,7 +1135,7 @@ killclient(const Arg *arg) { if (!selmon->sel) return; @@ -305,7 +305,7 @@ index 0362114..e574573 100644 XGrabServer(dpy); XSetErrorHandler(xerrordummy); XSetCloseDownMode(dpy, DestroyAll); -@@ -1105,6 +1217,12 @@ maprequest(XEvent *e) +@@ -1110,6 +1222,12 @@ maprequest(XEvent *e) { static XWindowAttributes wa; XMapRequestEvent *ev = &e->xmaprequest; @@ -318,7 +318,7 @@ index 0362114..e574573 100644 if (!XGetWindowAttributes(dpy, ev->window, &wa)) return; -@@ -1232,6 +1350,16 @@ propertynotify(XEvent *e) +@@ -1237,6 +1355,16 @@ propertynotify(XEvent *e) Window trans; XPropertyEvent *ev = &e->xproperty; @@ -335,7 +335,7 @@ index 0362114..e574573 100644 if ((ev->window == root) && (ev->atom == XA_WM_NAME)) updatestatus(); else if (ev->state == PropertyDelete) -@@ -1283,6 +1411,19 @@ recttomon(int x, int y, int w, int h) +@@ -1288,6 +1416,19 @@ recttomon(int x, int y, int w, int h) } void @@ -355,7 +355,7 @@ index 0362114..e574573 100644 resize(Client *c, int x, int y, int w, int h, int interact) { if (applysizehints(c, &x, &y, &w, &h, interact)) -@@ -1290,6 +1431,14 @@ resize(Client *c, int x, int y, int w, int h, int interact) +@@ -1295,6 +1436,14 @@ resize(Client *c, int x, int y, int w, int h, int interact) } void @@ -370,7 +370,7 @@ index 0362114..e574573 100644 resizeclient(Client *c, int x, int y, int w, int h) { XWindowChanges wc; -@@ -1362,6 +1511,18 @@ resizemouse(const Arg *arg) +@@ -1367,6 +1516,18 @@ resizemouse(const Arg *arg) } void @@ -389,7 +389,7 @@ index 0362114..e574573 100644 restack(Monitor *m) { Client *c; -@@ -1450,26 +1611,36 @@ setclientstate(Client *c, long state) +@@ -1455,26 +1616,36 @@ setclientstate(Client *c, long state) } int @@ -437,7 +437,7 @@ index 0362114..e574573 100644 } return exists; } -@@ -1483,7 +1654,7 @@ setfocus(Client *c) +@@ -1488,7 +1659,7 @@ setfocus(Client *c) XA_WINDOW, 32, PropModeReplace, (unsigned char *) &(c->win), 1); } @@ -446,7 +446,7 @@ index 0362114..e574573 100644 } void -@@ -1569,12 +1740,18 @@ setup(void) +@@ -1574,12 +1745,18 @@ setup(void) wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); @@ -465,7 +465,7 @@ index 0362114..e574573 100644 /* init cursors */ cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); cursor[CurResize] = drw_cur_create(drw, XC_sizing); -@@ -1586,6 +1763,8 @@ setup(void) +@@ -1591,6 +1768,8 @@ setup(void) scheme[SchemeSel].border = drw_clr_create(drw, selbordercolor); scheme[SchemeSel].bg = drw_clr_create(drw, selbgcolor); scheme[SchemeSel].fg = drw_clr_create(drw, selfgcolor); @@ -474,7 +474,7 @@ index 0362114..e574573 100644 /* init bars */ updatebars(); updatestatus(); -@@ -1645,6 +1824,22 @@ spawn(const Arg *arg) +@@ -1650,6 +1829,22 @@ spawn(const Arg *arg) } } @@ -497,7 +497,7 @@ index 0362114..e574573 100644 void tag(const Arg *arg) { -@@ -1694,7 +1889,18 @@ togglebar(const Arg *arg) +@@ -1699,7 +1894,18 @@ togglebar(const Arg *arg) { selmon->showbar = !selmon->showbar; updatebarpos(selmon); @@ -517,7 +517,7 @@ index 0362114..e574573 100644 arrange(selmon); } -@@ -1790,11 +1996,17 @@ unmapnotify(XEvent *e) +@@ -1795,11 +2001,17 @@ unmapnotify(XEvent *e) else unmanage(c, 0); } @@ -535,7 +535,7 @@ index 0362114..e574573 100644 Monitor *m; XSetWindowAttributes wa = { .override_redirect = True, -@@ -1804,10 +2016,15 @@ updatebars(void) +@@ -1809,10 +2021,15 @@ updatebars(void) for (m = mons; m; m = m->next) { if (m->barwin) continue; @@ -552,7 +552,7 @@ index 0362114..e574573 100644 XMapRaised(dpy, m->barwin); } } -@@ -1998,6 +2215,117 @@ updatestatus(void) +@@ -2003,6 +2220,117 @@ updatestatus(void) } void @@ -670,7 +670,7 @@ index 0362114..e574573 100644 updatewindowtype(Client *c) { Atom state = getatomprop(c, netatom[NetWMState]); -@@ -2070,6 +2398,16 @@ wintomon(Window w) +@@ -2075,6 +2403,16 @@ wintomon(Window w) return selmon; } diff --git a/dwm.suckless.org/patches/dwm-alpha-6.1.diff b/dwm.suckless.org/patches/dwm-alpha-6.1.diff @@ -0,0 +1,253 @@ +diff --git a/config.def.h b/config.def.h +index 7054c06..4448d46 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -11,6 +11,8 @@ static const char normfgcolor[] = "#bbbbbb"; + static const char selbordercolor[] = "#005577"; + static const char selbgcolor[] = "#005577"; + static const char selfgcolor[] = "#eeeeee"; ++static unsigned int baralpha = 0xd0; ++static unsigned int borderalpha = OPAQUE; + static const unsigned int borderpx = 1; /* border pixel of windows */ + static const unsigned int snap = 32; /* snap pixel */ + static const int showbar = 1; /* 0 means no bar */ +diff --git a/config.mk b/config.mk +index 4eefb71..de25d2a 100644 +--- a/config.mk ++++ b/config.mk +@@ -22,7 +22,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} -lXrender + + # flags + CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} +diff --git a/drw.c b/drw.c +index f49200b..12e3ebc 100644 +--- a/drw.c ++++ b/drw.c +@@ -61,7 +61,7 @@ utf8decode(const char *c, long *u, size_t clen) + } + + Drw * +-drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) ++drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap) + { + Drw *drw; + +@@ -71,8 +71,11 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h + drw->root = root; + drw->w = w; + drw->h = h; +- drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen)); +- drw->gc = XCreateGC(dpy, root, 0, NULL); ++ 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); + drw->fontcount = 0; + XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); + +@@ -86,7 +89,7 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h) + drw->h = h; + if (drw->drawable) + XFreePixmap(drw->dpy, drw->drawable); +- drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen)); ++ drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, drw->depth); + } + + void +@@ -180,16 +183,15 @@ drw_font_free(Fnt *font) + } + + Clr * +-drw_clr_create(Drw *drw, const char *clrname) ++drw_clr_create(Drw *drw, const char *clrname, unsigned int alpha) + { + Clr *clr; + + clr = ecalloc(1, sizeof(Clr)); +- if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), +- DefaultColormap(drw->dpy, drw->screen), ++ if (!XftColorAllocName(drw->dpy, drw->visual, drw->cmap, + clrname, &clr->rgb)) + die("error, cannot allocate color '%s'\n", clrname); +- clr->pix = clr->rgb.pixel; ++ clr->pix = (clr->rgb.pixel & 0x00ffffffU) | (alpha << 24); + + return clr; + } +@@ -245,9 +247,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex + XSetForeground(drw->dpy, drw->gc, invert ? + drw->scheme->fg->pix : drw->scheme->bg->pix); + XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); +- d = XftDrawCreate(drw->dpy, drw->drawable, +- DefaultVisual(drw->dpy, drw->screen), +- DefaultColormap(drw->dpy, drw->screen)); ++ d = XftDrawCreate(drw->dpy, drw->drawable, drw->visual, drw->cmap); + } + + curfont = drw->fonts[0]; +diff --git a/drw.h b/drw.h +index e3b8515..1fed824 100644 +--- a/drw.h ++++ b/drw.h +@@ -30,6 +30,9 @@ typedef struct { + Display *dpy; + int screen; + Window root; ++ Visual *visual; ++ unsigned int depth; ++ Colormap cmap; + Drawable drawable; + GC gc; + ClrScheme *scheme; +@@ -43,7 +46,7 @@ typedef struct { + } Extnts; + + /* Drawable abstraction */ +-Drw *drw_create(Display *, int, Window, unsigned int, unsigned int); ++Drw *drw_create(Display *, int, Window, unsigned int, unsigned int, Visual*, unsigned int, Colormap); + void drw_resize(Drw *, unsigned int, unsigned int); + void drw_free(Drw *); + +@@ -55,7 +58,7 @@ void drw_font_getexts(Fnt *, const char *, unsigned int, Extnts *); + unsigned int drw_font_getexts_width(Fnt *, const char *, unsigned int); + + /* Colour abstraction */ +-Clr *drw_clr_create(Drw *, const char *); ++Clr *drw_clr_create(Drw *, const char *, unsigned int); + void drw_clr_free(Clr *); + + /* Cursor abstraction */ +diff --git a/dwm.c b/dwm.c +index 0362114..17fe373 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -57,6 +57,8 @@ + #define TAGMASK ((1 << LENGTH(tags)) - 1) + #define TEXTW(X) (drw_text(drw, 0, 0, 0, 0, (X), 0) + drw->fonts[0]->h) + ++#define OPAQUE 0xffU ++ + /* enums */ + enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ + enum { SchemeNorm, SchemeSel, SchemeLast }; /* color schemes */ +@@ -232,6 +234,7 @@ static Monitor *wintomon(Window w); + static int xerror(Display *dpy, XErrorEvent *ee); + static int xerrordummy(Display *dpy, XErrorEvent *ee); + static int xerrorstart(Display *dpy, XErrorEvent *ee); ++static void xinitvisual(); + static void zoom(const Arg *arg); + + /* variables */ +@@ -267,6 +270,11 @@ static Drw *drw; + static Monitor *mons, *selmon; + static Window root; + ++static int useargb = 0; ++static Visual *visual; ++static int depth; ++static Colormap cmap; ++ + /* configuration, allows nested code to access above variables */ + #include "config.h" + +@@ -1556,7 +1564,8 @@ setup(void) + sw = DisplayWidth(dpy, screen); + sh = DisplayHeight(dpy, screen); + root = RootWindow(dpy, screen); +- drw = drw_create(dpy, screen, root, sw, sh); ++ xinitvisual(); ++ drw = drw_create(dpy, screen, root, sw, sh, visual, depth, cmap); + drw_load_fonts(drw, fonts, LENGTH(fonts)); + if (!drw->fontcount) + die("no fonts could be loaded.\n"); +@@ -1580,12 +1589,12 @@ setup(void) + cursor[CurResize] = drw_cur_create(drw, XC_sizing); + cursor[CurMove] = drw_cur_create(drw, XC_fleur); + /* init appearance */ +- scheme[SchemeNorm].border = drw_clr_create(drw, normbordercolor); +- scheme[SchemeNorm].bg = drw_clr_create(drw, normbgcolor); +- scheme[SchemeNorm].fg = drw_clr_create(drw, normfgcolor); +- scheme[SchemeSel].border = drw_clr_create(drw, selbordercolor); +- scheme[SchemeSel].bg = drw_clr_create(drw, selbgcolor); +- scheme[SchemeSel].fg = drw_clr_create(drw, selfgcolor); ++ scheme[SchemeNorm].border = drw_clr_create(drw, normbordercolor, borderalpha); ++ scheme[SchemeNorm].bg = drw_clr_create(drw, normbgcolor, baralpha); ++ scheme[SchemeNorm].fg = drw_clr_create(drw, normfgcolor, OPAQUE); ++ scheme[SchemeSel].border = drw_clr_create(drw, selbordercolor, borderalpha); ++ scheme[SchemeSel].bg = drw_clr_create(drw, selbgcolor, baralpha); ++ scheme[SchemeSel].fg = drw_clr_create(drw, selfgcolor, OPAQUE); + /* init bars */ + updatebars(); + updatestatus(); +@@ -1798,15 +1807,17 @@ updatebars(void) + Monitor *m; + XSetWindowAttributes wa = { + .override_redirect = True, +- .background_pixmap = ParentRelative, ++ .background_pixel = 0, ++ .border_pixel = 0, ++ .colormap = cmap, + .event_mask = ButtonPressMask|ExposureMask + }; + for (m = mons; m; m = m->next) { + if (m->barwin) + continue; +- m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen), +- CopyFromParent, DefaultVisual(dpy, screen), +- CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); ++ m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, depth, ++ InputOutput, visual, ++ CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &wa); + XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); + XMapRaised(dpy, m->barwin); + } +@@ -2107,6 +2118,43 @@ xerrorstart(Display *dpy, XErrorEvent *ee) + } + + void ++xinitvisual() ++{ ++ 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) { ++ visual = DefaultVisual(dpy, screen); ++ depth = DefaultDepth(dpy, screen); ++ cmap = DefaultColormap(dpy, screen); ++ } ++} ++ ++void + zoom(const Arg *arg) + { + Client *c = selmon->sel; diff --git a/dwm.suckless.org/patches/dwm-argbcolor.png b/dwm.suckless.org/patches/dwm-alpha.png Binary files differ. diff --git a/dwm.suckless.org/patches/dwm-alwaysfullscreen-20160713-56a31dc.diff b/dwm.suckless.org/patches/dwm-alwaysfullscreen-20160713-56a31dc.diff @@ -0,0 +1,13 @@ +diff --git a/dwm.c b/dwm.c +index b2bc9bd..aa1b407 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -849,7 +849,7 @@ focusstack(const Arg *arg) + { + Client *c = NULL, *i; + +- if (!selmon->sel) ++ if (!selmon->sel || selmon->sel->isfullscreen) + return; + if (arg->i > 0) { + for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next); diff --git a/dwm.suckless.org/patches/dwm-alwaysfullscreen-6.1.diff b/dwm.suckless.org/patches/dwm-alwaysfullscreen-6.1.diff @@ -0,0 +1,13 @@ +diff --git a/dwm.c b/dwm.c +index 0362114..a5cab76 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -847,7 +847,7 @@ focusstack(const Arg *arg) + { + Client *c = NULL, *i; + +- if (!selmon->sel) ++ if (!selmon->sel || selmon->sel->isfullscreen) + return; + if (arg->i > 0) { + for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next); diff --git a/dwm.suckless.org/patches/dwm-attachabove-20160713-56a31dc.diff b/dwm.suckless.org/patches/dwm-attachabove-20160713-56a31dc.diff @@ -0,0 +1,60 @@ +diff --git a/dwm.c b/dwm.c +index b2bc9bd..5a380e6 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -148,6 +148,7 @@ static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interac + static void arrange(Monitor *m); + static void arrangemon(Monitor *m); + static void attach(Client *c); ++static void attachabove(Client *c); + static void attachstack(Client *c); + static void buttonpress(XEvent *e); + static void checkotherwm(void); +@@ -408,6 +409,20 @@ attach(Client *c) + } + + void ++attachabove(Client *c) ++{ ++ if(c->mon->sel == NULL || c->mon->sel == c->mon->clients || c->mon->sel->isfloating) { ++ attach(c); ++ return; ++ } ++ ++ Client *at; ++ for(at = c->mon->clients; at->next != c->mon->sel; at = at->next); ++ c->next = at->next; ++ at->next = c; ++} ++ ++void + attachstack(Client *c) + { + c->snext = c->mon->stack; +@@ -1079,7 +1094,7 @@ manage(Window w, XWindowAttributes *wa) + c->isfloating = c->oldstate = trans != None || c->isfixed; + if (c->isfloating) + XRaiseWindow(dpy, c->win); +- attach(c); ++ attachabove(c); + attachstack(c); + XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, + (unsigned char *) &(c->win), 1); +@@ -1437,7 +1452,7 @@ sendmon(Client *c, Monitor *m) + detachstack(c); + c->mon = m; + c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ +- attach(c); ++ attachabove(c); + attachstack(c); + focus(NULL); + arrange(NULL); +@@ -1890,7 +1905,7 @@ updategeom(void) + m->clients = c->next; + detachstack(c); + c->mon = mons; +- attach(c); ++ attachabove(c); + attachstack(c); + } + if (m == selmon) diff --git a/dwm.suckless.org/patches/dwm-attachabove-6.0.diff b/dwm.suckless.org/patches/dwm-attachabove-6.0.diff @@ -0,0 +1,59 @@ +diff --git a/dwm.c b/dwm.c +index 1d78655..a9e0ea4 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -160,6 +160,7 @@ static Bool applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool inter + static void arrange(Monitor *m); + static void arrangemon(Monitor *m); + static void attach(Client *c); ++static void attachabove(Client *c); + static void attachstack(Client *c); + static void buttonpress(XEvent *e); + static void checkotherwm(void); +@@ -418,6 +419,19 @@ attach(Client *c) { + } + + void ++attachabove(Client *c) { ++ if(c->mon->sel == NULL || c->mon->sel == c->mon->clients || c->mon->sel->isfloating) { ++ attach(c); ++ return; ++ } ++ ++ Client *at; ++ for(at = c->mon->clients; at->next != c->mon->sel; at = at->next); ++ c->next = at->next; ++ at->next = c; ++} ++ ++void + attachstack(Client *c) { + c->snext = c->mon->stack; + c->mon->stack = c; +@@ -1155,7 +1169,7 @@ manage(Window w, XWindowAttributes *wa) { + c->isfloating = c->oldstate = trans != None || c->isfixed; + if(c->isfloating) + XRaiseWindow(dpy, c->win); +- attach(c); ++ attachabove(c); + attachstack(c); + XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */ + setclientstate(c, NormalState); +@@ -1480,7 +1494,7 @@ sendmon(Client *c, Monitor *m) { + detachstack(c); + c->mon = m; + c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ +- attach(c); ++ attachabove(c); + attachstack(c); + focus(NULL); + arrange(NULL); +@@ -1900,7 +1914,7 @@ updategeom(void) { + m->clients = c->next; + detachstack(c); + c->mon = mons; +- attach(c); ++ attachabove(c); + attachstack(c); + } + if(m == selmon) diff --git a/dwm.suckless.org/patches/dwm-attachabove-6.1.diff b/dwm.suckless.org/patches/dwm-attachabove-6.1.diff @@ -0,0 +1,60 @@ +diff --git a/dwm.c b/dwm.c +index 0362114..413ec1f 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -147,6 +147,7 @@ static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interac + static void arrange(Monitor *m); + static void arrangemon(Monitor *m); + static void attach(Client *c); ++static void attachabove(Client *c); + static void attachstack(Client *c); + static void buttonpress(XEvent *e); + static void checkotherwm(void); +@@ -406,6 +407,20 @@ attach(Client *c) + } + + void ++attachabove(Client *c) ++{ ++ if(c->mon->sel == NULL || c->mon->sel == c->mon->clients || c->mon->sel->isfloating) { ++ attach(c); ++ return; ++ } ++ ++ Client *at; ++ for(at = c->mon->clients; at->next != c->mon->sel; at = at->next); ++ c->next = at->next; ++ at->next = c; ++} ++ ++void + attachstack(Client *c) + { + c->snext = c->mon->stack; +@@ -1076,7 +1091,7 @@ manage(Window w, XWindowAttributes *wa) + c->isfloating = c->oldstate = trans != None || c->isfixed; + if (c->isfloating) + XRaiseWindow(dpy, c->win); +- attach(c); ++ attachabove(c); + attachstack(c); + XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, + (unsigned char *) &(c->win), 1); +@@ -1434,7 +1449,7 @@ sendmon(Client *c, Monitor *m) + detachstack(c); + c->mon = m; + c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ +- attach(c); ++ attachabove(c); + attachstack(c); + focus(NULL); + arrange(NULL); +@@ -1891,7 +1906,7 @@ updategeom(void) + m->clients = c->next; + detachstack(c); + c->mon = mons; +- attach(c); ++ attachabove(c); + attachstack(c); + } + if (m == selmon) diff --git a/dwm.suckless.org/patches/dwm-attachaside-20160718-56a31dc.diff b/dwm.suckless.org/patches/dwm-attachaside-20160718-56a31dc.diff @@ -0,0 +1,92 @@ +diff --git a/dwm.c b/dwm.c +index b2bc9bd..58a86fa 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -49,7 +49,8 @@ + #define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) + #define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \ + * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy))) +-#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags])) ++#define ISVISIBLEONTAG(C, T) ((C->tags & T)) ++#define ISVISIBLE(C) ISVISIBLEONTAG(C, C->mon->tagset[C->mon->seltags]) + #define LENGTH(X) (sizeof X / sizeof X[0]) + #define MOUSEMASK (BUTTONMASK|PointerMotionMask) + #define WIDTH(X) ((X)->w + 2 * (X)->bw) +@@ -148,6 +149,7 @@ static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interac + static void arrange(Monitor *m); + static void arrangemon(Monitor *m); + static void attach(Client *c); ++static void attachaside(Client *c); + static void attachstack(Client *c); + static void buttonpress(XEvent *e); + static void checkotherwm(void); +@@ -185,6 +187,7 @@ static void maprequest(XEvent *e); + static void monocle(Monitor *m); + static void motionnotify(XEvent *e); + static void movemouse(const Arg *arg); ++static Client *nexttagged(Client *c); + static Client *nexttiled(Client *c); + static void pop(Client *); + static void propertynotify(XEvent *e); +@@ -408,6 +411,17 @@ attach(Client *c) + } + + void ++attachaside(Client *c) { ++ Client *at = nexttagged(c); ++ if(!at) { ++ attach(c); ++ return; ++ } ++ c->next = at->next; ++ at->next = c; ++} ++ ++void + attachstack(Client *c) + { + c->snext = c->mon->stack; +@@ -1079,7 +1093,7 @@ manage(Window w, XWindowAttributes *wa) + c->isfloating = c->oldstate = trans != None || c->isfixed; + if (c->isfloating) + XRaiseWindow(dpy, c->win); +- attach(c); ++ attachaside(c); + attachstack(c); + XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, + (unsigned char *) &(c->win), 1); +@@ -1213,6 +1227,16 @@ movemouse(const Arg *arg) + } + + Client * ++nexttagged(Client *c) { ++ Client *walked = c->mon->clients; ++ for(; ++ walked && (walked->isfloating || !ISVISIBLEONTAG(walked, c->tags)); ++ walked = walked->next ++ ); ++ return walked; ++} ++ ++Client * + nexttiled(Client *c) + { + for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next); +@@ -1437,7 +1461,7 @@ sendmon(Client *c, Monitor *m) + detachstack(c); + c->mon = m; + c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ +- attach(c); ++ attachaside(c); + attachstack(c); + focus(NULL); + arrange(NULL); +@@ -1890,7 +1914,7 @@ updategeom(void) + m->clients = c->next; + detachstack(c); + c->mon = mons; +- attach(c); ++ attachaside(c); + attachstack(c); + } + if (m == selmon) diff --git a/dwm.suckless.org/patches/dwm-attachaside-6.1.diff b/dwm.suckless.org/patches/dwm-attachaside-6.1.diff @@ -0,0 +1,92 @@ +diff --git a/dwm.c b/dwm.c +index 0362114..be7e7a6 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -49,7 +49,8 @@ + #define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) + #define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \ + * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy))) +-#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags])) ++#define ISVISIBLEONTAG(C, T) ((C->tags & T)) ++#define ISVISIBLE(C) ISVISIBLEONTAG(C, C->mon->tagset[C->mon->seltags]) + #define LENGTH(X) (sizeof X / sizeof X[0]) + #define MOUSEMASK (BUTTONMASK|PointerMotionMask) + #define WIDTH(X) ((X)->w + 2 * (X)->bw) +@@ -147,6 +148,7 @@ static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interac + static void arrange(Monitor *m); + static void arrangemon(Monitor *m); + static void attach(Client *c); ++static void attachaside(Client *c); + static void attachstack(Client *c); + static void buttonpress(XEvent *e); + static void checkotherwm(void); +@@ -184,6 +186,7 @@ static void maprequest(XEvent *e); + static void monocle(Monitor *m); + static void motionnotify(XEvent *e); + static void movemouse(const Arg *arg); ++static Client *nexttagged(Client *c); + static Client *nexttiled(Client *c); + static void pop(Client *); + static void propertynotify(XEvent *e); +@@ -406,6 +409,17 @@ attach(Client *c) + } + + void ++attachaside(Client *c) { ++ Client *at = nexttagged(c); ++ if(!at) { ++ attach(c); ++ return; ++ } ++ c->next = at->next; ++ at->next = c; ++} ++ ++void + attachstack(Client *c) + { + c->snext = c->mon->stack; +@@ -1076,7 +1090,7 @@ manage(Window w, XWindowAttributes *wa) + c->isfloating = c->oldstate = trans != None || c->isfixed; + if (c->isfloating) + XRaiseWindow(dpy, c->win); +- attach(c); ++ attachaside(c); + attachstack(c); + XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, + (unsigned char *) &(c->win), 1); +@@ -1210,6 +1224,16 @@ movemouse(const Arg *arg) + } + + Client * ++nexttagged(Client *c) { ++ Client *walked = c->mon->clients; ++ for(; ++ walked && (walked->isfloating || !ISVISIBLEONTAG(walked, c->tags)); ++ walked = walked->next ++ ); ++ return walked; ++} ++ ++Client * + nexttiled(Client *c) + { + for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next); +@@ -1434,7 +1458,7 @@ sendmon(Client *c, Monitor *m) + detachstack(c); + c->mon = m; + c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ +- attach(c); ++ attachaside(c); + attachstack(c); + focus(NULL); + arrange(NULL); +@@ -1891,7 +1915,7 @@ updategeom(void) + m->clients = c->next; + detachstack(c); + c->mon = mons; +- attach(c); ++ attachaside(c); + attachstack(c); + } + if (m == selmon) diff --git a/dwm.suckless.org/patches/dwm-autoresize-20160718-56a31dc.diff b/dwm.suckless.org/patches/dwm-autoresize-20160718-56a31dc.diff @@ -0,0 +1,35 @@ +diff --git a/dwm.c b/dwm.c +index b2bc9bd..3002925 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -93,7 +93,7 @@ struct Client { + int basew, baseh, incw, inch, maxw, maxh, minw, minh; + int bw, oldbw; + unsigned int tags; +- int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; ++ int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, needresize; + Client *next; + Client *snext; + Monitor *mon; +@@ -625,6 +625,8 @@ configurerequest(XEvent *e) + configure(c); + if (ISVISIBLE(c)) + XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); ++ else ++ c->needresize = 1; + } else + configure(c); + } else { +@@ -1610,6 +1612,12 @@ showhide(Client *c) + if (ISVISIBLE(c)) { + /* show clients top down */ + XMoveWindow(dpy, c->win, c->x, c->y); ++ if (c->needresize) { ++ c->needresize = 0; ++ XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); ++ } else { ++ XMoveWindow(dpy, c->win, c->x, c->y); ++ } + if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen) + resize(c, c->x, c->y, c->w, c->h, 0); + showhide(c->snext); diff --git a/dwm.suckless.org/patches/dwm-autoresize-6.0.diff b/dwm.suckless.org/patches/dwm-autoresize-6.0.diff @@ -0,0 +1,35 @@ +diff --git a/dwm.c b/dwm.c +index 1d78655..6c61aab 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -90,7 +90,7 @@ struct Client { + int basew, baseh, incw, inch, maxw, maxh, minw, minh; + int bw, oldbw; + unsigned int tags; +- Bool isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; ++ Bool isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, needresize; + Client *next; + Client *snext; + Monitor *mon; +@@ -626,6 +626,8 @@ configurerequest(XEvent *e) { + configure(c); + if(ISVISIBLE(c)) + XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); ++ else ++ c->needresize=1; + } + else + configure(c); +@@ -1644,6 +1646,12 @@ showhide(Client *c) { + return; + if(ISVISIBLE(c)) { /* show clients top down */ + XMoveWindow(dpy, c->win, c->x, c->y); ++ if(c->needresize) { ++ c->needresize=0; ++ XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); ++ } else { ++ XMoveWindow(dpy, c->win, c->x, c->y); ++ } + if((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen) + resize(c, c->x, c->y, c->w, c->h, False); + showhide(c->snext); diff --git a/dwm.suckless.org/patches/dwm-autoresize-6.1.diff b/dwm.suckless.org/patches/dwm-autoresize-6.1.diff @@ -0,0 +1,35 @@ +diff --git a/dwm.c b/dwm.c +index 0362114..e4e8514 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -92,7 +92,7 @@ struct Client { + int basew, baseh, incw, inch, maxw, maxh, minw, minh; + int bw, oldbw; + unsigned int tags; +- int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; ++ int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, needresize; + Client *next; + Client *snext; + Monitor *mon; +@@ -621,6 +621,8 @@ configurerequest(XEvent *e) + configure(c); + if (ISVISIBLE(c)) + XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); ++ else ++ c->needresize = 1; + } else + configure(c); + } else { +@@ -1611,6 +1613,12 @@ showhide(Client *c) + if (ISVISIBLE(c)) { + /* show clients top down */ + XMoveWindow(dpy, c->win, c->x, c->y); ++ if (c->needresize) { ++ c->needresize = 0; ++ XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); ++ } else { ++ XMoveWindow(dpy, c->win, c->x, c->y); ++ } + if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen) + resize(c, c->x, c->y, c->w, c->h, 0); + showhide(c->snext); diff --git a/dwm.suckless.org/patches/dwm-azertykey.diff b/dwm.suckless.org/patches/dwm-azertykey.diff @@ -1,44 +0,0 @@ -diff -up dwm-5.8.2//config.def.h dwm-5.8.2-fr//config.def.h ---- dwm-5.8.2//config.def.h 2010-06-04 12:39:15.000000000 +0200 -+++ dwm-5.8.2-fr//config.def.h 2011-04-21 08:49:36.000000000 +0200 -@@ -65,21 +65,21 @@ static Key keys[] = { - { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, - { MODKEY, XK_space, setlayout, {0} }, - { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, -- { MODKEY, XK_0, view, {.ui = ~0 } }, -- { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, -+ { MODKEY, XK_agrave, view, {.ui = ~0 } }, -+ { MODKEY|ShiftMask, XK_agrave, tag, {.ui = ~0 } }, - { MODKEY, XK_comma, focusmon, {.i = -1 } }, -- { MODKEY, XK_period, focusmon, {.i = +1 } }, -+ { MODKEY, XK_semicolon, focusmon, {.i = +1 } }, - { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, -- { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, -- TAGKEYS( XK_1, 0) -- TAGKEYS( XK_2, 1) -- TAGKEYS( XK_3, 2) -- TAGKEYS( XK_4, 3) -- TAGKEYS( XK_5, 4) -- TAGKEYS( XK_6, 5) -- TAGKEYS( XK_7, 6) -- TAGKEYS( XK_8, 7) -- TAGKEYS( XK_9, 8) -+ { MODKEY|ShiftMask, XK_semicolon, tagmon, {.i = +1 } }, -+ TAGKEYS( XK_ampersand, 0) -+ TAGKEYS( XK_eacute, 1) -+ TAGKEYS( XK_quotedbl, 2) -+ TAGKEYS( XK_apostrophe, 3) -+ TAGKEYS( XK_parenleft, 4) -+ TAGKEYS( XK_minus, 5) -+ TAGKEYS( XK_egrave, 6) -+ TAGKEYS( XK_underscore, 7) -+ TAGKEYS( XK_ccedilla, 8) - { MODKEY|ShiftMask, XK_q, quit, {0} }, - }; - -@@ -99,4 +99,3 @@ static Button buttons[] = { - { ClkTagBar, MODKEY, Button1, tag, {0} }, - { ClkTagBar, MODKEY, Button3, toggletag, {0} }, - }; -- -Seulement dans dwm-5.8.2/: config.def.h.rej diff --git a/dwm.suckless.org/patches/dwm-bottomstack-20160719-56a31dc.diff b/dwm.suckless.org/patches/dwm-bottomstack-20160719-56a31dc.diff @@ -0,0 +1,101 @@ +diff --git a/config.def.h b/config.def.h +index fd77a07..c3a044b 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -41,6 +41,8 @@ static const Layout layouts[] = { + { "[]=", tile }, /* first entry is default */ + { "><>", NULL }, /* no layout function means floating behavior */ + { "[M]", monocle }, ++ { "TTT", bstack }, ++ { "===", bstackhoriz }, + }; + + /* key definitions */ +@@ -76,6 +78,8 @@ static Key keys[] = { + { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, + { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, + { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, ++ { MODKEY, XK_u, setlayout, {.v = &layouts[3]} }, ++ { MODKEY, XK_o, setlayout, {.v = &layouts[4]} }, + { MODKEY, XK_space, setlayout, {0} }, + { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, + { MODKEY, XK_0, view, {.ui = ~0 } }, +diff --git a/dwm.c b/dwm.c +index b2bc9bd..8b74165 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -234,6 +234,8 @@ static int xerror(Display *dpy, XErrorEvent *ee); + static int xerrordummy(Display *dpy, XErrorEvent *ee); + static int xerrorstart(Display *dpy, XErrorEvent *ee); + static void zoom(const Arg *arg); ++static void bstack(Monitor *m); ++static void bstackhoriz(Monitor *m); + + /* variables */ + static const char broken[] = "broken"; +@@ -2138,3 +2140,65 @@ main(int argc, char *argv[]) + XCloseDisplay(dpy); + return EXIT_SUCCESS; + } ++ ++static void ++bstack(Monitor *m) { ++ int w, h, mh, mx, tx, ty, tw; ++ unsigned int i, n; ++ Client *c; ++ ++ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); ++ if (n == 0) ++ return; ++ if (n > m->nmaster) { ++ mh = m->nmaster ? m->mfact * m->wh : 0; ++ tw = m->ww / (n - m->nmaster); ++ ty = m->wy + mh; ++ } else { ++ mh = m->wh; ++ tw = m->ww; ++ ty = m->wy; ++ } ++ for (i = mx = 0, tx = m->wx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { ++ if (i < m->nmaster) { ++ w = (m->ww - mx) / (MIN(n, m->nmaster) - i); ++ resize(c, m->wx + mx, m->wy, w - (2 * c->bw), mh - (2 * c->bw), 0); ++ mx += WIDTH(c); ++ } else { ++ h = m->wh - mh; ++ resize(c, tx, ty, tw - (2 * c->bw), h - (2 * c->bw), 0); ++ if (tw != m->ww) ++ tx += WIDTH(c); ++ } ++ } ++} ++ ++static void ++bstackhoriz(Monitor *m) { ++ int w, mh, mx, tx, ty, th; ++ unsigned int i, n; ++ Client *c; ++ ++ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); ++ if (n == 0) ++ return; ++ if (n > m->nmaster) { ++ mh = m->nmaster ? m->mfact * m->wh : 0; ++ th = (m->wh - mh) / (n - m->nmaster); ++ ty = m->wy + mh; ++ } else { ++ th = mh = m->wh; ++ ty = m->wy; ++ } ++ for (i = mx = 0, tx = m->wx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { ++ if (i < m->nmaster) { ++ w = (m->ww - mx) / (MIN(n, m->nmaster) - i); ++ resize(c, m->wx + mx, m->wy, w - (2 * c->bw), mh - (2 * c->bw), 0); ++ mx += WIDTH(c); ++ } else { ++ resize(c, tx, ty, m->ww - (2 * c->bw), th - (2 * c->bw), 0); ++ if (th != m->wh) ++ ty += HEIGHT(c); ++ } ++ } ++} diff --git a/dwm.suckless.org/patches/dwm-bottomstack-6.1.diff b/dwm.suckless.org/patches/dwm-bottomstack-6.1.diff @@ -0,0 +1,101 @@ +diff --git a/config.def.h b/config.def.h +index 7054c06..554f1db 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -39,6 +39,8 @@ static const Layout layouts[] = { + { "[]=", tile }, /* first entry is default */ + { "><>", NULL }, /* no layout function means floating behavior */ + { "[M]", monocle }, ++ { "TTT", bstack }, ++ { "===", bstackhoriz }, + }; + + /* key definitions */ +@@ -74,6 +76,8 @@ static Key keys[] = { + { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, + { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, + { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, ++ { MODKEY, XK_u, setlayout, {.v = &layouts[3]} }, ++ { MODKEY, XK_o, setlayout, {.v = &layouts[4]} }, + { MODKEY, XK_space, setlayout, {0} }, + { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, + { MODKEY, XK_0, view, {.ui = ~0 } }, +diff --git a/dwm.c b/dwm.c +index 0362114..c313b5e 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -233,6 +233,8 @@ static int xerror(Display *dpy, XErrorEvent *ee); + static int xerrordummy(Display *dpy, XErrorEvent *ee); + static int xerrorstart(Display *dpy, XErrorEvent *ee); + static void zoom(const Arg *arg); ++static void bstack(Monitor *m); ++static void bstackhoriz(Monitor *m); + + /* variables */ + static const char broken[] = "broken"; +@@ -2139,3 +2141,65 @@ main(int argc, char *argv[]) + XCloseDisplay(dpy); + return EXIT_SUCCESS; + } ++ ++static void ++bstack(Monitor *m) { ++ int w, h, mh, mx, tx, ty, tw; ++ unsigned int i, n; ++ Client *c; ++ ++ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); ++ if (n == 0) ++ return; ++ if (n > m->nmaster) { ++ mh = m->nmaster ? m->mfact * m->wh : 0; ++ tw = m->ww / (n - m->nmaster); ++ ty = m->wy + mh; ++ } else { ++ mh = m->wh; ++ tw = m->ww; ++ ty = m->wy; ++ } ++ for (i = mx = 0, tx = m->wx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { ++ if (i < m->nmaster) { ++ w = (m->ww - mx) / (MIN(n, m->nmaster) - i); ++ resize(c, m->wx + mx, m->wy, w - (2 * c->bw), mh - (2 * c->bw), 0); ++ mx += WIDTH(c); ++ } else { ++ h = m->wh - mh; ++ resize(c, tx, ty, tw - (2 * c->bw), h - (2 * c->bw), 0); ++ if (tw != m->ww) ++ tx += WIDTH(c); ++ } ++ } ++} ++ ++static void ++bstackhoriz(Monitor *m) { ++ int w, mh, mx, tx, ty, th; ++ unsigned int i, n; ++ Client *c; ++ ++ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); ++ if (n == 0) ++ return; ++ if (n > m->nmaster) { ++ mh = m->nmaster ? m->mfact * m->wh : 0; ++ th = (m->wh - mh) / (n - m->nmaster); ++ ty = m->wy + mh; ++ } else { ++ th = mh = m->wh; ++ ty = m->wy; ++ } ++ for (i = mx = 0, tx = m->wx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { ++ if (i < m->nmaster) { ++ w = (m->ww - mx) / (MIN(n, m->nmaster) - i); ++ resize(c, m->wx + mx, m->wy, w - (2 * c->bw), mh - (2 * c->bw), 0); ++ mx += WIDTH(c); ++ } else { ++ resize(c, tx, ty, m->ww - (2 * c->bw), th - (2 * c->bw), 0); ++ if (th != m->wh) ++ ty += HEIGHT(c); ++ } ++ } ++} diff --git a/dwm.suckless.org/patches/dwm-cdec978-alwaysfullscreen.diff b/dwm.suckless.org/patches/dwm-cdec978-alwaysfullscreen.diff @@ -1,13 +0,0 @@ -diff --git a/dwm.c b/dwm.c -index 1bbb4b3..fe5069d 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -829,7 +829,7 @@ void - focusstack(const Arg *arg) { - Client *c = NULL, *i; - -- if(!selmon->sel) -+ if(!selmon->sel || selmon->sel->isfullscreen) - return; - if(arg->i > 0) { - for(c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next); diff --git a/dwm.suckless.org/patches/dwm-center-20160719-56a31dc.diff b/dwm.suckless.org/patches/dwm-center-20160719-56a31dc.diff @@ -0,0 +1,58 @@ +diff --git a/config.def.h b/config.def.h +index fd77a07..5bf4860 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -26,9 +26,9 @@ static const Rule rules[] = { + * WM_CLASS(STRING) = instance, class + * WM_NAME(STRING) = title + */ +- /* class instance title tags mask isfloating monitor */ +- { "Gimp", NULL, NULL, 0, 1, -1 }, +- { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, ++ /* class instance title tags mask iscentered isfloating monitor */ ++ { "Gimp", NULL, NULL, 0, 0, 1, -1 }, ++ { "Firefox", NULL, NULL, 1 << 8, 0, 0, -1 }, + }; + + /* layout(s) */ +diff --git a/dwm.c b/dwm.c +index b2bc9bd..72c9497 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -93,7 +93,7 @@ struct Client { + int basew, baseh, incw, inch, maxw, maxh, minw, minh; + int bw, oldbw; + unsigned int tags; +- int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; ++ int isfixed, iscentered, isfloating, isurgent, neverfocus, oldstate, isfullscreen; + Client *next; + Client *snext; + Monitor *mon; +@@ -138,6 +138,7 @@ typedef struct { + const char *instance; + const char *title; + unsigned int tags; ++ int iscentered; + int isfloating; + int monitor; + } Rule; +@@ -298,6 +299,7 @@ applyrules(Client *c) + && (!r->class || strstr(class, r->class)) + && (!r->instance || strstr(instance, r->instance))) + { ++ c->iscentered = r->iscentered; + c->isfloating = r->isfloating; + c->tags |= r->tags; + for (m = mons; m && m->num != r->monitor; m = m->next); +@@ -1066,6 +1068,11 @@ manage(Window w, XWindowAttributes *wa) + && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my); + c->bw = borderpx; + ++ if(c->iscentered) { ++ c->x = (c->mon->mw - WIDTH(c)) / 2; ++ c->y = (c->mon->mh - HEIGHT(c)) / 2; ++ } ++ + wc.border_width = c->bw; + XConfigureWindow(dpy, w, CWBorderWidth, &wc); + XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel); diff --git a/dwm.suckless.org/patches/dwm-6.1-center.diff b/dwm.suckless.org/patches/dwm-center-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-centeredmaster-20160719-56a31dc.diff b/dwm.suckless.org/patches/dwm-centeredmaster-20160719-56a31dc.diff @@ -0,0 +1,142 @@ +diff --git a/config.def.h b/config.def.h +index fd77a07..f025619 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -41,6 +41,8 @@ static const Layout layouts[] = { + { "[]=", tile }, /* first entry is default */ + { "><>", NULL }, /* no layout function means floating behavior */ + { "[M]", monocle }, ++ { "|M|", centeredmaster }, ++ { ">M>", centeredfloatingmaster }, + }; + + /* key definitions */ +@@ -76,6 +78,8 @@ static Key keys[] = { + { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, + { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, + { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, ++ { MODKEY, XK_u, setlayout, {.v = &layouts[3]} }, ++ { MODKEY, XK_o, setlayout, {.v = &layouts[4]} }, + { MODKEY, XK_space, setlayout, {0} }, + { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, + { MODKEY, XK_0, view, {.ui = ~0 } }, +diff --git a/dwm.c b/dwm.c +index b2bc9bd..9ecabae 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -234,6 +234,8 @@ static int xerror(Display *dpy, XErrorEvent *ee); + static int xerrordummy(Display *dpy, XErrorEvent *ee); + static int xerrorstart(Display *dpy, XErrorEvent *ee); + static void zoom(const Arg *arg); ++static void centeredmaster(Monitor *m); ++static void centeredfloatingmaster(Monitor *m); + + /* variables */ + static const char broken[] = "broken"; +@@ -2138,3 +2140,106 @@ main(int argc, char *argv[]) + XCloseDisplay(dpy); + return EXIT_SUCCESS; + } ++ ++void ++centeredmaster(Monitor *m) ++{ ++ unsigned int i, n, h, mw, mx, my, oty, ety, tw; ++ Client *c; ++ ++ /* count number of clients in the selected monitor */ ++ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); ++ if (n == 0) ++ return; ++ ++ /* initialize areas */ ++ mw = m->ww; ++ mx = 0; ++ my = 0; ++ tw = mw; ++ ++ if (n > m->nmaster) { ++ /* go mfact box in the center if more than nmaster clients */ ++ mw = m->nmaster ? m->ww * m->mfact : 0; ++ tw = m->ww - mw; ++ ++ if (n - m->nmaster > 1) { ++ /* only one client */ ++ mx = (m->ww - mw) / 2; ++ tw = (m->ww - mw) / 2; ++ } ++ } ++ ++ oty = 0; ++ ety = 0; ++ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) ++ if (i < m->nmaster) { ++ /* nmaster clients are stacked vertically, in the center ++ * of the screen */ ++ h = (m->wh - my) / (MIN(n, m->nmaster) - i); ++ resize(c, m->wx + mx, m->wy + my, mw - (2*c->bw), ++ h - (2*c->bw), 0); ++ my += HEIGHT(c); ++ } else { ++ /* stack clients are stacked vertically */ ++ if ((i - m->nmaster) % 2 ) { ++ h = (m->wh - ety) / ( (1 + n - i) / 2); ++ resize(c, m->wx, m->wy + ety, tw - (2*c->bw), ++ h - (2*c->bw), 0); ++ ety += HEIGHT(c); ++ } else { ++ h = (m->wh - oty) / ((1 + n - i) / 2); ++ resize(c, m->wx + mx + mw, m->wy + oty, ++ tw - (2*c->bw), h - (2*c->bw), 0); ++ oty += HEIGHT(c); ++ } ++ } ++} ++ ++void ++centeredfloatingmaster(Monitor *m) ++{ ++ unsigned int i, n, w, mh, mw, mx, mxo, my, myo, tx; ++ Client *c; ++ ++ /* count number of clients in the selected monitor */ ++ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); ++ if (n == 0) ++ return; ++ ++ /* initialize nmaster area */ ++ if (n > m->nmaster) { ++ /* go mfact box in the center if more than nmaster clients */ ++ if (m->ww > m->wh) { ++ mw = m->nmaster ? m->ww * m->mfact : 0; ++ mh = m->nmaster ? m->wh * 0.9 : 0; ++ } else { ++ mh = m->nmaster ? m->wh * m->mfact : 0; ++ mw = m->nmaster ? m->ww * 0.9 : 0; ++ } ++ mx = mxo = (m->ww - mw) / 2; ++ my = myo = (m->wh - mh) / 2; ++ } else { ++ /* go fullscreen if all clients are in the master area */ ++ mh = m->wh; ++ mw = m->ww; ++ mx = mxo = 0; ++ my = myo = 0; ++ } ++ ++ for(i = tx = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) ++ if (i < m->nmaster) { ++ /* nmaster clients are stacked horizontally, in the center ++ * of the screen */ ++ w = (mw + mxo - mx) / (MIN(n, m->nmaster) - i); ++ resize(c, m->wx + mx, m->wy + my, w - (2*c->bw), ++ mh - (2*c->bw), 0); ++ mx += WIDTH(c); ++ } else { ++ /* stack clients are stacked horizontally */ ++ w = (m->ww - tx) / (n - i); ++ resize(c, m->wx + tx, m->wy, w - (2*c->bw), ++ m->wh - (2*c->bw), 0); ++ tx += WIDTH(c); ++ } ++} diff --git a/dwm.suckless.org/patches/dwm-centeredmaster-6.1.diff b/dwm.suckless.org/patches/dwm-centeredmaster-6.1.diff @@ -0,0 +1,142 @@ +diff --git a/config.def.h b/config.def.h +index 7054c06..527b214 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -39,6 +39,8 @@ static const Layout layouts[] = { + { "[]=", tile }, /* first entry is default */ + { "><>", NULL }, /* no layout function means floating behavior */ + { "[M]", monocle }, ++ { "|M|", centeredmaster }, ++ { ">M>", centeredfloatingmaster }, + }; + + /* key definitions */ +@@ -74,6 +76,8 @@ static Key keys[] = { + { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, + { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, + { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, ++ { MODKEY, XK_u, setlayout, {.v = &layouts[3]} }, ++ { MODKEY, XK_o, setlayout, {.v = &layouts[4]} }, + { MODKEY, XK_space, setlayout, {0} }, + { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, + { MODKEY, XK_0, view, {.ui = ~0 } }, +diff --git a/dwm.c b/dwm.c +index 0362114..1e81412 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -233,6 +233,8 @@ static int xerror(Display *dpy, XErrorEvent *ee); + static int xerrordummy(Display *dpy, XErrorEvent *ee); + static int xerrorstart(Display *dpy, XErrorEvent *ee); + static void zoom(const Arg *arg); ++static void centeredmaster(Monitor *m); ++static void centeredfloatingmaster(Monitor *m); + + /* variables */ + static const char broken[] = "broken"; +@@ -2139,3 +2141,106 @@ main(int argc, char *argv[]) + XCloseDisplay(dpy); + return EXIT_SUCCESS; + } ++ ++void ++centeredmaster(Monitor *m) ++{ ++ unsigned int i, n, h, mw, mx, my, oty, ety, tw; ++ Client *c; ++ ++ /* count number of clients in the selected monitor */ ++ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); ++ if (n == 0) ++ return; ++ ++ /* initialize areas */ ++ mw = m->ww; ++ mx = 0; ++ my = 0; ++ tw = mw; ++ ++ if (n > m->nmaster) { ++ /* go mfact box in the center if more than nmaster clients */ ++ mw = m->nmaster ? m->ww * m->mfact : 0; ++ tw = m->ww - mw; ++ ++ if (n - m->nmaster > 1) { ++ /* only one client */ ++ mx = (m->ww - mw) / 2; ++ tw = (m->ww - mw) / 2; ++ } ++ } ++ ++ oty = 0; ++ ety = 0; ++ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) ++ if (i < m->nmaster) { ++ /* nmaster clients are stacked vertically, in the center ++ * of the screen */ ++ h = (m->wh - my) / (MIN(n, m->nmaster) - i); ++ resize(c, m->wx + mx, m->wy + my, mw - (2*c->bw), ++ h - (2*c->bw), 0); ++ my += HEIGHT(c); ++ } else { ++ /* stack clients are stacked vertically */ ++ if ((i - m->nmaster) % 2 ) { ++ h = (m->wh - ety) / ( (1 + n - i) / 2); ++ resize(c, m->wx, m->wy + ety, tw - (2*c->bw), ++ h - (2*c->bw), 0); ++ ety += HEIGHT(c); ++ } else { ++ h = (m->wh - oty) / ((1 + n - i) / 2); ++ resize(c, m->wx + mx + mw, m->wy + oty, ++ tw - (2*c->bw), h - (2*c->bw), 0); ++ oty += HEIGHT(c); ++ } ++ } ++} ++ ++void ++centeredfloatingmaster(Monitor *m) ++{ ++ unsigned int i, n, w, mh, mw, mx, mxo, my, myo, tx; ++ Client *c; ++ ++ /* count number of clients in the selected monitor */ ++ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); ++ if (n == 0) ++ return; ++ ++ /* initialize nmaster area */ ++ if (n > m->nmaster) { ++ /* go mfact box in the center if more than nmaster clients */ ++ if (m->ww > m->wh) { ++ mw = m->nmaster ? m->ww * m->mfact : 0; ++ mh = m->nmaster ? m->wh * 0.9 : 0; ++ } else { ++ mh = m->nmaster ? m->wh * m->mfact : 0; ++ mw = m->nmaster ? m->ww * 0.9 : 0; ++ } ++ mx = mxo = (m->ww - mw) / 2; ++ my = myo = (m->wh - mh) / 2; ++ } else { ++ /* go fullscreen if all clients are in the master area */ ++ mh = m->wh; ++ mw = m->ww; ++ mx = mxo = 0; ++ my = myo = 0; ++ } ++ ++ for(i = tx = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) ++ if (i < m->nmaster) { ++ /* nmaster clients are stacked horizontally, in the center ++ * of the screen */ ++ w = (mw + mxo - mx) / (MIN(n, m->nmaster) - i); ++ resize(c, m->wx + mx, m->wy + my, w - (2*c->bw), ++ mh - (2*c->bw), 0); ++ mx += WIDTH(c); ++ } else { ++ /* stack clients are stacked horizontally */ ++ w = (m->ww - tx) / (n - i); ++ resize(c, m->wx + tx, m->wy, w - (2*c->bw), ++ m->wh - (2*c->bw), 0); ++ tx += WIDTH(c); ++ } ++} diff --git a/dwm.suckless.org/patches/dwm-5.6.1-cpt.diff b/dwm.suckless.org/patches/dwm-clientspertag-5.6.1.diff diff --git a/dwm.suckless.org/patches/dwm-6.0-column_master.diff b/dwm.suckless.org/patches/dwm-columns-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-5.9-combo.diff b/dwm.suckless.org/patches/dwm-combo-5.9.diff diff --git a/dwm.suckless.org/patches/dwm-6.0-combo.diff b/dwm.suckless.org/patches/dwm-combo-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-6.1-combo.diff b/dwm.suckless.org/patches/dwm-combo-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-5.8.2-current_desktop.diff b/dwm.suckless.org/patches/dwm-current_desktop-5.8.2.diff diff --git a/dwm.suckless.org/patches/dwm-6.0-dualstatus.diff b/dwm.suckless.org/patches/dwm-dualstatus-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-6.1-dualstatus.diff b/dwm.suckless.org/patches/dwm-dualstatus-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-dwmfifo-6.1.diff b/dwm.suckless.org/patches/dwm-dwmfifo-6.1.diff @@ -0,0 +1,217 @@ +diff --git a/config.def.h b/config.def.h +index 7054c06..9f4ef79 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -111,3 +111,65 @@ static Button buttons[] = { + { ClkTagBar, MODKEY, Button3, toggletag, {0} }, + }; + ++static const char *dwmfifo = "/tmp/dwm.fifo"; ++static Command commands[] = { ++ { "dmenu", spawn, {.v = dmenucmd} }, ++ { "term", spawn, {.v = termcmd} }, ++ { "togglebar", togglebar, {0} }, ++ { "focusstack+", focusstack, {.i = +1} }, ++ { "focusstack-", focusstack, {.i = -1} }, ++ { "incnmaster+", incnmaster, {.i = +1} }, ++ { "incnmaster-", incnmaster, {.i = -1} }, ++ { "setmfact+", setmfact, {.f = +0.05} }, ++ { "setmfact-", setmfact, {.f = -0.05} }, ++ { "zoom", zoom, {0} }, ++ { "view", view, {0} }, ++ { "killclient", killclient, {0} }, ++ { "setlayout-tiled", setlayout, {.v = &layouts[0]} }, ++ { "setlayout-float", setlayout, {.v = &layouts[1]} }, ++ { "setlayout-mono", setlayout, {.v = &layouts[2]} }, ++ { "togglelayout", setlayout, {0} }, ++ { "togglefloating", togglefloating, {0} }, ++ { "viewall", view, {.ui = ~0} }, ++ { "tag", tag, {.ui = ~0} }, ++ { "focusmon+", focusmon, {.i = +1} }, ++ { "focusmon-", focusmon, {.i = -1} }, ++ { "tagmon+", tagmon, {.i = +1} }, ++ { "tagmon-", tagmon, {.i = -1} }, ++ { "view1", view, {.ui = 1 << 0} }, ++ { "view2", view, {.ui = 1 << 1} }, ++ { "view3", view, {.ui = 1 << 2} }, ++ { "view4", view, {.ui = 1 << 3} }, ++ { "view5", view, {.ui = 1 << 4} }, ++ { "view6", view, {.ui = 1 << 5} }, ++ { "view7", view, {.ui = 1 << 6} }, ++ { "view8", view, {.ui = 1 << 7} }, ++ { "view9", view, {.ui = 1 << 8} }, ++ { "toggleview1", toggleview, {.ui = 1 << 0} }, ++ { "toggleview2", toggleview, {.ui = 1 << 1} }, ++ { "toggleview3", toggleview, {.ui = 1 << 2} }, ++ { "toggleview4", toggleview, {.ui = 1 << 3} }, ++ { "toggleview5", toggleview, {.ui = 1 << 4} }, ++ { "toggleview6", toggleview, {.ui = 1 << 5} }, ++ { "toggleview7", toggleview, {.ui = 1 << 6} }, ++ { "toggleview8", toggleview, {.ui = 1 << 7} }, ++ { "toggleview9", toggleview, {.ui = 1 << 8} }, ++ { "tag1", tag, {.ui = 1 << 0} }, ++ { "tag2", tag, {.ui = 1 << 1} }, ++ { "tag3", tag, {.ui = 1 << 2} }, ++ { "tag4", tag, {.ui = 1 << 3} }, ++ { "tag5", tag, {.ui = 1 << 4} }, ++ { "tag6", tag, {.ui = 1 << 5} }, ++ { "tag7", tag, {.ui = 1 << 6} }, ++ { "tag8", tag, {.ui = 1 << 7} }, ++ { "tag9", tag, {.ui = 1 << 8} }, ++ { "toggletag1", toggletag, {.ui = 1 << 0} }, ++ { "toggletag2", toggletag, {.ui = 1 << 1} }, ++ { "toggletag3", toggletag, {.ui = 1 << 2} }, ++ { "toggletag4", toggletag, {.ui = 1 << 3} }, ++ { "toggletag5", toggletag, {.ui = 1 << 4} }, ++ { "toggletag6", toggletag, {.ui = 1 << 5} }, ++ { "toggletag7", toggletag, {.ui = 1 << 6} }, ++ { "toggletag8", toggletag, {.ui = 1 << 7} }, ++ { "toggletag9", toggletag, {.ui = 1 << 8} }, ++}; +diff --git a/dwm.c b/dwm.c +index 0362114..5c45d2a 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -21,6 +21,7 @@ + * To understand everything else, start reading main(). + */ + #include <errno.h> ++#include <fcntl.h> + #include <locale.h> + #include <signal.h> + #include <stdarg.h> +@@ -28,6 +29,8 @@ + #include <stdlib.h> + #include <string.h> + #include <unistd.h> ++#include <sys/select.h> ++#include <sys/stat.h> + #include <sys/types.h> + #include <sys/wait.h> + #include <X11/cursorfont.h> +@@ -141,6 +144,12 @@ typedef struct { + int monitor; + } Rule; + ++typedef struct { ++ const char *name; ++ void (*func)(const Arg *arg); ++ const Arg arg; ++} Command; ++ + /* function declarations */ + static void applyrules(Client *c); + static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact); +@@ -162,9 +171,11 @@ static void destroynotify(XEvent *e); + static void detach(Client *c); + static void detachstack(Client *c); + static Monitor *dirtomon(int dir); ++static void dispatchcmd(void); + static void drawbar(Monitor *m); + static void drawbars(void); + static void enternotify(XEvent *e); ++static Bool evpredicate(); + static void expose(XEvent *e); + static void focus(Client *c); + static void focusin(XEvent *e); +@@ -266,6 +277,7 @@ static Display *dpy; + static Drw *drw; + static Monitor *mons, *selmon; + static Window root; ++static int fifofd; + + /* configuration, allows nested code to access above variables */ + #include "config.h" +@@ -490,6 +502,7 @@ cleanup(void) + XSync(dpy, False); + XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); + XDeleteProperty(dpy, root, netatom[NetActiveWindow]); ++ close(fifofd); + } + + void +@@ -702,6 +715,25 @@ dirtomon(int dir) + } + + void ++dispatchcmd(void) ++{ ++ int i; ++ char buf[BUFSIZ]; ++ ssize_t n; ++ ++ n = read(fifofd, buf, sizeof(buf) - 1); ++ if (n == -1) ++ die("Failed to read() from DWM fifo %s:", dwmfifo); ++ buf[n] = '\0'; ++ for (i = 0; i < LENGTH(commands); i++) { ++ if (strcmp(commands[i].name, buf) == 0) { ++ commands[i].func(&commands[i].arg); ++ break; ++ } ++ } ++} ++ ++void + drawbar(Monitor *m) + { + int x, xx, w, dx; +@@ -781,6 +813,12 @@ enternotify(XEvent *e) + focus(c); + } + ++Bool ++evpredicate() ++{ ++ return True; ++} ++ + void + expose(XEvent *e) + { +@@ -1390,11 +1428,30 @@ void + run(void) + { + XEvent ev; +- /* main event loop */ +- XSync(dpy, False); +- while (running && !XNextEvent(dpy, &ev)) +- if (handler[ev.type]) +- handler[ev.type](&ev); /* call handler */ ++ fd_set rfds; ++ int n; ++ int dpyfd, maxfd; ++ /* main event loop */ ++ XSync(dpy, False); ++ dpyfd = ConnectionNumber(dpy); ++ maxfd = fifofd; ++ if (dpyfd > maxfd) ++ maxfd = dpyfd; ++ maxfd++; ++ while (running) { ++ FD_ZERO(&rfds); ++ FD_SET(fifofd, &rfds); ++ FD_SET(dpyfd, &rfds); ++ n = select(maxfd, &rfds, NULL, NULL, NULL); ++ if (n > 0) { ++ if (FD_ISSET(fifofd, &rfds)) ++ dispatchcmd(); ++ if (FD_ISSET(dpyfd, &rfds)) ++ while (XCheckIfEvent(dpy, &ev, evpredicate, NULL)) ++ if (handler[ev.type]) ++ handler[ev.type](&ev); /* call handler */ ++ } ++ } + } + + void +@@ -1601,6 +1658,9 @@ setup(void) + XSelectInput(dpy, root, wa.event_mask); + grabkeys(); + focus(NULL); ++ fifofd = open(dwmfifo, O_RDWR | O_NONBLOCK); ++ if (fifofd < 0) ++ die("Failed to open() DWM fifo %s:", dwmfifo); + } + + void diff --git a/dwm.suckless.org/patches/dwm-6.0-emptyview.diff b/dwm.suckless.org/patches/dwm-emptyview-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-6.1-fancybar.diff b/dwm.suckless.org/patches/dwm-fancybar-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-fancybar-git-20160725-7af4d43.diff b/dwm.suckless.org/patches/dwm-fancybar-git-20160725-7af4d43.diff @@ -0,0 +1,74 @@ +diff --git a/dwm.c b/dwm.c +index b2bc9bd..32e94a7 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -708,10 +708,10 @@ dirtomon(int dir) + void + drawbar(Monitor *m) + { +- int x, w, sw = 0; ++ int x, w, sw = 0, tw, mw, ew = 0; + int boxs = drw->fonts->h / 9; + int boxw = drw->fonts->h / 6 + 2; +- unsigned int i, occ = 0, urg = 0; ++ unsigned int i, occ = 0, urg = 0, n = 0; + Client *c; + + /* draw status first so it can be overdrawn by tags later */ +@@ -722,6 +722,8 @@ drawbar(Monitor *m) + } + + for (c = m->clients; c; c = c->next) { ++ if (ISVISIBLE(c)) ++ n++; + occ |= c->tags; + if (c->isurgent) + urg |= c->tags; +@@ -742,15 +744,39 @@ drawbar(Monitor *m) + x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); + + if ((w = m->ww - sw - x) > bh) { +- if (m->sel) { +- drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); +- drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); +- if (m->sel->isfloating) +- drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0); +- } else { +- drw_setscheme(drw, scheme[SchemeNorm]); +- drw_rect(drw, x, 0, w, bh, 1, 1); ++ if (n > 0) { ++ tw = TEXTW(m->sel->name); ++ mw = (tw >= w || n == 1) ? 0 : (w - tw) / (n - 1); ++ ++ i = 0; ++ for (c = m->clients; c; c = c->next) { ++ if (!ISVISIBLE(c) || c == m->sel) ++ continue; ++ tw = TEXTW(c->name); ++ if(tw < mw) ++ ew += (mw - tw); ++ else ++ i++; ++ } ++ if (i > 0) ++ mw += ew / i; ++ ++ for (c = m->clients; c; c = c->next) { ++ if (!ISVISIBLE(c)) ++ continue; ++ tw = MIN(m->sel == c ? w : mw, TEXTW(c->name)); ++ ++ drw_setscheme(drw, scheme[m->sel == c ? SchemeSel : SchemeNorm]); ++ if (tw > 0) /* trap special handling of 0 in drw_text */ ++ drw_text(drw, x, 0, tw, bh, lrpad / 2, c->name, 0); ++ if (c->isfloating) ++ drw_rect(drw, x + boxs, boxs, boxw, boxw, c->isfixed, 0); ++ x += tw; ++ w -= tw; ++ } + } ++ drw_setscheme(drw, scheme[SchemeNorm]); ++ drw_rect(drw, x, 0, w, bh, 1, 1); + } + drw_map(drw, m->barwin, 0, 0, m->ww, bh); + } diff --git a/dwm.suckless.org/patches/dwm-5.8.2-fibonacci.diff b/dwm.suckless.org/patches/dwm-fibonacci-5.8.2.diff diff --git a/dwm.suckless.org/patches/flextile-5.8.2.diff b/dwm.suckless.org/patches/dwm-flextile-5.8.2.diff diff --git a/dwm.suckless.org/patches/dwm-6.0-float_border_color2.diff b/dwm.suckless.org/patches/dwm-float_border_color-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-6.1-float_border_color2.diff b/dwm.suckless.org/patches/dwm-float_border_color-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-float_border_color2-20160731-56a31dc.diff b/dwm.suckless.org/patches/dwm-float_border_color2-20160731-56a31dc.diff @@ -0,0 +1,90 @@ +URL: http://dwm.suckless.org/patches/historical/float_border_color +float_border_color2 allows you to specify a different border color for floating +windows. + +Index: dwm/config.def.h +=================================================================== +--- dwm/config.def.h.orig ++++ dwm/config.def.h +@@ -12,10 +12,10 @@ static const char col_gray2[] = "# + static const char col_gray3[] = "#bbbbbb"; + static const char col_gray4[] = "#eeeeee"; + static const char col_cyan[] = "#005577"; +-static const char *colors[SchemeLast][3] = { +- /* fg bg border */ +- [SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, +- [SchemeSel] = { col_gray4, col_cyan, col_cyan }, ++static const char *colors[SchemeLast][4] = { ++ /* fg bg border float */ ++ [SchemeNorm] = { col_gray3, col_gray1, col_gray2, col_gray2 }, ++ [SchemeSel] = { col_gray4, col_cyan, col_gray2, col_cyan }, + }; + + /* tagging */ +Index: dwm/dwm.c +=================================================================== +--- dwm/dwm.c.orig ++++ dwm/dwm.c +@@ -57,6 +57,7 @@ + #define TAGMASK ((1 << LENGTH(tags)) - 1) + #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) + #define ColBorder 2 ++#define ColFloat 3 + + /* enums */ + enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ +@@ -809,7 +810,10 @@ focus(Client *c) + detachstack(c); + attachstack(c); + grabbuttons(c, 1); +- XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel); ++ if(c->isfloating) ++ XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColFloat].pixel); ++ else ++ XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel); + setfocus(c); + } else { + XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); +@@ -1068,7 +1072,10 @@ manage(Window w, XWindowAttributes *wa) + + wc.border_width = c->bw; + XConfigureWindow(dpy, w, CWBorderWidth, &wc); +- XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel); ++ if(c->isfloating) ++ XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColFloat].pixel); ++ else ++ XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel); + configure(c); /* propagates border_width, if size doesn't change */ + updatewindowtype(c); + updatesizehints(c); +@@ -1079,6 +1086,8 @@ manage(Window w, XWindowAttributes *wa) + c->isfloating = c->oldstate = trans != None || c->isfixed; + if (c->isfloating) + XRaiseWindow(dpy, c->win); ++ if(c->isfloating) ++ XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColFloat].pixel); + attach(c); + attachstack(c); + XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, +@@ -1583,8 +1592,8 @@ setup(void) + cursor[CurResize] = drw_cur_create(drw, XC_sizing); + cursor[CurMove] = drw_cur_create(drw, XC_fleur); + /* init appearance */ +- scheme[SchemeNorm] = drw_scm_create(drw, colors[SchemeNorm], 3); +- scheme[SchemeSel] = drw_scm_create(drw, colors[SchemeSel], 3); ++ scheme[SchemeNorm] = drw_scm_create(drw, colors[SchemeNorm], 4); ++ scheme[SchemeSel] = drw_scm_create(drw, colors[SchemeSel], 4); + /* init bars */ + updatebars(); + updatestatus(); +@@ -1706,6 +1715,10 @@ togglefloating(const Arg *arg) + return; + selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; + if (selmon->sel->isfloating) ++ XSetWindowBorder(dpy, selmon->sel->win, scheme[SchemeSel][ColFloat].pixel); ++ else ++ XSetWindowBorder(dpy, selmon->sel->win, scheme[SchemeSel][ColBorder].pixel); ++ if(selmon->sel->isfloating) + resize(selmon->sel, selmon->sel->x, selmon->sel->y, + selmon->sel->w, selmon->sel->h, 0); + arrange(selmon); diff --git a/dwm.suckless.org/patches/dwm-6.0-focusonclick.diff b/dwm.suckless.org/patches/dwm-focusonclick-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-gaplessgrid-20160731-56a31dc.diff b/dwm.suckless.org/patches/dwm-gaplessgrid-20160731-56a31dc.diff @@ -0,0 +1,43 @@ +URL: http://dwm.suckless.org/patches/gapless_grid +Add gapless grid layout. + +Index: dwm/gaplessgrid.c +=================================================================== +--- /dev/null ++++ dwm/gaplessgrid.c +@@ -0,0 +1,35 @@ ++void ++gaplessgrid(Monitor *m) { ++ unsigned int n, cols, rows, cn, rn, i, cx, cy, cw, ch; ++ Client *c; ++ ++ for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) ; ++ if(n == 0) ++ return; ++ ++ /* grid dimensions */ ++ for(cols = 0; cols <= n/2; cols++) ++ if(cols*cols >= n) ++ break; ++ if(n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */ ++ cols = 2; ++ rows = n/cols; ++ ++ /* window geometries */ ++ cw = cols ? m->ww / cols : m->ww; ++ cn = 0; /* current column number */ ++ rn = 0; /* current row number */ ++ for(i = 0, c = nexttiled(m->clients); c; i++, c = nexttiled(c->next)) { ++ if(i/rows + 1 > cols - n%cols) ++ rows = n/cols + 1; ++ ch = rows ? m->wh / rows : m->wh; ++ cx = m->wx + cn*cw; ++ cy = m->wy + rn*ch; ++ resize(c, cx, cy, cw - 2 * c->bw, ch - 2 * c->bw, False); ++ rn++; ++ if(rn >= rows) { ++ rn = 0; ++ cn++; ++ } ++ } ++} diff --git a/dwm.suckless.org/patches/dwm-6.1-gaplessgrid.diff b/dwm.suckless.org/patches/dwm-gaplessgrid-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-6.0-gaps.diff b/dwm.suckless.org/patches/dwm-gaps-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-5.8.2-gridmode.diff b/dwm.suckless.org/patches/dwm-gridmode-5.8.2.diff diff --git a/dwm.suckless.org/patches/dwm-6.1-hide_vacant_tags.diff b/dwm.suckless.org/patches/dwm-hide_vacant_tags-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-hide_vacant_tags-git-20160626-7af4d43.diff b/dwm.suckless.org/patches/dwm-hide_vacant_tags-git-20160626-7af4d43.diff @@ -0,0 +1,52 @@ +diff --git a/dwm.c b/dwm.c +index b2bc9bd..d9a333a 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -417,7 +417,7 @@ attachstack(Client *c) + void + buttonpress(XEvent *e) + { +- unsigned int i, x, click; ++ unsigned int i, x, click, occ = 0; + Arg arg = {0}; + Client *c; + Monitor *m; +@@ -432,9 +432,13 @@ buttonpress(XEvent *e) + } + if (ev->window == selmon->barwin) { + i = x = 0; +- do ++ for (c = m->clients; c; c = c->next) ++ occ |= c->tags == 255 ? 0 : c->tags; ++ do { ++ if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) ++ continue; + x += TEXTW(tags[i]); +- while (ev->x >= x && ++i < LENGTH(tags)); ++ } while (ev->x >= x && ++i < LENGTH(tags)); + if (i < LENGTH(tags)) { + click = ClkTagBar; + arg.ui = 1 << i; +@@ -722,19 +726,17 @@ drawbar(Monitor *m) + } + + for (c = m->clients; c; c = c->next) { +- occ |= c->tags; ++ occ |= c->tags == 255 ? 0 : c->tags; + if (c->isurgent) + urg |= c->tags; + } + x = 0; + for (i = 0; i < LENGTH(tags); i++) { ++ if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) ++ continue; + w = TEXTW(tags[i]); + drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]); + drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i); +- if (occ & 1 << i) +- drw_rect(drw, x + boxs, boxs, boxw, boxw, +- m == selmon && selmon->sel && selmon->sel->tags & 1 << i, +- urg & 1 << i); + x += w; + } + w = blw = TEXTW(m->ltsymbol); diff --git a/dwm.suckless.org/patches/dwm-6.1-horizgrid.diff b/dwm.suckless.org/patches/dwm-horizgrid-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-keycode-20160702-56a31dc.diff b/dwm.suckless.org/patches/dwm-keycode-20160702-56a31dc.diff @@ -0,0 +1,133 @@ +diff --git a/config.def.h b/config.def.h +index fd77a07..7a568df 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -60,40 +60,40 @@ static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, + static const char *termcmd[] = { "st", NULL }; + + static Key keys[] = { +- /* modifier key function argument */ +- { MODKEY, XK_p, spawn, {.v = dmenucmd } }, +- { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, +- { MODKEY, XK_b, togglebar, {0} }, +- { MODKEY, XK_j, focusstack, {.i = +1 } }, +- { MODKEY, XK_k, focusstack, {.i = -1 } }, +- { MODKEY, XK_i, incnmaster, {.i = +1 } }, +- { MODKEY, XK_d, incnmaster, {.i = -1 } }, +- { MODKEY, XK_h, setmfact, {.f = -0.05} }, +- { MODKEY, XK_l, setmfact, {.f = +0.05} }, +- { MODKEY, XK_Return, zoom, {0} }, +- { MODKEY, XK_Tab, view, {0} }, +- { MODKEY|ShiftMask, XK_c, killclient, {0} }, +- { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, +- { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, +- { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, +- { MODKEY, XK_space, setlayout, {0} }, +- { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, +- { MODKEY, XK_0, view, {.ui = ~0 } }, +- { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, +- { MODKEY, XK_comma, focusmon, {.i = -1 } }, +- { MODKEY, XK_period, focusmon, {.i = +1 } }, +- { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, +- { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, +- TAGKEYS( XK_1, 0) +- TAGKEYS( XK_2, 1) +- TAGKEYS( XK_3, 2) +- TAGKEYS( XK_4, 3) +- TAGKEYS( XK_5, 4) +- TAGKEYS( XK_6, 5) +- TAGKEYS( XK_7, 6) +- TAGKEYS( XK_8, 7) +- TAGKEYS( XK_9, 8) +- { MODKEY|ShiftMask, XK_q, quit, {0} }, ++ /* modifier key function argument */ ++ { MODKEY, 33, spawn, {.v = dmenucmd } }, // p ++ { MODKEY|ShiftMask, 36, spawn, {.v = termcmd } }, // Return ++ { MODKEY, 56, togglebar, {0} }, // b ++ { MODKEY, 44, focusstack, {.i = +1 } }, // j ++ { MODKEY, 45, focusstack, {.i = -1 } }, // k ++ { MODKEY, 31, incnmaster, {.i = +1 } }, // i ++ { MODKEY, 40, incnmaster, {.i = -1 } }, // d ++ { MODKEY, 43, setmfact, {.f = -0.05} }, // h ++ { MODKEY, 46, setmfact, {.f = +0.05} }, // l ++ { MODKEY, 36, zoom, {0} }, // Return ++ { MODKEY, 23, view, {0} }, // Tab ++ { MODKEY|ShiftMask, 54, killclient, {0} }, // c ++ { MODKEY, 28, setlayout, {.v = &layouts[0]} }, // t ++ { MODKEY, 41, setlayout, {.v = &layouts[1]} }, // f ++ { MODKEY, 58, setlayout, {.v = &layouts[2]} }, // m ++ { MODKEY, 65, setlayout, {0} }, // space ++ { MODKEY|ShiftMask, 65, togglefloating, {0} }, // space ++ { MODKEY, 19, view, {.ui = ~0 } }, // 0 ++ { MODKEY|ShiftMask, 19, tag, {.ui = ~0 } }, // 0 ++ { MODKEY, 59, focusmon, {.i = -1 } }, // comma ++ { MODKEY, 60, focusmon, {.i = +1 } }, // period ++ { MODKEY|ShiftMask, 59, tagmon, {.i = -1 } }, // comma ++ { MODKEY|ShiftMask, 60, tagmon, {.i = +1 } }, // period ++ TAGKEYS( 10, 0) // 1 ++ TAGKEYS( 11, 1) // 2 ++ TAGKEYS( 12, 2) // 3 ++ TAGKEYS( 13, 3) // 4 ++ TAGKEYS( 14, 4) // 5 ++ TAGKEYS( 15, 5) // 6 ++ TAGKEYS( 16, 6) // 7 ++ TAGKEYS( 17, 7) // 8 ++ TAGKEYS( 18, 8) // 9 ++ { MODKEY|ShiftMask, 24, quit, {0} }, // q + }; + + /* button definitions */ +diff --git a/dwm.c b/dwm.c +index b2bc9bd..f36285a 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -31,7 +31,6 @@ + #include <sys/types.h> + #include <sys/wait.h> + #include <X11/cursorfont.h> +-#include <X11/keysym.h> + #include <X11/Xatom.h> + #include <X11/Xlib.h> + #include <X11/Xproto.h> +@@ -102,7 +101,7 @@ struct Client { + + typedef struct { + unsigned int mod; +- KeySym keysym; ++ KeyCode keycode; + void (*func)(const Arg *); + const Arg arg; + } Key; +@@ -969,14 +968,12 @@ grabkeys(void) + { + unsigned int i, j; + unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; +- KeyCode code; + + XUngrabKey(dpy, AnyKey, AnyModifier, root); + for (i = 0; i < LENGTH(keys); i++) +- if ((code = XKeysymToKeycode(dpy, keys[i].keysym))) +- for (j = 0; j < LENGTH(modifiers); j++) +- XGrabKey(dpy, code, keys[i].mod | modifiers[j], root, +- True, GrabModeAsync, GrabModeAsync); ++ for (j = 0; j < LENGTH(modifiers); j++) ++ XGrabKey(dpy, keys[i].keycode, keys[i].mod | modifiers[j], root, ++ True, GrabModeAsync, GrabModeAsync); + } + } + +@@ -1003,13 +1000,11 @@ void + keypress(XEvent *e) + { + unsigned int i; +- KeySym keysym; + XKeyEvent *ev; + + ev = &e->xkey; +- keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); + for (i = 0; i < LENGTH(keys); i++) +- if (keysym == keys[i].keysym ++ if (ev->keycode == keys[i].keycode + && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) + && keys[i].func) + keys[i].func(&(keys[i].arg)); diff --git a/dwm.suckless.org/patches/dwm-keycode-6.1.diff b/dwm.suckless.org/patches/dwm-keycode-6.1.diff @@ -0,0 +1,133 @@ +diff --git a/config.def.h b/config.def.h +index 7054c06..f59d1eb 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -58,40 +58,40 @@ static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, + static const char *termcmd[] = { "st", NULL }; + + static Key keys[] = { +- /* modifier key function argument */ +- { MODKEY, XK_p, spawn, {.v = dmenucmd } }, +- { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, +- { MODKEY, XK_b, togglebar, {0} }, +- { MODKEY, XK_j, focusstack, {.i = +1 } }, +- { MODKEY, XK_k, focusstack, {.i = -1 } }, +- { MODKEY, XK_i, incnmaster, {.i = +1 } }, +- { MODKEY, XK_d, incnmaster, {.i = -1 } }, +- { MODKEY, XK_h, setmfact, {.f = -0.05} }, +- { MODKEY, XK_l, setmfact, {.f = +0.05} }, +- { MODKEY, XK_Return, zoom, {0} }, +- { MODKEY, XK_Tab, view, {0} }, +- { MODKEY|ShiftMask, XK_c, killclient, {0} }, +- { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, +- { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, +- { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, +- { MODKEY, XK_space, setlayout, {0} }, +- { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, +- { MODKEY, XK_0, view, {.ui = ~0 } }, +- { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, +- { MODKEY, XK_comma, focusmon, {.i = -1 } }, +- { MODKEY, XK_period, focusmon, {.i = +1 } }, +- { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, +- { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, +- TAGKEYS( XK_1, 0) +- TAGKEYS( XK_2, 1) +- TAGKEYS( XK_3, 2) +- TAGKEYS( XK_4, 3) +- TAGKEYS( XK_5, 4) +- TAGKEYS( XK_6, 5) +- TAGKEYS( XK_7, 6) +- TAGKEYS( XK_8, 7) +- TAGKEYS( XK_9, 8) +- { MODKEY|ShiftMask, XK_q, quit, {0} }, ++ /* modifier key function argument */ ++ { MODKEY, 33, spawn, {.v = dmenucmd } }, // p ++ { MODKEY|ShiftMask, 36, spawn, {.v = termcmd } }, // Return ++ { MODKEY, 56, togglebar, {0} }, // b ++ { MODKEY, 44, focusstack, {.i = +1 } }, // j ++ { MODKEY, 45, focusstack, {.i = -1 } }, // k ++ { MODKEY, 31, incnmaster, {.i = +1 } }, // i ++ { MODKEY, 40, incnmaster, {.i = -1 } }, // d ++ { MODKEY, 43, setmfact, {.f = -0.05} }, // h ++ { MODKEY, 46, setmfact, {.f = +0.05} }, // l ++ { MODKEY, 36, zoom, {0} }, // Return ++ { MODKEY, 23, view, {0} }, // Tab ++ { MODKEY|ShiftMask, 54, killclient, {0} }, // c ++ { MODKEY, 28, setlayout, {.v = &layouts[0]} }, // t ++ { MODKEY, 41, setlayout, {.v = &layouts[1]} }, // f ++ { MODKEY, 58, setlayout, {.v = &layouts[2]} }, // m ++ { MODKEY, 65, setlayout, {0} }, // space ++ { MODKEY|ShiftMask, 65, togglefloating, {0} }, // space ++ { MODKEY, 19, view, {.ui = ~0 } }, // 0 ++ { MODKEY|ShiftMask, 19, tag, {.ui = ~0 } }, // 0 ++ { MODKEY, 59, focusmon, {.i = -1 } }, // comma ++ { MODKEY, 60, focusmon, {.i = +1 } }, // period ++ { MODKEY|ShiftMask, 59, tagmon, {.i = -1 } }, // comma ++ { MODKEY|ShiftMask, 60, tagmon, {.i = +1 } }, // period ++ TAGKEYS( 10, 0) // 1 ++ TAGKEYS( 11, 1) // 2 ++ TAGKEYS( 12, 2) // 3 ++ TAGKEYS( 13, 3) // 4 ++ TAGKEYS( 14, 4) // 5 ++ TAGKEYS( 15, 5) // 6 ++ TAGKEYS( 16, 6) // 7 ++ TAGKEYS( 17, 7) // 8 ++ TAGKEYS( 18, 8) // 9 ++ { MODKEY|ShiftMask, 24, quit, {0} }, // q + }; + + /* button definitions */ +diff --git a/dwm.c b/dwm.c +index 0362114..60dd817 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -31,7 +31,6 @@ + #include <sys/types.h> + #include <sys/wait.h> + #include <X11/cursorfont.h> +-#include <X11/keysym.h> + #include <X11/Xatom.h> + #include <X11/Xlib.h> + #include <X11/Xproto.h> +@@ -101,7 +100,7 @@ struct Client { + + typedef struct { + unsigned int mod; +- KeySym keysym; ++ KeyCode keycode; + void (*func)(const Arg *); + const Arg arg; + } Key; +@@ -967,14 +966,12 @@ grabkeys(void) + { + unsigned int i, j; + unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; +- KeyCode code; + + XUngrabKey(dpy, AnyKey, AnyModifier, root); + for (i = 0; i < LENGTH(keys); i++) +- if ((code = XKeysymToKeycode(dpy, keys[i].keysym))) +- for (j = 0; j < LENGTH(modifiers); j++) +- XGrabKey(dpy, code, keys[i].mod | modifiers[j], root, +- True, GrabModeAsync, GrabModeAsync); ++ for (j = 0; j < LENGTH(modifiers); j++) ++ XGrabKey(dpy, keys[i].keycode, keys[i].mod | modifiers[j], root, ++ True, GrabModeAsync, GrabModeAsync); + } + } + +@@ -1001,13 +998,11 @@ void + keypress(XEvent *e) + { + unsigned int i; +- KeySym keysym; + XKeyEvent *ev; + + ev = &e->xkey; +- keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); + for (i = 0; i < LENGTH(keys); i++) +- if (keysym == keys[i].keysym ++ if (ev->keycode == keys[i].keycode + && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) + && keys[i].func) + keys[i].func(&(keys[i].arg)); diff --git a/dwm.suckless.org/patches/dwm-6.0-keypressrelease.diff b/dwm.suckless.org/patches/dwm-keypressrelease-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-6.1-mark.diff b/dwm.suckless.org/patches/dwm-mark-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-6.1-mark-new.diff b/dwm.suckless.org/patches/dwm-mark-new-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-maximize_vert_horz-20160731-56a31dc.diff b/dwm.suckless.org/patches/dwm-maximize_vert_horz-20160731-56a31dc.diff @@ -0,0 +1,77 @@ +Author: Jan Christoph Ebersbach <jceb@e-jc.de> +URL: http://dwm.suckless.org/patches/maximize +These patches provide helper functions for moving and resizing floating windows +using keybindings. + +Index: dwm/dwm.c +=================================================================== +--- dwm/dwm.c.orig ++++ dwm/dwm.c +@@ -93,7 +93,7 @@ struct Client { + int basew, baseh, incw, inch, maxw, maxh, minw, minh; + int bw, oldbw; + unsigned int tags; +- int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; ++ int ismax, wasfloating, isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; + Client *next; + Client *snext; + Monitor *mon; +@@ -1075,6 +1075,8 @@ manage(Window w, XWindowAttributes *wa) + updatewmhints(c); + XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); + grabbuttons(c, 0); ++ c->wasfloating = 0; ++ c->ismax = 0; + if (!c->isfloating) + c->isfloating = c->oldstate = trans != None || c->isfixed; + if (c->isfloating) +Index: dwm/maximize.c +=================================================================== +--- /dev/null ++++ dwm/maximize.c +@@ -0,0 +1,45 @@ ++void ++maximize(int x, int y, int w, int h) { ++ XEvent ev; ++ ++ if(!selmon->sel || selmon->sel->isfixed) ++ return; ++ XRaiseWindow(dpy, selmon->sel->win); ++ if(!selmon->sel->ismax) { ++ if(!selmon->lt[selmon->sellt]->arrange || selmon->sel->isfloating) ++ selmon->sel->wasfloating = True; ++ else { ++ togglefloating(NULL); ++ selmon->sel->wasfloating = False; ++ } ++ selmon->sel->oldx = selmon->sel->x; ++ selmon->sel->oldy = selmon->sel->y; ++ selmon->sel->oldw = selmon->sel->w; ++ selmon->sel->oldh = selmon->sel->h; ++ resize(selmon->sel, x, y, w, h, True); ++ selmon->sel->ismax = True; ++ } ++ else { ++ resize(selmon->sel, selmon->sel->oldx, selmon->sel->oldy, selmon->sel->oldw, selmon->sel->oldh, True); ++ if(!selmon->sel->wasfloating) ++ togglefloating(NULL); ++ selmon->sel->ismax = False; ++ } ++ drawbar(selmon); ++ while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); ++} ++ ++void ++togglemaximize(const Arg *arg) { ++ maximize(selmon->wx, selmon->wy, selmon->ww - 2 * borderpx, selmon->wh - 2 * borderpx); ++} ++ ++void ++toggleverticalmax(const Arg *arg) { ++ maximize(selmon->sel->x, selmon->wy, selmon->sel->w, selmon->wh - 2 * borderpx); ++} ++ ++void ++togglehorizontalmax(const Arg *arg) { ++ maximize(selmon->wx, selmon->sel->y, selmon->ww - 2 * borderpx, selmon->sel->h); ++} diff --git a/dwm.suckless.org/patches/dwm-6.0-maximize_vert_horz.diff b/dwm.suckless.org/patches/dwm-maximize_vert_horz-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-6.1-maximize_vert_horz.diff b/dwm.suckless.org/patches/dwm-maximize_vert_horz-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-5.8.2-monocle_count.diff b/dwm.suckless.org/patches/dwm-monocle_count-5.8.2.diff diff --git a/dwm.suckless.org/patches/dwm-moveresize-20160731-56a31dc.diff b/dwm.suckless.org/patches/dwm-moveresize-20160731-56a31dc.diff @@ -0,0 +1,74 @@ +Author: Jan Christoph Ebersbach <jceb@e-jc.de> +URL: http://dwm.suckless.org/patches/moveresize +These patches provide helper functions for moving and resizing floating windows +using keybindings. + +Index: dwm/moveresize.c +=================================================================== +--- /dev/null ++++ dwm/moveresize.c +@@ -0,0 +1,64 @@ ++void ++moveresize(const Arg *arg) { ++ /* only floating windows can be moved */ ++ Client *c; ++ c = selmon->sel; ++ int x, y, w, h, nx, ny, nw, nh, ox, oy, ow, oh; ++ char xAbs, yAbs, wAbs, hAbs; ++ int msx, msy, dx, dy, nmx, nmy; ++ unsigned int dui; ++ Window dummy; ++ ++ if (!c || !arg) ++ return; ++ if (selmon->lt[selmon->sellt]->arrange && !c->isfloating) ++ return; ++ if(sscanf((char *)arg->v, "%d%c %d%c %d%c %d%c", &x, &xAbs, &y, &yAbs, &w, &wAbs, &h, &hAbs) != 8) ++ return; ++ /* compute new window position; prevent window from be positioned outside the current monitor */ ++ nw = c->w + w; ++ if(wAbs == 'W') ++ nw = w < selmon->mw - 2 * c->bw ? w : selmon->mw - 2 * c->bw; ++ ++ nh = c->h + h; ++ if(hAbs == 'H') ++ nh = h < selmon->mh - 2 * c->bw ? h : selmon->mh - 2 * c->bw; ++ ++ nx = c->x + x; ++ if(xAbs == 'X') { ++ if(x < selmon->mx) ++ nx = selmon->mx; ++ else if(x > selmon->mx + selmon->mw) ++ nx = selmon->mx + selmon->mw - nw - 2 * c->bw; ++ else ++ nx = x; ++ } ++ ++ ny = c->y + y; ++ if(yAbs == 'Y') { ++ if(y < selmon->my) ++ ny = selmon->my; ++ else if(y > selmon->my + selmon->mh) ++ ny = selmon->my + selmon->mh - nh - 2 * c->bw; ++ else ++ ny = y; ++ } ++ ++ ox = c->x; ++ oy = c->y; ++ ow = c->w; ++ oh = c->h; ++ ++ XRaiseWindow(dpy, c->win); ++ Bool xqp = XQueryPointer(dpy, root, &dummy, &dummy, &msx, &msy, &dx, &dy, &dui); ++ resize(c, nx, ny, nw, nh, True); ++ ++ /* move cursor along with the window to avoid problems caused by the sloppy focus */ ++ if (xqp && ox <= msx && (ox + ow) >= msx && oy <= msy && (oy + oh) >= msy) ++ { ++ nmx = c->x - ox + c->w - ow; ++ nmy = c->y - oy + c->h - oh; ++ XWarpPointer(dpy, None, None, 0, 0, 0, 0, nmx, nmy); ++ } ++} ++ diff --git a/dwm.suckless.org/patches/dwm-6.0-moveresize.diff b/dwm.suckless.org/patches/dwm-moveresize-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-6.1-moveresize.diff b/dwm.suckless.org/patches/dwm-moveresize-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-movestack-6.1.diff b/dwm.suckless.org/patches/dwm-movestack-6.1.diff @@ -0,0 +1,73 @@ +diff -r 050d521d66d8 config.def.h +--- a/config.def.h Tue Aug 24 13:13:20 2010 +0100 ++++ b/config.def.h Sun Sep 05 18:43:07 2010 +0200 +@@ -57,6 +57,7 @@ + static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL }; + static const char *termcmd[] = { "st", NULL }; + ++#include "movestack.c" + static Key keys[] = { + /* modifier key function argument */ + { MODKEY, XK_p, spawn, {.v = dmenucmd } }, +@@ -68,6 +69,8 @@ + { MODKEY, XK_d, incnmaster, {.i = -1 } }, + { MODKEY, XK_h, setmfact, {.f = -0.05} }, + { MODKEY, XK_l, setmfact, {.f = +0.05} }, ++ { MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } }, ++ { MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } }, + { MODKEY, XK_Return, zoom, {0} }, + { MODKEY, XK_Tab, view, {0} }, + { MODKEY|ShiftMask, XK_c, killclient, {0} }, +diff -r 050d521d66d8 movestack.c +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/movestack.c Sun Sep 05 18:43:07 2010 +0200 +@@ -0,0 +1,49 @@ ++void ++movestack(const Arg *arg) { ++ Client *c = NULL, *p = NULL, *pc = NULL, *i; ++ ++ if(arg->i > 0) { ++ /* find the client after selmon->sel */ ++ for(c = selmon->sel->next; c && (!ISVISIBLE(c) || c->isfloating); c = c->next); ++ if(!c) ++ for(c = selmon->clients; c && (!ISVISIBLE(c) || c->isfloating); c = c->next); ++ ++ } ++ else { ++ /* find the client before selmon->sel */ ++ for(i = selmon->clients; i != selmon->sel; i = i->next) ++ if(ISVISIBLE(i) && !i->isfloating) ++ c = i; ++ if(!c) ++ for(; i; i = i->next) ++ if(ISVISIBLE(i) && !i->isfloating) ++ c = i; ++ } ++ /* find the client before selmon->sel and c */ ++ for(i = selmon->clients; i && (!p || !pc); i = i->next) { ++ if(i->next == selmon->sel) ++ p = i; ++ if(i->next == c) ++ pc = i; ++ } ++ ++ /* swap c and selmon->sel selmon->clients in the selmon->clients list */ ++ if(c && c != selmon->sel) { ++ Client *temp = selmon->sel->next==c?selmon->sel:selmon->sel->next; ++ selmon->sel->next = c->next==selmon->sel?c:c->next; ++ c->next = temp; ++ ++ if(p && p != c) ++ p->next = c; ++ if(pc && pc != selmon->sel) ++ pc->next = selmon->sel; ++ ++ if(selmon->sel == selmon->clients) ++ selmon->clients = c; ++ else if(c == selmon->clients) ++ selmon->clients = selmon->sel; ++ ++ arrange(selmon); ++ } ++} ++ diff --git a/dwm.suckless.org/patches/dwm-5.7.2-nametag.diff b/dwm.suckless.org/patches/dwm-nametag-5.7.2.diff diff --git a/dwm.suckless.org/patches/dwm-6.1-nametag.diff b/dwm.suckless.org/patches/dwm-nametag-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-6.1-nametag-prepend.diff b/dwm.suckless.org/patches/dwm-nametag-prepend-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-noborder-20160718-56a31dc.diff b/dwm.suckless.org/patches/dwm-noborder-20160718-56a31dc.diff @@ -0,0 +1,71 @@ +diff --git a/dwm.c b/dwm.c +index b2bc9bd..d3e1970 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -395,9 +395,24 @@ arrange(Monitor *m) + void + arrangemon(Monitor *m) + { ++ int n = 0; ++ Client *c; + strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); +- if (m->lt[m->sellt]->arrange) +- m->lt[m->sellt]->arrange(m); ++ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); ++ if ((m->lt[m->sellt]->arrange != monocle && n > 1) || !m->lt[m->sellt]->arrange) { ++ for (c = m->clients; c; c = c->next) { ++ if (ISVISIBLE(c) && (!m->lt[m->sellt]->arrange || !c->isfloating) && (c->bw != borderpx)) { ++ c->oldbw = c->bw; ++ c->bw = borderpx; ++ resizeclient(c, m->wx, m->wy, m->ww - (2 * c->bw), m->wh - (2 * c->bw)); ++ } ++ } ++ if (m->lt[m->sellt]->arrange) { ++ m->lt[m->sellt]->arrange(m); ++ } ++ } else { ++ monocle(m); ++ } + } + + void +@@ -1126,10 +1141,19 @@ monocle(Monitor *m) + for (c = m->clients; c; c = c->next) + if (ISVISIBLE(c)) + n++; +- if (n > 0) /* override layout symbol */ ++ if (n > 0 && m->lt[m->sellt]->arrange == monocle) /* override layout symbol */ + snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n); +- for (c = nexttiled(m->clients); c; c = nexttiled(c->next)) +- resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); ++ for(c = nexttiled(m->clients); c; c = nexttiled(c->next)) { ++ // I'm not sure, but calling resize with the border width subtractions ++ // fixes a glitch where windows would not redraw until they were ++ // manually resized after restarting dwm. ++ resize(c, m->wx, m->wy, m->ww - (2 * c->bw), m->wh - (2 * c->bw), False); ++ if (c->bw) { ++ c->oldbw = c->bw; ++ c->bw = 0; ++ resizeclient(c, m->wx, m->wy, m->ww, m->wh); ++ } ++ } + } + + void +@@ -1705,9 +1729,14 @@ togglefloating(const Arg *arg) + if (selmon->sel->isfullscreen) /* no support for fullscreen windows */ + return; + selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; +- if (selmon->sel->isfloating) ++ if (selmon->sel->isfloating) { ++ if (selmon->sel->bw != borderpx) { ++ selmon->sel->oldbw = selmon->sel->bw; ++ selmon->sel->bw = borderpx; ++ } + resize(selmon->sel, selmon->sel->x, selmon->sel->y, +- selmon->sel->w, selmon->sel->h, 0); ++ selmon->sel->w - selmon->sel->bw * 2, selmon->sel->h - selmon->sel->bw * 2, 0); ++ } + arrange(selmon); + } + diff --git a/dwm.suckless.org/patches/dwm-noborder-6.1.diff b/dwm.suckless.org/patches/dwm-noborder-6.1.diff @@ -0,0 +1,71 @@ +diff --git a/dwm.c b/dwm.c +index 0362114..e3209e5 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -393,9 +393,24 @@ arrange(Monitor *m) + void + arrangemon(Monitor *m) + { ++ int n = 0; ++ Client *c; + strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); +- if (m->lt[m->sellt]->arrange) +- m->lt[m->sellt]->arrange(m); ++ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); ++ if ((m->lt[m->sellt]->arrange != monocle && n > 1) || !m->lt[m->sellt]->arrange) { ++ for (c = m->clients; c; c = c->next) { ++ if (ISVISIBLE(c) && (!m->lt[m->sellt]->arrange || !c->isfloating) && (c->bw != borderpx)) { ++ c->oldbw = c->bw; ++ c->bw = borderpx; ++ resizeclient(c, m->wx, m->wy, m->ww - (2 * c->bw), m->wh - (2 * c->bw)); ++ } ++ } ++ if (m->lt[m->sellt]->arrange) { ++ m->lt[m->sellt]->arrange(m); ++ } ++ } else { ++ monocle(m); ++ } + } + + void +@@ -1123,10 +1138,19 @@ monocle(Monitor *m) + for (c = m->clients; c; c = c->next) + if (ISVISIBLE(c)) + n++; +- if (n > 0) /* override layout symbol */ ++ if (n > 0 && m->lt[m->sellt]->arrange == monocle) /* override layout symbol */ + snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n); +- for (c = nexttiled(m->clients); c; c = nexttiled(c->next)) +- resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); ++ for(c = nexttiled(m->clients); c; c = nexttiled(c->next)) { ++ // I'm not sure, but calling resize with the border width subtractions ++ // fixes a glitch where windows would not redraw until they were ++ // manually resized after restarting dwm. ++ resize(c, m->wx, m->wy, m->ww - (2 * c->bw), m->wh - (2 * c->bw), False); ++ if (c->bw) { ++ c->oldbw = c->bw; ++ c->bw = 0; ++ resizeclient(c, m->wx, m->wy, m->ww, m->wh); ++ } ++ } + } + + void +@@ -1706,9 +1730,14 @@ togglefloating(const Arg *arg) + if (selmon->sel->isfullscreen) /* no support for fullscreen windows */ + return; + selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; +- if (selmon->sel->isfloating) ++ if (selmon->sel->isfloating) { ++ if (selmon->sel->bw != borderpx) { ++ selmon->sel->oldbw = selmon->sel->bw; ++ selmon->sel->bw = borderpx; ++ } + resize(selmon->sel, selmon->sel->x, selmon->sel->y, +- selmon->sel->w, selmon->sel->h, 0); ++ selmon->sel->w - selmon->sel->bw * 2, selmon->sel->h - selmon->sel->bw * 2, 0); ++ } + arrange(selmon); + } + diff --git a/dwm.suckless.org/patches/dwm-nofullscreen.diff b/dwm.suckless.org/patches/dwm-nofullscreen.diff @@ -1,11 +0,0 @@ ---- dwm.c 2014-03-05 21:51:42.716156981 +0100 -+++ dwm.c-nofullscreen 2014-03-05 21:52:45.598560519 +0100 -@@ -1441,7 +1441,7 @@ setfullscreen(Client *c, Bool fullscreen - c->oldstate = c->isfloating; - c->oldbw = c->bw; - c->bw = 0; -- c->isfloating = True; -+ //c->isfloating = True; - resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh); - XRaiseWindow(dpy, c->win); - } diff --git a/dwm.suckless.org/patches/dwm-6.0-pango.diff b/dwm.suckless.org/patches/dwm-pango-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-pertag-20160626-7af4d43.diff b/dwm.suckless.org/patches/dwm-pertag-20160626-7af4d43.diff @@ -0,0 +1,199 @@ +diff --git a/dwm.c b/dwm.c +index b2bc9bd..3022d78 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -112,6 +112,7 @@ typedef struct { + void (*arrange)(Monitor *); + } Layout; + ++typedef struct Pertag Pertag; + struct Monitor { + char ltsymbol[16]; + float mfact; +@@ -131,6 +132,7 @@ struct Monitor { + Monitor *next; + Window barwin; + const Layout *lt[2]; ++ Pertag *pertag; + }; + + typedef struct { +@@ -272,6 +274,16 @@ static Window root; + /* configuration, allows nested code to access above variables */ + #include "config.h" + ++struct Pertag { ++ unsigned int curtag, prevtag; /* current and previous tag */ ++ int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */ ++ float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */ ++ unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */ ++ const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and layouts indexes */ ++ int showbars[LENGTH(tags) + 1]; /* display bar for the current tag */ ++ Client *prevzooms[LENGTH(tags) + 1]; /* store zoom information */ ++}; ++ + /* compile-time check if all tags fit into an unsigned int bit array. */ + struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; + +@@ -525,6 +537,7 @@ clientmessage(XEvent *e) + { + XClientMessageEvent *cme = &e->xclient; + Client *c = wintoclient(cme->window); ++ int i; + + if (!c) + return; +@@ -536,6 +549,8 @@ clientmessage(XEvent *e) + if (!ISVISIBLE(c)) { + c->mon->seltags ^= 1; + c->mon->tagset[c->mon->seltags] = c->tags; ++ for(i=0; !(c->tags & 1 << i); i++); ++ view(&(Arg){.ui = 1 << i}); + } + pop(c); + } +@@ -644,6 +659,7 @@ Monitor * + createmon(void) + { + Monitor *m; ++ int i; + + m = ecalloc(1, sizeof(Monitor)); + m->tagset[0] = m->tagset[1] = 1; +@@ -654,6 +670,27 @@ createmon(void) + m->lt[0] = &layouts[0]; + m->lt[1] = &layouts[1 % LENGTH(layouts)]; + strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); ++ if (!(m->pertag = (Pertag *)calloc(1, sizeof(Pertag)))) ++ die("fatal: could not malloc() %u bytes\n", sizeof(Pertag)); ++ m->pertag->curtag = m->pertag->prevtag = 1; ++ for(i=0; i <= LENGTH(tags); i++) { ++ /* init nmaster */ ++ m->pertag->nmasters[i] = m->nmaster; ++ ++ /* init mfacts */ ++ m->pertag->mfacts[i] = m->mfact; ++ ++ /* init layouts */ ++ m->pertag->ltidxs[i][0] = m->lt[0]; ++ m->pertag->ltidxs[i][1] = m->lt[1]; ++ m->pertag->sellts[i] = m->sellt; ++ ++ /* init showbar */ ++ m->pertag->showbars[i] = m->showbar; ++ ++ /* swap focus and zoomswap*/ ++ m->pertag->prevzooms[i] = NULL; ++ } + return m; + } + +@@ -983,7 +1020,7 @@ grabkeys(void) + void + incnmaster(const Arg *arg) + { +- selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); ++ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = MAX(selmon->nmaster + arg->i, 0); + arrange(selmon); + } + +@@ -1520,10 +1557,13 @@ setfullscreen(Client *c, int fullscreen) + void + setlayout(const Arg *arg) + { +- if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) +- selmon->sellt ^= 1; ++ if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) { ++ selmon->pertag->sellts[selmon->pertag->curtag] ^= 1; ++ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; ++ } + if (arg && arg->v) +- selmon->lt[selmon->sellt] = (Layout *)arg->v; ++ selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v; ++ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; + strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); + if (selmon->sel) + arrange(selmon); +@@ -1542,7 +1582,7 @@ setmfact(const Arg *arg) + f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; + if (f < 0.1 || f > 0.9) + return; +- selmon->mfact = f; ++ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f; + arrange(selmon); + } + +@@ -1691,7 +1731,7 @@ tile(Monitor *m) + void + togglebar(const Arg *arg) + { +- selmon->showbar = !selmon->showbar; ++ selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = !selmon->showbar; + updatebarpos(selmon); + XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); + arrange(selmon); +@@ -1730,9 +1770,29 @@ void + toggleview(const Arg *arg) + { + unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); ++ int i; + + if (newtagset) { ++ if (newtagset == ~0) { ++ selmon->pertag->prevtag = selmon->pertag->curtag; ++ selmon->pertag->curtag = 0; ++ } ++ /* test if the user did not select the same tag */ ++ if (!(newtagset & 1 << (selmon->pertag->curtag - 1))) { ++ selmon->pertag->prevtag = selmon->pertag->curtag; ++ for (i=0; !(newtagset & 1 << i); i++) ; ++ selmon->pertag->curtag = i + 1; ++ } + selmon->tagset[selmon->seltags] = newtagset; ++ ++ /* apply settings for this view */ ++ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; ++ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; ++ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; ++ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; ++ selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; ++ if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag]) ++ togglebar(NULL); + focus(NULL); + arrange(selmon); + } +@@ -2030,11 +2090,33 @@ updatewmhints(Client *c) + void + view(const Arg *arg) + { ++ int i; ++ unsigned int tmptag; ++ + if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) + return; + selmon->seltags ^= 1; /* toggle sel tagset */ +- if (arg->ui & TAGMASK) ++ if (arg->ui & TAGMASK) { ++ selmon->pertag->prevtag = selmon->pertag->curtag; + selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; ++ if (arg->ui == ~0) ++ selmon->pertag->curtag = 0; ++ else { ++ for (i=0; !(arg->ui & 1 << i); i++) ; ++ selmon->pertag->curtag = i + 1; ++ } ++ } else { ++ tmptag = selmon->pertag->prevtag; ++ selmon->pertag->prevtag = selmon->pertag->curtag; ++ selmon->pertag->curtag = tmptag; ++ } ++ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; ++ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; ++ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; ++ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; ++ selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; ++ if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag]) ++ togglebar(NULL); + focus(NULL); + arrange(selmon); + } diff --git a/dwm.suckless.org/patches/dwm-pertag-20160731-56a31dc.diff b/dwm.suckless.org/patches/dwm-pertag-20160731-56a31dc.diff @@ -0,0 +1,205 @@ +Author: Jan Christoph Ebersbach <jceb@e-jc.de> +URL: http://dwm.suckless.org/patches/pertag +This patch keeps layout, mwfact, barpos and nmaster per tag. + +Contributors: +- Carlos Pita, thanks for debugging NetActiveWindow issues and sending a patch + +Index: dwm/dwm.c +=================================================================== +--- dwm/dwm.c.orig ++++ dwm/dwm.c +@@ -112,6 +112,7 @@ typedef struct { + void (*arrange)(Monitor *); + } Layout; + ++typedef struct Pertag Pertag; + struct Monitor { + char ltsymbol[16]; + float mfact; +@@ -131,6 +132,7 @@ struct Monitor { + Monitor *next; + Window barwin; + const Layout *lt[2]; ++ Pertag *pertag; + }; + + typedef struct { +@@ -272,6 +274,16 @@ static Window root; + /* configuration, allows nested code to access above variables */ + #include "config.h" + ++struct Pertag { ++ unsigned int curtag, prevtag; /* current and previous tag */ ++ int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */ ++ float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */ ++ unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */ ++ const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and layouts indexes */ ++ Bool showbars[LENGTH(tags) + 1]; /* display bar for the current tag */ ++ Client *prevzooms[LENGTH(tags) + 1]; /* store zoom information */ ++}; ++ + /* compile-time check if all tags fit into an unsigned int bit array. */ + struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; + +@@ -525,6 +537,7 @@ clientmessage(XEvent *e) + { + XClientMessageEvent *cme = &e->xclient; + Client *c = wintoclient(cme->window); ++ int i; + + if (!c) + return; +@@ -536,6 +549,8 @@ clientmessage(XEvent *e) + if (!ISVISIBLE(c)) { + c->mon->seltags ^= 1; + c->mon->tagset[c->mon->seltags] = c->tags; ++ for(i=0; !(c->tags & 1 << i); i++); ++ view(&(Arg){.ui = 1 << i}); + } + pop(c); + } +@@ -644,6 +659,7 @@ Monitor * + createmon(void) + { + Monitor *m; ++ int i; + + m = ecalloc(1, sizeof(Monitor)); + m->tagset[0] = m->tagset[1] = 1; +@@ -654,6 +670,27 @@ createmon(void) + m->lt[0] = &layouts[0]; + m->lt[1] = &layouts[1 % LENGTH(layouts)]; + strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); ++ if(!(m->pertag = (Pertag *)calloc(1, sizeof(Pertag)))) ++ die("fatal: could not malloc() %u bytes\n", sizeof(Pertag)); ++ m->pertag->curtag = m->pertag->prevtag = 1; ++ for(i=0; i <= LENGTH(tags); i++) { ++ /* init nmaster */ ++ m->pertag->nmasters[i] = m->nmaster; ++ ++ /* init mfacts */ ++ m->pertag->mfacts[i] = m->mfact; ++ ++ /* init layouts */ ++ m->pertag->ltidxs[i][0] = m->lt[0]; ++ m->pertag->ltidxs[i][1] = m->lt[1]; ++ m->pertag->sellts[i] = m->sellt; ++ ++ /* init showbar */ ++ m->pertag->showbars[i] = m->showbar; ++ ++ /* swap focus and zoomswap*/ ++ m->pertag->prevzooms[i] = NULL; ++ } + return m; + } + +@@ -983,7 +1020,7 @@ grabkeys(void) + void + incnmaster(const Arg *arg) + { +- selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); ++ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = MAX(selmon->nmaster + arg->i, 0); + arrange(selmon); + } + +@@ -1520,10 +1557,13 @@ setfullscreen(Client *c, int fullscreen) + void + setlayout(const Arg *arg) + { +- if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) +- selmon->sellt ^= 1; ++ if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) { ++ selmon->pertag->sellts[selmon->pertag->curtag] ^= 1; ++ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; ++ } + if (arg && arg->v) +- selmon->lt[selmon->sellt] = (Layout *)arg->v; ++ selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v; ++ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; + strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); + if (selmon->sel) + arrange(selmon); +@@ -1542,7 +1582,7 @@ setmfact(const Arg *arg) + f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; + if (f < 0.1 || f > 0.9) + return; +- selmon->mfact = f; ++ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f; + arrange(selmon); + } + +@@ -1691,7 +1731,7 @@ tile(Monitor *m) + void + togglebar(const Arg *arg) + { +- selmon->showbar = !selmon->showbar; ++ selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = !selmon->showbar; + updatebarpos(selmon); + XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); + arrange(selmon); +@@ -1730,9 +1770,29 @@ void + toggleview(const Arg *arg) + { + unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); ++ int i; + + if (newtagset) { ++ if(newtagset == ~0) { ++ selmon->pertag->prevtag = selmon->pertag->curtag; ++ selmon->pertag->curtag = 0; ++ } ++ /* test if the user did not select the same tag */ ++ if (!(newtagset & 1 << (selmon->pertag->curtag - 1))) { ++ selmon->pertag->prevtag = selmon->pertag->curtag; ++ for (i=0; !(newtagset & 1 << i); i++) ; ++ selmon->pertag->curtag = i + 1; ++ } + selmon->tagset[selmon->seltags] = newtagset; ++ ++ /* apply settings for this view */ ++ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; ++ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; ++ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; ++ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; ++ selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; ++ if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag]) ++ togglebar(NULL); + focus(NULL); + arrange(selmon); + } +@@ -2030,11 +2090,32 @@ updatewmhints(Client *c) + void + view(const Arg *arg) + { ++ int i; ++ unsigned int tmptag; + if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) + return; + selmon->seltags ^= 1; /* toggle sel tagset */ +- if (arg->ui & TAGMASK) ++ if (arg->ui & TAGMASK) { ++ selmon->pertag->prevtag = selmon->pertag->curtag; + selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; ++ if (arg->ui == ~0) ++ selmon->pertag->curtag = 0; ++ else { ++ for (i=0; !(arg->ui & 1 << i); i++) ; ++ selmon->pertag->curtag = i + 1; ++ } ++ } else { ++ tmptag = selmon->pertag->prevtag; ++ selmon->pertag->prevtag = selmon->pertag->curtag; ++ selmon->pertag->curtag = tmptag; ++ } ++ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; ++ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; ++ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; ++ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; ++ selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; ++ if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag]) ++ togglebar(NULL); + focus(NULL); + arrange(selmon); + } diff --git a/dwm.suckless.org/patches/dwm-6.0-pertag.diff b/dwm.suckless.org/patches/dwm-pertag-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-6.1-pertag.diff b/dwm.suckless.org/patches/dwm-pertag-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-push-20160731-56a31dc.diff b/dwm.suckless.org/patches/dwm-push-20160731-56a31dc.diff @@ -0,0 +1,75 @@ +URL: http://dwm.suckless.org/patches/push +pushup and pushdown provide a way to move clients inside the clients list. + +Index: dwm/push.c +=================================================================== +--- /dev/null ++++ dwm/push.c +@@ -0,0 +1,67 @@ ++Client * ++nextc(Client *c, float f) { ++ if(!f) ++ return nexttiled(c); ++ ++ for(; c && !ISVISIBLE(c); c = c->next); ++ return c; ++} ++ ++static Client * ++prevc(Client *c, float f) { ++ Client *p, *r; ++ ++ for(p = selmon->clients, r = NULL; c && p && p != c; p = p->next) ++ if((f || !p->isfloating) && ISVISIBLE(p)) ++ r = p; ++ return r; ++} ++ ++static void ++pushup(const Arg *arg) { ++ Client *sel = selmon->sel; ++ Client *c; ++ ++ if(!sel || (sel->isfloating && !arg->f)) ++ return; ++ if((c = prevc(sel, arg->f))) { ++ /* attach before c */ ++ detach(sel); ++ sel->next = c; ++ if(selmon->clients == c) ++ selmon->clients = sel; ++ else { ++ for(c = selmon->clients; c->next != sel->next; c = c->next); ++ c->next = sel; ++ } ++ } else { ++ /* move to the end */ ++ for(c = sel; c->next; c = c->next); ++ detach(sel); ++ sel->next = NULL; ++ c->next = sel; ++ } ++ focus(sel); ++ arrange(selmon); ++} ++ ++static void ++pushdown(const Arg *arg) { ++ Client *sel = selmon->sel; ++ Client *c; ++ ++ if(!sel || (sel->isfloating && !arg->f)) ++ return; ++ if((c = nextc(sel->next, arg->f))) { ++ /* attach after c */ ++ detach(sel); ++ sel->next = c->next; ++ c->next = sel; ++ } else { ++ /* move to the front */ ++ detach(sel); ++ attach(sel); ++ } ++ focus(sel); ++ arrange(selmon); ++} diff --git a/dwm.suckless.org/patches/dwm-6.0-push.diff b/dwm.suckless.org/patches/dwm-push-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-6.1-push.diff b/dwm.suckless.org/patches/dwm-push-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-5.9-pwkl.diff b/dwm.suckless.org/patches/dwm-pwkl-5.9.diff diff --git a/dwm.suckless.org/patches/dwm-r1580-col.diff b/dwm.suckless.org/patches/dwm-r1580-col.diff @@ -1,60 +0,0 @@ -diff -r cfcfa05033e3 config.def.h ---- a/config.def.h Fri Oct 28 23:45:12 2011 +0100 -+++ b/config.def.h Fri Oct 28 18:57:59 2011 -0700 -@@ -32,6 +32,7 @@ - { "[]=", tile }, /* first entry is default */ - { "><>", NULL }, /* no layout function means floating behavior */ - { "[M]", monocle }, -+ { "|||", col }, - }; - - /* key definitions */ -@@ -66,6 +67,7 @@ - { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, - { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, - { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, -+ { MODKEY, XK_c, setlayout, {.v = &layouts[3]} }, - { MODKEY, XK_space, setlayout, {0} }, - { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, - { MODKEY, XK_0, view, {.ui = ~0 } }, -diff -r cfcfa05033e3 dwm.c ---- a/dwm.c Fri Oct 28 23:45:12 2011 +0100 -+++ b/dwm.c Fri Oct 28 18:57:59 2011 -0700 -@@ -165,6 +165,7 @@ - static void cleanupmon(Monitor *mon); - static void clearurgent(Client *c); - static void clientmessage(XEvent *e); -+static void col(Monitor *); - static void configure(Client *c); - static void configurenotify(XEvent *e); - static void configurerequest(XEvent *e); -@@ -1658,6 +1659,29 @@ - } - - void -+col(Monitor *m) { -+ unsigned int i, n, h, w, x, y; -+ Client *c; -+ -+ for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); -+ if(n == 0) -+ return; -+ -+ for(i = x = y = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { -+ if(i < m->nmaster) { -+ w = (m->ww - x) / (MIN(n, m->nmaster) + (n > m->nmaster) - i); -+ resize(c, x + m->wx, m->wy, w - (2*c->bw), m->wh - (2*c->bw), False); -+ x += WIDTH(c); -+ } -+ else { -+ h = (m->wh - y) / (n - i); -+ resize(c, x + m->wx, m->wy + y, m->ww - x - (2*c->bw), h - (2*c->bw), False); -+ y += HEIGHT(c); -+ } -+ } -+} -+ -+void - tile(Monitor *m) { - unsigned int i, n, h, mw, my, ty; - Client *c; diff --git a/dwm.suckless.org/patches/dwm-6.0-resizecorners.diff b/dwm.suckless.org/patches/dwm-resizecorners-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-6.1-resizecorners.diff b/dwm.suckless.org/patches/dwm-resizecorners-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-6.0-save_floats.diff b/dwm.suckless.org/patches/dwm-save_floats-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-savefloats-20160723-56a31dc.diff b/dwm.suckless.org/patches/dwm-savefloats-20160723-56a31dc.diff @@ -0,0 +1,46 @@ +diff --git a/dwm.c b/dwm.c +index cfea881..87a23c4 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -107,6 +107,7 @@ struct Client { + char name[256]; + float mina, maxa; + int x, y, w, h; ++ int sfx, sfy, sfw, sfh; /* stored float geometry, used on mode revert */ + int oldx, oldy, oldw, oldh; + int basew, baseh, incw, inch, maxw, maxh, minw, minh; + int bw, oldbw; +@@ -1205,10 +1206,10 @@ manage(Window w, XWindowAttributes *wa) + c = ecalloc(1, sizeof(Client)); + c->win = w; + /* geometry */ +- c->x = c->oldx = wa->x; +- c->y = c->oldy = wa->y; +- c->w = c->oldw = wa->width; +- c->h = c->oldh = wa->height; ++ c->sfx = c->x = c->oldx = wa->x; ++ c->sfy = c->y = c->oldy = wa->y; ++ c->sfw = c->w = c->oldw = wa->width; ++ c->sfh = c->h = c->oldh = wa->height; + c->oldbw = wa->border_width; + + updatetitle(c); +@@ -1976,8 +1977,16 @@ togglefloating(const Arg *arg) + return; + selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; + if (selmon->sel->isfloating) +- resize(selmon->sel, selmon->sel->x, selmon->sel->y, +- selmon->sel->w, selmon->sel->h, 0); ++ /* restore last know float dimentions */ ++ resize(selmon->sel, selmon->sel->sfx, selmon->sel->sfy, ++ selmon->sel->sfw, selmon->sel->sfh, 0); ++ else { ++ /* save last known float dimentions */ ++ selmon->sel->sfx = selmon->sel->x; ++ selmon->sel->sfy = selmon->sel->y; ++ selmon->sel->sfw = selmon->sel->w; ++ selmon->sel->sfh = selmon->sel->h; ++ } + arrange(selmon); + } + diff --git a/dwm.suckless.org/patches/dwm-single_tagset-20160731-56a31dc.diff b/dwm.suckless.org/patches/dwm-single_tagset-20160731-56a31dc.diff @@ -0,0 +1,540 @@ +Author: Jan Christoph Ebersbach <jceb@e-jc.de> +URL: http://dwm.suckless.org/patches/single_tagset +This patch addresses the multi-monitor setup. Instead of having separate tags +for every monitor there is just one list of tags for all monitors. Instead of +moving windows from one monitor to the other, the desired tag from the +other monitor can just be selected and all windows will be drawn on the +current monitor. + +Several deep changes needed to be made: +1. Macro ISVISIBLE expects a second parameter, the monitor +2. Monitor->clients and Monitor->stack were moved to the global variable + Clientlist cl. All monitors refer to this one list. +3. A new method attachclients was added. When changing between tags this + function ensures that all clients are pointing to the right monitor. + +Please be aware that this patch probably breaks any other patch! + +Index: dwm/dwm.c +=================================================================== +--- dwm/dwm.c.orig ++++ dwm/dwm.c +@@ -49,7 +49,7 @@ + #define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) + #define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \ + * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy))) +-#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags])) ++#define ISVISIBLE(C, M) ((C->tags & M->tagset[M->seltags])) + #define LENGTH(X) (sizeof X / sizeof X[0]) + #define MOUSEMASK (BUTTONMASK|PointerMotionMask) + #define WIDTH(X) ((X)->w + 2 * (X)->bw) +@@ -83,6 +83,7 @@ typedef struct { + const Arg arg; + } Button; + ++typedef struct Clientlist Clientlist; + typedef struct Monitor Monitor; + typedef struct Client Client; + struct Client { +@@ -125,9 +126,8 @@ struct Monitor { + unsigned int tagset[2]; + int showbar; + int topbar; +- Client *clients; ++ Clientlist *cl; + Client *sel; +- Client *stack; + Monitor *next; + Window barwin; + const Layout *lt[2]; +@@ -142,12 +142,18 @@ typedef struct { + int monitor; + } Rule; + ++struct Clientlist { ++ Client *clients; ++ Client *stack; ++}; ++ + /* function declarations */ + static void applyrules(Client *c); + static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact); + static void arrange(Monitor *m); + static void arrangemon(Monitor *m); + static void attach(Client *c); ++static void attachclients(Monitor *m); + static void attachstack(Client *c); + static void buttonpress(XEvent *e); + static void checkotherwm(void); +@@ -185,7 +191,7 @@ static void maprequest(XEvent *e); + static void monocle(Monitor *m); + static void motionnotify(XEvent *e); + static void movemouse(const Arg *arg); +-static Client *nexttiled(Client *c); ++static Client *nexttiled(Client *c, Monitor *m); + static void pop(Client *); + static void propertynotify(XEvent *e); + static void quit(const Arg *arg); +@@ -268,6 +274,7 @@ static Display *dpy; + static Drw *drw; + static Monitor *mons, *selmon; + static Window root; ++static Clientlist *cl; + + /* configuration, allows nested code to access above variables */ + #include "config.h" +@@ -300,7 +307,7 @@ applyrules(Client *c) + { + c->isfloating = r->isfloating; + c->tags |= r->tags; +- for (m = mons; m && m->num != r->monitor; m = m->next); ++ for (m = mons; m && (m->tagset[m->seltags] & c->tags) == 0; m = m->next) ; + if (m) + c->mon = m; + } +@@ -382,9 +389,9 @@ void + arrange(Monitor *m) + { + if (m) +- showhide(m->stack); ++ showhide(m->cl->stack); + else for (m = mons; m; m = m->next) +- showhide(m->stack); ++ showhide(m->cl->stack); + if (m) { + arrangemon(m); + restack(m); +@@ -403,15 +410,48 @@ arrangemon(Monitor *m) + void + attach(Client *c) + { +- c->next = c->mon->clients; +- c->mon->clients = c; ++ c->next = c->mon->cl->clients; ++ c->mon->cl->clients = c; ++} ++ ++void ++attachclients(Monitor *m) { ++ /* attach clients to the specified monitor */ ++ Monitor *tm; ++ Client *c; ++ unsigned int utags = 0; ++ Bool rmons = False; ++ if(!m) ++ return; ++ ++ /* collect information about the tags in use */ ++ for (tm = mons; tm; tm = tm->next) ++ if(tm != m) ++ utags |= m->tagset[m->seltags]; ++ ++ for (c = m->cl->clients; c; c = c->next) ++ if(ISVISIBLE(c, m)) { ++ /* if client is also visible on other tags that are displayed on ++ * other monitors, remove these tags */ ++ if(c->tags & utags) { ++ c->tags = c->tags & m->tagset[m->seltags]; ++ rmons = True; ++ } ++ unfocus(c, True); ++ c->mon = m; ++ } ++ ++ if (rmons) ++ for (tm = mons; tm; tm = tm->next) ++ if(tm != m) ++ arrange(tm); + } + + void + attachstack(Client *c) + { +- c->snext = c->mon->stack; +- c->mon->stack = c; ++ c->snext = c->mon->cl->stack; ++ c->mon->cl->stack = c; + } + + void +@@ -476,8 +516,8 @@ cleanup(void) + view(&a); + selmon->lt[selmon->sellt] = &foo; + for (m = mons; m; m = m->next) +- while (m->stack) +- unmanage(m->stack, 0); ++ while (m->cl->stack) ++ unmanage(m->cl->stack, 0); + XUngrabKey(dpy, AnyKey, AnyModifier, root); + while (mons) + cleanupmon(mons); +@@ -533,7 +573,7 @@ clientmessage(XEvent *e) + setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */ + || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen))); + } else if (cme->message_type == netatom[NetActiveWindow]) { +- if (!ISVISIBLE(c)) { ++ if (!ISVISIBLE(c, c->mon)) { + c->mon->seltags ^= 1; + c->mon->tagset[c->mon->seltags] = c->tags; + } +@@ -577,7 +617,7 @@ configurenotify(XEvent *e) + drw_resize(drw, sw, bh); + updatebars(); + for (m = mons; m; m = m->next) { +- for (c = m->clients; c; c = c->next) ++ for (c = m->cl->clients; c; c = c->next) + if (c->isfullscreen) + resizeclient(c, m->mx, m->my, m->mw, m->mh); + XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); +@@ -623,7 +663,7 @@ configurerequest(XEvent *e) + c->y = m->my + (m->mh / 2 - HEIGHT(c) / 2); /* center in y direction */ + if ((ev->value_mask & (CWX|CWY)) && !(ev->value_mask & (CWWidth|CWHeight))) + configure(c); +- if (ISVISIBLE(c)) ++ if (ISVISIBLE(c, m)) + XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); + } else + configure(c); +@@ -643,10 +683,31 @@ configurerequest(XEvent *e) + Monitor * + createmon(void) + { +- Monitor *m; ++ Monitor *m, *tm; ++ int i; + ++ /* bail out if the number of monitors exceeds the number of tags */ ++ for (i=1, tm=mons; tm; i++, tm=tm->next); ++ if (i > LENGTH(tags)) { ++ fprintf(stderr, "dwm: failed to add monitor, number of tags exceeded\n"); ++ return NULL; ++ } ++ /* find the first tag that isn't in use */ ++ for (i=0; i < LENGTH(tags); i++) { ++ for (tm=mons; tm && !(tm->tagset[tm->seltags] & (1<<i)); tm=tm->next); ++ if (!tm) ++ break; ++ } ++ /* reassign all tags to monitors since there's currently no free tag for the ++ * new monitor */ ++ if (i >= LENGTH(tags)) ++ for (i=0, tm=mons; tm; tm=tm->next, i++) { ++ tm->seltags ^= 1; ++ tm->tagset[tm->seltags] = (1<<i) & TAGMASK; ++ } + m = ecalloc(1, sizeof(Monitor)); +- m->tagset[0] = m->tagset[1] = 1; ++ m->cl = cl; ++ m->tagset[0] = m->tagset[1] = (1<<i) & TAGMASK; + m->mfact = mfact; + m->nmaster = nmaster; + m->showbar = showbar; +@@ -672,7 +733,7 @@ detach(Client *c) + { + Client **tc; + +- for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next); ++ for (tc = &c->mon->cl->clients; *tc && *tc != c; tc = &(*tc)->next); + *tc = c->next; + } + +@@ -681,11 +742,11 @@ detachstack(Client *c) + { + Client **tc, *t; + +- for (tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext); ++ for (tc = &c->mon->cl->stack; *tc && *tc != c; tc = &(*tc)->snext); + *tc = c->snext; + + if (c == c->mon->sel) { +- for (t = c->mon->stack; t && !ISVISIBLE(t); t = t->snext); ++ for (t = c->mon->cl->stack; t && !ISVISIBLE(t, c->mon); t = t->snext); + c->mon->sel = t; + } + } +@@ -721,7 +782,7 @@ drawbar(Monitor *m) + drw_text(drw, m->ww - sw, 0, sw, bh, lrpad / 2 - 2, stext, 0); + } + +- for (c = m->clients; c; c = c->next) { ++ for(c = m->cl->clients; c; c = c->next) { + occ |= c->tags; + if (c->isurgent) + urg |= c->tags; +@@ -796,8 +857,8 @@ expose(XEvent *e) + void + focus(Client *c) + { +- if (!c || !ISVISIBLE(c)) +- for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext); ++ if (!c || !ISVISIBLE(c, selmon)) ++ for (c = selmon->cl->stack; c && !ISVISIBLE(c, selmon); c = c->snext); + /* was if (selmon->sel) */ + if (selmon->sel && selmon->sel != c) + unfocus(selmon->sel, 0); +@@ -852,16 +913,16 @@ focusstack(const Arg *arg) + if (!selmon->sel) + return; + if (arg->i > 0) { +- for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next); ++ for (c = selmon->sel->next; c && !ISVISIBLE(c, selmon); c = c->next); + if (!c) +- for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next); ++ for (c = selmon->cl->clients; c && !ISVISIBLE(c, selmon); c = c->next); + } else { +- for (i = selmon->clients; i != selmon->sel; i = i->next) +- if (ISVISIBLE(i)) ++ for (i = selmon->cl->clients; i != selmon->sel; i = i->next) ++ if (ISVISIBLE(i, selmon)) + c = i; + if (!c) + for (; i; i = i->next) +- if (ISVISIBLE(i)) ++ if (ISVISIBLE(i, selmon)) + c = i; + } + if (c) { +@@ -1123,12 +1184,12 @@ monocle(Monitor *m) + unsigned int n = 0; + Client *c; + +- for (c = m->clients; c; c = c->next) +- if (ISVISIBLE(c)) ++ for(c = m->cl->clients; c; c = c->next) ++ if(ISVISIBLE(c, m)) + n++; + if (n > 0) /* override layout symbol */ + snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n); +- for (c = nexttiled(m->clients); c; c = nexttiled(c->next)) ++ for (c = nexttiled(m->cl->clients, m); c; c = nexttiled(c->next, m)) + resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); + } + +@@ -1213,9 +1274,9 @@ movemouse(const Arg *arg) + } + + Client * +-nexttiled(Client *c) ++nexttiled(Client *c, Monitor *m) + { +- for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next); ++ for (; c && (c->isfloating || !ISVISIBLE(c, m)); c = c->next); + return c; + } + +@@ -1379,8 +1440,8 @@ restack(Monitor *m) + if (m->lt[m->sellt]->arrange) { + wc.stack_mode = Below; + wc.sibling = m->barwin; +- for (c = m->stack; c; c = c->snext) +- if (!c->isfloating && ISVISIBLE(c)) { ++ for (c = m->cl->stack; c; c = c->snext) ++ if (!c->isfloating && ISVISIBLE(c, m)) { + XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc); + wc.sibling = c->win; + } +@@ -1433,11 +1494,9 @@ sendmon(Client *c, Monitor *m) + if (c->mon == m) + return; + unfocus(c, 1); +- detach(c); + detachstack(c); + c->mon = m; + c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ +- attach(c); + attachstack(c); + focus(NULL); + arrange(NULL); +@@ -1558,6 +1617,8 @@ setup(void) + screen = DefaultScreen(dpy); + sw = DisplayWidth(dpy, screen); + sh = DisplayHeight(dpy, screen); ++ if(!(cl = (Clientlist *)calloc(1, sizeof(Clientlist)))) ++ die("fatal: could not malloc() %u bytes\n", sizeof(Clientlist)); + root = RootWindow(dpy, screen); + drw = drw_create(dpy, screen, root, sw, sh); + if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) +@@ -1607,7 +1668,7 @@ showhide(Client *c) + { + if (!c) + return; +- if (ISVISIBLE(c)) { ++ if (ISVISIBLE(c, c->mon)) { + /* show clients top down */ + XMoveWindow(dpy, c->win, c->x, c->y); + if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen) +@@ -1647,7 +1708,22 @@ spawn(const Arg *arg) + void + tag(const Arg *arg) + { ++ Monitor *m; ++ unsigned int newtags; + if (selmon->sel && arg->ui & TAGMASK) { ++ newtags = arg->ui & TAGMASK; ++ for (m = mons; m; m = m->next) ++ /* if tag is visible on another monitor, move client to the new monitor */ ++ if (m != selmon && m->tagset[m->seltags] & newtags) { ++ /* prevent moving client to all tags (MODKEY-Shift-0) when multiple monitors are connected */ ++ if(newtags & selmon->tagset[selmon->seltags]) ++ return; ++ selmon->sel->tags = newtags; ++ selmon->sel->mon = m; ++ arrange(m); ++ break; ++ } ++ /* workaround in case just one monitor is connected */ + selmon->sel->tags = arg->ui & TAGMASK; + focus(NULL); + arrange(selmon); +@@ -1668,7 +1744,7 @@ tile(Monitor *m) + unsigned int i, n, h, mw, my, ty; + Client *c; + +- for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); ++ for (n = 0, c = nexttiled(m->cl->clients, m); c; c = nexttiled(c->next, m), n++); + if (n == 0) + return; + +@@ -1676,7 +1752,7 @@ tile(Monitor *m) + mw = m->nmaster ? m->ww * m->mfact : 0; + else + mw = m->ww; +- for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) ++ for (i = my = ty = 0, c = nexttiled(m->cl->clients, m); c; c = nexttiled(c->next, m), i++) + if (i < m->nmaster) { + h = (m->wh - my) / (MIN(n, m->nmaster) - i); + resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); +@@ -1714,12 +1790,17 @@ togglefloating(const Arg *arg) + void + toggletag(const Arg *arg) + { ++ Monitor *m; + unsigned int newtags; + + if (!selmon->sel) + return; + newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); + if (newtags) { ++ /* prevent adding tags that are in use on other monitors */ ++ for (m = mons; m; m = m->next) ++ if (m != selmon && newtags & m->tagset[m->seltags]) ++ return; + selmon->sel->tags = newtags; + focus(NULL); + arrange(selmon); +@@ -1729,12 +1810,17 @@ toggletag(const Arg *arg) + void + toggleview(const Arg *arg) + { ++ Monitor *m; + unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); + + if (newtagset) { ++ /* prevent displaying the same tags on multiple monitors */ ++ for(m = mons; m; m = m->next) ++ if(m != selmon && newtagset & m->tagset[m->seltags]) ++ return; + selmon->tagset[selmon->seltags] = newtagset; + focus(NULL); +- arrange(selmon); ++ attachclients(selmon); + } + } + +@@ -1832,7 +1918,7 @@ updateclientlist() + + XDeleteProperty(dpy, root, netatom[NetClientList]); + for (m = mons; m; m = m->next) +- for (c = m->clients; c; c = c->next) ++ for (c = m->cl->clients; c; c = c->next) + XChangeProperty(dpy, root, netatom[NetClientList], + XA_WINDOW, 32, PropModeAppend, + (unsigned char *) &(c->win), 1); +@@ -1862,8 +1948,10 @@ updategeom(void) + if (n <= nn) { + for (i = 0; i < (nn - n); i++) { /* new monitors available */ + for (m = mons; m && m->next; m = m->next); +- if (m) ++ if (m) { + m->next = createmon(); ++ attachclients(m->next); ++ } + else + mons = createmon(); + } +@@ -1884,17 +1972,13 @@ updategeom(void) + /* less monitors available nn < n */ + for (i = nn; i < n; i++) { + for (m = mons; m && m->next; m = m->next); +- while (m->clients) { +- dirty = 1; +- c = m->clients; +- m->clients = c->next; +- detachstack(c); +- c->mon = mons; +- attach(c); +- attachstack(c); +- } + if (m == selmon) + selmon = mons; ++ for (c = m->cl->clients; c; c = c->next) { ++ dirty = True; ++ if (c->mon == m) ++ c->mon = selmon; ++ } + cleanupmon(m); + } + } +@@ -2030,13 +2114,31 @@ updatewmhints(Client *c) + void + view(const Arg *arg) + { ++ Monitor *m; ++ unsigned int newtagset = selmon->tagset[selmon->seltags ^ 1]; + if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) + return; ++ /* swap tags when trying to display a tag from another monitor */ ++ if (arg->ui & TAGMASK) ++ newtagset = arg->ui & TAGMASK; ++ for (m = mons; m; m = m->next) ++ if (m != selmon && newtagset & m->tagset[m->seltags]) { ++ /* prevent displaying all tags (MODKEY-0) when multiple monitors ++ * are connected */ ++ if (newtagset & selmon->tagset[selmon->seltags]) ++ return; ++ m->sel = selmon->sel; ++ m->seltags ^= 1; ++ m->tagset[m->seltags] = selmon->tagset[selmon->seltags]; ++ attachclients(m); ++ arrange(m); ++ break; ++ } + selmon->seltags ^= 1; /* toggle sel tagset */ + if (arg->ui & TAGMASK) + selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; + focus(NULL); +- arrange(selmon); ++ attachclients(selmon); + } + + Client * +@@ -2046,7 +2148,7 @@ wintoclient(Window w) + Monitor *m; + + for (m = mons; m; m = m->next) +- for (c = m->clients; c; c = c->next) ++ for (c = m->cl->clients; c; c = c->next) + if (c->win == w) + return c; + return NULL; +@@ -2113,8 +2215,8 @@ zoom(const Arg *arg) + if (!selmon->lt[selmon->sellt]->arrange + || (selmon->sel && selmon->sel->isfloating)) + return; +- if (c == nexttiled(selmon->clients)) +- if (!c || !(c = nexttiled(c->next))) ++ if (c == nexttiled(selmon->cl->clients, selmon)) ++ if (!c || !(c = nexttiled(c->next, selmon))) + return; + pop(c); + } diff --git a/dwm.suckless.org/patches/dwm-6.0-single_tagset.diff b/dwm.suckless.org/patches/dwm-single_tagset-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-5.7.2-sizehints.diff b/dwm.suckless.org/patches/dwm-sizehints-5.7.2.diff diff --git a/dwm.suckless.org/patches/dwm-6.0-stacker.diff b/dwm.suckless.org/patches/dwm-stacker-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-statusallmons-20160731-56a31dc.diff b/dwm.suckless.org/patches/dwm-statusallmons-20160731-56a31dc.diff @@ -0,0 +1,29 @@ +URL: http://dwm.suckless.org/patches/statusallmons +This patch draws and updates the statusbar on all monitors. + +Index: dwm/dwm.c +=================================================================== +--- dwm/dwm.c.orig ++++ dwm/dwm.c +@@ -715,7 +715,7 @@ drawbar(Monitor *m) + Client *c; + + /* draw status first so it can be overdrawn by tags later */ +- if (m == selmon) { /* status is only drawn on selected monitor */ ++ if (m == selmon || 1) { /* status is only drawn on selected monitor */ + drw_setscheme(drw, scheme[SchemeNorm]); + sw = TEXTW(stext) - lrpad / 2; /* no right padding so status text hugs the corner */ + drw_text(drw, m->ww - sw, 0, sw, bh, lrpad / 2 - 2, stext, 0); +@@ -1991,9 +1991,11 @@ updatetitle(Client *c) + void + updatestatus(void) + { ++ Monitor* m; + if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) + strcpy(stext, "dwm-"VERSION); +- drawbar(selmon); ++ for(m = mons; m; m = m->next) ++ drawbar(m); + } + + void diff --git a/dwm.suckless.org/patches/dwm-5.8.2-statusallmons.diff b/dwm.suckless.org/patches/dwm-statusallmons-5.8.2.diff diff --git a/dwm.suckless.org/patches/dwm-6.0-statusallmons.diff b/dwm.suckless.org/patches/dwm-statusallmons-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-5.9-statuscolors.diff b/dwm.suckless.org/patches/dwm-statuscolors-5.9.diff diff --git a/dwm.suckless.org/patches/dwm-6.1-statuscolors.diff b/dwm.suckless.org/patches/dwm-statuscolors-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-swallow-20160717-56a31dc.diff b/dwm.suckless.org/patches/dwm-swallow-20160717-56a31dc.diff @@ -0,0 +1,380 @@ +diff --git a/config.def.h b/config.def.h +index fd77a07..69976b3 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -26,9 +26,10 @@ static const Rule rules[] = { + * WM_CLASS(STRING) = instance, class + * WM_NAME(STRING) = title + */ +- /* class instance title tags mask isfloating monitor */ +- { "Gimp", NULL, NULL, 0, 1, -1 }, +- { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, ++ /* class instance title tags mask isfloating isterminal noswallow monitor */ ++ { "Gimp", NULL, NULL, 0, 1, 0, 0, -1 }, ++ { "Firefox", NULL, NULL, 1 << 8, 0, 0, 0, -1 }, ++ { "st", NULL, NULL, 0, 0, 1, 1, -1 }, + }; + + /* layout(s) */ +diff --git a/config.mk b/config.mk +index 80dc936..5ed14e3 100644 +--- a/config.mk ++++ b/config.mk +@@ -22,7 +22,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} -lX11-xcb -lxcb -lxcb-res + + # flags + CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} +diff --git a/dwm.c b/dwm.c +index b2bc9bd..528df2f 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -40,6 +40,8 @@ + #include <X11/extensions/Xinerama.h> + #endif /* XINERAMA */ + #include <X11/Xft/Xft.h> ++#include <X11/Xlib-xcb.h> ++#include <xcb/res.h> + + #include "drw.h" + #include "util.h" +@@ -93,9 +95,11 @@ struct Client { + int basew, baseh, incw, inch, maxw, maxh, minw, minh; + int bw, oldbw; + unsigned int tags; +- int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; ++ int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isterminal, noswallow; ++ pid_t pid; + Client *next; + Client *snext; ++ Client *swallowing; + Monitor *mon; + Window win; + }; +@@ -139,6 +143,8 @@ typedef struct { + const char *title; + unsigned int tags; + int isfloating; ++ int isterminal; ++ int noswallow; + int monitor; + } Rule; + +@@ -171,12 +177,14 @@ static void focus(Client *c); + static void focusin(XEvent *e); + static void focusmon(const Arg *arg); + static void focusstack(const Arg *arg); ++static pid_t getparentprocess(pid_t p); + static int getrootptr(int *x, int *y); + static long getstate(Window w); + static int gettextprop(Window w, Atom atom, char *text, unsigned int size); + static void grabbuttons(Client *c, int focused); + static void grabkeys(void); + static void incnmaster(const Arg *arg); ++static int isdescprocess(pid_t p, pid_t c); + static void keypress(XEvent *e); + static void killclient(const Arg *arg); + static void manage(Window w, XWindowAttributes *wa); +@@ -207,8 +215,10 @@ static void setup(void); + static void showhide(Client *c); + static void sigchld(int unused); + static void spawn(const Arg *arg); ++static Client *swallowingclient(Window w); + static void tag(const Arg *arg); + static void tagmon(const Arg *arg); ++static Client *termforwin(const Client *c); + static void tile(Monitor *); + static void togglebar(const Arg *arg); + static void togglefloating(const Arg *arg); +@@ -228,6 +238,7 @@ static void updatewindowtype(Client *c); + static void updatetitle(Client *c); + static void updatewmhints(Client *c); + static void view(const Arg *arg); ++static pid_t winpid(Window w); + static Client *wintoclient(Window w); + static Monitor *wintomon(Window w); + static int xerror(Display *dpy, XErrorEvent *ee); +@@ -269,6 +280,8 @@ static Drw *drw; + static Monitor *mons, *selmon; + static Window root; + ++static xcb_connection_t *xcon; ++ + /* configuration, allows nested code to access above variables */ + #include "config.h" + +@@ -298,6 +311,7 @@ applyrules(Client *c) + && (!r->class || strstr(class, r->class)) + && (!r->instance || strstr(instance, r->instance))) + { ++ c->isterminal = r->isterminal; + c->isfloating = r->isfloating; + c->tags |= r->tags; + for (m = mons; m && m->num != r->monitor; m = m->next); +@@ -415,6 +429,46 @@ attachstack(Client *c) + } + + void ++swallow(Client *p, Client *c) ++{ ++ if (c->noswallow || c->isterminal) ++ return; ++ ++ detach(c); ++ detachstack(c); ++ ++ setclientstate(c, WithdrawnState); ++ XUnmapWindow(dpy, p->win); ++ ++ p->swallowing = c; ++ c->mon = p->mon; ++ ++ Window w = p->win; ++ p->win = c->win; ++ c->win = w; ++ updatetitle(p); ++ arrange(p->mon); ++ configure(p); ++ updateclientlist(); ++} ++ ++void ++unswallow(Client *c) ++{ ++ c->win = c->swallowing->win; ++ ++ free(c->swallowing); ++ c->swallowing = NULL; ++ ++ updatetitle(c); ++ arrange(c->mon); ++ XMapWindow(dpy, c->win); ++ XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); ++ configure(c); ++ setclientstate(c, NormalState); ++} ++ ++void + buttonpress(XEvent *e) + { + unsigned int i, x, click; +@@ -477,7 +531,7 @@ cleanup(void) + selmon->lt[selmon->sellt] = &foo; + for (m = mons; m; m = m->next) + while (m->stack) +- unmanage(m->stack, 0); ++ unmanage(m->stack, 0); // XXX - unmanage swallowing windows too + XUngrabKey(dpy, AnyKey, AnyModifier, root); + while (mons) + cleanupmon(mons); +@@ -665,6 +719,9 @@ destroynotify(XEvent *e) + + if ((c = wintoclient(ev->window))) + unmanage(c, 1); ++ ++ else if ((c = swallowingclient(ev->window))) ++ unmanage(c->swallowing, 1); + } + + void +@@ -1034,12 +1091,13 @@ killclient(const Arg *arg) + void + manage(Window w, XWindowAttributes *wa) + { +- Client *c, *t = NULL; ++ Client *c, *t = NULL, *term = NULL; + Window trans = None; + XWindowChanges wc; + + c = ecalloc(1, sizeof(Client)); + c->win = w; ++ c->pid = winpid(w); + /* geometry */ + c->x = c->oldx = wa->x; + c->y = c->oldy = wa->y; +@@ -1054,6 +1112,7 @@ manage(Window w, XWindowAttributes *wa) + } else { + c->mon = selmon; + applyrules(c); ++ term = termforwin(c); + } + + if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw) +@@ -1090,6 +1149,8 @@ manage(Window w, XWindowAttributes *wa) + c->mon->sel = c; + arrange(c->mon); + XMapWindow(dpy, c->win); ++ if (term) ++ swallow(term, c); + focus(NULL); + } + +@@ -1757,6 +1818,20 @@ unmanage(Client *c, int destroyed) + Monitor *m = c->mon; + XWindowChanges wc; + ++ if (c->swallowing) { ++ unswallow(c); ++ return; ++ } ++ ++ Client *s = swallowingclient(c->win); ++ if (s) { ++ free(s->swallowing); ++ s->swallowing = NULL; ++ arrange(m); ++ focus(NULL); ++ return; ++ } ++ + /* The server grab construct avoids race conditions. */ + detach(c); + detachstack(c); +@@ -1772,9 +1847,12 @@ unmanage(Client *c, int destroyed) + XUngrabServer(dpy); + } + free(c); +- focus(NULL); +- updateclientlist(); +- arrange(m); ++ ++ if (!s) { ++ arrange(m); ++ focus(NULL); ++ updateclientlist(); ++ } + } + + void +@@ -2039,16 +2117,116 @@ view(const Arg *arg) + arrange(selmon); + } + ++pid_t ++winpid(Window w) ++{ ++ pid_t result = 0; ++ ++ xcb_res_client_id_spec_t spec = {0}; ++ spec.client = w; ++ spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID; ++ ++ xcb_generic_error_t *e = NULL; ++ xcb_res_query_client_ids_cookie_t c = xcb_res_query_client_ids(xcon, 1, &spec); ++ xcb_res_query_client_ids_reply_t *r = xcb_res_query_client_ids_reply(xcon, c, &e); ++ ++ if (!r) ++ return (pid_t)0; ++ ++ xcb_res_client_id_value_iterator_t i = xcb_res_query_client_ids_ids_iterator(r); ++ for (; i.rem; xcb_res_client_id_value_next(&i)) { ++ spec = i.data->spec; ++ if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID) { ++ uint32_t *t = xcb_res_client_id_value_value(i.data); ++ result = *t; ++ break; ++ } ++ } ++ ++ free(r); ++ ++ if (result == (pid_t)-1) ++ result = 0; ++ return result; ++} ++ ++pid_t ++getparentprocess(pid_t p) ++{ ++ unsigned int v = 0; ++ ++#ifdef __linux__ ++ FILE *f; ++ char buf[256]; ++ snprintf(buf, sizeof(buf) - 1, "/proc/%u/stat", (unsigned)p); ++ ++ if (!(f = fopen(buf, "r"))) ++ return 0; ++ ++ fscanf(f, "%*u %*s %*c %u", &v); ++ fclose(f); ++#endif /* __linux__ */ ++ ++ return (pid_t)v; ++} ++ ++int ++isdescprocess(pid_t p, pid_t c) ++{ ++ while (p != c && c != 0) ++ c = getparentprocess(c); ++ ++ return (int)c; ++} ++ ++Client * ++termforwin(const Client *w) ++{ ++ Client *c; ++ Monitor *m; ++ ++ if (!w->pid || w->isterminal) ++ return NULL; ++ ++ for (m = mons; m; m = m->next) { ++ for (c = m->clients; c; c = c->next) { ++ if (c->isterminal && !c->swallowing && c->pid && isdescprocess(c->pid, w->pid)) ++ return c; ++ } ++ } ++ ++ return NULL; ++} ++ ++Client * ++swallowingclient(Window w) ++{ ++ Client *c; ++ Monitor *m; ++ ++ for (m = mons; m; m = m->next) { ++ for (c = m->clients; c; c = c->next) { ++ if (c->swallowing && c->swallowing->win == w) ++ return c; ++ } ++ } ++ ++ return NULL; ++} ++ + Client * + wintoclient(Window w) + { + Client *c; + Monitor *m; + +- for (m = mons; m; m = m->next) +- for (c = m->clients; c; c = c->next) ++ for (m = mons; m; m = m->next) { ++ for (c = m->clients; c; c = c->next) { + if (c->win == w) + return c; ++ } ++ } ++ + return NULL; + } + +@@ -2130,6 +2308,8 @@ main(int argc, char *argv[]) + fputs("warning: no locale support\n", stderr); + if (!(dpy = XOpenDisplay(NULL))) + die("dwm: cannot open display\n"); ++ if (!(xcon = XGetXCBConnection(dpy))) ++ die("dwm: cannot get xcb connection\n"); + checkotherwm(); + setup(); + scan(); diff --git a/dwm.suckless.org/patches/dwm-swallow-6.1.diff b/dwm.suckless.org/patches/dwm-swallow-6.1.diff @@ -0,0 +1,382 @@ +diff --git a/config.def.h b/config.def.h +index 7054c06..2bfd607 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -24,9 +24,10 @@ static const Rule rules[] = { + * WM_CLASS(STRING) = instance, class + * WM_NAME(STRING) = title + */ +- /* class instance title tags mask isfloating monitor */ +- { "Gimp", NULL, NULL, 0, 1, -1 }, +- { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, ++ /* class instance title tags mask isfloating isterminal noswallow monitor */ ++ { "Gimp", NULL, NULL, 0, 1, 0, 0, -1 }, ++ { "Firefox", NULL, NULL, 1 << 8, 0, 0, 0, -1 }, ++ { "st", NULL, NULL, 0, 0, 1, 1, -1 }, + }; + + /* layout(s) */ +diff --git a/config.mk b/config.mk +index 4eefb71..34ea872 100644 +--- a/config.mk ++++ b/config.mk +@@ -22,7 +22,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} -lX11-xcb -lxcb -lxcb-res + + # flags + CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} +diff --git a/dwm.c b/dwm.c +index 0362114..566491a 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -40,6 +40,8 @@ + #include <X11/extensions/Xinerama.h> + #endif /* XINERAMA */ + #include <X11/Xft/Xft.h> ++#include <X11/Xlib-xcb.h> ++#include <xcb/res.h> + + #include "drw.h" + #include "util.h" +@@ -92,9 +94,11 @@ struct Client { + int basew, baseh, incw, inch, maxw, maxh, minw, minh; + int bw, oldbw; + unsigned int tags; +- int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; ++ int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isterminal, noswallow; ++ pid_t pid; + Client *next; + Client *snext; ++ Client *swallowing; + Monitor *mon; + Window win; + }; +@@ -138,6 +142,8 @@ typedef struct { + const char *title; + unsigned int tags; + int isfloating; ++ int isterminal; ++ int noswallow; + int monitor; + } Rule; + +@@ -170,12 +176,14 @@ static void focus(Client *c); + static void focusin(XEvent *e); + static void focusmon(const Arg *arg); + static void focusstack(const Arg *arg); ++static pid_t getparentprocess(pid_t p); + static int getrootptr(int *x, int *y); + static long getstate(Window w); + static int gettextprop(Window w, Atom atom, char *text, unsigned int size); + static void grabbuttons(Client *c, int focused); + static void grabkeys(void); + static void incnmaster(const Arg *arg); ++static int isdescprocess(pid_t p, pid_t c); + static void keypress(XEvent *e); + static void killclient(const Arg *arg); + static void manage(Window w, XWindowAttributes *wa); +@@ -206,8 +214,10 @@ static void setup(void); + static void showhide(Client *c); + static void sigchld(int unused); + static void spawn(const Arg *arg); ++static Client *swallowingclient(Window w); + static void tag(const Arg *arg); + static void tagmon(const Arg *arg); ++static Client *termforwin(const Client *c); + static void tile(Monitor *); + static void togglebar(const Arg *arg); + static void togglefloating(const Arg *arg); +@@ -227,6 +237,7 @@ static void updatewindowtype(Client *c); + static void updatetitle(Client *c); + static void updatewmhints(Client *c); + static void view(const Arg *arg); ++static pid_t winpid(Window w); + static Client *wintoclient(Window w); + static Monitor *wintomon(Window w); + static int xerror(Display *dpy, XErrorEvent *ee); +@@ -267,6 +278,8 @@ static Drw *drw; + static Monitor *mons, *selmon; + static Window root; + ++static xcb_connection_t *xcon; ++ + /* configuration, allows nested code to access above variables */ + #include "config.h" + +@@ -296,6 +309,7 @@ applyrules(Client *c) + && (!r->class || strstr(class, r->class)) + && (!r->instance || strstr(instance, r->instance))) + { ++ c->isterminal = r->isterminal; + c->isfloating = r->isfloating; + c->tags |= r->tags; + for (m = mons; m && m->num != r->monitor; m = m->next); +@@ -413,6 +427,46 @@ attachstack(Client *c) + } + + void ++swallow(Client *p, Client *c) ++{ ++ if (c->noswallow || c->isterminal) ++ return; ++ ++ detach(c); ++ detachstack(c); ++ ++ setclientstate(c, WithdrawnState); ++ XUnmapWindow(dpy, p->win); ++ ++ p->swallowing = c; ++ c->mon = p->mon; ++ ++ Window w = p->win; ++ p->win = c->win; ++ c->win = w; ++ updatetitle(p); ++ arrange(p->mon); ++ configure(p); ++ updateclientlist(); ++} ++ ++void ++unswallow(Client *c) ++{ ++ c->win = c->swallowing->win; ++ ++ free(c->swallowing); ++ c->swallowing = NULL; ++ ++ updatetitle(c); ++ arrange(c->mon); ++ XMapWindow(dpy, c->win); ++ XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); ++ configure(c); ++ setclientstate(c, NormalState); ++} ++ ++void + buttonpress(XEvent *e) + { + unsigned int i, x, click; +@@ -475,7 +529,7 @@ cleanup(void) + selmon->lt[selmon->sellt] = &foo; + for (m = mons; m; m = m->next) + while (m->stack) +- unmanage(m->stack, 0); ++ unmanage(m->stack, 0); // XXX - unmanage swallowing windows too + XUngrabKey(dpy, AnyKey, AnyModifier, root); + while (mons) + cleanupmon(mons); +@@ -661,6 +715,9 @@ destroynotify(XEvent *e) + + if ((c = wintoclient(ev->window))) + unmanage(c, 1); ++ ++ else if ((c = swallowingclient(ev->window))) ++ unmanage(c->swallowing, 1); + } + + void +@@ -1032,12 +1089,13 @@ killclient(const Arg *arg) + void + manage(Window w, XWindowAttributes *wa) + { +- Client *c, *t = NULL; ++ Client *c, *t, *term = NULL; + Window trans = None; + XWindowChanges wc; + + c = ecalloc(1, sizeof(Client)); + c->win = w; ++ c->pid = winpid(w); + updatetitle(c); + if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) { + c->mon = t->mon; +@@ -1045,7 +1103,9 @@ manage(Window w, XWindowAttributes *wa) + } else { + c->mon = selmon; + applyrules(c); ++ term = termforwin(c); + } ++ + /* geometry */ + c->x = c->oldx = wa->x; + c->y = c->oldy = wa->y; +@@ -1087,6 +1147,8 @@ manage(Window w, XWindowAttributes *wa) + c->mon->sel = c; + arrange(c->mon); + XMapWindow(dpy, c->win); ++ if (term) ++ swallow(term, c); + focus(NULL); + } + +@@ -1758,6 +1820,20 @@ unmanage(Client *c, int destroyed) + Monitor *m = c->mon; + XWindowChanges wc; + ++ if (c->swallowing) { ++ unswallow(c); ++ return; ++ } ++ ++ Client *s = swallowingclient(c->win); ++ if (s) { ++ free(s->swallowing); ++ s->swallowing = NULL; ++ arrange(m); ++ focus(NULL); ++ return; ++ } ++ + /* The server grab construct avoids race conditions. */ + detach(c); + detachstack(c); +@@ -1773,9 +1849,12 @@ unmanage(Client *c, int destroyed) + XUngrabServer(dpy); + } + free(c); +- focus(NULL); +- updateclientlist(); +- arrange(m); ++ ++ if (!s) { ++ arrange(m); ++ focus(NULL); ++ updateclientlist(); ++ } + } + + void +@@ -2040,16 +2119,116 @@ view(const Arg *arg) + arrange(selmon); + } + ++pid_t ++winpid(Window w) ++{ ++ pid_t result = 0; ++ ++ xcb_res_client_id_spec_t spec = {0}; ++ spec.client = w; ++ spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID; ++ ++ xcb_generic_error_t *e = NULL; ++ xcb_res_query_client_ids_cookie_t c = xcb_res_query_client_ids(xcon, 1, &spec); ++ xcb_res_query_client_ids_reply_t *r = xcb_res_query_client_ids_reply(xcon, c, &e); ++ ++ if (!r) ++ return (pid_t)0; ++ ++ xcb_res_client_id_value_iterator_t i = xcb_res_query_client_ids_ids_iterator(r); ++ for (; i.rem; xcb_res_client_id_value_next(&i)) { ++ spec = i.data->spec; ++ if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID) { ++ uint32_t *t = xcb_res_client_id_value_value(i.data); ++ result = *t; ++ break; ++ } ++ } ++ ++ free(r); ++ ++ if (result == (pid_t)-1) ++ result = 0; ++ return result; ++} ++ ++pid_t ++getparentprocess(pid_t p) ++{ ++ unsigned int v = 0; ++ ++#ifdef __linux__ ++ FILE *f; ++ char buf[256]; ++ snprintf(buf, sizeof(buf) - 1, "/proc/%u/stat", (unsigned)p); ++ ++ if (!(f = fopen(buf, "r"))) ++ return 0; ++ ++ fscanf(f, "%*u %*s %*c %u", &v); ++ fclose(f); ++#endif /* __linux__ */ ++ ++ return (pid_t)v; ++} ++ ++int ++isdescprocess(pid_t p, pid_t c) ++{ ++ while (p != c && c != 0) ++ c = getparentprocess(c); ++ ++ return (int)c; ++} ++ ++Client * ++termforwin(const Client *w) ++{ ++ Client *c; ++ Monitor *m; ++ ++ if (!w->pid || w->isterminal) ++ return NULL; ++ ++ for (m = mons; m; m = m->next) { ++ for (c = m->clients; c; c = c->next) { ++ if (c->isterminal && !c->swallowing && c->pid && isdescprocess(c->pid, w->pid)) ++ return c; ++ } ++ } ++ ++ return NULL; ++} ++ ++Client * ++swallowingclient(Window w) ++{ ++ Client *c; ++ Monitor *m; ++ ++ for (m = mons; m; m = m->next) { ++ for (c = m->clients; c; c = c->next) { ++ if (c->swallowing && c->swallowing->win == w) ++ return c; ++ } ++ } ++ ++ return NULL; ++} ++ + Client * + wintoclient(Window w) + { + Client *c; + Monitor *m; + +- for (m = mons; m; m = m->next) +- for (c = m->clients; c; c = c->next) ++ for (m = mons; m; m = m->next) { ++ for (c = m->clients; c; c = c->next) { + if (c->win == w) + return c; ++ } ++ } ++ + return NULL; + } + +@@ -2131,6 +2310,8 @@ main(int argc, char *argv[]) + fputs("warning: no locale support\n", stderr); + if (!(dpy = XOpenDisplay(NULL))) + die("dwm: cannot open display\n"); ++ if (!(xcon = XGetXCBConnection(dpy))) ++ die("dwm: cannot get xcb connection\n"); + checkotherwm(); + setup(); + scan(); diff --git a/dwm.suckless.org/patches/dwm-swapfocus-20160731-56a31dc.diff b/dwm.suckless.org/patches/dwm-swapfocus-20160731-56a31dc.diff @@ -0,0 +1,67 @@ +Author: Jan Christoph Ebersbach <jceb@e-jc.de> +URL: http://dwm.suckless.org/patches/swapfocus +This patch makes it possible to switch focus with one single shortcut (alt-s) +instead of having to think if you should use alt-j or alt-k for reaching the +last used window. + +Index: dwm/dwm.c +=================================================================== +--- dwm/dwm.c.orig ++++ dwm/dwm.c +@@ -207,6 +207,7 @@ static void setup(void); + static void showhide(Client *c); + static void sigchld(int unused); + static void spawn(const Arg *arg); ++static void swapfocus(); + static void tag(const Arg *arg); + static void tagmon(const Arg *arg); + static void tile(Monitor *); +@@ -236,6 +237,7 @@ static int xerrorstart(Display *dpy, XEr + static void zoom(const Arg *arg); + + /* variables */ ++static Client *prevclient = NULL; + static const char broken[] = "broken"; + static char stext[256]; + static int screen; +@@ -1645,6 +1647,17 @@ spawn(const Arg *arg) + } + + void ++swapfocus() ++{ ++ Client *c; ++ for(c = selmon->clients; c && c != prevclient; c = c->next) ; ++ if(c == prevclient) { ++ focus(prevclient); ++ restack(prevclient->mon); ++ } ++} ++ ++void + tag(const Arg *arg) + { + if (selmon->sel && arg->ui & TAGMASK) { +@@ -1743,6 +1756,7 @@ unfocus(Client *c, int setfocus) + { + if (!c) + return; ++ prevclient = c; + grabbuttons(c, 0); + XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel); + if (setfocus) { +@@ -2109,12 +2123,13 @@ void + zoom(const Arg *arg) + { + Client *c = selmon->sel; ++ prevclient = nexttiled(selmon->clients); + + if (!selmon->lt[selmon->sellt]->arrange + || (selmon->sel && selmon->sel->isfloating)) + return; + if (c == nexttiled(selmon->clients)) +- if (!c || !(c = nexttiled(c->next))) ++ if (!c || !(c = prevclient = nexttiled(c->next))) + return; + pop(c); + } diff --git a/dwm.suckless.org/patches/dwm-6.0-swapfocus.diff b/dwm.suckless.org/patches/dwm-swapfocus-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-switchcol-6.1.diff b/dwm.suckless.org/patches/dwm-switchcol-6.1.diff @@ -0,0 +1,47 @@ +diff -urp dwm-6.1/dwm.c dwm-6.1-patched/dwm.c +--- dwm-6.1/dwm.c 2015-11-09 06:39:37.000000000 +0800 ++++ dwm-6.1-patched/dwm.c 2016-03-24 23:56:35.435047948 +0800 +@@ -206,6 +206,7 @@ static void setup(void); + static void showhide(Client *c); + static void sigchld(int unused); + static void spawn(const Arg *arg); ++static void switchcol(const Arg *arg); + static void tag(const Arg *arg); + static void tagmon(const Arg *arg); + static void tile(Monitor *); +@@ -1645,6 +1646,35 @@ spawn(const Arg *arg) + } + } + ++void ++switchcol(const Arg *arg) ++{ ++ Client *c, *t; ++ int col = 0; ++ int i; ++ ++ if (!selmon->sel) ++ return; ++ for (i = 0, c = nexttiled(selmon->clients); c ; ++ c = nexttiled(c->next), i++) { ++ if (c == selmon->sel) ++ col = (i + 1) > selmon->nmaster; ++ } ++ if (i <= selmon->nmaster) ++ return; ++ for (c = selmon->stack; c; c = c->snext) { ++ if (!ISVISIBLE(c)) ++ continue; ++ for (i = 0, t = nexttiled(selmon->clients); t && t != c; ++ t = nexttiled(t->next), i++); ++ if (t && (i + 1 > selmon->nmaster) != col) { ++ focus(c); ++ restack(selmon); ++ break; ++ } ++ } ++} ++ + void + tag(const Arg *arg) + { diff --git a/dwm.suckless.org/patches/dwm-systray-20160731-56a31dc.diff b/dwm.suckless.org/patches/dwm-systray-20160731-56a31dc.diff @@ -0,0 +1,725 @@ +Authors: + Jan Christoph Ebersbach <jceb@e-jc.de>, inspired by http://code.google.com/p/dwm-plus + Eric Pruitt <eric.pruitt@gmail.com> + Yury Shvedov <shved@lvk.cs.msu.su> +URL: http://dwm.suckless.org/patches/systray +Implements a system tray for dwm. + +Contributors: +- Carlos Pita, thanks for investigating multi monitor issues and sending in a + patch + +Index: dwm/config.def.h +=================================================================== +--- dwm/config.def.h.orig ++++ dwm/config.def.h +@@ -3,6 +3,10 @@ + /* appearance */ + static const unsigned int borderpx = 1; /* border pixel of windows */ + static const unsigned int snap = 32; /* snap pixel */ ++static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */ ++static const unsigned int systrayspacing = 2; /* systray spacing */ ++static const int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/ ++static const int showsystray = 1; /* 0 means no systray */ + static const int showbar = 1; /* 0 means no bar */ + static const int topbar = 1; /* 0 means bottom bar */ + static const char *fonts[] = { "monospace:size=10" }; +Index: dwm/dwm.c +=================================================================== +--- dwm/dwm.c.orig ++++ dwm/dwm.c +@@ -58,12 +58,30 @@ + #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) + #define ColBorder 2 + ++#define SYSTEM_TRAY_REQUEST_DOCK 0 ++ ++/* XEMBED messages */ ++#define XEMBED_EMBEDDED_NOTIFY 0 ++#define XEMBED_WINDOW_ACTIVATE 1 ++#define XEMBED_FOCUS_IN 4 ++#define XEMBED_MODALITY_ON 10 ++ ++#define XEMBED_MAPPED (1 << 0) ++#define XEMBED_WINDOW_ACTIVATE 1 ++#define XEMBED_WINDOW_DEACTIVATE 2 ++ ++#define VERSION_MAJOR 0 ++#define VERSION_MINOR 0 ++#define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR ++ + /* enums */ + enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ + enum { SchemeNorm, SchemeSel, SchemeLast }; /* color schemes */ + enum { NetSupported, NetWMName, NetWMState, ++ NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSystemTrayOrientationHorz, + NetWMFullscreen, NetActiveWindow, NetWMWindowType, + NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ ++enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */ + enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ + enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, + ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ +@@ -142,6 +160,12 @@ typedef struct { + int monitor; + } Rule; + ++typedef struct Systray Systray; ++struct Systray { ++ Window win; ++ Client *icons; ++}; ++ + /* function declarations */ + static void applyrules(Client *c); + static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact); +@@ -171,8 +195,10 @@ static void focus(Client *c); + static void focusin(XEvent *e); + static void focusmon(const Arg *arg); + static void focusstack(const Arg *arg); ++static Atom getatomprop(Client *c, Atom prop); + static int getrootptr(int *x, int *y); + static long getstate(Window w); ++static unsigned int getsystraywidth(); + static int gettextprop(Window w, Atom atom, char *text, unsigned int size); + static void grabbuttons(Client *c, int focused); + static void grabkeys(void); +@@ -190,13 +216,16 @@ static void pop(Client *); + static void propertynotify(XEvent *e); + static void quit(const Arg *arg); + static Monitor *recttomon(int x, int y, int w, int h); ++static void removesystrayicon(Client *i); + static void resize(Client *c, int x, int y, int w, int h, int interact); ++static void resizebarwin(Monitor *m); + static void resizeclient(Client *c, int x, int y, int w, int h); + static void resizemouse(const Arg *arg); ++static void resizerequest(XEvent *e); + static void restack(Monitor *m); + static void run(void); + static void scan(void); +-static int sendevent(Client *c, Atom proto); ++static int sendevent(Window w, Atom proto, int m, long d0, long d1, long d2, long d3, long d4); + static void sendmon(Client *c, Monitor *m); + static void setclientstate(Client *c, long state); + static void setfocus(Client *c); +@@ -207,6 +236,7 @@ static void setup(void); + static void showhide(Client *c); + static void sigchld(int unused); + static void spawn(const Arg *arg); ++static Monitor *systraytomon(Monitor *m); + static void tag(const Arg *arg); + static void tagmon(const Arg *arg); + static void tile(Monitor *); +@@ -224,18 +254,23 @@ static void updateclientlist(void); + static void updatenumlockmask(void); + static void updatesizehints(Client *c); + static void updatestatus(void); ++static void updatesystray(void); ++static void updatesystrayicongeom(Client *i, int w, int h); ++static void updatesystrayiconstate(Client *i, XPropertyEvent *ev); + static void updatewindowtype(Client *c); + static void updatetitle(Client *c); + static void updatewmhints(Client *c); + static void view(const Arg *arg); + static Client *wintoclient(Window w); + static Monitor *wintomon(Window w); ++static Client *wintosystrayicon(Window w); + static int xerror(Display *dpy, XErrorEvent *ee); + static int xerrordummy(Display *dpy, XErrorEvent *ee); + static int xerrorstart(Display *dpy, XErrorEvent *ee); + static void zoom(const Arg *arg); + + /* variables */ ++static Systray *systray = NULL; + static const char broken[] = "broken"; + static char stext[256]; + static int screen; +@@ -258,9 +293,10 @@ static void (*handler[LASTEvent]) (XEven + [MapRequest] = maprequest, + [MotionNotify] = motionnotify, + [PropertyNotify] = propertynotify, ++ [ResizeRequest] = resizerequest, + [UnmapNotify] = unmapnotify + }; +-static Atom wmatom[WMLast], netatom[NetLast]; ++static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast]; + static int running = 1; + static Cur *cursor[CurLast]; + static Scm scheme[SchemeLast]; +@@ -481,6 +517,11 @@ cleanup(void) + XUngrabKey(dpy, AnyKey, AnyModifier, root); + while (mons) + cleanupmon(mons); ++ if (showsystray) { ++ XUnmapWindow(dpy, systray->win); ++ XDestroyWindow(dpy, systray->win); ++ free(systray); ++ } + for (i = 0; i < CurLast; i++) + drw_cur_free(drw, cursor[i]); + for (i = 0; i < SchemeLast; i++) +@@ -523,9 +564,52 @@ clearurgent(Client *c) + void + clientmessage(XEvent *e) + { ++ XWindowAttributes wa; ++ XSetWindowAttributes swa; + XClientMessageEvent *cme = &e->xclient; + Client *c = wintoclient(cme->window); + ++ if (showsystray && cme->window == systray->win && cme->message_type == netatom[NetSystemTrayOP]) { ++ /* add systray icons */ ++ if (cme->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) { ++ if (!(c = (Client *)calloc(1, sizeof(Client)))) ++ die("fatal: could not malloc() %u bytes\n", sizeof(Client)); ++ if (!(c->win = cme->data.l[2])) { ++ free(c); ++ return; ++ } ++ c->mon = selmon; ++ c->next = systray->icons; ++ systray->icons = c; ++ XGetWindowAttributes(dpy, c->win, &wa); ++ c->x = c->oldx = c->y = c->oldy = 0; ++ c->w = c->oldw = wa.width; ++ c->h = c->oldh = wa.height; ++ c->oldbw = wa.border_width; ++ c->bw = 0; ++ c->isfloating = True; ++ /* reuse tags field as mapped status */ ++ c->tags = 1; ++ updatesizehints(c); ++ updatesystrayicongeom(c, wa.width, wa.height); ++ XAddToSaveSet(dpy, c->win); ++ XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | ResizeRedirectMask); ++ XReparentWindow(dpy, c->win, systray->win, 0, 0); ++ /* use parents background color */ ++ swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; ++ XChangeWindowAttributes(dpy, c->win, CWBackPixel, &swa); ++ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0 , systray->win, XEMBED_EMBEDDED_VERSION); ++ /* FIXME not sure if I have to send these events, too */ ++ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_FOCUS_IN, 0 , systray->win, XEMBED_EMBEDDED_VERSION); ++ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0 , systray->win, XEMBED_EMBEDDED_VERSION); ++ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_MODALITY_ON, 0 , systray->win, XEMBED_EMBEDDED_VERSION); ++ XSync(dpy, False); ++ resizebarwin(selmon); ++ updatesystray(); ++ setclientstate(c, NormalState); ++ } ++ return; ++ } + if (!c) + return; + if (cme->message_type == netatom[NetWMState]) { +@@ -580,7 +664,7 @@ configurenotify(XEvent *e) + for (c = m->clients; c; c = c->next) + if (c->isfullscreen) + resizeclient(c, m->mx, m->my, m->mw, m->mh); +- XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); ++ resizebarwin(m); + } + focus(NULL); + arrange(NULL); +@@ -665,6 +749,11 @@ destroynotify(XEvent *e) + + if ((c = wintoclient(ev->window))) + unmanage(c, 1); ++ else if ((c = wintosystrayicon(ev->window))) { ++ removesystrayicon(c); ++ resizebarwin(selmon); ++ updatesystray(); ++ } + } + + void +@@ -708,19 +797,23 @@ dirtomon(int dir) + void + drawbar(Monitor *m) + { +- int x, w, sw = 0; ++ int x, w, sw = 0, stw = 0; + int boxs = drw->fonts->h / 9; + int boxw = drw->fonts->h / 6 + 2; + unsigned int i, occ = 0, urg = 0; + Client *c; + ++ if(showsystray && m == systraytomon(m)) ++ stw = getsystraywidth(); ++ + /* draw status first so it can be overdrawn by tags later */ + if (m == selmon) { /* status is only drawn on selected monitor */ + drw_setscheme(drw, scheme[SchemeNorm]); + sw = TEXTW(stext) - lrpad / 2; /* no right padding so status text hugs the corner */ +- drw_text(drw, m->ww - sw, 0, sw, bh, lrpad / 2 - 2, stext, 0); ++ drw_text(drw, m->ww - sw - stw, 0, sw, bh, lrpad / 2 - 2, stext, 0); + } + ++ resizebarwin(m); + for (c = m->clients; c; c = c->next) { + occ |= c->tags; + if (c->isurgent) +@@ -741,7 +834,7 @@ drawbar(Monitor *m) + drw_setscheme(drw, scheme[SchemeNorm]); + x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); + +- if ((w = m->ww - sw - x) > bh) { ++ if ((w = m->ww - sw - stw - x) > bh) { + if (m->sel) { + drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); + drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); +@@ -752,7 +845,7 @@ drawbar(Monitor *m) + drw_rect(drw, x, 0, w, bh, 1, 1); + } + } +- drw_map(drw, m->barwin, 0, 0, m->ww, bh); ++ drw_map(drw, m->barwin, 0, 0, m->ww - stw, bh); + } + + void +@@ -789,8 +882,11 @@ expose(XEvent *e) + Monitor *m; + XExposeEvent *ev = &e->xexpose; + +- if (ev->count == 0 && (m = wintomon(ev->window))) ++ if (ev->count == 0 && (m = wintomon(ev->window))) { + drawbar(m); ++ if (m == selmon) ++ updatesystray(); ++ } + } + + void +@@ -877,10 +973,17 @@ getatomprop(Client *c, Atom prop) + unsigned long dl; + unsigned char *p = NULL; + Atom da, atom = None; ++ /* FIXME getatomprop should return the number of items and a pointer to ++ * the stored data instead of this workaround */ ++ Atom req = XA_ATOM; ++ if (prop == xatom[XembedInfo]) ++ req = xatom[XembedInfo]; + +- if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM, ++ if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, req, + &da, &di, &dl, &dl, &p) == Success && p) { + atom = *(Atom *)p; ++ if (da == xatom[XembedInfo] && dl == 2) ++ atom = ((Atom *)p)[1]; + XFree(p); + } + return atom; +@@ -914,6 +1017,16 @@ getstate(Window w) + return result; + } + ++unsigned int ++getsystraywidth() ++{ ++ unsigned int w = 0; ++ Client *i; ++ if(showsystray) ++ for(i = systray->icons; i; w += i->w + systrayspacing, i = i->next) ; ++ return w ? w + systrayspacing : 1; ++} ++ + int + gettextprop(Window w, Atom atom, char *text, unsigned int size) + { +@@ -1020,7 +1133,7 @@ killclient(const Arg *arg) + { + if (!selmon->sel) + return; +- if (!sendevent(selmon->sel, wmatom[WMDelete])) { ++ if (!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, wmatom[WMDelete], CurrentTime, 0 , 0, 0)) { + XGrabServer(dpy); + XSetErrorHandler(xerrordummy); + XSetCloseDownMode(dpy, DestroyAll); +@@ -1108,6 +1221,12 @@ maprequest(XEvent *e) + { + static XWindowAttributes wa; + XMapRequestEvent *ev = &e->xmaprequest; ++ Client *i; ++ if ((i = wintosystrayicon(ev->window))) { ++ sendevent(i->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION); ++ resizebarwin(selmon); ++ updatesystray(); ++ } + + if (!XGetWindowAttributes(dpy, ev->window, &wa)) + return; +@@ -1235,6 +1354,16 @@ propertynotify(XEvent *e) + Window trans; + XPropertyEvent *ev = &e->xproperty; + ++ if ((c = wintosystrayicon(ev->window))) { ++ if (ev->atom == XA_WM_NORMAL_HINTS) { ++ updatesizehints(c); ++ updatesystrayicongeom(c, c->w, c->h); ++ } ++ else ++ updatesystrayiconstate(c, ev); ++ resizebarwin(selmon); ++ updatesystray(); ++ } + if ((ev->window == root) && (ev->atom == XA_WM_NAME)) + updatestatus(); + else if (ev->state == PropertyDelete) +@@ -1286,6 +1415,20 @@ recttomon(int x, int y, int w, int h) + } + + void ++removesystrayicon(Client *i) ++{ ++ Client **ii; ++ ++ if (!showsystray || !i) ++ return; ++ for (ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next); ++ if (ii) ++ *ii = i->next; ++ free(i); ++} ++ ++ ++void + resize(Client *c, int x, int y, int w, int h, int interact) + { + if (applysizehints(c, &x, &y, &w, &h, interact)) +@@ -1293,6 +1436,14 @@ resize(Client *c, int x, int y, int w, i + } + + void ++resizebarwin(Monitor *m) { ++ unsigned int w = m->ww; ++ if (showsystray && m == systraytomon(m)) ++ w -= getsystraywidth(); ++ XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, w, bh); ++} ++ ++void + resizeclient(Client *c, int x, int y, int w, int h) + { + XWindowChanges wc; +@@ -1365,6 +1516,19 @@ resizemouse(const Arg *arg) + } + + void ++resizerequest(XEvent *e) ++{ ++ XResizeRequestEvent *ev = &e->xresizerequest; ++ Client *i; ++ ++ if ((i = wintosystrayicon(ev->window))) { ++ updatesystrayicongeom(i, ev->width, ev->height); ++ resizebarwin(selmon); ++ updatesystray(); ++ } ++} ++ ++void + restack(Monitor *m) + { + Client *c; +@@ -1453,26 +1617,36 @@ setclientstate(Client *c, long state) + } + + int +-sendevent(Client *c, Atom proto) ++sendevent(Window w, Atom proto, int mask, long d0, long d1, long d2, long d3, long d4) + { + int n; +- Atom *protocols; ++ Atom *protocols, mt; + int exists = 0; + XEvent ev; + +- if (XGetWMProtocols(dpy, c->win, &protocols, &n)) { +- while (!exists && n--) +- exists = protocols[n] == proto; +- XFree(protocols); ++ if (proto == wmatom[WMTakeFocus] || proto == wmatom[WMDelete]) { ++ mt = wmatom[WMProtocols]; ++ if (XGetWMProtocols(dpy, w, &protocols, &n)) { ++ while (!exists && n--) ++ exists = protocols[n] == proto; ++ XFree(protocols); ++ } ++ } ++ else { ++ exists = True; ++ mt = proto; + } + if (exists) { + ev.type = ClientMessage; +- ev.xclient.window = c->win; +- ev.xclient.message_type = wmatom[WMProtocols]; ++ ev.xclient.window = w; ++ ev.xclient.message_type = mt; + ev.xclient.format = 32; +- ev.xclient.data.l[0] = proto; +- ev.xclient.data.l[1] = CurrentTime; +- XSendEvent(dpy, c->win, False, NoEventMask, &ev); ++ ev.xclient.data.l[0] = d0; ++ ev.xclient.data.l[1] = d1; ++ ev.xclient.data.l[2] = d2; ++ ev.xclient.data.l[3] = d3; ++ ev.xclient.data.l[4] = d4; ++ XSendEvent(dpy, w, False, mask, &ev); + } + return exists; + } +@@ -1486,7 +1660,7 @@ setfocus(Client *c) + XA_WINDOW, 32, PropModeReplace, + (unsigned char *) &(c->win), 1); + } +- sendevent(c, wmatom[WMTakeFocus]); ++ sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0); + } + + void +@@ -1572,12 +1746,19 @@ setup(void) + wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); + netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); + netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); ++ netatom[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0", False); ++ netatom[NetSystemTrayOP] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", False); ++ netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION", False); ++ netatom[NetSystemTrayOrientationHorz] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION_HORZ", False); + netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); + netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False); + netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); + netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); + netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); + netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); ++ xatom[Manager] = XInternAtom(dpy, "MANAGER", False); ++ xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False); ++ xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", False); + /* init cursors */ + cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); + cursor[CurResize] = drw_cur_create(drw, XC_sizing); +@@ -1585,6 +1766,8 @@ setup(void) + /* init appearance */ + scheme[SchemeNorm] = drw_scm_create(drw, colors[SchemeNorm], 3); + scheme[SchemeSel] = drw_scm_create(drw, colors[SchemeSel], 3); ++ /* init system tray */ ++ updatesystray(); + /* init bars */ + updatebars(); + updatestatus(); +@@ -1693,7 +1876,18 @@ togglebar(const Arg *arg) + { + selmon->showbar = !selmon->showbar; + updatebarpos(selmon); +- XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); ++ resizebarwin(selmon); ++ if (showsystray) { ++ XWindowChanges wc; ++ if (!selmon->showbar) ++ wc.y = -bh; ++ else if (selmon->showbar) { ++ wc.y = 0; ++ if (!selmon->topbar) ++ wc.y = selmon->mh - bh; ++ } ++ XConfigureWindow(dpy, systray->win, CWY, &wc); ++ } + arrange(selmon); + } + +@@ -1789,11 +1983,18 @@ unmapnotify(XEvent *e) + else + unmanage(c, 0); + } ++ else if ((c = wintosystrayicon(ev->window))) { ++ /* KLUDGE! sometimes icons occasionally unmap their windows, but do ++ * _not_ destroy them. We map those windows back */ ++ XMapRaised(dpy, c->win); ++ updatesystray(); ++ } + } + + void + updatebars(void) + { ++ unsigned int w; + Monitor *m; + XSetWindowAttributes wa = { + .override_redirect = True, +@@ -1803,10 +2004,15 @@ updatebars(void) + for (m = mons; m; m = m->next) { + if (m->barwin) + continue; +- m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen), ++ w = m->ww; ++ if (showsystray && m == systraytomon(m)) ++ w -= getsystraywidth(); ++ m->barwin = XCreateWindow(dpy, root, m->wx, m->by, w, bh, 0, DefaultDepth(dpy, screen), + CopyFromParent, DefaultVisual(dpy, screen), + CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); + XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); ++ if (showsystray && m == systraytomon(m)) ++ XMapRaised(dpy, systray->win); + XMapRaised(dpy, m->barwin); + } + } +@@ -1994,6 +2200,121 @@ updatestatus(void) + if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) + strcpy(stext, "dwm-"VERSION); + drawbar(selmon); ++ updatesystray(); ++} ++ ++void ++updatesystrayicongeom(Client *i, int w, int h) ++{ ++ if (i) { ++ i->h = bh; ++ if (w == h) ++ i->w = bh; ++ else if (h == bh) ++ i->w = w; ++ else ++ i->w = (int) ((float)bh * ((float)w / (float)h)); ++ applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), False); ++ /* force icons into the systray dimenons if they don't want to */ ++ if (i->h > bh) { ++ if (i->w == i->h) ++ i->w = bh; ++ else ++ i->w = (int) ((float)bh * ((float)i->w / (float)i->h)); ++ i->h = bh; ++ } ++ } ++} ++ ++void ++updatesystrayiconstate(Client *i, XPropertyEvent *ev) ++{ ++ long flags; ++ int code = 0; ++ ++ if (!showsystray || !i || ev->atom != xatom[XembedInfo] || ++ !(flags = getatomprop(i, xatom[XembedInfo]))) ++ return; ++ ++ if (flags & XEMBED_MAPPED && !i->tags) { ++ i->tags = 1; ++ code = XEMBED_WINDOW_ACTIVATE; ++ XMapRaised(dpy, i->win); ++ setclientstate(i, NormalState); ++ } ++ else if (!(flags & XEMBED_MAPPED) && i->tags) { ++ i->tags = 0; ++ code = XEMBED_WINDOW_DEACTIVATE; ++ XUnmapWindow(dpy, i->win); ++ setclientstate(i, WithdrawnState); ++ } ++ else ++ return; ++ sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0, ++ systray->win, XEMBED_EMBEDDED_VERSION); ++} ++ ++void ++updatesystray(void) ++{ ++ XSetWindowAttributes wa; ++ XWindowChanges wc; ++ Client *i; ++ Monitor *m = systraytomon(NULL); ++ unsigned int x = m->mx + m->mw; ++ unsigned int w = 1; ++ ++ if (!showsystray) ++ return; ++ if (!systray) { ++ /* init systray */ ++ if (!(systray = (Systray *)calloc(1, sizeof(Systray)))) ++ die("fatal: could not malloc() %u bytes\n", sizeof(Systray)); ++ systray->win = XCreateSimpleWindow(dpy, root, x, m->by, w, bh, 0, 0, scheme[SchemeSel][ColBg].pixel); ++ wa.event_mask = ButtonPressMask | ExposureMask; ++ wa.override_redirect = True; ++ wa.background_pixel = scheme[SchemeNorm][ColBg].pixel; ++ XSelectInput(dpy, systray->win, SubstructureNotifyMask); ++ XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], XA_CARDINAL, 32, ++ PropModeReplace, (unsigned char *)&netatom[NetSystemTrayOrientationHorz], 1); ++ XChangeWindowAttributes(dpy, systray->win, CWEventMask|CWOverrideRedirect|CWBackPixel, &wa); ++ XMapRaised(dpy, systray->win); ++ XSetSelectionOwner(dpy, netatom[NetSystemTray], systray->win, CurrentTime); ++ if (XGetSelectionOwner(dpy, netatom[NetSystemTray]) == systray->win) { ++ sendevent(root, xatom[Manager], StructureNotifyMask, CurrentTime, netatom[NetSystemTray], systray->win, 0, 0); ++ XSync(dpy, False); ++ } ++ else { ++ fprintf(stderr, "dwm: unable to obtain system tray.\n"); ++ free(systray); ++ systray = NULL; ++ return; ++ } ++ } ++ for (w = 0, i = systray->icons; i; i = i->next) { ++ /* make sure the background color stays the same */ ++ wa.background_pixel = scheme[SchemeNorm][ColBg].pixel; ++ XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa); ++ XMapRaised(dpy, i->win); ++ w += systrayspacing; ++ i->x = w; ++ XMoveResizeWindow(dpy, i->win, i->x, 0, i->w, i->h); ++ w += i->w; ++ if (i->mon != m) ++ i->mon = m; ++ } ++ w = w ? w + systrayspacing : 1; ++ x -= w; ++ XMoveResizeWindow(dpy, systray->win, x, m->by, w, bh); ++ wc.x = x; wc.y = m->by; wc.width = w; wc.height = bh; ++ wc.stack_mode = Above; wc.sibling = m->barwin; ++ XConfigureWindow(dpy, systray->win, CWX|CWY|CWWidth|CWHeight|CWSibling|CWStackMode, &wc); ++ XMapWindow(dpy, systray->win); ++ XMapSubwindows(dpy, systray->win); ++ /* redraw background */ ++ XSetForeground(dpy, drw->gc, scheme[SchemeNorm][ColBg].pixel); ++ XFillRectangle(dpy, systray->win, drw->gc, 0, 0, w, bh); ++ XSync(dpy, False); + } + + void +@@ -2052,6 +2373,16 @@ wintoclient(Window w) + return NULL; + } + ++Client * ++wintosystrayicon(Window w) { ++ Client *i = NULL; ++ ++ if (!showsystray || !w) ++ return i; ++ for (i = systray->icons; i && i->win != w; i = i->next) ; ++ return i; ++} ++ + Monitor * + wintomon(Window w) + { +@@ -2105,6 +2436,22 @@ xerrorstart(Display *dpy, XErrorEvent *e + return -1; + } + ++Monitor * ++systraytomon(Monitor *m) { ++ Monitor *t; ++ int i, n; ++ if(!systraypinning) { ++ if(!m) ++ return selmon; ++ return m == selmon ? m : NULL; ++ } ++ for(n = 1, t = mons; t && t->next; n++, t = t->next) ; ++ for(i = 1, t = mons; t && t->next && i < systraypinning; i++, t = t->next) ; ++ if(systraypinningfailfirst && n < systraypinning) ++ return mons; ++ return t; ++} ++ + void + zoom(const Arg *arg) + { diff --git a/dwm.suckless.org/patches/dwm-6.0-systray.diff b/dwm.suckless.org/patches/dwm-systray-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-systray-git-20160626-7af4d43.diff b/dwm.suckless.org/patches/dwm-systray-git-20160626-7af4d43.diff @@ -0,0 +1,685 @@ +diff --git a/config.def.h b/config.def.h +index 13ea4b9..d7ae387 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -3,6 +3,10 @@ + /* appearance */ + static const unsigned int borderpx = 1; /* border pixel of windows */ + static const unsigned int snap = 32; /* snap pixel */ ++static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */ ++static const unsigned int systrayspacing = 2; /* systray spacing */ ++static const int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, 0: display systray on the last monitor*/ ++static const int showsystray = 1; /* 0 means no systray */ + static const int showbar = 1; /* 0 means no bar */ + static const int topbar = 1; /* 0 means bottom bar */ + static const char *fonts[] = { "monospace:size=10" }; +diff --git a/dwm.c b/dwm.c +index b2bc9bd..38ad640 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -58,12 +58,30 @@ + #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) + #define ColBorder 2 + ++#define SYSTEM_TRAY_REQUEST_DOCK 0 ++#define _NET_SYSTEM_TRAY_ORIENTATION_HORZ 0 ++ ++/* XEMBED messages */ ++#define XEMBED_EMBEDDED_NOTIFY 0 ++#define XEMBED_WINDOW_ACTIVATE 1 ++#define XEMBED_FOCUS_IN 4 ++#define XEMBED_MODALITY_ON 10 ++ ++#define XEMBED_MAPPED (1 << 0) ++#define XEMBED_WINDOW_ACTIVATE 1 ++#define XEMBED_WINDOW_DEACTIVATE 2 ++ ++#define VERSION_MAJOR 0 ++#define VERSION_MINOR 0 ++#define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR ++ + /* enums */ + enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ + enum { SchemeNorm, SchemeSel, SchemeLast }; /* color schemes */ +-enum { NetSupported, NetWMName, NetWMState, +- NetWMFullscreen, NetActiveWindow, NetWMWindowType, +- NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ ++enum { NetSupported, NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, ++ NetWMName, NetWMState, NetWMFullscreen, NetActiveWindow, NetWMWindowType, ++ NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ ++enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */ + enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ + enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, + ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ +@@ -142,6 +160,12 @@ typedef struct { + int monitor; + } Rule; + ++typedef struct Systray Systray; ++struct Systray { ++ Window win; ++ Client *icons; ++}; ++ + /* function declarations */ + static void applyrules(Client *c); + static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact); +@@ -171,8 +195,10 @@ static void focus(Client *c); + static void focusin(XEvent *e); + static void focusmon(const Arg *arg); + static void focusstack(const Arg *arg); ++static Atom getatomprop(Client *c, Atom prop); + static int getrootptr(int *x, int *y); + static long getstate(Window w); ++static unsigned int getsystraywidth(); + static int gettextprop(Window w, Atom atom, char *text, unsigned int size); + static void grabbuttons(Client *c, int focused); + static void grabkeys(void); +@@ -190,13 +216,16 @@ static void pop(Client *); + static void propertynotify(XEvent *e); + static void quit(const Arg *arg); + static Monitor *recttomon(int x, int y, int w, int h); ++static void removesystrayicon(Client *i); + static void resize(Client *c, int x, int y, int w, int h, int interact); ++static void resizebarwin(Monitor *m); + static void resizeclient(Client *c, int x, int y, int w, int h); + static void resizemouse(const Arg *arg); ++static void resizerequest(XEvent *e); + static void restack(Monitor *m); + static void run(void); + static void scan(void); +-static int sendevent(Client *c, Atom proto); ++static int sendevent(Window w, Atom proto, int m, long d0, long d1, long d2, long d3, long d4); + static void sendmon(Client *c, Monitor *m); + static void setclientstate(Client *c, long state); + static void setfocus(Client *c); +@@ -207,6 +236,7 @@ static void setup(void); + static void showhide(Client *c); + static void sigchld(int unused); + static void spawn(const Arg *arg); ++static Monitor *systraytomon(Monitor *m); + static void tag(const Arg *arg); + static void tagmon(const Arg *arg); + static void tile(Monitor *); +@@ -224,18 +254,24 @@ static void updateclientlist(void); + static void updatenumlockmask(void); + static void updatesizehints(Client *c); + static void updatestatus(void); ++static void updatesystray(void); ++static void updatesystrayicongeom(Client *i, int w, int h); ++static void updatesystrayiconstate(Client *i, XPropertyEvent *ev); + static void updatewindowtype(Client *c); + static void updatetitle(Client *c); + static void updatewmhints(Client *c); + static void view(const Arg *arg); + static Client *wintoclient(Window w); + static Monitor *wintomon(Window w); ++static Client *wintosystrayicon(Window w); + static int xerror(Display *dpy, XErrorEvent *ee); + static int xerrordummy(Display *dpy, XErrorEvent *ee); + static int xerrorstart(Display *dpy, XErrorEvent *ee); + static void zoom(const Arg *arg); + + /* variables */ ++static Systray *systray = NULL; ++static unsigned long systrayorientation = _NET_SYSTEM_TRAY_ORIENTATION_HORZ; + static const char broken[] = "broken"; + static char stext[256]; + static int screen; +@@ -258,9 +294,10 @@ static void (*handler[LASTEvent]) (XEvent *) = { + [MapRequest] = maprequest, + [MotionNotify] = motionnotify, + [PropertyNotify] = propertynotify, ++ [ResizeRequest] = resizerequest, + [UnmapNotify] = unmapnotify + }; +-static Atom wmatom[WMLast], netatom[NetLast]; ++static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast]; + static int running = 1; + static Cur *cursor[CurLast]; + static Scm scheme[SchemeLast]; +@@ -481,6 +518,11 @@ cleanup(void) + XUngrabKey(dpy, AnyKey, AnyModifier, root); + while (mons) + cleanupmon(mons); ++ if (showsystray) { ++ XUnmapWindow(dpy, systray->win); ++ XDestroyWindow(dpy, systray->win); ++ free(systray); ++ } + for (i = 0; i < CurLast; i++) + drw_cur_free(drw, cursor[i]); + for (i = 0; i < SchemeLast; i++) +@@ -523,9 +565,50 @@ clearurgent(Client *c) + void + clientmessage(XEvent *e) + { ++ XWindowAttributes wa; ++ XSetWindowAttributes swa; + XClientMessageEvent *cme = &e->xclient; + Client *c = wintoclient(cme->window); + ++ if (showsystray && cme->window == systray->win && cme->message_type == netatom[NetSystemTrayOP]) { ++ /* add systray icons */ ++ if (cme->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) { ++ if (!(c = (Client *)calloc(1, sizeof(Client)))) ++ die("fatal: could not malloc() %u bytes\n", sizeof(Client)); ++ c->win = cme->data.l[2]; ++ c->mon = selmon; ++ c->next = systray->icons; ++ systray->icons = c; ++ XGetWindowAttributes(dpy, c->win, &wa); ++ c->x = c->oldx = c->y = c->oldy = 0; ++ c->w = c->oldw = wa.width; ++ c->h = c->oldh = wa.height; ++ c->oldbw = wa.border_width; ++ c->bw = 0; ++ c->isfloating = True; ++ /* reuse tags field as mapped status */ ++ c->tags = 1; ++ updatesizehints(c); ++ updatesystrayicongeom(c, wa.width, wa.height); ++ XAddToSaveSet(dpy, c->win); ++ XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | ResizeRedirectMask); ++ XReparentWindow(dpy, c->win, systray->win, 0, 0); ++ /* use parents background color */ ++ swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; ++ XChangeWindowAttributes(dpy, c->win, CWBackPixel, &swa); ++ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0 , systray->win, XEMBED_EMBEDDED_VERSION); ++ /* FIXME not sure if I have to send these events, too */ ++ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_FOCUS_IN, 0 , systray->win, XEMBED_EMBEDDED_VERSION); ++ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0 , systray->win, XEMBED_EMBEDDED_VERSION); ++ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_MODALITY_ON, 0 , systray->win, XEMBED_EMBEDDED_VERSION); ++ XSync(dpy, False); ++ resizebarwin(selmon); ++ updatesystray(); ++ setclientstate(c, NormalState); ++ } ++ return; ++ } ++ + if (!c) + return; + if (cme->message_type == netatom[NetWMState]) { +@@ -580,7 +663,7 @@ configurenotify(XEvent *e) + for (c = m->clients; c; c = c->next) + if (c->isfullscreen) + resizeclient(c, m->mx, m->my, m->mw, m->mh); +- XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); ++ resizebarwin(m); + } + focus(NULL); + arrange(NULL); +@@ -665,6 +748,11 @@ destroynotify(XEvent *e) + + if ((c = wintoclient(ev->window))) + unmanage(c, 1); ++ else if ((c = wintosystrayicon(ev->window))) { ++ removesystrayicon(c); ++ resizebarwin(selmon); ++ updatesystray(); ++ } + } + + void +@@ -718,9 +806,13 @@ drawbar(Monitor *m) + if (m == selmon) { /* status is only drawn on selected monitor */ + drw_setscheme(drw, scheme[SchemeNorm]); + sw = TEXTW(stext) - lrpad / 2; /* no right padding so status text hugs the corner */ ++ if (showsystray && m == systraytomon(m)) { ++ sw += getsystraywidth(); ++ } + drw_text(drw, m->ww - sw, 0, sw, bh, lrpad / 2 - 2, stext, 0); + } + ++ resizebarwin(m); + for (c = m->clients; c; c = c->next) { + occ |= c->tags; + if (c->isurgent) +@@ -762,6 +854,7 @@ drawbars(void) + + for (m = mons; m; m = m->next) + drawbar(m); ++ updatesystray(); + } + + void +@@ -789,8 +882,11 @@ expose(XEvent *e) + Monitor *m; + XExposeEvent *ev = &e->xexpose; + +- if (ev->count == 0 && (m = wintomon(ev->window))) ++ if (ev->count == 0 && (m = wintomon(ev->window))) { + drawbar(m); ++ if (m == selmon) ++ updatesystray(); ++ } + } + + void +@@ -877,10 +973,17 @@ getatomprop(Client *c, Atom prop) + unsigned long dl; + unsigned char *p = NULL; + Atom da, atom = None; ++ /* FIXME getatomprop should return the number of items and a pointer to ++ * the stored data instead of this workaround */ ++ Atom req = XA_ATOM; ++ if (prop == xatom[XembedInfo]) ++ req = xatom[XembedInfo]; + +- if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM, ++ if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, req, + &da, &di, &dl, &dl, &p) == Success && p) { + atom = *(Atom *)p; ++ if (da == xatom[XembedInfo] && dl == 2) ++ atom = ((Atom *)p)[1]; + XFree(p); + } + return atom; +@@ -914,6 +1017,15 @@ getstate(Window w) + return result; + } + ++unsigned int ++getsystraywidth() { ++ unsigned int w = 0; ++ Client *i; ++ if (showsystray) ++ for (i = systray->icons; i; w += i->w + systrayspacing, i = i->next); ++ return w ? w + systrayspacing : 1; ++} ++ + int + gettextprop(Window w, Atom atom, char *text, unsigned int size) + { +@@ -1020,7 +1132,7 @@ killclient(const Arg *arg) + { + if (!selmon->sel) + return; +- if (!sendevent(selmon->sel, wmatom[WMDelete])) { ++ if (!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, wmatom[WMDelete], CurrentTime, 0 , 0, 0)) { + XGrabServer(dpy); + XSetErrorHandler(xerrordummy); + XSetCloseDownMode(dpy, DestroyAll); +@@ -1108,6 +1220,12 @@ maprequest(XEvent *e) + { + static XWindowAttributes wa; + XMapRequestEvent *ev = &e->xmaprequest; ++ Client *i; ++ if ((i = wintosystrayicon(ev->window))) { ++ sendevent(i->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION); ++ resizebarwin(selmon); ++ updatesystray(); ++ } + + if (!XGetWindowAttributes(dpy, ev->window, &wa)) + return; +@@ -1235,6 +1353,16 @@ propertynotify(XEvent *e) + Window trans; + XPropertyEvent *ev = &e->xproperty; + ++ if ((c = wintosystrayicon(ev->window))) { ++ if (ev->atom == XA_WM_NORMAL_HINTS) { ++ updatesizehints(c); ++ updatesystrayicongeom(c, c->w, c->h); ++ } ++ else ++ updatesystrayiconstate(c, ev); ++ resizebarwin(selmon); ++ updatesystray(); ++ } + if ((ev->window == root) && (ev->atom == XA_WM_NAME)) + updatestatus(); + else if (ev->state == PropertyDelete) +@@ -1286,6 +1414,19 @@ recttomon(int x, int y, int w, int h) + } + + void ++removesystrayicon(Client *i) { ++ Client **ii; ++ ++ if (!showsystray || !i) ++ return; ++ for (ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next); ++ if (ii) ++ *ii = i->next; ++ free(i); ++} ++ ++ ++void + resize(Client *c, int x, int y, int w, int h, int interact) + { + if (applysizehints(c, &x, &y, &w, &h, interact)) +@@ -1293,6 +1434,14 @@ resize(Client *c, int x, int y, int w, int h, int interact) + } + + void ++resizebarwin(Monitor *m) { ++ unsigned int w = m->ww; ++ if (showsystray && m == systraytomon(m)) ++ w -= getsystraywidth(); ++ XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, w, bh); ++} ++ ++void + resizeclient(Client *c, int x, int y, int w, int h) + { + XWindowChanges wc; +@@ -1365,6 +1514,18 @@ resizemouse(const Arg *arg) + } + + void ++resizerequest(XEvent *e) { ++ XResizeRequestEvent *ev = &e->xresizerequest; ++ Client *i; ++ ++ if ((i = wintosystrayicon(ev->window))) { ++ updatesystrayicongeom(i, ev->width, ev->height); ++ resizebarwin(selmon); ++ updatesystray(); ++ } ++} ++ ++void + restack(Monitor *m) + { + Client *c; +@@ -1453,26 +1614,36 @@ setclientstate(Client *c, long state) + } + + int +-sendevent(Client *c, Atom proto) ++sendevent(Window w, Atom proto, int mask, long d0, long d1, long d2, long d3, long d4) + { + int n; +- Atom *protocols; ++ Atom *protocols, mt; + int exists = 0; + XEvent ev; + +- if (XGetWMProtocols(dpy, c->win, &protocols, &n)) { +- while (!exists && n--) +- exists = protocols[n] == proto; +- XFree(protocols); ++ if (proto == wmatom[WMTakeFocus] || proto == wmatom[WMDelete]) { ++ mt = wmatom[WMProtocols]; ++ if (XGetWMProtocols(dpy, w, &protocols, &n)) { ++ while(!exists && n--) ++ exists = protocols[n] == proto; ++ XFree(protocols); ++ } ++ } ++ else { ++ exists = True; ++ mt = proto; + } + if (exists) { + ev.type = ClientMessage; +- ev.xclient.window = c->win; +- ev.xclient.message_type = wmatom[WMProtocols]; ++ ev.xclient.window = w; ++ ev.xclient.message_type = mt; + ev.xclient.format = 32; +- ev.xclient.data.l[0] = proto; +- ev.xclient.data.l[1] = CurrentTime; +- XSendEvent(dpy, c->win, False, NoEventMask, &ev); ++ ev.xclient.data.l[0] = d0; ++ ev.xclient.data.l[1] = d1; ++ ev.xclient.data.l[2] = d2; ++ ev.xclient.data.l[3] = d3; ++ ev.xclient.data.l[4] = d4; ++ XSendEvent(dpy, w, False, mask, &ev); + } + return exists; + } +@@ -1486,7 +1657,7 @@ setfocus(Client *c) + XA_WINDOW, 32, PropModeReplace, + (unsigned char *) &(c->win), 1); + } +- sendevent(c, wmatom[WMTakeFocus]); ++ sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0); + } + + void +@@ -1572,12 +1743,18 @@ setup(void) + wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); + netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); + netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); ++ netatom[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0", False); ++ netatom[NetSystemTrayOP] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", False); ++ netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION", False); + netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); + netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False); + netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); + netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); + netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); + netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); ++ xatom[Manager] = XInternAtom(dpy, "MANAGER", False); ++ xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False); ++ xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", False); + /* init cursors */ + cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); + cursor[CurResize] = drw_cur_create(drw, XC_sizing); +@@ -1585,6 +1762,8 @@ setup(void) + /* init appearance */ + scheme[SchemeNorm] = drw_scm_create(drw, colors[SchemeNorm], 3); + scheme[SchemeSel] = drw_scm_create(drw, colors[SchemeSel], 3); ++ /* init system tray */ ++ updatesystray(); + /* init bars */ + updatebars(); + updatestatus(); +@@ -1644,6 +1823,22 @@ spawn(const Arg *arg) + } + } + ++Monitor * ++systraytomon(Monitor *m) { ++ Monitor *t; ++ int i, n; ++ if (!systraypinning) { ++ if (!m) ++ return selmon; ++ return m == selmon ? m : NULL; ++ } ++ for (n = 1, t = mons; t && t->next; n++, t = t->next); ++ for (i = 1, t = mons; t && t->next && i < systraypinning; i++, t = t->next); ++ if (systraypinningfailfirst && n < systraypinning) ++ return mons; ++ return t; ++} ++ + void + tag(const Arg *arg) + { +@@ -1693,7 +1888,18 @@ togglebar(const Arg *arg) + { + selmon->showbar = !selmon->showbar; + updatebarpos(selmon); +- XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); ++ resizebarwin(selmon); ++ if (showsystray) { ++ XWindowChanges wc; ++ if (!selmon->showbar) ++ wc.y = -bh; ++ else if (selmon->showbar) { ++ wc.y = 0; ++ if (!selmon->topbar) ++ wc.y = selmon->mh - bh; ++ } ++ XConfigureWindow(dpy, systray->win, CWY, &wc); ++ } + arrange(selmon); + } + +@@ -1789,11 +1995,17 @@ unmapnotify(XEvent *e) + else + unmanage(c, 0); + } ++ else if ((c = wintosystrayicon(ev->window))) { ++ removesystrayicon(c); ++ resizebarwin(selmon); ++ updatesystray(); ++ } + } + + void + updatebars(void) + { ++ unsigned int w; + Monitor *m; + XSetWindowAttributes wa = { + .override_redirect = True, +@@ -1803,10 +2015,15 @@ updatebars(void) + for (m = mons; m; m = m->next) { + if (m->barwin) + continue; +- m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen), ++ w = m->ww; ++ if (showsystray && m == systraytomon(m)) ++ w -= getsystraywidth(); ++ m->barwin = XCreateWindow(dpy, root, m->wx, m->by, w, bh, 0, DefaultDepth(dpy, screen), + CopyFromParent, DefaultVisual(dpy, screen), + CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); + XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); ++ if (showsystray && m == systraytomon(m)) ++ XMapRaised(dpy, systray->win); + XMapRaised(dpy, m->barwin); + } + } +@@ -1997,6 +2214,117 @@ updatestatus(void) + } + + void ++updatesystrayicongeom(Client *i, int w, int h) { ++ if (i) { ++ i->h = bh; ++ if (w == h) ++ i->w = bh; ++ else if (h == bh) ++ i->w = w; ++ else ++ i->w = (int) ((float)bh * ((float)w / (float)h)); ++ applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), False); ++ /* force icons into the systray dimenons if they don't want to */ ++ if (i->h > bh) { ++ if (i->w == i->h) ++ i->w = bh; ++ else ++ i->w = (int) ((float)bh * ((float)i->w / (float)i->h)); ++ i->h = bh; ++ } ++ } ++} ++ ++void ++updatesystrayiconstate(Client *i, XPropertyEvent *ev) { ++ long flags; ++ int code = 0; ++ ++ if (!showsystray || !i || ev->atom != xatom[XembedInfo] || ++ !(flags = getatomprop(i, xatom[XembedInfo]))) ++ return; ++ ++ if (flags & XEMBED_MAPPED && !i->tags) { ++ i->tags = 1; ++ code = XEMBED_WINDOW_ACTIVATE; ++ XMapRaised(dpy, i->win); ++ setclientstate(i, NormalState); ++ } ++ else if (!(flags & XEMBED_MAPPED) && i->tags) { ++ i->tags = 0; ++ code = XEMBED_WINDOW_DEACTIVATE; ++ XUnmapWindow(dpy, i->win); ++ setclientstate(i, WithdrawnState); ++ } ++ else ++ return; ++ sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0, ++ systray->win, XEMBED_EMBEDDED_VERSION); ++} ++ ++void ++updatesystray(void) { ++ XSetWindowAttributes wa; ++ XWindowChanges wc; ++ Client *i; ++ Monitor *m = systraytomon(NULL); ++ unsigned int x = m->mx + m->mw; ++ unsigned int w = 1; ++ ++ if (!showsystray) ++ return; ++ if (!systray) { ++ /* init systray */ ++ if (!(systray = (Systray *)calloc(1, sizeof(Systray)))) ++ die("fatal: could not malloc() %u bytes\n", sizeof(Systray)); ++ systray->win = XCreateSimpleWindow(dpy, root, x, m->by, w, bh, 0, 0, scheme[SchemeSel][ColBg].pixel); ++ wa.event_mask = ButtonPressMask | ExposureMask; ++ wa.override_redirect = True; ++ wa.background_pixel = scheme[SchemeNorm][ColBg].pixel; ++ XSelectInput(dpy, systray->win, SubstructureNotifyMask); ++ XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], XA_CARDINAL, 32, ++ PropModeReplace, (unsigned char *)&systrayorientation, 1); ++ XChangeWindowAttributes(dpy, systray->win, CWEventMask|CWOverrideRedirect|CWBackPixel, &wa); ++ XMapRaised(dpy, systray->win); ++ XSetSelectionOwner(dpy, netatom[NetSystemTray], systray->win, CurrentTime); ++ if (XGetSelectionOwner(dpy, netatom[NetSystemTray]) == systray->win) { ++ sendevent(root, xatom[Manager], StructureNotifyMask, CurrentTime, netatom[NetSystemTray], systray->win, 0, 0); ++ XSync(dpy, False); ++ } ++ else { ++ fprintf(stderr, "dwm: unable to obtain system tray.\n"); ++ free(systray); ++ systray = NULL; ++ return; ++ } ++ } ++ for (w = 0, i = systray->icons; i; i = i->next) { ++ /* make sure the background color stays the same */ ++ wa.background_pixel = scheme[SchemeNorm][ColBg].pixel; ++ XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa); ++ XMapRaised(dpy, i->win); ++ w += systrayspacing; ++ i->x = w; ++ XMoveResizeWindow(dpy, i->win, i->x, 0, i->w, i->h); ++ w += i->w; ++ if (i->mon != m) ++ i->mon = m; ++ } ++ w = w ? w + systrayspacing : 1; ++ x -= w; ++ XMoveResizeWindow(dpy, systray->win, x, m->by, w, bh); ++ wc.x = x; wc.y = m->by; wc.width = w; wc.height = bh; ++ wc.stack_mode = Above; wc.sibling = m->barwin; ++ XConfigureWindow(dpy, systray->win, CWX|CWY|CWWidth|CWHeight|CWSibling|CWStackMode, &wc); ++ XMapWindow(dpy, systray->win); ++ XMapSubwindows(dpy, systray->win); ++ /* redraw background */ ++ XSetForeground(dpy, drw->gc, scheme[SchemeNorm][ColBg].pixel); ++ XFillRectangle(dpy, systray->win, drw->gc, 0, 0, w, bh); ++ XSync(dpy, False); ++} ++ ++void + updatewindowtype(Client *c) + { + Atom state = getatomprop(c, netatom[NetWMState]); +@@ -2069,6 +2397,16 @@ wintomon(Window w) + return selmon; + } + ++Client * ++wintosystrayicon(Window w) { ++ Client *i = NULL; ++ ++ if (!showsystray || !w) ++ return i; ++ for (i = systray->icons; i && i->win != w; i = i->next); ++ return i; ++} ++ + /* There's no way to check accesses to destroyed windows, thus those cases are + * ignored (especially on UnmapNotify's). Other types of errors call Xlibs + * default error handler, which may call exit. */ diff --git a/dwm.suckless.org/patches/dwm-tagall-20160731-56a31dc.diff b/dwm.suckless.org/patches/dwm-tagall-20160731-56a31dc.diff @@ -0,0 +1,33 @@ +Author: Jan Christoph Ebersbach <jceb@e-jc.de> +URL: http://dwm.suckless.org/patches/historical/tagall +Shortcut to move all (floating) windows from one tag to another. + +Index: dwm/tagall.c +=================================================================== +--- /dev/null ++++ dwm/tagall.c +@@ -0,0 +1,24 @@ ++void ++tagall(const Arg *arg) { ++ if (!selmon->clients) ++ return; ++ /* if parameter starts with F, just move floating windows */ ++ int floating_only = (char *)arg->v && ((char *)arg->v)[0] == 'F' ? 1 : 0; ++ int tag = (char *)arg->v ? atoi(((char *)arg->v) + floating_only) : 0; ++ int j; ++ Client* c; ++ if(tag >= 0 && tag < LENGTH(tags)) ++ for(c = selmon->clients; c; c = c->next) ++ { ++ if(!floating_only || c->isfloating) ++ for(j = 0; j < LENGTH(tags); j++) ++ { ++ if(c->tags & 1 << j && selmon->tagset[selmon->seltags] & 1 << j) ++ { ++ c->tags = c->tags ^ (1 << j & TAGMASK); ++ c->tags = c->tags | 1 << (tag-1); ++ } ++ } ++ } ++ arrange(selmon); ++} diff --git a/dwm.suckless.org/patches/dwm-6.0-tagall.diff b/dwm.suckless.org/patches/dwm-tagall-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-6.1-tagall.diff b/dwm.suckless.org/patches/dwm-tagall-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-6.0-tilegap.diff b/dwm.suckless.org/patches/dwm-tilegap-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-5.9-uselessgap.diff b/dwm.suckless.org/patches/dwm-uselessgap-5.9.diff diff --git a/dwm.suckless.org/patches/dwm-6.1-uselessgap.diff b/dwm.suckless.org/patches/dwm-uselessgap-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-5.9-warp.diff b/dwm.suckless.org/patches/dwm-warp-5.9.diff diff --git a/dwm.suckless.org/patches/dwm-6.1-warp.diff b/dwm.suckless.org/patches/dwm-warp-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-warp-git-20160626-7af4d43.diff b/dwm.suckless.org/patches/dwm-warp-git-20160626-7af4d43.diff @@ -0,0 +1,58 @@ +diff --git a/dwm.c b/dwm.c +index b2bc9bd..0329e1f 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -228,6 +228,7 @@ static void updatewindowtype(Client *c); + static void updatetitle(Client *c); + static void updatewmhints(Client *c); + static void view(const Arg *arg); ++static void warp(const Client *c); + static Client *wintoclient(Window w); + static Monitor *wintomon(Window w); + static int xerror(Display *dpy, XErrorEvent *ee); +@@ -842,6 +843,7 @@ focusmon(const Arg *arg) + in gedit and anjuta */ + selmon = m; + focus(NULL); ++ warp(selmon->sel); + } + + void +@@ -1387,6 +1389,8 @@ restack(Monitor *m) + } + XSync(dpy, False); + while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); ++ if (m == selmon && (m->tagset[m->seltags] & m->sel->tags) && selmon->lt[selmon->sellt] != &layouts[2]) ++ warp(m->sel); + } + + void +@@ -2039,6 +2043,28 @@ view(const Arg *arg) + arrange(selmon); + } + ++void ++warp(const Client *c) ++{ ++ int x, y; ++ ++ if (!c) { ++ XWarpPointer(dpy, None, root, 0, 0, 0, 0, selmon->wx + selmon->ww/2, selmon->wy + selmon->wh/2); ++ return; ++ } ++ ++ if (!getrootptr(&x, &y) || ++ (x > c->x - c->bw && ++ y > c->y - c->bw && ++ x < c->x + c->w + c->bw*2 && ++ y < c->y + c->h + c->bw*2) || ++ (y > c->mon->by && y < c->mon->by + bh) || ++ (c->mon->topbar && !y)) ++ return; ++ ++ XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); ++} ++ + Client * + wintoclient(Window w) + { diff --git a/dwm.suckless.org/patches/dwm-zoomswap-20160731-56a31dc.diff b/dwm.suckless.org/patches/dwm-zoomswap-20160731-56a31dc.diff @@ -0,0 +1,86 @@ +Author: Jan Christoph Ebersbach <jceb@e-jc.de> +URL: http://dwm.suckless.org/patches/zoomswap +This patch swaps the current window with the previous master when zooming. + +Index: dwm/dwm.c +=================================================================== +--- dwm/dwm.c.orig ++++ dwm/dwm.c +@@ -236,6 +236,7 @@ static int xerrorstart(Display *dpy, XEr + static void zoom(const Arg *arg); + + /* variables */ ++static Client *prevzoom = NULL; + static const char broken[] = "broken"; + static char stext[256]; + static int screen; +@@ -2109,14 +2110,38 @@ void + zoom(const Arg *arg) + { + Client *c = selmon->sel; ++ Client *at = NULL, *cold, *cprevious = NULL; + + if (!selmon->lt[selmon->sellt]->arrange + || (selmon->sel && selmon->sel->isfloating)) + return; +- if (c == nexttiled(selmon->clients)) +- if (!c || !(c = nexttiled(c->next))) +- return; +- pop(c); ++ if (c == nexttiled(selmon->clients)) { ++ at = findbefore(prevzoom); ++ if (at) ++ cprevious = nexttiled(at->next); ++ if (!cprevious || cprevious != prevzoom) { ++ prevzoom = NULL; ++ if(!c || !(c = nexttiled(c->next))) ++ return; ++ } else ++ c = cprevious; ++ } ++ cold = nexttiled(selmon->clients); ++ if (c != cold && !at) ++ at = findbefore(c); ++ detach(c); ++ attach(c); ++ /* swap windows instead of pushing the previous one down */ ++ if (c != cold && at) { ++ prevzoom = cold; ++ if(cold && at != cold) { ++ detach(cold); ++ cold->next = at->next; ++ at->next = cold; ++ } ++ } ++ focus(c); ++ arrange(c->mon); + } + + int +Index: dwm/zoomswap.c +=================================================================== +--- /dev/null ++++ dwm/zoomswap.c +@@ -0,0 +1,10 @@ ++static Client * findbefore(Client *c); ++ ++Client * ++findbefore(Client *c) { ++ Client *tmp; ++ if(c == selmon->clients) ++ return NULL; ++ for(tmp = selmon->clients; tmp && tmp->next != c; tmp = tmp->next) ; ++ return tmp; ++} +Index: dwm/config.def.h +=================================================================== +--- dwm/config.def.h.orig ++++ dwm/config.def.h +@@ -59,6 +59,7 @@ static char dmenumon[2] = "0"; /* compon + static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; + static const char *termcmd[] = { "st", NULL }; + ++#include "zoomswap.c" + static Key keys[] = { + /* modifier key function argument */ + { MODKEY, XK_p, spawn, {.v = dmenucmd } }, diff --git a/dwm.suckless.org/patches/dwm-6.0-zoomswap.diff b/dwm.suckless.org/patches/dwm-zoomswap-6.0.diff diff --git a/dwm.suckless.org/patches/dwmfifo.md b/dwm.suckless.org/patches/dwmfifo.md @@ -30,7 +30,7 @@ that you may want to execute (like tabbed-surf or similar). Download -------- - * [dwm-6.1-dwmfifo.diff](dwm-6.1-dwmfifo.diff) (6.9k) (29.01.2014) + * [dwm-dwmfifo-6.1.diff](dwm-dwmfifo-6.1.diff) (6.9k) (29.01.2014) Author ------ diff --git a/dwm.suckless.org/patches/emptyview.md b/dwm.suckless.org/patches/emptyview.md @@ -10,7 +10,7 @@ With this patch, dwm will start with no tag selected. When you start a client wi Download -------- - * [dwm-6.0-emptyview.diff](dwm-6.0-emptyview.diff) (1753b) (20130330) + * [dwm-emptyview-6.0.diff](dwm-emptyview-6.0.diff) (1753b) (20130330) Authors ------- diff --git a/dwm.suckless.org/patches/exresize.md b/dwm.suckless.org/patches/exresize.md @@ -15,8 +15,10 @@ description. Download -------- - - * [dwm-r1606-exresize.diff](dwm-r1606-exresize.diff) (20121117) + +<!-- This patch used to say (20121117), but it doesn't build against commits + from that date. Author emailed. --> + * [dwm-r1606-exresize.diff](dwm-r1606-exresize.diff) (Old patch, unknown version) Authors ------- diff --git a/dwm.suckless.org/patches/fancybar.md b/dwm.suckless.org/patches/fancybar.md @@ -12,13 +12,14 @@ fit, they're cropped. The title of the selected window is inverted. ## Download - * [fancybar-5.6.1.diff](historical/fancybar-5.6.1.diff) (dwm 5.6.1) (20090824) - * [dwm-6.1-fancybar.diff](dwm-6.1-fancybar.diff) (20151109) + * [dwm-fancybar-5.6.1.diff](historical/dwm-fancybar-5.6.1.diff) + * [dwm-fancybar-6.1.diff](dwm-fancybar-6.1.diff) + * [dwm-fancybar-git-20160725-7af4d43.diff](dwm-fancybar-git-20160725-7af4d43.diff) ## Author * Mate Nagy - <mnagy@port70.net> - * Jochen Sprickerhof - project @ firstname . lastname . de + * [Jochen Sprickerhof](mailto:project@firstname.lastname.de) (rewrite) This patch was inspired by the decorated tabbed layout of Xmonad. diff --git a/dwm.suckless.org/patches/fancybarclickable.md b/dwm.suckless.org/patches/fancybarclickable.md @@ -12,7 +12,7 @@ selecting their title in the dwm bar. Download -------- -* [dwm-6.1-fancybarclickable.diff](dwm-6.1-fancybarclickable.diff) +* [dwm-6.1-fancybarclickable.diff](dwm-6.1-fancybarclickable.diff) (Unclean patch) Authors ------- diff --git a/dwm.suckless.org/patches/fibonacci.md b/dwm.suckless.org/patches/fibonacci.md @@ -36,7 +36,7 @@ arrangement can be seen below. ## Download - * [dwm-5.8.2-fibonacci.diff](dwm-5.8.2-fibonacci.diff) + * [dwm-fibonacci-5.8.2.diff](dwm-fibonacci-5.8.2.diff) ## Maintainer diff --git a/dwm.suckless.org/patches/flextile.md b/dwm.suckless.org/patches/flextile.md @@ -57,10 +57,16 @@ The original `tile` layout is only available by setting the above parameters, bu ## Download ## - * [flextile-5.8.2.diff][5.8.2] (13k, +164 SLOC) (20100611, joten (at) freenet (dot) de) updated by Pascal Wittmann `<mail at pascal-wittmann dot de>` - * [flextile-5.8.1.diff][5.8.1] (14k) (20100531, joten (at) freenet (dot) de) + * [dwm-flextile-5.8.2.diff][5.8.2] + * [dwm-flextile-5.8.1.diff][5.8.1] -[5.8.2]: flextile-5.8.2.diff -[5.8.1]: historical/flextile-5.8.1.diff +[5.8.2]: dwm-flextile-5.8.2.diff +[5.8.1]: historical/dwm-flextile-5.8.1.diff + +## Authors ## + +joten (at) freenet (dot) de + +mail at pascal-wittmann dot de diff --git a/dwm.suckless.org/patches/float_border_color.md b/dwm.suckless.org/patches/float_border_color.md @@ -7,9 +7,10 @@ This patch allows you to specify a different border color for floating windows. Patches against different versions of dwm are available at [dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). - * [dwm-6.1-float_border_color2.diff](dwm-6.1-float_border_color2.diff) (3594b) (20140209) - * [dwm-10e232f9ace7-float_border_color2.diff](dwm-10e232f9ace7-float_border_color2.diff) (3432b) (20120406) - * [dwm-6.0-float_border_color2.diff](dwm-6.0-float_border_color2.diff) (3356b) (20120406) +<!-- Author emailed about this patch not applying cleanly --> + * [dwm-float_border_color2-20160731-56a31dc.diff](dwm-float_border_color2-20160731-56a31dc.diff) + * [dwm-float_border_color-6.1.diff](dwm-float_border_color-6.1.diff) (Unclean patch) + * [dwm-float_border_color-6.0.diff](dwm-float_border_color-6.0.diff) ## Author ## * Message-ID: <20070626093131.GA5005@shota.mine.nu> diff --git a/dwm.suckless.org/patches/focusadjacenttag.md b/dwm.suckless.org/patches/focusadjacenttag.md @@ -21,8 +21,9 @@ Default key bindings Download -------- - * [dwm-6.0-focusadjacenttag.diff](dwm-6.0-focusadjacenttag.diff) (3740b) (20140624) +<!-- Author emailed about this issue already --> + * [dwm-6.0-focusadjacenttag.diff](dwm-6.0-focusadjacenttag.diff) (Unclean patch) Authors ------- - * Fabio Banfi - `<fbanfi90 at gmail dot com>`- \ No newline at end of file + * Fabio Banfi - `<fbanfi90 at gmail dot com>` diff --git a/dwm.suckless.org/patches/focusonclick.md b/dwm.suckless.org/patches/focusonclick.md @@ -6,9 +6,8 @@ ## Download - * [dwm-6.0-focusonclick.diff](dwm-6.0-focusonclick.diff) (2012-11-24) + * [dwm-focusonclick-6.0.diff](dwm-focusonclick-6.0.diff) (2012-11-24) * [dwm-git-20100321-focusonclick.diff](historical/dwm-git-20100321-focusonclick.diff) - * [dwm-5.8.2-focusonclick.diff](historical/dwm-5.8.2-focusonclick.diff) (dwm 2010604) ## Author diff --git a/dwm.suckless.org/patches/gapless_grid.md b/dwm.suckless.org/patches/gapless_grid.md @@ -26,7 +26,8 @@ Download `gaplessgrid.c` and add the gapless layout to your `config.h`: ## Download -* [dwm-6.1-gaplessgrid.diff](dwm-6.1-gaplessgrid.diff) (1180b) (20140209) +* [dwm-gaplessgrid-20160731-56a31dc.diff](dwm-gaplessgrid-20160731-56a31dc.diff) +* [dwm-gaplessgrid-6.1.diff](dwm-gaplessgrid-6.1.diff) (1180b) (20140209) * [gaplessgrid.c](gaplessgrid.c) (dwm 5.6.1) (20090908) * [dwm-r1437-gaplessgrid.diff](historical/dwm-r1437-gaplessgrid.diff) (1.9k) (20090704) * [dwm-5.2-gaplessgrid.diff](historical/dwm-5.2-gaplessgrid.diff) (1.9k) (20081020) diff --git a/dwm.suckless.org/patches/gaps.md b/dwm.suckless.org/patches/gaps.md @@ -17,7 +17,7 @@ There is a variation of the patch for the [xtile](xtile) layout also. Download -------- -* For vanilla tile: [dwm-6.0-gaps.diff](dwm-6.0-gaps.diff) +* For vanilla tile: [dwm-gaps-6.0.diff](dwm-gaps-6.0.diff) * For xtile tile: [dwm-6.0-xtile-gaps.diff](dwm-6.0-xtile-gaps.diff) diff --git a/dwm.suckless.org/patches/gestures.md b/dwm.suckless.org/patches/gestures.md @@ -8,8 +8,9 @@ and adds a gestures array to config.h. A gesture can call any dwm function. I us Download -------- -* [dwm-5.8-gestures.diff](dwm-5.8-gestures.diff) +<!-- Author email bounced (removed it), patch needs fixed --> +* [dwm-5.8-gestures.diff](dwm-5.8-gestures.diff) (Unclean patch) Author ------ -* David Galos - <galosd83@students.rowan.edu> +* David Galos diff --git a/dwm.suckless.org/patches/gridmode.md b/dwm.suckless.org/patches/gridmode.md @@ -9,7 +9,7 @@ tools that operate on multiple windows at once; e.g. Cluster SSH. Download -------- -* [dwm-5.8.2-gridmode.diff](dwm-5.8.2-gridmode.diff) +* [dwm-gridmode-5.8.2.diff](dwm-gridmode-5.8.2.diff) * See older versions in [historical](historical/gridmode). Authors diff --git a/dwm.suckless.org/patches/hide_vacant_tags.md b/dwm.suckless.org/patches/hide_vacant_tags.md @@ -18,10 +18,12 @@ filled/empty rectangles. Download -------- -* [dwm-6.1-hide_vacant_tags.diff](dwm-6.1-hide_vacant_tags.diff) - 2016-01-22 +* [dwm-hide_vacant_tags-6.1.diff](dwm-hide_vacant_tags-6.1.diff) - 2016-01-22 +* [dwm-hide_vacant_tags-git-20160626-7af4d43.diff](dwm-hide_vacant_tags-git-20160626-7af4d43.diff) Author ------ * [Ondřej Grover](mailto:ondrej.grover@gmail.com) * Matthew Boswell - mordervomubel+suckless at lockmail dot us (mechanical update for dwm 6.1 release) +* [Jochen Sprickerhof](mailto:project@firstname.lastname.de) (hide 0 tagged clients) diff --git a/dwm.suckless.org/patches/ansistatuscolors.md b/dwm.suckless.org/patches/historical/ansistatuscolors.md diff --git a/dwm.suckless.org/patches/ansistatuscolors.png b/dwm.suckless.org/patches/historical/ansistatuscolors.png Binary files differ. diff --git a/dwm.suckless.org/patches/autoresize.diff b/dwm.suckless.org/patches/historical/autoresize.diff diff --git a/dwm.suckless.org/patches/historical/dwm-5.6.1-attachabove.diff b/dwm.suckless.org/patches/historical/dwm-5.6.1-attachabove.diff @@ -1,40 +0,0 @@ -diff -r e47a47bd3ed4 dwm.c ---- a/dwm.c Tue Jul 21 10:57:54 2009 +0100 -+++ b/dwm.c Mon Aug 17 15:03:36 2009 +0200 -@@ -153,6 +153,7 @@ - static Bool applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool interact); - static void arrange(void); - static void attach(Client *c); -+static void attachabove(Client *c); - static void attachstack(Client *c); - static void buttonpress(XEvent *e); - static void checkotherwm(void); -@@ -394,6 +395,19 @@ - attach(Client *c) { - c->next = c->mon->clients; - c->mon->clients = c; -+} -+ -+void -+attachabove(Client *c) { -+ if(c->mon->sel == NULL || c->mon->sel == c->mon->clients || c->mon->sel->isfloating) { -+ attach(c); -+ return; -+ } -+ -+ Client *at; -+ for (at = c->mon->clients; at->next != c->mon->sel; at = at->next); -+ c->next = at->next; -+ at->next = c; - } - - void -@@ -1098,7 +1112,7 @@ - c->isfloating = trans != None || c->isfixed; - if(c->isfloating) - XRaiseWindow(dpy, c->win); -- attach(c); -+ attachabove(c); - attachstack(c); - XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */ - XMapWindow(dpy, c->win); diff --git a/dwm.suckless.org/patches/historical/dwm-5.6.1-attachaside.diff b/dwm.suckless.org/patches/historical/dwm-5.6.1-attachaside.diff @@ -1,38 +0,0 @@ -diff -r 9f79d36bd5e0 dwm.c ---- a/dwm.c Tue Sep 08 13:33:58 2009 +0100 -+++ b/dwm.c Tue Sep 15 14:19:26 2009 +0200 -@@ -153,6 +153,7 @@ - static Bool applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool interact); - static void arrange(void); - static void attach(Client *c); -+static void attachaside(Client *c); - static void attachstack(Client *c); - static void buttonpress(XEvent *e); - static void checkotherwm(void); -@@ -397,6 +398,17 @@ - } - - void -+attachaside(Client *c) { -+ Client *at = nexttiled(c->mon->clients);; -+ if(c->mon->sel == NULL || c->mon->sel->isfloating || !at) { -+ attach(c); -+ return; -+ } -+ c->next = at->next; -+ at->next = c; -+} -+ -+void - attachstack(Client *c) { - c->snext = c->mon->stack; - c->mon->stack = c; -@@ -1105,7 +1117,7 @@ - c->isfloating = trans != None || c->isfixed; - if(c->isfloating) - XRaiseWindow(dpy, c->win); -- attach(c); -+ attachaside(c); - attachstack(c); - XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */ - XMapWindow(dpy, c->win); diff --git a/dwm.suckless.org/patches/historical/dwm-5.7.2-attachaside.diff b/dwm.suckless.org/patches/historical/dwm-5.7.2-attachaside.diff @@ -1,38 +0,0 @@ -diff -r 9f79d36bd5e0 dwm.c ---- a/dwm.c Tue Sep 08 13:33:58 2009 +0100 -+++ b/dwm.c Tue Sep 15 14:19:26 2009 +0200 -@@ -153,6 +153,7 @@ - static Bool applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool interact); - static void arrange(void); - static void attach(Client *c); -+static void attachaside(Client *c); - static void attachstack(Client *c); - static void buttonpress(XEvent *e); - static void checkotherwm(void); -@@ -397,6 +398,17 @@ - } - - void -+attachaside(Client *c) { -+ Client *at = nexttiled(c->mon->clients);; -+ if(c->mon->sel == NULL || c->mon->sel->isfloating || !at) { -+ attach(c); -+ return; -+ } -+ c->next = at->next; -+ at->next = c; -+} -+ -+void - attachstack(Client *c) { - c->snext = c->mon->stack; - c->mon->stack = c; -@@ -1105,7 +1117,7 @@ - c->isfloating = trans != None || c->isfixed; - if(c->isfloating) - XRaiseWindow(dpy, c->win); -- attach(c); -+ attachaside(c); - attachstack(c); - XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */ - XMapWindow(dpy, c->win); diff --git a/dwm.suckless.org/patches/historical/dwm-5.8.2-bstack-alt.diff b/dwm.suckless.org/patches/historical/dwm-5.8.2-bstack-alt.diff @@ -1,93 +0,0 @@ -diff -up dwm-5.8.2-original/config.def.h dwm-5.8.2/config.def.h ---- dwm-5.8.2-original/config.def.h 2010-06-04 06:39:15.000000000 -0400 -+++ dwm-5.8.2/config.def.h 2010-07-07 14:56:15.000000000 -0400 -@@ -31,6 +31,8 @@ static const Layout layouts[] = { - { "[]=", tile }, /* first entry is default */ - { "><>", NULL }, /* no layout function means floating behavior */ - { "[M]", monocle }, -+ { "TTT", bstack }, -+ { "===", bstackhoriz }, - }; - - /* key definitions */ -diff -up dwm-5.8.2-original/dwm.c dwm-5.8.2/dwm.c ---- dwm-5.8.2-original/dwm.c 2010-06-04 06:39:15.000000000 -0400 -+++ dwm-5.8.2/dwm.c 2010-07-07 15:03:16.000000000 -0400 -@@ -158,6 +158,8 @@ static void arrange(Monitor *m); - static void arrangemon(Monitor *m); - static void attach(Client *c); - static void attachstack(Client *c); -+static void bstack(Monitor *m); -+static void bstackhoriz(Monitor *m); - static void buttonpress(XEvent *e); - static void checkotherwm(void); - static void cleanup(void); -@@ -1657,6 +1659,67 @@ tile(Monitor *m) { - if(h < bh) - h = m->wh; - for(i = 0, c = nexttiled(c->next); c; c = nexttiled(c->next), i++) { -+ resize(c, x, y, w - 2 * c->bw, /* remainder */ ((i + 1 == n) -+ ? m->wy + m->wh - y - 2 * c->bw : h - 2 * c->bw), False); -+ if(h != m->wh) -+ y = c->y + HEIGHT(c); -+ } -+} -+ -+static void -+bstack(Monitor *m) { -+ int x, y, h, w, mh; -+ unsigned int i, n; -+ Client *c; -+ -+ for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); -+ if(n == 0) -+ return; -+ /* master */ -+ c = nexttiled(m->clients); -+ mh = m->mfact * m->wh; -+ resize(c, m->wx, m->wy, m->ww - 2 * c->bw, (n == 1 ? m->wh : mh) - 2 * c->bw, False); -+ if(--n == 0) -+ return; -+ /* tile stack */ -+ x = m->wx; -+ y = (m->wy + mh > c->y + c->h) ? c->y + c->h + 2 * c->bw : m->wy + mh; -+ w = m->ww / n; -+ h = (m->wy + mh > c->y + c->h) ? m->wy + m->wh - y : m->wh - mh; -+ if(w < bh) -+ w = m->ww; -+ for(i = 0, c = nexttiled(c->next); c; c = nexttiled(c->next), i++) { -+ resize(c, x, y, /* remainder */ ((i + 1 == n) -+ ? m->wx + m->ww - x - 2 * c->bw : w - 2 * c->bw), h - 2 * c->bw, False); -+ if(w != m->ww) -+ x = c->x + WIDTH(c); -+ } -+} -+ -+static void -+bstackhoriz(Monitor *m) { -+ int x, y, h, w, mh; -+ unsigned int i, n; -+ Client *c; -+ -+ for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); -+ if(n == 0) -+ return; -+ /* master */ -+ c = nexttiled(m->clients); -+ mh = m->mfact * m->wh; -+ resize(c, m->wx, m->wy, m->ww - 2 * c->bw, (n == 1 ? m->wh : mh) - 2 * c->bw, False); -+ if(--n == 0) -+ return; -+ /* tile stack */ -+ x = m->wx; -+ y = (m->wy + mh > c->y + c->h) ? c->y + c->h + 2 * c->bw : m->wy + mh; -+ w = m->ww; -+ h = (m->wy + mh > c->y + c->h) ? m->wy + m->wh - y : m->wh - mh; -+ h /= n; -+ if(h < bh) -+ h = m->wh; -+ for(i = 0, c = nexttiled(c->next); c; c = nexttiled(c->next), i++) { - resize(c, x, y, w - 2 * c->bw, /* remainder */ ((i + 1 == n) - ? m->wy + m->wh - y - 2 * c->bw : h - 2 * c->bw), False); - if(h != m->wh) - diff --git a/dwm.suckless.org/patches/historical/dwm-5.8.2-bstack.diff b/dwm.suckless.org/patches/historical/dwm-5.8.2-bstack.diff @@ -1,82 +0,0 @@ -diff -NU5 -r dwm-5.8.2/bstack.c dwm-5.8.2-bstack/bstack.c ---- dwm-5.8.2/bstack.c 1970-01-01 01:00:00.000000000 +0100 -+++ dwm-5.8.2-bstack/bstack.c 2010-06-15 17:47:44.000000000 +0200 -@@ -0,0 +1,29 @@ -+static void -+bstack(Monitor *m) { -+ int x, y, h, w, mh; -+ unsigned int i, n; -+ Client *c; -+ -+ for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); -+ if(n == 0) -+ return; -+ /* master */ -+ c = nexttiled(m->clients); -+ mh = m->mfact * m->wh; -+ resize(c, m->wx, m->wy, m->ww - 2 * c->bw, (n == 1 ? m->wh : mh) - 2 * c->bw, False); -+ if(--n == 0) -+ return; -+ /* tile stack */ -+ x = m->wx; -+ y = (m->wy + mh > c->y + c->h) ? c->y + c->h + 2 * c->bw : m->wy + mh; -+ w = m->ww / n; -+ h = (m->wy + mh > c->y + c->h) ? m->wy + m->wh - y : m->wh - mh; -+ if(w < bh) -+ w = m->ww; -+ for(i = 0, c = nexttiled(c->next); c; c = nexttiled(c->next), i++) { -+ resize(c, x, y, /* remainder */ ((i + 1 == n) -+ ? m->wx + m->ww - x - 2 * c->bw : w - 2 * c->bw), h - 2 * c->bw, False); -+ if(w != m->ww) -+ x = c->x + WIDTH(c); -+ } -+} -diff -NU5 -r dwm-5.8.2/bstackhoriz.c dwm-5.8.2-bstack/bstackhoriz.c ---- dwm-5.8.2/bstackhoriz.c 1970-01-01 01:00:00.000000000 +0100 -+++ dwm-5.8.2-bstack/bstackhoriz.c 2010-06-15 17:47:44.000000000 +0200 -@@ -0,0 +1,30 @@ -+static void -+bstackhoriz(Monitor *m) { -+ int x, y, h, w, mh; -+ unsigned int i, n; -+ Client *c; -+ -+ for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); -+ if(n == 0) -+ return; -+ /* master */ -+ c = nexttiled(m->clients); -+ mh = m->mfact * m->wh; -+ resize(c, m->wx, m->wy, m->ww - 2 * c->bw, (n == 1 ? m->wh : mh) - 2 * c->bw, False); -+ if(--n == 0) -+ return; -+ /* tile stack */ -+ x = m->wx; -+ y = (m->wy + mh > c->y + c->h) ? c->y + c->h + 2 * c->bw : m->wy + mh; -+ w = m->ww; -+ h = (m->wy + mh > c->y + c->h) ? m->wy + m->wh - y : m->wh - mh; -+ h /= n; -+ if(h < bh) -+ h = m->wh; -+ for(i = 0, c = nexttiled(c->next); c; c = nexttiled(c->next), i++) { -+ resize(c, x, y, w - 2 * c->bw, /* remainder */ ((i + 1 == n) -+ ? m->wy + m->wh - y - 2 * c->bw : h - 2 * c->bw), False); -+ if(h != m->wh) -+ y = c->y + HEIGHT(c); -+ } -+} -diff -NU5 -r dwm-5.8.2/config.def.h dwm-5.8.2-bstack/config.def.h ---- dwm-5.8.2/config.def.h 2010-06-04 12:39:15.000000000 +0200 -+++ dwm-5.8.2-bstack/config.def.h 2010-06-15 17:47:44.000000000 +0200 -@@ -29,1 +29,3 @@ -+#include "bstack.c" -+#include "bstackhoriz.c" - static const Layout layouts[] = { -@@ -34,5 +36,7 @@ -+ { "TTT", bstack }, -+ { "===", bstackhoriz }, - }; - - /* key definitions */ - #define MODKEY Mod1Mask - #define TAGKEYS(KEY,TAG) \ diff --git a/dwm.suckless.org/patches/historical/dwm-5.9-bstack-alt.diff b/dwm.suckless.org/patches/historical/dwm-5.9-bstack-alt.diff @@ -1,98 +0,0 @@ -diff -up dwm-5.8.2-original/config.def.h dwm-5.8.2/config.def.h ---- dwm-5.8.2-original/config.def.h 2010-06-04 06:39:15.000000000 -0400 -+++ dwm-5.8.2/config.def.h 2010-07-07 14:56:15.000000000 -0400 -@@ -31,6 +31,8 @@ static const Layout layouts[] = { - /* symbol arrange function */ - { "[]=", tile }, /* first entry is default */ - { "><>", NULL }, /* no layout function means floating behavior */ - { "[M]", monocle }, -+ { "TTT", bstack }, -+ { "===", bstackhoriz }, - }; - - /* key definitions */ - #define MODKEY Mod1Mask - #define TAGKEYS(KEY,TAG) \ - }; - -diff -up dwm-5.8.2-original/dwm.c dwm-5.8.2/dwm.c ---- dwm-5.8.2-original/dwm.c 2010-06-04 06:39:15.000000000 -0400 -+++ dwm-5.8.2/dwm.c 2010-07-07 15:03:16.000000000 -0400 -@@ -158,6 +158,8 @@ static void arrange(Monitor *m); - static void arrangemon(Monitor *m); - static void attach(Client *c); - static void attachstack(Client *c); -+static void bstack(Monitor *m); -+static void bstackhoriz(Monitor *m); - static void buttonpress(XEvent *e); - static void checkotherwm(void); - static void cleanup(void); -@@ -1657,6 +1659,67 @@ tile(Monitor *m) { - if(h < bh) - h = m->wh; - for(i = 0, c = nexttiled(c->next); c; c = nexttiled(c->next), i++) { -+ resize(c, x, y, w - 2 * c->bw, /* remainder */ ((i + 1 == n) -+ ? m->wy + m->wh - y - 2 * c->bw : h - 2 * c->bw), False); -+ if(h != m->wh) -+ y = c->y + HEIGHT(c); -+ } -+} -+ -+static void -+bstack(Monitor *m) { -+ int x, y, h, w, mh; -+ unsigned int i, n; -+ Client *c; -+ -+ for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); -+ if(n == 0) -+ return; -+ /* master */ -+ c = nexttiled(m->clients); -+ mh = m->mfact * m->wh; -+ resize(c, m->wx, m->wy, m->ww - 2 * c->bw, (n == 1 ? m->wh : mh) - 2 * c->bw, False); -+ if(--n == 0) -+ return; -+ /* tile stack */ -+ x = m->wx; -+ y = (m->wy + mh > c->y + c->h) ? c->y + c->h + 2 * c->bw : m->wy + mh; -+ w = m->ww / n; -+ h = (m->wy + mh > c->y + c->h) ? m->wy + m->wh - y : m->wh - mh; -+ if(w < bh) -+ w = m->ww; -+ for(i = 0, c = nexttiled(c->next); c; c = nexttiled(c->next), i++) { -+ resize(c, x, y, /* remainder */ ((i + 1 == n) -+ ? m->wx + m->ww - x - 2 * c->bw : w - 2 * c->bw), h - 2 * c->bw, False); -+ if(w != m->ww) -+ x = c->x + WIDTH(c); -+ } -+} -+ -+static void -+bstackhoriz(Monitor *m) { -+ int x, y, h, w, mh; -+ unsigned int i, n; -+ Client *c; -+ -+ for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); -+ if(n == 0) -+ return; -+ /* master */ -+ c = nexttiled(m->clients); -+ mh = m->mfact * m->wh; -+ resize(c, m->wx, m->wy, m->ww - 2 * c->bw, (n == 1 ? m->wh : mh) - 2 * c->bw, False); -+ if(--n == 0) -+ return; -+ /* tile stack */ -+ x = m->wx; -+ y = (m->wy + mh > c->y + c->h) ? c->y + c->h + 2 * c->bw : m->wy + mh; -+ w = m->ww; -+ h = (m->wy + mh > c->y + c->h) ? m->wy + m->wh - y : m->wh - mh; -+ h /= n; -+ if(h < bh) -+ h = m->wh; -+ for(i = 0, c = nexttiled(c->next); c; c = nexttiled(c->next), i++) { - resize(c, x, y, w - 2 * c->bw, /* remainder */ ((i + 1 == n) - ? m->wy + m->wh - y - 2 * c->bw : h - 2 * c->bw), False); - if(h != m->wh) - diff --git a/dwm.suckless.org/patches/historical/dwm-5.9-bstack.diff b/dwm.suckless.org/patches/historical/dwm-5.9-bstack.diff @@ -1,87 +0,0 @@ -diff -NU5 -r dwm-5.8.2/bstack.c dwm-5.8.2-bstack/bstack.c ---- dwm-5.8.2/bstack.c 1970-01-01 01:00:00.000000000 +0100 -+++ dwm-5.8.2-bstack/bstack.c 2010-06-15 17:47:44.000000000 +0200 -@@ -0,0 +1,29 @@ -+static void -+bstack(Monitor *m) { -+ int x, y, h, w, mh; -+ unsigned int i, n; -+ Client *c; -+ -+ for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); -+ if(n == 0) -+ return; -+ /* master */ -+ c = nexttiled(m->clients); -+ mh = m->mfact * m->wh; -+ resize(c, m->wx, m->wy, m->ww - 2 * c->bw, (n == 1 ? m->wh : mh) - 2 * c->bw, False); -+ if(--n == 0) -+ return; -+ /* tile stack */ -+ x = m->wx; -+ y = (m->wy + mh > c->y + c->h) ? c->y + c->h + 2 * c->bw : m->wy + mh; -+ w = m->ww / n; -+ h = (m->wy + mh > c->y + c->h) ? m->wy + m->wh - y : m->wh - mh; -+ if(w < bh) -+ w = m->ww; -+ for(i = 0, c = nexttiled(c->next); c; c = nexttiled(c->next), i++) { -+ resize(c, x, y, /* remainder */ ((i + 1 == n) -+ ? m->wx + m->ww - x - 2 * c->bw : w - 2 * c->bw), h - 2 * c->bw, False); -+ if(w != m->ww) -+ x = c->x + WIDTH(c); -+ } -+} -diff -NU5 -r dwm-5.8.2/bstackhoriz.c dwm-5.8.2-bstack/bstackhoriz.c ---- dwm-5.8.2/bstackhoriz.c 1970-01-01 01:00:00.000000000 +0100 -+++ dwm-5.8.2-bstack/bstackhoriz.c 2010-06-15 17:47:44.000000000 +0200 -@@ -0,0 +1,30 @@ -+static void -+bstackhoriz(Monitor *m) { -+ int x, y, h, w, mh; -+ unsigned int i, n; -+ Client *c; -+ -+ for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); -+ if(n == 0) -+ return; -+ /* master */ -+ c = nexttiled(m->clients); -+ mh = m->mfact * m->wh; -+ resize(c, m->wx, m->wy, m->ww - 2 * c->bw, (n == 1 ? m->wh : mh) - 2 * c->bw, False); -+ if(--n == 0) -+ return; -+ /* tile stack */ -+ x = m->wx; -+ y = (m->wy + mh > c->y + c->h) ? c->y + c->h + 2 * c->bw : m->wy + mh; -+ w = m->ww; -+ h = (m->wy + mh > c->y + c->h) ? m->wy + m->wh - y : m->wh - mh; -+ h /= n; -+ if(h < bh) -+ h = m->wh; -+ for(i = 0, c = nexttiled(c->next); c; c = nexttiled(c->next), i++) { -+ resize(c, x, y, w - 2 * c->bw, /* remainder */ ((i + 1 == n) -+ ? m->wy + m->wh - y - 2 * c->bw : h - 2 * c->bw), False); -+ if(h != m->wh) -+ y = c->y + HEIGHT(c); -+ } -+} - -diff -r 23b71491e149 config.def.h ---- a/config.def.h Thu Dec 02 10:16:47 2010 +0000 -+++ b/config.def.h Fri Jan 07 15:10:06 2011 +0100 -@@ -26,11 +26,15 @@ - static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ - static const Bool resizehints = True; /* True means respect size hints in tiled resizals */ - -+#include "bstack.c" -+#include "bstackhoriz.c" - static const Layout layouts[] = { - /* symbol arrange function */ - { "[]=", tile }, /* first entry is default */ - { "><>", NULL }, /* no layout function means floating behavior */ - { "[M]", monocle }, -+ { "TTT", bstack }, -+ { "===", bstackhoriz }, - }; - - /* key definitions */ diff --git a/dwm.suckless.org/patches/historical/dwm-cdec978-center.diff b/dwm.suckless.org/patches/historical/dwm-cdec978-center.diff @@ -1,58 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 875885b..2e3a9fb 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -21,9 +21,9 @@ static const Rule rules[] = { - * WM_CLASS(STRING) = instance, class - * WM_NAME(STRING) = title - */ -- /* class instance title tags mask isfloating monitor */ -- { "Gimp", NULL, NULL, 0, True, -1 }, -- { "Firefox", NULL, NULL, 1 << 8, False, -1 }, -+ /* class instance title tags mask iscentered isfloating monitor */ -+ { "Gimp", NULL, NULL, 0, False, True, -1 }, -+ { "Firefox", NULL, NULL, 1 << 8, False, False, -1 }, - }; - - /* layout(s) */ -diff --git a/dwm.c b/dwm.c -index 1bbb4b3..a8a3356 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -91,7 +91,7 @@ struct Client { - int basew, baseh, incw, inch, maxw, maxh, minw, minh; - int bw, oldbw; - unsigned int tags; -- Bool isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; -+ Bool isfixed, iscentered, isfloating, isurgent, neverfocus, oldstate, isfullscreen; - Client *next; - Client *snext; - Monitor *mon; -@@ -136,6 +136,7 @@ typedef struct { - const char *instance; - const char *title; - unsigned int tags; -+ Bool iscentered; - Bool isfloating; - int monitor; - } Rule; -@@ -294,6 +295,7 @@ applyrules(Client *c) { - && (!r->class || strstr(class, r->class)) - && (!r->instance || strstr(instance, r->instance))) - { -+ c->iscentered = r->iscentered; - c->isfloating = r->isfloating; - c->tags |= r->tags; - for(m = mons; m && m->num != r->monitor; m = m->next); -@@ -1038,6 +1040,11 @@ manage(Window w, XWindowAttributes *wa) { - && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my); - c->bw = borderpx; - -+ if(c->iscentered) { -+ c->x = (c->mon->mw - WIDTH(c)) / 2; -+ c->y = (c->mon->mh - HEIGHT(c)) / 2; -+ } -+ - wc.border_width = c->bw; - XConfigureWindow(dpy, w, CWBorderWidth, &wc); - XSetWindowBorder(dpy, w, scheme[SchemeNorm].border->rgb); diff --git a/dwm.suckless.org/patches/historical/fancybar-5.6.1.diff b/dwm.suckless.org/patches/historical/dwm-fancybar-5.6.1.diff diff --git a/dwm.suckless.org/patches/historical/flextile-5.8.1.diff b/dwm.suckless.org/patches/historical/dwm-flextile-5.8.1.diff diff --git a/dwm.suckless.org/patches/movestack-5.8.2.diff b/dwm.suckless.org/patches/historical/dwm-movestack-5.8.2.diff diff --git a/dwm.suckless.org/patches/historical/dwm-pertag-5.1.diff b/dwm.suckless.org/patches/historical/dwm-pertag-5.1.diff @@ -0,0 +1,125 @@ +diff -NrU3 dwm-5.1/dwm.c dwm-5.1.playground-pertag/dwm.c +--- dwm-5.1/dwm.c 2008-07-29 20:18:32.000000000 +0200 ++++ dwm-5.1-pertag/dwm.c 2008-08-01 18:46:49.000000000 +0200 +@@ -238,6 +238,11 @@ + /* configuration, allows nested code to access above variables */ + #include "config.h" + ++static int curtag = 1, prevtag = 1; ++static Layout *lts[LENGTH(tags) + 1]; ++static double mfacts[LENGTH(tags) + 1]; ++static Bool showbars[LENGTH(tags) + 1]; ++ + /* compile-time check if all tags fit into an unsigned int bit array. */ + struct NumTags { char limitexceeded[sizeof(unsigned int) * 8 < LENGTH(tags) ? -1 : 1]; }; + +@@ -1307,7 +1312,7 @@ + if(!arg || !arg->v || arg->v != lt[sellt]) + sellt ^= 1; + if(arg && arg->v) +- lt[sellt] = (Layout *)arg->v; ++ lt[sellt] = lts[curtag] = (Layout *)arg->v; + if(sel) + arrange(); + else +@@ -1324,7 +1329,7 @@ + f = arg->f < 1.0 ? arg->f + mfact : arg->f - 1.0; + if(f < 0.1 || f > 0.9) + return; +- mfact = f; ++ mfact = mfacts[curtag] = f; + arrange(); + } + +@@ -1373,12 +1378,27 @@ + if(!dc.font.set) + XSetFont(dpy, dc.gc, dc.font.xfont->fid); + ++ /* init mfacts */ ++ for(i=0; i < LENGTH(tags) + 1 ; i++) { ++ mfacts[i] = mfact; ++ } ++ ++ /* init layouts */ ++ for(i=0; i < LENGTH(tags) + 1; i++) { ++ lts[i] = &layouts[0]; ++ } ++ ++ + /* init bar */ + for(blw = i = 0; LENGTH(layouts) > 1 && i < LENGTH(layouts); i++) { + w = TEXTW(layouts[i].symbol); + blw = MAX(blw, w); + } + ++ for(i=0; i < LENGTH(tags) + 1; i++) { ++ showbars[i] = showbar; ++ } ++ + wa.override_redirect = 1; + wa.background_pixmap = ParentRelative; + wa.event_mask = ButtonPressMask|ExposureMask; +@@ -1479,7 +1499,7 @@ + + void + togglebar(const Arg *arg) { +- showbar = !showbar; ++ showbar = showbars[curtag] = !showbar; + updategeom(); + updatebar(); + arrange(); +@@ -1508,9 +1528,23 @@ + void + toggleview(const Arg *arg) { + unsigned int mask = tagset[seltags] ^ (arg->ui & TAGMASK); ++ unsigned int i; + + if(mask) { ++ if(mask == ~0) { ++ prevtag = curtag; ++ curtag = 0; ++ } ++ if(!(mask & 1 << (curtag - 1))) { ++ prevtag = curtag; ++ for (i=0; !(mask & 1 << i); i++); ++ curtag = i + 1; ++ } + tagset[seltags] = mask; ++ lt[sellt] = lts[curtag]; ++ mfact = mfacts[curtag]; ++ if (showbar != showbars[curtag]) ++ togglebar(NULL); + clearurgent(); + arrange(); + } +@@ -1663,11 +1697,29 @@ + + void + view(const Arg *arg) { ++ unsigned int i; ++ + if(arg && (arg->i & TAGMASK) == tagset[seltags]) + return; + seltags ^= 1; /* toggle sel tagset */ +- if(arg && (arg->ui & TAGMASK)) ++ if(arg && (arg->ui & TAGMASK)) { + tagset[seltags] = arg->i & TAGMASK; ++ prevtag = curtag; ++ if(arg->ui == ~0) ++ curtag = 0; ++ else { ++ for (i=0; !(arg->ui & 1 << i); i++); ++ curtag = i + 1; ++ } ++ } else { ++ prevtag= curtag ^ prevtag; ++ curtag^= prevtag; ++ prevtag= curtag ^ prevtag; ++ } ++ lt[sellt]= lts[curtag]; ++ mfact = mfacts[curtag]; ++ if(showbar != showbars[curtag]) ++ togglebar(NULL); + clearurgent(); + arrange(); + } diff --git a/dwm.suckless.org/patches/historical/dwm-5.2-pertag.diff b/dwm.suckless.org/patches/historical/dwm-pertag-5.2.diff diff --git a/dwm.suckless.org/patches/historical/dwm-5.4-pertag.diff b/dwm.suckless.org/patches/historical/dwm-pertag-5.4.diff diff --git a/dwm.suckless.org/patches/historical/dwm-5.7.2-pertag.diff b/dwm.suckless.org/patches/historical/dwm-pertag-5.7.2.diff diff --git a/dwm.suckless.org/patches/historical/dwm-5.8.2-pertag.diff b/dwm.suckless.org/patches/historical/dwm-pertag-5.8.2.diff diff --git a/dwm.suckless.org/patches/multimon-1-added-monitor-marker-to-bar.diff b/dwm.suckless.org/patches/historical/multimon-1-added-monitor-marker-to-bar.diff diff --git a/dwm.suckless.org/patches/multimon-2-added-n-view-wrappers-for-unified-multi-monitor.diff b/dwm.suckless.org/patches/historical/multimon-2-added-n-view-wrappers-for-unified-multi-monitor.diff diff --git a/dwm.suckless.org/patches/multimon-3-added-reset_view-function.diff b/dwm.suckless.org/patches/historical/multimon-3-added-reset_view-function.diff diff --git a/dwm.suckless.org/patches/multimon-4-added-statusall-toggle-replacing-need-for-patch.diff b/dwm.suckless.org/patches/historical/multimon-4-added-statusall-toggle-replacing-need-for-patch.diff diff --git a/dwm.suckless.org/patches/multimon.md b/dwm.suckless.org/patches/historical/multimon.md diff --git a/dwm.suckless.org/patches/horizgrid.md b/dwm.suckless.org/patches/horizgrid.md @@ -29,7 +29,7 @@ Horizontal Grid Layout Download -------- - * [dwm-6.1-horizgrid.diff](dwm-6.1-horizgrid.diff) (20160108) + * [dwm-horizgrid-6.1.diff](dwm-horizgrid-6.1.diff) (20160108) Authors ------- diff --git a/dwm.suckless.org/patches/index.md b/dwm.suckless.org/patches/index.md @@ -1,62 +1,5 @@ -Patches +patches ======= -There are two types of patches: The ones that fit to your personal taste and -the ones you think should be included in mainline dwm. - -For patches that should be included in mainline dwm see the -[community](//suckless.org/community) page and the hackers@ mailing list. - - -You can use the following instructions to generate and apply patches posted on -this wiki. On how to upload patches which fit your personal taste and you want -to show the community, see the [wiki](//suckless.org/wiki) page on how to edit -the pages you see here. - -diff generation ---------------- -For git users: - - cd dwm-directory - git diff > dwm-X.Y-yourpatchname.diff - -For tarballs: - - cd modified-dwm-directory/.. - diff -up original-dwm-directory modified-dwm-directory > dwm-X.Y-yourpatchname.diff - -where `X.Y` is a dwm tag name or version number. - -patch application ------------------ -For git users, use `-3` to fix the conflict easily: - - cd dwm-directory - git apply path/to/patch.diff - -For tarballs: - - cd dwm-directory - patch -p1 < path/to/patch.diff - - -related projects ----------------- -* [awesome](http://awesome.naquadah.org/) -- dwm fork with XCB, EWMH, Lua script, Xft, D-Bus, multihead.. support -* [awm](http://www.freaknet.org/alpt/src/alpt-wm/readme) -- (old) modified dwm with workspaces and /proc like interface -* [bwm](http://lists.suckless.org/dwm/0708/3085.html) -- (old) modified dwm with extensive mouse support -* [cons-wm](http://github.com/dharmatech/psilab/tree/master/cons-wm) -- minimalist wm in scheme (not tiled) -* [bug.n](https://github.com/fuhsjr00/bug.n) -- dwm for Windows written in AutoHotkey -* [dvtm](http://www.brain-dump.org/projects/dvtm/) -- virtual terminal manager (dwm on the console) -* [dwm-gtx](http://s01.de/~gottox/index.cgi/proj_dwm) -- dwm branch with Xinerama support, pointer movement, different layout -* [dwm-sprinkles](http://0mark.unserver.de/dwm-sprinkles/) -- dwm with colorfull bar, transparency, pre-configured pertag and more -* [dwm-win32](http://www.brain-dump.org/projects/dwm-win32/) -- dwm ported to windows -* [echinus](http://www.rootshell.be/~polachok/code/) -- dwm fork with EWMH, Xft support -* [gemini](http://gemini.digitalmediaplanet.net) -- terminal manager -* [i3](http://i3.zekjur.net/) -- wmii fork with XCB, multihead, vertical column, command mode -* [musca](http://aerosuidae.net/musca.html) -- inspired by dwm, more complex layout, configurable with commands, EWMH support -* [qtile](http://www.qtile.org/) -- pure python wm, used ideas from dwm -* [scrotwm](http://www.peereboom.us/scrotwm/html/scrotwm.html) -- dwm clone with multihead, config file, restart.. support -* [TAL/wm](http://talwm.sourceforge.net/) -- minimal tiled wm based on dwm (discontinued) -* [teslawm](http://teslawm.org/) -- dwm fork with multihead, mouse, stdin commands support (was dwm-rfigura) -* [xmonad](http://www.xmonad.org/) -- dwm clone in haskell +For instructions on how to submit and format patches, take a look at +the [hacking guidelines](http://suckless.org/hacking). diff --git a/dwm.suckless.org/patches/ispermanent.md b/dwm.suckless.org/patches/ispermanent.md @@ -10,7 +10,7 @@ windows. Download -------- -* [dwm-6.1-ispermanent.diff](dwm-6.1-ispermanent.diff) (1.8k) (20150803) +* [dwm-6.0-ispermanent.diff](dwm-6.0-ispermanent.diff) Author ------ diff --git a/dwm.suckless.org/patches/keycode.md b/dwm.suckless.org/patches/keycode.md @@ -6,8 +6,8 @@ using for exemple xev). Download -------- -* [dwm-6.0-keycode.diff](dwm-6.0-keycode.diff) -* [dwm-20151110-5ed9c48-keycode.patch](dwm-20151110-5ed9c48-keycode.patch) +* [dwm-keycode-6.1.diff](dwm-keycode-6.1.diff) +* [dwm-keycode-20160702-56a31dc.diff](dwm-keycode-20160702-56a31dc.diff) Author ------ diff --git a/dwm.suckless.org/patches/keypressrelease.md b/dwm.suckless.org/patches/keypressrelease.md @@ -24,8 +24,8 @@ Or to only display the bar while the toggle key is held down (requires that it i Download --- - * [dwm-6.0-keypressrelease.diff](dwm-6.0-keypressrelease.diff) - * [dwm-6.0-keypressrelease.diff on GitHub](https://github.com/Ceryn/patches/blob/master/dwm/dwm-6.0-keypressrelease.diff) + * [dwm-keypressrelease-6.0.diff](dwm-keypressrelease-6.0.diff) + * [dwm-keypressrelease-6.0.diff on GitHub](https://github.com/Ceryn/patches/blob/master/dwm/dwm-keypressrelease-6.0.diff) Author ------ diff --git a/dwm.suckless.org/patches/mark.md b/dwm.suckless.org/patches/mark.md @@ -36,7 +36,7 @@ jump to mark and clear the mark ## Download ## this patch has been revised, it's recommended to use dwm-6.1-mark-new.diff -old behaviours of the patch(dwm-6.1-mark.diff): +old behaviours of the patch(dwm-mark-6.1.diff): 1. crashes when using mark features while the marked client has been killed. 2. swapclient clears the mark. @@ -44,8 +44,8 @@ old behaviours of the patch(dwm-6.1-mark.diff): 4. swapfocus does not activate tags for the marked client 5. swapfocus does not focus monitors correctly -* [dwm-6.1-mark-new.diff](dwm-6.1-mark-new.diff) (5815b) (20160309) -* [dwm-6.1-mark.diff](dwm-6.1-mark.diff) (7161b) (20160220) +* [dwm-mark-new-6.1.diff](dwm-mark-new-6.1.diff) +* [dwm-mark-6.1.diff](dwm-mark-6.1.diff) ## Author ## -* phi <crispyforg@163.com> +* phi <crispyfrog@163.com> diff --git a/dwm.suckless.org/patches/maximize.md b/dwm.suckless.org/patches/maximize.md @@ -18,8 +18,9 @@ Insert the bindings into the keys list. Here is an example: Download -------- -* [dwm-6.1-maximize_vert_horz.diff](dwm-6.1-maximize_vert_horz.diff) (2532b) (20140209) -* [dwm-6.0-maximize_vert_horz.diff](dwm-6.0-maximize_vert_horz.diff) (2013b) (20120406) +* [dwm-maximize_vert_horz-20160731-56a31dc.diff](dwm-maximize_vert_horz-20160731-56a31dc.diff) +* [dwm-maximize_vert_horz-6.1.diff](dwm-maximize_vert_horz-6.1.diff) (Unclean patch) +* [dwm-maximize_vert_horz-6.0.diff](dwm-maximize_vert_horz-6.0.diff) Author ------ diff --git a/dwm.suckless.org/patches/monarg.md b/dwm.suckless.org/patches/monarg.md @@ -1,18 +0,0 @@ -Monitor by Argument for dmenu -============================= - -Description ------------ - -Since dmenu was made to accept additional command line argument with -[dmenu-4.5-monarg.diff](http://tools.suckless.org/dmenu/patches/monarg) to -specify the monitor where dmenu is to be started. Works well with my monarg -patch for dwm. - -Download --------- -* [dwm-6.1-monarg.diff](dwm-6.1-monarg.diff) - -Author ------- -* mar77i <mysatyre at gmail dot com> diff --git a/dwm.suckless.org/patches/monocle_count.md b/dwm.suckless.org/patches/monocle_count.md @@ -9,7 +9,7 @@ current release prints only the number of total clients within the symbol. Download -------- -* [dwm-5.8.2-monocle_count.diff](dwm-5.8.2-monocle_count.diff) +* [dwm-monocle_count-5.8.2.diff](dwm-monocle_count-5.8.2.diff) Author ------ diff --git a/dwm.suckless.org/patches/moveresize.md b/dwm.suckless.org/patches/moveresize.md @@ -61,11 +61,10 @@ Download Patches against different versions of dwm are available at [dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). - * [dwm-6.1-moveresize.diff](dwm-6.1-moveresize.diff) (2095b) (20140209) + * [dwm-moveresize-20160731-56a31dc.diff](dwm-moveresize-20160731-56a31dc.diff) + * [dwm-moveresize-6.1.diff](dwm-moveresize-6.1.diff) (2095b) (20140209) * [dwm-10e232f9ace7-moveresize.diff](dwm-10e232f9ace7-moveresize.diff) (2025b) (20120406) - * [dwm-10e232f9ace7-maximize_vert_horz.diff](dwm-10e232f9ace7-maximize_vert_horz.diff) (2385b) (20120406) - * [dwm-6.0-moveresize.diff](dwm-6.0-moveresize.diff) (2025b) (20120406) - * [dwm-6.0-maximize_vert_horz.diff](dwm-6.0-maximize_vert_horz.diff) (2385b) (20120406) + * [dwm-moveresize-6.0.diff](dwm-moveresize-6.0.diff) (2025b) (20120406) Authors ------- diff --git a/dwm.suckless.org/patches/movestack.md b/dwm.suckless.org/patches/movestack.md @@ -23,8 +23,8 @@ movestack(-1) will swap the client with the current focus with the previous clie ## Download - * [dwm-5.8.2-movestack.diff](movestack-5.8.2.diff) (2.6k) (20101102) - * [dwm-5.6.1-movestack.diff][1] (2.4k) (20090911) + * [dwm-movestack-6.1.diff](dwm-movestack-6.1.diff) + * [dwm-movestack-5.8.2.diff](historical/dwm-movestack-5.8.2.diff) ## Author @@ -37,5 +37,3 @@ movestack(-1) will swap the client with the current focus with the previous clie ## Note This patch seems to be equivalent to the [push](push) patch. - -[1]: http://www.aplusbi.com/projects/dwm/dwm-5.6.1-movestack.diff diff --git a/dwm.suckless.org/patches/nametag.md b/dwm.suckless.org/patches/nametag.md @@ -11,9 +11,9 @@ The `prepend` version prepends the tag name with a short string which is used as Download -------- -* [dwm-6.1-nametag.diff](dwm-6.1-nametag.diff) (2.3k) (20131002) -* [dwm-6.1-nametag-prepend.diff](dwm-6.1-nametag-prepend.diff) (2525b) (20140607) -* [dwm-5.7.2-nametag.diff](dwm-5.7.2-nametag.diff) (2.5k) (20091029) +* [dwm-nametag-6.1.diff](dwm-nametag-6.1.diff) +* [dwm-nametag-prepend-6.1.diff](dwm-nametag-prepend-6.1.diff) +* [dwm-nametag-5.7.2.diff](dwm-nametag-5.7.2.diff) Author ------ diff --git a/dwm.suckless.org/patches/noborder.md b/dwm.suckless.org/patches/noborder.md @@ -3,20 +3,17 @@ noborder Description ----------- -This patch removes the border when there is just one window visible in tiled or monocle layout. -For an alternative that works with most layouts without any layout-specific -changes, check out [better borders](http://dwm.suckless.org/patches/better-borders). +Remove the border when there is only one window visible. Download -------- -Patches against different versions of dwm are available at -[dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). - * [dwm-6.1-single_window_no_border.diff](dwm-6.1-single_window_no_border.diff) (3047b) (20151111) - * [dwm-10e232f9ace7-statusallmons.diff](dwm-10e232f9ace7-statusallmons.diff) (982b) (20120406) - * [dwm-6.0-single_window_no_border.diff](dwm-6.0-single_window_no_border.diff) (2865b) (20120406) + * [dwm-noborder-6.1.diff](dwm-noborder-6.1.diff) + * [dwm-noborder-20160718-56a31dc.diff](dwm-noborder-20160718-56a31dc.diff) -Author ------- - * Jan Christoph Ebersbach - `<jceb at e-jc dot de>` +Authors +------- + + * Eric Pruitt - <eric.pruitt@gmail.com> + * Laslo Hunhold - <dev@frign.de> (6.1, git port) diff --git a/dwm.suckless.org/patches/nofullscreen.m4 b/dwm.suckless.org/patches/nofullscreen.m4 @@ -1,19 +0,0 @@ -nofullscreen -============ - -Description ------------ - -Prevent clients becoming floaters when going into fullscreen, -to keep them more manageable by dwm; useful if you work mainly -in monocle layout and don't want to lose control. - -Download --------- - -* [dwm-nofullscreen.diff](dwm-nofullscreen.diff) (389b) (20140305) - -Author ------- - -* Michael Hauser - aware water @ gmail diff --git a/dwm.suckless.org/patches/pango.md b/dwm.suckless.org/patches/pango.md @@ -32,7 +32,7 @@ not possible under barebone xft: Download -------- -* [dwm-6.0-pango.diff](dwm-6.0-pango.diff) +* [dwm-pango-6.0.diff](dwm-pango-6.0.diff) Author ------ diff --git a/dwm.suckless.org/patches/pertag.md b/dwm.suckless.org/patches/pertag.md @@ -11,16 +11,18 @@ Download Patches against different versions of dwm are available at [dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). - * [dwm-6.1-pertag.diff](dwm-6.1-pertag.diff) (6.4K) (20151109) + * [dwm-pertag-20160731-56a31dc.diff](dwm-pertag-20160731-56a31dc.diff) + * [dwm-pertag-20160626-7af4d43.diff](dwm-pertag-20160626-7af4d43.diff) + * [dwm-pertag-6.1.diff](dwm-pertag-6.1.diff) (6.4K) (20151109) * [dwm-git-20120406-pertag.diff](dwm-git-20120406-pertag.diff) (5955b) - * [dwm-6.0-pertag.diff](dwm-6.0-pertag.diff) (5955b) (20120406) + * [dwm-pertag-6.0.diff](dwm-pertag-6.0.diff) (5955b) (20120406) * [dwm-r1578-pertag.diff][9] (nmaster included in mainline) - * [dwm-5.8.2-pertag.diff][7] - * [dwm-5.7.2-pertag.diff][6] + * [dwm-pertag-5.8.2.diff][7] + * [dwm-pertag-5.7.2.diff][6] * [dwm-pertag-5.6.1.diff][5] - * [dwm-5.4-pertag.diff][4] - * [dwm-5.2-pertag.diff][3] - * [dwm-5.1-pertag.diff][2] + * [dwm-pertag-5.4.diff][4] + * [dwm-pertag-5.2.diff][3] + * [dwm-pertag-5.1.diff][2] * Using pertag but with the same barpos * [dwm-6.1-pertag_without_bar.diff](dwm-6.1-pertag_without_bar.diff) (5.2K) (20151109) @@ -36,13 +38,14 @@ Authors * Updated by William Light - `<wrl at illest dot net>` * Updated by termac - `<terror.macbeth.I at gmail dot com>` * Updated by Ivan Tham - `pickfire at riseup dot net` + * [Jochen Sprickerhof](mailto:project@firstname.lastname.de) (Updated to current git) [1]: historical/taglayouts -[2]: http://v4hn.de/patches/dwm-5.1-pertag.diff -[3]: historical/dwm-5.2-pertag.diff -[4]: historical/dwm-5.4-pertag.diff +[2]: historical/dwm-pertag-5.1.diff +[3]: historical/dwm-pertag-5.2.diff +[4]: historical/dwm-pertag-5.4.diff [5]: historical/dwm-pertag-5.6.1.diff -[6]: historical/dwm-5.7.2-pertag.diff -[7]: historical/dwm-5.8.2-pertag.diff +[6]: historical/dwm-pertag-5.7.2.diff +[7]: historical/dwm-pertag-5.8.2.diff [8]: historical/dwm-5.8.2-pertag_without_bar.diff [9]: historical/dwm-r1578-pertag.diff diff --git a/dwm.suckless.org/patches/push.md b/dwm.suckless.org/patches/push.md @@ -17,9 +17,10 @@ Patches against different versions of dwm are available at [dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). - * [dwm-6.0-push.diff](dwm-6.0-push.diff) (1332b) - 2012/4/6 + * [dwm-push-20160731-56a31dc.diff](dwm-push-20160731-56a31dc.diff) + * [dwm-push-6.0.diff](dwm-push-6.0.diff) (1332b) - 2012/4/6 * [dwm-6.0-push_no_master.diff](dwm-6.0-push_no_master.diff) - * [dwm-6.1-push.diff](dwm-6.1-push.diff) (1402b) - 2014/2/9 + * [dwm-push-6.1.diff](dwm-push-6.1.diff) (1402b) - 2014/2/9 * [dwm-6.1-push_no_master.diff](dwm-6.1-push_no_master.diff) - 2015/11/21 ## Note diff --git a/dwm.suckless.org/patches/pwkl.md b/dwm.suckless.org/patches/pwkl.md @@ -15,7 +15,7 @@ this: [see ml](http://lists.suckless.org/dev/1010/6195.html). Download -------- -* [dwm-5.9-pwkl.diff](dwm-5.9-pwkl.diff) (1.4K) (20101013) +* [dwm-pwkl-5.9.diff](dwm-pwkl-5.9.diff) (1.4K) (20101013) Author ------ diff --git a/dwm.suckless.org/patches/resizecorners.md b/dwm.suckless.org/patches/resizecorners.md @@ -6,8 +6,8 @@ By default, windows only from the bottom right corner. With this Patch, the mous ## Download - * [dwm-6.1-resizecorners.diff](dwm-6.1-resizecorners.diff) (17.02.2016) - * [dwm-6.0-resizecorners.diff](dwm-6.0-resizecorners.diff) (12.05.2015) + * [dwm-resizecorners-6.1.diff](dwm-resizecorners-6.1.diff) (17.02.2016) + * [dwm-resizecorners-6.0.diff](dwm-resizecorners-6.0.diff) (12.05.2015) ## Author diff --git a/dwm.suckless.org/patches/save_floats.md b/dwm.suckless.org/patches/save_floats.md @@ -9,10 +9,12 @@ be restored. Patches against different versions of dwm are available at [dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). + * [dwm-savefloats-20160723-56a31dc.diff](dwm-savefloats-20160723-56a31dc.diff) (1452b) * [dwm-6.1-save_floats.diff](dwm-6.1-save_floats.diff) (1605b) (20140209) * [dwm-10e232f9ace7-save_floats.diff](dwm-10e232f9ace7-save_floats.diff) (1604b) (20120406) - * [dwm-6.0-save_floats.diff](dwm-6.0-save_floats.diff) (1528b) (20120406) + * [dwm-save_floats-6.0.diff](dwm-save_floats-6.0.diff) (1528b) (20120406) ## Author ## * http://nymu.net/patches * Updated by Jan Christoph Ebersbach - <jceb@e-jc.de> + * Ivan Tham <pickfire@riseup.net> (git port) diff --git a/dwm.suckless.org/patches/single_tagset.md b/dwm.suckless.org/patches/single_tagset.md @@ -24,13 +24,15 @@ Please be aware that this patch probably breaks any other patch! Patches against different versions of dwm are available at [dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). + * [dwm-single_tagset-20160731-56a31dc.diff](dwm-single_tagset-20160731-56a31dc.diff) * [dwm-6.1-single_tagset.diff](dwm-6.1-single_tagset.diff) (16634b) (20140209) * [dwm-10e232f9ace7-single_tagset.diff](dwm-10e232f9ace7-single_tagset.diff) (14748b) (20120406) - * [dwm-6.0-single_tagset.diff](dwm-6.0-single_tagset.diff) (14417b) (20120406) + * [dwm-single_tagset-6.0.diff](dwm-single_tagset-6.0.diff) (14417b) (20120406) Special Version --------------- This is a special version of the patch that was created with following patches being applied: + * [attachabove](attachabove) * [float_border_color](float_border_color) * [focusmaster](https://raw.github.com/jceb/dwm-patches/master/patches/focusmaster.patch) diff --git a/dwm.suckless.org/patches/sizehints.md b/dwm.suckless.org/patches/sizehints.md @@ -12,7 +12,7 @@ There is no configuration for this patch. ## Download - * [dwm-5.7.2-sizehints.diff](dwm-5.7.2-sizehints.diff) (695B) (20091221) + * [dwm-sizehints-5.7.2.diff](dwm-sizehints-5.7.2.diff) (695B) (20091221) ## Author diff --git a/dwm.suckless.org/patches/stacker.md b/dwm.suckless.org/patches/stacker.md @@ -53,7 +53,7 @@ stacker changes to `MODKEY|ShiftMask+BackSpace`. Download -------- -* [dwm-6.0-stacker.diff](dwm-6.0-stacker.diff) +* [dwm-stacker-6.0.diff](dwm-stacker-6.0.diff) Author ------ diff --git a/dwm.suckless.org/patches/statusallmons.md b/dwm.suckless.org/patches/statusallmons.md @@ -10,10 +10,11 @@ Download Patches against different versions of dwm are available at [dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). + * [dwm-statusallmons-20160731-56a31dc.diff](dwm-statusallmons-20160731-56a31dc.diff) * [dwm-6.1-statusallmons.diff](dwm-6.1-statusallmons.diff) (1026b) (20140209) * [dwm-10e232f9ace7-statusallmons.diff](dwm-10e232f9ace7-statusallmons.diff) (982b) (20120406) - * [dwm-6.0-statusallmons.diff](dwm-6.0-statusallmons.diff) (982b) (20120406) - * [dwm-5.8.2-statusallmons.diff](dwm-5.8.2-statusallmons.diff) (4.0K) (20110318) + * [dwm-statusallmons-6.0.diff](dwm-statusallmons-6.0.diff) (982b) (20120406) + * [dwm-statusallmons-5.8.2.diff](dwm-statusallmons-5.8.2.diff) (4.0K) (20110318) Author ------ diff --git a/dwm.suckless.org/patches/statuscolors.md b/dwm.suckless.org/patches/statuscolors.md @@ -58,5 +58,5 @@ An example status script snippet to take advantage of the colors: * [dwm-5.7.2-statuscolors.diff](historical/dwm-5.7.2-statuscolors.diff) * [dwm-5.8.2-statuscolors.diff](historical/dwm-5.8.2-statuscolors.diff) - * [dwm-5.9-statuscolors.diff](dwm-5.9-statuscolors.diff) - * [dwm-6.1-statuscolors.diff](dwm-6.1-statuscolors.diff) + * [dwm-statuscolors-5.9.diff](dwm-statuscolors-5.9.diff) + * [dwm-statuscolors-6.1.diff](dwm-statuscolors-6.1.diff) diff --git a/dwm.suckless.org/patches/swallow.md b/dwm.suckless.org/patches/swallow.md @@ -1,34 +1,51 @@ -# terminals swallow windows +swallow +======= -## Description +Description +----------- -This patch adds "window swallowing" to dwm, a la `rio` from Plan 9. +This patch adds "window swallowing" to dwm as known from Plan 9's windowing +system `rio`. -Windows that are marked with the `isterminal` flag (settable using rules in `config.h`) will swallow a window opened by any descendant processes. -For example, if you open a terminal and then in that terminal type `xclock`, the `xclock` window takes the place of that terminal window. -Closing the `xclock` window restores the terminal window in the current position. +Clients marked with `isterminal` in config.h swallow a window opened by +any child process, e.g. running `xclock` in a terminal. +Closing the `xclock` window restores the terminal window in the current +position. -This patch is useful for users who tend to do most or all of their work from the command line, but sometimes need to use a graphical program. -This patch avoids cluttering the desktop with unused terminals. +This patch helps users spawning a lot of graphical programs from their +command line by avoiding cluttering the screen with many unusable terminals. +Being deep down in a directory hierarchy just does not make the use of +dmenu feasible. -(`dmenu` could be used, but if you are deep in a directory hierarchy and want to, say, view a PDF, cutting and pasting the path to `dmenu` takes longer than just running `mupdf`.) +Dependencies +------------ -## Download -Please see [deadpixi-dwm](https://github.com/deadpixi/deadpixi-dwm) for the development site. + * libxcb + * Xlib-libxcb + * xcb-res -Patches are also available here: +These dependencies are needed due to the use of the latest revision of the X +Resource Extension which is unsupported in vanilla Xlib. - * [dwm-6.1-swallowing.diff](dwm-6.1-swallowing.diff) (9319b) - 2016/1/27 +Download +-------- -## Note -The window swallowing functionality requires `dwm` to walk the process tree, which is an inherently OS-specific task. -Only Linux is supported at this time. -Please contact the author (jking@deadpixi.com) if you would like to help expand the list of supported operating systems. + * [dwm-swallow-6.1.diff](dwm-swallow-6.1.diff) + * [dwm-swallow-20160717-56a31dc.diff](dwm-swallow-20160717-56a31dc.diff) -Also please note that building with this patch requires `libxcb`, `Xlib-libxcb`, and `xcb-res`. -This is due to the use of the latest revision of the X Resource Extension, which is unsupported in vanilla Xlib. +Notes +----- -Only terminals created by local processes can swallow windows, and only windows created by local processes can be swallowed. +The window swallowing functionality requires `dwm` to walk the process tree, +which is an inherently OS-specific task. Only Linux is supported at this time. +Please contact one of the authors if you would like to help expand the list +of supported operating systems. -## Author - * Rob King <jking@deadpixi.com> +Only terminals created by local processes can swallow windows, and only +windows created by local processes can be swallowed. + +Authors +------- + + * Rob King - <jking@deadpixi.com> + * Laslo Hunhold - <dev@frign.de> (6.1, git port) diff --git a/dwm.suckless.org/patches/swapfocus.md b/dwm.suckless.org/patches/swapfocus.md @@ -7,9 +7,10 @@ This patch makes it possible to switch focus with one single shortcut (alt-s) in Patches against different versions of dwm are available at [dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). + * [dwm-swapfocus-20160731-56a31dc.diff](dwm-swapfocus-20160731-56a31dc.diff) * [dwm-6.1-swapfocus.diff](dwm-6.1-swapfocus.diff) (1807b) (20140209) * [dwm-10e232f9ace7-swapfocus.diff](dwm-10e232f9ace7-swapfocus.diff) (1484b) (20120406) - * [dwm-6.0-swapfocus.diff](dwm-6.0-swapfocus.diff) (1482b) (20120406) + * [dwm-swapfocus-6.0.diff](dwm-swapfocus-6.0.diff) (1482b) (20120406) * [dwm-5.8.2-swap.diff](dwm-5.8.2-swap.diff) (dwm 5.8.2) ## Author diff --git a/dwm.suckless.org/patches/switchcol.md b/dwm.suckless.org/patches/switchcol.md @@ -0,0 +1,20 @@ +# switchcol + +## Description + +Switch focus between the 2 columns (master or stack) easily. This patch only +has one function, it remembers the most recently focused client in the 2 +columns for each tag (it is implemented by searching the stack list to find +the most recent client in the other column). + +## Configuration + + /*config.h*/ + { MODKEY, XK_n, switchcol, {0} }, + +## Download + +* [dwm-switchcol-6.1.diff](dwm-switchcol-6.1.diff) (1126b) (20160325) + +## Author +* phi <crispyfrog@163.com> diff --git a/dwm.suckless.org/patches/systray.md b/dwm.suckless.org/patches/systray.md @@ -11,13 +11,16 @@ Download Patches against different versions of dwm are available at [dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). + * [dwm-systray-20160731-56a31dc.diff](dwm-systray-20160731-56a31dc.diff) + * [dwm-systray-git-20160626-7af4d43.diff](dwm-systray-git-20160626-7af4d43.diff) (7af4d43) * [dwm-git-20160103-systray.diff](dwm-git-20160103-systray.diff) (3465bed) * [dwm-6.1-systray.diff](dwm-6.1-systray.diff) (22K) (20151109) * [dwm-git-20130119-systray.diff](dwm-git-20130119-systray.diff]) (19946b) - * [dwm-6.0-systray.diff](dwm-6.0-systray.diff) (19788b) (20130119) + * [dwm-systray-6.0.diff](dwm-systray-6.0.diff) (19788b) (20130119) Author ------ * Jan Christoph Ebersbach <jceb@e-jc.de> * Eon S. Jeon <esjeon@hyunmu.am> (14343e69cc59) * David Phillips (5ed9c48 (6.1), and 20160103) + * Eric Pruitt (7af4d43 (6.1), and 20160626) diff --git a/dwm.suckless.org/patches/tagall.md b/dwm.suckless.org/patches/tagall.md @@ -8,9 +8,10 @@ Shortcut to move all (floating) windows from one tag to another. Patches against different versions of dwm are available at [dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). - * [dwm-6.1-tagall.diff](dwm-6.1-tagall.diff) (1058b) (20140209) + * [dwm-tagall-20160731-56a31dc.diff](dwm-tagall-20160731-56a31dc.diff) + * [dwm-tagall-6.1.diff](dwm-tagall-6.1.diff) (1058b) (20140209) * [dwm-10e232f9ace7-tagall.diff](dwm-10e232f9ace7-tagall.diff) (988b) (20120406) - * [dwm-6.0-tagall.diff](dwm-6.0-tagall.diff) (988b) (20120406) + * [dwm-tagall-6.0.diff](dwm-tagall-6.0.diff) (988b) (20120406) ## Configuration ## diff --git a/dwm.suckless.org/patches/tilegap.md b/dwm.suckless.org/patches/tilegap.md @@ -9,7 +9,7 @@ and screen edge. Size configurable in config.h. Download -------- -- [dwm-6.0-tilegap.diff](dwm-6.0-tilegap.diff) (948b) (20150707) +- [dwm-tilegap-6.0.diff](dwm-tilegap-6.0.diff) (948b) (20150707) Author ------ diff --git a/dwm.suckless.org/patches/uselessgap.md b/dwm.suckless.org/patches/uselessgap.md @@ -49,8 +49,8 @@ tile mode... ## Download - * [dwm-6.1-uselessgap.diff](dwm-6.1-uselessgap.diff) (4K) (20150815), now supports nmaster. - * [dwm-5.9-uselessgap.diff](dwm-5.9-uselessgap.diff) (1.8k) (20110107 updated. Thanks Jordan for your bug report) + * [dwm-uselessgap-6.1.diff](dwm-uselessgap-6.1.diff) (4K) (20150815), now supports nmaster. + * [dwm-uselessgap-5.9.diff](dwm-uselessgap-5.9.diff) (1.8k) (20110107 updated. Thanks Jordan for your bug report) Updated to use the new resizeclient() function instead of resize() diff --git a/dwm.suckless.org/patches/warp.md b/dwm.suckless.org/patches/warp.md @@ -11,13 +11,14 @@ different window. Download -------- -* [dwm-5.9-warp.diff](dwm-5.9-warp.diff) (20111028) -* [dwm-6.1-warp.diff](dwm-6.1-warp.diff) (20151215) +* [dwm-warp-5.9.diff](dwm-warp-5.9.diff) (20111028) +* [dwm-warp-6.1.diff](dwm-warp-6.1.diff) (20151215) +* [dwm-warp-git-20160626-7af4d43.diff](dwm-warp-git-20160626-7af4d43.diff) Author ------ * Evan Gates (emg) <evan.gates@gmail.com> * Enno Boland (Gottox) -* Jochen Sprickerhof +* [Jochen Sprickerhof](mailto:project@firstname.lastname.de) (don't warp in monocle) * Winston Weinert (winny) <winston@ml1.net> diff --git a/dwm.suckless.org/patches/zoomswap.md b/dwm.suckless.org/patches/zoomswap.md @@ -43,9 +43,10 @@ Download Patches against different versions of dwm are available at [dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). + * [dwm-zoomswap-20160731-56a31dc.diff](dwm-zoomswap-20160731-56a31dc.diff) * [dwm-6.1-zoomswap.diff](dwm-6.1-zoomswap.diff) (2585b) (20120406) * [dwm-10e232f9ace7-attachabove.diff](dwm-10e232f9ace7-attachabove.diff) (1.7K) (20120406) - * [dwm-6.0-zoomswap.diff](dwm-6.0-zoomswap.diff) (1.6K) (20120406) + * [dwm-zoomswap-6.0.diff](dwm-zoomswap-6.0.diff) (1.6K) (20120406) Author ------ diff --git a/dwm.suckless.org/scripts/basic_collection.md b/dwm.suckless.org/scripts/basic_collection.md @@ -0,0 +1,9 @@ +Scripts collection +================== + +Description +----------- + +A basic collection of simple, fully POSIX sh compliant scripts to get various +system information among other useful things can be found at kl3's [scripts](https://notabug.org/kl3/scripts) +repository. Feel free to copy, adapt and/or improve them. diff --git a/libs.suckless.org/_werc/config b/libs.suckless.org/_werc/config @@ -1,2 +1,2 @@ siteTitle='suckless.org' -siteSubtitle='deprecated libraries' +siteSubtitle='libraries' diff --git a/libs.suckless.org/deprecated/index.md b/libs.suckless.org/deprecated/index.md @@ -0,0 +1 @@ +This directory contains the deprecated libraries which have been created by the suckless community during the time. diff --git a/libs.suckless.org/deprecated/libixp.md b/libs.suckless.org/deprecated/libixp.md @@ -0,0 +1,18 @@ +LIBIXP +====== +`libixp` is a stand-alone client/server [9P](http://9p.cat-v.org/) library including `ixpc` client. It consists of less than 2000 lines of code (including `ixpc`). + +`libixp`'s server API is based heavily on that of [Plan 9](http://cm.bell-labs.com/plan9)'s [`lib9p`](http://man.cat-v.org/plan_9/2/9p), and the two libraries export virtually identical data structures. There are a few notable differences between the two, however: + +* `libixp` multiplexes connections internally, while on `Plan 9`, the kernel performs this task, and in [plan9port](http://swtch.com/plan9port/), a separate process is spawned to do so. Despite this divergence, the user of the library will not notice any difference in behavior, except that there may be duplicate `tag` and `fid` numbers between different connections. This issue is of little relevance, however, as the library handles the task of mapping `fid`s and `tag`s to arbitrary pointers and `P9Req` structs. + +* `libixp` is released under a lenient MIT-style license. + +* `libixp` lacks `lib9p`'s file trees. + +* Unlike `plan9port`'s `lib9p`, `libixp` is POSIX based, and should compile without specialized libraries on nearly any POSIX system. + +Download +-------- +* [libixp-0.5](http://dl.suckless.org/libs/libixp-0.5.tar.gz) + diff --git a/libs.suckless.org/deprecated/r9p.md b/libs.suckless.org/deprecated/r9p.md @@ -0,0 +1,12 @@ +R9P +=== + Author: Kris Maglione + License: MIT + Version: 0.4 + Repo: http://git.suckless.org/r9p + +`r9p` is a simple [9P](http://9p.cat-v.org) client implementation for Ruby. It currently supports basic filesystem operations, including reading, writing, and listing files. It also supports the operations of the IO class by providing a true file descriptor through a proxy thread. + +* [`r9p 0.4`](http://dl.suckless.org/libs/r9p-0.4.tgz) + + diff --git a/libs.suckless.org/libixp.md b/libs.suckless.org/libixp.md @@ -1,19 +0,0 @@ -LIBIXP -====== -`libixp` is a stand-alone client/server [9P](http://9p.cat-v.org/) library including `ixpc` client. It consists of less than 2000 lines of code (including `ixpc`). - -`libixp`'s server API is based heavily on that of [Plan 9](http://cm.bell-labs.com/plan9)'s [`lib9p`](http://man.cat-v.org/plan_9/2/9p), and the two libraries export virtually identical data structures. There are a few notable differences between the two, however: - -* `libixp` multiplexes connections internally, while on `Plan 9`, the kernel performs this task, and in [plan9port](http://swtch.com/plan9port/), a separate process is spawned to do so. Despite this divergence, the user of the library will not notice any difference in behavior, except that there may be duplicate `tag` and `fid` numbers between different connections. This issue is of little relevance, however, as the library handles the task of mapping `fid`s and `tag`s to arbitrary pointers and `P9Req` structs. - -* `libixp` is released under a lenient MIT-style license. - -* `libixp` lacks `lib9p`'s file trees. - -* Unlike `plan9port`'s `lib9p`, `libixp` is POSIX based, and should compile without specialized libraries on nearly any POSIX system. - -Download --------- -* [libixp-0.5](http://dl.suckless.org/libs/libixp-0.5.tar.gz) -* <code>git clone [http://git.suckless.org/libixp](http://git.suckless.org/libixp)</code> - diff --git a/libs.suckless.org/libzahl-paper-1.pdf b/libs.suckless.org/libzahl-paper-1.pdf Binary files differ. diff --git a/libs.suckless.org/libzahl-refman.pdf b/libs.suckless.org/libzahl-refman.pdf Binary files differ. diff --git a/libs.suckless.org/libzahl-refsheet.pdf b/libs.suckless.org/libzahl-refsheet.pdf Binary files differ. diff --git a/libs.suckless.org/libzahl.md b/libs.suckless.org/libzahl.md @@ -0,0 +1,34 @@ +libzahl +======= +`libzahl` is a library for arbitrary size integers, bigint. + +Download +-------- +* [ISC License](http://git.suckless.org/libzahl/plain/LICENSE) +* [libzahl 1.0](http://git.suckless.org/libzahl/snapshot/libzahl-1.0.tar.gz) + +Development +----------- +You can browse its [source code repository](http://git.suckless.org/libzahl) +or get a copy using git with the following command: + + git clone http://git.suckless.org/libzahl + +Documentation +------------- +Apart from [the man pages](http://git.suckless.org/libzahl/tree/man), +`libzahl`'s repository also contains a +[reference sheet](libzahl-refsheet.pdf) and a +[reference manual](libzahl-refman.pdf). + +Support +------- +If you cannot find what you need in the man pages, the +reference sheet, or the reference manual, the best way +to get support is to contact +[the author](http://suckless.org/people/maandree) via +e-mail. + +Papers +------ +* [Representing and working with almost none of the integers the suckless way](libzahl-paper-1.pdf) diff --git a/libs.suckless.org/r9p.md b/libs.suckless.org/r9p.md @@ -1,13 +0,0 @@ -R9P -=== - Author: Kris Maglione - License: MIT - Version: 0.4 - Repo: http://git.suckless.org/r9p - -`r9p` is a simple [9P](http://9p.cat-v.org) client implementation for Ruby. It currently supports basic filesystem operations, including reading, writing, and listing files. It also supports the operations of the IO class by providing a true file descriptor through a proxy thread. - -* [`r9p 0.4`](http://dl.suckless.org/libs/r9p-0.4.tgz) -* Latest: `git clone http://git.suckless.org/r9p` - - diff --git a/st.suckless.org/faq.md b/st.suckless.org/faq.md @@ -1,5 +0,0 @@ -<abbr title="Frequently Asked Questions">FAQ</abbr> -=== - -The FAQ is maintained in the st git repository and can be read -[here](http://git.suckless.org/st/tree/FAQ). diff --git a/st.suckless.org/index.md b/st.suckless.org/index.md @@ -2,10 +2,10 @@ st is a simple terminal implementation for X. -->[![Screenshot of dwm & st](screenshots/20h-2012-s.png)](screenshots/20h-2012.png)<- +->[![Screenshot of dwm & st](screenshots/frign-2016-s.png)](screenshots/frign-2016.png)<- -What is wrong with xterm? -------------------------- +Motivation +---------- xterm is bloated and unmaintainable. Here's an excerpt from the README: Abandon All Hope, Ye Who Enter Here @@ -20,62 +20,55 @@ xterm is bloated and unmaintainable. Here's an excerpt from the README: Needless to say things have *not* changed, it's still ugly. It has over 65K lines of code and emulates obscure and obsolete terminals you will [never need](http://www.science.uva.nl/museum/tek4014.php). + The popular alternative, rxvt has *only* 32K lines of code. This is just too much for something as simple as a terminal emulator; it's yet another example of code complexity. -Current state -------------- -See the [TODO](http://git.suckless.org/st/plain/TODO) file for what needs to -be implemented or fixed. +Terminal emulation doesn't need to be so complex. -What has been implemented: +Status +------ +Things that have already been implemented are -* 256 colors and [true colors](https://gist.github.com/XVilka/8346728) * most VT10X escape sequences -* utf8 -* X11 copy/paste -* antialiased fonts (using fontconfig) -* fallback fonts -* resize -* shortcuts via config.h -* line drawing -* wide-character support * serial line support * XIM support -* clipboard handling * utmp via utmp(1) +* clipboard handling +* mouse and keyboard shortcuts (via config.h) +* UTF-8 +* wide-character support +* resize +* 256 colors and [true colors](https://gist.github.com/XVilka/8346728) +* antialiased fonts (using fontconfig) +* fallback fonts +* line drawing -See the [goals](http://st.suckless.org/goals) section for more details. +See the [goals](http://st.suckless.org/goals) for more details and the +[TODO](http://git.suckless.org/st/plain/TODO) for what still needs to be +implemented or fixed. Configuration ------------- -The configuration is done in `config.h` (like in dwm). See the comments in the -generated `config.h` to edit it to your needs. +Configuration is done with `config.h`. Read the comments in the +generated `config.h` to edit it according to your needs. +Defaults are stored in `config.def.h`. FAQ --- -The FAQ is maintained in the st git repository and can be read -[here](http://git.suckless.org/st/tree/FAQ). - -Links ------ -* Mailing List: `dev+subscribe@suckless.org` [(Archives)](http://lists.suckless.org/dev) -* IRC channel: #suckless at irc.oftc.net - -Download --------- -* [st 0.6](http://dl.suckless.org/st/st-0.6.tar.gz) (2015-07-07) -* [MIT/X Consortium license](http://git.suckless.org/st/plain/LICENSE) +The [FAQ](http://git.suckless.org/st/plain/FAQ) is maintained in the st +source code repository. Development ----------- -st is actively developed. You can [browse](http://git.suckless.org/st) its source code repository or get a copy using git with the following command: - - git clone http://git.suckless.org/st +st is actively developed. You can [browse](http://git.suckless.org/st) its +source code repository or get a copy using git with the following command: -Contributors ------------- -* see the LICENSE file + git clone git://git.suckless.org/st +Download +-------- +* [st 0.6](http://dl.suckless.org/st/st-0.6.tar.gz) (2015-07-07) +* [LICENSE](http://git.suckless.org/st/plain/LICENSE) diff --git a/st.suckless.org/patches/alpha.md b/st.suckless.org/patches/alpha.md @@ -0,0 +1,33 @@ +alpha +===== + +->[![Screenshot](st-alpha-s.png)](st-alpha.png)<- + +Description +----------- + +This patch allows users to change the opacity of the background. +Note that *you need an X composite manager* (e.g. compton, xcompmgr) to +make this patch effective. + +Notes +----- + + - The alpha value affects the default background only. + - The color designated by 'defaultbg' should not be used elsewhere. + - Embedding might fail after applying this patch. + +Download +-------- + + * [st-alpha-0.4.1.diff](st-alpha-0.4.1.diff) + * [st-alpha-0.5.diff](st-alpha-0.5.diff) + * [st-alpha-0.6.diff](st-alpha-0.6.diff) + * [st-alpha-20160727-308bfbf.diff](st-alpha-20160727-308bfbf.diff) + +Authors +------- + + * Eon S. Jeon - <esjeon@hyunmu.am> + * pr - <protodev@gmx.net> (0.5 port) + * Laslo Hunhold - <dev@frign.de> (0.6, git ports) diff --git a/st.suckless.org/patches/argbbg.md b/st.suckless.org/patches/argbbg.md @@ -1,26 +0,0 @@ -argbbg -====== - -->[![Screenshot](st-argbbg-s.png)](st-argbbg.png)<- - -## Description ## -This patch allows users to change the opacity of the background. -Note that *you need an X composite manager* (e.g. compton, xcompmgr) to -make this patch effective. - -## Important Notes ## - - The alpha value affects the default background only. - - The color designated by 'defaultbg' should not be used elsewhere. - - Embedding might fail after applying this patch. - -## Download ## - * [st-0.4.1-argbbg.diff](st-0.4.1-argbbg.diff) - * [st-0.5-argbbg.diff](st-0.5-argbbg.diff) - * [st-0.6-argbbg.diff](st-0.6-argbbg.diff) - * [st-git-20160131-argbbg.diff](st-git-20160131-argbbg.diff) - -## Authors ## - * Eon S. Jeon - esjeon@hyunmu.am - * pr - protodev@gmx.net (st-0.5 port) - * Laslo Hunhold - dev@frign.de (st-0.6 port) - * David Phillips - dbphillipsnz@gmail.com (st-git-20160131 port) diff --git a/st.suckless.org/patches/boldcolor.md b/st.suckless.org/patches/boldcolor.md @@ -1,47 +0,0 @@ -boldcolor -========= - -Description ------------ - -This is a hack allowing to use different colors for bold, italic -and underlined text when the text would be in defaultfg color otherwise. - -This makes the special attributes more visible when no bold or italic -font is available or defaultfg is a special color (> 255). - -Usage ------ - -config.h example: - - static const char *colorname[] = { - // ... - [255]=0, - // extra - "#00cc00", - "#333333", - "#cdba96", - "#99ff00", - "#ffff00", - }; - - static unsigned int defaultfg = 7; - static unsigned int defaultbg = 0; - static unsigned int defaultcs = 256; - static unsigned int defaultucs = 257; - // we don't want bold font (dc.bfont == dc.font) - #define NOBOLDFONT 1 - // we have extra colors to mark bold, italic and underline - #define DEFAULTBOLD 258 - #define DEFAULTITALIC 259 - #define DEFAULTUNDERLINE 260 - -Download --------- -* [st-0.3-boldcolor.diff](st-0.3-boldcolor.diff) - -Author ------- - - * Szabolcs Nagy - nsz@port70.net diff --git a/st.suckless.org/patches/clipboard.md b/st.suckless.org/patches/clipboard.md @@ -1,6 +1,8 @@ -# clipboard +clipboard +========= -## Description +Description +----------- st only sets PRIMARY on selection since [March 2015](http://git.suckless.org/st/commit/?id=28259f5750f0dc7f52bbaf8b746ec3dc576a58ee) @@ -10,12 +12,14 @@ according to the This patch brings back the old behaviour, namely additionally setting CLIPBOARD. -## Download +Download +-------- -* [st-0.6-clipboard.diff](st-0.6-clipboard.diff) -* [st-git-20150917-clipboard.diff](st-git-20150917-clipboard.diff) +* [st-clipboard-0.6.diff](st-clipboard-0.6.diff) +* [st-clipboard-20160727-308bfbf.diff](st-clipboard-20160727-308bfbf.diff) -## Authors +Authors +------- - * Kai Hendry - hendry@iki.fi - * Laslo Hunhold - dev@frign.de (st-git-20150917 port) + * Kai Hendry - <hendry@iki.fi> + * Laslo Hunhold - <dev@frign.de> (git port) diff --git a/st.suckless.org/patches/copyurl.md b/st.suckless.org/patches/copyurl.md @@ -16,12 +16,11 @@ URL on each line is selected. Download -------- - * [st-0.6-copyurl.diff](st-0.6-copyurl.diff) - * [st-git-20160210-copyurl.diff](st-git-20160210-copyurl.diff) + * [st-copyurl-0.6.diff](st-copyurl-0.6.diff) + * [st-copyurl-20160727-308bfbf.diff](st-copyurl-20160727-308bfbf.diff) Authors ------- - * Brandon Mulcahy - brandon@jangler.info - * Laslo Hunhold - dev@frign.de (st-0.6 port) - * David Phillips - dbphillipsnz@gmail.com (st-git-20160210 port) + * Brandon Mulcahy - <brandon@jangler.info> + * Laslo Hunhold - <dev@frign.de> (0.6, git ports) diff --git a/st.suckless.org/patches/delkey.md b/st.suckless.org/patches/delkey.md @@ -9,11 +9,11 @@ Return BS on pressing backspace and DEL on pressing the delete key. Download -------- - * [st-0.6-delkey.diff](st-0.6-delkey.diff) - * [st-git-20150917-delkey.diff](st-git-20150917-delkey.diff) + * [st-delkey-0.6.diff](st-delkey-0.6.diff) + * [st-delkey-20160727-308bfbf.diff](st-delkey-20160727-308bfbf.diff) Authors ------- - * Roberto E. Vargas Caballero - k0ga@shike2.com - * Laslo Hunhold - dev@frign.de (st-0.6, st-git-20150917 ports) + * Roberto E. Vargas Caballero - <k0ga@shike2.com> + * Laslo Hunhold - <dev@frign.de> (0.6, git ports) diff --git a/st.suckless.org/patches/externalpipe.md b/st.suckless.org/patches/externalpipe.md @@ -24,13 +24,13 @@ dmenu to select and open one: Download -------- -* [st-0.4.1-externalpipe.diff](st-0.4.1-externalpipe.diff) -* [st-0.5-externalpipe.diff](st-0.5-externalpipe.diff) -* [st-0.6-externalpipe.diff](st-0.6-externalpipe.diff) -* [st-git-20160204-externalpipe.diff](st-git-20160204-externalpipe.diff) +* [st-externalpipe-0.4.1.diff](st-externalpipe-0.4.1.diff) +* [st-externalpipe-0.5.diff](st-externalpipe-0.5.diff) +* [st-externalpipe-0.6.diff](st-externalpipe-0.6.diff) +* [st-externalpipe-20160727-308bfbf.diff](st-externalpipe-20160727-308bfbf.diff) Authors ------- - * Rob Pilling - robpilling@gmail.com - * Laslo Hunhold - dev@frign.de (st-0.4.1, st-0.5, st-0.6, st-git-20150917 ports) + * Rob Pilling - <robpilling@gmail.com> + * Laslo Hunhold - <dev@frign.de> (0.4.1, 0.5, 0.6, git ports) diff --git a/st.suckless.org/patches/hidecursor.md b/st.suckless.org/patches/hidecursor.md @@ -10,12 +10,12 @@ is moved in the terminal window. Download -------- -* [st-0.5-hidecursor.diff](st-0.5-hidecursor.diff) -* [st-0.6-hidecursor.diff](st-0.6-hidecursor.diff) -* [st-git-20150917-hidecursor.diff](st-git-20150917-hidecursor.diff) +* [st-hidecursor-0.5.diff](st-hidecursor-0.5.diff) +* [st-hidecursor-0.6.diff](st-hidecursor-0.6.diff) +* [st-hidecursor-20160727-308bfbf.diff](st-hidecursor-20160727-308bfbf.diff) -Author ------- +Authors +------- - * Ivan Delalande - colona@ycc.fr - * Laslo Hunhold - dev@frign.de (st-git-20150917 port) + * Ivan Delalande - <colona@ycc.fr> + * Laslo Hunhold - <dev@frign.de> (git port) diff --git a/st.suckless.org/patches/index.md b/st.suckless.org/patches/index.md @@ -1,4 +1,5 @@ -Patches -------- -Much like the [dwm patches](http://dwm.suckless.org/patches/) but for st. +patches +======= +For instructions on how to submit and format patches, take a look at +the [hacking guidelines](http://suckless.org/hacking). diff --git a/st.suckless.org/patches/openbsd.md b/st.suckless.org/patches/openbsd.md @@ -27,11 +27,11 @@ More information on this issue can be found in this Download -------- -* [st-git-20150920-openbsd.diff](st-git-20150920-openbsd.diff) +* [st-openbsd-20160727-308bfbf.diff](st-openbsd-20160727-308bfbf.diff) Authors ------- - * Nils Reuße - nilsreusse@gmail.com - * Laslo Hunhold - dev@frign.de (st-git-20150920 port) + * Nils Reuße - <nilsreusse@gmail.com> + * Laslo Hunhold - <dev@frign.de> (git port) diff --git a/st.suckless.org/patches/scrollback.md b/st.suckless.org/patches/scrollback.md @@ -9,12 +9,12 @@ Scroll back through terminal output using Shift+{PageUp, PageDown}. Download -------- -* [st-git-20151217-scrollback.diff](st-git-20151217-scrollback.diff) +* [st-scrollback-20160727-308bfbf.diff](st-scrollback-20160727-308bfbf.diff) Apply the following patch on top of the previous to allow scrolling using `Shift+MouseWheel`. -* [st-git-20151106-scrollback-mouse.diff](st-git-20151106-scrollback-mouse.diff) +* [st-scrollback-mouse-20160727-308bfbf.diff](st-scrollback-mouse-20160727-308bfbf.diff) Apply the following patch on top of the previous two to allow scrollback using mouse wheel only when not in `MODE_ALTSCREEN`. eg. The content is being @@ -22,14 +22,14 @@ scrolled instead of the scrollback buffer in `less`. Consequently the Shift modifier for scrolling is not needed anymore. **Note: It might break other mkeys excluding scrolling functions.** -* [st-git-20160203-scrollback-mouse-altscreen.diff](st-git-20160203-scrollback-mouse-altscreen.diff) +* [st-scrollback-mouse-altscreen-20160727-308bfbf.diff](st-scrollback-mouse-altscreen-20160727-308bfbf.diff) Authors ------- - * Jochen Sprickerhof - dwm@jochen.sprickerhof.de - * M Farkas-Dyck - strake888@gmail.com - * Ivan Tham - pickfire@riseup.net (mouse scrolling, st-git-20151122 port) - * Laslo Hunhold - dev@frign.de (unscrambling, st-git-20151106 port) - * Ori Bernstein - ori@eigenstate.org (fix memory bug, st-git-20151216 port) - * Matthias Schoth - mschoth@gmail.com (auto altscreen scrolling) + * Jochen Sprickerhof - <st@jochen.sprickerhof.de> + * M Farkas-Dyck - <strake888@gmail.com> + * Ivan Tham - <pickfire@riseup.net> (mouse scrolling) + * Ori Bernstein - <ori@eigenstate.org> (fix memory bug) + * Matthias Schoth - <mschoth@gmail.com> (auto altscreen scrolling) + * Laslo Hunhold - <dev@frign.de> (unscrambling, git port) diff --git a/st.suckless.org/patches/solarized.md b/st.suckless.org/patches/solarized.md @@ -32,27 +32,33 @@ Download To get correct colors, you first need to apply the following patch to disable lighting up bold colors. - * [st-0.5-no-bold-colors.diff](st-0.5-no-bold-colors.diff) - * [st-0.6-no-bold-colors.diff](st-0.6-no-bold-colors.diff) - * [st-git-20150917-no-bold-colors.diff](st-git-20150917-no-bold-colors.diff) + * [st-no_bold_colors-0.5.diff](st-no_bold_colors-0.5.diff) + * [st-no_bold_colors-0.6.diff](st-no_bold_colors-0.6.diff) + * [st-no_bold_colors-20160727-308bfbf.diff](st-no_bold_colors-20160727-308bfbf.diff) Choose one of the following patches to get either the light or the dark color scheme: *Light*: - * [st-0.5-solarized-light.diff](st-0.5-solarized-light.diff) - * [st-0.6-solarized-light.diff](st-0.6-solarized-light.diff) - * [st-git-20151119-solarized-light.diff](st-git-20151119-solarized-light.diff) + * [st-solarized-light-0.5.diff](st-solarized-light-0.5.diff) + * [st-solarized-light-0.6.diff](st-solarized-light-0.6.diff) + * [st-solarized-light-20160727-308bfbf.diff](st-solarized-light-20160727-308bfbf.diff) *Dark*: - * [st-0.5-solarized-dark.diff](st-0.5-solarized-dark.diff) - * [st-0.6-solarized-dark.diff](st-0.6-solarized-dark.diff) - * [st-git-20151119-solarized-dark.diff](st-git-20151119-solarized-dark.diff) + * [st-solarized-dark-0.5.diff](st-solarized-dark-0.5.diff) + * [st-solarized-dark-0.6.diff](st-solarized-dark-0.6.diff) + * [st-solarized-dark-20160727-308bfbf.diff](st-solarized-dark-20160727-308bfbf.diff) + +*Both (swap between light/dark with F6)*: + + * [st-solarized-both-20160709-528241a.diff](st-solarized-both-20160727-308bfbf.diff) + Authors ------- - * Nils Reuße - nilsreusse@gmail.com - * Laslo Hunhold - dev@frign.de (st-0.5, st-0.6, st-git-20150917 ports) + * Nils Reuße - <nilsreusse@gmail.com> + * Laslo Hunhold - <dev@frign.de> (0.5, 0.6, git ports) + * Ryan Roden-Corrent - <ryan@rcorre.net> (both) diff --git a/st.suckless.org/patches/spoiler.md b/st.suckless.org/patches/spoiler.md @@ -19,10 +19,11 @@ just like most normal unformatted text when selected. Download -------- - * [st-0.6-spoiler.diff](st-0.6-spoiler.diff) - * [st-git-20150922-spoiler.diff](st-git-20150922-spoiler.diff) + * [st-spoiler-0.6.diff](st-spoiler-0.6.diff) + * [st-spoiler-20160727-308bfbf.diff](st-spoiler-20160727-308bfbf.diff) Author ------ - * dequis - dx@dxzone.com.ar + * dequis - <dx@dxzone.com.ar> + * Laslo Hunhold - <dev@frign.de> (git port) diff --git a/st.suckless.org/patches/st-0.3-boldcolor.diff b/st.suckless.org/patches/st-0.3-boldcolor.diff @@ -1,52 +0,0 @@ -diff -r db4f3f0ef420 st.c ---- a/st.c Fri Nov 02 20:08:51 2012 +0100 -+++ b/st.c Sat Nov 03 00:19:19 2012 +0100 -@@ -2260,8 +2260,10 @@ - xw.cw = dc.font.width; - xw.ch = dc.font.height; - -+#ifndef NOBOLDFONT - FcPatternDel(pattern, FC_WEIGHT); - FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD); -+#endif - if(xloadfont(&dc.bfont, pattern)) - die("st: can't open font %s\n", fontstr); - -@@ -2397,6 +2399,10 @@ - /* greyscale */ - fg = &dc.xft_col[base.fg + 4]; - } -+#ifdef DEFAULTBOLD -+ if(base.fg == defaultfg) -+ fg = &dc.xft_col[DEFAULTBOLD]; -+#endif - /* - * Those ranges will not be brightened: - * 8 - 15 – bright system colors -@@ -2406,10 +2412,22 @@ - font = &dc.bfont; - } - -- if(base.mode & ATTR_ITALIC) -- font = &dc.ifont; -- if(base.mode & (ATTR_ITALIC|ATTR_ITALIC)) -- font = &dc.ibfont; -+ if(base.mode & ATTR_ITALIC) { -+ if(base.mode & ATTR_BOLD) { -+ font = &dc.ibfont; -+ } else { -+ font = &dc.ifont; -+#ifdef DEFAULTITALIC -+ if(base.fg == defaultfg) -+ fg = &dc.xft_col[DEFAULTITALIC]; -+#endif -+ } -+ } -+ -+#ifdef DEFAULTUNDERLINE -+ if((base.mode & ATTR_UNDERLINE) && base.fg == defaultfg) -+ fg = &dc.xft_col[DEFAULTUNDERLINE]; -+#endif - - if(IS_SET(MODE_REVERSE)) { - if(fg == &dc.xft_col[defaultfg]) { diff --git a/st.suckless.org/patches/st-0.3-wordbreak.diff b/st.suckless.org/patches/st-0.3-wordbreak.diff @@ -1,58 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 1ba6d8e..3ddbe10 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -13,7 +13,7 @@ static unsigned int tripleclicktimeout = 600; - static char termname[] = "st-256color"; - - static unsigned int tabspaces = 8; -- -+#define WORD_BREAK " " - - /* Terminal colors (16 first used in escape sequence) */ - static const char *colorname[] = { -diff --git a/st.c b/st.c -index 8e0df08..2998468 100644 ---- a/st.c -+++ b/st.c -@@ -279,6 +279,7 @@ typedef struct { - } DC; - - static void die(const char *, ...); -+static bool is_word_break(char); - static void draw(void); - static void redraw(void); - static void drawregion(int, int, int, int); -@@ -813,12 +814,12 @@ brelease(XEvent *e) { - /* double click to select word */ - sel.bx = sel.ex; - while(sel.bx > 0 && term.line[sel.ey][sel.bx-1].state & GLYPH_SET && -- term.line[sel.ey][sel.bx-1].c[0] != ' ') { -+ !is_word_break(term.line[sel.ey][sel.bx-1].c[0])) { - sel.bx--; - } - sel.b.x = sel.bx; - while(sel.ex < term.col-1 && term.line[sel.ey][sel.ex+1].state & GLYPH_SET && -- term.line[sel.ey][sel.ex+1].c[0] != ' ') { -+ !is_word_break(term.line[sel.ey][sel.ex+1].c[0])) { - sel.ex++; - } - sel.e.x = sel.ex; -@@ -866,6 +867,17 @@ die(const char *errstr, ...) { - exit(EXIT_FAILURE); - } - -+bool -+is_word_break(char c) { -+ static char *word_break = WORD_BREAK; -+ char *s = word_break; -+ while(*s) { -+ if(*s == c) return true; -+ s++; -+ } -+ return false; -+} -+ - void - execsh(void) { - char **args; diff --git a/st.suckless.org/patches/st-0.4-wordbreak.diff b/st.suckless.org/patches/st-0.4-wordbreak.diff @@ -1,58 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 693bdbd..cba3754 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -21,7 +21,7 @@ static unsigned int actionfps = 30; - static char termname[] = "st-256color"; - - static unsigned int tabspaces = 8; -- -+#define WORD_BREAK " " - - /* Terminal colors (16 first used in escape sequence) */ - static const char *colorname[] = { -diff --git a/st.c b/st.c -index 8b1fc56..8ed395c 100644 ---- a/st.c -+++ b/st.c -@@ -294,6 +294,7 @@ typedef struct { - } DC; - - static void die(const char *, ...); -+static bool is_word_break(char); - static void draw(void); - static void redraw(int); - static void drawregion(int, int, int, int); -@@ -920,12 +921,12 @@ brelease(XEvent *e) { - /* double click to select word */ - sel.bx = sel.ex; - while(sel.bx > 0 && term.line[sel.ey][sel.bx-1].state & GLYPH_SET && -- term.line[sel.ey][sel.bx-1].c[0] != ' ') { -+ !is_word_break(term.line[sel.ey][sel.bx-1].c[0])) { - sel.bx--; - } - sel.b.x = sel.bx; - while(sel.ex < term.col-1 && term.line[sel.ey][sel.ex+1].state & GLYPH_SET && -- term.line[sel.ey][sel.ex+1].c[0] != ' ') { -+ !is_word_break(term.line[sel.ey][sel.ex+1].c[0])) { - sel.ex++; - } - sel.e.x = sel.ex; -@@ -974,6 +975,17 @@ die(const char *errstr, ...) { - exit(EXIT_FAILURE); - } - -+bool -+is_word_break(char c) { -+ static char *word_break = WORD_BREAK; -+ char *s = word_break; -+ while(*s) { -+ if(*s == c) return true; -+ s++; -+ } -+ return false; -+} -+ - void - execsh(void) { - char **args; diff --git a/st.suckless.org/patches/st-0.4.1-externalpipe.diff b/st.suckless.org/patches/st-0.4.1-externalpipe.diff @@ -1,109 +0,0 @@ -diff --git a/st.c b/st.c -index 686ed5d..697cd43 100644 ---- a/st.c -+++ b/st.c -@@ -249,6 +249,7 @@ typedef union { - unsigned int ui; - float f; - const void *v; -+ const char *s; - } Arg; - - typedef struct { -@@ -263,6 +264,7 @@ static void clippaste(const Arg *); - static void numlock(const Arg *); - static void selpaste(const Arg *); - static void xzoom(const Arg *); -+static void externalpipe(const Arg *); - - /* Config.h for applying patches and the configuration. */ - #include "config.h" -@@ -1024,15 +1026,22 @@ execsh(void) { - void - sigchld(int a) { - int stat = 0; -+ pid_t r; - -- if(waitpid(pid, &stat, 0) < 0) -- die("Waiting for pid %hd failed: %s\n", pid, SERRNO); -+ r = wait(&stat); -+ if(r < 0) -+ die("wait(): %s\n", SERRNO); - -- if(WIFEXITED(stat)) { -- exit(WEXITSTATUS(stat)); -- } else { -- exit(EXIT_FAILURE); -+ if(r == pid){ -+ /* _the_ sub process */ -+ if(WIFEXITED(stat)) { -+ exit(WEXITSTATUS(stat)); -+ } else { -+ exit(EXIT_FAILURE); -+ } - } -+ -+ /* something else we've forked out */ - } - - void -@@ -2593,6 +2602,59 @@ xzoom(const Arg *arg) { - } - - void -+externalpipe(const Arg *arg) -+{ -+ int to[2]; /* 0 = read, 1 = write */ -+ pid_t child; -+ int y, x; -+ void (*oldsigpipe)(int); -+ -+ if(pipe(to) == -1) -+ return; -+ -+ /* sigchld() handles this */ -+ switch((child = fork())){ -+ case -1: -+ close(to[0]), close(to[1]); -+ return; -+ case 0: -+ /* child */ -+ close(to[1]); -+ dup2(to[0], STDIN_FILENO); /* 0<&to */ -+ close(to[0]); -+ execvp( -+ "sh", -+ (char *const []){ -+ "/bin/sh", -+ "-c", -+ (char *)arg->s, -+ 0 -+ }); -+ exit(127); -+ } -+ -+ /* parent */ -+ close(to[0]); -+ /* ignore sigpipe for now, in case child exits early */ -+ oldsigpipe = signal(SIGPIPE, SIG_IGN); -+ -+ for(y = 0; y < term.row; y++){ -+ for(x = 0; x < term.col; x++){ -+ if(write(to[1], term.line[y][x].c, 1) == -1) -+ goto done; -+ } -+ if(write(to[1], "\n", 1) == -1) -+ break; -+ } -+ -+done: -+ close(to[1]); -+ -+ /* restore */ -+ signal(SIGPIPE, oldsigpipe); -+} -+ -+void - xinit(void) { - XSetWindowAttributes attrs; - XGCValues gcvalues; diff --git a/st.suckless.org/patches/st-0.4.1-wordbreak.diff b/st.suckless.org/patches/st-0.4.1-wordbreak.diff @@ -1,57 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index d1c20bd..d8db06d 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -24,7 +24,7 @@ static unsigned int actionfps = 30; - static char termname[] = "st-256color"; - - static unsigned int tabspaces = 8; -- -+#define WORD_BREAK " " - - /* Terminal colors (16 first used in escape sequence) */ - static const char *colorname[] = { -diff --git a/st.c b/st.c -index 686ed5d..4f5bb05 100644 ---- a/st.c -+++ b/st.c -@@ -288,6 +288,7 @@ typedef struct { - } DC; - - static void die(const char *, ...); -+static bool is_word_break(char); - static void draw(void); - static void redraw(int); - static void drawregion(int, int, int, int); -@@ -933,11 +934,11 @@ brelease(XEvent *e) { - } else if(TIMEDIFF(now, sel.tclick1) <= doubleclicktimeout) { - /* double click to select word */ - sel.bx = sel.ex; -- while(sel.bx > 0 && term.line[sel.ey][sel.bx-1].c[0] != ' ') { -+ while(sel.bx > 0 && !is_word_break(term.line[sel.ey][sel.bx-1].c[0])) { - sel.bx--; - } - sel.b.x = sel.bx; -- while(sel.ex < term.col-1 && term.line[sel.ey][sel.ex+1].c[0] != ' ') { -+ while(sel.ex < term.col-1 && !is_word_break(term.line[sel.ey][sel.ex+1].c[0])) { - sel.ex++; - } - sel.e.x = sel.ex; -@@ -986,6 +987,17 @@ die(const char *errstr, ...) { - exit(EXIT_FAILURE); - } - -+bool -+is_word_break(char c) { -+ static char *word_break = WORD_BREAK; -+ char *s = word_break; -+ while(*s) { -+ if(*s == c) return true; -+ s++; -+ } -+ return false; -+} -+ - void - execsh(void) { - char **args; diff --git a/st.suckless.org/patches/st-0.5-argbbg.diff b/st.suckless.org/patches/st-0.5-argbbg.diff @@ -1,169 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 58b470e..ce34f55 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -48,6 +48,8 @@ static char termname[] = "st-256color"; - - static unsigned int tabspaces = 8; - -+/* background opacity */ -+static const int alpha = 0xdd; - - /* Terminal colors (16 first used in escape sequence) */ - static const char *colorname[] = { -@@ -75,6 +77,7 @@ static const char *colorname[] = { - - /* more colors can be added after 255 to use with DefaultXX */ - "#cccccc", -+ "black", - }; - - -@@ -83,7 +86,7 @@ static const char *colorname[] = { - * foreground, background, cursor - */ - static unsigned int defaultfg = 7; --static unsigned int defaultbg = 0; -+static unsigned int defaultbg = 257; - static unsigned int defaultcs = 256; - - /* -diff --git a/config.mk b/config.mk -index 97afa2c..18aec14 100644 ---- a/config.mk -+++ b/config.mk -@@ -14,7 +14,7 @@ X11LIB = /usr/X11R6/lib - INCS = -I. -I/usr/include -I${X11INC} \ - `pkg-config --cflags fontconfig` \ - `pkg-config --cflags freetype2` --LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -lutil -lXext -lXft \ -+LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -lutil -lXext -lXft -lXrender \ - `pkg-config --libs fontconfig` \ - `pkg-config --libs freetype2` - -diff --git a/st.c b/st.c -index 392f12d..5b05a5f 100644 ---- a/st.c -+++ b/st.c -@@ -65,6 +65,7 @@ char *argv0; - #define XK_ANY_MOD UINT_MAX - #define XK_NO_MOD 0 - #define XK_SWITCH_MOD (1<<13) -+#define OPAQUE 0Xff - - #define REDRAW_TIMEOUT (80*1000) /* 80 ms */ - -@@ -79,6 +80,7 @@ char *argv0; - #define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || (a).bg != (b).bg) - #define IS_SET(flag) ((term.mode & (flag)) != 0) - #define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + (t1.tv_usec-t2.tv_usec)/1000) -+#define USE_ARGB (alpha != OPAQUE && opt_embed == NULL) - #define CEIL(x) (((x) != (int) (x)) ? (x) + 1 : (x)) - - #define TRUECOLOR(r,g,b) (1 << 24 | (r) << 16 | (g) << 8 | (b)) -@@ -255,6 +257,7 @@ typedef struct { - int w, h; /* window width and height */ - int ch; /* char height */ - int cw; /* char width */ -+ int depth; /* bit depth */ - char state; /* focus, redraw, visible */ - } XWindow; - -@@ -2706,8 +2709,7 @@ xresize(int col, int row) { - xw.th = MAX(1, row * xw.ch); - - XFreePixmap(xw.dpy, xw.buf); -- xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h, -- DefaultDepth(xw.dpy, xw.scr)); -+ xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h, xw.depth); - XftDrawChange(xw.draw, xw.buf); - xclear(0, 0, xw.w, xw.h); - } -@@ -2738,6 +2740,13 @@ xloadcols(void) { - } - } - -+ /* set alpha value of bg color */ -+ if (USE_ARGB) { -+ dc.col[defaultbg].color.alpha = (0xffff * alpha) / OPAQUE; //0xcccc; -+ dc.col[defaultbg].pixel &= 0x00111111; -+ dc.col[defaultbg].pixel |= alpha << 24; // 0xcc000000; -+ } -+ - /* load colors [16-255] ; same colors as xterm */ - for(i = 16, r = 0; r < 6; r++) { - for(g = 0; g < 6; g++) { -@@ -2992,7 +3001,38 @@ xinit(void) { - if(!(xw.dpy = XOpenDisplay(NULL))) - die("Can't open display\n"); - xw.scr = XDefaultScreen(xw.dpy); -- xw.vis = XDefaultVisual(xw.dpy, xw.scr); -+ xw.depth = (USE_ARGB)? 32: XDefaultDepth(xw.dpy, xw.scr); -+ if (! USE_ARGB) -+ xw.vis = XDefaultVisual(xw.dpy, xw.scr); -+ else { -+ XVisualInfo *vis; -+ XRenderPictFormat *fmt; -+ int nvi; -+ int i; -+ -+ XVisualInfo tpl = { -+ .screen = xw.scr, -+ .depth = 32, -+ .class = TrueColor -+ }; -+ -+ vis = XGetVisualInfo(xw.dpy, VisualScreenMask | VisualDepthMask | VisualClassMask, &tpl, &nvi); -+ xw.vis = NULL; -+ for(i = 0; i < nvi; i ++) { -+ fmt = XRenderFindVisualFormat(xw.dpy, vis[i].visual); -+ if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) { -+ xw.vis = vis[i].visual; -+ break; -+ } -+ } -+ -+ XFree(vis); -+ -+ if (! xw.vis) { -+ fprintf(stderr, "Couldn't find ARGB visual.\n"); -+ exit(1); -+ } -+ } - - /* font */ - if(!FcInit()) -@@ -3002,7 +3042,10 @@ xinit(void) { - xloadfonts(usedfont, 0); - - /* colors */ -- xw.cmap = XDefaultColormap(xw.dpy, xw.scr); -+ if (! USE_ARGB) -+ xw.cmap = XDefaultColormap(xw.dpy, xw.scr); -+ else -+ xw.cmap = XCreateColormap(xw.dpy, XRootWindow(xw.dpy, xw.scr), xw.vis, None); - xloadcols(); - - /* adjust fixed window geometry */ -@@ -3036,16 +3079,17 @@ xinit(void) { - parent = opt_embed ? strtol(opt_embed, NULL, 0) : \ - XRootWindow(xw.dpy, xw.scr); - xw.win = XCreateWindow(xw.dpy, parent, xw.fx, xw.fy, -- xw.w, xw.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput, -+ xw.w, xw.h, 0, xw.depth, InputOutput, - xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity - | CWEventMask | CWColormap, &xw.attrs); - - memset(&gcvalues, 0, sizeof(gcvalues)); - gcvalues.graphics_exposures = False; -- dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures, -+ xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h, xw.depth); -+ dc.gc = XCreateGC(xw.dpy, -+ (USE_ARGB)? xw.buf: parent, -+ GCGraphicsExposures, - &gcvalues); -- xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h, -- DefaultDepth(xw.dpy, xw.scr)); - XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel); - XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, xw.w, xw.h); - diff --git a/st.suckless.org/patches/st-0.5-externalpipe.diff b/st.suckless.org/patches/st-0.5-externalpipe.diff @@ -1,109 +0,0 @@ -diff --git a/st.c b/st.c -index 392f12d..31660c8 100644 ---- a/st.c -+++ b/st.c -@@ -301,6 +301,7 @@ typedef union { - unsigned int ui; - float f; - const void *v; -+ const char *s; - } Arg; - - typedef struct { -@@ -315,6 +316,7 @@ static void clippaste(const Arg *); - static void numlock(const Arg *); - static void selpaste(const Arg *); - static void xzoom(const Arg *); -+static void externalpipe(const Arg *); - static void printsel(const Arg *); - static void printscreen(const Arg *) ; - static void toggleprinter(const Arg *); -@@ -1179,15 +1181,22 @@ execsh(void) { - void - sigchld(int a) { - int stat = 0; -+ pid_t r; - -- if(waitpid(pid, &stat, 0) < 0) -- die("Waiting for pid %hd failed: %s\n", pid, SERRNO); -+ r = wait(&stat); -+ if(r < 0) -+ die("wait(): %s\n", strerror(errno)); - -- if(WIFEXITED(stat)) { -- exit(WEXITSTATUS(stat)); -- } else { -- exit(EXIT_FAILURE); -+ if(r == pid){ -+ /* _the_ sub process */ -+ if(WIFEXITED(stat)) { -+ exit(WEXITSTATUS(stat)); -+ } else { -+ exit(EXIT_FAILURE); -+ } - } -+ -+ /* something else we've forked out */ - } - - void -@@ -2982,6 +2991,59 @@ xzoom(const Arg *arg) { - } - - void -+externalpipe(const Arg *arg) -+{ -+ int to[2]; /* 0 = read, 1 = write */ -+ pid_t child; -+ int y, x; -+ void (*oldsigpipe)(int); -+ -+ if(pipe(to) == -1) -+ return; -+ -+ /* sigchld() handles this */ -+ switch((child = fork())){ -+ case -1: -+ close(to[0]), close(to[1]); -+ return; -+ case 0: -+ /* child */ -+ close(to[1]); -+ dup2(to[0], STDIN_FILENO); /* 0<&to */ -+ close(to[0]); -+ execvp( -+ "sh", -+ (char *const []){ -+ "/bin/sh", -+ "-c", -+ (char *)arg->s, -+ 0 -+ }); -+ exit(127); -+ } -+ -+ /* parent */ -+ close(to[0]); -+ /* ignore sigpipe for now, in case child exits early */ -+ oldsigpipe = signal(SIGPIPE, SIG_IGN); -+ -+ for(y = 0; y < term.row; y++){ -+ for(x = 0; x < term.col; x++){ -+ if(write(to[1], term.line[y][x].c, 1) == -1) -+ goto done; -+ } -+ if(write(to[1], "\n", 1) == -1) -+ break; -+ } -+ -+done: -+ close(to[1]); -+ -+ /* restore */ -+ signal(SIGPIPE, oldsigpipe); -+} -+ -+void - xinit(void) { - XGCValues gcvalues; - Cursor cursor; diff --git a/st.suckless.org/patches/st-0.5-hidecursor.diff b/st.suckless.org/patches/st-0.5-hidecursor.diff @@ -1,82 +0,0 @@ -diff --git a/st.c b/st.c -index 392f12d..52deb92 100644 ---- a/st.c -+++ b/st.c -@@ -248,6 +248,8 @@ typedef struct { - Draw draw; - Visual *vis; - XSetWindowAttributes attrs; -+ Cursor cursor, bcursor; /* visible and blank cursors */ -+ bool cursorstate; /* is cursor currently visible */ - int scr; - bool isfixed; /* is fixed geometry? */ - int fx, fy, fw, fh; /* fixed geometry */ -@@ -1112,6 +1114,13 @@ void - bmotion(XEvent *e) { - int oldey, oldex, oldsby, oldsey; - -+ if(!xw.cursorstate) { -+ XDefineCursor(xw.dpy, xw.win, xw.cursor); -+ xw.cursorstate = true; -+ if(!IS_SET(MODE_MOUSEMANY)) -+ xsetpointermotion(0); -+ } -+ - if(IS_SET(MODE_MOUSE)) { - mousereport(e); - return; -@@ -2984,10 +2993,12 @@ xzoom(const Arg *arg) { - void - xinit(void) { - XGCValues gcvalues; -- Cursor cursor; - Window parent; - int sw, sh; - pid_t thispid = getpid(); -+ XColor xcwhite = {.red = 0xffff, .green = 0xffff, .blue = 0xffff}; -+ XColor xcblack = {.red = 0x0000, .green = 0x0000, .blue = 0x0000}; -+ Pixmap blankpm; - - if(!(xw.dpy = XOpenDisplay(NULL))) - die("Can't open display\n"); -@@ -3071,11 +3082,13 @@ xinit(void) { - die("XCreateIC failed. Could not obtain input method.\n"); - - /* white cursor, black outline */ -- cursor = XCreateFontCursor(xw.dpy, XC_xterm); -- XDefineCursor(xw.dpy, xw.win, cursor); -- XRecolorCursor(xw.dpy, cursor, -- &(XColor){.red = 0xffff, .green = 0xffff, .blue = 0xffff}, -- &(XColor){.red = 0x0000, .green = 0x0000, .blue = 0x0000}); -+ xw.cursor = XCreateFontCursor(xw.dpy, XC_xterm); -+ XDefineCursor(xw.dpy, xw.win, xw.cursor); -+ XRecolorCursor(xw.dpy, xw.cursor, &xcwhite, &xcblack); -+ xw.cursorstate = true; -+ blankpm = XCreateBitmapFromData(xw.dpy, xw.win, &(char){0}, 1, 1); -+ xw.bcursor = XCreatePixmapCursor(xw.dpy, blankpm, blankpm, -+ &xcblack, &xcblack, 0, 0); - - xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False); - xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False); -@@ -3537,6 +3550,8 @@ unmap(XEvent *ev) { - - void - xsetpointermotion(int set) { -+ if(!set && !xw.cursorstate) -+ return; - MODBIT(xw.attrs.event_mask, set, PointerMotionMask); - XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs); - } -@@ -3630,6 +3645,12 @@ kpress(XEvent *ev) { - Status status; - Shortcut *bp; - -+ if(xw.cursorstate) { -+ XDefineCursor(xw.dpy, xw.win, xw.bcursor); -+ xsetpointermotion(1); -+ xw.cursorstate = false; -+ } -+ - if(IS_SET(MODE_KBDLOCK)) - return; - diff --git a/st.suckless.org/patches/st-0.5-no-bold-colors.diff b/st.suckless.org/patches/st-0.5-no-bold-colors.diff @@ -1,13 +0,0 @@ -diff --git a/st.c b/st.c -index 392f12d..f893147 100644 ---- a/st.c -+++ b/st.c -@@ -3152,7 +3152,7 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { - if(base.mode & ATTR_BOLD) { - if(BETWEEN(base.fg, 0, 7)) { - /* basic system colors */ -- fg = &dc.col[base.fg + 8]; -+ fg = &dc.col[base.fg]; - } else if(BETWEEN(base.fg, 16, 195)) { - /* 256 colors */ - fg = &dc.col[base.fg + 36]; diff --git a/st.suckless.org/patches/st-0.5-solarized-dark.diff b/st.suckless.org/patches/st-0.5-solarized-dark.diff @@ -1,65 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 58b470e..f1c5ed1 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -51,30 +51,23 @@ static unsigned int tabspaces = 8; - - /* Terminal colors (16 first used in escape sequence) */ - static const char *colorname[] = { -- /* 8 normal colors */ -- "black", -- "red3", -- "green3", -- "yellow3", -- "blue2", -- "magenta3", -- "cyan3", -- "gray90", -- -- /* 8 bright colors */ -- "gray50", -- "red", -- "green", -- "yellow", -- "#5c5cff", -- "magenta", -- "cyan", -- "white", -- -- [255] = 0, -- -- /* more colors can be added after 255 to use with DefaultXX */ -- "#cccccc", -+ /* solarized dark */ -+ "#073642", /* 0: black */ -+ "#dc322f", /* 1: red */ -+ "#859900", /* 2: green */ -+ "#b58900", /* 3: yellow */ -+ "#268bd2", /* 4: blue */ -+ "#d33682", /* 5: magenta */ -+ "#2aa198", /* 6: cyan */ -+ "#eee8d5", /* 7: white */ -+ "#002b36", /* 8: brblack */ -+ "#cb4b16", /* 9: brred */ -+ "#586e75", /* 10: brgreen */ -+ "#657b83", /* 11: bryellow */ -+ "#839496", /* 12: brblue */ -+ "#6c71c4", /* 13: brmagenta*/ -+ "#93a1a1", /* 14: brcyan */ -+ "#fdf6e3", /* 15: brwhite */ - }; - - -@@ -82,9 +75,9 @@ static const char *colorname[] = { - * Default colors (colorname index) - * foreground, background, cursor - */ --static unsigned int defaultfg = 7; --static unsigned int defaultbg = 0; --static unsigned int defaultcs = 256; -+static unsigned int defaultfg = 12; -+static unsigned int defaultbg = 8; -+static unsigned int defaultcs = 14; - - /* - * Colors used, when the specific fg == defaultfg. So in reverse mode this diff --git a/st.suckless.org/patches/st-0.5-solarized-light.diff b/st.suckless.org/patches/st-0.5-solarized-light.diff @@ -1,65 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 58b470e..ec39cca 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -51,30 +51,23 @@ static unsigned int tabspaces = 8; - - /* Terminal colors (16 first used in escape sequence) */ - static const char *colorname[] = { -- /* 8 normal colors */ -- "black", -- "red3", -- "green3", -- "yellow3", -- "blue2", -- "magenta3", -- "cyan3", -- "gray90", -- -- /* 8 bright colors */ -- "gray50", -- "red", -- "green", -- "yellow", -- "#5c5cff", -- "magenta", -- "cyan", -- "white", -- -- [255] = 0, -- -- /* more colors can be added after 255 to use with DefaultXX */ -- "#cccccc", -+ /* solarized light */ -+ "#eee8d5", /* 0: black */ -+ "#dc322f", /* 1: red */ -+ "#859900", /* 2: green */ -+ "#b58900", /* 3: yellow */ -+ "#268bd2", /* 4: blue */ -+ "#d33682", /* 5: magenta */ -+ "#2aa198", /* 6: cyan */ -+ "#073642", /* 7: white */ -+ "#fdf6e3", /* 8: brblack */ -+ "#cb4b16", /* 9: brred */ -+ "#93a1a1", /* 10: brgreen */ -+ "#839496", /* 11: bryellow */ -+ "#657b83", /* 12: brblue */ -+ "#6c71c4", /* 13: brmagenta*/ -+ "#586e75", /* 14: brcyan */ -+ "#002b36", /* 15: brwhite */ - }; - - -@@ -82,9 +75,9 @@ static const char *colorname[] = { - * Default colors (colorname index) - * foreground, background, cursor - */ --static unsigned int defaultfg = 7; --static unsigned int defaultbg = 0; --static unsigned int defaultcs = 256; -+static unsigned int defaultfg = 12; -+static unsigned int defaultbg = 8; -+static unsigned int defaultcs = 14; - - /* - * Colors used, when the specific fg == defaultfg. So in reverse mode this diff --git a/st.suckless.org/patches/st-0.5-wordbreak.diff b/st.suckless.org/patches/st-0.5-wordbreak.diff @@ -1,52 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 58b470e..8a8d968 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -47,7 +47,7 @@ static int bellvolume = 0; - static char termname[] = "st-256color"; - - static unsigned int tabspaces = 8; -- -+#define WORD_BREAK " " - - /* Terminal colors (16 first used in escape sequence) */ - static const char *colorname[] = { -diff --git a/st.c b/st.c -index 392f12d..6a32d03 100644 ---- a/st.c -+++ b/st.c -@@ -343,6 +343,7 @@ typedef struct { - } DC; - - static void die(const char *, ...); -+static bool is_word_break(char); - static void draw(void); - static void redraw(int); - static void drawregion(int, int, int, int); -@@ -751,7 +752,7 @@ selsnap(int mode, int *x, int *y, int direction) { - */ - if(direction > 0) { - i = term.col; -- while(--i > 0 && term.line[*y][i].c[0] == ' ') -+ while(--i > 0 && is_word_break(term.line[*y][i].c[0])) - /* nothing */; - if(i > 0 && i < *x) - *x = term.col - 1; -@@ -1141,6 +1142,17 @@ die(const char *errstr, ...) { - exit(EXIT_FAILURE); - } - -+bool -+is_word_break(char c) { -+ static char *word_break = WORD_BREAK; -+ char *s = word_break; -+ while(*s) { -+ if(*s == c) return true; -+ s++; -+ } -+ return false; -+} -+ - void - execsh(void) { - char **args; diff --git a/st.suckless.org/patches/st-0.6-argbbg.diff b/st.suckless.org/patches/st-0.6-argbbg.diff @@ -1,170 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 64e75b8..9a27c14 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -58,6 +58,8 @@ static char termname[] = "st-256color"; - - static unsigned int tabspaces = 8; - -+/* bg opacity */ -+static const int alpha = 0xdd; - - /* Terminal colors (16 first used in escape sequence) */ - static const char *colorname[] = { -@@ -85,6 +87,7 @@ static const char *colorname[] = { - - /* more colors can be added after 255 to use with DefaultXX */ - "#cccccc", -+ "black", - }; - - -@@ -93,7 +96,7 @@ static const char *colorname[] = { - * foreground, background, cursor - */ - static unsigned int defaultfg = 7; --static unsigned int defaultbg = 0; -+static unsigned int defaultbg = 257; - static unsigned int defaultcs = 256; - - /* -diff --git a/config.mk b/config.mk -index 67844dc..005b1c6 100644 ---- a/config.mk -+++ b/config.mk -@@ -14,7 +14,7 @@ X11LIB = /usr/X11R6/lib - INCS = -I. -I/usr/include -I${X11INC} \ - `pkg-config --cflags fontconfig` \ - `pkg-config --cflags freetype2` --LIBS = -L/usr/lib -lc -L${X11LIB} -lm -lrt -lX11 -lutil -lXext -lXft \ -+LIBS = -L/usr/lib -lc -L${X11LIB} -lm -lrt -lX11 -lutil -lXext -lXft -lXrender\ - `pkg-config --libs fontconfig` \ - `pkg-config --libs freetype2` - -diff --git a/st.c b/st.c -index b89d094..d212134 100644 ---- a/st.c -+++ b/st.c -@@ -61,6 +61,7 @@ char *argv0; - #define XK_ANY_MOD UINT_MAX - #define XK_NO_MOD 0 - #define XK_SWITCH_MOD (1<<13) -+#define OPAQUE 0Xff - - /* macros */ - #define MIN(a, b) ((a) < (b) ? (a) : (b)) -@@ -77,6 +78,7 @@ char *argv0; - #define IS_SET(flag) ((term.mode & (flag)) != 0) - #define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + (t1.tv_nsec-t2.tv_nsec)/1E6) - #define MODBIT(x, set, bit) ((set) ? ((x) |= (bit)) : ((x) &= ~(bit))) -+#define USE_ARGB (alpha != OPAQUE && opt_embed == NULL) - - #define TRUECOLOR(r,g,b) (1 << 24 | (r) << 16 | (g) << 8 | (b)) - #define IS_TRUECOL(x) (1 << 24 & (x)) -@@ -265,6 +267,7 @@ typedef struct { - int w, h; /* window width and height */ - int ch; /* char height */ - int cw; /* char width */ -+ int depth; /* bit depth */ - char state; /* focus, redraw, visible */ - int cursor; /* cursor style */ - } XWindow; -@@ -2895,8 +2898,7 @@ xresize(int col, int row) { - xw.th = MAX(1, row * xw.ch); - - XFreePixmap(xw.dpy, xw.buf); -- xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h, -- DefaultDepth(xw.dpy, xw.scr)); -+ xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h, xw.depth); - XftDrawChange(xw.draw, xw.buf); - xclear(0, 0, xw.w, xw.h); - } -@@ -2946,6 +2948,14 @@ xloadcols(void) { - else - die("Could not allocate color %d\n", i); - } -+ -+ /* set alpha value of bg color */ -+ if (USE_ARGB) { -+ dc.col[defaultbg].color.alpha = (0xffff * alpha) / OPAQUE; //0xcccc; -+ dc.col[defaultbg].pixel &= 0x00111111; -+ dc.col[defaultbg].pixel |= alpha << 24; // 0xcc000000; -+ } -+ - loaded = true; - } - -@@ -3189,7 +3199,38 @@ xinit(void) { - if(!(xw.dpy = XOpenDisplay(NULL))) - die("Can't open display\n"); - xw.scr = XDefaultScreen(xw.dpy); -- xw.vis = XDefaultVisual(xw.dpy, xw.scr); -+ xw.depth = (USE_ARGB) ? 32: XDefaultDepth(xw.dpy, xw.scr); -+ if (! USE_ARGB) -+ xw.vis = XDefaultVisual(xw.dpy, xw.scr); -+ else { -+ XVisualInfo *vis; -+ XRenderPictFormat *fmt; -+ int nvi; -+ int i; -+ -+ XVisualInfo tpl = { -+ .screen = xw.scr, -+ .depth = 32, -+ .class = TrueColor -+ }; -+ -+ vis = XGetVisualInfo(xw.dpy, VisualScreenMask | VisualDepthMask | VisualClassMask, &tpl, &nvi); -+ xw.vis = NULL; -+ for(i = 0; i < nvi; i ++) { -+ fmt = XRenderFindVisualFormat(xw.dpy, vis[i].visual); -+ if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) { -+ xw.vis = vis[i].visual; -+ break; -+ } -+ } -+ -+ XFree(vis); -+ -+ if (! xw.vis) { -+ fprintf(stderr, "Couldn't find ARGB visual.\n"); -+ exit(1); -+ } -+ } - - /* font */ - if(!FcInit()) -@@ -3199,7 +3240,10 @@ xinit(void) { - xloadfonts(usedfont, 0); - - /* colors */ -- xw.cmap = XDefaultColormap(xw.dpy, xw.scr); -+ if (! USE_ARGB) -+ xw.cmap = XDefaultColormap(xw.dpy, xw.scr); -+ else -+ xw.cmap = XCreateColormap(xw.dpy, XRootWindow(xw.dpy, xw.scr), xw.vis, None); - xloadcols(); - - /* adjust fixed window geometry */ -@@ -3222,16 +3266,17 @@ xinit(void) { - if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) - parent = XRootWindow(xw.dpy, xw.scr); - xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t, -- xw.w, xw.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput, -+ xw.w, xw.h, 0, xw.depth, InputOutput, - xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity - | CWEventMask | CWColormap, &xw.attrs); - - memset(&gcvalues, 0, sizeof(gcvalues)); - gcvalues.graphics_exposures = False; -- dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures, -+ xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h, xw.depth); -+ dc.gc = XCreateGC(xw.dpy, -+ (USE_ARGB)? xw.buf: parent, -+ GCGraphicsExposures, - &gcvalues); -- xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h, -- DefaultDepth(xw.dpy, xw.scr)); - XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel); - XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, xw.w, xw.h); - diff --git a/st.suckless.org/patches/st-0.6-clipboard.diff b/st.suckless.org/patches/st-0.6-clipboard.diff @@ -1,13 +0,0 @@ -diff --git a/st.c b/st.c -index b89d094..6658e6a 100644 ---- a/st.c -+++ b/st.c -@@ -1155,6 +1155,8 @@ xsetsel(char *str, Time t) { - XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t); - if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win) - selclear(0); -+ -+ clipcopy(NULL); - } - - void diff --git a/st.suckless.org/patches/st-0.6-copyurl.diff b/st.suckless.org/patches/st-0.6-copyurl.diff @@ -1,88 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 64e75b8..c3d4e88 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -128,6 +128,7 @@ static Shortcut shortcuts[] = { - { MODKEY|ShiftMask, XK_C, clipcopy, {.i = 0} }, - { MODKEY|ShiftMask, XK_V, clippaste, {.i = 0} }, - { MODKEY, XK_Num_Lock, numlock, {.i = 0} }, -+ { MODKEY, XK_l, copyurl, {.i = 0} }, - }; - - /* -diff --git a/st.c b/st.c -index b89d094..dafd5ba 100644 ---- a/st.c -+++ b/st.c -@@ -332,6 +332,7 @@ static void xzoomreset(const Arg *); - static void printsel(const Arg *); - static void printscreen(const Arg *) ; - static void toggleprinter(const Arg *); -+static void copyurl(const Arg *); - - /* Config.h for applying patches and the configuration. */ - #include "config.h" -@@ -4080,3 +4081,63 @@ run: - return 0; - } - -+/* select and copy the previous url on screen (do nothing if there's no url). -+ * known bug: doesn't handle urls that span multiple lines (wontfix) -+ * known bug: only finds first url on line (mightfix) -+ */ -+void -+copyurl(const Arg *arg) { -+ /* () and [] can appear in urls, but excluding them here will reduce false -+ * positives when figuring out where a given url ends. -+ */ -+ static char URLCHARS[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" -+ "abcdefghijklmnopqrstuvwxyz" -+ "0123456789-._~:/?#@!$&'*+,;=%"; -+ -+ int i, row, startrow; -+ char *linestr = calloc(sizeof(char), term.col+1); /* assume ascii */ -+ char *c, *match = NULL; -+ -+ row = (sel.ob.x >= 0 && sel.nb.y > 0) ? sel.nb.y-1 : term.bot; -+ LIMIT(row, term.top, term.bot); -+ startrow = row; -+ -+ /* find the start of the last url before selection */ -+ do { -+ for (i = 0; i < term.col; ++i) { -+ if (term.line[row][i].u > 127) /* assume ascii */ -+ continue; -+ linestr[i] = term.line[row][i].u; -+ } -+ linestr[term.col] = '\0'; -+ if ((match = strstr(linestr, "http://")) -+ || (match = strstr(linestr, "https://"))) -+ break; -+ if (--row < term.top) -+ row = term.bot; -+ } while (row != startrow); -+ -+ if (match) { -+ /* must happen before trim */ -+ selclear(NULL); -+ sel.ob.x = strlen(linestr) - strlen(match); -+ -+ /* trim the rest of the line from the url match */ -+ for (c = match; *c != '\0'; ++c) -+ if (!strchr(URLCHARS, *c)) { -+ *c = '\0'; -+ break; -+ } -+ -+ /* select and copy */ -+ sel.mode = 1; -+ sel.type = SEL_REGULAR; -+ sel.oe.x = sel.ob.x + strlen(match)-1; -+ sel.ob.y = sel.oe.y = row; -+ selnormalize(); -+ tsetdirt(sel.nb.y, sel.ne.y); -+ selcopy(0); -+ } -+ -+ free(linestr); -+} diff --git a/st.suckless.org/patches/st-0.6-delkey.diff b/st.suckless.org/patches/st-0.6-delkey.diff @@ -1,45 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 64e75b8..0811af4 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -211,7 +211,7 @@ static Key key[] = { - { XK_KP_Delete, ShiftMask, "\033[2K", -1, 0, 0}, - { XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0, 0}, - { XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0, 0}, -- { XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0, 0}, -+ { XK_KP_Delete, XK_ANY_MOD, "\177", +1, 0, 0}, - { XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0, 0}, - { XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0, 0}, - { XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0, 0}, -@@ -266,8 +266,7 @@ static Key key[] = { - { XK_Delete, ShiftMask, "\033[2K", -1, 0, 0}, - { XK_Delete, ShiftMask, "\033[3;2~", +1, 0, 0}, - { XK_Delete, XK_ANY_MOD, "\033[P", -1, 0, 0}, -- { XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0, 0}, -- { XK_BackSpace, XK_NO_MOD, "\177", 0, 0, 0}, -+ { XK_Delete, XK_ANY_MOD, "\177", +1, 0, 0}, - { XK_Home, ShiftMask, "\033[2J", 0, -1, 0}, - { XK_Home, ShiftMask, "\033[1;2H", 0, +1, 0}, - { XK_Home, XK_ANY_MOD, "\033[H", 0, -1, 0}, -diff --git a/st.info b/st.info -index 2acd8b2..21b4734 100644 ---- a/st.info -+++ b/st.info -@@ -53,7 +53,7 @@ st| simpleterm, - ka3=\E[5~, - kc1=\E[4~, - kc3=\E[6~, -- kbs=\177, -+ kbs=\010, - kcbt=\E[Z, - kb2=\EOu, - kcub1=\EOD, -@@ -73,7 +73,7 @@ st| simpleterm, - kri=\E[1;2A, - kclr=\E[3;5~, - kdl1=\E[3;2~, -- kdch1=\E[3~, -+ kdch1=\177~, - kich1=\E[2~, - kend=\E[4~, - kf1=\EOP, diff --git a/st.suckless.org/patches/st-0.6-externalpipe.diff b/st.suckless.org/patches/st-0.6-externalpipe.diff @@ -1,75 +0,0 @@ -diff --git a/st.c b/st.c -index b89d094..124ed16 100644 ---- a/st.c -+++ b/st.c -@@ -326,6 +326,7 @@ static void clipcopy(const Arg *); - static void clippaste(const Arg *); - static void numlock(const Arg *); - static void selpaste(const Arg *); -+static void externalpipe(const Arg *); - static void xzoom(const Arg *); - static void xzoomabs(const Arg *); - static void xzoomreset(const Arg *); -@@ -2684,6 +2685,62 @@ eschandle(uchar ascii) { - } - - void -+externalpipe(const Arg *arg) -+{ -+ int to[2]; /* 0 = read, 1 = write */ -+ pid_t child; -+ int n; -+ void (*oldsigpipe)(int); -+ char buf[UTF_SIZ]; -+ Glyph *bp, *end; -+ -+ if(pipe(to) == -1) -+ return; -+ -+ /* sigchld() handles this */ -+ switch(child = fork()){ -+ case -1: -+ close(to[0]), close(to[1]); -+ return; -+ case 0: -+ /* child */ -+ close(to[1]); -+ dup2(to[0], STDIN_FILENO); /* 0<&to */ -+ close(to[0]); -+ execvp( -+ "sh", -+ (char *const []){ -+ "/bin/sh", -+ "-c", -+ (char *)arg->v, -+ 0 -+ }); -+ exit(127); -+ } -+ -+ /* parent */ -+ close(to[0]); -+ /* ignore sigpipe for now, in case child exits early */ -+ oldsigpipe = signal(SIGPIPE, SIG_IGN); -+ -+ for(n = 0; n < term.row; n++){ -+ bp = &term.line[n][0]; -+ end = &bp[MIN(tlinelen(n), term.col) - 1]; -+ if(bp != end || bp->u != ' ') -+ for(; bp <= end; ++bp) -+ if(xwrite(to[1], buf, utf8encode(bp->u, buf)) < 0) -+ break; -+ if(xwrite(to[1], "\n", 1) < 0) -+ break; -+ } -+ -+ close(to[1]); -+ -+ /* restore */ -+ signal(SIGPIPE, oldsigpipe); -+} -+ -+void - tputc(Rune u) { - char c[UTF_SIZ]; - bool control; diff --git a/st.suckless.org/patches/st-0.6-hidecursor.diff b/st.suckless.org/patches/st-0.6-hidecursor.diff @@ -1,84 +0,0 @@ -diff --git a/st.c b/st.c -index b89d094..d2979ff 100644 ---- a/st.c -+++ b/st.c -@@ -257,6 +257,11 @@ typedef struct { - Draw draw; - Visual *vis; - XSetWindowAttributes attrs; -+ /* Here, we use the term *pointer* to differentiate the cursor -+ * one sees when hovering the mouse over the terminal from, e.g., -+ * a green rectangle where text would be entered. */ -+ Cursor vpointer, bpointer; /* visible and hidden pointers */ -+ bool pointerisvisible; - int scr; - bool isfixed; /* is fixed geometry? */ - int l, t; /* left and top offset */ -@@ -1181,6 +1186,13 @@ void - bmotion(XEvent *e) { - int oldey, oldex, oldsby, oldsey; - -+ if(!xw.pointerisvisible) { -+ XDefineCursor(xw.dpy, xw.win, xw.vpointer); -+ xw.pointerisvisible = true; -+ if(!IS_SET(MODE_MOUSEMANY)) -+ xsetpointermotion(0); -+ } -+ - if(IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) { - mousereport(e); - return; -@@ -3182,9 +3194,11 @@ xzoomreset(const Arg *arg) { - void - xinit(void) { - XGCValues gcvalues; -- Cursor cursor; - Window parent; - pid_t thispid = getpid(); -+ XColor xcwhite = {.red = 0xffff, .green = 0xffff, .blue = 0xffff}; -+ XColor xcblack = {.red = 0x0000, .green = 0x0000, .blue = 0x0000}; -+ Pixmap blankpm; - - if(!(xw.dpy = XOpenDisplay(NULL))) - die("Can't open display\n"); -@@ -3257,11 +3271,13 @@ xinit(void) { - die("XCreateIC failed. Could not obtain input method.\n"); - - /* white cursor, black outline */ -- cursor = XCreateFontCursor(xw.dpy, XC_xterm); -- XDefineCursor(xw.dpy, xw.win, cursor); -- XRecolorCursor(xw.dpy, cursor, -- &(XColor){.red = 0xffff, .green = 0xffff, .blue = 0xffff}, -- &(XColor){.red = 0x0000, .green = 0x0000, .blue = 0x0000}); -+ xw.vpointer = XCreateFontCursor(xw.dpy, XC_xterm); -+ XDefineCursor(xw.dpy, xw.win, xw.vpointer); -+ XRecolorCursor(xw.dpy, xw.vpointer, &xcwhite, &xcblack); -+ xw.pointerisvisible = true; -+ blankpm = XCreateBitmapFromData(xw.dpy, xw.win, &(char){0}, 1, 1); -+ xw.bpointer = XCreatePixmapCursor(xw.dpy, blankpm, blankpm, -+ &xcblack, &xcblack, 0, 0); - - xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False); - xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False); -@@ -3725,6 +3741,8 @@ unmap(XEvent *ev) { - - void - xsetpointermotion(int set) { -+ if(!set && !xw.pointerisvisible) -+ return; - MODBIT(xw.attrs.event_mask, set, PointerMotionMask); - XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs); - } -@@ -3818,6 +3836,12 @@ kpress(XEvent *ev) { - Status status; - Shortcut *bp; - -+ if(xw.pointerisvisible) { -+ XDefineCursor(xw.dpy, xw.win, xw.bpointer); -+ xsetpointermotion(1); -+ xw.pointerisvisible = false; -+ } -+ - if(IS_SET(MODE_KBDLOCK)) - return; - diff --git a/st.suckless.org/patches/st-0.6-no-bold-colors.diff b/st.suckless.org/patches/st-0.6-no-bold-colors.diff @@ -1,13 +0,0 @@ -diff --git a/st.c b/st.c -index b89d094..02bcf19 100644 ---- a/st.c -+++ b/st.c -@@ -3454,7 +3454,7 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i - - /* Change basic system colors [0-7] to bright system colors [8-15] */ - if((base.mode & ATTR_BOLD_FAINT) == ATTR_BOLD && BETWEEN(base.fg, 0, 7)) -- fg = &dc.col[base.fg + 8]; -+ fg = &dc.col[base.fg]; - - if(IS_SET(MODE_REVERSE)) { - if(fg == &dc.col[defaultfg]) { diff --git a/st.suckless.org/patches/st-0.6-solarized-dark.diff b/st.suckless.org/patches/st-0.6-solarized-dark.diff @@ -1,65 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 64e75b8..bc8d298 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -61,30 +61,23 @@ static unsigned int tabspaces = 8; - - /* Terminal colors (16 first used in escape sequence) */ - static const char *colorname[] = { -- /* 8 normal colors */ -- "black", -- "red3", -- "green3", -- "yellow3", -- "blue2", -- "magenta3", -- "cyan3", -- "gray90", -- -- /* 8 bright colors */ -- "gray50", -- "red", -- "green", -- "yellow", -- "#5c5cff", -- "magenta", -- "cyan", -- "white", -- -- [255] = 0, -- -- /* more colors can be added after 255 to use with DefaultXX */ -- "#cccccc", -+ /* solarized dark */ -+ "#073642", /* 0: black */ -+ "#dc322f", /* 1: red */ -+ "#859900", /* 2: green */ -+ "#b58900", /* 3: yellow */ -+ "#268bd2", /* 4: blue */ -+ "#d33682", /* 5: magenta */ -+ "#2aa198", /* 6: cyan */ -+ "#eee8d5", /* 7: white */ -+ "#002b36", /* 8: brblack */ -+ "#cb4b16", /* 9: brred */ -+ "#586e75", /* 10: brgreen */ -+ "#657b83", /* 11: bryellow */ -+ "#839496", /* 12: brblue */ -+ "#6c71c4", /* 13: brmagenta*/ -+ "#93a1a1", /* 14: brcyan */ -+ "#fdf6e3", /* 15: brwhite */ - }; - - -@@ -92,9 +85,9 @@ static const char *colorname[] = { - * Default colors (colorname index) - * foreground, background, cursor - */ --static unsigned int defaultfg = 7; --static unsigned int defaultbg = 0; --static unsigned int defaultcs = 256; -+static unsigned int defaultfg = 12; -+static unsigned int defaultbg = 8; -+static unsigned int defaultcs = 14; - - /* - * Colors used, when the specific fg == defaultfg. So in reverse mode this diff --git a/st.suckless.org/patches/st-0.6-solarized-light.diff b/st.suckless.org/patches/st-0.6-solarized-light.diff @@ -1,65 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 64e75b8..fba47b1 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -61,30 +61,23 @@ static unsigned int tabspaces = 8; - - /* Terminal colors (16 first used in escape sequence) */ - static const char *colorname[] = { -- /* 8 normal colors */ -- "black", -- "red3", -- "green3", -- "yellow3", -- "blue2", -- "magenta3", -- "cyan3", -- "gray90", -- -- /* 8 bright colors */ -- "gray50", -- "red", -- "green", -- "yellow", -- "#5c5cff", -- "magenta", -- "cyan", -- "white", -- -- [255] = 0, -- -- /* more colors can be added after 255 to use with DefaultXX */ -- "#cccccc", -+ /* solarized light */ -+ "#eee8d5", /* 0: black */ -+ "#dc322f", /* 1: red */ -+ "#859900", /* 2: green */ -+ "#b58900", /* 3: yellow */ -+ "#268bd2", /* 4: blue */ -+ "#d33682", /* 5: magenta */ -+ "#2aa198", /* 6: cyan */ -+ "#073642", /* 7: white */ -+ "#fdf6e3", /* 8: brblack */ -+ "#cb4b16", /* 9: brred */ -+ "#93a1a1", /* 10: brgreen */ -+ "#839496", /* 11: bryellow */ -+ "#657b83", /* 12: brblue */ -+ "#6c71c4", /* 13: brmagenta*/ -+ "#586e75", /* 14: brcyan */ -+ "#002b36", /* 15: brwhite */ - }; - - -@@ -92,9 +85,9 @@ static const char *colorname[] = { - * Default colors (colorname index) - * foreground, background, cursor - */ --static unsigned int defaultfg = 7; --static unsigned int defaultbg = 0; --static unsigned int defaultcs = 256; -+static unsigned int defaultfg = 12; -+static unsigned int defaultbg = 8; -+static unsigned int defaultcs = 14; - - /* - * Colors used, when the specific fg == defaultfg. So in reverse mode this diff --git a/st.suckless.org/patches/st-0.6-spoiler.diff b/st.suckless.org/patches/st-0.6-spoiler.diff @@ -1,22 +0,0 @@ -diff --git a/st.c b/st.c -index b89d094..88c78f5 100644 ---- a/st.c -+++ b/st.c -@@ -3483,9 +3483,14 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i - } - - if(base.mode & ATTR_REVERSE) { -- temp = fg; -- fg = bg; -- bg = temp; -+ if (bg == fg) { -+ bg = &dc.col[defaultfg]; -+ fg = &dc.col[defaultbg]; -+ } else { -+ temp = fg; -+ fg = bg; -+ bg = temp; -+ } - } - - if((base.mode & ATTR_BOLD_FAINT) == ATTR_FAINT) { diff --git a/st.suckless.org/patches/st-0.4.1-argbbg.diff b/st.suckless.org/patches/st-alpha-0.4.1.diff diff --git a/st.suckless.org/patches/st-alpha-0.5.diff b/st.suckless.org/patches/st-alpha-0.5.diff @@ -0,0 +1,169 @@ +diff --git a/config.def.h b/config.def.h +index 58b470e..ce34f55 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -48,6 +48,8 @@ static char termname[] = "st-256color"; + + static unsigned int tabspaces = 8; + ++/* background opacity */ ++static const int alpha = 0xdd; + + /* Terminal colors (16 first used in escape sequence) */ + static const char *colorname[] = { +@@ -75,6 +77,7 @@ static const char *colorname[] = { + + /* more colors can be added after 255 to use with DefaultXX */ + "#cccccc", ++ "black", + }; + + +@@ -83,7 +86,7 @@ static const char *colorname[] = { + * foreground, background, cursor + */ + static unsigned int defaultfg = 7; +-static unsigned int defaultbg = 0; ++static unsigned int defaultbg = 257; + static unsigned int defaultcs = 256; + + /* +diff --git a/config.mk b/config.mk +index 97afa2c..18aec14 100644 +--- a/config.mk ++++ b/config.mk +@@ -14,7 +14,7 @@ X11LIB = /usr/X11R6/lib + INCS = -I. -I/usr/include -I${X11INC} \ + `pkg-config --cflags fontconfig` \ + `pkg-config --cflags freetype2` +-LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -lutil -lXext -lXft \ ++LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -lutil -lXext -lXft -lXrender \ + `pkg-config --libs fontconfig` \ + `pkg-config --libs freetype2` + +diff --git a/st.c b/st.c +index 392f12d..5b05a5f 100644 +--- a/st.c ++++ b/st.c +@@ -65,6 +65,7 @@ char *argv0; + #define XK_ANY_MOD UINT_MAX + #define XK_NO_MOD 0 + #define XK_SWITCH_MOD (1<<13) ++#define OPAQUE 0Xff + + #define REDRAW_TIMEOUT (80*1000) /* 80 ms */ + +@@ -79,6 +80,7 @@ char *argv0; + #define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || (a).bg != (b).bg) + #define IS_SET(flag) ((term.mode & (flag)) != 0) + #define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + (t1.tv_usec-t2.tv_usec)/1000) ++#define USE_ARGB (alpha != OPAQUE && opt_embed == NULL) + #define CEIL(x) (((x) != (int) (x)) ? (x) + 1 : (x)) + + #define TRUECOLOR(r,g,b) (1 << 24 | (r) << 16 | (g) << 8 | (b)) +@@ -255,6 +257,7 @@ typedef struct { + int w, h; /* window width and height */ + int ch; /* char height */ + int cw; /* char width */ ++ int depth; /* bit depth */ + char state; /* focus, redraw, visible */ + } XWindow; + +@@ -2706,8 +2709,7 @@ xresize(int col, int row) { + xw.th = MAX(1, row * xw.ch); + + XFreePixmap(xw.dpy, xw.buf); +- xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h, +- DefaultDepth(xw.dpy, xw.scr)); ++ xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h, xw.depth); + XftDrawChange(xw.draw, xw.buf); + xclear(0, 0, xw.w, xw.h); + } +@@ -2738,6 +2740,13 @@ xloadcols(void) { + } + } + ++ /* set alpha value of bg color */ ++ if (USE_ARGB) { ++ dc.col[defaultbg].color.alpha = (0xffff * alpha) / OPAQUE; //0xcccc; ++ dc.col[defaultbg].pixel &= 0x00111111; ++ dc.col[defaultbg].pixel |= alpha << 24; // 0xcc000000; ++ } ++ + /* load colors [16-255] ; same colors as xterm */ + for(i = 16, r = 0; r < 6; r++) { + for(g = 0; g < 6; g++) { +@@ -2992,7 +3001,38 @@ xinit(void) { + if(!(xw.dpy = XOpenDisplay(NULL))) + die("Can't open display\n"); + xw.scr = XDefaultScreen(xw.dpy); +- xw.vis = XDefaultVisual(xw.dpy, xw.scr); ++ xw.depth = (USE_ARGB)? 32: XDefaultDepth(xw.dpy, xw.scr); ++ if (! USE_ARGB) ++ xw.vis = XDefaultVisual(xw.dpy, xw.scr); ++ else { ++ XVisualInfo *vis; ++ XRenderPictFormat *fmt; ++ int nvi; ++ int i; ++ ++ XVisualInfo tpl = { ++ .screen = xw.scr, ++ .depth = 32, ++ .class = TrueColor ++ }; ++ ++ vis = XGetVisualInfo(xw.dpy, VisualScreenMask | VisualDepthMask | VisualClassMask, &tpl, &nvi); ++ xw.vis = NULL; ++ for(i = 0; i < nvi; i ++) { ++ fmt = XRenderFindVisualFormat(xw.dpy, vis[i].visual); ++ if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) { ++ xw.vis = vis[i].visual; ++ break; ++ } ++ } ++ ++ XFree(vis); ++ ++ if (! xw.vis) { ++ fprintf(stderr, "Couldn't find ARGB visual.\n"); ++ exit(1); ++ } ++ } + + /* font */ + if(!FcInit()) +@@ -3002,7 +3042,10 @@ xinit(void) { + xloadfonts(usedfont, 0); + + /* colors */ +- xw.cmap = XDefaultColormap(xw.dpy, xw.scr); ++ if (! USE_ARGB) ++ xw.cmap = XDefaultColormap(xw.dpy, xw.scr); ++ else ++ xw.cmap = XCreateColormap(xw.dpy, XRootWindow(xw.dpy, xw.scr), xw.vis, None); + xloadcols(); + + /* adjust fixed window geometry */ +@@ -3036,16 +3079,17 @@ xinit(void) { + parent = opt_embed ? strtol(opt_embed, NULL, 0) : \ + XRootWindow(xw.dpy, xw.scr); + xw.win = XCreateWindow(xw.dpy, parent, xw.fx, xw.fy, +- xw.w, xw.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput, ++ xw.w, xw.h, 0, xw.depth, InputOutput, + xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity + | CWEventMask | CWColormap, &xw.attrs); + + memset(&gcvalues, 0, sizeof(gcvalues)); + gcvalues.graphics_exposures = False; +- dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures, ++ xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h, xw.depth); ++ dc.gc = XCreateGC(xw.dpy, ++ (USE_ARGB)? xw.buf: parent, ++ GCGraphicsExposures, + &gcvalues); +- xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h, +- DefaultDepth(xw.dpy, xw.scr)); + XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel); + XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, xw.w, xw.h); + diff --git a/st.suckless.org/patches/st-alpha-0.6.diff b/st.suckless.org/patches/st-alpha-0.6.diff @@ -0,0 +1,170 @@ +diff --git a/config.def.h b/config.def.h +index 64e75b8..9a27c14 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -58,6 +58,8 @@ static char termname[] = "st-256color"; + + static unsigned int tabspaces = 8; + ++/* bg opacity */ ++static const int alpha = 0xdd; + + /* Terminal colors (16 first used in escape sequence) */ + static const char *colorname[] = { +@@ -85,6 +87,7 @@ static const char *colorname[] = { + + /* more colors can be added after 255 to use with DefaultXX */ + "#cccccc", ++ "black", + }; + + +@@ -93,7 +96,7 @@ static const char *colorname[] = { + * foreground, background, cursor + */ + static unsigned int defaultfg = 7; +-static unsigned int defaultbg = 0; ++static unsigned int defaultbg = 257; + static unsigned int defaultcs = 256; + + /* +diff --git a/config.mk b/config.mk +index 67844dc..005b1c6 100644 +--- a/config.mk ++++ b/config.mk +@@ -14,7 +14,7 @@ X11LIB = /usr/X11R6/lib + INCS = -I. -I/usr/include -I${X11INC} \ + `pkg-config --cflags fontconfig` \ + `pkg-config --cflags freetype2` +-LIBS = -L/usr/lib -lc -L${X11LIB} -lm -lrt -lX11 -lutil -lXext -lXft \ ++LIBS = -L/usr/lib -lc -L${X11LIB} -lm -lrt -lX11 -lutil -lXext -lXft -lXrender\ + `pkg-config --libs fontconfig` \ + `pkg-config --libs freetype2` + +diff --git a/st.c b/st.c +index b89d094..d212134 100644 +--- a/st.c ++++ b/st.c +@@ -61,6 +61,7 @@ char *argv0; + #define XK_ANY_MOD UINT_MAX + #define XK_NO_MOD 0 + #define XK_SWITCH_MOD (1<<13) ++#define OPAQUE 0Xff + + /* macros */ + #define MIN(a, b) ((a) < (b) ? (a) : (b)) +@@ -77,6 +78,7 @@ char *argv0; + #define IS_SET(flag) ((term.mode & (flag)) != 0) + #define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + (t1.tv_nsec-t2.tv_nsec)/1E6) + #define MODBIT(x, set, bit) ((set) ? ((x) |= (bit)) : ((x) &= ~(bit))) ++#define USE_ARGB (alpha != OPAQUE && opt_embed == NULL) + + #define TRUECOLOR(r,g,b) (1 << 24 | (r) << 16 | (g) << 8 | (b)) + #define IS_TRUECOL(x) (1 << 24 & (x)) +@@ -265,6 +267,7 @@ typedef struct { + int w, h; /* window width and height */ + int ch; /* char height */ + int cw; /* char width */ ++ int depth; /* bit depth */ + char state; /* focus, redraw, visible */ + int cursor; /* cursor style */ + } XWindow; +@@ -2895,8 +2898,7 @@ xresize(int col, int row) { + xw.th = MAX(1, row * xw.ch); + + XFreePixmap(xw.dpy, xw.buf); +- xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h, +- DefaultDepth(xw.dpy, xw.scr)); ++ xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h, xw.depth); + XftDrawChange(xw.draw, xw.buf); + xclear(0, 0, xw.w, xw.h); + } +@@ -2946,6 +2948,14 @@ xloadcols(void) { + else + die("Could not allocate color %d\n", i); + } ++ ++ /* set alpha value of bg color */ ++ if (USE_ARGB) { ++ dc.col[defaultbg].color.alpha = (0xffff * alpha) / OPAQUE; //0xcccc; ++ dc.col[defaultbg].pixel &= 0x00111111; ++ dc.col[defaultbg].pixel |= alpha << 24; // 0xcc000000; ++ } ++ + loaded = true; + } + +@@ -3189,7 +3199,38 @@ xinit(void) { + if(!(xw.dpy = XOpenDisplay(NULL))) + die("Can't open display\n"); + xw.scr = XDefaultScreen(xw.dpy); +- xw.vis = XDefaultVisual(xw.dpy, xw.scr); ++ xw.depth = (USE_ARGB) ? 32: XDefaultDepth(xw.dpy, xw.scr); ++ if (! USE_ARGB) ++ xw.vis = XDefaultVisual(xw.dpy, xw.scr); ++ else { ++ XVisualInfo *vis; ++ XRenderPictFormat *fmt; ++ int nvi; ++ int i; ++ ++ XVisualInfo tpl = { ++ .screen = xw.scr, ++ .depth = 32, ++ .class = TrueColor ++ }; ++ ++ vis = XGetVisualInfo(xw.dpy, VisualScreenMask | VisualDepthMask | VisualClassMask, &tpl, &nvi); ++ xw.vis = NULL; ++ for(i = 0; i < nvi; i ++) { ++ fmt = XRenderFindVisualFormat(xw.dpy, vis[i].visual); ++ if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) { ++ xw.vis = vis[i].visual; ++ break; ++ } ++ } ++ ++ XFree(vis); ++ ++ if (! xw.vis) { ++ fprintf(stderr, "Couldn't find ARGB visual.\n"); ++ exit(1); ++ } ++ } + + /* font */ + if(!FcInit()) +@@ -3199,7 +3240,10 @@ xinit(void) { + xloadfonts(usedfont, 0); + + /* colors */ +- xw.cmap = XDefaultColormap(xw.dpy, xw.scr); ++ if (! USE_ARGB) ++ xw.cmap = XDefaultColormap(xw.dpy, xw.scr); ++ else ++ xw.cmap = XCreateColormap(xw.dpy, XRootWindow(xw.dpy, xw.scr), xw.vis, None); + xloadcols(); + + /* adjust fixed window geometry */ +@@ -3222,16 +3266,17 @@ xinit(void) { + if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) + parent = XRootWindow(xw.dpy, xw.scr); + xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t, +- xw.w, xw.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput, ++ xw.w, xw.h, 0, xw.depth, InputOutput, + xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity + | CWEventMask | CWColormap, &xw.attrs); + + memset(&gcvalues, 0, sizeof(gcvalues)); + gcvalues.graphics_exposures = False; +- dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures, ++ xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h, xw.depth); ++ dc.gc = XCreateGC(xw.dpy, ++ (USE_ARGB)? xw.buf: parent, ++ GCGraphicsExposures, + &gcvalues); +- xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h, +- DefaultDepth(xw.dpy, xw.scr)); + XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel); + XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, xw.w, xw.h); + diff --git a/st.suckless.org/patches/st-alpha-20160727-308bfbf.diff b/st.suckless.org/patches/st-alpha-20160727-308bfbf.diff @@ -0,0 +1,188 @@ +diff --git a/config.def.h b/config.def.h +index b41747f..e22ebd2 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -82,6 +82,9 @@ static char termname[] = "st-256color"; + */ + static unsigned int tabspaces = 8; + ++/* bg opacity */ ++static const int alpha = 0xdd; ++ + /* Terminal colors (16 first used in escape sequence) */ + static const char *colorname[] = { + /* 8 normal colors */ +@@ -109,6 +112,7 @@ static const char *colorname[] = { + /* more colors can be added after 255 to use with DefaultXX */ + "#cccccc", + "#555555", ++ "black", + }; + + +@@ -117,7 +121,7 @@ static const char *colorname[] = { + * foreground, background, cursor, reverse cursor + */ + static unsigned int defaultfg = 7; +-static unsigned int defaultbg = 0; ++static unsigned int defaultbg = 257; + static unsigned int defaultcs = 256; + static unsigned int defaultrcs = 257; + +diff --git a/config.mk b/config.mk +index 81e3e47..005b1c6 100644 +--- a/config.mk ++++ b/config.mk +@@ -14,7 +14,7 @@ X11LIB = /usr/X11R6/lib + INCS = -I. -I/usr/include -I${X11INC} \ + `pkg-config --cflags fontconfig` \ + `pkg-config --cflags freetype2` +-LIBS = -L/usr/lib -lc -L${X11LIB} -lm -lrt -lX11 -lutil -lXft \ ++LIBS = -L/usr/lib -lc -L${X11LIB} -lm -lrt -lX11 -lutil -lXext -lXft -lXrender\ + `pkg-config --libs fontconfig` \ + `pkg-config --libs freetype2` + +diff --git a/st.c b/st.c +index 2594c65..f9ba75b 100644 +--- a/st.c ++++ b/st.c +@@ -61,6 +61,7 @@ char *argv0; + #define XK_ANY_MOD UINT_MAX + #define XK_NO_MOD 0 + #define XK_SWITCH_MOD (1<<13) ++#define OPAQUE 0Xff + + /* macros */ + #define MIN(a, b) ((a) < (b) ? (a) : (b)) +@@ -81,6 +82,8 @@ char *argv0; + (t1.tv_nsec-t2.tv_nsec)/1E6) + #define MODBIT(x, set, bit) ((set) ? ((x) |= (bit)) : ((x) &= ~(bit))) + ++#define USE_ARGB (alpha != OPAQUE && opt_embed == NULL) ++ + #define TRUECOLOR(r,g,b) (1 << 24 | (r) << 16 | (g) << 8 | (b)) + #define IS_TRUECOL(x) (1 << 24 & (x)) + #define TRUERED(x) (((x) & 0xff0000) >> 8) +@@ -268,6 +271,7 @@ typedef struct { + int w, h; /* window width and height */ + int ch; /* char height */ + int cw; /* char width */ ++ int depth; /* bit depth */ + char state; /* focus, redraw, visible */ + int cursor; /* cursor style */ + } XWindow; +@@ -3137,7 +3141,7 @@ xresize(int col, int row) + + XFreePixmap(xw.dpy, xw.buf); + xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h, +- DefaultDepth(xw.dpy, xw.scr)); ++ xw.depth); + XftDrawChange(xw.draw, xw.buf); + xclear(0, 0, xw.w, xw.h); + } +@@ -3191,6 +3195,14 @@ xloadcols(void) + else + die("Could not allocate color %d\n", i); + } ++ ++ /* set alpha value of bg color */ ++ if (USE_ARGB) { ++ dc.col[defaultbg].color.alpha = (0xffff * alpha) / OPAQUE; //0xcccc; ++ dc.col[defaultbg].pixel &= 0x00111111; ++ dc.col[defaultbg].pixel |= alpha << 24; // 0xcc000000; ++ } ++ + loaded = 1; + } + +@@ -3212,6 +3224,16 @@ xsetcolorname(int x, const char *name) + return 0; + } + ++void ++xtermclear(int col1, int row1, int col2, int row2) { ++ XftDrawRect(xw.draw, ++ &dc.col[IS_SET(MODE_REVERSE) ? defaultfg : defaultbg], ++ borderpx + col1 * xw.cw, ++ borderpx + row1 * xw.ch, ++ (col2-col1+1) * xw.cw, ++ (row2-row1+1) * xw.ch); ++} ++ + /* + * Absolute coordinates. + */ +@@ -3443,7 +3465,38 @@ xinit(void) + if (!(xw.dpy = XOpenDisplay(NULL))) + die("Can't open display\n"); + xw.scr = XDefaultScreen(xw.dpy); +- xw.vis = XDefaultVisual(xw.dpy, xw.scr); ++ xw.depth = (USE_ARGB) ? 32: XDefaultDepth(xw.dpy, xw.scr); ++ if (! USE_ARGB) ++ xw.vis = XDefaultVisual(xw.dpy, xw.scr); ++ else { ++ XVisualInfo *vis; ++ XRenderPictFormat *fmt; ++ int nvi; ++ int i; ++ ++ XVisualInfo tpl = { ++ .screen = xw.scr, ++ .depth = 32, ++ .class = TrueColor ++ }; ++ ++ vis = XGetVisualInfo(xw.dpy, VisualScreenMask | VisualDepthMask | VisualClassMask, &tpl, &nvi); ++ xw.vis = NULL; ++ for(i = 0; i < nvi; i ++) { ++ fmt = XRenderFindVisualFormat(xw.dpy, vis[i].visual); ++ if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) { ++ xw.vis = vis[i].visual; ++ break; ++ } ++ } ++ ++ XFree(vis); ++ ++ if (! xw.vis) { ++ fprintf(stderr, "Couldn't find ARGB visual.\n"); ++ exit(1); ++ } ++ } + + /* font */ + if (!FcInit()) +@@ -3453,7 +3506,10 @@ xinit(void) + xloadfonts(usedfont, 0); + + /* colors */ +- xw.cmap = XDefaultColormap(xw.dpy, xw.scr); ++ if (! USE_ARGB) ++ xw.cmap = XDefaultColormap(xw.dpy, xw.scr); ++ else ++ xw.cmap = XCreateColormap(xw.dpy, XRootWindow(xw.dpy, xw.scr), xw.vis, None); + xloadcols(); + + /* adjust fixed window geometry */ +@@ -3476,16 +3532,17 @@ xinit(void) + if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) + parent = XRootWindow(xw.dpy, xw.scr); + xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t, +- xw.w, xw.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput, ++ xw.w, xw.h, 0, xw.depth, InputOutput, + xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity + | CWEventMask | CWColormap, &xw.attrs); + + memset(&gcvalues, 0, sizeof(gcvalues)); + gcvalues.graphics_exposures = False; +- dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures, ++ xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h, xw.depth); ++ dc.gc = XCreateGC(xw.dpy, ++ (USE_ARGB)? xw.buf: parent, ++ GCGraphicsExposures, + &gcvalues); +- xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h, +- DefaultDepth(xw.dpy, xw.scr)); + XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel); + XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, xw.w, xw.h); + diff --git a/st.suckless.org/patches/st-alpha-s.png b/st.suckless.org/patches/st-alpha-s.png Binary files differ. diff --git a/st.suckless.org/patches/st-alpha.png b/st.suckless.org/patches/st-alpha.png Binary files differ. diff --git a/st.suckless.org/patches/st-argbbg-s.png b/st.suckless.org/patches/st-argbbg-s.png Binary files differ. diff --git a/st.suckless.org/patches/st-argbbg.png b/st.suckless.org/patches/st-argbbg.png Binary files differ. diff --git a/st.suckless.org/patches/st-clipboard-0.6.diff b/st.suckless.org/patches/st-clipboard-0.6.diff @@ -0,0 +1,13 @@ +diff --git a/st.c b/st.c +index b89d094..6658e6a 100644 +--- a/st.c ++++ b/st.c +@@ -1155,6 +1155,8 @@ xsetsel(char *str, Time t) { + XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t); + if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win) + selclear(0); ++ ++ clipcopy(NULL); + } + + void diff --git a/st.suckless.org/patches/st-clipboard-20160727-308bfbf.diff b/st.suckless.org/patches/st-clipboard-20160727-308bfbf.diff @@ -0,0 +1,13 @@ +diff --git a/st.c b/st.c +index 2594c65..ebdde9f 100644 +--- a/st.c ++++ b/st.c +@@ -1263,6 +1263,8 @@ xsetsel(char *str, Time t) + XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t); + if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win) + selclear(0); ++ ++ clipcopy(NULL); + } + + void diff --git a/st.suckless.org/patches/st-copyurl-0.6.diff b/st.suckless.org/patches/st-copyurl-0.6.diff @@ -0,0 +1,88 @@ +diff --git a/config.def.h b/config.def.h +index 64e75b8..c3d4e88 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -128,6 +128,7 @@ static Shortcut shortcuts[] = { + { MODKEY|ShiftMask, XK_C, clipcopy, {.i = 0} }, + { MODKEY|ShiftMask, XK_V, clippaste, {.i = 0} }, + { MODKEY, XK_Num_Lock, numlock, {.i = 0} }, ++ { MODKEY, XK_l, copyurl, {.i = 0} }, + }; + + /* +diff --git a/st.c b/st.c +index b89d094..dafd5ba 100644 +--- a/st.c ++++ b/st.c +@@ -332,6 +332,7 @@ static void xzoomreset(const Arg *); + static void printsel(const Arg *); + static void printscreen(const Arg *) ; + static void toggleprinter(const Arg *); ++static void copyurl(const Arg *); + + /* Config.h for applying patches and the configuration. */ + #include "config.h" +@@ -4080,3 +4081,63 @@ run: + return 0; + } + ++/* select and copy the previous url on screen (do nothing if there's no url). ++ * known bug: doesn't handle urls that span multiple lines (wontfix) ++ * known bug: only finds first url on line (mightfix) ++ */ ++void ++copyurl(const Arg *arg) { ++ /* () and [] can appear in urls, but excluding them here will reduce false ++ * positives when figuring out where a given url ends. ++ */ ++ static char URLCHARS[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ++ "abcdefghijklmnopqrstuvwxyz" ++ "0123456789-._~:/?#@!$&'*+,;=%"; ++ ++ int i, row, startrow; ++ char *linestr = calloc(sizeof(char), term.col+1); /* assume ascii */ ++ char *c, *match = NULL; ++ ++ row = (sel.ob.x >= 0 && sel.nb.y > 0) ? sel.nb.y-1 : term.bot; ++ LIMIT(row, term.top, term.bot); ++ startrow = row; ++ ++ /* find the start of the last url before selection */ ++ do { ++ for (i = 0; i < term.col; ++i) { ++ if (term.line[row][i].u > 127) /* assume ascii */ ++ continue; ++ linestr[i] = term.line[row][i].u; ++ } ++ linestr[term.col] = '\0'; ++ if ((match = strstr(linestr, "http://")) ++ || (match = strstr(linestr, "https://"))) ++ break; ++ if (--row < term.top) ++ row = term.bot; ++ } while (row != startrow); ++ ++ if (match) { ++ /* must happen before trim */ ++ selclear(NULL); ++ sel.ob.x = strlen(linestr) - strlen(match); ++ ++ /* trim the rest of the line from the url match */ ++ for (c = match; *c != '\0'; ++c) ++ if (!strchr(URLCHARS, *c)) { ++ *c = '\0'; ++ break; ++ } ++ ++ /* select and copy */ ++ sel.mode = 1; ++ sel.type = SEL_REGULAR; ++ sel.oe.x = sel.ob.x + strlen(match)-1; ++ sel.ob.y = sel.oe.y = row; ++ selnormalize(); ++ tsetdirt(sel.nb.y, sel.ne.y); ++ selcopy(0); ++ } ++ ++ free(linestr); ++} diff --git a/st.suckless.org/patches/st-copyurl-20160727-308bfbf.diff b/st.suckless.org/patches/st-copyurl-20160727-308bfbf.diff @@ -0,0 +1,88 @@ +diff --git a/config.def.h b/config.def.h +index b41747f..50321db 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -172,6 +172,7 @@ static Shortcut shortcuts[] = { + { MODKEY|ShiftMask, XK_C, clipcopy, {.i = 0} }, + { MODKEY|ShiftMask, XK_V, clippaste, {.i = 0} }, + { MODKEY, XK_Num_Lock, numlock, {.i = 0} }, ++ { MODKEY, XK_l, copyurl, {.i = 0} }, + }; + + /* +diff --git a/st.c b/st.c +index 2594c65..78201ff 100644 +--- a/st.c ++++ b/st.c +@@ -336,6 +336,7 @@ static void printsel(const Arg *); + static void printscreen(const Arg *) ; + static void toggleprinter(const Arg *); + static void sendbreak(const Arg *); ++static void copyurl(const Arg *); + + /* Config.h for applying patches and the configuration. */ + #include "config.h" +@@ -4402,3 +4403,63 @@ run: + return 0; + } + ++/* select and copy the previous url on screen (do nothing if there's no url). ++ * known bug: doesn't handle urls that span multiple lines (wontfix) ++ * known bug: only finds first url on line (mightfix) ++ */ ++void ++copyurl(const Arg *arg) { ++ /* () and [] can appear in urls, but excluding them here will reduce false ++ * positives when figuring out where a given url ends. ++ */ ++ static char URLCHARS[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ++ "abcdefghijklmnopqrstuvwxyz" ++ "0123456789-._~:/?#@!$&'*+,;=%"; ++ ++ int i, row, startrow; ++ char *linestr = calloc(sizeof(char), term.col+1); /* assume ascii */ ++ char *c, *match = NULL; ++ ++ row = (sel.ob.x >= 0 && sel.nb.y > 0) ? sel.nb.y-1 : term.bot; ++ LIMIT(row, term.top, term.bot); ++ startrow = row; ++ ++ /* find the start of the last url before selection */ ++ do { ++ for (i = 0; i < term.col; ++i) { ++ if (term.line[row][i].u > 127) /* assume ascii */ ++ continue; ++ linestr[i] = term.line[row][i].u; ++ } ++ linestr[term.col] = '\0'; ++ if ((match = strstr(linestr, "http://")) ++ || (match = strstr(linestr, "https://"))) ++ break; ++ if (--row < term.top) ++ row = term.bot; ++ } while (row != startrow); ++ ++ if (match) { ++ /* must happen before trim */ ++ selclear(NULL); ++ sel.ob.x = strlen(linestr) - strlen(match); ++ ++ /* trim the rest of the line from the url match */ ++ for (c = match; *c != '\0'; ++c) ++ if (!strchr(URLCHARS, *c)) { ++ *c = '\0'; ++ break; ++ } ++ ++ /* select and copy */ ++ sel.mode = 1; ++ sel.type = SEL_REGULAR; ++ sel.oe.x = sel.ob.x + strlen(match)-1; ++ sel.ob.y = sel.oe.y = row; ++ selnormalize(); ++ tsetdirt(sel.nb.y, sel.ne.y); ++ selcopy(0); ++ } ++ ++ free(linestr); ++} diff --git a/st.suckless.org/patches/st-delkey-0.6.diff b/st.suckless.org/patches/st-delkey-0.6.diff @@ -0,0 +1,45 @@ +diff --git a/config.def.h b/config.def.h +index 64e75b8..0811af4 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -211,7 +211,7 @@ static Key key[] = { + { XK_KP_Delete, ShiftMask, "\033[2K", -1, 0, 0}, + { XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0, 0}, + { XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0, 0}, +- { XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0, 0}, ++ { XK_KP_Delete, XK_ANY_MOD, "\177", +1, 0, 0}, + { XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0, 0}, + { XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0, 0}, + { XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0, 0}, +@@ -266,8 +266,7 @@ static Key key[] = { + { XK_Delete, ShiftMask, "\033[2K", -1, 0, 0}, + { XK_Delete, ShiftMask, "\033[3;2~", +1, 0, 0}, + { XK_Delete, XK_ANY_MOD, "\033[P", -1, 0, 0}, +- { XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0, 0}, +- { XK_BackSpace, XK_NO_MOD, "\177", 0, 0, 0}, ++ { XK_Delete, XK_ANY_MOD, "\177", +1, 0, 0}, + { XK_Home, ShiftMask, "\033[2J", 0, -1, 0}, + { XK_Home, ShiftMask, "\033[1;2H", 0, +1, 0}, + { XK_Home, XK_ANY_MOD, "\033[H", 0, -1, 0}, +diff --git a/st.info b/st.info +index 2acd8b2..21b4734 100644 +--- a/st.info ++++ b/st.info +@@ -53,7 +53,7 @@ st| simpleterm, + ka3=\E[5~, + kc1=\E[4~, + kc3=\E[6~, +- kbs=\177, ++ kbs=\010, + kcbt=\E[Z, + kb2=\EOu, + kcub1=\EOD, +@@ -73,7 +73,7 @@ st| simpleterm, + kri=\E[1;2A, + kclr=\E[3;5~, + kdl1=\E[3;2~, +- kdch1=\E[3~, ++ kdch1=\177~, + kich1=\E[2~, + kend=\E[4~, + kf1=\EOP, diff --git a/st.suckless.org/patches/st-delkey-20160727-308bfbf.diff b/st.suckless.org/patches/st-delkey-20160727-308bfbf.diff @@ -0,0 +1,45 @@ +diff --git a/config.def.h b/config.def.h +index b41747f..1b52a86 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -261,7 +261,7 @@ static Key key[] = { + { XK_KP_Delete, ShiftMask, "\033[2K", -1, 0, 0}, + { XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0, 0}, + { XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0, 0}, +- { XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0, 0}, ++ { XK_KP_Delete, XK_ANY_MOD, "\177", +1, 0, 0}, + { XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0, 0}, + { XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0, 0}, + { XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0, 0}, +@@ -316,8 +316,7 @@ static Key key[] = { + { XK_Delete, ShiftMask, "\033[2K", -1, 0, 0}, + { XK_Delete, ShiftMask, "\033[3;2~", +1, 0, 0}, + { XK_Delete, XK_ANY_MOD, "\033[P", -1, 0, 0}, +- { XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0, 0}, +- { XK_BackSpace, XK_NO_MOD, "\177", 0, 0, 0}, ++ { XK_Delete, XK_ANY_MOD, "\177", +1, 0, 0}, + { XK_BackSpace, Mod1Mask, "\033\177", 0, 0, 0}, + { XK_Home, ShiftMask, "\033[2J", 0, -1, 0}, + { XK_Home, ShiftMask, "\033[1;2H", 0, +1, 0}, +diff --git a/st.info b/st.info +index b70fefa..d979946 100644 +--- a/st.info ++++ b/st.info +@@ -53,7 +53,7 @@ st| simpleterm, + ka3=\E[5~, + kc1=\E[4~, + kc3=\E[6~, +- kbs=\177, ++ kbs=\010, + kcbt=\E[Z, + kb2=\EOu, + kcub1=\EOD, +@@ -73,7 +73,7 @@ st| simpleterm, + kri=\E[1;2A, + kclr=\E[3;5~, + kdl1=\E[3;2~, +- kdch1=\E[3~, ++ kdch1=\177~, + kich1=\E[2~, + kend=\E[4~, + kf1=\EOP, diff --git a/st.suckless.org/patches/st-externalpipe-0.4.1.diff b/st.suckless.org/patches/st-externalpipe-0.4.1.diff @@ -0,0 +1,109 @@ +diff --git a/st.c b/st.c +index 686ed5d..697cd43 100644 +--- a/st.c ++++ b/st.c +@@ -249,6 +249,7 @@ typedef union { + unsigned int ui; + float f; + const void *v; ++ const char *s; + } Arg; + + typedef struct { +@@ -263,6 +264,7 @@ static void clippaste(const Arg *); + static void numlock(const Arg *); + static void selpaste(const Arg *); + static void xzoom(const Arg *); ++static void externalpipe(const Arg *); + + /* Config.h for applying patches and the configuration. */ + #include "config.h" +@@ -1024,15 +1026,22 @@ execsh(void) { + void + sigchld(int a) { + int stat = 0; ++ pid_t r; + +- if(waitpid(pid, &stat, 0) < 0) +- die("Waiting for pid %hd failed: %s\n", pid, SERRNO); ++ r = wait(&stat); ++ if(r < 0) ++ die("wait(): %s\n", SERRNO); + +- if(WIFEXITED(stat)) { +- exit(WEXITSTATUS(stat)); +- } else { +- exit(EXIT_FAILURE); ++ if(r == pid){ ++ /* _the_ sub process */ ++ if(WIFEXITED(stat)) { ++ exit(WEXITSTATUS(stat)); ++ } else { ++ exit(EXIT_FAILURE); ++ } + } ++ ++ /* something else we've forked out */ + } + + void +@@ -2593,6 +2602,59 @@ xzoom(const Arg *arg) { + } + + void ++externalpipe(const Arg *arg) ++{ ++ int to[2]; /* 0 = read, 1 = write */ ++ pid_t child; ++ int y, x; ++ void (*oldsigpipe)(int); ++ ++ if(pipe(to) == -1) ++ return; ++ ++ /* sigchld() handles this */ ++ switch((child = fork())){ ++ case -1: ++ close(to[0]), close(to[1]); ++ return; ++ case 0: ++ /* child */ ++ close(to[1]); ++ dup2(to[0], STDIN_FILENO); /* 0<&to */ ++ close(to[0]); ++ execvp( ++ "sh", ++ (char *const []){ ++ "/bin/sh", ++ "-c", ++ (char *)arg->s, ++ 0 ++ }); ++ exit(127); ++ } ++ ++ /* parent */ ++ close(to[0]); ++ /* ignore sigpipe for now, in case child exits early */ ++ oldsigpipe = signal(SIGPIPE, SIG_IGN); ++ ++ for(y = 0; y < term.row; y++){ ++ for(x = 0; x < term.col; x++){ ++ if(write(to[1], term.line[y][x].c, 1) == -1) ++ goto done; ++ } ++ if(write(to[1], "\n", 1) == -1) ++ break; ++ } ++ ++done: ++ close(to[1]); ++ ++ /* restore */ ++ signal(SIGPIPE, oldsigpipe); ++} ++ ++void + xinit(void) { + XSetWindowAttributes attrs; + XGCValues gcvalues; diff --git a/st.suckless.org/patches/st-externalpipe-0.5.diff b/st.suckless.org/patches/st-externalpipe-0.5.diff @@ -0,0 +1,109 @@ +diff --git a/st.c b/st.c +index 392f12d..31660c8 100644 +--- a/st.c ++++ b/st.c +@@ -301,6 +301,7 @@ typedef union { + unsigned int ui; + float f; + const void *v; ++ const char *s; + } Arg; + + typedef struct { +@@ -315,6 +316,7 @@ static void clippaste(const Arg *); + static void numlock(const Arg *); + static void selpaste(const Arg *); + static void xzoom(const Arg *); ++static void externalpipe(const Arg *); + static void printsel(const Arg *); + static void printscreen(const Arg *) ; + static void toggleprinter(const Arg *); +@@ -1179,15 +1181,22 @@ execsh(void) { + void + sigchld(int a) { + int stat = 0; ++ pid_t r; + +- if(waitpid(pid, &stat, 0) < 0) +- die("Waiting for pid %hd failed: %s\n", pid, SERRNO); ++ r = wait(&stat); ++ if(r < 0) ++ die("wait(): %s\n", strerror(errno)); + +- if(WIFEXITED(stat)) { +- exit(WEXITSTATUS(stat)); +- } else { +- exit(EXIT_FAILURE); ++ if(r == pid){ ++ /* _the_ sub process */ ++ if(WIFEXITED(stat)) { ++ exit(WEXITSTATUS(stat)); ++ } else { ++ exit(EXIT_FAILURE); ++ } + } ++ ++ /* something else we've forked out */ + } + + void +@@ -2982,6 +2991,59 @@ xzoom(const Arg *arg) { + } + + void ++externalpipe(const Arg *arg) ++{ ++ int to[2]; /* 0 = read, 1 = write */ ++ pid_t child; ++ int y, x; ++ void (*oldsigpipe)(int); ++ ++ if(pipe(to) == -1) ++ return; ++ ++ /* sigchld() handles this */ ++ switch((child = fork())){ ++ case -1: ++ close(to[0]), close(to[1]); ++ return; ++ case 0: ++ /* child */ ++ close(to[1]); ++ dup2(to[0], STDIN_FILENO); /* 0<&to */ ++ close(to[0]); ++ execvp( ++ "sh", ++ (char *const []){ ++ "/bin/sh", ++ "-c", ++ (char *)arg->s, ++ 0 ++ }); ++ exit(127); ++ } ++ ++ /* parent */ ++ close(to[0]); ++ /* ignore sigpipe for now, in case child exits early */ ++ oldsigpipe = signal(SIGPIPE, SIG_IGN); ++ ++ for(y = 0; y < term.row; y++){ ++ for(x = 0; x < term.col; x++){ ++ if(write(to[1], term.line[y][x].c, 1) == -1) ++ goto done; ++ } ++ if(write(to[1], "\n", 1) == -1) ++ break; ++ } ++ ++done: ++ close(to[1]); ++ ++ /* restore */ ++ signal(SIGPIPE, oldsigpipe); ++} ++ ++void + xinit(void) { + XGCValues gcvalues; + Cursor cursor; diff --git a/st.suckless.org/patches/st-externalpipe-0.6.diff b/st.suckless.org/patches/st-externalpipe-0.6.diff @@ -0,0 +1,75 @@ +diff --git a/st.c b/st.c +index b89d094..124ed16 100644 +--- a/st.c ++++ b/st.c +@@ -326,6 +326,7 @@ static void clipcopy(const Arg *); + static void clippaste(const Arg *); + static void numlock(const Arg *); + static void selpaste(const Arg *); ++static void externalpipe(const Arg *); + static void xzoom(const Arg *); + static void xzoomabs(const Arg *); + static void xzoomreset(const Arg *); +@@ -2684,6 +2685,62 @@ eschandle(uchar ascii) { + } + + void ++externalpipe(const Arg *arg) ++{ ++ int to[2]; /* 0 = read, 1 = write */ ++ pid_t child; ++ int n; ++ void (*oldsigpipe)(int); ++ char buf[UTF_SIZ]; ++ Glyph *bp, *end; ++ ++ if(pipe(to) == -1) ++ return; ++ ++ /* sigchld() handles this */ ++ switch(child = fork()){ ++ case -1: ++ close(to[0]), close(to[1]); ++ return; ++ case 0: ++ /* child */ ++ close(to[1]); ++ dup2(to[0], STDIN_FILENO); /* 0<&to */ ++ close(to[0]); ++ execvp( ++ "sh", ++ (char *const []){ ++ "/bin/sh", ++ "-c", ++ (char *)arg->v, ++ 0 ++ }); ++ exit(127); ++ } ++ ++ /* parent */ ++ close(to[0]); ++ /* ignore sigpipe for now, in case child exits early */ ++ oldsigpipe = signal(SIGPIPE, SIG_IGN); ++ ++ for(n = 0; n < term.row; n++){ ++ bp = &term.line[n][0]; ++ end = &bp[MIN(tlinelen(n), term.col) - 1]; ++ if(bp != end || bp->u != ' ') ++ for(; bp <= end; ++bp) ++ if(xwrite(to[1], buf, utf8encode(bp->u, buf)) < 0) ++ break; ++ if(xwrite(to[1], "\n", 1) < 0) ++ break; ++ } ++ ++ close(to[1]); ++ ++ /* restore */ ++ signal(SIGPIPE, oldsigpipe); ++} ++ ++void + tputc(Rune u) { + char c[UTF_SIZ]; + bool control; diff --git a/st.suckless.org/patches/st-externalpipe-20160727-308bfbf.diff b/st.suckless.org/patches/st-externalpipe-20160727-308bfbf.diff @@ -0,0 +1,75 @@ +diff --git a/st.c b/st.c +index 2594c65..1491e77 100644 +--- a/st.c ++++ b/st.c +@@ -336,6 +336,7 @@ static void printsel(const Arg *); + static void printscreen(const Arg *) ; + static void toggleprinter(const Arg *); + static void sendbreak(const Arg *); ++static void externalpipe(const Arg *); + + /* Config.h for applying patches and the configuration. */ + #include "config.h" +@@ -2922,6 +2923,62 @@ eschandle(uchar ascii) + } + + void ++externalpipe(const Arg *arg) ++{ ++ int to[2]; /* 0 = read, 1 = write */ ++ pid_t child; ++ int n; ++ void (*oldsigpipe)(int); ++ char buf[UTF_SIZ]; ++ Glyph *bp, *end; ++ ++ if(pipe(to) == -1) ++ return; ++ ++ /* sigchld() handles this */ ++ switch(child = fork()){ ++ case -1: ++ close(to[0]), close(to[1]); ++ return; ++ case 0: ++ /* child */ ++ close(to[1]); ++ dup2(to[0], STDIN_FILENO); /* 0<&to */ ++ close(to[0]); ++ execvp( ++ "sh", ++ (char *const []){ ++ "/bin/sh", ++ "-c", ++ (char *)arg->v, ++ 0 ++ }); ++ exit(127); ++ } ++ ++ /* parent */ ++ close(to[0]); ++ /* ignore sigpipe for now, in case child exits early */ ++ oldsigpipe = signal(SIGPIPE, SIG_IGN); ++ ++ for(n = 0; n < term.row; n++){ ++ bp = &term.line[n][0]; ++ end = &bp[MIN(tlinelen(n), term.col) - 1]; ++ if(bp != end || bp->u != ' ') ++ for(; bp <= end; ++bp) ++ if(xwrite(to[1], buf, utf8encode(bp->u, buf)) < 0) ++ break; ++ if(xwrite(to[1], "\n", 1) < 0) ++ break; ++ } ++ ++ close(to[1]); ++ ++ /* restore */ ++ signal(SIGPIPE, oldsigpipe); ++} ++ ++void + tputc(Rune u) + { + char c[UTF_SIZ]; diff --git a/st.suckless.org/patches/st-git-20150917-clipboard.diff b/st.suckless.org/patches/st-git-20150917-clipboard.diff @@ -1,13 +0,0 @@ -diff --git a/st.c b/st.c -index bd8b815..73c4573 100644 ---- a/st.c -+++ b/st.c -@@ -1262,6 +1262,8 @@ xsetsel(char *str, Time t) - XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t); - if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win) - selclear(0); -+ -+ clipcopy(NULL); - } - - void diff --git a/st.suckless.org/patches/st-git-20150917-delkey.diff b/st.suckless.org/patches/st-git-20150917-delkey.diff @@ -1,45 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index b6adc5e..ceaafa0 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -238,7 +238,7 @@ static Key key[] = { - { XK_KP_Delete, ShiftMask, "\033[2K", -1, 0, 0}, - { XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0, 0}, - { XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0, 0}, -- { XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0, 0}, -+ { XK_KP_Delete, XK_ANY_MOD, "\177", +1, 0, 0}, - { XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0, 0}, - { XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0, 0}, - { XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0, 0}, -@@ -293,8 +293,7 @@ static Key key[] = { - { XK_Delete, ShiftMask, "\033[2K", -1, 0, 0}, - { XK_Delete, ShiftMask, "\033[3;2~", +1, 0, 0}, - { XK_Delete, XK_ANY_MOD, "\033[P", -1, 0, 0}, -- { XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0, 0}, -- { XK_BackSpace, XK_NO_MOD, "\177", 0, 0, 0}, -+ { XK_Delete, XK_ANY_MOD, "\177", +1, 0, 0}, - { XK_Home, ShiftMask, "\033[2J", 0, -1, 0}, - { XK_Home, ShiftMask, "\033[1;2H", 0, +1, 0}, - { XK_Home, XK_ANY_MOD, "\033[H", 0, -1, 0}, -diff --git a/st.info b/st.info -index b70fefa..d979946 100644 ---- a/st.info -+++ b/st.info -@@ -53,7 +53,7 @@ st| simpleterm, - ka3=\E[5~, - kc1=\E[4~, - kc3=\E[6~, -- kbs=\177, -+ kbs=\010, - kcbt=\E[Z, - kb2=\EOu, - kcub1=\EOD, -@@ -73,7 +73,7 @@ st| simpleterm, - kri=\E[1;2A, - kclr=\E[3;5~, - kdl1=\E[3;2~, -- kdch1=\E[3~, -+ kdch1=\177~, - kich1=\E[2~, - kend=\E[4~, - kf1=\EOP, diff --git a/st.suckless.org/patches/st-git-20150917-hidecursor.diff b/st.suckless.org/patches/st-git-20150917-hidecursor.diff @@ -1,88 +0,0 @@ -diff --git a/st.c b/st.c -index bd8b815..9a8e872 100644 ---- a/st.c -+++ b/st.c -@@ -259,6 +259,11 @@ typedef struct { - Draw draw; - Visual *vis; - XSetWindowAttributes attrs; -+ /* Here, we use the term *pointer* to differentiate the cursor -+ * one sees when hovering the mouse over the terminal from, e.g., -+ * a green rectangle where text would be entered. */ -+ Cursor vpointer, bpointer; /* visible and hidden pointers */ -+ int pointerisvisible; - int scr; - int isfixed; /* is fixed geometry? */ - int l, t; /* left and top offset */ -@@ -1290,6 +1295,13 @@ bmotion(XEvent *e) - { - int oldey, oldex, oldsby, oldsey; - -+ if(!xw.pointerisvisible) { -+ XDefineCursor(xw.dpy, xw.win, xw.vpointer); -+ xw.pointerisvisible = 1; -+ if(!IS_SET(MODE_MOUSEMANY)) -+ xsetpointermotion(0); -+ } -+ - if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) { - mousereport(e); - return; -@@ -3440,10 +3452,10 @@ void - xinit(void) - { - XGCValues gcvalues; -- Cursor cursor; - Window parent; - pid_t thispid = getpid(); - XColor xmousefg, xmousebg; -+ Pixmap blankpm; - - if (!(xw.dpy = XOpenDisplay(NULL))) - die("Can't open display\n"); -@@ -3516,8 +3528,9 @@ xinit(void) - die("XCreateIC failed. Could not obtain input method.\n"); - - /* white cursor, black outline */ -- cursor = XCreateFontCursor(xw.dpy, mouseshape); -- XDefineCursor(xw.dpy, xw.win, cursor); -+ xw.pointerisvisible = 1; -+ xw.vpointer = XCreateFontCursor(xw.dpy, mouseshape); -+ XDefineCursor(xw.dpy, xw.win, xw.vpointer); - - if (XParseColor(xw.dpy, xw.cmap, colorname[mousefg], &xmousefg) == 0) { - xmousefg.red = 0xffff; -@@ -3531,7 +3544,10 @@ xinit(void) - xmousebg.blue = 0x0000; - } - -- XRecolorCursor(xw.dpy, cursor, &xmousefg, &xmousebg); -+ XRecolorCursor(xw.dpy, xw.vpointer, &xmousefg, &xmousebg); -+ blankpm = XCreateBitmapFromData(xw.dpy, xw.win, &(char){0}, 1, 1); -+ xw.bpointer = XCreatePixmapCursor(xw.dpy, blankpm, blankpm, -+ &xmousefg, &xmousebg, 0, 0); - - xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False); - xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False); -@@ -4006,6 +4022,8 @@ unmap(XEvent *ev) - void - xsetpointermotion(int set) - { -+ if(!set && !xw.pointerisvisible) -+ return; - MODBIT(xw.attrs.event_mask, set, PointerMotionMask); - XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs); - } -@@ -4105,6 +4123,12 @@ kpress(XEvent *ev) - Status status; - Shortcut *bp; - -+ if(xw.pointerisvisible) { -+ XDefineCursor(xw.dpy, xw.win, xw.bpointer); -+ xsetpointermotion(1); -+ xw.pointerisvisible = 0; -+ } -+ - if (IS_SET(MODE_KBDLOCK)) - return; - diff --git a/st.suckless.org/patches/st-git-20150917-no-bold-colors.diff b/st.suckless.org/patches/st-git-20150917-no-bold-colors.diff @@ -1,13 +0,0 @@ -diff --git a/st.c b/st.c -index bd8b815..ae5a7ba 100644 ---- a/st.c -+++ b/st.c -@@ -3724,7 +3724,7 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i - - /* Change basic system colors [0-7] to bright system colors [8-15] */ - if ((base.mode & ATTR_BOLD_FAINT) == ATTR_BOLD && BETWEEN(base.fg, 0, 7)) -- fg = &dc.col[base.fg + 8]; -+ fg = &dc.col[base.fg]; - - if (IS_SET(MODE_REVERSE)) { - if (fg == &dc.col[defaultfg]) { diff --git a/st.suckless.org/patches/st-git-20150917-solarized-dark.diff b/st.suckless.org/patches/st-git-20150917-solarized-dark.diff @@ -1,65 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index b6adc5e..9dc0faa 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -70,30 +70,23 @@ static unsigned int tabspaces = 8; - - /* Terminal colors (16 first used in escape sequence) */ - static const char *colorname[] = { -- /* 8 normal colors */ -- "black", -- "red3", -- "green3", -- "yellow3", -- "blue2", -- "magenta3", -- "cyan3", -- "gray90", -- -- /* 8 bright colors */ -- "gray50", -- "red", -- "green", -- "yellow", -- "#5c5cff", -- "magenta", -- "cyan", -- "white", -- -- [255] = 0, -- -- /* more colors can be added after 255 to use with DefaultXX */ -- "#cccccc", -+ /* solarized dark */ -+ "#073642", /* 0: black */ -+ "#dc322f", /* 1: red */ -+ "#859900", /* 2: green */ -+ "#b58900", /* 3: yellow */ -+ "#268bd2", /* 4: blue */ -+ "#d33682", /* 5: magenta */ -+ "#2aa198", /* 6: cyan */ -+ "#eee8d5", /* 7: white */ -+ "#002b36", /* 8: brblack */ -+ "#cb4b16", /* 9: brred */ -+ "#586e75", /* 10: brgreen */ -+ "#657b83", /* 11: bryellow */ -+ "#839496", /* 12: brblue */ -+ "#6c71c4", /* 13: brmagenta*/ -+ "#93a1a1", /* 14: brcyan */ -+ "#fdf6e3", /* 15: brwhite */ - }; - - -@@ -101,9 +94,9 @@ static const char *colorname[] = { - * Default colors (colorname index) - * foreground, background, cursor - */ --static unsigned int defaultfg = 7; --static unsigned int defaultbg = 0; --static unsigned int defaultcs = 256; -+static unsigned int defaultfg = 12; -+static unsigned int defaultbg = 8; -+static unsigned int defaultcs = 14; - - /* - * Default shape of cursor diff --git a/st.suckless.org/patches/st-git-20150917-solarized-light.diff b/st.suckless.org/patches/st-git-20150917-solarized-light.diff @@ -1,65 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index b6adc5e..69dbf07 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -70,30 +70,23 @@ static unsigned int tabspaces = 8; - - /* Terminal colors (16 first used in escape sequence) */ - static const char *colorname[] = { -- /* 8 normal colors */ -- "black", -- "red3", -- "green3", -- "yellow3", -- "blue2", -- "magenta3", -- "cyan3", -- "gray90", -- -- /* 8 bright colors */ -- "gray50", -- "red", -- "green", -- "yellow", -- "#5c5cff", -- "magenta", -- "cyan", -- "white", -- -- [255] = 0, -- -- /* more colors can be added after 255 to use with DefaultXX */ -- "#cccccc", -+ /* solarized light */ -+ "#eee8d5", /* 0: black */ -+ "#dc322f", /* 1: red */ -+ "#859900", /* 2: green */ -+ "#b58900", /* 3: yellow */ -+ "#268bd2", /* 4: blue */ -+ "#d33682", /* 5: magenta */ -+ "#2aa198", /* 6: cyan */ -+ "#073642", /* 7: white */ -+ "#fdf6e3", /* 8: brblack */ -+ "#cb4b16", /* 9: brred */ -+ "#93a1a1", /* 10: brgreen */ -+ "#839496", /* 11: bryellow */ -+ "#657b83", /* 12: brblue */ -+ "#6c71c4", /* 13: brmagenta*/ -+ "#586e75", /* 14: brcyan */ -+ "#002b36", /* 15: brwhite */ - }; - - -@@ -101,9 +94,9 @@ static const char *colorname[] = { - * Default colors (colorname index) - * foreground, background, cursor - */ --static unsigned int defaultfg = 7; --static unsigned int defaultbg = 0; --static unsigned int defaultcs = 256; -+static unsigned int defaultfg = 12; -+static unsigned int defaultbg = 8; -+static unsigned int defaultcs = 14; - - /* - * Default shape of cursor diff --git a/st.suckless.org/patches/st-git-20150920-openbsd.diff b/st.suckless.org/patches/st-git-20150920-openbsd.diff @@ -1,27 +0,0 @@ -diff --git a/Makefile b/Makefile -index 6158ab2..9b81f88 100644 ---- a/Makefile -+++ b/Makefile -@@ -49,7 +49,8 @@ install: all - @sed "s/VERSION/${VERSION}/g" < st.1 > ${DESTDIR}${MANPREFIX}/man1/st.1 - @chmod 644 ${DESTDIR}${MANPREFIX}/man1/st.1 - @echo Please see the README file regarding the terminfo entry of st. -- @tic -s st.info -+ @sed 's/st\([^t].*\)/st-git\1/g' st.info > st-git.info -+ @tic -s st-git.info - - uninstall: - @echo removing executable file from ${DESTDIR}${PREFIX}/bin -diff --git a/config.def.h b/config.def.h -index b6adc5e..ffc2e74 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -63,7 +63,7 @@ static unsigned int cursorthickness = 2; - static int bellvolume = 0; - - /* TERM value */ --static char termname[] = "st-256color"; -+static char termname[] = "st-git-256color"; - - static unsigned int tabspaces = 8; - diff --git a/st.suckless.org/patches/st-git-20150922-spoiler.diff b/st.suckless.org/patches/st-git-20150922-spoiler.diff @@ -1,22 +0,0 @@ -diff --git a/st.c b/st.c -index bcf74b3..0763f9f 100644 ---- a/st.c -+++ b/st.c -@@ -3752,9 +3752,14 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i - } - - if (base.mode & ATTR_REVERSE) { -- temp = fg; -- fg = bg; -- bg = temp; -+ if (bg == fg) { -+ bg = &dc.col[defaultfg]; -+ fg = &dc.col[defaultbg]; -+ } else { -+ temp = fg; -+ fg = bg; -+ bg = temp; -+ } - } - - if ((base.mode & ATTR_BOLD_FAINT) == ATTR_FAINT) { diff --git a/st.suckless.org/patches/st-git-20151106-scrollback-mouse.diff b/st.suckless.org/patches/st-git-20151106-scrollback-mouse.diff @@ -1,62 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 35060d7..30fa7a6 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -137,8 +137,14 @@ static unsigned int defaultunderline = 7; - */ - static MouseShortcut mshortcuts[] = { - /* button mask string */ -- { Button4, XK_ANY_MOD, "\031" }, -- { Button5, XK_ANY_MOD, "\005" }, -+ { Button4, XK_NO_MOD, "\031" }, -+ { Button5, XK_NO_MOD, "\005" }, -+}; -+ -+static MouseKey mkeys[] = { -+ /* button mask function argument */ -+ { Button4, ShiftMask, kscrollup, {.i = 1} }, -+ { Button5, ShiftMask, kscrolldown, {.i = 1} }, - }; - - /* Internal keyboard shortcuts. */ -diff --git a/st.c b/st.c -index 03b9473..91d4230 100644 ---- a/st.c -+++ b/st.c -@@ -322,6 +322,13 @@ typedef union { - } Arg; - - typedef struct { -+ uint b; -+ uint mask; -+ void (*func)(const Arg *); -+ const Arg arg; -+} MouseKey; -+ -+typedef struct { - uint mod; - KeySym keysym; - void (*func)(const Arg *); -@@ -952,6 +959,7 @@ bpress(XEvent *e) - { - struct timespec now; - MouseShortcut *ms; -+ MouseKey *mk; - - if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) { - mousereport(e); -@@ -966,6 +974,14 @@ bpress(XEvent *e) - } - } - -+ for (mk = mkeys; mk < mkeys + LEN(mkeys); mk++) { -+ if (e->xbutton.button == mk->b -+ && match(mk->mask, e->xbutton.state)) { -+ mk->func(&mk->arg); -+ return; -+ } -+ } -+ - if (e->xbutton.button == Button1) { - clock_gettime(CLOCK_MONOTONIC, &now); - diff --git a/st.suckless.org/patches/st-git-20151119-solarized-dark.diff b/st.suckless.org/patches/st-git-20151119-solarized-dark.diff @@ -1,68 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index fd09d72..1c0c1f9 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -69,31 +69,23 @@ static unsigned int tabspaces = 8; - - /* Terminal colors (16 first used in escape sequence) */ - static const char *colorname[] = { -- /* 8 normal colors */ -- "black", -- "red3", -- "green3", -- "yellow3", -- "blue2", -- "magenta3", -- "cyan3", -- "gray90", -- -- /* 8 bright colors */ -- "gray50", -- "red", -- "green", -- "yellow", -- "#5c5cff", -- "magenta", -- "cyan", -- "white", -- -- [255] = 0, -- -- /* more colors can be added after 255 to use with DefaultXX */ -- "#cccccc", -- "#555555", -+ /* solarized dark */ -+ "#073642", /* 0: black */ -+ "#dc322f", /* 1: red */ -+ "#859900", /* 2: green */ -+ "#b58900", /* 3: yellow */ -+ "#268bd2", /* 4: blue */ -+ "#d33682", /* 5: magenta */ -+ "#2aa198", /* 6: cyan */ -+ "#eee8d5", /* 7: white */ -+ "#002b36", /* 8: brblack */ -+ "#cb4b16", /* 9: brred */ -+ "#586e75", /* 10: brgreen */ -+ "#657b83", /* 11: bryellow */ -+ "#839496", /* 12: brblue */ -+ "#6c71c4", /* 13: brmagenta*/ -+ "#93a1a1", /* 14: brcyan */ -+ "#fdf6e3", /* 15: brwhite */ - }; - - -@@ -101,10 +93,10 @@ static const char *colorname[] = { - * Default colors (colorname index) - * foreground, background, cursor, reverse cursor - */ --static unsigned int defaultfg = 7; --static unsigned int defaultbg = 0; --static unsigned int defaultcs = 256; --static unsigned int defaultrcs = 257; -+static unsigned int defaultfg = 12; -+static unsigned int defaultbg = 8; -+static unsigned int defaultcs = 14; -+static unsigned int defaultrcs = 15; - - /* - * Default shape of cursor diff --git a/st.suckless.org/patches/st-git-20151119-solarized-light.diff b/st.suckless.org/patches/st-git-20151119-solarized-light.diff @@ -1,68 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index fd09d72..2d3c9d0 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -69,31 +69,23 @@ static unsigned int tabspaces = 8; - - /* Terminal colors (16 first used in escape sequence) */ - static const char *colorname[] = { -- /* 8 normal colors */ -- "black", -- "red3", -- "green3", -- "yellow3", -- "blue2", -- "magenta3", -- "cyan3", -- "gray90", -- -- /* 8 bright colors */ -- "gray50", -- "red", -- "green", -- "yellow", -- "#5c5cff", -- "magenta", -- "cyan", -- "white", -- -- [255] = 0, -- -- /* more colors can be added after 255 to use with DefaultXX */ -- "#cccccc", -- "#555555", -+ /* solarized light */ -+ "#eee8d5", /* 0: black */ -+ "#dc322f", /* 1: red */ -+ "#859900", /* 2: green */ -+ "#b58900", /* 3: yellow */ -+ "#268bd2", /* 4: blue */ -+ "#d33682", /* 5: magenta */ -+ "#2aa198", /* 6: cyan */ -+ "#073642", /* 7: white */ -+ "#fdf6e3", /* 8: brblack */ -+ "#cb4b16", /* 9: brred */ -+ "#93a1a1", /* 10: brgreen */ -+ "#839496", /* 11: bryellow */ -+ "#657b83", /* 12: brblue */ -+ "#6c71c4", /* 13: brmagenta*/ -+ "#586e75", /* 14: brcyan */ -+ "#002b36", /* 15: brwhite */ - }; - - -@@ -101,10 +93,10 @@ static const char *colorname[] = { - * Default colors (colorname index) - * foreground, background, cursor, reverse cursor - */ --static unsigned int defaultfg = 7; --static unsigned int defaultbg = 0; --static unsigned int defaultcs = 256; --static unsigned int defaultrcs = 257; -+static unsigned int defaultfg = 12; -+static unsigned int defaultbg = 8; -+static unsigned int defaultcs = 14; -+static unsigned int defaultrcs = 15; - - /* - * Default shape of cursor diff --git a/st.suckless.org/patches/st-git-20151217-scrollback.diff b/st.suckless.org/patches/st-git-20151217-scrollback.diff @@ -1,388 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index fd09d72..96892f1 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -7,6 +7,7 @@ - */ - static char font[] = "Liberation Mono:pixelsize=12:antialias=true:autohint=true"; - static int borderpx = 2; -+#define histsize 2000 - - /* - * What program is execed by st depends of these precedence rules: -@@ -157,6 +158,8 @@ static Shortcut shortcuts[] = { - { MODKEY|ShiftMask, XK_C, clipcopy, {.i = 0} }, - { MODKEY|ShiftMask, XK_V, clippaste, {.i = 0} }, - { MODKEY, XK_Num_Lock, numlock, {.i = 0} }, -+ { ShiftMask, XK_Page_Up, kscrollup, {.i = -1} }, -+ { ShiftMask, XK_Page_Down, kscrolldown, {.i = -1} }, - }; - - /* -diff --git a/st.c b/st.c -index c5d62c1..c58c8c5 100644 ---- a/st.c -+++ b/st.c -@@ -85,6 +85,8 @@ char *argv0; - #define TRUERED(x) (((x) & 0xff0000) >> 8) - #define TRUEGREEN(x) (((x) & 0xff00)) - #define TRUEBLUE(x) (((x) & 0xff) << 8) -+#define TLINE(y) ((y) < term.scr ? term.hist[((y) + term.histi - term.scr \ -+ + histsize + 1) % histsize] : term.line[(y) - term.scr]) - - - enum glyph_attribute { -@@ -227,26 +229,6 @@ typedef struct { - int narg; /* nb of args */ - } STREscape; - --/* Internal representation of the screen */ --typedef struct { -- int row; /* nb row */ -- int col; /* nb col */ -- Line *line; /* screen */ -- Line *alt; /* alternate screen */ -- int *dirty; /* dirtyness of lines */ -- XftGlyphFontSpec *specbuf; /* font spec buffer used for rendering */ -- TCursor c; /* cursor */ -- int top; /* top scroll limit */ -- int bot; /* bottom scroll limit */ -- int mode; /* terminal mode flags */ -- int esc; /* escape state flags */ -- char trantbl[4]; /* charset table translation */ -- int charset; /* current charset */ -- int icharset; /* selected charset for sequence */ -- int numlock; /* lock numbers in keyboard */ -- int *tabs; --} Term; -- - /* Purely graphic info */ - typedef struct { - Display *dpy; -@@ -326,6 +308,8 @@ typedef struct { - /* function definitions used in config.h */ - static void clipcopy(const Arg *); - static void clippaste(const Arg *); -+static void kscrolldown(const Arg *); -+static void kscrollup(const Arg *); - static void numlock(const Arg *); - static void selpaste(const Arg *); - static void xzoom(const Arg *); -@@ -359,6 +343,29 @@ typedef struct { - GC gc; - } DC; - -+/* Internal representation of the screen */ -+typedef struct { -+ int row; /* nb row */ -+ int col; /* nb col */ -+ Line *line; /* screen */ -+ Line *alt; /* alternate screen */ -+ Line hist[histsize]; /* history buffer */ -+ int histi; /* history index */ -+ int scr; /* scroll back */ -+ int *dirty; /* dirtyness of lines */ -+ XftGlyphFontSpec *specbuf; /* font spec buffer used for rendering */ -+ TCursor c; /* cursor */ -+ int top; /* top scroll limit */ -+ int bot; /* bottom scroll limit */ -+ int mode; /* terminal mode flags */ -+ int esc; /* escape state flags */ -+ char trantbl[4]; /* charset table translation */ -+ int charset; /* current charset */ -+ int icharset; /* selected charset for sequence */ -+ int numlock; /* lock numbers in keyboard */ -+ int *tabs; -+} Term; -+ - static void die(const char *, ...); - static void draw(void); - static void redraw(void); -@@ -398,8 +405,8 @@ static void tputtab(int); - static void tputc(Rune); - static void treset(void); - static void tresize(int, int); --static void tscrollup(int, int); --static void tscrolldown(int, int); -+static void tscrollup(int, int, int); -+static void tscrolldown(int, int, int); - static void tsetattr(int *, int); - static void tsetchar(Rune, Glyph *, int, int); - static void tsetscroll(int, int); -@@ -730,10 +737,10 @@ tlinelen(int y) - { - int i = term.col; - -- if (term.line[y][i - 1].mode & ATTR_WRAP) -+ if (TLINE(y)[i - 1].mode & ATTR_WRAP) - return i; - -- while (i > 0 && term.line[y][i - 1].u == ' ') -+ while (i > 0 && TLINE(y)[i - 1].u == ' ') - --i; - - return i; -@@ -795,7 +802,7 @@ selsnap(int *x, int *y, int direction) - * Snap around if the word wraps around at the end or - * beginning of a line. - */ -- prevgp = &term.line[*y][*x]; -+ prevgp = &TLINE(*y)[*x]; - prevdelim = ISDELIM(prevgp->u); - for (;;) { - newx = *x + direction; -@@ -810,14 +817,14 @@ selsnap(int *x, int *y, int direction) - yt = *y, xt = *x; - else - yt = newy, xt = newx; -- if (!(term.line[yt][xt].mode & ATTR_WRAP)) -+ if (!(TLINE(yt)[xt].mode & ATTR_WRAP)) - break; - } - - if (newx >= tlinelen(newy)) - break; - -- gp = &term.line[newy][newx]; -+ gp = &TLINE(newy)[newx]; - delim = ISDELIM(gp->u); - if (!(gp->mode & ATTR_WDUMMY) && (delim != prevdelim - || (delim && gp->u != prevgp->u))) -@@ -838,14 +845,14 @@ selsnap(int *x, int *y, int direction) - *x = (direction < 0) ? 0 : term.col - 1; - if (direction < 0) { - for (; *y > 0; *y += direction) { -- if (!(term.line[*y-1][term.col-1].mode -+ if (!(TLINE(*y-1)[term.col-1].mode - & ATTR_WRAP)) { - break; - } - } - } else if (direction > 0) { - for (; *y < term.row-1; *y += direction) { -- if (!(term.line[*y][term.col-1].mode -+ if (!(TLINE(*y)[term.col-1].mode - & ATTR_WRAP)) { - break; - } -@@ -1011,13 +1018,13 @@ getsel(void) - } - - if (sel.type == SEL_RECTANGULAR) { -- gp = &term.line[y][sel.nb.x]; -+ gp = &TLINE(y)[sel.nb.x]; - lastx = sel.ne.x; - } else { -- gp = &term.line[y][sel.nb.y == y ? sel.nb.x : 0]; -+ gp = &TLINE(y)[sel.nb.y == y ? sel.nb.x : 0]; - lastx = (sel.ne.y == y) ? sel.ne.x : term.col-1; - } -- last = &term.line[y][MIN(lastx, linelen-1)]; -+ last = &TLINE(y)[MIN(lastx, linelen-1)]; - while (last >= gp && last->u == ' ') - --last; - -@@ -1490,6 +1497,9 @@ ttyread(void) - /* keep any uncomplete utf8 char for the next call */ - memmove(buf, ptr, buflen); - -+ if (term.scr > 0 && term.scr < histsize-1) -+ term.scr++; -+ - return ret; - } - -@@ -1499,6 +1509,9 @@ ttywrite(const char *s, size_t n) - fd_set wfd, rfd; - ssize_t r; - size_t lim = 256; -+ Arg arg = (Arg){ .i = term.scr }; -+ -+ kscrolldown(&arg); - - /* - * Remember that we are using a pty, which might be a modem line. -@@ -1690,13 +1703,53 @@ tswapscreen(void) - } - - void --tscrolldown(int orig, int n) -+kscrolldown(const Arg* a) -+{ -+ int n = a->i; -+ -+ if (n < 0) -+ n = term.row + n; -+ -+ if (n > term.scr) -+ n = term.scr; -+ -+ if (term.scr > 0) { -+ term.scr -= n; -+ selscroll(0, -n); -+ tfulldirt(); -+ } -+} -+ -+void -+kscrollup(const Arg* a) -+{ -+ int n = a->i; -+ -+ if (n < 0) -+ n = term.row + n; -+ -+ if (term.scr <= histsize - n) { -+ term.scr += n; -+ selscroll(0, n); -+ tfulldirt(); -+ } -+} -+ -+void -+tscrolldown(int orig, int n, int copyhist) - { - int i; - Line temp; - - LIMIT(n, 0, term.bot-orig+1); - -+ if (copyhist) { -+ term.histi = (term.histi - 1 + histsize) % histsize; -+ temp = term.hist[term.histi]; -+ term.hist[term.histi] = term.line[term.bot]; -+ term.line[term.bot] = temp; -+ } -+ - tsetdirt(orig, term.bot-n); - tclearregion(0, term.bot-n+1, term.col-1, term.bot); - -@@ -1710,13 +1763,20 @@ tscrolldown(int orig, int n) - } - - void --tscrollup(int orig, int n) -+tscrollup(int orig, int n, int copyhist) - { - int i; - Line temp; - - LIMIT(n, 0, term.bot-orig+1); - -+ if (copyhist) { -+ term.histi = (term.histi + 1) % histsize; -+ temp = term.hist[term.histi]; -+ term.hist[term.histi] = term.line[orig]; -+ term.line[orig] = temp; -+ } -+ - tclearregion(0, orig, term.col-1, orig+n-1); - tsetdirt(orig+n, term.bot); - -@@ -1765,7 +1825,7 @@ tnewline(int first_col) - int y = term.c.y; - - if (y == term.bot) { -- tscrollup(term.top, 1); -+ tscrollup(term.top, 1, 1); - } else { - y++; - } -@@ -1930,14 +1990,14 @@ void - tinsertblankline(int n) - { - if (BETWEEN(term.c.y, term.top, term.bot)) -- tscrolldown(term.c.y, n); -+ tscrolldown(term.c.y, n, 0); - } - - void - tdeleteline(int n) - { - if (BETWEEN(term.c.y, term.top, term.bot)) -- tscrollup(term.c.y, n); -+ tscrollup(term.c.y, n, 0); - } - - int32_t -@@ -2371,11 +2431,11 @@ csihandle(void) - break; - case 'S': /* SU -- Scroll <n> line up */ - DEFAULT(csiescseq.arg[0], 1); -- tscrollup(term.top, csiescseq.arg[0]); -+ tscrollup(term.top, csiescseq.arg[0], 0); - break; - case 'T': /* SD -- Scroll <n> line down */ - DEFAULT(csiescseq.arg[0], 1); -- tscrolldown(term.top, csiescseq.arg[0]); -+ tscrolldown(term.top, csiescseq.arg[0], 0); - break; - case 'L': /* IL -- Insert <n> blank lines */ - DEFAULT(csiescseq.arg[0], 1); -@@ -2871,7 +2931,7 @@ eschandle(uchar ascii) - return 0; - case 'D': /* IND -- Linefeed */ - if (term.c.y == term.bot) { -- tscrollup(term.top, 1); -+ tscrollup(term.top, 1, 1); - } else { - tmoveto(term.c.x, term.c.y+1); - } -@@ -2884,7 +2944,7 @@ eschandle(uchar ascii) - break; - case 'M': /* RI -- Reverse index */ - if (term.c.y == term.top) { -- tscrolldown(term.top, 1); -+ tscrolldown(term.top, 1, 1); - } else { - tmoveto(term.c.x, term.c.y-1); - } -@@ -3047,7 +3107,7 @@ tputc(Rune u) - void - tresize(int col, int row) - { -- int i; -+ int i, j; - int minrow = MIN(row, term.row); - int mincol = MIN(col, term.col); - int *bp; -@@ -3087,6 +3147,14 @@ tresize(int col, int row) - term.dirty = xrealloc(term.dirty, row * sizeof(*term.dirty)); - term.tabs = xrealloc(term.tabs, col * sizeof(*term.tabs)); - -+ for (i = 0; i < histsize; i++) { -+ term.hist[i] = xrealloc(term.hist[i], col * sizeof(Glyph)); -+ for (j = mincol; j < col; j++) { -+ term.hist[i][j] = term.c.attr; -+ term.hist[i][j].u = ' '; -+ } -+ } -+ - /* resize each row to new width, zero-pad if needed */ - for (i = 0; i < minrow; i++) { - term.line[i] = xrealloc(term.line[i], col * sizeof(Glyph)); -@@ -3984,11 +4052,11 @@ drawregion(int x1, int y1, int x2, int y2) - term.dirty[y] = 0; - - specs = term.specbuf; -- numspecs = xmakeglyphfontspecs(specs, &term.line[y][x1], x2 - x1, x1, y); -+ numspecs = xmakeglyphfontspecs(specs, &TLINE(y)[x1], x2 - x1, x1, y); - - i = ox = 0; - for (x = x1; x < x2 && i < numspecs; x++) { -- new = term.line[y][x]; -+ new = TLINE(y)[x]; - if (new.mode == ATTR_WDUMMY) - continue; - if (ena_sel && selected(x, y)) -@@ -4008,7 +4076,8 @@ drawregion(int x1, int y1, int x2, int y2) - if (i > 0) - xdrawglyphfontspecs(specs, base, i, ox, y); - } -- xdrawcursor(); -+ if (term.scr == 0) -+ xdrawcursor(); - } - - void - diff --git a/st.suckless.org/patches/st-git-20160131-argbbg.diff b/st.suckless.org/patches/st-git-20160131-argbbg.diff @@ -1,161 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index fd09d72..d2cf4d6 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -96,6 +96,8 @@ static const char *colorname[] = { - "#555555", - }; - -+/* bg opacity */ -+static const int alpha = 0xdd; - - /* - * Default colors (colorname index) -@@ -123,6 +125,7 @@ static unsigned int mousefg = 7; - static unsigned int mousebg = 0; - - /* -+ "black", - * Colors used, when the specific fg == defaultfg. So in reverse mode this - * will reverse too. Another logic would only make the simple feature too - * complex. -diff --git a/config.mk b/config.mk -index 81e3e47..ab35200 100644 ---- a/config.mk -+++ b/config.mk -@@ -14,7 +14,7 @@ X11LIB = /usr/X11R6/lib - INCS = -I. -I/usr/include -I${X11INC} \ - `pkg-config --cflags fontconfig` \ - `pkg-config --cflags freetype2` --LIBS = -L/usr/lib -lc -L${X11LIB} -lm -lrt -lX11 -lutil -lXft \ -+LIBS = -L/usr/lib -lc -L${X11LIB} -lm -lrt -lX11 -lutil -lXft -lXrender \ - `pkg-config --libs fontconfig` \ - `pkg-config --libs freetype2` - -diff --git a/st.c b/st.c -index 41f6942..b908778 100644 ---- a/st.c -+++ b/st.c -@@ -61,6 +61,7 @@ char *argv0; - #define XK_ANY_MOD UINT_MAX - #define XK_NO_MOD 0 - #define XK_SWITCH_MOD (1<<13) -+#define OPAQUE 0xff - - /* macros */ - #define MIN(a, b) ((a) < (b) ? (a) : (b)) -@@ -79,6 +80,7 @@ char *argv0; - #define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + \ - (t1.tv_nsec-t2.tv_nsec)/1E6) - #define MODBIT(x, set, bit) ((set) ? ((x) |= (bit)) : ((x) &= ~(bit))) -+#define USE_ARGB (alpha != OPAQUE && opt_embed == NULL) - - #define TRUECOLOR(r,g,b) (1 << 24 | (r) << 16 | (g) << 8 | (b)) - #define IS_TRUECOL(x) (1 << 24 & (x)) -@@ -267,6 +269,7 @@ typedef struct { - int w, h; /* window width and height */ - int ch; /* char height */ - int cw; /* char width */ -+ int depth; /* bit depth */ - char state; /* focus, redraw, visible */ - int cursor; /* cursor style */ - } XWindow; -@@ -3137,8 +3140,7 @@ xresize(int col, int row) - xw.th = MAX(1, row * xw.ch); - - XFreePixmap(xw.dpy, xw.buf); -- xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h, -- DefaultDepth(xw.dpy, xw.scr)); -+ xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h, xw.depth); - XftDrawChange(xw.draw, xw.buf); - xclear(0, 0, xw.w, xw.h); - } -@@ -3192,6 +3194,14 @@ xloadcols(void) - else - die("Could not allocate color %d\n", i); - } -+ -+ /* set alpha value of bg color */ -+ if (USE_ARGB) { -+ dc.col[defaultbg].color.alpha = (0xffff * alpha) / OPAQUE; //0xcccc; -+ dc.col[defaultbg].pixel &= 0x00111111; -+ dc.col[defaultbg].pixel |= alpha << 24; // 0xcc000000; -+ } -+ - loaded = 1; - } - -@@ -3453,7 +3463,38 @@ xinit(void) - if (!(xw.dpy = XOpenDisplay(NULL))) - die("Can't open display\n"); - xw.scr = XDefaultScreen(xw.dpy); -- xw.vis = XDefaultVisual(xw.dpy, xw.scr); -+ xw.depth = (USE_ARGB) ? 32: XDefaultDepth(xw.dpy, xw.scr); -+ if (! USE_ARGB) -+ xw.vis = XDefaultVisual(xw.dpy, xw.scr); -+ else { -+ XVisualInfo *vis; -+ XRenderPictFormat *fmt; -+ int nvi; -+ int i; -+ -+ XVisualInfo tpl = { -+ .screen = xw.scr, -+ .depth = 32, -+ .class = TrueColor -+ }; -+ -+ vis = XGetVisualInfo(xw.dpy, VisualScreenMask | VisualDepthMask | VisualClassMask, &tpl, &nvi); -+ xw.vis = NULL; -+ for(i = 0; i < nvi; i ++) { -+ fmt = XRenderFindVisualFormat(xw.dpy, vis[i].visual); -+ if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) { -+ xw.vis = vis[i].visual; -+ break; -+ } -+ } -+ -+ XFree(vis); -+ -+ if (! xw.vis) { -+ fprintf(stderr, "Couldn't find ARGB visual.\n"); -+ exit(1); -+ } -+ } - - /* font */ - if (!FcInit()) -@@ -3463,7 +3504,10 @@ xinit(void) - xloadfonts(usedfont, 0); - - /* colors */ -- xw.cmap = XDefaultColormap(xw.dpy, xw.scr); -+ if (! USE_ARGB) -+ xw.cmap = XDefaultColormap(xw.dpy, xw.scr); -+ else -+ xw.cmap = XCreateColormap(xw.dpy, XRootWindow(xw.dpy, xw.scr), xw.vis, None); - xloadcols(); - - /* adjust fixed window geometry */ -@@ -3486,16 +3530,17 @@ xinit(void) - if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) - parent = XRootWindow(xw.dpy, xw.scr); - xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t, -- xw.w, xw.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput, -+ xw.w, xw.h, 0, xw.depth, InputOutput, - xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity - | CWEventMask | CWColormap, &xw.attrs); - - memset(&gcvalues, 0, sizeof(gcvalues)); - gcvalues.graphics_exposures = False; -- dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures, -+ xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h, xw.depth); -+ dc.gc = XCreateGC(xw.dpy, -+ (USE_ARGB)? xw.buf: parent, -+ GCGraphicsExposures, - &gcvalues); -- xw.buf = XCreatePixmap(xw.dpy, xw.win, xw.w, xw.h, -- DefaultDepth(xw.dpy, xw.scr)); - XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel); - XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, xw.w, xw.h); - diff --git a/st.suckless.org/patches/st-git-20160203-scrollback-mouse-altscreen.diff b/st.suckless.org/patches/st-git-20160203-scrollback-mouse-altscreen.diff @@ -1,40 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index db0bf24..1610013 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -143,8 +143,8 @@ static MouseShortcut mshortcuts[] = { - - static MouseKey mkeys[] = { - /* button mask function argument */ -- { Button4, ShiftMask, kscrollup, {.i = 1} }, -- { Button5, ShiftMask, kscrolldown, {.i = 1} }, -+ { Button4, XK_NO_MOD, kscrollup, {.i = 1} }, -+ { Button5, XK_NO_MOD, kscrolldown, {.i = 1} }, - }; - - /* Internal keyboard shortcuts. */ -diff --git a/st.c b/st.c -index 1c9df8f..acb4d8a 100644 ---- a/st.c -+++ b/st.c -@@ -967,13 +967,14 @@ bpress(XEvent *e) - return; - } - -- for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) { -- if (e->xbutton.button == ms->b -- && match(ms->mask, e->xbutton.state)) { -- ttysend(ms->s, strlen(ms->s)); -- return; -+ if (IS_SET(MODE_ALTSCREEN)) -+ for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) { -+ if (e->xbutton.button == ms->b -+ && match(ms->mask, e->xbutton.state)) { -+ ttysend(ms->s, strlen(ms->s)); -+ return; -+ } - } -- } - - for (mk = mkeys; mk < mkeys + LEN(mkeys); mk++) { - if (e->xbutton.button == mk->b diff --git a/st.suckless.org/patches/st-git-20160204-externalpipe.diff b/st.suckless.org/patches/st-git-20160204-externalpipe.diff @@ -1,75 +0,0 @@ -diff --git a/st.c b/st.c -index 0536b6f..59f982c 100644 ---- a/st.c -+++ b/st.c -@@ -335,6 +335,7 @@ static void printsel(const Arg *); - static void printscreen(const Arg *) ; - static void toggleprinter(const Arg *); - static void sendbreak(const Arg *); -+static void externalpipe(const Arg *); - - /* Config.h for applying patches and the configuration. */ - #include "config.h" -@@ -2923,6 +2924,62 @@ eschandle(uchar ascii) - } - - void -+externalpipe(const Arg *arg) -+{ -+ int to[2]; /* 0 = read, 1 = write */ -+ pid_t child; -+ int n; -+ void (*oldsigpipe)(int); -+ char buf[UTF_SIZ]; -+ Glyph *bp, *end; -+ -+ if(pipe(to) == -1) -+ return; -+ -+ /* sigchld() handles this */ -+ switch(child = fork()){ -+ case -1: -+ close(to[0]), close(to[1]); -+ return; -+ case 0: -+ /* child */ -+ close(to[1]); -+ dup2(to[0], STDIN_FILENO); /* 0<&to */ -+ close(to[0]); -+ execvp( -+ "sh", -+ (char *const []){ -+ "/bin/sh", -+ "-c", -+ (char *)arg->v, -+ 0 -+ }); -+ exit(127); -+ } -+ -+ /* parent */ -+ close(to[0]); -+ /* ignore sigpipe for now, in case child exits early */ -+ oldsigpipe = signal(SIGPIPE, SIG_IGN); -+ -+ for(n = 0; n < term.row; n++){ -+ bp = &term.line[n][0]; -+ end = &bp[MIN(tlinelen(n), term.col) - 1]; -+ if(bp != end || bp->u != ' ') -+ for(; bp <= end; ++bp) -+ if(xwrite(to[1], buf, utf8encode(bp->u, buf)) < 0) -+ break; -+ if(xwrite(to[1], "\n", 1) < 0) -+ break; -+ } -+ -+ close(to[1]); -+ -+ /* restore */ -+ signal(SIGPIPE, oldsigpipe); -+} -+ -+void - tputc(Rune u) - { - char c[UTF_SIZ]; diff --git a/st.suckless.org/patches/st-git-20160209-visualbell.diff b/st.suckless.org/patches/st-git-20160209-visualbell.diff @@ -1,42 +0,0 @@ -diff --git a/st.c b/st.c -index 0536b6f..948de40 100644 ---- a/st.c -+++ b/st.c -@@ -532,6 +532,7 @@ static char *opt_line = NULL; - static char *opt_name = NULL; - static char *opt_title = NULL; - static int oldbutton = 3; /* button event on startup: 3 = release */ -+static int bellon = 0; /* visual bell status */ - - static char *usedfont = NULL; - static double usedfontsize = 0; -@@ -2767,6 +2768,15 @@ tcontrolcode(uchar ascii) - xseturgency(1); - if (bellvolume) - XkbBell(xw.dpy, xw.win, bellvolume, (Atom)NULL); -+ -+ /* visual bell*/ -+ if (!bellon) { -+ bellon = 1; -+ MODBIT(term.mode, !IS_SET(MODE_REVERSE), MODE_REVERSE); -+ redraw(); -+ XFlush(xw.dpy); -+ MODBIT(term.mode, !IS_SET(MODE_REVERSE), MODE_REVERSE); -+ } - } - break; - case '\033': /* ESC */ -@@ -4303,7 +4313,12 @@ run(void) - (handler[ev.type])(&ev); - } - -- draw(); -+ if (bellon) { -+ bellon = 0; -+ redraw(); -+ } -+ else draw(); -+ - XFlush(xw.dpy); - - if (xev && !FD_ISSET(xfd, &rfd)) diff --git a/st.suckless.org/patches/st-git-20160210-copyurl.diff b/st.suckless.org/patches/st-git-20160210-copyurl.diff @@ -1,88 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index fd09d72..05fbba5 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -157,6 +157,7 @@ static Shortcut shortcuts[] = { - { MODKEY|ShiftMask, XK_C, clipcopy, {.i = 0} }, - { MODKEY|ShiftMask, XK_V, clippaste, {.i = 0} }, - { MODKEY, XK_Num_Lock, numlock, {.i = 0} }, -+ { MODKEY, XK_l, copyurl, {.i = 0} }, - }; - - /* -diff --git a/st.c b/st.c -index 41f6942..aa5ed41 100644 ---- a/st.c -+++ b/st.c -@@ -335,6 +335,7 @@ static void printsel(const Arg *); - static void printscreen(const Arg *) ; - static void toggleprinter(const Arg *); - static void sendbreak(const Arg *); -+static void copyurl(const Arg *); - - /* Config.h for applying patches and the configuration. */ - #include "config.h" -@@ -4411,3 +4412,63 @@ run: - return 0; - } - -+/* select and copy the previous url on screen (do nothing if there's no url). -+ * known bug: doesn't handle urls that span multiple lines (wontfix) -+ * known bug: only finds first url on line (mightfix) -+ */ -+void -+copyurl(const Arg *arg) { -+ /* () and [] can appear in urls, but excluding them here will reduce false -+ * positives when figuring out where a given url ends. -+ */ -+ static char URLCHARS[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" -+ "abcdefghijklmnopqrstuvwxyz" -+ "0123456789-._~:/?#@!$&'*+,;=%"; -+ -+ int i, row, startrow; -+ char *linestr = calloc(sizeof(char), term.col+1); /* assume ascii */ -+ char *c, *match = NULL; -+ -+ row = (sel.ob.x >= 0 && sel.nb.y > 0) ? sel.nb.y-1 : term.bot; -+ LIMIT(row, term.top, term.bot); -+ startrow = row; -+ -+ /* find the start of the last url before selection */ -+ do { -+ for (i = 0; i < term.col; ++i) { -+ if (term.line[row][i].u > 127) /* assume ascii */ -+ continue; -+ linestr[i] = term.line[row][i].u; -+ } -+ linestr[term.col] = '\0'; -+ if ((match = strstr(linestr, "http://")) -+ || (match = strstr(linestr, "https://"))) -+ break; -+ if (--row < term.top) -+ row = term.bot; -+ } while (row != startrow); -+ -+ if (match) { -+ /* must happen before trim */ -+ selclear(NULL); -+ sel.ob.x = strlen(linestr) - strlen(match); -+ -+ /* trim the rest of the line from the url match */ -+ for (c = match; *c != '\0'; ++c) -+ if (!strchr(URLCHARS, *c)) { -+ *c = '\0'; -+ break; -+ } -+ -+ /* select and copy */ -+ sel.mode = 1; -+ sel.type = SEL_REGULAR; -+ sel.oe.x = sel.ob.x + strlen(match)-1; -+ sel.ob.y = sel.oe.y = row; -+ selnormalize(); -+ tsetdirt(sel.nb.y, sel.ne.y); -+ selcopy(0); -+ } -+ -+ free(linestr); -+} diff --git a/st.suckless.org/patches/st-hidecursor-0.5.diff b/st.suckless.org/patches/st-hidecursor-0.5.diff @@ -0,0 +1,82 @@ +diff --git a/st.c b/st.c +index 392f12d..52deb92 100644 +--- a/st.c ++++ b/st.c +@@ -248,6 +248,8 @@ typedef struct { + Draw draw; + Visual *vis; + XSetWindowAttributes attrs; ++ Cursor cursor, bcursor; /* visible and blank cursors */ ++ bool cursorstate; /* is cursor currently visible */ + int scr; + bool isfixed; /* is fixed geometry? */ + int fx, fy, fw, fh; /* fixed geometry */ +@@ -1112,6 +1114,13 @@ void + bmotion(XEvent *e) { + int oldey, oldex, oldsby, oldsey; + ++ if(!xw.cursorstate) { ++ XDefineCursor(xw.dpy, xw.win, xw.cursor); ++ xw.cursorstate = true; ++ if(!IS_SET(MODE_MOUSEMANY)) ++ xsetpointermotion(0); ++ } ++ + if(IS_SET(MODE_MOUSE)) { + mousereport(e); + return; +@@ -2984,10 +2993,12 @@ xzoom(const Arg *arg) { + void + xinit(void) { + XGCValues gcvalues; +- Cursor cursor; + Window parent; + int sw, sh; + pid_t thispid = getpid(); ++ XColor xcwhite = {.red = 0xffff, .green = 0xffff, .blue = 0xffff}; ++ XColor xcblack = {.red = 0x0000, .green = 0x0000, .blue = 0x0000}; ++ Pixmap blankpm; + + if(!(xw.dpy = XOpenDisplay(NULL))) + die("Can't open display\n"); +@@ -3071,11 +3082,13 @@ xinit(void) { + die("XCreateIC failed. Could not obtain input method.\n"); + + /* white cursor, black outline */ +- cursor = XCreateFontCursor(xw.dpy, XC_xterm); +- XDefineCursor(xw.dpy, xw.win, cursor); +- XRecolorCursor(xw.dpy, cursor, +- &(XColor){.red = 0xffff, .green = 0xffff, .blue = 0xffff}, +- &(XColor){.red = 0x0000, .green = 0x0000, .blue = 0x0000}); ++ xw.cursor = XCreateFontCursor(xw.dpy, XC_xterm); ++ XDefineCursor(xw.dpy, xw.win, xw.cursor); ++ XRecolorCursor(xw.dpy, xw.cursor, &xcwhite, &xcblack); ++ xw.cursorstate = true; ++ blankpm = XCreateBitmapFromData(xw.dpy, xw.win, &(char){0}, 1, 1); ++ xw.bcursor = XCreatePixmapCursor(xw.dpy, blankpm, blankpm, ++ &xcblack, &xcblack, 0, 0); + + xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False); + xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False); +@@ -3537,6 +3550,8 @@ unmap(XEvent *ev) { + + void + xsetpointermotion(int set) { ++ if(!set && !xw.cursorstate) ++ return; + MODBIT(xw.attrs.event_mask, set, PointerMotionMask); + XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs); + } +@@ -3630,6 +3645,12 @@ kpress(XEvent *ev) { + Status status; + Shortcut *bp; + ++ if(xw.cursorstate) { ++ XDefineCursor(xw.dpy, xw.win, xw.bcursor); ++ xsetpointermotion(1); ++ xw.cursorstate = false; ++ } ++ + if(IS_SET(MODE_KBDLOCK)) + return; + diff --git a/st.suckless.org/patches/st-hidecursor-0.6.diff b/st.suckless.org/patches/st-hidecursor-0.6.diff @@ -0,0 +1,84 @@ +diff --git a/st.c b/st.c +index b89d094..d2979ff 100644 +--- a/st.c ++++ b/st.c +@@ -257,6 +257,11 @@ typedef struct { + Draw draw; + Visual *vis; + XSetWindowAttributes attrs; ++ /* Here, we use the term *pointer* to differentiate the cursor ++ * one sees when hovering the mouse over the terminal from, e.g., ++ * a green rectangle where text would be entered. */ ++ Cursor vpointer, bpointer; /* visible and hidden pointers */ ++ bool pointerisvisible; + int scr; + bool isfixed; /* is fixed geometry? */ + int l, t; /* left and top offset */ +@@ -1181,6 +1186,13 @@ void + bmotion(XEvent *e) { + int oldey, oldex, oldsby, oldsey; + ++ if(!xw.pointerisvisible) { ++ XDefineCursor(xw.dpy, xw.win, xw.vpointer); ++ xw.pointerisvisible = true; ++ if(!IS_SET(MODE_MOUSEMANY)) ++ xsetpointermotion(0); ++ } ++ + if(IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) { + mousereport(e); + return; +@@ -3182,9 +3194,11 @@ xzoomreset(const Arg *arg) { + void + xinit(void) { + XGCValues gcvalues; +- Cursor cursor; + Window parent; + pid_t thispid = getpid(); ++ XColor xcwhite = {.red = 0xffff, .green = 0xffff, .blue = 0xffff}; ++ XColor xcblack = {.red = 0x0000, .green = 0x0000, .blue = 0x0000}; ++ Pixmap blankpm; + + if(!(xw.dpy = XOpenDisplay(NULL))) + die("Can't open display\n"); +@@ -3257,11 +3271,13 @@ xinit(void) { + die("XCreateIC failed. Could not obtain input method.\n"); + + /* white cursor, black outline */ +- cursor = XCreateFontCursor(xw.dpy, XC_xterm); +- XDefineCursor(xw.dpy, xw.win, cursor); +- XRecolorCursor(xw.dpy, cursor, +- &(XColor){.red = 0xffff, .green = 0xffff, .blue = 0xffff}, +- &(XColor){.red = 0x0000, .green = 0x0000, .blue = 0x0000}); ++ xw.vpointer = XCreateFontCursor(xw.dpy, XC_xterm); ++ XDefineCursor(xw.dpy, xw.win, xw.vpointer); ++ XRecolorCursor(xw.dpy, xw.vpointer, &xcwhite, &xcblack); ++ xw.pointerisvisible = true; ++ blankpm = XCreateBitmapFromData(xw.dpy, xw.win, &(char){0}, 1, 1); ++ xw.bpointer = XCreatePixmapCursor(xw.dpy, blankpm, blankpm, ++ &xcblack, &xcblack, 0, 0); + + xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False); + xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False); +@@ -3725,6 +3741,8 @@ unmap(XEvent *ev) { + + void + xsetpointermotion(int set) { ++ if(!set && !xw.pointerisvisible) ++ return; + MODBIT(xw.attrs.event_mask, set, PointerMotionMask); + XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs); + } +@@ -3818,6 +3836,12 @@ kpress(XEvent *ev) { + Status status; + Shortcut *bp; + ++ if(xw.pointerisvisible) { ++ XDefineCursor(xw.dpy, xw.win, xw.bpointer); ++ xsetpointermotion(1); ++ xw.pointerisvisible = false; ++ } ++ + if(IS_SET(MODE_KBDLOCK)) + return; + diff --git a/st.suckless.org/patches/st-hidecursor-20160727-308bfbf.diff b/st.suckless.org/patches/st-hidecursor-20160727-308bfbf.diff @@ -0,0 +1,88 @@ +diff --git a/st.c b/st.c +index 2594c65..2a031f0 100644 +--- a/st.c ++++ b/st.c +@@ -260,6 +260,11 @@ typedef struct { + Draw draw; + Visual *vis; + XSetWindowAttributes attrs; ++ /* Here, we use the term *pointer* to differentiate the cursor ++ * one sees when hovering the mouse over the terminal from, e.g., ++ * a green rectangle where text would be entered. */ ++ Cursor vpointer, bpointer; /* visible and hidden pointers */ ++ int pointerisvisible; + int scr; + int isfixed; /* is fixed geometry? */ + int l, t; /* left and top offset */ +@@ -1291,6 +1296,13 @@ bmotion(XEvent *e) + { + int oldey, oldex, oldsby, oldsey; + ++ if(!xw.pointerisvisible) { ++ XDefineCursor(xw.dpy, xw.win, xw.vpointer); ++ xw.pointerisvisible = 1; ++ if(!IS_SET(MODE_MOUSEMANY)) ++ xsetpointermotion(0); ++ } ++ + if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) { + mousereport(e); + return; +@@ -3435,10 +3447,10 @@ void + xinit(void) + { + XGCValues gcvalues; +- Cursor cursor; + Window parent; + pid_t thispid = getpid(); + XColor xmousefg, xmousebg; ++ Pixmap blankpm; + + if (!(xw.dpy = XOpenDisplay(NULL))) + die("Can't open display\n"); +@@ -3511,8 +3523,9 @@ xinit(void) + die("XCreateIC failed. Could not obtain input method.\n"); + + /* white cursor, black outline */ +- cursor = XCreateFontCursor(xw.dpy, mouseshape); +- XDefineCursor(xw.dpy, xw.win, cursor); ++ xw.pointerisvisible = 1; ++ xw.vpointer = XCreateFontCursor(xw.dpy, mouseshape); ++ XDefineCursor(xw.dpy, xw.win, xw.vpointer); + + if (XParseColor(xw.dpy, xw.cmap, colorname[mousefg], &xmousefg) == 0) { + xmousefg.red = 0xffff; +@@ -3526,7 +3539,10 @@ xinit(void) + xmousebg.blue = 0x0000; + } + +- XRecolorCursor(xw.dpy, cursor, &xmousefg, &xmousebg); ++ XRecolorCursor(xw.dpy, xw.vpointer, &xmousefg, &xmousebg); ++ blankpm = XCreateBitmapFromData(xw.dpy, xw.win, &(char){0}, 1, 1); ++ xw.bpointer = XCreatePixmapCursor(xw.dpy, blankpm, blankpm, ++ &xmousefg, &xmousebg, 0, 0); + + xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False); + xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False); +@@ -4026,6 +4042,8 @@ unmap(XEvent *ev) + void + xsetpointermotion(int set) + { ++ if(!set && !xw.pointerisvisible) ++ return; + MODBIT(xw.attrs.event_mask, set, PointerMotionMask); + XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs); + } +@@ -4125,6 +4143,12 @@ kpress(XEvent *ev) + Status status; + Shortcut *bp; + ++ if(xw.pointerisvisible) { ++ XDefineCursor(xw.dpy, xw.win, xw.bpointer); ++ xsetpointermotion(1); ++ xw.pointerisvisible = 0; ++ } ++ + if (IS_SET(MODE_KBDLOCK)) + return; + diff --git a/st.suckless.org/patches/st-no_bold_colors-0.5.diff b/st.suckless.org/patches/st-no_bold_colors-0.5.diff @@ -0,0 +1,13 @@ +diff --git a/st.c b/st.c +index 392f12d..f893147 100644 +--- a/st.c ++++ b/st.c +@@ -3152,7 +3152,7 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { + if(base.mode & ATTR_BOLD) { + if(BETWEEN(base.fg, 0, 7)) { + /* basic system colors */ +- fg = &dc.col[base.fg + 8]; ++ fg = &dc.col[base.fg]; + } else if(BETWEEN(base.fg, 16, 195)) { + /* 256 colors */ + fg = &dc.col[base.fg + 36]; diff --git a/st.suckless.org/patches/st-no_bold_colors-0.6.diff b/st.suckless.org/patches/st-no_bold_colors-0.6.diff @@ -0,0 +1,13 @@ +diff --git a/st.c b/st.c +index b89d094..02bcf19 100644 +--- a/st.c ++++ b/st.c +@@ -3454,7 +3454,7 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i + + /* Change basic system colors [0-7] to bright system colors [8-15] */ + if((base.mode & ATTR_BOLD_FAINT) == ATTR_BOLD && BETWEEN(base.fg, 0, 7)) +- fg = &dc.col[base.fg + 8]; ++ fg = &dc.col[base.fg]; + + if(IS_SET(MODE_REVERSE)) { + if(fg == &dc.col[defaultfg]) { diff --git a/st.suckless.org/patches/st-no_bold_colors-20160727-308bfbf.diff b/st.suckless.org/patches/st-no_bold_colors-20160727-308bfbf.diff @@ -0,0 +1,13 @@ +diff --git a/st.c b/st.c +index 2594c65..f6fe717 100644 +--- a/st.c ++++ b/st.c +@@ -3719,7 +3719,7 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i + + /* Change basic system colors [0-7] to bright system colors [8-15] */ + if ((base.mode & ATTR_BOLD_FAINT) == ATTR_BOLD && BETWEEN(base.fg, 0, 7)) +- fg = &dc.col[base.fg + 8]; ++ fg = &dc.col[base.fg]; + + if (IS_SET(MODE_REVERSE)) { + if (fg == &dc.col[defaultfg]) { diff --git a/st.suckless.org/patches/st-openbsd-20160727-308bfbf.diff b/st.suckless.org/patches/st-openbsd-20160727-308bfbf.diff @@ -0,0 +1,27 @@ +diff --git a/Makefile b/Makefile +index 6158ab2..9b81f88 100644 +--- a/Makefile ++++ b/Makefile +@@ -49,7 +49,8 @@ install: all + @sed "s/VERSION/${VERSION}/g" < st.1 > ${DESTDIR}${MANPREFIX}/man1/st.1 + @chmod 644 ${DESTDIR}${MANPREFIX}/man1/st.1 + @echo Please see the README file regarding the terminfo entry of st. +- @tic -s st.info ++ @sed 's/st\([^t].*\)/st-git\1/g' st.info > st-git.info ++ @tic -s st-git.info + + uninstall: + @echo removing executable file from ${DESTDIR}${PREFIX}/bin +diff --git a/config.def.h b/config.def.h +index b41747f..60ffcb6 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -63,7 +63,7 @@ static unsigned int cursorthickness = 2; + static int bellvolume = 0; + + /* default TERM value */ +-static char termname[] = "st-256color"; ++static char termname[] = "st-git-256color"; + + /* + * spaces per tab diff --git a/st.suckless.org/patches/st-scrollback-20160727-308bfbf.diff b/st.suckless.org/patches/st-scrollback-20160727-308bfbf.diff @@ -0,0 +1,387 @@ +diff --git a/config.def.h b/config.def.h +index b41747f..eae969e 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -7,6 +7,7 @@ + */ + static char font[] = "Liberation Mono:pixelsize=12:antialias=true:autohint=true"; + static int borderpx = 2; ++#define histsize 2000 + + /* + * What program is execed by st depends of these precedence rules: +@@ -172,6 +173,8 @@ static Shortcut shortcuts[] = { + { MODKEY|ShiftMask, XK_C, clipcopy, {.i = 0} }, + { MODKEY|ShiftMask, XK_V, clippaste, {.i = 0} }, + { MODKEY, XK_Num_Lock, numlock, {.i = 0} }, ++ { ShiftMask, XK_Page_Up, kscrollup, {.i = -1} }, ++ { ShiftMask, XK_Page_Down, kscrolldown, {.i = -1} }, + }; + + /* +diff --git a/st.c b/st.c +index 2594c65..233d301 100644 +--- a/st.c ++++ b/st.c +@@ -86,6 +86,8 @@ char *argv0; + #define TRUERED(x) (((x) & 0xff0000) >> 8) + #define TRUEGREEN(x) (((x) & 0xff00)) + #define TRUEBLUE(x) (((x) & 0xff) << 8) ++#define TLINE(y) ((y) < term.scr ? term.hist[((y) + term.histi - term.scr \ ++ + histsize + 1) % histsize] : term.line[(y) - term.scr]) + + + enum glyph_attribute { +@@ -228,26 +230,6 @@ typedef struct { + int narg; /* nb of args */ + } STREscape; + +-/* Internal representation of the screen */ +-typedef struct { +- int row; /* nb row */ +- int col; /* nb col */ +- Line *line; /* screen */ +- Line *alt; /* alternate screen */ +- int *dirty; /* dirtyness of lines */ +- XftGlyphFontSpec *specbuf; /* font spec buffer used for rendering */ +- TCursor c; /* cursor */ +- int top; /* top scroll limit */ +- int bot; /* bottom scroll limit */ +- int mode; /* terminal mode flags */ +- int esc; /* escape state flags */ +- char trantbl[4]; /* charset table translation */ +- int charset; /* current charset */ +- int icharset; /* selected charset for sequence */ +- int numlock; /* lock numbers in keyboard */ +- int *tabs; +-} Term; +- + /* Purely graphic info */ + typedef struct { + Display *dpy; +@@ -327,6 +309,8 @@ typedef struct { + /* function definitions used in config.h */ + static void clipcopy(const Arg *); + static void clippaste(const Arg *); ++static void kscrolldown(const Arg *); ++static void kscrollup(const Arg *); + static void numlock(const Arg *); + static void selpaste(const Arg *); + static void xzoom(const Arg *); +@@ -340,6 +324,29 @@ static void sendbreak(const Arg *); + /* Config.h for applying patches and the configuration. */ + #include "config.h" + ++/* Internal representation of the screen */ ++typedef struct { ++ int row; /* nb row */ ++ int col; /* nb col */ ++ Line *line; /* screen */ ++ Line *alt; /* alternate screen */ ++ Line hist[histsize]; /* history buffer */ ++ int histi; /* history index */ ++ int scr; /* scroll back */ ++ int *dirty; /* dirtyness of lines */ ++ XftGlyphFontSpec *specbuf; /* font spec buffer used for rendering */ ++ TCursor c; /* cursor */ ++ int top; /* top scroll limit */ ++ int bot; /* bottom scroll limit */ ++ int mode; /* terminal mode flags */ ++ int esc; /* escape state flags */ ++ char trantbl[4]; /* charset table translation */ ++ int charset; /* current charset */ ++ int icharset; /* selected charset for sequence */ ++ int numlock; /* lock numbers in keyboard */ ++ int *tabs; ++} Term; ++ + /* Font structure */ + typedef struct { + int height; +@@ -399,8 +406,8 @@ static void tputtab(int); + static void tputc(Rune); + static void treset(void); + static void tresize(int, int); +-static void tscrollup(int, int); +-static void tscrolldown(int, int); ++static void tscrollup(int, int, int); ++static void tscrolldown(int, int, int); + static void tsetattr(int *, int); + static void tsetchar(Rune, Glyph *, int, int); + static void tsetscroll(int, int); +@@ -731,10 +738,10 @@ tlinelen(int y) + { + int i = term.col; + +- if (term.line[y][i - 1].mode & ATTR_WRAP) ++ if (TLINE(y)[i - 1].mode & ATTR_WRAP) + return i; + +- while (i > 0 && term.line[y][i - 1].u == ' ') ++ while (i > 0 && TLINE(y)[i - 1].u == ' ') + --i; + + return i; +@@ -796,7 +803,7 @@ selsnap(int *x, int *y, int direction) + * Snap around if the word wraps around at the end or + * beginning of a line. + */ +- prevgp = &term.line[*y][*x]; ++ prevgp = &TLINE(*y)[*x]; + prevdelim = ISDELIM(prevgp->u); + for (;;) { + newx = *x + direction; +@@ -811,14 +818,14 @@ selsnap(int *x, int *y, int direction) + yt = *y, xt = *x; + else + yt = newy, xt = newx; +- if (!(term.line[yt][xt].mode & ATTR_WRAP)) ++ if (!(TLINE(yt)[xt].mode & ATTR_WRAP)) + break; + } + + if (newx >= tlinelen(newy)) + break; + +- gp = &term.line[newy][newx]; ++ gp = &TLINE(newy)[newx]; + delim = ISDELIM(gp->u); + if (!(gp->mode & ATTR_WDUMMY) && (delim != prevdelim + || (delim && gp->u != prevgp->u))) +@@ -839,14 +846,14 @@ selsnap(int *x, int *y, int direction) + *x = (direction < 0) ? 0 : term.col - 1; + if (direction < 0) { + for (; *y > 0; *y += direction) { +- if (!(term.line[*y-1][term.col-1].mode ++ if (!(TLINE(*y-1)[term.col-1].mode + & ATTR_WRAP)) { + break; + } + } + } else if (direction > 0) { + for (; *y < term.row-1; *y += direction) { +- if (!(term.line[*y][term.col-1].mode ++ if (!(TLINE(*y)[term.col-1].mode + & ATTR_WRAP)) { + break; + } +@@ -1012,13 +1019,13 @@ getsel(void) + } + + if (sel.type == SEL_RECTANGULAR) { +- gp = &term.line[y][sel.nb.x]; ++ gp = &TLINE(y)[sel.nb.x]; + lastx = sel.ne.x; + } else { +- gp = &term.line[y][sel.nb.y == y ? sel.nb.x : 0]; ++ gp = &TLINE(y)[sel.nb.y == y ? sel.nb.x : 0]; + lastx = (sel.ne.y == y) ? sel.ne.x : term.col-1; + } +- last = &term.line[y][MIN(lastx, linelen-1)]; ++ last = &TLINE(y)[MIN(lastx, linelen-1)]; + while (last >= gp && last->u == ' ') + --last; + +@@ -1490,6 +1497,9 @@ ttyread(void) + /* keep any uncomplete utf8 char for the next call */ + memmove(buf, ptr, buflen); + ++ if (term.scr > 0 && term.scr < histsize-1) ++ term.scr++; ++ + return ret; + } + +@@ -1499,6 +1509,9 @@ ttywrite(const char *s, size_t n) + fd_set wfd, rfd; + ssize_t r; + size_t lim = 256; ++ Arg arg = (Arg){ .i = term.scr }; ++ ++ kscrolldown(&arg); + + /* + * Remember that we are using a pty, which might be a modem line. +@@ -1690,13 +1703,53 @@ tswapscreen(void) + } + + void +-tscrolldown(int orig, int n) ++kscrolldown(const Arg* a) ++{ ++ int n = a->i; ++ ++ if (n < 0) ++ n = term.row + n; ++ ++ if (n > term.scr) ++ n = term.scr; ++ ++ if (term.scr > 0) { ++ term.scr -= n; ++ selscroll(0, -n); ++ tfulldirt(); ++ } ++} ++ ++void ++kscrollup(const Arg* a) ++{ ++ int n = a->i; ++ ++ if (n < 0) ++ n = term.row + n; ++ ++ if (term.scr <= histsize - n) { ++ term.scr += n; ++ selscroll(0, n); ++ tfulldirt(); ++ } ++} ++ ++void ++tscrolldown(int orig, int n, int copyhist) + { + int i; + Line temp; + + LIMIT(n, 0, term.bot-orig+1); + ++ if (copyhist) { ++ term.histi = (term.histi - 1 + histsize) % histsize; ++ temp = term.hist[term.histi]; ++ term.hist[term.histi] = term.line[term.bot]; ++ term.line[term.bot] = temp; ++ } ++ + tsetdirt(orig, term.bot-n); + tclearregion(0, term.bot-n+1, term.col-1, term.bot); + +@@ -1710,13 +1763,20 @@ tscrolldown(int orig, int n) + } + + void +-tscrollup(int orig, int n) ++tscrollup(int orig, int n, int copyhist) + { + int i; + Line temp; + + LIMIT(n, 0, term.bot-orig+1); + ++ if (copyhist) { ++ term.histi = (term.histi + 1) % histsize; ++ temp = term.hist[term.histi]; ++ term.hist[term.histi] = term.line[orig]; ++ term.line[orig] = temp; ++ } ++ + tclearregion(0, orig, term.col-1, orig+n-1); + tsetdirt(orig+n, term.bot); + +@@ -1765,7 +1825,7 @@ tnewline(int first_col) + int y = term.c.y; + + if (y == term.bot) { +- tscrollup(term.top, 1); ++ tscrollup(term.top, 1, 1); + } else { + y++; + } +@@ -1930,14 +1990,14 @@ void + tinsertblankline(int n) + { + if (BETWEEN(term.c.y, term.top, term.bot)) +- tscrolldown(term.c.y, n); ++ tscrolldown(term.c.y, n, 0); + } + + void + tdeleteline(int n) + { + if (BETWEEN(term.c.y, term.top, term.bot)) +- tscrollup(term.c.y, n); ++ tscrollup(term.c.y, n, 0); + } + + int32_t +@@ -2371,11 +2431,11 @@ csihandle(void) + break; + case 'S': /* SU -- Scroll <n> line up */ + DEFAULT(csiescseq.arg[0], 1); +- tscrollup(term.top, csiescseq.arg[0]); ++ tscrollup(term.top, csiescseq.arg[0], 0); + break; + case 'T': /* SD -- Scroll <n> line down */ + DEFAULT(csiescseq.arg[0], 1); +- tscrolldown(term.top, csiescseq.arg[0]); ++ tscrolldown(term.top, csiescseq.arg[0], 0); + break; + case 'L': /* IL -- Insert <n> blank lines */ + DEFAULT(csiescseq.arg[0], 1); +@@ -2871,7 +2931,7 @@ eschandle(uchar ascii) + return 0; + case 'D': /* IND -- Linefeed */ + if (term.c.y == term.bot) { +- tscrollup(term.top, 1); ++ tscrollup(term.top, 1, 1); + } else { + tmoveto(term.c.x, term.c.y+1); + } +@@ -2884,7 +2944,7 @@ eschandle(uchar ascii) + break; + case 'M': /* RI -- Reverse index */ + if (term.c.y == term.top) { +- tscrolldown(term.top, 1); ++ tscrolldown(term.top, 1, 1); + } else { + tmoveto(term.c.x, term.c.y-1); + } +@@ -3047,7 +3107,7 @@ tputc(Rune u) + void + tresize(int col, int row) + { +- int i; ++ int i, j; + int minrow = MIN(row, term.row); + int mincol = MIN(col, term.col); + int *bp; +@@ -3087,6 +3147,14 @@ tresize(int col, int row) + term.dirty = xrealloc(term.dirty, row * sizeof(*term.dirty)); + term.tabs = xrealloc(term.tabs, col * sizeof(*term.tabs)); + ++ for (i = 0; i < histsize; i++) { ++ term.hist[i] = xrealloc(term.hist[i], col * sizeof(Glyph)); ++ for (j = mincol; j < col; j++) { ++ term.hist[i][j] = term.c.attr; ++ term.hist[i][j].u = ' '; ++ } ++ } ++ + /* resize each row to new width, zero-pad if needed */ + for (i = 0; i < minrow; i++) { + term.line[i] = xrealloc(term.line[i], col * sizeof(Glyph)); +@@ -3976,11 +4044,11 @@ drawregion(int x1, int y1, int x2, int y2) + term.dirty[y] = 0; + + specs = term.specbuf; +- numspecs = xmakeglyphfontspecs(specs, &term.line[y][x1], x2 - x1, x1, y); ++ numspecs = xmakeglyphfontspecs(specs, &TLINE(y)[x1], x2 - x1, x1, y); + + i = ox = 0; + for (x = x1; x < x2 && i < numspecs; x++) { +- new = term.line[y][x]; ++ new = TLINE(y)[x]; + if (new.mode == ATTR_WDUMMY) + continue; + if (ena_sel && selected(x, y)) +@@ -4000,7 +4068,8 @@ drawregion(int x1, int y1, int x2, int y2) + if (i > 0) + xdrawglyphfontspecs(specs, base, i, ox, y); + } +- xdrawcursor(); ++ if (term.scr == 0) ++ xdrawcursor(); + } + + void diff --git a/st.suckless.org/patches/st-scrollback-mouse-20160727-308bfbf.diff b/st.suckless.org/patches/st-scrollback-mouse-20160727-308bfbf.diff @@ -0,0 +1,62 @@ +diff --git a/config.def.h b/config.def.h +index b41747f..5ab8d2e 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -151,8 +151,14 @@ static unsigned int defaultunderline = 7; + */ + static MouseShortcut mshortcuts[] = { + /* button mask string */ +- { Button4, XK_ANY_MOD, "\031" }, +- { Button5, XK_ANY_MOD, "\005" }, ++ { Button4, XK_NO_MOD, "\031" }, ++ { Button5, XK_NO_MOD, "\005" }, ++}; ++ ++static MouseKey mkeys[] = { ++ /* button mask function argument */ ++ { Button4, ShiftMask, kscrollup, {.i = 1} }, ++ { Button5, ShiftMask, kscrolldown, {.i = 1} }, + }; + + /* Internal keyboard shortcuts. */ +diff --git a/st.c b/st.c +index 2594c65..9744bcf 100644 +--- a/st.c ++++ b/st.c +@@ -318,6 +318,13 @@ typedef union { + } Arg; + + typedef struct { ++ uint b; ++ uint mask; ++ void (*func)(const Arg *); ++ const Arg arg; ++} MouseKey; ++ ++typedef struct { + uint mod; + KeySym keysym; + void (*func)(const Arg *); +@@ -946,6 +953,7 @@ bpress(XEvent *e) + { + struct timespec now; + MouseShortcut *ms; ++ MouseKey *mk; + + if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) { + mousereport(e); +@@ -960,6 +968,14 @@ bpress(XEvent *e) + } + } + ++ for (mk = mkeys; mk < mkeys + LEN(mkeys); mk++) { ++ if (e->xbutton.button == mk->b ++ && match(mk->mask, e->xbutton.state)) { ++ mk->func(&mk->arg); ++ return; ++ } ++ } ++ + if (e->xbutton.button == Button1) { + clock_gettime(CLOCK_MONOTONIC, &now); + diff --git a/st.suckless.org/patches/st-scrollback-mouse-altscreen-20160727-308bfbf.diff b/st.suckless.org/patches/st-scrollback-mouse-altscreen-20160727-308bfbf.diff @@ -0,0 +1,25 @@ +diff --git a/st.c b/st.c +index 2594c65..bf5dc3e 100644 +--- a/st.c ++++ b/st.c +@@ -952,13 +952,14 @@ bpress(XEvent *e) + return; + } + +- for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) { +- if (e->xbutton.button == ms->b +- && match(ms->mask, e->xbutton.state)) { +- ttysend(ms->s, strlen(ms->s)); +- return; ++ if (IS_SET(MODE_ALTSCREEN)) ++ for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) { ++ if (e->xbutton.button == ms->b ++ && match(ms->mask, e->xbutton.state)) { ++ ttysend(ms->s, strlen(ms->s)); ++ return; ++ } + } +- } + + if (e->xbutton.button == Button1) { + clock_gettime(CLOCK_MONOTONIC, &now); diff --git a/st.suckless.org/patches/st-solarized-both-20160727-308bfbf.diff b/st.suckless.org/patches/st-solarized-both-20160727-308bfbf.diff @@ -0,0 +1,189 @@ +diff --git a/config.def.h b/config.def.h +index b41747f..adaa9b8 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -84,42 +84,54 @@ static unsigned int tabspaces = 8; + + /* Terminal colors (16 first used in escape sequence) */ + static const char *colorname[] = { +- /* 8 normal colors */ +- "black", +- "red3", +- "green3", +- "yellow3", +- "blue2", +- "magenta3", +- "cyan3", +- "gray90", +- +- /* 8 bright colors */ +- "gray50", +- "red", +- "green", +- "yellow", +- "#5c5cff", +- "magenta", +- "cyan", +- "white", +- +- [255] = 0, +- +- /* more colors can be added after 255 to use with DefaultXX */ +- "#cccccc", +- "#555555", ++ /* solarized dark */ ++ "#073642", /* 0: black */ ++ "#dc322f", /* 1: red */ ++ "#859900", /* 2: green */ ++ "#b58900", /* 3: yellow */ ++ "#268bd2", /* 4: blue */ ++ "#d33682", /* 5: magenta */ ++ "#2aa198", /* 6: cyan */ ++ "#eee8d5", /* 7: white */ ++ "#002b36", /* 8: brblack */ ++ "#cb4b16", /* 9: brred */ ++ "#586e75", /* 10: brgreen */ ++ "#657b83", /* 11: bryellow */ ++ "#839496", /* 12: brblue */ ++ "#6c71c4", /* 13: brmagenta*/ ++ "#93a1a1", /* 14: brcyan */ ++ "#fdf6e3", /* 15: brwhite */ + }; + ++/* Terminal colors for alternate (light) palette */ ++static const char *altcolorname[] = { ++ /* solarized light */ ++ "#eee8d5", /* 0: black */ ++ "#dc322f", /* 1: red */ ++ "#859900", /* 2: green */ ++ "#b58900", /* 3: yellow */ ++ "#268bd2", /* 4: blue */ ++ "#d33682", /* 5: magenta */ ++ "#2aa198", /* 6: cyan */ ++ "#073642", /* 7: white */ ++ "#fdf6e3", /* 8: brblack */ ++ "#cb4b16", /* 9: brred */ ++ "#93a1a1", /* 10: brgreen */ ++ "#839496", /* 11: bryellow */ ++ "#657b83", /* 12: brblue */ ++ "#6c71c4", /* 13: brmagenta*/ ++ "#586e75", /* 14: brcyan */ ++ "#002b36", /* 15: brwhite */ ++}; + + /* + * Default colors (colorname index) + * foreground, background, cursor, reverse cursor + */ +-static unsigned int defaultfg = 7; +-static unsigned int defaultbg = 0; +-static unsigned int defaultcs = 256; +-static unsigned int defaultrcs = 257; ++static unsigned int defaultfg = 12; ++static unsigned int defaultbg = 8; ++static unsigned int defaultcs = 14; ++static unsigned int defaultrcs = 15; + + /* + * Default shape of cursor +@@ -172,6 +184,7 @@ static Shortcut shortcuts[] = { + { MODKEY|ShiftMask, XK_C, clipcopy, {.i = 0} }, + { MODKEY|ShiftMask, XK_V, clippaste, {.i = 0} }, + { MODKEY, XK_Num_Lock, numlock, {.i = 0} }, ++ { XK_ANY_MOD, XK_F6, swapcolors, {.i = 0} }, + }; + + /* +diff --git a/st.c b/st.c +index 2594c65..b4a3089 100644 +--- a/st.c ++++ b/st.c +@@ -328,6 +328,7 @@ typedef struct { + static void clipcopy(const Arg *); + static void clippaste(const Arg *); + static void numlock(const Arg *); ++static void swapcolors(const Arg *); + static void selpaste(const Arg *); + static void xzoom(const Arg *); + static void xzoomabs(const Arg *); +@@ -355,7 +356,7 @@ typedef struct { + + /* Drawing Context */ + typedef struct { +- Color col[MAX(LEN(colorname), 256)]; ++ Color col[MAX(MAX(LEN(colorname), LEN(altcolorname)), 256)]; + Font font, bfont, ifont, ibfont; + GC gc; + } DC; +@@ -533,6 +534,8 @@ static char *opt_name = NULL; + static char *opt_title = NULL; + static int oldbutton = 3; /* button event on startup: 3 = release */ + ++static int usealtcolors = 0; /* 1 to use alternate palette */ ++ + static char *usedfont = NULL; + static double usedfontsize = 0; + static double defaultfontsize = 0; +@@ -3148,6 +3151,11 @@ sixd_to_16bit(int x) + return x == 0 ? 0 : 0x3737 + 0x2828 * x; + } + ++const char* getcolorname(int i) ++{ ++ return (usealtcolors) ? altcolorname[i] : colorname[i]; ++} ++ + int + xloadcolor(int i, const char *name, Color *ncolor) + { +@@ -3166,7 +3174,7 @@ xloadcolor(int i, const char *name, Color *ncolor) + return XftColorAllocValue(xw.dpy, xw.vis, + xw.cmap, &color, ncolor); + } else +- name = colorname[i]; ++ name = getcolorname(i); + } + + return XftColorAllocName(xw.dpy, xw.vis, xw.cmap, name, ncolor); +@@ -3186,8 +3194,8 @@ xloadcols(void) + + for (i = 0; i < LEN(dc.col); i++) + if (!xloadcolor(i, NULL, &dc.col[i])) { +- if (colorname[i]) +- die("Could not allocate color '%s'\n", colorname[i]); ++ if (getcolorname(i)) ++ die("Could not allocate color '%s'\n", getcolorname(i)); + else + die("Could not allocate color %d\n", i); + } +@@ -3514,13 +3522,13 @@ xinit(void) + cursor = XCreateFontCursor(xw.dpy, mouseshape); + XDefineCursor(xw.dpy, xw.win, cursor); + +- if (XParseColor(xw.dpy, xw.cmap, colorname[mousefg], &xmousefg) == 0) { ++ if (XParseColor(xw.dpy, xw.cmap, getcolorname(mousefg), &xmousefg) == 0) { + xmousefg.red = 0xffff; + xmousefg.green = 0xffff; + xmousefg.blue = 0xffff; + } + +- if (XParseColor(xw.dpy, xw.cmap, colorname[mousebg], &xmousebg) == 0) { ++ if (XParseColor(xw.dpy, xw.cmap, getcolorname(mousebg), &xmousebg) == 0) { + xmousebg.red = 0x0000; + xmousebg.green = 0x0000; + xmousebg.blue = 0x0000; +@@ -4074,6 +4082,14 @@ numlock(const Arg *dummy) + term.numlock ^= 1; + } + ++void ++swapcolors(const Arg *dummy) ++{ ++ usealtcolors = !usealtcolors; ++ xloadcols(); ++ redraw(); ++} ++ + char* + kmap(KeySym k, uint state) + { diff --git a/st.suckless.org/patches/st-solarized-dark-0.5.diff b/st.suckless.org/patches/st-solarized-dark-0.5.diff @@ -0,0 +1,65 @@ +diff --git a/config.def.h b/config.def.h +index 58b470e..f1c5ed1 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -51,30 +51,23 @@ static unsigned int tabspaces = 8; + + /* Terminal colors (16 first used in escape sequence) */ + static const char *colorname[] = { +- /* 8 normal colors */ +- "black", +- "red3", +- "green3", +- "yellow3", +- "blue2", +- "magenta3", +- "cyan3", +- "gray90", +- +- /* 8 bright colors */ +- "gray50", +- "red", +- "green", +- "yellow", +- "#5c5cff", +- "magenta", +- "cyan", +- "white", +- +- [255] = 0, +- +- /* more colors can be added after 255 to use with DefaultXX */ +- "#cccccc", ++ /* solarized dark */ ++ "#073642", /* 0: black */ ++ "#dc322f", /* 1: red */ ++ "#859900", /* 2: green */ ++ "#b58900", /* 3: yellow */ ++ "#268bd2", /* 4: blue */ ++ "#d33682", /* 5: magenta */ ++ "#2aa198", /* 6: cyan */ ++ "#eee8d5", /* 7: white */ ++ "#002b36", /* 8: brblack */ ++ "#cb4b16", /* 9: brred */ ++ "#586e75", /* 10: brgreen */ ++ "#657b83", /* 11: bryellow */ ++ "#839496", /* 12: brblue */ ++ "#6c71c4", /* 13: brmagenta*/ ++ "#93a1a1", /* 14: brcyan */ ++ "#fdf6e3", /* 15: brwhite */ + }; + + +@@ -82,9 +75,9 @@ static const char *colorname[] = { + * Default colors (colorname index) + * foreground, background, cursor + */ +-static unsigned int defaultfg = 7; +-static unsigned int defaultbg = 0; +-static unsigned int defaultcs = 256; ++static unsigned int defaultfg = 12; ++static unsigned int defaultbg = 8; ++static unsigned int defaultcs = 14; + + /* + * Colors used, when the specific fg == defaultfg. So in reverse mode this diff --git a/st.suckless.org/patches/st-solarized-dark-0.6.diff b/st.suckless.org/patches/st-solarized-dark-0.6.diff @@ -0,0 +1,65 @@ +diff --git a/config.def.h b/config.def.h +index 64e75b8..bc8d298 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -61,30 +61,23 @@ static unsigned int tabspaces = 8; + + /* Terminal colors (16 first used in escape sequence) */ + static const char *colorname[] = { +- /* 8 normal colors */ +- "black", +- "red3", +- "green3", +- "yellow3", +- "blue2", +- "magenta3", +- "cyan3", +- "gray90", +- +- /* 8 bright colors */ +- "gray50", +- "red", +- "green", +- "yellow", +- "#5c5cff", +- "magenta", +- "cyan", +- "white", +- +- [255] = 0, +- +- /* more colors can be added after 255 to use with DefaultXX */ +- "#cccccc", ++ /* solarized dark */ ++ "#073642", /* 0: black */ ++ "#dc322f", /* 1: red */ ++ "#859900", /* 2: green */ ++ "#b58900", /* 3: yellow */ ++ "#268bd2", /* 4: blue */ ++ "#d33682", /* 5: magenta */ ++ "#2aa198", /* 6: cyan */ ++ "#eee8d5", /* 7: white */ ++ "#002b36", /* 8: brblack */ ++ "#cb4b16", /* 9: brred */ ++ "#586e75", /* 10: brgreen */ ++ "#657b83", /* 11: bryellow */ ++ "#839496", /* 12: brblue */ ++ "#6c71c4", /* 13: brmagenta*/ ++ "#93a1a1", /* 14: brcyan */ ++ "#fdf6e3", /* 15: brwhite */ + }; + + +@@ -92,9 +85,9 @@ static const char *colorname[] = { + * Default colors (colorname index) + * foreground, background, cursor + */ +-static unsigned int defaultfg = 7; +-static unsigned int defaultbg = 0; +-static unsigned int defaultcs = 256; ++static unsigned int defaultfg = 12; ++static unsigned int defaultbg = 8; ++static unsigned int defaultcs = 14; + + /* + * Colors used, when the specific fg == defaultfg. So in reverse mode this diff --git a/st.suckless.org/patches/st-solarized-dark-20160727-308bfbf.diff b/st.suckless.org/patches/st-solarized-dark-20160727-308bfbf.diff @@ -0,0 +1,68 @@ +diff --git a/config.def.h b/config.def.h +index b41747f..8bdcc87 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -84,31 +84,23 @@ static unsigned int tabspaces = 8; + + /* Terminal colors (16 first used in escape sequence) */ + static const char *colorname[] = { +- /* 8 normal colors */ +- "black", +- "red3", +- "green3", +- "yellow3", +- "blue2", +- "magenta3", +- "cyan3", +- "gray90", +- +- /* 8 bright colors */ +- "gray50", +- "red", +- "green", +- "yellow", +- "#5c5cff", +- "magenta", +- "cyan", +- "white", +- +- [255] = 0, +- +- /* more colors can be added after 255 to use with DefaultXX */ +- "#cccccc", +- "#555555", ++ /* solarized dark */ ++ "#073642", /* 0: black */ ++ "#dc322f", /* 1: red */ ++ "#859900", /* 2: green */ ++ "#b58900", /* 3: yellow */ ++ "#268bd2", /* 4: blue */ ++ "#d33682", /* 5: magenta */ ++ "#2aa198", /* 6: cyan */ ++ "#eee8d5", /* 7: white */ ++ "#002b36", /* 8: brblack */ ++ "#cb4b16", /* 9: brred */ ++ "#586e75", /* 10: brgreen */ ++ "#657b83", /* 11: bryellow */ ++ "#839496", /* 12: brblue */ ++ "#6c71c4", /* 13: brmagenta*/ ++ "#93a1a1", /* 14: brcyan */ ++ "#fdf6e3", /* 15: brwhite */ + }; + + +@@ -116,10 +108,10 @@ static const char *colorname[] = { + * Default colors (colorname index) + * foreground, background, cursor, reverse cursor + */ +-static unsigned int defaultfg = 7; +-static unsigned int defaultbg = 0; +-static unsigned int defaultcs = 256; +-static unsigned int defaultrcs = 257; ++static unsigned int defaultfg = 12; ++static unsigned int defaultbg = 8; ++static unsigned int defaultcs = 14; ++static unsigned int defaultrcs = 15; + + /* + * Default shape of cursor diff --git a/st.suckless.org/patches/st-solarized-light-0.5.diff b/st.suckless.org/patches/st-solarized-light-0.5.diff @@ -0,0 +1,65 @@ +diff --git a/config.def.h b/config.def.h +index 58b470e..ec39cca 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -51,30 +51,23 @@ static unsigned int tabspaces = 8; + + /* Terminal colors (16 first used in escape sequence) */ + static const char *colorname[] = { +- /* 8 normal colors */ +- "black", +- "red3", +- "green3", +- "yellow3", +- "blue2", +- "magenta3", +- "cyan3", +- "gray90", +- +- /* 8 bright colors */ +- "gray50", +- "red", +- "green", +- "yellow", +- "#5c5cff", +- "magenta", +- "cyan", +- "white", +- +- [255] = 0, +- +- /* more colors can be added after 255 to use with DefaultXX */ +- "#cccccc", ++ /* solarized light */ ++ "#eee8d5", /* 0: black */ ++ "#dc322f", /* 1: red */ ++ "#859900", /* 2: green */ ++ "#b58900", /* 3: yellow */ ++ "#268bd2", /* 4: blue */ ++ "#d33682", /* 5: magenta */ ++ "#2aa198", /* 6: cyan */ ++ "#073642", /* 7: white */ ++ "#fdf6e3", /* 8: brblack */ ++ "#cb4b16", /* 9: brred */ ++ "#93a1a1", /* 10: brgreen */ ++ "#839496", /* 11: bryellow */ ++ "#657b83", /* 12: brblue */ ++ "#6c71c4", /* 13: brmagenta*/ ++ "#586e75", /* 14: brcyan */ ++ "#002b36", /* 15: brwhite */ + }; + + +@@ -82,9 +75,9 @@ static const char *colorname[] = { + * Default colors (colorname index) + * foreground, background, cursor + */ +-static unsigned int defaultfg = 7; +-static unsigned int defaultbg = 0; +-static unsigned int defaultcs = 256; ++static unsigned int defaultfg = 12; ++static unsigned int defaultbg = 8; ++static unsigned int defaultcs = 14; + + /* + * Colors used, when the specific fg == defaultfg. So in reverse mode this diff --git a/st.suckless.org/patches/st-solarized-light-0.6.diff b/st.suckless.org/patches/st-solarized-light-0.6.diff @@ -0,0 +1,65 @@ +diff --git a/config.def.h b/config.def.h +index 64e75b8..fba47b1 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -61,30 +61,23 @@ static unsigned int tabspaces = 8; + + /* Terminal colors (16 first used in escape sequence) */ + static const char *colorname[] = { +- /* 8 normal colors */ +- "black", +- "red3", +- "green3", +- "yellow3", +- "blue2", +- "magenta3", +- "cyan3", +- "gray90", +- +- /* 8 bright colors */ +- "gray50", +- "red", +- "green", +- "yellow", +- "#5c5cff", +- "magenta", +- "cyan", +- "white", +- +- [255] = 0, +- +- /* more colors can be added after 255 to use with DefaultXX */ +- "#cccccc", ++ /* solarized light */ ++ "#eee8d5", /* 0: black */ ++ "#dc322f", /* 1: red */ ++ "#859900", /* 2: green */ ++ "#b58900", /* 3: yellow */ ++ "#268bd2", /* 4: blue */ ++ "#d33682", /* 5: magenta */ ++ "#2aa198", /* 6: cyan */ ++ "#073642", /* 7: white */ ++ "#fdf6e3", /* 8: brblack */ ++ "#cb4b16", /* 9: brred */ ++ "#93a1a1", /* 10: brgreen */ ++ "#839496", /* 11: bryellow */ ++ "#657b83", /* 12: brblue */ ++ "#6c71c4", /* 13: brmagenta*/ ++ "#586e75", /* 14: brcyan */ ++ "#002b36", /* 15: brwhite */ + }; + + +@@ -92,9 +85,9 @@ static const char *colorname[] = { + * Default colors (colorname index) + * foreground, background, cursor + */ +-static unsigned int defaultfg = 7; +-static unsigned int defaultbg = 0; +-static unsigned int defaultcs = 256; ++static unsigned int defaultfg = 12; ++static unsigned int defaultbg = 8; ++static unsigned int defaultcs = 14; + + /* + * Colors used, when the specific fg == defaultfg. So in reverse mode this diff --git a/st.suckless.org/patches/st-solarized-light-20160727-308bfbf.diff b/st.suckless.org/patches/st-solarized-light-20160727-308bfbf.diff @@ -0,0 +1,68 @@ +diff --git a/config.def.h b/config.def.h +index b41747f..5a87570 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -84,31 +84,23 @@ static unsigned int tabspaces = 8; + + /* Terminal colors (16 first used in escape sequence) */ + static const char *colorname[] = { +- /* 8 normal colors */ +- "black", +- "red3", +- "green3", +- "yellow3", +- "blue2", +- "magenta3", +- "cyan3", +- "gray90", +- +- /* 8 bright colors */ +- "gray50", +- "red", +- "green", +- "yellow", +- "#5c5cff", +- "magenta", +- "cyan", +- "white", +- +- [255] = 0, +- +- /* more colors can be added after 255 to use with DefaultXX */ +- "#cccccc", +- "#555555", ++ /* solarized light */ ++ "#eee8d5", /* 0: black */ ++ "#dc322f", /* 1: red */ ++ "#859900", /* 2: green */ ++ "#b58900", /* 3: yellow */ ++ "#268bd2", /* 4: blue */ ++ "#d33682", /* 5: magenta */ ++ "#2aa198", /* 6: cyan */ ++ "#073642", /* 7: white */ ++ "#fdf6e3", /* 8: brblack */ ++ "#cb4b16", /* 9: brred */ ++ "#93a1a1", /* 10: brgreen */ ++ "#839496", /* 11: bryellow */ ++ "#657b83", /* 12: brblue */ ++ "#6c71c4", /* 13: brmagenta*/ ++ "#586e75", /* 14: brcyan */ ++ "#002b36", /* 15: brwhite */ + }; + + +@@ -116,10 +108,10 @@ static const char *colorname[] = { + * Default colors (colorname index) + * foreground, background, cursor, reverse cursor + */ +-static unsigned int defaultfg = 7; +-static unsigned int defaultbg = 0; +-static unsigned int defaultcs = 256; +-static unsigned int defaultrcs = 257; ++static unsigned int defaultfg = 12; ++static unsigned int defaultbg = 8; ++static unsigned int defaultcs = 14; ++static unsigned int defaultrcs = 15; + + /* + * Default shape of cursor diff --git a/st.suckless.org/patches/st-spoiler-0.6.diff b/st.suckless.org/patches/st-spoiler-0.6.diff @@ -0,0 +1,22 @@ +diff --git a/st.c b/st.c +index b89d094..88c78f5 100644 +--- a/st.c ++++ b/st.c +@@ -3483,9 +3483,14 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i + } + + if(base.mode & ATTR_REVERSE) { +- temp = fg; +- fg = bg; +- bg = temp; ++ if (bg == fg) { ++ bg = &dc.col[defaultfg]; ++ fg = &dc.col[defaultbg]; ++ } else { ++ temp = fg; ++ fg = bg; ++ bg = temp; ++ } + } + + if((base.mode & ATTR_BOLD_FAINT) == ATTR_FAINT) { diff --git a/st.suckless.org/patches/st-spoiler-20160727-308bfbf.diff b/st.suckless.org/patches/st-spoiler-20160727-308bfbf.diff @@ -0,0 +1,22 @@ +diff --git a/st.c b/st.c +index 2594c65..742bc5c 100644 +--- a/st.c ++++ b/st.c +@@ -3748,9 +3748,14 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i + } + + if (base.mode & ATTR_REVERSE) { +- temp = fg; +- fg = bg; +- bg = temp; ++ if (bg == fg) { ++ bg = &dc.col[defaultfg]; ++ fg = &dc.col[defaultbg]; ++ } else { ++ temp = fg; ++ fg = bg; ++ bg = temp; ++ } + } + + if ((base.mode & ATTR_BOLD_FAINT) == ATTR_FAINT) { diff --git a/st.suckless.org/patches/st-visualbell-20160727-308bfbf.diff b/st.suckless.org/patches/st-visualbell-20160727-308bfbf.diff @@ -0,0 +1,42 @@ +diff --git a/st.c b/st.c +index 2594c65..89bffdd 100644 +--- a/st.c ++++ b/st.c +@@ -532,6 +532,7 @@ static char *opt_line = NULL; + static char *opt_name = NULL; + static char *opt_title = NULL; + static int oldbutton = 3; /* button event on startup: 3 = release */ ++static int bellon = 0; /* visual bell status */ + + static char *usedfont = NULL; + static double usedfontsize = 0; +@@ -2766,6 +2767,15 @@ tcontrolcode(uchar ascii) + xseturgency(1); + if (bellvolume) + XkbBell(xw.dpy, xw.win, bellvolume, (Atom)NULL); ++ ++ /* visual bell*/ ++ if (!bellon) { ++ bellon = 1; ++ MODBIT(term.mode, !IS_SET(MODE_REVERSE), MODE_REVERSE); ++ redraw(); ++ XFlush(xw.dpy); ++ MODBIT(term.mode, !IS_SET(MODE_REVERSE), MODE_REVERSE); ++ } + } + break; + case '\033': /* ESC */ +@@ -4292,7 +4302,12 @@ run(void) + (handler[ev.type])(&ev); + } + +- draw(); ++ if (bellon) { ++ bellon = 0; ++ redraw(); ++ } ++ else draw(); ++ + XFlush(xw.dpy); + + if (xev && !FD_ISSET(xfd, &rfd)) diff --git a/st.suckless.org/patches/visualbell.md b/st.suckless.org/patches/visualbell.md @@ -16,9 +16,10 @@ monitor. Download -------- - * [st-git-20160209-visualbell.diff](st-git-20160209-visualbell.diff) + * [st-visualbell-20160727-308bfbf.diff](st-visualbell-20160727-308bfbf.diff) Authors ------- - * Matthias Schoth - mschoth@gmail.com + * Matthias Schoth - <mschoth@gmail.com> + * Laslo Hunhold - <dev@frign.de> (git port) diff --git a/st.suckless.org/patches/wordbreak.md b/st.suckless.org/patches/wordbreak.md @@ -1,29 +0,0 @@ -wordbreak -========= - -Description ------------ - -This patch allows you to configure which characters are used as -word boundaries for double click selections (instead of just ' '). -This feature is already implemented in all versions later than 0.5. - -Usage ------ - -config.h example: - - #define WORD_BREAK " ()<>[]\"" - -Download --------- -* [st-0.3-wordbreak.diff](st-0.3-wordbreak.diff) -* [st-0.4-wordbreak.diff](st-0.4-wordbreak.diff) -* [st-0.4.1-wordbreak.diff](st-0.4.1-wordbreak.diff) -* [st-0.5-wordbreak.diff](st-0.5-wordbreak.diff) - -Authors -------- - - * Stephen Paul Weber - singpolyma@singpolyma.net - * Laslo Hunhold - dev@frign.de (st-0.4, st-0.4.1, st-0.5 ports) diff --git a/st.suckless.org/screenshots/frign-2016-s.png b/st.suckless.org/screenshots/frign-2016-s.png Binary files differ. diff --git a/st.suckless.org/screenshots/frign-2016.png b/st.suckless.org/screenshots/frign-2016.png Binary files differ. diff --git a/st.suckless.org/screenshots/index.md b/st.suckless.org/screenshots/index.md @@ -1,3 +1,5 @@ +->[![st screenshot](frign-2016-s.png)](frign-2016-s.png)<- + ->[![st screenshot](putain-ouais-s.png)](putain-ouais.png)<- ->[![st screenshot](hendry-s.png)](hendry.png)<- diff --git a/suckless.org/coding_style.md b/suckless.org/coding_style.md @@ -8,7 +8,7 @@ The following contain good information, some of which is repeated below, some of * <http://doc.cat-v.org/bell_labs/pikestyle> * <https://www.kernel.org/doc/Documentation/CodingStyle> -* <http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man9/style.9?query=style&sec=9> +* <http://man.openbsd.org/OpenBSD-current/man9/style.9> File Layout ----------- diff --git a/suckless.org/conference/2015.md b/suckless.org/conference/2015.md @@ -73,6 +73,12 @@ Talks > Anselm presented the idea of suckless.org e.V.[<sup>1</sup>][1] and asked attendees to join. +<video width="600" height="338" controls="" style="display:block;margin:0 auto" poster="http://dl.sta.li/slcon/2015/slcon-2015-05-all-suckless_ev.png"> + <source src="http://dl.sta.li/slcon/2015/slcon-2015-05-all-suckless_ev.webm" type="video/webm"> + <a href="http://dl.sta.li/slcon/2015/slcon-2015-05-all-suckless_ev.webm">slcon-2015-05-all-suckless_ev.webm</a> +</video> + + (16:30-17:30) *suckless.org foundation*, All (17:30-19:00) Refresh break / check your rooms @@ -148,6 +154,15 @@ Talks (14:45-15:00) *Formal conference talk closing*, Anselm R Garbe +> Anselm formally closed the conference and it was decided upon the location + for the upcoming slcon3. + +<video width="600" height="338" controls="" style="display:block;margin:0 auto" poster="http://dl.sta.li/slcon/2015/slcon-2015-10-all-vote.png"> + <source src="http://dl.sta.li/slcon/2015/slcon-2015-10-all-vote.webm" type="video/webm"> + <a href="http://dl.sta.li/slcon/2015/slcon-2015-10-all-vote.webm">slcon-2015-10-all-vote.webm</a> +</video> + + (15:00-17:00) Hacking (17:00-) Social event in Budapest diff --git a/suckless.org/conference/index.md b/suckless.org/conference/index.md @@ -5,7 +5,34 @@ slcon3 will be held near Frankfurt/Main on 2016-09-(23-25). At the same occasion the Mitgliederversammlung (annual member meeting) of suckless.org e.V. will be held. -The CfP will start soon. +The CfP is open for proposals from 2016-06-03 to 2016-08-20. + +Proposals +--------- +We expect talk proposals between 30-60 minutes each covering either +technical or philosophical topics (rants are welcome as well). + +Each proposal should contain + +* the name of the author +* an abstract written in English +* presumably a couple of reference links to related ideas or topics + +Please note, do only submit a proposal if you are pretty certain that +you can attend the conference on the given date. + +Please submit your proposal to: con(at)suckless.org + +We don't expect a paper or slide set prior to the conference! Your +proposal should enable us to accept/deny your talk and to schedule an +adequate slot for it. + +If you cannot attend on a certain day, please add a note to your +proposal. We then are able to fine-tune the schedule. + +Acceptance and final schedule presentation +------------------------------------------ +We expect to publish the accepted talks and schedule around late August 2016. Previous conferences -------------------- diff --git a/suckless.org/donations.md b/suckless.org/donations.md @@ -6,7 +6,13 @@ a contribution, no matter the size, it will go towards ensuring that we are able to continue to write, support and host the high quality software that makes all of our lives easier. -You can donate through [PayPal](https://paypal.com/) using Anselm's gmail address: garbeam@gmail.com +You can donate through [PayPal](https://paypal.com/) using our treasurer's address: finance@suckless.org + +Or direct through a bank transfer: + + payee: suckless.org e.V. + IBAN: DE80 7002 2200 0020 1481 28 + BIC: FDDODEMMXXX We'd like to thank all people who have donated or are donating in one way or another to a suckless.org related project. Your generosity of time and/or money @@ -24,6 +30,8 @@ Following people have donated to the suckless.org project certain amounts of money, which have been used for the dedicated server rent in the past: +* Ryan Roden-Corrent <b>20 USD</b> +* Sebastian Eiser <b>10 EUR</b> * Jakub Jirutka donated <b>20 USD</b> * Surin Anton donated <b>20 USD</b> * Eero Molkoselkä donated <b>10 EUR</b> diff --git a/suckless.org/hacking.md b/suckless.org/hacking.md @@ -26,27 +26,59 @@ If you encounter freezes (no crash at all) of the program, you can debug as foll Send the output of that command to the mailing list along with the output of `program -v`! Thank you! - Patches ------- +There are two types of patches: The ones that fit to your personal taste and +the ones you think should be included in mainline. + +For patches that should be included in mainline see the +[community](//suckless.org/community) page and the hackers@ mailing list. + +You can use the following instructions to generate and apply patches posted on +this wiki. On how to upload patches which fit your personal taste and you want +to show the community, see the [wiki](//suckless.org/wiki) page on how to edit +the pages you see here. + +patch filename format +--------------------- +The expected format for patches is + +For git revisions: + + toolname-patchname-YYYYMMDD-SHORTHASH.diff + dwm-allyourbase-20160617-3465bed.diff + +The YYYYMMDD date should correspond to the last time the patch has been modified. +The SHORTHASH here is the seven chars git commit short hash corresponding to the +last commit of the tool on which the patch can be applied correctly and +is working with. +You can get it by taking the first seven chars of the full hash or for example: + + git rev-parse --short <commit-id> (with commit-id: HEAD, commit hash, etc.) + +For release versions: + + toolname-patchname-RELEASE.diff + dwm-allyourbase-6.1.diff + +The RELEASE should correspond to the tool release version, ie 6.1 for dwm-6.1. diff generation --------------- For git users: cd program-directory - git diff > program-X.Y-yourpatchname.diff + git diff > toolname-patchname-YYYYMMDD-SHORTHASH.diff For tarballs: cd modified-program-directory/.. - diff -up original-program-directory modified-program-directory > program-X.Y-yourpatchname.diff - -where `X.Y` is a dwm tag name or version number. + diff -up original-program-directory modified-program-directory > \ + toolname-patchname-RELEASE.diff patch program ------------- -For git users: +For git users, use -3 to fix the conflict easily: cd program-directory git apply path/to/patch.diff diff --git a/suckless.org/index.md b/suckless.org/index.md @@ -5,9 +5,17 @@ Read more about our [philosophy](/philosophy) and join us on the [mailing list]( News ==== +2016-07-20 +---------- +[slcon3](http://suckless.org/conference) Call for papers opened. Submission deadline: 2016-08-20 + +2016-04-02 +---------- +[stali ISO](http://dl.sta.li/stali.iso) pre-release. See [stali](http://sta.li) for more details. + 2016-02-29 ---------- -Final suckless.org server renewal will happen this week: +suckless.org server renewal will happen this spring: Heads up for the developers: @@ -73,11 +81,11 @@ community is invited to come, meet and hack! 2014-08-05 ---------- -[sinit 0.9.1](http://tools.suckless.org/sinit) released: [download](http://dl.suckless.org/sinit/sinit-0.9.1.tar.gz) +[sinit 0.9.1](http://core.suckless.org/sinit) released: [download](http://dl.suckless.org/sinit/sinit-0.9.1.tar.gz) 2014-05-01 ---------- -[ubase 0.1](http://tools.suckless.org/ubase) released: [download](http://dl.suckless.org/ubase/ubase-0.1.tar.gz) +[ubase 0.1](http://core.suckless.org/ubase) released: [download](http://dl.suckless.org/ubase/ubase-0.1.tar.gz) 2014-01-21 ---------- diff --git a/suckless.org/other_projects.md b/suckless.org/other_projects.md @@ -6,6 +6,7 @@ There are several other projects which are inspired by the spirit of suckless. * [autonet](https://github.com/mrdomino/autonet) - automatic wifi network chooser for OpenBSD * [bgs](https://github.com/Gottox/bgs) - background setter * [bug](http://vicerveza.homeunix.net/~viric/soft/bug/) - commandline todo-tracking system +* [bus](https://github.com/maandree/bus) - daemonless message broadcasting IPC * [cross-chroot](https://github.com/radare/cross-chroot) - cross platform qemu-powered chroot utilities (based on the ideas of the maemo sdk) * [dietline](https://github.com/radare/radare2/blob/master/libr/cons/dietline.c) - minimalist implementation of a readline-like library * [dmc](http://git.suckless.org/dmc/) - dynamic mail client @@ -14,10 +15,12 @@ There are several other projects which are inspired by the spirit of suckless. * [honden](https://github.com/joodan-van-github/honden) - system built on top of oboeta * [ired](https://github.com/radare/ired) - minimalistic hexadecimal editor inspired in radare * [kelp](http://kelp.sf.net) - source code annotation framework +* [librarian](https://github.com/maandree/librarian) - less sucky alternative to pkg-config * [micy](https://github.com/radare/toys/tree/master/micy) - minimalistic mouse handler (depends on driver) * [oboeta](https://github.com/joodan-van-github/oboeta) - minimalistic plain-text flashcard system * [pcw](https://bitbucket.org/emg/pcw) - popup chat windows (ii front end) * [ptar](https://github.com/joodan-van-github/ptar) - plain-text archives: like tar, but better +* [sat](https://github.com/maandree/sat) - simple incompatible alternative to at * [sdhcp](http://git.2f30.org/sdhcp) - tiny dhcp client * [sj](https://github.com/younix/sj) - simple jabber: modular FIFO-based XMPP client * [slpm](https://github.com/radare/slpm) - suckless package manager diff --git a/suckless.org/people/maandree.md b/suckless.org/people/maandree.md @@ -1,9 +1,12 @@ Mattias Andrée (maandree) ========================= -I'm the maintainer of [libzahl](http://git.suckless.org/libzahl/) and -and contibutor to [sbase](http://tools.suckless.org/sbase). +I'm the maintainer of [libzahl](http://libs.suckless.org/libzahl/) +and a contibutor to [sbase](http://core.suckless.org/sbase) and +[ubase](http://core.suckless.org/ubase). You can find my PGP key on -[MIT's keyserver](http://pgp.mit.edu:11371/pks/lookup?op=get&search=0xCE306090E98B08C7) and on -[GnuPG's keyserver](http://keys.gnupg.net/pks/lookup?op=get&fingerprint=on&search=0xCE306090E98B08C7). +[MIT's keyserver](http://pgp.mit.edu:11371/pks/lookup?op=get&search=0xBF2236A2678A6A76) and on +[GnuPG's keyserver](http://keys.gnupg.net/pks/lookup?op=get&search=0xBF2236A2678A6A76). +The domain part of my e-mail address is kth.se, I'll let you +guess the local part. diff --git a/suckless.org/people/more_people.md b/suckless.org/people/more_people.md @@ -1,74 +0,0 @@ -More people -=========== - -The following people are/were involved mainly in wmii and dwm development as -developers and contributors. If you are missing, feel free to add yourself. - -* Alexandre DE DOMMELIN (contributed a theme and works on PHP based theme configurator) -* Andrew Milkovich (patches, updates) -* [Anthony Martin](http://pbrane.org) (ality) (developer, bug fixes, documentation) -* AntThyKem (contributed rpm package) -* Bernhard Leiner (wmipager improvements) -* Bob Crochelt (various feedback) -* Brian Dorsey (contributed various feedback) -* carmee (contributed various feedback) -* chem (bugs and various feedback) -* Christian Schneider (provides the Slackware package) -* Christof Musik (various feedback, small fixes) -* [Christoph Wegscheider](http://www.wegi.net) (python bindings of old libixp, former irc logging) -* Daniel Baumann (Debian packaging) -* Daniel W&auml;ber (wabu) (fixes and patches) -* &dagger; Denis Grelich (ex-maintainer) -* Fabian Braennstroem (contributed archlinux packages) -* Fernan Bolando (one of the most active WMI testers, contributed various ideas and feedback concerning the slot) -* Fernando T. C. Lemos (contributed several themes) -* Filippo Erik Negroni (contributes wiki documentation to dwm) -* Dr. Frank Boehme (one of the first WMI users, contributed various ideas) -* Frank Ehmsen (contributed several bug reports and various good feature requests) -* Gabriel (various feedback, various color schemes) -* Gavin McCullagh (contributed various ideas) -* Georg Neis (Developer, documentation, tests) -* grayrest (great ideas for the menu, select-frame policy beside many other valuable ideas) -* Hannes Klas (contributed themes and maintains some translations in the Wiki) -* Henning Bekel (various feedback concerning the ratpoison shortcut handling) -* Dr. Johann Pfefferl (several patches which fixed many issues) -* John Pham (Debian Packager, Sysadmin) -* Jonas Domeij (various feedback concerning wmii, default wmi-10 theme) -* Jukka Salmi (fixes and patches) -* [Kai Hendry](http://hendry.iki.fi) (sales) -* Kathryn Andersen (contributed nice theme and valuable newbie feedback) -* Kris Malfettone (various feedback concerning wmir) -* Malte Zorn (various feedback) -* Marcel Manthe (Developer of PATH expansion in wmi-10 input mode) -* Marcin Pawlik (contributed Control-keys patch for input mode) -* Mark Weinem (contributed various ideas) -* Markus Lindorfer (contributed patch to compile on Solaris) -* Martin Moncrieff (various feedback concerning Mathematica issues) -* Mathieu L (contributed various feedback) -* Matthew Allen (contributed several themes and great art assets, works on the WMI mascot) -* Michael Ihde (provided several fixes to the container.h class and documentation) -* [Nico Golde (nion)](http://www.ngolde.de) (testing, fixes, wmii-2 blue theme, [ii developer](http://tools.suckless.org/ii/)) -* [Norman Golisz](http://www.zcat.de) (documentation) -* Norman K&ouml;hring (pSy) (developer of szs) -* Oliver Kopp (contributed various feedback) -* Oliver Rendgen (Documentation) -* PEYROUX Jean (BSD Port Maintainer (all platforms)) -* Rainer Trusch (contributed several bug reports and some ideas) -* Rajesh Menon (contributed various feedback) -* Robert Lillack (contributed some ideas to the new window concept) -* Ryan Sorensen (provided various debug input) -* Salva Peiro (gualteri) (user & translation guide-es) -* Sander van Dijk (developer) -* Sebastian Hartmann (Manual pages for wmii) -* Sebastian Roth (several bugfixes in C and Makefiles, Doxyfile) -* Stefan Kuttler (inventor of the WMI project name) -* Stefan Tibus (fixes and patches) -* Steffen Liebergeld ("A guide to wmii" author) -* Steve Hoffman (various feedback, small fixes) -* Szabolcs Nagy (fixes and patches) -* Tobias Walkowiak (provided various feedback) -* Tuncer Ayaz (contributed some grammar fixes for the Improved GUI concepts paper) -* Uwe Zeisberger (code review, bug fixings) -* Wilson Oliveira (contributed the wmizer tool) -* yiyus || Jesus Galan (dwm patches a go-go) - diff --git a/suckless.org/people/quinq.md b/suckless.org/people/quinq.md @@ -0,0 +1,11 @@ +quinq +===== + +Salut les aminches, + +I'm contributing to various suckless projects and currently +maintaining [surf](http://surf.suckless.org) for the webkit2 API. + +Friend of [2f30](http://2f30.org). + +Can be contacted at quinq AT fifth DOT space diff --git a/suckless.org/people/~ more_people.md b/suckless.org/people/~ more_people.md @@ -0,0 +1,74 @@ +More people +=========== + +The following people are/were involved mainly in wmii and dwm development as +developers and contributors. If you are missing, feel free to add yourself. + +* Alexandre DE DOMMELIN (contributed a theme and works on PHP based theme configurator) +* Andrew Milkovich (patches, updates) +* [Anthony Martin](http://pbrane.org) (ality) (developer, bug fixes, documentation) +* AntThyKem (contributed rpm package) +* Bernhard Leiner (wmipager improvements) +* Bob Crochelt (various feedback) +* Brian Dorsey (contributed various feedback) +* carmee (contributed various feedback) +* chem (bugs and various feedback) +* Christian Schneider (provides the Slackware package) +* Christof Musik (various feedback, small fixes) +* [Christoph Wegscheider](http://www.wegi.net) (python bindings of old libixp, former irc logging) +* Daniel Baumann (Debian packaging) +* Daniel W&auml;ber (wabu) (fixes and patches) +* &dagger; Denis Grelich (ex-maintainer) +* Fabian Braennstroem (contributed archlinux packages) +* Fernan Bolando (one of the most active WMI testers, contributed various ideas and feedback concerning the slot) +* Fernando T. C. Lemos (contributed several themes) +* Filippo Erik Negroni (contributes wiki documentation to dwm) +* Dr. Frank Boehme (one of the first WMI users, contributed various ideas) +* Frank Ehmsen (contributed several bug reports and various good feature requests) +* Gabriel (various feedback, various color schemes) +* Gavin McCullagh (contributed various ideas) +* Georg Neis (Developer, documentation, tests) +* grayrest (great ideas for the menu, select-frame policy beside many other valuable ideas) +* Hannes Klas (contributed themes and maintains some translations in the Wiki) +* Henning Bekel (various feedback concerning the ratpoison shortcut handling) +* Dr. Johann Pfefferl (several patches which fixed many issues) +* John Pham (Debian Packager, Sysadmin) +* Jonas Domeij (various feedback concerning wmii, default wmi-10 theme) +* Jukka Salmi (fixes and patches) +* [Kai Hendry](http://hendry.iki.fi) (sales) +* Kathryn Andersen (contributed nice theme and valuable newbie feedback) +* Kris Malfettone (various feedback concerning wmir) +* Malte Zorn (various feedback) +* Marcel Manthe (Developer of PATH expansion in wmi-10 input mode) +* Marcin Pawlik (contributed Control-keys patch for input mode) +* Mark Weinem (contributed various ideas) +* Markus Lindorfer (contributed patch to compile on Solaris) +* Martin Moncrieff (various feedback concerning Mathematica issues) +* Mathieu L (contributed various feedback) +* Matthew Allen (contributed several themes and great art assets, works on the WMI mascot) +* Michael Ihde (provided several fixes to the container.h class and documentation) +* [Nico Golde (nion)](http://www.ngolde.de) (testing, fixes, wmii-2 blue theme, [ii developer](http://tools.suckless.org/ii/)) +* [Norman Golisz](http://www.zcat.de) (documentation) +* Norman K&ouml;hring (pSy) (developer of szs) +* Oliver Kopp (contributed various feedback) +* Oliver Rendgen (Documentation) +* PEYROUX Jean (BSD Port Maintainer (all platforms)) +* Rainer Trusch (contributed several bug reports and some ideas) +* Rajesh Menon (contributed various feedback) +* Robert Lillack (contributed some ideas to the new window concept) +* Ryan Sorensen (provided various debug input) +* Salva Peiro (gualteri) (user & translation guide-es) +* Sander van Dijk (developer) +* Sebastian Hartmann (Manual pages for wmii) +* Sebastian Roth (several bugfixes in C and Makefiles, Doxyfile) +* Stefan Kuttler (inventor of the WMI project name) +* Stefan Tibus (fixes and patches) +* Steffen Liebergeld ("A guide to wmii" author) +* Steve Hoffman (various feedback, small fixes) +* Szabolcs Nagy (fixes and patches) +* Tobias Walkowiak (provided various feedback) +* Tuncer Ayaz (contributed some grammar fixes for the Improved GUI concepts paper) +* Uwe Zeisberger (code review, bug fixings) +* Wilson Oliveira (contributed the wmizer tool) +* yiyus || Jesus Galan (dwm patches a go-go) + diff --git a/suckless.org/philosophy.md b/suckless.org/philosophy.md @@ -64,3 +64,4 @@ Related links * [Facebook's code quality problem](http://www.darkcoding.net/software/facebooks-code-quality-problem/) * [Minimal Viable Programs](http://joearms.github.io/2014/06/25/minimal-viable-program.html) * [Why I Write Games in C](http://jonathanwhiting.com/writing/blog/games_in_c/) +* [Use of command-line tools for effective data processing](http://aadrake.com/command-line-tools-can-be-235x-faster-than-your-hadoop-cluster.html) diff --git a/suckless.org/project_ideas.md b/suckless.org/project_ideas.md @@ -45,6 +45,9 @@ draw some text somewhere. And this is what a suckless font rendering library should do: Give it a font string and render at some position the given font without having to care about font specifics. +[Some work](https://git.ekleog.org/dtext) has already been done to replace +libXft and Fontconfig. Real-world testing is however still needed. + ***Requirements:*** C knowledge, some X11 knowledge and of course knowledge about the font formats and how to handle them. diff --git a/suckless.org/rocks.md b/suckless.org/rocks.md @@ -20,7 +20,9 @@ Compression * [liblzf](http://oldhome.schmorp.de/marc/liblzf.html) - very fast, legally unencumbered compression library (dual licensed: 2-clause BSD or GPL License) * [miniz](http://code.google.com/p/miniz/) - single C-file reimplementation of zlib, public domain. * [xz embedded](http://tukaani.org/xz/embedded.html) - lightweight decompressor for the xz LZMA compressor (public domain) +* [Lzip](http://lzip.nongnu.org) - Properly designed data compressor outperforming gzip and bzip2 (GPLv2+) * [zlib](http://zlib.net/) - the "standard" compression/decompression library, quite small, used in many applications ([zlib license](http://zlib.net/zlib_license.html)) +* [libz](https://sortix.org/libz/) - ABI and API compatible zlib fork with focus on correctness, proper portability, auditability, simplification and opportunities to optimize ([zlib license](http://zlib.net/zlib_license.html)) Cryptography ------------ @@ -81,6 +83,7 @@ File managers IRC Clients ----------- * [Irc](http://swtch.com/irc/) +* [irc.c from mpu](http://c9x.me/irc/) - A Minimal Curses IRC Client. * [ii](http://tools.suckless.org/ii/) - A FIFO based IRC client which is part of the suckless.org project. * [ircc](http://www.r-36.net/src/Various/ircc.tgz) - A no-frills, ncurses free, console-based IRC client. * [ircrc](http://plan9.bell-labs.com/sources/contrib/fgb/rc/ircrc) - An rc-based IRC client similar to ircc. Needs minor modification to run on UNIX. @@ -134,6 +137,7 @@ Password managers ----------------- * [pass](http://www.passwordstore.org/) - The standard unix password manager * [tpm](https://github.com/nmeum/tpm/) - Tiny password manager +* [spm](https://notabug.org/kl3/spm/) - Simple password manager (actively maintained fork of nmeum's tpm) PDF Viewers ----------- @@ -143,6 +147,7 @@ PDF Viewers Shells ------ * [mksh](https://www.mirbsd.org/mksh.htm) - MirBSD Korn Shell, an actively developed free implementation of the Korn Shell programming language and a successor to the Public Domain Korn Shell (pdksh) +* [dash](http://gondor.apana.org.au/~herbert/dash/) - DASH is a POSIX-compliant implementation of /bin/sh that aims to be as small as possible. It does this without sacrificing speed where possible. Text Editors ------------ @@ -218,6 +223,7 @@ Web Servers * [mini_httpd](http://acme.com/software/mini_httpd/) - By the thttpd developers. Even smaller subset of thttpd with support for .htpasswd, CGI, dirlisting, HTTP errors and SSL, nothing more or less than that. * [darkhttpd](https://unix4lyfe.org/darkhttpd/) - Darkhttpd is a simple, fast HTTP 1.1 web server for static content. * [quark](http://git.suckless.org/quark/) - suckless httpd, not released yet +* [shus](https://github.com/dimkr/shus) - A tiny HTTP server for static sites Gopher Servers -------------- diff --git a/suckless.org/sucks/index.md b/suckless.org/sucks/index.md @@ -26,7 +26,7 @@ possible to avoid them. If you use them, consider looking for alternatives. * [GMP][3] - GNU's bignum/arbitrary precision library. Quite bloated, slow and [calls abort() on failed malloc][4] - Alternatives: [libtommath][5], [TomsFastMath][6], [MPI][7] + Alternatives: [libtommath][5], [TomsFastMath][6], [MPI][7], [libzahl][11] (WIP), [hebimath][12] (WIP) [1]: http://library.gnome.org/devel/glib/ @@ -39,16 +39,18 @@ possible to avoid them. If you use them, consider looking for alternatives. [8]: https://bugzilla.gnome.org/show_bug.cgi?id=674446 [9]: https://github.com/atheme/libmowgli-2 [10]: https://github.com/rofl0r/libulz +[11]: http://libs.suckless.org/libzahl +[12]: https://github.com/suiginsoft/hebimath Build Systems ------------- -* [cmake][11] (written in C++) - so huge and bloated, compilation takes longer +* [cmake][13] (written in C++) - so huge and bloated, compilation takes longer than compiling GCC (!). It's not even possible to create freestanding Makefiles, since the generated Makefiles call back into the cmake binary itself. -* [waf][12] and [scons][13] (both written in Python) - waf code is dropped +* [waf][14] and [scons][15] (both written in Python) - waf code is dropped into the compilee's build tree, so it does not benefit from updated versions and bugfixes. @@ -56,13 +58,13 @@ As these build systems are often used to compile C programs, one has to set up a C++ compiler or Python interpreter respectively just in order to be able to build some C code. -Alternatives: [mk][14], [gnu make][15] +Alternatives: [mk][16], [gnu make][17] -[11]: http://www.cmake.org/ -[12]: https://code.google.com/p/waf/ -[13]: http://www.scons.org/ -[14]: http://doc.cat-v.org/plan_9/4th_edition/papers/mk -[15]: https://www.gnu.org/software/make/ +[13]: http://www.cmake.org/ +[14]: https://code.google.com/p/waf/ +[15]: http://www.scons.org/ +[16]: http://doc.cat-v.org/plan_9/4th_edition/papers/mk +[17]: https://www.gnu.org/software/make/ Programs -------- diff --git a/suckless.org/sucks/systemd.md b/suckless.org/sucks/systemd.md @@ -30,6 +30,10 @@ The list is exceeding the life-time of a philosopher to discuss all implications on the sanity of a system design. That's why the comments are kept short. +Part 2 +------ +* [System now does your DNS](https://lists.dns-oarc.net/pipermail/dns-operations/2016-June/014964.html) + Part 1 ------ (If you are adding more parts, link to the right revision and not just the diff --git a/surf.suckless.org/files/bmarks.md b/surf.suckless.org/files/bmarks.md @@ -57,7 +57,7 @@ Code p=$2 uri=`xprop -id $xid _SURF_URI | cut -d '"' -f 2` kw=`xprop -id $xid _SURF_FIND | cut -d '"' -f 2` - dmenu="dmenu -e $xid -fn $font -nb $normbgcolor -nf $normfgcolor \ + dmenu="dmenu -fn $font -nb $normbgcolor -nf $normfgcolor \ -sb $selbgcolor -sf $selfgcolor" s_xprop() { diff --git a/surf.suckless.org/files/bmarks_history.md b/surf.suckless.org/files/bmarks_history.md @@ -71,7 +71,7 @@ Code fid=$2 xid=$3 - dmenu="dmenu -e $xid -nb $normbgcolor -nf $normfgcolor \ + dmenu="dmenu -nb $normbgcolor -nf $normfgcolor \ -sb $selbgcolor -sf $selfgcolor" s_get_prop() { # xprop diff --git a/surf.suckless.org/files/skip_streaming_limits.md b/surf.suckless.org/files/skip_streaming_limits.md @@ -1,35 +0,0 @@ -Simplyread -========== - -Description ------------ - -Call the http://www.debrideurstreaming.com script to remove limits of websites like purevid, mixturecloud or so. - -Add this in $HOME/.surf/script.js - -The default keybinding is alt-d. - - - (function() { - document.addEventListener('keydown', keybind, false); - })(); - - function keybind(e) { - // if(e.altKey && String.fromCharCode(e.keyCode) == "R") { - // simplyread(); } - if(e.altKey && String.fromCharCode(e.keyCode) == "D") { - debride(); - } - } - - function debride() { - h=document.getElementsByTagName('head')[0]; - if(!h){ - he=document.createElement('head'); - h=document.getElementsByTagName('body')[0].appendChild(he); - } - sc=document.createElement('script'); - sc.src='http://debrideurstreaming.com/scripts/mixidev.php?r='+Math.random()+''; - h.appendChild(sc); - } diff --git a/surf.suckless.org/files/surfraw_as_searchengine.md b/surf.suckless.org/files/surfraw_as_searchengine.md @@ -0,0 +1,28 @@ +Surfraw as search engine +========================= + +Description +----------- +Make sure to have surfraw installed. + +Modify your config.h just before the definition of `keys[]`: + + #define SR_SEARCH { .v = (char *[]){ "/bin/sh", "-c", \ + "xprop -id $0 -f _SURF_GO 8s -set _SURF_GO \ + $(sr -p $(sr -elvi | tail -n +2 | cut -s -f1 | dmenu))", \ + winid, NULL } } + +Then, inside `keys[]`, add: + + { MODKEY, GDK_s, spawn, SR_SEARCH }, + +### Modkeys + +**CTRL-s** + +Executes dmenu(1) displaying the list of elvis. Complete with TAB and enter +search terms. Confirm with ENTER. + +Author +------ +* Moritz Schönherr `<moritz dot schoenherr at gmail dot com>` diff --git a/surf.suckless.org/index.md b/surf.suckless.org/index.md @@ -27,6 +27,11 @@ Links * Mailing List: `dev+subscribe@suckless.org` ([Archives](http://lists.suckless.org/dev)) * IRC channel: #suckless at irc.oftc.net +Note On Webkit Versions +----------------------- +Compile your own webkit or expect hell. The packaging of webkit is pure +insane. + Development ----------- surf is actively developed. You can [browse](http://git.suckless.org/surf) its diff --git a/surf.suckless.org/patches/index.md b/surf.suckless.org/patches/index.md @@ -1,30 +1,5 @@ -Patches +patches ======= -diff generation ---------------- -For git users: - - cd surf-directory - git diff > surf-X.Y-yourpatchname.diff - -For tarballs: - - cd modified-surf-directory/.. - diff -up original-surf-directory modified-surf-directory > surf-X.Y-yourpatchname.diff - -where `X.Y` is a surf tag name or version number. - - -patch application ------------------ -For git users: - - cd surf-directory - git apply path/to/patch.diff - -For tarballs: - - cd surf-directory - patch -p1 < path/to/patch.diff - +For instructions on how to submit and format patches, take a look at +the [hacking guidelines](http://suckless.org/hacking). diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.1.1-xmms.diff b/tools.suckless.org/dmenu/patches/dmenu-4.1.1-xmms.diff @@ -1,130 +0,0 @@ ---- dmenu-4.1.1/config.def.h 2010-08-04 14:21:27.468630995 +0100 -+++ dmenu-4.1.1/config.def.h 2010-08-04 15:33:31.475940022 +0100 -@@ -7,3 +7,4 @@ - static const char *selbgcolor = "#0066ff"; - static const char *selfgcolor = "#ffffff"; - static unsigned int spaceitem = 30; /* px between menu items */ -+static unsigned int maxtokens = 16; /* max. tokens for pattern matching */ ---- dmenu-4.1.1/dmenu.1 2010-08-04 14:21:27.468630995 +0100 -+++ dmenu-4.1.1/dmenu.1 2010-08-04 15:18:35.557920858 +0100 -@@ -12,6 +12,7 @@ - .RB [ \-p " <prompt>"] - .RB [ \-sb " <color>"] - .RB [ \-sf " <color>"] -+.RB [ \-xs ] - .RB [ \-v ] - .SH DESCRIPTION - .SS Overview -@@ -49,6 +50,9 @@ - .B \-sf <color> - defines the selected foreground color (#RGB, #RRGGBB, and color names are supported). - .TP -+.B \-xs -+xmms-like pattern matching. -+.TP - .B \-v - prints version information to standard output, then exits. - .SH USAGE ---- dmenu-4.1.1/dmenu.c 2010-08-04 14:21:27.468630995 +0100 -+++ dmenu-4.1.1/dmenu.c 2010-08-04 15:18:35.557920858 +0100 -@@ -75,6 +75,7 @@ - /* variables */ - static char *maxname = NULL; - static char *prompt = NULL; -+static char **tokens = NULL; - static char text[4096]; - static int cmdw = 0; - static int promptw = 0; -@@ -84,6 +85,7 @@ - static unsigned int mw, mh; - static unsigned int numlockmask = 0; - static Bool running = True; -+static Bool xmms = False; - static Display *dpy; - static DC dc; - static Item *allitems = NULL; /* first of all items */ -@@ -578,22 +580,55 @@ - drawmenu(); - } - -+unsigned int tokenize(char *pat, char **tok) -+{ -+ unsigned int i = 0; -+ char tmp[4096] = {0}; -+ -+ strncpy(tmp, pat, strlen(pat)); -+ tok[0] = strtok(tmp, " "); -+ -+ while(tok[i] && i < maxtokens) -+ tok[++i] = strtok(NULL, " "); -+ return i; -+} -+ - void - match(char *pattern) { -- unsigned int plen; -+ unsigned int plen, tokencnt = 0; -+ char append = 0; - Item *i, *itemend, *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; - - if(!pattern) - return; -- plen = strlen(pattern); -+ -+ if(!xmms) -+ tokens[(tokencnt = 1)-1] = pattern; -+ else -+ if(!(tokencnt = tokenize(pattern, tokens))) -+ tokens[(tokencnt = 1)-1] = ""; - item = lexact = lprefix = lsubstr = itemend = exactend = prefixend = substrend = NULL; -- for(i = allitems; i; i = i->next) -- if(!fstrncmp(pattern, i->text, plen + 1)) -+ for(i = allitems; i; i = i->next) { -+ for(int j = 0; j < tokencnt; ++j) { -+ plen = strlen(tokens[j]); -+ if(!fstrncmp(tokens[j], i->text, plen + 1)) -+ append = !append || append > 1 ? 1 : append; -+ else if(!fstrncmp(tokens[j], i->text, plen )) -+ append = !append || append > 2 ? 2 : append; -+ else if(fstrstr(i->text, tokens[j])) -+ append = append > 0 && append < 3 ? append : 3; -+ else { -+ append = 0; -+ break; -+ } -+ } -+ if(append == 1) - appenditem(i, &lexact, &exactend); -- else if(!fstrncmp(pattern, i->text, plen)) -+ else if(append == 2) - appenditem(i, &lprefix, &prefixend); -- else if(fstrstr(i->text, pattern)) -+ else if(append == 3) - appenditem(i, &lsubstr, &substrend); -+ } - if(lexact) { - item = lexact; - itemend = exactend; -@@ -748,6 +783,7 @@ - if(prompt) - promptw = MIN(textw(prompt), mw / 5); - text[0] = '\0'; -+ tokens = malloc((xmms?maxtokens:1)*sizeof(char*)); - match(text); - XMapRaised(dpy, win); - } -@@ -806,11 +842,13 @@ - else if(!strcmp(argv[i], "-sf")) { - if(++i < argc) selfgcolor = argv[i]; - } -+ else if(!strcmp(argv[i], "-xs")) -+ xmms = True; - else if(!strcmp(argv[i], "-v")) - eprint("dmenu-"VERSION", © 2006-2010 dmenu engineers, see LICENSE for details\n"); - else - eprint("usage: dmenu [-i] [-b] [-e <xid>] [-l <lines>] [-fn <font>] [-nb <color>]\n" -- " [-nf <color>] [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); -+ " [-nf <color>] [-p <prompt>] [-sb <color>] [-sf <color>] [-xs] [-v]\n"); - if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) - fprintf(stderr, "warning: no locale support\n"); - if(!(dpy = XOpenDisplay(NULL))) diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.2.1-tok.diff b/tools.suckless.org/dmenu/patches/dmenu-4.2.1-tok.diff @@ -1,101 +0,0 @@ ---- a/dmenu.1 2010-12-28 17:26:44.368974910 +0000 -+++ b/dmenu.1 2010-12-28 17:28:41.902912662 +0000 -@@ -5,6 +5,7 @@ dmenu \- dynamic menu - .B dmenu - .RB [ \-b ] - .RB [ \-i ] -+.RB [ \-t ] - .RB [ \-l - .IR lines ] - .RB [ \-m -@@ -50,6 +51,9 @@ dmenu appears at the bottom of the scree - .B \-i - dmenu matches menu items case insensitively. - .TP -+.B \-t -+dmenu uses space separated tokens to match menu items. -+.TP - .BI \-l " lines" - dmenu lists items vertically, with the given number of lines. - .TP ---- a/dmenu.c 2010-12-28 17:26:44.368974910 +0000 -+++ b/dmenu.c 2010-12-28 17:53:30.548303785 +0000 -@@ -30,7 +30,8 @@ static char *fstrstr(const char *s, cons - static void grabkeyboard(void); - static void insert(const char *s, ssize_t n); - static void keypress(XKeyEvent *ev); --static void match(void); -+static void matchstr(void); -+static void matchtok(void); - static size_t nextrune(int incr); - static void paste(void); - static void readstdin(void); -@@ -62,6 +63,7 @@ static Item *prev, *curr, *next; - static Window root, win; - - static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; -+static void (*match)(void) = matchstr; - - int - main(int argc, char *argv[]) { -@@ -78,6 +80,8 @@ main(int argc, char *argv[]) { - topbar = False; - else if(!strcmp(argv[i], "-i")) - fstrncmp = strncasecmp; -+ else if(!strcmp(argv[i], "-t")) -+ match = matchtok; - else if(i == argc-1) - usage(); - /* double flags */ -@@ -368,7 +372,7 @@ keypress(XKeyEvent *ev) { - } - - void --match(void) { -+matchstr(void) { - size_t len; - Item *item, *itemend, *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; - -@@ -407,6 +411,33 @@ match(void) { - calcoffsets(); - } - -+void -+matchtok(void) { -+ char buf[sizeof text]; -+ char **tokv, *s; -+ int tokc, i; -+ Item *item, *end; -+ -+ tokc = 0; -+ tokv = NULL; -+ strcpy(buf, text); -+ for(s = strtok(buf, " "); s; tokv[tokc-1] = s, s = strtok(NULL, " ")) -+ if(!(tokv = realloc(tokv, ++tokc * sizeof *tokv))) -+ eprintf("cannot realloc %u bytes\n", tokc * sizeof *tokv); -+ -+ matches = end = NULL; -+ for(item = items; item; item = item->next) { -+ for(i = 0; i < tokc; i++) -+ if(!fstrstr(item->text, tokv[i])) -+ break; -+ if(i == tokc) -+ appenditem(item, &matches, &end); -+ } -+ free(tokv); -+ curr = prev = next = sel = matches; -+ calcoffsets(); -+} -+ - size_t - nextrune(int incr) { - size_t n, len; -@@ -536,7 +567,7 @@ setup(void) { - - void - usage(void) { -- fputs("usage: dmenu [-b] [-i] [-l lines] [-m monitor] [-p prompt] [-fn font]\n" -+ fputs("usage: dmenu [-b] [-i] [-t] [-l lines] [-m monitor] [-p prompt] [-fn font]\n" - " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); - exit(EXIT_FAILURE); - } diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.4-follow-focus.diff b/tools.suckless.org/dmenu/patches/dmenu-4.4-follow-focus.diff @@ -1,21 +0,0 @@ -diff -r f6b31468f983 dmenu.c ---- a/dmenu.c Sun Jul 24 20:04:58 2011 +0100 -+++ b/dmenu.c Tue Aug 02 23:22:00 2011 +0200 -@@ -492,11 +492,14 @@ - mh = (lines + 1) * bh; - #ifdef XINERAMA - if((info = XineramaQueryScreens(dc->dpy, &n))) { -- int i, di; -- unsigned int du; -+ int i, revert; - Window dw; -+ XWindowAttributes wa; -+ Window chi; - -- XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du); -+ XGetInputFocus(dc->dpy, &dw, &revert); -+ XGetWindowAttributes(dc->dpy, dw, &wa); -+ XTranslateCoordinates(dc->dpy, wa.root, wa.root, wa.x, wa.y, &x, &y, &chi); - for(i = 0; i < n-1; i++) - if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height)) - break; diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.4-tok.diff b/tools.suckless.org/dmenu/patches/dmenu-4.4-tok.diff @@ -1,103 +0,0 @@ -diff -r f6b31468f983 dmenu.1 ---- a/dmenu.1 Sun Jul 24 20:04:58 2011 +0100 -+++ b/dmenu.1 Mon Sep 12 10:43:11 2011 +0100 -@@ -6,6 +6,7 @@ - .RB [ \-b ] - .RB [ \-f ] - .RB [ \-i ] -+.RB [ \-t ] - .RB [ \-l - .IR lines ] - .RB [ \-p -@@ -48,6 +49,9 @@ - .B \-i - dmenu matches menu items case insensitively. - .TP -+.B \-t -+dmenu uses space\-separated tokens to match menu items. -+.TP - .BI \-l " lines" - dmenu lists items vertically, with the given number of lines. - .TP -diff -r f6b31468f983 dmenu.c ---- a/dmenu.c Sun Jul 24 20:04:58 2011 +0100 -+++ b/dmenu.c Mon Sep 12 10:43:11 2011 +0100 -@@ -30,7 +30,8 @@ - static void grabkeyboard(void); - static void insert(const char *str, ssize_t n); - static void keypress(XKeyEvent *ev); --static void match(Bool sub); -+static void matchstr(Bool sub); -+static void matchtok(Bool sub); - static size_t nextrune(int inc); - static void paste(void); - static void readstdin(void); -@@ -61,6 +62,7 @@ - - static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; - static char *(*fstrstr)(const char *, const char *) = strstr; -+static void (*match)(Bool) = matchstr; - - int - main(int argc, char *argv[]) { -@@ -81,6 +83,8 @@ - fstrncmp = strncasecmp; - fstrstr = cistrstr; - } -+ else if(!strcmp(argv[i], "-t")) -+ match = matchtok; - else if(i+1 == argc) - usage(); - /* double flags */ -@@ -362,7 +366,7 @@ - } - - void --match(Bool sub) { -+matchstr(Bool sub) { - size_t len = strlen(text); - Item *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; - Item *item, *lnext; -@@ -402,6 +406,33 @@ - calcoffsets(); - } - -+void -+matchtok(Bool sub) { -+ char buf[sizeof text]; -+ char **tokv, *s; -+ int tokc, i; -+ Item *item, *end; -+ -+ tokc = 0; -+ tokv = NULL; -+ strcpy(buf, text); -+ for(s = strtok(buf, " "); s; tokv[tokc-1] = s, s = strtok(NULL, " ")) -+ if(!(tokv = realloc(tokv, ++tokc * sizeof *tokv))) -+ eprintf("cannot realloc %u bytes\n", tokc * sizeof *tokv); -+ -+ matches = end = NULL; -+ for(item = items; item->text; item++) { -+ for(i = 0; i < tokc; i++) -+ if(!fstrstr(item->text, tokv[i])) -+ break; -+ if(i == tokc) -+ appenditem(item, &matches, &end); -+ } -+ free(tokv); -+ curr = prev = next = sel = matches; -+ calcoffsets(); -+} -+ - size_t - nextrune(int inc) { - ssize_t n; -@@ -532,7 +563,7 @@ - - void - usage(void) { -- fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font]\n" -+ fputs("usage: dmenu [-b] [-f] [-i] [-t] [-l lines] [-p prompt] [-fn font]\n" - " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); - exit(EXIT_FAILURE); - } diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.4.1-multisel.diff b/tools.suckless.org/dmenu/patches/dmenu-4.4.1-multisel.diff @@ -1,60 +0,0 @@ -diff -r bebcf140b8a9 dmenu.1 ---- a/dmenu.1 Wed Oct 26 14:16:12 2011 +0100 -+++ b/dmenu.1 Thu Oct 27 12:56:43 2011 -0700 -@@ -85,2 +85,5 @@ - .TP -+.B Ctrl-Return -+Confirm selection. Prints the selected item to stdout and continues. -+.TP - .B Shift\-Return (Ctrl\-Shift\-j) -diff -r bebcf140b8a9 dmenu.c ---- a/dmenu.c Wed Oct 26 14:16:12 2011 +0100 -+++ b/dmenu.c Thu Oct 27 12:56:43 2011 -0700 -@@ -24,2 +24,3 @@ - Item *left, *right; -+ Bool out; - }; -@@ -51,2 +52,4 @@ - static const char *selfgcolor = "#ffffff"; -+static const char *outbgcolor = "#00ffff"; -+static const char *outfgcolor = "#000000"; - static unsigned int lines = 0; -@@ -54,2 +57,3 @@ - static unsigned long selcol[ColLast]; -+static unsigned long outcol[ColLast]; - static Atom clip, utf8; -@@ -187,3 +191,4 @@ - dc->y += dc->h; -- drawtext(dc, item->text, (item == sel) ? selcol : normcol); -+ drawtext(dc, item->text, (item == sel) ? selcol : -+ (item->out) ? outcol : normcol); - } -@@ -199,3 +204,4 @@ - dc->w = MIN(textw(dc, item->text), mw - dc->x - textw(dc, ">")); -- drawtext(dc, item->text, (item == sel) ? selcol : normcol); -+ drawtext(dc, item->text, (item == sel) ? selcol : -+ (item->out) ? outcol : normcol); - } -@@ -280,2 +286,5 @@ - return; -+ case XK_Return: -+ case XK_KP_Enter: -+ break; - default: -@@ -352,3 +361,6 @@ - puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); -- exit(EXIT_SUCCESS); -+ if(!(ev->state & ControlMask)) -+ exit(EXIT_SUCCESS); -+ sel->out = True; -+ break; - case XK_Right: -@@ -468,2 +480,3 @@ - eprintf("cannot strdup %u bytes:", strlen(buf)+1); -+ items[i].out = False; - if(strlen(items[i].text) > max) -@@ -519,2 +532,4 @@ - selcol[ColFG] = getcolor(dc, selfgcolor); -+ outcol[ColBG] = getcolor(dc, outbgcolor); -+ outcol[ColFG] = getcolor(dc, outfgcolor); - diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.4.1-xft.diff b/tools.suckless.org/dmenu/patches/dmenu-4.4.1-xft.diff @@ -1,405 +0,0 @@ ---- a/dmenu.c 2011-09-19 11:48:13.000000000 +0200 -+++ b/dmenu.c 2011-12-31 00:48:16.000000000 +0200 -@@ -16,6 +16,7 @@ - #define INRECT(x,y,rx,ry,rw,rh) ((x) >= (rx) && (x) < (rx)+(rw) && (y) >= (ry) && (y) < (ry)+(rh)) - #define MIN(a,b) ((a) < (b) ? (a) : (b)) - #define MAX(a,b) ((a) > (b) ? (a) : (b)) -+#define DEFFONT "fixed" /* xft example: "Monospace-11" */ - - typedef struct Item Item; - struct Item { -@@ -25,6 +26,7 @@ struct Item { - - static void appenditem(Item *item, Item **list, Item **last); - static void calcoffsets(void); -+static void cleanup(void); - static char *cistrstr(const char *s, const char *sub); - static void drawmenu(void); - static void grabkeyboard(void); -@@ -49,10 +51,12 @@ static const char *normbgcolor = "#ccccc - static const char *normfgcolor = "#000000"; - static const char *selbgcolor = "#0066ff"; - static const char *selfgcolor = "#ffffff"; --static unsigned long normcol[ColLast]; --static unsigned long selcol[ColLast]; -+static ColorSet *normcol; -+static ColorSet *selcol; - static Atom utf8; - static Bool topbar = True; -+static Bool running = True; -+static int ret = 0; - static DC *dc; - static Item *items = NULL; - static Item *matches, *matchend; -@@ -102,7 +106,9 @@ main(int argc, char *argv[]) { - usage(); - - dc = initdc(); -- initfont(dc, font); -+ initfont(dc, font ? font : DEFFONT); -+ normcol = initcolor(dc, normfgcolor, normbgcolor); -+ selcol = initcolor(dc, selfgcolor, selbgcolor); - - if(fast) { - grabkeyboard(); -@@ -115,7 +121,8 @@ main(int argc, char *argv[]) { - setup(); - run(); - -- return EXIT_FAILURE; /* unreachable */ -+ cleanup(); -+ return ret; - } - - void -@@ -158,6 +165,16 @@ cistrstr(const char *s, const char *sub) - } - - void -+cleanup(void) { -+ Item *itm; -+ freecol(dc, normcol); -+ freecol(dc, selcol); -+ XDestroyWindow(dc->dpy, win); -+ XUngrabKeyboard(dc->dpy, CurrentTime); -+ freedc(dc); -+} -+ -+void - drawmenu(void) { - int curpos; - Item *item; -@@ -165,7 +182,7 @@ drawmenu(void) { - dc->x = 0; - dc->y = 0; - dc->h = bh; -- drawrect(dc, 0, 0, mw, mh, True, BG(dc, normcol)); -+ drawrect(dc, 0, 0, mw, mh, True, normcol->BG); - - if(prompt) { - dc->w = promptw; -@@ -175,7 +192,7 @@ drawmenu(void) { - dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw; - drawtext(dc, text, normcol); - if((curpos = textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w) -- drawrect(dc, curpos, 2, 1, dc->h - 4, True, FG(dc, normcol)); -+ drawrect(dc, curpos, 2, 1, dc->h - 4, True, normcol->FG); - - if(lines > 0) { - dc->w = mw - dc->x; -@@ -301,7 +318,8 @@ keypress(XKeyEvent *ev) { - sel = matchend; - break; - case XK_Escape: -- exit(EXIT_FAILURE); -+ ret = EXIT_FAILURE; -+ running = False; - case XK_Home: - if(sel == matches) { - cursor = 0; -@@ -337,7 +355,8 @@ keypress(XKeyEvent *ev) { - case XK_Return: - case XK_KP_Enter: - puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); -- exit(EXIT_SUCCESS); -+ ret = EXIT_SUCCESS; -+ running = False; - case XK_Right: - if(text[cursor] != '\0') { - cursor = nextrune(+1); -@@ -449,7 +468,7 @@ void - run(void) { - XEvent ev; - -- while(!XNextEvent(dc->dpy, &ev)) -+ while(running && !XNextEvent(dc->dpy, &ev)) - switch(ev.type) { - case Expose: - if(ev.xexpose.count == 0) -@@ -479,11 +498,6 @@ setup(void) { - XineramaScreenInfo *info; - #endif - -- normcol[ColBG] = getcolor(dc, normbgcolor); -- normcol[ColFG] = getcolor(dc, normfgcolor); -- selcol[ColBG] = getcolor(dc, selbgcolor); -- selcol[ColFG] = getcolor(dc, selfgcolor); -- - utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False); - - /* menu geometry */ ---- a/draw.c 2011-09-19 11:48:13.000000000 +0200 -+++ b/draw.c 2011-12-31 01:44:39.000000000 +0200 -@@ -9,9 +9,6 @@ - - #define MAX(a, b) ((a) > (b) ? (a) : (b)) - #define MIN(a, b) ((a) < (b) ? (a) : (b)) --#define DEFAULTFN "fixed" -- --static Bool loadfont(DC *dc, const char *fontstr); - - void - drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color) { -@@ -23,7 +20,7 @@ drawrect(DC *dc, int x, int y, unsigned - } - - void --drawtext(DC *dc, const char *text, unsigned long col[ColLast]) { -+drawtext(DC *dc, const char *text, ColorSet *col) { - char buf[BUFSIZ]; - size_t mn, n = strlen(text); - -@@ -35,19 +32,24 @@ drawtext(DC *dc, const char *text, unsig - if(mn < n) - for(n = MAX(mn-3, 0); n < mn; buf[n++] = '.'); - -- drawrect(dc, 0, 0, dc->w, dc->h, True, BG(dc, col)); -+ drawrect(dc, 0, 0, dc->w, dc->h, True, col->BG); - drawtextn(dc, buf, mn, col); - } - - void --drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]) { -+drawtextn(DC *dc, const char *text, size_t n, ColorSet *col) { - int x = dc->x + dc->font.height/2; - int y = dc->y + dc->font.ascent+1; - -- XSetForeground(dc->dpy, dc->gc, FG(dc, col)); -- if(dc->font.set) -+ XSetForeground(dc->dpy, dc->gc, col->FG); -+ if(dc->font.xft_font) { -+ if (!dc->xftdraw) -+ eprintf("error, xft drawable does not exist"); -+ XftDrawStringUtf8(dc->xftdraw, &col->FG_xft, -+ dc->font.xft_font, x, y, (unsigned char*)text, n); -+ } else if(dc->font.set) { - XmbDrawString(dc->dpy, dc->canvas, dc->font.set, dc->gc, x, y, text, n); -- else { -+ } else { - XSetFont(dc->dpy, dc->gc, dc->font.xfont->fid); - XDrawString(dc->dpy, dc->canvas, dc->gc, x, y, text, n); - } -@@ -69,16 +71,33 @@ eprintf(const char *fmt, ...) { - } - - void -+freecol(DC *dc, ColorSet *col) { -+ if(col) { -+ if(&col->FG_xft) -+ XftColorFree(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)), -+ DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), &col->FG_xft); -+ free(col); -+ } -+} -+ -+void - freedc(DC *dc) { -+ if(dc->font.xft_font) { -+ XftFontClose(dc->dpy, dc->font.xft_font); -+ XftDrawDestroy(dc->xftdraw); -+ } - if(dc->font.set) - XFreeFontSet(dc->dpy, dc->font.set); -- if(dc->font.xfont) -+ if(dc->font.xfont) - XFreeFont(dc->dpy, dc->font.xfont); -- if(dc->canvas) -+ if(dc->canvas) - XFreePixmap(dc->dpy, dc->canvas); -- XFreeGC(dc->dpy, dc->gc); -- XCloseDisplay(dc->dpy); -- free(dc); -+ if(dc->gc) -+ XFreeGC(dc->dpy, dc->gc); -+ if(dc->dpy) -+ XCloseDisplay(dc->dpy); -+ if(dc) -+ free(dc); - } - - unsigned long -@@ -91,6 +110,20 @@ getcolor(DC *dc, const char *colstr) { - return color.pixel; - } - -+ColorSet * -+initcolor(DC *dc, const char * foreground, const char * background) { -+ ColorSet * col = (ColorSet *)malloc(sizeof(ColorSet)); -+ if(!col) -+ eprintf("error, cannot allocate memory for color set"); -+ col->BG = getcolor(dc, background); -+ col->FG = getcolor(dc, foreground); -+ if(dc->font.xft_font) -+ if(!XftColorAllocName(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)), -+ DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), foreground, &col->FG_xft)) -+ eprintf("error, cannot allocate xft font color '%s'\n", foreground); -+ return col; -+} -+ - DC * - initdc(void) { - DC *dc; -@@ -109,39 +142,33 @@ initdc(void) { - - void - initfont(DC *dc, const char *fontstr) { -- if(!loadfont(dc, fontstr ? fontstr : DEFAULTFN)) { -- if(fontstr != NULL) -- fprintf(stderr, "cannot load font '%s'\n", fontstr); -- if(fontstr == NULL || !loadfont(dc, DEFAULTFN)) -- eprintf("cannot load font '%s'\n", DEFAULTFN); -- } -- dc->font.height = dc->font.ascent + dc->font.descent; --} -- --Bool --loadfont(DC *dc, const char *fontstr) { - char *def, **missing, **names; - int i, n; - XFontStruct **xfonts; - -- if(!*fontstr) -- return False; -- if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) { -+ missing = NULL; -+ if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) { -+ dc->font.ascent = dc->font.xfont->ascent; -+ dc->font.descent = dc->font.xfont->descent; -+ dc->font.width = dc->font.xfont->max_bounds.width; -+ } else if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) { - n = XFontsOfFontSet(dc->font.set, &xfonts, &names); - for(i = 0; i < n; i++) { - dc->font.ascent = MAX(dc->font.ascent, xfonts[i]->ascent); - dc->font.descent = MAX(dc->font.descent, xfonts[i]->descent); - dc->font.width = MAX(dc->font.width, xfonts[i]->max_bounds.width); - } -- } -- else if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) { -- dc->font.ascent = dc->font.xfont->ascent; -- dc->font.descent = dc->font.xfont->descent; -- dc->font.width = dc->font.xfont->max_bounds.width; -+ } else if((dc->font.xft_font = XftFontOpenName(dc->dpy, DefaultScreen(dc->dpy), fontstr))) { -+ dc->font.ascent = dc->font.xft_font->ascent; -+ dc->font.descent = dc->font.xft_font->descent; -+ dc->font.width = dc->font.xft_font->max_advance_width; -+ } else { -+ eprintf("cannot load font '%s'\n", fontstr); - } - if(missing) - XFreeStringList(missing); -- return dc->font.set || dc->font.xfont; -+ dc->font.height = dc->font.ascent + dc->font.descent; -+ return; - } - - void -@@ -151,20 +178,29 @@ mapdc(DC *dc, Window win, unsigned int w - - void - resizedc(DC *dc, unsigned int w, unsigned int h) { -+ int screen = DefaultScreen(dc->dpy); - if(dc->canvas) - XFreePixmap(dc->dpy, dc->canvas); - - dc->w = w; - dc->h = h; - dc->canvas = XCreatePixmap(dc->dpy, DefaultRootWindow(dc->dpy), w, h, -- DefaultDepth(dc->dpy, DefaultScreen(dc->dpy))); -+ DefaultDepth(dc->dpy, screen)); -+ if(dc->font.xft_font && !(dc->xftdraw)) { -+ dc->xftdraw = XftDrawCreate(dc->dpy, dc->canvas, DefaultVisual(dc->dpy,screen), DefaultColormap(dc->dpy,screen)); -+ if(!(dc->xftdraw)) -+ eprintf("error, cannot create xft drawable\n"); -+ } - } - - int - textnw(DC *dc, const char *text, size_t len) { -- if(dc->font.set) { -+ if(dc->font.xft_font) { -+ XGlyphInfo gi; -+ XftTextExtentsUtf8(dc->dpy, dc->font.xft_font, (const FcChar8*)text, len, &gi); -+ return gi.width; -+ } else if(dc->font.set) { - XRectangle r; -- - XmbTextExtents(dc->font.set, text, len, NULL, &r); - return r.width; - } ---- a/draw.h 2011-09-19 11:48:13.000000000 +0200 -+++ b/draw.h 2011-12-31 00:28:01.000000000 +0200 -@@ -1,9 +1,6 @@ - /* See LICENSE file for copyright and license details. */ - --#define FG(dc, col) ((col)[(dc)->invert ? ColBG : ColFG]) --#define BG(dc, col) ((col)[(dc)->invert ? ColFG : ColBG]) -- --enum { ColBG, ColFG, ColBorder, ColLast }; -+#include <X11/Xft/Xft.h> - - typedef struct { - int x, y, w, h; -@@ -11,6 +8,7 @@ typedef struct { - Display *dpy; - GC gc; - Pixmap canvas; -+ XftDraw *xftdraw; - struct { - int ascent; - int descent; -@@ -18,15 +16,24 @@ typedef struct { - int width; - XFontSet set; - XFontStruct *xfont; -+ XftFont *xft_font; - } font; - } DC; /* draw context */ - -+typedef struct { -+ unsigned long FG; -+ XftColor FG_xft; -+ unsigned long BG; -+} ColorSet; -+ - void drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color); --void drawtext(DC *dc, const char *text, unsigned long col[ColLast]); --void drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]); -+void drawtext(DC *dc, const char *text, ColorSet *col); -+void drawtextn(DC *dc, const char *text, size_t n, ColorSet *col); -+void freecol(DC *dc, ColorSet *col); - void eprintf(const char *fmt, ...); - void freedc(DC *dc); - unsigned long getcolor(DC *dc, const char *colstr); -+ColorSet *initcolor(DC *dc, const char *foreground, const char *background); - DC *initdc(void); - void initfont(DC *dc, const char *fontstr); - void mapdc(DC *dc, Window win, unsigned int w, unsigned int h); ---- a/dmenu.1 2011-09-19 11:48:13.000000000 +0200 -+++ b/dmenu.1 2011-12-30 23:23:44.000000000 +0200 -@@ -55,7 +55,7 @@ - defines the prompt to be displayed to the left of the input field. - .TP - .BI \-fn " font" --defines the font or font set used. -+defines the font or font set used. eg. "fixed" or "Monospace-12:normal" (an xft font) - .TP - .BI \-nb " color" - defines the normal background color. ---- a/config.mk 2011-12-30 23:23:44.000000000 +0200 -+++ b/config.mk 2011-12-30 23:23:44.000000000 +0200 -@@ -12,9 +12,13 @@ - XINERAMALIBS = -lXinerama - XINERAMAFLAGS = -DXINERAMA - -+# Xft, comment if you don't want it -+XFTINC = -I/usr/local/include/freetype2 -+XFTLIBS = -lXft -lXrender -lfreetype -lz -lfontconfig -+ - # includes and libs --INCS = -I${X11INC} --LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} -+INCS = -I${X11INC} ${XFTINC} -+LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${XFTLIBS} - - # flags - CPPFLAGS+= -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.5-fuzzymatch.diff b/tools.suckless.org/dmenu/patches/dmenu-4.5-fuzzymatch.diff @@ -1,135 +0,0 @@ -diff --git a/dmenu.c b/dmenu.c -index 4ea95f8..19c5cb6 100644 ---- a/dmenu.c -+++ b/dmenu.c -@@ -22,6 +22,7 @@ typedef struct Item Item; - struct Item { - char *text; - Item *left, *right; -+ int distance; - }; - - static void appenditem(Item *item, Item **list, Item **last); -@@ -221,6 +222,86 @@ grabkeyboard(void) { - eprintf("cannot grab keyboard\n"); - } - -+int -+compare_distance(const void *a, const void *b) { -+ Item const *da = *(Item **) a; -+ Item const *db = *(Item **) b; -+ if(!db) -+ return 1; -+ if(!da) -+ return -1; -+ return da->distance - db->distance; -+} -+ -+void -+fuzzymatch(void) { -+ /* bang - we have so much memory */ -+ Item *item; -+ Item **fuzzymatches = NULL; -+ char c; -+ int number_of_matches = 0, i, pidx, sidx, eidx; -+ int text_len = strlen(text), itext_len; -+ -+ matches = matchend = NULL; -+ -+ /* suppress compiler warning for unused match function */ -+ if(0) -+ match(); -+ -+ /* walk through all items */ -+ for(item = items; item && item->text; item++) { -+ if(text_len) { -+ itext_len = strlen(item->text); -+ pidx = 0; -+ sidx = eidx = -1; -+ /* walk through item text */ -+ for(i = 0; i < itext_len && (c = item->text[i]); i++) { -+ /* fuzzy match pattern */ -+ if(text[pidx] == c) { -+ if(sidx == -1) -+ sidx = i; -+ pidx++; -+ if(pidx == text_len) { -+ eidx = i; -+ break; -+ } -+ } -+ } -+ /* build list of matches */ -+ if(eidx != -1) { -+ /* compute distance */ -+ /* factor in 30% of sidx and distance between eidx and total -+ * text length .. let's see how it works */ -+ item->distance = eidx - sidx + (itext_len - eidx + sidx) / 3; -+ appenditem(item, &matches, &matchend); -+ number_of_matches++; -+ } -+ } -+ else -+ appenditem(item, &matches, &matchend); -+ } -+ -+ if(number_of_matches) { -+ /* initialize array with matches */ -+ if(!(fuzzymatches = realloc(fuzzymatches, number_of_matches * sizeof(Item*)))) -+ eprintf("cannot realloc %u bytes:", number_of_matches * sizeof(Item*)); -+ for(i = 0, item = matches; item && i < number_of_matches; i++, item = item->right) { -+ fuzzymatches[i] = item; -+ } -+ /* sort matches according to distance */ -+ qsort(fuzzymatches, number_of_matches, sizeof(Item*), compare_distance); -+ /* rebuild list of matches */ -+ matches = matchend = NULL; -+ for(i = 0, item = fuzzymatches[i]; i < number_of_matches && item && \ -+ item->text; i++, item = fuzzymatches[i]) { -+ appenditem(item, &matches, &matchend); -+ } -+ free(fuzzymatches); -+ } -+ curr = sel = matches; -+ calcoffsets(); -+} -+ - void - insert(const char *str, ssize_t n) { - if(strlen(text) + n > sizeof text - 1) -@@ -230,7 +311,7 @@ insert(const char *str, ssize_t n) { - if(n > 0) - memcpy(&text[cursor], str, n); - cursor += n; -- match(); -+ fuzzymatch(); - } - - void -@@ -260,7 +341,7 @@ keypress(XKeyEvent *ev) { - - case XK_k: /* delete right */ - text[cursor] = '\0'; -- match(); -+ fuzzymatch(); - break; - case XK_u: /* delete left */ - insert(NULL, 0 - cursor); -@@ -379,7 +460,7 @@ keypress(XKeyEvent *ev) { - return; - strncpy(text, sel->text, sizeof text); - cursor = strlen(text); -- match(); -+ fuzzymatch(); - break; - } - drawmenu(); -@@ -578,7 +659,7 @@ setup(void) { - } - promptw = prompt ? textw(dc, prompt) : 0; - inputw = MIN(inputw, mw/3); -- match(); -+ fuzzymatch(); - - /* create menu window */ - swa.override_redirect = True; diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.5-hide-single-newline.diff b/tools.suckless.org/dmenu/patches/dmenu-4.5-hide-single-newline.diff @@ -1,12 +0,0 @@ -diff --git a/dmenu.c b/dmenu.c -index 4ea95f8..4b76da5 100644 ---- a/dmenu.c -+++ b/dmenu.c -@@ -482,6 +482,7 @@ readstdin(void) { - } - if(items) - items[i].text = NULL; -+ if (i == 1 && items[0].text[0] == '\0') items = realloc(items, 0); - inputw = maxstr ? textw(dc, maxstr) : 0; - lines = MIN(lines, i); - } diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.5-monarg.diff b/tools.suckless.org/dmenu/patches/dmenu-4.5-monarg.diff @@ -1,101 +0,0 @@ -diff --git a/dmenu.1 b/dmenu.1 -index 0784cd9..a0b488b 100644 ---- a/dmenu.1 -+++ b/dmenu.1 -@@ -12,6 +12,8 @@ dmenu \- dynamic menu - .IR prompt ] - .RB [ \-fn - .IR font ] -+.RB [ \-m -+.IR monitor ] - .RB [ \-nb - .IR color ] - .RB [ \-nf -@@ -55,6 +57,9 @@ defines the prompt to be displayed to the left of the input field. - .BI \-fn " font" - defines the font or font set used. - .TP -+.BI \-m " monitor" -+defines what monitor to run dmenu on. -+.TP - .BI \-nb " color" - defines the normal background color. - .IR #RGB , -diff --git a/dmenu.c b/dmenu.c -index 4ea95f8..fb2f096 100644 ---- a/dmenu.c -+++ b/dmenu.c -@@ -60,6 +60,7 @@ static Item *matches, *matchend; - static Item *prev, *curr, *next, *sel; - static Window win; - static XIC xic; -+static int mon = -1; - - static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; - static char *(*fstrstr)(const char *, const char *) = strstr; -@@ -90,6 +91,8 @@ main(int argc, char *argv[]) { - lines = atoi(argv[++i]); - else if(!strcmp(argv[i], "-p")) /* adds prompt to left of input field */ - prompt = argv[++i]; -+ else if(!strcmp(argv[i], "-m")) /* monitor index */ -+ mon = atoi(argv[++i]); - else if(!strcmp(argv[i], "-fn")) /* font or font set */ - font = argv[++i]; - else if(!strcmp(argv[i], "-nb")) /* normal background color */ -@@ -544,25 +547,29 @@ setup(void) { - XWindowAttributes wa; - - XGetInputFocus(dc->dpy, &w, &di); -- if(w != root && w != PointerRoot && w != None) { -- /* find top-level window containing current input focus */ -- do { -- if(XQueryTree(dc->dpy, (pw = w), &dw, &w, &dws, &du) && dws) -- XFree(dws); -- } while(w != root && w != pw); -- /* find xinerama screen with which the window intersects most */ -- if(XGetWindowAttributes(dc->dpy, pw, &wa)) -- for(j = 0; j < n; j++) -- if((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) { -- area = a; -- i = j; -- } -+ if(mon > -1 && mon < n) -+ i = mon; -+ else { -+ if(w != root && w != PointerRoot && w != None) { -+ /* find top-level window containing current input focus */ -+ do { -+ if(XQueryTree(dc->dpy, (pw = w), &dw, &w, &dws, &du) && dws) -+ XFree(dws); -+ } while(w != root && w != pw); -+ /* find xinerama screen with which the window intersects most */ -+ if(XGetWindowAttributes(dc->dpy, pw, &wa)) -+ for(j = 0; j < n; j++) -+ if((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) { -+ area = a; -+ i = j; -+ } -+ } -+ /* no focused window is on screen, so use pointer location instead */ -+ if(!area && XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du)) -+ for(i = 0; i < n; i++) -+ if(INTERSECT(x, y, 1, 1, info[i])) -+ break; - } -- /* no focused window is on screen, so use pointer location instead */ -- if(!area && XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du)) -- for(i = 0; i < n; i++) -- if(INTERSECT(x, y, 1, 1, info[i])) -- break; - - x = info[i].x_org; - y = info[i].y_org + (topbar ? 0 : info[i].height - mh); -@@ -601,7 +608,7 @@ setup(void) { - - void - usage(void) { -- fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font]\n" -+ fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" - " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); - exit(EXIT_FAILURE); - } diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.5-mouse-support.diff b/tools.suckless.org/dmenu/patches/dmenu-4.5-mouse-support.diff @@ -1,142 +0,0 @@ -diff --git a/dmenu.c b/dmenu.c -index 3962801..a75bf80 100644 ---- a/dmenu.c -+++ b/dmenu.c -@@ -25,6 +25,7 @@ struct Item { - }; - - static void appenditem(Item *item, Item **list, Item **last); -+static void buttonpress(XEvent *e); - static void calcoffsets(void); - static char *cistrstr(const char *s, const char *sub); - static void drawmenu(void); -@@ -389,6 +390,109 @@ keypress(XKeyEvent *ev) { - } - - void -+buttonpress(XEvent *e) { -+ int curpos; -+ Item *item; -+ XButtonPressedEvent *ev = &e->xbutton; -+ -+ if(ev->window != win) -+ return; -+ -+ /* right-click: exit */ -+ if(ev->button == Button3) -+ exit(EXIT_FAILURE); -+ -+ dc->x = 0; -+ dc->y = 0; -+ dc->h = bh; -+ -+ if(prompt && *prompt) { -+ dc->w = promptw; -+ dc->x = dc->w; -+ } -+ /* input field */ -+ dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw; -+ if((curpos = textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w); -+ -+ /* 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(ev->button == Button1 && -+ ((lines <= 0 && ev->x >= 0 && ev->x <= dc->x + dc->w + -+ ((!prev || !curr->left) ? textw(dc, "<") : 0)) || -+ (lines > 0 && ev->y >= dc->y && ev->y <= dc->y + dc->h))) { -+ insert(NULL, 0 - cursor); -+ drawmenu(); -+ return; -+ } -+ /* middle-mouse click: paste selection */ -+ if(ev->button == Button2) { -+ XConvertSelection(dc->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(lines > 0) { -+ /* vertical list: left-click on item */ -+ dc->w = mw - dc->x; -+ for(item = curr; item != next; item = item->right) { -+ dc->y += dc->h; -+ if(ev->y >= dc->y && ev->y <= (dc->y + dc->h)) { -+ puts(item->text); -+ exit(EXIT_SUCCESS); -+ } -+ } -+ } -+ else if(matches) { -+ /* left-click on left arrow */ -+ dc->x += inputw; -+ dc->w = textw(dc, "<"); -+ if(prev && curr->left) { -+ if(ev->x >= dc->x && ev->x <= dc->x + dc->w) { -+ sel = curr = prev; -+ calcoffsets(); -+ drawmenu(); -+ return; -+ } -+ } -+ /* horizontal list: left-click on item */ -+ for(item = curr; item != next; item = item->right) { -+ dc->x += dc->w; -+ dc->w = MIN(textw(dc, item->text), mw - dc->x - textw(dc, ">")); -+ if(ev->x >= dc->x && ev->x <= (dc->x + dc->w)) { -+ puts(item->text); -+ exit(EXIT_SUCCESS); -+ } -+ } -+ /* left-click on right arrow */ -+ dc->w = textw(dc, ">"); -+ dc->x = mw - dc->w; -+ if(next && ev->x >= dc->x && ev->x <= dc->x + dc->w) { -+ sel = curr = next; -+ calcoffsets(); -+ drawmenu(); -+ return; -+ } -+ } -+} -+ -+void - match(void) { - static char **tokv = NULL; - static int tokn = 0; -@@ -497,6 +601,9 @@ run(void) { - if(XFilterEvent(&ev, win)) - continue; - switch(ev.type) { -+ case ButtonPress: -+ buttonpress(&ev); -+ break; - case Expose: - if(ev.xexpose.count == 0) - mapdc(dc, win, mw, mh); -@@ -586,7 +693,8 @@ setup(void) { - /* create menu window */ - swa.override_redirect = True; - swa.background_pixel = normcol[ColBG]; -- swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; -+ swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask | -+ ButtonPressMask; - win = XCreateWindow(dc->dpy, root, x, y, mw, mh, 0, - DefaultDepth(dc->dpy, screen), CopyFromParent, - DefaultVisual(dc->dpy, screen), diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.5-xft-debian.diff b/tools.suckless.org/dmenu/patches/dmenu-4.5-xft-debian.diff @@ -1,418 +0,0 @@ -diff -upr a/config.mk b/config.mk ---- a/config.mk 2012-01-10 19:03:22.000000000 +0200 -+++ b/config.mk 2012-01-10 19:03:38.000000000 +0200 -@@ -12,9 +12,13 @@ X11LIB = /usr/X11R6/lib - XINERAMALIBS = -lXinerama - XINERAMAFLAGS = -DXINERAMA - -+# Xft, comment if you don't want it -+XFTINC = -I/usr/include/freetype2 -+XFTLIBS = -lXft -lXrender -lfreetype -lz -lfontconfig -+ - # includes and libs --INCS = -I${X11INC} --LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} -+INCS = -I${X11INC} ${XFTINC} -+LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${XFTLIBS} - - # flags - CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -diff -upr a/dmenu.1 b/dmenu.1 ---- a/dmenu.1 2012-01-10 19:14:19.000000000 +0200 -+++ b/dmenu.1 2012-01-10 19:14:23.000000000 +0200 -@@ -53,7 +53,7 @@ dmenu lists items vertically, with the g - defines the prompt to be displayed to the left of the input field. - .TP - .BI \-fn " font" --defines the font or font set used. -+defines the font or font set used. eg. "fixed" or "Monospace-12:normal" (an xft font) - .TP - .BI \-nb " color" - defines the normal background color. -diff -upr a/dmenu.c b/dmenu.c ---- a/dmenu.c 2012-01-10 19:14:19.000000000 +0200 -+++ b/dmenu.c 2012-01-10 19:24:39.000000000 +0200 -@@ -17,6 +17,7 @@ - * MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org))) - #define MIN(a,b) ((a) < (b) ? (a) : (b)) - #define MAX(a,b) ((a) > (b) ? (a) : (b)) -+#define DEFFONT "fixed" /* xft example: "Monospace-11" */ - - typedef struct Item Item; - struct Item { -@@ -26,6 +27,7 @@ struct Item { - - static void appenditem(Item *item, Item **list, Item **last); - static void calcoffsets(void); -+static void cleanup(void); - static char *cistrstr(const char *s, const char *sub); - static void drawmenu(void); - static void grabkeyboard(void); -@@ -50,10 +52,12 @@ static const char *normfgcolor = "#bbbbb - static const char *selbgcolor = "#005577"; - static const char *selfgcolor = "#eeeeee"; - static unsigned int lines = 0; --static unsigned long normcol[ColLast]; --static unsigned long selcol[ColLast]; -+static ColorSet *normcol; -+static ColorSet *selcol; - static Atom clip, utf8; - static Bool topbar = True; -+static Bool running = True; -+static int ret = 0; - static DC *dc; - static Item *items = NULL; - static Item *matches, *matchend; -@@ -104,7 +108,9 @@ main(int argc, char *argv[]) { - usage(); - - dc = initdc(); -- initfont(dc, font); -+ initfont(dc, font ? font : DEFFONT); -+ normcol = initcolor(dc, normfgcolor, normbgcolor); -+ selcol = initcolor(dc, selfgcolor, selbgcolor); - - if(fast) { - grabkeyboard(); -@@ -117,7 +123,8 @@ main(int argc, char *argv[]) { - setup(); - run(); - -- return 1; /* unreachable */ -+ cleanup(); -+ return ret; - } - - void -@@ -160,6 +167,15 @@ cistrstr(const char *s, const char *sub) - } - - void -+cleanup(void) { -+ freecol(dc, normcol); -+ freecol(dc, selcol); -+ XDestroyWindow(dc->dpy, win); -+ XUngrabKeyboard(dc->dpy, CurrentTime); -+ freedc(dc); -+} -+ -+void - drawmenu(void) { - int curpos; - Item *item; -@@ -167,7 +183,7 @@ drawmenu(void) { - dc->x = 0; - dc->y = 0; - dc->h = bh; -- drawrect(dc, 0, 0, mw, mh, True, BG(dc, normcol)); -+ drawrect(dc, 0, 0, mw, mh, True, normcol->BG); - - if(prompt) { - dc->w = promptw; -@@ -178,7 +194,7 @@ drawmenu(void) { - dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw; - drawtext(dc, text, normcol); - if((curpos = textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w) -- drawrect(dc, curpos, 2, 1, dc->h - 4, True, FG(dc, normcol)); -+ drawrect(dc, curpos, 2, 1, dc->h - 4, True, normcol->FG); - - if(lines > 0) { - /* draw vertical list */ -@@ -321,7 +337,8 @@ keypress(XKeyEvent *ev) { - sel = matchend; - break; - case XK_Escape: -- exit(EXIT_FAILURE); -+ ret = EXIT_FAILURE; -+ running = False; - case XK_Home: - if(sel == matches) { - cursor = 0; -@@ -359,7 +376,8 @@ keypress(XKeyEvent *ev) { - case XK_Return: - case XK_KP_Enter: - puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); -- exit(EXIT_SUCCESS); -+ ret = EXIT_SUCCESS; -+ running = False; - case XK_Right: - if(text[cursor] != '\0') { - cursor = nextrune(+1); -@@ -490,7 +508,7 @@ void - run(void) { - XEvent ev; - -- while(!XNextEvent(dc->dpy, &ev)) { -+ while(running && !XNextEvent(dc->dpy, &ev)) { - if(XFilterEvent(&ev, win)) - continue; - switch(ev.type) { -@@ -524,11 +542,6 @@ setup(void) { - XineramaScreenInfo *info; - #endif - -- normcol[ColBG] = getcolor(dc, normbgcolor); -- normcol[ColFG] = getcolor(dc, normfgcolor); -- selcol[ColBG] = getcolor(dc, selbgcolor); -- selcol[ColFG] = getcolor(dc, selfgcolor); -- - clip = XInternAtom(dc->dpy, "CLIPBOARD", False); - utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False); - -@@ -582,7 +595,7 @@ setup(void) { - - /* create menu window */ - swa.override_redirect = True; -- swa.background_pixel = normcol[ColBG]; -+ swa.background_pixel = normcol->BG; - swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; - win = XCreateWindow(dc->dpy, root, x, y, mw, mh, 0, - DefaultDepth(dc->dpy, screen), CopyFromParent, -diff -upr a/draw.c b/draw.c ---- a/draw.c 2012-01-10 19:14:19.000000000 +0200 -+++ b/draw.c 2012-01-10 19:14:23.000000000 +0200 -@@ -9,9 +9,6 @@ - - #define MAX(a, b) ((a) > (b) ? (a) : (b)) - #define MIN(a, b) ((a) < (b) ? (a) : (b)) --#define DEFAULTFN "fixed" -- --static Bool loadfont(DC *dc, const char *fontstr); - - void - drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color) { -@@ -23,7 +20,7 @@ drawrect(DC *dc, int x, int y, unsigned - } - - void --drawtext(DC *dc, const char *text, unsigned long col[ColLast]) { -+drawtext(DC *dc, const char *text, ColorSet *col) { - char buf[BUFSIZ]; - size_t mn, n = strlen(text); - -@@ -35,19 +32,24 @@ drawtext(DC *dc, const char *text, unsig - if(mn < n) - for(n = MAX(mn-3, 0); n < mn; buf[n++] = '.'); - -- drawrect(dc, 0, 0, dc->w, dc->h, True, BG(dc, col)); -+ drawrect(dc, 0, 0, dc->w, dc->h, True, col->BG); - drawtextn(dc, buf, mn, col); - } - - void --drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]) { -+drawtextn(DC *dc, const char *text, size_t n, ColorSet *col) { - int x = dc->x + dc->font.height/2; - int y = dc->y + dc->font.ascent+1; - -- XSetForeground(dc->dpy, dc->gc, FG(dc, col)); -- if(dc->font.set) -+ XSetForeground(dc->dpy, dc->gc, col->FG); -+ if(dc->font.xft_font) { -+ if (!dc->xftdraw) -+ eprintf("error, xft drawable does not exist"); -+ XftDrawStringUtf8(dc->xftdraw, &col->FG_xft, -+ dc->font.xft_font, x, y, (unsigned char*)text, n); -+ } else if(dc->font.set) { - XmbDrawString(dc->dpy, dc->canvas, dc->font.set, dc->gc, x, y, text, n); -- else { -+ } else { - XSetFont(dc->dpy, dc->gc, dc->font.xfont->fid); - XDrawString(dc->dpy, dc->canvas, dc->gc, x, y, text, n); - } -@@ -69,16 +71,33 @@ eprintf(const char *fmt, ...) { - } - - void -+freecol(DC *dc, ColorSet *col) { -+ if(col) { -+ if(&col->FG_xft) -+ XftColorFree(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)), -+ DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), &col->FG_xft); -+ free(col); -+ } -+} -+ -+void - freedc(DC *dc) { -+ if(dc->font.xft_font) { -+ XftFontClose(dc->dpy, dc->font.xft_font); -+ XftDrawDestroy(dc->xftdraw); -+ } - if(dc->font.set) - XFreeFontSet(dc->dpy, dc->font.set); -- if(dc->font.xfont) -+ if(dc->font.xfont) - XFreeFont(dc->dpy, dc->font.xfont); -- if(dc->canvas) -+ if(dc->canvas) - XFreePixmap(dc->dpy, dc->canvas); -- XFreeGC(dc->dpy, dc->gc); -- XCloseDisplay(dc->dpy); -- free(dc); -+ if(dc->gc) -+ XFreeGC(dc->dpy, dc->gc); -+ if(dc->dpy) -+ XCloseDisplay(dc->dpy); -+ if(dc) -+ free(dc); - } - - unsigned long -@@ -91,6 +110,20 @@ getcolor(DC *dc, const char *colstr) { - return color.pixel; - } - -+ColorSet * -+initcolor(DC *dc, const char * foreground, const char * background) { -+ ColorSet * col = (ColorSet *)malloc(sizeof(ColorSet)); -+ if(!col) -+ eprintf("error, cannot allocate memory for color set"); -+ col->BG = getcolor(dc, background); -+ col->FG = getcolor(dc, foreground); -+ if(dc->font.xft_font) -+ if(!XftColorAllocName(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)), -+ DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), foreground, &col->FG_xft)) -+ eprintf("error, cannot allocate xft font color '%s'\n", foreground); -+ return col; -+} -+ - DC * - initdc(void) { - DC *dc; -@@ -109,39 +142,33 @@ initdc(void) { - - void - initfont(DC *dc, const char *fontstr) { -- if(!loadfont(dc, fontstr ? fontstr : DEFAULTFN)) { -- if(fontstr != NULL) -- fprintf(stderr, "cannot load font '%s'\n", fontstr); -- if(fontstr == NULL || !loadfont(dc, DEFAULTFN)) -- eprintf("cannot load font '%s'\n", DEFAULTFN); -- } -- dc->font.height = dc->font.ascent + dc->font.descent; --} -- --Bool --loadfont(DC *dc, const char *fontstr) { - char *def, **missing, **names; - int i, n; - XFontStruct **xfonts; - -- if(!*fontstr) -- return False; -- if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) { -+ missing = NULL; -+ if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) { -+ dc->font.ascent = dc->font.xfont->ascent; -+ dc->font.descent = dc->font.xfont->descent; -+ dc->font.width = dc->font.xfont->max_bounds.width; -+ } else if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) { - n = XFontsOfFontSet(dc->font.set, &xfonts, &names); - for(i = 0; i < n; i++) { - dc->font.ascent = MAX(dc->font.ascent, xfonts[i]->ascent); - dc->font.descent = MAX(dc->font.descent, xfonts[i]->descent); - dc->font.width = MAX(dc->font.width, xfonts[i]->max_bounds.width); - } -- } -- else if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) { -- dc->font.ascent = dc->font.xfont->ascent; -- dc->font.descent = dc->font.xfont->descent; -- dc->font.width = dc->font.xfont->max_bounds.width; -+ } else if((dc->font.xft_font = XftFontOpenName(dc->dpy, DefaultScreen(dc->dpy), fontstr))) { -+ dc->font.ascent = dc->font.xft_font->ascent; -+ dc->font.descent = dc->font.xft_font->descent; -+ dc->font.width = dc->font.xft_font->max_advance_width; -+ } else { -+ eprintf("cannot load font '%s'\n", fontstr); - } - if(missing) - XFreeStringList(missing); -- return dc->font.set || dc->font.xfont; -+ dc->font.height = dc->font.ascent + dc->font.descent; -+ return; - } - - void -@@ -151,20 +178,29 @@ mapdc(DC *dc, Window win, unsigned int w - - void - resizedc(DC *dc, unsigned int w, unsigned int h) { -+ int screen = DefaultScreen(dc->dpy); - if(dc->canvas) - XFreePixmap(dc->dpy, dc->canvas); - - dc->w = w; - dc->h = h; - dc->canvas = XCreatePixmap(dc->dpy, DefaultRootWindow(dc->dpy), w, h, -- DefaultDepth(dc->dpy, DefaultScreen(dc->dpy))); -+ DefaultDepth(dc->dpy, screen)); -+ if(dc->font.xft_font && !(dc->xftdraw)) { -+ dc->xftdraw = XftDrawCreate(dc->dpy, dc->canvas, DefaultVisual(dc->dpy,screen), DefaultColormap(dc->dpy,screen)); -+ if(!(dc->xftdraw)) -+ eprintf("error, cannot create xft drawable\n"); -+ } - } - - int - textnw(DC *dc, const char *text, size_t len) { -- if(dc->font.set) { -+ if(dc->font.xft_font) { -+ XGlyphInfo gi; -+ XftTextExtentsUtf8(dc->dpy, dc->font.xft_font, (const FcChar8*)text, len, &gi); -+ return gi.width; -+ } else if(dc->font.set) { - XRectangle r; -- - XmbTextExtents(dc->font.set, text, len, NULL, &r); - return r.width; - } -diff -upr a/draw.h b/draw.h ---- a/draw.h 2012-01-10 19:14:19.000000000 +0200 -+++ b/draw.h 2012-01-10 19:14:23.000000000 +0200 -@@ -1,9 +1,6 @@ - /* See LICENSE file for copyright and license details. */ - --#define FG(dc, col) ((col)[(dc)->invert ? ColBG : ColFG]) --#define BG(dc, col) ((col)[(dc)->invert ? ColFG : ColBG]) -- --enum { ColBG, ColFG, ColBorder, ColLast }; -+#include <X11/Xft/Xft.h> - - typedef struct { - int x, y, w, h; -@@ -11,6 +8,7 @@ typedef struct { - Display *dpy; - GC gc; - Pixmap canvas; -+ XftDraw *xftdraw; - struct { - int ascent; - int descent; -@@ -18,15 +16,24 @@ typedef struct { - int width; - XFontSet set; - XFontStruct *xfont; -+ XftFont *xft_font; - } font; - } DC; /* draw context */ - -+typedef struct { -+ unsigned long FG; -+ XftColor FG_xft; -+ unsigned long BG; -+} ColorSet; -+ - void drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color); --void drawtext(DC *dc, const char *text, unsigned long col[ColLast]); --void drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]); -+void drawtext(DC *dc, const char *text, ColorSet *col); -+void drawtextn(DC *dc, const char *text, size_t n, ColorSet *col); -+void freecol(DC *dc, ColorSet *col); - void eprintf(const char *fmt, ...); - void freedc(DC *dc); - unsigned long getcolor(DC *dc, const char *colstr); -+ColorSet *initcolor(DC *dc, const char *foreground, const char *background); - DC *initdc(void); - void initfont(DC *dc, const char *fontstr); - void mapdc(DC *dc, Window win, unsigned int w, unsigned int h); diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.5-xft-improved.diff b/tools.suckless.org/dmenu/patches/dmenu-4.5-xft-improved.diff @@ -1,425 +0,0 @@ -diff --git a/config.mk b/config.mk -index 92a5e63..9cff5db 100644 ---- a/config.mk -+++ b/config.mk -@@ -12,9 +12,13 @@ X11LIB = /usr/X11R6/lib - XINERAMALIBS = -lXinerama - XINERAMAFLAGS = -DXINERAMA - -+# Xft, comment if you don't want it -+XFTINC = -I/usr/include/freetype2 -+XFTLIBS = -lXft -lXrender -lfreetype -lz -lfontconfig -+ - # includes and libs --INCS = -I${X11INC} --LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} -+INCS = -I${X11INC} ${XFTINC} -+LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${XFTLIBS} - - # flags - CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -diff --git a/dmenu.1 b/dmenu.1 -index 0784cd9..f29ca36 100644 ---- a/dmenu.1 -+++ b/dmenu.1 -@@ -53,7 +53,7 @@ dmenu lists items vertically, with the given number of lines. - defines the prompt to be displayed to the left of the input field. - .TP - .BI \-fn " font" --defines the font or font set used. -+defines the font or font set used. eg. "fixed" or "Monospace-12:normal" (an xft font) - .TP - .BI \-nb " color" - defines the normal background color. -diff --git a/dmenu.c b/dmenu.c -index 4ea95f8..b4549ef 100644 ---- a/dmenu.c -+++ b/dmenu.c -@@ -17,6 +17,7 @@ - * MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org))) - #define MIN(a,b) ((a) < (b) ? (a) : (b)) - #define MAX(a,b) ((a) > (b) ? (a) : (b)) -+#define DEFFONT "monospace-9" /* xft example: "Monospace-11" */ - - typedef struct Item Item; - struct Item { -@@ -26,6 +27,7 @@ struct Item { - - static void appenditem(Item *item, Item **list, Item **last); - static void calcoffsets(void); -+static void cleanup(void); - static char *cistrstr(const char *s, const char *sub); - static void drawmenu(void); - static void grabkeyboard(void); -@@ -50,10 +52,12 @@ static const char *normfgcolor = "#bbbbbb"; - static const char *selbgcolor = "#005577"; - static const char *selfgcolor = "#eeeeee"; - static unsigned int lines = 0; --static unsigned long normcol[ColLast]; --static unsigned long selcol[ColLast]; -+static ColorSet *normcol; -+static ColorSet *selcol; - static Atom clip, utf8; - static Bool topbar = True; -+static Bool running = True; -+static int ret = 0; - static DC *dc; - static Item *items = NULL; - static Item *matches, *matchend; -@@ -104,7 +108,9 @@ main(int argc, char *argv[]) { - usage(); - - dc = initdc(); -- initfont(dc, font); -+ initfont(dc, font ? font : DEFFONT); -+ normcol = initcolor(dc, normfgcolor, normbgcolor); -+ selcol = initcolor(dc, selfgcolor, selbgcolor); - - if(fast) { - grabkeyboard(); -@@ -117,7 +123,8 @@ main(int argc, char *argv[]) { - setup(); - run(); - -- return 1; /* unreachable */ -+ cleanup(); -+ return ret; - } - - void -@@ -160,6 +167,15 @@ cistrstr(const char *s, const char *sub) { - } - - void -+cleanup(void) { -+ freecol(dc, normcol); -+ freecol(dc, selcol); -+ XDestroyWindow(dc->dpy, win); -+ XUngrabKeyboard(dc->dpy, CurrentTime); -+ freedc(dc); -+} -+ -+void - drawmenu(void) { - int curpos; - Item *item; -@@ -167,7 +183,7 @@ drawmenu(void) { - dc->x = 0; - dc->y = 0; - dc->h = bh; -- drawrect(dc, 0, 0, mw, mh, True, BG(dc, normcol)); -+ drawrect(dc, 0, 0, mw, mh, True, normcol->BG); - - if(prompt) { - dc->w = promptw; -@@ -177,8 +193,9 @@ drawmenu(void) { - /* draw input field */ - dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw; - drawtext(dc, text, normcol); -+ dc->x += 2; - if((curpos = textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w) -- drawrect(dc, curpos, 2, 1, dc->h - 4, True, FG(dc, normcol)); -+ drawrect(dc, curpos, 2, 1, dc->h - 4, True, normcol->FG); - - if(lines > 0) { - /* draw vertical list */ -@@ -321,7 +338,8 @@ keypress(XKeyEvent *ev) { - sel = matchend; - break; - case XK_Escape: -- exit(EXIT_FAILURE); -+ ret = EXIT_FAILURE; -+ running = False; - case XK_Home: - if(sel == matches) { - cursor = 0; -@@ -359,7 +377,8 @@ keypress(XKeyEvent *ev) { - case XK_Return: - case XK_KP_Enter: - puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); -- exit(EXIT_SUCCESS); -+ ret = EXIT_SUCCESS; -+ running = False; - case XK_Right: - if(text[cursor] != '\0') { - cursor = nextrune(+1); -@@ -490,7 +509,7 @@ void - run(void) { - XEvent ev; - -- while(!XNextEvent(dc->dpy, &ev)) { -+ while(running && !XNextEvent(dc->dpy, &ev)) { - if(XFilterEvent(&ev, win)) - continue; - switch(ev.type) { -@@ -524,11 +543,6 @@ setup(void) { - XineramaScreenInfo *info; - #endif - -- normcol[ColBG] = getcolor(dc, normbgcolor); -- normcol[ColFG] = getcolor(dc, normfgcolor); -- selcol[ColBG] = getcolor(dc, selbgcolor); -- selcol[ColFG] = getcolor(dc, selfgcolor); -- - clip = XInternAtom(dc->dpy, "CLIPBOARD", False); - utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False); - -@@ -582,7 +596,7 @@ setup(void) { - - /* create menu window */ - swa.override_redirect = True; -- swa.background_pixel = normcol[ColBG]; -+ swa.background_pixel = normcol->BG; - swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; - win = XCreateWindow(dc->dpy, root, x, y, mw, mh, 0, - DefaultDepth(dc->dpy, screen), CopyFromParent, -diff --git a/draw.c b/draw.c -index 76f0c54..81b991c 100644 ---- a/draw.c -+++ b/draw.c -@@ -9,9 +9,6 @@ - - #define MAX(a, b) ((a) > (b) ? (a) : (b)) - #define MIN(a, b) ((a) < (b) ? (a) : (b)) --#define DEFAULTFN "fixed" -- --static Bool loadfont(DC *dc, const char *fontstr); - - void - drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color) { -@@ -23,7 +20,7 @@ drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsign - } - - void --drawtext(DC *dc, const char *text, unsigned long col[ColLast]) { -+drawtext(DC *dc, const char *text, ColorSet *col) { - char buf[BUFSIZ]; - size_t mn, n = strlen(text); - -@@ -35,19 +32,24 @@ drawtext(DC *dc, const char *text, unsigned long col[ColLast]) { - if(mn < n) - for(n = MAX(mn-3, 0); n < mn; buf[n++] = '.'); - -- drawrect(dc, 0, 0, dc->w, dc->h, True, BG(dc, col)); -+ drawrect(dc, 0, 0, dc->w, dc->h, True, col->BG); - drawtextn(dc, buf, mn, col); - } - - void --drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]) { -+drawtextn(DC *dc, const char *text, size_t n, ColorSet *col) { - int x = dc->x + dc->font.height/2; - int y = dc->y + dc->font.ascent+1; - -- XSetForeground(dc->dpy, dc->gc, FG(dc, col)); -- if(dc->font.set) -+ XSetForeground(dc->dpy, dc->gc, col->FG); -+ if(dc->font.xft_font) { -+ if (!dc->xftdraw) -+ eprintf("error, xft drawable does not exist"); -+ XftDrawStringUtf8(dc->xftdraw, &col->FG_xft, -+ dc->font.xft_font, x, y, (unsigned char*)text, n); -+ } else if(dc->font.set) { - XmbDrawString(dc->dpy, dc->canvas, dc->font.set, dc->gc, x, y, text, n); -- else { -+ } else { - XSetFont(dc->dpy, dc->gc, dc->font.xfont->fid); - XDrawString(dc->dpy, dc->canvas, dc->gc, x, y, text, n); - } -@@ -69,16 +71,33 @@ eprintf(const char *fmt, ...) { - } - - void -+freecol(DC *dc, ColorSet *col) { -+ if(col) { -+ if(&col->FG_xft) -+ XftColorFree(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)), -+ DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), &col->FG_xft); -+ free(col); -+ } -+} -+ -+void - freedc(DC *dc) { -+ if(dc->font.xft_font) { -+ XftFontClose(dc->dpy, dc->font.xft_font); -+ XftDrawDestroy(dc->xftdraw); -+ } - if(dc->font.set) - XFreeFontSet(dc->dpy, dc->font.set); -- if(dc->font.xfont) -+ if(dc->font.xfont) - XFreeFont(dc->dpy, dc->font.xfont); -- if(dc->canvas) -+ if(dc->canvas) - XFreePixmap(dc->dpy, dc->canvas); -- XFreeGC(dc->dpy, dc->gc); -- XCloseDisplay(dc->dpy); -- free(dc); -+ if(dc->gc) -+ XFreeGC(dc->dpy, dc->gc); -+ if(dc->dpy) -+ XCloseDisplay(dc->dpy); -+ if(dc) -+ free(dc); - } - - unsigned long -@@ -91,6 +110,20 @@ getcolor(DC *dc, const char *colstr) { - return color.pixel; - } - -+ColorSet * -+initcolor(DC *dc, const char * foreground, const char * background) { -+ ColorSet * col = (ColorSet *)malloc(sizeof(ColorSet)); -+ if(!col) -+ eprintf("error, cannot allocate memory for color set"); -+ col->BG = getcolor(dc, background); -+ col->FG = getcolor(dc, foreground); -+ if(dc->font.xft_font) -+ if(!XftColorAllocName(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)), -+ DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), foreground, &col->FG_xft)) -+ eprintf("error, cannot allocate xft font color '%s'\n", foreground); -+ return col; -+} -+ - DC * - initdc(void) { - DC *dc; -@@ -109,39 +142,33 @@ initdc(void) { - - void - initfont(DC *dc, const char *fontstr) { -- if(!loadfont(dc, fontstr ? fontstr : DEFAULTFN)) { -- if(fontstr != NULL) -- fprintf(stderr, "cannot load font '%s'\n", fontstr); -- if(fontstr == NULL || !loadfont(dc, DEFAULTFN)) -- eprintf("cannot load font '%s'\n", DEFAULTFN); -- } -- dc->font.height = dc->font.ascent + dc->font.descent; --} -- --Bool --loadfont(DC *dc, const char *fontstr) { - char *def, **missing, **names; - int i, n; - XFontStruct **xfonts; - -- if(!*fontstr) -- return False; -- if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) { -+ missing = NULL; -+ if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) { -+ dc->font.ascent = dc->font.xfont->ascent; -+ dc->font.descent = dc->font.xfont->descent; -+ dc->font.width = dc->font.xfont->max_bounds.width; -+ } else if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) { - n = XFontsOfFontSet(dc->font.set, &xfonts, &names); - for(i = 0; i < n; i++) { - dc->font.ascent = MAX(dc->font.ascent, xfonts[i]->ascent); - dc->font.descent = MAX(dc->font.descent, xfonts[i]->descent); - dc->font.width = MAX(dc->font.width, xfonts[i]->max_bounds.width); - } -- } -- else if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) { -- dc->font.ascent = dc->font.xfont->ascent; -- dc->font.descent = dc->font.xfont->descent; -- dc->font.width = dc->font.xfont->max_bounds.width; -+ } else if((dc->font.xft_font = XftFontOpenName(dc->dpy, DefaultScreen(dc->dpy), fontstr))) { -+ dc->font.ascent = dc->font.xft_font->ascent; -+ dc->font.descent = dc->font.xft_font->descent; -+ dc->font.width = dc->font.xft_font->max_advance_width; -+ } else { -+ eprintf("cannot load font '%s'\n", fontstr); - } - if(missing) - XFreeStringList(missing); -- return dc->font.set || dc->font.xfont; -+ dc->font.height = dc->font.ascent + dc->font.descent; -+ return; - } - - void -@@ -151,20 +178,29 @@ mapdc(DC *dc, Window win, unsigned int w, unsigned int h) { - - void - resizedc(DC *dc, unsigned int w, unsigned int h) { -+ int screen = DefaultScreen(dc->dpy); - if(dc->canvas) - XFreePixmap(dc->dpy, dc->canvas); - - dc->w = w; - dc->h = h; - dc->canvas = XCreatePixmap(dc->dpy, DefaultRootWindow(dc->dpy), w, h, -- DefaultDepth(dc->dpy, DefaultScreen(dc->dpy))); -+ DefaultDepth(dc->dpy, screen)); -+ if(dc->font.xft_font && !(dc->xftdraw)) { -+ dc->xftdraw = XftDrawCreate(dc->dpy, dc->canvas, DefaultVisual(dc->dpy,screen), DefaultColormap(dc->dpy,screen)); -+ if(!(dc->xftdraw)) -+ eprintf("error, cannot create xft drawable\n"); -+ } - } - - int - textnw(DC *dc, const char *text, size_t len) { -- if(dc->font.set) { -+ if(dc->font.xft_font) { -+ XGlyphInfo gi; -+ XftTextExtentsUtf8(dc->dpy, dc->font.xft_font, (const FcChar8*)text, len, &gi); -+ return gi.xOff; -+ } else if(dc->font.set) { - XRectangle r; -- - XmbTextExtents(dc->font.set, text, len, NULL, &r); - return r.width; - } -diff --git a/draw.h b/draw.h -index 43a57bf..1b4f21a 100644 ---- a/draw.h -+++ b/draw.h -@@ -1,9 +1,6 @@ - /* See LICENSE file for copyright and license details. */ - --#define FG(dc, col) ((col)[(dc)->invert ? ColBG : ColFG]) --#define BG(dc, col) ((col)[(dc)->invert ? ColFG : ColBG]) -- --enum { ColBG, ColFG, ColBorder, ColLast }; -+#include <X11/Xft/Xft.h> - - typedef struct { - int x, y, w, h; -@@ -11,6 +8,7 @@ typedef struct { - Display *dpy; - GC gc; - Pixmap canvas; -+ XftDraw *xftdraw; - struct { - int ascent; - int descent; -@@ -18,15 +16,24 @@ typedef struct { - int width; - XFontSet set; - XFontStruct *xfont; -+ XftFont *xft_font; - } font; - } DC; /* draw context */ - -+typedef struct { -+ unsigned long FG; -+ XftColor FG_xft; -+ unsigned long BG; -+} ColorSet; -+ - void drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color); --void drawtext(DC *dc, const char *text, unsigned long col[ColLast]); --void drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]); -+void drawtext(DC *dc, const char *text, ColorSet *col); -+void drawtextn(DC *dc, const char *text, size_t n, ColorSet *col); -+void freecol(DC *dc, ColorSet *col); - void eprintf(const char *fmt, ...); - void freedc(DC *dc); - unsigned long getcolor(DC *dc, const char *colstr); -+ColorSet *initcolor(DC *dc, const char *foreground, const char *background); - DC *initdc(void); - void initfont(DC *dc, const char *fontstr); - void mapdc(DC *dc, Window win, unsigned int w, unsigned int h); diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.5-xft.diff b/tools.suckless.org/dmenu/patches/dmenu-4.5-xft.diff @@ -1,418 +0,0 @@ -diff -upr a/config.mk b/config.mk ---- a/config.mk 2012-01-10 19:03:22.000000000 +0200 -+++ b/config.mk 2012-01-10 19:03:38.000000000 +0200 -@@ -12,9 +12,13 @@ X11LIB = /usr/X11R6/lib - XINERAMALIBS = -lXinerama - XINERAMAFLAGS = -DXINERAMA - -+# Xft, comment if you don't want it -+XFTINC = -I/usr/local/include/freetype2 -+XFTLIBS = -lXft -lXrender -lfreetype -lz -lfontconfig -+ - # includes and libs --INCS = -I${X11INC} --LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} -+INCS = -I${X11INC} ${XFTINC} -+LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${XFTLIBS} - - # flags - CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -diff -upr a/dmenu.1 b/dmenu.1 ---- a/dmenu.1 2012-01-10 19:14:19.000000000 +0200 -+++ b/dmenu.1 2012-01-10 19:14:23.000000000 +0200 -@@ -53,7 +53,7 @@ dmenu lists items vertically, with the g - defines the prompt to be displayed to the left of the input field. - .TP - .BI \-fn " font" --defines the font or font set used. -+defines the font or font set used. eg. "fixed" or "Monospace-12:normal" (an xft font) - .TP - .BI \-nb " color" - defines the normal background color. -diff -upr a/dmenu.c b/dmenu.c ---- a/dmenu.c 2012-01-10 19:14:19.000000000 +0200 -+++ b/dmenu.c 2012-01-10 19:24:39.000000000 +0200 -@@ -17,6 +17,7 @@ - * MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org))) - #define MIN(a,b) ((a) < (b) ? (a) : (b)) - #define MAX(a,b) ((a) > (b) ? (a) : (b)) -+#define DEFFONT "fixed" /* xft example: "Monospace-11" */ - - typedef struct Item Item; - struct Item { -@@ -26,6 +27,7 @@ struct Item { - - static void appenditem(Item *item, Item **list, Item **last); - static void calcoffsets(void); -+static void cleanup(void); - static char *cistrstr(const char *s, const char *sub); - static void drawmenu(void); - static void grabkeyboard(void); -@@ -50,10 +52,12 @@ static const char *normfgcolor = "#bbbbb - static const char *selbgcolor = "#005577"; - static const char *selfgcolor = "#eeeeee"; - static unsigned int lines = 0; --static unsigned long normcol[ColLast]; --static unsigned long selcol[ColLast]; -+static ColorSet *normcol; -+static ColorSet *selcol; - static Atom clip, utf8; - static Bool topbar = True; -+static Bool running = True; -+static int ret = 0; - static DC *dc; - static Item *items = NULL; - static Item *matches, *matchend; -@@ -104,7 +108,9 @@ main(int argc, char *argv[]) { - usage(); - - dc = initdc(); -- initfont(dc, font); -+ initfont(dc, font ? font : DEFFONT); -+ normcol = initcolor(dc, normfgcolor, normbgcolor); -+ selcol = initcolor(dc, selfgcolor, selbgcolor); - - if(fast) { - grabkeyboard(); -@@ -117,7 +123,8 @@ main(int argc, char *argv[]) { - setup(); - run(); - -- return 1; /* unreachable */ -+ cleanup(); -+ return ret; - } - - void -@@ -160,6 +167,15 @@ cistrstr(const char *s, const char *sub) - } - - void -+cleanup(void) { -+ freecol(dc, normcol); -+ freecol(dc, selcol); -+ XDestroyWindow(dc->dpy, win); -+ XUngrabKeyboard(dc->dpy, CurrentTime); -+ freedc(dc); -+} -+ -+void - drawmenu(void) { - int curpos; - Item *item; -@@ -167,7 +183,7 @@ drawmenu(void) { - dc->x = 0; - dc->y = 0; - dc->h = bh; -- drawrect(dc, 0, 0, mw, mh, True, BG(dc, normcol)); -+ drawrect(dc, 0, 0, mw, mh, True, normcol->BG); - - if(prompt) { - dc->w = promptw; -@@ -178,7 +194,7 @@ drawmenu(void) { - dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw; - drawtext(dc, text, normcol); - if((curpos = textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w) -- drawrect(dc, curpos, 2, 1, dc->h - 4, True, FG(dc, normcol)); -+ drawrect(dc, curpos, 2, 1, dc->h - 4, True, normcol->FG); - - if(lines > 0) { - /* draw vertical list */ -@@ -321,7 +337,8 @@ keypress(XKeyEvent *ev) { - sel = matchend; - break; - case XK_Escape: -- exit(EXIT_FAILURE); -+ ret = EXIT_FAILURE; -+ running = False; - case XK_Home: - if(sel == matches) { - cursor = 0; -@@ -359,7 +376,8 @@ keypress(XKeyEvent *ev) { - case XK_Return: - case XK_KP_Enter: - puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); -- exit(EXIT_SUCCESS); -+ ret = EXIT_SUCCESS; -+ running = False; - case XK_Right: - if(text[cursor] != '\0') { - cursor = nextrune(+1); -@@ -490,7 +508,7 @@ void - run(void) { - XEvent ev; - -- while(!XNextEvent(dc->dpy, &ev)) { -+ while(running && !XNextEvent(dc->dpy, &ev)) { - if(XFilterEvent(&ev, win)) - continue; - switch(ev.type) { -@@ -524,11 +542,6 @@ setup(void) { - XineramaScreenInfo *info; - #endif - -- normcol[ColBG] = getcolor(dc, normbgcolor); -- normcol[ColFG] = getcolor(dc, normfgcolor); -- selcol[ColBG] = getcolor(dc, selbgcolor); -- selcol[ColFG] = getcolor(dc, selfgcolor); -- - clip = XInternAtom(dc->dpy, "CLIPBOARD", False); - utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False); - -@@ -582,7 +595,7 @@ setup(void) { - - /* create menu window */ - swa.override_redirect = True; -- swa.background_pixel = normcol[ColBG]; -+ swa.background_pixel = normcol->BG; - swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; - win = XCreateWindow(dc->dpy, root, x, y, mw, mh, 0, - DefaultDepth(dc->dpy, screen), CopyFromParent, -diff -upr a/draw.c b/draw.c ---- a/draw.c 2012-01-10 19:14:19.000000000 +0200 -+++ b/draw.c 2012-01-10 19:14:23.000000000 +0200 -@@ -9,9 +9,6 @@ - - #define MAX(a, b) ((a) > (b) ? (a) : (b)) - #define MIN(a, b) ((a) < (b) ? (a) : (b)) --#define DEFAULTFN "fixed" -- --static Bool loadfont(DC *dc, const char *fontstr); - - void - drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color) { -@@ -23,7 +20,7 @@ drawrect(DC *dc, int x, int y, unsigned - } - - void --drawtext(DC *dc, const char *text, unsigned long col[ColLast]) { -+drawtext(DC *dc, const char *text, ColorSet *col) { - char buf[BUFSIZ]; - size_t mn, n = strlen(text); - -@@ -35,19 +32,24 @@ drawtext(DC *dc, const char *text, unsig - if(mn < n) - for(n = MAX(mn-3, 0); n < mn; buf[n++] = '.'); - -- drawrect(dc, 0, 0, dc->w, dc->h, True, BG(dc, col)); -+ drawrect(dc, 0, 0, dc->w, dc->h, True, col->BG); - drawtextn(dc, buf, mn, col); - } - - void --drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]) { -+drawtextn(DC *dc, const char *text, size_t n, ColorSet *col) { - int x = dc->x + dc->font.height/2; - int y = dc->y + dc->font.ascent+1; - -- XSetForeground(dc->dpy, dc->gc, FG(dc, col)); -- if(dc->font.set) -+ XSetForeground(dc->dpy, dc->gc, col->FG); -+ if(dc->font.xft_font) { -+ if (!dc->xftdraw) -+ eprintf("error, xft drawable does not exist"); -+ XftDrawStringUtf8(dc->xftdraw, &col->FG_xft, -+ dc->font.xft_font, x, y, (unsigned char*)text, n); -+ } else if(dc->font.set) { - XmbDrawString(dc->dpy, dc->canvas, dc->font.set, dc->gc, x, y, text, n); -- else { -+ } else { - XSetFont(dc->dpy, dc->gc, dc->font.xfont->fid); - XDrawString(dc->dpy, dc->canvas, dc->gc, x, y, text, n); - } -@@ -69,16 +71,33 @@ eprintf(const char *fmt, ...) { - } - - void -+freecol(DC *dc, ColorSet *col) { -+ if(col) { -+ if(&col->FG_xft) -+ XftColorFree(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)), -+ DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), &col->FG_xft); -+ free(col); -+ } -+} -+ -+void - freedc(DC *dc) { -+ if(dc->font.xft_font) { -+ XftFontClose(dc->dpy, dc->font.xft_font); -+ XftDrawDestroy(dc->xftdraw); -+ } - if(dc->font.set) - XFreeFontSet(dc->dpy, dc->font.set); -- if(dc->font.xfont) -+ if(dc->font.xfont) - XFreeFont(dc->dpy, dc->font.xfont); -- if(dc->canvas) -+ if(dc->canvas) - XFreePixmap(dc->dpy, dc->canvas); -- XFreeGC(dc->dpy, dc->gc); -- XCloseDisplay(dc->dpy); -- free(dc); -+ if(dc->gc) -+ XFreeGC(dc->dpy, dc->gc); -+ if(dc->dpy) -+ XCloseDisplay(dc->dpy); -+ if(dc) -+ free(dc); - } - - unsigned long -@@ -91,6 +110,20 @@ getcolor(DC *dc, const char *colstr) { - return color.pixel; - } - -+ColorSet * -+initcolor(DC *dc, const char * foreground, const char * background) { -+ ColorSet * col = (ColorSet *)malloc(sizeof(ColorSet)); -+ if(!col) -+ eprintf("error, cannot allocate memory for color set"); -+ col->BG = getcolor(dc, background); -+ col->FG = getcolor(dc, foreground); -+ if(dc->font.xft_font) -+ if(!XftColorAllocName(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)), -+ DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), foreground, &col->FG_xft)) -+ eprintf("error, cannot allocate xft font color '%s'\n", foreground); -+ return col; -+} -+ - DC * - initdc(void) { - DC *dc; -@@ -109,39 +142,33 @@ initdc(void) { - - void - initfont(DC *dc, const char *fontstr) { -- if(!loadfont(dc, fontstr ? fontstr : DEFAULTFN)) { -- if(fontstr != NULL) -- fprintf(stderr, "cannot load font '%s'\n", fontstr); -- if(fontstr == NULL || !loadfont(dc, DEFAULTFN)) -- eprintf("cannot load font '%s'\n", DEFAULTFN); -- } -- dc->font.height = dc->font.ascent + dc->font.descent; --} -- --Bool --loadfont(DC *dc, const char *fontstr) { - char *def, **missing, **names; - int i, n; - XFontStruct **xfonts; - -- if(!*fontstr) -- return False; -- if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) { -+ missing = NULL; -+ if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) { -+ dc->font.ascent = dc->font.xfont->ascent; -+ dc->font.descent = dc->font.xfont->descent; -+ dc->font.width = dc->font.xfont->max_bounds.width; -+ } else if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) { - n = XFontsOfFontSet(dc->font.set, &xfonts, &names); - for(i = 0; i < n; i++) { - dc->font.ascent = MAX(dc->font.ascent, xfonts[i]->ascent); - dc->font.descent = MAX(dc->font.descent, xfonts[i]->descent); - dc->font.width = MAX(dc->font.width, xfonts[i]->max_bounds.width); - } -- } -- else if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) { -- dc->font.ascent = dc->font.xfont->ascent; -- dc->font.descent = dc->font.xfont->descent; -- dc->font.width = dc->font.xfont->max_bounds.width; -+ } else if((dc->font.xft_font = XftFontOpenName(dc->dpy, DefaultScreen(dc->dpy), fontstr))) { -+ dc->font.ascent = dc->font.xft_font->ascent; -+ dc->font.descent = dc->font.xft_font->descent; -+ dc->font.width = dc->font.xft_font->max_advance_width; -+ } else { -+ eprintf("cannot load font '%s'\n", fontstr); - } - if(missing) - XFreeStringList(missing); -- return dc->font.set || dc->font.xfont; -+ dc->font.height = dc->font.ascent + dc->font.descent; -+ return; - } - - void -@@ -151,20 +178,29 @@ mapdc(DC *dc, Window win, unsigned int w - - void - resizedc(DC *dc, unsigned int w, unsigned int h) { -+ int screen = DefaultScreen(dc->dpy); - if(dc->canvas) - XFreePixmap(dc->dpy, dc->canvas); - - dc->w = w; - dc->h = h; - dc->canvas = XCreatePixmap(dc->dpy, DefaultRootWindow(dc->dpy), w, h, -- DefaultDepth(dc->dpy, DefaultScreen(dc->dpy))); -+ DefaultDepth(dc->dpy, screen)); -+ if(dc->font.xft_font && !(dc->xftdraw)) { -+ dc->xftdraw = XftDrawCreate(dc->dpy, dc->canvas, DefaultVisual(dc->dpy,screen), DefaultColormap(dc->dpy,screen)); -+ if(!(dc->xftdraw)) -+ eprintf("error, cannot create xft drawable\n"); -+ } - } - - int - textnw(DC *dc, const char *text, size_t len) { -- if(dc->font.set) { -+ if(dc->font.xft_font) { -+ XGlyphInfo gi; -+ XftTextExtentsUtf8(dc->dpy, dc->font.xft_font, (const FcChar8*)text, len, &gi); -+ return gi.width; -+ } else if(dc->font.set) { - XRectangle r; -- - XmbTextExtents(dc->font.set, text, len, NULL, &r); - return r.width; - } -diff -upr a/draw.h b/draw.h ---- a/draw.h 2012-01-10 19:14:19.000000000 +0200 -+++ b/draw.h 2012-01-10 19:14:23.000000000 +0200 -@@ -1,9 +1,6 @@ - /* See LICENSE file for copyright and license details. */ - --#define FG(dc, col) ((col)[(dc)->invert ? ColBG : ColFG]) --#define BG(dc, col) ((col)[(dc)->invert ? ColFG : ColBG]) -- --enum { ColBG, ColFG, ColBorder, ColLast }; -+#include <X11/Xft/Xft.h> - - typedef struct { - int x, y, w, h; -@@ -11,6 +8,7 @@ typedef struct { - Display *dpy; - GC gc; - Pixmap canvas; -+ XftDraw *xftdraw; - struct { - int ascent; - int descent; -@@ -18,15 +16,24 @@ typedef struct { - int width; - XFontSet set; - XFontStruct *xfont; -+ XftFont *xft_font; - } font; - } DC; /* draw context */ - -+typedef struct { -+ unsigned long FG; -+ XftColor FG_xft; -+ unsigned long BG; -+} ColorSet; -+ - void drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color); --void drawtext(DC *dc, const char *text, unsigned long col[ColLast]); --void drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]); -+void drawtext(DC *dc, const char *text, ColorSet *col); -+void drawtextn(DC *dc, const char *text, size_t n, ColorSet *col); -+void freecol(DC *dc, ColorSet *col); - void eprintf(const char *fmt, ...); - void freedc(DC *dc); - unsigned long getcolor(DC *dc, const char *colstr); -+ColorSet *initcolor(DC *dc, const char *foreground, const char *background); - DC *initdc(void); - void initfont(DC *dc, const char *fontstr); - void mapdc(DC *dc, Window win, unsigned int w, unsigned int h); diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.6-line-height.diff b/tools.suckless.org/dmenu/patches/dmenu-4.6-line-height.diff @@ -1,99 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index a9122f7..6d936b7 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -15,3 +15,6 @@ static const char *outbgcolor = "#00ffff"; - static const char *outfgcolor = "#000000"; - /* -l option; if nonzero, dmenu uses vertical list with given number of lines */ - static unsigned int lines = 0; -+ -+static unsigned int lineheight = 0; /* -lh option; minimum height of a menu line */ -+ -diff --git a/dmenu.1 b/dmenu.1 -index d3ab805..9fe4434 100644 ---- a/dmenu.1 -+++ b/dmenu.1 -@@ -51,6 +51,9 @@ dmenu matches menu items case insensitively. - .BI \-l " lines" - dmenu lists items vertically, with the given number of lines. - .TP -+.BI \-lh " height" -+dmenu uses a menu line of at least 'height' pixels tall, but no less than 8. -+.TP - .BI \-m " monitor" - dmenu is displayed on the monitor number supplied. Monitor numbers are starting - from 0. -diff --git a/dmenu.c b/dmenu.c -index a07f8e3..25832a7 100644 ---- a/dmenu.c -+++ b/dmenu.c -@@ -119,7 +119,7 @@ drawmenu(void) - { - int curpos; - struct item *item; -- int x = 0, y = 0, h = bh, w; -+ int x = 0, y = 0, fh = drw->fonts[0]->h, w; - - drw_setscheme(drw, &scheme[SchemeNorm]); - drw_rect(drw, 0, 0, mw, mh, 1, 1, 1); -@@ -134,16 +134,16 @@ drawmenu(void) - drw_setscheme(drw, &scheme[SchemeNorm]); - drw_text(drw, x, 0, w, bh, text, 0); - -- if ((curpos = TEXTNW(text, cursor) + bh / 2 - 2) < w) { -+ if ((curpos = TEXTNW(text, cursor) + fh / 2 - 2) < w) { - drw_setscheme(drw, &scheme[SchemeNorm]); -- drw_rect(drw, x + curpos + 2, 2, 1, bh - 4, 1, 1, 0); -+ drw_rect(drw, x + curpos + 2, 2 + (bh-fh)/2, 1, fh - 4, 1, 1, 0); - } - - if (lines > 0) { - /* draw vertical list */ - w = mw - x; - for (item = curr; item != next; item = item->right) { -- y += h; -+ y += bh; - if (item == sel) - drw_setscheme(drw, &scheme[SchemeSel]); - else if (item->out) -@@ -544,6 +544,7 @@ setup(void) - - /* calculate menu geometry */ - bh = drw->fonts[0]->h + 2; -+ bh = MAX(bh,lineheight); /* make a menu line AT LEAST 'lineheight' tall */ - lines = MAX(lines, 0); - mh = (lines + 1) * bh; - #ifdef XINERAMA -@@ -608,7 +609,7 @@ setup(void) - static void - usage(void) - { -- fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" -+ fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font] [-lh height] [-m monitor]\n" - " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); - exit(1); - } -@@ -641,6 +642,10 @@ main(int argc, char *argv[]) - prompt = argv[++i]; - else if (!strcmp(argv[i], "-fn")) /* font or font set */ - fonts[0] = argv[++i]; -+ else if(!strcmp(argv[i], "-lh")) { /* minimum height of one menu line */ -+ lineheight = atoi(argv[++i]); -+ lineheight = MAX(lineheight,8); /* reasonable default in case of value too small/negative */ -+ } - else if (!strcmp(argv[i], "-nb")) /* normal background color */ - normbgcolor = argv[++i]; - else if (!strcmp(argv[i], "-nf")) /* normal foreground color */ -diff --git a/drw.c b/drw.c -index 80e3c39..f4a741f 100644 ---- a/drw.c -+++ b/drw.c -@@ -291,7 +291,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex - if (render) { - th = curfont->ascent + curfont->descent; - ty = y + (h / 2) - (th / 2) + curfont->ascent; -- tx = x + (h / 2); -+ tx = x + (drw->fonts[0]->h / 2); - XftDrawStringUtf8(d, invert ? &drw->scheme->bg->rgb : &drw->scheme->fg->rgb, curfont->xfont, tx, ty, (XftChar8 *)buf, len); - } - x += tex.w; diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.6-mouse-support-msel.diff b/tools.suckless.org/dmenu/patches/dmenu-4.6-mouse-support-msel.diff @@ -1,154 +0,0 @@ -diff --git a/dmenu.c b/dmenu.c -index a07f8e3..1de62c1 100644 ---- a/dmenu.c -+++ b/dmenu.c -@@ -277,6 +277,129 @@ nextrune(int inc) - return n; - } - -+void -+buttonpress(XEvent *e) -+{ -+ struct item *item; -+ XButtonPressedEvent *ev = &e->xbutton; -+ int xpos, ypos, wpos, hpos; -+ -+ if(ev->window != win) -+ return; -+ -+ /* right-click: exit */ -+ if(ev->button == Button3) -+ exit(EXIT_FAILURE); -+ -+ xpos = 0; -+ ypos = 0; -+ hpos = bh; -+ -+ if(prompt && *prompt) { -+ wpos = promptw; -+ xpos = wpos; -+ } -+ /* input field */ -+ wpos = (lines > 0 || !matches) ? mw - xpos : 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(ev->button == Button1 && -+ ((lines <= 0 && ev->x >= 0 && ev->x <= xpos + wpos + -+ ((!prev || !curr->left) ? TEXTW("<") : 0)) || -+ (lines > 0 && ev->y >= ypos && ev->y <= ypos + hpos))) { -+ insert(NULL, 0 - cursor); -+ drawmenu(); -+ return; -+ } -+ /* 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) { -+ /* vertical list: (ctrl-)left-click on item */ -+ wpos = mw - xpos; -+ for(item = curr; item != next; item = item->right) { -+ ypos += hpos; -+ if(ev->y >= ypos && ev->y <= (ypos + hpos)) { -+ puts(item->text); -+ sel=item; -+ if (!(ev->state & ControlMask)) { -+ cleanup(); -+ exit(EXIT_SUCCESS); -+ } -+ if (sel) { -+ sel->out = 1; -+ drawmenu(); -+ } -+ return; -+ } -+ } -+ } -+ else if(matches) { -+ /* left-click on left arrow */ -+ xpos += inputw; -+ wpos = TEXTW("<"); -+ if(prev && curr->left) { -+ if(ev->x >= xpos && ev->x <= xpos + wpos) { -+ sel = curr = prev; -+ calcoffsets(); -+ drawmenu(); -+ return; -+ } -+ } -+ /* horizontal list: (ctrl-)left-click on item */ -+ for(item = curr; item != next; item = item->right) { -+ xpos += wpos; -+ wpos = MIN(TEXTW(item->text), mw - xpos - TEXTW(">")); -+ if(ev->x >= xpos && ev->x <= (xpos + wpos)) { -+ puts(item->text); -+ sel=item; -+ if (!(ev->state & ControlMask)) { -+ cleanup(); -+ exit(EXIT_SUCCESS); -+ } -+ if (sel) { -+ sel->out = 1; -+ drawmenu(); -+ } -+ return; -+ } -+ } -+ /* left-click on right arrow */ -+ wpos = TEXTW(">"); -+ xpos = mw - wpos; -+ if(next && ev->x >= xpos && ev->x <= xpos + wpos) { -+ sel = curr = next; -+ calcoffsets(); -+ drawmenu(); -+ return; -+ } -+ } -+} -+ - static void - keypress(XKeyEvent *ev) - { -@@ -502,6 +625,9 @@ run(void) - if (ev.xexpose.count == 0) - drw_map(drw, win, 0, 0, mw, mh); - break; -+ case ButtonPress: -+ buttonpress(&ev); -+ break; - case KeyPress: - keypress(&ev.xkey); - break; -@@ -589,7 +715,8 @@ setup(void) - /* create menu window */ - swa.override_redirect = True; - swa.background_pixel = scheme[SchemeNorm].bg->pix; -- swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; -+ swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask | -+ ButtonPressMask; - win = XCreateWindow(dpy, root, x, y, mw, mh, 0, - DefaultDepth(dpy, screen), CopyFromParent, - DefaultVisual(dpy, screen), diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.6-vertfull.diff b/tools.suckless.org/dmenu/patches/dmenu-4.6-vertfull.diff @@ -1,20 +0,0 @@ -diff -wu a/dmenu.c b/dmenu.c ---- a/dmenu.c 2015-11-08 23:42:21.000000000 +0100 -+++ b/dmenu.c 2015-11-10 18:13:43.937450512 +0100 -@@ -141,7 +141,6 @@ - - if (lines > 0) { - /* draw vertical list */ -- w = mw - x; - for (item = curr; item != next; item = item->right) { - y += h; - if (item == sel) -@@ -151,7 +150,7 @@ - else - drw_setscheme(drw, &scheme[SchemeNorm]); - -- drw_text(drw, x, y, w, bh, item->text, 0); -+ drw_text(drw, 0, y, mw, bh, item->text, 0); - } - } else if (matches) { - /* draw horizontal list */ diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.6-xyw.diff b/tools.suckless.org/dmenu/patches/dmenu-4.6-xyw.diff @@ -1,87 +0,0 @@ -diff --git a/dmenu.1 b/dmenu.1 -index d3ab805..5301910 100644 ---- a/dmenu.1 -+++ b/dmenu.1 -@@ -51,6 +51,24 @@ dmenu matches menu items case insensitively. - .BI \-l " lines" - dmenu lists items vertically, with the given number of lines. - .TP -+.BI \-x " xoffset" -+dmenu is placed at this offset measured from the left side of the monitor. -+Can be negative. -+If option -+.B \-m -+is present, the measurement will use the given monitor. -+.TP -+.BI \-y " yoffset" -+dmenu is placed at this offset measured from the top of the monitor. If the -+.B \-b -+option is used, the offset is measured from the bottom. Can be negative. -+If option -+.B \-m -+is present, the measurement will use the given monitor. -+.TP -+.BI \-w " width" -+sets the width of the dmenu window. -+.TP - .BI \-m " monitor" - dmenu is displayed on the monitor number supplied. Monitor numbers are starting - from 0. -diff --git a/dmenu.c b/dmenu.c -index a07f8e3..9e0c51c 100644 ---- a/dmenu.c -+++ b/dmenu.c -@@ -37,6 +37,9 @@ struct item { - static char text[BUFSIZ] = ""; - static int bh, mw, mh; - static int sw, sh; /* X display screen geometry width, height */ -+static int dmx = 0; /* put dmenu at this x offset */ -+static int dmy = 0; /* put dmenu at this y offset (measured from the bottom if topbar is 0) */ -+static unsigned int dmw = 0; /* make dmenu this wide */ - static int inputw, promptw; - static size_t cursor; - static struct item *items = NULL; -@@ -571,16 +574,16 @@ setup(void) - if (INTERSECT(x, y, 1, 1, info[i])) - break; - -- x = info[i].x_org; -- y = info[i].y_org + (topbar ? 0 : info[i].height - mh); -- mw = info[i].width; -+ 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); - XFree(info); - } else - #endif - { -- x = 0; -- y = topbar ? 0 : sh - mh; -- mw = sw; -+ x = dmx; -+ y = topbar ? dmy : sh - mh - dmy; -+ mw = (dmw>0 ? dmw : sw); - } - promptw = (prompt && *prompt) ? TEXTW(prompt) : 0; - inputw = MIN(inputw, mw/3); -@@ -609,6 +612,7 @@ static void - usage(void) - { - fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" -+ " [-x xoffset] [-y yoffset] [-w width]\n" - " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); - exit(1); - } -@@ -635,6 +639,12 @@ main(int argc, char *argv[]) - /* these options take one argument */ - else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */ - lines = atoi(argv[++i]); -+ 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]); - else if (!strcmp(argv[i], "-m")) - mon = atoi(argv[++i]); - else if (!strcmp(argv[i], "-p")) /* adds prompt to left of input field */ diff --git a/tools.suckless.org/dmenu/patches/dmenu-fuzzymatch-4.6.diff b/tools.suckless.org/dmenu/patches/dmenu-fuzzymatch-4.6.diff @@ -0,0 +1,145 @@ +From f5caf807c884f92e6f07ad8b461334343287eca3 Mon Sep 17 00:00:00 2001 +From: Hiltjo Posthuma <hiltjo@codemadness.org> +Date: Fri, 17 Jun 2016 15:09:30 +0200 +Subject: [PATCH] fuzzy match, fix off-by-one in previous patch. + +--- + dmenu.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 83 insertions(+), 4 deletions(-) + +diff --git a/dmenu.c b/dmenu.c +index e0c2f80..b4a6f70 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -32,6 +32,7 @@ struct item { + char *text; + struct item *left, *right; + int out; ++ int distance; + }; + + static char text[BUFSIZ] = ""; +@@ -253,6 +254,84 @@ match(void) + calcoffsets(); + } + ++static int ++compare_distance(const void *a, const void *b) ++{ ++ struct item const *da = *(struct item **) a; ++ struct item const *db = *(struct item **) b; ++ ++ if (!db) ++ return 1; ++ if (!da) ++ return -1; ++ return da->distance - db->distance; ++} ++ ++static void ++fuzzymatch(void) ++{ ++ struct item *item; ++ 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 (item = items; item && item->text; item++) { ++ if (text_len) { ++ itext_len = strlen(item->text); ++ pidx = 0; ++ sidx = eidx = -1; ++ /* walk through item text */ ++ for (i = 0; i < itext_len && (c = item->text[i]); i++) { ++ /* fuzzy match pattern */ ++ if (text[pidx] == c) { ++ if (sidx == -1) ++ sidx = i; ++ pidx++; ++ if (pidx == text_len) { ++ eidx = i; ++ break; ++ } ++ } ++ } ++ /* build list of matches */ ++ if (eidx != -1) { ++ /* compute distance */ ++ /* factor in 30% of sidx and distance between eidx and total ++ * text length .. let's see how it works */ ++ item->distance = eidx - sidx + (itext_len - eidx + sidx) / 3; ++ appenditem(item, &matches, &matchend); ++ number_of_matches++; ++ } ++ } ++ else ++ appenditem(item, &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, item = matches; item && i < number_of_matches; i++, item = item->right) ++ fuzzymatches[i] = item; ++ ++ /* 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, item = fuzzymatches[0]; i < number_of_matches && item && \ ++ item->text; item = fuzzymatches[i], i++) ++ appenditem(item, &matches, &matchend); ++ ++ free(fuzzymatches); ++ } ++ curr = sel = matches; ++ calcoffsets(); ++} ++ + static void + insert(const char *str, ssize_t n) + { +@@ -263,7 +342,7 @@ insert(const char *str, ssize_t n) + if (n > 0) + memcpy(&text[cursor], str, n); + cursor += n; +- match(); ++ fuzzymatch(); + } + + static size_t +@@ -308,7 +387,7 @@ keypress(XKeyEvent *ev) + + case XK_k: /* delete right */ + text[cursor] = '\0'; +- match(); ++ fuzzymatch(); + break; + case XK_u: /* delete left */ + insert(NULL, 0 - cursor); +@@ -444,7 +523,7 @@ keypress(XKeyEvent *ev) + strncpy(text, sel->text, sizeof text - 1); + text[sizeof text - 1] = '\0'; + cursor = strlen(text); +- match(); ++ fuzzymatch(); + break; + } + drawmenu(); +@@ -586,7 +665,7 @@ setup(void) + } + promptw = (prompt && *prompt) ? TEXTW(prompt) : 0; + inputw = MIN(inputw, mw/3); +- match(); ++ fuzzymatch(); + + /* create menu window */ + swa.override_redirect = True; +-- +2.8.3 + diff --git a/tools.suckless.org/dmenu/patches/dmenu-git-20151020-fuzzymatch.diff b/tools.suckless.org/dmenu/patches/dmenu-git-20151020-fuzzymatch.diff @@ -1,135 +0,0 @@ -diff --git a/dmenu.c b/dmenu.c -index 4f22ffe..c2fc3ee 100644 ---- a/dmenu.c -+++ b/dmenu.c -@@ -33,6 +33,7 @@ struct item { - char *text; - struct item *left, *right; - bool out; -+ int distance; - }; - - static char text[BUFSIZ] = ""; -@@ -254,6 +255,86 @@ match(void) - calcoffsets(); - } - -+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; -+} -+ -+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; -+ sidx = eidx = -1; -+ /* walk through item text */ -+ for (i = 0; i < itext_len && (c = it->text[i]); i++) { -+ /* fuzzy match pattern */ -+ if (text[pidx] == c) { -+ if(sidx == -1) -+ sidx = i; -+ pidx++; -+ if (pidx == text_len) { -+ eidx = i; -+ break; -+ } -+ } -+ } -+ /* build list of matches */ -+ if (eidx != -1) { -+ /* compute distance */ -+ /* factor in 30% of sidx and distance between eidx and total -+ * text length .. let's see how it works */ -+ it->distance = eidx - sidx + (itext_len - eidx + sidx) / 3; -+ 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 - insert(const char *str, ssize_t n) - { -@@ -264,7 +345,7 @@ insert(const char *str, ssize_t n) - if (n > 0) - memcpy(&text[cursor], str, n); - cursor += n; -- match(); -+ fuzzymatch(); - } - - static size_t -@@ -309,7 +390,7 @@ keypress(XKeyEvent *ev) - - case XK_k: /* delete right */ - text[cursor] = '\0'; -- match(); -+ fuzzymatch(); - break; - case XK_u: /* delete left */ - insert(NULL, 0 - cursor); -@@ -443,7 +524,7 @@ keypress(XKeyEvent *ev) - strncpy(text, sel->text, sizeof text - 1); - text[sizeof text - 1] = '\0'; - cursor = strlen(text); -- match(); -+ fuzzymatch(); - break; - } - drawmenu(); -@@ -585,7 +666,7 @@ setup(void) - } - promptw = (prompt && *prompt) ? TEXTW(prompt) : 0; - inputw = MIN(inputw, mw/3); -- match(); -+ fuzzymatch(); - - /* create menu window */ - swa.override_redirect = True; diff --git a/tools.suckless.org/dmenu/patches/dmenu-git-20160111-hide-single-newline.diff b/tools.suckless.org/dmenu/patches/dmenu-git-20160111-hide-single-newline.diff @@ -1,12 +0,0 @@ -diff --git a/dmenu.c b/dmenu.c -index e0c2f80..ef25442 100644 ---- a/dmenu.c -+++ b/dmenu.c -@@ -487,6 +487,7 @@ readstdin(void) - } - if (items) - items[i].text = NULL; -+ if (i == 1 && items[0].text[0] == '\0') items = realloc(items, 0); - inputw = maxstr ? TEXTW(maxstr) : 0; - lines = MIN(lines, i); - } diff --git a/tools.suckless.org/dmenu/patches/dmenu-git-xft.diff b/tools.suckless.org/dmenu/patches/dmenu-git-xft.diff @@ -1,450 +0,0 @@ -diff --git a/config.mk b/config.mk -index c0d466b..04e2dce 100644 ---- a/config.mk -+++ b/config.mk -@@ -12,9 +12,13 @@ X11LIB = /usr/X11R6/lib - XINERAMALIBS = -lXinerama - XINERAMAFLAGS = -DXINERAMA - -+# Xft, comment if you don't want it -+XFTINC = -I/usr/include/freetype2 -+XFTLIBS = -lXft -lXrender -lfreetype -lz -lfontconfig -+ - # includes and libs --INCS = -I${X11INC} --LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} -+INCS = -I${X11INC} ${XFTINC} -+LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${XFTLIBS} - - # flags - CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -diff --git a/dmenu.1 b/dmenu.1 -index 2897ab1..d06b484 100644 ---- a/dmenu.1 -+++ b/dmenu.1 -@@ -58,7 +58,7 @@ dmenu is displayed on the monitor supplied. - defines the prompt to be displayed to the left of the input field. - .TP - .BI \-fn " font" --defines the font or font set used. -+defines the font or font set used. eg. "fixed" or "Monospace-12:normal" (a xft font) - .TP - .BI \-nb " color" - defines the normal background color. -diff --git a/dmenu.c b/dmenu.c -index 94c70de..cc6dedf 100644 ---- a/dmenu.c -+++ b/dmenu.c -@@ -17,6 +17,7 @@ - * MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org))) - #define MIN(a,b) ((a) < (b) ? (a) : (b)) - #define MAX(a,b) ((a) > (b) ? (a) : (b)) -+#define DEFFONT "fixed" /* xft example: "Monospace-11" */ - - typedef struct Item Item; - struct Item { -@@ -27,6 +28,7 @@ struct Item { - - static void appenditem(Item *item, Item **list, Item **last); - static void calcoffsets(void); -+static void cleanup(void); - static char *cistrstr(const char *s, const char *sub); - static void drawmenu(void); - static void grabkeyboard(void); -@@ -44,9 +46,9 @@ static char text[BUFSIZ] = ""; - static int bh, mw, mh; - static int inputw, promptw; - static size_t cursor = 0; --static unsigned long normcol[ColLast]; --static unsigned long selcol[ColLast]; --static unsigned long outcol[ColLast]; -+static ColorSet *normcol; -+static ColorSet *selcol; -+static ColorSet *outcol; - static Atom clip, utf8; - static DC *dc; - static Item *items = NULL; -@@ -55,6 +57,8 @@ static Item *prev, *curr, *next, *sel; - static Window win; - static XIC xic; - static int mon = -1; -+static Bool running = True; -+static int ret = EXIT_SUCCESS; - - #include "config.h" - -@@ -103,7 +107,10 @@ main(int argc, char *argv[]) { - usage(); - - dc = initdc(); -- initfont(dc, font); -+ initfont(dc, font ? font : DEFFONT); -+ normcol = initcolor(dc, normfgcolor, normbgcolor); -+ selcol = initcolor(dc, selfgcolor, selbgcolor); -+ outcol = initcolor(dc, outfgcolor, outbgcolor); - - if(fast) { - grabkeyboard(); -@@ -116,7 +123,8 @@ main(int argc, char *argv[]) { - setup(); - run(); - -- return 1; /* unreachable */ -+ cleanup(); -+ return ret; - } - - void -@@ -159,6 +167,15 @@ cistrstr(const char *s, const char *sub) { - } - - void -+cleanup(void) { -+ freecol(dc, normcol); -+ freecol(dc, selcol); -+ XDestroyWindow(dc->dpy, win); -+ XUngrabKeyboard(dc->dpy, CurrentTime); -+ freedc(dc); -+} -+ -+void - drawmenu(void) { - int curpos; - Item *item; -@@ -166,7 +183,7 @@ drawmenu(void) { - dc->x = 0; - dc->y = 0; - dc->h = bh; -- drawrect(dc, 0, 0, mw, mh, True, BG(dc, normcol)); -+ drawrect(dc, 0, 0, mw, mh, True, normcol->BG); - - if(prompt && *prompt) { - dc->w = promptw; -@@ -177,7 +194,7 @@ drawmenu(void) { - dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw; - drawtext(dc, text, normcol); - if((curpos = textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w) -- drawrect(dc, curpos, 2, 1, dc->h - 4, True, FG(dc, normcol)); -+ drawrect(dc, curpos, 2, 1, dc->h - 4, True, normcol->FG); - - if(lines > 0) { - /* draw vertical list */ -@@ -281,9 +298,12 @@ keypress(XKeyEvent *ev) { - return; - case XK_Return: - case XK_KP_Enter: -+ ret = EXIT_SUCCESS; -+ running = False; - break; - case XK_bracketleft: -- exit(EXIT_FAILURE); -+ ret = EXIT_FAILURE; -+ running = False; - default: - return; - } -@@ -330,7 +350,8 @@ keypress(XKeyEvent *ev) { - sel = matchend; - break; - case XK_Escape: -- exit(EXIT_FAILURE); -+ ret = EXIT_FAILURE; -+ running = False; - case XK_Home: - if(sel == matches) { - cursor = 0; -@@ -368,8 +389,10 @@ keypress(XKeyEvent *ev) { - case XK_Return: - case XK_KP_Enter: - puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); -- if(!(ev->state & ControlMask)) -- exit(EXIT_SUCCESS); -+ if(!(ev->state & ControlMask)) { -+ ret = EXIT_SUCCESS; -+ running = False; -+ } - if(sel) - sel->out = True; - break; -@@ -505,7 +528,7 @@ void - run(void) { - XEvent ev; - -- while(!XNextEvent(dc->dpy, &ev)) { -+ while(running && !XNextEvent(dc->dpy, &ev)) { - if(XFilterEvent(&ev, win)) - continue; - switch(ev.type) { -@@ -539,13 +562,6 @@ setup(void) { - XineramaScreenInfo *info; - #endif - -- normcol[ColBG] = getcolor(dc, normbgcolor); -- normcol[ColFG] = getcolor(dc, normfgcolor); -- selcol[ColBG] = getcolor(dc, selbgcolor); -- selcol[ColFG] = getcolor(dc, selfgcolor); -- outcol[ColBG] = getcolor(dc, outbgcolor); -- outcol[ColFG] = getcolor(dc, outfgcolor); -- - clip = XInternAtom(dc->dpy, "CLIPBOARD", False); - utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False); - -@@ -601,7 +617,7 @@ setup(void) { - - /* create menu window */ - swa.override_redirect = True; -- swa.background_pixel = normcol[ColBG]; -+ swa.background_pixel = normcol->BG; - swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; - win = XCreateWindow(dc->dpy, root, x, y, mw, mh, 0, - DefaultDepth(dc->dpy, screen), CopyFromParent, -diff --git a/draw.c b/draw.c -index 76f0c54..09e66ea 100644 ---- a/draw.c -+++ b/draw.c -@@ -9,9 +9,6 @@ - - #define MAX(a, b) ((a) > (b) ? (a) : (b)) - #define MIN(a, b) ((a) < (b) ? (a) : (b)) --#define DEFAULTFN "fixed" -- --static Bool loadfont(DC *dc, const char *fontstr); - - void - drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color) { -@@ -23,7 +20,7 @@ drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsign - } - - void --drawtext(DC *dc, const char *text, unsigned long col[ColLast]) { -+drawtext(DC *dc, const char *text, ColorSet *col) { - char buf[BUFSIZ]; - size_t mn, n = strlen(text); - -@@ -35,19 +32,24 @@ drawtext(DC *dc, const char *text, unsigned long col[ColLast]) { - if(mn < n) - for(n = MAX(mn-3, 0); n < mn; buf[n++] = '.'); - -- drawrect(dc, 0, 0, dc->w, dc->h, True, BG(dc, col)); -+ drawrect(dc, 0, 0, dc->w, dc->h, True, col->BG); - drawtextn(dc, buf, mn, col); - } - - void --drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]) { -+drawtextn(DC *dc, const char *text, size_t n, ColorSet *col) { - int x = dc->x + dc->font.height/2; - int y = dc->y + dc->font.ascent+1; - -- XSetForeground(dc->dpy, dc->gc, FG(dc, col)); -- if(dc->font.set) -+ XSetForeground(dc->dpy, dc->gc, col->FG); -+ if(dc->font.xft_font) { -+ if(!dc->xftdraw) -+ eprintf("error, xft drawable does not exist"); -+ XftDrawStringUtf8(dc->xftdraw, &col->FG_xft, -+ dc->font.xft_font, x, y, (unsigned char*)text, n); -+ } else if(dc->font.set) { - XmbDrawString(dc->dpy, dc->canvas, dc->font.set, dc->gc, x, y, text, n); -- else { -+ } else { - XSetFont(dc->dpy, dc->gc, dc->font.xfont->fid); - XDrawString(dc->dpy, dc->canvas, dc->gc, x, y, text, n); - } -@@ -69,16 +71,33 @@ eprintf(const char *fmt, ...) { - } - - void -+freecol(DC *dc, ColorSet *col) { -+ if(col) { -+ if(&col->FG_xft) -+ XftColorFree(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)), -+ DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), &col->FG_xft); -+ free(col); -+ } -+} -+ -+void - freedc(DC *dc) { -+ if(dc->font.xft_font) { -+ XftFontClose(dc->dpy, dc->font.xft_font); -+ XftDrawDestroy(dc->xftdraw); -+ } - if(dc->font.set) - XFreeFontSet(dc->dpy, dc->font.set); - if(dc->font.xfont) - XFreeFont(dc->dpy, dc->font.xfont); - if(dc->canvas) - XFreePixmap(dc->dpy, dc->canvas); -- XFreeGC(dc->dpy, dc->gc); -- XCloseDisplay(dc->dpy); -- free(dc); -+ if(dc->gc) -+ XFreeGC(dc->dpy, dc->gc); -+ if(dc->dpy) -+ XCloseDisplay(dc->dpy); -+ if(dc) -+ free(dc); - } - - unsigned long -@@ -91,6 +110,20 @@ getcolor(DC *dc, const char *colstr) { - return color.pixel; - } - -+ColorSet * -+initcolor(DC *dc, const char * foreground, const char * background) { -+ ColorSet * col = (ColorSet *)malloc(sizeof(ColorSet)); -+ if(!col) -+ eprintf("error, cannot allocate memory for color set"); -+ col->BG = getcolor(dc, background); -+ col->FG = getcolor(dc, foreground); -+ if(dc->font.xft_font) -+ if(!XftColorAllocName(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)), -+ DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), foreground, &col->FG_xft)) -+ eprintf("error, cannot allocate xft font color '%s'\n", foreground); -+ return col; -+} -+ - DC * - initdc(void) { - DC *dc; -@@ -109,39 +142,33 @@ initdc(void) { - - void - initfont(DC *dc, const char *fontstr) { -- if(!loadfont(dc, fontstr ? fontstr : DEFAULTFN)) { -- if(fontstr != NULL) -- fprintf(stderr, "cannot load font '%s'\n", fontstr); -- if(fontstr == NULL || !loadfont(dc, DEFAULTFN)) -- eprintf("cannot load font '%s'\n", DEFAULTFN); -- } -- dc->font.height = dc->font.ascent + dc->font.descent; --} -- --Bool --loadfont(DC *dc, const char *fontstr) { - char *def, **missing, **names; - int i, n; - XFontStruct **xfonts; - -- if(!*fontstr) -- return False; -- if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) { -+ missing = NULL; -+ if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) { -+ dc->font.ascent = dc->font.xfont->ascent; -+ dc->font.descent = dc->font.xfont->descent; -+ dc->font.width = dc->font.xfont->max_bounds.width; -+ } else if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) { - n = XFontsOfFontSet(dc->font.set, &xfonts, &names); - for(i = 0; i < n; i++) { -- dc->font.ascent = MAX(dc->font.ascent, xfonts[i]->ascent); -+ dc->font.ascent= MAX(dc->font.ascent,xfonts[i]->ascent); - dc->font.descent = MAX(dc->font.descent, xfonts[i]->descent); -- dc->font.width = MAX(dc->font.width, xfonts[i]->max_bounds.width); -+ dc->font.width = MAX(dc->font.width, xfonts[i]->max_bounds.width); - } -- } -- else if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) { -- dc->font.ascent = dc->font.xfont->ascent; -- dc->font.descent = dc->font.xfont->descent; -- dc->font.width = dc->font.xfont->max_bounds.width; -+ } else if((dc->font.xft_font = XftFontOpenName(dc->dpy, DefaultScreen(dc->dpy), fontstr))) { -+ dc->font.ascent = dc->font.xft_font->ascent; -+ dc->font.descent = dc->font.xft_font->descent; -+ dc->font.width = dc->font.xft_font->max_advance_width; -+ } else { -+ eprintf("cannot load font '%s'\n", fontstr); - } - if(missing) - XFreeStringList(missing); -- return dc->font.set || dc->font.xfont; -+ dc->font.height = dc->font.ascent + dc->font.descent; -+ return; - } - - void -@@ -151,20 +178,29 @@ mapdc(DC *dc, Window win, unsigned int w, unsigned int h) { - - void - resizedc(DC *dc, unsigned int w, unsigned int h) { -+ int screen = DefaultScreen(dc->dpy); - if(dc->canvas) - XFreePixmap(dc->dpy, dc->canvas); - - dc->w = w; - dc->h = h; - dc->canvas = XCreatePixmap(dc->dpy, DefaultRootWindow(dc->dpy), w, h, -- DefaultDepth(dc->dpy, DefaultScreen(dc->dpy))); -+ DefaultDepth(dc->dpy, screen)); -+ if(dc->font.xft_font && !(dc->xftdraw)) { -+ dc->xftdraw = XftDrawCreate(dc->dpy, dc->canvas, DefaultVisual(dc->dpy,screen), DefaultColormap(dc->dpy,screen)); -+ if(!(dc->xftdraw)) -+ eprintf("error, cannot create xft drawable\n"); -+ } - } - - int - textnw(DC *dc, const char *text, size_t len) { -- if(dc->font.set) { -+ if(dc->font.xft_font) { -+ XGlyphInfo gi; -+ XftTextExtentsUtf8(dc->dpy, dc->font.xft_font, (const FcChar8*)text, len, &gi); -+ return gi.width; -+ } else if(dc->font.set) { - XRectangle r; -- - XmbTextExtents(dc->font.set, text, len, NULL, &r); - return r.width; - } -diff --git a/draw.h b/draw.h -index 43a57bf..1b4f21a 100644 ---- a/draw.h -+++ b/draw.h -@@ -1,9 +1,6 @@ - /* See LICENSE file for copyright and license details. */ - --#define FG(dc, col) ((col)[(dc)->invert ? ColBG : ColFG]) --#define BG(dc, col) ((col)[(dc)->invert ? ColFG : ColBG]) -- --enum { ColBG, ColFG, ColBorder, ColLast }; -+#include <X11/Xft/Xft.h> - - typedef struct { - int x, y, w, h; -@@ -11,6 +8,7 @@ typedef struct { - Display *dpy; - GC gc; - Pixmap canvas; -+ XftDraw *xftdraw; - struct { - int ascent; - int descent; -@@ -18,15 +16,24 @@ typedef struct { - int width; - XFontSet set; - XFontStruct *xfont; -+ XftFont *xft_font; - } font; - } DC; /* draw context */ - -+typedef struct { -+ unsigned long FG; -+ XftColor FG_xft; -+ unsigned long BG; -+} ColorSet; -+ - void drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color); --void drawtext(DC *dc, const char *text, unsigned long col[ColLast]); --void drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]); -+void drawtext(DC *dc, const char *text, ColorSet *col); -+void drawtextn(DC *dc, const char *text, size_t n, ColorSet *col); -+void freecol(DC *dc, ColorSet *col); - void eprintf(const char *fmt, ...); - void freedc(DC *dc); - unsigned long getcolor(DC *dc, const char *colstr); -+ColorSet *initcolor(DC *dc, const char *foreground, const char *background); - DC *initdc(void); - void initfont(DC *dc, const char *fontstr); - void mapdc(DC *dc, Window win, unsigned int w, unsigned int h); diff --git a/tools.suckless.org/dmenu/patches/dmenu-incremental-20160702-3c91eed.diff b/tools.suckless.org/dmenu/patches/dmenu-incremental-20160702-3c91eed.diff @@ -0,0 +1,82 @@ +From 38914e7a39b12ba1001b5464e6d96d1d15e73634 Mon Sep 17 00:00:00 2001 +From: Hiltjo Posthuma <hiltjo@codemadness.org> +Date: Fri, 17 Jun 2016 15:33:50 +0200 +Subject: [PATCH] incremental mode: dmenu outputs text each time a key is + pressed. + +--- + config.def.h | 1 + + dmenu.1 | 4 ++++ + dmenu.c | 8 +++++++- + 3 files changed, 12 insertions(+), 1 deletion(-) + +diff --git a/config.def.h b/config.def.h +index dcffd38..994f3a5 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 incremental = 0; /* -r option; if 1, outputs text each time a key is pressed */ + /* -fn option overrides fonts[0]; default X11 font or font set */ + static const char *fonts[] = { + "monospace:size=10" +diff --git a/dmenu.1 b/dmenu.1 +index d3ab805..e5bf42f 100644 +--- a/dmenu.1 ++++ b/dmenu.1 +@@ -18,6 +18,7 @@ dmenu \- dynamic menu + .IR color ] + .RB [ \-nf + .IR color ] ++.RB [ \-r ] + .RB [ \-sb + .IR color ] + .RB [ \-sf +@@ -58,6 +59,9 @@ from 0. + .BI \-p " prompt" + defines the prompt to be displayed to the left of the input field. + .TP ++.B \-r ++dmenu outputs text each time a key is pressed. ++.TP + .BI \-fn " font" + defines the font or font set used. + .TP +diff --git a/dmenu.c b/dmenu.c +index e0c2f80..7f1be56 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -447,6 +447,10 @@ keypress(XKeyEvent *ev) + match(); + break; + } ++ if (incremental) { ++ puts(text); ++ fflush(stdout); ++ } + drawmenu(); + } + +@@ -611,7 +615,7 @@ static void + usage(void) + { + fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" +- " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); ++ " [-nb color] [-nf color] [-r] [-sb color] [-sf color] [-v]\n", stderr); + exit(1); + } + +@@ -629,6 +633,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], "-r")) /* incremental */ ++ incremental = 1; + else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ + fstrncmp = strncasecmp; + fstrstr = cistrstr; +-- +2.8.3 + diff --git a/tools.suckless.org/dmenu/patches/dmenu-instant-20160702-3c91eed.diff b/tools.suckless.org/dmenu/patches/dmenu-instant-20160702-3c91eed.diff @@ -0,0 +1,72 @@ +diff --git a/config.def.h b/config.def.h +index dcffd38..a42d28b 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -1,6 +1,7 @@ + /* See LICENSE file for copyright and license details. */ + /* Default settings; can be overriden by command line. */ + ++static int instant = 0; + 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[] = { +diff --git a/dmenu.1 b/dmenu.1 +index d3ab805..8806d4d 100644 +--- a/dmenu.1 ++++ b/dmenu.1 +@@ -6,6 +6,7 @@ dmenu \- dynamic menu + .RB [ \-b ] + .RB [ \-f ] + .RB [ \-i ] ++.RB [ \-n ] + .RB [ \-l + .RB [ \-m + .IR monitor ] +@@ -48,6 +49,9 @@ X until stdin reaches end\-of\-file. + .B \-i + dmenu matches menu items case insensitively. + .TP ++.B \-n ++dmenu instantly selects if only one match. ++.TP + .BI \-l " lines" + dmenu lists items vertically, with the given number of lines. + .TP +diff --git a/dmenu.c b/dmenu.c +index e0c2f80..f079479 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -250,6 +250,13 @@ match(void) + matchend = substrend; + } + curr = sel = matches; ++ ++ if(instant && matches && matches==matchend && !lsubstr) { ++ puts(matches->text); ++ cleanup(); ++ exit(0); ++ } ++ + calcoffsets(); + } + +@@ -610,7 +617,7 @@ setup(void) + static void + usage(void) + { +- fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" ++ fputs("usage: dmenu [-b] [-f] [-i] [-n] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" + " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); + exit(1); + } +@@ -632,7 +639,9 @@ main(int argc, char *argv[]) + else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ + fstrncmp = strncasecmp; + fstrstr = cistrstr; +- } else if (i + 1 == argc) ++ } else if (!strcmp(argv[i], "-n")) /* instant select only match */ ++ instant = 1; ++ else if (i + 1 == argc) + usage(); + /* these options take one argument */ + else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */ diff --git a/tools.suckless.org/dmenu/patches/dmenu-instant-4.6.diff b/tools.suckless.org/dmenu/patches/dmenu-instant-4.6.diff @@ -0,0 +1,74 @@ +From e95c945f9a6afe486782962dfe2dd81c00c05781 Mon Sep 17 00:00:00 2001 +From: Hiltjo Posthuma <hiltjo@codemadness.org> +Date: Fri, 17 Jun 2016 13:24:21 +0200 +Subject: [PATCH] dmenu instant match: end dmenu immediately if there is one + match left. + +--- + config.def.h | 1 + + dmenu.1 | 4 ++++ + dmenu.c | 7 +++++++ + 3 files changed, 12 insertions(+) + +diff --git a/config.def.h b/config.def.h +index dcffd38..b06f1d5 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 instant = 0; /* -n option; if 1, dmenu ends immediately on a distinct match */ + /* -fn option overrides fonts[0]; default X11 font or font set */ + static const char *fonts[] = { + "monospace:size=10" +diff --git a/dmenu.1 b/dmenu.1 +index d3ab805..f0aa123 100644 +--- a/dmenu.1 ++++ b/dmenu.1 +@@ -10,6 +10,7 @@ dmenu \- dynamic menu + .RB [ \-m + .IR monitor ] + .IR lines ] ++.RB [ \-n ] + .RB [ \-p + .IR prompt ] + .RB [ \-fn +@@ -55,6 +56,9 @@ dmenu lists items vertically, with the given number of lines. + dmenu is displayed on the monitor number supplied. Monitor numbers are starting + from 0. + .TP ++.BI \-n ++instant match, end dmenu if there is only one match left. ++.TP + .BI \-p " prompt" + defines the prompt to be displayed to the left of the input field. + .TP +diff --git a/dmenu.c b/dmenu.c +index e0c2f80..0c41d46 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -250,6 +250,11 @@ match(void) + matchend = substrend; + } + curr = sel = matches; ++ if (instant && matches && matches == matchend && !lsubstr) { ++ puts(matches->text); ++ cleanup(); ++ exit(0); ++ } + calcoffsets(); + } + +@@ -632,6 +637,8 @@ main(int argc, char *argv[]) + else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ + fstrncmp = strncasecmp; + fstrstr = cistrstr; ++ } else if (!strcmp(argv[i], "-n")) { /* instant match */ ++ instant = !instant; + } else if (i + 1 == argc) + usage(); + /* these options take one argument */ +-- +2.8.3 + diff --git a/tools.suckless.org/dmenu/patches/dmenu-instant.diff b/tools.suckless.org/dmenu/patches/dmenu-instant.diff @@ -1,38 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 4e5e3e7..22ef78b 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -4,6 +4,8 @@ - /* Default settings; can be overrided by command line. */ - - static Bool topbar = True; /* -b option; if False, dmenu appears at bottom */ -+static Bool instant = False; /* -n option; if True, dmenu ends immediately */ -+ /* on a distinct match */ - /* -fn option overrides fonts[0]; default X11 font or font set */ - static const char *fonts[] = { - "monospace:size=10" -diff --git a/dmenu.c b/dmenu.c -index f0bc176..a357692 100644 ---- a/dmenu.c -+++ b/dmenu.c -@@ -93,6 +93,8 @@ main(int argc, char *argv[]) { - fstrncmp = strncasecmp; - fstrstr = cistrstr; - } -+ else if(!strcmp(argv[i], "-n")) /* instant match */ -+ instant = !instant; - else if(i+1 == argc) - usage(); - /* these options take one argument */ -@@ -511,6 +513,11 @@ match(void) { - matchend = substrend; - } - curr = sel = matches; -+ if(instant && matches && matches==matchend && !lsubstr) { -+ puts(matches->text); -+ cleanup(); -+ exit(0); -+ } - calcoffsets(); - } - diff --git a/tools.suckless.org/dmenu/patches/dmenu-lineheight-4.6.diff b/tools.suckless.org/dmenu/patches/dmenu-lineheight-4.6.diff @@ -0,0 +1,99 @@ +diff --git a/config.def.h b/config.def.h +index a9122f7..6d936b7 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -15,3 +15,6 @@ static const char *outbgcolor = "#00ffff"; + static const char *outfgcolor = "#000000"; + /* -l option; if nonzero, dmenu uses vertical list with given number of lines */ + static unsigned int lines = 0; ++ ++static unsigned int lineheight = 0; /* -lh option; minimum height of a menu line */ ++ +diff --git a/dmenu.1 b/dmenu.1 +index d3ab805..9fe4434 100644 +--- a/dmenu.1 ++++ b/dmenu.1 +@@ -51,6 +51,9 @@ dmenu matches menu items case insensitively. + .BI \-l " lines" + dmenu lists items vertically, with the given number of lines. + .TP ++.BI \-lh " height" ++dmenu uses a menu line of at least 'height' pixels tall, but no less than 8. ++.TP + .BI \-m " monitor" + dmenu is displayed on the monitor number supplied. Monitor numbers are starting + from 0. +diff --git a/dmenu.c b/dmenu.c +index a07f8e3..25832a7 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -119,7 +119,7 @@ drawmenu(void) + { + int curpos; + struct item *item; +- int x = 0, y = 0, h = bh, w; ++ int x = 0, y = 0, fh = drw->fonts[0]->h, w; + + drw_setscheme(drw, &scheme[SchemeNorm]); + drw_rect(drw, 0, 0, mw, mh, 1, 1, 1); +@@ -134,16 +134,16 @@ drawmenu(void) + drw_setscheme(drw, &scheme[SchemeNorm]); + drw_text(drw, x, 0, w, bh, text, 0); + +- if ((curpos = TEXTNW(text, cursor) + bh / 2 - 2) < w) { ++ if ((curpos = TEXTNW(text, cursor) + fh / 2 - 2) < w) { + drw_setscheme(drw, &scheme[SchemeNorm]); +- drw_rect(drw, x + curpos + 2, 2, 1, bh - 4, 1, 1, 0); ++ drw_rect(drw, x + curpos + 2, 2 + (bh-fh)/2, 1, fh - 4, 1, 1, 0); + } + + if (lines > 0) { + /* draw vertical list */ + w = mw - x; + for (item = curr; item != next; item = item->right) { +- y += h; ++ y += bh; + if (item == sel) + drw_setscheme(drw, &scheme[SchemeSel]); + else if (item->out) +@@ -544,6 +544,7 @@ setup(void) + + /* calculate menu geometry */ + bh = drw->fonts[0]->h + 2; ++ bh = MAX(bh,lineheight); /* make a menu line AT LEAST 'lineheight' tall */ + lines = MAX(lines, 0); + mh = (lines + 1) * bh; + #ifdef XINERAMA +@@ -608,7 +609,7 @@ setup(void) + static void + usage(void) + { +- fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" ++ fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font] [-lh height] [-m monitor]\n" + " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); + exit(1); + } +@@ -641,6 +642,10 @@ main(int argc, char *argv[]) + prompt = argv[++i]; + else if (!strcmp(argv[i], "-fn")) /* font or font set */ + fonts[0] = argv[++i]; ++ else if(!strcmp(argv[i], "-lh")) { /* minimum height of one menu line */ ++ lineheight = atoi(argv[++i]); ++ lineheight = MAX(lineheight,8); /* reasonable default in case of value too small/negative */ ++ } + else if (!strcmp(argv[i], "-nb")) /* normal background color */ + normbgcolor = argv[++i]; + else if (!strcmp(argv[i], "-nf")) /* normal foreground color */ +diff --git a/drw.c b/drw.c +index 80e3c39..f4a741f 100644 +--- a/drw.c ++++ b/drw.c +@@ -291,7 +291,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex + if (render) { + th = curfont->ascent + curfont->descent; + ty = y + (h / 2) - (th / 2) + curfont->ascent; +- tx = x + (h / 2); ++ tx = x + (drw->fonts[0]->h / 2); + XftDrawStringUtf8(d, invert ? &drw->scheme->bg->rgb : &drw->scheme->fg->rgb, curfont->xfont, tx, ty, (XftChar8 *)buf, len); + } + x += tex.w; diff --git a/tools.suckless.org/dmenu/patches/dmenu-mousesupport-20160702-3c91eed.diff b/tools.suckless.org/dmenu/patches/dmenu-mousesupport-20160702-3c91eed.diff @@ -0,0 +1,156 @@ +From e9057c96463a3fdf97c0aca9d8626f552fd29de1 Mon Sep 17 00:00:00 2001 +From: Hiltjo Posthuma <hiltjo@codemadness.org> +Date: Sat, 2 Jul 2016 12:15:02 +0200 +Subject: [PATCH] dmenu mouse support + +--- + dmenu.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 118 insertions(+), 1 deletion(-) + +diff --git a/dmenu.c b/dmenu.c +index e926eca..f5c173c 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -440,6 +440,119 @@ keypress(XKeyEvent *ev) + } + + static void ++buttonpress(XEvent *e) ++{ ++ struct item *item; ++ XButtonPressedEvent *ev = &e->xbutton; ++ int x = 0, y = 0, h = bh, w; ++ ++ if (ev->window != win) ++ 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 (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; ++ } ++ /* 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) { ++ /* vertical list: (ctrl)left-click on item */ ++ w = mw - x; ++ for (item = curr; item != next; item = item->right) { ++ y += h; ++ if (ev->y >= y && ev->y <= (y + h)) { ++ puts(item->text); ++ if (!(ev->state & ControlMask)) ++ exit(0); ++ sel = item; ++ if (sel) { ++ sel->out = 1; ++ drawmenu(); ++ } ++ return; ++ } ++ } ++ } else if (matches) { ++ /* left-click on left arrow */ ++ x += inputw; ++ w = TEXTW("<"); ++ 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; ++ w = MIN(TEXTW(item->text), mw - x - TEXTW(">")); ++ if (ev->x >= x && ev->x <= x + w) { ++ puts(item->text); ++ if (!(ev->state & ControlMask)) ++ exit(0); ++ sel = item; ++ if (sel) { ++ sel->out = 1; ++ drawmenu(); ++ } ++ return; ++ } ++ } ++ /* left-click on right arrow */ ++ w = TEXTW(">"); ++ x = mw - w; ++ if (next && ev->x >= x && ev->x <= x + w) { ++ sel = curr = next; ++ calcoffsets(); ++ drawmenu(); ++ return; ++ } ++ } ++} ++ ++static void + paste(void) + { + char *p, *q; +@@ -493,6 +606,9 @@ run(void) + if (XFilterEvent(&ev, win)) + continue; + switch(ev.type) { ++ case ButtonPress: ++ buttonpress(&ev); ++ break; + case Expose: + if (ev.xexpose.count == 0) + drw_map(drw, win, 0, 0, mw, mh); +@@ -581,7 +697,8 @@ setup(void) + /* create menu window */ + swa.override_redirect = True; + swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; +- swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; ++ swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask | ++ ButtonPressMask;; + win = XCreateWindow(dpy, root, x, y, mw, mh, 0, + DefaultDepth(dpy, screen), CopyFromParent, + DefaultVisual(dpy, screen), +-- +2.8.4 + diff --git a/tools.suckless.org/dmenu/patches/dmenu-mousesupport-4.6.diff b/tools.suckless.org/dmenu/patches/dmenu-mousesupport-4.6.diff @@ -0,0 +1,156 @@ +From 66df5f738c17ba5cf23ba99ce18313a39fdfd291 Mon Sep 17 00:00:00 2001 +From: Hiltjo Posthuma <hiltjo@codemadness.org> +Date: Fri, 17 Jun 2016 14:44:16 +0200 +Subject: [PATCH] dmenu mouse support + +--- + dmenu.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 118 insertions(+), 1 deletion(-) + +diff --git a/dmenu.c b/dmenu.c +index a07f8e3..b60037f 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -449,6 +449,119 @@ keypress(XKeyEvent *ev) + } + + static void ++buttonpress(XEvent *e) ++{ ++ struct item *item; ++ XButtonPressedEvent *ev = &e->xbutton; ++ int x = 0, y = 0, h = bh, w; ++ ++ if (ev->window != win) ++ 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 (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; ++ } ++ /* 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) { ++ /* vertical list: (ctrl)left-click on item */ ++ w = mw - x; ++ for (item = curr; item != next; item = item->right) { ++ y += h; ++ if (ev->y >= y && ev->y <= (y + h)) { ++ puts(item->text); ++ if (!(ev->state & ControlMask)) ++ exit(0); ++ sel = item; ++ if (sel) { ++ sel->out = 1; ++ drawmenu(); ++ } ++ return; ++ } ++ } ++ } else if (matches) { ++ /* left-click on left arrow */ ++ x += inputw; ++ w = TEXTW("<"); ++ 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; ++ w = MIN(TEXTW(item->text), mw - x - TEXTW(">")); ++ if (ev->x >= x && ev->x <= x + w) { ++ puts(item->text); ++ if (!(ev->state & ControlMask)) ++ exit(0); ++ sel = item; ++ if (sel) { ++ sel->out = 1; ++ drawmenu(); ++ } ++ return; ++ } ++ } ++ /* left-click on right arrow */ ++ w = TEXTW(">"); ++ x = mw - w; ++ if (next && ev->x >= x && ev->x <= x + w) { ++ sel = curr = next; ++ calcoffsets(); ++ drawmenu(); ++ return; ++ } ++ } ++} ++ ++static void + paste(void) + { + char *p, *q; +@@ -498,6 +611,9 @@ run(void) + if (XFilterEvent(&ev, win)) + continue; + switch(ev.type) { ++ case ButtonPress: ++ buttonpress(&ev); ++ break; + case Expose: + if (ev.xexpose.count == 0) + drw_map(drw, win, 0, 0, mw, mh); +@@ -589,7 +705,8 @@ setup(void) + /* create menu window */ + swa.override_redirect = True; + swa.background_pixel = scheme[SchemeNorm].bg->pix; +- swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; ++ swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask | ++ ButtonPressMask; + win = XCreateWindow(dpy, root, x, y, mw, mh, 0, + DefaultDepth(dpy, screen), CopyFromParent, + DefaultVisual(dpy, screen), +-- +2.8.4 + diff --git a/tools.suckless.org/dmenu/patches/dmenu-ms_nl.diff b/tools.suckless.org/dmenu/patches/dmenu-ms_nl.diff @@ -1,79 +0,0 @@ -diff -up dmenu-4.0/dmenu.1 dmenu-4.0_ms_nl/dmenu.1 ---- dmenu-4.0/dmenu.1 2009-04-18 13:50:04.000000000 +0200 -+++ dmenu-4.0_ms_nl/dmenu.1 2009-11-19 23:01:15.000000000 +0100 -@@ -11,6 +11,8 @@ dmenu \- dynamic menu - .RB [ \-p " <prompt>"] - .RB [ \-sb " <color>"] - .RB [ \-sf " <color>"] -+.RB [ \-ms ] -+.RB [ \-nl ] - .RB [ \-v ] - .SH DESCRIPTION - .SS Overview -@@ -44,6 +46,12 @@ defines the selected background color (# - .B \-sf <color> - defines the selected foreground color (#RGB, #RRGGBB, and color names are supported). - .TP -+.B \-ms -+multi-select; selecting an item and pressing return won't terminate dmenu. -+.TP -+.B \-nl -+seperates standard output by newlines. -+.TP - .B \-v - prints version information to standard output, then exits. - .SH USAGE -diff -up dmenu-4.0/dmenu.c dmenu-4.0_ms_nl/dmenu.c ---- dmenu-4.0/dmenu.c 2009-04-18 13:50:04.000000000 +0200 -+++ dmenu-4.0_ms_nl/dmenu.c 2009-11-19 23:04:59.000000000 +0100 -@@ -69,6 +69,7 @@ static int textw(const char *text); - /* variables */ - static char *maxname = NULL; - static char *prompt = NULL; -+static char *nl = ""; - static char text[4096]; - static int cmdw = 0; - static int promptw = 0; -@@ -77,6 +78,7 @@ static int screen; - static unsigned int mw, mh; - static unsigned int numlockmask = 0; - static Bool running = True; -+static Bool multiselect = False; - static Display *dpy; - static DC dc; - static Item *allitems = NULL; /* first of all items */ -@@ -448,13 +450,13 @@ kpress(XKeyEvent * e) { - break; - case XK_Return: - if((e->state & ShiftMask) && *text) -- fprintf(stdout, "%s", text); -+ fprintf(stdout, "%s%s", text, nl); - else if(sel) -- fprintf(stdout, "%s", sel->text); -+ fprintf(stdout, "%s%s", sel->text, nl); - else if(*text) -- fprintf(stdout, "%s", text); -+ fprintf(stdout, "%s%s", text, nl); - fflush(stdout); -- running = False; -+ running = multiselect; - break; - case XK_Right: - if(!(sel && sel->right)) -@@ -694,11 +696,15 @@ main(int argc, char *argv[]) { - else if(!strcmp(argv[i], "-sf")) { - if(++i < argc) selfgcolor = argv[i]; - } -+ else if(!strcmp(argv[i], "-ms")) -+ multiselect = True; -+ else if(!strcmp(argv[i], "-nl")) -+ nl = "\n"; - else if(!strcmp(argv[i], "-v")) - eprint("dmenu-"VERSION", © 2006-2008 dmenu engineers, see LICENSE for details\n"); - else - eprint("usage: dmenu [-i] [-b] [-fn <font>] [-nb <color>] [-nf <color>]\n" -- " [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); -+ " [-p <prompt>] [-sb <color>] [-sf <color>] [-ms] [-nl] [-v]\n"); - if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) - fprintf(stderr, "warning: no locale support\n"); - if(!(dpy = XOpenDisplay(NULL))) diff --git a/tools.suckless.org/dmenu/patches/dmenu-navhistory-4.6.diff b/tools.suckless.org/dmenu/patches/dmenu-navhistory-4.6.diff @@ -0,0 +1,173 @@ +diff -urp dmenu-4.6/config.def.h dmenu-4.6-patched/config.def.h +--- dmenu-4.6/config.def.h 2015-11-09 06:42:21.000000000 +0800 ++++ dmenu-4.6-patched/config.def.h 2016-04-03 10:59:02.413544865 +0800 +@@ -15,3 +15,5 @@ static const char *outbgcolor = "#00fff + static const char *outfgcolor = "#000000"; + /* -l option; if nonzero, dmenu uses vertical list with given number of lines */ + static unsigned int lines = 0; ++static unsigned int maxhist = 15; ++static int histnodup = 1; /* if 0, record repeated histories */ +diff -urp dmenu-4.6/dmenu.c dmenu-4.6-patched/dmenu.c +--- dmenu-4.6/dmenu.c 2015-11-09 06:42:21.000000000 +0800 ++++ dmenu-4.6-patched/dmenu.c 2016-04-03 10:54:51.798552270 +0800 +@@ -52,6 +52,10 @@ static XIC xic; + static ClrScheme scheme[SchemeLast]; + static Drw *drw; + ++static char *histfile; ++static char *histbuf, *histptr; ++static size_t histsz; ++ + #include "config.h" + + static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; +@@ -278,6 +282,105 @@ nextrune(int inc) + } + + static void ++loadhistory(void) ++{ ++ FILE *fp = NULL; ++ size_t sz; ++ ++ if (!histfile) ++ return; ++ if (!(fp = fopen(histfile, "r"))) ++ return; ++ fseek(fp, 0, SEEK_END); ++ sz = ftell(fp); ++ fseek(fp, 0, SEEK_SET); ++ if (sz) { ++ histsz = sz + 1 + BUFSIZ; ++ if (!(histbuf = malloc(histsz))) { ++ fprintf(stderr, "warning: cannot malloc %lu "\ ++ "bytes", histsz); ++ } else { ++ histptr = histbuf + fread(histbuf, 1, sz, fp); ++ if (histptr <= histbuf) { /* fread error */ ++ free(histbuf); ++ histbuf = NULL; ++ return; ++ } ++ if (histptr[-1] != '\n') ++ *histptr++ = '\n'; ++ histptr[BUFSIZ - 1] = '\0'; ++ *histptr = '\0'; ++ histsz = histptr - histbuf + BUFSIZ; ++ } ++ } ++ fclose(fp); ++} ++ ++static void ++navhistory(int dir) ++{ ++ char *p; ++ size_t len = 0, textlen; ++ ++ if (!histbuf) ++ return; ++ if (dir > 0) { ++ if (histptr == histbuf + histsz - BUFSIZ) ++ return; ++ while (*histptr && *histptr++ != '\n'); ++ for (p = histptr; *p && *p++ != '\n'; len++); ++ } else { ++ if (histptr == histbuf) ++ return; ++ if (histptr == histbuf + histsz - BUFSIZ) { ++ textlen = strlen(text); ++ textlen = MIN(textlen, BUFSIZ - 1); ++ strncpy(histptr, text, textlen); ++ histptr[textlen] = '\0'; ++ } ++ for (histptr--; histptr != histbuf && histptr[-1] != '\n'; ++ histptr--, len++); ++ } ++ len = MIN(len, BUFSIZ - 1); ++ strncpy(text, histptr, len); ++ text[len] = '\0'; ++ cursor = len; ++ match(); ++} ++static void ++savehistory(char *str) ++{ ++ unsigned int n, len = 0; ++ size_t slen; ++ char *p; ++ FILE *fp; ++ ++ if (!histfile || !maxhist) ++ return; ++ if (!(slen = strlen(str))) ++ return; ++ if (histbuf && maxhist > 1) { ++ p = histbuf + histsz - BUFSIZ - 1; /* skip the last newline */ ++ if (histnodup) { ++ for (; p != histbuf && p[-1] != '\n'; p--, len++); ++ n++; ++ if (slen == len && !strncmp(p, str, len)) { ++ return; ++ } ++ } ++ for (; p != histbuf; p--, len++) ++ if (p[-1] == '\n' && ++n + 1 > maxhist) ++ break; ++ fp = fopen(histfile, "w"); ++ fwrite(p, 1, len + 1, fp); /* plus the last newline */ ++ } else { ++ fp = fopen(histfile, "w"); ++ } ++ fwrite(str, 1, strlen(str), fp); ++ fclose(fp); ++} ++ ++static void + keypress(XKeyEvent *ev) + { + char buf[32]; +@@ -341,6 +444,8 @@ keypress(XKeyEvent *ev) + case XK_j: ksym = XK_Next; break; + case XK_k: ksym = XK_Prior; break; + case XK_l: ksym = XK_Down; break; ++ case XK_p: navhistory(-1); buf[0]=0; break; ++ case XK_n: navhistory(1); buf[0]=0; break; + default: + return; + } +@@ -416,6 +521,8 @@ keypress(XKeyEvent *ev) + case XK_KP_Enter: + puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); + if (!(ev->state & ControlMask)) { ++ savehistory((sel && !(ev->state & ShiftMask)) ++ ? sel->text : text); + cleanup(); + exit(0); + } +@@ -608,7 +715,7 @@ setup(void) + static void + usage(void) + { +- fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" ++ fputs("usage: dmenu [-b] [-f] [-H histfile] [-i] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" + " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); + exit(1); + } +@@ -633,6 +740,8 @@ main(int argc, char *argv[]) + } else if (i + 1 == argc) + usage(); + /* these options take one argument */ ++ else if (!strcmp(argv[i], "-H")) ++ histfile = argv[++i]; + else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */ + lines = atoi(argv[++i]); + else if (!strcmp(argv[i], "-m")) +@@ -665,6 +774,7 @@ main(int argc, char *argv[]) + if (!drw->fontcount) + die("no fonts could be loaded.\n"); + drw_setscheme(drw, &scheme[SchemeNorm]); ++ loadhistory(); + + if (fast) { + grabkeyboard(); diff --git a/tools.suckless.org/dmenu/patches/dmenu-nonblockingstdin-20160702-3c91eed.diff b/tools.suckless.org/dmenu/patches/dmenu-nonblockingstdin-20160702-3c91eed.diff @@ -0,0 +1,248 @@ +diff --git a/dmenu.1 b/dmenu.1 +index d3ab805..00958cf 100644 +--- a/dmenu.1 ++++ b/dmenu.1 +@@ -4,7 +4,6 @@ dmenu \- dynamic menu + .SH SYNOPSIS + .B dmenu + .RB [ \-b ] +-.RB [ \-f ] + .RB [ \-i ] + .RB [ \-l + .RB [ \-m +@@ -41,10 +40,6 @@ 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 \-f +-dmenu grabs the keyboard before reading stdin. This is faster, but will lock up +-X until stdin reaches end\-of\-file. +-.TP + .B \-i + dmenu matches menu items case insensitively. + .TP +diff --git a/dmenu.c b/dmenu.c +index e926eca..dc81ef2 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -1,12 +1,15 @@ + /* See LICENSE file for copyright and license details. */ + #include <ctype.h> ++#include <fcntl.h> + #include <locale.h> + #include <stdio.h> + #include <stdlib.h> + #include <string.h> + #include <strings.h> + #include <time.h> ++#include <unistd.h> + ++#include <sys/select.h> + #include <X11/Xlib.h> + #include <X11/Xatom.h> + #include <X11/Xutil.h> +@@ -30,6 +33,7 @@ enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ + struct item { + char *text; + struct item *left, *right; ++ struct item *next; + int out; + }; + +@@ -172,6 +176,7 @@ drawmenu(void) + } + } + drw_map(drw, win, 0, 0, mw, mh); ++ XFlush(dpy); + } + + static void +@@ -200,6 +205,7 @@ match(void) + int i, tokc = 0; + size_t len, textsize; + struct item *item, *lprefix, *lsubstr, *prefixend, *substrend; ++ int preserve = 0; + + strcpy(buf, text); + /* separate input text into tokens to be matched individually */ +@@ -210,19 +216,24 @@ match(void) + + matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL; + textsize = strlen(text); +- for (item = items; item && item->text; item++) { ++ ++ for (item = items; item; item = item->next) { + for (i = 0; i < tokc; i++) + if (!fstrstr(item->text, tokv[i])) + break; + if (i != tokc) /* not all tokens match */ + continue; + /* exact matches go first, then prefixes, then substrings */ +- if (!tokc || !fstrncmp(text, item->text, textsize)) ++ if (!tokc || !fstrncmp(text, item->text, textsize)) { + appenditem(item, &matches, &matchend); +- else if (!fstrncmp(tokv[0], item->text, len)) ++ if (sel == item) preserve = 1; ++ } else if (!fstrncmp(tokv[0], item->text, len)) { + appenditem(item, &lprefix, &prefixend); +- else ++ if (sel == item) preserve = 1; ++ } else { + appenditem(item, &lsubstr, &substrend); ++ if (sel == item) preserve = 1; ++ } + } + if (lprefix) { + if (matches) { +@@ -240,7 +251,9 @@ match(void) + matches = lsubstr; + matchend = substrend; + } +- curr = sel = matches; ++ if (!preserve) ++ curr = sel = matches; ++ + calcoffsets(); + } + +@@ -456,36 +469,7 @@ paste(void) + } + + static void +-readstdin(void) +-{ +- 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, stdin); 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); +- items[i].out = 0; +- drw_font_getexts(drw->fonts, buf, strlen(buf), &tmpmax, NULL); +- if (tmpmax > inputw) { +- inputw = tmpmax; +- imax = i; +- } +- } +- if (items) +- items[i].text = NULL; +- inputw = items ? TEXTW(items[imax].text) : 0; +- lines = MIN(lines, i); +-} +- +-static void +-run(void) ++readevent(void) + { + XEvent ev; + +@@ -513,6 +497,60 @@ run(void) + } + + static void ++readstdin(void) ++{ ++ static size_t max = 0; ++ static struct item **end = &items; ++ ++ char buf[sizeof text], *p, *maxstr; ++ struct item *item; ++ ++ /* 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); ++ inputw = maxstr ? TEXTW(maxstr) : 0; ++ } ++ *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(); ++ } ++} ++ ++static void + setup(void) + { + int x, y; +@@ -600,7 +638,7 @@ setup(void) + static void + usage(void) + { +- fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" ++ fputs("usage: dmenu [-b] [-i] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" + " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); + exit(1); + } +@@ -608,7 +646,7 @@ usage(void) + int + main(int argc, char *argv[]) + { +- int i, fast = 0; ++ int i; + + for (i = 1; i < argc; i++) + /* these options take no arguments */ +@@ -617,8 +655,6 @@ main(int argc, char *argv[]) + exit(0); + } else if (!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */ + topbar = 0; +- else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ +- fast = 1; + else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ + fstrncmp = strncasecmp; + fstrstr = cistrstr; +@@ -657,13 +693,7 @@ main(int argc, char *argv[]) + die("no fonts could be loaded.\n"); + lrpad = drw->fonts->h; + +- if (fast) { +- grabkeyboard(); +- readstdin(); +- } else { +- readstdin(); +- grabkeyboard(); +- } ++ grabkeyboard(); + setup(); + run(); + diff --git a/tools.suckless.org/dmenu/patches/dmenu-pipeout-20160701-3c91eed.diff b/tools.suckless.org/dmenu/patches/dmenu-pipeout-20160701-3c91eed.diff @@ -0,0 +1,44 @@ +diff --git a/config.def.h b/config.def.h +index dcffd38..8c18a07 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -20,4 +20,5 @@ static unsigned int lines = 0; + * Characters not considered part of a word while deleting words + * for example: " /?\"&[]" + */ ++static const char startpipe[] = "#"; + static const char worddelimiters[] = " "; +diff --git a/dmenu.c b/dmenu.c +index e0c2f80..9ed07bc 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -35,6 +35,7 @@ struct item { + }; + + static char text[BUFSIZ] = ""; ++static char pipeout[8] = " | dmenu"; + static int bh, mw, mh; + static int sw, sh; /* X display screen geometry width, height */ + static int inputw, promptw; +@@ -416,7 +417,20 @@ keypress(XKeyEvent *ev) + break; + case XK_Return: + case XK_KP_Enter: +- puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); ++ if ((sel && !(ev->state & ShiftMask))) { ++ if (sel->text[0] == startpipe[0]) { ++ strncpy(sel->text + strlen(sel->text),pipeout,8); ++ puts(sel->text+1); ++ } ++ puts(sel->text); ++ } ++ else { ++ if (text[0] == startpipe[0]) { ++ strncpy(text + strlen(text),pipeout,8); ++ puts(text+1); ++ } ++ puts(text); ++ } + if (!(ev->state & ControlMask)) { + cleanup(); + exit(0); diff --git a/tools.suckless.org/dmenu/patches/dmenu-tip-history.diff b/tools.suckless.org/dmenu/patches/dmenu-tip-history.diff @@ -1,149 +0,0 @@ -diff -r 23bd778df432 dmenu.1 ---- a/dmenu.1 Fri Aug 20 19:57:13 2010 +0100 -+++ b/dmenu.1 Sat Aug 28 18:34:49 2010 +0100 -@@ -19,6 +19,8 @@ - .IR color ] - .RB [ \-sf - .IR color ] -+.RB [ \-hist -+.IR "<filename>" ] - .RB [ \-v ] - .P - .BR dmenu_run " ..." -@@ -72,6 +74,9 @@ - .BI \-sf " color" - defines the selected foreground color. - .TP -+.BI \-hist " <histfile>" -+the file to use for history -+.TP - .B \-v - prints version information to standard output, then exits. - .SH USAGE -diff -r 23bd778df432 dmenu.c ---- a/dmenu.c Fri Aug 20 19:57:13 2010 +0100 -+++ b/dmenu.c Sat Aug 28 18:34:49 2010 +0100 -@@ -16,6 +16,8 @@ - #define MIN(a,b) ((a) < (b) ? (a) : (b)) - #define MAX(a,b) ((a) > (b) ? (a) : (b)) - -+#define HIST_SIZE 20 -+ - typedef struct Item Item; - struct Item { - char *text; -@@ -33,7 +35,7 @@ - static void match(void); - static size_t nextrune(int incr); - static void paste(void); --static void readstdin(void); -+static void readitems(void); - static void run(void); - static void setup(void); - static void usage(void); -@@ -60,8 +62,37 @@ - static Item *prev, *curr, *next; - static Window root, win; - -+static char hist[HIST_SIZE][1024]; -+static char *histfile = NULL; -+static int hcnt = 0; -+ - static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; - -+static int -+writehistory(char *command) { -+ int i = 0; -+ FILE *f; -+ -+ if(!histfile || strlen(command) <= 0) -+ return 0; -+ -+ if((f = fopen(histfile, "w"))) { -+ fputs(command, f); -+ fputc('\n', f); -+ for(; i < hcnt; i++) { -+ if(strcmp(command, hist[i]) != 0) { -+ fputs(hist[i], f); -+ fputc('\n', f); -+ } -+ } -+ fclose(f); -+ return 1; -+ } -+ -+ return 0; -+} -+ -+ - void - appenditem(Item *item, Item **list, Item **last) { - if(!*last) -@@ -296,6 +327,7 @@ - case XK_KP_Enter: - fputs((sel && !(ev->state & ShiftMask)) ? sel->text : text, stdout); - fflush(stdout); -+ writehistory( (sel == NULL) ? text : sel->text); - exit(EXIT_SUCCESS); - case XK_Right: - if(cursor < len) { -@@ -385,9 +417,10 @@ - } - - void --readstdin(void) { -+readitems(void) { - char buf[sizeof text], *p; - Item *item, **end; -+ FILE *f; - - for(end = &items; fgets(buf, sizeof buf, stdin); *end = item, end = &item->next) { - if((p = strchr(buf, '\n'))) -@@ -399,6 +432,22 @@ - item->next = item->left = item->right = NULL; - inputw = MAX(inputw, dc_textw(dc, item->text)); - } -+ -+ if(histfile && (f = fopen(histfile, "r"))) { -+ for(; fgets(buf, sizeof buf, f); *end = item, end = &item->next) { -+ if((p = strchr(buf, '\n'))) -+ *p = '\0'; -+ if(!(item = malloc(sizeof *item))) -+ eprintf("cannot malloc %u bytes\n", sizeof *item); -+ if(!(item->text = strdup(buf))) -+ eprintf("cannot strdup %u bytes\n", strlen(buf)+1); -+ item->next = item->left = item->right = NULL; -+ inputw = MAX(inputw, dc_textw(dc, item->text)); -+ -+ strncpy(hist[hcnt++], buf, (strlen(buf) <= 1024) ? strlen(buf): 1024 ); -+ } -+ fclose(f); -+ } - } - - void -@@ -490,7 +539,7 @@ - void - usage(void) { - fputs("usage: dmenu [-b] [-i] [-l lines] [-p prompt] [-fn font] [-nb color]\n" -- " [-nf color] [-sb color] [-sf color] [-v]\n", stderr); -+ " [-nf color] [-sb color] [-sf color] [-hist histfile] [-v]\n", stderr); - exit(EXIT_FAILURE); - } - -@@ -526,12 +575,14 @@ - selbgcolor = argv[++i]; - else if(!strcmp(argv[i], "-sf")) - selfgcolor = argv[++i]; -+ else if(!strcmp(argv[i], "-hist")) -+ histfile = argv[++i]; - else - usage(); - - dc = dc_init(); - dc_font(dc, font); -- readstdin(); -+ readitems(); - setup(); - run(); - diff --git a/tools.suckless.org/dmenu/patches/dmenu-tip-incremental.diff b/tools.suckless.org/dmenu/patches/dmenu-tip-incremental.diff @@ -1,62 +0,0 @@ -diff -r a79e4a9cb167 dmenu.1 ---- a/dmenu.1 Sat Nov 20 09:25:08 2010 +0000 -+++ b/dmenu.1 Sat Nov 20 18:51:43 2010 +0000 -@@ -5,6 +5,7 @@ - .B dmenu - .RB [ \-b ] - .RB [ \-i ] -+.RB [ \-r ] - .RB [ \-l - .IR lines ] - .RB [ \-m -@@ -50,6 +51,9 @@ - .B \-i - dmenu matches menu items case insensitively. - .TP -+.B \-r -+dmenu outputs text each time a key is pressed. -+.TP - .BI \-l " lines" - dmenu lists items vertically, with the given number of lines. - .TP -diff -r a79e4a9cb167 dmenu.c ---- a/dmenu.c Sat Nov 20 09:25:08 2010 +0000 -+++ b/dmenu.c Sat Nov 20 18:51:43 2010 +0000 -@@ -54,7 +54,7 @@ - static unsigned long normcol[ColLast]; - static unsigned long selcol[ColLast]; - static Atom utf8; --static Bool topbar = True; -+static Bool topbar = True, incremental = False; - static DC *dc; - static Item *items = NULL; - static Item *matches, *sel; -@@ -78,6 +78,8 @@ - topbar = False; - else if(!strcmp(argv[i], "-i")) - fstrncmp = strncasecmp; -+ else if(!strcmp(argv[i], "-r")) -+ incremental = 1; - else if(i == argc-1) - usage(); - /* double flags */ -@@ -364,6 +366,10 @@ - match(); - break; - } -+ if(incremental) { -+ fprintf(stdout, "%s\n", text); -+ fflush(stdout); -+ } - drawmenu(); - } - -@@ -536,7 +542,7 @@ - - void - usage(void) { -- fputs("usage: dmenu [-b] [-i] [-l lines] [-m monitor] [-p prompt] [-fn font]\n" -+ fputs("usage: dmenu [-b] [-i] [-r] [-l lines] [-m monitor] [-p prompt] [-fn font]\n" - " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); - exit(EXIT_FAILURE); - } diff --git a/tools.suckless.org/dmenu/patches/dmenu-tip-non-blocking-stdin.diff b/tools.suckless.org/dmenu/patches/dmenu-tip-non-blocking-stdin.diff @@ -1,110 +0,0 @@ -diff -r 2b9683c50723 dmenu.c ---- a/dmenu.c Wed Dec 01 20:25:10 2010 +0000 -+++ b/dmenu.c Tue Dec 07 17:32:54 2010 +0100 -@@ -4,6 +4,8 @@ - #include <stdlib.h> - #include <string.h> - #include <unistd.h> -+#include <fcntl.h> -+#include <sys/select.h> - #include <X11/Xlib.h> - #include <X11/Xatom.h> - #include <X11/Xutil.h> -@@ -34,6 +36,7 @@ - static size_t nextrune(int incr); - static void paste(void); - static void readstdin(void); -+static void readXEvent(void); - static void run(void); - static void setup(void); - static void usage(void); -@@ -59,6 +62,7 @@ - static Item *items = NULL; - static Item *matches, *sel; - static Item *prev, *curr, *next; -+static Item **end = &items; - static Window root, win; - - static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; -@@ -102,7 +106,6 @@ - - dc = initdc(); - initfont(dc, font); -- readstdin(); - setup(); - run(); - -@@ -433,9 +436,9 @@ - void - readstdin(void) { - char buf[sizeof text], *p; -- Item *item, **end; -+ Item *item; - -- for(end = &items; fgets(buf, sizeof buf, stdin); *end = item, end = &item->next) { -+ while (fgets(buf, sizeof buf, stdin)) { - if((p = strchr(buf, '\n'))) - *p = '\0'; - if(!(item = malloc(sizeof *item))) -@@ -444,14 +447,17 @@ - eprintf("cannot strdup %u bytes\n", strlen(buf)+1); - item->next = item->left = item->right = NULL; - inputw = MAX(inputw, textw(dc, item->text)); -+ *end = item; -+ end = &item->next; - } -+ match(); - } - - void --run(void) { -+readXEvent(void) { - XEvent ev; - -- while(!XNextEvent(dc->dpy, &ev)) -+ while(XPending(dc->dpy) && !XNextEvent(dc->dpy, &ev)) - switch(ev.type) { - case Expose: - if(ev.xexpose.count == 0) -@@ -472,6 +478,32 @@ - } - - void -+run(void) { -+ fd_set fds; -+ int x11_fd, n, nfds, flags; -+ -+ flags = fcntl(STDIN_FILENO, F_GETFL); -+ flags |= O_NONBLOCK; -+ fcntl(STDIN_FILENO, F_SETFL, flags); -+ -+ x11_fd = XConnectionNumber(dc->dpy); -+ nfds = MAX(STDIN_FILENO, x11_fd) + 1; -+ while(1) { -+ FD_ZERO(&fds); -+ if (!feof(stdin)) -+ FD_SET(STDIN_FILENO, &fds); -+ FD_SET(x11_fd, &fds); -+ n = select(nfds, &fds, NULL, NULL, NULL); -+ if(n < 0) -+ eprintf("cannot select\n"); -+ if (FD_ISSET(STDIN_FILENO, &fds)) -+ readstdin(); -+ if (FD_ISSET(x11_fd, &fds)) -+ readXEvent(); -+ } -+} -+ -+void - setup(void) { - int x, y, screen; - XSetWindowAttributes wa; -@@ -531,7 +563,7 @@ - promptw = prompt ? textw(dc, prompt) : 0; - XMapRaised(dc->dpy, win); - text[0] = '\0'; -- match(); -+ drawmenu(); - } - - void diff --git a/tools.suckless.org/dmenu/patches/dmenu-vertfull-4.6.diff b/tools.suckless.org/dmenu/patches/dmenu-vertfull-4.6.diff @@ -0,0 +1,20 @@ +diff -wu a/dmenu.c b/dmenu.c +--- a/dmenu.c 2015-11-08 23:42:21.000000000 +0100 ++++ b/dmenu.c 2015-11-10 18:13:43.937450512 +0100 +@@ -141,7 +141,6 @@ + + if (lines > 0) { + /* draw vertical list */ +- w = mw - x; + for (item = curr; item != next; item = item->right) { + y += h; + if (item == sel) +@@ -151,7 +150,7 @@ + else + drw_setscheme(drw, &scheme[SchemeNorm]); + +- drw_text(drw, x, y, w, bh, item->text, 0); ++ drw_text(drw, 0, y, mw, bh, item->text, 0); + } + } else if (matches) { + /* draw horizontal list */ diff --git a/tools.suckless.org/dmenu/patches/dmenu-xyw-4.6.diff b/tools.suckless.org/dmenu/patches/dmenu-xyw-4.6.diff @@ -0,0 +1,87 @@ +diff --git a/dmenu.1 b/dmenu.1 +index d3ab805..5301910 100644 +--- a/dmenu.1 ++++ b/dmenu.1 +@@ -51,6 +51,24 @@ dmenu matches menu items case insensitively. + .BI \-l " lines" + dmenu lists items vertically, with the given number of lines. + .TP ++.BI \-x " xoffset" ++dmenu is placed at this offset measured from the left side of the monitor. ++Can be negative. ++If option ++.B \-m ++is present, the measurement will use the given monitor. ++.TP ++.BI \-y " yoffset" ++dmenu is placed at this offset measured from the top of the monitor. If the ++.B \-b ++option is used, the offset is measured from the bottom. Can be negative. ++If option ++.B \-m ++is present, the measurement will use the given monitor. ++.TP ++.BI \-w " width" ++sets the width of the dmenu window. ++.TP + .BI \-m " monitor" + dmenu is displayed on the monitor number supplied. Monitor numbers are starting + from 0. +diff --git a/dmenu.c b/dmenu.c +index a07f8e3..9e0c51c 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -37,6 +37,9 @@ struct item { + static char text[BUFSIZ] = ""; + static int bh, mw, mh; + static int sw, sh; /* X display screen geometry width, height */ ++static int dmx = 0; /* put dmenu at this x offset */ ++static int dmy = 0; /* put dmenu at this y offset (measured from the bottom if topbar is 0) */ ++static unsigned int dmw = 0; /* make dmenu this wide */ + static int inputw, promptw; + static size_t cursor; + static struct item *items = NULL; +@@ -571,16 +574,16 @@ setup(void) + if (INTERSECT(x, y, 1, 1, info[i])) + break; + +- x = info[i].x_org; +- y = info[i].y_org + (topbar ? 0 : info[i].height - mh); +- mw = info[i].width; ++ 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); + XFree(info); + } else + #endif + { +- x = 0; +- y = topbar ? 0 : sh - mh; +- mw = sw; ++ x = dmx; ++ y = topbar ? dmy : sh - mh - dmy; ++ mw = (dmw>0 ? dmw : sw); + } + promptw = (prompt && *prompt) ? TEXTW(prompt) : 0; + inputw = MIN(inputw, mw/3); +@@ -609,6 +612,7 @@ static void + usage(void) + { + fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" ++ " [-x xoffset] [-y yoffset] [-w width]\n" + " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); + exit(1); + } +@@ -635,6 +639,12 @@ main(int argc, char *argv[]) + /* these options take one argument */ + else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */ + lines = atoi(argv[++i]); ++ 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]); + else if (!strcmp(argv[i], "-m")) + mon = atoi(argv[++i]); + else if (!strcmp(argv[i], "-p")) /* adds prompt to left of input field */ diff --git a/tools.suckless.org/dmenu/patches/dmenu_xmms.diff b/tools.suckless.org/dmenu/patches/dmenu_xmms.diff @@ -1,133 +0,0 @@ -diff -up dmenu-4.0/config.h dmenu-4.0_xmms/config.h ---- dmenu-4.0/config.h 2009-04-18 13:50:04.000000000 +0200 -+++ dmenu-4.0_xmms/config.h 2009-11-19 21:31:17.000000000 +0100 -@@ -7,3 +7,4 @@ static const char *normfgcolor = "#00000 - static const char *selbgcolor = "#0066ff"; - static const char *selfgcolor = "#ffffff"; - static unsigned int spaceitem = 30; /* px between menu items */ -+static unsigned int maxtokens = 16; /* max. tokens for pattern matching */ -diff -up dmenu-4.0/dmenu.1 dmenu-4.0_xmms/dmenu.1 ---- dmenu-4.0/dmenu.1 2009-04-18 13:50:04.000000000 +0200 -+++ dmenu-4.0_xmms/dmenu.1 2009-11-19 21:14:24.000000000 +0100 -@@ -11,6 +11,7 @@ dmenu \- dynamic menu - .RB [ \-p " <prompt>"] - .RB [ \-sb " <color>"] - .RB [ \-sf " <color>"] -+.RB [ \-xs ] - .RB [ \-v ] - .SH DESCRIPTION - .SS Overview -@@ -44,6 +45,9 @@ defines the selected background color (# - .B \-sf <color> - defines the selected foreground color (#RGB, #RRGGBB, and color names are supported). - .TP -+.B \-xs -+xmms-like pattern matching. -+.TP - .B \-v - prints version information to standard output, then exits. - .SH USAGE -diff -up dmenu-4.0/dmenu.c dmenu-4.0_xmms/dmenu.c ---- dmenu-4.0/dmenu.c 2009-04-18 13:50:04.000000000 +0200 -+++ dmenu-4.0_xmms/dmenu.c 2009-11-19 21:56:30.000000000 +0100 -@@ -69,6 +69,7 @@ static int textw(const char *text); - /* variables */ - static char *maxname = NULL; - static char *prompt = NULL; -+static char **tokens = NULL; - static char text[4096]; - static int cmdw = 0; - static int promptw = 0; -@@ -77,6 +78,7 @@ static int screen; - static unsigned int mw, mh; - static unsigned int numlockmask = 0; - static Bool running = True; -+static Bool xmms = False; - static Display *dpy; - static DC dc; - static Item *allitems = NULL; /* first of all items */ -@@ -475,22 +477,55 @@ kpress(XKeyEvent * e) { - drawmenu(); - } - -+unsigned int tokenize(char *pat, char **tok) -+{ -+ unsigned int i = 0; -+ char tmp[4096] = {0}; -+ -+ strncpy(tmp, pat, strlen(pat)); -+ tok[0] = strtok(tmp, " "); -+ -+ while(tok[i] && i < maxtokens) -+ tok[++i] = strtok(NULL, " "); -+ return i; -+} -+ - void - match(char *pattern) { -- unsigned int plen; -+ unsigned int plen, tokencnt = 0; -+ char append = 0; - Item *i, *itemend, *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; - - if(!pattern) - return; -- plen = strlen(pattern); -+ -+ if(!xmms) -+ tokens[(tokencnt = 1)-1] = pattern; -+ else -+ if(!(tokencnt = tokenize(pattern, tokens))) -+ tokens[(tokencnt = 1)-1] = ""; - item = lexact = lprefix = lsubstr = itemend = exactend = prefixend = substrend = NULL; -- for(i = allitems; i; i = i->next) -- if(!fstrncmp(pattern, i->text, plen + 1)) -+ for(i = allitems; i; i = i->next) { -+ for(int j = 0; j < tokencnt; ++j) { -+ plen = strlen(tokens[j]); -+ if(!fstrncmp(tokens[j], i->text, plen + 1)) -+ append = !append || append > 1 ? 1 : append; -+ else if(!fstrncmp(tokens[j], i->text, plen )) -+ append = !append || append > 2 ? 2 : append; -+ else if(fstrstr(i->text, tokens[j])) -+ append = append > 0 && append < 3 ? append : 3; -+ else { -+ append = 0; -+ break; -+ } -+ } -+ if(append == 1) - appenditem(i, &lexact, &exactend); -- else if(!fstrncmp(pattern, i->text, plen)) -+ else if(append == 2) - appenditem(i, &lprefix, &prefixend); -- else if(fstrstr(i->text, pattern)) -+ else if(append == 3) - appenditem(i, &lsubstr, &substrend); -+ } - if(lexact) { - item = lexact; - itemend = exactend; -@@ -643,6 +678,7 @@ setup(Bool topbar) { - if(promptw > mw / 5) - promptw = mw / 5; - text[0] = 0; -+ tokens = malloc((xmms?maxtokens:1)*sizeof(char*)); - match(text); - XMapRaised(dpy, win); - } -@@ -694,11 +730,13 @@ main(int argc, char *argv[]) { - else if(!strcmp(argv[i], "-sf")) { - if(++i < argc) selfgcolor = argv[i]; - } -+ else if(!strcmp(argv[i], "-xs")) -+ xmms = True; - else if(!strcmp(argv[i], "-v")) - eprint("dmenu-"VERSION", © 2006-2008 dmenu engineers, see LICENSE for details\n"); - else - eprint("usage: dmenu [-i] [-b] [-fn <font>] [-nb <color>] [-nf <color>]\n" -- " [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); -+ " [-p <prompt>] [-sb <color>] [-sf <color>] [-xs] [-v]\n"); - if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) - fprintf(stderr, "warning: no locale support\n"); - if(!(dpy = XOpenDisplay(NULL))) diff --git a/tools.suckless.org/dmenu/patches/follow-focus.md b/tools.suckless.org/dmenu/patches/follow-focus.md @@ -1,12 +0,0 @@ -Follow input focus -================== - -With this patch dmenu will show up on the monitor which has input focus. - -Download --------- -* [dmenu-4.4-follow-focus.diff](dmenu-4.4-follow-focus.diff) - -Author ------- -* Pascal Wittmann - <mail@pascal-wittmann.de> diff --git a/tools.suckless.org/dmenu/patches/fuzzymatch.md b/tools.suckless.org/dmenu/patches/fuzzymatch.md @@ -10,11 +10,10 @@ non-consecutive portions of the string to be matched. Download -------- -* [dmenu-4.5-fuzzymatch.diff](dmenu-4.5-fuzzymatch.diff) -* [dmenu-git-20151020-fuzzymatch.diff](dmenu-git-20151020-fuzzymatch.diff) +* [dmenu-fuzzymatch-4.6.diff](dmenu-fuzzymatch-4.6.diff) Authors ------ * Jan Christoph Ebersbach - jceb@e-jc.de -* Laslo Hunhold - dev@frign.de (dmenu-4.5, dmenu-git-20151020 ports) +* Laslo Hunhold - dev@frign.de (dmenu-4.6) diff --git a/tools.suckless.org/dmenu/patches/hide-single-newline.md b/tools.suckless.org/dmenu/patches/hide-single-newline.md @@ -1,19 +0,0 @@ -Hide single newline -=================== - -Description ------------ - -When you pass the single newline (for example, using `echo | dmenu`) dmenu displays one empty menu item. You can see this effect in surf with "go to url" and "find in page" menus. This patch hides this sad, lonely item. - -Download --------- - -* [dmenu-4.5-hide-single-newline.diff](dmenu-4.5-hide-single-newline.diff) (0.1k) (18 Sep 2015) -* [dmenu-git-20160111-hide-single-newline.diff](dmenu-git-20160111-hide-single-newline.diff) - -Authors -------- - -* Danil Semelenov - `<mail at danil dot mobi>` -* Klemens Nanni <[kl3@posteo.org](mailto:kl3@posteo.org)> (20160111 version) diff --git a/tools.suckless.org/dmenu/patches/history.md b/tools.suckless.org/dmenu/patches/history.md @@ -1,32 +0,0 @@ -History -======= - -Description ------------ - -A patch to have dmenu do "smart" history. It will re-order the options in a -history file based on frequency of use, with the most used heading to the -top. This is best in conjunction with the history patch to surf. In surf, I -have "^G" point to: - - dmenu -hist /home/peterjh/.dmenu.history -b -l 10 < ~/.surf/history - -Enjoy! - -Download --------- - -* [dmenu-tip-history.diff](dmenu-tip-history.diff) (3545) (20091216) - -Author ------- - -* Peter John Hartman (wart_) <[http://antiopus.trilidun.org/durandus/](http://antiopus.trilidun.org/durandus/)> - -Note ----- - -As an alternative to the patch above, the following script is meant to replace -`dmenu_run` : it handles the command history in a similar way as the patch and -can be used with an unpatched dmenu 4.6. -[dmenu_run_history](http://tools.suckless.org/dmenu/scripts/dmenu_run_with_command_history) diff --git a/tools.suckless.org/dmenu/patches/incremental.md b/tools.suckless.org/dmenu/patches/incremental.md @@ -14,4 +14,4 @@ This is useful as an incremental search feature, for example in surf's config.h: Download -------- -* [dmenu-tip-incremental.diff](dmenu-tip-incremental.diff) +* [dmenu-incremental-20160702-3c91eed.diff](dmenu-incremental-20160702-3c91eed.diff) diff --git a/tools.suckless.org/dmenu/patches/index.md b/tools.suckless.org/dmenu/patches/index.md @@ -1,29 +1,5 @@ -Patches +patches ======= -diff generation ---------------- -For git users: - - cd dmenu-directory - git diff > dmenu-X.Y-yourpatchname.diff - -For tarballs: - - cd modified-dmenu-directory/.. - diff -up original-dmenu-directory modified-dmenu-directory > dmenu-X.Y-yourpatchname.diff - -where `X.Y` is a dmenu tag name or version number. - - -patch application ------------------ -For git users: - - cd dmenu-directory - git apply path/to/patch.diff - -For tarballs: - - cd dmenu-directory - patch -p1 < path/to/patch.diff +For instructions on how to submit and format patches, take a look at +the [hacking guidelines](http://suckless.org/hacking). diff --git a/tools.suckless.org/dmenu/patches/instant.md b/tools.suckless.org/dmenu/patches/instant.md @@ -5,7 +5,8 @@ Adds an flag which will cause dmenu to select an item immediately if theres one Download -------- -* [dmenu-instant.diff](dmenu-instant.diff) +* [dmenu-instant-4.6.diff](dmenu-instant-4.6.diff) +* [dmenu-instant-20160702-3c91eed.diff](dmenu-instant-20160702-3c91eed.diff) Author ------ diff --git a/tools.suckless.org/dmenu/patches/legacy/allow-kp_decimal-in-dmenu.patch b/tools.suckless.org/dmenu/patches/legacy/allow-kp_decimal-in-dmenu.patch @@ -1,12 +0,0 @@ -diff -r 4684b2cf4eab dmenu.c ---- a/dmenu.c Sat Dec 05 16:52:53 2009 +0000 -+++ b/dmenu.c Sun Dec 13 20:50:57 2009 +0000 -@@ -395,6 +395,8 @@ - ksym = XK_Return; - else if(ksym >= XK_KP_0 && ksym <= XK_KP_9) - ksym = (ksym - XK_KP_0) + XK_0; -+ else if(ksym == XK_KP_Decimal) -+ ksym = XK_period; - } - if(IsFunctionKey(ksym) || IsKeypadKey(ksym) - || IsMiscFunctionKey(ksym) || IsPFKey(ksym) diff --git a/tools.suckless.org/dmenu/patches/legacy/dmenu-4.0-paste.diff b/tools.suckless.org/dmenu/patches/legacy/dmenu-4.0-paste.diff @@ -1,27 +0,0 @@ -diff -r f48e2b63129e dmenu.c ---- a/dmenu.c Tue Oct 27 14:38:03 2009 -0700 -+++ b/dmenu.c Thu Oct 29 13:14:21 2009 -0700 -@@ -389,6 +389,23 @@ - case XK_G: - ksym = XK_End; - break; -+ case XK_p: -+ { -+ FILE *fp; -+ char *c; -+ if(!(fp = (FILE*)popen("sselp", "r"))) -+ fprintf(stderr, "dmenu: Could not popen sselp\n"); -+ c = fgets(text + len, sizeof(text) - len, fp); -+ pclose(fp); -+ if(c == NULL) -+ return; -+ } -+ len = strlen(text); -+ if(len && text[len-1] == '\n') -+ text[--len] = '\0'; -+ match(text); -+ drawmenu(); -+ return; - } - } - switch(ksym) { diff --git a/tools.suckless.org/dmenu/patches/legacy/dmenu-4.0-vertical_meillo.diff b/tools.suckless.org/dmenu/patches/legacy/dmenu-4.0-vertical_meillo.diff @@ -1,221 +0,0 @@ -# dmenu-4.0 vertical patch -# -# assembled by meillo@marmaro.de -# -# this is a minimal version of fresch's patch -# http://schiewek.net/fresch/dmenu-3.9-fresch-3.diff -# http://bbs.archlinux.org/viewtopic.php?id=54086 - - -diff -up dmenu-4.0/config.mk dmenu-v/config.mk ---- dmenu-4.0/config.mk 2009-04-18 13:50:04.000000000 +0200 -+++ dmenu-v/config.mk 2009-06-03 10:48:35.000000000 +0200 -@@ -1,5 +1,5 @@ - # dmenu version --VERSION = 4.0 -+VERSION = 4.0-vertical - - # Customize below to fit your system - -diff -up dmenu-4.0/dmenu.1 dmenu-v/dmenu.1 ---- dmenu-4.0/dmenu.1 2009-04-18 13:50:04.000000000 +0200 -+++ dmenu-v/dmenu.1 2009-06-03 12:54:25.000000000 +0200 -@@ -5,6 +5,7 @@ dmenu \- dynamic menu - .B dmenu - .RB [ \-i ] - .RB [ \-b ] -+.RB [ \-l " <lines>"] - .RB [ \-fn " <font>"] - .RB [ \-nb " <color>"] - .RB [ \-nf " <color>"] -@@ -26,6 +27,10 @@ makes dmenu match menu entries case inse - .B \-b - defines that dmenu appears at the bottom. - .TP -+.B \-l <lines> -+activates vertical list mode. -+The given number of lines will be displayed. Window height will get adjusted. -+.TP - .B \-fn <font> - defines the font. - .TP -@@ -57,7 +62,7 @@ dmenu is completely controlled by the ke - Appends the character to the text in the input field. This works as a filter: - only items containing this text will be displayed. - .TP --.B Left/Right (Mod1\-h/Mod1\-l) -+.B Left/Right (Up/Down) (Mod1\-h/Mod1\-l) - Select the previous/next item. - .TP - .B PageUp/PageDown (Mod1\-k/Mod1\-j) -diff -up dmenu-4.0/dmenu.c dmenu-v/dmenu.c ---- dmenu-4.0/dmenu.c 2009-04-18 13:50:04.000000000 +0200 -+++ dmenu-v/dmenu.c 2009-06-03 12:31:00.000000000 +0200 -@@ -47,10 +47,12 @@ struct Item { - - /* forward declarations */ - static void appenditem(Item *i, Item **list, Item **last); --static void calcoffsets(void); -+static void calcoffsetsh(void); -+static void calcoffsetsv(void); - static char *cistrstr(const char *s, const char *sub); - static void cleanup(void); --static void drawmenu(void); -+static void drawmenuh(void); -+static void drawmenuv(void); - static void drawtext(const char *text, unsigned long col[ColLast]); - static void eprint(const char *errstr, ...); - static unsigned long getcolor(const char *colstr); -@@ -88,6 +90,10 @@ static Item *curr = NULL; - static Window root, win; - static int (*fstrncmp)(const char *, const char *, size_t n) = strncmp; - static char *(*fstrstr)(const char *, const char *) = strstr; -+static Bool vlist = False; -+static unsigned int lines = 0; -+static void (*calcoffsets)(void) = calcoffsetsh; -+static void (*drawmenu)(void) = drawmenuh; - - void - appenditem(Item *i, Item **list, Item **last) { -@@ -101,7 +107,7 @@ appenditem(Item *i, Item **list, Item ** - } - - void --calcoffsets(void) { -+calcoffsetsh(void) { - int tw; - unsigned int w; - -@@ -127,6 +133,26 @@ calcoffsets(void) { - } - } - -+void -+calcoffsetsv(void) { -+ static unsigned int w; -+ -+ if(!curr) -+ return; -+ w = (dc.font.height + 2) * (lines + 1); -+ for(next = curr; next; next=next->right) { -+ w -= dc.font.height + 2; -+ if(w <= 0) -+ break; -+ } -+ w = (dc.font.height + 2) * (lines + 1); -+ for(prev = curr; prev && prev->left; prev=prev->left) { -+ w -= dc.font.height + 2; -+ if(w <= 0) -+ break; -+ } -+} -+ - char * - cistrstr(const char *s, const char *sub) { - int c, csub; -@@ -171,7 +197,7 @@ cleanup(void) { - } - - void --drawmenu(void) { -+drawmenuh(void) { - Item *i; - - dc.x = 0; -@@ -212,6 +238,39 @@ drawmenu(void) { - } - - void -+drawmenuv(void) { -+ Item *i; -+ -+ dc.x = 0; -+ dc.y = 0; -+ dc.w = mw; -+ dc.h = mh; -+ drawtext(NULL, dc.norm); -+ /* print prompt? */ -+ if(promptw) { -+ dc.w = promptw; -+ drawtext(prompt, dc.sel); -+ } -+ dc.x += promptw; -+ dc.w = mw - promptw; -+ /* print command */ -+ drawtext(text[0] ? text : NULL, dc.norm); -+ if(curr) { -+ dc.x = 0; -+ dc.w = mw; -+ dc.y += dc.font.height + 2; -+ /* determine maximum items */ -+ for(i = curr; i != next; i=i->right) { -+ drawtext(i->text, (sel == i) ? dc.sel : dc.norm); -+ dc.y += dc.font.height + 2; -+ } -+ drawtext(NULL, dc.norm); -+ } -+ XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); -+ XFlush(dpy); -+} -+ -+void - drawtext(const char *text, unsigned long col[ColLast]) { - char buf[256]; - int i, x, y, h, len, olen; -@@ -222,8 +281,8 @@ drawtext(const char *text, unsigned long - if(!text) - return; - olen = strlen(text); -- h = dc.font.ascent + dc.font.descent; -- y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; -+ h = dc.font.height; -+ y = dc.y + ((h+2) / 2) - (h / 2) + dc.font.ascent; - x = dc.x + (h / 2); - /* shorten text if necessary */ - for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w - h; len--); -@@ -426,6 +485,7 @@ kpress(XKeyEvent * e) { - calcoffsets(); - break; - case XK_Left: -+ case XK_Up: - if(!(sel && sel->left)) - return; - sel=sel->left; -@@ -457,6 +517,7 @@ kpress(XKeyEvent * e) { - running = False; - break; - case XK_Right: -+ case XK_Down: - if(!(sel && sel->right)) - return; - sel=sel->right; -@@ -598,6 +659,7 @@ setup(Bool topbar) { - - /* menu window geometry */ - mh = dc.font.height + 2; -+ mh = vlist ? mh * (lines+1) : mh; - #if XINERAMA - if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { - i = 0; -@@ -676,6 +738,12 @@ main(int argc, char *argv[]) { - } - else if(!strcmp(argv[i], "-b")) - topbar = False; -+ else if(!strcmp(argv[i], "-l")) { -+ vlist = True; -+ calcoffsets = calcoffsetsv; -+ drawmenu = drawmenuv; -+ if(++i < argc) lines += atoi(argv[i]); -+ } - else if(!strcmp(argv[i], "-fn")) { - if(++i < argc) font = argv[i]; - } -@@ -697,7 +765,7 @@ main(int argc, char *argv[]) { - else if(!strcmp(argv[i], "-v")) - eprint("dmenu-"VERSION", © 2006-2008 dmenu engineers, see LICENSE for details\n"); - else -- eprint("usage: dmenu [-i] [-b] [-fn <font>] [-nb <color>] [-nf <color>]\n" -+ eprint("usage: dmenu [-i] [-b] [-l <lines>] [-fn <font>] [-nb <color>] [-nf <color>]\n" - " [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); - if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) - fprintf(stderr, "warning: no locale support\n"); diff --git a/tools.suckless.org/dmenu/patches/legacy/dmenu_path-cls.c b/tools.suckless.org/dmenu/patches/legacy/dmenu_path-cls.c @@ -1,100 +0,0 @@ -#include <dirent.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/stat.h> - -#define CACHE ".dmenu_cache" - -static int qstrcmp(const void *a, const void *b); -static void die(const char *s); -static void scan(void); -static int uptodate(void); - -static char **items = NULL; -static const char *HOME, *PATH; -static size_t count = 0; - -int -main(void) { - if(!(HOME = getenv("HOME"))) - die("no $HOME"); - if(!(PATH = getenv("PATH"))) - die("no $PATH"); - if(chdir(HOME) < 0) - die("chdir failed"); - if(uptodate()) { - execlp("cat", "cat", CACHE, NULL); - die("exec failed"); - } - scan(); - return EXIT_SUCCESS; -} - -void -die(const char *s) { - fprintf(stderr, "dmenu_path: %s\n", s); - exit(EXIT_FAILURE); -} - -int -qstrcmp(const void *a, const void *b) { - return strcmp(*(const char **)a, *(const char **)b); -} - -void -scan(void) { - char buf[PATH_MAX]; - char *dir, *path; - size_t i; - struct dirent *ent; - DIR *dp; - FILE *cache; - - if(!(path = strdup(PATH))) - die("strdup failed"); - for(dir = strtok(path, ":"); dir; dir = strtok(NULL, ":")) { - if(!(dp = opendir(dir))) - continue; - while((ent = readdir(dp))) { - snprintf(buf, sizeof buf, "%s/%s", dir, ent->d_name); - if(ent->d_name[0] == '.' || access(buf, X_OK) < 0) - continue; - if(!(items = realloc(items, ++count * sizeof *items))) - die("malloc failed"); - if(!(items[count-1] = strdup(ent->d_name))) - die("strdup failed"); - } - closedir(dp); - } - qsort(items, count, sizeof *items, qstrcmp); - if(!(cache = fopen(CACHE, "w"))) - die("open failed"); - for(i = 0; i < count; i++) { - if(i > 0 && !strcmp(items[i], items[i-1])) - continue; - fprintf(cache, "%s\n", items[i]); - fprintf(stdout, "%s\n", items[i]); - } - fclose(cache); - free(path); -} - -int -uptodate(void) { - char *dir, *path; - time_t mtime; - struct stat st; - - if(stat(CACHE, &st) < 0) - return 0; - mtime = st.st_mtime; - if(!(path = strdup(PATH))) - die("strdup failed"); - for(dir = strtok(path, ":"); dir; dir = strtok(NULL, ":")) - if(!stat(dir, &st) && st.st_mtime > mtime) - return 0; - free(path); - return 1; -} diff --git a/tools.suckless.org/dmenu/patches/legacy/dmenu_path.c b/tools.suckless.org/dmenu/patches/legacy/dmenu_path.c @@ -1,376 +0,0 @@ -/* - * dmenu_path - * This program dumps all executables in $PATH to stdout. - * It uses the file $HOME/.dmenu_cache as a cache. - * - * This program is released under the X11 license (sometimes known as the MIT - * license), which basically means that you can do whatever you want with it. - * - * Sorry for the hairy code. I didn't know how to make it simpler and still - * as generic. Valgrind claims it's correct and doesn't leak, but I'm sure you - * can find a couple of ways to make it crash. - * - * I'd appreciate, but I don't require, that you mail me any improvements or - * comments on the code. - * - * Elmo Todurov todurov+dmenu@gmail.com - * 2010-05-19 09:55 - */ - -#include <sys/stat.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <malloc.h> -#include <unistd.h> -#include <dirent.h> -#include <assert.h> - -static uid_t uid; -static gid_t gid; -static char* cache_path; - -static int uptodate(char** paths) -{ - struct stat dirstat; - time_t cache_time; - char** dirs; - - if (stat(cache_path, &dirstat)) - { - if (errno != ENOENT) - { - perror("stat"); - } - return 0; - } - cache_time = dirstat.st_mtime; - - dirs = paths; - while (*dirs != NULL) - { - if (stat(*dirs, &dirstat)) - { - if (errno != ENOENT) - perror("stat"); - return 0; - } - - if (cache_time < dirstat.st_mtime) - return 0; - - dirs++; - } - - return 1; -} - -static void die(const char* msg) -{ - perror(msg); - exit(EXIT_FAILURE); -} - -static char* get_cache_path() -{ - const char* home; - char* path; - home = getenv("HOME"); - if (home == NULL) - die("getenv"); - path = (char*)malloc(strlen(home) + strlen("/.dmenu_cache") + 1); - if (path == NULL) - die("malloc"); - strcpy(path, home); - strcat(path, "/.dmenu_cache"); - return path; -} - -static char* get_PATH() -{ - const char* path = getenv("PATH"); - char* copy_path; - if (path == NULL) - die("getenv"); - - copy_path = strdup(path); - return copy_path; -} - -static void split_PATH(char* PATH, char*** dirs_in) -{ - char** dirs; - const char* dir = strtok(PATH, ":"); - size_t i = 0; - size_t allocated = 10; - dirs = (char**)malloc(sizeof(char*) * allocated); - if (dirs == NULL) - die("malloc"); - - while (dir != NULL) - { - dirs[i] = (char*)malloc(strlen(dir) + 1); - if (dirs[i] == NULL) - die("malloc"); - strcpy(dirs[i], dir); - dir = strtok(NULL, ":"); - i++; - if (i == allocated) - { - allocated *= 2; - dirs = (char**)realloc(dirs, allocated * sizeof(char**)); - if (dirs == NULL) - die("realloc"); - } - } - dirs[i] = NULL; - - *dirs_in = dirs; -} - -static void free_charpp(char** in) -{ - char** ptr = in; - while (*ptr != NULL) - { - free(*ptr); - ptr++; - } - free(in); -} - -static void fprint_charpp(char** in, FILE* out) -{ - char** ptr = in; - while (*ptr != NULL) - { - fputs(*ptr, out); - fputc('\n', out); - ptr++; - } -} - -static size_t count_charpp(char** in) -{ - char** ptr = in; - size_t count = 0; - while (*ptr != NULL) - { - count++; - ptr++; - } - return count; -} - -static int isexecutable(const char* fname) -{ - struct stat st; - int ret; - int success; - gid_t* grouplist; - - ret = stat(fname, &st); - if (ret != 0) - return 0; - if (!S_ISREG(st.st_mode)) /* this catches regular files and symlinks as well */ - return 0; - if ((st.st_uid == uid && (st.st_mode & S_IXUSR) != 0) - || (st.st_uid != uid && st.st_gid != gid && (st.st_mode & S_IXOTH) != 0)) - { - return 1; - } - - /* check secondary groups */ - if (st.st_mode & S_IXGRP) - { - success = 0; - ret = getgroups(0, 0); - grouplist = (gid_t*)malloc(sizeof(gid_t) * ret); - if (grouplist == NULL) - die("malloc"); - ret = getgroups(ret, grouplist); - while (ret != 0) - { - ret--; - if (st.st_uid != uid /* for group to match, user must not match. */ - && st.st_gid == grouplist[ret]) - { - success = 1; - break; - } - } - free(grouplist); - return success; - } - - return 0; -} - -static void add(const char* prog, char*** progs) -{ - static unsigned progs_allocated = 0; - static unsigned progs_used = 0; - - if (progs_used == progs_allocated) - { - progs_allocated = progs_allocated == 0 ? 256 : progs_allocated * 2; - *progs = (char**)realloc(*progs, sizeof(char*) * progs_allocated); - if (*progs == NULL) - die("realloc"); - } - - if (prog != NULL) - { - (*progs)[progs_used] = (char*)malloc(strlen(prog) + 1); - if ((*progs)[progs_used] == NULL) - die("malloc"); - strcpy((*progs)[progs_used], prog); - progs_used++; - } - else - { - (*progs)[progs_used] = NULL; - } -} - -static void refresh_path(const char* path, char*** progs) -{ - DIR* dirp = opendir(path); - struct dirent* dp; - char fullpath[PATH_MAX]; - char* end; - strcpy(fullpath, path); - end = fullpath + strlen(fullpath); - - if (dirp == NULL) - { - if (errno != ENOENT) - perror("opendir"); - return; - } - - dp = readdir(dirp); - while (dp != NULL) - { - strcat(end, "/"); - strcpy(end + 1, dp->d_name); - if (isexecutable(fullpath)) - add(dp->d_name, progs); - dp = readdir(dirp); - } - closedir(dirp); -} - -static int compare(const void* a, const void* b) -{ - return strcmp(*(const char**)a, *(const char**)b); -} - -static void sort(char*** progs) -{ - qsort(*progs, count_charpp(*progs), sizeof(*progs), compare); -} - -static void uniq(char*** progs) -{ - char** progs_new; - char** ptr_1 = *progs; - char** ptr_2 = ptr_1 + 1; - unsigned long i = 0;; - - progs_new = (char**)malloc(sizeof(char*) * (count_charpp(*progs) + 1)); - if (progs_new == NULL) - die("malloc"); - - while (*ptr_1 != NULL) - { - while (*ptr_2 != NULL && strcmp(*ptr_1, *ptr_2) == 0) - { - free(*ptr_2); - ptr_2++; - } - progs_new[i] = *ptr_1; - i++; - ptr_1 = ptr_2; - ptr_2++; - } - progs_new[i] = NULL; - - free(*progs); - - *progs = progs_new; -} - -static void refresh(char** paths) -{ - char** progs = NULL; - FILE* out; - while (*paths != NULL) - { - refresh_path(*paths, &progs); - paths++; - } - add(NULL, &progs); - - out = fopen(cache_path, "w"); - if (out == NULL) - die("fopen"); - - sort(&progs); - uniq(&progs); - fprint_charpp(progs, out); - fprint_charpp(progs, stdout); - - free_charpp(progs); - fclose(out); -} - -static void cat() -{ - FILE* cache = fopen(cache_path, "r"); - char buf[4096]; - struct stat cachestat; - size_t still_unread; - size_t chunk; - if (cache == NULL) - die("fopen"); - - if (stat(cache_path, &cachestat)) - die("stat"); - still_unread = cachestat.st_size; - - while (still_unread > 0) - { - chunk = fread(buf, 1, sizeof(buf), cache); - still_unread -= chunk; - fwrite(buf, 1, chunk, stdout); - } - fclose(cache); -} - -int main(int argc, char *argv[]) -{ - char* PATH; - char** paths = NULL; - PATH = get_PATH(); - uid = getuid(); - gid = getgid(); - - cache_path = get_cache_path(); - split_PATH(PATH, &paths); - free(PATH); - sort(&paths); - uniq(&paths); - - if ((argc == 2 && strcmp(argv[1], "-f") == 0) - || !uptodate(paths)) - refresh(paths); - else - cat(); - - free_charpp(paths); - free(cache_path); - - return 0; -} diff --git a/tools.suckless.org/dmenu/patches/legacy/dmenu_path.md b/tools.suckless.org/dmenu/patches/legacy/dmenu_path.md @@ -1,11 +0,0 @@ -dmenu_path.c -============ - -The mainline dmenu_path is a shell script, which means it can be slow. Faster -implementations have been written in C. - -Download --------- - -* [376 LOC](dmenu_path.c) by Elmo Todurov - <todurov@gmail.com> -* [100 LOC](dmenu_path-cls.c) by Connor Lane Smith - <cls@lubutu.com> diff --git a/tools.suckless.org/dmenu/patches/legacy/index.md b/tools.suckless.org/dmenu/patches/legacy/index.md @@ -1,4 +0,0 @@ -Legacy patches -============== - -Patches that have since been merged into dmenu trunk in the latest release. diff --git a/tools.suckless.org/dmenu/patches/legacy/kp_decimal.md b/tools.suckless.org/dmenu/patches/legacy/kp_decimal.md @@ -1,14 +0,0 @@ -Keypad decimal key -================== - -This patch allows the decimal key on keypads to input a decimal in dmenu. - -Download --------- - -* [allow-kp_decimal-in-dmenu.patch](allow-kp_decimal-in-dmenu.patch) - -Author ------- - -* Thomas Adam (thomas_adam) <[thomas.adam22@gmail.com](mailto:thomas.adam22@gmail.com)> diff --git a/tools.suckless.org/dmenu/patches/legacy/paste.md b/tools.suckless.org/dmenu/patches/legacy/paste.md @@ -1,23 +0,0 @@ -Paste -===== - -Description ------------ - -This patch allows you to paste the contents of the X selection into dmenu. The -default keybinding for this is mod1+p. - -The patch depends on [sselp](/sselp). - -Download --------- - -* [dmenu-4.0-paste.diff](dmenu-4.0-paste.diff) (597) (20091029) - -Author ------- - -* Evan Gates (emg) <[evan.gates@gmail.com](mailto:evan.gates@gmail.com)> - - -***Note, this patch is present in dmenu-4.1.1.*** diff --git a/tools.suckless.org/dmenu/patches/legacy/vertical.md b/tools.suckless.org/dmenu/patches/legacy/vertical.md @@ -1,14 +0,0 @@ -Vertical menu -============= - -This patch allows you to present a vertical menu instead of a horizontal (this is especially useful for long menu entries such as URLs in conjunction with surf). - -It is expected this patch will go into mainstream dmenu in a slightly modified form in the next version (due to the recent decision of surf to use dmenu for interactive input). - -Download --------- - -* [dmenu-4.0-vertical_meillo.diff](dmenu-4.0-vertical_meillo.diff) - - -***Note, this patch is present in dmenu-4.1.1.*** diff --git a/tools.suckless.org/dmenu/patches/line-height.md b/tools.suckless.org/dmenu/patches/line-height.md @@ -25,11 +25,9 @@ thus completely covering the panel, as shown below: The line height value is also used when dmenu is used in 'vertical' mode ('-l' option). -The patch applies cleanly against 4.6 (32f2564dbbbf5aeafb7190a3d35066142f34448f). - Download -------- -* [dmenu-4.6-line-height.diff](dmenu-4.6-line-height.diff) +* [dmenu-lineheight-4.6.diff](dmenu-lineheight-4.6.diff) Author ------ diff --git a/tools.suckless.org/dmenu/patches/monarg.md b/tools.suckless.org/dmenu/patches/monarg.md @@ -1,17 +0,0 @@ -Monitor by Argument -=================== - -Description ------------ - -Accept an additional command line argument to specify the monitor where dmenu -is to be started. Works well with -[dwm-6.1-monarg.diff](http://dwm.suckless.org/patches/monarg). - -Download --------- -* [dmenu-4.5-monarg.diff](dmenu-4.5-monarg.diff) - -Author ------- -* mar77i <mysatyre at gmail dot com> diff --git a/tools.suckless.org/dmenu/patches/mouse-support-msel.md b/tools.suckless.org/dmenu/patches/mouse-support-msel.md @@ -1,19 +0,0 @@ -Mouse support with multisel -=========================== - -This provides the basic mouse support described in the 'mouse support' patch, -but against 4.6 (32f2564dbbbf5aeafb7190a3d35066142f34448f). - -In addition, multisel is supported via Ctrl-leftclick. -(i.e. Ctrl-leftclick does for mouse operation what Ctrl-Return does for -keyboard, as described in the 'multisel' patch; however, the 'multisel' patch -itself is no longer needed in 4.6 because its functionality has been previously -merged in and now it's part of the master) - -Download --------- -* [dmenu-4.6-mouse-support-msel.diff](dmenu-4.6-mouse-support-msel.diff) - -Author ------- -* Xarchus diff --git a/tools.suckless.org/dmenu/patches/mouse-support.md b/tools.suckless.org/dmenu/patches/mouse-support.md @@ -9,6 +9,7 @@ Mouse actions supported: * On prompt and input field: clear input text and selection. * In horizontal and vertical mode on item: select and output item (same as pressing enter). * In horizontal mode on arrows: change items to show left or right. +* Ctrl-left-mouse click: multisel modifier. * Right-mouse click: close. * Middle-mouse click: * Paste current selection. @@ -20,12 +21,14 @@ Mouse actions supported: * In horizontal mode: same as left-clicking on right arrow. * In vertical mode: show items below. -The attached patch applies cleanly to latest dmenu 4.5 tip (dec9a28863f388072be105e0950deb72ac719d48). Download -------- -* [dmenu-4.5-mouse-support.diff](dmenu-4.5-mouse-support.diff) +* [dmenu-mousesupport-4.6.diff](dmenu-mouse-support-4.6.diff) +* [dmenu-mousesupport-20160702-3c91eed.diff](dmenu-mousesupport-20160702-3c91eed.diff) + Author ------ * Hiltjo Posthuma - <hiltjo@codemadness.org> +* Xarchus (for multisel support). diff --git a/tools.suckless.org/dmenu/patches/multisel.md b/tools.suckless.org/dmenu/patches/multisel.md @@ -1,12 +0,0 @@ -Multiselect -=========== - -Allow for selecting multiple items. Ctrl+Enter prints an item, colors it differently, and allows input to continue. - -Download --------- -* [dmenu-4.4.1-multisel.diff](dmenu-4.4.1-multisel.diff) - -Author ------- -* Evan Gates (emg)<evan.gates@gmail.com> diff --git a/tools.suckless.org/dmenu/patches/multiselect_and_newline.md b/tools.suckless.org/dmenu/patches/multiselect_and_newline.md @@ -1,19 +0,0 @@ -Multiselect and newline -======================= - -multi-select: selecting an item and pressing return won't terminate dmenu -newline : seperates standard outputs by newlines - -These two features are enabled by -ms and -nl command line flag, they can be useful in scripts where one wishes to print several elements from a list -with new line in between. - -The code comes from a vertical patch for dmenu_3.9 wrote by Fresch, the original patch has a lot of options, I just cutted out the one I use on top of Meillo's dmenu vertical patch. (these two and xmms-like pattern matching for huge strings) - -Cutter ------- -- Julien Steinhauser <[julien.steinhauser@orange.fr](mailto:julien.steinhauser@orange.fr)> - -Download --------- - -* [dmenu-ms_nl.diff](dmenu-ms_nl.diff) diff --git a/tools.suckless.org/dmenu/patches/navhistory.md b/tools.suckless.org/dmenu/patches/navhistory.md @@ -0,0 +1,19 @@ +# navhistory + +## Description + +This patch provides dmenu the ability for history navigation similar to that +of bash. Press alt+p for the previous history and alt+n for the next. + +## Configuration + +Set the maximum number of histories with a new variable 'maxhist' in config.h. +By default, it only records a new history if it is not the same as the last one. +To change this behaviour, set 'histnodup' to 0 in config.h. + +## Download + +* [dmenu-navhistory-4.6.diff](dmenu-navhistory-4.6.diff) + +## Author +* phi <crispyfrog@163.com> diff --git a/tools.suckless.org/dmenu/patches/non_blocking_stdin.md b/tools.suckless.org/dmenu/patches/non_blocking_stdin.md @@ -12,12 +12,10 @@ patch, so that you can use stdout to feed stdin. Download -------- -This patch should apply on git version 2b9683c50723 (the latest - -2010-12-08) - -* [dmenu-tip-non-blocking-stdin.diff](dmenu-tip-non-blocking-stdin.diff) +* [dmenu-nonblockingstdin-20160702-3c91eed.diff](dmenu-nonblockingstdin-20160702-3c91eed.diff) Author ------ * Christophe-Marie Duquesne <chm.duquesne@gmail.com> +* koniu at riseup.net (update for 20160615 git master) diff --git a/tools.suckless.org/dmenu/patches/pipeout.md b/tools.suckless.org/dmenu/patches/pipeout.md @@ -0,0 +1,22 @@ +pipeout +======= + +Description +----------- + +This patch allows the selected text to be piped back out with dmenu. This is 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. + +Configuration +------------- +Set the variable 'startpipe' in config.h to any character. + + +Download +-------- + +* [dmenu-pipeout-20160701-3c91eed.diff](dmenu-pipeout-20160701-3c91eed.diff) + +Author +------ + +* Ayrton diff --git a/tools.suckless.org/dmenu/patches/vertfull.md b/tools.suckless.org/dmenu/patches/vertfull.md @@ -4,7 +4,7 @@ Prevents dmenu from indenting items at the same level as the prompt length. Download -------- -* [dmenu-4.6-vertfull.diff](dmenu-4.6-vertfull.diff) +* [dmenu-vertfull-4.6.diff](dmenu-vertfull-4.6.diff) Author ------ diff --git a/tools.suckless.org/dmenu/patches/xft.md b/tools.suckless.org/dmenu/patches/xft.md @@ -1,29 +0,0 @@ -Xft support -=========== - -Description ------------ - -This patch provides Xft support to dmenu, thereby allowing use of -anti-aliased fonts and more. Fonts are specified using the standard -Xft syntax: - - <family>-<size>:<name>=<value> - -For example, 28pt Sans: - - dmenu -fn Sans-28 - -Download --------- - -* [dmenu git](dmenu-git-xft.diff) applies cleanly against 13a529ce63364544bdc851dfd5d3aa2ef8740914 -* [dmenu 4.5](dmenu-4.5-xft.diff) -* [dmenu 4.5 for debian](dmenu-4.5-xft-debian.diff) -* [dmenu 4.5 (improved)](dmenu-4.5-xft-improved.diff) -* [dmenu 4.4.1](dmenu-4.4.1-xft.diff) - -History ------- - -Created from Dan Brown's [4.2.1 patch](http://lists.suckless.org/dev/1011/6474.html). diff --git a/tools.suckless.org/dmenu/patches/xmms-like_pattern_matching.md b/tools.suckless.org/dmenu/patches/xmms-like_pattern_matching.md @@ -1,34 +0,0 @@ -xmms-like pattern matching -========================== - -This patch allows the user to match strings in several pieces. -For example to type: - - dme atc - -could match - - http://tools.suckless.org/dmenu/patches/ - -It can be useful to ease the matching on huge strings. - -The patch comes in two flavours: - -* **tok** (tokenise), for dmenu 4.2.1. Enabled with **-t** command line flag. - -* **xmms**, for legacy dmenu. The original patch submitted by Julien Steinhauser. Enabled with the **-xs** command line flag. - -Download tok ------------- - -* [dmenu-4.2.1-tok.diff](dmenu-4.2.1-tok.diff) - -* [dmenu-4.4-tok.diff](dmenu-4.4-tok.diff) - -Download xmms (legacy) -------------- - -* [dmenu-4.1.1-xmms.diff](dmenu-4.1.1-xmms.diff) - -* [dmenu_xmms.diff](dmenu_xmms.diff) (for **dmenu_3.9** - the original patch submitted by Julien Steinhauser <[julien.steinhauser@orange.fr](mailto:julien.steinhauser@orange.fr)>, taken from [fresch's patch](https://bbs.archlinux.org/viewtopic.php?pid=429090#p429090)) - diff --git a/tools.suckless.org/dmenu/patches/xrdb.diff b/tools.suckless.org/dmenu/patches/xrdb.diff @@ -1,85 +0,0 @@ -diff -r 2b9683c50723 -r ebcc0d8213e0 dmenu.c ---- a/dmenu.c Wed Dec 01 20:25:10 2010 +0000 -+++ b/dmenu.c Tue Dec 14 15:53:44 2010 +0300 -@@ -7,6 +7,7 @@ - #include <X11/Xlib.h> - #include <X11/Xatom.h> - #include <X11/Xutil.h> -+#include <X11/Xresource.h> - #ifdef XINERAMA - #include <X11/extensions/Xinerama.h> - #endif -@@ -37,6 +38,7 @@ - static void run(void); - static void setup(void); - static void usage(void); -+static void read_resourses(void); - - static char text[BUFSIZ]; - static int bh, mw, mh; -@@ -47,10 +49,10 @@ - static size_t cursor = 0; - static const char *font = NULL; - static const char *prompt = NULL; --static const char *normbgcolor = "#cccccc"; --static const char *normfgcolor = "#000000"; --static const char *selbgcolor = "#0066ff"; --static const char *selfgcolor = "#ffffff"; -+static const char *normbgcolor = NULL; -+static const char *normfgcolor = NULL; -+static const char *selbgcolor = NULL; -+static const char *selfgcolor = NULL; - static unsigned long normcol[ColLast]; - static unsigned long selcol[ColLast]; - static Atom utf8; -@@ -101,6 +103,7 @@ - usage(); - - dc = initdc(); -+ read_resourses(); - initfont(dc, font); - readstdin(); - setup(); -@@ -109,6 +112,42 @@ - return EXIT_FAILURE; /* should not reach */ - } - -+/* Set font and colors from X resources database if they are not set -+ * from command line */ -+void -+read_resourses(void) { -+ XrmDatabase xdb; -+ char* xrm; -+ char* datatype[20]; -+ XrmValue xvalue; -+ -+ XrmInitialize(); -+ xrm = XResourceManagerString(dc->dpy); -+ if( xrm != NULL ) { -+ xdb = XrmGetStringDatabase(xrm); -+ if( font == NULL && XrmGetResource(xdb, "dmenu.font", "*", datatype, &xvalue) == True ) -+ font = strdup(xvalue.addr); -+ if( normfgcolor == NULL && XrmGetResource(xdb, "dmenu.foreground", "*", datatype, &xvalue) == True ) -+ normfgcolor = strdup(xvalue.addr); -+ if( normbgcolor == NULL && XrmGetResource(xdb, "dmenu.background", "*", datatype, &xvalue) == True ) -+ normbgcolor = strdup(xvalue.addr); -+ if( selfgcolor == NULL && XrmGetResource(xdb, "dmenu.selforeground", "*", datatype, &xvalue) == True ) -+ selfgcolor = strdup(xvalue.addr); -+ if( selbgcolor == NULL && XrmGetResource(xdb, "dmenu.selbackground", "*", datatype, &xvalue) == True ) -+ selbgcolor = strdup(xvalue.addr); -+ XrmDestroyDatabase(xdb); -+ } -+ /* Set default colors if they are not set */ -+ if( normbgcolor == NULL ) -+ normbgcolor = "#cccccc"; -+ if( normfgcolor == NULL ) -+ normfgcolor = "#000000"; -+ if( selbgcolor == NULL ) -+ selbgcolor = "#0066ff"; -+ if( selfgcolor == NULL ) -+ selfgcolor = "#ffffff"; -+} -+ - void - appenditem(Item *item, Item **list, Item **last) { - if(!*last) diff --git a/tools.suckless.org/dmenu/patches/xrdb.md b/tools.suckless.org/dmenu/patches/xrdb.md @@ -1,16 +0,0 @@ -Incremental output -================== - -This patch allows to confgure font and colors using X resource database. -Following resources are supported: - - * dmenu.font - font - * dmenu.foreground - foreground color - * dmenu.background - background color - * dmenu.selforeground - foreground color for selected area - * dmenu.selbackground - background color for selected area - -Download --------- - -* [xrdb.diff](xrdb.diff) diff --git a/tools.suckless.org/dmenu/patches/xyw.md b/tools.suckless.org/dmenu/patches/xyw.md @@ -10,7 +10,7 @@ The patch adds options for setting window position and width. Download -------- -* [dmenu-4.6-xyw.diff](dmenu-4.6-xyw.diff) +* [dmenu-xyw-4.6.diff](dmenu-xyw-4.6.diff) Author ------ diff --git a/tools.suckless.org/farbfeld/farbfeld.svg b/tools.suckless.org/farbfeld/farbfeld.svg @@ -1,5 +1,5 @@ <?xml version="1.0"?> -<!-- Copyright (c) 2016, Laslo Hunhold <dev@frign.de> --> +<!-- Copyright (c) 2016, Laslo Hunhold <dev@frign.de> CC BY 4.0 --> <svg xmlns="http://www.w3.org/2000/svg" width="178" height="40"> <path d="m 0,0 0,40 5.7143,0 0,-17.14287 5.71428,0 0,-5.71429 -5.71428,0 0,-11.42858 11.42858,0 0,-5.71429 -17.14288,0 z m 22.85716,0 0,40 5.71429,0 0,-17.14287 5.7143,0 0,17.14287 5.71428,0 0,-40 -17.14287,0 z m 22.85716,0 0,40 5.7143,0 0,-17.14287 5.71429,0 0,-5.71429 -5.71429,0 0,-11.42858 5.71429,0 0,-5.71429 -11.42859,0 z m 11.42859,5.71429 0,11.42858 5.71428,0 0,-11.42858 -5.71428,0 z m 0,17.14287 0,17.14287 5.71428,0 0,-17.14287 -5.71428,0 z m 11.42857,-22.85716 0,40 11.42859,0 0,-5.7143 -5.71428,0 0,-11.42857 5.71428,0 0,-5.71429 -5.71428,0 0,-11.42858 5.71428,0 0,-5.71429 -11.42859,0 z m 11.42859,5.71429 0,11.42858 5.71429,0 0,-11.42858 -5.71429,0 z m 0,17.14287 0,11.42857 5.71429,0 0,-11.42857 -5.71429,0 z m 11.42859,-22.85716 0,40 5.71429,0 0,-17.14287 5.71428,0 0,-5.71429 -5.71428,0 0,-11.42858 11.42858,0 0,-5.71429 -17.14287,0 z m 22.85715,0 0,40 17.14287,0 0,-5.7143 -11.42858,0 0,-11.42857 5.7143,0 0,-5.71429 -5.7143,0 0,-11.42858 11.42858,0 0,-5.71429 -17.14287,0 z m 22.85717,0 0,40 17.14287,0 0,-5.7143 -11.42859,0 0,-34.28573 -5.71428,0 z m 22.85715,0 0,40 11.42859,0 0,-5.7143 -5.7143,0 0,-28.57144 5.7143,0 0,-5.71429 -11.42859,0 z m 11.42859,5.71429 0,28.57144 5.71428,0 0,-28.57144 -5.71428,0 z m -142.85727,0 5.7143,0 0,11.42858 -5.7143,0 0,-11.42858 z" style="fill:#222" /> </svg> diff --git a/tools.suckless.org/farbfeld/index.md b/tools.suckless.org/farbfeld/index.md @@ -160,13 +160,15 @@ Download -------- * [farbfeld-1](http://dl.suckless.org/farbfeld/farbfeld-1.tar.gz) (2016-01-06) +* [farbfeld-2](http://dl.suckless.org/farbfeld/farbfeld-2.tar.gz) (2016-03-14) Also make sure to check your package manager. The following distributions provide packages: -* Gentoo (Portage) -* Arch Linux (AUR) -* Void Linux +* [Arch Linux (AUR)](https://aur.archlinux.org/packages/farbfeld) +* [FreeBSD](https://svnweb.freebsd.org/ports/head/graphics/farbfeld/) +* [Gentoo](https://packages.gentoo.org/packages/media-gfx/farbfeld) +* [Void Linux](https://github.com/voidlinux/void-packages/tree/master/srcpkgs/farbfeld) Implementations --------------- @@ -177,6 +179,7 @@ Implementations * [resize](https://github.com/ender672/farbfeld-resize) image filter * [gamut](https://github.com/erik/gamut) image filter collection * [gimp-farbfeld](https://github.com/ids1024/gimp-farbfeld) gimp plug-in +* [farbfeld utilities](http://zzo38computer.org/fossil/farbfeld.ui/) huge collection of image filters Author ------ diff --git a/tools.suckless.org/farbfeld/invert.c b/tools.suckless.org/farbfeld/invert.c @@ -12,40 +12,44 @@ int main(int argc, char *argv[]) { - uint32_t width, height, i, j, k; - uint16_t rgba[4]; - uint8_t hdr[strlen("farbfeld") + 2 * sizeof(uint32_t)]; + uint64_t rowlen; + uint32_t hdr[4], width, height, i, j; + uint16_t *row, *rgba; if (argc > 1) { fprintf(stderr, "usage: %s\n", argv[0]); return 1; } - if (fread(hdr, 1, sizeof(hdr), stdin) != sizeof(hdr)) { - fprintf(stderr, "incomplete header\n"); + if (fread(hdr, sizeof(uint32_t), 4, stdin) != 4) { + fprintf(stderr, "%s: fread error\n", argv[0]); return 1; } - if (memcmp("farbfeld", hdr, strlen("farbfeld"))) { - fprintf(stderr, "invalid magic\n"); + if (memcmp("farbfeld", hdr, sizeof("farbfeld") - 1)) { + fprintf(stderr, "%s: invalid magic value\n", argv[0]); return 1; } - width = ntohl(*((uint32_t *)(hdr + 8))); - height = ntohl(*((uint32_t *)(hdr + 12))); + width = ntohl(hdr[2]); + height = ntohl(hdr[3]); - if (fwrite(hdr, 1, sizeof(hdr), stdout) != sizeof(hdr)) { - fprintf(stderr, "write error\n"); + if (fwrite(hdr, sizeof(uint32_t), 4, stdout) != 4) { + fprintf(stderr, "%s: fwrite error\n", argv[0]); return 1; } + rowlen = (sizeof("RGBA") - 1) * width; + if (!(row = malloc(rowlen * sizeof(uint16_t)))) { + fprintf(stderr, "%s: malloc: out of memory\n", argv[0]); + return 1; + } for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) { - if (fread(rgba, sizeof(uint16_t), 4, - stdin) != 4) { - fprintf(stderr, "unexpected EOF\n"); - return 1; - } - for (k = 0; k < 4; k++) { - rgba[k] = ntohs(rgba[k]); + if (fread(row, sizeof(uint16_t), rowlen, stdin) != rowlen) { + fprintf(stderr, "%s: fread error\n", argv[0]); + return 1; + } + for (rgba = row; (rgba - row) < rowlen; rgba += 4) { + for (j = 0; j < 4; j++) { + rgba[j] = ntohs(rgba[j]); } /* invert colors */ @@ -53,15 +57,14 @@ main(int argc, char *argv[]) rgba[1] = 65535 - rgba[1]; rgba[2] = 65535 - rgba[2]; - for (k = 0; k < 4; k++) { - rgba[k] = htons(rgba[k]); - } - if (fwrite(rgba, sizeof(uint16_t), 4, - stdout) != 4) { - fprintf(stderr, "write error\n"); - return 1; + for (j = 0; j < 4; j++) { + rgba[j] = htons(rgba[j]); } } + if (fwrite(row, sizeof(uint16_t), rowlen, stdout) != rowlen) { + fprintf(stderr, "%s: fwrite error\n", argv[0]); + return 1; + } } return 0; diff --git a/tools.suckless.org/ii/patches/ii-1.7-ucspi.diff b/tools.suckless.org/ii/patches/ii-1.7-ucspi.diff @@ -0,0 +1,165 @@ +diff --git a/ii.1 b/ii.1 +index dd1f6e3..c293c37 100644 +--- a/ii.1 ++++ b/ii.1 +@@ -20,6 +20,10 @@ server with basic command line tools. + For example if you will join a channel just do echo "/j #channel" > in + and ii creates a new channel directory with in and out file. + .SH SYNOPSIS ++.B tcpclient ++host ++port ++.RB [ tlsc ] + .B ii + .RB [ \-s + .IR servername ] +@@ -93,5 +97,7 @@ Write to ii (at) modprobe (dot) de for suggestions, fixes, 7|-|>< ;) etc. + Copyright \(co 2005-2006 by Anselm R. Garbe <garbeam (at) gmail (dot) com> and + Copyright \(co 2005-2008 by Nico Golde <nico (at) ngolde (dot) de> + .SH SEE ALSO ++.BR tcpclient(1), ++.BR tlsc(1), + .BR echo (1), + .BR tail (1), +diff --git a/ii.c b/ii.c +index d93266c..5305869 100644 +--- a/ii.c ++++ b/ii.c +@@ -5,9 +5,7 @@ + #include <netdb.h> + #include <sys/types.h> + #include <sys/stat.h> +-#include <sys/socket.h> + #include <sys/select.h> +-#include <netinet/in.h> + #include <stdio.h> + #include <stdlib.h> + #include <limits.h> +@@ -19,6 +17,9 @@ + #include <time.h> + #include <unistd.h> + ++#define READ_FD 6 ++#define WRITE_FD 7 ++ + #ifndef PIPE_BUF /* FreeBSD don't know PIPE_BUF */ + #define PIPE_BUF 4096 + #endif +@@ -33,7 +34,6 @@ struct Channel { + Channel *next; + }; + +-static int irc; + static time_t last_response; + static Channel *channels = NULL; + static char *host = "irc.freenode.net"; +@@ -148,31 +148,7 @@ static void login(char *key, char *fullname) { + nick, nick, host, fullname ? fullname : nick); + else snprintf(message, PIPE_BUF, "NICK %s\r\nUSER %s localhost %s :%s\r\n", + nick, nick, host, fullname ? fullname : nick); +- write(irc, message, strlen(message)); /* login */ +-} +- +-static int tcpopen(unsigned short port) { +- int fd; +- struct sockaddr_in sin; +- struct hostent *hp = gethostbyname(host); +- +- memset(&sin, 0, sizeof(struct sockaddr_in)); +- if(!hp) { +- perror("ii: cannot retrieve host information"); +- exit(EXIT_FAILURE); +- } +- sin.sin_family = AF_INET; +- memcpy(&sin.sin_addr, hp->h_addr, hp->h_length); +- sin.sin_port = htons(port); +- if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { +- perror("ii: cannot create socket"); +- exit(EXIT_FAILURE); +- } +- if(connect(fd, (const struct sockaddr *) &sin, sizeof(sin)) < 0) { +- perror("ii: cannot connect to host"); +- exit(EXIT_FAILURE); +- } +- return fd; ++ write(WRITE_FD, message, strlen(message)); /* login */ + } + + static size_t tokenize(char **result, size_t reslen, char *str, char delim) { +@@ -219,7 +195,7 @@ static void proc_channels_privmsg(char *channel, char *buf) { + snprintf(message, PIPE_BUF, "<%s> %s", nick, buf); + print_out(channel, message); + snprintf(message, PIPE_BUF, "PRIVMSG %s :%s\r\n", channel, buf); +- write(irc, message, strlen(message)); ++ write(WRITE_FD, message, strlen(message)); + } + + static void proc_channels_input(Channel *c, char *buf) { +@@ -273,7 +249,7 @@ static void proc_channels_input(Channel *c, char *buf) { + else + snprintf(message, PIPE_BUF, + "PART %s :ii - 500 SLOC are too much\r\n", c->name); +- write(irc, message, strlen(message)); ++ write(WRITE_FD, message, strlen(message)); + close(c->fd); + /*create_filepath(infile, sizeof(infile), c->name, "in"); + unlink(infile); */ +@@ -288,7 +264,7 @@ static void proc_channels_input(Channel *c, char *buf) { + snprintf(message, PIPE_BUF, "%s\r\n", &buf[1]); + + if (message[0] != '\0') +- write(irc, message, strlen(message)); ++ write(WRITE_FD, message, strlen(message)); + } + + static void proc_server_cmd(char *buf) { +@@ -339,7 +315,7 @@ static void proc_server_cmd(char *buf) { + return; + } else if(!strncmp("PING", argv[TOK_CMD], 5)) { + snprintf(message, PIPE_BUF, "PONG %s\r\n", argv[TOK_TEXT]); +- write(irc, message, strlen(message)); ++ write(WRITE_FD, message, strlen(message)); + return; + } else if(!argv[TOK_NICKSRV] || !argv[TOK_USER]) { /* server command */ + snprintf(message, PIPE_BUF, "%s%s", argv[TOK_ARG] ? argv[TOK_ARG] : "", argv[TOK_TEXT] ? argv[TOK_TEXT] : ""); +@@ -402,7 +378,7 @@ static void handle_channels_input(Channel *c) { + + static void handle_server_output() { + static char buf[PIPE_BUF]; +- if(read_line(irc, PIPE_BUF, buf) == -1) { ++ if(read_line(READ_FD, PIPE_BUF, buf) == -1) { + perror("ii: remote host closed connection"); + exit(EXIT_FAILURE); + } +@@ -419,8 +395,8 @@ static void run() { + snprintf(ping_msg, sizeof(ping_msg), "PING %s\r\n", host); + for(;;) { + FD_ZERO(&rd); +- maxfd = irc; +- FD_SET(irc, &rd); ++ maxfd = READ_FD; ++ FD_SET(READ_FD, &rd); + for(c = channels; c; c = c->next) { + if(maxfd < c->fd) + maxfd = c->fd; +@@ -440,10 +416,10 @@ static void run() { + print_out(NULL, "-!- ii shutting down: ping timeout"); + exit(EXIT_FAILURE); + } +- write(irc, ping_msg, strlen(ping_msg)); ++ write(WRITE_FD, ping_msg, strlen(ping_msg)); + continue; + } +- if(FD_ISSET(irc, &rd)) { ++ if(FD_ISSET(READ_FD, &rd)) { + handle_server_output(); + last_response = time(NULL); + } +@@ -479,7 +455,6 @@ int main(int argc, char *argv[]) { + default: usage(); break; + } + } +- irc = tcpopen(port); + if(!snprintf(path, sizeof(path), "%s/%s", prefix, host)) { + fputs("ii: path to irc directory too long\n", stderr); + exit(EXIT_FAILURE); diff --git a/tools.suckless.org/ii/patches/index.md b/tools.suckless.org/ii/patches/index.md @@ -1,29 +1,5 @@ -Patches +patches ======= -diff generation ---------------- -For git users: - - cd ii-directory - git diff > ii-X.Y-yourpatchname.diff - -For tarballs: - - cd modified-ii-directory/.. - diff -up original-ii-directory modified-ii-directory > ii-X.Y-yourpatchname.diff - -where `X.Y` is an ii tag name or version number. - - -patch application ------------------ -For git users: - - cd ii-directory - git apply path/to/patch.diff - -For tarballs: - - cd ii-directory - patch -p1 < path/to/patch.diff +For instructions on how to submit and format patches, take a look at +the [hacking guidelines](http://suckless.org/hacking). diff --git a/tools.suckless.org/ii/patches/ssl.md b/tools.suckless.org/ii/patches/ssl.md @@ -15,5 +15,5 @@ Download Author ------ -* Hunter Haugen (Hunner) <[h.haugen@gmail.com](mailto:h.haugen@gmail.com)> +* Written for 1.6 by Hunter Haugen * Ported to ii 1.7 by Nik Unger diff --git a/tools.suckless.org/ii/patches/ucspi.md b/tools.suckless.org/ii/patches/ucspi.md @@ -0,0 +1,20 @@ +UCSPI +===== + +Description +----------- + +Replaces the socket back-end with the [ucspi](https://cr.yp.to/proto/ucspi.txt). +This makes ii more flexable and outsources the handling of IPv6, TLS and SOCKS +to other tools like [tcpclient](https://cr.yp.to/ucspi-tcp.html), +[tlc and socks](https://github.com/younix/ucspi). + +Download +-------- + +* [ii-1.7-ucspi.diff](ii-1.7-ucspi.diff) + +Author +------ + +* Jan Klemkow (younix) <[j.klemkow@wemelug.de](mailto:j.klemkow@wemelug.de)> diff --git a/tools.suckless.org/sent/index.md b/tools.suckless.org/sent/index.md @@ -6,27 +6,26 @@ Simple plaintext presentation tool. ->[![Screenshot of sent](sent-bullets-s.png)](sent-bullets.png)<- sent does not need latex, libreoffice or any other fancy file format, it uses -plaintext files to describe the slides and can include images via -[farbfeld](http://git.2f30.org/farbfeld/about/). Every paragraph represents a -slide in the presentation. Especially for presentations using the [Takahashi -method](https://en.wikipedia.org/wiki/Takahashi_method) this is very nice and -allows you to write down the presentation for a quick lightning talk within a -few minutes. +plaintext files to describe the slides and can also display images. Every +paragraph represents a slide in the presentation. Especially for presentations +using the [Takahashi method](https://en.wikipedia.org/wiki/Takahashi_method) +this is very nice and allows you to write down the presentation for a quick +lightning talk within a few minutes. The presentation is displayed in a simple X11 window colored black on white for maximum contrast even if the sun shines directly onto the projected image. The content of each slide is automatically scaled to fit the window so you don't -have to worry about alignment. Instead you can really concentrate on the -content. +have to worry about alignment. Instead you can really focus on the content. Dependencies ------------ -* Xlib for building -* farbfeld tools to use images in the presentations (if you don't want to use - farbfeld, [sent-0.2](http://dl.suckless.org/tools/sent-0.2.tar.gz) was the - last version with png support, but may lack fixes and further improvements - since its release) +* Xlib and Xft for building +* [farbfeld](http://git.2f30.org/farbfeld/about/) tools to use images in the + presentations (if you don't want to use farbfeld, + [sent-0.2](http://dl.suckless.org/tools/sent-0.2.tar.gz) was the last version + with just png support, but may lack fixes and further improvements since its + release) Demo ---- @@ -40,12 +39,12 @@ You can navigate with the arrow keys and quit with `q`. (Non-)Features -------------- -* A presentation is just a simple text file -* Each paragraph represents one slide -* Content is automatically scaled to fit the screen -* UTF-8 is supported -* Images can be displayed (no text on the same slide), farbfeld required -* Just around 1000 lines of C. +* A presentation is just a simple text file. +* Each paragraph represents one slide. +* Content is automatically scaled to fit the screen. +* UTF-8 is supported. +* Images can be displayed (no text on the same slide). +* Just around 1000 lines of C * No different font styles (bold, italic, underline) * No fancy layout options (different font sizes, different colors, …) * No animations @@ -53,7 +52,7 @@ You can navigate with the arrow keys and quit with `q`. * No export function. If you really need one, just use a shell script with `xdotool` and your favorite screenshot application. * Slides with exuberant amount of lines or characters produce rendering glitches - intentionally to prevent you from holding bad presentations + intentionally to prevent you from holding bad presentations. Usage ----- diff --git a/tools.suckless.org/sent/patches/index.md b/tools.suckless.org/sent/patches/index.md @@ -1,29 +1,5 @@ -Patches +patches ======= -diff generation ---------------- -For git users: - - cd sent-directory - git diff > sent-X.Y-yourpatchname.diff - -For tarballs: - - cd modified-sent-directory/.. - diff -up original-sent-directory modified-sent-directory > sent-X.Y-yourpatchname.diff - -where `X.Y` is a sent tag name or version number. - - -patch application ------------------ -For git users: - - cd sent-directory - git apply path/to/patch.diff - -For tarballs: - - cd sent-directory - patch -p1 < path/to/patch.diff +For instructions on how to submit and format patches, take a look at +the [hacking guidelines](http://suckless.org/hacking). diff --git a/tools.suckless.org/sic/patches/index.md b/tools.suckless.org/sic/patches/index.md @@ -1,29 +1,5 @@ -Patches +patches ======= -diff generation ---------------- -For git users: - - cd sic-directory - git diff > sic-X.Y-yourpatchname.diff - -For tarballs: - - cd modified-sic-directory/.. - diff -up original-sic-directory modified-sic-directory > sic-X.Y-yourpatchname.diff - -where `X.Y` is an sic tag name or version number. - - -patch application ------------------ -For git users: - - cd sic-directory - git apply path/to/patch.diff - -For tarballs: - - cd sic-directory - patch -p1 < path/to/patch.diff +For instructions on how to submit and format patches, take a look at +the [hacking guidelines](http://suckless.org/hacking). diff --git a/tools.suckless.org/slock/index.md b/tools.suckless.org/slock/index.md @@ -5,6 +5,14 @@ aware of. It is stable and quite a lot of people in our community are using it every day when they are out with friends or fetching some food from the local pub. +Configuration +------------- + +Slock is configured via `config.h` like most other suckless.org software. Per +default it will turn the screen red on any keyboard press, if you are less +paranoid and turning red on failed login attempts suffices for you, set +`failonclear = 0` in `config.h`. + Development ----------- You can [browse](http://git.suckless.org/slock) its source code repository diff --git a/tools.suckless.org/slock/patches/control-clear.md b/tools.suckless.org/slock/patches/control-clear.md @@ -0,0 +1,20 @@ +Control Clear +============= + +Description +----------- +Adds an additional configuration parameter, controlkeyclear. When set to 1, +slock will no longer change to the failure color if a control key is pressed +while the buffer is empty. This is useful if, for example, you wake your +monitor up by pressing a control key and don't want to spoil the detection of +failed unlocking attempts. + +Download +-------- + +* [slock-git-20160406-control-clear.diff](slock-git-20160406-control-clear.diff) + +Author +------ + +* David Phillips - <dbphillipsnz@gmail.com> diff --git a/tools.suckless.org/slock/patches/index.md b/tools.suckless.org/slock/patches/index.md @@ -0,0 +1,5 @@ +patches +======= + +For instructions on how to submit and format patches, take a look at +the [hacking guidelines](http://suckless.org/hacking). diff --git a/tools.suckless.org/slock/patches/pam_auth.md b/tools.suckless.org/slock/patches/pam_auth.md @@ -0,0 +1,20 @@ +PAM auth +========= + +Description +----------- + +Replaces shadow support with PAM authentication support. + +Change variable `pam_service` in `config.def.h` to the corresponding PAM +service. The default configuration is for ArchLinux's `login` service. + +Download +-------- + +* [slock-pam_auth.diff](slock-pam_auth.diff) + +Authors +------- + +* Jan Christoph Ebersbach <[jceb@e-jc.de](mailto:jceb@e-jc.de)> diff --git a/tools.suckless.org/slock/patches/quickcancel.md b/tools.suckless.org/slock/patches/quickcancel.md @@ -0,0 +1,28 @@ +quickcancel +=========== + +Description +----------- + +Allow slock to be cancelled by simple mouse movement within the +first 3 seconds after starting. + +This is useful if you forgot to disable `xautolock` during +an activity that requires no input (e.g. reading text, watching video). + +Notes +----- + +The number of seconds while the lock can be cancelled is configured +in `config.h` via the `timetocancel` option. + +Download +-------- + + * [slock-quickcancel-20160619-65b8d52.diff](slock-quickcancel-20160619-65b8d52.diff) + +Authors +------- + + * Matthias Schoth - mschoth@gmail.com + diff --git a/tools.suckless.org/slock/patches/slock-git-20160406-control-clear.diff b/tools.suckless.org/slock/patches/slock-git-20160406-control-clear.diff @@ -0,0 +1,26 @@ +diff --git a/config.def.h b/config.def.h +index eae2d9a..c81908a 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -6,3 +6,6 @@ static const char *colorname[NUMCOLS] = { + + /* treat a cleared input like a wrong password */ + static const int failonclear = 1; ++ ++/* allow control key to trigger fail on clear */ ++static const int controlkeyclear = 0; +diff --git a/slock.c b/slock.c +index c9cdee2..43f6e97 100644 +--- a/slock.c ++++ b/slock.c +@@ -171,7 +171,9 @@ readpw(Display *dpy, const char *pws) + --len; + break; + default: +- if (num && !iscntrl((int)buf[0]) && (len + num < sizeof(passwd))) { ++ if (controlkeyclear && iscntrl((int)buf[0])) ++ continue; ++ if (num && (len + num < sizeof(passwd))) { + memcpy(passwd + len, buf, num); + len += num; + } diff --git a/tools.suckless.org/slock/patches/slock-pam_auth.diff b/tools.suckless.org/slock/patches/slock-pam_auth.diff @@ -0,0 +1,137 @@ +Author: Jan Christoph Ebersbach <jceb@e-jc.de> +URL: http://tools.suckless.org/slock/patches/pam_auth +Replaces shadow support with PAM authentication support. + +Change variable `pam_service` in `config.def.h` to the corresponding PAM +service. The default configuration is for ArchLinux's `login` service. + +diff --git a/config.def.h b/config.def.h +index eae2d9a..085968d 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -6,3 +6,6 @@ static const char *colorname[NUMCOLS] = { + + /* treat a cleared input like a wrong password */ + static const int failonclear = 1; ++ ++/* PAM service that's used for authentication */ ++static const char* pam_service = "login"; +diff --git a/config.mk b/config.mk +index f93879e..e054879 100644 +--- a/config.mk ++++ b/config.mk +@@ -12,7 +12,7 @@ X11LIB = /usr/X11R6/lib + + # includes and libs + INCS = -I. -I/usr/include -I${X11INC} +-LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr ++LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr -lpam + + # flags + CPPFLAGS = -DVERSION=\"${VERSION}\" -DHAVE_SHADOW_H +diff --git a/slock.c b/slock.c +index c9cdee2..6fdfe2f 100644 +--- a/slock.c ++++ b/slock.c +@@ -17,6 +17,8 @@ + #include <X11/keysym.h> + #include <X11/Xlib.h> + #include <X11/Xutil.h> ++#include <security/pam_appl.h> ++#include <security/pam_misc.h> + + #if HAVE_BSD_AUTH + #include <login_cap.h> +@@ -39,6 +41,9 @@ typedef struct { + unsigned long colors[NUMCOLS]; + } Lock; + ++static int pam_conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr); ++struct pam_conv pamc = {pam_conv, NULL}; ++char passwd[256]; + static Lock **locks; + static int nscreens; + static Bool running = True; +@@ -112,6 +117,31 @@ getpw(void) + } + #endif + ++static int ++pam_conv(int num_msg, const struct pam_message **msg, ++ struct pam_response **resp, void *appdata_ptr) ++{ ++ int retval = PAM_CONV_ERR; ++ for(int i=0; i<num_msg; i++) { ++ if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF && ++ strncmp(msg[i]->msg, "Password: ", 10) == 0) { ++ struct pam_response *resp_msg = malloc(sizeof(struct pam_response)); ++ if (!resp_msg) ++ die("malloc failed"); ++ char *password = malloc(strlen(passwd) + 1); ++ if (!password) ++ die("malloc failed"); ++ memset(password, 0, strlen(passwd) + 1); ++ strcpy(password, passwd); ++ resp_msg->resp_retcode = 0; ++ resp_msg->resp = password; ++ resp[i] = resp_msg; ++ retval = PAM_SUCCESS; ++ } ++ } ++ return retval; ++} ++ + static void + #ifdef HAVE_BSD_AUTH + readpw(Display *dpy) +@@ -119,12 +149,15 @@ readpw(Display *dpy) + readpw(Display *dpy, const char *pws) + #endif + { +- char buf[32], passwd[256]; +- int num, screen; ++ char buf[32]; ++ struct passwd* pw; ++ int num, screen, retval; + unsigned int len, color; + KeySym ksym; + XEvent ev; + static int oldc = INIT; ++ pam_handle_t *pamh; ++ + + len = 0; + running = True; +@@ -155,7 +188,19 @@ readpw(Display *dpy, const char *pws) + #ifdef HAVE_BSD_AUTH + running = !auth_userokay(getlogin(), NULL, "auth-xlock", passwd); + #else +- running = !!strcmp(crypt(passwd, pws), pws); ++ pw = getpwuid(getuid()); ++ retval = pam_start(pam_service, pw->pw_name, &pamc, &pamh); ++ if (retval == PAM_SUCCESS) ++ retval = pam_authenticate(pamh, 0); ++ if (retval == PAM_SUCCESS) ++ retval = pam_acct_mgmt(pamh, 0); ++ ++ running = 1; ++ if (retval == PAM_SUCCESS) ++ running = 0; ++ else ++ fprintf(stderr, "slock: %s\n", pam_strerror(pamh, retval)); ++ pam_end(pamh, retval); + #endif + if (running) { + XBell(dpy, 100); +@@ -299,10 +344,10 @@ main(int argc, char **argv) { + dontkillme(); + #endif + ++#ifndef HAVE_BSD_AUTH + if (!getpwuid(getuid())) + die("no passwd entry for you\n"); + +-#ifndef HAVE_BSD_AUTH + pws = getpw(); + #endif + diff --git a/tools.suckless.org/slock/patches/slock-quickcancel-20160619-65b8d52.diff b/tools.suckless.org/slock/patches/slock-quickcancel-20160619-65b8d52.diff @@ -0,0 +1,47 @@ +diff --git a/config.def.h b/config.def.h +index eae2d9a..fbc8f13 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -6,3 +6,6 @@ static const char *colorname[NUMCOLS] = { + + /* treat a cleared input like a wrong password */ + static const int failonclear = 1; ++ ++/* time to cancel lock with mouse movement in seconds */ ++static const int timetocancel = 3; +diff --git a/slock.c b/slock.c +index c9cdee2..a187d7a 100644 +--- a/slock.c ++++ b/slock.c +@@ -12,6 +12,7 @@ + #include <stdio.h> + #include <string.h> + #include <unistd.h> ++#include <time.h> + #include <sys/types.h> + #include <X11/extensions/Xrandr.h> + #include <X11/keysym.h> +@@ -46,6 +47,7 @@ static Bool failure = False; + static Bool rr; + static int rrevbase; + static int rrerrbase; ++static time_t tim; + + static void + die(const char *errstr, ...) +@@ -134,6 +136,7 @@ readpw(Display *dpy, const char *pws) + * utility. This way the user can easily set a customized DPMS + * timeout. */ + while (running && !XNextEvent(dpy, &ev)) { ++ running = !((time(NULL) - tim < timetocancel) && (ev.type == MotionNotify)); + if (ev.type == KeyPress) { + buf[0] = 0; + num = XLookupString(&ev.xkey, buf, sizeof(buf), &ksym, 0); +@@ -261,6 +264,7 @@ lockscreen(Display *dpy, int screen) + if (XGrabKeyboard(dpy, lock->root, True, GrabModeAsync, GrabModeAsync, CurrentTime) == GrabSuccess) { + /* everything fine, we grabbed both inputs */ + XSelectInput(dpy, lock->root, SubstructureNotifyMask); ++ tim = time(NULL); + return lock; + } + usleep(1000); diff --git a/tools.suckless.org/slock/patches/slock-terminalkeys-20160618-65b8d52.diff b/tools.suckless.org/slock/patches/slock-terminalkeys-20160618-65b8d52.diff @@ -0,0 +1,27 @@ +diff --git a/slock.c b/slock.c +index c9cdee2..03e191d 100644 +--- a/slock.c ++++ b/slock.c +@@ -149,6 +149,22 @@ readpw(Display *dpy, const char *pws) + IsPFKey(ksym) || + IsPrivateKeypadKey(ksym)) + continue; ++ if (ev.xkey.state & ControlMask) { ++ switch (ksym) { ++ case XK_u: ++ ksym = XK_Escape; ++ break; ++ case XK_m: ++ ksym = XK_Return; ++ break; ++ case XK_j: ++ ksym = XK_Return; ++ break; ++ case XK_h: ++ ksym = XK_BackSpace; ++ break; ++ } ++ } + switch (ksym) { + case XK_Return: + passwd[len] = 0; diff --git a/tools.suckless.org/slock/patches/terminalkeys.md b/tools.suckless.org/slock/patches/terminalkeys.md @@ -0,0 +1,29 @@ +terminalkeys +============ + +Description +----------- + +Add key commands that are commonly used in terminal applications +(in particular the login prompt) to slock. + +Mappings: + +|Key| | |Function| | | Mapped to| +|:---|-|-|:---|-|-|:---| +|Ctrl-u| | |Delete until beginning of line| | |Esc| +|Ctrl-h| | |Backspace| | |Backspace| +|Ctrl-j| | |Line feed| | |Return| +|Ctrl-m| | |Carriage feed| | |Return| + + +Download +-------- + + * [slock-terminalkeys-20160618-65b8d52.diff](slock-terminalkeys-20160618-65b8d52.diff) + +Authors +------- + + * Matthias Schoth - mschoth@gmail.com + diff --git a/tools.suckless.org/tabbed/patches/clientnumber.md b/tools.suckless.org/tabbed/patches/clientnumber.md @@ -5,8 +5,8 @@ window title. Download -------- -* [tabbed-clientnumber-20160103-eb0ff62.patch](tabbed-clientnumber-20160103-eb0ff62.patch) - (works with 0.6). +* [tabbed-clientnumber-0.6.diff](tabbed-clientnumber-0.6.diff) +* [tabbed-clientnumber-20160702-bc23614.diff](tabbed-clientnumber-20160702-bc23614.diff) Author ------ diff --git a/tools.suckless.org/tabbed/patches/index.md b/tools.suckless.org/tabbed/patches/index.md @@ -1,30 +1,5 @@ -Patches +patches ======= -diff generation ---------------- -For git users: - - cd tabbed-directory - git diff > tabbed-X.Y-yourpatchname.diff - -For tarballs: - - cd modified-tabbed-directory/.. - diff -up original-tabbed-directory modified-tabbed-directory > tabbed-X.Y-yourpatchname.diff - -where `X.Y` is a tabbed tag name or version number. - - -patch application ------------------ -For git users: - - cd tabbed-directory - git apply path/to/patch.diff - -For tarballs: - - cd tabbed-directory - patch -p1 < path/to/patch.diff - +For instructions on how to submit and format patches, take a look at +the [hacking guidelines](http://suckless.org/hacking). diff --git a/tools.suckless.org/tabbed/patches/keycode.md b/tools.suckless.org/tabbed/patches/keycode.md @@ -5,8 +5,8 @@ This way, input is keyboard layout independant (adapt config.h to your keyboard Download -------- -* [tabbed-0.6-keycode.diff](tabbed-0.6-keycode.diff) -* [tabbed-keycode-20160103-eb0ff62.patch](tabbed-keycode-20160103-eb0ff62.patch) +* [tabbed-keycode-0.6.diff](tabbed-keycode-0.6.diff) +* [tabbed-keycode-20160702-bc23614.diff](tabbed-keycode-20160702-bc23614.diff) Author ------ diff --git a/tools.suckless.org/tabbed/patches/tabbed-0.6-keycode.diff b/tools.suckless.org/tabbed/patches/tabbed-0.6-keycode.diff @@ -1,113 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index ceda9f7..088201a 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -29,30 +29,30 @@ static Bool npisrelative = False; - - #define MODKEY ControlMask - static Key keys[] = { \ -- /* modifier key function argument */ -- { MODKEY|ShiftMask, XK_Return, focusonce, { 0 } }, -- { MODKEY|ShiftMask, XK_Return, spawn, { 0 } }, -- { MODKEY, XK_t, spawn, SETPROP("_TABBED_SELECT_TAB") }, -- -- { MODKEY|ShiftMask, XK_l, rotate, { .i = +1 } }, -- { MODKEY|ShiftMask, XK_h, rotate, { .i = -1 } }, -- { MODKEY|ShiftMask, XK_j, movetab, { .i = -1 } }, -- { MODKEY|ShiftMask, XK_k, movetab, { .i = +1 } }, -- { MODKEY, XK_Tab, rotate, { .i = 0 } }, -- -- { MODKEY, XK_1, move, { .i = 0 } }, -- { MODKEY, XK_2, move, { .i = 1 } }, -- { MODKEY, XK_3, move, { .i = 2 } }, -- { MODKEY, XK_4, move, { .i = 3 } }, -- { MODKEY, XK_5, move, { .i = 4 } }, -- { MODKEY, XK_6, move, { .i = 5 } }, -- { MODKEY, XK_7, move, { .i = 6 } }, -- { MODKEY, XK_8, move, { .i = 7 } }, -- { MODKEY, XK_9, move, { .i = 8 } }, -- { MODKEY, XK_0, move, { .i = 9 } }, -- -- { MODKEY, XK_q, killclient, { 0 } }, -- -- { 0, XK_F11, fullscreen, { 0 } }, -+ /* modifier key function argument */ -+ { MODKEY|ShiftMask, 36, focusonce, { 0 } }, // Return -+ { MODKEY|ShiftMask, 36, spawn, { 0 } }, // Return -+ { MODKEY, 44, spawn, SETPROP("_TABBED_SELECT_TAB") }, // t -+ -+ { MODKEY|ShiftMask, 46, rotate, { .i = +1 } }, // l -+ { MODKEY|ShiftMask, 43, rotate, { .i = -1 } }, // h -+ { MODKEY|ShiftMask, 44, movetab, { .i = -1 } }, // j -+ { MODKEY|ShiftMask, 45, movetab, { .i = +1 } }, // k -+ { MODKEY, 23, rotate, { .i = 0 } }, // Tab -+ -+ { MODKEY, 10, move, { .i = 0 } }, // 1 -+ { MODKEY, 11, move, { .i = 1 } }, // 2 -+ { MODKEY, 12, move, { .i = 2 } }, // 3 -+ { MODKEY, 13, move, { .i = 3 } }, // 4 -+ { MODKEY, 14, move, { .i = 4 } }, // 5 -+ { MODKEY, 15, move, { .i = 5 } }, // 6 -+ { MODKEY, 16, move, { .i = 6 } }, // 7 -+ { MODKEY, 17, move, { .i = 7 } }, // 8 -+ { MODKEY, 18, move, { .i = 8 } }, // 9 -+ { MODKEY, 19, move, { .i = 9 } }, // 0 -+ -+ { MODKEY, 24, killclient, { 0 } }, // q -+ -+ { 0, 95, fullscreen, { 0 } }, // F11 - }; - -diff --git a/tabbed.c b/tabbed.c -index 93a213a..744fe4e 100644 ---- a/tabbed.c -+++ b/tabbed.c -@@ -57,7 +57,7 @@ typedef union { - - typedef struct { - unsigned int mod; -- KeySym keysym; -+ KeyCode keycode; - void (*func)(const Arg *); - const Arg arg; - } Key; -@@ -644,11 +644,9 @@ void - keypress(const XEvent *e) { - const XKeyEvent *ev = &e->xkey; - unsigned int i; -- KeySym keysym; - -- keysym = XkbKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0, 0); - for(i = 0; i < LENGTH(keys); i++) { -- if(keysym == keys[i].keysym -+ if(ev->keycode == keys[i].keycode - && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) - && keys[i].func) { - keys[i].func(&(keys[i].arg)); -@@ -684,7 +682,6 @@ manage(Window w) { - int i, j, nextpos; - unsigned int modifiers[] = { 0, LockMask, numlockmask, - numlockmask|LockMask }; -- KeyCode code; - Client *c; - XEvent e; - -@@ -695,13 +692,11 @@ manage(Window w) { - XSync(dpy, False); - - for(i = 0; i < LENGTH(keys); i++) { -- if((code = XKeysymToKeycode(dpy, keys[i].keysym))) { -- for(j = 0; j < LENGTH(modifiers); j++) { -- XGrabKey(dpy, code, keys[i].mod -- | modifiers[j], w, -- True, GrabModeAsync, -- GrabModeAsync); -- } -+ for(j = 0; j < LENGTH(modifiers); j++) { -+ XGrabKey(dpy, keys[i].keycode, keys[i].mod -+ | modifiers[j], w, -+ True, GrabModeAsync, -+ GrabModeAsync); - } - } - diff --git a/tools.suckless.org/tabbed/patches/tabbed-clientnumber-0.6.diff b/tools.suckless.org/tabbed/patches/tabbed-clientnumber-0.6.diff @@ -0,0 +1,23 @@ +diff --git a/tabbed.c b/tabbed.c +index d30206b..70642cb 100644 +--- a/tabbed.c ++++ b/tabbed.c +@@ -308,6 +308,7 @@ drawbar(void) { + unsigned long *col; + int c, fc, width, n = 0; + char *name = NULL; ++ char tabtitle[256]; + + if(nclients == 0) { + dc.x = 0; +@@ -353,7 +354,9 @@ drawbar(void) { + } else { + col = dc.norm; + } +- drawtext(clients[c]->name, col); ++ snprintf(tabtitle, sizeof(tabtitle), "%d: %s", ++ c + 1, clients[c]->name); ++ drawtext(tabtitle, col); + dc.x += dc.w; + clients[c]->tabx = dc.x; + } diff --git a/tools.suckless.org/tabbed/patches/tabbed-clientnumber-20160103-eb0ff62.patch b/tools.suckless.org/tabbed/patches/tabbed-clientnumber-20160103-eb0ff62.patch @@ -1,23 +0,0 @@ -diff --git a/tabbed.c b/tabbed.c -index 5f035c0..b118050 100644 ---- a/tabbed.c -+++ b/tabbed.c -@@ -317,6 +317,7 @@ drawbar(void) - unsigned long *col; - int c, cc, fc, width; - char *name = NULL; -+ char tabtitle[258]; /* drawtext buffer + one char + '\0' */ - - if (nclients == 0) { - dc.x = 0; -@@ -358,7 +359,9 @@ drawbar(void) - } else { - col = clients[c]->urgent ? dc.urg : dc.norm; - } -- drawtext(clients[c]->name, col); -+ snprintf(tabtitle, sizeof(tabtitle), "%d: %s", -+ c + 1, clients[c]->name); -+ drawtext(tabtitle, col); - dc.x += dc.w; - clients[c]->tabx = dc.x; - } diff --git a/tools.suckless.org/tabbed/patches/tabbed-clientnumber-20160702-bc23614.diff b/tools.suckless.org/tabbed/patches/tabbed-clientnumber-20160702-bc23614.diff @@ -0,0 +1,23 @@ +diff --git a/tabbed.c b/tabbed.c +index 9a44795..657909e 100644 +--- a/tabbed.c ++++ b/tabbed.c +@@ -318,6 +318,7 @@ drawbar(void) + XftColor *col; + int c, cc, fc, width; + char *name = NULL; ++ char tabtitle[256]; + + if (nclients == 0) { + dc.x = 0; +@@ -359,7 +360,9 @@ drawbar(void) + } else { + col = clients[c]->urgent ? dc.urg : dc.norm; + } +- drawtext(clients[c]->name, col); ++ snprintf(tabtitle, sizeof(tabtitle), "%d: %s", ++ c + 1, clients[c]->name); ++ drawtext(tabtitle, col); + dc.x += dc.w; + clients[c]->tabx = dc.x; + } diff --git a/tools.suckless.org/tabbed/patches/tabbed-keycode-0.6.diff b/tools.suckless.org/tabbed/patches/tabbed-keycode-0.6.diff @@ -0,0 +1,113 @@ +diff --git a/config.def.h b/config.def.h +index ceda9f7..272074a 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -29,30 +29,30 @@ static Bool npisrelative = False; + + #define MODKEY ControlMask + static Key keys[] = { \ +- /* modifier key function argument */ +- { MODKEY|ShiftMask, XK_Return, focusonce, { 0 } }, +- { MODKEY|ShiftMask, XK_Return, spawn, { 0 } }, +- { MODKEY, XK_t, spawn, SETPROP("_TABBED_SELECT_TAB") }, +- +- { MODKEY|ShiftMask, XK_l, rotate, { .i = +1 } }, +- { MODKEY|ShiftMask, XK_h, rotate, { .i = -1 } }, +- { MODKEY|ShiftMask, XK_j, movetab, { .i = -1 } }, +- { MODKEY|ShiftMask, XK_k, movetab, { .i = +1 } }, +- { MODKEY, XK_Tab, rotate, { .i = 0 } }, +- +- { MODKEY, XK_1, move, { .i = 0 } }, +- { MODKEY, XK_2, move, { .i = 1 } }, +- { MODKEY, XK_3, move, { .i = 2 } }, +- { MODKEY, XK_4, move, { .i = 3 } }, +- { MODKEY, XK_5, move, { .i = 4 } }, +- { MODKEY, XK_6, move, { .i = 5 } }, +- { MODKEY, XK_7, move, { .i = 6 } }, +- { MODKEY, XK_8, move, { .i = 7 } }, +- { MODKEY, XK_9, move, { .i = 8 } }, +- { MODKEY, XK_0, move, { .i = 9 } }, +- +- { MODKEY, XK_q, killclient, { 0 } }, +- +- { 0, XK_F11, fullscreen, { 0 } }, ++ /* modifier key function argument */ ++ { MODKEY|ShiftMask, 36, focusonce, { 0 } }, // Return ++ { MODKEY|ShiftMask, 36, spawn, { 0 } }, // Return ++ { MODKEY, 44, spawn, SETPROP("_TABBED_SELECT_TAB") }, // t ++ ++ { MODKEY|ShiftMask, 46, rotate, { .i = +1 } }, // l ++ { MODKEY|ShiftMask, 43, rotate, { .i = -1 } }, // h ++ { MODKEY|ShiftMask, 44, movetab, { .i = -1 } }, // j ++ { MODKEY|ShiftMask, 45, movetab, { .i = +1 } }, // k ++ { MODKEY, 23, rotate, { .i = 0 } }, // Tab ++ ++ { MODKEY, 10, move, { .i = 0 } }, // 1 ++ { MODKEY, 11, move, { .i = 1 } }, // 2 ++ { MODKEY, 12, move, { .i = 2 } }, // 3 ++ { MODKEY, 13, move, { .i = 3 } }, // 4 ++ { MODKEY, 14, move, { .i = 4 } }, // 5 ++ { MODKEY, 15, move, { .i = 5 } }, // 6 ++ { MODKEY, 16, move, { .i = 6 } }, // 7 ++ { MODKEY, 17, move, { .i = 7 } }, // 8 ++ { MODKEY, 18, move, { .i = 8 } }, // 9 ++ { MODKEY, 19, move, { .i = 9 } }, // 0 ++ ++ { MODKEY, 24, killclient, { 0 } }, // q ++ ++ { 0, 95, fullscreen, { 0 } }, // F11 + }; + +diff --git a/tabbed.c b/tabbed.c +index d30206b..15d6572 100644 +--- a/tabbed.c ++++ b/tabbed.c +@@ -57,7 +57,7 @@ typedef union { + + typedef struct { + unsigned int mod; +- KeySym keysym; ++ KeyCode keycode; + void (*func)(const Arg *); + const Arg arg; + } Key; +@@ -644,11 +644,9 @@ void + keypress(const XEvent *e) { + const XKeyEvent *ev = &e->xkey; + unsigned int i; +- KeySym keysym; + +- keysym = XkbKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0, 0); + for(i = 0; i < LENGTH(keys); i++) { +- if(keysym == keys[i].keysym ++ if(ev->keycode == keys[i].keycode + && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) + && keys[i].func) { + keys[i].func(&(keys[i].arg)); +@@ -684,7 +682,6 @@ manage(Window w) { + int i, j, nextpos; + unsigned int modifiers[] = { 0, LockMask, numlockmask, + numlockmask|LockMask }; +- KeyCode code; + Client *c; + XEvent e; + +@@ -695,13 +692,11 @@ manage(Window w) { + XSync(dpy, False); + + for(i = 0; i < LENGTH(keys); i++) { +- if((code = XKeysymToKeycode(dpy, keys[i].keysym))) { +- for(j = 0; j < LENGTH(modifiers); j++) { +- XGrabKey(dpy, code, keys[i].mod +- | modifiers[j], w, +- True, GrabModeAsync, +- GrabModeAsync); +- } ++ for(j = 0; j < LENGTH(modifiers); j++) { ++ XGrabKey(dpy, keys[i].keycode, keys[i].mod ++ | modifiers[j], w, ++ True, GrabModeAsync, ++ GrabModeAsync); + } + } + diff --git a/tools.suckless.org/tabbed/patches/tabbed-keycode-20160103-eb0ff62.patch b/tools.suckless.org/tabbed/patches/tabbed-keycode-20160103-eb0ff62.patch @@ -1,110 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 587ce73..7d7e67f 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -35,31 +35,32 @@ static Bool npisrelative = False; - #define MODKEY ControlMask - static Key keys[] = { - /* modifier key function argument */ -- { MODKEY|ShiftMask, XK_Return, focusonce, { 0 } }, -- { MODKEY|ShiftMask, XK_Return, spawn, { 0 } }, -- { MODKEY, XK_t, spawn, SETPROP("_TABBED_SELECT_TAB") }, -+ { MODKEY|ShiftMask, 36, focusonce, { 0 } }, -+ { MODKEY|ShiftMask, 36, spawn, { 0 } }, -+ { MODKEY, 28, spawn, SETPROP("_TABBED_SELECT_TAB") }, - -- { MODKEY|ShiftMask, XK_l, rotate, { .i = +1 } }, -- { MODKEY|ShiftMask, XK_h, rotate, { .i = -1 } }, -- { MODKEY|ShiftMask, XK_j, movetab, { .i = -1 } }, -- { MODKEY|ShiftMask, XK_k, movetab, { .i = +1 } }, -- { MODKEY, XK_Tab, rotate, { .i = 0 } }, -+ { MODKEY|ShiftMask, 46, rotate, { .i = +1 } }, -+ { MODKEY|ShiftMask, 43, rotate, { .i = -1 } }, -+ { MODKEY|ShiftMask, 44, movetab, { .i = -1 } }, -+ { MODKEY|ShiftMask, 45, movetab, { .i = +1 } }, -+ { MODKEY, 23, rotate, { .i = 0 } }, - -- { MODKEY, XK_1, move, { .i = 0 } }, -- { MODKEY, XK_2, move, { .i = 1 } }, -- { MODKEY, XK_3, move, { .i = 2 } }, -- { MODKEY, XK_4, move, { .i = 3 } }, -- { MODKEY, XK_5, move, { .i = 4 } }, -- { MODKEY, XK_6, move, { .i = 5 } }, -- { MODKEY, XK_7, move, { .i = 6 } }, -- { MODKEY, XK_8, move, { .i = 7 } }, -- { MODKEY, XK_9, move, { .i = 8 } }, -- { MODKEY, XK_0, move, { .i = 9 } }, - -- { MODKEY, XK_q, killclient, { 0 } }, -+ { MODKEY, 10, move, { .i = 0 } }, -+ { MODKEY, 11, move, { .i = 1 } }, -+ { MODKEY, 12, move, { .i = 2 } }, -+ { MODKEY, 13, move, { .i = 3 } }, -+ { MODKEY, 14, move, { .i = 4 } }, -+ { MODKEY, 15, move, { .i = 5 } }, -+ { MODKEY, 16, move, { .i = 6 } }, -+ { MODKEY, 17, move, { .i = 7 } }, -+ { MODKEY, 18, move, { .i = 8 } }, -+ { MODKEY, 19, move, { .i = 9 } }, - -- { MODKEY, XK_u, focusurgent, { 0 } }, -- { MODKEY|ShiftMask, XK_u, toggle, { .v = (void*) &urgentswitch } }, -+ { MODKEY, 24, killclient, { 0 } }, - -- { 0, XK_F11, fullscreen, { 0 } }, -+ { MODKEY, 30, focusurgent, { .v = NULL } }, -+ { MODKEY|ShiftMask, 30, toggle, { .v = (void*) &urgentswitch } }, -+ -+ { 0, 95, fullscreen, { 0 } }, - }; -diff --git a/tabbed.c b/tabbed.c -index 5f035c0..c5ed4a3 100644 ---- a/tabbed.c -+++ b/tabbed.c -@@ -57,7 +57,7 @@ typedef union { - - typedef struct { - unsigned int mod; -- KeySym keysym; -+ KeyCode keycode; - void (*func)(const Arg *); - const Arg arg; - } Key; -@@ -680,11 +680,9 @@ keypress(const XEvent *e) - { - const XKeyEvent *ev = &e->xkey; - unsigned int i; -- KeySym keysym; - -- keysym = XkbKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0, 0); - for (i = 0; i < LENGTH(keys); i++) { -- if (keysym == keys[i].keysym && -+ if (ev->keycode == keys[i].keycode && - CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) && - keys[i].func) - keys[i].func(&(keys[i].arg)); -@@ -721,7 +719,6 @@ manage(Window w) - int i, j, nextpos; - unsigned int modifiers[] = { 0, LockMask, numlockmask, - numlockmask | LockMask }; -- KeyCode code; - Client *c; - XEvent e; - -@@ -732,12 +729,10 @@ manage(Window w) - XSync(dpy, False); - - for (i = 0; i < LENGTH(keys); i++) { -- if ((code = XKeysymToKeycode(dpy, keys[i].keysym))) { -- for (j = 0; j < LENGTH(modifiers); j++) { -- XGrabKey(dpy, code, keys[i].mod | -- modifiers[j], w, True, -- GrabModeAsync, GrabModeAsync); -- } -+ for (j = 0; j < LENGTH(modifiers); ++j) { -+ XGrabKey(dpy, keys[i].keycode, -+ keys[i].mod | modifiers[j], w, -+ True, GrabModeAsync, GrabModeAsync); - } - } - diff --git a/tools.suckless.org/tabbed/patches/tabbed-keycode-20160702-bc23614.diff b/tools.suckless.org/tabbed/patches/tabbed-keycode-20160702-bc23614.diff @@ -0,0 +1,110 @@ +diff --git a/config.def.h b/config.def.h +index 989992c..821f481 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -36,31 +36,32 @@ static Bool npisrelative = False; + #define MODKEY ControlMask + static Key keys[] = { + /* modifier key function argument */ +- { MODKEY|ShiftMask, XK_Return, focusonce, { 0 } }, +- { MODKEY|ShiftMask, XK_Return, spawn, { 0 } }, +- { MODKEY, XK_t, spawn, SETPROP("_TABBED_SELECT_TAB") }, ++ { MODKEY|ShiftMask, 36, focusonce, { 0 } }, ++ { MODKEY|ShiftMask, 36, spawn, { 0 } }, ++ { MODKEY, 28, spawn, SETPROP("_TABBED_SELECT_TAB") }, + +- { MODKEY|ShiftMask, XK_l, rotate, { .i = +1 } }, +- { MODKEY|ShiftMask, XK_h, rotate, { .i = -1 } }, +- { MODKEY|ShiftMask, XK_j, movetab, { .i = -1 } }, +- { MODKEY|ShiftMask, XK_k, movetab, { .i = +1 } }, +- { MODKEY, XK_Tab, rotate, { .i = 0 } }, ++ { MODKEY|ShiftMask, 46, rotate, { .i = +1 } }, ++ { MODKEY|ShiftMask, 43, rotate, { .i = -1 } }, ++ { MODKEY|ShiftMask, 44, movetab, { .i = -1 } }, ++ { MODKEY|ShiftMask, 45, movetab, { .i = +1 } }, ++ { MODKEY, 23, rotate, { .i = 0 } }, + +- { MODKEY, XK_1, move, { .i = 0 } }, +- { MODKEY, XK_2, move, { .i = 1 } }, +- { MODKEY, XK_3, move, { .i = 2 } }, +- { MODKEY, XK_4, move, { .i = 3 } }, +- { MODKEY, XK_5, move, { .i = 4 } }, +- { MODKEY, XK_6, move, { .i = 5 } }, +- { MODKEY, XK_7, move, { .i = 6 } }, +- { MODKEY, XK_8, move, { .i = 7 } }, +- { MODKEY, XK_9, move, { .i = 8 } }, +- { MODKEY, XK_0, move, { .i = 9 } }, + +- { MODKEY, XK_q, killclient, { 0 } }, ++ { MODKEY, 10, move, { .i = 0 } }, ++ { MODKEY, 11, move, { .i = 1 } }, ++ { MODKEY, 12, move, { .i = 2 } }, ++ { MODKEY, 13, move, { .i = 3 } }, ++ { MODKEY, 14, move, { .i = 4 } }, ++ { MODKEY, 15, move, { .i = 5 } }, ++ { MODKEY, 16, move, { .i = 6 } }, ++ { MODKEY, 17, move, { .i = 7 } }, ++ { MODKEY, 18, move, { .i = 8 } }, ++ { MODKEY, 19, move, { .i = 9 } }, + +- { MODKEY, XK_u, focusurgent, { 0 } }, +- { MODKEY|ShiftMask, XK_u, toggle, { .v = (void*) &urgentswitch } }, ++ { MODKEY, 24, killclient, { 0 } }, + +- { 0, XK_F11, fullscreen, { 0 } }, ++ { MODKEY, 30, focusurgent, { .v = NULL } }, ++ { MODKEY|ShiftMask, 30, toggle, { .v = (void*) &urgentswitch } }, ++ ++ { 0, 95, fullscreen, { 0 } }, + }; +diff --git a/tabbed.c b/tabbed.c +index 9a44795..5e2b416 100644 +--- a/tabbed.c ++++ b/tabbed.c +@@ -58,7 +58,7 @@ typedef union { + + typedef struct { + unsigned int mod; +- KeySym keysym; ++ KeyCode keycode; + void (*func)(const Arg *); + const Arg arg; + } Key; +@@ -651,11 +651,9 @@ keypress(const XEvent *e) + { + const XKeyEvent *ev = &e->xkey; + unsigned int i; +- KeySym keysym; + +- keysym = XkbKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0, 0); + for (i = 0; i < LENGTH(keys); i++) { +- if (keysym == keys[i].keysym && ++ if (ev->keycode == keys[i].keycode && + CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) && + keys[i].func) + keys[i].func(&(keys[i].arg)); +@@ -692,7 +690,6 @@ manage(Window w) + int i, j, nextpos; + unsigned int modifiers[] = { 0, LockMask, numlockmask, + numlockmask | LockMask }; +- KeyCode code; + Client *c; + XEvent e; + +@@ -703,12 +700,10 @@ manage(Window w) + XSync(dpy, False); + + for (i = 0; i < LENGTH(keys); i++) { +- if ((code = XKeysymToKeycode(dpy, keys[i].keysym))) { +- for (j = 0; j < LENGTH(modifiers); j++) { +- XGrabKey(dpy, code, keys[i].mod | +- modifiers[j], w, True, +- GrabModeAsync, GrabModeAsync); +- } ++ for (j = 0; j < LENGTH(modifiers); ++j) { ++ XGrabKey(dpy, keys[i].keycode, ++ keys[i].mod | modifiers[j], w, ++ True, GrabModeAsync, GrabModeAsync); + } + } +