Browse Source

Merge branch 'master' of git.wmfs.info:wmfs into philpep

Philippe Pepiot 14 years ago
parent
commit
b49744289c
12 changed files with 245 additions and 33 deletions
  1. 2 2
      CMakeLists.txt
  2. 13 0
      rc/status.sh
  3. 46 6
      src/client.c
  4. 16 7
      src/config.c
  5. 12 6
      src/event.c
  6. 3 3
      src/ewmh.c
  7. 35 0
      src/init.c
  8. 30 0
      src/layout.c
  9. 4 0
      src/structs.h
  10. 68 6
      src/wmfs.c
  11. 10 2
      src/wmfs.h
  12. 6 1
      wmfs.1

+ 2 - 2
CMakeLists.txt

@@ -51,10 +51,10 @@ set(wmfs_src
 add_executable(wmfs ${wmfs_src})
 
 # Set the version
-set(VERSION "WMFS-200910")
+set(VERSION "WMFS-201001")
 
 # FLAGS
-set(CFLAGS "-g -Wall -ansi")
+set(CFLAGS "-g -Wall -lpthread -ansi")
 set(CMAKE_C_FLAGS ${CFLAGS})
 
 # Linker FLAGS

+ 13 - 0
rc/status.sh

@@ -0,0 +1,13 @@
+#!/bin/sh
+#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"
+}
+
+statustext

+ 46 - 6
src/client.c

@@ -193,6 +193,33 @@ uicb_client_swap_prev(uicb_t cmd)
      return;
 }
 
+/** Set the client c above
+  *\param c Client pointer
+*/
+void
+client_above(Client *c)
+{
+     XRectangle geo = { 0 };
+
+     if(c->flags & AboveFlag)
+          return;
+
+     c->flags |= AboveFlag;
+
+     geo.height = spgeo[c->screen].height * 0.75;
+     geo.width = spgeo[c->screen].width * 0.75;
+
+     geo.y = spgeo[c->screen].y + (spgeo[c->screen].height / 2) - (geo.height / 2);
+     geo.x = spgeo[c->screen].x + (spgeo[c->screen].width / 2)- (geo.width / 2);
+
+     client_moveresize(c, geo, tags[c->screen][c->tag].resizehint);
+     client_raise(c);
+
+     tags[c->screen][c->tag].layout.func(c->screen);
+
+     return;
+}
+
 /** Set the focus to a client
  * \param c Client pointer
 */
@@ -207,15 +234,18 @@ client_focus(Client *c)
           sel->colors.frame = conf.client.bordernormal;
           sel->colors.fg = conf.titlebar.fg_normal;
           sel->colors.resizecorner = conf.client.resizecorner_normal;
+
           if(TBARH - BORDH && sel->titlebar->stipple)
                sel->titlebar->stipple_color = conf.titlebar.stipple.colors.normal;
+
+          if(sel->flags & AboveFlag)
+               sel->flags &= ~AboveFlag;
+
           frame_update(sel);
           mouse_grabbuttons(sel, False);
      }
 
-     sel = c;
-
-     if(c)
+     if((sel = c))
      {
           c->colors.frame = conf.client.borderfocus;
           c->colors.fg = conf.titlebar.fg_focus;
@@ -235,6 +265,10 @@ client_focus(Client *c)
                     client_raise(c);
           }
 
+          if(tags[sel->screen][sel->tag].abovefc
+                    && !conf.focus_fmouse)
+               client_above(sel);
+
           XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
      }
      else
@@ -558,7 +592,7 @@ client_manage(Window w, XWindowAttributes *wa, Bool ar)
      if(ar)
           arrange(c->screen, True);
 
-     if(conf.client.set_new_win_master)
+     if(!conf.client.set_new_win_master)
           layout_set_client_master(c);
 
      return c;
