Compare commits

..

85 Commits

Author SHA1 Message Date
Sravan Balaji
af632efafb Parameter Adjustments
- Increase gap between windows to 15 pixels
- Decrease snap pixel to 10
- Make inactive window border color darker so active window is easier to distinguish
- Remove rules for GIMP and Firefox
2020-11-19 09:20:12 -05:00
Sravan Balaji
5130e64014 Replace deadd with xfce notifications
- Replace autostart and quit commands
- Remove deadd notification center script & keybinding
- Update man page
2020-11-06 21:02:41 -05:00
Sravan Balaji
48b71050ab Origin Floating Window
- Add rule to make origin open in a floating window
2020-11-06 21:02:41 -05:00
Sravan Balaji
c959e1cb58 Redshift Restart Fix
- Add redshift reset mode to autostart
- Move redshift-gtk to system tray application section of autoquit
- Add kill redshift background process to autoquit
2020-11-06 21:02:41 -05:00
Sravan Balaji
10b140adff Backlight Control
- Add support for brightness buttons to control screen brightness
- Update readme with link to acpilight
2020-11-06 21:02:41 -05:00
Sravan Balaji
fde880858a NVIDIA Optimus Manager
- Add optimus-manager-qt to autostart and autoquit scripts
2020-11-06 21:02:41 -05:00
Sravan Balaji
e896c3107e restartsig patch
- Apply restartsig patch
- Add keybinding for restarting dwm
- Update man page with keybinding
- Update README with patch link
2020-11-06 21:02:41 -05:00
Sravan Balaji
e7ece2aaba Autoquit Script & Autostart Consolidation
- Create autoquit script to end all autostarted processes on quit
- Move process from autostart_blocking to autostart
- Fix missing "\" in autostart
- Add runautoquit function to dwm.c
- Call runautoquit after run exits in dwm.c main
2020-11-06 21:02:41 -05:00
Sravan Balaji
7d5b1b38a2 cyclelayouts patch
- Apply cyclelayouts patch
- Add patch link to README
- Add new layout cycling keybindings to man page
2020-11-06 21:02:41 -05:00
Sravan Balaji
bfa185fac4 gridmode patch
- Apply gridmode patch
- Add patch link to README
- Add new layout keybinding to man page
2020-11-06 21:02:41 -05:00
Sravan Balaji
36e11cc61c centeredmaster patch
- Apply centeredmaster patch
- Add patch link to README
- Add new layout keybindings to man page
2020-11-06 21:02:41 -05:00
Sravan Balaji
3047114a1f ru_gaps Patch
- Add ru_gaps patch
- Increase border size to 3 pixels
- Set default gap size to 10 pixels
- Update README to include ru_gaps patch link & modifications
- Update man page to include keybindings for ru_gaps
2020-11-06 21:02:41 -05:00
Sravan Balaji
81f908b5c6 Screen Layout & Rclone fix
- Add screen layout script to autostart_blocking
- Fix rclone command in autostart
2020-11-06 21:02:41 -05:00
Sravan Balaji
795f7d0011 Fix Picom Not Starting
- Fix picom config path in autostart
2020-11-06 21:02:41 -05:00
Sravan Balaji
99a906d9e3 Flameshot Autostart & Shortcut
- Add flameshot to autostart script
- Bind print screen button to open flameshot gui
2020-11-06 21:02:41 -05:00
Sravan Balaji
8fe17768f7 Nerd Font, Icons, & Size Changes
- Change font to NotoSans Nerd Font
- Change font size to 10
- Change tag icons and add subscript numbers
2020-11-06 21:02:40 -05:00
Sravan Balaji
bd69540724 Switch from slock to LightDM
- Add background process for light-locker
- lockcmd uses light-locker-command
- sleepcmd uses systemctl suspend
2020-11-06 21:02:40 -05:00
Sravan Balaji
e4457dd31e Media Control
- Bind media track keys to control playerctl for play/pause, next, prev
- Update README with volume and media control
2020-11-06 21:02:40 -05:00
Sravan Balaji
5e3c442a2f Volume Control
- Bind volume control keys to control PuseAudio volume
2020-11-06 21:02:40 -05:00
Sravan Balaji
b788a08745 README Update
- Add list of personal modifications
2020-11-06 21:02:40 -05:00
Sravan Balaji
e9c7ebcddc slstatus
- Add slstatus to background processes to autostart
2020-11-06 21:02:40 -05:00
Sravan Balaji
699c83b6ff GNOME Polkit Authentication Agent
- Add startup background process for polkit agent
2020-11-06 21:02:40 -05:00
Sravan Balaji
5015cfc93b Merge All Autostart Applications & Blocking Processes into Master
- Ignore applications if they don't exist rather than having separate branches for desktop and laptop
- Re-organize scripts to define arrays and run applications with for loops
2020-11-06 21:02:40 -05:00
Sravan Balaji
485c40d5f9 Lock Screen & Sleep Shortcuts
- Add keybinding to lock screen with slock
- Add keybinding to lock screen and go to sleep with slock
2020-11-06 21:02:40 -05:00
Sravan Balaji
41958715d4 Apply movestack patch
- Add keybinds to switch window between master and slaves
- Add movestack.c
2020-11-06 21:02:40 -05:00
Sravan Balaji
5ac75bb689 deadd notification center shortcut
- Add shorcut for opening deadd notification center via bash script
2020-11-06 21:02:40 -05:00
Sravan Balaji
a60b1c5d2f Rofi Launcher w/ Greenclip Manager
- Add greenclip daemon to autostart
- Add background processes section to autostart
- Remove references to dmenu
- Add rofi run and clipboard shortcuts
- Update man page to reference rofi instead of dmenu
2020-11-06 21:02:40 -05:00
Sravan Balaji
0f49dbddfb Combo Tag & View Patches
- Add combo tag & view patch
- Change tag and view functions to combotag and comboview in config.h
2020-11-06 21:02:40 -05:00
Sravan Balaji
d194f2c726 KDE Connect
- Add KDE Connect system tray indicator to autostart
2020-11-06 21:02:40 -05:00
Sravan Balaji
2769ef11ad Redshift Tray Icon
- Move redshift from autostart_blocking to autostart
- Use redshift-gtk instead of redshift to get a tray icon
2020-11-06 21:02:40 -05:00
Sravan Balaji
8faf64215e Add Deadd Autostart
- Add deadd notification center to autostart
2020-11-06 21:02:40 -05:00
Sravan Balaji
c2fa943e86 Add Network Manager Autostart
- Add network manager applet to autostart
2020-11-06 21:02:40 -05:00
Sravan Balaji
eaf997ee88 Add Blueman Autostart
- Add Blueman tray application to autostart
2020-11-06 21:02:40 -05:00
Sravan Balaji
d0b1d46ed4 Autostart Background Fix
- Run autostart programs in background
- Add Nyrna to autostart
- Move system tray startup applications to top of autostart script
2020-11-06 21:02:40 -05:00
Sravan Balaji
4134edfc38 Startup Application
- Remove extra empty line from autostart_blocking.sh
- Add PulseAudio volume control as startup application
2020-11-06 21:02:40 -05:00
Sravan Balaji
5315d6ae96 Systemtray Patch
- Add system tray patch
2020-11-06 21:02:38 -05:00
Sravan Balaji
0a4ab3b407 Move rclone out of autostart_blocking
- Put rclone sync in autostart so dwm isn't prevented from starting
2020-11-06 21:01:45 -05:00
Sravan Balaji
cc1f6ffbc2 Specify Autostart Location, README & LICENSE updates, and Add config.h
- Remove config.h from gitignore
- Move config.def.h modifications to config.h
- Restore config.def.h to original version
- Specify location of autostart instead of searching certain locations
- Rename autostart.sh to autostart_blocking.sh
- Add myself to license
- Change README to markdown and add personal changes
2020-11-06 21:01:45 -05:00
Sravan Balaji
8531dc3158 Autostart Patch w/ Modifications
- Add autostart patch
- Include config directory in autostart search dirs
- Sync cloud drives
- Start compositor
- Restore wallpaper
- Start redshift for blue light filtering
2020-11-06 21:01:45 -05:00
Sravan Balaji
ab1c6e3d00 Increase Font & Replace Icons
- Change font size to 12
- Replace music icon with podcast and spotify icons
- Remove infinity icon
2020-11-06 21:01:45 -05:00
Sravan Balaji
84d1b45060 Font Size & Color Changes
- Change font sizes to 10
- Change active font color to background for contrast with accent color
2020-11-06 21:01:45 -05:00
Sravan Balaji
96163849d6 Dracula Theme & Icons
- Change border size to 2 pixels
- Add font awesome
- Change colors to follow dracula theme
- Add unicode icons for tags
2020-11-06 21:01:45 -05:00
Sravan Balaji
cbf3a73d72 gitignore & config changes
- Add gitignore for vscode folder, dwm executable, output files, and config.h
- Change mod key to super key
- Change terminal from st to alacritty
2020-11-06 21:01:45 -05:00
Ian Remmler
61bb8b2241 Fix x coordinate calculation in buttonpress. 2020-08-21 16:13:22 +02:00
Hiltjo Posthuma
bb2e7222ba dwm.1: fix wrong text in man page 2020-07-08 18:05:50 +02:00
Alex Flierl
f04cac6d6e Fix memory leaks in drw
The function drw_fontset_free in drw.c was never called.
2020-06-11 18:32:21 +02:00
bakkeby
f09418bbb6 dwm crashes when opening 50+ clients (tile layout)
Many users new to dwm find themselves caught out by being kicked out to the login manager (dwm crashing) when they open 50+ clients for demonstration purposes. The number of clients reported varies depending on the resolution of the monitor.

