Compare commits
No commits in common. "master" and "linkdd" have entirely different histories.
@ -11,14 +11,13 @@ SRCS= \
|
|||||||
src/ewmh.c \
|
src/ewmh.c \
|
||||||
src/infobar.c \
|
src/infobar.c \
|
||||||
src/layout.c \
|
src/layout.c \
|
||||||
src/launcher.c \
|
|
||||||
src/parse_api.c \
|
src/parse_api.c \
|
||||||
src/parse.c \
|
src/parse.c \
|
||||||
src/screen.c \
|
src/screen.c \
|
||||||
src/tag.c \
|
src/tag.c \
|
||||||
src/util.c \
|
src/util.c \
|
||||||
|
src/fifo.c \
|
||||||
src/status.c \
|
src/status.c \
|
||||||
src/systray.c \
|
|
||||||
src/mouse.c \
|
src/mouse.c \
|
||||||
src/log.c \
|
src/log.c \
|
||||||
src/wmfs.c
|
src/wmfs.c
|
||||||
@ -53,13 +52,9 @@ install: all
|
|||||||
install ${PROG} ${DESTDIR}${PREFIX}/bin
|
install ${PROG} ${DESTDIR}${PREFIX}/bin
|
||||||
@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
|
|
||||||
@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
|
||||||
@ -68,8 +63,6 @@ uninstall:
|
|||||||
@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:
|
dist:
|
||||||
@echo "Generate wmfs-`date +%Y%m`.tar.gz"
|
@echo "Generate wmfs-`date +%Y%m`.tar.gz"
|
||||||
|
|||||||
92
configure
vendored
92
configure
vendored
@ -11,77 +11,61 @@ MANPREFIX="$PREFIX/man"
|
|||||||
XDG_CONFIG_DIR="$PREFIX/etc/xdg"
|
XDG_CONFIG_DIR="$PREFIX/etc/xdg"
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
--without-xinerama)
|
--without-xinerama)
|
||||||
USE_XINERAMA=""; shift;;
|
USE_XINERAMA=""; shift;;
|
||||||
--without-imlib2)
|
--prefix)
|
||||||
USE_IMLIB2=""; shift;;
|
[ -z "$2" ] && echo "Missing argument" && exit 1
|
||||||
--prefix)
|
PREFIX=$2; shift 2;;
|
||||||
[ -z "$2" ] && echo "Missing argument" && exit 1
|
--xdg-config-dir)
|
||||||
PREFIX=$2; shift 2;;
|
[ -z "$2" ] && echo "Missing argument" && exit 1
|
||||||
--man-prefix)
|
XDG_CONFIG_DIR=$2; shift 2;;
|
||||||
[ -z "$2" ] && echo "Missing argument" && exit 1
|
--help|-h)
|
||||||
MANPREFIX=$2; shift 2;;
|
echo "Usage: ./configure [options]
|
||||||
--xdg-config-dir)
|
|
||||||
[ -z "$2" ] && echo "Missing argument" && exit 1
|
|
||||||
XDG_CONFIG_DIR=$2; shift 2;;
|
|
||||||
--help|-h)
|
|
||||||
echo "Usage: ./configure [options]
|
|
||||||
--without-xinerama : compile without xinerama support
|
--without-xinerama : compile without xinerama support
|
||||||
--without-imlib2 : compile without imlib2 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)"
|
||||||
exit 0;;
|
exit 0;;
|
||||||
*) break;;
|
*) break;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
LIBS="$LIBS $USE_XINERAMA $USE_IMLIB2"
|
LIBS="$LIBS $USE_XINERAMA"
|
||||||
|
|
||||||
which pkg-config > /dev/null 2>&1
|
which pkg-config > /dev/null 2>&1
|
||||||
|
|
||||||
if [ $? -eq 0 ];
|
if [ $? -eq 0 ];
|
||||||
then
|
then
|
||||||
CFLAGS=`pkg-config --cflags-only-I $LIBS`
|
CFLAGS=`pkg-config --cflags-only-I $LIBS`
|
||||||
LDFLAGS=`pkg-config --libs $LIBS`
|
LDFLAGS=`pkg-config --libs $LIBS`
|
||||||
else
|
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"
|
||||||
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/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/local/include"
|
||||||
LDFLAGS="-L/usr/X11R7/lib -L/usr/pkg/lib";;
|
LDFLAGS="-L/usr/X11R7/lib -L/usr/local/lib";;
|
||||||
Linux)
|
Linux)
|
||||||
CFLAGS=""
|
CFLAGS=""
|
||||||
LDFLAGS=""
|
LDFLAGS=""
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "No default CFLAGS and LDFLAGS found for your OS, feel free to contribute or install pkg-config :)"
|
echo "No default CFLAGS and LDFLAGS found for your OS, feel free to contribute or install pkg-config :)"
|
||||||
exit 1;;
|
exit 1;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
LDFLAGS="$LDFLAGS -lX11"
|
LDFLAGS="$LDFLAGS -lX11"
|
||||||
|
|
||||||
|
[ -n "$USE_XINERAMA" ] && LDFLAGS="$LDFLAGS -lXinerama"
|
||||||
|
|
||||||
[ -n "$USE_XINERAMA" ] && LDFLAGS="$LDFLAGS -lXinerama"
|
|
||||||
[ -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"
|
|
||||||
|
|
||||||
# Debian hardening options http://wiki.debian.org/Hardening
|
|
||||||
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
|
|
||||||
@ -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"
|
|
||||||
@ -5,9 +5,7 @@ TIMING=10
|
|||||||
|
|
||||||
statustext()
|
statustext()
|
||||||
{
|
{
|
||||||
# Syntax : status <bar name> <data>
|
echo "status default `date`" > /tmp/wmfs-$DISPLAY.fifo
|
||||||
# possible sequences as data: \s[] \R[] \i[]
|
|
||||||
wmfs -c status "default `date`"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while true;
|
while true;
|
||||||
|
|||||||
@ -23,7 +23,7 @@ barwin_new(Window parent, int x, int y, int w, int h, Color fg, Color bg, bool e
|
|||||||
struct barwin *b = (struct barwin*)xcalloc(1, sizeof(struct barwin));
|
struct barwin *b = (struct barwin*)xcalloc(1, sizeof(struct barwin));
|
||||||
XSetWindowAttributes at =
|
XSetWindowAttributes at =
|
||||||
{
|
{
|
||||||
.override_redirect = true,
|
.override_redirect = True,
|
||||||
.background_pixmap = ParentRelative,
|
.background_pixmap = ParentRelative,
|
||||||
.event_mask = BARWIN_MASK
|
.event_mask = BARWIN_MASK
|
||||||
};
|
};
|
||||||
@ -51,7 +51,6 @@ barwin_new(Window parent, int x, int y, int w, int h, Color fg, Color bg, bool e
|
|||||||
b->fg = fg;
|
b->fg = fg;
|
||||||
|
|
||||||
SLIST_INIT(&b->mousebinds);
|
SLIST_INIT(&b->mousebinds);
|
||||||
SLIST_INIT(&b->statusmousebinds);
|
|
||||||
|
|
||||||
/* Attach */
|
/* Attach */
|
||||||
SLIST_INSERT_HEAD(&W->h.barwin, b, next);
|
SLIST_INSERT_HEAD(&W->h.barwin, b, next);
|
||||||
|
|||||||
@ -22,14 +22,9 @@
|
|||||||
#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_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_map(b) XMapWindow(W->dpy, b->win);
|
||||||
#define barwin_unmap(b) XUnmapWindow(W->dpy, b->win);
|
#define barwin_unmap(b) XUnmapWindow(W->dpy, b->win);
|
||||||
|
#define barwin_move(b, x, y) XMoveWindow(W->dpy, b->win, x, y);
|
||||||
#define barwin_reparent(b, w) XReparentWindow(W->dpy, b->win, w, 0, 0);
|
#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);
|
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_remove(struct barwin *b);
|
||||||
void barwin_resize(struct barwin *b, int w, int h);
|
void barwin_resize(struct barwin *b, int w, int h);
|
||||||
|
|||||||
536
src/client.c
536
src/client.c
@ -9,42 +9,45 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "barwin.h"
|
#include "barwin.h"
|
||||||
|
#include "barwin.h"
|
||||||
#include "draw.h"
|
#include "draw.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "mouse.h"
|
#include "mouse.h"
|
||||||
|
|
||||||
#define CLIENT_RESIZE_DIR(D) \
|
#define CLIENT_MOUSE_MOD Mod1Mask
|
||||||
void uicb_client_resize_##D(Uicb cmd) \
|
|
||||||
{ \
|
|
||||||
if(W->client) \
|
|
||||||
client_fac_resize(W->client, D, ATOI(cmd)); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CLIENT_ACTION_DIR(A, D) \
|
#define CLIENT_RESIZE_DIR(D) \
|
||||||
void uicb_client_##A##_##D(Uicb cmd) \
|
void uicb_client_resize_##D(Uicb cmd) \
|
||||||
{ \
|
{ \
|
||||||
(void)cmd; \
|
if(W->client) \
|
||||||
struct client *c; \
|
client_fac_resize(W->client, D, ATOI(cmd)); \
|
||||||
if(W->client && (c = client_next_with_pos(W->client, D))) \
|
}
|
||||||
client_##A(c); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CLIENT_ACTION_IDIR(A, D) \
|
#define CLIENT_ACTION_DIR(A, D) \
|
||||||
void uicb_client_##A##_##D(Uicb cmd) \
|
void uicb_client_##A##_##D(Uicb cmd) \
|
||||||
{ \
|
{ \
|
||||||
(void)cmd; \
|
(void)cmd; \
|
||||||
if(W->client) \
|
struct client *c; \
|
||||||
client_##A(W->client, D); \
|
if(W->client && (c = client_next_with_pos(W->client, D))) \
|
||||||
}
|
client_##A(c); \
|
||||||
|
}
|
||||||
|
|
||||||
#define CLIENT_ACTION_LIST(A, L) \
|
#define CLIENT_ACTION_IDIR(A, D) \
|
||||||
void uicb_client_##A##_##L(Uicb cmd) \
|
void uicb_client_##A##_##D(Uicb cmd) \
|
||||||
{ \
|
{ \
|
||||||
(void)cmd; \
|
(void)cmd; \
|
||||||
struct client *c; \
|
if(W->client) \
|
||||||
if(W->client && (c = client_##L(W->client))) \
|
client_##A(W->client, D); \
|
||||||
client_##A(c); \
|
}
|
||||||
}
|
|
||||||
|
#define CLIENT_ACTION_LIST(A, L) \
|
||||||
|
void uicb_client_##A##_##L(Uicb cmd) \
|
||||||
|
{ \
|
||||||
|
(void)cmd; \
|
||||||
|
struct client *c; \
|
||||||
|
if(W->client && (c = client_##L(W->client))) \
|
||||||
|
client_##A(c); \
|
||||||
|
}
|
||||||
|
|
||||||
/* uicb_client_resize_dir() */
|
/* uicb_client_resize_dir() */
|
||||||
CLIENT_RESIZE_DIR(Right)
|
CLIENT_RESIZE_DIR(Right)
|
||||||
@ -87,7 +90,7 @@ CLIENT_ACTION_LIST(focus, prev_tab)
|
|||||||
/** Send a ConfigureRequest event to the struct client
|
/** Send a ConfigureRequest event to the struct client
|
||||||
* \param c struct client pointer
|
* \param c struct client pointer
|
||||||
*/
|
*/
|
||||||
void
|
inline void
|
||||||
client_configure(struct client *c)
|
client_configure(struct client *c)
|
||||||
{
|
{
|
||||||
XConfigureEvent ev =
|
XConfigureEvent ev =
|
||||||
@ -104,8 +107,8 @@ client_configure(struct client *c)
|
|||||||
.override_redirect = 0
|
.override_redirect = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
XSendEvent(W->dpy, c->win, false, StructureNotifyMask, (XEvent *)&ev);
|
XSendEvent(W->dpy, c->win, False, StructureNotifyMask, (XEvent *)&ev);
|
||||||
XSync(W->dpy, false);
|
XSync(W->dpy, False);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct client*
|
struct client*
|
||||||
@ -113,15 +116,10 @@ client_gb_win(Window w)
|
|||||||
{
|
{
|
||||||
struct client *c = SLIST_FIRST(&W->h.client);
|
struct client *c = SLIST_FIRST(&W->h.client);
|
||||||
|
|
||||||
while(c)
|
while(c && c->win != w)
|
||||||
{
|
|
||||||
if(c->win == w)
|
|
||||||
return c;
|
|
||||||
|
|
||||||
c = SLIST_NEXT(c, next);
|
c = SLIST_NEXT(c, next);
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct client*
|
struct client*
|
||||||
@ -129,26 +127,25 @@ client_gb_frame(Window w)
|
|||||||
{
|
{
|
||||||
struct client *c = SLIST_FIRST(&W->h.client);
|
struct client *c = SLIST_FIRST(&W->h.client);
|
||||||
|
|
||||||
while(c)
|
while(c && c->frame != w)
|
||||||
{
|
|
||||||
if(c->frame == w)
|
|
||||||
return c;
|
|
||||||
|
|
||||||
c = SLIST_NEXT(c, next);
|
c = SLIST_NEXT(c, next);
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct client*
|
struct client*
|
||||||
client_gb_pos(struct tag *t, int x, int y)
|
client_gb_pos(struct tag *t, int x, int y)
|
||||||
{
|
{
|
||||||
struct client *c;
|
struct client *c = SLIST_FIRST(&t->clients);
|
||||||
|
|
||||||
FOREACH_NFCLIENT(c, &t->clients, tnext)
|
while(c)
|
||||||
|
{
|
||||||
if(INAREA(x, y, c->geo))
|
if(INAREA(x, y, c->geo))
|
||||||
return c;
|
return c;
|
||||||
|
|
||||||
|
c = SLIST_NEXT(c, tnext);
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,18 +154,10 @@ client_gb_titlebar(Window w)
|
|||||||
{
|
{
|
||||||
struct client *c = SLIST_FIRST(&W->h.client);
|
struct client *c = SLIST_FIRST(&W->h.client);
|
||||||
|
|
||||||
if(!c->titlebar)
|
while(c && c->titlebar->win != w)
|
||||||
return NULL;
|
|
||||||
|
|
||||||
while(c)
|
|
||||||
{
|
|
||||||
if(c->titlebar->win == w)
|
|
||||||
return c;
|
|
||||||
|
|
||||||
c = SLIST_NEXT(c, next);
|
c = SLIST_NEXT(c, next);
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -198,68 +187,38 @@ client_next_with_pos(struct client *bc, enum position p)
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FLAG_SWAP2(f1, f2, m1) \
|
|
||||||
if((f1 & m1) != (f2 & m1)) \
|
|
||||||
{ \
|
|
||||||
f1 ^= m1; \
|
|
||||||
f2 ^= m1; \
|
|
||||||
}
|
|
||||||
#define SWAP_ARRANGE_TAB(C) \
|
|
||||||
SLIST_FOREACH(c, &C->tag->clients, tnext) \
|
|
||||||
{ \
|
|
||||||
if(c->tabmaster == C) \
|
|
||||||
{ \
|
|
||||||
c->screen = C->screen; \
|
|
||||||
if((C->flags & CLIENT_FREE) != (c->flags & CLIENT_FREE)) \
|
|
||||||
{ \
|
|
||||||
c->flags ^= CLIENT_FREE; \
|
|
||||||
c->flags ^= CLIENT_TILED; \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
void
|
void
|
||||||
client_swap2(struct client *c1, struct client *c2)
|
client_swap2(struct client *c1, struct client *c2)
|
||||||
{
|
{
|
||||||
struct client *c;
|
|
||||||
struct tag *t;
|
struct tag *t;
|
||||||
struct geo g;
|
|
||||||
|
|
||||||
/* Conflict / errors */
|
/* Conflict / errors */
|
||||||
if(c1 == c2 || !c1 || !c2)
|
if(c1 == c2 || !c1 || !c2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Reverse FREE/TILED flags if there are different */
|
/* are swapped geos compatible? */
|
||||||
FLAG_SWAP2(c1->flags, c2->flags, CLIENT_FREE);
|
if(client_winsize(c1, &c2->geo)
|
||||||
FLAG_SWAP2(c1->flags, c2->flags, CLIENT_TILED);
|
|| client_winsize(c2, &c1->geo))
|
||||||
|
return;
|
||||||
|
|
||||||
if(c1->screen != c2->screen)
|
if(c1->screen != c2->screen)
|
||||||
swap_ptr((void**)&c1->screen, (void**)&c2->screen);
|
swap_ptr((void**)&c1->screen, (void**)&c2->screen);
|
||||||
|
|
||||||
/*
|
|
||||||
* Arrange flags for all tabbed client of
|
|
||||||
* possible c1/c2 tabmaster
|
|
||||||
*/
|
|
||||||
if(c1->flags & CLIENT_TABMASTER)
|
|
||||||
SWAP_ARRANGE_TAB(c1);
|
|
||||||
if(c2->flags & CLIENT_TABMASTER)
|
|
||||||
SWAP_ARRANGE_TAB(c2);
|
|
||||||
|
|
||||||
if(c1->tag != c2->tag)
|
if(c1->tag != c2->tag)
|
||||||
{
|
{
|
||||||
c1->flags |= CLIENT_IGNORE_LAYOUT;
|
|
||||||
c2->flags |= CLIENT_IGNORE_LAYOUT;
|
|
||||||
|
|
||||||
t = c1->tag;
|
t = c1->tag;
|
||||||
tag_client(c2->tag, c1);
|
tag_client(c2->tag, c1);
|
||||||
tag_client(t, c2);
|
tag_client(t, c2);
|
||||||
}
|
}
|
||||||
|
|
||||||
g = c1->geo;
|
c1->tgeo = c2->geo;
|
||||||
client_moveresize(c1, &c2->geo);
|
c2->tgeo = c1->geo;
|
||||||
client_moveresize(c2, &g);
|
|
||||||
|
|
||||||
c1->flags |= CLIENT_IGNORE_ENTER;
|
c1->flags |= CLIENT_IGNORE_ENTER;
|
||||||
c2->flags |= CLIENT_IGNORE_ENTER;
|
c2->flags |= CLIENT_IGNORE_ENTER;
|
||||||
|
|
||||||
|
client_moveresize(c1, &c1->tgeo);
|
||||||
|
client_moveresize(c2, &c2->tgeo);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct client*
|
static inline struct client*
|
||||||
@ -304,7 +263,7 @@ client_swap(struct client *c, enum position p)
|
|||||||
if(ev.type == KeyPress)
|
if(ev.type == KeyPress)
|
||||||
{
|
{
|
||||||
XKeyPressedEvent *ke = &ev.xkey;
|
XKeyPressedEvent *ke = &ev.xkey;
|
||||||
keysym = XkbKeycodeToKeysym(W->dpy, (KeyCode)ke->keycode, 0, 0);
|
keysym = XKeycodeToKeysym(W->dpy, (KeyCode)ke->keycode, 0);
|
||||||
|
|
||||||
_REV_SBORDER();
|
_REV_SBORDER();
|
||||||
|
|
||||||
@ -363,13 +322,13 @@ client_grabbuttons(struct client *c, bool focused)
|
|||||||
|
|
||||||
while(i++ != Button5)
|
while(i++ != Button5)
|
||||||
{
|
{
|
||||||
XGrabButton(W->dpy, i, W->client_mod, c->win, False,
|
XGrabButton(W->dpy, i, CLIENT_MOUSE_MOD, c->win, False,
|
||||||
ButtonMask, GrabModeAsync, GrabModeSync, None, None);
|
ButtonMask, GrabModeAsync, GrabModeSync, None, None);
|
||||||
XGrabButton(W->dpy, i, W->client_mod | LockMask, c->win, False,
|
XGrabButton(W->dpy, i, CLIENT_MOUSE_MOD | LockMask, c->win, False,
|
||||||
ButtonMask, GrabModeAsync, GrabModeSync, None, None);
|
ButtonMask, GrabModeAsync, GrabModeSync, None, None);
|
||||||
XGrabButton(W->dpy, i, W->client_mod | W->numlockmask, c->win, False,
|
XGrabButton(W->dpy, i, CLIENT_MOUSE_MOD | W->numlockmask, c->win, False,
|
||||||
ButtonMask, GrabModeAsync, GrabModeSync, None, None);
|
ButtonMask, GrabModeAsync, GrabModeSync, None, None);
|
||||||
XGrabButton(W->dpy, i, W->client_mod | LockMask | W->numlockmask, c->win, False,
|
XGrabButton(W->dpy, i, CLIENT_MOUSE_MOD | LockMask | W->numlockmask, c->win, False,
|
||||||
ButtonMask, GrabModeAsync, GrabModeSync, None, None);
|
ButtonMask, GrabModeAsync, GrabModeSync, None, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,26 +346,10 @@ client_grabbuttons(struct client *c, bool focused)
|
|||||||
#define _REMAINDER() \
|
#define _REMAINDER() \
|
||||||
if((rm = ((x + f) - (c->rgeo.w - c->border))) > 0) \
|
if((rm = ((x + f) - (c->rgeo.w - c->border))) > 0) \
|
||||||
f -= rm;
|
f -= rm;
|
||||||
|
|
||||||
#define _STATUSLINE(C, b) \
|
|
||||||
do { \
|
|
||||||
sctx = (b ? &c->theme->client_s_sl : &c->theme->client_n_sl); \
|
|
||||||
sctx->barwin = C->titlebar; \
|
|
||||||
status_copy_mousebind(sctx); \
|
|
||||||
status_render(sctx); \
|
|
||||||
if(C->flags & CLIENT_FREE) \
|
|
||||||
{ \
|
|
||||||
sctx = &c->theme->client_f_sl; \
|
|
||||||
sctx->barwin = C->titlebar; \
|
|
||||||
status_copy_mousebind(sctx); \
|
|
||||||
status_render(sctx); \
|
|
||||||
} \
|
|
||||||
} while(/* CONSTCOND */ 0);
|
|
||||||
void
|
void
|
||||||
client_frame_update(struct client *c, struct colpair *cp)
|
client_frame_update(struct client *c, struct colpair *cp)
|
||||||
{
|
{
|
||||||
struct client *cc;
|
struct client *cc;
|
||||||
struct status_ctx *sctx;
|
|
||||||
int y, f, xt, rm, w, n = 1;
|
int y, f, xt, rm, w, n = 1;
|
||||||
|
|
||||||
if(c->flags & CLIENT_TABBED)
|
if(c->flags & CLIENT_TABBED)
|
||||||
@ -441,9 +384,6 @@ client_frame_update(struct client *c, struct colpair *cp)
|
|||||||
barwin_move(c->titlebar, 0, 0);
|
barwin_move(c->titlebar, 0, 0);
|
||||||
barwin_resize(c->titlebar, f, c->tbarw);
|
barwin_resize(c->titlebar, f, c->tbarw);
|
||||||
barwin_refresh_color(c->titlebar);
|
barwin_refresh_color(c->titlebar);
|
||||||
|
|
||||||
_STATUSLINE(c, (cp == &c->scol));
|
|
||||||
|
|
||||||
draw_text(c->titlebar->dr, c->theme, xt, y, cp->fg, c->title);
|
draw_text(c->titlebar->dr, c->theme, xt, y, cp->fg, c->title);
|
||||||
barwin_refresh(c->titlebar);
|
barwin_refresh(c->titlebar);
|
||||||
}
|
}
|
||||||
@ -452,12 +392,10 @@ client_frame_update(struct client *c, struct colpair *cp)
|
|||||||
{
|
{
|
||||||
struct geo g = { f - 1, 0, 1, c->titlebar->geo.h };
|
struct geo g = { f - 1, 0, 1, c->titlebar->geo.h };
|
||||||
int x = c->border;
|
int x = c->border;
|
||||||
char *title;
|
|
||||||
|
|
||||||
SLIST_FOREACH(cc, &c->tag->clients, tnext)
|
SLIST_FOREACH(cc, &c->tag->clients, tnext)
|
||||||
{
|
{
|
||||||
title = (cc->title ? cc->title : "WMFS");
|
w = (cc->title ? draw_textw(c->theme, cc->title) : 0);
|
||||||
w = draw_textw(c->theme, title);
|
|
||||||
_XTEXT();
|
_XTEXT();
|
||||||
|
|
||||||
if(cc == c)
|
if(cc == c)
|
||||||
@ -469,10 +407,8 @@ client_frame_update(struct client *c, struct colpair *cp)
|
|||||||
barwin_resize(c->titlebar, f, c->tbarw);
|
barwin_resize(c->titlebar, f, c->tbarw);
|
||||||
|
|
||||||
barwin_refresh_color(c->titlebar);
|
barwin_refresh_color(c->titlebar);
|
||||||
|
draw_rect(cc->titlebar->dr, g, c->scol.bg);
|
||||||
_STATUSLINE(c, true);
|
draw_text(c->titlebar->dr, c->theme, xt, y, cp->fg, c->title);
|
||||||
draw_rect(c->titlebar->dr, &g, c->scol.bg);
|
|
||||||
draw_text(c->titlebar->dr, c->theme, xt, y, cp->fg, title);
|
|
||||||
barwin_refresh(c->titlebar);
|
barwin_refresh(c->titlebar);
|
||||||
|
|
||||||
x += f;
|
x += f;
|
||||||
@ -487,10 +423,8 @@ client_frame_update(struct client *c, struct colpair *cp)
|
|||||||
barwin_resize(cc->titlebar, f, c->tbarw - 2);
|
barwin_resize(cc->titlebar, f, c->tbarw - 2);
|
||||||
|
|
||||||
barwin_refresh_color(cc->titlebar);
|
barwin_refresh_color(cc->titlebar);
|
||||||
|
draw_rect(cc->titlebar->dr, g, c->scol.bg);
|
||||||
_STATUSLINE(cc, false);
|
draw_text(cc->titlebar->dr, c->theme, xt, y - 1, c->ncol.fg, cc->title);
|
||||||
draw_rect(cc->titlebar->dr, &g, c->scol.bg);
|
|
||||||
draw_text(cc->titlebar->dr, c->theme, xt, y - 1, c->ncol.fg, title);
|
|
||||||
barwin_refresh(cc->titlebar);
|
barwin_refresh(cc->titlebar);
|
||||||
|
|
||||||
x += f;
|
x += f;
|
||||||
@ -499,6 +433,7 @@ client_frame_update(struct client *c, struct colpair *cp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
client_tab_focus(struct client *c)
|
client_tab_focus(struct client *c)
|
||||||
{
|
{
|
||||||
@ -509,9 +444,7 @@ client_tab_focus(struct client *c)
|
|||||||
|
|
||||||
c->flags |= CLIENT_TABMASTER;
|
c->flags |= CLIENT_TABMASTER;
|
||||||
c->flags &= ~CLIENT_TABBED;
|
c->flags &= ~CLIENT_TABBED;
|
||||||
|
|
||||||
client_moveresize(c, &c->tabmaster->geo);
|
client_moveresize(c, &c->tabmaster->geo);
|
||||||
|
|
||||||
if(c->tag == c->screen->seltag)
|
if(c->tag == c->screen->seltag)
|
||||||
client_map(c);
|
client_map(c);
|
||||||
|
|
||||||
@ -544,12 +477,9 @@ client_tab_focus(struct client *c)
|
|||||||
void
|
void
|
||||||
_client_tab(struct client *c, struct client *cm)
|
_client_tab(struct client *c, struct client *cm)
|
||||||
{
|
{
|
||||||
Flags m[2] = { CLIENT_TILED, CLIENT_FREE };
|
/* Do not tab already tabed client */
|
||||||
|
|
||||||
/* Do not tab already tabbed client */
|
|
||||||
if(c->flags & (CLIENT_TABBED | CLIENT_TABMASTER)
|
if(c->flags & (CLIENT_TABBED | CLIENT_TABMASTER)
|
||||||
|| c->tag != cm->tag || c == cm
|
|| c->tag != cm->tag || c == cm)
|
||||||
|| !COMPCLIENT(c, cm))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
layout_split_arrange_closed(c);
|
layout_split_arrange_closed(c);
|
||||||
@ -558,12 +488,6 @@ _client_tab(struct client *c, struct client *cm)
|
|||||||
c->geo = cm->geo;
|
c->geo = cm->geo;
|
||||||
cm->tabmaster = c;
|
cm->tabmaster = c;
|
||||||
|
|
||||||
if(cm->flags & CLIENT_FREE)
|
|
||||||
swap_int((int*)&m[0], (int*)&m[1]);
|
|
||||||
|
|
||||||
c->flags |= m[0];
|
|
||||||
c->flags &= ~m[1];
|
|
||||||
|
|
||||||
client_focus(cm);
|
client_focus(cm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -588,7 +512,6 @@ client_untab(struct client *c)
|
|||||||
{
|
{
|
||||||
client_tab_focus(cc);
|
client_tab_focus(cc);
|
||||||
c->flags &= ~CLIENT_TABBED;
|
c->flags &= ~CLIENT_TABBED;
|
||||||
c->flags |= CLIENT_IGNORE_ENTER;
|
|
||||||
c->tabmaster = NULL;
|
c->tabmaster = NULL;
|
||||||
|
|
||||||
/* Looking for tabbed client in cc, if there is not
|
/* Looking for tabbed client in cc, if there is not
|
||||||
@ -608,8 +531,7 @@ client_untab(struct client *c)
|
|||||||
{
|
{
|
||||||
c->geo = c->tgeo = og;
|
c->geo = c->tgeo = og;
|
||||||
|
|
||||||
c->tag->sel = cc;
|
layout_split_integrate(c, cc);
|
||||||
layout_client(c);
|
|
||||||
client_map(c);
|
client_map(c);
|
||||||
client_moveresize(c, &c->geo);
|
client_moveresize(c, &c->geo);
|
||||||
client_update_props(c, CPROP_TAB);
|
client_update_props(c, CPROP_TAB);
|
||||||
@ -645,17 +567,7 @@ client_focus(struct client *c)
|
|||||||
client_grabbuttons(c, true);
|
client_grabbuttons(c, true);
|
||||||
client_tab_focus(c);
|
client_tab_focus(c);
|
||||||
client_frame_update(c, CCOL(c));
|
client_frame_update(c, CCOL(c));
|
||||||
|
|
||||||
if(c->flags & CLIENT_FREE
|
|
||||||
&& !(c->flags & (CLIENT_FULLSCREEN | CLIENT_TABBED)))
|
|
||||||
{
|
|
||||||
c->tag->flags |= CLIENT_IGNORE_ENTER;
|
|
||||||
XRaiseWindow(W->dpy, c->frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
XSetInputFocus(W->dpy, c->win, RevertToPointerRoot, CurrentTime);
|
XSetInputFocus(W->dpy, c->win, RevertToPointerRoot, CurrentTime);
|
||||||
XChangeProperty(W->dpy, W->root, W->net_atom[net_active_window], XA_WINDOW, 32,
|
|
||||||
PropModeReplace, (unsigned char *)&c->win, 1);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -688,10 +600,10 @@ client_get_name(struct client *c)
|
|||||||
unsigned long ir, il;
|
unsigned long ir, il;
|
||||||
|
|
||||||
/* This one instead XFetchName for utf8 name support */
|
/* This one instead XFetchName for utf8 name support */
|
||||||
if(XGetWindowProperty(W->dpy, c->win, W->net_atom[net_wm_name], 0, 65536,
|
if(XGetWindowProperty(W->dpy, c->win, ATOM("_NET_WM_NAME"), 0, 4096,
|
||||||
False, W->net_atom[utf8_string], &rt, &rf, &ir, &il, (unsigned char**)&c->title) != Success)
|
False, ATOM("UTF8_STRING"), &rt, &rf, &ir, &il, (unsigned char**)&c->title) != Success)
|
||||||
XGetWindowProperty(W->dpy, c->win, W->net_atom[net_wm_name], 0, 65536,
|
XGetWindowProperty(W->dpy, c->win, ATOM("WM_NAME"), 0, 4096,
|
||||||
False, W->net_atom[utf8_string], &rt, &rf, &ir, &il, (unsigned char**)&c->title);
|
False, ATOM("UTF8_STRING"), &rt, &rf, &ir, &il, (unsigned char**)&c->title);
|
||||||
|
|
||||||
/* Still no title... */
|
/* Still no title... */
|
||||||
if(!c->title)
|
if(!c->title)
|
||||||
@ -742,7 +654,7 @@ uicb_client_close(Uicb cmd)
|
|||||||
client_close(W->client);
|
client_close(W->client);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
client_get_sizeh(struct client *c)
|
client_get_sizeh(struct client *c)
|
||||||
{
|
{
|
||||||
long msize;
|
long msize;
|
||||||
@ -809,7 +721,6 @@ static void
|
|||||||
client_frame_new(struct client *c)
|
client_frame_new(struct client *c)
|
||||||
{
|
{
|
||||||
struct barwin *frameb;
|
struct barwin *frameb;
|
||||||
struct barwin *clientb;
|
|
||||||
XSetWindowAttributes at =
|
XSetWindowAttributes at =
|
||||||
{
|
{
|
||||||
.background_pixel = c->ncol.bg,
|
.background_pixel = c->ncol.bg,
|
||||||
@ -820,7 +731,6 @@ client_frame_new(struct client *c)
|
|||||||
|
|
||||||
/* Use a fake barwin only to store mousebinds of frame win */
|
/* Use a fake barwin only to store mousebinds of frame win */
|
||||||
frameb = barwin_new(W->root, 0, 0, 1, 1, 0, 0, false);
|
frameb = barwin_new(W->root, 0, 0, 1, 1, 0, 0, false);
|
||||||
clientb = barwin_new(W->root, 0, 0, 1, 1, 0, 0, false);
|
|
||||||
|
|
||||||
frameb->win =
|
frameb->win =
|
||||||
c->frame = XCreateWindow(W->dpy, W->root,
|
c->frame = XCreateWindow(W->dpy, W->root,
|
||||||
@ -831,10 +741,8 @@ client_frame_new(struct client *c)
|
|||||||
CopyFromParent,
|
CopyFromParent,
|
||||||
(CWOverrideRedirect | CWBackPixmap
|
(CWOverrideRedirect | CWBackPixmap
|
||||||
| CWBackPixel | CWEventMask), &at);
|
| CWBackPixel | CWEventMask), &at);
|
||||||
clientb->win = c->win;
|
|
||||||
|
|
||||||
frameb->mousebinds = W->tmp_head.client;
|
frameb->mousebinds = W->tmp_head.client;
|
||||||
clientb->mousebinds = W->tmp_head.client;
|
|
||||||
|
|
||||||
if(c->tbarw > c->border)
|
if(c->tbarw > c->border)
|
||||||
{
|
{
|
||||||
@ -847,34 +755,6 @@ client_frame_new(struct client *c)
|
|||||||
XReparentWindow(W->dpy, c->win, c->frame, c->border, c->tbarw);
|
XReparentWindow(W->dpy, c->win, c->frame, c->border, c->tbarw);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
_apply_rule(struct client *c, struct rule *r)
|
|
||||||
{
|
|
||||||
if(r->screen != -1)
|
|
||||||
c->screen = screen_gb_id(r->screen);
|
|
||||||
|
|
||||||
c->tag = c->screen->seltag;
|
|
||||||
if(r->tag != -1)
|
|
||||||
c->tag = tag_gb_id(c->screen, r->tag);
|
|
||||||
|
|
||||||
c->theme = r->theme;
|
|
||||||
|
|
||||||
/* free = false for originally free client */
|
|
||||||
if(r->flags & RULE_FREE)
|
|
||||||
c->flags |= CLIENT_FREE;
|
|
||||||
else
|
|
||||||
c->flags &= ~CLIENT_FREE;
|
|
||||||
|
|
||||||
/* Free rule is not compatible with tab rule */
|
|
||||||
if(r->flags & RULE_TAB)
|
|
||||||
W->flags ^= WMFS_TABNOC; /* < can be disable by client_tab_next_opened */
|
|
||||||
|
|
||||||
if(r->flags & RULE_IGNORE_TAG)
|
|
||||||
c->flags |= CLIENT_IGNORE_TAG;
|
|
||||||
|
|
||||||
c->flags |= CLIENT_RULED;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define RINSTANCE 0x01
|
#define RINSTANCE 0x01
|
||||||
#define RCLASS 0x02
|
#define RCLASS 0x02
|
||||||
#define RROLE 0x04
|
#define RROLE 0x04
|
||||||
@ -883,7 +763,6 @@ static void
|
|||||||
client_apply_rule(struct client *c)
|
client_apply_rule(struct client *c)
|
||||||
{
|
{
|
||||||
struct rule *r;
|
struct rule *r;
|
||||||
struct rule *defaultr = NULL;
|
|
||||||
char *wmname = NULL;
|
char *wmname = NULL;
|
||||||
char *role = NULL;
|
char *role = NULL;
|
||||||
int f;
|
int f;
|
||||||
@ -904,30 +783,42 @@ client_apply_rule(struct client *c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get _NET_WM_NAME */
|
/* Get _NET_WM_NAME */
|
||||||
if(XGetWindowProperty(W->dpy, c->win, W->net_atom[net_wm_name], 0, 0x77777777, false,
|
if(XGetWindowProperty(W->dpy, c->win, ATOM("_NET_WM_NAME"), 0, 0x77777777, false,
|
||||||
W->net_atom[utf8_string], &rf, &f, &n, &il, &data)
|
ATOM("UTF8_STRING"), &rf, &f, &n, &il, &data)
|
||||||
== Success && data)
|
== Success && data)
|
||||||
{
|
{
|
||||||
wmname = xstrdup((char*)data);
|
wmname = xstrdup((char*)data);
|
||||||
XFree(data);
|
XFree(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Apply a specific rule */
|
|
||||||
SLIST_FOREACH(r, &W->h.rule, next)
|
SLIST_FOREACH(r, &W->h.rule, next)
|
||||||
{
|
{
|
||||||
if (r->instance && !strcmp(r->instance, "*"))
|
|
||||||
defaultr = r;
|
|
||||||
if(s)
|
if(s)
|
||||||
{
|
{
|
||||||
FLAGAPPLY(flags, (xch.res_name && r->instance && !strcmp(xch.res_name, r->instance)), RINSTANCE);
|
FLAGAPPLY(flags, (xch.res_name && r->instance && !strcmp(xch.res_name, r->instance)), RINSTANCE);
|
||||||
FLAGAPPLY(flags, (xch.res_class && r->class && !strcmp(xch.res_class, r->class)), RCLASS);
|
FLAGAPPLY(flags, (xch.res_class && r->class && !strcmp(xch.res_class, r->class)), RCLASS);
|
||||||
}
|
}
|
||||||
|
|
||||||
FLAGAPPLY(flags, (wmname && r->name && !strcmp(wmname, r->name)), RNAME);
|
FLAGAPPLY(flags, (wmname && r->name && !strcmp(wmname, r->name)), RNAME);
|
||||||
FLAGAPPLY(flags, ((role && r->role && !strcmp(role, r->role)) || !role || !r->role), RROLE);
|
FLAGAPPLY(flags, ((role && r->role && !strcmp(role, r->role)) || !role || !r->role), RROLE);
|
||||||
|
|
||||||
if(flags & (RINSTANCE | RCLASS | RNAME) && flags & RROLE)
|
if(flags & (RINSTANCE | RCLASS | RNAME) && flags & RROLE)
|
||||||
_apply_rule(c, r);
|
{
|
||||||
|
c->screen = screen_gb_id(r->screen);
|
||||||
|
c->tag = tag_gb_id(c->screen, r->tag);
|
||||||
|
c->theme = r->theme;
|
||||||
|
|
||||||
|
if(r->flags & RULE_FREE)
|
||||||
|
{ /* TODO */ }
|
||||||
|
|
||||||
|
if(r->flags & RULE_MAX)
|
||||||
|
{ /* TODO */ }
|
||||||
|
|
||||||
|
if(r->flags & RULE_IGNORE_TAG)
|
||||||
|
{ /* TODO */ }
|
||||||
|
|
||||||
|
c->flags = r->flags | CLIENT_RULED;
|
||||||
|
}
|
||||||
flags = 0;
|
flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -936,10 +827,6 @@ client_apply_rule(struct client *c)
|
|||||||
|
|
||||||
if(wmname)
|
if(wmname)
|
||||||
free(wmname);
|
free(wmname);
|
||||||
|
|
||||||
/* Apply default rule */
|
|
||||||
if (!(c->flags & CLIENT_RULED) && defaultr != NULL)
|
|
||||||
_apply_rule(c, defaultr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct client*
|
struct client*
|
||||||
@ -951,7 +838,7 @@ client_new(Window w, XWindowAttributes *wa, bool scan)
|
|||||||
c->win = w;
|
c->win = w;
|
||||||
c->flags = 0;
|
c->flags = 0;
|
||||||
c->screen = screen_update_sel();
|
c->screen = screen_update_sel();
|
||||||
c->theme = W->ctheme;
|
c->theme = THEME_DEFAULT;
|
||||||
c->tag = NULL;
|
c->tag = NULL;
|
||||||
c->tabmaster = NULL;
|
c->tabmaster = NULL;
|
||||||
|
|
||||||
@ -963,14 +850,7 @@ client_new(Window w, XWindowAttributes *wa, bool scan)
|
|||||||
c->tgeo = c->wgeo = c->rgeo = c->geo;
|
c->tgeo = c->wgeo = c->rgeo = c->geo;
|
||||||
c->tbgeo = NULL;
|
c->tbgeo = NULL;
|
||||||
|
|
||||||
client_get_sizeh(c);
|
client_apply_rule(c);
|
||||||
|
|
||||||
if(!scan)
|
|
||||||
{
|
|
||||||
if(c->flags & CLIENT_HINT_FLAG /* && OPTIONKIVABIEN */)
|
|
||||||
c->flags |= CLIENT_FREE;
|
|
||||||
client_apply_rule(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Conf option set per client, for possibility
|
* Conf option set per client, for possibility
|
||||||
@ -985,11 +865,11 @@ client_new(Window w, XWindowAttributes *wa, bool scan)
|
|||||||
|
|
||||||
client_frame_new(c);
|
client_frame_new(c);
|
||||||
|
|
||||||
|
/* Set tag */
|
||||||
|
client_get_sizeh(c);
|
||||||
|
|
||||||
if(!scan)
|
if(!scan)
|
||||||
{
|
|
||||||
ewmh_manage_window_type(c);
|
|
||||||
tag_client((c->flags & CLIENT_RULED ? c->tag : c->screen->seltag), c);
|
tag_client((c->flags & CLIENT_RULED ? c->tag : c->screen->seltag), c);
|
||||||
}
|
|
||||||
|
|
||||||
/* Map, not at reload */
|
/* Map, not at reload */
|
||||||
if(c->tag == c->screen->seltag)
|
if(c->tag == c->screen->seltag)
|
||||||
@ -1003,16 +883,16 @@ client_new(Window w, XWindowAttributes *wa, bool scan)
|
|||||||
/* Attach */
|
/* Attach */
|
||||||
SLIST_INSERT_HEAD(&W->h.client, c, next);
|
SLIST_INSERT_HEAD(&W->h.client, c, next);
|
||||||
|
|
||||||
|
ewmh_set_wm_state(w, NormalState);
|
||||||
|
|
||||||
if(!scan)
|
if(!scan)
|
||||||
{
|
{
|
||||||
client_get_name(c);
|
client_get_name(c);
|
||||||
if(W->flags & WMFS_AUTOFOCUS)
|
client_focus(c);
|
||||||
client_focus(c);
|
|
||||||
client_configure(c);
|
client_configure(c);
|
||||||
|
ewmh_manage_window_type(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
ewmh_get_client_list();
|
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1049,7 +929,7 @@ client_update_props(struct client *c, Flags f)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
client_geo_hints(struct geo *g, int *s)
|
client_geo_hints(struct geo *g, int *s)
|
||||||
{
|
{
|
||||||
/* base */
|
/* base */
|
||||||
@ -1085,32 +965,29 @@ client_geo_hints(struct geo *g, int *s)
|
|||||||
g->h = s[MAXH];
|
g->h = s[MAXH];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Manage window size in frame in tiling mode */
|
|
||||||
bool
|
bool
|
||||||
client_winsize(struct client *c, struct geo *g)
|
client_winsize(struct client *c, struct geo *g)
|
||||||
{
|
{
|
||||||
int ow, oh;
|
int ow, oh;
|
||||||
struct geo og = c->wgeo;
|
struct geo og = c->wgeo;
|
||||||
struct geo tmp = *g;
|
|
||||||
|
|
||||||
tmp.w -= W->padding >> 1;
|
|
||||||
tmp.h -= W->padding >> 1;
|
|
||||||
|
|
||||||
/* Window geo */
|
/* Window geo */
|
||||||
c->wgeo.x = c->border;
|
c->wgeo.x = c->border;
|
||||||
c->wgeo.y = c->tbarw;
|
c->wgeo.y = c->tbarw;
|
||||||
c->wgeo.h = oh = tmp.h - (c->border + c->tbarw);
|
c->wgeo.h = oh = g->h - (c->border + c->tbarw);
|
||||||
c->wgeo.w = ow = tmp.w - (c->border << 1);
|
c->wgeo.w = ow = g->w - (c->border << 1);
|
||||||
|
|
||||||
client_geo_hints(&c->wgeo, (int*)c->sizeh);
|
client_geo_hints(&c->wgeo, (int*)c->sizeh);
|
||||||
|
|
||||||
/* Check possible problem for tile integration */
|
/* Check possible problem for tile integration */
|
||||||
if(ow < c->sizeh[MINW] || oh < c->sizeh[MINH])
|
if(ow < c->sizeh[MINW] || oh < c->sizeh[MINH])
|
||||||
if(tmp.w < c->geo.w || tmp.h < c->geo.h)
|
{
|
||||||
|
if(g->w < c->geo.w || g->h < c->geo.h)
|
||||||
{
|
{
|
||||||
c->wgeo = og;
|
c->wgeo = og;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Balance position with new size */
|
/* Balance position with new size */
|
||||||
c->wgeo.x += (ow - c->wgeo.w) >> 1;
|
c->wgeo.x += (ow - c->wgeo.w) >> 1;
|
||||||
@ -1120,68 +997,29 @@ client_winsize(struct client *c, struct geo *g)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
client_moveresize(struct client *c, struct geo *g)
|
client_moveresize(struct client *c, struct geo *g)
|
||||||
{
|
{
|
||||||
|
bool r = true;
|
||||||
|
|
||||||
if(c->flags & CLIENT_TABBED)
|
if(c->flags & CLIENT_TABBED)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
/* Adjust frame regarding window required size */
|
c->ttgeo = c->tgeo = c->rgeo = c->geo = *g;
|
||||||
if(c->flags & CLIENT_FREE)
|
|
||||||
{
|
|
||||||
g->w -= c->border + c->border;
|
|
||||||
g->h -= c->tbarw + c->border;
|
|
||||||
|
|
||||||
client_geo_hints(g, (int*)c->sizeh);
|
if(!(c->flags & CLIENT_DID_WINSIZE))
|
||||||
|
if(client_winsize(c, g))
|
||||||
c->wgeo = c->geo = c->rgeo = *g;
|
|
||||||
c->wgeo.x = c->border;
|
|
||||||
c->wgeo.y = c->tbarw;
|
|
||||||
c->geo.w = c->rgeo.w = c->wgeo.w + c->border + c->border;
|
|
||||||
c->geo.h = c->rgeo.h = c->wgeo.h + c->tbarw + c->border;
|
|
||||||
|
|
||||||
c->rgeo.x += c->screen->ugeo.x;
|
|
||||||
c->rgeo.y += c->screen->ugeo.y;
|
|
||||||
|
|
||||||
if(!INAREA(c->rgeo.x, c->rgeo.y, c->screen->ugeo))
|
|
||||||
{
|
{
|
||||||
/* New screen (moved by mouse) */
|
r = false;
|
||||||
if(c->flags & CLIENT_MOUSE)
|
/* TODO
|
||||||
{
|
* Window required size not compatible
|
||||||
c->flags |= CLIENT_IGNORE_LAYOUT;
|
* with frame window size in tile mode
|
||||||
c->screen = screen_gb_geo(c->rgeo.x, c->rgeo.y);
|
*/
|
||||||
tag_client(c->screen->seltag, c);
|
|
||||||
|
|
||||||
c->geo.x = c->rgeo.x - c->screen->ugeo.x;
|
|
||||||
c->geo.y = c->rgeo.y - c->screen->ugeo.y;
|
|
||||||
|
|
||||||
}
|
|
||||||
/* Out of the screen case */
|
|
||||||
else
|
|
||||||
{
|
|
||||||
c->geo.x = (c->screen->ugeo.w >> 1) - (c->geo.w >> 1);
|
|
||||||
c->geo.y = (c->screen->ugeo.h >> 1) - (c->geo.h >> 1);
|
|
||||||
c->rgeo.x = c->screen->ugeo.x + c->geo.x;
|
|
||||||
c->rgeo.y = c->screen->ugeo.y + c->geo.y;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
/* Adjust window regarding required size for frame (tiling) */
|
|
||||||
else
|
|
||||||
{
|
|
||||||
c->ttgeo = c->tgeo = c->rgeo = c->geo = *g;
|
|
||||||
|
|
||||||
if(!(c->flags & CLIENT_DID_WINSIZE))
|
/* Real geo regarding full root size */
|
||||||
client_winsize(c, g);
|
c->rgeo.x += c->screen->ugeo.x;
|
||||||
|
c->rgeo.y += c->screen->ugeo.y;
|
||||||
c->rgeo.x += c->screen->ugeo.x;
|
|
||||||
c->rgeo.y += c->screen->ugeo.y;
|
|
||||||
|
|
||||||
c->rgeo.x += W->padding >> 2;
|
|
||||||
c->rgeo.y += W->padding >> 2;
|
|
||||||
c->rgeo.w -= W->padding >> 1;
|
|
||||||
c->rgeo.h -= W->padding >> 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
XMoveResizeWindow(W->dpy, c->frame,
|
XMoveResizeWindow(W->dpy, c->frame,
|
||||||
c->rgeo.x, c->rgeo.y,
|
c->rgeo.x, c->rgeo.y,
|
||||||
@ -1197,25 +1035,8 @@ client_moveresize(struct client *c, struct geo *g)
|
|||||||
client_frame_update(c, CCOL(c));
|
client_frame_update(c, CCOL(c));
|
||||||
client_update_props(c, CPROP_GEO);
|
client_update_props(c, CPROP_GEO);
|
||||||
client_configure(c);
|
client_configure(c);
|
||||||
}
|
|
||||||
|
|
||||||
void
|
return r;
|
||||||
client_place_at_mouse(struct client *c)
|
|
||||||
{
|
|
||||||
int x, y;
|
|
||||||
|
|
||||||
Window w;
|
|
||||||
int d, u;
|
|
||||||
|
|
||||||
XQueryPointer(W->dpy, W->root, &w, &w, &x, &y, &d, &d, (uint *)&u);
|
|
||||||
|
|
||||||
if(x < c->screen->ugeo.x)
|
|
||||||
x = 0;
|
|
||||||
if(y < c->screen->ugeo.y)
|
|
||||||
y = 0;
|
|
||||||
|
|
||||||
c->geo.x = ((x + c->geo.w) > c->screen->ugeo.w ? c->screen->ugeo.w - c->geo.w : x);
|
|
||||||
c->geo.y = ((y + c->geo.h) > c->screen->ugeo.h ? c->screen->ugeo.h - c->geo.h : y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1262,7 +1083,7 @@ _fac_arrange_row(struct client *c, enum position p, int fac)
|
|||||||
struct client *cc;
|
struct client *cc;
|
||||||
|
|
||||||
/* Travel clients to search row parents and apply fac */
|
/* Travel clients to search row parents and apply fac */
|
||||||
FOREACH_NFCLIENT(cc, &c->tag->clients, tnext)
|
SLIST_FOREACH(cc, &c->tag->clients, tnext)
|
||||||
if(GEO_PARENTROW(g, cc->tgeo, p))
|
if(GEO_PARENTROW(g, cc->tgeo, p))
|
||||||
_fac_apply(cc, p, fac);
|
_fac_apply(cc, p, fac);
|
||||||
}
|
}
|
||||||
@ -1278,7 +1099,7 @@ _fac_check_to_reverse(struct client *c)
|
|||||||
* resize client because of possible error with next
|
* resize client because of possible error with next
|
||||||
* clients in linked list.
|
* clients in linked list.
|
||||||
*/
|
*/
|
||||||
FOREACH_NFCLIENT(gc, &c->tag->clients, tnext)
|
SLIST_FOREACH(gc, &c->tag->clients, tnext)
|
||||||
if(gc->flags & CLIENT_FAC_APPLIED
|
if(gc->flags & CLIENT_FAC_APPLIED
|
||||||
&& client_winsize(gc, &gc->tgeo))
|
&& client_winsize(gc, &gc->tgeo))
|
||||||
{
|
{
|
||||||
@ -1286,7 +1107,7 @@ _fac_check_to_reverse(struct client *c)
|
|||||||
* Reverse back the flag and the window geo
|
* Reverse back the flag and the window geo
|
||||||
* in previous affected clients
|
* in previous affected clients
|
||||||
*/
|
*/
|
||||||
FOREACH_NFCLIENT(cc, &c->tag->clients, tnext)
|
SLIST_FOREACH(cc, &c->tag->clients, tnext)
|
||||||
{
|
{
|
||||||
cc->tgeo = cc->ttgeo;
|
cc->tgeo = cc->ttgeo;
|
||||||
cc->flags &= ~CLIENT_DID_WINSIZE;
|
cc->flags &= ~CLIENT_DID_WINSIZE;
|
||||||
@ -1302,10 +1123,10 @@ _fac_resize(struct client *c, enum position p, int fac)
|
|||||||
struct client *cc, *gc = client_next_with_pos(c, p);
|
struct client *cc, *gc = client_next_with_pos(c, p);
|
||||||
enum position rp = RPOS(p);
|
enum position rp = RPOS(p);
|
||||||
|
|
||||||
if(!gc || gc->screen != c->screen || !(c->flags & CLIENT_TILED))
|
if(!gc || gc->screen != c->screen)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
FOREACH_NFCLIENT(cc, &c->tag->clients, tnext)
|
SLIST_FOREACH(cc, &c->tag->clients, tnext)
|
||||||
cc->ttgeo = cc->tgeo;
|
cc->ttgeo = cc->tgeo;
|
||||||
|
|
||||||
if(GEO_CHECK2(c->tgeo, gc->tgeo, p))
|
if(GEO_CHECK2(c->tgeo, gc->tgeo, p))
|
||||||
@ -1327,17 +1148,17 @@ client_apply_tgeo(struct tag *t)
|
|||||||
{
|
{
|
||||||
struct client *c;
|
struct client *c;
|
||||||
|
|
||||||
FOREACH_NFCLIENT(c, &t->clients, tnext)
|
SLIST_FOREACH(c, &t->clients, tnext)
|
||||||
{
|
{
|
||||||
client_moveresize(c, &c->tgeo);
|
client_moveresize(c, &c->tgeo);
|
||||||
c->flags &= ~CLIENT_FAC_APPLIED;
|
c->flags &= ~CLIENT_FAC_APPLIED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define _REV_BORDER() \
|
#define _REV_BORDER() \
|
||||||
do { \
|
do { \
|
||||||
FOREACH_NFCLIENT(gc, &c->tag->clients, tnext) \
|
SLIST_FOREACH(gc, &c->tag->clients, tnext) \
|
||||||
draw_reversed_rect(W->root, gc, true); \
|
draw_reversed_rect(W->root, gc, true); \
|
||||||
} while(/* CONSTCOND */ 0);
|
} while(/* CONSTCOND */ 0);
|
||||||
void
|
void
|
||||||
client_fac_resize(struct client *c, enum position p, int fac)
|
client_fac_resize(struct client *c, enum position p, int fac)
|
||||||
@ -1368,7 +1189,7 @@ client_fac_resize(struct client *c, enum position p, int fac)
|
|||||||
if(ev.type == KeyPress)
|
if(ev.type == KeyPress)
|
||||||
{
|
{
|
||||||
XKeyPressedEvent *ke = &ev.xkey;
|
XKeyPressedEvent *ke = &ev.xkey;
|
||||||
keysym = XkbKeycodeToKeysym(W->dpy, (KeyCode)ke->keycode, 0, 0);
|
keysym = XKeycodeToKeysym(W->dpy, (KeyCode)ke->keycode, 0);
|
||||||
|
|
||||||
_REV_BORDER();
|
_REV_BORDER();
|
||||||
|
|
||||||
@ -1419,7 +1240,7 @@ client_fac_resize(struct client *c, enum position p, int fac)
|
|||||||
/* Aborted with escape, Set back original geos */
|
/* Aborted with escape, Set back original geos */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FOREACH_NFCLIENT(gc, &c->tag->clients, tnext)
|
SLIST_FOREACH(gc, &c->tag->clients, tnext)
|
||||||
{
|
{
|
||||||
gc->tgeo = gc->geo;
|
gc->tgeo = gc->geo;
|
||||||
gc->flags &= ~CLIENT_DID_WINSIZE;
|
gc->flags &= ~CLIENT_DID_WINSIZE;
|
||||||
@ -1430,7 +1251,7 @@ client_fac_resize(struct client *c, enum position p, int fac)
|
|||||||
XUngrabKeyboard(W->dpy, CurrentTime);
|
XUngrabKeyboard(W->dpy, CurrentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
inline void
|
||||||
client_fac_hint(struct client *c)
|
client_fac_hint(struct client *c)
|
||||||
{
|
{
|
||||||
int w = c->sizeh[MINW] + c->border + c->border;
|
int w = c->sizeh[MINW] + c->border + c->border;
|
||||||
@ -1454,76 +1275,31 @@ client_remove(struct client *c)
|
|||||||
{
|
{
|
||||||
c->flags |= CLIENT_DYING;
|
c->flags |= CLIENT_DYING;
|
||||||
|
|
||||||
client_untab(c);
|
|
||||||
|
|
||||||
XGrabServer(W->dpy);
|
XGrabServer(W->dpy);
|
||||||
XSetErrorHandler(wmfs_error_handler_dummy);
|
XSetErrorHandler(wmfs_error_handler_dummy);
|
||||||
|
|
||||||
|
client_map(c);
|
||||||
XReparentWindow(W->dpy, c->win, W->root, c->rgeo.x, c->rgeo.y);
|
XReparentWindow(W->dpy, c->win, W->root, c->rgeo.x, c->rgeo.y);
|
||||||
XUngrabButton(W->dpy, AnyButton, AnyModifier, c->win);
|
|
||||||
ewmh_set_wm_state(c->win, WithdrawnState);
|
|
||||||
XSync(W->dpy, false);
|
|
||||||
XSetErrorHandler(wmfs_error_handler);
|
|
||||||
XUngrabServer(W->dpy);
|
|
||||||
|
|
||||||
SLIST_REMOVE(&W->h.client, c, client, next);
|
client_untab(c);
|
||||||
tag_client(NULL, c);
|
|
||||||
|
|
||||||
/* Remove frame */
|
|
||||||
if(c->titlebar)
|
|
||||||
barwin_remove(c->titlebar);
|
|
||||||
XDestroyWindow(W->dpy, c->frame);
|
XDestroyWindow(W->dpy, c->frame);
|
||||||
|
|
||||||
|
if(c->titlebar)
|
||||||
|
barwin_remove(c->titlebar);
|
||||||
|
|
||||||
|
/* Remove from global client list */
|
||||||
|
SLIST_REMOVE(&W->h.client, c, client, next);
|
||||||
|
|
||||||
|
tag_client(NULL, c);
|
||||||
|
|
||||||
|
ewmh_set_wm_state(c->win, WithdrawnState);
|
||||||
|
|
||||||
|
XUngrabServer(W->dpy);
|
||||||
|
XSync(W->dpy, False);
|
||||||
|
XSetErrorHandler(wmfs_error_handler);
|
||||||
|
|
||||||
free(c);
|
free(c);
|
||||||
ewmh_get_client_list();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
uicb_client_toggle_free(Uicb cmd)
|
|
||||||
{
|
|
||||||
struct client *c;
|
|
||||||
(void)cmd;
|
|
||||||
|
|
||||||
if(!(W->client))
|
|
||||||
return;
|
|
||||||
|
|
||||||
W->client->flags ^= CLIENT_FREE;
|
|
||||||
|
|
||||||
layout_client(W->client);
|
|
||||||
|
|
||||||
/* Set tabbed client of toggled client as free */
|
|
||||||
if(W->client->flags & CLIENT_TABMASTER)
|
|
||||||
{
|
|
||||||
SLIST_FOREACH(c, &W->client->tag->clients, tnext)
|
|
||||||
if(c->tabmaster == W->client && c != W->client)
|
|
||||||
c->flags ^= CLIENT_FREE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void uicb_client_toggle_ignore_tag(Uicb cmd)
|
|
||||||
{
|
|
||||||
struct client *c;
|
|
||||||
(void)cmd;
|
|
||||||
|
|
||||||
if(!(W->client))
|
|
||||||
return;
|
|
||||||
|
|
||||||
W->client->flags ^= CLIENT_IGNORE_TAG;
|
|
||||||
|
|
||||||
/* Set tabbed client of toggled client as ignore_tag */
|
|
||||||
if(W->client->flags & CLIENT_TABMASTER)
|
|
||||||
{
|
|
||||||
SLIST_FOREACH(c, &W->client->tag->clients, tnext)
|
|
||||||
if(c->tabmaster == W->client && c != W->client)
|
|
||||||
c->flags ^= CLIENT_IGNORE_TAG;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
uicb_client_tab_next_opened(Uicb cmd)
|
|
||||||
{
|
|
||||||
(void)cmd;
|
|
||||||
|
|
||||||
W->flags ^= WMFS_TABNOC;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
42
src/client.h
42
src/client.h
@ -6,8 +6,6 @@
|
|||||||
#ifndef CLIENT_H
|
#ifndef CLIENT_H
|
||||||
#define CLIENT_H
|
#define CLIENT_H
|
||||||
|
|
||||||
#include <X11/XKBlib.h>
|
|
||||||
|
|
||||||
#include "wmfs.h"
|
#include "wmfs.h"
|
||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
#include "ewmh.h"
|
#include "ewmh.h"
|
||||||
@ -15,15 +13,7 @@
|
|||||||
|
|
||||||
#define TCLIENT_CHECK(C) (C->flags & CLIENT_TABBED && !(C->flags & CLIENT_TABMASTER))
|
#define TCLIENT_CHECK(C) (C->flags & CLIENT_TABBED && !(C->flags & CLIENT_TABMASTER))
|
||||||
|
|
||||||
/* SLIST_FOREACH for client with no free client */
|
inline void client_configure(struct client *c);
|
||||||
#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_win(Window w);
|
||||||
struct client *client_gb_frame(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_pos(struct tag *t, int x, int y);
|
||||||
@ -42,11 +32,8 @@ void client_get_name(struct client *c);
|
|||||||
void client_close(struct client *c);
|
void client_close(struct client *c);
|
||||||
void uicb_client_close(Uicb cmd);
|
void uicb_client_close(Uicb cmd);
|
||||||
struct client *client_new(Window w, XWindowAttributes *wa, bool scan);
|
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);
|
bool client_winsize(struct client *c, struct geo *geo);
|
||||||
void client_moveresize(struct client *c, struct geo *g);
|
bool client_moveresize(struct client *c, struct geo *g);
|
||||||
void client_place_at_mouse(struct client *c);
|
|
||||||
void client_maximize(struct client *c);
|
void client_maximize(struct client *c);
|
||||||
void client_fac_resize(struct client *c, enum position p, int fac);
|
void client_fac_resize(struct client *c, enum position p, int fac);
|
||||||
void client_fac_adjust(struct client *c);
|
void client_fac_adjust(struct client *c);
|
||||||
@ -61,11 +48,8 @@ void client_apply_tgeo(struct tag *t);
|
|||||||
#define CPROP_TAB 0x08
|
#define CPROP_TAB 0x08
|
||||||
void client_update_props(struct client *c, Flags f);
|
void client_update_props(struct client *c, Flags f);
|
||||||
|
|
||||||
void client_fac_hint(struct client *c);
|
inline void client_fac_hint(struct client *c);
|
||||||
void uicb_client_untab(Uicb cmd);
|
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 */
|
/* Generated */
|
||||||
void uicb_client_resize_Right(Uicb);
|
void uicb_client_resize_Right(Uicb);
|
||||||
@ -193,25 +177,5 @@ clients_tag_arrange_map(struct tag *t)
|
|||||||
sfunc(c);
|
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 */
|
#endif /* CLIENT_H */
|
||||||
|
|||||||
142
src/config.c
142
src/config.c
@ -10,13 +10,6 @@
|
|||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "infobar.h"
|
#include "infobar.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "status.h"
|
|
||||||
|
|
||||||
#define ISTRDUP(t, s) \
|
|
||||||
do { \
|
|
||||||
if((tmp = s)) \
|
|
||||||
t = xstrdup(tmp); \
|
|
||||||
} while(/* CONSTCOND */ 0);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
config_mouse_section(struct mbhead *mousebinds, struct conf_sec **sec)
|
config_mouse_section(struct mbhead *mousebinds, struct conf_sec **sec)
|
||||||
@ -50,7 +43,6 @@ config_theme(void)
|
|||||||
struct theme *t, *p = NULL;
|
struct theme *t, *p = NULL;
|
||||||
size_t i, n;
|
size_t i, n;
|
||||||
struct conf_sec *sec, **ks;
|
struct conf_sec *sec, **ks;
|
||||||
char *tmp;
|
|
||||||
|
|
||||||
/* [themes] */
|
/* [themes] */
|
||||||
sec = fetch_section_first(NULL, "themes");
|
sec = fetch_section_first(NULL, "themes");
|
||||||
@ -83,33 +75,9 @@ config_theme(void)
|
|||||||
t->tags_n.bg = color_atoh(fetch_opt_first(ks[i], "#222222", "tags_normal_bg").str);
|
t->tags_n.bg = color_atoh(fetch_opt_first(ks[i], "#222222", "tags_normal_bg").str);
|
||||||
t->tags_s.fg = color_atoh(fetch_opt_first(ks[i], "#222222", "tags_sel_fg").str);
|
t->tags_s.fg = color_atoh(fetch_opt_first(ks[i], "#222222", "tags_sel_fg").str);
|
||||||
t->tags_s.bg = color_atoh(fetch_opt_first(ks[i], "#CCCCCC", "tags_sel_bg").str);
|
t->tags_s.bg = color_atoh(fetch_opt_first(ks[i], "#CCCCCC", "tags_sel_bg").str);
|
||||||
t->tags_o.fg = color_atoh(fetch_opt_first(ks[i], "#CCCCCC", "tags_occupied_fg").str);
|
|
||||||
t->tags_o.bg = color_atoh(fetch_opt_first(ks[i], "#444444", "tags_occupied_bg").str);
|
|
||||||
t->tags_u.fg = color_atoh(fetch_opt_first(ks[i], "#444444", "tags_urgent_fg").str);
|
|
||||||
t->tags_u.bg = color_atoh(fetch_opt_first(ks[i], "#CC4444", "tags_urgent_bg").str);
|
|
||||||
t->tags_border_col = color_atoh(fetch_opt_first(ks[i], "#888888", "tags_border_color").str);
|
t->tags_border_col = color_atoh(fetch_opt_first(ks[i], "#888888", "tags_border_color").str);
|
||||||
t->tags_border_width = fetch_opt_first(ks[i], "0", "tags_border_width").num;
|
t->tags_border_width = fetch_opt_first(ks[i], "0", "tags_border_width").num;
|
||||||
|
|
||||||
/* status line */
|
|
||||||
t->tags_n_sl = status_new_ctx(NULL, t);
|
|
||||||
t->tags_s_sl = status_new_ctx(NULL, t);
|
|
||||||
t->tags_o_sl = status_new_ctx(NULL, t);
|
|
||||||
t->tags_u_sl = status_new_ctx(NULL, t);
|
|
||||||
|
|
||||||
ISTRDUP(t->tags_n_sl.status, fetch_opt_first(ks[i], "", "tags_normal_statusline").str);
|
|
||||||
ISTRDUP(t->tags_s_sl.status, fetch_opt_first(ks[i], "", "tags_sel_statusline").str);
|
|
||||||
ISTRDUP(t->tags_o_sl.status, fetch_opt_first(ks[i], "", "tags_occupied_statusline").str);
|
|
||||||
ISTRDUP(t->tags_u_sl.status, fetch_opt_first(ks[i], "", "tags_urgent_statusline").str);
|
|
||||||
|
|
||||||
if(t->tags_n_sl.status)
|
|
||||||
status_parse(&t->tags_n_sl);
|
|
||||||
if(t->tags_s_sl.status)
|
|
||||||
status_parse(&t->tags_s_sl);
|
|
||||||
if(t->tags_o_sl.status)
|
|
||||||
status_parse(&t->tags_o_sl);
|
|
||||||
if(t->tags_u_sl.status)
|
|
||||||
status_parse(&t->tags_u_sl);
|
|
||||||
|
|
||||||
/* Client / frame */
|
/* Client / frame */
|
||||||
t->client_n.fg = color_atoh(fetch_opt_first(ks[i], "#CCCCCC", "client_normal_fg").str);
|
t->client_n.fg = color_atoh(fetch_opt_first(ks[i], "#CCCCCC", "client_normal_fg").str);
|
||||||
t->client_n.bg = color_atoh(fetch_opt_first(ks[i], "#222222", "client_normal_bg").str);
|
t->client_n.bg = color_atoh(fetch_opt_first(ks[i], "#222222", "client_normal_bg").str);
|
||||||
@ -119,22 +87,6 @@ config_theme(void)
|
|||||||
t->client_titlebar_width = fetch_opt_first(ks[i], "12", "client_titlebar_width").num;
|
t->client_titlebar_width = fetch_opt_first(ks[i], "12", "client_titlebar_width").num;
|
||||||
t->client_border_width = fetch_opt_first(ks[i], "1", "client_border_width").num;
|
t->client_border_width = fetch_opt_first(ks[i], "1", "client_border_width").num;
|
||||||
|
|
||||||
/* status line */
|
|
||||||
t->client_n_sl = status_new_ctx(NULL, t);
|
|
||||||
t->client_s_sl = status_new_ctx(NULL, t);
|
|
||||||
t->client_f_sl = status_new_ctx(NULL, t);
|
|
||||||
|
|
||||||
ISTRDUP(t->client_n_sl.status, fetch_opt_first(ks[i], "", "client_normal_statusline").str);
|
|
||||||
ISTRDUP(t->client_s_sl.status, fetch_opt_first(ks[i], "", "client_sel_statusline").str);
|
|
||||||
ISTRDUP(t->client_f_sl.status, fetch_opt_first(ks[i], "", "client_free_statusline").str);
|
|
||||||
|
|
||||||
if(t->client_n_sl.status)
|
|
||||||
status_parse(&t->client_n_sl);
|
|
||||||
if(t->client_s_sl.status)
|
|
||||||
status_parse(&t->client_s_sl);
|
|
||||||
if(t->client_f_sl.status)
|
|
||||||
status_parse(&t->client_f_sl);
|
|
||||||
|
|
||||||
SLIST_INSERT_TAIL(&W->h.theme, t, next, p);
|
SLIST_INSERT_TAIL(&W->h.theme, t, next, p);
|
||||||
|
|
||||||
p = t;
|
p = t;
|
||||||
@ -181,10 +133,9 @@ static void
|
|||||||
config_tag(void)
|
config_tag(void)
|
||||||
{
|
{
|
||||||
struct screen *s;
|
struct screen *s;
|
||||||
struct tag *t;
|
|
||||||
size_t i, n;
|
size_t i, n;
|
||||||
struct conf_sec *sec, **ks, **mb;
|
struct conf_sec *sec, **ks, **mb;
|
||||||
char *name, *tmp;
|
char *name;
|
||||||
int screenid;
|
int screenid;
|
||||||
|
|
||||||
/* [tags] */
|
/* [tags] */
|
||||||
@ -192,9 +143,6 @@ config_tag(void)
|
|||||||
ks = fetch_section(sec, "tag");
|
ks = fetch_section(sec, "tag");
|
||||||
n = fetch_section_count(ks);
|
n = fetch_section_count(ks);
|
||||||
|
|
||||||
if (fetch_opt_first(sec, "1", "circular").boolean)
|
|
||||||
W->flags |= WMFS_TAGCIRC;
|
|
||||||
|
|
||||||
/* [mouse] */
|
/* [mouse] */
|
||||||
if((mb = fetch_section(sec, "mouse")))
|
if((mb = fetch_section(sec, "mouse")))
|
||||||
{
|
{
|
||||||
@ -210,14 +158,7 @@ config_tag(void)
|
|||||||
|
|
||||||
SLIST_FOREACH(s, &W->h.screen, next)
|
SLIST_FOREACH(s, &W->h.screen, next)
|
||||||
if(screenid == s->id || screenid == -1)
|
if(screenid == s->id || screenid == -1)
|
||||||
{
|
tag_new(s, name);
|
||||||
t = tag_new(s, name);
|
|
||||||
|
|
||||||
t->statusctx = status_new_ctx(NULL, NULL);
|
|
||||||
ISTRDUP(t->statusctx.status, fetch_opt_first(ks[i], "", "statusline").str);
|
|
||||||
if(t->statusctx.status)
|
|
||||||
status_parse(&t->statusctx);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If no tag at all on a screen, add one anyway */
|
/* If no tag at all on a screen, add one anyway */
|
||||||
@ -232,29 +173,10 @@ static void
|
|||||||
config_client(void)
|
config_client(void)
|
||||||
{
|
{
|
||||||
struct conf_sec *sec, **mb;
|
struct conf_sec *sec, **mb;
|
||||||
char *tmp;
|
|
||||||
|
|
||||||
/* [client] */
|
/* [client] */
|
||||||
sec = fetch_section_first(NULL, "client");
|
sec = fetch_section_first(NULL, "client");
|
||||||
|
|
||||||
W->padding = fetch_opt_first(sec, "0", "padding").num;
|
|
||||||
W->client_mod = modkey_keysym(fetch_opt_first(sec, "Super", "key_modifier").str);
|
|
||||||
|
|
||||||
if(fetch_opt_first(sec, "0", "autofocus").boolean)
|
|
||||||
W->flags |= WMFS_AUTOFOCUS;
|
|
||||||
|
|
||||||
/* Get theme */
|
|
||||||
tmp = fetch_opt_first(sec, "default", "theme").str;
|
|
||||||
W->ctheme = name_to_theme(tmp);
|
|
||||||
|
|
||||||
/* Get focus configuration */
|
|
||||||
W->cfocus = 0;
|
|
||||||
tmp = fetch_opt_first(sec, "enter", "focus").str;
|
|
||||||
if(strstr(tmp, "enter"))
|
|
||||||
W->cfocus |= CFOCUS_ENTER;
|
|
||||||
if(strstr(tmp, "click"))
|
|
||||||
W->cfocus |= CFOCUS_CLICK;
|
|
||||||
|
|
||||||
/* [mouse] */
|
/* [mouse] */
|
||||||
/* for client frame AND titlebar */
|
/* for client frame AND titlebar */
|
||||||
if((mb = fetch_section(sec, "mouse")))
|
if((mb = fetch_section(sec, "mouse")))
|
||||||
@ -264,12 +186,18 @@ config_client(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define ISTRDUP(t, s) \
|
||||||
|
do { \
|
||||||
|
if((tmp = s)) \
|
||||||
|
t = xstrdup(tmp); \
|
||||||
|
} while(/* CONSTCOND */ 0);
|
||||||
static void
|
static void
|
||||||
config_rule(void)
|
config_rule(void)
|
||||||
{
|
{
|
||||||
int i, n;
|
int i, n;
|
||||||
struct conf_sec *sec, **ks;
|
struct conf_sec *sec, **ks;
|
||||||
struct rule *r;
|
struct rule *r;
|
||||||
|
struct theme *t;
|
||||||
char *tn, *tmp;
|
char *tn, *tmp;
|
||||||
|
|
||||||
/* [rules] */
|
/* [rules] */
|
||||||
@ -293,13 +221,20 @@ config_rule(void)
|
|||||||
r->tag = fetch_opt_first(ks[i], "-1", "tag").num;
|
r->tag = fetch_opt_first(ks[i], "-1", "tag").num;
|
||||||
|
|
||||||
FLAGAPPLY(r->flags, fetch_opt_first(ks[i], "false", "free").boolean, RULE_FREE);
|
FLAGAPPLY(r->flags, fetch_opt_first(ks[i], "false", "free").boolean, RULE_FREE);
|
||||||
FLAGAPPLY(r->flags, fetch_opt_first(ks[i], "false", "tab").boolean, RULE_TAB);
|
FLAGAPPLY(r->flags, fetch_opt_first(ks[i], "false", "max").boolean, RULE_MAX);
|
||||||
FLAGAPPLY(r->flags, fetch_opt_first(ks[i], "false", "ignore_tag").boolean, RULE_IGNORE_TAG);
|
FLAGAPPLY(r->flags, fetch_opt_first(ks[i], "false", "ignore_tag").boolean, RULE_IGNORE_TAG);
|
||||||
|
|
||||||
if((tn = fetch_opt_first(ks[i], "", "theme").str))
|
if((tn = fetch_opt_first(ks[i], "", "theme").str))
|
||||||
r->theme = name_to_theme(tn);
|
{
|
||||||
|
SLIST_FOREACH(t, &W->h.theme, next)
|
||||||
|
if(!strcmp(tn, t->name))
|
||||||
|
{
|
||||||
|
r->theme = t;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
r->theme = W->ctheme;
|
r->theme = SLIST_FIRST(&W->h.theme);
|
||||||
|
|
||||||
SLIST_INSERT_HEAD(&W->h.rule, r, next);
|
SLIST_INSERT_HEAD(&W->h.rule, r, next);
|
||||||
}
|
}
|
||||||
@ -307,38 +242,6 @@ config_rule(void)
|
|||||||
free(ks);
|
free(ks);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
config_launcher(void)
|
|
||||||
{
|
|
||||||
struct conf_sec *sec, **ks;
|
|
||||||
struct launcher *l;
|
|
||||||
int n, i;
|
|
||||||
|
|
||||||
/* [launchers] */
|
|
||||||
sec = fetch_section_first(NULL, "launchers");
|
|
||||||
ks = fetch_section(sec, "launcher");
|
|
||||||
n = fetch_section_count(ks);
|
|
||||||
|
|
||||||
SLIST_INIT(&W->h.launcher);
|
|
||||||
|
|
||||||
/* [launcher] */
|
|
||||||
for(i = 0; i < n; ++i)
|
|
||||||
{
|
|
||||||
l = xcalloc(1, sizeof(struct launcher));
|
|
||||||
|
|
||||||
l->name = xstrdup(fetch_opt_first(ks[i], "default", "name").str);
|
|
||||||
l->prompt = xstrdup(fetch_opt_first(ks[i], ":", "prompt").str);
|
|
||||||
l->command = xstrdup(fetch_opt_first(ks[i], "spawn", "command").str);
|
|
||||||
|
|
||||||
if((l->width = fetch_opt_first(ks[i], "150", "width").num) <= 0)
|
|
||||||
l->width = 150;
|
|
||||||
|
|
||||||
SLIST_INSERT_HEAD(&W->h.launcher, l, next);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(ks);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
config_keybind(void)
|
config_keybind(void)
|
||||||
{
|
{
|
||||||
@ -401,13 +304,7 @@ config_init(void)
|
|||||||
sprintf(W->confpath, "%s/"CONFIG_DEFAULT_PATH, getenv("HOME"));
|
sprintf(W->confpath, "%s/"CONFIG_DEFAULT_PATH, getenv("HOME"));
|
||||||
|
|
||||||
if(get_conf(W->confpath) == -1)
|
if(get_conf(W->confpath) == -1)
|
||||||
{
|
errxl(1, "parsing default configuration file (%s) failed.", W->confpath);
|
||||||
warnxl("parsing default configuration file (%s) failed.", W->confpath);
|
|
||||||
sprintf(W->confpath, "%s/wmfs/wmfsrc", XDG_CONFIG_DIR);
|
|
||||||
|
|
||||||
if(get_conf(W->confpath) == -1)
|
|
||||||
errxl(1, "parsing system configuration file (%s) failed.", W->confpath);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
config_theme();
|
config_theme();
|
||||||
@ -416,7 +313,6 @@ config_init(void)
|
|||||||
config_client();
|
config_client();
|
||||||
config_bars();
|
config_bars();
|
||||||
config_rule();
|
config_rule();
|
||||||
config_launcher();
|
|
||||||
|
|
||||||
free_conf();
|
free_conf();
|
||||||
}
|
}
|
||||||
|
|||||||
83
src/config.h
83
src/config.h
@ -17,8 +17,6 @@
|
|||||||
#include "status.h"
|
#include "status.h"
|
||||||
#include "mouse.h"
|
#include "mouse.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "infobar.h"
|
|
||||||
#include "launcher.h"
|
|
||||||
|
|
||||||
#define THEME_DEFAULT (SLIST_FIRST(&W->h.theme))
|
#define THEME_DEFAULT (SLIST_FIRST(&W->h.theme))
|
||||||
|
|
||||||
@ -35,61 +33,47 @@ static const struct { char *name; void (*func)(Uicb cmd); } uicb_list[] =
|
|||||||
{ "tag_next", uicb_tag_next },
|
{ "tag_next", uicb_tag_next },
|
||||||
{ "tag_prev", uicb_tag_prev },
|
{ "tag_prev", uicb_tag_prev },
|
||||||
{ "tag_client", uicb_tag_client },
|
{ "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_next", uicb_tag_move_client_next },
|
||||||
{ "tag_move_client_prev", uicb_tag_move_client_prev },
|
{ "tag_move_client_prev", uicb_tag_move_client_prev },
|
||||||
{ "tag_click", uicb_tag_click },
|
{ "tag_click", uicb_tag_click },
|
||||||
{ "tag_new", uicb_tag_new },
|
|
||||||
{ "tag_del", uicb_tag_del },
|
|
||||||
|
|
||||||
/* Layout */
|
/* Layout */
|
||||||
{ "layout_vmirror", uicb_layout_vmirror },
|
{ "layout_vmirror", uicb_layout_vmirror },
|
||||||
{ "layout_hmirror", uicb_layout_hmirror },
|
{ "layout_hmirror", uicb_layout_hmirror },
|
||||||
{ "layout_rotate_left", uicb_layout_rotate_left },
|
{ "layout_rotate_left", uicb_layout_rotate_left },
|
||||||
{ "layout_rotate_right", uicb_layout_rotate_right },
|
{ "layout_rotate_right", uicb_layout_rotate_right },
|
||||||
{ "layout_prev_set", uicb_layout_prev_set },
|
{ "layout_prev_set", uicb_layout_prev_set },
|
||||||
{ "layout_next_set", uicb_layout_next_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 */
|
||||||
{ "client_close", uicb_client_close },
|
{ "client_close", uicb_client_close },
|
||||||
{ "client_resize_right", uicb_client_resize_Right },
|
{ "client_resize_right", uicb_client_resize_Right },
|
||||||
{ "client_resize_left", uicb_client_resize_Left },
|
{ "client_resize_left", uicb_client_resize_Left },
|
||||||
{ "client_resize_top", uicb_client_resize_Top },
|
{ "client_resize_top", uicb_client_resize_Top },
|
||||||
{ "client_resize_bottom", uicb_client_resize_Bottom },
|
{ "client_resize_bottom", uicb_client_resize_Bottom },
|
||||||
{ "client_focus_right", uicb_client_focus_Right },
|
{ "client_focus_right", uicb_client_focus_Right },
|
||||||
{ "client_focus_left", uicb_client_focus_Left },
|
{ "client_focus_left", uicb_client_focus_Left },
|
||||||
{ "client_focus_top", uicb_client_focus_Top },
|
{ "client_focus_top", uicb_client_focus_Top },
|
||||||
{ "client_focus_bottom", uicb_client_focus_Bottom },
|
{ "client_focus_bottom", uicb_client_focus_Bottom },
|
||||||
{ "client_tab_right", uicb_client_tab_Right },
|
{ "client_tab_right", uicb_client_tab_Right },
|
||||||
{ "client_tab_left", uicb_client_tab_Left },
|
{ "client_tab_left", uicb_client_tab_Left },
|
||||||
{ "client_tab_top", uicb_client_tab_Top },
|
{ "client_tab_top", uicb_client_tab_Top },
|
||||||
{ "client_tab_bottom", uicb_client_tab_Bottom },
|
{ "client_tab_bottom", uicb_client_tab_Bottom },
|
||||||
{ "client_swap_right", uicb_client_swap_Right },
|
{ "client_swap_right", uicb_client_swap_Right },
|
||||||
{ "client_swap_left", uicb_client_swap_Left },
|
{ "client_swap_left", uicb_client_swap_Left },
|
||||||
{ "client_swap_top", uicb_client_swap_Top },
|
{ "client_swap_top", uicb_client_swap_Top },
|
||||||
{ "client_swap_bottom", uicb_client_swap_Bottom },
|
{ "client_swap_bottom", uicb_client_swap_Bottom },
|
||||||
{ "client_focus_next", uicb_client_focus_next },
|
{ "client_focus_next", uicb_client_focus_next },
|
||||||
{ "client_focus_prev", uicb_client_focus_prev },
|
{ "client_focus_prev", uicb_client_focus_prev },
|
||||||
{ "client_swap_next", uicb_client_swapsel_next },
|
{ "client_swap_next", uicb_client_swapsel_next },
|
||||||
{ "client_swap_prev", uicb_client_swapsel_prev },
|
{ "client_swap_prev", uicb_client_swapsel_prev },
|
||||||
{ "client_untab", uicb_client_untab },
|
{ "client_untab", uicb_client_untab },
|
||||||
{ "client_focus_next_tab", uicb_client_focus_next_tab },
|
{ "client_focus_next_tab", uicb_client_focus_next_tab },
|
||||||
{ "client_focus_prev_tab", uicb_client_focus_prev_tab },
|
{ "client_focus_prev_tab", uicb_client_focus_prev_tab },
|
||||||
{ "client_focus_click", uicb_client_focus_click },
|
{ "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 */
|
||||||
{ "status" , uicb_status },
|
{ "status" , uicb_status },
|
||||||
{ "status_surface", uicb_status_surface },
|
|
||||||
|
|
||||||
/* Infobar */
|
|
||||||
{ "infobar_toggle_hide", uicb_infobar_toggle_hide },
|
|
||||||
|
|
||||||
/* Mouse */
|
/* Mouse */
|
||||||
{ "mouse_resize", uicb_mouse_resize },
|
{ "mouse_resize", uicb_mouse_resize },
|
||||||
@ -103,9 +87,6 @@ static const struct { char *name; void (*func)(Uicb cmd); } uicb_list[] =
|
|||||||
{ "screen_move_client_next", uicb_screen_move_client_next },
|
{ "screen_move_client_next", uicb_screen_move_client_next },
|
||||||
{ "screen_move_client_prev", uicb_screen_move_client_prev },
|
{ "screen_move_client_prev", uicb_screen_move_client_prev },
|
||||||
|
|
||||||
/* Launcher */
|
|
||||||
{ "launcher", uicb_launcher },
|
|
||||||
|
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
71
src/draw.h
71
src/draw.h
@ -10,10 +10,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
#ifdef HAVE_IMLIB2
|
|
||||||
#include <Imlib2.h>
|
|
||||||
#endif /* HAVE_IMLIB2 */
|
|
||||||
|
|
||||||
#include "wmfs.h"
|
#include "wmfs.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
@ -29,43 +25,12 @@ draw_text(Drawable d, struct theme *t, int x, int y, Color fg, const char *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
draw_rect(Drawable d, struct geo *g, Color bg)
|
draw_rect(Drawable d, struct geo g, Color bg)
|
||||||
{
|
{
|
||||||
XSetForeground(W->dpy, W->gc, bg);
|
XSetForeground(W->dpy, W->gc, bg);
|
||||||
XFillRectangle(W->dpy, d, W->gc, g->x, g->y, g->w, g->h);
|
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
|
* For client use
|
||||||
*/
|
*/
|
||||||
@ -76,28 +41,24 @@ draw_reversed_rect(Drawable dr, struct client *c, bool t)
|
|||||||
struct geo *ug = &c->screen->ugeo;
|
struct geo *ug = &c->screen->ugeo;
|
||||||
int i = c->theme->client_border_width;
|
int i = c->theme->client_border_width;
|
||||||
|
|
||||||
if(c->flags & CLIENT_FREE)
|
XDrawRectangle(W->dpy, dr, W->rgc,
|
||||||
{
|
ug->x + g->x + i,
|
||||||
XDrawRectangle(W->dpy, dr, W->rgc,
|
ug->y + g->y + i,
|
||||||
ug->x + g->x + i,
|
g->w - (i << 1),
|
||||||
ug->y + g->y + i,
|
g->h - (i << 1));
|
||||||
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
|
static inline void
|
||||||
draw_line(Drawable d, int x1, int y1, int x2, int y2)
|
draw_reversed_cross(Drawable dr, struct geo *g)
|
||||||
{
|
{
|
||||||
XDrawLine(W->dpy, d, W->gc, x1, y1, x2, y2);
|
int x = g->x + W->screen->ugeo.x;
|
||||||
|
int y = g->y + W->screen->ugeo.y;
|
||||||
|
|
||||||
|
XDrawLine(W->dpy, dr, W->rgc,
|
||||||
|
x, y, x + g->w, y + g->h);
|
||||||
|
|
||||||
|
XDrawLine(W->dpy, dr, W->rgc,
|
||||||
|
x + g->w, y, x, y + g->h);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned short
|
static inline unsigned short
|
||||||
|
|||||||
217
src/event.c
217
src/event.c
@ -5,32 +5,22 @@
|
|||||||
|
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "ewmh.h"
|
#include "ewmh.h"
|
||||||
#include "config.h"
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "wmfs.h"
|
#include "wmfs.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "barwin.h"
|
#include "barwin.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "systray.h"
|
|
||||||
#include "infobar.h"
|
|
||||||
|
|
||||||
#define EVDPY(e) (e)->xany.display
|
#define EVDPY(e) (e)->xany.display
|
||||||
|
|
||||||
#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)
|
event_buttonpress(XEvent *e)
|
||||||
{
|
{
|
||||||
XButtonEvent *ev = &e->xbutton;
|
XButtonEvent *ev = &e->xbutton;
|
||||||
struct mousebind *m;
|
struct mousebind *m;
|
||||||
struct barwin *b;
|
struct barwin *b;
|
||||||
struct client *c;
|
|
||||||
|
|
||||||
screen_update_sel();
|
screen_update_sel();
|
||||||
status_flush_surface();
|
|
||||||
|
|
||||||
SLIST_FOREACH(b, &W->h.barwin, next)
|
SLIST_FOREACH(b, &W->h.barwin, next)
|
||||||
if(b->win == ev->window)
|
if(b->win == ev->window)
|
||||||
@ -38,16 +28,13 @@ event_buttonpress(XEvent *e)
|
|||||||
W->last_clicked_barwin = b;
|
W->last_clicked_barwin = b;
|
||||||
|
|
||||||
SLIST_FOREACH(m, &b->mousebinds, next)
|
SLIST_FOREACH(m, &b->mousebinds, next)
|
||||||
MOUSE_DO_BIND(m);
|
if(m->button == ev->button)
|
||||||
|
if(!m->use_area || (m->use_area && INAREA(ev->x, ev->y, m->area)))
|
||||||
SLIST_FOREACH(m, &b->statusmousebinds, next)
|
if(m->func)
|
||||||
MOUSE_DO_BIND(m);
|
m->func(m->cmd);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if((c = client_gb_win(ev->window)) && c != W->client
|
|
||||||
&& ev->button == 1 && W->cfocus & CFOCUS_CLICK)
|
|
||||||
client_focus(c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -61,18 +48,12 @@ event_enternotify(XEvent *e)
|
|||||||
&& ev->window != W->root)
|
&& ev->window != W->root)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(ev->window == W->systray.win || systray_find(ev->window))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if((c = client_gb_win(ev->window))
|
if((c = client_gb_win(ev->window))
|
||||||
|| (c = client_gb_frame(ev->window)))
|
|| (c = client_gb_frame(ev->window)))
|
||||||
{
|
{
|
||||||
if(c->flags & CLIENT_IGNORE_ENTER)
|
if(c->flags & CLIENT_IGNORE_ENTER)
|
||||||
c->flags ^= CLIENT_IGNORE_ENTER;
|
c->flags ^= CLIENT_IGNORE_ENTER;
|
||||||
else if(c->tag->flags & TAG_IGNORE_ENTER)
|
else if(c != W->client && !(c->flags & CLIENT_TABBED))
|
||||||
c->tag->flags ^= TAG_IGNORE_ENTER;
|
|
||||||
else if(c != W->client && !(c->flags & CLIENT_TABBED)
|
|
||||||
&& W->cfocus & CFOCUS_ENTER)
|
|
||||||
client_focus(c);
|
client_focus(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,70 +63,11 @@ event_clientmessageevent(XEvent *e)
|
|||||||
{
|
{
|
||||||
XClientMessageEvent *ev = &e->xclient;
|
XClientMessageEvent *ev = &e->xclient;
|
||||||
struct client *c;
|
struct client *c;
|
||||||
struct _systray *sy;
|
|
||||||
int type = 0;
|
int type = 0;
|
||||||
|
|
||||||
while(type < net_last && W->net_atom[type] != ev->message_type)
|
while(type < net_last && W->net_atom[type] != ev->message_type)
|
||||||
++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)
|
|
||||||
{
|
|
||||||
systray_add(ev->data.l[2]);
|
|
||||||
systray_update();
|
|
||||||
}
|
|
||||||
else if(ev->data.l[1] == XEMBED_REQUEST_FOCUS)
|
|
||||||
{
|
|
||||||
if((sy = systray_find(ev->data.l[2])))
|
|
||||||
ewmh_send_message(sy->win, sy->win, "_XEMBED", 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,
|
|
||||||
False, W->net_atom[utf8_string], &rt, &d,
|
|
||||||
&len, &il, &ret) == Success
|
|
||||||
&& ret && ((func = uicb_name_func((char*)ret))))
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
|
|
||||||
XFree(ret);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(type == net_active_window)
|
|
||||||
if((sy = systray_find(ev->data.l[0])))
|
|
||||||
XSetInputFocus(W->dpy, sy->win, RevertToNone, CurrentTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
/* _NET_WM_STATE */
|
/* _NET_WM_STATE */
|
||||||
@ -173,28 +95,12 @@ event_configureevent(XEvent *e)
|
|||||||
|
|
||||||
if((c = client_gb_win(ev->window)))
|
if((c = client_gb_win(ev->window)))
|
||||||
{
|
{
|
||||||
if(c->flags & CLIENT_FREE)
|
if(ev->value_mask & CWWidth)
|
||||||
{
|
_fac_resize(c, Right, ev->width - c->wgeo.w);
|
||||||
if(ev->value_mask & CWX)
|
if(ev->value_mask & CWHeight)
|
||||||
c->geo.x = ev->x;
|
_fac_resize(c, Bottom, ev->height - c->wgeo.h);
|
||||||
if(ev->value_mask & CWY)
|
|
||||||
c->geo.y = ev->y - c->tbarw - c->border - c->border;
|
|
||||||
if(ev->value_mask & CWWidth)
|
|
||||||
c->geo.w = ev->width + c->border + c->border;
|
|
||||||
if(ev->value_mask & CWHeight)
|
|
||||||
c->geo.h = ev->height + c->tbarw + c->border;
|
|
||||||
|
|
||||||
client_moveresize(c, &c->geo);
|
client_apply_tgeo(c->tag);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(ev->value_mask & CWWidth)
|
|
||||||
_fac_resize(c, Right, ev->width - c->wgeo.w);
|
|
||||||
if(ev->value_mask & CWHeight)
|
|
||||||
_fac_resize(c, Bottom, ev->height - c->wgeo.h);
|
|
||||||
|
|
||||||
client_apply_tgeo(c->tag);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -215,16 +121,9 @@ event_destroynotify(XEvent *e)
|
|||||||
{
|
{
|
||||||
XDestroyWindowEvent *ev = &e->xdestroywindow;
|
XDestroyWindowEvent *ev = &e->xdestroywindow;
|
||||||
struct client *c;
|
struct client *c;
|
||||||
struct _systray *s;
|
|
||||||
|
|
||||||
if((c = client_gb_win(ev->window)))
|
if((c = client_gb_win(ev->window)))
|
||||||
client_remove(c);
|
client_remove(c);
|
||||||
else if((s = systray_find(ev->window)))
|
|
||||||
{
|
|
||||||
ewmh_set_wm_state(s->win, WithdrawnState);
|
|
||||||
systray_del(s);
|
|
||||||
systray_update();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -241,23 +140,14 @@ event_maprequest(XEvent *e)
|
|||||||
{
|
{
|
||||||
XMapRequestEvent *ev = &e->xmaprequest;
|
XMapRequestEvent *ev = &e->xmaprequest;
|
||||||
XWindowAttributes at;
|
XWindowAttributes at;
|
||||||
struct _systray *s;
|
|
||||||
|
|
||||||
/* Which windows to manage */
|
/* Which windows to manage */
|
||||||
if(!XGetWindowAttributes(EVDPY(e), ev->window, &at)
|
if(!XGetWindowAttributes(EVDPY(e), ev->window, &at)
|
||||||
|| at.override_redirect
|
|| at.override_redirect)
|
||||||
|| ewmh_manage_window_type_desktop(ev->window)
|
|
||||||
|| ewmh_manage_state_sticky(ev->window))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(!client_gb_win(ev->window))
|
if(!client_gb_win(ev->window))
|
||||||
client_new(ev->window, &at, false);
|
client_new(ev->window, &at, false);
|
||||||
else if((s = systray_find(ev->window)))
|
|
||||||
{
|
|
||||||
ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime,
|
|
||||||
XEMBED_WINDOW_ACTIVATE, 0, 0, 0);
|
|
||||||
systray_update();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -274,9 +164,7 @@ static void
|
|||||||
event_propertynotify(XEvent *e)
|
event_propertynotify(XEvent *e)
|
||||||
{
|
{
|
||||||
XPropertyEvent *ev = &e->xproperty;
|
XPropertyEvent *ev = &e->xproperty;
|
||||||
XWMHints *h;
|
|
||||||
struct client *c;
|
struct client *c;
|
||||||
struct _systray *s;
|
|
||||||
|
|
||||||
if(ev->state == PropertyDelete)
|
if(ev->state == PropertyDelete)
|
||||||
return;
|
return;
|
||||||
@ -287,34 +175,26 @@ event_propertynotify(XEvent *e)
|
|||||||
{
|
{
|
||||||
case XA_WM_TRANSIENT_FOR:
|
case XA_WM_TRANSIENT_FOR:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XA_WM_NORMAL_HINTS:
|
case XA_WM_NORMAL_HINTS:
|
||||||
client_get_sizeh(c);
|
/* client_get_size_hints(c); */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XA_WM_HINTS:
|
case XA_WM_HINTS:
|
||||||
if((h = XGetWMHints(EVDPY(e), c->win))
|
/*
|
||||||
&& (h->flags & XUrgencyHint)
|
XWMHints *h;
|
||||||
&& c->tag != W->screen->seltag)
|
|
||||||
|
if((h = XGetWMHints(EVDPY, c->win)) && (h->flags & XUrgencyHint) && c != sel)
|
||||||
{
|
{
|
||||||
c->tag->flags |= TAG_URGENT;
|
client_urgent(c, True);
|
||||||
infobar_elem_screen_update(c->screen, ElemTag);
|
|
||||||
XFree(h);
|
XFree(h);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if(ev->atom == XA_WM_NAME || ev->atom == W->net_atom[net_wm_name])
|
if(ev->atom == XA_WM_NAME || ev->atom == W->net_atom[net_wm_name])
|
||||||
client_get_name(c);
|
client_get_name(c);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if((s = systray_find(ev->window)))
|
|
||||||
{
|
|
||||||
systray_state(s);
|
|
||||||
systray_update();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -322,39 +202,19 @@ event_unmapnotify(XEvent *e)
|
|||||||
{
|
{
|
||||||
XUnmapEvent *ev = &e->xunmap;
|
XUnmapEvent *ev = &e->xunmap;
|
||||||
struct client *c;
|
struct client *c;
|
||||||
struct _systray *s;
|
|
||||||
|
|
||||||
if((c = client_gb_win(ev->window))
|
if((c = client_gb_win(ev->window)) && ev->send_event)
|
||||||
&& ev->send_event
|
client_remove(c);
|
||||||
&& ev->event == W->root)
|
|
||||||
{
|
|
||||||
Atom rt;
|
|
||||||
unsigned long n, il;
|
|
||||||
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)))
|
|
||||||
{
|
|
||||||
systray_del(s);
|
|
||||||
systray_update();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
event_keypress(XEvent *e)
|
event_keypress(XEvent *e)
|
||||||
{
|
{
|
||||||
XKeyPressedEvent *ev = &e->xkey;
|
XKeyPressedEvent *ev = &e->xkey;
|
||||||
KeySym keysym = XkbKeycodeToKeysym(EVDPY(e), (KeyCode)ev->keycode, 0, 0);
|
KeySym keysym = XKeycodeToKeysym(EVDPY(e), (KeyCode)ev->keycode, 0);
|
||||||
struct keybind *k;
|
struct keybind *k;
|
||||||
|
|
||||||
screen_update_sel();
|
screen_update_sel();
|
||||||
status_flush_surface();
|
|
||||||
|
|
||||||
SLIST_FOREACH(k, &W->h.keybind, next)
|
SLIST_FOREACH(k, &W->h.keybind, next)
|
||||||
if(k->keysym == keysym && KEYPRESS_MASK(k->mod) == KEYPRESS_MASK(ev->state))
|
if(k->keysym == keysym && KEYPRESS_MASK(k->mod) == KEYPRESS_MASK(ev->state))
|
||||||
@ -376,36 +236,6 @@ event_expose(XEvent *e)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
event_mapnotify(XEvent *e)
|
|
||||||
{
|
|
||||||
XMapEvent *ev = &e->xmap;
|
|
||||||
struct client *c;
|
|
||||||
struct _systray *s;
|
|
||||||
|
|
||||||
if(ev->window != ev->event && !ev->send_event)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if((c = client_gb_win(ev->window)))
|
|
||||||
client_map(c);
|
|
||||||
else if((s = systray_find(ev->window)))
|
|
||||||
{
|
|
||||||
ewmh_set_wm_state(s->win, NormalState);
|
|
||||||
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
|
static void
|
||||||
event_dummy(XEvent *e)
|
event_dummy(XEvent *e)
|
||||||
{
|
{
|
||||||
@ -429,11 +259,12 @@ event_init(void)
|
|||||||
event_handle[Expose] = event_expose;
|
event_handle[Expose] = event_expose;
|
||||||
event_handle[FocusIn] = event_focusin;
|
event_handle[FocusIn] = event_focusin;
|
||||||
event_handle[KeyPress] = event_keypress;
|
event_handle[KeyPress] = event_keypress;
|
||||||
event_handle[MapNotify] = event_mapnotify;
|
/*event_handle[MapNotify] = event_mapnotify;*/
|
||||||
event_handle[MapRequest] = event_maprequest;
|
event_handle[MapRequest] = event_maprequest;
|
||||||
event_handle[MappingNotify] = event_mappingnotify;
|
event_handle[MappingNotify] = event_mappingnotify;
|
||||||
event_handle[PropertyNotify] = event_propertynotify;
|
event_handle[PropertyNotify] = event_propertynotify;
|
||||||
/*event_handle[ReparentNotify] = event_reparentnotify;*/
|
/*event_handle[ReparentNotify] = event_reparentnotify;*/
|
||||||
event_handle[SelectionClear] = event_selectionclearevent;
|
/*event_handle[SelectionClear] = event_selectionclearevent;*/
|
||||||
event_handle[UnmapNotify] = event_unmapnotify;
|
event_handle[UnmapNotify] = event_unmapnotify;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,8 +6,6 @@
|
|||||||
#ifndef EVENT_H
|
#ifndef EVENT_H
|
||||||
#define EVENT_H
|
#define EVENT_H
|
||||||
|
|
||||||
#include <X11/XKBlib.h>
|
|
||||||
|
|
||||||
#include "wmfs.h"
|
#include "wmfs.h"
|
||||||
|
|
||||||
#define MAX_EV 256
|
#define MAX_EV 256
|
||||||
|
|||||||
212
src/ewmh.c
212
src/ewmh.c
@ -22,8 +22,6 @@ ewmh_init(void)
|
|||||||
|
|
||||||
/* EWMH hints */
|
/* EWMH hints */
|
||||||
W->net_atom[wm_state] = ATOM("WM_STATE");
|
W->net_atom[wm_state] = ATOM("WM_STATE");
|
||||||
W->net_atom[wm_class] = ATOM("WM_CLASS");
|
|
||||||
W->net_atom[wm_name] = ATOM("WM_NAME");
|
|
||||||
W->net_atom[net_supported] = ATOM("_NET_SUPPORTED");
|
W->net_atom[net_supported] = ATOM("_NET_SUPPORTED");
|
||||||
W->net_atom[net_client_list] = ATOM("_NET_CLIENT_LIST");
|
W->net_atom[net_client_list] = ATOM("_NET_CLIENT_LIST");
|
||||||
W->net_atom[net_frame_extents] = ATOM("_NET_FRAME_EXTENTS");
|
W->net_atom[net_frame_extents] = ATOM("_NET_FRAME_EXTENTS");
|
||||||
@ -42,7 +40,6 @@ ewmh_init(void)
|
|||||||
W->net_atom[net_supporting_wm_check] = ATOM("_NET_SUPPORTING_WM_CHECK");
|
W->net_atom[net_supporting_wm_check] = ATOM("_NET_SUPPORTING_WM_CHECK");
|
||||||
W->net_atom[net_wm_window_opacity] = ATOM("_NET_WM_WINDOW_OPACITY");
|
W->net_atom[net_wm_window_opacity] = ATOM("_NET_WM_WINDOW_OPACITY");
|
||||||
W->net_atom[net_wm_window_type_normal] = ATOM("_NET_WM_WINDOW_TYPE_NORMAL");
|
W->net_atom[net_wm_window_type_normal] = ATOM("_NET_WM_WINDOW_TYPE_NORMAL");
|
||||||
W->net_atom[net_wm_window_type_desktop] = ATOM("_NET_WM_WINDOW_TYPE_DESKTOP");
|
|
||||||
W->net_atom[net_wm_window_type_dock] = ATOM("_NET_WM_WINDOW_TYPE_DOCK");
|
W->net_atom[net_wm_window_type_dock] = ATOM("_NET_WM_WINDOW_TYPE_DOCK");
|
||||||
W->net_atom[net_wm_window_type_splash] = ATOM("_NET_WM_WINDOW_TYPE_SPLASH");
|
W->net_atom[net_wm_window_type_splash] = ATOM("_NET_WM_WINDOW_TYPE_SPLASH");
|
||||||
W->net_atom[net_wm_window_type_dialog] = ATOM("_NET_WM_WINDOW_TYPE_DIALOG");
|
W->net_atom[net_wm_window_type_dialog] = ATOM("_NET_WM_WINDOW_TYPE_DIALOG");
|
||||||
@ -51,9 +48,7 @@ ewmh_init(void)
|
|||||||
W->net_atom[net_wm_state_fullscreen] = ATOM("_NET_WM_STATE_FULLSCREEN");
|
W->net_atom[net_wm_state_fullscreen] = ATOM("_NET_WM_STATE_FULLSCREEN");
|
||||||
W->net_atom[net_wm_state_sticky] = ATOM("_NET_WM_STATE_STICKY");
|
W->net_atom[net_wm_state_sticky] = ATOM("_NET_WM_STATE_STICKY");
|
||||||
W->net_atom[net_wm_state_demands_attention] = ATOM("_NET_WM_STATE_DEMANDS_ATTENTION");
|
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");
|
W->net_atom[net_wm_system_tray_opcode] = ATOM("_NET_SYSTEM_TRAY_OPCODE");
|
||||||
W->net_atom[net_system_tray_s] = ATOM("_NET_SYSTEM_TRAY_S0");
|
|
||||||
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");
|
W->net_atom[net_system_tray_message_data] = ATOM("_NET_SYSTEM_TRAY_MESSAGE_DATA");
|
||||||
W->net_atom[net_system_tray_visual] = ATOM("_NET_SYSTEM_TRAY_VISUAL");
|
W->net_atom[net_system_tray_visual] = ATOM("_NET_SYSTEM_TRAY_VISUAL");
|
||||||
W->net_atom[net_system_tray_orientation] = ATOM("_NET_SYSTEM_TRAY_ORIENTATION");
|
W->net_atom[net_system_tray_orientation] = ATOM("_NET_SYSTEM_TRAY_ORIENTATION");
|
||||||
@ -84,14 +79,12 @@ ewmh_init(void)
|
|||||||
/* 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(W->dpy, W->root, W->net_atom[net_supporting_wm_check], XA_WINDOW, 32,
|
||||||
PropModeReplace, (unsigned char*)&W->root, 1);
|
PropModeReplace, (unsigned char*)&W->root, 1);
|
||||||
|
/*
|
||||||
|
XChangeProperty(W->dpy, W->root, W->net_atom[net_wm_name], W->net_atom[utf8_string], 8,
|
||||||
|
PropModeReplace, (unsigned char*)&rootn, strlen(rootn));
|
||||||
|
|
||||||
XChangeProperty(W->dpy, W->root, ATOM("WM_CLASS"), XA_STRING, 8,
|
XChangeProperty(W->dpy, W->root, ATOM("WM_CLASS"), XA_STRING, 8,
|
||||||
PropModeReplace, (unsigned char*)&"wmfs", 4);
|
PropModeReplace, (unsigned char*)&class, strlen(class));
|
||||||
|
|
||||||
XChangeProperty(W->dpy, W->root, W->net_atom[net_wm_name], W->net_atom[utf8_string], 8,
|
|
||||||
PropModeReplace, (unsigned char*)&"wmfs2", 5);
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
* Set _NET_WM_PID
|
* Set _NET_WM_PID
|
||||||
XChangeProperty(W->dpy, W->root, W->net_atom[net_wm_pid], XA_CARDINAL, 32,
|
XChangeProperty(W->dpy, W->root, W->net_atom[net_wm_pid], XA_CARDINAL, 32,
|
||||||
@ -113,56 +106,6 @@ ewmh_set_wm_state(Window w, int state)
|
|||||||
W->net_atom[wm_state], 32, PropModeReplace, d, 2);
|
W->net_atom[wm_state], 32, PropModeReplace, d, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* _NET_CLIENT_LIST
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
ewmh_get_client_list(void)
|
|
||||||
{
|
|
||||||
Window *list;
|
|
||||||
struct client *c;
|
|
||||||
int win_n = 0;
|
|
||||||
|
|
||||||
SLIST_FOREACH(c, &W->h.client, next)
|
|
||||||
++win_n;
|
|
||||||
|
|
||||||
list = xcalloc(win_n, sizeof(Window));
|
|
||||||
|
|
||||||
win_n = 0;
|
|
||||||
SLIST_FOREACH(c, &W->h.client, next)
|
|
||||||
list[win_n++] = c->win;
|
|
||||||
|
|
||||||
XChangeProperty(W->dpy, W->root, W->net_atom[net_client_list], XA_WINDOW, 32,
|
|
||||||
PropModeReplace, (unsigned char *)list, win_n);
|
|
||||||
|
|
||||||
XFree(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get xembed state
|
|
||||||
*/
|
|
||||||
long
|
|
||||||
ewmh_get_xembed_state(Window win)
|
|
||||||
{
|
|
||||||
Atom rf;
|
|
||||||
int f;
|
|
||||||
long ret = 0;
|
|
||||||
unsigned long n, il;
|
|
||||||
unsigned char *data = NULL;
|
|
||||||
|
|
||||||
if(XGetWindowProperty(W->dpy, win, W->net_atom[xembedinfo], 0L, 2, False,
|
|
||||||
W->net_atom[xembedinfo], &rf, &f, &n, &il, &data) != Success)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if(rf == W->net_atom[xembedinfo] && n == 2)
|
|
||||||
ret = (long)data[1];
|
|
||||||
|
|
||||||
if(n && data)
|
|
||||||
XFree(data);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ewmh_update_wmfs_props(void)
|
ewmh_update_wmfs_props(void)
|
||||||
{
|
{
|
||||||
@ -175,6 +118,7 @@ ewmh_update_wmfs_props(void)
|
|||||||
|
|
||||||
cts = xcalloc(ns, sizeof(long));
|
cts = xcalloc(ns, sizeof(long));
|
||||||
|
|
||||||
|
|
||||||
for(i = 0; i < ns; ++i)
|
for(i = 0; i < ns; ++i)
|
||||||
{
|
{
|
||||||
s = screen_gb_id(i);
|
s = screen_gb_id(i);
|
||||||
@ -195,113 +139,34 @@ void
|
|||||||
ewmh_manage_state(long data[], struct client *c)
|
ewmh_manage_state(long data[], struct client *c)
|
||||||
{
|
{
|
||||||
/* _NET_WM_STATE_FULLSCREEN */
|
/* _NET_WM_STATE_FULLSCREEN */
|
||||||
if(data[1] == (long)W->net_atom[net_wm_state_fullscreen]
|
if(data[1] == (long)W->net_atom[net_wm_state_fullscreen])
|
||||||
|| data[2] == (long)W->net_atom[net_wm_state_fullscreen])
|
|
||||||
{
|
{
|
||||||
if(data[0] == _NET_WM_STATE_ADD
|
if(data[0] == _NET_WM_STATE_ADD
|
||||||
|| (data[0] == _NET_WM_STATE_TOGGLE && !(c->flags & CLIENT_FULLSCREEN)))
|
|| (data[0] == _NET_WM_STATE_TOGGLE && !(c->flags & CLIENT_FULLSCREEN)))
|
||||||
{
|
{
|
||||||
c->flags |= CLIENT_FULLSCREEN;
|
c->flags |= CLIENT_FULLSCREEN;
|
||||||
|
|
||||||
XChangeProperty(W->dpy, c->win, W->net_atom[net_wm_state], XA_ATOM, 32, PropModeReplace,
|
|
||||||
(unsigned char*)&W->net_atom[net_wm_state_fullscreen], 1);
|
|
||||||
XReparentWindow(W->dpy, c->win, W->root, c->screen->geo.x, c->screen->geo.y);
|
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);
|
XResizeWindow(W->dpy, c->win, c->screen->geo.w, c->screen->geo.h);
|
||||||
|
XChangeProperty(W->dpy, c->win, W->net_atom[net_wm_state], XA_ATOM, 32, PropModeReplace,
|
||||||
|
(unsigned char*)&W->net_atom[net_wm_state_fullscreen], true);
|
||||||
|
|
||||||
if(c->tag)
|
client_focus(c);
|
||||||
client_focus(c);
|
|
||||||
|
|
||||||
XRaiseWindow(W->dpy, c->win);
|
XRaiseWindow(W->dpy, c->win);
|
||||||
}
|
}
|
||||||
else
|
else if(data[0] == _NET_WM_STATE_REMOVE
|
||||||
|
|| (data[0] == _NET_WM_STATE_TOGGLE && c->flags & CLIENT_FULLSCREEN))
|
||||||
{
|
{
|
||||||
c->flags &= ~CLIENT_FULLSCREEN;
|
c->flags &= ~CLIENT_FULLSCREEN;
|
||||||
|
|
||||||
XChangeProperty(W->dpy, c->win, W->net_atom[net_wm_state], XA_ATOM, 32, PropModeReplace,
|
|
||||||
(unsigned char*)0, 0);
|
|
||||||
XReparentWindow(W->dpy, c->win, c->frame, c->wgeo.x, c->wgeo.y);
|
XReparentWindow(W->dpy, c->win, c->frame, c->wgeo.x, c->wgeo.y);
|
||||||
|
XChangeProperty(W->dpy, c->win, W->net_atom[net_wm_state], XA_ATOM, 32, PropModeReplace,
|
||||||
|
(unsigned char*)&W->net_atom[net_wm_state_fullscreen], false);
|
||||||
|
|
||||||
if(c->flags & CLIENT_FREE)
|
client_moveresize(c, &c->geo);
|
||||||
client_moveresize(c, &c->geo);
|
|
||||||
else
|
|
||||||
layout_fix_hole(c);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -313,20 +178,6 @@ ewmh_manage_window_type(struct client *c)
|
|||||||
unsigned char *data = NULL;
|
unsigned char *data = NULL;
|
||||||
long ldata[5] = { _NET_WM_STATE_ADD };
|
long ldata[5] = { _NET_WM_STATE_ADD };
|
||||||
|
|
||||||
if(XGetWindowProperty(W->dpy, c->win, W->net_atom[net_wm_window_type], 0L, 0x7FFFFFFFL,
|
|
||||||
False, XA_ATOM, &rf, &f, &n, &il, &data) == Success && n)
|
|
||||||
{
|
|
||||||
atom = (Atom*)data;
|
|
||||||
|
|
||||||
for(i = 0; i < n; ++i)
|
|
||||||
{
|
|
||||||
/* MANAGE _NET_WM_WINDOW_TYPE_DIALOG */
|
|
||||||
if(atom[i] == W->net_atom[net_wm_window_type_dialog])
|
|
||||||
c->flags |= CLIENT_FREE;
|
|
||||||
}
|
|
||||||
XFree(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* _NET_WM_STATE at window mangement */
|
/* _NET_WM_STATE at window mangement */
|
||||||
if(XGetWindowProperty(W->dpy, c->win, W->net_atom[net_wm_state], 0L, 0x7FFFFFFFL, false,
|
if(XGetWindowProperty(W->dpy, c->win, W->net_atom[net_wm_state], 0L, 0x7FFFFFFFL, false,
|
||||||
XA_ATOM, &rf, &f, &n, &il, &data) == Success && n)
|
XA_ATOM, &rf, &f, &n, &il, &data) == Success && n)
|
||||||
@ -343,36 +194,3 @@ ewmh_manage_window_type(struct client *c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
atom = (Atom*)data;
|
|
||||||
|
|
||||||
for(i = 0; i < n; ++i)
|
|
||||||
{
|
|
||||||
/* If it is a _NET_WM_WINDOW_TYPE_DESKTOP window */
|
|
||||||
if(atom[i] == W->net_atom[net_wm_window_type_desktop])
|
|
||||||
{
|
|
||||||
/* map it, but don't manage it */
|
|
||||||
XMapWindow(W->dpy, win);
|
|
||||||
XMapSubwindows(W->dpy, win);
|
|
||||||
|
|
||||||
is_desktop = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
XFree(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
return is_desktop;
|
|
||||||
}
|
|
||||||
|
|||||||
52
src/ewmh.h
52
src/ewmh.h
@ -11,37 +11,12 @@
|
|||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
|
|
||||||
#include "wmfs.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 */
|
/* Ewmh hints list */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
/* ICCCM */
|
/* ICCCM */
|
||||||
wm_state,
|
wm_state,
|
||||||
wm_class,
|
|
||||||
wm_name,
|
|
||||||
/* EWMH */
|
/* EWMH */
|
||||||
net_supported,
|
net_supported,
|
||||||
net_wm_name,
|
net_wm_name,
|
||||||
@ -60,7 +35,6 @@ enum
|
|||||||
net_supporting_wm_check,
|
net_supporting_wm_check,
|
||||||
net_wm_window_opacity,
|
net_wm_window_opacity,
|
||||||
net_wm_window_type_normal,
|
net_wm_window_type_normal,
|
||||||
net_wm_window_type_desktop,
|
|
||||||
net_wm_window_type_dock,
|
net_wm_window_type_dock,
|
||||||
net_wm_window_type_splash,
|
net_wm_window_type_splash,
|
||||||
net_wm_window_type_dialog,
|
net_wm_window_type_dialog,
|
||||||
@ -70,8 +44,7 @@ enum
|
|||||||
net_wm_state_fullscreen,
|
net_wm_state_fullscreen,
|
||||||
net_wm_state_sticky,
|
net_wm_state_sticky,
|
||||||
net_wm_state_demands_attention,
|
net_wm_state_demands_attention,
|
||||||
net_wm_state_hidden,
|
net_wm_system_tray_opcode,
|
||||||
net_system_tray_opcode,
|
|
||||||
net_system_tray_message_data,
|
net_system_tray_message_data,
|
||||||
net_system_tray_s,
|
net_system_tray_s,
|
||||||
net_system_tray_visual,
|
net_system_tray_visual,
|
||||||
@ -99,33 +72,10 @@ enum
|
|||||||
net_last
|
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_init(void);
|
||||||
void ewmh_set_wm_state(Window w, int state);
|
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_update_wmfs_props(void);
|
||||||
void ewmh_manage_state(long data[], struct client *c);
|
void ewmh_manage_state(long data[], struct client *c);
|
||||||
bool ewmh_manage_state_sticky(Window win);
|
|
||||||
void ewmh_manage_window_type(struct client *c);
|
void ewmh_manage_window_type(struct client *c);
|
||||||
bool ewmh_manage_window_type_desktop(Window win);
|
|
||||||
|
|
||||||
#endif /* EWMH_H */
|
#endif /* EWMH_H */
|
||||||
|
|||||||
73
src/fifo.c
Normal file
73
src/fifo.c
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
||||||
|
* File created by David Delassus.
|
||||||
|
* For license, see COPYING.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/stat.h> /* access */
|
||||||
|
|
||||||
|
#include "wmfs.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "fifo.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
fifo_open(void)
|
||||||
|
{
|
||||||
|
if(W->fifo.fd)
|
||||||
|
close(W->fifo.fd);
|
||||||
|
|
||||||
|
if(!(W->fifo.fd = open(W->fifo.path, O_RDONLY | O_NDELAY, 0)))
|
||||||
|
warnxl("Can't open FIFO: %s\n", strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fifo_init(void)
|
||||||
|
{
|
||||||
|
xasprintf(&(W->fifo.path), "%s/wmfs-%s.fifo", P_tmpdir, DisplayString(W->dpy));
|
||||||
|
|
||||||
|
/* Check if fifo already exists */
|
||||||
|
if(access(W->fifo.path, F_OK) != -1)
|
||||||
|
unlink(W->fifo.path);
|
||||||
|
|
||||||
|
if(mkfifo(W->fifo.path, 0644) < 0)
|
||||||
|
warnxl("Can't create FIFO: %s\n", strerror(errno));
|
||||||
|
|
||||||
|
fifo_open();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fifo_parse(char *cmd)
|
||||||
|
{
|
||||||
|
void (*func)(Uicb);
|
||||||
|
char *p, *arg = NULL;
|
||||||
|
|
||||||
|
/* remove trailing newline */
|
||||||
|
if((p = strchr(cmd, '\n')))
|
||||||
|
*p = '\0';
|
||||||
|
|
||||||
|
/* If an argument is present, delimit function string */
|
||||||
|
if((p = strchr(cmd, ' ')))
|
||||||
|
{
|
||||||
|
*p = '\0';
|
||||||
|
arg = p + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* call the UICB function, p + 1 is command or NULL */
|
||||||
|
if((func = uicb_name_func(cmd)))
|
||||||
|
func(arg);
|
||||||
|
|
||||||
|
XSync(W->dpy, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fifo_read(void)
|
||||||
|
{
|
||||||
|
char buf[256] = { 0 };
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if((ret = read(W->fifo.fd, buf, sizeof(buf) - 1)) > 0)
|
||||||
|
fifo_parse(buf);
|
||||||
|
else if(!ret)
|
||||||
|
fifo_open();
|
||||||
|
}
|
||||||
340
src/infobar.c
340
src/infobar.c
@ -10,25 +10,10 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "tag.h"
|
#include "tag.h"
|
||||||
#include "status.h"
|
#include "status.h"
|
||||||
#include "systray.h"
|
|
||||||
#include "client.h"
|
|
||||||
|
|
||||||
#define ELEM_FREE_BARWIN(e) \
|
|
||||||
while(!SLIST_EMPTY(&e->bars)) \
|
|
||||||
{ \
|
|
||||||
b = SLIST_FIRST(&e->bars); \
|
|
||||||
SLIST_REMOVE_HEAD(&e->bars, enext); \
|
|
||||||
barwin_remove(b); \
|
|
||||||
}
|
|
||||||
|
|
||||||
static void infobar_elem_tag_init(struct element *e);
|
static void infobar_elem_tag_init(struct element *e);
|
||||||
static void infobar_elem_tag_update(struct element *e);
|
static void infobar_elem_tag_update(struct element *e);
|
||||||
static void infobar_elem_status_init(struct element *e);
|
static void infobar_elem_status_init(struct element *e);
|
||||||
static void infobar_elem_status_update(struct element *e);
|
|
||||||
static void infobar_elem_systray_init(struct element *e);
|
|
||||||
static void infobar_elem_systray_update(struct element *e);
|
|
||||||
static void infobar_elem_launcher_init(struct element *e);
|
|
||||||
static void infobar_elem_launcher_update(struct element *e);
|
|
||||||
|
|
||||||
const struct elem_funcs
|
const struct elem_funcs
|
||||||
{
|
{
|
||||||
@ -37,10 +22,12 @@ const struct elem_funcs
|
|||||||
void (*func_update)(struct element *e);
|
void (*func_update)(struct element *e);
|
||||||
} elem_funcs[] =
|
} elem_funcs[] =
|
||||||
{
|
{
|
||||||
{ 't', infobar_elem_tag_init, infobar_elem_tag_update },
|
{ 't', infobar_elem_tag_init, infobar_elem_tag_update },
|
||||||
{ 's', infobar_elem_status_init, infobar_elem_status_update },
|
{ 's', infobar_elem_status_init, status_manage },
|
||||||
{ 'y', infobar_elem_systray_init, infobar_elem_systray_update },
|
|
||||||
{ 'l', infobar_elem_launcher_init, infobar_elem_launcher_update },
|
/* { 'l', infobar_elem_layout_init, infobar_elem_layout_update },
|
||||||
|
{ 'S', infobar_elem_selbar_init, infobar_elem_selbar_update },
|
||||||
|
*/
|
||||||
{ '\0', NULL, NULL }
|
{ '\0', NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -61,54 +48,32 @@ infobar_elem_tag_init(struct element *e)
|
|||||||
j = e->geo.x;
|
j = e->geo.x;
|
||||||
e->geo.h -= (e->infobar->theme->tags_border_width << 1);
|
e->geo.h -= (e->infobar->theme->tags_border_width << 1);
|
||||||
|
|
||||||
e->statusctx = &e->infobar->theme->tags_n_sl;
|
TAILQ_FOREACH(t, &e->infobar->screen->tags, next)
|
||||||
e->statusctx->flags |= STATUS_BLOCK_REFRESH;
|
|
||||||
|
|
||||||
if(SLIST_EMPTY(&e->bars) || (e->infobar->screen->flags & SCREEN_TAG_UPDATE))
|
|
||||||
{
|
{
|
||||||
if((e->infobar->screen->flags & SCREEN_TAG_UPDATE))
|
s = draw_textw(e->infobar->theme, t->name) + PAD;
|
||||||
|
|
||||||
|
/* Init barwin */
|
||||||
|
b = barwin_new(e->infobar->bar->win, j, 0, s, e->geo.h, 0, 0, false);
|
||||||
|
|
||||||
|
/* Set border */
|
||||||
|
if(e->infobar->theme->tags_border_width)
|
||||||
{
|
{
|
||||||
ELEM_FREE_BARWIN(e);
|
XSetWindowBorder(W->dpy, b->win, e->infobar->theme->tags_border_col);
|
||||||
SLIST_INIT(&e->bars);
|
XSetWindowBorderWidth(W->dpy, b->win, e->infobar->theme->tags_border_width);
|
||||||
}
|
}
|
||||||
|
|
||||||
TAILQ_FOREACH(t, &e->infobar->screen->tags, next)
|
b->ptr = (void*)t;
|
||||||
{
|
barwin_map(b);
|
||||||
s = draw_textw(e->infobar->theme, t->name) + PAD;
|
|
||||||
|
|
||||||
/* Init barwin */
|
b->mousebinds = W->tmp_head.tag;
|
||||||
b = barwin_new(e->infobar->bar->win, j, 0, s, e->geo.h, 0, 0, false);
|
|
||||||
|
|
||||||
/* Status doesn't have theme yet */
|
SLIST_INSERT_TAIL(&e->bars, b, enext, prev);
|
||||||
t->statusctx.theme = e->infobar->theme;
|
|
||||||
t->statusctx.flags |= STATUS_BLOCK_REFRESH;
|
|
||||||
|
|
||||||
/* Set border */
|
prev = b;
|
||||||
if(e->infobar->theme->tags_border_width)
|
j += s;
|
||||||
{
|
|
||||||
XSetWindowBorder(W->dpy, b->win, e->infobar->theme->tags_border_col);
|
|
||||||
XSetWindowBorderWidth(W->dpy, b->win, e->infobar->theme->tags_border_width);
|
|
||||||
}
|
|
||||||
|
|
||||||
b->ptr = (void*)t;
|
|
||||||
barwin_map(b);
|
|
||||||
|
|
||||||
b->mousebinds = W->tmp_head.tag;
|
|
||||||
|
|
||||||
SLIST_INSERT_TAIL(&e->bars, b, enext, prev);
|
|
||||||
|
|
||||||
prev = b;
|
|
||||||
j += s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SLIST_FOREACH(b, &e->bars, enext)
|
|
||||||
{
|
|
||||||
barwin_move(b, j, 0);
|
|
||||||
j += b->geo.w;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
e->infobar->screen->elemupdate |= FLAGINT(ElemTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -126,44 +91,15 @@ infobar_elem_tag_update(struct element *e)
|
|||||||
{
|
{
|
||||||
b->fg = e->infobar->theme->tags_s.fg;
|
b->fg = e->infobar->theme->tags_s.fg;
|
||||||
b->bg = e->infobar->theme->tags_s.bg;
|
b->bg = e->infobar->theme->tags_s.bg;
|
||||||
e->statusctx = &e->infobar->theme->tags_s_sl;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Normal tag */
|
b->fg = e->infobar->theme->tags_n.fg;
|
||||||
if(SLIST_EMPTY(&t->clients))
|
b->bg = e->infobar->theme->tags_n.bg;
|
||||||
{
|
|
||||||
b->fg = e->infobar->theme->tags_n.fg;
|
|
||||||
b->bg = e->infobar->theme->tags_n.bg;
|
|
||||||
e->statusctx = &e->infobar->theme->tags_n_sl;
|
|
||||||
}
|
|
||||||
/* Urgent tag */
|
|
||||||
else if(t->flags & TAG_URGENT)
|
|
||||||
{
|
|
||||||
b->fg = e->infobar->theme->tags_u.fg;
|
|
||||||
b->bg = e->infobar->theme->tags_u.bg;
|
|
||||||
e->statusctx = &e->infobar->theme->tags_u_sl;
|
|
||||||
}
|
|
||||||
/* Occupied tag */
|
|
||||||
else
|
|
||||||
{
|
|
||||||
b->fg = e->infobar->theme->tags_o.fg;
|
|
||||||
b->bg = e->infobar->theme->tags_o.bg;
|
|
||||||
e->statusctx = &e->infobar->theme->tags_o_sl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
barwin_refresh_color(b);
|
barwin_refresh_color(b);
|
||||||
|
|
||||||
/* Manage status line */
|
|
||||||
e->statusctx->barwin = b;
|
|
||||||
status_copy_mousebind(e->statusctx);
|
|
||||||
status_render(e->statusctx);
|
|
||||||
|
|
||||||
t->statusctx.barwin = b;
|
|
||||||
status_copy_mousebind(&t->statusctx);
|
|
||||||
status_render(&t->statusctx);
|
|
||||||
|
|
||||||
draw_text(b->dr, e->infobar->theme, (PAD >> 1),
|
draw_text(b->dr, e->infobar->theme, (PAD >> 1),
|
||||||
TEXTY(e->infobar->theme, e->geo.h), b->fg, t->name);
|
TEXTY(e->infobar->theme, e->geo.h), b->fg, t->name);
|
||||||
|
|
||||||
@ -181,123 +117,17 @@ infobar_elem_status_init(struct element *e)
|
|||||||
|
|
||||||
e->geo.w = e->infobar->geo.w - e->geo.x - (en ? e->infobar->geo.w - en->geo.x : 0);
|
e->geo.w = e->infobar->geo.w - e->geo.x - (en ? e->infobar->geo.w - en->geo.x : 0);
|
||||||
|
|
||||||
if(!(b = SLIST_FIRST(&e->bars)))
|
b = barwin_new(e->infobar->bar->win, e->geo.x, 0, e->geo.w, e->geo.h, 0, 0, false);
|
||||||
{
|
|
||||||
b = barwin_new(e->infobar->bar->win, e->geo.x, 0, e->geo.w, e->geo.h, 0, 0, false);
|
|
||||||
barwin_refresh_color(b);
|
|
||||||
SLIST_INSERT_HEAD(&e->bars, b, enext);
|
|
||||||
|
|
||||||
e->infobar->statusctx = status_new_ctx(b, e->infobar->theme);
|
|
||||||
e->infobar->statusctx.status = strdup("wmfs2");
|
|
||||||
e->infobar->statusctx.update = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
barwin_move(b, e->geo.x, e->geo.y);
|
|
||||||
barwin_resize(b, e->geo.w, e->geo.h);
|
|
||||||
}
|
|
||||||
|
|
||||||
b->fg = e->infobar->theme->bars.fg;
|
b->fg = e->infobar->theme->bars.fg;
|
||||||
b->bg = e->infobar->theme->bars.bg;
|
b->bg = e->infobar->theme->bars.bg;
|
||||||
|
|
||||||
barwin_map(b);
|
barwin_map(b);
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
SLIST_INSERT_HEAD(&e->bars, b, enext);
|
||||||
infobar_elem_status_update(struct element *e)
|
|
||||||
{
|
|
||||||
if(e->infobar->statusctx.update)
|
|
||||||
status_manage(&e->infobar->statusctx);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
status_render(&e->infobar->statusctx);
|
|
||||||
status_copy_mousebind(&e->infobar->statusctx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
e->infobar->screen->elemupdate |= FLAGINT(ElemStatus);
|
||||||
infobar_elem_systray_init(struct element *e)
|
e->infobar->status = strdup("wmfs2");
|
||||||
{
|
|
||||||
struct barwin *b;
|
|
||||||
|
|
||||||
/* Activate systray mask; no more systray element allowed now */
|
|
||||||
W->flags |= WMFS_SYSTRAY;
|
|
||||||
|
|
||||||
W->systray.infobar = e->infobar;
|
|
||||||
|
|
||||||
e->geo.w = systray_get_width();
|
|
||||||
infobar_elem_placement(e);
|
|
||||||
|
|
||||||
if(!(b = SLIST_FIRST(&e->bars)))
|
|
||||||
{
|
|
||||||
b = barwin_new(e->infobar->bar->win, e->geo.x, 0, e->geo.w, e->geo.h, 0, 0, false);
|
|
||||||
XFreePixmap(W->dpy, b->dr);
|
|
||||||
SLIST_INSERT_HEAD(&e->bars, b, enext);
|
|
||||||
W->systray.barwin = b;
|
|
||||||
systray_acquire();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
barwin_move(b, e->geo.x, e->geo.y);
|
|
||||||
barwin_resize(b, e->geo.w, e->geo.h);
|
|
||||||
}
|
|
||||||
|
|
||||||
XMoveResizeWindow(W->dpy, W->systray.win, 0, 0, e->geo.w, e->geo.h);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
infobar_elem_systray_update(struct element *e)
|
|
||||||
{
|
|
||||||
(void)e;
|
|
||||||
|
|
||||||
systray_update();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
infobar_elem_launcher_init(struct element *e)
|
|
||||||
{
|
|
||||||
struct barwin *b;
|
|
||||||
|
|
||||||
if(!(W->flags & WMFS_LAUNCHER))
|
|
||||||
e->geo.w = 1;
|
|
||||||
|
|
||||||
infobar_elem_placement(e);
|
|
||||||
|
|
||||||
if(!(b = SLIST_FIRST(&e->bars)))
|
|
||||||
{
|
|
||||||
b = barwin_new(e->infobar->bar->win, e->geo.x, 0, e->geo.w, e->geo.h, 0, 0, false);
|
|
||||||
b->fg = e->infobar->theme->bars.fg;
|
|
||||||
b->bg = e->infobar->theme->bars.bg;
|
|
||||||
SLIST_INSERT_HEAD(&e->bars, b, enext);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
barwin_move(b, e->geo.x, e->geo.y);
|
|
||||||
barwin_resize(b, e->geo.w, e->geo.h);
|
|
||||||
}
|
|
||||||
|
|
||||||
barwin_refresh_color(b);
|
|
||||||
barwin_refresh(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
infobar_elem_launcher_update(struct element *e)
|
|
||||||
{
|
|
||||||
struct barwin *b = SLIST_FIRST(&e->bars);
|
|
||||||
int l;
|
|
||||||
|
|
||||||
if(!(W->flags & WMFS_LAUNCHER))
|
|
||||||
return;
|
|
||||||
|
|
||||||
barwin_refresh_color(b);
|
|
||||||
|
|
||||||
l = draw_textw(e->infobar->theme, e->data) + 2;
|
|
||||||
draw_text(b->dr, e->infobar->theme, 1, TEXTY(e->infobar->theme, e->geo.h), b->fg, e->data);
|
|
||||||
|
|
||||||
/* Cursor */
|
|
||||||
XDrawLine(W->dpy, b->dr, W->gc, l, 2, l, e->geo.h - 4);
|
|
||||||
|
|
||||||
barwin_refresh(b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ELEM_INIT(a) \
|
#define ELEM_INIT(a) \
|
||||||
@ -306,7 +136,6 @@ infobar_elem_launcher_update(struct element *e)
|
|||||||
SLIST_INIT(&e->bars); \
|
SLIST_INIT(&e->bars); \
|
||||||
e->infobar = i; \
|
e->infobar = i; \
|
||||||
e->type = j; \
|
e->type = j; \
|
||||||
e->data = NULL; \
|
|
||||||
e->align = a; \
|
e->align = a; \
|
||||||
e->func_init = elem_funcs[j].func_init; \
|
e->func_init = elem_funcs[j].func_init; \
|
||||||
e->func_update = elem_funcs[j].func_update; \
|
e->func_update = elem_funcs[j].func_update; \
|
||||||
@ -330,16 +159,15 @@ infobar_elem_init(struct infobar *i)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only one systray element in a wmfs session */
|
|
||||||
if(i->elemorder[n] == 'y' && W->flags & WMFS_SYSTRAY)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for(j = 0; j < (int)LEN(elem_funcs); ++j)
|
for(j = 0; j < (int)LEN(elem_funcs); ++j)
|
||||||
if(elem_funcs[j].c == i->elemorder[n])
|
if(elem_funcs[j].c == i->elemorder[n])
|
||||||
{
|
{
|
||||||
ELEM_INIT(Left);
|
ELEM_INIT(Left);
|
||||||
|
|
||||||
TAILQ_INSERT_TAIL(&i->elements, e, next);
|
if(TAILQ_EMPTY(&i->elements))
|
||||||
|
TAILQ_INSERT_HEAD(&i->elements, e, next);
|
||||||
|
else
|
||||||
|
TAILQ_INSERT_TAIL(&i->elements, e, next);
|
||||||
|
|
||||||
e->func_init(e);
|
e->func_init(e);
|
||||||
es = e;
|
es = e;
|
||||||
@ -355,7 +183,7 @@ infobar_elem_init(struct infobar *i)
|
|||||||
for(k = l - 1; k >= n; --k)
|
for(k = l - 1; k >= n; --k)
|
||||||
{
|
{
|
||||||
/* Only one status */
|
/* Only one status */
|
||||||
if(i->elemorder[k] == 's' || (i->elemorder[n] == 'y' && W->flags & WMFS_SYSTRAY))
|
if(i->elemorder[k] == 's')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for(j = 0; j < (int)LEN(elem_funcs); ++j)
|
for(j = 0; j < (int)LEN(elem_funcs); ++j)
|
||||||
@ -388,49 +216,30 @@ infobar_elem_init(struct infobar *i)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
infobar_elem_update(struct infobar *i, int type)
|
infobar_elem_update(struct infobar *i)
|
||||||
{
|
{
|
||||||
struct element *e;
|
struct element *e;
|
||||||
|
|
||||||
TAILQ_FOREACH(e, &i->elements, next)
|
TAILQ_FOREACH(e, &i->elements, next)
|
||||||
if(type == e->type || type == -1)
|
if(i->screen->elemupdate & FLAGINT(e->type))
|
||||||
e->func_update(e);
|
e->func_update(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
infobar_elem_reinit(struct infobar *i)
|
infobar_elem_remove(struct element *e)
|
||||||
{
|
{
|
||||||
struct element *e;
|
struct barwin *b;
|
||||||
|
|
||||||
barwin_refresh_color(i->bar);
|
TAILQ_REMOVE(&e->infobar->elements, e, next);
|
||||||
|
|
||||||
TAILQ_FOREACH(e, &i->elements, next)
|
while(!SLIST_EMPTY(&e->bars))
|
||||||
{
|
{
|
||||||
/* Status element found, scan from the tail now */
|
b = SLIST_FIRST(&e->bars);
|
||||||
if(e->type == ElemStatus)
|
SLIST_REMOVE_HEAD(&e->bars, enext);
|
||||||
{
|
barwin_remove(b);
|
||||||
struct element *ee;
|
|
||||||
|
|
||||||
TAILQ_FOREACH_REVERSE(ee, &i->elements, esub, next)
|
|
||||||
{
|
|
||||||
if(e == ee)
|
|
||||||
break;
|
|
||||||
|
|
||||||
ee->func_init(ee);
|
|
||||||
ee->func_update(ee);
|
|
||||||
}
|
|
||||||
|
|
||||||
e->func_init(e);
|
|
||||||
e->func_update(e);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
e->func_init(e);
|
|
||||||
e->func_update(e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
barwin_refresh(i->bar);
|
free(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct infobar*
|
struct infobar*
|
||||||
@ -455,6 +264,8 @@ infobar_new(struct screen *s, char *name, struct theme *theme, enum barpos pos,
|
|||||||
/* struct elements */
|
/* struct elements */
|
||||||
infobar_elem_init(i);
|
infobar_elem_init(i);
|
||||||
|
|
||||||
|
SLIST_INIT(&i->statushead);
|
||||||
|
|
||||||
/* Render, only if pos is Top or Bottom */
|
/* Render, only if pos is Top or Bottom */
|
||||||
if(!map)
|
if(!map)
|
||||||
return i;
|
return i;
|
||||||
@ -470,7 +281,7 @@ infobar_new(struct screen *s, char *name, struct theme *theme, enum barpos pos,
|
|||||||
void
|
void
|
||||||
infobar_refresh(struct infobar *i)
|
infobar_refresh(struct infobar *i)
|
||||||
{
|
{
|
||||||
infobar_elem_update(i, -1);
|
infobar_elem_update(i);
|
||||||
|
|
||||||
barwin_refresh(i->bar);
|
barwin_refresh(i->bar);
|
||||||
}
|
}
|
||||||
@ -479,21 +290,13 @@ void
|
|||||||
infobar_remove(struct infobar *i)
|
infobar_remove(struct infobar *i)
|
||||||
{
|
{
|
||||||
struct element *e;
|
struct element *e;
|
||||||
struct barwin *b;
|
|
||||||
|
|
||||||
free(i->elemorder);
|
free(i->elemorder);
|
||||||
free(i->name);
|
free(i->name);
|
||||||
|
free(i->status);
|
||||||
|
|
||||||
if(i == W->systray.infobar)
|
TAILQ_FOREACH(e, &i->elements, next)
|
||||||
systray_freeicons();
|
infobar_elem_remove(e);
|
||||||
|
|
||||||
while(!TAILQ_EMPTY(&i->elements))
|
|
||||||
{
|
|
||||||
e = TAILQ_FIRST(&i->elements);
|
|
||||||
TAILQ_REMOVE(&i->elements, e, next);
|
|
||||||
ELEM_FREE_BARWIN(e);
|
|
||||||
free(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
barwin_remove(i->bar);
|
barwin_remove(i->bar);
|
||||||
|
|
||||||
@ -516,49 +319,8 @@ infobar_free(struct screen *s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
uicb_infobar_toggle_hide(Uicb iname)
|
|
||||||
{
|
|
||||||
struct client *c;
|
|
||||||
struct infobar *i;
|
|
||||||
|
|
||||||
if(iname)
|
|
||||||
i = infobar_gb_name(iname);
|
|
||||||
else
|
|
||||||
i = SLIST_FIRST(&W->screen->infobars);
|
|
||||||
|
|
||||||
if(i->pos == BarHide)
|
|
||||||
{
|
|
||||||
i->pos = i->opos;
|
|
||||||
|
|
||||||
if(infobar_placement(i, i->pos))
|
|
||||||
{
|
|
||||||
barwin_map(i->bar);
|
|
||||||
barwin_map_subwin(i->bar);
|
|
||||||
barwin_refresh_color(i->bar);
|
|
||||||
infobar_refresh(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
i->opos = i->pos;
|
|
||||||
i->pos = BarHide;
|
|
||||||
|
|
||||||
barwin_unmap_subwin(i->bar);
|
|
||||||
barwin_unmap(i->bar);
|
|
||||||
|
|
||||||
switch(i->opos)
|
|
||||||
{
|
|
||||||
case BarTop:
|
|
||||||
i->screen->ugeo.y -= i->geo.h;
|
|
||||||
case BarBottom:
|
|
||||||
i->screen->ugeo.h += i->geo.h;
|
|
||||||
case BarHide:
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SLIST_FOREACH(c, &W->h.client, next)
|
|
||||||
layout_fix_hole(c);
|
|
||||||
}
|
|
||||||
|
|||||||
@ -8,16 +8,16 @@
|
|||||||
|
|
||||||
#include "wmfs.h"
|
#include "wmfs.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "draw.h"
|
||||||
#include "tag.h"
|
#include "tag.h"
|
||||||
|
|
||||||
enum { ElemTag = 0, ElemStatus, ElemSystray, ElemLauncher, ElemCustom, ElemLast };
|
enum { ElemTag = 0, ElemStatus, ElemCustom, ElemLast };
|
||||||
|
|
||||||
struct infobar *infobar_new(struct screen *s, char *name, struct theme *theme, enum barpos pos, const char *elem);
|
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_elem_update(struct infobar *i);
|
||||||
void infobar_refresh(struct infobar *i);
|
void infobar_refresh(struct infobar *i);
|
||||||
void infobar_remove(struct infobar *i);
|
void infobar_remove(struct infobar *i);
|
||||||
void infobar_free(struct screen *s);
|
void infobar_free(struct screen *s);
|
||||||
void infobar_elem_reinit(struct infobar *i);
|
|
||||||
|
|
||||||
/* Basic placement of elements */
|
/* Basic placement of elements */
|
||||||
static inline void
|
static inline void
|
||||||
@ -63,13 +63,16 @@ infobar_placement(struct infobar *i, enum barpos p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
infobar_elem_screen_update(struct screen *s, int type)
|
infobar_elem_screen_update(struct screen *s, int addf)
|
||||||
{
|
{
|
||||||
struct infobar *i;
|
struct infobar *i;
|
||||||
|
|
||||||
SLIST_FOREACH(i, &s->infobars, next)
|
s->elemupdate |= FLAGINT(addf);
|
||||||
infobar_elem_update(i, type);
|
|
||||||
|
|
||||||
|
SLIST_FOREACH(i, &s->infobars, next)
|
||||||
|
infobar_elem_update(i);
|
||||||
|
|
||||||
|
s->elemupdate &= ~FLAGINT(addf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct infobar*
|
static inline struct infobar*
|
||||||
@ -88,6 +91,4 @@ infobar_gb_name(const char *name)
|
|||||||
return SLIST_FIRST(&s->infobars);
|
return SLIST_FIRST(&s->infobars);
|
||||||
}
|
}
|
||||||
|
|
||||||
void uicb_infobar_toggle_hide(Uicb iname);
|
|
||||||
|
|
||||||
#endif /* INFOBAR_H */
|
#endif /* INFOBAR_H */
|
||||||
|
|||||||
438
src/launcher.c
438
src/launcher.c
@ -1,438 +0,0 @@
|
|||||||
/*
|
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
|
||||||
* For license, see COPYING.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <X11/Xutil.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)
|
|
||||||
{
|
|
||||||
return (strcmp(*(char **)a, *(char **)b));
|
|
||||||
}
|
|
||||||
|
|
||||||
static char **
|
|
||||||
complete_on_command(char *start)
|
|
||||||
{
|
|
||||||
struct dirent *content;
|
|
||||||
DIR *dir;
|
|
||||||
char **paths, *path, *p, **namelist = NULL;
|
|
||||||
int i, count;
|
|
||||||
|
|
||||||
if(!(path = getenv("PATH")) || !start)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* split PATH into paths */
|
|
||||||
path = p = xstrdup(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 */
|
|
||||||
for(i = count = 0; paths[i]; ++i)
|
|
||||||
{
|
|
||||||
if(!(dir = opendir(paths[i])))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
while((content = readdir(dir)))
|
|
||||||
{
|
|
||||||
if(strncmp(content->d_name, ".", 1)
|
|
||||||
&& !strncmp(content->d_name, start, strlen(start)))
|
|
||||||
{
|
|
||||||
namelist = xrealloc(namelist, ++count, sizeof(*namelist));
|
|
||||||
namelist[count - 1] = xstrdup(content->d_name + strlen(start));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
closedir(dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(count)
|
|
||||||
{
|
|
||||||
qsort(namelist, count, sizeof(char *), qsort_string_compare);
|
|
||||||
namelist = xrealloc(namelist, ++count, sizeof(*namelist));
|
|
||||||
namelist[count - 1] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(paths);
|
|
||||||
free(path);
|
|
||||||
|
|
||||||
return namelist;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Complete a filename or directory name.
|
|
||||||
* works like complete_on_command.
|
|
||||||
*/
|
|
||||||
static char **
|
|
||||||
complete_on_files(char *start)
|
|
||||||
{
|
|
||||||
struct dirent *content = NULL;
|
|
||||||
struct stat st;
|
|
||||||
DIR *dir;
|
|
||||||
char *home, *path, *dirname = NULL;
|
|
||||||
char **namelist = NULL, *filepath, *p = start;
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Search the directory to open and set
|
|
||||||
* the beginning of file to complete on pointer 'p'.
|
|
||||||
*/
|
|
||||||
if(*p == '\0' || !strrchr(p, '/'))
|
|
||||||
path = xstrdup(".");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(!(home = getenv("HOME")))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* remplace ~ by $HOME in dirname */
|
|
||||||
if(!strncmp(p, "~/", 2) && home)
|
|
||||||
xasprintf(&dirname, "%s%s", home, p+1);
|
|
||||||
else
|
|
||||||
dirname = xstrdup(p);
|
|
||||||
|
|
||||||
/* Set p to filename to be complete
|
|
||||||
* and path the directory containing the file
|
|
||||||
* /foooooo/baaaaaar/somethinglikethis<tab>
|
|
||||||
* <---- path - ---><------- p ------>
|
|
||||||
*/
|
|
||||||
p = strrchr(dirname, '/');
|
|
||||||
if(p != dirname)
|
|
||||||
{
|
|
||||||
*(p++) = '\0';
|
|
||||||
path = xstrdup(dirname);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
path = xstrdup("/");
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if((dir = opendir(path)))
|
|
||||||
{
|
|
||||||
while((content = readdir(dir)))
|
|
||||||
{
|
|
||||||
if(!strcmp(content->d_name, ".")
|
|
||||||
|| !strcmp(content->d_name, "..")
|
|
||||||
|| strncmp(content->d_name, p, strlen(p)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* If it's a directory append '/' to the completion */
|
|
||||||
xasprintf(&filepath, "%s/%s", path, content->d_name);
|
|
||||||
|
|
||||||
if(filepath && stat(filepath, &st) != -1)
|
|
||||||
{
|
|
||||||
namelist = xrealloc(namelist, ++count, sizeof(*namelist));
|
|
||||||
|
|
||||||
if(S_ISDIR(st.st_mode))
|
|
||||||
xasprintf(&namelist[count - 1], "%s/", content->d_name + strlen(p));
|
|
||||||
else
|
|
||||||
namelist[count - 1] = xstrdup(content->d_name + strlen(p));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
warnl("%s", filepath);
|
|
||||||
|
|
||||||
free(filepath);
|
|
||||||
}
|
|
||||||
closedir(dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(count)
|
|
||||||
{
|
|
||||||
namelist = xrealloc(namelist, ++count, sizeof(*namelist));
|
|
||||||
namelist[count - 1] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(dirname);
|
|
||||||
free(path);
|
|
||||||
|
|
||||||
return namelist;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
complete_cache_free(struct launcher_ccache *cache)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* release memory */
|
|
||||||
free(cache->start);
|
|
||||||
|
|
||||||
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 *p, *data, *arg, *end, *cmd = xstrdup(l->command);
|
|
||||||
int i, pos = 0, histpos = 0;
|
|
||||||
void (*func)(Uicb);
|
|
||||||
XEvent ev;
|
|
||||||
KeySym ks;
|
|
||||||
|
|
||||||
W->flags |= WMFS_LAUNCHER;
|
|
||||||
|
|
||||||
/* Prepare elements */
|
|
||||||
xasprintf(&data, "%s ", l->prompt);
|
|
||||||
LAUNCHER_INIT_ELEM(l->width);
|
|
||||||
|
|
||||||
XGrabKeyboard(W->dpy, W->root, true, GrabModeAsync, GrabModeAsync, CurrentTime);
|
|
||||||
|
|
||||||
while(loop)
|
|
||||||
{
|
|
||||||
XNextEvent(W->dpy, &ev);
|
|
||||||
|
|
||||||
if(ev.type != KeyPress)
|
|
||||||
{
|
|
||||||
EVENT_HANDLE(&ev);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get pressed key */
|
|
||||||
XLookupString(&ev.xkey, tmp, sizeof(tmp), &ks, 0);
|
|
||||||
|
|
||||||
/* Check Ctrl-c / Ctrl-d */
|
|
||||||
if(ev.xkey.state & ControlMask)
|
|
||||||
{
|
|
||||||
switch(ks)
|
|
||||||
{
|
|
||||||
case XK_c:
|
|
||||||
case XK_d:
|
|
||||||
ks = XK_Escape;
|
|
||||||
break;
|
|
||||||
case XK_p:
|
|
||||||
ks = XK_Up;
|
|
||||||
break;
|
|
||||||
case XK_n:
|
|
||||||
ks = XK_Down;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if there is a keypad */
|
|
||||||
if(IsKeypadKey(ks) && ks == XK_KP_Enter)
|
|
||||||
ks = XK_Return;
|
|
||||||
|
|
||||||
/* Manage pressed keys */
|
|
||||||
switch(ks)
|
|
||||||
{
|
|
||||||
case XK_Up:
|
|
||||||
if(l->nhisto)
|
|
||||||
{
|
|
||||||
if(histpos >= (int)l->nhisto)
|
|
||||||
histpos = 0;
|
|
||||||
strncpy(buf, l->histo[l->nhisto - ++histpos], sizeof(buf));
|
|
||||||
pos = strlen(buf);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case XK_Down:
|
|
||||||
if(l->nhisto && histpos > 0 && histpos < (int)l->nhisto)
|
|
||||||
{
|
|
||||||
strncpy(buf, l->histo[l->nhisto - --histpos], sizeof(buf));
|
|
||||||
pos = strlen(buf);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case XK_Return:
|
|
||||||
/* Get function name only, if cmds are added in command */
|
|
||||||
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 */
|
|
||||||
if(l->nhisto + 1 > HISTOLEN)
|
|
||||||
{
|
|
||||||
for(i = l->nhisto - 1; i > 1; --i)
|
|
||||||
strncpy(l->histo[i], l->histo[i - 1], sizeof(l->histo[i]));
|
|
||||||
|
|
||||||
l->nhisto = 0;
|
|
||||||
}
|
|
||||||
/* Store in histo array */
|
|
||||||
strncpy(l->histo[l->nhisto++], buf, sizeof(buf));
|
|
||||||
|
|
||||||
loop = false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case XK_Escape:
|
|
||||||
loop = false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Completion */
|
|
||||||
case XK_Tab:
|
|
||||||
buf[pos] = '\0';
|
|
||||||
if(lastwastab)
|
|
||||||
++cache.hits;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cache.hits = 0;
|
|
||||||
strncpy(tmpbuf, buf, sizeof(tmpbuf));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pos && (end = complete(&cache, tmpbuf)))
|
|
||||||
{
|
|
||||||
strncpy(buf, tmpbuf, sizeof(buf));
|
|
||||||
strncat(buf, end, sizeof(buf));
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastwastab = true;
|
|
||||||
|
|
||||||
/* start a new round of tabbing */
|
|
||||||
if(!found)
|
|
||||||
cache.hits = 0;
|
|
||||||
|
|
||||||
pos = strlen(buf);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case XK_BackSpace:
|
|
||||||
lastwastab = false;
|
|
||||||
if(pos)
|
|
||||||
buf[--pos] = '\0';
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
lastwastab = false;
|
|
||||||
strncat(buf, tmp, sizeof(tmp));
|
|
||||||
++pos;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(data);
|
|
||||||
xasprintf(&data, "%s %s", l->prompt, buf);
|
|
||||||
|
|
||||||
/* Update EVERY launcher element of the screen */
|
|
||||||
SLIST_FOREACH(ib, &W->screen->infobars, next)
|
|
||||||
{
|
|
||||||
TAILQ_FOREACH(e, &ib->elements, next)
|
|
||||||
{
|
|
||||||
if(e->type != ElemLauncher)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
e->data = data;
|
|
||||||
e->func_update(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
XUngrabKeyboard(W->dpy, CurrentTime);
|
|
||||||
|
|
||||||
complete_cache_free(&cache);
|
|
||||||
free(cmd);
|
|
||||||
free(data);
|
|
||||||
|
|
||||||
/* 'Close' launcher elements */
|
|
||||||
W->flags ^= WMFS_LAUNCHER;
|
|
||||||
data = NULL;
|
|
||||||
LAUNCHER_INIT_ELEM(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
uicb_launcher(Uicb cmd)
|
|
||||||
{
|
|
||||||
struct launcher *l;
|
|
||||||
|
|
||||||
if(!cmd)
|
|
||||||
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 */
|
|
||||||
139
src/layout.c
139
src/layout.c
@ -4,7 +4,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
#include <X11/XKBlib.h>
|
|
||||||
|
|
||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@ -13,9 +12,6 @@
|
|||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
/* Shift in client split to keep clients's parent at close arrange */
|
|
||||||
static int shiftv = 1, shifth = 1;
|
|
||||||
|
|
||||||
void
|
void
|
||||||
layout_save_set(struct tag *t)
|
layout_save_set(struct tag *t)
|
||||||
{
|
{
|
||||||
@ -27,7 +23,7 @@ layout_save_set(struct tag *t)
|
|||||||
l = xcalloc(1, sizeof(struct layout_set));
|
l = xcalloc(1, sizeof(struct layout_set));
|
||||||
SLIST_INIT(&l->geos);
|
SLIST_INIT(&l->geos);
|
||||||
|
|
||||||
FOREACH_NFCLIENT(c, &t->clients, tnext)
|
SLIST_FOREACH(c, &t->clients, tnext)
|
||||||
{
|
{
|
||||||
g = xcalloc(1, sizeof(struct geo_list));
|
g = xcalloc(1, sizeof(struct geo_list));
|
||||||
g->geo = c->geo;
|
g->geo = c->geo;
|
||||||
@ -53,7 +49,7 @@ layout_apply_set(struct tag *t, struct layout_set *l)
|
|||||||
struct client *c;
|
struct client *c;
|
||||||
int nc = 1;
|
int nc = 1;
|
||||||
|
|
||||||
FOREACH_NFCLIENT(c, &t->clients, tnext)
|
SLIST_FOREACH(c, &t->clients, tnext)
|
||||||
++nc;
|
++nc;
|
||||||
|
|
||||||
/* TODO: Adapt different client number case */
|
/* TODO: Adapt different client number case */
|
||||||
@ -99,9 +95,8 @@ layout_free_set(struct tag *t)
|
|||||||
{
|
{
|
||||||
struct layout_set *l;
|
struct layout_set *l;
|
||||||
|
|
||||||
while(!TAILQ_EMPTY(&t->sets))
|
TAILQ_FOREACH(l, &t->sets, next)
|
||||||
{
|
{
|
||||||
l = TAILQ_FIRST(&t->sets);
|
|
||||||
TAILQ_REMOVE(&t->sets, l, next);
|
TAILQ_REMOVE(&t->sets, l, next);
|
||||||
FREE_LIST(geo_list, l->geos);
|
FREE_LIST(geo_list, l->geos);
|
||||||
free(l);
|
free(l);
|
||||||
@ -153,7 +148,7 @@ _historic_set(struct tag *t, bool prev)
|
|||||||
if(ev.type == KeyPress)
|
if(ev.type == KeyPress)
|
||||||
{
|
{
|
||||||
XKeyPressedEvent *ke = &ev.xkey;
|
XKeyPressedEvent *ke = &ev.xkey;
|
||||||
keysym = XkbKeycodeToKeysym(W->dpy, (KeyCode)ke->keycode, 0, 0);
|
keysym = XKeycodeToKeysym(W->dpy, (KeyCode)ke->keycode, 0);
|
||||||
|
|
||||||
_REV_BORDER();
|
_REV_BORDER();
|
||||||
|
|
||||||
@ -233,26 +228,20 @@ layout_split(struct client *c, bool vertical)
|
|||||||
if(vertical)
|
if(vertical)
|
||||||
{
|
{
|
||||||
c->geo.w >>= 1;
|
c->geo.w >>= 1;
|
||||||
c->geo.w += shiftv;
|
|
||||||
geo.x = c->geo.x + c->geo.w;
|
geo.x = c->geo.x + c->geo.w;
|
||||||
geo.w >>= 1;
|
geo.w >>= 1;
|
||||||
|
|
||||||
/* Remainder */
|
/* Remainder */
|
||||||
geo.w += (og.x + og.w) - (geo.x + geo.w);
|
geo.w += (og.x + og.w) - (geo.x + geo.w);
|
||||||
|
|
||||||
shiftv = -shiftv;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
c->geo.h >>= 1;
|
c->geo.h >>= 1;
|
||||||
c->geo.h += shifth;
|
|
||||||
geo.y = c->geo.y + c->geo.h;
|
geo.y = c->geo.y + c->geo.h;
|
||||||
geo.h >>= 1;
|
geo.h >>= 1;
|
||||||
|
|
||||||
/* Remainder */
|
/* Remainder */
|
||||||
geo.h += (og.y + og.h) - (geo.y + geo.h);
|
geo.h += (og.y + og.h) - (geo.y + geo.h);
|
||||||
|
|
||||||
shifth = -shifth;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return geo;
|
return geo;
|
||||||
@ -286,7 +275,7 @@ layout_split_check_row_dir(struct client *c, struct client *g, enum position p)
|
|||||||
struct client *cc;
|
struct client *cc;
|
||||||
int s = 0, cs = (LDIR(p) ? g->geo.h : g->geo.w);
|
int s = 0, cs = (LDIR(p) ? g->geo.h : g->geo.w);
|
||||||
|
|
||||||
FOREACH_NFCLIENT(cc, &c->tag->clients, tnext)
|
SLIST_FOREACH(cc, &c->tag->clients, tnext)
|
||||||
if(GEO_PARENTROW(cgeo, cc->geo, RPOS(p))
|
if(GEO_PARENTROW(cgeo, cc->geo, RPOS(p))
|
||||||
&& GEO_CHECK_ROW(cc->geo, g->geo, p))
|
&& GEO_CHECK_ROW(cc->geo, g->geo, p))
|
||||||
{
|
{
|
||||||
@ -330,8 +319,6 @@ layout_split_arrange_closed(struct client *ghost)
|
|||||||
bool b = false;
|
bool b = false;
|
||||||
enum position p;
|
enum position p;
|
||||||
|
|
||||||
if(!(ghost->flags & CLIENT_TILED))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Search for single parent for easy resize
|
/* Search for single parent for easy resize
|
||||||
* Example case:
|
* Example case:
|
||||||
@ -360,7 +347,7 @@ layout_split_arrange_closed(struct client *ghost)
|
|||||||
&& layout_split_check_row_dir(c, ghost, p))
|
&& layout_split_check_row_dir(c, ghost, p))
|
||||||
{
|
{
|
||||||
g = c->geo;
|
g = c->geo;
|
||||||
FOREACH_NFCLIENT(cc, &c->tag->clients, tnext)
|
SLIST_FOREACH(cc, &c->tag->clients, tnext)
|
||||||
if(GEO_PARENTROW(g, cc->geo, RPOS(p))
|
if(GEO_PARENTROW(g, cc->geo, RPOS(p))
|
||||||
&& GEO_CHECK_ROW(cc->geo, ghost->geo, p))
|
&& GEO_CHECK_ROW(cc->geo, ghost->geo, p))
|
||||||
{
|
{
|
||||||
@ -373,64 +360,26 @@ layout_split_arrange_closed(struct client *ghost)
|
|||||||
layout_save_set(ghost->tag);
|
layout_save_set(ghost->tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Integrate a client in split layout: split sc and fill c in new geo */
|
||||||
* Integrate a client in split layout:
|
|
||||||
* - Check if there is no sc
|
|
||||||
* - Check if sc is on a different tag than c
|
|
||||||
* - Check if sc is not in free mode
|
|
||||||
*
|
|
||||||
* So from there, sc is not compatible, so we will integrate
|
|
||||||
* c in the larger tiled client of c tag:
|
|
||||||
* - Check if the larger client is correct
|
|
||||||
*
|
|
||||||
* Checks all failed? Get first tiled client of the tag to integrate in.
|
|
||||||
* Still no client, it means that c is the first tiled client of the tag, then maximize it.
|
|
||||||
*/
|
|
||||||
void
|
void
|
||||||
layout_split_integrate(struct client *c, struct client *sc)
|
layout_split_integrate(struct client *c, struct client *sc)
|
||||||
{
|
{
|
||||||
struct geo g;
|
struct geo g;
|
||||||
bool f = false;
|
|
||||||
|
|
||||||
/* No sc or not compatible, get the largest of the tag */
|
/* No sc */
|
||||||
if(!sc
|
if(!sc || sc == c || sc->tag != c->tag)
|
||||||
|| sc == c
|
|
||||||
|| sc->tag != c->tag
|
|
||||||
|| (sc->flags & CLIENT_FREE)
|
|
||||||
|| !COMPCLIENT(c, sc))
|
|
||||||
sc = client_get_larger(c->tag, c->flags & CLIENT_IGNORE_TAG);
|
|
||||||
|
|
||||||
/* Largest not correct */
|
|
||||||
if(!sc || sc == c)
|
|
||||||
{
|
{
|
||||||
FOREACH_NFCLIENT(sc, &c->tag->clients, tnext)
|
/*
|
||||||
if(sc != c && !(sc->flags & CLIENT_TABBED))
|
* Not even a first client in list, then
|
||||||
{
|
* maximize the lonely client
|
||||||
f = true;
|
*/
|
||||||
break;
|
if(!(sc = SLIST_NEXT(SLIST_FIRST(&c->tag->clients), tnext)))
|
||||||
}
|
|
||||||
|
|
||||||
/* Ok there is no client to integrate in */
|
|
||||||
if(!f)
|
|
||||||
{
|
{
|
||||||
client_maximize(c);
|
client_maximize(c);
|
||||||
c->flags |= CLIENT_TILED;
|
|
||||||
W->flags &= ~WMFS_TABNOC;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tab Next Opened Client option */
|
|
||||||
if(W->flags & WMFS_TABNOC && COMPCLIENT(c, sc))
|
|
||||||
{
|
|
||||||
W->flags ^= WMFS_TABNOC;
|
|
||||||
_client_tab(c, sc);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If there are clients but we can tab with them, split the screen. */
|
|
||||||
c->flags |= CLIENT_TILED;
|
|
||||||
|
|
||||||
g = layout_split(sc, (sc->geo.h < sc->geo.w));
|
g = layout_split(sc, (sc->geo.h < sc->geo.w));
|
||||||
|
|
||||||
client_moveresize(c, &g);
|
client_moveresize(c, &g);
|
||||||
@ -440,7 +389,6 @@ layout_split_integrate(struct client *c, struct client *sc)
|
|||||||
client_fac_hint(sc);
|
client_fac_hint(sc);
|
||||||
|
|
||||||
layout_save_set(c->tag);
|
layout_save_set(c->tag);
|
||||||
W->flags &= ~WMFS_TABNOC;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Arrange inter-clients holes:
|
/* Arrange inter-clients holes:
|
||||||
@ -459,7 +407,7 @@ layout_split_integrate(struct client *c, struct client *sc)
|
|||||||
* |_____|----'| -> |_____|__v__|
|
* |_____|----'| -> |_____|__v__|
|
||||||
* ^^^ void
|
* ^^^ void
|
||||||
*/
|
*/
|
||||||
void
|
inline void
|
||||||
layout_fix_hole(struct client *c)
|
layout_fix_hole(struct client *c)
|
||||||
{
|
{
|
||||||
struct client *cr = client_next_with_pos(c, Right);
|
struct client *cr = client_next_with_pos(c, Right);
|
||||||
@ -512,7 +460,7 @@ layout_rotate(struct tag *t, void (*pfunc)(struct geo*, struct geo*, struct geo*
|
|||||||
float f1 = (float)t->screen->ugeo.w / (float)t->screen->ugeo.h;
|
float f1 = (float)t->screen->ugeo.w / (float)t->screen->ugeo.h;
|
||||||
float f2 = 1 / f1;
|
float f2 = 1 / f1;
|
||||||
|
|
||||||
FOREACH_NFCLIENT(c, &t->clients, tnext)
|
SLIST_FOREACH(c, &t->clients, tnext)
|
||||||
{
|
{
|
||||||
pfunc(&g, ug, &c->geo);
|
pfunc(&g, ug, &c->geo);
|
||||||
|
|
||||||
@ -526,7 +474,7 @@ layout_rotate(struct tag *t, void (*pfunc)(struct geo*, struct geo*, struct geo*
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Rotate sometimes do not set back perfect size.. */
|
/* Rotate sometimes do not set back perfect size.. */
|
||||||
FOREACH_NFCLIENT(c, &t->clients, tnext)
|
SLIST_FOREACH(c, &t->clients, tnext)
|
||||||
layout_fix_hole(c);
|
layout_fix_hole(c);
|
||||||
|
|
||||||
layout_save_set(t);
|
layout_save_set(t);
|
||||||
@ -570,7 +518,7 @@ uicb_layout_vmirror(Uicb cmd)
|
|||||||
(void)cmd;
|
(void)cmd;
|
||||||
struct client *c;
|
struct client *c;
|
||||||
|
|
||||||
FOREACH_NFCLIENT(c, &W->screen->seltag->clients, tnext)
|
SLIST_FOREACH(c, &W->screen->seltag->clients, tnext)
|
||||||
{
|
{
|
||||||
c->geo.x = W->screen->ugeo.w - (c->geo.x + c->geo.w);
|
c->geo.x = W->screen->ugeo.w - (c->geo.x + c->geo.w);
|
||||||
client_moveresize(c, &c->geo);
|
client_moveresize(c, &c->geo);
|
||||||
@ -585,7 +533,7 @@ uicb_layout_hmirror(Uicb cmd)
|
|||||||
(void)cmd;
|
(void)cmd;
|
||||||
struct client *c;
|
struct client *c;
|
||||||
|
|
||||||
FOREACH_NFCLIENT(c, &W->screen->seltag->clients, tnext)
|
SLIST_FOREACH(c, &W->screen->seltag->clients, tnext)
|
||||||
{
|
{
|
||||||
c->geo.y = W->screen->ugeo.h - (c->geo.y + c->geo.h);
|
c->geo.y = W->screen->ugeo.h - (c->geo.y + c->geo.h);
|
||||||
client_moveresize(c, &c->geo);
|
client_moveresize(c, &c->geo);
|
||||||
@ -593,52 +541,3 @@ uicb_layout_hmirror(Uicb cmd)
|
|||||||
|
|
||||||
layout_save_set(W->screen->seltag);
|
layout_save_set(W->screen->seltag);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LAYOUT_INTEGRATE_DIR(D) \
|
|
||||||
void uicb_layout_integrate_##D(Uicb cmd) \
|
|
||||||
{ \
|
|
||||||
(void)cmd; \
|
|
||||||
if(W->client) \
|
|
||||||
layout_integrate(W->client, D); \
|
|
||||||
}
|
|
||||||
static void
|
|
||||||
layout_integrate(struct client *c, enum position p)
|
|
||||||
{
|
|
||||||
struct client *n;
|
|
||||||
struct client ghost = *c;
|
|
||||||
|
|
||||||
if(!(c->flags & CLIENT_TILED))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if((n = client_next_with_pos(c, p))
|
|
||||||
&& (n->flags & CLIENT_TILED))
|
|
||||||
{
|
|
||||||
layout_split_integrate(c, n);
|
|
||||||
layout_split_arrange_closed(&ghost);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LAYOUT_INTEGRATE_DIR(Left);
|
|
||||||
LAYOUT_INTEGRATE_DIR(Right);
|
|
||||||
LAYOUT_INTEGRATE_DIR(Top);
|
|
||||||
LAYOUT_INTEGRATE_DIR(Bottom);
|
|
||||||
|
|
||||||
void
|
|
||||||
layout_client(struct client *c)
|
|
||||||
{
|
|
||||||
if(c->flags & (CLIENT_IGNORE_LAYOUT | CLIENT_FULLSCREEN))
|
|
||||||
{
|
|
||||||
c->flags &= ~CLIENT_IGNORE_LAYOUT;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(c->flags & CLIENT_FREE)
|
|
||||||
{
|
|
||||||
layout_split_arrange_closed(c);
|
|
||||||
c->flags ^= CLIENT_TILED;
|
|
||||||
client_moveresize(c, &c->geo);
|
|
||||||
XRaiseWindow(W->dpy, c->frame);
|
|
||||||
}
|
|
||||||
else if(!(c->flags & CLIENT_TABBED))
|
|
||||||
layout_split_integrate(c, c->tag->sel);
|
|
||||||
}
|
|
||||||
|
|||||||
11
src/layout.h
11
src/layout.h
@ -7,7 +7,6 @@
|
|||||||
#define LAYOUT_H
|
#define LAYOUT_H
|
||||||
|
|
||||||
#include "wmfs.h"
|
#include "wmfs.h"
|
||||||
#include "client.h"
|
|
||||||
|
|
||||||
/* Check lateral direction (if p is Right or Left) */
|
/* Check lateral direction (if p is Right or Left) */
|
||||||
#define LDIR(P) (P < Top)
|
#define LDIR(P) (P < Top)
|
||||||
@ -34,8 +33,7 @@ void layout_save_set(struct tag *t);
|
|||||||
void layout_free_set(struct tag *t);
|
void layout_free_set(struct tag *t);
|
||||||
void layout_split_integrate(struct client *c, struct client *sc);
|
void layout_split_integrate(struct client *c, struct client *sc);
|
||||||
void layout_split_arrange_closed(struct client *ghost);
|
void layout_split_arrange_closed(struct client *ghost);
|
||||||
void layout_fix_hole(struct client *c);
|
inline void layout_fix_hole(struct client *c);
|
||||||
void layout_client(struct client *c);
|
|
||||||
void uicb_layout_vmirror(Uicb cmd);
|
void uicb_layout_vmirror(Uicb cmd);
|
||||||
void uicb_layout_hmirror(Uicb cmd);
|
void uicb_layout_hmirror(Uicb cmd);
|
||||||
void uicb_layout_rotate_left(Uicb cmd);
|
void uicb_layout_rotate_left(Uicb cmd);
|
||||||
@ -43,12 +41,5 @@ void uicb_layout_rotate_right(Uicb cmd);
|
|||||||
void uicb_layout_prev_set(Uicb cmd);
|
void uicb_layout_prev_set(Uicb cmd);
|
||||||
void uicb_layout_next_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 */
|
#endif /* LAYOUT_H */
|
||||||
|
|
||||||
|
|||||||
148
src/mouse.c
148
src/mouse.c
@ -9,14 +9,11 @@
|
|||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "draw.h"
|
#include "draw.h"
|
||||||
|
|
||||||
#define _REV_SBORDER(c) draw_reversed_rect(W->root, c, false);
|
#define _REV_BORDER() \
|
||||||
|
do { \
|
||||||
#define _REV_BORDER() \
|
SLIST_FOREACH(gc, &c->tag->clients, tnext) \
|
||||||
do { \
|
draw_reversed_rect(W->root, gc, true); \
|
||||||
FOREACH_NFCLIENT(gc, &c->tag->clients, tnext) \
|
|
||||||
draw_reversed_rect(W->root, gc, true); \
|
|
||||||
} while(/* CONSTCOND */ 0);
|
} while(/* CONSTCOND */ 0);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mouse_resize(struct client *c)
|
mouse_resize(struct client *c)
|
||||||
{
|
{
|
||||||
@ -24,17 +21,11 @@ mouse_resize(struct client *c)
|
|||||||
XEvent ev;
|
XEvent ev;
|
||||||
Window w;
|
Window w;
|
||||||
int d, u, ox, oy, ix, iy;
|
int d, u, ox, oy, ix, iy;
|
||||||
int mx, my;
|
|
||||||
|
|
||||||
XQueryPointer(W->dpy, W->root, &w, &w, &ox, &oy, &d, &d, (unsigned int *)&u);
|
XQueryPointer(W->dpy, W->root, &w, &w, &ox, &oy, &d, &d, (uint *)&u);
|
||||||
XGrabServer(W->dpy);
|
XGrabServer(W->dpy);
|
||||||
|
|
||||||
if(c->flags & CLIENT_FREE)
|
_REV_BORDER();
|
||||||
{
|
|
||||||
_REV_SBORDER(c);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
_REV_BORDER();
|
|
||||||
|
|
||||||
if(c->flags & CLIENT_TABBED && !(c->flags & CLIENT_TABMASTER))
|
if(c->flags & CLIENT_TABBED && !(c->flags & CLIENT_TABMASTER))
|
||||||
c = c->tabmaster;
|
c = c->tabmaster;
|
||||||
@ -42,8 +33,6 @@ mouse_resize(struct client *c)
|
|||||||
ix = ox;
|
ix = ox;
|
||||||
iy = oy;
|
iy = oy;
|
||||||
|
|
||||||
c->flags |= CLIENT_MOUSE;
|
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
XMaskEvent(W->dpy, MouseMask | SubstructureRedirectMask, &ev);
|
XMaskEvent(W->dpy, MouseMask | SubstructureRedirectMask, &ev);
|
||||||
@ -51,68 +40,31 @@ mouse_resize(struct client *c)
|
|||||||
if(ev.type != MotionNotify)
|
if(ev.type != MotionNotify)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
mx = ev.xmotion.x_root;
|
_REV_BORDER();
|
||||||
my = ev.xmotion.y_root;
|
|
||||||
|
|
||||||
if(c->flags & CLIENT_FREE)
|
if(ix >= c->geo.x + (c->geo.w >> 1))
|
||||||
{
|
_fac_resize(c, Right, ev.xmotion.x_root - ox);
|
||||||
_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
|
else
|
||||||
{
|
_fac_resize(c, Left, ox - ev.xmotion.x_root);
|
||||||
_REV_BORDER();
|
|
||||||
|
|
||||||
if(ix >= c->rgeo.x + (c->geo.w >> 1))
|
if(iy >= c->geo.y + (c->geo.h >> 1))
|
||||||
_fac_resize(c, Right, mx - ox);
|
_fac_resize(c, Bottom, ev.xmotion.y_root - oy);
|
||||||
else
|
else
|
||||||
_fac_resize(c, Left, ox - mx);
|
_fac_resize(c, Top, oy - ev.xmotion.y_root);
|
||||||
|
|
||||||
if(iy >= c->rgeo.y + (c->geo.h >> 1))
|
ox = ev.xmotion.x_root;
|
||||||
_fac_resize(c, Bottom, my - oy);
|
oy = ev.xmotion.y_root;
|
||||||
else
|
|
||||||
_fac_resize(c, Top, oy - my);
|
|
||||||
|
|
||||||
ox = mx;
|
_REV_BORDER();
|
||||||
oy = my;
|
|
||||||
|
|
||||||
_REV_BORDER();
|
|
||||||
}
|
|
||||||
|
|
||||||
XSync(W->dpy, false);
|
XSync(W->dpy, false);
|
||||||
|
|
||||||
} while(ev.type != ButtonRelease);
|
} while(ev.type != ButtonRelease);
|
||||||
|
|
||||||
if(c->flags & CLIENT_FREE)
|
_REV_BORDER();
|
||||||
{
|
|
||||||
_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;
|
client_apply_tgeo(c->tag);
|
||||||
|
layout_save_set(c->tag);
|
||||||
|
|
||||||
XUngrabServer(W->dpy);
|
XUngrabServer(W->dpy);
|
||||||
}
|
}
|
||||||
@ -136,6 +88,7 @@ mouse_drag_tag(struct client *c, Window w)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define _REV_SBORDER(c) draw_reversed_rect(W->root, c, false);
|
||||||
void
|
void
|
||||||
mouse_move(struct client *c, void (*func)(struct client*, struct client*))
|
mouse_move(struct client *c, void (*func)(struct client*, struct client*))
|
||||||
{
|
{
|
||||||
@ -143,21 +96,13 @@ mouse_move(struct client *c, void (*func)(struct client*, struct client*))
|
|||||||
struct tag *t = NULL;
|
struct tag *t = NULL;
|
||||||
XEvent ev;
|
XEvent ev;
|
||||||
Window w;
|
Window w;
|
||||||
int d, u, ox, oy;
|
int d, u;
|
||||||
int ocx, ocy;
|
|
||||||
|
|
||||||
ocx = c->geo.x;
|
|
||||||
ocy = c->geo.y;
|
|
||||||
|
|
||||||
if(c->flags & CLIENT_TABBED && !(c->flags & CLIENT_TABMASTER))
|
if(c->flags & CLIENT_TABBED && !(c->flags & CLIENT_TABMASTER))
|
||||||
c = c->tabmaster;
|
c = c->tabmaster;
|
||||||
|
|
||||||
XQueryPointer(W->dpy, W->root, &w, &w, &ox, &oy, &d, &d, (uint *)&u);
|
|
||||||
|
|
||||||
_REV_SBORDER(c);
|
_REV_SBORDER(c);
|
||||||
|
|
||||||
c->flags |= CLIENT_MOUSE;
|
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
XMaskEvent(W->dpy, MouseMask | SubstructureRedirectMask, &ev);
|
XMaskEvent(W->dpy, MouseMask | SubstructureRedirectMask, &ev);
|
||||||
@ -165,33 +110,23 @@ mouse_move(struct client *c, void (*func)(struct client*, struct client*))
|
|||||||
if(ev.type != MotionNotify)
|
if(ev.type != MotionNotify)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(!func && c->flags & CLIENT_FREE)
|
XQueryPointer(W->dpy, W->root, &w, &w, &d, &d, &d, &d, (uint *)&u);
|
||||||
|
|
||||||
|
if(!(c2 = client_gb_win(w)))
|
||||||
|
if(!(c2 = client_gb_frame(w)))
|
||||||
|
c2 = client_gb_titlebar(w);
|
||||||
|
|
||||||
|
if(c2)
|
||||||
{
|
{
|
||||||
_REV_SBORDER(c);
|
if(c2 != last)
|
||||||
|
{
|
||||||
c->geo.x = (ocx + (ev.xmotion.x_root - ox));
|
_REV_SBORDER(last);
|
||||||
c->geo.y = (ocy + (ev.xmotion.y_root - oy));
|
_REV_SBORDER(c2);
|
||||||
|
last = c2;
|
||||||
_REV_SBORDER(c);
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
t = mouse_drag_tag(c, w);
|
||||||
c2 = NULL;
|
|
||||||
|
|
||||||
XQueryPointer(W->dpy, W->root, &w, &w, &d, &d, &d, &d, (uint *)&u);
|
|
||||||
|
|
||||||
if((c2 = client_gb_win(w)) || (c2 = client_gb_frame(w)) || (c2 = client_gb_titlebar(w)))
|
|
||||||
{
|
|
||||||
if(c2 != last)
|
|
||||||
{
|
|
||||||
_REV_SBORDER(last);
|
|
||||||
_REV_SBORDER(c2);
|
|
||||||
last = c2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
t = mouse_drag_tag(c, w);
|
|
||||||
}
|
|
||||||
|
|
||||||
XSync(W->dpy, false);
|
XSync(W->dpy, false);
|
||||||
|
|
||||||
@ -202,15 +137,7 @@ mouse_move(struct client *c, void (*func)(struct client*, struct client*))
|
|||||||
else if(t && t != (struct tag*)c)
|
else if(t && t != (struct tag*)c)
|
||||||
tag_client(t, c);
|
tag_client(t, c);
|
||||||
else
|
else
|
||||||
{
|
|
||||||
_REV_SBORDER(c);
|
_REV_SBORDER(c);
|
||||||
|
|
||||||
/* No func mean free client resize */
|
|
||||||
if(!func)
|
|
||||||
client_moveresize(c, &c->geo);
|
|
||||||
}
|
|
||||||
|
|
||||||
c->flags &= ~CLIENT_MOUSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -228,7 +155,7 @@ uicb_mouse_move(Uicb cmd)
|
|||||||
(void)cmd;
|
(void)cmd;
|
||||||
|
|
||||||
if(W->client && mouse_check_client(W->client))
|
if(W->client && mouse_check_client(W->client))
|
||||||
mouse_move(W->client, (W->client->flags & CLIENT_FREE ? NULL : client_swap2));
|
mouse_move(W->client, client_swap2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -238,5 +165,4 @@ uicb_mouse_tab(Uicb cmd)
|
|||||||
|
|
||||||
if(W->client && mouse_check_client(W->client))
|
if(W->client && mouse_check_client(W->client))
|
||||||
mouse_move(W->client, _client_tab);
|
mouse_move(W->client, _client_tab);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,7 +42,7 @@ string_to_opt(char *s)
|
|||||||
ret.fnum = strtod(s, NULL);
|
ret.fnum = strtod(s, NULL);
|
||||||
|
|
||||||
ret.boolean = (!strcmp(s, "true")
|
ret.boolean = (!strcmp(s, "true")
|
||||||
|| !strcmp(s, "True")
|
|| !strcmp(s, "true")
|
||||||
|| !strcmp(s, "TRUE")
|
|| !strcmp(s, "TRUE")
|
||||||
|| !strcmp(s, "1"));
|
|| !strcmp(s, "1"));
|
||||||
|
|
||||||
|
|||||||
43
src/screen.c
43
src/screen.c
@ -21,7 +21,6 @@ screen_new(struct geo *g, int id)
|
|||||||
s->geo = s->ugeo = *g;
|
s->geo = s->ugeo = *g;
|
||||||
s->seltag = NULL;
|
s->seltag = NULL;
|
||||||
s->id = id;
|
s->id = id;
|
||||||
s->flags = 0;
|
|
||||||
|
|
||||||
TAILQ_INIT(&s->tags);
|
TAILQ_INIT(&s->tags);
|
||||||
SLIST_INIT(&s->infobars);
|
SLIST_INIT(&s->infobars);
|
||||||
@ -102,10 +101,10 @@ screen_select(struct screen *s)
|
|||||||
void
|
void
|
||||||
uicb_screen_next(Uicb cmd)
|
uicb_screen_next(Uicb cmd)
|
||||||
{
|
{
|
||||||
struct screen *s = SLIST_NEXT(W->screen, next);
|
struct screen *s;
|
||||||
(void)cmd;
|
(void)cmd;
|
||||||
|
|
||||||
if(!s)
|
if(!(s = SLIST_NEXT(W->screen, next)))
|
||||||
s = SLIST_FIRST(&W->h.screen);
|
s = SLIST_FIRST(&W->h.screen);
|
||||||
|
|
||||||
screen_select(s);
|
screen_select(s);
|
||||||
@ -114,39 +113,51 @@ uicb_screen_next(Uicb cmd)
|
|||||||
void
|
void
|
||||||
uicb_screen_prev(Uicb cmd)
|
uicb_screen_prev(Uicb cmd)
|
||||||
{
|
{
|
||||||
struct screen *s = SLIST_FIRST(&W->h.screen);
|
struct screen *s;
|
||||||
(void)cmd;
|
(void)cmd;
|
||||||
|
|
||||||
while(SLIST_NEXT(s, next) && SLIST_NEXT(s, next) != s)
|
SLIST_FOREACH(s, &W->h.screen, next)
|
||||||
s = SLIST_NEXT(s, next);
|
if(SLIST_NEXT(W->screen, next) == s)
|
||||||
|
{
|
||||||
|
screen_select(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
screen_select(s);
|
screen_select(SLIST_FIRST(&W->h.screen));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
screen_move_client(struct client *c, struct screen *s)
|
||||||
|
{
|
||||||
|
tag_client(s->seltag, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uicb_screen_move_client_next(Uicb cmd)
|
uicb_screen_move_client_next(Uicb cmd)
|
||||||
{
|
{
|
||||||
struct screen *s = SLIST_NEXT(W->screen, next);
|
struct screen *s;
|
||||||
(void)cmd;
|
(void)cmd;
|
||||||
|
|
||||||
if(!s)
|
if(!(s = SLIST_NEXT(W->screen, next)))
|
||||||
s = SLIST_FIRST(&W->h.screen);
|
s = SLIST_FIRST(&W->h.screen);
|
||||||
|
|
||||||
if(W->client)
|
screen_move_client(W->client, s);
|
||||||
tag_client(s->seltag, W->client);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uicb_screen_move_client_prev(Uicb cmd)
|
uicb_screen_move_client_prev(Uicb cmd)
|
||||||
{
|
{
|
||||||
struct screen *s = SLIST_FIRST(&W->h.screen);
|
struct screen *s;
|
||||||
(void)cmd;
|
(void)cmd;
|
||||||
|
|
||||||
while(SLIST_NEXT(s, next) && SLIST_NEXT(s, next) != s)
|
SLIST_FOREACH(s, &W->h.screen, next)
|
||||||
s = SLIST_NEXT(s, next);
|
if(SLIST_NEXT(W->screen, next) == s)
|
||||||
|
{
|
||||||
|
screen_move_client(W->client, s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(W->client)
|
screen_move_client(W->client, SLIST_FIRST(&W->h.screen));
|
||||||
tag_client(s->seltag, W->client);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
22
src/screen.h
22
src/screen.h
@ -21,27 +21,23 @@ screen_gb_id(int id)
|
|||||||
return SLIST_FIRST(&W->h.screen);
|
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*
|
static inline struct screen*
|
||||||
screen_gb_mouse(void)
|
screen_gb_mouse(void)
|
||||||
{
|
{
|
||||||
|
struct screen *s;
|
||||||
Window w;
|
Window w;
|
||||||
int d, x, y;
|
int d, x, y;
|
||||||
|
|
||||||
XQueryPointer(W->dpy, W->root, &w, &w, &x, &y, &d, &d, (unsigned int *)&d);
|
XQueryPointer(W->dpy, W->root, &w, &w, &x, &y, &d, &d, (unsigned int *)&d);
|
||||||
|
|
||||||
return screen_gb_geo(x, y);
|
SLIST_FOREACH(s, &W->h.screen, next)
|
||||||
|
if(INAREA(x, y, s->geo))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(!s)
|
||||||
|
s = SLIST_FIRST(&W->h.screen);
|
||||||
|
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void screen_init(void);
|
void screen_init(void);
|
||||||
|
|||||||
523
src/status.c
523
src/status.c
@ -8,11 +8,10 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "infobar.h"
|
#include "infobar.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "draw.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
struct status_seq*
|
static struct status_seq*
|
||||||
status_new_seq(char type, int narg, int minarg, char *args[], int *shift)
|
status_new_seq(char type, int narg, int minarg, char *args[], int *shift)
|
||||||
{
|
{
|
||||||
struct status_seq *sq = xcalloc(1, sizeof(struct status_seq));
|
struct status_seq *sq = xcalloc(1, sizeof(struct status_seq));
|
||||||
@ -34,124 +33,17 @@ status_new_seq(char type, int narg, int minarg, char *args[], int *shift)
|
|||||||
return sq;
|
return sq;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct status_ctx
|
|
||||||
status_new_ctx(struct barwin *b, struct theme *t)
|
|
||||||
{
|
|
||||||
struct status_ctx ctx = { .barwin = b, .theme = t };
|
|
||||||
|
|
||||||
SLIST_INIT(&ctx.statushead);
|
|
||||||
SLIST_INIT(&ctx.gcache);
|
|
||||||
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
status_gcache_free(struct status_ctx *ctx)
|
|
||||||
{
|
|
||||||
struct status_gcache *gc;
|
|
||||||
|
|
||||||
while(!SLIST_EMPTY(&ctx->gcache))
|
|
||||||
{
|
|
||||||
gc = SLIST_FIRST(&ctx->gcache);
|
|
||||||
SLIST_REMOVE_HEAD(&ctx->gcache, next);
|
|
||||||
free(gc->datas);
|
|
||||||
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
|
|
||||||
max = sq->data[2];
|
|
||||||
|
|
||||||
XSetForeground(W->dpy, W->gc, sq->color2);
|
|
||||||
|
|
||||||
for(i = sq->geo.x + sq->geo.w - 1, j = gc->ndata - 1;
|
|
||||||
j >= 0 && i >= sq->geo.x;
|
|
||||||
--j, --i)
|
|
||||||
{
|
|
||||||
/* You divided by zero didn't you? */
|
|
||||||
if(gc->datas[j])
|
|
||||||
{
|
|
||||||
c = (float)max / (float)gc->datas[j];
|
|
||||||
y = ys - (sq->geo.h / (c > 1 ? c : 1)) + 1;
|
|
||||||
draw_line(ctx->barwin->dr, i, y, i, ys);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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) */
|
/* Parse mousebind sequence next normal sequence: \<seq>[](button;func;cmd) */
|
||||||
static char*
|
static char*
|
||||||
status_parse_mouse(struct status_seq *sq, char *str)
|
status_parse_mouse(struct status_seq *sq, struct element *e, char *str)
|
||||||
{
|
{
|
||||||
struct mousebind *m;
|
struct mousebind *m;
|
||||||
|
struct barwin *b = SLIST_FIRST(&e->bars);
|
||||||
char *end, *arg[3] = { NULL };
|
char *end, *arg[3] = { NULL };
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if(*str != '(' || !(end = strchr(str, ')')))
|
if(*str != '(' || !(end = strchr(str, ')')))
|
||||||
return str;
|
return str + 1;
|
||||||
|
|
||||||
i = parse_args(++str, ';', ')', 3, arg);
|
i = parse_args(++str, ';', ')', 3, arg);
|
||||||
|
|
||||||
@ -162,6 +54,7 @@ status_parse_mouse(struct status_seq *sq, char *str)
|
|||||||
m->func = uicb_name_func(arg[1]);
|
m->func = uicb_name_func(arg[1]);
|
||||||
m->cmd = (i > 1 ? xstrdup(arg[2]) : NULL);
|
m->cmd = (i > 1 ? xstrdup(arg[2]) : NULL);
|
||||||
|
|
||||||
|
SLIST_INSERT_HEAD(&b->mousebinds, m, next);
|
||||||
SLIST_INSERT_HEAD(&sq->mousebinds, m, snext);
|
SLIST_INSERT_HEAD(&sq->mousebinds, m, snext);
|
||||||
|
|
||||||
return end + 1;
|
return end + 1;
|
||||||
@ -173,28 +66,23 @@ status_parse_mouse(struct status_seq *sq, char *str)
|
|||||||
str = end + 2; \
|
str = end + 2; \
|
||||||
continue; \
|
continue; \
|
||||||
}
|
}
|
||||||
void
|
static void
|
||||||
status_parse(struct status_ctx *ctx)
|
status_parse(struct element *e)
|
||||||
{
|
{
|
||||||
struct status_seq *sq, *prev = NULL;
|
struct status_seq *sq, *prev = NULL;
|
||||||
int i, tmp, shift = 0;
|
int i, shift = 0;
|
||||||
char *dstr = xstrdup(ctx->status), *sauv = dstr;
|
char *dstr = xstrdup(e->infobar->status), *sauv = dstr;
|
||||||
char type, *p, *pp, *end, *arg[10] = { NULL };
|
char type, *p, *end, *arg[6] = { NULL };
|
||||||
|
|
||||||
for(; *dstr; ++dstr)
|
for(; *dstr; ++dstr)
|
||||||
{
|
{
|
||||||
/* Check if this is a sequence */
|
/* Check if this is a sequence */
|
||||||
if(*dstr != '^' && *dstr != '\\')
|
if(*dstr != '\\')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
p = ++dstr;
|
p = ++dstr;
|
||||||
|
|
||||||
/* Search for correct end of sequence (] without \ behind) */
|
if(!(strchr("sR", *p)) || !(end = strchr(p, ']')))
|
||||||
if((end = strchr(p, ']')))
|
|
||||||
while(*(end - 1) == '\\')
|
|
||||||
end = strchr(end + 1, ']');
|
|
||||||
|
|
||||||
if(!(strchr("sRpPig", *p)) || !end)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Then parse & list it */
|
/* Then parse & list it */
|
||||||
@ -211,10 +99,6 @@ status_parse(struct status_ctx *ctx)
|
|||||||
sq->color = color_atoh(arg[1 + shift]);
|
sq->color = color_atoh(arg[1 + shift]);
|
||||||
sq->str = xstrdup(arg[2 + 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;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -230,83 +114,16 @@ status_parse(struct status_ctx *ctx)
|
|||||||
sq->color = color_atoh(arg[3 + shift]);
|
sq->color = color_atoh(arg[3 + shift]);
|
||||||
|
|
||||||
break;
|
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_TAIL(&e->infobar->statushead, sq, next, prev);
|
||||||
SLIST_INSERT_HEAD(&ctx->statushead, sq, next);
|
|
||||||
else
|
|
||||||
SLIST_INSERT_TAIL(&ctx->statushead, sq, next, prev);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Optional mousebind sequence(s) \<seq>[](button;func;cmd)
|
* Optional mousebind sequence(s) \<seq>[](button;func;cmd)
|
||||||
* Parse it while there is a mousebind sequence.
|
* Parse it while there is a mousebind sequence.
|
||||||
*/
|
*/
|
||||||
dstr = end + 1;
|
dstr = ++end;
|
||||||
|
while((*(dstr = status_parse_mouse(sq, e, dstr)) == '('));
|
||||||
do
|
|
||||||
dstr = status_parse_mouse(sq, dstr);
|
|
||||||
while(*dstr == '(');
|
|
||||||
|
|
||||||
--dstr;
|
|
||||||
|
|
||||||
prev = sq;
|
prev = sq;
|
||||||
}
|
}
|
||||||
@ -314,49 +131,40 @@ status_parse(struct status_ctx *ctx)
|
|||||||
free(sauv);
|
free(sauv);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define STATUS_ALIGN(align) \
|
#define STATUS_ALIGN(align) \
|
||||||
if(align == Left) \
|
if(align == Left) \
|
||||||
{ \
|
{ \
|
||||||
sq->geo.x = left; \
|
sq->geo.x = left; \
|
||||||
left += sq->geo.w; \
|
left += sq->geo.w; \
|
||||||
} \
|
} \
|
||||||
else if(align == Right) \
|
else if(align == Right) \
|
||||||
{ \
|
{ \
|
||||||
sq->geo.x = ctx->barwin->geo.w - right - sq->geo.w; \
|
sq->geo.x = e->geo.w - right - sq->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
|
static void
|
||||||
status_apply_list(struct status_ctx *ctx)
|
status_apply_list(struct element *e)
|
||||||
{
|
{
|
||||||
struct status_seq *sq;
|
struct status_seq *sq;
|
||||||
|
struct barwin *b = SLIST_FIRST(&e->bars);
|
||||||
struct mousebind *m;
|
struct mousebind *m;
|
||||||
struct geo g;
|
int left = 0, right = 0;
|
||||||
int left = 0, right = 0, w, h;
|
|
||||||
|
|
||||||
SLIST_FOREACH(sq, &ctx->statushead, next)
|
SLIST_FOREACH(sq, &e->infobar->statushead, next)
|
||||||
{
|
{
|
||||||
switch(sq->type)
|
switch(sq->type)
|
||||||
{
|
{
|
||||||
/* Text */
|
/* Text */
|
||||||
case 's':
|
case 's':
|
||||||
sq->geo.w = draw_textw(ctx->theme, sq->str);
|
sq->geo.w = draw_textw(e->infobar->theme, sq->str);
|
||||||
sq->geo.h = ctx->theme->font.height;
|
sq->geo.h = e->infobar->theme->font.height;
|
||||||
|
|
||||||
if(sq->align != NoAlign)
|
if(sq->align != NoAlign)
|
||||||
sq->geo.y = TEXTY(ctx->theme, ctx->barwin->geo.h);
|
sq->geo.y = TEXTY(e->infobar->theme, e->geo.h);
|
||||||
|
|
||||||
STATUS_ALIGN(sq->align);
|
STATUS_ALIGN(sq->align);
|
||||||
|
|
||||||
draw_text(ctx->barwin->dr, ctx->theme, sq->geo.x, sq->geo.y, sq->color, sq->str);
|
draw_text(b->dr, e->infobar->theme, sq->geo.x, sq->geo.y, sq->color, sq->str);
|
||||||
|
|
||||||
if(!SLIST_EMPTY(&sq->mousebinds))
|
if(!SLIST_EMPTY(&sq->mousebinds))
|
||||||
SLIST_FOREACH(m, &sq->mousebinds, snext)
|
SLIST_FOREACH(m, &sq->mousebinds, snext)
|
||||||
@ -369,259 +177,75 @@ status_apply_list(struct status_ctx *ctx)
|
|||||||
|
|
||||||
/* Rectangle */
|
/* Rectangle */
|
||||||
case 'R':
|
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)
|
if(sq->align != NoAlign)
|
||||||
sq->geo.y = (ctx->barwin->geo.h >> 1) - (sq->geo.h >> 1);
|
sq->geo.y = (e->geo.h >> 1) - (sq->geo.h >> 1);
|
||||||
|
|
||||||
STATUS_ALIGN(sq->align);
|
STATUS_ALIGN(sq->align);
|
||||||
draw_image(ctx->barwin->dr, &sq->geo);
|
|
||||||
STORE_MOUSEBIND();
|
draw_rect(b->dr, sq->geo, sq->color);
|
||||||
|
|
||||||
|
if(!SLIST_EMPTY(&sq->mousebinds))
|
||||||
|
SLIST_FOREACH(m, &sq->mousebinds, snext)
|
||||||
|
m->area = sq->geo;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
#endif /* HAVE_IMLIB2 */
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Render current statustext of an element */
|
/* Render current statustext of an element */
|
||||||
void
|
void
|
||||||
status_render(struct status_ctx *ctx)
|
status_render(struct element *e)
|
||||||
{
|
{
|
||||||
if(!ctx->status)
|
struct barwin *b = SLIST_FIRST(&e->bars);
|
||||||
|
|
||||||
|
if(!e->infobar->status)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(!(ctx->flags & STATUS_BLOCK_REFRESH))
|
barwin_refresh_color(b);
|
||||||
barwin_refresh_color(ctx->barwin);
|
|
||||||
|
|
||||||
/* Use simple text instead sequence if no sequence found */
|
/* Use simple text instead sequence if no sequence found */
|
||||||
if(SLIST_EMPTY(&ctx->statushead))
|
if(SLIST_EMPTY(&e->infobar->statushead))
|
||||||
{
|
{
|
||||||
int l = draw_textw(ctx->theme, ctx->status);
|
int l = draw_textw(e->infobar->theme, e->infobar->status);
|
||||||
draw_text(ctx->barwin->dr, ctx->theme, ctx->barwin->geo.w - l,
|
draw_text(b->dr, e->infobar->theme, e->geo.w - l,
|
||||||
TEXTY(ctx->theme, ctx->barwin->geo.h), ctx->barwin->fg, ctx->status);
|
TEXTY(e->infobar->theme, e->geo.h), b->fg, e->infobar->status);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
status_apply_list(ctx);
|
status_apply_list(e);
|
||||||
|
|
||||||
barwin_refresh(ctx->barwin);
|
barwin_refresh(b);
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
status_flush_list(struct status_ctx *ctx)
|
|
||||||
{
|
|
||||||
struct status_seq *sq;
|
|
||||||
struct mousebind *m;
|
|
||||||
|
|
||||||
/* Flush previous linked list of status sequences */
|
|
||||||
while(!SLIST_EMPTY(&ctx->statushead))
|
|
||||||
{
|
|
||||||
sq = SLIST_FIRST(&ctx->statushead);
|
|
||||||
SLIST_REMOVE_HEAD(&ctx->statushead, next);
|
|
||||||
|
|
||||||
while(!SLIST_EMPTY(&sq->mousebinds))
|
|
||||||
{
|
|
||||||
m = SLIST_FIRST(&sq->mousebinds);
|
|
||||||
SLIST_REMOVE_HEAD(&sq->mousebinds, snext);
|
|
||||||
free((void*)m->cmd);
|
|
||||||
free(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(sq->str);
|
|
||||||
free(sq);
|
|
||||||
}
|
|
||||||
|
|
||||||
SLIST_INIT(&ctx->statushead);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
status_copy_mousebind(struct status_ctx *ctx)
|
|
||||||
{
|
|
||||||
struct mousebind *m;
|
|
||||||
struct status_seq *sq;
|
|
||||||
|
|
||||||
if(!ctx->barwin)
|
|
||||||
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 */
|
/* Parse and render statustext */
|
||||||
void
|
void
|
||||||
status_manage(struct status_ctx *ctx)
|
status_manage(struct element *e)
|
||||||
{
|
{
|
||||||
if(!ctx->status)
|
struct status_seq *sq;
|
||||||
return;
|
struct mousebind *m;
|
||||||
|
struct barwin *b = SLIST_FIRST(&e->bars);
|
||||||
|
|
||||||
ctx->update = false;
|
/*
|
||||||
|
* Flush previous linked list of status sequences
|
||||||
status_flush_list(ctx);
|
* and mousebind of status barwin
|
||||||
status_parse(ctx);
|
*/
|
||||||
status_render(ctx);
|
while(!SLIST_EMPTY(&e->infobar->statushead))
|
||||||
status_copy_mousebind(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
status_flush_surface(void)
|
|
||||||
{
|
|
||||||
struct barwin *b;
|
|
||||||
|
|
||||||
while(!SLIST_EMPTY(&W->h.vbarwin))
|
|
||||||
{
|
{
|
||||||
b = SLIST_FIRST(&W->h.vbarwin);
|
sq = SLIST_FIRST(&e->infobar->statushead);
|
||||||
SLIST_REMOVE_HEAD(&W->h.vbarwin, vnext);
|
SLIST_REMOVE_HEAD(&e->infobar->statushead, next);
|
||||||
barwin_remove(b);
|
free(sq->str);
|
||||||
|
free(sq);
|
||||||
}
|
}
|
||||||
}
|
while(!SLIST_EMPTY(&b->mousebinds))
|
||||||
|
|
||||||
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);
|
m = SLIST_FIRST(&b->mousebinds);
|
||||||
return;
|
SLIST_REMOVE_HEAD(&b->mousebinds, next);
|
||||||
|
free((void*)m->cmd);
|
||||||
|
free(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
status_surface(x, y, w, h, bg, p);
|
status_parse(e);
|
||||||
|
status_render(e);
|
||||||
free(ccmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Syntax: "<infobar name> <status string>" */
|
/* Syntax: "<infobar name> <status string>" */
|
||||||
@ -644,9 +268,8 @@ uicb_status(Uicb cmd)
|
|||||||
SLIST_FOREACH(ib, &s->infobars, next)
|
SLIST_FOREACH(ib, &s->infobars, next)
|
||||||
if(!strcmp(cmd, ib->name))
|
if(!strcmp(cmd, ib->name))
|
||||||
{
|
{
|
||||||
free(ib->statusctx.status);
|
free(ib->status);
|
||||||
ib->statusctx.status = xstrdup(p);
|
ib->status = xstrdup(p);
|
||||||
ib->statusctx.update = true;
|
|
||||||
infobar_elem_screen_update(s, ElemStatus);
|
infobar_elem_screen_update(s, ElemStatus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/status.h
12
src/status.h
@ -8,16 +8,8 @@
|
|||||||
|
|
||||||
#include "wmfs.h"
|
#include "wmfs.h"
|
||||||
|
|
||||||
struct status_ctx status_new_ctx(struct barwin *b, struct theme *t);
|
void status_render(struct element *e);
|
||||||
void status_free_ctx(struct status_ctx *ctx);
|
void status_manage(struct element *e);
|
||||||
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(Uicb cmd);
|
||||||
void uicb_status_surface(Uicb cmd);
|
|
||||||
|
|
||||||
#endif /* STATUS_H */
|
#endif /* STATUS_H */
|
||||||
|
|||||||
200
src/systray.c
200
src/systray.c
@ -1,200 +0,0 @@
|
|||||||
/*
|
|
||||||
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
|
|
||||||
* For license, see COPYING.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "wmfs.h"
|
|
||||||
#include "systray.h"
|
|
||||||
#include "ewmh.h"
|
|
||||||
#include "infobar.h"
|
|
||||||
|
|
||||||
#define SYSTRAY_SPACING (2)
|
|
||||||
|
|
||||||
void
|
|
||||||
systray_acquire(void)
|
|
||||||
{
|
|
||||||
Window w = 0;
|
|
||||||
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)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(XGetSelectionOwner(W->dpy, W->net_atom[net_system_tray_s]) != None)
|
|
||||||
{
|
|
||||||
warnx("Can't initialize system tray: owned by another process.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SLIST_INIT(&W->systray.head);
|
|
||||||
|
|
||||||
/* Init systray window */
|
|
||||||
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);
|
|
||||||
XSelectInput(W->dpy, w, KeyPressMask | ButtonPressMask);
|
|
||||||
XMapRaised(W->dpy, w);
|
|
||||||
|
|
||||||
XSetSelectionOwner(W->dpy, W->net_atom[net_system_tray_s], w, CurrentTime);
|
|
||||||
|
|
||||||
if(XGetSelectionOwner(W->dpy, W->net_atom[net_system_tray_s]) != w)
|
|
||||||
{
|
|
||||||
warnl("System tray: can't get systray manager");
|
|
||||||
systray_freeicons();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ewmh_send_message(W->root, W->root, "MANAGER", CurrentTime,
|
|
||||||
W->net_atom[net_system_tray_s], w, 0, 0);
|
|
||||||
|
|
||||||
XSync(W->dpy, false);
|
|
||||||
|
|
||||||
W->systray.win = w;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
systray_add(Window win)
|
|
||||||
{
|
|
||||||
struct _systray *s;
|
|
||||||
|
|
||||||
if(!(W->flags & WMFS_SYSTRAY))
|
|
||||||
return;
|
|
||||||
|
|
||||||
s = xcalloc(1, sizeof(struct _systray));
|
|
||||||
s->win = win;
|
|
||||||
|
|
||||||
s->geo.h = W->systray.barwin->geo.h;
|
|
||||||
s->geo.w = W->systray.barwin->geo.h + SYSTRAY_SPACING;
|
|
||||||
|
|
||||||
ewmh_set_wm_state(s->win, NormalState);
|
|
||||||
XSelectInput(W->dpy, s->win, StructureNotifyMask | PropertyChangeMask| EnterWindowMask | FocusChangeMask);
|
|
||||||
XReparentWindow(W->dpy, s->win, W->systray.win, 0, 0);
|
|
||||||
|
|
||||||
ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime,
|
|
||||||
XEMBED_EMBEDDED_NOTIFY, 0, W->systray.win, 0);
|
|
||||||
|
|
||||||
SLIST_INSERT_HEAD(&W->systray.head, s, next);
|
|
||||||
|
|
||||||
W->systray.redim = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
systray_del(struct _systray *s)
|
|
||||||
{
|
|
||||||
if(!(W->flags & WMFS_SYSTRAY))
|
|
||||||
return;
|
|
||||||
|
|
||||||
SLIST_REMOVE(&W->systray.head, s, _systray, next);
|
|
||||||
free(s);
|
|
||||||
|
|
||||||
W->systray.redim = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
systray_state(struct _systray *s)
|
|
||||||
{
|
|
||||||
long flags;
|
|
||||||
int code = 0;
|
|
||||||
|
|
||||||
if(!(W->flags & WMFS_SYSTRAY) || !(flags = ewmh_get_xembed_state(s->win)))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(flags & XEMBED_MAPPED)
|
|
||||||
{
|
|
||||||
code = XEMBED_WINDOW_ACTIVATE;
|
|
||||||
XMapRaised(W->dpy, s->win);
|
|
||||||
ewmh_set_wm_state(s->win, NormalState);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
code = XEMBED_WINDOW_DEACTIVATE;
|
|
||||||
XUnmapWindow(W->dpy, s->win);
|
|
||||||
ewmh_set_wm_state(s->win, WithdrawnState);
|
|
||||||
}
|
|
||||||
|
|
||||||
ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime, code, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
systray_freeicons(void)
|
|
||||||
{
|
|
||||||
struct _systray *i;
|
|
||||||
|
|
||||||
if(!(W->flags & WMFS_SYSTRAY))
|
|
||||||
return;
|
|
||||||
|
|
||||||
while(!SLIST_EMPTY(&W->systray.head))
|
|
||||||
{
|
|
||||||
i = SLIST_FIRST(&W->systray.head);
|
|
||||||
SLIST_REMOVE_HEAD(&W->systray.head, next);
|
|
||||||
|
|
||||||
XUnmapWindow(W->dpy, i->win);
|
|
||||||
XReparentWindow(W->dpy, i->win, W->root, 0, 0);
|
|
||||||
free(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
XSetSelectionOwner(W->dpy, W->net_atom[net_system_tray_s], None, CurrentTime);
|
|
||||||
W->systray.barwin->geo.w = 0;
|
|
||||||
infobar_elem_reinit(W->systray.infobar);
|
|
||||||
XSync(W->dpy, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct _systray*
|
|
||||||
systray_find(Window win)
|
|
||||||
{
|
|
||||||
struct _systray *i;
|
|
||||||
|
|
||||||
if(!(W->flags & WMFS_SYSTRAY))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
SLIST_FOREACH(i, &W->systray.head, next)
|
|
||||||
if(i->win == win)
|
|
||||||
return i;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
systray_get_width(void)
|
|
||||||
{
|
|
||||||
int w = 1;
|
|
||||||
struct _systray *i;
|
|
||||||
|
|
||||||
SLIST_FOREACH(i, &W->systray.head, next)
|
|
||||||
w += i->geo.w + SYSTRAY_SPACING;
|
|
||||||
|
|
||||||
return w;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
systray_update(void)
|
|
||||||
{
|
|
||||||
int x = 1;
|
|
||||||
struct _systray *i;
|
|
||||||
|
|
||||||
if(!(W->flags & WMFS_SYSTRAY))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(W->systray.redim)
|
|
||||||
{
|
|
||||||
W->systray.redim = false;
|
|
||||||
infobar_elem_reinit(W->systray.infobar);
|
|
||||||
}
|
|
||||||
|
|
||||||
SLIST_FOREACH(i, &W->systray.head, next)
|
|
||||||
{
|
|
||||||
XMapWindow(W->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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -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 */
|
|
||||||
112
src/tag.c
112
src/tag.c
@ -22,6 +22,7 @@ tag_new(struct screen *s, char *name)
|
|||||||
t = xcalloc(1, sizeof(struct tag));
|
t = xcalloc(1, sizeof(struct tag));
|
||||||
|
|
||||||
t->screen = s;
|
t->screen = s;
|
||||||
|
t->name = xstrdup(name);
|
||||||
t->flags = 0;
|
t->flags = 0;
|
||||||
t->id = 0;
|
t->id = 0;
|
||||||
t->sel = NULL;
|
t->sel = NULL;
|
||||||
@ -30,11 +31,6 @@ tag_new(struct screen *s, char *name)
|
|||||||
if((l = TAILQ_LAST(&s->tags, tsub)))
|
if((l = TAILQ_LAST(&s->tags, tsub)))
|
||||||
t->id = l->id + 1;
|
t->id = l->id + 1;
|
||||||
|
|
||||||
if(!name || !strlen(name))
|
|
||||||
xasprintf(&t->name, "%d", t->id + 1);
|
|
||||||
else
|
|
||||||
t->name = xstrdup(name);
|
|
||||||
|
|
||||||
SLIST_INIT(&t->clients);
|
SLIST_INIT(&t->clients);
|
||||||
TAILQ_INIT(&t->sets);
|
TAILQ_INIT(&t->sets);
|
||||||
|
|
||||||
@ -46,31 +42,20 @@ tag_new(struct screen *s, char *name)
|
|||||||
void
|
void
|
||||||
tag_screen(struct screen *s, struct tag *t)
|
tag_screen(struct screen *s, struct tag *t)
|
||||||
{
|
{
|
||||||
struct client *c;
|
if(t == s->seltag)
|
||||||
|
|
||||||
/* Return to the previous tag */
|
|
||||||
if(t == s->seltag && TAILQ_NEXT(TAILQ_FIRST(&s->tags), next))
|
|
||||||
t = t->prev;
|
t = t->prev;
|
||||||
|
|
||||||
if(!t)
|
if(!t)
|
||||||
t = TAILQ_FIRST(&s->tags);
|
t = TAILQ_FIRST(&s->tags);
|
||||||
|
|
||||||
/* Move clients which ignore tags */
|
|
||||||
SLIST_FOREACH(c, &W->h.client, next)
|
|
||||||
if (c->flags & CLIENT_IGNORE_TAG)
|
|
||||||
tag_client(t, c);
|
|
||||||
|
|
||||||
t->prev = s->seltag;
|
t->prev = s->seltag;
|
||||||
s->seltag = t;
|
s->seltag = t;
|
||||||
|
|
||||||
clients_arrange_map();
|
clients_arrange_map();
|
||||||
|
|
||||||
/* Update focus */
|
|
||||||
if(!SLIST_EMPTY(&t->clients) && !(W->flags & WMFS_SCAN))
|
if(!SLIST_EMPTY(&t->clients) && !(W->flags & WMFS_SCAN))
|
||||||
client_focus( client_tab_next(t->sel));
|
client_focus( client_tab_next(t->sel));
|
||||||
|
|
||||||
t->flags &= ~TAG_URGENT;
|
|
||||||
|
|
||||||
infobar_elem_screen_update(s, ElemTag);
|
infobar_elem_screen_update(s, ElemTag);
|
||||||
|
|
||||||
ewmh_update_wmfs_props();
|
ewmh_update_wmfs_props();
|
||||||
@ -86,7 +71,7 @@ tag_client(struct tag *t, struct client *c)
|
|||||||
if(c->tag == t)
|
if(c->tag == t)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(!(c->flags & (CLIENT_IGNORE_LAYOUT | CLIENT_FREE)))
|
if(!(c->flags & CLIENT_IGNORE_LAYOUT))
|
||||||
layout_split_arrange_closed(c);
|
layout_split_arrange_closed(c);
|
||||||
|
|
||||||
if(!(c->flags & CLIENT_REMOVEALL))
|
if(!(c->flags & CLIENT_REMOVEALL))
|
||||||
@ -102,10 +87,7 @@ tag_client(struct tag *t, struct client *c)
|
|||||||
|
|
||||||
/* Client remove */
|
/* Client remove */
|
||||||
if(!t)
|
if(!t)
|
||||||
{
|
|
||||||
infobar_elem_screen_update(c->screen, ElemTag);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
c->prevtag = c->tag;
|
c->prevtag = c->tag;
|
||||||
c->tag = t;
|
c->tag = t;
|
||||||
@ -113,9 +95,16 @@ tag_client(struct tag *t, struct client *c)
|
|||||||
|
|
||||||
client_update_props(c, CPROP_LOC);
|
client_update_props(c, CPROP_LOC);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Insert in new tag list before
|
||||||
|
* layout_split_integrate, because of set historic.
|
||||||
|
*/
|
||||||
SLIST_INSERT_HEAD(&t->clients, c, tnext);
|
SLIST_INSERT_HEAD(&t->clients, c, tnext);
|
||||||
|
|
||||||
infobar_elem_screen_update(c->screen, ElemTag);
|
if(c->flags & CLIENT_IGNORE_LAYOUT)
|
||||||
|
c->flags ^= CLIENT_IGNORE_LAYOUT;
|
||||||
|
else if(!(c->flags & CLIENT_TABBED))
|
||||||
|
layout_split_integrate(c, t->sel);
|
||||||
|
|
||||||
if(c->flags & CLIENT_TABMASTER && c->prevtag)
|
if(c->flags & CLIENT_TABMASTER && c->prevtag)
|
||||||
{
|
{
|
||||||
@ -123,14 +112,9 @@ tag_client(struct tag *t, struct client *c)
|
|||||||
|
|
||||||
SLIST_FOREACH(cc, &c->prevtag->clients, tnext)
|
SLIST_FOREACH(cc, &c->prevtag->clients, tnext)
|
||||||
if(cc->tabmaster == c)
|
if(cc->tabmaster == c)
|
||||||
{
|
|
||||||
cc->flags |= CLIENT_IGNORE_LAYOUT;
|
|
||||||
tag_client(t, cc);
|
tag_client(t, cc);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
layout_client(c);
|
|
||||||
|
|
||||||
if(t != c->screen->seltag || c->flags & CLIENT_TABBED)
|
if(t != c->screen->seltag || c->flags & CLIENT_TABBED)
|
||||||
client_unmap(c);
|
client_unmap(c);
|
||||||
}
|
}
|
||||||
@ -169,8 +153,8 @@ uicb_tag_next(Uicb cmd)
|
|||||||
struct tag *t;
|
struct tag *t;
|
||||||
|
|
||||||
if((t = TAILQ_NEXT(W->screen->seltag, next)))
|
if((t = TAILQ_NEXT(W->screen->seltag, next)))
|
||||||
tag_screen(W->screen, t);
|
tag_screen(W->screen, t);
|
||||||
else if(W->flags & WMFS_TAGCIRC)
|
else if( /* CIRCULAR OPTION */ 1)
|
||||||
tag_screen(W->screen, TAILQ_FIRST(&W->screen->tags));
|
tag_screen(W->screen, TAILQ_FIRST(&W->screen->tags));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,7 +166,7 @@ uicb_tag_prev(Uicb cmd)
|
|||||||
|
|
||||||
if((t = TAILQ_PREV(W->screen->seltag, tsub, next)))
|
if((t = TAILQ_PREV(W->screen->seltag, tsub, next)))
|
||||||
tag_screen(W->screen, t);
|
tag_screen(W->screen, t);
|
||||||
else if(W->flags & WMFS_TAGCIRC)
|
else if( /* CIRCULAR OPTION */ 1)
|
||||||
tag_screen(W->screen, TAILQ_LAST(&W->screen->tags, tsub));
|
tag_screen(W->screen, TAILQ_LAST(&W->screen->tags, tsub));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,29 +176,19 @@ uicb_tag_client(Uicb cmd)
|
|||||||
struct tag *t;
|
struct tag *t;
|
||||||
int id = ATOI(cmd);
|
int id = ATOI(cmd);
|
||||||
|
|
||||||
if(W->client && (t = tag_gb_id(W->screen, id)))
|
if((t = tag_gb_id(W->screen, id)))
|
||||||
tag_client(t, W->client);
|
tag_client(t, W->client);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
uicb_tag_client_and_set(Uicb cmd)
|
|
||||||
{
|
|
||||||
uicb_tag_client(cmd);
|
|
||||||
uicb_tag_set(cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
uicb_tag_move_client_next(Uicb cmd)
|
uicb_tag_move_client_next(Uicb cmd)
|
||||||
{
|
{
|
||||||
(void)cmd;
|
(void)cmd;
|
||||||
struct tag *t;
|
struct tag *t;
|
||||||
|
|
||||||
if(!W->client)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if((t = TAILQ_NEXT(W->screen->seltag, next)))
|
if((t = TAILQ_NEXT(W->screen->seltag, next)))
|
||||||
tag_client(t, W->client);
|
tag_client(t, W->client);
|
||||||
else if(W->flags & WMFS_TAGCIRC)
|
else if( /* CIRCULAR OPTION */ 1)
|
||||||
tag_client(TAILQ_FIRST(&W->screen->tags), W->client);
|
tag_client(TAILQ_FIRST(&W->screen->tags), W->client);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,12 +198,9 @@ uicb_tag_move_client_prev(Uicb cmd)
|
|||||||
(void)cmd;
|
(void)cmd;
|
||||||
struct tag *t;
|
struct tag *t;
|
||||||
|
|
||||||
if(!W->client)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if((t = TAILQ_PREV(W->screen->seltag, tsub, next)))
|
if((t = TAILQ_PREV(W->screen->seltag, tsub, next)))
|
||||||
tag_client(t, W->client);
|
tag_client(t, W->client);
|
||||||
else if(W->flags & WMFS_TAGCIRC)
|
else if( /* CIRCULAR OPTION */ 1)
|
||||||
tag_client(TAILQ_LAST(&W->screen->tags, tsub), W->client);
|
tag_client(TAILQ_LAST(&W->screen->tags, tsub), W->client);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,8 +218,6 @@ uicb_tag_click(Uicb cmd)
|
|||||||
static void
|
static void
|
||||||
tag_remove(struct tag *t)
|
tag_remove(struct tag *t)
|
||||||
{
|
{
|
||||||
TAILQ_REMOVE(&t->screen->tags, t, next);
|
|
||||||
|
|
||||||
free(t->name);
|
free(t->name);
|
||||||
|
|
||||||
layout_free_set(t);
|
layout_free_set(t);
|
||||||
@ -256,47 +225,14 @@ tag_remove(struct tag *t)
|
|||||||
free(t);
|
free(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
uicb_tag_new(Uicb cmd)
|
|
||||||
{
|
|
||||||
struct screen *s = W->screen;
|
|
||||||
struct infobar *i;
|
|
||||||
|
|
||||||
tag_new(s, (char*)cmd);
|
|
||||||
|
|
||||||
s->flags |= SCREEN_TAG_UPDATE;
|
|
||||||
|
|
||||||
SLIST_FOREACH(i, &s->infobars, next)
|
|
||||||
infobar_elem_reinit(i);
|
|
||||||
|
|
||||||
s->flags ^= SCREEN_TAG_UPDATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
uicb_tag_del(Uicb cmd)
|
|
||||||
{
|
|
||||||
struct infobar *i;
|
|
||||||
struct tag *t = W->screen->seltag;
|
|
||||||
(void)cmd;
|
|
||||||
|
|
||||||
if(SLIST_EMPTY(&t->clients)
|
|
||||||
&& TAILQ_NEXT(TAILQ_FIRST(&W->screen->tags), next))
|
|
||||||
{
|
|
||||||
tag_screen(W->screen, TAILQ_NEXT(t, next));
|
|
||||||
tag_remove(t);
|
|
||||||
|
|
||||||
W->screen->flags |= SCREEN_TAG_UPDATE;
|
|
||||||
|
|
||||||
SLIST_FOREACH(i, &W->screen->infobars, next)
|
|
||||||
infobar_elem_reinit(i);
|
|
||||||
|
|
||||||
W->screen->flags ^= SCREEN_TAG_UPDATE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
tag_free(struct screen *s)
|
tag_free(struct screen *s)
|
||||||
{
|
{
|
||||||
while(!TAILQ_EMPTY(&s->tags))
|
struct tag *t;
|
||||||
tag_remove(TAILQ_FIRST(&s->tags));
|
|
||||||
|
TAILQ_FOREACH(t, &s->tags, next)
|
||||||
|
{
|
||||||
|
TAILQ_REMOVE(&s->tags, t, next);
|
||||||
|
tag_remove(t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "wmfs.h"
|
#include "wmfs.h"
|
||||||
|
|
||||||
|
|
||||||
static inline struct tag*
|
static inline struct tag*
|
||||||
tag_gb_id(struct screen *s, int id)
|
tag_gb_id(struct screen *s, int id)
|
||||||
{
|
{
|
||||||
@ -29,11 +30,9 @@ void uicb_tag_set_with_name(Uicb cmd);
|
|||||||
void uicb_tag_next(Uicb cmd);
|
void uicb_tag_next(Uicb cmd);
|
||||||
void uicb_tag_prev(Uicb cmd);
|
void uicb_tag_prev(Uicb cmd);
|
||||||
void uicb_tag_client(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_next(Uicb cmd);
|
||||||
void uicb_tag_move_client_prev(Uicb cmd);
|
void uicb_tag_move_client_prev(Uicb cmd);
|
||||||
void uicb_tag_click(Uicb cmd);
|
void uicb_tag_click(Uicb cmd);
|
||||||
void uicb_tag_new(Uicb cmd);
|
|
||||||
void uicb_tag_del(Uicb cmd);
|
|
||||||
|
|
||||||
#endif /* TAG_H */
|
#endif /* TAG_H */
|
||||||
|
|||||||
28
src/util.c
28
src/util.c
@ -46,28 +46,6 @@ xcalloc(size_t nmemb, size_t size)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** realloc with error support and size_t overflow check
|
|
||||||
* \param ptr old pointer
|
|
||||||
* \param nmemb number of objects
|
|
||||||
* \param size size of single object
|
|
||||||
* \return non null void pointer
|
|
||||||
*/
|
|
||||||
void *
|
|
||||||
xrealloc(void *ptr, size_t nmemb, size_t size)
|
|
||||||
{
|
|
||||||
void *ret;
|
|
||||||
|
|
||||||
if(SIZE_MAX / nmemb < size)
|
|
||||||
err(EXIT_FAILURE, "xrealloc(%p, %zu, %zu), "
|
|
||||||
"size_t overflow detected", ptr, nmemb, size);
|
|
||||||
|
|
||||||
if((ret = realloc(ptr, nmemb * size)) == NULL)
|
|
||||||
err(EXIT_FAILURE, "realloc(%p, %zu)", ptr, nmemb * size);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** asprintf wrapper
|
/** asprintf wrapper
|
||||||
* \param strp target string
|
* \param strp target string
|
||||||
* \param fmt format
|
* \param fmt format
|
||||||
@ -130,7 +108,7 @@ spawn(const char *format, ...)
|
|||||||
if(!(sh = getenv("SHELL")) || sh[0] != '/')
|
if(!(sh = getenv("SHELL")) || sh[0] != '/')
|
||||||
sh = "/bin/sh";
|
sh = "/bin/sh";
|
||||||
|
|
||||||
if(!(pid = fork()))
|
if((pid = fork()) == 0)
|
||||||
{
|
{
|
||||||
setsid();
|
setsid();
|
||||||
if (execl(sh, sh, "-c", cmd, (char*)NULL) == -1)
|
if (execl(sh, sh, "-c", cmd, (char*)NULL) == -1)
|
||||||
@ -148,8 +126,8 @@ parse_args(char *str, char delim, char end, int narg, char *args[])
|
|||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
for(args[0] = str; *str && (*str != end || *(str - 1) == '\\') && i < narg; ++str)
|
for(args[0] = str; *str && *str != end && i < narg; ++str)
|
||||||
if(*str == delim && i < narg - 1)
|
if(*str == delim)
|
||||||
{
|
{
|
||||||
*str = '\0';
|
*str = '\0';
|
||||||
args[++i] = ++str;
|
args[++i] = ++str;
|
||||||
|
|||||||
18
src/util.h
18
src/util.h
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
/* Insert at the end with SLIST */
|
/* Insert at the end with SLIST */
|
||||||
#define SLIST_INSERT_TAIL(head, elem, field, prev) \
|
#define SLIST_INSERT_TAIL(head, elem, field, prev) \
|
||||||
if(!prev) \
|
if(SLIST_EMPTY(head)) \
|
||||||
SLIST_INSERT_HEAD(head, elem, field); \
|
SLIST_INSERT_HEAD(head, elem, field); \
|
||||||
else \
|
else \
|
||||||
SLIST_INSERT_AFTER(prev, elem, field);
|
SLIST_INSERT_AFTER(prev, elem, field);
|
||||||
@ -49,12 +49,9 @@
|
|||||||
static inline Color
|
static inline Color
|
||||||
color_atoh(const char *col)
|
color_atoh(const char *col)
|
||||||
{
|
{
|
||||||
XColor xcolor;
|
int shift = (col[0] == '#');
|
||||||
|
|
||||||
if(!XAllocNamedColor(W->dpy, DefaultColormap(W->dpy, W->xscreen), col, &xcolor, &xcolor))
|
return (Color)strtol(col + shift, NULL, 16);
|
||||||
warnl("Error: cannot allocate color \"%s\".", col);
|
|
||||||
|
|
||||||
return xcolor.pixel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
@ -66,14 +63,6 @@ swap_ptr(void **x, void **y)
|
|||||||
*y = t;
|
*y = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
|
||||||
swap_int(int *x, int *y)
|
|
||||||
{
|
|
||||||
*y = *x ^ *y;
|
|
||||||
*x = *y ^ *x;
|
|
||||||
*y = *x ^ *y;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline enum position
|
static inline enum position
|
||||||
str_to_position(char *str)
|
str_to_position(char *str)
|
||||||
{
|
{
|
||||||
@ -89,7 +78,6 @@ str_to_position(char *str)
|
|||||||
|
|
||||||
void *xmalloc(size_t nmemb, size_t size);
|
void *xmalloc(size_t nmemb, size_t size);
|
||||||
void *xcalloc(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, ...);
|
int xasprintf(char **strp, const char *fmt, ...);
|
||||||
char *xstrdup(const char *str);
|
char *xstrdup(const char *str);
|
||||||
pid_t spawn(const char *format, ...);
|
pid_t spawn(const char *format, ...);
|
||||||
|
|||||||
265
src/wmfs.c
265
src/wmfs.c
@ -3,17 +3,10 @@
|
|||||||
* For license, see COPYING.
|
* For license, see COPYING.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <signal.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <X11/keysym.h>
|
#include <X11/keysym.h>
|
||||||
#include <X11/cursorfont.h>
|
#include <X11/cursorfont.h>
|
||||||
|
|
||||||
#ifdef HAVE_IMLIB2
|
|
||||||
#include <Imlib2.h>
|
|
||||||
#endif /* HAVE_IMLIB2 */
|
|
||||||
|
|
||||||
#include "wmfs.h"
|
#include "wmfs.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "ewmh.h"
|
#include "ewmh.h"
|
||||||
@ -22,8 +15,7 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "layout.h"
|
#include "fifo.h"
|
||||||
#include "systray.h"
|
|
||||||
|
|
||||||
int
|
int
|
||||||
wmfs_error_handler(Display *d, XErrorEvent *event)
|
wmfs_error_handler(Display *d, XErrorEvent *event)
|
||||||
@ -161,16 +153,6 @@ wmfs_xinit(void)
|
|||||||
* Barwin linked list
|
* Barwin linked list
|
||||||
*/
|
*/
|
||||||
SLIST_INIT(&W->h.barwin);
|
SLIST_INIT(&W->h.barwin);
|
||||||
SLIST_INIT(&W->h.vbarwin);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Optional dep init
|
|
||||||
*/
|
|
||||||
#ifdef HAVE_IMLIB2
|
|
||||||
imlib_context_set_display(W->dpy);
|
|
||||||
imlib_context_set_visual(DefaultVisual(W->dpy, W->xscreen));
|
|
||||||
imlib_context_set_colormap(DefaultColormap(W->dpy, W->xscreen));
|
|
||||||
#endif /* HAVE_IMLIB2 */
|
|
||||||
|
|
||||||
W->flags |= WMFS_RUNNING;
|
W->flags |= WMFS_RUNNING;
|
||||||
}
|
}
|
||||||
@ -207,7 +189,7 @@ wmfs_scan(void)
|
|||||||
int i, n, rf, nscreen = 0;
|
int i, n, rf, nscreen = 0;
|
||||||
int tag = -1, screen = -1, flags = -1;
|
int tag = -1, screen = -1, flags = -1;
|
||||||
unsigned long ir, il;
|
unsigned long ir, il;
|
||||||
long *ret = NULL, *tret = NULL;
|
long *ret, *tret;
|
||||||
bool getg = false;
|
bool getg = false;
|
||||||
XWindowAttributes wa;
|
XWindowAttributes wa;
|
||||||
Window usl, usl2, *w = NULL, tm, focus;
|
Window usl, usl2, *w = NULL, tm, focus;
|
||||||
@ -221,7 +203,7 @@ wmfs_scan(void)
|
|||||||
if(XGetWindowProperty(W->dpy, W->root, W->net_atom[wmfs_current_tag], 0, 32,
|
if(XGetWindowProperty(W->dpy, W->root, W->net_atom[wmfs_current_tag], 0, 32,
|
||||||
False, XA_CARDINAL, &rt, &rf, &ir, &il,
|
False, XA_CARDINAL, &rt, &rf, &ir, &il,
|
||||||
(unsigned char**)&tret)
|
(unsigned char**)&tret)
|
||||||
== Success && tret)
|
== Success && ret)
|
||||||
{
|
{
|
||||||
nscreen = (int)ir;
|
nscreen = (int)ir;
|
||||||
}
|
}
|
||||||
@ -244,15 +226,6 @@ wmfs_scan(void)
|
|||||||
|
|
||||||
if(!wa.override_redirect && wa.map_state == IsViewable)
|
if(!wa.override_redirect && wa.map_state == IsViewable)
|
||||||
{
|
{
|
||||||
if(ewmh_get_xembed_state(w[i]))
|
|
||||||
{
|
|
||||||
systray_add(w[i]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ewmh_manage_window_type_desktop(w[i]))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(XGetWindowProperty(W->dpy, w[i], ATOM("_WMFS_TAG"), 0, 32,
|
if(XGetWindowProperty(W->dpy, w[i], ATOM("_WMFS_TAG"), 0, 32,
|
||||||
False, XA_CARDINAL, &rt, &rf, &ir, &il,
|
False, XA_CARDINAL, &rt, &rf, &ir, &il,
|
||||||
(unsigned char**)&ret)
|
(unsigned char**)&ret)
|
||||||
@ -320,16 +293,11 @@ wmfs_scan(void)
|
|||||||
if(getg)
|
if(getg)
|
||||||
c->flags |= CLIENT_IGNORE_LAYOUT;
|
c->flags |= CLIENT_IGNORE_LAYOUT;
|
||||||
|
|
||||||
|
client_map(c);
|
||||||
tag_client(tag_gb_id(c->screen, tag), c);
|
tag_client(tag_gb_id(c->screen, tag), c);
|
||||||
|
|
||||||
if(getg && tag <= TAILQ_LAST(&c->screen->tags, tsub)->id - 1)
|
if(getg)
|
||||||
client_moveresize(c, &g);
|
client_moveresize(c, &g);
|
||||||
/* In a removed tag */
|
|
||||||
else
|
|
||||||
{
|
|
||||||
c->geo = g;
|
|
||||||
layout_client(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
client_get_name(c);
|
client_get_name(c);
|
||||||
}
|
}
|
||||||
@ -360,10 +328,6 @@ wmfs_scan(void)
|
|||||||
if((fc = client_gb_win(focus)) && fc != W->client)
|
if((fc = client_gb_win(focus)) && fc != W->client)
|
||||||
client_focus(fc);
|
client_focus(fc);
|
||||||
|
|
||||||
SLIST_FOREACH(c, &W->h.client, next)
|
|
||||||
if(c->flags & CLIENT_TILED)
|
|
||||||
layout_fix_hole(c);
|
|
||||||
|
|
||||||
W->flags &= ~WMFS_SCAN;
|
W->flags &= ~WMFS_SCAN;
|
||||||
|
|
||||||
if(tret)
|
if(tret)
|
||||||
@ -373,26 +337,39 @@ wmfs_scan(void)
|
|||||||
XSync(W->dpy, false);
|
XSync(W->dpy, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
|
||||||
wmfs_sigchld(void)
|
|
||||||
{
|
|
||||||
if(W->flags & WMFS_SIGCHLD)
|
|
||||||
{
|
|
||||||
while(waitpid(-1, NULL, WNOHANG) > 0);
|
|
||||||
W->flags ^= WMFS_SIGCHLD;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
wmfs_loop(void)
|
wmfs_loop(void)
|
||||||
{
|
{
|
||||||
XEvent ev;
|
XEvent ev;
|
||||||
|
int maxfd, fd = ConnectionNumber(W->dpy);
|
||||||
|
fd_set iset;
|
||||||
|
|
||||||
while((W->flags & WMFS_RUNNING) && !XNextEvent(W->dpy, &ev))
|
while(W->flags & WMFS_RUNNING)
|
||||||
{
|
{
|
||||||
/* Manage SIGCHLD event here, X is not safe with it */
|
maxfd = fd + 1;
|
||||||
wmfs_sigchld();
|
|
||||||
EVENT_HANDLE(&ev);
|
FD_ZERO(&iset);
|
||||||
|
FD_SET(fd, &iset);
|
||||||
|
|
||||||
|
if(W->fifo.fd > 0)
|
||||||
|
{
|
||||||
|
maxfd += W->fifo.fd;
|
||||||
|
FD_SET(W->fifo.fd, &iset);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(select(maxfd, &iset, NULL, NULL, NULL) > 0)
|
||||||
|
{
|
||||||
|
if(FD_ISSET(fd, &iset))
|
||||||
|
{
|
||||||
|
while((W->flags & WMFS_RUNNING) && XPending(W->dpy))
|
||||||
|
{
|
||||||
|
XNextEvent(W->dpy, &ev);
|
||||||
|
EVENT_HANDLE(&ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(W->fifo.fd > 0 && FD_ISSET(W->fifo.fd, &iset))
|
||||||
|
fifo_read();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,6 +382,7 @@ wmfs_init(void)
|
|||||||
screen_init();
|
screen_init();
|
||||||
event_init();
|
event_init();
|
||||||
config_init();
|
config_init();
|
||||||
|
fifo_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -415,10 +393,16 @@ wmfs_quit(void)
|
|||||||
struct theme *t;
|
struct theme *t;
|
||||||
struct client *c;
|
struct client *c;
|
||||||
struct mousebind *m;
|
struct mousebind *m;
|
||||||
struct launcher *l;
|
|
||||||
|
|
||||||
|
/* Will free:
|
||||||
|
*
|
||||||
|
* Screens -> tags
|
||||||
|
* -> Infobars -> Elements
|
||||||
|
*/
|
||||||
ewmh_update_wmfs_props();
|
ewmh_update_wmfs_props();
|
||||||
|
|
||||||
|
screen_free();
|
||||||
|
|
||||||
XFreeGC(W->dpy, W->rgc);
|
XFreeGC(W->dpy, W->rgc);
|
||||||
|
|
||||||
while(!SLIST_EMPTY(&W->h.client))
|
while(!SLIST_EMPTY(&W->h.client))
|
||||||
@ -426,32 +410,29 @@ wmfs_quit(void)
|
|||||||
c = SLIST_FIRST(&W->h.client);
|
c = SLIST_FIRST(&W->h.client);
|
||||||
client_update_props(c, CPROP_LOC | CPROP_FLAG | CPROP_GEO);
|
client_update_props(c, CPROP_LOC | CPROP_FLAG | CPROP_GEO);
|
||||||
c->flags |= (CLIENT_IGNORE_LAYOUT | CLIENT_REMOVEALL);
|
c->flags |= (CLIENT_IGNORE_LAYOUT | CLIENT_REMOVEALL);
|
||||||
XMapWindow(W->dpy, c->win);
|
|
||||||
client_remove(c);
|
client_remove(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Will free:
|
|
||||||
*
|
|
||||||
* Screens -> tags
|
|
||||||
* -> Infobars -> Elements
|
|
||||||
*/
|
|
||||||
screen_free();
|
|
||||||
|
|
||||||
/* Conf stuffs */
|
/* Conf stuffs */
|
||||||
while(!SLIST_EMPTY(&W->h.theme))
|
while(!SLIST_EMPTY(&W->h.theme))
|
||||||
{
|
{
|
||||||
t = SLIST_FIRST(&W->h.theme);
|
t = SLIST_FIRST(&W->h.theme);
|
||||||
SLIST_REMOVE_HEAD(&W->h.theme, next);
|
SLIST_REMOVE_HEAD(&W->h.theme, next);
|
||||||
XFreeFontSet(W->dpy, t->font.fontset);
|
XFreeFontSet(W->dpy, t->font.fontset);
|
||||||
status_free_ctx(&t->tags_n_sl);
|
|
||||||
status_free_ctx(&t->tags_s_sl);
|
|
||||||
status_free_ctx(&t->tags_o_sl);
|
|
||||||
status_free_ctx(&t->tags_u_sl);
|
|
||||||
status_free_ctx(&t->client_n_sl);
|
|
||||||
status_free_ctx(&t->client_s_sl);
|
|
||||||
free(t);
|
free(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while(!SLIST_EMPTY(&W->h.rule))
|
||||||
|
{
|
||||||
|
r = SLIST_FIRST(&W->h.rule);
|
||||||
|
SLIST_REMOVE_HEAD(&W->h.rule, next);
|
||||||
|
free(r->class);
|
||||||
|
free(r->instance);
|
||||||
|
free(r->role);
|
||||||
|
free(r->name);
|
||||||
|
free(r);
|
||||||
|
}
|
||||||
|
|
||||||
while(!SLIST_EMPTY(&W->h.keybind))
|
while(!SLIST_EMPTY(&W->h.keybind))
|
||||||
{
|
{
|
||||||
k = SLIST_FIRST(&W->h.keybind);
|
k = SLIST_FIRST(&W->h.keybind);
|
||||||
@ -468,25 +449,11 @@ wmfs_quit(void)
|
|||||||
free(m);
|
free(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
while(!SLIST_EMPTY(&W->h.launcher))
|
/* FIFO stuffs */
|
||||||
|
if(W->fifo.fd > 0)
|
||||||
{
|
{
|
||||||
l = SLIST_FIRST(&W->h.launcher);
|
close(W->fifo.fd);
|
||||||
SLIST_REMOVE_HEAD(&W->h.launcher, next);
|
unlink(W->fifo.path);
|
||||||
free((void*)l->name);
|
|
||||||
free((void*)l->prompt);
|
|
||||||
free((void*)l->command);
|
|
||||||
free(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
while(!SLIST_EMPTY(&W->h.rule))
|
|
||||||
{
|
|
||||||
r = SLIST_FIRST(&W->h.rule);
|
|
||||||
SLIST_REMOVE_HEAD(&W->h.rule, next);
|
|
||||||
free(r->class);
|
|
||||||
free(r->instance);
|
|
||||||
free(r->role);
|
|
||||||
free(r->name);
|
|
||||||
free(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* close log */
|
/* close log */
|
||||||
@ -494,6 +461,8 @@ wmfs_quit(void)
|
|||||||
fclose(W->log), W->log = NULL;
|
fclose(W->log), W->log = NULL;
|
||||||
|
|
||||||
W->flags &= ~WMFS_RUNNING;
|
W->flags &= ~WMFS_RUNNING;
|
||||||
|
|
||||||
|
XCloseDisplay(W->dpy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Reload WMFS binary
|
/** Reload WMFS binary
|
||||||
@ -515,101 +484,41 @@ uicb_quit(Uicb cmd)
|
|||||||
W->flags &= ~WMFS_RUNNING;
|
W->flags &= ~WMFS_RUNNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
exec_uicb_function(Display *dpy, Window root, char *func, char *cmd)
|
|
||||||
{
|
|
||||||
Atom utf8s = XInternAtom(dpy, "UTF8_STRING", false);
|
|
||||||
XClientMessageEvent e = {
|
|
||||||
.type = ClientMessage,
|
|
||||||
.message_type = XInternAtom(dpy, "_WMFS_FUNCTION", false),
|
|
||||||
.window = root,
|
|
||||||
.format = 32,
|
|
||||||
.data.l[4] = true
|
|
||||||
};
|
|
||||||
|
|
||||||
XChangeProperty(dpy,root, XInternAtom(dpy, "_WMFS_FUNCTION", false), utf8s,
|
|
||||||
8, PropModeReplace, (unsigned char*)func, strlen(func));
|
|
||||||
|
|
||||||
if(!cmd)
|
|
||||||
cmd = "";
|
|
||||||
|
|
||||||
XChangeProperty(dpy, root, XInternAtom(dpy, "_WMFS_CMD", false), utf8s,
|
|
||||||
8, PropModeReplace, (unsigned char*)cmd, strlen(cmd));
|
|
||||||
|
|
||||||
XSendEvent(dpy, root, false, StructureNotifyMask, (XEvent*)&e);
|
|
||||||
XSync(dpy, False);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
signal_handle(int sig)
|
|
||||||
{
|
|
||||||
switch (sig)
|
|
||||||
{
|
|
||||||
case SIGQUIT:
|
|
||||||
case SIGTERM:
|
|
||||||
W->flags &= ~WMFS_RUNNING;
|
|
||||||
break;
|
|
||||||
case SIGCHLD:
|
|
||||||
W->flags |= WMFS_SIGCHLD;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
bool r;
|
bool r;
|
||||||
Display *dpy;
|
|
||||||
char path[MAX_PATH_LEN] = { 0 };
|
|
||||||
struct sigaction sa;
|
|
||||||
(void)argc;
|
(void)argc;
|
||||||
|
|
||||||
sprintf(path, "%s/"CONFIG_DEFAULT_PATH, getenv("HOME"));
|
|
||||||
|
|
||||||
/* Opt */
|
|
||||||
while((i = getopt(argc, argv, "hvC:c:")) != -1)
|
|
||||||
{
|
|
||||||
switch(i)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
case 'h':
|
|
||||||
printf("usage: %s [-hv] [-c <func> <cmd] [-C <file>]\n"
|
|
||||||
" -h Show this page\n"
|
|
||||||
" -v Show WMFS version\n"
|
|
||||||
" -c <func> <cmd> Execute a specified UICB function\n"
|
|
||||||
" -C <file> Launch WMFS with a specified configuration file\n", argv[0]);
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'v':
|
|
||||||
printf("wmfs("WMFS_VERSION") 2 beta\n");
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'c':
|
|
||||||
if(!(dpy = XOpenDisplay(NULL)))
|
|
||||||
{
|
|
||||||
fprintf(stderr, "%s: Can't open X server\n", argv[0]);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
exec_uicb_function(dpy, DefaultRootWindow(dpy), optarg, argv[optind]);
|
|
||||||
|
|
||||||
XCloseDisplay(dpy);
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'C':
|
|
||||||
strncpy(path, optarg, MAX_PATH_LEN);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
W = (struct wmfs*)xcalloc(1, sizeof(struct wmfs));
|
W = (struct wmfs*)xcalloc(1, sizeof(struct wmfs));
|
||||||
|
|
||||||
/* Default path ~/.config/wmfs/wmfsrc */
|
/* Default path ~/.config/wmfs/wmfsrc */
|
||||||
W->confpath = path;
|
sprintf(W->confpath, "%s/"CONFIG_DEFAULT_PATH, getenv("HOME"));
|
||||||
|
|
||||||
|
/* Opt */
|
||||||
|
while((i = getopt(argc, argv, "hvC:")) != -1)
|
||||||
|
{
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
case 'h':
|
||||||
|
printf("usage: %s [-hv] [-C <file>]\n"
|
||||||
|
" -h Show this page\n"
|
||||||
|
" -v Show WMFS version\n"
|
||||||
|
" -C <file> Launch WMFS with a specified configuration file\n", argv[0]);
|
||||||
|
free(W);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
printf("wmfs("WMFS_VERSION") 2 beta\n");
|
||||||
|
free(W);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
strncpy(W->confpath, optarg, sizeof(W->confpath));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Get X display */
|
/* Get X display */
|
||||||
if(!(W->dpy = XOpenDisplay(NULL)))
|
if(!(W->dpy = XOpenDisplay(NULL)))
|
||||||
@ -618,14 +527,6 @@ main(int argc, char **argv)
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set signal handler */
|
|
||||||
memset(&sa, 0, sizeof(sa));
|
|
||||||
sa.sa_handler = signal_handle;
|
|
||||||
sigemptyset(&sa.sa_mask);
|
|
||||||
sigaction(SIGQUIT, &sa, NULL);
|
|
||||||
sigaction(SIGTERM, &sa, NULL);
|
|
||||||
sigaction(SIGCHLD, &sa, NULL);
|
|
||||||
|
|
||||||
/* Core */
|
/* Core */
|
||||||
wmfs_init();
|
wmfs_init();
|
||||||
wmfs_scan();
|
wmfs_scan();
|
||||||
@ -638,7 +539,5 @@ main(int argc, char **argv)
|
|||||||
if(r)
|
if(r)
|
||||||
execvp(argv[0], argv);
|
execvp(argv[0], argv);
|
||||||
|
|
||||||
XCloseDisplay(W->dpy);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
116
src/wmfs.h
116
src/wmfs.h
@ -92,51 +92,26 @@ struct barwin
|
|||||||
Color fg, bg;
|
Color fg, bg;
|
||||||
void *ptr; /* Special cases */
|
void *ptr; /* Special cases */
|
||||||
SLIST_HEAD(mbhead, mousebind) mousebinds;
|
SLIST_HEAD(mbhead, mousebind) mousebinds;
|
||||||
SLIST_HEAD(, mousebind) statusmousebinds;
|
|
||||||
SLIST_ENTRY(barwin) next; /* global barwin */
|
SLIST_ENTRY(barwin) next; /* global barwin */
|
||||||
SLIST_ENTRY(barwin) enext; /* element barwin */
|
SLIST_ENTRY(barwin) enext; /* element barwin */
|
||||||
SLIST_ENTRY(barwin) vnext; /* volatile barwin */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct status_seq
|
struct status_seq
|
||||||
{
|
{
|
||||||
struct geo geo;
|
struct geo geo;
|
||||||
enum position align;
|
enum position align;
|
||||||
int data[4];
|
|
||||||
char type;
|
char type;
|
||||||
char *str;
|
char *str;
|
||||||
Color color, color2;
|
Color color;
|
||||||
SLIST_HEAD(, mousebind) mousebinds;
|
SLIST_HEAD(, mousebind) mousebinds;
|
||||||
SLIST_ENTRY(status_seq) next;
|
SLIST_ENTRY(status_seq) next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct status_ctx
|
|
||||||
{
|
|
||||||
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
|
|
||||||
{
|
|
||||||
char *name;
|
|
||||||
int *datas;
|
|
||||||
int ndata;
|
|
||||||
SLIST_ENTRY(status_gcache) next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct element
|
struct element
|
||||||
{
|
{
|
||||||
struct geo geo;
|
struct geo geo;
|
||||||
struct infobar *infobar;
|
struct infobar *infobar;
|
||||||
struct status_ctx *statusctx;
|
|
||||||
int type;
|
int type;
|
||||||
char *data;
|
|
||||||
enum position align;
|
enum position align;
|
||||||
void (*func_init)(struct element *e);
|
void (*func_init)(struct element *e);
|
||||||
void (*func_update)(struct element *e);
|
void (*func_update)(struct element *e);
|
||||||
@ -150,11 +125,12 @@ struct infobar
|
|||||||
struct geo geo;
|
struct geo geo;
|
||||||
struct screen *screen;
|
struct screen *screen;
|
||||||
struct theme *theme;
|
struct theme *theme;
|
||||||
struct status_ctx statusctx;
|
enum barpos pos;
|
||||||
enum barpos opos, pos;
|
|
||||||
char *elemorder;
|
char *elemorder;
|
||||||
char *name;
|
char *name;
|
||||||
|
char *status;
|
||||||
TAILQ_HEAD(esub, element) elements;
|
TAILQ_HEAD(esub, element) elements;
|
||||||
|
SLIST_HEAD(, status_seq) statushead;
|
||||||
SLIST_ENTRY(infobar) next;
|
SLIST_ENTRY(infobar) next;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -162,9 +138,8 @@ struct screen
|
|||||||
{
|
{
|
||||||
struct geo geo, ugeo;
|
struct geo geo, ugeo;
|
||||||
struct tag *seltag;
|
struct tag *seltag;
|
||||||
#define SCREEN_TAG_UPDATE 0x01
|
|
||||||
Flags flags;
|
|
||||||
int id;
|
int id;
|
||||||
|
Flags elemupdate;
|
||||||
TAILQ_HEAD(tsub, tag) tags;
|
TAILQ_HEAD(tsub, tag) tags;
|
||||||
SLIST_HEAD(, infobar) infobars;
|
SLIST_HEAD(, infobar) infobars;
|
||||||
SLIST_ENTRY(screen) next;
|
SLIST_ENTRY(screen) next;
|
||||||
@ -178,11 +153,8 @@ struct tag
|
|||||||
struct client *sel;
|
struct client *sel;
|
||||||
struct client *prevsel;
|
struct client *prevsel;
|
||||||
struct tag *prev;
|
struct tag *prev;
|
||||||
struct status_ctx statusctx;
|
|
||||||
char *name;
|
char *name;
|
||||||
int id;
|
int id;
|
||||||
#define TAG_URGENT 0x01
|
|
||||||
#define TAG_IGNORE_ENTER 0x02
|
|
||||||
Flags flags;
|
Flags flags;
|
||||||
SLIST_HEAD(, client) clients;
|
SLIST_HEAD(, client) clients;
|
||||||
TAILQ_HEAD(ssub, layout_set) sets;
|
TAILQ_HEAD(ssub, layout_set) sets;
|
||||||
@ -213,10 +185,6 @@ struct client
|
|||||||
#define CLIENT_REMOVEALL 0x200
|
#define CLIENT_REMOVEALL 0x200
|
||||||
#define CLIENT_MAPPED 0x400
|
#define CLIENT_MAPPED 0x400
|
||||||
#define CLIENT_FULLSCREEN 0x800
|
#define CLIENT_FULLSCREEN 0x800
|
||||||
#define CLIENT_FREE 0x1000
|
|
||||||
#define CLIENT_TILED 0x2000
|
|
||||||
#define CLIENT_MOUSE 0x4000
|
|
||||||
#define CLIENT_IGNORE_TAG 0x8000
|
|
||||||
Flags flags;
|
Flags flags;
|
||||||
Window win, frame, tmp;
|
Window win, frame, tmp;
|
||||||
SLIST_ENTRY(client) next; /* Global list */
|
SLIST_ENTRY(client) next; /* Global list */
|
||||||
@ -267,14 +235,12 @@ struct theme
|
|||||||
int bars_width;
|
int bars_width;
|
||||||
|
|
||||||
/* struct elements */
|
/* struct elements */
|
||||||
struct colpair tags_n, tags_s, tags_o, tags_u; /* normal / selected / occupied */
|
struct colpair tags_n, tags_s; /* normal / selected */
|
||||||
struct status_ctx tags_n_sl, tags_s_sl, tags_o_sl, tags_u_sl; /* status line */
|
|
||||||
int tags_border_width;
|
int tags_border_width;
|
||||||
Color tags_border_col;
|
Color tags_border_col;
|
||||||
|
|
||||||
/* client / frame */
|
/* client / frame */
|
||||||
struct colpair client_n, client_s;
|
struct colpair client_n, client_s;
|
||||||
struct status_ctx client_n_sl, client_s_sl, client_f_sl;
|
|
||||||
Color frame_bg;
|
Color frame_bg;
|
||||||
int client_titlebar_width;
|
int client_titlebar_width;
|
||||||
int client_border_width;
|
int client_border_width;
|
||||||
@ -291,38 +257,12 @@ struct rule
|
|||||||
char *name;
|
char *name;
|
||||||
int tag, screen;
|
int tag, screen;
|
||||||
#define RULE_FREE 0x01
|
#define RULE_FREE 0x01
|
||||||
#define RULE_TAB 0x02
|
#define RULE_MAX 0x02
|
||||||
#define RULE_IGNORE_TAG 0x04
|
#define RULE_IGNORE_TAG 0x04
|
||||||
Flags flags;
|
Flags flags;
|
||||||
SLIST_ENTRY(rule) next;
|
SLIST_ENTRY(rule) next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct launcher
|
|
||||||
{
|
|
||||||
char *name;
|
|
||||||
char *prompt;
|
|
||||||
char *command;
|
|
||||||
#define HISTOLEN 64
|
|
||||||
char histo[HISTOLEN][256];
|
|
||||||
int nhisto;
|
|
||||||
int width;
|
|
||||||
SLIST_ENTRY(launcher) next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct launcher_ccache
|
|
||||||
{
|
|
||||||
char *start;
|
|
||||||
char **namelist;
|
|
||||||
size_t hits;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _systray
|
|
||||||
{
|
|
||||||
struct geo geo;
|
|
||||||
Window win;
|
|
||||||
SLIST_ENTRY(_systray) next;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MAX_PATH_LEN 8192
|
#define MAX_PATH_LEN 8192
|
||||||
|
|
||||||
struct wmfs
|
struct wmfs
|
||||||
@ -333,30 +273,23 @@ struct wmfs
|
|||||||
int xscreen, xdepth;
|
int xscreen, xdepth;
|
||||||
int xmaxw, xmaxh;
|
int xmaxw, xmaxh;
|
||||||
int nscreen;
|
int nscreen;
|
||||||
unsigned int client_mod;
|
|
||||||
Flags numlockmask;
|
Flags numlockmask;
|
||||||
#define WMFS_SCAN 0x001
|
#define WMFS_SCAN 0x01
|
||||||
#define WMFS_RUNNING 0x002
|
#define WMFS_RUNNING 0x02
|
||||||
#define WMFS_RELOAD 0x004
|
#define WMFS_RELOAD 0x04
|
||||||
#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;
|
Flags flags;
|
||||||
GC gc, rgc;
|
GC gc, rgc;
|
||||||
Atom *net_atom;
|
Atom *net_atom;
|
||||||
char **argv;
|
char **argv;
|
||||||
char *confpath;
|
char confpath[MAX_PATH_LEN];
|
||||||
struct barwin *last_clicked_barwin;
|
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;
|
/* FIFO stuffs */
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
char *path;
|
||||||
|
int fd;
|
||||||
|
} fifo;
|
||||||
|
|
||||||
/* Log file */
|
/* Log file */
|
||||||
FILE *log;
|
FILE *log;
|
||||||
@ -371,8 +304,6 @@ struct wmfs
|
|||||||
SLIST_HEAD(, theme) theme;
|
SLIST_HEAD(, theme) theme;
|
||||||
SLIST_HEAD(, rule) rule;
|
SLIST_HEAD(, rule) rule;
|
||||||
SLIST_HEAD(, mousebind) mousebind;
|
SLIST_HEAD(, mousebind) mousebind;
|
||||||
SLIST_HEAD(, launcher) launcher;
|
|
||||||
SLIST_HEAD(, barwin) vbarwin;
|
|
||||||
} h;
|
} h;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -387,19 +318,6 @@ struct wmfs
|
|||||||
struct mbhead root;
|
struct mbhead root;
|
||||||
} tmp_head;
|
} 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
|
* Selected screen, client
|
||||||
*/
|
*/
|
||||||
|
|||||||
788
wmfs.1
788
wmfs.1
@ -1,788 +0,0 @@
|
|||||||
.\" title: wmfs
|
|
||||||
.\" dev: xorg62
|
|
||||||
.\" man: arpinux
|
|
||||||
.\"
|
|
||||||
.TH "WMFS" "1" "2012/05/02" "wmfs" "manual of wmfs"
|
|
||||||
.\" disable hyphenation
|
|
||||||
.nh
|
|
||||||
.\" disable justification (adjust text to left margin only)
|
|
||||||
.ad l
|
|
||||||
.SH "NAME"
|
|
||||||
wmfs \- Window Manager From Scratch
|
|
||||||
.SH "SYNOPSIS"
|
|
||||||
\fBwmfs\fR [\fB\-hv\fR] [\fB\-C <file>\fR] [\fB\-c <uicb_function> <cmd>\fR]
|
|
||||||
.sp
|
|
||||||
.SH "DESCRIPTION"
|
|
||||||
\fBWMFS\fR is a lightweight and highly configurable tiling window manager for X written in C\&.
|
|
||||||
.sp
|
|
||||||
.SH "OPTIONS"
|
|
||||||
.PP
|
|
||||||
\fB\-C <file>\fR
|
|
||||||
.RS 4
|
|
||||||
Load a configuration file\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\-c <uicb_function> <cmd>\fR
|
|
||||||
.RS 4
|
|
||||||
Execute an uicb function to control WMFS\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\-v\fR
|
|
||||||
.RS 4
|
|
||||||
Print version information to standard output, then exit\&.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fB\-h\fR
|
|
||||||
.RS 4
|
|
||||||
Print help information, then exit\&.
|
|
||||||
.RE
|
|
||||||
.SH "DEFAULT KEY BINDINGS"
|
|
||||||
.PP
|
|
||||||
\fBControl\-Alt + r\fR
|
|
||||||
.RS 4
|
|
||||||
Reload WMFS binary
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper + Return\fR
|
|
||||||
.RS 4
|
|
||||||
Run a terminal (urxvt by default)
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper + q\fR
|
|
||||||
.RS 4
|
|
||||||
Quit the selected client
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBControl\-Alt + q\fR
|
|
||||||
.RS 4
|
|
||||||
Exit WMFS
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper + f \fR
|
|
||||||
.RS 4
|
|
||||||
Toggle free the selected client
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper + Shift + f \fR
|
|
||||||
.RS 4
|
|
||||||
Toggle ignore_tag the selected client
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper + Shift + h \fR
|
|
||||||
.RS 4
|
|
||||||
Toggle infobar visibility
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBAlt + Tab\fR
|
|
||||||
.RS 4
|
|
||||||
Give the focus to the next client
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBAlt\-Shift + Tab\fR
|
|
||||||
.RS 4
|
|
||||||
Give the focus to the previous client
|
|
||||||
.RE
|
|
||||||
.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
|
|
||||||
.RS 4
|
|
||||||
Next tag
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBControl + Left\fR
|
|
||||||
.RS 4
|
|
||||||
Previous tag
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBControl + Up\fR
|
|
||||||
.RS 4
|
|
||||||
Next screen
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBControl + Down\fR
|
|
||||||
.RS 4
|
|
||||||
Previous screen
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper + m\fR
|
|
||||||
.RS 4
|
|
||||||
Vertical mirror layout
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper\-Shift + m\fR
|
|
||||||
.RS 4
|
|
||||||
Horizontal mirror layout
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper + r\fR
|
|
||||||
.RS 4
|
|
||||||
Rotate layout right
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper\-Shift + r\fR
|
|
||||||
.RS 4
|
|
||||||
Rotate layout left
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper\-Control\-Alt + h\fR
|
|
||||||
.RS 4
|
|
||||||
Integrate client in left layout
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper\-Control\-Alt + j\fR
|
|
||||||
.RS 4
|
|
||||||
Integrate client in bottom layout
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper\-Control\-Alt + k\fR
|
|
||||||
.RS 4
|
|
||||||
Integrate client in top layout
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper\-Control\-Alt + l\fR
|
|
||||||
.RS 4
|
|
||||||
Integrate client in right layout
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper + o\fR
|
|
||||||
.RS 4
|
|
||||||
Restore previous layout
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper\-Shift + o\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
|
|
||||||
Change tag view
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper\-Shift + F[1\&.\&.9]\fR
|
|
||||||
.RS 4
|
|
||||||
Transfert the selected client to the wanted tag
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper + -\fR
|
|
||||||
.RS 4
|
|
||||||
Delete current tag\fR
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fBSuper\-Shift + -\fR
|
|
||||||
.RS 4
|
|
||||||
Add current tag\fR
|
|
||||||
.RE
|
|
||||||
.SH "CONFIGURATION"
|
|
||||||
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
|
|
||||||
.SH "BUGS"
|
|
||||||
WMFS isn\'t stable for now\&. So it certainly contains some bugs\&.
|
|
||||||
.sp
|
|
||||||
.SH "AUTHOR"
|
|
||||||
Martin Duquesnoy <\fIxorg62@gmail\&.com\fR\&[1]>\&.
|
|
||||||
.sp
|
|
||||||
.SH "WWW"
|
|
||||||
Main site: \fIhttps://github\&.com/xorg62/wmfs\fR
|
|
||||||
.PP
|
|
||||||
Wiki: \fIhttps://github\&.com/xorg62/wmfs/wiki\fR
|
|
||||||
.PP
|
|
||||||
Bug tracker: \fIhttps://github\&.com/xorg62/wmfs/issues\fR
|
|
||||||
.sp
|
|
||||||
.SH "COPYING"
|
|
||||||
WMFS is under the BSD license\&. See COPYING for more information\&.
|
|
||||||
.RE
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
[Desktop Entry]
|
|
||||||
Encoding=UTF-8
|
|
||||||
Type=Application
|
|
||||||
Name=wmfs
|
|
||||||
Comment=Window Manager From Scratch
|
|
||||||
TryExec=wmfs
|
|
||||||
Exec=wmfs
|
|
||||||
52
wmfs.vim
Normal file
52
wmfs.vim
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
" Vim syntax file
|
||||||
|
" Language: WMFS Configuration file
|
||||||
|
" Maintainer: David Delassus <david.jose.delassus@gmail.com>
|
||||||
|
" Latest Revision: 17 October 2011
|
||||||
|
|
||||||
|
if exists("b:current_syntax")
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
syn case ignore
|
||||||
|
|
||||||
|
" Keywords
|
||||||
|
syn keyword wmfsBlockTheme font
|
||||||
|
syn keyword wmfsBlockThemeBars bars_width bars_fg bars_bg
|
||||||
|
syn keyword wmfsBlockThemeTags tags_normal_fg tags_normal_bg tags_sel_fg tags_sel_bg tags_border_color tags_border_width
|
||||||
|
syn keyword wmfsBlockThemeClient client_normal_fg client_normal_bg client_sel_fg client_sel_bg frame_bg client_titlebar_width client_border_width
|
||||||
|
|
||||||
|
syn keyword wmfsBlockBar position screen elements theme
|
||||||
|
|
||||||
|
syn keyword wmfsBlockTag screen name
|
||||||
|
|
||||||
|
syn keyword wmfsBlockKey mod key func cmd
|
||||||
|
|
||||||
|
syn keyword wmfsTodo contained TODO FIXME XXX NOTE
|
||||||
|
|
||||||
|
" Matches
|
||||||
|
syn match wmfsNumber /\S\@<!\d\+\(\.\d\+\)\?\(\S\@!\|}\@=\)/ nextgroup=wmfsNumber
|
||||||
|
syn match wmfsNumber '\d\+' contained display
|
||||||
|
syn match wmfsNumber '[-+]\d\+' contained display
|
||||||
|
|
||||||
|
" Regions
|
||||||
|
syn region wmfsComment start="#" end="$" contains=wmfsTodo
|
||||||
|
syn region wmfsString start='"' end='"' contains=CONTAINED
|
||||||
|
syn region wmfsSection start="\[" end="\]"
|
||||||
|
syn region wmfsList start="{" end="}" contains=wmfsNumber,wmfsString
|
||||||
|
|
||||||
|
let b:current_syntax = "wmfs"
|
||||||
|
|
||||||
|
hi def link wmfsTodo Todo
|
||||||
|
hi def link wmfsComment Comment
|
||||||
|
hi def link wmfsSection Statement
|
||||||
|
hi def link wmfsList Statement
|
||||||
|
hi def link wmfsNumber Number
|
||||||
|
hi def link wmfsString String
|
||||||
|
|
||||||
|
hi def link wmfsBlockTheme Identifier
|
||||||
|
hi def link wmfsBlockThemeBars Identifier
|
||||||
|
hi def link wmfsBlockThemeTags Identifier
|
||||||
|
hi def link wmfsBlockThemeClient Identifier
|
||||||
|
hi def link wmfsBlockBar Identifier
|
||||||
|
hi def link wmfsBlockTag Identifier
|
||||||
|
hi def link wmfsBlockKey Identifier
|
||||||
93
wmfsrc
93
wmfsrc
@ -22,34 +22,16 @@
|
|||||||
# Element tags
|
# Element tags
|
||||||
tags_normal_fg = "#AABBAA"
|
tags_normal_fg = "#AABBAA"
|
||||||
tags_normal_bg = "#223322"
|
tags_normal_bg = "#223322"
|
||||||
# tags_normal_statusline = ""
|
|
||||||
|
|
||||||
tags_sel_fg = "#223322"
|
tags_sel_fg = "#223322"
|
||||||
tags_sel_bg = "#AABBAA"
|
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_color = "#112211"
|
||||||
tags_border_width = 1
|
tags_border_width = 1
|
||||||
|
|
||||||
# Frame / Client
|
# Frame / Client
|
||||||
client_normal_fg = "#AABBAA"
|
client_normal_fg = "#AABBAA"
|
||||||
client_normal_bg = "#223322"
|
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_fg = "#223322"
|
||||||
client_sel_bg = "#AABBAA"
|
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"
|
frame_bg = "#555555"
|
||||||
client_titlebar_width = 12
|
client_titlebar_width = 12
|
||||||
client_border_width = 1
|
client_border_width = 1
|
||||||
@ -70,13 +52,11 @@
|
|||||||
#
|
#
|
||||||
# t Tags
|
# t Tags
|
||||||
# s Statustext (will take available space)
|
# 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]
|
[bar]
|
||||||
position = 0
|
position = 0
|
||||||
screen = 0
|
screen = 0
|
||||||
elements = "tlsy" # element order in bar
|
elements = "ts" # element order in bar
|
||||||
theme = "default"
|
theme = "default"
|
||||||
[/bar]
|
[/bar]
|
||||||
|
|
||||||
@ -91,14 +71,10 @@
|
|||||||
|
|
||||||
[tags]
|
[tags]
|
||||||
|
|
||||||
# Tag wrapping navigation
|
|
||||||
circular = false
|
|
||||||
|
|
||||||
# Use no screen option or screen = -1 to set tag on each screen
|
# Use no screen option or screen = -1 to set tag on each screen
|
||||||
[tag]
|
[tag]
|
||||||
screen = -1
|
screen = -1
|
||||||
name = "1"
|
name = "1"
|
||||||
# statusline=""
|
|
||||||
[/tag]
|
[/tag]
|
||||||
|
|
||||||
[tag] name = "2" [/tag]
|
[tag] name = "2" [/tag]
|
||||||
@ -118,34 +94,16 @@
|
|||||||
|
|
||||||
[client]
|
[client]
|
||||||
|
|
||||||
# Padding between clients (default: 0) :
|
[mouse] button = "1" func = "client_focus_click" [/mouse]
|
||||||
#padding = 75
|
[mouse] button = "1" func = "mouse_swap" [/mouse]
|
||||||
|
[mouse] button = "2" func = "mouse_tab" [/mouse]
|
||||||
# Give focus to new created client (default = false)
|
[mouse] button = "3" func = "mouse_resize" [/mouse]
|
||||||
autofocus = false
|
|
||||||
|
|
||||||
theme = "default"
|
|
||||||
key_modifier = "Super"
|
|
||||||
|
|
||||||
# Focus type:
|
|
||||||
# enter : focus follow mouse (default)
|
|
||||||
# click : click to focus
|
|
||||||
# everything-else : disable mouse focus support
|
|
||||||
focus = enter
|
|
||||||
|
|
||||||
[mouse] button = "1" func = "client_focus_click" [/mouse]
|
|
||||||
[mouse] button = "1" func = "mouse_swap" [/mouse]
|
|
||||||
[mouse] button = "2" func = "mouse_tab" [/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]
|
|
||||||
|
|
||||||
[/client]
|
[/client]
|
||||||
|
|
||||||
[rules]
|
[rules]
|
||||||
|
|
||||||
[rule]
|
[rule]
|
||||||
# use instance = "*" for a all-clients rule
|
|
||||||
instance = "chromium"
|
instance = "chromium"
|
||||||
|
|
||||||
# role = ""
|
# role = ""
|
||||||
@ -156,28 +114,12 @@
|
|||||||
screen = 0
|
screen = 0
|
||||||
|
|
||||||
free = false
|
free = false
|
||||||
tab = false
|
max = false
|
||||||
ignore_tag = false
|
ignore_tag = false
|
||||||
[/rule]
|
[/rule]
|
||||||
|
|
||||||
[/rules]
|
[/rules]
|
||||||
|
|
||||||
[launchers]
|
|
||||||
|
|
||||||
# command can be an uicb function or an uicb function + extension (see example)
|
|
||||||
[launcher]
|
|
||||||
name = "exec"
|
|
||||||
prompt = "Run:"
|
|
||||||
|
|
||||||
# Example of uicb + ext:
|
|
||||||
# command = "spawn xterm -e"
|
|
||||||
command = "spawn"
|
|
||||||
|
|
||||||
width = 150
|
|
||||||
[/launcher]
|
|
||||||
|
|
||||||
[/launchers]
|
|
||||||
|
|
||||||
[keys]
|
[keys]
|
||||||
|
|
||||||
[key] mod = {"Super"} key = "Return" func = "spawn" cmd = "urxvt || xterm" [/key]
|
[key] mod = {"Super"} key = "Return" func = "spawn" cmd = "urxvt || xterm" [/key]
|
||||||
@ -204,9 +146,6 @@
|
|||||||
[key] mod = {"Super", "Shift"} key = "F7" func = "tag_client" cmd = "6" [/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", "Shift"} key = "F8" func = "tag_client" cmd = "7" [/key]
|
||||||
|
|
||||||
[key] mod = {"Super"} key = "minus" func = "tag_del" [/key]
|
|
||||||
[key] mod = {"Super", "Shift"} key = "minus" func = "tag_new" [/key]
|
|
||||||
|
|
||||||
# tag function: cmd = nameofthetag
|
# tag function: cmd = nameofthetag
|
||||||
#[key] mod = {"Super"} key = "z" func = "tag" cmd = "2" [/key]
|
#[key] mod = {"Super"} key = "z" func = "tag" cmd = "2" [/key]
|
||||||
|
|
||||||
@ -252,7 +191,6 @@
|
|||||||
[key] mod = {"Alt", "Shift"} key = "k" func = "client_tab_top" [/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 = "j" func = "client_tab_bottom" [/key]
|
||||||
[key] mod = {"Alt", "Shift"} key = "u" func = "client_untab" [/key]
|
[key] mod = {"Alt", "Shift"} key = "u" func = "client_untab" [/key]
|
||||||
[key] mod = {"Super"} key = "t" func = "client_tab_next_opened" [/key]
|
|
||||||
|
|
||||||
# Layout manipulation
|
# Layout manipulation
|
||||||
[key] mod = {"Super"} key = "m" func = "layout_vmirror" [/key]
|
[key] mod = {"Super"} key = "m" func = "layout_vmirror" [/key]
|
||||||
@ -260,25 +198,8 @@
|
|||||||
[key] mod = {"Super"} key = "r" func = "layout_rotate_right" [/key]
|
[key] mod = {"Super"} key = "r" func = "layout_rotate_right" [/key]
|
||||||
[key] mod = {"Super", "Shift"} key = "r" func = "layout_rotate_left" [/key]
|
[key] mod = {"Super", "Shift"} key = "r" func = "layout_rotate_left" [/key]
|
||||||
|
|
||||||
[key] mod = {"Control", "Super", "Alt"} key = "h" func = "layout_integrate_left" [/key]
|
|
||||||
[key] mod = {"Control", "Super", "Alt"} key = "j" func = "layout_integrate_bottom" [/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)
|
# Layout set historic travelling function (TESTING)
|
||||||
[key] mod = {"Super"} key = "o" func = "layout_prev_set" [/key]
|
[key] mod = {"Super"} key = "o" func = "layout_prev_set" [/key]
|
||||||
[key] mod = {"Super", "Shift"} key = "o" func = "layout_next_set" [/key]
|
[key] mod = {"Super"} key = "p" func = "layout_next_set" [/key]
|
||||||
|
|
||||||
# Toggle client free/tile
|
|
||||||
[key] mod = {"Super"} key = "f" func = "client_toggle_free" [/key]
|
|
||||||
|
|
||||||
# Toggle client ignore_tag
|
|
||||||
[key] mod = {"Super", "Shift"} key = "f" func = "client_toggle_ignore_tag" [/key]
|
|
||||||
|
|
||||||
# Toggle infobar visibility
|
|
||||||
[key] mod = {"Super", "Shift"} key = "h" func = "infobar_toggle_hide" cmd = "default" [/key]
|
|
||||||
|
|
||||||
# Launcher
|
|
||||||
[key] mod = {"Super"} key = "p" func = "launcher" cmd = "exec" [/key]
|
|
||||||
|
|
||||||
[/keys]
|
[/keys]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user