@@ -842,7 +876,7 @@ client_update_attributes(Client *c)
 void
 client_raise(Client *c)
 {
-     if(!c || (c->flags & TileFlag))
+     if(!c || ((c->flags & TileFlag) && !(c->flags & AboveFlag)))
           return;
 
      XRaiseWindow(dpy, c->frame);
@@ -883,6 +917,8 @@ void
 client_unmanage(Client *c)
 {
      Client *c_next = NULL;
+     Bool b = False;
+     int i;
 
      XGrabServer(dpy);
      XSetErrorHandler(errorhandlerdummy);
@@ -900,7 +936,11 @@ client_unmanage(Client *c)
      ewmh_get_client_list();
 
      /* Arrange */
-     if(c->tag == seltag[selscreen] && c->screen == selscreen)
+     for(i = 0; i < screen_count() && !b; ++i)
+          if(c->tag == seltag[i])
+               b = True;
+
+     if(b)
           tags[c->screen][c->tag].layout.func(c->screen);
      else
      {

+ 16 - 7
src/config.c

@@ -63,6 +63,7 @@ func_name_list_t tmp_func_list[] =
      {"mouse_resize",            uicb_mouse_resize },
      {"client_raise",            uicb_client_raise },
      {"toggle_free",             uicb_togglefree },
+     {"toggle_abovefc",          uicb_toggle_abovefc },
      {"screen_select",           uicb_screen_select },
      {"screen_next",             uicb_screen_next },
      {"screen_prev",             uicb_screen_prev },
@@ -135,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)
      {
@@ -150,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;
 }
 
@@ -206,7 +214,7 @@ conf_client_section(char *src)
      conf.client.resizecorner_normal = getcolor(get_opt(src, "#222222", "resize_corner_normal").str);
      conf.client.resizecorner_focus  = getcolor(get_opt(src, "#DDDDDD", "resize_corner_focus").str);
      conf.client.mod                 |= char_to_modkey(get_opt(src, "Alt", "modifier").str, key_list);
-     conf.client.set_new_win_master  = get_opt(src, "false", "set_new_win_master").bool;
+     conf.client.set_new_win_master  = get_opt(src, "true", "set_new_win_master").bool;
 
      if((conf.client.nmouse = get_size_sec(src, "mouse")))
      {
@@ -369,7 +377,7 @@ conf_tag_section(char *src)
       * MAXTAG (32) print an error and create only one.
       */
      Tag default_tag = { "WMFS", NULL, 0, 1,
-                         0.50, 1, False, False, IB_Top,
+                         0.50, 1, False, False, False, IB_Top,
                          layout_name_to_struct(conf.layout, "tile_right", conf.nlayout, layout_list) };
 
      cfg_set_sauv(src);
@@ -413,6 +421,7 @@ conf_tag_section(char *src)
                tags[k][conf.ntag[k]].mwfact     = get_opt(cfgtmp, "0.65", "mwfact").fnum;
                tags[k][conf.ntag[k]].nmaster    = get_opt(cfgtmp, "1", "nmaster").num;
                tags[k][conf.ntag[k]].resizehint = get_opt(cfgtmp, "false", "resizehint").bool;
+               tags[k][conf.ntag[k]].abovefc    = get_opt(cfgtmp, "false", "abovefc").bool;
                tags[k][conf.ntag[k]].layers = 1;
 
                tmp = _strdup(get_opt(cfgtmp, "top", "infobar_position").str);

+ 12 - 6
src/event.c

@@ -151,7 +151,7 @@ clientmessageevent(XClientMessageEvent *ev)
      if(ev->format != 32)
           return;
 
-     for(i = 0; i < net_last; ++i)
+     for(i = 0; i < net_last + screen_count(); ++i)
           if(net_atom[i] == ev->message_type)
                mess_t = i;
 
@@ -231,6 +231,10 @@ clientmessageevent(XClientMessageEvent *ev)
           screen_get_sel();
      }
 
+     if(mess_t == wmfs_update_status
+               && estatus)
+          spawn(status_path);
+
      return;
 }
 
@@ -253,7 +257,7 @@ configureevent(XConfigureRequestEvent *ev)
           CHECK(!(c->flags & FSSFlag));
      }
 