The cause of this is due to how the default tile layout calculates the height of the next client based on the position of the previous client. Because clients have a minimum size the (ty) position can exceed that of the window height, resulting in (m->wh - ty) becoming negative. The negative height stored as an unsigned int results in a very large height ultimately resulting in dwm crashing.

This patch adds safeguards to prevent the ty and my positions from exceeding that of the window height.
2020-04-25 13:31:02 +02:00
Chris Down
ed3ab6b4fc drawbar: Don't shadow sw global
This jarred me a bit while reading the code, since "sw" usually refers
to the global screen geometry, but in drawbar() only it refers to
text-related geometry. Renaming it makes it more obvious that these are
not related.
2020-04-22 20:33:39 +02:00
Chris Down
f087d20e6e getatomprop: Add forward declaration
No functional changes, but for every other function we have a forward
declaration here. getatomprop should be no exception.
2020-04-22 20:33:26 +02:00
Chris Down
a8e9513783 setmfact: Unify bounds for compile-time and runtime mfact
There are two places that mfact can be set:

- In the mfact global, which is defined at compile time and passed
  into m->mfact during monitor setup. No bounds checks are performed,
  but the comment alongside it says that valid values are [0.05..0.95]:

      static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */

- By setmfact, which adjusts m->mfact at runtime. It also does some
  minimum and maximum bounds checks, allowing [0.1..0.9]. Values outside
  of that range are ignored, and mfact is not adjusted.

These different thresholds mean that one cannot setmfact 0.95 or 0.05,
despite the comment above that lists the legal range for mfact.

Clarify this by enforcing the same bounds in setmfact at runtime as
those listed for mfact at compile time.
2020-04-20 17:56:41 +02:00
Hiltjo Posthuma
c82db690cc config.mk: fix POSIX_C_SOURCE macro for feature test for snprintf()
The feature test was incorrect:
_POSIX_C_SOURCE=2

"The value 2 or greater additionally exposes definitions for POSIX.2-1992."
http://man7.org/linux/man-pages/man7/feature_test_macros.7.html

A higher value is needed (atleast 1995):
https://pubs.opengroup.org/onlinepubs/9699919799/functions/snprintf.html

FreeBSD feature test macro:
on
https://github.com/freebsd/freebsd/blob/master/include/stdio.h line 297

This was already fixed in dmenu.

This fixes a warning on FreeBSD, reported by Plasmoduck on IRC, thanks.
2020-04-03 15:36:32 +02:00
Anselm R Garbe
cb3f58ad06 Prepare 6.2 release. 2019-02-02 04:50:42 -08:00
Hiltjo Posthuma
b69c870a30 pledge: add rpath promise for the ugly Xft font fallback 2018-06-02 17:15:42 +02:00
Hiltjo Posthuma
e78b4a9207 Makefile: just show the compiler output
Don't be fancy and just show the actual output so debugging is simpler.
2018-06-02 17:10:28 +02:00
Klemens Nanni
3cd4023fb3 Do not strip at link stage
Building with debug symbols is worthless unless LDFLAGS are manually
adjusted as well.
2018-06-02 16:56:10 +02:00
Klemens Nanni
f40f86fa87 Pledge on OpenBSD 2018-05-25 11:49:30 +02:00
Hiltjo Posthuma
c3a2e016bb config.def.h: ClkTagBar missing from comment
by Christopher Drelich <cd@cdrakka.com>

Patch was mangled on the ML, also adjusted the order to be the same as
the enum in dwm.c
2018-05-25 06:56:36 +02:00
Christopher Drelich
c8e9479186 Function declarations in correct order.
In dwm.c function declarations are in alphabetical order except for
updategeom(). There doesn't appear to be any reason for this, so this
patch corrects that, and now all function declarations are in
alphabetical order.
2018-05-12 19:19:20 +02:00
Hiltjo Posthuma
10dfa65860 remove old TODO and BUGS entries
the bug in the dwm man page is an (ancient) Java issue.

Thanks David and quinq for the patches and feedback!
2018-05-12 19:14:19 +02:00
Hiltjo Posthuma
3bd8466e93 update README: remove mentioning the old dextra repo
Thanks Christopher Drelich <cd@cdrakka.com>
2018-03-14 21:03:11 +01:00
Christopher Drelich
76c8c16d79 All functions in alphabetical order except for this one. 2018-03-14 21:02:06 +01:00
Christopher Drelich
3cb34830eb ColBorder has been moved to the enum with ColFg and ColBg. 2018-03-14 17:46:48 +01:00
Hiltjo Posthuma
db2236001c dont NUL terminate _NET_WM_NAME
Reported by Kernc, thanks!

"This makes a particular program that uses libwnck [1] fail after:

    Wnck-WARNING **: Property _NET_WM_NAME contained invalid UTF-8

in this code [2] because the returned string contains a '\0' and the
documentation for g_utf8_validate() [3] explicitly states that when
string length is provided, no nul bytes are allowed."

It is not entirely clear it is incorrect, other WM's seem to not
NUL terminate it either though.
2017-12-27 13:36:53 +01:00
Hiltjo Posthuma
3756f7f6b8 sync dmenu drw.{c,h} code: use Clr* (was Scm) 2017-11-03 21:20:48 +01:00
Hiltjo Posthuma
99f78fa553 gettextprop: check result of XGetTextProperty (undefined behaviour for XFree) 2017-11-03 21:14:58 +01:00
Omar Sandoval
a9b6a312a7 Set class name on status bar
This is useful for configuring compositors to ignore the status bar
window.
2017-11-03 20:40:34 +01:00
Daniel Cousens
6aa8e37efe simplify isfixed conditions 2017-10-11 09:46:28 +02:00
Anselm R Garbe
ceac8c91ff yet another cleanup
The previous patches introduced some unclean space-based indentation
patterns. This patch fixes them.
2017-05-08 21:08:27 +02:00
Markus Teich
5b238c8dab Don't restrict snap in mousemove
This also fixes a bug where client windows only switch to floating mode when the
mouse is dragged in one specific direction.
2017-03-28 20:23:38 +02:00
Markus Teich
022d076054 Button passthrough when client is not focused
Before this change it is not possible to press a button in a client on the first
click if the client is not yet focused. The first click on the button would
only focus the client and a second click on the button is needed to activate it.
This situation can occur when moving the mouse over a client (therefore focusing
it) and then moving the focus to another client with keyboard shortcuts.

After this commit the behavior is fixed and button presses on unfocused clients
are passed to the client correctly.
2017-03-28 20:23:34 +02:00
Markus Teich
2952b68db8 cleanup
- unify multi-line expression alignment style.
- unify multi-line function call alignment style.
- simplify client moving on monitor count decrease.
- clarify comment for focusin().
- remove old confusing comment about input focus fix in focusmon(). The
  explanation is already in the old commit message, so no need to keep it in the
  code.
- remove old comment describing even older state of the code in focus().
- unify comment style.
- break up some long lines.
- fix some typos and grammar.
2017-03-28 20:23:28 +02:00
Anselm R Garbe
bb3bd6fec3 applied Markus' tagset purge of alternative view on _NET_ACTIVE_WINDOW event 2016-12-05 10:16:46 +01:00
Anselm R Garbe
e63bf22948 applied Ivan Delalande's NET_SUPPORTING_WM_CHECK patch for gtk3 compatibility 2016-12-05 10:09:49 +01:00
Anselm R Garbe
5376947571 applied Ian Remmler's man page adjustment suggestions 2016-12-05 10:05:00 +01:00
Anselm R Garbe
975c898376 applied Markus' decouple color-scheme patch 2016-12-05 10:01:33 +01:00
Anselm R Garbe
a137a86a23 applied Markus' clarify status text padding patch 2016-12-05 09:54:20 +01:00
Quentin Rameau
839c7f6939 LICENSE: update people 2016-11-15 17:35:33 +01:00
Quentin Rameau
7a59cd1457 dwm.1: add keybinding for spawning dmenu 2016-11-15 17:35:30 +01:00
Hiltjo Posthuma
24849acada die() on calloc failure
thanks Markus Teich and David!
2016-11-05 11:34:52 +01:00
Hiltjo Posthuma
ab9571bbc5 die() consistency: always add newline 2016-08-12 14:36:35 +02:00
Hiltjo Posthuma
56a31dc4a7 config.def.h: style improvement, use color Scheme enum 2016-06-28 18:04:56 +02:00
Markus Teich
7af4d439bd import new drw from libsl and minor fixes.
- better scaling for occupied tag squares.
- draw statusline first to omitt some complicated calculations.
2016-06-26 13:52:36 +02:00
Eric Pruitt
cd2d7549b3 Configure geometry before applying rules
Configuring geometry before applying rules makes it possible to have
more complex constraints in applyrules that depend on the initial window
dimensions and location.
2016-06-24 05:38:58 +02:00
Hiltjo Posthuma
3465bed290 fix fullscreen clients not resized on X display resolution change
patch provided by Bert Münnich <ber.t_AT_posteo.de>, thanks!
2015-12-19 20:25:26 +01:00
Quentin Rameau
4ec3a673ff Shut up glibc about _BSD_SOURCE being deprecated 2015-12-19 20:20:26 +01:00
20 changed files with 1633 additions and 525 deletions

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
.vscode/
*.o
dwm

44
BUGS
View File

@@ -1,44 +0,0 @@
---
18:17 < Biolunar> when i change my resolution in dwm (to a smaller one) and then back to the native, the top bar is not repainted. that's since 5.7.2, in 5.6 it worked fine
18:19 < Biolunar> is it just happening to me or a (known) bug?
18:24 < Biolunar> and in addition, mplayers fullscreen is limited to the small resolution after i changed it back to the native
reproducible with xrandr -s but not with --output and --mode, strange
---
yet another corner case:
open a terminal, focus another monitor, but without moving the mouse
pointer there
if there is no client on the other monitor to get the focus, then the
terminal will be unfocused but it will accept input
---
Donald Allen reported this:
starting emacs from dmenu in archlinux results in missing configure of emacs, but mod1-space or mod1-shift-space fix this problem. this problem is new and did not happen in 1.6 xorg servers
---
voltaic reports this:
When I use two monitors, one larger in resolution than the other, the
bar is drawn using the smaller x-dimension on both screens. I think
what's happening is that there are two bars drawn, but the short bar
is always on top of the long bar such that I can't see the information
under the short bar. If I switch to the small screen, hide the short
bar, and then switch to the large screen, the long bar is drawn
correctly.
A similar problem occurs when I have started dwm on a small resolution
monitor (laptop screen) and then I switch to a large external display.
When I do this, the bar itself is drawn for the original smaller
resolution, but the information to be printed on the bar is
right-aligned for a longer bar. So what I see is a bar that has the
right hand side of it cut-off. See attached screenshot.
I am using standard options for xrandr such as --output VGA1 --auto, etc.
---

19
LICENSE
View File

@@ -1,18 +1,23 @@
MIT/X Consortium License MIT/X Consortium License
© 2006-2014 Anselm R Garbe <anselm@garbe.us> © 2006-2019 Anselm R Garbe <anselm@garbe.ca>
© 2010-2014 Hiltjo Posthuma <hiltjo@codemadness.org>
© 2007-2011 Peter Hartlich <sgkkr at hartlich dot com>
© 2010-2011 Connor Lane Smith <cls@lubutu.com>
© 2006-2009 Jukka Salmi <jukka at salmi dot ch> © 2006-2009 Jukka Salmi <jukka at salmi dot ch>
© 2007-2009 Premysl Hruby <dfenze at gmail dot com> © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
© 2007-2011 Peter Hartlich <sgkkr at hartlich dot com>
© 2007-2009 Szabolcs Nagy <nszabolcs at gmail dot com> © 2007-2009 Szabolcs Nagy <nszabolcs at gmail dot com>
© 2007-2009 Christof Musik <christof at sendfax dot de> © 2007-2009 Christof Musik <christof at sendfax dot de>
© 2009 Mate Nagy <mnagy at port70 dot net> © 2007-2009 Premysl Hruby <dfenze at gmail dot com>
© 2007-2008 Enno Gottox Boland <gottox at s01 dot de> © 2007-2008 Enno Gottox Boland <gottox at s01 dot de>
© 2008 Martin Hurton <martin dot hurton at gmail dot com> © 2008 Martin Hurton <martin dot hurton at gmail dot com>
© 2008 Neale Pickett <neale dot woozle dot org> © 2008 Neale Pickett <neale dot woozle dot org>
© 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com> © 2009 Mate Nagy <mnagy at port70 dot net>
© 2010-2016 Hiltjo Posthuma <hiltjo@codemadness.org>
© 2010-2012 Connor Lane Smith <cls@lubutu.com>
© 2011 Christoph Lohmann <20h@r-36.net>
© 2015-2016 Quentin Rameau <quinq@fifth.space>
© 2015-2016 Eric Pruitt <eric.pruitt@gmail.com>
© 2016-2017 Markus Teich <markus.teich@stusta.mhn.de>
© 2020 Sravan Balaji <balajsra@umich.edu>
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),

View File

@@ -15,46 +15,37 @@ options:
@echo "CC = ${CC}" @echo "CC = ${CC}"
.c.o: .c.o:
@echo CC $< ${CC} -c ${CFLAGS} $<
@${CC} -c ${CFLAGS} $<
${OBJ}: config.h config.mk ${OBJ}: config.h config.mk
config.h: config.h:
@echo creating $@ from config.def.h cp config.def.h $@
@cp config.def.h $@
dwm: ${OBJ} dwm: ${OBJ}
@echo CC -o $@ ${CC} -o $@ ${OBJ} ${LDFLAGS}
@${CC} -o $@ ${OBJ} ${LDFLAGS}
clean: clean:
@echo cleaning rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz
@rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz
dist: clean dist: clean
@echo creating dist tarball mkdir -p dwm-${VERSION}
@mkdir -p dwm-${VERSION} cp -R LICENSE Makefile README config.def.h config.mk\
@cp -R LICENSE TODO BUGS Makefile README config.def.h config.mk \
dwm.1 drw.h util.h ${SRC} dwm.png transient.c dwm-${VERSION} dwm.1 drw.h util.h ${SRC} dwm.png transient.c dwm-${VERSION}
@tar -cf dwm-${VERSION}.tar dwm-${VERSION} tar -cf dwm-${VERSION}.tar dwm-${VERSION}
@gzip dwm-${VERSION}.tar gzip dwm-${VERSION}.tar
@rm -rf dwm-${VERSION} rm -rf dwm-${VERSION}
install: all install: all
@echo installing executable file to ${DESTDIR}${PREFIX}/bin mkdir -p ${DESTDIR}${PREFIX}/bin
@mkdir -p ${DESTDIR}${PREFIX}/bin cp -f dwm ${DESTDIR}${PREFIX}/bin
@cp -f dwm ${DESTDIR}${PREFIX}/bin chmod 755 ${DESTDIR}${PREFIX}/bin/dwm
@chmod 755 ${DESTDIR}${PREFIX}/bin/dwm mkdir -p ${DESTDIR}${MANPREFIX}/man1
@echo installing manual page to ${DESTDIR}${MANPREFIX}/man1 sed "s/VERSION/${VERSION}/g" < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1
@mkdir -p ${DESTDIR}${MANPREFIX}/man1 chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1
@sed "s/VERSION/${VERSION}/g" < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1
@chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1
uninstall: uninstall:
@echo removing executable file from ${DESTDIR}${PREFIX}/bin rm -f ${DESTDIR}${PREFIX}/bin/dwm\
@rm -f ${DESTDIR}${PREFIX}/bin/dwm ${DESTDIR}${MANPREFIX}/man1/dwm.1
@echo removing manual page from ${DESTDIR}${MANPREFIX}/man1
@rm -f ${DESTDIR}${MANPREFIX}/man1/dwm.1
.PHONY: all options clean dist install uninstall .PHONY: all options clean dist install uninstall

51
README
View File

