Merge branch 'master' into bacardi55

This commit is contained in:
Raphael Khaiat 2010-09-05 15:13:49 +02:00
commit 1ec6d90c1e
23 changed files with 1225 additions and 859 deletions

View File

@ -1,273 +1,171 @@
# -*- mode: cmake -*-
#Cmakelists.txt
# Minimum version of CMake
cmake_minimum_required(VERSION 2.6)
# Minimal version of CMake
cmake_minimum_required(VERSION 2.6.0)
cmake_minimum_required(VERSION 2.6.0 FATAL_ERROR)
if(COMMAND cmake_policy)
cmake_policy(VERSION 2.6)
endif()
cmake_policy(SET CMP0003 NEW)
endif(COMMAND cmake_policy)
CONFIGURE_FILE(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
# set some default options
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules ${CMAKE_MODULE_PATH} )
set(CMAKE_COLOR_MAKEFILE ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_BUILD_TYPE_SHARED_LIBS ON)
set(CMAKE_C_FLAGS $ENV{CFLAGS})
set(CMAKE_CXX_FLAGS $ENV{CXXFLAGS})
set(CMAKE_LINK_FLAGS $ENV{LDFLAGS})
ADD_CUSTOM_TARGET(uninstall
"${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
# include macros
include(MacroConfigureFile)
# Source and build dirs
set(SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR})
# uninstall
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY )
add_custom_target( uninstall
"${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" )
# Project name - wmfs
set(PROJECT_NAME wmfs)
set(VERSION "WMFS-201008")
project(${PROJECT_NAME} C)
# Definition of the wmfs source
set(wmfs_src
src/parse/parse.c
src/barwin.c
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/systray.c
src/tag.c
src/util.c
src/viwmfs.c
src/wmfs.c)
find_package(PkgConfig REQUIRED)
# required packages
pkg_check_modules(FREETYPE REQUIRED freetype2)
pkg_check_modules(X11 REQUIRED x11)
pkg_check_modules(XFT REQUIRED xft)
# Set the executable from the wmfs_src
add_executable(wmfs ${wmfs_src})
# Set the version
set(VERSION "WMFS-201006")
# 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
)
${FREETYPE_INCLUDE_DIRS}
${X11_INCLUDE_DIRS}
${XFT_INCLUDE_DIRS}
)
# 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)
set(CMAKE_LINK_LIBRARIES
${FREETYPE_LIBRARIES}
${X11_LIBRARIES}
${XFT_LIBRARIES}
-lpthread
)
find_package(X11)
if(X11_FOUND)
include_directories(${X11_INCLUDE_DIR})
else (X11_FOUND)
message(FATAL_ERROR "Could not find X11")
endif (X11_FOUND)
# options
option(BUILD_DOC "Generate documentation using doxygen" OFF)
option(WITH_XINERAMA "Build with Xinerama support" ON)
option(WITH_XRANDR "Build with Xrandr support" ON)
option(WITH_IMLIB2 "Build with Imlib2 support" ON)
# Link Libraries
set(LIBRARIES_TO_LINK
${FREETYPE_LIBRARIES}
${X11_LIBRARIES}
Xft)
# optional finders
if(WITH_XINERAMA)
add_definitions(-DHAVE_XINERAMA)
pkg_check_modules(XINERAMA REQUIRED xinerama)
include_directories(${XINERAMA_INCLUDE_DIRS})
set(CMAKE_LINK_LIBRARIES ${XINERAMA_LIBRARIES} ${CMAKE_LINK_LIBRARIES})
else(WITH_XINERAMA)
message(STATUS "Not building with Xinerama support")
endif(WITH_XINERAMA)
# Includes
include(FindDoxygen)
include(FindPkgConfig)
if(WITH_XRANDR)
add_definitions(-DHAVE_XRANDR)
pkg_check_modules(XRANDR REQUIRED xrandr)
include_directories(${XRANDR_INCLUDE_DIRS})
set(CMAKE_LINK_LIBRARIES ${XRANDR_LIBRARIES} ${CMAKE_LINK_LIBRARIES})
else(WITH_XRANDR)
message(STATUS "Not building with Xrandr support")
endif(WITH_XRANDR)
# Use pkgconfig to get required libraries
pkg_check_modules(WMFS_REQUIRED REQUIRED
x11
freetype2
xft)
if(WITH_IMLIB2)
add_definitions(-DHAVE_IMLIB)
pkg_check_modules(IMLIB2 REQUIRED imlib2)
include_directories(${IMLIB2_INCLUDE_DIRS})
set(CMAKE_LINK_LIBRARIES ${IMLIB2_LIBRARIES} ${CMAKE_LINK_LIBRARIES})
else(WITH_IMLIB2)
message(STATUS "Not building with Imlib2 support")
endif(WITH_IMLIB2)
# Optional dependencies check
set(CMAKE_SYSCONFDIR ${CMAKE_INSTALL_PREFIX}/etc/ CACHE PATH "Config directory")
set(CMAKE_XDGCONFDIR ${CMAKE_SYSCONFDIR}/xdg/ CACHE PATH "XDG config directory")
set(CMAKE_DATADIR ${CMAKE_INSTALL_PREFIX}/share/ CACHE PATH "Data directory")
set(CMAKE_DOCDIR ${CMAKE_INSTALL_PREFIX}/share/doc/${PROJECT_NAME}-${VERSION} CACHE PATH "Data directory")
# Check for xinerama
pkg_check_modules(HAVE_XINERAMA xinerama)
if(HAVE_XINERAMA_FOUND)
set(WMFS_HAVE_XINERAMA "#define HAVE_XINERAMA")
set(LIBRARIES_TO_LINK ${LIBRARIES_TO_LINK} Xinerama)
else()
set(WMFS_HAVE_XINERAMA "")
endif()
# set default terminal for user
set(WMFS_TERM xterm)
# get the user compiling this thing
SET(USERNAME $ENV{USER})
# Check for xrandr
pkg_check_modules(HAVE_XRANDR xrandr)
if(HAVE_XRANDR_FOUND)
set(WMFS_HAVE_XRANDR "#define HAVE_XRANDR")
set(LIBRARIES_TO_LINK ${LIBRARIES_TO_LINK} Xrandr)
else()
set(WMFS_HAVE_XRANDR "")
endif()
# Check for Imlib
pkg_check_modules(HAVE_IMLIB imlib2)
if(HAVE_IMLIB_FOUND)
set(WMFS_HAVE_IMLIB "#define HAVE_IMLIB")
set(LIBRARIES_TO_LINK ${LIBRARIES_TO_LINK} Imlib2)
else()
set(WMFS_HAVE_IMLIB "")
endif()
target_link_libraries(wmfs ${LIBRARIES_TO_LINK})
# Messages
message("Project version: ${VERSION}")
message("Using these CFLAGS: ${CMAKE_C_FLAGS}")
message("Using these LDFLAGS: ${LDFLAGS}")
message("Linking with theses libraries : ${LIBRARIES_TO_LINK}")
# Generating man page
find_program(GZIP_EXECUTABLE gzip)
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
find_program(GIT_EXECUTABLE git)
if(EXISTS ${SOURCE_DIR}/.git/HEAD AND GIT_EXECUTABLE)
message(STATUS "Looking for git -- ${GIT_EXECUTABLE}")
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
# {{{ Install path and configuration variables
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
#of the default configuration dir.
if(DEFINED SYSCONFDIR)
set(SYSCONFDIR ${SYSCONFDIR} CACHE PATH "config directory")
else()
set(SYSCONFDIR /etc CACHE PATH "config directory")
endif()
#If an XDG Config Dir is specificed, use it instead
#of the default XDG configuration dir.
if(DEFINED 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
if(DEFINED WMFS_XSESSION_PATH)
set(WMFS_XSESSION_PATH ${WMFS_XSESSION_PATH} CACHE PATH "wmfs xsessions directory")
else()
set(WMFS_XSESSION_PATH ${PREFIX}/share/xsessions CACHE PATH "wmfs xsessions directory")
endif()
if(DEFINED WMFS_MAN_PATH)
set(WMFS_MAN_PATH ${WMFS_MAN_PATH} CACHE PATH "wmfs manpage directory")
else()
set(WMFS_MAN_PATH ${PREFIX}/share/man CACHE PATH "wmfs manpage directory")
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
# configure files
set(CONFIGURE_FILES
src/config.h.in
wmfs.doxygen.in
wmfsrc.in)
foreach(file ${CONFIGURE_FILES})
ConfigureFile(${file})
endforeach(file)
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()
# add the source directory
add_subdirectory(src)
foreach(file ${wmfs_configure_files})
a_configure_file(${file})
endforeach()
# documentation
if(BUILD_DOC)
find_package(Doxygen REQUIRED)
if(DOXYGEN_FOUND)
add_custom_target(doc
COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/wmfs.doxygen
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
else(DOXYGEN_FOUND)
MESSAGE(FATAL_ERROR "Doxygen executable not found")
endif(DOXYGEN_FOUND)
endif(BUILD_DOC)
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)
# Generating ChangeLog only for live version, for release we generate it to tarball
if(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/ChangeLog)
find_program(GIT_EXECUTABLE git)
if(EXISTS ${CMAKE_SOURCE_DIR}/.git/HEAD AND GIT_EXECUTABLE)
message(STATUS "<<< Generating ChangeLog... >>>")
execute_process(
COMMAND ${GIT_EXECUTABLE} log
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
OUTPUT_FILE ${CMAKE_CURRENT_BINARY_DIR}/ChangeLog)
else(EXISTS ${CMAKE_SOURCE_DIR}/.git/HEAD AND GIT_EXECUTABLE)
message(STATUS "No ChangeLog present and git not found")
message(STATUS "<<< Will not generate ChangeLog >>>")
endif(EXISTS ${CMAKE_SOURCE_DIR}/.git/HEAD AND GIT_EXECUTABLE)
endif(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/ChangeLog)
# installs
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)
# manpage (compression handled by system not by us)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/wmfs.1 DESTINATION ${CMAKE_DATADIR}/man/man1)
if(WMFS_MAN1_FILES)
install(FILES ${WMFS_MAN1_FILES} DESTINATION ${WMFS_MAN_PATH}/man1)
endif()
# install docs
# changelog || can have 2 locations based on whether we generate it or not
if(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/ChangeLog)
set(WMFS_DOCS ${CMAKE_CURRENT_BINARY_DIR}/ChangeLog ${WMFS_DOCS})
endif(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/ChangeLog)
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/ChangeLog)
set(WMFS_DOCS ${CMAKE_CURRENT_SOURCE_DIR}/ChangeLog ${WMFS_DOCS})
endif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/ChangeLog)
set(WMFS_DOCS
${CMAKE_CURRENT_SOURCE_DIR}/TODO
${CMAKE_CURRENT_SOURCE_DIR}/README
${WMFS_DOCS}
)
install(FILES ${WMFS_DOCS} DESTINATION ${CMAKE_DOCDIR})
if(PROJECT_CHANGELOG)
install(FILES ${PROJECT_CHANGELOG} DESTINATION ${PROJECT_DATA_PATH})
endif()
# config file
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/wmfsrc DESTINATION ${CMAKE_XDGCONFDIR}/${PROJECT_NAME})
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})
# xsession
install(FILES "wmfs.desktop" DESTINATION ${CMAKE_DATADIR}/xsessions)
# Status messages
message(STATUS "<<< ${PROJECT_NAME} ${VERSION} configuration >>>
Build type ${CMAKE_BUILD_TYPE}
Install path ${CMAKE_INSTALL_PREFIX}
Compiler flags:
C ${CMAKE_C_FLAGS}
C++ ${CMAKE_CXX_FLAGS}
Linker flags:
Executable ${CMAKE_EXE_LINKER_FLAGS}
Module ${CMAKE_MODULE_LINKER_FLAGS}
Shared ${CMAKE_SHARED_LINKER_FLAGS}\n")

21
cmake/cmake_uninstall.cmake.in Executable file
View File

@ -0,0 +1,21 @@
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)