-     if((c= client_gb_win(ev->window)))
+     if((c = client_gb_win(ev->window)))
      {
           if(ev->value_mask & CWX)
                c->geo.x = ev->x + BORDH;
@@ -264,7 +268,8 @@ configureevent(XConfigureRequestEvent *ev)
           if(ev->value_mask & CWHeight)
                c->geo.height = ev->height;
 
-          client_moveresize(c, c->geo, False);
+          if(c->flags & FreeFlag)
+               client_moveresize(c, c->geo, False);
      }
      else
      {
@@ -316,14 +321,15 @@ enternotify(XCrossingEvent *ev)
      if(conf.focus_fmouse)
      {
           if((c = client_gb_win(ev->window))
-             || (c = client_gb_frame(ev->window))
-             || (c = client_gb_titlebar(ev->window))
-             || (c = client_gb_button(ev->window, &n)))
+                    || (c = client_gb_frame(ev->window))
+                    || (c = client_gb_titlebar(ev->window))
+                    || (c = client_gb_button(ev->window, &n)))
                client_focus(c);
           else
                client_focus(NULL);
      }
 
+
      return;
 }
 

+ 3 - 3
src/ewmh.c

@@ -47,7 +47,7 @@ ewmh_init_hints(void)
      char class[] = "wmfs", st[64];
      long pid = (long)getpid();
 
-     net_atom = emalloc(net_last + screen_count() + 1, sizeof(Atom));
+     net_atom = emalloc(net_last + screen_count(), sizeof(Atom));
 
      /* EWMH hints */
      net_atom[net_supported]                  = ATOM("_NET_SUPPORTED");
@@ -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");
@@ -98,9 +99,8 @@ ewmh_init_hints(void)
           net_atom[wmfs_statustext + j] = ATOM(st);
      }
 
-
      XChangeProperty(dpy, ROOT, net_atom[net_supported], XA_ATOM, 32,
-                     PropModeReplace, (uchar*)net_atom, net_last);
+                     PropModeReplace, (uchar*)net_atom, net_last + screen_count());
 
      XChangeProperty(dpy, ROOT, net_atom[wmfs_running], XA_CARDINAL, 32,
                      PropModeReplace, (uchar*)&i, 1);

+ 35 - 0
src/init.c

@@ -48,6 +48,7 @@ init(void)
      init_root();
      screen_init_geo();
      infobar_init();
+     init_status();
      ewmh_update_current_tag_prop();
      grabkeys();
 
@@ -189,4 +190,38 @@ init_layout(void)
      return;
 }
 
+/** Init statustext shell script
+  */
+void
+init_status(void)
+{
+     int fd;
+     struct stat st;
+
+     status_path = emalloc(strlen(getenv("HOME")) + strlen(DEF_STATUS) + 2, sizeof(char));
+
+     sprintf(status_path, "%s/"DEF_STATUS, getenv("HOME"));
+
+     if(!(fd = open(status_path, O_RDONLY)))
+     {
+          free(status_path);
+
+          return;
+     }
+
+     stat(status_path, &st);
+
+     if(st.st_mode & S_IXUSR)
+     {
+          estatus = True;
+          system(status_path);
+     }
+     else
+          warnx("status.sh file present in wmfs directory can't be executed, try 'chmod +x %s'.",
+                    status_path);
+
+     close(fd);
+
+     return;
+}
 

+ 30 - 0
src/layout.c

@@ -168,6 +168,7 @@ 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);
 
@@ -830,6 +831,35 @@ uicb_toggle_resizehint(uicb_t cmd)
      return;
 }
 
+/** Toggle abovefc option
+  *\param cmd uicb_t type
+  */
+void
+uicb_toggle_abovefc(uicb_t cmd)
+{
+     Client *c;
+
+     screen_get_sel();
+
+     if(!(tags[selscreen][seltag[selscreen]].abovefc = !tags[selscreen][seltag[selscreen]].abovefc))
+     {
+          for(c = clients; c; c = c->next)
+               if(c->flags & AboveFlag
+                         && c->screen == selscreen
+                         && c->tag == seltag[selscreen])
+               {
+                    c->flags &= ~AboveFlag;
+                    break;
+               }
+
+          tags[selscreen][seltag[selscreen]].layout.func(selscreen);
+     }
+
+     client_focus(sel);
+
+     return;
+}
+
 /** Set the layout
  * \param cmd uicb_t type
 */

+ 4 - 0
src/structs.h

@@ -48,6 +48,7 @@
 #define UnmapFlag (1 << 6)
 #define HintFlag  (1 << 7)
 #define FSSFlag   (1 << 8)
+#define AboveFlag (1 << 9)
 
 /* XEMBED messages */
 #define XEMBED_MAPPED                 (1 << 0)
