35 Commits
Author SHA1 Message Date
Martin Duquesnoy eb2dea3a1c Merge pull request #72 from MicroJoe/gh-pages
Add MicroJoe in authors section
2012-08-09 08:41:19 -07:00
Romain Porte c63c12d280 Added MicroJoe in authors section 2012-08-08 16:26:14 +02:00
arnault a081d18e49 add kidanger in authors section 2012-04-20 17:23:01 +02:00
arnault 3920c55f56 remove header shadow - not well dispayed in all browsers 2012-04-01 18:02:19 +02:00
arnault 780de544bc add irc link in support section 2012-02-24 17:31:53 +01:00
arnault 135108b3cb fix irc link 2012-02-24 17:10:55 +01:00
arnault fd16abfa07 add irc page 2012-02-24 17:09:02 +01:00
arnault 1bd6c770a3 test basic favicon 2012-02-22 19:13:40 +01:00
arnault 151a3d41f3 add basic favicon 2012-02-22 19:11:39 +01:00
arnault 965bb197aa remove transparency from favicon 2012-02-22 19:02:33 +01:00
arnault 45b7d02401 change favicon 2012-02-22 18:53:38 +01:00
arnault d80dcd0b0c fix git code 2012-02-22 15:55:44 +01:00
arnault aee8d91837 fix link and add titles 2012-02-22 15:44:05 +01:00
arnault 9c09a0c958 add git link 2012-02-22 15:38:32 +01:00
arnault 870f6ac0ce update logo 2012-02-14 20:06:16 +01:00
arnault f4329419f5 add 6pi in authors 2012-02-14 17:56:04 +01:00
arnault f98a404837 clear and cmpact css 2012-02-14 17:40:37 +01:00
arnault 14b414447a add tar download link 2012-02-13 21:17:28 +01:00
arnault fc3a15fb0e fix slideshow offset + fix doxnload link + add support section 2012-02-13 21:05:37 +01:00
arnault 31db953491 fix download link 2012-02-13 16:02:03 +01:00
arnault 2610380b32 add content to homepage 2012-02-13 13:30:55 +01:00
Martin Duquesnoy 95270b2afe CNAME 2012-02-13 02:18:24 +01:00
Martin Duquesnoy 77861f6cc6 cname 2012-02-12 23:57:04 +01:00
Martin Duquesnoy 20c2c25a66 CNAME 2012-02-12 23:18:39 +01:00
Martin Duquesnoy 5955579c99 CNAME 2012-02-12 23:06:01 +01:00
Martin Duquesnoy eeac90402d CNAME 2012-02-12 23:02:41 +01:00
Martin Duquesnoy e74081a234 page 2012-02-12 21:57:00 +01:00
Martin Duquesnoy 46fe901a0e cname 2012-02-12 21:47:23 +01:00
Martin Duquesnoy 4ff82cae8b add 2012-02-12 21:41:12 +01:00
Martin Duquesnoy 8fbd096923 Arpinux webpages 2012-02-12 21:38:57 +01:00
Martin Duquesnoy a72d232db3 page 2012-02-12 21:06:04 +01:00
Martin Duquesnoy 2c4b6db3b0 page 2012-02-12 21:05:35 +01:00
Martin Duquesnoy 17967150c0 page 2012-02-12 21:05:19 +01:00
Martin Duquesnoy 1f572b9e9a page 2012-02-12 21:04:02 +01:00
Martin Duquesnoy 49ce029ea2 Created gh-pages branch via GitHub 2012-02-11 17:52:45 -08:00
76 changed files with 349 additions and 14058 deletions
-11
View File
@@ -1,11 +0,0 @@
*.o
.*.sw?
wmfs
#*
\#*
wmfs.1.gz
tags
*.patch
*.diff
Makefile
build/
-134
View File
@@ -1,134 +0,0 @@
#
# CMake for wmfs David Demelier <markand@malikania.fr>
#
# General settings
cmake_minimum_required(VERSION 2.8)
project(wmfs)
set(CMAKE_C_FLAGS_RELEASE "-Wall")
set(CMAKE_C_FLAGS_DEBUG "-Wall -g -ansi -pendantic -O3 -funroll-loops")
# General option
option(WITH_XINERAMA "Build with X.Org xinerama support" ON)
option(WITH_XRANDR "Build with X.Org xrandr support" ON)
option(WITH_XFT "Build with X.Org xft support" ON)
option(WITH_IMLIB2 "Build with imlib2 graphic library" ON)
# WMFS Version and XDG directory
set(WMFS_VERSION "201106")
if (NOT XDG_CONFIG_DIR)
set(XDG_CONFIG_DIR "${CMAKE_INSTALL_PREFIX}/etc/wmfs")
endif ()
# Man prefix
if (NOT MANPREFIX)
set(MANPREFIX "${CMAKE_INSTALL_PREFIX}/share")
endif ()
# Libraries are optional
find_package(X11)
if (NOT X11_FOUND)
message(FATAL_ERROR "You need x11 libraries to build wmfs")
else ()
list(APPEND INCLUDES ${X11_INCLUDE_DIR})
list(APPEND LIBRARIES ${X11_LIBRARIES})
endif ()
# pthread is needed
set(CMAKE_THREAD_PREFER_PTHREAD)
find_package(Threads)
if (NOT CMAKE_USE_PTHREADS_INIT)
message(FATAL_ERROR "You need pthread libraries to build wmfs")
else ()
list(APPEND LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
endif ()
# The following are optional X11 libraries
if (X11_Xinerama_FOUND AND WITH_XINERAMA)
list(APPEND INCLUDES ${X11_Xinerama_INCLUDE_PATH})
list(APPEND LIBRARIES ${X11_Xinerama_LIB})
list(APPEND DEFINES "HAVE_XINERAMA")
else ()
list(APPEND DISABLED "HAVE_XINERAMA")
endif ()
if (X11_Xrandr_FOUND AND WITH_XRANDR)
list(APPEND INCLUDES ${X11_Xrandr_INCLUDE_PATH})
list(APPEND LIBRARIES ${X11_Xrandr_LIB})
list(APPEND DEFINES "HAVE_XRANDR")
else ()
list(APPEND DISABLED "HAVE_XRANDR")
endif ()
if (X11_Xft_FOUND AND WITH_XFT)
find_package(Freetype)
if (FREETYPE_FOUND)
list(APPEND INCLUDES ${FREETYPE_INCLUDE_DIRS}
${X11_Xft_INCLUDE_PATH})
list(APPEND LIBRARIES ${FREETYPE_LIBRARIES}
${X11_Xft_LIB})
list(APPEND DEFINES "HAVE_XFT")
else ()
list(APPEND DISABLED "HAVE_XFT")
endif ()
endif ()
if (WITH_IMLIB2)
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
pkg_check_modules(IMLIB2 imlib2)
if (IMLIB2_FOUND)
list(APPEND INCLUDES ${IMLIB2_INCLUDE_DIRS})
list(APPEND LIBRARIES ${IMLIB2_LIBRARIES})
list(APPEND DEFINES "HAVE_IMLIB")
link_directories(${IMLIB2_LIBRARY_DIRS})
else ()
list(APPEND DISABLED "HAVE_IMLIB")
endif ()
else ()
list(APPEND DISABLED "HAVE_IMLIB")
endif ()
endif ()
# Enable the optional module to compilation
foreach (modname ${DEFINES})
add_definitions(-D${modname})
# Set a variable to print all enabled modules.
# Remove the HAVE_ from module names
string(SUBSTRING ${modname} 5 -1 upcase)
string(TOLOWER ${upcase} module)
message("INFO: ${module} enabled")
endforeach ()
# Show modules disabled
foreach (modname ${DISABLED})
string(SUBSTRING ${modname} 5 -1 upcase)
string(TOLOWER ${upcase} module)
message("INFO: ${module} disabled")
endforeach ()
file(
GLOB
SOURCES
src/*.c
src/*.h
)
# Add definitions for the version and XDG
add_definitions(-DWMFS_VERSION=\"${WMFS_VERSION}\")
add_definitions(-DXDG_CONFIG_DIR=\"${XDG_CONFIG_DIR}\")
include_directories(${INCLUDES})
add_executable(wmfs ${SOURCES})
target_link_libraries(wmfs ${LIBRARIES})
# Install targets
install(TARGETS wmfs DESTINATION bin/)
install(FILES wmfsrc DESTINATION ${XDG_CONFIG_DIR}/)
install(FILES wmfs.1 DESTINATION ${MANPREFIX}/man1/)
+1
View File
@@ -0,0 +1 @@
wmfs.info
-27
View File
@@ -1,27 +0,0 @@
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.
-87
View File
@@ -1,87 +0,0 @@
PROG=wmfs
MAN=wmfs.1
# wmfs version
VERSION=$(shell scripts/setlocalversion)
SRCS= \
src/barwin.c \
src/client.c \
src/config.c \
src/draw.c \
src/event.c \
src/ewmh.c \
src/frame.c \
src/infobar.c \
src/init.c \
src/launcher.c \
src/layout.c \
src/menu.c \
src/mouse.c \
src/parse_api.c \
src/parse.c \
src/screen.c \
src/status.c \
src/systray.c \
src/tag.c \
src/util.c \
src/color.c \
src/split.c \
src/cfactor.c \
src/wmfs.c
# flags
CFLAGS+= -DXDG_CONFIG_DIR=\"${XDG_CONFIG_DIR}\"
CFLAGS+= -DWMFS_VERSION=\"${VERSION}\"
CFLAGS+= -Wall -Wextra
OBJS= ${SRCS:.c=.o}
all: ${PROG} ${MAN}.gz
${PROG}: ${OBJS} src/structs.h src/wmfs.h src/parse.h
${CC} -o $@ ${OBJS} ${LDFLAGS}
${MAN}.gz: ${MAN}
gzip -cn -9 ${MAN} > $@
.c.o:
${CC} -c ${CFLAGS} $< -o $@
.PHONY: all clean distclean install uninstall dist
clean:
rm -f ${OBJS} wmfs ${MAN}.gz
distclean: clean
rm -f Makefile
install: all
@echo installing executable file to ${DESTDIR}${PREFIX}/bin
mkdir -p ${DESTDIR}${PREFIX}/bin
install ${PROG} ${DESTDIR}${PREFIX}/bin
@echo installing manual page to ${DESTDIR}${MANPREFIX}/man1
mkdir -p ${DESTDIR}${MANPREFIX}/man1
install -m 644 ${MAN}.gz ${DESTDIR}${MANPREFIX}/man1/
@echo installing xsession file to ${DESTDIR}${PREFIX}/share/xsessions
mkdir -p ${DESTDIR}${PREFIX}/share/xsessions
install -m 644 wmfs.desktop ${DESTDIR}${PREFIX}/share/xsessions/
@echo installing default config file to ${DESTDIR}${XDG_CONFIG_DIR}/wmfs/
mkdir -p ${DESTDIR}${XDG_CONFIG_DIR}/wmfs/
install -m 444 wmfsrc ${DESTDIR}${XDG_CONFIG_DIR}/wmfs/
uninstall:
@echo removing executable file from ${DESTDIR}${PREFIX}/bin
rm -f ${DESTDIR}${PREFIX}/bin/wmfs
@echo removing manual page from ${DESTDIR}${MANPREFIX}/man1
rm -f ${DESTDIR}${MANPREFIX}/man1/wmfs.1.gz
@echo removing xsession file from ${DESTDIR}${PREFIX}/share/xsessions
rm -f ${DESTDIR}${PREFIX}/share/xsessions/wmfs.desktop
@echo removing config file from ${DESTDIR}${XDG_CONFIG_DIR}/wmfs/
rm -f ${DESTDIR}${XDG_CONFIG_DIR}/wmfs/wmfsrc
rmdir ${DESTDIR}${XDG_CONFIG_DIR}/wmfs/
dist:
@echo "Generate wmfs-`date +%Y%m`.tar.gz"
git archive --format=tar --prefix=wmfs-`date +%Y%m`/ master | gzip -c > wmfs-`date +%Y%m`.tar.gz
-43
View File
@@ -1,43 +0,0 @@
ABOUT :
WMFS Window Manager.
* Window Manager From Scratch
A highly configurable and manageable tiling Window Manager created from scratch
AUTHOR :
- Martin Duquesnoy <xorg62@gmail.com>
CONTRIBUTORS :
- Philippe Pepiot <phil@philpep.org>
- Marc Lagrange <markocpc@gmail.com>
- OldMan <tele-post@mail.ru>
- Raphael Khaiat <raphael@khaiat.org>
- Tomáš Chvátal <scarabeus@gentoo.org>
- David Delassus <linkdd@ydb.me>
- David Demelier <markand@malikania.fr>
LICENSE : BSD, see COPYING.
REQUIREMENT :
- libx11
- libxft (optional)
- freetype
- libxinerama (optional)
- libxrandr (optional)
- imlib2 (optional)
- cmake>=2.8 (build system, optional)
OS :
- GNU/Linux : Supported.
- FreeBSD/OpenBSD/NetBSD : Supported.
INSTALL :
mkdir build/ && cd build/
cmake ..
You can also use old build system if you don't want^Whave cmake
./configure && make
DISTROS :
- wmfs port for FreeBSD at x11-wm/wmfs
- wmfs is available with AUR in ArchLinux (wmfs or wmfs-git)
-24
View File
@@ -1,24 +0,0 @@
,
dM
MMr
4MMML .
MMMMM. xf
. "M6MMM .MM-
Mh.. +MM5MMM .MMMM
.MMM. .MMMMML. MMMMMh
)MMMh. MM5MMM MMMMMMM
3MMMMx. 'MMM3MMf xnMMMMMM"
'*MMMMM MMMMMM. nMMMMMMP"
*MMMMMx "MMM5M\ .MMMMMMM=
*MMMMMh "MMMMM" JMMMMMMP
MMMMMM GMMMM. dMMMMMM .
MMMMMM "MMMM .MMMMM( .nnMP"
.. *MMMMx MMM" dMMMM" .nnMMMMM*
"MMn... 'MMMMr 'MM MMM" .nMMMMMMM*"
"4MMMMnn.. *MMM MM MMP" .dMMMMMMM""
^MMMMMMMMx. *ML "M .M* .MMMMMM**"
*PMMMMMMhn. *x > M .MMMM**""
""**MMMMhx/.h/ .=*"
.3P"%....
nP" "*MMnx
Vendored
-111
View File
@@ -1,111 +0,0 @@
#!/bin/sh
LIBS="x11"
USE_XINERAMA="xinerama"
USE_XRANDR="xrandr"
USE_IMLIB2="imlib2"
USE_XFT="xft freetype2"
OS=`uname -s`
PREFIX=/usr/local
MANPREFIX="$PREFIX/man"
XDG_CONFIG_DIR="$PREFIX/etc/xdg"
while true; do
case "$1" in
--without-xinerama)
USE_XINERAMA=""; shift;;
--without-xrandr)
USE_XRANDR=""; shift;;
--without-imlib2)
USE_IMLIB2=""; shift;;
--without-xft)
USE_XFT=""; shift;;
--prefix)
[ -z "$2" ] && echo "Missing argument" && exit 1
PREFIX=$2; shift 2;;
--xdg-config-dir)
[ -z "$2" ] && echo "Missing argument" && exit 1
XDG_CONFIG_DIR=$2; shift 2;;
--man-prefix)
[ -z "$2" ] && echo "Missing argument" && exit 1
MANPREFIX=$2; shift 2;;
--help|-h)
echo "Usage: ./configure [options]
--without-imlib2 : compile without imlib2 support
--without-xrandr : compile without xrandr support
--without-xinerama : compile without xinerama support
--without-xft : compile without xft support
--prefix DIRECTORY : install binary with specified prefix (default $PREFIX)
--xdg-config-dir DIRECTORY : install configuration to specified directory (default $XDG_CONFIG_DIR)
--man-prefix DIRECTORY : install man page to specified prefix (default $MANPREFIX)"
exit 0;;
*) break;;
esac
done
LIBS="$LIBS $USE_XINERAMA $USE_XRANDR $USE_IMLIB2 $USE_XFT"
which pkg-config >/dev/null 2>&1
if [ $? -eq 0 ];
then
CFLAGS=`pkg-config --cflags-only-I $LIBS`
LDFLAGS=`pkg-config --libs $LIBS`
else
# Try to use some known paths
case $OS in
FreeBSD)
CFLAGS="-I/usr/local/include -I/usr/local/include/freetype2"
LDFLAGS="-L/usr/local/lib";;
OpenBSD)
CFLAGS="-I/usr/X11R6/include -I/usr/X11R6/include/freetype2 -I/usr/local/include"
LDFLAGS="-L/usr/X11R6/lib -L/usr/local/lib";;
NetBSD)
CFLAGS="-I/usr/X11R7/include -I/usr/X11R7/include/freetype2 -I/usr/local/include"
LDFLAGS="-L/usr/X11R7/lib -L/usr/local/lib";;
Linux)
CFLAGS="-I/usr/include/freetype2"
LDFLAGS=""
;;
*)
echo "No default CFLAGS and LDFLAGS found for your OS, feel free to contribute or install pkg-config :)"
exit 1;;
esac
LDFLAGS="$LDFLAGS -lX11"
[ -n "$USE_XINERAMA" ] && LDFLAGS="$LDFLAGS -lXinerama"
[ -n "$USE_XRANDR" ] && LDFLAGS="$LDFLAGS -lXrandr"
[ -n "$USE_IMLIB2" ] && LDFLAGS="$LDFLAGS -lImlib2"
[ -n "$USE_XFT" ] && LDFLAGS="$LDFLAGS -lXft -lfreetype"
fi
[ -n "$USE_XINERAMA" ] && CFLAGS="$CFLAGS -DHAVE_XINERAMA"
[ -n "$USE_XRANDR" ] && CFLAGS="$CFLAGS -DHAVE_XRANDR"
[ -n "$USE_IMLIB2" ] && CFLAGS="$CFLAGS -DHAVE_IMLIB"
[ -n "$USE_XFT" ] && CFLAGS="$CFLAGS -DHAVE_XFT"
LDFLAGS="$LDFLAGS -lpthread"
cat > Makefile << EOF
PREFIX=$PREFIX
XDG_CONFIG_DIR=$XDG_CONFIG_DIR
MANPREFIX=$MANPREFIX
CFLAGS+=$CFLAGS
LDFLAGS+=$LDFLAGS
EOF
cat Makefile.in >> Makefile
echo "Compilation resume:
OS=$OS
CFLAGS=$CFLAGS
LDFLAGS=$LDFLAGS
PREFIX=$PREFIX
MANPREFIX=$MANPREFIX
XDG_CONFIG_DIR=$XDG_CONFIG_DIR
You can run 'make' now :-)
"
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 824 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

BIN
View File
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 474 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

+77
View File
@@ -0,0 +1,77 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<link rel="stylesheet" href="style.css" type="text/css" />
<link rel="Shortcut Icon" href="favicon-basic.ico" type="image/x-icon" />
<!-- Page Title -->
<title>WMFS - Window Manager From Scratch</title>
</head>
<body>
<div id="container">
<div id="header">
<h1><span>window manager from scratch by <a href="https://github.com/xorg62" title ="who is...">xorg62</a></span><a href="https://github.com/xorg62/wmfs" title="go to github">WMFS2</a></h1>
<h2><a href="https://github.com/xorg62/wmfs" title="go to git repository">git</a> | <a href="https://github.com/xorg62/wmfs/wiki" title="visit wmfs wiki eng/fr">wiki</a> | <a href="https://github.com/xorg62/wmfs/tarball/master" title="download wmfs as tgz">download</a> | <a href="mailto:xorg62@gmail.com" title="mail to xorg62">contact</a> | <a href="irc.html" title="chan #wmfs on freenode">irc</a></h2>
</div>
<div id="links">
<div class="categorie">
<img src="images/logo-snap2.png" alt="wmfs2"/>
<h2> - what ?</h2>
<p>WMFS2 is a lightweight and highly configurable tiling window manager for X written in C. wmfs2 is a free software distributed under the <a href="http://en.wikipedia.org/wiki/BSD_licenses">BSD license</a>. it can be drive from keyboard or mouse and it's configuration stands in one text file easily understandable</p>
<h2> - where ?</h2>
<p>You can download this project either in <a href="https://github.com/xorg62/wmfs/zipball/master">zip</a> or <a href="https://github.com/xorg62/wmfs/tarball/master">tar</a> formats. You can also clone the project with <a href="http://git-scm.com">Git</a> by running: <pre>$ git clone git://github.com/xorg62/wmfs.git</pre></p>
<h2> - look</h2>
<p>wmfs2 supports themable statusbars and clients</p>
<div class="slider-wrapper theme-default">
<div id="slider" class="nivoSlider">
<a href="shots/wmfs2_shots_01.png"><img src="images/wmfs2_thmb_01.png" alt=""/></a>
<a href="shots/wmfs2_shots_02.png"><img src="images/wmfs2_thmb_01.png" alt=""/></a>
<a href="shots/wmfs2_shots_03.png"><img src="images/wmfs2_thmb_03.png" alt=""/></a>
<a href="shots/wmfs2_shots_04.png"><img src="images/wmfs2_thmb_04.png" alt=""/></a>
<a href="shots/wmfs2_shots_05.png"><img src="images/wmfs2_thmb_05.png" alt=""/></a>
<a href="shots/wmfs2_shots_06.png"><img src="images/wmfs2_thmb_06.png" alt=""/></a>
<a href="shots/wmfs2_shots_07.png"><img src="images/wmfs2_thmb_07.png" alt=""/></a>
<a href="shots/wmfs2_shots_08.png"><img src="images/wmfs2_thmb_08.png" alt=""/></a>
<a href="shots/wmfs2_shots_09.png"><img src="images/wmfs2_thmb_09.png" alt=""/></a>
<a href="shots/wmfs2_shots_10.png"><img src="images/wmfs2_thmb_10.png" alt=""/></a>
</div>
<h2> - support</h2>
<a href="https://github.com/xorg62/wmfs/wiki">the wiki</a> is a good place to find answers to common questions.<br/>
need more help ? the best way to get direct support is to join our IRC channel, <a href="irc.html" title="wmfs on freenode">#wmfs on freenode</a>.
<h2> - authors</h2>
<p>Martin Duquesnoy (xorg62@gmail.com)<br />
David Delassus (david.jose.delassus@gmail.com)<br />
Paul Fariello (fariello@archos.com)<br />
Hobbestigrou (hobbestigrou@erakis.im)<br />
Philippe Pepiot (phil@philpep.org)<br />
m-r-r (raybaudroigm@gmail.com)<br />
6pi (c.sipieter@gmail.com)<br />
Jeremy Anger (angerj.dev@gmail.com)<br />
arnault (contact@arpinux.org)<br />
Romain Porte (microjoe@mailoo.org)</p>
</div>
<script type="text/javascript" src="scripts/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="scripts/jquery.nivo.slider.pack.js"></script>
<script type="text/javascript">
$(window).load(function() {
$('#slider').nivoSlider({
effect: 'fade',
pauseTime: 5000,
controlNav: false,
randomStart: true
});
});
</script>
</div>
</div>
<div id="footer">
<p>:: theme by <a href="http://arpinux.org">arpinux</a> inspired by <a href="http://wiscot.deviantart.com">wiscot</a> :: slider by <a href="license.txt">dev7</a> :: arpinux 2012 :: license <a href="http://creativecommons.org/licenses/by-nc-sa/3.0/">cc BY-NC-SA</a> :: <a href="http://validator.w3.org/check/referer" title="Valid XHTML 1.0">XHTML</a> :: <!--a href="http://jigsaw.w3.org/css-validator/check/referer?profile=css3" title="Valid CSS">CSS</a--></p>
</div>
</div>
</body>
</html>
<!-- cc BY-NC-SA License :: arpinux :: 2012 :: http://arpinux.org -->
+31
View File
@@ -0,0 +1,31 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<link rel="stylesheet" href="style.css" type="text/css" />
<link rel="Shortcut Icon" href="favicon-basic.ico" type="image/x-icon" />
<!-- Page Title -->
<title>WMFS on freenode</title>
</head>
<body>
<div id="container">
<div id="header">
<h1><span>window manager from scratch by <a href="https://github.com/xorg62" title ="who is...">xorg62</a></span><a href="https://github.com/xorg62/wmfs" title="go to github">WMFS2</a></h1>
<h2><a href="https://github.com/xorg62/wmfs" title="go to git repository">git</a> | <a href="https://github.com/xorg62/wmfs/wiki" title="visit wmfs wiki eng/fr">wiki</a> | <a href="https://github.com/xorg62/wmfs/tarball/master" title="download wmfs as tgz">download</a> | <a href="mailto:xorg62@gmail.com" title="mail to xorg62">contact</a> | <a href="irc.html" title="chan #wmfs on freenode">irc</a></h2>
</div>
<div id="links">
<div class="categorie">
<iframe src="http://webchat.freenode.net?channels=wmfs" frameborder="0" width="100%" height="400"><p>your browser does not support iframes. please use an irc client like irssi, weechat or pidgin.</p></iframe>
</div>
</div>
<div id="footer">
<p>:: theme by arpinux inspired by <a href="http://wiscot.deviantart.com">wiscot</a> :: irc by <a href="http://www.qwebirc.org/">qwebirc</a> :: arpinux 2012 :: license <a href="http://creativecommons.org/licenses/by-nc-sa/3.0/">cc BY-NC-SA</a> :: <!--a href="http://validator.w3.org/check/referer" title="Valid XHTML 1.0">XHTML</a> :: <a href="http://jigsaw.w3.org/css-validator/check/referer?profile=css3" title="Valid CSS">CSS</a--></p>
</div>
</div>
</body>
</html>
<!-- cc BY-NC-SA License :: arpinux :: 2011 :: http://arpinux.org -->
+25
View File
@@ -0,0 +1,25 @@
Nivo Slider is "The Most Awesome jQuery Image Slider".
See http://nivo.dev7studios.com for more info.
Copyright (c) 2011 Gilbert Pellegrom
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
Vendored Executable
+4
View File
File diff suppressed because one or more lines are too long
+12
View File
File diff suppressed because one or more lines are too long
-75
View File
@@ -1,75 +0,0 @@
#!/bin/sh
# Print additional version information for non-release trees.
usage() {
echo "Usage: $0 [srctree]" >&2
exit 1
}
cd "${1:-.}" || usage
# Check for git and a git repo.
if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then
# Do we have an untagged version?
if git name-rev --tags HEAD | grep -E '^HEAD[[:space:]]+(.*~[0-9]*|undefined)$' > /dev/null; then
if tag=`git describe 2>/dev/null`; then
echo $tag | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}'
else
printf '%s%s' -g $head
fi
fi
# Is this git on svn?
if git config --get svn-remote.svn.url >/dev/null; then
printf -- '-svn%s' "`git svn find-rev $head`"
fi
# Are there uncommitted changes?
git update-index --refresh --unmerged > /dev/null
if git diff-index --name-only HEAD | grep -v "^scripts/package" \
| read dummy; then
printf '%s' -dirty
fi
# All done with git
exit
fi
# Check for mercurial and a mercurial repo.
if hgid=`hg id 2>/dev/null`; then
tag=`printf '%s' "$hgid" | cut -d' ' -f2`
# Do we have an untagged version?
if [ -z "$tag" -o "$tag" = tip ]; then
id=`printf '%s' "$hgid" | sed 's/[+ ].*//'`
printf '%s%s' -hg "$id"
fi
# Are there uncommitted changes?
# These are represented by + after the changeset id.
case "$hgid" in
*+|*+\ *) printf '%s' -dirty ;;
esac
# All done with mercurial
exit
fi
# Check for svn and a svn repo.
if rev=`svn info 2>/dev/null | grep '^Last Changed Rev'`; then
rev=`echo $rev | awk '{print $NF}'`
changes=`svn status 2>/dev/null | grep '^[AMD]' | wc -l`
# Are there uncommitted changes?
if [ $changes != 0 ]; then
printf -- '-svn%s%s' "$rev" -dirty
else
printf -- '-svn%s' "$rev"
fi
# All done with svn
exit
fi
# default version
printf -- '-%s' "`date +%Y%m`"
-11
View File
@@ -1,11 +0,0 @@
#!/bin/sh
#WMFS status.sh example file
#Will be executed if put in ~/.config/wmfs/
#Timing adjustable in wmfsrc (misc -> status_timing)
statustext()
{
wmfs -s "`date`"
}
while true; do statustext; sleep 10; done
Binary file not shown.

After

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 KiB

-241
View File
@@ -1,241 +0,0 @@
/*
* barwin.c
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "wmfs.h"
/** Create a BarWindow
* \param parent Parent window of the BarWindow
* \param x X position
* \param y Y position
* \param w BarWindow Width
* \param h BarWindow Height
* \param color BarWindow color
* \param entermask bool for know if the EnterMask mask is needed
* \return The BarWindow pointer
*/
BarWindow*
barwin_create(Window parent,
int x,
int y,
int w,
int h,
uint bg,
char *fg,
bool entermask,
bool stipple,
bool border)
{
XSetWindowAttributes at;
BarWindow *bw;
/* Allocate memory */
bw = zcalloc(sizeof(*bw));
/* Barwin attributes */
at.override_redirect = True;
at.background_pixmap = ParentRelative;
at.event_mask = SubstructureRedirectMask|SubstructureNotifyMask
|ButtonMask|MouseMask
|ExposureMask|VisibilityChangeMask
|StructureNotifyMask|SubstructureRedirectMask;
if(entermask)
at.event_mask |= EnterWindowMask|LeaveWindowMask|FocusChangeMask;
/* Create window */
bw->win = XCreateWindow(dpy, parent, x, y, w, h, 0, DefaultDepth(dpy, SCREEN),
CopyFromParent, DefaultVisual(dpy, SCREEN),
CWOverrideRedirect | CWBackPixmap | CWEventMask, &at);
bw->dr = XCreatePixmap(dpy, parent, w, h, DefaultDepth(dpy, SCREEN));
/* His border */
if(border)
{
bw->flags |= BordFlag;
bw->border.light = color_shade(bg, conf.colors.bar_light_shade);
bw->border.dark = color_shade(bg, conf.colors.bar_dark_shade);
CWIN(bw->border.left, bw->win, 0, 0, SHADH, h, 0, CWBackPixel, bg, &at);
CWIN(bw->border.top, bw->win, 0, 0, w, SHADH, 0, CWBackPixel, bg, &at);
CWIN(bw->border.bottom, bw->win, 0, h - SHADH, w, SHADH, 0, CWBackPixel, bg, &at);
CWIN(bw->border.right, bw->win, w - SHADH, 0, SHADH, h, 0, CWBackPixel, bg, &at);
}
/* Property */
bw->geo.x = x;
bw->geo.y = y;
bw->geo.width = w;
bw->geo.height = h;
bw->bg = bg;
bw->fg = fg;
FLAGAPPLY(bw->flags, stipple, StippleFlag);
bw->stipple_color = 0xffffffff;
/* Attach */
SLIST_INSERT_HEAD(&bwhead, bw, next);
return bw;
}
/** Draw text in a Barwindow
*/
void
barwin_draw_text(BarWindow *bw, int x, int y, char *text)
{
/* Background color of the text if there is stipple */
if(bw->flags & StippleFlag)
draw_rectangle(bw->dr, x - 4, 0, textw(text) + 8, bw->geo.height, bw->bg);
/* Draw text */
draw_text(bw->dr, x, y, bw->fg, text);
barwin_refresh(bw);
return;
}
void
barwin_color_set(BarWindow *bw, uint bg, char *fg)
{
bw->bg = bg;
bw->fg = fg;
if(bw->flags & BordFlag)
{
bw->border.light = color_shade(bg, conf.colors.bar_light_shade);
bw->border.dark = color_shade(bg, conf.colors.bar_dark_shade);
}
if(bw->flags & StippleFlag && bw->stipple_color == 0xffffffff)
bw->stipple_color = getcolor(fg);
return;
}
/** Delete a BarWindow
* \param bw BarWindow pointer
*/
void
barwin_delete(BarWindow *bw)
{
SLIST_REMOVE(&bwhead, bw, BarWindow, next);
XSelectInput(dpy, bw->win, NoEventMask);
XDestroyWindow(dpy, bw->win);
XFreePixmap(dpy, bw->dr);
free(bw);
return;
}
/** Move a BarWindow
* \param bw BarWindow pointer
* \param x X position
* \param y Y poistion
*/
void
barwin_move(BarWindow *bw, int x, int y)
{
if(bw->geo.x == x && bw->geo.y == y)
return;
XMoveWindow(dpy, bw->win, (bw->geo.x = x), (bw->geo.y = y));
return;
}
/** Resize a BarWindow
* \param bw BarWindow pointer
* \param w Width
* \param h Height
*/
void
barwin_resize(BarWindow *bw, int w, int h)
{
if(bw->geo.width == w && bw->geo.height == h)
return;
/* Frame */
XFreePixmap(dpy, bw->dr);
bw->dr = XCreatePixmap(dpy, ROOT,
w - ((bw->flags & BordFlag) ? SHADH : 0),
h - ((bw->flags & BordFlag) ? SHADH : 0),
DefaultDepth(dpy, SCREEN));
bw->geo.width = w;
bw->geo.height = h;
XResizeWindow(dpy, bw->win, w, h);
/* Border */
if(bw->flags & BordFlag)
{
XResizeWindow(dpy, bw->border.left, SHADH, h);
XResizeWindow(dpy, bw->border.top, w, SHADH);
XResizeWindow(dpy, bw->border.bottom, w, SHADH);
XMoveResizeWindow(dpy, bw->border.right, w - SHADH, 0, SHADH, h);
}
return;
}
/** Refresh the BarWindow Color
* \param bw BarWindow pointer
*/
void
barwin_refresh_color(BarWindow *bw)
{
XSetForeground(dpy, gc, bw->bg);
XFillRectangle(dpy, bw->dr, gc, 0, 0, bw->geo.width, bw->geo.height);
if(bw->flags & StippleFlag)
{
XSetForeground(dpy, gc_stipple, bw->stipple_color);
XFillRectangle(dpy, bw->dr, gc_stipple, 3, 2, bw->geo.width - 6, bw->geo.height - 4);
}
if(bw->flags & BordFlag)
{
XSetWindowBackground(dpy, bw->border.left, bw->border.light);
XSetWindowBackground(dpy, bw->border.top, bw->border.light);
XSetWindowBackground(dpy, bw->border.bottom, bw->border.dark);
XSetWindowBackground(dpy, bw->border.right, bw->border.dark);
XClearWindow(dpy, bw->border.left);
XClearWindow(dpy, bw->border.top);
XClearWindow(dpy, bw->border.bottom);
XClearWindow(dpy, bw->border.right);
}
return;
}
-279
View File
@@ -1,279 +0,0 @@
/*
* cfactor.c
* Copyright © 2011 Martin Duquesnoy <xorg62@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "wmfs.h"
#define CLIENT_RESIZE_DIR(d) \
void \
uicb_client_resize_##d(uicb_t cmd) \
{ \
CHECK(sel); \
cfactor_set(sel, d, atoi(cmd)); \
}
/* uicb_client_resize_dir() */
CLIENT_RESIZE_DIR(Right);
CLIENT_RESIZE_DIR(Left);
CLIENT_RESIZE_DIR(Top);
CLIENT_RESIZE_DIR(Bottom);
/** Clean client tile factors
*\param c Client pointer
*/
void
cfactor_clean(Client *c)
{
CHECK(c);
if(!(tags[c->screen][c->tag].flags & (SplitFlag | CleanFactFlag)))
return;
c->tilefact[Right] = c->tilefact[Left] = 0;
c->tilefact[Top] = c->tilefact[Bottom] = 0;
return;
}
/** Return new geo of client with factors applied
*\param c Client pointer
*\return geo
*/
Geo
cfactor_geo(Geo geo, int fact[4], int *err)
{
Geo cgeo = geo;
*err = 0;
/* Right factor */
cgeo.width += fact[Right];
/* Left factor */
cgeo.x -= fact[Left];
cgeo.width += fact[Left];
/* Top factor */
cgeo.y -= fact[Top];
cgeo.height += fact[Top];
/* Bottom factor */
cgeo.height += fact[Bottom];
/* Too big/small */
if(cgeo.width > sgeo[selscreen].width || cgeo.height > sgeo[selscreen].height
|| cgeo.width < (BORDH << 1) || cgeo.height < (BORDH + TBARH))
{
*err = 1;
return geo;
}
return cgeo;
}
/** Get c parents of row and resize
*\param c Client pointer
*\param p Direction of resizing
*\param fac Factor of resizing
*/
static void
_cfactor_arrange_row(Client *c, Position p, int fac)
{
Geo cgeo = c->frame_geo;
Client *cc = tiled_client(c->screen, SLIST_FIRST(&clients));
/* Travel clients to search parents of row and apply fact */
for(; cc; cc = tiled_client(c->screen, SLIST_NEXT(cc, next)))
if(CFACTOR_PARENTROW(cgeo, cc->frame_geo, p))
{
cc->tilefact[p] += fac;
client_moveresize(cc, cc->geo, (tags[cc->screen][cc->tag].flags & ResizeHintFlag));
}
return;
}
/** Get c parents of row and check geo with futur resize factor
*\param c Client pointer
*\param p Direction of resizing
*\param fac Factor of resizing
*\return False in case of error
*/
static bool
_cfactor_check_geo_row(Client *c, Position p, int fac)
{
Geo cgeo = c->frame_geo;
Client *cc = tiled_client(c->screen, SLIST_FIRST(&clients));
int e, f[4] = { 0 };
f[p] += fac;
/* Travel clients to search parents of row and check geos */
for(; cc; cc = tiled_client(c->screen, SLIST_NEXT(cc, next)))
if(CFACTOR_PARENTROW(cgeo, cc->frame_geo, p))
{
(Geo)cfactor_geo(cc->wrgeo, f, &e);
if(e)
return False;
}
return True;
}
/* Resize only 2 client with applied factor
*\param c1 Client pointer
*\param c2 Client pointer
*\param p Direction of resizing
*\param fac Facotr
*/
static void
cfactor_arrange_two(Client *c1, Client *c2, Position p, int fac)
{
c1->tilefact[p] += fac;
c2->tilefact[RPOS(p)] -= fac;
/* Needed in case of padding */
if(conf.client.padding)
{
c1->flags |= FLayFlag;
c2->flags |= FLayFlag;
}
client_moveresize(c1, c1->geo, (tags[c1->screen][c1->tag].flags & ResizeHintFlag));
client_moveresize(c2, c2->geo, (tags[c2->screen][c2->tag].flags & ResizeHintFlag));
return;
}
/** Get c parents of row and resize, exception checking same size before arranging row
*\param c Client pointer
*\param gc Client pointer
*\param p Direction of resizing
*\param fac Factor of resizing
*/
static void
cfactor_arrange_row(Client *c, Client *gc, Position p, int fac)
{
if(CFACTOR_CHECK2(c->frame_geo, gc->frame_geo, p))
cfactor_arrange_two(c, gc, p, fac);
else
{
_cfactor_arrange_row(c, p, fac);
_cfactor_arrange_row(gc, RPOS(p), -fac);
}
return;
}
/** Check future geometry of factorized client
*\param c Client pointer
*\param g Client pointer
*\param p Direction of resizing
*\param fac Factor of resizing
*/
static bool
cfactor_check_geo(Client *c, Client *g, Position p, int fac)
{
int e, ee;
int cf[4] = { 0 }, gf[4] = { 0 };
/* Check c & g first */
cf[p] += fac;
gf[RPOS(p)] -= fac;
(Geo)cfactor_geo(c->geo, cf, &e);
(Geo)cfactor_geo(g->geo, gf, &ee);
/* Size failure */
if(e || ee || !_cfactor_check_geo_row(c, p, fac)
|| !_cfactor_check_geo_row(g, RPOS(p), -fac))
return False;
return True;
}
/** Manual resizing of tiled clients
* \param c Client pointer
* \param p Direction of resizing
* \param fac Factor of resizing
*/
void
cfactor_set(Client *c, Position p, int fac)
{
Client *gc = NULL;
if(!c || !(c->flags & TileFlag) || p > Bottom)
return;
/* Get next client with direction of resize */
gc = client_get_next_with_direction(c, p);
if(!gc || c->screen != gc->screen)
return;
/* Check size */
if(!cfactor_check_geo(c, gc, p, fac))
return;
/* Arrange client and row parents */
cfactor_arrange_row(c, gc, p, fac);
/* Enable split with cfactor_enable_split option */
if(conf.cfactor_enable_split
&& !(tags[c->screen][c->tag].flags & SplitFlag))
{
tags[c->screen][c->tag].flags |= SplitFlag;
infobar_draw_layout(&infobar[c->screen]);
}
return;
}
/** Apply a complete factor array to a client
* \param c Client pointer
* \param fac factor array
*/
void
cfactor_multi_set(Client *c, int fac[4])
{
if(!c)
return;
cfactor_set(c, Right, fac[Right]);
cfactor_set(c, Left, fac[Left]);
cfactor_set(c, Top, fac[Top]);
cfactor_set(c, Bottom, fac[Bottom]);
return;
}
-1550
View File
File diff suppressed because it is too large Load Diff
-223
View File
@@ -1,223 +0,0 @@
/*
* color.c
* Copyright © 2011 Brian Mock <mock.brian@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "wmfs.h"
/** Clamp a number x within the range [a, b].
* \param x the number which to clamp
* \param a the lowest possible value
* \param b the highest possible value
* \return the clamped number
*/
static double
color_clamp(double x, double a, double b)
{
if(x < a)
return a;
else if(x > b)
return b;
else
return x;
}
/** Pack a triplet of RGB values into a single uint
* \param r the red value
* \param g the green value
* \param b the blue value
* \return the packed RGB value
*/
static uint
color_pack_rgb(uint r, uint g, uint b)
{
return (r << 16) | (g << 8) | b;
}
/** Unpack an RGB uint into three separate values
* \param rgb the packed color
* \param r a pointer to a uint where the red value will be stored
* \param g a pointer to a uint where the green value will be stored
* \param b a pointer to a uint where the blue value will be stored
*/
static void
color_unpack_rgb(uint rgb, uint *r, uint *g, uint *b)
{
*r = (rgb >> 16) & 0xFF;
*g = (rgb >> 8) & 0xFF;
*b = rgb & 0xFF;
}
/** Convert unpacked RGB values into HSL, storing in the doubles referenced
* by the pointers h, s, l
*/
static void
color_rgb_to_hsl(uint xr, uint xg, uint xb, double *h, double *s, double *l)
{
double r = xr/255.0;
double g = xg/255.0;
double b = xb/255.0;
double v;
double m;
double vm;
double r2, g2, b2;
*h = 0;
*s = 0;
*l = 0;
/* v is max(r, g, b)
* m is min(r, g, b)
*/
v = r > g ? r : g;
v = v > b ? v : b;
m = r < g ? r : g;
m = m < b ? m : b;
*l = (m + v)/2.0;
if(*l <= 0.0)
return;
vm = v - m;
*s = vm;
if(*s > 0.0)
*s /= (*l <= 0.5) ? (v + m) : (2.0 - v - m);
else
return;
r2 = (v - r)/vm;
g2 = (v - g)/vm;
b2 = (v - b)/vm;
if(r == v)
*h = (g == m ? 5.0 + b2 : 1.0 - g2);
else if(g == v)
*h = (b == m ? 1.0 + r2 : 3.0 - b2);
else
*h = (r == m ? 3.0 + g2 : 5.0 - r2);
*h /= 6.0;
}
/** Convert h, s, l values to RGB and store them in the three uint
* referenced by the last three parameters.
*/
static void
color_hsl_to_rgb(double h, double sl, double l, uint *rx, uint *gx, uint *bx)
{
double v;
double r,g,b;
r = l;
g = l;
b = l;
v = (l <= 0.5) ? (l * (1.0 + sl)) : (l + sl - l * sl);
if(v > 0)
{
double m;
double sv;
int sextant;
double fract, vsf, mid1, mid2;
m = l + l - v;
sv = (v - m ) / v;
h *= 6.0;
sextant = (int) h;
fract = h - sextant;
vsf = v * sv * fract;
mid1 = m + vsf;
mid2 = v - vsf;
switch(sextant)
{
case 0:
r = v;
g = mid1;
b = m;
break;
case 1:
r = mid2;
g = v;
b = m;
break;
case 2:
r = m;
g = v;
b = mid1;
break;
case 3:
r = m;
g = mid2;
b = v;
break;
case 4:
r = mid1;
g = m;
b = v;
break;
case 5:
r = v;
g = m;
b = mid2;
break;
}
}
*rx = r * 255.0;
*gx = g * 255.0;
*bx = b * 255.0;
}
/** Shades a color by the amount. This works by converting a packed RGB
* color to HSL, adding the amount to the lightness,
* and then converting back to RGB. 1.0 is max lightness, 0.0 is min lightness.
* \param shadeVal the amount to shade the lightness by.
* \return the shaded color
*/
uint
color_shade(uint rgb, double shadeVal)
{
uint r, g, b;
double h, s, l;
color_unpack_rgb(rgb, &r, &g, &b);
color_rgb_to_hsl(r, g, b, &h, &s, &l);
l += shadeVal;
l = color_clamp(l, 0, 1);
color_hsl_to_rgb(h, s, l, &r, &g, &b);
rgb = color_pack_rgb(r, g, b);
return rgb;
}
-852
View File
@@ -1,852 +0,0 @@
/*
* config.c
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "wmfs.h"
const func_name_list_t func_list[] =
{
{"spawn", uicb_spawn },
{"client_kill", uicb_client_kill },
{"client_prev", uicb_client_focus_prev },
{"client_next", uicb_client_focus_next },
{"client_swap_next", uicb_client_swapsel_next },
{"client_swap_prev", uicb_client_swapsel_prev },
{"client_swap_right", uicb_client_swapsel_Right },
{"client_swap_left", uicb_client_swapsel_Left },
{"client_swap_top", uicb_client_swapsel_Top },
{"client_swap_bottom", uicb_client_swapsel_Bottom },
{"client_screen_next", uicb_client_screen_next },
{"client_screen_prev", uicb_client_screen_prev },
{"client_screen_set", uicb_client_screen_set },
{"client_focus_right", uicb_client_focus_Right },
{"client_focus_left" , uicb_client_focus_Left },
{"client_focus_top", uicb_client_focus_Top },
{"client_focus_bottom", uicb_client_focus_Bottom },
{"client_move", uicb_client_move },
{"client_resize", uicb_client_resize },
{"client_ignore_tag", uicb_client_ignore_tag },
{"client_set_master", uicb_client_set_master },
{"client_resize_right", uicb_client_resize_Right },
{"client_resize_left", uicb_client_resize_Left },
{"client_resize_top", uicb_client_resize_Top },
{"client_resize_bottom", uicb_client_resize_Bottom },
{"toggle_max", uicb_togglemax },
{"layout_next", uicb_layout_next },
{"layout_prev", uicb_layout_prev },
{"tag", uicb_tag },
{"tag_next", uicb_tag_next },
{"tag_prev", uicb_tag_prev },
{"tag_next_visible", uicb_tag_next_visible },
{"tag_prev_visible", uicb_tag_prev_visible },
{"tag_prev_sel", uicb_tag_prev_sel },
{"tag_transfert", uicb_tagtransfert },
{"tag_transfert_next", uicb_tagtransfert_next },
{"tag_transfert_prev", uicb_tagtransfert_prev },
{"tag_urgent", uicb_tag_urgent },
{"tag_toggle_additional", uicb_tag_toggle_additional },
{"tag_swap", uicb_tag_swap },
{"tag_swap_next", uicb_tag_swap_next },
{"tag_swap_prev", uicb_tag_swap_previous },
{"tag_new", uicb_tag_new },
{"tag_del", uicb_tag_del },
{"tag_rename", uicb_tag_rename },
{"tag_last", uicb_tag_last },
{"tag_stay_last", uicb_tag_stay_last },
{"set_mwfact", uicb_set_mwfact },
{"set_nmaster", uicb_set_nmaster },
{"quit", uicb_quit },
{"toggle_infobar_position", uicb_infobar_togglepos },
{"toggle_infobar_display", uicb_infobar_toggledisplay },
{"toggle_resizehint", uicb_toggle_resizehint },
{"mouse_move", uicb_mouse_move },
{"mouse_resize", uicb_mouse_resize },
{"client_raise", uicb_client_raise },
{"toggle_free", uicb_togglefree },
{"toggle_abovefc", uicb_toggle_abovefc },
{"screen_select", uicb_screen_select },
{"screen_next", uicb_screen_next },
{"screen_prev", uicb_screen_prev },
{"screen_prev_sel", uicb_screen_prev_sel},
{"reload", uicb_reload },
{"launcher", uicb_launcher },
{"set_layout", uicb_set_layout },
{"menu", uicb_menu },
{"ignore_next_client_rules", uicb_ignore_next_client_rules },
{"check_max", uicb_checkmax },
{"check_free", uicb_checkfree },
{"check_layout", uicb_checklayout },
{"clientlist", uicb_clientlist },
{"check_clist", uicb_checkclist },
{"toggle_tagautohide", uicb_toggle_tagautohide },
{"toggle_tag_expose", uicb_tag_toggle_expose},
{"split_toggle", uicb_split_toggle },
{"split_move_right", uicb_split_move_Right },
{"split_move_left", uicb_split_move_Left },
{"split_move_top", uicb_split_move_Top },
{"split_move_bottom", uicb_split_move_Bottom },
/*{"split_client_vertical" uicb_split_client_vertical },
{"split_client_horizontal", uicb_split_client_horizontal }, */
{NULL, NULL}
};
static key_name_list_t key_list[] =
{
{"Control", ControlMask },
{"Shift", ShiftMask },
{"Lock", LockMask },
{"Alt", Mod1Mask },
{"Mod2", Mod2Mask },
{"Mod3", Mod3Mask },
{"Mod4", Mod4Mask },
{"Super", Mod4Mask },
{"Home", Mod4Mask },
{"Mod5", Mod5Mask },
{NULL, NoSymbol }
};
static name_to_uint_t mouse_button_list[] =
{
{"Button1", Button1 },
{"Button2", Button2 },
{"Button3", Button3 },
{"Button4", Button4 },
{"Button5", Button5 },
{"1", Button1 },
{"2", Button2 },
{"3", Button3 },
{"4", Button4 },
{"5", Button5 },
{NULL, NoSymbol}
};
static void
mouse_section(MouseBinding mb[], struct conf_sec **sec)
{
int n;
for (n = 0; sec[n]; n++)
{
mb[n].tag = fetch_opt_first(sec[n], "-1", "tag").num;
mb[n].screen = fetch_opt_first(sec[n], "-1", "screen").num;
mb[n].button = char_to_button(fetch_opt_first(sec[n], "1", "button").str, mouse_button_list);
mb[n].func = name_to_func(fetch_opt_first(sec[n], "", "func").str, func_list);
mb[n].cmd = fetch_opt_first(sec[n], "", "cmd").str;
}
}
static void
conf_misc_section(void)
{
bool xft = False;
int pad = 12;
uint opacity = 255;
struct conf_sec *sec;
sec = fetch_section_first(NULL, "misc");
#ifdef HAVE_XFT
xft = True;
#endif /* HAVE_XFT */
conf.font = fetch_opt_first(sec, "sans-9", "font").str;
conf.use_xft = fetch_opt_first(sec, (xft ? "true" : "false"), "use_xft").boolean;
conf.raisefocus = fetch_opt_first(sec, "false", "raisefocus").boolean;
conf.focus_fmouse = fetch_opt_first(sec, "true", "focus_follow_mouse").boolean;
conf.focus_fmov = fetch_opt_first(sec, "false", "focus_follow_movement").boolean;
conf.focus_pclick = fetch_opt_first(sec, "true", "focus_pointer_click").boolean;
conf.autostart_path = fetch_opt_first(sec, "", "autostart_path").str;
conf.autostart_command = fetch_opt_first(sec, "", "autostart_command").str;
pad = fetch_opt_first(sec, "12", "pad").num;
opacity = fetch_opt_first(sec, "255", "opacity").num;
if(opacity > 255)
opacity = 255;
conf.opacity = opacity << 24;
if(pad > 24 || pad < 1)
{
warnx("configuration : pad value (%d) incorrect.", pad);
pad = 12;
}
conf.pad = pad;
return;
}
static void
conf_bar_section(void)
{
struct conf_sec *bar, **mouse, *selbar, *systray;
char *barbg;
int sc = screen_count();
bar = fetch_section_first(NULL, "bar");
conf.border.bar = fetch_opt_first(bar, "false", "border").boolean;
conf.bars.height = fetch_opt_first(bar, "-1", "height").num;
conf.colors.bar = getcolor((barbg = fetch_opt_first(bar, "#000000", "bg").str));
conf.colors.text = fetch_opt_first(bar, "#ffffff", "fg").str;
conf.colors.bar_light_shade = fetch_opt_first(bar, "0.25", "light_shade").fnum;
conf.colors.bar_dark_shade = fetch_opt_first(bar, "-0.25", "dark_shade").fnum;
conf.bars.element_order = fetch_opt_first(bar, "tls", "elements_order").str;
mouse = fetch_section(bar, "mouse");
if ((conf.bars.nmouse = fetch_section_count(mouse)) > 0)
{
conf.bars.mouse = xcalloc(conf.bars.nmouse, sizeof(MouseBinding));
mouse_section(conf.bars.mouse, mouse);
}
free(mouse);
if((systray = fetch_section_first(bar, "systray")))
{
conf.systray.active = fetch_opt_first(systray, "true", "active").boolean;
if((conf.systray.screen = fetch_opt_first(systray, "0", "screen").num) < 0
|| conf.systray.screen >= sc)
conf.systray.screen = 0;
if((conf.systray.spacing = fetch_opt_first(systray, "3", "spacing").num) < 0)
conf.systray.spacing = 0;
}
else
conf.systray.active = False;
selbar = fetch_section_first(bar, "selbar");
conf.bars.selbar = selbar ? True : False;
conf.selbar.bg = getcolor(fetch_opt_first(selbar, barbg, "bg").str);
conf.selbar.fg = fetch_opt_first(selbar, conf.colors.text, "fg").str;
conf.selbar.maxlength = fetch_opt_first(selbar, "-1", "max_length").num;
mouse = fetch_section(selbar, "mouse");
if ((conf.selbar.nmouse = fetch_section_count(mouse)))
{
conf.selbar.mouse = xcalloc(conf.selbar.nmouse, sizeof(MouseBinding));
mouse_section(conf.selbar.mouse, mouse);
}
free(mouse);
return;
}
static void
conf_root_section(void)
{
struct conf_sec *root, **mouse;
root = fetch_section_first(NULL, "root");
conf.root.background_command = fetch_opt_first(root, "", "background_command").str;
mouse = fetch_section(root, "mouse");
if ((conf.root.nmouse = fetch_section_count(mouse)) > 0)
{
conf.root.mouse = xcalloc(conf.root.nmouse, sizeof(MouseBinding));
mouse_section(conf.root.mouse, mouse);
}
free(mouse);
return;
}
static void
conf_client_section(void)
{
int i, j;
char *flags, *p;
struct conf_sec *sec, **mouse, *titlebar, **button, **line;
struct opt_type *opt;
sec = fetch_section_first(NULL, "client");
conf.client_round = fetch_opt_first(sec, "true", "client_round").boolean;
conf.client_auto_center = fetch_opt_first(sec, "false", "client_auto_center").boolean;
conf.client_tile_raise = fetch_opt_first(sec, "false", "client_tile_raise").boolean;
if ((conf.client.borderheight = fetch_opt_first(sec, "1", "border_height").num) < 1)
conf.client.borderheight = 1;
conf.client.border_shadow = fetch_opt_first(sec, "false", "border_shadow").boolean;
conf.client.place_at_mouse = fetch_opt_first(sec, "false", "place_at_mouse").boolean;
conf.client.bordernormal = getcolor(fetch_opt_first(sec, "#000000", "border_normal").str);
conf.client.borderfocus = getcolor(fetch_opt_first(sec, "#ffffff", "border_focus").str);
conf.client.resizecorner_normal = getcolor(fetch_opt_first(sec, "#222222", "resize_corner_normal").str);
conf.client.resizecorner_focus = getcolor(fetch_opt_first(sec, "#DDDDDD", "resize_corner_focus").str);
conf.client.mod |= char_to_modkey(fetch_opt_first(sec, "Alt", "modifier").str, key_list);
conf.client.set_new_win_master = fetch_opt_first(sec, "true", "set_new_win_master").boolean;
conf.client.padding = fetch_opt_first(sec, "0", "padding").num;
conf.client.autofree = fetch_opt_first(sec, "", "autofree").str;
conf.client.automax = fetch_opt_first(sec, "", "automax").str;
conf.client.default_open_tag = fetch_opt_first(sec, "0", "default_open_tag").num;
conf.client.default_open_screen = fetch_opt_first(sec, "-1", "default_open_screen").num;
conf.client.new_client_get_mouse = fetch_opt_first(sec, "false", "new_client_get_mouse").boolean;
conf.colors.client_light_shade = fetch_opt_first(sec, "0.25", "light_shade").fnum;
conf.colors.client_dark_shade = fetch_opt_first(sec, "-0.25", "dark_shade").fnum;
mouse = fetch_section(sec, "mouse");
if((conf.client.nmouse = fetch_section_count(mouse)) > 0)
{
conf.client.mouse = xcalloc(conf.client.nmouse, sizeof(MouseBinding));
mouse_section(conf.client.mouse, mouse);
}
free(mouse);
titlebar = fetch_section_first(sec, "titlebar");
conf.titlebar.height = fetch_opt_first(titlebar, "0", "height").num;
conf.titlebar.fg_normal = fetch_opt_first(titlebar, "#ffffff", "fg_normal").str;
conf.titlebar.fg_focus = fetch_opt_first(titlebar, "#000000", "fg_focus").str;
conf.titlebar.stipple.active = fetch_opt_first(titlebar, "false", "stipple").boolean;
if(!strcmp((p = fetch_opt_first(titlebar, "-1", "stipple_normal").str), "-1"))
conf.titlebar.stipple.colors.normal = getcolor(conf.titlebar.fg_normal);
else
conf.titlebar.stipple.colors.normal = getcolor(p);
if(!strcmp((p = fetch_opt_first(titlebar, "-1", "stipple_focus").str), "-1"))
conf.titlebar.stipple.colors.focus = getcolor(conf.titlebar.fg_focus);
else
conf.titlebar.stipple.colors.focus = getcolor(p);
mouse = fetch_section(titlebar, "mouse");
if((conf.titlebar.nmouse = fetch_section_count(mouse)) > 0)
{
conf.titlebar.mouse = xcalloc(conf.titlebar.nmouse, sizeof(MouseBinding));
mouse_section(conf.titlebar.mouse, mouse);
}
free(mouse);
/* Multi button part */
button = fetch_section(titlebar, "button");
if((conf.titlebar.nbutton = fetch_section_count(button)) > 0)
{
conf.titlebar.button = xcalloc(conf.titlebar.nbutton, sizeof(Button));
for(i = 0; i < conf.titlebar.nbutton; ++i)
{
flags = fetch_opt_first(button[i], "none", "flags").str;
conf.titlebar.button[i].flags = 0;
if(strstr(flags, "free"))
conf.titlebar.button[i].flags |= FreeFlag;
if(strstr(flags, "max"))
conf.titlebar.button[i].flags |= MaxFlag;
if(strstr(flags, "tile"))
conf.titlebar.button[i].flags |= TileFlag;
/* Multi mouse section */
mouse = fetch_section(button[i], "mouse");
if((conf.titlebar.button[i].nmouse = fetch_section_count(mouse)) > 0)
{
conf.titlebar.button[i].mouse = xcalloc(conf.titlebar.button[i].nmouse, sizeof(MouseBinding));
mouse_section(conf.titlebar.button[i].mouse, mouse);
}
free(mouse);
/* Multi line section */
line = fetch_section(button[i], "line");
if((conf.titlebar.button[i].nlines = fetch_section_count(line)) > 0)
{
conf.titlebar.button[i].linecoord = xcalloc(conf.titlebar.button[i].nlines, sizeof(XSegment));
for(j = 0; j < conf.titlebar.button[i].nlines; ++j)
{
opt = fetch_opt(line[j], "0", "coord");
conf.titlebar.button[i].linecoord[j].x1 = opt[0].num;
conf.titlebar.button[i].linecoord[j].y1 = opt[1].num;
conf.titlebar.button[i].linecoord[j].x2 = opt[2].num;
conf.titlebar.button[i].linecoord[j].y2 = opt[3].num;
free(opt);
}
}
free(line);
}
}
free(button);
return;
}
static void
conf_layout_section(void)
{
int i;
char *tmp = NULL, *p;
struct conf_sec *layouts, **layout;
/* Set conf.layout NULL for conf reload */
for(i = 0; i < NUM_OF_LAYOUT; ++i)
{
conf.layout[i].symbol = NULL;
conf.layout[i].func = NULL;
}
layouts = fetch_section_first(NULL, "layouts");
conf.layout_button_width = fetch_opt_first(layouts, "O", "layout_button_width").num;
conf.border.layout = fetch_opt_first(layouts, "false", "border").boolean;
conf.colors.layout_fg = fetch_opt_first(layouts, "#ffffff", "fg").str;
conf.colors.layout_bg = getcolor((fetch_opt_first(layouts, "#000000", "bg").str));
conf.keep_layout_geo = fetch_opt_first(layouts, "false", "keep_layout_geo").boolean;
conf.selected_layout_symbol = fetch_opt_first(layouts, "*", "selected_layout_symbol").str;
conf.cfactor_enable_split = fetch_opt_first(layouts, "false", "cfactor_enable_split").boolean;
if((tmp = fetch_opt_first(layouts, "menu", "system").str) && !strcmp(tmp, "menu"))
conf.layout_system = True;
layout = fetch_section(layouts, "layout");
conf.nlayout = fetch_section_count(layout);
if(conf.nlayout > NUM_OF_LAYOUT || !(conf.nlayout))
{
warnx("configuration : Too many or no layouts (%d).", conf.nlayout);
conf.nlayout = 1;
conf.layout[0].symbol = xstrdup("TILE");
conf.layout[0].func = tile;
}
if(conf.layout_system && conf.nlayout > 1)
{
menu_init(&menulayout, "menulayout", conf.nlayout,
/* Colors */
conf.colors.layout_bg,
conf.colors.layout_fg,
conf.colors.bar,
conf.colors.text);
}
if(!conf.layout[0].symbol
&& !conf.layout[0].func)
{
for(i = 0; i < conf.nlayout; ++i)
{
if(!name_to_func((p = fetch_opt_first(layout[i], "tile", "type").str), layout_list))
warnx("configuration : Unknown Layout type : \"%s\".", p);
else
{
if(conf.layout_system && conf.nlayout > 1)
{
menu_new_item(&menulayout.item[i], fetch_opt_first(layout[i], "", "symbol").str,
uicb_set_layout, p);
menulayout.item[i].check = name_to_func("check_layout", func_list);
}
conf.layout[i].symbol = fetch_opt_first(layout[i], "TILE (default)", "symbol").str;
conf.layout[i].func = name_to_func(p, layout_list);
conf.layout[i].type = p;
}
}
}
free(layout);
return;
}
static void
conf_tag_section(void)
{
int i, j, k, l = 0, n, sc, bar_pos;
char *tmp;
char *position;
struct conf_sec *sec, *def_tag, **tag, **mouse;
sec = fetch_section_first(NULL, "tags");
conf.tag_round = fetch_opt_first(sec, "false", "tag_round").boolean;
conf.tag_auto_prev = fetch_opt_first(sec, "true", "tag_auto_prev").boolean;
conf.colors.tagselfg = fetch_opt_first(sec, "#ffffff", "sel_fg").str;
conf.colors.tagselbg = getcolor(fetch_opt_first(sec, "#000000", "sel_bg").str);
conf.colors.tagurfg = fetch_opt_first(sec, "#000000", "urgent_fg").str;
conf.colors.tagurbg = getcolor(fetch_opt_first(sec, "#DD1111", "urgent_bg").str);
conf.colors.tag_occupied_bg = getcolor(fetch_opt_first(sec, "#222222", "occupied_bg").str);
conf.colors.tag_occupied_fg = fetch_opt_first(sec, conf.colors.text, "occupied_fg").str;
conf.border.tag = fetch_opt_first(sec, "false", "border").boolean;
conf.tagautohide = fetch_opt_first(sec, "false", "autohide").boolean;
conf.tagnamecount = fetch_opt_first(sec, "false", "name_count").boolean;
conf.tag_expose_name = fetch_opt_first(sec, "EXPOSE", "expose_name").str;
conf.expose_layout = fetch_opt_first(sec, "tile_grid_vertical", "expose_layout").str;
def_tag = fetch_section_first(sec, "default_tag");
position = fetch_opt_first(def_tag, "top", "infobar_position").str;
if(!strcmp(position, "none")
|| !strcmp(position, "hide")
|| !strcmp(position, "hidden"))
bar_pos = IB_Hide;
else if(!strcmp(position, "bottom")
|| !strcmp(position, "down"))
bar_pos = IB_Bottom;
else
bar_pos = IB_Top;
/* If there is no tag in the conf or more than
* MAXTAG (36) print an error and create only one.
*/
Tag default_tag =
{
fetch_opt_first(def_tag, "new tag", "name").str,
NULL,
1,
fetch_opt_first(def_tag, "0.6", "mwfact").fnum,
fetch_opt_first(def_tag, "1", "nmaster").num,
0,
bar_pos,
bar_pos,
layout_name_to_struct(conf.layout, fetch_opt_first(def_tag, "tile", "layout").str, conf.nlayout, layout_list),
0,
NULL,
0
};
FLAGAPPLY(default_tag.flags,
fetch_opt_first(def_tag, "false", "resizehint").boolean,
ResizeHintFlag);
FLAGAPPLY(default_tag.flags,
fetch_opt_first(def_tag, "false", "split").boolean,
(SplitFlag | FirstArrangeFlag));
conf.default_tag = default_tag;
/* Mouse button action on tag */
conf.mouse_tag_action[TagSel] =
char_to_button(fetch_opt_first(sec, "1", "mouse_button_tag_sel").str, mouse_button_list);
conf.mouse_tag_action[TagTransfert] =
char_to_button(fetch_opt_first(sec, "2", "mouse_button_tag_transfert").str, mouse_button_list);
conf.mouse_tag_action[TagAdd] =
char_to_button(fetch_opt_first(sec, "3", "mouse_button_tag_add").str, mouse_button_list);
conf.mouse_tag_action[TagNext] =
char_to_button(fetch_opt_first(sec, "4", "mouse_button_tag_next").str, mouse_button_list);
conf.mouse_tag_action[TagPrev] =
char_to_button(fetch_opt_first(sec, "5", "mouse_button_tag_prev").str, mouse_button_list);
sc = screen_count();
/* Alloc all */
conf.ntag = xcalloc(sc, sizeof(*conf.ntag));
tags = xcalloc(sc, sizeof(*tags));
seltag = xcalloc(sc, sizeof(*seltag));
prevseltag = xcalloc(sc, sizeof(*prevseltag));
for(i = 0; i < sc; ++i)
seltag[i] = 1;
tag = fetch_section(sec, "tag");
n = fetch_section_count(tag);
for(i = 0; i < sc; ++i)
tags[i] = xcalloc(n + 2, sizeof(Tag));
for(i = 0; i < n; i++)
{
j = fetch_opt_first(tag[i], "-1", "screen").num;
if(j < 0 || j > sc - 1)
j = -1;
for(k = ((j == -1) ? 0 : j);
((j == -1) ? (k < sc) : !l);
((j == -1) ? ++k : --l))
{
++conf.ntag[k];
tags[k][conf.ntag[k]].name = fetch_opt_first(tag[i], fetch_opt_first(def_tag, "", "name").str, "name").str;
tags[k][conf.ntag[k]].mwfact = fetch_opt_first(tag[i], fetch_opt_first(def_tag, "0.65", "mwfact").str, "mwfact").fnum;
tags[k][conf.ntag[k]].nmaster = fetch_opt_first(tag[i], fetch_opt_first(def_tag, "1", "nmaster").str, "nmaster").num;
FLAGAPPLY(tags[k][conf.ntag[k]].flags,
fetch_opt_first(tag[i], fetch_opt_first(def_tag, "false", "resizehint").str, "resizehint").boolean,
ResizeHintFlag);
FLAGAPPLY(tags[k][conf.ntag[k]].flags,
fetch_opt_first(tag[i], "false", "abovefc").boolean,
AboveFCFlag);
FLAGAPPLY(tags[k][conf.ntag[k]].flags,
fetch_opt_first(tag[i], "false", "split").boolean,
(SplitFlag | FirstArrangeFlag));
tmp = fetch_opt_first(tag[i], fetch_opt_first(def_tag, "top", "infobar_position").str, "infobar_position").str;
if(!strcmp(tmp ,"none") || !strcmp(tmp, "hide") || !strcmp(tmp, "hidden"))
tags[k][conf.ntag[k]].barpos = IB_Hide;
else if(!strcmp(tmp, "bottom") || !strcmp(tmp, "down"))
tags[k][conf.ntag[k]].barpos = IB_Bottom;
else
tags[k][conf.ntag[k]].barpos = IB_Top;
tags[k][conf.ntag[k]].layout = layout_name_to_struct(conf.layout,
fetch_opt_first(tag[i], fetch_opt_first(def_tag, "tile", "layout").str, "layout").str,
conf.nlayout,
layout_list);
/* Multi mouse sections */
mouse = fetch_section(tag[i], "mouse");
if((tags[k][conf.ntag[k]].nmouse = fetch_section_count(mouse)))
{
tags[k][conf.ntag[k]].mouse = xcalloc(tags[k][conf.ntag[k]].nmouse, sizeof(MouseBinding));
mouse_section(tags[k][conf.ntag[k]].mouse, mouse);
}
free(mouse);
}
l = 0;
}
for(i = 0; i < sc; ++i)
if(!conf.ntag[i] || conf.ntag[i] > MAXTAG)
{
warnx("configuration : Too many or no tag (%d) in the screen %d.", conf.ntag[i], i);
conf.ntag[i] = 1;
tags[i][1] = default_tag;
}
free(tag);
return;
}
static void
conf_rule_section(void)
{
int i;
struct conf_sec *rules, **rule;
if ((rules = fetch_section_first(NULL, "rules")) == NULL)
return;
rule = fetch_section(rules, "rule");
CHECK((conf.nrule = fetch_section_count(rule)));
conf.rule = xcalloc(conf.nrule, sizeof(Rule));
for(i = 0; i < conf.nrule; ++i)
{
conf.rule[i].class = fetch_opt_first(rule[i], "", "class").str;
conf.rule[i].instance = fetch_opt_first(rule[i], "", "instance").str;
conf.rule[i].role = fetch_opt_first(rule[i], "", "role").str;
conf.rule[i].name = fetch_opt_first(rule[i], "", "name").str;
conf.rule[i].screen = fetch_opt_first(rule[i], "-1", "screen").num;
conf.rule[i].tag = fetch_opt_first(rule[i], "-1", "tag").num;
conf.rule[i].free = fetch_opt_first(rule[i], "false", "free").boolean;
conf.rule[i].max = fetch_opt_first(rule[i], "false", "max").boolean;
conf.rule[i].ignoretags = fetch_opt_first(rule[i], "false", "ignoretags").boolean;
conf.rule[i].follow_client = fetch_opt_first(rule[i], "false", "follow_client").boolean;
}
free(rule);
return;
}
static void
conf_menu_section(void)
{
char *tmp2;
int i, j;
struct conf_sec *menu, **set_menu, **item;
menu = fetch_section_first(NULL, "menu");
set_menu = fetch_section(menu, "set_menu");
CHECK((conf.nmenu = fetch_section_count(set_menu)));
conf.menu = xcalloc(conf.nmenu, sizeof(Menu));
for(i = 0; i < conf.nmenu; ++i)
{
conf.menu[i].name = fetch_opt_first(set_menu[i], "menu_wname", "name").str;
if(!(conf.menu[i].place_at_mouse = fetch_opt_first(set_menu[i], "true", "place_at_mouse").boolean))
{
conf.menu[i].x = fetch_opt_first(set_menu[i], "0", "x").num;
conf.menu[i].y = fetch_opt_first(set_menu[i], "0", "y").num;
}
tmp2 = fetch_opt_first(set_menu[i], "center", "align").str;
if(!strcmp(tmp2 ,"left"))
conf.menu[i].align = MA_Left;
else if(!strcmp(tmp2, "right"))
conf.menu[i].align = MA_Right;
else
conf.menu[i].align = MA_Center;
conf.menu[i].colors.focus.bg = getcolor(fetch_opt_first(set_menu[i], "#000000", "bg_focus").str);
conf.menu[i].colors.focus.fg = fetch_opt_first(set_menu[i], "#ffffff", "fg_focus").str;
conf.menu[i].colors.normal.bg = getcolor(fetch_opt_first(set_menu[i], "#000000", "bg_normal").str);
conf.menu[i].colors.normal.fg = fetch_opt_first(set_menu[i], "#ffffff", "fg_normal").str;
item = fetch_section(set_menu[i], "item");
if((conf.menu[i].nitem = fetch_section_count(item)))
{
conf.menu[i].item = xcalloc(conf.menu[i].nitem, sizeof(MenuItem));
for(j = 0; j < conf.menu[i].nitem; ++j)
{
conf.menu[i].item[j].name = fetch_opt_first(item[j], "item_wname", "name").str;
conf.menu[i].item[j].func = name_to_func(fetch_opt_first(item[j], "", "func").str, func_list);
conf.menu[i].item[j].cmd = fetch_opt_first(item[j], "", "cmd").str;
conf.menu[i].item[j].check = name_to_func(fetch_opt_first(item[j], "", "check").str, func_list);
conf.menu[i].item[j].submenu = fetch_opt_first(item[j], "", "submenu").str;
}
}
free(item);
}
free(set_menu);
return;
}
static void
conf_launcher_section(void)
{
int i;
struct conf_sec *launcher, **set_launcher;
launcher = fetch_section_first(NULL, "launcher");
set_launcher = fetch_section(launcher, "set_launcher");
CHECK((conf.nlauncher = fetch_section_count(set_launcher)));
conf.launcher = xcalloc(conf.nlauncher, sizeof(Launcher));
for(i = 0; i < conf.nlauncher; ++i)
{
conf.launcher[i].name = fetch_opt_first(set_launcher[i], "launcher", "name").str;
conf.launcher[i].prompt = fetch_opt_first(set_launcher[i], "Exec:", "prompt").str;
conf.launcher[i].command = fetch_opt_first(set_launcher[i], "exec", "command").str;
conf.launcher[i].width = fetch_opt_first(set_launcher[i], "0", "width_limit").num;
conf.launcher[i].nhisto = 1;
}
free(set_launcher);
return;
}
static void
conf_keybind_section(void)
{
int i;
size_t j;
struct conf_sec *sec, **ks;
struct opt_type *opt;
sec = fetch_section_first(NULL, "keys");
ks = fetch_section(sec, "key");
conf.nkeybind = fetch_section_count(ks);
keys = xcalloc(conf.nkeybind, sizeof(Key));
for(i = 0; i < conf.nkeybind; ++i)
{
opt = fetch_opt(ks[i], "", "mod");
for(j = 0; j < fetch_opt_count(opt); ++j)
keys[i].mod |= char_to_modkey(opt[j].str, key_list);
free(opt);
keys[i].keysym = XStringToKeysym(fetch_opt_first(ks[i], "None", "key").str);
keys[i].func = name_to_func(fetch_opt_first(ks[i], "", "func").str, func_list);
if(keys[i].func == NULL)
{
warnx("configuration : Unknown Function \"%s\".", fetch_opt_first(ks[i], "", "func").str);
keys[i].func = uicb_spawn;
}
keys[i].cmd = fetch_opt_first(ks[i], "", "cmd").str;
}
free(ks);
return;
}
/** Configuration initialization
*/
void
init_conf(void)
{
if(get_conf(conf.confpath) == -1)
{
warnx("parsing configuration file (%s) failed.", conf.confpath);
sprintf(conf.confpath, "%s/wmfs/wmfsrc", XDG_CONFIG_DIR);
warnx("Use the default configuration (%s).", conf.confpath);
if(get_conf(conf.confpath) == -1)
errx(1, "parsing configuration file (%s) failed.", conf.confpath);
}
conf_misc_section();
conf_bar_section();
conf_root_section();
conf_client_section();
conf_layout_section();
conf_tag_section();
conf_rule_section();
conf_menu_section();
conf_launcher_section();
conf_keybind_section();
print_unused(NULL);
return;
}
-285
View File
@@ -1,285 +0,0 @@
/*
* draw.c
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "wmfs.h"
#ifdef HAVE_IMLIB
static int sw = 0;
/** Draw an image in a drawable
* \param dr Drawable
* \param x X position
* \param y Y position
* \param name Path of the image
*/
static void
draw_image(Drawable dr, int x, int y, int w, int h, char *name)
{
Imlib_Image image;
if(!dr)
return;
imlib_context_set_display(dpy);
imlib_context_set_visual(DefaultVisual(dpy, DefaultScreen(dpy)));
imlib_context_set_colormap(DefaultColormap(dpy, DefaultScreen(dpy)));
imlib_context_set_drawable(dr);
image = imlib_load_image(patht(name));
imlib_context_set_image(image);
if(w <= 0)
w = imlib_image_get_width();
if(h <= 0)
h = imlib_image_get_height();
if(image)
imlib_render_image_on_drawable_at_size(x, y, w, h);
else
warnx("Can't draw image: '%s'", name);
imlib_free_image();
return;
}
/** Check images blocks in str and return properties
* --> \i[x;y;w;h;name]\
*\param im ImageAttr pointer, image properties
*\param str String
*\param m Check dynamic mouse
*\return n Lenght of i
*/
static void
parse_image_block(Drawable dr, char *str, bool m)
{
ImageAttr im;
Geo area;
char as, mouse[512] = { 0 };
int i = 0, j = 0, k = 0, n;
for(; i < (int)strlen(str); ++i, ++j)
if(((n = sscanf(&str[i], "\\i[%d;%d;%d;%d;%512[^];]]%c",
&im.x, &im.y, &im.w, &im.h, im.name, &as)) == 6
|| (n = sscanf(&str[i], "\\i[%d;%d;%d;%d;%512[^;];%512[^]]]%c",
&im.x, &im.y, &im.w, &im.h, im.name, mouse, &as)) == 7)
&& as == '\\')
{
draw_image(dr, im.x - sw, im.y, im.w, im.h, im.name);
/* Etablish clickable area on image (on infobar wins only (status mouse bind) */
if(n == 7 && m)
{
area.x = im.x - sw;
area.y = im.y;
area.width = im.w;
area.height = im.h;
/* Associate drawable with window; travel infobars */
for(; k < screen_count(); ++k)
if(infobar[k].bar->dr == dr)
{
statustext_mouse(mouse, area, &infobar[k]);
break;
}
}
for(++i, --j; str[i] != as || str[i - 1] != ']'; ++i);
}
else if(j != i)
str[j] = str[i];
for(sw = 0, k = j; k < i; str[k++] = 0);
return;
}
#endif /* HAVE_IMLIB */
/** Draw a string in a Drawable
* \param d Drawable
* \param x X position
* \param y Y position
* \param fg Foreground text color
* \param pad Text padding
* \param str String that will be draw
*/
void
draw_text(Drawable d, int x, int y, char* fg, char *str)
{
CHECK(str);
/* To draw image everywhere we can draw text */
#ifdef HAVE_IMLIB
char *ostr;
size_t textlen = 0;
if(strstr(str, "i["))
{
if(d == infobar[conf.systray.screen].bar->dr)
sw = systray_get_width();
ostr = xstrdup(str);
textlen = strlen(ostr);
parse_image_block(d, str, True);
}
#endif /* HAVE_IMLIB */
#ifdef HAVE_XFT
if(conf.use_xft)
{
XftColor xftcolor;
XftDraw *xftd;
/* Transform X Drawable -> Xft Drawable */
xftd = XftDrawCreate(dpy, d, DefaultVisual(dpy, SCREEN), DefaultColormap(dpy, SCREEN));
/* Alloc text color */
XftColorAllocName(dpy, DefaultVisual(dpy, SCREEN),
DefaultColormap(dpy, SCREEN), fg, &xftcolor);
XftDrawStringUtf8(xftd, &xftcolor, font.font, x, y, (FcChar8 *)str, strlen(str));
/* Free the text color and XftDraw */
XftColorFree(dpy, DefaultVisual(dpy, SCREEN), DefaultColormap(dpy, SCREEN), &xftcolor);
XftDrawDestroy(xftd);
}
else
#endif /* HAVE_XFT */
{
/* Use font set */
XSetForeground(dpy, gc, getcolor(fg));
XmbDrawString(dpy, d, font.fontset, gc, x, y, str, strlen(str));
}
#ifdef HAVE_IMLIB
if(textlen)
{
strncpy(str, ostr, textlen);
free(ostr);
}
#endif /* HAVE_IMLIB */
return;
}
/** Draw a Rectangle in a drawable
* \param dr Drawable
* \param x X position
* \param y Y position
* \param w Width
* \param h Height
* \param color Color of the rectangle
*/
void
draw_rectangle(Drawable dr, int x, int y, int w, int h, uint color)
{
XSetForeground(dpy, gc, color);
XFillRectangle(dpy, dr, gc, x, y, (uint)w, (uint)h);
return;
}
/** Draw a Graph in a drawable
* \param dr Drawable
* \param x X position
* \param y Y position
* \param w Width
* \param h Height
* \param color Color of the graph
* \param data Array of bytes that will be draw
*/
void
draw_graph(Drawable dr, int x, int y, int w, int h, uint color, char *data)
{
int i;
for(i = 0; i < w; ++i)
draw_rectangle(dr, x + i, y + h - data[i], 1, data[i], color);
return;
}
/** Calculates the text's size relatively to the font
* \param text Text string
* \return final text width
*/
ushort
textw(char *text)
{
Drawable d = 0;
ushort ret = 0;
if(!text)
return 0;
#ifdef HAVE_IMLIB
char *ostr;
size_t textlen = 0;
if(strstr(text, "i["))
{
ostr = xstrdup(text);
textlen = strlen(ostr);
parse_image_block(d, text, False);
}
#endif /* HAVE_IMLIB */
#ifdef HAVE_XFT
if(conf.use_xft)
{
XGlyphInfo gl;
XftTextExtentsUtf8(dpy, font.font, (FcChar8 *)text, strlen(text), &gl);
ret = gl.width + font.de;
}
else
#endif /* HAVE_XFT */
{
XRectangle r;
XmbTextExtents(font.fontset, text, strlen(text), NULL, &r);
ret = r.width;
}
#ifdef HAVE_IMLIB
if(textlen)
{
strncpy(text, ostr, textlen);
free(ostr);
}
#endif /* HAVE_IMLIB */
return ret;
}
-716
View File
@@ -1,716 +0,0 @@
/*
* event.c
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "wmfs.h"
#define EVDPY (e->xany.display)
#define MAX_EV 256
/** Check mouse bind condition and execute associated function
*/
static void
do_mousebind(int screen, uint button, int n, MouseBinding m[])
{
int i = 0;
for(; i < n; ++i)
{
if(m[i].screen == screen || m[i].screen < 0) /* Screen */
if(m[i].tag == seltag[i] || m[i].tag < 0) /* Tag */
if(m[i].button == button) /* Button */
if(m[i].func) /* Function */
m[i].func(m[i].cmd);
}
return;
}
/** ButtonPress handle event
*/
static void
buttonpress(XEvent *e)
{
XButtonEvent *ev = &e->xbutton;
StatusMouse *sm;
InfoBar *ib;
Client *c;
int i, n;
screen_get_sel();
ib = &infobar[selscreen];
/* If the mouse is on a not selected client and you click on it. */
if(((c = client_gb_win(ev->window)) || (c = client_gb_titlebar(ev->window)))
&& c != sel && ev->button >= Button1 && ev->button <= Button3)
{
client_focus(c);
client_raise(c);
return;
}
/* Titlebar */
if((c = client_gb_titlebar(ev->window)) && c == sel)
do_mousebind(selscreen, ev->button, conf.titlebar.nmouse, conf.titlebar.mouse);
/* Titlebar buttons */
if((c = client_gb_button(ev->window, &n)))
for(i = 0; i < conf.titlebar.button[n].nmouse; ++i)
if(ev->button == conf.titlebar.button[n].mouse[i].button)
if(conf.titlebar.button[n].mouse[i].func)
{
client_focus(c);
conf.titlebar.button[n].mouse[i].func(conf.titlebar.button[n].mouse[i].cmd);
}
/* Frame Resize Area */
if((c = client_gb_resize(ev->window)))
mouse_resize(c);
/* Client */
if((c = client_gb_win(ev->window)) && c == sel)
do_mousebind(selscreen, ev->button, conf.client.nmouse, conf.client.mouse);
/* Root */
if(ev->window == ROOT)
do_mousebind(selscreen, ev->button, conf.root.nmouse, conf.root.mouse);
/* Infobars */
for(i = 0; i < screen_count(); ++i)
if(ev->window == infobar[i].bar->win)
do_mousebind(i, ev->button, conf.bars.nmouse, conf.bars.mouse);
/* Selbar */
if(conf.bars.selbar && ev->window == ib->bar->win)
if(INAREA(ev->x, ev->y, ib->selbar_geo))
do_mousebind(selscreen, ev->button, conf.selbar.nmouse, conf.selbar.mouse);
/* Tags */
if(ib->tags_board)
{
for(i = 1; i < conf.ntag[selscreen] + 1; ++i)
if(ib->tags[i] && ev->window == ib->tags[i]->win)
{
do_mousebind(selscreen, ev->button, tags[selscreen][i].nmouse, tags[selscreen][i].mouse);
/* Mouse button action on tag */
if(ev->button == conf.mouse_tag_action[TagSel])
tag_set(i);
else if(ev->button == conf.mouse_tag_action[TagTransfert])
tag_transfert(sel, i);
else if(ev->button == conf.mouse_tag_action[TagAdd])
tag_additional(selscreen, seltag[selscreen], i);
else if(ev->button == conf.mouse_tag_action[TagNext])
tag_set(seltag[selscreen] + 1);
else if(ev->button == conf.mouse_tag_action[TagPrev])
tag_set(seltag[selscreen] - 1);
}
}
/* Layout button */
if(ib->layout_button && ev->window == ib->layout_button->win && conf.nlayout > 1)
{
if(conf.layout_system && (ev->button == Button1 || ev->button == Button3)) /* True -> menu */
{
menulayout.y = spgeo[selscreen].y + ib->layout_button->geo.y + INFOBARH;
menulayout.x = ib->layout_button->geo.x + (sgeo[selscreen].x - BORDH);
if(ib->geo.y != spgeo[selscreen].y)
menulayout.y = ib->geo.y - (INFOBARH * menulayout.nitem) - SHADH;
uicb_menu("menulayout");
}
else
layoutswitch(ev->button == Button1 || ev->button == Button4);
}
/* Status mouse bindings */
SLIST_FOREACH(sm, &smhead, next)
if(sm->infobar->bar->win == ev->window && ev->button == sm->button)
if(INAREA(ev->x, ev->y, sm->area))
if(sm->func)
sm->func(sm->cmd);
return;
}
/* ClientMessage handle event
*/
static void
clientmessageevent(XEvent *e)
{
XClientMessageEvent *ev = &e->xclient;
Client *c;
InfoBar *ib;
Systray *sy;
int s, mess_t = 0;
Atom rt;
int rf;
ulong ir, il;
uchar *ret = NULL;
uchar *ret_cmd = NULL;
void (*func)(uicb_t);
if(ev->format != 32)
return;
s = screen_count();
while(mess_t < net_last + s && net_atom[mess_t] != ev->message_type)
++mess_t;
if(ev->window == ROOT)
{
/* Manage _NET_CURRENT_DESKTOP */
if(mess_t == net_current_desktop
&& ev->data.l[0] >= 0
&& ev->data.l[0] < conf.ntag[selscreen])
tag_set((int)(ev->data.l[0] + 1));
/* Manage _WMFS_SET_SCREEN */
if(mess_t == wmfs_set_screen
&& ev->data.l[0] >= 0
&& ev->data.l[0] <= s)
screen_set_sel((int)(ev->data.l[0]));
/* Manage _NET_ACTIVE_WINDOW */
else if(mess_t == net_active_window)
{
if((c = client_gb_win(ev->window)))
client_focus(c);
else if((sy = systray_find(ev->data.l[0])))
XSetInputFocus(EVDPY, sy->win, RevertToNone, CurrentTime);
}
}
else if(ev->window == traywin)
{
/* Manage _NET_WM_SYSTEM_TRAY_OPCODE */
if(mess_t == net_wm_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);
}
}
/* Manage _NET_WM_STATE */
if(mess_t == net_wm_state)
if((c = client_gb_win(ev->window)))
ewmh_manage_net_wm_state(ev->data.l, c);
/* Manage _NET_CLOSE_WINDOW */
if(mess_t == net_close_window)
if((c = client_gb_win(ev->window)))
client_kill(c);
/* Manage _NET_WM_DESKTOP */
if(mess_t == net_wm_desktop)
if((c = client_gb_win(ev->window)) && ev->data.l[0] != (long)0xFFFFFFFF)
tag_transfert(c, ev->data.l[0]);
if(ev->data.l[4])
{
/* Manage _WMFS_STATUSTEXT_x */
if(mess_t >= wmfs_statustext)
{
if(XGetWindowProperty(EVDPY, ROOT, net_atom[mess_t], 0, 4096,
False, net_atom[utf8_string], &rt, &rf, &ir, &il, &ret) == Success)
{
ib = &infobar[mess_t - wmfs_statustext];
free(ib->statustext);
ib->statustext = xstrdup((char*)ret);
_infobar_draw(ib);
XFree(ret);
}
}
/* Manage _WMFS_FUNCTION && _WMFS_CMD */
if(mess_t == wmfs_function || mess_t == wmfs_cmd)
{
XGetWindowProperty(EVDPY, ROOT, net_atom[wmfs_function], 0, 4096,
False, net_atom[utf8_string], &rt, &rf, &ir, &il, &ret);
XGetWindowProperty(EVDPY, ROOT, net_atom[wmfs_cmd], 0, 4096,
False, net_atom[utf8_string], &rt, &rf, &ir, &il, &ret_cmd);
if((func = name_to_func((char*)ret, func_list)))
func((uicb_t)ret_cmd);
XFree(ret_cmd);
XFree(ret);
}
}
/* Manage _WMFS_UPDATE_HINTS */
if(mess_t == wmfs_update_hints)
{
ewmh_get_number_of_desktop();
ewmh_update_current_tag_prop();
ewmh_get_client_list();
ewmh_get_desktop_names();
ewmh_set_desktop_geometry();
screen_count();
screen_get_sel();
}
return;
}
/** ConfigureRequesthandle events
*/
static void
configureevent(XEvent *e)
{
XConfigureRequestEvent *ev = &e->xconfigurerequest;
XWindowChanges wc;
Client *c;
/* Check part */
if(((c = client_gb_win(ev->window)) || (c = client_gb_win(ev->window)))
&& (c->flags & (LMaxFlag | MaxFlag | FSSFlag)))
return;
if((c = client_gb_win(ev->window)))
{
if(ev->value_mask & CWX)
c->geo.x = ev->x + BORDH;
if(ev->value_mask & CWY)
c->geo.y = ev->y + TBARH;
if(ev->value_mask & CWWidth)
c->geo.width = ev->width;
if(ev->value_mask & CWHeight)
c->geo.height = ev->height;
if(c->flags & FreeFlag || !(c->flags & TileFlag))
client_moveresize(c, c->geo, False);
else
{
client_configure(c);
arrange(c->screen, True);
}
}
else
{
wc.x = ev->x;
wc.y = ev->y;
wc.width = ev->width;
wc.height = ev->height;
wc.border_width = ev->border_width;
wc.sibling = ev->above;
wc.stack_mode = ev->detail;
XConfigureWindow(EVDPY, ev->window, ev->value_mask, &wc);
}
return;
}
/** DestroyNotify handle event
*/
static void
destroynotify(XEvent *e)
{
XDestroyWindowEvent *ev = &e->xdestroywindow;
Client *c;
Systray *s;
if((c = client_gb_win(ev->window)))
{
client_unmanage(c);
XSetErrorHandler(errorhandler);
}
else if((s = systray_find(ev->window)))
{
setwinstate(s->win, WithdrawnState);
systray_del(s);
systray_update();
}
return;
}
/** EnterNotify handle event
*/
static void
enternotify(XEvent *e)
{
XCrossingEvent *ev = &e->xcrossing;
Client *c;
int n;
if((ev->mode != NotifyNormal || ev->detail == NotifyInferior)
&& ev->window != ROOT)
return;
if(tags[selscreen][seltag[selscreen]].flags & IgnoreEnterFlag)
{
tags[selscreen][seltag[selscreen]].flags &= ~IgnoreEnterFlag;
return;
}
/* Don't handle EnterNotify event if it's about systray */
if(systray_find(ev->window) || ev->window == traywin)
return;
if(conf.focus_fmouse)
{
if((c = client_gb_win(ev->window))
|| (c = client_gb_frame(ev->window))
|| (c = client_gb_titlebar(ev->window))
|| (c = client_gb_button(ev->window, &n)))
client_focus(c);
else
client_focus(NULL);
}
return;
}
/** ExposeEvent handle event
*/
static void
expose(XEvent *e)
{
XExposeEvent *ev = &e->xexpose;
Client *c;
BarWindow *bw;
/* BarWindows */
SLIST_FOREACH(bw, &bwhead, next)
if(ev->window == bw->win)
{
barwin_refresh(bw);
break;
}
/* Client frame */
if((c = client_gb_titlebar(ev->window)))
frame_update(c);
return;
}
/** FocusChange handle event
*/
static void
focusin(XEvent *e)
{
if(sel && e->xfocus.window != sel->win)
client_focus(sel);
return;
}
/** KeyPress handle event
*/
static void
keypress(XEvent *e)
{
XKeyPressedEvent *ev = &e->xkey;
KeySym keysym;
int i;
keysym = XKeycodeToKeysym(EVDPY, (KeyCode)ev->keycode, 0);
for(i = 0; i < conf.nkeybind; ++i)
if(keysym == keys[i].keysym
&& (keys[i].mod & ~(numlockmask | LockMask))
== (ev->state & ~(numlockmask | LockMask))
&& keys[i].func)
keys[i].func(keys[i].cmd);
return;
}
/** MappingNotify handle event
*/
static void
mappingnotify(XEvent *e)
{
XMappingEvent *ev = &e->xmapping;
XRefreshKeyboardMapping(ev);
if(ev->request == MappingKeyboard)
grabkeys();
return;
}
/** MapNotify handle event
*/
static void
mapnotify(XEvent *e)
{
XMapEvent *ev = &e->xmap;
Client *c;
Systray *s;
if(ev->window != ev->event && !ev->send_event)
return;
if((c = client_gb_win(ev->window)))
setwinstate(c->win, NormalState);
else if((s = systray_find(ev->window)))
{
setwinstate(s->win, NormalState);
ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, 0, 0);
}
return;
}
/** MapRequest handle event
*/
static void
maprequest(XEvent *e)
{
XMapRequestEvent *ev = &e->xmaprequest;
XWindowAttributes at;
Systray *s;
CHECK(XGetWindowAttributes(EVDPY, ev->window, &at));
CHECK(!at.override_redirect);
if((s = systray_find(ev->window)))
{
ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, 0, 0);
systray_update();
}
else if(!client_gb_win(ev->window))
client_manage(ev->window, &at, True);
return;
}
/** PropertyNotify handle event
*/
static void
propertynotify(XEvent *e)
{
XPropertyEvent *ev = &e->xproperty;
Client *c;
Systray *s;
Window trans;
XWMHints *h;
if(ev->state == PropertyDelete)
return;
if((s = systray_find(ev->window)))
{
systray_state(s);
systray_update();
}
if((c = client_gb_win(ev->window)))
{
switch(ev->atom)
{
case XA_WM_TRANSIENT_FOR:
XGetTransientForHint(EVDPY, c->win, &trans);
if((c->flags & (TileFlag | MaxFlag)) && client_gb_win(trans))
arrange(c->screen, True);
break;
case XA_WM_NORMAL_HINTS:
client_size_hints(c);
break;
case XA_WM_HINTS:
if((h = XGetWMHints(EVDPY, c->win)) && (h->flags & XUrgencyHint) && c != sel)
{
client_urgent(c, True);
XFree(h);
}
break;
case XA_WM_NAME:
client_get_name(c);
break;
default:
if(ev->atom == net_atom[net_wm_name])
client_get_name(c);
break;
}
}
return;
}
/** XReparentEvent handle event
*/
static void
reparentnotify(XEvent *ev)
{
(void)ev;
return;
}
/** SelectionClearEvent handle event
*/
static void
selectionclearevent(XEvent *ev)
{
/* Getting selection if lost it */
if(ev->xselectionclear.window == traywin)
systray_acquire();
systray_update();
return;
}
/** UnmapNotify handle event
*/
static void
unmapnotify(XEvent *e)
{
XUnmapEvent *ev = &e->xunmap;
Client *c;
Systray *s;
if((c = client_gb_win(ev->window))
&& ev->send_event
&& !(c->flags & HideFlag))
{
client_unmanage(c);
XSetErrorHandler(errorhandler);
}
if((s = systray_find(ev->window)))
{
systray_del(s);
systray_update();
}
return;
}
/** XMotionNotify handle event
*/
static void
motionnotify(XEvent *e)
{
XMotionEvent *ev = &e->xmotion;
Client *c;
if(!conf.focus_fmouse || !conf.focus_fmov)
return;
if((c = client_gb_win(ev->subwindow)))
if(c != sel)
client_focus(c);
return;
}
/** XRandr handle event
*/
#ifdef HAVE_XRANDR
void
xrandrevent(XEvent *e)
{
/* Update xrandr configuration */
if(!XRRUpdateConfiguration(e))
return;
/* Reload WMFS to update the screen(s) geometry changement */
quit();
for(; argv_global[0] && argv_global[0] == ' '; ++argv_global);
execvp(argv_global, all_argv);
}
#endif /* HAVE_XRANDR */
/** Key grabbing function
*/
void
grabkeys(void)
{
int i;
KeyCode code;
XUngrabKey(dpy, AnyKey, AnyModifier, ROOT);
for(i = 0; i < conf.nkeybind; ++i)
if((code = XKeysymToKeycode(dpy, keys[i].keysym)))
{
XGrabKey(dpy, code, keys[i].mod, ROOT, True, GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, code, keys[i].mod | LockMask, ROOT, True, GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, code, keys[i].mod | numlockmask, ROOT, True, GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, code, keys[i].mod | LockMask | numlockmask, ROOT, True, GrabModeAsync, GrabModeAsync);
}
return;
}
/** Make event handle function pointer array
*/
void
event_make_array(void)
{
int i = MAX_EV;
event_handle = xcalloc(MAX_EV, sizeof(event_handle));
/* Fill array with non-used function (do nothing) */
while(i--)
event_handle[i] = reparentnotify;
event_handle[ButtonPress] = buttonpress;
event_handle[ClientMessage] = clientmessageevent;
event_handle[ConfigureRequest] = configureevent;
event_handle[DestroyNotify] = destroynotify;
event_handle[EnterNotify] = enternotify;
event_handle[Expose] = expose;
event_handle[FocusIn] = focusin;
event_handle[KeyPress] = keypress;
event_handle[MapNotify] = mapnotify;
event_handle[MapRequest] = maprequest;
event_handle[MappingNotify] = mappingnotify;
event_handle[MotionNotify] = motionnotify;
event_handle[PropertyNotify] = propertynotify;
event_handle[ReparentNotify] = reparentnotify;
event_handle[SelectionClear] = selectionclearevent;
event_handle[UnmapNotify] = unmapnotify;
#ifdef HAVE_XRANDR
event_handle[xrandr_event + RRScreenChangeNotify] = xrandrevent;
#endif /* HAVE_XRANDR */
return;
}
-451
View File
@@ -1,451 +0,0 @@
/*
* ewmh.c
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "wmfs.h"
/* Taken From standards.freedesktop.org */
#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
#define _NET_WM_STATE_ADD 1 /* add/set property */
#define _NET_WM_STATE_TOGGLE 2 /* toggle property */
/** Init ewmh atoms
*/
void
ewmh_init_hints(void)
{
int i = 1, s, j, showing_desk = 0;
char rootn[] = "wmfs-"WMFS_VERSION;
char class[] = "wmfs", st[64];
long pid = (long)getpid();
char systray_atom[48];
s = screen_count();
net_atom = xcalloc(net_last + s, sizeof(Atom));
/* EWMH hints */
net_atom[net_supported] = ATOM("_NET_SUPPORTED");
net_atom[net_client_list] = ATOM("_NET_CLIENT_LIST");
net_atom[net_frame_extents] = ATOM("_NET_FRAME_EXTENTS");
net_atom[net_number_of_desktops] = ATOM("_NET_NUMBER_OF_DESKTOPS");
net_atom[net_current_desktop] = ATOM("_NET_CURRENT_DESKTOP");
net_atom[net_desktop_names] = ATOM("_NET_DESKTOP_NAMES");
net_atom[net_desktop_geometry] = ATOM("_NET_DESKTOP_GEOMETRY");
net_atom[net_active_window] = ATOM("_NET_ACTIVE_WINDOW");
net_atom[net_close_window] = ATOM("_NET_CLOSE_WINDOW");
net_atom[net_wm_name] = ATOM("_NET_WM_NAME");
net_atom[net_wm_pid] = ATOM("_NET_WM_PID");
net_atom[net_wm_desktop] = ATOM("_NET_WM_DESKTOP");
net_atom[net_showing_desktop] = ATOM("_NET_SHOWING_DESKTOP");
net_atom[net_wm_icon_name] = ATOM("_NET_WM_ICON_NAME");
net_atom[net_wm_window_type] = ATOM("_NET_WM_WINDOW_TYPE");
net_atom[net_supporting_wm_check] = ATOM("_NET_SUPPORTING_WM_CHECK");
net_atom[net_wm_window_opacity] = ATOM("_NET_WM_WINDOW_OPACITY");
net_atom[net_wm_window_type_normal] = ATOM("_NET_WM_WINDOW_TYPE_NORMAL");
net_atom[net_wm_window_type_dock] = ATOM("_NET_WM_WINDOW_TYPE_DOCK");
net_atom[net_wm_window_type_splash] = ATOM("_NET_WM_WINDOW_TYPE_SPLASH");
net_atom[net_wm_window_type_dialog] = ATOM("_NET_WM_WINDOW_TYPE_DIALOG");
net_atom[net_wm_icon] = ATOM("_NET_WM_ICON");
net_atom[net_wm_state] = ATOM("_NET_WM_STATE");
net_atom[net_wm_state_fullscreen] = ATOM("_NET_WM_STATE_FULLSCREEN");
net_atom[net_wm_state_sticky] = ATOM("_NET_WM_STATE_STICKY");
net_atom[net_wm_state_demands_attention] = ATOM("_NET_WM_STATE_DEMANDS_ATTENTION");
net_atom[net_wm_system_tray_opcode] = ATOM("_NET_SYSTEM_TRAY_OPCODE");
net_atom[net_system_tray_message_data] = ATOM("_NET_SYSTEM_TRAY_MESSAGE_DATA");
net_atom[net_system_tray_visual] = ATOM("_NET_SYSTEM_TRAY_VISUAL");
snprintf(systray_atom, sizeof(systray_atom), "_NET_SYSTEM_TRAY_S%d", 0/*SCREEN*/);
net_atom[net_system_tray_s] = ATOM(systray_atom);
net_atom[net_system_tray_orientation] = ATOM("_NET_SYSTEM_TRAY_ORIENTATION");
net_atom[xembed] = ATOM("_XEMBED");
net_atom[xembedinfo] = ATOM("_XEMBED_INFO");
net_atom[manager] = ATOM("MANAGER");
net_atom[utf8_string] = ATOM("UTF8_STRING");
/* WMFS hints */
net_atom[wmfs_running] = ATOM("_WMFS_RUNNING");
net_atom[wmfs_update_hints] = ATOM("_WMFS_UPDATE_HINTS");
net_atom[wmfs_set_screen] = ATOM("_WMFS_SET_SCREEN");
net_atom[wmfs_screen_count] = ATOM("_WMFS_SCREEN_COUNT");
net_atom[wmfs_current_tag] = ATOM("_WMFS_CURRENT_TAG");
net_atom[wmfs_tag_list] = ATOM("_WMFS_TAG_LIST");
net_atom[wmfs_current_screen] = ATOM("_WMFS_CURRENT_SCREEN");
net_atom[wmfs_current_layout] = ATOM("_WMFS_CURRENT_LAYOUT");
net_atom[wmfs_mwfact] = ATOM("_WMFS_MWFACT");
net_atom[wmfs_nmaster] = ATOM("_WMFS_NMASTER");
net_atom[wmfs_function] = ATOM("_WMFS_FUNCTION");
net_atom[wmfs_cmd] = ATOM("_WMFS_CMD");
net_atom[wmfs_font] = ATOM("_WMFS_FONT");
/* Multi atom _WMFS_STATUSTEXT_<screennum> */
for(j = 0; j < s; ++j)
{
sprintf(st, "_WMFS_STATUSTEXT_%d", j);
net_atom[wmfs_statustext + j] = ATOM(st);
}
XChangeProperty(dpy, ROOT, net_atom[net_supported], XA_ATOM, 32,
PropModeReplace, (uchar*)net_atom, net_last + s);
XChangeProperty(dpy, ROOT, net_atom[wmfs_running], XA_CARDINAL, 32,
PropModeReplace, (uchar*)&i, 1);
/* Set _NET_SUPPORTING_WM_CHECK */
XChangeProperty(dpy, ROOT, net_atom[net_supporting_wm_check], XA_WINDOW, 32,
PropModeReplace, (uchar*)&ROOT, 1);
XChangeProperty(dpy, ROOT, net_atom[net_wm_name], net_atom[utf8_string], 8,
PropModeReplace, (uchar*)&rootn, strlen(rootn));
XChangeProperty(dpy, ROOT, ATOM("WM_CLASS"), XA_STRING, 8,
PropModeReplace, (uchar*)&class, strlen(class));
/* Set _NET_WM_PID */
XChangeProperty(dpy, ROOT, net_atom[net_wm_pid], XA_CARDINAL, 32,
PropModeReplace, (uchar*)&pid, 1);
/* Set _NET_SHOWING_DESKTOP */
XChangeProperty(dpy, ROOT, net_atom[net_showing_desktop], XA_CARDINAL, 32,
PropModeReplace, (uchar*)&showing_desk, 1);
return;
}
/** Send ewmh message
*/
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(dpy, d, False, StructureNotifyMask, (XEvent*)&e);
XSync(dpy, False);
return;
}
/** Get xembed state
*/
long
ewmh_get_xembed_state(Window win)
{
Atom rf;
int f;
ulong n, il;
long ret = 0;
uchar *data = NULL;
if(XGetWindowProperty(dpy, win, net_atom[xembedinfo], 0L, 2, False,
net_atom[xembedinfo], &rf, &f, &n, &il, &data) != Success)
return 0;
if(rf == net_atom[xembedinfo] && n == 2)
ret = (long)data[1];
if(n && data)
XFree(data);
return ret;
}
/** Get the number of desktop (tag)
*/
void
ewmh_get_number_of_desktop(void)
{
int c = 0, i;
for(i = 0; i < screen_count(); ++i)
c += conf.ntag[i];
XChangeProperty(dpy, ROOT, net_atom[net_number_of_desktops], XA_CARDINAL, 32,
PropModeReplace, (uchar*)&c, 1);
return;
}
/** Get the current desktop
*/
void
ewmh_update_current_tag_prop(void)
{
int t;
char s[8] = { 0 };
screen_get_sel();
t = seltag[selscreen] - 1;
/* Get current desktop (tag) */
XChangeProperty(dpy, ROOT, net_atom[net_current_desktop], XA_CARDINAL, 32,
PropModeReplace, (uchar*)&t, 1);
/* Current tag name */
XChangeProperty(dpy, ROOT, net_atom[wmfs_current_tag], net_atom[utf8_string], 8,
PropModeReplace, (uchar*)tags[selscreen][seltag[selscreen]].name,
strlen(tags[selscreen][seltag[selscreen]].name));
sprintf(s, "%.3f", tags[selscreen][t + 1].mwfact);
/* Current tag mwfact */
XChangeProperty(dpy, ROOT, net_atom[wmfs_mwfact], XA_STRING, 8,
PropModeReplace, (uchar*)s, strlen(s));
/* Current nmaster */
XChangeProperty(dpy, ROOT, net_atom[wmfs_nmaster], XA_CARDINAL, 32,
PropModeReplace, (uchar*)&tags[selscreen][t + 1].nmaster, 1);
/* Current layout */
XChangeProperty(dpy, ROOT, net_atom[wmfs_current_layout], net_atom[utf8_string], 8,
PropModeReplace, (uchar*)tags[selscreen][seltag[selscreen]].layout.symbol,
strlen(tags[selscreen][seltag[selscreen]].layout.symbol));
return;
}
/** Get _NET_CLIENT_LIST
*/
void
ewmh_get_client_list(void)
{
Window *list;
Client *c;
int win_n = 0;
SLIST_FOREACH(c, &clients, next)
++win_n;
list = xcalloc(win_n, sizeof(Window));
win_n = 0;
SLIST_FOREACH(c, &clients, next)
list[win_n++] = c->win;
XChangeProperty(dpy, ROOT, net_atom[net_client_list], XA_WINDOW, 32,
PropModeReplace, (uchar *)list, win_n);
XFree(list);
return;
}
/** The desktop names
*/
void
ewmh_get_desktop_names(void)
{
char *str = NULL;
int S, s, i = 0, len = 0, pos = 0;
S = screen_count();
for(s = 0 ; s < S; ++s)
for(i = 1; i < conf.ntag[s] + 1; ++i)
len += strlen(tags[s][i].name);
str = xcalloc(len + i + 1, sizeof(char*));
for(s = 0; s < S; ++s)
for(i = 1; i < conf.ntag[s] + 1; ++i, ++pos)
{
strncpy(str + pos, tags[s][i].name, strlen(tags[s][i].name));
pos += strlen(tags[s][i].name);
str[pos] = '\0';
}
XChangeProperty(dpy, ROOT, net_atom[net_desktop_names], net_atom[utf8_string], 8,
PropModeReplace, (uchar*)str, pos);
for(i = 0; i < pos; ++i)
if(str[i] == '\0' && i < pos - 1)
str[i] = ' ';
XChangeProperty(dpy, ROOT, net_atom[wmfs_tag_list], net_atom[utf8_string], 8,
PropModeReplace, (uchar*)str, pos);
free(str);
return;
}
/** Manage _NET_DESKTOP_GEOMETRY
*/
void
ewmh_set_desktop_geometry(void)
{
long data[2] = { MAXW, MAXH };
XChangeProperty(dpy, ROOT, net_atom[net_desktop_geometry], XA_CARDINAL, 32,
PropModeReplace, (uchar*)&data, 2);
return;
}
/** Manage _NET_WM_STATE_* ewmh
*/
void
ewmh_manage_net_wm_state(long data_l[], Client *c)
{
/* Manage _NET_WM_STATE_FULLSCREEN */
if(data_l[1] == (long)net_atom[net_wm_state_fullscreen])
{
if(data_l[0] == _NET_WM_STATE_ADD && !(c->flags & FSSFlag))
{
c->screen = screen_get_with_geo(c->geo.x, c->geo.y);
c->flags &= ~UnmapFlag;
XMapWindow(dpy, c->win);
XReparentWindow(dpy, c->win, ROOT, spgeo[c->screen].x, spgeo[c->screen].y);
XResizeWindow(dpy, c->win,
spgeo[c->screen].width,
spgeo[c->screen].height);
XChangeProperty(dpy, c->win, net_atom[net_wm_state], XA_ATOM, 32,
PropModeReplace, (uchar *)&net_atom[net_wm_state_fullscreen], 1);
c->tmp_geo = c->geo;
if(c->flags & FreeFlag)
c->ogeo = c->geo;
c->flags |= (FSSFlag | MaxFlag);
client_raise(c);
client_focus(c);
XUnmapWindow(dpy, c->frame);
}
else if(data_l[0] == _NET_WM_STATE_REMOVE && (c->flags & FSSFlag))
{
XChangeProperty(dpy, c->win, net_atom[net_wm_state], XA_ATOM, 32, PropModeReplace, (uchar *)0, 0);
c->flags &= ~(FSSFlag | MaxFlag);
client_map(c);
XReparentWindow(dpy, c->win, c->frame, BORDH, TBARH);
client_moveresize(c, c->tmp_geo, False);
}
}
/* Manage _NET_WM_STATE_STICKY */
else if(data_l[1] == (long)net_atom[net_wm_state_sticky])
{
/* == client_ignore_tag */
c->tag = MAXTAG + 1;
arrange(c->screen, True);
}
/* Manage _NET_WM_STATE_DEMANDS_ATTENTION */
else if(data_l[1] == (long)net_atom[net_wm_state_demands_attention])
{
if(data_l[0] == _NET_WM_STATE_ADD)
client_urgent(c, True);
if(data_l[0] == _NET_WM_STATE_REMOVE)
if(c == sel)
client_focus(NULL);
}
return;
}
/** Manage the client hints
*\param c Client pointer
*/
void
ewmh_manage_window_type(Client *c)
{
Atom *atom, rf;
int f;
ulong n, il, i;
uchar *data = NULL;
long ldata[5] = { 0 };
if(XGetWindowProperty(dpy, c->win, 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_DOCK & _NET_WM_WINDOW_TYPE_SPLASH */
if(atom[i] == net_atom[net_wm_window_type_dock]
|| atom[i] == net_atom[net_wm_window_type_splash])
{
/* Unmap frame, decoration.. */
client_unmap(c);
/* Map only window */
XMapWindow(dpy, c->win);
/* Reparent it to ROOT win */
XReparentWindow(dpy, c->win, ROOT, c->geo.x, c->geo.y);
XRaiseWindow(dpy, c->win);
c->flags |= DockFlag;
}
/* MANAGE _NET_WM_WINDOW_TYPE_DIALOG */
else if(atom[i] == net_atom[net_wm_window_type_dialog])
{
c->flags |= FreeFlag;
c->flags &= ~(TileFlag | MaxFlag | LMaxFlag);
client_moveresize(c, c->ogeo, True);
client_focus(c);
layout_func(selscreen, seltag[selscreen]);
}
}
XFree(data);
}
/* Get NET_WM_STATE set without sending client message event */
if(XGetWindowProperty(dpy, c->win, 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)
{
ldata[0] = _NET_WM_STATE_ADD;
ldata[1] = atom[i];
ewmh_manage_net_wm_state(ldata, c);
}
XFree(data);
}
return;
}
-320
View File
@@ -1,320 +0,0 @@
/*
* frame.c
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "wmfs.h"
/** Frame creation function, for make a
* client frame, and configure it
* \param c Client pointer
*/
void
frame_create(Client *c)
{
XSetWindowAttributes at;
int i;
at.background_pixel = conf.client.bordernormal;
at.background_pixmap = ParentRelative;
at.override_redirect = True;
at.bit_gravity = StaticGravity;
at.event_mask = SubstructureRedirectMask|SubstructureNotifyMask
|ExposureMask|VisibilityChangeMask
|EnterWindowMask|LeaveWindowMask|FocusChangeMask
|KeyMask|ButtonMask|MouseMask;
/* Set property */
c->frame_geo.x = c->geo.x - BORDH;
c->frame_geo.y = c->geo.y - TBARH;
c->frame_geo.width = FRAMEW(c->geo.width);
c->frame_geo.height = FRAMEH(c->geo.height);
c->colors.fg = conf.titlebar.fg_normal;
c->colors.frame = conf.client.bordernormal;
c->colors.resizecorner = conf.client.resizecorner_normal;
/* Create frame window */
CWIN(c->frame, ROOT,
c->frame_geo.x,
c->frame_geo.y,
c->frame_geo.width,
c->frame_geo.height, 0,
CWOverrideRedirect | CWBackPixmap | CWEventMask,
c->colors.frame, &at);
/* Create titlebar window */
if(TBARH - BORDH)
{
c->titlebar = barwin_create(c->frame, 0, 0,
c->frame_geo.width ,
TBARH,
c->colors.frame,
c->colors.fg,
True, conf.titlebar.stipple.active, False);
/* Buttons */
if(BUTTONWH >= 1)
{
c->button = xcalloc(conf.titlebar.nbutton, sizeof(Window));
for(i = 0; i < conf.titlebar.nbutton; ++i)
{
CWIN(c->button[i], c->titlebar->win,
(c->button_last_x = (BORDH + (BUTTONWH * i) + (i << 2))),
((BUTTONWH - 1) >> 1), BUTTONWH, BUTTONWH,
1, CWEventMask|CWOverrideRedirect|CWBackPixmap,
c->colors.frame, &at);
XSetWindowBorder(dpy, c->button[i], getcolor(c->colors.fg));
}
}
}
at.event_mask &= ~(EnterWindowMask | LeaveWindowMask); /* <- Delete useless mask */
/* Create resize area */
at.cursor = cursor[CurRightResize];
CWIN(c->resize[Right], c->frame,
c->frame_geo.width - RESHW,
c->frame_geo.height - RESHW,
RESHW, RESHW, 0,
CWEventMask | CWBackPixel | CWCursor,
c->colors.resizecorner, &at);
at.cursor = cursor[CurLeftResize];
CWIN(c->resize[Left], c->frame,
0, c->frame_geo.height - RESHW,
RESHW, RESHW, 0,
CWEventMask | CWBackPixel | CWCursor,
c->colors.resizecorner, &at);
/* Border (for shadow) */
if(conf.client.border_shadow)
{
c->colors.borddark = color_shade(c->colors.frame, conf.colors.client_dark_shade);
c->colors.bordlight = color_shade(c->colors.frame, conf.colors.client_light_shade);
CWIN(c->left, c->frame, 0, 0, SHADH, c->frame_geo.height, 0, CWBackPixel, c->colors.bordlight, &at);
CWIN(c->top, c->frame, 0, 0, c->frame_geo.width, SHADH, 0, CWBackPixel, c->colors.bordlight, &at);
CWIN(c->bottom, c->frame, 0, c->frame_geo.height - SHADH, c->frame_geo.width, SHADH, 0, CWBackPixel, c->colors.borddark, &at);
CWIN(c->right, c->frame, c->frame_geo.width - SHADH, 0, SHADH, c->frame_geo.height, 0, CWBackPixel, c->colors.borddark, &at);
}
/* Reparent window with the frame */
XReparentWindow(dpy, c->win, c->frame, BORDH, TBARH);
return;
}
/** Delete a frame
* \param c The client frame
*/
void
frame_delete(Client *c)
{
/* If there is, delete the titlebar */
if(TBARH - BORDH)
{
barwin_delete_subwin(c->titlebar);
barwin_delete(c->titlebar);
}
/* Delete the frame's sub win and the frame */
XDestroySubwindows(dpy, c->frame);
XDestroyWindow(dpy, c->frame);
return;
}
/** Move a frame
* \param c The client frame
* \param geo Coordinate info for move the frame
*/
void
frame_moveresize(Client *c, Geo geo)
{
CHECK(c);
c->frame_geo.x = (geo.x) ? geo.x - BORDH : c->frame_geo.x;
c->frame_geo.y = (geo.y) ? geo.y - TBARH : c->frame_geo.y;
c->frame_geo.width = (geo.width) ? FRAMEW(geo.width) : c->frame_geo.width;
c->frame_geo.height = (geo.height) ? FRAMEH(geo.height) : c->frame_geo.height;
/* Frame */
XMoveResizeWindow(dpy, c->frame,
c->frame_geo.x,
c->frame_geo.y,
c->frame_geo.width,
c->frame_geo.height);
/* Titlebar */
if(TBARH - BORDH)
barwin_resize(c->titlebar, c->frame_geo.width, TBARH);
/* Resize area */
XMoveWindow(dpy, c->resize[Right], c->frame_geo.width - RESHW, c->frame_geo.height - RESHW);
XMoveWindow(dpy, c->resize[Left], 0, c->frame_geo.height - RESHW);
/* Border */
if(conf.client.border_shadow)
{
XResizeWindow(dpy, c->left, SHADH, c->frame_geo.height - SHADH);
XResizeWindow(dpy, c->top, c->frame_geo.width, SHADH);
XMoveResizeWindow(dpy, c->bottom, 0, c->frame_geo.height - SHADH, c->frame_geo.width, SHADH);
XMoveResizeWindow(dpy, c->right, c->frame_geo.width - SHADH, 0, SHADH, c->frame_geo.height);
}
return;
}
/** Update frame colors for focus event
*\param c Client pointer
*/
void
frame_update_color(Client *c, bool focused)
{
CHECK(c);
/* Not focused client */
if(focused)
{
c->colors.frame = conf.client.bordernormal;
c->colors.fg = conf.titlebar.fg_normal;
c->colors.resizecorner = conf.client.resizecorner_normal;
if(TBARH - BORDH)
c->titlebar->stipple_color = conf.titlebar.stipple.colors.normal;
}
/* Focused */
else
{
c->colors.frame = conf.client.borderfocus;
c->colors.fg = conf.titlebar.fg_focus;
c->colors.resizecorner = conf.client.resizecorner_focus;
if(TBARH - BORDH)
c->titlebar->stipple_color = conf.titlebar.stipple.colors.focus;
}
if(conf.client.border_shadow)
{
c->colors.borddark = color_shade(c->colors.frame, conf.colors.client_dark_shade);
c->colors.bordlight = color_shade(c->colors.frame, conf.colors.client_light_shade);
}
return;
}
/** Update the client frame; Set the new color
* and the title --> refresh
* \param c Client pointer
*/
void
frame_update(Client *c)
{
int i;
CHECK(c);
if(TBARH - BORDH)
{
c->titlebar->bg = c->colors.frame;
c->titlebar->fg = c->colors.fg;
barwin_refresh_color(c->titlebar);
/* Buttons */
if(conf.titlebar.nbutton && BUTTONWH >= 1)
{
if(conf.titlebar.stipple.active)
draw_rectangle(c->titlebar->dr, 0, 0, c->button_last_x + TBARH - (TBARH >> 2),
TBARH + (BORDH << 2), c->colors.frame);
for(i = 0; i < conf.titlebar.nbutton; ++i)
{
XSetWindowBackground(dpy, c->button[i], c->colors.frame);
XClearWindow(dpy, c->button[i]);
if((!conf.titlebar.button[i].flags)
|| ((conf.titlebar.button[i].flags & FreeFlag)
&& ((c->flags & FreeFlag) || !(c->flags & (TileFlag | LMaxFlag))))
|| ((conf.titlebar.button[i].flags & MaxFlag)
&& ((c->flags & MaxFlag) || (c->flags & LMaxFlag)))
|| ((conf.titlebar.button[i].flags & TileFlag) && (c->flags & TileFlag)))
{
XSetWindowBorder(dpy, c->button[i], getcolor(c->colors.fg));
/* Button's lines */
if(conf.titlebar.button[i].nlines)
{
XSetForeground(dpy, gc, getcolor(c->colors.fg));
XDrawSegments(dpy, c->button[i], gc,
conf.titlebar.button[i].linecoord,
conf.titlebar.button[i].nlines);
}
}
else
XSetWindowBorder(dpy, c->button[i], c->colors.frame);
}
}
}
XSetWindowBackground(dpy, c->frame, c->colors.frame);
XSetWindowBackground(dpy, c->resize[Right], c->colors.resizecorner);
XSetWindowBackground(dpy, c->resize[Left], c->colors.resizecorner);
XClearWindow(dpy, c->frame);
XClearWindow(dpy, c->resize[Right]);
XClearWindow(dpy, c->resize[Left]);
if(conf.client.border_shadow)
{
XSetWindowBackground(dpy, c->left, c->colors.bordlight);
XSetWindowBackground(dpy, c->top, c->colors.bordlight);
XSetWindowBackground(dpy, c->right, c->colors.borddark);
XSetWindowBackground(dpy, c->bottom, c->colors.borddark);
XClearWindow(dpy, c->left);
XClearWindow(dpy, c->top);
XClearWindow(dpy, c->right);
XClearWindow(dpy, c->bottom);
}
if(TBARH - BORDH)
barwin_draw_text(c->titlebar,
(c->frame_geo.width >> 1) - (textw(c->title) >> 1),
((font.height - font.de) + ((TBARH - font.height) >> 1)),
c->title);
return;
}
-583
View File
@@ -1,583 +0,0 @@
/*
* infobar.c
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "wmfs.h"
#define SPLIT_IND_S (3 + conf.border.layout)
/** Init InfoBar elements
*/
static void
infobar_init_element(InfoBar *i)
{
int j = 0, k, n = 0;
InfobarElem *e, *prev = NULL;
Geo pg = { -PAD, 0, 0, 0 };
STAILQ_INIT(&i->elemhead);
for(; n < (int)strlen(i->elemorder); ++n)
{
e = zcalloc(sizeof(InfobarElem));
/* Previous element geo */
if(prev)
pg = prev->geo;
e->geo.x = pg.x + pg.width + PAD;
e->geo.y = 0;
e->geo.height = i->geo.height;
switch(i->elemorder[n])
{
/* Tags element */
case 't':
e->type = ElemTag;
e->geo.width = PAD; /* Will change */
if(!i->tags_board)
{
i->tags_board = barwin_create(i->bar->win,
e->geo.x,
e->geo.y,
e->geo.width,
e->geo.height,
conf.colors.bar, conf.colors.text,
False, False, False);
/* Create tags window */
for(k = 1; k < conf.ntag[i->screen] + 1; ++k)
{
i->tags[k] = barwin_create(i->tags_board->win,
j, 0,
textw(tags[i->screen][k].name) + PAD,
i->geo.height,
conf.colors.bar, conf.colors.text,
False, False, conf.border.tag);
j += textw(tags[i->screen][k].name) + PAD;
barwin_map_subwin(i->tags[k]);
}
}
barwin_resize(i->tags_board, (e->geo.width = j), i->geo.height);
barwin_map(i->tags_board);
barwin_map_subwin(i->tags_board);
break;
/* Layout button element */
case 'l':
e->type = ElemLayout;
e->geo.width = (conf.layout_button_width > 0
? (uint)conf.layout_button_width
: textw(tags[i->screen][seltag[i->screen]].layout.symbol) + PAD);
if(!i->layout_button)
i->layout_button = barwin_create(i->bar->win,
e->geo.x,
e->geo.y,
e->geo.width,
e->geo.height,
conf.colors.layout_bg, conf.colors.layout_fg,
False, False, conf.border.layout);
barwin_map(i->layout_button);
if(conf.border.layout)
barwin_map_subwin(i->layout_button);
break;
/* Selbar element */
case 's':
e->type = ElemSelbar;
i->selbar_geo = e->geo;
break;
}
STAILQ_INSERT_TAIL(&i->elemhead, e, next);
prev = e;
e = NULL;
}
return;
}
/** Init the InfoBar
*/
void
infobar_init(void)
{
InfoBar *i;
int s = screen_count(), sc = 0;
if(!infobar)
infobar = xcalloc(s, sizeof(InfoBar));
for(; sc < s; ++sc)
{
i = &infobar[sc];
i->geo.height = INFOBARH;
i->screen = sc;
i->elemorder = conf.bars.element_order;
switch(tags[sc][seltag[sc]].barpos)
{
case IB_Hide:
sgeo[sc].y = spgeo[sc].y + TBARH;
sgeo[sc].height += INFOBARH;
i->geo.y = (-(i->geo.height) << 2);
break;
case IB_Bottom:
sgeo[sc].y = TBARH;
i->geo.y = spgeo[sc].y + sgeo[sc].height + TBARH;
break;
default:
case IB_Top:
sgeo[sc].y = spgeo[sc].y + INFOBARH + TBARH;
i->geo.y = spgeo[sc].y;
break;
}
/* Create infobar barwindow */
i->bar = barwin_create(ROOT,
sgeo[sc].x - BORDH,
i->geo.y,
sgeo[sc].width,
i->geo.height,
conf.colors.bar, conf.colors.text,
False, False, conf.border.bar);
barwin_map(i->bar);
barwin_map_subwin(i->bar);
barwin_refresh_color(i->bar);
barwin_refresh(i->bar);
/* Init elements */
infobar_init_element(i);
/* Default statustext is set here */
i->statustext = xstrdup("wmfs"WMFS_VERSION);
infobar_draw(i);
}
return;
}
static void
infobar_arrange_element(InfoBar *i)
{
Geo pg = { -PAD, 0, 0, 0 };
InfobarElem *e, *pe = NULL;
STAILQ_FOREACH(e, &i->elemhead, next)
{
if(pe)
pg = pe->geo;
e->geo.x = pg.x + pg.width + PAD;
e->geo.y = 0;
if(e->type != ElemSelbar)
barwin_move((e->type == ElemTag ? i->tags_board : i->layout_button), e->geo.x, e->geo.y);
pe = e;
}
return;
}
/** Draw the layout button in the InfoBar
*\param i InfoBar pointer
*/
void
infobar_draw_layout(InfoBar *i)
{
InfobarElem *e;
int s = i->screen;
/* Check if there is element in string element list */
if(!strchr(i->elemorder, 'l'))
return;
STAILQ_FOREACH(e, &i->elemhead, next)
if(e->type == ElemLayout)
break;
e->geo.width = (conf.layout_button_width >= 1)
? conf.layout_button_width
: (int)(textw(tags[s][seltag[s]].layout.symbol) + PAD);
barwin_resize(i->layout_button, e->geo.width, e->geo.height);
barwin_refresh_color(i->layout_button);
/* Split mode indicator; little rectangle at bottom-right */
if(tags[s][seltag[s]].flags & SplitFlag)
draw_rectangle(i->layout_button->dr,
e->geo.width - SPLIT_IND_S,
e->geo.height - SPLIT_IND_S,
SPLIT_IND_S, SPLIT_IND_S,
getcolor(i->layout_button->fg));
if(tags[s][seltag[s]].layout.symbol)
barwin_draw_text(i->layout_button, (PAD >> 1), FHINFOBAR, tags[s][seltag[s]].layout.symbol);
return;
}
/** Draw Infobar barwin (selbar / statustext)
*\param i Infobar pointer
*/
void
_infobar_draw(InfoBar *i)
{
barwin_refresh_color(i->bar);
infobar_draw_selbar(i);
statustext_handle(i);
barwin_refresh(i->bar);
infobar_arrange_element(i);
return;
}
/** Draw the InfoBar
*\param i InfoBar pointer
*/
void
infobar_draw(InfoBar *i)
{
infobar_draw_taglist(i);
infobar_draw_layout(i);
_infobar_draw(i);
return;
}
/** Draw Selbar (selected client title bar in infobar
*\param sc Screen Number
*/
void
infobar_draw_selbar(InfoBar *i)
{
InfobarElem *e;
char *str = NULL;
int sc = i->screen;
bool f = False;
if(!conf.bars.selbar)
return;
if(!strchr(i->elemorder, 's'))
return;
if(!sel || (sel && sel->screen != sc))
return;
STAILQ_FOREACH(e, &i->elemhead, next)
if(e->type == ElemSelbar)
break;
str = sel->title;
/* Truncate string if too long */
if(conf.selbar.maxlength >= 0 && sel && sel->title)
{
str = NULL;
str = xcalloc(conf.selbar.maxlength + 4, sizeof(char));
strncpy(str, sel->title, conf.selbar.maxlength);
if(strlen(sel->title) > (size_t)conf.selbar.maxlength)
strcat(str, "...");
f = True;
}
XSetForeground(dpy, gc, conf.selbar.bg);
XFillRectangle(dpy, i->bar->dr, gc,
e->geo.x,
e->geo.y,
(e->geo.width = textw(str) + PAD),
e->geo.height);
draw_text(i->bar->dr, e->geo.x, FHINFOBAR, conf.selbar.fg, str);
if(f)
free(str);
i->selbar_geo = e->geo;
return;
}
/** Draw the taglist in the InfoBar
*\param i InfoBar pointer
*/
void
infobar_draw_taglist(InfoBar *i)
{
InfobarElem *e;
Client *c;
int j = 1, x = 0, sc = i->screen;
uint occupied = 0;
if(!strchr(i->elemorder, 't'))
return;
STAILQ_FOREACH(e, &i->elemhead, next)
if(e->type == ElemTag)
break;
SLIST_FOREACH(c, &clients, next)
if(c->screen == sc)
occupied |= TagFlag(c->tag);
for(; j < conf.ntag[sc] + 1; ++j)
{
/* Autohide tag feature */
if(conf.tagautohide)
{
if(!(occupied & TagFlag(j)) && j != seltag[sc])
{
barwin_unmap(i->tags[j]);
continue;
}
barwin_map(i->tags[j]);
barwin_move(i->tags[j], x, 0);
barwin_resize(i->tags_board, (e->geo.width = (x += i->tags[j]->geo.width)), e->geo.height);
}
if(tags[sc][j].flags & TagUrgentFlag)
{
i->tags[j]->bg = conf.colors.tagurbg;
i->tags[j]->fg = conf.colors.tagurfg;
}
else if(j == seltag[sc] || tags[sc][seltag[sc]].tagad & TagFlag(j))
{
i->tags[j]->bg = conf.colors.tagselbg;
i->tags[j]->fg = conf.colors.tagselfg;
}
else
{
i->tags[j]->bg = ((occupied & TagFlag(j)) ? conf.colors.tag_occupied_bg : conf.colors.bar);
i->tags[j]->fg = ((occupied & TagFlag(j)) ? conf.colors.tag_occupied_fg : conf.colors.text);
}
barwin_color_set(i->tags[j], i->tags[j]->bg, i->tags[j]->fg);
barwin_refresh_color(i->tags[j]);
if(tags[sc][j].name)
barwin_draw_text(i->tags[j], (PAD >> 1), FHINFOBAR, tags[sc][j].name);
}
return;
}
/** Update taglist geo
*\param i InfoBar pointer
*/
void
infobar_update_taglist(InfoBar *i)
{
int t, j, sc = i->screen;
for(t = 1, j = 0; t < conf.ntag[sc] + 1; ++t)
{
/* If the tag t does not exist yet (graphically) or need full update */
if(!i->tags[t] || i->need_update)
{
i->tags[t] = barwin_create(i->tags_board->win, j, 0,
textw(tags[sc][t].name) + PAD,
i->geo.height,
conf.colors.bar, conf.colors.text, False, False, conf.border.tag);
barwin_map(i->tags[t]);
barwin_map_subwin(i->tags[t]);
barwin_resize(i->tags_board, (j += textw(tags[sc][t].name) + PAD), i->geo.height);
continue;
}
barwin_move(i->tags[t], j, 0);
barwin_resize(i->tags[t], textw(tags[sc][t].name) + PAD, i->geo.height);
barwin_resize(i->tags_board, (j += textw(tags[sc][t].name) + PAD), i->geo.height);
}
i->need_update = False;
return;
}
/** Destroy the InfoBar
*/
void
infobar_destroy(void)
{
InfobarElem *e;
int sc, i;
for(sc = 0; sc < screen_count(); ++sc)
{
barwin_delete(infobar[sc].layout_button);
barwin_delete_subwin(infobar[sc].layout_button);
for(i = 1; i < conf.ntag[sc] + 1; ++i)
{
barwin_delete_subwin(infobar[sc].tags[i]);
barwin_delete(infobar[sc].tags[i]);
}
barwin_delete_subwin(infobar[sc].tags_board);
barwin_delete(infobar[sc].tags_board);
barwin_delete_subwin(infobar[sc].bar);
barwin_delete(infobar[sc].bar);
/* Free elements */
while(!STAILQ_EMPTY(&infobar[sc].elemhead))
{
e = STAILQ_FIRST(&infobar[sc].elemhead);
STAILQ_REMOVE_HEAD(&infobar[sc].elemhead, next);
free(e);
}
}
return;
}
/* Set the infobar position
* \param pos Position of the bar
*/
void
infobar_set_position(int pos)
{
screen_get_sel();
switch(pos)
{
case IB_Hide:
sgeo[selscreen].y = spgeo[selscreen].y + TBARH;
sgeo[selscreen].height = spgeo[selscreen].height - TBARH;
infobar[selscreen].geo.y = (-(infobar[selscreen].geo.height) << 1);
break;
case IB_Bottom:
sgeo[selscreen].y = spgeo[selscreen].y + TBARH;
sgeo[selscreen].height = spgeo[selscreen].height - INFOBARH - TBARH;
infobar[selscreen].geo.y = spgeo[selscreen].y + sgeo[selscreen].height + TBARH;
break;
default:
case IB_Top:
sgeo[selscreen].y = spgeo[selscreen].y + INFOBARH + TBARH;
sgeo[selscreen].height = spgeo[selscreen].height - INFOBARH - TBARH;
infobar[selscreen].geo.y = spgeo[selscreen].y;
break;
}
tags[selscreen][seltag[selscreen]].barpos = pos;
barwin_move(infobar[selscreen].bar, sgeo[selscreen].x - BORDH, infobar[selscreen].geo.y);
arrange(selscreen, True);
return;
}
/** Toggle the infobar position
* \param cmd uicb_t type unused
*/
void
uicb_infobar_togglepos(uicb_t cmd)
{
(void)cmd;
screen_get_sel();
infobar_set_position((tags[selscreen][seltag[selscreen]].barpos
= (tags[selscreen][seltag[selscreen]].barpos < 2)
? tags[selscreen][seltag[selscreen]].barpos + 1
: 0));
return;
}
/** Toggle hide/display infobar
* \param cmd uicb_t type unused
*/
void
uicb_infobar_toggledisplay(uicb_t cmd)
{
(void)cmd;
screen_get_sel();
int new_pos;
new_pos = (tags[selscreen][seltag[selscreen]].barpos
? 0 : (tags[selscreen][seltag[selscreen]].prev_barpos
? tags[selscreen][seltag[selscreen]].prev_barpos : 2));
tags[selscreen][seltag[selscreen]].prev_barpos = tags[selscreen][seltag[selscreen]].barpos;
tags[selscreen][seltag[selscreen]].barpos = new_pos;
infobar_set_position(new_pos);
return;
}
/** Toggle the tag_autohide mode
* \param cmd uicb_t type unused
*/
void
uicb_toggle_tagautohide(uicb_t cmd)
{
int i, x;
(void)cmd;
screen_get_sel();
conf.tagautohide = !conf.tagautohide;
if(!conf.tagautohide)
{
for(i = 1, x = 0; i < conf.ntag[selscreen] + 1; ++i)
{
barwin_map(infobar[selscreen].tags[i]);
barwin_move(infobar[selscreen].tags[i], x, 0);
x += infobar[selscreen].tags[i]->geo.width;
}
barwin_resize(infobar[selscreen].tags_board, x, infobar[selscreen].geo.height);
}
infobar_draw(&infobar[selscreen]);
return;
}
-227
View File
@@ -1,227 +0,0 @@
/*
* wmfs.c
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "wmfs.h"
const func_name_list_t layout_list[] =
{
{"tile", tile },
{"tile_right", tile },
{"tile_left", tile_left },
{"tile_top", tile_top },
{"tile_bottom", tile_bottom },
{"tile_grid", grid_horizontal },
{"tile_grid_horizontal", grid_horizontal },
{"tile_grid_vertical", grid_vertical },
{"grid", grid_horizontal },
{"mirror_vertical", mirror_vertical },
{"tile_mirror_vertical", mirror_vertical },
{"mirror_horizontal", mirror_horizontal },
{"tile_mirror_horizontal", mirror_horizontal },
{"max", maxlayout },
{"maxlayout", maxlayout },
{"freelayout", freelayout },
{"free", freelayout },
{ NULL, NULL }
};
/** Init the font
*/
static void
init_font(void)
{
#ifdef HAVE_XFT
if(conf.use_xft)
{
if(!(font.font = XftFontOpenName(dpy, SCREEN, conf.font)))
{
warnx("WMFS Error: Cannot initialize Xft font");
font.font = XftFontOpenName(dpy, SCREEN, "sans-10");
}
font.de = font.font->descent;
font.as = font.font->ascent;
font.height = font.font->height;
}
else
#endif /* HAVE_XFT */
{
char **misschar, **names, *defstring;
int d;
XFontStruct **xfs = NULL;
/* locale support */
setlocale(LC_CTYPE, "");
if(!conf.font)
conf.font = xstrdup("fixed");
/* Using Font Set */
if(!(font.fontset = XCreateFontSet(dpy, conf.font, &misschar, &d, &defstring)))
{
warnx("Can't load font '%s'", conf.font);
font.fontset = XCreateFontSet(dpy, "fixed", &misschar, &d, &defstring);
}
XExtentsOfFontSet(font.fontset);
XFontsOfFontSet(font.fontset, &xfs, &names);
font.as = xfs[0]->max_bounds.ascent;
font.de = xfs[0]->max_bounds.descent;
font.width = xfs[0]->max_bounds.width;
font.height = font.as + font.de;
if(misschar)
XFreeStringList(misschar);
}
/* Set font in _WMFS_FONT for eventual status tools */
XChangeProperty(dpy, ROOT, net_atom[wmfs_font], net_atom[utf8_string], 8,
PropModeReplace, (uchar*)conf.font, strlen(conf.font));
return;
}
/** Init the graphic context
*/
static void
init_gc(void)
{
XGCValues gcv;
/* Bits sequences */
const char pix_bits[] =
{
0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55,
0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55,
0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55,
0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55
};
gc = DefaultGC(dpy, SCREEN);
/* Stipple GC */
gcv.function = GXcopy;
gcv.fill_style = FillStippled;
gcv.stipple = XCreateBitmapFromData(dpy, ROOT, pix_bits, 10, 4);
gc_stipple = XCreateGC(dpy, ROOT, GCFunction | GCFillStyle | GCStipple, &gcv);
return;
}
/** Init WMFS cursor
*/
static void
init_cursor(void)
{
cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr);
cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
cursor[CurRightResize] = XCreateFontCursor(dpy, XC_lr_angle);
cursor[CurLeftResize] = XCreateFontCursor(dpy, XC_ll_angle);
cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur);
return;
}
/** Init key modifier
*/
static void
init_key(void)
{
int i, j;
XModifierKeymap *modmap = XGetModifierMapping(dpy);
for(i = 0; i < 8; i++)
for(j = 0; j < modmap->max_keypermod; ++j)
if(modmap->modifiermap[i * modmap->max_keypermod + j]
== XKeysymToKeycode(dpy, XK_Num_Lock))
numlockmask = (1 << i);
XFreeModifiermap(modmap);
return;
}
/** Init root Window
*/
static void
init_root(void)
{
XSetWindowAttributes at;
at.event_mask = KeyMask | ButtonMask | MouseMask | PropertyChangeMask
| SubstructureRedirectMask | SubstructureNotifyMask | StructureNotifyMask;
at.cursor = cursor[CurNormal];
XChangeWindowAttributes(dpy, ROOT, CWEventMask | CWCursor, &at);
if(conf.root.background_command)
spawn("%s", conf.root.background_command);
ewmh_init_hints();
ewmh_get_number_of_desktop();
ewmh_get_desktop_names();
return;
}
/** Init WMFS
*/
void
init(void)
{
/* Init lists heads */
SLIST_INIT(&bwhead);
SLIST_INIT(&smhead);
SLIST_INIT(&clients);
SLIST_INIT(&trayicons);
/* First init */
ewmh_init_hints();
init_conf();
init_gc();
init_font();
init_cursor();
init_key();
init_root();
screen_init_geo();
event_make_array();
infobar_init();
systray_acquire();
ewmh_update_current_tag_prop();
grabkeys();
return;
}
-384
View File
@@ -1,384 +0,0 @@
/*
* launcher.c
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "wmfs.h"
/*
* Just search command in PATH.
* Return the characters to complete the command.
*/
static char *
complete_on_command(char *start, size_t hits)
{
char *path;
char *dirname;
char *ret = NULL;
DIR *dir;
struct dirent *content;
char **namelist = NULL;
int n = 0, i;
if (!getenv("PATH") || !start || hits <= 0)
return NULL;
path = xstrdup(getenv("PATH"));
dirname = strtok(path, ":");
/* recursively open PATH */
while (dirname != NULL)
{
if ((dir = opendir(dirname)))
{
while ((content = readdir(dir)))
{
if(strncmp(content->d_name, ".", 1))
{
if (!strncmp(content->d_name, start, strlen(start)))
{
namelist = xrealloc(namelist, ++n, sizeof(*namelist));
namelist[n-1] = xstrdup(content->d_name);
}
}
}
closedir(dir);
}
dirname = strtok(NULL, ":");
}
free(path);
if(n > 0)
{
qsort(namelist, n, sizeof(char *), qsort_string_compare);
ret = xstrdup(namelist[((hits > 0) ? hits - 1 : 0) % n] + strlen(start));
for(i = 0; i < n; i++)
free(namelist[i]);
free(namelist);
}
return ret;
}
/*
* Complete a filename or directory name.
* works like complete_on_command.
*/
static char *
complete_on_files(char *start, size_t hits)
{
char *ret = NULL;
char *p = NULL;
char *dirname = NULL;
char *path = NULL;
char *filepath = NULL;
DIR *dir = NULL;
struct dirent *content = NULL;
struct stat st;
size_t count = 0;
if (!start || hits <= 0 || !(p = strrchr(start, ' ')))
return NULL;
/*
* Search the directory to open and set
* the beginning of file to complete on pointer 'p'.
*/
if (*(++p) == '\0' || !strrchr(p, '/'))
path = xstrdup(".");
else
{
/* remplace ~ by $HOME in dirname */
if (!strncmp(p, "~/", 2) && getenv("HOME"))
xasprintf(&dirname, "%s%s", getenv("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, ".."))
continue;
if (!strncmp(content->d_name, p, strlen(p)) && ++count == hits)
{
/* If it's a directory append '/' to the completion */
xasprintf(&filepath, "%s/%s", path, content->d_name);
if (filepath && stat(filepath, &st) != -1)
{
if (S_ISDIR(st.st_mode))
xasprintf(&ret, "%s/", content->d_name + strlen(p));
else
ret = xstrdup(content->d_name + strlen(p));
}
else
warn("%s", filepath);
free(filepath);
break;
}
}
closedir(dir);
}
free(dirname);
free(path);
return ret;
}
static void
launcher_execute(Launcher *launcher)
{
BarWindow *bw;
bool found;
bool lastwastab = False;
bool my_guitar_gently_wheeps = True;
char tmp[32] = { 0 };
char buf[512] = { 0 };
char tmpbuf[512] = { 0 };
char *complete;
int i, pos = 0, histpos = 0, w, x = 0;
int tabhits = 0;
KeySym ks;
XEvent ev;
InfobarElem *e;
screen_get_sel();
STAILQ_FOREACH(e, &infobar[selscreen].elemhead, next)
if(x < (e->geo.x + e->geo.width))
x = e->geo.x + e->geo.width + PAD;
XGrabKeyboard(dpy, ROOT, True, GrabModeAsync, GrabModeAsync, CurrentTime);
w = (launcher->width ? launcher->width : infobar[selscreen].bar->geo.width - x - 1);
bw = barwin_create(infobar[selscreen].bar->win, x, 1, w,
/* infobar[selscreen].bar->geo.width - x - 1, */
infobar[selscreen].bar->geo.height - 2,
infobar[selscreen].bar->bg,
infobar[selscreen].bar->fg,
False, False, conf.border.bar);
barwin_map(bw);
barwin_refresh_color(bw);
/* First draw of the cursor */
XSetForeground(dpy, gc, getcolor(infobar[selscreen].bar->fg));
XDrawLine(dpy, bw->dr, gc,
1 + textw(launcher->prompt) + textw(" ") + textw(buf), 2,
1 + textw(launcher->prompt) + textw(" ") + textw(buf), INFOBARH - 4);
barwin_refresh(bw);
barwin_draw_text(bw, 1, FHINFOBAR - 1, launcher->prompt);
while(my_guitar_gently_wheeps)
{
if(ev.type == KeyPress)
{
XLookupString(&ev.xkey, tmp, sizeof(tmp), &ks, 0);
/* Check Ctrl-c / Ctrl-d */
if(ev.xkey.state & ControlMask)
{
if(ks == XK_c || ks == XK_d)
ks = XK_Escape;
else if(ks == XK_p)
ks = XK_Up;
else if(ks == XK_n)
ks = XK_Down;
}
/* Check if there is a keypad */
if(IsKeypadKey(ks) && ks == XK_KP_Enter)
ks = XK_Return;
switch(ks)
{
case XK_Up:
if(launcher->nhisto)
{
if(histpos >= (int)launcher->nhisto)
histpos = 0;
strncpy(buf, launcher->histo[launcher->nhisto - ++histpos], sizeof(buf));
pos = strlen(buf);
}
break;
case XK_Down:
if(launcher->nhisto && histpos > 0 && histpos < (int)launcher->nhisto)
{
strncpy(buf, launcher->histo[launcher->nhisto - --histpos], sizeof(buf));
pos = strlen(buf);
}
break;
case XK_Return:
spawn("%s %s", launcher->command, buf);
/* Histo */
if(launcher->nhisto + 1 > HISTOLEN)
{
for(i = launcher->nhisto - 1; i > 1; --i)
strncpy(launcher->histo[i], launcher->histo[i - 1], sizeof(launcher->histo[i]));
launcher->nhisto = 0;
}
/* Store in histo array */
strncpy(launcher->histo[launcher->nhisto++], buf, sizeof(buf));
my_guitar_gently_wheeps = 0;
break;
case XK_Escape:
my_guitar_gently_wheeps = 0;
break;
case XK_Tab:
/*
* completion
* if there is not space in buffer we
* complete the command using complete_on_command.
* Else we try to complete on filename using
* complete_on_files.
*/
buf[pos] = '\0';
if (lastwastab)
tabhits++;
else
{
tabhits = 1;
strncpy(tmpbuf, buf, sizeof(tmpbuf));
}
if (pos)
{
if (strchr(tmpbuf, ' '))
complete = complete_on_files(tmpbuf, tabhits);
else
complete = complete_on_command(tmpbuf, tabhits);
if (complete)
{
strncpy(buf, tmpbuf, sizeof(buf));
strncat(buf, complete, sizeof(buf));
found = True;
free(complete);
}
}
lastwastab = True;
/* start a new round of tabbing */
if (found == False)
tabhits = 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;
}
barwin_refresh_color(bw);
/* Update cursor position */
XSetForeground(dpy, gc, getcolor(infobar[selscreen].bar->fg));
XDrawLine(dpy, bw->dr, gc,
1 + textw(launcher->prompt) + textw(" ") + textw(buf), 2,
1 + textw(launcher->prompt) + textw(" ") + textw(buf), INFOBARH - 4);
barwin_draw_text(bw, 1, FHINFOBAR - 1, launcher->prompt);
barwin_draw_text(bw, 1 + textw(launcher->prompt) + textw(" "), FHINFOBAR - 1, buf);
barwin_refresh(bw);
}
else if(ev.type < nevent && ev.type > 0)
HANDLE_EVENT(&ev);
XNextEvent(dpy, &ev);
}
barwin_unmap(bw);
barwin_delete(bw);
infobar_draw(&infobar[selscreen]);
XUngrabKeyboard(dpy, CurrentTime);
return;
}
void
uicb_launcher(uicb_t cmd)
{
int i;
for(i = 0; i < conf.nlauncher; ++i)
if(!strcmp(cmd, conf.launcher[i].name))
launcher_execute(&conf.launcher[i]);
return;
}
-942
View File
@@ -1,942 +0,0 @@
/*
* layout.c
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "wmfs.h"
/** Arrange All
*/
void
arrange(int screen, bool update_layout)
{
Client *c;
if(screen < 0 || screen > screen_count() - 1)
screen = screen_get_sel();
SLIST_FOREACH(c, &clients, next)
if(c->screen == screen)
{
if(!ishide(c, screen))
client_unhide(c);
else
client_hide(c);
}
if(tags[screen][seltag[screen]].layout.func)
{
if(update_layout)
layout_func(screen, seltag[screen]);
infobar_draw(&infobar[screen]);
}
return;
}
/** Apply layout function
*/
void
layout_func(int screen, int tag)
{
if((tags[screen][tag].flags & SplitFlag)
&& !(tags[screen][tag].flags & FirstArrangeFlag))
split_apply_current(screen, tag);
else
{
tags[screen][tag].layout.func(screen);
tags[screen][tag].flags &= ~FirstArrangeFlag;
}
return;
}
/** The free layout function
*/
void
freelayout(int screen)
{
Client *c;
(void)screen;
SLIST_FOREACH(c, &clients, next)
if(!ishide(c, selscreen)
&& c->screen == screen
&& !(c->flags & MaxFlag))
{
client_moveresize(c, c->free_geo, True);
c->flags &= ~(TileFlag | LMaxFlag);
}
ewmh_update_current_tag_prop();
return;
}
/** Layout switching function
* \param b bool True : next False : previous
*/
void
layoutswitch(bool b)
{
int i;
Client *c = SLIST_FIRST(&clients);
screen_get_sel();
if(tags[selscreen][seltag[selscreen]].layout.func == freelayout)
for(; c && (c->tag != seltag[selscreen] && c->screen != selscreen); c = SLIST_NEXT(c, next))
{
c->ogeo = c->geo;
c->free_geo = c->geo;
}
for(i = 0; i < conf.nlayout; ++i)
{
if(tags[selscreen][seltag[selscreen]].layout.func == conf.layout[i].func
&& tags[selscreen][seltag[selscreen]].layout.symbol == conf.layout[i].symbol)
{
if(b)
tags[selscreen][seltag[selscreen]].layout = conf.layout[(i + 1) % conf.nlayout];
else
tags[selscreen][seltag[selscreen]].layout = conf.layout[(i + conf.nlayout - 1) % conf.nlayout];
break;
}
}
ewmh_update_current_tag_prop();
tags[selscreen][seltag[selscreen]].flags |= CleanFactFlag;
tags[selscreen][seltag[selscreen]].flags &= ~SplitFlag;
layout_func(selscreen, seltag[selscreen]);
infobar_draw(&infobar[selscreen]);
return;
}
/** Set the next layout
* \param cmd uicb_t type unused
*/
void
uicb_layout_next(uicb_t cmd)
{
(void)cmd;
layoutswitch(True);
return;
}
/** Set the previous layout
* \param cmd uicb_t type unused
*/
void
uicb_layout_prev(uicb_t cmd)
{
(void)cmd;
layoutswitch(False);
return;
}
/** Sort all the client that can be
* tiled
* \param c Client pointer
* \return a client pointer
*/
Client*
tiled_client(int screen, Client *c)
{
for(; c && (c->flags & (MaxFlag | FreeFlag | FSSFlag | AboveFlag)
|| c->screen != screen
|| ishide(c, screen)); c = SLIST_NEXT(c, next));
if(c)
c->flags |= FLayFlag;
return c;
}
/** Max layout function
*/
void
maxlayout(int screen)
{
Client *c = tiled_client(screen, SLIST_FIRST(&clients));
int i = 0;
for(; c; c = tiled_client(screen, SLIST_NEXT(c, next)), ++i)
{
c->flags &= ~TileFlag;
c->flags |= LMaxFlag;
client_maximize(c);
}
ewmh_update_current_tag_prop();
return;
}
/** Set the mwfact
* \param cmd Mwfact (string)
*/
void
uicb_set_mwfact(uicb_t cmd)
{
double c;
screen_get_sel();
CHECK((sscanf(cmd, "%lf", &c)));
if(tags[selscreen][seltag[selscreen]].mwfact + c > 0.95
|| tags[selscreen][seltag[selscreen]].mwfact + c < 0.05)
return;
tags[selscreen][seltag[selscreen]].mwfact += c;
layout_func(selscreen, seltag[selscreen]);
ewmh_update_current_tag_prop();
return;
}
/** Set the nmaster
* \param cmd Nmaster (string)
*/
void
uicb_set_nmaster(uicb_t cmd)
{
int nc = 0, n = atoi(cmd);
Client *c = tiled_client(selscreen, SLIST_FIRST(&clients));
screen_get_sel();
for(; c; c = tiled_client(selscreen, SLIST_NEXT(c, next)), ++nc);
if(!nc || tags[selscreen][seltag[selscreen]].nmaster + n == 0
|| tags[selscreen][seltag[selscreen]].nmaster + n > nc)
return;
tags[selscreen][seltag[selscreen]].nmaster += n;
tags[selscreen][seltag[selscreen]].flags |= CleanFactFlag;
layout_func(selscreen, seltag[selscreen]);
ewmh_update_current_tag_prop();
return;
}
/** Grid layout function
*/
static void
grid(int screen, bool horizontal)
{
Client *c = tiled_client(screen, SLIST_FIRST(&clients));
Geo sg = sgeo[screen];
Geo cgeo = {sg.x, sg.y, 0, 0};
unsigned int i = 0, n = 0, temp, cols, rows, cpcols = 0;
for(; c; c = tiled_client(screen, SLIST_NEXT(c, next)), ++n);
CHECK((tags[screen][seltag[screen]].nclients = n));
for(rows = 0; rows <= (n >> 1); ++rows)
if(rows * rows >= n)
break;
cols = (rows && ((rows - 1) * rows) >= n)
? rows - 1
: rows;
if(!horizontal)
{
temp = cols;
cols = rows;
rows = temp;
}
for(c = tiled_client(screen, SLIST_FIRST(&clients)); c; c = tiled_client(screen, SLIST_NEXT(c, next)), ++i)
{
/* Set client property */
c->flags &= ~(MaxFlag | LMaxFlag);
c->flags |= TileFlag;
++cpcols;
cfactor_clean(c);
cgeo.width = (sg.width / cols) - (BORDH << 1);
cgeo.height = (sg.height / rows) - BORDH;
/* Last row's and last client remainder */
if(cpcols == rows || i + 1 == n)
cgeo.height = sg.y + sg.height - cgeo.y - BORDH;
/* Last column's client remainder */
if(i >= rows * (cols - 1))
cgeo.width = sg.width - (cgeo.x - (sg.x - (BORDH << 1)));
/* Resize */
client_moveresize(c, (c->pgeo = cgeo), (tags[screen][seltag[screen]].flags & ResizeHintFlag));
/* Set all the other size with current client info */
cgeo.y = c->pgeo.y + c->pgeo.height + BORDH + TBARH;
if(cpcols + 1 > rows)
{
cpcols = 0;
cgeo.x = c->pgeo.x + c->pgeo.width + (BORDH << 1);
cgeo.y = sg.y;
}
}
tags[screen][seltag[screen]].flags &= ~CleanFactFlag;
ewmh_update_current_tag_prop();
return;
}
/** Multi tile function
* \param type Postion type { Top, Bottom, Left, Right }
*/
static void
multi_tile(int screen, Position type)
{
Client *c = tiled_client(screen, SLIST_FIRST(&clients));
Geo sg = sgeo[screen];
Geo mastergeo = {sg.x, sg.y, 0, 0};
Geo cgeo = {sg.x, sg.y, 0, 0};
int i = 0, n = 0, tilesize = 0, mwfact, nmaster = tags[screen][seltag[screen]].nmaster;
for(; c; c = tiled_client(screen, SLIST_NEXT(c, next)), ++n);
CHECK((tags[screen][seltag[screen]].nclients = n));
/* FIX NMASTER */
nmaster = (n < nmaster) ? n : nmaster;
/* SET MWFACT */
mwfact = (type == Top || type == Bottom)
? tags[screen][seltag[screen]].mwfact * sg.height
: tags[screen][seltag[screen]].mwfact * sg.width;
/* MASTER SIZE */
if(LDIR(type))
{
if(type == Left)
mastergeo.x = (n <= nmaster) ? sg.x : (sg.x + sg.width) - mwfact - (BORDH << 1);
mastergeo.width = (n <= nmaster) ? (sg.width - (BORDH << 1)) : mwfact;
mastergeo.height = (sg.height / nmaster) - BORDH;
}
else
{
if(type == Top)
mastergeo.y = (n <= nmaster) ? sg.y : sg.y + (sg.height - mwfact) - BORDH;
mastergeo.width = (sg.width / nmaster) - (BORDH << 2);
mastergeo.height = (n <= nmaster) ? (sg.height - BORDH) : mwfact;
}
/* TILED SIZE */
if(n > nmaster)
{
if(LDIR(type))
tilesize = sg.height / (n - nmaster) - ((BORDH << 1) + TBARH);
else
tilesize = sg.width / (n - nmaster) - (BORDH << 2);
}
for(c = tiled_client(screen, SLIST_FIRST(&clients)); c; c = tiled_client(screen, SLIST_NEXT(c, next)), ++i)
{
/* Set client property */
c->flags &= ~(MaxFlag | LMaxFlag);
c->flags |= TileFlag;
cfactor_clean(c);
/* MASTER */
if(i < nmaster)
{
cgeo.width = mastergeo.width;
cgeo.height = mastergeo.height;
if(LDIR(type))
{
cgeo.x = mastergeo.x;
cgeo.height -= (TBARH + BORDH);
}
else
cgeo.y = mastergeo.y;
}
/* TILED */
else
{
if(i == nmaster)
{
switch(type)
{
case Top:
case Left:
cgeo.y = sg.y;
cgeo.x = sg.x;
break;
case Bottom:
cgeo.y += mastergeo.height + TBARH + BORDH;
cgeo.x = sg.x;
break;
default:
case Right:
cgeo.x += mastergeo.width + (BORDH << 1);
cgeo.y = sg.y;
break;
}
}
if(LDIR(type))
{
cgeo.width = sg.width - mastergeo.width - (BORDH << 2);
cgeo.height = tilesize;
}
else
{
cgeo.width = tilesize;
cgeo.height = sg.height - mastergeo.height - TBARH - (BORDH << 1);
}
}
/* REMAINDER */
if(i + 1 == n || i + 1 == (n < nmaster ? n : nmaster))
{
if(LDIR(type))
cgeo.height = (sg.y + sg.height) - cgeo.y - BORDH;
else
cgeo.width = sg.width - (cgeo.x - (sg.x - (BORDH << 1)));
}
/* Magic instant */
client_moveresize(c, (c->pgeo = cgeo), (tags[screen][seltag[screen]].flags & ResizeHintFlag));
/* Set the position of the next client */
if(LDIR(type))
cgeo.y = c->pgeo.y + c->pgeo.height + BORDH + TBARH;
else
cgeo.x = c->pgeo.x + c->pgeo.width + (BORDH << 1);
}
tags[screen][seltag[screen]].flags &= ~CleanFactFlag;
ewmh_update_current_tag_prop();
return;
}
/** Mirror layout function
* \param screen Screen to execute this function
* \param horizont To specify the mirror mode (vertical/horizontal)
*/
static void
mirror(int screen, bool horizontal)
{
Client *c = tiled_client(screen, SLIST_FIRST(&clients));
Geo sg = sgeo[screen];
Geo mastergeo = {sg.x, sg.y, sg.width, sg.height};
Geo cgeo = {sg.x, sg.y , sg.width, sg.height};
Geo nextg[2];
int i = 0, n = 0, tilesize = 0, mwfact;
int nmaster = tags[screen][seltag[screen]].nmaster;
int pa, imp;
bool isp = False;
memset(nextg, 0, sizeof(nextg));
for(; c; c = tiled_client(screen, SLIST_NEXT(c, next)), ++n);
CHECK((tags[screen][seltag[screen]].nclients = n));
/* Fix nmaster */
nmaster = (n < nmaster) ? n : nmaster;
imp = ((n - (nmaster - 1)) >> 1);
pa = ((n - (nmaster - 1)) >> 1) - (((n - (nmaster - 1)) & 1) ? 0 : 1);
/* Set mwfact */
if(tags[screen][seltag[screen]].mwfact < 0.55)
tags[screen][seltag[screen]].mwfact = 0.55;
mwfact = tags[screen][seltag[screen]].mwfact * ((horizontal) ? sg.height : sg.width);
/* Master size */
if(horizontal)
{
mastergeo.width = (sg.width / nmaster) - (BORDH << 1);
mastergeo.height -= BORDH;
}
else
{
mastergeo.width -= (BORDH << 1);
mastergeo.height = (sg.height / nmaster) - (TBARH + (BORDH << 1));
}
if(n == nmaster + 1)
{
if(horizontal)
{
mastergeo.height = mwfact - ((BORDH << 1) + TBARH);
tilesize = (sg.height - mastergeo.height) - ((BORDH << 1) + TBARH);
}
else
{
mastergeo.width = mwfact - (BORDH * 3);
tilesize = (sg.width - mastergeo.width) - (BORDH << 2);
}
}
if(n > nmaster + 1)
{
if(horizontal)
{
mastergeo.y = (sg.y + (sg.height - mwfact)) + TBARH + BORDH;
mastergeo.height = ((mwfact << 1) - sg.height) - ((BORDH * 3) + (TBARH << 1));
tilesize = (mwfact - mastergeo.height) - ((BORDH * 3) + (TBARH << 1));
}
else
{
mastergeo.x = (sg.x + (sg.width - mwfact)) + BORDH;
mastergeo.width = ((mwfact << 1) - sg.width) - (BORDH << 2);
tilesize = (mwfact - mastergeo.width) - (BORDH * 5);
}
}
for(c = tiled_client(screen, SLIST_FIRST(&clients)); c; c = tiled_client(screen, SLIST_NEXT(c, next)), ++i)
{
/* Set client property */
c->flags &= ~(MaxFlag | LMaxFlag);
c->flags |= TileFlag;
cfactor_clean(c);
if(i < nmaster)
{
cgeo = mastergeo;
/* Master remainder */
if(i + 1 == nmaster)
{
if(horizontal)
cgeo.width = (sg.x + sg.width) - (cgeo.x + (BORDH << 1));
else
cgeo.height = (sg.y + sg.height) - (cgeo.y + BORDH);
}
}
else
{
if(horizontal)
cgeo.height = tilesize;
else
cgeo.width = tilesize;
if((i + nmaster) & 1)
{
isp = 1;
if(horizontal)
{
cgeo.y = sg.y;
cgeo.width = (sg.width / pa) - (BORDH << 1);
}
else
{
cgeo.x = sg.x;
cgeo.height = (sg.height / pa) - (TBARH + (BORDH << 1));
}
}
else
{
isp = 0;
if(horizontal)
{
cgeo.y = (sg.y + mwfact) - BORDH;
cgeo.width = (sg.width / imp) - (BORDH << 1);
}
else
{
cgeo.x = (sg.x + mwfact) - BORDH;
cgeo.height = (sg.height / imp) - (TBARH + (BORDH << 1));
}
}
/* Remainder */
if(i + 1 == n || i + 1 == n - 1)
{
if(horizontal)
cgeo.width = (sg.x + sg.width) - (cgeo.x + (BORDH << 1));
else
cgeo.height = (sg.y + sg.height) - (cgeo.y + BORDH);
}
}
client_moveresize(c, (c->pgeo = cgeo), (tags[screen][seltag[screen]].flags & ResizeHintFlag));
if(i >= nmaster)
nextg[!isp] = c->pgeo;
/* Next y/x position */
if(i >= nmaster - 1)
{
if(horizontal)
{
if(i == nmaster || i == nmaster - 1)
cgeo.x = sg.x;
else
cgeo.x = nextg[isp].x + nextg[isp].width + (BORDH << 1);
}
else
{
if(i == nmaster || i == nmaster - 1)
cgeo.y = sg.y;
else
cgeo.y = nextg[isp].y + nextg[isp].height + BORDH + TBARH;
}
}
else if (i <= nmaster - 1)
{
if(horizontal)
mastergeo.x = cgeo.x + cgeo.width + (BORDH << 1);
else
mastergeo.y = cgeo.y + cgeo.height + BORDH + TBARH;
}
}
tags[screen][seltag[screen]].flags &= ~CleanFactFlag;
ewmh_update_current_tag_prop();
return;
}
/** Tile Right function
*/
void
tile(int screen)
{
multi_tile(screen, Right);
return;
}
/** Tile Left function
*/
void
tile_left(int screen)
{
multi_tile(screen, Left);
return;
}
/** Tile Top function
*/
void
tile_top(int screen)
{
multi_tile(screen, Top);
return;
}
/** Tile Bottom function
*/
void
tile_bottom(int screen)
{
multi_tile(screen, Bottom);
return;
}
/** Mirror tile vertical function
*/
void
mirror_vertical(int screen)
{
mirror(screen, False);
return;
}
/** Mirror tile horizontal function
*/
void
mirror_horizontal(int screen)
{
mirror(screen, True);
return;
}
/** Horizontal grid function
*/
void
grid_horizontal(int screen)
{
grid(screen, True);
return;
}
/** Vertical grid function
*/
void
grid_vertical(int screen)
{
grid(screen, False);
return;
}
/** Toggle the selected client to free
* \param cmd uicb_t type unused
*/
void
uicb_togglefree(uicb_t cmd)
{
(void)cmd;
if(!sel || sel->screen != screen_get_sel() || (sel->flags & FSSFlag))
return;
sel->flags ^= FreeFlag;
if(sel->flags & FreeFlag)
{
split_set_current(NULL, sel);
sel->flags &= ~(TileFlag | MaxFlag | LMaxFlag);
client_moveresize(sel, sel->free_geo, True);
client_raise(sel);
}
else
{
sel->free_geo = sel->geo;
sel->ogeo = sel->geo;
split_set_current(sel, NULL);
}
client_update_attributes(sel);
tags[selscreen][seltag[selscreen]].flags |= CleanFactFlag;
layout_func(selscreen, seltag[selscreen]);
return;
}
/** Toggle the selected client to max
* \param cmd uicb_t type unused
*/
void
uicb_togglemax(uicb_t cmd)
{
(void)cmd;
if(!sel || ishide(sel, selscreen) || (sel->flags & (HintFlag | FSSFlag)))
return;
sel->flags ^= MaxFlag;
if(sel->flags & MaxFlag)
{
sel->ogeo = sel->geo;
sel->free_geo = sel->geo;
sel->flags &= ~(TileFlag | FreeFlag);
split_set_current(NULL, sel);
client_maximize(sel);
XRaiseWindow(dpy, sel->frame);
}
else
{
sel->geo = sel->ogeo;
client_moveresize(sel, sel->geo, True);
tags[selscreen][seltag[selscreen]].flags |= CleanFactFlag;
split_set_current(sel, NULL);
layout_func(selscreen, seltag[selscreen]);
}
return;
}
/** Toggle the resizehint
* \param cmd uicb_t type
*/
void
uicb_toggle_resizehint(uicb_t cmd)
{
Client *c = tiled_client(selscreen, SLIST_FIRST(&clients));
screen_get_sel();
(void)cmd;
tags[selscreen][seltag[selscreen]].flags ^= ResizeHintFlag;
for(; c; c = tiled_client(selscreen, SLIST_NEXT(c, next)))
client_moveresize(c, c->geo, (tags[selscreen][seltag[selscreen]].flags & ResizeHintFlag));
return;
}
/** Toggle abovefc option
*\param cmd uicb_t type
*/
void
uicb_toggle_abovefc(uicb_t cmd)
{
Client *c;
(void)cmd;
screen_get_sel();
tags[selscreen][seltag[selscreen]].flags ^= AboveFCFlag;
if(!(tags[selscreen][seltag[selscreen]].flags & AboveFCFlag))
{
SLIST_FOREACH(c, &clients, next)
if(c->flags & AboveFlag
&& c->screen == selscreen
&& c->tag == seltag[selscreen])
{
c->flags &= ~AboveFlag;
break;
}
tags[selscreen][seltag[selscreen]].flags |= CleanFactFlag;
layout_func(selscreen, seltag[selscreen]);
}
client_focus(sel);
return;
}
/** Set the layout
* \param cmd uicb_t type
*/
void
uicb_set_layout(uicb_t cmd)
{
size_t i, j, n;
screen_get_sel();
/* Set layout_list lenght */
for(n = 0; layout_list[n].name != NULL && layout_list[n].func != NULL; ++n);
for(i = 0; i < n; ++i)
if(!strcmp(cmd, xstrdup(layout_list[i].name)))
for(j = 0; j < LEN(conf.layout); ++j)
if(layout_list[i].func == conf.layout[j].func)
tags[selscreen][seltag[selscreen]].layout = conf.layout[j];
tags[selscreen][seltag[selscreen]].flags |= CleanFactFlag;
tags[selscreen][seltag[selscreen]].flags &= ~SplitFlag;
arrange(selscreen, True);
return;
}
/** Set the client as master
* \param c Client
*/
void
layout_set_client_master(Client *c)
{
screen_get_sel();
if(!c || (c->flags & (HintFlag | FSSFlag)) || !(c->flags & TileFlag))
return;
if(c == tiled_client(selscreen, SLIST_FIRST(&clients)))
CHECK((c = tiled_client(selscreen, SLIST_NEXT(c, next))));
client_detach(c);
client_attach(c);
tags[selscreen][seltag[selscreen]].flags |= CleanFactFlag;
layout_func(selscreen, seltag[selscreen]);
return;
}
/** Check the selected client is max
* \param cmd uicb_t type unused
*/
bool
uicb_checkmax(uicb_t cmd)
{
(void)cmd;
if(!sel)
return False;
if(sel->flags & MaxFlag)
return True;
return False;
}
/** Check the selected client is free
* \param cmd uicb_t type unused
*/
bool
uicb_checkfree(uicb_t cmd)
{
(void)cmd;
if(!sel)
return False;
if(sel->flags & FreeFlag)
return True;
return False;
}
/** Check layout type
* \param cmd uicb_t type layout type
*/
bool
uicb_checklayout(uicb_t cmd)
{
screen_get_sel();
char *type = tags[selscreen][seltag[selscreen]].layout.type;
if(type && !strcmp(cmd, type))
return True;
return False;
}
-363
View File
@@ -1,363 +0,0 @@
/*
* menu.c
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "wmfs.h"
static int
menu_get_longer_string(MenuItem *mi, int nitem)
{
int i, w, l = 0;
for(i = 0; i < nitem; ++i)
if((w = textw(mi[i].name)) > l)
l = w;
return l;
}
static bool
menu_get_checkstring_needed(MenuItem *mi, int nitem)
{
(void)mi;
(void)nitem;
return True;
}
static void
menu_draw_item_name(Menu *menu, int item, BarWindow *winitem[], int chcklen)
{
int x;
int width = menu_get_longer_string(menu->item, menu->nitem) + chcklen + PAD / 3;
switch(menu->align)
{
case MA_Left:
x = chcklen + PAD / 2;
break;
case MA_Right:
x = width - textw(menu->item[item].name) + PAD * 3 / 2;
break;
default:
case MA_Center:
x = (width - (chcklen + PAD / 3)) / 2 - textw(menu->item[item].name) / 2 + chcklen + PAD / 3;
break;
}
barwin_draw_text(winitem[item], x, FHINFOBAR, menu->item[item].name);
if(menu->item[item].check)
if(menu->item[item].check(menu->item[item].cmd))
barwin_draw_text(winitem[item], PAD / 3, FHINFOBAR, conf.selected_layout_symbol);
if(menu->item[item].submenu)
barwin_draw_text(winitem[item], width + PAD * 2, FHINFOBAR, ">");
return;
}
static bool
menu_activate_item(Menu *menu, int i)
{
int j, x, y;
int chcklen = 0;
if(menu_get_checkstring_needed(menu->item, menu->nitem))
chcklen = textw(conf.selected_layout_symbol) + PAD / 3;
if(menu->item[i].submenu)
{
for(j = 0; j < conf.nmenu; ++j)
if(!strcmp(menu->item[i].submenu, conf.menu[j].name))
{
y = menu->y + ((i - 1) * INFOBARH + PAD) - SHADH * 2;
x = menu->x + menu_get_longer_string(menu->item, menu->nitem) + chcklen + textw(">") + PAD * 3;
menu_draw(conf.menu[j], x, y);
return True;
}
}
else if(menu->item[i].func)
{
menu->item[i].func(menu->item[i].cmd);
return True;
}
return False;
}
static void
menu_focus_item(Menu *menu, int item, BarWindow *winitem[])
{
int i;
int chcklen = 0;
if(menu_get_checkstring_needed(menu->item, menu->nitem))
chcklen = textw(conf.selected_layout_symbol) + PAD / 3;
menu->focus_item = item;
if(menu->focus_item > menu->nitem - 1)
menu->focus_item = 0;
else if(menu->focus_item < 0)
menu->focus_item = menu->nitem - 1;
for(i = 0; i < menu->nitem; ++i)
{
winitem[i]->fg = ((i == menu->focus_item) ? menu->colors.focus.fg : menu->colors.normal.fg);
winitem[i]->bg = ((i == menu->focus_item) ? menu->colors.focus.bg : menu->colors.normal.bg);
barwin_refresh_color(winitem[i]);
menu_draw_item_name(menu, i, winitem, chcklen);
barwin_refresh(winitem[i]);
}
return;
}
static bool
menu_manage_event(XEvent *ev, Menu *menu, BarWindow *winitem[])
{
int i, c = 0;
KeySym ks = 0;
bool quit = False;
char acc = 0;
switch(ev->type)
{
/* Mouse events */
case ButtonPress:
/* Execute the function linked with the item */
for(i = 0; i < menu->nitem; ++i)
{
if(ev->xbutton.window == winitem[i]->win
&& (ev->xbutton.button == Button1 || ev->xbutton.button == Button2))
quit = menu_activate_item(menu, i);
else if(ev->xbutton.window != winitem[i]->win)
++c;
else if(ev->xbutton.button == Button4)
menu_focus_item(menu, menu->focus_item - 1, winitem);
else if(ev->xbutton.button == Button5)
menu_focus_item(menu, menu->focus_item + 1, winitem);
}
/* If the clicked window is not one of menu wins (items), quit. */
if(c == i)
quit = True;
break;
/* Keys */
case KeyPress:
XLookupString(&ev->xkey, NULL, 0, &ks, 0);
switch(ks)
{
case XK_Up:
menu_focus_item(menu, menu->focus_item - 1, winitem);
break;
case XK_Down:
menu_focus_item(menu, menu->focus_item + 1, winitem);
break;
case XK_Return:
quit = menu_activate_item(menu, menu->focus_item);
break;
case XK_Escape:
quit = True;
break;
}
break;
/* Focus (with mouse) management */
case EnterNotify:
/* For focus an item with the mouse */
for(i = 0; i < menu->nitem; ++i)
if(ev->xcrossing.window == winitem[i]->win)
{
acc = 1;
menu_focus_item(menu, i, winitem);
if(menu->item[i].submenu)
menu_activate_item(menu, menu->focus_item);
}
if(!acc)
{
if(ev->xcrossing.window)
XSendEvent(dpy, ev->xcrossing.window, False, StructureNotifyMask, ev);
return True;
}
break;
default:
if(ev->type < nevent && ev->type > 0)
HANDLE_EVENT(ev);
break;
}
XNextEvent(dpy, ev);
return quit;
}
void
uicb_menu(uicb_t cmd)
{
int i, d, u, x, y;
Window w;
if(!strcmp(cmd, "menulayout"))
menu_draw(menulayout, menulayout.x, menulayout.y);
for(i = 0; i < conf.nmenu; ++i)
if(!strcmp(cmd, conf.menu[i].name))
{
if(conf.menu[i].place_at_mouse)
{
XQueryPointer(dpy, ROOT, &w, &w, &x, &y, &d, &d, (uint *)&u);
conf.menu[i].x = x;
conf.menu[i].y = y;
}
else
{
screen_get_sel();
x = conf.menu[i].x + spgeo[selscreen].x;
y = conf.menu[i].y + spgeo[selscreen].y;
}
menu_draw(conf.menu[i], x, y);
}
return;
}
void
menu_clear(Menu *menu)
{
free(menu->item);
menu->nitem = 0;
return;
}
void
menu_init(Menu *menu, char *name, int nitem, uint bg_f, char *fg_f, uint bg_n, char *fg_n)
{
/* Item */
menu->nitem = nitem;
menu->item = xcalloc(nitem, sizeof(*menu->item));
menu->name = name;
/* Colors */
menu->colors.focus.bg = bg_f;
menu->colors.focus.fg = fg_f;
menu->colors.normal.bg = bg_n;
menu->colors.normal.fg = fg_n;
return;
}
void
menu_new_item(MenuItem *mi, char *name, void *func, char *cmd)
{
mi->name = name;
mi->func = func;
mi->cmd = cmd;
return;
}
void
menu_draw(Menu menu, int x, int y)
{
int i, width, height, out;
XEvent ev;
BarWindow *item[menu.nitem];
BarWindow *frame;
int chcklen = 0;
if(menu_get_checkstring_needed(menu.item, menu.nitem))
chcklen = textw(conf.selected_layout_symbol) + PAD / 3;
width = menu_get_longer_string(menu.item, menu.nitem) + chcklen + textw(">") + PAD * 3;
height = menu.nitem * (INFOBARH - SHADH);
/* Frame barwin */
screen_get_sel();
if((out = x + width - MAXW) > 0)
x -= out;
if((out = y + height - MAXH) > 0)
y -= out;
frame = barwin_create(ROOT, x, y, width + SHADH, height + SHADH * 3,
menu.colors.normal.bg, menu.colors.normal.fg, False, False, True);
barwin_map(frame);
barwin_map_subwin(frame);
barwin_refresh_color(frame);
for(i = 0; i < menu.nitem; ++i)
{
item[i] = barwin_create(frame->win,
SHADH,
(i * (INFOBARH - SHADH) + SHADH),
width - SHADH,
INFOBARH,
menu.colors.normal.bg,
menu.colors.normal.fg,
True, False, False);
barwin_map(item[i]);
barwin_refresh_color(item[i]);
menu_draw_item_name(&menu, i, item, chcklen);
barwin_refresh(item[i]);
}
/* Select the first item */
menu_focus_item(&menu, 0, item);
XGrabKeyboard(dpy, ROOT, True, GrabModeAsync, GrabModeAsync, CurrentTime);
XNextEvent(dpy, &ev);
while(!menu_manage_event(&ev, &menu, item));
XUngrabKeyboard(dpy, CurrentTime);
for(i = 0; i < menu.nitem; ++i)
barwin_delete(item[i]);
barwin_delete(frame);
return;
}
-386
View File
@@ -1,386 +0,0 @@
/*
* mouse.c
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "wmfs.h"
Window prevwin;
/** Draw the border when a client in dragging/resizing with mouse
*/
static void
mouse_dragborder(Geo geo, GC g)
{
XDrawRectangle(dpy, ROOT, g,
geo.x - (BORDH >> 1),
geo.y - (TBARH - (BORDH >> 1)),
geo.width + BORDH,
geo.height + TBARH);
return;
}
static void
mouse_cfactor_border(Client *c, int f[4], GC g)
{
int e;
mouse_dragborder(cfactor_geo(c->wrgeo, f, &e), g);
return;
}
/** Move a client in tile grid with the mouse
*\param c Client double pointer
*/
static void
mouse_move_tile_client(Client **c)
{
Client *sc;
Window w;
int d;
if(!((*c)->flags & (TileFlag | LMaxFlag)))
return;
XQueryPointer(dpy, ROOT, &w, &w, &d, &d, &d, &d, (uint*)&d);
if(((sc = client_gb_win(w)) || (sc = client_gb_frame(w)) || (sc = client_gb_titlebar(w)))
&& (*c)->win != sc->win && !((*c)->flags & HideFlag) && !(sc->flags & HideFlag) && (sc->flags & TileFlag))
{
client_swap(sc, *c);
client_focus(sc);
swap_ptr((void**)c, (void**)&sc);
}
return;
}
/** Move a client from one tag to another with dah mouse
*\param c client pointer
*/
static void
mouse_move_tag_client(Client *c)
{
Window w;
int i, d, s;
if(!(c->flags & (TileFlag | LMaxFlag)))
return;
s = c->screen;
XQueryPointer(dpy, infobar[selscreen].tags_board->win, &w, &w, &d, &d, &d, &d, (uint*)&d);
if(w == prevwin)
return;
prevwin = w;
for(i = 1; i < conf.ntag[selscreen] + 1; ++i)
if(infobar[selscreen].tags[i]->win == w
&& tags[selscreen][i].layout.func != freelayout)
{
tag_transfert(c, i);
if(s != c->screen)
arrange(c->screen, True);
}
return;
}
/** Move the client with the mouse
* \param c Client pointer
*/
static void
mouse_move(Client *c)
{
int ocx, ocy, mx, my;
int dint;
uint duint;
Window dw;
Geo geo = c->geo;
XGCValues xgc;
GC gci;
XEvent ev;
if(c->flags & (MaxFlag | FSSFlag))
return;
ocx = c->geo.x;
ocy = c->geo.y;
if(XGrabPointer(dpy, ROOT, False, MouseMask, GrabModeAsync, GrabModeAsync,
None, cursor[CurMove], CurrentTime) != GrabSuccess)
return;
if(!(c->flags & TileFlag) && !(c->flags & LMaxFlag))
XGrabServer(dpy);
/* Set the GC for the rectangle */
xgc.function = GXinvert;
xgc.subwindow_mode = IncludeInferiors;
xgc.line_width = BORDH;
gci = XCreateGC(dpy, ROOT, GCFunction | GCSubwindowMode | GCLineWidth, &xgc);
if(!(c->flags & TileFlag) && !(c->flags & LMaxFlag))
mouse_dragborder(c->geo, gci);
XQueryPointer(dpy, ROOT, &dw, &dw, &mx, &my, &dint, &dint, &duint);
do
{
XMaskEvent(dpy, MouseMask | SubstructureRedirectMask, &ev);
screen_get_sel();
if(ev.type == MotionNotify)
{
mouse_move_tile_client(&c);
mouse_move_tag_client(c);
/* To move a client normally, in freelayout */
if(!(c->flags & TileFlag) && !(c->flags & LMaxFlag))
{
mouse_dragborder(geo, gci);
geo.x = (ocx + (ev.xmotion.x - mx));
geo.y = (ocy + (ev.xmotion.y - my));
/*
* Need to draw 2 times the same rectangle because
* it is draw with the revert color; revert + revert = normal
*/
mouse_dragborder(geo, gci);
}
}
else if((ev.type == MapRequest || ev.type == ConfigureRequest))
HANDLE_EVENT(&ev);
}
while(ev.type != ButtonRelease);
/* One time again to delete all the trace on the window */
if(!(c->flags & (TileFlag | LMaxFlag)))
{
mouse_dragborder(geo, gci);
client_moveresize(c, geo, False);
frame_update(c);
XUngrabServer(dpy);
}
client_update_attributes(c);
XUngrabPointer(dpy, CurrentTime);
XFreeGC(dpy, gci);
return;
}
/** Resize a client with the mouse
* \param c Client pointer
*/
void
mouse_resize(Client *c)
{
Geo geo = c->geo, ogeo = c->geo;
Position pos = Right;
XEvent ev;
Window w;
int d, u, omx, omy;
XGCValues xgc;
GC gci;
int f[4] = { 0 };
if(c->flags & (MaxFlag | LMaxFlag | FSSFlag))
return;
XQueryPointer(dpy, ROOT, &w, &w, &omx, &omy, &d, &d, (uint *)&u);
if((omx - c->geo.x) < (c->geo.width >> 1))
pos = Left;
if(XGrabPointer(dpy, ROOT, False, MouseMask, GrabModeAsync, GrabModeAsync, None,
cursor[((c->flags & TileFlag) ? CurResize : ((pos == Right) ? CurRightResize : CurLeftResize))],
CurrentTime) != GrabSuccess)
return;
if(!(c->flags & TileFlag))
XGrabServer(dpy);
/* Set the GC for the rectangle */
xgc.function = GXinvert;
xgc.subwindow_mode = IncludeInferiors;
xgc.line_width = BORDH;
gci = XCreateGC(dpy, ROOT, GCFunction | GCSubwindowMode | GCLineWidth, &xgc);
if(!(c->flags & TileFlag))
{
if(pos == Right)
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->geo.width + conf.client.borderheight, c->geo.height);
else
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, 0, c->geo.height);
mouse_dragborder(c->geo, gci);
}
else
mouse_cfactor_border(c, f, gci);
do
{
XMaskEvent(dpy, MouseMask | SubstructureRedirectMask, &ev);
if(ev.type == MotionNotify)
{
/* To resize client in tile mode with cfactor */
if(c->flags & TileFlag)
{
mouse_cfactor_border(c, f, gci);
if(omx >= c->frame_geo.x + (c->frame_geo.width >> 1))
f[Right] = ev.xmotion.x_root - omx;
else
f[Left] = omx - ev.xmotion.x_root;
if(omy >= c->frame_geo.y + (c->frame_geo.height >> 1))
f[Bottom] = ev.xmotion.y_root - omy;
else
f[Top] = omy - ev.xmotion.y_root;
mouse_cfactor_border(c, f, gci);
}
/* Free mode */
else if(!(c->flags & TileFlag))
{
mouse_dragborder(geo, gci);
if(pos == Right)
{
geo.width = ((ev.xmotion.x - c->geo.x < c->minw) ? c->minw : ev.xmotion.x - c->geo.x);
geo.height = ((ev.xmotion.y - c->geo.y < c->minh) ? c->minh : ev.xmotion.y - c->geo.y);
}
else
{
geo.x = (geo.width != c->maxw) ? c->geo.x - (c->geo.x - ev.xmotion.x) : geo.x;
geo.width = ((c->geo.width + (c->geo.x - geo.x) < c->minw)
? c->minw && (geo.x = (c->geo.x + c->geo.width) - c->minw)
: c->geo.width + (c->geo.x - geo.x));
geo.height = ((ev.xmotion.y - c->geo.y <= c->minh) ? c->minh : ev.xmotion.y - c->geo.y);
}
client_geo_hints(&geo, c);
mouse_dragborder((ogeo = geo), gci);
XSync(dpy, False);
}
}
}
while(ev.type != ButtonRelease);
if(!(c->flags & TileFlag))
{
mouse_dragborder(ogeo, gci);
client_moveresize(c, geo, True);
frame_update(c);
XUngrabServer(dpy);
}
else
{
mouse_cfactor_border(c, f, gci);
cfactor_multi_set(c, f);
}
client_update_attributes(c);
XUngrabPointer(dpy, CurrentTime);
XFreeGC(dpy, gci);
return;
}
/** Grab buttons
* \param c Client pointer
* \param focused For know if c is or not focused
*/
void
mouse_grabbuttons(Client *c, bool focused)
{
size_t i = 0;
uint but[] = {Button1, Button2, Button3, Button4, Button5};
XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
if(focused)
for(; i < LEN(but); ++i)
{
XGrabButton(dpy, but[i], conf.client.mod, c->win, False,
ButtonMask, GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, but[i], conf.client.mod | LockMask, c->win, False,
ButtonMask, GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, but[i], conf.client.mod | numlockmask, c->win, False,
ButtonMask, GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, but[i], conf.client.mod | LockMask | numlockmask, c->win, False,
ButtonMask, GrabModeAsync, GrabModeSync, None, None);
}
else
XGrabButton(dpy, AnyButton, AnyModifier, c->win, False,
ButtonMask, GrabModeAsync, GrabModeSync, None, None);
return;
}
/** Move the selected client
* \param cmd uicb_t type unused
*/
void
uicb_mouse_move(uicb_t cmd)
{
(void)cmd;
CHECK(sel);
mouse_move(sel);
return;
}
/** Reisze the selected client
* \param cmd uicb_t type unused
*/
void
uicb_mouse_resize(uicb_t cmd)
{
(void)cmd;
CHECK(sel);
mouse_resize(sel);
return;
}
-626
View File
@@ -1,626 +0,0 @@
/*
* Copyright (c) 2010 Philippe Pepiot <phil@philpep.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#ifndef _BSD_SOURCE
#define _BSD_SOURCE
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include <libgen.h>
#include <pwd.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <err.h>
#include "parse.h"
extern char *__progname;
enum keyword_t { SEC_START, SEC_END, INCLUDE, WORD, EQUAL, LIST_START, LIST_END, NONE };
#ifdef DEBUG
static struct {
const char *name;
enum keyword_t type;
} kw_t_name[] = {
{"SEC_START", SEC_START},
{"SEC_END", SEC_END},
{"INCLUDE", INCLUDE},
{"WORD", WORD},
{"EQUAL", EQUAL},
{"LIST_START", LIST_START},
{"LIST_END", LIST_END},
{"NONE", NONE},
};
#endif
struct files {
char *name;
struct files *parent;
};
struct keyword {
enum keyword_t type;
/* if WORD */
int line;
struct files *file;
char *name;
struct keyword *next;
};
struct state {
bool quote;
bool comment;
char quote_char;
};
/* TO REMOVE (use a identifier for config and fallback XDG in api functions) */
TAILQ_HEAD(, conf_sec) config;
static struct keyword *keywords = NULL;
static struct keyword *
push_keyword(struct keyword *tail, enum keyword_t type, char *buf, size_t *offset, struct files *file, int line)
{
struct keyword *kw;
#ifdef DEBUG
int i = 0;
#endif
if (type == WORD && *offset == 0)
return tail;
kw = zcalloc(sizeof(*kw));
kw->type = type;
kw->line = line;
kw->file = file;
kw->next = NULL;
if (*offset != 0) {
buf[*offset] = '\0';
if (!strcmp(buf, INCLUDE_CMD))
kw->type = INCLUDE;
else
kw->name = strdup(buf);
*offset = 0;
}
else
kw->name = NULL;
if (tail)
tail->next = kw;
#ifdef DEBUG
for (i = 0; kw_t_name[i].type != NONE; i++) {
if (kw_t_name[i].type == kw->type) {
warnx("%s %s %s:%d\n", kw_t_name[i].name,
(kw->name) ? kw->name : "",
kw->file->name, kw->line);
}
}
#endif
return kw;
}
static void
syntax(struct keyword *kw, const char *fmt, ...)
{
va_list args;
fprintf(stderr, "%s:", __progname);
if (kw && kw->file && kw->file->name)
fprintf(stderr, "%s:%d", kw->file->name, kw->line);
if (kw && kw->name)
fprintf(stderr, ", near '%s'", kw->name);
fprintf(stderr, ": ");
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
fprintf(stderr, "\n");
}
#define PUSH_KEYWORD(type) tail = push_keyword(tail, type, bufname, &j, file, line)
static struct keyword *
parse_keywords(const char *filename)
{
int fd;
struct stat st;
char *buf;
struct keyword *head = NULL;
struct keyword *tail = NULL;
struct files *file;
enum keyword_t type; /* keyword type to push */
struct state s = { False, False, '\0'};
char *bufname;
char path[PATH_MAX];
size_t i, j;
int line;
bool error = False;
if (stat(filename, &st) == -1 || (fd = open(filename, O_RDONLY)) == -1) {
warn("%s", filename);
return NULL;
}
if (st.st_size == 0) {
warnx("%s: empty file", filename);
close(fd);
return NULL;
}
if (!realpath(filename, path)) {
warn("%s", filename);
close(fd);
return NULL;
}
buf = zmalloc(st.st_size+1);
if (read(fd, buf, st.st_size) == -1) {
warn("%s", filename);
free(buf);
close(fd);
return NULL;
}
buf[st.st_size] = '\0';
file = zcalloc(sizeof(*file));
bufname = zcalloc(sizeof(*bufname) * BUFSIZ);
file->name = strdup(path);
file->parent = NULL;
for(i = 0, j = 0, line = 1; i < (size_t)st.st_size; i++) {
if (!head && tail)
head = tail;
if (buf[i] == '\n' && s.comment == True) {
line++;
s.comment = False;
continue;
}
if (buf[i] == '#' && s.quote == False) {
s.comment = True;
continue;
}
if (s.comment == True)
continue;
if (s.quote == True && buf[i] == s.quote_char) {
/* end of quotted string */
PUSH_KEYWORD(WORD);
s.quote = False;
continue;
}
if (s.quote == False) {
if ((buf[i] == '"' || buf[i] == '\'')) {
PUSH_KEYWORD(WORD);
/* begin quotted string */
s.quote_char = buf[i];
s.quote = True;
continue;
}
if (buf[i] == '[') {
PUSH_KEYWORD(WORD);
if (buf[i+1] == '/') {
i +=2;
type = SEC_END;
}
else {
i++;
type = SEC_START;
}
/* get section name */
while (buf[i] != ']') {
if (i >= ((size_t)st.st_size-1) || j >= (BUFSIZ-1)) {
bufname[j] = '\0';
syntax(NULL, "word too long in %s:%d near '%s'",
file->name, line, bufname);
error = True;
break;
}
bufname[j++] = buf[i++];
}
PUSH_KEYWORD(type);
continue;
}
if (buf[i] == '{') {
PUSH_KEYWORD(WORD);
PUSH_KEYWORD(LIST_START);
continue;
}
if (buf[i] == '}') {
PUSH_KEYWORD(WORD);
PUSH_KEYWORD(LIST_END);
continue;
}
if (buf[i] == ',') {
PUSH_KEYWORD(WORD);
continue;
}
if (buf[i] == '=') {
PUSH_KEYWORD(WORD);
PUSH_KEYWORD(EQUAL);
continue;
}
if (strchr("\t\n ", buf[i])) {
PUSH_KEYWORD(WORD);
if (buf[i] == '\n')
line++;
continue;
}
} /* s.quote == False */
if (j >= (BUFSIZ - 1)) {
bufname[j] = '\0';
syntax(NULL, "word too long in %s:%d near '%s'",
file->name, line, bufname);
error = True;
break;
}
bufname[j++] = buf[i];
}
free(buf);
free(bufname);
close(fd);
warnx("%s read", file->name);
return (error ? NULL: head);
}
/*
* return NULL on failure and head->next if
* no config found (of file doesn't exist)
* NOTE to devs: head->name is the file to include
*/
static struct keyword *
include(struct keyword *head)
{
struct keyword *kw;
struct keyword *tail;
struct files *file;
struct passwd *user;
char *filename = NULL;
char *base = NULL;
head = head->next;
if (!head || head->type != WORD) {
syntax(head, "missing filename to include");
return NULL;
}
/* replace ~ by user directory */
if (head->name && head->name[0] == '~') {
if ( (user = getpwuid(getuid())) && user->pw_dir)
xasprintf(&filename, "%s%s", user->pw_dir, head->name+1);
else if (getenv("HOME"))
xasprintf(&filename, "%s%s", getenv("HOME"), head->name+1);
else /* to warning ? */
filename = head->name;
}
/* relative path from parent file */
else if (head->name && head->name[0] != '/') {
base = strdup(head->file->name);
xasprintf(&filename, "%s/%s", dirname(base), head->name);
free(base);
}
else
filename = head->name;
if (!(kw = parse_keywords(filename))) {
warnx("no config found in include file %s", head->name);
if (filename != head->name)
free(filename);
return NULL;
}
kw->file->parent = head->file;
/* detect circular include */
for (file = kw->file->parent; file != NULL; file = file->parent) {
if (!strcmp(file->name, kw->file->name)) {
syntax(kw, "circular include of %s", kw->file->name);
if (filename != head->name)
free(filename);
return NULL;
}
}
if (filename != head->name)
free(filename);
head = head->next;
if (kw) {
for (tail = kw; tail->next; tail = tail->next);
tail->next = head;
}
return kw;
}
static void *
free_opt(struct conf_opt *o)
{
free(o);
return NULL;
}
static struct conf_opt *
get_option(struct keyword **head)
{
struct conf_opt *o;
size_t j = 0;
struct keyword *kw = *head;
o = zcalloc(sizeof(*o));
o->name = kw->name;
o->used = False;
o->line = kw->line;
o->filename = kw->file->name;
kw = kw->next;
if (kw->type != EQUAL) {
syntax(kw, "missing '=' here");
return free_opt(o);
}
kw = kw->next;
if (!kw) {
syntax(kw, "missing value");
return free_opt(o);
}
switch (kw->type) {
case INCLUDE:
if (!(kw = include(kw)))
return free_opt(o);
break;
case WORD:
o->val[0] = kw->name;
o->val[1] = NULL;
kw = kw->next;
break;
case LIST_START:
kw = kw->next;
while (kw && kw->type != LIST_END) {
switch (kw->type) {
case WORD:
if (j >= (PARSE_MAX_LIST - 1)) {
syntax(kw, "too much values in list");
return free_opt(o);
}
o->val[j++] = kw->name;
kw = kw->next;
break;
case INCLUDE:
if (!(kw = include(kw)))
return free_opt(o);
break;
default:
syntax(kw, "declaration into a list");
return free_opt(o);
break;
}
}
if (!kw) {
syntax(kw, "list unclosed");
return free_opt(o);
}
kw = kw->next;
break;
default:
syntax(kw, "missing value");
return free_opt(o);
break;
}
*head = kw;
return o;
}
static void *
free_sec(struct conf_sec *sec)
{
struct conf_opt *o;
struct conf_sec *s;
if (sec) {
while (!SLIST_EMPTY(&sec->optlist)) {
o = SLIST_FIRST(&sec->optlist);
SLIST_REMOVE_HEAD(&sec->optlist, entry);
free_opt(o);
}
while (!TAILQ_EMPTY(&sec->sub)) {
s = TAILQ_FIRST(&sec->sub);
TAILQ_REMOVE(&sec->sub, s, entry);
free_sec(s);
}
free(sec);
}
return NULL;
}
static struct conf_sec *
get_section(struct keyword **head)
{
struct conf_sec *s;
struct conf_opt *o;
struct conf_sec *sub;
struct keyword *kw = *head;
s = zcalloc(sizeof(*s));
s->name = kw->name;
TAILQ_INIT(&s->sub);
SLIST_INIT(&s->optlist);
kw = kw->next;
while (kw && kw->type != SEC_END) {
switch (kw->type) {
case INCLUDE:
if (!(kw = include(kw)))
return free_sec(s);
break;
case SEC_START:
if (!(sub = get_section(&kw)))
return free_sec(s);
TAILQ_INSERT_TAIL(&s->sub, sub, entry);
s->nsub++;
break;
case WORD:
if (!(o = get_option(&kw)))
return free_sec(s);
SLIST_INSERT_HEAD(&s->optlist, o, entry);
s->nopt++;
break;
default:
syntax(kw, "syntax error");
return free_sec(s);
break;
}
}
if (!kw || strcmp(kw->name, s->name)) {
syntax(kw, "missing end section %s", s->name);
return free_sec(s);
}
kw = kw->next;
*head = kw;
return s;
}
int
free_conf(void)
{
struct conf_sec *s;
struct keyword *kw, *nkw;
struct files **f = NULL;
int i, nf = 0;
while (!TAILQ_EMPTY(&config)) {
s = TAILQ_FIRST(&config);
TAILQ_REMOVE(&config, s, entry);
free_sec(s);
}
kw = keywords;
while (kw) {
nkw = kw->next;
free(kw->name);
for (i = 0; i < nf; i++) {
if (f[i] == kw->file) {
if (!(f = realloc(f, sizeof(*f) * (++i))))
err(EXIT_FAILURE, "realloc");
f[i-1] = kw->file;
}
}
kw = nkw;
}
if (nf > 0) {
for (i = 0; i < nf; i++) {
free(f[i]->name);
free(f[i]);
}
free(f);
}
return -1;
}
int
get_conf(const char *filename)
{
struct conf_sec *s;
struct keyword *head, *kw;
kw = head = parse_keywords(filename);
if (!head)
return -1; /* TODO ERREUR */
keywords = head;
TAILQ_INIT(&config);
while (kw) {
switch (kw->type) {
case INCLUDE:
if (!(kw = include(kw)))
return free_conf();
break;
case SEC_START:
if (!(s = get_section(&kw)))
return free_conf();
TAILQ_INSERT_TAIL(&config, s, entry);
break;
default:
syntax(kw, "out of any section");
return free_conf();
break;
}
}
return 0;
}
-114
View File
@@ -1,114 +0,0 @@
/*
* Copyright (c) 2010 Philippe Pepiot <phil@philpep.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef PARSE_H
#define PARSE_H
#include "wmfs.h"
#define INCLUDE_CMD "@include"
#define PARSE_MAX_LIST 32
struct conf_opt {
char *name;
char *val[PARSE_MAX_LIST];
size_t nval;
bool used;
int line;
char *filename;
SLIST_ENTRY(conf_opt) entry;
};
struct conf_sec {
char *name;
SLIST_HEAD(, conf_opt) optlist;
TAILQ_HEAD(, conf_sec) sub;
size_t nopt;
size_t nsub;
TAILQ_ENTRY(conf_sec) entry;
};
struct opt_type {
long int num;
float fnum;
bool boolean;
char *str;
};
/*
* Create config from file
* return -1 on failure
*/
int get_conf(const char *);
/*
* Print unused option name from section s (and subsections).
* If s == NULL print unused option name for all config struct.
*/
void print_unused(struct conf_sec *s);
/*
* Free the config struct.
* WARNING: This make all string
* returned by fetch_(opt|section)(_first) unusable.
*/
int free_conf(void);
/*
* Get all subsection matching the given name on the given
* section.
* If section == NULL, return subsections from root section.
* Return a NULL terminated array.
* Subsections are returned in order as they are in config file
* WARNING : This MUST be free() after use.
*/
struct conf_sec **fetch_section(struct conf_sec *, char *);
/*
* Get first subsection matching the given name
* on the given section. (first found on the file)
*/
struct conf_sec *fetch_section_first(struct conf_sec *, char *);
/*
* Count member of a conf_sec **
*/
size_t fetch_section_count(struct conf_sec **);
/*
* Return all options matching the given name on the given subsection.
* If none match or section == NULL return opt_type build with the
* given default param.
* WARNING: This MUST be free() after use.
* WARNING: The string member is directly taken from the config struct.
* WARNING: Returned in reverse order as they are in config file.
* (I think the last option MUST overwrite all others)
*/
struct opt_type fetch_opt_first(struct conf_sec *, char *, char *);
/*
* Get first (last in config file) option matching the given name
* on the given section.
* WARNING: The string member is directly taken from the config struct.
*/
struct opt_type *fetch_opt(struct conf_sec *, char *, char *);
/*
* Count member of a opt_type *
*/
size_t fetch_opt_count(struct opt_type *);
#endif /* PARSE_H */
-197
View File
@@ -1,197 +0,0 @@
/*
* Copyright (c) 2010 Philippe Pepiot <phil@philpep.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _BSD_SOURCE
#define _BSD_SOURCE
#endif
#include <string.h>
#include <stdlib.h>
#include <err.h>
#include "parse.h"
extern TAILQ_HEAD(, conf_sec) config;
static const struct opt_type opt_type_null = { 0, 0, False, NULL };
static struct opt_type
string_to_opt(char *s)
{
struct opt_type ret = opt_type_null;
if (!s || !strlen(s))
return ret;
ret.num = strtol(s, (char**)NULL, 10);
ret.fnum = strtod(s, NULL);
if (!strcmp(s, "true") || !strcmp(s, "True") ||
!strcmp(s, "TRUE") || !strcmp(s, "1"))
ret.boolean = True;
else
ret.boolean = False;
ret.str = s;
return ret;
}
void
print_unused(struct conf_sec *sec)
{
struct conf_sec *s;
struct conf_opt *o;
if (!sec)
{
TAILQ_FOREACH(s, &config, entry)
print_unused(s);
return;
}
SLIST_FOREACH(o, &sec->optlist, entry)
if (o->used == False)
warnx("%s:%d, unused param %s",
o->filename, o->line, o->name);
TAILQ_FOREACH(s, &sec->sub, entry)
if (!TAILQ_EMPTY(&s->sub))
print_unused(s);
}
struct conf_sec **
fetch_section(struct conf_sec *s, char *name)
{
struct conf_sec **ret;
struct conf_sec *sec;
size_t i = 0;
if (!name)
return NULL;
if (!s) {
ret = xcalloc(2, sizeof(struct conf_sec *));
TAILQ_FOREACH(sec, &config, entry)
if (!strcmp(sec->name, name)) {
ret[0] = sec;
ret[1] = NULL;
break;
}
}
else {
ret = xcalloc(s->nsub+1, sizeof(struct conf_sec *));
TAILQ_FOREACH(sec, &s->sub, entry) {
if (!strcmp(sec->name, name) && i < s->nsub)
ret[i++] = sec;
}
ret[i] = NULL;
}
return ret;
}
struct conf_sec *
fetch_section_first(struct conf_sec *s, char *name)
{
struct conf_sec *sec, *ret = NULL;
if (!name)
return NULL;
if (!s)
{
TAILQ_FOREACH(sec, &config, entry)
if(sec->name && !strcmp(sec->name, name)) {
ret = sec;
break;
}
}
else
{
TAILQ_FOREACH(sec, &s->sub, entry)
if (sec->name && !strcmp(sec->name, name)) {
ret = sec;
break;
}
}
return ret;
}
size_t
fetch_section_count(struct conf_sec **s)
{
size_t ret;
for (ret = 0; s[ret]; ret++);
return ret;
}
struct opt_type *
fetch_opt(struct conf_sec *s, char *dfl, char *name)
{
struct conf_opt *o;
struct opt_type *ret;
size_t i = 0;
if (!name)
return NULL;
ret = xcalloc(10, sizeof(struct opt_type));
if (s) {
SLIST_FOREACH(o, &s->optlist, entry)
if (!strcmp(o->name, name)) {
while (o->val[i]) {
o->used = True;
ret[i] = string_to_opt(o->val[i]);
i++;
}
ret[i] = opt_type_null;
return ret;
}
}
ret[0] = string_to_opt(dfl);
ret[1] = opt_type_null;
return ret;
}
struct opt_type
fetch_opt_first(struct conf_sec *s, char *dfl, char *name)
{
struct conf_opt *o;
if (!name)
return opt_type_null;
else if (s)
SLIST_FOREACH(o, &s->optlist, entry)
if (!strcmp(o->name, name)) {
o->used = True;
return string_to_opt(o->val[0]);
}
return string_to_opt(dfl);
}
size_t
fetch_opt_count(struct opt_type *o)
{
size_t ret;
for(ret = 0; o[ret].str; ret++);
return ret;
}
-281
View File
@@ -1,281 +0,0 @@
/*
* screen.c
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "wmfs.h"
/** Count the screens
*\return the number of screen
*/
int
screen_count(void)
{
int n = ScreenCount(dpy);
#ifdef HAVE_XINERAMA
if(XineramaIsActive(dpy))
XineramaQueryScreens(dpy, &n);
#endif /* HAVE_XINERAMA */
/* Set _WMFS_SCREEN_COUNT */
if(net_atom)
XChangeProperty(dpy, ROOT, net_atom[wmfs_screen_count], XA_CARDINAL, 32,
PropModeReplace, (uchar*)&n, 1);
return n;
}
/** Get screen geometry by number
*\param s Screen number
*\return Geo struct
*/
Geo
screen_get_geo(int s)
{
int barpos = tags[selscreen][seltag[selscreen]].barpos;
Geo geo;
geo.x = BORDH;
if(barpos == IB_Hide || barpos == IB_Bottom)
geo.y = TBARH;
else
geo.y = INFOBARH + TBARH;
geo.height = MAXH - INFOBARH - TBARH;
geo.width = MAXW;
#ifdef HAVE_XINERAMA
if(XineramaIsActive(dpy))
{
XineramaScreenInfo *xsi;
int n = 0;
xsi = XineramaQueryScreens(dpy, &n);
geo.x = xsi[s].x_org + BORDH;
if(barpos == IB_Hide || barpos == IB_Bottom)
geo.y = TBARH;
else
geo.y = xsi[s].y_org + INFOBARH + TBARH;
geo.height = xsi[s].height - INFOBARH - TBARH;
geo.width = xsi[s].width;
XFree(xsi);
}
#else
(void)s;
#endif /* HAVE_XINERAMA */
return geo;
}
/** Get the current screen number with
* coordinated
*\param geo Geometry for get the screen number
*\return The screen number
*/
int
screen_get_with_geo(int x, int y)
{
int i = 0;
for(; i < screen_count(); ++i)
if(INAREA(x, y, spgeo[i]))
return i;
return 0;
}
/** Set the selected screen
*\param screen Number of the wanted selected screen
*/
void
screen_set_sel(int screen)
{
if(screen < 0 || screen > screen_count() - 1)
screen = 0;
if(selscreen != screen)
prevselscreen = selscreen;
client_focus(NULL);
XWarpPointer(dpy, None, ROOT, 0, 0, 0, 0,
sgeo[screen].x + (sgeo[screen].width >> 1),
sgeo[screen].y + (sgeo[screen].height >> 1));
selscreen = screen;
return;
}
/** Get and set the selected screen
*\return The number of the selected screen
*/
int
screen_get_sel(void)
{
int os = selscreen;
selscreen = 0;
#ifdef HAVE_XINERAMA
if(XineramaIsActive(dpy))
{
/* Unused variables (except x/y) */
Window w;
int d, x, y;
XQueryPointer(dpy, ROOT, &w, &w, &x, &y, &d, &d, (uint *)&d);
selscreen = screen_get_with_geo(x, y);
}
#endif /* HAVE_XINERAMA */
/* Set _WMFS_CURRENT_SCREEN */
XChangeProperty(dpy, ROOT, net_atom[wmfs_current_screen], XA_CARDINAL, 32,
PropModeReplace, (uchar*)&selscreen, 1);
if(os != selscreen && os != prevselscreen)
prevselscreen = os;
return selscreen;
}
/** Init screen geo
*/
void
screen_init_geo(void)
{
int i;
int s = screen_count();
sgeo = xcalloc(s, sizeof(Geo));
spgeo = xcalloc(s, sizeof(Geo));
for(i = 0; i < s; ++i)
sgeo[i] = screen_get_geo(i);
spgeo[0].x = 0;
spgeo[0].y = 0;
spgeo[0].width = MAXW;
spgeo[0].height = MAXH;
#ifdef HAVE_XINERAMA
XineramaScreenInfo *xsi;
int n;
if(XineramaIsActive(dpy))
{
xsi = XineramaQueryScreens(dpy, &n);
for(i = 0; i < n; ++i)
{
spgeo[i].x = xsi[i].x_org;
spgeo[i].y = xsi[i].y_org;
spgeo[i].width = xsi[i].width;
spgeo[i].height = xsi[i].height;
}
XFree(xsi);
}
#endif /* HAVE_XINERAMA */
#ifdef HAVE_XRANDR
/* Init xrandr stuff */
int d;
XRRSelectInput(dpy, ROOT, 1);
XRRQueryExtension(dpy, &xrandr_event, &d);
#endif /* HAVE_XRANDR */
ewmh_set_desktop_geometry();
return;
}
/** Uicb: screen select
* \param cmd Screen uicb_t type
*/
void
uicb_screen_select(uicb_t cmd)
{
screen_set_sel(atoi(cmd));
return;
}
/** Uicb: screen next
* \param cmd Screen uicb_t type
*/
void
uicb_screen_next(uicb_t cmd)
{
(void)cmd;
screen_get_sel();
if(screen_count() > 1)
{
selscreen = (selscreen + 1 > screen_count() - 1) ? 0 : selscreen + 1;
screen_set_sel(selscreen);
}
return;
}
/** Uicb: screen prev
* \param cmd Screen uicb_t type
*/
void
uicb_screen_prev(uicb_t cmd)
{
(void)cmd;
screen_get_sel();
selscreen = (selscreen - 1 < 0) ? screen_count() - 1 : selscreen - 1;
screen_set_sel(selscreen);
return;
}
/** Uicb: screen prev sel
* \param cmd uicb_t type unused
*/
void
uicb_screen_prev_sel(uicb_t cmd)
{
(void)cmd;
screen_get_sel();
screen_set_sel(prevselscreen);
return;
}
-374
View File
@@ -1,374 +0,0 @@
/*
* split.c
* Copyright © 2011 Martin Duquesnoy <xorg62@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "wmfs.h"
#define SPLIT_CHECK_ROW(g1, g2, p) \
(LDIR(p) \
? (g1.y >= g2.y && (g1.y + g1.height) <= (g2.y + g2.height)) \
: (g1.x >= g2.x && (g1.x + g1.width) <= (g2.x + g2.width))) \
#define SPLIT_MOVE_DIR(d) \
void \
uicb_split_move_##d(uicb_t cmd) \
{ \
(void)cmd; \
CHECK(sel); \
split_move_dir(sel, d); \
}
/* uicb_split_move_dir() */
SPLIT_MOVE_DIR(Right);
SPLIT_MOVE_DIR(Left);
SPLIT_MOVE_DIR(Top);
SPLIT_MOVE_DIR(Bottom);
/** Arrange size of parent client of last closed client
*/
static void
_split_arrange_size(Geo g, Geo *cg, Position p)
{
if(LDIR(p))
cg->width += FRAMEW(g.width);
else
cg->height += FRAMEH(g.height);
if(p == Right)
cg->x -= FRAMEW(g.width);
if(p == Bottom)
cg->y -= FRAMEH(g.height);
return;
}
/** Set layout current clients to split/unsplit
*/
void
split_set_current(Client *nc, Client *ghost)
{
if(nc && (tags[nc->screen][nc->tag].flags & SplitFlag))
{
tags[nc->screen][nc->tag].layout.nc = nc;
tags[nc->screen][nc->tag].layout.flags |= IntegrationFlag;
}
if(ghost && (tags[ghost->screen][ghost->tag].flags & SplitFlag))
{
tags[ghost->screen][ghost->tag].layout.ghost = *ghost;
tags[ghost->screen][ghost->tag].layout.flags |= ArrangeFlag;
}
return;
}
/** Apply current operation about split
*/
void
split_apply_current(int screen, int tag)
{
/* Integrate in split mode */
if(tags[screen][tag].layout.flags & IntegrationFlag)
{
split_client_integrate(tags[screen][tag].layout.nc, sel, screen, tag);
tags[screen][tag].layout.flags &= ~IntegrationFlag;
}
/* Remove from split mode */
if(tags[screen][tag].layout.flags & ArrangeFlag)
{
split_arrange_closed(&tags[screen][tag].layout.ghost);
tags[screen][tag].layout.flags &= ~ArrangeFlag;
}
return;
}
/** Check if row direction is available to resize from it
*\param c Client pointer
*\param g Client pointer
*\param p Position
*\return True if available
*/
static bool
_split_check_row_dir(Client *c, Client *g, Position p)
{
int s = 0, cs;
Geo cgeo = c->frame_geo;
Client *cc = tiled_client(c->screen, SLIST_FIRST(&clients));
cs = (LDIR(p) ? g->frame_geo.height : g->frame_geo.width);
for(; cc; cc = tiled_client(c->screen, SLIST_NEXT(cc, next)))
if(CFACTOR_PARENTROW(cgeo, cc->frame_geo, RPOS(p))
&& SPLIT_CHECK_ROW(cc->frame_geo, g->frame_geo, p))
{
s += (LDIR(p) ? cc->frame_geo.height : cc->frame_geo.width);
if(s == cs)
return True;
if(s > cs)
return False;
}
return False;
}
/** Arrange clients after a client close
*\param ghost Ghost client
*/
void
split_arrange_closed(Client *ghost)
{
Position p;
bool b = False;
Geo cgeo;
Client *c, *cc;
int screen = ghost->screen;
int tag = (ghost->tag ? ghost->tag : seltag[screen]);
/* Use ghost client properties to fix holes in tile
* .--. ~ ~
* /xx \ ~ ~
* ~~\O _ (____ ~
* __.| .--'-==~ ~
* '---\ '. ~ , ~
* '. '-.___.-'/ ~
* '-.__ _.' ~
* ````` ~
*/
/* Search for single parent for easy resize
* Example case:
* ___________ ___________
* | | B | -> -> | | |
* | A |_____| -> Close -> | A | B |
* | | C | -> C -> | |v v v|
* |_____|_____| -> -> |_____|_____|
*/
for(p = Right; p < Center; ++p)
if((c = client_get_next_with_direction(ghost, p)))
if(CFACTOR_CHECK2(ghost->frame_geo, c->frame_geo, p))
{
_split_arrange_size(ghost->wrgeo, &c->wrgeo, p);
cfactor_clean(c);
client_moveresize(c, (c->pgeo = c->wrgeo), (tags[screen][tag].flags & ResizeHintFlag));
return;
}
/* Check row parents for full resize
* Example case:
* ___________ ___________
* | | B | -> -> | << B |
* | A |_____| -> Close -> |___________|
* | | C | -> A -> | << C |
* |_____|_____| -> -> |___________|
*/
for(p = Right; p < Center && !b; ++p)
if((c = client_get_next_with_direction(ghost, p)) && _split_check_row_dir(c, ghost, p))
{
for(cgeo = c->frame_geo, cc = tiled_client(c->screen, SLIST_FIRST(&clients));
cc; cc = tiled_client(c->screen, SLIST_NEXT(cc, next)))
if(CFACTOR_PARENTROW(cgeo, cc->frame_geo, RPOS(p))
&& SPLIT_CHECK_ROW(cc->frame_geo, ghost->frame_geo, p))
{
_split_arrange_size(ghost->wrgeo, &cc->wrgeo, p);
cfactor_clean(cc);
client_moveresize(cc, (cc->pgeo = cc->wrgeo), (tags[screen][tag].flags & ResizeHintFlag));
b = True;
}
}
return;
}
/** Split client hor or vert to insert another client in the new area
*\param c Client pointer
*\param p True = Vertical, False = Horizontal
*\return sgeo Geo of future integrated client
*/
Geo
split_client(Client *c, bool p)
{
Geo geo, sgeo;
if(!c || !(c->flags & TileFlag))
return c->wrgeo;
cfactor_clean(c);
c->flags &= ~(MaxFlag | LMaxFlag);
c->flags |= TileFlag;
/* Use geometry without resizehint applied on it */
geo = sgeo = c->wrgeo;
/* Vertical */
if(p)
{
geo.width >>= 1;
sgeo.x = FRAMEW(geo.x + geo.width);
sgeo.width = (sgeo.width >> 1) - (BORDH << 1);
/* Remainder */
sgeo.width += (c->wrgeo.x + c->wrgeo.width) - (sgeo.x + sgeo.width);
}
/* Horizontal */
else
{
geo.height = (geo.height >> 1) - TBARH;
sgeo.y = FRAMEH(geo.y + geo.height);
sgeo.height = (sgeo.height >> 1) - BORDH;
/* Remainder */
sgeo.height += (c->wrgeo.y + c->wrgeo.height) - (sgeo.y + sgeo.height);
}
client_moveresize(c, (c->pgeo = geo), (tags[c->screen][c->tag].flags & ResizeHintFlag));
return sgeo;
}
/** Apply new attributes to splitted client
*\param c Client pointer
*\param geo New geo
*/
void
split_client_fill(Client *c, Geo geo)
{
if(!c)
return;
c->flags &= ~(MaxFlag | LMaxFlag);
c->flags |= TileFlag;
cfactor_clean(c);
client_moveresize(c, (c->pgeo = geo), (tags[c->screen][c->tag].flags & ResizeHintFlag));
return;
}
/** Integrate client in tag
*\param c Client pointer (integrate)
*\param sc Splitted client pointer
*/
void
split_client_integrate(Client *c, Client *sc, int screen, int tag)
{
bool b = True;
Geo g;
if(!c || c->flags & FreeFlag || !(tags[screen][tag].flags & SplitFlag))
return;
/* Can't integrate in sc */
if(!sc || sc == c || !(sc->flags & TileFlag)
|| sc->screen != screen || sc->tag != tag)
{
/* Looking for first client on wanted tag */
b = False;
SLIST_FOREACH(sc, &clients, next)
if(sc != c && sc->screen == screen && sc->tag == tag
&& (sc->flags & TileFlag))
{
b = True;
break;
}
/* No client on wanted tag to integrate */
if(!b)
{
/* client_maximize check position of client
* to maximize it; so in case of transfert one client
* on a tag from another screen, we need it.
*/
c->geo.x = sgeo[screen].x;
c->geo.y = sgeo[screen].y;
client_maximize(c);
c->flags |= TileFlag;
return;
}
}
g = split_client(sc, (sc->frame_geo.height < sc->frame_geo.width));
split_client_fill(c, g);
return;
}
/** Move splitted client by re-arranging it in next by direction client
* Integrate c in next client by direction
* Example case, direction = left:
* ___________ ___________
* | | B | -> | A | |
* | A |_____| -> |_____| B |
* | |< C | -> | C |v v v|
* |_____|_____| -> |_____|_____|
*/
void
split_move_dir(Client *c, Position p)
{
Client *sc;
if(!c || !(tags[c->screen][c->tag].flags & SplitFlag))
return;
if((sc = client_get_next_with_direction(c, p)))
{
split_arrange_closed(c);
split_client_integrate(c, sc, sc->screen, sc->tag);
}
return;
}
/** Toggle split mode
*/
void
uicb_split_toggle(uicb_t cmd)
{
(void)cmd;
tags[selscreen][seltag[selscreen]].flags ^= SplitFlag;
layout_func(selscreen, seltag[selscreen]);
infobar_draw_layout(&infobar[selscreen]);
return;
}
-290
View File
@@ -1,290 +0,0 @@
/*
* status.c
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "wmfs.h"
/* Systray width */
static int sw = 0;
/** Parse dynamic mouse binds in str and insert it in linked list
* --> \<block>[;;;;(button;func;cmd)]\ add a mouse bind on the block object
*\param str String
*\param area Area of clicking
*\param infobar Infobar pointer
*/
void
statustext_mouse(char *str, Geo area, InfoBar *infobar)
{
StatusMouse *sm = NULL;
int i = 0, button = 1, n;
char cmd[256] = { 0 };
char func[64] = { 0 };
for(; i < (int)strlen(str); ++i, sm = NULL)
if((n = sscanf(&str[i], "(%d;%64[^;];%256[^)])", &button, func, cmd) >= 2) && n < 4)
{
sm = zcalloc(sizeof(StatusMouse));
sm->button = button;
sm->func = name_to_func((char*)func, func_list);
sm->cmd = xstrdup(cmd);
sm->area = area;
sm->infobar = infobar;
SLIST_INSERT_HEAD(&smhead, sm, next);
/* Jump to the end of the sequence */
while(str[++i + 1] != ')');
}
return;
}
/** Check rectangles blocks in str and draw it
* --> \b[x;y;width;height;#color]\
*\param ib Infobar pointer
*\param str String
*/
static void
statustext_rectangle(InfoBar *ib, char *str)
{
StatusRec r;
char as, mouse[512] = { 0 };
int i = 0, j = 0, k, n;
for(; i < (int)strlen(str); ++i, ++j)
if(((n = sscanf(&str[i], "\\b[%d;%d;%d;%d;#%x]%c",
&r.g.x, &r.g.y, &r.g.width, &r.g.height, &r.color, &as)) == 6
|| (n = sscanf(&str[i], "\\b[%d;%d;%d;%d;#%x;%512[^]]]%c",
&r.g.x, &r.g.y, &r.g.width, &r.g.height, &r.color, mouse, &as)) == 7)
&& as == '\\')
{
draw_rectangle(ib->bar->dr, r.g.x - sw, r.g.y, r.g.width, r.g.height, r.color);
if(n == 7)
statustext_mouse(mouse, r.g, ib);
for(++i, --j; str[i] != as || str[i - 1] != ']'; ++i);
}
else if(j != i)
str[j] = str[i];
for(k = j; k < i; str[k++] = '\0');
return;
}
/** Check graphs blocks in str and draw it
* --> \g[x;y;width;height;#color;data]\
*\param ib Infobar pointer
*\param str String
*/
static void
statustext_graph(InfoBar *ib, char *str)
{
StatusGraph g;
char as, c, *p;
int i, j, k, m, w;
for(i = j = 0; i < (int)strlen(str); ++i, ++j)
if(sscanf(&str[i], "\\g[%d;%d;%d;%d;#%x;%512[^]]]%c",
&g.x, &g.y, &g.w, &g.h, &g.color, g.data, &as) == 7
&& as == '\\')
{
/* data is a list of numbers separated by ';' */
w = g.w;
p = strtok(g.data, ";");
m = 0;
for(c = atoi(p); p && m < w; ++m)
{
/* height limits */
if(c < 0)
c = 0;
if(c > (char)g.h)
c = g.h;
g.data[m] = c;
p = strtok(NULL, ";");
}
/* width limits */
for(; m < w; g.data[m++] = 0);
/* data is a array[w] of bytes now */
draw_graph(ib->bar->dr, g.x - sw, g.y, g.w, g.h, g.color, g.data);
for(++i, --j; str[i] != as || str[i - 1] != ']'; ++i);
}
else if(j != i)
str[j] = str[i];
for(k = j; k < i; str[k++] = '\0');
return;
}
/** Check text blocks in str and draw it
* --> \s[x;y;#color;text]\
*\param ib Infobar pointer
*\param str String
*/
static void
statustext_text(InfoBar *ib, char *str)
{
StatusText s;
Geo area;
char as, mouse[512] = { 0 };
int i = 0, j = 0, k, n;
for(; i < (int)strlen(str); ++i, ++j)
if(((n = sscanf(&str[i], "\\s[%d;%d;%7[^;];%512[^];]]%c",
&s.x, &s.y, s.color, s.text, &as)) == 5
|| (n = sscanf(&str[i], "\\s[%d;%d;%7[^;];%512[^;];%512[^]]]%c",
&s.x, &s.y, s.color, s.text, mouse, &as)) == 6)
&& as == '\\')
{
draw_text(ib->bar->dr, s.x - sw, s.y, s.color, s.text);
/* Etablish clickable area on text */
if(n == 6)
{
area.height = font.height;
area.width = textw(s.text);
area.x = s.x - sw;
area.y = s.y - area.height;
statustext_mouse(mouse, area, ib);
}
for(++i, --j; str[i] != as || str[i - 1] != ']'; ++i);
}
else if(j != i)
str[j] = str[i];
for(k = j; k < i; str[k++] = '\0');
return;
}
/** Draw normal text and colored normal text
* --> \#color\ text in color
*\param sc Screen id
*\param ib Infobar pointer
*\param str String
*/
static void
statustext_normal(InfoBar *ib, char *str)
{
char strwc[MAXSTATUS] = { 0 };
char buf[MAXSTATUS] = { 0 };
char col[8] = { 0 };
int n, i, j, k, tw;
for(i = j = n = 0; i < (int)strlen(str); ++i, ++j)
if(str[i] == '\\' && str[i + 1] == '#' && str[i + 8] == '\\')
{
++n;
i += 8;
--j;
}
else
strwc[j] = str[i];
/* Draw normal text without any blocks */
draw_text(ib->bar->dr, (sgeo[ib->screen].width - SHADH) - (textw(strwc) + sw), FHINFOBAR, ib->bar->fg, strwc);
if(n)
{
strncpy(buf, strwc, sizeof(buf));
for(i = k = 0; i < (int)strlen(str); ++i, ++k)
if(str[i] == '\\' && str[i + 1] == '#' && str[i + 8] == '\\')
{
tw = textw(&buf[k]);
/* Store current color in col[] */
for(j = 0, ++i; str[i] != '\\'; col[j++] = str[i++]);
/* Draw a rectangle with the bar color to draw the text properly */
draw_rectangle(ib->bar->dr, (sgeo[ib->screen].width - SHADH) - (tw + sw),
0, INFOBARH - (sgeo[ib->screen].width - SHADH) - tw,
INFOBARH, conf.colors.bar);
/* Draw text with its color */
draw_text(ib->bar->dr, (sgeo[ib->screen].width - SHADH) - (tw + sw), FHINFOBAR, col, &buf[k]);
strncpy(buf, strwc, sizeof(buf));
++i;
}
}
return;
}
/** Handle statustext and draw all things in infobar of specified screen
*\param sc Screen id
*\param str String
*/
void
statustext_handle(InfoBar *ib)
{
char *str;
StatusMouse *sm;
/* Free previous linked list of mouse bind */
if(!ib->screen)
while(!SLIST_EMPTY(&smhead))
{
sm = SLIST_FIRST(&smhead);
SLIST_REMOVE_HEAD(&smhead, next);
free((void*)sm->cmd);
free(sm);
}
if(ib->screen == conf.systray.screen)
sw = systray_get_width();
str = xstrdup(ib->statustext);
/* Store rectangles, located text & images properties. */
statustext_rectangle(ib, str);
statustext_graph(ib, str);
statustext_text(ib, str);
/* Draw normal text (and possibly colored with \#color\ blocks) */
statustext_normal(ib, str);
sw = 0;
free(str);
return;
}
-620
View File
@@ -1,620 +0,0 @@
/*
* structs.h
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef STRUCTS_H
#define STRUCTS_H
#include "wmfs.h"
#define NBUTTON 8
#define MAXTAG 36
#define NUM_OF_LAYOUT 11
#define HISTOLEN 128
/* Clients flags definition */
#define FreeFlag 0x01
#define MaxFlag 0x02
#define TileFlag 0x04
#define HideFlag 0x08
#define LMaxFlag 0x10
#define UnmapFlag 0x20
#define HintFlag 0x40
#define FSSFlag 0x80
#define AboveFlag 0x100
#define UrgentFlag 0x200
#define FLayFlag 0x400
#define DockFlag 0x800
/* Layout flags definition */
#define IntegrationFlag 0x01
#define ArrangeFlag 0x02
/* Tag flags definition */
#define TagUrgentFlag 0x01
#define ResizeHintFlag 0x02
#define RequestUpdateFlag 0x04
#define AboveFCFlag 0x08
#define CleanFactFlag 0x10
#define StayLastFlag 0x20
#define SplitFlag 0x40
#define FirstArrangeFlag 0x80
#define IgnoreEnterFlag 0x100
#define TagFlag(t) (1 << (t))
/* BarWindow flags definition */
#define MappedFlag 0x01
#define StippleFlag 0x02
#define BordFlag 0x04
/* XEMBED messages */
#define XEMBED_MAPPED (1 << 0)
#define XEMBED_EMBEDDED_NOTIFY 0
#define XEMBED_WINDOW_ACTIVATE 1
#define XEMBED_WINDOW_DEACTIVATE 2
#define XEMBED_REQUEST_FOCUS 3
#define XEMBED_FOCUS_IN 4
#define XEMBED_FOCUS_OUT 5
#define XEMBED_FOCUS_NEXT 6
#define XEMBED_FOCUS_PREV 7
/* 8-9 were used for XEMBED_GRAB_KEY/XEMBED_UNGRAB_KEY */
#define XEMBED_MODALITY_ON 10
#define XEMBED_MODALITY_OFF 11
#define XEMBED_REGISTER_ACCELERATOR 12
#define XEMBED_UNREGISTER_ACCELERATOR 13
#define XEMBED_ACTIVATE_ACCELERATOR 14
/* Details for XEMBED_FOCUS_IN: */
#define XEMBED_FOCUS_CURRENT 0
#define XEMBED_FOCUS_FIRST 1
#define XEMBED_FOCUS_LAST 2
/* Typedef */
typedef const char* uicb_t;
typedef unsigned int uint;
typedef unsigned long ulong;
typedef unsigned short ushort;
typedef unsigned char uchar;
/* Enum */
enum { CurNormal, CurResize, CurRightResize, CurLeftResize, CurMove, CurLast };
enum { TagSel, TagTransfert, TagAdd, TagNext, TagPrev, TagActionLast };
/* Menu align */
enum { MA_Center = 0, MA_Left = 1, MA_Right = 2 };
/* Infobar position / elements */
enum { IB_Hide = 0, IB_Bottom = 1, IB_Top = 2 };
typedef enum { Right = 0, Left, Top, Bottom, Center, PositionLast } Position;
typedef enum { ElemTag, ElemLayout, ElemSelbar } IbElemType;
/* Ewmh hints list */
enum
{
net_supported,
net_wm_name,
net_client_list,
net_frame_extents,
net_number_of_desktops,
net_current_desktop,
net_desktop_names,
net_desktop_geometry,
net_active_window,
net_close_window,
net_wm_icon_name,
net_wm_window_type,
net_wm_pid,
net_showing_desktop,
net_supporting_wm_check,
net_wm_window_opacity,
net_wm_window_type_normal,
net_wm_window_type_dock,
net_wm_window_type_splash,
net_wm_window_type_dialog,
net_wm_desktop,
net_wm_icon,
net_wm_state,
net_wm_state_fullscreen,
net_wm_state_sticky,
net_wm_state_demands_attention,
net_wm_system_tray_opcode,
net_system_tray_message_data,
net_system_tray_s,
net_system_tray_visual,
net_system_tray_orientation,
xembed,
xembedinfo,
manager,
utf8_string,
/* WMFS HINTS */
wmfs_running,
wmfs_update_hints,
wmfs_current_tag,
wmfs_current_screen,
wmfs_current_layout,
wmfs_tag_list,
wmfs_mwfact,
wmfs_nmaster,
wmfs_set_screen,
wmfs_screen_count,
wmfs_function,
wmfs_cmd,
wmfs_font,
wmfs_statustext,
net_last
};
/* Geometry structure */
typedef struct
{
int x, y;
int width, height;
} Geo;
/*
* BarWindow Structure
* (titlebar, infobar..)
*/
typedef struct BarWindow
{
Window win;
Drawable dr;
struct
{
/* Border Window */
Window left, right, top, bottom;
/* Border color */
uint dark, light;
} border;
uint bg;
char *fg;
uint stipple_color;
Geo geo;
uint flags;
SLIST_ENTRY(BarWindow) next;
} BarWindow;
/* Client Structure. */
typedef struct Client
{
/* Client title */
char *title;
/* Tag num */
int tag;
int focusontag;
/* Screen */
int screen;
/* Window attribute */
Geo geo, pgeo; /* Window geo, tiling pure geo */
Geo tmp_geo, wrgeo; /* Temporary geo, without resizehint geo */
Geo frame_geo; /* Frame geo */
Geo ogeo; /* Old window attribute */
Geo split_geo, free_geo; /* Split & Free window attribute */
/* Tile size factors */
int tilefact[4];
/* For resizehint usage */
int basew, baseh, incw, inch;
int maxw, maxh, minw, minh;
int minax, maxax, minay, maxay;
/* Client composant {{{ */
Window win;
Window *button;
int button_last_x;
BarWindow *titlebar;
Window frame, resize[2];
/* Border */
Window right, left, top, bottom;
/* }}} */
struct
{
uint frame;
char *fg;
uint resizecorner;
uint bordlight, borddark;
} colors;
/* Client Information by flags */
uint flags;
/* Simply-linked list */
SLIST_ENTRY(Client) next;
} Client;
/* Keybind Structure */
typedef struct
{
uint mod;
KeySym keysym;
void (*func)(uicb_t);
uicb_t cmd;
} Key;
/* Mouse Binding Struct */
typedef struct
{
int tag;
int screen;
uint button;
void (*func)(uicb_t);
uicb_t cmd;
} MouseBinding;
/* InfoBar elements */
typedef struct InfobarElem
{
IbElemType type;
Geo geo;
STAILQ_ENTRY(InfobarElem) next;
} InfobarElem;
/* InfoBar Struct */
typedef struct
{
BarWindow *tags_board, *tags[MAXTAG];
BarWindow *layout_button;
BarWindow *bar;
STAILQ_HEAD(, InfobarElem) elemhead;
char *elemorder;
Geo geo, selbar_geo;
int screen, position;
char *statustext;
bool need_update;
} InfoBar;
/* Layout Structure */
typedef struct
{
uint flags; /* Flags */
Client *nc; /* New client needing integration */
Client ghost; /* Ghost client to arrange hole in split */
char *symbol;
char *type;
void (*func)(int screen);
} Layout;
/* Systray Structure */
typedef struct Systray
{
Window win;
Geo geo;
SLIST_ENTRY(Systray) next;
} Systray;
/* Tag Structure */
typedef struct
{
char *name;
char **clients;
int nclients;
float mwfact;
int nmaster;
uint flags;
int barpos;
int prev_barpos;
Layout layout;
uint tagad;
MouseBinding *mouse;
int nmouse;
} Tag;
/* Menu Item Struct */
typedef struct
{
char *name;
void (*func)(uicb_t);
uicb_t cmd;
bool (*check)(uicb_t);
char *submenu;
} MenuItem;
/* Menu Struct */
typedef struct
{
/* Name of the menu for call
* it in the conf (function = "menu"
* menu = "<name>").
*/
char *name;
/* Placement */
bool place_at_mouse;
int align;
int x, y;
/* Color */
struct
{
struct { uint bg; char *fg; } focus;
struct { uint bg; char *fg; } normal;
} colors;
/* Number of item */
int nitem, focus_item;
/* Item */
MenuItem *item;
} Menu;
/* Launcher struct */
typedef struct
{
char *name;
char *prompt;
char *command;
char histo[HISTOLEN][512];
uint nhisto;
int width;
} Launcher;
/* Button struct */
typedef struct
{
MouseBinding *mouse;
XSegment *linecoord;
int nlines;
int nmouse;
uint flags;
} Button;
/* Alias struct */
typedef struct
{
char *name;
char *content;
} Alias;
/* Rule struct */
typedef struct
{
char *class;
char *instance;
char *role;
char *name;
int screen;
int tag;
bool free;
bool max;
bool ignoretags;
bool follow_client;
} Rule;
/* Configuration structure */
typedef struct
{
/* Configuration file path */
char confpath[512];
/* Misc option */
char *font;
bool use_xft;
uint opacity;
bool raisefocus;
bool focus_fmouse;
bool focus_fmov;
bool focus_pclick;
bool ignore_next_client_rules;
bool tagautohide;
bool tagnamecount;
Tag default_tag;
uint pad;
char *autostart_path;
char *autostart_command;
struct
{
/*
* Only the colors will be use for text
* are 'char*' (for xprint -> XftColorAllocName)
*/
uint bar;
char *text;
char *tagselfg;
char *tagurfg;
uint tagurbg;
uint tagselbg;
uint tag_occupied_bg;
char *tag_occupied_fg;
uint tagbord;
char *layout_fg;
uint layout_bg;
float client_light_shade;
float client_dark_shade;
float bar_light_shade;
float bar_dark_shade;
} colors;
struct
{
int height;
MouseBinding *mouse;
int nmouse;
bool selbar;
char *element_order;
} bars;
struct
{
char *fg;
uint bg;
int maxlength;
MouseBinding *mouse;
int nmouse;
} selbar;
struct
{
char *background_command;
MouseBinding *mouse;
int nmouse;
} root;
struct
{
bool set_new_win_master;
bool place_at_mouse;
bool border_shadow;
bool new_client_get_mouse;
int borderheight;
char *autofree, *automax;
uint bordernormal;
uint borderfocus;
uint resizecorner_normal;
uint resizecorner_focus;
uint mod;
uint padding;
MouseBinding *mouse;
int nmouse;
uint default_open_tag;
int default_open_screen;
} client;
struct
{
int height;
char *fg_normal;
char *fg_focus;
struct
{
bool active;
struct { uint normal, focus; } colors;
} stipple;
MouseBinding *mouse;
int nmouse;
Button *button;
int nbutton;
} titlebar;
struct
{
bool bar;
bool tag;
bool layout;
} border;
struct
{
bool active;
int screen;
int spacing;
} systray;
Alias alias[256];
uint mouse_tag_action[TagActionLast];
int layout_button_width;
Layout layout[NUM_OF_LAYOUT];
Menu *menu;
Launcher *launcher;
Rule *rule;
int *ntag;
bool tag_round;
bool tag_auto_prev;
bool client_round;
bool client_auto_center;
bool client_tile_raise;
bool layout_system; /* Switch: False, Menu: True. */
bool keep_layout_geo;
bool cfactor_enable_split;
char *tag_expose_name;
char *expose_layout;
char *selected_layout_symbol;
/* Number of... */
int nkeybind;
int nlayout;
int nmenu;
int nlauncher;
int nrule;
} Conf;
typedef struct
{
int as, de, width, height;
#ifdef HAVE_XFT
XftFont *font;
#endif /* HAVE_XFT */
XFontSet fontset;
} FontStruct;
/* status.c util struct */
typedef struct
{
Geo g;
uint color;
} StatusRec;
typedef struct
{
int x, y, w, h;
uint color;
char data[512];
} StatusGraph;
typedef struct
{
int x, y;
char color[8];
char text[512];
} StatusText;
typedef struct StatusMouse
{
Geo area;
InfoBar *infobar;
uint button;
void (*func)(uicb_t);
uicb_t cmd;
SLIST_ENTRY(StatusMouse) next;
} StatusMouse;
typedef struct
{
int x, y, w, h;
char name[512];
} ImageAttr;
/* Config.c struct */
typedef struct
{
char *name;
void *func;
} func_name_list_t;
typedef struct
{
char *name;
KeySym keysym;
} key_name_list_t;
typedef struct
{
char *name;
uint button;
} name_to_uint_t;
typedef struct
{
char *cmd;
char *uicb;
} vicmd_to_uicb;
typedef struct
{
int version;
int flags;
} xembed_info;
#endif /* STRUCTS_H */
-229
View File
@@ -1,229 +0,0 @@
/*
* systray.c
* Copyright © 2008, 2009, 2010 Martin Duquesnoy <xorg62@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "wmfs.h"
#define TRAY_DWIDTH (infobar[conf.systray.screen].bar->geo.height + conf.systray.spacing)
bool
systray_acquire(void)
{
XSetWindowAttributes wattr;
if(!conf.systray.active || traywin)
return False;
if(XGetSelectionOwner(dpy, net_atom[net_system_tray_s]) != None)
{
warnx("Can't initialize system tray: owned by another process");
return False;
}
/* Init traywin window */
wattr.event_mask = ButtonPressMask | ExposureMask;
wattr.override_redirect = True;
wattr.background_pixmap = ParentRelative;
wattr.background_pixel = conf.colors.bar;
traywin = XCreateSimpleWindow(dpy, infobar[conf.systray.screen].bar->win, -1, -1, 1, 1, 0, 0, conf.colors.bar);
XChangeWindowAttributes(dpy, traywin, CWEventMask | CWOverrideRedirect | CWBackPixel, &wattr);
XSelectInput(dpy, traywin, KeyPressMask | ButtonPressMask);
XMapRaised(dpy, traywin);
XSetSelectionOwner(dpy, net_atom[net_system_tray_s], traywin, CurrentTime);
if(XGetSelectionOwner(dpy, net_atom[net_system_tray_s]) != traywin)
{
systray_freeicons();
warnx("System tray: can't get systray manager");
return False;
}
ewmh_send_message(ROOT, ROOT, "MANAGER", CurrentTime, net_atom[net_system_tray_s], traywin, 0, 0);
XSync(dpy, False);
return True;
}
void
systray_add(Window win)
{
Systray *s;
if(!conf.systray.active)
return;
s = xcalloc(1, sizeof(Systray));
s->win = win;
s->geo.height = infobar[conf.systray.screen].bar->geo.height;
s->geo.width = TRAY_DWIDTH;
setwinstate(s->win, WithdrawnState);
XSelectInput(dpy, s->win, StructureNotifyMask | PropertyChangeMask| EnterWindowMask | FocusChangeMask);
XReparentWindow(dpy, s->win, traywin, 0, 0);
ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0, traywin, 0);
/* Attach */
SLIST_INSERT_HEAD(&trayicons, s, next);
return;
}
void
systray_del(Systray *s)
{
if(!conf.systray.active)
return;
SLIST_REMOVE(&trayicons, s, Systray, next);
free(s);
return;
}
void
systray_state(Systray *s)
{
long flags;
int code = 0;
if(!(flags = ewmh_get_xembed_state(s->win)) || !conf.systray.active)
return;
if(flags & XEMBED_MAPPED)
{
code = XEMBED_WINDOW_ACTIVATE;
XMapRaised(dpy, s->win);
setwinstate(s->win, NormalState);
}
else
{
code = XEMBED_WINDOW_DEACTIVATE;
XUnmapWindow(dpy, s->win);
setwinstate(s->win, WithdrawnState);
}
ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime, code, 0, 0, 0);
return;
}
void
systray_freeicons(void)
{
Systray *i;
if(!conf.systray.active)
return;
while(!SLIST_EMPTY(&trayicons))
{
i = SLIST_FIRST(&trayicons);
SLIST_REMOVE_HEAD(&trayicons, next);
XUnmapWindow(dpy, i->win);
XReparentWindow(dpy, i->win, ROOT, 0, 0);
free(i);
}
XSetSelectionOwner(dpy, net_atom[net_system_tray_s], None, CurrentTime);
XDestroyWindow(dpy, traywin);
XSync(dpy, 0);
return;
}
Systray*
systray_find(Window win)
{
Systray *i;
if(!conf.systray.active)
return NULL;
SLIST_FOREACH(i, &trayicons, next)
if(i->win == win)
return i;
return NULL;
}
int
systray_get_width(void)
{
int w = 0;
Systray *i;
if(!conf.systray.active)
return 0;
SLIST_FOREACH(i, &trayicons, next)
w += i->geo.width + conf.systray.spacing + 1;
return w;
}
void
systray_update(void)
{
Systray *i;
int x = 1;
if(!conf.systray.active)
return;
if(!SLIST_FIRST(&trayicons))
{
XMoveResizeWindow(dpy, traywin, infobar[conf.systray.screen].bar->geo.width - 1, 0, 1, 1);
return;
}
SLIST_FOREACH(i, &trayicons, next)
{
XMapWindow(dpy, i->win);
XMoveResizeWindow(dpy, i->win, (i->geo.x = x), 0, i->geo.width, i->geo.height);
x += i->geo.width + conf.systray.spacing;
}
XMoveResizeWindow(dpy, traywin, infobar[conf.systray.screen].bar->geo.width - x,
0, x, infobar[conf.systray.screen].bar->geo.height);
return;
}
-781
View File
@@ -1,781 +0,0 @@
/*
* tag.c
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "wmfs.h"
/* Set the tag
* \param tag The tag number
*/
void
tag_set(int tag)
{
Client *c;
bool al = False;
int i;
if(tag < 0 || tag > MAXTAG)
return;
screen_get_sel();
if(seltag[selscreen] != tag)
prevseltag[selscreen] = seltag[selscreen];
else if(tag == seltag[selscreen] && tag != prevseltag[selscreen] && conf.tag_auto_prev)
tag = seltag[selscreen] = prevseltag[selscreen];
else
seltag[selscreen] = tag;
if(conf.tag_round)
{
if(tag <= 0)
seltag[selscreen] = conf.ntag[selscreen];
else if(tag > conf.ntag[selscreen])
seltag[selscreen] = 1;
else
seltag[selscreen] = tag;
}
else
{
if(!tag || tag > conf.ntag[selscreen])
return;
seltag[selscreen] = tag;
}
ewmh_update_current_tag_prop();
/* Arrange infobar position */
if(tags[selscreen][prevseltag[selscreen]].barpos != tags[selscreen][seltag[selscreen]].barpos
|| prevseltag[selscreen] == seltag[selscreen])
infobar_set_position(tags[selscreen][seltag[selscreen]].barpos);
/* Check if a layout update is needed with additional tags */
if(tags[selscreen][seltag[selscreen]].tagad)
al = True;
else if(tags[selscreen][seltag[selscreen]].flags & RequestUpdateFlag)
{
al = True;
tags[selscreen][seltag[selscreen]].flags &= ~RequestUpdateFlag;
}
for(i = 1; i < conf.ntag[selscreen] + 1; ++i)
if(tags[selscreen][i].tagad & TagFlag(seltag[selscreen]))
{
al = True;
break;
}
/* Check for ignore_tag clients */
SLIST_FOREACH(c, &clients, next)
if(c->tag == MAXTAG + 1 && c->screen == selscreen)
{
al = True;
break;
}
/* To focus selected client of the via focusontag option */
SLIST_FOREACH(c, &clients, next)
if(c->focusontag == tag && c->screen == selscreen)
break;
arrange(selscreen, al);
if(tags[selscreen][tag].flags & RequestUpdateFlag)
{
layout_func(selscreen, tag);
tags[selscreen][tag].flags &= ~RequestUpdateFlag;
}
/* No focusontag option found on any client, try to find the first of the tag */
if(!c)
SLIST_FOREACH(c, &clients, next)
if(c->tag == seltag[selscreen] && c->screen == selscreen)
break;
client_focus((c) ? c : NULL);
return;
}
/* Transfert a client to a tag
* \param c Client pointer
* \param tag Tag
*/
void
tag_transfert(Client *c, int tag)
{
int s;
CHECK(c);
screen_get_sel();
if(tag <= 0)
tag = 1;
if(tag > conf.ntag[selscreen]
|| (c->tag == tag && c->screen == selscreen))
return;
s = c->screen;
tags[c->screen][c->tag].flags |= CleanFactFlag;
cfactor_clean(c);
/* Case of tag in split mode */
if(tags[c->screen][c->tag].flags & SplitFlag)
split_arrange_closed(c);
if(tags[selscreen][tag].flags & SplitFlag)
split_client_integrate(c, NULL, selscreen, tag);
/* Set new location */
c->tag = tag;
c->screen = selscreen;
if(s != c->screen)
arrange(s, True);
arrange(c->screen, True);
client_focus_next(c);
client_update_attributes(c);
tags[c->screen][tag].flags |= RequestUpdateFlag;
return;
}
/** Uicb Set a tag
* \param cmd Tag number or '+' / '-', uicb_t type
*/
void
uicb_tag(uicb_t cmd)
{
int tmp = atoi(cmd);
if(cmd[0] == '+' || cmd[0] == '-')
tag_set(seltag[selscreen] + tmp);
else
tag_set(tmp);
return;
}
/** Set the next tag
* \param cmd uicb_t type unused
*/
void
uicb_tag_next(uicb_t cmd)
{
(void)cmd;
screen_get_sel();
tag_set(seltag[selscreen] + 1);
return;
}
/** Set the previous tag
* \param cmd uicb_t type unused
*/
void
uicb_tag_prev(uicb_t cmd)
{
(void)cmd;
screen_get_sel();
tag_set(seltag[selscreen] - 1);
return;
}
/** Set the next visible tag
* \param cmd uicb_t type unused
*/
void
uicb_tag_next_visible(uicb_t cmd)
{
int tag;
Client *c;
uint occupied = 0;
(void)cmd;
screen_get_sel();
if(!conf.tagautohide)
{
tag_set(seltag[selscreen] + 1);
return;
}
SLIST_FOREACH(c, &clients, next)
if(c->screen == selscreen)
occupied |= TagFlag(c->tag);
for(tag = seltag[selscreen] + 1; tag < conf.ntag[selscreen] + 1; ++tag)
if(occupied & TagFlag(tag))
{
tag_set(tag);
return;
}
if(conf.tag_round)
for(tag = 0; tag < seltag[selscreen]; ++tag)
if(occupied & TagFlag(tag))
{
tag_set(tag);
return;
}
return;
}
/** Set the prev visible tag
* \param cmd uicb_t type unused
*/
void
uicb_tag_prev_visible(uicb_t cmd)
{
int tag;
Client *c;
uint occupied = 0;
(void)cmd;
screen_get_sel();
if(!conf.tagautohide)
{
tag_set(seltag[selscreen] - 1);
return;
}
SLIST_FOREACH(c, &clients, next)
if(c->screen == selscreen)
occupied |= TagFlag(c->tag);
for(tag = seltag[selscreen] - 1; tag >= 0; --tag)
if(occupied & TagFlag(tag))
{
tag_set(tag);
return;
}
if(conf.tag_round)
for(tag = conf.ntag[selscreen]; tag > seltag[selscreen]; --tag)
if(occupied & TagFlag(tag))
{
tag_set(tag);
return;
}
return;
}
/** Go to the last tag
*\param cmd uicb_t type unused
*/
void
uicb_tag_last(uicb_t cmd)
{
(void)cmd;
screen_get_sel();
tag_set(conf.ntag[selscreen]);
return;
}
/**
*\param selscreen int
*/
static void
remove_old_last_tag(int selscreen)
{
int i;
for(i = 0; i <= conf.ntag[selscreen]; i++)
{
if(tags[selscreen][i].flags & StayLastFlag)
{
tags[selscreen][i].flags &= ~StayLastFlag;
break;
}
}
return;
}
/** Swap 2 tags
*\param s Screen
*\param t1 Tag 1
*\param t2 Tag 2
*/
static void
tag_swap(int s, int t1, int t2)
{
Client *c;
Tag t;
if(t1 == t2 || (t1 & t2) < 1 || (t1 | t2) > conf.ntag[s])
return;
t = tags[s][t1];
tags[s][t1] = tags[s][t2];
tags[s][t2] = t;
SLIST_FOREACH(c, &clients, next)
{
if(c->screen == s && c->tag == t1)
c->tag = t2;
else if(c->screen == s && c->tag == t2)
c->tag = t1;
}
infobar_update_taglist(&infobar[s]);
tag_set(t2);
return;
}
/** Keep that tag the last one
*\param cmd uicb_t type unused
*/
void
uicb_tag_stay_last(uicb_t cmd)
{
int i;
(void)cmd;
screen_get_sel();
if(tags[selscreen][seltag[selscreen]].flags & StayLastFlag)
tags[selscreen][seltag[selscreen]].flags &= ~StayLastFlag;
else
{
remove_old_last_tag(selscreen);
for(i = seltag[selscreen]; i <= conf.ntag[selscreen]; i++)
tag_swap(selscreen, seltag[selscreen], seltag[selscreen] + 1);
tag_set(conf.ntag[selscreen]);
tags[selscreen][seltag[selscreen]].flags |= StayLastFlag;
arrange(selscreen, True);
}
return;
}
/** Transfert the selected client to
* the wanted tag
* \param cmd Wanted tag, uicb_t type
*/
void
uicb_tagtransfert(uicb_t cmd)
{
CHECK(sel);
tag_transfert(sel, atoi(cmd));
return;
}
/** Set the previous selected tag
* \param cmd uicb_t type unused
*/
void
uicb_tag_prev_sel(uicb_t cmd)
{
(void)cmd;
screen_get_sel();
tag_set(prevseltag[selscreen]);
return;
}
/** Transfert the selected client to the next tag
* \param cmd uicb_t type unused
*/
void
uicb_tagtransfert_next(uicb_t cmd)
{
CHECK(sel);
int tag = seltag[selscreen] + 1;
(void)cmd;
if(tag > conf.ntag[selscreen])
{
if(!conf.tag_round)
return;
tag = 1;
}
tag_transfert(sel, tag);
return;
}
/** Transfert the selected client to the prev tag
* \param cmd uicb_t type unused
*/
void
uicb_tagtransfert_prev(uicb_t cmd)
{
CHECK(sel);
int tag = seltag[selscreen] - 1;
(void)cmd;
if(tag <= 0)
{
if(!conf.tag_round)
return;
tag = conf.ntag[selscreen];
}
tag_transfert(sel, tag);
return;
}
/** Go to the current urgent tag
*\param cmd uicb_t type unused
*/
void
uicb_tag_urgent(uicb_t cmd)
{
Client *c;
(void)cmd;
/* Check if there is a urgent client */
SLIST_FOREACH(c, &clients, next)
if(c->flags & UrgentFlag)
{
screen_set_sel(c->screen);
tag_set(c->tag);
client_focus(c);
break;
}
return;
}
/** Add an additional tag to the current tag
*\param sc Screen
*\param tag Tag where apply additional tag
*\param adtag Additional tag to apply in tag
*/
void
tag_additional(int sc, int tag, int adtag)
{
if(tag < 0 || (tag | adtag) > conf.ntag[sc] + 1
|| adtag < 1 || adtag == seltag[sc])
return;
tags[sc][tag].flags &= ~SplitFlag;
tags[sc][tag].tagad ^= TagFlag(adtag);
tags[sc][adtag].flags |= RequestUpdateFlag;
tags[sc][tag].flags |= CleanFactFlag;
tags[sc][adtag].flags |= CleanFactFlag;
tags[sc][adtag].flags &= ~SplitFlag;
arrange(sc, True);
return;
}
/** Add an additional tag to the current tag
*\param cmd uicb_t
*/
void
uicb_tag_toggle_additional(uicb_t cmd)
{
screen_get_sel();
tag_additional(selscreen, seltag[selscreen], atoi(cmd));
return;
}
/** Swap current tag with a specified tag
*\param cmd uicb_t type
*/
void
uicb_tag_swap(uicb_t cmd)
{
screen_get_sel();
tag_swap(selscreen, seltag[selscreen], atoi(cmd));
return;
}
/** Swap current tag with next tag
*\param cmd uicb_t type
*/
void
uicb_tag_swap_next(uicb_t cmd)
{
(void)cmd;
screen_get_sel();
/* Check if the next one does have the stay_last bool */
if(!(tags[selscreen][conf.ntag[selscreen]].flags & StayLastFlag))
tag_swap(selscreen, seltag[selscreen], seltag[selscreen] + 1);
else
warnx("The next tag is set to always stay the last one");
return;
}
/** Swap current tag with previous tag
*\param cmd uicb_t type
*/
void
uicb_tag_swap_previous(uicb_t cmd)
{
(void)cmd;
screen_get_sel();
tag_swap(selscreen, seltag[selscreen], seltag[selscreen] - 1);
return;
}
/** Adding a tag
*\param s Screen number
*\param name New tag name
*/
static void
tag_new(int s, char *name)
{
char * displayedName;
int goToTag;
if(conf.ntag[s] + 1 > MAXTAG)
{
warnx("Too many tag: Can't create new tag");
return;
}
++conf.ntag[s];
/* TODO: memleak here */
if(!name || strlen(name) == 0)
{
if(conf.tagnamecount)
{
/* displayedName = zmalloc(2); */
xasprintf(&displayedName, "[%d]", conf.ntag[s]);
}
else
displayedName = conf.default_tag.name;
}
else
displayedName = xstrdup(name);
Tag t = { displayedName, NULL, 0,
conf.default_tag.mwfact, conf.default_tag.nmaster, conf.default_tag.flags,
conf.default_tag.barpos, conf.default_tag.barpos,
conf.default_tag.layout, 0, NULL, 0 };
tags[s][conf.ntag[s]] = t;
/* For stay_last_tag */
if(tags[s][conf.ntag[s] - 1].flags & StayLastFlag)
{
tag_swap(s, conf.ntag[s], conf.ntag[s] - 1);
goToTag = conf.ntag[s] - 1;
}
else
goToTag = conf.ntag[s];
infobar_update_taglist(&infobar[s]);
infobar_draw(&infobar[s]);
tag_set(goToTag);
return;
}
/** Adding a tag
*\param cmd uicb_t type
*/
void
uicb_tag_new(uicb_t cmd)
{
screen_get_sel();
tag_new(selscreen, (char*)cmd);
return;
}
/** Delete a tag
*\param s Screen number
*\param tag Tag number
*/
static void
tag_delete(int s, int tag)
{
Tag t;
Client *c;
int i;
memset(&t, 0, sizeof(t));
if(tag < 0 || tag > conf.ntag[s] || conf.ntag[s] == 1)
return;
SLIST_FOREACH(c, &clients, next)
if(c->screen == s && c->tag ==tag)
{
warnx("Client(s) present in this tag, can't delete it");
return;
}
--conf.ntag[s];
tags[s][tag] = t;
infobar[s].tags[tag] = NULL;
for(i = tag; i < conf.ntag[s] + 1; ++i)
{
/* Set clients tag because of shift */
SLIST_FOREACH(c, &clients, next)
if(c->screen == s && c->tag == i + 1)
c->tag = i;
/* shift */
tags[s][i] = tags[s][i + 1];
}
infobar[s].need_update = True;
infobar_update_taglist(&infobar[s]);
infobar_draw(&infobar[s]);
if(tag == seltag[s])
tag_set(tag <= conf.ntag[s] ? tag : conf.ntag[s]);
return;
}
/** Delete a tag
*\param cmd uicb_t type
*/
void
uicb_tag_del(uicb_t cmd)
{
int n;
screen_get_sel();
if(cmd == NULL || !(n = atoi(cmd)))
n = seltag[selscreen];
tag_delete(selscreen, n);
return;
}
/** Rename the selected tag
*\param cmd uicb_t type
*/
void
uicb_tag_rename(uicb_t cmd)
{
screen_get_sel();
char *str;
size_t len;
if(!cmd || !strlen(cmd))
return;
str = tags[selscreen][seltag[selscreen]].name;
len = strlen(str);
/* TODO: if strlen(cmd) > len, the tag name
* will be truncated...
* We can't do a realloc because if the pointer change
* free() on paser will segfault.on free_conf()...
*/
strncpy(str, cmd, len);
infobar_update_taglist(&infobar[selscreen]);
infobar_draw(&infobar[selscreen]);
return;
}
void
uicb_tag_toggle_expose(uicb_t cmd)
{
(void)cmd;
int i, j;
screen_get_sel();
for(i = 1; i <= conf.ntag[selscreen]; i++)
{
if(strcmp(tags[selscreen][i].name, conf.tag_expose_name) == 0)
{
if(SLIST_FIRST(&clients) && sel->tag)
tag_set(sel->tag);
tag_delete(selscreen, i);
for(j = 0; j < conf.ntag[selscreen]; j++)
tags[selscreen][j].flags |= RequestUpdateFlag;
arrange(selscreen, True);
return;
}
}
tag_new(selscreen, conf.tag_expose_name);
for(i = 0; i < conf.nlayout; ++i)
if(strcmp(conf.expose_layout, conf.layout[i].type) == 0)
tags[selscreen][conf.ntag[selscreen]].layout = conf.layout[i];
for(i = 1; i < conf.ntag[selscreen]; ++i)
tags[selscreen][conf.ntag[selscreen]].tagad ^= TagFlag(i);
tags[selscreen][conf.ntag[selscreen]].flags |= RequestUpdateFlag;
arrange(selscreen, True);
return;
}
-304
View File
@@ -1,304 +0,0 @@
/*
* util.c
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define _GNU_SOURCE
#include "wmfs.h"
/** malloc with error support and size_t overflow protection
* \param nmemb number of objects
* \param size size of single object
* \return non null void pointer
*/
void *
xmalloc(size_t nmemb, size_t size)
{
void *ret;
if (SIZE_MAX / nmemb < size)
err(EXIT_FAILURE, "xmalloc(%zu, %zu), "
"size_t overflow detected", nmemb, size);
if ((ret = malloc(nmemb * size)) == NULL)
err(EXIT_FAILURE, "malloc(%zu)", nmemb * size);
return ret;
}
/** calloc with error support
* \param nmemb Number of objects
* \param size size of single object
* \return non null void pointer
*/
void *
xcalloc(size_t nmemb, size_t size)
{
void *ret;
if ((ret = calloc(nmemb, size)) == NULL)
err(EXIT_FAILURE, "calloc(%zu * %zu)", nmemb, size);
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;
}
/** strdup with error support
* \param str char pointer
* \retun non null void pointer
*/
char *
xstrdup(const char *str)
{
char *ret;
if (str == NULL || (ret = strdup(str)) == NULL)
err(EXIT_FAILURE, "strdup(%s)", str);
return ret;
}
/** asprintf wrapper
* \param strp target string
* \param fmt format
* \return non zero integer
*/
int
xasprintf(char **strp, const char *fmt, ...)
{
int ret;
va_list args;
va_start(args, fmt);
ret = vasprintf(strp, fmt, args);
va_end(args);
if (ret == -1)
err(EXIT_FAILURE, "asprintf(%s)", fmt);
return ret;
}
/** Get a color with a string
* \param color Color string
* \return Color pixel
*/
long
getcolor(char *color)
{
XColor xcolor;
if(!XAllocNamedColor(dpy, DefaultColormap(dpy, SCREEN), color, &xcolor, &xcolor))
warnx("Error: cannot allocate color \"%s\".", color);
return xcolor.pixel;
}
/** Set the window WM State
* \param win Window target
* \param state WM State
*/
void
setwinstate(Window win, long state)
{
long data[] = {state, None};
XChangeProperty(dpy, win, ATOM("WM_STATE"), ATOM("WM_STATE"), 32,
PropModeReplace, (uchar *)data, 2);
return;
}
/* The following function are for configuration
usage. {{{
*/
void*
name_to_func(char *name, const func_name_list_t *l)
{
int i;
if(name)
for(i = 0; l[i].name; ++i)
if(!strcmp(name, l[i].name))
return l[i].func;
return NULL;
}
ulong
char_to_modkey(char *name, key_name_list_t key_l[])
{
int i;
if(name)
for(i = 0; key_l[i].name; ++i)
if(!strcmp(name, key_l[i].name))
return key_l[i].keysym;
return NoSymbol;
}
uint
char_to_button(char *name, name_to_uint_t blist[])
{
int i;
if(name)
for(i = 0; blist[i].name; ++i)
if(!strcmp(name, blist[i].name))
return blist[i].button;
return 0;
}
Layout
layout_name_to_struct(Layout lt[], char *name, int n, const func_name_list_t llist[])
{
int i;
for(i = 0; i < n; ++i)
if(lt[i].func == name_to_func(name, llist))
return lt[i];
return lt[0];
}
/* }}} */
/** Execute a sh command
* \param cmd Command
* \return child pid
*/
pid_t
spawn(const char *format, ...)
{
char *sh = NULL;
char cmd[512];
va_list ap;
pid_t pid;
size_t len;
va_start(ap, format);
len = vsnprintf(cmd, sizeof(cmd), format, ap);
va_end(ap);
if (len >= sizeof(cmd))
{
warnx("command too long (> 512 bytes)");
return -1;
}
if(!(sh = getenv("SHELL")))
sh = "/bin/sh";
if((pid = fork()) == 0)
{
if(dpy)
close(ConnectionNumber(dpy));
setsid();
if (execl(sh, sh, "-c", cmd, (char*)NULL) == -1)
warn("execl(sh -c %s)", cmd);
exit(EXIT_FAILURE);
}
else if (pid == -1)
warn("fork");
return pid;
}
/** Swap two pointer.
*\param x First pointer
*\param y Second pointer
*/
void
swap_ptr(void **x, void **y)
{
void *t = *x;
*x = *y;
*y = t;
return;
}
/** Execute a sh command
* \param cmd Command (uicb_t type)
*/
void
uicb_spawn(uicb_t cmd)
{
spawn("%s", cmd);
return;
}
/* To use ~/ shortcut.. */
char*
patht(char *path)
{
static char ret[512];
if(!path)
return NULL;
strncpy(ret, path, sizeof(ret));
ret[sizeof(ret) - 1] = 0;
if(strstr(path, "~/"))
snprintf(ret, sizeof(ret), "%s/%s", getenv("HOME"), path + 2);
return ret;
}
int
qsort_string_compare (const void * a, const void * b)
{
return (strcmp(*(char **)a, *(char **)b));
}
-481
View File
@@ -1,481 +0,0 @@
/*
* wmfs.c
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "wmfs.h"
static volatile bool exiting = False, sig_chld = False;
int
errorhandler(Display *d, XErrorEvent *event)
{
char mess[256];
/* Check if there is another WM running */
if(BadAccess == event->error_code
&& ROOT == event->resourceid)
errx(EXIT_FAILURE, "Another Window Manager is already running.");
/* Ignore focus change error for unmapped client */
/* Too lazy to add Xproto.h so:
* 42 = X_SetInputFocus
* 28 = X_GrabButton
*/
if(client_gb_win(event->resourceid))
if(event->error_code == BadWindow
|| event->request_code == 42
|| event->request_code == 28)
return 0;
XGetErrorText(d, event->error_code, mess, 128);
warnx("%s(%d) opcodes %d/%d\n resource #%lx\n", mess,
event->error_code,
event->request_code,
event->minor_code,
event->resourceid);
return 1;
}
int
errorhandlerdummy(Display *d, XErrorEvent *event)
{
(void)d;
(void)event;
return 0;
}
/** Clean wmfs before the exit
*/
void
quit(void)
{
size_t i, len;
/* Set the silent error handler */
XSetErrorHandler(errorhandlerdummy);
/* Unmanage all clients */
while(!SLIST_EMPTY(&clients))
{
Client *c = SLIST_FIRST(&clients);
client_unhide(c);
XReparentWindow(dpy, c->win, ROOT, c->geo.x, c->geo.y);
free(c);
SLIST_REMOVE_HEAD(&clients, next);
}
free(tags);
free(seltag);
systray_freeicons();
#ifdef HAVE_XFT
if(conf.use_xft)
XftFontClose(dpy, font.font);
else
#endif /* HAVE_XFT */
XFreeFontSet(dpy, font.fontset);
for(i = 0; i < CurLast; ++i)
XFreeCursor(dpy, cursor[i]);
XFreeGC(dpy, gc_stipple);
infobar_destroy();
/* BarWindows */
while(!SLIST_EMPTY(&bwhead))
SLIST_REMOVE_HEAD(&bwhead, next);
free(sgeo);
free(spgeo);
free(infobar);
free(keys);
free(net_atom);
/* Clean conf alloced thing */
free(menulayout.item);
if(conf.menu)
{
len = LEN(conf.menu);
for(i = 0; i < len; ++i)
free(conf.menu[i].item);
free(conf.menu);
}
free(conf.launcher);
free(conf.rule);
free(conf.bars.mouse);
free(conf.selbar.mouse);
free(conf.titlebar.button);
free(conf.client.mouse);
free(conf.root.mouse);
free_conf();
XSync(dpy, False);
XCloseDisplay(dpy);
free(event_handle);
return;
}
/** WMFS main loop.
*/
static void
mainloop(void)
{
XEvent ev;
while(!exiting && !XNextEvent(dpy, &ev)) {
if (sig_chld) {
while(waitpid(-1, NULL, WNOHANG) > 0);
sig_chld = False;
}
HANDLE_EVENT(&ev);
}
return;
}
/** Set the exiting variable to True
* for stop the main loop
* \param cmd unused uicb_t
*/
void
uicb_quit(uicb_t cmd)
{
(void)cmd;
exiting = True;
return;
}
/** Scan if there are windows on X
* for manage it
*/
static void
scan(void)
{
uint n;
XWindowAttributes wa;
Window usl, usl2, *w = NULL;
Atom rt;
int s, rf, tag = -1, screen = -1, flags = -1, i;
ulong ir, il;
uchar *ret;
Client *c;
s = screen_count();
if(XQueryTree(dpy, ROOT, &usl, &usl2, &w, &n))
for(i = n - 1; i != -1; --i)
{
XGetWindowAttributes(dpy, w[i], &wa);
if(!wa.override_redirect && wa.map_state == IsViewable)
{
if(XGetWindowProperty(dpy, w[i], ATOM("_WMFS_TAG"), 0, 32,
False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret) == Success && ret)
{
tag = *ret;
XFree(ret);
}
if(XGetWindowProperty(dpy, w[i], ATOM("_WMFS_SCREEN"), 0, 32,
False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret) == Success && ret)
{
screen = *ret;
XFree(ret);
}
if(XGetWindowProperty(dpy, w[i], ATOM("_WMFS_FLAGS"), 0, 32,
False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret) == Success && ret)
{
flags = *ret;
XFree(ret);
}
c = client_manage(w[i], &wa, False);
if(tag != -1 && tag != MAXTAG + 1)
c->tag = tag;
if(screen != -1 && screen <= s - 1)
c->screen = screen;
if(flags != -1)
c->flags = flags;
client_update_attributes(c);
}
}
/* Set update layout request */
SLIST_FOREACH(c, &clients, next)
{
if(c->tag > conf.ntag[c->screen])
c->tag = conf.ntag[c->screen];
tags[c->screen][c->tag].flags |= RequestUpdateFlag;
}
for(i = 0; i < s; ++i)
arrange(i, True);
XFree(w);
return;
}
/** Reload the WMFS with the new configuration
* file changement *TESTING*
*/
void
uicb_reload(uicb_t cmd)
{
(void)cmd;
quit();
for(; argv_global[0] && argv_global[0] == ' '; ++argv_global);
/* add -C to always load the same config file */
execvp(argv_global, all_argv);
return;
}
/** Check if wmfs is running (for functions that will be
execute when wmfs will be already running).
\return False if wmfs is not running
*/
bool
check_wmfs_running(void)
{
Atom rt;
int rf;
ulong ir, il;
uchar *ret;
XGetWindowProperty(dpy, ROOT, ATOM("_WMFS_RUNNING"), 0L, 4096,
False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret);
if(!ret)
{
XFree(ret);
warnx("Wmfs is not running. (_WMFS_RUNNING not present)");
return False;
}
XFree(ret);
return True;
}
/** Execute an uicb function
*\param func Function name
*\param cmd Function's command
*\return 0 if there is an error
*/
void
exec_uicb_function(char *func, char *cmd)
{
/* Check if wmfs is running (this function is executed when wmfs
is already running normally...) */
if(!check_wmfs_running())
return;
XChangeProperty(dpy, ROOT, ATOM("_WMFS_FUNCTION"), ATOM("UTF8_STRING"),
8, PropModeReplace, (uchar*)func, strlen(func));
if(cmd == NULL)
cmd = "";
XChangeProperty(dpy, ROOT, ATOM("_WMFS_CMD"), ATOM("UTF8_STRING"),
8, PropModeReplace, (uchar*)cmd, strlen(cmd));
ewmh_send_message(ROOT, ROOT, "_WMFS_FUNCTION", 0, 0, 0, 0, True);
return;
}
/** Set statustext
*\param str Statustext string
*/
static void
set_statustext(int s, char *str)
{
int i;
char atom_name[64];
if(!str)
return;
if(s == -1)
{
for(i = 0; i < screen_count(); ++i)
{
sprintf(atom_name, "_WMFS_STATUSTEXT_%d", i);
XChangeProperty(dpy, ROOT, ATOM(atom_name), ATOM("UTF8_STRING"),
8, PropModeReplace, (uchar*)str, strlen(str));
ewmh_send_message(ROOT, ROOT, atom_name, 0, 0, 0, 0, True);
}
}
else
{
sprintf(atom_name, "_WMFS_STATUSTEXT_%d", s);
XChangeProperty(dpy, ROOT, ATOM(atom_name), ATOM("UTF8_STRING"),
8, PropModeReplace, (uchar*)str, strlen(str));
ewmh_send_message(ROOT, ROOT, atom_name, 0, 0, 0, 0, True);
}
return;
}
/** Signal handle function
*/
static void
signal_handle(int sig)
{
switch (sig)
{
case SIGQUIT:
case SIGTERM:
exiting = True;
break;
case SIGCHLD:
sig_chld = True;
break;
}
return;
}
/** main function
* \param argc ?
* \param argv ?
* \return 0
*/
int
main(int argc, char **argv)
{
int i;
char *ol = "cs";
extern char *optarg;
extern int optind;
struct sigaction sa;
argv_global = xstrdup(argv[0]);
all_argv = argv;
sprintf(conf.confpath, "%s/"DEF_CONF, getenv("HOME"));
while((i = getopt(argc, argv, "hvic:s:C:")) != -1)
{
/* For options who need WMFS running */
if(strchr(ol, i) && !(dpy = XOpenDisplay(NULL)))
errx(EXIT_FAILURE, "cannot open X server.");
switch(i)
{
case 'h':
default:
printf("usage: %s [-ihv] [-C <file>] [-c <uicb function> <cmd> ] [-g <argument>] [-s <screen_num> <string>]\n"
" -C <file> Load a configuration file\n"
" -c <uicb_function> <cmd> Execute an uicb function to control WMFS\n"
" -s <screen_num> <string> Set the bar(s) statustext\n"
" -h Show this page\n"
" -i Show informations\n"
" -v Show WMFS version\n", argv[0]);
exit(EXIT_SUCCESS);
break;
case 'i':
printf("WMFS - Window Manager From Scratch By Martin Duquesnoy\n");
exit(EXIT_SUCCESS);
break;
case 'v':
printf("wmfs"WMFS_VERSION"\n");
exit(EXIT_SUCCESS);
break;
case 'C':
strncpy(conf.confpath, optarg, sizeof(conf.confpath));
break;
case 'c':
exec_uicb_function(optarg, argv[optind]);
XCloseDisplay(dpy);
exit(EXIT_SUCCESS);
break;
case 's':
if(argc > 3)
set_statustext(atoi(optarg), argv[3]);
else
set_statustext(-1, optarg);
XCloseDisplay(dpy);
exit(EXIT_SUCCESS);
break;
}
}
/* Check if WMFS can open X server */
if(!(dpy = XOpenDisplay(NULL)))
errx(EXIT_FAILURE, "cannot open X server.");
/* 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);
/* Check if an other WM is already running; set the error handler */
XSetErrorHandler(errorhandler);
/* Let's Go ! */
init();
scan();
mainloop();
quit();
return 0;
}
-511
View File
@@ -1,511 +0,0 @@
/*
* wmfs.h
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef WMFS_H
#define WMFS_H
/* Lib headers */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <signal.h>
#include <unistd.h>
#include <ctype.h>
#include <fcntl.h>
#include <time.h>
#include <getopt.h>
#include <dirent.h>
#include <err.h>
#include <pthread.h>
#include <locale.h>
#include <sys/queue.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
/* Optional dependencies */
#ifdef HAVE_XFT
#include <X11/Xft/Xft.h>
#endif /* HAVE_XFT */
#ifdef HAVE_XINERAMA
#include <X11/extensions/Xinerama.h>
#endif /* HAVE_XINERAMA */
#ifdef HAVE_XRANDR
#include <X11/extensions/Xrandr.h>
#endif /* HAVE_XRANDR */
#ifdef HAVE_IMLIB
#include <Imlib2.h>
#endif /* HAVE_IMLIB */
/* Local headers */
#include "parse.h"
#include "structs.h"
/* MACRO */
#define ButtonMask (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask)
#define MouseMask (ButtonMask | PointerMotionMask)
#define KeyMask (KeyPressMask | KeyReleaseMask)
#define SCREEN DefaultScreen(dpy)
#define ROOT RootWindow(dpy, SCREEN)
#define MAXH DisplayHeight(dpy, DefaultScreen(dpy))
#define MAXW DisplayWidth(dpy, DefaultScreen(dpy))
#define INFOBARH ((conf.bars.height > 0) ? conf.bars.height : (font.height * 1.5))
#define FHINFOBAR ((font.height - font.de) + (((int)INFOBARH - font.height) >> 1))
#define SHADH (1)
#define BORDH conf.client.borderheight
#define TBARH ((conf.titlebar.height < BORDH) ? BORDH : conf.titlebar.height)
#define RESHW (6 * (BORDH))
#define BUTTONWH (TBARH >> 1)
#define DEF_CONF ".config/wmfs/wmfsrc"
#define DEF_STATUS ".config/wmfs/status.sh"
#define PAD conf.pad
#define MAXSTATUS (4096)
#define CWIN(win, parent, x, y, w, h, b, mask, col, at) \
do { \
win = XCreateWindow(dpy, (parent), (x), (y), (w), (h), (b), CopyFromParent, \
InputOutput, CopyFromParent, (mask), (at)); \
XSetWindowBackground(dpy, win, (col)); \
} while(/* CONSTCOND */ 0)
#define HANDLE_EVENT(e) event_handle[(e)->type](e);
#define ATOM(a) XInternAtom(dpy, (a), False)
#define FRAMEW(w) ((w) + (BORDH << 1))
#define FRAMEH(h) ((h) + (BORDH + TBARH))
#define CHECK(x) if(!(x)) return
#define LEN(x) (sizeof(x) / sizeof((x)[0]))
#define MAXCLIST (64)
#define RPOS(x) (x & 1 ? x - 1 : x + 1)
#define LDIR(x) (x < Top)
#define FLAGAPPLY(v, b, f) ((b) ? (v |= (f)) : (v &= ~(f)))
#define INAREA(i, j, a) ((i) >= (a).x && (i) <= (a).x + (a).width && (j) >= (a).y && (j) <= (a).y + (a).height)
/* Cfactor define */
#define CFACTOR_CHECK2(g1, g2, p) (LDIR(p) ? (g1.height == g2.height) : (g1.width == g2.width))
#define CFACTOR_PARENTROW(g1, g2, p) \
(LDIR(p) \
? (p == Left ? (g1.x == g2.x) : (g1.x + g1.width == g2.x + g2.width)) \
: (p == Top ? (g1.y == g2.y) : (g1.y + g1.height == g2.y + g2.height))) \
/* Barwin define, wrappers for simple function */
#define barwin_delete_subwin(bw) XDestroySubwindows(dpy, bw->win)
#define barwin_map_subwin(bw) XMapSubwindows(dpy, bw->win)
#define barwin_unmap_subwin(bw) XUnmapSubwindows(dpy, bw->win)
#define barwin_refresh(bw) XCopyArea(dpy, bw->dr, bw->win, gc, 0, 0, bw->geo.width, bw->geo.height, 0, 0)
#define barwin_map(bw) \
do { \
XMapWindow(dpy, bw->win); \
bw->flags |= MappedFlag; \
} while(/* CONSTCOND */ 0)
#define barwin_unmap(bw) \
do { \
XUnmapWindow(dpy, bw->win); \
bw->flags &= ~MappedFlag; \
} while(/* CONSTCOND */ 0)
/* barwin.c */
BarWindow *barwin_create(Window parent,
int x, int y,
int w, int h,
uint bg, char*fg,
bool entermask,
bool stipple,
bool border);
void barwin_draw_text(BarWindow *bw, int x, int y, char *text);
void barwin_color_set(BarWindow *bw, uint bg, char *fg);
void barwin_delete(BarWindow *bw);
void barwin_move(BarWindow *bw, int x, int y);
void barwin_resize(BarWindow *bw, int w, int h);
void barwin_refresh_color(BarWindow *bw);
/* draw.c */
void draw_text(Drawable d, int x, int y, char* fg, char *str);
void draw_rectangle(Drawable dr, int x, int y, int w, int h, uint color);
void draw_graph(Drawable dr, int x, int y, int w, int h, uint color, char *data);
ushort textw(char *text);
/* infobar.c */
void infobar_init(void);
void infobar_draw_layout(InfoBar *i);
void _infobar_draw(InfoBar *i);
void infobar_draw(InfoBar *i);
void infobar_draw_selbar(InfoBar *i);
void infobar_draw_taglist(InfoBar *i);
void infobar_update_taglist(InfoBar *i);
void infobar_destroy(void);
void infobar_set_position(int pos);
void uicb_infobar_togglepos(uicb_t);
void uicb_infobar_toggledisplay(uicb_t);
void uicb_toggle_tagautohide(uicb_t);
/* cfactor.c */
void cfactor_clean(Client *c);
Geo cfactor_geo(Geo geo, int fact[4], int *err);
void cfactor_set(Client *c, Position p, int fac);
void cfactor_multi_set(Client *c, int fac[4]);
/* Generated with macro {{{ */
void uicb_client_resize_Right(uicb_t cmd);
void uicb_client_resize_Left(uicb_t cmd);
void uicb_client_resize_Top(uicb_t cmd);
void uicb_client_resize_Bottom(uicb_t cmd);
/* }}} */
/* client.c */
void client_attach(Client *c);
void client_configure(Client *c);
void client_detach(Client *c);
void client_focus(Client *c);
Client *client_get_next(void);
Client *client_get_prev(void);
/* client_gb_*() {{{ */
Client* client_gb_win(Window w);
Client* client_gb_frame(Window w);
Client* client_gb_titlebar(Window w);
Client* client_gb_resize(Window w);
Client* client_gb_button(Window w, int *n);
Client* client_gb_pos(Client *c, int x, int y);
/* }}} */
void client_get_name(Client *c);
void client_hide(Client *c);
void client_kill(Client *c);
bool ishide(Client *c, int screen);
void client_map(Client *c);
Client* client_manage(Window w, XWindowAttributes *wa, bool ar);
void client_geo_hints(Geo *geo, Client *c);
void client_moveresize(Client *c, Geo geo, bool r);
void client_maximize(Client *c);
void client_size_hints(Client *c);
void client_swap(Client *c1, Client *c2);
void client_raise(Client *c);
void client_unhide(Client *c);
void client_focus_next(Client *c);
void client_unmanage(Client *c);
void client_unmap(Client *c);
void client_update_attributes(Client *c);
void client_urgent(Client *c, bool u);
Client* client_get_next_with_direction(Client *bc, Position pos);
void uicb_client_raise(uicb_t);
/* Generated with macro {{{ */
void uicb_client_focus_next(uicb_t);
void uicb_client_focus_prev(uicb_t);
void uicb_client_swapsel_next(uicb_t);
void uicb_client_swapsel_prev(uicb_t);
void uicb_client_swapsel_Right(uicb_t);
void uicb_client_swapsel_Left(uicb_t);
void uicb_client_swapsel_Top(uicb_t);
void uicb_client_swapsel_Bottom(uicb_t);
void uicb_client_focus_Right(uicb_t cmd);
void uicb_client_focus_Left(uicb_t cmd);
void uicb_client_focus_Top(uicb_t cmd);
void uicb_client_focus_Bottom(uicb_t cmd);
/* }}} */
void uicb_client_kill(uicb_t);
void uicb_client_screen_next(uicb_t);
void uicb_client_screen_prev(uicb_t);
void uicb_client_screen_set(uicb_t);
void uicb_client_move(uicb_t cmd);
void uicb_client_resize(uicb_t cmd);
void uicb_ignore_next_client_rules(uicb_t cmd);
void uicb_clientlist(uicb_t cmd);
bool uicb_checkclist(uicb_t);
void uicb_client_ignore_tag(uicb_t);
void uicb_client_set_master(uicb_t);
/* ewmh.c */
void ewmh_init_hints(void);
void ewmh_send_message(Window d, Window w, char *atom, long d0, long d1, long d2, long d3, long d4);
long ewmh_get_xembed_state(Window win);
void ewmh_get_number_of_desktop(void);
void ewmh_update_current_tag_prop(void);
void ewmh_get_client_list(void);
void ewmh_get_desktop_names(void);
void ewmh_set_desktop_geometry(void);
void ewmh_manage_net_wm_state(long data_l[], Client *c);
void ewmh_manage_window_type(Client *c);
/* frame.c */
void frame_create(Client *c);
void frame_delete(Client *c);
void frame_moveresize(Client *c, Geo geo);
void frame_update_color(Client *c, bool focused);
void frame_update(Client *c);
/* config.c */
void init_conf(void);
/* color.c */
uint color_shade(uint, double);
/* event.c */
void grabkeys(void);
void event_make_array(void);
#ifdef HAVE_XRANDR
void xrandrevent(XEvent *e);
#endif /* HAVE_XRANDR */
/* menu.c */
void menu_init(Menu *menu, char *name, int nitem, uint bg_f, char *fg_f, uint bg_n, char *fg_n);
void menu_new_item(MenuItem *mi, char *name, void *func, char *cmd);
void menu_draw(Menu menu, int x, int y);
void uicb_menu(uicb_t cmd);
void menu_clear(Menu *menu);
/* launcher.c */
void uicb_launcher(uicb_t);
/* mouse.c */
void mouse_resize(Client *c);
void mouse_grabbuttons(Client *c, bool focused);
void uicb_mouse_move(uicb_t);
void uicb_mouse_resize(uicb_t);
/* util.c */
void *xmalloc(size_t, size_t);
void *xcalloc(size_t, size_t);
void *xrealloc(void *, size_t, size_t);
/* simples wrappers for allocating only one object */
#define zmalloc(size) xmalloc(1, (size))
#define zcalloc(size) xcalloc(1, (size))
#define zrealloc(ptr, size) xrealloc((ptr), 1, (size))
char *xstrdup(const char *);
int xasprintf(char **, const char *, ...);
long getcolor(char *color);
void setwinstate(Window win, long state);
/* Conf usage {{{ */
void* name_to_func(char *name, const func_name_list_t *l);
ulong char_to_modkey(char *name, key_name_list_t key_l[]);
uint char_to_button(char *name, name_to_uint_t blist[]);
Layout layout_name_to_struct(Layout lt[], char *name, int n, const func_name_list_t llist[]);
/* }}} */
char *char_to_str(const char c);
pid_t spawn(const char *str, ...);
void swap_ptr(void **x, void **y);
void uicb_spawn(uicb_t);
char* patht(char *path);
int qsort_string_compare (const void * a, const void * b);
/* tag.c */
void tag_set(int tag);
void tag_transfert(Client *c, int tag);
void uicb_tag(uicb_t);
void uicb_tag_next(uicb_t);
void uicb_tag_prev(uicb_t);
void uicb_tag_next_visible(uicb_t);
void uicb_tag_prev_visible(uicb_t);
void uicb_tagtransfert(uicb_t);
void uicb_tag_prev_sel(uicb_t);
void uicb_tagtransfert_next(uicb_t);
void uicb_tagtransfert_prev(uicb_t);
void uicb_tag_urgent(uicb_t cmd);
void tag_additional(int sc, int tag, int adtag);
void uicb_tag_toggle_additional(uicb_t);
void uicb_tag_swap(uicb_t);
void uicb_tag_swap_next(uicb_t);
void uicb_tag_swap_previous(uicb_t);
void uicb_tag_new(uicb_t);
void uicb_tag_del(uicb_t);
void uicb_tag_rename(uicb_t cmd);
void uicb_tag_last(uicb_t cmd);
void uicb_tag_stay_last(uicb_t cmd);
void uicb_tag_toggle_expose(uicb_t cmd);
/* screen.c */
int screen_count(void);
Geo screen_get_geo(int s);
int screen_get_with_geo(int x, int y);
int screen_get_sel(void);
void screen_set_sel(int screen);
void screen_init_geo(void);
void uicb_screen_select(uicb_t);
void uicb_screen_next(uicb_t);
void uicb_screen_prev(uicb_t);
void uicb_screen_prev_sel(uicb_t);
/* status.c */
void statustext_mouse(char *str, Geo area, InfoBar *infobar);
void statustext_handle(InfoBar *ib);
/* systray.c */
bool systray_acquire(void);
void systray_add(Window win);
void systray_del(Systray *s);
void systray_state(Systray *s);
void systray_freeicons(void);
Systray* systray_find(Window win);
int systray_get_width(void);
void systray_update(void);
/* layout.c */
void arrange(int screen, bool update_layout);
void layout_func(int screen, int tag);
Client *tiled_client(int screen, Client *c);
void freelayout(int screen);
void layoutswitch(bool b);
void maxlayout(int screen);
/* tile {{{ */
void tile(int screen);
void tile_left(int screen);
void tile_top(int screen);
void tile_bottom(int screen);
void mirror_vertical(int screen);
void mirror_horizontal(int screen);
void grid_vertical(int screen);
void grid_horizontal(int screen);
/* }}} */
void uicb_togglemax(uicb_t);
void uicb_togglefree(uicb_t);
void uicb_layout_prev(uicb_t);
void uicb_layout_next(uicb_t);
void uicb_set_mwfact(uicb_t);
void uicb_set_nmaster(uicb_t);
void uicb_set_layout(uicb_t);
void uicb_toggle_resizehint(uicb_t);
void uicb_toggle_abovefc(uicb_t cmd);
void layout_set_client_master(Client *c);
void layout_split_client(Client *c, bool p);
void layout_split_apply(Client *c);
void layout_split_arrange_closed(int screen);
void uicb_split_client_vertical(uicb_t);
void uicb_split_client_horizontal(uicb_t);
bool uicb_checkmax(uicb_t);
bool uicb_checkfree(uicb_t);
bool uicb_checklayout(uicb_t);
/* init.c */
void init(void);
/* split.c */
void split_store_geo(int screen, int tag);
void split_set_current(Client *nc, Client *ghost);
void split_apply_current(int screen, int tag);
void split_arrange_closed(Client *ghost);
Geo split_client(Client *c, bool p);
void split_client_fill(Client *c, Geo geo);
void split_client_integrate(Client *c, Client *sc, int screen, int tag);
void split_move_dir(Client *c, Position p);
void uicb_split_toggle(uicb_t cmd);
/* Generated with macro {{{ */
void uicb_split_move_Right(uicb_t);
void uicb_split_move_Left(uicb_t);
void uicb_split_move_Top(uicb_t);
void uicb_split_move_Bottom(uicb_t);
/* }}} */
/* wmfs.c */
int errorhandler(Display *d, XErrorEvent *event);
int errorhandlerdummy(Display *d, XErrorEvent *event);
void quit(void);
void *thread_process(void *arg);
bool check_wmfs_running(void);
void exec_uicb_function(char *func, char *cmd);
void handle_signal(int signum);
void uicb_quit(uicb_t);
void uicb_reload(uicb_t);
/* Variables */
/* Main */
Display *dpy;
GC gc, gc_stipple;
int selscreen;
int prevselscreen;
Conf conf;
Key *keys;
Geo *sgeo;
Geo *spgeo;
Cursor cursor[CurLast];
char *argv_global;
char **all_argv;
int xrandr_event;
uint timing;
/* Fonts */
FontStruct font;
/* Atoms list */
Atom *net_atom;
Atom trayatom;
/* InfoBar/Tags */
InfoBar *infobar;
Tag **tags;
int *seltag;
int *prevseltag;
Menu menulayout;
/* ClientList */
Menu clientlist;
struct clndx {
char key[4];
Client *client;
} clist_index[MAXCLIST];
/* Client */
SLIST_HEAD(, Client) clients;
Client *sel;
/* Event */
int nevent;
void (**event_handle)(XEvent*);
extern const func_name_list_t func_list[];
extern const func_name_list_t layout_list[];
uint numlockmask;
/* Systray */
SLIST_HEAD(, Systray) trayicons;
Window traywin;
int tray_width;
/* BarWindow */
SLIST_HEAD(, BarWindow) bwhead;
/* Status */
SLIST_HEAD(, StatusMouse) smhead;
#endif /* WMFS_H */
+199
View File
@@ -0,0 +1,199 @@
/* options -----------------------------------------------------------*/
* { padding:0; margin:0; }
a { color: #ccc; text-decoration: none; }
a:hover { color: #aaa; }
pre { color: #ccc; }
/* body --------------------------------------------------------------*/
body {
font: 12px/18px sans-serif;
color: #aaa;
background-color: #0F0F0F;
}
/* container ---------------------------------------------------------*/
#container {
width: 100%;
height: 100%;
margin: 0px auto;
background-color: #A8A8A8;
overflow: hidden;
}
/* header ------------------------------------------------------------*/
#header {
position: fixed;
top: 0px;
z-index: 10;
width: 100%;
padding: 3px 5px 5px 2px;
background-color: #2B2B2B;
}
#header h1 {
font: 30px sans-serif;
text-align: right;
margin-right: 20px;
}
#header h1 span {
margin-right: 40px;
font-size: 13px;
}
#header h2 {
position: absolute;
font: 18px sans-serif;
left: 20px;
top: 10px;
}
/* links -------------------------------------------------------------*/
#links {
display: block;
margin: 60px auto 5px auto;
width: 100%;
}
.categorie {
padding: 0 10px 15px 25px;
margin: 0 auto 10px auto;
position: relative;
width: 90%;
background-color: #525252;
-webkit-box-shadow: 1px 1px 12px #000;
-moz-box-shadow: 1px 1px 12px #000;
box-shadow: 1px 1px 12px #000;
}
.categorie a { text-decoration: underline ; }
.categorie h2 { padding: 15px 0 5px 10px; }
/* iframe for irc ----------------------------------------------------*/
iframe {
opacity: 0.9;
-moz-opacity : 0.9;
-ms-filter: "alpha(opacity=90)";
margin: 15px auto 0 -10px;
-webkit-box-shadow: 1px 1px 12px #000;
-moz-box-shadow: 1px 1px 12px #000;
box-shadow: 1px 1px 12px #000;
}
/* footer ------------------------------------------------------------*/
#footer {
margin: 20px auto 0px auto;
display: block;
width: 100%;
padding: 0px 5px 0px 5px;
background-color: #2B2B2B;
font-size: 10px;
text-align: center;
-webkit-box-shadow: 1px 1px 12px #000;
-moz-box-shadow: 1px 1px 12px #000;
box-shadow: 1px 1px 12px #000;
}
/* cc BY-NC-SA License :: arpinux :: 2011 :: http://arpinux.org */
/* slideshow */
/*
Skin Name: Nivo Slider Default Theme
Skin URI: http://nivo.dev7studios.com
Skin Type: flexible
Description: The default skin for the Nivo Slider.
Version: 1.0
Author: Gilbert Pellegrom
Author URI: http://dev7studios.com
*/
.theme-default .nivoSlider {
position:relative;
background:#444 url(icons/loading.gif) no-repeat 50% 50%;
margin-bottom:20px;
-webkit-box-shadow: 1px 1px 12px #000;
-moz-box-shadow: 1px 1px 12px #000;
box-shadow: 1px 1px 12px #000;
}
.theme-default .nivoSlider img {
position:absolute;
top:0px;
left:0px;
display:none;
}
.theme-default .nivo-controlNav {
position:absolute;
left:5%;
bottom:-42px;
margin-left:-40px; /* Tweak this to center bullets */
}
.theme-default .nivo-directionNav a {
display:block;
width:30px;
height:30px;
background:url(icons/arrows.png) no-repeat;
text-indent:-9999px;
border:0;
}
.theme-default a.nivo-nextNav {
background-position:-30px 0;
right:15px;
}
.theme-default a.nivo-prevNav {
left:15px;
}
table {
border-collapse:separate;
border-spacing:0;
}
.theme-default #slider {
margin: 20px auto 20px auto;
width:800px; /* Make sure your images are the same size */
height:345px; /* Make sure your images are the same size */
}
.clear {
clear:both;
}
/*
* jQuery Nivo Slider v2.7.1
* http://nivo.dev7studios.com
*
* Copyright 2011, Gilbert Pellegrom
* Free to use and abuse under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
*
* March 2010
*/
/* The Nivo Slider styles */
.nivoSlider {
position:relative;
}
.nivoSlider img {
position:absolute;
top:0px;
left:0px;
}
/* The slices and boxes in the Slider */
.nivo-slice {
display:block;
position:absolute;
z-index:5;
height:100%;
}
.nivo-box {
display:block;
position:absolute;
z-index:5;
}
/* Direction nav styles (e.g. Next & Prev) */
.nivo-directionNav a {
position:absolute;
top:45%;
z-index:9;
cursor:pointer;
}
.nivo-prevNav {
left:0px;
}
.nivo-nextNav {
right:0px;
}
-203
View File
@@ -1,203 +0,0 @@
.\" Title: wmfs
.\" Author:
.\" Generator: DocBook XSL Stylesheets v1.73.2 <http://docbook.sf.net/>
.\" Date: 04/22/2009
.\" Manual: manual of wmfs
.\" Source: wmfs 0.1rc4 (On The Run)
.\"
.TH "WMFS" "1" "04/22/2009" "wmfs 0\&.1rc4 (On The Run)" "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\-ihvS\fR] [\fB\-C <file>\fR] [\fB\-c <uicb_function> <cmd>\fR] [\fB\-g <argument>\fR] [\fB\-s <screen_num> <string>\fR] [\fB\-V <viwmfs cmd>\fR]
.sp
.SH "DESCRIPTION"
\fBWMFS\fR is a basic, lightweight and dynamic tiling windows manager for X\&.
.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\-g <argument>\fR
.RS 4
Show information about wmfs status\&.
.RE
.PP
\fB\-s <screen_num> <string>\fR
.RS 4
Set the bar(s) statustext. If the screen number is not specified, the string will be show on all screens bars\&.
.RE
.PP
\fB\-V <viwmfs cmd>\fR
.RS 4
Manage WMFS with vi-like command\&.
.RE
.PP
\fB\-S\fR
.RS 4
Update status script\&.
.RE
.PP
\fB\-v\fR
.RS 4
Print version information to standard output, then exit\&.
.RE
.PP
\fB\-h\fR
.RS 4
Print help information, then exit\&.
.RE
.PP
\fB\-i\fR
.RS 4
Print WMFS information
.RE
.SH "DEFAULT KEY BINDINGS"
.PP
\fBControl\-Alt + r\fR
.RS 4
Reload WMFS binary
.RE
.PP
\fBControl + Return\fR
.RS 4
Run a terminal (urxvt by default)
.RE
.PP
\fBAlt + q\fR
.RS 4
Quit the selected client
.RE
.PP
\fBControl\-Alt\-Shift + q\fR
.RS 4
Exit WMFS
.RE
.PP
\fBAlt + m \fR
.RS 4
Toggle maximize the selected client
.RE
.PP
\fBAlt + b \fR
.RS 4
Toggle the bar position between top, hide and bottom
.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
\fBControl + Right\fR
.RS 4
Next tag
.RE
.PP
\fBControl + Left\fR
.RS 4
Previous tag
.RE
.PP
\fBAlt + Space\fR
.RS 4
Next layout
.RE
.PP
\fBAlt\-Shift + Space\fR
.RS 4
Previous layout
.RE
.PP
\fBAlt + l\fR
.RS 4
Increase the mwfact (+0\&.025)
.RE
.PP
\fBAlt + h\fR
.RS 4
Decrease the mwfact (\-0\&.025)
.RE
.PP
\fBAlt + d\fR
.RS 4
Increase the nmaster (+1)\fR
.RE
.PP
\fBAlt\-Shift + d\fR
.RS 4
Decrease the nmaster (\-1)\fR
.RE
.PP
\fBAlt + t\fR
.RS 4
Swap the current client with the next\fR
.RE
.PP
\fBAlt\-Shift + t\fR
.RS 4
Swap the current client with the previous\fR
.RE
.PP
\fBAlt + p\fR
.RS 4
Make a launcher in the infobar to run an unix command\fR
.RE
.PP
\fBAlt + Escape\fR
.RS 4
Set WMFS in ViWMFS mode. (see wmfs \-V)\fR
.RE
.PP
\fBAlt\-Shift + p\fR
.RS 4
Make a launcher in the infobar to run an ssh session\fR
.RE
.PP
\fBAlt + F[1\&.\&.9]\fR
.RS 4
Change tag view
.RE
.PP
\fBControl\-Shift +F[1\&.\&.9]\fR
.RS 4
Transfert the selected client to the wanted tag
.RE
.SH "CONFIGURATION"
WMFS is configured by \fI$HOME/\&.config/wmfs/wmfsrc\fR\&.
.sp
.SH "BUGS"
WMFS isn\'t stable for now\&. So it certainly contains some bugs\&.
.sp
.SH "AUTHORS"
Martin Duquesnoy <\fIxorg62@gmail\&.com\fR\&[1]>\&.
.sp
.SH "WWW"
Main site: \fIhttp://wmfs\&.info\fR Bug tracker: \fIhttp://bugs\&.wmfs\&.info\fR
.sp
.SH "COPYING"
WMFS is under the BSD license\&. See COPYING for more information\&.
.sp
.SH "NOTES"
.IP " 1." 4
xorg62@gmail.com
.RS 4
\%mailto:xorg62@gmail.com
.RE
-5
View File
@@ -1,5 +0,0 @@
[Desktop Entry]
Encoding=UTF-8
Name=wmfs
Comment=Window Manager From Scratch
Exec=ck-launch-session wmfs
-242
View File
@@ -1,242 +0,0 @@
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = WMFS
PROJECT_NUMBER = devel
OUTPUT_DIRECTORY = doc
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = YES
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO
QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
DETAILS_AT_TOP = NO
INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 4
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = YES
OPTIMIZE_OUTPUT_JAVA = NO
BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
DISTRIBUTE_GROUP_DOC = NO
SUBGROUPING = YES
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = YES
EXTRACT_PRIVATE = YES
EXTRACT_STATIC = YES
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = YES
EXTRACT_ANON_NSPACES = YES
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = YES
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
SORT_BY_SCOPE_NAME = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_DIRECTORIES = NO
FILE_VERSION_FILTER =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = YES
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = src
INPUT_ENCODING = UTF-8
FILE_PATTERNS = *.c \
*.h \
RECURSIVE = YES
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXCLUDE_SYMBOLS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS = *
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = YES
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = NO
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES
REFERENCES_LINK_SOURCE = YES
USE_HTAGS = NO
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = NO
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
GENERATE_HTMLHELP = NO
HTML_DYNAMIC_SECTIONS = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
BINARY_TOC = NO
TOC_EXPAND = NO
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 4
GENERATE_TREEVIEW = YES
TREEVIEW_WIDTH = 250
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4wide
EXTRA_PACKAGES =
LATEX_HEADER =
PDF_HYPERLINKS = NO
USE_PDFLATEX = NO
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor...
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references...
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool...
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = NO
MSCGEN_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = YES
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = YES
TEMPLATE_RELATIONS = YeS
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = YES
CALLER_GRAPH = YES
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
DOT_PATH =
DOTFILE_DIRS =
DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 1000
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES
#---------------------------------------------------------------------------
# Configuration::additions related to the search engine...
#---------------------------------------------------------------------------
SEARCHENGINE = NO
-475
View File
@@ -1,475 +0,0 @@
#
# This is the default wmfs config file, copy it to
# ~/.config/wmfs/wmfsrc and edit it.
#
# Include file to split configuration
# @include "~/.config/wmfs/menu-wmfsrc"
[misc]
use_xft = true
font = "dejavu-10"
raisefocus = true
focus_follow_mouse = true
focus_follow_movement = true
opacity = 255
# focus_pointer_click: click on unfocused client area:
# true -- default, set focus
# false -- click go to client; including dockapps
focus_pointer_click = true
[/misc]
[bar]
bg = "#191919"
fg = "#D4D4D4"
border = true
#height = "-1"
light_shade = 0.10
dark_shade = -0.10
# Order of infobar elements:
# t = Tag list
# l = Layout button
# s = Selbar
elements_order = "tls"
[systray]
# Enable/disable systray
active = true
# Screen of systray
screen = 0
# Spacing between tray icons
spacing = 3
[/systray]
# Remove this section to disable the selbar.
[selbar]
bg = "#191919"
fg = "#D4D4ff"
# Cut title length
# max_length = 25
[mouse] button = "3" func = "clientlist" [/mouse]
[mouse] button = "4" func = "client_next" [/mouse]
[mouse] button = "5" func = "client_prev" [/mouse]
[/selbar]
[/bar]
[layouts]
fg = "#191919"
bg = "#7E89A2"
# Border around the layout button.
border = true
# Value menu or switch.
system = "menu"
# Keep layout geo for free layout
keep_layout_geo = false
# Enable split mode with client_resize_<direction>
cfactor_enable_split = true
# Symbol displayed for the selected layout in the list
selected_layout_symbol = "*"
# Width of layout button
# layout_button_width = x
# Tiling layouts.
[layout] type = "tile_right" symbol = "RIGHT" [/layout]
[layout] type = "tile_left" symbol = "LEFT" [/layout]
[layout] type = "tile_top" symbol = "TOP" [/layout]
[layout] type = "tile_bottom" symbol = "BOTTOM" [/layout]
[layout] type = "tile_grid" symbol = "GRID_H" [/layout]
[layout] type = "tile_grid_vertical" symbol = "GRID_V" [/layout]
[layout] type = "mirror_vertical" symbol = "MIRROR_V" [/layout]
[layout] type = "mirror_horizontal" symbol = "MIRROR_H" [/layout]
# Other layouts.
[layout] type = "max" symbol = "MAX" [/layout]
[layout] type = "free" symbol = "FREE" [/layout]
[/layouts]
[tags]
[default_tag]
name = "new tag"
mwfact = 0.5
nmaster = 1
layout = "tile"
resizehint = false
infobar_position = "top"
split = false
[/default_tag]
# whether client_next on the last tag will send you on the first
# and client_prev on the first tag will send you on the last one
tag_round = false
# Going twice on the same tag will bring you back on the previous one
tag_auto_prev = true
occupied_bg = "#003366"
occupied_fg = "#D4D4D4"
sel_fg = "#191919"
sel_bg = "#7E89A2"
urgent_bg = "#DD1111"
urgent_fg = "#000000"
# If true, number of the tag will be used for name
name_count = false
#default_name = "new tag" # deprecated, use [default_tag] instead
#default_layout = "tile_right" # deprecated, use [default_tag] instead
expose_name = "EXPOSE"
expose_layout = "tile_left"
# Border around the tag buttons.
border = true
# Hide empty tags in tag list
autohide = false
# Mouse buttons action on tag.
mouse_button_tag_sel = "1"
mouse_button_tag_transfert = "2"
mouse_button_tag_add = "3"
mouse_button_tag_next = "4"
mouse_button_tag_prev = "5"
[tag]
name = "one"
screen = 0
mwfact = 0.65
nmaster = 1
layout = "tile_right"
resizehint = false
infobar_position = "top"
above_fc = false
split = false
#[mouse] [/mouse] Possible multi mouse section
[/tag]
[tag] name = "two" [/tag]
[tag] name = "three" [/tag]
[tag] name = "four" [/tag]
[tag] name = "five" [/tag]
[tag] name = "six" [/tag]
[tag] name = "seven" [/tag]
[tag] name = "eight" [/tag]
[tag] name = "nine" [/tag]
[/tags]
[root]
# Command you can execute to set the background.
background_command = "xsetroot -solid black"
[mouse] button = "4" func = "tag_next" [/mouse]
[mouse] button = "5" func = "tag_prev" [/mouse]
[mouse] button = "3" func = "menu" cmd = "rootmenu" [/mouse]
[/root]
[client]
client_round = true
client_auto_center = false
border_height = 3
border_shadow = true
border_normal = "#191919"
border_focus = "#003366"
place_at_mouse = false
resize_corner_normal = "#191919"
resize_corner_focus = "#003366"
set_new_win_master = true
client_tile_raise = false
new_client_get_mouse = false
# send all client that have no tag rule in this default tag
#default_open_tag = 4
# same as above but for the screen
#default_open_screen = 1
# Space between tiled clients (px)
padding = 0
# Modifier for mouse use
modifier = "Alt"
light_shade = 0.10
dark_shade = -0.10
# *DEPRECATED* but works, see [rules] section
# Set automatic free or max client
# autofree = "xterm|MPlayer"
# automax = "Navigator"
[mouse] button = "1" func = "client_raise" [/mouse]
[mouse] button = "1" func = "mouse_move" [/mouse]
[mouse] button = "3" func = "client_raise" [/mouse]
[mouse] button = "3" func = "mouse_resize" [/mouse]
# Remove this section to delete the titlebar.
[titlebar]
stipple = false
height = 12
fg_normal = "#7E89A2"
fg_focus = "#9F9AB3"
[mouse] button = "1" func = "client_raise" [/mouse]
[mouse] button = "1" func = "mouse_move" [/mouse]
[mouse] button = "3" func = "client_raise" [/mouse]
[mouse] button = "3" func = "mouse_resize" [/mouse]
[button]
# Available "free", "max", "tile" flags or button.
flags = "free,max,tile"
[mouse] button = "1" func = "client_kill" [/mouse]
[mouse] button = "3" func = "menu" cmd = "clientmenu" [/mouse]
[line] coord = {1, 1, 4, 1} [/line]
[line] coord = {1, 1, 1, 4} [/line]
[line] coord = {1, 4, 4, 4} [/line]
[/button]
[/titlebar]
[/client]
[rules]
# Example of rule for MPlayer
[rule]
instance = "xv" # First part of WM_CLASS
class = "MPlayer" # Seconf part of WM_CLASS, not needed if first part is correct
# role = "" # WM_WINDOW_ROLE
screen = 0 # Screen to use
tag = 2 # Tag number of apps
free = true # Set automatic free client
max = false # Set automatic maximized client
follow_client = false # follow the client
ignore_tags = false # ignore tag (free mode)
[/rule]
[/rules]
[menu]
# Default menu, binded on the root window, button 3.
[set_menu]
name = "rootmenu"
# place_at_mouse = false
# x = 40 y = 50
# Available "center", "left", "right" menu align. Default: "center".
align = "left"
fg_focus = "#191919" bg_focus = "#7E89A2"
fg_normal = "#9F9AB3" bg_normal = "#191919"
[item] name = "Terminal" func = "spawn" cmd = "urxvt || xterm || gnome-terminal" [/item]
[item] name = "Applications" submenu = "appmenu" [/item]
[item] name = "Next tag" func = "tag_next" [/item]
[item] name = "Previous tag" func = "tag_prev" [/item]
[item] name = "Next layout" func = "layout_next" [/item]
[item] name = "Previous layout" func = "layout_prev" [/item]
[item] name = "Toggle infobar" func = "toggle_infobar_position" [/item]
[item] name = "Quit WMFS" func = "quit" [/item]
[/set_menu]
[set_menu]
name = "appmenu"
align = "left"
fg_focus = "#191919" bg_focus = "#7E89A2"
fg_normal = "#9F9AB3" bg_normal = "#191919"
[item] name = "Browser" func = "spawn" cmd = "firefox" [/item]
[item] name = "Calculator" func = "spawn" cmd = "xcalc" [/item]
[/set_menu]
[set_menu]
name = "clientmenu"
fg_focus = "#D4D4D4" bg_focus = "#003366"
fg_normal = "#D4D4D4" bg_normal = "#191919"
# Check items: possible 'check_max' or 'check_free'.
[item] name = "Close" func = "client_kill" [/item]
[item] name = "Maximize" func = "toggle_max" check = "check_max" [/item]
[item] name = "Free" func = "toggle_free" check = "check_free" [/item]
[/set_menu]
[/menu]
[launcher]
[set_launcher]
# Limit size of the launcher window (px)
width_limit = 300
name = "launcher_exec"
prompt = "Exec: "
command = "exec"
[/set_launcher]
[/launcher]
[keys]
# Reload the configuration of wmfs.
[key] mod = {"Alt", "Control"} key = "r" func = "reload" [/key]
# Open a terminal.
[key] mod = {"Control"} key = "Return" func = "spawn" cmd = "xterm" [/key]
# Kill the selected client.
[key] mod = {"Alt"} key = "q" func = "client_kill" [/key]
# Quit wmfs.
[key] mod = {"Control", "Alt", "Shift"} key = "q" func = "quit" [/key]
# Swap current client with the next.
[key] mod = {"Alt"} key = "t" func = "client_swap_next" [/key]
# Swap current client with the previous.
[key] mod = {"Alt", "Shift"} key = "t" func = "client_swap_prev" [/key]
# Set the selected client as Master
[key] mod = {"Control"} key = "m" func = "client_set_master" [/key]
# Toggle maximum the selected client
[key] mod = {"Alt"} key = "m" func = "toggle_max" [/key]
# Toggle free the selected client.
[key] mod = {"Alt"} key = "f" func = "toggle_free" [/key]
# Toggle the position of the infobar.
[key] mod = {"Alt"} key = "b" func = "toggle_infobar_position" [/key]
[key] mod = {"Alt", "Shift"} key = "b" func = "toggle_infobar_display" [/key]
# Toggle the resizehint of the current tag/screen
[key] mod = {"Shift", "Control"} key = "r" func = "toggle_resizehint" [/key]
# Toggle the tag_autohide mode
[key] mod = {"Shift", "Control"} key = "t" func = "toggle_tagautohide" [/key]
# Select the next client.
[key] mod = {"Alt"} key = "Tab" func = "client_next" [/key]
# Select the previous client.
[key] mod = {"Alt","Shift"} key = "Tab" func = "client_prev" [/key]
# Select the next tag.
[key] mod = {"Control"} key = "Right" func = "tag_next" [/key]
# Select the previous tag.
[key] mod = {"Control"} key = "Left" func = "tag_prev" [/key]
# Select the next visible tag.
[key] mod = {"Control","Alt"} key = "Right" func = "tag_next_visible" [/key]
# Select the previous visible tag.
[key] mod = {"Control","Alt"} key = "Left" func = "tag_prev_visible" [/key]
# Set the next layout.
[key] mod = {"Alt"} key = "space" func = "layout_next" [/key]
# Set the previous layout.
[key] mod = {"Alt", "Shift"} key = "space" func = "layout_prev" [/key]
# Increase nmaster.
[key] mod = {"Alt"} key = "d" func = "set_nmaster" cmd = "+1" [/key]
# Decease nmaster.
[key] mod = {"Alt", "Shift"} key = "d" func = "set_nmaster" cmd = "-1" [/key]
#Launcher.
[key] mod = {"Alt"} key = "p" func = "launcher" cmd = "launcher_exec" [/key]
# Set the tag x.
[key] mod = {"Alt"} key = "F1" func = "tag" cmd = "1" [/key]
[key] mod = {"Alt"} key = "F2" func = "tag" cmd = "2" [/key]
[key] mod = {"Alt"} key = "F3" func = "tag" cmd = "3" [/key]
[key] mod = {"Alt"} key = "F4" func = "tag" cmd = "4" [/key]
[key] mod = {"Alt"} key = "F5" func = "tag" cmd = "5" [/key]
[key] mod = {"Alt"} key = "F6" func = "tag" cmd = "6" [/key]
[key] mod = {"Alt"} key = "F7" func = "tag" cmd = "7" [/key]
[key] mod = {"Alt"} key = "F8" func = "tag" cmd = "8" [/key]
[key] mod = {"Alt"} key = "F9" func = "tag" cmd = "9" [/key]
# Transfert selected client to x.
[key] mod = {"Alt", "Shift"} key = "F1" func = "tag_transfert" cmd ="1" [/key]
[key] mod = {"Alt", "Shift"} key = "F2" func = "tag_transfert" cmd ="2" [/key]
[key] mod = {"Alt", "Shift"} key = "F3" func = "tag_transfert" cmd ="3" [/key]
[key] mod = {"Alt", "Shift"} key = "F4" func = "tag_transfert" cmd ="4" [/key]
[key] mod = {"Alt", "Shift"} key = "F5" func = "tag_transfert" cmd ="5" [/key]
[key] mod = {"Alt", "Shift"} key = "F6" func = "tag_transfert" cmd ="6" [/key]
[key] mod = {"Alt", "Shift"} key = "F7" func = "tag_transfert" cmd ="7" [/key]
[key] mod = {"Alt", "Shift"} key = "F8" func = "tag_transfert" cmd ="8" [/key]
[key] mod = {"Alt", "Shift"} key = "F9" func = "tag_transfert" cmd ="9" [/key]
# Toggle additional tags (x) on the current tag
[key] mod = {"Alt", "Super"} key = "F1" func = "tag_toggle_additional" cmd ="1" [/key]
[key] mod = {"Alt", "Super"} key = "F2" func = "tag_toggle_additional" cmd ="2" [/key]
[key] mod = {"Alt", "Super"} key = "F3" func = "tag_toggle_additional" cmd ="3" [/key]
[key] mod = {"Alt", "Super"} key = "F4" func = "tag_toggle_additional" cmd ="4" [/key]
[key] mod = {"Alt", "Super"} key = "F5" func = "tag_toggle_additional" cmd ="5" [/key]
[key] mod = {"Alt", "Super"} key = "F6" func = "tag_toggle_additional" cmd ="6" [/key]
[key] mod = {"Alt", "Super"} key = "F7" func = "tag_toggle_additional" cmd ="7" [/key]
[key] mod = {"Alt", "Super"} key = "F8" func = "tag_toggle_additional" cmd ="8" [/key]
[key] mod = {"Alt", "Super"} key = "F9" func = "tag_toggle_additional" cmd ="9" [/key]
# change screen
[key] mod = {"Super"} key = "Tab" func = "screen_next" [/key]
[key] mod = {"Super", "Shift"} key = "Tab" func = "screen_prev" [/key]
# swap client in the next/prev screen
[key] mod = {"Super", "Shift"} key = "a" func = "client_screen_next" [/key]
[key] mod = {"Super", "Shift"} key = "z" func = "client_screen_prev" [/key]
# Toggle tag explose
[key] mod = {"Alt"} key = "e" func = "toggle_tag_expose" [/key]
# Toggle split mode
[key] mod = {"Alt"} key = "s" func = "split_toggle" [/key]
# Focus next client with direction
[key] mod = {"Alt"} key = "h" func = "client_focus_left" [/key]
[key] mod = {"Alt"} key = "l" func = "client_focus_right" [/key]
[key] mod = {"Alt"} key = "k" func = "client_focus_top" [/key]
[key] mod = {"Alt"} key = "j" func = "client_focus_bottom" [/key]
# Swap next client with direction
[key] mod = {"Control"} key = "h" func = "client_swap_left" [/key]
[key] mod = {"Control"} key = "l" func = "client_swap_right" [/key]
[key] mod = {"Control"} key = "k" func = "client_swap_top" [/key]
[key] mod = {"Control"} key = "j" func = "client_swap_bottom" [/key]
# Move next splitted client with direction
[key] mod = {"Control", "Shift"} key = "h" func = "split_move_left" [/key]
[key] mod = {"Control", "Shift"} key = "l" func = "split_move_right" [/key]
[key] mod = {"Control", "Shift"} key = "k" func = "split_move_top" [/key]
[key] mod = {"Control", "Shift"} key = "j" func = "split_move_bottom" [/key]
# Resize selected tiled client with direction
[key] mod = {"Super"} key = "h" func = "client_resize_left" cmd = "20" [/key]
[key] mod = {"Super"} key = "l" func = "client_resize_right" cmd = "20" [/key]
[key] mod = {"Super"} key = "k" func = "client_resize_top" cmd = "20" [/key]
[key] mod = {"Super"} key = "j" func = "client_resize_bottom" cmd = "20" [/key]
[key] mod = { "Super", "Control"} key = "h" func = "client_resize_right" cmd = "-20" [/key]
[key] mod = { "Super", "Control"} key = "l" func = "client_resize_left" cmd = "-20" [/key]
[key] mod = { "Super", "Control"} key = "k" func = "client_resize_bottom" cmd = "-20" [/key]
[key] mod = { "Super", "Control"} key = "j" func = "client_resize_top" cmd = "-20" [/key]
# unlisted fonctions that can be used in [key] func = ""
# client_ignore_tag # Toggle the client in ignore_tag (display the client on all tags)
# tag_prev_sel # go back to the previous selected tag
# tag_transfert_{next, prev}
# tag_urgent # go to the urgent tag
# tag_swap_{next, prev} # swap tag with the previous/next one
# tag_last # go to the last tag
# tag_stay_last # toggle the current tag as the last one
# toggle_abovefc
# screen_prev_sel # go to the previous screen selected
# set_layout # set layout. need to be called with cmd = "<layout_name>"
# ignore_next_client_rules # ignore the rule the next time a rule is called
[/keys]