View File

@ -0,0 +1,8 @@
macro(ConfigureFile file)
string(REGEX REPLACE ".in\$" "" outfile ${file})
message(STATUS "<<< Configuring ${outfile} >>>")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${file}
${CMAKE_CURRENT_BINARY_DIR}/${outfile}
ESCAPE_QUOTE
@ONLY)
endmacro(ConfigureFile)

View File

@ -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)

35
src/CMakeLists.txt Normal file
View File

@ -0,0 +1,35 @@
# -*- mode: cmake -*-
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/parse)
SET(WMFS_SOURCES
parse/parse.c
parse/api.c
barwin.c
client.c
config.c
draw.c
event.c
ewmh.c
frame.c
getinfo.c
infobar.c
init.c
launcher.c
layout.c
menu.c
mouse.c
screen.c
status.c
systray.c
tag.c
util.c
viwmfs.c
wmfs.c
)
add_executable(${PROJECT_NAME} ${WMFS_SOURCES})
target_link_libraries(${PROJECT_NAME} ${CMAKE_LINK_LIBRARIES})
INSTALL ( TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib${LIB_SUFFIX} )

View File

@ -123,6 +123,26 @@ barwin_draw_text(BarWindow *bw, int x, int y, char *text)
return;
}
/** Draw text in a Barwindow
*/
void
barwin_draw_image_ofset_text(BarWindow *bw, int x, int y, char *text, int x_image_ofset, int y_image_ofset)
{
if(!text)
return;
/* Background color of the text if there is stipple */
if(bw->stipple)
draw_rectangle(bw->dr, x - 4, 0, textw(text) + 8, bw->geo.height, bw->bg);
/* Draw text */
draw_image_ofset_text(bw->dr, x, y, bw->fg, 0, text, x_image_ofset, y_image_ofset);
barwin_refresh(bw);
return;
}
/** Delete a BarWindow
* \param bw BarWindow pointer
*/

View File

@ -93,6 +93,8 @@ client_get_next(void)
{
Client *c = NULL;
screen_get_sel();
if(!sel || ishide(sel, selscreen))
return NULL;
@ -112,6 +114,8 @@ client_get_prev(void)
{
Client *c = NULL, *d;
screen_get_sel();
if(!sel || ishide(sel, selscreen))
return NULL;
@ -987,7 +991,11 @@ void
client_set_rules(Client *c)
{
XClassHint xch = { 0 };
int i, j, k;
int i, j, k, f;
Atom rf;
ulong n, il;
uchar *data = NULL;
char wwrole[256] = { 0 };
if(conf.ignore_next_client_rules)
{
@ -995,8 +1003,19 @@ client_set_rules(Client *c)
return;
}
/* Get WM_CLASS */
XGetClassHint(dpy, c->win, &xch);
/* Get WM_WINDOW_ROLE */
if(XGetWindowProperty(dpy, c->win, ATOM("WM_WINDOW_ROLE"), 0L, 0x7FFFFFFFL, False,
XA_STRING, &rf, &f, &n, &il, &data) == Success && data)
{
strcpy(wwrole, (char*)data);
XFree(data);
}
/* Following features is *DEPRECATED*, will be removed in some revision. {{{ */
/* Auto free */
if(conf.client.autofree && ((xch.res_name && strstr(conf.client.autofree, xch.res_name))
|| (xch.res_class && strstr(conf.client.autofree, xch.res_class))))
@ -1030,6 +1049,42 @@ client_set_rules(Client *c)
tags[c->screen][c->tag].layout.func(c->screen);
}
/* }}} */
/* Apply Rule if class || instance || role match */
for(i = 0; i < conf.nrule; ++i)
{
if((xch.res_class && conf.rule[i].class && !strcmp(xch.res_class, conf.rule[i].class))
|| (xch.res_name && conf.rule[i].instance && !strcmp(xch.res_name, conf.rule[i].instance)))
{
if((strlen(wwrole) && conf.rule[i].role && !strcmp(wwrole, conf.rule[i].role)) || (!strlen(wwrole) || !conf.rule[i].role))
{
if(conf.rule[i].screen != -1)
c->screen = conf.rule[i].screen;
if(conf.rule[i].tag != -1)
c->tag = conf.rule[i].tag;
if(conf.rule[i].free)
c->flags |= FreeFlag;
if(conf.rule[i].max)
{
client_maximize(c);
c->flags |= MaxFlag;
}
if(c->tag != seltag[selscreen])
{
tags[c->screen][c->tag].request_update = True;
client_focus(NULL);
}
tags[c->screen][c->tag].layout.func(c->screen);
}
}
}
return;
}
@ -1342,13 +1397,17 @@ uicb_clientlist(uicb_t cmd)
{
int i, d, u, x, y;
int n = 0;
Bool all = False;
Window w;
Client *c = NULL;
screen_get_sel();
if(cmd && !strcmp(cmd, "all"))
all = True;
for(c = clients; c; c = c->next)
if(!ishide(c, selscreen))
if(!ishide(c, selscreen) || all)
++n;
if(n > 0)
@ -1363,8 +1422,10 @@ uicb_clientlist(uicb_t cmd)
conf.colors.bar,
conf.colors.text);
clientlist.align = MA_Left;
for(i = 0, c = clients; c; c = c->next)
if(!ishide(c, selscreen))
if(!ishide(c, selscreen) || all)
{
sprintf(clist_index[i].key, "%d", i);
clist_index[i].client = c;
@ -1401,6 +1462,12 @@ uicb_client_select(uicb_t cmd)
for(i = 0; i < MAXCLIST && clist_index[i].client; ++i)
if(!strcmp(cmd, clist_index[i].key))
{
if(clist_index[i].client->screen != selscreen)
screen_set_sel(clist_index[i].client->screen);
if(clist_index[i].client->tag != seltag[clist_index[i].client->screen])
tag_set(clist_index[i].client->tag);
client_focus(clist_index[i].client);
client_raise(clist_index[i].client);

View File

@ -181,7 +181,8 @@ void
conf_bar_section(void)
{
struct conf_sec *bar, **mouse, *selbar, *systray;
char *barbg, sc = screen_count();
char *barbg;
int sc = screen_count();
bar = fetch_section_first(NULL, "bar");
@ -219,7 +220,7 @@ conf_bar_section(void)
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.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");
@ -230,7 +231,6 @@ conf_bar_section(void)
}
free(mouse);
free(barbg);
return;
}
@ -393,6 +393,7 @@ conf_layout_section(void)
layouts = fetch_section_first(NULL, "layouts");
conf.layout_button_width = fetch_opt_first(layouts, "O", "layout_button_width").num;
conf.border.layout = fetch_opt_first(layouts, "false", "border").bool;
conf.colors.layout_fg = fetch_opt_first(layouts, "#ffffff", "fg").str;
conf.colors.layout_bg = getcolor((fetch_opt_first(layouts, "#000000", "bg").str));
@ -605,6 +606,36 @@ conf_tag_section(void)
return;
}
void
conf_rule_section(void)
{
int i;
struct conf_sec *rules, **rule;
rules = fetch_section_first(NULL, "rules");
rule = fetch_section(rules, "rule");
CHECK((conf.nrule = fetch_section_count(rule)));
conf.rule = emalloc(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").bool;
conf.rule[i].max = fetch_opt_first(rule[i], "false", "max").bool;
}
free(rule);
return;
}
void
conf_menu_section(void)
{
@ -618,7 +649,7 @@ conf_menu_section(void)
CHECK((conf.nmenu = fetch_section_count(set_menu)));
conf.menu = calloc(conf.nmenu, sizeof(Menu));
conf.menu = emalloc(conf.nmenu, sizeof(Menu));
for(i = 0; i < conf.nmenu; ++i)
{
@ -756,6 +787,7 @@ init_conf(void)
conf_client_section();
conf_layout_section();
conf_tag_section();
conf_rule_section();
conf_menu_section();
conf_launcher_section();
conf_keybind_section();

View File

@ -35,16 +35,11 @@
#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@
#define WMFS_VERSION "@VERSION@"
#define WMFS_COMPILE_MACHINE "@CMAKE_SYSTEM_PROCESSOR@"
#define WMFS_COMPILE_BY "@USERNAME@"
#define WMFS_COMPILE_FLAGS "@CMAKE_C_FLAGS@"
#define WMFS_LINKED_LIBS "@CMAKE_LINK_LIBRARIES@"
#define XDG_CONFIG_DIR "@CMAKE_XDGCONFDIR@"
#endif /* CONFIG_H */

View File

@ -32,6 +32,12 @@
#include "wmfs.h"
void
draw_text(Drawable d, int x, int y, char* fg, int pad, char *str)
{
draw_image_ofset_text(d, x, y, fg, pad, str, 0, 0);
}
/** Draw a string in a Drawable
* \param d Drawable
* \param x X position
@ -41,7 +47,7 @@
* \param str String that will be draw
*/
void
draw_text(Drawable d, int x, int y, char* fg, int pad, char *str)
draw_image_ofset_text(Drawable d, int x, int y, char* fg, int pad, char *str, int x_image_ofset, int y_image_ofset)
{
XftColor xftcolor;
XftDraw *xftd;
@ -65,7 +71,7 @@ draw_text(Drawable d, int x, int y, char* fg, int pad, char *str)
sw = systray_get_width();
for(i = 0; i < ni; ++i)
draw_image(d, im[i].x - sw, im[i].y, im[i].w, im[i].h, im[i].name);
draw_image(d, x_image_ofset + im[i].x - sw, y_image_ofset + im[i].y, im[i].w, im[i].h, im[i].name);
}
#endif /* HAVE_IMLIB */

View File

@ -65,7 +65,10 @@ buttonpress(XButtonEvent *ev)
for(i = 0; i < conf.titlebar.button[n].nmouse; ++i)
if(ev->button == conf.titlebar.button[n].mouse[i].button)
if(conf.titlebar.button[n].mouse[i].func)
{
client_focus(c);
conf.titlebar.button[n].mouse[i].func(conf.titlebar.button[n].mouse[i].cmd);
}
/* Frame Resize Area */
if((c = client_gb_resize(ev->window)))

View File

@ -95,7 +95,7 @@ infobar_init(void)
/* Create layout switch barwindow */
infobar[sc].layout_button = barwin_create(infobar[sc].bar->win,
((conf.layout_placement) ? 0 : (j + PAD / 2)), 0,
textw(tags[sc][seltag[sc]].layout.symbol) + PAD,
((conf.layout_button_width > 0) ? conf.layout_button_width : (textw(tags[sc][seltag[sc]].layout.symbol) + PAD)),
infobar[sc].geo.height,
conf.colors.layout_bg, conf.colors.layout_fg,
False, False, conf.border.layout);
@ -159,7 +159,7 @@ infobar_draw_layout(int sc)
if(!conf.layout_placement)
barwin_move(infobar[sc].layout_button, infobar[sc].tags_board->geo.width + PAD / 2, 0);
barwin_resize(infobar[sc].layout_button, textw(tags[sc][seltag[sc]].layout.symbol) + PAD, infobar[sc].geo.height);
barwin_resize(infobar[sc].layout_button, ((conf.layout_button_width > 0) ? conf.layout_button_width : (textw(tags[sc][seltag[sc]].layout.symbol) + PAD)), infobar[sc].geo.height);
barwin_refresh_color(infobar[sc].layout_button);
if(tags[sc][seltag[sc]].layout.symbol)
@ -188,12 +188,12 @@ infobar_draw_selbar(int sc)
else if(sel && !infobar[sc].selbar->mapped)
barwin_map(infobar[sc].selbar);
if(conf.selbar.maxlenght >= 0 && sel)
if(conf.selbar.maxlength >= 0 && sel)
{
str = emalloc(conf.selbar.maxlenght + 4, sizeof(char));
strncpy(str, sel->title, conf.selbar.maxlenght);
str = emalloc(conf.selbar.maxlength + 4, sizeof(char));
strncpy(str, sel->title, conf.selbar.maxlength);
if(strlen(sel->title) > conf.selbar.maxlenght)
if(strlen(sel->title) > conf.selbar.maxlength)
strcat(str, "...");
}
@ -225,7 +225,7 @@ infobar_draw_taglist(int sc)
Bool is_occupied[MAXTAG + 1];
if(conf.layout_placement)
barwin_move(infobar[sc].tags_board, textw(tags[sc][seltag[sc]].layout.symbol) + PAD * 1.5, 0);
barwin_move(infobar[sc].tags_board, ((conf.layout_button_width > 0) ? conf.layout_button_width : (textw(tags[sc][seltag[sc]].layout.symbol) + PAD)) + PAD / 2, 0);
for(i = 0; i < MAXTAG; i++)
is_occupied[i] = False;

View File

@ -30,14 +30,8 @@
* 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"
static char *complete_on_command(char*, size_t);
static char *complete_on_files(char*, size_t);
@ -61,7 +55,7 @@ launcher_execute(Launcher *launcher)
x = (conf.layout_placement)
? (infobar[selscreen].tags_board->geo.x + infobar[selscreen].tags_board->geo.width)
: (infobar[selscreen].layout_button->geo.x + textw(tags[selscreen][seltag[selscreen]].layout.symbol) + PAD);
: (infobar[selscreen].layout_button->geo.x + infobar[selscreen].layout_button->geo.width);
XGrabKeyboard(dpy, ROOT, True, GrabModeAsync, GrabModeAsync, CurrentTime);
@ -256,7 +250,10 @@ complete_on_command(char *start, size_t hits)
char *ret = NULL;
DIR *dir;
struct dirent *content;
size_t count = 0;
char **namelist = NULL;
int n = 0, i;
void *temp = NULL;
if (!getenv("PATH") || !start || hits <= 0)
return NULL;
@ -265,27 +262,40 @@ complete_on_command(char *start, size_t hits)
dirname = strtok(path, ":");
/* recursively open PATH */
while (dirname)
while (dirname != NULL)
{
if ((dir = opendir(dirname)))
{
while ((content = readdir(dir)))
if (!strncmp(content->d_name, start, strlen(start)) && ++count == hits)
{
if(strncmp(content->d_name, ".", 1))
{
ret = _strdup(content->d_name + strlen(start));
break;
if (!strncmp(content->d_name, start, strlen(start)))
{
temp = realloc(namelist, ++n * sizeof(*namelist));
if ( temp != NULL )
namelist = temp;
namelist[n-1] = strdup(content->d_name);
}
}
}
closedir(dir);
}
if (ret)
break;
dirname = strtok(NULL, ":");
}
qsort(namelist, n, sizeof(char *), qsort_string_compare);
free(path);
if(n > 0)
{
ret = _strdup(namelist[((hits > 0) ? hits - 1 : 0) % n] + strlen(start));
for(i = 0; i < n; i++)
free(namelist[i]);
}
free(namelist);
return ret;
}
@ -319,7 +329,7 @@ complete_on_files(char *start, size_t hits)
{
/* remplace ~ by $HOME in dirname */
if (!strncmp(p, "~/", 2) && getenv("HOME"))
asprintf(&dirname, "%s%s", getenv("HOME"), p+1);
xasprintf(&dirname, "%s%s", getenv("HOME"), p+1);
else
dirname = _strdup(p);
@ -350,12 +360,12 @@ complete_on_files(char *start, size_t hits)
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);
xasprintf(&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));
xasprintf(&ret, "%s/", content->d_name + strlen(p));
else
ret = _strdup(content->d_name + strlen(p));
}

View File

@ -68,7 +68,11 @@ menu_draw(Menu menu, int x, int y)
BarWindow *item[menu.nitem];
BarWindow *frame;
width = menu_get_longer_string(menu.item, menu.nitem) + PAD * 3;
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 */
@ -99,7 +103,7 @@ menu_draw(Menu menu, int x, int y)
barwin_map(item[i]);
barwin_refresh_color(item[i]);
menu_draw_item_name(&menu, i, item);
menu_draw_item_name(&menu, i, item, chcklen);
barwin_refresh(item[i]);
}
@ -209,6 +213,9 @@ 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)
{
@ -216,7 +223,7 @@ menu_activate_item(Menu *menu, int i)
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;
x = menu->x + menu_get_longer_string(menu->item, menu->nitem) + chcklen + textw(">") + PAD * 3;
menu_draw(conf.menu[j], x, y);
@ -238,6 +245,10 @@ menu_focus_item(Menu *menu, int item, BarWindow *winitem[])
{
int i;
int chcklen = 0;
if(menu_get_checkstring_needed(menu->item, menu->nitem))
chcklen = textw(conf.selected_layout_symbol) + PAD / 3;
menu->focus_item = item;
if(menu->focus_item > menu->nitem - 1)
@ -251,7 +262,7 @@ menu_focus_item(Menu *menu, int item, BarWindow *winitem[])
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);
menu_draw_item_name(menu, i, winitem, chcklen);
barwin_refresh(winitem[i]);
}
@ -259,29 +270,29 @@ menu_focus_item(Menu *menu, int item, BarWindow *winitem[])
}
void
menu_draw_item_name(Menu *menu, int item, BarWindow *winitem[])
menu_draw_item_name(Menu *menu, int item, BarWindow *winitem[], int chcklen)
{
int x;
int width = menu_get_longer_string(menu->item, menu->nitem);
int width = menu_get_longer_string(menu->item, menu->nitem) + chcklen + PAD / 3;
switch(menu->align)
{
case MA_Left:
x = PAD * 3 / 2;
x = chcklen + PAD / 2;
break;
case MA_Right:
x = width - textw(menu->item[item].name) + PAD * 3 / 2;
break;
default:
case MA_Center:
x = width / 2 - textw(menu->item[item].name) / 2 + PAD * 3 / 2;
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_draw_image_ofset_text(winitem[item], x, FHINFOBAR, menu->item[item].name, chcklen + PAD / 2, 0);
if(menu->item[item].check)
if(menu->item[item].check(menu->item[item].cmd))
barwin_draw_text(winitem[item], PAD / 3, FHINFOBAR, conf.selected_layout_symbol);
barwin_draw_image_ofset_text(winitem[item], PAD / 3, FHINFOBAR, conf.selected_layout_symbol, PAD / 3, 0);
if(menu->item[item].submenu)
barwin_draw_text(winitem[item], width + PAD * 2, FHINFOBAR, ">");
@ -340,3 +351,9 @@ menu_clear(Menu *menu)
return;
}
Bool
menu_get_checkstring_needed(MenuItem *mi, int nitem)
{
return True;
}

195
src/parse/api.c Normal file
View File

@ -0,0 +1,195 @@
/*
* 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 <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.bool = True;
else
ret.bool = 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;
}

File diff suppressed because it is too large Load Diff

View File

@ -19,12 +19,22 @@
#include <sys/queue.h>
#define INCLUDE_CMD "@include"
#define PARSE_MAX_LIST 10
#if defined(Bool)
#define bool_t Bool
#else
typedef enum { False, True } bool_t;
#endif /* Bool */
struct conf_opt {
char *name;
char *val[10];
char *val[PARSE_MAX_LIST];
size_t nval;
Bool used;
bool_t used;
int line;
char *filename;
SLIST_ENTRY(conf_opt) entry;
};
@ -40,7 +50,7 @@ struct conf_sec {
struct opt_type {
long int num;
float fnum;
Bool bool;
bool_t bool;
char *str;
};
@ -61,7 +71,7 @@ void print_unused(struct conf_sec *s);
* WARNING: This make all string
* 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
@ -107,4 +117,10 @@ struct opt_type *fetch_opt(struct conf_sec *, char *, char *);
*/
size_t fetch_opt_count(struct opt_type *);
/* wrapper for calloc */
void *xcalloc(size_t, size_t);
/* wrapper for asprintf */
int xasprintf(char **, const char *, ...);
#endif /* PARSE_H */

View File

@ -352,6 +352,18 @@ typedef struct
char *content;
} Alias;
/* Rule struct */
typedef struct
{
char *class;
char *instance;
char *role;
int screen;
int tag;
Bool free;
Bool max;
} Rule;
/* Configuration structure */
typedef struct
{
@ -402,7 +414,7 @@ typedef struct
{
char *fg;
uint bg;
int maxlenght;
int maxlength;
MouseBinding *mouse;
int nmouse;
} selbar;
@ -457,9 +469,11 @@ typedef struct
} systray;
Alias alias[256];
uint mouse_tag_action[TagActionLast];
int layout_button_width;
Layout layout[NUM_OF_LAYOUT];
Menu *menu;
Launcher *launcher;
Rule *rule;
int *ntag;
Bool tag_round;
Bool client_round;
@ -472,6 +486,7 @@ typedef struct
int nlayout;
int nmenu;
int nlauncher;
int nrule;
} Conf;
typedef struct

