Compare commits
39 Commits
splitlayou
...
wmfs1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b9e67982f8 | ||
|
|
0400fb5454 | ||
|
|
a7371e9445 | ||
|
|
a3a2f33ddf | ||
|
|
13d8a0acc8 | ||
|
|
02cd7d91e9 | ||
|
|
71f4b9df89 | ||
|
|
8f040ed7a4 | ||
|
|
e5a804cee8 | ||
|
|
48bdc94538 | ||
|
|
a501bd1127 | ||
|
|
ec5b71b371 | ||
|
|
5e2bcf03d6 | ||
|
|
fb04cef137 | ||
|
|
acffbdc188 | ||
|
|
b42c42245a | ||
|
|
570a3f0e64 | ||
|
|
39080f9952 | ||
|
|
8958dbfe70 | ||
|
|
84d30e25e2 | ||
|
|
31d875c438 | ||
|
|
c1fcd0dac7 | ||
|
|
8344b1cc82 | ||
|
|
92831181e7 | ||
|
|
1934aa713d | ||
|
|
bbf11ac274 | ||
|
|
2ec2bf4760 | ||
|
|
08d55605da | ||
|
|
69ec9d7db0 | ||
|
|
9c3130a17c | ||
|
|
4e2459318c | ||
|
|
58f6f674ca | ||
|
|
5d80ec8538 | ||
|
|
7e33c322ff | ||
|
|
d1f5acf938 | ||
|
|
6ed013fc7c | ||
|
|
4e33bc9bf7 | ||
|
|
7bfba91a92 | ||
|
|
54687912c5 |
87
Makefile.in
Normal file
87
Makefile.in
Normal file
@@ -0,0 +1,87 @@
|
||||
PROG=wmfs
|
||||
MAN=wmfs.1
|
||||
|
||||
# wmfs version
|
||||
VERSION=$(shell scripts/setlocalversion)
|
||||
|
||||
SRCS= \
|
||||
src/barwin.c \
|
||||
src/client.c \
|
||||
src/config.c \
|
||||
src/draw.c \
|
||||
src/event.c \
|
||||
src/ewmh.c \
|
||||
src/frame.c \
|
||||
src/infobar.c \
|
||||
src/init.c \
|
||||
src/launcher.c \
|
||||
src/layout.c \
|
||||
src/menu.c \
|
||||
src/mouse.c \
|
||||
src/parse_api.c \
|
||||
src/parse.c \
|
||||
src/screen.c \
|
||||
src/status.c \
|
||||
src/systray.c \
|
||||
src/tag.c \
|
||||
src/util.c \
|
||||
src/color.c \
|
||||
src/split.c \
|
||||
src/cfactor.c \
|
||||
src/wmfs.c
|
||||
|
||||
# flags
|
||||
CFLAGS+= -DXDG_CONFIG_DIR=\"${XDG_CONFIG_DIR}\"
|
||||
CFLAGS+= -DWMFS_VERSION=\"${VERSION}\"
|
||||
CFLAGS+= -Wall -Wextra
|
||||
|
||||
OBJS= ${SRCS:.c=.o}
|
||||
|
||||
all: ${PROG} ${MAN}.gz
|
||||
|
||||
${PROG}: ${OBJS} src/structs.h src/wmfs.h src/parse.h
|
||||
${CC} -o $@ ${OBJS} ${LDFLAGS}
|
||||
|
||||
${MAN}.gz: ${MAN}
|
||||
gzip -cn -9 ${MAN} > $@
|
||||
|
||||
.c.o:
|
||||
${CC} -c ${CFLAGS} $< -o $@
|
||||
|
||||
.PHONY: all clean distclean install uninstall dist
|
||||
|
||||
clean:
|
||||
rm -f ${OBJS} wmfs ${MAN}.gz
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile
|
||||
|
||||
install: all
|
||||
@echo installing executable file to ${DESTDIR}${PREFIX}/bin
|
||||
mkdir -p ${DESTDIR}${PREFIX}/bin
|
||||
install ${PROG} ${DESTDIR}${PREFIX}/bin
|
||||
@echo installing manual page to ${DESTDIR}${MANPREFIX}/man1
|
||||
mkdir -p ${DESTDIR}${MANPREFIX}/man1
|
||||
install -m 644 ${MAN}.gz ${DESTDIR}${MANPREFIX}/man1/
|
||||
@echo installing xsession file to ${DESTDIR}${PREFIX}/share/xsessions
|
||||
mkdir -p ${DESTDIR}${PREFIX}/share/xsessions
|
||||
install -m 644 wmfs.desktop ${DESTDIR}${PREFIX}/share/xsessions/
|
||||
@echo installing default config file to ${DESTDIR}${XDG_CONFIG_DIR}/wmfs/
|
||||
mkdir -p ${DESTDIR}${XDG_CONFIG_DIR}/wmfs/
|
||||
install -m 444 wmfsrc ${DESTDIR}${XDG_CONFIG_DIR}/wmfs/
|
||||
|
||||
uninstall:
|
||||
@echo removing executable file from ${DESTDIR}${PREFIX}/bin
|
||||
rm -f ${DESTDIR}${PREFIX}/bin/wmfs
|
||||
@echo removing manual page from ${DESTDIR}${MANPREFIX}/man1
|
||||
rm -f ${DESTDIR}${MANPREFIX}/man1/wmfs.1.gz
|
||||
@echo removing xsession file from ${DESTDIR}${PREFIX}/share/xsessions
|
||||
rm -f ${DESTDIR}${PREFIX}/share/xsessions/wmfs.desktop
|
||||
@echo removing config file from ${DESTDIR}${XDG_CONFIG_DIR}/wmfs/
|
||||
rm -f ${DESTDIR}${XDG_CONFIG_DIR}/wmfs/wmfsrc
|
||||
rmdir ${DESTDIR}${XDG_CONFIG_DIR}/wmfs/
|
||||
|
||||
dist:
|
||||
@echo "Generate wmfs-`date +%Y%m`.tar.gz"
|
||||
git archive --format=tar --prefix=wmfs-`date +%Y%m`/ master | gzip -c > wmfs-`date +%Y%m`.tar.gz
|
||||
|
||||
7
README
7
README
@@ -21,11 +21,11 @@ LICENSE : BSD, see COPYING.
|
||||
REQUIREMENT :
|
||||
- libx11
|
||||
- libxft (optional)
|
||||
\- freetype
|
||||
- freetype
|
||||
- libxinerama (optional)
|
||||
- libxrandr (optional)
|
||||
- imlib2 (optional)
|
||||
- cmake>=2.8 (build system)
|
||||
- cmake>=2.8 (build system, optional)
|
||||
|
||||
OS :
|
||||
- GNU/Linux : Supported.
|
||||
@@ -35,6 +35,9 @@ INSTALL :
|
||||
mkdir build/ && cd build/
|
||||
cmake ..
|
||||
|
||||
You can also use old build system if you don't want^Whave cmake
|
||||
./configure && make
|
||||
|
||||
DISTROS :
|
||||
- wmfs port for FreeBSD at x11-wm/wmfs
|
||||
- wmfs is available with AUR in ArchLinux (wmfs or wmfs-git)
|
||||
|
||||
111
configure
vendored
Executable file
111
configure
vendored
Executable file
@@ -0,0 +1,111 @@
|
||||
#!/bin/sh
|
||||
|
||||
LIBS="x11"
|
||||
USE_XINERAMA="xinerama"
|
||||
USE_XRANDR="xrandr"
|
||||
USE_IMLIB2="imlib2"
|
||||
USE_XFT="xft freetype2"
|
||||
OS=`uname -s`
|
||||
PREFIX=/usr/local
|
||||
MANPREFIX="$PREFIX/man"
|
||||
XDG_CONFIG_DIR="$PREFIX/etc/xdg"
|
||||
|
||||
while true; do
|
||||
case "$1" in
|
||||
--without-xinerama)
|
||||
USE_XINERAMA=""; shift;;
|
||||
--without-xrandr)
|
||||
USE_XRANDR=""; shift;;
|
||||
--without-imlib2)
|
||||
USE_IMLIB2=""; shift;;
|
||||
--without-xft)
|
||||
USE_XFT=""; shift;;
|
||||
--prefix)
|
||||
[ -z "$2" ] && echo "Missing argument" && exit 1
|
||||
PREFIX=$2; shift 2;;
|
||||
--xdg-config-dir)
|
||||
[ -z "$2" ] && echo "Missing argument" && exit 1
|
||||
XDG_CONFIG_DIR=$2; shift 2;;
|
||||
--man-prefix)
|
||||
[ -z "$2" ] && echo "Missing argument" && exit 1
|
||||
MANPREFIX=$2; shift 2;;
|
||||
--help|-h)
|
||||
echo "Usage: ./configure [options]
|
||||
--without-imlib2 : compile without imlib2 support
|
||||
--without-xrandr : compile without xrandr support
|
||||
--without-xinerama : compile without xinerama support
|
||||
--without-xft : compile without xft support
|
||||
--prefix DIRECTORY : install binary with specified prefix (default $PREFIX)
|
||||
--xdg-config-dir DIRECTORY : install configuration to specified directory (default $XDG_CONFIG_DIR)
|
||||
--man-prefix DIRECTORY : install man page to specified prefix (default $MANPREFIX)"
|
||||
exit 0;;
|
||||
*) break;;
|
||||
esac
|
||||
done
|
||||
|
||||
LIBS="$LIBS $USE_XINERAMA $USE_XRANDR $USE_IMLIB2 $USE_XFT"
|
||||
|
||||
which pkg-config >/dev/null 2>&1
|
||||
|
||||
if [ $? -eq 0 ];
|
||||
then
|
||||
CFLAGS=`pkg-config --cflags-only-I $LIBS`
|
||||
LDFLAGS=`pkg-config --libs $LIBS`
|
||||
else
|
||||
# Try to use some known paths
|
||||
case $OS in
|
||||
FreeBSD)
|
||||
CFLAGS="-I/usr/local/include -I/usr/local/include/freetype2"
|
||||
LDFLAGS="-L/usr/local/lib";;
|
||||
OpenBSD)
|
||||
CFLAGS="-I/usr/X11R6/include -I/usr/X11R6/include/freetype2 -I/usr/local/include"
|
||||
LDFLAGS="-L/usr/X11R6/lib -L/usr/local/lib";;
|
||||
NetBSD)
|
||||
CFLAGS="-I/usr/X11R7/include -I/usr/X11R7/include/freetype2 -I/usr/local/include"
|
||||
LDFLAGS="-L/usr/X11R7/lib -L/usr/local/lib";;
|
||||
Linux)
|
||||
CFLAGS="-I/usr/include/freetype2"
|
||||
LDFLAGS=""
|
||||
;;
|
||||
*)
|
||||
echo "No default CFLAGS and LDFLAGS found for your OS, feel free to contribute or install pkg-config :)"
|
||||
exit 1;;
|
||||
esac
|
||||
|
||||
LDFLAGS="$LDFLAGS -lX11"
|
||||
|
||||
[ -n "$USE_XINERAMA" ] && LDFLAGS="$LDFLAGS -lXinerama"
|
||||
[ -n "$USE_XRANDR" ] && LDFLAGS="$LDFLAGS -lXrandr"
|
||||
[ -n "$USE_IMLIB2" ] && LDFLAGS="$LDFLAGS -lImlib2"
|
||||
[ -n "$USE_XFT" ] && LDFLAGS="$LDFLAGS -lXft -lfreetype"
|
||||
fi
|
||||
|
||||
[ -n "$USE_XINERAMA" ] && CFLAGS="$CFLAGS -DHAVE_XINERAMA"
|
||||
[ -n "$USE_XRANDR" ] && CFLAGS="$CFLAGS -DHAVE_XRANDR"
|
||||
[ -n "$USE_IMLIB2" ] && CFLAGS="$CFLAGS -DHAVE_IMLIB"
|
||||
[ -n "$USE_XFT" ] && CFLAGS="$CFLAGS -DHAVE_XFT"
|
||||
|
||||
LDFLAGS="$LDFLAGS -lpthread"
|
||||
|
||||
cat > Makefile << EOF
|
||||
PREFIX=$PREFIX
|
||||
XDG_CONFIG_DIR=$XDG_CONFIG_DIR
|
||||
MANPREFIX=$MANPREFIX
|
||||
|
||||
CFLAGS+=$CFLAGS
|
||||
LDFLAGS+=$LDFLAGS
|
||||
|
||||
EOF
|
||||
|
||||
cat Makefile.in >> Makefile
|
||||
|
||||
echo "Compilation resume:
|
||||
OS=$OS
|
||||
CFLAGS=$CFLAGS
|
||||
LDFLAGS=$LDFLAGS
|
||||
PREFIX=$PREFIX
|
||||
MANPREFIX=$MANPREFIX
|
||||
XDG_CONFIG_DIR=$XDG_CONFIG_DIR
|
||||
|
||||
You can run 'make' now :-)
|
||||
"
|
||||
@@ -8,4 +8,4 @@ statustext()
|
||||
wmfs -s "`date`"
|
||||
}
|
||||
|
||||
statustext
|
||||
while true; do statustext; sleep 10; done
|
||||
|
||||
101
src/barwin.c
101
src/barwin.c
@@ -98,7 +98,10 @@ barwin_create(Window parent,
|
||||
bw->bg = bg;
|
||||
bw->fg = fg;
|
||||
FLAGAPPLY(bw->flags, stipple, StippleFlag);
|
||||
bw->stipple_color = -1;
|
||||
bw->stipple_color = 0xffffffff;
|
||||
|
||||
/* Attach */
|
||||
SLIST_INSERT_HEAD(&bwhead, bw, next);
|
||||
|
||||
return bw;
|
||||
}
|
||||
@@ -123,8 +126,6 @@ barwin_draw_text(BarWindow *bw, int x, int y, char *text)
|
||||
void
|
||||
barwin_color_set(BarWindow *bw, uint bg, char *fg)
|
||||
{
|
||||
CHECK(bw);
|
||||
|
||||
bw->bg = bg;
|
||||
bw->fg = fg;
|
||||
|
||||
@@ -134,7 +135,7 @@ barwin_color_set(BarWindow *bw, uint bg, char *fg)
|
||||
bw->border.dark = color_shade(bg, conf.colors.bar_dark_shade);
|
||||
}
|
||||
|
||||
if(bw->flags & StippleFlag && bw->stipple_color == -1)
|
||||
if(bw->flags & StippleFlag && bw->stipple_color == 0xffffffff)
|
||||
bw->stipple_color = getcolor(fg);
|
||||
|
||||
return;
|
||||
@@ -146,8 +147,7 @@ barwin_color_set(BarWindow *bw, uint bg, char *fg)
|
||||
void
|
||||
barwin_delete(BarWindow *bw)
|
||||
{
|
||||
CHECK(bw);
|
||||
|
||||
SLIST_REMOVE(&bwhead, bw, BarWindow, next);
|
||||
XSelectInput(dpy, bw->win, NoEventMask);
|
||||
XDestroyWindow(dpy, bw->win);
|
||||
XFreePixmap(dpy, bw->dr);
|
||||
@@ -156,77 +156,6 @@ barwin_delete(BarWindow *bw)
|
||||
return;
|
||||
}
|
||||
|
||||
/** Delete the BarWindow sub windows
|
||||
* \param bw BarWindow pointer
|
||||
*/
|
||||
void
|
||||
barwin_delete_subwin(BarWindow *bw)
|
||||
{
|
||||
CHECK(bw);
|
||||
|
||||
XDestroySubwindows(dpy, bw->win);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** Map a BarWindow
|
||||
* \param bw BarWindow pointer
|
||||
*/
|
||||
void
|
||||
barwin_map(BarWindow *bw)
|
||||
{
|
||||
CHECK(!(bw->flags & MappedFlag));
|
||||
|
||||
XMapWindow(dpy, bw->win);
|
||||
|
||||
bw->flags |= MappedFlag;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/** Map the subwindows of a BarWindow
|
||||
* Use for the BarWindow special border...
|
||||
* \param bw BarWindow pointer
|
||||
*/
|
||||
void
|
||||
barwin_map_subwin(BarWindow *bw)
|
||||
{
|
||||
CHECK(bw);
|
||||
|
||||
XMapSubwindows(dpy, bw->win);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** Unmap a BarWindow
|
||||
* \param bw BarWindow pointer
|
||||
*/
|
||||
void
|
||||
barwin_unmap(BarWindow *bw)
|
||||
{
|
||||
CHECK(bw->flags & MappedFlag);
|
||||
|
||||
XUnmapWindow(dpy, bw->win);
|
||||
|
||||
bw->flags &= ~MappedFlag;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** Unmap the BarWindow sub windows
|
||||
* \param bw BarWindow pointer
|
||||
*/
|
||||
void
|
||||
barwin_unmap_subwin(BarWindow *bw)
|
||||
{
|
||||
CHECK(bw);
|
||||
|
||||
XUnmapSubwindows(dpy, bw->win);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** Move a BarWindow
|
||||
* \param bw BarWindow pointer
|
||||
* \param x X position
|
||||
@@ -235,7 +164,7 @@ barwin_unmap_subwin(BarWindow *bw)
|
||||
void
|
||||
barwin_move(BarWindow *bw, int x, int y)
|
||||
{
|
||||
if(!bw || (bw->geo.x == x && bw->geo.y == y))
|
||||
if(bw->geo.x == x && bw->geo.y == y)
|
||||
return;
|
||||
|
||||
XMoveWindow(dpy, bw->win, (bw->geo.x = x), (bw->geo.y = y));
|
||||
@@ -251,7 +180,7 @@ barwin_move(BarWindow *bw, int x, int y)
|
||||
void
|
||||
barwin_resize(BarWindow *bw, int w, int h)
|
||||
{
|
||||
if(!bw || (bw->geo.width == w && bw->geo.height == h))
|
||||
if(bw->geo.width == w && bw->geo.height == h)
|
||||
return;
|
||||
|
||||
/* Frame */
|
||||
@@ -285,8 +214,6 @@ barwin_resize(BarWindow *bw, int w, int h)
|
||||
void
|
||||
barwin_refresh_color(BarWindow *bw)
|
||||
{
|
||||
CHECK(bw);
|
||||
|
||||
XSetForeground(dpy, gc, bw->bg);
|
||||
XFillRectangle(dpy, bw->dr, gc, 0, 0, bw->geo.width, bw->geo.height);
|
||||
|
||||
@@ -312,15 +239,3 @@ barwin_refresh_color(BarWindow *bw)
|
||||
return;
|
||||
}
|
||||
|
||||
/** Refresh the BarWindow
|
||||
* \param bw BarWindow pointer
|
||||
*/
|
||||
void
|
||||
barwin_refresh(BarWindow *bw)
|
||||
{
|
||||
CHECK(bw);
|
||||
|
||||
XCopyArea(dpy, bw->dr, bw->win, gc, 0, 0, bw->geo.width, bw->geo.height, 0, 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -108,10 +108,10 @@ static void
|
||||
_cfactor_arrange_row(Client *c, Position p, int fac)
|
||||
{
|
||||
Geo cgeo = c->frame_geo;
|
||||
Client *cc;
|
||||
Client *cc = tiled_client(c->screen, SLIST_FIRST(&clients));
|
||||
|
||||
/* Travel clients to search parents of row and apply fact */
|
||||
for(cc = tiled_client(c->screen, clients); cc; cc = tiled_client(c->screen, cc->next))
|
||||
for(; cc; cc = tiled_client(c->screen, SLIST_NEXT(cc, next)))
|
||||
if(CFACTOR_PARENTROW(cgeo, cc->frame_geo, p))
|
||||
{
|
||||
cc->tilefact[p] += fac;
|
||||
@@ -131,13 +131,13 @@ static bool
|
||||
_cfactor_check_geo_row(Client *c, Position p, int fac)
|
||||
{
|
||||
Geo cgeo = c->frame_geo;
|
||||
Client *cc;
|
||||
Client *cc = tiled_client(c->screen, SLIST_FIRST(&clients));
|
||||
int e, f[4] = { 0 };
|
||||
|
||||
f[p] += fac;
|
||||
|
||||
/* Travel clients to search parents of row and check geos */
|
||||
for(cc = tiled_client(c->screen, clients); cc; cc = tiled_client(c->screen, cc->next))
|
||||
for(; cc; cc = tiled_client(c->screen, SLIST_NEXT(cc, next)))
|
||||
if(CFACTOR_PARENTROW(cgeo, cc->frame_geo, p))
|
||||
{
|
||||
(Geo)cfactor_geo(cc->wrgeo, f, &e);
|
||||
|
||||
112
src/client.c
112
src/client.c
@@ -87,11 +87,7 @@ CLIENT_ACTION_DIR(swapsel, Bottom);
|
||||
void
|
||||
client_attach(Client *c)
|
||||
{
|
||||
if(clients)
|
||||
clients->prev = c;
|
||||
|
||||
c->next = clients;
|
||||
clients = c;
|
||||
SLIST_INSERT_HEAD(&clients, c, next);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -126,10 +122,7 @@ client_configure(Client *c)
|
||||
void
|
||||
client_detach(Client *c)
|
||||
{
|
||||
Client **cc;
|
||||
|
||||
for(cc = &clients; *cc && *cc != c; cc = &(*cc)->next);
|
||||
*cc = c->next;
|
||||
SLIST_REMOVE(&clients, c, Client, next);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -147,10 +140,10 @@ client_get_next(void)
|
||||
if(!sel || ishide(sel, selscreen))
|
||||
return NULL;
|
||||
|
||||
for(c = sel->next; c && ishide(c, selscreen); c = c->next);
|
||||
for(c = SLIST_NEXT(sel, next); c && ishide(c, selscreen); c = SLIST_NEXT(c, next));
|
||||
|
||||
if(!c && conf.client_round)
|
||||
for(c = clients; c && ishide(c, selscreen); c = c->next);
|
||||
for(c = SLIST_FIRST(&clients); c && ishide(c, selscreen); c = SLIST_NEXT(c, next));
|
||||
|
||||
return c;
|
||||
}
|
||||
@@ -161,19 +154,19 @@ client_get_next(void)
|
||||
Client*
|
||||
client_get_prev(void)
|
||||
{
|
||||
Client *c = NULL, *d;
|
||||
Client *c = NULL, *d = SLIST_FIRST(&clients);
|
||||
|
||||
screen_get_sel();
|
||||
|
||||
if(!sel || ishide(sel, selscreen))
|
||||
return NULL;
|
||||
|
||||
for(d = clients; d != sel; d = d->next)
|
||||
for(; d != sel; d = SLIST_NEXT(d, next))
|
||||
if(!ishide(d, selscreen))
|
||||
c = d;
|
||||
|
||||
if(!c && conf.client_round)
|
||||
for(; d; d = d->next)
|
||||
for(; d; d = SLIST_NEXT(d, next))
|
||||
if(!ishide(d, selscreen))
|
||||
c = d;
|
||||
|
||||
@@ -273,7 +266,7 @@ client_focus(Client *c)
|
||||
if((sel = c))
|
||||
{
|
||||
/* Set focusontag option */
|
||||
for(cc = clients; cc; cc = cc->next)
|
||||
SLIST_FOREACH(cc, &clients, next)
|
||||
if(cc->focusontag == (int)c->tag)
|
||||
cc->focusontag = -1;
|
||||
|
||||
@@ -302,13 +295,13 @@ client_focus(Client *c)
|
||||
XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
|
||||
|
||||
if(conf.bars.selbar)
|
||||
infobar_draw_selbar(&infobar[sel->screen]);
|
||||
_infobar_draw(&infobar[sel->screen]);
|
||||
}
|
||||
else
|
||||
{
|
||||
XSetInputFocus(dpy, ROOT, RevertToPointerRoot, CurrentTime);
|
||||
if(conf.bars.selbar)
|
||||
infobar_draw_selbar(&infobar[selscreen]);
|
||||
_infobar_draw(&infobar[selscreen]);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -338,10 +331,10 @@ client_urgent(Client *c, bool u)
|
||||
*/
|
||||
Client* client_gb_win(Window w)
|
||||
{
|
||||
Client *c = clients;
|
||||
Client *c = SLIST_FIRST(&clients);
|
||||
|
||||
while(c && c->win != w)
|
||||
c = c->next;
|
||||
c = SLIST_NEXT(c, next);
|
||||
|
||||
return c;
|
||||
}
|
||||
@@ -352,10 +345,10 @@ client_urgent(Client *c, bool u)
|
||||
*/
|
||||
Client* client_gb_frame(Window w)
|
||||
{
|
||||
Client *c = clients;
|
||||
Client *c = SLIST_FIRST(&clients);
|
||||
|
||||
while(c && c->frame != w)
|
||||
c = c->next;
|
||||
c = SLIST_NEXT(c, next);
|
||||
|
||||
return c;
|
||||
}
|
||||
@@ -366,13 +359,13 @@ client_urgent(Client *c, bool u)
|
||||
*/
|
||||
Client* client_gb_titlebar(Window w)
|
||||
{
|
||||
Client *c = clients;
|
||||
Client *c = SLIST_FIRST(&clients);
|
||||
|
||||
if(!(TBARH - BORDH))
|
||||
return NULL;
|
||||
|
||||
while(c && c->titlebar->win != w)
|
||||
c = c->next;
|
||||
c = SLIST_NEXT(c, next);
|
||||
|
||||
return c;
|
||||
}
|
||||
@@ -383,10 +376,10 @@ client_urgent(Client *c, bool u)
|
||||
*/
|
||||
Client* client_gb_resize(Window w)
|
||||
{
|
||||
Client *c = clients;
|
||||
Client *c = SLIST_FIRST(&clients);
|
||||
|
||||
while(c && (c->resize[Right] != w) && (c->resize[Left] != w))
|
||||
c = c->next;
|
||||
c = SLIST_NEXT(c, next);
|
||||
|
||||
return c;
|
||||
}
|
||||
@@ -398,13 +391,13 @@ client_urgent(Client *c, bool u)
|
||||
*/
|
||||
Client* client_gb_button(Window w, int *n)
|
||||
{
|
||||
Client *c = clients;
|
||||
Client *c;
|
||||
int i;
|
||||
|
||||
if(!BUTTONWH || !(TBARH - BORDH))
|
||||
return NULL;
|
||||
|
||||
for(; c; c = c->next)
|
||||
SLIST_FOREACH(c, &clients, next)
|
||||
for(i = 0; i < conf.titlebar.nbutton; ++i)
|
||||
if(c->button[i] == w)
|
||||
{
|
||||
@@ -422,17 +415,16 @@ client_urgent(Client *c, bool u)
|
||||
*/
|
||||
Client* client_gb_pos(Client *c, int x, int y)
|
||||
{
|
||||
Client *cc = clients;
|
||||
Client *cc;
|
||||
|
||||
if((x | y) < 0 || x > spgeo[c->screen].x + spgeo[c->screen].width
|
||||
|| y > spgeo[c->screen].y + spgeo[c->screen].height)
|
||||
return NULL;
|
||||
|
||||
for(; cc; cc = cc->next)
|
||||
SLIST_FOREACH(cc, &clients, next)
|
||||
if(cc != c && cc->screen == c->screen && cc->tag == c->tag
|
||||
&& (cc->flags & TileFlag))
|
||||
if(cc->frame_geo.x < x && cc->frame_geo.x + cc->frame_geo.width > x
|
||||
&& cc->frame_geo.y < y && cc->frame_geo.y + cc->frame_geo.height > y)
|
||||
if(INAREA(x, y, cc->frame_geo))
|
||||
return cc;
|
||||
|
||||
return c;
|
||||
@@ -468,7 +460,7 @@ client_get_name(Client *c)
|
||||
frame_update(c);
|
||||
|
||||
if(conf.bars.selbar && c == sel)
|
||||
infobar_draw_selbar(&infobar[c->screen]);
|
||||
_infobar_draw(&infobar[c->screen]);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -597,6 +589,7 @@ client_set_rules(Client *c)
|
||||
ulong n, il;
|
||||
uchar *data = NULL;
|
||||
char wwrole[256] = { 0 };
|
||||
char netwmname[256] = { 0 };
|
||||
bool applied_tag_rule = False;
|
||||
bool applied_screen_rule = False;
|
||||
|
||||
@@ -619,14 +612,24 @@ client_set_rules(Client *c)
|
||||
XFree(data);
|
||||
}
|
||||
|
||||
/* Apply Rule if class || instance || role match */
|
||||
/* Get _NET_WM_NAME */
|
||||
if(XGetWindowProperty(dpy, c->win, ATOM("_NET_WM_NAME"), 0, 0x77777777, False,
|
||||
ATOM("UTF8_STRING"), &rf, &f, &n, &il, &data) == Success && data)
|
||||
{
|
||||
strncpy(netwmname, (char*)data, sizeof(netwmname));
|
||||
XFree(data);
|
||||
}
|
||||
|
||||
/* Apply Rule if class || instance || role || name match */
|
||||
for(i = 0; i < conf.nrule; ++i)
|
||||
{
|
||||
if((xch.res_class && conf.rule[i].class && !strcmp(xch.res_class, conf.rule[i].class))
|
||||
|| (xch.res_name && conf.rule[i].instance && !strcmp(xch.res_name, conf.rule[i].instance)))
|
||||
{
|
||||
if((strlen(wwrole) && conf.rule[i].role && !strcmp(wwrole, conf.rule[i].role))
|
||||
|| (!strlen(wwrole) || !conf.rule[i].role))
|
||||
if(((strlen(wwrole) && conf.rule[i].role && !strcmp(wwrole, conf.rule[i].role))
|
||||
|| (!strlen(wwrole) || !conf.rule[i].role))
|
||||
&& ((strlen(netwmname) && conf.rule[i].name && !strcmp(netwmname, conf.rule[i].name))
|
||||
|| (!strlen(netwmname) || !conf.rule[i].name)))
|
||||
{
|
||||
if(conf.rule[i].screen != -1)
|
||||
c->screen = conf.rule[i].screen;
|
||||
@@ -649,7 +652,7 @@ client_set_rules(Client *c)
|
||||
client_maximize(c);
|
||||
}
|
||||
|
||||
if(c->tag != (uint)seltag[selscreen])
|
||||
if(c->tag != seltag[selscreen])
|
||||
{
|
||||
tags[c->screen][c->tag].flags |= RequestUpdateFlag;
|
||||
client_focus(NULL);
|
||||
@@ -755,7 +758,7 @@ client_manage(Window w, XWindowAttributes *wa, bool ar)
|
||||
tags[c->screen][c->tag].flags |= CleanFactFlag;
|
||||
cfactor_clean(c);
|
||||
|
||||
at.event_mask = PropertyChangeMask;
|
||||
at.event_mask = EnterWindowMask | LeaveWindowMask | StructureNotifyMask | PropertyChangeMask;
|
||||
|
||||
frame_create(c);
|
||||
client_size_hints(c);
|
||||
@@ -767,7 +770,7 @@ client_manage(Window w, XWindowAttributes *wa, bool ar)
|
||||
|
||||
/* Transient for tag setting */
|
||||
if((rettrans = XGetTransientForHint(dpy, w, &trans) == Success))
|
||||
for(t = clients; t && t->win != trans; t = t->next);
|
||||
for(t = SLIST_FIRST(&clients); t && t->win != trans; t = SLIST_NEXT(t, next));
|
||||
|
||||
if(t)
|
||||
{
|
||||
@@ -783,7 +786,7 @@ client_manage(Window w, XWindowAttributes *wa, bool ar)
|
||||
client_set_rules(c);
|
||||
client_get_name(c);
|
||||
|
||||
if(c->tag == (uint)seltag[selscreen])
|
||||
if(c->tag == seltag[selscreen])
|
||||
{
|
||||
client_raise(c);
|
||||
client_map(c);
|
||||
@@ -804,7 +807,7 @@ client_manage(Window w, XWindowAttributes *wa, bool ar)
|
||||
if(!conf.client.set_new_win_master)
|
||||
layout_set_client_master(c);
|
||||
|
||||
if(c->tag == (uint)seltag[selscreen])
|
||||
if(c->tag == seltag[selscreen])
|
||||
client_focus(c);
|
||||
|
||||
if(conf.client.new_client_get_mouse)
|
||||
@@ -1146,16 +1149,13 @@ client_unhide(Client *c)
|
||||
void
|
||||
client_focus_next(Client *c)
|
||||
{
|
||||
Client *c_next = NULL;
|
||||
Client *c_next = SLIST_FIRST(&clients);
|
||||
|
||||
for(c_next = clients;
|
||||
c_next && c_next != c->prev
|
||||
&& c_next->tag != c->tag
|
||||
&& c_next->screen != c->screen;
|
||||
c_next = c_next->next);
|
||||
for(; c_next && c_next->tag != c->tag && c_next->screen != c->screen;
|
||||
c_next = SLIST_NEXT(c_next, next));
|
||||
|
||||
if(c_next && c_next->tag == (uint)seltag[selscreen]
|
||||
&& c_next->screen == selscreen)
|
||||
if(c_next && c_next->tag == seltag[selscreen]
|
||||
&& c_next->screen == selscreen)
|
||||
client_focus(c_next);
|
||||
|
||||
return;
|
||||
@@ -1204,7 +1204,7 @@ client_unmanage(Client *c)
|
||||
{
|
||||
/* Arrange */
|
||||
for(i = 0; i < screen_count() && !b; ++i)
|
||||
if(c->tag == (uint)seltag[i])
|
||||
if(c->tag == seltag[i])
|
||||
{
|
||||
b = True;
|
||||
break;
|
||||
@@ -1421,7 +1421,7 @@ uicb_client_select(uicb_t cmd)
|
||||
if(clist_index[i].client->screen != selscreen)
|
||||
screen_set_sel(clist_index[i].client->screen);
|
||||
|
||||
if(clist_index[i].client->tag != (uint)seltag[clist_index[i].client->screen])
|
||||
if(clist_index[i].client->tag != seltag[clist_index[i].client->screen])
|
||||
tag_set(clist_index[i].client->tag);
|
||||
|
||||
client_focus(clist_index[i].client);
|
||||
@@ -1443,8 +1443,8 @@ uicb_client_select(uicb_t cmd)
|
||||
void
|
||||
uicb_clientlist(uicb_t cmd)
|
||||
{
|
||||
int i, d, u, x, y;
|
||||
int n = 0;
|
||||
int d, u, x, y;
|
||||
int n = 0, i = 0;
|
||||
bool all = False;
|
||||
Window w;
|
||||
Client *c = NULL;
|
||||
@@ -1454,7 +1454,7 @@ uicb_clientlist(uicb_t cmd)
|
||||
if(cmd && !strcmp(cmd, "all"))
|
||||
all = True;
|
||||
|
||||
for(c = clients; c; c = c->next)
|
||||
SLIST_FOREACH(c, &clients, next)
|
||||
if(!ishide(c, selscreen) || all)
|
||||
++n;
|
||||
|
||||
@@ -1472,7 +1472,7 @@ uicb_clientlist(uicb_t cmd)
|
||||
|
||||
clientlist.align = MA_Left;
|
||||
|
||||
for(i = 0, c = clients; c; c = c->next)
|
||||
SLIST_FOREACH(c, &clients, next)
|
||||
if(!ishide(c, selscreen) || all)
|
||||
{
|
||||
sprintf(clist_index[i].key, "%d", i);
|
||||
@@ -1530,7 +1530,7 @@ uicb_client_ignore_tag(uicb_t cmd)
|
||||
void
|
||||
uicb_client_set_master(uicb_t cmd)
|
||||
{
|
||||
Client *c;
|
||||
Client *c = SLIST_FIRST(&clients);
|
||||
(void)cmd;
|
||||
|
||||
/* get the first client */
|
||||
@@ -1538,7 +1538,7 @@ uicb_client_set_master(uicb_t cmd)
|
||||
if(!sel || ishide(sel, selscreen))
|
||||
return;
|
||||
|
||||
for(c = clients; c && ishide(c, selscreen); c = c->next);
|
||||
for(; c && ishide(c, selscreen); c = SLIST_NEXT(c, next));
|
||||
|
||||
if (c && c != sel)
|
||||
{
|
||||
|
||||
15
src/config.c
15
src/config.c
@@ -183,8 +183,6 @@ conf_misc_section(void)
|
||||
conf.focus_fmouse = fetch_opt_first(sec, "true", "focus_follow_mouse").boolean;
|
||||
conf.focus_fmov = fetch_opt_first(sec, "false", "focus_follow_movement").boolean;
|
||||
conf.focus_pclick = fetch_opt_first(sec, "true", "focus_pointer_click").boolean;
|
||||
conf.status_timing = fetch_opt_first(sec, "1", "status_timing").num;
|
||||
conf.status_path = fetch_opt_first(sec, "", "status_path").str;
|
||||
conf.autostart_path = fetch_opt_first(sec, "", "autostart_path").str;
|
||||
conf.autostart_command = fetch_opt_first(sec, "", "autostart_command").str;
|
||||
pad = fetch_opt_first(sec, "12", "pad").num;
|
||||
@@ -203,12 +201,6 @@ conf_misc_section(void)
|
||||
|
||||
conf.pad = pad;
|
||||
|
||||
if(conf.status_timing < 0)
|
||||
{
|
||||
warnx("configuration : status_timing value (%d) incorrect.", conf.status_timing);
|
||||
conf.status_timing = 1;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -225,10 +217,11 @@ conf_bar_section(void)
|
||||
conf.bars.height = fetch_opt_first(bar, "-1", "height").num;
|
||||
conf.colors.bar = getcolor((barbg = fetch_opt_first(bar, "#000000", "bg").str));
|
||||
conf.colors.text = fetch_opt_first(bar, "#ffffff", "fg").str;
|
||||
|
||||
conf.colors.bar_light_shade = fetch_opt_first(bar, "0.25", "light_shade").fnum;
|
||||
conf.colors.bar_dark_shade = fetch_opt_first(bar, "-0.25", "dark_shade").fnum;
|
||||
|
||||
conf.bars.element_order = fetch_opt_first(bar, "tls", "elements_order").str;
|
||||
|
||||
mouse = fetch_section(bar, "mouse");
|
||||
|
||||
if ((conf.bars.nmouse = fetch_section_count(mouse)) > 0)
|
||||
@@ -450,9 +443,6 @@ conf_layout_section(void)
|
||||
if((tmp = fetch_opt_first(layouts, "menu", "system").str) && !strcmp(tmp, "menu"))
|
||||
conf.layout_system = True;
|
||||
|
||||
if((tmp = fetch_opt_first(layouts, "right", "placement").str) && !strcmp(tmp, "left"))
|
||||
conf.layout_placement = True;
|
||||
|
||||
layout = fetch_section(layouts, "layout");
|
||||
conf.nlayout = fetch_section_count(layout);
|
||||
|
||||
@@ -686,6 +676,7 @@ conf_rule_section(void)
|
||||
conf.rule[i].class = fetch_opt_first(rule[i], "", "class").str;
|
||||
conf.rule[i].instance = fetch_opt_first(rule[i], "", "instance").str;
|
||||
conf.rule[i].role = fetch_opt_first(rule[i], "", "role").str;
|
||||
conf.rule[i].name = fetch_opt_first(rule[i], "", "name").str;
|
||||
conf.rule[i].screen = fetch_opt_first(rule[i], "-1", "screen").num;
|
||||
conf.rule[i].tag = fetch_opt_first(rule[i], "-1", "tag").num;
|
||||
conf.rule[i].free = fetch_opt_first(rule[i], "false", "free").boolean;
|
||||
|
||||
38
src/draw.c
38
src/draw.c
@@ -77,21 +77,43 @@ draw_image(Drawable dr, int x, int y, int w, int h, char *name)
|
||||
* --> \i[x;y;w;h;name]\
|
||||
*\param im ImageAttr pointer, image properties
|
||||
*\param str String
|
||||
*\param m Check dynamic mouse
|
||||
*\return n Lenght of i
|
||||
*/
|
||||
static int
|
||||
parse_image_block(Drawable dr, char *str)
|
||||
static void
|
||||
parse_image_block(Drawable dr, char *str, bool m)
|
||||
{
|
||||
ImageAttr im;
|
||||
char as;
|
||||
int i, j, k;
|
||||
Geo area;
|
||||
char as, mouse[512] = { 0 };
|
||||
int i = 0, j = 0, k = 0, n;
|
||||
|
||||
for(i = j = 0; i < (int)strlen(str); ++i, ++j)
|
||||
if(sscanf(&str[i], "\\i[%d;%d;%d;%d;%512[^]]]%c", &im.x, &im.y, &im.w, &im.h, im.name, &as) == 6
|
||||
for(; i < (int)strlen(str); ++i, ++j)
|
||||
if(((n = sscanf(&str[i], "\\i[%d;%d;%d;%d;%512[^];]]%c",
|
||||
&im.x, &im.y, &im.w, &im.h, im.name, &as)) == 6
|
||||
|| (n = sscanf(&str[i], "\\i[%d;%d;%d;%d;%512[^;];%512[^]]]%c",
|
||||
&im.x, &im.y, &im.w, &im.h, im.name, mouse, &as)) == 7)
|
||||
&& as == '\\')
|
||||
{
|
||||
draw_image(dr, im.x - sw, im.y, im.w, im.h, im.name);
|
||||
|
||||
/* Etablish clickable area on image (on infobar wins only (status mouse bind) */
|
||||
if(n == 7 && m)
|
||||
{
|
||||
area.x = im.x - sw;
|
||||
area.y = im.y;
|
||||
area.width = im.w;
|
||||
area.height = im.h;
|
||||
|
||||
/* Associate drawable with window; travel infobars */
|
||||
for(; k < screen_count(); ++k)
|
||||
if(infobar[k].bar->dr == dr)
|
||||
{
|
||||
statustext_mouse(mouse, area, &infobar[k]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(++i, --j; str[i] != as || str[i - 1] != ']'; ++i);
|
||||
}
|
||||
else if(j != i)
|
||||
@@ -128,7 +150,7 @@ draw_text(Drawable d, int x, int y, char* fg, char *str)
|
||||
|
||||
ostr = xstrdup(str);
|
||||
textlen = strlen(ostr);
|
||||
parse_image_block(d, str);
|
||||
parse_image_block(d, str, True);
|
||||
}
|
||||
#endif /* HAVE_IMLIB */
|
||||
|
||||
@@ -230,7 +252,7 @@ textw(char *text)
|
||||
{
|
||||
ostr = xstrdup(text);
|
||||
textlen = strlen(ostr);
|
||||
parse_image_block(d, text);
|
||||
parse_image_block(d, text, False);
|
||||
}
|
||||
#endif /* HAVE_IMLIB */
|
||||
|
||||
|
||||
169
src/event.c
169
src/event.c
@@ -33,6 +33,26 @@
|
||||
#include "wmfs.h"
|
||||
|
||||
#define EVDPY (e->xany.display)
|
||||
#define MAX_EV 256
|
||||
|
||||
/** Check mouse bind condition and execute associated function
|
||||
*/
|
||||
static void
|
||||
do_mousebind(int screen, uint button, int n, MouseBinding m[])
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for(; i < n; ++i)
|
||||
{
|
||||
if(m[i].screen == screen || m[i].screen < 0) /* Screen */
|
||||
if(m[i].tag == seltag[i] || m[i].tag < 0) /* Tag */
|
||||
if(m[i].button == button) /* Button */
|
||||
if(m[i].func) /* Function */
|
||||
m[i].func(m[i].cmd);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** ButtonPress handle event
|
||||
*/
|
||||
@@ -40,14 +60,18 @@ static void
|
||||
buttonpress(XEvent *e)
|
||||
{
|
||||
XButtonEvent *ev = &e->xbutton;
|
||||
StatusMouse *sm;
|
||||
InfoBar *ib;
|
||||
Client *c;
|
||||
int i, j, n;
|
||||
int i, n;
|
||||
|
||||
screen_get_sel();
|
||||
|
||||
ib = &infobar[selscreen];
|
||||
|
||||
/* If the mouse is on a not selected client and you click on it. */
|
||||
if(((c = client_gb_win(ev->window)) || (c = client_gb_titlebar(ev->window))) && c != sel
|
||||
&& (ev->button == Button1 || ev->button == Button2 || ev->button == Button3))
|
||||
if(((c = client_gb_win(ev->window)) || (c = client_gb_titlebar(ev->window)))
|
||||
&& c != sel && ev->button >= Button1 && ev->button <= Button3)
|
||||
{
|
||||
client_focus(c);
|
||||
client_raise(c);
|
||||
@@ -57,10 +81,7 @@ buttonpress(XEvent *e)
|
||||
|
||||
/* Titlebar */
|
||||
if((c = client_gb_titlebar(ev->window)) && c == sel)
|
||||
for(i = 0; i < conf.titlebar.nmouse; ++i)
|
||||
if(ev->button == conf.titlebar.mouse[i].button)
|
||||
if(conf.titlebar.mouse[i].func)
|
||||
conf.titlebar.mouse[i].func(conf.titlebar.mouse[i].cmd);
|
||||
do_mousebind(selscreen, ev->button, conf.titlebar.nmouse, conf.titlebar.mouse);
|
||||
|
||||
/* Titlebar buttons */
|
||||
if((c = client_gb_button(ev->window, &n)))
|
||||
@@ -78,86 +99,68 @@ buttonpress(XEvent *e)
|
||||
|
||||
/* Client */
|
||||
if((c = client_gb_win(ev->window)) && c == sel)
|
||||
for(i = 0; i < conf.client.nmouse; ++i)
|
||||
if(ev->button == conf.client.mouse[i].button)
|
||||
if(conf.client.mouse[i].func)
|
||||
conf.client.mouse[i].func(conf.client.mouse[i].cmd);
|
||||
do_mousebind(selscreen, ev->button, conf.client.nmouse, conf.client.mouse);
|
||||
|
||||
/* Root */
|
||||
if(ev->window == ROOT)
|
||||
for(i = 0; i < conf.root.nmouse; ++i)
|
||||
if(conf.root.mouse[i].tag == seltag[conf.root.mouse[i].screen]
|
||||
|| conf.root.mouse[i].tag < 0)
|
||||
if(ev->button == conf.root.mouse[i].button)
|
||||
if(conf.root.mouse[i].func)
|
||||
conf.root.mouse[i].func(conf.root.mouse[i].cmd);
|
||||
do_mousebind(selscreen, ev->button, conf.root.nmouse, conf.root.mouse);
|
||||
|
||||
/* Infobars */
|
||||
for(i = 0; i < screen_count(); ++i)
|
||||
if(ev->window == infobar[i].bar->win)
|
||||
for(j = 0; j < conf.bars.nmouse; ++j)
|
||||
if(conf.bars.mouse[j].screen == i
|
||||
|| conf.bars.mouse[j].screen < 0)
|
||||
if(conf.bars.mouse[j].tag == seltag[i]
|
||||
|| conf.bars.mouse[j].tag < 0)
|
||||
if(ev->button == conf.bars.mouse[j].button)
|
||||
if(conf.bars.mouse[j].func)
|
||||
conf.bars.mouse[j].func(conf.bars.mouse[j].cmd);
|
||||
do_mousebind(i, ev->button, conf.bars.nmouse, conf.bars.mouse);
|
||||
|
||||
/* Selbar */
|
||||
if(conf.bars.selbar && ev->window == infobar[selscreen].selbar->win)
|
||||
for(i = 0; i < conf.selbar.nmouse; ++i)
|
||||
if(conf.selbar.mouse[i].tag == seltag[conf.selbar.mouse[i].screen]
|
||||
|| conf.selbar.mouse[i].tag < 0)
|
||||
if(ev->button == conf.selbar.mouse[i].button)
|
||||
if(conf.selbar.mouse[i].func)
|
||||
conf.selbar.mouse[i].func(conf.selbar.mouse[i].cmd);
|
||||
if(conf.bars.selbar && ev->window == ib->bar->win)
|
||||
if(INAREA(ev->x, ev->y, ib->selbar_geo))
|
||||
do_mousebind(selscreen, ev->button, conf.selbar.nmouse, conf.selbar.mouse);
|
||||
|
||||
/* Tags */
|
||||
for(i = 1; i < conf.ntag[selscreen] + 1; ++i)
|
||||
if(ev->window == infobar[selscreen].tags[i]->win)
|
||||
{
|
||||
for(j = 0; j < tags[selscreen][i].nmouse; ++j)
|
||||
if(ev->button == tags[selscreen][i].mouse[j].button)
|
||||
if(tags[selscreen][i].mouse[j].func)
|
||||
tags[selscreen][i].mouse[j].func(tags[selscreen][i].mouse[j].cmd);
|
||||
if(ib->tags_board)
|
||||
{
|
||||
for(i = 1; i < conf.ntag[selscreen] + 1; ++i)
|
||||
if(ib->tags[i] && ev->window == ib->tags[i]->win)
|
||||
{
|
||||
do_mousebind(selscreen, ev->button, tags[selscreen][i].nmouse, tags[selscreen][i].mouse);
|
||||
|
||||
/* Mouse button action on tag */
|
||||
if(ev->button == conf.mouse_tag_action[TagSel])
|
||||
tag_set(i);
|
||||
else if(ev->button == conf.mouse_tag_action[TagTransfert])
|
||||
tag_transfert(sel, i);
|
||||
else if(ev->button == conf.mouse_tag_action[TagAdd])
|
||||
tag_additional(selscreen, seltag[selscreen], i);
|
||||
else if(ev->button == conf.mouse_tag_action[TagNext])
|
||||
tag_set(seltag[selscreen] + 1);
|
||||
else if(ev->button == conf.mouse_tag_action[TagPrev])
|
||||
tag_set(seltag[selscreen] - 1);
|
||||
}
|
||||
/* Mouse button action on tag */
|
||||
if(ev->button == conf.mouse_tag_action[TagSel])
|
||||
tag_set(i);
|
||||
else if(ev->button == conf.mouse_tag_action[TagTransfert])
|
||||
tag_transfert(sel, i);
|
||||
else if(ev->button == conf.mouse_tag_action[TagAdd])
|
||||
tag_additional(selscreen, seltag[selscreen], i);
|
||||
else if(ev->button == conf.mouse_tag_action[TagNext])
|
||||
tag_set(seltag[selscreen] + 1);
|
||||
else if(ev->button == conf.mouse_tag_action[TagPrev])
|
||||
tag_set(seltag[selscreen] - 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Layout button */
|
||||
if(ev->window == infobar[selscreen].layout_button->win && conf.nlayout > 1)
|
||||
if(ib->layout_button && ev->window == ib->layout_button->win && conf.nlayout > 1)
|
||||
{
|
||||
if(conf.layout_system && (ev->button == Button1 || ev->button == Button3)) /* True -> menu */
|
||||
{
|
||||
menulayout.y = spgeo[selscreen].y + infobar[selscreen].layout_button->geo.y + INFOBARH;
|
||||
menulayout.x = infobar[selscreen].layout_button->geo.x + (sgeo[selscreen].x - BORDH);
|
||||
menulayout.y = spgeo[selscreen].y + ib->layout_button->geo.y + INFOBARH;
|
||||
menulayout.x = ib->layout_button->geo.x + (sgeo[selscreen].x - BORDH);
|
||||
|
||||
if(infobar[selscreen].geo.y != spgeo[selscreen].y)
|
||||
menulayout.y = infobar[selscreen].geo.y - (INFOBARH * menulayout.nitem) - SHADH;
|
||||
if(ib->geo.y != spgeo[selscreen].y)
|
||||
menulayout.y = ib->geo.y - (INFOBARH * menulayout.nitem) - SHADH;
|
||||
|
||||
uicb_menu("menulayout");
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(ev->button)
|
||||
{
|
||||
case Button1: case Button4: layoutswitch(True); break;
|
||||
case Button3: case Button5: layoutswitch(False); break;
|
||||
}
|
||||
}
|
||||
layoutswitch(ev->button == Button1 || ev->button == Button4);
|
||||
}
|
||||
|
||||
/* Status mouse bindings */
|
||||
SLIST_FOREACH(sm, &smhead, next)
|
||||
if(sm->infobar->bar->win == ev->window && ev->button == sm->button)
|
||||
if(INAREA(ev->x, ev->y, sm->area))
|
||||
if(sm->func)
|
||||
sm->func(sm->cmd);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -168,6 +171,7 @@ clientmessageevent(XEvent *e)
|
||||
{
|
||||
XClientMessageEvent *ev = &e->xclient;
|
||||
Client *c;
|
||||
InfoBar *ib;
|
||||
Systray *sy;
|
||||
int s, mess_t = 0;
|
||||
Atom rt;
|
||||
@@ -248,7 +252,10 @@ clientmessageevent(XEvent *e)
|
||||
if(XGetWindowProperty(EVDPY, ROOT, net_atom[mess_t], 0, 4096,
|
||||
False, net_atom[utf8_string], &rt, &rf, &ir, &il, &ret) == Success)
|
||||
{
|
||||
statustext_handle(mess_t - wmfs_statustext, (char*)ret);
|
||||
ib = &infobar[mess_t - wmfs_statustext];
|
||||
free(ib->statustext);
|
||||
ib->statustext = xstrdup((char*)ret);
|
||||
_infobar_draw(ib);
|
||||
XFree(ret);
|
||||
}
|
||||
}
|
||||
@@ -281,10 +288,6 @@ clientmessageevent(XEvent *e)
|
||||
screen_get_sel();
|
||||
}
|
||||
|
||||
/* Manage _WMFS_UPDATE_STATUS */
|
||||
if(mess_t == wmfs_update_status && estatus)
|
||||
spawn(conf.status_path);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -406,21 +409,15 @@ expose(XEvent *e)
|
||||
{
|
||||
XExposeEvent *ev = &e->xexpose;
|
||||
Client *c;
|
||||
int i, sc;
|
||||
BarWindow *bw;
|
||||
|
||||
/* InfoBar member */
|
||||
for(sc = 0; sc < screen_count(); ++sc)
|
||||
{
|
||||
if(ev->window == infobar[sc].bar->win)
|
||||
barwin_refresh(infobar[sc].bar);
|
||||
if(ev->window == infobar[sc].layout_button->win)
|
||||
barwin_refresh(infobar[sc].layout_button);
|
||||
if(conf.bars.selbar && ev->window == infobar[sc].selbar->win)
|
||||
barwin_refresh(infobar[sc].selbar);
|
||||
for(i = 1; i < conf.ntag[sc] + 1; ++i)
|
||||
if(ev->window == infobar[sc].tags[i]->win)
|
||||
barwin_refresh(infobar[sc].tags[i]);
|
||||
}
|
||||
/* BarWindows */
|
||||
SLIST_FOREACH(bw, &bwhead, next)
|
||||
if(ev->window == bw->win)
|
||||
{
|
||||
barwin_refresh(bw);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Client frame */
|
||||
if((c = client_gb_titlebar(ev->window)))
|
||||
@@ -684,13 +681,9 @@ grabkeys(void)
|
||||
void
|
||||
event_make_array(void)
|
||||
{
|
||||
int i = LASTEvent;
|
||||
int i = MAX_EV;
|
||||
|
||||
#ifdef HAVE_XRANDR
|
||||
i = xrandr_event + RRScreenChangeNotify;
|
||||
#endif /* HAVE_XRANDR */
|
||||
|
||||
event_handle = xcalloc((nevent = i + 1), sizeof(event_handle));
|
||||
event_handle = xcalloc(MAX_EV, sizeof(event_handle));
|
||||
|
||||
/* Fill array with non-used function (do nothing) */
|
||||
while(i--)
|
||||
|
||||
12
src/ewmh.c
12
src/ewmh.c
@@ -95,7 +95,6 @@ ewmh_init_hints(void)
|
||||
/* WMFS hints */
|
||||
net_atom[wmfs_running] = ATOM("_WMFS_RUNNING");
|
||||
net_atom[wmfs_update_hints] = ATOM("_WMFS_UPDATE_HINTS");
|
||||
net_atom[wmfs_update_status] = ATOM("_WMFS_UPDATE_STATUS");
|
||||
net_atom[wmfs_set_screen] = ATOM("_WMFS_SET_SCREEN");
|
||||
net_atom[wmfs_screen_count] = ATOM("_WMFS_SCREEN_COUNT");
|
||||
net_atom[wmfs_current_tag] = ATOM("_WMFS_CURRENT_TAG");
|
||||
@@ -251,13 +250,16 @@ ewmh_get_client_list(void)
|
||||
{
|
||||
Window *list;
|
||||
Client *c;
|
||||
int win_n;
|
||||
int win_n = 0;
|
||||
|
||||
SLIST_FOREACH(c, &clients, next)
|
||||
++win_n;
|
||||
|
||||
for(win_n = 0, c = clients; c; c = c->next, ++win_n);
|
||||
list = xcalloc(win_n, sizeof(Window));
|
||||
|
||||
for(win_n = 0, c = clients; c; c = c->next, ++win_n)
|
||||
list[win_n] = c->win;
|
||||
win_n = 0;
|
||||
SLIST_FOREACH(c, &clients, next)
|
||||
list[win_n++] = c->win;
|
||||
|
||||
XChangeProperty(dpy, ROOT, net_atom[net_client_list], XA_WINDOW, 32,
|
||||
PropModeReplace, (uchar *)list, win_n);
|
||||
|
||||
397
src/infobar.c
397
src/infobar.c
@@ -34,105 +34,184 @@
|
||||
|
||||
#define SPLIT_IND_S (3 + conf.border.layout)
|
||||
|
||||
/** Init InfoBar elements
|
||||
*/
|
||||
static void
|
||||
infobar_init_element(InfoBar *i)
|
||||
{
|
||||
int j = 0, k, n = 0;
|
||||
InfobarElem *e, *prev = NULL;
|
||||
Geo pg = { -PAD, 0, 0, 0 };
|
||||
|
||||
STAILQ_INIT(&i->elemhead);
|
||||
|
||||
for(; n < (int)strlen(i->elemorder); ++n)
|
||||
{
|
||||
e = zcalloc(sizeof(InfobarElem));
|
||||
|
||||
/* Previous element geo */
|
||||
if(prev)
|
||||
pg = prev->geo;
|
||||
|
||||
e->geo.x = pg.x + pg.width + PAD;
|
||||
e->geo.y = 0;
|
||||
e->geo.height = i->geo.height;
|
||||
|
||||
switch(i->elemorder[n])
|
||||
{
|
||||
/* Tags element */
|
||||
case 't':
|
||||
e->type = ElemTag;
|
||||
e->geo.width = PAD; /* Will change */
|
||||
|
||||
if(!i->tags_board)
|
||||
{
|
||||
i->tags_board = barwin_create(i->bar->win,
|
||||
e->geo.x,
|
||||
e->geo.y,
|
||||
e->geo.width,
|
||||
e->geo.height,
|
||||
conf.colors.bar, conf.colors.text,
|
||||
False, False, False);
|
||||
|
||||
/* Create tags window */
|
||||
for(k = 1; k < conf.ntag[i->screen] + 1; ++k)
|
||||
{
|
||||
i->tags[k] = barwin_create(i->tags_board->win,
|
||||
j, 0,
|
||||
textw(tags[i->screen][k].name) + PAD,
|
||||
i->geo.height,
|
||||
conf.colors.bar, conf.colors.text,
|
||||
False, False, conf.border.tag);
|
||||
|
||||
j += textw(tags[i->screen][k].name) + PAD;
|
||||
barwin_map_subwin(i->tags[k]);
|
||||
}
|
||||
}
|
||||
|
||||
barwin_resize(i->tags_board, (e->geo.width = j), i->geo.height);
|
||||
barwin_map(i->tags_board);
|
||||
barwin_map_subwin(i->tags_board);
|
||||
break;
|
||||
|
||||
/* Layout button element */
|
||||
case 'l':
|
||||
e->type = ElemLayout;
|
||||
e->geo.width = (conf.layout_button_width > 0
|
||||
? (uint)conf.layout_button_width
|
||||
: textw(tags[i->screen][seltag[i->screen]].layout.symbol) + PAD);
|
||||
|
||||
if(!i->layout_button)
|
||||
i->layout_button = barwin_create(i->bar->win,
|
||||
e->geo.x,
|
||||
e->geo.y,
|
||||
e->geo.width,
|
||||
e->geo.height,
|
||||
conf.colors.layout_bg, conf.colors.layout_fg,
|
||||
False, False, conf.border.layout);
|
||||
|
||||
barwin_map(i->layout_button);
|
||||
|
||||
if(conf.border.layout)
|
||||
barwin_map_subwin(i->layout_button);
|
||||
break;
|
||||
|
||||
/* Selbar element */
|
||||
case 's':
|
||||
e->type = ElemSelbar;
|
||||
i->selbar_geo = e->geo;
|
||||
break;
|
||||
}
|
||||
|
||||
STAILQ_INSERT_TAIL(&i->elemhead, e, next);
|
||||
|
||||
prev = e;
|
||||
e = NULL;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** Init the InfoBar
|
||||
*/
|
||||
void
|
||||
infobar_init(void)
|
||||
{
|
||||
int s, sc, i, j = 0;
|
||||
|
||||
s = screen_count();
|
||||
InfoBar *i;
|
||||
int s = screen_count(), sc = 0;
|
||||
|
||||
if(!infobar)
|
||||
infobar = xcalloc(s, sizeof(InfoBar));
|
||||
|
||||
for(sc = 0; sc < s; ++sc)
|
||||
for(; sc < s; ++sc)
|
||||
{
|
||||
j = 0;
|
||||
infobar[sc].geo.height = INFOBARH;
|
||||
infobar[sc].screen = sc;
|
||||
i = &infobar[sc];
|
||||
i->geo.height = INFOBARH;
|
||||
i->screen = sc;
|
||||
i->elemorder = conf.bars.element_order;
|
||||
|
||||
switch(tags[sc][seltag[sc]].barpos)
|
||||
{
|
||||
case IB_Hide:
|
||||
sgeo[sc].y = spgeo[sc].y + TBARH;
|
||||
sgeo[sc].height += INFOBARH;
|
||||
infobar[sc].geo.y = (-(infobar[sc].geo.height) << 2);
|
||||
break;
|
||||
case IB_Bottom:
|
||||
sgeo[sc].y = TBARH;
|
||||
infobar[sc].geo.y = spgeo[sc].y + sgeo[sc].height + TBARH;
|
||||
break;
|
||||
default:
|
||||
case IB_Top:
|
||||
sgeo[sc].y = spgeo[sc].y + INFOBARH + TBARH;
|
||||
infobar[sc].geo.y = spgeo[sc].y;
|
||||
break;
|
||||
case IB_Hide:
|
||||
sgeo[sc].y = spgeo[sc].y + TBARH;
|
||||
sgeo[sc].height += INFOBARH;
|
||||
i->geo.y = (-(i->geo.height) << 2);
|
||||
break;
|
||||
case IB_Bottom:
|
||||
sgeo[sc].y = TBARH;
|
||||
i->geo.y = spgeo[sc].y + sgeo[sc].height + TBARH;
|
||||
break;
|
||||
default:
|
||||
case IB_Top:
|
||||
sgeo[sc].y = spgeo[sc].y + INFOBARH + TBARH;
|
||||
i->geo.y = spgeo[sc].y;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Create infobar barwindow */
|
||||
infobar[sc].bar = barwin_create(ROOT, sgeo[sc].x - BORDH, infobar[sc].geo.y,
|
||||
sgeo[sc].width, infobar[sc].geo.height,
|
||||
conf.colors.bar, conf.colors.text, False, False, conf.border.bar);
|
||||
i->bar = barwin_create(ROOT,
|
||||
sgeo[sc].x - BORDH,
|
||||
i->geo.y,
|
||||
sgeo[sc].width,
|
||||
i->geo.height,
|
||||
conf.colors.bar, conf.colors.text,
|
||||
False, False, conf.border.bar);
|
||||
|
||||
infobar[sc].tags_board = barwin_create(infobar[sc].bar->win,
|
||||
((conf.layout_placement) ? textw(tags[sc][seltag[sc]].layout.symbol) + PAD * 1.5: 0), 0,
|
||||
textw(tags[sc][0].name) + PAD, /* Base size, will change */
|
||||
infobar[sc].geo.height,
|
||||
conf.colors.bar, conf.colors.text, False, False, False);
|
||||
barwin_map(i->bar);
|
||||
barwin_map_subwin(i->bar);
|
||||
barwin_refresh_color(i->bar);
|
||||
barwin_refresh(i->bar);
|
||||
|
||||
/* Create tags window */
|
||||
for(i = 1; i < conf.ntag[sc] + 1; ++i)
|
||||
{
|
||||
infobar[sc].tags[i] = barwin_create(infobar[sc].tags_board->win, j, 0,
|
||||
textw(tags[sc][i].name) + PAD,
|
||||
infobar[sc].geo.height,
|
||||
conf.colors.bar, conf.colors.text, False, False, conf.border.tag);
|
||||
|
||||
j += textw(tags[sc][i].name) + PAD;
|
||||
|
||||
barwin_resize(infobar[sc].tags_board, j, infobar[sc].geo.height);
|
||||
barwin_map_subwin(infobar[sc].tags[i]);
|
||||
}
|
||||
|
||||
/* Create layout switch barwindow */
|
||||
infobar[sc].layout_button = barwin_create(infobar[sc].bar->win,
|
||||
((conf.layout_placement) ? 0 : (j + (PAD >> 1))), 0,
|
||||
((conf.layout_button_width > 0) ? (uint)conf.layout_button_width : (textw(tags[sc][seltag[sc]].layout.symbol) + PAD)),
|
||||
infobar[sc].geo.height,
|
||||
conf.colors.layout_bg, conf.colors.layout_fg,
|
||||
False, False, conf.border.layout);
|
||||
|
||||
/* Selbar */
|
||||
if(conf.bars.selbar)
|
||||
infobar[sc].selbar = barwin_create(infobar[sc].bar->win,
|
||||
((conf.layout_placement)
|
||||
? (j + (PAD >> 1))
|
||||
: infobar[sc].layout_button->geo.x + infobar[sc].layout_button->geo.width + (PAD >> 1)), 1,
|
||||
(sel) ? textw(sel->title) + PAD : 1,
|
||||
infobar[sc].geo.height - 2,
|
||||
conf.selbar.bg, conf.selbar.fg, False, False, False);
|
||||
|
||||
/* Map/Refresh all */
|
||||
barwin_map(infobar[sc].bar);
|
||||
barwin_map_subwin(infobar[sc].bar);
|
||||
|
||||
barwin_map(infobar[sc].tags_board);
|
||||
barwin_map_subwin(infobar[sc].tags_board);
|
||||
|
||||
if(conf.border.layout)
|
||||
barwin_map_subwin(infobar[sc].layout_button);
|
||||
|
||||
if(conf.bars.selbar)
|
||||
barwin_map(infobar[sc].selbar);
|
||||
|
||||
barwin_refresh_color(infobar[sc].bar);
|
||||
barwin_refresh(infobar[sc].bar);
|
||||
/* Init elements */
|
||||
infobar_init_element(i);
|
||||
|
||||
/* Default statustext is set here */
|
||||
infobar[sc].statustext = xstrdup("wmfs"WMFS_VERSION);
|
||||
i->statustext = xstrdup("wmfs"WMFS_VERSION);
|
||||
|
||||
infobar_draw(&infobar[sc]);
|
||||
infobar_draw(i);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
infobar_arrange_element(InfoBar *i)
|
||||
{
|
||||
Geo pg = { -PAD, 0, 0, 0 };
|
||||
InfobarElem *e, *pe = NULL;
|
||||
|
||||
STAILQ_FOREACH(e, &i->elemhead, next)
|
||||
{
|
||||
if(pe)
|
||||
pg = pe->geo;
|
||||
|
||||
e->geo.x = pg.x + pg.width + PAD;
|
||||
e->geo.y = 0;
|
||||
|
||||
if(e->type != ElemSelbar)
|
||||
barwin_move((e->type == ElemTag ? i->tags_board : i->layout_button), e->geo.x, e->geo.y);
|
||||
|
||||
pe = e;
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -144,28 +223,52 @@ infobar_init(void)
|
||||
void
|
||||
infobar_draw_layout(InfoBar *i)
|
||||
{
|
||||
int w, sc = i->screen;
|
||||
InfobarElem *e;
|
||||
int s = i->screen;
|
||||
|
||||
if(!conf.layout_placement)
|
||||
barwin_move(i->layout_button, i->tags_board->geo.width + (PAD >> 1), 0);
|
||||
/* Check if there is element in string element list */
|
||||
if(!strchr(i->elemorder, 'l'))
|
||||
return;
|
||||
|
||||
w = (conf.layout_button_width > 0)
|
||||
STAILQ_FOREACH(e, &i->elemhead, next)
|
||||
if(e->type == ElemLayout)
|
||||
break;
|
||||
|
||||
e->geo.width = (conf.layout_button_width >= 1)
|
||||
? conf.layout_button_width
|
||||
: textw(tags[sc][seltag[sc]].layout.symbol) + PAD;
|
||||
: (int)(textw(tags[s][seltag[s]].layout.symbol) + PAD);
|
||||
|
||||
barwin_resize(i->layout_button, w, i->geo.height);
|
||||
barwin_resize(i->layout_button, e->geo.width, e->geo.height);
|
||||
barwin_refresh_color(i->layout_button);
|
||||
|
||||
/* Split mode indicator; little rectangle at bottom-right */
|
||||
if(tags[sc][seltag[sc]].flags & SplitFlag)
|
||||
if(tags[s][seltag[s]].flags & SplitFlag)
|
||||
draw_rectangle(i->layout_button->dr,
|
||||
w - SPLIT_IND_S,
|
||||
i->geo.height - SPLIT_IND_S,
|
||||
e->geo.width - SPLIT_IND_S,
|
||||
e->geo.height - SPLIT_IND_S,
|
||||
SPLIT_IND_S, SPLIT_IND_S,
|
||||
getcolor(i->layout_button->fg));
|
||||
|
||||
if(tags[sc][seltag[sc]].layout.symbol)
|
||||
barwin_draw_text(i->layout_button, (PAD >> 1), FHINFOBAR, tags[sc][seltag[sc]].layout.symbol);
|
||||
if(tags[s][seltag[s]].layout.symbol)
|
||||
barwin_draw_text(i->layout_button, (PAD >> 1), FHINFOBAR, tags[s][seltag[s]].layout.symbol);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** Draw Infobar barwin (selbar / statustext)
|
||||
*\param i Infobar pointer
|
||||
*/
|
||||
void
|
||||
_infobar_draw(InfoBar *i)
|
||||
{
|
||||
barwin_refresh_color(i->bar);
|
||||
|
||||
infobar_draw_selbar(i);
|
||||
statustext_handle(i);
|
||||
|
||||
barwin_refresh(i->bar);
|
||||
|
||||
infobar_arrange_element(i);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -178,9 +281,8 @@ infobar_draw(InfoBar *i)
|
||||
{
|
||||
infobar_draw_taglist(i);
|
||||
infobar_draw_layout(i);
|
||||
infobar_draw_selbar(i);
|
||||
barwin_refresh_color(i->bar);
|
||||
statustext_handle(i->screen, i->statustext);
|
||||
|
||||
_infobar_draw(i);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -191,44 +293,51 @@ infobar_draw(InfoBar *i)
|
||||
void
|
||||
infobar_draw_selbar(InfoBar *i)
|
||||
{
|
||||
InfobarElem *e;
|
||||
char *str = NULL;
|
||||
int s, sc = i->screen;
|
||||
int sc = i->screen;
|
||||
bool f = False;
|
||||
|
||||
if(!conf.bars.selbar)
|
||||
return;
|
||||
|
||||
if(!sel || (sel && sel->screen != sc))
|
||||
{
|
||||
barwin_unmap(i->selbar);
|
||||
if(!strchr(i->elemorder, 's'))
|
||||
return;
|
||||
}
|
||||
else if(sel)
|
||||
barwin_map(i->selbar);
|
||||
|
||||
if(!sel || (sel && sel->screen != sc))
|
||||
return;
|
||||
|
||||
STAILQ_FOREACH(e, &i->elemhead, next)
|
||||
if(e->type == ElemSelbar)
|
||||
break;
|
||||
|
||||
str = sel->title;
|
||||
|
||||
/* Truncate string if too long */
|
||||
if(conf.selbar.maxlength >= 0 && sel && sel->title)
|
||||
{
|
||||
str = NULL;
|
||||
str = xcalloc(conf.selbar.maxlength + 4, sizeof(char));
|
||||
strncpy(str, sel->title, conf.selbar.maxlength);
|
||||
|
||||
if(strlen(sel->title) > (size_t)conf.selbar.maxlength)
|
||||
strcat(str, "...");
|
||||
|
||||
f = True;
|
||||
}
|
||||
|
||||
if((s = (textw(str ? str : sel->title) + PAD)) > i->selbar->geo.width)
|
||||
barwin_resize(i->selbar, s, i->geo.height - 2);
|
||||
XSetForeground(dpy, gc, conf.selbar.bg);
|
||||
XFillRectangle(dpy, i->bar->dr, gc,
|
||||
e->geo.x,
|
||||
e->geo.y,
|
||||
(e->geo.width = textw(str) + PAD),
|
||||
e->geo.height);
|
||||
draw_text(i->bar->dr, e->geo.x, FHINFOBAR, conf.selbar.fg, str);
|
||||
|
||||
barwin_move(i->selbar,
|
||||
((conf.layout_placement)
|
||||
? (i->tags_board->geo.x + i->tags_board->geo.width + (PAD >> 1))
|
||||
: (i->layout_button->geo.x + i->layout_button->geo.width + (PAD >> 1))), 1);
|
||||
if(f)
|
||||
free(str);
|
||||
|
||||
barwin_refresh_color(i->selbar);
|
||||
barwin_draw_text(i->selbar, (PAD >> 1), FHINFOBAR - 1, ((str) ? str : sel->title));
|
||||
|
||||
barwin_refresh(i->selbar);
|
||||
|
||||
free(str);
|
||||
i->selbar_geo = e->geo;
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -239,21 +348,23 @@ infobar_draw_selbar(InfoBar *i)
|
||||
void
|
||||
infobar_draw_taglist(InfoBar *i)
|
||||
{
|
||||
int j, x, sc = i->screen;
|
||||
Client *c = NULL;
|
||||
InfobarElem *e;
|
||||
Client *c;
|
||||
int j = 1, x = 0, sc = i->screen;
|
||||
uint occupied = 0;
|
||||
|
||||
if(conf.layout_placement)
|
||||
barwin_move(i->tags_board,
|
||||
((conf.layout_button_width > 0)
|
||||
? (uint)conf.layout_button_width
|
||||
: (textw(tags[sc][seltag[sc]].layout.symbol) + PAD)) + (PAD >> 1), 0);
|
||||
if(!strchr(i->elemorder, 't'))
|
||||
return;
|
||||
|
||||
for(c = clients; c; c = c->next)
|
||||
STAILQ_FOREACH(e, &i->elemhead, next)
|
||||
if(e->type == ElemTag)
|
||||
break;
|
||||
|
||||
SLIST_FOREACH(c, &clients, next)
|
||||
if(c->screen == sc)
|
||||
occupied |= TagFlag(c->tag);
|
||||
|
||||
for(j = 1, x = 0; j < conf.ntag[sc] + 1; ++j)
|
||||
for(; j < conf.ntag[sc] + 1; ++j)
|
||||
{
|
||||
/* Autohide tag feature */
|
||||
if(conf.tagautohide)
|
||||
@@ -266,7 +377,7 @@ infobar_draw_taglist(InfoBar *i)
|
||||
|
||||
barwin_map(i->tags[j]);
|
||||
barwin_move(i->tags[j], x, 0);
|
||||
barwin_resize(i->tags_board, (x += i->tags[j]->geo.width), i->geo.height);
|
||||
barwin_resize(i->tags_board, (e->geo.width = (x += i->tags[j]->geo.width)), e->geo.height);
|
||||
}
|
||||
|
||||
if(tags[sc][j].flags & TagUrgentFlag)
|
||||
@@ -335,6 +446,7 @@ infobar_update_taglist(InfoBar *i)
|
||||
void
|
||||
infobar_destroy(void)
|
||||
{
|
||||
InfobarElem *e;
|
||||
int sc, i;
|
||||
|
||||
for(sc = 0; sc < screen_count(); ++sc)
|
||||
@@ -350,9 +462,17 @@ infobar_destroy(void)
|
||||
|
||||
barwin_delete_subwin(infobar[sc].tags_board);
|
||||
barwin_delete(infobar[sc].tags_board);
|
||||
barwin_delete(infobar[sc].selbar);
|
||||
barwin_delete_subwin(infobar[sc].bar);
|
||||
barwin_delete(infobar[sc].bar);
|
||||
|
||||
/* Free elements */
|
||||
while(!STAILQ_EMPTY(&infobar[sc].elemhead))
|
||||
{
|
||||
e = STAILQ_FIRST(&infobar[sc].elemhead);
|
||||
STAILQ_REMOVE_HEAD(&infobar[sc].elemhead, next);
|
||||
free(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -368,28 +488,27 @@ infobar_set_position(int pos)
|
||||
|
||||
switch(pos)
|
||||
{
|
||||
case IB_Hide:
|
||||
sgeo[selscreen].y = spgeo[selscreen].y + TBARH;
|
||||
sgeo[selscreen].height = spgeo[selscreen].height - TBARH;
|
||||
infobar[selscreen].geo.y = (-(infobar[selscreen].geo.height) << 1);
|
||||
break;
|
||||
case IB_Bottom:
|
||||
sgeo[selscreen].y = spgeo[selscreen].y + TBARH;
|
||||
sgeo[selscreen].height = spgeo[selscreen].height - INFOBARH - TBARH;
|
||||
infobar[selscreen].geo.y = spgeo[selscreen].y + sgeo[selscreen].height + TBARH;
|
||||
break;
|
||||
default:
|
||||
case IB_Top:
|
||||
sgeo[selscreen].y = spgeo[selscreen].y + INFOBARH + TBARH;
|
||||
sgeo[selscreen].height = spgeo[selscreen].height - INFOBARH - TBARH;
|
||||
infobar[selscreen].geo.y = spgeo[selscreen].y;
|
||||
break;
|
||||
case IB_Hide:
|
||||
sgeo[selscreen].y = spgeo[selscreen].y + TBARH;
|
||||
sgeo[selscreen].height = spgeo[selscreen].height - TBARH;
|
||||
infobar[selscreen].geo.y = (-(infobar[selscreen].geo.height) << 1);
|
||||
break;
|
||||
case IB_Bottom:
|
||||
sgeo[selscreen].y = spgeo[selscreen].y + TBARH;
|
||||
sgeo[selscreen].height = spgeo[selscreen].height - INFOBARH - TBARH;
|
||||
infobar[selscreen].geo.y = spgeo[selscreen].y + sgeo[selscreen].height + TBARH;
|
||||
break;
|
||||
default:
|
||||
case IB_Top:
|
||||
sgeo[selscreen].y = spgeo[selscreen].y + INFOBARH + TBARH;
|
||||
sgeo[selscreen].height = spgeo[selscreen].height - INFOBARH - TBARH;
|
||||
infobar[selscreen].geo.y = spgeo[selscreen].y;
|
||||
break;
|
||||
}
|
||||
|
||||
tags[selscreen][seltag[selscreen]].barpos = pos;
|
||||
|
||||
barwin_move(infobar[selscreen].bar, sgeo[selscreen].x - BORDH, infobar[selscreen].geo.y);
|
||||
infobar_draw(&infobar[selscreen]);
|
||||
arrange(selscreen, True);
|
||||
|
||||
return;
|
||||
|
||||
44
src/init.c
44
src/init.c
@@ -196,48 +196,17 @@ init_root(void)
|
||||
return;
|
||||
}
|
||||
|
||||
/** Init statustext shell script
|
||||
*/
|
||||
static void
|
||||
init_status(void)
|
||||
{
|
||||
struct stat st;
|
||||
char *home;
|
||||
|
||||
conf.status_pid = -1;
|
||||
estatus = False;
|
||||
|
||||
if(!conf.status_path)
|
||||
{
|
||||
if(!(home = getenv("HOME")))
|
||||
{
|
||||
warnx("HOME not set, can't launch status.sh");
|
||||
return;
|
||||
}
|
||||
|
||||
conf.status_path = zmalloc(strlen(home) + strlen(DEF_STATUS) + 2);
|
||||
sprintf(conf.status_path, "%s/"DEF_STATUS, home);
|
||||
}
|
||||
|
||||
if (stat(patht(conf.status_path), &st) == -1)
|
||||
{
|
||||
warn("%s", patht(conf.status_path));
|
||||
return;
|
||||
}
|
||||
|
||||
if(st.st_size && st.st_mode & S_IXUSR)
|
||||
estatus = True;
|
||||
else
|
||||
warnx("status file specified in configuratin (status_path) or present in wmfs directory can't be executed, try 'chmod +x %s'.", patht(conf.status_path));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** Init WMFS
|
||||
*/
|
||||
void
|
||||
init(void)
|
||||
{
|
||||
/* Init lists heads */
|
||||
SLIST_INIT(&bwhead);
|
||||
SLIST_INIT(&smhead);
|
||||
SLIST_INIT(&clients);
|
||||
SLIST_INIT(&trayicons);
|
||||
|
||||
/* First init */
|
||||
ewmh_init_hints();
|
||||
init_conf();
|
||||
@@ -250,7 +219,6 @@ init(void)
|
||||
event_make_array();
|
||||
infobar_init();
|
||||
systray_acquire();
|
||||
init_status();
|
||||
ewmh_update_current_tag_prop();
|
||||
grabkeys();
|
||||
|
||||
|
||||
@@ -189,16 +189,17 @@ launcher_execute(Launcher *launcher)
|
||||
char buf[512] = { 0 };
|
||||
char tmpbuf[512] = { 0 };
|
||||
char *complete;
|
||||
int i, pos = 0, histpos = 0, x, w;
|
||||
int i, pos = 0, histpos = 0, w, x = 0;
|
||||
int tabhits = 0;
|
||||
KeySym ks;
|
||||
XEvent ev;
|
||||
InfobarElem *e;
|
||||
|
||||
screen_get_sel();
|
||||
|
||||
x = (conf.layout_placement)
|
||||
? (infobar[selscreen].tags_board->geo.x + infobar[selscreen].tags_board->geo.width)
|
||||
: (infobar[selscreen].layout_button->geo.x + infobar[selscreen].layout_button->geo.width);
|
||||
STAILQ_FOREACH(e, &infobar[selscreen].elemhead, next)
|
||||
if(x < (e->geo.x + e->geo.width))
|
||||
x = e->geo.x + e->geo.width + PAD;
|
||||
|
||||
XGrabKeyboard(dpy, ROOT, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||
|
||||
|
||||
74
src/layout.c
74
src/layout.c
@@ -42,7 +42,7 @@ arrange(int screen, bool update_layout)
|
||||
if(screen < 0 || screen > screen_count() - 1)
|
||||
screen = screen_get_sel();
|
||||
|
||||
for(c = clients; c; c = c->next)
|
||||
SLIST_FOREACH(c, &clients, next)
|
||||
if(c->screen == screen)
|
||||
{
|
||||
if(!ishide(c, screen))
|
||||
@@ -87,7 +87,7 @@ freelayout(int screen)
|
||||
Client *c;
|
||||
(void)screen;
|
||||
|
||||
for(c = clients; c; c = c->next)
|
||||
SLIST_FOREACH(c, &clients, next)
|
||||
if(!ishide(c, selscreen)
|
||||
&& c->screen == screen
|
||||
&& !(c->flags & MaxFlag))
|
||||
@@ -108,12 +108,12 @@ void
|
||||
layoutswitch(bool b)
|
||||
{
|
||||
int i;
|
||||
Client *c;
|
||||
Client *c = SLIST_FIRST(&clients);
|
||||
|
||||
screen_get_sel();
|
||||
|
||||
if(tags[selscreen][seltag[selscreen]].layout.func == freelayout)
|
||||
for(c = clients; c && (c->tag != (uint)seltag[selscreen] && c->screen != selscreen); c = c->next)
|
||||
for(; c && (c->tag != seltag[selscreen] && c->screen != selscreen); c = SLIST_NEXT(c, next))
|
||||
{
|
||||
c->ogeo = c->geo;
|
||||
c->free_geo = c->geo;
|
||||
@@ -133,10 +133,12 @@ layoutswitch(bool b)
|
||||
}
|
||||
|
||||
ewmh_update_current_tag_prop();
|
||||
|
||||
tags[selscreen][seltag[selscreen]].flags |= CleanFactFlag;
|
||||
tags[selscreen][seltag[selscreen]].flags &= ~SplitFlag;
|
||||
|
||||
layout_func(selscreen, seltag[selscreen]);
|
||||
infobar_draw_layout(&infobar[selscreen]);
|
||||
infobar_draw(&infobar[selscreen]);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -173,9 +175,9 @@ uicb_layout_prev(uicb_t cmd)
|
||||
Client*
|
||||
tiled_client(int screen, Client *c)
|
||||
{
|
||||
for(;c && (c->flags & (MaxFlag | FreeFlag | FSSFlag | AboveFlag)
|
||||
for(; c && (c->flags & (MaxFlag | FreeFlag | FSSFlag | AboveFlag)
|
||||
|| c->screen != screen
|
||||
|| ishide(c, screen)); c = c->next);
|
||||
|| ishide(c, screen)); c = SLIST_NEXT(c, next));
|
||||
|
||||
if(c)
|
||||
c->flags |= FLayFlag;
|
||||
@@ -188,10 +190,10 @@ tiled_client(int screen, Client *c)
|
||||
void
|
||||
maxlayout(int screen)
|
||||
{
|
||||
Client *c;
|
||||
int i;
|
||||
Client *c = tiled_client(screen, SLIST_FIRST(&clients));
|
||||
int i = 0;
|
||||
|
||||
for(i = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++i)
|
||||
for(; c; c = tiled_client(screen, SLIST_NEXT(c, next)), ++i)
|
||||
{
|
||||
c->flags &= ~TileFlag;
|
||||
c->flags |= LMaxFlag;
|
||||
@@ -233,12 +235,12 @@ uicb_set_mwfact(uicb_t cmd)
|
||||
void
|
||||
uicb_set_nmaster(uicb_t cmd)
|
||||
{
|
||||
int nc, n = atoi(cmd);
|
||||
Client *c;
|
||||
int nc = 0, n = atoi(cmd);
|
||||
Client *c = tiled_client(selscreen, SLIST_FIRST(&clients));
|
||||
|
||||
screen_get_sel();
|
||||
|
||||
for(nc = 0, c = tiled_client(selscreen, clients); c; c = tiled_client(selscreen, c->next), ++nc);
|
||||
for(; c; c = tiled_client(selscreen, SLIST_NEXT(c, next)), ++nc);
|
||||
|
||||
if(!nc || tags[selscreen][seltag[selscreen]].nmaster + n == 0
|
||||
|| tags[selscreen][seltag[selscreen]].nmaster + n > nc)
|
||||
@@ -258,12 +260,12 @@ uicb_set_nmaster(uicb_t cmd)
|
||||
static void
|
||||
grid(int screen, bool horizontal)
|
||||
{
|
||||
Client *c;
|
||||
Client *c = tiled_client(screen, SLIST_FIRST(&clients));
|
||||
Geo sg = sgeo[screen];
|
||||
Geo cgeo = {sg.x, sg.y, 0, 0};
|
||||
unsigned int i, n, temp, cols, rows, cpcols = 0;
|
||||
unsigned int i = 0, n = 0, temp, cols, rows, cpcols = 0;
|
||||
|
||||
for(n = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++n);
|
||||
for(; c; c = tiled_client(screen, SLIST_NEXT(c, next)), ++n);
|
||||
CHECK((tags[screen][seltag[screen]].nclients = n));
|
||||
|
||||
for(rows = 0; rows <= (n >> 1); ++rows)
|
||||
@@ -281,7 +283,7 @@ grid(int screen, bool horizontal)
|
||||
rows = temp;
|
||||
}
|
||||
|
||||
for(i = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++i)
|
||||
for(c = tiled_client(screen, SLIST_FIRST(&clients)); c; c = tiled_client(screen, SLIST_NEXT(c, next)), ++i)
|
||||
{
|
||||
/* Set client property */
|
||||
c->flags &= ~(MaxFlag | LMaxFlag);
|
||||
@@ -327,13 +329,13 @@ grid(int screen, bool horizontal)
|
||||
static void
|
||||
multi_tile(int screen, Position type)
|
||||
{
|
||||
Client *c;
|
||||
Client *c = tiled_client(screen, SLIST_FIRST(&clients));
|
||||
Geo sg = sgeo[screen];
|
||||
Geo mastergeo = {sg.x, sg.y, 0, 0};
|
||||
Geo cgeo = {sg.x, sg.y, 0, 0};
|
||||
uint i, n, tilesize = 0, mwfact, nmaster = tags[screen][seltag[screen]].nmaster;
|
||||
int i = 0, n = 0, tilesize = 0, mwfact, nmaster = tags[screen][seltag[screen]].nmaster;
|
||||
|
||||
for(n = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++n);
|
||||
for(; c; c = tiled_client(screen, SLIST_NEXT(c, next)), ++n);
|
||||
CHECK((tags[screen][seltag[screen]].nclients = n));
|
||||
|
||||
/* FIX NMASTER */
|
||||
@@ -348,16 +350,16 @@ multi_tile(int screen, Position type)
|
||||
if(LDIR(type))
|
||||
{
|
||||
if(type == Left)
|
||||
mastergeo.x = (n <= nmaster) ? (uint)sg.x : (sg.x + sg.width) - mwfact - (BORDH << 1);
|
||||
mastergeo.width = (n <= nmaster) ? (uint)(sg.width - (BORDH << 1)) : mwfact;
|
||||
mastergeo.x = (n <= nmaster) ? sg.x : (sg.x + sg.width) - mwfact - (BORDH << 1);
|
||||
mastergeo.width = (n <= nmaster) ? (sg.width - (BORDH << 1)) : mwfact;
|
||||
mastergeo.height = (sg.height / nmaster) - BORDH;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(type == Top)
|
||||
mastergeo.y = (n <= nmaster) ? (uint)sg.y : sg.y + (sg.height - mwfact) - BORDH;
|
||||
mastergeo.y = (n <= nmaster) ? sg.y : sg.y + (sg.height - mwfact) - BORDH;
|
||||
mastergeo.width = (sg.width / nmaster) - (BORDH << 2);
|
||||
mastergeo.height = (n <= nmaster) ? (uint)(sg.height - BORDH) : mwfact;
|
||||
mastergeo.height = (n <= nmaster) ? (sg.height - BORDH) : mwfact;
|
||||
}
|
||||
/* TILED SIZE */
|
||||
if(n > nmaster)
|
||||
@@ -369,7 +371,7 @@ multi_tile(int screen, Position type)
|
||||
}
|
||||
|
||||
|
||||
for(i = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++i)
|
||||
for(c = tiled_client(screen, SLIST_FIRST(&clients)); c; c = tiled_client(screen, SLIST_NEXT(c, next)), ++i)
|
||||
{
|
||||
/* Set client property */
|
||||
c->flags &= ~(MaxFlag | LMaxFlag);
|
||||
@@ -459,19 +461,19 @@ multi_tile(int screen, Position type)
|
||||
static void
|
||||
mirror(int screen, bool horizontal)
|
||||
{
|
||||
Client *c;
|
||||
Client *c = tiled_client(screen, SLIST_FIRST(&clients));
|
||||
Geo sg = sgeo[screen];
|
||||
Geo mastergeo = {sg.x, sg.y, sg.width, sg.height};
|
||||
Geo cgeo = {sg.x, sg.y , sg.width, sg.height};
|
||||
Geo nextg[2];
|
||||
uint i, n, tilesize = 0, mwfact;
|
||||
uint nmaster = tags[screen][seltag[screen]].nmaster;
|
||||
int i = 0, n = 0, tilesize = 0, mwfact;
|
||||
int nmaster = tags[screen][seltag[screen]].nmaster;
|
||||
int pa, imp;
|
||||
bool isp = False;
|
||||
|
||||
memset(nextg, 0, sizeof(nextg));
|
||||
|
||||
for(n = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++n);
|
||||
for(; c; c = tiled_client(screen, SLIST_NEXT(c, next)), ++n);
|
||||
CHECK((tags[screen][seltag[screen]].nclients = n));
|
||||
|
||||
/* Fix nmaster */
|
||||
@@ -527,7 +529,7 @@ mirror(int screen, bool horizontal)
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++i)
|
||||
for(c = tiled_client(screen, SLIST_FIRST(&clients)); c; c = tiled_client(screen, SLIST_NEXT(c, next)), ++i)
|
||||
{
|
||||
/* Set client property */
|
||||
c->flags &= ~(MaxFlag | LMaxFlag);
|
||||
@@ -794,14 +796,14 @@ uicb_togglemax(uicb_t cmd)
|
||||
void
|
||||
uicb_toggle_resizehint(uicb_t cmd)
|
||||
{
|
||||
Client *c;
|
||||
Client *c = tiled_client(selscreen, SLIST_FIRST(&clients));
|
||||
|
||||
screen_get_sel();
|
||||
(void)cmd;
|
||||
|
||||
tags[selscreen][seltag[selscreen]].flags ^= ResizeHintFlag;
|
||||
|
||||
for(c = tiled_client(selscreen, clients); c; c = tiled_client(selscreen, c->next))
|
||||
for(; c; c = tiled_client(selscreen, SLIST_NEXT(c, next)))
|
||||
client_moveresize(c, c->geo, (tags[selscreen][seltag[selscreen]].flags & ResizeHintFlag));
|
||||
|
||||
return;
|
||||
@@ -822,10 +824,10 @@ uicb_toggle_abovefc(uicb_t cmd)
|
||||
|
||||
if(!(tags[selscreen][seltag[selscreen]].flags & AboveFCFlag))
|
||||
{
|
||||
for(c = clients; c; c = c->next)
|
||||
SLIST_FOREACH(c, &clients, next)
|
||||
if(c->flags & AboveFlag
|
||||
&& c->screen == selscreen
|
||||
&& c->tag == (uint)seltag[selscreen])
|
||||
&& c->tag == seltag[selscreen])
|
||||
{
|
||||
c->flags &= ~AboveFlag;
|
||||
break;
|
||||
@@ -877,8 +879,8 @@ layout_set_client_master(Client *c)
|
||||
if(!c || (c->flags & (HintFlag | FSSFlag)) || !(c->flags & TileFlag))
|
||||
return;
|
||||
|
||||
if(c == tiled_client(selscreen, clients))
|
||||
CHECK((c = tiled_client(selscreen, c->next)));
|
||||
if(c == tiled_client(selscreen, SLIST_FIRST(&clients)))
|
||||
CHECK((c = tiled_client(selscreen, SLIST_NEXT(c, next))));
|
||||
|
||||
client_detach(c);
|
||||
client_attach(c);
|
||||
|
||||
18
src/mouse.c
18
src/mouse.c
@@ -332,21 +332,21 @@ mouse_resize(Client *c)
|
||||
void
|
||||
mouse_grabbuttons(Client *c, bool focused)
|
||||
{
|
||||
size_t i;
|
||||
size_t i = 0;
|
||||
uint but[] = {Button1, Button2, Button3, Button4, Button5};
|
||||
|
||||
XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
|
||||
if(focused)
|
||||
for(i = 0; i < LEN(but); ++i)
|
||||
for(; i < LEN(but); ++i)
|
||||
{
|
||||
XGrabButton(dpy, but[i], conf.client.mod, c->win, False,
|
||||
ButtonMask, GrabModeAsync,GrabModeSync, None, None);
|
||||
XGrabButton(dpy, but[i], conf.client.mod|LockMask, c->win, False,
|
||||
ButtonMask, GrabModeAsync,GrabModeSync, None, None);
|
||||
XGrabButton(dpy, but[i], conf.client.mod|numlockmask, c->win, False,
|
||||
ButtonMask, GrabModeAsync,GrabModeSync, None, None);
|
||||
XGrabButton(dpy, but[i], conf.client.mod|LockMask|numlockmask, c->win, False,
|
||||
ButtonMask, GrabModeAsync,GrabModeSync, None, None);
|
||||
ButtonMask, GrabModeAsync, GrabModeSync, None, None);
|
||||
XGrabButton(dpy, but[i], conf.client.mod | LockMask, c->win, False,
|
||||
ButtonMask, GrabModeAsync, GrabModeSync, None, None);
|
||||
XGrabButton(dpy, but[i], conf.client.mod | numlockmask, c->win, False,
|
||||
ButtonMask, GrabModeAsync, GrabModeSync, None, None);
|
||||
XGrabButton(dpy, but[i], conf.client.mod | LockMask | numlockmask, c->win, False,
|
||||
ButtonMask, GrabModeAsync, GrabModeSync, None, None);
|
||||
}
|
||||
else
|
||||
XGrabButton(dpy, AnyButton, AnyModifier, c->win, False,
|
||||
|
||||
@@ -165,7 +165,7 @@ parse_keywords(const char *filename)
|
||||
bool error = False;
|
||||
|
||||
|
||||
if ((fd = open(filename, O_RDONLY)) == -1 || stat(filename, &st) == -1) {
|
||||
if (stat(filename, &st) == -1 || (fd = open(filename, O_RDONLY)) == -1) {
|
||||
warn("%s", filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#define PARSE_H
|
||||
|
||||
#include "wmfs.h"
|
||||
#include <sys/queue.h>
|
||||
|
||||
#define INCLUDE_CMD "@include"
|
||||
#define PARSE_MAX_LIST 32
|
||||
|
||||
11
src/screen.c
11
src/screen.c
@@ -38,9 +38,7 @@
|
||||
int
|
||||
screen_count(void)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
n = ScreenCount(dpy);
|
||||
int n = ScreenCount(dpy);
|
||||
|
||||
#ifdef HAVE_XINERAMA
|
||||
if(XineramaIsActive(dpy))
|
||||
@@ -106,11 +104,10 @@ screen_get_geo(int s)
|
||||
int
|
||||
screen_get_with_geo(int x, int y)
|
||||
{
|
||||
int i;
|
||||
int i = 0;
|
||||
|
||||
for(i = 0; i < screen_count(); ++i)
|
||||
if((x >= spgeo[i].x && x < spgeo[i].x + spgeo[i].width)
|
||||
&& y >= spgeo[i].y && y < spgeo[i].y + spgeo[i].height)
|
||||
for(; i < screen_count(); ++i)
|
||||
if(INAREA(x, y, spgeo[i]))
|
||||
return i;
|
||||
|
||||
return 0;
|
||||
|
||||
17
src/split.c
17
src/split.c
@@ -41,6 +41,7 @@
|
||||
void \
|
||||
uicb_split_move_##d(uicb_t cmd) \
|
||||
{ \
|
||||
(void)cmd; \
|
||||
CHECK(sel); \
|
||||
split_move_dir(sel, d); \
|
||||
}
|
||||
@@ -121,14 +122,13 @@ split_apply_current(int screen, int tag)
|
||||
static bool
|
||||
_split_check_row_dir(Client *c, Client *g, Position p)
|
||||
{
|
||||
int s, cs;
|
||||
Geo cgeo;
|
||||
Client *cc;
|
||||
int s = 0, cs;
|
||||
Geo cgeo = c->frame_geo;
|
||||
Client *cc = tiled_client(c->screen, SLIST_FIRST(&clients));
|
||||
|
||||
cs = (LDIR(p) ? g->frame_geo.height : g->frame_geo.width);
|
||||
|
||||
for(s = 0, cgeo = c->frame_geo, cc = tiled_client(c->screen, clients);
|
||||
cc; cc = tiled_client(c->screen, cc->next))
|
||||
for(; cc; cc = tiled_client(c->screen, SLIST_NEXT(cc, next)))
|
||||
if(CFACTOR_PARENTROW(cgeo, cc->frame_geo, RPOS(p))
|
||||
&& SPLIT_CHECK_ROW(cc->frame_geo, g->frame_geo, p))
|
||||
{
|
||||
@@ -197,8 +197,8 @@ split_arrange_closed(Client *ghost)
|
||||
for(p = Right; p < Center && !b; ++p)
|
||||
if((c = client_get_next_with_direction(ghost, p)) && _split_check_row_dir(c, ghost, p))
|
||||
{
|
||||
for(cgeo = c->frame_geo, cc = tiled_client(c->screen, clients);
|
||||
cc; cc = tiled_client(c->screen, cc->next))
|
||||
for(cgeo = c->frame_geo, cc = tiled_client(c->screen, SLIST_FIRST(&clients));
|
||||
cc; cc = tiled_client(c->screen, SLIST_NEXT(cc, next)))
|
||||
if(CFACTOR_PARENTROW(cgeo, cc->frame_geo, RPOS(p))
|
||||
&& SPLIT_CHECK_ROW(cc->frame_geo, ghost->frame_geo, p))
|
||||
{
|
||||
@@ -296,7 +296,8 @@ split_client_integrate(Client *c, Client *sc, int screen, int tag)
|
||||
|| sc->screen != screen || sc->tag != tag)
|
||||
{
|
||||
/* Looking for first client on wanted tag */
|
||||
for(b = False, sc = clients; sc; sc = sc->next)
|
||||
b = False;
|
||||
SLIST_FOREACH(sc, &clients, next)
|
||||
if(sc != c && sc->screen == screen && sc->tag == tag
|
||||
&& (sc->flags & TileFlag))
|
||||
{
|
||||
|
||||
115
src/status.c
115
src/status.c
@@ -35,6 +35,39 @@
|
||||
/* Systray width */
|
||||
static int sw = 0;
|
||||
|
||||
/** Parse dynamic mouse binds in str and insert it in linked list
|
||||
* --> \<block>[;;;;(button;func;cmd)]\ add a mouse bind on the block object
|
||||
*\param str String
|
||||
*\param area Area of clicking
|
||||
*\param infobar Infobar pointer
|
||||
*/
|
||||
void
|
||||
statustext_mouse(char *str, Geo area, InfoBar *infobar)
|
||||
{
|
||||
StatusMouse *sm = NULL;
|
||||
int i = 0, button = 1, n;
|
||||
char cmd[256] = { 0 };
|
||||
char func[64] = { 0 };
|
||||
|
||||
for(; i < (int)strlen(str); ++i, sm = NULL)
|
||||
if((n = sscanf(&str[i], "(%d;%64[^;];%256[^)])", &button, func, cmd) >= 2) && n < 4)
|
||||
{
|
||||
sm = zcalloc(sizeof(StatusMouse));
|
||||
sm->button = button;
|
||||
sm->func = name_to_func((char*)func, func_list);
|
||||
sm->cmd = xstrdup(cmd);
|
||||
sm->area = area;
|
||||
sm->infobar = infobar;
|
||||
|
||||
SLIST_INSERT_HEAD(&smhead, sm, next);
|
||||
|
||||
/* Jump to the end of the sequence */
|
||||
while(str[++i + 1] != ')');
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** Check rectangles blocks in str and draw it
|
||||
* --> \b[x;y;width;height;#color]\
|
||||
*\param ib Infobar pointer
|
||||
@@ -44,14 +77,20 @@ static void
|
||||
statustext_rectangle(InfoBar *ib, char *str)
|
||||
{
|
||||
StatusRec r;
|
||||
char as;
|
||||
int i, j, k;
|
||||
char as, mouse[512] = { 0 };
|
||||
int i = 0, j = 0, k, n;
|
||||
|
||||
for(i = j = 0; i < (int)strlen(str); ++i, ++j)
|
||||
if(sscanf(&str[i], "\\b[%d;%d;%d;%d;#%x]%c", &r.x, &r.y, &r.w, &r.h, &r.color, &as) == 6
|
||||
for(; i < (int)strlen(str); ++i, ++j)
|
||||
if(((n = sscanf(&str[i], "\\b[%d;%d;%d;%d;#%x]%c",
|
||||
&r.g.x, &r.g.y, &r.g.width, &r.g.height, &r.color, &as)) == 6
|
||||
|| (n = sscanf(&str[i], "\\b[%d;%d;%d;%d;#%x;%512[^]]]%c",
|
||||
&r.g.x, &r.g.y, &r.g.width, &r.g.height, &r.color, mouse, &as)) == 7)
|
||||
&& as == '\\')
|
||||
{
|
||||
draw_rectangle(ib->bar->dr, r.x - sw, r.y, r.w, r.h, r.color);
|
||||
draw_rectangle(ib->bar->dr, r.g.x - sw, r.g.y, r.g.width, r.g.height, r.color);
|
||||
|
||||
if(n == 7)
|
||||
statustext_mouse(mouse, r.g, ib);
|
||||
|
||||
for(++i, --j; str[i] != as || str[i - 1] != ']'; ++i);
|
||||
}
|
||||
@@ -121,15 +160,30 @@ static void
|
||||
statustext_text(InfoBar *ib, char *str)
|
||||
{
|
||||
StatusText s;
|
||||
char as;
|
||||
int i, j, k;
|
||||
Geo area;
|
||||
char as, mouse[512] = { 0 };
|
||||
int i = 0, j = 0, k, n;
|
||||
|
||||
for(i = j = 0; i < (int)strlen(str); ++i, ++j)
|
||||
if(sscanf(&str[i], "\\s[%d;%d;%7[^;];%512[^]]]%c", &s.x, &s.y, s.color, s.text, &as) == 5
|
||||
for(; i < (int)strlen(str); ++i, ++j)
|
||||
if(((n = sscanf(&str[i], "\\s[%d;%d;%7[^;];%512[^];]]%c",
|
||||
&s.x, &s.y, s.color, s.text, &as)) == 5
|
||||
|| (n = sscanf(&str[i], "\\s[%d;%d;%7[^;];%512[^;];%512[^]]]%c",
|
||||
&s.x, &s.y, s.color, s.text, mouse, &as)) == 6)
|
||||
&& as == '\\')
|
||||
{
|
||||
draw_text(ib->bar->dr, s.x - sw, s.y, s.color, s.text);
|
||||
|
||||
/* Etablish clickable area on text */
|
||||
if(n == 6)
|
||||
{
|
||||
area.height = font.height;
|
||||
area.width = textw(s.text);
|
||||
area.x = s.x - sw;
|
||||
area.y = s.y - area.height;
|
||||
|
||||
statustext_mouse(mouse, area, ib);
|
||||
}
|
||||
|
||||
for(++i, --j; str[i] != as || str[i - 1] != ']'; ++i);
|
||||
}
|
||||
else if(j != i)
|
||||
@@ -147,7 +201,7 @@ statustext_text(InfoBar *ib, char *str)
|
||||
*\param str String
|
||||
*/
|
||||
static void
|
||||
statustext_normal(int sc, InfoBar *ib, char *str)
|
||||
statustext_normal(InfoBar *ib, char *str)
|
||||
{
|
||||
char strwc[MAXSTATUS] = { 0 };
|
||||
char buf[MAXSTATUS] = { 0 };
|
||||
@@ -165,7 +219,7 @@ statustext_normal(int sc, InfoBar *ib, char *str)
|
||||
strwc[j] = str[i];
|
||||
|
||||
/* Draw normal text without any blocks */
|
||||
draw_text(ib->bar->dr, (sgeo[sc].width - SHADH) - (textw(strwc) + sw), FHINFOBAR, ib->bar->fg, strwc);
|
||||
draw_text(ib->bar->dr, (sgeo[ib->screen].width - SHADH) - (textw(strwc) + sw), FHINFOBAR, ib->bar->fg, strwc);
|
||||
|
||||
if(n)
|
||||
{
|
||||
@@ -180,12 +234,12 @@ statustext_normal(int sc, InfoBar *ib, char *str)
|
||||
for(j = 0, ++i; str[i] != '\\'; col[j++] = str[i++]);
|
||||
|
||||
/* Draw a rectangle with the bar color to draw the text properly */
|
||||
draw_rectangle(ib->bar->dr, (sgeo[sc].width - SHADH) - (tw + sw),
|
||||
0, INFOBARH - (sgeo[sc].width - SHADH) - tw,
|
||||
draw_rectangle(ib->bar->dr, (sgeo[ib->screen].width - SHADH) - (tw + sw),
|
||||
0, INFOBARH - (sgeo[ib->screen].width - SHADH) - tw,
|
||||
INFOBARH, conf.colors.bar);
|
||||
|
||||
/* Draw text with its color */
|
||||
draw_text(ib->bar->dr, (sgeo[sc].width - SHADH) - (tw + sw), FHINFOBAR, col, &buf[k]);
|
||||
draw_text(ib->bar->dr, (sgeo[ib->screen].width - SHADH) - (tw + sw), FHINFOBAR, col, &buf[k]);
|
||||
|
||||
strncpy(buf, strwc, sizeof(buf));
|
||||
++i;
|
||||
@@ -200,25 +254,25 @@ statustext_normal(int sc, InfoBar *ib, char *str)
|
||||
*\param str String
|
||||
*/
|
||||
void
|
||||
statustext_handle(int sc, char *str)
|
||||
statustext_handle(InfoBar *ib)
|
||||
{
|
||||
InfoBar *ib = &infobar[sc];
|
||||
char *lastst;
|
||||
int i;
|
||||
char *str;
|
||||
StatusMouse *sm;
|
||||
|
||||
/* If the str == the current statustext, return (not needed) */
|
||||
if(!str)
|
||||
return;
|
||||
/* Free previous linked list of mouse bind */
|
||||
if(!ib->screen)
|
||||
while(!SLIST_EMPTY(&smhead))
|
||||
{
|
||||
sm = SLIST_FIRST(&smhead);
|
||||
SLIST_REMOVE_HEAD(&smhead, next);
|
||||
free((void*)sm->cmd);
|
||||
free(sm);
|
||||
}
|
||||
|
||||
if(sc == conf.systray.screen)
|
||||
if(ib->screen == conf.systray.screen)
|
||||
sw = systray_get_width();
|
||||
|
||||
barwin_refresh_color(ib->bar);
|
||||
|
||||
/* save last status text address (for free at the end) */
|
||||
lastst = ib->statustext;
|
||||
|
||||
ib->statustext = xstrdup(str);
|
||||
str = xstrdup(ib->statustext);
|
||||
|
||||
/* Store rectangles, located text & images properties. */
|
||||
statustext_rectangle(ib, str);
|
||||
@@ -226,12 +280,11 @@ statustext_handle(int sc, char *str)
|
||||
statustext_text(ib, str);
|
||||
|
||||
/* Draw normal text (and possibly colored with \#color\ blocks) */
|
||||
statustext_normal(sc, ib, str);
|
||||
statustext_normal(ib, str);
|
||||
|
||||
sw = 0;
|
||||
barwin_refresh(ib->bar);
|
||||
|
||||
free(lastst);
|
||||
free(str);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -112,10 +112,10 @@ enum { TagSel, TagTransfert, TagAdd, TagNext, TagPrev, TagActionLast };
|
||||
/* Menu align */
|
||||
enum { MA_Center = 0, MA_Left = 1, MA_Right = 2 };
|
||||
|
||||
/* Infobar position */
|
||||
/* Infobar position / elements */
|
||||
enum { IB_Hide = 0, IB_Bottom = 1, IB_Top = 2 };
|
||||
|
||||
typedef enum { Right = 0, Left, Top, Bottom, Center, PositionLast } Position;
|
||||
typedef enum { ElemTag, ElemLayout, ElemSelbar } IbElemType;
|
||||
|
||||
/* Ewmh hints list */
|
||||
enum
|
||||
@@ -158,7 +158,6 @@ enum
|
||||
/* WMFS HINTS */
|
||||
wmfs_running,
|
||||
wmfs_update_hints,
|
||||
wmfs_update_status,
|
||||
wmfs_current_tag,
|
||||
wmfs_current_screen,
|
||||
wmfs_current_layout,
|
||||
@@ -185,7 +184,7 @@ typedef struct
|
||||
* BarWindow Structure
|
||||
* (titlebar, infobar..)
|
||||
*/
|
||||
typedef struct
|
||||
typedef struct BarWindow
|
||||
{
|
||||
Window win;
|
||||
Drawable dr;
|
||||
@@ -202,16 +201,16 @@ typedef struct
|
||||
uint stipple_color;
|
||||
Geo geo;
|
||||
uint flags;
|
||||
SLIST_ENTRY(BarWindow) next;
|
||||
} BarWindow;
|
||||
|
||||
/* Client Structure. */
|
||||
typedef struct Client Client;
|
||||
struct Client
|
||||
typedef struct Client
|
||||
{
|
||||
/* Client title */
|
||||
char *title;
|
||||
/* Tag num */
|
||||
uint tag;
|
||||
int tag;
|
||||
int focusontag;
|
||||
/* Screen */
|
||||
int screen;
|
||||
@@ -245,10 +244,9 @@ struct Client
|
||||
} colors;
|
||||
/* Client Information by flags */
|
||||
uint flags;
|
||||
/* Struct in chains */
|
||||
Client *next;
|
||||
Client *prev;
|
||||
};
|
||||
/* Simply-linked list */
|
||||
SLIST_ENTRY(Client) next;
|
||||
} Client;
|
||||
|
||||
/* Keybind Structure */
|
||||
typedef struct
|
||||
@@ -269,13 +267,23 @@ typedef struct
|
||||
uicb_t cmd;
|
||||
} MouseBinding;
|
||||
|
||||
/* InfoBar elements */
|
||||
typedef struct InfobarElem
|
||||
{
|
||||
IbElemType type;
|
||||
Geo geo;
|
||||
STAILQ_ENTRY(InfobarElem) next;
|
||||
} InfobarElem;
|
||||
|
||||
/* InfoBar Struct */
|
||||
typedef struct
|
||||
{
|
||||
BarWindow *bar, *selbar;
|
||||
BarWindow *layout_button;
|
||||
BarWindow *tags_board, *tags[MAXTAG];
|
||||
Geo geo;
|
||||
BarWindow *layout_button;
|
||||
BarWindow *bar;
|
||||
STAILQ_HEAD(, InfobarElem) elemhead;
|
||||
char *elemorder;
|
||||
Geo geo, selbar_geo;
|
||||
int screen, position;
|
||||
char *statustext;
|
||||
bool need_update;
|
||||
@@ -293,13 +301,12 @@ typedef struct
|
||||
} Layout;
|
||||
|
||||
/* Systray Structure */
|
||||
typedef struct Systray Systray;
|
||||
struct Systray
|
||||
typedef struct Systray
|
||||
{
|
||||
Window win;
|
||||
Geo geo;
|
||||
Systray *next, *prev;
|
||||
};
|
||||
SLIST_ENTRY(Systray) next;
|
||||
} Systray;
|
||||
|
||||
/* Tag Structure */
|
||||
typedef struct
|
||||
@@ -386,6 +393,7 @@ typedef struct
|
||||
char *class;
|
||||
char *instance;
|
||||
char *role;
|
||||
char *name;
|
||||
int screen;
|
||||
int tag;
|
||||
bool free;
|
||||
@@ -413,9 +421,6 @@ typedef struct
|
||||
bool tagnamecount;
|
||||
Tag default_tag;
|
||||
uint pad;
|
||||
int status_timing;
|
||||
char *status_path;
|
||||
pid_t status_pid;
|
||||
char *autostart_path;
|
||||
char *autostart_command;
|
||||
struct
|
||||
@@ -446,6 +451,7 @@ typedef struct
|
||||
MouseBinding *mouse;
|
||||
int nmouse;
|
||||
bool selbar;
|
||||
char *element_order;
|
||||
} bars;
|
||||
struct
|
||||
{
|
||||
@@ -521,7 +527,6 @@ typedef struct
|
||||
bool client_auto_center;
|
||||
bool client_tile_raise;
|
||||
bool layout_system; /* Switch: False, Menu: True. */
|
||||
bool layout_placement; /* Right (normal): False, Left: True. */
|
||||
bool keep_layout_geo;
|
||||
bool cfactor_enable_split;
|
||||
char *tag_expose_name;
|
||||
@@ -547,7 +552,7 @@ typedef struct
|
||||
/* status.c util struct */
|
||||
typedef struct
|
||||
{
|
||||
int x, y, w, h;
|
||||
Geo g;
|
||||
uint color;
|
||||
} StatusRec;
|
||||
|
||||
@@ -565,6 +570,16 @@ typedef struct
|
||||
char text[512];
|
||||
} StatusText;
|
||||
|
||||
typedef struct StatusMouse
|
||||
{
|
||||
Geo area;
|
||||
InfoBar *infobar;
|
||||
uint button;
|
||||
void (*func)(uicb_t);
|
||||
uicb_t cmd;
|
||||
SLIST_ENTRY(StatusMouse) next;
|
||||
} StatusMouse;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int x, y, w, h;
|
||||
|
||||
@@ -98,11 +98,7 @@ systray_add(Window win)
|
||||
ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0, traywin, 0);
|
||||
|
||||
/* Attach */
|
||||
if(trayicons)
|
||||
trayicons->prev = s;
|
||||
|
||||
s->next = trayicons;
|
||||
trayicons = s;
|
||||
SLIST_INSERT_HEAD(&trayicons, s, next);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -110,14 +106,10 @@ systray_add(Window win)
|
||||
void
|
||||
systray_del(Systray *s)
|
||||
{
|
||||
Systray **ss;
|
||||
|
||||
if(!conf.systray.active)
|
||||
return;
|
||||
|
||||
for(ss = &trayicons; *ss && *ss != s; ss = &(*ss)->next);
|
||||
*ss = s->next;
|
||||
|
||||
SLIST_REMOVE(&trayicons, s, Systray, next);
|
||||
free(s);
|
||||
|
||||
return;
|
||||
@@ -158,10 +150,13 @@ systray_freeicons(void)
|
||||
if(!conf.systray.active)
|
||||
return;
|
||||
|
||||
for(i = trayicons; i; i = i->next)
|
||||
while(!SLIST_EMPTY(&trayicons))
|
||||
{
|
||||
i = SLIST_FIRST(&trayicons);
|
||||
SLIST_REMOVE_HEAD(&trayicons, next);
|
||||
|
||||
XUnmapWindow(dpy, i->win);
|
||||
XReparentWindow(dpy, i->win, ROOT, 0, 0);
|
||||
XReparentWindow(dpy, i->win, ROOT, 0, 0);
|
||||
free(i);
|
||||
}
|
||||
|
||||
@@ -181,7 +176,7 @@ systray_find(Window win)
|
||||
if(!conf.systray.active)
|
||||
return NULL;
|
||||
|
||||
for(i = trayicons; i; i = i->next)
|
||||
SLIST_FOREACH(i, &trayicons, next)
|
||||
if(i->win == win)
|
||||
return i;
|
||||
|
||||
@@ -197,7 +192,7 @@ systray_get_width(void)
|
||||
if(!conf.systray.active)
|
||||
return 0;
|
||||
|
||||
for(i = trayicons; i; i = i->next)
|
||||
SLIST_FOREACH(i, &trayicons, next)
|
||||
w += i->geo.width + conf.systray.spacing + 1;
|
||||
|
||||
return w;
|
||||
@@ -212,13 +207,13 @@ systray_update(void)
|
||||
if(!conf.systray.active)
|
||||
return;
|
||||
|
||||
if(!trayicons)
|
||||
if(!SLIST_FIRST(&trayicons))
|
||||
{
|
||||
XMoveResizeWindow(dpy, traywin, infobar[conf.systray.screen].bar->geo.width - 1, 0, 1, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
for(i = trayicons; i; i = i->next)
|
||||
SLIST_FOREACH(i, &trayicons, next)
|
||||
{
|
||||
XMapWindow(dpy, i->win);
|
||||
|
||||
|
||||
40
src/tag.c
40
src/tag.c
@@ -95,13 +95,18 @@ tag_set(int tag)
|
||||
}
|
||||
|
||||
/* Check for ignore_tag clients */
|
||||
for(c = clients; c; c = c->next)
|
||||
SLIST_FOREACH(c, &clients, next)
|
||||
if(c->tag == MAXTAG + 1 && c->screen == selscreen)
|
||||
{
|
||||
al = True;
|
||||
break;
|
||||
}
|
||||
|
||||
/* To focus selected client of the via focusontag option */
|
||||
SLIST_FOREACH(c, &clients, next)
|
||||
if(c->focusontag == tag && c->screen == selscreen)
|
||||
break;
|
||||
|
||||
arrange(selscreen, al);
|
||||
|
||||
if(tags[selscreen][tag].flags & RequestUpdateFlag)
|
||||
@@ -110,15 +115,10 @@ tag_set(int tag)
|
||||
tags[selscreen][tag].flags &= ~RequestUpdateFlag;
|
||||
}
|
||||
|
||||
/* To focus selected client of the via focusontag option */
|
||||
for(c = clients; c; c = c->next)
|
||||
if(c->focusontag == tag && c->screen == selscreen)
|
||||
break;
|
||||
|
||||
/* No focusontag option found on any client, try to find the first of the tag */
|
||||
if(!c)
|
||||
for(c = clients; c; c = c->next)
|
||||
if(c->tag == (uint)seltag[selscreen] && c->screen == selscreen)
|
||||
SLIST_FOREACH(c, &clients, next)
|
||||
if(c->tag == seltag[selscreen] && c->screen == selscreen)
|
||||
break;
|
||||
|
||||
client_focus((c) ? c : NULL);
|
||||
@@ -237,7 +237,7 @@ uicb_tag_next_visible(uicb_t cmd)
|
||||
return;
|
||||
}
|
||||
|
||||
for(c = clients; c; c = c->next)
|
||||
SLIST_FOREACH(c, &clients, next)
|
||||
if(c->screen == selscreen)
|
||||
occupied |= TagFlag(c->tag);
|
||||
|
||||
@@ -278,7 +278,7 @@ uicb_tag_prev_visible(uicb_t cmd)
|
||||
return;
|
||||
}
|
||||
|
||||
for(c = clients; c; c = c->next)
|
||||
SLIST_FOREACH(c, &clients, next)
|
||||
if(c->screen == selscreen)
|
||||
occupied |= TagFlag(c->tag);
|
||||
|
||||
@@ -351,11 +351,11 @@ tag_swap(int s, int t1, int t2)
|
||||
tags[s][t1] = tags[s][t2];
|
||||
tags[s][t2] = t;
|
||||
|
||||
for(c = clients; c; c = c->next)
|
||||
SLIST_FOREACH(c, &clients, next)
|
||||
{
|
||||
if(c->screen == s && c->tag == (uint)t1)
|
||||
if(c->screen == s && c->tag == t1)
|
||||
c->tag = t2;
|
||||
else if(c->screen == s && c->tag == (uint)t2)
|
||||
else if(c->screen == s && c->tag == t2)
|
||||
c->tag = t1;
|
||||
}
|
||||
|
||||
@@ -477,7 +477,7 @@ uicb_tag_urgent(uicb_t cmd)
|
||||
(void)cmd;
|
||||
|
||||
/* Check if there is a urgent client */
|
||||
for(c = clients; c; c = c->next)
|
||||
SLIST_FOREACH(c, &clients, next)
|
||||
if(c->flags & UrgentFlag)
|
||||
{
|
||||
screen_set_sel(c->screen);
|
||||
@@ -651,15 +651,15 @@ tag_delete(int s, int tag)
|
||||
{
|
||||
Tag t;
|
||||
Client *c;
|
||||
size_t i;
|
||||
int i;
|
||||
|
||||
memset(&t, 0, sizeof(t));
|
||||
|
||||
if(tag < 0 || tag > conf.ntag[s] || conf.ntag[s] == 1)
|
||||
return;
|
||||
|
||||
for(c = clients; c; c = c->next)
|
||||
if(c->screen == s && c->tag == (uint)tag)
|
||||
SLIST_FOREACH(c, &clients, next)
|
||||
if(c->screen == s && c->tag ==tag)
|
||||
{
|
||||
warnx("Client(s) present in this tag, can't delete it");
|
||||
|
||||
@@ -671,10 +671,10 @@ tag_delete(int s, int tag)
|
||||
tags[s][tag] = t;
|
||||
infobar[s].tags[tag] = NULL;
|
||||
|
||||
for(i = tag; i < (size_t)conf.ntag[s] + 1; ++i)
|
||||
for(i = tag; i < conf.ntag[s] + 1; ++i)
|
||||
{
|
||||
/* Set clients tag because of shift */
|
||||
for(c = clients; c; c = c->next)
|
||||
SLIST_FOREACH(c, &clients, next)
|
||||
if(c->screen == s && c->tag == i + 1)
|
||||
c->tag = i;
|
||||
|
||||
@@ -751,7 +751,7 @@ uicb_tag_toggle_expose(uicb_t cmd)
|
||||
{
|
||||
if(strcmp(tags[selscreen][i].name, conf.tag_expose_name) == 0)
|
||||
{
|
||||
if(clients && sel->tag)
|
||||
if(SLIST_FIRST(&clients) && sel->tag)
|
||||
tag_set(sel->tag);
|
||||
|
||||
tag_delete(selscreen, i);
|
||||
|
||||
23
src/util.c
23
src/util.c
@@ -279,29 +279,6 @@ uicb_spawn(uicb_t cmd)
|
||||
return;
|
||||
}
|
||||
|
||||
char*
|
||||
clean_value(char *str)
|
||||
{
|
||||
int i;
|
||||
char c, *p;
|
||||
|
||||
if(!str || !(p = xstrdup(str)))
|
||||
return NULL;
|
||||
|
||||
/* Remove useless spaces */
|
||||
for(; *p == ' '; ++p);
|
||||
for(; *(p + strlen(p) - 1) == ' '; *(p + strlen(p) - 1) = '\0');
|
||||
|
||||
/* For string delimiter (" or ') */
|
||||
if(((c = *p) == '"' || (c = *p) == '\'') && strchr(p + 1, c))
|
||||
{
|
||||
for(++p, i = 0; p[i] && p[i] != c; ++i);
|
||||
p[i] = '\0';
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/* To use ~/ shortcut.. */
|
||||
char*
|
||||
patht(char *path)
|
||||
|
||||
105
src/wmfs.c
105
src/wmfs.c
@@ -33,7 +33,6 @@
|
||||
#include "wmfs.h"
|
||||
|
||||
static volatile bool exiting = False, sig_chld = False;
|
||||
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
int
|
||||
errorhandler(Display *d, XErrorEvent *event)
|
||||
@@ -80,17 +79,19 @@ errorhandlerdummy(Display *d, XErrorEvent *event)
|
||||
void
|
||||
quit(void)
|
||||
{
|
||||
Client *c;
|
||||
size_t i, len;
|
||||
|
||||
/* Set the silent error handler */
|
||||
XSetErrorHandler(errorhandlerdummy);
|
||||
|
||||
/* Unmanage all clients */
|
||||
for(c = clients; c; c = c->next)
|
||||
while(!SLIST_EMPTY(&clients))
|
||||
{
|
||||
Client *c = SLIST_FIRST(&clients);
|
||||
client_unhide(c);
|
||||
XReparentWindow(dpy, c->win, ROOT, c->geo.x, c->geo.y);
|
||||
free(c);
|
||||
SLIST_REMOVE_HEAD(&clients, next);
|
||||
}
|
||||
|
||||
free(tags);
|
||||
@@ -110,6 +111,10 @@ quit(void)
|
||||
XFreeGC(dpy, gc_stipple);
|
||||
infobar_destroy();
|
||||
|
||||
/* BarWindows */
|
||||
while(!SLIST_EMPTY(&bwhead))
|
||||
SLIST_REMOVE_HEAD(&bwhead, next);
|
||||
|
||||
free(sgeo);
|
||||
free(spgeo);
|
||||
free(infobar);
|
||||
@@ -143,78 +148,24 @@ quit(void)
|
||||
|
||||
free(event_handle);
|
||||
|
||||
/* kill status script */
|
||||
if (conf.status_pid != (pid_t)-1)
|
||||
kill(conf.status_pid, SIGTERM);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
wait_childs_and_status(void)
|
||||
{
|
||||
int pid;
|
||||
|
||||
pthread_mutex_lock(&mtx);
|
||||
if (sig_chld) {
|
||||
while ((pid = waitpid(-1, NULL, WNOHANG)) > 0)
|
||||
if (pid == conf.status_pid)
|
||||
conf.status_pid = -1;
|
||||
sig_chld = False;
|
||||
}
|
||||
pthread_mutex_unlock(&mtx);
|
||||
}
|
||||
|
||||
static void *
|
||||
thread_status(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
int left = conf.status_timing;
|
||||
|
||||
pthread_detach(pthread_self());
|
||||
|
||||
do
|
||||
{
|
||||
wait_childs_and_status();
|
||||
|
||||
pthread_mutex_lock(&mtx);
|
||||
if (conf.status_pid == -1)
|
||||
conf.status_pid = spawn(conf.status_path);
|
||||
pthread_mutex_unlock(&mtx);
|
||||
|
||||
while ((left = sleep(left)) > 0);
|
||||
left = conf.status_timing;
|
||||
|
||||
} while (!exiting);
|
||||
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
/** WMFS main loop.
|
||||
*/
|
||||
static void
|
||||
mainloop(void)
|
||||
{
|
||||
XEvent ev;
|
||||
pthread_t th_status;
|
||||
|
||||
if(estatus && !conf.status_timing)
|
||||
conf.status_pid = spawn(conf.status_path);
|
||||
else if(estatus && pthread_create(&th_status, NULL, thread_status, NULL) != 0)
|
||||
{
|
||||
warnx("pthread_create");
|
||||
estatus = False;
|
||||
}
|
||||
|
||||
while(!exiting && !XNextEvent(dpy, &ev))
|
||||
{
|
||||
while(!exiting && !XNextEvent(dpy, &ev)) {
|
||||
if (sig_chld) {
|
||||
while(waitpid(-1, NULL, WNOHANG) > 0);
|
||||
sig_chld = False;
|
||||
}
|
||||
HANDLE_EVENT(&ev);
|
||||
wait_childs_and_status();
|
||||
}
|
||||
|
||||
if(estatus)
|
||||
pthread_join(th_status, NULL);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -290,9 +241,9 @@ scan(void)
|
||||
}
|
||||
|
||||
/* Set update layout request */
|
||||
for(c = clients; c; c = c->next)
|
||||
SLIST_FOREACH(c, &clients, next)
|
||||
{
|
||||
if(c->tag > (uint)conf.ntag[c->screen])
|
||||
if(c->tag > conf.ntag[c->screen])
|
||||
c->tag = conf.ntag[c->screen];
|
||||
tags[c->screen][c->tag].flags |= RequestUpdateFlag;
|
||||
}
|
||||
@@ -415,19 +366,6 @@ set_statustext(int s, char *str)
|
||||
return;
|
||||
}
|
||||
|
||||
/** Update status script by ewmh hint
|
||||
*/
|
||||
static void
|
||||
update_status(void)
|
||||
{
|
||||
if(!check_wmfs_running())
|
||||
return;
|
||||
|
||||
ewmh_send_message(ROOT, ROOT, "_WMFS_UPDATE_STATUS", 0, 0, 0, 0, True);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** Signal handle function
|
||||
*/
|
||||
static void
|
||||
@@ -456,7 +394,7 @@ int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
char *ol = "csS";
|
||||
char *ol = "cs";
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
struct sigaction sa;
|
||||
@@ -465,7 +403,7 @@ main(int argc, char **argv)
|
||||
all_argv = argv;
|
||||
sprintf(conf.confpath, "%s/"DEF_CONF, getenv("HOME"));
|
||||
|
||||
while((i = getopt(argc, argv, "hviSc:s:C:")) != -1)
|
||||
while((i = getopt(argc, argv, "hvic:s:C:")) != -1)
|
||||
{
|
||||
|
||||
/* For options who need WMFS running */
|
||||
@@ -476,11 +414,10 @@ main(int argc, char **argv)
|
||||
{
|
||||
case 'h':
|
||||
default:
|
||||
printf("usage: %s [-ihvS] [-C <file>] [-c <uicb function> <cmd> ] [-g <argument>] [-s <screen_num> <string>] [-V <viwmfs cmd]\n"
|
||||
printf("usage: %s [-ihv] [-C <file>] [-c <uicb function> <cmd> ] [-g <argument>] [-s <screen_num> <string>]\n"
|
||||
" -C <file> Load a configuration file\n"
|
||||
" -c <uicb_function> <cmd> Execute an uicb function to control WMFS\n"
|
||||
" -s <screen_num> <string> Set the bar(s) statustext\n"
|
||||
" -S Update status script\n"
|
||||
" -h Show this page\n"
|
||||
" -i Show informations\n"
|
||||
" -v Show WMFS version\n", argv[0]);
|
||||
@@ -497,12 +434,6 @@ main(int argc, char **argv)
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
update_status();
|
||||
XCloseDisplay(dpy);
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
strncpy(conf.confpath, optarg, sizeof(conf.confpath));
|
||||
break;
|
||||
|
||||
50
src/wmfs.h
50
src/wmfs.h
@@ -51,6 +51,7 @@
|
||||
#include <err.h>
|
||||
#include <pthread.h>
|
||||
#include <locale.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
@@ -58,6 +59,7 @@
|
||||
#include <sys/time.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/cursorfont.h>
|
||||
|
||||
/* Optional dependencies */
|
||||
@@ -112,13 +114,13 @@
|
||||
#define ATOM(a) XInternAtom(dpy, (a), False)
|
||||
#define FRAMEW(w) ((w) + (BORDH << 1))
|
||||
#define FRAMEH(h) ((h) + (BORDH + TBARH))
|
||||
#define ROUND(x) (float)((x > 0) ? x + (float)0.5 : x - (float)0.5)
|
||||
#define CHECK(x) if(!(x)) return
|
||||
#define LEN(x) (sizeof(x) / sizeof((x)[0]))
|
||||
#define MAXCLIST (64)
|
||||
#define RPOS(x) (x & 1 ? x - 1 : x + 1)
|
||||
#define LDIR(x) (x < Top)
|
||||
#define FLAGAPPLY(v, b, f) ((b) ? (v |= (f)) : (v &= ~(f)))
|
||||
#define INAREA(i, j, a) ((i) >= (a).x && (i) <= (a).x + (a).width && (j) >= (a).y && (j) <= (a).y + (a).height)
|
||||
|
||||
/* Cfactor define */
|
||||
#define CFACTOR_CHECK2(g1, g2, p) (LDIR(p) ? (g1.height == g2.height) : (g1.width == g2.width))
|
||||
@@ -127,6 +129,22 @@
|
||||
? (p == Left ? (g1.x == g2.x) : (g1.x + g1.width == g2.x + g2.width)) \
|
||||
: (p == Top ? (g1.y == g2.y) : (g1.y + g1.height == g2.y + g2.height))) \
|
||||
|
||||
/* Barwin define, wrappers for simple function */
|
||||
#define barwin_delete_subwin(bw) XDestroySubwindows(dpy, bw->win)
|
||||
#define barwin_map_subwin(bw) XMapSubwindows(dpy, bw->win)
|
||||
#define barwin_unmap_subwin(bw) XUnmapSubwindows(dpy, bw->win)
|
||||
#define barwin_refresh(bw) XCopyArea(dpy, bw->dr, bw->win, gc, 0, 0, bw->geo.width, bw->geo.height, 0, 0)
|
||||
#define barwin_map(bw) \
|
||||
do { \
|
||||
XMapWindow(dpy, bw->win); \
|
||||
bw->flags |= MappedFlag; \
|
||||
} while(/* CONSTCOND */ 0)
|
||||
#define barwin_unmap(bw) \
|
||||
do { \
|
||||
XUnmapWindow(dpy, bw->win); \
|
||||
bw->flags &= ~MappedFlag; \
|
||||
} while(/* CONSTCOND */ 0)
|
||||
|
||||
/* barwin.c */
|
||||
BarWindow *barwin_create(Window parent,
|
||||
int x, int y,
|
||||
@@ -138,15 +156,9 @@ BarWindow *barwin_create(Window parent,
|
||||
void barwin_draw_text(BarWindow *bw, int x, int y, char *text);
|
||||
void barwin_color_set(BarWindow *bw, uint bg, char *fg);
|
||||
void barwin_delete(BarWindow *bw);
|
||||
void barwin_delete_subwin(BarWindow *bw);
|
||||
void barwin_map(BarWindow *bw);
|
||||
void barwin_map_subwin(BarWindow *bw);
|
||||
void barwin_unmap(BarWindow *bw);
|
||||
void barwin_unmap_subwin(BarWindow *bw);
|
||||
void barwin_move(BarWindow *bw, int x, int y);
|
||||
void barwin_resize(BarWindow *bw, int w, int h);
|
||||
void barwin_refresh_color(BarWindow *bw);
|
||||
void barwin_refresh(BarWindow *bw);
|
||||
|
||||
/* draw.c */
|
||||
void draw_text(Drawable d, int x, int y, char* fg, char *str);
|
||||
@@ -158,6 +170,7 @@ ushort textw(char *text);
|
||||
/* infobar.c */
|
||||
void infobar_init(void);
|
||||
void infobar_draw_layout(InfoBar *i);
|
||||
void _infobar_draw(InfoBar *i);
|
||||
void infobar_draw(InfoBar *i);
|
||||
void infobar_draw_selbar(InfoBar *i);
|
||||
void infobar_draw_taglist(InfoBar *i);
|
||||
@@ -312,7 +325,6 @@ char *char_to_str(const char c);
|
||||
pid_t spawn(const char *str, ...);
|
||||
void swap_ptr(void **x, void **y);
|
||||
void uicb_spawn(uicb_t);
|
||||
char *clean_value(char *str);
|
||||
char* patht(char *path);
|
||||
int qsort_string_compare (const void * a, const void * b);
|
||||
|
||||
@@ -354,7 +366,8 @@ void uicb_screen_prev(uicb_t);
|
||||
void uicb_screen_prev_sel(uicb_t);
|
||||
|
||||
/* status.c */
|
||||
void statustext_handle(int sc, char *str);
|
||||
void statustext_mouse(char *str, Geo area, InfoBar *infobar);
|
||||
void statustext_handle(InfoBar *ib);
|
||||
|
||||
/* systray.c */
|
||||
bool systray_acquire(void);
|
||||
@@ -435,14 +448,13 @@ void uicb_reload(uicb_t);
|
||||
|
||||
/* Variables */
|
||||
|
||||
/* Principal */
|
||||
/* Main */
|
||||
Display *dpy;
|
||||
GC gc, gc_stipple;
|
||||
int selscreen;
|
||||
int prevselscreen;
|
||||
Conf conf;
|
||||
Key *keys;
|
||||
bool estatus;
|
||||
Geo *sgeo;
|
||||
Geo *spgeo;
|
||||
Cursor cursor[CurLast];
|
||||
@@ -472,20 +484,28 @@ struct clndx {
|
||||
Client *client;
|
||||
} clist_index[MAXCLIST];
|
||||
|
||||
/* Important Client */
|
||||
Client *clients;
|
||||
/* Client */
|
||||
SLIST_HEAD(, Client) clients;
|
||||
Client *sel;
|
||||
|
||||
/* Other */
|
||||
/* Event */
|
||||
int nevent;
|
||||
void (**event_handle)(XEvent*);
|
||||
extern const func_name_list_t func_list[];
|
||||
extern const func_name_list_t layout_list[];
|
||||
uint numlockmask;
|
||||
Systray *trayicons;
|
||||
|
||||
/* Systray */
|
||||
SLIST_HEAD(, Systray) trayicons;
|
||||
Window traywin;
|
||||
int tray_width;
|
||||
|
||||
/* BarWindow */
|
||||
SLIST_HEAD(, BarWindow) bwhead;
|
||||
|
||||
/* Status */
|
||||
SLIST_HEAD(, StatusMouse) smhead;
|
||||
|
||||
#endif /* WMFS_H */
|
||||
|
||||
|
||||
|
||||
15
wmfsrc
15
wmfsrc
@@ -11,15 +11,13 @@
|
||||
font = "dejavu-10"
|
||||
raisefocus = true
|
||||
focus_follow_mouse = true
|
||||
focus_follow_movement = false
|
||||
focus_follow_movement = true
|
||||
opacity = 255
|
||||
|
||||
# focus_pointer_click: click on unfocused client area:
|
||||
# true -- default, set focus
|
||||
# false -- click go to client; including dockapps
|
||||
focus_pointer_click = true
|
||||
status_timing = 1 #seconds
|
||||
# status_path = "~/.config/wmfs/status.sh"
|
||||
[/misc]
|
||||
|
||||
[bar]
|
||||
@@ -31,6 +29,12 @@
|
||||
light_shade = 0.10
|
||||
dark_shade = -0.10
|
||||
|
||||
# Order of infobar elements:
|
||||
# t = Tag list
|
||||
# l = Layout button
|
||||
# s = Selbar
|
||||
elements_order = "tls"
|
||||
|
||||
[systray]
|
||||
# Enable/disable systray
|
||||
active = true
|
||||
@@ -67,9 +71,6 @@
|
||||
# Value menu or switch.
|
||||
system = "menu"
|
||||
|
||||
# Value left or right.
|
||||
placement = "right"
|
||||
|
||||
# Keep layout geo for free layout
|
||||
keep_layout_geo = false
|
||||
|
||||
@@ -311,6 +312,8 @@
|
||||
prompt = "Exec: "
|
||||
command = "exec"
|
||||
[/set_launcher]
|
||||
[/launcher]
|
||||
|
||||
[keys]
|
||||
# Reload the configuration of wmfs.
|
||||
[key] mod = {"Alt", "Control"} key = "r" func = "reload" [/key]
|
||||
|
||||
Reference in New Issue
Block a user