@@ -1,51 +0,0 @@
dwm - dynamic window manager
============================
dwm is an extremely fast, small, and dynamic window manager for X.
Requirements
------------
In order to build dwm you need the Xlib header files.
Installation
------------
Edit config.mk to match your local setup (dwm is installed into
the /usr/local namespace by default).
Afterwards enter the following command to build and install dwm (if
necessary as root):
make clean install
If you are going to use the default bluegray color scheme it is highly
recommended to also install the bluegray files shipped in the dextra package.
Running dwm
-----------
Add the following line to your .xinitrc to start dwm using startx:
exec dwm
In order to connect dwm to a specific display, make sure that
the DISPLAY environment variable is set correctly, e.g.:
DISPLAY=foo.bar:1 exec dwm
(This will start dwm on display :1 of the host foo.bar.)
In order to display status info in the bar, you can do something
like this in your .xinitrc:
while xsetroot -name "`date` `uptime | sed 's/.*,//'`"
do
sleep 1
done &
exec dwm
Configuration
-------------
The configuration of dwm is done by creating a custom config.h
and (re)compiling the source code.

79
README.md Normal file
View File

@@ -0,0 +1,79 @@
# Sravan's dwm - dynamic window manager
[dwm](https://dwm.suckless.org/) is an extremely fast, small, and dynamic window manager for X.
This is Sravan's fork of dwm with patches and custom modifications.
## dwm Information
### Requirements
In order to build dwm you need the Xlib header files.
### Installation
Edit config.mk to match your local setup (dwm is installed into
the /usr/local namespace by default).
Afterwards enter the following command to build and install dwm (if
necessary as root):
make clean install
### Running dwm
Add the following line to your .xinitrc to start dwm using startx:
exec dwm
In order to connect dwm to a specific display, make sure that
the DISPLAY environment variable is set correctly, e.g.:
DISPLAY=foo.bar:1 exec dwm
(This will start dwm on display :1 of the host foo.bar.)
In order to display status info in the bar, you can do something
like this in your .xinitrc:
while xsetroot -name "`date` `uptime | sed 's/.*,//'`"
do
sleep 1
done &
exec dwm
### Configuration
The configuration of dwm is done by creating a custom config.h
and (re)compiling the source code.
## Personal Modifications
### Patches
* [autostart](https://dwm.suckless.org/patches/autostart/)
* [centeredmaster](https://dwm.suckless.org/patches/centeredmaster/)
* [combo](https://dwm.suckless.org/patches/combo/)
* [cyclelayouts](https://dwm.suckless.org/patches/cyclelayouts/)
* [gridmode](https://dwm.suckless.org/patches/gridmode/)
* [movestack](https://dwm.suckless.org/patches/movestack/)
* [restartsig](https://dwm.suckless.org/patches/restartsig/)
* [ru_gaps](https://dwm.suckless.org/patches/ru_gaps/)
* [systray](https://dwm.suckless.org/patches/systray/)
### Modifications
* Change mod key to super key (windows key)
* Change terminal from st to alacritty
* Change colors to follow [Dracula](https://draculatheme.com) theme
* Increase border to 3 pixels
* Set default gap size to 10 pixels
* Change tags to be [Font Awesome](https://fontawesome.com) icons
* Run programs and processes on autostart
* [Pulse Audio Volume Control](https://gist.github.com/palopezv/efd34059af6126ad970940bcc6a90f2e)
* Media Play/Pause, Prev, and Next Keybindings via [Playerctl](https://github.com/altdesktop/playerctl)
* Arch Community Repo: [playerctl](https://www.archlinux.org/packages/community/x86_64/playerctl/)
* Use [light-locker](https://github.com/the-cavalry/light-locker) to lock screen with [LightDM](https://github.com/canonical/lightdm)
* Arch Community Repo: [lightdm](https://www.archlinux.org/packages/extra/x86_64/lightdm/)
* Arch Community Repo: [light-locker](https://www.archlinux.org/packages/community/x86_64/light-locker/)
* Brightness Increase and Decrease Keybindings via [acpilight](https://gitlab.com/wavexx/acpilight)
* Arch Community Repo: [acpilight](https://www.archlinux.org/packages/community/any/acpilight/)

4
TODO
View File

@@ -1,4 +0,0 @@
- add a flag to Key to execute the command on release (needed for commands
affecting the keyboard grab, see scrot -s for example)
- add updategeom() hook for external tools like dzen
- consider onscreenkeyboard hooks for tablet deployment

53
autoquit.sh Executable file
View File

@@ -0,0 +1,53 @@
#!/bin/bash
########################
# Startup Applications #
########################
# List of applications to kill on exit
declare -a applications_array=(\
# System Tray Applications
"volctl" \ # PulseAudio Volume Control
"nyrna" \ # Nyrna Application Suspend
"blueman-tray" \ # Blueman Bluetooth Manager
"nm-applet" \ # Network Manager Applet
"kdeconnect-indi" \ # KDE Connect
"flameshot" \ # Flameshot Screenshot Tool
"redshift-gtk" \ # Redshift Blue Light Filter
# Background Processes
"picom" \ # Picom Compositor
"xfce4-notifyd" \ # Xfce Notification Daemon
"greenclip" \ # Greenclip Clipboard Manager
"redshift" \ # Redshift Blue Light Filter
"polkit-gnome-au" \ # GNOME Polkit Authentication Agent
"slstatus" \ # slstatus status bar
"light-locker" \ # LightDM Locker
# Hardware Driver Applications
"solaar" \ # Logitech Mouse Driver
"polychromatic-t" \ # Razer Keyboard Customization
"optimus-manager" \ # Optimus Manager Qt
)
# Kill applications
for i in "${applications_array[@]}"
do
pkill -9 $i &
done
#####################
# Cloud Drive Rsync #
#####################
# Local cloud storage directory
local_clone_dir="$HOME/Cloud"
# List of remotes as defined in rclone
declare -a remote_array=(\
"OneDrive - Personal" \
"Google Drive - Personal" \
)
# Unmount Remotes
for i in "${remote_array[@]}"
do
local_path="$local_clone_dir"/"$i"
fusermount -u "$local_path" &
done

62
autostart.sh Executable file
View File

@@ -0,0 +1,62 @@
#!/bin/bash
########################
# Startup Applications #
########################
# List of applications to run on start
declare -a applications_array=(\
# System Restore Processes
"bash /home/sravan/.screenlayout/default-screen-layout.sh" \ # Restore default screen layout
"nitrogen --restore" \ # Restore wallpaper
# System Tray Applications
"volctl" \ # PulseAudio Volume Control
"nyrna" \ # Nyrna Application Suspend
"blueman-tray" \ # Blueman Bluetooth Manager
"nm-applet" \ # Network Manager Applet
"kdeconnect-indicator" \ # KDE Connect
"flameshot" \ # Flameshot Screenshot Tool
# Background Processes
"picom --config /home/sravan/.config/picom/picom.conf" \ # Picom Compositor
"/usr/lib/xfce4/notifyd/xfce4-notifyd" \ # Xfce Notification Daemon
"greenclip daemon" \ # Greenclip Clipboard Manager
"redshift -x" \ # Reset redshift display gamma
"redshift-gtk" \ # Redshift Blue Light Filter
"/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1" \ # GNOME Polkit Authentication Agent
"slstatus" \ # slstatus status bar
"light-locker --lock-on-suspend --lock-on-lid" \ # LightDM Locker
# Hardware Driver Applications
"solaar --window=hide" \ # Logitech Mouse Driver
"polychromatic-tray-applet" \ # Razer Keyboard Customization
"optimus-manager-qt" \ # Optimus Manager Qt
)
# Run applications (ignore if they don't exist)
for i in "${applications_array[@]}"
do
if ! command -v $i > /dev/null
then
do_nothing() { :; }
else
$i &
fi
done
#####################
# Cloud Drive Rsync #
#####################
# Local cloud storage directory
local_clone_dir="$HOME/Cloud"
# List of remotes as defined in rclone
declare -a remote_array=(\
"OneDrive - Personal" \
"Google Drive - Personal" \
)
# Mount Remotes
for i in "${remote_array[@]}"
do
local_path="$local_clone_dir"/"$i"
mkdir -p "$local_path"
rclone mount "$i": "$local_path" &
done

View File

@@ -1,20 +1,22 @@
/* See LICENSE file for copyright and license details. */ /* See LICENSE file for copyright and license details. */
/* appearance */ /* appearance */
static const char *fonts[] = {
"monospace:size=10"
};
static const char dmenufont[] = "monospace:size=10";
static const char normbordercolor[] = "#444444";
static const char normbgcolor[] = "#222222";
static const char normfgcolor[] = "#bbbbbb";
static const char selbordercolor[] = "#005577";
static const char selbgcolor[] = "#005577";
static const char selfgcolor[] = "#eeeeee";
static const unsigned int borderpx = 1; /* border pixel of windows */ static const unsigned int borderpx = 1; /* border pixel of windows */
static const unsigned int snap = 32; /* snap pixel */ static const unsigned int snap = 32; /* snap pixel */
static const int showbar = 1; /* 0 means no bar */ static const int showbar = 1; /* 0 means no bar */
static const int topbar = 1; /* 0 means bottom bar */ static const int topbar = 1; /* 0 means bottom bar */
static const char *fonts[] = { "monospace:size=10" };
static const char dmenufont[] = "monospace:size=10";
static const char col_gray1[] = "#222222";
static const char col_gray2[] = "#444444";
static const char col_gray3[] = "#bbbbbb";
static const char col_gray4[] = "#eeeeee";
static const char col_cyan[] = "#005577";
static const char *colors[][3] = {
/* fg bg border */
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
[SchemeSel] = { col_gray4, col_cyan, col_cyan },
};
/* tagging */ /* tagging */
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
@@ -54,7 +56,7 @@ static const Layout layouts[] = {
/* commands */ /* commands */
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL }; 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 }; static const char *termcmd[] = { "st", NULL };
static Key keys[] = { static Key keys[] = {
@@ -95,7 +97,7 @@ static Key keys[] = {
}; };
/* button definitions */ /* button definitions */
/* click can be ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ /* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
static Button buttons[] = { static Button buttons[] = {
/* click event mask button function argument */ /* click event mask button function argument */
{ ClkLtSymbol, 0, Button1, setlayout, {0} }, { ClkLtSymbol, 0, Button1, setlayout, {0} },

164
config.h Normal file
View File

@@ -0,0 +1,164 @@
/* See LICENSE file for copyright and license details. */
/* includes */
#include <X11/XF86keysym.h>
#include "movestack.c"
/* appearance */
static const unsigned int borderpx = 3; /* border pixel of windows */
static const int gappx = 15; /* gaps between windows */
static const unsigned int snap = 10; /* 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[] = { "NotoSans Nerd Font:size=10" };
static const char col_gray1[] = "#282a36"; /* background color */
static const char col_gray2[] = "#44475a"; /* inactive window border color */
static const char col_gray3[] = "#f8f8f2"; /* font color */
static const char col_gray4[] = "#282a36"; /* current tag and current window font color */
static const char col_cyan[] = "#bd93f9"; /* Top bar second color and active window border color */
static const char *colors[][3] = {
/* fg bg border */
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
[SchemeSel] = { col_gray4, col_cyan, col_cyan },
};
/* tagging */
static const char *tags[] = { " ₁", "龎 ₂", " ₃", " ₄", "爵 ₅", " ₆", " ₇", " ₈", " ₉" };
static const Rule rules[] = {
/* xprop(1):
* WM_CLASS(STRING) = instance, class
* WM_NAME(STRING) = title
*/
/* class instance title tags mask isfloating monitor */
{ "origin", NULL, NULL, 0, 1, -1 },
};
/* layout(s) */
static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */
static const int nmaster = 1; /* number of clients in master area */
static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
#include "layouts.c"
static const Layout layouts[] = {
/* symbol arrange function */
{ "[]=", tile }, /* first entry is default */
{ "><>", NULL }, /* no layout function means floating behavior */
{ "[M]", monocle },
{ "|M|", centeredmaster },
{ ">M>", centeredfloatingmaster },
{ "HHH", grid },
{ NULL, NULL },
};
/* key definitions */
#define MODKEY Mod4Mask /* Mod1Mask = Alt, Mod4Mask = Super */
#define TAGKEYS(KEY,TAG) \
{ MODKEY, KEY, comboview, {.ui = 1 << TAG} }, \
{ MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
{ MODKEY|ShiftMask, KEY, combotag, {.ui = 1 << TAG} }, \
{ MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
/* configuration parameters */
static const char rootdir[] = "/home/sravan/.config"; /* Location of dwm source code */
/* commands */
static const char *rofiruncmd[] = { "rofi", "-show", "drun", NULL };
static const char *roficlipcmd[] = { "rofi", "-show", "clipboard", NULL };
static const char *lockcmd[] = { "light-locker-command", "--lock", NULL };
static const char *sleepcmd[] = { "systemctl", "suspend", NULL };
static const char *termcmd[] = { "alacritty", NULL };
static const char *upvolcmd[] = { "/usr/bin/pactl", "set-sink-volume", "@DEFAULT_SINK@", "+1%", NULL };
static const char *downvolcmd[] = { "/usr/bin/pactl", "set-sink-volume", "@DEFAULT_SINK@", "-1%", NULL };
static const char *mutevolcmd[] = { "/usr/bin/pactl", "set-sink-mute", "@DEFAULT_SINK@", "toggle", NULL };
static const char *brightness_up[] = { "xbacklight", "-inc", "1", NULL };
static const char *brightness_down[] = { "xbacklight", "-dec", "1", NULL };
static const char *playerplaypausecmd[] = { "playerctl", "--player=playerctld", "play-pause", NULL };
static const char *playernextcmd[] = { "playerctl", "--player=playerctld", "next", NULL };
static const char *playerprevcmd[] = { "playerctl", "--player=playerctld", "previous", NULL };
static const char *flameshotcmd[] = { "flameshot", "gui", NULL };
/* key definitions */
static Key keys[] = {
/* modifier key function argument */
{ MODKEY, XK_p, spawn, {.v = rofiruncmd} },
{ MODKEY, XK_c, spawn, {.v = roficlipcmd} },
{ MODKEY|ShiftMask, XK_l, spawn, {.v = lockcmd} },
{ MODKEY|ShiftMask, XK_s, spawn, {.v = sleepcmd} },
{ 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|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} },
{ 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_g, setlayout, {.v = &layouts[5]} },
{ MODKEY|ControlMask, XK_comma, cyclelayout, {.i = -1 } },
{ MODKEY|ControlMask, XK_period, cyclelayout, {.i = +1 } },
{ 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} },
{ MODKEY, XK_minus, setgaps, {.i = -5 } },
{ MODKEY, XK_equal, setgaps, {.i = +5 } },
{ MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } },
{ 0, XF86XK_AudioLowerVolume, spawn, {.v = downvolcmd} },
{ 0, XF86XK_AudioMute, spawn, {.v = mutevolcmd} },
{ 0, XF86XK_AudioRaiseVolume, spawn, {.v = upvolcmd} },
{ 0, XF86XK_MonBrightnessUp, spawn, {.v = brightness_up} },
{ 0, XF86XK_MonBrightnessDown, spawn, {.v = brightness_down} },
{ 0, XF86XK_AudioPlay, spawn, {.v = playerplaypausecmd} },
{ 0, XF86XK_AudioNext, spawn, {.v = playernextcmd} },
{ 0, XF86XK_AudioPrev, spawn, {.v = playerprevcmd} },
{ 0, XK_Print, spawn, {.v = flameshotcmd} },
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} },
{ MODKEY|ControlMask|ShiftMask, XK_q, quit, {1} },
};
/* button definitions */
/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
static Button buttons[] = {
/* click event mask button function argument */
{ ClkLtSymbol, 0, Button1, setlayout, {0} },
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
{ ClkWinTitle, 0, Button2, zoom, {0} },
{ ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} },
{ ClkTagBar, 0, Button1, view, {0} },
{ ClkTagBar, 0, Button3, toggleview, {0} },
{ ClkTagBar, MODKEY, Button1, tag, {0} },
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
};

View File

@@ -1,5 +1,5 @@
# dwm version # dwm version
VERSION = 6.1 VERSION = 6.2
# Customize below to fit your system # Customize below to fit your system
@@ -25,10 +25,10 @@ INCS = -I${X11INC} -I${FREETYPEINC}
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
# flags # flags
CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} #CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS} CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS}
LDFLAGS = -s ${LIBS} LDFLAGS = ${LIBS}
# Solaris # Solaris
#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\" #CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"

274
drw.c
View File

@@ -63,9 +63,8 @@ utf8decode(const char *c, long *u, size_t clen)
Drw * 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)
{ {
Drw *drw; Drw *drw = ecalloc(1, sizeof(Drw));
drw = ecalloc(1, sizeof(Drw));
drw->dpy = dpy; drw->dpy = dpy;
drw->screen = screen; drw->screen = screen;
drw->root = root; drw->root = root;
@@ -73,7 +72,6 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h
drw->h = h; drw->h = h;
drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen)); drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
drw->gc = XCreateGC(dpy, root, 0, NULL); drw->gc = XCreateGC(dpy, root, 0, NULL);
drw->fontcount = 0;
XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
return drw; return drw;
@@ -82,6 +80,9 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h
void void
drw_resize(Drw *drw, unsigned int w, unsigned int h) drw_resize(Drw *drw, unsigned int w, unsigned int h)
{ {
if (!drw)
return;
drw->w = w; drw->w = w;
drw->h = h; drw->h = h;
if (drw->drawable) if (drw->drawable)
@@ -92,84 +93,70 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h)
void void
drw_free(Drw *drw) drw_free(Drw *drw)
{ {
size_t i;
for (i = 0; i < drw->fontcount; i++)
drw_font_free(drw->fonts[i]);
XFreePixmap(drw->dpy, drw->drawable); XFreePixmap(drw->dpy, drw->drawable);
XFreeGC(drw->dpy, drw->gc); XFreeGC(drw->dpy, drw->gc);
drw_fontset_free(drw->fonts);
free(drw); free(drw);
} }
/* This function is an implementation detail. Library users should use /* This function is an implementation detail. Library users should use
* drw_font_create instead. * drw_fontset_create instead.
*/ */
static Fnt * static Fnt *
drw_font_xcreate(Drw *drw, const char *fontname, FcPattern *fontpattern) xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
{ {
Fnt *font; Fnt *font;
XftFont *xfont = NULL; XftFont *xfont = NULL;
FcPattern *pattern = NULL; FcPattern *pattern = NULL;
if (fontname) { if (fontname) {
/* Using the pattern found at font->xfont->pattern does not yield same /* Using the pattern found at font->xfont->pattern does not yield the
* the same substitution results as using the pattern returned by * same substitution results as using the pattern returned by
* FcNameParse; using the latter results in the desired fallback * FcNameParse; using the latter results in the desired fallback
* behaviour whereas the former just results in * behaviour whereas the former just results in missing-character
* missing-character-rectangles being drawn, at least with some fonts. * rectangles being drawn, at least with some fonts. */
*/
if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) { if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) {
fprintf(stderr, "error, cannot load font: '%s'\n", fontname); fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname);
return NULL; return NULL;
} }
if (!(pattern = FcNameParse((FcChar8 *) fontname))) { if (!(pattern = FcNameParse((FcChar8 *) fontname))) {
fprintf(stderr, "error, cannot load font: '%s'\n", fontname); fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname);
XftFontClose(drw->dpy, xfont); XftFontClose(drw->dpy, xfont);
return NULL; return NULL;
} }
} else if (fontpattern) { } else if (fontpattern) {
if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) {
fprintf(stderr, "error, cannot load font pattern.\n"); fprintf(stderr, "error, cannot load font from pattern.\n");
return NULL; return NULL;
} }
} else { } else {
die("no font specified.\n"); die("no font specified.");
}
/* Do not allow using color fonts. This is a workaround for a BadLength
* error from Xft with color glyphs. Modelled on the Xterm workaround. See
* https://bugzilla.redhat.com/show_bug.cgi?id=1498269
* https://lists.suckless.org/dev/1701/30932.html
* https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916349
* and lots more all over the internet.
*/
FcBool iscol;
if(FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) {
XftFontClose(drw->dpy, xfont);
return NULL;
} }
font = ecalloc(1, sizeof(Fnt)); font = ecalloc(1, sizeof(Fnt));
font->xfont = xfont; font->xfont = xfont;
font->pattern = pattern; font->pattern = pattern;
font->ascent = xfont->ascent; font->h = xfont->ascent + xfont->descent;
font->descent = xfont->descent;
font->h = font->ascent + font->descent;
font->dpy = drw->dpy; font->dpy = drw->dpy;
return font; return font;
} }
Fnt* static void
drw_font_create(Drw *drw, const char *fontname) xfont_free(Fnt *font)
{
return drw_font_xcreate(drw, fontname, NULL);
}
void
drw_load_fonts(Drw* drw, const char *fonts[], size_t fontcount)
{
size_t i;
Fnt *font;
for (i = 0; i < fontcount; i++) {
if (drw->fontcount >= DRW_FONT_CACHE_SIZE) {
die("font cache exhausted.\n");
} else if ((font = drw_font_xcreate(drw, fonts[i], NULL))) {
drw->fonts[drw->fontcount++] = font;
}
}
}
void
drw_font_free(Fnt *font)
{ {
if (!font) if (!font)
return; return;
@@ -179,55 +166,98 @@ drw_font_free(Fnt *font)
free(font); free(font);
} }
Clr * Fnt*
drw_clr_create(Drw *drw, const char *clrname) drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount)
{ {
Clr *clr; Fnt *cur, *ret = NULL;
size_t i;
if (!drw || !fonts)
return NULL;
for (i = 1; i <= fontcount; i++) {
if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) {
cur->next = ret;
ret = cur;
}
}
return (drw->fonts = ret);
}
void
drw_fontset_free(Fnt *font)
{
if (font) {
drw_fontset_free(font->next);
xfont_free(font);
}
}
void
drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
{
if (!drw || !dest || !clrname)
return;
clr = ecalloc(1, sizeof(Clr));
if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
DefaultColormap(drw->dpy, drw->screen), DefaultColormap(drw->dpy, drw->screen),
clrname, &clr->rgb)) clrname, dest))
die("error, cannot allocate color '%s'\n", clrname); die("error, cannot allocate color '%s'", clrname);
clr->pix = clr->rgb.pixel; }
return clr; /* Wrapper to create color schemes. The caller has to call free(3) on the
* returned color scheme when done using it. */
Clr *
drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
{
size_t i;
Clr *ret;
/* need at least two colors for a scheme */
if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor))))
return NULL;
for (i = 0; i < clrcount; i++)
drw_clr_create(drw, &ret[i], clrnames[i]);
return ret;
} }
void void
drw_clr_free(Clr *clr) drw_setfontset(Drw *drw, Fnt *set)
{ {
free(clr); if (drw)
drw->fonts = set;
} }
void void
drw_setscheme(Drw *drw, ClrScheme *scheme) drw_setscheme(Drw *drw, Clr *scm)
{ {
drw->scheme = scheme; if (drw)
drw->scheme = scm;
} }
void void
drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int empty, int invert) drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert)
{ {
if (!drw->scheme) if (!drw || !drw->scheme)
return; return;
XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->bg->pix : drw->scheme->fg->pix); XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel);
if (filled) if (filled)
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w + 1, h + 1); XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
else if (empty) else
XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1);
} }
int int
drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *text, int invert) drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert)
{ {
char buf[1024]; char buf[1024];
int tx, ty, th; int ty;
Extnts tex; unsigned int ew;
XftDraw *d = NULL; XftDraw *d = NULL;
Fnt *curfont, *nextfont; Fnt *usedfont, *curfont, *nextfont;
size_t i, len; size_t i, len;
int utf8strlen, utf8charlen, render; int utf8strlen, utf8charlen, render = x || y || w || h;
long utf8codepoint = 0; long utf8codepoint = 0;
const char *utf8str; const char *utf8str;
FcCharSet *fccharset; FcCharSet *fccharset;
@@ -236,66 +266,67 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex
XftResult result; XftResult result;
int charexists = 0; int charexists = 0;
if (!drw->scheme || !drw->fontcount) if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
return 0; return 0;
if (!(render = x || y || w || h)) { if (!render) {
w = ~w; w = ~w;
} else { } else {
XSetForeground(drw->dpy, drw->gc, invert ? XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
drw->scheme->fg->pix : drw->scheme->bg->pix);
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
d = XftDrawCreate(drw->dpy, drw->drawable, d = XftDrawCreate(drw->dpy, drw->drawable,
DefaultVisual(drw->dpy, drw->screen), DefaultVisual(drw->dpy, drw->screen),
DefaultColormap(drw->dpy, drw->screen)); DefaultColormap(drw->dpy, drw->screen));
x += lpad;
w -= lpad;
} }
curfont = drw->fonts[0]; usedfont = drw->fonts;
while (1) { while (1) {
utf8strlen = 0; utf8strlen = 0;
utf8str = text; utf8str = text;
nextfont = NULL; nextfont = NULL;
while (*text) { while (*text) {
utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ); utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ);
for (i = 0; i < drw->fontcount; i++) { for (curfont = drw->fonts; curfont; curfont = curfont->next) {
charexists = charexists || XftCharExists(drw->dpy, drw->fonts[i]->xfont, utf8codepoint); charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
if (charexists) { if (charexists) {
if (drw->fonts[i] == curfont) { if (curfont == usedfont) {
utf8strlen += utf8charlen; utf8strlen += utf8charlen;
text += utf8charlen; text += utf8charlen;
} else { } else {
nextfont = drw->fonts[i]; nextfont = curfont;
} }
break; break;
} }
} }
if (!charexists || (nextfont && nextfont != curfont)) if (!charexists || nextfont)
break; break;
else else
charexists = 0; charexists = 0;
} }
if (utf8strlen) { if (utf8strlen) {
drw_font_getexts(curfont, utf8str, utf8strlen, &tex); drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL);
/* shorten text if necessary */ /* shorten text if necessary */
for (len = MIN(utf8strlen, (sizeof buf) - 1); len && (tex.w > w - drw->fonts[0]->h || w < drw->fonts[0]->h); len--) for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--)
drw_font_getexts(curfont, utf8str, len, &tex); drw_font_getexts(usedfont, utf8str, len, &ew, NULL);
if (len) { if (len) {
memcpy(buf, utf8str, len); memcpy(buf, utf8str, len);
buf[len] = '\0'; buf[len] = '\0';
if (len < utf8strlen) if (len < utf8strlen)
for (i = len; i && i > len - 3; buf[--i] = '.'); for (i = len; i && i > len - 3; buf[--i] = '.')
; /* NOP */
if (render) { if (render) {
th = curfont->ascent + curfont->descent; ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
ty = y + (h / 2) - (th / 2) + curfont->ascent; XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
tx = x + (h / 2); usedfont->xfont, x, ty, (XftChar8 *)buf, len);
XftDrawStringUtf8(d, invert ? &drw->scheme->bg->rgb : &drw->scheme->fg->rgb, curfont->xfont, tx, ty, (XftChar8 *)buf, len);
} }
x += tex.w; x += ew;
w -= tex.w; w -= ew;
} }
} }
@@ -303,28 +334,24 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex
break; break;
} else if (nextfont) { } else if (nextfont) {
charexists = 0; charexists = 0;
curfont = nextfont; usedfont = nextfont;
} else { } else {
/* Regardless of whether or not a fallback font is found, the /* Regardless of whether or not a fallback font is found, the
* character must be drawn. * character must be drawn. */
*/
charexists = 1; charexists = 1;
if (drw->fontcount >= DRW_FONT_CACHE_SIZE)
continue;
fccharset = FcCharSetCreate(); fccharset = FcCharSetCreate();
FcCharSetAddChar(fccharset, utf8codepoint); FcCharSetAddChar(fccharset, utf8codepoint);
if (!drw->fonts[0]->pattern) { if (!drw->fonts->pattern) {
/* Refer to the comment in drw_font_xcreate for more /* Refer to the comment in xfont_create for more information. */
* information. */ die("the first font in the cache must be loaded from a font string.");
die("the first font in the cache must be loaded from a font string.\n");
} }
fcpattern = FcPatternDuplicate(drw->fonts[0]->pattern); fcpattern = FcPatternDuplicate(drw->fonts->pattern);
FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset); FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue); FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue);
FcPatternAddBool(fcpattern, FC_COLOR, FcFalse);
FcConfigSubstitute(NULL, fcpattern, FcMatchPattern); FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
FcDefaultSubstitute(fcpattern); FcDefaultSubstitute(fcpattern);
@@ -334,12 +361,14 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex
FcPatternDestroy(fcpattern); FcPatternDestroy(fcpattern);
if (match) { if (match) {
curfont = drw_font_xcreate(drw, NULL, match); usedfont = xfont_create(drw, NULL, match);
if (curfont && XftCharExists(drw->dpy, curfont->xfont, utf8codepoint)) { if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) {
drw->fonts[drw->fontcount++] = curfont; for (curfont = drw->fonts; curfont->next; curfont = curfont->next)
; /* NOP */
curfont->next = usedfont;
} else { } else {
drw_font_free(curfont); xfont_free(usedfont);
curfont = drw->fonts[0]; usedfont = drw->fonts;
} }
} }
} }
@@ -347,34 +376,40 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex
if (d) if (d)
XftDrawDestroy(d); XftDrawDestroy(d);
return x; return x + (render ? w : 0);
} }
void void
drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
{ {
if (!drw)
return;
XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y); XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y);
XSync(drw->dpy, False); XSync(drw->dpy, False);
} }
unsigned int
drw_fontset_getwidth(Drw *drw, const char *text)
{
if (!drw || !drw->fonts || !text)
return 0;
return drw_text(drw, 0, 0, 0, 0, 0, text, 0);
}
void void
drw_font_getexts(Fnt *font, const char *text, unsigned int len, Extnts *tex) drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
{ {
XGlyphInfo ext; XGlyphInfo ext;
if (!font || !text)
return;
XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext); XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext);
tex->h = font->h; if (w)
tex->w = ext.xOff; *w = ext.xOff;
} if (h)
*h = font->h;
unsigned int
drw_font_getexts_width(Fnt *font, const char *text, unsigned int len)
{
Extnts tex;
drw_font_getexts(font, text, len, &tex);
return tex.w;
} }
Cur * Cur *
@@ -382,7 +417,9 @@ drw_cur_create(Drw *drw, int shape)
{ {
Cur *cur; Cur *cur;
cur = ecalloc(1, sizeof(Cur)); if (!drw || !(cur = ecalloc(1, sizeof(Cur))))
return NULL;
cur->cursor = XCreateFontCursor(drw->dpy, shape); cur->cursor = XCreateFontCursor(drw->dpy, shape);
return cur; return cur;
@@ -393,6 +430,7 @@ drw_cur_free(Drw *drw, Cur *cursor)
{ {
if (!cursor) if (!cursor)
return; return;
XFreeCursor(drw->dpy, cursor->cursor); XFreeCursor(drw->dpy, cursor->cursor);
free(cursor); free(cursor);
} }

63
drw.h
View File

@@ -1,29 +1,19 @@
/* See LICENSE file for copyright and license details. */ /* See LICENSE file for copyright and license details. */
#define DRW_FONT_CACHE_SIZE 32
typedef struct {
unsigned long pix;
XftColor rgb;
} Clr;
typedef struct { typedef struct {
Cursor cursor; Cursor cursor;
} Cur; } Cur;
typedef struct { typedef struct Fnt {
Display *dpy; Display *dpy;
int ascent;
int descent;
unsigned int h; unsigned int h;
XftFont *xfont; XftFont *xfont;
FcPattern *pattern; FcPattern *pattern;
struct Fnt *next;
} Fnt; } Fnt;
typedef struct { enum { ColFg, ColBg, ColBorder }; /* Clr scheme index */
Clr *fg; typedef XftColor Clr;
Clr *bg;
Clr *border;
} ClrScheme;
typedef struct { typedef struct {
unsigned int w, h; unsigned int w, h;
@@ -32,43 +22,36 @@ typedef struct {
Window root; Window root;
Drawable drawable; Drawable drawable;
GC gc; GC gc;
ClrScheme *scheme; Clr *scheme;
size_t fontcount; Fnt *fonts;
Fnt *fonts[DRW_FONT_CACHE_SIZE];
} Drw; } Drw;
typedef struct {
unsigned int w;
unsigned int h;
} Extnts;
/* Drawable abstraction */ /* Drawable abstraction */
Drw *drw_create(Display *, int, Window, unsigned int, unsigned int); Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
void drw_resize(Drw *, unsigned int, unsigned int); void drw_resize(Drw *drw, unsigned int w, unsigned int h);
void drw_free(Drw *); void drw_free(Drw *drw);
/* Fnt abstraction */ /* Fnt abstraction */
Fnt *drw_font_create(Drw *, const char *); Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount);
void drw_load_fonts(Drw *, const char *[], size_t); void drw_fontset_free(Fnt* set);
void drw_font_free(Fnt *); unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
void drw_font_getexts(Fnt *, const char *, unsigned int, Extnts *); void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
unsigned int drw_font_getexts_width(Fnt *, const char *, unsigned int);
/* Colour abstraction */ /* Colorscheme abstraction */
Clr *drw_clr_create(Drw *, const char *); void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
void drw_clr_free(Clr *); Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
/* Cursor abstraction */ /* Cursor abstraction */
Cur *drw_cur_create(Drw *, int); Cur *drw_cur_create(Drw *drw, int shape);
void drw_cur_free(Drw *, Cur *); void drw_cur_free(Drw *drw, Cur *cursor);
/* Drawing context manipulation */ /* Drawing context manipulation */
void drw_setfont(Drw *, Fnt *); void drw_setfontset(Drw *drw, Fnt *set);
void drw_setscheme(Drw *, ClrScheme *); void drw_setscheme(Drw *drw, Clr *scm);
/* Drawing functions */ /* Drawing functions */
void drw_rect(Drw *, int, int, unsigned int, unsigned int, int, int, int); void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert);
int drw_text(Drw *, int, int, unsigned int, unsigned int, const char *, int); int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert);
/* Map functions */ /* Map functions */
void drw_map(Drw *, Window, int, int, unsigned int, unsigned int); void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);