View File

@ -241,7 +241,10 @@ spawn(const char *format, ...)
execl(sh, sh, "-c", cmd, (char*)NULL);
exit(EXIT_FAILURE);
}
write(p[1], &pid, sizeof(pid_t));
if (sizeof(pid_t) != write(p[1], &pid, sizeof(pid_t)))
warn("write");
close(p[1]);
exit(EXIT_SUCCESS);
}
@ -356,3 +359,10 @@ patht(char *path)
return ret;
}
int
qsort_string_compare (const void * a, const void * b)
{
return (strcmp(*(char **)a, *(char **)b));
}

View File

@ -118,6 +118,7 @@ quit(void)
}
IFREE(conf.launcher);
IFREE(conf.rule);
IFREE(conf.bars.mouse);
IFREE(conf.selbar.mouse);
@ -125,7 +126,7 @@ quit(void)
IFREE(conf.client.mouse);
IFREE(conf.root.mouse);
free_conf(NULL);
free_conf();
XSync(dpy, False);
XCloseDisplay(dpy);

View File

@ -34,7 +34,7 @@
#define WMFS_H
#define _BSD_SOURCE /* vsnprintf */
#define _POSIX_SOURCE /* kill */
/* Lib headers */
#include <stdio.h>
#include <stdlib.h>
@ -122,6 +122,7 @@ BarWindow *barwin_create(Window parent,
Bool stipple,
Bool border);
void barwin_draw_text(BarWindow *bw, int x, int y, char *text);
void barwin_draw_image_ofset_text(BarWindow *bw, int x, int y, char *text, int x_image_ofset, int y_image_ofset);
void barwin_delete(BarWindow *bw);
void barwin_delete_subwin(BarWindow *bw);
void barwin_map(BarWindow *bw);
@ -135,6 +136,7 @@ void barwin_refresh(BarWindow *bw);
/* draw.c */
void draw_text(Drawable d, int x, int y, char* fg, int pad, char *str);
void draw_image_ofset_text(Drawable d, int x, int y, char* fg, int pad, char *str, int x_image_ofset, int y_image_ofset);
void draw_rectangle(Drawable dr, int x, int y, uint w, uint h, uint color);
void draw_graph(Drawable dr, int x, int y, uint w, uint h, uint color, char *data);
@ -258,10 +260,11 @@ 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[]);
void menu_draw_item_name(Menu *menu, int item, BarWindow *winitem[], int chcklen);
int menu_get_longer_string(MenuItem *mi, int nitem);
void uicb_menu(uicb_t cmd);
void menu_clear(Menu *menu);
Bool menu_get_checkstring_needed(MenuItem *mi, int nitem);
/* launcher.c */
void launcher_execute(Launcher *launcher);
@ -297,7 +300,7 @@ void swap_ptr(void **x, void **y);
void uicb_spawn(uicb_t);
char *clean_value(char *str);
char* patht(char *path);
int qsort_string_compare (const void * a, const void * b);
#ifdef HAVE_IMLIB
int parse_image_block(ImageAttr *im, char *str);

