mirror of
https://gitlab.com/dwt1/dotfiles.git
synced 2023-02-13 20:55:19 -05:00
Lots of updates.
This commit is contained in:
parent
55f24bf77c
commit
3814732157
55 changed files with 981 additions and 7944 deletions
1
.bashrc
1
.bashrc
|
@ -6,6 +6,7 @@
|
|||
#
|
||||
# My bash config. Not much to see here. Some pretty standard stuff.
|
||||
|
||||
PATH="$HOME/.local/bin${PATH:+:${PATH}}"
|
||||
EDITOR="emacsclient -c"
|
||||
export TERM="xterm-256color"
|
||||
|
||||
|
|
|
@ -339,8 +339,7 @@ def init_widgets_list():
|
|||
foreground = colors[2],
|
||||
background = colors[0]
|
||||
),
|
||||
widget.WindowName(font="Ubuntu",
|
||||
fontsize = 11,
|
||||
widget.WindowName(
|
||||
foreground = colors[4],
|
||||
background = colors[0],
|
||||
padding = 5
|
||||
|
@ -353,7 +352,6 @@ def init_widgets_list():
|
|||
fontsize=37
|
||||
),
|
||||
widget.TextBox(
|
||||
font="Ubuntu Bold",
|
||||
text=" ⟳",
|
||||
padding = 5,
|
||||
foreground=colors[2],
|
||||
|
@ -419,7 +417,6 @@ def init_widgets_list():
|
|||
fontsize=37
|
||||
),
|
||||
widget.TextBox(
|
||||
font="Ubuntu Bold",
|
||||
text=" ♫",
|
||||
padding = 5,
|
||||
foreground=colors[2],
|
||||
|
@ -460,7 +457,6 @@ def init_widgets_list():
|
|||
fontsize=37
|
||||
),
|
||||
widget.TextBox(
|
||||
font="Ubuntu Bold",
|
||||
text=" ☵",
|
||||
padding = 5,
|
||||
foreground=colors[2],
|
||||
|
@ -480,7 +476,6 @@ def init_widgets_list():
|
|||
fontsize=37
|
||||
),
|
||||
widget.TextBox(
|
||||
font="Ubuntu Bold",
|
||||
text=" 🕒",
|
||||
foreground=colors[2],
|
||||
background=colors[4],
|
||||
|
|
|
@ -1,45 +1,4 @@
|
|||
#! /bin/bash
|
||||
compton --config ~/.config/compton/compton.conf &
|
||||
compton &
|
||||
nitrogen --restore &
|
||||
urxvtd -q -o -f &
|
||||
|
||||
dte(){
|
||||
dte="$(date +"%A, %B %d %l:%M%p")"
|
||||
echo -e "🕒 $dte"
|
||||
}
|
||||
|
||||
hdd() {
|
||||
hdd="$(df -h | awk 'NR==4{print $3, $5}')"
|
||||
echo -e "💿 $hdd"
|
||||
}
|
||||
|
||||
mem(){
|
||||
mem=`free | awk '/Mem/ {printf "%d MiB/%d MiB\n", $3 / 1024.0, $2 / 1024.0 }'`
|
||||
echo -e "🖪 $mem"
|
||||
}
|
||||
|
||||
cpu(){
|
||||
read cpu a b c previdle rest < /proc/stat
|
||||
prevtotal=$((a+b+c+previdle))
|
||||
sleep 0.5
|
||||
read cpu a b c idle rest < /proc/stat
|
||||
total=$((a+b+c+idle))
|
||||
cpu=$((100*( (total-prevtotal) - (idle-previdle) ) / (total-prevtotal) ))
|
||||
echo -e "💻 $cpu% cpu"
|
||||
}
|
||||
|
||||
pulse () {
|
||||
volume=$(pactl list sinks | grep '^[[:space:]]Volume:' | head -n $(( $SINK + 1 )) | tail -n 1 | sed -e 's,.* \([0-9][0-9]*\)%.*,\1,')
|
||||
status=$(pacmd list-sinks | awk '/muted/ { print $2 }')
|
||||
|
||||
if [ "$status" = "yes" ]; then
|
||||
echo -e "🔈 muted"
|
||||
else
|
||||
echo -e "🔈 $volume%"
|
||||
fi
|
||||
}
|
||||
|
||||
while true; do
|
||||
xsetroot -name "$(cpu) | $(mem) | $(hdd) | $(pulse) | $(dte)"
|
||||
sleep 1s # Update time every one second(s)
|
||||
done &
|
||||
dwmblocks &
|
||||
|
|
4
.local/bin/clock
Executable file
4
.local/bin/clock
Executable file
|
@ -0,0 +1,4 @@
|
|||
#! /bin/bash
|
||||
|
||||
dte="$(date +"%a, %B %d %l:%M%p"| sed 's/ / /g')"
|
||||
echo -e "$dte"
|
4
.local/bin/kernel
Executable file
4
.local/bin/kernel
Executable file
|
@ -0,0 +1,4 @@
|
|||
#! /bin/bash
|
||||
|
||||
kern="$(uname -r)"
|
||||
echo -e "$kern "
|
4
.local/bin/memory
Executable file
4
.local/bin/memory
Executable file
|
@ -0,0 +1,4 @@
|
|||
#! /bin/bash
|
||||
|
||||
mem="$(free -h | awk '/^Mem:/ {print $3 "/" $2}')"
|
||||
echo -e "$mem ram "
|
4
.local/bin/pacupdate
Executable file
4
.local/bin/pacupdate
Executable file
|
@ -0,0 +1,4 @@
|
|||
#!/bin/bash
|
||||
|
||||
cupd=$(checkupdates | wc -l)
|
||||
printf "$cupd udpates \n"
|
4
.local/bin/upt
Executable file
4
.local/bin/upt
Executable file
|
@ -0,0 +1,4 @@
|
|||
#! /bin/bash
|
||||
|
||||
upt="$(uptime --pretty | sed -e 's/up //g' -e 's/ hours/h/g' -e 's/ hour/h/g' -e 's/ minutes/m/g' -e 's/, //g')"
|
||||
echo -e "$upt uptime "
|
4
.local/bin/volume
Executable file
4
.local/bin/volume
Executable file
|
@ -0,0 +1,4 @@
|
|||
#!/bin/bash
|
||||
|
||||
vol="$(amixer get Master | tail -n1 | sed -r 's/.*\[(.*)%\].*/\1/')"
|
||||
echo "${vol}% "
|
|
@ -1,32 +1,41 @@
|
|||
body {
|
||||
background-color: #292d3e !important;
|
||||
color: #eee !important;
|
||||
font-size: 13px;
|
||||
background-color: #282a36 !important;
|
||||
color: #d0d0d0 !important;
|
||||
}
|
||||
|
||||
#header {
|
||||
|
||||
background-color: #292d3e !important;
|
||||
background-color: #282a36 !important;
|
||||
clear: both;
|
||||
color: #BD93F9 !important;
|
||||
|
||||
color: #c3e88d !important;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #82aaff !important;
|
||||
}
|
||||
|
||||
#header a {
|
||||
color: #e1acff !important;
|
||||
}
|
||||
|
||||
#menu {
|
||||
clear: both;
|
||||
color: #069;
|
||||
clear: both;
|
||||
color: #c792ea;
|
||||
font-weight: bold;
|
||||
overflow: hidden;
|
||||
background-color: #17a;
|
||||
padding: 0.7ex;
|
||||
border: 0px !important;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #BD93F9 !important;
|
||||
}
|
||||
|
||||
#header a {
|
||||
color: #BD93F9 !important;
|
||||
}
|
||||
|
||||
#menu a {
|
||||
color: #F8F8F2 !important;
|
||||
color: #d0d0d0 !important;
|
||||
}
|
||||
|
||||
#nav li a:hover {
|
||||
background-color: #282a36 !important;
|
||||
}
|
||||
|
||||
h1, h2 {
|
||||
color: #f07178 !important;
|
||||
}
|
||||
|
||||
|
|
37
dwm/LICENSE
37
dwm/LICENSE
|
@ -1,37 +0,0 @@
|
|||
MIT/X Consortium License
|
||||
|
||||
© 2006-2019 Anselm R Garbe <anselm@garbe.ca>
|
||||
© 2006-2009 Jukka Salmi <jukka at salmi dot ch>
|
||||
© 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 Christof Musik <christof at sendfax dot de>
|
||||
© 2007-2009 Premysl Hruby <dfenze at gmail dot com>
|
||||
© 2007-2008 Enno Gottox Boland <gottox at s01 dot de>
|
||||
© 2008 Martin Hurton <martin dot hurton at gmail dot com>
|
||||
© 2008 Neale Pickett <neale dot woozle dot org>
|
||||
© 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>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
51
dwm/Makefile
51
dwm/Makefile
|
@ -1,51 +0,0 @@
|
|||
# dwm - dynamic window manager
|
||||
# See LICENSE file for copyright and license details.
|
||||
|
||||
include config.mk
|
||||
|
||||
SRC = drw.c dwm.c util.c
|
||||
OBJ = ${SRC:.c=.o}
|
||||
|
||||
all: options dwm
|
||||
|
||||
options:
|
||||
@echo dwm build options:
|
||||
@echo "CFLAGS = ${CFLAGS}"
|
||||
@echo "LDFLAGS = ${LDFLAGS}"
|
||||
@echo "CC = ${CC}"
|
||||
|
||||
.c.o:
|
||||
${CC} -c ${CFLAGS} $<
|
||||
|
||||
${OBJ}: config.h config.mk
|
||||
|
||||
config.h:
|
||||
cp config.def.h $@
|
||||
|
||||
dwm: ${OBJ}
|
||||
${CC} -o $@ ${OBJ} ${LDFLAGS}
|
||||
|
||||
clean:
|
||||
rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz
|
||||
|
||||
dist: clean
|
||||
mkdir -p dwm-${VERSION}
|
||||
cp -R LICENSE Makefile README config.def.h config.mk\
|
||||
dwm.1 drw.h util.h ${SRC} dwm.png transient.c dwm-${VERSION}
|
||||
tar -cf dwm-${VERSION}.tar dwm-${VERSION}
|
||||
gzip dwm-${VERSION}.tar
|
||||
rm -rf dwm-${VERSION}
|
||||
|
||||
install: all
|
||||
mkdir -p ${DESTDIR}${PREFIX}/bin
|
||||
cp -f dwm ${DESTDIR}${PREFIX}/bin
|
||||
chmod 755 ${DESTDIR}${PREFIX}/bin/dwm
|
||||
mkdir -p ${DESTDIR}${MANPREFIX}/man1
|
||||
sed "s/VERSION/${VERSION}/g" < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1
|
||||
chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1
|
||||
|
||||
uninstall:
|
||||
rm -f ${DESTDIR}${PREFIX}/bin/dwm\
|
||||
${DESTDIR}${MANPREFIX}/man1/dwm.1
|
||||
|
||||
.PHONY: all options clean dist install uninstall
|
|
@ -1,61 +0,0 @@
|
|||
# My dwm (Dynamic Window Manager) build
|
||||
|
||||
![Screenshot of my desktop](https://gitlab.com/dwt1/dotfiles/raw/master/.screenshots/dotfiles04.png)
|
||||
Dwm is an extremely fast, small, and dynamic window manager for X. This is my personal build of dwm. I used a number of patches in this build to make dwm more "sensible" rather than "suckless."
|
||||
|
||||
# My Keybindings
|
||||
|
||||
The MODKEY is set to the Super key (aka the Windows key). I try to keep the
|
||||
keybindings consistent with all of my window managers.
|
||||
|
||||
| Keybinding | Action |
|
||||
| :--- | :--- |
|
||||
| `MODKEY + RETURN` | opens terminal (alacritty is the terminal but can be easily changed) |
|
||||
| `MODKEY + SHIFT + RETURN` | opens run launcher (dmenu is the run launcher but can be easily changed) |
|
||||
| `MODKEY + SHIFT + c` | closes window with focus |
|
||||
| `MODKEY + SHIFT + r` | restarts dwm |
|
||||
| `MODKEY + SHIFT + q` | quits dwm |
|
||||
| `MODKEY + 1-9` | switch focus to workspace (1-9) |
|
||||
| `MODKEY + SHIFT + 1-9` | send focused window to workspace (1-9) |
|
||||
| `MODKEY + j` | focus stack +1 (switches focus between windows in the stack) |
|
||||
| `MODKEY + k` | focus stack -1 (switches focus between windows in the stack) |
|
||||
| `MODKEY + SHIFT + j` | rotate stack +1 (rotates the windows in the stack) |
|
||||
| `MODKEY + SHIFT + k` | rotate stack -1 (rotates the windows in the stack) |
|
||||
| `MODKEY + h` | setmfact -0.05 (expands size of window) |
|
||||
| `MODKEY + l` | setmfact +0.05 (shrinks size of window) |
|
||||
| `MODKEY + .` | focusmon +1 (switches focus next monitors) |
|
||||
| `MODKEY + ,` | focusmon -1 (switches focus to prev monitors) |
|
||||
|
||||
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.
|
132
dwm/config.def.h
132
dwm/config.def.h
|
@ -1,132 +0,0 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
/* appearance */
|
||||
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 */
|
||||
static const int topbar = 1; /* 0 means bottom bar */
|
||||
static const int horizpadbar = 4; /* horizontal padding for statusbar */
|
||||
static const int vertpadbar = 2; /* vertical padding for statusbar */
|
||||
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 unsigned int baralpha = 0xd0;
|
||||
static const unsigned int borderalpha = OPAQUE;
|
||||
static const char *colors[][3] = {
|
||||
/* fg bg border */
|
||||
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
|
||||
[SchemeSel] = { col_gray4, col_cyan, col_cyan },
|
||||
};
|
||||
static const unsigned int alphas[][3] = {
|
||||
/* fg bg border */
|
||||
[SchemeNorm] = { OPAQUE, baralpha, borderalpha },
|
||||
[SchemeSel] = { OPAQUE, baralpha, borderalpha },
|
||||
};
|
||||
|
||||
/* tagging */
|
||||
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
|
||||
|
||||
static const Rule rules[] = {
|
||||
/* xprop(1):
|
||||
* 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 },
|
||||
};
|
||||
|
||||
/* 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 */
|
||||
|
||||
static const Layout layouts[] = {
|
||||
/* symbol arrange function */
|
||||
{ "[]=", tile }, /* first entry is default */
|
||||
{ "><>", NULL }, /* no layout function means floating behavior */
|
||||
{ "[M]", monocle },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
/* key definitions */
|
||||
#define MODKEY Mod1Mask
|
||||
#define TAGKEYS(KEY,TAG) \
|
||||
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
|
||||
{ MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
|
||||
{ MODKEY|ShiftMask, KEY, tag, {.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 } }
|
||||
|
||||
/* commands */
|
||||
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
|
||||
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 "selfrestart.c"
|
||||
|
||||
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|ShiftMask, XK_j, rotatestack, {.i = +1 } },
|
||||
{ MODKEY|ShiftMask, XK_k, rotatestack, {.i = -1 } },
|
||||
{ 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|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 } },
|
||||
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_r, self_restart, {0} },
|
||||
{ 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} },
|
||||
};
|
|
@ -1,131 +0,0 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
/* appearance */
|
||||
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 */
|
||||
static const int topbar = 1; /* 0 means bottom bar */
|
||||
static const int horizpadbar = 4; /* horizontal padding for statusbar */
|
||||
static const int vertpadbar = 2; /* vertical padding for statusbar */
|
||||
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 unsigned int baralpha = 0xd0;
|
||||
static const unsigned int borderalpha = OPAQUE;
|
||||
static const char *colors[][3] = {
|
||||
/* fg bg border */
|
||||
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
|
||||
[SchemeSel] = { col_gray4, col_cyan, col_cyan },
|
||||
};
|
||||
static const unsigned int alphas[][3] = {
|
||||
/* fg bg border */
|
||||
[SchemeNorm] = { OPAQUE, baralpha, borderalpha },
|
||||
[SchemeSel] = { OPAQUE, baralpha, borderalpha },
|
||||
};
|
||||
|
||||
/* tagging */
|
||||
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
|
||||
|
||||
static const Rule rules[] = {
|
||||
/* xprop(1):
|
||||
* 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 },
|
||||
};
|
||||
|
||||
/* 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 */
|
||||
|
||||
static const Layout layouts[] = {
|
||||
/* symbol arrange function */
|
||||
{ "[]=", tile }, /* first entry is default */
|
||||
{ "><>", NULL }, /* no layout function means floating behavior */
|
||||
{ "[M]", monocle },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
/* key definitions */
|
||||
#define MODKEY Mod1Mask
|
||||
#define TAGKEYS(KEY,TAG) \
|
||||
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
|
||||
{ MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
|
||||
{ MODKEY|ShiftMask, KEY, tag, {.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 } }
|
||||
|
||||
/* commands */
|
||||
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
|
||||
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 "selfrestart.c"
|
||||
|
||||
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|ShiftMask, XK_j, rotatestack, {.i = +1 } },
|
||||
{ MODKEY|ShiftMask, XK_k, rotatestack, {.i = -1 } },
|
||||
{ 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|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 } },
|
||||
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_r, self_restart, {0} },
|
||||
{ MODKEY|ShiftMask, XK_q, quit, {0} },
|
||||
};
|
||||
|
||||
/* 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} },
|
||||
};
|
|
@ -1,19 +0,0 @@
|
|||
--- config.def.h
|
||||
+++ config.def.h
|
||||
@@ -41,6 +41,7 @@ static const Layout layouts[] = {
|
||||
{ "[]=", tile }, /* first entry is default */
|
||||
{ "><>", NULL }, /* no layout function means floating behavior */
|
||||
{ "[M]", monocle },
|
||||
+ { NULL, NULL },
|
||||
};
|
||||
|
||||
/* key definitions */
|
||||
@@ -76,6 +77,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|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 } },
|
165
dwm/config.h
165
dwm/config.h
|
@ -1,165 +0,0 @@
|
|||
/* ____ _____ */
|
||||
/* | _ \_ _| Derek Taylor (DistroTube) */
|
||||
/* | | | || | http://www.youtube.com/c/DistroTube */
|
||||
/* | |_| || | http://www.gitlab.com/dwt1/ */
|
||||
/* |____/ |_| */
|
||||
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
/* appearance */
|
||||
static const unsigned int borderpx = 2; /* border pixel of windows */
|
||||
static const unsigned int snap = 32; /* snap pixel */
|
||||
static const unsigned int gappx = 6; /* pixel gap between clients */
|
||||
static const int showbar = 1; /* 0 means no bar */
|
||||
static const int topbar = 1; /* 0 means bottom bar */
|
||||
static const int horizpadbar = 6; /* horizontal padding for statusbar */
|
||||
static const int vertpadbar = 7; /* vertical padding for statusbar */
|
||||
static const char *fonts[] = { "Mononoki Nerd Font:size=9" };
|
||||
static const char dmenufont[] = "Mononoki Nerd Font:size=9";
|
||||
static const char col_gray1[] = "#282a36";
|
||||
static const char col_gray2[] = "#282a36"; /* border color unfocused windows */
|
||||
static const char col_gray3[] = "#96b5b4";
|
||||
static const char col_gray4[] = "#d7d7d7";
|
||||
static const char col_cyan[] = "#924441"; /* border color focused windows and tags */
|
||||
static const unsigned int baralpha = 0xff; /* 0xee adds a wee bit transparency */
|
||||
static const unsigned int borderalpha = OPAQUE;
|
||||
static const char *colors[][3] = {
|
||||
/* fg bg border */
|
||||
[SchemeNorm] = { col_gray4, col_gray1, col_gray2 },
|
||||
[SchemeSel] = { col_gray4, col_cyan, col_cyan },
|
||||
};
|
||||
static const unsigned int alphas[][3] = {
|
||||
/* fg bg border */
|
||||
[SchemeNorm] = { OPAQUE, baralpha, borderalpha },
|
||||
[SchemeSel] = { OPAQUE, baralpha, borderalpha },
|
||||
};
|
||||
|
||||
/* tagging */
|
||||
/* static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; */
|
||||
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 */
|
||||
{ "Gimp", NULL, NULL, 0, 1, -1 },
|
||||
{ "Firefox", NULL, NULL, 1 << 8, 0, -1 },
|
||||
};
|
||||
|
||||
/* layout(s) */
|
||||
static const float mfact = 0.50; /* factor of master area size [0.05..0.95] */
|
||||
static const int nmaster = 1; /* number of clients in master area */
|
||||
static const int resizehints = 0; /* 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 },
|
||||
{ "HHH", grid },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
/* key definitions */
|
||||
#define MODKEY Mod4Mask
|
||||
#define TAGKEYS(KEY,TAG) \
|
||||
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
|
||||
{ MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
|
||||
{ MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
|
||||
{ MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
|
||||
#define CMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
|
||||
|
||||
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
|
||||
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
|
||||
|
||||
/* commands */
|
||||
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
|
||||
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[] = { "alacritty", NULL };
|
||||
|
||||
static Key keys[] = {
|
||||
/* modifier key function argument */
|
||||
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = dmenucmd } },
|
||||
{ MODKEY, XK_Return, spawn, {.v = termcmd } },
|
||||
{ MODKEY, XK_b, togglebar, {0} },
|
||||
{ MODKEY|ShiftMask, XK_j, rotatestack, {.i = +1 } },
|
||||
{ MODKEY|ShiftMask, XK_k, rotatestack, {.i = -1 } },
|
||||
{ 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|ControlMask, XK_Return, zoom, {0} },
|
||||
{ MODKEY, XK_Tab, view, {0} },
|
||||
{ MODKEY|ShiftMask, XK_c, killclient, {0} },
|
||||
|
||||
/* Layouts and layout manipulation */
|
||||
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
|
||||
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
|
||||
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
|
||||
{ MODKEY, XK_g, setlayout, {.v = &layouts[3]} },
|
||||
{ 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 } },
|
||||
|
||||
/* Switching between monitors */
|
||||
{ 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 } },
|
||||
|
||||
/* Dmenu scripts launched with ALT + CTRL + KEY */
|
||||
{ Mod1Mask|ControlMask, XK_e, spawn, CMD("./.dmenu/dmenu-edit-configs.sh") },
|
||||
{ Mod1Mask|ControlMask, XK_m, spawn, CMD("./.dmenu/dmenu-sysmon.sh") },
|
||||
{ Mod1Mask|ControlMask, XK_p, spawn, CMD("passmenu") },
|
||||
{ Mod1Mask|ControlMask, XK_r, spawn, CMD("./.dmenu/dmenu-reddio.sh") },
|
||||
{ Mod1Mask|ControlMask, XK_s, spawn, CMD("./.dmenu/dmenu-surfraw.sh") },
|
||||
{ Mod1Mask|ControlMask, XK_t, spawn, CMD("./.dmenu/dmenu-trading.sh") },
|
||||
{ Mod1Mask|ControlMask, XK_i, spawn, CMD("./.dmenu/dmenu-scrot.sh") },
|
||||
|
||||
/* Apps Launched with SUPER + ALT + KEY */
|
||||
{ MODKEY|Mod1Mask, XK_l, spawn, CMD("alacritty -e lynx gopher://distro.tube") },
|
||||
{ MODKEY|Mod1Mask, XK_f, spawn, CMD("alacritty -e sh ./.config/vifm/scripts/vifmrun") },
|
||||
{ MODKEY|Mod1Mask, XK_i, spawn, CMD("alacritty -e irssi") },
|
||||
{ MODKEY|Mod1Mask, XK_n, spawn, CMD("alacritty -e newsboat") },
|
||||
{ MODKEY|Mod1Mask, XK_r, spawn, CMD("alacritty -e rtv") },
|
||||
{ MODKEY|Mod1Mask, XK_e, spawn, CMD("alacritty -e neomutt") },
|
||||
|
||||
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|ShiftMask, XK_r, 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} },
|
||||
};
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
# dwm version
|
||||
VERSION = 6.2
|
||||
|
||||
# Customize below to fit your system
|
||||
|
||||
# paths
|
||||
PREFIX = /usr/local
|
||||
MANPREFIX = ${PREFIX}/share/man
|
||||
|
||||
X11INC = /usr/X11R6/include
|
||||
X11LIB = /usr/X11R6/lib
|
||||
|
||||
# Xinerama, comment if you don't want it
|
||||
XINERAMALIBS = -lXinerama
|
||||
XINERAMAFLAGS = -DXINERAMA
|
||||
|
||||
# freetype
|
||||
FREETYPELIBS = -lfontconfig -lXft
|
||||
FREETYPEINC = /usr/include/freetype2
|
||||
# OpenBSD (uncomment)
|
||||
#FREETYPEINC = ${X11INC}/freetype2
|
||||
|
||||
# includes and libs
|
||||
INCS = -I${X11INC} -I${FREETYPEINC}
|
||||
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lXrender
|
||||
|
||||
# flags
|
||||
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
|
||||
#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
|
||||
CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS}
|
||||
LDFLAGS = ${LIBS}
|
||||
|
||||
# Solaris
|
||||
#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
|
||||
#LDFLAGS = ${LIBS}
|
||||
|
||||
# compiler and linker
|
||||
CC = cc
|
437
dwm/drw.c
437
dwm/drw.c
|
@ -1,437 +0,0 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xft/Xft.h>
|
||||
|
||||
#include "drw.h"
|
||||
#include "util.h"
|
||||
|
||||
#define UTF_INVALID 0xFFFD
|
||||
#define UTF_SIZ 4
|
||||
|
||||
static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
|
||||
static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
|
||||
static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
|
||||
static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
|
||||
|
||||
static long
|
||||
utf8decodebyte(const char c, size_t *i)
|
||||
{
|
||||
for (*i = 0; *i < (UTF_SIZ + 1); ++(*i))
|
||||
if (((unsigned char)c & utfmask[*i]) == utfbyte[*i])
|
||||
return (unsigned char)c & ~utfmask[*i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t
|
||||
utf8validate(long *u, size_t i)
|
||||
{
|
||||
if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
|
||||
*u = UTF_INVALID;
|
||||
for (i = 1; *u > utfmax[i]; ++i)
|
||||
;
|
||||
return i;
|
||||
}
|
||||
|
||||
static size_t
|
||||
utf8decode(const char *c, long *u, size_t clen)
|
||||
{
|
||||
size_t i, j, len, type;
|
||||
long udecoded;
|
||||
|
||||
*u = UTF_INVALID;
|
||||
if (!clen)
|
||||
return 0;
|
||||
udecoded = utf8decodebyte(c[0], &len);
|
||||
if (!BETWEEN(len, 1, UTF_SIZ))
|
||||
return 1;
|
||||
for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
|
||||
udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type);
|
||||
if (type)
|
||||
return j;
|
||||
}
|
||||
if (j < len)
|
||||
return 0;
|
||||
*u = udecoded;
|
||||
utf8validate(u, len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
Drw *
|
||||
drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap)
|
||||
{
|
||||
Drw *drw = ecalloc(1, sizeof(Drw));
|
||||
|
||||
drw->dpy = dpy;
|
||||
drw->screen = screen;
|
||||
drw->root = root;
|
||||
drw->w = w;
|
||||
drw->h = h;
|
||||
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);
|
||||
XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
|
||||
|
||||
return drw;
|
||||
}
|
||||
|
||||
void
|
||||
drw_resize(Drw *drw, unsigned int w, unsigned int h)
|
||||
{
|
||||
if (!drw)
|
||||
return;
|
||||
|
||||
drw->w = w;
|
||||
drw->h = h;
|
||||
if (drw->drawable)
|
||||
XFreePixmap(drw->dpy, drw->drawable);
|
||||
drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, drw->depth);
|
||||
}
|
||||
|
||||
void
|
||||
drw_free(Drw *drw)
|
||||
{
|
||||
XFreePixmap(drw->dpy, drw->drawable);
|
||||
XFreeGC(drw->dpy, drw->gc);
|
||||
free(drw);
|
||||
}
|
||||
|
||||
/* This function is an implementation detail. Library users should use
|
||||
* drw_fontset_create instead.
|
||||
*/
|
||||
static Fnt *
|
||||
xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
|
||||
{
|
||||
Fnt *font;
|
||||
XftFont *xfont = NULL;
|
||||
FcPattern *pattern = NULL;
|
||||
|
||||
if (fontname) {
|
||||
/* Using the pattern found at font->xfont->pattern does not yield the
|
||||
* same substitution results as using the pattern returned by
|
||||
* FcNameParse; using the latter results in the desired fallback
|
||||
* behaviour whereas the former just results in missing-character
|
||||
* rectangles being drawn, at least with some fonts. */
|
||||
if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) {
|
||||
fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname);
|
||||
return NULL;
|
||||
}
|
||||
if (!(pattern = FcNameParse((FcChar8 *) fontname))) {
|
||||
fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname);
|
||||
XftFontClose(drw->dpy, xfont);
|
||||
return NULL;
|
||||
}
|
||||
} else if (fontpattern) {
|
||||
if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) {
|
||||
fprintf(stderr, "error, cannot load font from pattern.\n");
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
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->xfont = xfont;
|
||||
font->pattern = pattern;
|
||||
font->h = xfont->ascent + xfont->descent;
|
||||
font->dpy = drw->dpy;
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
static void
|
||||
xfont_free(Fnt *font)
|
||||
{
|
||||
if (!font)
|
||||
return;
|
||||
if (font->pattern)
|
||||
FcPatternDestroy(font->pattern);
|
||||
XftFontClose(font->dpy, font->xfont);
|
||||
free(font);
|
||||
}
|
||||
|
||||
Fnt*
|
||||
drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount)
|
||||
{
|
||||
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, unsigned int alpha)
|
||||
{
|
||||
if (!drw || !dest || !clrname)
|
||||
return;
|
||||
|
||||
if (!XftColorAllocName(drw->dpy, drw->visual, drw->cmap,
|
||||
clrname, dest))
|
||||
die("error, cannot allocate color '%s'", clrname);
|
||||
|
||||
dest->pixel = (dest->pixel & 0x00ffffffU) | (alpha << 24);
|
||||
}
|
||||
|
||||
/* 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[], const unsigned int alphas[], 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], alphas[i]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
drw_setfontset(Drw *drw, Fnt *set)
|
||||
{
|
||||
if (drw)
|
||||
drw->fonts = set;
|
||||
}
|
||||
|
||||
void
|
||||
drw_setscheme(Drw *drw, Clr *scm)
|
||||
{
|
||||
if (drw)
|
||||
drw->scheme = scm;
|
||||
}
|
||||
|
||||
void
|
||||
drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert)
|
||||
{
|
||||
if (!drw || !drw->scheme)
|
||||
return;
|
||||
XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel);
|
||||
if (filled)
|
||||
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
|
||||
else
|
||||
XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1);
|
||||
}
|
||||
|
||||
int
|
||||
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];
|
||||
int ty;
|
||||
unsigned int ew;
|
||||
XftDraw *d = NULL;
|
||||
Fnt *usedfont, *curfont, *nextfont;
|
||||
size_t i, len;
|
||||
int utf8strlen, utf8charlen, render = x || y || w || h;
|
||||
long utf8codepoint = 0;
|
||||
const char *utf8str;
|
||||
FcCharSet *fccharset;
|
||||
FcPattern *fcpattern;
|
||||
FcPattern *match;
|
||||
XftResult result;
|
||||
int charexists = 0;
|
||||
|
||||
if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
|
||||
return 0;
|
||||
|
||||
if (!render) {
|
||||
w = ~w;
|
||||
} else {
|
||||
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
|
||||
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
|
||||
d = XftDrawCreate(drw->dpy, drw->drawable, drw->visual, drw->cmap);
|
||||
x += lpad;
|
||||
w -= lpad;
|
||||
}
|
||||
|
||||
usedfont = drw->fonts;
|
||||
while (1) {
|
||||
utf8strlen = 0;
|
||||
utf8str = text;
|
||||
nextfont = NULL;
|
||||
while (*text) {
|
||||
utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ);
|
||||
for (curfont = drw->fonts; curfont; curfont = curfont->next) {
|
||||
charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
|
||||
if (charexists) {
|
||||
if (curfont == usedfont) {
|
||||
utf8strlen += utf8charlen;
|
||||
text += utf8charlen;
|
||||
} else {
|
||||
nextfont = curfont;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!charexists || nextfont)
|
||||
break;
|
||||
else
|
||||
charexists = 0;
|
||||
}
|
||||
|
||||
if (utf8strlen) {
|
||||
drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL);
|
||||
/* shorten text if necessary */
|
||||
for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--)
|
||||
drw_font_getexts(usedfont, utf8str, len, &ew, NULL);
|
||||
|
||||
if (len) {
|
||||
memcpy(buf, utf8str, len);
|
||||
buf[len] = '\0';
|
||||
if (len < utf8strlen)
|
||||
for (i = len; i && i > len - 3; buf[--i] = '.')
|
||||
; /* NOP */
|
||||
|
||||
if (render) {
|
||||
ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
|
||||
XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
|
||||
usedfont->xfont, x, ty, (XftChar8 *)buf, len);
|
||||
}
|
||||
x += ew;
|
||||
w -= ew;
|
||||
}
|
||||
}
|
||||
|
||||
if (!*text) {
|
||||
break;
|
||||
} else if (nextfont) {
|
||||
charexists = 0;
|
||||
usedfont = nextfont;
|
||||
} else {
|
||||
/* Regardless of whether or not a fallback font is found, the
|
||||
* character must be drawn. */
|
||||
charexists = 1;
|
||||
|
||||
fccharset = FcCharSetCreate();
|
||||
FcCharSetAddChar(fccharset, utf8codepoint);
|
||||
|
||||
if (!drw->fonts->pattern) {
|
||||
/* Refer to the comment in xfont_create for more information. */
|
||||
die("the first font in the cache must be loaded from a font string.");
|
||||
}
|
||||
|
||||
fcpattern = FcPatternDuplicate(drw->fonts->pattern);
|
||||
FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
|
||||
FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue);
|
||||
FcPatternAddBool(fcpattern, FC_COLOR, FcFalse);
|
||||
|
||||
FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
|
||||
FcDefaultSubstitute(fcpattern);
|
||||
match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result);
|
||||
|
||||
FcCharSetDestroy(fccharset);
|
||||
FcPatternDestroy(fcpattern);
|
||||
|
||||
if (match) {
|
||||
usedfont = xfont_create(drw, NULL, match);
|
||||
if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) {
|
||||
for (curfont = drw->fonts; curfont->next; curfont = curfont->next)
|
||||
; /* NOP */
|
||||
curfont->next = usedfont;
|
||||
} else {
|
||||
xfont_free(usedfont);
|
||||
usedfont = drw->fonts;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (d)
|
||||
XftDrawDestroy(d);
|
||||
|
||||
return x + (render ? w : 0);
|
||||
}
|
||||
|
||||
void
|
||||
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);
|
||||
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
|
||||
drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
|
||||
{
|
||||
XGlyphInfo ext;
|
||||
|
||||
if (!font || !text)
|
||||
return;
|
||||
|
||||
XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext);
|
||||
if (w)
|
||||
*w = ext.xOff;
|
||||
if (h)
|
||||
*h = font->h;
|
||||
}
|
||||
|
||||
Cur *
|
||||
drw_cur_create(Drw *drw, int shape)
|
||||
{
|
||||
Cur *cur;
|
||||
|
||||
if (!drw || !(cur = ecalloc(1, sizeof(Cur))))
|
||||
return NULL;
|
||||
|
||||
cur->cursor = XCreateFontCursor(drw->dpy, shape);
|
||||
|
||||
return cur;
|
||||
}
|
||||
|
||||
void
|
||||
drw_cur_free(Drw *drw, Cur *cursor)
|
||||
{
|
||||
if (!cursor)
|
||||
return;
|
||||
|
||||
XFreeCursor(drw->dpy, cursor->cursor);
|
||||
free(cursor);
|
||||
}
|
60
dwm/drw.h
60
dwm/drw.h
|
@ -1,60 +0,0 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
typedef struct {
|
||||
Cursor cursor;
|
||||
} Cur;
|
||||
|
||||
typedef struct Fnt {
|
||||
Display *dpy;
|
||||
unsigned int h;
|
||||
XftFont *xfont;
|
||||
FcPattern *pattern;
|
||||
struct Fnt *next;
|
||||
} Fnt;
|
||||
|
||||
enum { ColFg, ColBg, ColBorder }; /* Clr scheme index */
|
||||
typedef XftColor Clr;
|
||||
|
||||
typedef struct {
|
||||
unsigned int w, h;
|
||||
Display *dpy;
|
||||
int screen;
|
||||
Window root;
|
||||
Visual *visual;
|
||||
unsigned int depth;
|
||||
Colormap cmap;
|
||||
Drawable drawable;
|
||||
GC gc;
|
||||
Clr *scheme;
|
||||
Fnt *fonts;
|
||||
} Drw;
|
||||
|
||||
/* Drawable abstraction */
|
||||
Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap);
|
||||
void drw_resize(Drw *drw, unsigned int w, unsigned int h);
|
||||
void drw_free(Drw *drw);
|
||||
|
||||
/* Fnt abstraction */
|
||||
Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount);
|
||||
void drw_fontset_free(Fnt* set);
|
||||
unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
|
||||
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
|
||||
|
||||
/* Colorscheme abstraction */
|
||||
void drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha);
|
||||
Clr *drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount);
|
||||
|
||||
/* Cursor abstraction */
|
||||
Cur *drw_cur_create(Drw *drw, int shape);
|
||||
void drw_cur_free(Drw *drw, Cur *cursor);
|
||||
|
||||
/* Drawing context manipulation */
|
||||
void drw_setfontset(Drw *drw, Fnt *set);
|
||||
void drw_setscheme(Drw *drw, Clr *scm);
|
||||
|
||||
/* Drawing functions */
|
||||
void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert);
|
||||
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 */
|
||||
void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);
|
|
@ -1,289 +0,0 @@
|
|||
From f699934b8c8a9c15988ad359bf8fedd6c55abd53 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Oltmann <thomas.oltmann.hhg@gmail.com>
|
||||
Date: Wed, 13 Jun 2018 19:46:26 +0200
|
||||
Subject: [PATCH] Allow dwm to have translucent bars, while keeping all the
|
||||
text on it opaque, just like the alpha-patch for st. Updated for b69c870.
|
||||
|
||||
---
|
||||
config.def.h | 7 ++++++
|
||||
config.mk | 2 +-
|
||||
drw.c | 26 ++++++++++++-----------
|
||||
drw.h | 9 +++++---
|
||||
dwm.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++------
|
||||
5 files changed, 82 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index 1c0b587..4f68fe8 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -12,11 +12,18 @@ 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 unsigned int baralpha = 0xd0;
|
||||
+static const unsigned int borderalpha = OPAQUE;
|
||||
static const char *colors[][3] = {
|
||||
/* fg bg border */
|
||||
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
|
||||
[SchemeSel] = { col_gray4, col_cyan, col_cyan },
|
||||
};
|
||||
+static const unsigned int alphas[][3] = {
|
||||
+ /* fg bg border */
|
||||
+ [SchemeNorm] = { OPAQUE, baralpha, borderalpha },
|
||||
+ [SchemeSel] = { OPAQUE, baralpha, borderalpha },
|
||||
+};
|
||||
|
||||
/* tagging */
|
||||
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
|
||||
diff --git a/config.mk b/config.mk
|
||||
index 25e2685..bef8de0 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 c638323..77fc113 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 = ecalloc(1, sizeof(Drw));
|
||||
|
||||
@@ -70,8 +70,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);
|
||||
XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
|
||||
|
||||
return drw;
|
||||
@@ -87,7 +90,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,21 +183,22 @@ drw_fontset_free(Fnt *font)
|
||||
}
|
||||
|
||||
void
|
||||
-drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
|
||||
+drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha)
|
||||
{
|
||||
if (!drw || !dest || !clrname)
|
||||
return;
|
||||
|
||||
- if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
|
||||
- DefaultColormap(drw->dpy, drw->screen),
|
||||
+ if (!XftColorAllocName(drw->dpy, drw->visual, drw->cmap,
|
||||
clrname, dest))
|
||||
die("error, cannot allocate color '%s'", clrname);
|
||||
+
|
||||
+ dest->pixel = (dest->pixel & 0x00ffffffU) | (alpha << 24);
|
||||
}
|
||||
|
||||
/* 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)
|
||||
+drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount)
|
||||
{
|
||||
size_t i;
|
||||
Clr *ret;
|
||||
@@ -204,7 +208,7 @@ drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < clrcount; i++)
|
||||
- drw_clr_create(drw, &ret[i], clrnames[i]);
|
||||
+ drw_clr_create(drw, &ret[i], clrnames[i], alphas[i]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -260,9 +264,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
|
||||
} else {
|
||||
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
|
||||
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
|
||||
- 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);
|
||||
x += lpad;
|
||||
w -= lpad;
|
||||
}
|
||||
diff --git a/drw.h b/drw.h
|
||||
index 4bcd5ad..a56f523 100644
|
||||
--- a/drw.h
|
||||
+++ b/drw.h
|
||||
@@ -20,6 +20,9 @@ typedef struct {
|
||||
Display *dpy;
|
||||
int screen;
|
||||
Window root;
|
||||
+ Visual *visual;
|
||||
+ unsigned int depth;
|
||||
+ Colormap cmap;
|
||||
Drawable drawable;
|
||||
GC gc;
|
||||
Clr *scheme;
|
||||
@@ -27,7 +30,7 @@ typedef struct {
|
||||
} Drw;
|
||||
|
||||
/* Drawable abstraction */
|
||||
-Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
|
||||
+Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap);
|
||||
void drw_resize(Drw *drw, unsigned int w, unsigned int h);
|
||||
void drw_free(Drw *drw);
|
||||
|
||||
@@ -38,8 +41,8 @@ unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
|
||||
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
|
||||
|
||||
/* Colorscheme abstraction */
|
||||
-void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
|
||||
-Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
|
||||
+void drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha);
|
||||
+Clr *drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount);
|
||||
|
||||
/* Cursor abstraction */
|
||||
Cur *drw_cur_create(Drw *drw, int shape);
|
||||
diff --git a/dwm.c b/dwm.c
|
||||
index 4465af1..20f8309 100644
|
||||
--- a/dwm.c
|
||||
+++ b/dwm.c
|
||||
@@ -57,6 +57,8 @@
|
||||
#define TAGMASK ((1 << LENGTH(tags)) - 1)
|
||||
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
|
||||
|
||||
+#define OPAQUE 0xffU
|
||||
+
|
||||
/* enums */
|
||||
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
|
||||
enum { SchemeNorm, SchemeSel }; /* 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 */
|
||||
@@ -268,6 +271,11 @@ static Drw *drw;
|
||||
static Monitor *mons, *selmon;
|
||||
static Window root, wmcheckwin;
|
||||
|
||||
+static int useargb = 0;
|
||||
+static Visual *visual;
|
||||
+static int depth;
|
||||
+static Colormap cmap;
|
||||
+
|
||||
/* configuration, allows nested code to access above variables */
|
||||
#include "config.h"
|
||||
|
||||
@@ -1541,7 +1549,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);
|
||||
if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
|
||||
die("no fonts could be loaded.");
|
||||
lrpad = drw->fonts->h;
|
||||
@@ -1569,7 +1578,7 @@ setup(void)
|
||||
/* init appearance */
|
||||
scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
|
||||
for (i = 0; i < LENGTH(colors); i++)
|
||||
- scheme[i] = drw_scm_create(drw, colors[i], 3);
|
||||
+ scheme[i] = drw_scm_create(drw, colors[i], alphas[i], 3);
|
||||
/* init bars */
|
||||
updatebars();
|
||||
updatestatus();
|
||||
@@ -1804,16 +1813,18 @@ updatebars(void)
|
||||
Monitor *m;
|
||||
XSetWindowAttributes wa = {
|
||||
.override_redirect = True,
|
||||
- .background_pixmap = ParentRelative,
|
||||
+ .background_pixel = 0,
|
||||
+ .border_pixel = 0,
|
||||
+ .colormap = cmap,
|
||||
.event_mask = ButtonPressMask|ExposureMask
|
||||
};
|
||||
XClassHint ch = {"dwm", "dwm"};
|
||||
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);
|
||||
XSetClassHint(dpy, m->barwin, &ch);
|
||||
@@ -2110,6 +2121,43 @@ xerrorstart(Display *dpy, XErrorEvent *ee)
|
||||
return -1;
|
||||
}
|
||||
|
||||
+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)
|
||||
{
|
||||
--
|
||||
2.17.0
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
diff --git a/dwm.c b/dwm.c
|
||||
index ec6a27c..7b6ce67 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);
|
||||
@@ -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);
|
||||
@@ -407,6 +410,18 @@ attach(Client *c)
|
||||
c->mon->clients = 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)
|
||||
{
|
||||
@@ -1063,7 +1078,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);
|
||||
@@ -1193,6 +1208,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)
|
||||
{
|
||||
@@ -1418,7 +1443,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);
|
||||
@@ -1899,6 +1924,7 @@ updategeom(void)
|
||||
detachstack(c);
|
||||
c->mon = mons;
|
||||
attach(c);
|
||||
+ attachaside(c);
|
||||
attachstack(c);
|
||||
}
|
||||
if (m == selmon)
|
|
@ -1,39 +0,0 @@
|
|||
commit 5918623c5bd7fda155bf9dc3d33890c4ae1722d0
|
||||
Author: Simon Bremer <simon.bremer@tum.de>
|
||||
Date: Thu Dec 22 17:31:07 2016 +0100
|
||||
|
||||
Applied and fixed autostart patch for previous version;
|
||||
|
||||
diff --git a/dwm.c b/dwm.c
|
||||
index d27cb67..066ed71 100644
|
||||
--- a/dwm.c
|
||||
+++ b/dwm.c
|
||||
@@ -194,6 +194,7 @@ static void resizeclient(Client *c, int x, int y, int w, int h);
|
||||
static void resizemouse(const Arg *arg);
|
||||
static void restack(Monitor *m);
|
||||
static void run(void);
|
||||
+static void runAutostart(void);
|
||||
static void scan(void);
|
||||
static int sendevent(Client *c, Atom proto);
|
||||
static void sendmon(Client *c, Monitor *m);
|
||||
@@ -1386,6 +1387,12 @@ run(void)
|
||||
}
|
||||
|
||||
void
|
||||
+runAutostart(void) {
|
||||
+ system("cd ~/.dwm; ./autostart_blocking.sh");
|
||||
+ system("cd ~/.dwm; ./autostart.sh &");
|
||||
+}
|
||||
+
|
||||
+void
|
||||
scan(void)
|
||||
{
|
||||
unsigned int i, num;
|
||||
@@ -2145,6 +2152,7 @@ main(int argc, char *argv[])
|
||||
checkotherwm();
|
||||
setup();
|
||||
scan();
|
||||
+ runAutostart();
|
||||
run();
|
||||
cleanup();
|
||||
XCloseDisplay(dpy);
|
|
@ -1,93 +0,0 @@
|
|||
From a09e766a4342f580582082a92b2de65f33208eb4 Mon Sep 17 00:00:00 2001
|
||||
From: Christopher Drelich <cd@cdrakka.com>
|
||||
Date: Thu, 24 May 2018 00:56:56 -0400
|
||||
Subject: [PATCH] Function to cycle through available layouts.
|
||||
|
||||
MOD-CTRL-, and MOD-CTRL-.
|
||||
cycle backwards and forwards through available layouts.
|
||||
Probably only useful if you have a lot of additional layouts.
|
||||
The NULL, NULL layout should always be the last layout in your list,
|
||||
in order to guarantee consistent behavior.
|
||||
---
|
||||
config.def.h | 3 +++
|
||||
dwm.1 | 6 ++++++
|
||||
dwm.c | 18 ++++++++++++++++++
|
||||
3 files changed, 27 insertions(+)
|
||||
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index a9ac303..153b880 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -41,6 +41,7 @@ static const Layout layouts[] = {
|
||||
{ "[]=", tile }, /* first entry is default */
|
||||
{ "><>", NULL }, /* no layout function means floating behavior */
|
||||
{ "[M]", monocle },
|
||||
+ { NULL, NULL },
|
||||
};
|
||||
|
||||
/* key definitions */
|
||||
@@ -76,6 +77,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|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 } },
|
||||
diff --git a/dwm.1 b/dwm.1
|
||||
index 13b3729..165891b 100644
|
||||
--- a/dwm.1
|
||||
+++ b/dwm.1
|
||||
@@ -92,6 +92,12 @@ Sets monocle layout.
|
||||
.B Mod1\-space
|
||||
Toggles between current and previous layout.
|
||||
.TP
|
||||
+.B Mod1\-Control\-,
|
||||
+Cycles backwards in layout list.
|
||||
+.TP
|
||||
+.B Mod1\-Control\-.
|
||||
+Cycles forwards in layout list.
|
||||
+.TP
|
||||
.B Mod1\-j
|
||||
Focus next window.
|
||||
.TP
|
||||
diff --git a/dwm.c b/dwm.c
|
||||
index bb95e26..db73000 100644
|
||||
--- a/dwm.c
|
||||
+++ b/dwm.c
|
||||
@@ -157,6 +157,7 @@ static void configure(Client *c);
|
||||
static void configurenotify(XEvent *e);
|
||||
static void configurerequest(XEvent *e);
|
||||
static Monitor *createmon(void);
|
||||
+static void cyclelayout(const Arg *arg);
|
||||
static void destroynotify(XEvent *e);
|
||||
static void detach(Client *c);
|
||||
static void detachstack(Client *c);
|
||||
@@ -645,6 +646,23 @@ createmon(void)
|
||||
}
|
||||
|
||||
void
|
||||
+cyclelayout(const Arg *arg) {
|
||||
+ Layout *l;
|
||||
+ for(l = (Layout *)layouts; l != selmon->lt[selmon->sellt]; l++);
|
||||
+ if(arg->i > 0) {
|
||||
+ if(l->symbol && (l + 1)->symbol)
|
||||
+ setlayout(&((Arg) { .v = (l + 1) }));
|
||||
+ else
|
||||
+ setlayout(&((Arg) { .v = layouts }));
|
||||
+ } else {
|
||||
+ if(l != layouts && (l - 1)->symbol)
|
||||
+ setlayout(&((Arg) { .v = (l - 1) }));
|
||||
+ else
|
||||
+ setlayout(&((Arg) { .v = &layouts[LENGTH(layouts) - 2] }));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void
|
||||
destroynotify(XEvent *e)
|
||||
{
|
||||
Client *c;
|
||||
--
|
||||
2.7.4
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
diff --git a/dwm.c b/dwm.c
|
||||
index 4465af1..eff2da6 100644
|
||||
--- a/dwm.c
|
||||
+++ b/dwm.c
|
||||
@@ -695,10 +695,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 */
|
||||
@@ -709,6 +709,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;
|
||||
@@ -729,15 +731,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) + lrpad;
|
||||
+ 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);
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
From b04bb473cf9818277d33a591f7fe2dfae96afaaf Mon Sep 17 00:00:00 2001
|
||||
From: Joshua Haase <hahj87@gmail.com>
|
||||
Date: Mon, 15 Aug 2016 17:06:18 -0500
|
||||
Subject: [PATCH] Apply modified gridmode patch.
|
||||
|
||||
---
|
||||
config.def.h | 3 +++
|
||||
layouts.c | 27 +++++++++++++++++++++++++++
|
||||
2 files changed, 30 insertions(+)
|
||||
create mode 100644 layouts.c
|
||||
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index a9ac303..30b7c4a 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -36,11 +36,13 @@ 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 },
|
||||
+ { "HHH", grid },
|
||||
};
|
||||
|
||||
/* key definitions */
|
||||
@@ -76,6 +78,7 @@ 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_g, setlayout, {.v = &layouts[3]} },
|
||||
{ MODKEY, XK_space, setlayout, {0} },
|
||||
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
|
||||
{ MODKEY, XK_0, view, {.ui = ~0 } },
|
||||
diff --git a/layouts.c b/layouts.c
|
||||
new file mode 100644
|
||||
index 0000000..d26acf3
|
||||
--- /dev/null
|
||||
+++ b/layouts.c
|
||||
@@ -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++;
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
2.14.1
|
||||
|
|
@ -1,139 +0,0 @@
|
|||
From 2991f37f0aaf44b9f9b11e7893ff0af8eb88f649 Mon Sep 17 00:00:00 2001
|
||||
From: Christopher Drelich <cd@cdrakka.com>
|
||||
Date: Wed, 23 May 2018 22:50:38 -0400
|
||||
Subject: [PATCH] Modifies quit to handle restarts and adds SIGHUP and SIGTERM
|
||||
handlers.
|
||||
|
||||
Modified quit() to restart if it receives arg .i = 1
|
||||
MOD+CTRL+SHIFT+Q was added to confid.def.h to do just that.
|
||||
|
||||
Signal handlers were handled for SIGHUP and SIGTERM.
|
||||
If dwm receives these signals it calls quit() with
|
||||
arg .i = to 1 or 0, respectively.
|
||||
|
||||
To restart dwm:
|
||||
MOD+CTRL+SHIFT+Q
|
||||
or
|
||||
kill -HUP dwmpid
|
||||
|
||||
To quit dwm cleanly:
|
||||
MOD+SHIFT+Q
|
||||
or
|
||||
kill -TERM dwmpid
|
||||
---
|
||||
config.def.h | 1 +
|
||||
dwm.1 | 10 ++++++++++
|
||||
dwm.c | 22 ++++++++++++++++++++++
|
||||
3 files changed, 33 insertions(+)
|
||||
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index a9ac303..e559429 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -94,6 +94,7 @@ static Key keys[] = {
|
||||
TAGKEYS( XK_8, 7)
|
||||
TAGKEYS( XK_9, 8)
|
||||
{ MODKEY|ShiftMask, XK_q, quit, {0} },
|
||||
+ { MODKEY|ControlMask|ShiftMask, XK_q, quit, {1} },
|
||||
};
|
||||
|
||||
/* button definitions */
|
||||
diff --git a/dwm.1 b/dwm.1
|
||||
index 13b3729..36a331c 100644
|
||||
--- a/dwm.1
|
||||
+++ b/dwm.1
|
||||
@@ -142,6 +142,9 @@ Add/remove all windows with nth tag to/from the view.
|
||||
.TP
|
||||
.B Mod1\-Shift\-q
|
||||
Quit dwm.
|
||||
+.TP
|
||||
+.B Mod1\-Control\-Shift\-q
|
||||
+Restart dwm.
|
||||
.SS Mouse commands
|
||||
.TP
|
||||
.B Mod1\-Button1
|
||||
@@ -155,6 +158,13 @@ Resize focused window while dragging. Tiled windows will be toggled to the float
|
||||
.SH CUSTOMIZATION
|
||||
dwm is customized by creating a custom config.h and (re)compiling the source
|
||||
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
|
||||
.BR dmenu (1),
|
||||
.BR st (1)
|
||||
diff --git a/dwm.c b/dwm.c
|
||||
index bb95e26..286eecd 100644
|
||||
--- a/dwm.c
|
||||
+++ b/dwm.c
|
||||
@@ -205,6 +205,8 @@ static void setup(void);
|
||||
static void seturgent(Client *c, int urg);
|
||||
static void showhide(Client *c);
|
||||
static void sigchld(int unused);
|
||||
+static void sighup(int unused);
|
||||
+static void sigterm(int unused);
|
||||
static void spawn(const Arg *arg);
|
||||
static void tag(const Arg *arg);
|
||||
static void tagmon(const Arg *arg);
|
||||
@@ -260,6 +262,7 @@ static void (*handler[LASTEvent]) (XEvent *) = {
|
||||
[UnmapNotify] = unmapnotify
|
||||
};
|
||||
static Atom wmatom[WMLast], netatom[NetLast];
|
||||
+static int restart = 0;
|
||||
static int running = 1;
|
||||
static Cur *cursor[CurLast];
|
||||
static Clr **scheme;
|
||||
@@ -1248,6 +1251,7 @@ propertynotify(XEvent *e)
|
||||
void
|
||||
quit(const Arg *arg)
|
||||
{
|
||||
+ if(arg->i) restart = 1;
|
||||
running = 0;
|
||||
}
|
||||
|
||||
@@ -1536,6 +1540,9 @@ setup(void)
|
||||
/* clean up any zombies immediately */
|
||||
sigchld(0);
|
||||
|
||||
+ signal(SIGHUP, sighup);
|
||||
+ signal(SIGTERM, sigterm);
|
||||
+
|
||||
/* init screen */
|
||||
screen = DefaultScreen(dpy);
|
||||
sw = DisplayWidth(dpy, screen);
|
||||
@@ -1637,6 +1644,20 @@ sigchld(int unused)
|
||||
}
|
||||
|
||||
void
|
||||
+sighup(int unused)
|
||||
+{
|
||||
+ Arg a = {.i = 1};
|
||||
+ quit(&a);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+sigterm(int unused)
|
||||
+{
|
||||
+ Arg a = {.i = 0};
|
||||
+ quit(&a);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
spawn(const Arg *arg)
|
||||
{
|
||||
if (arg->v == dmenucmd)
|
||||
@@ -2139,6 +2160,7 @@ main(int argc, char *argv[])
|
||||
setup();
|
||||
scan();
|
||||
run();
|
||||
+ if(restart) execvp(argv[0], argv);
|
||||
cleanup();
|
||||
XCloseDisplay(dpy);
|
||||
return EXIT_SUCCESS;
|
||||
--
|
||||
2.7.4
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
diff --git a/config.def.h b/config.def.h
|
||||
index fd77a07..09737d7 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -64,6 +64,8 @@ static Key keys[] = {
|
||||
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
|
||||
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
|
||||
{ MODKEY, XK_b, togglebar, {0} },
|
||||
+ { MODKEY|ShiftMask, XK_j, rotatestack, {.i = +1 } },
|
||||
+ { MODKEY|ShiftMask, XK_k, rotatestack, {.i = -1 } },
|
||||
{ MODKEY, XK_j, focusstack, {.i = +1 } },
|
||||
{ MODKEY, XK_k, focusstack, {.i = -1 } },
|
||||
{ MODKEY, XK_i, incnmaster, {.i = +1 } },
|
||||
diff --git a/dwm.c b/dwm.c
|
||||
index 421bf27..1ec8b10 100644
|
||||
--- a/dwm.c
|
||||
+++ b/dwm.c
|
||||
@@ -165,6 +165,8 @@ static void detachstack(Client *c);
|
||||
static Monitor *dirtomon(int dir);
|
||||
static void drawbar(Monitor *m);
|
||||
static void drawbars(void);
|
||||
+static void enqueue(Client *c);
|
||||
+static void enqueuestack(Client *c);
|
||||
static void enternotify(XEvent *e);
|
||||
static void expose(XEvent *e);
|
||||
static void focus(Client *c);
|
||||
@@ -194,6 +196,7 @@ static void resize(Client *c, int x, int y, int w, int h, int interact);
|
||||
static void resizeclient(Client *c, int x, int y, int w, int h);
|
||||
static void resizemouse(const Arg *arg);
|
||||
static void restack(Monitor *m);
|
||||
+static void rotatestack(const Arg *arg);
|
||||
static void run(void);
|
||||
static void scan(void);
|
||||
static int sendevent(Client *c, Atom proto);
|
||||
@@ -765,6 +768,28 @@ drawbars(void)
|
||||
}
|
||||
|
||||
void
|
||||
+enqueue(Client *c)
|
||||
+{
|
||||
+ Client *l;
|
||||
+ for (l = c->mon->clients; l && l->next; l = l->next);
|
||||
+ if (l) {
|
||||
+ l->next = c;
|
||||
+ c->next = NULL;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+enqueuestack(Client *c)
|
||||
+{
|
||||
+ Client *l;
|
||||
+ for (l = c->mon->stack; l && l->snext; l = l->snext);
|
||||
+ if (l) {
|
||||
+ l->snext = c;
|
||||
+ c->snext = NULL;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void
|
||||
enternotify(XEvent *e)
|
||||
{
|
||||
Client *c;
|
||||
@@ -1390,6 +1415,38 @@ restack(Monitor *m)
|
||||
}
|
||||
|
||||
void
|
||||
+rotatestack(const Arg *arg)
|
||||
+{
|
||||
+ Client *c = NULL, *f;
|
||||
+
|
||||
+ if (!selmon->sel)
|
||||
+ return;
|
||||
+ f = selmon->sel;
|
||||
+ if (arg->i > 0) {
|
||||
+ for (c = nexttiled(selmon->clients); c && nexttiled(c->next); c = nexttiled(c->next));
|
||||
+ if (c){
|
||||
+ detach(c);
|
||||
+ attach(c);
|
||||
+ detachstack(c);
|
||||
+ attachstack(c);
|
||||
+ }
|
||||
+ } else {
|
||||
+ if ((c = nexttiled(selmon->clients))){
|
||||
+ detach(c);
|
||||
+ enqueue(c);
|
||||
+ detachstack(c);
|
||||
+ enqueuestack(c);
|
||||
+ }
|
||||
+ }
|
||||
+ if (c){
|
||||
+ arrange(selmon);
|
||||
+ //unfocus(f, 1);
|
||||
+ focus(f);
|
||||
+ restack(selmon);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void
|
||||
run(void)
|
||||
{
|
||||
XEvent ev;
|
|
@ -1,62 +0,0 @@
|
|||
From 75d5edbe16ee2fc060ff8b05eea17791d6334a59 Mon Sep 17 00:00:00 2001
|
||||
From: Christopher Drelich <cd@cdrakka.com>
|
||||
Date: Thu, 24 May 2018 23:24:12 -0400
|
||||
Subject: [PATCH] Replaces magic numbers in statusbar with configurable
|
||||
variables.
|
||||
|
||||
horizpadbar for horizontal statusbar padding
|
||||
vertpadbar for vertical statusbar padding
|
||||
|
||||
StatusText now has both left and right padding,
|
||||
as well as the vertical padding that all of the statusbar shares.
|
||||
|
||||
Other than the addition of left padding to StatusText, appearance
|
||||
of the statusbar is identical to pre-patch when using the defaults
|
||||
in config.def.h
|
||||
---
|
||||
config.def.h | 2 ++
|
||||
dwm.c | 8 ++++----
|
||||
2 files changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index a9ac303..5819399 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -5,6 +5,8 @@ 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 */
|
||||
static const int topbar = 1; /* 0 means bottom bar */
|
||||
+static const int horizpadbar = 2; /* horizontal padding for statusbar */
|
||||
+static const int vertpadbar = 0; /* vertical padding for statusbar */
|
||||
static const char *fonts[] = { "monospace:size=10" };
|
||||
static const char dmenufont[] = "monospace:size=10";
|
||||
static const char col_gray1[] = "#222222";
|
||||
diff --git a/dwm.c b/dwm.c
|
||||
index bb95e26..7b9ed42 100644
|
||||
--- a/dwm.c
|
||||
+++ b/dwm.c
|
||||
@@ -704,8 +704,8 @@ drawbar(Monitor *m)
|
||||
/* 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; /* 2px right padding */
|
||||
- drw_text(drw, m->ww - sw, 0, sw, bh, 0, stext, 0);
|
||||
+ sw = TEXTW(stext);
|
||||
+ drw_text(drw, m->ww - sw, 0, sw, bh, lrpad / 2, stext, 0);
|
||||
}
|
||||
|
||||
for (c = m->clients; c; c = c->next) {
|
||||
@@ -1544,8 +1544,8 @@ setup(void)
|
||||
drw = drw_create(dpy, screen, root, sw, sh);
|
||||
if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
|
||||
die("no fonts could be loaded.");
|
||||
- lrpad = drw->fonts->h;
|
||||
- bh = drw->fonts->h + 2;
|
||||
+ lrpad = drw->fonts->h + horizpadbar;
|
||||
+ bh = drw->fonts->h + vertpadbar;
|
||||
updategeom();
|
||||
/* init atoms */
|
||||
utf8string = XInternAtom(dpy, "UTF8_STRING", False);
|
||||
--
|
||||
2.7.4
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
--- dwm/dwm.c.orig 2015-11-22 13:26:16.664650238 -0700
|
||||
+++ dwm/dwm.c 2015-11-22 13:25:57.407984351 -0700
|
||||
@@ -52,8 +52,8 @@
|
||||
#define ISVISIBLE(C) ((C->tags & 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)
|
||||
-#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
|
||||
+#define WIDTH(X) ((X)->w + 2 * (X)->bw + gappx)
|
||||
+#define HEIGHT(X) ((X)->h + 2 * (X)->bw + gappx)
|
||||
#define TAGMASK ((1 << LENGTH(tags)) - 1)
|
||||
#define TEXTW(X) (drw_text(drw, 0, 0, 0, 0, (X), 0) + drw->fonts[0]->h)
|
||||
|
||||
@@ -1293,12 +1293,36 @@ void
|
||||
resizeclient(Client *c, int x, int y, int w, int h)
|
||||
{
|
||||
XWindowChanges wc;
|
||||
+ unsigned int n;
|
||||
+ unsigned int gapoffset;
|
||||
+ unsigned int gapincr;
|
||||
+ Client *nbc;
|
||||
|
||||
- c->oldx = c->x; c->x = wc.x = x;
|
||||
- c->oldy = c->y; c->y = wc.y = y;
|
||||
- c->oldw = c->w; c->w = wc.width = w;
|
||||
- c->oldh = c->h; c->h = wc.height = h;
|
||||
wc.border_width = c->bw;
|
||||
+
|
||||
+ /* Get number of clients for the selected monitor */
|
||||
+ for (n = 0, nbc = nexttiled(selmon->clients); nbc; nbc = nexttiled(nbc->next), n++);
|
||||
+
|
||||
+ /* Do nothing if layout is floating */
|
||||
+ if (c->isfloating || selmon->lt[selmon->sellt]->arrange == NULL) {
|
||||
+ gapincr = gapoffset = 0;
|
||||
+ } else {
|
||||
+ /* Remove border and gap if layout is monocle or only one client */
|
||||
+ if (selmon->lt[selmon->sellt]->arrange == monocle || n == 1) {
|
||||
+ gapoffset = 0;
|
||||
+ gapincr = -2 * borderpx;
|
||||
+ wc.border_width = 0;
|
||||
+ } else {
|
||||
+ gapoffset = gappx;
|
||||
+ gapincr = 2 * gappx;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ c->oldx = c->x; c->x = wc.x = x + gapoffset;
|
||||
+ c->oldy = c->y; c->y = wc.y = y + gapoffset;
|
||||
+ c->oldw = c->w; c->w = wc.width = w - gapincr;
|
||||
+ c->oldh = c->h; c->h = wc.height = h - gapincr;
|
||||
+
|
||||
XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
|
||||
configure(c);
|
||||
XSync(dpy, False);
|
192
dwm/dwm.1
192
dwm/dwm.1
|
@ -1,192 +0,0 @@
|
|||
.TH DWM 1 dwm\-VERSION
|
||||
.SH NAME
|
||||
dwm \- dynamic window manager
|
||||
.SH SYNOPSIS
|
||||
.B dwm
|
||||
.RB [ \-v ]
|
||||
.SH DESCRIPTION
|
||||
dwm is a dynamic window manager for X. It manages windows in tiled, monocle
|
||||
and floating layouts. Either layout can be applied dynamically, optimising the
|
||||
environment for the application in use and the task performed.
|
||||
.P
|
||||
In tiled layouts windows are managed in a master and stacking area. The master
|
||||
area on the left contains one window by default, and the stacking area on the
|
||||
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
|
||||
moved freely. Dialog windows are always managed floating, regardless of the
|
||||
layout applied.
|
||||
.P
|
||||
Windows are grouped by tags. Each window can be tagged with one or multiple
|
||||
tags. Selecting certain tags displays all windows with these tags.
|
||||
.P
|
||||
Each screen contains a small status bar which displays all available tags, the
|
||||
layout, the title of the focused window, and the text read from the root window
|
||||
name property, if the screen is focused. A floating window is indicated with an
|
||||
empty square and a maximised floating window is indicated with a filled square
|
||||
before the windows title. The selected tags are indicated with a different
|
||||
color. The tags of the focused window are indicated with a filled square in the
|
||||
top left corner. The tags which are applied to one or more windows are
|
||||
indicated with an empty square in the top left corner.
|
||||
.P
|
||||
dwm draws a small border around windows to indicate the focus state.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-v
|
||||
prints version information to standard output, then exits.
|
||||
.SH USAGE
|
||||
.SS Status bar
|
||||
.TP
|
||||
.B X root window name
|
||||
is read and displayed in the status text area. It can be set with the
|
||||
.BR xsetroot (1)
|
||||
command.
|
||||
.TP
|
||||
.B Button1
|
||||
click on a tag label to display all windows with that tag, click on the layout
|
||||
label toggles between tiled and floating layout.
|
||||
.TP
|
||||
.B Button3
|
||||
click on a tag label adds/removes all windows with that tag to/from the view.
|
||||
.TP
|
||||
.B Mod1\-Button1
|
||||
click on a tag label applies that tag to the focused window.
|
||||
.TP
|
||||
.B Mod1\-Button3
|
||||
click on a tag label adds/removes that tag to/from the focused window.
|
||||
.SS Keyboard commands
|
||||
.TP
|
||||
.B Mod1\-Shift\-Return
|
||||
Start
|
||||
.BR st(1).
|
||||
.TP
|
||||
.B Mod1\-p
|
||||
Spawn
|
||||
.BR dmenu(1)
|
||||
for launching other programs.
|
||||
.TP
|
||||
.B Mod1\-,
|
||||
Focus previous screen, if any.
|
||||
.TP
|
||||
.B Mod1\-.
|
||||
Focus next screen, if any.
|
||||
.TP
|
||||
.B Mod1\-Shift\-,
|
||||
Send focused window to previous screen, if any.
|
||||
.TP
|
||||
.B Mod1\-Shift\-.
|
||||
Send focused window to next screen, if any.
|
||||
.TP
|
||||
.B Mod1\-b
|
||||
Toggles bar on and off.
|
||||
.TP
|
||||
.B Mod1\-t
|
||||
Sets tiled layout.
|
||||
.TP
|
||||
.B Mod1\-f
|
||||
Sets floating layout.
|
||||
.TP
|
||||
.B Mod1\-m
|
||||
Sets monocle layout.
|
||||
.TP
|
||||
.B Mod1\-space
|
||||
Toggles between current and previous layout.
|
||||
.TP
|
||||
.B Mod1\-Control\-,
|
||||
Cycles backwards in layout list.
|
||||
.TP
|
||||
.B Mod1\-Control\-.
|
||||
Cycles forwards in layout list.
|
||||
.TP
|
||||
.B Mod1\-j
|
||||
Focus next window.
|
||||
.TP
|
||||
.B Mod1\-k
|
||||
Focus previous window.
|
||||
.TP
|
||||
.B Mod1\-i
|
||||
Increase number of windows in master area.
|
||||
.TP
|
||||
.B Mod1\-d
|
||||
Decrease number of windows in master area.
|
||||
.TP
|
||||
.B Mod1\-l
|
||||
Increase master area size.
|
||||
.TP
|
||||
.B Mod1\-h
|
||||
Decrease master area size.
|
||||
.TP
|
||||
.B Mod1\-Return
|
||||
Zooms/cycles focused window to/from master area (tiled layouts only).
|
||||
.TP
|
||||
.B Mod1\-Shift\-c
|
||||
Close focused window.
|
||||
.TP
|
||||
.B Mod1\-Shift\-space
|
||||
Toggle focused window between tiled and floating state.
|
||||
.TP
|
||||
.B Mod1\-Tab
|
||||
Toggles to the previously selected tags.
|
||||
.TP
|
||||
.B Mod1\-Shift\-[1..n]
|
||||
Apply nth tag to focused window.
|
||||
.TP
|
||||
.B Mod1\-Shift\-0
|
||||
Apply all tags to focused window.
|
||||
.TP
|
||||
.B Mod1\-Control\-Shift\-[1..n]
|
||||
Add/remove nth tag to/from focused window.
|
||||
.TP
|
||||
.B Mod1\-[1..n]
|
||||
View all windows with nth tag.
|
||||
.TP
|
||||
.B Mod1\-0
|
||||
View all windows with any tag.
|
||||
.TP
|
||||
.B Mod1\-Control\-[1..n]
|
||||
Add/remove all windows with nth tag to/from the view.
|
||||
.TP
|
||||
.B Mod1\-Shift\-q
|
||||
Quit dwm.
|
||||
.TP
|
||||
.B Mod1\-Control\-Shift\-q
|
||||
Restart dwm.
|
||||
.SS Mouse commands
|
||||
.TP
|
||||
.B Mod1\-Button1
|
||||
Move focused window while dragging. Tiled windows will be toggled to the floating state.
|
||||
.TP
|
||||
.B Mod1\-Button2
|
||||
Toggles focused window between floating and tiled state.
|
||||
.TP
|
||||
.B Mod1\-Button3
|
||||
Resize focused window while dragging. Tiled windows will be toggled to the floating state.
|
||||
.SH CUSTOMIZATION
|
||||
dwm is customized by creating a custom config.h and (re)compiling the source
|
||||
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
|
||||
.BR dmenu (1),
|
||||
.BR st (1)
|
||||
.SH ISSUES
|
||||
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
|
||||
JDK 1.6 versions, because it assumes a reparenting window manager. Possible workarounds
|
||||
are using JDK 1.4 (which doesn't contain the XToolkit/XAWT backend) or setting the
|
||||
environment variable
|
||||
.BR AWT_TOOLKIT=MToolkit
|
||||
(to use the older Motif backend instead) or running
|
||||
.B xprop -root -f _NET_WM_NAME 32a -set _NET_WM_NAME LG3D
|
||||
or
|
||||
.B wmname LG3D
|
||||
(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
|
||||
.BR _JAVA_AWT_WM_NONREPARENTING=1 .
|
||||
.SH BUGS
|
||||
Send all bug reports with a patch to hackers@suckless.org.
|
2356
dwm/dwm.c.orig
2356
dwm/dwm.c.orig
File diff suppressed because it is too large
Load diff
BIN
dwm/dwm.png
BIN
dwm/dwm.png
Binary file not shown.
Before Width: | Height: | Size: 373 B |
|
@ -1,27 +0,0 @@
|
|||
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++;
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
/* cc transient.c -o transient -lX11 */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
int main(void) {
|
||||
Display *d;
|
||||
Window r, f, t = None;
|
||||
XSizeHints h;
|
||||
XEvent e;
|
||||
|
||||
d = XOpenDisplay(NULL);
|
||||
if (!d)
|
||||
exit(1);
|
||||
r = DefaultRootWindow(d);
|
||||
|
||||
f = XCreateSimpleWindow(d, r, 100, 100, 400, 400, 0, 0, 0);
|
||||
h.min_width = h.max_width = h.min_height = h.max_height = 400;
|
||||
h.flags = PMinSize | PMaxSize;
|
||||
XSetWMNormalHints(d, f, &h);
|
||||
XStoreName(d, f, "floating");
|
||||
XMapWindow(d, f);
|
||||
|
||||
XSelectInput(d, f, ExposureMask);
|
||||
while (1) {
|
||||
XNextEvent(d, &e);
|
||||
|
||||
if (t == None) {
|
||||
sleep(5);
|
||||
t = XCreateSimpleWindow(d, r, 50, 50, 100, 100, 0, 0, 0);
|
||||
XSetTransientForHint(d, t, f);
|
||||
XStoreName(d, t, "transient");
|
||||
XMapWindow(d, t);
|
||||
XSelectInput(d, t, ExposureMask);
|
||||
}
|
||||
}
|
||||
|
||||
XCloseDisplay(d);
|
||||
exit(0);
|
||||
}
|
35
dwm/util.c
35
dwm/util.c
|
@ -1,35 +0,0 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
void *
|
||||
ecalloc(size_t nmemb, size_t size)
|
||||
{
|
||||
void *p;
|
||||
|
||||
if (!(p = calloc(nmemb, size)))
|
||||
die("calloc:");
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
die(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
|
||||
fputc(' ', stderr);
|
||||
perror(NULL);
|
||||
} else {
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
#define MAX(A, B) ((A) > (B) ? (A) : (B))
|
||||
#define MIN(A, B) ((A) < (B) ? (A) : (B))
|
||||
#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B))
|
||||
|
||||
void die(const char *fmt, ...);
|
||||
void *ecalloc(size_t nmemb, size_t size);
|
339
dwmblocks/LICENSE
Normal file
339
dwmblocks/LICENSE
Normal file
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
7
dwmblocks/Makefile
Normal file
7
dwmblocks/Makefile
Normal file
|
@ -0,0 +1,7 @@
|
|||
output: dwmblocks.c blocks.h
|
||||
cc `pkg-config --cflags x11` `pkg-config --libs x11` dwmblocks.c -o dwmblocks
|
||||
clean:
|
||||
rm -f *.o *.gch dwmblocks
|
||||
install: output
|
||||
mkdir -p /usr/local/bin
|
||||
cp -f dwmblocks /usr/local/bin
|
5
dwmblocks/README.md
Normal file
5
dwmblocks/README.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# dwmblocks
|
||||
Modular status bar for dwm written in c.
|
||||
# modifying blocks
|
||||
The statusbar is made from text output from commandline programs.
|
||||
Blocks are added and removed by editing the blocks.h header file.
|
18
dwmblocks/blocks.h
Normal file
18
dwmblocks/blocks.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
//Modify this file to change what commands output to your statusbar, and recompile using the make command.
|
||||
static const Block blocks[] = {
|
||||
/*Icon*/ /*Command*/ /*Update Interval*/ /*Update Signal*/
|
||||
{" 🐧 ", "kernel", 360, 2},
|
||||
|
||||
{" ▲ ", "upt", 60, 2},
|
||||
|
||||
{" 📦 ", "pacupdate", 360, 9},
|
||||
|
||||
{" 💻 ", "memory", 6, 1},
|
||||
|
||||
{" 🔊 ", "volume", 2, 10},
|
||||
|
||||
{" 🕑 ", "clock", 5, 0},
|
||||
};
|
||||
|
||||
//sets delimeter between status commands. NULL character ('\0') means no delimeter.
|
||||
static char delim = '|';
|
BIN
dwmblocks/dwmblocks
Executable file
BIN
dwmblocks/dwmblocks
Executable file
Binary file not shown.
175
dwmblocks/dwmblocks.c
Normal file
175
dwmblocks/dwmblocks.c
Normal file
|
@ -0,0 +1,175 @@
|
|||
#include<stdlib.h>
|
||||
#include<stdio.h>
|
||||
#include<string.h>
|
||||
#include<unistd.h>
|
||||
#include<signal.h>
|
||||
#include<X11/Xlib.h>
|
||||
#define LENGTH(X) (sizeof(X) / sizeof (X[0]))
|
||||
#define CMDLENGTH 50
|
||||
|
||||
typedef struct {
|
||||
char* icon;
|
||||
char* command;
|
||||
unsigned int interval;
|
||||
unsigned int signal;
|
||||
} Block;
|
||||
void sighandler(int num);
|
||||
void replace(char *str, char old, char new);
|
||||
void getcmds(int time);
|
||||
#ifndef __OpenBSD__
|
||||
void getsigcmds(int signal);
|
||||
void setupsignals();
|
||||
void sighandler(int signum);
|
||||
#endif
|
||||
int getstatus(char *str, char *last);
|
||||
void setroot();
|
||||
void statusloop();
|
||||
void termhandler(int signum);
|
||||
|
||||
|
||||
#include "blocks.h"
|
||||
|
||||
static Display *dpy;
|
||||
static int screen;
|
||||
static Window root;
|
||||
static char statusbar[LENGTH(blocks)][CMDLENGTH] = {0};
|
||||
static char statusstr[2][256];
|
||||
static int statusContinue = 1;
|
||||
static void (*writestatus) () = setroot;
|
||||
|
||||
void replace(char *str, char old, char new)
|
||||
{
|
||||
int N = strlen(str);
|
||||
for(int i = 0; i < N; i++)
|
||||
if(str[i] == old)
|
||||
str[i] = new;
|
||||
}
|
||||
|
||||
//opens process *cmd and stores output in *output
|
||||
void getcmd(const Block *block, char *output)
|
||||
{
|
||||
strcpy(output, block->icon);
|
||||
char *cmd = block->command;
|
||||
FILE *cmdf = popen(cmd,"r");
|
||||
if (!cmdf)
|
||||
return;
|
||||
char c;
|
||||
int i = strlen(block->icon);
|
||||
fgets(output+i, CMDLENGTH-i, cmdf);
|
||||
i = strlen(output);
|
||||
if (delim != '\0' && --i)
|
||||
output[i++] = delim;
|
||||
output[i++] = '\0';
|
||||
pclose(cmdf);
|
||||
}
|
||||
|
||||
void getcmds(int time)
|
||||
{
|
||||
const Block* current;
|
||||
for(int i = 0; i < LENGTH(blocks); i++)
|
||||
{
|
||||
current = blocks + i;
|
||||
if ((current->interval != 0 && time % current->interval == 0) || time == -1)
|
||||
getcmd(current,statusbar[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef __OpenBSD__
|
||||
void getsigcmds(int signal)
|
||||
{
|
||||
const Block *current;
|
||||
for (int i = 0; i < LENGTH(blocks); i++)
|
||||
{
|
||||
current = blocks + i;
|
||||
if (current->signal == signal)
|
||||
getcmd(current,statusbar[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void setupsignals()
|
||||
{
|
||||
for(int i = 0; i < LENGTH(blocks); i++)
|
||||
{
|
||||
if (blocks[i].signal > 0)
|
||||
signal(SIGRTMIN+blocks[i].signal, sighandler);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
int getstatus(char *str, char *last)
|
||||
{
|
||||
strcpy(last, str);
|
||||
str[0] = '\0';
|
||||
for(int i = 0; i < LENGTH(blocks); i++)
|
||||
strcat(str, statusbar[i]);
|
||||
str[strlen(str)-1] = '\0';
|
||||
return strcmp(str, last);//0 if they are the same
|
||||
}
|
||||
|
||||
void setroot()
|
||||
{
|
||||
if (!getstatus(statusstr[0], statusstr[1]))//Only set root if text has changed.
|
||||
return;
|
||||
Display *d = XOpenDisplay(NULL);
|
||||
if (d) {
|
||||
dpy = d;
|
||||
}
|
||||
screen = DefaultScreen(dpy);
|
||||
root = RootWindow(dpy, screen);
|
||||
XStoreName(dpy, root, statusstr[0]);
|
||||
XCloseDisplay(dpy);
|
||||
}
|
||||
|
||||
void pstdout()
|
||||
{
|
||||
if (!getstatus(statusstr[0], statusstr[1]))//Only write out if text has changed.
|
||||
return;
|
||||
printf("%s\n",statusstr[0]);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
||||
void statusloop()
|
||||
{
|
||||
#ifndef __OpenBSD__
|
||||
setupsignals();
|
||||
#endif
|
||||
int i = 0;
|
||||
getcmds(-1);
|
||||
while(statusContinue)
|
||||
{
|
||||
getcmds(i);
|
||||
writestatus();
|
||||
sleep(1.0);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef __OpenBSD__
|
||||
void sighandler(int signum)
|
||||
{
|
||||
getsigcmds(signum-SIGRTMIN);
|
||||
writestatus();
|
||||
}
|
||||
#endif
|
||||
|
||||
void termhandler(int signum)
|
||||
{
|
||||
statusContinue = 0;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
for(int i = 0; i < argc; i++)
|
||||
{
|
||||
if (!strcmp("-d",argv[i]))
|
||||
delim = argv[++i][0];
|
||||
else if(!strcmp("-p",argv[i]))
|
||||
writestatus = pstdout;
|
||||
}
|
||||
signal(SIGTERM, termhandler);
|
||||
signal(SIGINT, termhandler);
|
||||
statusloop();
|
||||
}
|
48
st/FAQ
48
st/FAQ
|
@ -1,6 +1,6 @@
|
|||
## Why does st not handle utmp entries?
|
||||
|
||||
Use the excellent tool of [utmp](http://git.suckless.org/utmp/) for this task.
|
||||
Use the excellent tool of [utmp](https://git.suckless.org/utmp/) for this task.
|
||||
|
||||
## Some _random program_ complains that st is unknown/not recognised/unsupported/whatever!
|
||||
|
||||
|
@ -15,13 +15,6 @@ you can manually run `tic -sx st.info`.
|
|||
* Some programs don’t complain about the lacking st description and default to
|
||||
another terminal. In that case see the question about terminfo.
|
||||
|
||||
## I get some weird glitches/visual bug on _random program_!
|
||||
|
||||
Try launching it with a different TERM: $ TERM=xterm myapp. toe(1) will give
|
||||
you a list of available terminals, but you’ll most likely switch between xterm,
|
||||
st or st-256color. The default value for TERM can be changed in config.h
|
||||
(TNAME).
|
||||
|
||||
## How do I scroll back up?
|
||||
|
||||
Using a terminal multiplexer.
|
||||
|
@ -104,7 +97,7 @@ St is emulating the Linux way of handling backspace being delete and delete bein
|
|||
backspace.
|
||||
|
||||
This is an issue that was discussed in suckless mailing list
|
||||
<http://lists.suckless.org/dev/1404/20697.html>. Here is why some old grumpy
|
||||
<https://lists.suckless.org/dev/1404/20697.html>. Here is why some old grumpy
|
||||
terminal users wants its backspace to be how he feels it:
|
||||
|
||||
Well, I am going to comment why I want to change the behaviour
|
||||
|
@ -163,5 +156,40 @@ terminal users wants its backspace to be how he feels it:
|
|||
|
||||
Apply [1].
|
||||
|
||||
[1] http://st.suckless.org/patches/delkey
|
||||
[1] https://st.suckless.org/patches/delkey
|
||||
|
||||
## Why do images not work in st (in programs such as w3m)?
|
||||
|
||||
This is a terrible hack that overdraws an image on top of the terminal emulator
|
||||
window. It also relies on a very specific way the terminal draws it's contents.
|
||||
|
||||
A more proper (but limited way) would be using sixels. Which st doesn't
|
||||
support.
|
||||
|
||||
## BadLength X error in Xft when trying to render emoji
|
||||
|
||||
Xft makes st crash when rendering color emojis with the following error:
|
||||
|
||||
"X Error of failed request: BadLength (poly request too large or internal Xlib length error)"
|
||||
Major opcode of failed request: 139 (RENDER)
|
||||
Minor opcode of failed request: 20 (RenderAddGlyphs)
|
||||
Serial number of failed request: 1595
|
||||
Current serial number in output stream: 1818"
|
||||
|
||||
This is a known bug in Xft (not st) which happens on some platforms and
|
||||
combination of particular fonts and fontconfig settings.
|
||||
|
||||
See also:
|
||||
https://gitlab.freedesktop.org/xorg/lib/libxft/issues/6
|
||||
https://bugs.freedesktop.org/show_bug.cgi?id=107534
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1498269
|
||||
|
||||
The solution is to remove color emoji fonts or disable this in the fontconfig
|
||||
XML configuration. As an ugly workaround (which may work only on newer
|
||||
fontconfig versions (FC_COLOR)), the following code can be used to mask color
|
||||
fonts:
|
||||
|
||||
FcPatternAddBool(fcpattern, FC_COLOR, FcFalse);
|
||||
|
||||
Please don't bother reporting this bug to st, but notify the upstream Xft
|
||||
developers about fixing this bug.
|
||||
|
|
119
st/config.def.h
119
st/config.def.h
|
@ -1,11 +1,16 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
/* ____ _____ */
|
||||
/* | _ \_ _| Derek Taylor (DistroTube) */
|
||||
/* | | | || | http://www.youtube.com/c/DistroTube */
|
||||
/* | |_| || | http://www.gitlab.com/dwt1/ */
|
||||
/* |____/ |_| */
|
||||
|
||||
/*
|
||||
* appearance
|
||||
*
|
||||
* font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
|
||||
*/
|
||||
static char *font = "Liberation Mono:pixelsize=12:antialias=true:autohint=true";
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
/* appearance */
|
||||
static char *font = "Mononoki Nerd Font:pixelsize=14:antialias=true:autohint=true";
|
||||
static char *font2[] = {
|
||||
"Inconsolata for Powerline:pixelsize=12:antialias=true:autohint=true",
|
||||
"Hack Nerd Font Mono:pixelsize=11:antialias=true:autohint=true",
|
||||
};
|
||||
static int borderpx = 2;
|
||||
|
||||
/*
|
||||
|
@ -30,9 +35,9 @@ static float chscale = 1.0;
|
|||
/*
|
||||
* word delimiter string
|
||||
*
|
||||
* More advanced example: " `'\"()[]{}"
|
||||
* More advanced example: L" `'\"()[]{}"
|
||||
*/
|
||||
char *worddelimiters = " ";
|
||||
wchar_t *worddelimiters = L" ";
|
||||
|
||||
/* selection timeouts (in milliseconds) */
|
||||
static unsigned int doubleclicktimeout = 300;
|
||||
|
@ -82,48 +87,51 @@ char *termname = "st-256color";
|
|||
*/
|
||||
unsigned int tabspaces = 8;
|
||||
|
||||
/* bg opacity */
|
||||
unsigned int alpha = 0xcc;
|
||||
/* bg opacity
|
||||
* 0xff is no transparency.
|
||||
* 0xee adds wee bit of transparency.
|
||||
* Play with the value to get desired transparency.
|
||||
*/
|
||||
unsigned int alpha = 0xff;
|
||||
|
||||
/* Terminal colors (16 first used in escape sequence) */
|
||||
static const char *colorname[] = {
|
||||
/* 8 normal colors */
|
||||
"black",
|
||||
"red3",
|
||||
"green3",
|
||||
"yellow3",
|
||||
"blue2",
|
||||
"magenta3",
|
||||
"cyan3",
|
||||
"gray90",
|
||||
"#282a36",
|
||||
"#f07178",
|
||||
"#c3e88d",
|
||||
"#ffcb6b",
|
||||
"#82aaff",
|
||||
"#c792ea",
|
||||
"#89ddff",
|
||||
"#d0d0d0",
|
||||
|
||||
/* 8 bright colors */
|
||||
"gray50",
|
||||
"red",
|
||||
"green",
|
||||
"yellow",
|
||||
"#5c5cff",
|
||||
"magenta",
|
||||
"cyan",
|
||||
"white",
|
||||
"#434758",
|
||||
"#ff8b92",
|
||||
"#ddffa7",
|
||||
"#ffe585",
|
||||
"#9cc4ff",
|
||||
"#e1acff",
|
||||
"#a3f7ff",
|
||||
"#ffffff",
|
||||
|
||||
[255] = 0,
|
||||
|
||||
/* more colors can be added after 255 to use with DefaultXX */
|
||||
"#cccccc",
|
||||
"#555555",
|
||||
"black",
|
||||
"#282a36",
|
||||
"#bbc5ff",
|
||||
"#d7d7d7",
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Default colors (colorname index)
|
||||
* foreground, background, cursor, reverse cursor
|
||||
*/
|
||||
unsigned int defaultfg = 7;
|
||||
unsigned int defaultbg = 257;
|
||||
static unsigned int defaultcs = 256;
|
||||
static unsigned int defaultrcs = 257;
|
||||
unsigned int defaultbg = 256;
|
||||
unsigned int defaultfg = 257;
|
||||
static unsigned int defaultcs = 258;
|
||||
static unsigned int defaultrcs = 258;
|
||||
|
||||
/*
|
||||
* Default shape of cursor
|
||||
|
@ -154,20 +162,24 @@ static unsigned int mousebg = 0;
|
|||
*/
|
||||
static unsigned int defaultattr = 11;
|
||||
|
||||
/*
|
||||
* Force mouse select/shortcuts while mask is active (when MODE_MOUSE is set).
|
||||
* Note that if you want to use ShiftMask with selmasks, set this to an other
|
||||
* modifier, set to 0 to not use it.
|
||||
*/
|
||||
static uint forcemousemod = ShiftMask;
|
||||
|
||||
/*
|
||||
* Internal mouse shortcuts.
|
||||
* Beware that overloading Button1 will disable the selection.
|
||||
*/
|
||||
static MouseShortcut mshortcuts[] = {
|
||||
/* button mask string */
|
||||
{ Button4, XK_NO_MOD, "\031" },
|
||||
{ Button5, XK_NO_MOD, "\005" },
|
||||
};
|
||||
|
||||
MouseKey mkeys[] = {
|
||||
/* button mask function argument */
|
||||
{ Button4, XK_NO_MOD, kscrollup, {.i = 1} },
|
||||
{ Button5, XK_NO_MOD, kscrolldown, {.i = 1} },
|
||||
/* mask button function argument release */
|
||||
{ XK_ANY_MOD, Button4, kscrollup, {.i = 3}, 0, /* !alt */ -1 },
|
||||
{ XK_ANY_MOD, Button5, kscrolldown, {.i = 3}, 0, /* !alt */ -1 },
|
||||
{ XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 },
|
||||
{ XK_ANY_MOD, Button4, ttysend, {.s = "\031"} },
|
||||
{ XK_ANY_MOD, Button5, ttysend, {.s = "\005"} },
|
||||
};
|
||||
|
||||
/* Internal keyboard shortcuts. */
|
||||
|
@ -180,16 +192,14 @@ static Shortcut shortcuts[] = {
|
|||
{ ControlMask, XK_Print, toggleprinter, {.i = 0} },
|
||||
{ ShiftMask, XK_Print, printscreen, {.i = 0} },
|
||||
{ XK_ANY_MOD, XK_Print, printsel, {.i = 0} },
|
||||
{ TERMMOD, XK_Prior, zoom, {.f = +1} },
|
||||
{ TERMMOD, XK_Next, zoom, {.f = -1} },
|
||||
{ TERMMOD, XK_Home, zoomreset, {.f = 0} },
|
||||
{ TERMMOD, XK_K, zoom, {.f = +1} },
|
||||
{ TERMMOD, XK_J, zoom, {.f = -1} },
|
||||
{ TERMMOD, XK_U, zoomreset, {.f = 0} },
|
||||
{ TERMMOD, XK_C, clipcopy, {.i = 0} },
|
||||
{ TERMMOD, XK_V, clippaste, {.i = 0} },
|
||||
{ TERMMOD, XK_Y, selpaste, {.i = 0} },
|
||||
{ ShiftMask, XK_Insert, selpaste, {.i = 0} },
|
||||
{ TERMMOD, XK_Num_Lock, numlock, {.i = 0} },
|
||||
{ ShiftMask, XK_Page_Up, kscrollup, {.i = -1} },
|
||||
{ ShiftMask, XK_Page_Down, kscrolldown, {.i = -1} },
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -207,10 +217,6 @@ static Shortcut shortcuts[] = {
|
|||
* * 0: no value
|
||||
* * > 0: cursor application mode enabled
|
||||
* * < 0: cursor application mode disabled
|
||||
* crlf value
|
||||
* * 0: no value
|
||||
* * > 0: crlf mode is enabled
|
||||
* * < 0: crlf mode is disabled
|
||||
*
|
||||
* Be careful with the order of the definitions because st searches in
|
||||
* this table sequentially, so any XK_ANY_MOD must be in the last
|
||||
|
@ -229,13 +235,6 @@ static KeySym mappedkeys[] = { -1 };
|
|||
*/
|
||||
static uint ignoremod = Mod2Mask|XK_SWITCH_MOD;
|
||||
|
||||
/*
|
||||
* Override mouse-select while mask is active (when MODE_MOUSE is set).
|
||||
* Note that if you want to use ShiftMask with selmasks, set this to an other
|
||||
* modifier, set to 0 to not use it.
|
||||
*/
|
||||
static uint forceselmod = ShiftMask;
|
||||
|
||||
/*
|
||||
* This is the huge key array which defines all compatibility to the Linux
|
||||
* world. Please decide about changes wisely.
|
||||
|
|
74
st/config.h
Executable file → Normal file
74
st/config.h
Executable file → Normal file
|
@ -1,11 +1,16 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
/* ____ _____ */
|
||||
/* | _ \_ _| Derek Taylor (DistroTube) */
|
||||
/* | | | || | http://www.youtube.com/c/DistroTube */
|
||||
/* | |_| || | http://www.gitlab.com/dwt1/ */
|
||||
/* |____/ |_| */
|
||||
|
||||
/*
|
||||
* appearance
|
||||
*
|
||||
* font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
|
||||
*/
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
/* appearance */
|
||||
static char *font = "Mononoki Nerd Font:pixelsize=14:antialias=true:autohint=true";
|
||||
static char *font2[] = {
|
||||
"Inconsolata for Powerline:pixelsize=12:antialias=true:autohint=true",
|
||||
"Hack Nerd Font Mono:pixelsize=11:antialias=true:autohint=true",
|
||||
};
|
||||
static int borderpx = 2;
|
||||
|
||||
/*
|
||||
|
@ -24,15 +29,15 @@ char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400";
|
|||
char *vtiden = "\033[?6c";
|
||||
|
||||
/* Kerning / character bounding-box multipliers */
|
||||
static float cwscale = 1.1;
|
||||
static float cwscale = 1.0;
|
||||
static float chscale = 1.0;
|
||||
|
||||
/*
|
||||
* word delimiter string
|
||||
*
|
||||
* More advanced example: " `'\"()[]{}"
|
||||
* More advanced example: L" `'\"()[]{}"
|
||||
*/
|
||||
char *worddelimiters = " ";
|
||||
wchar_t *worddelimiters = L" ";
|
||||
|
||||
/* selection timeouts (in milliseconds) */
|
||||
static unsigned int doubleclicktimeout = 300;
|
||||
|
@ -82,8 +87,12 @@ char *termname = "st-256color";
|
|||
*/
|
||||
unsigned int tabspaces = 8;
|
||||
|
||||
/* bg opacity */
|
||||
unsigned int alpha = 0xff; /* 0xf2 adds wee bit of transparency */
|
||||
/* bg opacity
|
||||
* 0xff is no transparency.
|
||||
* 0xee adds wee bit of transparency.
|
||||
* Play with the value to get desired transparency.
|
||||
*/
|
||||
unsigned int alpha = 0xff;
|
||||
|
||||
/* Terminal colors (16 first used in escape sequence) */
|
||||
static const char *colorname[] = {
|
||||
|
@ -153,39 +162,39 @@ static unsigned int mousebg = 0;
|
|||
*/
|
||||
static unsigned int defaultattr = 11;
|
||||
|
||||
/*
|
||||
* Force mouse select/shortcuts while mask is active (when MODE_MOUSE is set).
|
||||
* Note that if you want to use ShiftMask with selmasks, set this to an other
|
||||
* modifier, set to 0 to not use it.
|
||||
*/
|
||||
static uint forcemousemod = ShiftMask;
|
||||
|
||||
/*
|
||||
* Internal mouse shortcuts.
|
||||
* Beware that overloading Button1 will disable the selection.
|
||||
*/
|
||||
static MouseShortcut mshortcuts[] = {
|
||||
/* button mask string */
|
||||
{ Button4, XK_ANY_MOD, "\031" },
|
||||
{ Button5, XK_ANY_MOD, "\005" },
|
||||
/* mask button function argument release */
|
||||
{ XK_ANY_MOD, Button4, kscrollup, {.i = 3}, 0, /* !alt */ -1 },
|
||||
{ XK_ANY_MOD, Button5, kscrolldown, {.i = 3}, 0, /* !alt */ -1 },
|
||||
{ XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 },
|
||||
{ XK_ANY_MOD, Button4, ttysend, {.s = "\031"} },
|
||||
{ XK_ANY_MOD, Button5, ttysend, {.s = "\005"} },
|
||||
};
|
||||
|
||||
/* Internal keyboard shortcuts. */
|
||||
#define MODKEY Mod1Mask
|
||||
#define TERMMOD (ControlMask|ShiftMask)
|
||||
|
||||
MouseKey mkeys[] = {
|
||||
/* button mask function argument */
|
||||
{ Button4, ShiftMask, kscrollup, {.i = 1} },
|
||||
{ Button5, ShiftMask, kscrolldown, {.i = 1} },
|
||||
{ Button4, TERMMOD, zoom, {.f = +1} },
|
||||
{ Button5, TERMMOD, zoom, {.f = -1} },
|
||||
};
|
||||
|
||||
static Shortcut shortcuts[] = {
|
||||
/* mask keysym function argument */
|
||||
{ XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} },
|
||||
{ ControlMask, XK_Print, toggleprinter, {.i = 0} },
|
||||
{ ShiftMask, XK_Print, printscreen, {.i = 0} },
|
||||
{ XK_ANY_MOD, XK_Print, printsel, {.i = 0} },
|
||||
{ ShiftMask, XK_Page_Up, kscrollup, {.i = 1} },
|
||||
{ ShiftMask, XK_Page_Down, kscrolldown, {.i = 1} },
|
||||
{ TERMMOD, XK_K, zoom, {.f = +1} },
|
||||
{ TERMMOD, XK_J, zoom, {.f = -1} },
|
||||
{ TERMMOD, XK_Home, zoomreset, {.f = 0} },
|
||||
{ TERMMOD, XK_K, zoom, {.f = +1} },
|
||||
{ TERMMOD, XK_J, zoom, {.f = -1} },
|
||||
{ TERMMOD, XK_U, zoomreset, {.f = 0} },
|
||||
{ TERMMOD, XK_C, clipcopy, {.i = 0} },
|
||||
{ TERMMOD, XK_V, clippaste, {.i = 0} },
|
||||
{ TERMMOD, XK_Y, selpaste, {.i = 0} },
|
||||
|
@ -208,10 +217,6 @@ static Shortcut shortcuts[] = {
|
|||
* * 0: no value
|
||||
* * > 0: cursor application mode enabled
|
||||
* * < 0: cursor application mode disabled
|
||||
* crlf value
|
||||
* * 0: no value
|
||||
* * > 0: crlf mode is enabled
|
||||
* * < 0: crlf mode is disabled
|
||||
*
|
||||
* Be careful with the order of the definitions because st searches in
|
||||
* this table sequentially, so any XK_ANY_MOD must be in the last
|
||||
|
@ -230,13 +235,6 @@ static KeySym mappedkeys[] = { -1 };
|
|||
*/
|
||||
static uint ignoremod = Mod2Mask|XK_SWITCH_MOD;
|
||||
|
||||
/*
|
||||
* Override mouse-select while mask is active (when MODE_MOUSE is set).
|
||||
* Note that if you want to use ShiftMask with selmasks, set this to an other
|
||||
* modifier, set to 0 to not use it.
|
||||
*/
|
||||
static uint forceselmod = ShiftMask;
|
||||
|
||||
/*
|
||||
* This is the huge key array which defines all compatibility to the Linux
|
||||
* world. Please decide about changes wisely.
|
||||
|
|
|
@ -1,335 +0,0 @@
|
|||
diff --git a/config.def.h b/config.def.h
|
||||
index 823e79f..f6278a3 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -178,6 +178,8 @@ static Shortcut shortcuts[] = {
|
||||
{ TERMMOD, XK_Y, selpaste, {.i = 0} },
|
||||
{ ShiftMask, XK_Insert, selpaste, {.i = 0} },
|
||||
{ TERMMOD, 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 b8e6077..218ae73 100644
|
||||
--- a/st.c
|
||||
+++ b/st.c
|
||||
@@ -35,6 +35,7 @@
|
||||
#define ESC_ARG_SIZ 16
|
||||
#define STR_BUF_SIZ ESC_BUF_SIZ
|
||||
#define STR_ARG_SIZ ESC_ARG_SIZ
|
||||
+#define HISTSIZE 2000
|
||||
|
||||
/* macros */
|
||||
#define IS_SET(flag) ((term.mode & (flag)) != 0)
|
||||
@@ -42,6 +43,9 @@
|
||||
#define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f))
|
||||
#define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c))
|
||||
#define ISDELIM(u) (utf8strchr(worddelimiters, u) != NULL)
|
||||
+#define TLINE(y) ((y) < term.scr ? term.hist[((y) + term.histi - \
|
||||
+ term.scr + HISTSIZE + 1) % HISTSIZE] : \
|
||||
+ term.line[(y) - term.scr])
|
||||
|
||||
enum term_mode {
|
||||
MODE_WRAP = 1 << 0,
|
||||
@@ -117,6 +121,9 @@ typedef struct {
|
||||
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 */
|
||||
TCursor c; /* cursor */
|
||||
int ocx; /* old cursor col */
|
||||
@@ -184,8 +191,8 @@ static void tnewline(int);
|
||||
static void tputtab(int);
|
||||
static void tputc(Rune);
|
||||
static void treset(void);
|
||||
-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 tsetdirt(int, int);
|
||||
@@ -427,10 +434,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;
|
||||
@@ -539,7 +546,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;
|
||||
@@ -554,14 +561,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)))
|
||||
@@ -582,14 +589,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;
|
||||
}
|
||||
@@ -620,13 +627,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;
|
||||
|
||||
@@ -849,6 +856,9 @@ void
|
||||
ttywrite(const char *s, size_t n, int may_echo)
|
||||
{
|
||||
const char *next;
|
||||
+ Arg arg = (Arg) { .i = term.scr };
|
||||
+
|
||||
+ kscrolldown(&arg);
|
||||
|
||||
if (may_echo && IS_SET(MODE_ECHO))
|
||||
twrite(s, n, 1);
|
||||
@@ -1060,13 +1070,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);
|
||||
|
||||
@@ -1080,13 +1130,23 @@ 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;
|
||||
+ }
|
||||
+
|
||||
+ if (term.scr > 0 && term.scr < HISTSIZE)
|
||||
+ term.scr = MIN(term.scr + n, HISTSIZE-1);
|
||||
+
|
||||
tclearregion(0, orig, term.col-1, orig+n-1);
|
||||
tsetdirt(orig+n, term.bot);
|
||||
|
||||
@@ -1135,7 +1195,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++;
|
||||
}
|
||||
@@ -1300,14 +1360,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
|
||||
@@ -1737,11 +1797,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);
|
||||
@@ -2243,7 +2303,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);
|
||||
}
|
||||
@@ -2256,7 +2316,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);
|
||||
}
|
||||
@@ -2475,7 +2535,7 @@ twrite(const char *buf, int buflen, int show_ctrl)
|
||||
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;
|
||||
@@ -2512,6 +2572,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));
|
||||
@@ -2569,7 +2637,7 @@ drawregion(int x1, int y1, int x2, int y2)
|
||||
continue;
|
||||
|
||||
term.dirty[y] = 0;
|
||||
- xdrawline(term.line[y], x1, y, x2);
|
||||
+ xdrawline(TLINE(y), x1, y, x2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2590,8 +2658,9 @@ draw(void)
|
||||
cx--;
|
||||
|
||||
drawregion(0, 0, term.col, term.row);
|
||||
- xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
|
||||
- term.ocx, term.ocy, term.line[term.ocy][term.ocx]);
|
||||
+ if (term.scr == 0)
|
||||
+ xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
|
||||
+ term.ocx, term.ocy, term.line[term.ocy][term.ocx]);
|
||||
term.ocx = cx, term.ocy = term.c.y;
|
||||
xfinishdraw();
|
||||
}
|
||||
diff --git a/st.h b/st.h
|
||||
index 38c61c4..17a79e0 100644
|
||||
--- a/st.h
|
||||
+++ b/st.h
|
||||
@@ -80,6 +80,8 @@ void die(const char *, ...);
|
||||
void redraw(void);
|
||||
void draw(void);
|
||||
|
||||
+void kscrolldown(const Arg *);
|
||||
+void kscrollup(const Arg *);
|
||||
void printscreen(const Arg *);
|
||||
void printsel(const Arg *);
|
||||
void sendbreak(const Arg *);
|
|
@ -1,71 +0,0 @@
|
|||
diff --git a/config.def.h b/config.def.h
|
||||
index 27d42ca..feec7e2 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -156,8 +156,14 @@ static unsigned int defaultattr = 11;
|
||||
*/
|
||||
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" },
|
||||
+};
|
||||
+
|
||||
+MouseKey mkeys[] = {
|
||||
+ /* button mask function argument */
|
||||
+ { Button4, ShiftMask, kscrollup, {.i = 1} },
|
||||
+ { Button5, ShiftMask, kscrolldown, {.i = 1} },
|
||||
};
|
||||
|
||||
/* Internal keyboard shortcuts. */
|
||||
diff --git a/st.h b/st.h
|
||||
index 628e876..cdd25ae 100644
|
||||
--- a/st.h
|
||||
+++ b/st.h
|
||||
@@ -81,6 +81,13 @@ typedef union {
|
||||
const void *v;
|
||||
} Arg;
|
||||
|
||||
+typedef struct {
|
||||
+ uint b;
|
||||
+ uint mask;
|
||||
+ void (*func)(const Arg *);
|
||||
+ const Arg arg;
|
||||
+} MouseKey;
|
||||
+
|
||||
void die(const char *, ...);
|
||||
void redraw(void);
|
||||
void draw(void);
|
||||
@@ -129,3 +136,4 @@ extern char *termname;
|
||||
extern unsigned int tabspaces;
|
||||
extern unsigned int defaultfg;
|
||||
extern unsigned int defaultbg;
|
||||
+extern MouseKey mkeys[];
|
||||
diff --git a/x.c b/x.c
|
||||
index d43a529..754d859 100644
|
||||
--- a/x.c
|
||||
+++ b/x.c
|
||||
@@ -409,6 +409,7 @@ bpress(XEvent *e)
|
||||
{
|
||||
struct timespec now;
|
||||
MouseShortcut *ms;
|
||||
+ MouseKey *mk;
|
||||
int snap;
|
||||
|
||||
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) {
|
||||
@@ -424,6 +425,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) {
|
||||
/*
|
||||
* If the user clicks below predefined timeouts specific
|
|
@ -1,66 +0,0 @@
|
|||
diff --git a/config.def.h b/config.def.h
|
||||
index a6d2fb9..16830c8 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -162,8 +162,8 @@ static MouseShortcut mshortcuts[] = {
|
||||
|
||||
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 218ae73..f543305 100644
|
||||
--- a/st.c
|
||||
+++ b/st.c
|
||||
@@ -1058,6 +1058,11 @@ tnew(int col, int row)
|
||||
treset();
|
||||
}
|
||||
|
||||
+int tisaltscr(void)
|
||||
+{
|
||||
+ return IS_SET(MODE_ALTSCREEN);
|
||||
+}
|
||||
+
|
||||
void
|
||||
tswapscreen(void)
|
||||
{
|
||||
diff --git a/st.h b/st.h
|
||||
index 3592957..23f4ca3 100644
|
||||
--- a/st.h
|
||||
+++ b/st.h
|
||||
@@ -95,6 +95,7 @@ void sendbreak(const Arg *);
|
||||
void toggleprinter(const Arg *);
|
||||
|
||||
int tattrset(int);
|
||||
+int tisaltscr(void);
|
||||
void tnew(int, int);
|
||||
void tresize(int, int);
|
||||
void tsetdirtattr(int);
|
||||
diff --git a/x.c b/x.c
|
||||
index e9fd6e9..2dc315e 100644
|
||||
--- a/x.c
|
||||
+++ b/x.c
|
||||
@@ -417,11 +417,13 @@ bpress(XEvent *e)
|
||||
return;
|
||||
}
|
||||
|
||||
- for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) {
|
||||
- if (e->xbutton.button == ms->b
|
||||
- && match(ms->mask, e->xbutton.state)) {
|
||||
- ttywrite(ms->s, strlen(ms->s), 1);
|
||||
- return;
|
||||
+ if (tisaltscr()) {
|
||||
+ for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) {
|
||||
+ if (e->xbutton.button == ms->b
|
||||
+ && match(ms->mask, e->xbutton.state)) {
|
||||
+ ttywrite(ms->s, strlen(ms->s), 1);
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
62
st/st.c
62
st/st.c
|
@ -42,7 +42,7 @@
|
|||
#define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f) || (c) == '\177')
|
||||
#define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f))
|
||||
#define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c))
|
||||
#define ISDELIM(u) (utf8strchr(worddelimiters, u) != NULL)
|
||||
#define ISDELIM(u) (u && wcschr(worddelimiters, u))
|
||||
#define TLINE(y) ((y) < term.scr ? term.hist[((y) + term.histi - \
|
||||
term.scr + HISTSIZE + 1) % HISTSIZE] : \
|
||||
term.line[(y) - term.scr])
|
||||
|
@ -142,7 +142,7 @@ typedef struct {
|
|||
/* ESC '[' [[ [<priv>] <arg> [;]] <mode> [<mode>]] */
|
||||
typedef struct {
|
||||
char buf[ESC_BUF_SIZ]; /* raw string */
|
||||
int len; /* raw string length */
|
||||
size_t len; /* raw string length */
|
||||
char priv;
|
||||
int arg[ESC_ARG_SIZ];
|
||||
int narg; /* nb of args */
|
||||
|
@ -153,8 +153,9 @@ typedef struct {
|
|||
/* ESC type [[ [<priv>] <arg> [;]] <mode>] ESC '\' */
|
||||
typedef struct {
|
||||
char type; /* ESC type ... */
|
||||
char buf[STR_BUF_SIZ]; /* raw string */
|
||||
int len; /* raw string length */
|
||||
char *buf; /* allocated raw string */
|
||||
size_t siz; /* allocation size */
|
||||
size_t len; /* raw string length */
|
||||
char *args[STR_ARG_SIZ];
|
||||
int narg; /* nb of args */
|
||||
} STREscape;
|
||||
|
@ -217,7 +218,6 @@ static void selsnap(int *, int *, int);
|
|||
static size_t utf8decode(const char *, Rune *, size_t);
|
||||
static Rune utf8decodebyte(char, size_t *);
|
||||
static char utf8encodebyte(Rune, size_t);
|
||||
static char *utf8strchr(char *, Rune);
|
||||
static size_t utf8validate(Rune *, size_t);
|
||||
|
||||
static char *base64dec(const char *);
|
||||
|
@ -344,23 +344,6 @@ utf8encodebyte(Rune u, size_t i)
|
|||
return utfbyte[i] | (u & ~utfmask[i]);
|
||||
}
|
||||
|
||||
char *
|
||||
utf8strchr(char *s, Rune u)
|
||||
{
|
||||
Rune r;
|
||||
size_t i, j, len;
|
||||
|
||||
len = strlen(s);
|
||||
for (i = 0, j = 0; i < len; i += j) {
|
||||
if (!(j = utf8decode(&s[i], &r, len - i)))
|
||||
break;
|
||||
if (r == u)
|
||||
return &(s[i]);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t
|
||||
utf8validate(Rune *u, size_t i)
|
||||
{
|
||||
|
@ -391,7 +374,7 @@ char
|
|||
base64dec_getc(const char **src)
|
||||
{
|
||||
while (**src && !isprint(**src)) (*src)++;
|
||||
return *((*src)++);
|
||||
return **src ? *((*src)++) : '='; /* emulate padding if string ends */
|
||||
}
|
||||
|
||||
char *
|
||||
|
@ -409,6 +392,10 @@ base64dec(const char *src)
|
|||
int c = base64_digits[(unsigned char) base64dec_getc(&src)];
|
||||
int d = base64_digits[(unsigned char) base64dec_getc(&src)];
|
||||
|
||||
/* invalid input. 'a' can be -1, e.g. if src is "\n" (c-str) */
|
||||
if (a == -1 || b == -1)
|
||||
break;
|
||||
|
||||
*dst++ = (a << 2) | ((b & 0x30) >> 4);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
@ -483,7 +470,7 @@ selextend(int col, int row, int type, int done)
|
|||
selnormalize();
|
||||
sel.type = type;
|
||||
|
||||
if (oldey != sel.oe.y || oldex != sel.oe.x || oldtype != sel.type)
|
||||
if (oldey != sel.oe.y || oldex != sel.oe.x || oldtype != sel.type || sel.mode == SEL_EMPTY)
|
||||
tsetdirt(MIN(sel.nb.y, oldsby), MAX(sel.ne.y, oldsey));
|
||||
|
||||
sel.mode = done ? SEL_IDLE : SEL_READY;
|
||||
|
@ -1640,6 +1627,7 @@ tsetmode(int priv, int set, int *args, int narg)
|
|||
case 1015: /* urxvt mangled mouse mode; incompatible
|
||||
and can be mistaken for other control
|
||||
codes. */
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,
|
||||
"erresc: unknown private set/reset mode %d\n",
|
||||
|
@ -1881,7 +1869,7 @@ csihandle(void)
|
|||
void
|
||||
csidump(void)
|
||||
{
|
||||
int i;
|
||||
size_t i;
|
||||
uint c;
|
||||
|
||||
fprintf(stderr, "ESC[");
|
||||
|
@ -1911,7 +1899,7 @@ csireset(void)
|
|||
void
|
||||
strhandle(void)
|
||||
{
|
||||
char *p = NULL;
|
||||
char *p = NULL, *dec;
|
||||
int j, narg, par;
|
||||
|
||||
term.esc &= ~(ESC_STR_END|ESC_STR);
|
||||
|
@ -1929,8 +1917,6 @@ strhandle(void)
|
|||
return;
|
||||
case 52:
|
||||
if (narg > 2) {
|
||||
char *dec;
|
||||
|
||||
dec = base64dec(strescseq.args[2]);
|
||||
if (dec) {
|
||||
xsetsel(dec);
|
||||
|
@ -1948,7 +1934,10 @@ strhandle(void)
|
|||
case 104: /* color reset, here p = NULL */
|
||||
j = (narg > 1) ? atoi(strescseq.args[1]) : -1;
|
||||
if (xsetcolorname(j, p)) {
|
||||
fprintf(stderr, "erresc: invalid color %s\n", p);
|
||||
if (par == 104 && narg <= 1)
|
||||
return; /* color reset without parameter */
|
||||
fprintf(stderr, "erresc: invalid color j=%d, p=%s\n",
|
||||
j, p ? p : "(null)");
|
||||
} else {
|
||||
/*
|
||||
* TODO if defaultbg color is changed, borders
|
||||
|
@ -1998,7 +1987,7 @@ strparse(void)
|
|||
void
|
||||
strdump(void)
|
||||
{
|
||||
int i;
|
||||
size_t i;
|
||||
uint c;
|
||||
|
||||
fprintf(stderr, "ESC%c", strescseq.type);
|
||||
|
@ -2025,7 +2014,10 @@ strdump(void)
|
|||
void
|
||||
strreset(void)
|
||||
{
|
||||
memset(&strescseq, 0, sizeof(strescseq));
|
||||
strescseq = (STREscape){
|
||||
.buf = xrealloc(strescseq.buf, STR_BUF_SIZ),
|
||||
.siz = STR_BUF_SIZ,
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2400,7 +2392,6 @@ tputc(Rune u)
|
|||
goto check_control_code;
|
||||
}
|
||||
|
||||
|
||||
if (IS_SET(MODE_SIXEL)) {
|
||||
/* TODO: implement sixel mode */
|
||||
return;
|
||||
|
@ -2408,7 +2399,7 @@ tputc(Rune u)
|
|||
if (term.esc&ESC_DCS && strescseq.len == 0 && u == 'q')
|
||||
term.mode |= MODE_SIXEL;
|
||||
|
||||
if (strescseq.len+len >= sizeof(strescseq.buf)-1) {
|
||||
if (strescseq.len+len >= strescseq.siz) {
|
||||
/*
|
||||
* Here is a bug in terminals. If the user never sends
|
||||
* some code to stop the str or esc command, then st
|
||||
|
@ -2422,7 +2413,10 @@ tputc(Rune u)
|
|||
* term.esc = 0;
|
||||
* strhandle();
|
||||
*/
|
||||
return;
|
||||
if (strescseq.siz > (SIZE_MAX - UTF_SIZ) / 2)
|
||||
return;
|
||||
strescseq.siz *= 2;
|
||||
strescseq.buf = xrealloc(strescseq.buf, strescseq.siz);
|
||||
}
|
||||
|
||||
memmove(&strescseq.buf[strescseq.len], c, len);
|
||||
|
|
13
st/st.h
13
st/st.h
|
@ -6,7 +6,7 @@
|
|||
/* macros */
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define MAX(a, b) ((a) < (b) ? (b) : (a))
|
||||
#define LEN(a) (sizeof(a) / sizeof(a)[0])
|
||||
#define LEN(a) (sizeof(a) / sizeof(a)[0])
|
||||
#define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b))
|
||||
#define DIVCEIL(n, d) (((n) + ((d) - 1)) / (d))
|
||||
#define DEFAULT(a, b) (a) = (a) ? (a) : (b)
|
||||
|
@ -74,15 +74,9 @@ typedef union {
|
|||
uint ui;
|
||||
float f;
|
||||
const void *v;
|
||||
const char *s;
|
||||
} Arg;
|
||||
|
||||
typedef struct {
|
||||
uint b;
|
||||
uint mask;
|
||||
void (*func)(const Arg *);
|
||||
const Arg arg;
|
||||
} MouseKey;
|
||||
|
||||
void die(const char *, ...);
|
||||
void redraw(void);
|
||||
void draw(void);
|
||||
|
@ -124,11 +118,10 @@ char *xstrdup(char *);
|
|||
extern char *utmp;
|
||||
extern char *stty_args;
|
||||
extern char *vtiden;
|
||||
extern char *worddelimiters;
|
||||
extern wchar_t *worddelimiters;
|
||||
extern int allowaltscreen;
|
||||
extern char *termname;
|
||||
extern unsigned int tabspaces;
|
||||
extern unsigned int alpha;
|
||||
extern unsigned int defaultfg;
|
||||
extern unsigned int defaultbg;
|
||||
extern MouseKey mkeys[];
|
||||
|
|
|
@ -189,10 +189,10 @@ st| simpleterm,
|
|||
rmxx=\E[29m,
|
||||
smxx=\E[9m,
|
||||
# tmux extensions, see TERMINFO EXTENSIONS in tmux(1)
|
||||
Se,
|
||||
Ss,
|
||||
Tc,
|
||||
Ms=\E]52;%p1%s;%p2%s\007,
|
||||
Se=\E[2 q,
|
||||
Ss=\E[%p1%d q,
|
||||
|
||||
st-256color| simpleterm with 256 colors,
|
||||
use=st,
|
||||
|
|
286
st/x.c
286
st/x.c
|
@ -29,9 +29,12 @@ typedef struct {
|
|||
} Shortcut;
|
||||
|
||||
typedef struct {
|
||||
uint b;
|
||||
uint mask;
|
||||
char *s;
|
||||
uint mod;
|
||||
uint button;
|
||||
void (*func)(const Arg *);
|
||||
const Arg arg;
|
||||
uint release;
|
||||
int altscrn; /* 0: don't care, -1: not alt screen, 1: alt screen */
|
||||
} MouseShortcut;
|
||||
|
||||
typedef struct {
|
||||
|
@ -60,6 +63,7 @@ static void selpaste(const Arg *);
|
|||
static void zoom(const Arg *);
|
||||
static void zoomabs(const Arg *);
|
||||
static void zoomreset(const Arg *);
|
||||
static void ttysend(const Arg *);
|
||||
|
||||
/* config.h for applying patches and the configuration. */
|
||||
#include "config.h"
|
||||
|
@ -95,8 +99,12 @@ typedef struct {
|
|||
Drawable buf;
|
||||
GlyphFontSpec *specbuf; /* font spec buffer used for rendering */
|
||||
Atom xembed, wmdeletewin, netwmname, netwmpid;
|
||||
XIM xim;
|
||||
XIC xic;
|
||||
struct {
|
||||
XIM xim;
|
||||
XIC xic;
|
||||
XPoint spot;
|
||||
XVaNestedList spotlist;
|
||||
} ime;
|
||||
Draw draw;
|
||||
Visual *vis;
|
||||
XSetWindowAttributes attrs;
|
||||
|
@ -144,9 +152,10 @@ static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int);
|
|||
static void xdrawglyph(Glyph, int, int);
|
||||
static void xclear(int, int, int, int);
|
||||
static int xgeommasktogravity(int);
|
||||
static void ximopen(Display *);
|
||||
static int ximopen(Display *);
|
||||
static void ximinstantiate(Display *, XPointer, XPointer);
|
||||
static void ximdestroy(XIM, XPointer, XPointer);
|
||||
static int xicdestroy(XIC, XPointer, XPointer);
|
||||
static void xinit(int, int);
|
||||
static void cresize(int, int);
|
||||
static void xresize(int, int);
|
||||
|
@ -154,6 +163,8 @@ static void xhints(void);
|
|||
static int xloadcolor(int, const char *, Color *);
|
||||
static int xloadfont(Font *, FcPattern *);
|
||||
static void xloadfonts(char *, double);
|
||||
static int xloadsparefont(FcPattern *, int);
|
||||
static void xloadsparefonts(void);
|
||||
static void xunloadfont(Font *);
|
||||
static void xunloadfonts(void);
|
||||
static void xsetenv(void);
|
||||
|
@ -168,6 +179,7 @@ static void kpress(XEvent *);
|
|||
static void cmessage(XEvent *);
|
||||
static void resize(XEvent *);
|
||||
static void focus(XEvent *);
|
||||
static int mouseaction(XEvent *, uint);
|
||||
static void brelease(XEvent *);
|
||||
static void bpress(XEvent *);
|
||||
static void bmotion(XEvent *);
|
||||
|
@ -231,8 +243,9 @@ typedef struct {
|
|||
} Fontcache;
|
||||
|
||||
/* Fontcache is an array now. A new font will be appended to the array. */
|
||||
static Fontcache frc[16];
|
||||
static Fontcache *frc = NULL;
|
||||
static int frclen = 0;
|
||||
static int frccap = 0;
|
||||
static char *usedfont = NULL;
|
||||
static double usedfontsize = 0;
|
||||
static double defaultfontsize = 0;
|
||||
|
@ -300,6 +313,7 @@ zoomabs(const Arg *arg)
|
|||
{
|
||||
xunloadfonts();
|
||||
xloadfonts(usedfont, arg->f);
|
||||
xloadsparefonts();
|
||||
cresize(0, 0);
|
||||
redraw();
|
||||
xhints();
|
||||
|
@ -316,6 +330,12 @@ zoomreset(const Arg *arg)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ttysend(const Arg *arg)
|
||||
{
|
||||
ttywrite(arg->s, strlen(arg->s), 1);
|
||||
}
|
||||
|
||||
int
|
||||
evcol(XEvent *e)
|
||||
{
|
||||
|
@ -336,7 +356,7 @@ void
|
|||
mousesel(XEvent *e, int done)
|
||||
{
|
||||
int type, seltype = SEL_REGULAR;
|
||||
uint state = e->xbutton.state & ~(Button1Mask | forceselmod);
|
||||
uint state = e->xbutton.state & ~(Button1Mask | forcemousemod);
|
||||
|
||||
for (type = 1; type < LEN(selmasks); ++type) {
|
||||
if (match(selmasks[type], state)) {
|
||||
|
@ -412,36 +432,38 @@ mousereport(XEvent *e)
|
|||
ttywrite(buf, len, 0);
|
||||
}
|
||||
|
||||
int
|
||||
mouseaction(XEvent *e, uint release)
|
||||
{
|
||||
MouseShortcut *ms;
|
||||
|
||||
for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) {
|
||||
if (ms->release == release &&
|
||||
ms->button == e->xbutton.button &&
|
||||
(!ms->altscrn || (ms->altscrn == (tisaltscr() ? 1 : -1))) &&
|
||||
(match(ms->mod, e->xbutton.state) || /* exact or forced */
|
||||
match(ms->mod, e->xbutton.state & ~forcemousemod))) {
|
||||
ms->func(&(ms->arg));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
bpress(XEvent *e)
|
||||
{
|
||||
struct timespec now;
|
||||
MouseShortcut *ms;
|
||||
MouseKey *mk;
|
||||
int snap;
|
||||
|
||||
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) {
|
||||
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) {
|
||||
mousereport(e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (tisaltscr()) {
|
||||
for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) {
|
||||
if (e->xbutton.button == ms->b
|
||||
&& match(ms->mask, e->xbutton.state)) {
|
||||
ttywrite(ms->s, strlen(ms->s), 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 (mouseaction(e, 0))
|
||||
return;
|
||||
|
||||
if (e->xbutton.button == Button1) {
|
||||
/*
|
||||
|
@ -657,21 +679,21 @@ xsetsel(char *str)
|
|||
void
|
||||
brelease(XEvent *e)
|
||||
{
|
||||
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) {
|
||||
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) {
|
||||
mousereport(e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (e->xbutton.button == Button2)
|
||||
selpaste(NULL);
|
||||
else if (e->xbutton.button == Button1)
|
||||
if (mouseaction(e, 1))
|
||||
return;
|
||||
if (e->xbutton.button == Button1)
|
||||
mousesel(e, 1);
|
||||
}
|
||||
|
||||
void
|
||||
bmotion(XEvent *e)
|
||||
{
|
||||
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) {
|
||||
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) {
|
||||
mousereport(e);
|
||||
return;
|
||||
}
|
||||
|
@ -786,7 +808,6 @@ xsetcolorname(int x, const char *name)
|
|||
if (!BETWEEN(x, 0, dc.collen))
|
||||
return 1;
|
||||
|
||||
|
||||
if (!xloadcolor(x, name, &ncolor))
|
||||
return 1;
|
||||
|
||||
|
@ -1012,6 +1033,101 @@ xloadfonts(char *fontstr, double fontsize)
|
|||
FcPatternDestroy(pattern);
|
||||
}
|
||||
|
||||
int
|
||||
xloadsparefont(FcPattern *pattern, int flags)
|
||||
{
|
||||
FcPattern *match;
|
||||
FcResult result;
|
||||
|
||||
match = FcFontMatch(NULL, pattern, &result);
|
||||
if (!match) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!(frc[frclen].font = XftFontOpenPattern(xw.dpy, match))) {
|
||||
FcPatternDestroy(match);
|
||||
return 1;
|
||||
}
|
||||
|
||||
frc[frclen].flags = flags;
|
||||
/* Believe U+0000 glyph will present in each default font */
|
||||
frc[frclen].unicodep = 0;
|
||||
frclen++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
xloadsparefonts(void)
|
||||
{
|
||||
FcPattern *pattern;
|
||||
double sizeshift, fontval;
|
||||
int fc;
|
||||
char **fp;
|
||||
|
||||
if (frclen != 0)
|
||||
die("can't embed spare fonts. cache isn't empty");
|
||||
|
||||
/* Calculate count of spare fonts */
|
||||
fc = sizeof(font2) / sizeof(*font2);
|
||||
if (fc == 0)
|
||||
return;
|
||||
|
||||
/* Allocate memory for cache entries. */
|
||||
if (frccap < 4 * fc) {
|
||||
frccap += 4 * fc - frccap;
|
||||
frc = xrealloc(frc, frccap * sizeof(Fontcache));
|
||||
}
|
||||
|
||||
for (fp = font2; fp - font2 < fc; ++fp) {
|
||||
|
||||
if (**fp == '-')
|
||||
pattern = XftXlfdParse(*fp, False, False);
|
||||
else
|
||||
pattern = FcNameParse((FcChar8 *)*fp);
|
||||
|
||||
if (!pattern)
|
||||
die("can't open spare font %s\n", *fp);
|
||||
|
||||
if (defaultfontsize > 0) {
|
||||
sizeshift = usedfontsize - defaultfontsize;
|
||||
if (sizeshift != 0 &&
|
||||
FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval) ==
|
||||
FcResultMatch) {
|
||||
fontval += sizeshift;
|
||||
FcPatternDel(pattern, FC_PIXEL_SIZE);
|
||||
FcPatternDel(pattern, FC_SIZE);
|
||||
FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fontval);
|
||||
}
|
||||
}
|
||||
|
||||
FcPatternAddBool(pattern, FC_SCALABLE, 1);
|
||||
|
||||
FcConfigSubstitute(NULL, pattern, FcMatchPattern);
|
||||
XftDefaultSubstitute(xw.dpy, xw.scr, pattern);
|
||||
|
||||
if (xloadsparefont(pattern, FRC_NORMAL))
|
||||
die("can't open spare font %s\n", *fp);
|
||||
|
||||
FcPatternDel(pattern, FC_SLANT);
|
||||
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
|
||||
if (xloadsparefont(pattern, FRC_ITALIC))
|
||||
die("can't open spare font %s\n", *fp);
|
||||
|
||||
FcPatternDel(pattern, FC_WEIGHT);
|
||||
FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD);
|
||||
if (xloadsparefont(pattern, FRC_ITALICBOLD))
|
||||
die("can't open spare font %s\n", *fp);
|
||||
|
||||
FcPatternDel(pattern, FC_SLANT);
|
||||
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN);
|
||||
if (xloadsparefont(pattern, FRC_BOLD))
|
||||
die("can't open spare font %s\n", *fp);
|
||||
|
||||
FcPatternDestroy(pattern);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
xunloadfont(Font *f)
|
||||
{
|
||||
|
@ -1034,41 +1150,58 @@ xunloadfonts(void)
|
|||
xunloadfont(&dc.ibfont);
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
ximopen(Display *dpy)
|
||||
{
|
||||
XIMCallback destroy = { .client_data = NULL, .callback = ximdestroy };
|
||||
XIMCallback imdestroy = { .client_data = NULL, .callback = ximdestroy };
|
||||
XICCallback icdestroy = { .client_data = NULL, .callback = xicdestroy };
|
||||
|
||||
if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) {
|
||||
XSetLocaleModifiers("@im=local");
|
||||
if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) {
|
||||
XSetLocaleModifiers("@im=");
|
||||
if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL)
|
||||
die("XOpenIM failed. Could not open input device.\n");
|
||||
}
|
||||
xw.ime.xim = XOpenIM(xw.dpy, NULL, NULL, NULL);
|
||||
if (xw.ime.xim == NULL)
|
||||
return 0;
|
||||
|
||||
if (XSetIMValues(xw.ime.xim, XNDestroyCallback, &imdestroy, NULL))
|
||||
fprintf(stderr, "XSetIMValues: "
|
||||
"Could not set XNDestroyCallback.\n");
|
||||
|
||||
xw.ime.spotlist = XVaCreateNestedList(0, XNSpotLocation, &xw.ime.spot,
|
||||
NULL);
|
||||
|
||||
if (xw.ime.xic == NULL) {
|
||||
xw.ime.xic = XCreateIC(xw.ime.xim, XNInputStyle,
|
||||
XIMPreeditNothing | XIMStatusNothing,
|
||||
XNClientWindow, xw.win,
|
||||
XNDestroyCallback, &icdestroy,
|
||||
NULL);
|
||||
}
|
||||
if (XSetIMValues(xw.xim, XNDestroyCallback, &destroy, NULL) != NULL)
|
||||
die("XSetIMValues failed. Could not set input method value.\n");
|
||||
xw.xic = XCreateIC(xw.xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
|
||||
XNClientWindow, xw.win, XNFocusWindow, xw.win, NULL);
|
||||
if (xw.xic == NULL)
|
||||
die("XCreateIC failed. Could not obtain input method.\n");
|
||||
if (xw.ime.xic == NULL)
|
||||
fprintf(stderr, "XCreateIC: Could not create input context.\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
ximinstantiate(Display *dpy, XPointer client, XPointer call)
|
||||
{
|
||||
ximopen(dpy);
|
||||
XUnregisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
|
||||
ximinstantiate, NULL);
|
||||
if (ximopen(dpy))
|
||||
XUnregisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
|
||||
ximinstantiate, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
ximdestroy(XIM xim, XPointer client, XPointer call)
|
||||
{
|
||||
xw.xim = NULL;
|
||||
xw.ime.xim = NULL;
|
||||
XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
|
||||
ximinstantiate, NULL);
|
||||
ximinstantiate, NULL);
|
||||
XFree(xw.ime.spotlist);
|
||||
}
|
||||
|
||||
int
|
||||
xicdestroy(XIC xim, XPointer client, XPointer call)
|
||||
{
|
||||
xw.ime.xic = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1125,6 +1258,9 @@ xinit(int cols, int rows)
|
|||
usedfont = (opt_font == NULL)? font : opt_font;
|
||||
xloadfonts(usedfont, 0);
|
||||
|
||||
/* spare fonts */
|
||||
xloadsparefonts();
|
||||
|
||||
/* colors */
|
||||
if (!USE_ARGB)
|
||||
xw.cmap = XDefaultColormap(xw.dpy, xw.scr);
|
||||
|
@ -1172,7 +1308,10 @@ xinit(int cols, int rows)
|
|||
xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap);
|
||||
|
||||
/* input methods */
|
||||
ximopen(xw.dpy);
|
||||
if (!ximopen(xw.dpy)) {
|
||||
XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
|
||||
ximinstantiate, NULL);
|
||||
}
|
||||
|
||||
/* white cursor, black outline */
|
||||
cursor = XCreateFontCursor(xw.dpy, mouseshape);
|
||||
|
@ -1203,8 +1342,8 @@ xinit(int cols, int rows)
|
|||
|
||||
win.mode = MODE_NUMLOCK;
|
||||
resettitle();
|
||||
XMapWindow(xw.dpy, xw.win);
|
||||
xhints();
|
||||
XMapWindow(xw.dpy, xw.win);
|
||||
XSync(xw.dpy, False);
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &xsel.tclick1);
|
||||
|
@ -1314,13 +1453,10 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
|
|||
fontpattern = FcFontSetMatch(0, fcsets, 1,
|
||||
fcpattern, &fcres);
|
||||
|
||||
/*
|
||||
* Overwrite or create the new cache entry.
|
||||
*/
|
||||
if (frclen >= LEN(frc)) {
|
||||
frclen = LEN(frc) - 1;
|
||||
XftFontClose(xw.dpy, frc[frclen].font);
|
||||
frc[frclen].unicodep = 0;
|
||||
/* Allocate memory for the new cache entry. */
|
||||
if (frclen >= frccap) {
|
||||
frccap += 16;
|
||||
frc = xrealloc(frc, frccap * sizeof(Fontcache));
|
||||
}
|
||||
|
||||
frc[frclen].font = XftFontOpenPattern(xw.dpy,
|
||||
|
@ -1653,11 +1789,13 @@ xfinishdraw(void)
|
|||
void
|
||||
xximspot(int x, int y)
|
||||
{
|
||||
XPoint spot = { borderpx + x * win.cw, borderpx + (y + 1) * win.ch };
|
||||
XVaNestedList attr = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL);
|
||||
if (xw.ime.xic == NULL)
|
||||
return;
|
||||
|
||||
XSetICValues(xw.xic, XNPreeditAttributes, attr, NULL);
|
||||
XFree(attr);
|
||||
xw.ime.spot.x = borderpx + x * win.cw;
|
||||
xw.ime.spot.y = borderpx + (y + 1) * win.ch;
|
||||
|
||||
XSetICValues(xw.ime.xic, XNPreeditAttributes, xw.ime.spotlist, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1734,13 +1872,15 @@ focus(XEvent *ev)
|
|||
return;
|
||||
|
||||
if (ev->type == FocusIn) {
|
||||
XSetICFocus(xw.xic);
|
||||
if (xw.ime.xic)
|
||||
XSetICFocus(xw.ime.xic);
|
||||
win.mode |= MODE_FOCUSED;
|
||||
xseturgency(0);
|
||||
if (IS_SET(MODE_FOCUS))
|
||||
ttywrite("\033[I", 3, 0);
|
||||
} else {
|
||||
XUnsetICFocus(xw.xic);
|
||||
if (xw.ime.xic)
|
||||
XUnsetICFocus(xw.ime.xic);
|
||||
win.mode &= ~MODE_FOCUSED;
|
||||
if (IS_SET(MODE_FOCUS))
|
||||
ttywrite("\033[O", 3, 0);
|
||||
|
@ -1795,7 +1935,7 @@ kpress(XEvent *ev)
|
|||
{
|
||||
XKeyEvent *e = &ev->xkey;
|
||||
KeySym ksym;
|
||||
char buf[32], *customkey;
|
||||
char buf[64], *customkey;
|
||||
int len;
|
||||
Rune c;
|
||||
Status status;
|
||||
|
@ -1804,7 +1944,10 @@ kpress(XEvent *ev)
|
|||
if (IS_SET(MODE_KBDLOCK))
|
||||
return;
|
||||
|
||||
len = XmbLookupString(xw.xic, e, buf, sizeof buf, &ksym, &status);
|
||||
if (xw.ime.xic)
|
||||
len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &ksym, &status);
|
||||
else
|
||||
len = XLookupString(e, buf, sizeof buf, &ksym, NULL);
|
||||
/* 1. shortcuts */
|
||||
for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) {
|
||||
if (ksym == bp->keysym && match(bp->mod, e->state)) {
|
||||
|
@ -1837,7 +1980,6 @@ kpress(XEvent *ev)
|
|||
ttywrite(buf, len, 1);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cmessage(XEvent *e)
|
||||
{
|
||||
|
|
|
@ -122,6 +122,8 @@ static WebKitFindOptions findopts = WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE |
|
|||
static SiteSpecific styles[] = {
|
||||
/* regexp file in $styledir */
|
||||
/* { ".*", "default.css" }, */
|
||||
{ ".*arcolinux.info.*", "arcolinux-info.css" },
|
||||
{ ".*arcolinuxforum.com.*", "arcolinuxforum.css" },
|
||||
{ ".*suckless.org.*", "suckless.css" },
|
||||
{ ".*wikipedia.org.*", "wikipedia.css" },
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue