diff --git a/CMakeLists.txt b/CMakeLists.txt index ebf1c81..3ddc626 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,7 +54,7 @@ add_executable(wmfs ${wmfs_src}) set(VERSION "WMFS-200912") # FLAGS -set(CFLAGS "-g -Wall -ansi") +set(CFLAGS "-g -Wall -lpthread -ansi") set(CMAKE_C_FLAGS ${CFLAGS}) # Linker FLAGS diff --git a/rc/status.sh b/rc/status.sh index 6f885ed..bd07953 100755 --- a/rc/status.sh +++ b/rc/status.sh @@ -1,20 +1,13 @@ #!/bin/sh -# Print - -TIMING=1 -RET=0 +#WMFS status.sh example file +#Will be executed if put in ~/.config/wmfs/ +#Timing adjustable in wmfsrc (misc -> status_timing) statustext() { local DATE=`date` wmfs -s "$DATE" - - RET=$? } -while [[ $RET == "0" ]]; -do - statustext - sleep $TIMING -done +statustext diff --git a/src/config.c b/src/config.c index 2a1bcba..d59b6fe 100644 --- a/src/config.c +++ b/src/config.c @@ -136,11 +136,12 @@ conf_misc_section(char *src) cfg_set_sauv(src); - conf.font = get_opt(src, "sans-9", "font").str; - conf.raisefocus = get_opt(src, "false", "raisefocus").bool; - conf.raiseswitch = get_opt(src, "false", "raiseswitch").bool; - conf.focus_fmouse = get_opt(src, "true", "focus_follow_mouse").bool; - pad = get_opt(src, "12", "pad").num; + conf.font = get_opt(src, "sans-9", "font").str; + conf.raisefocus = get_opt(src, "false", "raisefocus").bool; + conf.raiseswitch = get_opt(src, "false", "raiseswitch").bool; + conf.focus_fmouse = get_opt(src, "true", "focus_follow_mouse").bool; + conf.status_timing = get_opt(src, "1", "status_timing").num; + pad = get_opt(src, "12", "pad").num; if(pad > 24 || pad < 1) { @@ -151,6 +152,12 @@ conf_misc_section(char *src) conf.pad = pad; + if(conf.status_timing <= 0) + { + warnx("configuration : status_timing value (%d) incorrect.", conf.status_timing); + conf.status_timing = 1; + } + return; } diff --git a/src/event.c b/src/event.c index f879e4b..ddc0566 100644 --- a/src/event.c +++ b/src/event.c @@ -231,6 +231,10 @@ clientmessageevent(XClientMessageEvent *ev) screen_get_sel(); } + if(mess_t == wmfs_update_status + && estatus) + spawn(status_path); + return; } diff --git a/src/ewmh.c b/src/ewmh.c index 00bcb5d..e4178ac 100644 --- a/src/ewmh.c +++ b/src/ewmh.c @@ -80,6 +80,7 @@ ewmh_init_hints(void) /* WMFS hints */ net_atom[wmfs_running] = ATOM("_WMFS_RUNNING"); net_atom[wmfs_update_hints] = ATOM("_WMFS_UPDATE_HINTS"); + net_atom[wmfs_update_status] = ATOM("_WMFS_UPDATE_STATUS"); net_atom[wmfs_set_screen] = ATOM("_WMFS_SET_SCREEN"); net_atom[wmfs_screen_count] = ATOM("_WMFS_SCREEN_COUNT"); net_atom[wmfs_current_tag] = ATOM("_WMFS_CURRENT_TAG"); diff --git a/src/init.c b/src/init.c index c62cd6a..ae58bb4 100644 --- a/src/init.c +++ b/src/init.c @@ -195,32 +195,33 @@ init_layout(void) void init_status(void) { - char *path; int fd; struct stat st; - path = emalloc(strlen(getenv("HOME")) + strlen(DEF_STATUS) + 2, sizeof(char)); + status_path = emalloc(strlen(getenv("HOME")) + strlen(DEF_STATUS) + 2, sizeof(char)); - sprintf(path, "%s/"DEF_STATUS, getenv("HOME")); + sprintf(status_path, "%s/"DEF_STATUS, getenv("HOME")); - if(!(fd = open(path, O_RDONLY))) + if(!(fd = open(status_path, O_RDONLY))) { - free(path); + free(status_path); return; } - stat(path, &st); + stat(status_path, &st); if(st.st_mode & S_IXUSR) - spawn(path); + { + estatus = True; + system(status_path); + } else - warnx("status.sh file present in wmfs directory can't be executed, try 'chmod +x %s'.", path); + warnx("status.sh file present in wmfs directory can't be executed, try 'chmod +x %s'.", + status_path); close(fd); - free(path); - return; } diff --git a/src/structs.h b/src/structs.h index 23db925..e5190f3 100644 --- a/src/structs.h +++ b/src/structs.h @@ -120,6 +120,7 @@ enum /* WMFS HINTS */ wmfs_running, wmfs_update_hints, + wmfs_update_status, wmfs_current_tag, wmfs_current_screen, wmfs_current_layout, @@ -321,6 +322,7 @@ typedef struct Bool raiseswitch; Bool focus_fmouse; uint pad; + int status_timing; struct { /* diff --git a/src/wmfs.c b/src/wmfs.c index 0a7f78e..1b768b6 100644 --- a/src/wmfs.c +++ b/src/wmfs.c @@ -136,15 +136,53 @@ quit(void) return; } +void * +thread_process(void *arg) +{ + XEvent ev; + + /* X event loop */ + if(!(int*)arg) + { + while(!exiting && !XNextEvent(dpy, &ev)) + getevent(ev); + + pthread_exit(0); + } + + /* Status checking loop with timing */ + else + { + while(!exiting) + { + spawn(status_path); + sleep(conf.status_timing); + } + + pthread_exit(0); + } +} + /** WMFS main loop. */ void mainloop(void) { XEvent ev; + pthread_t evloop, evstatus; + void *ret; - while(!exiting && !XNextEvent(dpy, &ev)) - getevent(ev); + if(!estatus) + while(!exiting && !XNextEvent(dpy, &ev)) + getevent(ev); + else + { + pthread_create(&evloop, NULL, thread_process, "1"); + pthread_create(&evstatus, NULL, thread_process, NULL); + + (void)pthread_join(evloop, &ret); + (void)pthread_join(evstatus, &ret); + } return; } @@ -347,6 +385,23 @@ set_statustext(int s, char *str) return; } +/** Update status script by ewmh hint + */ +void +update_status(void) +{ + long data[5]; + + if(!check_wmfs_running()) + return; + + data[4] = True; + + send_client_event(data, "_WMFS_UPDATE_STATUS"); + + return; +} + /** Signal handle function */ void @@ -368,12 +423,12 @@ int main(int argc, char **argv) { int i; - char *ol = "csgV"; + char *ol = "csgVS"; argv_global = _strdup(argv[0]); sprintf(conf.confpath, "%s/"DEF_CONF, getenv("HOME")); - while((i = getopt(argc, argv, "hvic:s:g:C:V:")) != -1) + while((i = getopt(argc, argv, "hviSc:s:g:C:V:")) != -1) { /* For options who need WMFS running */ @@ -384,12 +439,13 @@ main(int argc, char **argv) { case 'h': default: - printf("usage: %s [-ihv] [-C ] [-c ] [-g ] [-s ] [-V ] [-c ] [-g ] [-s ] [-V Load a configuration file\n" " -c Execute an uicb function to control WMFS\n" " -g Show information about wmfs status\n" " -s Set the bar(s) statustext\n" " -V Manage WMFS with vi-like command\n" + " -S Update status script\n" " -h Show this page\n" " -i Show informations\n" " -v Show WMFS version\n", argv[0]); @@ -410,6 +466,12 @@ main(int argc, char **argv) exit(EXIT_SUCCESS); break; + case 'S': + update_status(); + XCloseDisplay(dpy); + exit(EXIT_SUCCESS); + break; + case 'C': strcpy(conf.confpath, optarg); break; diff --git a/src/wmfs.h b/src/wmfs.h index 2db66b3..d3bbc35 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -334,11 +335,13 @@ void viwmfs(int argc, char **argv); int errorhandler(Display *d, XErrorEvent *event); int errorhandlerdummy(Display *d, XErrorEvent *event); void quit(void); +void *thread_process(void *arg); void mainloop(void); void scan(void); Bool check_wmfs_running(void); 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 uicb_quit(uicb_t); void uicb_reload(uicb_t); @@ -351,12 +354,13 @@ GC gc, gc_stipple; int selscreen; Conf conf; Key *keys; -Bool exiting; +Bool exiting, estatus; XRectangle *sgeo; XRectangle *spgeo; Cursor cursor[CurLast]; -char *argv_global; +char *argv_global, *status_path; int xrandr_event; +uint timing; /* Fonts */ XftFont *font; diff --git a/wmfs.1 b/wmfs.1 index 7f0a3f9..5721d96 100644 --- a/wmfs.1 +++ b/wmfs.1 @@ -13,7 +13,7 @@ .SH "NAME" wmfs \- Window Manager From Scratch .SH "SYNOPSIS" -\fBwmfs\fR [\fB\-ihv\fR] [\fB\-C \fR] [\fB\-c \fR] [\fB\-g \fR] [\fB\-s \fR] [\fB\-V \fR] +\fBwmfs\fR [\fB\-ihvS\fR] [\fB\-C \fR] [\fB\-c \fR] [\fB\-g \fR] [\fB\-s \fR] [\fB\-V \fR] .sp .SH "DESCRIPTION" \fBWMFS\fR is a basic, lightweight and dynamic tiling windows manager for X\&. @@ -45,6 +45,11 @@ Set the bar(s) statustext. If the screen number is not specified, the string wil Manage WMFS with vi-like command\&. .RE .PP +\fB\-S\fR +.RS 4 +Update status script\&. +.RE +.PP \fB\-v\fR .RS 4 Print version information to standard output, then exit\&.