View File

@ -73,7 +73,7 @@ WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = @SOURCE_DIR@/src
INPUT = @CMAKE_CURRENT_SOURCE_DIR@/src
INPUT_ENCODING = UTF-8
FILE_PATTERNS = *.c \
*.h \

View File

@ -3,6 +3,9 @@
# ~/.config/wmfs/wmfsrc and edit it.
#
# Include file to split configuration
# @include "~/.config/wmfs/menu-wmfsrc"
[misc]
font = "dejavu-10"
raisefocus = false
@ -36,8 +39,8 @@
bg = "#191919"
fg = "#D4D4ff"
# Cut title lenght
# max_lenght = 25
# Cut title length
# max_length = 25
[mouse] button = "3" func = "clientlist" [/mouse]
[mouse] button = "4" func = "client_next" [/mouse]
@ -65,6 +68,9 @@
# Symbol displayed for the selected layout in the list
selected_layout_symbol = "*"
# Width of layout button
# layout_button_width = x
# Tiling layouts.
[layout] type = "tile_right" symbol = "RIGHT" [/layout]
[layout] type = "tile_left" symbol = "LEFT" [/layout]
@ -127,6 +133,7 @@
#[mouse] [/mouse] Possible multi mouse section
[/tag]
# clients option is *DEPRECATED* but works, see [rules] section
[tag] name = "two" clients = {"Browser"} [/tag]
[tag] name = "three" [/tag]
[tag] name = "four" [/tag]
@ -161,6 +168,7 @@
# Modifier for mouse use
modifier = "Alt"
# *DEPRECATED* but works, see [rules] section
# Set automatic free or max client
# autofree = "xterm|MPlayer"
# automax = "Navigator"
@ -195,6 +203,19 @@
[/titlebar]
[/client]
[rules]
# Example of rule for Mplayer
[rule]
instance = "xv" # First part of WM_CLASS
class = "MPlayer" # Seconf part of WM_CLASS, not needed if first part is correct
# role = "" # WM_WINDOW_ROLE
screen = 0 # Screen to use
tag = 2 # Tag number of apps
free = true # Set automatic free client
max = false # Set automatic maximized client
[/rule]
[/rules]
[menu]
# Default menu, binded on the root window, button 3.
[set_menu]