@@ -119,6 +120,7 @@ enum
      /* WMFS HINTS */
      wmfs_running,
      wmfs_update_hints,
+     wmfs_update_status,
      wmfs_current_tag,
      wmfs_current_screen,
      wmfs_current_layout,
@@ -248,6 +250,7 @@ typedef struct
      int nmaster;
      Bool resizehint;
      Bool request_update;
+     Bool abovefc;
      int barpos;
      Layout layout;
 } Tag;
@@ -319,6 +322,7 @@ typedef struct
      Bool raiseswitch;
      Bool focus_fmouse;
      uint pad;
+     int status_timing;
      struct
      {
           /*

+ 68 - 6
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;
+
+     if(!estatus)
+          while(!exiting && !XNextEvent(dpy, &ev))
+               getevent(ev);
+     else
+     {
+          pthread_create(&evloop, NULL, thread_process, "1");
+          pthread_create(&evstatus, NULL, thread_process, NULL);
 
-     while(!exiting && !XNextEvent(dpy, &ev))
-          getevent(ev);
+          (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 <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 <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"
                       "   -V <viwmfs cmd>           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]);
@@ -402,7 +458,7 @@ main(int argc, char **argv)
                break;
 
           case 'v':
-               printf("WMFS version : "WMFS_VERSION".\n"
+               printf("WMFS version : "WMFS_VERSION"\n"
                       "  Compilation settings :\n"
                       "    - Flags : "WMFS_COMPILE_FLAGS"\n"
                       "    - Linked Libs : "WMFS_LINKED_LIBS"\n"
@@ -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;

+ 10 - 2
src/wmfs.h

@@ -44,6 +44,7 @@
 #include <getopt.h>
 #include <dirent.h>
 #include <err.h>
+#include <pthread.h>
 #include <sys/select.h>
 #include <sys/types.h>
 #include <sys/wait.h>
@@ -84,6 +85,7 @@
 #define RESHW        (6 * BORDH)
 #define BUTTONWH     (TBARH / 2)
 #define DEF_CONF     ".config/wmfs/wmfsrc"
+#define DEF_STATUS   ".config/wmfs/status.sh"
 #define PAD          conf.pad
 
 #define CWIN(win, parent, x, y, w, h, b, mask, col, at)                             \
@@ -140,6 +142,7 @@ void uicb_infobar_togglepos(uicb_t);
 void client_attach(Client *c);
 void client_configure(Client *c);
 void client_detach(Client *c);
+void client_above(Client *c);
 void client_focus(Client *c);
 Client* client_get_next(void);
 Client* client_get_prev(void);
@@ -301,6 +304,7 @@ void uicb_set_mwfact(uicb_t);
 void uicb_set_nmaster(uicb_t);
 void uicb_set_layout(uicb_t);
 void uicb_toggle_resizehint(uicb_t);
+void uicb_toggle_abovefc(uicb_t cmd);
 void uicb_set_layer(uicb_t cmd);
 void uicb_set_client_layer(uicb_t cmd);
 void layout_set_client_master(Client *c);
@@ -314,6 +318,7 @@ void init_gc(void);
 void init_cursor(void);
 void init_key(void);
 void init_geometry(void);
+void init_status(void);
 
 /* getinfo.c */
 void getinfo_tag(void);
@@ -330,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);
@@ -347,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;

+ 6 - 1
wmfs.1

@@ -13,7 +13,7 @@
 .SH "NAME"
 wmfs \- Window Manager From Scratch
 .SH "SYNOPSIS"
-\fBwmfs\fR [\fB\-ihv\fR] [\fB\-C <file>\fR] [\fB\-c <uicb_function> <cmd>\fR] [\fB\-g <argument>\fR] [\fB\-s <screen_num> <string>\fR]  [\fB\-V <viwmfs cmd>\fR]
+\fBwmfs\fR [\fB\-ihvS\fR] [\fB\-C <file>\fR] [\fB\-c <uicb_function> <cmd>\fR] [\fB\-g <argument>\fR] [\fB\-s <screen_num> <string>\fR]  [\fB\-V <viwmfs cmd>\fR]
 .sp
 .SH "DESCRIPTION"
 \fBWMFS\fR is a basic, lightweight and dynamic tiling windows manager for X\&.
@@ -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\&.