Compare commits
415 Commits
oldman
...
splitlayou
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5d83a4a664 | ||
|
|
bfb8658bba | ||
|
|
b47c4457f2 | ||
|
|
83c491527d | ||
|
|
c1d83e8c8b | ||
|
|
b6f728f1cc | ||
|
|
586620e1b1 | ||
|
|
52020cb22d | ||
|
|
fbcd31253b | ||
|
|
ff0d345b11 | ||
|
|
134bb3add4 | ||
|
|
74281424da | ||
|
|
b117a49b5a | ||
|
|
43f44ae9fd | ||
|
|
2aa654709e | ||
|
|
9a8fdd37c6 | ||
|
|
5d208730cd | ||
|
|
9bda577718 | ||
|
|
58f1c25eaf | ||
|
|
c0610091d6 | ||
|
|
5491037f54 | ||
|
|
e885449144 | ||
|
|
be2c983004 | ||
|
|
56ae367eee | ||
|
|
be5de68e93 | ||
|
|
5176103605 | ||
|
|
ef5c824a59 | ||
|
|
4a61cb8b18 | ||
|
|
87f926253f | ||
|
|
96b1c0dff2 | ||
|
|
bccd36d522 | ||
|
|
4e978c1824 | ||
|
|
2a30083520 | ||
|
|
13ac8cfa82 | ||
|
|
e4dbca928d | ||
|
|
eeedd9e4be | ||
|
|
a06e0daa5a | ||
|
|
860a1a2c11 | ||
|
|
ff888494f2 | ||
|
|
0774936a6f | ||
|
|
58b6d9bccb | ||
|
|
73a0d7ed01 | ||
|
|
ecda7adcf7 | ||
|
|
9e78421e2e | ||
|
|
87b558b4b9 | ||
|
|
82bea4cee8 | ||
|
|
d9cc60a205 | ||
|
|
e2d775ff83 | ||
|
|
af0ddeda3f | ||
|
|
7d754f71d4 | ||
|
|
517f6dc700 | ||
|
|
d229efe44b | ||
|
|
0445bb05da | ||
|
|
7b47fd041a | ||
|
|
9636f9188d | ||
|
|
b36af57fb0 | ||
|
|
a0e4a1657d | ||
|
|
c054e529a3 | ||
|
|
9e932ec98a | ||
|
|
83d56269f0 | ||
|
|
0b94f5496e | ||
|
|
34d94335f2 | ||
|
|
57ab723f5d | ||
|
|
99018268ef | ||
|
|
c556b45a8d | ||
|
|
f75c75645d | ||
|
|
6a93c6fa35 | ||
|
|
24de771713 | ||
|
|
a44505c1a9 | ||
|
|
468ecfdcb8 | ||
|
|
534eae3ae3 | ||
|
|
d2f3377f97 | ||
|
|
7839889071 | ||
|
|
664e4effdb | ||
|
|
ff923542ba | ||
|
|
c5e96961cb | ||
|
|
1ba4a0ad46 | ||
|
|
825620b25c | ||
|
|
911ac2f74a | ||
|
|
7eb15d595f | ||
|
|
dc836ccb86 | ||
|
|
f606b5ba88 | ||
|
|
391aae2dea | ||
|
|
f147bbbaf0 | ||
|
|
1b02cfed3e | ||
|
|
81e74e4bb6 | ||
|
|
4cda38ce26 | ||
|
|
c8b9b41a3e | ||
|
|
9d44177f20 | ||
|
|
06fb9553fc | ||
|
|
1061b79c5a | ||
|
|
50dcf7c8c2 | ||
|
|
a7162d803d | ||
|
|
4a804a740b | ||
|
|
813d88ff7a | ||
|
|
3f9c8a0030 | ||
|
|
c628970c60 | ||
|
|
3e3b18e6a3 | ||
|
|
89ff1ffcc5 | ||
|
|
dbaa966eb9 | ||
|
|
cb8e9889c8 | ||
|
|
11edb78e84 | ||
|
|
82eb33df85 | ||
|
|
12aa86e914 | ||
|
|
e57a6c5e62 | ||
|
|
a33ec045ab | ||
|
|
05bedec5c6 | ||
|
|
88d92149dd | ||
|
|
e28c6a3d64 | ||
|
|
3f21c79f08 | ||
|
|
0e8634fbe4 | ||
|
|
df4e32f4f9 | ||
|
|
6372f3974c | ||
|
|
703974cb00 | ||
|
|
4064cbdfd9 | ||
|
|
a7f9bf65ff | ||
|
|
79928efd35 | ||
|
|
b1a52a3a6b | ||
|
|
41c4570dcf | ||
|
|
ae47ab6f71 | ||
|
|
5ece3a6e55 | ||
|
|
4d39413f56 | ||
|
|
8bc30628c3 | ||
|
|
041e9ec20d | ||
|
|
1e35777c18 | ||
|
|
3ca201c42a | ||
|
|
34f2cb5b03 | ||
|
|
946e4c1606 | ||
|
|
6291639b24 | ||
|
|
6a0eedb63c | ||
|
|
22c9eee9af | ||
|
|
7d66c50676 | ||
|
|
9766392332 | ||
|
|
d79404f5ee | ||
|
|
f5134bd6b3 | ||
|
|
d213d13784 | ||
|
|
57019236aa | ||
|
|
ac00fefaa9 | ||
|
|
ddcdf6ce83 | ||
|
|
9235775dd2 | ||
|
|
971fb3240a | ||
|
|
bd1575e1b2 | ||
|
|
83d2da9da6 | ||
|
|
3be59059f4 | ||
|
|
891ba6d866 | ||
|
|
5729fe95fb | ||
|
|
43686dc82c | ||
|
|
d1f400e940 | ||
|
|
16120744a8 | ||
|
|
e2942ec597 | ||
|
|
bf26e8c22e | ||
|
|
4898e07e5e | ||
|
|
ff7853738f | ||
|
|
7180d733bd | ||
|
|
325f115c09 | ||
|
|
f48b9651c9 | ||
|
|
dcf3979c00 | ||
|
|
db98e3978b | ||
|
|
3cc68b6872 | ||
|
|
45e796406b | ||
|
|
f91699d6bc | ||
|
|
7d391f47f5 | ||
|
|
aa3f2b7fd0 | ||
|
|
2e4c8bd202 | ||
|
|
741002b724 | ||
|
|
c8e5ac4619 | ||
|
|
07ad0c6263 | ||
|
|
41cc6944ae | ||
|
|
48e226f5ae | ||
|
|
3652a4060c | ||
|
|
b4e33395b3 | ||
|
|
d0bb69150a | ||
|
|
7e0436ffdc | ||
|
|
c8c210bcac | ||
|
|
993b408262 | ||
|
|
f51d943bd9 | ||
|
|
56b6b467ee | ||
|
|
7ac4bf32c2 | ||
|
|
b5f24e042f | ||
|
|
a5432919ca | ||
|
|
c174e69b64 | ||
|
|
209f9a09a4 | ||
|
|
c5dfeb9878 | ||
|
|
3abfe9d7bb | ||
|
|
27c4c260c6 | ||
|
|
8ea76e1167 | ||
|
|
6ec79f626e | ||
|
|
2320e8586c | ||
|
|
c317afc79d | ||
|
|
056cb5daf6 | ||
|
|
7bb0fdcbad | ||
|
|
2273ccc5d5 | ||
|
|
18e97d3e1e | ||
|
|
9de133dac7 | ||
|
|
b1d4e2a403 | ||
|
|
8e6cea6d05 | ||
|
|
03c41f9b3b | ||
|
|
42a0612664 | ||
|
|
fb1627e8cc | ||
|
|
c8eb002768 | ||
|
|
0d0c3af47b | ||
|
|
5b5dd104d9 | ||
|
|
0a2c1f9d13 | ||
|
|
c817b7277b | ||
|
|
99e85cbfc2 | ||
|
|
a1ad5685f9 | ||
|
|
abf71d99b9 | ||
|
|
1460229397 | ||
|
|
47a68568fe | ||
|
|
a0fd6a77cc | ||
|
|
ef6b057234 | ||
|
|
e32726f008 | ||
|
|
74bbf0bd04 | ||
|
|
b85b6bd687 | ||
|
|
bf16b4a2e7 | ||
|
|
f2bd808b86 | ||
|
|
f2734a5f2b | ||
|
|
b4fb75806a | ||
|
|
dbe7588c0a | ||
|
|
dae3019185 | ||
|
|
3f461810d2 | ||
|
|
0a708c8dda | ||
|
|
6072c2d811 | ||
|
|
ce3813608c | ||
|
|
6c332c9ea5 | ||
|
|
d606f999f9 | ||
|
|
87575a019d | ||
|
|
6882cfb986 | ||
|
|
9e457b3832 | ||
|
|
c8a74878a1 | ||
|
|
d0058146dd | ||
|
|
77e458048d | ||
|
|
f6206d65b1 | ||
|
|
c90a5743b3 | ||
|
|
3459ed0b20 | ||
|
|
3cf93a0961 | ||
|
|
719654fcbc | ||
|
|
e053d41a3d | ||
|
|
1170a6afbc | ||
|
|
a42237aab7 | ||
|
|
f5f2d8c7de | ||
|
|
bc31510d64 | ||
|
|
f928497e70 | ||
|
|
daeffb324e | ||
|
|
d75746bcf4 | ||
|
|
82b17ea02f | ||
|
|
19ecd89d89 | ||
|
|
c7b2d98303 | ||
|
|
546366b282 | ||
|
|
20c99826ce | ||
|
|
eda1bfdfec | ||
|
|
22295948ec | ||
|
|
c2664e8e85 | ||
|
|
e5b2a9e058 | ||
|
|
b6c557a8ee | ||
|
|
14f12edf25 | ||
|
|
3d6f8da805 | ||
|
|
40b4662ff8 | ||
|
|
8d71b8c2a8 | ||
|
|
31899139e4 | ||
|
|
61a1e18a59 | ||
|
|
3d3dbf589f | ||
|
|
6912599c72 | ||
|
|
1294d7e35c | ||
|
|
6bd0175db0 | ||
|
|
2d9baf78c5 | ||
|
|
b7ded56ef9 | ||
|
|
7f96a338c6 | ||
|
|
bfc56f8c37 | ||
|
|
d8e2d54d8e | ||
|
|
7096101651 | ||
|
|
103c86db03 | ||
|
|
01bd4cc265 | ||
|
|
f6ad74273c | ||
|
|
c3cf9d64b3 | ||
|
|
26dde34d5c | ||
|
|
9ff9c81441 | ||
|
|
66d1b9b2fb | ||
|
|
6ac65840c0 | ||
|
|
7c9e560236 | ||
|
|
5a05594092 | ||
|
|
eb567d9936 | ||
|
|
b055908080 | ||
|
|
2614c61657 | ||
|
|
52e53c7415 | ||
|
|
e01bb5c3b0 | ||
|
|
a1de32cac7 | ||
|
|
57f8768228 | ||
|
|
f3c0f5492a | ||
|
|
7db51713e5 | ||
|
|
20756b30cd | ||
|
|
d242ab880a | ||
|
|
658e26bd49 | ||
|
|
464f06c5c1 | ||
|
|
a0e5ddc45a | ||
|
|
2a9d024784 | ||
|
|
6b788edc38 | ||
|
|
8f8d47dc23 | ||
|
|
3a021bf026 | ||
|
|
1ec6d90c1e | ||
|
|
b91db6b431 | ||
|
|
c6469260de | ||
|
|
5aeeae4198 | ||
|
|
3841e55f82 | ||
|
|
4a3952f54f | ||
|
|
8816bd6753 | ||
|
|
3366ec835f | ||
|
|
839ebeaf2b | ||
|
|
36aa4ce43a | ||
|
|
4f1742eef9 | ||
|
|
fd9cedd695 | ||
|
|
3644bc736b | ||
|
|
1eeb5e167e | ||
|
|
a1d134a1b7 | ||
|
|
52bfa713df | ||
|
|
3b60e23f9f | ||
|
|
59d9dcdc93 | ||
|
|
9055a55d58 | ||
|
|
e254f76211 | ||
|
|
e6db51d8fd | ||
|
|
ce4575ee04 | ||
|
|
e9b409b564 | ||
|
|
578b62ec09 | ||
|
|
4f42436098 | ||
|
|
dce3b8eb3c | ||
|
|
ce8238fb20 | ||
|
|
e9ffab7d62 | ||
|
|
cf565c9b57 | ||
|
|
179c94f26f | ||
|
|
5017c4ced5 | ||
|
|
7b0113ab6e | ||
|
|
dc2e571e5e | ||
|
|
5d9ad3e1db | ||
|
|
695cf69790 | ||
|
|
86b20ba799 | ||
|
|
ec2c2f6337 | ||
|
|
5d7f4a2382 | ||
|
|
d8d09f9e1a | ||
|
|
a496d77f9e | ||
|
|
7a1bfb48f5 | ||
|
|
3e71c420d6 | ||
|
|
0eab6d1a92 | ||
|
|
c63a9af492 | ||
|
|
0c38afdb35 | ||
|
|
19f9a35685 | ||
|
|
ed390279f5 | ||
|
|
6d99de883c | ||
|
|
7abc282d21 | ||
|
|
ed254ea417 | ||
|
|
f2e9c1fd02 | ||
|
|
36ca03f8f3 | ||
|
|
00638264d3 | ||
|
|
6a420e2934 | ||
|
|
132f7d1da4 | ||
|
|
4a1ab8ef79 | ||
|
|
61015e2567 | ||
|
|
5742ed4fca | ||
|
|
872d9cb348 | ||
|
|
2292ab97d1 | ||
|
|
3b81cacaac | ||
|
|
0270a28181 | ||
|
|
e6fc0a4976 | ||
|
|
374abb0e26 | ||
|
|
1d5792b278 | ||
|
|
461b45545a | ||
|
|
4cf2b8bf8f | ||
|
|
cc10d56359 | ||
|
|
1094861b49 | ||
|
|
fdb1d2c748 | ||
|
|
908978cca1 | ||
|
|
b3325867ed | ||
|
|
d32ee3295e | ||
|
|
910421c41c | ||
|
|
46d212297a | ||
|
|
bf9e9ca578 | ||
|
|
ce652d29e4 | ||
|
|
00e4e9975e | ||
|
|
aa04eab011 | ||
|
|
afdda3b95a | ||
|
|
2522b21ab3 | ||
|
|
8aeded6cd6 | ||
|
|
9a3b06c645 | ||
|
|
89b115e850 | ||
|
|
e71f85ff26 | ||
|
|
253d50762b | ||
|
|
e17f36f24f | ||
|
|
6d720d9848 | ||
|
|
414273fff9 | ||
|
|
cee16d6f7f | ||
|
|
fb0ddc6b73 | ||
|
|
8062f4a42a | ||
|
|
c6f0204901 | ||
|
|
a90f4ee7ce | ||
|
|
fb97d95787 | ||
|
|
6e05fd498d | ||
|
|
f683022678 | ||
|
|
32b3120fbd | ||
|
|
470606af1b | ||
|
|
12fc01b824 | ||
|
|
9067f3cb66 | ||
|
|
2040385af6 | ||
|
|
510cb29e9f | ||
|
|
32686569c4 | ||
|
|
faab6d946e | ||
|
|
d49ebaa57e | ||
|
|
5d1aaa1363 | ||
|
|
5dd811b91e | ||
|
|
a0a53f3af2 | ||
|
|
6ecc58bdb1 | ||
|
|
c524326714 | ||
|
|
c886edb19d | ||
|
|
995c4e94e7 | ||
|
|
d3207be191 | ||
|
|
1cc8506610 | ||
|
|
4b692b7a0f |
16
.gitignore
vendored
16
.gitignore
vendored
@@ -1,17 +1,11 @@
|
|||||||
CMakeCache.txt
|
|
||||||
CMakeFiles/
|
|
||||||
cmake_install.cmake
|
|
||||||
cmake_uninstall.cmake
|
|
||||||
Makefile
|
|
||||||
*.o
|
*.o
|
||||||
.*.sw?
|
.*.sw?
|
||||||
wmfs
|
wmfs
|
||||||
src/config.h
|
|
||||||
changelog
|
|
||||||
config.h
|
|
||||||
#*
|
#*
|
||||||
\#*
|
\#*
|
||||||
|
wmfs.1.gz
|
||||||
|
tags
|
||||||
|
*.patch
|
||||||
|
*.diff
|
||||||
|
Makefile
|
||||||
build/
|
build/
|
||||||
doc/
|
|
||||||
wmfs.doxygen
|
|
||||||
wmfsrc
|
|
||||||
|
|||||||
360
CMakeLists.txt
360
CMakeLists.txt
@@ -1,272 +1,134 @@
|
|||||||
# -*- mode: cmake -*-
|
#
|
||||||
#Cmakelists.txt
|
# CMake for wmfs David Demelier <markand@malikania.fr>
|
||||||
# Minimum version of CMake
|
#
|
||||||
cmake_minimum_required(VERSION 2.6)
|
|
||||||
if(COMMAND cmake_policy)
|
|
||||||
cmake_policy(VERSION 2.6)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
CONFIGURE_FILE(
|
# General settings
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
|
cmake_minimum_required(VERSION 2.8)
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
project(wmfs)
|
||||||
IMMEDIATE @ONLY)
|
|
||||||
|
|
||||||
ADD_CUSTOM_TARGET(uninstall
|
set(CMAKE_C_FLAGS_RELEASE "-Wall")
|
||||||
"${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
|
set(CMAKE_C_FLAGS_DEBUG "-Wall -g -ansi -pendantic -O3 -funroll-loops")
|
||||||
|
|
||||||
# Source and build dirs
|
# General option
|
||||||
set(SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
option(WITH_XINERAMA "Build with X.Org xinerama support" ON)
|
||||||
set(BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
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)
|
||||||
|
|
||||||
# Project name - wmfs
|
# WMFS Version and XDG directory
|
||||||
set(PROJECT_NAME wmfs)
|
set(WMFS_VERSION "201106")
|
||||||
project(${PROJECT_NAME} C)
|
if (NOT XDG_CONFIG_DIR)
|
||||||
|
set(XDG_CONFIG_DIR "${CMAKE_INSTALL_PREFIX}/etc/wmfs")
|
||||||
|
endif ()
|
||||||
|
|
||||||
# Definition of the wmfs source
|
# Man prefix
|
||||||
set(wmfs_src
|
if (NOT MANPREFIX)
|
||||||
src/parse/parse.c
|
set(MANPREFIX "${CMAKE_INSTALL_PREFIX}/share")
|
||||||
src/barwin.c
|
endif ()
|
||||||
src/client.c
|
|
||||||
src/config.c
|
|
||||||
src/
|
|
||||||
src/draw.c
|
|
||||||
src/event.c
|
|
||||||
src/ewmh.c
|
|
||||||
src/frame.c
|
|
||||||
src/getinfo.c
|
|
||||||
src/infobar.c
|
|
||||||
src/init.c
|
|
||||||
src/launcher.c
|
|
||||||
src/layout.c
|
|
||||||
src/menu.c
|
|
||||||
src/mouse.c
|
|
||||||
src/screen.c
|
|
||||||
src/status.c
|
|
||||||
src/tag.c
|
|
||||||
src/util.c
|
|
||||||
src/viwmfs.c
|
|
||||||
src/wmfs.c)
|
|
||||||
|
|
||||||
# Set the executable from the wmfs_src
|
|
||||||
add_executable(wmfs ${wmfs_src})
|
|
||||||
|
|
||||||
# Set the version
|
|
||||||
set(VERSION "WMFS-201004")
|
|
||||||
|
|
||||||
# FLAGS
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -ansi")
|
|
||||||
|
|
||||||
# Linker FLAGS
|
|
||||||
|
|
||||||
set(DEFAULT_LDFLAGS "-L /usr/local/lib -lpthread")
|
|
||||||
|
|
||||||
if(CMAKE_SYSTEM_NAME MATCHES NetBSD)
|
|
||||||
message("-- NetBSD system found - Using /usr/pkg/lib for linker")
|
|
||||||
set(LDFLAGS "${DEFAULT_LDFLAGS} -L /usr/pkg/lib")
|
|
||||||
else(CMAKE_SYSTEM_NAME MATCHES NetBSD)
|
|
||||||
set(LDFLAGS ${DEFAULT_LDFLAGS})
|
|
||||||
endif(CMAKE_SYSTEM_NAME MATCHES NetBSD)
|
|
||||||
|
|
||||||
set_target_properties(wmfs PROPERTIES LINK_FLAGS ${LDFLAGS})
|
|
||||||
# Includes dir for libs in build_dir
|
|
||||||
include_directories(
|
|
||||||
${BUILD_DIR}/src
|
|
||||||
)
|
|
||||||
|
|
||||||
# Package find
|
|
||||||
find_package(Freetype)
|
|
||||||
if(FREETYPE_FOUND)
|
|
||||||
include_directories(${FREETYPE_INCLUDE_DIRS})
|
|
||||||
else (FREETYPE_FOUND)
|
|
||||||
message(FATAL_ERROR "Could not find Freetype")
|
|
||||||
endif (FREETYPE_FOUND)
|
|
||||||
|
|
||||||
|
# Libraries are optional
|
||||||
find_package(X11)
|
find_package(X11)
|
||||||
if(X11_FOUND)
|
if (NOT X11_FOUND)
|
||||||
include_directories(${X11_INCLUDE_DIR})
|
message(FATAL_ERROR "You need x11 libraries to build wmfs")
|
||||||
else (X11_FOUND)
|
else ()
|
||||||
message(FATAL_ERROR "Could not find X11")
|
list(APPEND INCLUDES ${X11_INCLUDE_DIR})
|
||||||
endif (X11_FOUND)
|
list(APPEND LIBRARIES ${X11_LIBRARIES})
|
||||||
|
endif ()
|
||||||
|
|
||||||
# Link Libraries
|
# pthread is needed
|
||||||
set(LIBRARIES_TO_LINK
|
set(CMAKE_THREAD_PREFER_PTHREAD)
|
||||||
${FREETYPE_LIBRARIES}
|
find_package(Threads)
|
||||||
${X11_LIBRARIES}
|
|
||||||
Xft)
|
|
||||||
|
|
||||||
# Includes
|
if (NOT CMAKE_USE_PTHREADS_INIT)
|
||||||
include(FindDoxygen)
|
message(FATAL_ERROR "You need pthread libraries to build wmfs")
|
||||||
include(FindPkgConfig)
|
else ()
|
||||||
|
list(APPEND LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
|
||||||
|
endif ()
|
||||||
|
|
||||||
# Use pkgconfig to get required libraries
|
# The following are optional X11 libraries
|
||||||
pkg_check_modules(WMFS_REQUIRED REQUIRED
|
if (X11_Xinerama_FOUND AND WITH_XINERAMA)
|
||||||
x11
|
list(APPEND INCLUDES ${X11_Xinerama_INCLUDE_PATH})
|
||||||
freetype2
|
list(APPEND LIBRARIES ${X11_Xinerama_LIB})
|
||||||
xft)
|
list(APPEND DEFINES "HAVE_XINERAMA")
|
||||||
|
else ()
|
||||||
|
list(APPEND DISABLED "HAVE_XINERAMA")
|
||||||
|
endif ()
|
||||||
|
|
||||||
# Optional dependencies check
|
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 ()
|
||||||
|
|
||||||
# Check for xinerama
|
if (X11_Xft_FOUND AND WITH_XFT)
|
||||||
pkg_check_modules(HAVE_XINERAMA xinerama)
|
find_package(Freetype)
|
||||||
if(HAVE_XINERAMA_FOUND)
|
if (FREETYPE_FOUND)
|
||||||
set(WMFS_HAVE_XINERAMA "#define HAVE_XINERAMA")
|
list(APPEND INCLUDES ${FREETYPE_INCLUDE_DIRS}
|
||||||
set(LIBRARIES_TO_LINK ${LIBRARIES_TO_LINK} Xinerama)
|
${X11_Xft_INCLUDE_PATH})
|
||||||
else()
|
list(APPEND LIBRARIES ${FREETYPE_LIBRARIES}
|
||||||
set(WMFS_HAVE_XINERAMA "")
|
${X11_Xft_LIB})
|
||||||
endif()
|
list(APPEND DEFINES "HAVE_XFT")
|
||||||
|
else ()
|
||||||
|
list(APPEND DISABLED "HAVE_XFT")
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
# Check for xrandr
|
if (WITH_IMLIB2)
|
||||||
pkg_check_modules(HAVE_XRANDR xrandr)
|
find_package(PkgConfig)
|
||||||
if(HAVE_XRANDR_FOUND)
|
if (PKG_CONFIG_FOUND)
|
||||||
set(WMFS_HAVE_XRANDR "#define HAVE_XRANDR")
|
pkg_check_modules(IMLIB2 imlib2)
|
||||||
set(LIBRARIES_TO_LINK ${LIBRARIES_TO_LINK} Xrandr)
|
if (IMLIB2_FOUND)
|
||||||
else()
|
list(APPEND INCLUDES ${IMLIB2_INCLUDE_DIRS})
|
||||||
set(WMFS_HAVE_XRANDR "")
|
list(APPEND LIBRARIES ${IMLIB2_LIBRARIES})
|
||||||
endif()
|
list(APPEND DEFINES "HAVE_IMLIB")
|
||||||
|
|
||||||
# Check for Imlib
|
link_directories(${IMLIB2_LIBRARY_DIRS})
|
||||||
pkg_check_modules(HAVE_IMLIB imlib2)
|
else ()
|
||||||
if(HAVE_IMLIB_FOUND)
|
list(APPEND DISABLED "HAVE_IMLIB")
|
||||||
set(WMFS_HAVE_IMLIB "#define HAVE_IMLIB")
|
endif ()
|
||||||
set(LIBRARIES_TO_LINK ${LIBRARIES_TO_LINK} Imlib2)
|
else ()
|
||||||
else()
|
list(APPEND DISABLED "HAVE_IMLIB")
|
||||||
set(WMFS_HAVE_IMLIB "")
|
endif ()
|
||||||
endif()
|
endif ()
|
||||||
|
|
||||||
target_link_libraries(wmfs ${LIBRARIES_TO_LINK})
|
# Enable the optional module to compilation
|
||||||
|
foreach (modname ${DEFINES})
|
||||||
|
add_definitions(-D${modname})
|
||||||
|
|
||||||
# Messages
|
# Set a variable to print all enabled modules.
|
||||||
message("Project version: ${VERSION}")
|
# Remove the HAVE_ from module names
|
||||||
message("Using these CFLAGS: ${CMAKE_C_FLAGS}")
|
string(SUBSTRING ${modname} 5 -1 upcase)
|
||||||
message("Using these LDFLAGS: ${LDFLAGS}")
|
string(TOLOWER ${upcase} module)
|
||||||
message("Linking with theses libraries : ${LIBRARIES_TO_LINK}")
|
|
||||||
|
|
||||||
# Generating man page
|
message("INFO: ${module} enabled")
|
||||||
find_program(GZIP_EXECUTABLE gzip)
|
endforeach ()
|
||||||
if(NOT GZIP_EXECUTABLE)
|
|
||||||
message(STATUS "Looking for gzip -- not found")
|
|
||||||
message(STATUS "Could not generating man page")
|
|
||||||
else()
|
|
||||||
message(STATUS "Looking for gzip -- ${GZIP_EXECUTABLE}")
|
|
||||||
message(STATUS "Generating man page")
|
|
||||||
set(WMFS_MAN1_FILES ${BUILD_DIR}/wmfs.1.gz)
|
|
||||||
execute_process(
|
|
||||||
COMMAND ${GZIP_EXECUTABLE} -c wmfs.1
|
|
||||||
WORKING_DIRECTORY ${SOURCE_DIR}
|
|
||||||
OUTPUT_FILE ${WMFS_MAN1_FILES})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Generating CHANGELOG
|
# Show modules disabled
|
||||||
find_program(GIT_EXECUTABLE git)
|
foreach (modname ${DISABLED})
|
||||||
if(EXISTS ${SOURCE_DIR}/.git/HEAD AND GIT_EXECUTABLE)
|
string(SUBSTRING ${modname} 5 -1 upcase)
|
||||||
message(STATUS "Looking for git -- ${GIT_EXECUTABLE}")
|
string(TOLOWER ${upcase} module)
|
||||||
message(STATUS "Git dir -- Generating changelog...")
|
|
||||||
set(PROJECT_CHANGELOG ${SOURCE_DIR}/changelog)
|
|
||||||
execute_process(
|
|
||||||
COMMAND ${GIT_EXECUTABLE} log
|
|
||||||
WORKING_DIRECTORY ${SOURCE_DIR}
|
|
||||||
OUTPUT_FILE ${PROJECT_CHANGELOG})
|
|
||||||
else()
|
|
||||||
message(STATUS "Looking for git -- not found")
|
|
||||||
message(STATUS "Could not generating changelog")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# sets
|
message("INFO: ${module} disabled")
|
||||||
# {{{ Install path and configuration variables
|
endforeach ()
|
||||||
if(DEFINED PREFIX)
|
|
||||||
set(PREFIX ${PREFIX} CACHE PATH "install prefix")
|
|
||||||
set(CMAKE_INSTALL_PREFIX ${PREFIX})
|
|
||||||
else()
|
|
||||||
set(PREFIX ${CMAKE_INSTALL_PREFIX} CACHE PATH "install prefix")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#If a sysconfdir is specified, use it instead
|
file(
|
||||||
#of the default configuration dir.
|
GLOB
|
||||||
if(DEFINED SYSCONFDIR)
|
SOURCES
|
||||||
set(SYSCONFDIR ${SYSCONFDIR} CACHE PATH "config directory")
|
src/*.c
|
||||||
else()
|
src/*.h
|
||||||
set(SYSCONFDIR /etc CACHE PATH "config directory")
|
)
|
||||||
endif()
|
|
||||||
|
|
||||||
#If an XDG Config Dir is specificed, use it instead
|
# Add definitions for the version and XDG
|
||||||
#of the default XDG configuration dir.
|
add_definitions(-DWMFS_VERSION=\"${WMFS_VERSION}\")
|
||||||
if(DEFINED XDG_CONFIG_DIR)
|
add_definitions(-DXDG_CONFIG_DIR=\"${XDG_CONFIG_DIR}\")
|
||||||
set(XDG_CONFIG_DIR ${XDG_CONFIG_SYS} CACHE PATH "xdg config directory")
|
|
||||||
else()
|
|
||||||
set(XDG_CONFIG_DIR ${SYSCONFDIR}/xdg CACHE PATH "xdg config directory")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# setting WMFS_XSESSION_PATH
|
include_directories(${INCLUDES})
|
||||||
if(DEFINED WMFS_XSESSION_PATH)
|
add_executable(wmfs ${SOURCES})
|
||||||
set(WMFS_XSESSION_PATH ${WMFS_XSESSION_PATH} CACHE PATH "wmfs xsessions directory")
|
target_link_libraries(wmfs ${LIBRARIES})
|
||||||
else()
|
|
||||||
set(WMFS_XSESSION_PATH ${PREFIX}/share/xsessions CACHE PATH "wmfs xsessions directory")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(DEFINED WMFS_MAN_PATH)
|
# Install targets
|
||||||
set(WMFS_MAN_PATH ${WMFS_MAN_PATH} CACHE PATH "wmfs manpage directory")
|
install(TARGETS wmfs DESTINATION bin/)
|
||||||
else()
|
install(FILES wmfsrc DESTINATION ${XDG_CONFIG_DIR}/)
|
||||||
set(WMFS_MAN_PATH ${PREFIX}/share/man CACHE PATH "wmfs manpage directory")
|
install(FILES wmfs.1 DESTINATION ${MANPREFIX}/man1/)
|
||||||
endif()
|
|
||||||
|
|
||||||
if(DOXYGEN_EXECUTABLE)
|
|
||||||
add_custom_target(doc
|
|
||||||
COMMAND ${DOXYGEN_EXECUTABLE} ${SOURCE_DIR}/wmfs.doxygen
|
|
||||||
WORKING_DIRECTORY ${BUILD_DIR})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
find_program(URXVT_EXECUTABLE urxvt)
|
|
||||||
if(URXVT_EXECUTABLE)
|
|
||||||
set(WMFS_TERM urxvt)
|
|
||||||
else()
|
|
||||||
set(WMFS_TERM xterm)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Remplace strings in configs
|
|
||||||
set(WMFS_VERSION ${VERSION})
|
|
||||||
set(WMFS_COMPILE_MACHINE ${CMAKE_SYSTEM_PROCESSOR})
|
|
||||||
set(WMFS_COMPILE_BY $ENV{USER})
|
|
||||||
set(WMFS_COMPILE_FLAGS ${CMAKE_C_FLAGS})
|
|
||||||
set(WMFS_LINKED_LIBS ${LIBRARIES_TO_LINK})
|
|
||||||
set(WMFS_SYSCONFDIR ${XDG_CONFIG_DIR}/${PROJECT_NAME})
|
|
||||||
set(WMFS_SOURCE_DIR ${SOURCE_DIR})
|
|
||||||
|
|
||||||
# Configure files
|
|
||||||
set(wmfs_configure_files
|
|
||||||
src/config.h.in
|
|
||||||
wmfs.doxygen.in
|
|
||||||
wmfsrc.in)
|
|
||||||
|
|
||||||
macro(a_configure_file file)
|
|
||||||
string(REGEX REPLACE ".in\$" "" outfile ${file})
|
|
||||||
message(STATUS "Configuring ${outfile}")
|
|
||||||
configure_file(${SOURCE_DIR}/${file}
|
|
||||||
${SOURCE_DIR}/${outfile}
|
|
||||||
ESCAPE_QUOTE
|
|
||||||
@ONLY)
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
foreach(file ${wmfs_configure_files})
|
|
||||||
a_configure_file(${file})
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
set(PROJECT_DATA_PATH share/${PROJECT_NAME})
|
|
||||||
set(PROJECT_TODO ${SOURCE_DIR}/TODO)
|
|
||||||
set(PROJECT_README ${SOURCE_DIR}/README)
|
|
||||||
set(PROJECT_DEFAULT_CONF ${SOURCE_DIR}/wmfsrc)
|
|
||||||
|
|
||||||
# installs
|
|
||||||
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)
|
|
||||||
|
|
||||||
if(WMFS_MAN1_FILES)
|
|
||||||
install(FILES ${WMFS_MAN1_FILES} DESTINATION ${WMFS_MAN_PATH}/man1)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(PROJECT_CHANGELOG)
|
|
||||||
install(FILES ${PROJECT_CHANGELOG} DESTINATION ${PROJECT_DATA_PATH})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
install(FILES ${PROJECT_TODO} ${PROJECT_README}
|
|
||||||
${PROJECT_DEFAULT_CONF} DESTINATION ${PROJECT_DATA_PATH})
|
|
||||||
install(FILES ${PROJECT_DEFAULT_CONF} DESTINATION ${WMFS_SYSCONFDIR})
|
|
||||||
install(FILES "wmfs.desktop" DESTINATION ${WMFS_XSESSION_PATH})
|
|
||||||
|
|||||||
35
README
35
README
@@ -4,33 +4,36 @@ WMFS Window Manager.
|
|||||||
|
|
||||||
A highly configurable and manageable tiling Window Manager created from scratch
|
A highly configurable and manageable tiling Window Manager created from scratch
|
||||||
|
|
||||||
AUTHORS :
|
AUTHOR :
|
||||||
Martin Duquesnoy <xorg62@gmail.com>
|
- Martin Duquesnoy <xorg62@gmail.com>
|
||||||
|
|
||||||
LICENSE : BSD
|
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 :
|
REQUIREMENT :
|
||||||
- freetype2
|
- libx11
|
||||||
|
- libxft (optional)
|
||||||
|
\- freetype
|
||||||
- libxinerama (optional)
|
- libxinerama (optional)
|
||||||
- libxrandr (optional)
|
- libxrandr (optional)
|
||||||
- imlib2 (optional)
|
- imlib2 (optional)
|
||||||
- libxft
|
- cmake>=2.8 (build system)
|
||||||
- libx11
|
|
||||||
- CMake >= 2.6
|
|
||||||
|
|
||||||
OS :
|
OS :
|
||||||
- GNU/Linux : Supported.
|
- GNU/Linux : Supported.
|
||||||
- FreeBSD : Supported.
|
- FreeBSD/OpenBSD/NetBSD : Supported.
|
||||||
|
|
||||||
INSTALL :
|
INSTALL :
|
||||||
- mkdir build
|
mkdir build/ && cd build/
|
||||||
- cd build
|
cmake ..
|
||||||
- cmake ..
|
|
||||||
- make
|
|
||||||
- sudo make install
|
|
||||||
- sudo make uninstall # if you would to remove it.
|
|
||||||
|
|
||||||
If you have doxygen installed you can generate doxygen documentation via custom target 'make doc' in the build dir.
|
|
||||||
|
|
||||||
DISTROS :
|
DISTROS :
|
||||||
- wmfs port for FreeBSD at x11-wm/wmfs
|
- wmfs port for FreeBSD at x11-wm/wmfs
|
||||||
|
|||||||
29
TODO
29
TODO
@@ -1,5 +1,24 @@
|
|||||||
· Add Doxygen comment <-> OK
|
,
|
||||||
· Mouse bindings in the config file
|
dM
|
||||||
· Can change client position in the tile grid
|
MMr
|
||||||
· Fix all the bug \o/
|
4MMML .
|
||||||
· XCB ?
|
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
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
|
||||||
MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
|
|
||||||
ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
|
||||||
|
|
||||||
FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
|
|
||||||
STRING(REGEX REPLACE "\n" ";" files "${files}")
|
|
||||||
FOREACH(file ${files})
|
|
||||||
MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
|
|
||||||
IF(EXISTS "$ENV{DESTDIR}${file}")
|
|
||||||
EXEC_PROGRAM(
|
|
||||||
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
|
|
||||||
OUTPUT_VARIABLE rm_out
|
|
||||||
RETURN_VALUE rm_retval
|
|
||||||
)
|
|
||||||
IF(NOT "${rm_retval}" STREQUAL 0)
|
|
||||||
MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
|
|
||||||
ENDIF(NOT "${rm_retval}" STREQUAL 0)
|
|
||||||
ELSE(EXISTS "$ENV{DESTDIR}${file}")
|
|
||||||
MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
|
|
||||||
ENDIF(EXISTS "$ENV{DESTDIR}${file}")
|
|
||||||
ENDFOREACH(file)
|
|
||||||
75
scripts/setlocalversion
Executable file
75
scripts/setlocalversion
Executable file
@@ -0,0 +1,75 @@
|
|||||||
|
#!/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`"
|
||||||
100
src/barwin.c
100
src/barwin.c
@@ -39,26 +39,26 @@
|
|||||||
* \param w BarWindow Width
|
* \param w BarWindow Width
|
||||||
* \param h BarWindow Height
|
* \param h BarWindow Height
|
||||||
* \param color BarWindow color
|
* \param color BarWindow color
|
||||||
* \param entermask Bool for know if the EnterMask mask is needed
|
* \param entermask bool for know if the EnterMask mask is needed
|
||||||
* \return The BarWindow pointer
|
* \return The BarWindow pointer
|
||||||
*/
|
*/
|
||||||
BarWindow*
|
BarWindow*
|
||||||
barwin_create(Window parent,
|
barwin_create(Window parent,
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y,
|
||||||
uint w,
|
int w,
|
||||||
uint h,
|
int h,
|
||||||
uint bg,
|
uint bg,
|
||||||
char *fg,
|
char *fg,
|
||||||
Bool entermask,
|
bool entermask,
|
||||||
Bool stipple,
|
bool stipple,
|
||||||
Bool border)
|
bool border)
|
||||||
{
|
{
|
||||||
XSetWindowAttributes at;
|
XSetWindowAttributes at;
|
||||||
BarWindow *bw;
|
BarWindow *bw;
|
||||||
|
|
||||||
/* Allocate memory */
|
/* Allocate memory */
|
||||||
bw = emalloc(1, sizeof(BarWindow));
|
bw = zcalloc(sizeof(*bw));
|
||||||
|
|
||||||
/* Barwin attributes */
|
/* Barwin attributes */
|
||||||
at.override_redirect = True;
|
at.override_redirect = True;
|
||||||
@@ -80,12 +80,14 @@ barwin_create(Window parent,
|
|||||||
/* His border */
|
/* His border */
|
||||||
if(border)
|
if(border)
|
||||||
{
|
{
|
||||||
bw->bord = True;
|
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, color_enlight(bg), &at);
|
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, color_enlight(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, SHADC, &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, SHADC, &at);
|
CWIN(bw->border.right, bw->win, w - SHADH, 0, SHADH, h, 0, CWBackPixel, bg, &at);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Property */
|
/* Property */
|
||||||
@@ -95,9 +97,7 @@ barwin_create(Window parent,
|
|||||||
bw->geo.height = h;
|
bw->geo.height = h;
|
||||||
bw->bg = bg;
|
bw->bg = bg;
|
||||||
bw->fg = fg;
|
bw->fg = fg;
|
||||||
bw->border.light = color_enlight(bg);
|
FLAGAPPLY(bw->flags, stipple, StippleFlag);
|
||||||
bw->border.dark = SHADC;
|
|
||||||
bw->stipple = stipple;
|
|
||||||
bw->stipple_color = -1;
|
bw->stipple_color = -1;
|
||||||
|
|
||||||
return bw;
|
return bw;
|
||||||
@@ -108,21 +108,38 @@ barwin_create(Window parent,
|
|||||||
void
|
void
|
||||||
barwin_draw_text(BarWindow *bw, int x, int y, char *text)
|
barwin_draw_text(BarWindow *bw, int x, int y, char *text)
|
||||||
{
|
{
|
||||||
if(!text)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Background color of the text if there is stipple */
|
/* Background color of the text if there is stipple */
|
||||||
if(bw->stipple)
|
if(bw->flags & StippleFlag)
|
||||||
draw_rectangle(bw->dr, x - 4, 0, textw(text) + 8, bw->geo.height, bw->bg);
|
draw_rectangle(bw->dr, x - 4, 0, textw(text) + 8, bw->geo.height, bw->bg);
|
||||||
|
|
||||||
/* Draw text */
|
/* Draw text */
|
||||||
draw_text(bw->dr, x, y, bw->fg, 0, text);
|
draw_text(bw->dr, x, y, bw->fg, text);
|
||||||
|
|
||||||
barwin_refresh(bw);
|
barwin_refresh(bw);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
barwin_color_set(BarWindow *bw, uint bg, char *fg)
|
||||||
|
{
|
||||||
|
CHECK(bw);
|
||||||
|
|
||||||
|
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 == -1)
|
||||||
|
bw->stipple_color = getcolor(fg);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/** Delete a BarWindow
|
/** Delete a BarWindow
|
||||||
* \param bw BarWindow pointer
|
* \param bw BarWindow pointer
|
||||||
*/
|
*/
|
||||||
@@ -158,11 +175,11 @@ barwin_delete_subwin(BarWindow *bw)
|
|||||||
void
|
void
|
||||||
barwin_map(BarWindow *bw)
|
barwin_map(BarWindow *bw)
|
||||||
{
|
{
|
||||||
CHECK(!bw->mapped);
|
CHECK(!(bw->flags & MappedFlag));
|
||||||
|
|
||||||
XMapWindow(dpy, bw->win);
|
XMapWindow(dpy, bw->win);
|
||||||
|
|
||||||
bw->mapped = True;
|
bw->flags |= MappedFlag;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -188,11 +205,11 @@ barwin_map_subwin(BarWindow *bw)
|
|||||||
void
|
void
|
||||||
barwin_unmap(BarWindow *bw)
|
barwin_unmap(BarWindow *bw)
|
||||||
{
|
{
|
||||||
CHECK(bw->mapped);
|
CHECK(bw->flags & MappedFlag);
|
||||||
|
|
||||||
XUnmapWindow(dpy, bw->win);
|
XUnmapWindow(dpy, bw->win);
|
||||||
|
|
||||||
bw->mapped = False;
|
bw->flags &= ~MappedFlag;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -232,25 +249,26 @@ barwin_move(BarWindow *bw, int x, int y)
|
|||||||
* \param h Height
|
* \param h Height
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
barwin_resize(BarWindow *bw, uint w, uint h)
|
barwin_resize(BarWindow *bw, int w, int h)
|
||||||
{
|
{
|
||||||
if(!bw || (bw->geo.width == w && bw->geo.height == h))
|
if(!bw || (bw->geo.width == w && bw->geo.height == h))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bw->geo.width = w;
|
/* Frame */
|
||||||
bw->geo.height = h;
|
|
||||||
XFreePixmap(dpy, bw->dr);
|
XFreePixmap(dpy, bw->dr);
|
||||||
|
|
||||||
/* Frame */
|
|
||||||
bw->dr = XCreatePixmap(dpy, ROOT,
|
bw->dr = XCreatePixmap(dpy, ROOT,
|
||||||
w - ((bw->bord) ? SHADH : 0),
|
w - ((bw->flags & BordFlag) ? SHADH : 0),
|
||||||
h - ((bw->bord) ? SHADH : 0),
|
h - ((bw->flags & BordFlag) ? SHADH : 0),
|
||||||
DefaultDepth(dpy, SCREEN));
|
DefaultDepth(dpy, SCREEN));
|
||||||
|
|
||||||
|
bw->geo.width = w;
|
||||||
|
bw->geo.height = h;
|
||||||
|
|
||||||
XResizeWindow(dpy, bw->win, w, h);
|
XResizeWindow(dpy, bw->win, w, h);
|
||||||
|
|
||||||
/* Border */
|
/* Border */
|
||||||
if(bw->bord)
|
if(bw->flags & BordFlag)
|
||||||
{
|
{
|
||||||
XResizeWindow(dpy, bw->border.left, SHADH, h);
|
XResizeWindow(dpy, bw->border.left, SHADH, h);
|
||||||
XResizeWindow(dpy, bw->border.top, w, SHADH);
|
XResizeWindow(dpy, bw->border.top, w, SHADH);
|
||||||
@@ -269,20 +287,21 @@ barwin_refresh_color(BarWindow *bw)
|
|||||||
{
|
{
|
||||||
CHECK(bw);
|
CHECK(bw);
|
||||||
|
|
||||||
draw_rectangle(bw->dr, 0, 0, bw->geo.width, bw->geo.height, bw->bg);
|
XSetForeground(dpy, gc, bw->bg);
|
||||||
|
XFillRectangle(dpy, bw->dr, gc, 0, 0, bw->geo.width, bw->geo.height);
|
||||||
|
|
||||||
if(bw->stipple)
|
if(bw->flags & StippleFlag)
|
||||||
{
|
{
|
||||||
XSetForeground(dpy, gc_stipple, ((bw->stipple_color != -1) ? bw->stipple_color : getcolor(bw->fg)));
|
XSetForeground(dpy, gc_stipple, bw->stipple_color);
|
||||||
XFillRectangle(dpy, bw->dr, gc_stipple, 3, 2, bw->geo.width - 6, bw->geo.height - 4);
|
XFillRectangle(dpy, bw->dr, gc_stipple, 3, 2, bw->geo.width - 6, bw->geo.height - 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(bw->bord)
|
if(bw->flags & BordFlag)
|
||||||
{
|
{
|
||||||
XSetWindowBackground(dpy, bw->border.left, bw->border.light);
|
XSetWindowBackground(dpy, bw->border.left, bw->border.light);
|
||||||
XSetWindowBackground(dpy, bw->border.top, bw->border.light);
|
XSetWindowBackground(dpy, bw->border.top, bw->border.light);
|
||||||
XSetWindowBackground(dpy, bw->border.bottom, bw->border.dark);
|
XSetWindowBackground(dpy, bw->border.bottom, bw->border.dark);
|
||||||
XSetWindowBackground(dpy, bw->border.right, bw->border.dark);
|
XSetWindowBackground(dpy, bw->border.right, bw->border.dark);
|
||||||
|
|
||||||
XClearWindow(dpy, bw->border.left);
|
XClearWindow(dpy, bw->border.left);
|
||||||
XClearWindow(dpy, bw->border.top);
|
XClearWindow(dpy, bw->border.top);
|
||||||
@@ -299,8 +318,7 @@ barwin_refresh_color(BarWindow *bw)
|
|||||||
void
|
void
|
||||||
barwin_refresh(BarWindow *bw)
|
barwin_refresh(BarWindow *bw)
|
||||||
{
|
{
|
||||||
if(!bw || !bw->dr || !bw->win)
|
CHECK(bw);
|
||||||
return;
|
|
||||||
|
|
||||||
XCopyArea(dpy, bw->dr, bw->win, gc, 0, 0, bw->geo.width, bw->geo.height, 0, 0);
|
XCopyArea(dpy, bw->dr, bw->win, gc, 0, 0, bw->geo.width, bw->geo.height, 0, 0);
|
||||||
|
|
||||||
|
|||||||
279
src/cfactor.c
Normal file
279
src/cfactor.c
Normal file
@@ -0,0 +1,279 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/* Travel clients to search parents of row and apply fact */
|
||||||
|
for(cc = tiled_client(c->screen, clients); cc; cc = tiled_client(c->screen, cc->next))
|
||||||
|
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;
|
||||||
|
int e, f[4] = { 0 };
|
||||||
|
|
||||||
|
f[p] += fac;
|
||||||
|
|
||||||
|
/* Travel clients to search parents of row and check geos */
|
||||||
|
for(cc = tiled_client(c->screen, clients); cc; cc = tiled_client(c->screen, cc->next))
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
799
src/client.c
799
src/client.c
File diff suppressed because it is too large
Load Diff
223
src/color.c
Normal file
223
src/color.c
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
/*
|
||||||
|
* color.c
|
||||||
|
* Copyright © 2011 Brian Mock <mock.brian@gmail.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of the nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "wmfs.h"
|
||||||
|
|
||||||
|
/** Clamp a number x within the range [a, b].
|
||||||
|
* \param x the number which to clamp
|
||||||
|
* \param a the lowest possible value
|
||||||
|
* \param b the highest possible value
|
||||||
|
* \return the clamped number
|
||||||
|
*/
|
||||||
|
static double
|
||||||
|
color_clamp(double x, double a, double b)
|
||||||
|
{
|
||||||
|
if(x < a)
|
||||||
|
return a;
|
||||||
|
else if(x > b)
|
||||||
|
return b;
|
||||||
|
else
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Pack a triplet of RGB values into a single uint
|
||||||
|
* \param r the red value
|
||||||
|
* \param g the green value
|
||||||
|
* \param b the blue value
|
||||||
|
* \return the packed RGB value
|
||||||
|
*/
|
||||||
|
static uint
|
||||||
|
color_pack_rgb(uint r, uint g, uint b)
|
||||||
|
{
|
||||||
|
return (r << 16) | (g << 8) | b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Unpack an RGB uint into three separate values
|
||||||
|
* \param rgb the packed color
|
||||||
|
* \param r a pointer to a uint where the red value will be stored
|
||||||
|
* \param g a pointer to a uint where the green value will be stored
|
||||||
|
* \param b a pointer to a uint where the blue value will be stored
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
color_unpack_rgb(uint rgb, uint *r, uint *g, uint *b)
|
||||||
|
{
|
||||||
|
*r = (rgb >> 16) & 0xFF;
|
||||||
|
*g = (rgb >> 8) & 0xFF;
|
||||||
|
*b = rgb & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Convert unpacked RGB values into HSL, storing in the doubles referenced
|
||||||
|
* by the pointers h, s, l
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
color_rgb_to_hsl(uint xr, uint xg, uint xb, double *h, double *s, double *l)
|
||||||
|
{
|
||||||
|
double r = xr/255.0;
|
||||||
|
double g = xg/255.0;
|
||||||
|
double b = xb/255.0;
|
||||||
|
|
||||||
|
double v;
|
||||||
|
double m;
|
||||||
|
double vm;
|
||||||
|
double r2, g2, b2;
|
||||||
|
|
||||||
|
*h = 0;
|
||||||
|
*s = 0;
|
||||||
|
*l = 0;
|
||||||
|
|
||||||
|
/* v is max(r, g, b)
|
||||||
|
* m is min(r, g, b)
|
||||||
|
*/
|
||||||
|
v = r > g ? r : g;
|
||||||
|
v = v > b ? v : b;
|
||||||
|
m = r < g ? r : g;
|
||||||
|
m = m < b ? m : b;
|
||||||
|
|
||||||
|
*l = (m + v)/2.0;
|
||||||
|
|
||||||
|
if(*l <= 0.0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
vm = v - m;
|
||||||
|
*s = vm;
|
||||||
|
|
||||||
|
if(*s > 0.0)
|
||||||
|
*s /= (*l <= 0.5) ? (v + m) : (2.0 - v - m);
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
|
r2 = (v - r)/vm;
|
||||||
|
g2 = (v - g)/vm;
|
||||||
|
b2 = (v - b)/vm;
|
||||||
|
|
||||||
|
if(r == v)
|
||||||
|
*h = (g == m ? 5.0 + b2 : 1.0 - g2);
|
||||||
|
else if(g == v)
|
||||||
|
*h = (b == m ? 1.0 + r2 : 3.0 - b2);
|
||||||
|
else
|
||||||
|
*h = (r == m ? 3.0 + g2 : 5.0 - r2);
|
||||||
|
|
||||||
|
*h /= 6.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Convert h, s, l values to RGB and store them in the three uint
|
||||||
|
* referenced by the last three parameters.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
color_hsl_to_rgb(double h, double sl, double l, uint *rx, uint *gx, uint *bx)
|
||||||
|
{
|
||||||
|
double v;
|
||||||
|
double r,g,b;
|
||||||
|
|
||||||
|
r = l;
|
||||||
|
g = l;
|
||||||
|
b = l;
|
||||||
|
v = (l <= 0.5) ? (l * (1.0 + sl)) : (l + sl - l * sl);
|
||||||
|
if(v > 0)
|
||||||
|
{
|
||||||
|
double m;
|
||||||
|
double sv;
|
||||||
|
int sextant;
|
||||||
|
double fract, vsf, mid1, mid2;
|
||||||
|
|
||||||
|
m = l + l - v;
|
||||||
|
sv = (v - m ) / v;
|
||||||
|
h *= 6.0;
|
||||||
|
sextant = (int) h;
|
||||||
|
fract = h - sextant;
|
||||||
|
vsf = v * sv * fract;
|
||||||
|
mid1 = m + vsf;
|
||||||
|
mid2 = v - vsf;
|
||||||
|
switch(sextant)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
r = v;
|
||||||
|
g = mid1;
|
||||||
|
b = m;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
r = mid2;
|
||||||
|
g = v;
|
||||||
|
b = m;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
r = m;
|
||||||
|
g = v;
|
||||||
|
b = mid1;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
r = m;
|
||||||
|
g = mid2;
|
||||||
|
b = v;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
r = mid1;
|
||||||
|
g = m;
|
||||||
|
b = v;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
r = v;
|
||||||
|
g = m;
|
||||||
|
b = mid2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*rx = r * 255.0;
|
||||||
|
*gx = g * 255.0;
|
||||||
|
*bx = b * 255.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Shades a color by the amount. This works by converting a packed RGB
|
||||||
|
* color to HSL, adding the amount to the lightness,
|
||||||
|
* and then converting back to RGB. 1.0 is max lightness, 0.0 is min lightness.
|
||||||
|
* \param shadeVal the amount to shade the lightness by.
|
||||||
|
* \return the shaded color
|
||||||
|
*/
|
||||||
|
uint
|
||||||
|
color_shade(uint rgb, double shadeVal)
|
||||||
|
{
|
||||||
|
uint r, g, b;
|
||||||
|
double h, s, l;
|
||||||
|
|
||||||
|
color_unpack_rgb(rgb, &r, &g, &b);
|
||||||
|
color_rgb_to_hsl(r, g, b, &h, &s, &l);
|
||||||
|
|
||||||
|
l += shadeVal;
|
||||||
|
|
||||||
|
l = color_clamp(l, 0, 1);
|
||||||
|
|
||||||
|
color_hsl_to_rgb(h, s, l, &r, &g, &b);
|
||||||
|
rgb = color_pack_rgb(r, g, b);
|
||||||
|
|
||||||
|
return rgb;
|
||||||
|
}
|
||||||
349
src/config.c
349
src/config.c
@@ -32,19 +32,33 @@
|
|||||||
|
|
||||||
#include "wmfs.h"
|
#include "wmfs.h"
|
||||||
|
|
||||||
func_name_list_t tmp_func_list[] =
|
const func_name_list_t func_list[] =
|
||||||
{
|
{
|
||||||
{"spawn", uicb_spawn },
|
{"spawn", uicb_spawn },
|
||||||
{"client_kill", uicb_client_kill },
|
{"client_kill", uicb_client_kill },
|
||||||
{"client_prev", uicb_client_prev },
|
{"client_prev", uicb_client_focus_prev },
|
||||||
{"client_next", uicb_client_next },
|
{"client_next", uicb_client_focus_next },
|
||||||
{"client_swap_next", uicb_client_swap_next },
|
{"client_swap_next", uicb_client_swapsel_next },
|
||||||
{"client_swap_prev", uicb_client_swap_prev },
|
{"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_next", uicb_client_screen_next },
|
||||||
{"client_screen_prev", uicb_client_screen_prev },
|
{"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_move", uicb_client_move },
|
||||||
{"client_resize", uicb_client_resize },
|
{"client_resize", uicb_client_resize },
|
||||||
{"client_ignore_tag", uicb_client_ignore_tag },
|
{"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 },
|
{"toggle_max", uicb_togglemax },
|
||||||
{"layout_next", uicb_layout_next },
|
{"layout_next", uicb_layout_next },
|
||||||
{"layout_prev", uicb_layout_prev },
|
{"layout_prev", uicb_layout_prev },
|
||||||
@@ -64,10 +78,14 @@ func_name_list_t tmp_func_list[] =
|
|||||||
{"tag_swap_prev", uicb_tag_swap_previous },
|
{"tag_swap_prev", uicb_tag_swap_previous },
|
||||||
{"tag_new", uicb_tag_new },
|
{"tag_new", uicb_tag_new },
|
||||||
{"tag_del", uicb_tag_del },
|
{"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_mwfact", uicb_set_mwfact },
|
||||||
{"set_nmaster", uicb_set_nmaster },
|
{"set_nmaster", uicb_set_nmaster },
|
||||||
{"quit", uicb_quit },
|
{"quit", uicb_quit },
|
||||||
{"toggle_infobar_position", uicb_infobar_togglepos },
|
{"toggle_infobar_position", uicb_infobar_togglepos },
|
||||||
|
{"toggle_infobar_display", uicb_infobar_toggledisplay },
|
||||||
{"toggle_resizehint", uicb_toggle_resizehint },
|
{"toggle_resizehint", uicb_toggle_resizehint },
|
||||||
{"mouse_move", uicb_mouse_move },
|
{"mouse_move", uicb_mouse_move },
|
||||||
{"mouse_resize", uicb_mouse_resize },
|
{"mouse_resize", uicb_mouse_resize },
|
||||||
@@ -82,18 +100,25 @@ func_name_list_t tmp_func_list[] =
|
|||||||
{"launcher", uicb_launcher },
|
{"launcher", uicb_launcher },
|
||||||
{"set_layout", uicb_set_layout },
|
{"set_layout", uicb_set_layout },
|
||||||
{"menu", uicb_menu },
|
{"menu", uicb_menu },
|
||||||
{"set_client_layer", uicb_set_client_layer },
|
|
||||||
{"set_layer", uicb_set_layer },
|
|
||||||
{"ignore_next_client_rules", uicb_ignore_next_client_rules },
|
{"ignore_next_client_rules", uicb_ignore_next_client_rules },
|
||||||
{"check_max", uicb_checkmax },
|
{"check_max", uicb_checkmax },
|
||||||
{"check_free", uicb_checkfree },
|
{"check_free", uicb_checkfree },
|
||||||
{"check_layout", uicb_checklayout },
|
{"check_layout", uicb_checklayout },
|
||||||
{"clientlist", uicb_clientlist },
|
{"clientlist", uicb_clientlist },
|
||||||
{"check_clist", uicb_checkclist },
|
{"check_clist", uicb_checkclist },
|
||||||
{"toggle_tagautohide", uicb_toggle_tagautohide }
|
{"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}
|
||||||
};
|
};
|
||||||
|
|
||||||
key_name_list_t key_list[] =
|
static key_name_list_t key_list[] =
|
||||||
{
|
{
|
||||||
{"Control", ControlMask },
|
{"Control", ControlMask },
|
||||||
{"Shift", ShiftMask },
|
{"Shift", ShiftMask },
|
||||||
@@ -108,7 +133,7 @@ key_name_list_t key_list[] =
|
|||||||
{NULL, NoSymbol }
|
{NULL, NoSymbol }
|
||||||
};
|
};
|
||||||
|
|
||||||
name_to_uint_t mouse_button_list[] =
|
static name_to_uint_t mouse_button_list[] =
|
||||||
{
|
{
|
||||||
{"Button1", Button1 },
|
{"Button1", Button1 },
|
||||||
{"Button2", Button2 },
|
{"Button2", Button2 },
|
||||||
@@ -120,9 +145,10 @@ name_to_uint_t mouse_button_list[] =
|
|||||||
{"3", Button3 },
|
{"3", Button3 },
|
||||||
{"4", Button4 },
|
{"4", Button4 },
|
||||||
{"5", Button5 },
|
{"5", Button5 },
|
||||||
|
{NULL, NoSymbol}
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
static void
|
||||||
mouse_section(MouseBinding mb[], struct conf_sec **sec)
|
mouse_section(MouseBinding mb[], struct conf_sec **sec)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
@@ -137,29 +163,41 @@ mouse_section(MouseBinding mb[], struct conf_sec **sec)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
conf_misc_section(void)
|
conf_misc_section(void)
|
||||||
{
|
{
|
||||||
|
bool xft = False;
|
||||||
int pad = 12;
|
int pad = 12;
|
||||||
|
uint opacity = 255;
|
||||||
struct conf_sec *sec;
|
struct conf_sec *sec;
|
||||||
|
|
||||||
sec = fetch_section_first(NULL, "misc");
|
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.font = fetch_opt_first(sec, "sans-9", "font").str;
|
||||||
conf.raisefocus = fetch_opt_first(sec, "false", "raisefocus").bool;
|
conf.use_xft = fetch_opt_first(sec, (xft ? "true" : "false"), "use_xft").boolean;
|
||||||
conf.raiseswitch = fetch_opt_first(sec, "false", "raiseswitch").bool;
|
conf.raisefocus = fetch_opt_first(sec, "false", "raisefocus").boolean;
|
||||||
conf.focus_fmouse = fetch_opt_first(sec, "true", "focus_follow_mouse").bool;
|
conf.focus_fmouse = fetch_opt_first(sec, "true", "focus_follow_mouse").boolean;
|
||||||
conf.focus_pclick = fetch_opt_first(sec, "true", "focus_pointer_click").bool;
|
conf.focus_fmov = fetch_opt_first(sec, "false", "focus_follow_movement").boolean;
|
||||||
|
conf.focus_pclick = fetch_opt_first(sec, "true", "focus_pointer_click").boolean;
|
||||||
conf.status_timing = fetch_opt_first(sec, "1", "status_timing").num;
|
conf.status_timing = fetch_opt_first(sec, "1", "status_timing").num;
|
||||||
conf.status_path = fetch_opt_first(sec, "", "status_path").str;
|
conf.status_path = fetch_opt_first(sec, "", "status_path").str;
|
||||||
conf.autostart_path = fetch_opt_first(sec, "", "autostart_path").str;
|
conf.autostart_path = fetch_opt_first(sec, "", "autostart_path").str;
|
||||||
conf.autostart_command = fetch_opt_first(sec, "", "autostart_command").str;
|
conf.autostart_command = fetch_opt_first(sec, "", "autostart_command").str;
|
||||||
pad = fetch_opt_first(sec, "12", "pad").num;
|
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)
|
if(pad > 24 || pad < 1)
|
||||||
{
|
{
|
||||||
warnx("configuration : pad value (%d) incorrect.", pad);
|
warnx("configuration : pad value (%d) incorrect.", pad);
|
||||||
|
|
||||||
pad = 12;
|
pad = 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,51 +212,68 @@ conf_misc_section(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
conf_bar_section(void)
|
conf_bar_section(void)
|
||||||
{
|
{
|
||||||
struct conf_sec *bar, **mouse, *selbar;
|
struct conf_sec *bar, **mouse, *selbar, *systray;
|
||||||
char *barbg;
|
char *barbg;
|
||||||
|
int sc = screen_count();
|
||||||
|
|
||||||
bar = fetch_section_first(NULL, "bar");
|
bar = fetch_section_first(NULL, "bar");
|
||||||
|
|
||||||
conf.border.bar = fetch_opt_first(bar, "false", "border").bool;
|
conf.border.bar = fetch_opt_first(bar, "false", "border").boolean;
|
||||||
conf.bars.height = fetch_opt_first(bar, "-1", "height").num;
|
conf.bars.height = fetch_opt_first(bar, "-1", "height").num;
|
||||||
conf.colors.bar = getcolor((barbg = fetch_opt_first(bar, "#000000", "bg").str));
|
conf.colors.bar = getcolor((barbg = fetch_opt_first(bar, "#000000", "bg").str));
|
||||||
conf.colors.text = fetch_opt_first(bar, "#ffffff", "fg").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;
|
||||||
|
|
||||||
mouse = fetch_section(bar, "mouse");
|
mouse = fetch_section(bar, "mouse");
|
||||||
|
|
||||||
if ((conf.bars.nmouse = fetch_section_count(mouse)) > 0)
|
if ((conf.bars.nmouse = fetch_section_count(mouse)) > 0)
|
||||||
{
|
{
|
||||||
conf.bars.mouse = emalloc(conf.bars.nmouse, sizeof(MouseBinding));
|
conf.bars.mouse = xcalloc(conf.bars.nmouse, sizeof(MouseBinding));
|
||||||
mouse_section(conf.bars.mouse, mouse);
|
mouse_section(conf.bars.mouse, mouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(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");
|
selbar = fetch_section_first(bar, "selbar");
|
||||||
conf.bars.selbar = selbar ? True : False;
|
conf.bars.selbar = selbar ? True : False;
|
||||||
|
|
||||||
conf.selbar.bg = getcolor(fetch_opt_first(selbar, barbg, "bg").str);
|
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.fg = fetch_opt_first(selbar, conf.colors.text, "fg").str;
|
||||||
conf.selbar.maxlenght = fetch_opt_first(selbar, "-1", "max_lenght").num;
|
conf.selbar.maxlength = fetch_opt_first(selbar, "-1", "max_length").num;
|
||||||
|
|
||||||
mouse = fetch_section(selbar, "mouse");
|
mouse = fetch_section(selbar, "mouse");
|
||||||
|
|
||||||
if ((conf.selbar.nmouse = fetch_section_count(mouse)))
|
if ((conf.selbar.nmouse = fetch_section_count(mouse)))
|
||||||
{
|
{
|
||||||
conf.selbar.mouse = emalloc(conf.selbar.nmouse, sizeof(MouseBinding));
|
conf.selbar.mouse = xcalloc(conf.selbar.nmouse, sizeof(MouseBinding));
|
||||||
mouse_section(conf.selbar.mouse, mouse);
|
mouse_section(conf.selbar.mouse, mouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(mouse);
|
free(mouse);
|
||||||
free(barbg);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
conf_root_section(void)
|
conf_root_section(void)
|
||||||
{
|
{
|
||||||
struct conf_sec *root, **mouse;
|
struct conf_sec *root, **mouse;
|
||||||
@@ -231,7 +286,7 @@ conf_root_section(void)
|
|||||||
|
|
||||||
if ((conf.root.nmouse = fetch_section_count(mouse)) > 0)
|
if ((conf.root.nmouse = fetch_section_count(mouse)) > 0)
|
||||||
{
|
{
|
||||||
conf.root.mouse = emalloc(conf.root.nmouse, sizeof(MouseBinding));
|
conf.root.mouse = xcalloc(conf.root.nmouse, sizeof(MouseBinding));
|
||||||
mouse_section(conf.root.mouse, mouse);
|
mouse_section(conf.root.mouse, mouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,7 +295,7 @@ conf_root_section(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
conf_client_section(void)
|
conf_client_section(void)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
@@ -250,25 +305,36 @@ conf_client_section(void)
|
|||||||
|
|
||||||
sec = fetch_section_first(NULL, "client");
|
sec = fetch_section_first(NULL, "client");
|
||||||
|
|
||||||
conf.client_round = fetch_opt_first(sec, "true", "client_round").bool;
|
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)
|
if ((conf.client.borderheight = fetch_opt_first(sec, "1", "border_height").num) < 1)
|
||||||
conf.client.borderheight = 1;
|
conf.client.borderheight = 1;
|
||||||
|
|
||||||
conf.client.border_shadow = fetch_opt_first(sec, "false", "border_shadow").bool;
|
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").bool;
|
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.bordernormal = getcolor(fetch_opt_first(sec, "#000000", "border_normal").str);
|
||||||
conf.client.borderfocus = getcolor(fetch_opt_first(sec, "#ffffff", "border_focus").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_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.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.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").bool;
|
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");
|
mouse = fetch_section(sec, "mouse");
|
||||||
|
|
||||||
if((conf.client.nmouse = fetch_section_count(mouse)) > 0)
|
if((conf.client.nmouse = fetch_section_count(mouse)) > 0)
|
||||||
{
|
{
|
||||||
conf.client.mouse = emalloc(conf.client.nmouse, sizeof(MouseBinding));
|
conf.client.mouse = xcalloc(conf.client.nmouse, sizeof(MouseBinding));
|
||||||
mouse_section(conf.client.mouse, mouse);
|
mouse_section(conf.client.mouse, mouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,7 +346,7 @@ conf_client_section(void)
|
|||||||
conf.titlebar.fg_normal = fetch_opt_first(titlebar, "#ffffff", "fg_normal").str;
|
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.fg_focus = fetch_opt_first(titlebar, "#000000", "fg_focus").str;
|
||||||
|
|
||||||
conf.titlebar.stipple.active = fetch_opt_first(titlebar, "false", "stipple").bool;
|
conf.titlebar.stipple.active = fetch_opt_first(titlebar, "false", "stipple").boolean;
|
||||||
|
|
||||||
if(!strcmp((p = fetch_opt_first(titlebar, "-1", "stipple_normal").str), "-1"))
|
if(!strcmp((p = fetch_opt_first(titlebar, "-1", "stipple_normal").str), "-1"))
|
||||||
conf.titlebar.stipple.colors.normal = getcolor(conf.titlebar.fg_normal);
|
conf.titlebar.stipple.colors.normal = getcolor(conf.titlebar.fg_normal);
|
||||||
@@ -296,7 +362,7 @@ conf_client_section(void)
|
|||||||
|
|
||||||
if((conf.titlebar.nmouse = fetch_section_count(mouse)) > 0)
|
if((conf.titlebar.nmouse = fetch_section_count(mouse)) > 0)
|
||||||
{
|
{
|
||||||
conf.titlebar.mouse = emalloc(conf.titlebar.nmouse, sizeof(MouseBinding));
|
conf.titlebar.mouse = xcalloc(conf.titlebar.nmouse, sizeof(MouseBinding));
|
||||||
mouse_section(conf.titlebar.mouse, mouse);
|
mouse_section(conf.titlebar.mouse, mouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,7 +373,7 @@ conf_client_section(void)
|
|||||||
|
|
||||||
if((conf.titlebar.nbutton = fetch_section_count(button)) > 0)
|
if((conf.titlebar.nbutton = fetch_section_count(button)) > 0)
|
||||||
{
|
{
|
||||||
conf.titlebar.button = emalloc(conf.titlebar.nbutton, sizeof(Button));
|
conf.titlebar.button = xcalloc(conf.titlebar.nbutton, sizeof(Button));
|
||||||
for(i = 0; i < conf.titlebar.nbutton; ++i)
|
for(i = 0; i < conf.titlebar.nbutton; ++i)
|
||||||
{
|
{
|
||||||
flags = fetch_opt_first(button[i], "none", "flags").str;
|
flags = fetch_opt_first(button[i], "none", "flags").str;
|
||||||
@@ -325,7 +391,7 @@ conf_client_section(void)
|
|||||||
|
|
||||||
if((conf.titlebar.button[i].nmouse = fetch_section_count(mouse)) > 0)
|
if((conf.titlebar.button[i].nmouse = fetch_section_count(mouse)) > 0)
|
||||||
{
|
{
|
||||||
conf.titlebar.button[i].mouse = emalloc(conf.titlebar.button[i].nmouse, sizeof(MouseBinding));
|
conf.titlebar.button[i].mouse = xcalloc(conf.titlebar.button[i].nmouse, sizeof(MouseBinding));
|
||||||
mouse_section(conf.titlebar.button[i].mouse, mouse);
|
mouse_section(conf.titlebar.button[i].mouse, mouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,7 +402,7 @@ conf_client_section(void)
|
|||||||
|
|
||||||
if((conf.titlebar.button[i].nlines = fetch_section_count(line)) > 0)
|
if((conf.titlebar.button[i].nlines = fetch_section_count(line)) > 0)
|
||||||
{
|
{
|
||||||
conf.titlebar.button[i].linecoord = emalloc(conf.titlebar.button[i].nlines, sizeof(XSegment));
|
conf.titlebar.button[i].linecoord = xcalloc(conf.titlebar.button[i].nlines, sizeof(XSegment));
|
||||||
|
|
||||||
for(j = 0; j < conf.titlebar.button[i].nlines; ++j)
|
for(j = 0; j < conf.titlebar.button[i].nlines; ++j)
|
||||||
{
|
{
|
||||||
@@ -357,7 +423,7 @@ conf_client_section(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
conf_layout_section(void)
|
conf_layout_section(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -373,10 +439,13 @@ conf_layout_section(void)
|
|||||||
|
|
||||||
layouts = fetch_section_first(NULL, "layouts");
|
layouts = fetch_section_first(NULL, "layouts");
|
||||||
|
|
||||||
conf.border.layout = fetch_opt_first(layouts, "false", "border").bool;
|
conf.layout_button_width = fetch_opt_first(layouts, "O", "layout_button_width").num;
|
||||||
conf.colors.layout_fg = fetch_opt_first(layouts, "#ffffff", "fg").str;
|
conf.border.layout = fetch_opt_first(layouts, "false", "border").boolean;
|
||||||
conf.colors.layout_bg = getcolor((fetch_opt_first(layouts, "#000000", "bg").str));
|
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"))
|
if((tmp = fetch_opt_first(layouts, "menu", "system").str) && !strcmp(tmp, "menu"))
|
||||||
conf.layout_system = True;
|
conf.layout_system = True;
|
||||||
@@ -391,7 +460,7 @@ conf_layout_section(void)
|
|||||||
{
|
{
|
||||||
warnx("configuration : Too many or no layouts (%d).", conf.nlayout);
|
warnx("configuration : Too many or no layouts (%d).", conf.nlayout);
|
||||||
conf.nlayout = 1;
|
conf.nlayout = 1;
|
||||||
conf.layout[0].symbol = _strdup("TILE");
|
conf.layout[0].symbol = xstrdup("TILE");
|
||||||
conf.layout[0].func = tile;
|
conf.layout[0].func = tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -433,32 +502,71 @@ conf_layout_section(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
conf_tag_section(void)
|
conf_tag_section(void)
|
||||||
{
|
{
|
||||||
int i, j, k, l = 0, m, n, sc, count;
|
int i, j, k, l = 0, n, sc, bar_pos;
|
||||||
char *tmp;
|
char *tmp;
|
||||||
struct conf_sec *sec, **tag, **mouse;
|
char *position;
|
||||||
struct opt_type *opt;
|
struct conf_sec *sec, *def_tag, **tag, **mouse;
|
||||||
|
|
||||||
/* If there is no tag in the conf or more than
|
|
||||||
* MAXTAG (32) print an error and create only one.
|
|
||||||
*/
|
|
||||||
Tag default_tag = { "WMFS", NULL, 0, 1,
|
|
||||||
0.50, 1, False, False, False, False, IB_Top,
|
|
||||||
layout_name_to_struct(conf.layout, "tile_right", conf.nlayout, layout_list),
|
|
||||||
0, NULL, 0 };
|
|
||||||
|
|
||||||
sec = fetch_section_first(NULL, "tags");
|
sec = fetch_section_first(NULL, "tags");
|
||||||
|
|
||||||
conf.tag_round = fetch_opt_first(sec, "false", "tag_round").bool;
|
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.tagselfg = fetch_opt_first(sec, "#ffffff", "sel_fg").str;
|
||||||
conf.colors.tagselbg = getcolor(fetch_opt_first(sec, "#000000", "sel_bg").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.tagurfg = fetch_opt_first(sec, "#000000", "urgent_fg").str;
|
||||||
conf.colors.tagurbg = getcolor(fetch_opt_first(sec, "#DD1111", "urgent_bg").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_bg = getcolor(fetch_opt_first(sec, "#222222", "occupied_bg").str);
|
||||||
conf.border.tag = fetch_opt_first(sec, "false", "border").bool;
|
conf.colors.tag_occupied_fg = fetch_opt_first(sec, conf.colors.text, "occupied_fg").str;
|
||||||
conf.tagautohide = fetch_opt_first(sec, "false", "autohide").bool;
|
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 */
|
/* Mouse button action on tag */
|
||||||
conf.mouse_tag_action[TagSel] =
|
conf.mouse_tag_action[TagSel] =
|
||||||
@@ -475,10 +583,10 @@ conf_tag_section(void)
|
|||||||
sc = screen_count();
|
sc = screen_count();
|
||||||
|
|
||||||
/* Alloc all */
|
/* Alloc all */
|
||||||
conf.ntag = emalloc(sc, sizeof(int));
|
conf.ntag = xcalloc(sc, sizeof(*conf.ntag));
|
||||||
tags = emalloc(sc, sizeof(Tag*));
|
tags = xcalloc(sc, sizeof(*tags));
|
||||||
seltag = emalloc(sc, sizeof(int));
|
seltag = xcalloc(sc, sizeof(*seltag));
|
||||||
prevseltag = emalloc(sc, sizeof(int));
|
prevseltag = xcalloc(sc, sizeof(*prevseltag));
|
||||||
|
|
||||||
for(i = 0; i < sc; ++i)
|
for(i = 0; i < sc; ++i)
|
||||||
seltag[i] = 1;
|
seltag[i] = 1;
|
||||||
@@ -488,7 +596,7 @@ conf_tag_section(void)
|
|||||||
n = fetch_section_count(tag);
|
n = fetch_section_count(tag);
|
||||||
|
|
||||||
for(i = 0; i < sc; ++i)
|
for(i = 0; i < sc; ++i)
|
||||||
tags[i] = emalloc(n + 2, sizeof(Tag));
|
tags[i] = xcalloc(n + 2, sizeof(Tag));
|
||||||
|
|
||||||
for(i = 0; i < n; i++)
|
for(i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
@@ -502,14 +610,22 @@ conf_tag_section(void)
|
|||||||
((j == -1) ? ++k : --l))
|
((j == -1) ? ++k : --l))
|
||||||
{
|
{
|
||||||
++conf.ntag[k];
|
++conf.ntag[k];
|
||||||
tags[k][conf.ntag[k]].name = fetch_opt_first(tag[i], "", "name").str;
|
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], "0.65", "mwfact").fnum;
|
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], "1", "nmaster").num;
|
tags[k][conf.ntag[k]].nmaster = fetch_opt_first(tag[i], fetch_opt_first(def_tag, "1", "nmaster").str, "nmaster").num;
|
||||||
tags[k][conf.ntag[k]].resizehint = fetch_opt_first(tag[i], "false", "resizehint").bool;
|
FLAGAPPLY(tags[k][conf.ntag[k]].flags,
|
||||||
tags[k][conf.ntag[k]].abovefc = fetch_opt_first(tag[i], "false", "abovefc").bool;
|
fetch_opt_first(tag[i], fetch_opt_first(def_tag, "false", "resizehint").str, "resizehint").boolean,
|
||||||
tags[k][conf.ntag[k]].layers = 1;
|
ResizeHintFlag);
|
||||||
|
|
||||||
tmp = fetch_opt_first(tag[i], "top", "infobar_position").str;
|
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"))
|
if(!strcmp(tmp ,"none") || !strcmp(tmp, "hide") || !strcmp(tmp, "hidden"))
|
||||||
tags[k][conf.ntag[k]].barpos = IB_Hide;
|
tags[k][conf.ntag[k]].barpos = IB_Hide;
|
||||||
@@ -519,29 +635,16 @@ conf_tag_section(void)
|
|||||||
tags[k][conf.ntag[k]].barpos = IB_Top;
|
tags[k][conf.ntag[k]].barpos = IB_Top;
|
||||||
|
|
||||||
tags[k][conf.ntag[k]].layout = layout_name_to_struct(conf.layout,
|
tags[k][conf.ntag[k]].layout = layout_name_to_struct(conf.layout,
|
||||||
fetch_opt_first(tag[i], "tile_right", "layout").str,
|
fetch_opt_first(tag[i], fetch_opt_first(def_tag, "tile", "layout").str, "layout").str,
|
||||||
conf.nlayout,
|
conf.nlayout,
|
||||||
layout_list);
|
layout_list);
|
||||||
|
|
||||||
/* Clients list */
|
|
||||||
opt = fetch_opt(tag[i], "", "clients");
|
|
||||||
|
|
||||||
if ((count = fetch_opt_count(opt)))
|
|
||||||
{
|
|
||||||
tags[k][conf.ntag[k]].nclients = count;
|
|
||||||
tags[k][conf.ntag[k]].clients = emalloc(count, sizeof(char *));
|
|
||||||
for(m = 0; m < count; ++m)
|
|
||||||
tags[k][conf.ntag[k]].clients[m] = opt[m].str;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(opt);
|
|
||||||
|
|
||||||
/* Multi mouse sections */
|
/* Multi mouse sections */
|
||||||
mouse = fetch_section(tag[i], "mouse");
|
mouse = fetch_section(tag[i], "mouse");
|
||||||
|
|
||||||
if((tags[k][conf.ntag[k]].nmouse = fetch_section_count(mouse)))
|
if((tags[k][conf.ntag[k]].nmouse = fetch_section_count(mouse)))
|
||||||
{
|
{
|
||||||
tags[k][conf.ntag[k]].mouse = emalloc(tags[k][conf.ntag[k]].nmouse, sizeof(MouseBinding));
|
tags[k][conf.ntag[k]].mouse = xcalloc(tags[k][conf.ntag[k]].nmouse, sizeof(MouseBinding));
|
||||||
mouse_section(tags[k][conf.ntag[k]].mouse, mouse);
|
mouse_section(tags[k][conf.ntag[k]].mouse, mouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -563,7 +666,40 @@ conf_tag_section(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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].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)
|
conf_menu_section(void)
|
||||||
{
|
{
|
||||||
char *tmp2;
|
char *tmp2;
|
||||||
@@ -576,14 +712,14 @@ conf_menu_section(void)
|
|||||||
|
|
||||||
CHECK((conf.nmenu = fetch_section_count(set_menu)));
|
CHECK((conf.nmenu = fetch_section_count(set_menu)));
|
||||||
|
|
||||||
conf.menu = calloc(conf.nmenu, sizeof(Menu));
|
conf.menu = xcalloc(conf.nmenu, sizeof(Menu));
|
||||||
|
|
||||||
for(i = 0; i < conf.nmenu; ++i)
|
for(i = 0; i < conf.nmenu; ++i)
|
||||||
{
|
{
|
||||||
|
|
||||||
conf.menu[i].name = fetch_opt_first(set_menu[i], "menu_wname", "name").str;
|
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").bool))
|
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].x = fetch_opt_first(set_menu[i], "0", "x").num;
|
||||||
conf.menu[i].y = fetch_opt_first(set_menu[i], "0", "y").num;
|
conf.menu[i].y = fetch_opt_first(set_menu[i], "0", "y").num;
|
||||||
@@ -607,7 +743,7 @@ conf_menu_section(void)
|
|||||||
|
|
||||||
if((conf.menu[i].nitem = fetch_section_count(item)))
|
if((conf.menu[i].nitem = fetch_section_count(item)))
|
||||||
{
|
{
|
||||||
conf.menu[i].item = emalloc(conf.menu[i].nitem, sizeof(MenuItem));
|
conf.menu[i].item = xcalloc(conf.menu[i].nitem, sizeof(MenuItem));
|
||||||
for(j = 0; j < conf.menu[i].nitem; ++j)
|
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].name = fetch_opt_first(item[j], "item_wname", "name").str;
|
||||||
@@ -624,7 +760,7 @@ conf_menu_section(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
conf_launcher_section(void)
|
conf_launcher_section(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -635,13 +771,14 @@ conf_launcher_section(void)
|
|||||||
|
|
||||||
CHECK((conf.nlauncher = fetch_section_count(set_launcher)));
|
CHECK((conf.nlauncher = fetch_section_count(set_launcher)));
|
||||||
|
|
||||||
conf.launcher = emalloc(conf.nlauncher, sizeof(Launcher));
|
conf.launcher = xcalloc(conf.nlauncher, sizeof(Launcher));
|
||||||
|
|
||||||
for(i = 0; i < conf.nlauncher; ++i)
|
for(i = 0; i < conf.nlauncher; ++i)
|
||||||
{
|
{
|
||||||
conf.launcher[i].name = fetch_opt_first(set_launcher[i], "launcher", "name").str;
|
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].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].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;
|
conf.launcher[i].nhisto = 1;
|
||||||
}
|
}
|
||||||
free(set_launcher);
|
free(set_launcher);
|
||||||
@@ -649,10 +786,11 @@ conf_launcher_section(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
conf_keybind_section(void)
|
conf_keybind_section(void)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i;
|
||||||
|
size_t j;
|
||||||
struct conf_sec *sec, **ks;
|
struct conf_sec *sec, **ks;
|
||||||
struct opt_type *opt;
|
struct opt_type *opt;
|
||||||
|
|
||||||
@@ -660,7 +798,7 @@ conf_keybind_section(void)
|
|||||||
ks = fetch_section(sec, "key");
|
ks = fetch_section(sec, "key");
|
||||||
|
|
||||||
conf.nkeybind = fetch_section_count(ks);
|
conf.nkeybind = fetch_section_count(ks);
|
||||||
keys = emalloc(conf.nkeybind, sizeof(Key));
|
keys = xcalloc(conf.nkeybind, sizeof(Key));
|
||||||
|
|
||||||
for(i = 0; i < conf.nkeybind; ++i)
|
for(i = 0; i < conf.nkeybind; ++i)
|
||||||
{
|
{
|
||||||
@@ -694,26 +832,23 @@ conf_keybind_section(void)
|
|||||||
void
|
void
|
||||||
init_conf(void)
|
init_conf(void)
|
||||||
{
|
{
|
||||||
if (get_conf(conf.confpath) == -1)
|
if(get_conf(conf.confpath) == -1)
|
||||||
{
|
{
|
||||||
warnx("parsing configuration file (%s) failed.", conf.confpath);
|
warnx("parsing configuration file (%s) failed.", conf.confpath);
|
||||||
sprintf(conf.confpath, "%s/wmfs/wmfsrc", XDG_CONFIG_DIR);
|
sprintf(conf.confpath, "%s/wmfs/wmfsrc", XDG_CONFIG_DIR);
|
||||||
warnx("Use the default configuration (%s).", conf.confpath);
|
warnx("Use the default configuration (%s).", conf.confpath);
|
||||||
if (get_conf(conf.confpath) == -1)
|
if(get_conf(conf.confpath) == -1)
|
||||||
errx(1, "parsing configuration file (%s) failed.", conf.confpath);
|
errx(1, "parsing configuration file (%s) failed.", conf.confpath);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set func_list */
|
|
||||||
func_list = emalloc(LEN(tmp_func_list), sizeof(func_name_list_t));
|
|
||||||
memcpy(func_list, tmp_func_list, LEN(tmp_func_list) * sizeof(func_name_list_t));
|
|
||||||
|
|
||||||
conf_misc_section();
|
conf_misc_section();
|
||||||
conf_bar_section();
|
conf_bar_section();
|
||||||
conf_root_section();
|
conf_root_section();
|
||||||
conf_client_section();
|
conf_client_section();
|
||||||
conf_layout_section();
|
conf_layout_section();
|
||||||
conf_tag_section();
|
conf_tag_section();
|
||||||
|
conf_rule_section();
|
||||||
conf_menu_section();
|
conf_menu_section();
|
||||||
conf_launcher_section();
|
conf_launcher_section();
|
||||||
conf_keybind_section();
|
conf_keybind_section();
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* config.h
|
|
||||||
* Copyright © 2008 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 CONFIG_H
|
|
||||||
#define CONFIG_H
|
|
||||||
|
|
||||||
#include "wmfs.h"
|
|
||||||
|
|
||||||
#define WMFS_VERSION "@WMFS_VERSION@"
|
|
||||||
#define WMFS_COMPILE_MACHINE "@WMFS_COMPILE_MACHINE@"
|
|
||||||
#define WMFS_COMPILE_BY "@WMFS_COMPILE_BY@"
|
|
||||||
#define WMFS_COMPILE_FLAGS "@WMFS_COMPILE_FLAGS@"
|
|
||||||
#define WMFS_LINKED_LIBS "@WMFS_LINKED_LIBS@"
|
|
||||||
#define XDG_CONFIG_DIR "@XDG_CONFIG_DIR@"
|
|
||||||
|
|
||||||
/* Optional dependencies */
|
|
||||||
@WMFS_HAVE_XINERAMA@
|
|
||||||
@WMFS_HAVE_XRANDR@
|
|
||||||
@WMFS_HAVE_IMLIB@
|
|
||||||
|
|
||||||
#endif /* CONFIG_H */
|
|
||||||
240
src/draw.c
240
src/draw.c
@@ -32,6 +32,77 @@
|
|||||||
|
|
||||||
#include "wmfs.h"
|
#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
|
||||||
|
*\return n Lenght of i
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
parse_image_block(Drawable dr, char *str)
|
||||||
|
{
|
||||||
|
ImageAttr im;
|
||||||
|
char as;
|
||||||
|
int i, j, k;
|
||||||
|
|
||||||
|
for(i = j = 0; i < (int)strlen(str); ++i, ++j)
|
||||||
|
if(sscanf(&str[i], "\\i[%d;%d;%d;%d;%512[^]]]%c", &im.x, &im.y, &im.w, &im.h, im.name, &as) == 6
|
||||||
|
&& as == '\\')
|
||||||
|
{
|
||||||
|
draw_image(dr, im.x - sw, im.y, im.w, im.h, im.name);
|
||||||
|
|
||||||
|
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
|
/** Draw a string in a Drawable
|
||||||
* \param d Drawable
|
* \param d Drawable
|
||||||
* \param x X position
|
* \param x X position
|
||||||
@@ -41,50 +112,61 @@
|
|||||||
* \param str String that will be draw
|
* \param str String that will be draw
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
draw_text(Drawable d, int x, int y, char* fg, int pad, char *str)
|
draw_text(Drawable d, int x, int y, char* fg, char *str)
|
||||||
{
|
{
|
||||||
XftColor xftcolor;
|
CHECK(str);
|
||||||
XftDraw *xftd;
|
|
||||||
|
|
||||||
if(!str)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* To draw image everywhere we can draw text */
|
/* To draw image everywhere we can draw text */
|
||||||
#ifdef HAVE_IMLIB
|
#ifdef HAVE_IMLIB
|
||||||
char *ostr = NULL;
|
char *ostr;
|
||||||
int i, ni;
|
size_t textlen = 0;
|
||||||
ImageAttr im[128];
|
|
||||||
|
|
||||||
ostr = _strdup(str);
|
|
||||||
|
|
||||||
if(strstr(str, "i["))
|
if(strstr(str, "i["))
|
||||||
{
|
{
|
||||||
ni = parse_image_block(im, str);
|
if(d == infobar[conf.systray.screen].bar->dr)
|
||||||
|
sw = systray_get_width();
|
||||||
|
|
||||||
for(i = 0; i < ni; ++i)
|
ostr = xstrdup(str);
|
||||||
draw_image(d, im[i].x, im[i].y, im[i].w, im[i].h, im[i].name);
|
textlen = strlen(ostr);
|
||||||
|
parse_image_block(d, str);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_IMLIB */
|
#endif /* HAVE_IMLIB */
|
||||||
|
|
||||||
/* Transform X Drawable -> Xft Drawable */
|
#ifdef HAVE_XFT
|
||||||
xftd = XftDrawCreate(dpy, d, DefaultVisual(dpy, SCREEN), DefaultColormap(dpy, SCREEN));
|
if(conf.use_xft)
|
||||||
|
{
|
||||||
|
XftColor xftcolor;
|
||||||
|
XftDraw *xftd;
|
||||||
|
|
||||||
/* Alloc text color */
|
/* Transform X Drawable -> Xft Drawable */
|
||||||
XftColorAllocName(dpy, DefaultVisual(dpy, SCREEN),
|
xftd = XftDrawCreate(dpy, d, DefaultVisual(dpy, SCREEN), DefaultColormap(dpy, SCREEN));
|
||||||
DefaultColormap(dpy, SCREEN), fg, &xftcolor);
|
|
||||||
|
|
||||||
XftDrawStringUtf8(xftd, &xftcolor, font, x, y, (FcChar8 *)str, strlen(str));
|
/* Alloc text color */
|
||||||
|
XftColorAllocName(dpy, DefaultVisual(dpy, SCREEN),
|
||||||
|
DefaultColormap(dpy, SCREEN), fg, &xftcolor);
|
||||||
|
|
||||||
/* Free the text color and XftDraw */
|
XftDrawStringUtf8(xftd, &xftcolor, font.font, x, y, (FcChar8 *)str, strlen(str));
|
||||||
XftColorFree(dpy, DefaultVisual(dpy, SCREEN), DefaultColormap(dpy, SCREEN), &xftcolor);
|
|
||||||
|
/* 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));
|
||||||
|
}
|
||||||
|
|
||||||
XftDrawDestroy(xftd);
|
|
||||||
|
|
||||||
#ifdef HAVE_IMLIB
|
#ifdef HAVE_IMLIB
|
||||||
if(strstr(ostr, "i["))
|
if(textlen)
|
||||||
strcpy(str, ostr);
|
{
|
||||||
|
strncpy(str, ostr, textlen);
|
||||||
IFREE(ostr);
|
free(ostr);
|
||||||
|
}
|
||||||
#endif /* HAVE_IMLIB */
|
#endif /* HAVE_IMLIB */
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -99,12 +181,10 @@ draw_text(Drawable d, int x, int y, char* fg, int pad, char *str)
|
|||||||
* \param color Color of the rectangle
|
* \param color Color of the rectangle
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
draw_rectangle(Drawable dr, int x, int y, uint w, uint h, uint color)
|
draw_rectangle(Drawable dr, int x, int y, int w, int h, uint color)
|
||||||
{
|
{
|
||||||
XRectangle r = { x, y, w, h };
|
|
||||||
|
|
||||||
XSetForeground(dpy, gc, color);
|
XSetForeground(dpy, gc, color);
|
||||||
XFillRectangles(dpy, dr, gc, &r, 1);
|
XFillRectangle(dpy, dr, gc, x, y, (uint)w, (uint)h);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -119,64 +199,16 @@ draw_rectangle(Drawable dr, int x, int y, uint w, uint h, uint color)
|
|||||||
* \param data Array of bytes that will be draw
|
* \param data Array of bytes that will be draw
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
draw_graph(Drawable dr, int x, int y, uint w, uint h, uint color, char *data)
|
draw_graph(Drawable dr, int x, int y, int w, int h, uint color, char *data)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
XSetForeground(dpy, gc, color);
|
|
||||||
|
|
||||||
for(i = 0; i < w; ++i)
|
for(i = 0; i < w; ++i)
|
||||||
{
|
draw_rectangle(dr, x + i, y + h - data[i], 1, data[i], color);
|
||||||
XRectangle r = { (x + i), (y + h - data[i]), 1, data[i] };
|
|
||||||
|
|
||||||
XFillRectangles(dpy, dr, gc, &r, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_IMLIB
|
|
||||||
/** Draw an image in a drawable
|
|
||||||
* \param dr Drawable
|
|
||||||
* \param x X position
|
|
||||||
* \param y Y position
|
|
||||||
* \param name Path of the image
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
draw_image(Drawable dr, int x, int y, int w, int h, char *name)
|
|
||||||
{
|
|
||||||
Imlib_Image image;
|
|
||||||
|
|
||||||
if(!name)
|
|
||||||
return;
|
|
||||||
|
|
||||||
imlib_set_cache_size(2048 * 1024);
|
|
||||||
imlib_context_set_display(dpy);
|
|
||||||
imlib_context_set_visual(DefaultVisual(dpy, DefaultScreen(dpy)));
|
|
||||||
imlib_context_set_colormap(DefaultColormap(dpy, DefaultScreen(dpy)));
|
|
||||||
imlib_context_set_drawable(dr);
|
|
||||||
|
|
||||||
image = imlib_load_image(name);
|
|
||||||
imlib_context_set_image(image);
|
|
||||||
|
|
||||||
if(w <= 0)
|
|
||||||
w = imlib_image_get_width();
|
|
||||||
|
|
||||||
if(h <= 0)
|
|
||||||
h = imlib_image_get_height();
|
|
||||||
|
|
||||||
if(image)
|
|
||||||
{
|
|
||||||
imlib_render_image_on_drawable_at_size(x, y, w, h);
|
|
||||||
imlib_free_image();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
warnx("Can't draw image: '%s'", name);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif /* HAVE_IMLIB */
|
|
||||||
|
|
||||||
/** Calculates the text's size relatively to the font
|
/** Calculates the text's size relatively to the font
|
||||||
* \param text Text string
|
* \param text Text string
|
||||||
* \return final text width
|
* \return final text width
|
||||||
@@ -184,32 +216,48 @@ draw_image(Drawable dr, int x, int y, int w, int h, char *name)
|
|||||||
ushort
|
ushort
|
||||||
textw(char *text)
|
textw(char *text)
|
||||||
{
|
{
|
||||||
XGlyphInfo gl;
|
Drawable d = 0;
|
||||||
|
ushort ret = 0;
|
||||||
|
|
||||||
if(!text)
|
if(!text)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#ifdef HAVE_IMLIB
|
#ifdef HAVE_IMLIB
|
||||||
char *ostr = NULL;
|
char *ostr;
|
||||||
|
size_t textlen = 0;
|
||||||
ImageAttr im[128];
|
|
||||||
|
|
||||||
ostr = _strdup(text);
|
|
||||||
|
|
||||||
if(strstr(text, "i["))
|
if(strstr(text, "i["))
|
||||||
parse_image_block(im, text);
|
{
|
||||||
|
ostr = xstrdup(text);
|
||||||
|
textlen = strlen(ostr);
|
||||||
|
parse_image_block(d, text);
|
||||||
|
}
|
||||||
#endif /* HAVE_IMLIB */
|
#endif /* HAVE_IMLIB */
|
||||||
|
|
||||||
XftTextExtentsUtf8(dpy, font, (FcChar8 *)text, strlen(text), &gl);
|
#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
|
#ifdef HAVE_IMLIB
|
||||||
if(strstr(ostr, "i["))
|
if(textlen)
|
||||||
strcpy(text, ostr);
|
{
|
||||||
|
strncpy(text, ostr, textlen);
|
||||||
IFREE(ostr);
|
free(ostr);
|
||||||
|
}
|
||||||
#endif /* HAVE_IMLIB */
|
#endif /* HAVE_IMLIB */
|
||||||
|
|
||||||
return gl.width + font->descent;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
488
src/event.c
488
src/event.c
@@ -32,12 +32,14 @@
|
|||||||
|
|
||||||
#include "wmfs.h"
|
#include "wmfs.h"
|
||||||
|
|
||||||
|
#define EVDPY (e->xany.display)
|
||||||
|
|
||||||
/** ButtonPress handle event
|
/** ButtonPress handle event
|
||||||
* \param ev XButtonEvent pointer
|
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
buttonpress(XButtonEvent *ev)
|
buttonpress(XEvent *e)
|
||||||
{
|
{
|
||||||
|
XButtonEvent *ev = &e->xbutton;
|
||||||
Client *c;
|
Client *c;
|
||||||
int i, j, n;
|
int i, j, n;
|
||||||
|
|
||||||
@@ -65,7 +67,10 @@ buttonpress(XButtonEvent *ev)
|
|||||||
for(i = 0; i < conf.titlebar.button[n].nmouse; ++i)
|
for(i = 0; i < conf.titlebar.button[n].nmouse; ++i)
|
||||||
if(ev->button == conf.titlebar.button[n].mouse[i].button)
|
if(ev->button == conf.titlebar.button[n].mouse[i].button)
|
||||||
if(conf.titlebar.button[n].mouse[i].func)
|
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);
|
conf.titlebar.button[n].mouse[i].func(conf.titlebar.button[n].mouse[i].cmd);
|
||||||
|
}
|
||||||
|
|
||||||
/* Frame Resize Area */
|
/* Frame Resize Area */
|
||||||
if((c = client_gb_resize(ev->window)))
|
if((c = client_gb_resize(ev->window)))
|
||||||
@@ -77,6 +82,7 @@ buttonpress(XButtonEvent *ev)
|
|||||||
if(ev->button == conf.client.mouse[i].button)
|
if(ev->button == conf.client.mouse[i].button)
|
||||||
if(conf.client.mouse[i].func)
|
if(conf.client.mouse[i].func)
|
||||||
conf.client.mouse[i].func(conf.client.mouse[i].cmd);
|
conf.client.mouse[i].func(conf.client.mouse[i].cmd);
|
||||||
|
|
||||||
/* Root */
|
/* Root */
|
||||||
if(ev->window == ROOT)
|
if(ev->window == ROOT)
|
||||||
for(i = 0; i < conf.root.nmouse; ++i)
|
for(i = 0; i < conf.root.nmouse; ++i)
|
||||||
@@ -156,13 +162,14 @@ buttonpress(XButtonEvent *ev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ClientMessage handle event
|
/* ClientMessage handle event
|
||||||
*\param ev XClientMessageEvent pointer
|
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
clientmessageevent(XClientMessageEvent *ev)
|
clientmessageevent(XEvent *e)
|
||||||
{
|
{
|
||||||
|
XClientMessageEvent *ev = &e->xclient;
|
||||||
Client *c;
|
Client *c;
|
||||||
int s, i, mess_t = 0;
|
Systray *sy;
|
||||||
|
int s, mess_t = 0;
|
||||||
Atom rt;
|
Atom rt;
|
||||||
int rf;
|
int rf;
|
||||||
ulong ir, il;
|
ulong ir, il;
|
||||||
@@ -175,9 +182,8 @@ clientmessageevent(XClientMessageEvent *ev)
|
|||||||
|
|
||||||
s = screen_count();
|
s = screen_count();
|
||||||
|
|
||||||
for(i = 0; i < net_last + s; ++i)
|
while(mess_t < net_last + s && net_atom[mess_t] != ev->message_type)
|
||||||
if(net_atom[i] == ev->message_type)
|
++mess_t;
|
||||||
mess_t = i;
|
|
||||||
|
|
||||||
if(ev->window == ROOT)
|
if(ev->window == ROOT)
|
||||||
{
|
{
|
||||||
@@ -195,8 +201,28 @@ clientmessageevent(XClientMessageEvent *ev)
|
|||||||
|
|
||||||
/* Manage _NET_ACTIVE_WINDOW */
|
/* Manage _NET_ACTIVE_WINDOW */
|
||||||
else if(mess_t == net_active_window)
|
else if(mess_t == net_active_window)
|
||||||
|
{
|
||||||
if((c = client_gb_win(ev->window)))
|
if((c = client_gb_win(ev->window)))
|
||||||
client_focus(c);
|
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 */
|
/* Manage _NET_WM_STATE */
|
||||||
@@ -211,37 +237,38 @@ clientmessageevent(XClientMessageEvent *ev)
|
|||||||
|
|
||||||
/* Manage _NET_WM_DESKTOP */
|
/* Manage _NET_WM_DESKTOP */
|
||||||
if(mess_t == net_wm_desktop)
|
if(mess_t == net_wm_desktop)
|
||||||
if((c = client_gb_win(ev->window)))
|
if((c = client_gb_win(ev->window)) && ev->data.l[0] != (long)0xFFFFFFFF)
|
||||||
tag_transfert(c, ev->data.l[0]);
|
tag_transfert(c, ev->data.l[0]);
|
||||||
|
|
||||||
/* Manage _WMFS_STATUSTEXT_x */
|
if(ev->data.l[4])
|
||||||
if(mess_t >= wmfs_statustext && ev->data.l[4] == True)
|
|
||||||
{
|
{
|
||||||
if(XGetWindowProperty(dpy, ROOT, net_atom[mess_t], 0, 4096,
|
/* Manage _WMFS_STATUSTEXT_x */
|
||||||
False, net_atom[utf8_string], &rt, &rf, &ir, &il, &ret) == Success)
|
if(mess_t >= wmfs_statustext)
|
||||||
{
|
{
|
||||||
statustext_handle(mess_t - wmfs_statustext, (char*)ret);
|
if(XGetWindowProperty(EVDPY, ROOT, net_atom[mess_t], 0, 4096,
|
||||||
|
False, net_atom[utf8_string], &rt, &rf, &ir, &il, &ret) == Success)
|
||||||
|
{
|
||||||
|
statustext_handle(mess_t - wmfs_statustext, (char*)ret);
|
||||||
|
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);
|
XFree(ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Manage _WMFS_FUNCTION && _WMFS_CMD */
|
|
||||||
if((mess_t == wmfs_function && ev->data.l[4] == True)
|
|
||||||
|| (mess_t == wmfs_cmd && ev->data.l[4] == True))
|
|
||||||
{
|
|
||||||
XGetWindowProperty(dpy, ROOT, net_atom[wmfs_function], 0, 4096,
|
|
||||||
False, net_atom[utf8_string], &rt, &rf, &ir, &il, &ret);
|
|
||||||
|
|
||||||
XGetWindowProperty(dpy, 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 */
|
/* Manage _WMFS_UPDATE_HINTS */
|
||||||
if(mess_t == wmfs_update_hints)
|
if(mess_t == wmfs_update_hints)
|
||||||
{
|
{
|
||||||
@@ -250,36 +277,30 @@ clientmessageevent(XClientMessageEvent *ev)
|
|||||||
ewmh_get_client_list();
|
ewmh_get_client_list();
|
||||||
ewmh_get_desktop_names();
|
ewmh_get_desktop_names();
|
||||||
ewmh_set_desktop_geometry();
|
ewmh_set_desktop_geometry();
|
||||||
ewmh_set_workarea();
|
|
||||||
screen_count();
|
screen_count();
|
||||||
screen_get_sel();
|
screen_get_sel();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mess_t == wmfs_update_status
|
/* Manage _WMFS_UPDATE_STATUS */
|
||||||
&& estatus)
|
if(mess_t == wmfs_update_status && estatus)
|
||||||
spawn(conf.status_path);
|
spawn(conf.status_path);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** ConfigureRequest & ConfigureNotify handle events
|
/** ConfigureRequesthandle events
|
||||||
* \param ev XEvent pointer
|
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
configureevent(XConfigureRequestEvent *ev)
|
configureevent(XEvent *e)
|
||||||
{
|
{
|
||||||
|
XConfigureRequestEvent *ev = &e->xconfigurerequest;
|
||||||
XWindowChanges wc;
|
XWindowChanges wc;
|
||||||
Client *c;
|
Client *c;
|
||||||
|
|
||||||
/* Check part */
|
/* Check part */
|
||||||
if((c = client_gb_win(ev->window))
|
if(((c = client_gb_win(ev->window)) || (c = client_gb_win(ev->window)))
|
||||||
|| (c = client_gb_win(ev->window)))
|
&& (c->flags & (LMaxFlag | MaxFlag | FSSFlag)))
|
||||||
{
|
return;
|
||||||
CHECK(!(c->flags & TileFlag));
|
|
||||||
CHECK(!(c->flags & LMaxFlag));
|
|
||||||
CHECK(!(c->flags & MaxFlag));
|
|
||||||
CHECK(!(c->flags & FSSFlag));
|
|
||||||
}
|
|
||||||
|
|
||||||
if((c = client_gb_win(ev->window)))
|
if((c = client_gb_win(ev->window)))
|
||||||
{
|
{
|
||||||
@@ -292,8 +313,13 @@ configureevent(XConfigureRequestEvent *ev)
|
|||||||
if(ev->value_mask & CWHeight)
|
if(ev->value_mask & CWHeight)
|
||||||
c->geo.height = ev->height;
|
c->geo.height = ev->height;
|
||||||
|
|
||||||
if(c->flags & FreeFlag)
|
if(c->flags & FreeFlag || !(c->flags & TileFlag))
|
||||||
client_moveresize(c, c->geo, False);
|
client_moveresize(c, c->geo, False);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
client_configure(c);
|
||||||
|
arrange(c->screen, True);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -305,41 +331,57 @@ configureevent(XConfigureRequestEvent *ev)
|
|||||||
wc.sibling = ev->above;
|
wc.sibling = ev->above;
|
||||||
wc.stack_mode = ev->detail;
|
wc.stack_mode = ev->detail;
|
||||||
|
|
||||||
XConfigureWindow(dpy, ev->window, ev->value_mask, &wc);
|
XConfigureWindow(EVDPY, ev->window, ev->value_mask, &wc);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** DestroyNotify handle event
|
/** DestroyNotify handle event
|
||||||
* \param ev XDestroyWindowEvent pointer
|
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
destroynotify(XDestroyWindowEvent *ev)
|
destroynotify(XEvent *e)
|
||||||
{
|
{
|
||||||
|
XDestroyWindowEvent *ev = &e->xdestroywindow;
|
||||||
Client *c;
|
Client *c;
|
||||||
|
Systray *s;
|
||||||
|
|
||||||
if((c = client_gb_win(ev->window)))
|
if((c = client_gb_win(ev->window)))
|
||||||
{
|
{
|
||||||
client_unmanage(c);
|
client_unmanage(c);
|
||||||
XSetErrorHandler(errorhandler);
|
XSetErrorHandler(errorhandler);
|
||||||
}
|
}
|
||||||
|
else if((s = systray_find(ev->window)))
|
||||||
|
{
|
||||||
|
setwinstate(s->win, WithdrawnState);
|
||||||
|
systray_del(s);
|
||||||
|
systray_update();
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** EnterNotify handle event
|
/** EnterNotify handle event
|
||||||
* \param ev XCrossingEvent pointer
|
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
enternotify(XCrossingEvent *ev)
|
enternotify(XEvent *e)
|
||||||
{
|
{
|
||||||
|
XCrossingEvent *ev = &e->xcrossing;
|
||||||
Client *c;
|
Client *c;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if((ev->mode != NotifyNormal
|
if((ev->mode != NotifyNormal || ev->detail == NotifyInferior)
|
||||||
|| ev->detail == NotifyInferior)
|
&& ev->window != ROOT)
|
||||||
&& 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;
|
return;
|
||||||
|
|
||||||
if(conf.focus_fmouse)
|
if(conf.focus_fmouse)
|
||||||
@@ -358,11 +400,11 @@ enternotify(XCrossingEvent *ev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** ExposeEvent handle event
|
/** ExposeEvent handle event
|
||||||
* \param ev XExposeEvent pointer
|
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
expose(XExposeEvent *ev)
|
expose(XEvent *e)
|
||||||
{
|
{
|
||||||
|
XExposeEvent *ev = &e->xexpose;
|
||||||
Client *c;
|
Client *c;
|
||||||
int i, sc;
|
int i, sc;
|
||||||
|
|
||||||
@@ -388,49 +430,26 @@ expose(XExposeEvent *ev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** FocusChange handle event
|
/** FocusChange handle event
|
||||||
* \param ev XFocusChangeEvent pointer
|
|
||||||
* \return
|
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
focusin(XFocusChangeEvent *ev)
|
focusin(XEvent *e)
|
||||||
{
|
{
|
||||||
if(sel && ev->window != sel->win)
|
if(sel && e->xfocus.window != sel->win)
|
||||||
client_focus(sel);
|
client_focus(sel);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Key grabbing function
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
grabkeys(void)
|
|
||||||
{
|
|
||||||
uint i;
|
|
||||||
KeyCode code;
|
|
||||||
|
|
||||||
XUngrabKey(dpy, AnyKey, AnyModifier, ROOT);
|
|
||||||
for(i = 0; i < conf.nkeybind; ++i)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** KeyPress handle event
|
/** KeyPress handle event
|
||||||
* \param ev XKeyPressedEvent pointer
|
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
keypress(XKeyPressedEvent *ev)
|
keypress(XEvent *e)
|
||||||
{
|
{
|
||||||
uint i;
|
XKeyPressedEvent *ev = &e->xkey;
|
||||||
KeySym keysym;
|
KeySym keysym;
|
||||||
|
int i;
|
||||||
|
|
||||||
keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
|
keysym = XKeycodeToKeysym(EVDPY, (KeyCode)ev->keycode, 0);
|
||||||
for(i = 0; i < conf.nkeybind; ++i)
|
for(i = 0; i < conf.nkeybind; ++i)
|
||||||
if(keysym == keys[i].keysym
|
if(keysym == keys[i].keysym
|
||||||
&& (keys[i].mod & ~(numlockmask | LockMask))
|
&& (keys[i].mod & ~(numlockmask | LockMask))
|
||||||
@@ -441,12 +460,12 @@ keypress(XKeyPressedEvent *ev)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** MapNotify handle event
|
/** MappingNotify handle event
|
||||||
* \param ev XMappingEvent pointer
|
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
mappingnotify(XMappingEvent *ev)
|
mappingnotify(XEvent *e)
|
||||||
{
|
{
|
||||||
|
XMappingEvent *ev = &e->xmapping;
|
||||||
XRefreshKeyboardMapping(ev);
|
XRefreshKeyboardMapping(ev);
|
||||||
|
|
||||||
if(ev->request == MappingKeyboard)
|
if(ev->request == MappingKeyboard)
|
||||||
@@ -455,59 +474,88 @@ mappingnotify(XMappingEvent *ev)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** MapRequest handle event
|
/** MapNotify handle event
|
||||||
* \param ev XMapRequestEvent pointer
|
*/
|
||||||
*/
|
static void
|
||||||
void
|
mapnotify(XEvent *e)
|
||||||
maprequest(XMapRequestEvent *ev)
|
|
||||||
{
|
{
|
||||||
XWindowAttributes at;
|
XMapEvent *ev = &e->xmap;
|
||||||
Client *c;
|
Client *c;
|
||||||
|
Systray *s;
|
||||||
|
|
||||||
CHECK(XGetWindowAttributes(dpy, ev->window, &at));
|
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);
|
CHECK(!at.override_redirect);
|
||||||
|
|
||||||
if(!(c = client_gb_win(ev->window)))
|
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);
|
client_manage(ev->window, &at, True);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** PropertyNotify handle event
|
/** PropertyNotify handle event
|
||||||
* \param ev XPropertyEvent pointer
|
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
propertynotify(XPropertyEvent *ev)
|
propertynotify(XEvent *e)
|
||||||
{
|
{
|
||||||
|
XPropertyEvent *ev = &e->xproperty;
|
||||||
Client *c;
|
Client *c;
|
||||||
|
Systray *s;
|
||||||
Window trans;
|
Window trans;
|
||||||
XWMHints *h;
|
XWMHints *h;
|
||||||
|
|
||||||
if(ev->state == PropertyDelete)
|
if(ev->state == PropertyDelete)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if((s = systray_find(ev->window)))
|
||||||
|
{
|
||||||
|
systray_state(s);
|
||||||
|
systray_update();
|
||||||
|
}
|
||||||
|
|
||||||
if((c = client_gb_win(ev->window)))
|
if((c = client_gb_win(ev->window)))
|
||||||
{
|
{
|
||||||
switch(ev->atom)
|
switch(ev->atom)
|
||||||
{
|
{
|
||||||
case XA_WM_TRANSIENT_FOR:
|
case XA_WM_TRANSIENT_FOR:
|
||||||
XGetTransientForHint(dpy, c->win, &trans);
|
XGetTransientForHint(EVDPY, c->win, &trans);
|
||||||
if((c->flags & TileFlag || c->flags & MaxFlag))
|
if((c->flags & (TileFlag | MaxFlag)) && client_gb_win(trans))
|
||||||
if(((c->flags & HintFlag && (client_gb_win(trans) != NULL)))
|
arrange(c->screen, True);
|
||||||
|| (!(c->flags & HintFlag && (client_gb_win(trans) != NULL))))
|
|
||||||
arrange(c->screen, True);
|
|
||||||
break;
|
break;
|
||||||
case XA_WM_NORMAL_HINTS:
|
case XA_WM_NORMAL_HINTS:
|
||||||
client_size_hints(c);
|
client_size_hints(c);
|
||||||
break;
|
break;
|
||||||
case XA_WM_HINTS:
|
case XA_WM_HINTS:
|
||||||
if((h = XGetWMHints(dpy, c->win)) && (h->flags & XUrgencyHint) && c != sel)
|
if((h = XGetWMHints(EVDPY, c->win)) && (h->flags & XUrgencyHint) && c != sel)
|
||||||
{
|
{
|
||||||
c->flags |= UrgentFlag;
|
client_urgent(c, True);
|
||||||
|
|
||||||
tags[c->screen][c->tag].urgent = True;
|
|
||||||
infobar_draw_taglist(c->screen);
|
|
||||||
|
|
||||||
XFree(h);
|
XFree(h);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -524,13 +572,38 @@ propertynotify(XPropertyEvent *ev)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** UnmapNotify handle event
|
/** XReparentEvent handle event
|
||||||
* \param ev XUnmapEvent pointer
|
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
unmapnotify(XUnmapEvent *ev)
|
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;
|
Client *c;
|
||||||
|
Systray *s;
|
||||||
|
|
||||||
if((c = client_gb_win(ev->window))
|
if((c = client_gb_win(ev->window))
|
||||||
&& ev->send_event
|
&& ev->send_event
|
||||||
@@ -540,76 +613,111 @@ unmapnotify(XUnmapEvent *ev)
|
|||||||
XSetErrorHandler(errorhandler);
|
XSetErrorHandler(errorhandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
if((s = systray_find(ev->window)))
|
||||||
}
|
|
||||||
|
|
||||||
/** Send a client event
|
|
||||||
*\param data Event data
|
|
||||||
*\param atom_name Event atom name
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
send_client_event(long data[5], char *atom_name)
|
|
||||||
{
|
|
||||||
XEvent ev;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
ev.xclient.type = ClientMessage;
|
|
||||||
ev.xclient.serial = 0;
|
|
||||||
ev.xclient.send_event = True;
|
|
||||||
ev.xclient.message_type = ATOM(atom_name);
|
|
||||||
ev.xclient.window = ROOT;
|
|
||||||
ev.xclient.format = 32;
|
|
||||||
|
|
||||||
for(i = 0; i < 5; ++i, ev.xclient.data.l[i] = data[i]);
|
|
||||||
|
|
||||||
XSendEvent(dpy, ROOT, False, SubstructureRedirectMask | SubstructureNotifyMask, &ev);
|
|
||||||
XSync(dpy, False);
|
|
||||||
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Event handle function: execute every function
|
|
||||||
* handle by event
|
|
||||||
* \param ev Event
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
getevent(XEvent ev)
|
|
||||||
{
|
|
||||||
|
|
||||||
switch(ev.type)
|
|
||||||
{
|
{
|
||||||
case ButtonPress: buttonpress(&ev.xbutton); break;
|
systray_del(s);
|
||||||
case ClientMessage: clientmessageevent(&ev.xclient); break;
|
systray_update();
|
||||||
case ConfigureRequest: configureevent(&ev.xconfigurerequest); break;
|
|
||||||
case DestroyNotify: destroynotify(&ev.xdestroywindow); break;
|
|
||||||
case EnterNotify: enternotify(&ev.xcrossing); break;
|
|
||||||
case Expose: expose(&ev.xexpose); break;
|
|
||||||
case FocusIn: focusin(&ev.xfocus); break;
|
|
||||||
case KeyPress: keypress(&ev.xkey); break;
|
|
||||||
case MapRequest: maprequest(&ev.xmaprequest); break;
|
|
||||||
case MappingNotify: mappingnotify(&ev.xmapping); break;
|
|
||||||
case PropertyNotify: propertynotify(&ev.xproperty); break;
|
|
||||||
case UnmapNotify: unmapnotify(&ev.xunmap); break;
|
|
||||||
default:
|
|
||||||
|
|
||||||
#ifdef HAVE_XRANDR
|
|
||||||
/* Check Xrandr event */
|
|
||||||
if(ev.type == xrandr_event)
|
|
||||||
{
|
|
||||||
/* Update xrandr configuration */
|
|
||||||
XRRUpdateConfiguration(&ev);
|
|
||||||
|
|
||||||
/* Reload WMFS to update the screen(s) geometry changement */
|
|
||||||
quit();
|
|
||||||
for(; argv_global[0] && argv_global[0] == ' '; ++argv_global);
|
|
||||||
execlp(argv_global, argv_global, NULL);
|
|
||||||
}
|
|
||||||
#endif /* HAVE_XRANDR */
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wait((int[]){0});
|
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;
|
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 = LASTEvent;
|
||||||
|
|
||||||
|
#ifdef HAVE_XRANDR
|
||||||
|
i = xrandr_event + RRScreenChangeNotify;
|
||||||
|
#endif /* HAVE_XRANDR */
|
||||||
|
|
||||||
|
event_handle = xcalloc((nevent = i + 1), 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
151
src/ewmh.c
151
src/ewmh.c
@@ -43,12 +43,14 @@ void
|
|||||||
ewmh_init_hints(void)
|
ewmh_init_hints(void)
|
||||||
{
|
{
|
||||||
int i = 1, s, j, showing_desk = 0;
|
int i = 1, s, j, showing_desk = 0;
|
||||||
char root_name[] = WMFS_VERSION;
|
char rootn[] = "wmfs-"WMFS_VERSION;
|
||||||
char class[] = "wmfs", st[64];
|
char class[] = "wmfs", st[64];
|
||||||
long pid = (long)getpid();
|
long pid = (long)getpid();
|
||||||
|
char systray_atom[48];
|
||||||
|
|
||||||
|
|
||||||
s = screen_count();
|
s = screen_count();
|
||||||
net_atom = emalloc(net_last + s, sizeof(Atom));
|
net_atom = xcalloc(net_last + s, sizeof(Atom));
|
||||||
|
|
||||||
/* EWMH hints */
|
/* EWMH hints */
|
||||||
net_atom[net_supported] = ATOM("_NET_SUPPORTED");
|
net_atom[net_supported] = ATOM("_NET_SUPPORTED");
|
||||||
@@ -58,7 +60,6 @@ ewmh_init_hints(void)
|
|||||||
net_atom[net_current_desktop] = ATOM("_NET_CURRENT_DESKTOP");
|
net_atom[net_current_desktop] = ATOM("_NET_CURRENT_DESKTOP");
|
||||||
net_atom[net_desktop_names] = ATOM("_NET_DESKTOP_NAMES");
|
net_atom[net_desktop_names] = ATOM("_NET_DESKTOP_NAMES");
|
||||||
net_atom[net_desktop_geometry] = ATOM("_NET_DESKTOP_GEOMETRY");
|
net_atom[net_desktop_geometry] = ATOM("_NET_DESKTOP_GEOMETRY");
|
||||||
net_atom[net_workarea] = ATOM("_NET_WORKAREA");
|
|
||||||
net_atom[net_active_window] = ATOM("_NET_ACTIVE_WINDOW");
|
net_atom[net_active_window] = ATOM("_NET_ACTIVE_WINDOW");
|
||||||
net_atom[net_close_window] = ATOM("_NET_CLOSE_WINDOW");
|
net_atom[net_close_window] = ATOM("_NET_CLOSE_WINDOW");
|
||||||
net_atom[net_wm_name] = ATOM("_NET_WM_NAME");
|
net_atom[net_wm_name] = ATOM("_NET_WM_NAME");
|
||||||
@@ -68,6 +69,7 @@ ewmh_init_hints(void)
|
|||||||
net_atom[net_wm_icon_name] = ATOM("_NET_WM_ICON_NAME");
|
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_wm_window_type] = ATOM("_NET_WM_WINDOW_TYPE");
|
||||||
net_atom[net_supporting_wm_check] = ATOM("_NET_SUPPORTING_WM_CHECK");
|
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_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_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_splash] = ATOM("_NET_WM_WINDOW_TYPE_SPLASH");
|
||||||
@@ -75,7 +77,19 @@ ewmh_init_hints(void)
|
|||||||
net_atom[net_wm_icon] = ATOM("_NET_WM_ICON");
|
net_atom[net_wm_icon] = ATOM("_NET_WM_ICON");
|
||||||
net_atom[net_wm_state] = ATOM("_NET_WM_STATE");
|
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_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_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");
|
net_atom[utf8_string] = ATOM("UTF8_STRING");
|
||||||
|
|
||||||
/* WMFS hints */
|
/* WMFS hints */
|
||||||
@@ -92,6 +106,7 @@ ewmh_init_hints(void)
|
|||||||
net_atom[wmfs_nmaster] = ATOM("_WMFS_NMASTER");
|
net_atom[wmfs_nmaster] = ATOM("_WMFS_NMASTER");
|
||||||
net_atom[wmfs_function] = ATOM("_WMFS_FUNCTION");
|
net_atom[wmfs_function] = ATOM("_WMFS_FUNCTION");
|
||||||
net_atom[wmfs_cmd] = ATOM("_WMFS_CMD");
|
net_atom[wmfs_cmd] = ATOM("_WMFS_CMD");
|
||||||
|
net_atom[wmfs_font] = ATOM("_WMFS_FONT");
|
||||||
|
|
||||||
/* Multi atom _WMFS_STATUSTEXT_<screennum> */
|
/* Multi atom _WMFS_STATUSTEXT_<screennum> */
|
||||||
for(j = 0; j < s; ++j)
|
for(j = 0; j < s; ++j)
|
||||||
@@ -111,7 +126,7 @@ ewmh_init_hints(void)
|
|||||||
PropModeReplace, (uchar*)&ROOT, 1);
|
PropModeReplace, (uchar*)&ROOT, 1);
|
||||||
|
|
||||||
XChangeProperty(dpy, ROOT, net_atom[net_wm_name], net_atom[utf8_string], 8,
|
XChangeProperty(dpy, ROOT, net_atom[net_wm_name], net_atom[utf8_string], 8,
|
||||||
PropModeReplace, (uchar*)&root_name, strlen(root_name));
|
PropModeReplace, (uchar*)&rootn, strlen(rootn));
|
||||||
|
|
||||||
XChangeProperty(dpy, ROOT, ATOM("WM_CLASS"), XA_STRING, 8,
|
XChangeProperty(dpy, ROOT, ATOM("WM_CLASS"), XA_STRING, 8,
|
||||||
PropModeReplace, (uchar*)&class, strlen(class));
|
PropModeReplace, (uchar*)&class, strlen(class));
|
||||||
@@ -127,6 +142,54 @@ ewmh_init_hints(void)
|
|||||||
return;
|
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)
|
/** Get the number of desktop (tag)
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
@@ -191,7 +254,7 @@ ewmh_get_client_list(void)
|
|||||||
int win_n;
|
int win_n;
|
||||||
|
|
||||||
for(win_n = 0, c = clients; c; c = c->next, ++win_n);
|
for(win_n = 0, c = clients; c; c = c->next, ++win_n);
|
||||||
list = emalloc(win_n, sizeof(Window));
|
list = xcalloc(win_n, sizeof(Window));
|
||||||
|
|
||||||
for(win_n = 0, c = clients; c; c = c->next, ++win_n)
|
for(win_n = 0, c = clients; c; c = c->next, ++win_n)
|
||||||
list[win_n] = c->win;
|
list[win_n] = c->win;
|
||||||
@@ -218,7 +281,7 @@ ewmh_get_desktop_names(void)
|
|||||||
for(i = 1; i < conf.ntag[s] + 1; ++i)
|
for(i = 1; i < conf.ntag[s] + 1; ++i)
|
||||||
len += strlen(tags[s][i].name);
|
len += strlen(tags[s][i].name);
|
||||||
|
|
||||||
str = emalloc(len + i + 1, sizeof(char*));
|
str = xcalloc(len + i + 1, sizeof(char*));
|
||||||
|
|
||||||
for(s = 0; s < S; ++s)
|
for(s = 0; s < S; ++s)
|
||||||
for(i = 1; i < conf.ntag[s] + 1; ++i, ++pos)
|
for(i = 1; i < conf.ntag[s] + 1; ++i, ++pos)
|
||||||
@@ -257,45 +320,13 @@ ewmh_set_desktop_geometry(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Manage _NET_WORKAREA
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
ewmh_set_workarea(void)
|
|
||||||
{
|
|
||||||
long *data;
|
|
||||||
int i, s, j, tag_c = 0, pos = 0;
|
|
||||||
|
|
||||||
s = screen_count();
|
|
||||||
|
|
||||||
for(i = 0; i < s; ++i)
|
|
||||||
tag_c += conf.ntag[i];
|
|
||||||
|
|
||||||
data = emalloc(tag_c * 4, sizeof(long));
|
|
||||||
|
|
||||||
for(i = 0; i < s; ++i)
|
|
||||||
for(j = 0; j < conf.ntag[i]; ++j)
|
|
||||||
{
|
|
||||||
data[pos++] = spgeo[i].x;
|
|
||||||
data[pos++] = spgeo[i].y;
|
|
||||||
data[pos++] = spgeo[i].width;
|
|
||||||
data[pos++] = spgeo[i].height;
|
|
||||||
}
|
|
||||||
|
|
||||||
XChangeProperty(dpy, ROOT, net_atom[net_workarea], XA_CARDINAL, 32,
|
|
||||||
PropModeReplace, (uchar*)data, 4 * tag_c);
|
|
||||||
|
|
||||||
free(data);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Manage _NET_WM_STATE_* ewmh
|
/** Manage _NET_WM_STATE_* ewmh
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ewmh_manage_net_wm_state(long data_l[], Client *c)
|
ewmh_manage_net_wm_state(long data_l[], Client *c)
|
||||||
{
|
{
|
||||||
/* Manage _NET_WM_STATE_FULLSCREEN */
|
/* Manage _NET_WM_STATE_FULLSCREEN */
|
||||||
if(data_l[1] == net_atom[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))
|
if(data_l[0] == _NET_WM_STATE_ADD && !(c->flags & FSSFlag))
|
||||||
{
|
{
|
||||||
@@ -306,6 +337,8 @@ ewmh_manage_net_wm_state(long data_l[], Client *c)
|
|||||||
XResizeWindow(dpy, c->win,
|
XResizeWindow(dpy, c->win,
|
||||||
spgeo[c->screen].width,
|
spgeo[c->screen].width,
|
||||||
spgeo[c->screen].height);
|
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;
|
c->tmp_geo = c->geo;
|
||||||
|
|
||||||
@@ -320,17 +353,25 @@ ewmh_manage_net_wm_state(long data_l[], Client *c)
|
|||||||
}
|
}
|
||||||
else if(data_l[0] == _NET_WM_STATE_REMOVE && (c->flags & FSSFlag))
|
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);
|
c->flags &= ~(FSSFlag | MaxFlag);
|
||||||
client_map(c);
|
client_map(c);
|
||||||
XReparentWindow(dpy, c->win, c->frame, BORDH, TBARH);
|
XReparentWindow(dpy, c->win, c->frame, BORDH, TBARH);
|
||||||
client_moveresize(c, c->tmp_geo, False);
|
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 */
|
/* Manage _NET_WM_STATE_DEMANDS_ATTENTION */
|
||||||
else if(data_l[1] == net_atom[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)
|
if(data_l[0] == _NET_WM_STATE_ADD)
|
||||||
client_focus(c);
|
client_urgent(c, True);
|
||||||
if(data_l[0] == _NET_WM_STATE_REMOVE)
|
if(data_l[0] == _NET_WM_STATE_REMOVE)
|
||||||
if(c == sel)
|
if(c == sel)
|
||||||
client_focus(NULL);
|
client_focus(NULL);
|
||||||
@@ -347,9 +388,10 @@ void
|
|||||||
ewmh_manage_window_type(Client *c)
|
ewmh_manage_window_type(Client *c)
|
||||||
{
|
{
|
||||||
Atom *atom, rf;
|
Atom *atom, rf;
|
||||||
int i, f;
|
int f;
|
||||||
ulong n, il;
|
ulong n, il, i;
|
||||||
uchar *data = NULL;
|
uchar *data = NULL;
|
||||||
|
long ldata[5] = { 0 };
|
||||||
|
|
||||||
if(XGetWindowProperty(dpy, c->win, net_atom[net_wm_window_type], 0L, 0x7FFFFFFFL,
|
if(XGetWindowProperty(dpy, c->win, net_atom[net_wm_window_type], 0L, 0x7FFFFFFFL,
|
||||||
False, XA_ATOM, &rf, &f, &n, &il, &data) == Success && n)
|
False, XA_ATOM, &rf, &f, &n, &il, &data) == Success && n)
|
||||||
@@ -372,23 +414,36 @@ ewmh_manage_window_type(Client *c)
|
|||||||
XReparentWindow(dpy, c->win, ROOT, c->geo.x, c->geo.y);
|
XReparentWindow(dpy, c->win, ROOT, c->geo.x, c->geo.y);
|
||||||
XRaiseWindow(dpy, c->win);
|
XRaiseWindow(dpy, c->win);
|
||||||
|
|
||||||
/* This window will not be managed anymore,
|
c->flags |= DockFlag;
|
||||||
* so let's detach it. */
|
|
||||||
client_detach(c);
|
|
||||||
}
|
}
|
||||||
/* MANAGE _NET_WM_WINDOW_TYPE_DIALOG */
|
/* MANAGE _NET_WM_WINDOW_TYPE_DIALOG */
|
||||||
else if(atom[i] == net_atom[net_wm_window_type_dialog])
|
else if(atom[i] == net_atom[net_wm_window_type_dialog])
|
||||||
{
|
{
|
||||||
c->flags |= FreeFlag;
|
c->flags |= FreeFlag;
|
||||||
c->flags &= ~(TileFlag | MaxFlag | LMaxFlag);
|
c->flags &= ~(TileFlag | MaxFlag | LMaxFlag);
|
||||||
client_moveresize(sel, sel->ogeo, True);
|
client_moveresize(c, c->ogeo, True);
|
||||||
client_focus(c);
|
client_focus(c);
|
||||||
tags[selscreen][seltag[selscreen]].layout.func(selscreen);
|
layout_func(selscreen, seltag[selscreen]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
XFree(data);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
83
src/frame.c
83
src/frame.c
@@ -83,12 +83,12 @@ frame_create(Client *c)
|
|||||||
/* Buttons */
|
/* Buttons */
|
||||||
if(BUTTONWH >= 1)
|
if(BUTTONWH >= 1)
|
||||||
{
|
{
|
||||||
c->button = emalloc(conf.titlebar.nbutton, sizeof(Window));
|
c->button = xcalloc(conf.titlebar.nbutton, sizeof(Window));
|
||||||
for(i = 0; i < conf.titlebar.nbutton; ++i)
|
for(i = 0; i < conf.titlebar.nbutton; ++i)
|
||||||
{
|
{
|
||||||
CWIN(c->button[i], c->titlebar->win,
|
CWIN(c->button[i], c->titlebar->win,
|
||||||
(c->button_last_x = (BORDH + (BUTTONWH * i) + (4 * i))),
|
(c->button_last_x = (BORDH + (BUTTONWH * i) + (i << 2))),
|
||||||
((BUTTONWH - 1) / 2), BUTTONWH, BUTTONWH,
|
((BUTTONWH - 1) >> 1), BUTTONWH, BUTTONWH,
|
||||||
1, CWEventMask|CWOverrideRedirect|CWBackPixmap,
|
1, CWEventMask|CWOverrideRedirect|CWBackPixmap,
|
||||||
c->colors.frame, &at);
|
c->colors.frame, &at);
|
||||||
|
|
||||||
@@ -118,10 +118,13 @@ frame_create(Client *c)
|
|||||||
/* Border (for shadow) */
|
/* Border (for shadow) */
|
||||||
if(conf.client.border_shadow)
|
if(conf.client.border_shadow)
|
||||||
{
|
{
|
||||||
CWIN(c->left, c->frame, 0, 0, SHADH, c->frame_geo.height, 0, CWBackPixel, color_enlight(c->colors.frame), &at);
|
c->colors.borddark = color_shade(c->colors.frame, conf.colors.client_dark_shade);
|
||||||
CWIN(c->top, c->frame, 0, 0, c->frame_geo.width, SHADH, 0, CWBackPixel, color_enlight(c->colors.frame), &at);
|
c->colors.bordlight = color_shade(c->colors.frame, conf.colors.client_light_shade);
|
||||||
CWIN(c->bottom, c->frame, 0, c->frame_geo.height - SHADH, c->frame_geo.width, SHADH, 0, CWBackPixel, SHADC, &at);
|
|
||||||
CWIN(c->right, c->frame, c->frame_geo.width - SHADH, 0, SHADH, c->frame_geo.height, 0, CWBackPixel, SHADC, &at);
|
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 */
|
/* Reparent window with the frame */
|
||||||
@@ -155,7 +158,7 @@ frame_delete(Client *c)
|
|||||||
* \param geo Coordinate info for move the frame
|
* \param geo Coordinate info for move the frame
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
frame_moveresize(Client *c, XRectangle geo)
|
frame_moveresize(Client *c, Geo geo)
|
||||||
{
|
{
|
||||||
CHECK(c);
|
CHECK(c);
|
||||||
|
|
||||||
@@ -191,6 +194,44 @@ frame_moveresize(Client *c, XRectangle geo)
|
|||||||
return;
|
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
|
/** Update the client frame; Set the new color
|
||||||
* and the title --> refresh
|
* and the title --> refresh
|
||||||
* \param c Client pointer
|
* \param c Client pointer
|
||||||
@@ -213,8 +254,8 @@ frame_update(Client *c)
|
|||||||
if(conf.titlebar.nbutton && BUTTONWH >= 1)
|
if(conf.titlebar.nbutton && BUTTONWH >= 1)
|
||||||
{
|
{
|
||||||
if(conf.titlebar.stipple.active)
|
if(conf.titlebar.stipple.active)
|
||||||
draw_rectangle(c->titlebar->dr, 0, 0, c->button_last_x + TBARH - (TBARH / 4),
|
draw_rectangle(c->titlebar->dr, 0, 0, c->button_last_x + TBARH - (TBARH >> 2),
|
||||||
TBARH + BORDH * 2, c->colors.frame);
|
TBARH + (BORDH << 2), c->colors.frame);
|
||||||
|
|
||||||
for(i = 0; i < conf.titlebar.nbutton; ++i)
|
for(i = 0; i < conf.titlebar.nbutton; ++i)
|
||||||
{
|
{
|
||||||
@@ -222,8 +263,10 @@ frame_update(Client *c)
|
|||||||
XClearWindow(dpy, c->button[i]);
|
XClearWindow(dpy, c->button[i]);
|
||||||
|
|
||||||
if((!conf.titlebar.button[i].flags)
|
if((!conf.titlebar.button[i].flags)
|
||||||
|| ((conf.titlebar.button[i].flags & FreeFlag) && (c->flags & FreeFlag))
|
|| ((conf.titlebar.button[i].flags & FreeFlag)
|
||||||
|| ((conf.titlebar.button[i].flags & MaxFlag) && (c->flags & MaxFlag))
|
&& ((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)))
|
|| ((conf.titlebar.button[i].flags & TileFlag) && (c->flags & TileFlag)))
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -242,8 +285,6 @@ frame_update(Client *c)
|
|||||||
XSetWindowBorder(dpy, c->button[i], c->colors.frame);
|
XSetWindowBorder(dpy, c->button[i], c->colors.frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
barwin_refresh(c->titlebar);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XSetWindowBackground(dpy, c->frame, c->colors.frame);
|
XSetWindowBackground(dpy, c->frame, c->colors.frame);
|
||||||
@@ -256,10 +297,10 @@ frame_update(Client *c)
|
|||||||
|
|
||||||
if(conf.client.border_shadow)
|
if(conf.client.border_shadow)
|
||||||
{
|
{
|
||||||
XSetWindowBackground(dpy, c->left, color_enlight(c->colors.frame));
|
XSetWindowBackground(dpy, c->left, c->colors.bordlight);
|
||||||
XSetWindowBackground(dpy, c->top, color_enlight(c->colors.frame));
|
XSetWindowBackground(dpy, c->top, c->colors.bordlight);
|
||||||
XSetWindowBackground(dpy, c->right, SHADC);
|
XSetWindowBackground(dpy, c->right, c->colors.borddark);
|
||||||
XSetWindowBackground(dpy, c->bottom, SHADC);
|
XSetWindowBackground(dpy, c->bottom, c->colors.borddark);
|
||||||
|
|
||||||
XClearWindow(dpy, c->left);
|
XClearWindow(dpy, c->left);
|
||||||
XClearWindow(dpy, c->top);
|
XClearWindow(dpy, c->top);
|
||||||
@@ -269,9 +310,9 @@ frame_update(Client *c)
|
|||||||
|
|
||||||
if(TBARH - BORDH)
|
if(TBARH - BORDH)
|
||||||
barwin_draw_text(c->titlebar,
|
barwin_draw_text(c->titlebar,
|
||||||
(c->frame_geo.width / 2) - (textw(c->title) / 2),
|
(c->frame_geo.width >> 1) - (textw(c->title) >> 1),
|
||||||
((font->height - font->descent) + (TBARH - font->height) / 2),
|
((font.height - font.de) + ((TBARH - font.height) >> 1)),
|
||||||
c->title);
|
c->title);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
207
src/getinfo.c
207
src/getinfo.c
@@ -1,207 +0,0 @@
|
|||||||
/*
|
|
||||||
* getinfo.c
|
|
||||||
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are
|
|
||||||
* met:
|
|
||||||
*
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above
|
|
||||||
* copyright notice, this list of conditions and the following disclaimer
|
|
||||||
* in the documentation and/or other materials provided with the
|
|
||||||
* distribution.
|
|
||||||
* * Neither the name of the nor the names of its
|
|
||||||
* contributors may be used to endorse or promote products derived from
|
|
||||||
* this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "wmfs.h"
|
|
||||||
|
|
||||||
/* Global variables for each XGetWindowProperty
|
|
||||||
* of each getinfo functions.
|
|
||||||
*/
|
|
||||||
Atom rt;
|
|
||||||
int rf;
|
|
||||||
ulong ir, il;
|
|
||||||
uchar *ret;
|
|
||||||
|
|
||||||
/** Get information about tag (current, list, names)
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
getinfo_tag(void)
|
|
||||||
{
|
|
||||||
int tag = 0;
|
|
||||||
char *tag_name = NULL;
|
|
||||||
char *tag_list = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
if(XGetWindowProperty(dpy, ROOT, ATOM("_NET_CURRENT_DESKTOP"), 0L, 4096,
|
|
||||||
False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret) == Success && ret)
|
|
||||||
{
|
|
||||||
tag = (int)*ret + 1;
|
|
||||||
XFree(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(XGetWindowProperty(dpy, ROOT, ATOM("_WMFS_CURRENT_TAG"), 0L, 4096,
|
|
||||||
False, ATOM("UTF8_STRING"), &rt, &rf, &ir, &il, &ret) == Success && ret)
|
|
||||||
{
|
|
||||||
tag_name = _strdup((char*)ret);
|
|
||||||
XFree(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(XGetWindowProperty(dpy, ROOT, ATOM("_WMFS_TAG_LIST"), 0L, 4096,
|
|
||||||
False, ATOM("UTF8_STRING"), &rt, &rf, &ir, &il, &ret) == Success && ret)
|
|
||||||
{
|
|
||||||
tag_list = _strdup((char*)ret);
|
|
||||||
XFree(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Current tag: %d - %s\n", tag, tag_name);
|
|
||||||
printf("Tag list: %s\n", tag_list);
|
|
||||||
|
|
||||||
IFREE(tag_name);
|
|
||||||
IFREE(tag_list);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get information about screens
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
getinfo_screen(void)
|
|
||||||
{
|
|
||||||
int screen = 1;
|
|
||||||
int screen_num = 1;
|
|
||||||
|
|
||||||
if(XGetWindowProperty(dpy, ROOT, ATOM("_WMFS_CURRENT_SCREEN"), 0L, 4096,
|
|
||||||
False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret) == Success && ret)
|
|
||||||
{
|
|
||||||
screen = (int)*ret + 1;
|
|
||||||
XFree(ret);
|
|
||||||
}
|
|
||||||
if(XGetWindowProperty(dpy, ROOT, ATOM("_WMFS_SCREEN_COUNT"), 0L, 4096,
|
|
||||||
False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret) == Success && ret)
|
|
||||||
{
|
|
||||||
screen_num = (int)*ret;
|
|
||||||
XFree(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Current screen: %d\nScreen number: %d\n", screen, screen_num);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get current layout name
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
getinfo_layout(void)
|
|
||||||
{
|
|
||||||
char *layout = NULL;
|
|
||||||
|
|
||||||
if(XGetWindowProperty(dpy, ROOT, ATOM("_WMFS_CURRENT_LAYOUT"), 0L, 4096,
|
|
||||||
False, ATOM("UTF8_STRING"), &rt, &rf, &ir, &il, &ret) == Success && ret)
|
|
||||||
{
|
|
||||||
layout = _strdup((char*)ret);
|
|
||||||
XFree(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Current layout: %s\n", layout);
|
|
||||||
|
|
||||||
IFREE(layout);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get information about current mwfact
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
getinfo_mwfact(void)
|
|
||||||
{
|
|
||||||
char *mwfact = NULL;
|
|
||||||
|
|
||||||
if(XGetWindowProperty(dpy, ROOT, ATOM("_WMFS_MWFACT"), 0L, 4096,
|
|
||||||
False, XA_STRING, &rt, &rf, &ir, &il, &ret) == Success && ret)
|
|
||||||
{
|
|
||||||
mwfact = _strdup((char*)ret);
|
|
||||||
XFree(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Current mwfact: %s\n", mwfact);
|
|
||||||
|
|
||||||
IFREE(mwfact);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get information about current nmaster
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
getinfo_nmaster(void)
|
|
||||||
{
|
|
||||||
int nmaster = 1;
|
|
||||||
|
|
||||||
if(XGetWindowProperty(dpy, ROOT, ATOM("_WMFS_NMASTER"), 0L, 4096,
|
|
||||||
False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret) == Success && ret)
|
|
||||||
{
|
|
||||||
nmaster = (int)*ret;
|
|
||||||
XFree(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Current nmaster: %d\n", nmaster);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get information about wmfs
|
|
||||||
*\param info Type of information in a string
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
getinfo(char *info)
|
|
||||||
{
|
|
||||||
long data[5];
|
|
||||||
|
|
||||||
if(!check_wmfs_running())
|
|
||||||
return;
|
|
||||||
|
|
||||||
data[4] = True;
|
|
||||||
|
|
||||||
send_client_event(data, "_WMFS_UPDATE_HINTS");
|
|
||||||
|
|
||||||
if(!strcmp(info, "tag"))
|
|
||||||
getinfo_tag();
|
|
||||||
else if(!strcmp(info, "screen"))
|
|
||||||
getinfo_screen();
|
|
||||||
else if(!strcmp(info, "layout"))
|
|
||||||
getinfo_layout();
|
|
||||||
else if(!strcmp(info, "mwfact"))
|
|
||||||
getinfo_mwfact();
|
|
||||||
else if(!strcmp(info, "nmaster"))
|
|
||||||
getinfo_nmaster();
|
|
||||||
else if(!strcmp(info, "help"))
|
|
||||||
printf("Argument list for wmfs -g options:\n"
|
|
||||||
" tag Show current tag number and name, and tag list.\n"
|
|
||||||
" screen Show current screen and screens number.\n"
|
|
||||||
" layout Show current layout name.\n"
|
|
||||||
" mwfact Show mwfact of current tag.\n"
|
|
||||||
" nmaster Show nmaster of current tag.\n");
|
|
||||||
else
|
|
||||||
warnx("Unknow info argument '%s'\nTry 'wmfs -g help'", info);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
259
src/infobar.c
259
src/infobar.c
@@ -32,7 +32,9 @@
|
|||||||
|
|
||||||
#include "wmfs.h"
|
#include "wmfs.h"
|
||||||
|
|
||||||
/** Init the Infobar
|
#define SPLIT_IND_S (3 + conf.border.layout)
|
||||||
|
|
||||||
|
/** Init the InfoBar
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
infobar_init(void)
|
infobar_init(void)
|
||||||
@@ -42,19 +44,20 @@ infobar_init(void)
|
|||||||
s = screen_count();
|
s = screen_count();
|
||||||
|
|
||||||
if(!infobar)
|
if(!infobar)
|
||||||
infobar = emalloc(s, sizeof(InfoBar));
|
infobar = xcalloc(s, sizeof(InfoBar));
|
||||||
|
|
||||||
for(sc = 0; sc < s; ++sc)
|
for(sc = 0; sc < s; ++sc)
|
||||||
{
|
{
|
||||||
j = 0;
|
j = 0;
|
||||||
infobar[sc].geo.height = INFOBARH;
|
infobar[sc].geo.height = INFOBARH;
|
||||||
|
infobar[sc].screen = sc;
|
||||||
|
|
||||||
switch(tags[sc][seltag[sc]].barpos)
|
switch(tags[sc][seltag[sc]].barpos)
|
||||||
{
|
{
|
||||||
case IB_Hide:
|
case IB_Hide:
|
||||||
sgeo[sc].y = spgeo[sc].y + TBARH;
|
sgeo[sc].y = spgeo[sc].y + TBARH;
|
||||||
sgeo[sc].height += INFOBARH;
|
sgeo[sc].height += INFOBARH;
|
||||||
infobar[sc].geo.y = -(infobar[sc].geo.height) * 2;
|
infobar[sc].geo.y = (-(infobar[sc].geo.height) << 2);
|
||||||
break;
|
break;
|
||||||
case IB_Bottom:
|
case IB_Bottom:
|
||||||
sgeo[sc].y = TBARH;
|
sgeo[sc].y = TBARH;
|
||||||
@@ -94,8 +97,8 @@ infobar_init(void)
|
|||||||
|
|
||||||
/* Create layout switch barwindow */
|
/* Create layout switch barwindow */
|
||||||
infobar[sc].layout_button = barwin_create(infobar[sc].bar->win,
|
infobar[sc].layout_button = barwin_create(infobar[sc].bar->win,
|
||||||
((conf.layout_placement) ? 0 : (j + PAD / 2)), 0,
|
((conf.layout_placement) ? 0 : (j + (PAD >> 1))), 0,
|
||||||
textw(tags[sc][seltag[sc]].layout.symbol) + PAD,
|
((conf.layout_button_width > 0) ? (uint)conf.layout_button_width : (textw(tags[sc][seltag[sc]].layout.symbol) + PAD)),
|
||||||
infobar[sc].geo.height,
|
infobar[sc].geo.height,
|
||||||
conf.colors.layout_bg, conf.colors.layout_fg,
|
conf.colors.layout_bg, conf.colors.layout_fg,
|
||||||
False, False, conf.border.layout);
|
False, False, conf.border.layout);
|
||||||
@@ -104,8 +107,8 @@ infobar_init(void)
|
|||||||
if(conf.bars.selbar)
|
if(conf.bars.selbar)
|
||||||
infobar[sc].selbar = barwin_create(infobar[sc].bar->win,
|
infobar[sc].selbar = barwin_create(infobar[sc].bar->win,
|
||||||
((conf.layout_placement)
|
((conf.layout_placement)
|
||||||
? (j + PAD / 2)
|
? (j + (PAD >> 1))
|
||||||
: infobar[sc].layout_button->geo.x + infobar[sc].layout_button->geo.width + PAD / 2), 1,
|
: infobar[sc].layout_button->geo.x + infobar[sc].layout_button->geo.width + (PAD >> 1)), 1,
|
||||||
(sel) ? textw(sel->title) + PAD : 1,
|
(sel) ? textw(sel->title) + PAD : 1,
|
||||||
infobar[sc].geo.height - 2,
|
infobar[sc].geo.height - 2,
|
||||||
conf.selbar.bg, conf.selbar.fg, False, False, False);
|
conf.selbar.bg, conf.selbar.fg, False, False, False);
|
||||||
@@ -127,43 +130,57 @@ infobar_init(void)
|
|||||||
barwin_refresh(infobar[sc].bar);
|
barwin_refresh(infobar[sc].bar);
|
||||||
|
|
||||||
/* Default statustext is set here */
|
/* Default statustext is set here */
|
||||||
infobar[sc].statustext = _strdup(WMFS_VERSION);
|
infobar[sc].statustext = xstrdup("wmfs"WMFS_VERSION);
|
||||||
|
|
||||||
infobar_draw(sc);
|
infobar_draw(&infobar[sc]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Draw the Infobar
|
/** Draw the layout button in the InfoBar
|
||||||
*\param sc Screen number
|
*\param i InfoBar pointer
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
infobar_draw(int sc)
|
infobar_draw_layout(InfoBar *i)
|
||||||
{
|
{
|
||||||
infobar_draw_taglist(sc);
|
int w, sc = i->screen;
|
||||||
infobar_draw_layout(sc);
|
|
||||||
infobar_draw_selbar(sc);
|
if(!conf.layout_placement)
|
||||||
barwin_refresh_color(infobar[sc].bar);
|
barwin_move(i->layout_button, i->tags_board->geo.width + (PAD >> 1), 0);
|
||||||
statustext_handle(sc, infobar[sc].statustext);
|
|
||||||
|
w = (conf.layout_button_width > 0)
|
||||||
|
? conf.layout_button_width
|
||||||
|
: textw(tags[sc][seltag[sc]].layout.symbol) + PAD;
|
||||||
|
|
||||||
|
barwin_resize(i->layout_button, w, i->geo.height);
|
||||||
|
barwin_refresh_color(i->layout_button);
|
||||||
|
|
||||||
|
/* Split mode indicator; little rectangle at bottom-right */
|
||||||
|
if(tags[sc][seltag[sc]].flags & SplitFlag)
|
||||||
|
draw_rectangle(i->layout_button->dr,
|
||||||
|
w - SPLIT_IND_S,
|
||||||
|
i->geo.height - SPLIT_IND_S,
|
||||||
|
SPLIT_IND_S, SPLIT_IND_S,
|
||||||
|
getcolor(i->layout_button->fg));
|
||||||
|
|
||||||
|
if(tags[sc][seltag[sc]].layout.symbol)
|
||||||
|
barwin_draw_text(i->layout_button, (PAD >> 1), FHINFOBAR, tags[sc][seltag[sc]].layout.symbol);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Draw the layout button in the InfoBar
|
/** Draw the InfoBar
|
||||||
*\param sc Screen number
|
*\param i InfoBar pointer
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
infobar_draw_layout(int sc)
|
infobar_draw(InfoBar *i)
|
||||||
{
|
{
|
||||||
if(!conf.layout_placement)
|
infobar_draw_taglist(i);
|
||||||
barwin_move(infobar[sc].layout_button, infobar[sc].tags_board->geo.width + PAD / 2, 0);
|
infobar_draw_layout(i);
|
||||||
|
infobar_draw_selbar(i);
|
||||||
barwin_resize(infobar[sc].layout_button, textw(tags[sc][seltag[sc]].layout.symbol) + PAD, infobar[sc].geo.height);
|
barwin_refresh_color(i->bar);
|
||||||
barwin_refresh_color(infobar[sc].layout_button);
|
statustext_handle(i->screen, i->statustext);
|
||||||
|
|
||||||
if(tags[sc][seltag[sc]].layout.symbol)
|
|
||||||
barwin_draw_text(infobar[sc].layout_button, PAD / 2, FHINFOBAR, tags[sc][seltag[sc]].layout.symbol);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -172,152 +189,147 @@ infobar_draw_layout(int sc)
|
|||||||
*\param sc Screen Number
|
*\param sc Screen Number
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
infobar_draw_selbar(int sc)
|
infobar_draw_selbar(InfoBar *i)
|
||||||
{
|
{
|
||||||
char *str = NULL;
|
char *str = NULL;
|
||||||
|
int s, sc = i->screen;
|
||||||
|
|
||||||
if(!conf.bars.selbar)
|
if(!conf.bars.selbar)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(!sel)
|
if(!sel || (sel && sel->screen != sc))
|
||||||
{
|
{
|
||||||
barwin_unmap(infobar[sc].selbar);
|
barwin_unmap(i->selbar);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if(sel && !infobar[sc].selbar->mapped)
|
else if(sel)
|
||||||
barwin_map(infobar[sc].selbar);
|
barwin_map(i->selbar);
|
||||||
|
|
||||||
if(conf.selbar.maxlenght >= 0 && sel)
|
/* Truncate string if too long */
|
||||||
|
if(conf.selbar.maxlength >= 0 && sel && sel->title)
|
||||||
{
|
{
|
||||||
str = emalloc(conf.selbar.maxlenght + 4, sizeof(char));
|
str = xcalloc(conf.selbar.maxlength + 4, sizeof(char));
|
||||||
strncpy(str, sel->title, conf.selbar.maxlenght);
|
strncpy(str, sel->title, conf.selbar.maxlength);
|
||||||
|
|
||||||
if(strlen(sel->title) > conf.selbar.maxlenght)
|
if(strlen(sel->title) > (size_t)conf.selbar.maxlength)
|
||||||
strcat(str, "...");
|
strcat(str, "...");
|
||||||
}
|
}
|
||||||
|
|
||||||
barwin_resize(infobar[sc].selbar, textw(str ? str : sel->title) + PAD, infobar[sc].geo.height - 2);
|
if((s = (textw(str ? str : sel->title) + PAD)) > i->selbar->geo.width)
|
||||||
|
barwin_resize(i->selbar, s, i->geo.height - 2);
|
||||||
|
|
||||||
barwin_move(infobar[sc].selbar,
|
barwin_move(i->selbar,
|
||||||
((conf.layout_placement)
|
((conf.layout_placement)
|
||||||
? (infobar[sc].tags_board->geo.x + infobar[sc].tags_board->geo.width + PAD / 2)
|
? (i->tags_board->geo.x + i->tags_board->geo.width + (PAD >> 1))
|
||||||
: (infobar[sc].layout_button->geo.x + infobar[sc].layout_button->geo.width + PAD / 2)), 1);
|
: (i->layout_button->geo.x + i->layout_button->geo.width + (PAD >> 1))), 1);
|
||||||
|
|
||||||
barwin_refresh_color(infobar[sc].selbar);
|
barwin_refresh_color(i->selbar);
|
||||||
barwin_draw_text(infobar[sc].selbar, PAD / 2, FHINFOBAR - 1, ((str) ? str : sel->title));
|
barwin_draw_text(i->selbar, (PAD >> 1), FHINFOBAR - 1, ((str) ? str : sel->title));
|
||||||
|
|
||||||
barwin_refresh(infobar[sc].selbar);
|
barwin_refresh(i->selbar);
|
||||||
|
|
||||||
IFREE(str);
|
free(str);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Draw the taglist in the InfoBar
|
/** Draw the taglist in the InfoBar
|
||||||
*\param sc Screen number
|
*\param i InfoBar pointer
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
infobar_draw_taglist(int sc)
|
infobar_draw_taglist(InfoBar *i)
|
||||||
{
|
{
|
||||||
int i, x, j;
|
int j, x, sc = i->screen;
|
||||||
Client *c;
|
Client *c = NULL;
|
||||||
Bool is_occupied[MAXTAG];
|
uint occupied = 0;
|
||||||
|
|
||||||
if(conf.layout_placement)
|
if(conf.layout_placement)
|
||||||
barwin_move(infobar[sc].tags_board, textw(tags[sc][seltag[sc]].layout.symbol) + PAD * 1.5, 0);
|
barwin_move(i->tags_board,
|
||||||
|
((conf.layout_button_width > 0)
|
||||||
for(i = 0; i < MAXTAG; i++)
|
? (uint)conf.layout_button_width
|
||||||
is_occupied[i] = False;
|
: (textw(tags[sc][seltag[sc]].layout.symbol) + PAD)) + (PAD >> 1), 0);
|
||||||
|
|
||||||
for(c = clients; c; c = c->next)
|
for(c = clients; c; c = c->next)
|
||||||
if(c->screen == sc)
|
if(c->screen == sc)
|
||||||
is_occupied[c->tag] = True;
|
occupied |= TagFlag(c->tag);
|
||||||
|
|
||||||
for(i = 1, x = j = 0; i < conf.ntag[sc] + 1; ++i)
|
for(j = 1, x = 0; j < conf.ntag[sc] + 1; ++j)
|
||||||
{
|
{
|
||||||
/* Autohide tag feature */
|
/* Autohide tag feature */
|
||||||
if(conf.tagautohide)
|
if(conf.tagautohide)
|
||||||
{
|
{
|
||||||
if(!is_occupied[i] && i != seltag[sc])
|
if(!(occupied & TagFlag(j)) && j != seltag[sc])
|
||||||
{
|
{
|
||||||
barwin_unmap(infobar[sc].tags[i]);
|
barwin_unmap(i->tags[j]);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!infobar[sc].tags[i]->mapped)
|
barwin_map(i->tags[j]);
|
||||||
barwin_map(infobar[sc].tags[i]);
|
barwin_move(i->tags[j], x, 0);
|
||||||
|
barwin_resize(i->tags_board, (x += i->tags[j]->geo.width), i->geo.height);
|
||||||
barwin_move(infobar[sc].tags[i], x, 0);
|
|
||||||
|
|
||||||
x += infobar[sc].tags[i]->geo.width;
|
|
||||||
|
|
||||||
barwin_resize(infobar[sc].tags_board, x, infobar[sc].geo.height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
infobar[sc].tags[i]->bg = tags[sc][i].urgent
|
if(tags[sc][j].flags & TagUrgentFlag)
|
||||||
? conf.colors.tagurbg
|
{
|
||||||
: ((i == seltag[sc] || tags[sc][seltag[sc]].tagad & TagFlag(i))
|
i->tags[j]->bg = conf.colors.tagurbg;
|
||||||
? conf.colors.tagselbg
|
i->tags[j]->fg = conf.colors.tagurfg;
|
||||||
: (is_occupied[i]
|
}
|
||||||
? conf.colors.tag_occupied_bg
|
else if(j == seltag[sc] || tags[sc][seltag[sc]].tagad & TagFlag(j))
|
||||||
: conf.colors.bar));
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
infobar[sc].tags[i]->fg = tags[sc][i].urgent
|
barwin_color_set(i->tags[j], i->tags[j]->bg, i->tags[j]->fg);
|
||||||
? conf.colors.tagurfg
|
barwin_refresh_color(i->tags[j]);
|
||||||
: ((i == seltag[sc] || tags[sc][seltag[sc]].tagad & TagFlag(i))
|
|
||||||
? conf.colors.tagselfg
|
|
||||||
: conf.colors.text);
|
|
||||||
|
|
||||||
barwin_refresh_color(infobar[sc].tags[i]);
|
if(tags[sc][j].name)
|
||||||
|
barwin_draw_text(i->tags[j], (PAD >> 1), FHINFOBAR, tags[sc][j].name);
|
||||||
if(tags[sc][i].name)
|
|
||||||
barwin_draw_text(infobar[sc].tags[i], PAD / 2, FHINFOBAR, tags[sc][i].name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Update taglist geo
|
/** Update taglist geo
|
||||||
*\param sc Screen number
|
*\param i InfoBar pointer
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
infobar_update_taglist(int sc)
|
infobar_update_taglist(InfoBar *i)
|
||||||
{
|
{
|
||||||
int i, j;
|
int t, j, sc = i->screen;
|
||||||
|
|
||||||
for(i = 1, j = 0; i < conf.ntag[sc] + 1; ++i)
|
for(t = 1, j = 0; t < conf.ntag[sc] + 1; ++t)
|
||||||
{
|
{
|
||||||
/* If the tag i does not exist yet (graphically) or need full update */
|
/* If the tag t does not exist yet (graphically) or need full update */
|
||||||
if(!infobar[sc].tags[i] || infobar[sc].need_update)
|
if(!i->tags[t] || i->need_update)
|
||||||
{
|
{
|
||||||
infobar[sc].tags[i] = barwin_create(infobar[sc].tags_board->win, j, 0,
|
i->tags[t] = barwin_create(i->tags_board->win, j, 0,
|
||||||
textw(tags[sc][i].name) + PAD,
|
textw(tags[sc][t].name) + PAD,
|
||||||
infobar[sc].geo.height,
|
i->geo.height,
|
||||||
conf.colors.bar, conf.colors.text, False, False, conf.border.tag);
|
conf.colors.bar, conf.colors.text, False, False, conf.border.tag);
|
||||||
|
|
||||||
barwin_map(infobar[sc].tags[i]);
|
barwin_map(i->tags[t]);
|
||||||
barwin_map_subwin(infobar[sc].tags[i]);
|
barwin_map_subwin(i->tags[t]);
|
||||||
|
barwin_resize(i->tags_board, (j += textw(tags[sc][t].name) + PAD), i->geo.height);
|
||||||
j += textw(tags[sc][i].name) + PAD;
|
|
||||||
|
|
||||||
barwin_resize(infobar[sc].tags_board, j, infobar[sc].geo.height);
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
barwin_move(infobar[sc].tags[i], j, 0);
|
barwin_move(i->tags[t], j, 0);
|
||||||
j += textw(tags[sc][i].name) + PAD;
|
barwin_resize(i->tags[t], textw(tags[sc][t].name) + PAD, i->geo.height);
|
||||||
barwin_resize(infobar[sc].tags[i], textw(tags[sc][i].name) + PAD, infobar[sc].geo.height);
|
barwin_resize(i->tags_board, (j += textw(tags[sc][t].name) + PAD), i->geo.height);
|
||||||
barwin_resize(infobar[sc].tags_board, j, infobar[sc].geo.height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
infobar[sc].need_update = False;
|
i->need_update = False;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Destroy the InfoBar
|
/** Destroy the InfoBar
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
@@ -359,7 +371,7 @@ infobar_set_position(int pos)
|
|||||||
case IB_Hide:
|
case IB_Hide:
|
||||||
sgeo[selscreen].y = spgeo[selscreen].y + TBARH;
|
sgeo[selscreen].y = spgeo[selscreen].y + TBARH;
|
||||||
sgeo[selscreen].height = spgeo[selscreen].height - TBARH;
|
sgeo[selscreen].height = spgeo[selscreen].height - TBARH;
|
||||||
infobar[selscreen].geo.y = -(infobar[selscreen].geo.height) * 2;
|
infobar[selscreen].geo.y = (-(infobar[selscreen].geo.height) << 1);
|
||||||
break;
|
break;
|
||||||
case IB_Bottom:
|
case IB_Bottom:
|
||||||
sgeo[selscreen].y = spgeo[selscreen].y + TBARH;
|
sgeo[selscreen].y = spgeo[selscreen].y + TBARH;
|
||||||
@@ -377,8 +389,7 @@ infobar_set_position(int pos)
|
|||||||
tags[selscreen][seltag[selscreen]].barpos = pos;
|
tags[selscreen][seltag[selscreen]].barpos = pos;
|
||||||
|
|
||||||
barwin_move(infobar[selscreen].bar, sgeo[selscreen].x - BORDH, infobar[selscreen].geo.y);
|
barwin_move(infobar[selscreen].bar, sgeo[selscreen].x - BORDH, infobar[selscreen].geo.y);
|
||||||
infobar_draw(selscreen);
|
infobar_draw(&infobar[selscreen]);
|
||||||
ewmh_set_workarea();
|
|
||||||
arrange(selscreen, True);
|
arrange(selscreen, True);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -390,6 +401,7 @@ infobar_set_position(int pos)
|
|||||||
void
|
void
|
||||||
uicb_infobar_togglepos(uicb_t cmd)
|
uicb_infobar_togglepos(uicb_t cmd)
|
||||||
{
|
{
|
||||||
|
(void)cmd;
|
||||||
screen_get_sel();
|
screen_get_sel();
|
||||||
|
|
||||||
infobar_set_position((tags[selscreen][seltag[selscreen]].barpos
|
infobar_set_position((tags[selscreen][seltag[selscreen]].barpos
|
||||||
@@ -400,6 +412,28 @@ uicb_infobar_togglepos(uicb_t cmd)
|
|||||||
return;
|
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
|
/** Toggle the tag_autohide mode
|
||||||
* \param cmd uicb_t type unused
|
* \param cmd uicb_t type unused
|
||||||
*/
|
*/
|
||||||
@@ -407,6 +441,7 @@ void
|
|||||||
uicb_toggle_tagautohide(uicb_t cmd)
|
uicb_toggle_tagautohide(uicb_t cmd)
|
||||||
{
|
{
|
||||||
int i, x;
|
int i, x;
|
||||||
|
(void)cmd;
|
||||||
|
|
||||||
screen_get_sel();
|
screen_get_sel();
|
||||||
conf.tagautohide = !conf.tagautohide;
|
conf.tagautohide = !conf.tagautohide;
|
||||||
@@ -415,9 +450,7 @@ uicb_toggle_tagautohide(uicb_t cmd)
|
|||||||
{
|
{
|
||||||
for(i = 1, x = 0; i < conf.ntag[selscreen] + 1; ++i)
|
for(i = 1, x = 0; i < conf.ntag[selscreen] + 1; ++i)
|
||||||
{
|
{
|
||||||
if(!infobar[selscreen].tags[i]->mapped)
|
barwin_map(infobar[selscreen].tags[i]);
|
||||||
barwin_map(infobar[selscreen].tags[i]);
|
|
||||||
|
|
||||||
barwin_move(infobar[selscreen].tags[i], x, 0);
|
barwin_move(infobar[selscreen].tags[i], x, 0);
|
||||||
x += infobar[selscreen].tags[i]->geo.width;
|
x += infobar[selscreen].tags[i]->geo.width;
|
||||||
}
|
}
|
||||||
@@ -425,7 +458,7 @@ uicb_toggle_tagautohide(uicb_t cmd)
|
|||||||
barwin_resize(infobar[selscreen].tags_board, x, infobar[selscreen].geo.height);
|
barwin_resize(infobar[selscreen].tags_board, x, infobar[selscreen].geo.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
infobar_draw(selscreen);
|
infobar_draw(&infobar[selscreen]);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
125
src/init.c
125
src/init.c
@@ -40,13 +40,14 @@ const func_name_list_t layout_list[] =
|
|||||||
{"tile_left", tile_left },
|
{"tile_left", tile_left },
|
||||||
{"tile_top", tile_top },
|
{"tile_top", tile_top },
|
||||||
{"tile_bottom", tile_bottom },
|
{"tile_bottom", tile_bottom },
|
||||||
{"tile_grid", grid },
|
{"tile_grid", grid_horizontal },
|
||||||
{"grid", grid },
|
{"tile_grid_horizontal", grid_horizontal },
|
||||||
|
{"tile_grid_vertical", grid_vertical },
|
||||||
|
{"grid", grid_horizontal },
|
||||||
{"mirror_vertical", mirror_vertical },
|
{"mirror_vertical", mirror_vertical },
|
||||||
{"tile_mirror_vertical", mirror_vertical },
|
{"tile_mirror_vertical", mirror_vertical },
|
||||||
{"mirror_horizontal", mirror_horizontal },
|
{"mirror_horizontal", mirror_horizontal },
|
||||||
{"tile_mirror_horizontal", mirror_horizontal },
|
{"tile_mirror_horizontal", mirror_horizontal },
|
||||||
{"layer", layer },
|
|
||||||
{"max", maxlayout },
|
{"max", maxlayout },
|
||||||
{"maxlayout", maxlayout },
|
{"maxlayout", maxlayout },
|
||||||
{"freelayout", freelayout },
|
{"freelayout", freelayout },
|
||||||
@@ -54,47 +55,67 @@ const func_name_list_t layout_list[] =
|
|||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Init WMFS
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
init(void)
|
|
||||||
{
|
|
||||||
/* First init */
|
|
||||||
ewmh_init_hints();
|
|
||||||
init_conf();
|
|
||||||
init_gc();
|
|
||||||
init_font();
|
|
||||||
init_cursor();
|
|
||||||
init_key();
|
|
||||||
init_root();
|
|
||||||
screen_init_geo();
|
|
||||||
infobar_init();
|
|
||||||
init_status();
|
|
||||||
ewmh_update_current_tag_prop();
|
|
||||||
grabkeys();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Init the font
|
/** Init the font
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
init_font(void)
|
init_font(void)
|
||||||
{
|
{
|
||||||
font = XftFontOpenName(dpy, SCREEN, conf.font);
|
#ifdef HAVE_XFT
|
||||||
|
if(conf.use_xft)
|
||||||
if(!font)
|
|
||||||
{
|
{
|
||||||
warnx("WMFS Error: Cannot initialize font");
|
if(!(font.font = XftFontOpenName(dpy, SCREEN, conf.font)))
|
||||||
font = XftFontOpenName(dpy, SCREEN, "sans-10");
|
{
|
||||||
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Init the graphic context
|
/** Init the graphic context
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
init_gc(void)
|
init_gc(void)
|
||||||
{
|
{
|
||||||
XGCValues gcv;
|
XGCValues gcv;
|
||||||
@@ -121,7 +142,7 @@ init_gc(void)
|
|||||||
|
|
||||||
/** Init WMFS cursor
|
/** Init WMFS cursor
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
init_cursor(void)
|
init_cursor(void)
|
||||||
{
|
{
|
||||||
cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr);
|
cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr);
|
||||||
@@ -135,7 +156,7 @@ init_cursor(void)
|
|||||||
|
|
||||||
/** Init key modifier
|
/** Init key modifier
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
init_key(void)
|
init_key(void)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
@@ -154,7 +175,7 @@ init_key(void)
|
|||||||
|
|
||||||
/** Init root Window
|
/** Init root Window
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
init_root(void)
|
init_root(void)
|
||||||
{
|
{
|
||||||
XSetWindowAttributes at;
|
XSetWindowAttributes at;
|
||||||
@@ -177,7 +198,7 @@ init_root(void)
|
|||||||
|
|
||||||
/** Init statustext shell script
|
/** Init statustext shell script
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
init_status(void)
|
init_status(void)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
@@ -194,20 +215,44 @@ init_status(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
conf.status_path = emalloc(strlen(home) + strlen(DEF_STATUS) + 2, sizeof(char));
|
conf.status_path = zmalloc(strlen(home) + strlen(DEF_STATUS) + 2);
|
||||||
sprintf(conf.status_path, "%s/"DEF_STATUS, home);
|
sprintf(conf.status_path, "%s/"DEF_STATUS, home);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stat(conf.status_path, &st) == -1)
|
if (stat(patht(conf.status_path), &st) == -1)
|
||||||
{
|
{
|
||||||
warn("%s", conf.status_path);
|
warn("%s", patht(conf.status_path));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(st.st_size && st.st_mode & S_IXUSR)
|
if(st.st_size && st.st_mode & S_IXUSR)
|
||||||
estatus = True;
|
estatus = True;
|
||||||
else
|
else
|
||||||
warnx("status file specified in configuratin (status_path) or present in wmfs directory can't be executed, try 'chmod +x %s'.", conf.status_path);
|
warnx("status file specified in configuratin (status_path) or present in wmfs directory can't be executed, try 'chmod +x %s'.", patht(conf.status_path));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Init WMFS
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
init(void)
|
||||||
|
{
|
||||||
|
/* First init */
|
||||||
|
ewmh_init_hints();
|
||||||
|
init_conf();
|
||||||
|
init_gc();
|
||||||
|
init_font();
|
||||||
|
init_cursor();
|
||||||
|
init_key();
|
||||||
|
init_root();
|
||||||
|
screen_init_geo();
|
||||||
|
event_make_array();
|
||||||
|
infobar_init();
|
||||||
|
systray_acquire();
|
||||||
|
init_status();
|
||||||
|
ewmh_update_current_tag_prop();
|
||||||
|
grabkeys();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
325
src/launcher.c
325
src/launcher.c
@@ -30,42 +30,182 @@
|
|||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* conforming to glib use _GNU_SOURCE for asprintf declaration */
|
|
||||||
#ifndef _GNU_SOURCE
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "wmfs.h"
|
#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;
|
||||||
|
|
||||||
static char *complete_on_command(char*, size_t);
|
char **namelist = NULL;
|
||||||
static char *complete_on_files(char*, size_t);
|
int n = 0, i;
|
||||||
|
|
||||||
void
|
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)
|
launcher_execute(Launcher *launcher)
|
||||||
{
|
{
|
||||||
BarWindow *bw;
|
BarWindow *bw;
|
||||||
Bool found;
|
bool found;
|
||||||
Bool lastwastab = False;
|
bool lastwastab = False;
|
||||||
Bool my_guitar_gently_wheeps = True;
|
bool my_guitar_gently_wheeps = True;
|
||||||
char tmp[32] = { 0 };
|
char tmp[32] = { 0 };
|
||||||
char buf[512] = { 0 };
|
char buf[512] = { 0 };
|
||||||
char tmpbuf[512] = { 0 };
|
char tmpbuf[512] = { 0 };
|
||||||
char *complete;
|
char *complete;
|
||||||
int i, pos = 0, histpos = 0, x;
|
int i, pos = 0, histpos = 0, x, w;
|
||||||
int tabhits = 0;
|
int tabhits = 0;
|
||||||
KeySym ks;
|
KeySym ks;
|
||||||
XEvent ev;
|
XEvent ev;
|
||||||
|
|
||||||
screen_get_sel();
|
screen_get_sel();
|
||||||
|
|
||||||
x = (infobar[selscreen].layout_button->geo.x
|
x = (conf.layout_placement)
|
||||||
+ textw(tags[selscreen][seltag[selscreen]].layout.symbol) + PAD);
|
? (infobar[selscreen].tags_board->geo.x + infobar[selscreen].tags_board->geo.width)
|
||||||
|
: (infobar[selscreen].layout_button->geo.x + infobar[selscreen].layout_button->geo.width);
|
||||||
|
|
||||||
XGrabKeyboard(dpy, ROOT, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
XGrabKeyboard(dpy, ROOT, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||||
|
|
||||||
bw = barwin_create(infobar[selscreen].bar->win, x, 1,
|
w = (launcher->width ? launcher->width : infobar[selscreen].bar->geo.width - x - 1);
|
||||||
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->geo.height - 2,
|
||||||
infobar[selscreen].bar->bg,
|
infobar[selscreen].bar->bg,
|
||||||
infobar[selscreen].bar->fg,
|
infobar[selscreen].bar->fg,
|
||||||
@@ -76,9 +216,7 @@ launcher_execute(Launcher *launcher)
|
|||||||
|
|
||||||
/* First draw of the cursor */
|
/* First draw of the cursor */
|
||||||
XSetForeground(dpy, gc, getcolor(infobar[selscreen].bar->fg));
|
XSetForeground(dpy, gc, getcolor(infobar[selscreen].bar->fg));
|
||||||
/*XDrawLine(dpy, bw->dr, gc, 1 + textw(launcher->prompt) + textw(" "),
|
|
||||||
, 1 + textw(launcher->prompt) + textw(" "), INFOBARH - 4);
|
|
||||||
*/
|
|
||||||
XDrawLine(dpy, bw->dr, gc,
|
XDrawLine(dpy, bw->dr, gc,
|
||||||
1 + textw(launcher->prompt) + textw(" ") + textw(buf), 2,
|
1 + textw(launcher->prompt) + textw(" ") + textw(buf), 2,
|
||||||
1 + textw(launcher->prompt) + textw(" ") + textw(buf), INFOBARH - 4);
|
1 + textw(launcher->prompt) + textw(" ") + textw(buf), INFOBARH - 4);
|
||||||
@@ -113,14 +251,14 @@ launcher_execute(Launcher *launcher)
|
|||||||
case XK_Up:
|
case XK_Up:
|
||||||
if(launcher->nhisto)
|
if(launcher->nhisto)
|
||||||
{
|
{
|
||||||
if(histpos >= launcher->nhisto)
|
if(histpos >= (int)launcher->nhisto)
|
||||||
histpos = 0;
|
histpos = 0;
|
||||||
strncpy(buf, launcher->histo[launcher->nhisto - ++histpos], sizeof(buf));
|
strncpy(buf, launcher->histo[launcher->nhisto - ++histpos], sizeof(buf));
|
||||||
pos = strlen(buf);
|
pos = strlen(buf);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case XK_Down:
|
case XK_Down:
|
||||||
if(launcher->nhisto && histpos > 0 && histpos < launcher->nhisto)
|
if(launcher->nhisto && histpos > 0 && histpos < (int)launcher->nhisto)
|
||||||
{
|
{
|
||||||
strncpy(buf, launcher->histo[launcher->nhisto - --histpos], sizeof(buf));
|
strncpy(buf, launcher->histo[launcher->nhisto - --histpos], sizeof(buf));
|
||||||
pos = strlen(buf);
|
pos = strlen(buf);
|
||||||
@@ -161,7 +299,7 @@ launcher_execute(Launcher *launcher)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
tabhits = 1;
|
tabhits = 1;
|
||||||
strcpy(tmpbuf, buf);
|
strncpy(tmpbuf, buf, sizeof(tmpbuf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -174,7 +312,7 @@ launcher_execute(Launcher *launcher)
|
|||||||
|
|
||||||
if (complete)
|
if (complete)
|
||||||
{
|
{
|
||||||
strcpy(buf, tmpbuf);
|
strncpy(buf, tmpbuf, sizeof(buf));
|
||||||
strncat(buf, complete, sizeof(buf));
|
strncat(buf, complete, sizeof(buf));
|
||||||
found = True;
|
found = True;
|
||||||
free(complete);
|
free(complete);
|
||||||
@@ -184,7 +322,7 @@ launcher_execute(Launcher *launcher)
|
|||||||
lastwastab = True;
|
lastwastab = True;
|
||||||
|
|
||||||
/* start a new round of tabbing */
|
/* start a new round of tabbing */
|
||||||
if (!found)
|
if (found == False)
|
||||||
tabhits = 0;
|
tabhits = 0;
|
||||||
|
|
||||||
pos = strlen(buf);
|
pos = strlen(buf);
|
||||||
@@ -216,14 +354,15 @@ launcher_execute(Launcher *launcher)
|
|||||||
barwin_draw_text(bw, 1 + textw(launcher->prompt) + textw(" "), FHINFOBAR - 1, buf);
|
barwin_draw_text(bw, 1 + textw(launcher->prompt) + textw(" "), FHINFOBAR - 1, buf);
|
||||||
barwin_refresh(bw);
|
barwin_refresh(bw);
|
||||||
}
|
}
|
||||||
else
|
else if(ev.type < nevent && ev.type > 0)
|
||||||
getevent(ev);
|
HANDLE_EVENT(&ev);
|
||||||
|
|
||||||
XNextEvent(dpy, &ev);
|
XNextEvent(dpy, &ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
barwin_unmap(bw);
|
barwin_unmap(bw);
|
||||||
barwin_delete(bw);
|
barwin_delete(bw);
|
||||||
infobar_draw(selscreen);
|
infobar_draw(&infobar[selscreen]);
|
||||||
|
|
||||||
XUngrabKeyboard(dpy, CurrentTime);
|
XUngrabKeyboard(dpy, CurrentTime);
|
||||||
|
|
||||||
@@ -242,135 +381,3 @@ uicb_launcher(uicb_t cmd)
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
size_t count = 0;
|
|
||||||
|
|
||||||
if (!getenv("PATH") || !start || hits <= 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
path = _strdup(getenv("PATH"));
|
|
||||||
dirname = strtok(path, ":");
|
|
||||||
|
|
||||||
/* recursively open PATH */
|
|
||||||
while (dirname)
|
|
||||||
{
|
|
||||||
if ((dir = opendir(dirname)))
|
|
||||||
{
|
|
||||||
while ((content = readdir(dir)))
|
|
||||||
if (!strncmp(content->d_name, start, strlen(start)) && ++count == hits)
|
|
||||||
{
|
|
||||||
ret = _strdup(content->d_name + strlen(start));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
closedir(dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
|
|
||||||
dirname = strtok(NULL, ":");
|
|
||||||
}
|
|
||||||
|
|
||||||
free(path);
|
|
||||||
|
|
||||||
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 = _strdup(".");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* remplace ~ by $HOME in dirname */
|
|
||||||
if (!strncmp(p, "~/", 2) && getenv("HOME"))
|
|
||||||
asprintf(&dirname, "%s%s", getenv("HOME"), p+1);
|
|
||||||
else
|
|
||||||
dirname = _strdup(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 = _strdup(dirname);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
path = _strdup("/");
|
|
||||||
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 */
|
|
||||||
asprintf(&filepath, "%s/%s", path, content->d_name);
|
|
||||||
|
|
||||||
if (filepath && stat(filepath, &st) != -1)
|
|
||||||
{
|
|
||||||
if (S_ISDIR(st.st_mode))
|
|
||||||
asprintf(&ret, "%s/", content->d_name + strlen(p));
|
|
||||||
else
|
|
||||||
ret = _strdup(content->d_name + strlen(p));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
warn("%s", filepath);
|
|
||||||
|
|
||||||
IFREE(filepath);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
closedir(dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
IFREE(dirname);
|
|
||||||
IFREE(path);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|||||||
467
src/layout.c
467
src/layout.c
@@ -35,11 +35,11 @@
|
|||||||
/** Arrange All
|
/** Arrange All
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
arrange(int screen, Bool update_layout)
|
arrange(int screen, bool update_layout)
|
||||||
{
|
{
|
||||||
Client *c;
|
Client *c;
|
||||||
|
|
||||||
if(screen < 0 || screen > screen_count())
|
if(screen < 0 || screen > screen_count() - 1)
|
||||||
screen = screen_get_sel();
|
screen = screen_get_sel();
|
||||||
|
|
||||||
for(c = clients; c; c = c->next)
|
for(c = clients; c; c = c->next)
|
||||||
@@ -51,10 +51,30 @@ arrange(int screen, Bool update_layout)
|
|||||||
client_hide(c);
|
client_hide(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(update_layout)
|
if(tags[screen][seltag[screen]].layout.func)
|
||||||
tags[screen][seltag[screen]].layout.func(screen);
|
{
|
||||||
|
if(update_layout)
|
||||||
|
layout_func(screen, seltag[screen]);
|
||||||
|
|
||||||
infobar_draw(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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -65,11 +85,12 @@ void
|
|||||||
freelayout(int screen)
|
freelayout(int screen)
|
||||||
{
|
{
|
||||||
Client *c;
|
Client *c;
|
||||||
|
(void)screen;
|
||||||
|
|
||||||
for(c = clients; c; c = c->next)
|
for(c = clients; c; c = c->next)
|
||||||
if(!ishide(c, selscreen)
|
if(!ishide(c, selscreen)
|
||||||
&& c->screen == screen_get_sel()
|
&& c->screen == screen
|
||||||
&& !(c->flags & MaxFlag))
|
&& !(c->flags & MaxFlag))
|
||||||
{
|
{
|
||||||
client_moveresize(c, c->free_geo, True);
|
client_moveresize(c, c->free_geo, True);
|
||||||
c->flags &= ~(TileFlag | LMaxFlag);
|
c->flags &= ~(TileFlag | LMaxFlag);
|
||||||
@@ -81,10 +102,10 @@ freelayout(int screen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Layout switching function
|
/** Layout switching function
|
||||||
* \param b Bool True : next False : previous
|
* \param b bool True : next False : previous
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
layoutswitch(Bool b)
|
layoutswitch(bool b)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
Client *c;
|
Client *c;
|
||||||
@@ -92,7 +113,7 @@ layoutswitch(Bool b)
|
|||||||
screen_get_sel();
|
screen_get_sel();
|
||||||
|
|
||||||
if(tags[selscreen][seltag[selscreen]].layout.func == freelayout)
|
if(tags[selscreen][seltag[selscreen]].layout.func == freelayout)
|
||||||
for(c = clients; c && (c->tag != seltag[selscreen] && c->screen != selscreen); c = c->next)
|
for(c = clients; c && (c->tag != (uint)seltag[selscreen] && c->screen != selscreen); c = c->next)
|
||||||
{
|
{
|
||||||
c->ogeo = c->geo;
|
c->ogeo = c->geo;
|
||||||
c->free_geo = c->geo;
|
c->free_geo = c->geo;
|
||||||
@@ -112,8 +133,10 @@ layoutswitch(Bool b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ewmh_update_current_tag_prop();
|
ewmh_update_current_tag_prop();
|
||||||
tags[selscreen][seltag[selscreen]].layout.func(selscreen);
|
tags[selscreen][seltag[selscreen]].flags |= CleanFactFlag;
|
||||||
infobar_draw(selscreen);
|
tags[selscreen][seltag[selscreen]].flags &= ~SplitFlag;
|
||||||
|
layout_func(selscreen, seltag[selscreen]);
|
||||||
|
infobar_draw_layout(&infobar[selscreen]);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -124,6 +147,7 @@ layoutswitch(Bool b)
|
|||||||
void
|
void
|
||||||
uicb_layout_next(uicb_t cmd)
|
uicb_layout_next(uicb_t cmd)
|
||||||
{
|
{
|
||||||
|
(void)cmd;
|
||||||
layoutswitch(True);
|
layoutswitch(True);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -135,11 +159,30 @@ uicb_layout_next(uicb_t cmd)
|
|||||||
void
|
void
|
||||||
uicb_layout_prev(uicb_t cmd)
|
uicb_layout_prev(uicb_t cmd)
|
||||||
{
|
{
|
||||||
|
(void)cmd;
|
||||||
layoutswitch(False);
|
layoutswitch(False);
|
||||||
|
|
||||||
return;
|
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 = c->next);
|
||||||
|
|
||||||
|
if(c)
|
||||||
|
c->flags |= FLayFlag;
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
/** Max layout function
|
/** Max layout function
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
@@ -160,24 +203,6 @@ maxlayout(int screen)
|
|||||||
return;
|
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)
|
|
||||||
|| (c->flags & FreeFlag)
|
|
||||||
|| (c->flags & FSSFlag)
|
|
||||||
|| (c->flags & AboveFlag)
|
|
||||||
|| c->screen != screen
|
|
||||||
|| ishide(c, screen)); c = c->next);
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set the mwfact
|
/** Set the mwfact
|
||||||
* \param cmd Mwfact (string)
|
* \param cmd Mwfact (string)
|
||||||
*/
|
*/
|
||||||
@@ -195,7 +220,7 @@ uicb_set_mwfact(uicb_t cmd)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
tags[selscreen][seltag[selscreen]].mwfact += c;
|
tags[selscreen][seltag[selscreen]].mwfact += c;
|
||||||
tags[selscreen][seltag[selscreen]].layout.func(selscreen);
|
layout_func(selscreen, seltag[selscreen]);
|
||||||
|
|
||||||
ewmh_update_current_tag_prop();
|
ewmh_update_current_tag_prop();
|
||||||
|
|
||||||
@@ -220,64 +245,28 @@ uicb_set_nmaster(uicb_t cmd)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
tags[selscreen][seltag[selscreen]].nmaster += n;
|
tags[selscreen][seltag[selscreen]].nmaster += n;
|
||||||
tags[selscreen][seltag[selscreen]].layout.func(selscreen);
|
tags[selscreen][seltag[selscreen]].flags |= CleanFactFlag;
|
||||||
|
layout_func(selscreen, seltag[selscreen]);
|
||||||
|
|
||||||
ewmh_update_current_tag_prop();
|
ewmh_update_current_tag_prop();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
uicb_set_client_layer(uicb_t cmd)
|
|
||||||
{
|
|
||||||
int n = atoi(cmd);
|
|
||||||
|
|
||||||
screen_get_sel();
|
|
||||||
|
|
||||||
CHECK(sel);
|
|
||||||
|
|
||||||
if(sel->layer + n < 1
|
|
||||||
|| sel->layer + n > tags[selscreen][seltag[selscreen]].layers)
|
|
||||||
return;
|
|
||||||
|
|
||||||
sel->layer += n;
|
|
||||||
|
|
||||||
tags[selscreen][seltag[selscreen]].layout.func(selscreen);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
uicb_set_layer(uicb_t cmd)
|
|
||||||
{
|
|
||||||
int n = atoi(cmd);
|
|
||||||
|
|
||||||
screen_get_sel();
|
|
||||||
|
|
||||||
if(tags[selscreen][seltag[selscreen]].layers + n < 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
tags[selscreen][seltag[selscreen]].layers += n;
|
|
||||||
tags[selscreen][seltag[selscreen]].layout.func(selscreen);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Grid layout function
|
/** Grid layout function
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
grid(int screen)
|
grid(int screen, bool horizontal)
|
||||||
{
|
{
|
||||||
Client *c;
|
Client *c;
|
||||||
XRectangle sg = sgeo[screen];
|
Geo sg = sgeo[screen];
|
||||||
XRectangle cgeo = {sg.x, sg.y, 0, 0};
|
Geo cgeo = {sg.x, sg.y, 0, 0};
|
||||||
unsigned int i, n, cols, rows, cpcols = 0;
|
unsigned int i, n, temp, cols, rows, cpcols = 0;
|
||||||
|
|
||||||
for(n = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++n);
|
for(n = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++n);
|
||||||
CHECK(n);
|
CHECK((tags[screen][seltag[screen]].nclients = n));
|
||||||
|
|
||||||
for(rows = 0; rows <= n / 2; ++rows)
|
for(rows = 0; rows <= (n >> 1); ++rows)
|
||||||
if(rows * rows >= n)
|
if(rows * rows >= n)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -285,13 +274,23 @@ grid(int screen)
|
|||||||
? rows - 1
|
? rows - 1
|
||||||
: rows;
|
: rows;
|
||||||
|
|
||||||
|
if(!horizontal)
|
||||||
|
{
|
||||||
|
temp = cols;
|
||||||
|
cols = rows;
|
||||||
|
rows = temp;
|
||||||
|
}
|
||||||
|
|
||||||
for(i = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++i)
|
for(i = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++i)
|
||||||
{
|
{
|
||||||
/* Set client property */
|
/* Set client property */
|
||||||
c->flags &= ~(MaxFlag | LMaxFlag);
|
c->flags &= ~(MaxFlag | LMaxFlag);
|
||||||
c->flags |= TileFlag;
|
c->flags |= TileFlag;
|
||||||
++cpcols;
|
++cpcols;
|
||||||
cgeo.width = (sg.width / cols) - (BORDH * 2);
|
|
||||||
|
cfactor_clean(c);
|
||||||
|
|
||||||
|
cgeo.width = (sg.width / cols) - (BORDH << 1);
|
||||||
cgeo.height = (sg.height / rows) - BORDH;
|
cgeo.height = (sg.height / rows) - BORDH;
|
||||||
|
|
||||||
/* Last row's and last client remainder */
|
/* Last row's and last client remainder */
|
||||||
@@ -300,22 +299,23 @@ grid(int screen)
|
|||||||
|
|
||||||
/* Last column's client remainder */
|
/* Last column's client remainder */
|
||||||
if(i >= rows * (cols - 1))
|
if(i >= rows * (cols - 1))
|
||||||
cgeo.width = sg.width - (cgeo.x - (sg.x - (BORDH * 2)));
|
cgeo.width = sg.width - (cgeo.x - (sg.x - (BORDH << 1)));
|
||||||
|
|
||||||
/* Resize */
|
/* Resize */
|
||||||
client_moveresize(c, cgeo, tags[screen][seltag[screen]].resizehint);
|
client_moveresize(c, (c->pgeo = cgeo), (tags[screen][seltag[screen]].flags & ResizeHintFlag));
|
||||||
|
|
||||||
/* Set all the other size with current client info */
|
/* Set all the other size with current client info */
|
||||||
cgeo.y = c->geo.y + c->geo.height + BORDH + TBARH;
|
cgeo.y = c->pgeo.y + c->pgeo.height + BORDH + TBARH;
|
||||||
|
|
||||||
if(cpcols + 1 > rows)
|
if(cpcols + 1 > rows)
|
||||||
{
|
{
|
||||||
cpcols = 0;
|
cpcols = 0;
|
||||||
cgeo.x = c->geo.x + c->geo.width + (BORDH * 2);
|
cgeo.x = c->pgeo.x + c->pgeo.width + (BORDH << 1);
|
||||||
cgeo.y = sg.y;
|
cgeo.y = sg.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tags[screen][seltag[screen]].flags &= ~CleanFactFlag;
|
||||||
ewmh_update_current_tag_prop();
|
ewmh_update_current_tag_prop();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -324,17 +324,17 @@ grid(int screen)
|
|||||||
/** Multi tile function
|
/** Multi tile function
|
||||||
* \param type Postion type { Top, Bottom, Left, Right }
|
* \param type Postion type { Top, Bottom, Left, Right }
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
multi_tile(int screen, Position type)
|
multi_tile(int screen, Position type)
|
||||||
{
|
{
|
||||||
Client *c;
|
Client *c;
|
||||||
XRectangle sg = sgeo[screen];
|
Geo sg = sgeo[screen];
|
||||||
XRectangle mastergeo = {sg.x, sg.y, 0, 0};
|
Geo mastergeo = {sg.x, sg.y, 0, 0};
|
||||||
XRectangle cgeo = {sg.x, sg.y, 0, 0};
|
Geo cgeo = {sg.x, sg.y, 0, 0};
|
||||||
uint i, n, tilesize = 0, mwfact, nmaster = tags[screen][seltag[screen]].nmaster;
|
uint i, n, tilesize = 0, mwfact, nmaster = tags[screen][seltag[screen]].nmaster;
|
||||||
|
|
||||||
for(n = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++n);
|
for(n = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++n);
|
||||||
CHECK(n);
|
CHECK((tags[screen][seltag[screen]].nclients = n));
|
||||||
|
|
||||||
/* FIX NMASTER */
|
/* FIX NMASTER */
|
||||||
nmaster = (n < nmaster) ? n : nmaster;
|
nmaster = (n < nmaster) ? n : nmaster;
|
||||||
@@ -345,28 +345,27 @@ multi_tile(int screen, Position type)
|
|||||||
: tags[screen][seltag[screen]].mwfact * sg.width;
|
: tags[screen][seltag[screen]].mwfact * sg.width;
|
||||||
|
|
||||||
/* MASTER SIZE */
|
/* MASTER SIZE */
|
||||||
if(type == Top || type == Bottom)
|
if(LDIR(type))
|
||||||
{
|
{
|
||||||
if(type == Top)
|
if(type == Left)
|
||||||
mastergeo.y = (n <= nmaster) ? sg.y : sg.y + (sg.height - mwfact) - BORDH;
|
mastergeo.x = (n <= nmaster) ? (uint)sg.x : (sg.x + sg.width) - mwfact - (BORDH << 1);
|
||||||
mastergeo.width = (sg.width / nmaster) - (BORDH * 4);
|
mastergeo.width = (n <= nmaster) ? (uint)(sg.width - (BORDH << 1)) : mwfact;
|
||||||
mastergeo.height = (n <= nmaster) ? sg.height - BORDH : mwfact;
|
mastergeo.height = (sg.height / nmaster) - BORDH;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(type == Left)
|
if(type == Top)
|
||||||
mastergeo.x = (n <= nmaster) ? sg.x : (sg.x + sg.width) - mwfact - (BORDH * 2);
|
mastergeo.y = (n <= nmaster) ? (uint)sg.y : sg.y + (sg.height - mwfact) - BORDH;
|
||||||
mastergeo.width = (n <= nmaster) ? sg.width - (BORDH * 2) : mwfact;
|
mastergeo.width = (sg.width / nmaster) - (BORDH << 2);
|
||||||
mastergeo.height = (sg.height / nmaster) - BORDH;
|
mastergeo.height = (n <= nmaster) ? (uint)(sg.height - BORDH) : mwfact;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TILED SIZE */
|
/* TILED SIZE */
|
||||||
if(n > nmaster)
|
if(n > nmaster)
|
||||||
{
|
{
|
||||||
if(type == Top || type == Bottom)
|
if(LDIR(type))
|
||||||
tilesize = sg.width / (n - nmaster) - (BORDH * 4);
|
tilesize = sg.height / (n - nmaster) - ((BORDH << 1) + TBARH);
|
||||||
else
|
else
|
||||||
tilesize = sg.height / (n - nmaster) - ((BORDH * 2) + TBARH);
|
tilesize = sg.width / (n - nmaster) - (BORDH << 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -376,19 +375,21 @@ multi_tile(int screen, Position type)
|
|||||||
c->flags &= ~(MaxFlag | LMaxFlag);
|
c->flags &= ~(MaxFlag | LMaxFlag);
|
||||||
c->flags |= TileFlag;
|
c->flags |= TileFlag;
|
||||||
|
|
||||||
|
cfactor_clean(c);
|
||||||
|
|
||||||
/* MASTER */
|
/* MASTER */
|
||||||
if(i < nmaster)
|
if(i < nmaster)
|
||||||
{
|
{
|
||||||
cgeo.width = mastergeo.width;
|
cgeo.width = mastergeo.width;
|
||||||
cgeo.height = mastergeo.height;
|
cgeo.height = mastergeo.height;
|
||||||
|
|
||||||
if(type == Top || type == Bottom)
|
if(LDIR(type))
|
||||||
cgeo.y = mastergeo.y;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
cgeo.x = mastergeo.x;
|
cgeo.x = mastergeo.x;
|
||||||
cgeo.height -= (TBARH + BORDH);
|
cgeo.height -= (TBARH + BORDH);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
cgeo.y = mastergeo.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TILED */
|
/* TILED */
|
||||||
@@ -409,42 +410,43 @@ multi_tile(int screen, Position type)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
case Right:
|
case Right:
|
||||||
cgeo.x += mastergeo.width + (BORDH * 2);
|
cgeo.x += mastergeo.width + (BORDH << 1);
|
||||||
cgeo.y = sg.y;
|
cgeo.y = sg.y;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(type == Top || type == Bottom)
|
if(LDIR(type))
|
||||||
{
|
{
|
||||||
cgeo.width = tilesize;
|
cgeo.width = sg.width - mastergeo.width - (BORDH << 2);
|
||||||
cgeo.height = sg.height - mastergeo.height - TBARH - (BORDH * 2);
|
cgeo.height = tilesize;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cgeo.width = sg.width - mastergeo.width - (BORDH * 4);
|
cgeo.width = tilesize;
|
||||||
cgeo.height = tilesize;
|
cgeo.height = sg.height - mastergeo.height - TBARH - (BORDH << 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* REMAINDER */
|
/* REMAINDER */
|
||||||
if(i + 1 == n || i + 1 == (n < nmaster ? n : nmaster))
|
if(i + 1 == n || i + 1 == (n < nmaster ? n : nmaster))
|
||||||
{
|
{
|
||||||
if(type == Top || type == Bottom)
|
if(LDIR(type))
|
||||||
cgeo.width = sg.width - (cgeo.x - (sg.x - (BORDH * 2)));
|
|
||||||
else
|
|
||||||
cgeo.height = (sg.y + sg.height) - cgeo.y - BORDH;
|
cgeo.height = (sg.y + sg.height) - cgeo.y - BORDH;
|
||||||
|
else
|
||||||
|
cgeo.width = sg.width - (cgeo.x - (sg.x - (BORDH << 1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Magic instant */
|
/* Magic instant */
|
||||||
client_moveresize(c, cgeo, tags[screen][seltag[screen]].resizehint);
|
client_moveresize(c, (c->pgeo = cgeo), (tags[screen][seltag[screen]].flags & ResizeHintFlag));
|
||||||
|
|
||||||
/* Set the position of the next client */
|
/* Set the position of the next client */
|
||||||
if(type == Top || type == Bottom)
|
if(LDIR(type))
|
||||||
cgeo.x = c->geo.x + c->geo.width + (BORDH * 2);
|
cgeo.y = c->pgeo.y + c->pgeo.height + BORDH + TBARH;
|
||||||
else
|
else
|
||||||
cgeo.y = c->geo.y + c->geo.height + BORDH + TBARH;
|
cgeo.x = c->pgeo.x + c->pgeo.width + (BORDH << 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tags[screen][seltag[screen]].flags &= ~CleanFactFlag;
|
||||||
ewmh_update_current_tag_prop();
|
ewmh_update_current_tag_prop();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -454,27 +456,29 @@ multi_tile(int screen, Position type)
|
|||||||
* \param screen Screen to execute this function
|
* \param screen Screen to execute this function
|
||||||
* \param horizont To specify the mirror mode (vertical/horizontal)
|
* \param horizont To specify the mirror mode (vertical/horizontal)
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
mirror(int screen, Bool horizontal)
|
mirror(int screen, bool horizontal)
|
||||||
{
|
{
|
||||||
Client *c;
|
Client *c;
|
||||||
XRectangle sg = sgeo[screen];
|
Geo sg = sgeo[screen];
|
||||||
XRectangle mastergeo = {sg.x, sg.y, sg.width, sg.height};
|
Geo mastergeo = {sg.x, sg.y, sg.width, sg.height};
|
||||||
XRectangle cgeo = {sg.x, sg.y , sg.width, sg.height};
|
Geo cgeo = {sg.x, sg.y , sg.width, sg.height};
|
||||||
XRectangle nextg[2] = { {0} };
|
Geo nextg[2];
|
||||||
uint i, n, tilesize = 0, mwfact;
|
uint i, n, tilesize = 0, mwfact;
|
||||||
uint nmaster = tags[screen][seltag[screen]].nmaster;
|
uint nmaster = tags[screen][seltag[screen]].nmaster;
|
||||||
int pa, imp;
|
int pa, imp;
|
||||||
Bool isp = 0;
|
bool isp = False;
|
||||||
|
|
||||||
|
memset(nextg, 0, sizeof(nextg));
|
||||||
|
|
||||||
for(n = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++n);
|
for(n = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++n);
|
||||||
CHECK(n);
|
CHECK((tags[screen][seltag[screen]].nclients = n));
|
||||||
|
|
||||||
/* Fix nmaster */
|
/* Fix nmaster */
|
||||||
nmaster = (n < nmaster) ? n : nmaster;
|
nmaster = (n < nmaster) ? n : nmaster;
|
||||||
|
|
||||||
imp = ((n - (nmaster - 1)) / 2);
|
imp = ((n - (nmaster - 1)) >> 1);
|
||||||
pa = ((n - (nmaster - 1)) / 2) - (((n - (nmaster - 1)) % 2) ? 0 : 1);
|
pa = ((n - (nmaster - 1)) >> 1) - (((n - (nmaster - 1)) & 1) ? 0 : 1);
|
||||||
|
|
||||||
/* Set mwfact */
|
/* Set mwfact */
|
||||||
if(tags[screen][seltag[screen]].mwfact < 0.55)
|
if(tags[screen][seltag[screen]].mwfact < 0.55)
|
||||||
@@ -485,26 +489,26 @@ mirror(int screen, Bool horizontal)
|
|||||||
/* Master size */
|
/* Master size */
|
||||||
if(horizontal)
|
if(horizontal)
|
||||||
{
|
{
|
||||||
mastergeo.width = (sg.width / nmaster) - (BORDH * 2);
|
mastergeo.width = (sg.width / nmaster) - (BORDH << 1);
|
||||||
mastergeo.height -= BORDH;
|
mastergeo.height -= BORDH;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mastergeo.width -= BORDH * 2;
|
mastergeo.width -= (BORDH << 1);
|
||||||
mastergeo.height = (sg.height / nmaster) - (TBARH + (BORDH * 2));
|
mastergeo.height = (sg.height / nmaster) - (TBARH + (BORDH << 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(n == nmaster + 1)
|
if(n == nmaster + 1)
|
||||||
{
|
{
|
||||||
if(horizontal)
|
if(horizontal)
|
||||||
{
|
{
|
||||||
mastergeo.height = mwfact - ((BORDH * 2) + TBARH);
|
mastergeo.height = mwfact - ((BORDH << 1) + TBARH);
|
||||||
tilesize = (sg.height - mastergeo.height) - ((BORDH * 2) + TBARH);
|
tilesize = (sg.height - mastergeo.height) - ((BORDH << 1) + TBARH);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mastergeo.width = mwfact - (BORDH * 3);
|
mastergeo.width = mwfact - (BORDH * 3);
|
||||||
tilesize = (sg.width - mastergeo.width) - (BORDH * 4);
|
tilesize = (sg.width - mastergeo.width) - (BORDH << 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(n > nmaster + 1)
|
if(n > nmaster + 1)
|
||||||
@@ -512,13 +516,13 @@ mirror(int screen, Bool horizontal)
|
|||||||
if(horizontal)
|
if(horizontal)
|
||||||
{
|
{
|
||||||
mastergeo.y = (sg.y + (sg.height - mwfact)) + TBARH + BORDH;
|
mastergeo.y = (sg.y + (sg.height - mwfact)) + TBARH + BORDH;
|
||||||
mastergeo.height = (2 * mwfact - sg.height) - ((BORDH * 3) + (TBARH * 2));
|
mastergeo.height = ((mwfact << 1) - sg.height) - ((BORDH * 3) + (TBARH << 1));
|
||||||
tilesize = (mwfact - mastergeo.height) - ((BORDH * 3) + (TBARH * 2));
|
tilesize = (mwfact - mastergeo.height) - ((BORDH * 3) + (TBARH << 1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mastergeo.x = (sg.x + (sg.width - mwfact)) + BORDH;
|
mastergeo.x = (sg.x + (sg.width - mwfact)) + BORDH;
|
||||||
mastergeo.width = ((2 * mwfact - sg.width) - (BORDH * 4));
|
mastergeo.width = ((mwfact << 1) - sg.width) - (BORDH << 2);
|
||||||
tilesize = (mwfact - mastergeo.width) - (BORDH * 5);
|
tilesize = (mwfact - mastergeo.width) - (BORDH * 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -529,6 +533,8 @@ mirror(int screen, Bool horizontal)
|
|||||||
c->flags &= ~(MaxFlag | LMaxFlag);
|
c->flags &= ~(MaxFlag | LMaxFlag);
|
||||||
c->flags |= TileFlag;
|
c->flags |= TileFlag;
|
||||||
|
|
||||||
|
cfactor_clean(c);
|
||||||
|
|
||||||
if(i < nmaster)
|
if(i < nmaster)
|
||||||
{
|
{
|
||||||
cgeo = mastergeo;
|
cgeo = mastergeo;
|
||||||
@@ -537,7 +543,7 @@ mirror(int screen, Bool horizontal)
|
|||||||
if(i + 1 == nmaster)
|
if(i + 1 == nmaster)
|
||||||
{
|
{
|
||||||
if(horizontal)
|
if(horizontal)
|
||||||
cgeo.width = (sg.x + sg.width) - (cgeo.x + (BORDH * 2));
|
cgeo.width = (sg.x + sg.width) - (cgeo.x + (BORDH << 1));
|
||||||
else
|
else
|
||||||
cgeo.height = (sg.y + sg.height) - (cgeo.y + BORDH);
|
cgeo.height = (sg.y + sg.height) - (cgeo.y + BORDH);
|
||||||
}
|
}
|
||||||
@@ -549,19 +555,19 @@ mirror(int screen, Bool horizontal)
|
|||||||
else
|
else
|
||||||
cgeo.width = tilesize;
|
cgeo.width = tilesize;
|
||||||
|
|
||||||
if((i + nmaster) % 2)
|
if((i + nmaster) & 1)
|
||||||
{
|
{
|
||||||
isp = 1;
|
isp = 1;
|
||||||
|
|
||||||
if(horizontal)
|
if(horizontal)
|
||||||
{
|
{
|
||||||
cgeo.y = sg.y;
|
cgeo.y = sg.y;
|
||||||
cgeo.width = (sg.width / pa) - (BORDH * 2);
|
cgeo.width = (sg.width / pa) - (BORDH << 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cgeo.x = sg.x;
|
cgeo.x = sg.x;
|
||||||
cgeo.height = (sg.height / pa) - (TBARH + (BORDH * 2));
|
cgeo.height = (sg.height / pa) - (TBARH + (BORDH << 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -571,12 +577,12 @@ mirror(int screen, Bool horizontal)
|
|||||||
if(horizontal)
|
if(horizontal)
|
||||||
{
|
{
|
||||||
cgeo.y = (sg.y + mwfact) - BORDH;
|
cgeo.y = (sg.y + mwfact) - BORDH;
|
||||||
cgeo.width = (sg.width / imp) - (BORDH * 2);
|
cgeo.width = (sg.width / imp) - (BORDH << 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cgeo.x = (sg.x + mwfact) - BORDH;
|
cgeo.x = (sg.x + mwfact) - BORDH;
|
||||||
cgeo.height = (sg.height / imp) - (TBARH + (BORDH * 2));
|
cgeo.height = (sg.height / imp) - (TBARH + (BORDH << 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -584,16 +590,16 @@ mirror(int screen, Bool horizontal)
|
|||||||
if(i + 1 == n || i + 1 == n - 1)
|
if(i + 1 == n || i + 1 == n - 1)
|
||||||
{
|
{
|
||||||
if(horizontal)
|
if(horizontal)
|
||||||
cgeo.width = (sg.x + sg.width) - (cgeo.x + (BORDH * 2));
|
cgeo.width = (sg.x + sg.width) - (cgeo.x + (BORDH << 1));
|
||||||
else
|
else
|
||||||
cgeo.height = (sg.y + sg.height) - (cgeo.y + BORDH);
|
cgeo.height = (sg.y + sg.height) - (cgeo.y + BORDH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
client_moveresize(c, cgeo, tags[screen][seltag[screen]].resizehint);
|
client_moveresize(c, (c->pgeo = cgeo), (tags[screen][seltag[screen]].flags & ResizeHintFlag));
|
||||||
|
|
||||||
if(i >= nmaster)
|
if(i >= nmaster)
|
||||||
nextg[!isp] = c->geo;
|
nextg[!isp] = c->pgeo;
|
||||||
|
|
||||||
/* Next y/x position */
|
/* Next y/x position */
|
||||||
if(i >= nmaster - 1)
|
if(i >= nmaster - 1)
|
||||||
@@ -603,7 +609,7 @@ mirror(int screen, Bool horizontal)
|
|||||||
if(i == nmaster || i == nmaster - 1)
|
if(i == nmaster || i == nmaster - 1)
|
||||||
cgeo.x = sg.x;
|
cgeo.x = sg.x;
|
||||||
else
|
else
|
||||||
cgeo.x = nextg[isp].x + nextg[isp].width + BORDH * 2;
|
cgeo.x = nextg[isp].x + nextg[isp].width + (BORDH << 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -616,79 +622,14 @@ mirror(int screen, Bool horizontal)
|
|||||||
else if (i <= nmaster - 1)
|
else if (i <= nmaster - 1)
|
||||||
{
|
{
|
||||||
if(horizontal)
|
if(horizontal)
|
||||||
mastergeo.x = c->geo.x + c->geo.width + BORDH * 2;
|
mastergeo.x = cgeo.x + cgeo.width + (BORDH << 1);
|
||||||
else
|
else
|
||||||
mastergeo.y = c->geo.y + c->geo.height + BORDH + TBARH;
|
mastergeo.y = cgeo.y + cgeo.height + BORDH + TBARH;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ewmh_update_current_tag_prop();
|
tags[screen][seltag[screen]].flags &= ~CleanFactFlag;
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Layer layout function
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
layer(int screen)
|
|
||||||
{
|
|
||||||
Client *c;
|
|
||||||
XRectangle geo = { 0 };
|
|
||||||
XRectangle sg = sgeo[screen];
|
|
||||||
int n, i, l = tags[screen][seltag[screen]].layers;
|
|
||||||
int *x = NULL;
|
|
||||||
int *nl = NULL;
|
|
||||||
int *ncl = NULL;
|
|
||||||
|
|
||||||
for(n = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++n);
|
|
||||||
CHECK(n);
|
|
||||||
|
|
||||||
x = emalloc(l + 1, sizeof(int));
|
|
||||||
nl = emalloc(l + 1, sizeof(int));
|
|
||||||
ncl = emalloc(l + 1, sizeof(int));
|
|
||||||
|
|
||||||
for(i = 0; i < l + 1; ++i)
|
|
||||||
{
|
|
||||||
x[i] = sg.x;
|
|
||||||
nl[i] = 0;
|
|
||||||
ncl[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next))
|
|
||||||
{
|
|
||||||
for(; c->layer > l; --(c->layer));
|
|
||||||
++nl[c->layer];
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++i)
|
|
||||||
{
|
|
||||||
/* Set client property */
|
|
||||||
c->flags &= ~(MaxFlag | LMaxFlag);
|
|
||||||
c->flags |= TileFlag;
|
|
||||||
|
|
||||||
++ncl[c->layer];
|
|
||||||
|
|
||||||
geo.x = x[c->layer];
|
|
||||||
geo.height = (sg.height / l) - (BORDH + TBARH);
|
|
||||||
geo.width = (sg.width / ((nl[c->layer]) ? nl[c->layer] : 1)) - BORDH * 2;
|
|
||||||
geo.y = sg.y + ((geo.height + TBARH + BORDH) * c->layer) - (geo.height + TBARH + BORDH);
|
|
||||||
|
|
||||||
if(c->layer == l)
|
|
||||||
geo.height = (sg.y + sg.height) - geo.y - BORDH;
|
|
||||||
|
|
||||||
if(ncl[c->layer] == nl[c->layer])
|
|
||||||
geo.width = sg.width - (geo.x - (sg.x - (BORDH * 2)));
|
|
||||||
|
|
||||||
client_moveresize(c, geo, False);
|
|
||||||
|
|
||||||
x[c->layer] = geo.x + geo.width + BORDH * 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(x);
|
|
||||||
free(nl);
|
|
||||||
free(ncl);
|
|
||||||
|
|
||||||
ewmh_update_current_tag_prop();
|
ewmh_update_current_tag_prop();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -754,14 +695,24 @@ mirror_horizontal(int screen)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Put the selected client to the master postion
|
/** Horizontal grid function
|
||||||
* \param cmd uicb_t type unused
|
*/
|
||||||
*/
|
|
||||||
void
|
void
|
||||||
uicb_tile_switch(uicb_t cmd)
|
grid_horizontal(int screen)
|
||||||
{
|
{
|
||||||
layout_set_client_master (sel);
|
grid(screen, True);
|
||||||
return;
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Vertical grid function
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
grid_vertical(int screen)
|
||||||
|
{
|
||||||
|
grid(screen, False);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Toggle the selected client to free
|
/** Toggle the selected client to free
|
||||||
@@ -770,13 +721,16 @@ uicb_tile_switch(uicb_t cmd)
|
|||||||
void
|
void
|
||||||
uicb_togglefree(uicb_t cmd)
|
uicb_togglefree(uicb_t cmd)
|
||||||
{
|
{
|
||||||
|
(void)cmd;
|
||||||
|
|
||||||
if(!sel || sel->screen != screen_get_sel() || (sel->flags & FSSFlag))
|
if(!sel || sel->screen != screen_get_sel() || (sel->flags & FSSFlag))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sel->flags ^= FreeFlag;
|
sel->flags ^= FreeFlag;
|
||||||
|
|
||||||
if((sel->flags & FreeFlag))
|
if(sel->flags & FreeFlag)
|
||||||
{
|
{
|
||||||
|
split_set_current(NULL, sel);
|
||||||
sel->flags &= ~(TileFlag | MaxFlag | LMaxFlag);
|
sel->flags &= ~(TileFlag | MaxFlag | LMaxFlag);
|
||||||
client_moveresize(sel, sel->free_geo, True);
|
client_moveresize(sel, sel->free_geo, True);
|
||||||
client_raise(sel);
|
client_raise(sel);
|
||||||
@@ -785,41 +739,50 @@ uicb_togglefree(uicb_t cmd)
|
|||||||
{
|
{
|
||||||
sel->free_geo = sel->geo;
|
sel->free_geo = sel->geo;
|
||||||
sel->ogeo = sel->geo;
|
sel->ogeo = sel->geo;
|
||||||
|
split_set_current(sel, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
client_update_attributes(sel);
|
client_update_attributes(sel);
|
||||||
|
|
||||||
tags[selscreen][seltag[selscreen]].layout.func(selscreen);
|
tags[selscreen][seltag[selscreen]].flags |= CleanFactFlag;
|
||||||
|
layout_func(selscreen, seltag[selscreen]);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Toggle the selected client to max
|
/** Toggle the selected client to max
|
||||||
* \param cmd uicb_t type unused
|
* \param cmd uicb_t type unused
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
uicb_togglemax(uicb_t cmd)
|
uicb_togglemax(uicb_t cmd)
|
||||||
{
|
{
|
||||||
if(!sel || ishide(sel, selscreen)
|
(void)cmd;
|
||||||
|| (sel->flags & HintFlag)|| (sel->flags & FSSFlag))
|
|
||||||
|
if(!sel || ishide(sel, selscreen) || (sel->flags & (HintFlag | FSSFlag)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(!(sel->flags & MaxFlag))
|
sel->flags ^= MaxFlag;
|
||||||
|
|
||||||
|
if(sel->flags & MaxFlag)
|
||||||
{
|
{
|
||||||
sel->ogeo = sel->geo;
|
sel->ogeo = sel->geo;
|
||||||
sel->free_geo = sel->geo;
|
sel->free_geo = sel->geo;
|
||||||
sel->flags &= ~(TileFlag | FreeFlag);
|
sel->flags &= ~(TileFlag | FreeFlag);
|
||||||
|
|
||||||
|
split_set_current(NULL, sel);
|
||||||
client_maximize(sel);
|
client_maximize(sel);
|
||||||
client_raise(sel);
|
XRaiseWindow(dpy, sel->frame);
|
||||||
sel->flags |= MaxFlag;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sel->geo = sel->free_geo;
|
sel->geo = sel->ogeo;
|
||||||
|
|
||||||
client_moveresize(sel, sel->geo, True);
|
client_moveresize(sel, sel->geo, True);
|
||||||
sel->flags &= ~MaxFlag;
|
|
||||||
tags[selscreen][seltag[selscreen]].layout.func(selscreen);
|
tags[selscreen][seltag[selscreen]].flags |= CleanFactFlag;
|
||||||
|
|
||||||
|
split_set_current(sel, NULL);
|
||||||
|
layout_func(selscreen, seltag[selscreen]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -831,11 +794,15 @@ uicb_togglemax(uicb_t cmd)
|
|||||||
void
|
void
|
||||||
uicb_toggle_resizehint(uicb_t cmd)
|
uicb_toggle_resizehint(uicb_t cmd)
|
||||||
{
|
{
|
||||||
|
Client *c;
|
||||||
|
|
||||||
screen_get_sel();
|
screen_get_sel();
|
||||||
|
(void)cmd;
|
||||||
|
|
||||||
tags[selscreen][seltag[selscreen]].resizehint = !tags[selscreen][seltag[selscreen]].resizehint;
|
tags[selscreen][seltag[selscreen]].flags ^= ResizeHintFlag;
|
||||||
|
|
||||||
tags[selscreen][seltag[selscreen]].layout.func(selscreen);
|
for(c = tiled_client(selscreen, clients); c; c = tiled_client(selscreen, c->next))
|
||||||
|
client_moveresize(c, c->geo, (tags[selscreen][seltag[selscreen]].flags & ResizeHintFlag));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -847,21 +814,25 @@ void
|
|||||||
uicb_toggle_abovefc(uicb_t cmd)
|
uicb_toggle_abovefc(uicb_t cmd)
|
||||||
{
|
{
|
||||||
Client *c;
|
Client *c;
|
||||||
|
(void)cmd;
|
||||||
|
|
||||||
screen_get_sel();
|
screen_get_sel();
|
||||||
|
|
||||||
if(!(tags[selscreen][seltag[selscreen]].abovefc = !tags[selscreen][seltag[selscreen]].abovefc))
|
tags[selscreen][seltag[selscreen]].flags ^= AboveFCFlag;
|
||||||
|
|
||||||
|
if(!(tags[selscreen][seltag[selscreen]].flags & AboveFCFlag))
|
||||||
{
|
{
|
||||||
for(c = clients; c; c = c->next)
|
for(c = clients; c; c = c->next)
|
||||||
if(c->flags & AboveFlag
|
if(c->flags & AboveFlag
|
||||||
&& c->screen == selscreen
|
&& c->screen == selscreen
|
||||||
&& c->tag == seltag[selscreen])
|
&& c->tag == (uint)seltag[selscreen])
|
||||||
{
|
{
|
||||||
c->flags &= ~AboveFlag;
|
c->flags &= ~AboveFlag;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
tags[selscreen][seltag[selscreen]].layout.func(selscreen);
|
tags[selscreen][seltag[selscreen]].flags |= CleanFactFlag;
|
||||||
|
layout_func(selscreen, seltag[selscreen]);
|
||||||
}
|
}
|
||||||
|
|
||||||
client_focus(sel);
|
client_focus(sel);
|
||||||
@@ -875,7 +846,7 @@ uicb_toggle_abovefc(uicb_t cmd)
|
|||||||
void
|
void
|
||||||
uicb_set_layout(uicb_t cmd)
|
uicb_set_layout(uicb_t cmd)
|
||||||
{
|
{
|
||||||
int i, j, n;
|
size_t i, j, n;
|
||||||
|
|
||||||
screen_get_sel();
|
screen_get_sel();
|
||||||
|
|
||||||
@@ -883,11 +854,13 @@ uicb_set_layout(uicb_t cmd)
|
|||||||
for(n = 0; layout_list[n].name != NULL && layout_list[n].func != NULL; ++n);
|
for(n = 0; layout_list[n].name != NULL && layout_list[n].func != NULL; ++n);
|
||||||
|
|
||||||
for(i = 0; i < n; ++i)
|
for(i = 0; i < n; ++i)
|
||||||
if(!strcmp(cmd, _strdup(layout_list[i].name)))
|
if(!strcmp(cmd, xstrdup(layout_list[i].name)))
|
||||||
for(j = 0; j < LEN(conf.layout); ++j)
|
for(j = 0; j < LEN(conf.layout); ++j)
|
||||||
if(layout_list[i].func == conf.layout[j].func)
|
if(layout_list[i].func == conf.layout[j].func)
|
||||||
tags[selscreen][seltag[selscreen]].layout = conf.layout[j];
|
tags[selscreen][seltag[selscreen]].layout = conf.layout[j];
|
||||||
|
|
||||||
|
tags[selscreen][seltag[selscreen]].flags |= CleanFactFlag;
|
||||||
|
tags[selscreen][seltag[selscreen]].flags &= ~SplitFlag;
|
||||||
arrange(selscreen, True);
|
arrange(selscreen, True);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -901,8 +874,7 @@ layout_set_client_master(Client *c)
|
|||||||
{
|
{
|
||||||
screen_get_sel();
|
screen_get_sel();
|
||||||
|
|
||||||
if(!c || (c->flags & HintFlag) || !(c->flags & TileFlag)
|
if(!c || (c->flags & (HintFlag | FSSFlag)) || !(c->flags & TileFlag))
|
||||||
|| (c->flags & FSSFlag))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(c == tiled_client(selscreen, clients))
|
if(c == tiled_client(selscreen, clients))
|
||||||
@@ -910,9 +882,9 @@ layout_set_client_master(Client *c)
|
|||||||
|
|
||||||
client_detach(c);
|
client_detach(c);
|
||||||
client_attach(c);
|
client_attach(c);
|
||||||
client_focus(c);
|
|
||||||
|
|
||||||
tags[selscreen][seltag[selscreen]].layout.func(selscreen);
|
tags[selscreen][seltag[selscreen]].flags |= CleanFactFlag;
|
||||||
|
layout_func(selscreen, seltag[selscreen]);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -920,9 +892,11 @@ layout_set_client_master(Client *c)
|
|||||||
/** Check the selected client is max
|
/** Check the selected client is max
|
||||||
* \param cmd uicb_t type unused
|
* \param cmd uicb_t type unused
|
||||||
*/
|
*/
|
||||||
Bool
|
bool
|
||||||
uicb_checkmax(uicb_t cmd)
|
uicb_checkmax(uicb_t cmd)
|
||||||
{
|
{
|
||||||
|
(void)cmd;
|
||||||
|
|
||||||
if(!sel)
|
if(!sel)
|
||||||
return False;
|
return False;
|
||||||
|
|
||||||
@@ -935,9 +909,11 @@ uicb_checkmax(uicb_t cmd)
|
|||||||
/** Check the selected client is free
|
/** Check the selected client is free
|
||||||
* \param cmd uicb_t type unused
|
* \param cmd uicb_t type unused
|
||||||
*/
|
*/
|
||||||
Bool
|
bool
|
||||||
uicb_checkfree(uicb_t cmd)
|
uicb_checkfree(uicb_t cmd)
|
||||||
{
|
{
|
||||||
|
(void)cmd;
|
||||||
|
|
||||||
if(!sel)
|
if(!sel)
|
||||||
return False;
|
return False;
|
||||||
|
|
||||||
@@ -950,12 +926,13 @@ uicb_checkfree(uicb_t cmd)
|
|||||||
/** Check layout type
|
/** Check layout type
|
||||||
* \param cmd uicb_t type layout type
|
* \param cmd uicb_t type layout type
|
||||||
*/
|
*/
|
||||||
Bool
|
bool
|
||||||
uicb_checklayout(uicb_t cmd)
|
uicb_checklayout(uicb_t cmd)
|
||||||
{
|
{
|
||||||
screen_get_sel();
|
screen_get_sel();
|
||||||
|
char *type = tags[selscreen][seltag[selscreen]].layout.type;
|
||||||
|
|
||||||
if(!strcmp(cmd, tags[selscreen][seltag[selscreen]].layout.type))
|
if(type && !strcmp(cmd, type))
|
||||||
return True;
|
return True;
|
||||||
|
|
||||||
return False;
|
return False;
|
||||||
|
|||||||
366
src/menu.c
366
src/menu.c
@@ -32,98 +32,124 @@
|
|||||||
|
|
||||||
#include "wmfs.h"
|
#include "wmfs.h"
|
||||||
|
|
||||||
void
|
static int
|
||||||
menu_init(Menu *menu, char *name, int nitem, uint bg_f, char *fg_f, uint bg_n, char *fg_n)
|
menu_get_longer_string(MenuItem *mi, int nitem)
|
||||||
{
|
{
|
||||||
/* Item */
|
int i, w, l = 0;
|
||||||
menu->nitem = nitem;
|
|
||||||
menu->item = emalloc(sizeof(MenuItem), nitem);
|
|
||||||
menu->name = name;
|
|
||||||
|
|
||||||
/* Colors */
|
for(i = 0; i < nitem; ++i)
|
||||||
menu->colors.focus.bg = bg_f;
|
if((w = textw(mi[i].name)) > l)
|
||||||
menu->colors.focus.fg = fg_f;
|
l = w;
|
||||||
menu->colors.normal.bg = bg_n;
|
|
||||||
menu->colors.normal.fg = fg_n;
|
|
||||||
|
|
||||||
return;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static bool
|
||||||
menu_new_item(MenuItem *mi, char *name, void *func, char *cmd)
|
menu_get_checkstring_needed(MenuItem *mi, int nitem)
|
||||||
{
|
{
|
||||||
mi->name = name;
|
(void)mi;
|
||||||
mi->func = func;
|
(void)nitem;
|
||||||
mi->cmd = cmd;
|
return True;
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
menu_draw(Menu menu, int x, int y)
|
menu_draw_item_name(Menu *menu, int item, BarWindow *winitem[], int chcklen)
|
||||||
{
|
{
|
||||||
int i, width, height, out;
|
int x;
|
||||||
XEvent ev;
|
int width = menu_get_longer_string(menu->item, menu->nitem) + chcklen + PAD / 3;
|
||||||
BarWindow *item[menu.nitem];
|
|
||||||
BarWindow *frame;
|
|
||||||
|
|
||||||
width = menu_get_longer_string(menu.item, menu.nitem) + PAD * 3;
|
switch(menu->align)
|
||||||
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 * 2,
|
|
||||||
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,
|
case MA_Left:
|
||||||
SHADH,
|
x = chcklen + PAD / 2;
|
||||||
(i * (INFOBARH - SHADH) + SHADH),
|
break;
|
||||||
width - SHADH,
|
case MA_Right:
|
||||||
INFOBARH - SHADH,
|
x = width - textw(menu->item[item].name) + PAD * 3 / 2;
|
||||||
menu.colors.normal.bg,
|
break;
|
||||||
menu.colors.normal.fg,
|
default:
|
||||||
True, False, False);
|
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);
|
||||||
|
|
||||||
barwin_map(item[i]);
|
if(menu->item[item].check)
|
||||||
barwin_refresh_color(item[i]);
|
if(menu->item[item].check(menu->item[item].cmd))
|
||||||
menu_draw_item_name(&menu, i, item);
|
barwin_draw_text(winitem[item], PAD / 3, FHINFOBAR, conf.selected_layout_symbol);
|
||||||
barwin_refresh(item[i]);
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Select the first item */
|
return False;
|
||||||
menu_focus_item(&menu, 0, item);
|
}
|
||||||
|
|
||||||
XGrabKeyboard(dpy, ROOT, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
static void
|
||||||
|
menu_focus_item(Menu *menu, int item, BarWindow *winitem[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
while(!menu_manage_event(&ev, &menu, item));
|
int chcklen = 0;
|
||||||
|
if(menu_get_checkstring_needed(menu->item, menu->nitem))
|
||||||
|
chcklen = textw(conf.selected_layout_symbol) + PAD / 3;
|
||||||
|
|
||||||
XUngrabKeyboard(dpy, CurrentTime);
|
menu->focus_item = item;
|
||||||
|
|
||||||
for(i = 0; i < menu.nitem; ++i)
|
if(menu->focus_item > menu->nitem - 1)
|
||||||
barwin_delete(item[i]);
|
menu->focus_item = 0;
|
||||||
barwin_delete(frame);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool
|
static bool
|
||||||
menu_manage_event(XEvent *ev, Menu *menu, BarWindow *winitem[])
|
menu_manage_event(XEvent *ev, Menu *menu, BarWindow *winitem[])
|
||||||
{
|
{
|
||||||
int i, c = 0;
|
int i, c = 0;
|
||||||
KeySym ks;
|
KeySym ks = 0;
|
||||||
Bool quit = False;
|
bool quit = False;
|
||||||
|
char acc = 0;
|
||||||
|
|
||||||
switch(ev->type)
|
switch(ev->type)
|
||||||
{
|
{
|
||||||
@@ -178,114 +204,33 @@ menu_manage_event(XEvent *ev, Menu *menu, BarWindow *winitem[])
|
|||||||
/* For focus an item with the mouse */
|
/* For focus an item with the mouse */
|
||||||
for(i = 0; i < menu->nitem; ++i)
|
for(i = 0; i < menu->nitem; ++i)
|
||||||
if(ev->xcrossing.window == winitem[i]->win)
|
if(ev->xcrossing.window == winitem[i]->win)
|
||||||
|
{
|
||||||
|
acc = 1;
|
||||||
menu_focus_item(menu, i, winitem);
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
getevent(*ev);
|
if(ev->type < nevent && ev->type > 0)
|
||||||
|
HANDLE_EVENT(ev);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
XNextEvent(dpy, ev);
|
XNextEvent(dpy, ev);
|
||||||
|
|
||||||
return quit;
|
return quit;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool
|
|
||||||
menu_activate_item(Menu *menu, int i)
|
|
||||||
{
|
|
||||||
int j, x, y;
|
|
||||||
|
|
||||||
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) + 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
menu_focus_item(Menu *menu, int item, BarWindow *winitem[])
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
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);
|
|
||||||
barwin_refresh(winitem[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
menu_draw_item_name(Menu *menu, int item, BarWindow *winitem[])
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
int width = menu_get_longer_string(menu->item, menu->nitem);
|
|
||||||
|
|
||||||
switch(menu->align)
|
|
||||||
{
|
|
||||||
case MA_Left:
|
|
||||||
x = PAD * 3 / 2;
|
|
||||||
break;
|
|
||||||
case MA_Right:
|
|
||||||
x = width - textw(menu->item[item].name) + PAD * 3 / 2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
case MA_Center:
|
|
||||||
x = width / 2 - textw(menu->item[item].name) / 2 + PAD * 3 / 2;
|
|
||||||
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, "*");
|
|
||||||
|
|
||||||
if(menu->item[item].submenu)
|
|
||||||
barwin_draw_text(winitem[item], width + PAD * 2, FHINFOBAR, ">");
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
uicb_menu(uicb_t cmd)
|
uicb_menu(uicb_t cmd)
|
||||||
{
|
{
|
||||||
@@ -319,9 +264,100 @@ uicb_menu(uicb_t cmd)
|
|||||||
void
|
void
|
||||||
menu_clear(Menu *menu)
|
menu_clear(Menu *menu)
|
||||||
{
|
{
|
||||||
IFREE(menu->item);
|
free(menu->item);
|
||||||
menu->nitem = 0;
|
menu->nitem = 0;
|
||||||
|
|
||||||
return;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
102
src/mouse.c
102
src/mouse.c
@@ -32,37 +32,50 @@
|
|||||||
|
|
||||||
#include "wmfs.h"
|
#include "wmfs.h"
|
||||||
|
|
||||||
|
Window prevwin;
|
||||||
|
|
||||||
/** Draw the border when a client in dragging/resizing with mouse
|
/** Draw the border when a client in dragging/resizing with mouse
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
mouse_dragborder(XRectangle geo, GC g)
|
mouse_dragborder(Geo geo, GC g)
|
||||||
{
|
{
|
||||||
XDrawRectangle(dpy, ROOT, g,
|
XDrawRectangle(dpy, ROOT, g,
|
||||||
geo.x - BORDH / 2,
|
geo.x - (BORDH >> 1),
|
||||||
geo.y - (TBARH - (BORDH / 2)),
|
geo.y - (TBARH - (BORDH >> 1)),
|
||||||
geo.width + BORDH,
|
geo.width + BORDH,
|
||||||
geo.height + TBARH);
|
geo.height + TBARH);
|
||||||
|
|
||||||
return;
|
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
|
/** Move a client in tile grid with the mouse
|
||||||
*\param c Client double pointer
|
*\param c Client double pointer
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
mouse_move_tile_client(Client **c)
|
mouse_move_tile_client(Client **c)
|
||||||
{
|
{
|
||||||
Client *sc;
|
Client *sc;
|
||||||
Window w;
|
Window w;
|
||||||
int d;
|
int d;
|
||||||
|
|
||||||
if(!((*c)->flags & TileFlag) && !((*c)->flags & LMaxFlag))
|
if(!((*c)->flags & (TileFlag | LMaxFlag)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
XQueryPointer(dpy, ROOT, &w, &w, &d, &d, &d, &d, (uint*)&d);
|
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)))
|
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))
|
&& (*c)->win != sc->win && !((*c)->flags & HideFlag) && !(sc->flags & HideFlag) && (sc->flags & TileFlag))
|
||||||
{
|
{
|
||||||
client_swap(sc, *c);
|
client_swap(sc, *c);
|
||||||
client_focus(sc);
|
client_focus(sc);
|
||||||
@@ -76,27 +89,29 @@ mouse_move_tile_client(Client **c)
|
|||||||
/** Move a client from one tag to another with dah mouse
|
/** Move a client from one tag to another with dah mouse
|
||||||
*\param c client pointer
|
*\param c client pointer
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
mouse_move_tag_client(Client *c)
|
mouse_move_tag_client(Client *c)
|
||||||
{
|
{
|
||||||
Window w;
|
Window w;
|
||||||
int i, d, s;
|
int i, d, s;
|
||||||
|
|
||||||
if(!(c->flags & TileFlag) && !(c->flags & LMaxFlag))
|
if(!(c->flags & (TileFlag | LMaxFlag)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
s = c->screen;
|
s = c->screen;
|
||||||
|
|
||||||
XQueryPointer(dpy, infobar[selscreen].tags_board->win, &w, &w, &d, &d, &d, &d, (uint*)&d);
|
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)
|
for(i = 1; i < conf.ntag[selscreen] + 1; ++i)
|
||||||
if(infobar[selscreen].tags[i]->win == w
|
if(infobar[selscreen].tags[i]->win == w
|
||||||
&& tags[selscreen][i].layout.func != freelayout)
|
&& tags[selscreen][i].layout.func != freelayout)
|
||||||
{
|
{
|
||||||
c->screen = selscreen;
|
tag_transfert(c, i);
|
||||||
c->tag = i;
|
|
||||||
tags[c->screen][c->tag].request_update = True;
|
|
||||||
arrange(s, True);
|
|
||||||
|
|
||||||
if(s != c->screen)
|
if(s != c->screen)
|
||||||
arrange(c->screen, True);
|
arrange(c->screen, True);
|
||||||
@@ -108,19 +123,19 @@ mouse_move_tag_client(Client *c)
|
|||||||
/** Move the client with the mouse
|
/** Move the client with the mouse
|
||||||
* \param c Client pointer
|
* \param c Client pointer
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
mouse_move(Client *c)
|
mouse_move(Client *c)
|
||||||
{
|
{
|
||||||
int ocx, ocy, mx, my;
|
int ocx, ocy, mx, my;
|
||||||
int dint;
|
int dint;
|
||||||
uint duint;
|
uint duint;
|
||||||
Window dw;
|
Window dw;
|
||||||
XRectangle geo = c->geo;
|
Geo geo = c->geo;
|
||||||
XGCValues xgc;
|
XGCValues xgc;
|
||||||
GC gci;
|
GC gci;
|
||||||
XEvent ev;
|
XEvent ev;
|
||||||
|
|
||||||
if((c->flags & MaxFlag) || (c->flags & FSSFlag))
|
if(c->flags & (MaxFlag | FSSFlag))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ocx = c->geo.x;
|
ocx = c->geo.x;
|
||||||
@@ -169,14 +184,13 @@ mouse_move(Client *c)
|
|||||||
mouse_dragborder(geo, gci);
|
mouse_dragborder(geo, gci);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(ev.type == MapRequest
|
else if((ev.type == MapRequest || ev.type == ConfigureRequest))
|
||||||
|| ev.type == ConfigureRequest)
|
HANDLE_EVENT(&ev);
|
||||||
getevent(ev);
|
|
||||||
}
|
}
|
||||||
while(ev.type != ButtonRelease);
|
while(ev.type != ButtonRelease);
|
||||||
|
|
||||||
/* One time again to delete all the trace on the window */
|
/* One time again to delete all the trace on the window */
|
||||||
if(!(c->flags & TileFlag) && !(c->flags & LMaxFlag))
|
if(!(c->flags & (TileFlag | LMaxFlag)))
|
||||||
{
|
{
|
||||||
mouse_dragborder(geo, gci);
|
mouse_dragborder(geo, gci);
|
||||||
client_moveresize(c, geo, False);
|
client_moveresize(c, geo, False);
|
||||||
@@ -197,23 +211,21 @@ mouse_move(Client *c)
|
|||||||
void
|
void
|
||||||
mouse_resize(Client *c)
|
mouse_resize(Client *c)
|
||||||
{
|
{
|
||||||
XRectangle geo = c->geo, ogeo = c->geo;
|
Geo geo = c->geo, ogeo = c->geo;
|
||||||
Position pos = Right;
|
Position pos = Right;
|
||||||
XEvent ev;
|
XEvent ev;
|
||||||
Window w;
|
Window w;
|
||||||
int d, u, omx, omy;
|
int d, u, omx, omy;
|
||||||
XGCValues xgc;
|
XGCValues xgc;
|
||||||
GC gci;
|
GC gci;
|
||||||
float mwf = tags[selscreen][seltag[selscreen]].mwfact;
|
int f[4] = { 0 };
|
||||||
|
|
||||||
if((c->flags & MaxFlag)
|
if(c->flags & (MaxFlag | LMaxFlag | FSSFlag))
|
||||||
|| (c->flags & LMaxFlag)
|
|
||||||
|| (c->flags & FSSFlag))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
XQueryPointer(dpy, ROOT, &w, &w, &omx, &omy, &d, &d, (uint *)&u);
|
XQueryPointer(dpy, ROOT, &w, &w, &omx, &omy, &d, &d, (uint *)&u);
|
||||||
|
|
||||||
if((omx - c->geo.x) < (c->geo.width / 2))
|
if((omx - c->geo.x) < (c->geo.width >> 1))
|
||||||
pos = Left;
|
pos = Left;
|
||||||
|
|
||||||
if(XGrabPointer(dpy, ROOT, False, MouseMask, GrabModeAsync, GrabModeAsync, None,
|
if(XGrabPointer(dpy, ROOT, False, MouseMask, GrabModeAsync, GrabModeAsync, None,
|
||||||
@@ -238,6 +250,8 @@ mouse_resize(Client *c)
|
|||||||
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, 0, c->geo.height);
|
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, 0, c->geo.height);
|
||||||
mouse_dragborder(c->geo, gci);
|
mouse_dragborder(c->geo, gci);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
mouse_cfactor_border(c, f, gci);
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@@ -245,23 +259,22 @@ mouse_resize(Client *c)
|
|||||||
|
|
||||||
if(ev.type == MotionNotify)
|
if(ev.type == MotionNotify)
|
||||||
{
|
{
|
||||||
/* To resize MWFACT in tile mode */
|
/* To resize client in tile mode with cfactor */
|
||||||
if((c->flags & TileFlag)
|
if(c->flags & TileFlag)
|
||||||
&& tags[selscreen][seltag[selscreen]].layout.func != grid)
|
|
||||||
{
|
{
|
||||||
if(tags[selscreen][seltag[selscreen]].layout.func == tile)
|
mouse_cfactor_border(c, f, gci);
|
||||||
mwf += (ROUND(ev.xmotion.x_root) - omx) / (sgeo[c->screen].width);
|
|
||||||
else if(tags[selscreen][seltag[selscreen]].layout.func == tile_left)
|
if(omx >= c->frame_geo.x + (c->frame_geo.width >> 1))
|
||||||
mwf -= (ROUND(ev.xmotion.x_root) - omx) / (sgeo[c->screen].width);
|
f[Right] = ev.xmotion.x_root - omx;
|
||||||
else if(tags[selscreen][seltag[selscreen]].layout.func == tile_top)
|
|
||||||
mwf -= (ROUND(ev.xmotion.y_root) - omy) / (sgeo[c->screen].height);
|
|
||||||
else
|
else
|
||||||
mwf += (ROUND(ev.xmotion.y_root) - omy) / (sgeo[c->screen].height);
|
f[Left] = omx - ev.xmotion.x_root;
|
||||||
|
|
||||||
omx = ROUND(ev.xmotion.x_root);
|
if(omy >= c->frame_geo.y + (c->frame_geo.height >> 1))
|
||||||
omy = ROUND(ev.xmotion.y_root);
|
f[Bottom] = ev.xmotion.y_root - omy;
|
||||||
|
else
|
||||||
|
f[Top] = omy - ev.xmotion.y_root;
|
||||||
|
|
||||||
tags[selscreen][seltag[selscreen]].mwfact = (mwf < 0.05) ? 0.05 : ((mwf > 0.95) ? 0.95 : mwf);
|
mouse_cfactor_border(c, f, gci);
|
||||||
}
|
}
|
||||||
/* Free mode */
|
/* Free mode */
|
||||||
else if(!(c->flags & TileFlag))
|
else if(!(c->flags & TileFlag))
|
||||||
@@ -300,7 +313,10 @@ mouse_resize(Client *c)
|
|||||||
XUngrabServer(dpy);
|
XUngrabServer(dpy);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
tags[selscreen][seltag[selscreen]].layout.func(c->screen);
|
{
|
||||||
|
mouse_cfactor_border(c, f, gci);
|
||||||
|
cfactor_multi_set(c, f);
|
||||||
|
}
|
||||||
|
|
||||||
client_update_attributes(c);
|
client_update_attributes(c);
|
||||||
XUngrabPointer(dpy, CurrentTime);
|
XUngrabPointer(dpy, CurrentTime);
|
||||||
@@ -314,9 +330,9 @@ mouse_resize(Client *c)
|
|||||||
* \param focused For know if c is or not focused
|
* \param focused For know if c is or not focused
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
mouse_grabbuttons(Client *c, Bool focused)
|
mouse_grabbuttons(Client *c, bool focused)
|
||||||
{
|
{
|
||||||
int i;
|
size_t i;
|
||||||
uint but[] = {Button1, Button2, Button3, Button4, Button5};
|
uint but[] = {Button1, Button2, Button3, Button4, Button5};
|
||||||
|
|
||||||
XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
|
XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
|
||||||
@@ -345,6 +361,7 @@ mouse_grabbuttons(Client *c, Bool focused)
|
|||||||
void
|
void
|
||||||
uicb_mouse_move(uicb_t cmd)
|
uicb_mouse_move(uicb_t cmd)
|
||||||
{
|
{
|
||||||
|
(void)cmd;
|
||||||
CHECK(sel);
|
CHECK(sel);
|
||||||
|
|
||||||
mouse_move(sel);
|
mouse_move(sel);
|
||||||
@@ -358,6 +375,7 @@ uicb_mouse_move(uicb_t cmd)
|
|||||||
void
|
void
|
||||||
uicb_mouse_resize(uicb_t cmd)
|
uicb_mouse_resize(uicb_t cmd)
|
||||||
{
|
{
|
||||||
|
(void)cmd;
|
||||||
CHECK(sel);
|
CHECK(sel);
|
||||||
|
|
||||||
mouse_resize(sel);
|
mouse_resize(sel);
|
||||||
|
|||||||
626
src/parse.c
Normal file
626
src/parse.c
Normal file
@@ -0,0 +1,626 @@
|
|||||||
|
/*
|
||||||
|
* 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 ((fd = open(filename, O_RDONLY)) == -1 || stat(filename, &st) == -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;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -17,14 +17,19 @@
|
|||||||
#ifndef PARSE_H
|
#ifndef PARSE_H
|
||||||
#define PARSE_H
|
#define PARSE_H
|
||||||
|
|
||||||
|
#include "wmfs.h"
|
||||||
#include <sys/queue.h>
|
#include <sys/queue.h>
|
||||||
|
|
||||||
|
#define INCLUDE_CMD "@include"
|
||||||
|
#define PARSE_MAX_LIST 32
|
||||||
|
|
||||||
struct conf_opt {
|
struct conf_opt {
|
||||||
char *name;
|
char *name;
|
||||||
char *val[10];
|
char *val[PARSE_MAX_LIST];
|
||||||
size_t nval;
|
size_t nval;
|
||||||
Bool used;
|
bool used;
|
||||||
int line;
|
int line;
|
||||||
|
char *filename;
|
||||||
SLIST_ENTRY(conf_opt) entry;
|
SLIST_ENTRY(conf_opt) entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -40,7 +45,7 @@ struct conf_sec {
|
|||||||
struct opt_type {
|
struct opt_type {
|
||||||
long int num;
|
long int num;
|
||||||
float fnum;
|
float fnum;
|
||||||
Bool bool;
|
bool boolean;
|
||||||
char *str;
|
char *str;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -61,7 +66,7 @@ void print_unused(struct conf_sec *s);
|
|||||||
* WARNING: This make all string
|
* WARNING: This make all string
|
||||||
* returned by fetch_(opt|section)(_first) unusable.
|
* returned by fetch_(opt|section)(_first) unusable.
|
||||||
*/
|
*/
|
||||||
void free_conf(struct conf_sec *s);
|
int free_conf(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get all subsection matching the given name on the given
|
* Get all subsection matching the given name on the given
|
||||||
@@ -1,605 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define _BSD_SOURCE
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <err.h>
|
|
||||||
|
|
||||||
#include "../wmfs.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define TOKEN(t) \
|
|
||||||
do { \
|
|
||||||
kw->type = (t); \
|
|
||||||
TAILQ_INSERT_TAIL(&keywords, kw, entry); \
|
|
||||||
kw = malloc(sizeof(*kw)); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define NEW_WORD() \
|
|
||||||
do { \
|
|
||||||
if (j > 0) { \
|
|
||||||
e->name[j] = '\0'; \
|
|
||||||
e->line = file.line; \
|
|
||||||
TAILQ_INSERT_TAIL(&stack, e, entry); \
|
|
||||||
e = malloc(sizeof(*e)); \
|
|
||||||
j = 0; \
|
|
||||||
TOKEN(WORD); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
enum conf_type { SEC_START, SEC_END, WORD, EQUAL, LIST_START, LIST_END, NONE };
|
|
||||||
|
|
||||||
struct conf_keyword {
|
|
||||||
enum conf_type type;
|
|
||||||
TAILQ_ENTRY(conf_keyword) entry;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct conf_stack {
|
|
||||||
char name[BUFSIZ];
|
|
||||||
int line;
|
|
||||||
TAILQ_ENTRY(conf_stack) entry;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct conf_state {
|
|
||||||
Bool quote;
|
|
||||||
Bool comment;
|
|
||||||
char quote_char;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void get_keyword(const char *buf, size_t n);
|
|
||||||
static void pop_keyword(void);
|
|
||||||
static void pop_stack(void);
|
|
||||||
static struct conf_sec *get_section(void);
|
|
||||||
static struct conf_opt *get_option(void);
|
|
||||||
static struct opt_type string_to_opt(char *);
|
|
||||||
#ifdef DEBUG
|
|
||||||
static void print_kw_tree(void);
|
|
||||||
static char * get_kw_name(enum conf_type);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static TAILQ_HEAD(, conf_keyword) keywords;
|
|
||||||
static TAILQ_HEAD(, conf_stack) stack;
|
|
||||||
static TAILQ_HEAD(, conf_sec) config;
|
|
||||||
static struct conf_keyword *curk; /* current keyword */
|
|
||||||
static struct conf_stack *curw; /* current word */
|
|
||||||
static const struct opt_type opt_type_null = { 0, 0, False, NULL };
|
|
||||||
|
|
||||||
static struct {
|
|
||||||
const char *name;
|
|
||||||
int line;
|
|
||||||
} file = { NULL, 1 };
|
|
||||||
|
|
||||||
static void
|
|
||||||
get_keyword(const char *buf, size_t n)
|
|
||||||
{
|
|
||||||
struct conf_keyword *kw;
|
|
||||||
size_t j, i;
|
|
||||||
struct conf_state s = { False, False, '\0' };
|
|
||||||
struct conf_stack *e;
|
|
||||||
|
|
||||||
TAILQ_INIT(&stack);
|
|
||||||
TAILQ_INIT(&keywords);
|
|
||||||
kw = emalloc(1, sizeof(*kw));
|
|
||||||
e = emalloc(1, sizeof(*e));
|
|
||||||
|
|
||||||
for(i = 0, j = 0; i < n; i++)
|
|
||||||
{
|
|
||||||
if (buf[i] == '\n' && s.comment == True) {
|
|
||||||
file.line++;
|
|
||||||
s.comment = False;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf[i] == '#' && s.quote == False) {
|
|
||||||
s.comment = True;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s.comment == True)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (buf[i] == s.quote_char && s.quote == True) {
|
|
||||||
NEW_WORD();
|
|
||||||
s.quote = False;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((buf[i] == '"' || buf[i] == '\'') &&
|
|
||||||
s.quote == False)
|
|
||||||
{
|
|
||||||
s.quote_char = buf[i];
|
|
||||||
s.quote = True;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf[i] == '[' && s.quote == False) {
|
|
||||||
NEW_WORD();
|
|
||||||
TOKEN((buf[i+1] == '/') ? SEC_END : SEC_START);
|
|
||||||
if (buf[i+1] == '/')
|
|
||||||
i++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf[i] == ']' && s.quote == False) {
|
|
||||||
NEW_WORD();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf[i] == '{' && s.quote == False) {
|
|
||||||
NEW_WORD();
|
|
||||||
TOKEN(LIST_START);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf[i] == '}' && s.quote == False) {
|
|
||||||
NEW_WORD();
|
|
||||||
TOKEN(LIST_END);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf[i] == ',' && s.quote == False) {
|
|
||||||
NEW_WORD();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf[i] == '=' && s.quote == False) {
|
|
||||||
NEW_WORD();
|
|
||||||
TOKEN(EQUAL);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strchr("\t\n ", buf[i]) && s.quote == False) {
|
|
||||||
NEW_WORD();
|
|
||||||
if (buf[i] == '\n')
|
|
||||||
file.line++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
e->name[j++] = buf[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
static void
|
|
||||||
print_kw_tree(void)
|
|
||||||
{
|
|
||||||
struct conf_keyword *k;
|
|
||||||
struct conf_stack *s;
|
|
||||||
|
|
||||||
s = TAILQ_FIRST(&stack);
|
|
||||||
|
|
||||||
TAILQ_FOREACH(k, &keywords, entry)
|
|
||||||
printf("%s ", get_kw_name(k->type));
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
|
||||||
get_kw_name(enum conf_type type)
|
|
||||||
{
|
|
||||||
switch (type) {
|
|
||||||
case SEC_START:
|
|
||||||
return ("SEC_START");
|
|
||||||
break;
|
|
||||||
case SEC_END:
|
|
||||||
return ("SEC_END");
|
|
||||||
break;
|
|
||||||
case WORD:
|
|
||||||
return ("WORD");
|
|
||||||
break;
|
|
||||||
case LIST_START:
|
|
||||||
return ("LIST_START ");
|
|
||||||
break;
|
|
||||||
case LIST_END:
|
|
||||||
return ("LIST_END ");
|
|
||||||
break;
|
|
||||||
case EQUAL:
|
|
||||||
return ("EQUAL ");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return ("NONE ");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int
|
|
||||||
get_conf(const char *name)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
struct stat st;
|
|
||||||
char *buf;
|
|
||||||
struct conf_sec *s;
|
|
||||||
|
|
||||||
if (!name)
|
|
||||||
return (-1);
|
|
||||||
|
|
||||||
if ((fd = open(name, O_RDONLY)) == -1 ||
|
|
||||||
stat(name, &st) == -1)
|
|
||||||
{
|
|
||||||
warn("%s", name);
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = (char*)mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, SEEK_SET);
|
|
||||||
|
|
||||||
if (buf == (char*) MAP_FAILED)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
get_keyword(buf, st.st_size);
|
|
||||||
|
|
||||||
munmap(buf, st.st_size);
|
|
||||||
close(fd);
|
|
||||||
warnx("%s read", name);
|
|
||||||
|
|
||||||
file.name = name;
|
|
||||||
|
|
||||||
curk = TAILQ_FIRST(&keywords);
|
|
||||||
curw = TAILQ_FIRST(&stack);
|
|
||||||
|
|
||||||
TAILQ_INIT(&config);
|
|
||||||
|
|
||||||
while (!TAILQ_EMPTY(&keywords)) {
|
|
||||||
switch (curk->type) {
|
|
||||||
case SEC_START:
|
|
||||||
s = get_section();
|
|
||||||
TAILQ_INSERT_TAIL(&config, s, entry);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
errx(1, "%s:%d: near '%s', config out of any section",
|
|
||||||
file.name, curw->line, curw->name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct conf_sec *
|
|
||||||
get_section(void)
|
|
||||||
{
|
|
||||||
struct conf_sec *s;
|
|
||||||
struct conf_opt *o;
|
|
||||||
struct conf_sec *sub;
|
|
||||||
|
|
||||||
s = emalloc(1, sizeof(*s));
|
|
||||||
s->name = strdup(curw->name);
|
|
||||||
TAILQ_INIT(&s->sub);
|
|
||||||
SLIST_INIT(&s->optlist);
|
|
||||||
|
|
||||||
pop_stack();
|
|
||||||
pop_keyword();
|
|
||||||
|
|
||||||
if (curk->type != WORD)
|
|
||||||
errx(1, "%s:%d: near '%s', missing section name",
|
|
||||||
file.name, curw->line, curw->name);
|
|
||||||
pop_keyword();
|
|
||||||
|
|
||||||
while (curk->type != SEC_END) {
|
|
||||||
switch (curk->type) {
|
|
||||||
case WORD:
|
|
||||||
o = get_option();
|
|
||||||
SLIST_INSERT_HEAD(&s->optlist, o, entry);
|
|
||||||
s->nopt++;
|
|
||||||
break;
|
|
||||||
case SEC_START:
|
|
||||||
sub = get_section();
|
|
||||||
TAILQ_INSERT_TAIL(&s->sub, sub, entry);
|
|
||||||
s->nsub++;
|
|
||||||
case SEC_END:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
errx(1, "%s:%d: near '%s', syntax error",
|
|
||||||
file.name, curw->line, curw->name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pop_keyword();
|
|
||||||
|
|
||||||
if (curk->type != WORD)
|
|
||||||
errx(1, "%s:%d: near '%s', missing end-section name",
|
|
||||||
file.name, curw->line, curw->name);
|
|
||||||
|
|
||||||
if (strcmp(curw->name, s->name))
|
|
||||||
errx(1, "%s:%d: near '%s', non-closed section '%s'",
|
|
||||||
file.name, curw->line, curw->name, s->name);
|
|
||||||
|
|
||||||
pop_stack();
|
|
||||||
pop_keyword();
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static struct conf_opt *
|
|
||||||
get_option(void)
|
|
||||||
{
|
|
||||||
struct conf_opt *o;
|
|
||||||
size_t j = 0;
|
|
||||||
|
|
||||||
o = emalloc(1, sizeof(*o));
|
|
||||||
o->name = strdup(curw->name);
|
|
||||||
o->used = False;
|
|
||||||
o->line = curw->line;
|
|
||||||
pop_stack();
|
|
||||||
pop_keyword();
|
|
||||||
|
|
||||||
if (curk->type != EQUAL)
|
|
||||||
errx(1, "%s:%d: near '%s', missing '=' here",
|
|
||||||
file.name, curw->line, curw->name);
|
|
||||||
|
|
||||||
pop_keyword();
|
|
||||||
|
|
||||||
switch (curk->type) {
|
|
||||||
case WORD:
|
|
||||||
o->val[0] = strdup(curw->name);
|
|
||||||
o->val[1] = NULL;
|
|
||||||
pop_stack();
|
|
||||||
break;
|
|
||||||
case LIST_START:
|
|
||||||
pop_keyword();
|
|
||||||
while (curk->type != LIST_END) {
|
|
||||||
if (curk->type != WORD)
|
|
||||||
errx(1, "%s:%d: near '%s', declaration into a list",
|
|
||||||
file.name, curw->line, curw->name);
|
|
||||||
o->val[j++] = strdup(curw->name);
|
|
||||||
pop_stack();
|
|
||||||
pop_keyword();
|
|
||||||
}
|
|
||||||
o->val[j] = NULL;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
errx(1, "%s:%d: near '%s', syntax error",
|
|
||||||
file.name, curw->line, curw->name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pop_keyword();
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
pop_keyword(void)
|
|
||||||
{
|
|
||||||
TAILQ_REMOVE(&keywords, curk, entry);
|
|
||||||
#ifdef DEBUG
|
|
||||||
warnx("%s", get_kw_name(curk->type));
|
|
||||||
#endif
|
|
||||||
free(curk);
|
|
||||||
|
|
||||||
curk = TAILQ_FIRST(&keywords);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
pop_stack(void)
|
|
||||||
{
|
|
||||||
TAILQ_REMOVE(&stack, curw, entry);
|
|
||||||
#ifdef DEBUG
|
|
||||||
warnx("%s", curw->name);
|
|
||||||
#endif
|
|
||||||
free(curw);
|
|
||||||
|
|
||||||
curw = TAILQ_FIRST(&stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
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",
|
|
||||||
file.name, o->line, o->name);
|
|
||||||
|
|
||||||
TAILQ_FOREACH(s, &sec->sub, entry)
|
|
||||||
if (!TAILQ_EMPTY(&s->sub))
|
|
||||||
print_unused(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
free_conf(struct conf_sec *sec)
|
|
||||||
{
|
|
||||||
struct conf_sec *s;
|
|
||||||
struct conf_opt *o;
|
|
||||||
size_t n;
|
|
||||||
|
|
||||||
if (!sec)
|
|
||||||
{
|
|
||||||
TAILQ_FOREACH(s, &config, entry)
|
|
||||||
{
|
|
||||||
free(s->name);
|
|
||||||
free_conf(s);
|
|
||||||
free(s);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!SLIST_EMPTY(&sec->optlist))
|
|
||||||
{
|
|
||||||
o = SLIST_FIRST(&sec->optlist);
|
|
||||||
SLIST_REMOVE_HEAD(&sec->optlist, entry);
|
|
||||||
free(o->name);
|
|
||||||
|
|
||||||
for (n = 0; o->val[n]; n++)
|
|
||||||
free(o->val[n]);
|
|
||||||
|
|
||||||
free(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!TAILQ_EMPTY(&sec->sub))
|
|
||||||
{
|
|
||||||
s = TAILQ_FIRST(&sec->sub);
|
|
||||||
TAILQ_REMOVE(&sec->sub, s, entry);
|
|
||||||
free_conf(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 = emalloc(2, sizeof(struct conf_sec *));
|
|
||||||
TAILQ_FOREACH(sec, &config, entry)
|
|
||||||
if (!strcmp(sec->name, name)) {
|
|
||||||
ret[0] = sec;
|
|
||||||
ret[1] = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ret = emalloc(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 (!strcmp(sec->name, name)) {
|
|
||||||
ret = sec;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TAILQ_FOREACH(sec, &s->sub, entry)
|
|
||||||
if (!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 = emalloc(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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.bool = True;
|
|
||||||
else
|
|
||||||
ret.bool = False;
|
|
||||||
|
|
||||||
ret.str = s;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
197
src/parse_api.c
Normal file
197
src/parse_api.c
Normal file
@@ -0,0 +1,197 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
38
src/screen.c
38
src/screen.c
@@ -57,13 +57,13 @@ screen_count(void)
|
|||||||
|
|
||||||
/** Get screen geometry by number
|
/** Get screen geometry by number
|
||||||
*\param s Screen number
|
*\param s Screen number
|
||||||
*\return XRectangle struct
|
*\return Geo struct
|
||||||
*/
|
*/
|
||||||
XRectangle
|
Geo
|
||||||
screen_get_geo(int s)
|
screen_get_geo(int s)
|
||||||
{
|
{
|
||||||
int barpos = tags[selscreen][seltag[selscreen]].barpos;
|
int barpos = tags[selscreen][seltag[selscreen]].barpos;
|
||||||
XRectangle geo;
|
Geo geo;
|
||||||
|
|
||||||
geo.x = BORDH;
|
geo.x = BORDH;
|
||||||
if(barpos == IB_Hide || barpos == IB_Bottom)
|
if(barpos == IB_Hide || barpos == IB_Bottom)
|
||||||
@@ -91,6 +91,8 @@ screen_get_geo(int s)
|
|||||||
|
|
||||||
XFree(xsi);
|
XFree(xsi);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
(void)s;
|
||||||
#endif /* HAVE_XINERAMA */
|
#endif /* HAVE_XINERAMA */
|
||||||
|
|
||||||
return geo;
|
return geo;
|
||||||
@@ -104,14 +106,14 @@ screen_get_geo(int s)
|
|||||||
int
|
int
|
||||||
screen_get_with_geo(int x, int y)
|
screen_get_with_geo(int x, int y)
|
||||||
{
|
{
|
||||||
int i, r = 0;
|
int i;
|
||||||
|
|
||||||
for(i = 0; i < screen_count(); ++i)
|
for(i = 0; i < screen_count(); ++i)
|
||||||
if((x >= spgeo[i].x && x < spgeo[i].x + spgeo[i].width)
|
if((x >= spgeo[i].x && x < spgeo[i].x + spgeo[i].width)
|
||||||
&& y >= spgeo[i].y && y < spgeo[i].y + spgeo[i].height)
|
&& y >= spgeo[i].y && y < spgeo[i].y + spgeo[i].height)
|
||||||
r = i;
|
return i;
|
||||||
|
|
||||||
return r;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set the selected screen
|
/** Set the selected screen
|
||||||
@@ -123,12 +125,13 @@ screen_set_sel(int screen)
|
|||||||
if(screen < 0 || screen > screen_count() - 1)
|
if(screen < 0 || screen > screen_count() - 1)
|
||||||
screen = 0;
|
screen = 0;
|
||||||
|
|
||||||
prevselscreen = selscreen;
|
if(selscreen != screen)
|
||||||
|
prevselscreen = selscreen;
|
||||||
|
|
||||||
client_focus(NULL);
|
client_focus(NULL);
|
||||||
XWarpPointer(dpy, None, ROOT, 0, 0, 0, 0,
|
XWarpPointer(dpy, None, ROOT, 0, 0, 0, 0,
|
||||||
sgeo[screen].x + sgeo[screen].width / 2,
|
sgeo[screen].x + (sgeo[screen].width >> 1),
|
||||||
sgeo[screen].y + sgeo[screen].height / 2);
|
sgeo[screen].y + (sgeo[screen].height >> 1));
|
||||||
|
|
||||||
selscreen = screen;
|
selscreen = screen;
|
||||||
|
|
||||||
@@ -162,7 +165,7 @@ screen_get_sel(void)
|
|||||||
XChangeProperty(dpy, ROOT, net_atom[wmfs_current_screen], XA_CARDINAL, 32,
|
XChangeProperty(dpy, ROOT, net_atom[wmfs_current_screen], XA_CARDINAL, 32,
|
||||||
PropModeReplace, (uchar*)&selscreen, 1);
|
PropModeReplace, (uchar*)&selscreen, 1);
|
||||||
|
|
||||||
if(os != selscreen)
|
if(os != selscreen && os != prevselscreen)
|
||||||
prevselscreen = os;
|
prevselscreen = os;
|
||||||
|
|
||||||
return selscreen;
|
return selscreen;
|
||||||
@@ -176,8 +179,8 @@ screen_init_geo(void)
|
|||||||
int i;
|
int i;
|
||||||
int s = screen_count();
|
int s = screen_count();
|
||||||
|
|
||||||
sgeo = emalloc(s, sizeof(XRectangle));
|
sgeo = xcalloc(s, sizeof(Geo));
|
||||||
spgeo = emalloc(s, sizeof(XRectangle));
|
spgeo = xcalloc(s, sizeof(Geo));
|
||||||
|
|
||||||
for(i = 0; i < s; ++i)
|
for(i = 0; i < s; ++i)
|
||||||
sgeo[i] = screen_get_geo(i);
|
sgeo[i] = screen_get_geo(i);
|
||||||
@@ -214,7 +217,6 @@ screen_init_geo(void)
|
|||||||
#endif /* HAVE_XRANDR */
|
#endif /* HAVE_XRANDR */
|
||||||
|
|
||||||
ewmh_set_desktop_geometry();
|
ewmh_set_desktop_geometry();
|
||||||
ewmh_set_workarea();
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -236,11 +238,15 @@ uicb_screen_select(uicb_t cmd)
|
|||||||
void
|
void
|
||||||
uicb_screen_next(uicb_t cmd)
|
uicb_screen_next(uicb_t cmd)
|
||||||
{
|
{
|
||||||
|
(void)cmd;
|
||||||
screen_get_sel();
|
screen_get_sel();
|
||||||
|
|
||||||
selscreen = (selscreen + 1 > screen_count() - 1) ? 0 : selscreen + 1;
|
if(screen_count() > 1)
|
||||||
|
{
|
||||||
|
selscreen = (selscreen + 1 > screen_count() - 1) ? 0 : selscreen + 1;
|
||||||
|
|
||||||
screen_set_sel(selscreen);
|
screen_set_sel(selscreen);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -251,6 +257,7 @@ uicb_screen_next(uicb_t cmd)
|
|||||||
void
|
void
|
||||||
uicb_screen_prev(uicb_t cmd)
|
uicb_screen_prev(uicb_t cmd)
|
||||||
{
|
{
|
||||||
|
(void)cmd;
|
||||||
screen_get_sel();
|
screen_get_sel();
|
||||||
|
|
||||||
selscreen = (selscreen - 1 < 0) ? screen_count() - 1 : selscreen - 1;
|
selscreen = (selscreen - 1 < 0) ? screen_count() - 1 : selscreen - 1;
|
||||||
@@ -266,6 +273,7 @@ uicb_screen_prev(uicb_t cmd)
|
|||||||
void
|
void
|
||||||
uicb_screen_prev_sel(uicb_t cmd)
|
uicb_screen_prev_sel(uicb_t cmd)
|
||||||
{
|
{
|
||||||
|
(void)cmd;
|
||||||
screen_get_sel();
|
screen_get_sel();
|
||||||
|
|
||||||
screen_set_sel(prevselscreen);
|
screen_set_sel(prevselscreen);
|
||||||
|
|||||||
373
src/split.c
Normal file
373
src/split.c
Normal file
@@ -0,0 +1,373 @@
|
|||||||
|
/*
|
||||||
|
* 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) \
|
||||||
|
{ \
|
||||||
|
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, cs;
|
||||||
|
Geo cgeo;
|
||||||
|
Client *cc;
|
||||||
|
|
||||||
|
cs = (LDIR(p) ? g->frame_geo.height : g->frame_geo.width);
|
||||||
|
|
||||||
|
for(s = 0, cgeo = c->frame_geo, cc = tiled_client(c->screen, clients);
|
||||||
|
cc; cc = tiled_client(c->screen, cc->next))
|
||||||
|
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, clients);
|
||||||
|
cc; cc = tiled_client(c->screen, 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 */
|
||||||
|
for(b = False, sc = clients; sc; sc = sc->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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
224
src/status.c
224
src/status.c
@@ -32,118 +32,129 @@
|
|||||||
|
|
||||||
#include "wmfs.h"
|
#include "wmfs.h"
|
||||||
|
|
||||||
/** Check rectangles blocks in str and return properties
|
/* Systray width */
|
||||||
|
static int sw = 0;
|
||||||
|
|
||||||
|
/** Check rectangles blocks in str and draw it
|
||||||
* --> \b[x;y;width;height;#color]\
|
* --> \b[x;y;width;height;#color]\
|
||||||
*\param r StatusRec pointer, rectangles properties
|
*\param ib Infobar pointer
|
||||||
*\param str String
|
*\param str String
|
||||||
*\return n Length of r
|
|
||||||
*/
|
*/
|
||||||
int
|
static void
|
||||||
statustext_rectangle(StatusRec *r, char *str)
|
statustext_rectangle(InfoBar *ib, char *str)
|
||||||
{
|
{
|
||||||
|
StatusRec r;
|
||||||
char as;
|
char as;
|
||||||
int n, i, j, k;
|
int i, j, k;
|
||||||
|
|
||||||
for(i = j = n = 0; i < strlen(str); ++i, ++j)
|
for(i = j = 0; i < (int)strlen(str); ++i, ++j)
|
||||||
if(sscanf(&str[i], "\\b[%d;%d;%d;%d;#%x]%c", &r[n].x, &r[n].y, &r[n].w, &r[n].h, &r[n].color, &as) == 6
|
if(sscanf(&str[i], "\\b[%d;%d;%d;%d;#%x]%c", &r.x, &r.y, &r.w, &r.h, &r.color, &as) == 6
|
||||||
&& as == '\\')
|
|
||||||
for(++n, ++i, --j; str[i] != as || str[i - 1] != ']'; ++i);
|
|
||||||
else if(j != i)
|
|
||||||
str[j] = str[i];
|
|
||||||
|
|
||||||
for(k = j; k < i; str[k++] = 0);
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Check graphs blocks in str and return properties
|
|
||||||
* --> \g[x;y;width;height;#color;data]\
|
|
||||||
*\param g StatusGraph pointer, graphs properties
|
|
||||||
*\param str String
|
|
||||||
*\return n Length of g
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
statustext_graph(StatusGraph *g, char *str)
|
|
||||||
{
|
|
||||||
char as, c, *p;
|
|
||||||
int n, i, j, k, m, w;
|
|
||||||
|
|
||||||
for(i = j = n = 0; i < strlen(str); ++i, ++j)
|
|
||||||
if(sscanf(&str[i], "\\g[%d;%d;%d;%d;#%x;%512[^]]]%c",
|
|
||||||
&g[n].x, &g[n].y, &g[n].w, &g[n].h, &g[n].color, g[n].data, &as) == 7
|
|
||||||
&& as == '\\')
|
&& as == '\\')
|
||||||
{
|
{
|
||||||
/* data is a list of numbers separated by ';' */
|
draw_rectangle(ib->bar->dr, r.x - sw, r.y, r.w, r.h, r.color);
|
||||||
w = g[n].w;
|
|
||||||
p = strtok(g[n].data, ";");
|
|
||||||
m = 0;
|
|
||||||
|
|
||||||
while(p && m < w)
|
for(++i, --j; str[i] != as || str[i - 1] != ']'; ++i);
|
||||||
{
|
|
||||||
c = atoi(p);
|
|
||||||
/* height limits */
|
|
||||||
if(c < 0)
|
|
||||||
c = 0;
|
|
||||||
if(c > g[n].h)
|
|
||||||
c = g[n].h;
|
|
||||||
g[n].data[m] = c;
|
|
||||||
p = strtok(NULL, ";");
|
|
||||||
++m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* width limits */
|
|
||||||
for(; m < w; ++m)
|
|
||||||
g[n].data[m] = 0;
|
|
||||||
/* data is a array[w] of bytes now */
|
|
||||||
|
|
||||||
for(++n, ++i, --j; str[i] != as || str[i - 1] != ']'; ++i);
|
|
||||||
}
|
}
|
||||||
else if(j != i)
|
else if(j != i)
|
||||||
str[j] = str[i];
|
str[j] = str[i];
|
||||||
|
|
||||||
for(k = j; k < i; str[k++] = 0);
|
for(k = j; k < i; str[k++] = '\0');
|
||||||
|
|
||||||
return n;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Check text blocks in str and return properties
|
/** Check graphs blocks in str and draw it
|
||||||
* --> \s[x;y;#color;text]\
|
* --> \g[x;y;width;height;#color;data]\
|
||||||
*\param s StatusText pointer, text properties
|
*\param ib Infobar pointer
|
||||||
*\param str String
|
*\param str String
|
||||||
*\return n Length of s
|
|
||||||
*/
|
*/
|
||||||
int
|
static void
|
||||||
statustext_text(StatusText *s, char *str)
|
statustext_graph(InfoBar *ib, char *str)
|
||||||
{
|
{
|
||||||
char as;
|
StatusGraph g;
|
||||||
int n, i, j, k;
|
char as, c, *p;
|
||||||
|
int i, j, k, m, w;
|
||||||
|
|
||||||
for(i = j = n = 0; i < strlen(str); ++i, ++j)
|
for(i = j = 0; i < (int)strlen(str); ++i, ++j)
|
||||||
if(sscanf(&str[i], "\\s[%d;%d;%7[^;];%512[^]]]%c", &s[n].x, &s[n].y, s[n].color, s[n].text, &as) == 5
|
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 == '\\')
|
&& as == '\\')
|
||||||
for(++n, ++i, --j; str[i] != as || str[i - 1] != ']'; ++i);
|
{
|
||||||
|
/* 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)
|
else if(j != i)
|
||||||
str[j] = str[i];
|
str[j] = str[i];
|
||||||
|
|
||||||
for(k = j; k < i; str[k++] = 0);
|
for(k = j; k < i; str[k++] = '\0');
|
||||||
|
|
||||||
return n;
|
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;
|
||||||
|
char as;
|
||||||
|
int i, j, k;
|
||||||
|
|
||||||
|
for(i = j = 0; i < (int)strlen(str); ++i, ++j)
|
||||||
|
if(sscanf(&str[i], "\\s[%d;%d;%7[^;];%512[^]]]%c", &s.x, &s.y, s.color, s.text, &as) == 5
|
||||||
|
&& as == '\\')
|
||||||
|
{
|
||||||
|
draw_text(ib->bar->dr, s.x - sw, s.y, s.color, s.text);
|
||||||
|
|
||||||
|
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
|
/** Draw normal text and colored normal text
|
||||||
* --> \#color\ text in color
|
* --> \#color\ text in color
|
||||||
*\param sc Screen
|
*\param sc Screen id
|
||||||
|
*\param ib Infobar pointer
|
||||||
*\param str String
|
*\param str String
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
statustext_normal(int sc, char *str)
|
statustext_normal(int sc, InfoBar *ib, char *str)
|
||||||
{
|
{
|
||||||
char strwc[MAXSTATUS] = { 0 };
|
char strwc[MAXSTATUS] = { 0 };
|
||||||
char buf[MAXSTATUS] = { 0 };
|
char buf[MAXSTATUS] = { 0 };
|
||||||
char col[8] = { 0 };
|
char col[8] = { 0 };
|
||||||
int n, i, j, k;
|
int n, i, j, k, tw;
|
||||||
|
|
||||||
for(i = j = n = 0; i < strlen(str); ++i, ++j)
|
for(i = j = n = 0; i < (int)strlen(str); ++i, ++j)
|
||||||
if(str[i] == '\\' && str[i + 1] == '#' && str[i + 8] == '\\')
|
if(str[i] == '\\' && str[i + 1] == '#' && str[i + 8] == '\\')
|
||||||
{
|
{
|
||||||
++n;
|
++n;
|
||||||
@@ -154,29 +165,29 @@ statustext_normal(int sc, char *str)
|
|||||||
strwc[j] = str[i];
|
strwc[j] = str[i];
|
||||||
|
|
||||||
/* Draw normal text without any blocks */
|
/* Draw normal text without any blocks */
|
||||||
draw_text(infobar[sc].bar->dr, (sgeo[sc].width - SHADH) - textw(strwc),
|
draw_text(ib->bar->dr, (sgeo[sc].width - SHADH) - (textw(strwc) + sw), FHINFOBAR, ib->bar->fg, strwc);
|
||||||
FHINFOBAR, infobar[sc].bar->fg, 0, strwc);
|
|
||||||
|
|
||||||
if(n)
|
if(n)
|
||||||
{
|
{
|
||||||
strcpy(buf, strwc);
|
strncpy(buf, strwc, sizeof(buf));
|
||||||
|
|
||||||
for(i = k = 0; i < strlen(str); ++i, ++k)
|
for(i = k = 0; i < (int)strlen(str); ++i, ++k)
|
||||||
if(str[i] == '\\' && str[i + 1] == '#' && str[i + 8] == '\\')
|
if(str[i] == '\\' && str[i + 1] == '#' && str[i + 8] == '\\')
|
||||||
{
|
{
|
||||||
|
tw = textw(&buf[k]);
|
||||||
|
|
||||||
/* Store current color in col[] */
|
/* Store current color in col[] */
|
||||||
for(j = 0, ++i; str[i] != '\\'; col[j++] = str[i++]);
|
for(j = 0, ++i; str[i] != '\\'; col[j++] = str[i++]);
|
||||||
|
|
||||||
/* Draw a rectangle with the bar color to draw the text properly */
|
/* Draw a rectangle with the bar color to draw the text properly */
|
||||||
draw_rectangle(infobar[sc].bar->dr, (sgeo[sc].width - SHADH) - textw(&buf[k]),
|
draw_rectangle(ib->bar->dr, (sgeo[sc].width - SHADH) - (tw + sw),
|
||||||
0, INFOBARH - (sgeo[sc].width - SHADH) - textw(&buf[k]),
|
0, INFOBARH - (sgeo[sc].width - SHADH) - tw,
|
||||||
INFOBARH, conf.colors.bar);
|
INFOBARH, conf.colors.bar);
|
||||||
|
|
||||||
/* Draw text with its color */
|
/* Draw text with its color */
|
||||||
draw_text(infobar[sc].bar->dr, (sgeo[sc].width - SHADH) - textw(&buf[k]),
|
draw_text(ib->bar->dr, (sgeo[sc].width - SHADH) - (tw + sw), FHINFOBAR, col, &buf[k]);
|
||||||
FHINFOBAR, col, 0, &buf[k]);
|
|
||||||
|
|
||||||
strcpy(buf, strwc);
|
strncpy(buf, strwc, sizeof(buf));
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -185,51 +196,40 @@ statustext_normal(int sc, char *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Handle statustext and draw all things in infobar of specified screen
|
/** Handle statustext and draw all things in infobar of specified screen
|
||||||
*\param sc Screen number
|
*\param sc Screen id
|
||||||
*\param str String
|
*\param str String
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
statustext_handle(int sc, char *str)
|
statustext_handle(int sc, char *str)
|
||||||
{
|
{
|
||||||
|
InfoBar *ib = &infobar[sc];
|
||||||
char *lastst;
|
char *lastst;
|
||||||
int i, nr, ng, ns, len;
|
int i;
|
||||||
StatusRec r[128];
|
|
||||||
StatusGraph g[128];
|
|
||||||
StatusText s[128];
|
|
||||||
|
|
||||||
/* If the str == the current statustext, return (not needed) */
|
/* If the str == the current statustext, return (not needed) */
|
||||||
if(!str)
|
if(!str)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
barwin_refresh_color(infobar[sc].bar);
|
if(sc == conf.systray.screen)
|
||||||
|
sw = systray_get_width();
|
||||||
|
|
||||||
|
barwin_refresh_color(ib->bar);
|
||||||
|
|
||||||
/* save last status text address (for free at the end) */
|
/* save last status text address (for free at the end) */
|
||||||
lastst = infobar[sc].statustext;
|
lastst = ib->statustext;
|
||||||
|
|
||||||
infobar[sc].statustext = _strdup(str);
|
ib->statustext = xstrdup(str);
|
||||||
len = ((strlen(str) > MAXSTATUS) ? MAXSTATUS : strlen(str));
|
|
||||||
|
|
||||||
/* Store rectangles, located text & images properties. */
|
/* Store rectangles, located text & images properties. */
|
||||||
nr = statustext_rectangle(r, str);
|
statustext_rectangle(ib, str);
|
||||||
ng = statustext_graph(g, str);
|
statustext_graph(ib, str);
|
||||||
ns = statustext_text(s, str);
|
statustext_text(ib, str);
|
||||||
|
|
||||||
/* Draw normal text (and possibly colored with \#color\ blocks) */
|
/* Draw normal text (and possibly colored with \#color\ blocks) */
|
||||||
statustext_normal(sc, str);
|
statustext_normal(sc, ib, str);
|
||||||
|
|
||||||
/* Draw rectangles with stored properties. */
|
sw = 0;
|
||||||
for(i = 0; i < nr; ++i)
|
barwin_refresh(ib->bar);
|
||||||
draw_rectangle(infobar[sc].bar->dr, r[i].x, r[i].y, r[i].w, r[i].h, r[i].color);
|
|
||||||
|
|
||||||
/* Draw graphs with stored properties. */
|
|
||||||
for(i = 0; i < ng; ++i)
|
|
||||||
draw_graph(infobar[sc].bar->dr, g[i].x, g[i].y, g[i].w, g[i].h, g[i].color, g[i].data);
|
|
||||||
|
|
||||||
/* Draw located text with stored properties. */
|
|
||||||
for(i = 0; i < ns; ++i)
|
|
||||||
draw_text(infobar[sc].bar->dr, s[i].x, s[i].y, s[i].color, 0, s[i].text);
|
|
||||||
|
|
||||||
barwin_refresh(infobar[sc].bar);
|
|
||||||
|
|
||||||
free(lastst);
|
free(lastst);
|
||||||
|
|
||||||
|
|||||||
224
src/structs.h
224
src/structs.h
@@ -37,23 +37,45 @@
|
|||||||
|
|
||||||
#define NBUTTON 8
|
#define NBUTTON 8
|
||||||
#define MAXTAG 36
|
#define MAXTAG 36
|
||||||
#define NUM_OF_LAYOUT 10
|
#define NUM_OF_LAYOUT 11
|
||||||
#define HISTOLEN 128
|
#define HISTOLEN 128
|
||||||
|
|
||||||
/* Clients flags definition */
|
/* Clients flags definition */
|
||||||
#define FreeFlag (1 << 1)
|
#define FreeFlag 0x01
|
||||||
#define MaxFlag (1 << 2)
|
#define MaxFlag 0x02
|
||||||
#define TileFlag (1 << 3)
|
#define TileFlag 0x04
|
||||||
#define HideFlag (1 << 4)
|
#define HideFlag 0x08
|
||||||
#define LMaxFlag (1 << 5)
|
#define LMaxFlag 0x10
|
||||||
#define UnmapFlag (1 << 6)
|
#define UnmapFlag 0x20
|
||||||
#define HintFlag (1 << 7)
|
#define HintFlag 0x40
|
||||||
#define FSSFlag (1 << 8)
|
#define FSSFlag 0x80
|
||||||
#define AboveFlag (1 << 9)
|
#define AboveFlag 0x100
|
||||||
#define UrgentFlag (1 << 10)
|
#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))
|
#define TagFlag(t) (1 << (t))
|
||||||
|
|
||||||
|
/* BarWindow flags definition */
|
||||||
|
#define MappedFlag 0x01
|
||||||
|
#define StippleFlag 0x02
|
||||||
|
#define BordFlag 0x04
|
||||||
|
|
||||||
/* XEMBED messages */
|
/* XEMBED messages */
|
||||||
#define XEMBED_MAPPED (1 << 0)
|
#define XEMBED_MAPPED (1 << 0)
|
||||||
#define XEMBED_EMBEDDED_NOTIFY 0
|
#define XEMBED_EMBEDDED_NOTIFY 0
|
||||||
@@ -93,7 +115,7 @@ enum { MA_Center = 0, MA_Left = 1, MA_Right = 2 };
|
|||||||
/* Infobar position */
|
/* Infobar position */
|
||||||
enum { IB_Hide = 0, IB_Bottom = 1, IB_Top = 2 };
|
enum { IB_Hide = 0, IB_Bottom = 1, IB_Top = 2 };
|
||||||
|
|
||||||
typedef enum { Right, Left, Top, Bottom, Center, PositionLast } Position;
|
typedef enum { Right = 0, Left, Top, Bottom, Center, PositionLast } Position;
|
||||||
|
|
||||||
/* Ewmh hints list */
|
/* Ewmh hints list */
|
||||||
enum
|
enum
|
||||||
@@ -106,7 +128,6 @@ enum
|
|||||||
net_current_desktop,
|
net_current_desktop,
|
||||||
net_desktop_names,
|
net_desktop_names,
|
||||||
net_desktop_geometry,
|
net_desktop_geometry,
|
||||||
net_workarea,
|
|
||||||
net_active_window,
|
net_active_window,
|
||||||
net_close_window,
|
net_close_window,
|
||||||
net_wm_icon_name,
|
net_wm_icon_name,
|
||||||
@@ -114,6 +135,7 @@ enum
|
|||||||
net_wm_pid,
|
net_wm_pid,
|
||||||
net_showing_desktop,
|
net_showing_desktop,
|
||||||
net_supporting_wm_check,
|
net_supporting_wm_check,
|
||||||
|
net_wm_window_opacity,
|
||||||
net_wm_window_type_normal,
|
net_wm_window_type_normal,
|
||||||
net_wm_window_type_dock,
|
net_wm_window_type_dock,
|
||||||
net_wm_window_type_splash,
|
net_wm_window_type_splash,
|
||||||
@@ -122,7 +144,16 @@ enum
|
|||||||
net_wm_icon,
|
net_wm_icon,
|
||||||
net_wm_state,
|
net_wm_state,
|
||||||
net_wm_state_fullscreen,
|
net_wm_state_fullscreen,
|
||||||
|
net_wm_state_sticky,
|
||||||
net_wm_state_demands_attention,
|
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,
|
utf8_string,
|
||||||
/* WMFS HINTS */
|
/* WMFS HINTS */
|
||||||
wmfs_running,
|
wmfs_running,
|
||||||
@@ -138,10 +169,18 @@ enum
|
|||||||
wmfs_screen_count,
|
wmfs_screen_count,
|
||||||
wmfs_function,
|
wmfs_function,
|
||||||
wmfs_cmd,
|
wmfs_cmd,
|
||||||
|
wmfs_font,
|
||||||
wmfs_statustext,
|
wmfs_statustext,
|
||||||
net_last
|
net_last
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Geometry structure */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
int width, height;
|
||||||
|
} Geo;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BarWindow Structure
|
* BarWindow Structure
|
||||||
* (titlebar, infobar..)
|
* (titlebar, infobar..)
|
||||||
@@ -161,8 +200,8 @@ typedef struct
|
|||||||
uint bg;
|
uint bg;
|
||||||
char *fg;
|
char *fg;
|
||||||
uint stipple_color;
|
uint stipple_color;
|
||||||
XRectangle geo;
|
Geo geo;
|
||||||
Bool mapped, stipple, bord;
|
uint flags;
|
||||||
} BarWindow;
|
} BarWindow;
|
||||||
|
|
||||||
/* Client Structure. */
|
/* Client Structure. */
|
||||||
@@ -173,18 +212,17 @@ struct Client
|
|||||||
char *title;
|
char *title;
|
||||||
/* Tag num */
|
/* Tag num */
|
||||||
uint tag;
|
uint tag;
|
||||||
|
int focusontag;
|
||||||
/* Screen */
|
/* Screen */
|
||||||
int screen;
|
int screen;
|
||||||
/* Layer */
|
|
||||||
int layer;
|
|
||||||
/* Window attribute */
|
/* Window attribute */
|
||||||
XRectangle geo;
|
Geo geo, pgeo; /* Window geo, tiling pure geo */
|
||||||
XRectangle tmp_geo;
|
Geo tmp_geo, wrgeo; /* Temporary geo, without resizehint geo */
|
||||||
XRectangle frame_geo;
|
Geo frame_geo; /* Frame geo */
|
||||||
/* Old window attribute */
|
Geo ogeo; /* Old window attribute */
|
||||||
XRectangle ogeo;
|
Geo split_geo, free_geo; /* Split & Free window attribute */
|
||||||
/* Free window attribute */
|
/* Tile size factors */
|
||||||
XRectangle free_geo;
|
int tilefact[4];
|
||||||
/* For resizehint usage */
|
/* For resizehint usage */
|
||||||
int basew, baseh, incw, inch;
|
int basew, baseh, incw, inch;
|
||||||
int maxw, maxh, minw, minh;
|
int maxw, maxh, minw, minh;
|
||||||
@@ -203,6 +241,7 @@ struct Client
|
|||||||
uint frame;
|
uint frame;
|
||||||
char *fg;
|
char *fg;
|
||||||
uint resizecorner;
|
uint resizecorner;
|
||||||
|
uint bordlight, borddark;
|
||||||
} colors;
|
} colors;
|
||||||
/* Client Information by flags */
|
/* Client Information by flags */
|
||||||
uint flags;
|
uint flags;
|
||||||
@@ -236,34 +275,43 @@ typedef struct
|
|||||||
BarWindow *bar, *selbar;
|
BarWindow *bar, *selbar;
|
||||||
BarWindow *layout_button;
|
BarWindow *layout_button;
|
||||||
BarWindow *tags_board, *tags[MAXTAG];
|
BarWindow *tags_board, *tags[MAXTAG];
|
||||||
XRectangle geo;
|
Geo geo;
|
||||||
int position;
|
int screen, position;
|
||||||
char *statustext;
|
char *statustext;
|
||||||
Bool need_update;
|
bool need_update;
|
||||||
} InfoBar;
|
} InfoBar;
|
||||||
|
|
||||||
/* Layout Structure */
|
/* Layout Structure */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
uint flags; /* Flags */
|
||||||
|
Client *nc; /* New client needing integration */
|
||||||
|
Client ghost; /* Ghost client to arrange hole in split */
|
||||||
char *symbol;
|
char *symbol;
|
||||||
char *type;
|
char *type;
|
||||||
void (*func)(int screen);
|
void (*func)(int screen);
|
||||||
} Layout;
|
} Layout;
|
||||||
|
|
||||||
|
/* Systray Structure */
|
||||||
|
typedef struct Systray Systray;
|
||||||
|
struct Systray
|
||||||
|
{
|
||||||
|
Window win;
|
||||||
|
Geo geo;
|
||||||
|
Systray *next, *prev;
|
||||||
|
};
|
||||||
|
|
||||||
/* Tag Structure */
|
/* Tag Structure */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
char **clients;
|
char **clients;
|
||||||
int nclients;
|
int nclients;
|
||||||
int layers;
|
|
||||||
float mwfact;
|
float mwfact;
|
||||||
int nmaster;
|
int nmaster;
|
||||||
Bool urgent;
|
uint flags;
|
||||||
Bool resizehint;
|
|
||||||
Bool request_update;
|
|
||||||
Bool abovefc;
|
|
||||||
int barpos;
|
int barpos;
|
||||||
|
int prev_barpos;
|
||||||
Layout layout;
|
Layout layout;
|
||||||
uint tagad;
|
uint tagad;
|
||||||
MouseBinding *mouse;
|
MouseBinding *mouse;
|
||||||
@@ -276,7 +324,7 @@ typedef struct
|
|||||||
char *name;
|
char *name;
|
||||||
void (*func)(uicb_t);
|
void (*func)(uicb_t);
|
||||||
uicb_t cmd;
|
uicb_t cmd;
|
||||||
Bool (*check)(uicb_t);
|
bool (*check)(uicb_t);
|
||||||
char *submenu;
|
char *submenu;
|
||||||
} MenuItem;
|
} MenuItem;
|
||||||
|
|
||||||
@@ -289,7 +337,7 @@ typedef struct
|
|||||||
*/
|
*/
|
||||||
char *name;
|
char *name;
|
||||||
/* Placement */
|
/* Placement */
|
||||||
Bool place_at_mouse;
|
bool place_at_mouse;
|
||||||
int align;
|
int align;
|
||||||
int x, y;
|
int x, y;
|
||||||
/* Color */
|
/* Color */
|
||||||
@@ -312,6 +360,7 @@ typedef struct
|
|||||||
char *command;
|
char *command;
|
||||||
char histo[HISTOLEN][512];
|
char histo[HISTOLEN][512];
|
||||||
uint nhisto;
|
uint nhisto;
|
||||||
|
int width;
|
||||||
} Launcher;
|
} Launcher;
|
||||||
|
|
||||||
/* Button struct */
|
/* Button struct */
|
||||||
@@ -331,6 +380,20 @@ typedef struct
|
|||||||
char *content;
|
char *content;
|
||||||
} Alias;
|
} Alias;
|
||||||
|
|
||||||
|
/* Rule struct */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *class;
|
||||||
|
char *instance;
|
||||||
|
char *role;
|
||||||
|
int screen;
|
||||||
|
int tag;
|
||||||
|
bool free;
|
||||||
|
bool max;
|
||||||
|
bool ignoretags;
|
||||||
|
bool follow_client;
|
||||||
|
} Rule;
|
||||||
|
|
||||||
/* Configuration structure */
|
/* Configuration structure */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -339,12 +402,16 @@ typedef struct
|
|||||||
|
|
||||||
/* Misc option */
|
/* Misc option */
|
||||||
char *font;
|
char *font;
|
||||||
Bool raisefocus;
|
bool use_xft;
|
||||||
Bool raiseswitch;
|
uint opacity;
|
||||||
Bool focus_fmouse;
|
bool raisefocus;
|
||||||
Bool focus_pclick;
|
bool focus_fmouse;
|
||||||
Bool ignore_next_client_rules;
|
bool focus_fmov;
|
||||||
Bool tagautohide;
|
bool focus_pclick;
|
||||||
|
bool ignore_next_client_rules;
|
||||||
|
bool tagautohide;
|
||||||
|
bool tagnamecount;
|
||||||
|
Tag default_tag;
|
||||||
uint pad;
|
uint pad;
|
||||||
int status_timing;
|
int status_timing;
|
||||||
char *status_path;
|
char *status_path;
|
||||||
@@ -364,22 +431,27 @@ typedef struct
|
|||||||
uint tagurbg;
|
uint tagurbg;
|
||||||
uint tagselbg;
|
uint tagselbg;
|
||||||
uint tag_occupied_bg;
|
uint tag_occupied_bg;
|
||||||
|
char *tag_occupied_fg;
|
||||||
uint tagbord;
|
uint tagbord;
|
||||||
char *layout_fg;
|
char *layout_fg;
|
||||||
uint layout_bg;
|
uint layout_bg;
|
||||||
|
float client_light_shade;
|
||||||
|
float client_dark_shade;
|
||||||
|
float bar_light_shade;
|
||||||
|
float bar_dark_shade;
|
||||||
} colors;
|
} colors;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
int height;
|
int height;
|
||||||
MouseBinding *mouse;
|
MouseBinding *mouse;
|
||||||
int nmouse;
|
int nmouse;
|
||||||
Bool selbar;
|
bool selbar;
|
||||||
} bars;
|
} bars;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
char *fg;
|
char *fg;
|
||||||
uint bg;
|
uint bg;
|
||||||
int maxlenght;
|
int maxlength;
|
||||||
MouseBinding *mouse;
|
MouseBinding *mouse;
|
||||||
int nmouse;
|
int nmouse;
|
||||||
} selbar;
|
} selbar;
|
||||||
@@ -391,17 +463,22 @@ typedef struct
|
|||||||
} root;
|
} root;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
Bool set_new_win_master;
|
bool set_new_win_master;
|
||||||
Bool place_at_mouse;
|
bool place_at_mouse;
|
||||||
Bool border_shadow;
|
bool border_shadow;
|
||||||
|
bool new_client_get_mouse;
|
||||||
int borderheight;
|
int borderheight;
|
||||||
|
char *autofree, *automax;
|
||||||
uint bordernormal;
|
uint bordernormal;
|
||||||
uint borderfocus;
|
uint borderfocus;
|
||||||
uint resizecorner_normal;
|
uint resizecorner_normal;
|
||||||
uint resizecorner_focus;
|
uint resizecorner_focus;
|
||||||
uint mod;
|
uint mod;
|
||||||
|
uint padding;
|
||||||
MouseBinding *mouse;
|
MouseBinding *mouse;
|
||||||
int nmouse;
|
int nmouse;
|
||||||
|
uint default_open_tag;
|
||||||
|
int default_open_screen;
|
||||||
} client;
|
} client;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
@@ -410,7 +487,7 @@ typedef struct
|
|||||||
char *fg_focus;
|
char *fg_focus;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
Bool active;
|
bool active;
|
||||||
struct { uint normal, focus; } colors;
|
struct { uint normal, focus; } colors;
|
||||||
} stipple;
|
} stipple;
|
||||||
MouseBinding *mouse;
|
MouseBinding *mouse;
|
||||||
@@ -420,50 +497,77 @@ typedef struct
|
|||||||
} titlebar;
|
} titlebar;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
Bool bar;
|
bool bar;
|
||||||
Bool tag;
|
bool tag;
|
||||||
Bool layout;
|
bool layout;
|
||||||
} border;
|
} border;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
bool active;
|
||||||
|
int screen;
|
||||||
|
int spacing;
|
||||||
|
} systray;
|
||||||
Alias alias[256];
|
Alias alias[256];
|
||||||
uint mouse_tag_action[TagActionLast];
|
uint mouse_tag_action[TagActionLast];
|
||||||
|
int layout_button_width;
|
||||||
Layout layout[NUM_OF_LAYOUT];
|
Layout layout[NUM_OF_LAYOUT];
|
||||||
Menu *menu;
|
Menu *menu;
|
||||||
Launcher *launcher;
|
Launcher *launcher;
|
||||||
|
Rule *rule;
|
||||||
int *ntag;
|
int *ntag;
|
||||||
Bool tag_round;
|
bool tag_round;
|
||||||
Bool client_round;
|
bool tag_auto_prev;
|
||||||
Bool layout_system; /* Switch: False, Menu: True. */
|
bool client_round;
|
||||||
Bool layout_placement; /* Right (normal): False, Left: True. */
|
bool client_auto_center;
|
||||||
|
bool client_tile_raise;
|
||||||
|
bool layout_system; /* Switch: False, Menu: True. */
|
||||||
|
bool layout_placement; /* Right (normal): False, Left: True. */
|
||||||
|
bool keep_layout_geo;
|
||||||
|
bool cfactor_enable_split;
|
||||||
|
char *tag_expose_name;
|
||||||
|
char *expose_layout;
|
||||||
|
char *selected_layout_symbol;
|
||||||
/* Number of... */
|
/* Number of... */
|
||||||
int nkeybind;
|
int nkeybind;
|
||||||
int nlayout;
|
int nlayout;
|
||||||
int nmenu;
|
int nmenu;
|
||||||
int nlauncher;
|
int nlauncher;
|
||||||
|
int nrule;
|
||||||
} Conf;
|
} Conf;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint x, y, w, h;
|
int as, de, width, height;
|
||||||
|
#ifdef HAVE_XFT
|
||||||
|
XftFont *font;
|
||||||
|
#endif /* HAVE_XFT */
|
||||||
|
XFontSet fontset;
|
||||||
|
} FontStruct;
|
||||||
|
|
||||||
|
/* status.c util struct */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int x, y, w, h;
|
||||||
uint color;
|
uint color;
|
||||||
} StatusRec;
|
} StatusRec;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint x, y, w, h;
|
int x, y, w, h;
|
||||||
uint color;
|
uint color;
|
||||||
char data[512];
|
char data[512];
|
||||||
} StatusGraph;
|
} StatusGraph;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint x, y;
|
int x, y;
|
||||||
char color[8];
|
char color[8];
|
||||||
char text[512];
|
char text[512];
|
||||||
} StatusText;
|
} StatusText;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint x, y, w, h;
|
int x, y, w, h;
|
||||||
char name[512];
|
char name[512];
|
||||||
} ImageAttr;
|
} ImageAttr;
|
||||||
|
|
||||||
@@ -492,4 +596,10 @@ typedef struct
|
|||||||
char *uicb;
|
char *uicb;
|
||||||
} vicmd_to_uicb;
|
} vicmd_to_uicb;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int version;
|
||||||
|
int flags;
|
||||||
|
} xembed_info;
|
||||||
|
|
||||||
#endif /* STRUCTS_H */
|
#endif /* STRUCTS_H */
|
||||||
|
|||||||
234
src/systray.c
Normal file
234
src/systray.c
Normal file
@@ -0,0 +1,234 @@
|
|||||||
|
/*
|
||||||
|
* 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 */
|
||||||
|
if(trayicons)
|
||||||
|
trayicons->prev = s;
|
||||||
|
|
||||||
|
s->next = trayicons;
|
||||||
|
trayicons = s;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
systray_del(Systray *s)
|
||||||
|
{
|
||||||
|
Systray **ss;
|
||||||
|
|
||||||
|
if(!conf.systray.active)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for(ss = &trayicons; *ss && *ss != s; ss = &(*ss)->next);
|
||||||
|
*ss = s->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;
|
||||||
|
|
||||||
|
for(i = trayicons; i; i = i->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;
|
||||||
|
|
||||||
|
for(i = trayicons; i; i = i->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;
|
||||||
|
|
||||||
|
for(i = trayicons; i; i = i->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(!trayicons)
|
||||||
|
{
|
||||||
|
XMoveResizeWindow(dpy, traywin, infobar[conf.systray.screen].bar->geo.width - 1, 0, 1, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = trayicons; i; i = i->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;
|
||||||
|
}
|
||||||
395
src/tag.c
395
src/tag.c
@@ -39,26 +39,33 @@ void
|
|||||||
tag_set(int tag)
|
tag_set(int tag)
|
||||||
{
|
{
|
||||||
Client *c;
|
Client *c;
|
||||||
Bool al = False;
|
bool al = False;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if(tag < 0 || tag > MAXTAG)
|
||||||
|
return;
|
||||||
|
|
||||||
screen_get_sel();
|
screen_get_sel();
|
||||||
|
|
||||||
prevseltag[selscreen] = seltag[selscreen];
|
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(conf.tag_round)
|
||||||
{
|
{
|
||||||
if(tag <= 0)
|
if(tag <= 0)
|
||||||
seltag[selscreen] = conf.ntag[selscreen];
|
seltag[selscreen] = conf.ntag[selscreen];
|
||||||
else if(tag > conf.ntag[selscreen])
|
else if(tag > conf.ntag[selscreen])
|
||||||
seltag[selscreen] = 1;
|
seltag[selscreen] = 1;
|
||||||
else
|
else
|
||||||
seltag[selscreen] = tag;
|
seltag[selscreen] = tag;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(!tag || tag == seltag[selscreen]
|
if(!tag || tag > conf.ntag[selscreen])
|
||||||
|| tag > conf.ntag[selscreen])
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
seltag[selscreen] = tag;
|
seltag[selscreen] = tag;
|
||||||
@@ -67,12 +74,18 @@ tag_set(int tag)
|
|||||||
ewmh_update_current_tag_prop();
|
ewmh_update_current_tag_prop();
|
||||||
|
|
||||||
/* Arrange infobar position */
|
/* Arrange infobar position */
|
||||||
if(tags[selscreen][prevseltag[selscreen]].barpos != tags[selscreen][seltag[selscreen]].barpos)
|
if(tags[selscreen][prevseltag[selscreen]].barpos != tags[selscreen][seltag[selscreen]].barpos
|
||||||
|
|| prevseltag[selscreen] == seltag[selscreen])
|
||||||
infobar_set_position(tags[selscreen][seltag[selscreen]].barpos);
|
infobar_set_position(tags[selscreen][seltag[selscreen]].barpos);
|
||||||
|
|
||||||
/* Check if a layout update is needed with additional tags */
|
/* Check if a layout update is needed with additional tags */
|
||||||
if(tags[selscreen][seltag[selscreen]].tagad)
|
if(tags[selscreen][seltag[selscreen]].tagad)
|
||||||
al = True;
|
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)
|
for(i = 1; i < conf.ntag[selscreen] + 1; ++i)
|
||||||
if(tags[selscreen][i].tagad & TagFlag(seltag[selscreen]))
|
if(tags[selscreen][i].tagad & TagFlag(seltag[selscreen]))
|
||||||
@@ -91,17 +104,23 @@ tag_set(int tag)
|
|||||||
|
|
||||||
arrange(selscreen, al);
|
arrange(selscreen, al);
|
||||||
|
|
||||||
if(tags[selscreen][tag].request_update)
|
if(tags[selscreen][tag].flags & RequestUpdateFlag)
|
||||||
{
|
{
|
||||||
tags[selscreen][seltag[selscreen]].layout.func(selscreen);
|
layout_func(selscreen, tag);
|
||||||
tags[selscreen][tag].request_update = False;
|
tags[selscreen][tag].flags &= ~RequestUpdateFlag;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* To focus the first client in the new tag */
|
/* To focus selected client of the via focusontag option */
|
||||||
for(c = clients; c; c = c->next)
|
for(c = clients; c; c = c->next)
|
||||||
if(c->tag == seltag[selscreen] && c->screen == selscreen)
|
if(c->focusontag == tag && c->screen == selscreen)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* No focusontag option found on any client, try to find the first of the tag */
|
||||||
|
if(!c)
|
||||||
|
for(c = clients; c; c = c->next)
|
||||||
|
if(c->tag == (uint)seltag[selscreen] && c->screen == selscreen)
|
||||||
|
break;
|
||||||
|
|
||||||
client_focus((c) ? c : NULL);
|
client_focus((c) ? c : NULL);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -114,27 +133,43 @@ tag_set(int tag)
|
|||||||
void
|
void
|
||||||
tag_transfert(Client *c, int tag)
|
tag_transfert(Client *c, int tag)
|
||||||
{
|
{
|
||||||
screen_get_sel();
|
int s;
|
||||||
|
|
||||||
CHECK(c);
|
CHECK(c);
|
||||||
|
|
||||||
if(!tag)
|
screen_get_sel();
|
||||||
|
|
||||||
|
if(tag <= 0)
|
||||||
tag = 1;
|
tag = 1;
|
||||||
|
|
||||||
if(tag > conf.ntag[selscreen])
|
if(tag > conf.ntag[selscreen]
|
||||||
|
|| (c->tag == tag && c->screen == selscreen))
|
||||||
return;
|
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->tag = tag;
|
||||||
c->screen = selscreen;
|
c->screen = selscreen;
|
||||||
|
|
||||||
|
if(s != c->screen)
|
||||||
|
arrange(s, True);
|
||||||
arrange(c->screen, True);
|
arrange(c->screen, True);
|
||||||
|
|
||||||
if(c == sel && c->tag != tag)
|
client_focus_next(c);
|
||||||
client_focus(NULL);
|
|
||||||
|
|
||||||
client_update_attributes(c);
|
client_update_attributes(c);
|
||||||
|
|
||||||
tags[c->screen][tag].request_update = True;
|
tags[c->screen][tag].flags |= RequestUpdateFlag;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -161,6 +196,7 @@ uicb_tag(uicb_t cmd)
|
|||||||
void
|
void
|
||||||
uicb_tag_next(uicb_t cmd)
|
uicb_tag_next(uicb_t cmd)
|
||||||
{
|
{
|
||||||
|
(void)cmd;
|
||||||
screen_get_sel();
|
screen_get_sel();
|
||||||
|
|
||||||
tag_set(seltag[selscreen] + 1);
|
tag_set(seltag[selscreen] + 1);
|
||||||
@@ -174,6 +210,7 @@ uicb_tag_next(uicb_t cmd)
|
|||||||
void
|
void
|
||||||
uicb_tag_prev(uicb_t cmd)
|
uicb_tag_prev(uicb_t cmd)
|
||||||
{
|
{
|
||||||
|
(void)cmd;
|
||||||
screen_get_sel();
|
screen_get_sel();
|
||||||
|
|
||||||
tag_set(seltag[selscreen] - 1);
|
tag_set(seltag[selscreen] - 1);
|
||||||
@@ -187,9 +224,10 @@ uicb_tag_prev(uicb_t cmd)
|
|||||||
void
|
void
|
||||||
uicb_tag_next_visible(uicb_t cmd)
|
uicb_tag_next_visible(uicb_t cmd)
|
||||||
{
|
{
|
||||||
int i, tag;
|
int tag;
|
||||||
Client *c;
|
Client *c;
|
||||||
Bool is_occupied[MAXTAG];
|
uint occupied = 0;
|
||||||
|
(void)cmd;
|
||||||
|
|
||||||
screen_get_sel();
|
screen_get_sel();
|
||||||
|
|
||||||
@@ -199,15 +237,12 @@ uicb_tag_next_visible(uicb_t cmd)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < MAXTAG; i++)
|
|
||||||
is_occupied[i] = False;
|
|
||||||
|
|
||||||
for(c = clients; c; c = c->next)
|
for(c = clients; c; c = c->next)
|
||||||
if(c->screen == selscreen)
|
if(c->screen == selscreen)
|
||||||
is_occupied[c->tag] = True;
|
occupied |= TagFlag(c->tag);
|
||||||
|
|
||||||
for(tag = seltag[selscreen] + 1; tag < conf.ntag[selscreen] + 1; ++tag)
|
for(tag = seltag[selscreen] + 1; tag < conf.ntag[selscreen] + 1; ++tag)
|
||||||
if(is_occupied[tag])
|
if(occupied & TagFlag(tag))
|
||||||
{
|
{
|
||||||
tag_set(tag);
|
tag_set(tag);
|
||||||
return;
|
return;
|
||||||
@@ -215,7 +250,7 @@ uicb_tag_next_visible(uicb_t cmd)
|
|||||||
|
|
||||||
if(conf.tag_round)
|
if(conf.tag_round)
|
||||||
for(tag = 0; tag < seltag[selscreen]; ++tag)
|
for(tag = 0; tag < seltag[selscreen]; ++tag)
|
||||||
if(is_occupied[tag])
|
if(occupied & TagFlag(tag))
|
||||||
{
|
{
|
||||||
tag_set(tag);
|
tag_set(tag);
|
||||||
return;
|
return;
|
||||||
@@ -230,9 +265,10 @@ uicb_tag_next_visible(uicb_t cmd)
|
|||||||
void
|
void
|
||||||
uicb_tag_prev_visible(uicb_t cmd)
|
uicb_tag_prev_visible(uicb_t cmd)
|
||||||
{
|
{
|
||||||
int i, tag;
|
int tag;
|
||||||
Client *c;
|
Client *c;
|
||||||
Bool is_occupied[MAXTAG];
|
uint occupied = 0;
|
||||||
|
(void)cmd;
|
||||||
|
|
||||||
screen_get_sel();
|
screen_get_sel();
|
||||||
|
|
||||||
@@ -242,15 +278,12 @@ uicb_tag_prev_visible(uicb_t cmd)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < MAXTAG; i++)
|
|
||||||
is_occupied[i] = False;
|
|
||||||
|
|
||||||
for(c = clients; c; c = c->next)
|
for(c = clients; c; c = c->next)
|
||||||
if(c->screen == selscreen)
|
if(c->screen == selscreen)
|
||||||
is_occupied[c->tag] = True;
|
occupied |= TagFlag(c->tag);
|
||||||
|
|
||||||
for(tag = seltag[selscreen] - 1; tag >= 0; --tag)
|
for(tag = seltag[selscreen] - 1; tag >= 0; --tag)
|
||||||
if(is_occupied[tag])
|
if(occupied & TagFlag(tag))
|
||||||
{
|
{
|
||||||
tag_set(tag);
|
tag_set(tag);
|
||||||
return;
|
return;
|
||||||
@@ -258,7 +291,7 @@ uicb_tag_prev_visible(uicb_t cmd)
|
|||||||
|
|
||||||
if(conf.tag_round)
|
if(conf.tag_round)
|
||||||
for(tag = conf.ntag[selscreen]; tag > seltag[selscreen]; --tag)
|
for(tag = conf.ntag[selscreen]; tag > seltag[selscreen]; --tag)
|
||||||
if(is_occupied[tag])
|
if(occupied & TagFlag(tag))
|
||||||
{
|
{
|
||||||
tag_set(tag);
|
tag_set(tag);
|
||||||
return;
|
return;
|
||||||
@@ -267,6 +300,102 @@ uicb_tag_prev_visible(uicb_t cmd)
|
|||||||
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;
|
||||||
|
|
||||||
|
for(c = clients; c; c = c->next)
|
||||||
|
{
|
||||||
|
if(c->screen == s && c->tag == (uint)t1)
|
||||||
|
c->tag = t2;
|
||||||
|
else if(c->screen == s && c->tag == (uint)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
|
/** Transfert the selected client to
|
||||||
* the wanted tag
|
* the wanted tag
|
||||||
* \param cmd Wanted tag, uicb_t type
|
* \param cmd Wanted tag, uicb_t type
|
||||||
@@ -287,6 +416,7 @@ uicb_tagtransfert(uicb_t cmd)
|
|||||||
void
|
void
|
||||||
uicb_tag_prev_sel(uicb_t cmd)
|
uicb_tag_prev_sel(uicb_t cmd)
|
||||||
{
|
{
|
||||||
|
(void)cmd;
|
||||||
screen_get_sel();
|
screen_get_sel();
|
||||||
|
|
||||||
tag_set(prevseltag[selscreen]);
|
tag_set(prevseltag[selscreen]);
|
||||||
@@ -302,6 +432,7 @@ uicb_tagtransfert_next(uicb_t cmd)
|
|||||||
{
|
{
|
||||||
CHECK(sel);
|
CHECK(sel);
|
||||||
int tag = seltag[selscreen] + 1;
|
int tag = seltag[selscreen] + 1;
|
||||||
|
(void)cmd;
|
||||||
|
|
||||||
if(tag > conf.ntag[selscreen])
|
if(tag > conf.ntag[selscreen])
|
||||||
{
|
{
|
||||||
@@ -322,6 +453,7 @@ uicb_tagtransfert_prev(uicb_t cmd)
|
|||||||
{
|
{
|
||||||
CHECK(sel);
|
CHECK(sel);
|
||||||
int tag = seltag[selscreen] - 1;
|
int tag = seltag[selscreen] - 1;
|
||||||
|
(void)cmd;
|
||||||
|
|
||||||
if(tag <= 0)
|
if(tag <= 0)
|
||||||
{
|
{
|
||||||
@@ -341,23 +473,20 @@ void
|
|||||||
uicb_tag_urgent(uicb_t cmd)
|
uicb_tag_urgent(uicb_t cmd)
|
||||||
{
|
{
|
||||||
Client *c;
|
Client *c;
|
||||||
Bool b = False;
|
|
||||||
|
(void)cmd;
|
||||||
|
|
||||||
/* Check if there is a urgent client */
|
/* Check if there is a urgent client */
|
||||||
for(c = clients; c; c = c->next)
|
for(c = clients; c; c = c->next)
|
||||||
if(c->flags & UrgentFlag)
|
if(c->flags & UrgentFlag)
|
||||||
{
|
{
|
||||||
b = True;
|
screen_set_sel(c->screen);
|
||||||
|
tag_set(c->tag);
|
||||||
|
client_focus(c);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!b)
|
|
||||||
return;
|
|
||||||
|
|
||||||
screen_set_sel(c->screen);
|
|
||||||
tag_set(c->tag);
|
|
||||||
client_focus(c);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -369,12 +498,17 @@ uicb_tag_urgent(uicb_t cmd)
|
|||||||
void
|
void
|
||||||
tag_additional(int sc, int tag, int adtag)
|
tag_additional(int sc, int tag, int adtag)
|
||||||
{
|
{
|
||||||
if(tag < 0 || tag > conf.ntag[sc]
|
if(tag < 0 || (tag | adtag) > conf.ntag[sc] + 1
|
||||||
|| adtag < 1 || adtag > conf.ntag[sc] || adtag == seltag[sc])
|
|| adtag < 1 || adtag == seltag[sc])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tags[sc][tag].tagad ^= TagFlag(adtag);
|
tags[sc][tag].flags &= ~SplitFlag;
|
||||||
tags[sc][adtag].request_update = True;
|
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);
|
arrange(sc, True);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -393,39 +527,6 @@ uicb_tag_toggle_additional(uicb_t cmd)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Swap 2 tags
|
|
||||||
*\param s Screen
|
|
||||||
*\param t1 Tag 1
|
|
||||||
*\param t2 Tag 2
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
tag_swap(int s, int t1, int t2)
|
|
||||||
{
|
|
||||||
Client *c;
|
|
||||||
Tag t;
|
|
||||||
|
|
||||||
if(t1 > conf.ntag[s] || t1 < 1
|
|
||||||
|| t2 > conf.ntag[s] || t2 < 1 || t1 == t2)
|
|
||||||
return;
|
|
||||||
|
|
||||||
t = tags[s][t1];
|
|
||||||
tags[s][t1] = tags[s][t2];
|
|
||||||
tags[s][t2] = t;
|
|
||||||
|
|
||||||
for(c = clients; c; c = c->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(s);
|
|
||||||
tag_set(t2);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Swap current tag with a specified tag
|
/** Swap current tag with a specified tag
|
||||||
*\param cmd uicb_t type
|
*\param cmd uicb_t type
|
||||||
*/
|
*/
|
||||||
@@ -445,9 +546,14 @@ uicb_tag_swap(uicb_t cmd)
|
|||||||
void
|
void
|
||||||
uicb_tag_swap_next(uicb_t cmd)
|
uicb_tag_swap_next(uicb_t cmd)
|
||||||
{
|
{
|
||||||
|
(void)cmd;
|
||||||
screen_get_sel();
|
screen_get_sel();
|
||||||
|
|
||||||
tag_swap(selscreen, seltag[selscreen], seltag[selscreen] + 1);
|
/* 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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -458,6 +564,7 @@ uicb_tag_swap_next(uicb_t cmd)
|
|||||||
void
|
void
|
||||||
uicb_tag_swap_previous(uicb_t cmd)
|
uicb_tag_swap_previous(uicb_t cmd)
|
||||||
{
|
{
|
||||||
|
(void)cmd;
|
||||||
screen_get_sel();
|
screen_get_sel();
|
||||||
|
|
||||||
tag_swap(selscreen, seltag[selscreen], seltag[selscreen] - 1);
|
tag_swap(selscreen, seltag[selscreen], seltag[selscreen] - 1);
|
||||||
@@ -469,11 +576,11 @@ uicb_tag_swap_previous(uicb_t cmd)
|
|||||||
*\param s Screen number
|
*\param s Screen number
|
||||||
*\param name New tag name
|
*\param name New tag name
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
tag_new(int s, char *name)
|
tag_new(int s, char *name)
|
||||||
{
|
{
|
||||||
Tag t = { NULL, NULL, 0, 0, 0.65, 1, False, False, False, False, IB_Top,
|
char * displayedName;
|
||||||
layout_name_to_struct(conf.layout, "tile_right", conf.nlayout, layout_list), 0, NULL, 0 };
|
int goToTag;
|
||||||
|
|
||||||
if(conf.ntag[s] + 1 > MAXTAG)
|
if(conf.ntag[s] + 1 > MAXTAG)
|
||||||
{
|
{
|
||||||
@@ -484,13 +591,40 @@ tag_new(int s, char *name)
|
|||||||
|
|
||||||
++conf.ntag[s];
|
++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;
|
tags[s][conf.ntag[s]] = t;
|
||||||
|
|
||||||
tags[s][conf.ntag[s]].name = _strdup((name ? name : "new tag"));
|
/* 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(s);
|
infobar_update_taglist(&infobar[s]);
|
||||||
infobar_draw(s);
|
infobar_draw(&infobar[s]);
|
||||||
tag_set(conf.ntag[s]);
|
tag_set(goToTag);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -512,18 +646,20 @@ uicb_tag_new(uicb_t cmd)
|
|||||||
*\param s Screen number
|
*\param s Screen number
|
||||||
*\param tag Tag number
|
*\param tag Tag number
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
tag_delete(int s, int tag)
|
tag_delete(int s, int tag)
|
||||||
{
|
{
|
||||||
Tag t = { 0 };
|
Tag t;
|
||||||
Client *c;
|
Client *c;
|
||||||
int i;
|
size_t i;
|
||||||
|
|
||||||
|
memset(&t, 0, sizeof(t));
|
||||||
|
|
||||||
if(tag < 0 || tag > conf.ntag[s] || conf.ntag[s] == 1)
|
if(tag < 0 || tag > conf.ntag[s] || conf.ntag[s] == 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for(c = clients; c; c = c->next)
|
for(c = clients; c; c = c->next)
|
||||||
if(c->screen == s && c->tag == tag)
|
if(c->screen == s && c->tag == (uint)tag)
|
||||||
{
|
{
|
||||||
warnx("Client(s) present in this tag, can't delete it");
|
warnx("Client(s) present in this tag, can't delete it");
|
||||||
|
|
||||||
@@ -535,7 +671,7 @@ tag_delete(int s, int tag)
|
|||||||
tags[s][tag] = t;
|
tags[s][tag] = t;
|
||||||
infobar[s].tags[tag] = NULL;
|
infobar[s].tags[tag] = NULL;
|
||||||
|
|
||||||
for(i = tag; i < conf.ntag[s] + 1; ++i)
|
for(i = tag; i < (size_t)conf.ntag[s] + 1; ++i)
|
||||||
{
|
{
|
||||||
/* Set clients tag because of shift */
|
/* Set clients tag because of shift */
|
||||||
for(c = clients; c; c = c->next)
|
for(c = clients; c; c = c->next)
|
||||||
@@ -547,8 +683,8 @@ tag_delete(int s, int tag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
infobar[s].need_update = True;
|
infobar[s].need_update = True;
|
||||||
infobar_update_taglist(s);
|
infobar_update_taglist(&infobar[s]);
|
||||||
infobar_draw(s);
|
infobar_draw(&infobar[s]);
|
||||||
|
|
||||||
if(tag == seltag[s])
|
if(tag == seltag[s])
|
||||||
tag_set(tag <= conf.ntag[s] ? tag : conf.ntag[s]);
|
tag_set(tag <= conf.ntag[s] ? tag : conf.ntag[s]);
|
||||||
@@ -574,3 +710,72 @@ uicb_tag_del(uicb_t cmd)
|
|||||||
return;
|
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(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;
|
||||||
|
}
|
||||||
|
|||||||
265
src/util.c
265
src/util.c
@@ -30,24 +30,103 @@
|
|||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
#include "wmfs.h"
|
#include "wmfs.h"
|
||||||
|
|
||||||
/** Calloc with an error message if there is a probleme
|
/** malloc with error support and size_t overflow protection
|
||||||
* \param element Element
|
* \param nmemb number of objects
|
||||||
* \param size Size
|
* \param size size of single object
|
||||||
* \return void pointer
|
* \return non null void pointer
|
||||||
*/
|
*/
|
||||||
void*
|
void *
|
||||||
emalloc(uint element, uint size)
|
xmalloc(size_t nmemb, size_t size)
|
||||||
{
|
{
|
||||||
void *ret = calloc(element, size);
|
void *ret;
|
||||||
|
|
||||||
if(!ret)
|
if (SIZE_MAX / nmemb < size)
|
||||||
warn("calloc()");
|
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;
|
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
|
/** Get a color with a string
|
||||||
* \param color Color string
|
* \param color Color string
|
||||||
* \return Color pixel
|
* \return Color pixel
|
||||||
@@ -63,21 +142,6 @@ getcolor(char *color)
|
|||||||
return xcolor.pixel;
|
return xcolor.pixel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Enlight an hexadecimal color
|
|
||||||
* \param col Color
|
|
||||||
* \return The clarified color
|
|
||||||
*/
|
|
||||||
ulong
|
|
||||||
color_enlight(ulong col)
|
|
||||||
{
|
|
||||||
if((col + 0x330000) < 0xffffff
|
|
||||||
&& (col + 0x003300) < 0xffffff
|
|
||||||
&& (col + 0x000033) < 0xffffff)
|
|
||||||
return col + 0x333333;
|
|
||||||
else
|
|
||||||
return col;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set the window WM State
|
/** Set the window WM State
|
||||||
* \param win Window target
|
* \param win Window target
|
||||||
* \param state WM State
|
* \param state WM State
|
||||||
@@ -93,20 +157,6 @@ setwinstate(Window win, long state)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** My strdup. the strdup of string.h isn't ansi compatible..
|
|
||||||
* Thanks linkdd.
|
|
||||||
* \param str char pointer
|
|
||||||
*/
|
|
||||||
char*
|
|
||||||
_strdup(const char *str)
|
|
||||||
{
|
|
||||||
char *ret = emalloc(strlen(str) + 1, sizeof(char));
|
|
||||||
|
|
||||||
strcpy(ret, str);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The following function are for configuration
|
/* The following function are for configuration
|
||||||
usage. {{{
|
usage. {{{
|
||||||
*/
|
*/
|
||||||
@@ -116,7 +166,7 @@ name_to_func(char *name, const func_name_list_t *l)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
if(name)
|
if(name)
|
||||||
for(i = 0; l[i].name ; ++i)
|
for(i = 0; l[i].name; ++i)
|
||||||
if(!strcmp(name, l[i].name))
|
if(!strcmp(name, l[i].name))
|
||||||
return l[i].func;
|
return l[i].func;
|
||||||
|
|
||||||
@@ -160,56 +210,20 @@ layout_name_to_struct(Layout lt[], char *name, int n, const func_name_list_t lli
|
|||||||
|
|
||||||
return lt[0];
|
return lt[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
char*
|
|
||||||
alias_to_str(char *conf_choice)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
char *tmpchar = NULL;
|
|
||||||
|
|
||||||
if(!conf_choice)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if(conf.alias)
|
|
||||||
for(i = 0; conf.alias[i].name; i++)
|
|
||||||
if(!strcmp(conf_choice, conf.alias[i].name))
|
|
||||||
tmpchar = conf.alias[i].content;
|
|
||||||
|
|
||||||
if(tmpchar)
|
|
||||||
return _strdup(tmpchar);
|
|
||||||
else
|
|
||||||
return _strdup(conf_choice);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/** Get the mouse pointer position.
|
|
||||||
*/
|
|
||||||
XRectangle
|
|
||||||
get_mouse_pos(void)
|
|
||||||
{
|
|
||||||
Window dum;
|
|
||||||
int d, u;
|
|
||||||
XRectangle ret;
|
|
||||||
|
|
||||||
XQueryPointer(dpy, ROOT, &dum, &dum, (int*)&ret.x, (int*)&ret.y, &d, &d, (uint *)&u);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Execute a sh command
|
/** Execute a sh command
|
||||||
* \param cmd Command
|
* \param cmd Command
|
||||||
* \return child pid
|
* \return child pid
|
||||||
*/
|
*/
|
||||||
int
|
pid_t
|
||||||
spawn(const char *format, ...)
|
spawn(const char *format, ...)
|
||||||
{
|
{
|
||||||
char *sh = NULL;
|
char *sh = NULL;
|
||||||
char cmd[512];
|
char cmd[512];
|
||||||
va_list ap;
|
va_list ap;
|
||||||
pid_t pid, ret;
|
pid_t pid;
|
||||||
int p[2], len;
|
size_t len;
|
||||||
|
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
len = vsnprintf(cmd, sizeof(cmd), format, ap);
|
len = vsnprintf(cmd, sizeof(cmd), format, ap);
|
||||||
@@ -224,45 +238,19 @@ spawn(const char *format, ...)
|
|||||||
if(!(sh = getenv("SHELL")))
|
if(!(sh = getenv("SHELL")))
|
||||||
sh = "/bin/sh";
|
sh = "/bin/sh";
|
||||||
|
|
||||||
if (pipe(p) == -1)
|
|
||||||
{
|
|
||||||
warn("pipe");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((pid = fork()) == 0)
|
if((pid = fork()) == 0)
|
||||||
{
|
{
|
||||||
close(p[0]);
|
if(dpy)
|
||||||
if((pid = fork()) == 0)
|
close(ConnectionNumber(dpy));
|
||||||
{
|
setsid();
|
||||||
if(dpy)
|
if (execl(sh, sh, "-c", cmd, (char*)NULL) == -1)
|
||||||
close(ConnectionNumber(dpy));
|
warn("execl(sh -c %s)", cmd);
|
||||||
setsid();
|
exit(EXIT_FAILURE);
|
||||||
execl(sh, sh, "-c", cmd, (char*)NULL);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
write(p[1], &pid, sizeof(pid_t));
|
|
||||||
close(p[1]);
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
}
|
||||||
else if (pid != -1)
|
else if (pid == -1)
|
||||||
{
|
|
||||||
close(p[1]);
|
|
||||||
if (sizeof(pid_t) != read(p[0], &ret, sizeof(pid_t)))
|
|
||||||
{
|
|
||||||
warn("read");
|
|
||||||
ret = -1;
|
|
||||||
}
|
|
||||||
close(p[0]);
|
|
||||||
waitpid(pid, NULL, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
warn("fork");
|
warn("fork");
|
||||||
ret = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Swap two pointer.
|
/** Swap two pointer.
|
||||||
@@ -291,39 +279,13 @@ uicb_spawn(uicb_t cmd)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_IMLIB
|
|
||||||
/** Check images blocks in str and return properties
|
|
||||||
* --> \i[x;y;w;h;name]\
|
|
||||||
*\param im ImageAttr pointer, image properties
|
|
||||||
*\param str String
|
|
||||||
*\return n Lenght of i
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
parse_image_block(ImageAttr *im, char *str)
|
|
||||||
{
|
|
||||||
char as;
|
|
||||||
int n, i, j, k;
|
|
||||||
|
|
||||||
for(i = j = n = 0; i < strlen(str); ++i, ++j)
|
|
||||||
if(sscanf(&str[i], "\\i[%d;%d;%d;%d;%512[^]]]%c", &im[n].x, &im[n].y, &im[n].w, &im[n].h, im[n].name, &as) == 6
|
|
||||||
&& as == '\\')
|
|
||||||
for(++n, ++i, --j; str[i] != as || str[i - 1] != ']'; ++i);
|
|
||||||
else if(j != i)
|
|
||||||
str[j] = str[i];
|
|
||||||
|
|
||||||
for(k = j; k < i; str[k++] = 0);
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
#endif /* HAVE_IMLIB */
|
|
||||||
|
|
||||||
char*
|
char*
|
||||||
clean_value(char *str)
|
clean_value(char *str)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char c, *p;
|
char c, *p;
|
||||||
|
|
||||||
if(!str || !(p = _strdup(str)))
|
if(!str || !(p = xstrdup(str)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Remove useless spaces */
|
/* Remove useless spaces */
|
||||||
@@ -340,3 +302,26 @@ clean_value(char *str)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* To use ~/ shortcut.. */
|
||||||
|
char*
|
||||||
|
patht(char *path)
|
||||||
|
{
|
||||||
|
static char ret[512];
|
||||||
|
|
||||||
|
if(!path)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
strncpy(ret, path, sizeof(ret));
|
||||||
|
ret[sizeof(ret) - 1] = 0;
|
||||||
|
if(strstr(path, "~/"))
|
||||||
|
snprintf(ret, sizeof(ret), "%s/%s", getenv("HOME"), path + 2);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
qsort_string_compare (const void * a, const void * b)
|
||||||
|
{
|
||||||
|
return (strcmp(*(char **)a, *(char **)b));
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
143
src/viwmfs.c
143
src/viwmfs.c
@@ -1,143 +0,0 @@
|
|||||||
/*
|
|
||||||
* viwmfs.c
|
|
||||||
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are
|
|
||||||
* met:
|
|
||||||
*
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above
|
|
||||||
* copyright notice, this list of conditions and the following disclaimer
|
|
||||||
* in the documentation and/or other materials provided with the
|
|
||||||
* distribution.
|
|
||||||
* * Neither the name of the nor the names of its
|
|
||||||
* contributors may be used to endorse or promote products derived from
|
|
||||||
* this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "wmfs.h"
|
|
||||||
|
|
||||||
vicmd_to_uicb vicmd[] =
|
|
||||||
{
|
|
||||||
{"r", "reload"},
|
|
||||||
{"q", "quit"},
|
|
||||||
{"t", "tag"},
|
|
||||||
{"tn", "tag_next"},
|
|
||||||
{"tp", "tag_prev"},
|
|
||||||
{"l", "set_layout"},
|
|
||||||
{"layout", "set_layout"},
|
|
||||||
{"ln", "layout_next"},
|
|
||||||
{"lp", "layout_prev"},
|
|
||||||
{"s", "screen_select"},
|
|
||||||
{"screen", "screen_select"},
|
|
||||||
{"sn", "screen_next"},
|
|
||||||
{"sp", "screen_prev"},
|
|
||||||
{"cc", "client_kill"},
|
|
||||||
{"ct", "tag_transfert"},
|
|
||||||
{"ctn", "tag_transfert_next"},
|
|
||||||
{"ctp", "tag_transfert_prev"},
|
|
||||||
{"cn", "client_next"},
|
|
||||||
{"cp", "client_prev"},
|
|
||||||
{"csn", "client_swap_next"},
|
|
||||||
{"csp", "client_swap_prev"},
|
|
||||||
{"mwf", "set_mwfact"},
|
|
||||||
{"mwfact", "set_mwfact"},
|
|
||||||
{"nmaster", "set_nmaster"},
|
|
||||||
{"tm", "toggle_max"},
|
|
||||||
{"tf", "toggle_free"},
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
viwmfs_help(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
char s[20];
|
|
||||||
|
|
||||||
printf("ViWMFS commands list:\n");
|
|
||||||
|
|
||||||
for(i = 0; i < LEN(vicmd); ++i)
|
|
||||||
{
|
|
||||||
memset(s, ' ', sizeof(s));
|
|
||||||
|
|
||||||
s[15 - strlen(vicmd[i].cmd)] = '\0';
|
|
||||||
|
|
||||||
printf(" :%s%s %s\n", vicmd[i].cmd, s, vicmd[i].uicb);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
viwmfs(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
char *cmd, str[256] = { 0 };
|
|
||||||
Bool e;
|
|
||||||
|
|
||||||
if(!argc)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(argc > 3)
|
|
||||||
{
|
|
||||||
for(i = 2; i < argc; ++i)
|
|
||||||
{
|
|
||||||
strcat(str, argv[i]);
|
|
||||||
|
|
||||||
if(*(str + strlen(str) - 1) != ':')
|
|
||||||
strcat(str, " ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
strcpy(str, argv[2]);
|
|
||||||
|
|
||||||
if(!strcmp(str, "help"))
|
|
||||||
{
|
|
||||||
viwmfs_help();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(*str == ':')
|
|
||||||
{
|
|
||||||
for(i = 0; i < strlen(str); str[i] = str[i + 1], ++i);
|
|
||||||
|
|
||||||
cmd = _strdup(str);
|
|
||||||
|
|
||||||
for(i = 0; cmd[i] && cmd[i] != ' '; ++i);
|
|
||||||
cmd[i] = '\0';
|
|
||||||
|
|
||||||
for(i = 0; i < LEN(vicmd); ++i)
|
|
||||||
if(!strncmp(cmd, vicmd[i].cmd, strlen(cmd)))
|
|
||||||
{
|
|
||||||
exec_uicb_function(vicmd[i].uicb, clean_value(str + strlen(cmd)));
|
|
||||||
e = True;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For uicb function with normal name specified */
|
|
||||||
if(!e)
|
|
||||||
{
|
|
||||||
if(!strcmp(str, "h") || !strcmp(str, "help"))
|
|
||||||
viwmfs_help();
|
|
||||||
else
|
|
||||||
exec_uicb_function(cmd, str + strlen(cmd));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
255
src/wmfs.c
255
src/wmfs.c
@@ -32,11 +32,13 @@
|
|||||||
|
|
||||||
#include "wmfs.h"
|
#include "wmfs.h"
|
||||||
|
|
||||||
|
static volatile bool exiting = False, sig_chld = False;
|
||||||
|
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
int
|
int
|
||||||
errorhandler(Display *d, XErrorEvent *event)
|
errorhandler(Display *d, XErrorEvent *event)
|
||||||
{
|
{
|
||||||
char mess[256];
|
char mess[256];
|
||||||
Client *c;
|
|
||||||
|
|
||||||
/* Check if there is another WM running */
|
/* Check if there is another WM running */
|
||||||
if(BadAccess == event->error_code
|
if(BadAccess == event->error_code
|
||||||
@@ -48,7 +50,7 @@ errorhandler(Display *d, XErrorEvent *event)
|
|||||||
* 42 = X_SetInputFocus
|
* 42 = X_SetInputFocus
|
||||||
* 28 = X_GrabButton
|
* 28 = X_GrabButton
|
||||||
*/
|
*/
|
||||||
if((c = client_gb_win(event->resourceid)))
|
if(client_gb_win(event->resourceid))
|
||||||
if(event->error_code == BadWindow
|
if(event->error_code == BadWindow
|
||||||
|| event->request_code == 42
|
|| event->request_code == 42
|
||||||
|| event->request_code == 28)
|
|| event->request_code == 28)
|
||||||
@@ -68,6 +70,8 @@ errorhandler(Display *d, XErrorEvent *event)
|
|||||||
int
|
int
|
||||||
errorhandlerdummy(Display *d, XErrorEvent *event)
|
errorhandlerdummy(Display *d, XErrorEvent *event)
|
||||||
{
|
{
|
||||||
|
(void)d;
|
||||||
|
(void)event;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +81,7 @@ void
|
|||||||
quit(void)
|
quit(void)
|
||||||
{
|
{
|
||||||
Client *c;
|
Client *c;
|
||||||
int i;
|
size_t i, len;
|
||||||
|
|
||||||
/* Set the silent error handler */
|
/* Set the silent error handler */
|
||||||
XSetErrorHandler(errorhandlerdummy);
|
XSetErrorHandler(errorhandlerdummy);
|
||||||
@@ -89,100 +93,131 @@ quit(void)
|
|||||||
XReparentWindow(dpy, c->win, ROOT, c->geo.x, c->geo.y);
|
XReparentWindow(dpy, c->win, ROOT, c->geo.x, c->geo.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
IFREE(tags);
|
free(tags);
|
||||||
IFREE(seltag);
|
free(seltag);
|
||||||
|
|
||||||
|
systray_freeicons();
|
||||||
|
|
||||||
|
#ifdef HAVE_XFT
|
||||||
|
if(conf.use_xft)
|
||||||
|
XftFontClose(dpy, font.font);
|
||||||
|
else
|
||||||
|
#endif /* HAVE_XFT */
|
||||||
|
XFreeFontSet(dpy, font.fontset);
|
||||||
|
|
||||||
XftFontClose(dpy, font);
|
|
||||||
for(i = 0; i < CurLast; ++i)
|
for(i = 0; i < CurLast; ++i)
|
||||||
XFreeCursor(dpy, cursor[i]);
|
XFreeCursor(dpy, cursor[i]);
|
||||||
XFreeGC(dpy, gc_stipple);
|
XFreeGC(dpy, gc_stipple);
|
||||||
infobar_destroy();
|
infobar_destroy();
|
||||||
|
|
||||||
IFREE(sgeo);
|
free(sgeo);
|
||||||
IFREE(spgeo);
|
free(spgeo);
|
||||||
IFREE(infobar);
|
free(infobar);
|
||||||
IFREE(keys);
|
free(keys);
|
||||||
IFREE(func_list);
|
free(net_atom);
|
||||||
IFREE(net_atom);
|
|
||||||
|
|
||||||
/* Clean conf alloced thing */
|
/* Clean conf alloced thing */
|
||||||
IFREE(menulayout.item);
|
free(menulayout.item);
|
||||||
|
|
||||||
if(conf.menu)
|
if(conf.menu)
|
||||||
{
|
{
|
||||||
for(i = 0; i < LEN(conf.menu); ++i)
|
len = LEN(conf.menu);
|
||||||
IFREE(conf.menu[i].item);
|
for(i = 0; i < len; ++i)
|
||||||
IFREE(conf.menu);
|
free(conf.menu[i].item);
|
||||||
|
free(conf.menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
IFREE(conf.launcher);
|
free(conf.launcher);
|
||||||
|
free(conf.rule);
|
||||||
|
|
||||||
IFREE(conf.bars.mouse);
|
free(conf.bars.mouse);
|
||||||
IFREE(conf.selbar.mouse);
|
free(conf.selbar.mouse);
|
||||||
IFREE(conf.titlebar.button);
|
free(conf.titlebar.button);
|
||||||
IFREE(conf.client.mouse);
|
free(conf.client.mouse);
|
||||||
IFREE(conf.root.mouse);
|
free(conf.root.mouse);
|
||||||
|
|
||||||
free_conf(NULL);
|
free_conf();
|
||||||
|
|
||||||
XSync(dpy, False);
|
XSync(dpy, False);
|
||||||
XCloseDisplay(dpy);
|
XCloseDisplay(dpy);
|
||||||
|
|
||||||
|
free(event_handle);
|
||||||
|
|
||||||
/* kill status script */
|
/* kill status script */
|
||||||
if (conf.status_pid != (pid_t)-1)
|
if (conf.status_pid != (pid_t)-1)
|
||||||
kill(conf.status_pid, SIGQUIT);
|
kill(conf.status_pid, SIGTERM);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
static void
|
||||||
thread_process(void *arg)
|
wait_childs_and_status(void)
|
||||||
{
|
{
|
||||||
XEvent ev;
|
int pid;
|
||||||
|
|
||||||
/* X event loop */
|
pthread_mutex_lock(&mtx);
|
||||||
if(arg)
|
if (sig_chld) {
|
||||||
{
|
while ((pid = waitpid(-1, NULL, WNOHANG)) > 0)
|
||||||
while(!exiting && !XNextEvent(dpy, &ev))
|
if (pid == conf.status_pid)
|
||||||
getevent(ev);
|
conf.status_pid = -1;
|
||||||
|
sig_chld = False;
|
||||||
}
|
}
|
||||||
/* Status checking loop with timing */
|
pthread_mutex_unlock(&mtx);
|
||||||
else
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
thread_status(void *arg)
|
||||||
|
{
|
||||||
|
(void)arg;
|
||||||
|
int left = conf.status_timing;
|
||||||
|
|
||||||
|
pthread_detach(pthread_self());
|
||||||
|
|
||||||
|
do
|
||||||
{
|
{
|
||||||
pthread_detach(pthread_self());
|
wait_childs_and_status();
|
||||||
do
|
|
||||||
{
|
pthread_mutex_lock(&mtx);
|
||||||
|
if (conf.status_pid == -1)
|
||||||
conf.status_pid = spawn(conf.status_path);
|
conf.status_pid = spawn(conf.status_path);
|
||||||
sleep(conf.status_timing);
|
pthread_mutex_unlock(&mtx);
|
||||||
} while (!exiting && conf.status_timing != 0);
|
|
||||||
}
|
while ((left = sleep(left)) > 0);
|
||||||
|
left = conf.status_timing;
|
||||||
|
|
||||||
|
} while (!exiting);
|
||||||
|
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** WMFS main loop.
|
/** WMFS main loop.
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
mainloop(void)
|
mainloop(void)
|
||||||
{
|
{
|
||||||
XEvent ev;
|
XEvent ev;
|
||||||
pthread_t evloop, evstatus;
|
pthread_t th_status;
|
||||||
void *ret;
|
|
||||||
|
|
||||||
if(!estatus)
|
if(estatus && !conf.status_timing)
|
||||||
while(!exiting && !XNextEvent(dpy, &ev))
|
conf.status_pid = spawn(conf.status_path);
|
||||||
getevent(ev);
|
else if(estatus && pthread_create(&th_status, NULL, thread_status, NULL) != 0)
|
||||||
else
|
|
||||||
{
|
{
|
||||||
pthread_create(&evloop, NULL, thread_process, "1");
|
warnx("pthread_create");
|
||||||
pthread_create(&evstatus, NULL, thread_process, NULL);
|
estatus = False;
|
||||||
|
|
||||||
(void)pthread_join(evloop, &ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while(!exiting && !XNextEvent(dpy, &ev))
|
||||||
|
{
|
||||||
|
HANDLE_EVENT(&ev);
|
||||||
|
wait_childs_and_status();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(estatus)
|
||||||
|
pthread_join(th_status, NULL);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Set the exiting variable to True
|
/** Set the exiting variable to True
|
||||||
* for stop the main loop
|
* for stop the main loop
|
||||||
* \param cmd unused uicb_t
|
* \param cmd unused uicb_t
|
||||||
@@ -190,6 +225,7 @@ mainloop(void)
|
|||||||
void
|
void
|
||||||
uicb_quit(uicb_t cmd)
|
uicb_quit(uicb_t cmd)
|
||||||
{
|
{
|
||||||
|
(void)cmd;
|
||||||
exiting = True;
|
exiting = True;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -198,14 +234,14 @@ uicb_quit(uicb_t cmd)
|
|||||||
/** Scan if there are windows on X
|
/** Scan if there are windows on X
|
||||||
* for manage it
|
* for manage it
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
scan(void)
|
scan(void)
|
||||||
{
|
{
|
||||||
uint i, n;
|
uint n;
|
||||||
XWindowAttributes wa;
|
XWindowAttributes wa;
|
||||||
Window usl, usl2, *w = NULL;
|
Window usl, usl2, *w = NULL;
|
||||||
Atom rt;
|
Atom rt;
|
||||||
int s, rf, tag = -1, screen = -1, free = -1;
|
int s, rf, tag = -1, screen = -1, flags = -1, i;
|
||||||
ulong ir, il;
|
ulong ir, il;
|
||||||
uchar *ret;
|
uchar *ret;
|
||||||
Client *c;
|
Client *c;
|
||||||
@@ -214,28 +250,29 @@ scan(void)
|
|||||||
|
|
||||||
if(XQueryTree(dpy, ROOT, &usl, &usl2, &w, &n))
|
if(XQueryTree(dpy, ROOT, &usl, &usl2, &w, &n))
|
||||||
for(i = n - 1; i != -1; --i)
|
for(i = n - 1; i != -1; --i)
|
||||||
if(XGetWindowAttributes(dpy, w[i], &wa)
|
{
|
||||||
&& !(wa.override_redirect || XGetTransientForHint(dpy, w[i], &usl))
|
XGetWindowAttributes(dpy, w[i], &wa);
|
||||||
&& wa.map_state == IsViewable)
|
|
||||||
|
if(!wa.override_redirect && wa.map_state == IsViewable)
|
||||||
{
|
{
|
||||||
if(XGetWindowProperty(dpy, w[i], ATOM("_WMFS_TAG"), 0, 32,
|
if(XGetWindowProperty(dpy, w[i], ATOM("_WMFS_TAG"), 0, 32,
|
||||||
False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret) == Success && ret)
|
False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret) == Success && ret)
|
||||||
{
|
{
|
||||||
tag = *ret;
|
tag = *ret;
|
||||||
XFree(ret);
|
XFree(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(XGetWindowProperty(dpy, w[i], ATOM("_WMFS_SCREEN"), 0, 32,
|
if(XGetWindowProperty(dpy, w[i], ATOM("_WMFS_SCREEN"), 0, 32,
|
||||||
False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret) == Success && ret)
|
False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret) == Success && ret)
|
||||||
{
|
{
|
||||||
screen = *ret;
|
screen = *ret;
|
||||||
XFree(ret);
|
XFree(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(XGetWindowProperty(dpy, w[i], ATOM("_WMFS_ISFREE"), 0, 32,
|
if(XGetWindowProperty(dpy, w[i], ATOM("_WMFS_FLAGS"), 0, 32,
|
||||||
False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret) == Success && ret)
|
False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret) == Success && ret)
|
||||||
{
|
{
|
||||||
free = *ret;
|
flags = *ret;
|
||||||
XFree(ret);
|
XFree(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,18 +282,19 @@ scan(void)
|
|||||||
c->tag = tag;
|
c->tag = tag;
|
||||||
if(screen != -1 && screen <= s - 1)
|
if(screen != -1 && screen <= s - 1)
|
||||||
c->screen = screen;
|
c->screen = screen;
|
||||||
if(free != -1)
|
if(flags != -1)
|
||||||
c->flags |= (free) ? FreeFlag : 0;
|
c->flags = flags;
|
||||||
|
|
||||||
client_update_attributes(c);
|
client_update_attributes(c);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Set update layout request */
|
/* Set update layout request */
|
||||||
for(c = clients; c; c = c->next)
|
for(c = clients; c; c = c->next)
|
||||||
{
|
{
|
||||||
if(c->tag > conf.ntag[c->screen])
|
if(c->tag > (uint)conf.ntag[c->screen])
|
||||||
c->tag = conf.ntag[c->screen];
|
c->tag = conf.ntag[c->screen];
|
||||||
tags[c->screen][c->tag].request_update = True;
|
tags[c->screen][c->tag].flags |= RequestUpdateFlag;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < s; ++i)
|
for(i = 0; i < s; ++i)
|
||||||
@@ -273,11 +311,13 @@ scan(void)
|
|||||||
void
|
void
|
||||||
uicb_reload(uicb_t cmd)
|
uicb_reload(uicb_t cmd)
|
||||||
{
|
{
|
||||||
|
(void)cmd;
|
||||||
quit();
|
quit();
|
||||||
|
|
||||||
for(; argv_global[0] && argv_global[0] == ' '; ++argv_global);
|
for(; argv_global[0] && argv_global[0] == ' '; ++argv_global);
|
||||||
|
|
||||||
execlp(argv_global, argv_global, NULL);
|
/* add -C to always load the same config file */
|
||||||
|
execvp(argv_global, all_argv);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -286,7 +326,7 @@ uicb_reload(uicb_t cmd)
|
|||||||
execute when wmfs will be already running).
|
execute when wmfs will be already running).
|
||||||
\return False if wmfs is not running
|
\return False if wmfs is not running
|
||||||
*/
|
*/
|
||||||
Bool
|
bool
|
||||||
check_wmfs_running(void)
|
check_wmfs_running(void)
|
||||||
{
|
{
|
||||||
Atom rt;
|
Atom rt;
|
||||||
@@ -319,15 +359,11 @@ check_wmfs_running(void)
|
|||||||
void
|
void
|
||||||
exec_uicb_function(char *func, char *cmd)
|
exec_uicb_function(char *func, char *cmd)
|
||||||
{
|
{
|
||||||
long data[5];
|
|
||||||
|
|
||||||
/* Check if wmfs is running (this function is executed when wmfs
|
/* Check if wmfs is running (this function is executed when wmfs
|
||||||
is already running normally...) */
|
is already running normally...) */
|
||||||
if(!check_wmfs_running())
|
if(!check_wmfs_running())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
data[4] = True;
|
|
||||||
|
|
||||||
XChangeProperty(dpy, ROOT, ATOM("_WMFS_FUNCTION"), ATOM("UTF8_STRING"),
|
XChangeProperty(dpy, ROOT, ATOM("_WMFS_FUNCTION"), ATOM("UTF8_STRING"),
|
||||||
8, PropModeReplace, (uchar*)func, strlen(func));
|
8, PropModeReplace, (uchar*)func, strlen(func));
|
||||||
|
|
||||||
@@ -337,7 +373,7 @@ exec_uicb_function(char *func, char *cmd)
|
|||||||
XChangeProperty(dpy, ROOT, ATOM("_WMFS_CMD"), ATOM("UTF8_STRING"),
|
XChangeProperty(dpy, ROOT, ATOM("_WMFS_CMD"), ATOM("UTF8_STRING"),
|
||||||
8, PropModeReplace, (uchar*)cmd, strlen(cmd));
|
8, PropModeReplace, (uchar*)cmd, strlen(cmd));
|
||||||
|
|
||||||
send_client_event(data, "_WMFS_FUNCTION");
|
ewmh_send_message(ROOT, ROOT, "_WMFS_FUNCTION", 0, 0, 0, 0, True);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -345,15 +381,12 @@ exec_uicb_function(char *func, char *cmd)
|
|||||||
/** Set statustext
|
/** Set statustext
|
||||||
*\param str Statustext string
|
*\param str Statustext string
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
set_statustext(int s, char *str)
|
set_statustext(int s, char *str)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
long data[5];
|
|
||||||
char atom_name[64];
|
char atom_name[64];
|
||||||
|
|
||||||
data[4] = True;
|
|
||||||
|
|
||||||
if(!str)
|
if(!str)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -366,7 +399,7 @@ set_statustext(int s, char *str)
|
|||||||
XChangeProperty(dpy, ROOT, ATOM(atom_name), ATOM("UTF8_STRING"),
|
XChangeProperty(dpy, ROOT, ATOM(atom_name), ATOM("UTF8_STRING"),
|
||||||
8, PropModeReplace, (uchar*)str, strlen(str));
|
8, PropModeReplace, (uchar*)str, strlen(str));
|
||||||
|
|
||||||
send_client_event(data, atom_name);
|
ewmh_send_message(ROOT, ROOT, atom_name, 0, 0, 0, 0, True);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -376,7 +409,7 @@ set_statustext(int s, char *str)
|
|||||||
XChangeProperty(dpy, ROOT, ATOM(atom_name), ATOM("UTF8_STRING"),
|
XChangeProperty(dpy, ROOT, ATOM(atom_name), ATOM("UTF8_STRING"),
|
||||||
8, PropModeReplace, (uchar*)str, strlen(str));
|
8, PropModeReplace, (uchar*)str, strlen(str));
|
||||||
|
|
||||||
send_client_event(data, atom_name);
|
ewmh_send_message(ROOT, ROOT, atom_name, 0, 0, 0, 0, True);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -384,29 +417,32 @@ set_statustext(int s, char *str)
|
|||||||
|
|
||||||
/** Update status script by ewmh hint
|
/** Update status script by ewmh hint
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
update_status(void)
|
update_status(void)
|
||||||
{
|
{
|
||||||
long data[5];
|
|
||||||
|
|
||||||
if(!check_wmfs_running())
|
if(!check_wmfs_running())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
data[4] = True;
|
ewmh_send_message(ROOT, ROOT, "_WMFS_UPDATE_STATUS", 0, 0, 0, 0, True);
|
||||||
|
|
||||||
send_client_event(data, "_WMFS_UPDATE_STATUS");
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Signal handle function
|
/** Signal handle function
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
signal_handle(int sig)
|
signal_handle(int sig)
|
||||||
{
|
{
|
||||||
exiting = True;
|
switch (sig)
|
||||||
quit();
|
{
|
||||||
exit(EXIT_SUCCESS);
|
case SIGQUIT:
|
||||||
|
case SIGTERM:
|
||||||
|
exiting = True;
|
||||||
|
break;
|
||||||
|
case SIGCHLD:
|
||||||
|
sig_chld = True;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -420,12 +456,16 @@ int
|
|||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char *ol = "csgVS";
|
char *ol = "csS";
|
||||||
|
extern char *optarg;
|
||||||
|
extern int optind;
|
||||||
|
struct sigaction sa;
|
||||||
|
|
||||||
argv_global = _strdup(argv[0]);
|
argv_global = xstrdup(argv[0]);
|
||||||
|
all_argv = argv;
|
||||||
sprintf(conf.confpath, "%s/"DEF_CONF, getenv("HOME"));
|
sprintf(conf.confpath, "%s/"DEF_CONF, getenv("HOME"));
|
||||||
|
|
||||||
while((i = getopt(argc, argv, "hviSc:s:g:C:V:")) != -1)
|
while((i = getopt(argc, argv, "hviSc:s:C:")) != -1)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* For options who need WMFS running */
|
/* For options who need WMFS running */
|
||||||
@@ -439,9 +479,7 @@ main(int argc, char **argv)
|
|||||||
printf("usage: %s [-ihvS] [-C <file>] [-c <uicb function> <cmd> ] [-g <argument>] [-s <screen_num> <string>] [-V <viwmfs cmd]\n"
|
printf("usage: %s [-ihvS] [-C <file>] [-c <uicb function> <cmd> ] [-g <argument>] [-s <screen_num> <string>] [-V <viwmfs cmd]\n"
|
||||||
" -C <file> Load a configuration file\n"
|
" -C <file> Load a configuration file\n"
|
||||||
" -c <uicb_function> <cmd> Execute an uicb function to control WMFS\n"
|
" -c <uicb_function> <cmd> Execute an uicb function to control WMFS\n"
|
||||||
" -g <argument> Show information about wmfs status\n"
|
|
||||||
" -s <screen_num> <string> Set the bar(s) statustext\n"
|
" -s <screen_num> <string> Set the bar(s) statustext\n"
|
||||||
" -V <viwmfs cmd> Manage WMFS with vi-like command\n"
|
|
||||||
" -S Update status script\n"
|
" -S Update status script\n"
|
||||||
" -h Show this page\n"
|
" -h Show this page\n"
|
||||||
" -i Show informations\n"
|
" -i Show informations\n"
|
||||||
@@ -455,11 +493,7 @@ main(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'v':
|
case 'v':
|
||||||
printf("WMFS version : "WMFS_VERSION"\n"
|
printf("wmfs"WMFS_VERSION"\n");
|
||||||
" Compilation settings :\n"
|
|
||||||
" - Flags : "WMFS_COMPILE_FLAGS"\n"
|
|
||||||
" - Linked Libs : "WMFS_LINKED_LIBS"\n"
|
|
||||||
" - On "WMFS_COMPILE_MACHINE" by "WMFS_COMPILE_BY".\n");
|
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -470,7 +504,7 @@ main(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'C':
|
case 'C':
|
||||||
strcpy(conf.confpath, optarg);
|
strncpy(conf.confpath, optarg, sizeof(conf.confpath));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'c':
|
case 'c':
|
||||||
@@ -487,17 +521,6 @@ main(int argc, char **argv)
|
|||||||
XCloseDisplay(dpy);
|
XCloseDisplay(dpy);
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'g':
|
|
||||||
getinfo(optarg);
|
|
||||||
XCloseDisplay(dpy);
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
break;
|
|
||||||
case 'V':
|
|
||||||
viwmfs(argc, argv);
|
|
||||||
XCloseDisplay(dpy);
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -506,8 +529,12 @@ main(int argc, char **argv)
|
|||||||
errx(EXIT_FAILURE, "cannot open X server.");
|
errx(EXIT_FAILURE, "cannot open X server.");
|
||||||
|
|
||||||
/* Set signal handler */
|
/* Set signal handler */
|
||||||
(void)signal(SIGTERM, &signal_handle);
|
memset(&sa, 0, sizeof(sa));
|
||||||
(void)signal(SIGINT, &signal_handle);
|
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 */
|
/* Check if an other WM is already running; set the error handler */
|
||||||
XSetErrorHandler(errorhandler);
|
XSetErrorHandler(errorhandler);
|
||||||
|
|||||||
308
src/wmfs.h
308
src/wmfs.h
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* wmfs.h
|
* wmfs.h
|
||||||
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
|
* Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
|
||||||
@@ -33,13 +34,13 @@
|
|||||||
#ifndef WMFS_H
|
#ifndef WMFS_H
|
||||||
#define WMFS_H
|
#define WMFS_H
|
||||||
|
|
||||||
#define _BSD_SOURCE /* vsnprintf */
|
|
||||||
#define _POSIX_SOURCE /* kill */
|
|
||||||
/* Lib headers */
|
/* Lib headers */
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -49,21 +50,21 @@
|
|||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <locale.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/time.h>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
#include <X11/cursorfont.h>
|
#include <X11/cursorfont.h>
|
||||||
#include <X11/Xft/Xft.h>
|
|
||||||
|
|
||||||
/* Local headers */
|
|
||||||
#include "parse/parse.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "structs.h"
|
|
||||||
|
|
||||||
/* Optional dependencies */
|
/* Optional dependencies */
|
||||||
|
#ifdef HAVE_XFT
|
||||||
|
#include <X11/Xft/Xft.h>
|
||||||
|
#endif /* HAVE_XFT */
|
||||||
|
|
||||||
#ifdef HAVE_XINERAMA
|
#ifdef HAVE_XINERAMA
|
||||||
#include <X11/extensions/Xinerama.h>
|
#include <X11/extensions/Xinerama.h>
|
||||||
#endif /* HAVE_XINERAMA */
|
#endif /* HAVE_XINERAMA */
|
||||||
@@ -76,6 +77,10 @@
|
|||||||
#include <Imlib2.h>
|
#include <Imlib2.h>
|
||||||
#endif /* HAVE_IMLIB */
|
#endif /* HAVE_IMLIB */
|
||||||
|
|
||||||
|
/* Local headers */
|
||||||
|
#include "parse.h"
|
||||||
|
#include "structs.h"
|
||||||
|
|
||||||
/* MACRO */
|
/* MACRO */
|
||||||
#define ButtonMask (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask)
|
#define ButtonMask (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask)
|
||||||
#define MouseMask (ButtonMask | PointerMotionMask)
|
#define MouseMask (ButtonMask | PointerMotionMask)
|
||||||
@@ -84,14 +89,13 @@
|
|||||||
#define ROOT RootWindow(dpy, SCREEN)
|
#define ROOT RootWindow(dpy, SCREEN)
|
||||||
#define MAXH DisplayHeight(dpy, DefaultScreen(dpy))
|
#define MAXH DisplayHeight(dpy, DefaultScreen(dpy))
|
||||||
#define MAXW DisplayWidth(dpy, DefaultScreen(dpy))
|
#define MAXW DisplayWidth(dpy, DefaultScreen(dpy))
|
||||||
#define INFOBARH ((conf.bars.height > 0) ? conf.bars.height : (font->height * 1.5))
|
#define INFOBARH ((conf.bars.height > 0) ? conf.bars.height : (font.height * 1.5))
|
||||||
#define FHINFOBAR ((font->height - font->descent) + (INFOBARH - font->height) / 2)
|
#define FHINFOBAR ((font.height - font.de) + (((int)INFOBARH - font.height) >> 1))
|
||||||
#define SHADH (1)
|
#define SHADH (1)
|
||||||
#define SHADC (0x000000) /* 'Cause i don't know how darken a color yet */
|
|
||||||
#define BORDH conf.client.borderheight
|
#define BORDH conf.client.borderheight
|
||||||
#define TBARH ((conf.titlebar.height < BORDH) ? BORDH : conf.titlebar.height)
|
#define TBARH ((conf.titlebar.height < BORDH) ? BORDH : conf.titlebar.height)
|
||||||
#define RESHW (6 * (BORDH))
|
#define RESHW (6 * (BORDH))
|
||||||
#define BUTTONWH (TBARH / 2)
|
#define BUTTONWH (TBARH >> 1)
|
||||||
#define DEF_CONF ".config/wmfs/wmfsrc"
|
#define DEF_CONF ".config/wmfs/wmfsrc"
|
||||||
#define DEF_STATUS ".config/wmfs/status.sh"
|
#define DEF_STATUS ".config/wmfs/status.sh"
|
||||||
#define PAD conf.pad
|
#define PAD conf.pad
|
||||||
@@ -102,26 +106,37 @@
|
|||||||
win = XCreateWindow(dpy, (parent), (x), (y), (w), (h), (b), CopyFromParent, \
|
win = XCreateWindow(dpy, (parent), (x), (y), (w), (h), (b), CopyFromParent, \
|
||||||
InputOutput, CopyFromParent, (mask), (at)); \
|
InputOutput, CopyFromParent, (mask), (at)); \
|
||||||
XSetWindowBackground(dpy, win, (col)); \
|
XSetWindowBackground(dpy, win, (col)); \
|
||||||
} while (/* CONSTCOND */ 0)
|
} while(/* CONSTCOND */ 0)
|
||||||
|
|
||||||
#define ATOM(a) XInternAtom(dpy, (a), False)
|
#define HANDLE_EVENT(e) event_handle[(e)->type](e);
|
||||||
#define FRAMEW(w) ((w) + BORDH * 2)
|
#define ATOM(a) XInternAtom(dpy, (a), False)
|
||||||
#define FRAMEH(h) ((h) + (BORDH + TBARH))
|
#define FRAMEW(w) ((w) + (BORDH << 1))
|
||||||
#define ROUND(x) (float)((x > 0) ? x + (float)0.5 : x - (float)0.5)
|
#define FRAMEH(h) ((h) + (BORDH + TBARH))
|
||||||
#define CHECK(x) if(!(x)) return
|
#define ROUND(x) (float)((x > 0) ? x + (float)0.5 : x - (float)0.5)
|
||||||
#define IFREE(x) if(x) free(x)
|
#define CHECK(x) if(!(x)) return
|
||||||
#define LEN(x) (sizeof(x) / sizeof((x)[0]))
|
#define LEN(x) (sizeof(x) / sizeof((x)[0]))
|
||||||
#define MAXCLIST (64)
|
#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)))
|
||||||
|
|
||||||
|
/* 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.c */
|
/* barwin.c */
|
||||||
BarWindow *barwin_create(Window parent,
|
BarWindow *barwin_create(Window parent,
|
||||||
int x, int y,
|
int x, int y,
|
||||||
uint w, uint h,
|
int w, int h,
|
||||||
uint bg, char*fg,
|
uint bg, char*fg,
|
||||||
Bool entermask,
|
bool entermask,
|
||||||
Bool stipple,
|
bool stipple,
|
||||||
Bool border);
|
bool border);
|
||||||
void barwin_draw_text(BarWindow *bw, int x, int y, char *text);
|
void barwin_draw_text(BarWindow *bw, int x, int y, char *text);
|
||||||
|
void barwin_color_set(BarWindow *bw, uint bg, char *fg);
|
||||||
void barwin_delete(BarWindow *bw);
|
void barwin_delete(BarWindow *bw);
|
||||||
void barwin_delete_subwin(BarWindow *bw);
|
void barwin_delete_subwin(BarWindow *bw);
|
||||||
void barwin_map(BarWindow *bw);
|
void barwin_map(BarWindow *bw);
|
||||||
@@ -129,167 +144,177 @@ void barwin_map_subwin(BarWindow *bw);
|
|||||||
void barwin_unmap(BarWindow *bw);
|
void barwin_unmap(BarWindow *bw);
|
||||||
void barwin_unmap_subwin(BarWindow *bw);
|
void barwin_unmap_subwin(BarWindow *bw);
|
||||||
void barwin_move(BarWindow *bw, int x, int y);
|
void barwin_move(BarWindow *bw, int x, int y);
|
||||||
void barwin_resize(BarWindow *bw, uint w, uint h);
|
void barwin_resize(BarWindow *bw, int w, int h);
|
||||||
void barwin_refresh_color(BarWindow *bw);
|
void barwin_refresh_color(BarWindow *bw);
|
||||||
void barwin_refresh(BarWindow *bw);
|
void barwin_refresh(BarWindow *bw);
|
||||||
|
|
||||||
/* draw.c */
|
/* draw.c */
|
||||||
void draw_text(Drawable d, int x, int y, char* fg, int pad, char *str);
|
void draw_text(Drawable d, int x, int y, char* fg, char *str);
|
||||||
void draw_rectangle(Drawable dr, int x, int y, uint w, uint h, uint color);
|
void draw_rectangle(Drawable dr, int x, int y, int w, int h, uint color);
|
||||||
void draw_graph(Drawable dr, int x, int y, uint w, uint h, uint color, char *data);
|
void draw_graph(Drawable dr, int x, int y, int w, int h, uint color, char *data);
|
||||||
|
|
||||||
#ifdef HAVE_IMLIB
|
|
||||||
void draw_image(Drawable dr, int x, int y, int w, int h, char *name);
|
|
||||||
#endif /* HAVE_IMLIB */
|
|
||||||
|
|
||||||
ushort textw(char *text);
|
ushort textw(char *text);
|
||||||
|
|
||||||
/* infobar.c */
|
/* infobar.c */
|
||||||
void infobar_init(void);
|
void infobar_init(void);
|
||||||
void infobar_draw(int sc);
|
void infobar_draw_layout(InfoBar *i);
|
||||||
void infobar_draw_layout(int sc);
|
void infobar_draw(InfoBar *i);
|
||||||
void infobar_draw_selbar(int sc);
|
void infobar_draw_selbar(InfoBar *i);
|
||||||
void infobar_draw_taglist(int sc);
|
void infobar_draw_taglist(InfoBar *i);
|
||||||
void infobar_update_taglist(int sc);
|
void infobar_update_taglist(InfoBar *i);
|
||||||
void infobar_destroy(void);
|
void infobar_destroy(void);
|
||||||
void infobar_set_position(int pos);
|
void infobar_set_position(int pos);
|
||||||
void uicb_infobar_togglepos(uicb_t);
|
void uicb_infobar_togglepos(uicb_t);
|
||||||
|
void uicb_infobar_toggledisplay(uicb_t);
|
||||||
void uicb_toggle_tagautohide(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 */
|
/* client.c */
|
||||||
void client_attach(Client *c);
|
void client_attach(Client *c);
|
||||||
void client_configure(Client *c);
|
void client_configure(Client *c);
|
||||||
void client_detach(Client *c);
|
void client_detach(Client *c);
|
||||||
void client_above(Client *c);
|
|
||||||
void client_focus(Client *c);
|
void client_focus(Client *c);
|
||||||
Client* client_get_next(void);
|
Client *client_get_next(void);
|
||||||
Client* client_get_prev(void);
|
Client *client_get_prev(void);
|
||||||
/* client_gb_*() {{{ */
|
/* client_gb_*() {{{ */
|
||||||
Client* client_gb_win(Window w);
|
Client* client_gb_win(Window w);
|
||||||
Client* client_gb_frame(Window w);
|
Client* client_gb_frame(Window w);
|
||||||
Client* client_gb_titlebar(Window w);
|
Client* client_gb_titlebar(Window w);
|
||||||
Client* client_gb_resize(Window w);
|
Client* client_gb_resize(Window w);
|
||||||
Client* client_gb_button(Window w, int *n);
|
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_get_name(Client *c);
|
||||||
void client_hide(Client *c);
|
void client_hide(Client *c);
|
||||||
void client_kill(Client *c);
|
void client_kill(Client *c);
|
||||||
Bool ishide(Client *c, int screen);
|
bool ishide(Client *c, int screen);
|
||||||
void client_map(Client *c);
|
void client_map(Client *c);
|
||||||
Client* client_manage(Window w, XWindowAttributes *wa, Bool ar);
|
Client* client_manage(Window w, XWindowAttributes *wa, bool ar);
|
||||||
void client_geo_hints(XRectangle *geo, Client *c);
|
void client_geo_hints(Geo *geo, Client *c);
|
||||||
void client_moveresize(Client *c, XRectangle geo, Bool r);
|
void client_moveresize(Client *c, Geo geo, bool r);
|
||||||
void client_maximize(Client *c);
|
void client_maximize(Client *c);
|
||||||
void client_size_hints(Client *c);
|
void client_size_hints(Client *c);
|
||||||
void client_swap(Client *c1, Client *c2);
|
void client_swap(Client *c1, Client *c2);
|
||||||
void client_raise(Client *c);
|
void client_raise(Client *c);
|
||||||
void client_unhide(Client *c);
|
void client_unhide(Client *c);
|
||||||
|
void client_focus_next(Client *c);
|
||||||
void client_unmanage(Client *c);
|
void client_unmanage(Client *c);
|
||||||
void client_unmap(Client *c);
|
void client_unmap(Client *c);
|
||||||
void client_set_wanted_tag(Client *c);
|
|
||||||
void client_update_attributes(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);
|
void uicb_client_raise(uicb_t);
|
||||||
void uicb_client_next(uicb_t);
|
/* Generated with macro {{{ */
|
||||||
void uicb_client_prev(uicb_t);
|
void uicb_client_focus_next(uicb_t);
|
||||||
void uicb_client_swap_next(uicb_t);
|
void uicb_client_focus_prev(uicb_t);
|
||||||
void uicb_client_swap_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_kill(uicb_t);
|
||||||
void uicb_client_screen_next(uicb_t);
|
void uicb_client_screen_next(uicb_t);
|
||||||
void uicb_client_screen_prev(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_move(uicb_t cmd);
|
||||||
void uicb_client_resize(uicb_t cmd);
|
void uicb_client_resize(uicb_t cmd);
|
||||||
void uicb_ignore_next_client_rules(uicb_t cmd);
|
void uicb_ignore_next_client_rules(uicb_t cmd);
|
||||||
void uicb_clientlist(uicb_t cmd);
|
void uicb_clientlist(uicb_t cmd);
|
||||||
void uicb_client_select(uicb_t cmd);
|
bool uicb_checkclist(uicb_t);
|
||||||
Bool uicb_checkclist(uicb_t);
|
|
||||||
void uicb_client_ignore_tag(uicb_t);
|
void uicb_client_ignore_tag(uicb_t);
|
||||||
|
void uicb_client_set_master(uicb_t);
|
||||||
|
|
||||||
/* ewmh.c */
|
/* ewmh.c */
|
||||||
void ewmh_init_hints(void);
|
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_get_number_of_desktop(void);
|
||||||
void ewmh_update_current_tag_prop(void);
|
void ewmh_update_current_tag_prop(void);
|
||||||
void ewmh_get_client_list(void);
|
void ewmh_get_client_list(void);
|
||||||
void ewmh_get_desktop_names(void);
|
void ewmh_get_desktop_names(void);
|
||||||
void ewmh_set_desktop_geometry(void);
|
void ewmh_set_desktop_geometry(void);
|
||||||
void ewmh_set_workarea(void);
|
|
||||||
void ewmh_manage_net_wm_state(long data_l[], Client *c);
|
void ewmh_manage_net_wm_state(long data_l[], Client *c);
|
||||||
void ewmh_manage_window_type(Client *c);
|
void ewmh_manage_window_type(Client *c);
|
||||||
|
|
||||||
/* frame.c */
|
/* frame.c */
|
||||||
void frame_create(Client *c);
|
void frame_create(Client *c);
|
||||||
void frame_delete(Client *c);
|
void frame_delete(Client *c);
|
||||||
void frame_moveresize(Client *c, XRectangle geo);
|
void frame_moveresize(Client *c, Geo geo);
|
||||||
|
void frame_update_color(Client *c, bool focused);
|
||||||
void frame_update(Client *c);
|
void frame_update(Client *c);
|
||||||
|
|
||||||
/* config.c */
|
/* config.c */
|
||||||
void init_conf(void);
|
void init_conf(void);
|
||||||
|
|
||||||
|
/* color.c */
|
||||||
|
uint color_shade(uint, double);
|
||||||
|
|
||||||
/* event.c */
|
/* event.c */
|
||||||
void buttonpress(XButtonEvent *ev);
|
|
||||||
void configureevent(XConfigureRequestEvent *ev);
|
|
||||||
void clientmessageevent(XClientMessageEvent *ev);
|
|
||||||
void destroynotify(XDestroyWindowEvent *ev);
|
|
||||||
void enternotify(XCrossingEvent *ev);
|
|
||||||
void expose(XExposeEvent *ev);
|
|
||||||
void focusin(XFocusChangeEvent *ev);
|
|
||||||
void grabkeys(void);
|
void grabkeys(void);
|
||||||
void keypress(XKeyPressedEvent *ev);
|
void event_make_array(void);
|
||||||
void mappingnotify(XMappingEvent *ev);
|
|
||||||
void maprequest(XMapRequestEvent *ev);
|
#ifdef HAVE_XRANDR
|
||||||
void propertynotify(XPropertyEvent *ev);
|
void xrandrevent(XEvent *e);
|
||||||
void unmapnotify(XUnmapEvent *ev);
|
#endif /* HAVE_XRANDR */
|
||||||
void send_client_event(long data[5], char *atom_name);
|
|
||||||
void getevent(XEvent ev);
|
|
||||||
|
|
||||||
/* menu.c */
|
/* 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_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_new_item(MenuItem *mi, char *name, void *func, char *cmd);
|
||||||
void menu_draw(Menu menu, int x, int y);
|
void menu_draw(Menu menu, int x, int y);
|
||||||
Bool menu_manage_event(XEvent *ev, Menu *menu, BarWindow *winitem[]);
|
|
||||||
Bool menu_activate_item(Menu *menu, int i);
|
|
||||||
void menu_focus_item(Menu *menu, int item, BarWindow *winitem[]);
|
|
||||||
void menu_draw_item_name(Menu *menu, int item, BarWindow *winitem[]);
|
|
||||||
int menu_get_longer_string(MenuItem *mi, int nitem);
|
|
||||||
void uicb_menu(uicb_t cmd);
|
void uicb_menu(uicb_t cmd);
|
||||||
void menu_clear(Menu *menu);
|
void menu_clear(Menu *menu);
|
||||||
|
|
||||||
/* launcher.c */
|
/* launcher.c */
|
||||||
void launcher_execute(Launcher *launcher);
|
|
||||||
void uicb_launcher(uicb_t);
|
void uicb_launcher(uicb_t);
|
||||||
|
|
||||||
/* mouse.c */
|
/* mouse.c */
|
||||||
void mouse_dragborder(XRectangle geo, GC g);
|
|
||||||
void mouse_move_tile_client(Client **c);
|
|
||||||
void mouse_move_tag_client(Client *c);
|
|
||||||
void mouse_move(Client *c);
|
|
||||||
void mouse_resize(Client *c);
|
void mouse_resize(Client *c);
|
||||||
void mouse_grabbuttons(Client *c, Bool focused);
|
void mouse_grabbuttons(Client *c, bool focused);
|
||||||
void uicb_mouse_move(uicb_t);
|
void uicb_mouse_move(uicb_t);
|
||||||
void uicb_mouse_resize(uicb_t);
|
void uicb_mouse_resize(uicb_t);
|
||||||
|
|
||||||
/* util.c */
|
/* util.c */
|
||||||
ulong color_enlight(ulong col);
|
void *xmalloc(size_t, size_t);
|
||||||
void *emalloc(uint element, uint size);
|
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);
|
long getcolor(char *color);
|
||||||
void setwinstate(Window win, long state);
|
void setwinstate(Window win, long state);
|
||||||
char* _strdup(char const *str);
|
|
||||||
/* Conf usage {{{ */
|
/* Conf usage {{{ */
|
||||||
void* name_to_func(char *name, const func_name_list_t *l);
|
void* name_to_func(char *name, const func_name_list_t *l);
|
||||||
ulong char_to_modkey(char *name, key_name_list_t key_l[]);
|
ulong char_to_modkey(char *name, key_name_list_t key_l[]);
|
||||||
uint char_to_button(char *name, name_to_uint_t blist[]);
|
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[]);
|
Layout layout_name_to_struct(Layout lt[], char *name, int n, const func_name_list_t llist[]);
|
||||||
char* alias_to_str(char *conf_choice);
|
|
||||||
/* }}} */
|
/* }}} */
|
||||||
XRectangle get_mouse_pos(void);
|
|
||||||
char *char_to_str(const char c);
|
char *char_to_str(const char c);
|
||||||
int spawn(const char *str, ...);
|
pid_t spawn(const char *str, ...);
|
||||||
void swap_ptr(void **x, void **y);
|
void swap_ptr(void **x, void **y);
|
||||||
void uicb_spawn(uicb_t);
|
void uicb_spawn(uicb_t);
|
||||||
char *clean_value(char *str);
|
char *clean_value(char *str);
|
||||||
|
char* patht(char *path);
|
||||||
#ifdef HAVE_IMLIB
|
int qsort_string_compare (const void * a, const void * b);
|
||||||
int parse_image_block(ImageAttr *im, char *str);
|
|
||||||
#endif /* HAVE_IMLIB */
|
|
||||||
|
|
||||||
/* tag.c */
|
/* tag.c */
|
||||||
void tag_set(int tag);
|
void tag_set(int tag);
|
||||||
@@ -306,18 +331,19 @@ void uicb_tagtransfert_prev(uicb_t);
|
|||||||
void uicb_tag_urgent(uicb_t cmd);
|
void uicb_tag_urgent(uicb_t cmd);
|
||||||
void tag_additional(int sc, int tag, int adtag);
|
void tag_additional(int sc, int tag, int adtag);
|
||||||
void uicb_tag_toggle_additional(uicb_t);
|
void uicb_tag_toggle_additional(uicb_t);
|
||||||
void tag_swap(int s, int t1, int t2);
|
|
||||||
void uicb_tag_swap(uicb_t);
|
void uicb_tag_swap(uicb_t);
|
||||||
void uicb_tag_swap_next(uicb_t);
|
void uicb_tag_swap_next(uicb_t);
|
||||||
void uicb_tag_swap_previous(uicb_t);
|
void uicb_tag_swap_previous(uicb_t);
|
||||||
void tag_new(int s, char *name);
|
|
||||||
void uicb_tag_new(uicb_t);
|
void uicb_tag_new(uicb_t);
|
||||||
void tag_delete(int s, int tag);
|
|
||||||
void uicb_tag_del(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 */
|
/* screen.c */
|
||||||
int screen_count(void);
|
int screen_count(void);
|
||||||
XRectangle screen_get_geo(int s);
|
Geo screen_get_geo(int s);
|
||||||
int screen_get_with_geo(int x, int y);
|
int screen_get_with_geo(int x, int y);
|
||||||
int screen_get_sel(void);
|
int screen_get_sel(void);
|
||||||
void screen_set_sel(int screen);
|
void screen_set_sel(int screen);
|
||||||
@@ -328,27 +354,34 @@ void uicb_screen_prev(uicb_t);
|
|||||||
void uicb_screen_prev_sel(uicb_t);
|
void uicb_screen_prev_sel(uicb_t);
|
||||||
|
|
||||||
/* status.c */
|
/* status.c */
|
||||||
int statustext_rectangle(StatusRec *r, char *str);
|
|
||||||
int statustext_graph(StatusGraph *g, char *str);
|
|
||||||
int statustext_text(StatusText *s, char *str);
|
|
||||||
void statustext_normal(int sc, char *str);
|
|
||||||
void statustext_handle(int sc, char *str);
|
void statustext_handle(int sc, char *str);
|
||||||
|
|
||||||
|
/* 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 */
|
/* layout.c */
|
||||||
void arrange(int screen, Bool update_layout);
|
void arrange(int screen, bool update_layout);
|
||||||
void freelayout(int screen);
|
void layout_func(int screen, int tag);
|
||||||
void layoutswitch(Bool b);
|
|
||||||
void maxlayout(int screen);
|
|
||||||
Client *tiled_client(int screen, Client *c);
|
Client *tiled_client(int screen, Client *c);
|
||||||
|
void freelayout(int screen);
|
||||||
|
void layoutswitch(bool b);
|
||||||
|
void maxlayout(int screen);
|
||||||
/* tile {{{ */
|
/* tile {{{ */
|
||||||
void grid(int screen);
|
|
||||||
void tile(int screen);
|
void tile(int screen);
|
||||||
void tile_left(int screen);
|
void tile_left(int screen);
|
||||||
void tile_top(int screen);
|
void tile_top(int screen);
|
||||||
void tile_bottom(int screen);
|
void tile_bottom(int screen);
|
||||||
void mirror_vertical(int screen);
|
void mirror_vertical(int screen);
|
||||||
void mirror_horizontal(int screen);
|
void mirror_horizontal(int screen);
|
||||||
void layer(int screen);
|
void grid_vertical(int screen);
|
||||||
|
void grid_horizontal(int screen);
|
||||||
/* }}} */
|
/* }}} */
|
||||||
void uicb_togglemax(uicb_t);
|
void uicb_togglemax(uicb_t);
|
||||||
void uicb_togglefree(uicb_t);
|
void uicb_togglefree(uicb_t);
|
||||||
@@ -359,45 +392,43 @@ void uicb_set_nmaster(uicb_t);
|
|||||||
void uicb_set_layout(uicb_t);
|
void uicb_set_layout(uicb_t);
|
||||||
void uicb_toggle_resizehint(uicb_t);
|
void uicb_toggle_resizehint(uicb_t);
|
||||||
void uicb_toggle_abovefc(uicb_t cmd);
|
void uicb_toggle_abovefc(uicb_t cmd);
|
||||||
void uicb_set_layer(uicb_t cmd);
|
|
||||||
void uicb_set_client_layer(uicb_t cmd);
|
|
||||||
void layout_set_client_master(Client *c);
|
void layout_set_client_master(Client *c);
|
||||||
Bool uicb_checkmax(uicb_t);
|
void layout_split_client(Client *c, bool p);
|
||||||
Bool uicb_checkfree(uicb_t);
|
void layout_split_apply(Client *c);
|
||||||
Bool uicb_checklayout(uicb_t);
|
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 */
|
/* init.c */
|
||||||
void init(void);
|
void init(void);
|
||||||
void init_root(void);
|
|
||||||
void init_font(void);
|
|
||||||
void init_gc(void);
|
|
||||||
void init_cursor(void);
|
|
||||||
void init_key(void);
|
|
||||||
void init_geometry(void);
|
|
||||||
void init_status(void);
|
|
||||||
|
|
||||||
/* getinfo.c */
|
/* split.c */
|
||||||
void getinfo_tag(void);
|
void split_store_geo(int screen, int tag);
|
||||||
void getinfo_screen(void);
|
void split_set_current(Client *nc, Client *ghost);
|
||||||
void getinfo_layout(void);
|
void split_apply_current(int screen, int tag);
|
||||||
void getinfo_mwfact(void);
|
void split_arrange_closed(Client *ghost);
|
||||||
void getinfo_nmaster(void);
|
Geo split_client(Client *c, bool p);
|
||||||
void getinfo(char *info);
|
void split_client_fill(Client *c, Geo geo);
|
||||||
|
void split_client_integrate(Client *c, Client *sc, int screen, int tag);
|
||||||
/* viwmfs.c */
|
void split_move_dir(Client *c, Position p);
|
||||||
void viwmfs(int argc, char **argv);
|
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 */
|
/* wmfs.c */
|
||||||
int errorhandler(Display *d, XErrorEvent *event);
|
int errorhandler(Display *d, XErrorEvent *event);
|
||||||
int errorhandlerdummy(Display *d, XErrorEvent *event);
|
int errorhandlerdummy(Display *d, XErrorEvent *event);
|
||||||
void quit(void);
|
void quit(void);
|
||||||
void *thread_process(void *arg);
|
void *thread_process(void *arg);
|
||||||
void mainloop(void);
|
bool check_wmfs_running(void);
|
||||||
void scan(void);
|
|
||||||
Bool check_wmfs_running(void);
|
|
||||||
void exec_uicb_function(char *func, char *cmd);
|
void exec_uicb_function(char *func, char *cmd);
|
||||||
void set_statustext(int s, char *str);
|
|
||||||
void update_status(void);
|
|
||||||
void handle_signal(int signum);
|
void handle_signal(int signum);
|
||||||
void uicb_quit(uicb_t);
|
void uicb_quit(uicb_t);
|
||||||
void uicb_reload(uicb_t);
|
void uicb_reload(uicb_t);
|
||||||
@@ -411,19 +442,21 @@ int selscreen;
|
|||||||
int prevselscreen;
|
int prevselscreen;
|
||||||
Conf conf;
|
Conf conf;
|
||||||
Key *keys;
|
Key *keys;
|
||||||
Bool exiting, estatus;
|
bool estatus;
|
||||||
XRectangle *sgeo;
|
Geo *sgeo;
|
||||||
XRectangle *spgeo;
|
Geo *spgeo;
|
||||||
Cursor cursor[CurLast];
|
Cursor cursor[CurLast];
|
||||||
char *argv_global;
|
char *argv_global;
|
||||||
|
char **all_argv;
|
||||||
int xrandr_event;
|
int xrandr_event;
|
||||||
uint timing;
|
uint timing;
|
||||||
|
|
||||||
/* Fonts */
|
/* Fonts */
|
||||||
XftFont *font;
|
FontStruct font;
|
||||||
|
|
||||||
/* Atoms list */
|
/* Atoms list */
|
||||||
Atom *net_atom;
|
Atom *net_atom;
|
||||||
|
Atom trayatom;
|
||||||
|
|
||||||
/* InfoBar/Tags */
|
/* InfoBar/Tags */
|
||||||
InfoBar *infobar;
|
InfoBar *infobar;
|
||||||
@@ -444,9 +477,14 @@ Client *clients;
|
|||||||
Client *sel;
|
Client *sel;
|
||||||
|
|
||||||
/* Other */
|
/* Other */
|
||||||
func_name_list_t *func_list;
|
int nevent;
|
||||||
|
void (**event_handle)(XEvent*);
|
||||||
|
extern const func_name_list_t func_list[];
|
||||||
extern const func_name_list_t layout_list[];
|
extern const func_name_list_t layout_list[];
|
||||||
uint numlockmask;
|
uint numlockmask;
|
||||||
|
Systray *trayicons;
|
||||||
|
Window traywin;
|
||||||
|
int tray_width;
|
||||||
|
|
||||||
#endif /* WMFS_H */
|
#endif /* WMFS_H */
|
||||||
|
|
||||||
|
|||||||
8
wmfs.1
8
wmfs.1
@@ -62,7 +62,7 @@ Print help information, then exit\&.
|
|||||||
.PP
|
.PP
|
||||||
\fB\-i\fR
|
\fB\-i\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Print WMFS informations
|
Print WMFS information
|
||||||
.RE
|
.RE
|
||||||
.SH "DEFAULT KEY BINDINGS"
|
.SH "DEFAULT KEY BINDINGS"
|
||||||
.PP
|
.PP
|
||||||
@@ -143,7 +143,7 @@ Increase the nmaster (+1)\fR
|
|||||||
.PP
|
.PP
|
||||||
\fBAlt\-Shift + d\fR
|
\fBAlt\-Shift + d\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Decrease the nmaster (-1)\fR
|
Decrease the nmaster (\-1)\fR
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBAlt + t\fR
|
\fBAlt + t\fR
|
||||||
@@ -163,7 +163,7 @@ Make a launcher in the infobar to run an unix command\fR
|
|||||||
.PP
|
.PP
|
||||||
\fBAlt + Escape\fR
|
\fBAlt + Escape\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Set WMFS in ViWMFS mode. (see wmfs -V)\fR
|
Set WMFS in ViWMFS mode. (see wmfs \-V)\fR
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBAlt\-Shift + p\fR
|
\fBAlt\-Shift + p\fR
|
||||||
@@ -193,7 +193,7 @@ Martin Duquesnoy <\fIxorg62@gmail\&.com\fR\&[1]>\&.
|
|||||||
Main site: \fIhttp://wmfs\&.info\fR Bug tracker: \fIhttp://bugs\&.wmfs\&.info\fR
|
Main site: \fIhttp://wmfs\&.info\fR Bug tracker: \fIhttp://bugs\&.wmfs\&.info\fR
|
||||||
.sp
|
.sp
|
||||||
.SH "COPYING"
|
.SH "COPYING"
|
||||||
WMFS is under the BSD license\&. See COPYING for more informations\&.
|
WMFS is under the BSD license\&. See COPYING for more information\&.
|
||||||
.sp
|
.sp
|
||||||
.SH "NOTES"
|
.SH "NOTES"
|
||||||
.IP " 1." 4
|
.IP " 1." 4
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
Encoding=UTF-8
|
Encoding=UTF-8
|
||||||
Name=wmfs
|
Name=wmfs
|
||||||
Comment=Window manager from scratch
|
Comment=Window Manager From Scratch
|
||||||
TryExec=wmfs
|
Exec=ck-launch-session wmfs
|
||||||
Exec=wmfs
|
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ WARN_LOGFILE =
|
|||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# configuration options related to the input files
|
# configuration options related to the input files
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
INPUT = @SOURCE_DIR@/src
|
INPUT = src
|
||||||
INPUT_ENCODING = UTF-8
|
INPUT_ENCODING = UTF-8
|
||||||
FILE_PATTERNS = *.c \
|
FILE_PATTERNS = *.c \
|
||||||
*.h \
|
*.h \
|
||||||
@@ -3,30 +3,52 @@
|
|||||||
# ~/.config/wmfs/wmfsrc and edit it.
|
# ~/.config/wmfs/wmfsrc and edit it.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
# Include file to split configuration
|
||||||
|
# @include "~/.config/wmfs/menu-wmfsrc"
|
||||||
|
|
||||||
[misc]
|
[misc]
|
||||||
font = "dejavu-10"
|
use_xft = true
|
||||||
raisefocus = false
|
font = "dejavu-10"
|
||||||
focus_follow_mouse = true
|
raisefocus = true
|
||||||
|
focus_follow_mouse = true
|
||||||
|
focus_follow_movement = false
|
||||||
|
opacity = 255
|
||||||
|
|
||||||
# focus_pointer_click: click on unfocused client area:
|
# focus_pointer_click: click on unfocused client area:
|
||||||
# true -- default, set focus
|
# true -- default, set focus
|
||||||
# false -- click go to client; including dockapps
|
# false -- click go to client; including dockapps
|
||||||
focus_pointer_click = true
|
focus_pointer_click = true
|
||||||
status_timing = 1 #seconds
|
status_timing = 1 #seconds
|
||||||
|
# status_path = "~/.config/wmfs/status.sh"
|
||||||
[/misc]
|
[/misc]
|
||||||
|
|
||||||
[bar]
|
[bar]
|
||||||
bg = "#191919"
|
bg = "#191919"
|
||||||
fg = "#D4D4D4"
|
fg = "#D4D4D4"
|
||||||
border = true
|
border = true
|
||||||
# selbar = false #not worked now, see section [selbar]
|
#height = "-1"
|
||||||
|
|
||||||
|
light_shade = 0.10
|
||||||
|
dark_shade = -0.10
|
||||||
|
|
||||||
|
[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.
|
# Remove this section to disable the selbar.
|
||||||
[selbar]
|
[selbar]
|
||||||
bg = "#191919"
|
bg = "#191919"
|
||||||
fg = "#D4D4ff"
|
fg = "#D4D4ff"
|
||||||
|
|
||||||
# Cut title lenght
|
# Cut title length
|
||||||
# max_lenght = 25
|
# max_length = 25
|
||||||
|
|
||||||
[mouse] button = "3" func = "clientlist" [/mouse]
|
[mouse] button = "3" func = "clientlist" [/mouse]
|
||||||
[mouse] button = "4" func = "client_next" [/mouse]
|
[mouse] button = "4" func = "client_next" [/mouse]
|
||||||
@@ -48,14 +70,27 @@
|
|||||||
# Value left or right.
|
# Value left or right.
|
||||||
placement = "right"
|
placement = "right"
|
||||||
|
|
||||||
|
# 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.
|
# Tiling layouts.
|
||||||
[layout] type = "tile_right" symbol = "RIGHT" [/layout]
|
[layout] type = "tile_right" symbol = "RIGHT" [/layout]
|
||||||
[layout] type = "tile_left" symbol = "LEFT" [/layout]
|
[layout] type = "tile_left" symbol = "LEFT" [/layout]
|
||||||
[layout] type = "tile_top" symbol = "TOP" [/layout]
|
[layout] type = "tile_top" symbol = "TOP" [/layout]
|
||||||
[layout] type = "tile_bottom" symbol = "BOTTOM" [/layout]
|
[layout] type = "tile_bottom" symbol = "BOTTOM" [/layout]
|
||||||
[layout] type = "tile_grid" symbol = "GRID" [/layout]
|
[layout] type = "tile_grid" symbol = "GRID_H" [/layout]
|
||||||
[layout] type = "mirror_vertical" symbol = "MIRROR_V" [/layout]
|
[layout] type = "tile_grid_vertical" symbol = "GRID_V" [/layout]
|
||||||
[layout] type = "mirror_horizontal" symbol = "MIRROR_H" [/layout]
|
[layout] type = "mirror_vertical" symbol = "MIRROR_V" [/layout]
|
||||||
|
[layout] type = "mirror_horizontal" symbol = "MIRROR_H" [/layout]
|
||||||
|
|
||||||
# Other layouts.
|
# Other layouts.
|
||||||
[layout] type = "max" symbol = "MAX" [/layout]
|
[layout] type = "max" symbol = "MAX" [/layout]
|
||||||
@@ -64,18 +99,43 @@
|
|||||||
[/layouts]
|
[/layouts]
|
||||||
|
|
||||||
[tags]
|
[tags]
|
||||||
tag_round = false
|
[default_tag]
|
||||||
occupied_bg = "#003366"
|
name = "new tag"
|
||||||
sel_fg = "#191919"
|
mwfact = 0.5
|
||||||
sel_bg = "#7E89A2"
|
nmaster = 1
|
||||||
urgent_bg = "#DD1111"
|
layout = "tile"
|
||||||
urgent_fg = "#000000"
|
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 around the tag buttons.
|
||||||
border = true
|
border = true
|
||||||
|
|
||||||
# Hide empty tags in tag list
|
# Hide empty tags in tag list
|
||||||
autohide = false
|
autohide = false
|
||||||
|
|
||||||
# Mouse buttons action on tag.
|
# Mouse buttons action on tag.
|
||||||
mouse_button_tag_sel = "1"
|
mouse_button_tag_sel = "1"
|
||||||
@@ -92,11 +152,12 @@
|
|||||||
layout = "tile_right"
|
layout = "tile_right"
|
||||||
resizehint = false
|
resizehint = false
|
||||||
infobar_position = "top"
|
infobar_position = "top"
|
||||||
|
above_fc = false
|
||||||
|
split = false
|
||||||
#[mouse] [/mouse] Possible multi mouse section
|
#[mouse] [/mouse] Possible multi mouse section
|
||||||
[/tag]
|
[/tag]
|
||||||
|
|
||||||
[tag] name = "two" clients = {"Browser"} [/tag]
|
[tag] name = "two" [/tag]
|
||||||
[tag] name = "three" [/tag]
|
[tag] name = "three" [/tag]
|
||||||
[tag] name = "four" [/tag]
|
[tag] name = "four" [/tag]
|
||||||
[tag] name = "five" [/tag]
|
[tag] name = "five" [/tag]
|
||||||
@@ -117,15 +178,37 @@
|
|||||||
|
|
||||||
[client]
|
[client]
|
||||||
client_round = true
|
client_round = true
|
||||||
|
client_auto_center = false
|
||||||
border_height = 3
|
border_height = 3
|
||||||
border_shadow = true
|
border_shadow = true
|
||||||
border_normal = "#191919"
|
border_normal = "#191919"
|
||||||
border_focus = "#003366"
|
border_focus = "#003366"
|
||||||
|
place_at_mouse = false
|
||||||
resize_corner_normal = "#191919"
|
resize_corner_normal = "#191919"
|
||||||
resize_corner_focus = "#003366"
|
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"
|
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 = "client_raise" [/mouse]
|
||||||
[mouse] button = "1" func = "mouse_move" [/mouse]
|
[mouse] button = "1" func = "mouse_move" [/mouse]
|
||||||
[mouse] button = "3" func = "client_raise" [/mouse]
|
[mouse] button = "3" func = "client_raise" [/mouse]
|
||||||
@@ -144,7 +227,7 @@
|
|||||||
[mouse] button = "3" func = "mouse_resize" [/mouse]
|
[mouse] button = "3" func = "mouse_resize" [/mouse]
|
||||||
|
|
||||||
[button]
|
[button]
|
||||||
# Available "free", "max", "tile" flags of button.
|
# Available "free", "max", "tile" flags or button.
|
||||||
flags = "free,max,tile"
|
flags = "free,max,tile"
|
||||||
[mouse] button = "1" func = "client_kill" [/mouse]
|
[mouse] button = "1" func = "client_kill" [/mouse]
|
||||||
[mouse] button = "3" func = "menu" cmd = "clientmenu" [/mouse]
|
[mouse] button = "3" func = "menu" cmd = "clientmenu" [/mouse]
|
||||||
@@ -156,6 +239,21 @@
|
|||||||
[/titlebar]
|
[/titlebar]
|
||||||
[/client]
|
[/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]
|
[menu]
|
||||||
# Default menu, binded on the root window, button 3.
|
# Default menu, binded on the root window, button 3.
|
||||||
[set_menu]
|
[set_menu]
|
||||||
@@ -170,7 +268,7 @@
|
|||||||
fg_focus = "#191919" bg_focus = "#7E89A2"
|
fg_focus = "#191919" bg_focus = "#7E89A2"
|
||||||
fg_normal = "#9F9AB3" bg_normal = "#191919"
|
fg_normal = "#9F9AB3" bg_normal = "#191919"
|
||||||
|
|
||||||
[item] name = "Terminal" func = "spawn" cmd = "@WMFS_TERM@" [/item]
|
[item] name = "Terminal" func = "spawn" cmd = "urxvt || xterm || gnome-terminal" [/item]
|
||||||
[item] name = "Applications" submenu = "appmenu" [/item]
|
[item] name = "Applications" submenu = "appmenu" [/item]
|
||||||
[item] name = "Next tag" func = "tag_next" [/item]
|
[item] name = "Next tag" func = "tag_next" [/item]
|
||||||
[item] name = "Previous tag" func = "tag_prev" [/item]
|
[item] name = "Previous tag" func = "tag_prev" [/item]
|
||||||
@@ -206,25 +304,19 @@
|
|||||||
|
|
||||||
[launcher]
|
[launcher]
|
||||||
[set_launcher]
|
[set_launcher]
|
||||||
|
# Limit size of the launcher window (px)
|
||||||
|
width_limit = 300
|
||||||
|
|
||||||
name = "launcher_exec"
|
name = "launcher_exec"
|
||||||
prompt = "Exec: "
|
prompt = "Exec: "
|
||||||
command = "exec"
|
command = "exec"
|
||||||
[/set_launcher]
|
[/set_launcher]
|
||||||
|
|
||||||
#ViWMFS : manage wmfs with vi-based command.
|
|
||||||
[set_launcher]
|
|
||||||
name = "viwmfs"
|
|
||||||
prompt = "> "
|
|
||||||
command = "wmfs -V"
|
|
||||||
[/set_launcher]
|
|
||||||
[/launcher]
|
|
||||||
|
|
||||||
[keys]
|
[keys]
|
||||||
# Reload the configuration of wmfs.
|
# Reload the configuration of wmfs.
|
||||||
[key] mod = {"Alt", "Control"} key = "r" func = "reload" [/key]
|
[key] mod = {"Alt", "Control"} key = "r" func = "reload" [/key]
|
||||||
|
|
||||||
# Open a terminal.
|
# Open a terminal.
|
||||||
[key] mod = {"Control"} key = "Return" func = "spawn" cmd = "@WMFS_TERM@" [/key]
|
[key] mod = {"Control"} key = "Return" func = "spawn" cmd = "xterm" [/key]
|
||||||
|
|
||||||
# Kill the selected client.
|
# Kill the selected client.
|
||||||
[key] mod = {"Alt"} key = "q" func = "client_kill" [/key]
|
[key] mod = {"Alt"} key = "q" func = "client_kill" [/key]
|
||||||
@@ -238,6 +330,9 @@
|
|||||||
# Swap current client with the previous.
|
# Swap current client with the previous.
|
||||||
[key] mod = {"Alt", "Shift"} key = "t" func = "client_swap_prev" [/key]
|
[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
|
# Toggle maximum the selected client
|
||||||
[key] mod = {"Alt"} key = "m" func = "toggle_max" [/key]
|
[key] mod = {"Alt"} key = "m" func = "toggle_max" [/key]
|
||||||
|
|
||||||
@@ -246,6 +341,7 @@
|
|||||||
|
|
||||||
# Toggle the position of the infobar.
|
# Toggle the position of the infobar.
|
||||||
[key] mod = {"Alt"} key = "b" func = "toggle_infobar_position" [/key]
|
[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
|
# Toggle the resizehint of the current tag/screen
|
||||||
[key] mod = {"Shift", "Control"} key = "r" func = "toggle_resizehint" [/key]
|
[key] mod = {"Shift", "Control"} key = "r" func = "toggle_resizehint" [/key]
|
||||||
@@ -277,12 +373,6 @@
|
|||||||
# Set the previous layout.
|
# Set the previous layout.
|
||||||
[key] mod = {"Alt", "Shift"} key = "space" func = "layout_prev" [/key]
|
[key] mod = {"Alt", "Shift"} key = "space" func = "layout_prev" [/key]
|
||||||
|
|
||||||
# Increase mwfact.
|
|
||||||
[key] mod = {"Alt"} key = "l" func = "set_mwfact" cmd = "+0.025" [/key]
|
|
||||||
|
|
||||||
# Decrease mwfact.
|
|
||||||
[key] mod = {"Alt"} key = "h" func = "set_mwfact" cmd = "-0.025" [/key]
|
|
||||||
|
|
||||||
# Increase nmaster.
|
# Increase nmaster.
|
||||||
[key] mod = {"Alt"} key = "d" func = "set_nmaster" cmd = "+1" [/key]
|
[key] mod = {"Alt"} key = "d" func = "set_nmaster" cmd = "+1" [/key]
|
||||||
|
|
||||||
@@ -292,9 +382,6 @@
|
|||||||
#Launcher.
|
#Launcher.
|
||||||
[key] mod = {"Alt"} key = "p" func = "launcher" cmd = "launcher_exec" [/key]
|
[key] mod = {"Alt"} key = "p" func = "launcher" cmd = "launcher_exec" [/key]
|
||||||
|
|
||||||
#ViWMFS
|
|
||||||
[key] mod = {"Alt"} key = "Escape" func = "launcher" cmd = "viwmfs" [/key]
|
|
||||||
|
|
||||||
# Set the tag x.
|
# Set the tag x.
|
||||||
[key] mod = {"Alt"} key = "F1" func = "tag" cmd = "1" [/key]
|
[key] mod = {"Alt"} key = "F1" func = "tag" cmd = "1" [/key]
|
||||||
[key] mod = {"Alt"} key = "F2" func = "tag" cmd = "2" [/key]
|
[key] mod = {"Alt"} key = "F2" func = "tag" cmd = "2" [/key]
|
||||||
@@ -328,6 +415,58 @@
|
|||||||
[key] mod = {"Alt", "Super"} key = "F8" func = "tag_toggle_additional" cmd ="8" [/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]
|
[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]
|
[/keys]
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user