99
dwm.1
View File

@@ -10,8 +10,9 @@ and floating layouts. Either layout can be applied dynamically, optimising the
environment for the application in use and the task performed. environment for the application in use and the task performed.
.P .P
In tiled layouts windows are managed in a master and stacking area. The master In tiled layouts windows are managed in a master and stacking area. The master
area contains the window which currently needs most attention, whereas the area on the left contains one window by default, and the stacking area on the
stacking area contains all other windows. In monocle layout all windows are right contains all other windows. The number of master area windows can be
adjusted from zero to an arbitrary number. In monocle layout all windows are
maximised to the screen size. In floating layout windows can be resized and maximised to the screen size. In floating layout windows can be resized and
moved freely. Dialog windows are always managed floating, regardless of the moved freely. Dialog windows are always managed floating, regardless of the
layout applied. layout applied.
@@ -29,10 +30,18 @@ top left corner. The tags which are applied to one or more windows are
indicated with an empty square in the top left corner. indicated with an empty square in the top left corner.
.P .P
dwm draws a small border around windows to indicate the focus state. dwm draws a small border around windows to indicate the focus state.
.P
On start, dwm can start additional programs that may be specified in two special
shell scripts (see the FILES section below), autostart_blocking.sh and
autostart.sh. The former is executed first and dwm will wait for its
termination before starting. The latter is executed in the background before
dwm enters its handler loop.
.P
Either of these files may be omitted.
.SH OPTIONS .SH OPTIONS
.TP .TP
.B \-v .B \-v
prints version information to standard output, then exits. prints version information to stderr, then exits.
.SH USAGE .SH USAGE
.SS Status bar .SS Status bar
.TP .TP
@@ -59,6 +68,26 @@ click on a tag label adds/removes that tag to/from the focused window.
Start Start
.BR st(1). .BR st(1).
.TP .TP
.B Mod1\-p
Spawn
.BR rofi(1)
for launching other programs.
.TP
.B Mod1\-c
Spawn
.BR rofi(1)
for Greenclip clipboard manager
.TP
.B Mod1\-Shift\-n
Spawn
.BR light-locker(1)
to lock screen.
.TP
.B Mod1\-Shift\-s
Spawn
.BR suspend(1)
to lock screen and go to sleep.
.TP
.B Mod1\-, .B Mod1\-,
Focus previous screen, if any. Focus previous screen, if any.
.TP .TP
@@ -71,6 +100,15 @@ Send focused window to previous screen, if any.
.B Mod1\-Shift\-. .B Mod1\-Shift\-.
Send focused window to next screen, if any. Send focused window to next screen, if any.
.TP .TP
.B Mod1\--
Decrease window gap.
.TP
.B Mod1\-=
Increase window gap.
.TP
.B Mod1\-Shift\-=
Reset window gap to 0.
.TP
.B Mod1\-b .B Mod1\-b
Toggles bar on and off. Toggles bar on and off.
.TP .TP
@@ -83,9 +121,24 @@ Sets floating layout.
.B Mod1\-m .B Mod1\-m
Sets monocle layout. Sets monocle layout.
.TP .TP
.B Mod1\-u
Sets centered master layout.
.TP
.B Mod1\-o
Sets centered floating master layout.
.TP
.B Mod1\-g
Sets grid layout.
.TP
.B Mod1\-space .B Mod1\-space
Toggles between current and previous layout. Toggles between current and previous layout.
.TP .TP
.B Mod1\-Control\-,
Cycles backwards in layout list.
.TP
.B Mod1\-Control\-.
Cycles forwards in layout list.
.TP
.B Mod1\-j .B Mod1\-j
Focus next window. Focus next window.
.TP .TP
@@ -93,10 +146,10 @@ Focus next window.
Focus previous window. Focus previous window.
.TP .TP
.B Mod1\-i .B Mod1\-i
Increase clients in master area. Increase number of windows in master area.
.TP .TP
.B Mod1\-d .B Mod1\-d
Decrease clients in master area. Decrease number of windows in master area.
.TP .TP
.B Mod1\-l .B Mod1\-l
Increase master area size. Increase master area size.
@@ -136,6 +189,9 @@ Add/remove all windows with nth tag to/from the view.
.TP .TP
.B Mod1\-Shift\-q .B Mod1\-Shift\-q
Quit dwm. Quit dwm.
.TP
.B Mod1\-Control\-Shift\-q
Restart dwm.
.SS Mouse commands .SS Mouse commands
.TP .TP
.B Mod1\-Button1 .B Mod1\-Button1
@@ -146,13 +202,32 @@ Toggles focused window between floating and tiled state.
.TP .TP
.B Mod1\-Button3 .B Mod1\-Button3
Resize focused window while dragging. Tiled windows will be toggled to the floating state. Resize focused window while dragging. Tiled windows will be toggled to the floating state.
.SH FILES
The files containing programs to be started along with dwm are searched for in
the dwm root directory.
.P
The first existing directory is scanned for any of the autostart files below.
.TP 15
autostart.sh
This file is started as a shell background process before dwm enters its handler
loop.
.TP 15
autostart_blocking.sh
This file is started before any autostart.sh; dwm waits for its termination.
.SH CUSTOMIZATION .SH CUSTOMIZATION
dwm is customized by creating a custom config.h and (re)compiling the source dwm is customized by creating a custom config.h and (re)compiling the source
code. This keeps it fast, secure and simple. code. This keeps it fast, secure and simple.
.SH SIGNALS
.TP
.B SIGHUP - 1
Restart the dwm process.
.TP
.B SIGTERM - 15
Cleanly terminate the dwm process.
.SH SEE ALSO .SH SEE ALSO
.BR dmenu (1), .BR rofi (1),
.BR st (1) .BR st (1)
.SH BUGS .SH ISSUES
Java applications which use the XToolkit/XAWT backend may draw grey windows Java applications which use the XToolkit/XAWT backend may draw grey windows
only. The XToolkit/XAWT backend breaks ICCCM-compliance in recent JDK 1.5 and early only. The XToolkit/XAWT backend breaks ICCCM-compliance in recent JDK 1.5 and early
JDK 1.6 versions, because it assumes a reparenting window manager. Possible workarounds JDK 1.6 versions, because it assumes a reparenting window manager. Possible workarounds
@@ -166,11 +241,5 @@ or
(to pretend that a non-reparenting window manager is running that the (to pretend that a non-reparenting window manager is running that the
XToolkit/XAWT backend can recognize) or when using OpenJDK setting the environment variable XToolkit/XAWT backend can recognize) or when using OpenJDK setting the environment variable
.BR _JAVA_AWT_WM_NONREPARENTING=1 . .BR _JAVA_AWT_WM_NONREPARENTING=1 .
.P .SH BUGS
GTK 2.10.9+ versions contain a broken Send all bug reports with a patch to hackers@suckless.org.
.BR Save\-As
file dialog implementation,
which requests to reconfigure its window size in an endless loop. However, its
window is still respondable during this state, so you can simply ignore the flicker
until a new GTK version appears, which will fix this bug, approximately
GTK 2.10.12+ versions.

