Compare commits
No commits in common. "master" and "bacardi55" have entirely different histories.
10
.gitignore
vendored
10
.gitignore
vendored
@ -1,3 +1,9 @@
|
|||||||
Makefile
|
*.o
|
||||||
|
.*.sw?
|
||||||
wmfs
|
wmfs
|
||||||
src/*.o
|
#*
|
||||||
|
\#*
|
||||||
|
Makefile
|
||||||
|
wmfs.1.gz
|
||||||
|
tags
|
||||||
|
*.patch
|
||||||
|
|||||||
1
COPYING
1
COPYING
@ -24,3 +24,4 @@
|
|||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
SUCH DAMAGE.
|
SUCH DAMAGE.
|
||||||
|
|
||||||
|
|||||||
77
Makefile.in
77
Makefile.in
@ -1,28 +1,34 @@
|
|||||||
PROG=wmfs
|
PROG=wmfs
|
||||||
|
MAN=wmfs.1
|
||||||
|
|
||||||
# wmfs version
|
# wmfs version
|
||||||
VERSION=$(shell scripts/setlocalversion)
|
VERSION= 201011
|
||||||
|
|
||||||
SRCS= \
|
SRCS= \
|
||||||
src/barwin.c \
|
src/barwin.c \
|
||||||
src/config.c \
|
src/client.c \
|
||||||
src/client.c \
|
src/config.c \
|
||||||
src/event.c \
|
src/draw.c \
|
||||||
src/ewmh.c \
|
src/event.c \
|
||||||
src/infobar.c \
|
src/ewmh.c \
|
||||||
src/layout.c \
|
src/frame.c \
|
||||||
src/launcher.c \
|
src/getinfo.c \
|
||||||
src/parse_api.c \
|
src/infobar.c \
|
||||||
src/parse.c \
|
src/init.c \
|
||||||
src/screen.c \
|
src/launcher.c \
|
||||||
src/tag.c \
|
src/layout.c \
|
||||||
src/util.c \
|
src/menu.c \
|
||||||
src/status.c \
|
src/mouse.c \
|
||||||
src/systray.c \
|
src/parse_api.c \
|
||||||
src/mouse.c \
|
src/parse.c \
|
||||||
src/log.c \
|
src/screen.c \
|
||||||
src/wmfs.c
|
src/status.c \
|
||||||
|
src/systray.c \
|
||||||
|
src/tag.c \
|
||||||
|
src/util.c \
|
||||||
|
src/viwmfs.c \
|
||||||
|
src/color.c \
|
||||||
|
src/wmfs.c
|
||||||
|
|
||||||
# flags
|
# flags
|
||||||
CFLAGS+= -DXDG_CONFIG_DIR=\"${XDG_CONFIG_DIR}\"
|
CFLAGS+= -DXDG_CONFIG_DIR=\"${XDG_CONFIG_DIR}\"
|
||||||
@ -31,47 +37,50 @@ CFLAGS+= -Wall -Wextra
|
|||||||
|
|
||||||
OBJS= ${SRCS:.c=.o}
|
OBJS= ${SRCS:.c=.o}
|
||||||
|
|
||||||
all: ${PROG}
|
all: ${PROG} ${MAN}.gz
|
||||||
|
|
||||||
${PROG}: ${OBJS}
|
${PROG}: ${OBJS} src/structs.h src/wmfs.h src/parse.h
|
||||||
${CC} -o $@ ${OBJS} ${LDFLAGS}
|
${CC} -o $@ ${OBJS} ${LDFLAGS}
|
||||||
|
|
||||||
|
${MAN}.gz: ${MAN}
|
||||||
|
gzip -cn -9 ${MAN} > $@
|
||||||
|
|
||||||
.c.o:
|
.c.o:
|
||||||
${CC} -c ${CFLAGS} $< -o $@
|
${CC} -c ${CFLAGS} $< -o $@
|
||||||
|
|
||||||
.PHONY: all clean distclean install uninstall dist
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f ${OBJS} wmfs
|
rm -f ${OBJS} wmfs ${MAN}.gz
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
rm -f Makefile
|
rm -f Makefile
|
||||||
|
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
@echo installing executable file to ${DESTDIR}${PREFIX}/bin
|
@echo installing executable file to ${DESTDIR}${PREFIX}/bin
|
||||||
mkdir -p ${DESTDIR}${PREFIX}/bin
|
mkdir -p ${DESTDIR}${PREFIX}/bin
|
||||||
install ${PROG} ${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
|
@echo installing xsession file to ${DESTDIR}${PREFIX}/share/xsessions
|
||||||
mkdir -p ${DESTDIR}${PREFIX}/share/xsessions
|
mkdir -p ${DESTDIR}${PREFIX}/share/xsessions
|
||||||
install -m 444 wmfs.desktop ${DESTDIR}${PREFIX}/share/xsessions
|
install -m 644 wmfs.desktop ${DESTDIR}${PREFIX}/share/xsessions/
|
||||||
@echo installing default config file to ${DESTDIR}${XDG_CONFIG_DIR}/wmfs/
|
@echo installing default config file to ${DESTDIR}${XDG_CONFIG_DIR}/wmfs/
|
||||||
mkdir -p ${DESTDIR}${XDG_CONFIG_DIR}/wmfs/
|
mkdir -p ${DESTDIR}${XDG_CONFIG_DIR}/wmfs/
|
||||||
install -m 444 wmfsrc ${DESTDIR}${XDG_CONFIG_DIR}/wmfs/
|
install -m 444 wmfsrc ${DESTDIR}${XDG_CONFIG_DIR}/wmfs/
|
||||||
@echo installing manual pages to ${DESTDIR}${MANPREFIX}/man1/
|
|
||||||
mkdir -p ${DESTDIR}${MANPREFIX}/man1/
|
|
||||||
install -m 644 wmfs.1 ${DESTDIR}${MANPREFIX}/man1/wmfs.1
|
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
@echo removing executable file from ${DESTDIR}${PREFIX}/bin
|
@echo removing executable file from ${DESTDIR}${PREFIX}/bin
|
||||||
rm -f ${DESTDIR}${PREFIX}/bin/wmfs
|
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
|
@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/
|
@echo removing config file from ${DESTDIR}${XDG_CONFIG_DIR}/wmfs/
|
||||||
rm -f ${DESTDIR}${XDG_CONFIG_DIR}/wmfs/wmfsrc
|
rm -f ${DESTDIR}${XDG_CONFIG_DIR}/wmfs/wmfsrc
|
||||||
rmdir ${DESTDIR}${XDG_CONFIG_DIR}/wmfs/
|
rmdir ${DESTDIR}${XDG_CONFIG_DIR}/wmfs/
|
||||||
@echo removing manual pages from ${DESTDIR}${MANPREFIX}/man1
|
|
||||||
rm -f ${DESTDIR}${MANPREFIX}/man1/wmfs.1
|
|
||||||
|
|
||||||
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
|
.PHONY: all clean distclean install uninstall
|
||||||
|
|
||||||
|
|||||||
39
README
39
README
@ -1 +1,38 @@
|
|||||||
next WMFS dev branch.
|
ABOUT :
|
||||||
|
WMFS Window Manager.
|
||||||
|
* Window Manager From Scratch
|
||||||
|
|
||||||
|
A highly configurable and manageable tiling Window Manager created from scratch
|
||||||
|
|
||||||
|
AUTHORS : (in order of commits and > 5 commits)
|
||||||
|
- Martin Duquesnoy <xorg62@gmail.com>
|
||||||
|
- Philippe Pepiot <phil@philpep.org>
|
||||||
|
- Marc Lagrange <markocpc@gmail.com>
|
||||||
|
- OldMan <tele-post@mail.ru>
|
||||||
|
- Raphael Khaiat <raphael@khaiat.org>
|
||||||
|
- Tomáš Chvátal <scarabeus@gentoo.org>
|
||||||
|
- David Delassus <linkdd@ydb.me>
|
||||||
|
|
||||||
|
|
||||||
|
LICENSE : BSD
|
||||||
|
|
||||||
|
REQUIREMENT :
|
||||||
|
- freetype2
|
||||||
|
- libxft
|
||||||
|
- libx11
|
||||||
|
- libxinerama (optional)
|
||||||
|
- libxrandr (optional)
|
||||||
|
- imlib2 (optional)
|
||||||
|
|
||||||
|
OS :
|
||||||
|
- GNU/Linux : Supported.
|
||||||
|
- FreeBSD/OpenBSD/NetBSD : Supported.
|
||||||
|
|
||||||
|
INSTALL :
|
||||||
|
./configure [--without-imlib2|--without-xrandr|--without-xinerama] (./configure -h)
|
||||||
|
make
|
||||||
|
sudo make install
|
||||||
|
|
||||||
|
DISTROS :
|
||||||
|
- wmfs port for FreeBSD at x11-wm/wmfs
|
||||||
|
- wmfs is available with AUR in ArchLinux (wmfs or wmfs-git)
|
||||||
|
|||||||
5
TODO
Normal file
5
TODO
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
· Add Doxygen comment <-> OK
|
||||||
|
· Mouse bindings in the config file
|
||||||
|
· Can change client position in the tile grid
|
||||||
|
· Fix all the bug \o/
|
||||||
|
· XCB ?
|
||||||
46
configure
vendored
46
configure
vendored
@ -1,10 +1,9 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
LIBS="x11"
|
LIBS="x11 xft freetype2"
|
||||||
USE_XINERAMA="xinerama"
|
USE_XINERAMA="xinerama"
|
||||||
USE_XRANDR="xrandr"
|
USE_XRANDR="xrandr"
|
||||||
USE_IMLIB2="imlib2"
|
USE_IMLIB2="imlib2"
|
||||||
USE_XFT="xft freetype2"
|
|
||||||
OS=`uname -s`
|
OS=`uname -s`
|
||||||
PREFIX=/usr/local
|
PREFIX=/usr/local
|
||||||
MANPREFIX="$PREFIX/man"
|
MANPREFIX="$PREFIX/man"
|
||||||
@ -14,32 +13,35 @@ while true; do
|
|||||||
case "$1" in
|
case "$1" in
|
||||||
--without-xinerama)
|
--without-xinerama)
|
||||||
USE_XINERAMA=""; shift;;
|
USE_XINERAMA=""; shift;;
|
||||||
|
--without-xrandr)
|
||||||
|
USE_XRANDR=""; shift;;
|
||||||
--without-imlib2)
|
--without-imlib2)
|
||||||
USE_IMLIB2=""; shift;;
|
USE_IMLIB2=""; shift;;
|
||||||
--prefix)
|
--prefix)
|
||||||
[ -z "$2" ] && echo "Missing argument" && exit 1
|
[ -z "$2" ] && echo "Missing argument" && exit 1
|
||||||
PREFIX=$2; shift 2;;
|
PREFIX=$2; shift 2;;
|
||||||
--man-prefix)
|
|
||||||
[ -z "$2" ] && echo "Missing argument" && exit 1
|
|
||||||
MANPREFIX=$2; shift 2;;
|
|
||||||
--xdg-config-dir)
|
--xdg-config-dir)
|
||||||
[ -z "$2" ] && echo "Missing argument" && exit 1
|
[ -z "$2" ] && echo "Missing argument" && exit 1
|
||||||
XDG_CONFIG_DIR=$2; shift 2;;
|
XDG_CONFIG_DIR=$2; shift 2;;
|
||||||
|
--man-prefix)
|
||||||
|
[ -z "$2" ] && echo "Missing argument" && exit 1
|
||||||
|
MANPREFIX=$2; shift 2;;
|
||||||
--help|-h)
|
--help|-h)
|
||||||
echo "Usage: ./configure [options]
|
echo "Usage: ./configure [options]
|
||||||
--without-xinerama : compile without xinerama support
|
|
||||||
--without-imlib2 : compile without imlib2 support
|
--without-imlib2 : compile without imlib2 support
|
||||||
|
--without-xrandr : compile without xrandr support
|
||||||
|
--without-xinerama : compile without xinerama support
|
||||||
--prefix DIRECTORY : install binary with specified prefix (default $PREFIX)
|
--prefix DIRECTORY : install binary with specified prefix (default $PREFIX)
|
||||||
--man-prefix DIRECTORY : install binary with specified prefix (default $PREFIX)
|
--xdg-config-dir DIRECTORY : install configuration to specified directory (default $XDG_CONFIG_DIR)
|
||||||
--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;;
|
exit 0;;
|
||||||
*) break;;
|
*) break;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
LIBS="$LIBS $USE_XINERAMA $USE_IMLIB2"
|
LIBS="$LIBS $USE_XINERAMA $USE_XRANDR $USE_IMLIB2"
|
||||||
|
|
||||||
which pkg-config > /dev/null 2>&1
|
which pkg-config >/dev/null 2>&1
|
||||||
|
|
||||||
if [ $? -eq 0 ];
|
if [ $? -eq 0 ];
|
||||||
then
|
then
|
||||||
@ -49,16 +51,16 @@ else
|
|||||||
# Try to use some known paths
|
# Try to use some known paths
|
||||||
case $OS in
|
case $OS in
|
||||||
FreeBSD)
|
FreeBSD)
|
||||||
CFLAGS="-I/usr/local/include"
|
CFLAGS="-I/usr/local/include -I/usr/local/include/freetype2"
|
||||||
LDFLAGS="-L/usr/local/lib";;
|
LDFLAGS="-L/usr/local/lib";;
|
||||||
OpenBSD)
|
OpenBSD)
|
||||||
CFLAGS="-I/usr/X11R6/include -I/usr/local/include"
|
CFLAGS="-I/usr/X11R6/include -I/usr/X11R6/include/freetype2 -I/usr/local/include"
|
||||||
LDFLAGS="-L/usr/X11R6/lib -L/usr/local/lib";;
|
LDFLAGS="-L/usr/X11R6/lib -L/usr/local/lib";;
|
||||||
NetBSD)
|
NetBSD)
|
||||||
CFLAGS="-I/usr/X11R7/include -I/usr/pkg/include"
|
CFLAGS="-I/usr/X11R7/include -I/usr/X11R7/include/freetype2 -I/usr/local/include"
|
||||||
LDFLAGS="-L/usr/X11R7/lib -L/usr/pkg/lib";;
|
LDFLAGS="-L/usr/X11R7/lib -L/usr/local/lib";;
|
||||||
Linux)
|
Linux)
|
||||||
CFLAGS=""
|
CFLAGS="-I/usr/include/freetype2"
|
||||||
LDFLAGS=""
|
LDFLAGS=""
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
@ -66,22 +68,18 @@ else
|
|||||||
exit 1;;
|
exit 1;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
LDFLAGS="$LDFLAGS -lX11"
|
LDFLAGS="$LDFLAGS -lX11 -lXft -lfreetype"
|
||||||
|
|
||||||
[ -n "$USE_XINERAMA" ] && LDFLAGS="$LDFLAGS -lXinerama"
|
[ -n "$USE_XINERAMA" ] && LDFLAGS="$LDFLAGS -lXinerama"
|
||||||
|
[ -n "$USE_XRANDR" ] && LDFLAGS="$LDFLAGS -lXrandr"
|
||||||
[ -n "$USE_IMLIB2" ] && LDFLAGS="$LDFLAGS -lImlib2"
|
[ -n "$USE_IMLIB2" ] && LDFLAGS="$LDFLAGS -lImlib2"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
[ -n "$USE_XINERAMA" ] && CFLAGS="$CFLAGS -DHAVE_XINERAMA"
|
[ -n "$USE_XINERAMA" ] && CFLAGS="$CFLAGS -DHAVE_XINERAMA"
|
||||||
[ -n "$USE_IMLIB2" ] && CFLAGS="$CFLAGS -DHAVE_IMLIB2"
|
[ -n "$USE_XRANDR" ] && CFLAGS="$CFLAGS -DHAVE_XRANDR"
|
||||||
|
[ -n "$USE_IMLIB2" ] && CFLAGS="$CFLAGS -DHAVE_IMLIB"
|
||||||
|
|
||||||
# Debian hardening options http://wiki.debian.org/Hardening
|
LDFLAGS="$LDFLAGS -lpthread"
|
||||||
which dpkg-buildflags > /dev/null 2>&1
|
|
||||||
if [ $? -eq 0 ];
|
|
||||||
then
|
|
||||||
CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=2 `dpkg-buildflags --get CFLAGS`"
|
|
||||||
LDFLAGS="$LDFLAGS `dpkg-buildflags --get LDFLAGS`"
|
|
||||||
fi
|
|
||||||
|
|
||||||
cat > Makefile << EOF
|
cat > Makefile << EOF
|
||||||
PREFIX=$PREFIX
|
PREFIX=$PREFIX
|
||||||
|
|||||||
45
debian/changelog
vendored
45
debian/changelog
vendored
@ -1,45 +0,0 @@
|
|||||||
wmfs (2~beta201206-3) unstable; urgency=low
|
|
||||||
|
|
||||||
* No hardening-related Lintiant warnings
|
|
||||||
|
|
||||||
-- Mickaël Raybaud-Roig <raybaudroigm@gmail.com> Sun, 24 Jun 2012 16:40:54 +0200
|
|
||||||
|
|
||||||
wmfs (2~beta201206-2) unstable; urgency=low
|
|
||||||
|
|
||||||
* Fixed some Lintian warnings
|
|
||||||
* New standards version
|
|
||||||
|
|
||||||
-- Mickaël Raybaud-Roig <raybaudroigm@gmail.com> Sun, 24 Jun 2012 15:19:38 +0200
|
|
||||||
|
|
||||||
wmfs (2~beta201206-1) unstable; urgency=low
|
|
||||||
|
|
||||||
* Updated changelog version
|
|
||||||
* Added build-depends to the control file
|
|
||||||
* Updated Vcs-* fields in the control file
|
|
||||||
|
|
||||||
-- Mickaël Raybaud-Roig <raybaudroigm@gmail.com> Sun, 24 Jun 2012 13:12:26 +0200
|
|
||||||
|
|
||||||
wmfs (2~beta-3) unstable; urgency=low
|
|
||||||
|
|
||||||
* Modified build script (debian/rules)
|
|
||||||
* Modified versions in changelog
|
|
||||||
* Removed the old manpage
|
|
||||||
* The configuration is done in override_dh_auto_configure (in debian/rules)
|
|
||||||
* The .desktop file is installed by dh_install
|
|
||||||
|
|
||||||
-- Mickaël Raybaud-Roig <raybaudroigm@gmail.com> Sat, 18 Feb 2012 19:40:09 +0100
|
|
||||||
|
|
||||||
wmfs (2~beta-2) unstable; urgency=low
|
|
||||||
|
|
||||||
* Added a manpage
|
|
||||||
* Modified the debian/rules script
|
|
||||||
* Filled debian/copying
|
|
||||||
* Added dependencies
|
|
||||||
|
|
||||||
-- Mickaël Raybaud-Roig <raybaudroigm@gmail.com> Sat, 28 Jan 2012 12:44:18 +0100
|
|
||||||
|
|
||||||
wmfs (2~beta-1) unstable; urgency=low
|
|
||||||
|
|
||||||
* Initial release
|
|
||||||
|
|
||||||
-- Mickaël Raybaud-Roig <raybaudroigm@gmail.com> Sat, 21 Jan 2012 13:22:37 +0100
|
|
||||||
1
debian/compat
vendored
1
debian/compat
vendored
@ -1 +0,0 @@
|
|||||||
8
|
|
||||||
16
debian/control
vendored
16
debian/control
vendored
@ -1,16 +0,0 @@
|
|||||||
Source: wmfs
|
|
||||||
Section: x11
|
|
||||||
Priority: extra
|
|
||||||
Maintainer: Mickaël Raybaud-Roig <raybaudroigm@gmail.com>
|
|
||||||
Build-Depends: debhelper (>= 8.0.0), libimlib2-dev, libxinerama-dev, libx11-dev
|
|
||||||
Standards-Version: 3.9.3
|
|
||||||
Homepage: http://wmfs.info
|
|
||||||
Vcs-Git: git://github.com/xorg62/wmfs.git
|
|
||||||
Vcs-Browser: https://github.com/xorg62/wmfs
|
|
||||||
|
|
||||||
Package: wmfs
|
|
||||||
Architecture: any
|
|
||||||
Depends: ${shlibs:Depends}, ${misc:Depends}, libxinerama1, libimlib2, libxcb1, libfreetype6
|
|
||||||
Description: Window Manager From Scratch
|
|
||||||
WMFS (Window Manager From Scratch) is a lightweight and highly configurable
|
|
||||||
tiling window manager for X.
|
|
||||||
54
debian/copyright
vendored
54
debian/copyright
vendored
@ -1,54 +0,0 @@
|
|||||||
Format: http://dep.debian.net/deps/dep5
|
|
||||||
Upstream-Name: wmfs
|
|
||||||
Source: http://wmfs.info
|
|
||||||
|
|
||||||
Files: *
|
|
||||||
Copyright: 2011-2012 Martin Duquesnoy <xorg62@gmail.com>
|
|
||||||
License: BSD-3-Clauses
|
|
||||||
|
|
||||||
Files: debian/*
|
|
||||||
Copyright: 2012 Mickaël Raybaud-Roig <raybaudroigm@gmail.com>
|
|
||||||
License: WTFPL-2
|
|
||||||
|
|
||||||
License: BSD-3-Clauses
|
|
||||||
Copyright (c) 1983 The Regents of the University of California.
|
|
||||||
All rights reserved.
|
|
||||||
.
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. Neither the name of the University nor the names of its contributors
|
|
||||||
may be used to endorse or promote products derived from this software
|
|
||||||
without specific prior written permission.
|
|
||||||
.
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
||||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
SUCH DAMAGE.
|
|
||||||
|
|
||||||
License: WTFPL-2
|
|
||||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
|
||||||
Version 2, December 2004
|
|
||||||
.
|
|
||||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
|
||||||
.
|
|
||||||
Everyone is permitted to copy and distribute verbatim or modified
|
|
||||||
copies of this license document, and changing it is allowed as long
|
|
||||||
as the name is changed.
|
|
||||||
.
|
|
||||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
|
||||||
.
|
|
||||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
|
||||||
1
debian/docs
vendored
1
debian/docs
vendored
@ -1 +0,0 @@
|
|||||||
README
|
|
||||||
16
debian/rules
vendored
16
debian/rules
vendored
@ -1,16 +0,0 @@
|
|||||||
#!/usr/bin/make -f
|
|
||||||
# -*- makefile -*-
|
|
||||||
# Sample debian/rules that uses debhelper.
|
|
||||||
# This file was originally written by Joey Hess and Craig Small.
|
|
||||||
# As a special exception, when this file is copied by dh-make into a
|
|
||||||
# dh-make output file, you may use that output file without restriction.
|
|
||||||
# This special exception was added by Craig Small in version 0.37 of dh-make.
|
|
||||||
|
|
||||||
# Uncomment this to turn on verbose mode.
|
|
||||||
export DH_VERBOSE=1
|
|
||||||
|
|
||||||
override_dh_auto_configure:
|
|
||||||
./configure --prefix /usr --xdg-config-dir /etc/xdg --man-prefix /usr/share/man/
|
|
||||||
|
|
||||||
%:
|
|
||||||
dh $@
|
|
||||||
1
debian/source/format
vendored
1
debian/source/format
vendored
@ -1 +0,0 @@
|
|||||||
3.0 (quilt)
|
|
||||||
1
debian/wmfs.install
vendored
1
debian/wmfs.install
vendored
@ -1 +0,0 @@
|
|||||||
wmfs.desktop /usr/share/xsessions
|
|
||||||
1
debian/wmfs.manpages
vendored
1
debian/wmfs.manpages
vendored
@ -1 +0,0 @@
|
|||||||
wmfs.1
|
|
||||||
1
debian/wmfs.wm
vendored
1
debian/wmfs.wm
vendored
@ -1 +0,0 @@
|
|||||||
/usr/bin/wmfs
|
|
||||||
11
rc/status.sh
Executable file
11
rc/status.sh
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#WMFS status.sh example file
|
||||||
|
#Will be executed if put in ~/.config/wmfs/
|
||||||
|
#Timing adjustable in wmfsrc (misc -> status_timing)
|
||||||
|
|
||||||
|
statustext()
|
||||||
|
{
|
||||||
|
wmfs -s "`date`"
|
||||||
|
}
|
||||||
|
|
||||||
|
statustext
|
||||||
@ -1,64 +0,0 @@
|
|||||||
#! /bin/sh
|
|
||||||
# simple help script for WMFS2 by arpinux
|
|
||||||
# default keybinds list
|
|
||||||
|
|
||||||
xpos="5"
|
|
||||||
ypos="5"
|
|
||||||
width="350"
|
|
||||||
height="730"
|
|
||||||
bg="#222222"
|
|
||||||
fg="#7D7D7D"
|
|
||||||
l01="^s[80;12;$bg;WMFS² Keybinds Help]"
|
|
||||||
l03="^s[15;35;$fg;launch terminal:]^s[190;35;$fg;Super + Return]"
|
|
||||||
l04="^s[15;50;$fg;launch prompt:]^s[190;50;$fg;Super + p]"
|
|
||||||
l05="^s[15;65;$fg;close client:]^s[190;65;$fg;Super + q]"
|
|
||||||
l06="^s[15;80;$fg;reload wmfs:]^s[190;80;$fg;Control + Alt + r]"
|
|
||||||
l07="^s[15;95;$fg;quit wmfs:]^s[190;95;$fg;Control + Alt + q]"
|
|
||||||
|
|
||||||
l08="^s[15;115;$fg;next client:]^s[190;115;$fg;Alt + Tab]"
|
|
||||||
l09="^s[15;130;$fg;prev client:]^s[190;130;$fg;Alt + Shift + Tab]"
|
|
||||||
l10="^s[15;145;$fg;next tabbed client:]^s[190;145;$fg;Super + Tab]"
|
|
||||||
l11="^s[15;160;$fg;prev tabbed client:]^s[190;160;$fg;Super + Shift + Tab]"
|
|
||||||
l12="^s[15;175;$fg;left client:]^s[190;175;$fg;Alt + h]"
|
|
||||||
l13="^s[15;190;$fg;right client:]^s[190;190;$fg;Alt + l]"
|
|
||||||
l14="^s[15;205;$fg;top client:]^s[190;205;$fg;Alt + k]"
|
|
||||||
l15="^s[15;220;$fg;bottom client:]^s[190;220;$fg;Alt + j]"
|
|
||||||
l16="^s[15;235;$fg;swap client left:]^s[190;235;$fg;Control + Shift + h]"
|
|
||||||
l17="^s[15;250;$fg;swap client right:]^s[190;250;$fg;Control + Shift + l]"
|
|
||||||
l18="^s[15;265;$fg;swap client top:]^s[190;265;$fg;Control + Shift + k]"
|
|
||||||
l19="^s[15;280;$fg;swap client bottom:]^s[190;280;$fg;Control + Shift + j]"
|
|
||||||
l20="^s[15;295;$fg;tab client left:]^s[190;295;$fg;Alt + Shift + h]"
|
|
||||||
l21="^s[15;310;$fg;tab client right:]^s[190;310;$fg;Alt + Shift + l]"
|
|
||||||
l22="^s[15;325;$fg;tab client top:]^s[190;325;$fg;Alt + Shift + k]"
|
|
||||||
l23="^s[15;340;$fg;tab client bottom:]^s[190;340;$fg;Alt + Shift + j]"
|
|
||||||
l24="^s[15;355;$fg;untab client:]^s[190;355;$fg;Alt + Shift + u]"
|
|
||||||
|
|
||||||
l25="^s[15;375;$fg;increase client on left:]^s[190;375;$fg;Super + h]"
|
|
||||||
l26="^s[15;390;$fg;decrease client from left:]^s[190;390;$fg;Super + l]"
|
|
||||||
l27="^s[15;405;$fg;increase client on top:]^s[190;405;$fg;Super + k]"
|
|
||||||
l28="^s[15;420;$fg;decrease client from top:]^s[190;420;$fg;Super + j]"
|
|
||||||
l29="^s[15;435;$fg;decrease client from right:]^s[190;435;$fg;Super + Control + h]"
|
|
||||||
l30="^s[15;450;$fg;increase client on right:]^s[190;450;$fg;Super + Control + l]"
|
|
||||||
l31="^s[15;465;$fg;decrease client from bottom:]^s[190;465;$fg;Super + Control + k]"
|
|
||||||
l32="^s[15;480;$fg;increase client to bottom:]^s[190;480;$fg;Super + Control + j]"
|
|
||||||
l33="^s[15;495;$fg;integrate client to left:]^s[190;495;$fg;Super + Control + Alt + h]"
|
|
||||||
l34="^s[15;510;$fg;integrate client to right:]^s[190;510;$fg;Super + Control + Alt + l]"
|
|
||||||
l35="^s[15;525;$fg;integrate client to top:]^s[190;525;$fg;Super + Control + Alt + k]"
|
|
||||||
l36="^s[15;540;$fg;integrate client to bottom:]^s[190;540;$fg;Super + Control + Alt + j]"
|
|
||||||
|
|
||||||
l37="^s[15;560;$fg;horizontal layout:]^s[190;560;$fg;Super + Shift + m]"
|
|
||||||
l38="^s[15;575;$fg;vertical layout:]^s[190;575;$fg;Super + m]"
|
|
||||||
l39="^s[15;590;$fg;layout rotate right:]^s[190;590;$fg;Super + r]"
|
|
||||||
l40="^s[15;605;$fg;layout rotate left:]^s[190;605;$fg;Super + Shift + r]"
|
|
||||||
l41="^s[15;620;$fg;toggle client free:]^s[190;620;$fg;Super + f]"
|
|
||||||
|
|
||||||
l42="^s[15;640;$fg;prev/next tag:]^s[190;640;$fg;Control + Left/Right]"
|
|
||||||
l43="^s[15;655;$fg;prev/next screen:]^s[190;655;$fg;Control + Up/Down]"
|
|
||||||
l44="^s[15;670;$fg;set tag (x):]^s[190;670;$fg;Super + F(x)]"
|
|
||||||
l45="^s[15;685;$fg;tag client with (x):]^s[190;685;$fg;Super + Shift + F(x)]"
|
|
||||||
l46="^s[15;700;$fg;add tag:]^s[190;700;$fg;Super + Shift + -]"
|
|
||||||
l47="^s[15;715;$fg;delete tag:]^s[190;715;$fg;Super + -]"
|
|
||||||
|
|
||||||
frame="^R[0;0;350;15;$fg] ^R[0;728;350;2;$fg] ^R[0;0;2;730;$fg] ^R[348;0;2;730;$fg]"
|
|
||||||
|
|
||||||
wmfs -c status_surface "$xpos,$ypos,$width,$height,$bg $frame $l01 $l03 $l04 $l05 $l06 $l07 $l08 $l09 $l10 $l11 $l12 $l13 $l14 $l15 $l16 $l17 $l18 $l19 $l20 $l21 $l22 $l23 $l24 $l25 $l26 $l27 $l28 $l29 $l30 $l31 $l32 $l33 $l34 $l35 $l36 $l37 $l38 $l39 $l40 $l41 $l42 $l43 $l44 $l45 $l46 $l47"
|
|
||||||
@ -1,75 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# Print additional version information for non-release trees.
|
|
||||||
|
|
||||||
usage() {
|
|
||||||
echo "Usage: $0 [srctree]" >&2
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
cd "${1:-.}" || usage
|
|
||||||
|
|
||||||
# Check for git and a git repo.
|
|
||||||
if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then
|
|
||||||
# Do we have an untagged version?
|
|
||||||
if git name-rev --tags HEAD | grep -E '^HEAD[[:space:]]+(.*~[0-9]*|undefined)$' > /dev/null; then
|
|
||||||
if tag=`git describe 2>/dev/null`; then
|
|
||||||
echo $tag | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}'
|
|
||||||
else
|
|
||||||
printf '%s%s' -g $head
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Is this git on svn?
|
|
||||||
if git config --get svn-remote.svn.url >/dev/null; then
|
|
||||||
printf -- '-svn%s' "`git svn find-rev $head`"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Are there uncommitted changes?
|
|
||||||
git update-index --refresh --unmerged > /dev/null
|
|
||||||
if git diff-index --name-only HEAD | grep -v "^scripts/package" \
|
|
||||||
| read dummy; then
|
|
||||||
printf '%s' -dirty
|
|
||||||
fi
|
|
||||||
|
|
||||||
# All done with git
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check for mercurial and a mercurial repo.
|
|
||||||
if hgid=`hg id 2>/dev/null`; then
|
|
||||||
tag=`printf '%s' "$hgid" | cut -d' ' -f2`
|
|
||||||
|
|
||||||
# Do we have an untagged version?
|
|
||||||
if [ -z "$tag" -o "$tag" = tip ]; then
|
|
||||||
id=`printf '%s' "$hgid" | sed 's/[+ ].*//'`
|
|
||||||
printf '%s%s' -hg "$id"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Are there uncommitted changes?
|
|
||||||
# These are represented by + after the changeset id.
|
|
||||||
case "$hgid" in
|
|
||||||
*+|*+\ *) printf '%s' -dirty ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# All done with mercurial
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check for svn and a svn repo.
|
|
||||||
if rev=`svn info 2>/dev/null | grep '^Last Changed Rev'`; then
|
|
||||||
rev=`echo $rev | awk '{print $NF}'`
|
|
||||||
changes=`svn status 2>/dev/null | grep '^[AMD]' | wc -l`
|
|
||||||
|
|
||||||
# Are there uncommitted changes?
|
|
||||||
if [ $changes != 0 ]; then
|
|
||||||
printf -- '-svn%s%s' "$rev" -dirty
|
|
||||||
else
|
|
||||||
printf -- '-svn%s' "$rev"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# All done with svn
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
# default version
|
|
||||||
printf -- '-%s' "`date +%Y%m`"
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
#WMFS status.sh example file
|
|
||||||
|
|
||||||
TIMING=10
|
|
||||||
|
|
||||||
statustext()
|
|
||||||
{
|
|
||||||
# Syntax : status <bar name> <data>
|
|
||||||
# possible sequences as data: \s[] \R[] \i[]
|
|
||||||
wmfs -c status "default `date`"
|
|
||||||
}
|
|
||||||
|
|
||||||
while true;
|
|
||||||
do
|
|
||||||
statustext
|
|
||||||
sleep $TIMING
|
|
||||||
done
|
|
||||||
362
src/barwin.c
362
src/barwin.c
@ -1,107 +1,345 @@
|
|||||||
/*
|
/*
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
* barwin.c
|
||||||
* For license, see COPYING.
|
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
|
||||||
*/
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of the nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "wmfs.h"
|
#include "wmfs.h"
|
||||||
#include "barwin.h"
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
/** Create a barwin
|
/** Create a BarWindow
|
||||||
* \param parent Parent window of the BarWindow
|
* \param parent Parent window of the BarWindow
|
||||||
* \param x X position
|
* \param x X position
|
||||||
* \param y Y position
|
* \param y Y position
|
||||||
* \param w barwin Width
|
* \param w BarWindow Width
|
||||||
* \param h barwin Height
|
* \param h BarWindow Height
|
||||||
* \param color barwin color
|
* \param color BarWindow color
|
||||||
* \param entermask bool for know if the EnterMask mask is needed
|
* \param entermask Bool for know if the EnterMask mask is needed
|
||||||
* \return The BarWindow pointer
|
* \return The BarWindow pointer
|
||||||
*/
|
*/
|
||||||
struct barwin*
|
BarWindow*
|
||||||
barwin_new(Window parent, int x, int y, int w, int h, Color fg, Color bg, bool entermask)
|
barwin_create(Window parent,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
uint w,
|
||||||
|
uint h,
|
||||||
|
uint bg,
|
||||||
|
char *fg,
|
||||||
|
Bool entermask,
|
||||||
|
Bool stipple,
|
||||||
|
Bool border)
|
||||||
{
|
{
|
||||||
struct barwin *b = (struct barwin*)xcalloc(1, sizeof(struct barwin));
|
XSetWindowAttributes at;
|
||||||
XSetWindowAttributes at =
|
BarWindow *bw;
|
||||||
{
|
|
||||||
.override_redirect = true,
|
/* Allocate memory */
|
||||||
.background_pixmap = ParentRelative,
|
bw = zcalloc(sizeof(*bw));
|
||||||
.event_mask = BARWIN_MASK
|
|
||||||
};
|
/* Barwin attributes */
|
||||||
|
at.override_redirect = True;
|
||||||
|
at.background_pixmap = ParentRelative;
|
||||||
|
at.event_mask = SubstructureRedirectMask|SubstructureNotifyMask
|
||||||
|
|ButtonMask|MouseMask
|
||||||
|
|ExposureMask|VisibilityChangeMask
|
||||||
|
|StructureNotifyMask|SubstructureRedirectMask;
|
||||||
|
|
||||||
if(entermask)
|
if(entermask)
|
||||||
at.event_mask |= BARWIN_ENTERMASK;
|
at.event_mask |= EnterWindowMask|LeaveWindowMask|FocusChangeMask;
|
||||||
|
|
||||||
/* Create window */
|
/* Create window */
|
||||||
b->win = XCreateWindow(W->dpy, parent,
|
bw->win = XCreateWindow(dpy, parent, x, y, w, h, 0, DefaultDepth(dpy, SCREEN),
|
||||||
x, y, w, h,
|
CopyFromParent, DefaultVisual(dpy, SCREEN),
|
||||||
0, W->xdepth,
|
CWOverrideRedirect | CWBackPixmap | CWEventMask, &at);
|
||||||
CopyFromParent,
|
bw->dr = XCreatePixmap(dpy, parent, w, h, DefaultDepth(dpy, SCREEN));
|
||||||
DefaultVisual(W->dpy, W->xscreen),
|
|
||||||
BARWIN_WINCW,
|
|
||||||
&at);
|
|
||||||
|
|
||||||
b->dr = XCreatePixmap(W->dpy, parent, w, h, W->xdepth);
|
/* His border */
|
||||||
|
if(border)
|
||||||
|
{
|
||||||
|
bw->bord = True;
|
||||||
|
bw->border.light = color_shade(bg, conf.colors.bar_light_shade);
|
||||||
|
bw->border.dark = color_shade(bg, conf.colors.bar_dark_shade);
|
||||||
|
|
||||||
|
CWIN(bw->border.left, bw->win, 0, 0, SHADH, h, 0, CWBackPixel, bg, &at);
|
||||||
|
CWIN(bw->border.top, bw->win, 0, 0, w, SHADH, 0, CWBackPixel, bg, &at);
|
||||||
|
CWIN(bw->border.bottom, bw->win, 0, h - SHADH, w, SHADH, 0, CWBackPixel, bg, &at);
|
||||||
|
CWIN(bw->border.right, bw->win, w - SHADH, 0, SHADH, h, 0, CWBackPixel, bg, &at);
|
||||||
|
}
|
||||||
|
|
||||||
/* Property */
|
/* Property */
|
||||||
b->geo.x = x;
|
bw->geo.x = x;
|
||||||
b->geo.y = y;
|
bw->geo.y = y;
|
||||||
b->geo.w = w;
|
bw->geo.width = w;
|
||||||
b->geo.h = h;
|
bw->geo.height = h;
|
||||||
b->bg = bg;
|
bw->bg = bg;
|
||||||
b->fg = fg;
|
bw->fg = fg;
|
||||||
|
bw->stipple = stipple;
|
||||||
|
bw->stipple_color = -1;
|
||||||
|
|
||||||
SLIST_INIT(&b->mousebinds);
|
return bw;
|
||||||
SLIST_INIT(&b->statusmousebinds);
|
|
||||||
|
|
||||||
/* Attach */
|
|
||||||
SLIST_INSERT_HEAD(&W->h.barwin, b, next);
|
|
||||||
|
|
||||||
return b;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Delete a barwin
|
/** Draw text in a Barwindow
|
||||||
* \param bw barwin pointer
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
barwin_remove(struct barwin *b)
|
barwin_draw_text(BarWindow *bw, int x, int y, char *text)
|
||||||
{
|
{
|
||||||
SLIST_REMOVE(&W->h.barwin, b, barwin, next);
|
if(!text)
|
||||||
|
return;
|
||||||
|
|
||||||
XSelectInput(W->dpy, b->win, NoEventMask);
|
/* Background color of the text if there is stipple */
|
||||||
XDestroyWindow(W->dpy, b->win);
|
if(bw->stipple)
|
||||||
XFreePixmap(W->dpy, b->dr);
|
draw_rectangle(bw->dr, x - 4, 0, textw(text) + 8, bw->geo.height, bw->bg);
|
||||||
|
|
||||||
free(b);
|
/* Draw text */
|
||||||
|
draw_text(bw->dr, x, y, bw->fg, text);
|
||||||
|
|
||||||
|
barwin_refresh(bw);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Resize a barwin
|
/** Draw text in a Barwindow
|
||||||
* \param bw barwin pointer
|
*/
|
||||||
|
void
|
||||||
|
barwin_draw_image_ofset_text(BarWindow *bw, int x, int y, char *text, int x_image_ofset, int y_image_ofset)
|
||||||
|
{
|
||||||
|
if(!text)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Background color of the text if there is stipple */
|
||||||
|
if(bw->stipple)
|
||||||
|
draw_rectangle(bw->dr, x - 4, 0, textw(text) + 8, bw->geo.height, bw->bg);
|
||||||
|
|
||||||
|
/* Draw text */
|
||||||
|
draw_image_ofset_text(bw->dr, x, y, bw->fg, text, x_image_ofset, y_image_ofset);
|
||||||
|
|
||||||
|
barwin_refresh(bw);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
barwin_color_set(BarWindow *bw, uint bg, char *fg)
|
||||||
|
{
|
||||||
|
CHECK(bw);
|
||||||
|
|
||||||
|
bw->bg = bg;
|
||||||
|
bw->fg = fg;
|
||||||
|
|
||||||
|
if(bw->bord)
|
||||||
|
{
|
||||||
|
bw->border.light = color_shade(bg, conf.colors.bar_light_shade);
|
||||||
|
bw->border.dark = color_shade(bg, conf.colors.bar_dark_shade);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Delete a BarWindow
|
||||||
|
* \param bw BarWindow pointer
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
barwin_delete(BarWindow *bw)
|
||||||
|
{
|
||||||
|
CHECK(bw);
|
||||||
|
|
||||||
|
XSelectInput(dpy, bw->win, NoEventMask);
|
||||||
|
XDestroyWindow(dpy, bw->win);
|
||||||
|
XFreePixmap(dpy, bw->dr);
|
||||||
|
free(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->mapped);
|
||||||
|
|
||||||
|
XMapWindow(dpy, bw->win);
|
||||||
|
|
||||||
|
bw->mapped = True;
|
||||||
|
|
||||||
|
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->mapped);
|
||||||
|
|
||||||
|
XUnmapWindow(dpy, bw->win);
|
||||||
|
|
||||||
|
bw->mapped = False;
|
||||||
|
|
||||||
|
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
|
||||||
|
* \param y Y poistion
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
barwin_move(BarWindow *bw, int x, int y)
|
||||||
|
{
|
||||||
|
if(!bw || (bw->geo.x == x && bw->geo.y == y))
|
||||||
|
return;
|
||||||
|
|
||||||
|
XMoveWindow(dpy, bw->win, (bw->geo.x = x), (bw->geo.y = y));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Resize a BarWindow
|
||||||
|
* \param bw BarWindow pointer
|
||||||
* \param w Width
|
* \param w Width
|
||||||
* \param h Height
|
* \param h Height
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
barwin_resize(struct barwin *b, int w, int h)
|
barwin_resize(BarWindow *bw, uint w, uint h)
|
||||||
{
|
{
|
||||||
|
if(!bw || (bw->geo.width == w && bw->geo.height == h))
|
||||||
|
return;
|
||||||
|
|
||||||
|
bw->geo.width = w;
|
||||||
|
bw->geo.height = h;
|
||||||
|
XFreePixmap(dpy, bw->dr);
|
||||||
|
|
||||||
/* Frame */
|
/* Frame */
|
||||||
XFreePixmap(W->dpy, b->dr);
|
bw->dr = XCreatePixmap(dpy, ROOT,
|
||||||
|
w - ((bw->bord) ? SHADH : 0),
|
||||||
|
h - ((bw->bord) ? SHADH : 0),
|
||||||
|
DefaultDepth(dpy, SCREEN));
|
||||||
|
|
||||||
b->dr = XCreatePixmap(W->dpy, W->root, w, h, W->xdepth);
|
XResizeWindow(dpy, bw->win, w, h);
|
||||||
|
|
||||||
b->geo.w = w;
|
/* Border */
|
||||||
b->geo.h = h;
|
if(bw->bord)
|
||||||
|
{
|
||||||
|
XResizeWindow(dpy, bw->border.left, SHADH, h);
|
||||||
|
XResizeWindow(dpy, bw->border.top, w, SHADH);
|
||||||
|
XResizeWindow(dpy, bw->border.bottom, w, SHADH);
|
||||||
|
XMoveResizeWindow(dpy, bw->border.right, w - SHADH, 0, SHADH, h);
|
||||||
|
}
|
||||||
|
|
||||||
XResizeWindow(W->dpy, b->win, w, h);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Refresh the barwin Color
|
/** Refresh the BarWindow Color
|
||||||
* \param bw barwin pointer
|
* \param bw BarWindow pointer
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
barwin_refresh_color(struct barwin *b)
|
barwin_refresh_color(BarWindow *bw)
|
||||||
{
|
{
|
||||||
XSetForeground(W->dpy, W->gc, b->bg);
|
CHECK(bw);
|
||||||
XFillRectangle(W->dpy, b->dr, W->gc, 0, 0, b->geo.w, b->geo.h);
|
|
||||||
|
draw_rectangle(bw->dr, 0, 0, bw->geo.width, bw->geo.height, bw->bg);
|
||||||
|
|
||||||
|
if(bw->stipple)
|
||||||
|
{
|
||||||
|
XSetForeground(dpy, gc_stipple, ((bw->stipple_color != (uint)-1) ? (long)bw->stipple_color : getcolor(bw->fg)));
|
||||||
|
XFillRectangle(dpy, bw->dr, gc_stipple, 3, 2, bw->geo.width - 6, bw->geo.height - 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bw->bord)
|
||||||
|
{
|
||||||
|
XSetWindowBackground(dpy, bw->border.left, bw->border.light);
|
||||||
|
XSetWindowBackground(dpy, bw->border.top, bw->border.light);
|
||||||
|
XSetWindowBackground(dpy, bw->border.bottom, bw->border.dark);
|
||||||
|
XSetWindowBackground(dpy, bw->border.right, bw->border.dark);
|
||||||
|
|
||||||
|
XClearWindow(dpy, bw->border.left);
|
||||||
|
XClearWindow(dpy, bw->border.top);
|
||||||
|
XClearWindow(dpy, bw->border.bottom);
|
||||||
|
XClearWindow(dpy, bw->border.right);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Refresh the BarWindow
|
||||||
|
* \param bw BarWindow pointer
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
barwin_refresh(BarWindow *bw)
|
||||||
|
{
|
||||||
|
if(!bw || !bw->dr || !bw->win)
|
||||||
|
return;
|
||||||
|
|
||||||
|
XCopyArea(dpy, bw->dr, bw->win, gc, 0, 0, bw->geo.width, bw->geo.height, 0, 0);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|||||||
38
src/barwin.h
38
src/barwin.h
@ -1,38 +0,0 @@
|
|||||||
/*
|
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
|
||||||
* For license, see COPYING.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BARWIN_H
|
|
||||||
#define BARWIN_H
|
|
||||||
|
|
||||||
#include "wmfs.h"
|
|
||||||
|
|
||||||
#define BARWIN_MASK \
|
|
||||||
(SubstructureRedirectMask | SubstructureNotifyMask \
|
|
||||||
| ButtonMask | MouseMask | ExposureMask | VisibilityChangeMask \
|
|
||||||
| StructureNotifyMask)
|
|
||||||
|
|
||||||
#define BARWIN_ENTERMASK (EnterWindowMask | LeaveWindowMask | FocusChangeMask)
|
|
||||||
#define BARWIN_WINCW (CWOverrideRedirect | CWBackPixmap | CWEventMask)
|
|
||||||
|
|
||||||
#define barwin_delete_subwin(b) XDestroySubwindows(W->dpy, b->win)
|
|
||||||
#define barwin_map_subwin(b) XMapSubwindows(W->dpy, b->win)
|
|
||||||
#define barwin_unmap_subwin(b) XUnmapSubwindows(W->dpy, b->win)
|
|
||||||
#define barwin_refresh(b) XCopyArea(W->dpy, b->dr, b->win, W->gc, 0, 0, b->geo.w, b->geo.h, 0, 0)
|
|
||||||
#define barwin_map(b) XMapWindow(W->dpy, b->win);
|
|
||||||
#define barwin_unmap(b) XUnmapWindow(W->dpy, b->win);
|
|
||||||
#define barwin_reparent(b, w) XReparentWindow(W->dpy, b->win, w, 0, 0);
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
barwin_move(struct barwin *b, int x, int y)
|
|
||||||
{
|
|
||||||
XMoveWindow(W->dpy, b->win, (b->geo.x = x), (b->geo.y = y));
|
|
||||||
}
|
|
||||||
|
|
||||||
struct barwin* barwin_new(Window parent, int x, int y, int w, int h, Color fg, Color bg, bool entermask);
|
|
||||||
void barwin_remove(struct barwin *b);
|
|
||||||
void barwin_resize(struct barwin *b, int w, int h);
|
|
||||||
void barwin_refresh_color(struct barwin *b);
|
|
||||||
|
|
||||||
#endif /* BARWIN_H */
|
|
||||||
2834
src/client.c
2834
src/client.c
File diff suppressed because it is too large
Load Diff
217
src/client.h
217
src/client.h
@ -1,217 +0,0 @@
|
|||||||
/*
|
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
|
||||||
* For license, see COPYING.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef CLIENT_H
|
|
||||||
#define CLIENT_H
|
|
||||||
|
|
||||||
#include <X11/XKBlib.h>
|
|
||||||
|
|
||||||
#include "wmfs.h"
|
|
||||||
#include "layout.h"
|
|
||||||
#include "ewmh.h"
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
#define TCLIENT_CHECK(C) (C->flags & CLIENT_TABBED && !(C->flags & CLIENT_TABMASTER))
|
|
||||||
|
|
||||||
/* SLIST_FOREACH for client with no free client */
|
|
||||||
#define FOREACH_NFCLIENT(V, H, F) \
|
|
||||||
SLIST_FOREACH(V, H, F) \
|
|
||||||
if(!(V->flags & CLIENT_FREE))
|
|
||||||
|
|
||||||
/* Are two clients compatibles ? (to be tabbed together) */
|
|
||||||
#define COMPCLIENT(C1, C2) ((C1->flags & CLIENT_IGNORE_TAG) == (C2->flags & CLIENT_IGNORE_TAG))
|
|
||||||
|
|
||||||
void client_configure(struct client *c);
|
|
||||||
struct client *client_gb_win(Window w);
|
|
||||||
struct client *client_gb_frame(Window w);
|
|
||||||
struct client *client_gb_pos(struct tag *t, int x, int y);
|
|
||||||
struct client *client_gb_titlebar(Window w);
|
|
||||||
struct client *client_next_with_pos(struct client *bc, enum position p);
|
|
||||||
void client_swap2(struct client *c1, struct client *c2);
|
|
||||||
void client_swap(struct client *c, enum position p);
|
|
||||||
#define CCOL(c) (c == W->client ? &c->scol : &c->ncol)
|
|
||||||
void client_frame_update(struct client *c, struct colpair *cp);
|
|
||||||
void client_tab_pull(struct client *c);
|
|
||||||
void _client_tab(struct client *c, struct client *cm);
|
|
||||||
void client_tab_focus(struct client *c);
|
|
||||||
void client_focus(struct client *c);
|
|
||||||
void uicb_client_focus_click(Uicb);
|
|
||||||
void client_get_name(struct client *c);
|
|
||||||
void client_close(struct client *c);
|
|
||||||
void uicb_client_close(Uicb cmd);
|
|
||||||
struct client *client_new(Window w, XWindowAttributes *wa, bool scan);
|
|
||||||
void client_geo_hints(struct geo *g, int *s);
|
|
||||||
void client_get_sizeh(struct client *c);
|
|
||||||
bool client_winsize(struct client *c, struct geo *geo);
|
|
||||||
void client_moveresize(struct client *c, struct geo *g);
|
|
||||||
void client_place_at_mouse(struct client *c);
|
|
||||||
void client_maximize(struct client *c);
|
|
||||||
void client_fac_resize(struct client *c, enum position p, int fac);
|
|
||||||
void client_fac_adjust(struct client *c);
|
|
||||||
void client_remove(struct client *c);
|
|
||||||
void client_free(void);
|
|
||||||
void _fac_resize(struct client *c, enum position p, int fac);
|
|
||||||
void client_apply_tgeo(struct tag *t);
|
|
||||||
|
|
||||||
#define CPROP_LOC 0x01
|
|
||||||
#define CPROP_FLAG 0x02
|
|
||||||
#define CPROP_GEO 0x04
|
|
||||||
#define CPROP_TAB 0x08
|
|
||||||
void client_update_props(struct client *c, Flags f);
|
|
||||||
|
|
||||||
void client_fac_hint(struct client *c);
|
|
||||||
void uicb_client_untab(Uicb cmd);
|
|
||||||
void uicb_client_toggle_free(Uicb cmd);
|
|
||||||
void uicb_client_toggle_ignore_tag(Uicb cmd);
|
|
||||||
void uicb_client_tab_next_opened(Uicb cmd);
|
|
||||||
|
|
||||||
/* Generated */
|
|
||||||
void uicb_client_resize_Right(Uicb);
|
|
||||||
void uicb_client_resize_Left(Uicb);
|
|
||||||
void uicb_client_resize_Top(Uicb);
|
|
||||||
void uicb_client_resize_Bottom(Uicb);
|
|
||||||
void uicb_client_focus_Right(Uicb);
|
|
||||||
void uicb_client_focus_Left(Uicb);
|
|
||||||
void uicb_client_focus_Top(Uicb);
|
|
||||||
void uicb_client_focus_Bottom(Uicb);
|
|
||||||
void uicb_client_tab_Right(Uicb);
|
|
||||||
void uicb_client_tab_Left(Uicb);
|
|
||||||
void uicb_client_tab_Top(Uicb);
|
|
||||||
void uicb_client_tab_Bottom(Uicb);
|
|
||||||
void uicb_client_swap_Right(Uicb);
|
|
||||||
void uicb_client_swap_Left(Uicb);
|
|
||||||
void uicb_client_swap_Top(Uicb);
|
|
||||||
void uicb_client_swap_Bottom(Uicb);
|
|
||||||
void uicb_client_focus_next(Uicb);
|
|
||||||
void uicb_client_focus_prev(Uicb);
|
|
||||||
void uicb_client_swapsel_next(Uicb);
|
|
||||||
void uicb_client_swapsel_prev(Uicb);
|
|
||||||
void uicb_client_focus_next_tab(Uicb);
|
|
||||||
void uicb_client_focus_prev_tab(Uicb);
|
|
||||||
|
|
||||||
static inline struct client*
|
|
||||||
client_next(struct client *c)
|
|
||||||
{
|
|
||||||
return (SLIST_NEXT(c, tnext)
|
|
||||||
? SLIST_NEXT(c, tnext)
|
|
||||||
: SLIST_FIRST(&c->tag->clients));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct client*
|
|
||||||
client_prev(struct client *c)
|
|
||||||
{
|
|
||||||
struct client *cc = SLIST_FIRST(&c->tag->clients);
|
|
||||||
|
|
||||||
while(SLIST_NEXT(cc, tnext) && SLIST_NEXT(cc, tnext) != c)
|
|
||||||
cc = SLIST_NEXT(cc, tnext);
|
|
||||||
|
|
||||||
return cc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct client*
|
|
||||||
client_next_tab(struct client *c)
|
|
||||||
{
|
|
||||||
struct client *n = client_next(c);
|
|
||||||
|
|
||||||
if(!(c->flags & CLIENT_TABMASTER))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
while((!(n->flags & CLIENT_TABBED) || n->tabmaster != c) && n != c)
|
|
||||||
n = client_next(n);
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct client*
|
|
||||||
client_prev_tab(struct client *c)
|
|
||||||
{
|
|
||||||
struct client *p = client_prev(c);
|
|
||||||
|
|
||||||
if(!(c->flags & CLIENT_TABMASTER))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
while((!(p->flags & CLIENT_TABBED) || p->tabmaster != c) && p != c)
|
|
||||||
p = client_prev(p);
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct client*
|
|
||||||
client_tab_next(struct client *c)
|
|
||||||
{
|
|
||||||
return (c && c->tabmaster ? c->tabmaster : c);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
client_map(struct client *c)
|
|
||||||
{
|
|
||||||
if(!(c->flags & CLIENT_MAPPED))
|
|
||||||
{
|
|
||||||
WIN_STATE(c->frame, Map);
|
|
||||||
WIN_STATE(c->win, Map);
|
|
||||||
ewmh_set_wm_state(c->win, NormalState);
|
|
||||||
c->flags ^= CLIENT_MAPPED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
client_unmap(struct client *c)
|
|
||||||
{
|
|
||||||
if(c->flags & CLIENT_MAPPED)
|
|
||||||
{
|
|
||||||
WIN_STATE(c->frame, Unmap);
|
|
||||||
WIN_STATE(c->win, Unmap);
|
|
||||||
ewmh_set_wm_state(c->win, IconicState);
|
|
||||||
c->flags ^= CLIENT_MAPPED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
clients_arrange_map(void)
|
|
||||||
{
|
|
||||||
struct client *c;
|
|
||||||
|
|
||||||
SLIST_FOREACH(c, &W->h.client, next)
|
|
||||||
{
|
|
||||||
if(c->tag == c->screen->seltag && !(c->flags & CLIENT_TABBED))
|
|
||||||
client_map(c);
|
|
||||||
else
|
|
||||||
client_unmap(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
clients_tag_arrange_map(struct tag *t)
|
|
||||||
{
|
|
||||||
struct client *c;
|
|
||||||
void (*sfunc)(struct client*)
|
|
||||||
= (t == t->screen->seltag ? client_map : client_unmap);
|
|
||||||
|
|
||||||
SLIST_FOREACH(c, &t->clients, tnext)
|
|
||||||
sfunc(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct client*
|
|
||||||
client_get_larger(struct tag *t, bool ignoring_tag)
|
|
||||||
{
|
|
||||||
struct client *c, *lc = NULL;
|
|
||||||
int tmp, l = 0;
|
|
||||||
|
|
||||||
FOREACH_NFCLIENT(c, &t->clients, tnext)
|
|
||||||
{
|
|
||||||
if((tmp = (c->geo.w + c->geo.h)) > l && (c->flags & CLIENT_IGNORE_TAG) == ignoring_tag)
|
|
||||||
{
|
|
||||||
l = tmp;
|
|
||||||
lc = c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(lc && (lc->flags & CLIENT_TABBED))
|
|
||||||
lc = lc->tabmaster;
|
|
||||||
|
|
||||||
return lc;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* CLIENT_H */
|
|
||||||
223
src/color.c
Normal file
223
src/color.c
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
/*
|
||||||
|
* color.c
|
||||||
|
* Copyright © 2011 Brian Mock <mock.brian@gmail.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of the nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "wmfs.h"
|
||||||
|
|
||||||
|
/** Clamp a number x within the range [a, b].
|
||||||
|
* \param x the number which to clamp
|
||||||
|
* \param a the lowest possible value
|
||||||
|
* \param b the highest possible value
|
||||||
|
* \return the clamped number
|
||||||
|
*/
|
||||||
|
static double
|
||||||
|
color_clamp(double x, double a, double b)
|
||||||
|
{
|
||||||
|
if(x < a)
|
||||||
|
return a;
|
||||||
|
else if(x > b)
|
||||||
|
return b;
|
||||||
|
else
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Pack a triplet of RGB values into a single uint
|
||||||
|
* \param r the red value
|
||||||
|
* \param g the green value
|
||||||
|
* \param b the blue value
|
||||||
|
* \return the packed RGB value
|
||||||
|
*/
|
||||||
|
static uint
|
||||||
|
color_pack_rgb(uint r, uint g, uint b)
|
||||||
|
{
|
||||||
|
return (r << 16) | (g << 8) | b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Unpack an RGB uint into three separate values
|
||||||
|
* \param rgb the packed color
|
||||||
|
* \param r a pointer to a uint where the red value will be stored
|
||||||
|
* \param g a pointer to a uint where the green value will be stored
|
||||||
|
* \param b a pointer to a uint where the blue value will be stored
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
color_unpack_rgb(uint rgb, uint *r, uint *g, uint *b)
|
||||||
|
{
|
||||||
|
*r = (rgb >> 16) & 0xFF;
|
||||||
|
*g = (rgb >> 8) & 0xFF;
|
||||||
|
*b = rgb & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Convert unpacked RGB values into HSL, storing in the doubles referenced
|
||||||
|
* by the pointers h, s, l
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
color_rgb_to_hsl(uint xr, uint xg, uint xb, double *h, double *s, double *l)
|
||||||
|
{
|
||||||
|
double r = xr/255.0;
|
||||||
|
double g = xg/255.0;
|
||||||
|
double b = xb/255.0;
|
||||||
|
|
||||||
|
double v;
|
||||||
|
double m;
|
||||||
|
double vm;
|
||||||
|
double r2, g2, b2;
|
||||||
|
|
||||||
|
*h = 0;
|
||||||
|
*s = 0;
|
||||||
|
*l = 0;
|
||||||
|
|
||||||
|
/* v is max(r, g, b)
|
||||||
|
* m is min(r, g, b)
|
||||||
|
*/
|
||||||
|
v = r > g ? r : g;
|
||||||
|
v = v > b ? v : b;
|
||||||
|
m = r < g ? r : g;
|
||||||
|
m = m < b ? m : b;
|
||||||
|
|
||||||
|
*l = (m + v)/2.0;
|
||||||
|
|
||||||
|
if(*l <= 0.0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
vm = v - m;
|
||||||
|
*s = vm;
|
||||||
|
|
||||||
|
if(*s > 0.0)
|
||||||
|
*s /= (*l <= 0.5) ? (v + m) : (2.0 - v - m);
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
|
r2 = (v - r)/vm;
|
||||||
|
g2 = (v - g)/vm;
|
||||||
|
b2 = (v - b)/vm;
|
||||||
|
|
||||||
|
if(r == v)
|
||||||
|
*h = (g == m ? 5.0 + b2 : 1.0 - g2);
|
||||||
|
else if(g == v)
|
||||||
|
*h = (b == m ? 1.0 + r2 : 3.0 - b2);
|
||||||
|
else
|
||||||
|
*h = (r == m ? 3.0 + g2 : 5.0 - r2);
|
||||||
|
|
||||||
|
*h /= 6.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Convert h, s, l values to RGB and store them in the three uint
|
||||||
|
* referenced by the last three parameters.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
color_hsl_to_rgb(double h, double sl, double l, uint *rx, uint *gx, uint *bx)
|
||||||
|
{
|
||||||
|
double v;
|
||||||
|
double r,g,b;
|
||||||
|
|
||||||
|
r = l;
|
||||||
|
g = l;
|
||||||
|
b = l;
|
||||||
|
v = (l <= 0.5) ? (l * (1.0 + sl)) : (l + sl - l * sl);
|
||||||
|
if(v > 0)
|
||||||
|
{
|
||||||
|
double m;
|
||||||
|
double sv;
|
||||||
|
int sextant;
|
||||||
|
double fract, vsf, mid1, mid2;
|
||||||
|
|
||||||
|
m = l + l - v;
|
||||||
|
sv = (v - m ) / v;
|
||||||
|
h *= 6.0;
|
||||||
|
sextant = (int) h;
|
||||||
|
fract = h - sextant;
|
||||||
|
vsf = v * sv * fract;
|
||||||
|
mid1 = m + vsf;
|
||||||
|
mid2 = v - vsf;
|
||||||
|
switch(sextant)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
r = v;
|
||||||
|
g = mid1;
|
||||||
|
b = m;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
r = mid2;
|
||||||
|
g = v;
|
||||||
|
b = m;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
r = m;
|
||||||
|
g = v;
|
||||||
|
b = mid1;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
r = m;
|
||||||
|
g = mid2;
|
||||||
|
b = v;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
r = mid1;
|
||||||
|
g = m;
|
||||||
|
b = v;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
r = v;
|
||||||
|
g = m;
|
||||||
|
b = mid2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*rx = r * 255.0;
|
||||||
|
*gx = g * 255.0;
|
||||||
|
*bx = b * 255.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Shades a color by the amount. This works by converting a packed RGB
|
||||||
|
* color to HSL, adding the amount to the lightness,
|
||||||
|
* and then converting back to RGB. 1.0 is max lightness, 0.0 is min lightness.
|
||||||
|
* \param shadeVal the amount to shade the lightness by.
|
||||||
|
* \return the shaded color
|
||||||
|
*/
|
||||||
|
uint
|
||||||
|
color_shade(uint rgb, double shadeVal)
|
||||||
|
{
|
||||||
|
uint r, g, b;
|
||||||
|
double h, s, l;
|
||||||
|
|
||||||
|
color_unpack_rgb(rgb, &r, &g, &b);
|
||||||
|
color_rgb_to_hsl(r, g, b, &h, &s, &l);
|
||||||
|
|
||||||
|
l += shadeVal;
|
||||||
|
|
||||||
|
l = color_clamp(l, 0, 1);
|
||||||
|
|
||||||
|
color_hsl_to_rgb(h, s, l, &r, &g, &b);
|
||||||
|
rgb = color_pack_rgb(r, g, b);
|
||||||
|
|
||||||
|
return rgb;
|
||||||
|
}
|
||||||
1065
src/config.c
1065
src/config.c
File diff suppressed because it is too large
Load Diff
167
src/config.h
167
src/config.h
@ -1,167 +0,0 @@
|
|||||||
/*
|
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
|
||||||
* For license, see COPYING.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef CONFIG_H
|
|
||||||
#define CONFIG_H
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
|
|
||||||
#include "wmfs.h"
|
|
||||||
#include "util.h"
|
|
||||||
#include "tag.h"
|
|
||||||
#include "client.h"
|
|
||||||
#include "status.h"
|
|
||||||
#include "mouse.h"
|
|
||||||
#include "screen.h"
|
|
||||||
#include "infobar.h"
|
|
||||||
#include "launcher.h"
|
|
||||||
|
|
||||||
#define THEME_DEFAULT (SLIST_FIRST(&W->h.theme))
|
|
||||||
|
|
||||||
static const struct { char *name; void (*func)(Uicb cmd); } uicb_list[] =
|
|
||||||
{
|
|
||||||
/* Sys */
|
|
||||||
{ "spawn", uicb_spawn },
|
|
||||||
{ "quit", uicb_quit },
|
|
||||||
{ "reload", uicb_reload },
|
|
||||||
|
|
||||||
/* Tag */
|
|
||||||
{ "tag_set", uicb_tag_set },
|
|
||||||
{ "tag", uicb_tag_set_with_name },
|
|
||||||
{ "tag_next", uicb_tag_next },
|
|
||||||
{ "tag_prev", uicb_tag_prev },
|
|
||||||
{ "tag_client", uicb_tag_client },
|
|
||||||
{ "tag_client_and_set", uicb_tag_client_and_set },
|
|
||||||
{ "tag_move_client_next", uicb_tag_move_client_next },
|
|
||||||
{ "tag_move_client_prev", uicb_tag_move_client_prev },
|
|
||||||
{ "tag_click", uicb_tag_click },
|
|
||||||
{ "tag_new", uicb_tag_new },
|
|
||||||
{ "tag_del", uicb_tag_del },
|
|
||||||
|
|
||||||
/* Layout */
|
|
||||||
{ "layout_vmirror", uicb_layout_vmirror },
|
|
||||||
{ "layout_hmirror", uicb_layout_hmirror },
|
|
||||||
{ "layout_rotate_left", uicb_layout_rotate_left },
|
|
||||||
{ "layout_rotate_right", uicb_layout_rotate_right },
|
|
||||||
{ "layout_prev_set", uicb_layout_prev_set },
|
|
||||||
{ "layout_next_set", uicb_layout_next_set },
|
|
||||||
{ "layout_integrate_left", uicb_layout_integrate_Left },
|
|
||||||
{ "layout_integrate_right", uicb_layout_integrate_Right },
|
|
||||||
{ "layout_integrate_top", uicb_layout_integrate_Top },
|
|
||||||
{ "layout_integrate_bottom", uicb_layout_integrate_Bottom },
|
|
||||||
|
|
||||||
/* Client */
|
|
||||||
{ "client_close", uicb_client_close },
|
|
||||||
{ "client_resize_right", uicb_client_resize_Right },
|
|
||||||
{ "client_resize_left", uicb_client_resize_Left },
|
|
||||||
{ "client_resize_top", uicb_client_resize_Top },
|
|
||||||
{ "client_resize_bottom", uicb_client_resize_Bottom },
|
|
||||||
{ "client_focus_right", uicb_client_focus_Right },
|
|
||||||
{ "client_focus_left", uicb_client_focus_Left },
|
|
||||||
{ "client_focus_top", uicb_client_focus_Top },
|
|
||||||
{ "client_focus_bottom", uicb_client_focus_Bottom },
|
|
||||||
{ "client_tab_right", uicb_client_tab_Right },
|
|
||||||
{ "client_tab_left", uicb_client_tab_Left },
|
|
||||||
{ "client_tab_top", uicb_client_tab_Top },
|
|
||||||
{ "client_tab_bottom", uicb_client_tab_Bottom },
|
|
||||||
{ "client_swap_right", uicb_client_swap_Right },
|
|
||||||
{ "client_swap_left", uicb_client_swap_Left },
|
|
||||||
{ "client_swap_top", uicb_client_swap_Top },
|
|
||||||
{ "client_swap_bottom", uicb_client_swap_Bottom },
|
|
||||||
{ "client_focus_next", uicb_client_focus_next },
|
|
||||||
{ "client_focus_prev", uicb_client_focus_prev },
|
|
||||||
{ "client_swap_next", uicb_client_swapsel_next },
|
|
||||||
{ "client_swap_prev", uicb_client_swapsel_prev },
|
|
||||||
{ "client_untab", uicb_client_untab },
|
|
||||||
{ "client_focus_next_tab", uicb_client_focus_next_tab },
|
|
||||||
{ "client_focus_prev_tab", uicb_client_focus_prev_tab },
|
|
||||||
{ "client_focus_click", uicb_client_focus_click },
|
|
||||||
{ "client_toggle_free", uicb_client_toggle_free },
|
|
||||||
{ "client_toggle_ignore_tag", uicb_client_toggle_ignore_tag },
|
|
||||||
{ "client_tab_next_opened", uicb_client_tab_next_opened },
|
|
||||||
|
|
||||||
/* Status */
|
|
||||||
{ "status" , uicb_status },
|
|
||||||
{ "status_surface", uicb_status_surface },
|
|
||||||
|
|
||||||
/* Infobar */
|
|
||||||
{ "infobar_toggle_hide", uicb_infobar_toggle_hide },
|
|
||||||
|
|
||||||
/* Mouse */
|
|
||||||
{ "mouse_resize", uicb_mouse_resize },
|
|
||||||
{ "mouse_move", uicb_mouse_move },
|
|
||||||
{ "mouse_swap", uicb_mouse_move },
|
|
||||||
{ "mouse_tab", uicb_mouse_tab },
|
|
||||||
|
|
||||||
/* Screen */
|
|
||||||
{ "screen_next", uicb_screen_next },
|
|
||||||
{ "screen_prev", uicb_screen_prev },
|
|
||||||
{ "screen_move_client_next", uicb_screen_move_client_next },
|
|
||||||
{ "screen_move_client_prev", uicb_screen_move_client_prev },
|
|
||||||
|
|
||||||
/* Launcher */
|
|
||||||
{ "launcher", uicb_launcher },
|
|
||||||
|
|
||||||
{ NULL, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline void*
|
|
||||||
uicb_name_func(Uicb name)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
for(; uicb_list[i].func; ++i)
|
|
||||||
if(!strcmp(name, uicb_list[i].name))
|
|
||||||
return uicb_list[i].func;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct { const char *name; KeySym keysym; } key_list[] =
|
|
||||||
{
|
|
||||||
{"Control", ControlMask },
|
|
||||||
{"Shift", ShiftMask },
|
|
||||||
{"Lock", LockMask },
|
|
||||||
{"Alt", Mod1Mask },
|
|
||||||
{"Mod1", Mod1Mask },
|
|
||||||
{"Mod2", Mod2Mask },
|
|
||||||
{"Mod3", Mod3Mask },
|
|
||||||
{"Mod4", Mod4Mask },
|
|
||||||
{"Super", Mod4Mask },
|
|
||||||
{"Home", Mod4Mask },
|
|
||||||
{"Mod5", Mod5Mask },
|
|
||||||
{NULL, NoSymbol }
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline KeySym
|
|
||||||
modkey_keysym(const char *name)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
for(; key_list[i].name; ++i)
|
|
||||||
if(!strcmp(name, key_list[i].name))
|
|
||||||
return key_list[i].keysym;
|
|
||||||
|
|
||||||
return NoSymbol;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct theme*
|
|
||||||
name_to_theme(const char *name)
|
|
||||||
{
|
|
||||||
struct theme *t;
|
|
||||||
|
|
||||||
SLIST_FOREACH(t, &W->h.theme, next)
|
|
||||||
if(!strcmp(t->name, name))
|
|
||||||
return t;
|
|
||||||
|
|
||||||
return THEME_DEFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void config_init(void);
|
|
||||||
|
|
||||||
#endif /* CONFIG_H */
|
|
||||||
232
src/draw.c
Normal file
232
src/draw.c
Normal file
@ -0,0 +1,232 @@
|
|||||||
|
/*
|
||||||
|
* draw.c
|
||||||
|
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of the nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "wmfs.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_IMLIB
|
||||||
|
/** Draw an image in a drawable
|
||||||
|
* \param dr Drawable
|
||||||
|
* \param x X position
|
||||||
|
* \param y Y position
|
||||||
|
* \param name Path of the image
|
||||||
|
*/
|
||||||
|
static void draw_image(Drawable dr, int x, int y, int w, int h, char *name)
|
||||||
|
{
|
||||||
|
Imlib_Image image;
|
||||||
|
|
||||||
|
if(!name)
|
||||||
|
return;
|
||||||
|
|
||||||
|
imlib_set_cache_size(2048 * 1024);
|
||||||
|
imlib_context_set_display(dpy);
|
||||||
|
imlib_context_set_visual(DefaultVisual(dpy, DefaultScreen(dpy)));
|
||||||
|
imlib_context_set_colormap(DefaultColormap(dpy, DefaultScreen(dpy)));
|
||||||
|
imlib_context_set_drawable(dr);
|
||||||
|
|
||||||
|
image = imlib_load_image(patht(name));
|
||||||
|
imlib_context_set_image(image);
|
||||||
|
|
||||||
|
if(w <= 0)
|
||||||
|
w = imlib_image_get_width();
|
||||||
|
|
||||||
|
if(h <= 0)
|
||||||
|
h = imlib_image_get_height();
|
||||||
|
|
||||||
|
if(image)
|
||||||
|
{
|
||||||
|
imlib_render_image_on_drawable_at_size(x, y, w, h);
|
||||||
|
imlib_free_image();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
warnx("Can't draw image: '%s'", name);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_IMLIB */
|
||||||
|
|
||||||
|
void
|
||||||
|
draw_text(Drawable d, int x, int y, char* fg, char *str)
|
||||||
|
{
|
||||||
|
draw_image_ofset_text(d, x, y, fg, str, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Draw a string in a Drawable
|
||||||
|
* \param d Drawable
|
||||||
|
* \param x X position
|
||||||
|
* \param y Y position
|
||||||
|
* \param fg Foreground text color
|
||||||
|
* \param pad Text padding
|
||||||
|
* \param str String that will be draw
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
draw_image_ofset_text(Drawable d, int x, int y, char* fg, char *str, int x_image_ofset, int y_image_ofset)
|
||||||
|
{
|
||||||
|
XftColor xftcolor;
|
||||||
|
XftDraw *xftd;
|
||||||
|
#ifdef HAVE_IMLIB
|
||||||
|
char *ostr = NULL;
|
||||||
|
int i, ni, sw = 0;
|
||||||
|
ImageAttr im[128];
|
||||||
|
size_t textlen;
|
||||||
|
#else
|
||||||
|
(void)x_image_ofset;
|
||||||
|
(void)y_image_ofset;
|
||||||
|
#endif /* HAVE_IMLIB */
|
||||||
|
|
||||||
|
if(!str)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* To draw image everywhere we can draw text */
|
||||||
|
#ifdef HAVE_IMLIB
|
||||||
|
|
||||||
|
ostr = xstrdup(str);
|
||||||
|
textlen = strlen(ostr);
|
||||||
|
|
||||||
|
if(strstr(str, "i["))
|
||||||
|
{
|
||||||
|
ni = parse_image_block(im, str);
|
||||||
|
|
||||||
|
if(infobar[conf.systray.screen].bar && d == infobar[conf.systray.screen].bar->dr)
|
||||||
|
sw = systray_get_width();
|
||||||
|
|
||||||
|
for(i = 0; i < ni; ++i)
|
||||||
|
draw_image(d, x_image_ofset + im[i].x - sw, y_image_ofset + im[i].y, im[i].w, im[i].h, im[i].name);
|
||||||
|
}
|
||||||
|
#endif /* HAVE_IMLIB */
|
||||||
|
|
||||||
|
/* Transform X Drawable -> Xft Drawable */
|
||||||
|
xftd = XftDrawCreate(dpy, d, DefaultVisual(dpy, SCREEN), DefaultColormap(dpy, SCREEN));
|
||||||
|
|
||||||
|
/* Alloc text color */
|
||||||
|
XftColorAllocName(dpy, DefaultVisual(dpy, SCREEN),
|
||||||
|
DefaultColormap(dpy, SCREEN), fg, &xftcolor);
|
||||||
|
|
||||||
|
XftDrawStringUtf8(xftd, &xftcolor, font, x, y, (FcChar8 *)str, strlen(str));
|
||||||
|
|
||||||
|
/* Free the text color and XftDraw */
|
||||||
|
XftColorFree(dpy, DefaultVisual(dpy, SCREEN), DefaultColormap(dpy, SCREEN), &xftcolor);
|
||||||
|
|
||||||
|
XftDrawDestroy(xftd);
|
||||||
|
|
||||||
|
#ifdef HAVE_IMLIB
|
||||||
|
if(strstr(ostr, "i["))
|
||||||
|
strncpy(str, ostr, textlen);
|
||||||
|
|
||||||
|
free(ostr);
|
||||||
|
#endif /* HAVE_IMLIB */
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Draw a Rectangle in a drawable
|
||||||
|
* \param dr Drawable
|
||||||
|
* \param x X position
|
||||||
|
* \param y Y position
|
||||||
|
* \param w Width
|
||||||
|
* \param h Height
|
||||||
|
* \param color Color of the rectangle
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
draw_rectangle(Drawable dr, int x, int y, uint w, uint h, uint color)
|
||||||
|
{
|
||||||
|
XRectangle r = { x, y, w, h };
|
||||||
|
|
||||||
|
XSetForeground(dpy, gc, color);
|
||||||
|
XFillRectangles(dpy, dr, gc, &r, 1);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Draw a Graph in a drawable
|
||||||
|
* \param dr Drawable
|
||||||
|
* \param x X position
|
||||||
|
* \param y Y position
|
||||||
|
* \param w Width
|
||||||
|
* \param h Height
|
||||||
|
* \param color Color of the graph
|
||||||
|
* \param data Array of bytes that will be draw
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
draw_graph(Drawable dr, int x, int y, uint w, uint h, uint color, char *data)
|
||||||
|
{
|
||||||
|
uint i;
|
||||||
|
|
||||||
|
XSetForeground(dpy, gc, color);
|
||||||
|
|
||||||
|
for(i = 0; i < w; ++i)
|
||||||
|
{
|
||||||
|
XRectangle r = { (x + i), (y + h - data[i]), 1, data[i] };
|
||||||
|
|
||||||
|
XFillRectangles(dpy, dr, gc, &r, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Calculates the text's size relatively to the font
|
||||||
|
* \param text Text string
|
||||||
|
* \return final text width
|
||||||
|
*/
|
||||||
|
ushort
|
||||||
|
textw(char *text)
|
||||||
|
{
|
||||||
|
XGlyphInfo gl;
|
||||||
|
#ifdef HAVE_IMLIB
|
||||||
|
char *ostr = NULL;
|
||||||
|
ImageAttr im[128];
|
||||||
|
size_t textlen;
|
||||||
|
#endif /* HAVE_IMLIB */
|
||||||
|
|
||||||
|
if(!text)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_IMLIB
|
||||||
|
|
||||||
|
ostr = xstrdup(text);
|
||||||
|
textlen = strlen(ostr);
|
||||||
|
|
||||||
|
if(strstr(text, "i["))
|
||||||
|
parse_image_block(im, text);
|
||||||
|
#endif /* HAVE_IMLIB */
|
||||||
|
|
||||||
|
XftTextExtentsUtf8(dpy, font, (FcChar8 *)text, strlen(text), &gl);
|
||||||
|
|
||||||
|
#ifdef HAVE_IMLIB
|
||||||
|
if(strstr(ostr, "i["))
|
||||||
|
strncpy(text, ostr, textlen);
|
||||||
|
|
||||||
|
free(ostr);
|
||||||
|
#endif /* HAVE_IMLIB */
|
||||||
|
|
||||||
|
return gl.width + font->descent;
|
||||||
|
}
|
||||||
113
src/draw.h
113
src/draw.h
@ -1,113 +0,0 @@
|
|||||||
/*
|
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
|
||||||
* For license, see COPYING.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef DRAW_H
|
|
||||||
#define DRAW_H
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_IMLIB2
|
|
||||||
#include <Imlib2.h>
|
|
||||||
#endif /* HAVE_IMLIB2 */
|
|
||||||
|
|
||||||
#include "wmfs.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "screen.h"
|
|
||||||
|
|
||||||
#define TEXTY(t, w) ((t->font.height - t->font.de) + ((w - t->font.height) >> 1))
|
|
||||||
#define PAD (8)
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
draw_text(Drawable d, struct theme *t, int x, int y, Color fg, const char *str)
|
|
||||||
{
|
|
||||||
XSetForeground(W->dpy, W->gc, fg);
|
|
||||||
XmbDrawString(W->dpy, d, t->font.fontset, W->gc, x, y, str, strlen(str));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
draw_rect(Drawable d, struct geo *g, Color bg)
|
|
||||||
{
|
|
||||||
XSetForeground(W->dpy, W->gc, bg);
|
|
||||||
XFillRectangle(W->dpy, d, W->gc, g->x, g->y, g->w, g->h);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_IMLIB2
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Draw image on drawable with g geo
|
|
||||||
* Require that the image was loaded with draw_image_load()
|
|
||||||
*/
|
|
||||||
static inline void
|
|
||||||
draw_image(Drawable d, struct geo *g)
|
|
||||||
{
|
|
||||||
imlib_context_set_drawable(d);
|
|
||||||
imlib_render_image_on_drawable_at_size(g->x, g->y, g->w, g->h);
|
|
||||||
imlib_free_image();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Load image, set it in imlib context, and return
|
|
||||||
* width & height as argument 2 & 3
|
|
||||||
*/
|
|
||||||
static inline void
|
|
||||||
draw_image_load(char *path, int *w, int *h)
|
|
||||||
{
|
|
||||||
Imlib_Image image = imlib_load_image(path);
|
|
||||||
|
|
||||||
imlib_context_set_image(image);
|
|
||||||
|
|
||||||
*w = imlib_image_get_width();
|
|
||||||
*h = imlib_image_get_height();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* HAVE_IMLIB2 */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For client use
|
|
||||||
*/
|
|
||||||
static inline void
|
|
||||||
draw_reversed_rect(Drawable dr, struct client *c, bool t)
|
|
||||||
{
|
|
||||||
struct geo *g = (t ? &c->tgeo : &c->geo);
|
|
||||||
struct geo *ug = &c->screen->ugeo;
|
|
||||||
int i = c->theme->client_border_width;
|
|
||||||
|
|
||||||
if(c->flags & CLIENT_FREE)
|
|
||||||
{
|
|
||||||
XDrawRectangle(W->dpy, dr, W->rgc,
|
|
||||||
ug->x + g->x + i,
|
|
||||||
ug->y + g->y + i,
|
|
||||||
g->w - (i << 1),
|
|
||||||
g->h - (i << 1));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
XDrawRectangle(W->dpy, dr, W->rgc,
|
|
||||||
ug->x + g->x + i + (W->padding >> 2),
|
|
||||||
ug->y + g->y + i + (W->padding >> 2),
|
|
||||||
g->w - (i << 1) - (W->padding >> 1),
|
|
||||||
g->h - (i << 1) - (W->padding >> 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
draw_line(Drawable d, int x1, int y1, int x2, int y2)
|
|
||||||
{
|
|
||||||
XDrawLine(W->dpy, d, W->gc, x1, y1, x2, y2);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned short
|
|
||||||
draw_textw(struct theme *t, const char *str)
|
|
||||||
{
|
|
||||||
XRectangle r;
|
|
||||||
|
|
||||||
XmbTextExtents(t->font.fontset, str, strlen(str), NULL, &r);
|
|
||||||
|
|
||||||
return r.width;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* DRAW_H */
|
|
||||||
851
src/event.c
851
src/event.c
@ -1,98 +1,216 @@
|
|||||||
/*
|
/*
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
* event.c
|
||||||
* For license, see COPYING.
|
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
|
||||||
*/
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of the nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "event.h"
|
|
||||||
#include "ewmh.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "util.h"
|
|
||||||
#include "wmfs.h"
|
#include "wmfs.h"
|
||||||
#include "client.h"
|
|
||||||
#include "barwin.h"
|
|
||||||
#include "screen.h"
|
|
||||||
#include "systray.h"
|
|
||||||
#include "infobar.h"
|
|
||||||
|
|
||||||
#define EVDPY(e) (e)->xany.display
|
/** ButtonPress handle event
|
||||||
|
* \param ev XButtonEvent pointer
|
||||||
#define MOUSE_DO_BIND(m) \
|
*/
|
||||||
if(m->button == ev->button) \
|
|
||||||
if(!m->use_area || (m->use_area && INAREA(ev->x, ev->y, m->area))) \
|
|
||||||
if(m->func) \
|
|
||||||
m->func(m->cmd);
|
|
||||||
static void
|
static void
|
||||||
event_buttonpress(XEvent *e)
|
buttonpress(XButtonEvent *ev)
|
||||||
{
|
{
|
||||||
XButtonEvent *ev = &e->xbutton;
|
Client *c;
|
||||||
struct mousebind *m;
|
int i, j, n;
|
||||||
struct barwin *b;
|
|
||||||
struct client *c;
|
|
||||||
|
|
||||||
screen_update_sel();
|
screen_get_sel();
|
||||||
status_flush_surface();
|
|
||||||
|
|
||||||
SLIST_FOREACH(b, &W->h.barwin, next)
|
/* If the mouse is on a not selected client and you click on it. */
|
||||||
if(b->win == ev->window)
|
if(((c = client_gb_win(ev->window)) || (c = client_gb_titlebar(ev->window))) && c != sel
|
||||||
|
&& (ev->button == Button1 || ev->button == Button2 || ev->button == Button3))
|
||||||
{
|
{
|
||||||
W->last_clicked_barwin = b;
|
|
||||||
|
|
||||||
SLIST_FOREACH(m, &b->mousebinds, next)
|
|
||||||
MOUSE_DO_BIND(m);
|
|
||||||
|
|
||||||
SLIST_FOREACH(m, &b->statusmousebinds, next)
|
|
||||||
MOUSE_DO_BIND(m);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if((c = client_gb_win(ev->window)) && c != W->client
|
|
||||||
&& ev->button == 1 && W->cfocus & CFOCUS_CLICK)
|
|
||||||
client_focus(c);
|
client_focus(c);
|
||||||
|
client_raise(c);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
/* Titlebar buttons */
|
||||||
|
if((c = client_gb_button(ev->window, &n)))
|
||||||
|
for(i = 0; i < conf.titlebar.button[n].nmouse; ++i)
|
||||||
|
if(ev->button == conf.titlebar.button[n].mouse[i].button)
|
||||||
|
if(conf.titlebar.button[n].mouse[i].func)
|
||||||
|
{
|
||||||
|
client_focus(c);
|
||||||
|
conf.titlebar.button[n].mouse[i].func(conf.titlebar.button[n].mouse[i].cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Frame Resize Area */
|
||||||
|
if((c = client_gb_resize(ev->window)))
|
||||||
|
mouse_resize(c);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
/* 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(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);
|
||||||
|
|
||||||
|
if(infobar[selscreen].geo.y != spgeo[selscreen].y)
|
||||||
|
menulayout.y = infobar[selscreen].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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ClientMessage handle event
|
||||||
|
*\param ev XClientMessageEvent pointer
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
event_enternotify(XEvent *e)
|
clientmessageevent(XClientMessageEvent *ev)
|
||||||
{
|
{
|
||||||
XCrossingEvent *ev = &e->xcrossing;
|
Client *c;
|
||||||
struct client *c;
|
Systray *sy;
|
||||||
|
int s, i, mess_t = 0;
|
||||||
|
Atom rt;
|
||||||
|
int rf;
|
||||||
|
ulong ir, il;
|
||||||
|
uchar *ret = NULL;
|
||||||
|
uchar *ret_cmd = NULL;
|
||||||
|
void (*func)(uicb_t);
|
||||||
|
|
||||||
if((ev->mode != NotifyNormal
|
if(ev->format != 32)
|
||||||
|| ev->detail == NotifyInferior)
|
|
||||||
&& ev->window != W->root)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(ev->window == W->systray.win || systray_find(ev->window))
|
s = screen_count();
|
||||||
return;
|
|
||||||
|
|
||||||
if((c = client_gb_win(ev->window))
|
for(i = 0; i < net_last + s; ++i)
|
||||||
|| (c = client_gb_frame(ev->window)))
|
if(net_atom[i] == ev->message_type)
|
||||||
|
mess_t = i;
|
||||||
|
|
||||||
|
if(ev->window == ROOT)
|
||||||
{
|
{
|
||||||
if(c->flags & CLIENT_IGNORE_ENTER)
|
/* Manage _NET_CURRENT_DESKTOP */
|
||||||
c->flags ^= CLIENT_IGNORE_ENTER;
|
if(mess_t == net_current_desktop
|
||||||
else if(c->tag->flags & TAG_IGNORE_ENTER)
|
&& ev->data.l[0] >= 0
|
||||||
c->tag->flags ^= TAG_IGNORE_ENTER;
|
&& ev->data.l[0] < conf.ntag[selscreen])
|
||||||
else if(c != W->client && !(c->flags & CLIENT_TABBED)
|
tag_set((int)(ev->data.l[0] + 1));
|
||||||
&& W->cfocus & CFOCUS_ENTER)
|
|
||||||
|
/* Manage _WMFS_SET_SCREEN */
|
||||||
|
if(mess_t == wmfs_set_screen
|
||||||
|
&& ev->data.l[0] >= 0
|
||||||
|
&& ev->data.l[0] <= s)
|
||||||
|
screen_set_sel((int)(ev->data.l[0]));
|
||||||
|
|
||||||
|
/* Manage _NET_ACTIVE_WINDOW */
|
||||||
|
else if(mess_t == net_active_window)
|
||||||
|
{
|
||||||
|
if((c = client_gb_win(ev->window)))
|
||||||
client_focus(c);
|
client_focus(c);
|
||||||
|
else if((sy = systray_find(ev->data.l[0])))
|
||||||
|
XSetInputFocus(dpy, sy->win, RevertToNone, CurrentTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(ev->window == traywin)
|
||||||
static void
|
{
|
||||||
event_clientmessageevent(XEvent *e)
|
/* Manage _NET_WM_SYSTEM_TRAY_OPCODE */
|
||||||
{
|
if(mess_t == net_wm_system_tray_opcode)
|
||||||
XClientMessageEvent *ev = &e->xclient;
|
|
||||||
struct client *c;
|
|
||||||
struct _systray *sy;
|
|
||||||
int type = 0;
|
|
||||||
|
|
||||||
while(type < net_last && W->net_atom[type] != ev->message_type)
|
|
||||||
++type;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Systray message
|
|
||||||
* _NET_WM_SYSTRAY_TRAY_OPCODE
|
|
||||||
*/
|
|
||||||
if(ev->window == W->systray.win && type == net_system_tray_opcode)
|
|
||||||
{
|
{
|
||||||
if(ev->data.l[1] == XEMBED_EMBEDDED_NOTIFY)
|
if(ev->data.l[1] == XEMBED_EMBEDDED_NOTIFY)
|
||||||
{
|
{
|
||||||
@ -100,100 +218,109 @@ event_clientmessageevent(XEvent *e)
|
|||||||
systray_update();
|
systray_update();
|
||||||
}
|
}
|
||||||
else if(ev->data.l[1] == XEMBED_REQUEST_FOCUS)
|
else if(ev->data.l[1] == XEMBED_REQUEST_FOCUS)
|
||||||
{
|
|
||||||
if((sy = systray_find(ev->data.l[2])))
|
if((sy = systray_find(ev->data.l[2])))
|
||||||
ewmh_send_message(sy->win, sy->win, "_XEMBED", XEMBED_FOCUS_IN,
|
ewmh_send_message(sy->win, sy->win, "_XEMBED",
|
||||||
XEMBED_FOCUS_CURRENT, 0, 0, 0);
|
XEMBED_FOCUS_IN, XEMBED_FOCUS_CURRENT, 0, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(ev->window == W->root)
|
|
||||||
{
|
|
||||||
/* WMFS message */
|
|
||||||
if(ev->data.l[4])
|
|
||||||
{
|
|
||||||
/* Manage _WMFS_FUNCTION && _WMFS_CMD */
|
|
||||||
if(type == wmfs_function || type == wmfs_cmd)
|
|
||||||
{
|
|
||||||
Atom rt;
|
|
||||||
int d;
|
|
||||||
long unsigned int len, il;
|
|
||||||
unsigned char *ret = NULL, *ret_cmd = NULL;
|
|
||||||
void (*func)(Uicb);
|
|
||||||
|
|
||||||
if(XGetWindowProperty(EVDPY(e), W->root, W->net_atom[wmfs_function], 0, 65536,
|
/* Manage _NET_WM_STATE */
|
||||||
False, W->net_atom[utf8_string], &rt, &d,
|
if(mess_t == net_wm_state)
|
||||||
&len, &il, &ret) == Success
|
if((c = client_gb_win(ev->window)))
|
||||||
&& ret && ((func = uicb_name_func((char*)ret))))
|
ewmh_manage_net_wm_state(ev->data.l, c);
|
||||||
{
|
|
||||||
if(XGetWindowProperty(EVDPY(e), W->root, W->net_atom[wmfs_cmd], 0, 65536,
|
|
||||||
False, W->net_atom[utf8_string], &rt, &d,
|
|
||||||
&len, &il, &ret_cmd) == Success
|
|
||||||
&& len && ret_cmd)
|
|
||||||
{
|
|
||||||
func((Uicb)ret_cmd);
|
|
||||||
XFree(ret_cmd);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
func(NULL);
|
|
||||||
|
|
||||||
|
/* Manage _NET_CLOSE_WINDOW */
|
||||||
|
if(mess_t == net_close_window)
|
||||||
|
if((c = client_gb_win(ev->window)))
|
||||||
|
client_kill(c);
|
||||||
|
|
||||||
|
/* Manage _NET_WM_DESKTOP */
|
||||||
|
if(mess_t == net_wm_desktop)
|
||||||
|
if((c = client_gb_win(ev->window)) && ev->data.l[0] != (long)0xFFFFFFFF)
|
||||||
|
tag_transfert(c, ev->data.l[0]);
|
||||||
|
|
||||||
|
/* Manage _WMFS_STATUSTEXT_x */
|
||||||
|
if(mess_t >= wmfs_statustext && ev->data.l[4] == True)
|
||||||
|
{
|
||||||
|
if(XGetWindowProperty(dpy, 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);
|
||||||
XFree(ret);
|
XFree(ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(type == net_active_window)
|
/* Manage _WMFS_FUNCTION && _WMFS_CMD */
|
||||||
if((sy = systray_find(ev->data.l[0])))
|
if((mess_t == wmfs_function && ev->data.l[4] == True)
|
||||||
XSetInputFocus(W->dpy, sy->win, RevertToNone, CurrentTime);
|
|| (mess_t == wmfs_cmd && ev->data.l[4] == True))
|
||||||
}
|
|
||||||
|
|
||||||
switch(type)
|
|
||||||
{
|
{
|
||||||
/* _NET_WM_STATE */
|
XGetWindowProperty(dpy, ROOT, net_atom[wmfs_function], 0, 4096,
|
||||||
case net_wm_state:
|
False, net_atom[utf8_string], &rt, &rf, &ir, &il, &ret);
|
||||||
if((c = client_gb_win(ev->window)))
|
|
||||||
ewmh_manage_state(ev->data.l, c);
|
XGetWindowProperty(dpy, ROOT, net_atom[wmfs_cmd], 0, 4096,
|
||||||
break;
|
False, net_atom[utf8_string], &rt, &rf, &ir, &il, &ret_cmd);
|
||||||
/* _NET_CLOSE_WINDOW */
|
|
||||||
case net_close_window:
|
if((func = name_to_func((char*)ret, func_list)))
|
||||||
if((c = client_gb_win(ev->window)))
|
func((uicb_t)ret_cmd);
|
||||||
client_close(c);
|
|
||||||
break;
|
XFree(ret_cmd);
|
||||||
/* _NET_WM_DESKTOP */
|
XFree(ret);
|
||||||
case net_wm_desktop:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Manage _WMFS_UPDATE_HINTS */
|
||||||
|
if(mess_t == wmfs_update_hints)
|
||||||
|
{
|
||||||
|
ewmh_get_number_of_desktop();
|
||||||
|
ewmh_update_current_tag_prop();
|
||||||
|
ewmh_get_client_list();
|
||||||
|
ewmh_get_desktop_names();
|
||||||
|
ewmh_set_desktop_geometry();
|
||||||
|
screen_count();
|
||||||
|
screen_get_sel();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mess_t == wmfs_update_status
|
||||||
|
&& estatus)
|
||||||
|
spawn(conf.status_path);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** ConfigureRequesthandle events
|
||||||
|
* \param ev XConfigureRequestEvent pointer
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
event_configureevent(XEvent *e)
|
configureevent(XConfigureRequestEvent *ev)
|
||||||
{
|
{
|
||||||
XConfigureRequestEvent *ev = &e->xconfigurerequest;
|
|
||||||
XWindowChanges wc;
|
XWindowChanges wc;
|
||||||
struct client *c;
|
Client *c;
|
||||||
|
|
||||||
|
/* Check part */
|
||||||
|
if((c = client_gb_win(ev->window))
|
||||||
|
|| (c = client_gb_win(ev->window)))
|
||||||
|
{
|
||||||
|
CHECK(!(c->flags & LMaxFlag));
|
||||||
|
CHECK(!(c->flags & MaxFlag));
|
||||||
|
CHECK(!(c->flags & FSSFlag));
|
||||||
|
}
|
||||||
|
|
||||||
if((c = client_gb_win(ev->window)))
|
if((c = client_gb_win(ev->window)))
|
||||||
{
|
|
||||||
if(c->flags & CLIENT_FREE)
|
|
||||||
{
|
{
|
||||||
if(ev->value_mask & CWX)
|
if(ev->value_mask & CWX)
|
||||||
c->geo.x = ev->x;
|
c->geo.x = ev->x + BORDH;
|
||||||
if(ev->value_mask & CWY)
|
if(ev->value_mask & CWY)
|
||||||
c->geo.y = ev->y - c->tbarw - c->border - c->border;
|
c->geo.y = ev->y + TBARH;
|
||||||
if(ev->value_mask & CWWidth)
|
if(ev->value_mask & CWWidth)
|
||||||
c->geo.w = ev->width + c->border + c->border;
|
c->geo.width = ev->width;
|
||||||
if(ev->value_mask & CWHeight)
|
if(ev->value_mask & CWHeight)
|
||||||
c->geo.h = ev->height + c->tbarw + c->border;
|
c->geo.height = ev->height;
|
||||||
|
|
||||||
client_moveresize(c, &c->geo);
|
if(c->flags & FreeFlag || !(c->flags & (TileFlag | LMaxFlag)))
|
||||||
}
|
client_moveresize(c, c->geo, False);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(ev->value_mask & CWWidth)
|
client_configure(c);
|
||||||
_fac_resize(c, Right, ev->width - c->wgeo.w);
|
arrange(c->screen, True);
|
||||||
if(ev->value_mask & CWHeight)
|
|
||||||
_fac_resize(c, Bottom, ev->height - c->wgeo.h);
|
|
||||||
|
|
||||||
client_apply_tgeo(c->tag);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -206,234 +333,380 @@ event_configureevent(XEvent *e)
|
|||||||
wc.sibling = ev->above;
|
wc.sibling = ev->above;
|
||||||
wc.stack_mode = ev->detail;
|
wc.stack_mode = ev->detail;
|
||||||
|
|
||||||
XConfigureWindow(EVDPY(e), ev->window, ev->value_mask, &wc);
|
XConfigureWindow(dpy, ev->window, ev->value_mask, &wc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** DestroyNotify handle event
|
||||||
|
* \param ev XDestroyWindowEvent pointer
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
event_destroynotify(XEvent *e)
|
destroynotify(XDestroyWindowEvent *ev)
|
||||||
{
|
{
|
||||||
XDestroyWindowEvent *ev = &e->xdestroywindow;
|
Client *c;
|
||||||
struct client *c;
|
Systray *s;
|
||||||
struct _systray *s;
|
|
||||||
|
|
||||||
if((c = client_gb_win(ev->window)))
|
if((c = client_gb_win(ev->window)))
|
||||||
client_remove(c);
|
{
|
||||||
|
client_unmanage(c);
|
||||||
|
XSetErrorHandler(errorhandler);
|
||||||
|
}
|
||||||
else if((s = systray_find(ev->window)))
|
else if((s = systray_find(ev->window)))
|
||||||
{
|
{
|
||||||
ewmh_set_wm_state(s->win, WithdrawnState);
|
setwinstate(s->win, WithdrawnState);
|
||||||
systray_del(s);
|
systray_del(s);
|
||||||
systray_update();
|
systray_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** EnterNotify handle event
|
||||||
|
* \param ev XCrossingEvent pointer
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
event_focusin(XEvent *e)
|
enternotify(XCrossingEvent *ev)
|
||||||
{
|
{
|
||||||
if(W->client
|
Client *c;
|
||||||
&& e->xfocus.window != W->client->win
|
int n;
|
||||||
&& e->xfocus.window != W->client->frame)
|
|
||||||
client_focus(W->client);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
if((ev->mode != NotifyNormal
|
||||||
event_maprequest(XEvent *e)
|
|| ev->detail == NotifyInferior)
|
||||||
{
|
&& ev->window != ROOT)
|
||||||
XMapRequestEvent *ev = &e->xmaprequest;
|
|
||||||
XWindowAttributes at;
|
|
||||||
struct _systray *s;
|
|
||||||
|
|
||||||
/* Which windows to manage */
|
|
||||||
if(!XGetWindowAttributes(EVDPY(e), ev->window, &at)
|
|
||||||
|| at.override_redirect
|
|
||||||
|| ewmh_manage_window_type_desktop(ev->window)
|
|
||||||
|| ewmh_manage_state_sticky(ev->window))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(!client_gb_win(ev->window))
|
/* Don't handle EnterNotify event if it's about systray */
|
||||||
client_new(ev->window, &at, false);
|
if(systray_find(ev->window) || ev->window == traywin)
|
||||||
else if((s = systray_find(ev->window)))
|
return;
|
||||||
|
|
||||||
|
if(conf.focus_fmouse)
|
||||||
{
|
{
|
||||||
ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime,
|
if((c = client_gb_win(ev->window))
|
||||||
XEMBED_WINDOW_ACTIVATE, 0, 0, 0);
|
|| (c = client_gb_frame(ev->window))
|
||||||
systray_update();
|
|| (c = client_gb_titlebar(ev->window))
|
||||||
|
|| (c = client_gb_button(ev->window, &n)))
|
||||||
|
client_focus(c);
|
||||||
|
else
|
||||||
|
client_focus(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** ExposeEvent handle event
|
||||||
|
* \param ev XExposeEvent pointer
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
event_mappingnotify(XEvent *e)
|
expose(XExposeEvent *ev)
|
||||||
|
{
|
||||||
|
Client *c;
|
||||||
|
int i, sc;
|
||||||
|
|
||||||
|
/* 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]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Client frame */
|
||||||
|
if((c = client_gb_titlebar(ev->window)))
|
||||||
|
frame_update(c);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** FocusChange handle event
|
||||||
|
* \param ev XFocusChangeEvent pointer
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
focusin(XFocusChangeEvent *ev)
|
||||||
|
{
|
||||||
|
if(sel && ev->window != sel->win)
|
||||||
|
client_focus(sel);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** KeyPress handle event
|
||||||
|
* \param ev XKeyPressedEvent pointer
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
keypress(XKeyPressedEvent *ev)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
KeySym keysym;
|
||||||
|
|
||||||
|
keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
|
||||||
|
for(i = 0; i < conf.nkeybind; ++i)
|
||||||
|
if(keysym == keys[i].keysym
|
||||||
|
&& (keys[i].mod & ~(numlockmask | LockMask))
|
||||||
|
== (ev->state & ~(numlockmask | LockMask))
|
||||||
|
&& keys[i].func)
|
||||||
|
keys[i].func(keys[i].cmd);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** MappingNotify handle event
|
||||||
|
* \param ev XMappingEvent pointer
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
mappingnotify(XMappingEvent *ev)
|
||||||
{
|
{
|
||||||
XMappingEvent *ev = &e->xmapping;
|
|
||||||
XRefreshKeyboardMapping(ev);
|
XRefreshKeyboardMapping(ev);
|
||||||
|
|
||||||
if(ev->request == MappingKeyboard)
|
if(ev->request == MappingKeyboard)
|
||||||
wmfs_grab_keys();
|
grabkeys();
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** MapNotify handle event
|
||||||
|
* \param ev XMapEvent pointer
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
event_propertynotify(XEvent *e)
|
mapnotify(XMapEvent *ev)
|
||||||
{
|
{
|
||||||
XPropertyEvent *ev = &e->xproperty;
|
Client *c;
|
||||||
|
Systray *s;
|
||||||
|
|
||||||
|
if(ev->window != ev->event && !ev->send_event)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if((c = client_gb_win(ev->window)))
|
||||||
|
setwinstate(c->win, NormalState);
|
||||||
|
else if((s = systray_find(ev->window)))
|
||||||
|
{
|
||||||
|
setwinstate(s->win, NormalState);
|
||||||
|
ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** MapRequest handle event
|
||||||
|
* \param ev XMapRequestEvent pointer
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
maprequest(XMapRequestEvent *ev)
|
||||||
|
{
|
||||||
|
XWindowAttributes at;
|
||||||
|
Systray *s;
|
||||||
|
|
||||||
|
CHECK(XGetWindowAttributes(dpy, ev->window, &at));
|
||||||
|
CHECK(!at.override_redirect);
|
||||||
|
|
||||||
|
if((s = systray_find(ev->window)))
|
||||||
|
{
|
||||||
|
ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, 0, 0);
|
||||||
|
systray_update();
|
||||||
|
}
|
||||||
|
else if(!client_gb_win(ev->window))
|
||||||
|
client_manage(ev->window, &at, True);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** PropertyNotify handle event
|
||||||
|
* \param ev XPropertyEvent pointer
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
propertynotify(XPropertyEvent *ev)
|
||||||
|
{
|
||||||
|
Client *c;
|
||||||
|
Systray *s;
|
||||||
|
Window trans;
|
||||||
XWMHints *h;
|
XWMHints *h;
|
||||||
struct client *c;
|
|
||||||
struct _systray *s;
|
|
||||||
|
|
||||||
if(ev->state == PropertyDelete)
|
if(ev->state == PropertyDelete)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if((s = systray_find(ev->window)))
|
||||||
|
{
|
||||||
|
systray_state(s);
|
||||||
|
systray_update();
|
||||||
|
}
|
||||||
|
|
||||||
if((c = client_gb_win(ev->window)))
|
if((c = client_gb_win(ev->window)))
|
||||||
{
|
{
|
||||||
switch(ev->atom)
|
switch(ev->atom)
|
||||||
{
|
{
|
||||||
case XA_WM_TRANSIENT_FOR:
|
case XA_WM_TRANSIENT_FOR:
|
||||||
|
XGetTransientForHint(dpy, c->win, &trans);
|
||||||
|
if((c->flags & TileFlag || c->flags & MaxFlag))
|
||||||
|
if(((c->flags & HintFlag && (client_gb_win(trans) != NULL)))
|
||||||
|
|| (!(c->flags & HintFlag && (client_gb_win(trans) != NULL))))
|
||||||
|
arrange(c->screen, True);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XA_WM_NORMAL_HINTS:
|
case XA_WM_NORMAL_HINTS:
|
||||||
client_get_sizeh(c);
|
client_size_hints(c);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XA_WM_HINTS:
|
case XA_WM_HINTS:
|
||||||
if((h = XGetWMHints(EVDPY(e), c->win))
|
if((h = XGetWMHints(dpy, c->win)) && (h->flags & XUrgencyHint) && c != sel)
|
||||||
&& (h->flags & XUrgencyHint)
|
|
||||||
&& c->tag != W->screen->seltag)
|
|
||||||
{
|
{
|
||||||
c->tag->flags |= TAG_URGENT;
|
client_urgent(c, True);
|
||||||
infobar_elem_screen_update(c->screen, ElemTag);
|
|
||||||
XFree(h);
|
XFree(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
case XA_WM_NAME:
|
||||||
|
client_get_name(c);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if(ev->atom == XA_WM_NAME || ev->atom == W->net_atom[net_wm_name])
|
if(ev->atom == net_atom[net_wm_name])
|
||||||
client_get_name(c);
|
client_get_name(c);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if((s = systray_find(ev->window)))
|
|
||||||
{
|
return;
|
||||||
systray_state(s);
|
|
||||||
systray_update();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** XReparentEvent handle event
|
||||||
|
* \param ev XReparentEvent pointer
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
event_unmapnotify(XEvent *e)
|
reparentnotify(XReparentEvent *ev)
|
||||||
{
|
{
|
||||||
XUnmapEvent *ev = &e->xunmap;
|
(void)ev;
|
||||||
struct client *c;
|
|
||||||
struct _systray *s;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** SelectionClearEvent handle event
|
||||||
|
* \param ev XSelectionClearEvent pointer
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
selectionclearevent(XSelectionClearEvent *ev)
|
||||||
|
{
|
||||||
|
/* Getting selection if lost it */
|
||||||
|
if(ev->window == traywin)
|
||||||
|
systray_acquire();
|
||||||
|
|
||||||
|
systray_update();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** UnmapNotify handle event
|
||||||
|
* \param ev XUnmapEvent pointer
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
unmapnotify(XUnmapEvent *ev)
|
||||||
|
{
|
||||||
|
Client *c;
|
||||||
|
Systray *s;
|
||||||
|
|
||||||
if((c = client_gb_win(ev->window))
|
if((c = client_gb_win(ev->window))
|
||||||
&& ev->send_event
|
&& ev->send_event
|
||||||
&& ev->event == W->root)
|
&& !(c->flags & HideFlag))
|
||||||
{
|
{
|
||||||
Atom rt;
|
client_unmanage(c);
|
||||||
unsigned long n, il;
|
XSetErrorHandler(errorhandler);
|
||||||
int d;
|
|
||||||
unsigned char *ret = NULL;
|
|
||||||
|
|
||||||
if(XGetWindowProperty(EVDPY(e), c->win, W->net_atom[wm_state], 0, 2,
|
|
||||||
False, W->net_atom[wm_state], &rt, &d,
|
|
||||||
&n, &il, &ret) == Success)
|
|
||||||
if(*ret == NormalState)
|
|
||||||
client_remove(c);
|
|
||||||
}
|
}
|
||||||
else if((s = systray_find(ev->window)))
|
|
||||||
|
if((s = systray_find(ev->window)))
|
||||||
{
|
{
|
||||||
systray_del(s);
|
systray_del(s);
|
||||||
systray_update();
|
systray_update();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
event_keypress(XEvent *e)
|
|
||||||
{
|
|
||||||
XKeyPressedEvent *ev = &e->xkey;
|
|
||||||
KeySym keysym = XkbKeycodeToKeysym(EVDPY(e), (KeyCode)ev->keycode, 0, 0);
|
|
||||||
struct keybind *k;
|
|
||||||
|
|
||||||
screen_update_sel();
|
|
||||||
status_flush_surface();
|
|
||||||
|
|
||||||
SLIST_FOREACH(k, &W->h.keybind, next)
|
|
||||||
if(k->keysym == keysym && KEYPRESS_MASK(k->mod) == KEYPRESS_MASK(ev->state))
|
|
||||||
if(k->func)
|
|
||||||
k->func(k->cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
event_expose(XEvent *e)
|
|
||||||
{
|
|
||||||
XExposeEvent *ev = &e->xexpose;
|
|
||||||
struct barwin *b;
|
|
||||||
|
|
||||||
SLIST_FOREACH(b, &W->h.barwin, next)
|
|
||||||
if(b->win == ev->window)
|
|
||||||
{
|
|
||||||
barwin_refresh(b);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** XMotionNotify handle event
|
||||||
|
* \param ev XMotionEvent pointer
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
event_mapnotify(XEvent *e)
|
motionnotify(XMotionEvent *ev)
|
||||||
{
|
{
|
||||||
XMapEvent *ev = &e->xmap;
|
Client *c;
|
||||||
struct client *c;
|
|
||||||
struct _systray *s;
|
|
||||||
|
|
||||||
if(ev->window != ev->event && !ev->send_event)
|
if(!conf.focus_fmouse || !conf.focus_fmov)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if((c = client_gb_win(ev->window)))
|
if((c = client_gb_win(ev->subwindow)))
|
||||||
client_map(c);
|
if (c != sel)
|
||||||
else if((s = systray_find(ev->window)))
|
client_focus(c);
|
||||||
{
|
|
||||||
ewmh_set_wm_state(s->win, NormalState);
|
return;
|
||||||
ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime,
|
|
||||||
XEMBED_WINDOW_ACTIVATE, 0, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
event_selectionclearevent(XEvent *ev)
|
|
||||||
{
|
|
||||||
/* Getting selection if lost it */
|
|
||||||
if(ev->xselectionclear.window == W->systray.win)
|
|
||||||
systray_acquire();
|
|
||||||
|
|
||||||
systray_update();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
event_dummy(XEvent *e)
|
|
||||||
{
|
|
||||||
/* printf("%d\n", e->type);*/
|
|
||||||
(void)e;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Key grabbing function
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
event_init(void)
|
grabkeys(void)
|
||||||
{
|
{
|
||||||
int i = MAX_EV;
|
int i;
|
||||||
|
KeyCode code;
|
||||||
|
|
||||||
while(i--)
|
XUngrabKey(dpy, AnyKey, AnyModifier, ROOT);
|
||||||
event_handle[i] = event_dummy;
|
for(i = 0; i < conf.nkeybind; ++i)
|
||||||
|
if((code = XKeysymToKeycode(dpy, keys[i].keysym)))
|
||||||
|
{
|
||||||
|
XGrabKey(dpy, code, keys[i].mod, ROOT, True, GrabModeAsync, GrabModeAsync);
|
||||||
|
XGrabKey(dpy, code, keys[i].mod | LockMask, ROOT, True, GrabModeAsync, GrabModeAsync);
|
||||||
|
XGrabKey(dpy, code, keys[i].mod | numlockmask, ROOT, True, GrabModeAsync, GrabModeAsync);
|
||||||
|
XGrabKey(dpy, code, keys[i].mod | LockMask | numlockmask, ROOT, True, GrabModeAsync, GrabModeAsync);
|
||||||
|
}
|
||||||
|
|
||||||
event_handle[ButtonPress] = event_buttonpress;
|
return;
|
||||||
event_handle[ClientMessage] = event_clientmessageevent;
|
}
|
||||||
event_handle[ConfigureRequest] = event_configureevent;
|
|
||||||
event_handle[DestroyNotify] = event_destroynotify;
|
/** Event handle function: execute every function
|
||||||
event_handle[EnterNotify] = event_enternotify;
|
* handle by event
|
||||||
event_handle[Expose] = event_expose;
|
* \param ev Event
|
||||||
event_handle[FocusIn] = event_focusin;
|
*/
|
||||||
event_handle[KeyPress] = event_keypress;
|
void
|
||||||
event_handle[MapNotify] = event_mapnotify;
|
getevent(XEvent ev)
|
||||||
event_handle[MapRequest] = event_maprequest;
|
{
|
||||||
event_handle[MappingNotify] = event_mappingnotify;
|
|
||||||
event_handle[PropertyNotify] = event_propertynotify;
|
switch(ev.type)
|
||||||
/*event_handle[ReparentNotify] = event_reparentnotify;*/
|
{
|
||||||
event_handle[SelectionClear] = event_selectionclearevent;
|
case ButtonPress: buttonpress(&ev.xbutton); break;
|
||||||
event_handle[UnmapNotify] = event_unmapnotify;
|
case ClientMessage: clientmessageevent(&ev.xclient); break;
|
||||||
|
case ConfigureRequest: configureevent(&ev.xconfigurerequest); break;
|
||||||
|
case DestroyNotify: destroynotify(&ev.xdestroywindow); break;
|
||||||
|
case EnterNotify: enternotify(&ev.xcrossing); break;
|
||||||
|
case Expose: expose(&ev.xexpose); break;
|
||||||
|
case FocusIn: focusin(&ev.xfocus); break;
|
||||||
|
case KeyPress: keypress(&ev.xkey); break;
|
||||||
|
case MapNotify: mapnotify(&ev.xmap); break;
|
||||||
|
case MapRequest: maprequest(&ev.xmaprequest); break;
|
||||||
|
case MappingNotify: mappingnotify(&ev.xmapping); break;
|
||||||
|
case MotionNotify: motionnotify(&ev.xmotion); break;
|
||||||
|
case PropertyNotify: propertynotify(&ev.xproperty); break;
|
||||||
|
case ReparentNotify: reparentnotify(&ev.xreparent); break;
|
||||||
|
case SelectionClear: selectionclearevent(&ev.xselectionclear); break;
|
||||||
|
case UnmapNotify: unmapnotify(&ev.xunmap); break;
|
||||||
|
default:
|
||||||
|
|
||||||
|
#ifdef HAVE_XRANDR
|
||||||
|
/* Check Xrandr event */
|
||||||
|
if(ev.type == xrandr_event)
|
||||||
|
{
|
||||||
|
/* Update xrandr configuration */
|
||||||
|
XRRUpdateConfiguration(&ev);
|
||||||
|
|
||||||
|
/* Reload WMFS to update the screen(s) geometry changement */
|
||||||
|
quit();
|
||||||
|
for(; argv_global[0] && argv_global[0] == ' '; ++argv_global);
|
||||||
|
execvp(argv_global, all_argv);
|
||||||
|
}
|
||||||
|
#endif /* HAVE_XRANDR */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
22
src/event.h
22
src/event.h
@ -1,22 +0,0 @@
|
|||||||
/*
|
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
|
||||||
* For license, see COPYING.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef EVENT_H
|
|
||||||
#define EVENT_H
|
|
||||||
|
|
||||||
#include <X11/XKBlib.h>
|
|
||||||
|
|
||||||
#include "wmfs.h"
|
|
||||||
|
|
||||||
#define MAX_EV 256
|
|
||||||
|
|
||||||
#define KEYPRESS_MASK(m) (m & ~(W->numlockmask | LockMask))
|
|
||||||
#define EVENT_HANDLE(e) event_handle[(e)->type](e);
|
|
||||||
|
|
||||||
void event_init(void);
|
|
||||||
|
|
||||||
void (*event_handle[MAX_EV])(XEvent*);
|
|
||||||
|
|
||||||
#endif /* EVENT_H */
|
|
||||||
627
src/ewmh.c
627
src/ewmh.c
@ -1,160 +1,187 @@
|
|||||||
/*
|
/*
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
* ewmh.c
|
||||||
* For license, see COPYING.
|
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
|
||||||
*/
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of the nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "ewmh.h"
|
#include "wmfs.h"
|
||||||
#include "util.h"
|
|
||||||
#include "screen.h"
|
|
||||||
#include "client.h"
|
|
||||||
|
|
||||||
/* Taken From standards.freedesktop.org */
|
/* Taken From standards.freedesktop.org */
|
||||||
#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
|
#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
|
||||||
#define _NET_WM_STATE_ADD 1 /* add/set property */
|
#define _NET_WM_STATE_ADD 1 /* add/set property */
|
||||||
#define _NET_WM_STATE_TOGGLE 2 /* toggle property */
|
#define _NET_WM_STATE_TOGGLE 2 /* toggle property */
|
||||||
|
|
||||||
|
/** Init ewmh atoms
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
ewmh_init(void)
|
ewmh_init_hints(void)
|
||||||
{
|
{
|
||||||
int b = 1;
|
int i = 1, s, j, showing_desk = 0;
|
||||||
|
char root_name[] = WMFS_VERSION;
|
||||||
|
char class[] = "wmfs", st[64];
|
||||||
|
long pid = (long)getpid();
|
||||||
|
char systray_atom[48];
|
||||||
|
|
||||||
W->net_atom = xcalloc(net_last, sizeof(Atom));
|
|
||||||
|
s = screen_count();
|
||||||
|
net_atom = xcalloc(net_last + s, sizeof(Atom));
|
||||||
|
|
||||||
/* EWMH hints */
|
/* EWMH hints */
|
||||||
W->net_atom[wm_state] = ATOM("WM_STATE");
|
net_atom[net_supported] = ATOM("_NET_SUPPORTED");
|
||||||
W->net_atom[wm_class] = ATOM("WM_CLASS");
|
net_atom[net_client_list] = ATOM("_NET_CLIENT_LIST");
|
||||||
W->net_atom[wm_name] = ATOM("WM_NAME");
|
net_atom[net_frame_extents] = ATOM("_NET_FRAME_EXTENTS");
|
||||||
W->net_atom[net_supported] = ATOM("_NET_SUPPORTED");
|
net_atom[net_number_of_desktops] = ATOM("_NET_NUMBER_OF_DESKTOPS");
|
||||||
W->net_atom[net_client_list] = ATOM("_NET_CLIENT_LIST");
|
net_atom[net_current_desktop] = ATOM("_NET_CURRENT_DESKTOP");
|
||||||
W->net_atom[net_frame_extents] = ATOM("_NET_FRAME_EXTENTS");
|
net_atom[net_desktop_names] = ATOM("_NET_DESKTOP_NAMES");
|
||||||
W->net_atom[net_number_of_desktops] = ATOM("_NET_NUMBER_OF_DESKTOPS");
|
net_atom[net_desktop_geometry] = ATOM("_NET_DESKTOP_GEOMETRY");
|
||||||
W->net_atom[net_current_desktop] = ATOM("_NET_CURRENT_DESKTOP");
|
net_atom[net_active_window] = ATOM("_NET_ACTIVE_WINDOW");
|
||||||
W->net_atom[net_desktop_names] = ATOM("_NET_DESKTOP_NAMES");
|
net_atom[net_close_window] = ATOM("_NET_CLOSE_WINDOW");
|
||||||
W->net_atom[net_desktop_geometry] = ATOM("_NET_DESKTOP_GEOMETRY");
|
net_atom[net_wm_name] = ATOM("_NET_WM_NAME");
|
||||||
W->net_atom[net_active_window] = ATOM("_NET_ACTIVE_WINDOW");
|
net_atom[net_wm_pid] = ATOM("_NET_WM_PID");
|
||||||
W->net_atom[net_close_window] = ATOM("_NET_CLOSE_WINDOW");
|
net_atom[net_wm_desktop] = ATOM("_NET_WM_DESKTOP");
|
||||||
W->net_atom[net_wm_name] = ATOM("_NET_WM_NAME");
|
net_atom[net_showing_desktop] = ATOM("_NET_SHOWING_DESKTOP");
|
||||||
W->net_atom[net_wm_pid] = ATOM("_NET_WM_PID");
|
net_atom[net_wm_icon_name] = ATOM("_NET_WM_ICON_NAME");
|
||||||
W->net_atom[net_wm_desktop] = ATOM("_NET_WM_DESKTOP");
|
net_atom[net_wm_window_type] = ATOM("_NET_WM_WINDOW_TYPE");
|
||||||
W->net_atom[net_showing_desktop] = ATOM("_NET_SHOWING_DESKTOP");
|
net_atom[net_supporting_wm_check] = ATOM("_NET_SUPPORTING_WM_CHECK");
|
||||||
W->net_atom[net_wm_icon_name] = ATOM("_NET_WM_ICON_NAME");
|
net_atom[net_wm_window_opacity] = ATOM("_NET_WM_WINDOW_OPACITY");
|
||||||
W->net_atom[net_wm_window_type] = ATOM("_NET_WM_WINDOW_TYPE");
|
net_atom[net_wm_window_type_normal] = ATOM("_NET_WM_WINDOW_TYPE_NORMAL");
|
||||||
W->net_atom[net_supporting_wm_check] = ATOM("_NET_SUPPORTING_WM_CHECK");
|
net_atom[net_wm_window_type_dock] = ATOM("_NET_WM_WINDOW_TYPE_DOCK");
|
||||||
W->net_atom[net_wm_window_opacity] = ATOM("_NET_WM_WINDOW_OPACITY");
|
net_atom[net_wm_window_type_splash] = ATOM("_NET_WM_WINDOW_TYPE_SPLASH");
|
||||||
W->net_atom[net_wm_window_type_normal] = ATOM("_NET_WM_WINDOW_TYPE_NORMAL");
|
net_atom[net_wm_window_type_dialog] = ATOM("_NET_WM_WINDOW_TYPE_DIALOG");
|
||||||
W->net_atom[net_wm_window_type_desktop] = ATOM("_NET_WM_WINDOW_TYPE_DESKTOP");
|
net_atom[net_wm_icon] = ATOM("_NET_WM_ICON");
|
||||||
W->net_atom[net_wm_window_type_dock] = ATOM("_NET_WM_WINDOW_TYPE_DOCK");
|
net_atom[net_wm_state] = ATOM("_NET_WM_STATE");
|
||||||
W->net_atom[net_wm_window_type_splash] = ATOM("_NET_WM_WINDOW_TYPE_SPLASH");
|
net_atom[net_wm_state_fullscreen] = ATOM("_NET_WM_STATE_FULLSCREEN");
|
||||||
W->net_atom[net_wm_window_type_dialog] = ATOM("_NET_WM_WINDOW_TYPE_DIALOG");
|
net_atom[net_wm_state_sticky] = ATOM("_NET_WM_STATE_STICKY");
|
||||||
W->net_atom[net_wm_icon] = ATOM("_NET_WM_ICON");
|
net_atom[net_wm_state_demands_attention] = ATOM("_NET_WM_STATE_DEMANDS_ATTENTION");
|
||||||
W->net_atom[net_wm_state] = ATOM("_NET_WM_STATE");
|
net_atom[net_wm_system_tray_opcode] = ATOM("_NET_SYSTEM_TRAY_OPCODE");
|
||||||
W->net_atom[net_wm_state_fullscreen] = ATOM("_NET_WM_STATE_FULLSCREEN");
|
net_atom[net_system_tray_message_data] = ATOM("_NET_SYSTEM_TRAY_MESSAGE_DATA");
|
||||||
W->net_atom[net_wm_state_sticky] = ATOM("_NET_WM_STATE_STICKY");
|
net_atom[net_system_tray_visual] = ATOM("_NET_SYSTEM_TRAY_VISUAL");
|
||||||
W->net_atom[net_wm_state_demands_attention] = ATOM("_NET_WM_STATE_DEMANDS_ATTENTION");
|
|
||||||
W->net_atom[net_wm_state_hidden] = ATOM("_NET_WM_STATE_HIDDEN");
|
snprintf(systray_atom, sizeof(systray_atom), "_NET_SYSTEM_TRAY_S%d", 0/*SCREEN*/);
|
||||||
W->net_atom[net_system_tray_s] = ATOM("_NET_SYSTEM_TRAY_S0");
|
net_atom[net_system_tray_s] = ATOM(systray_atom);
|
||||||
W->net_atom[net_system_tray_opcode] = ATOM("_NET_SYSTEM_TRAY_OPCODE");
|
|
||||||
W->net_atom[net_system_tray_message_data] = ATOM("_NET_SYSTEM_TRAY_MESSAGE_DATA");
|
net_atom[net_system_tray_orientation] = ATOM("_NET_SYSTEM_TRAY_ORIENTATION");
|
||||||
W->net_atom[net_system_tray_visual] = ATOM("_NET_SYSTEM_TRAY_VISUAL");
|
net_atom[xembed] = ATOM("_XEMBED");
|
||||||
W->net_atom[net_system_tray_orientation] = ATOM("_NET_SYSTEM_TRAY_ORIENTATION");
|
net_atom[xembedinfo] = ATOM("_XEMBED_INFO");
|
||||||
W->net_atom[xembed] = ATOM("_XEMBED");
|
net_atom[manager] = ATOM("MANAGER");
|
||||||
W->net_atom[xembedinfo] = ATOM("_XEMBED_INFO");
|
net_atom[utf8_string] = ATOM("UTF8_STRING");
|
||||||
W->net_atom[manager] = ATOM("MANAGER");
|
|
||||||
W->net_atom[utf8_string] = ATOM("UTF8_STRING");
|
|
||||||
|
|
||||||
/* WMFS hints */
|
/* WMFS hints */
|
||||||
W->net_atom[wmfs_running] = ATOM("_WMFS_RUNNING");
|
net_atom[wmfs_running] = ATOM("_WMFS_RUNNING");
|
||||||
W->net_atom[wmfs_focus] = ATOM("_WMFS_FOCUS");
|
net_atom[wmfs_update_hints] = ATOM("_WMFS_UPDATE_HINTS");
|
||||||
W->net_atom[wmfs_update_hints] = ATOM("_WMFS_UPDATE_HINTS");
|
net_atom[wmfs_update_status] = ATOM("_WMFS_UPDATE_STATUS");
|
||||||
W->net_atom[wmfs_set_screen] = ATOM("_WMFS_SET_SCREEN");
|
net_atom[wmfs_set_screen] = ATOM("_WMFS_SET_SCREEN");
|
||||||
W->net_atom[wmfs_screen_count] = ATOM("_WMFS_SCREEN_COUNT");
|
net_atom[wmfs_screen_count] = ATOM("_WMFS_SCREEN_COUNT");
|
||||||
W->net_atom[wmfs_current_tag] = ATOM("_WMFS_CURRENT_TAG");
|
net_atom[wmfs_current_tag] = ATOM("_WMFS_CURRENT_TAG");
|
||||||
W->net_atom[wmfs_tag_list] = ATOM("_WMFS_TAG_LIST");
|
net_atom[wmfs_tag_list] = ATOM("_WMFS_TAG_LIST");
|
||||||
W->net_atom[wmfs_current_screen] = ATOM("_WMFS_CURRENT_SCREEN");
|
net_atom[wmfs_current_screen] = ATOM("_WMFS_CURRENT_SCREEN");
|
||||||
W->net_atom[wmfs_current_layout] = ATOM("_WMFS_CURRENT_LAYOUT");
|
net_atom[wmfs_current_layout] = ATOM("_WMFS_CURRENT_LAYOUT");
|
||||||
W->net_atom[wmfs_function] = ATOM("_WMFS_FUNCTION");
|
net_atom[wmfs_mwfact] = ATOM("_WMFS_MWFACT");
|
||||||
W->net_atom[wmfs_cmd] = ATOM("_WMFS_CMD");
|
net_atom[wmfs_nmaster] = ATOM("_WMFS_NMASTER");
|
||||||
|
net_atom[wmfs_function] = ATOM("_WMFS_FUNCTION");
|
||||||
|
net_atom[wmfs_cmd] = ATOM("_WMFS_CMD");
|
||||||
|
net_atom[wmfs_font] = ATOM("_WMFS_FONT");
|
||||||
|
|
||||||
XChangeProperty(W->dpy, W->root, W->net_atom[net_supported], XA_ATOM, 32,
|
/* Multi atom _WMFS_STATUSTEXT_<screennum> */
|
||||||
PropModeReplace, (unsigned char*)W->net_atom, net_last);
|
for(j = 0; j < s; ++j)
|
||||||
|
{
|
||||||
|
sprintf(st, "_WMFS_STATUSTEXT_%d", j);
|
||||||
|
net_atom[wmfs_statustext + j] = ATOM(st);
|
||||||
|
}
|
||||||
|
|
||||||
XChangeProperty(W->dpy, W->root, W->net_atom[wmfs_running], XA_CARDINAL, 32,
|
XChangeProperty(dpy, ROOT, net_atom[net_supported], XA_ATOM, 32,
|
||||||
PropModeReplace, (unsigned char*)&b, 1);
|
PropModeReplace, (uchar*)net_atom, net_last + s);
|
||||||
|
|
||||||
|
XChangeProperty(dpy, ROOT, net_atom[wmfs_running], XA_CARDINAL, 32,
|
||||||
|
PropModeReplace, (uchar*)&i, 1);
|
||||||
|
|
||||||
/* Set _NET_SUPPORTING_WM_CHECK */
|
/* Set _NET_SUPPORTING_WM_CHECK */
|
||||||
XChangeProperty(W->dpy, W->root, W->net_atom[net_supporting_wm_check], XA_WINDOW, 32,
|
XChangeProperty(dpy, ROOT, net_atom[net_supporting_wm_check], XA_WINDOW, 32,
|
||||||
PropModeReplace, (unsigned char*)&W->root, 1);
|
PropModeReplace, (uchar*)&ROOT, 1);
|
||||||
|
|
||||||
XChangeProperty(W->dpy, W->root, ATOM("WM_CLASS"), XA_STRING, 8,
|
XChangeProperty(dpy, ROOT, net_atom[net_wm_name], net_atom[utf8_string], 8,
|
||||||
PropModeReplace, (unsigned char*)&"wmfs", 4);
|
PropModeReplace, (uchar*)&root_name, strlen(root_name));
|
||||||
|
|
||||||
XChangeProperty(W->dpy, W->root, W->net_atom[net_wm_name], W->net_atom[utf8_string], 8,
|
XChangeProperty(dpy, ROOT, ATOM("WM_CLASS"), XA_STRING, 8,
|
||||||
PropModeReplace, (unsigned char*)&"wmfs2", 5);
|
PropModeReplace, (uchar*)&class, strlen(class));
|
||||||
|
|
||||||
/*
|
/* Set _NET_WM_PID */
|
||||||
|
XChangeProperty(dpy, ROOT, net_atom[net_wm_pid], XA_CARDINAL, 32,
|
||||||
|
PropModeReplace, (uchar*)&pid, 1);
|
||||||
|
|
||||||
* Set _NET_WM_PID
|
/* Set _NET_SHOWING_DESKTOP */
|
||||||
XChangeProperty(W->dpy, W->root, W->net_atom[net_wm_pid], XA_CARDINAL, 32,
|
XChangeProperty(dpy, ROOT, net_atom[net_showing_desktop], XA_CARDINAL, 32,
|
||||||
PropModeReplace, (unsigned char*)&pid, 1);
|
PropModeReplace, (uchar*)&showing_desk, 1);
|
||||||
|
|
||||||
* Set _NET_SHOWING_DESKTOP
|
|
||||||
XChangeProperty(W->dpy, W->root, W->net_atom[net_showing_desktop], XA_CARDINAL, 32,
|
|
||||||
PropModeReplace, (unsigned char*)&showing_desk, 1);
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
/** Send ewmh message
|
||||||
ewmh_set_wm_state(Window w, int state)
|
|
||||||
{
|
|
||||||
unsigned char d[] = { state, None };
|
|
||||||
|
|
||||||
XChangeProperty(W->dpy, w, W->net_atom[wm_state],
|
|
||||||
W->net_atom[wm_state], 32, PropModeReplace, d, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* _NET_CLIENT_LIST
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ewmh_get_client_list(void)
|
ewmh_send_message(Window d, Window w, char *atom, long d0, long d1, long d2, long d3, long d4)
|
||||||
{
|
{
|
||||||
Window *list;
|
|
||||||
struct client *c;
|
|
||||||
int win_n = 0;
|
|
||||||
|
|
||||||
SLIST_FOREACH(c, &W->h.client, next)
|
XClientMessageEvent e;
|
||||||
++win_n;
|
|
||||||
|
|
||||||
list = xcalloc(win_n, sizeof(Window));
|
e.type = ClientMessage;
|
||||||
|
e.message_type = ATOM(atom);
|
||||||
|
e.window = w;
|
||||||
|
e.format = 32;
|
||||||
|
e.data.l[0] = d0;
|
||||||
|
e.data.l[1] = d1;
|
||||||
|
e.data.l[2] = d2;
|
||||||
|
e.data.l[3] = d3;
|
||||||
|
e.data.l[4] = d4;
|
||||||
|
|
||||||
win_n = 0;
|
XSendEvent(dpy, d, False, StructureNotifyMask, (XEvent*)&e);
|
||||||
SLIST_FOREACH(c, &W->h.client, next)
|
XSync(dpy, False);
|
||||||
list[win_n++] = c->win;
|
|
||||||
|
|
||||||
XChangeProperty(W->dpy, W->root, W->net_atom[net_client_list], XA_WINDOW, 32,
|
return;
|
||||||
PropModeReplace, (unsigned char *)list, win_n);
|
|
||||||
|
|
||||||
XFree(list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/** Get xembed state
|
||||||
* Get xembed state
|
|
||||||
*/
|
*/
|
||||||
long
|
long
|
||||||
ewmh_get_xembed_state(Window win)
|
ewmh_get_xembed_state(Window win)
|
||||||
{
|
{
|
||||||
Atom rf;
|
Atom rf;
|
||||||
int f;
|
int f;
|
||||||
|
ulong n, il;
|
||||||
long ret = 0;
|
long ret = 0;
|
||||||
unsigned long n, il;
|
uchar *data = NULL;
|
||||||
unsigned char *data = NULL;
|
|
||||||
|
|
||||||
if(XGetWindowProperty(W->dpy, win, W->net_atom[xembedinfo], 0L, 2, False,
|
if(XGetWindowProperty(dpy, win, net_atom[xembedinfo], 0L, 2, False,
|
||||||
W->net_atom[xembedinfo], &rf, &f, &n, &il, &data) != Success)
|
net_atom[xembedinfo], &rf, &f, &n, &il, &data) != Success)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if(rf == W->net_atom[xembedinfo] && n == 2)
|
if(rf == net_atom[xembedinfo] && n == 2)
|
||||||
ret = (long)data[1];
|
ret = (long)data[1];
|
||||||
|
|
||||||
if(n && data)
|
if(n && data)
|
||||||
@ -163,216 +190,260 @@ ewmh_get_xembed_state(Window win)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Get the number of desktop (tag)
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
ewmh_update_wmfs_props(void)
|
ewmh_get_number_of_desktop(void)
|
||||||
{
|
{
|
||||||
struct screen *s;
|
int c = 0, i;
|
||||||
int i, ns = 0;
|
|
||||||
long *cts = NULL;
|
|
||||||
|
|
||||||
SLIST_FOREACH(s, &W->h.screen, next)
|
for(i = 0; i < screen_count(); ++i)
|
||||||
++ns;
|
c += conf.ntag[i];
|
||||||
|
|
||||||
cts = xcalloc(ns, sizeof(long));
|
XChangeProperty(dpy, ROOT, net_atom[net_number_of_desktops], XA_CARDINAL, 32,
|
||||||
|
PropModeReplace, (uchar*)&c, 1);
|
||||||
|
|
||||||
for(i = 0; i < ns; ++i)
|
return;
|
||||||
{
|
|
||||||
s = screen_gb_id(i);
|
|
||||||
cts[i] = (s->seltag ? s->seltag->id : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
XChangeProperty(W->dpy, W->root, W->net_atom[wmfs_current_tag], XA_CARDINAL, 32,
|
|
||||||
PropModeReplace, (unsigned char*)cts, ns);
|
|
||||||
|
|
||||||
if(W->client)
|
|
||||||
XChangeProperty(W->dpy, W->root, W->net_atom[wmfs_focus], XA_WINDOW, 32,
|
|
||||||
PropModeReplace, (unsigned char*)&W->client->win, 1);
|
|
||||||
|
|
||||||
free(cts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Get the current desktop
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
ewmh_manage_state(long data[], struct client *c)
|
ewmh_update_current_tag_prop(void)
|
||||||
{
|
{
|
||||||
/* _NET_WM_STATE_FULLSCREEN */
|
int t;
|
||||||
if(data[1] == (long)W->net_atom[net_wm_state_fullscreen]
|
char s[8] = { 0 };
|
||||||
|| data[2] == (long)W->net_atom[net_wm_state_fullscreen])
|
|
||||||
{
|
|
||||||
if(data[0] == _NET_WM_STATE_ADD
|
|
||||||
|| (data[0] == _NET_WM_STATE_TOGGLE && !(c->flags & CLIENT_FULLSCREEN)))
|
|
||||||
{
|
|
||||||
c->flags |= CLIENT_FULLSCREEN;
|
|
||||||
|
|
||||||
XChangeProperty(W->dpy, c->win, W->net_atom[net_wm_state], XA_ATOM, 32, PropModeReplace,
|
screen_get_sel();
|
||||||
(unsigned char*)&W->net_atom[net_wm_state_fullscreen], 1);
|
t = seltag[selscreen] - 1;
|
||||||
XReparentWindow(W->dpy, c->win, W->root, c->screen->geo.x, c->screen->geo.y);
|
|
||||||
XResizeWindow(W->dpy, c->win, c->screen->geo.w, c->screen->geo.h);
|
|
||||||
|
|
||||||
if(c->tag)
|
/* Get current desktop (tag) */
|
||||||
|
XChangeProperty(dpy, ROOT, net_atom[net_current_desktop], XA_CARDINAL, 32,
|
||||||
|
PropModeReplace, (uchar*)&t, 1);
|
||||||
|
|
||||||
|
/* Current tag name */
|
||||||
|
XChangeProperty(dpy, ROOT, net_atom[wmfs_current_tag], net_atom[utf8_string], 8,
|
||||||
|
PropModeReplace, (uchar*)tags[selscreen][seltag[selscreen]].name,
|
||||||
|
strlen(tags[selscreen][seltag[selscreen]].name));
|
||||||
|
|
||||||
|
sprintf(s, "%.3f", tags[selscreen][t + 1].mwfact);
|
||||||
|
|
||||||
|
/* Current tag mwfact */
|
||||||
|
XChangeProperty(dpy, ROOT, net_atom[wmfs_mwfact], XA_STRING, 8,
|
||||||
|
PropModeReplace, (uchar*)s, strlen(s));
|
||||||
|
|
||||||
|
/* Current nmaster */
|
||||||
|
XChangeProperty(dpy, ROOT, net_atom[wmfs_nmaster], XA_CARDINAL, 32,
|
||||||
|
PropModeReplace, (uchar*)&tags[selscreen][t + 1].nmaster, 1);
|
||||||
|
|
||||||
|
/* Current layout */
|
||||||
|
XChangeProperty(dpy, ROOT, net_atom[wmfs_current_layout], net_atom[utf8_string], 8,
|
||||||
|
PropModeReplace, (uchar*)tags[selscreen][seltag[selscreen]].layout.symbol,
|
||||||
|
strlen(tags[selscreen][seltag[selscreen]].layout.symbol));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get _NET_CLIENT_LIST
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ewmh_get_client_list(void)
|
||||||
|
{
|
||||||
|
Window *list;
|
||||||
|
Client *c;
|
||||||
|
int 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;
|
||||||
|
|
||||||
|
XChangeProperty(dpy, ROOT, net_atom[net_client_list], XA_WINDOW, 32,
|
||||||
|
PropModeReplace, (uchar *)list, win_n);
|
||||||
|
|
||||||
|
XFree(list);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The desktop names
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ewmh_get_desktop_names(void)
|
||||||
|
{
|
||||||
|
char *str = NULL;
|
||||||
|
int S, s, i = 0, len = 0, pos = 0;
|
||||||
|
|
||||||
|
S = screen_count();
|
||||||
|
|
||||||
|
for(s = 0 ; s < S; ++s)
|
||||||
|
for(i = 1; i < conf.ntag[s] + 1; ++i)
|
||||||
|
len += strlen(tags[s][i].name);
|
||||||
|
|
||||||
|
str = xcalloc(len + i + 1, sizeof(char*));
|
||||||
|
|
||||||
|
for(s = 0; s < S; ++s)
|
||||||
|
for(i = 1; i < conf.ntag[s] + 1; ++i, ++pos)
|
||||||
|
{
|
||||||
|
strncpy(str + pos, tags[s][i].name, strlen(tags[s][i].name));
|
||||||
|
pos += strlen(tags[s][i].name);
|
||||||
|
str[pos] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
XChangeProperty(dpy, ROOT, net_atom[net_desktop_names], net_atom[utf8_string], 8,
|
||||||
|
PropModeReplace, (uchar*)str, pos);
|
||||||
|
|
||||||
|
for(i = 0; i < pos; ++i)
|
||||||
|
if(str[i] == '\0' && i < pos - 1)
|
||||||
|
str[i] = ' ';
|
||||||
|
|
||||||
|
XChangeProperty(dpy, ROOT, net_atom[wmfs_tag_list], net_atom[utf8_string], 8,
|
||||||
|
PropModeReplace, (uchar*)str, pos);
|
||||||
|
|
||||||
|
free(str);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Manage _NET_DESKTOP_GEOMETRY
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ewmh_set_desktop_geometry(void)
|
||||||
|
{
|
||||||
|
long data[2] = { MAXW, MAXH };
|
||||||
|
|
||||||
|
XChangeProperty(dpy, ROOT, net_atom[net_desktop_geometry], XA_CARDINAL, 32,
|
||||||
|
PropModeReplace, (uchar*)&data, 2);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Manage _NET_WM_STATE_* ewmh
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ewmh_manage_net_wm_state(long data_l[], Client *c)
|
||||||
|
{
|
||||||
|
/* Manage _NET_WM_STATE_FULLSCREEN */
|
||||||
|
if(data_l[1] == (long)net_atom[net_wm_state_fullscreen])
|
||||||
|
{
|
||||||
|
if(data_l[0] == _NET_WM_STATE_ADD && !(c->flags & FSSFlag))
|
||||||
|
{
|
||||||
|
c->screen = screen_get_with_geo(c->geo.x, c->geo.y);
|
||||||
|
c->flags &= ~UnmapFlag;
|
||||||
|
XMapWindow(dpy, c->win);
|
||||||
|
XReparentWindow(dpy, c->win, ROOT, spgeo[c->screen].x, spgeo[c->screen].y);
|
||||||
|
XResizeWindow(dpy, c->win,
|
||||||
|
spgeo[c->screen].width,
|
||||||
|
spgeo[c->screen].height);
|
||||||
|
XChangeProperty(dpy, c->win, net_atom[net_wm_state], XA_ATOM, 32,
|
||||||
|
PropModeReplace, (uchar *)&net_atom[net_wm_state_fullscreen], 1);
|
||||||
|
|
||||||
|
c->tmp_geo = c->geo;
|
||||||
|
|
||||||
|
if(c->flags & FreeFlag)
|
||||||
|
c->ogeo = c->geo;
|
||||||
|
|
||||||
|
c->flags |= (FSSFlag | MaxFlag);
|
||||||
|
|
||||||
|
client_raise(c);
|
||||||
client_focus(c);
|
client_focus(c);
|
||||||
|
XUnmapWindow(dpy, c->frame);
|
||||||
XRaiseWindow(W->dpy, c->win);
|
|
||||||
}
|
}
|
||||||
else
|
else if(data_l[0] == _NET_WM_STATE_REMOVE && (c->flags & FSSFlag))
|
||||||
{
|
{
|
||||||
c->flags &= ~CLIENT_FULLSCREEN;
|
XChangeProperty(dpy, c->win, net_atom[net_wm_state], XA_ATOM, 32, PropModeReplace, (uchar *)0, 0);
|
||||||
|
c->flags &= ~(FSSFlag | MaxFlag);
|
||||||
XChangeProperty(W->dpy, c->win, W->net_atom[net_wm_state], XA_ATOM, 32, PropModeReplace,
|
client_map(c);
|
||||||
(unsigned char*)0, 0);
|
XReparentWindow(dpy, c->win, c->frame, BORDH, TBARH);
|
||||||
XReparentWindow(W->dpy, c->win, c->frame, c->wgeo.x, c->wgeo.y);
|
client_moveresize(c, c->tmp_geo, False);
|
||||||
|
|
||||||
if(c->flags & CLIENT_FREE)
|
|
||||||
client_moveresize(c, &c->geo);
|
|
||||||
else
|
|
||||||
layout_fix_hole(c);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* Manage _NET_WM_STATE_STICKY */
|
||||||
|
else if(data_l[1] == (long)net_atom[net_wm_state_sticky])
|
||||||
|
{
|
||||||
|
/* == client_ignore_tag */
|
||||||
|
c->tag = MAXTAG + 1;
|
||||||
|
arrange(c->screen, True);
|
||||||
|
}
|
||||||
|
/* Manage _NET_WM_STATE_DEMANDS_ATTENTION */
|
||||||
|
else if(data_l[1] == (long)net_atom[net_wm_state_demands_attention])
|
||||||
|
{
|
||||||
|
if(data_l[0] == _NET_WM_STATE_ADD)
|
||||||
|
client_urgent(c, True);
|
||||||
|
if(data_l[0] == _NET_WM_STATE_REMOVE)
|
||||||
|
if(c == sel)
|
||||||
|
client_focus(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
ewmh_manage_state_sticky(Window win)
|
|
||||||
{
|
|
||||||
Atom *atom, rf;
|
|
||||||
int f;
|
|
||||||
unsigned long n, il, i;
|
|
||||||
unsigned char *data = NULL;
|
|
||||||
bool is_sticky = false;
|
|
||||||
|
|
||||||
if(XGetWindowProperty(W->dpy, win, W->net_atom[net_wm_state], 0L, 0x7FFFFFFFL, false,
|
|
||||||
XA_ATOM, &rf, &f, &n, &il, &data) == Success && n)
|
|
||||||
{
|
|
||||||
atom = (Atom*)data;
|
|
||||||
|
|
||||||
for(i = 0; i < n; ++i)
|
|
||||||
{
|
|
||||||
/* manage _NET_WM_STATE_STICKY */
|
|
||||||
if(atom[i] == W->net_atom[net_wm_state_sticky])
|
|
||||||
{
|
|
||||||
XWindowAttributes at;
|
|
||||||
|
|
||||||
XMapWindow(W->dpy, win);
|
|
||||||
XMapSubwindows(W->dpy, win);
|
|
||||||
|
|
||||||
if(XGetWindowAttributes(W->dpy, win, &at))
|
|
||||||
{
|
|
||||||
struct geo g;
|
|
||||||
|
|
||||||
if(at.x < W->screen->ugeo.x)
|
|
||||||
g.x = W->screen->ugeo.x;
|
|
||||||
else if((at.x + at.width) > W->screen->ugeo.w)
|
|
||||||
g.x = W->screen->ugeo.w - at.width;
|
|
||||||
else
|
|
||||||
g.x = at.x;
|
|
||||||
|
|
||||||
if(at.y < W->screen->ugeo.y)
|
|
||||||
g.y = W->screen->ugeo.y;
|
|
||||||
else if((at.y + at.height) > W->screen->ugeo.h)
|
|
||||||
g.y = W->screen->ugeo.h - at.height;
|
|
||||||
else
|
|
||||||
g.y = at.y;
|
|
||||||
|
|
||||||
XMoveWindow(W->dpy, win, g.x, g.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(W->client)
|
|
||||||
{
|
|
||||||
XUngrabButton(W->dpy, AnyButton, AnyModifier, W->client->win);
|
|
||||||
XGrabButton(W->dpy, AnyButton, AnyModifier, W->client->win, False,
|
|
||||||
ButtonMask, GrabModeAsync, GrabModeSync, None, None);
|
|
||||||
|
|
||||||
client_frame_update(W->client, &W->client->ncol);
|
|
||||||
|
|
||||||
W->client = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
XRaiseWindow(W->dpy, win);
|
|
||||||
|
|
||||||
XSetInputFocus(W->dpy, win, RevertToPointerRoot, CurrentTime);
|
|
||||||
XChangeProperty(W->dpy, W->root, W->net_atom[net_active_window], XA_WINDOW, 32,
|
|
||||||
PropModeReplace, (unsigned char *)&win, 1);
|
|
||||||
|
|
||||||
is_sticky = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
XFree(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
return is_sticky;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/** Manage the client hints
|
||||||
|
*\param c Client pointer
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
ewmh_manage_window_type(struct client *c)
|
ewmh_manage_window_type(Client *c)
|
||||||
{
|
{
|
||||||
Atom *atom, rf;
|
Atom *atom, rf;
|
||||||
int f;
|
int f;
|
||||||
unsigned long n, il, i;
|
ulong n, il, i;
|
||||||
unsigned char *data = NULL;
|
uchar *data = NULL;
|
||||||
long ldata[5] = { _NET_WM_STATE_ADD };
|
long ldata[5] = { 0 };
|
||||||
|
|
||||||
if(XGetWindowProperty(W->dpy, c->win, W->net_atom[net_wm_window_type], 0L, 0x7FFFFFFFL,
|
if(XGetWindowProperty(dpy, c->win, net_atom[net_wm_window_type], 0L, 0x7FFFFFFFL,
|
||||||
False, XA_ATOM, &rf, &f, &n, &il, &data) == Success && n)
|
False, XA_ATOM, &rf, &f, &n, &il, &data) == Success && n)
|
||||||
{
|
{
|
||||||
atom = (Atom*)data;
|
atom = (Atom*)data;
|
||||||
|
|
||||||
for(i = 0; i < n; ++i)
|
for(i = 0; i < n; ++i)
|
||||||
{
|
{
|
||||||
|
/* Manage _NET_WM_WINDOW_TYPE_DOCK & _NET_WM_WINDOW_TYPE_SPLASH */
|
||||||
|
if(atom[i] == net_atom[net_wm_window_type_dock]
|
||||||
|
|| atom[i] == net_atom[net_wm_window_type_splash])
|
||||||
|
{
|
||||||
|
/* Unmap frame, decoration.. */
|
||||||
|
client_unmap(c);
|
||||||
|
|
||||||
|
/* Map only window */
|
||||||
|
XMapWindow(dpy, c->win);
|
||||||
|
|
||||||
|
/* Reparent it to ROOT win */
|
||||||
|
XReparentWindow(dpy, c->win, ROOT, c->geo.x, c->geo.y);
|
||||||
|
XRaiseWindow(dpy, c->win);
|
||||||
|
|
||||||
|
c->flags |= DockFlag;
|
||||||
|
}
|
||||||
/* MANAGE _NET_WM_WINDOW_TYPE_DIALOG */
|
/* MANAGE _NET_WM_WINDOW_TYPE_DIALOG */
|
||||||
if(atom[i] == W->net_atom[net_wm_window_type_dialog])
|
else if(atom[i] == net_atom[net_wm_window_type_dialog])
|
||||||
c->flags |= CLIENT_FREE;
|
{
|
||||||
|
c->flags |= FreeFlag;
|
||||||
|
c->flags &= ~(TileFlag | MaxFlag | LMaxFlag);
|
||||||
|
client_moveresize(c, c->ogeo, True);
|
||||||
|
client_focus(c);
|
||||||
|
tags[selscreen][seltag[selscreen]].layout.func(selscreen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
XFree(data);
|
XFree(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* _NET_WM_STATE at window mangement */
|
/* Get NET_WM_STATE set without sending client message event */
|
||||||
if(XGetWindowProperty(W->dpy, c->win, W->net_atom[net_wm_state], 0L, 0x7FFFFFFFL, false,
|
if(XGetWindowProperty(dpy, c->win, net_atom[net_wm_state], 0L, 0x7FFFFFFFL,
|
||||||
XA_ATOM, &rf, &f, &n, &il, &data) == Success && n)
|
|
||||||
{
|
|
||||||
atom = (Atom*)data;
|
|
||||||
|
|
||||||
for(i = 0; i < n; ++i)
|
|
||||||
{
|
|
||||||
ldata[1] = atom[i];
|
|
||||||
ewmh_manage_state(ldata, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
XFree(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
ewmh_manage_window_type_desktop(Window win)
|
|
||||||
{
|
|
||||||
Atom *atom, rf;
|
|
||||||
int f;
|
|
||||||
unsigned long n, il, i;
|
|
||||||
unsigned char *data = NULL;
|
|
||||||
bool is_desktop = false;
|
|
||||||
|
|
||||||
if(XGetWindowProperty(W->dpy, win, W->net_atom[net_wm_window_type], 0L, 0x7FFFFFFF,
|
|
||||||
False, XA_ATOM, &rf, &f, &n, &il, &data) == Success && n)
|
False, XA_ATOM, &rf, &f, &n, &il, &data) == Success && n)
|
||||||
{
|
{
|
||||||
atom = (Atom*)data;
|
atom = (Atom*)data;
|
||||||
|
|
||||||
for(i = 0; i < n; ++i)
|
for(i = 0; i < n; ++i)
|
||||||
{
|
{
|
||||||
/* If it is a _NET_WM_WINDOW_TYPE_DESKTOP window */
|
ldata[0] = _NET_WM_STATE_ADD;
|
||||||
if(atom[i] == W->net_atom[net_wm_window_type_desktop])
|
ldata[1] = atom[i];
|
||||||
{
|
ewmh_manage_net_wm_state(ldata, c);
|
||||||
/* map it, but don't manage it */
|
|
||||||
XMapWindow(W->dpy, win);
|
|
||||||
XMapSubwindows(W->dpy, win);
|
|
||||||
|
|
||||||
is_desktop = true;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
XFree(data);
|
XFree(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return is_desktop;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
131
src/ewmh.h
131
src/ewmh.h
@ -1,131 +0,0 @@
|
|||||||
/*
|
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
|
||||||
* For license, see COPYING.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef EWMH_H
|
|
||||||
#define EWMH_H
|
|
||||||
|
|
||||||
#include <X11/Xatom.h>
|
|
||||||
#include <X11/Xutil.h>
|
|
||||||
|
|
||||||
#include "wmfs.h"
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
/* EWMH/Xembed const from freedesktop */
|
|
||||||
#define XEMBED_MAPPED (1 << 0)
|
|
||||||
#define XEMBED_EMBEDDED_NOTIFY 0
|
|
||||||
#define XEMBED_WINDOW_ACTIVATE 1
|
|
||||||
#define XEMBED_WINDOW_DEACTIVATE 2
|
|
||||||
#define XEMBED_REQUEST_FOCUS 3
|
|
||||||
#define XEMBED_FOCUS_IN 4
|
|
||||||
#define XEMBED_FOCUS_OUT 5
|
|
||||||
#define XEMBED_FOCUS_NEXT 6
|
|
||||||
#define XEMBED_FOCUS_PREV 7
|
|
||||||
/* 8-9 were used for XEMBED_GRAB_KEY/XEMBED_UNGRAB_KEY */
|
|
||||||
#define XEMBED_MODALITY_ON 10
|
|
||||||
#define XEMBED_MODALITY_OFF 11
|
|
||||||
#define XEMBED_REGISTER_ACCELERATOR 12
|
|
||||||
#define XEMBED_UNREGISTER_ACCELERATOR 13
|
|
||||||
#define XEMBED_ACTIVATE_ACCELERATOR 14
|
|
||||||
|
|
||||||
/* Details for XEMBED_FOCUS_IN: */
|
|
||||||
#define XEMBED_FOCUS_CURRENT 0
|
|
||||||
#define XEMBED_FOCUS_FIRST 1
|
|
||||||
#define XEMBED_FOCUS_LAST 2
|
|
||||||
|
|
||||||
/* Ewmh hints list */
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
/* ICCCM */
|
|
||||||
wm_state,
|
|
||||||
wm_class,
|
|
||||||
wm_name,
|
|
||||||
/* EWMH */
|
|
||||||
net_supported,
|
|
||||||
net_wm_name,
|
|
||||||
net_client_list,
|
|
||||||
net_frame_extents,
|
|
||||||
net_number_of_desktops,
|
|
||||||
net_current_desktop,
|
|
||||||
net_desktop_names,
|
|
||||||
net_desktop_geometry,
|
|
||||||
net_active_window,
|
|
||||||
net_close_window,
|
|
||||||
net_wm_icon_name,
|
|
||||||
net_wm_window_type,
|
|
||||||
net_wm_pid,
|
|
||||||
net_showing_desktop,
|
|
||||||
net_supporting_wm_check,
|
|
||||||
net_wm_window_opacity,
|
|
||||||
net_wm_window_type_normal,
|
|
||||||
net_wm_window_type_desktop,
|
|
||||||
net_wm_window_type_dock,
|
|
||||||
net_wm_window_type_splash,
|
|
||||||
net_wm_window_type_dialog,
|
|
||||||
net_wm_desktop,
|
|
||||||
net_wm_icon,
|
|
||||||
net_wm_state,
|
|
||||||
net_wm_state_fullscreen,
|
|
||||||
net_wm_state_sticky,
|
|
||||||
net_wm_state_demands_attention,
|
|
||||||
net_wm_state_hidden,
|
|
||||||
net_system_tray_opcode,
|
|
||||||
net_system_tray_message_data,
|
|
||||||
net_system_tray_s,
|
|
||||||
net_system_tray_visual,
|
|
||||||
net_system_tray_orientation,
|
|
||||||
xembed,
|
|
||||||
xembedinfo,
|
|
||||||
manager,
|
|
||||||
utf8_string,
|
|
||||||
/* WMFS HINTS */
|
|
||||||
wmfs_running,
|
|
||||||
wmfs_focus,
|
|
||||||
wmfs_update_hints,
|
|
||||||
wmfs_current_tag,
|
|
||||||
wmfs_current_screen,
|
|
||||||
wmfs_current_layout,
|
|
||||||
wmfs_tag_list,
|
|
||||||
wmfs_mwfact,
|
|
||||||
wmfs_nmaster,
|
|
||||||
wmfs_set_screen,
|
|
||||||
wmfs_screen_count,
|
|
||||||
wmfs_function,
|
|
||||||
wmfs_cmd,
|
|
||||||
wmfs_font,
|
|
||||||
wmfs_statustext,
|
|
||||||
net_last
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
ewmh_send_message(Window d, Window w, char *atom, long d0, long d1, long d2, long d3, long d4)
|
|
||||||
{
|
|
||||||
XClientMessageEvent e;
|
|
||||||
|
|
||||||
e.type = ClientMessage;
|
|
||||||
e.message_type = ATOM(atom);
|
|
||||||
e.window = w;
|
|
||||||
e.format = 32;
|
|
||||||
e.data.l[0] = d0;
|
|
||||||
e.data.l[1] = d1;
|
|
||||||
e.data.l[2] = d2;
|
|
||||||
e.data.l[3] = d3;
|
|
||||||
e.data.l[4] = d4;
|
|
||||||
|
|
||||||
XSendEvent(W->dpy, d, false, StructureNotifyMask, (XEvent*)&e);
|
|
||||||
XSync(W->dpy, False);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ewmh_init(void);
|
|
||||||
void ewmh_set_wm_state(Window w, int state);
|
|
||||||
void ewmh_get_client_list(void);
|
|
||||||
long ewmh_get_xembed_state(Window win);
|
|
||||||
void ewmh_update_wmfs_props(void);
|
|
||||||
void ewmh_manage_state(long data[], struct client *c);
|
|
||||||
bool ewmh_manage_state_sticky(Window win);
|
|
||||||
void ewmh_manage_window_type(struct client *c);
|
|
||||||
bool ewmh_manage_window_type_desktop(Window win);
|
|
||||||
|
|
||||||
#endif /* EWMH_H */
|
|
||||||
19
src/fifo.h
19
src/fifo.h
@ -1,19 +0,0 @@
|
|||||||
/*
|
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
|
||||||
* File created by David Delassus.
|
|
||||||
* For license, see COPYING.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __FIFO_H
|
|
||||||
#define __FIFO_H
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
void fifo_init(void);
|
|
||||||
void fifo_read(void);
|
|
||||||
|
|
||||||
#endif /* __FIFO_H */
|
|
||||||
322
src/frame.c
Normal file
322
src/frame.c
Normal file
@ -0,0 +1,322 @@
|
|||||||
|
/*
|
||||||
|
* frame.c
|
||||||
|
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of the nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "wmfs.h"
|
||||||
|
|
||||||
|
/** Frame creation function, for make a
|
||||||
|
* client frame, and configure it
|
||||||
|
* \param c Client pointer
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
frame_create(Client *c)
|
||||||
|
{
|
||||||
|
XSetWindowAttributes at;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
at.background_pixel = conf.client.bordernormal;
|
||||||
|
at.background_pixmap = ParentRelative;
|
||||||
|
at.override_redirect = True;
|
||||||
|
at.bit_gravity = StaticGravity;
|
||||||
|
at.event_mask = SubstructureRedirectMask|SubstructureNotifyMask
|
||||||
|
|ExposureMask|VisibilityChangeMask
|
||||||
|
|EnterWindowMask|LeaveWindowMask|FocusChangeMask
|
||||||
|
|KeyMask|ButtonMask|MouseMask;
|
||||||
|
|
||||||
|
/* Set property */
|
||||||
|
c->frame_geo.x = c->geo.x - BORDH;
|
||||||
|
c->frame_geo.y = c->geo.y - TBARH;
|
||||||
|
c->frame_geo.width = FRAMEW(c->geo.width);
|
||||||
|
c->frame_geo.height = FRAMEH(c->geo.height);
|
||||||
|
c->colors.fg = conf.titlebar.fg_normal;
|
||||||
|
c->colors.frame = conf.client.bordernormal;
|
||||||
|
c->colors.resizecorner = conf.client.resizecorner_normal;
|
||||||
|
|
||||||
|
/* Create frame window */
|
||||||
|
CWIN(c->frame, ROOT,
|
||||||
|
c->frame_geo.x,
|
||||||
|
c->frame_geo.y,
|
||||||
|
c->frame_geo.width,
|
||||||
|
c->frame_geo.height, 0,
|
||||||
|
CWOverrideRedirect | CWBackPixmap | CWEventMask,
|
||||||
|
c->colors.frame, &at);
|
||||||
|
|
||||||
|
|
||||||
|
/* Create titlebar window */
|
||||||
|
if(TBARH - BORDH)
|
||||||
|
{
|
||||||
|
c->titlebar = barwin_create(c->frame, 0, 0,
|
||||||
|
c->frame_geo.width ,
|
||||||
|
TBARH,
|
||||||
|
c->colors.frame,
|
||||||
|
c->colors.fg,
|
||||||
|
True, conf.titlebar.stipple.active, False);
|
||||||
|
|
||||||
|
/* Buttons */
|
||||||
|
if(BUTTONWH >= 1)
|
||||||
|
{
|
||||||
|
c->button = xcalloc(conf.titlebar.nbutton, sizeof(Window));
|
||||||
|
for(i = 0; i < conf.titlebar.nbutton; ++i)
|
||||||
|
{
|
||||||
|
CWIN(c->button[i], c->titlebar->win,
|
||||||
|
(c->button_last_x = (BORDH + (BUTTONWH * i) + (4 * i))),
|
||||||
|
((BUTTONWH - 1) / 2), BUTTONWH, BUTTONWH,
|
||||||
|
1, CWEventMask|CWOverrideRedirect|CWBackPixmap,
|
||||||
|
c->colors.frame, &at);
|
||||||
|
|
||||||
|
XSetWindowBorder(dpy, c->button[i], getcolor(c->colors.fg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
at.event_mask &= ~(EnterWindowMask | LeaveWindowMask); /* <- Delete useless mask */
|
||||||
|
|
||||||
|
/* Create resize area */
|
||||||
|
at.cursor = cursor[CurRightResize];
|
||||||
|
CWIN(c->resize[Right], c->frame,
|
||||||
|
c->frame_geo.width - RESHW,
|
||||||
|
c->frame_geo.height - RESHW,
|
||||||
|
RESHW, RESHW, 0,
|
||||||
|
CWEventMask | CWBackPixel | CWCursor,
|
||||||
|
c->colors.resizecorner, &at);
|
||||||
|
|
||||||
|
at.cursor = cursor[CurLeftResize];
|
||||||
|
CWIN(c->resize[Left], c->frame,
|
||||||
|
0, c->frame_geo.height - RESHW,
|
||||||
|
RESHW, RESHW, 0,
|
||||||
|
CWEventMask | CWBackPixel | CWCursor,
|
||||||
|
c->colors.resizecorner, &at);
|
||||||
|
|
||||||
|
/* Border (for shadow) */
|
||||||
|
if(conf.client.border_shadow)
|
||||||
|
{
|
||||||
|
c->colors.borddark = color_shade(c->colors.frame, conf.colors.client_dark_shade);
|
||||||
|
c->colors.bordlight = color_shade(c->colors.frame, conf.colors.client_light_shade);
|
||||||
|
|
||||||
|
CWIN(c->left, c->frame, 0, 0, SHADH, c->frame_geo.height, 0, CWBackPixel, c->colors.bordlight, &at);
|
||||||
|
CWIN(c->top, c->frame, 0, 0, c->frame_geo.width, SHADH, 0, CWBackPixel, c->colors.bordlight, &at);
|
||||||
|
CWIN(c->bottom, c->frame, 0, c->frame_geo.height - SHADH, c->frame_geo.width, SHADH, 0, CWBackPixel, c->colors.borddark, &at);
|
||||||
|
CWIN(c->right, c->frame, c->frame_geo.width - SHADH, 0, SHADH, c->frame_geo.height, 0, CWBackPixel, c->colors.borddark, &at);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reparent window with the frame */
|
||||||
|
XReparentWindow(dpy, c->win, c->frame, BORDH, TBARH);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Delete a frame
|
||||||
|
* \param c The client frame
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
frame_delete(Client *c)
|
||||||
|
{
|
||||||
|
/* If there is, delete the titlebar */
|
||||||
|
if(TBARH - BORDH)
|
||||||
|
{
|
||||||
|
barwin_delete_subwin(c->titlebar);
|
||||||
|
barwin_delete(c->titlebar);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Delete the frame's sub win and the frame */
|
||||||
|
XDestroySubwindows(dpy, c->frame);
|
||||||
|
XDestroyWindow(dpy, c->frame);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Move a frame
|
||||||
|
* \param c The client frame
|
||||||
|
* \param geo Coordinate info for move the frame
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
frame_moveresize(Client *c, XRectangle geo)
|
||||||
|
{
|
||||||
|
CHECK(c);
|
||||||
|
|
||||||
|
c->frame_geo.x = (geo.x) ? geo.x - BORDH : c->frame_geo.x;
|
||||||
|
c->frame_geo.y = (geo.y) ? geo.y - TBARH : c->frame_geo.y;
|
||||||
|
c->frame_geo.width = (geo.width) ? FRAMEW(geo.width) : c->frame_geo.width;
|
||||||
|
c->frame_geo.height = (geo.height) ? FRAMEH(geo.height) : c->frame_geo.height;
|
||||||
|
|
||||||
|
/* Frame */
|
||||||
|
XMoveResizeWindow(dpy, c->frame,
|
||||||
|
c->frame_geo.x,
|
||||||
|
c->frame_geo.y,
|
||||||
|
c->frame_geo.width,
|
||||||
|
c->frame_geo.height);
|
||||||
|
|
||||||
|
/* Titlebar */
|
||||||
|
if(TBARH - BORDH)
|
||||||
|
barwin_resize(c->titlebar, c->frame_geo.width, TBARH);
|
||||||
|
|
||||||
|
/* Resize area */
|
||||||
|
XMoveWindow(dpy, c->resize[Right], c->frame_geo.width - RESHW, c->frame_geo.height - RESHW);
|
||||||
|
XMoveWindow(dpy, c->resize[Left], 0, c->frame_geo.height - RESHW);
|
||||||
|
|
||||||
|
/* Border */
|
||||||
|
if(conf.client.border_shadow)
|
||||||
|
{
|
||||||
|
XResizeWindow(dpy, c->left, SHADH, c->frame_geo.height - SHADH);
|
||||||
|
XResizeWindow(dpy, c->top, c->frame_geo.width, SHADH);
|
||||||
|
XMoveResizeWindow(dpy, c->bottom, 0, c->frame_geo.height - SHADH, c->frame_geo.width, SHADH);
|
||||||
|
XMoveResizeWindow(dpy, c->right, c->frame_geo.width - SHADH, 0, SHADH, c->frame_geo.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Update frame colors for focus event
|
||||||
|
*\param c Client pointer
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
frame_update_color(Client *c, Bool focused)
|
||||||
|
{
|
||||||
|
CHECK(c);
|
||||||
|
|
||||||
|
/* Not focused client */
|
||||||
|
if(focused)
|
||||||
|
{
|
||||||
|
c->colors.frame = conf.client.bordernormal;
|
||||||
|
c->colors.fg = conf.titlebar.fg_normal;
|
||||||
|
c->colors.resizecorner = conf.client.resizecorner_normal;
|
||||||
|
|
||||||
|
if(TBARH - BORDH && c->titlebar->stipple)
|
||||||
|
c->titlebar->stipple_color = conf.titlebar.stipple.colors.normal;
|
||||||
|
}
|
||||||
|
/* Focused */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c->colors.frame = conf.client.borderfocus;
|
||||||
|
c->colors.fg = conf.titlebar.fg_focus;
|
||||||
|
c->colors.resizecorner = conf.client.resizecorner_focus;
|
||||||
|
|
||||||
|
if(TBARH - BORDH && c->titlebar->stipple)
|
||||||
|
c->titlebar->stipple_color = conf.titlebar.stipple.colors.focus;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(conf.client.border_shadow)
|
||||||
|
{
|
||||||
|
c->colors.borddark = color_shade(c->colors.frame, conf.colors.client_dark_shade);
|
||||||
|
c->colors.bordlight = color_shade(c->colors.frame, conf.colors.client_light_shade);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Update the client frame; Set the new color
|
||||||
|
* and the title --> refresh
|
||||||
|
* \param c Client pointer
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
frame_update(Client *c)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
CHECK(c);
|
||||||
|
|
||||||
|
if(TBARH - BORDH)
|
||||||
|
{
|
||||||
|
c->titlebar->bg = c->colors.frame;
|
||||||
|
c->titlebar->fg = c->colors.fg;
|
||||||
|
|
||||||
|
barwin_refresh_color(c->titlebar);
|
||||||
|
|
||||||
|
/* Buttons */
|
||||||
|
if(conf.titlebar.nbutton && BUTTONWH >= 1)
|
||||||
|
{
|
||||||
|
if(conf.titlebar.stipple.active)
|
||||||
|
draw_rectangle(c->titlebar->dr, 0, 0, c->button_last_x + TBARH - (TBARH / 4),
|
||||||
|
TBARH + BORDH * 2, c->colors.frame);
|
||||||
|
|
||||||
|
for(i = 0; i < conf.titlebar.nbutton; ++i)
|
||||||
|
{
|
||||||
|
XSetWindowBackground(dpy, c->button[i], c->colors.frame);
|
||||||
|
XClearWindow(dpy, c->button[i]);
|
||||||
|
|
||||||
|
if((!conf.titlebar.button[i].flags)
|
||||||
|
|| ((conf.titlebar.button[i].flags & FreeFlag)
|
||||||
|
&& ((c->flags & FreeFlag) || !(c->flags & (TileFlag | LMaxFlag))))
|
||||||
|
|| ((conf.titlebar.button[i].flags & MaxFlag)
|
||||||
|
&& ((c->flags & MaxFlag) || (c->flags & LMaxFlag)))
|
||||||
|
|| ((conf.titlebar.button[i].flags & TileFlag) && (c->flags & TileFlag)))
|
||||||
|
{
|
||||||
|
|
||||||
|
XSetWindowBorder(dpy, c->button[i], getcolor(c->colors.fg));
|
||||||
|
|
||||||
|
/* Button's lines */
|
||||||
|
if(conf.titlebar.button[i].nlines)
|
||||||
|
{
|
||||||
|
XSetForeground(dpy, gc, getcolor(c->colors.fg));
|
||||||
|
XDrawSegments(dpy, c->button[i], gc,
|
||||||
|
conf.titlebar.button[i].linecoord,
|
||||||
|
conf.titlebar.button[i].nlines);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
XSetWindowBorder(dpy, c->button[i], c->colors.frame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
barwin_refresh(c->titlebar);
|
||||||
|
}
|
||||||
|
|
||||||
|
XSetWindowBackground(dpy, c->frame, c->colors.frame);
|
||||||
|
XSetWindowBackground(dpy, c->resize[Right], c->colors.resizecorner);
|
||||||
|
XSetWindowBackground(dpy, c->resize[Left], c->colors.resizecorner);
|
||||||
|
XClearWindow(dpy, c->frame);
|
||||||
|
XClearWindow(dpy, c->resize[Right]);
|
||||||
|
XClearWindow(dpy, c->resize[Left]);
|
||||||
|
|
||||||
|
|
||||||
|
if(conf.client.border_shadow)
|
||||||
|
{
|
||||||
|
XSetWindowBackground(dpy, c->left, c->colors.bordlight);
|
||||||
|
XSetWindowBackground(dpy, c->top, c->colors.bordlight);
|
||||||
|
XSetWindowBackground(dpy, c->right, c->colors.borddark);
|
||||||
|
XSetWindowBackground(dpy, c->bottom, c->colors.borddark);
|
||||||
|
|
||||||
|
XClearWindow(dpy, c->left);
|
||||||
|
XClearWindow(dpy, c->top);
|
||||||
|
XClearWindow(dpy, c->right);
|
||||||
|
XClearWindow(dpy, c->bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(TBARH - BORDH)
|
||||||
|
barwin_draw_text(c->titlebar,
|
||||||
|
(c->frame_geo.width / 2) - (textw(c->title) / 2),
|
||||||
|
((font->height - font->descent) + (TBARH - font->height) / 2),
|
||||||
|
c->title);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
203
src/getinfo.c
Normal file
203
src/getinfo.c
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
/*
|
||||||
|
* getinfo.c
|
||||||
|
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of the nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "wmfs.h"
|
||||||
|
|
||||||
|
/* Global variables for each XGetWindowProperty
|
||||||
|
* of each getinfo functions.
|
||||||
|
*/
|
||||||
|
Atom rt;
|
||||||
|
int rf;
|
||||||
|
ulong ir, il;
|
||||||
|
uchar *ret;
|
||||||
|
|
||||||
|
/** Get information about tag (current, list, names)
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
getinfo_tag(void)
|
||||||
|
{
|
||||||
|
int tag = 0;
|
||||||
|
char *tag_name = NULL;
|
||||||
|
char *tag_list = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
if(XGetWindowProperty(dpy, ROOT, ATOM("_NET_CURRENT_DESKTOP"), 0L, 4096,
|
||||||
|
False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret) == Success && ret)
|
||||||
|
{
|
||||||
|
tag = (int)*ret + 1;
|
||||||
|
XFree(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(XGetWindowProperty(dpy, ROOT, ATOM("_WMFS_CURRENT_TAG"), 0L, 4096,
|
||||||
|
False, ATOM("UTF8_STRING"), &rt, &rf, &ir, &il, &ret) == Success && ret)
|
||||||
|
{
|
||||||
|
tag_name = xstrdup((char*)ret);
|
||||||
|
XFree(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(XGetWindowProperty(dpy, ROOT, ATOM("_WMFS_TAG_LIST"), 0L, 4096,
|
||||||
|
False, ATOM("UTF8_STRING"), &rt, &rf, &ir, &il, &ret) == Success && ret)
|
||||||
|
{
|
||||||
|
tag_list = xstrdup((char*)ret);
|
||||||
|
XFree(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Current tag: %d - %s\n", tag, tag_name);
|
||||||
|
printf("Tag list: %s\n", tag_list);
|
||||||
|
|
||||||
|
free(tag_name);
|
||||||
|
free(tag_list);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get information about screens
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
getinfo_screen(void)
|
||||||
|
{
|
||||||
|
int screen = 1;
|
||||||
|
int screen_num = 1;
|
||||||
|
|
||||||
|
if(XGetWindowProperty(dpy, ROOT, ATOM("_WMFS_CURRENT_SCREEN"), 0L, 4096,
|
||||||
|
False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret) == Success && ret)
|
||||||
|
{
|
||||||
|
screen = (int)*ret + 1;
|
||||||
|
XFree(ret);
|
||||||
|
}
|
||||||
|
if(XGetWindowProperty(dpy, ROOT, ATOM("_WMFS_SCREEN_COUNT"), 0L, 4096,
|
||||||
|
False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret) == Success && ret)
|
||||||
|
{
|
||||||
|
screen_num = (int)*ret;
|
||||||
|
XFree(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Current screen: %d\nScreen number: %d\n", screen, screen_num);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get current layout name
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
getinfo_layout(void)
|
||||||
|
{
|
||||||
|
char *layout = NULL;
|
||||||
|
|
||||||
|
if(XGetWindowProperty(dpy, ROOT, ATOM("_WMFS_CURRENT_LAYOUT"), 0L, 4096,
|
||||||
|
False, ATOM("UTF8_STRING"), &rt, &rf, &ir, &il, &ret) == Success && ret)
|
||||||
|
{
|
||||||
|
layout = xstrdup((char*)ret);
|
||||||
|
XFree(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Current layout: %s\n", layout);
|
||||||
|
|
||||||
|
free(layout);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get information about current mwfact
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
getinfo_mwfact(void)
|
||||||
|
{
|
||||||
|
char *mwfact = NULL;
|
||||||
|
|
||||||
|
if(XGetWindowProperty(dpy, ROOT, ATOM("_WMFS_MWFACT"), 0L, 4096,
|
||||||
|
False, XA_STRING, &rt, &rf, &ir, &il, &ret) == Success && ret)
|
||||||
|
{
|
||||||
|
mwfact = xstrdup((char*)ret);
|
||||||
|
XFree(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Current mwfact: %s\n", mwfact);
|
||||||
|
|
||||||
|
free(mwfact);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get information about current nmaster
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
getinfo_nmaster(void)
|
||||||
|
{
|
||||||
|
int nmaster = 1;
|
||||||
|
|
||||||
|
if(XGetWindowProperty(dpy, ROOT, ATOM("_WMFS_NMASTER"), 0L, 4096,
|
||||||
|
False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret) == Success && ret)
|
||||||
|
{
|
||||||
|
nmaster = (int)*ret;
|
||||||
|
XFree(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Current nmaster: %d\n", nmaster);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get information about wmfs
|
||||||
|
*\param info Type of information in a string
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
getinfo(char *info)
|
||||||
|
{
|
||||||
|
if(!check_wmfs_running())
|
||||||
|
return;
|
||||||
|
|
||||||
|
ewmh_send_message(ROOT, ROOT, "_WMFS_UPDATE_HINTS", 0, 0, 0, 0, True);
|
||||||
|
|
||||||
|
if(!strcmp(info, "tag"))
|
||||||
|
getinfo_tag();
|
||||||
|
else if(!strcmp(info, "screen"))
|
||||||
|
getinfo_screen();
|
||||||
|
else if(!strcmp(info, "layout"))
|
||||||
|
getinfo_layout();
|
||||||
|
else if(!strcmp(info, "mwfact"))
|
||||||
|
getinfo_mwfact();
|
||||||
|
else if(!strcmp(info, "nmaster"))
|
||||||
|
getinfo_nmaster();
|
||||||
|
else if(!strcmp(info, "help"))
|
||||||
|
printf("Argument list for wmfs -g options:\n"
|
||||||
|
" tag Show current tag number and name, and tag list.\n"
|
||||||
|
" screen Show current screen and screens number.\n"
|
||||||
|
" layout Show current layout name.\n"
|
||||||
|
" mwfact Show mwfact of current tag.\n"
|
||||||
|
" nmaster Show nmaster of current tag.\n");
|
||||||
|
else
|
||||||
|
warnx("Unknow info argument '%s'\nTry 'wmfs -g help'", info);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
986
src/infobar.c
986
src/infobar.c
File diff suppressed because it is too large
Load Diff
@ -1,93 +0,0 @@
|
|||||||
/*
|
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
|
||||||
* For license, see COPYING.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef INFOBAR_H
|
|
||||||
#define INFOBAR_H
|
|
||||||
|
|
||||||
#include "wmfs.h"
|
|
||||||
#include "util.h"
|
|
||||||
#include "tag.h"
|
|
||||||
|
|
||||||
enum { ElemTag = 0, ElemStatus, ElemSystray, ElemLauncher, ElemCustom, ElemLast };
|
|
||||||
|
|
||||||
struct infobar *infobar_new(struct screen *s, char *name, struct theme *theme, enum barpos pos, const char *elem);
|
|
||||||
void infobar_elem_update(struct infobar *i, int type);
|
|
||||||
void infobar_refresh(struct infobar *i);
|
|
||||||
void infobar_remove(struct infobar *i);
|
|
||||||
void infobar_free(struct screen *s);
|
|
||||||
void infobar_elem_reinit(struct infobar *i);
|
|
||||||
|
|
||||||
/* Basic placement of elements */
|
|
||||||
static inline void
|
|
||||||
infobar_elem_placement(struct element *e)
|
|
||||||
{
|
|
||||||
struct element *p = TAILQ_PREV(e, esub, next);
|
|
||||||
|
|
||||||
e->geo.y = 0;
|
|
||||||
e->geo.h = e->infobar->geo.h;
|
|
||||||
|
|
||||||
if(e->align == Left)
|
|
||||||
e->geo.x = (p ? p->geo.x + p->geo.w : 0);
|
|
||||||
else
|
|
||||||
e->geo.x = ((p = TAILQ_NEXT(e, next))
|
|
||||||
? p->geo.x - e->geo.w
|
|
||||||
: e->infobar->geo.w - e->geo.w);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bars placement management and usable space management */
|
|
||||||
static inline bool
|
|
||||||
infobar_placement(struct infobar *i, enum barpos p)
|
|
||||||
{
|
|
||||||
i->pos = p;
|
|
||||||
i->geo = i->screen->ugeo;
|
|
||||||
i->geo.h = i->theme->bars_width;
|
|
||||||
|
|
||||||
switch(p)
|
|
||||||
{
|
|
||||||
case BarTop:
|
|
||||||
i->screen->ugeo.y += i->geo.h;
|
|
||||||
i->screen->ugeo.h -= i->geo.h;
|
|
||||||
break;
|
|
||||||
case BarBottom:
|
|
||||||
i->geo.y = (i->screen->ugeo.y + i->screen->ugeo.h) - i->geo.h;
|
|
||||||
i->screen->ugeo.h -= i->geo.h;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
case BarHide:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
infobar_elem_screen_update(struct screen *s, int type)
|
|
||||||
{
|
|
||||||
struct infobar *i;
|
|
||||||
|
|
||||||
SLIST_FOREACH(i, &s->infobars, next)
|
|
||||||
infobar_elem_update(i, type);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct infobar*
|
|
||||||
infobar_gb_name(const char *name)
|
|
||||||
{
|
|
||||||
struct screen *s;
|
|
||||||
struct infobar *i;
|
|
||||||
|
|
||||||
SLIST_FOREACH(s, &W->h.screen, next)
|
|
||||||
{
|
|
||||||
SLIST_FOREACH(i, &s->infobars, next)
|
|
||||||
if(!strcmp(i->name, name))
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return SLIST_FIRST(&s->infobars);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uicb_infobar_toggle_hide(Uicb iname);
|
|
||||||
|
|
||||||
#endif /* INFOBAR_H */
|
|
||||||
220
src/init.c
Normal file
220
src/init.c
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
/*
|
||||||
|
* wmfs.c
|
||||||
|
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of the nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "wmfs.h"
|
||||||
|
|
||||||
|
|
||||||
|
const func_name_list_t layout_list[] =
|
||||||
|
{
|
||||||
|
{"tile", tile },
|
||||||
|
{"tile_right", tile },
|
||||||
|
{"tile_left", tile_left },
|
||||||
|
{"tile_top", tile_top },
|
||||||
|
{"tile_bottom", tile_bottom },
|
||||||
|
{"tile_grid", grid_horizontal },
|
||||||
|
{"tile_grid_horizontal", grid_horizontal },
|
||||||
|
{"tile_grid_vertical", grid_vertical },
|
||||||
|
{"grid", grid_horizontal },
|
||||||
|
{"mirror_vertical", mirror_vertical },
|
||||||
|
{"tile_mirror_vertical", mirror_vertical },
|
||||||
|
{"mirror_horizontal", mirror_horizontal },
|
||||||
|
{"tile_mirror_horizontal", mirror_horizontal },
|
||||||
|
{"max", maxlayout },
|
||||||
|
{"maxlayout", maxlayout },
|
||||||
|
{"freelayout", freelayout },
|
||||||
|
{"free", freelayout },
|
||||||
|
{ NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Init the font
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
init_font(void)
|
||||||
|
{
|
||||||
|
font = XftFontOpenName(dpy, SCREEN, conf.font);
|
||||||
|
|
||||||
|
if(!font)
|
||||||
|
{
|
||||||
|
warnx("WMFS Error: Cannot initialize font");
|
||||||
|
font = XftFontOpenName(dpy, SCREEN, "sans-10");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set font in _WMFS_FONT for eventual status tools */
|
||||||
|
XChangeProperty(dpy, ROOT, net_atom[wmfs_font], net_atom[utf8_string], 8,
|
||||||
|
PropModeReplace, (uchar*)conf.font, strlen(conf.font));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Init the graphic context
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
init_gc(void)
|
||||||
|
{
|
||||||
|
XGCValues gcv;
|
||||||
|
|
||||||
|
/* Bits sequences */
|
||||||
|
const char pix_bits[] =
|
||||||
|
{
|
||||||
|
0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55,
|
||||||
|
0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55,
|
||||||
|
0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55,
|
||||||
|
0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55
|
||||||
|
};
|
||||||
|
|
||||||
|
gc = DefaultGC(dpy, SCREEN);
|
||||||
|
|
||||||
|
/* Stipple GC */
|
||||||
|
gcv.function = GXcopy;
|
||||||
|
gcv.fill_style = FillStippled;
|
||||||
|
gcv.stipple = XCreateBitmapFromData(dpy, ROOT, pix_bits, 10, 4);
|
||||||
|
gc_stipple = XCreateGC(dpy, ROOT, GCFunction | GCFillStyle | GCStipple, &gcv);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Init WMFS cursor
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
init_cursor(void)
|
||||||
|
{
|
||||||
|
cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr);
|
||||||
|
cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
|
||||||
|
cursor[CurRightResize] = XCreateFontCursor(dpy, XC_lr_angle);
|
||||||
|
cursor[CurLeftResize] = XCreateFontCursor(dpy, XC_ll_angle);
|
||||||
|
cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Init key modifier
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
init_key(void)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
XModifierKeymap *modmap = XGetModifierMapping(dpy);
|
||||||
|
|
||||||
|
for(i = 0; i < 8; i++)
|
||||||
|
for(j = 0; j < modmap->max_keypermod; ++j)
|
||||||
|
if(modmap->modifiermap[i * modmap->max_keypermod + j]
|
||||||
|
== XKeysymToKeycode(dpy, XK_Num_Lock))
|
||||||
|
numlockmask = (1 << i);
|
||||||
|
|
||||||
|
XFreeModifiermap(modmap);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Init root Window
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
init_root(void)
|
||||||
|
{
|
||||||
|
XSetWindowAttributes at;
|
||||||
|
|
||||||
|
at.event_mask = KeyMask | ButtonMask | MouseMask | PropertyChangeMask
|
||||||
|
| SubstructureRedirectMask | SubstructureNotifyMask | StructureNotifyMask;
|
||||||
|
|
||||||
|
at.cursor = cursor[CurNormal];
|
||||||
|
XChangeWindowAttributes(dpy, ROOT, CWEventMask | CWCursor, &at);
|
||||||
|
|
||||||
|
if(conf.root.background_command)
|
||||||
|
spawn("%s", conf.root.background_command);
|
||||||
|
|
||||||
|
ewmh_init_hints();
|
||||||
|
ewmh_get_number_of_desktop();
|
||||||
|
ewmh_get_desktop_names();
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
/* First init */
|
||||||
|
ewmh_init_hints();
|
||||||
|
init_conf();
|
||||||
|
init_gc();
|
||||||
|
init_font();
|
||||||
|
init_cursor();
|
||||||
|
init_key();
|
||||||
|
init_root();
|
||||||
|
screen_init_geo();
|
||||||
|
infobar_init();
|
||||||
|
systray_acquire();
|
||||||
|
init_status();
|
||||||
|
ewmh_update_current_tag_prop();
|
||||||
|
grabkeys();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
476
src/launcher.c
476
src/launcher.c
@ -1,110 +1,127 @@
|
|||||||
/*
|
/*
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
* launcher.c
|
||||||
* For license, see COPYING.
|
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
|
||||||
*/
|
* All rights reserved.
|
||||||
|
*
|
||||||
#include <string.h>
|
* Redistribution and use in source and binary forms, with or without
|
||||||
#include <dirent.h>
|
* modification, are permitted provided that the following conditions are
|
||||||
#include <sys/stat.h>
|
* met:
|
||||||
#include <X11/Xutil.h>
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of the nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "wmfs.h"
|
#include "wmfs.h"
|
||||||
#include "event.h"
|
|
||||||
#include "util.h"
|
|
||||||
#include "infobar.h"
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
static int
|
/*
|
||||||
qsort_string_compare(const void * a, const void * b)
|
* Just search command in PATH.
|
||||||
|
* Return the characters to complete the command.
|
||||||
|
*/
|
||||||
|
static char *
|
||||||
|
complete_on_command(char *start, size_t hits)
|
||||||
{
|
{
|
||||||
return (strcmp(*(char **)a, *(char **)b));
|
char *path;
|
||||||
}
|
char *dirname;
|
||||||
|
char *ret = NULL;
|
||||||
static char **
|
|
||||||
complete_on_command(char *start)
|
|
||||||
{
|
|
||||||
struct dirent *content;
|
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
char **paths, *path, *p, **namelist = NULL;
|
struct dirent *content;
|
||||||
int i, count;
|
|
||||||
|
|
||||||
if(!(path = getenv("PATH")) || !start)
|
char **namelist = NULL;
|
||||||
|
int n = 0, i;
|
||||||
|
|
||||||
|
if (!getenv("PATH") || !start || hits <= 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* split PATH into paths */
|
path = xstrdup(getenv("PATH"));
|
||||||
path = p = xstrdup(path);
|
dirname = strtok(path, ":");
|
||||||
|
|
||||||
for(count = 1, p = path; strchr(p, ':'); ++p, ++count);
|
|
||||||
|
|
||||||
paths = xcalloc(count, sizeof(*paths));
|
|
||||||
|
|
||||||
for(paths[0] = p = path, count = 1; (p = strchr(p, ':')); ++p, ++count)
|
|
||||||
{
|
|
||||||
paths[count] = p + 1;
|
|
||||||
*p = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
paths[count] = NULL;
|
|
||||||
|
|
||||||
/* recursively open PATH */
|
/* recursively open PATH */
|
||||||
for(i = count = 0; paths[i]; ++i)
|
while (dirname != NULL)
|
||||||
{
|
{
|
||||||
if(!(dir = opendir(paths[i])))
|
if ((dir = opendir(dirname)))
|
||||||
continue;
|
|
||||||
|
|
||||||
while((content = readdir(dir)))
|
|
||||||
{
|
{
|
||||||
if(strncmp(content->d_name, ".", 1)
|
while ((content = readdir(dir)))
|
||||||
&& !strncmp(content->d_name, start, strlen(start)))
|
|
||||||
{
|
{
|
||||||
namelist = xrealloc(namelist, ++count, sizeof(*namelist));
|
if(strncmp(content->d_name, ".", 1))
|
||||||
namelist[count - 1] = xstrdup(content->d_name + strlen(start));
|
{
|
||||||
|
if (!strncmp(content->d_name, start, strlen(start)))
|
||||||
|
{
|
||||||
|
namelist = xrealloc(namelist, ++n, sizeof(*namelist));
|
||||||
|
namelist[n-1] = xstrdup(content->d_name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
}
|
}
|
||||||
|
dirname = strtok(NULL, ":");
|
||||||
if(count)
|
|
||||||
{
|
|
||||||
qsort(namelist, count, sizeof(char *), qsort_string_compare);
|
|
||||||
namelist = xrealloc(namelist, ++count, sizeof(*namelist));
|
|
||||||
namelist[count - 1] = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free(paths);
|
|
||||||
free(path);
|
free(path);
|
||||||
|
|
||||||
return namelist;
|
if(n > 0)
|
||||||
|
{
|
||||||
|
qsort(namelist, n, sizeof(char *), qsort_string_compare);
|
||||||
|
ret = xstrdup(namelist[((hits > 0) ? hits - 1 : 0) % n] + strlen(start));
|
||||||
|
|
||||||
|
for(i = 0; i < n; i++)
|
||||||
|
free(namelist[i]);
|
||||||
|
|
||||||
|
free(namelist);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Complete a filename or directory name.
|
* Complete a filename or directory name.
|
||||||
* works like complete_on_command.
|
* works like complete_on_command.
|
||||||
*/
|
*/
|
||||||
static char **
|
static char *
|
||||||
complete_on_files(char *start)
|
complete_on_files(char *start, size_t hits)
|
||||||
{
|
{
|
||||||
|
char *ret = NULL;
|
||||||
|
char *p = NULL;
|
||||||
|
char *dirname = NULL;
|
||||||
|
char *path = NULL;
|
||||||
|
char *filepath = NULL;
|
||||||
|
DIR *dir = NULL;
|
||||||
struct dirent *content = NULL;
|
struct dirent *content = NULL;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
DIR *dir;
|
size_t count = 0;
|
||||||
char *home, *path, *dirname = NULL;
|
|
||||||
char **namelist = NULL, *filepath, *p = start;
|
if (!start || hits <= 0 || !(p = strrchr(start, ' ')))
|
||||||
int count = 0;
|
return NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Search the directory to open and set
|
* Search the directory to open and set
|
||||||
* the beginning of file to complete on pointer 'p'.
|
* the beginning of file to complete on pointer 'p'.
|
||||||
*/
|
*/
|
||||||
if(*p == '\0' || !strrchr(p, '/'))
|
if (*(++p) == '\0' || !strrchr(p, '/'))
|
||||||
path = xstrdup(".");
|
path = xstrdup(".");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(!(home = getenv("HOME")))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* remplace ~ by $HOME in dirname */
|
/* remplace ~ by $HOME in dirname */
|
||||||
if(!strncmp(p, "~/", 2) && home)
|
if (!strncmp(p, "~/", 2) && getenv("HOME"))
|
||||||
xasprintf(&dirname, "%s%s", home, p+1);
|
xasprintf(&dirname, "%s%s", getenv("HOME"), p+1);
|
||||||
else
|
else
|
||||||
dirname = xstrdup(p);
|
dirname = xstrdup(p);
|
||||||
|
|
||||||
@ -114,7 +131,7 @@ complete_on_files(char *start)
|
|||||||
* <---- path - ---><------- p ------>
|
* <---- path - ---><------- p ------>
|
||||||
*/
|
*/
|
||||||
p = strrchr(dirname, '/');
|
p = strrchr(dirname, '/');
|
||||||
if(p != dirname)
|
if (p != dirname)
|
||||||
{
|
{
|
||||||
*(p++) = '\0';
|
*(p++) = '\0';
|
||||||
path = xstrdup(dirname);
|
path = xstrdup(dirname);
|
||||||
@ -126,313 +143,240 @@ complete_on_files(char *start)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((dir = opendir(path)))
|
if ((dir = opendir(path)))
|
||||||
{
|
{
|
||||||
while((content = readdir(dir)))
|
while ((content = readdir(dir)))
|
||||||
{
|
{
|
||||||
if(!strcmp(content->d_name, ".")
|
if (!strcmp(content->d_name, ".") || !strcmp(content->d_name, ".."))
|
||||||
|| !strcmp(content->d_name, "..")
|
|
||||||
|| strncmp(content->d_name, p, strlen(p)))
|
|
||||||
continue;
|
continue;
|
||||||
|
if (!strncmp(content->d_name, p, strlen(p)) && ++count == hits)
|
||||||
|
{
|
||||||
/* If it's a directory append '/' to the completion */
|
/* If it's a directory append '/' to the completion */
|
||||||
xasprintf(&filepath, "%s/%s", path, content->d_name);
|
xasprintf(&filepath, "%s/%s", path, content->d_name);
|
||||||
|
|
||||||
if(filepath && stat(filepath, &st) != -1)
|
if (filepath && stat(filepath, &st) != -1)
|
||||||
{
|
{
|
||||||
namelist = xrealloc(namelist, ++count, sizeof(*namelist));
|
if (S_ISDIR(st.st_mode))
|
||||||
|
xasprintf(&ret, "%s/", content->d_name + strlen(p));
|
||||||
if(S_ISDIR(st.st_mode))
|
|
||||||
xasprintf(&namelist[count - 1], "%s/", content->d_name + strlen(p));
|
|
||||||
else
|
else
|
||||||
namelist[count - 1] = xstrdup(content->d_name + strlen(p));
|
ret = xstrdup(content->d_name + strlen(p));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
warnl("%s", filepath);
|
warn("%s", filepath);
|
||||||
|
|
||||||
free(filepath);
|
free(filepath);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(count)
|
|
||||||
{
|
|
||||||
namelist = xrealloc(namelist, ++count, sizeof(*namelist));
|
|
||||||
namelist[count - 1] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(dirname);
|
free(dirname);
|
||||||
free(path);
|
free(path);
|
||||||
|
|
||||||
return namelist;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
complete_cache_free(struct launcher_ccache *cache)
|
launcher_execute(Launcher *launcher)
|
||||||
{
|
{
|
||||||
int i;
|
BarWindow *bw;
|
||||||
|
Bool found;
|
||||||
/* release memory */
|
Bool lastwastab = False;
|
||||||
free(cache->start);
|
Bool my_guitar_gently_wheeps = True;
|
||||||
|
|
||||||
if(cache->namelist)
|
|
||||||
{
|
|
||||||
for(i = 0; cache->namelist[i]; i++)
|
|
||||||
free(cache->namelist[i]);
|
|
||||||
free(cache->namelist);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* init */
|
|
||||||
cache->hits = 0;
|
|
||||||
cache->start = NULL;
|
|
||||||
cache->namelist = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
|
||||||
complete(struct launcher_ccache *cache, char *start)
|
|
||||||
{
|
|
||||||
char *p = NULL, *comp = NULL;
|
|
||||||
|
|
||||||
if(!start || !cache)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if((p = strrchr(start, ' ')))
|
|
||||||
p++;
|
|
||||||
else
|
|
||||||
p = start;
|
|
||||||
|
|
||||||
if(cache->start && !strcmp(cache->start, start))
|
|
||||||
{
|
|
||||||
if(cache->namelist && !cache->namelist[cache->hits])
|
|
||||||
cache->hits = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
complete_cache_free(cache);
|
|
||||||
cache->start = xstrdup(start);
|
|
||||||
|
|
||||||
if(p == start)
|
|
||||||
cache->namelist = complete_on_command(p);
|
|
||||||
else
|
|
||||||
cache->namelist = complete_on_files(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(cache->namelist && cache->namelist[cache->hits])
|
|
||||||
comp = cache->namelist[cache->hits];
|
|
||||||
|
|
||||||
return comp;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define LAUNCHER_INIT_ELEM(width) \
|
|
||||||
SLIST_FOREACH(ib, &W->screen->infobars, next) \
|
|
||||||
{ \
|
|
||||||
TAILQ_FOREACH(e, &ib->elements, next) \
|
|
||||||
if(e->type == ElemLauncher) \
|
|
||||||
{ \
|
|
||||||
e->geo.w = width; \
|
|
||||||
e->data = data; \
|
|
||||||
} \
|
|
||||||
infobar_elem_reinit(ib); \
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
launcher_process(struct launcher *l)
|
|
||||||
{
|
|
||||||
struct infobar *ib;
|
|
||||||
struct element *e;
|
|
||||||
struct launcher_ccache cache = {NULL, NULL, 0};
|
|
||||||
bool loop = true, found = false, lastwastab = false;
|
|
||||||
char tmpbuf[512] = { 0 }, buf[512] = { 0 };
|
|
||||||
char tmp[32] = { 0 };
|
char tmp[32] = { 0 };
|
||||||
char *p, *data, *arg, *end, *cmd = xstrdup(l->command);
|
char buf[512] = { 0 };
|
||||||
int i, pos = 0, histpos = 0;
|
char tmpbuf[512] = { 0 };
|
||||||
void (*func)(Uicb);
|
char *complete;
|
||||||
XEvent ev;
|
int i, pos = 0, histpos = 0, x, w;
|
||||||
|
int tabhits = 0;
|
||||||
KeySym ks;
|
KeySym ks;
|
||||||
|
XEvent ev;
|
||||||
|
|
||||||
W->flags |= WMFS_LAUNCHER;
|
screen_get_sel();
|
||||||
|
|
||||||
/* Prepare elements */
|
x = (conf.layout_placement)
|
||||||
xasprintf(&data, "%s ", l->prompt);
|
? (infobar[selscreen].tags_board->geo.x + infobar[selscreen].tags_board->geo.width)
|
||||||
LAUNCHER_INIT_ELEM(l->width);
|
: (infobar[selscreen].layout_button->geo.x + infobar[selscreen].layout_button->geo.width);
|
||||||
|
|
||||||
XGrabKeyboard(W->dpy, W->root, true, GrabModeAsync, GrabModeAsync, CurrentTime);
|
XGrabKeyboard(dpy, ROOT, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||||
|
|
||||||
while(loop)
|
w = (launcher->width ? launcher->width : infobar[selscreen].bar->geo.width - x - 1);
|
||||||
|
|
||||||
|
bw = barwin_create(infobar[selscreen].bar->win, x, 1, w,
|
||||||
|
/* infobar[selscreen].bar->geo.width - x - 1, */
|
||||||
|
infobar[selscreen].bar->geo.height - 2,
|
||||||
|
infobar[selscreen].bar->bg,
|
||||||
|
infobar[selscreen].bar->fg,
|
||||||
|
False, False, conf.border.bar);
|
||||||
|
|
||||||
|
barwin_map(bw);
|
||||||
|
barwin_refresh_color(bw);
|
||||||
|
|
||||||
|
/* First draw of the cursor */
|
||||||
|
XSetForeground(dpy, gc, getcolor(infobar[selscreen].bar->fg));
|
||||||
|
|
||||||
|
XDrawLine(dpy, bw->dr, gc,
|
||||||
|
1 + textw(launcher->prompt) + textw(" ") + textw(buf), 2,
|
||||||
|
1 + textw(launcher->prompt) + textw(" ") + textw(buf), INFOBARH - 4);
|
||||||
|
|
||||||
|
barwin_refresh(bw);
|
||||||
|
|
||||||
|
barwin_draw_text(bw, 1, FHINFOBAR - 1, launcher->prompt);
|
||||||
|
|
||||||
|
while(my_guitar_gently_wheeps)
|
||||||
{
|
{
|
||||||
XNextEvent(W->dpy, &ev);
|
if(ev.type == KeyPress)
|
||||||
|
|
||||||
if(ev.type != KeyPress)
|
|
||||||
{
|
{
|
||||||
EVENT_HANDLE(&ev);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get pressed key */
|
|
||||||
XLookupString(&ev.xkey, tmp, sizeof(tmp), &ks, 0);
|
XLookupString(&ev.xkey, tmp, sizeof(tmp), &ks, 0);
|
||||||
|
|
||||||
/* Check Ctrl-c / Ctrl-d */
|
/* Check Ctrl-c / Ctrl-d */
|
||||||
if(ev.xkey.state & ControlMask)
|
if(ev.xkey.state & ControlMask)
|
||||||
{
|
{
|
||||||
switch(ks)
|
if(ks == XK_c || ks == XK_d)
|
||||||
{
|
|
||||||
case XK_c:
|
|
||||||
case XK_d:
|
|
||||||
ks = XK_Escape;
|
ks = XK_Escape;
|
||||||
break;
|
else if(ks == XK_p)
|
||||||
case XK_p:
|
|
||||||
ks = XK_Up;
|
ks = XK_Up;
|
||||||
break;
|
else if(ks == XK_n)
|
||||||
case XK_n:
|
|
||||||
ks = XK_Down;
|
ks = XK_Down;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if there is a keypad */
|
/* Check if there is a keypad */
|
||||||
if(IsKeypadKey(ks) && ks == XK_KP_Enter)
|
if(IsKeypadKey(ks) && ks == XK_KP_Enter)
|
||||||
ks = XK_Return;
|
ks = XK_Return;
|
||||||
|
|
||||||
/* Manage pressed keys */
|
|
||||||
switch(ks)
|
switch(ks)
|
||||||
{
|
{
|
||||||
case XK_Up:
|
case XK_Up:
|
||||||
if(l->nhisto)
|
if(launcher->nhisto)
|
||||||
{
|
{
|
||||||
if(histpos >= (int)l->nhisto)
|
if(histpos >= (int)launcher->nhisto)
|
||||||
histpos = 0;
|
histpos = 0;
|
||||||
strncpy(buf, l->histo[l->nhisto - ++histpos], sizeof(buf));
|
strncpy(buf, launcher->histo[launcher->nhisto - ++histpos], sizeof(buf));
|
||||||
pos = strlen(buf);
|
pos = strlen(buf);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XK_Down:
|
case XK_Down:
|
||||||
if(l->nhisto && histpos > 0 && histpos < (int)l->nhisto)
|
if(launcher->nhisto && histpos > 0 && histpos < (int)launcher->nhisto)
|
||||||
{
|
{
|
||||||
strncpy(buf, l->histo[l->nhisto - --histpos], sizeof(buf));
|
strncpy(buf, launcher->histo[launcher->nhisto - --histpos], sizeof(buf));
|
||||||
pos = strlen(buf);
|
pos = strlen(buf);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XK_Return:
|
case XK_Return:
|
||||||
/* Get function name only, if cmds are added in command */
|
spawn("%s %s", launcher->command, buf);
|
||||||
arg = NULL;
|
|
||||||
if((p = strchr(cmd, ' ')))
|
|
||||||
{
|
|
||||||
*p = '\0';
|
|
||||||
xasprintf(&arg, "%s %s", p + 1, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if((func = uicb_name_func(cmd)))
|
|
||||||
{
|
|
||||||
if(arg)
|
|
||||||
{
|
|
||||||
func(arg);
|
|
||||||
free(arg);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
func(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Histo */
|
/* Histo */
|
||||||
if(l->nhisto + 1 > HISTOLEN)
|
if(launcher->nhisto + 1 > HISTOLEN)
|
||||||
{
|
{
|
||||||
for(i = l->nhisto - 1; i > 1; --i)
|
for(i = launcher->nhisto - 1; i > 1; --i)
|
||||||
strncpy(l->histo[i], l->histo[i - 1], sizeof(l->histo[i]));
|
strncpy(launcher->histo[i], launcher->histo[i - 1], sizeof(launcher->histo[i]));
|
||||||
|
|
||||||
l->nhisto = 0;
|
launcher->nhisto = 0;
|
||||||
}
|
}
|
||||||
/* Store in histo array */
|
/* Store in histo array */
|
||||||
strncpy(l->histo[l->nhisto++], buf, sizeof(buf));
|
strncpy(launcher->histo[launcher->nhisto++], buf, sizeof(buf));
|
||||||
|
|
||||||
loop = false;
|
my_guitar_gently_wheeps = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XK_Escape:
|
case XK_Escape:
|
||||||
loop = false;
|
my_guitar_gently_wheeps = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Completion */
|
|
||||||
case XK_Tab:
|
case XK_Tab:
|
||||||
|
/*
|
||||||
|
* completion
|
||||||
|
* if there is not space in buffer we
|
||||||
|
* complete the command using complete_on_command.
|
||||||
|
* Else we try to complete on filename using
|
||||||
|
* complete_on_files.
|
||||||
|
*/
|
||||||
buf[pos] = '\0';
|
buf[pos] = '\0';
|
||||||
if(lastwastab)
|
if (lastwastab)
|
||||||
++cache.hits;
|
tabhits++;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cache.hits = 0;
|
tabhits = 1;
|
||||||
strncpy(tmpbuf, buf, sizeof(tmpbuf));
|
strncpy(tmpbuf, buf, sizeof(tmpbuf));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pos && (end = complete(&cache, tmpbuf)))
|
|
||||||
|
if (pos)
|
||||||
|
{
|
||||||
|
if (strchr(tmpbuf, ' '))
|
||||||
|
complete = complete_on_files(tmpbuf, tabhits);
|
||||||
|
else
|
||||||
|
complete = complete_on_command(tmpbuf, tabhits);
|
||||||
|
|
||||||
|
if (complete)
|
||||||
{
|
{
|
||||||
strncpy(buf, tmpbuf, sizeof(buf));
|
strncpy(buf, tmpbuf, sizeof(buf));
|
||||||
strncat(buf, end, sizeof(buf));
|
strncat(buf, complete, sizeof(buf));
|
||||||
found = true;
|
found = True;
|
||||||
|
free(complete);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lastwastab = true;
|
lastwastab = True;
|
||||||
|
|
||||||
/* start a new round of tabbing */
|
/* start a new round of tabbing */
|
||||||
if(!found)
|
if (found == False)
|
||||||
cache.hits = 0;
|
tabhits = 0;
|
||||||
|
|
||||||
pos = strlen(buf);
|
pos = strlen(buf);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XK_BackSpace:
|
case XK_BackSpace:
|
||||||
lastwastab = false;
|
lastwastab = False;
|
||||||
if(pos)
|
if(pos)
|
||||||
buf[--pos] = '\0';
|
buf[--pos] = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
lastwastab = false;
|
lastwastab = False;
|
||||||
strncat(buf, tmp, sizeof(tmp));
|
strncat(buf, tmp, sizeof(tmp));
|
||||||
++pos;
|
++pos;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(data);
|
barwin_refresh_color(bw);
|
||||||
xasprintf(&data, "%s %s", l->prompt, buf);
|
|
||||||
|
|
||||||
/* Update EVERY launcher element of the screen */
|
/* Update cursor position */
|
||||||
SLIST_FOREACH(ib, &W->screen->infobars, next)
|
XSetForeground(dpy, gc, getcolor(infobar[selscreen].bar->fg));
|
||||||
{
|
XDrawLine(dpy, bw->dr, gc,
|
||||||
TAILQ_FOREACH(e, &ib->elements, next)
|
1 + textw(launcher->prompt) + textw(" ") + textw(buf), 2,
|
||||||
{
|
1 + textw(launcher->prompt) + textw(" ") + textw(buf), INFOBARH - 4);
|
||||||
if(e->type != ElemLauncher)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
e->data = data;
|
barwin_draw_text(bw, 1, FHINFOBAR - 1, launcher->prompt);
|
||||||
e->func_update(e);
|
barwin_draw_text(bw, 1 + textw(launcher->prompt) + textw(" "), FHINFOBAR - 1, buf);
|
||||||
}
|
barwin_refresh(bw);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
getevent(ev);
|
||||||
|
XNextEvent(dpy, &ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
XUngrabKeyboard(W->dpy, CurrentTime);
|
barwin_unmap(bw);
|
||||||
|
barwin_delete(bw);
|
||||||
|
infobar_draw(selscreen);
|
||||||
|
|
||||||
complete_cache_free(&cache);
|
XUngrabKeyboard(dpy, CurrentTime);
|
||||||
free(cmd);
|
|
||||||
free(data);
|
return;
|
||||||
|
|
||||||
/* 'Close' launcher elements */
|
|
||||||
W->flags ^= WMFS_LAUNCHER;
|
|
||||||
data = NULL;
|
|
||||||
LAUNCHER_INIT_ELEM(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uicb_launcher(Uicb cmd)
|
uicb_launcher(uicb_t cmd)
|
||||||
{
|
{
|
||||||
struct launcher *l;
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < conf.nlauncher; ++i)
|
||||||
|
if(!strcmp(cmd, conf.launcher[i].name))
|
||||||
|
launcher_execute(&conf.launcher[i]);
|
||||||
|
|
||||||
if(!cmd)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SLIST_FOREACH(l, &W->h.launcher, next)
|
|
||||||
if(!strcmp(l->name, cmd))
|
|
||||||
{
|
|
||||||
launcher_process(l);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +0,0 @@
|
|||||||
/*
|
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
|
||||||
* For license, see COPYING.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LAUNCHER_H
|
|
||||||
#define LAUNCHER_H
|
|
||||||
|
|
||||||
#include "wmfs.h"
|
|
||||||
|
|
||||||
void uicb_launcher(Uicb cmd);
|
|
||||||
|
|
||||||
#endif /* LAUNCHER_H */
|
|
||||||
1379
src/layout.c
1379
src/layout.c
File diff suppressed because it is too large
Load Diff
54
src/layout.h
54
src/layout.h
@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
|
||||||
* For license, see COPYING.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LAYOUT_H
|
|
||||||
#define LAYOUT_H
|
|
||||||
|
|
||||||
#include "wmfs.h"
|
|
||||||
#include "client.h"
|
|
||||||
|
|
||||||
/* Check lateral direction (if p is Right or Left) */
|
|
||||||
#define LDIR(P) (P < Top)
|
|
||||||
|
|
||||||
/* Reverse position */
|
|
||||||
#define RPOS(P) (P & 1 ? P - 1 : P + 1)
|
|
||||||
|
|
||||||
/* geo comparaison */
|
|
||||||
#define GEO_CHECK2(g1, g2, p) (LDIR(p) ? ((g1).h == (g2).h) : ((g1).w == (g2).w))
|
|
||||||
#define GEO_CHECK_ROW(g1, g2, p) \
|
|
||||||
(LDIR(p) \
|
|
||||||
? ((g1).y >= (g2).y && ((g1).y + (g1).h) <= ((g2).y + (g2).h)) \
|
|
||||||
: ((g1).x >= (g2).x && ((g1).x + (g1).w) <= ((g2).x + (g2).w)))
|
|
||||||
#define GEO_PARENTROW(g1, g2, p) \
|
|
||||||
(LDIR(p) \
|
|
||||||
? (p == Left ? ((g1).x == (g2).x) : ((g1).x + (g1).w == (g2).x + (g2).w)) \
|
|
||||||
: (p == Top ? ((g1).y == (g2).y) : ((g1).y + (g1).h == (g2).y + (g2).h)))
|
|
||||||
|
|
||||||
|
|
||||||
/* Debug */
|
|
||||||
#define DGEO(G) printf(": %d %d %d %d\n", G.x, G.y, G.w, G.h)
|
|
||||||
|
|
||||||
void layout_save_set(struct tag *t);
|
|
||||||
void layout_free_set(struct tag *t);
|
|
||||||
void layout_split_integrate(struct client *c, struct client *sc);
|
|
||||||
void layout_split_arrange_closed(struct client *ghost);
|
|
||||||
void layout_fix_hole(struct client *c);
|
|
||||||
void layout_client(struct client *c);
|
|
||||||
void uicb_layout_vmirror(Uicb cmd);
|
|
||||||
void uicb_layout_hmirror(Uicb cmd);
|
|
||||||
void uicb_layout_rotate_left(Uicb cmd);
|
|
||||||
void uicb_layout_rotate_right(Uicb cmd);
|
|
||||||
void uicb_layout_prev_set(Uicb cmd);
|
|
||||||
void uicb_layout_next_set(Uicb cmd);
|
|
||||||
|
|
||||||
/* Generated */
|
|
||||||
void uicb_layout_integrate_Left(Uicb);
|
|
||||||
void uicb_layout_integrate_Right(Uicb);
|
|
||||||
void uicb_layout_integrate_Top(Uicb);
|
|
||||||
void uicb_layout_integrate_Bottom(Uicb);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* LAYOUT_H */
|
|
||||||
|
|
||||||
110
src/log.c
110
src/log.c
@ -1,110 +0,0 @@
|
|||||||
/*
|
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
|
||||||
* File created by David Delassus.
|
|
||||||
* For license, see COPYING.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "wmfs.h"
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
void
|
|
||||||
log_init(void)
|
|
||||||
{
|
|
||||||
char *path = NULL;
|
|
||||||
|
|
||||||
xasprintf(&path, "%s/wmfs-%s.log", P_tmpdir, DisplayString(W->dpy));
|
|
||||||
|
|
||||||
if(path)
|
|
||||||
{
|
|
||||||
/* open log */
|
|
||||||
if(!(W->log = fopen(path, "a")))
|
|
||||||
warnx("Can't open log file '%s': %s\n", path, strerror(errno));
|
|
||||||
|
|
||||||
free(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Print a warning on standard error output and in the log file
|
|
||||||
* \param format Format string (same syntax as printf)
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
warnl(const char *format, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
|
|
||||||
if(W->log)
|
|
||||||
{
|
|
||||||
va_start(args, format);
|
|
||||||
vfprintf(W->log, format, args);
|
|
||||||
fprintf(W->log, "\n");
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
va_start(args, format);
|
|
||||||
vwarn(format, args);
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Print an error on standard error output and in the log file
|
|
||||||
* \param eval Exit value
|
|
||||||
* \param format Format string (same syntax as printf)
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
errl(int eval, const char *format, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
|
|
||||||
if(W->log)
|
|
||||||
{
|
|
||||||
va_start(args, format);
|
|
||||||
vfprintf(W->log, format, args);
|
|
||||||
fprintf(W->log, "\n");
|
|
||||||
va_end(args);
|
|
||||||
fclose (W->log);
|
|
||||||
}
|
|
||||||
|
|
||||||
va_start(args, format);
|
|
||||||
verr(eval, format, args);
|
|
||||||
}
|
|
||||||
/** Print a warning on standard error output and in the log file
|
|
||||||
* \param format Format string (same syntax as printf)
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
warnxl(const char *format, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
|
|
||||||
if(W->log)
|
|
||||||
{
|
|
||||||
va_start(args, format);
|
|
||||||
vfprintf(W->log, format, args);
|
|
||||||
fprintf(W->log, "\n");
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
va_start(args, format);
|
|
||||||
vwarnx(format, args);
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Print an error on standard error output and in the log file
|
|
||||||
* \param eval Exit value
|
|
||||||
* \param format Format string (same syntax as printf)
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
errxl(int eval, const char *format, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
|
|
||||||
if(W->log)
|
|
||||||
{
|
|
||||||
va_start(args, format);
|
|
||||||
vfprintf(W->log, format, args);
|
|
||||||
fprintf(W->log, "\n");
|
|
||||||
va_end(args);
|
|
||||||
fclose (W->log);
|
|
||||||
}
|
|
||||||
|
|
||||||
va_start(args, format);
|
|
||||||
verrx(eval, format, args);
|
|
||||||
}
|
|
||||||
18
src/log.h
18
src/log.h
@ -1,18 +0,0 @@
|
|||||||
/*
|
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
|
||||||
* File created by David Delassus.
|
|
||||||
* For license, see COPYING.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __LOG_H
|
|
||||||
#define __LOG_H
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
void log_init(void);
|
|
||||||
void warnl(const char *format, ...);
|
|
||||||
void warnxl(const char *format, ...);
|
|
||||||
void errl(int eval, const char *format, ...);
|
|
||||||
void errxl(int eval, const char *format, ...);
|
|
||||||
|
|
||||||
#endif /* __LOG_H */
|
|
||||||
359
src/menu.c
Normal file
359
src/menu.c
Normal file
@ -0,0 +1,359 @@
|
|||||||
|
/*
|
||||||
|
* menu.c
|
||||||
|
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of the nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "wmfs.h"
|
||||||
|
|
||||||
|
static int
|
||||||
|
menu_get_longer_string(MenuItem *mi, int nitem)
|
||||||
|
{
|
||||||
|
int i, w, l = 0;
|
||||||
|
|
||||||
|
for(i = 0; i < nitem; ++i)
|
||||||
|
if((w = textw(mi[i].name)) > l)
|
||||||
|
l = w;
|
||||||
|
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
menu_get_checkstring_needed(MenuItem *mi, int nitem)
|
||||||
|
{
|
||||||
|
(void)mi;
|
||||||
|
(void)nitem;
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
menu_draw_item_name(Menu *menu, int item, BarWindow *winitem[], int chcklen)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int width = menu_get_longer_string(menu->item, menu->nitem) + chcklen + PAD / 3;
|
||||||
|
|
||||||
|
switch(menu->align)
|
||||||
|
{
|
||||||
|
case MA_Left:
|
||||||
|
x = chcklen + PAD / 2;
|
||||||
|
break;
|
||||||
|
case MA_Right:
|
||||||
|
x = width - textw(menu->item[item].name) + PAD * 3 / 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
case MA_Center:
|
||||||
|
x = (width - (chcklen + PAD / 3)) / 2 - textw(menu->item[item].name) / 2 + chcklen + PAD / 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
barwin_draw_image_ofset_text(winitem[item], x, FHINFOBAR, menu->item[item].name, chcklen + PAD / 2, 0);
|
||||||
|
|
||||||
|
if(menu->item[item].check)
|
||||||
|
if(menu->item[item].check(menu->item[item].cmd))
|
||||||
|
barwin_draw_image_ofset_text(winitem[item], PAD / 3, FHINFOBAR, conf.selected_layout_symbol, PAD / 3, 0);
|
||||||
|
|
||||||
|
if(menu->item[item].submenu)
|
||||||
|
barwin_draw_text(winitem[item], width + PAD * 2, FHINFOBAR, ">");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
menu_activate_item(Menu *menu, int i)
|
||||||
|
{
|
||||||
|
int j, x, y;
|
||||||
|
int chcklen = 0;
|
||||||
|
if(menu_get_checkstring_needed(menu->item, menu->nitem))
|
||||||
|
chcklen = textw(conf.selected_layout_symbol) + PAD / 3;
|
||||||
|
|
||||||
|
if(menu->item[i].submenu)
|
||||||
|
{
|
||||||
|
for(j = 0; j < conf.nmenu; ++j)
|
||||||
|
if(!strcmp(menu->item[i].submenu, conf.menu[j].name))
|
||||||
|
{
|
||||||
|
y = menu->y + ((i - 1) * INFOBARH + PAD) - SHADH * 2;
|
||||||
|
x = menu->x + menu_get_longer_string(menu->item, menu->nitem) + chcklen + textw(">") + PAD * 3;
|
||||||
|
|
||||||
|
menu_draw(conf.menu[j], x, y);
|
||||||
|
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(menu->item[i].func)
|
||||||
|
{
|
||||||
|
menu->item[i].func(menu->item[i].cmd);
|
||||||
|
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
menu_focus_item(Menu *menu, int item, BarWindow *winitem[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
int chcklen = 0;
|
||||||
|
if(menu_get_checkstring_needed(menu->item, menu->nitem))
|
||||||
|
chcklen = textw(conf.selected_layout_symbol) + PAD / 3;
|
||||||
|
|
||||||
|
menu->focus_item = item;
|
||||||
|
|
||||||
|
if(menu->focus_item > menu->nitem - 1)
|
||||||
|
menu->focus_item = 0;
|
||||||
|
else if(menu->focus_item < 0)
|
||||||
|
menu->focus_item = menu->nitem - 1;
|
||||||
|
|
||||||
|
for(i = 0; i < menu->nitem; ++i)
|
||||||
|
{
|
||||||
|
winitem[i]->fg = ((i == menu->focus_item) ? menu->colors.focus.fg : menu->colors.normal.fg);
|
||||||
|
winitem[i]->bg = ((i == menu->focus_item) ? menu->colors.focus.bg : menu->colors.normal.bg);
|
||||||
|
|
||||||
|
barwin_refresh_color(winitem[i]);
|
||||||
|
menu_draw_item_name(menu, i, winitem, chcklen);
|
||||||
|
barwin_refresh(winitem[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
menu_manage_event(XEvent *ev, Menu *menu, BarWindow *winitem[])
|
||||||
|
{
|
||||||
|
int i, c = 0;
|
||||||
|
KeySym ks;
|
||||||
|
Bool quit = False;
|
||||||
|
char acc = 0;
|
||||||
|
|
||||||
|
switch(ev->type)
|
||||||
|
{
|
||||||
|
/* Mouse events */
|
||||||
|
case ButtonPress:
|
||||||
|
/* Execute the function linked with the item */
|
||||||
|
for(i = 0; i < menu->nitem; ++i)
|
||||||
|
{
|
||||||
|
if(ev->xbutton.window == winitem[i]->win
|
||||||
|
&& (ev->xbutton.button == Button1 || ev->xbutton.button == Button2))
|
||||||
|
quit = menu_activate_item(menu, i);
|
||||||
|
else if(ev->xbutton.window != winitem[i]->win)
|
||||||
|
++c;
|
||||||
|
else if(ev->xbutton.button == Button4)
|
||||||
|
menu_focus_item(menu, menu->focus_item - 1, winitem);
|
||||||
|
else if(ev->xbutton.button == Button5)
|
||||||
|
menu_focus_item(menu, menu->focus_item + 1, winitem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the clicked window is not one of menu wins (items), quit. */
|
||||||
|
if(c == i)
|
||||||
|
quit = True;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Keys */
|
||||||
|
case KeyPress:
|
||||||
|
XLookupString(&ev->xkey, NULL, 0, &ks, 0);
|
||||||
|
switch(ks)
|
||||||
|
{
|
||||||
|
case XK_Up:
|
||||||
|
menu_focus_item(menu, menu->focus_item - 1, winitem);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XK_Down:
|
||||||
|
menu_focus_item(menu, menu->focus_item + 1, winitem);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XK_Return:
|
||||||
|
quit = menu_activate_item(menu, menu->focus_item);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XK_Escape:
|
||||||
|
quit = True;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Focus (with mouse) management */
|
||||||
|
case EnterNotify:
|
||||||
|
/* For focus an item with the mouse */
|
||||||
|
for(i = 0; i < menu->nitem; ++i)
|
||||||
|
if(ev->xcrossing.window == winitem[i]->win)
|
||||||
|
{
|
||||||
|
acc = 1;
|
||||||
|
menu_focus_item(menu, i, winitem);
|
||||||
|
if(menu->item[i].submenu)
|
||||||
|
menu_activate_item(menu, menu->focus_item);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!acc)
|
||||||
|
{
|
||||||
|
if(ev->xcrossing.window)
|
||||||
|
XSendEvent(dpy, ev->xcrossing.window, False, StructureNotifyMask, ev);
|
||||||
|
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
getevent(*ev);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
XNextEvent(dpy, ev);
|
||||||
|
|
||||||
|
return quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
uicb_menu(uicb_t cmd)
|
||||||
|
{
|
||||||
|
int i, d, u, x, y;
|
||||||
|
Window w;
|
||||||
|
|
||||||
|
if(!strcmp(cmd, "menulayout"))
|
||||||
|
menu_draw(menulayout, menulayout.x, menulayout.y);
|
||||||
|
|
||||||
|
for(i = 0; i < conf.nmenu; ++i)
|
||||||
|
if(!strcmp(cmd, conf.menu[i].name))
|
||||||
|
{
|
||||||
|
if(conf.menu[i].place_at_mouse)
|
||||||
|
{
|
||||||
|
XQueryPointer(dpy, ROOT, &w, &w, &x, &y, &d, &d, (uint *)&u);
|
||||||
|
conf.menu[i].x = x;
|
||||||
|
conf.menu[i].y = y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
screen_get_sel();
|
||||||
|
x = conf.menu[i].x + spgeo[selscreen].x;
|
||||||
|
y = conf.menu[i].y + spgeo[selscreen].y;
|
||||||
|
}
|
||||||
|
menu_draw(conf.menu[i], x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
menu_clear(Menu *menu)
|
||||||
|
{
|
||||||
|
free(menu->item);
|
||||||
|
menu->nitem = 0;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
menu_init(Menu *menu, char *name, int nitem, uint bg_f, char *fg_f, uint bg_n, char *fg_n)
|
||||||
|
{
|
||||||
|
/* Item */
|
||||||
|
menu->nitem = nitem;
|
||||||
|
menu->item = xcalloc(nitem, sizeof(*menu->item));
|
||||||
|
menu->name = name;
|
||||||
|
|
||||||
|
/* Colors */
|
||||||
|
menu->colors.focus.bg = bg_f;
|
||||||
|
menu->colors.focus.fg = fg_f;
|
||||||
|
menu->colors.normal.bg = bg_n;
|
||||||
|
menu->colors.normal.fg = fg_n;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
menu_new_item(MenuItem *mi, char *name, void *func, char *cmd)
|
||||||
|
{
|
||||||
|
mi->name = name;
|
||||||
|
mi->func = func;
|
||||||
|
mi->cmd = cmd;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
menu_draw(Menu menu, int x, int y)
|
||||||
|
{
|
||||||
|
int i, width, height, out;
|
||||||
|
XEvent ev;
|
||||||
|
BarWindow *item[menu.nitem];
|
||||||
|
BarWindow *frame;
|
||||||
|
|
||||||
|
int chcklen = 0;
|
||||||
|
if(menu_get_checkstring_needed(menu.item, menu.nitem))
|
||||||
|
chcklen = textw(conf.selected_layout_symbol) + PAD / 3;
|
||||||
|
|
||||||
|
width = menu_get_longer_string(menu.item, menu.nitem) + chcklen + textw(">") + PAD * 3;
|
||||||
|
height = menu.nitem * (INFOBARH - SHADH);
|
||||||
|
|
||||||
|
/* Frame barwin */
|
||||||
|
screen_get_sel();
|
||||||
|
|
||||||
|
if((out = x + width - MAXW) > 0)
|
||||||
|
x -= out;
|
||||||
|
if((out = y + height - MAXH) > 0)
|
||||||
|
y -= out;
|
||||||
|
|
||||||
|
frame = barwin_create(ROOT, x, y, width + SHADH, height + SHADH * 3,
|
||||||
|
menu.colors.normal.bg, menu.colors.normal.fg, False, False, True);
|
||||||
|
|
||||||
|
barwin_map(frame);
|
||||||
|
barwin_map_subwin(frame);
|
||||||
|
barwin_refresh_color(frame);
|
||||||
|
|
||||||
|
for(i = 0; i < menu.nitem; ++i)
|
||||||
|
{
|
||||||
|
item[i] = barwin_create(frame->win,
|
||||||
|
SHADH,
|
||||||
|
(i * (INFOBARH - SHADH) + SHADH),
|
||||||
|
width - SHADH,
|
||||||
|
INFOBARH,
|
||||||
|
menu.colors.normal.bg,
|
||||||
|
menu.colors.normal.fg,
|
||||||
|
True, False, False);
|
||||||
|
|
||||||
|
barwin_map(item[i]);
|
||||||
|
barwin_refresh_color(item[i]);
|
||||||
|
menu_draw_item_name(&menu, i, item, chcklen);
|
||||||
|
barwin_refresh(item[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Select the first item */
|
||||||
|
menu_focus_item(&menu, 0, item);
|
||||||
|
|
||||||
|
XGrabKeyboard(dpy, ROOT, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||||
|
|
||||||
|
while(!menu_manage_event(&ev, &menu, item));
|
||||||
|
|
||||||
|
XUngrabKeyboard(dpy, CurrentTime);
|
||||||
|
|
||||||
|
for(i = 0; i < menu.nitem; ++i)
|
||||||
|
barwin_delete(item[i]);
|
||||||
|
barwin_delete(frame);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
499
src/mouse.c
499
src/mouse.c
@ -1,242 +1,373 @@
|
|||||||
/*
|
/*
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
* mouse.c
|
||||||
* For license, see COPYING.
|
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
|
||||||
*/
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of the nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "wmfs.h"
|
#include "wmfs.h"
|
||||||
#include "mouse.h"
|
|
||||||
#include "barwin.h"
|
|
||||||
#include "client.h"
|
|
||||||
#include "draw.h"
|
|
||||||
|
|
||||||
#define _REV_SBORDER(c) draw_reversed_rect(W->root, c, false);
|
|
||||||
|
|
||||||
#define _REV_BORDER() \
|
|
||||||
do { \
|
|
||||||
FOREACH_NFCLIENT(gc, &c->tag->clients, tnext) \
|
|
||||||
draw_reversed_rect(W->root, gc, true); \
|
|
||||||
} while(/* CONSTCOND */ 0);
|
|
||||||
|
|
||||||
|
/** Draw the border when a client in dragging/resizing with mouse
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
mouse_resize(struct client *c)
|
mouse_dragborder(XRectangle geo, GC g)
|
||||||
{
|
{
|
||||||
struct client *gc;
|
XDrawRectangle(dpy, ROOT, g,
|
||||||
XEvent ev;
|
geo.x - BORDH / 2,
|
||||||
Window w;
|
geo.y - (TBARH - (BORDH / 2)),
|
||||||
int d, u, ox, oy, ix, iy;
|
geo.width + BORDH,
|
||||||
int mx, my;
|
geo.height + TBARH);
|
||||||
|
|
||||||
XQueryPointer(W->dpy, W->root, &w, &w, &ox, &oy, &d, &d, (unsigned int *)&u);
|
return;
|
||||||
XGrabServer(W->dpy);
|
|
||||||
|
|
||||||
if(c->flags & CLIENT_FREE)
|
|
||||||
{
|
|
||||||
_REV_SBORDER(c);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
_REV_BORDER();
|
|
||||||
|
|
||||||
if(c->flags & CLIENT_TABBED && !(c->flags & CLIENT_TABMASTER))
|
|
||||||
c = c->tabmaster;
|
|
||||||
|
|
||||||
ix = ox;
|
|
||||||
iy = oy;
|
|
||||||
|
|
||||||
c->flags |= CLIENT_MOUSE;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
XMaskEvent(W->dpy, MouseMask | SubstructureRedirectMask, &ev);
|
|
||||||
|
|
||||||
if(ev.type != MotionNotify)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
mx = ev.xmotion.x_root;
|
|
||||||
my = ev.xmotion.y_root;
|
|
||||||
|
|
||||||
if(c->flags & CLIENT_FREE)
|
|
||||||
{
|
|
||||||
_REV_SBORDER(c);
|
|
||||||
|
|
||||||
mx -= c->screen->ugeo.x;
|
|
||||||
my -= c->screen->ugeo.y;
|
|
||||||
|
|
||||||
c->geo.w = ((mx - c->geo.x <= c->sizeh[MINW] + c->border + c->border)
|
|
||||||
? c->sizeh[MINW] + c->border + c->border
|
|
||||||
: mx - c->geo.x);
|
|
||||||
c->geo.h = ((my - c->geo.y <= (c->sizeh[MINH] + c->tbarw + c->border))
|
|
||||||
? c->sizeh[MINH] + c->tbarw + c->border
|
|
||||||
: my - c->geo.y);
|
|
||||||
|
|
||||||
client_geo_hints(&c->geo, (int*)c->sizeh);
|
|
||||||
|
|
||||||
/* For border preview cohesion */
|
|
||||||
c->geo.h += c->tbarw + c->border;
|
|
||||||
c->geo.w += c->border + c->border;
|
|
||||||
|
|
||||||
_REV_SBORDER(c);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_REV_BORDER();
|
|
||||||
|
|
||||||
if(ix >= c->rgeo.x + (c->geo.w >> 1))
|
|
||||||
_fac_resize(c, Right, mx - ox);
|
|
||||||
else
|
|
||||||
_fac_resize(c, Left, ox - mx);
|
|
||||||
|
|
||||||
if(iy >= c->rgeo.y + (c->geo.h >> 1))
|
|
||||||
_fac_resize(c, Bottom, my - oy);
|
|
||||||
else
|
|
||||||
_fac_resize(c, Top, oy - my);
|
|
||||||
|
|
||||||
ox = mx;
|
|
||||||
oy = my;
|
|
||||||
|
|
||||||
_REV_BORDER();
|
|
||||||
}
|
|
||||||
|
|
||||||
XSync(W->dpy, false);
|
|
||||||
|
|
||||||
} while(ev.type != ButtonRelease);
|
|
||||||
|
|
||||||
if(c->flags & CLIENT_FREE)
|
|
||||||
{
|
|
||||||
_REV_SBORDER(c);
|
|
||||||
client_moveresize(c, &c->geo);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_REV_BORDER();
|
|
||||||
client_apply_tgeo(c->tag);
|
|
||||||
layout_save_set(c->tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
c->flags &= ~CLIENT_MOUSE;
|
|
||||||
|
|
||||||
XUngrabServer(W->dpy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct tag*
|
/** Move a client in tile grid with the mouse
|
||||||
mouse_drag_tag(struct client *c, Window w)
|
*\param c Client double pointer
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
mouse_move_tile_client(Client **c)
|
||||||
{
|
{
|
||||||
struct barwin *b;
|
Client *sc;
|
||||||
struct tag *t = NULL;
|
Window w;
|
||||||
Window rw;
|
int d;
|
||||||
int d, u;
|
|
||||||
|
|
||||||
XQueryPointer(W->dpy, w, &rw, &rw, &d, &d, &d, &d, (uint *)&u);
|
if(!((*c)->flags & TileFlag) && !((*c)->flags & LMaxFlag))
|
||||||
|
return;
|
||||||
|
|
||||||
SLIST_FOREACH(b, &W->h.barwin, next)
|
XQueryPointer(dpy, ROOT, &w, &w, &d, &d, &d, &d, (uint*)&d);
|
||||||
if(b->win == rw
|
|
||||||
&& (t = (struct tag*)b->ptr)
|
if(((sc = client_gb_win(w)) || (sc = client_gb_frame(w)) || (sc = client_gb_titlebar(w)))
|
||||||
&& t != c->tag)
|
&& (*c)->win != sc->win && !((*c)->flags & HideFlag) && !(sc->flags & HideFlag))
|
||||||
return t;
|
{
|
||||||
|
client_swap(sc, *c);
|
||||||
|
client_focus(sc);
|
||||||
|
swap_ptr((void**)c, (void**)&sc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
/** Move a client from one tag to another with dah mouse
|
||||||
mouse_move(struct client *c, void (*func)(struct client*, struct client*))
|
*\param c client pointer
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
mouse_move_tag_client(Client *c)
|
||||||
{
|
{
|
||||||
struct client *c2 = NULL, *last = c;
|
|
||||||
struct tag *t = NULL;
|
|
||||||
XEvent ev;
|
|
||||||
Window w;
|
Window w;
|
||||||
int d, u, ox, oy;
|
int i, d, s;
|
||||||
int ocx, ocy;
|
|
||||||
|
if(!(c->flags & TileFlag) && !(c->flags & LMaxFlag))
|
||||||
|
return;
|
||||||
|
|
||||||
|
s = c->screen;
|
||||||
|
|
||||||
|
XQueryPointer(dpy, infobar[selscreen].tags_board->win, &w, &w, &d, &d, &d, &d, (uint*)&d);
|
||||||
|
|
||||||
|
for(i = 1; i < conf.ntag[selscreen] + 1; ++i)
|
||||||
|
if(infobar[selscreen].tags[i]->win == w
|
||||||
|
&& tags[selscreen][i].layout.func != freelayout)
|
||||||
|
{
|
||||||
|
c->screen = selscreen;
|
||||||
|
c->tag = i;
|
||||||
|
tags[c->screen][c->tag].request_update = True;
|
||||||
|
arrange(s, True);
|
||||||
|
|
||||||
|
if(s != c->screen)
|
||||||
|
arrange(c->screen, True);
|
||||||
|
}
|
||||||
|
|
||||||
|
client_focus_next(c);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Move the client with the mouse
|
||||||
|
* \param c Client pointer
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
mouse_move(Client *c)
|
||||||
|
{
|
||||||
|
int ocx, ocy, mx, my;
|
||||||
|
int dint;
|
||||||
|
uint duint;
|
||||||
|
Window dw;
|
||||||
|
XRectangle geo = c->geo;
|
||||||
|
XGCValues xgc;
|
||||||
|
GC gci;
|
||||||
|
XEvent ev;
|
||||||
|
|
||||||
|
if((c->flags & MaxFlag) || (c->flags & FSSFlag))
|
||||||
|
return;
|
||||||
|
|
||||||
ocx = c->geo.x;
|
ocx = c->geo.x;
|
||||||
ocy = c->geo.y;
|
ocy = c->geo.y;
|
||||||
|
|
||||||
if(c->flags & CLIENT_TABBED && !(c->flags & CLIENT_TABMASTER))
|
if(XGrabPointer(dpy, ROOT, False, MouseMask, GrabModeAsync, GrabModeAsync,
|
||||||
c = c->tabmaster;
|
None, cursor[CurMove], CurrentTime) != GrabSuccess)
|
||||||
|
return;
|
||||||
|
|
||||||
XQueryPointer(W->dpy, W->root, &w, &w, &ox, &oy, &d, &d, (uint *)&u);
|
if(!(c->flags & TileFlag) && !(c->flags & LMaxFlag))
|
||||||
|
XGrabServer(dpy);
|
||||||
|
|
||||||
_REV_SBORDER(c);
|
/* Set the GC for the rectangle */
|
||||||
|
xgc.function = GXinvert;
|
||||||
|
xgc.subwindow_mode = IncludeInferiors;
|
||||||
|
xgc.line_width = BORDH;
|
||||||
|
gci = XCreateGC(dpy, ROOT, GCFunction | GCSubwindowMode | GCLineWidth, &xgc);
|
||||||
|
|
||||||
c->flags |= CLIENT_MOUSE;
|
if(!(c->flags & TileFlag) && !(c->flags & LMaxFlag))
|
||||||
|
mouse_dragborder(c->geo, gci);
|
||||||
|
|
||||||
|
XQueryPointer(dpy, ROOT, &dw, &dw, &mx, &my, &dint, &dint, &duint);
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
XMaskEvent(W->dpy, MouseMask | SubstructureRedirectMask, &ev);
|
XMaskEvent(dpy, MouseMask | SubstructureRedirectMask, &ev);
|
||||||
|
screen_get_sel();
|
||||||
|
|
||||||
if(ev.type != MotionNotify)
|
if(ev.type == MotionNotify)
|
||||||
continue;
|
|
||||||
|
|
||||||
if(!func && c->flags & CLIENT_FREE)
|
|
||||||
{
|
{
|
||||||
_REV_SBORDER(c);
|
mouse_move_tile_client(&c);
|
||||||
|
mouse_move_tag_client(c);
|
||||||
|
|
||||||
c->geo.x = (ocx + (ev.xmotion.x_root - ox));
|
/* To move a client normally, in freelayout */
|
||||||
c->geo.y = (ocy + (ev.xmotion.y_root - oy));
|
if(!(c->flags & TileFlag) && !(c->flags & LMaxFlag))
|
||||||
|
{
|
||||||
|
mouse_dragborder(geo, gci);
|
||||||
|
|
||||||
_REV_SBORDER(c);
|
geo.x = (ocx + (ev.xmotion.x - mx));
|
||||||
|
geo.y = (ocy + (ev.xmotion.y - my));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Need to draw 2 times the same rectangle because
|
||||||
|
* it is draw with the revert color; revert + revert = normal
|
||||||
|
*/
|
||||||
|
mouse_dragborder(geo, gci);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(ev.type == MapRequest
|
||||||
|
|| ev.type == ConfigureRequest)
|
||||||
|
getevent(ev);
|
||||||
|
}
|
||||||
|
while(ev.type != ButtonRelease);
|
||||||
|
|
||||||
|
/* One time again to delete all the trace on the window */
|
||||||
|
if(!(c->flags & TileFlag) && !(c->flags & LMaxFlag))
|
||||||
|
{
|
||||||
|
mouse_dragborder(geo, gci);
|
||||||
|
client_moveresize(c, geo, False);
|
||||||
|
frame_update(c);
|
||||||
|
XUngrabServer(dpy);
|
||||||
|
}
|
||||||
|
client_update_attributes(c);
|
||||||
|
XUngrabPointer(dpy, CurrentTime);
|
||||||
|
XFreeGC(dpy, gci);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Resize a client with the mouse
|
||||||
|
* \param c Client pointer
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
mouse_resize(Client *c)
|
||||||
|
{
|
||||||
|
XRectangle geo = c->geo, ogeo = c->geo;
|
||||||
|
Position pos = Right;
|
||||||
|
XEvent ev;
|
||||||
|
Window w;
|
||||||
|
int d, u, omx, omy;
|
||||||
|
XGCValues xgc;
|
||||||
|
GC gci;
|
||||||
|
float mwf = tags[selscreen][seltag[selscreen]].mwfact;
|
||||||
|
|
||||||
|
if((c->flags & MaxFlag)
|
||||||
|
|| (c->flags & LMaxFlag)
|
||||||
|
|| (c->flags & FSSFlag))
|
||||||
|
return;
|
||||||
|
|
||||||
|
XQueryPointer(dpy, ROOT, &w, &w, &omx, &omy, &d, &d, (uint *)&u);
|
||||||
|
|
||||||
|
if((omx - c->geo.x) < (c->geo.width / 2))
|
||||||
|
pos = Left;
|
||||||
|
|
||||||
|
if(XGrabPointer(dpy, ROOT, False, MouseMask, GrabModeAsync, GrabModeAsync, None,
|
||||||
|
cursor[((c->flags & TileFlag) ? CurResize : ((pos == Right) ? CurRightResize : CurLeftResize))],
|
||||||
|
CurrentTime) != GrabSuccess)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(!(c->flags & TileFlag))
|
||||||
|
XGrabServer(dpy);
|
||||||
|
|
||||||
|
/* Set the GC for the rectangle */
|
||||||
|
xgc.function = GXinvert;
|
||||||
|
xgc.subwindow_mode = IncludeInferiors;
|
||||||
|
xgc.line_width = BORDH;
|
||||||
|
gci = XCreateGC(dpy, ROOT, GCFunction | GCSubwindowMode | GCLineWidth, &xgc);
|
||||||
|
|
||||||
|
if(!(c->flags & TileFlag))
|
||||||
|
{
|
||||||
|
if(pos == Right)
|
||||||
|
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->geo.width + conf.client.borderheight, c->geo.height);
|
||||||
|
else
|
||||||
|
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, 0, c->geo.height);
|
||||||
|
mouse_dragborder(c->geo, gci);
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
XMaskEvent(dpy, MouseMask | SubstructureRedirectMask, &ev);
|
||||||
|
|
||||||
|
if(ev.type == MotionNotify)
|
||||||
|
{
|
||||||
|
/* To resize MWFACT in tile mode */
|
||||||
|
if((c->flags & TileFlag)
|
||||||
|
&& tags[selscreen][seltag[selscreen]].layout.func != grid_vertical
|
||||||
|
&& tags[selscreen][seltag[selscreen]].layout.func != grid_horizontal)
|
||||||
|
{
|
||||||
|
if(tags[selscreen][seltag[selscreen]].layout.func == tile)
|
||||||
|
mwf += (ROUND(ev.xmotion.x_root) - omx) / (sgeo[c->screen].width);
|
||||||
|
else if(tags[selscreen][seltag[selscreen]].layout.func == tile_left)
|
||||||
|
mwf -= (ROUND(ev.xmotion.x_root) - omx) / (sgeo[c->screen].width);
|
||||||
|
else if(tags[selscreen][seltag[selscreen]].layout.func == tile_top)
|
||||||
|
mwf -= (ROUND(ev.xmotion.y_root) - omy) / (sgeo[c->screen].height);
|
||||||
|
else
|
||||||
|
mwf += (ROUND(ev.xmotion.y_root) - omy) / (sgeo[c->screen].height);
|
||||||
|
|
||||||
|
omx = ROUND(ev.xmotion.x_root);
|
||||||
|
omy = ROUND(ev.xmotion.y_root);
|
||||||
|
|
||||||
|
tags[selscreen][seltag[selscreen]].mwfact = (mwf < 0.05) ? 0.05 : ((mwf > 0.95) ? 0.95 : mwf);
|
||||||
|
}
|
||||||
|
/* Free mode */
|
||||||
|
else if(!(c->flags & TileFlag))
|
||||||
|
{
|
||||||
|
mouse_dragborder(geo, gci);
|
||||||
|
|
||||||
|
if(pos == Right)
|
||||||
|
{
|
||||||
|
geo.width = ((ev.xmotion.x - c->geo.x < c->minw) ? c->minw : ev.xmotion.x - c->geo.x);
|
||||||
|
geo.height = ((ev.xmotion.y - c->geo.y < c->minh) ? c->minh : ev.xmotion.y - c->geo.y);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
c2 = NULL;
|
geo.x = (geo.width != c->maxw) ? c->geo.x - (c->geo.x - ev.xmotion.x) : geo.x;
|
||||||
|
geo.width = ((c->geo.width + (c->geo.x - geo.x) < c->minw)
|
||||||
XQueryPointer(W->dpy, W->root, &w, &w, &d, &d, &d, &d, (uint *)&u);
|
? c->minw && (geo.x = (c->geo.x + c->geo.width) - c->minw)
|
||||||
|
: c->geo.width + (c->geo.x - geo.x));
|
||||||
if((c2 = client_gb_win(w)) || (c2 = client_gb_frame(w)) || (c2 = client_gb_titlebar(w)))
|
geo.height = ((ev.xmotion.y - c->geo.y <= c->minh) ? c->minh : ev.xmotion.y - c->geo.y);
|
||||||
{
|
|
||||||
if(c2 != last)
|
|
||||||
{
|
|
||||||
_REV_SBORDER(last);
|
|
||||||
_REV_SBORDER(c2);
|
|
||||||
last = c2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
client_geo_hints(&geo, c);
|
||||||
|
|
||||||
|
mouse_dragborder((ogeo = geo), gci);
|
||||||
|
|
||||||
|
XSync(dpy, False);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while(ev.type != ButtonRelease);
|
||||||
|
|
||||||
|
if(!(c->flags & TileFlag))
|
||||||
|
{
|
||||||
|
mouse_dragborder(ogeo, gci);
|
||||||
|
client_moveresize(c, geo, True);
|
||||||
|
frame_update(c);
|
||||||
|
XUngrabServer(dpy);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
t = mouse_drag_tag(c, w);
|
tags[selscreen][seltag[selscreen]].layout.func(c->screen);
|
||||||
}
|
|
||||||
|
|
||||||
XSync(W->dpy, false);
|
client_update_attributes(c);
|
||||||
|
XUngrabPointer(dpy, CurrentTime);
|
||||||
|
XFreeGC(dpy, gci);
|
||||||
|
|
||||||
} while(ev.type != ButtonRelease);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(c2)
|
/** Grab buttons
|
||||||
func(c, c2);
|
* \param c Client pointer
|
||||||
else if(t && t != (struct tag*)c)
|
* \param focused For know if c is or not focused
|
||||||
tag_client(t, c);
|
*/
|
||||||
else
|
void
|
||||||
|
mouse_grabbuttons(Client *c, Bool focused)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
uint but[] = {Button1, Button2, Button3, Button4, Button5};
|
||||||
|
|
||||||
|
XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
|
||||||
|
if(focused)
|
||||||
|
for(i = 0; i < LEN(but); ++i)
|
||||||
{
|
{
|
||||||
_REV_SBORDER(c);
|
XGrabButton(dpy, but[i], conf.client.mod, c->win, False,
|
||||||
|
ButtonMask, GrabModeAsync,GrabModeSync, None, None);
|
||||||
/* No func mean free client resize */
|
XGrabButton(dpy, but[i], conf.client.mod|LockMask, c->win, False,
|
||||||
if(!func)
|
ButtonMask, GrabModeAsync,GrabModeSync, None, None);
|
||||||
client_moveresize(c, &c->geo);
|
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,
|
||||||
|
ButtonMask, GrabModeAsync, GrabModeSync, None, None);
|
||||||
|
|
||||||
c->flags &= ~CLIENT_MOUSE;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Move the selected client
|
||||||
|
* \param cmd uicb_t type unused
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
uicb_mouse_resize(Uicb cmd)
|
uicb_mouse_move(uicb_t cmd)
|
||||||
{
|
{
|
||||||
(void)cmd;
|
(void)cmd;
|
||||||
|
CHECK(sel);
|
||||||
|
|
||||||
if(W->client && mouse_check_client(W->client))
|
mouse_move(sel);
|
||||||
mouse_resize(W->client);
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Reisze the selected client
|
||||||
|
* \param cmd uicb_t type unused
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
uicb_mouse_move(Uicb cmd)
|
uicb_mouse_resize(uicb_t cmd)
|
||||||
{
|
{
|
||||||
(void)cmd;
|
(void)cmd;
|
||||||
|
CHECK(sel);
|
||||||
|
|
||||||
if(W->client && mouse_check_client(W->client))
|
mouse_resize(sel);
|
||||||
mouse_move(W->client, (W->client->flags & CLIENT_FREE ? NULL : client_swap2));
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
uicb_mouse_tab(Uicb cmd)
|
|
||||||
{
|
|
||||||
(void)cmd;
|
|
||||||
|
|
||||||
if(W->client && mouse_check_client(W->client))
|
|
||||||
mouse_move(W->client, _client_tab);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
29
src/mouse.h
29
src/mouse.h
@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
|
||||||
* For license, see COPYING.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MOUSE_H
|
|
||||||
#define MOUSE_H
|
|
||||||
|
|
||||||
#include "client.h"
|
|
||||||
|
|
||||||
void uicb_mouse_resize(Uicb);
|
|
||||||
void uicb_mouse_move(Uicb);
|
|
||||||
void uicb_mouse_tab(Uicb);
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
mouse_check_client(struct client *c)
|
|
||||||
{
|
|
||||||
Window w;
|
|
||||||
int d;
|
|
||||||
|
|
||||||
XQueryPointer(W->dpy, W->root, &w, &w, &d, &d, &d, &d, (uint *)&d);
|
|
||||||
|
|
||||||
if(c == client_gb_win(w) || c == client_gb_titlebar(w) || c == client_gb_frame(w))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* MOUSE_H */
|
|
||||||
320
src/parse.c
320
src/parse.c
@ -1,6 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2010 Philippe Pepiot <phil@philpep.org>
|
* Copyright (c) 2010 Philippe Pepiot <phil@philpep.org>
|
||||||
* Copyright (c) 2011 Martin Duquesnoy <xorg62@gmail.com>
|
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -35,19 +34,16 @@
|
|||||||
#include <err.h>
|
#include <err.h>
|
||||||
|
|
||||||
#include "parse.h"
|
#include "parse.h"
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
extern char *__progname;
|
extern char *__progname;
|
||||||
|
|
||||||
enum keyword_t { SEC_START, SEC_END, INCLUDE, WORD, EQUAL, LIST_START, LIST_END, NONE };
|
enum keyword_t { SEC_START, SEC_END, INCLUDE, WORD, EQUAL, LIST_START, LIST_END, NONE };
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static const struct
|
static struct {
|
||||||
{
|
|
||||||
const char *name;
|
const char *name;
|
||||||
enum keyword_t type;
|
enum keyword_t type;
|
||||||
} kw_t_name[] =
|
} kw_t_name[] = {
|
||||||
{
|
|
||||||
{"SEC_START", SEC_START},
|
{"SEC_START", SEC_START},
|
||||||
{"SEC_END", SEC_END},
|
{"SEC_END", SEC_END},
|
||||||
{"INCLUDE", INCLUDE},
|
{"INCLUDE", INCLUDE},
|
||||||
@ -59,14 +55,12 @@ static const struct
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct files
|
struct files {
|
||||||
{
|
|
||||||
char *name;
|
char *name;
|
||||||
struct files *parent;
|
struct files *parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct keyword
|
struct keyword {
|
||||||
{
|
|
||||||
enum keyword_t type;
|
enum keyword_t type;
|
||||||
/* if WORD */
|
/* if WORD */
|
||||||
int line;
|
int line;
|
||||||
@ -75,10 +69,9 @@ struct keyword
|
|||||||
struct keyword *next;
|
struct keyword *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct state
|
struct state {
|
||||||
{
|
bool_t quote;
|
||||||
bool quote;
|
bool_t comment;
|
||||||
bool comment;
|
|
||||||
char quote_char;
|
char quote_char;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -94,38 +87,37 @@ push_keyword(struct keyword *tail, enum keyword_t type, char *buf, size_t *offse
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(type == WORD && *offset == 0)
|
if (type == WORD && *offset == 0)
|
||||||
return tail;
|
return tail;
|
||||||
|
|
||||||
kw = xcalloc(1, sizeof(*kw));
|
kw = zcalloc(sizeof(*kw));
|
||||||
kw->type = type;
|
kw->type = type;
|
||||||
kw->line = line;
|
kw->line = line;
|
||||||
kw->file = file;
|
kw->file = file;
|
||||||
kw->next = NULL;
|
kw->next = NULL;
|
||||||
|
|
||||||
if(*offset)
|
if (*offset != 0) {
|
||||||
{
|
|
||||||
buf[*offset] = '\0';
|
buf[*offset] = '\0';
|
||||||
|
if (!strcmp(buf, INCLUDE_CMD))
|
||||||
if(!strcmp(buf, INCLUDE_CMD))
|
|
||||||
kw->type = INCLUDE;
|
kw->type = INCLUDE;
|
||||||
else
|
else
|
||||||
kw->name = strdup(buf);
|
kw->name = strdup(buf);
|
||||||
|
|
||||||
*offset = 0;
|
*offset = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
kw->name = NULL;
|
kw->name = NULL;
|
||||||
|
|
||||||
if(tail)
|
if (tail)
|
||||||
tail->next = kw;
|
tail->next = kw;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
for(i = 0; kw_t_name[i].type != NONE; ++i)
|
for (i = 0; kw_t_name[i].type != NONE; i++) {
|
||||||
if(kw_t_name[i].type == kw->type)
|
if (kw_t_name[i].type == kw->type) {
|
||||||
warnxl("%s %s %s:%d\n", kw_t_name[i].name,
|
warnx("%s %s %s:%d\n", kw_t_name[i].name,
|
||||||
(kw->name) ? kw->name : "",
|
(kw->name) ? kw->name : "",
|
||||||
kw->file->name, kw->line);
|
kw->file->name, kw->line);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return kw;
|
return kw;
|
||||||
@ -138,10 +130,10 @@ syntax(struct keyword *kw, const char *fmt, ...)
|
|||||||
|
|
||||||
fprintf(stderr, "%s:", __progname);
|
fprintf(stderr, "%s:", __progname);
|
||||||
|
|
||||||
if(kw && kw->file && kw->file->name)
|
if (kw && kw->file && kw->file->name)
|
||||||
fprintf(stderr, "%s:%d", kw->file->name, kw->line);
|
fprintf(stderr, "%s:%d", kw->file->name, kw->line);
|
||||||
|
|
||||||
if(kw && kw->name)
|
if (kw && kw->name)
|
||||||
fprintf(stderr, ", near '%s'", kw->name);
|
fprintf(stderr, ", near '%s'", kw->name);
|
||||||
fprintf(stderr, ": ");
|
fprintf(stderr, ": ");
|
||||||
|
|
||||||
@ -160,43 +152,40 @@ parse_keywords(const char *filename)
|
|||||||
int fd;
|
int fd;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
struct keyword *head = NULL;
|
struct keyword *head = NULL;
|
||||||
struct keyword *tail = NULL;
|
struct keyword *tail = NULL;
|
||||||
struct files *file;
|
struct files *file;
|
||||||
enum keyword_t type; /* keyword type to push */
|
enum keyword_t type; /* keyword type to push */
|
||||||
struct state s = { false, false, '\0'};
|
struct state s = { False, False, '\0'};
|
||||||
char *bufname;
|
char *bufname;
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
size_t i, j;
|
size_t i, j;
|
||||||
int line;
|
int line;
|
||||||
bool error = false;
|
bool_t error = False;
|
||||||
|
|
||||||
|
|
||||||
if(stat(filename, &st) == -1 || (fd = open(filename, O_RDONLY)) == -1)
|
if ((fd = open(filename, O_RDONLY)) == -1 || stat(filename, &st) == -1) {
|
||||||
{
|
warn("%s", filename);
|
||||||
warnxl("%s", filename);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!st.st_size)
|
if (st.st_size == 0) {
|
||||||
{
|
warnx("%s: empty file", filename);
|
||||||
warnxl("%s: empty file", filename);
|
|
||||||
close(fd);
|
close(fd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!realpath(filename, path))
|
if (!realpath(filename, path)) {
|
||||||
{
|
warn("%s", filename);
|
||||||
warnxl("%s", filename);
|
|
||||||
close(fd);
|
close(fd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = xmalloc(1, st.st_size + 1);
|
buf = zmalloc(st.st_size+1);
|
||||||
|
|
||||||
if(read(fd, buf, st.st_size) == -1)
|
if (read(fd, buf, st.st_size) == -1) {
|
||||||
{
|
warn("%s", filename);
|
||||||
warnxl("%s", filename);
|
|
||||||
free(buf);
|
free(buf);
|
||||||
close(fd);
|
close(fd);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -204,127 +193,112 @@ parse_keywords(const char *filename)
|
|||||||
|
|
||||||
buf[st.st_size] = '\0';
|
buf[st.st_size] = '\0';
|
||||||
|
|
||||||
file = xcalloc(1, sizeof(*file));
|
file = zcalloc(sizeof(*file));
|
||||||
bufname = xcalloc(BUFSIZ, sizeof(*bufname));
|
bufname = zcalloc(sizeof(*bufname) * BUFSIZ);
|
||||||
file->name = strdup(path);
|
file->name = strdup(path);
|
||||||
file->parent = NULL;
|
file->parent = NULL;
|
||||||
|
|
||||||
for(i = j = 0, line = 1; i < (size_t)st.st_size; ++i)
|
for(i = 0, j = 0, line = 1; i < (size_t)st.st_size; i++) {
|
||||||
{
|
|
||||||
if(!head && tail)
|
if (!head && tail)
|
||||||
head = tail;
|
head = tail;
|
||||||
|
|
||||||
if(buf[i] == '\n' && s.comment)
|
if (buf[i] == '\n' && s.comment == True) {
|
||||||
{
|
|
||||||
line++;
|
line++;
|
||||||
s.comment = false;
|
s.comment = False;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(buf[i] == '#' && !s.quote)
|
if (buf[i] == '#' && s.quote == False) {
|
||||||
{
|
s.comment = True;
|
||||||
s.comment = true;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(s.comment)
|
if (s.comment == True)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (s.quote == True && buf[i] == s.quote_char) {
|
||||||
/* end of quotted string */
|
/* end of quotted string */
|
||||||
if(s.quote && buf[i] == s.quote_char)
|
|
||||||
{
|
|
||||||
PUSH_KEYWORD(WORD);
|
PUSH_KEYWORD(WORD);
|
||||||
s.quote = false;
|
s.quote = False;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!s.quote)
|
if (s.quote == False) {
|
||||||
{
|
if ((buf[i] == '"' || buf[i] == '\'')) {
|
||||||
if((buf[i] == '"' || buf[i] == '\''))
|
|
||||||
{
|
|
||||||
PUSH_KEYWORD(WORD);
|
PUSH_KEYWORD(WORD);
|
||||||
/* begin quotted string */
|
/* begin quotted string */
|
||||||
s.quote_char = buf[i];
|
s.quote_char = buf[i];
|
||||||
s.quote = true;
|
s.quote = True;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(buf[i] == '[')
|
if (buf[i] == '[') {
|
||||||
{
|
|
||||||
PUSH_KEYWORD(WORD);
|
PUSH_KEYWORD(WORD);
|
||||||
|
if (buf[i+1] == '/') {
|
||||||
if(buf[i + 1] == '/')
|
i +=2;
|
||||||
{
|
|
||||||
i += 2;
|
|
||||||
type = SEC_END;
|
type = SEC_END;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
i++;
|
||||||
++i;
|
|
||||||
type = SEC_START;
|
type = SEC_START;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get section name */
|
/* get section name */
|
||||||
while(buf[i] != ']')
|
while (buf[i] != ']') {
|
||||||
{
|
|
||||||
if(i >= ((size_t)st.st_size-1) || j >= (BUFSIZ-1))
|
if (i >= ((size_t)st.st_size-1) || j >= (BUFSIZ-1)) {
|
||||||
{
|
|
||||||
bufname[j] = '\0';
|
bufname[j] = '\0';
|
||||||
syntax(NULL, "word too long in %s:%d near '%s'",
|
syntax(NULL, "word too long in %s:%d near '%s'",
|
||||||
file->name, line, bufname);
|
file->name, line, bufname);
|
||||||
error = true;
|
error = True;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
bufname[j++] = buf[i++];
|
bufname[j++] = buf[i++];
|
||||||
}
|
}
|
||||||
PUSH_KEYWORD(type);
|
PUSH_KEYWORD(type);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(buf[i] == '{')
|
if (buf[i] == '{') {
|
||||||
{
|
|
||||||
PUSH_KEYWORD(WORD);
|
PUSH_KEYWORD(WORD);
|
||||||
PUSH_KEYWORD(LIST_START);
|
PUSH_KEYWORD(LIST_START);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(buf[i] == '}')
|
if (buf[i] == '}') {
|
||||||
{
|
|
||||||
PUSH_KEYWORD(WORD);
|
PUSH_KEYWORD(WORD);
|
||||||
PUSH_KEYWORD(LIST_END);
|
PUSH_KEYWORD(LIST_END);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(buf[i] == ',')
|
if (buf[i] == ',') {
|
||||||
{
|
|
||||||
PUSH_KEYWORD(WORD);
|
PUSH_KEYWORD(WORD);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(buf[i] == '=')
|
if (buf[i] == '=') {
|
||||||
{
|
|
||||||
PUSH_KEYWORD(WORD);
|
PUSH_KEYWORD(WORD);
|
||||||
PUSH_KEYWORD(EQUAL);
|
PUSH_KEYWORD(EQUAL);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(strchr("\t\n ", buf[i]))
|
if (strchr("\t\n ", buf[i])) {
|
||||||
{
|
|
||||||
PUSH_KEYWORD(WORD);
|
PUSH_KEYWORD(WORD);
|
||||||
|
|
||||||
if(buf[i] == '\n')
|
if (buf[i] == '\n')
|
||||||
++line;
|
line++;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
} /* s.quote == False */
|
||||||
|
|
||||||
if(j >= (BUFSIZ - 1))
|
if (j >= (BUFSIZ - 1)) {
|
||||||
{
|
|
||||||
bufname[j] = '\0';
|
bufname[j] = '\0';
|
||||||
syntax(NULL, "word too long in %s:%d near '%s'",
|
syntax(NULL, "word too long in %s:%d near '%s'",
|
||||||
file->name, line, bufname);
|
file->name, line, bufname);
|
||||||
error = true;
|
error = True;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,7 +308,7 @@ parse_keywords(const char *filename)
|
|||||||
free(buf);
|
free(buf);
|
||||||
free(bufname);
|
free(bufname);
|
||||||
close(fd);
|
close(fd);
|
||||||
warnxl("%s read", file->name);
|
warnx("%s read", file->name);
|
||||||
|
|
||||||
return (error ? NULL: head);
|
return (error ? NULL: head);
|
||||||
}
|
}
|
||||||
@ -356,26 +330,22 @@ include(struct keyword *head)
|
|||||||
|
|
||||||
head = head->next;
|
head = head->next;
|
||||||
|
|
||||||
if(!head || head->type != WORD)
|
if (!head || head->type != WORD) {
|
||||||
{
|
|
||||||
syntax(head, "missing filename to include");
|
syntax(head, "missing filename to include");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* replace ~ by user directory */
|
/* replace ~ by user directory */
|
||||||
if(head->name && head->name[0] == '~')
|
if (head->name && head->name[0] == '~') {
|
||||||
{
|
if ( (user = getpwuid(getuid())) && user->pw_dir)
|
||||||
if((user = getpwuid(getuid())) && user->pw_dir)
|
xasprintf(&filename, "%s%s", user->pw_dir, head->name+1);
|
||||||
xasprintf(&filename, "%s%s", user->pw_dir, head->name + 1);
|
else if (getenv("HOME"))
|
||||||
else if(getenv("HOME"))
|
xasprintf(&filename, "%s%s", getenv("HOME"), head->name+1);
|
||||||
xasprintf(&filename, "%s%s", getenv("HOME"), head->name + 1);
|
|
||||||
else /* to warning ? */
|
else /* to warning ? */
|
||||||
filename = head->name;
|
filename = head->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* relative path from parent file */
|
/* relative path from parent file */
|
||||||
else if(head->name && head->name[0] != '/')
|
else if (head->name && head->name[0] != '/') {
|
||||||
{
|
|
||||||
base = strdup(head->file->name);
|
base = strdup(head->file->name);
|
||||||
xasprintf(&filename, "%s/%s", dirname(base), head->name);
|
xasprintf(&filename, "%s/%s", dirname(base), head->name);
|
||||||
free(base);
|
free(base);
|
||||||
@ -383,11 +353,10 @@ include(struct keyword *head)
|
|||||||
else
|
else
|
||||||
filename = head->name;
|
filename = head->name;
|
||||||
|
|
||||||
if(!(kw = parse_keywords(filename)))
|
if (!(kw = parse_keywords(filename))) {
|
||||||
{
|
warnx("no config found in include file %s", head->name);
|
||||||
warnxl("no config found in include file %s", head->name);
|
|
||||||
|
|
||||||
if(filename != head->name)
|
if (filename != head->name)
|
||||||
free(filename);
|
free(filename);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -396,25 +365,21 @@ include(struct keyword *head)
|
|||||||
kw->file->parent = head->file;
|
kw->file->parent = head->file;
|
||||||
|
|
||||||
/* detect circular include */
|
/* detect circular include */
|
||||||
for(file = kw->file->parent; file != NULL; file = file->parent)
|
for (file = kw->file->parent; file != NULL; file = file->parent) {
|
||||||
if(!strcmp(file->name, kw->file->name))
|
if (!strcmp(file->name, kw->file->name)) {
|
||||||
{
|
|
||||||
syntax(kw, "circular include of %s", kw->file->name);
|
syntax(kw, "circular include of %s", kw->file->name);
|
||||||
|
|
||||||
if(filename != head->name)
|
if (filename != head->name)
|
||||||
free(filename);
|
free(filename);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if(filename != head->name)
|
|
||||||
free(filename);
|
|
||||||
|
|
||||||
head = head->next;
|
head = head->next;
|
||||||
|
|
||||||
if(kw)
|
if (kw) {
|
||||||
{
|
for (tail = kw; tail->next; tail = tail->next);
|
||||||
for(tail = kw; tail->next; tail = tail->next);
|
|
||||||
tail->next = head;
|
tail->next = head;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -435,62 +400,53 @@ get_option(struct keyword **head)
|
|||||||
size_t j = 0;
|
size_t j = 0;
|
||||||
struct keyword *kw = *head;
|
struct keyword *kw = *head;
|
||||||
|
|
||||||
o = xcalloc(1, sizeof(*o));
|
o = zcalloc(sizeof(*o));
|
||||||
o->name = kw->name;
|
o->name = kw->name;
|
||||||
o->used = false;
|
o->used = False;
|
||||||
o->line = kw->line;
|
o->line = kw->line;
|
||||||
o->filename = kw->file->name;
|
o->filename = kw->file->name;
|
||||||
|
|
||||||
kw = kw->next;
|
kw = kw->next;
|
||||||
|
|
||||||
if(kw->type != EQUAL)
|
if (kw->type != EQUAL) {
|
||||||
{
|
|
||||||
syntax(kw, "missing '=' here");
|
syntax(kw, "missing '=' here");
|
||||||
return free_opt(o);
|
return free_opt(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(kw = kw->next))
|
kw = kw->next;
|
||||||
{
|
|
||||||
|
if (!kw) {
|
||||||
syntax(kw, "missing value");
|
syntax(kw, "missing value");
|
||||||
return free_opt(o);
|
return free_opt(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(kw->type)
|
|
||||||
{
|
switch (kw->type) {
|
||||||
case INCLUDE:
|
case INCLUDE:
|
||||||
if(!(kw = include(kw)))
|
if (!(kw = include(kw)))
|
||||||
return free_opt(o);
|
return free_opt(o);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WORD:
|
case WORD:
|
||||||
o->val[0] = kw->name;
|
o->val[0] = kw->name;
|
||||||
o->val[1] = NULL;
|
o->val[1] = NULL;
|
||||||
kw = kw->next;
|
kw = kw->next;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIST_START:
|
case LIST_START:
|
||||||
kw = kw->next;
|
kw = kw->next;
|
||||||
|
while (kw && kw->type != LIST_END) {
|
||||||
while(kw && kw->type != LIST_END)
|
switch (kw->type) {
|
||||||
{
|
|
||||||
switch(kw->type)
|
|
||||||
{
|
|
||||||
case WORD:
|
case WORD:
|
||||||
if(j >= (PARSE_MAX_LIST - 1))
|
if (j >= (PARSE_MAX_LIST - 1)) {
|
||||||
{
|
|
||||||
syntax(kw, "too much values in list");
|
syntax(kw, "too much values in list");
|
||||||
return free_opt(o);
|
return free_opt(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
o->val[j++] = kw->name;
|
o->val[j++] = kw->name;
|
||||||
kw = kw->next;
|
kw = kw->next;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INCLUDE:
|
case INCLUDE:
|
||||||
if(!(kw = include(kw)))
|
if (!(kw = include(kw)))
|
||||||
return free_opt(o);
|
return free_opt(o);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
syntax(kw, "declaration into a list");
|
syntax(kw, "declaration into a list");
|
||||||
return free_opt(o);
|
return free_opt(o);
|
||||||
@ -498,15 +454,13 @@ get_option(struct keyword **head)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!kw)
|
if (!kw) {
|
||||||
{
|
|
||||||
syntax(kw, "list unclosed");
|
syntax(kw, "list unclosed");
|
||||||
return free_opt(o);
|
return free_opt(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
kw = kw->next;
|
kw = kw->next;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
syntax(kw, "missing value");
|
syntax(kw, "missing value");
|
||||||
return free_opt(o);
|
return free_opt(o);
|
||||||
@ -523,25 +477,19 @@ free_sec(struct conf_sec *sec)
|
|||||||
struct conf_opt *o;
|
struct conf_opt *o;
|
||||||
struct conf_sec *s;
|
struct conf_sec *s;
|
||||||
|
|
||||||
if(sec)
|
if (sec) {
|
||||||
{
|
while (!SLIST_EMPTY(&sec->optlist)) {
|
||||||
while(!SLIST_EMPTY(&sec->optlist))
|
|
||||||
{
|
|
||||||
o = SLIST_FIRST(&sec->optlist);
|
o = SLIST_FIRST(&sec->optlist);
|
||||||
SLIST_REMOVE_HEAD(&sec->optlist, entry);
|
SLIST_REMOVE_HEAD(&sec->optlist, entry);
|
||||||
free_opt(o);
|
free_opt(o);
|
||||||
}
|
}
|
||||||
|
while (!TAILQ_EMPTY(&sec->sub)) {
|
||||||
while(!TAILQ_EMPTY(&sec->sub))
|
|
||||||
{
|
|
||||||
s = TAILQ_FIRST(&sec->sub);
|
s = TAILQ_FIRST(&sec->sub);
|
||||||
TAILQ_REMOVE(&sec->sub, s, entry);
|
TAILQ_REMOVE(&sec->sub, s, entry);
|
||||||
free_sec(s);
|
free_sec(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(sec);
|
free(sec);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -553,37 +501,31 @@ get_section(struct keyword **head)
|
|||||||
struct conf_sec *sub;
|
struct conf_sec *sub;
|
||||||
struct keyword *kw = *head;
|
struct keyword *kw = *head;
|
||||||
|
|
||||||
s = xcalloc(1, sizeof(*s));
|
s = zcalloc(sizeof(*s));
|
||||||
s->name = kw->name;
|
s->name = kw->name;
|
||||||
|
|
||||||
TAILQ_INIT(&s->sub);
|
TAILQ_INIT(&s->sub);
|
||||||
SLIST_INIT(&s->optlist);
|
SLIST_INIT(&s->optlist);
|
||||||
|
|
||||||
kw = kw->next;
|
kw = kw->next;
|
||||||
|
|
||||||
while(kw && kw->type != SEC_END)
|
while (kw && kw->type != SEC_END) {
|
||||||
{
|
switch (kw->type) {
|
||||||
switch(kw->type)
|
|
||||||
{
|
|
||||||
case INCLUDE:
|
case INCLUDE:
|
||||||
if(!(kw = include(kw)))
|
if (!(kw = include(kw)))
|
||||||
return free_sec(s);
|
return free_sec(s);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SEC_START:
|
case SEC_START:
|
||||||
if(!(sub = get_section(&kw)))
|
if (!(sub = get_section(&kw)))
|
||||||
return free_sec(s);
|
return free_sec(s);
|
||||||
TAILQ_INSERT_TAIL(&s->sub, sub, entry);
|
TAILQ_INSERT_TAIL(&s->sub, sub, entry);
|
||||||
++s->nsub;
|
s->nsub++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WORD:
|
case WORD:
|
||||||
if(!(o = get_option(&kw)))
|
if (!(o = get_option(&kw)))
|
||||||
return free_sec(s);
|
return free_sec(s);
|
||||||
SLIST_INSERT_HEAD(&s->optlist, o, entry);
|
SLIST_INSERT_HEAD(&s->optlist, o, entry);
|
||||||
++s->nopt;
|
s->nopt++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
syntax(kw, "syntax error");
|
syntax(kw, "syntax error");
|
||||||
return free_sec(s);
|
return free_sec(s);
|
||||||
@ -591,8 +533,7 @@ get_section(struct keyword **head)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!kw || strcmp(kw->name, s->name))
|
if (!kw || strcmp(kw->name, s->name)) {
|
||||||
{
|
|
||||||
syntax(kw, "missing end section %s", s->name);
|
syntax(kw, "missing end section %s", s->name);
|
||||||
return free_sec(s);
|
return free_sec(s);
|
||||||
}
|
}
|
||||||
@ -611,8 +552,7 @@ free_conf(void)
|
|||||||
struct files **f = NULL;
|
struct files **f = NULL;
|
||||||
int i, nf = 0;
|
int i, nf = 0;
|
||||||
|
|
||||||
while(!TAILQ_EMPTY(&config))
|
while (!TAILQ_EMPTY(&config)) {
|
||||||
{
|
|
||||||
s = TAILQ_FIRST(&config);
|
s = TAILQ_FIRST(&config);
|
||||||
TAILQ_REMOVE(&config, s, entry);
|
TAILQ_REMOVE(&config, s, entry);
|
||||||
free_sec(s);
|
free_sec(s);
|
||||||
@ -620,34 +560,29 @@ free_conf(void)
|
|||||||
|
|
||||||
kw = keywords;
|
kw = keywords;
|
||||||
|
|
||||||
while(kw)
|
while (kw) {
|
||||||
{
|
|
||||||
nkw = kw->next;
|
nkw = kw->next;
|
||||||
|
|
||||||
free(kw->name);
|
free(kw->name);
|
||||||
|
|
||||||
for(i = 0; i < nf; ++i)
|
for (i = 0; i < nf; i++) {
|
||||||
if(f[i] == kw->file)
|
if (f[i] == kw->file) {
|
||||||
{
|
if (!(f = realloc(f, sizeof(*f) * (++i))))
|
||||||
if(!(f = realloc(f, sizeof(*f) * (++i))))
|
err(EXIT_FAILURE, "realloc");
|
||||||
errl(EXIT_FAILURE, "realloc");
|
f[i-1] = kw->file;
|
||||||
|
}
|
||||||
f[i - 1] = kw->file;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
kw = nkw;
|
kw = nkw;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(nf > 0)
|
if (nf > 0) {
|
||||||
{
|
for (i = 0; i < nf; i++) {
|
||||||
for(i = 0; i < nf; ++i)
|
|
||||||
{
|
|
||||||
free(f[i]->name);
|
free(f[i]->name);
|
||||||
free(f[i]);
|
free(f[i]);
|
||||||
}
|
}
|
||||||
free(f);
|
free(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -657,37 +592,32 @@ get_conf(const char *filename)
|
|||||||
struct conf_sec *s;
|
struct conf_sec *s;
|
||||||
struct keyword *head, *kw;
|
struct keyword *head, *kw;
|
||||||
|
|
||||||
head = kw = parse_keywords(filename);
|
kw = head = parse_keywords(filename);
|
||||||
|
|
||||||
if(!head)
|
if (!head)
|
||||||
return -1; /* TODO ERREUR */
|
return -1; /* TODO ERREUR */
|
||||||
|
|
||||||
keywords = head;
|
keywords = head;
|
||||||
|
|
||||||
TAILQ_INIT(&config);
|
TAILQ_INIT(&config);
|
||||||
|
|
||||||
while(kw)
|
while (kw) {
|
||||||
{
|
switch (kw->type) {
|
||||||
switch(kw->type)
|
|
||||||
{
|
|
||||||
case INCLUDE:
|
case INCLUDE:
|
||||||
if(!(kw = include(kw)))
|
if (!(kw = include(kw)))
|
||||||
return free_conf();
|
return free_conf();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SEC_START:
|
case SEC_START:
|
||||||
if(!(s = get_section(&kw)))
|
if (!(s = get_section(&kw)))
|
||||||
return free_conf();
|
return free_conf();
|
||||||
TAILQ_INSERT_TAIL(&config, s, entry);
|
TAILQ_INSERT_TAIL(&config, s, entry);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
syntax(kw, "out of any section");
|
syntax(kw, "out of any section");
|
||||||
return free_conf();
|
return free_conf();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
23
src/parse.h
23
src/parse.h
@ -1,6 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2010 Philippe Pepiot <phil@philpep.org>
|
* Copyright (c) 2010 Philippe Pepiot <phil@philpep.org>
|
||||||
* Copyright (c) 2011 Martin Duquesnoy <xorg62@gmail.com>
|
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -19,36 +18,40 @@
|
|||||||
#define PARSE_H
|
#define PARSE_H
|
||||||
|
|
||||||
#include "wmfs.h"
|
#include "wmfs.h"
|
||||||
|
#include <sys/queue.h>
|
||||||
|
|
||||||
#define INCLUDE_CMD "@include"
|
#define INCLUDE_CMD "@include"
|
||||||
#define PARSE_MAX_LIST 32
|
#define PARSE_MAX_LIST 32
|
||||||
|
|
||||||
struct conf_opt
|
#if defined(Bool)
|
||||||
{
|
#define bool_t Bool
|
||||||
|
#else
|
||||||
|
typedef enum { False, True } bool_t;
|
||||||
|
#endif /* Bool */
|
||||||
|
|
||||||
|
struct conf_opt {
|
||||||
char *name;
|
char *name;
|
||||||
char *val[PARSE_MAX_LIST];
|
char *val[PARSE_MAX_LIST];
|
||||||
size_t nval;
|
size_t nval;
|
||||||
bool used;
|
bool_t used;
|
||||||
int line;
|
int line;
|
||||||
char *filename;
|
char *filename;
|
||||||
SLIST_ENTRY(conf_opt) entry;
|
SLIST_ENTRY(conf_opt) entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct conf_sec
|
struct conf_sec {
|
||||||
{
|
|
||||||
char *name;
|
char *name;
|
||||||
SLIST_HEAD(, conf_opt) optlist;
|
SLIST_HEAD(, conf_opt) optlist;
|
||||||
TAILQ_HEAD(cshead, conf_sec) sub;
|
TAILQ_HEAD(, conf_sec) sub;
|
||||||
size_t nopt;
|
size_t nopt;
|
||||||
size_t nsub;
|
size_t nsub;
|
||||||
TAILQ_ENTRY(conf_sec) entry;
|
TAILQ_ENTRY(conf_sec) entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct opt_type
|
struct opt_type {
|
||||||
{
|
|
||||||
long int num;
|
long int num;
|
||||||
float fnum;
|
float fnum;
|
||||||
bool boolean;
|
bool_t bool;
|
||||||
char *str;
|
char *str;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
111
src/parse_api.c
111
src/parse_api.c
@ -1,6 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2010 Philippe Pepiot <phil@philpep.org>
|
* Copyright (c) 2010 Philippe Pepiot <phil@philpep.org>
|
||||||
* Copyright (c) 2011 Martin Duquesnoy <xorg62@gmail.com>
|
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -22,29 +21,28 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
|
|
||||||
#include "wmfs.h"
|
|
||||||
#include "parse.h"
|
#include "parse.h"
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
extern TAILQ_HEAD(, conf_sec) config;
|
extern TAILQ_HEAD(, conf_sec) config;
|
||||||
|
|
||||||
static const struct opt_type opt_type_null = { 0, 0, false, NULL };
|
static const struct opt_type opt_type_null = { 0, 0, False, NULL };
|
||||||
|
|
||||||
static struct opt_type
|
static struct opt_type
|
||||||
string_to_opt(char *s)
|
string_to_opt(char *s)
|
||||||
{
|
{
|
||||||
struct opt_type ret = opt_type_null;
|
struct opt_type ret = opt_type_null;
|
||||||
|
|
||||||
if(!s || !strlen(s))
|
if (!s || !strlen(s))
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret.num = strtol(s, (char**)NULL, 10);
|
ret.num = strtol(s, (char**)NULL, 10);
|
||||||
ret.fnum = strtod(s, NULL);
|
ret.fnum = strtod(s, NULL);
|
||||||
|
|
||||||
ret.boolean = (!strcmp(s, "true")
|
if (!strcmp(s, "true") || !strcmp(s, "True") ||
|
||||||
|| !strcmp(s, "True")
|
!strcmp(s, "TRUE") || !strcmp(s, "1"))
|
||||||
|| !strcmp(s, "TRUE")
|
ret.bool = True;
|
||||||
|| !strcmp(s, "1"));
|
else
|
||||||
|
ret.bool = False;
|
||||||
|
|
||||||
ret.str = s;
|
ret.str = s;
|
||||||
|
|
||||||
@ -58,7 +56,7 @@ print_unused(struct conf_sec *sec)
|
|||||||
struct conf_sec *s;
|
struct conf_sec *s;
|
||||||
struct conf_opt *o;
|
struct conf_opt *o;
|
||||||
|
|
||||||
if(!sec)
|
if (!sec)
|
||||||
{
|
{
|
||||||
TAILQ_FOREACH(s, &config, entry)
|
TAILQ_FOREACH(s, &config, entry)
|
||||||
print_unused(s);
|
print_unused(s);
|
||||||
@ -66,11 +64,12 @@ print_unused(struct conf_sec *sec)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SLIST_FOREACH(o, &sec->optlist, entry)
|
SLIST_FOREACH(o, &sec->optlist, entry)
|
||||||
if(!o->used)
|
if (o->used == False)
|
||||||
warnxl("%s:%d, unused param %s", o->filename, o->line, o->name);
|
warnx("%s:%d, unused param %s",
|
||||||
|
o->filename, o->line, o->name);
|
||||||
|
|
||||||
TAILQ_FOREACH(s, &sec->sub, entry)
|
TAILQ_FOREACH(s, &sec->sub, entry)
|
||||||
if(!TAILQ_EMPTY(&s->sub))
|
if (!TAILQ_EMPTY(&s->sub))
|
||||||
print_unused(s);
|
print_unused(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,32 +80,26 @@ fetch_section(struct conf_sec *s, char *name)
|
|||||||
struct conf_sec *sec;
|
struct conf_sec *sec;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
if(!name)
|
if (!name)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if(!s)
|
if (!s) {
|
||||||
{
|
|
||||||
ret = xcalloc(2, sizeof(struct conf_sec *));
|
ret = xcalloc(2, sizeof(struct conf_sec *));
|
||||||
|
|
||||||
TAILQ_FOREACH(sec, &config, entry)
|
TAILQ_FOREACH(sec, &config, entry)
|
||||||
if(!strcmp(sec->name, name))
|
if (!strcmp(sec->name, name)) {
|
||||||
{
|
|
||||||
ret[0] = sec;
|
ret[0] = sec;
|
||||||
ret[1] = NULL;
|
ret[1] = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
ret = xcalloc(s->nsub+1, sizeof(struct conf_sec *));
|
||||||
ret = xcalloc(s->nsub + 1, sizeof(struct conf_sec *));
|
TAILQ_FOREACH(sec, &s->sub, entry) {
|
||||||
|
if (!strcmp(sec->name, name) && i < s->nsub)
|
||||||
TAILQ_FOREACH(sec, &s->sub, entry)
|
|
||||||
if(!strcmp(sec->name, name) && i < s->nsub)
|
|
||||||
ret[i++] = sec;
|
ret[i++] = sec;
|
||||||
|
}
|
||||||
ret[i] = NULL;
|
ret[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,20 +107,26 @@ struct conf_sec *
|
|||||||
fetch_section_first(struct conf_sec *s, char *name)
|
fetch_section_first(struct conf_sec *s, char *name)
|
||||||
{
|
{
|
||||||
struct conf_sec *sec, *ret = NULL;
|
struct conf_sec *sec, *ret = NULL;
|
||||||
TAILQ_HEAD(cshead, conf_sec) *head =
|
|
||||||
(s
|
|
||||||
? (struct cshead*)&s->sub
|
|
||||||
: (struct cshead*)&config);
|
|
||||||
|
|
||||||
if(!name)
|
if (!name)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
TAILQ_FOREACH(sec, head, entry)
|
if (!s)
|
||||||
if(sec->name && !strcmp(sec->name, name))
|
|
||||||
{
|
{
|
||||||
|
TAILQ_FOREACH(sec, &config, entry)
|
||||||
|
if(sec->name && !strcmp(sec->name, name)) {
|
||||||
ret = sec;
|
ret = sec;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TAILQ_FOREACH(sec, &s->sub, entry)
|
||||||
|
if (sec->name && !strcmp(sec->name, name)) {
|
||||||
|
ret = sec;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -135,11 +134,8 @@ fetch_section_first(struct conf_sec *s, char *name)
|
|||||||
size_t
|
size_t
|
||||||
fetch_section_count(struct conf_sec **s)
|
fetch_section_count(struct conf_sec **s)
|
||||||
{
|
{
|
||||||
size_t ret = 0;
|
size_t ret;
|
||||||
|
for (ret = 0; s[ret]; ret++);
|
||||||
while(s[ret])
|
|
||||||
++ret;
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,25 +146,20 @@ fetch_opt(struct conf_sec *s, char *dfl, char *name)
|
|||||||
struct opt_type *ret;
|
struct opt_type *ret;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
if(!name)
|
if (!name)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
ret = xcalloc(10, sizeof(struct opt_type));
|
ret = xcalloc(10, sizeof(struct opt_type));
|
||||||
|
|
||||||
if(s)
|
if (s) {
|
||||||
{
|
|
||||||
SLIST_FOREACH(o, &s->optlist, entry)
|
SLIST_FOREACH(o, &s->optlist, entry)
|
||||||
if(!strcmp(o->name, name))
|
if (!strcmp(o->name, name)) {
|
||||||
{
|
while (o->val[i]) {
|
||||||
while(o->val[i])
|
o->used = True;
|
||||||
{
|
|
||||||
o->used = true;
|
|
||||||
ret[i] = string_to_opt(o->val[i]);
|
ret[i] = string_to_opt(o->val[i]);
|
||||||
++i;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret[i] = opt_type_null;
|
ret[i] = opt_type_null;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -184,30 +175,22 @@ fetch_opt_first(struct conf_sec *s, char *dfl, char *name)
|
|||||||
{
|
{
|
||||||
struct conf_opt *o;
|
struct conf_opt *o;
|
||||||
|
|
||||||
if(!name)
|
if (!name)
|
||||||
return opt_type_null;
|
return opt_type_null;
|
||||||
else if(s)
|
else if (s)
|
||||||
{
|
|
||||||
SLIST_FOREACH(o, &s->optlist, entry)
|
SLIST_FOREACH(o, &s->optlist, entry)
|
||||||
if(!strcmp(o->name, name))
|
if (!strcmp(o->name, name)) {
|
||||||
{
|
o->used = True;
|
||||||
o->used = true;
|
|
||||||
|
|
||||||
return string_to_opt(o->val[0]);
|
return string_to_opt(o->val[0]);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return string_to_opt(dfl);
|
return string_to_opt(dfl);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
fetch_opt_count(struct opt_type *o)
|
fetch_opt_count(struct opt_type *o)
|
||||||
{
|
{
|
||||||
size_t ret = 0;
|
size_t ret;
|
||||||
|
for(ret = 0; o[ret].str; ret++);
|
||||||
while(o[ret].str)
|
|
||||||
++ret;
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
374
src/screen.c
374
src/screen.c
@ -1,166 +1,284 @@
|
|||||||
/*
|
/*
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
* screen.c
|
||||||
* For license, see COPYING.
|
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
|
||||||
*/
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of the nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "wmfs.h"
|
||||||
|
|
||||||
|
/** Count the screens
|
||||||
|
*\return the number of screen
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
screen_count(void)
|
||||||
|
{
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
n = ScreenCount(dpy);
|
||||||
|
|
||||||
#ifdef HAVE_XINERAMA
|
#ifdef HAVE_XINERAMA
|
||||||
#include <X11/extensions/Xinerama.h>
|
if(XineramaIsActive(dpy))
|
||||||
|
XineramaQueryScreens(dpy, &n);
|
||||||
#endif /* HAVE_XINERAMA */
|
#endif /* HAVE_XINERAMA */
|
||||||
|
|
||||||
#include "screen.h"
|
/* Set _WMFS_SCREEN_COUNT */
|
||||||
#include "util.h"
|
if(net_atom)
|
||||||
#include "tag.h"
|
XChangeProperty(dpy, ROOT, net_atom[wmfs_screen_count], XA_CARDINAL, 32,
|
||||||
#include "infobar.h"
|
PropModeReplace, (uchar*)&n, 1);
|
||||||
#include "client.h"
|
|
||||||
|
|
||||||
static struct screen*
|
return n;
|
||||||
screen_new(struct geo *g, int id)
|
|
||||||
{
|
|
||||||
struct screen *s = (struct screen*)xcalloc(1, sizeof(struct screen));
|
|
||||||
|
|
||||||
s->geo = s->ugeo = *g;
|
|
||||||
s->seltag = NULL;
|
|
||||||
s->id = id;
|
|
||||||
s->flags = 0;
|
|
||||||
|
|
||||||
TAILQ_INIT(&s->tags);
|
|
||||||
SLIST_INIT(&s->infobars);
|
|
||||||
|
|
||||||
SLIST_INSERT_HEAD(&W->h.screen, s, next);
|
|
||||||
|
|
||||||
/* Set as selected screen */
|
|
||||||
W->screen = s;
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
/** Get screen geometry by number
|
||||||
screen_init(void)
|
*\param s Screen number
|
||||||
|
*\return XRectangle struct
|
||||||
|
*/
|
||||||
|
XRectangle
|
||||||
|
screen_get_geo(int s)
|
||||||
{
|
{
|
||||||
struct geo g;
|
int barpos = tags[selscreen][seltag[selscreen]].barpos;
|
||||||
|
XRectangle geo;
|
||||||
|
|
||||||
SLIST_INIT(&W->h.screen);
|
geo.x = BORDH;
|
||||||
|
if(barpos == IB_Hide || barpos == IB_Bottom)
|
||||||
|
geo.y = TBARH;
|
||||||
|
else
|
||||||
|
geo.y = INFOBARH + TBARH;
|
||||||
|
geo.height = MAXH - INFOBARH - TBARH;
|
||||||
|
geo.width = MAXW;
|
||||||
|
|
||||||
#ifdef HAVE_XINERAMA
|
#ifdef HAVE_XINERAMA
|
||||||
|
if(XineramaIsActive(dpy))
|
||||||
|
{
|
||||||
XineramaScreenInfo *xsi;
|
XineramaScreenInfo *xsi;
|
||||||
int i, n = 0;
|
int n = 0;
|
||||||
|
|
||||||
if(XineramaIsActive(W->dpy))
|
xsi = XineramaQueryScreens(dpy, &n);
|
||||||
{
|
|
||||||
xsi = XineramaQueryScreens(W->dpy, &n);
|
|
||||||
|
|
||||||
for(i = 0; i < n; ++i)
|
geo.x = xsi[s].x_org + BORDH;
|
||||||
{
|
if(barpos == IB_Hide || barpos == IB_Bottom)
|
||||||
g.x = xsi[i].x_org;
|
geo.y = TBARH;
|
||||||
g.y = xsi[i].y_org;
|
else
|
||||||
g.w = xsi[i].width;
|
geo.y = xsi[s].y_org + INFOBARH + TBARH;
|
||||||
g.h = xsi[i].height;
|
geo.height = xsi[s].height - INFOBARH - TBARH;
|
||||||
|
geo.width = xsi[s].width;
|
||||||
screen_new(&g, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
W->nscreen = n;
|
|
||||||
|
|
||||||
XFree(xsi);
|
XFree(xsi);
|
||||||
}
|
}
|
||||||
else
|
#else
|
||||||
|
(void)s;
|
||||||
#endif /* HAVE_XINERAMA */
|
#endif /* HAVE_XINERAMA */
|
||||||
{
|
|
||||||
g.x = g.y = 0;
|
|
||||||
g.w = DisplayWidth(W->dpy, W->xscreen);
|
|
||||||
g.h = DisplayHeight(W->dpy, W->xscreen);
|
|
||||||
|
|
||||||
screen_new(&g, 0);
|
return geo;
|
||||||
W->nscreen = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/** Get the current screen number with
|
||||||
* Update selected screen with mouse location
|
* coordinated
|
||||||
*/
|
*\param geo Geometry for get the screen number
|
||||||
struct screen*
|
*\return The screen number
|
||||||
screen_update_sel(void)
|
*/
|
||||||
|
int
|
||||||
|
screen_get_with_geo(int x, int y)
|
||||||
{
|
{
|
||||||
|
int i, r = 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)
|
||||||
|
r = i;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set the selected screen
|
||||||
|
*\param screen Number of the wanted selected screen
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
screen_set_sel(int screen)
|
||||||
|
{
|
||||||
|
if(screen < 0 || screen > screen_count() - 1)
|
||||||
|
screen = 0;
|
||||||
|
|
||||||
|
if(selscreen != screen)
|
||||||
|
prevselscreen = selscreen;
|
||||||
|
|
||||||
|
client_focus(NULL);
|
||||||
|
XWarpPointer(dpy, None, ROOT, 0, 0, 0, 0,
|
||||||
|
sgeo[screen].x + sgeo[screen].width / 2,
|
||||||
|
sgeo[screen].y + sgeo[screen].height / 2);
|
||||||
|
|
||||||
|
selscreen = screen;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get and set the selected screen
|
||||||
|
*\return The number of the selected screen
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
screen_get_sel(void)
|
||||||
|
{
|
||||||
|
int os = selscreen;
|
||||||
|
|
||||||
|
selscreen = 0;
|
||||||
|
|
||||||
#ifdef HAVE_XINERAMA
|
#ifdef HAVE_XINERAMA
|
||||||
if(XineramaIsActive(W->dpy))
|
if(XineramaIsActive(dpy))
|
||||||
return (W->screen = screen_gb_mouse());
|
{
|
||||||
|
/* Unused variables (except x/y) */
|
||||||
|
Window w;
|
||||||
|
int d, x, y;
|
||||||
|
|
||||||
|
XQueryPointer(dpy, ROOT, &w, &w, &x, &y, &d, &d, (uint *)&d);
|
||||||
|
|
||||||
|
selscreen = screen_get_with_geo(x, y);
|
||||||
|
}
|
||||||
#endif /* HAVE_XINERAMA */
|
#endif /* HAVE_XINERAMA */
|
||||||
|
|
||||||
return W->screen;
|
/* Set _WMFS_CURRENT_SCREEN */
|
||||||
}
|
XChangeProperty(dpy, ROOT, net_atom[wmfs_current_screen], XA_CARDINAL, 32,
|
||||||
|
PropModeReplace, (uchar*)&selscreen, 1);
|
||||||
static void
|
|
||||||
screen_select(struct screen *s)
|
if(os != selscreen && os != prevselscreen)
|
||||||
{
|
prevselscreen = os;
|
||||||
XWarpPointer(W->dpy, None, W->root, 0, 0, 0, 0,
|
|
||||||
s->ugeo.x + (s->ugeo.w >> 1),
|
return selscreen;
|
||||||
s->ugeo.y + (s->ugeo.h >> 1));
|
|
||||||
|
|
||||||
W->screen = s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Init screen geo
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
uicb_screen_next(Uicb cmd)
|
screen_init_geo(void)
|
||||||
{
|
{
|
||||||
struct screen *s = SLIST_NEXT(W->screen, next);
|
int i;
|
||||||
(void)cmd;
|
int s = screen_count();
|
||||||
|
|
||||||
if(!s)
|
sgeo = xcalloc(s, sizeof(XRectangle));
|
||||||
s = SLIST_FIRST(&W->h.screen);
|
spgeo = xcalloc(s, sizeof(XRectangle));
|
||||||
|
|
||||||
screen_select(s);
|
for(i = 0; i < s; ++i)
|
||||||
}
|
sgeo[i] = screen_get_geo(i);
|
||||||
|
|
||||||
void
|
spgeo[0].x = 0;
|
||||||
uicb_screen_prev(Uicb cmd)
|
spgeo[0].y = 0;
|
||||||
{
|
spgeo[0].width = MAXW;
|
||||||
struct screen *s = SLIST_FIRST(&W->h.screen);
|
spgeo[0].height = MAXH;
|
||||||
(void)cmd;
|
|
||||||
|
|
||||||
while(SLIST_NEXT(s, next) && SLIST_NEXT(s, next) != s)
|
#ifdef HAVE_XINERAMA
|
||||||
s = SLIST_NEXT(s, next);
|
XineramaScreenInfo *xsi;
|
||||||
|
int n;
|
||||||
|
|
||||||
screen_select(s);
|
if(XineramaIsActive(dpy))
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
uicb_screen_move_client_next(Uicb cmd)
|
|
||||||
{
|
|
||||||
struct screen *s = SLIST_NEXT(W->screen, next);
|
|
||||||
(void)cmd;
|
|
||||||
|
|
||||||
if(!s)
|
|
||||||
s = SLIST_FIRST(&W->h.screen);
|
|
||||||
|
|
||||||
if(W->client)
|
|
||||||
tag_client(s->seltag, W->client);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
uicb_screen_move_client_prev(Uicb cmd)
|
|
||||||
{
|
|
||||||
struct screen *s = SLIST_FIRST(&W->h.screen);
|
|
||||||
(void)cmd;
|
|
||||||
|
|
||||||
while(SLIST_NEXT(s, next) && SLIST_NEXT(s, next) != s)
|
|
||||||
s = SLIST_NEXT(s, next);
|
|
||||||
|
|
||||||
if(W->client)
|
|
||||||
tag_client(s->seltag, W->client);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
screen_free(void)
|
|
||||||
{
|
|
||||||
struct screen *s;
|
|
||||||
|
|
||||||
while(!SLIST_EMPTY(&W->h.screen))
|
|
||||||
{
|
{
|
||||||
s = SLIST_FIRST(&W->h.screen);
|
xsi = XineramaQueryScreens(dpy, &n);
|
||||||
SLIST_REMOVE_HEAD(&W->h.screen, next);
|
for(i = 0; i < n; ++i)
|
||||||
|
{
|
||||||
infobar_free(s);
|
spgeo[i].x = xsi[i].x_org;
|
||||||
tag_free(s);
|
spgeo[i].y = xsi[i].y_org;
|
||||||
free(s);
|
spgeo[i].width = xsi[i].width;
|
||||||
|
spgeo[i].height = xsi[i].height;
|
||||||
}
|
}
|
||||||
|
XFree(xsi);
|
||||||
|
}
|
||||||
|
#endif /* HAVE_XINERAMA */
|
||||||
|
|
||||||
|
#ifdef HAVE_XRANDR
|
||||||
|
/* Init xrandr stuff */
|
||||||
|
int d;
|
||||||
|
|
||||||
|
XRRSelectInput(dpy, ROOT, 1);
|
||||||
|
XRRQueryExtension(dpy, &xrandr_event, &d);
|
||||||
|
#endif /* HAVE_XRANDR */
|
||||||
|
|
||||||
|
ewmh_set_desktop_geometry();
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Uicb: screen select
|
||||||
|
* \param cmd Screen uicb_t type
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
uicb_screen_select(uicb_t cmd)
|
||||||
|
{
|
||||||
|
screen_set_sel(atoi(cmd));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Uicb: screen next
|
||||||
|
* \param cmd Screen uicb_t type
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
uicb_screen_next(uicb_t cmd)
|
||||||
|
{
|
||||||
|
(void)cmd;
|
||||||
|
screen_get_sel();
|
||||||
|
|
||||||
|
if(screen_count() > 1)
|
||||||
|
{
|
||||||
|
selscreen = (selscreen + 1 > screen_count() - 1) ? 0 : selscreen + 1;
|
||||||
|
|
||||||
|
screen_set_sel(selscreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Uicb: screen prev
|
||||||
|
* \param cmd Screen uicb_t type
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
uicb_screen_prev(uicb_t cmd)
|
||||||
|
{
|
||||||
|
(void)cmd;
|
||||||
|
screen_get_sel();
|
||||||
|
|
||||||
|
selscreen = (selscreen - 1 < 0) ? screen_count() - 1 : selscreen - 1;
|
||||||
|
|
||||||
|
screen_set_sel(selscreen);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Uicb: screen prev sel
|
||||||
|
* \param cmd uicb_t type unused
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
uicb_screen_prev_sel(uicb_t cmd)
|
||||||
|
{
|
||||||
|
(void)cmd;
|
||||||
|
screen_get_sel();
|
||||||
|
|
||||||
|
screen_set_sel(prevselscreen);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
56
src/screen.h
56
src/screen.h
@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
|
||||||
* For license, see COPYING.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SCREEN_H
|
|
||||||
#define SCREEN_H
|
|
||||||
|
|
||||||
#include "wmfs.h"
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
static inline struct screen*
|
|
||||||
screen_gb_id(int id)
|
|
||||||
{
|
|
||||||
struct screen *s;
|
|
||||||
|
|
||||||
SLIST_FOREACH(s, &W->h.screen, next)
|
|
||||||
if(s->id == id)
|
|
||||||
return s;
|
|
||||||
|
|
||||||
return SLIST_FIRST(&W->h.screen);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct screen*
|
|
||||||
screen_gb_geo(int x, int y)
|
|
||||||
{
|
|
||||||
struct screen *s;
|
|
||||||
|
|
||||||
SLIST_FOREACH(s, &W->h.screen, next)
|
|
||||||
if(INAREA(x, y, s->geo))
|
|
||||||
return s;
|
|
||||||
|
|
||||||
return SLIST_FIRST(&W->h.screen);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct screen*
|
|
||||||
screen_gb_mouse(void)
|
|
||||||
{
|
|
||||||
Window w;
|
|
||||||
int d, x, y;
|
|
||||||
|
|
||||||
XQueryPointer(W->dpy, W->root, &w, &w, &x, &y, &d, &d, (unsigned int *)&d);
|
|
||||||
|
|
||||||
return screen_gb_geo(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void screen_init(void);
|
|
||||||
struct screen* screen_update_sel(void);
|
|
||||||
void screen_free(void);
|
|
||||||
void uicb_screen_next(Uicb cmd);
|
|
||||||
void uicb_screen_prev(Uicb cmd);
|
|
||||||
void uicb_screen_move_client_next(Uicb cmd);
|
|
||||||
void uicb_screen_move_client_prev(Uicb cmd);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* SCREEN_H */
|
|
||||||
801
src/status.c
801
src/status.c
@ -1,653 +1,242 @@
|
|||||||
/*
|
/*
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
* status.c
|
||||||
* For license, see COPYING.
|
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of the nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "wmfs.h"
|
||||||
|
|
||||||
|
/** Check rectangles blocks in str and return properties
|
||||||
|
* --> \b[x;y;width;height;#color]\
|
||||||
|
*\param r StatusRec pointer, rectangles properties
|
||||||
|
*\param str String
|
||||||
|
*\return n Length of r
|
||||||
*/
|
*/
|
||||||
|
static int
|
||||||
#include "status.h"
|
statustext_rectangle(StatusRec *r, char *str)
|
||||||
#include "barwin.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "infobar.h"
|
|
||||||
#include "util.h"
|
|
||||||
#include "draw.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
struct status_seq*
|
|
||||||
status_new_seq(char type, int narg, int minarg, char *args[], int *shift)
|
|
||||||
{
|
{
|
||||||
struct status_seq *sq = xcalloc(1, sizeof(struct status_seq));
|
char as;
|
||||||
|
int n, i, j, k;
|
||||||
|
|
||||||
SLIST_INIT(&sq->mousebinds);
|
for(i = j = n = 0; i < (int)strlen(str); ++i, ++j)
|
||||||
sq->type = type;
|
if(sscanf(&str[i], "\\b[%d;%d;%d;%d;#%x]%c", &r[n].x, &r[n].y, &r[n].w, &r[n].h, &r[n].color, &as) == 6
|
||||||
*shift = 0;
|
&& as == '\\')
|
||||||
|
for(++n, ++i, --j; str[i] != as || str[i - 1] != ']'; ++i);
|
||||||
|
else if(j != i)
|
||||||
|
str[j] = str[i];
|
||||||
|
|
||||||
if(narg == minarg || !strcmp(args[0], "right") || !strcmp(args[0], "left"))
|
for(k = j; k < i; str[k++] = 0);
|
||||||
sq->align = str_to_position(args[0]);
|
|
||||||
else
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check graphs blocks in str and return properties
|
||||||
|
* --> \g[x;y;width;height;#color;data]\
|
||||||
|
*\param g StatusGraph pointer, graphs properties
|
||||||
|
*\param str String
|
||||||
|
*\return n Length of g
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
statustext_graph(StatusGraph *g, char *str)
|
||||||
|
{
|
||||||
|
char as, c, *p;
|
||||||
|
int n, i, j, k, m, w;
|
||||||
|
|
||||||
|
for(i = j = n = 0; i < (int)strlen(str); ++i, ++j)
|
||||||
|
if(sscanf(&str[i], "\\g[%d;%d;%d;%d;#%x;%512[^]]]%c",
|
||||||
|
&g[n].x, &g[n].y, &g[n].w, &g[n].h, &g[n].color, g[n].data, &as) == 7
|
||||||
|
&& as == '\\')
|
||||||
{
|
{
|
||||||
sq->align = NoAlign;
|
/* data is a list of numbers separated by ';' */
|
||||||
sq->geo.x = ATOI(args[0]);
|
w = g[n].w;
|
||||||
sq->geo.y = ATOI(args[1]);
|
p = strtok(g[n].data, ";");
|
||||||
*shift = 1;
|
m = 0;
|
||||||
|
|
||||||
|
while(p && m < w)
|
||||||
|
{
|
||||||
|
c = atoi(p);
|
||||||
|
/* height limits */
|
||||||
|
if(c < 0)
|
||||||
|
c = 0;
|
||||||
|
if(c > (char)g[n].h)
|
||||||
|
c = g[n].h;
|
||||||
|
g[n].data[m] = c;
|
||||||
|
p = strtok(NULL, ";");
|
||||||
|
++m;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sq;
|
/* width limits */
|
||||||
|
for(; m < w; ++m)
|
||||||
|
g[n].data[m] = 0;
|
||||||
|
/* data is a array[w] of bytes now */
|
||||||
|
|
||||||
|
for(++n, ++i, --j; str[i] != as || str[i - 1] != ']'; ++i);
|
||||||
|
}
|
||||||
|
else if(j != i)
|
||||||
|
str[j] = str[i];
|
||||||
|
|
||||||
|
for(k = j; k < i; str[k++] = 0);
|
||||||
|
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct status_ctx
|
/** Check text blocks in str and return properties
|
||||||
status_new_ctx(struct barwin *b, struct theme *t)
|
* --> \s[x;y;#color;text]\
|
||||||
|
*\param s StatusText pointer, text properties
|
||||||
|
*\param str String
|
||||||
|
*\return n Length of s
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
statustext_text(StatusText *s, char *str)
|
||||||
{
|
{
|
||||||
struct status_ctx ctx = { .barwin = b, .theme = t };
|
char as;
|
||||||
|
int n, i, j, k;
|
||||||
|
|
||||||
SLIST_INIT(&ctx.statushead);
|
for(i = j = n = 0; i < (int)strlen(str); ++i, ++j)
|
||||||
SLIST_INIT(&ctx.gcache);
|
if(sscanf(&str[i], "\\s[%d;%d;%7[^;];%512[^]]]%c", &s[n].x, &s[n].y, s[n].color, s[n].text, &as) == 5
|
||||||
|
&& as == '\\')
|
||||||
|
for(++n, ++i, --j; str[i] != as || str[i - 1] != ']'; ++i);
|
||||||
|
else if(j != i)
|
||||||
|
str[j] = str[i];
|
||||||
|
|
||||||
return ctx;
|
for(k = j; k < i; str[k++] = 0);
|
||||||
|
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Draw normal text and colored normal text
|
||||||
|
* --> \#color\ text in color
|
||||||
|
*\param sc Screen
|
||||||
|
*\param str String
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
status_gcache_free(struct status_ctx *ctx)
|
statustext_normal(int sc, char *str)
|
||||||
{
|
{
|
||||||
struct status_gcache *gc;
|
char strwc[MAXSTATUS] = { 0 };
|
||||||
|
char buf[MAXSTATUS] = { 0 };
|
||||||
|
char col[8] = { 0 };
|
||||||
|
int n, i, j, k, sw = 0;
|
||||||
|
|
||||||
while(!SLIST_EMPTY(&ctx->gcache))
|
if(sc == conf.systray.screen)
|
||||||
|
sw = systray_get_width();
|
||||||
|
|
||||||
|
for(i = j = n = 0; i < (int)strlen(str); ++i, ++j)
|
||||||
|
if(str[i] == '\\' && str[i + 1] == '#' && str[i + 8] == '\\')
|
||||||
{
|
{
|
||||||
gc = SLIST_FIRST(&ctx->gcache);
|
++n;
|
||||||
SLIST_REMOVE_HEAD(&ctx->gcache, next);
|
i += 8;
|
||||||
free(gc->datas);
|
--j;
|
||||||
free(gc->name);
|
|
||||||
free(gc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
status_free_ctx(struct status_ctx *ctx)
|
|
||||||
{
|
|
||||||
free(ctx->status);
|
|
||||||
status_flush_list(ctx);
|
|
||||||
status_gcache_free(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
status_graph_draw(struct status_ctx *ctx, struct status_seq *sq, struct status_gcache *gc)
|
|
||||||
{
|
|
||||||
int max = 0;
|
|
||||||
int i, j, y;
|
|
||||||
float c;
|
|
||||||
int ys = sq->geo.y + sq->geo.h - 1;
|
|
||||||
|
|
||||||
/* If invalid maximum, we have to compute it ourselves */
|
|
||||||
if(sq->data[2] <= 0)
|
|
||||||
{
|
|
||||||
for(i = sq->geo.x + sq->geo.w - 1, j = gc->ndata - 1;
|
|
||||||
j >= 0 && i >= sq->geo.x;
|
|
||||||
--j, --i)
|
|
||||||
{
|
|
||||||
if(gc->datas[j] > max)
|
|
||||||
max = gc->datas[j];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
max = sq->data[2];
|
strwc[j] = str[i];
|
||||||
|
|
||||||
XSetForeground(W->dpy, W->gc, sq->color2);
|
/* Draw normal text without any blocks */
|
||||||
|
draw_text(infobar[sc].bar->dr, (sgeo[sc].width - SHADH) - (textw(strwc) + sw),
|
||||||
|
FHINFOBAR, infobar[sc].bar->fg, strwc);
|
||||||
|
|
||||||
for(i = sq->geo.x + sq->geo.w - 1, j = gc->ndata - 1;
|
if(n)
|
||||||
j >= 0 && i >= sq->geo.x;
|
|
||||||
--j, --i)
|
|
||||||
{
|
{
|
||||||
/* You divided by zero didn't you? */
|
strncpy(buf, strwc, sizeof(buf));
|
||||||
if(gc->datas[j])
|
|
||||||
|
for(i = k = 0; i < (int)strlen(str); ++i, ++k)
|
||||||
|
if(str[i] == '\\' && str[i + 1] == '#' && str[i + 8] == '\\')
|
||||||
{
|
{
|
||||||
c = (float)max / (float)gc->datas[j];
|
/* Store current color in col[] */
|
||||||
y = ys - (sq->geo.h / (c > 1 ? c : 1)) + 1;
|
for(j = 0, ++i; str[i] != '\\'; col[j++] = str[i++]);
|
||||||
draw_line(ctx->barwin->dr, i, y, i, ys);
|
|
||||||
|
/* Draw a rectangle with the bar color to draw the text properly */
|
||||||
|
draw_rectangle(infobar[sc].bar->dr, (sgeo[sc].width - SHADH) - (textw(&buf[k]) + sw),
|
||||||
|
0, INFOBARH - (sgeo[sc].width - SHADH) - textw(&buf[k]),
|
||||||
|
INFOBARH, conf.colors.bar);
|
||||||
|
|
||||||
|
/* Draw text with its color */
|
||||||
|
draw_text(infobar[sc].bar->dr, (sgeo[sc].width - SHADH) - (textw(&buf[k]) + sw),
|
||||||
|
FHINFOBAR, col, &buf[k]);
|
||||||
|
|
||||||
|
strncpy(buf, strwc, sizeof(buf));
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
status_graph_process(struct status_ctx *ctx, struct status_seq *sq, char *name)
|
|
||||||
{
|
|
||||||
int j;
|
|
||||||
struct status_gcache *gc;
|
|
||||||
|
|
||||||
/* Graph already exist and have a cache */
|
|
||||||
SLIST_FOREACH(gc, &ctx->gcache, next)
|
|
||||||
if(!strcmp(name, gc->name))
|
|
||||||
{
|
|
||||||
/* shift buffer to remove unused old value */
|
|
||||||
if(gc->ndata > (sq->geo.w << 1))
|
|
||||||
for(gc->ndata /= 2, j = 0;
|
|
||||||
j < gc->ndata;
|
|
||||||
gc->datas[j] = gc->datas[j + gc->ndata], ++j);
|
|
||||||
|
|
||||||
gc->datas[gc->ndata++] = sq->data[1];
|
|
||||||
status_graph_draw(ctx, sq, gc);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if(sq->data[1] > sq->data[2])
|
|
||||||
sq->data[1] = sq->data[2];
|
|
||||||
|
|
||||||
/* No? Make a cache for it */
|
|
||||||
gc = xcalloc(1, sizeof(struct status_gcache));
|
|
||||||
gc->name = xstrdup(name);
|
|
||||||
gc->ndata = 1;
|
|
||||||
gc->datas = xcalloc(sq->geo.w << 2, sizeof(int));
|
|
||||||
gc->datas[0] = sq->data[1];
|
|
||||||
|
|
||||||
SLIST_INSERT_HEAD(&ctx->gcache, gc, next);
|
|
||||||
|
|
||||||
status_graph_draw(ctx, sq, gc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse mousebind sequence next normal sequence: \<seq>[](button;func;cmd) */
|
/** Handle statustext and draw all things in infobar of specified screen
|
||||||
static char*
|
*\param sc Screen number
|
||||||
status_parse_mouse(struct status_seq *sq, char *str)
|
*\param str String
|
||||||
{
|
|
||||||
struct mousebind *m;
|
|
||||||
char *end, *arg[3] = { NULL };
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if(*str != '(' || !(end = strchr(str, ')')))
|
|
||||||
return str;
|
|
||||||
|
|
||||||
i = parse_args(++str, ';', ')', 3, arg);
|
|
||||||
|
|
||||||
m = xcalloc(1, sizeof(struct mousebind));
|
|
||||||
|
|
||||||
m->use_area = true;
|
|
||||||
m->button = ATOI(arg[0]);
|
|
||||||
m->func = uicb_name_func(arg[1]);
|
|
||||||
m->cmd = (i > 1 ? xstrdup(arg[2]) : NULL);
|
|
||||||
|
|
||||||
SLIST_INSERT_HEAD(&sq->mousebinds, m, snext);
|
|
||||||
|
|
||||||
return end + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define STATUS_CHECK_ARGS(i, n1, n2, str, end) \
|
|
||||||
if(i != n1 && i != n2) \
|
|
||||||
{ \
|
|
||||||
str = end + 2; \
|
|
||||||
continue; \
|
|
||||||
}
|
|
||||||
void
|
|
||||||
status_parse(struct status_ctx *ctx)
|
|
||||||
{
|
|
||||||
struct status_seq *sq, *prev = NULL;
|
|
||||||
int i, tmp, shift = 0;
|
|
||||||
char *dstr = xstrdup(ctx->status), *sauv = dstr;
|
|
||||||
char type, *p, *pp, *end, *arg[10] = { NULL };
|
|
||||||
|
|
||||||
for(; *dstr; ++dstr)
|
|
||||||
{
|
|
||||||
/* Check if this is a sequence */
|
|
||||||
if(*dstr != '^' && *dstr != '\\')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
p = ++dstr;
|
|
||||||
|
|
||||||
/* Search for correct end of sequence (] without \ behind) */
|
|
||||||
if((end = strchr(p, ']')))
|
|
||||||
while(*(end - 1) == '\\')
|
|
||||||
end = strchr(end + 1, ']');
|
|
||||||
|
|
||||||
if(!(strchr("sRpPig", *p)) || !end)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Then parse & list it */
|
|
||||||
switch((type = *p))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Text sequence: \s[left/right;#color;text] OR \s[x;y;#color;text]
|
|
||||||
*/
|
*/
|
||||||
case 's':
|
|
||||||
i = parse_args(p + 2, ';', ']', 4, arg);
|
|
||||||
STATUS_CHECK_ARGS(i, 2, 3, dstr, end);
|
|
||||||
sq = status_new_seq(type, i, 2, arg, &shift);
|
|
||||||
|
|
||||||
sq->color = color_atoh(arg[1 + shift]);
|
|
||||||
sq->str = xstrdup(arg[2 + shift]);
|
|
||||||
|
|
||||||
/* Remove \ from string */
|
|
||||||
for(pp = sq->str; (pp = strchr(sq->str, '\\'));)
|
|
||||||
memmove(pp, pp + 1, strlen(pp));
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Rectangle sequence: \R[left/right;w;h;#color] OR \R[x;y;w;h;#color]
|
|
||||||
*/
|
|
||||||
case 'R':
|
|
||||||
i = parse_args(p + 2, ';', ']', 5, arg);
|
|
||||||
STATUS_CHECK_ARGS(i, 3, 4, dstr, end);
|
|
||||||
sq = status_new_seq(type, i, 3, arg, &shift);
|
|
||||||
|
|
||||||
sq->geo.w = ATOI(arg[1 + shift]);
|
|
||||||
sq->geo.h = ATOI(arg[2 + shift]);
|
|
||||||
sq->color = color_atoh(arg[3 + shift]);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Progress bar sequence: \p[left/right;w;h;bord;val;valmax;bg;fg] OR x;y
|
|
||||||
* Position bar sequence: \P[left/right;w;h;tickbord;val;valmax;bg;fg] OR x;y
|
|
||||||
*/
|
|
||||||
case 'p':
|
|
||||||
case 'P':
|
|
||||||
i = parse_args(p + 2, ';', ']', 9, arg);
|
|
||||||
STATUS_CHECK_ARGS(i, 7, 8, dstr, end);
|
|
||||||
sq = status_new_seq(type, i, 7, arg, &shift);
|
|
||||||
|
|
||||||
sq->geo.w = ATOI(arg[1 + shift]);
|
|
||||||
sq->geo.h = ATOI(arg[2 + shift]);
|
|
||||||
|
|
||||||
sq->data[0] = ATOI(arg[3 + shift]); /* Border */
|
|
||||||
sq->data[1] = ((tmp = ATOI(arg[4 + shift])) ? tmp : 1); /* Value */
|
|
||||||
sq->data[2] = ATOI(arg[5 + shift]); /* Value Max */
|
|
||||||
|
|
||||||
sq->color = color_atoh(arg[6 + shift]);
|
|
||||||
sq->color2 = color_atoh(arg[7 + shift]);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Graph sequence: \g[left/right;w;h;val;valmax;bg;fg;name] OR x;y
|
|
||||||
*/
|
|
||||||
case 'g':
|
|
||||||
i = parse_args(p + 2, ';', ']', 9, arg);
|
|
||||||
STATUS_CHECK_ARGS(i, 7, 8, dstr, end);
|
|
||||||
sq = status_new_seq(type, i, 7, arg, &shift);
|
|
||||||
|
|
||||||
sq->geo.w = ATOI(arg[1 + shift]);
|
|
||||||
sq->geo.h = ATOI(arg[2 + shift]);
|
|
||||||
|
|
||||||
sq->data[1] = ATOI(arg[3 + shift]); /* Value */
|
|
||||||
sq->data[2] = ATOI(arg[4 + shift]); /* Value Max */
|
|
||||||
|
|
||||||
sq->color = color_atoh(arg[5 + shift]);
|
|
||||||
sq->color2 = color_atoh(arg[6 + shift]);
|
|
||||||
|
|
||||||
sq->str = xstrdup(arg[7 + shift]);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Image sequence: \i[left/right;w;h;/path/img] OR \i[x;y;w;h;/path/img]
|
|
||||||
*/
|
|
||||||
#ifdef HAVE_IMLIB2
|
|
||||||
case 'i':
|
|
||||||
i = parse_args(p + 2, ';', ']', 5, arg);
|
|
||||||
STATUS_CHECK_ARGS(i, 3, 4, dstr, end);
|
|
||||||
sq = status_new_seq(type, i, 3, arg, &shift);
|
|
||||||
|
|
||||||
sq->geo.w = ATOI(arg[1 + shift]);
|
|
||||||
sq->geo.h = ATOI(arg[2 + shift]);
|
|
||||||
sq->str = xstrdup(arg[3 + shift]);
|
|
||||||
|
|
||||||
break;
|
|
||||||
#endif /* HAVE_IMLIB2 */
|
|
||||||
}
|
|
||||||
|
|
||||||
if(sq->align == Right)
|
|
||||||
SLIST_INSERT_HEAD(&ctx->statushead, sq, next);
|
|
||||||
else
|
|
||||||
SLIST_INSERT_TAIL(&ctx->statushead, sq, next, prev);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Optional mousebind sequence(s) \<seq>[](button;func;cmd)
|
|
||||||
* Parse it while there is a mousebind sequence.
|
|
||||||
*/
|
|
||||||
dstr = end + 1;
|
|
||||||
|
|
||||||
do
|
|
||||||
dstr = status_parse_mouse(sq, dstr);
|
|
||||||
while(*dstr == '(');
|
|
||||||
|
|
||||||
--dstr;
|
|
||||||
|
|
||||||
prev = sq;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(sauv);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define STATUS_ALIGN(align) \
|
|
||||||
if(align == Left) \
|
|
||||||
{ \
|
|
||||||
sq->geo.x = left; \
|
|
||||||
left += sq->geo.w; \
|
|
||||||
} \
|
|
||||||
else if(align == Right) \
|
|
||||||
{ \
|
|
||||||
sq->geo.x = ctx->barwin->geo.w - right - sq->geo.w; \
|
|
||||||
right += sq->geo.w; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define STORE_MOUSEBIND() \
|
|
||||||
if(!SLIST_EMPTY(&sq->mousebinds)) \
|
|
||||||
SLIST_FOREACH(m, &sq->mousebinds, snext) \
|
|
||||||
m->area = sq->geo;
|
|
||||||
|
|
||||||
#define NOALIGN_Y() \
|
|
||||||
if(sq->align != NoAlign) \
|
|
||||||
sq->geo.y = (ctx->barwin->geo.h >> 1) - (sq->geo.h >> 1);
|
|
||||||
static void
|
|
||||||
status_apply_list(struct status_ctx *ctx)
|
|
||||||
{
|
|
||||||
struct status_seq *sq;
|
|
||||||
struct mousebind *m;
|
|
||||||
struct geo g;
|
|
||||||
int left = 0, right = 0, w, h;
|
|
||||||
|
|
||||||
SLIST_FOREACH(sq, &ctx->statushead, next)
|
|
||||||
{
|
|
||||||
switch(sq->type)
|
|
||||||
{
|
|
||||||
/* Text */
|
|
||||||
case 's':
|
|
||||||
sq->geo.w = draw_textw(ctx->theme, sq->str);
|
|
||||||
sq->geo.h = ctx->theme->font.height;
|
|
||||||
|
|
||||||
if(sq->align != NoAlign)
|
|
||||||
sq->geo.y = TEXTY(ctx->theme, ctx->barwin->geo.h);
|
|
||||||
|
|
||||||
STATUS_ALIGN(sq->align);
|
|
||||||
|
|
||||||
draw_text(ctx->barwin->dr, ctx->theme, sq->geo.x, sq->geo.y, sq->color, sq->str);
|
|
||||||
|
|
||||||
if(!SLIST_EMPTY(&sq->mousebinds))
|
|
||||||
SLIST_FOREACH(m, &sq->mousebinds, snext)
|
|
||||||
{
|
|
||||||
m->area = sq->geo;
|
|
||||||
m->area.y -= sq->geo.h;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Rectangle */
|
|
||||||
case 'R':
|
|
||||||
NOALIGN_Y();
|
|
||||||
STATUS_ALIGN(sq->align);
|
|
||||||
|
|
||||||
draw_rect(ctx->barwin->dr, &sq->geo, sq->color);
|
|
||||||
|
|
||||||
STORE_MOUSEBIND();
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Progress */
|
|
||||||
case 'p':
|
|
||||||
NOALIGN_Y();
|
|
||||||
STATUS_ALIGN(sq->align);
|
|
||||||
|
|
||||||
draw_rect(ctx->barwin->dr, &sq->geo, sq->color);
|
|
||||||
|
|
||||||
/* Progress bar geo */
|
|
||||||
g.x = sq->geo.x + sq->data[0];
|
|
||||||
g.y = sq->geo.y + sq->data[0];
|
|
||||||
g.w = sq->geo.w - sq->data[0] - sq->data[0];
|
|
||||||
g.h = sq->geo.h - sq->data[0] - sq->data[0];
|
|
||||||
|
|
||||||
if(sq->data[1] > sq->data[2])
|
|
||||||
sq->data[1] = sq->data[2];
|
|
||||||
|
|
||||||
if(sq->geo.w > sq->geo.h)
|
|
||||||
g.w /= ((float)sq->data[2] / (float)sq->data[1]);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g.y += g.h;
|
|
||||||
g.h /= ((float)sq->data[2] / (float)sq->data[1]);
|
|
||||||
g.y -= g.h;
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_rect(ctx->barwin->dr, &g, sq->color2);
|
|
||||||
|
|
||||||
STORE_MOUSEBIND();
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Position */
|
|
||||||
case 'P':
|
|
||||||
NOALIGN_Y();
|
|
||||||
STATUS_ALIGN(sq->align);
|
|
||||||
|
|
||||||
draw_rect(ctx->barwin->dr, &sq->geo, sq->color);
|
|
||||||
|
|
||||||
if(sq->data[1] > sq->data[2])
|
|
||||||
sq->data[1] = sq->data[2];
|
|
||||||
|
|
||||||
g.x = sq->geo.x + ((sq->geo.w - sq->data[0]) / ((float)sq->data[2] / (float)sq->data[1]));
|
|
||||||
g.y = sq->geo.y;
|
|
||||||
g.w = sq->data[0];
|
|
||||||
g.h = sq->geo.h;
|
|
||||||
|
|
||||||
draw_rect(ctx->barwin->dr, &g, sq->color2);
|
|
||||||
|
|
||||||
STORE_MOUSEBIND();
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Graph */
|
|
||||||
case 'g':
|
|
||||||
NOALIGN_Y();
|
|
||||||
STATUS_ALIGN(sq->align);
|
|
||||||
|
|
||||||
draw_rect(ctx->barwin->dr, &sq->geo, sq->color);
|
|
||||||
|
|
||||||
status_graph_process(ctx, sq, sq->str);
|
|
||||||
|
|
||||||
STORE_MOUSEBIND();
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Image */
|
|
||||||
#ifdef HAVE_IMLIB2
|
|
||||||
case 'i':
|
|
||||||
draw_image_load(sq->str, &w, &h);
|
|
||||||
|
|
||||||
if(sq->geo.w <= 0)
|
|
||||||
sq->geo.w = w;
|
|
||||||
if(sq->geo.h <= 0)
|
|
||||||
sq->geo.h = h;
|
|
||||||
|
|
||||||
if(sq->align != NoAlign)
|
|
||||||
sq->geo.y = (ctx->barwin->geo.h >> 1) - (sq->geo.h >> 1);
|
|
||||||
|
|
||||||
STATUS_ALIGN(sq->align);
|
|
||||||
draw_image(ctx->barwin->dr, &sq->geo);
|
|
||||||
STORE_MOUSEBIND();
|
|
||||||
|
|
||||||
break;
|
|
||||||
#endif /* HAVE_IMLIB2 */
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Render current statustext of an element */
|
|
||||||
void
|
void
|
||||||
status_render(struct status_ctx *ctx)
|
statustext_handle(int sc, char *str)
|
||||||
{
|
{
|
||||||
if(!ctx->status)
|
char *lastst;
|
||||||
|
int i, nr, ng, ns, sw = 0;
|
||||||
|
StatusRec r[128];
|
||||||
|
StatusGraph g[128];
|
||||||
|
StatusText s[128];
|
||||||
|
|
||||||
|
/* If the str == the current statustext, return (not needed) */
|
||||||
|
if(!str)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(!(ctx->flags & STATUS_BLOCK_REFRESH))
|
if(sc == conf.systray.screen)
|
||||||
barwin_refresh_color(ctx->barwin);
|
sw = systray_get_width();
|
||||||
|
|
||||||
/* Use simple text instead sequence if no sequence found */
|
barwin_refresh_color(infobar[sc].bar);
|
||||||
if(SLIST_EMPTY(&ctx->statushead))
|
|
||||||
{
|
|
||||||
int l = draw_textw(ctx->theme, ctx->status);
|
|
||||||
draw_text(ctx->barwin->dr, ctx->theme, ctx->barwin->geo.w - l,
|
|
||||||
TEXTY(ctx->theme, ctx->barwin->geo.h), ctx->barwin->fg, ctx->status);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
status_apply_list(ctx);
|
|
||||||
|
|
||||||
barwin_refresh(ctx->barwin);
|
/* save last status text address (for free at the end) */
|
||||||
}
|
lastst = infobar[sc].statustext;
|
||||||
|
|
||||||
void
|
infobar[sc].statustext = xstrdup(str);
|
||||||
status_flush_list(struct status_ctx *ctx)
|
|
||||||
{
|
|
||||||
struct status_seq *sq;
|
|
||||||
struct mousebind *m;
|
|
||||||
|
|
||||||
/* Flush previous linked list of status sequences */
|
/* Store rectangles, located text & images properties. */
|
||||||
while(!SLIST_EMPTY(&ctx->statushead))
|
nr = statustext_rectangle(r, str);
|
||||||
{
|
ng = statustext_graph(g, str);
|
||||||
sq = SLIST_FIRST(&ctx->statushead);
|
ns = statustext_text(s, str);
|
||||||
SLIST_REMOVE_HEAD(&ctx->statushead, next);
|
|
||||||
|
|
||||||
while(!SLIST_EMPTY(&sq->mousebinds))
|
/* Draw normal text (and possibly colored with \#color\ blocks) */
|
||||||
{
|
statustext_normal(sc, str);
|
||||||
m = SLIST_FIRST(&sq->mousebinds);
|
|
||||||
SLIST_REMOVE_HEAD(&sq->mousebinds, snext);
|
|
||||||
free((void*)m->cmd);
|
|
||||||
free(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(sq->str);
|
/* Draw rectangles with stored properties. */
|
||||||
free(sq);
|
for(i = 0; i < nr; ++i)
|
||||||
}
|
draw_rectangle(infobar[sc].bar->dr, r[i].x - sw, r[i].y, r[i].w, r[i].h, r[i].color);
|
||||||
|
|
||||||
SLIST_INIT(&ctx->statushead);
|
/* Draw graphs with stored properties. */
|
||||||
}
|
for(i = 0; i < ng; ++i)
|
||||||
|
draw_graph(infobar[sc].bar->dr, g[i].x - sw, g[i].y, g[i].w, g[i].h, g[i].color, g[i].data);
|
||||||
|
|
||||||
void
|
/* Draw located text with stored properties. */
|
||||||
status_copy_mousebind(struct status_ctx *ctx)
|
for(i = 0; i < ns; ++i)
|
||||||
{
|
draw_text(infobar[sc].bar->dr, s[i].x - sw, s[i].y, s[i].color, s[i].text);
|
||||||
struct mousebind *m;
|
|
||||||
struct status_seq *sq;
|
barwin_refresh(infobar[sc].bar);
|
||||||
|
|
||||||
|
free(lastst);
|
||||||
|
|
||||||
if(!ctx->barwin)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Flush barwin head of status mousebinds */
|
|
||||||
SLIST_INIT(&ctx->barwin->statusmousebinds);
|
|
||||||
|
|
||||||
SLIST_FOREACH(sq, &ctx->statushead, next)
|
|
||||||
{
|
|
||||||
SLIST_FOREACH(m, &sq->mousebinds, snext)
|
|
||||||
SLIST_INSERT_HEAD(&ctx->barwin->statusmousebinds, m, next);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parse and render statustext */
|
|
||||||
void
|
|
||||||
status_manage(struct status_ctx *ctx)
|
|
||||||
{
|
|
||||||
if(!ctx->status)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ctx->update = false;
|
|
||||||
|
|
||||||
status_flush_list(ctx);
|
|
||||||
status_parse(ctx);
|
|
||||||
status_render(ctx);
|
|
||||||
status_copy_mousebind(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
status_flush_surface(void)
|
|
||||||
{
|
|
||||||
struct barwin *b;
|
|
||||||
|
|
||||||
while(!SLIST_EMPTY(&W->h.vbarwin))
|
|
||||||
{
|
|
||||||
b = SLIST_FIRST(&W->h.vbarwin);
|
|
||||||
SLIST_REMOVE_HEAD(&W->h.vbarwin, vnext);
|
|
||||||
barwin_remove(b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
status_surface(int x, int y, int w, int h, Color bg, char *status)
|
|
||||||
{
|
|
||||||
struct barwin *b;
|
|
||||||
struct screen *s;
|
|
||||||
struct status_ctx ctx;
|
|
||||||
int d;
|
|
||||||
Window rw;
|
|
||||||
|
|
||||||
if(!status)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(x + y < 0)
|
|
||||||
XQueryPointer(W->dpy, W->root, &rw, &rw, &x, &y, &d, &d, (unsigned int *)&d);
|
|
||||||
|
|
||||||
s = screen_gb_geo(x, y);
|
|
||||||
|
|
||||||
if(x + w > s->geo.x + s->geo.w)
|
|
||||||
x -= w;
|
|
||||||
if(y + h > s->geo.y + s->geo.h)
|
|
||||||
y -= h;
|
|
||||||
|
|
||||||
b = barwin_new(W->root, x, y, w, h, 0, bg, false);
|
|
||||||
barwin_map(b);
|
|
||||||
|
|
||||||
/* Use client theme */
|
|
||||||
ctx = status_new_ctx(b, W->ctheme);
|
|
||||||
ctx.status = xstrdup(status);
|
|
||||||
|
|
||||||
SLIST_INSERT_HEAD(&W->h.vbarwin, b, vnext);
|
|
||||||
|
|
||||||
status_manage(&ctx);
|
|
||||||
status_free_ctx(&ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
uicb_status_surface(Uicb cmd)
|
|
||||||
{
|
|
||||||
char *p, *ccmd = xstrdup(cmd);
|
|
||||||
int s, w, h, x = -1, y = -1;
|
|
||||||
Color bg;
|
|
||||||
|
|
||||||
if(!ccmd || !(p = strchr(ccmd, ' ')))
|
|
||||||
return;
|
|
||||||
|
|
||||||
*p = '\0';
|
|
||||||
++p;
|
|
||||||
|
|
||||||
if(!(((s = sscanf(ccmd, "%d,%d,#%x", &w, &h, &bg)) == 3)
|
|
||||||
|| (s = sscanf(ccmd, "%d,%d,%d,%d,#%x", &x, &y, &w, &h, &bg)) == 5))
|
|
||||||
{
|
|
||||||
free(ccmd);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
status_surface(x, y, w, h, bg, p);
|
|
||||||
|
|
||||||
free(ccmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Syntax: "<infobar name> <status string>" */
|
|
||||||
void
|
|
||||||
uicb_status(Uicb cmd)
|
|
||||||
{
|
|
||||||
struct infobar *ib;
|
|
||||||
struct screen *s;
|
|
||||||
char *p;
|
|
||||||
|
|
||||||
if(!cmd || !(p = strchr(cmd, ' ')))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Get infobar name & status */
|
|
||||||
*p = '\0';
|
|
||||||
++p;
|
|
||||||
|
|
||||||
SLIST_FOREACH(s, &W->h.screen, next)
|
|
||||||
{
|
|
||||||
SLIST_FOREACH(ib, &s->infobars, next)
|
|
||||||
if(!strcmp(cmd, ib->name))
|
|
||||||
{
|
|
||||||
free(ib->statusctx.status);
|
|
||||||
ib->statusctx.status = xstrdup(p);
|
|
||||||
ib->statusctx.update = true;
|
|
||||||
infobar_elem_screen_update(s, ElemStatus);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
23
src/status.h
23
src/status.h
@ -1,23 +0,0 @@
|
|||||||
/*
|
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
|
||||||
* For license, see COPYING.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef STATUS_H
|
|
||||||
#define STATUS_H
|
|
||||||
|
|
||||||
#include "wmfs.h"
|
|
||||||
|
|
||||||
struct status_ctx status_new_ctx(struct barwin *b, struct theme *t);
|
|
||||||
void status_free_ctx(struct status_ctx *ctx);
|
|
||||||
void status_flush_list(struct status_ctx *ctx);
|
|
||||||
void status_flush_mousebind(struct status_ctx *ctx);
|
|
||||||
void status_copy_mousebind(struct status_ctx *ctx);
|
|
||||||
void status_parse(struct status_ctx *ctx);
|
|
||||||
void status_render(struct status_ctx *ctx);
|
|
||||||
void status_manage(struct status_ctx *ctx);
|
|
||||||
void status_flush_surface(void);
|
|
||||||
void uicb_status(Uicb cmd);
|
|
||||||
void uicb_status_surface(Uicb cmd);
|
|
||||||
|
|
||||||
#endif /* STATUS_H */
|
|
||||||
570
src/structs.h
Normal file
570
src/structs.h
Normal file
@ -0,0 +1,570 @@
|
|||||||
|
/*
|
||||||
|
* structs.h
|
||||||
|
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of the nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef STRUCTS_H
|
||||||
|
#define STRUCTS_H
|
||||||
|
|
||||||
|
#include "wmfs.h"
|
||||||
|
|
||||||
|
#define NBUTTON 8
|
||||||
|
#define MAXTAG 36
|
||||||
|
#define NUM_OF_LAYOUT 10
|
||||||
|
#define HISTOLEN 128
|
||||||
|
|
||||||
|
/* Clients flags definition */
|
||||||
|
#define FreeFlag (1 << 1)
|
||||||
|
#define MaxFlag (1 << 2)
|
||||||
|
#define TileFlag (1 << 3)
|
||||||
|
#define HideFlag (1 << 4)
|
||||||
|
#define LMaxFlag (1 << 5)
|
||||||
|
#define UnmapFlag (1 << 6)
|
||||||
|
#define HintFlag (1 << 7)
|
||||||
|
#define FSSFlag (1 << 8)
|
||||||
|
#define AboveFlag (1 << 9)
|
||||||
|
#define UrgentFlag (1 << 10)
|
||||||
|
#define FLayFlag (1 << 11)
|
||||||
|
#define DockFlag (1 << 12)
|
||||||
|
|
||||||
|
#define TagFlag(t) (1 << (t))
|
||||||
|
|
||||||
|
/* XEMBED messages */
|
||||||
|
#define XEMBED_MAPPED (1 << 0)
|
||||||
|
#define XEMBED_EMBEDDED_NOTIFY 0
|
||||||
|
#define XEMBED_WINDOW_ACTIVATE 1
|
||||||
|
#define XEMBED_WINDOW_DEACTIVATE 2
|
||||||
|
#define XEMBED_REQUEST_FOCUS 3
|
||||||
|
#define XEMBED_FOCUS_IN 4
|
||||||
|
#define XEMBED_FOCUS_OUT 5
|
||||||
|
#define XEMBED_FOCUS_NEXT 6
|
||||||
|
#define XEMBED_FOCUS_PREV 7
|
||||||
|
/* 8-9 were used for XEMBED_GRAB_KEY/XEMBED_UNGRAB_KEY */
|
||||||
|
#define XEMBED_MODALITY_ON 10
|
||||||
|
#define XEMBED_MODALITY_OFF 11
|
||||||
|
#define XEMBED_REGISTER_ACCELERATOR 12
|
||||||
|
#define XEMBED_UNREGISTER_ACCELERATOR 13
|
||||||
|
#define XEMBED_ACTIVATE_ACCELERATOR 14
|
||||||
|
|
||||||
|
/* Details for XEMBED_FOCUS_IN: */
|
||||||
|
#define XEMBED_FOCUS_CURRENT 0
|
||||||
|
#define XEMBED_FOCUS_FIRST 1
|
||||||
|
#define XEMBED_FOCUS_LAST 2
|
||||||
|
|
||||||
|
/* Typedef */
|
||||||
|
typedef const char* uicb_t;
|
||||||
|
typedef unsigned int uint;
|
||||||
|
typedef unsigned long ulong;
|
||||||
|
typedef unsigned short ushort;
|
||||||
|
typedef unsigned char uchar;
|
||||||
|
|
||||||
|
/* Enum */
|
||||||
|
enum { CurNormal, CurResize, CurRightResize, CurLeftResize, CurMove, CurLast };
|
||||||
|
enum { TagSel, TagTransfert, TagAdd, TagNext, TagPrev, TagActionLast };
|
||||||
|
|
||||||
|
/* Menu align */
|
||||||
|
enum { MA_Center = 0, MA_Left = 1, MA_Right = 2 };
|
||||||
|
|
||||||
|
/* Infobar position */
|
||||||
|
enum { IB_Hide = 0, IB_Bottom = 1, IB_Top = 2 };
|
||||||
|
|
||||||
|
typedef enum { Right, Left, Top, Bottom, Center, PositionLast } Position;
|
||||||
|
|
||||||
|
/* Ewmh hints list */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
net_supported,
|
||||||
|
net_wm_name,
|
||||||
|
net_client_list,
|
||||||
|
net_frame_extents,
|
||||||
|
net_number_of_desktops,
|
||||||
|
net_current_desktop,
|
||||||
|
net_desktop_names,
|
||||||
|
net_desktop_geometry,
|
||||||
|
net_active_window,
|
||||||
|
net_close_window,
|
||||||
|
net_wm_icon_name,
|
||||||
|
net_wm_window_type,
|
||||||
|
net_wm_pid,
|
||||||
|
net_showing_desktop,
|
||||||
|
net_supporting_wm_check,
|
||||||
|
net_wm_window_opacity,
|
||||||
|
net_wm_window_type_normal,
|
||||||
|
net_wm_window_type_dock,
|
||||||
|
net_wm_window_type_splash,
|
||||||
|
net_wm_window_type_dialog,
|
||||||
|
net_wm_desktop,
|
||||||
|
net_wm_icon,
|
||||||
|
net_wm_state,
|
||||||
|
net_wm_state_fullscreen,
|
||||||
|
net_wm_state_sticky,
|
||||||
|
net_wm_state_demands_attention,
|
||||||
|
net_wm_system_tray_opcode,
|
||||||
|
net_system_tray_message_data,
|
||||||
|
net_system_tray_s,
|
||||||
|
net_system_tray_visual,
|
||||||
|
net_system_tray_orientation,
|
||||||
|
xembed,
|
||||||
|
xembedinfo,
|
||||||
|
manager,
|
||||||
|
utf8_string,
|
||||||
|
/* WMFS HINTS */
|
||||||
|
wmfs_running,
|
||||||
|
wmfs_update_hints,
|
||||||
|
wmfs_update_status,
|
||||||
|
wmfs_current_tag,
|
||||||
|
wmfs_current_screen,
|
||||||
|
wmfs_current_layout,
|
||||||
|
wmfs_tag_list,
|
||||||
|
wmfs_mwfact,
|
||||||
|
wmfs_nmaster,
|
||||||
|
wmfs_set_screen,
|
||||||
|
wmfs_screen_count,
|
||||||
|
wmfs_function,
|
||||||
|
wmfs_cmd,
|
||||||
|
wmfs_font,
|
||||||
|
wmfs_statustext,
|
||||||
|
net_last
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BarWindow Structure
|
||||||
|
* (titlebar, infobar..)
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
Window win;
|
||||||
|
Drawable dr;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
/* Border Window */
|
||||||
|
Window left, right, top, bottom;
|
||||||
|
/* Border color */
|
||||||
|
uint dark, light;
|
||||||
|
|
||||||
|
} border;
|
||||||
|
uint bg;
|
||||||
|
char *fg;
|
||||||
|
uint stipple_color;
|
||||||
|
XRectangle geo;
|
||||||
|
Bool mapped, stipple, bord;
|
||||||
|
} BarWindow;
|
||||||
|
|
||||||
|
/* Client Structure. */
|
||||||
|
typedef struct Client Client;
|
||||||
|
struct Client
|
||||||
|
{
|
||||||
|
/* Client title */
|
||||||
|
char *title;
|
||||||
|
/* Tag num */
|
||||||
|
uint tag;
|
||||||
|
int focusontag;
|
||||||
|
/* Screen */
|
||||||
|
int screen;
|
||||||
|
/* Layer */
|
||||||
|
int layer;
|
||||||
|
/* Window attribute */
|
||||||
|
XRectangle geo;
|
||||||
|
XRectangle tmp_geo;
|
||||||
|
XRectangle frame_geo;
|
||||||
|
/* Old window attribute */
|
||||||
|
XRectangle ogeo;
|
||||||
|
/* Free window attribute */
|
||||||
|
XRectangle free_geo;
|
||||||
|
/* For resizehint usage */
|
||||||
|
int basew, baseh, incw, inch;
|
||||||
|
int maxw, maxh, minw, minh;
|
||||||
|
int minax, maxax, minay, maxay;
|
||||||
|
/* Client composant {{{ */
|
||||||
|
Window win;
|
||||||
|
Window *button;
|
||||||
|
int button_last_x;
|
||||||
|
BarWindow *titlebar;
|
||||||
|
Window frame, resize[2];
|
||||||
|
/* Border */
|
||||||
|
Window right, left, top, bottom;
|
||||||
|
/* }}} */
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint frame;
|
||||||
|
char *fg;
|
||||||
|
uint resizecorner;
|
||||||
|
uint bordlight, borddark;
|
||||||
|
} colors;
|
||||||
|
/* Client Information by flags */
|
||||||
|
uint flags;
|
||||||
|
/* Struct in chains */
|
||||||
|
Client *next;
|
||||||
|
Client *prev;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Keybind Structure */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint mod;
|
||||||
|
KeySym keysym;
|
||||||
|
void (*func)(uicb_t);
|
||||||
|
uicb_t cmd;
|
||||||
|
} Key;
|
||||||
|
|
||||||
|
/* Mouse Binding Struct */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int tag;
|
||||||
|
int screen;
|
||||||
|
uint button;
|
||||||
|
void (*func)(uicb_t);
|
||||||
|
uicb_t cmd;
|
||||||
|
} MouseBinding;
|
||||||
|
|
||||||
|
/* InfoBar Struct */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
BarWindow *bar, *selbar;
|
||||||
|
BarWindow *layout_button;
|
||||||
|
BarWindow *tags_board, *tags[MAXTAG];
|
||||||
|
XRectangle geo;
|
||||||
|
int position;
|
||||||
|
char *statustext;
|
||||||
|
Bool need_update;
|
||||||
|
} InfoBar;
|
||||||
|
|
||||||
|
/* Layout Structure */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *symbol;
|
||||||
|
char *type;
|
||||||
|
void (*func)(int screen);
|
||||||
|
} Layout;
|
||||||
|
|
||||||
|
/* Systray Structure */
|
||||||
|
typedef struct Systray Systray;
|
||||||
|
struct Systray
|
||||||
|
{
|
||||||
|
Window win;
|
||||||
|
XRectangle geo;
|
||||||
|
Systray *next, *prev;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Tag Structure */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
char **clients;
|
||||||
|
int nclients;
|
||||||
|
int layers;
|
||||||
|
float mwfact;
|
||||||
|
int nmaster;
|
||||||
|
Bool urgent;
|
||||||
|
Bool resizehint;
|
||||||
|
Bool request_update;
|
||||||
|
Bool abovefc;
|
||||||
|
int barpos;
|
||||||
|
int prev_barpos;
|
||||||
|
Layout layout;
|
||||||
|
uint tagad;
|
||||||
|
MouseBinding *mouse;
|
||||||
|
int nmouse;
|
||||||
|
Bool stay_last;
|
||||||
|
} Tag;
|
||||||
|
|
||||||
|
/* Menu Item Struct */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
void (*func)(uicb_t);
|
||||||
|
uicb_t cmd;
|
||||||
|
Bool (*check)(uicb_t);
|
||||||
|
char *submenu;
|
||||||
|
} MenuItem;
|
||||||
|
|
||||||
|
/* Menu Struct */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/* Name of the menu for call
|
||||||
|
* it in the conf (function = "menu"
|
||||||
|
* menu = "<name>").
|
||||||
|
*/
|
||||||
|
char *name;
|
||||||
|
/* Placement */
|
||||||
|
Bool place_at_mouse;
|
||||||
|
int align;
|
||||||
|
int x, y;
|
||||||
|
/* Color */
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
struct { uint bg; char *fg; } focus;
|
||||||
|
struct { uint bg; char *fg; } normal;
|
||||||
|
} colors;
|
||||||
|
/* Number of item */
|
||||||
|
int nitem, focus_item;
|
||||||
|
/* Item */
|
||||||
|
MenuItem *item;
|
||||||
|
} Menu;
|
||||||
|
|
||||||
|
/* Launcher struct */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
char *prompt;
|
||||||
|
char *command;
|
||||||
|
char histo[HISTOLEN][512];
|
||||||
|
uint nhisto;
|
||||||
|
int width;
|
||||||
|
} Launcher;
|
||||||
|
|
||||||
|
/* Button struct */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
MouseBinding *mouse;
|
||||||
|
XSegment *linecoord;
|
||||||
|
int nlines;
|
||||||
|
int nmouse;
|
||||||
|
uint flags;
|
||||||
|
} Button;
|
||||||
|
|
||||||
|
/* Alias struct */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
char *content;
|
||||||
|
} Alias;
|
||||||
|
|
||||||
|
/* Rule struct */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *class;
|
||||||
|
char *instance;
|
||||||
|
char *role;
|
||||||
|
int screen;
|
||||||
|
int tag;
|
||||||
|
Bool free;
|
||||||
|
Bool max;
|
||||||
|
Bool ignoretags;
|
||||||
|
Bool follow_client;
|
||||||
|
} Rule;
|
||||||
|
|
||||||
|
/* Configuration structure */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/* Configuration file path */
|
||||||
|
char confpath[512];
|
||||||
|
|
||||||
|
/* Misc option */
|
||||||
|
char *font;
|
||||||
|
uint opacity;
|
||||||
|
Bool raisefocus;
|
||||||
|
Bool focus_fmouse;
|
||||||
|
Bool focus_fmov;
|
||||||
|
Bool focus_pclick;
|
||||||
|
Bool ignore_next_client_rules;
|
||||||
|
Bool tagautohide;
|
||||||
|
Bool tagnamecount;
|
||||||
|
Tag default_tag;
|
||||||
|
uint pad;
|
||||||
|
int status_timing;
|
||||||
|
char *status_path;
|
||||||
|
pid_t status_pid;
|
||||||
|
char *autostart_path;
|
||||||
|
char *autostart_command;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Only the colors will be use for text
|
||||||
|
* are 'char*' (for xprint -> XftColorAllocName)
|
||||||
|
*/
|
||||||
|
uint bar;
|
||||||
|
char *text;
|
||||||
|
char *tagselfg;
|
||||||
|
char *tagurfg;
|
||||||
|
uint tagurbg;
|
||||||
|
uint tagselbg;
|
||||||
|
uint tag_occupied_bg;
|
||||||
|
char *tag_occupied_fg;
|
||||||
|
uint tagbord;
|
||||||
|
char *layout_fg;
|
||||||
|
uint layout_bg;
|
||||||
|
float client_light_shade;
|
||||||
|
float client_dark_shade;
|
||||||
|
float bar_light_shade;
|
||||||
|
float bar_dark_shade;
|
||||||
|
} colors;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int height;
|
||||||
|
MouseBinding *mouse;
|
||||||
|
int nmouse;
|
||||||
|
Bool selbar;
|
||||||
|
} bars;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
char *fg;
|
||||||
|
uint bg;
|
||||||
|
int maxlength;
|
||||||
|
MouseBinding *mouse;
|
||||||
|
int nmouse;
|
||||||
|
} selbar;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
char *background_command;
|
||||||
|
MouseBinding *mouse;
|
||||||
|
int nmouse;
|
||||||
|
} root;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
Bool set_new_win_master;
|
||||||
|
Bool place_at_mouse;
|
||||||
|
Bool border_shadow;
|
||||||
|
Bool new_client_get_mouse;
|
||||||
|
int borderheight;
|
||||||
|
char *autofree, *automax;
|
||||||
|
uint bordernormal;
|
||||||
|
uint borderfocus;
|
||||||
|
uint resizecorner_normal;
|
||||||
|
uint resizecorner_focus;
|
||||||
|
uint mod;
|
||||||
|
uint padding;
|
||||||
|
MouseBinding *mouse;
|
||||||
|
int nmouse;
|
||||||
|
uint default_open_tag;
|
||||||
|
int default_open_screen;
|
||||||
|
} client;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int height;
|
||||||
|
char *fg_normal;
|
||||||
|
char *fg_focus;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
Bool active;
|
||||||
|
struct { uint normal, focus; } colors;
|
||||||
|
} stipple;
|
||||||
|
MouseBinding *mouse;
|
||||||
|
int nmouse;
|
||||||
|
Button *button;
|
||||||
|
int nbutton;
|
||||||
|
} titlebar;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
Bool bar;
|
||||||
|
Bool tag;
|
||||||
|
Bool layout;
|
||||||
|
} border;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
Bool active;
|
||||||
|
int screen;
|
||||||
|
int spacing;
|
||||||
|
} systray;
|
||||||
|
Alias alias[256];
|
||||||
|
uint mouse_tag_action[TagActionLast];
|
||||||
|
int layout_button_width;
|
||||||
|
Layout layout[NUM_OF_LAYOUT];
|
||||||
|
Menu *menu;
|
||||||
|
Launcher *launcher;
|
||||||
|
Rule *rule;
|
||||||
|
int *ntag;
|
||||||
|
Bool tag_round;
|
||||||
|
Bool tag_auto_prev;
|
||||||
|
Bool client_round;
|
||||||
|
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;
|
||||||
|
char *tag_expose_name;
|
||||||
|
char *expose_layout;
|
||||||
|
char *selected_layout_symbol;
|
||||||
|
/* Number of... */
|
||||||
|
int nkeybind;
|
||||||
|
int nlayout;
|
||||||
|
int nmenu;
|
||||||
|
int nlauncher;
|
||||||
|
int nrule;
|
||||||
|
} Conf;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint x, y, w, h;
|
||||||
|
uint color;
|
||||||
|
} StatusRec;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint x, y, w, h;
|
||||||
|
uint color;
|
||||||
|
char data[512];
|
||||||
|
} StatusGraph;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint x, y;
|
||||||
|
char color[8];
|
||||||
|
char text[512];
|
||||||
|
} StatusText;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint x, y, w, h;
|
||||||
|
char name[512];
|
||||||
|
} ImageAttr;
|
||||||
|
|
||||||
|
/* Config.c struct */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
void *func;
|
||||||
|
} func_name_list_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
KeySym keysym;
|
||||||
|
} key_name_list_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
uint button;
|
||||||
|
} name_to_uint_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *cmd;
|
||||||
|
char *uicb;
|
||||||
|
} vicmd_to_uicb;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int version;
|
||||||
|
int flags;
|
||||||
|
} xembed_info;
|
||||||
|
|
||||||
|
#endif /* STRUCTS_H */
|
||||||
214
src/systray.c
214
src/systray.c
@ -1,159 +1,187 @@
|
|||||||
/*
|
/*
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
* systray.c
|
||||||
* For license, see COPYING.
|
* Copyright © 2008, 2009, 2010 Martin Duquesnoy <xorg62@gmail.com>
|
||||||
*/
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of the nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "wmfs.h"
|
#include "wmfs.h"
|
||||||
#include "systray.h"
|
|
||||||
#include "ewmh.h"
|
|
||||||
#include "infobar.h"
|
|
||||||
|
|
||||||
#define SYSTRAY_SPACING (2)
|
#define TRAY_DWIDTH (infobar[conf.systray.screen].bar->geo.height + conf.systray.spacing)
|
||||||
|
|
||||||
void
|
Bool
|
||||||
systray_acquire(void)
|
systray_acquire(void)
|
||||||
{
|
{
|
||||||
Window w = 0;
|
XSetWindowAttributes wattr;
|
||||||
XSetWindowAttributes wattr =
|
|
||||||
{
|
|
||||||
.event_mask = ButtonPressMask | ExposureMask,
|
|
||||||
.override_redirect = true,
|
|
||||||
.background_pixmap = ParentRelative,
|
|
||||||
.background_pixel = W->systray.infobar->theme->bars.bg,
|
|
||||||
};
|
|
||||||
|
|
||||||
if(!(W->flags & WMFS_SYSTRAY) || W->systray.win)
|
if(!conf.systray.active || traywin)
|
||||||
return;
|
return False;
|
||||||
|
|
||||||
if(XGetSelectionOwner(W->dpy, W->net_atom[net_system_tray_s]) != None)
|
if(XGetSelectionOwner(dpy, net_atom[net_system_tray_s]) != None)
|
||||||
{
|
{
|
||||||
warnx("Can't initialize system tray: owned by another process.");
|
warnx("Can't initialize system tray: owned by another process");
|
||||||
return;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
SLIST_INIT(&W->systray.head);
|
/* Init traywin window */
|
||||||
|
wattr.event_mask = ButtonPressMask | ExposureMask;
|
||||||
|
wattr.override_redirect = True;
|
||||||
|
wattr.background_pixmap = ParentRelative;
|
||||||
|
wattr.background_pixel = conf.colors.bar;
|
||||||
|
|
||||||
/* Init systray window */
|
traywin = XCreateSimpleWindow(dpy, infobar[conf.systray.screen].bar->win, -1, -1, 1, 1, 0, 0, conf.colors.bar);
|
||||||
w = XCreateSimpleWindow(W->dpy, W->systray.barwin->win, 0, 0,
|
|
||||||
W->systray.barwin->geo.h, W->systray.barwin->geo.h, 0, 0, 0);
|
|
||||||
|
|
||||||
XChangeWindowAttributes(W->dpy, w, CWEventMask | CWOverrideRedirect | CWBackPixel, &wattr);
|
XChangeWindowAttributes(dpy, traywin, CWEventMask | CWOverrideRedirect | CWBackPixel, &wattr);
|
||||||
XSelectInput(W->dpy, w, KeyPressMask | ButtonPressMask);
|
XSelectInput(dpy, traywin, KeyPressMask | ButtonPressMask);
|
||||||
XMapRaised(W->dpy, w);
|
|
||||||
|
|
||||||
XSetSelectionOwner(W->dpy, W->net_atom[net_system_tray_s], w, CurrentTime);
|
XMapRaised(dpy, traywin);
|
||||||
|
|
||||||
if(XGetSelectionOwner(W->dpy, W->net_atom[net_system_tray_s]) != w)
|
XSetSelectionOwner(dpy, net_atom[net_system_tray_s], traywin, CurrentTime);
|
||||||
|
|
||||||
|
if(XGetSelectionOwner(dpy, net_atom[net_system_tray_s]) != traywin)
|
||||||
{
|
{
|
||||||
warnl("System tray: can't get systray manager");
|
|
||||||
systray_freeicons();
|
systray_freeicons();
|
||||||
return;
|
warnx("System tray: can't get systray manager");
|
||||||
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
ewmh_send_message(W->root, W->root, "MANAGER", CurrentTime,
|
ewmh_send_message(ROOT, ROOT, "MANAGER", CurrentTime, net_atom[net_system_tray_s], traywin, 0, 0);
|
||||||
W->net_atom[net_system_tray_s], w, 0, 0);
|
|
||||||
|
|
||||||
XSync(W->dpy, false);
|
XSync(dpy, False);
|
||||||
|
|
||||||
W->systray.win = w;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
systray_add(Window win)
|
systray_add(Window win)
|
||||||
{
|
{
|
||||||
struct _systray *s;
|
Systray *s;
|
||||||
|
|
||||||
if(!(W->flags & WMFS_SYSTRAY))
|
if(!conf.systray.active)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
s = xcalloc(1, sizeof(struct _systray));
|
s = xcalloc(1, sizeof(Systray));
|
||||||
s->win = win;
|
s->win = win;
|
||||||
|
|
||||||
s->geo.h = W->systray.barwin->geo.h;
|
s->geo.height = infobar[conf.systray.screen].bar->geo.height;
|
||||||
s->geo.w = W->systray.barwin->geo.h + SYSTRAY_SPACING;
|
s->geo.width = TRAY_DWIDTH;
|
||||||
|
|
||||||
ewmh_set_wm_state(s->win, NormalState);
|
setwinstate(s->win, WithdrawnState);
|
||||||
XSelectInput(W->dpy, s->win, StructureNotifyMask | PropertyChangeMask| EnterWindowMask | FocusChangeMask);
|
XSelectInput(dpy, s->win, StructureNotifyMask | PropertyChangeMask| EnterWindowMask | FocusChangeMask);
|
||||||
XReparentWindow(W->dpy, s->win, W->systray.win, 0, 0);
|
XReparentWindow(dpy, s->win, traywin, 0, 0);
|
||||||
|
|
||||||
ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime,
|
ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0, traywin, 0);
|
||||||
XEMBED_EMBEDDED_NOTIFY, 0, W->systray.win, 0);
|
|
||||||
|
|
||||||
SLIST_INSERT_HEAD(&W->systray.head, s, next);
|
/* Attach */
|
||||||
|
if(trayicons)
|
||||||
|
trayicons->prev = s;
|
||||||
|
|
||||||
W->systray.redim = true;
|
s->next = trayicons;
|
||||||
|
trayicons = s;
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
systray_del(struct _systray *s)
|
systray_del(Systray *s)
|
||||||
{
|
{
|
||||||
if(!(W->flags & WMFS_SYSTRAY))
|
Systray **ss;
|
||||||
|
|
||||||
|
if(!conf.systray.active)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SLIST_REMOVE(&W->systray.head, s, _systray, next);
|
for(ss = &trayicons; *ss && *ss != s; ss = &(*ss)->next);
|
||||||
|
*ss = s->next;
|
||||||
|
|
||||||
free(s);
|
free(s);
|
||||||
|
|
||||||
W->systray.redim = true;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
systray_state(struct _systray *s)
|
systray_state(Systray *s)
|
||||||
{
|
{
|
||||||
long flags;
|
long flags;
|
||||||
int code = 0;
|
int code = 0;
|
||||||
|
|
||||||
if(!(W->flags & WMFS_SYSTRAY) || !(flags = ewmh_get_xembed_state(s->win)))
|
if(!(flags = ewmh_get_xembed_state(s->win)) || !conf.systray.active)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(flags & XEMBED_MAPPED)
|
if(flags & XEMBED_MAPPED)
|
||||||
{
|
{
|
||||||
code = XEMBED_WINDOW_ACTIVATE;
|
code = XEMBED_WINDOW_ACTIVATE;
|
||||||
XMapRaised(W->dpy, s->win);
|
XMapRaised(dpy, s->win);
|
||||||
ewmh_set_wm_state(s->win, NormalState);
|
setwinstate(s->win, NormalState);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
code = XEMBED_WINDOW_DEACTIVATE;
|
code = XEMBED_WINDOW_DEACTIVATE;
|
||||||
XUnmapWindow(W->dpy, s->win);
|
XUnmapWindow(dpy, s->win);
|
||||||
ewmh_set_wm_state(s->win, WithdrawnState);
|
setwinstate(s->win, WithdrawnState);
|
||||||
}
|
}
|
||||||
|
|
||||||
ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime, code, 0, 0, 0);
|
ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime, code, 0, 0, 0);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
systray_freeicons(void)
|
systray_freeicons(void)
|
||||||
{
|
{
|
||||||
struct _systray *i;
|
Systray *i;
|
||||||
|
|
||||||
if(!(W->flags & WMFS_SYSTRAY))
|
if(!conf.systray.active)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
while(!SLIST_EMPTY(&W->systray.head))
|
for(i = trayicons; i; i = i->next)
|
||||||
{
|
{
|
||||||
i = SLIST_FIRST(&W->systray.head);
|
XUnmapWindow(dpy, i->win);
|
||||||
SLIST_REMOVE_HEAD(&W->systray.head, next);
|
XReparentWindow(dpy, i->win, ROOT, 0, 0);
|
||||||
|
|
||||||
XUnmapWindow(W->dpy, i->win);
|
|
||||||
XReparentWindow(W->dpy, i->win, W->root, 0, 0);
|
|
||||||
free(i);
|
free(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
XSetSelectionOwner(W->dpy, W->net_atom[net_system_tray_s], None, CurrentTime);
|
XSetSelectionOwner(dpy, net_atom[net_system_tray_s], None, CurrentTime);
|
||||||
W->systray.barwin->geo.w = 0;
|
XDestroyWindow(dpy, traywin);
|
||||||
infobar_elem_reinit(W->systray.infobar);
|
|
||||||
XSync(W->dpy, false);
|
XSync(dpy, 0);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct _systray*
|
Systray*
|
||||||
systray_find(Window win)
|
systray_find(Window win)
|
||||||
{
|
{
|
||||||
struct _systray *i;
|
Systray *i;
|
||||||
|
|
||||||
if(!(W->flags & WMFS_SYSTRAY))
|
if(!conf.systray.active)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
SLIST_FOREACH(i, &W->systray.head, next)
|
for(i = trayicons; i; i = i->next)
|
||||||
if(i->win == win)
|
if(i->win == win)
|
||||||
return i;
|
return i;
|
||||||
|
|
||||||
@ -163,11 +191,14 @@ systray_find(Window win)
|
|||||||
int
|
int
|
||||||
systray_get_width(void)
|
systray_get_width(void)
|
||||||
{
|
{
|
||||||
int w = 1;
|
int w = 0;
|
||||||
struct _systray *i;
|
Systray *i;
|
||||||
|
|
||||||
SLIST_FOREACH(i, &W->systray.head, next)
|
if(!conf.systray.active)
|
||||||
w += i->geo.w + SYSTRAY_SPACING;
|
return 0;
|
||||||
|
|
||||||
|
for(i = trayicons; i; i = i->next)
|
||||||
|
w += i->geo.width + conf.systray.spacing + 1;
|
||||||
|
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
@ -175,26 +206,29 @@ systray_get_width(void)
|
|||||||
void
|
void
|
||||||
systray_update(void)
|
systray_update(void)
|
||||||
{
|
{
|
||||||
|
Systray *i;
|
||||||
int x = 1;
|
int x = 1;
|
||||||
struct _systray *i;
|
|
||||||
|
|
||||||
if(!(W->flags & WMFS_SYSTRAY))
|
if(!conf.systray.active)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(W->systray.redim)
|
if(!trayicons)
|
||||||
{
|
{
|
||||||
W->systray.redim = false;
|
XMoveResizeWindow(dpy, traywin, infobar[conf.systray.screen].bar->geo.width - 1, 0, 1, 1);
|
||||||
infobar_elem_reinit(W->systray.infobar);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SLIST_FOREACH(i, &W->systray.head, next)
|
for(i = trayicons; i; i = i->next)
|
||||||
{
|
{
|
||||||
XMapWindow(W->dpy, i->win);
|
XMapWindow(dpy, i->win);
|
||||||
XMoveResizeWindow(W->dpy, i->win, (i->geo.x = x), 0, i->geo.w, i->geo.h);
|
|
||||||
|
|
||||||
x += i->geo.w + SYSTRAY_SPACING;
|
XMoveResizeWindow(dpy, i->win, (i->geo.x = x), 0, i->geo.width, i->geo.height);
|
||||||
|
|
||||||
|
x += i->geo.width + conf.systray.spacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XMoveResizeWindow(dpy, traywin, infobar[conf.systray.screen].bar->geo.width - x,
|
||||||
|
0, x, infobar[conf.systray.screen].bar->geo.height);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,20 +0,0 @@
|
|||||||
/*
|
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
|
||||||
* For license, see COPYING.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SYSTRAY_H
|
|
||||||
#define SYSTRAY_H
|
|
||||||
|
|
||||||
#include "wmfs.h"
|
|
||||||
|
|
||||||
void systray_acquire(void);
|
|
||||||
void systray_add(Window win);
|
|
||||||
void systray_del(struct _systray *s);
|
|
||||||
void systray_state(struct _systray *s);
|
|
||||||
void systray_freeicons(void);
|
|
||||||
struct _systray *systray_find(Window win);
|
|
||||||
int systray_get_width(void);
|
|
||||||
void systray_update(void);
|
|
||||||
|
|
||||||
#endif /* SYSTRAY_H */
|
|
||||||
39
src/tag.h
39
src/tag.h
@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
|
||||||
* For license, see COPYING.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef TAG_H
|
|
||||||
#define TAG_H
|
|
||||||
|
|
||||||
#include "wmfs.h"
|
|
||||||
|
|
||||||
static inline struct tag*
|
|
||||||
tag_gb_id(struct screen *s, int id)
|
|
||||||
{
|
|
||||||
struct tag *t;
|
|
||||||
|
|
||||||
TAILQ_FOREACH(t, &s->tags, next)
|
|
||||||
if(t->id == id)
|
|
||||||
return t;
|
|
||||||
|
|
||||||
return TAILQ_FIRST(&s->tags);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct tag *tag_new(struct screen *s, char *name);
|
|
||||||
void tag_screen(struct screen *s, struct tag *t);
|
|
||||||
void tag_client(struct tag *t, struct client *c);
|
|
||||||
void tag_free(struct screen *s);
|
|
||||||
void uicb_tag_set(Uicb cmd);
|
|
||||||
void uicb_tag_set_with_name(Uicb cmd);
|
|
||||||
void uicb_tag_next(Uicb cmd);
|
|
||||||
void uicb_tag_prev(Uicb cmd);
|
|
||||||
void uicb_tag_client(Uicb cmd);
|
|
||||||
void uicb_tag_client_and_set(Uicb cmd);
|
|
||||||
void uicb_tag_move_client_next(Uicb cmd);
|
|
||||||
void uicb_tag_move_client_prev(Uicb cmd);
|
|
||||||
void uicb_tag_click(Uicb cmd);
|
|
||||||
void uicb_tag_new(Uicb cmd);
|
|
||||||
void uicb_tag_del(Uicb cmd);
|
|
||||||
|
|
||||||
#endif /* TAG_H */
|
|
||||||
284
src/util.c
284
src/util.c
@ -1,31 +1,54 @@
|
|||||||
/*
|
/*
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
* util.c
|
||||||
* For license, see COPYING.
|
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
|
||||||
*/
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of the nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
#define _GNU_SOURCE /* vasprintf() */
|
#define _GNU_SOURCE
|
||||||
|
#include "wmfs.h"
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
/** malloc with error support and size_t overflow protection
|
/** malloc with error support and size_t overflow protection
|
||||||
* \param nmemb number of objects
|
* \param nmemb number of objects
|
||||||
* \param size size of single object
|
* \param size size of single object
|
||||||
* \return non null void pointer
|
* \return non null void pointer
|
||||||
*/
|
*/
|
||||||
void*
|
void *
|
||||||
xmalloc(size_t nmemb, size_t size)
|
xmalloc(size_t nmemb, size_t size)
|
||||||
{
|
{
|
||||||
void *ret;
|
void *ret;
|
||||||
|
|
||||||
if(SIZE_MAX / nmemb < size)
|
if (SIZE_MAX / nmemb < size)
|
||||||
errl(EXIT_FAILURE, "xmalloc(%zu, %zu), "
|
err(EXIT_FAILURE, "xmalloc(%zu, %zu), "
|
||||||
"size_t overflow detected", nmemb, size);
|
"size_t overflow detected", nmemb, size);
|
||||||
|
|
||||||
if((ret = malloc(nmemb * size)) == NULL)
|
if ((ret = malloc(nmemb * size)) == NULL)
|
||||||
errl(EXIT_FAILURE, "malloc(%zu)", nmemb * size);
|
err(EXIT_FAILURE, "malloc(%zu)", nmemb * size);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -35,13 +58,13 @@ xmalloc(size_t nmemb, size_t size)
|
|||||||
* \param size size of single object
|
* \param size size of single object
|
||||||
* \return non null void pointer
|
* \return non null void pointer
|
||||||
*/
|
*/
|
||||||
void*
|
void *
|
||||||
xcalloc(size_t nmemb, size_t size)
|
xcalloc(size_t nmemb, size_t size)
|
||||||
{
|
{
|
||||||
void *ret;
|
void *ret;
|
||||||
|
|
||||||
if((ret = calloc(nmemb, size)) == NULL)
|
if ((ret = calloc(nmemb, size)) == NULL)
|
||||||
errl(EXIT_FAILURE, "calloc(%zu * %zu)", nmemb, size);
|
err(EXIT_FAILURE, "calloc(%zu * %zu)", nmemb, size);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -57,16 +80,30 @@ xrealloc(void *ptr, size_t nmemb, size_t size)
|
|||||||
{
|
{
|
||||||
void *ret;
|
void *ret;
|
||||||
|
|
||||||
if(SIZE_MAX / nmemb < size)
|
if (SIZE_MAX / nmemb < size)
|
||||||
err(EXIT_FAILURE, "xrealloc(%p, %zu, %zu), "
|
err(EXIT_FAILURE, "xrealloc(%p, %zu, %zu), "
|
||||||
"size_t overflow detected", ptr, nmemb, size);
|
"size_t overflow detected", ptr, nmemb, size);
|
||||||
|
|
||||||
if((ret = realloc(ptr, nmemb * size)) == NULL)
|
if ((ret = realloc(ptr, nmemb * size)) == NULL)
|
||||||
err(EXIT_FAILURE, "realloc(%p, %zu)", ptr, nmemb * size);
|
err(EXIT_FAILURE, "realloc(%p, %zu)", ptr, nmemb * size);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** strdup with error support
|
||||||
|
* \param str char pointer
|
||||||
|
* \retun non null void pointer
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
xstrdup(const char *str)
|
||||||
|
{
|
||||||
|
char *ret;
|
||||||
|
|
||||||
|
if (str == NULL || (ret = strdup(str)) == NULL)
|
||||||
|
err(EXIT_FAILURE, "strdup(%s)", str);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/** asprintf wrapper
|
/** asprintf wrapper
|
||||||
* \param strp target string
|
* \param strp target string
|
||||||
@ -84,27 +121,98 @@ xasprintf(char **strp, const char *fmt, ...)
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
errl(EXIT_FAILURE, "asprintf(%s)", fmt);
|
err(EXIT_FAILURE, "asprintf(%s)", fmt);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** strdup with error support
|
|
||||||
* \param str char pointer
|
/** Get a color with a string
|
||||||
* \retun non null void pointer
|
* \param color Color string
|
||||||
*/
|
* \return Color pixel
|
||||||
char *
|
*/
|
||||||
xstrdup(const char *str)
|
long
|
||||||
|
getcolor(char *color)
|
||||||
{
|
{
|
||||||
char *ret = NULL;
|
XColor xcolor;
|
||||||
|
|
||||||
if(str == NULL || (ret = strdup(str)) == NULL)
|
if(!XAllocNamedColor(dpy, DefaultColormap(dpy, SCREEN), color, &xcolor, &xcolor))
|
||||||
warnxl("strdup(%s)", str);
|
warnx("Error: cannot allocate color \"%s\".", color);
|
||||||
|
|
||||||
return ret;
|
return xcolor.pixel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Execute a system command
|
/** Set the window WM State
|
||||||
|
* \param win Window target
|
||||||
|
* \param state WM State
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
setwinstate(Window win, long state)
|
||||||
|
{
|
||||||
|
long data[] = {state, None};
|
||||||
|
|
||||||
|
XChangeProperty(dpy, win, ATOM("WM_STATE"), ATOM("WM_STATE"), 32,
|
||||||
|
PropModeReplace, (uchar *)data, 2);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The following function are for configuration
|
||||||
|
usage. {{{
|
||||||
|
*/
|
||||||
|
void*
|
||||||
|
name_to_func(char *name, const func_name_list_t *l)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if(name)
|
||||||
|
for(i = 0; l[i].name ; ++i)
|
||||||
|
if(!strcmp(name, l[i].name))
|
||||||
|
return l[i].func;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong
|
||||||
|
char_to_modkey(char *name, key_name_list_t key_l[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if(name)
|
||||||
|
for(i = 0; key_l[i].name; ++i)
|
||||||
|
if(!strcmp(name, key_l[i].name))
|
||||||
|
return key_l[i].keysym;
|
||||||
|
|
||||||
|
return NoSymbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint
|
||||||
|
char_to_button(char *name, name_to_uint_t blist[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if(name)
|
||||||
|
for(i = 0; blist[i].name; ++i)
|
||||||
|
if(!strcmp(name, blist[i].name))
|
||||||
|
return blist[i].button;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Layout
|
||||||
|
layout_name_to_struct(Layout lt[], char *name, int n, const func_name_list_t llist[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < n; ++i)
|
||||||
|
if(lt[i].func == name_to_func(name, llist))
|
||||||
|
return lt[i];
|
||||||
|
|
||||||
|
return lt[0];
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
/** Execute a sh command
|
||||||
* \param cmd Command
|
* \param cmd Command
|
||||||
* \return child pid
|
* \return child pid
|
||||||
*/
|
*/
|
||||||
@ -123,45 +231,123 @@ spawn(const char *format, ...)
|
|||||||
|
|
||||||
if (len >= sizeof(cmd))
|
if (len >= sizeof(cmd))
|
||||||
{
|
{
|
||||||
warnxl("command too long (> 512 bytes)");
|
warnx("command too long (> 512 bytes)");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(sh = getenv("SHELL")) || sh[0] != '/')
|
if(!(sh = getenv("SHELL")))
|
||||||
sh = "/bin/sh";
|
sh = "/bin/sh";
|
||||||
|
|
||||||
if(!(pid = fork()))
|
if((pid = fork()) == 0)
|
||||||
{
|
{
|
||||||
|
if(dpy)
|
||||||
|
close(ConnectionNumber(dpy));
|
||||||
setsid();
|
setsid();
|
||||||
if (execl(sh, sh, "-c", cmd, (char*)NULL) == -1)
|
if (execl(sh, sh, "-c", cmd, (char*)NULL) == -1)
|
||||||
warnl("execl(sh -c %s)", cmd);
|
warn("execl(sh -c %s)", cmd);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
else if (pid == -1)
|
else if (pid == -1)
|
||||||
warnl("fork");
|
warn("fork");
|
||||||
|
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
/** Swap two pointer.
|
||||||
parse_args(char *str, char delim, char end, int narg, char *args[])
|
*\param x First pointer
|
||||||
|
*\param y Second pointer
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
swap_ptr(void **x, void **y)
|
||||||
{
|
{
|
||||||
int i = 0;
|
void *t = *x;
|
||||||
|
|
||||||
for(args[0] = str; *str && (*str != end || *(str - 1) == '\\') && i < narg; ++str)
|
*x = *y;
|
||||||
if(*str == delim && i < narg - 1)
|
*y = t;
|
||||||
{
|
|
||||||
*str = '\0';
|
|
||||||
args[++i] = ++str;
|
|
||||||
}
|
|
||||||
|
|
||||||
*str = '\0';
|
return;
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Execute a sh command
|
||||||
|
* \param cmd Command (uicb_t type)
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
uicb_spawn(Uicb cmd)
|
uicb_spawn(uicb_t cmd)
|
||||||
{
|
{
|
||||||
spawn("%s", cmd);
|
spawn("%s", cmd);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_IMLIB
|
||||||
|
/** Check images blocks in str and return properties
|
||||||
|
* --> \i[x;y;w;h;name]\
|
||||||
|
*\param im ImageAttr pointer, image properties
|
||||||
|
*\param str String
|
||||||
|
*\return n Lenght of i
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
parse_image_block(ImageAttr *im, char *str)
|
||||||
|
{
|
||||||
|
char as;
|
||||||
|
int n, i, j, k;
|
||||||
|
|
||||||
|
for(i = j = n = 0; i < (int)strlen(str); ++i, ++j)
|
||||||
|
if(sscanf(&str[i], "\\i[%d;%d;%d;%d;%512[^]]]%c", &im[n].x, &im[n].y, &im[n].w, &im[n].h, im[n].name, &as) == 6
|
||||||
|
&& as == '\\')
|
||||||
|
for(++n, ++i, --j; str[i] != as || str[i - 1] != ']'; ++i);
|
||||||
|
else if(j != i)
|
||||||
|
str[j] = str[i];
|
||||||
|
|
||||||
|
for(k = j; k < i; str[k++] = 0);
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_IMLIB */
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
static char ret[512];
|
||||||
|
|
||||||
|
if(!path)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
strncpy(ret, path, sizeof(ret));
|
||||||
|
ret[sizeof(ret) - 1] = 0;
|
||||||
|
if(strstr(path, "~/"))
|
||||||
|
snprintf(ret, sizeof(ret), "%s/%s", getenv("HOME"), path + 2);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
qsort_string_compare (const void * a, const void * b)
|
||||||
|
{
|
||||||
|
return (strcmp(*(char **)a, *(char **)b));
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
99
src/util.h
99
src/util.h
@ -1,99 +0,0 @@
|
|||||||
/*
|
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
|
||||||
* For license, see COPYING.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef UTIL_H
|
|
||||||
#define UTIL_H
|
|
||||||
|
|
||||||
#include "wmfs.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/* Todo FREE_LIST(type, head, function_remove) */
|
|
||||||
#define FREE_LIST(type, head) \
|
|
||||||
do { \
|
|
||||||
struct type *Z; \
|
|
||||||
while(!SLIST_EMPTY(&head)) { \
|
|
||||||
Z = SLIST_FIRST(&head); \
|
|
||||||
SLIST_REMOVE_HEAD(&head, next); \
|
|
||||||
free(Z); /* function_remove(t)*/ \
|
|
||||||
} \
|
|
||||||
} while(/* CONSTCOND */ 0);
|
|
||||||
|
|
||||||
/* Insert at the end with SLIST */
|
|
||||||
#define SLIST_INSERT_TAIL(head, elem, field, prev) \
|
|
||||||
if(!prev) \
|
|
||||||
SLIST_INSERT_HEAD(head, elem, field); \
|
|
||||||
else \
|
|
||||||
SLIST_INSERT_AFTER(prev, elem, field);
|
|
||||||
|
|
||||||
/* t is Map or Unmap */
|
|
||||||
#define WIN_STATE(w, t) do { \
|
|
||||||
X##t##Subwindows(W->dpy, w); \
|
|
||||||
X##t##Window(W->dpy, w); \
|
|
||||||
} while( /* CONSTCOND */ 0);
|
|
||||||
|
|
||||||
#define ATOM(a) XInternAtom(W->dpy, (a), False)
|
|
||||||
#define LEN(x) (sizeof(x) / sizeof(*x))
|
|
||||||
#define FLAGINT(i) (1 << i)
|
|
||||||
#define FLAGAPPLY(f, b, m) (f |= (b ? m : 0))
|
|
||||||
#define ATOI(s) strtol(s, NULL, 10)
|
|
||||||
#define ABS(j) (j < 0 ? -j : j)
|
|
||||||
#define INAREA(i, j, a) ((i) >= (a).x && (i) <= (a).x + (a).w && (j) >= (a).y && (j) <= (a).y + (a).h)
|
|
||||||
#define GEOCMP(g1, g2) ((g1).x == (g2).x && (g1).y == (g2).y && (g1).w == (g2).w && (g1).h == (g2).h)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* "#RRGGBB" -> 0xRRGGBB
|
|
||||||
*/
|
|
||||||
static inline Color
|
|
||||||
color_atoh(const char *col)
|
|
||||||
{
|
|
||||||
XColor xcolor;
|
|
||||||
|
|
||||||
if(!XAllocNamedColor(W->dpy, DefaultColormap(W->dpy, W->xscreen), col, &xcolor, &xcolor))
|
|
||||||
warnl("Error: cannot allocate color \"%s\".", col);
|
|
||||||
|
|
||||||
return xcolor.pixel;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
swap_ptr(void **x, void **y)
|
|
||||||
{
|
|
||||||
void *t = *x;
|
|
||||||
|
|
||||||
*x = *y;
|
|
||||||
*y = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
swap_int(int *x, int *y)
|
|
||||||
{
|
|
||||||
*y = *x ^ *y;
|
|
||||||
*x = *y ^ *x;
|
|
||||||
*y = *x ^ *y;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline enum position
|
|
||||||
str_to_position(char *str)
|
|
||||||
{
|
|
||||||
enum position i;
|
|
||||||
static const char index[PositionLast][8] = { "right", "left", "top", "bottom", "center" };
|
|
||||||
|
|
||||||
for(i = 0; i < PositionLast; ++i)
|
|
||||||
if(!strcmp(index[i], str))
|
|
||||||
return i;
|
|
||||||
|
|
||||||
return Right;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *xmalloc(size_t nmemb, size_t size);
|
|
||||||
void *xcalloc(size_t nmemb, size_t size);
|
|
||||||
void *xrealloc(void *ptr, size_t nmemb, size_t size);
|
|
||||||
int xasprintf(char **strp, const char *fmt, ...);
|
|
||||||
char *xstrdup(const char *str);
|
|
||||||
pid_t spawn(const char *format, ...);
|
|
||||||
int parse_args(char *str, char delim, char end, int narg, char *args[]);
|
|
||||||
void uicb_spawn(Uicb cmd);
|
|
||||||
|
|
||||||
#endif /* UTIL_H */
|
|
||||||
143
src/viwmfs.c
Normal file
143
src/viwmfs.c
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
* viwmfs.c
|
||||||
|
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of the nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "wmfs.h"
|
||||||
|
|
||||||
|
static vicmd_to_uicb vicmd[] =
|
||||||
|
{
|
||||||
|
{"r", "reload"},
|
||||||
|
{"q", "quit"},
|
||||||
|
{"t", "tag"},
|
||||||
|
{"tn", "tag_next"},
|
||||||
|
{"tp", "tag_prev"},
|
||||||
|
{"l", "set_layout"},
|
||||||
|
{"layout", "set_layout"},
|
||||||
|
{"ln", "layout_next"},
|
||||||
|
{"lp", "layout_prev"},
|
||||||
|
{"s", "screen_select"},
|
||||||
|
{"screen", "screen_select"},
|
||||||
|
{"sn", "screen_next"},
|
||||||
|
{"sp", "screen_prev"},
|
||||||
|
{"cc", "client_kill"},
|
||||||
|
{"ct", "tag_transfert"},
|
||||||
|
{"ctn", "tag_transfert_next"},
|
||||||
|
{"ctp", "tag_transfert_prev"},
|
||||||
|
{"cn", "client_next"},
|
||||||
|
{"cp", "client_prev"},
|
||||||
|
{"csn", "client_swap_next"},
|
||||||
|
{"csp", "client_swap_prev"},
|
||||||
|
{"mwf", "set_mwfact"},
|
||||||
|
{"mwfact", "set_mwfact"},
|
||||||
|
{"nmaster", "set_nmaster"},
|
||||||
|
{"tm", "toggle_max"},
|
||||||
|
{"tf", "toggle_free"},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
viwmfs_help(void)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
char s[20];
|
||||||
|
|
||||||
|
printf("ViWMFS commands list:\n");
|
||||||
|
|
||||||
|
for(i = 0; i < LEN(vicmd); ++i)
|
||||||
|
{
|
||||||
|
memset(s, ' ', sizeof(s));
|
||||||
|
|
||||||
|
s[15 - strlen(vicmd[i].cmd)] = '\0';
|
||||||
|
|
||||||
|
printf(" :%s%s %s\n", vicmd[i].cmd, s, vicmd[i].uicb);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
viwmfs(int argc, char **argv)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
char *cmd, str[256] = { 0 };
|
||||||
|
Bool e;
|
||||||
|
|
||||||
|
if(!argc)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(argc > 3)
|
||||||
|
{
|
||||||
|
for(i = 2; i < (size_t)argc; ++i)
|
||||||
|
{
|
||||||
|
strcat(str, argv[i]);
|
||||||
|
|
||||||
|
if(*(str + strlen(str) - 1) != ':')
|
||||||
|
strcat(str, " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
strncpy(str, argv[2], sizeof(str));
|
||||||
|
|
||||||
|
if(!strcmp(str, "help"))
|
||||||
|
{
|
||||||
|
viwmfs_help();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(*str == ':')
|
||||||
|
{
|
||||||
|
for(i = 0; i < strlen(str); str[i] = str[i + 1], ++i);
|
||||||
|
|
||||||
|
cmd = xstrdup(str);
|
||||||
|
|
||||||
|
for(i = 0; cmd[i] && cmd[i] != ' '; ++i);
|
||||||
|
cmd[i] = '\0';
|
||||||
|
|
||||||
|
for(i = 0; i < LEN(vicmd); ++i)
|
||||||
|
if(!strncmp(cmd, vicmd[i].cmd, strlen(cmd)))
|
||||||
|
{
|
||||||
|
exec_uicb_function(vicmd[i].uicb, clean_value(str + strlen(cmd)));
|
||||||
|
e = True;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For uicb function with normal name specified */
|
||||||
|
if(!e)
|
||||||
|
{
|
||||||
|
if(!strcmp(str, "h") || !strcmp(str, "help"))
|
||||||
|
viwmfs_help();
|
||||||
|
else
|
||||||
|
exec_uicb_function(cmd, str + strlen(cmd));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
888
src/wmfs.c
888
src/wmfs.c
File diff suppressed because it is too large
Load Diff
746
src/wmfs.h
746
src/wmfs.h
@ -1,423 +1,433 @@
|
|||||||
/*
|
/*
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
* wmfs.h
|
||||||
* For license, see COPYING.
|
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
|
||||||
*/
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of the nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef WMFS_H
|
#ifndef WMFS_H
|
||||||
#define WMFS_H
|
#define WMFS_H
|
||||||
|
|
||||||
/* Standard */
|
/* Lib headers */
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <locale.h>
|
#include <ctype.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <dirent.h>
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <sys/queue.h>
|
#include <pthread.h>
|
||||||
|
#include <sys/select.h>
|
||||||
/* Xlib */
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/time.h>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
|
#include <X11/cursorfont.h>
|
||||||
|
#include <X11/Xft/Xft.h>
|
||||||
|
|
||||||
/* Local */
|
/* Local headers */
|
||||||
#include "log.h"
|
#include "parse.h"
|
||||||
|
#include "structs.h"
|
||||||
|
|
||||||
#define CONFIG_DEFAULT_PATH ".config/wmfs/wmfsrc"
|
/* Optional dependencies */
|
||||||
|
#ifdef HAVE_XINERAMA
|
||||||
|
#include <X11/extensions/Xinerama.h>
|
||||||
|
#endif /* HAVE_XINERAMA */
|
||||||
|
|
||||||
|
#ifdef HAVE_XRANDR
|
||||||
|
#include <X11/extensions/Xrandr.h>
|
||||||
|
#endif /* HAVE_XRANDR */
|
||||||
|
|
||||||
|
#ifdef HAVE_IMLIB
|
||||||
|
#include <Imlib2.h>
|
||||||
|
#endif /* HAVE_IMLIB */
|
||||||
|
|
||||||
|
/* MACRO */
|
||||||
#define ButtonMask (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask)
|
#define ButtonMask (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask)
|
||||||
#define MouseMask (ButtonMask | PointerMotionMask)
|
#define MouseMask (ButtonMask | PointerMotionMask)
|
||||||
#define KeyMask (KeyPressMask | KeyReleaseMask)
|
#define KeyMask (KeyPressMask | KeyReleaseMask)
|
||||||
|
#define SCREEN DefaultScreen(dpy)
|
||||||
|
#define ROOT RootWindow(dpy, SCREEN)
|
||||||
|
#define MAXH DisplayHeight(dpy, DefaultScreen(dpy))
|
||||||
|
#define MAXW DisplayWidth(dpy, DefaultScreen(dpy))
|
||||||
|
#define INFOBARH ((conf.bars.height > 0) ? conf.bars.height : (font->height * 1.5))
|
||||||
|
#define FHINFOBAR ((font->height - font->descent) + (INFOBARH - font->height) / 2)
|
||||||
|
#define SHADH (1)
|
||||||
|
#define BORDH conf.client.borderheight
|
||||||
|
#define TBARH ((conf.titlebar.height < BORDH) ? BORDH : conf.titlebar.height)
|
||||||
|
#define RESHW (6 * (BORDH))
|
||||||
|
#define BUTTONWH (TBARH / 2)
|
||||||
|
#define DEF_CONF ".config/wmfs/wmfsrc"
|
||||||
|
#define DEF_STATUS ".config/wmfs/status.sh"
|
||||||
|
#define PAD conf.pad
|
||||||
|
#define MAXSTATUS (4096)
|
||||||
|
|
||||||
typedef unsigned long Flags;
|
#define CWIN(win, parent, x, y, w, h, b, mask, col, at) \
|
||||||
typedef unsigned int Color;
|
do { \
|
||||||
typedef const char* Uicb;
|
win = XCreateWindow(dpy, (parent), (x), (y), (w), (h), (b), CopyFromParent, \
|
||||||
|
InputOutput, CopyFromParent, (mask), (at)); \
|
||||||
|
XSetWindowBackground(dpy, win, (col)); \
|
||||||
|
} while (/* CONSTCOND */ 0)
|
||||||
|
|
||||||
enum barpos
|
#define ATOM(a) XInternAtom(dpy, (a), False)
|
||||||
{
|
#define FRAMEW(w) ((w) + BORDH * 2)
|
||||||
BarTop = 0,
|
#define FRAMEH(h) ((h) + (BORDH + TBARH))
|
||||||
BarBottom,
|
#define ROUND(x) (float)((x > 0) ? x + (float)0.5 : x - (float)0.5)
|
||||||
BarHide,
|
#define CHECK(x) if(!(x)) return
|
||||||
BarLast
|
#define LEN(x) (sizeof(x) / sizeof((x)[0]))
|
||||||
};
|
#define MAXCLIST (64)
|
||||||
|
|
||||||
enum position
|
/* barwin.c */
|
||||||
{
|
BarWindow *barwin_create(Window parent,
|
||||||
Right = 0,
|
int x, int y,
|
||||||
Left,
|
uint w, uint h,
|
||||||
Top,
|
uint bg, char*fg,
|
||||||
Bottom,
|
Bool entermask,
|
||||||
Center,
|
Bool stipple,
|
||||||
NoAlign,
|
Bool border);
|
||||||
PositionLast
|
void barwin_draw_text(BarWindow *bw, int x, int y, char *text);
|
||||||
};
|
void barwin_draw_image_ofset_text(BarWindow *bw, int x, int y, char *text, int x_image_ofset, int y_image_ofset);
|
||||||
|
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, uint w, uint h);
|
||||||
|
void barwin_refresh_color(BarWindow *bw);
|
||||||
|
void barwin_refresh(BarWindow *bw);
|
||||||
|
|
||||||
enum size_hints
|
/* draw.c */
|
||||||
{
|
void draw_text(Drawable d, int x, int y, char* fg, char *str);
|
||||||
BASEW, BASEH,
|
void draw_image_ofset_text(Drawable d, int x, int y, char* fg, char *str, int x_image_ofset, int y_image_ofset);
|
||||||
INCW, INCH,
|
void draw_rectangle(Drawable dr, int x, int y, uint w, uint h, uint color);
|
||||||
MAXW, MAXH,
|
void draw_graph(Drawable dr, int x, int y, uint w, uint h, uint color, char *data);
|
||||||
MINW, MINH,
|
|
||||||
MINAX, MINAY,
|
|
||||||
MAXAX, MAXAY,
|
|
||||||
SHLAST
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
ushort textw(char *text);
|
||||||
* Structures
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct geo
|
/* infobar.c */
|
||||||
{
|
void infobar_init(void);
|
||||||
int x, y, w, h;
|
void infobar_draw(int sc);
|
||||||
};
|
void infobar_draw_selbar(int sc);
|
||||||
|
void infobar_draw_taglist(int sc);
|
||||||
|
void infobar_update_taglist(int sc);
|
||||||
|
void infobar_destroy(void);
|
||||||
|
void infobar_set_position(int pos);
|
||||||
|
void uicb_infobar_togglepos(uicb_t);
|
||||||
|
void uicb_infobar_toggledisplay(uicb_t);
|
||||||
|
void uicb_toggle_tagautohide(uicb_t);
|
||||||
|
|
||||||
struct geo_list
|
/* client.c */
|
||||||
{
|
void client_attach(Client *c);
|
||||||
struct geo geo;
|
void client_configure(Client *c);
|
||||||
SLIST_ENTRY(geo_list) next;
|
void client_detach(Client *c);
|
||||||
};
|
void client_focus(Client *c);
|
||||||
|
/* client_gb_*() {{{ */
|
||||||
|
Client* client_gb_win(Window w);
|
||||||
|
Client* client_gb_frame(Window w);
|
||||||
|
Client* client_gb_titlebar(Window w);
|
||||||
|
Client* client_gb_resize(Window w);
|
||||||
|
Client* client_gb_button(Window w, int *n);
|
||||||
|
/* }}} */
|
||||||
|
void client_get_name(Client *c);
|
||||||
|
void client_hide(Client *c);
|
||||||
|
void client_kill(Client *c);
|
||||||
|
Bool ishide(Client *c, int screen);
|
||||||
|
void client_map(Client *c);
|
||||||
|
Client* client_manage(Window w, XWindowAttributes *wa, Bool ar);
|
||||||
|
void client_geo_hints(XRectangle *geo, Client *c);
|
||||||
|
void client_moveresize(Client *c, XRectangle geo, Bool r);
|
||||||
|
void client_maximize(Client *c);
|
||||||
|
void client_size_hints(Client *c);
|
||||||
|
void client_swap(Client *c1, Client *c2);
|
||||||
|
void client_raise(Client *c);
|
||||||
|
void client_unhide(Client *c);
|
||||||
|
void client_focus_next(Client *c);
|
||||||
|
void client_unmanage(Client *c);
|
||||||
|
void client_unmap(Client *c);
|
||||||
|
void client_update_attributes(Client *c);
|
||||||
|
void client_urgent(Client *c, Bool u);
|
||||||
|
void uicb_client_raise(uicb_t);
|
||||||
|
void uicb_client_next(uicb_t);
|
||||||
|
void uicb_client_prev(uicb_t);
|
||||||
|
void uicb_client_swap_next(uicb_t);
|
||||||
|
void uicb_client_swap_prev(uicb_t);
|
||||||
|
void uicb_client_focus_right(uicb_t cmd);
|
||||||
|
void uicb_client_focus_left(uicb_t cmd);
|
||||||
|
void uicb_client_focus_top(uicb_t cmd);
|
||||||
|
void uicb_client_focus_bottom(uicb_t cmd);
|
||||||
|
void uicb_client_kill(uicb_t);
|
||||||
|
void uicb_client_screen_next(uicb_t);
|
||||||
|
void uicb_client_screen_prev(uicb_t);
|
||||||
|
void uicb_client_screen_set(uicb_t);
|
||||||
|
void uicb_client_move(uicb_t cmd);
|
||||||
|
void uicb_client_resize(uicb_t cmd);
|
||||||
|
void uicb_ignore_next_client_rules(uicb_t cmd);
|
||||||
|
void uicb_clientlist(uicb_t cmd);
|
||||||
|
Bool uicb_checkclist(uicb_t);
|
||||||
|
void uicb_client_ignore_tag(uicb_t);
|
||||||
|
void uicb_client_set_master(uicb_t);
|
||||||
|
|
||||||
struct colpair
|
/* ewmh.c */
|
||||||
{
|
void ewmh_init_hints(void);
|
||||||
Color fg, bg;
|
void ewmh_send_message(Window d, Window w, char *atom, long d0, long d1, long d2, long d3, long d4);
|
||||||
};
|
long ewmh_get_xembed_state(Window win);
|
||||||
|
void ewmh_get_number_of_desktop(void);
|
||||||
|
void ewmh_update_current_tag_prop(void);
|
||||||
|
void ewmh_get_client_list(void);
|
||||||
|
void ewmh_get_desktop_names(void);
|
||||||
|
void ewmh_set_desktop_geometry(void);
|
||||||
|
void ewmh_manage_net_wm_state(long data_l[], Client *c);
|
||||||
|
void ewmh_manage_window_type(Client *c);
|
||||||
|
|
||||||
struct barwin
|
/* frame.c */
|
||||||
{
|
void frame_create(Client *c);
|
||||||
struct geo geo;
|
void frame_delete(Client *c);
|
||||||
Window win;
|
void frame_moveresize(Client *c, XRectangle geo);
|
||||||
Drawable dr;
|
void frame_update_color(Client *c, Bool focused);
|
||||||
Color fg, bg;
|
void frame_update(Client *c);
|
||||||
void *ptr; /* Special cases */
|
|
||||||
SLIST_HEAD(mbhead, mousebind) mousebinds;
|
|
||||||
SLIST_HEAD(, mousebind) statusmousebinds;
|
|
||||||
SLIST_ENTRY(barwin) next; /* global barwin */
|
|
||||||
SLIST_ENTRY(barwin) enext; /* element barwin */
|
|
||||||
SLIST_ENTRY(barwin) vnext; /* volatile barwin */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct status_seq
|
/* config.c */
|
||||||
{
|
void init_conf(void);
|
||||||
struct geo geo;
|
|
||||||
enum position align;
|
|
||||||
int data[4];
|
|
||||||
char type;
|
|
||||||
char *str;
|
|
||||||
Color color, color2;
|
|
||||||
SLIST_HEAD(, mousebind) mousebinds;
|
|
||||||
SLIST_ENTRY(status_seq) next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct status_ctx
|
/* color.c */
|
||||||
{
|
uint color_shade(uint, double);
|
||||||
struct barwin *barwin;
|
|
||||||
struct theme *theme;
|
|
||||||
#define STATUS_BLOCK_REFRESH 0x01
|
|
||||||
Flags flags;
|
|
||||||
char *status;
|
|
||||||
bool update;
|
|
||||||
SLIST_HEAD(, status_gcache) gcache;
|
|
||||||
SLIST_HEAD(, status_seq) statushead;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct status_gcache
|
/* event.c */
|
||||||
{
|
void grabkeys(void);
|
||||||
char *name;
|
void getevent(XEvent ev);
|
||||||
int *datas;
|
|
||||||
int ndata;
|
|
||||||
SLIST_ENTRY(status_gcache) next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct element
|
/* menu.c */
|
||||||
{
|
void menu_init(Menu *menu, char *name, int nitem, uint bg_f, char *fg_f, uint bg_n, char *fg_n);
|
||||||
struct geo geo;
|
void menu_new_item(MenuItem *mi, char *name, void *func, char *cmd);
|
||||||
struct infobar *infobar;
|
void menu_draw(Menu menu, int x, int y);
|
||||||
struct status_ctx *statusctx;
|
void uicb_menu(uicb_t cmd);
|
||||||
int type;
|
void menu_clear(Menu *menu);
|
||||||
char *data;
|
|
||||||
enum position align;
|
|
||||||
void (*func_init)(struct element *e);
|
|
||||||
void (*func_update)(struct element *e);
|
|
||||||
SLIST_HEAD(, barwin) bars;
|
|
||||||
TAILQ_ENTRY(element) next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct infobar
|
/* launcher.c */
|
||||||
{
|
void uicb_launcher(uicb_t);
|
||||||
struct barwin *bar;
|
|
||||||
struct geo geo;
|
|
||||||
struct screen *screen;
|
|
||||||
struct theme *theme;
|
|
||||||
struct status_ctx statusctx;
|
|
||||||
enum barpos opos, pos;
|
|
||||||
char *elemorder;
|
|
||||||
char *name;
|
|
||||||
TAILQ_HEAD(esub, element) elements;
|
|
||||||
SLIST_ENTRY(infobar) next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct screen
|
/* mouse.c */
|
||||||
{
|
void mouse_resize(Client *c);
|
||||||
struct geo geo, ugeo;
|
void mouse_grabbuttons(Client *c, Bool focused);
|
||||||
struct tag *seltag;
|
void uicb_mouse_move(uicb_t);
|
||||||
#define SCREEN_TAG_UPDATE 0x01
|
void uicb_mouse_resize(uicb_t);
|
||||||
Flags flags;
|
|
||||||
int id;
|
|
||||||
TAILQ_HEAD(tsub, tag) tags;
|
|
||||||
SLIST_HEAD(, infobar) infobars;
|
|
||||||
SLIST_ENTRY(screen) next;
|
|
||||||
};
|
|
||||||
|
|
||||||
SLIST_HEAD(chead, client);
|
/* util.c */
|
||||||
|
void *xmalloc(size_t, size_t);
|
||||||
|
void *xcalloc(size_t, size_t);
|
||||||
|
void *xrealloc(void *, size_t, size_t);
|
||||||
|
/* simples wrappers for allocating only one object */
|
||||||
|
#define zmalloc(size) xmalloc(1, (size))
|
||||||
|
#define zcalloc(size) xcalloc(1, (size))
|
||||||
|
#define zrealloc(ptr, size) xrealloc((ptr), 1, (size))
|
||||||
|
char *xstrdup(const char *);
|
||||||
|
int xasprintf(char **, const char *, ...);
|
||||||
|
long getcolor(char *color);
|
||||||
|
void setwinstate(Window win, long state);
|
||||||
|
/* Conf usage {{{ */
|
||||||
|
void* name_to_func(char *name, const func_name_list_t *l);
|
||||||
|
ulong char_to_modkey(char *name, key_name_list_t key_l[]);
|
||||||
|
uint char_to_button(char *name, name_to_uint_t blist[]);
|
||||||
|
Layout layout_name_to_struct(Layout lt[], char *name, int n, const func_name_list_t llist[]);
|
||||||
|
/* }}} */
|
||||||
|
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);
|
||||||
|
|
||||||
struct tag
|
#ifdef HAVE_IMLIB
|
||||||
{
|
int parse_image_block(ImageAttr *im, char *str);
|
||||||
struct screen *screen;
|
#endif /* HAVE_IMLIB */
|
||||||
struct client *sel;
|
|
||||||
struct client *prevsel;
|
|
||||||
struct tag *prev;
|
|
||||||
struct status_ctx statusctx;
|
|
||||||
char *name;
|
|
||||||
int id;
|
|
||||||
#define TAG_URGENT 0x01
|
|
||||||
#define TAG_IGNORE_ENTER 0x02
|
|
||||||
Flags flags;
|
|
||||||
SLIST_HEAD(, client) clients;
|
|
||||||
TAILQ_HEAD(ssub, layout_set) sets;
|
|
||||||
TAILQ_ENTRY(tag) next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct client
|
/* tag.c */
|
||||||
{
|
void tag_set(int tag);
|
||||||
struct tag *tag, *prevtag;
|
void tag_transfert(Client *c, int tag);
|
||||||
struct screen *screen;
|
void uicb_tag(uicb_t);
|
||||||
struct barwin *titlebar;
|
void uicb_tag_next(uicb_t);
|
||||||
struct geo geo, wgeo, tgeo, ttgeo, rgeo, *tbgeo;
|
void uicb_tag_prev(uicb_t);
|
||||||
struct colpair ncol, scol;
|
void uicb_tag_next_visible(uicb_t);
|
||||||
struct theme *theme;
|
void uicb_tag_prev_visible(uicb_t);
|
||||||
struct client *tabmaster;
|
void uicb_tagtransfert(uicb_t);
|
||||||
int sizeh[SHLAST];
|
void uicb_tag_prev_sel(uicb_t);
|
||||||
char *title;
|
void uicb_tagtransfert_next(uicb_t);
|
||||||
int border, tbarw;
|
void uicb_tagtransfert_prev(uicb_t);
|
||||||
#define CLIENT_HINT_FLAG 0x01
|
void uicb_tag_urgent(uicb_t cmd);
|
||||||
#define CLIENT_IGNORE_ENTER 0x02
|
void tag_additional(int sc, int tag, int adtag);
|
||||||
#define CLIENT_DID_WINSIZE 0x04
|
void uicb_tag_toggle_additional(uicb_t);
|
||||||
#define CLIENT_FAC_APPLIED 0x08
|
void uicb_tag_swap(uicb_t);
|
||||||
#define CLIENT_IGNORE_LAYOUT 0x10
|
void uicb_tag_swap_next(uicb_t);
|
||||||
#define CLIENT_RULED 0x20
|
void uicb_tag_swap_previous(uicb_t);
|
||||||
#define CLIENT_TABBED 0x40
|
void uicb_tag_new(uicb_t);
|
||||||
#define CLIENT_TABMASTER 0x80
|
void uicb_tag_del(uicb_t);
|
||||||
#define CLIENT_DYING 0x100 /* Saddest flag ever */
|
void uicb_tag_rename(uicb_t cmd);
|
||||||
#define CLIENT_REMOVEALL 0x200
|
void uicb_tag_last(uicb_t cmd);
|
||||||
#define CLIENT_MAPPED 0x400
|
void uicb_tag_stay_last(uicb_t cmd);
|
||||||
#define CLIENT_FULLSCREEN 0x800
|
void uicb_tag_toggle_expose(uicb_t cmd);
|
||||||
#define CLIENT_FREE 0x1000
|
|
||||||
#define CLIENT_TILED 0x2000
|
|
||||||
#define CLIENT_MOUSE 0x4000
|
|
||||||
#define CLIENT_IGNORE_TAG 0x8000
|
|
||||||
Flags flags;
|
|
||||||
Window win, frame, tmp;
|
|
||||||
SLIST_ENTRY(client) next; /* Global list */
|
|
||||||
SLIST_ENTRY(client) tnext; /* struct tag list */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct layout_set
|
/* screen.c */
|
||||||
{
|
int screen_count(void);
|
||||||
int n;
|
XRectangle screen_get_geo(int s);
|
||||||
SLIST_HEAD(, geo_list) geos;
|
int screen_get_with_geo(int x, int y);
|
||||||
TAILQ_ENTRY(layout_set) next;
|
int screen_get_sel(void);
|
||||||
};
|
void screen_set_sel(int screen);
|
||||||
|
void screen_init_geo(void);
|
||||||
|
void uicb_screen_select(uicb_t);
|
||||||
|
void uicb_screen_next(uicb_t);
|
||||||
|
void uicb_screen_prev(uicb_t);
|
||||||
|
void uicb_screen_prev_sel(uicb_t);
|
||||||
|
|
||||||
struct keybind
|
/* status.c */
|
||||||
{
|
void statustext_handle(int sc, char *str);
|
||||||
unsigned int mod;
|
|
||||||
void (*func)(Uicb);
|
|
||||||
Uicb cmd;
|
|
||||||
KeySym keysym;
|
|
||||||
SLIST_ENTRY(keybind) next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct mousebind
|
/* systray.c */
|
||||||
{
|
Bool systray_acquire(void);
|
||||||
struct geo area;
|
void systray_add(Window win);
|
||||||
unsigned int button;
|
void systray_del(Systray *s);
|
||||||
bool use_area;
|
void systray_state(Systray *s);
|
||||||
void (*func)(Uicb);
|
void systray_freeicons(void);
|
||||||
Uicb cmd;
|
Systray* systray_find(Window win);
|
||||||
SLIST_ENTRY(mousebind) next;
|
int systray_get_width(void);
|
||||||
SLIST_ENTRY(mousebind) snext;
|
void systray_update(void);
|
||||||
SLIST_ENTRY(mousebind) globnext;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct theme
|
/* layout.c */
|
||||||
{
|
void arrange(int screen, Bool update_layout);
|
||||||
char *name;
|
void freelayout(int screen);
|
||||||
|
void layoutswitch(Bool b);
|
||||||
|
void maxlayout(int screen);
|
||||||
|
/* tile {{{ */
|
||||||
|
void tile(int screen);
|
||||||
|
void tile_left(int screen);
|
||||||
|
void tile_top(int screen);
|
||||||
|
void tile_bottom(int screen);
|
||||||
|
void mirror_vertical(int screen);
|
||||||
|
void mirror_horizontal(int screen);
|
||||||
|
void grid_vertical(int screen);
|
||||||
|
void grid_horizontal(int screen);
|
||||||
|
/* }}} */
|
||||||
|
void uicb_togglemax(uicb_t);
|
||||||
|
void uicb_togglefree(uicb_t);
|
||||||
|
void uicb_layout_prev(uicb_t);
|
||||||
|
void uicb_layout_next(uicb_t);
|
||||||
|
void uicb_set_mwfact(uicb_t);
|
||||||
|
void uicb_set_nmaster(uicb_t);
|
||||||
|
void uicb_set_layout(uicb_t);
|
||||||
|
void uicb_toggle_resizehint(uicb_t);
|
||||||
|
void uicb_toggle_abovefc(uicb_t cmd);
|
||||||
|
void layout_set_client_master(Client *c);
|
||||||
|
Bool uicb_checkmax(uicb_t);
|
||||||
|
Bool uicb_checkfree(uicb_t);
|
||||||
|
Bool uicb_checklayout(uicb_t);
|
||||||
|
|
||||||
/* Font */
|
/* init.c */
|
||||||
struct
|
void init(void);
|
||||||
{
|
|
||||||
int as, de, width, height;
|
|
||||||
XFontSet fontset;
|
|
||||||
} font;
|
|
||||||
|
|
||||||
/* Bars */
|
/* getinfo.c */
|
||||||
struct colpair bars;
|
void getinfo(char *info);
|
||||||
int bars_width;
|
|
||||||
|
|
||||||
/* struct elements */
|
/* viwmfs.c */
|
||||||
struct colpair tags_n, tags_s, tags_o, tags_u; /* normal / selected / occupied */
|
void viwmfs(int argc, char **argv);
|
||||||
struct status_ctx tags_n_sl, tags_s_sl, tags_o_sl, tags_u_sl; /* status line */
|
|
||||||
int tags_border_width;
|
|
||||||
Color tags_border_col;
|
|
||||||
|
|
||||||
/* client / frame */
|
/* wmfs.c */
|
||||||
struct colpair client_n, client_s;
|
int errorhandler(Display *d, XErrorEvent *event);
|
||||||
struct status_ctx client_n_sl, client_s_sl, client_f_sl;
|
int errorhandlerdummy(Display *d, XErrorEvent *event);
|
||||||
Color frame_bg;
|
void quit(void);
|
||||||
int client_titlebar_width;
|
void *thread_process(void *arg);
|
||||||
int client_border_width;
|
Bool check_wmfs_running(void);
|
||||||
|
void exec_uicb_function(char *func, char *cmd);
|
||||||
|
void handle_signal(int signum);
|
||||||
|
void uicb_quit(uicb_t);
|
||||||
|
void uicb_reload(uicb_t);
|
||||||
|
|
||||||
SLIST_ENTRY(theme) next;
|
/* Variables */
|
||||||
};
|
|
||||||
|
|
||||||
struct rule
|
/* Principal */
|
||||||
{
|
Display *dpy;
|
||||||
struct theme *theme;
|
GC gc, gc_stipple;
|
||||||
char *class;
|
int selscreen;
|
||||||
char *instance;
|
int prevselscreen;
|
||||||
char *role;
|
Conf conf;
|
||||||
char *name;
|
Key *keys;
|
||||||
int tag, screen;
|
Bool estatus;
|
||||||
#define RULE_FREE 0x01
|
XRectangle *sgeo;
|
||||||
#define RULE_TAB 0x02
|
XRectangle *spgeo;
|
||||||
#define RULE_IGNORE_TAG 0x04
|
Cursor cursor[CurLast];
|
||||||
Flags flags;
|
char *argv_global;
|
||||||
SLIST_ENTRY(rule) next;
|
char **all_argv;
|
||||||
};
|
int xrandr_event;
|
||||||
|
uint timing;
|
||||||
|
|
||||||
struct launcher
|
/* Fonts */
|
||||||
{
|
XftFont *font;
|
||||||
char *name;
|
|
||||||
char *prompt;
|
|
||||||
char *command;
|
|
||||||
#define HISTOLEN 64
|
|
||||||
char histo[HISTOLEN][256];
|
|
||||||
int nhisto;
|
|
||||||
int width;
|
|
||||||
SLIST_ENTRY(launcher) next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct launcher_ccache
|
/* Atoms list */
|
||||||
{
|
Atom *net_atom;
|
||||||
char *start;
|
Atom trayatom;
|
||||||
char **namelist;
|
|
||||||
size_t hits;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _systray
|
/* InfoBar/Tags */
|
||||||
{
|
InfoBar *infobar;
|
||||||
struct geo geo;
|
Tag **tags;
|
||||||
Window win;
|
int *seltag;
|
||||||
SLIST_ENTRY(_systray) next;
|
int *prevseltag;
|
||||||
};
|
Menu menulayout;
|
||||||
|
|
||||||
#define MAX_PATH_LEN 8192
|
/* ClientList */
|
||||||
|
Menu clientlist;
|
||||||
|
struct clndx {
|
||||||
|
char key[4];
|
||||||
|
Client *client;
|
||||||
|
} clist_index[MAXCLIST];
|
||||||
|
|
||||||
struct wmfs
|
/* Important Client */
|
||||||
{
|
Client *clients;
|
||||||
/* X11 stuffs */
|
Client *sel;
|
||||||
Display *dpy;
|
|
||||||
Window root;
|
|
||||||
int xscreen, xdepth;
|
|
||||||
int xmaxw, xmaxh;
|
|
||||||
int nscreen;
|
|
||||||
unsigned int client_mod;
|
|
||||||
Flags numlockmask;
|
|
||||||
#define WMFS_SCAN 0x001
|
|
||||||
#define WMFS_RUNNING 0x002
|
|
||||||
#define WMFS_RELOAD 0x004
|
|
||||||
#define WMFS_SYSTRAY 0x008
|
|
||||||
#define WMFS_LOG 0x010
|
|
||||||
#define WMFS_LAUNCHER 0x020
|
|
||||||
#define WMFS_SIGCHLD 0x040
|
|
||||||
#define WMFS_TABNOC 0x080 /* tab next opened client */
|
|
||||||
#define WMFS_TAGCIRC 0x100 /* tab_next on last tag -> go to first tag / tab_prev on first tag -> go to last tag */
|
|
||||||
#define WMFS_AUTOFOCUS 0x200
|
|
||||||
Flags flags;
|
|
||||||
GC gc, rgc;
|
|
||||||
Atom *net_atom;
|
|
||||||
char **argv;
|
|
||||||
char *confpath;
|
|
||||||
struct barwin *last_clicked_barwin;
|
|
||||||
struct theme *ctheme;
|
|
||||||
#define CFOCUS_ENTER 0x01
|
|
||||||
#define CFOCUS_CLICK 0x02
|
|
||||||
Flags cfocus; /* Focus configuration, can be set to 0, CFOCUS_ENTER or CFOCUS_CLICK*/
|
|
||||||
|
|
||||||
int padding;
|
/* Other */
|
||||||
|
extern const func_name_list_t func_list[];
|
||||||
/* Log file */
|
extern const func_name_list_t layout_list[];
|
||||||
FILE *log;
|
uint numlockmask;
|
||||||
|
Systray *trayicons;
|
||||||
/* Lists heads */
|
Window traywin;
|
||||||
struct
|
int tray_width;
|
||||||
{
|
|
||||||
SLIST_HEAD(, screen) screen;
|
|
||||||
SLIST_HEAD(, client) client;
|
|
||||||
SLIST_HEAD(, keybind) keybind;
|
|
||||||
SLIST_HEAD(, barwin) barwin;
|
|
||||||
SLIST_HEAD(, theme) theme;
|
|
||||||
SLIST_HEAD(, rule) rule;
|
|
||||||
SLIST_HEAD(, mousebind) mousebind;
|
|
||||||
SLIST_HEAD(, launcher) launcher;
|
|
||||||
SLIST_HEAD(, barwin) vbarwin;
|
|
||||||
} h;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Temporary head of mousebind list from config
|
|
||||||
* Will be copied in barwin of clickable drawable
|
|
||||||
* later in code
|
|
||||||
*/
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
struct mbhead tag;
|
|
||||||
struct mbhead client;
|
|
||||||
struct mbhead root;
|
|
||||||
} tmp_head;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Because there is only one systray per display,
|
|
||||||
* set struct there
|
|
||||||
*/
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
struct barwin *barwin;
|
|
||||||
struct infobar *infobar;
|
|
||||||
bool redim;
|
|
||||||
Window win;
|
|
||||||
SLIST_HEAD(, _systray) head;
|
|
||||||
} systray;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Selected screen, client
|
|
||||||
*/
|
|
||||||
struct screen *screen;
|
|
||||||
struct client *client;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
int wmfs_error_handler(Display *d, XErrorEvent *event);
|
|
||||||
int wmfs_error_handler_dummy(Display *d, XErrorEvent *event);
|
|
||||||
void wmfs_grab_keys(void);
|
|
||||||
void wmfs_numlockmask(void);
|
|
||||||
void wmfs_init_font(char *font, struct theme *t);
|
|
||||||
void wmfs_quit(void);
|
|
||||||
void uicb_reload(Uicb cmd);
|
|
||||||
void uicb_quit(Uicb cmd);
|
|
||||||
|
|
||||||
/* Single global variable */
|
|
||||||
struct wmfs *W;
|
|
||||||
|
|
||||||
#endif /* WMFS_H */
|
#endif /* WMFS_H */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
731
wmfs.1
731
wmfs.1
@ -1,8 +1,11 @@
|
|||||||
.\" title: wmfs
|
.\" Title: wmfs
|
||||||
.\" dev: xorg62
|
.\" Author:
|
||||||
.\" man: arpinux
|
.\" Generator: DocBook XSL Stylesheets v1.73.2 <http://docbook.sf.net/>
|
||||||
|
.\" Date: 04/22/2009
|
||||||
|
.\" Manual: manual of wmfs
|
||||||
|
.\" Source: wmfs 0.1rc4 (On The Run)
|
||||||
.\"
|
.\"
|
||||||
.TH "WMFS" "1" "2012/05/02" "wmfs" "manual of wmfs"
|
.TH "WMFS" "1" "04/22/2009" "wmfs 0\&.1rc4 (On The Run)" "manual of wmfs"
|
||||||
.\" disable hyphenation
|
.\" disable hyphenation
|
||||||
.nh
|
.nh
|
||||||
.\" disable justification (adjust text to left margin only)
|
.\" disable justification (adjust text to left margin only)
|
||||||
@ -10,10 +13,10 @@
|
|||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
wmfs \- Window Manager From Scratch
|
wmfs \- Window Manager From Scratch
|
||||||
.SH "SYNOPSIS"
|
.SH "SYNOPSIS"
|
||||||
\fBwmfs\fR [\fB\-hv\fR] [\fB\-C <file>\fR] [\fB\-c <uicb_function> <cmd>\fR]
|
\fBwmfs\fR [\fB\-ihvS\fR] [\fB\-C <file>\fR] [\fB\-c <uicb_function> <cmd>\fR] [\fB\-g <argument>\fR] [\fB\-s <screen_num> <string>\fR] [\fB\-V <viwmfs cmd>\fR]
|
||||||
.sp
|
.sp
|
||||||
.SH "DESCRIPTION"
|
.SH "DESCRIPTION"
|
||||||
\fBWMFS\fR is a lightweight and highly configurable tiling window manager for X written in C\&.
|
\fBWMFS\fR is a basic, lightweight and dynamic tiling windows manager for X\&.
|
||||||
.sp
|
.sp
|
||||||
.SH "OPTIONS"
|
.SH "OPTIONS"
|
||||||
.PP
|
.PP
|
||||||
@ -27,6 +30,26 @@ Load a configuration file\&.
|
|||||||
Execute an uicb function to control WMFS\&.
|
Execute an uicb function to control WMFS\&.
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
|
\fB\-g <argument>\fR
|
||||||
|
.RS 4
|
||||||
|
Show information about wmfs status\&.
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
\fB\-s <screen_num> <string>\fR
|
||||||
|
.RS 4
|
||||||
|
Set the bar(s) statustext. If the screen number is not specified, the string will be show on all screens bars\&.
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
\fB\-V <viwmfs cmd>\fR
|
||||||
|
.RS 4
|
||||||
|
Manage WMFS with vi-like command\&.
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
\fB\-S\fR
|
||||||
|
.RS 4
|
||||||
|
Update status script\&.
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
\fB\-v\fR
|
\fB\-v\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Print version information to standard output, then exit\&.
|
Print version information to standard output, then exit\&.
|
||||||
@ -36,6 +59,11 @@ Print version information to standard output, then exit\&.
|
|||||||
.RS 4
|
.RS 4
|
||||||
Print help information, then exit\&.
|
Print help information, then exit\&.
|
||||||
.RE
|
.RE
|
||||||
|
.PP
|
||||||
|
\fB\-i\fR
|
||||||
|
.RS 4
|
||||||
|
Print WMFS information
|
||||||
|
.RE
|
||||||
.SH "DEFAULT KEY BINDINGS"
|
.SH "DEFAULT KEY BINDINGS"
|
||||||
.PP
|
.PP
|
||||||
\fBControl\-Alt + r\fR
|
\fBControl\-Alt + r\fR
|
||||||
@ -43,34 +71,29 @@ Print help information, then exit\&.
|
|||||||
Reload WMFS binary
|
Reload WMFS binary
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBSuper + Return\fR
|
\fBControl + Return\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Run a terminal (urxvt by default)
|
Run a terminal (urxvt by default)
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBSuper + q\fR
|
\fBAlt + q\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Quit the selected client
|
Quit the selected client
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBControl\-Alt + q\fR
|
\fBControl\-Alt\-Shift + q\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Exit WMFS
|
Exit WMFS
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBSuper + f \fR
|
\fBAlt + m \fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Toggle free the selected client
|
Toggle maximize the selected client
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBSuper + Shift + f \fR
|
\fBAlt + b \fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Toggle ignore_tag the selected client
|
Toggle the bar position between top, hide and bottom
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper + Shift + h \fR
|
|
||||||
.RS 4
|
|
||||||
Toggle infobar visibility
|
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBAlt + Tab\fR
|
\fBAlt + Tab\fR
|
||||||
@ -83,121 +106,6 @@ Give the focus to the next client
|
|||||||
Give the focus to the previous client
|
Give the focus to the previous client
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBAlt + h\fR
|
|
||||||
.RS 4
|
|
||||||
Give the focus to the client on the left
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBAlt + l\fR
|
|
||||||
.RS 4
|
|
||||||
Give the focus to the client on the right
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBAlt + k\fR
|
|
||||||
.RS 4
|
|
||||||
Give the focus to the client on the top
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBAlt + j\fR
|
|
||||||
.RS 4
|
|
||||||
Give the focus to the client on the bottom
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper + Tab\fR
|
|
||||||
.RS 4
|
|
||||||
Give the focus to the next tabbed client
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper\-Shift + Tab\fR
|
|
||||||
.RS 4
|
|
||||||
Give the focus to the previous tabbed client
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBControl\-Shift + h\fR
|
|
||||||
.RS 4
|
|
||||||
Swap with the client on the left
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBControl\-Shift + l\fR
|
|
||||||
.RS 4
|
|
||||||
Swap with the client on the right
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBControl\-Shift + k\fR
|
|
||||||
.RS 4
|
|
||||||
Swap with the client on the top
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBControl\-Shift + j\fR
|
|
||||||
.RS 4
|
|
||||||
Swap with the client on the bottom
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBAlt\-Shift + h\fR
|
|
||||||
.RS 4
|
|
||||||
Tab in the client on the left
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBAlt\-Shift + l\fR
|
|
||||||
.RS 4
|
|
||||||
Tab in the client on the right
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBAlt\-Shift + k\fR
|
|
||||||
.RS 4
|
|
||||||
Tab in the client on the top
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBAlt\-Shift + j\fR
|
|
||||||
.RS 4
|
|
||||||
Tab in the client on the bottom
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBAlt\-Shift + u\fR
|
|
||||||
.RS 4
|
|
||||||
Untab the client
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper + h\fR
|
|
||||||
.RS 4
|
|
||||||
Increase the client to the left
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper + l\fR
|
|
||||||
.RS 4
|
|
||||||
Decrease the client from the left
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper + k\fR
|
|
||||||
.RS 4
|
|
||||||
Increase the client to the top
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper + j\fR
|
|
||||||
.RS 4
|
|
||||||
Decrease the client from the top
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper\-Control + h\fR
|
|
||||||
.RS 4
|
|
||||||
Decrease the client from the right
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper\-Control + l\fR
|
|
||||||
.RS 4
|
|
||||||
Increase the client to the right
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper\-Control + k\fR
|
|
||||||
.RS 4
|
|
||||||
Decrease the client from the bottom
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper\-Control + j\fR
|
|
||||||
.RS 4
|
|
||||||
Increase the client to the bottom
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBControl + Right\fR
|
\fBControl + Right\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Next tag
|
Next tag
|
||||||
@ -208,581 +116,88 @@ Next tag
|
|||||||
Previous tag
|
Previous tag
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBControl + Up\fR
|
\fBAlt + Space\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Next screen
|
Next layout
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBControl + Down\fR
|
\fBAlt\-Shift + Space\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Previous screen
|
Previous layout
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBSuper + m\fR
|
\fBAlt + l\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Vertical mirror layout
|
Increase the mwfact (+0\&.025)
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBSuper\-Shift + m\fR
|
\fBAlt + h\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Horizontal mirror layout
|
Decrease the mwfact (\-0\&.025)
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBSuper + r\fR
|
\fBAlt + d\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Rotate layout right
|
Increase the nmaster (+1)\fR
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBSuper\-Shift + r\fR
|
\fBAlt\-Shift + d\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Rotate layout left
|
Decrease the nmaster (\-1)\fR
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBSuper\-Control\-Alt + h\fR
|
\fBAlt + t\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Integrate client in left layout
|
Swap the current client with the next\fR
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBSuper\-Control\-Alt + j\fR
|
\fBAlt\-Shift + t\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Integrate client in bottom layout
|
Swap the current client with the previous\fR
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBSuper\-Control\-Alt + k\fR
|
\fBAlt + p\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Integrate client in top layout
|
Make a launcher in the infobar to run an unix command\fR
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBSuper\-Control\-Alt + l\fR
|
\fBAlt + Escape\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Integrate client in right layout
|
Set WMFS in ViWMFS mode. (see wmfs \-V)\fR
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBSuper + o\fR
|
\fBAlt\-Shift + p\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Restore previous layout
|
Make a launcher in the infobar to run an ssh session\fR
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBSuper\-Shift + o\fR
|
\fBAlt + F[1\&.\&.9]\fR
|
||||||
.RS 4
|
|
||||||
Restore next layout
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper + p\fR
|
|
||||||
.RS 4
|
|
||||||
Display a launcher in the statusbar to run an unix command\fR
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper + F[1\&.\&.9]\fR
|
|
||||||
.RS 4
|
.RS 4
|
||||||
Change tag view
|
Change tag view
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBSuper\-Shift + F[1\&.\&.9]\fR
|
\fBControl\-Shift +F[1\&.\&.9]\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Transfert the selected client to the wanted tag
|
Transfert the selected client to the wanted tag
|
||||||
.RE
|
.RE
|
||||||
.PP
|
|
||||||
\fBSuper + -\fR
|
|
||||||
.RS 4
|
|
||||||
Delete current tag\fR
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper\-Shift + -\fR
|
|
||||||
.RS 4
|
|
||||||
Add current tag\fR
|
|
||||||
.RE
|
|
||||||
.SH "CONFIGURATION"
|
.SH "CONFIGURATION"
|
||||||
WMFS is configured by \fI$HOME/\&.config/wmfs/wmfsrc\fR\&.
|
WMFS is configured by \fI$HOME/\&.config/wmfs/wmfsrc\fR\&.
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ include:\fR
|
|
||||||
wmfsrc supports ”@include” to split configuration file by section\&.
|
|
||||||
.RS 2
|
|
||||||
\fB\ Usage:\fR "@include ~/.config/wmfs/wmfs_themes"\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ [themes]\fR
|
|
||||||
wmfsrc supports themes for client and statusbar\&.
|
|
||||||
.RS 2
|
|
||||||
\fB Misc\fR
|
|
||||||
.RS 2
|
|
||||||
\fB\ name:\fR
|
|
||||||
theme name, will be used in next sections\&.
|
|
||||||
.PP
|
|
||||||
\fB\ font:\fR
|
|
||||||
theme font in XLFD format\&.
|
|
||||||
.PP
|
|
||||||
.RE
|
|
||||||
\fB\ Bars\fR
|
|
||||||
.RS 2
|
|
||||||
\fB\ bars_width:\fR
|
|
||||||
bar height in pixels\&.
|
|
||||||
.PP
|
|
||||||
\fB\ bars_fg/bg:\fR
|
|
||||||
statusbar text/background color\&.
|
|
||||||
.PP
|
|
||||||
.RE
|
|
||||||
\fB\ Tags\fR
|
|
||||||
.RS 2
|
|
||||||
\fB\ tags_normal_fg/bg:\fR
|
|
||||||
normal tag text/button color\&.
|
|
||||||
.PP
|
|
||||||
\fB\ tags_normal_statusline:\fR
|
|
||||||
normal tag statusline\&.
|
|
||||||
.PP
|
|
||||||
\fB\ tags_sel_fg/bg:\fR
|
|
||||||
selected tag text/button color\&.
|
|
||||||
.PP
|
|
||||||
\fB\ tags_sel_statusline:\fR
|
|
||||||
selected tag statusline\&.
|
|
||||||
.PP
|
|
||||||
\fB\ tags_occupied_fg/bg:\fR
|
|
||||||
occupied tag text/button color\&.
|
|
||||||
.PP
|
|
||||||
\fB\ tags_occupied_statusline:\fR
|
|
||||||
occupied tag statusline\&.
|
|
||||||
.PP
|
|
||||||
\fB\ tags_urgent_fg/bg:\fR
|
|
||||||
urgent tag text/button color\&.
|
|
||||||
.PP
|
|
||||||
\fB\ tags_urgent_statusline:\fR
|
|
||||||
urgent tag statusline\&.
|
|
||||||
.PP
|
|
||||||
\fB\ tags_border_color:\fR
|
|
||||||
tag button border color\&.
|
|
||||||
.PP
|
|
||||||
\fB\ tags_border_width:\fR
|
|
||||||
tag button border width\&.
|
|
||||||
.PP
|
|
||||||
.RE
|
|
||||||
\fB\ Clients\fR
|
|
||||||
.RS 2
|
|
||||||
\fB\ client_normal_fg/bg:\fR
|
|
||||||
normal client titlebar text/background color\&.
|
|
||||||
.PP
|
|
||||||
\fB\ client_normal_statusline:\fR
|
|
||||||
normal client statusline\&.
|
|
||||||
.PP
|
|
||||||
\fB\ client_sel_fg/bg:\fR
|
|
||||||
selected client titlebar text/background color\&.
|
|
||||||
.PP
|
|
||||||
\fB\ client_sel_statusline:\fR
|
|
||||||
selected client statusline\&.
|
|
||||||
.PP
|
|
||||||
\fB\ frame_bg:\fR
|
|
||||||
client border color\&.
|
|
||||||
.PP
|
|
||||||
\fB\ client_titlebar_width:\fR
|
|
||||||
client titlebar height in pixels\&.
|
|
||||||
.PP
|
|
||||||
\fB\ client_border_width:\fR
|
|
||||||
client border height in pixels\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
.RE
|
|
||||||
\fB\ [bars]\fR
|
|
||||||
.RS 2
|
|
||||||
\fB\ position:\fR
|
|
||||||
statusbar position on screen (0=Top; 1=Bottom, 2=Hide)\&.
|
|
||||||
.PP
|
|
||||||
\fB\ screen:\fR
|
|
||||||
screen to display statusbar (start ar 0), set to\fB -1\fR to display on every screen\&.
|
|
||||||
.PP
|
|
||||||
\fB\ elements:\fR
|
|
||||||
ordered statusbar elements t=Tags, s=Statustext, y=Systray, l=Launcher\&.
|
|
||||||
.PP
|
|
||||||
\fB\ theme:\fR
|
|
||||||
names of the statusbar theme\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
.RE
|
|
||||||
\fB\ [tags]\fR
|
|
||||||
.RS 2
|
|
||||||
\fB\ circular:\fR
|
|
||||||
enable tag wrapping. default is true\&.
|
|
||||||
.PP
|
|
||||||
\fB\ screen:\fR
|
|
||||||
screen to display tag. use no screen option or screen =\fB -1\fR to set tag on each screen\&.
|
|
||||||
.PP
|
|
||||||
\fB\ name:\fR
|
|
||||||
display tagname\&.
|
|
||||||
.PP
|
|
||||||
\fB\ statusline:\fR
|
|
||||||
draw a custom statusline in the specific tag (can display any sequences)\&.
|
|
||||||
.PP
|
|
||||||
\fB\ mousebinds:\fR
|
|
||||||
mouse actions on the tag buttons\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
.RE
|
|
||||||
\fB\ [client]\fR
|
|
||||||
.RS 2
|
|
||||||
\fB\ theme:\fR
|
|
||||||
apply theme to client by default\&.
|
|
||||||
.PP
|
|
||||||
\fB\ key_modifier:\fR
|
|
||||||
key modifier to perform actions on clients\&.
|
|
||||||
.PP
|
|
||||||
\fB\ focus:\fR
|
|
||||||
select the focus mouse options; enter=focus follow mouse, click=click to focus, everything-else=disable focus mouse support\&.
|
|
||||||
.PP
|
|
||||||
\fB\ mousebinds:\fR
|
|
||||||
mouse actions on client\&.
|
|
||||||
.PP
|
|
||||||
\fB\ padding:\fR
|
|
||||||
enable padding between clients. default is 0\&.
|
|
||||||
.PP
|
|
||||||
\fB\ autofocus:\fR
|
|
||||||
give focus to new created clients. default is false\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
.RE
|
|
||||||
\fB\ [rules]\fR
|
|
||||||
specific rules for clients: to identify an application, use xprop\&.
|
|
||||||
.RS 2
|
|
||||||
\fB\ instance:\fR
|
|
||||||
first part of WM_CLASS\&.
|
|
||||||
.PP
|
|
||||||
\fB\ class:\fR
|
|
||||||
second part of WM_CLASS\&.
|
|
||||||
.PP
|
|
||||||
\fB\ role:\fR
|
|
||||||
WM_WINDOW_ROLE\&.
|
|
||||||
.PP
|
|
||||||
\fB\ name:\fR
|
|
||||||
_NET_WM_NAME\&.
|
|
||||||
.PP
|
|
||||||
\fB\ theme:\fR
|
|
||||||
apply theme to client\&.
|
|
||||||
.PP
|
|
||||||
\fB\ tag:\fR
|
|
||||||
specify a tag to display client (start at 0)\&.
|
|
||||||
.PP
|
|
||||||
\fB\ screen:\fR
|
|
||||||
display client on a specific screen\&.
|
|
||||||
.PP
|
|
||||||
\fB\ free:\fR
|
|
||||||
client in auto-free mode (true/false)\&.
|
|
||||||
.PP
|
|
||||||
\fB\ tab:\fR
|
|
||||||
open client in a tab (true/false)\&.
|
|
||||||
.PP
|
|
||||||
\fB\ ignore_tag:\fR
|
|
||||||
specify to client to ignore tags (client is displayed on every tag)\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
.RE
|
|
||||||
\fB\ [launchers]\fR
|
|
||||||
.RS 2
|
|
||||||
\fB\ name:\fR
|
|
||||||
launcher-name, will be used in the [keys] section\&.
|
|
||||||
.PP
|
|
||||||
\fB\ prompt:\fR
|
|
||||||
display text at the beginning of the prompt\&.
|
|
||||||
.PP
|
|
||||||
\fB\ command:\fR
|
|
||||||
command used by the launcher. can be an uicb function or an uicb function + extension\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
.RE
|
|
||||||
\fB\ [keys]\fR
|
|
||||||
.RS 2
|
|
||||||
each line is contained within\fB\ [key]...[/key]\fR
|
|
||||||
.PP
|
|
||||||
\fB\ mod:\fR
|
|
||||||
key modifier (Alt, Control, Shift, Super)\&.
|
|
||||||
.PP
|
|
||||||
\fB\ key:\fR
|
|
||||||
key to press, you can identify it with "xev"\&.
|
|
||||||
.PP
|
|
||||||
\fB\ func:\fR
|
|
||||||
uicb function to launch\&.
|
|
||||||
.PP
|
|
||||||
\fB\ cmd:\fR
|
|
||||||
if\fB\ func = "spawn"\fR set the external command to launch\&.
|
|
||||||
.sp
|
|
||||||
.SH "STATUS"
|
|
||||||
statusbars, tags, surfaces and titlebars support sequences to display text, images bars and graphs through the\fB\ wmfs -c status\fR command.
|
|
||||||
.PP
|
|
||||||
\fB\ Syntax\fR
|
|
||||||
.PP
|
|
||||||
.RS 4
|
|
||||||
\fB\ position:\fR “left/right” (relative) or “x;y” (absolute)\&.
|
|
||||||
.PP
|
|
||||||
\fB\ dimension:\fR “ww;hh” for width;height of the rectangle or the image, to display an image at its original size, set it to “0;0”\&.
|
|
||||||
.PP
|
|
||||||
\fB\ color:\fR ”#rrggbb”\&.
|
|
||||||
.PP
|
|
||||||
\fB\ imagepath:\fR absolute path for the image\&.
|
|
||||||
.PP
|
|
||||||
\fB\ border:\fR width of the progressbar border in pixels\&.
|
|
||||||
.PP
|
|
||||||
\fB\ curser:\fR width of the curser in the positionbar\&.
|
|
||||||
.PP
|
|
||||||
\fB\ value:\fR a variable, to draw progressbar\&.
|
|
||||||
.PP
|
|
||||||
\fB\ valuemax:\fR maximum value of the ‘value’ used in the progressbar\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ basic usage:\fR
|
|
||||||
wmfs -c status "<barname> TEXT visible on 'barname'"\&.
|
|
||||||
.PP
|
|
||||||
\fB\ display colors:\fR
|
|
||||||
wmfs -c status "<barname> ^s[<position>;<color>;<text>]"\&.
|
|
||||||
.PP
|
|
||||||
\fB\ display rectangles:\fR
|
|
||||||
wmfs -c status "<barname> ^R[<position>;<dimensions>;<color>]"\&.
|
|
||||||
.PP
|
|
||||||
\fB\ display images:\fR
|
|
||||||
wmfs -c status "<barname> ^i[<position>;<dimensions>;<imagepath>]"\&.
|
|
||||||
.PP
|
|
||||||
\fB\ display progressbars:\fR
|
|
||||||
wmfs -c status "<barname> ^p[<position>;<dimensions>;<border>;<value>;<valuemax>;<bgcolor>;<fgcolor>]"\&.
|
|
||||||
.PP
|
|
||||||
\fB\ display positionbars:\fR
|
|
||||||
wmfs -c status "<barname> ^P[<position>;<dimensions>;<curser>;<value>;<valuemax>;<bgcolor>;<fgcolor>]"\&.
|
|
||||||
.PP
|
|
||||||
\fB\ display graph:\fR
|
|
||||||
wmfs -c status "<barname> ^g[<position>;<dimensions>;<value>;<valuemax>;<bgcolor>;<fgcolor>;<name>]"\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ mousebinds:\fR
|
|
||||||
sequences supports mousebinds with format\fB\ (<key>;<uicb-function>)\fR or\fB\ (<key>;<spawn>;<command>)\fR
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ surfaces:\fR
|
|
||||||
you can display popups from the statusbar with the mousebind\fB\ (<key>;status_surface;<position>,<dimension>,<color> <datas>)\fR
|
|
||||||
.PP
|
|
||||||
.sp
|
|
||||||
.SH "UICB Functions"
|
|
||||||
UICB functions list. for “User Interface Call Backs”\&.
|
|
||||||
.PP
|
|
||||||
\fB\ usage in the wmfsrc:\fR func = "tag_next"\fB\ or\fR func = "spawn" cmd = "urxvt -e vim"\&.
|
|
||||||
.RE
|
|
||||||
\fB\ usage in the status.sh:\fR wmfs -c status "<barname> ^s[<position>;<color>;next](1;tag_next)"\&.
|
|
||||||
.RE
|
|
||||||
\fB\ usage in your terminal:\fR wmfs -c tag_next\&.
|
|
||||||
.PP
|
|
||||||
\fB\ spawn\fR
|
|
||||||
.RS 4
|
|
||||||
launch a command. ex: func = "spawn" cmd = "urxvtc -e screen irssi"\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ quit\fR
|
|
||||||
.RS 4
|
|
||||||
quit wmfs\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ reload\fR
|
|
||||||
.RS 4
|
|
||||||
reload wmfs\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ tag_set\fR
|
|
||||||
.RS 4
|
|
||||||
set tag by number\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ tag\fR
|
|
||||||
.RS 4
|
|
||||||
set tag by name\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ tag_next/prev\fR
|
|
||||||
.RS 4
|
|
||||||
set next/previous tag\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ tag_client\fR
|
|
||||||
.RS 4
|
|
||||||
tag the client\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ tag_client_and_set\fR
|
|
||||||
.RS 4
|
|
||||||
teg the client and set the tag\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ tag_move_client_next/prev\fR
|
|
||||||
.RS 4
|
|
||||||
tag the client with next/previous tag\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ tag_click\fR
|
|
||||||
.RS 4
|
|
||||||
display tag with a clic on tag button\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ tag_new/del\fR
|
|
||||||
.RS 4
|
|
||||||
add/delete a tag\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB infobar_toggle_hide\fR
|
|
||||||
.RS 4
|
|
||||||
toggle specific infobar visibility (infobar_name as cmd)\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ layout_vmirror\fR
|
|
||||||
.RS 4
|
|
||||||
vertical mirror tiling\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ layout_hmirror\fR
|
|
||||||
.RS 4
|
|
||||||
horizontal mirror tiling\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ layout_rotate_left\fR
|
|
||||||
.RS 4
|
|
||||||
tiling rotate anti/clockwise\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ layout_prev_set\fR
|
|
||||||
.RS 4
|
|
||||||
back to previous set layout\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ layout_next_set\fR
|
|
||||||
.RS 4
|
|
||||||
go to next set layout\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ layout_integrate_left/right/top/bottom\fR
|
|
||||||
.RS 4
|
|
||||||
client integration in the client zone by direction\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ client_close\fR
|
|
||||||
.RS 4
|
|
||||||
close the client\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ client_resize_right/left/top/bottom\fR
|
|
||||||
.RS 4
|
|
||||||
resize client with direction\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ client_focus_right/left/top/bottom\fR
|
|
||||||
.RS 4
|
|
||||||
focus client with direction\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ client_tab_right/left/top/bottom\fR
|
|
||||||
.RS 4
|
|
||||||
tab client with direction\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ client_swap_right/left/top/bottom\fR
|
|
||||||
.RS 4
|
|
||||||
swap client with direction\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ client_focus_next/prev\fR
|
|
||||||
.RS 4
|
|
||||||
move focus to the next/previous client\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ client_swap_next/prev\fR
|
|
||||||
.RS 4
|
|
||||||
swap with the next/previous client\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ client_untab\fR
|
|
||||||
.RS 4
|
|
||||||
untab the client\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ client_focus_next_tab\fR
|
|
||||||
.RS 4
|
|
||||||
move focus to next tab-client\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ client_focus_prev_tab\fR
|
|
||||||
.RS 4
|
|
||||||
move focus to previous tab-client\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ client_focus_click\fR
|
|
||||||
.RS 4
|
|
||||||
give focus to client with a clic\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ client_toggle_free\fR
|
|
||||||
.RS 4
|
|
||||||
toggle free the selected client\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ client_toggle_ignore_tag\fR
|
|
||||||
.RS 4
|
|
||||||
toggle ignore_tag the selected client\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ client_tab_next_opened\fR
|
|
||||||
.RS 4
|
|
||||||
open the client in a tab\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ status\fR
|
|
||||||
.RS 4
|
|
||||||
display the argument text in the statusbar\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ status_surface\fR
|
|
||||||
.RS 4
|
|
||||||
display a surface. can contain sequences\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ mouse_resize\fR
|
|
||||||
.RS 4
|
|
||||||
resize the client\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ mouse_move\fR
|
|
||||||
.RS 4
|
|
||||||
move the client\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ mouse_swap\fR
|
|
||||||
.RS 4
|
|
||||||
swap the client\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ mouse_tab\fR
|
|
||||||
.RS 4
|
|
||||||
tab the client\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ screen_next/prev\fR
|
|
||||||
.RS 4
|
|
||||||
go to next/previous screen\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ screen_move_client_next/prev\fR
|
|
||||||
.RS 4
|
|
||||||
move the client to next/previous screen\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\ launcher\fR
|
|
||||||
.RS 4
|
|
||||||
native prompt. ex:\fB\ func = "launcher" cmd = "exec"\fR display the “exec” launcher\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
.sp
|
.sp
|
||||||
.SH "BUGS"
|
.SH "BUGS"
|
||||||
WMFS isn\'t stable for now\&. So it certainly contains some bugs\&.
|
WMFS isn\'t stable for now\&. So it certainly contains some bugs\&.
|
||||||
.sp
|
.sp
|
||||||
.SH "AUTHOR"
|
.SH "AUTHORS"
|
||||||
Martin Duquesnoy <\fIxorg62@gmail\&.com\fR\&[1]>\&.
|
Martin Duquesnoy <\fIxorg62@gmail\&.com\fR\&[1]>\&.
|
||||||
.sp
|
.sp
|
||||||
.SH "WWW"
|
.SH "WWW"
|
||||||
Main site: \fIhttps://github\&.com/xorg62/wmfs\fR
|
Main site: \fIhttp://wmfs\&.info\fR Bug tracker: \fIhttp://bugs\&.wmfs\&.info\fR
|
||||||
.PP
|
|
||||||
Wiki: \fIhttps://github\&.com/xorg62/wmfs/wiki\fR
|
|
||||||
.PP
|
|
||||||
Bug tracker: \fIhttps://github\&.com/xorg62/wmfs/issues\fR
|
|
||||||
.sp
|
.sp
|
||||||
.SH "COPYING"
|
.SH "COPYING"
|
||||||
WMFS is under the BSD license\&. See COPYING for more information\&.
|
WMFS is under the BSD license\&. See COPYING for more information\&.
|
||||||
|
.sp
|
||||||
|
.SH "NOTES"
|
||||||
|
.IP " 1." 4
|
||||||
|
xorg62@gmail.com
|
||||||
|
.RS 4
|
||||||
|
\%mailto:xorg62@gmail.com
|
||||||
.RE
|
.RE
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
Encoding=UTF-8
|
Encoding=UTF-8
|
||||||
Type=Application
|
|
||||||
Name=wmfs
|
Name=wmfs
|
||||||
Comment=Window Manager From Scratch
|
Comment=Window Manager From Scratch
|
||||||
TryExec=wmfs
|
Exec=ck-launch-session wmfs
|
||||||
Exec=wmfs
|
|
||||||
|
|||||||
242
wmfs.doxygen
Normal file
242
wmfs.doxygen
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
DOXYFILE_ENCODING = UTF-8
|
||||||
|
PROJECT_NAME = WMFS
|
||||||
|
PROJECT_NUMBER = devel
|
||||||
|
OUTPUT_DIRECTORY = doc
|
||||||
|
CREATE_SUBDIRS = NO
|
||||||
|
OUTPUT_LANGUAGE = English
|
||||||
|
BRIEF_MEMBER_DESC = YES
|
||||||
|
REPEAT_BRIEF = YES
|
||||||
|
ALWAYS_DETAILED_SEC = NO
|
||||||
|
INLINE_INHERITED_MEMB = NO
|
||||||
|
FULL_PATH_NAMES = YES
|
||||||
|
STRIP_FROM_PATH =
|
||||||
|
STRIP_FROM_INC_PATH =
|
||||||
|
SHORT_NAMES = NO
|
||||||
|
JAVADOC_AUTOBRIEF = NO
|
||||||
|
QT_AUTOBRIEF = NO
|
||||||
|
MULTILINE_CPP_IS_BRIEF = NO
|
||||||
|
DETAILS_AT_TOP = NO
|
||||||
|
INHERIT_DOCS = YES
|
||||||
|
SEPARATE_MEMBER_PAGES = NO
|
||||||
|
TAB_SIZE = 4
|
||||||
|
ALIASES =
|
||||||
|
|
||||||
|
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||||
|
OPTIMIZE_OUTPUT_JAVA = NO
|
||||||
|
BUILTIN_STL_SUPPORT = NO
|
||||||
|
CPP_CLI_SUPPORT = NO
|
||||||
|
DISTRIBUTE_GROUP_DOC = NO
|
||||||
|
SUBGROUPING = YES
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Build related configuration options
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
EXTRACT_ALL = YES
|
||||||
|
EXTRACT_PRIVATE = YES
|
||||||
|
EXTRACT_STATIC = YES
|
||||||
|
EXTRACT_LOCAL_CLASSES = YES
|
||||||
|
EXTRACT_LOCAL_METHODS = YES
|
||||||
|
EXTRACT_ANON_NSPACES = YES
|
||||||
|
HIDE_UNDOC_MEMBERS = NO
|
||||||
|
HIDE_UNDOC_CLASSES = NO
|
||||||
|
HIDE_FRIEND_COMPOUNDS = NO
|
||||||
|
HIDE_IN_BODY_DOCS = NO
|
||||||
|
INTERNAL_DOCS = NO
|
||||||
|
CASE_SENSE_NAMES = YES
|
||||||
|
HIDE_SCOPE_NAMES = NO
|
||||||
|
SHOW_INCLUDE_FILES = YES
|
||||||
|
INLINE_INFO = YES
|
||||||
|
SORT_MEMBER_DOCS = YES
|
||||||
|
SORT_BRIEF_DOCS = NO
|
||||||
|
SORT_BY_SCOPE_NAME = NO
|
||||||
|
GENERATE_TODOLIST = YES
|
||||||
|
GENERATE_TESTLIST = YES
|
||||||
|
GENERATE_BUGLIST = YES
|
||||||
|
GENERATE_DEPRECATEDLIST= YES
|
||||||
|
ENABLED_SECTIONS =
|
||||||
|
MAX_INITIALIZER_LINES = 30
|
||||||
|
SHOW_USED_FILES = YES
|
||||||
|
SHOW_DIRECTORIES = NO
|
||||||
|
FILE_VERSION_FILTER =
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# configuration options related to warning and progress messages
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
QUIET = YES
|
||||||
|
WARNINGS = YES
|
||||||
|
WARN_IF_UNDOCUMENTED = YES
|
||||||
|
WARN_IF_DOC_ERROR = YES
|
||||||
|
WARN_NO_PARAMDOC = NO
|
||||||
|
WARN_FORMAT = "$file:$line: $text"
|
||||||
|
WARN_LOGFILE =
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# configuration options related to the input files
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
INPUT = src
|
||||||
|
INPUT_ENCODING = UTF-8
|
||||||
|
FILE_PATTERNS = *.c \
|
||||||
|
*.h \
|
||||||
|
RECURSIVE = YES
|
||||||
|
EXCLUDE =
|
||||||
|
EXCLUDE_SYMLINKS = NO
|
||||||
|
EXCLUDE_PATTERNS =
|
||||||
|
EXCLUDE_SYMBOLS =
|
||||||
|
EXAMPLE_PATH =
|
||||||
|
EXAMPLE_PATTERNS = *
|
||||||
|
EXAMPLE_RECURSIVE = NO
|
||||||
|
IMAGE_PATH =
|
||||||
|
INPUT_FILTER =
|
||||||
|
FILTER_PATTERNS =
|
||||||
|
FILTER_SOURCE_FILES = NO
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# configuration options related to source browsing
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
SOURCE_BROWSER = YES
|
||||||
|
INLINE_SOURCES = NO
|
||||||
|
STRIP_CODE_COMMENTS = NO
|
||||||
|
REFERENCED_BY_RELATION = YES
|
||||||
|
REFERENCES_RELATION = YES
|
||||||
|
REFERENCES_LINK_SOURCE = YES
|
||||||
|
USE_HTAGS = NO
|
||||||
|
VERBATIM_HEADERS = YES
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# configuration options related to the alphabetical class index
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
ALPHABETICAL_INDEX = NO
|
||||||
|
COLS_IN_ALPHA_INDEX = 5
|
||||||
|
IGNORE_PREFIX =
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# configuration options related to the HTML output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
GENERATE_HTML = YES
|
||||||
|
HTML_OUTPUT = html
|
||||||
|
HTML_FILE_EXTENSION = .html
|
||||||
|
HTML_HEADER =
|
||||||
|
HTML_FOOTER =
|
||||||
|
HTML_STYLESHEET =
|
||||||
|
HTML_ALIGN_MEMBERS = YES
|
||||||
|
GENERATE_HTMLHELP = NO
|
||||||
|
HTML_DYNAMIC_SECTIONS = NO
|
||||||
|
CHM_FILE =
|
||||||
|
HHC_LOCATION =
|
||||||
|
GENERATE_CHI = NO
|
||||||
|
BINARY_TOC = NO
|
||||||
|
TOC_EXPAND = NO
|
||||||
|
DISABLE_INDEX = NO
|
||||||
|
ENUM_VALUES_PER_LINE = 4
|
||||||
|
GENERATE_TREEVIEW = YES
|
||||||
|
TREEVIEW_WIDTH = 250
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# configuration options related to the LaTeX output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
GENERATE_LATEX = NO
|
||||||
|
LATEX_OUTPUT = latex
|
||||||
|
LATEX_CMD_NAME = latex
|
||||||
|
MAKEINDEX_CMD_NAME = makeindex
|
||||||
|
COMPACT_LATEX = NO
|
||||||
|
PAPER_TYPE = a4wide
|
||||||
|
EXTRA_PACKAGES =
|
||||||
|
LATEX_HEADER =
|
||||||
|
PDF_HYPERLINKS = NO
|
||||||
|
USE_PDFLATEX = NO
|
||||||
|
LATEX_BATCHMODE = NO
|
||||||
|
LATEX_HIDE_INDICES = NO
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# configuration options related to the RTF output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
GENERATE_RTF = NO
|
||||||
|
RTF_OUTPUT = rtf
|
||||||
|
COMPACT_RTF = NO
|
||||||
|
RTF_HYPERLINKS = NO
|
||||||
|
RTF_STYLESHEET_FILE =
|
||||||
|
RTF_EXTENSIONS_FILE =
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# configuration options related to the man page output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
GENERATE_MAN = NO
|
||||||
|
MAN_OUTPUT = man
|
||||||
|
MAN_EXTENSION = .3
|
||||||
|
MAN_LINKS = NO
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# configuration options related to the XML output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
GENERATE_XML = NO
|
||||||
|
XML_OUTPUT = xml
|
||||||
|
XML_SCHEMA =
|
||||||
|
XML_DTD =
|
||||||
|
XML_PROGRAMLISTING = YES
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# configuration options for the AutoGen Definitions output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
GENERATE_AUTOGEN_DEF = NO
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# configuration options related to the Perl module output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
GENERATE_PERLMOD = NO
|
||||||
|
PERLMOD_LATEX = NO
|
||||||
|
PERLMOD_PRETTY = YES
|
||||||
|
PERLMOD_MAKEVAR_PREFIX =
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to the preprocessor...
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
ENABLE_PREPROCESSING = YES
|
||||||
|
MACRO_EXPANSION = YES
|
||||||
|
EXPAND_ONLY_PREDEF = YES
|
||||||
|
SEARCH_INCLUDES = YES
|
||||||
|
INCLUDE_PATH =
|
||||||
|
INCLUDE_FILE_PATTERNS =
|
||||||
|
EXPAND_AS_DEFINED =
|
||||||
|
SKIP_FUNCTION_MACROS = YES
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration::additions related to external references...
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
TAGFILES =
|
||||||
|
GENERATE_TAGFILE =
|
||||||
|
ALLEXTERNALS = NO
|
||||||
|
EXTERNAL_GROUPS = YES
|
||||||
|
PERL_PATH = /usr/bin/perl
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to the dot tool...
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
CLASS_DIAGRAMS = NO
|
||||||
|
MSCGEN_PATH =
|
||||||
|
HIDE_UNDOC_RELATIONS = YES
|
||||||
|
HAVE_DOT = YES
|
||||||
|
CLASS_GRAPH = YES
|
||||||
|
COLLABORATION_GRAPH = YES
|
||||||
|
GROUP_GRAPHS = YES
|
||||||
|
UML_LOOK = YES
|
||||||
|
TEMPLATE_RELATIONS = YeS
|
||||||
|
INCLUDE_GRAPH = YES
|
||||||
|
INCLUDED_BY_GRAPH = YES
|
||||||
|
CALL_GRAPH = YES
|
||||||
|
CALLER_GRAPH = YES
|
||||||
|
GRAPHICAL_HIERARCHY = YES
|
||||||
|
DIRECTORY_GRAPH = YES
|
||||||
|
DOT_IMAGE_FORMAT = png
|
||||||
|
DOT_PATH =
|
||||||
|
DOTFILE_DIRS =
|
||||||
|
DOT_GRAPH_MAX_NODES = 50
|
||||||
|
MAX_DOT_GRAPH_DEPTH = 1000
|
||||||
|
DOT_TRANSPARENT = NO
|
||||||
|
DOT_MULTI_TARGETS = NO
|
||||||
|
GENERATE_LEGEND = YES
|
||||||
|
DOT_CLEANUP = YES
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration::additions related to the search engine...
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
SEARCHENGINE = NO
|
||||||
605
wmfsrc
605
wmfsrc
@ -1,284 +1,455 @@
|
|||||||
#
|
#
|
||||||
# WMFS2 configuration file
|
# This is the default wmfs config file, copy it to
|
||||||
|
# ~/.config/wmfs/wmfsrc and edit it.
|
||||||
#
|
#
|
||||||
|
|
||||||
# Possible file inclusion:
|
# Include file to split configuration
|
||||||
# @include "file"
|
# @include "~/.config/wmfs/menu-wmfsrc"
|
||||||
|
|
||||||
# Multi theme section
|
[misc]
|
||||||
[themes]
|
font = "dejavu-10"
|
||||||
|
raisefocus = true
|
||||||
|
raiseswitch = false
|
||||||
|
focus_follow_mouse = true
|
||||||
|
focus_follow_movement = false
|
||||||
|
opacity = 255
|
||||||
|
|
||||||
[theme]
|
# focus_pointer_click: click on unfocused client area:
|
||||||
# No name mean default
|
# true -- default, set focus
|
||||||
# name = "default"
|
# false -- click go to client; including dockapps
|
||||||
|
focus_pointer_click = true
|
||||||
|
status_timing = 1 #seconds
|
||||||
|
# status_path = "~/.config/wmfs/status.sh"
|
||||||
|
[/misc]
|
||||||
|
|
||||||
font = "fixed"
|
[bar]
|
||||||
|
bg = "#191919"
|
||||||
|
fg = "#D4D4D4"
|
||||||
|
border = true
|
||||||
|
#height = "-1"
|
||||||
|
|
||||||
# Bars
|
light_shade = 0.10
|
||||||
bars_width = 14
|
dark_shade = -0.10
|
||||||
bars_fg = "#AABBAA"
|
|
||||||
bars_bg = "#223322"
|
|
||||||
|
|
||||||
# Element tags
|
[systray]
|
||||||
tags_normal_fg = "#AABBAA"
|
# Enable/disable systray
|
||||||
tags_normal_bg = "#223322"
|
active = true
|
||||||
# tags_normal_statusline = ""
|
|
||||||
|
|
||||||
tags_sel_fg = "#223322"
|
# Screen of systray
|
||||||
tags_sel_bg = "#AABBAA"
|
|
||||||
# tags_sel_statusline = ""
|
|
||||||
|
|
||||||
tags_occupied_fg = "#AABBAA"
|
|
||||||
tags_occupied_bg = "#445544"
|
|
||||||
tags_occupied_statusline = "\R[0;0;100;1;#AABBAA]"
|
|
||||||
|
|
||||||
tags_urgent_fg = "#223322"
|
|
||||||
tags_urgent_bg = "#CC5544"
|
|
||||||
# tags_urgent_statusline = ""
|
|
||||||
|
|
||||||
tags_border_color = "#112211"
|
|
||||||
tags_border_width = 1
|
|
||||||
|
|
||||||
# Frame / Client
|
|
||||||
client_normal_fg = "#AABBAA"
|
|
||||||
client_normal_bg = "#223322"
|
|
||||||
client_normal_statusline = "\s[3;9;#121212;x] \s[2;8;#ff0000;x](1;client_close)"
|
|
||||||
|
|
||||||
client_sel_fg = "#223322"
|
|
||||||
client_sel_bg = "#AABBAA"
|
|
||||||
client_sel_statusline = "\s[3;9;#121212;x] \s[2;8;#ff0000;x](1;client_close)"
|
|
||||||
|
|
||||||
# client_free_statusline = ""
|
|
||||||
|
|
||||||
frame_bg = "#555555"
|
|
||||||
client_titlebar_width = 12
|
|
||||||
client_border_width = 1
|
|
||||||
|
|
||||||
[/theme]
|
|
||||||
|
|
||||||
[/themes]
|
|
||||||
|
|
||||||
[bars]
|
|
||||||
|
|
||||||
# Position:
|
|
||||||
#
|
|
||||||
# 0 Top
|
|
||||||
# 1 Bottom
|
|
||||||
# 2 Hide
|
|
||||||
|
|
||||||
# Element type:
|
|
||||||
#
|
|
||||||
# t Tags
|
|
||||||
# s Statustext (will take available space)
|
|
||||||
# y Systray (can be set only ONE time among all element)
|
|
||||||
# l Launcher (will be expended at launcher use)
|
|
||||||
|
|
||||||
[bar]
|
|
||||||
position = 0
|
|
||||||
screen = 0
|
screen = 0
|
||||||
elements = "tlsy" # element order in bar
|
|
||||||
theme = "default"
|
|
||||||
[/bar]
|
|
||||||
|
|
||||||
# [bar]
|
# Spacing between tray icons
|
||||||
# position = 0
|
spacing = 3
|
||||||
# screen = 1
|
[/systray]
|
||||||
# elements = "ts"
|
|
||||||
# theme = "default"
|
|
||||||
# [/bar]
|
|
||||||
|
|
||||||
[/bars]
|
# Remove this section to disable the selbar.
|
||||||
|
[selbar]
|
||||||
|
bg = "#191919"
|
||||||
|
fg = "#D4D4ff"
|
||||||
|
|
||||||
|
# Cut title length
|
||||||
|
# max_length = 25
|
||||||
|
|
||||||
|
[mouse] button = "3" func = "clientlist" [/mouse]
|
||||||
|
[mouse] button = "4" func = "client_next" [/mouse]
|
||||||
|
[mouse] button = "5" func = "client_prev" [/mouse]
|
||||||
|
[/selbar]
|
||||||
|
|
||||||
|
[/bar]
|
||||||
|
|
||||||
|
[layouts]
|
||||||
|
fg = "#191919"
|
||||||
|
bg = "#7E89A2"
|
||||||
|
|
||||||
|
# Border around the layout button.
|
||||||
|
border = true
|
||||||
|
|
||||||
|
# Value menu or switch.
|
||||||
|
system = "menu"
|
||||||
|
|
||||||
|
# Value left or right.
|
||||||
|
placement = "right"
|
||||||
|
|
||||||
|
# Keep layout geo for free layout
|
||||||
|
keep_layout_geo = false
|
||||||
|
|
||||||
|
# Symbol displayed for the selected layout in the list
|
||||||
|
selected_layout_symbol = "*"
|
||||||
|
|
||||||
|
# Width of layout button
|
||||||
|
# layout_button_width = x
|
||||||
|
|
||||||
|
# Tiling layouts.
|
||||||
|
[layout] type = "tile_right" symbol = "RIGHT" [/layout]
|
||||||
|
[layout] type = "tile_left" symbol = "LEFT" [/layout]
|
||||||
|
[layout] type = "tile_top" symbol = "TOP" [/layout]
|
||||||
|
[layout] type = "tile_bottom" symbol = "BOTTOM" [/layout]
|
||||||
|
[layout] type = "tile_grid" symbol = "GRID_H" [/layout]
|
||||||
|
[layout] type = "tile_grid_vertical" symbol = "GRID_V" [/layout]
|
||||||
|
[layout] type = "mirror_vertical" symbol = "MIRROR_V" [/layout]
|
||||||
|
[layout] type = "mirror_horizontal" symbol = "MIRROR_H" [/layout]
|
||||||
|
|
||||||
|
# Other layouts.
|
||||||
|
[layout] type = "max" symbol = "MAX" [/layout]
|
||||||
|
[layout] type = "free" symbol = "FREE" [/layout]
|
||||||
|
|
||||||
|
[/layouts]
|
||||||
|
|
||||||
[tags]
|
[tags]
|
||||||
|
[default_tag]
|
||||||
|
name = "new tag"
|
||||||
|
mwfact = 0.5
|
||||||
|
nmaster = 1
|
||||||
|
layout = "tile_right"
|
||||||
|
resizehint = false
|
||||||
|
infobar_position = "top"
|
||||||
|
[/default_tag]
|
||||||
|
|
||||||
# Tag wrapping navigation
|
# whether client_next on the last tag will send you on the first
|
||||||
circular = false
|
# and client_prev on the first tag will send you on the last one
|
||||||
|
tag_round = false
|
||||||
|
|
||||||
|
# Going twice on the same tag will bring you back on the previous one
|
||||||
|
tag_auto_prev = true
|
||||||
|
|
||||||
|
occupied_bg = "#003366"
|
||||||
|
occupied_fg = "#D4D4D4"
|
||||||
|
sel_fg = "#191919"
|
||||||
|
sel_bg = "#7E89A2"
|
||||||
|
urgent_bg = "#DD1111"
|
||||||
|
urgent_fg = "#000000"
|
||||||
|
|
||||||
|
# If true, number of the tag will be used for name
|
||||||
|
name_count = false
|
||||||
|
#default_name = "new tag" # deprecated, use [default_tag] instead
|
||||||
|
#default_layout = "tile_right" # deprecated, use [default_tag] instead
|
||||||
|
|
||||||
|
expose_name = "EXPOSE"
|
||||||
|
expose_layout = "tile_left"
|
||||||
|
|
||||||
|
# Border around the tag buttons.
|
||||||
|
border = true
|
||||||
|
|
||||||
|
# Hide empty tags in tag list
|
||||||
|
autohide = true
|
||||||
|
|
||||||
|
# Mouse buttons action on tag.
|
||||||
|
mouse_button_tag_sel = "1"
|
||||||
|
mouse_button_tag_transfert = "2"
|
||||||
|
mouse_button_tag_add = "3"
|
||||||
|
mouse_button_tag_next = "4"
|
||||||
|
mouse_button_tag_prev = "5"
|
||||||
|
|
||||||
# Use no screen option or screen = -1 to set tag on each screen
|
|
||||||
[tag]
|
[tag]
|
||||||
screen = -1
|
name = "one"
|
||||||
name = "1"
|
screen = 0
|
||||||
# statusline=""
|
mwfact = 0.65
|
||||||
|
nmaster = 1
|
||||||
|
layout = "tile_right"
|
||||||
|
resizehint = false
|
||||||
|
infobar_position = "top"
|
||||||
|
above_fc = false
|
||||||
|
#[mouse] [/mouse] Possible multi mouse section
|
||||||
[/tag]
|
[/tag]
|
||||||
|
|
||||||
[tag] name = "2" [/tag]
|
# clients option is *DEPRECATED* but works, see [rules] section
|
||||||
[tag] name = "3" [/tag]
|
[tag] name = "two" clients = {"Browser"} [/tag]
|
||||||
[tag] name = "4" [/tag]
|
[tag] name = "three" [/tag]
|
||||||
[tag] name = "5" [/tag]
|
[tag] name = "four" [/tag]
|
||||||
[tag] name = "6" [/tag]
|
[tag] name = "five" [/tag]
|
||||||
[tag] name = "7" [/tag]
|
[tag] name = "six" [/tag]
|
||||||
|
[tag] name = "seven" [/tag]
|
||||||
# Mousebinds associated to Tags element button
|
[tag] name = "eight" [/tag]
|
||||||
[mouse] button = "1" func = "tag_click" [/mouse]
|
[tag] name = "nine" [/tag]
|
||||||
[mouse] button = "4" func = "tag_next" [/mouse]
|
|
||||||
[mouse] button = "5" func = "tag_prev" [/mouse]
|
|
||||||
|
|
||||||
|
|
||||||
[/tags]
|
[/tags]
|
||||||
|
|
||||||
|
[root]
|
||||||
|
# Command you can execute to set the background.
|
||||||
|
background_command = "xsetroot -solid black"
|
||||||
|
|
||||||
|
[mouse] button = "4" func = "tag_next" [/mouse]
|
||||||
|
[mouse] button = "5" func = "tag_prev" [/mouse]
|
||||||
|
[mouse] button = "3" func = "menu" cmd = "rootmenu" [/mouse]
|
||||||
|
[/root]
|
||||||
|
|
||||||
[client]
|
[client]
|
||||||
|
client_round = true
|
||||||
|
client_auto_center = false
|
||||||
|
border_height = 3
|
||||||
|
border_shadow = true
|
||||||
|
border_normal = "#191919"
|
||||||
|
border_focus = "#003366"
|
||||||
|
place_at_mouse = false
|
||||||
|
resize_corner_normal = "#191919"
|
||||||
|
resize_corner_focus = "#003366"
|
||||||
|
set_new_win_master = true
|
||||||
|
client_tile_raise = false
|
||||||
|
new_client_get_mouse = false
|
||||||
|
|
||||||
# Padding between clients (default: 0) :
|
# send all client that have no tag rule in this default tag
|
||||||
#padding = 75
|
#default_open_tag = 4
|
||||||
|
# same as above but for the screen
|
||||||
|
#default_open_screen = 1
|
||||||
|
|
||||||
# Give focus to new created client (default = false)
|
# Space between tiled clients
|
||||||
autofocus = false
|
padding = 0
|
||||||
|
|
||||||
theme = "default"
|
# Modifier for mouse use
|
||||||
key_modifier = "Super"
|
modifier = "Alt"
|
||||||
|
|
||||||
# Focus type:
|
light_shade = 0.10
|
||||||
# enter : focus follow mouse (default)
|
dark_shade = -0.10
|
||||||
# click : click to focus
|
|
||||||
# everything-else : disable mouse focus support
|
|
||||||
focus = enter
|
|
||||||
|
|
||||||
[mouse] button = "1" func = "client_focus_click" [/mouse]
|
# *DEPRECATED* but works, see [rules] section
|
||||||
[mouse] button = "1" func = "mouse_swap" [/mouse]
|
# Set automatic free or max client
|
||||||
[mouse] button = "2" func = "mouse_tab" [/mouse]
|
# autofree = "xterm|MPlayer"
|
||||||
|
# automax = "Navigator"
|
||||||
|
|
||||||
|
[mouse] button = "1" func = "client_raise" [/mouse]
|
||||||
|
[mouse] button = "1" func = "mouse_move" [/mouse]
|
||||||
|
[mouse] button = "3" func = "client_raise" [/mouse]
|
||||||
[mouse] button = "3" func = "mouse_resize" [/mouse]
|
[mouse] button = "3" func = "mouse_resize" [/mouse]
|
||||||
[mouse] button = "4" func = "client_focus_next_tab" [/mouse]
|
|
||||||
[mouse] button = "5" func = "client_focus_prev_tab" [/mouse]
|
|
||||||
|
|
||||||
|
# Remove this section to delete the titlebar.
|
||||||
|
[titlebar]
|
||||||
|
stipple = false
|
||||||
|
height = 12
|
||||||
|
fg_normal = "#7E89A2"
|
||||||
|
fg_focus = "#9F9AB3"
|
||||||
|
|
||||||
|
[mouse] button = "1" func = "client_raise" [/mouse]
|
||||||
|
[mouse] button = "1" func = "mouse_move" [/mouse]
|
||||||
|
[mouse] button = "3" func = "client_raise" [/mouse]
|
||||||
|
[mouse] button = "3" func = "mouse_resize" [/mouse]
|
||||||
|
|
||||||
|
[button]
|
||||||
|
# Available "free", "max", "tile" flags or button.
|
||||||
|
flags = "free,max,tile"
|
||||||
|
[mouse] button = "1" func = "client_kill" [/mouse]
|
||||||
|
[mouse] button = "3" func = "menu" cmd = "clientmenu" [/mouse]
|
||||||
|
|
||||||
|
[line] coord = {1, 1, 4, 1} [/line]
|
||||||
|
[line] coord = {1, 1, 1, 4} [/line]
|
||||||
|
[line] coord = {1, 4, 4, 4} [/line]
|
||||||
|
[/button]
|
||||||
|
[/titlebar]
|
||||||
[/client]
|
[/client]
|
||||||
|
|
||||||
[rules]
|
[rules]
|
||||||
|
# Example of rule for MPlayer
|
||||||
[rule]
|
[rule]
|
||||||
# use instance = "*" for a all-clients rule
|
instance = "xv" # First part of WM_CLASS
|
||||||
instance = "chromium"
|
class = "MPlayer" # Seconf part of WM_CLASS, not needed if first part is correct
|
||||||
|
# role = "" # WM_WINDOW_ROLE
|
||||||
# role = ""
|
screen = 0 # Screen to use
|
||||||
# name = ""
|
tag = 2 # Tag number of apps
|
||||||
# theme = "default"
|
free = true # Set automatic free client
|
||||||
|
max = false # Set automatic maximized client
|
||||||
tag = 1 # 2nd tag
|
follow_client = false # follow the client
|
||||||
screen = 0
|
ignore_tags = false # ignore tag (free mode)
|
||||||
|
|
||||||
free = false
|
|
||||||
tab = false
|
|
||||||
ignore_tag = false
|
|
||||||
[/rule]
|
[/rule]
|
||||||
|
|
||||||
[/rules]
|
[/rules]
|
||||||
|
|
||||||
[launchers]
|
[menu]
|
||||||
|
# Default menu, binded on the root window, button 3.
|
||||||
|
[set_menu]
|
||||||
|
name = "rootmenu"
|
||||||
|
|
||||||
# command can be an uicb function or an uicb function + extension (see example)
|
# place_at_mouse = false
|
||||||
[launcher]
|
# x = 40 y = 50
|
||||||
name = "exec"
|
|
||||||
prompt = "Run:"
|
|
||||||
|
|
||||||
# Example of uicb + ext:
|
# Available "center", "left", "right" menu align. Default: "center".
|
||||||
# command = "spawn xterm -e"
|
align = "left"
|
||||||
command = "spawn"
|
|
||||||
|
|
||||||
width = 150
|
fg_focus = "#191919" bg_focus = "#7E89A2"
|
||||||
[/launcher]
|
fg_normal = "#9F9AB3" bg_normal = "#191919"
|
||||||
|
|
||||||
[/launchers]
|
[item] name = "Terminal" func = "spawn" cmd = "urxvt || xterm || gnome-terminal" [/item]
|
||||||
|
[item] name = "Applications" submenu = "appmenu" [/item]
|
||||||
|
[item] name = "Next tag" func = "tag_next" [/item]
|
||||||
|
[item] name = "Previous tag" func = "tag_prev" [/item]
|
||||||
|
[item] name = "Next layout" func = "layout_next" [/item]
|
||||||
|
[item] name = "Previous layout" func = "layout_prev" [/item]
|
||||||
|
[item] name = "Toggle infobar" func = "toggle_infobar_position" [/item]
|
||||||
|
[item] name = "Quit WMFS" func = "quit" [/item]
|
||||||
|
[/set_menu]
|
||||||
|
|
||||||
|
[set_menu]
|
||||||
|
name = "appmenu"
|
||||||
|
align = "left"
|
||||||
|
|
||||||
|
fg_focus = "#191919" bg_focus = "#7E89A2"
|
||||||
|
fg_normal = "#9F9AB3" bg_normal = "#191919"
|
||||||
|
|
||||||
|
[item] name = "Browser" func = "spawn" cmd = "firefox" [/item]
|
||||||
|
[item] name = "Calculator" func = "spawn" cmd = "xcalc" [/item]
|
||||||
|
[/set_menu]
|
||||||
|
|
||||||
|
[set_menu]
|
||||||
|
name = "clientmenu"
|
||||||
|
|
||||||
|
fg_focus = "#D4D4D4" bg_focus = "#003366"
|
||||||
|
fg_normal = "#D4D4D4" bg_normal = "#191919"
|
||||||
|
|
||||||
|
# Check items: possible 'check_max' or 'check_free'.
|
||||||
|
[item] name = "Close" func = "client_kill" [/item]
|
||||||
|
[item] name = "Maximize" func = "toggle_max" check = "check_max" [/item]
|
||||||
|
[item] name = "Free" func = "toggle_free" check = "check_free" [/item]
|
||||||
|
[/set_menu]
|
||||||
|
[/menu]
|
||||||
|
|
||||||
|
[launcher]
|
||||||
|
[set_launcher]
|
||||||
|
# Limit size of the launcher window (px)
|
||||||
|
width_limit = 300
|
||||||
|
|
||||||
|
name = "launcher_exec"
|
||||||
|
prompt = "Exec: "
|
||||||
|
command = "exec"
|
||||||
|
[/set_launcher]
|
||||||
|
|
||||||
|
#ViWMFS : manage wmfs with vi-based command.
|
||||||
|
[set_launcher]
|
||||||
|
name = "viwmfs"
|
||||||
|
prompt = "> "
|
||||||
|
command = "wmfs -V"
|
||||||
|
[/set_launcher]
|
||||||
|
[/launcher]
|
||||||
|
|
||||||
[keys]
|
[keys]
|
||||||
|
# Reload the configuration of wmfs.
|
||||||
|
[key] mod = {"Alt", "Control"} key = "r" func = "reload" [/key]
|
||||||
|
|
||||||
[key] mod = {"Super"} key = "Return" func = "spawn" cmd = "urxvt || xterm" [/key]
|
# Open a terminal.
|
||||||
|
[key] mod = {"Control"} key = "Return" func = "spawn" cmd = "xterm" [/key]
|
||||||
|
|
||||||
[key] mod = {"Control", "Alt"} key = "q" func = "quit" [/key]
|
# Kill the selected client.
|
||||||
[key] mod = {"Control", "Alt"} key = "r" func = "reload" [/key]
|
[key] mod = {"Alt"} key = "q" func = "client_kill" [/key]
|
||||||
|
|
||||||
# Tag manipulation
|
# Quit wmfs.
|
||||||
[key] mod = {"Super"} key = "F1" func = "tag_set" cmd = "0" [/key]
|
[key] mod = {"Control", "Alt", "Shift"} key = "q" func = "quit" [/key]
|
||||||
[key] mod = {"Super"} key = "F2" func = "tag_set" cmd = "1" [/key]
|
|
||||||
[key] mod = {"Super"} key = "F3" func = "tag_set" cmd = "2" [/key]
|
|
||||||
[key] mod = {"Super"} key = "F4" func = "tag_set" cmd = "3" [/key]
|
|
||||||
[key] mod = {"Super"} key = "F5" func = "tag_set" cmd = "4" [/key]
|
|
||||||
[key] mod = {"Super"} key = "F6" func = "tag_set" cmd = "5" [/key]
|
|
||||||
[key] mod = {"Super"} key = "F7" func = "tag_set" cmd = "6" [/key]
|
|
||||||
[key] mod = {"Super"} key = "F8" func = "tag_set" cmd = "7" [/key]
|
|
||||||
|
|
||||||
[key] mod = {"Super", "Shift"} key = "F1" func = "tag_client" cmd = "0" [/key]
|
# Swap current client with the next.
|
||||||
[key] mod = {"Super", "Shift"} key = "F2" func = "tag_client" cmd = "1" [/key]
|
[key] mod = {"Alt"} key = "t" func = "client_swap_next" [/key]
|
||||||
[key] mod = {"Super", "Shift"} key = "F3" func = "tag_client" cmd = "2" [/key]
|
|
||||||
[key] mod = {"Super", "Shift"} key = "F4" func = "tag_client" cmd = "3" [/key]
|
|
||||||
[key] mod = {"Super", "Shift"} key = "F5" func = "tag_client" cmd = "4" [/key]
|
|
||||||
[key] mod = {"Super", "Shift"} key = "F6" func = "tag_client" cmd = "5" [/key]
|
|
||||||
[key] mod = {"Super", "Shift"} key = "F7" func = "tag_client" cmd = "6" [/key]
|
|
||||||
[key] mod = {"Super", "Shift"} key = "F8" func = "tag_client" cmd = "7" [/key]
|
|
||||||
|
|
||||||
[key] mod = {"Super"} key = "minus" func = "tag_del" [/key]
|
# Swap current client with the previous.
|
||||||
[key] mod = {"Super", "Shift"} key = "minus" func = "tag_new" [/key]
|
[key] mod = {"Alt", "Shift"} key = "t" func = "client_swap_prev" [/key]
|
||||||
|
|
||||||
# tag function: cmd = nameofthetag
|
# Set the selected client as Master
|
||||||
#[key] mod = {"Super"} key = "z" func = "tag" cmd = "2" [/key]
|
[key] mod = {"Control"} key = "m" func = "client_set_master" [/key]
|
||||||
|
|
||||||
|
# Toggle maximum the selected client
|
||||||
|
[key] mod = {"Alt"} key = "m" func = "toggle_max" [/key]
|
||||||
|
|
||||||
|
# Toggle free the selected client.
|
||||||
|
[key] mod = {"Alt"} key = "f" func = "toggle_free" [/key]
|
||||||
|
|
||||||
|
# Toggle the position of the infobar.
|
||||||
|
[key] mod = {"Alt"} key = "b" func = "toggle_infobar_position" [/key]
|
||||||
|
[key] mod = {"Alt", "Shift"} key = "b" func = "toggle_infobar_display" [/key]
|
||||||
|
|
||||||
|
# Toggle the resizehint of the current tag/screen
|
||||||
|
[key] mod = {"Shift", "Control"} key = "r" func = "toggle_resizehint" [/key]
|
||||||
|
|
||||||
|
# Toggle the tag_autohide mode
|
||||||
|
[key] mod = {"Shift", "Control"} key = "t" func = "toggle_tagautohide" [/key]
|
||||||
|
|
||||||
|
# Select the next client.
|
||||||
|
[key] mod = {"Alt"} key = "Tab" func = "client_next" [/key]
|
||||||
|
|
||||||
|
# Select the previous client.
|
||||||
|
[key] mod = {"Alt","Shift"} key = "Tab" func = "client_prev" [/key]
|
||||||
|
|
||||||
|
# Select the next tag.
|
||||||
[key] mod = {"Control"} key = "Right" func = "tag_next" [/key]
|
[key] mod = {"Control"} key = "Right" func = "tag_next" [/key]
|
||||||
|
|
||||||
|
# Select the previous tag.
|
||||||
[key] mod = {"Control"} key = "Left" func = "tag_prev" [/key]
|
[key] mod = {"Control"} key = "Left" func = "tag_prev" [/key]
|
||||||
|
|
||||||
[key] mod = {"Control"} key = "Up" func = "screen_next" [/key]
|
# Select the next visible tag.
|
||||||
[key] mod = {"Control"} key = "Down" func = "screen_prev" [/key]
|
[key] mod = {"Control","Alt"} key = "Right" func = "tag_next_visible" [/key]
|
||||||
|
|
||||||
[key] mod = {"Super"} key = "q" func = "client_close" [/key]
|
# Select the previous visible tag.
|
||||||
|
[key] mod = {"Control","Alt"} key = "Left" func = "tag_prev_visible" [/key]
|
||||||
|
|
||||||
# Focus next / prev client and next / prev tabbed client
|
# Set the next layout.
|
||||||
[key] mod = { "Alt" } key = "Tab" func = "client_focus_next" [/key]
|
[key] mod = {"Alt"} key = "space" func = "layout_next" [/key]
|
||||||
[key] mod = { "Alt", "Shift" } key = "Tab" func = "client_focus_prev" [/key]
|
|
||||||
[key] mod = { "Super" } key = "Tab" func = "client_focus_next_tab" [/key]
|
|
||||||
[key] mod = { "Super", "Shift" } key = "Tab" func = "client_focus_prev_tab" [/key]
|
|
||||||
|
|
||||||
# Focus next client with direction
|
# Set the previous layout.
|
||||||
[key] mod = {"Alt"} key = "h" func = "client_focus_left" [/key]
|
[key] mod = {"Alt", "Shift"} key = "space" func = "layout_prev" [/key]
|
||||||
[key] mod = {"Alt"} key = "l" func = "client_focus_right" [/key]
|
|
||||||
[key] mod = {"Alt"} key = "k" func = "client_focus_top" [/key]
|
|
||||||
[key] mod = {"Alt"} key = "j" func = "client_focus_bottom" [/key]
|
|
||||||
|
|
||||||
# swap next client with direction:
|
# Increase mwfact.
|
||||||
[key] mod = {"Control", "Shift"} key = "h" func = "client_swap_left" [/key]
|
[key] mod = {"Alt"} key = "l" func = "set_mwfact" cmd = "+0.025" [/key]
|
||||||
[key] mod = {"Control", "Shift"} key = "l" func = "client_swap_right" [/key]
|
|
||||||
[key] mod = {"Control", "Shift"} key = "k" func = "client_swap_top" [/key]
|
|
||||||
[key] mod = {"Control", "Shift"} key = "j" func = "client_swap_bottom" [/key]
|
|
||||||
|
|
||||||
# Resize selected tiled client with direction
|
# Decrease mwfact.
|
||||||
[key] mod = {"Super"} key = "h" func = "client_resize_left" cmd = "20" [/key]
|
[key] mod = {"Alt"} key = "h" func = "set_mwfact" cmd = "-0.025" [/key]
|
||||||
[key] mod = {"Super"} key = "l" func = "client_resize_left" cmd = "-20" [/key]
|
|
||||||
[key] mod = {"Super"} key = "k" func = "client_resize_top" cmd = "20" [/key]
|
|
||||||
[key] mod = {"Super"} key = "j" func = "client_resize_top" cmd = "-20" [/key]
|
|
||||||
[key] mod = {"Super", "Control"} key = "h" func = "client_resize_right" cmd = "-20" [/key]
|
|
||||||
[key] mod = {"Super", "Control"} key = "l" func = "client_resize_right" cmd = "20" [/key]
|
|
||||||
[key] mod = {"Super", "Control"} key = "k" func = "client_resize_bottom" cmd = "-20" [/key]
|
|
||||||
[key] mod = {"Super", "Control"} key = "j" func = "client_resize_bottom" cmd = "20" [/key]
|
|
||||||
|
|
||||||
# Tabbing command
|
# Increase nmaster.
|
||||||
[key] mod = {"Alt", "Shift"} key = "h" func = "client_tab_left" [/key]
|
[key] mod = {"Alt"} key = "d" func = "set_nmaster" cmd = "+1" [/key]
|
||||||
[key] mod = {"Alt", "Shift"} key = "l" func = "client_tab_right" [/key]
|
|
||||||
[key] mod = {"Alt", "Shift"} key = "k" func = "client_tab_top" [/key]
|
|
||||||
[key] mod = {"Alt", "Shift"} key = "j" func = "client_tab_bottom" [/key]
|
|
||||||
[key] mod = {"Alt", "Shift"} key = "u" func = "client_untab" [/key]
|
|
||||||
[key] mod = {"Super"} key = "t" func = "client_tab_next_opened" [/key]
|
|
||||||
|
|
||||||
# Layout manipulation
|
# Decease nmaster.
|
||||||
[key] mod = {"Super"} key = "m" func = "layout_vmirror" [/key]
|
[key] mod = {"Alt", "Shift"} key = "d" func = "set_nmaster" cmd = "-1" [/key]
|
||||||
[key] mod = {"Super", "Shift"} key = "m" func = "layout_hmirror" [/key]
|
|
||||||
[key] mod = {"Super"} key = "r" func = "layout_rotate_right" [/key]
|
|
||||||
[key] mod = {"Super", "Shift"} key = "r" func = "layout_rotate_left" [/key]
|
|
||||||
|
|
||||||
[key] mod = {"Control", "Super", "Alt"} key = "h" func = "layout_integrate_left" [/key]
|
#Launcher.
|
||||||
[key] mod = {"Control", "Super", "Alt"} key = "j" func = "layout_integrate_bottom" [/key]
|
[key] mod = {"Alt"} key = "p" func = "launcher" cmd = "launcher_exec" [/key]
|
||||||
[key] mod = {"Control", "Super", "Alt"} key = "k" func = "layout_integrate_top" [/key]
|
|
||||||
[key] mod = {"Control", "Super", "Alt"} key = "l" func = "layout_integrate_right" [/key]
|
|
||||||
|
|
||||||
# Layout set historic travelling function (TESTING)
|
#ViWMFS
|
||||||
[key] mod = {"Super"} key = "o" func = "layout_prev_set" [/key]
|
[key] mod = {"Alt"} key = "Escape" func = "launcher" cmd = "viwmfs" [/key]
|
||||||
[key] mod = {"Super", "Shift"} key = "o" func = "layout_next_set" [/key]
|
|
||||||
|
|
||||||
# Toggle client free/tile
|
# Set the tag x.
|
||||||
[key] mod = {"Super"} key = "f" func = "client_toggle_free" [/key]
|
[key] mod = {"Alt"} key = "F1" func = "tag" cmd = "1" [/key]
|
||||||
|
[key] mod = {"Alt"} key = "F2" func = "tag" cmd = "2" [/key]
|
||||||
|
[key] mod = {"Alt"} key = "F3" func = "tag" cmd = "3" [/key]
|
||||||
|
[key] mod = {"Alt"} key = "F4" func = "tag" cmd = "4" [/key]
|
||||||
|
[key] mod = {"Alt"} key = "F5" func = "tag" cmd = "5" [/key]
|
||||||
|
[key] mod = {"Alt"} key = "F6" func = "tag" cmd = "6" [/key]
|
||||||
|
[key] mod = {"Alt"} key = "F7" func = "tag" cmd = "7" [/key]
|
||||||
|
[key] mod = {"Alt"} key = "F8" func = "tag" cmd = "8" [/key]
|
||||||
|
[key] mod = {"Alt"} key = "F9" func = "tag" cmd = "9" [/key]
|
||||||
|
|
||||||
# Toggle client ignore_tag
|
# Transfert selected client to x.
|
||||||
[key] mod = {"Super", "Shift"} key = "f" func = "client_toggle_ignore_tag" [/key]
|
[key] mod = {"Alt", "Shift"} key = "F1" func = "tag_transfert" cmd ="1" [/key]
|
||||||
|
[key] mod = {"Alt", "Shift"} key = "F2" func = "tag_transfert" cmd ="2" [/key]
|
||||||
|
[key] mod = {"Alt", "Shift"} key = "F3" func = "tag_transfert" cmd ="3" [/key]
|
||||||
|
[key] mod = {"Alt", "Shift"} key = "F4" func = "tag_transfert" cmd ="4" [/key]
|
||||||
|
[key] mod = {"Alt", "Shift"} key = "F5" func = "tag_transfert" cmd ="5" [/key]
|
||||||
|
[key] mod = {"Alt", "Shift"} key = "F6" func = "tag_transfert" cmd ="6" [/key]
|
||||||
|
[key] mod = {"Alt", "Shift"} key = "F7" func = "tag_transfert" cmd ="7" [/key]
|
||||||
|
[key] mod = {"Alt", "Shift"} key = "F8" func = "tag_transfert" cmd ="8" [/key]
|
||||||
|
[key] mod = {"Alt", "Shift"} key = "F9" func = "tag_transfert" cmd ="9" [/key]
|
||||||
|
|
||||||
# Toggle infobar visibility
|
# Toggle additional tags (x) on the current tag
|
||||||
[key] mod = {"Super", "Shift"} key = "h" func = "infobar_toggle_hide" cmd = "default" [/key]
|
[key] mod = {"Alt", "Super"} key = "F1" func = "tag_toggle_additional" cmd ="1" [/key]
|
||||||
|
[key] mod = {"Alt", "Super"} key = "F2" func = "tag_toggle_additional" cmd ="2" [/key]
|
||||||
|
[key] mod = {"Alt", "Super"} key = "F3" func = "tag_toggle_additional" cmd ="3" [/key]
|
||||||
|
[key] mod = {"Alt", "Super"} key = "F4" func = "tag_toggle_additional" cmd ="4" [/key]
|
||||||
|
[key] mod = {"Alt", "Super"} key = "F5" func = "tag_toggle_additional" cmd ="5" [/key]
|
||||||
|
[key] mod = {"Alt", "Super"} key = "F6" func = "tag_toggle_additional" cmd ="6" [/key]
|
||||||
|
[key] mod = {"Alt", "Super"} key = "F7" func = "tag_toggle_additional" cmd ="7" [/key]
|
||||||
|
[key] mod = {"Alt", "Super"} key = "F8" func = "tag_toggle_additional" cmd ="8" [/key]
|
||||||
|
[key] mod = {"Alt", "Super"} key = "F9" func = "tag_toggle_additional" cmd ="9" [/key]
|
||||||
|
|
||||||
# Launcher
|
# change screen
|
||||||
[key] mod = {"Super"} key = "p" func = "launcher" cmd = "exec" [/key]
|
[key] mod = {"Super"} key = "Tab" func = "screen_next" [/key]
|
||||||
|
[key] mod = {"Super", "Shift"} key = "Tab" func = "screen_prev" [/key]
|
||||||
|
|
||||||
|
# swap client in the next/prev screen
|
||||||
|
[key] mod = {"Super", "Shift"} key = "a" func = "client_screen_next" [/key]
|
||||||
|
[key] mod = {"Super", "Shift"} key = "z" func = "client_screen_prev" [/key]
|
||||||
|
|
||||||
|
[key] mod = {"Alt"} key = "e" func = "toggle_tag_expose" [/key]
|
||||||
|
|
||||||
|
# unlisted fonctions that can be used in [key] func = ""
|
||||||
|
# client_focus_{right, left, top, bottom}
|
||||||
|
# client_ignore_tag # Toggle the client in ignore_tag (display the client on all tags)
|
||||||
|
# tag_prev_sel # go back to the previous selected tag
|
||||||
|
# tag_transfert_{next, prev}
|
||||||
|
# tag_urgent # go to the urgent tag
|
||||||
|
# tag_swap_{next, prev} # swap tag with the previous/next one
|
||||||
|
# tag_last # go to the last tag
|
||||||
|
# tag_stay_last # toggle the current tag as the last one
|
||||||
|
# toggle_abovefc
|
||||||
|
# screen_prev_sel # go to the previous screen selected
|
||||||
|
# set_layout # set layout. need to be called with cmd = "<layout_name>"
|
||||||
|
# ignore_next_client_rules # ignore the rule the next time a rule is called
|
||||||
[/keys]
|
[/keys]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user