993
dwm.c

File diff suppressed because it is too large Load Diff

27
layouts.c Normal file
View File

@@ -0,0 +1,27 @@
void
grid(Monitor *m) {
unsigned int i, n, cx, cy, cw, ch, aw, ah, cols, rows;
Client *c;
for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next))
n++;
/* grid dimensions */
for(rows = 0; rows <= n/2; rows++)
if(rows*rows >= n)
break;
cols = (rows && (rows - 1) * rows >= n) ? rows - 1 : rows;
/* window geoms (cell height/width) */
ch = m->wh / (rows ? rows : 1);
cw = m->ww / (cols ? cols : 1);
for(i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) {
cx = m->wx + (i / rows) * cw;
cy = m->wy + (i % rows) * ch;
/* adjust height/width of last row/column's windows */
ah = ((i + 1) % rows == 0) ? m->wh - ch * rows : 0;
aw = (i >= rows * (cols - 1)) ? m->ww - cw * cols : 0;
resize(c, cx, cy, cw - 2 * c->bw + aw, ch - 2 * c->bw + ah, False);
i++;
}
}

48
movestack.c Normal file
View File

@@ -0,0 +1,48 @@
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);
}
}

4
util.c
View File

@@ -12,7 +12,7 @@ ecalloc(size_t nmemb, size_t size)
void *p; void *p;
if (!(p = calloc(nmemb, size))) if (!(p = calloc(nmemb, size)))
perror(NULL); die("calloc:");
return p; return p;
} }
@@ -27,6 +27,8 @@ die(const char *fmt, ...) {
if (fmt[0] && fmt[strlen(fmt)-1] == ':') { if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
fputc(' ', stderr); fputc(' ', stderr);
perror(NULL); perror(NULL);
} else {
fputc('\n', stderr);
} }
exit(1); exit(1);

4
util.h
View File

@@ -4,5 +4,5 @@
#define MIN(A, B) ((A) < (B) ? (A) : (B)) #define MIN(A, B) ((A) < (B) ? (A) : (B))
#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B)) #define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B))
void die(const char *errstr, ...); void die(const char *fmt, ...);
void *ecalloc(size_t, size_t); void *ecalloc(size_t nmemb, size_t size);