This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project wmaker-crm.git.

The branch, next has been updated
  discards  c2290ef404dcc2f437b93dd9bbfffb696cf867d4 (commit)
  discards  103cd9a13e62a24f46afab12f388f8436dc075aa (commit)
  discards  ef5f542eceb18702b4880d010421fa101381210b (commit)
  discards  41d7f7f513aa362004ddddee99a74f496c66da83 (commit)
  discards  f328bfcdd2ad594535a7c8b9190fcc7f47f76f51 (commit)
  discards  f36849c24891d3e0f0290d2d0952756636b5f6c6 (commit)
  discards  8c32dd7d321e16dfe83e03e944affd148add2830 (commit)
  discards  118993bfd7304249d1bb1a196710fd4d625a80ac (commit)
  discards  1a75270c0a50ca339a476b47c542ccfddf86c79f (commit)
  discards  67ed6a40b401173474e3b6b5fc4b2a1c6a00a796 (commit)
       via  42acb5d34cd960a6dadfefbf1498021c63e2e3a2 (commit)
       via  6aad540b889c752dec030d3d455b1dac67984a1e (commit)
       via  ea2b5f064178c854ca401d1203e5be1362a4c97c (commit)
       via  28b016914706b2c8eb062992f788c1b7cca35efe (commit)
       via  fa5f8d99375649df869e079d084af6dcc5bf25c2 (commit)
       via  ea42641033ec4dacd232e7d3017c5fe6636f5226 (commit)
       via  5ecb96cbf4c327f25de32585d3ac83257b4a7f27 (commit)
       via  14d1d3f141bc6740e7c8704f7883ed9c56fc45d5 (commit)
       via  976083f5b937a8f76b1e3cd2f70e1396c5a3a520 (commit)
       via  997b3e5d91f4194fa592c72a71ca29496014ba99 (commit)
       via  fd1dd9c7eae188aa67bb3592b4f0037bdafc8ef9 (commit)
       via  a8f6abc9ea0350ddfc0b6b4a76cb92be4c89a1b0 (commit)
       via  8276ff13310a06e79a17c50bbe2602724cf68386 (commit)
       via  1a068faa4993ed6ec628b4fc0e9b90381e9c5526 (commit)

This update added new revisions after undoing existing revisions.  That is
to say, the old revision is not a strict subset of the new revision.  This
situation occurs when you --force push a change and generate a repository
containing something like this:

 * -- * -- B -- O -- O -- O (c2290ef404dcc2f437b93dd9bbfffb696cf867d4)
            \
             N -- N -- N (42acb5d34cd960a6dadfefbf1498021c63e2e3a2)

When this happens we assume that you've already had alert emails for all
of the O revisions, and so we here report only the revisions in the N
branch from the common base, B.

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://repo.or.cz/w/wmaker-crm.git/commit/42acb5d34cd960a6dadfefbf1498021c63e2e3a2

commit 42acb5d34cd960a6dadfefbf1498021c63e2e3a2
Author: Christophe CURIS <[email protected]>
Date:   Thu May 14 18:55:35 2015 +0200

    doc: describe Iain Patterson's new feature for ICCCM compliance
    
    Signed-off-by: Christophe CURIS <[email protected]>

diff --git a/NEWS b/NEWS
index 6561c4e..023ceb1 100644
--- a/NEWS
+++ b/NEWS
@@ -66,6 +66,17 @@ tell Window Maker to just ignore them. This is done with the 
new setting called
 "IgnoreGtkHints", which is available in the "Expert" panel in WPrefs.
 
 
+Cooperative Window Manager Replacement
+--------------------------------------
+
+The ICCCM defines a protocol for window managers to ask to replace the 
currently
+running one; Window Maker now supports it. You can ask Window Maker to take the
+place of current one by running "wmaker --replace", or any other window manager
+can ask Window Maker to leave the place for them when started the same way.
+Please note that this feature must be explicitely enabled at compile time 
because
+by default it is not compiled in ("configure --enable-wmreplace").
+
+
 --- 0.95.6
 
 More image format supported
diff --git a/doc/Makefile.am b/doc/Makefile.am
index fff203f..706158c 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -32,6 +32,7 @@ EXTRA_DIST = wmaker.in wmsetbg.in
 wmaker.1x: wmaker.in Makefile $(top_builddir)/config.h
        $(AM_V_GEN)$(top_srcdir)/script/replace-ac-keywords.sh \
                --header "$(top_builddir)/config.h" --filter "HAVE_INOTIFY" \
+               --filter "USE_ICCCM_WMREPLACE" \
                -D"sysconfdir=$(sysconfdir)" --replace "sysconfdir" \
                -D"pkgdatadir=$(pkgdatadir)" --replace "pkgdatadir" \
                -o "wmaker.1x"  "$(srcdir)/wmaker.in"
diff --git a/doc/wmaker.in b/doc/wmaker.in
index dc09ce0..48e2879 100644
--- a/doc/wmaker.in
+++ b/doc/wmaker.in
@@ -51,6 +51,9 @@ disable the Drawers in the Dock
 @[email protected]
 @[email protected] \-\-no\-polling
 @!HAVE_INOTIFY@disable the periodic check on the configuration file to reload 
it automatically
+@[email protected]
+@[email protected] \-\-replace
+@USE_ICCCM_WMREPLACE@ask the currently running window manager to let Window 
Maker take his place
 .TP
 .B \-\-static
 do not update or save automatically the configuration

http://repo.or.cz/w/wmaker-crm.git/commit/6aad540b889c752dec030d3d455b1dac67984a1e

commit 6aad540b889c752dec030d3d455b1dac67984a1e
Author: Christophe CURIS <[email protected]>
Date:   Thu May 14 18:55:34 2015 +0200

    wmaker: support providing ICCCM version, for compliance with the standard
    
    The standard specify that the pseudo-selection which is used to
    cooperatively replace window managers should actually contain the version
    of the ICCCM standard which is supported. As this could be handy for
    compatibility checks in the future, let Window Maker comply.
    
    Signed-off-by: Christophe CURIS <[email protected]>

diff --git a/src/event.c b/src/event.c
index 71450fc..a6a5402 100644
--- a/src/event.c
+++ b/src/event.c
@@ -37,6 +37,7 @@
 
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
+#include <X11/Xatom.h>
 #ifdef USE_XSHAPE
 # include <X11/extensions/shape.h>
 #endif
@@ -103,6 +104,7 @@ static void handleFocusIn(XEvent *event);
 static void handleMotionNotify(XEvent *event);
 static void handleVisibilityNotify(XEvent *event);
 static void handle_inotify_events(void);
+static void handle_selection_request(XSelectionRequestEvent *event);
 static void handle_selection_clear(XSelectionClearEvent *event);
 static void wdelete_death_handler(WMagicNumber id);
 
@@ -275,6 +277,10 @@ void DispatchEvent(XEvent * event)
 #endif
                break;
 
+       case SelectionRequest:
+               handle_selection_request(&event->xselectionrequest);
+               break;
+
        case SelectionClear:
                handle_selection_clear(&event->xselectionclear);
                break;
@@ -1892,6 +1898,79 @@ static void handleVisibilityNotify(XEvent * event)
        wwin->flags.obscured = (event->xvisibility.state == 
VisibilityFullyObscured);
 }
 
+static void handle_selection_request(XSelectionRequestEvent *event)
+{
+#ifdef USE_ICCCM_WMREPLACE
+       static Atom atom_version = None;
+       WScreen *scr;
+       XSelectionEvent notify;
+
+       /*
+        * This event must be sent to the slection requester to not block him
+        *
+        * We create it with the answer 'there is no selection' by default
+        */
+       notify.type = SelectionNotify;
+       notify.display = dpy;
+       notify.requestor = event->requestor;
+       notify.selection = event->selection;
+       notify.target = event->target;
+       notify.property = None; /* This says that there is no selection */
+       notify.time = event->time;
+
+       scr = wScreenForWindow(event->owner);
+       if (!scr)
+               goto not_our_selection;
+
+       if (event->owner != scr->info_window)
+               goto not_our_selection;
+
+       if (event->selection != scr->sn_atom)
+               goto not_our_selection;
+
+       if (atom_version == None)
+               atom_version = XInternAtom(dpy, "VERSION", False);
+
+       if (event->target == atom_version) {
+               static const long icccm_version[] = { 2, 0 };
+
+               /*
+                * This protocol is defined in ICCCM 2.0:
+                * 
http://www.x.org/releases/X11R7.7/doc/xorg-docs/icccm/icccm.html
+                *  "Communication with the Window Manager by Means of 
Selections"
+                */
+
+               /*
+                * Setting the property means the content of the selection is 
available
+                * According to the ICCCM spec, we need to support being asked 
for a property
+                * set to 'None' for compatibility with old clients
+                */
+               notify.property = (event->property == 
None)?(event->target):(event->property);
+
+               XChangeProperty(dpy, event->requestor, notify.property,
+                               XA_INTEGER, 32, PropModeReplace,
+                               (unsigned char *) icccm_version, 
wlengthof(icccm_version));
+       }
+
+ not_our_selection:
+       if (notify.property == None)
+               wwarning("received SelectionRequest(%s) for target=\"%s\" from 
requestor 0x%lX but we have no answer",
+                        XGetAtomName(dpy, event->selection), XGetAtomName(dpy, 
event->target), (long) event->requestor);
+
+       /* Send the answer to the requestor */
+       XSendEvent(dpy, event->requestor, False, 0L, (XEvent *) &notify);
+
+#else
+       /*
+        * If the support for ICCCM window manager replacement was not enabled, 
we should not receive
+        * this kind of event, so we just ignore it (Conceptually, we should 
reply with 'SelectionNotify'
+        * event with property set to 'None' to tell that we don't have this 
selection, but that is a bit
+        * costly for an event that shall never happen).
+        */
+       (void) event;
+#endif
+}
+
 static void handle_selection_clear(XSelectionClearEvent *event)
 {
 #ifdef USE_ICCCM_WMREPLACE

http://repo.or.cz/w/wmaker-crm.git/commit/ea2b5f064178c854ca401d1203e5be1362a4c97c

commit ea2b5f064178c854ca401d1203e5be1362a4c97c
Author: Christophe CURIS <[email protected]>
Date:   Thu May 14 18:55:33 2015 +0200

    wmaker: make the '--replace' de-activable at compile time
    
    As it is really unlikely that in normal use case someone would need this
    feature, it is now conditional code, which is not enabled by default; the
    configure scripts now propose a '--enable-wmreplace' option to enable the
    corresponding code, as people making package for distributions may want to
    enable the feature to provide users the ability to give a try of all the
    window managers.
    
    Suggested-by: Carlos R. Mafra <[email protected]>
    Signed-off-by: Christophe CURIS <[email protected]>

diff --git a/configure.ac b/configure.ac
index 491bdc7..40f76fb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -526,6 +526,20 @@ AS_IF([test "x$enable_xdnd" = "xyes"],
 AM_CONDITIONAL([USE_DOCK_XDND], [test "x$enable_dock_xdnd" != "xno"])
 
 
+dnl Support for ICCCM 2.0 Window Manager replacement
+dnl ================================================
+AC_ARG_ENABLE([wmreplace],
+    [AS_HELP_STRING([--enable-wmreplace], [support for ICCCM window manager 
replacement])],
+    [AS_CASE([$enableval],
+        [yes|no], [],
+        [AC_MSG_ERROR([bad value '$enableval' for --enable-wmreplace])])],
+    [enable_wmreplace=no])
+AS_IF([test "x$enable_wmreplace" = "xyes"],
+    [AC_DEFINE([USE_ICCCM_WMREPLACE], [1],
+       [define to support ICCCM protocol for window manager replacement])
+     supported_xext="$supported_xext WMReplace"])
+
+
 dnl XShape support
 dnl ==============
 AC_ARG_ENABLE([shape],
diff --git a/doc/build/Compilation.texi b/doc/build/Compilation.texi
index 095718c..2ab7598 100644
--- a/doc/build/Compilation.texi
+++ b/doc/build/Compilation.texi
@@ -575,6 +575,12 @@ Disable support for Motif's MWM Window Manager hints.
 These attributes were introduced by the Motif toolkit to ask for special 
window appearance requests.
 Nowadays this is covered by the NetWM/EWMH specification, but there are still 
applications that rely on MWM Hints.
 
+@item --enable-wmreplace
+Add support for the @emph{ICCCM} protocol for cooperative window manager 
replacement.
+This feature is disabled by default because you probably don't need to switch 
seamlessly the window manager;
+if you are making a package for a distribution you'd probably want to enable 
this because it allows users to give
+a try to different window managers without restarting everything for an extra 
cost that is not really big.
+
 @item --disable-xdnd
 Disable support for dragging and dropping files on the dock, which launches a 
user-specified command
 with that file.
diff --git a/src/WindowMaker.h b/src/WindowMaker.h
index 606298d..37e3fc0 100644
--- a/src/WindowMaker.h
+++ b/src/WindowMaker.h
@@ -463,7 +463,9 @@ extern struct WPreferences {
        char show_clip_title;
 
        struct {
+#ifdef USE_ICCCM_WMREPLACE
                unsigned int replace:1;               /* replace existing 
window manager */
+#endif
                unsigned int nodock:1;                /* don't display the dock 
*/
                unsigned int noclip:1;                /* don't display the clip 
*/
                unsigned int clip_merged_in_dock:1;   /* disable clip, switch 
workspaces with dock */
diff --git a/src/event.c b/src/event.c
index 1e100f7..71450fc 100644
--- a/src/event.c
+++ b/src/event.c
@@ -1894,6 +1894,7 @@ static void handleVisibilityNotify(XEvent * event)
 
 static void handle_selection_clear(XSelectionClearEvent *event)
 {
+#ifdef USE_ICCCM_WMREPLACE
        WScreen *scr = wScreenForWindow(event->window);
 
        if (!scr)
@@ -1904,4 +1905,11 @@ static void handle_selection_clear(XSelectionClearEvent 
*event)
 
        wmessage(_("another window manager is replacing us!"));
        Shutdown(WSExitMode);
+#else
+       /*
+        * If the support for ICCCM window manager replacement was not enabled, 
we should not receive
+        * this kind of event, so we simply do nothing.
+        */
+       (void) event;
+#endif
 }
diff --git a/src/main.c b/src/main.c
index b68c5b6..d7aee3d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -435,7 +435,9 @@ static void print_help(void)
        puts(_("The Window Maker window manager for the X window system"));
        puts("");
        puts(_(" -display host:dpy      display to use"));
+#ifdef USE_ICCCM_WMREPLACE
        puts(_(" --replace              replace running window manager"));
+#endif
        puts(_(" --no-dock              do not open the application Dock"));
        puts(_(" --no-clip              do not open the workspace Clip"));
        puts(_(" --no-autolaunch        do not autolaunch applications"));
@@ -652,8 +654,10 @@ static int real_main(int argc, char **argv)
                                wPreferences.flags.noclip = 1;
                        } else if (strcmp(argv[i], "-nodrawer") == 0 || 
strcmp(argv[i], "--no-drawer") == 0) {
                                wPreferences.flags.nodrawer = 1;
+#ifdef USE_ICCCM_WMREPLACE
                        } else if (strcmp(argv[i], "-replace") == 0 || 
strcmp(argv[i], "--replace") == 0) {
                                wPreferences.flags.replace = 1;
+#endif
                        } else if (strcmp(argv[i], "-version") == 0 || 
strcmp(argv[i], "--version") == 0) {
                                printf("Window Maker %s\n", VERSION);
                                exit(0);
diff --git a/src/screen.c b/src/screen.c
index 1f246c4..01571c0 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -66,7 +66,9 @@
     |SubstructureRedirectMask|ButtonPressMask|ButtonReleaseMask\
     |KeyPressMask|KeyReleaseMask)
 
+#ifdef USE_ICCCM_WMREPLACE
 #define REPLACE_WM_TIMEOUT 15
+#endif
 
 #define STIPPLE_WIDTH 2
 #define STIPPLE_HEIGHT 2
@@ -108,6 +110,7 @@ static void make_keys(void)
  */
 static Bool replace_existing_wm(WScreen *scr)
 {
+#ifdef USE_ICCCM_WMREPLACE
        char atomName[16];
        Window wm;
        XSetWindowAttributes attribs;
@@ -139,10 +142,12 @@ static Bool replace_existing_wm(WScreen *scr)
                if (!XChangeWindowAttributes(dpy, wm, CWEventMask, &attribs))
                        wm = None;
        }
+#endif
 
        /* for our window manager info notice board and the selection owner */
        scr->info_window = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 10, 
10, 0, 0, 0);
 
+#ifdef USE_ICCCM_WMREPLACE
        /* Try to acquire the selection */
        current_time = CurrentTime;
        ret = XSetSelectionOwner(dpy, scr->sn_atom, scr->info_window, 
current_time);
@@ -188,6 +193,7 @@ static Bool replace_existing_wm(WScreen *scr)
        event.data.l[4] = (long) 0L;
        event.window = scr->root_win;
        XSendEvent(dpy, scr->root_win, False, StructureNotifyMask, (XEvent *) 
&event);
+#endif
 
        return True;
 }
diff --git a/src/screen.h b/src/screen.h
index f3fc6fb..4d846c5 100644
--- a/src/screen.h
+++ b/src/screen.h
@@ -69,7 +69,9 @@ typedef struct WDrawerChain {
 typedef struct _WScreen {
     int        screen;                        /* screen number */
     Window info_window;                       /* for our window manager info 
stuff */
+#ifdef USE_ICCCM_WMREPLACE
     Atom sn_atom;                     /* window manager selection */
+#endif
 
     int scr_width;                    /* size of the screen */
     int scr_height;

http://repo.or.cz/w/wmaker-crm.git/commit/28b016914706b2c8eb062992f788c1b7cca35efe

commit 28b016914706b2c8eb062992f788c1b7cca35efe
Author: Iain Patterson <[email protected]>
Date:   Thu May 14 18:55:32 2015 +0200

    wmaker: replace and be replaced (ICCCM protocol)
    
    Use the same logic used by xfwm4, metacity et al to replace an existing
    window manager on the screen and allow other window managers to replace
    us, as defined by the ICCCM 2.0:
    
    http://www.x.org/releases/X11R7.6/doc/xorg-docs/specs/ICCCM/icccm.html
      Communication with the Window Manager by Means of Selections
    
    By convention those window managers try to become the selection owner of
    the WM_Sn atom where n is the screen number.  If the atom is owned by
    another window manager and the --replace argument was not given to wmaker
    we fail to start.  If the argument was given we try to become the new
    owner and wait for the existing window manger to exit.
    
    After a successful startup we watch for SelectionClear events on the
    atom and initiate a shutdown if one arrives, as that implies that
    another window manager was started with --replace.

diff --git a/src/WindowMaker.h b/src/WindowMaker.h
index 3c2869c..606298d 100644
--- a/src/WindowMaker.h
+++ b/src/WindowMaker.h
@@ -463,6 +463,7 @@ extern struct WPreferences {
        char show_clip_title;
 
        struct {
+               unsigned int replace:1;               /* replace existing 
window manager */
                unsigned int nodock:1;                /* don't display the dock 
*/
                unsigned int noclip:1;                /* don't display the clip 
*/
                unsigned int clip_merged_in_dock:1;   /* disable clip, switch 
workspaces with dock */
diff --git a/src/event.c b/src/event.c
index dbb927b..1e100f7 100644
--- a/src/event.c
+++ b/src/event.c
@@ -103,6 +103,7 @@ static void handleFocusIn(XEvent *event);
 static void handleMotionNotify(XEvent *event);
 static void handleVisibilityNotify(XEvent *event);
 static void handle_inotify_events(void);
+static void handle_selection_clear(XSelectionClearEvent *event);
 static void wdelete_death_handler(WMagicNumber id);
 
 
@@ -274,6 +275,10 @@ void DispatchEvent(XEvent * event)
 #endif
                break;
 
+       case SelectionClear:
+               handle_selection_clear(&event->xselectionclear);
+               break;
+
        default:
                handleExtensions(event);
                break;
@@ -1886,3 +1891,17 @@ static void handleVisibilityNotify(XEvent * event)
                return;
        wwin->flags.obscured = (event->xvisibility.state == 
VisibilityFullyObscured);
 }
+
+static void handle_selection_clear(XSelectionClearEvent *event)
+{
+       WScreen *scr = wScreenForWindow(event->window);
+
+       if (!scr)
+               return;
+
+       if (event->selection != scr->sn_atom)
+               return;
+
+       wmessage(_("another window manager is replacing us!"));
+       Shutdown(WSExitMode);
+}
diff --git a/src/main.c b/src/main.c
index 297f3ab..b68c5b6 100644
--- a/src/main.c
+++ b/src/main.c
@@ -435,6 +435,7 @@ static void print_help(void)
        puts(_("The Window Maker window manager for the X window system"));
        puts("");
        puts(_(" -display host:dpy      display to use"));
+       puts(_(" --replace              replace running window manager"));
        puts(_(" --no-dock              do not open the application Dock"));
        puts(_(" --no-clip              do not open the workspace Clip"));
        puts(_(" --no-autolaunch        do not autolaunch applications"));
@@ -651,6 +652,8 @@ static int real_main(int argc, char **argv)
                                wPreferences.flags.noclip = 1;
                        } else if (strcmp(argv[i], "-nodrawer") == 0 || 
strcmp(argv[i], "--no-drawer") == 0) {
                                wPreferences.flags.nodrawer = 1;
+                       } else if (strcmp(argv[i], "-replace") == 0 || 
strcmp(argv[i], "--replace") == 0) {
+                               wPreferences.flags.replace = 1;
                        } else if (strcmp(argv[i], "-version") == 0 || 
strcmp(argv[i], "--version") == 0) {
                                printf("Window Maker %s\n", VERSION);
                                exit(0);
diff --git a/src/screen.c b/src/screen.c
index 10a1fc9..1f246c4 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -66,6 +66,8 @@
     |SubstructureRedirectMask|ButtonPressMask|ButtonReleaseMask\
     |KeyPressMask|KeyReleaseMask)
 
+#define REPLACE_WM_TIMEOUT 15
+
 #define STIPPLE_WIDTH 2
 #define STIPPLE_HEIGHT 2
 static char STIPPLE_DATA[] = { 0x02, 0x01 };
@@ -91,6 +93,106 @@ static void make_keys(void)
 }
 
 /*
+ * Support for ICCCM 2.0: Window Manager Replacement protocol
+ * See: http://www.x.org/releases/X11R7.6/doc/xorg-docs/specs/ICCCM/icccm.html
+ *
+ * Basically, user should be able to dynamically change its window manager; 
this is done
+ * cooperatively through a special Selection ("WM_Sn" where 'n' is the X 
screen number)
+ *
+ * This function does 2 things:
+ *  - it checks if this selection is already owned, which means that another 
window
+ * manager is running. If it is the case and user specified '--replace' on the 
command
+ * line, then it asks the WM to shut down;
+ *  - when ok, it sets the selection ownership to ourself, so another window 
manager
+ * may ask us to shut down (this is handled in "event.c")
+ */
+static Bool replace_existing_wm(WScreen *scr)
+{
+       char atomName[16];
+       Window wm;
+       XSetWindowAttributes attribs;
+       XClientMessageEvent event;
+       unsigned long current_time;
+       int ret;
+
+       /* Try to acquire the atom named WM_S<screen> */
+       ret = snprintf(atomName, sizeof(atomName), "WM_S%d", scr->screen);
+       if (ret < 0 || ret == sizeof(atomName)) {
+               werror("out of memory trying to allocate window manager 
selection atom for screen %d", scr->screen);
+               return False;
+       }
+
+       scr->sn_atom = XInternAtom(dpy, atomName, False);
+       if (! scr->sn_atom)
+               return False;
+
+       /* Check if an existing window manager owns the selection */
+       wm = XGetSelectionOwner(dpy, scr->sn_atom);
+       if (wm) {
+               if (!wPreferences.flags.replace) {
+                       wmessage(_("another window manager is running"));
+                       wwarning(_("use the --replace flag to replace it"));
+                       return False;
+               }
+
+               attribs.event_mask = StructureNotifyMask;
+               if (!XChangeWindowAttributes(dpy, wm, CWEventMask, &attribs))
+                       wm = None;
+       }
+
+       /* for our window manager info notice board and the selection owner */
+       scr->info_window = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 10, 
10, 0, 0, 0);
+
+       /* Try to acquire the selection */
+       current_time = CurrentTime;
+       ret = XSetSelectionOwner(dpy, scr->sn_atom, scr->info_window, 
current_time);
+       if (ret == BadAtom || ret == BadWindow)
+               return False;
+
+       /* Wait for other window manager to exit */
+       if (wm) {
+               unsigned long wait = 0;
+               unsigned long timeout = REPLACE_WM_TIMEOUT * 1000000L;
+               XEvent event;
+
+               while (wait < timeout) {
+                       if (!(wait % 1000000))
+                               wmessage(_("waiting %lus for other window 
manager to exit"), (timeout - wait) / 1000000L);
+
+                       if (XCheckWindowEvent(dpy, wm, StructureNotifyMask, 
&event))
+                               if (event.type == DestroyNotify)
+                                       break;
+
+                       wusleep(100000);
+                       wait += 100000;
+               }
+
+               if (wait >= timeout) {
+                       wwarning(_("other window manager hasn't exited!"));
+                       return False;
+               }
+
+               wmessage(_("replacing the other window manager"));
+       }
+
+       if (XGetSelectionOwner(dpy, scr->sn_atom) != scr->info_window)
+               return False;
+
+       event.type = ClientMessage;
+       event.message_type = scr->sn_atom;
+       event.format = 32;
+       event.data.l[0] = (long) current_time;
+       event.data.l[1] = (long) scr->sn_atom;
+       event.data.l[2] = (long) scr->info_window;
+       event.data.l[3] = (long) 0L;
+       event.data.l[4] = (long) 0L;
+       event.window = scr->root_win;
+       XSendEvent(dpy, scr->root_win, False, StructureNotifyMask, (XEvent *) 
&event);
+
+       return True;
+}
+
+/*
  *----------------------------------------------------------------------
  * alreadyRunningError--
  *     X error handler used to catch errors when trying to do
@@ -523,6 +625,13 @@ WScreen *wScreenInit(int screen_number)
        CantManageScreen = 0;
        oldHandler = XSetErrorHandler(alreadyRunningError);
 
+       /* Do we need to replace an existing window manager? */
+       if (!replace_existing_wm(scr)) {
+               XDestroyWindow(dpy, scr->info_window);
+               wfree(scr);
+               return NULL;
+       }
+
        event_mask = EVENT_MASK;
        XSelectInput(dpy, scr->root_win, event_mask);
 
@@ -616,11 +725,6 @@ WScreen *wScreenInit(int screen_number)
        /* create GCs with default values */
        allocGCs(scr);
 
-       /* for our window manager info notice board. Need to
-        * create before reading the defaults, because it will be used there.
-        */
-       scr->info_window = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 10, 
10, 0, 0, 0);
-
        /* read defaults for this screen */
        wReadDefaults(scr, w_global.domain.wmaker->dictionary);
 
diff --git a/src/screen.h b/src/screen.h
index 8ffb6f9..f3fc6fb 100644
--- a/src/screen.h
+++ b/src/screen.h
@@ -69,6 +69,7 @@ typedef struct WDrawerChain {
 typedef struct _WScreen {
     int        screen;                        /* screen number */
     Window info_window;                       /* for our window manager info 
stuff */
+    Atom sn_atom;                     /* window manager selection */
 
     int scr_width;                    /* size of the screen */
     int scr_height;

http://repo.or.cz/w/wmaker-crm.git/commit/fa5f8d99375649df869e079d084af6dcc5bf25c2

commit fa5f8d99375649df869e079d084af6dcc5bf25c2
Author: Christophe CURIS <[email protected]>
Date:   Thu May 14 15:07:04 2015 +0200

    wmaker-check: rewrote parsing of structure fields for callback checker
    
    Doug Torrance reported a problem with some versions of AWK which caused the
    signed/unsigned attribute to not be properly ignored, because the regular
    expression was using a GNU extension to keep it simple.
    
    While trying to reproduce it, I discovered that mawk was chocking on one
    regexp used in parsing the type+names parsing of structure members.
    
    This patch is rewriting the parsing, because hacking regexp to make them
    fall working is still not the best solution for maintainability. There is
    now a clearer code which is also safer because it will handle more
    gracefully corner cases.
    
    Reported-by: Doug Torrance <[email protected]>
    Signed-off-by: Christophe CURIS <[email protected]>

diff --git a/script/check-wmaker-loaddef-callbacks.sh 
b/script/check-wmaker-loaddef-callbacks.sh
index 1cc9541..57d4cda 100755
--- a/script/check-wmaker-loaddef-callbacks.sh
+++ b/script/check-wmaker-loaddef-callbacks.sh
@@ -163,8 +163,8 @@ function parse_structure(prefix) {
     }
 
     # skip line that define nothing interresting
-    if (/^[ \t]*$/) { continue; }
     gsub(/^[ \t]+/, "");
+    if (/^$/) { continue; }
     if (/^#/) { continue; }
     gsub(/[ \t]+$/, "");
 
@@ -198,39 +198,79 @@ function parse_structure(prefix) {
       print "Warning: line " FILENAME ":" NR " not understood inside struct" > 
"/dev/stderr";
       continue;
     }
+    gsub(/;$/, "");
 
     # Skip the lines that define a bit-field because they cannot be safely
     # pointed to anyway
     if (/:/) { continue; }
 
-    # It looks like a valid line, separate the name from the type
-    gsub(/;$/, "");
-    name = $0;
-    gsub(/([A-Z_a-z][A-Z_a-z0-9]*([ \t]*,[ \t]*)*)*$/, "");
-    name = substr(name, length($0) + 1);
+    separate_type_and_names();
 
     # In some rare case we cannot extract the name, that is likely a function 
pointer type
-    if (name == "") { continue; }
-
-    # Remove the sign specification because it is not a real problem
-    gsub(/\<(un)?signed\>/, " ");
-    if (/^[^A-Za-z]*$/) {
-      # If there is no more character, that means that the sign declaration 
was the only type specified, so
-      # we use the "int" type which is what C will use
-      $0 = "int " $0;
+    if (type == "") { continue; }
+
+    # Save this information in an array
+    for (i = 1; i <= nb_names; i++) {
+      # If it is an array, push that information into the type
+      idx = index(name_list[i], "[");
+      if (idx > 0) {
+        member[prefix ":" substr(name_list[i], 1, idx-1) ] = type 
substr(name_list[i], idx);
+      } else {
+        member[prefix ":" name_list[i] ] = type;
+      }
     }
+  }
+}
 
-    # Pack the type to have something consistent
-    gsub(/^[ \t]+/, "");
-    gsub(/[ \t]+$/, "");
-    gsub(/[ \t]*\*[ \t]*/, "*");
-    gsub(/[ \t]+/, " ");
+# Separate the declaration of an member of the struct: its type and the list 
of names
+# The result is returned through variables "name_list + nb_names" and "type"
+function separate_type_and_names() {
+  # Separate by names first
+  nb_names = split($0, name_list, /[ \t]*,[ \t]*/);
+
+  # Separate the type from the 1st name
+  if (name_list[1] ~ /\]$/) {
+    idx = index(name_list[1], "[") - 1;
+  } else {
+    idx = length(name_list[1]);
+  }
+  while (substr(name_list[1], idx, 1) ~ /[A-Za-z_0-9]/) { idx--; }
 
-    # Save this information in an array
-    nb_vars = split(name, var_list, /[ \t]*,[ \t]*/);
-    for (i = 1; i <= nb_vars; i++) {
-      member[prefix ":" var_list[i] ] = $0;
+  type = substr(name_list[1], 1, idx);
+  name_list[1] = substr(name_list[1], idx + 1);
+
+  if (type ~ /\(/) {
+    # If therese is a parenthesis in the type, that means we are parsing a 
function pointer
+    # declaration. This is not supported at current time (not needed), so we 
silently ignore
+    type = "";
+    return;
+  }
+
+  # Remove size information from array declarations
+  for (i in name_list) {
+    gsub(/\[[^\]]+\]/, "[]", name_list[i]);
+  }
+
+  # Parse the type to make it into a "standard" format
+  gsub(/[ \t]+$/, "", type);
+  nb_elem = split(type, type_list, /[ \t]+/);
+  type = "";
+  for (i = 1; i <= nb_elem; i++) {
+    if (type_list[i] == "signed" || type_list[i] == "unsigned") {
+      # The sign information is not a problem for pointer compatibility, so we 
do not keep it
+      continue;
     }
+    if (type_list[i] ~ /^\*+$/) {
+      # If we have a pointer mark by itself, we glue it to the previous keyword
+      type = type type_list[i];
+    } else {
+      type = type " " type_list[i];
+    }
+  }
+  gsub(/^ /, "", type);
+  if (type ~ /^\*/ || type == "") {
+    # We have a signed/unsigned without explicit "int" specification, add it 
now
+    type = "int" type;
   }
 }
 
@@ -364,7 +404,7 @@ function extract_string_to_element() {
   return content "\"";
 }
 
-# Wherever a long C comment (/* comment */) is encounter, it is discarded
+# Wherever a long C comment (/* comment */) is encountered, it is discarded
 function skip_long_comment() {
   while (1) {
     idx = index($0, "*/");

http://repo.or.cz/w/wmaker-crm.git/commit/ea42641033ec4dacd232e7d3017c5fe6636f5226

commit ea42641033ec4dacd232e7d3017c5fe6636f5226
Author: Christophe CURIS <[email protected]>
Date:   Sun May 10 19:56:08 2015 +0200

    Add a configuration option to ignore Decoration Hints from GTK-based 
application
    
    As reported by Nerijus Baliunas and Paul Jakma, the GNOME application,
    which use the GTK toolkit, are asking to have no window decoration. This
    can be solved by editing the window's attributes in Window Maker, but this
    can be tedious when there are many GNOME application used.
    
    This patch adds a configuration option: Window Maker tries to detect for
    GTK-based windows and in this case ignore the decoration hints that were
    provided by the application.
    
    Suggested-by: Paul Jakma <[email protected]>
    Signed-off-by: Christophe CURIS <[email protected]>

diff --git a/FAQ b/FAQ
index c458080..79ac476 100644
--- a/FAQ
+++ b/FAQ
@@ -740,6 +740,11 @@ The workaround is, for each application, to ask for Window 
Maker's window menu
 and click on the greyed "Disable titlebar" until it is white (the same can be
 done for other decoration attributes).
 
+If you use a lot of GNOME applications, you may want to ask Window Maker to 
just
+ignore the no-titlebar-and-all for all windows at once, which is done from
+WPrefs by going to the "Expert" panel and checking the "Ignore decoration hints
+for GTK applications" button.
+
 
 
 -=-=-=-=-=-=-=-
diff --git a/NEWS b/NEWS
index 172c970..6561c4e 100644
--- a/NEWS
+++ b/NEWS
@@ -56,6 +56,16 @@ Mini-Preview name. The setting is configurable with WPrefs 
in the Icon
 Preferences tab, the size is now expressed in pixels directly.
 
 
+Ignore Decoration Hints from GNOME applications
+-----------------------------------------------
+
+The GNOME applications ask Window Maker to get no title bar and no resize bar 
to
+their windows by using "Hints". You can re-add them using the Attribute dialog
+in the Window menu, but if you are using many GNOME applications you may want 
to
+tell Window Maker to just ignore them. This is done with the new setting called
+"IgnoreGtkHints", which is available in the "Expert" panel in WPrefs.
+
+
 --- 0.95.6
 
 More image format supported
diff --git a/WPrefs.app/Expert.c b/WPrefs.app/Expert.c
index 7268002..6db1dfa 100644
--- a/WPrefs.app/Expert.c
+++ b/WPrefs.app/Expert.c
@@ -43,6 +43,9 @@ static const struct {
        { N_("Disable miniwindows (icons for minimized windows). For use with 
KDE/GNOME."),
          /* default: */ False, OPTION_WMAKER, "DisableMiniwindows" },
 
+       { N_("Ignore decoration hints for GTK applications."),
+         /* default: */ False, OPTION_WMAKER, "IgnoreGtkHints" },
+
        { N_("Disable workspace pager."),
          /* default: */ False, OPTION_WMAKER, "DisableWorkspacePager" },
 
diff --git a/src/WindowMaker.h b/src/WindowMaker.h
index ccdb6c8..3c2869c 100644
--- a/src/WindowMaker.h
+++ b/src/WindowMaker.h
@@ -394,6 +394,7 @@ extern struct WPreferences {
        char dont_confirm_kill;            /* do not confirm Kill application */
        char disable_miniwindows;
        char disable_workspace_pager;
+       char ignore_gtk_decoration_hints;
 
        char dont_blink;                   /* do not blink icon selection */
 
@@ -558,6 +559,11 @@ extern struct wmaker_global_variables {
                        Atom titlebar_state;
                } gnustep;
 
+               /* Destkop-environment related */
+               struct {
+                       Atom gtk_object_path;
+               } desktop;
+
                /* WindowMaker specific */
                struct {
                        Atom menu;
diff --git a/src/defaults.c b/src/defaults.c
index b6e855c..70fbeb5 100644
--- a/src/defaults.c
+++ b/src/defaults.c
@@ -518,6 +518,8 @@ WDefaultEntry optionList[] = {
            &wPreferences.panel_only_open, getBool, NULL, NULL, NULL},
        {"MiniPreviewSize", "128", NULL,
            &wPreferences.minipreview_size, getInt, NULL, NULL, NULL},
+       {"IgnoreGtkHints", "NO", NULL,
+           &wPreferences.ignore_gtk_decoration_hints, getBool, NULL, NULL, 
NULL},
 
        /*
         * Backward Compatibility:
diff --git a/src/startup.c b/src/startup.c
index 5f43cfd..8e633b8 100644
--- a/src/startup.c
+++ b/src/startup.c
@@ -394,6 +394,8 @@ static char *atomNames[] = {
        GNUSTEP_WM_MINIATURIZE_WINDOW,
        GNUSTEP_TITLEBAR_STATE,
 
+       "_GTK_APPLICATION_OBJECT_PATH",
+
        "WM_IGNORE_FOCUS_EVENTS"
 };
 
@@ -467,7 +469,9 @@ void StartUp(Bool defaultScreenOnly)
        w_global.atom.gnustep.wm_miniaturize_window = atom[18];
        w_global.atom.gnustep.titlebar_state = atom[19];
 
-       w_global.atom.wm.ignore_focus_events = atom[20];
+       w_global.atom.desktop.gtk_object_path = atom[20];
+
+       w_global.atom.wm.ignore_focus_events = atom[21];
 
 #ifdef USE_DOCK_XDND
        wXDNDInitializeAtoms();
diff --git a/src/window.c b/src/window.c
index b1cbd30..532670c 100644
--- a/src/window.c
+++ b/src/window.c
@@ -288,6 +288,31 @@ static void setupGNUstepHints(WWindow *wwin, 
GNUstepWMAttributes *gs_hints)
                wwin->client_flags.no_appicon = 1;
 }
 
+static void discard_hints_from_gtk(WWindow *wwin)
+{
+       Atom type;
+       int format;
+       unsigned long nb_item, nb_remain;
+       unsigned char *result;
+       int status;
+
+       status = XGetWindowProperty(dpy, wwin->client_win, 
w_global.atom.desktop.gtk_object_path, 0, 16, False,
+                                   AnyPropertyType, &type, &format, &nb_item, 
&nb_remain, &result);
+       if (status != Success)
+               return;
+
+       /* If we're here, that means the Property exists. We don't care what is 
inside, it means it is a GTK-based application */
+
+       if (result != NULL)
+               XFree(result);
+
+       /* GTK is asking to remove these decorations: */
+       wwin->client_flags.no_titlebar = 0;
+       wwin->client_flags.no_close_button = 0;
+       wwin->client_flags.no_miniaturize_button = 0;
+       wwin->client_flags.no_resizebar = 0;
+}
+
 void wWindowSetupInitialAttributes(WWindow *wwin, int *level, int *workspace)
 {
        WScreen *scr = wwin->screen_ptr;
@@ -351,6 +376,9 @@ void wWindowSetupInitialAttributes(WWindow *wwin, int 
*level, int *workspace)
 
                wNETWMCheckClientHints(wwin, &tmp_level, &tmp_workspace);
 
+               if (wPreferences.ignore_gtk_decoration_hints)
+                       discard_hints_from_gtk(wwin);
+
                /* window levels are between INT_MIN+1 and INT_MAX, so if we 
still
                 * have INT_MIN that means that no window level was requested. 
-Dan
                 */

http://repo.or.cz/w/wmaker-crm.git/commit/5ecb96cbf4c327f25de32585d3ac83257b4a7f27

commit 5ecb96cbf4c327f25de32585d3ac83257b4a7f27
Author: Christophe CURIS <[email protected]>
Date:   Sun May 10 19:56:07 2015 +0200

    doc: describe the GNOME application issue in the FAQ
    
    Now that Window Maker have been fixed to allow the user to properly control
    and save the title bar/resize bar/other decoration settings on the window,
    describe the problem reported (first) by Nerijus Baliunas, so more people
    may find the answer.
    
    Signed-off-by: Christophe CURIS <[email protected]>

diff --git a/FAQ b/FAQ
index 985e861..c458080 100644
--- a/FAQ
+++ b/FAQ
@@ -60,6 +60,7 @@ Summary of Contents:
         fonts.
      3.10 When I set the root background with wmsetbg by hand it works,
           but when I do that from the configuration files it doesn't!
+     3.11 When I run GNOME application they have no title bar.
 
 4 - Configuration 
      4.1 What are those files inside my ~/GNUstep directory? 
@@ -345,7 +346,10 @@ The same is true for CDE.
 
 Now, answering the question: Yes, you can use WindowMaker in these
 environments. To use Window Maker with GNOME, you don't need to do
-anything special. To use it with CDE, read the answer for "How do I switch
+anything special, although you may want to look at the "When I run
+GNOME application they have no title bar" below.
+
+To use it with CDE, read the answer for "How do I switch
 CDE's window manager to use Window Maker?"
 
 To use it with KDE, read it's documentation to get rid of kwm (and possibly
@@ -724,6 +728,20 @@ These directories will be listed under the "Search Path" 
section of WPrefs.
 
 
 
+3.11 When I run GNOME application they have no title bar.
+----------------------------------
+
+The GNOME toolkit decided to behave his own way, so it draws its own title bar
+with buttons, and asks Window Maker to not draw anything (title bar, resize 
bar,
+close and miniaturise button, ...).
+
+The workaround is, for each application, to ask for Window Maker's window menu
+(that is likely <Ctrl>+<Escape> if you did not change it), get the Attributes,
+and click on the greyed "Disable titlebar" until it is white (the same can be
+done for other decoration attributes).
+
+
+
 -=-=-=-=-=-=-=-
 Configuration:
 -=-=-=-=-=-=-=-

http://repo.or.cz/w/wmaker-crm.git/commit/14d1d3f141bc6740e7c8704f7883ed9c56fc45d5

commit 14d1d3f141bc6740e7c8704f7883ed9c56fc45d5
Author: Christophe CURIS <[email protected]>
Date:   Sun May 10 19:56:06 2015 +0200

    wmaker: fix clearing of window attribute that was not saved properly
    
    As reported by Nerijus Baliunas, there was a problem when unchecking an
    attribute in the Window Inspector and saving it. The original code was
    meant to save an attribute that is being checked by user, but not one that
    is explicitly unchecked, which means than although it looked ok when using
    the "Apply" button, it was not remembered when restarting the application.
    
    In continuation to the clean-up started in the previous patches, this one
    is updating the Window Inspector to display 2 check-boxes, one read-only on
    the left, displaying the state requested by the application, and a second
    one which makes use of the new Tri-State button in WINGs to let the user
    specify if he wants to force-on, force-off, or leave as-is the attribute.
    
    The saving to the property list is then updated to take into account this
    new 3-state when saving to the file, so relaunching the application will
    remember correctly the user choice.
    
    Reported-by: Nerijus Baliunas <[email protected]>
    Signed-off-by: Christophe CURIS <[email protected]>

diff --git a/src/winspector.c b/src/winspector.c
index 0d6d57d..e947a14 100644
--- a/src/winspector.c
+++ b/src/winspector.c
@@ -203,6 +203,7 @@ typedef struct InspectorPanel {
 
        /* second page. attributes */
        WMFrame *attrFrm;
+       WMButton *attrClient[sizeof(window_attribute) / 
sizeof(window_attribute[0])];
        WMButton *attrChk[sizeof(window_attribute) / 
sizeof(window_attribute[0])];
 
        /* 3rd page. more attributes */
@@ -642,8 +643,27 @@ static void saveSettings(WMWidget *button, void 
*client_data)
 
        /* Attributes... --> Window Attributes */
        for (i = 0; i < wlengthof(window_attribute); i++) {
-               value = (WMGetButtonSelected(panel->attrChk[i]) != 0) ? Yes : 
No;
-               different |= insertAttribute(dict, winDic, pl_attribute[i], 
value, flags);
+               WMPropList *old_value;
+               int state;
+
+               old_value = WMGetFromPLDictionary(winDic, pl_attribute[i]);
+               state = WMGetButtonSelected(panel->attrChk[i]);
+               if (state > 0) {
+                       if ((old_value == NULL) || !getBool(old_value)) {
+                               WMPutInPLDictionary(winDic, pl_attribute[i], 
Yes);
+                               different |= 1;
+                       }
+               } else if (state == 0) {
+                       if ((old_value == NULL) || getBool(old_value)) {
+                               WMPutInPLDictionary(winDic, pl_attribute[i], 
No);
+                               different |= 1;
+                       }
+               } else {        /* (state < 0) */
+                       if (old_value != NULL) {
+                               WMRemoveFromPLDictionary(winDic, 
pl_attribute[i]);
+                               different |= 1;
+                       }
+               }
        }
 
        /* Attributes... --> Advanced Options */
@@ -726,12 +746,19 @@ static void applySettings(WMWidget *button, void 
*client_data)
 
        /* Attributes... --> Window Attributes */
        for (i = 0; i < wlengthof(window_attribute); i++) {
-               if (WMGetButtonSelected(panel->attrChk[i]))
+               int state;
+
+               state = WMGetButtonSelected(panel->attrChk[i]);
+
+               if (state > 0)
                        set_attr_flag(&wwin->user_flags, 
&window_attribute[i].flag);
                else
                        clear_attr_flag(&wwin->user_flags, 
&window_attribute[i].flag);
 
-               set_attr_flag(&wwin->defined_user_flags, 
&window_attribute[i].flag);
+               if (state < 0)
+                       clear_attr_flag(&wwin->defined_user_flags, 
&window_attribute[i].flag);
+               else
+                       set_attr_flag(&wwin->defined_user_flags, 
&window_attribute[i].flag);
        }
 
        /* Attributes... --> Advanced Options */
@@ -904,7 +931,7 @@ static void revertSettings(WMWidget *button, void 
*client_data)
                if (is_userdef)
                        flag = get_attr_flag(&wwin->user_flags, 
&window_attribute[i].flag);
                else
-                       flag = get_attr_flag(&wwin->client_flags, 
&window_attribute[i].flag);
+                       flag = -1;
 
                WMSetButtonSelected(panel->attrChk[i], flag);
        }
@@ -1315,15 +1342,31 @@ static void create_tab_window_attributes(WWindow *wwin, 
InspectorPanel *panel, i
        for (i = 0; i < wlengthof(window_attribute); i++) {
                int is_userdef, flag;
 
+               /* Read-only button to display the state requested by the 
application */
+               flag = get_attr_flag(&wwin->client_flags, 
&window_attribute[i].flag);
+
+               panel->attrClient[i] = WMCreateSwitchButton(panel->attrFrm);
+               WMMoveWidget(panel->attrClient[i], 10, 20 * (i + 1));
+               WMResizeWidget(panel->attrClient[i], 20, 20);
+               WMSetButtonText(panel->attrClient[i], NULL);
+               WMSetButtonSelected(panel->attrClient[i], flag);
+               WMSetButtonEnabled(panel->attrClient[i], False);
+
+               WMSetBalloonTextForView(_("Show the state that was asked by the 
application.\n"
+                                         "You can use the checkbox on the 
right to change this setting;\n"
+                                         "when it is grayed it means to follow 
application's choice."),
+                                       WMWidgetView(panel->attrClient[i]));
+
+               /* Button to let user override this choice */
                is_userdef = get_attr_flag(&wwin->defined_user_flags, 
&window_attribute[i].flag);
                if (is_userdef)
                        flag = get_attr_flag(&wwin->user_flags, 
&window_attribute[i].flag);
                else
-                       flag = get_attr_flag(&wwin->client_flags, 
&window_attribute[i].flag);
+                       flag = -1;
 
-               panel->attrChk[i] = WMCreateSwitchButton(panel->attrFrm);
-               WMMoveWidget(panel->attrChk[i], 10, 20 * (i + 1));
-               WMResizeWidget(panel->attrChk[i], frame_width - 15, 20);
+               panel->attrChk[i] = WMCreateButton(panel->attrFrm, WBTTriState);
+               WMMoveWidget(panel->attrChk[i], 30, 20 * (i + 1));
+               WMResizeWidget(panel->attrChk[i], frame_width - 45, 20);
                WMSetButtonSelected(panel->attrChk[i], flag);
                WMSetButtonText(panel->attrChk[i], 
_(window_attribute[i].caption));
 

http://repo.or.cz/w/wmaker-crm.git/commit/976083f5b937a8f76b1e3cd2f70e1396c5a3a520

commit 976083f5b937a8f76b1e3cd2f70e1396c5a3a520
Author: Christophe CURIS <[email protected]>
Date:   Sun May 10 19:56:05 2015 +0200

    WINGs: create a new type of Tri-State Switch Button (to doc)
    
    There are some times when we need a Switch Button (aka CheckBox) with more
    than 2 states, generally to express check/uncheck/leave-as-is.
    
    This patch extends the Button widget to support the new WBTTriState type,
    similar to the existing WBTSwitch except it supports a 3rd state which is
    reported to application as '-1'.
    
    The implementation was done in order to not break the binary API. The
    version have been incremented in the WINGs header to reflect the change,
    but not the version in the 'configure.ac' because that have already been
    done in commit c6e323e75d for the next Window Maker release.
    
    Signed-off-by: Christophe CURIS <[email protected]>

diff --git a/WINGs/WINGs/WINGs.h b/WINGs/WINGs/WINGs.h
index 4798174..5235c20 100644
--- a/WINGs/WINGs/WINGs.h
+++ b/WINGs/WINGs/WINGs.h
@@ -26,7 +26,7 @@
 #include <WINGs/WUtil.h>
 #include <X11/Xlib.h>
 
-#define WINGS_H_VERSION  20141205
+#define WINGS_H_VERSION  20150508
 
 
 #ifdef __cplusplus
@@ -127,7 +127,8 @@ typedef enum {
     WBTRadio = 5,
     WBTMomentaryChange = 6,
     WBTOnOff = 7,
-    WBTMomentaryLight = 8
+    WBTMomentaryLight = 8,
+    WBTTriState = 9
 } WMButtonType;
 
 /* button behaviour masks */
diff --git a/WINGs/WINGs/WINGsP.h b/WINGs/WINGs/WINGsP.h
index fc18b1c..4cbe0fc 100644
--- a/WINGs/WINGs/WINGsP.h
+++ b/WINGs/WINGs/WINGsP.h
@@ -268,6 +268,16 @@ typedef struct W_Screen {
     struct W_View *modalView;
     unsigned modalLoop:1;
     unsigned ignoreNextDoubleClick:1;
+
+    /*
+     * New stuff in Window Maker 0.95.7
+     * Added at the end of the structure to avoid breaking binary compatibility
+     * with previous versions of the toolkit
+     */
+    W_Pixmap *tristateButtonImageOn;
+    W_Pixmap *tristateButtonImageOff;
+    W_Pixmap *tristateButtonImageTri;
+
 } W_Screen;
 
 #define W_DRAWABLE(scr)                (scr)->rcontext->drawable
diff --git a/WINGs/wbutton.c b/WINGs/wbutton.c
index 8c8e4dc..c8d78d9 100644
--- a/WINGs/wbutton.c
+++ b/WINGs/wbutton.c
@@ -17,6 +17,7 @@ typedef struct W_Button {
 
        W_Pixmap *image;
        W_Pixmap *altImage;
+       W_Pixmap *tsImage;
 
        W_Pixmap *dimage;
 
@@ -37,7 +38,7 @@ typedef struct W_Button {
                WMImagePosition imagePosition:4;
                WMAlignment alignment:2;
 
-               unsigned int selected:1;
+               unsigned int selected:2;
 
                unsigned int enabled:1;
 
@@ -183,6 +184,14 @@ WMButton *WMCreateButton(WMWidget * parent, WMButtonType 
type)
                bPtr->altImage = WMRetainPixmap(scrPtr->radioButtonImageOn);
                break;
 
+       case WBTTriState:
+               bPtr = WMCreateCustomButton(parent, WBBStateChangeMask);
+               bPtr->flags.bordered = 0;
+               bPtr->image = WMRetainPixmap(scrPtr->tristateButtonImageOff);
+               bPtr->altImage = WMRetainPixmap(scrPtr->tristateButtonImageOn);
+               bPtr->tsImage = WMRetainPixmap(scrPtr->tristateButtonImageTri);
+               break;
+
        default:
        case WBTMomentaryLight:
                bPtr = WMCreateCustomButton(parent, WBBSpringLoadedMask | 
WBBPushLightMask);
@@ -197,7 +206,7 @@ WMButton *WMCreateButton(WMWidget * parent, WMButtonType 
type)
                WMSetButtonText(bPtr, DEFAULT_RADIO_TEXT);
                bPtr->flags.alignment = DEFAULT_RADIO_ALIGNMENT;
                bPtr->flags.imagePosition = DEFAULT_RADIO_IMAGE_POSITION;
-       } else if (type == WBTSwitch) {
+       } else if (type == WBTSwitch || type == WBTTriState) {
                W_ResizeView(bPtr->view, DEFAULT_SWITCH_WIDTH, 
DEFAULT_SWITCH_HEIGHT);
                WMSetButtonText(bPtr, DEFAULT_SWITCH_TEXT);
                bPtr->flags.alignment = DEFAULT_SWITCH_ALIGNMENT;
@@ -371,7 +380,10 @@ void WMSetButtonDisabledTextColor(WMButton * bPtr, WMColor 
* color)
 
 void WMSetButtonSelected(WMButton * bPtr, int isSelected)
 {
-       bPtr->flags.selected = isSelected ? 1 : 0;
+       if ((bPtr->flags.type == WBTTriState) && (isSelected < 0))
+               bPtr->flags.selected = 2;
+       else
+               bPtr->flags.selected = isSelected ? 1 : 0;
 
        if (bPtr->view->flags.realized) {
                paintButton(bPtr);
@@ -384,6 +396,9 @@ int WMGetButtonSelected(WMButton * bPtr)
 {
        CHECK_CLASS(bPtr, WC_Button);
 
+       if ((bPtr->flags.type == WBTTriState) && (bPtr->flags.selected == 2))
+               return -1;
+
        return bPtr->flags.selected;
 }
 
@@ -558,7 +573,9 @@ static void paintButton(Button * bPtr)
                if (bPtr->flags.stateChange) {
                        if (bPtr->altCaption)
                                caption = bPtr->altCaption;
-                       if (bPtr->altImage)
+                       if (bPtr->flags.selected == 2)
+                               image = bPtr->tsImage;
+                       else if (bPtr->altImage)
                                image = bPtr->altImage;
                        if (bPtr->altTextColor)
                                textColor = bPtr->altTextColor;
@@ -659,6 +676,8 @@ static void handleActionEvents(XEvent * event, void *data)
 
        case ButtonPress:
                if (event->xbutton.button == Button1) {
+                       static const unsigned int next_state[4] = { [0] = 1, 
[1] = 2, [2] = 0 };
+
                        bPtr->flags.prevSelected = bPtr->flags.selected;
                        bPtr->flags.wasPushed = 0;
                        bPtr->flags.pushed = 1;
@@ -667,7 +686,10 @@ static void handleActionEvents(XEvent * event, void *data)
                                dopaint = 1;
                                break;
                        }
-                       bPtr->flags.selected = !bPtr->flags.selected;
+                       if (bPtr->flags.type == WBTTriState)
+                               bPtr->flags.selected = 
next_state[bPtr->flags.selected];
+                       else
+                               bPtr->flags.selected = !bPtr->flags.selected;
                        dopaint = 1;
 
                        if (bPtr->flags.continuous && !bPtr->timer) {
@@ -748,5 +770,8 @@ static void destroyButton(Button * bPtr)
        if (bPtr->altImage)
                WMReleasePixmap(bPtr->altImage);
 
+       if (bPtr->tsImage)
+               WMReleasePixmap(bPtr->tsImage);
+
        wfree(bPtr);
 }
diff --git a/WINGs/widgets.c b/WINGs/widgets.c
index 4c9c687..177ad3c 100644
--- a/WINGs/widgets.c
+++ b/WINGs/widgets.c
@@ -97,6 +97,66 @@ static char *RADIO_BUTTON_OFF[] = {
        ".....     .....",
 };
 
+#define TRISTATE_BUTTON_ON_WIDTH       15
+#define TRISTATE_BUTTON_ON_HEIGHT      15
+static char *TRISTATE_BUTTON_ON[] = {
+       "%%%%%%%%%%%%%%.",
+       "%%%%%%%%%%%%%. ",
+       "%%           . ",
+       "%% ##     ## . ",
+       "%% ###   ### . ",
+       "%%  ### ###  . ",
+       "%%   #####   . ",
+       "%%    ###    . ",
+       "%%   #####   . ",
+       "%%  ### ###  . ",
+       "%% ###   ### . ",
+       "%% ##     ## . ",
+       "%%           . ",
+       "%............. ",
+       ".              ",
+};
+
+#define TRISTATE_BUTTON_OFF_WIDTH      15
+#define TRISTATE_BUTTON_OFF_HEIGHT     15
+static char *TRISTATE_BUTTON_OFF[] = {
+       "%%%%%%%%%%%%%%.",
+       "%%%%%%%%%%%%%. ",
+       "%%           . ",
+       "%%           . ",
+       "%%           . ",
+       "%%           . ",
+       "%%           . ",
+       "%%           . ",
+       "%%           . ",
+       "%%           . ",
+       "%%           . ",
+       "%%           . ",
+       "%%           . ",
+       "%............. ",
+       ".              ",
+};
+
+#define TRISTATE_BUTTON_TRI_WIDTH      15
+#define TRISTATE_BUTTON_TRI_HEIGHT     15
+static char *TRISTATE_BUTTON_TRI[] = {
+       "%%%%%%%%%%%%%%.",
+       "%%%%%%%%%%%%%. ",
+       "%%           . ",
+       "%% # # # # # . ",
+       "%%  # # # #  . ",
+       "%% # # # # # . ",
+       "%%  # # # #  . ",
+       "%% # # # # # . ",
+       "%%  # # # #  . ",
+       "%% # # # # # . ",
+       "%%  # # # #  . ",
+       "%% # # # # # . ",
+       "%%           . ",
+       "%............. ",
+       ".              ",
+};
+
 static char *BUTTON_ARROW[] = {
        "..................",
        "....##....#### ...",
@@ -729,6 +789,15 @@ WMScreen *WMCreateScreenWithRContext(Display * display, 
int screen, RContext * c
        scrPtr->radioButtonImageOff = makePixmap(scrPtr, RADIO_BUTTON_OFF,
                                                 RADIO_BUTTON_OFF_WIDTH, 
RADIO_BUTTON_OFF_HEIGHT, False);
 
+       scrPtr->tristateButtonImageOn = makePixmap(scrPtr, TRISTATE_BUTTON_ON,
+                                                  TRISTATE_BUTTON_ON_WIDTH, 
TRISTATE_BUTTON_ON_HEIGHT, False);
+
+       scrPtr->tristateButtonImageOff = makePixmap(scrPtr, TRISTATE_BUTTON_OFF,
+                                                   TRISTATE_BUTTON_OFF_WIDTH, 
TRISTATE_BUTTON_OFF_HEIGHT, False);
+
+       scrPtr->tristateButtonImageTri = makePixmap(scrPtr, TRISTATE_BUTTON_TRI,
+                                                   TRISTATE_BUTTON_TRI_WIDTH, 
TRISTATE_BUTTON_TRI_HEIGHT, False);
+
        scrPtr->buttonArrow = makePixmap(scrPtr, BUTTON_ARROW, 
BUTTON_ARROW_WIDTH, BUTTON_ARROW_HEIGHT, False);
 
        scrPtr->pushedButtonArrow = makePixmap(scrPtr, BUTTON_ARROW2,

http://repo.or.cz/w/wmaker-crm.git/commit/997b3e5d91f4194fa592c72a71ca29496014ba99

commit 997b3e5d91f4194fa592c72a71ca29496014ba99
Author: Christophe CURIS <[email protected]>
Date:   Sun May 10 19:56:04 2015 +0200

    wmaker: honour MWM Hint to have no border to a window
    
    As there is already an attribute to allow changing this behaviour, and this
    is being using for the Net WM hints, there is no reason to not support it
    for MWM Hints also; contrary to the initial guess suggested by the comment
    it costs actually nothing to properly support that.
    
    Signed-off-by: Christophe CURIS <[email protected]>

diff --git a/src/motif.c b/src/motif.c
index 6537038..34f6847 100644
--- a/src/motif.c
+++ b/src/motif.c
@@ -93,13 +93,7 @@ static void setupMWMHints(WWindow *wwin, MWMHints *mwm_hints)
                }
 
                if (mwm_hints->decorations & MWM_DECOR_BORDER) {
-                       /*
-                        * WindowMaker is drawing only a discreet 1 pixel 
border without
-                        * any decoration like a few other X window managers 
used to do, so
-                        * we assume it is not worth spending the time to add 
extra
-                        * complexity to handle this special request, 
considering also that
-                        * the Motif toolkit is not used anymore nowadays.
-                        */
+                       wwin->client_flags.no_border = 0;
                }
 
                if (mwm_hints->decorations & MWM_DECOR_RESIZEH)

http://repo.or.cz/w/wmaker-crm.git/commit/fd1dd9c7eae188aa67bb3592b4f0037bdafc8ef9

commit fd1dd9c7eae188aa67bb3592b4f0037bdafc8ef9
Author: Christophe CURIS <[email protected]>
Date:   Sun May 10 19:56:03 2015 +0200

    wmaker: fix misuse of 'user_flags' instead of 'client_flags' for window 
attributes
    
    The structure containing the information on windows contains 2 sets of
    attributes, client_flags which contains those asked by the application
    through Hints (like MWM Hints and others) and user_flags which was defined
    to allow the user to override them.
    
    Unfortunately many places of the code was using the wrong structure to save
    the attributes to (for example by using the WSETUFLAG macro) which was
    merely ok as the user_flags have priority, but when we want to provide a
    clean consistent behaviour to users, we need to get things in the right
    place.
    
    Signed-off-by: Christophe CURIS <[email protected]>

diff --git a/src/client.c b/src/client.c
index 9af875c..92912b9 100644
--- a/src/client.c
+++ b/src/client.c
@@ -524,14 +524,14 @@ void wClientCheckProperty(WWindow * wwin, XPropertyEvent 
* event)
                                wwin->transient_for = new_owner;
                                if (new_owner == None) {
                                        if (WFLAGP(wwin, no_miniaturizable)) {
-                                               WSETUFLAG(wwin, 
no_miniaturizable, 0);
-                                               WSETUFLAG(wwin, 
no_miniaturize_button, 0);
+                                               
wwin->client_flags.no_miniaturizable = 0;
+                                               
wwin->client_flags.no_miniaturize_button = 0;
                                                if (wwin->frame)
                                                        
wWindowConfigureBorders(wwin);
                                        }
                                } else if (!WFLAGP(wwin, no_miniaturizable)) {
-                                       WSETUFLAG(wwin, no_miniaturizable, 1);
-                                       WSETUFLAG(wwin, no_miniaturize_button, 
1);
+                                       wwin->client_flags.no_miniaturizable = 
1;
+                                       
wwin->client_flags.no_miniaturize_button = 1;
                                        if (wwin->frame)
                                                wWindowConfigureBorders(wwin);
                                }
@@ -544,7 +544,7 @@ void wClientCheckProperty(WWindow * wwin, XPropertyEvent * 
event)
 
                        PropGetProtocols(wwin->client_win, &wwin->protocols);
 
-                       WSETUFLAG(wwin, kill_close, 
!wwin->protocols.DELETE_WINDOW);
+                       wwin->client_flags.kill_close = 
!wwin->protocols.DELETE_WINDOW;
 
                        if (wwin->frame)
                                wWindowUpdateButtonImages(wwin);
@@ -572,7 +572,7 @@ void wClientCheckProperty(WWindow * wwin, XPropertyEvent * 
event)
                                        wApplicationDestroy(wapp);
                                        while (foo) {
                                                if (foo->fake_group && 
foo->fake_group == fPtr) {
-                                                       WSETUFLAG(foo, 
shared_appicon, 0);
+                                                       
foo->client_flags.shared_appicon = 0;
                                                        foo->fake_group = NULL;
 
                                                        if (foo->group_id != 
None)
diff --git a/src/motif.c b/src/motif.c
index b649f82..6537038 100644
--- a/src/motif.c
+++ b/src/motif.c
@@ -75,19 +75,21 @@ static void setupMWMHints(WWindow *wwin, MWMHints 
*mwm_hints)
         */
 
        if (mwm_hints->flags & MWM_HINTS_DECORATIONS) {
-               WSETUFLAG(wwin, no_titlebar, 1);
-               WSETUFLAG(wwin, no_close_button, 1);
-               WSETUFLAG(wwin, no_miniaturize_button, 1);
-               WSETUFLAG(wwin, no_resizebar, 1);
+               wwin->client_flags.no_titlebar = 1;
+               wwin->client_flags.no_close_button = 1;
+               wwin->client_flags.no_miniaturize_button = 1;
+               wwin->client_flags.no_resizebar = 1;
+               wwin->client_flags.no_border = 1;
 
                if (mwm_hints->decorations & MWM_DECOR_ALL) {
-                       WSETUFLAG(wwin, no_titlebar, 0);
-                       WSETUFLAG(wwin, no_close_button, 0);
-                       WSETUFLAG(wwin, no_closable, 0);
-                       WSETUFLAG(wwin, no_miniaturize_button, 0);
-                       WSETUFLAG(wwin, no_miniaturizable, 0);
-                       WSETUFLAG(wwin, no_resizebar, 0);
-                       WSETUFLAG(wwin, no_resizable, 0);
+                       wwin->client_flags.no_titlebar = 0;
+                       wwin->client_flags.no_close_button = 0;
+                       wwin->client_flags.no_closable = 0;
+                       wwin->client_flags.no_miniaturize_button = 0;
+                       wwin->client_flags.no_miniaturizable = 0;
+                       wwin->client_flags.no_resizebar = 0;
+                       wwin->client_flags.no_resizable = 0;
+                       wwin->client_flags.no_border = 0;
                }
 
                if (mwm_hints->decorations & MWM_DECOR_BORDER) {
@@ -101,12 +103,12 @@ static void setupMWMHints(WWindow *wwin, MWMHints 
*mwm_hints)
                }
 
                if (mwm_hints->decorations & MWM_DECOR_RESIZEH)
-                       WSETUFLAG(wwin, no_resizebar, 0);
+                       wwin->client_flags.no_resizebar = 0;
 
                if (mwm_hints->decorations & MWM_DECOR_TITLE) {
-                       WSETUFLAG(wwin, no_titlebar, 0);
-                       WSETUFLAG(wwin, no_close_button, 0);
-                       WSETUFLAG(wwin, no_closable, 0);
+                       wwin->client_flags.no_titlebar = 0;
+                       wwin->client_flags.no_close_button = 0;
+                       wwin->client_flags.no_closable = 0;
                }
 
                if (mwm_hints->decorations * MWM_DECOR_MENU) {
@@ -119,8 +121,8 @@ static void setupMWMHints(WWindow *wwin, MWMHints 
*mwm_hints)
                }
 
                if (mwm_hints->decorations & MWM_DECOR_MINIMIZE) {
-                       WSETUFLAG(wwin, no_miniaturize_button, 0);
-                       WSETUFLAG(wwin, no_miniaturizable, 0);
+                       wwin->client_flags.no_miniaturize_button = 0;
+                       wwin->client_flags.no_miniaturizable = 0;
                }
 
                if (mwm_hints->decorations & MWM_DECOR_MAXIMIZE) {
@@ -132,17 +134,17 @@ static void setupMWMHints(WWindow *wwin, MWMHints 
*mwm_hints)
        }
 
        if (mwm_hints->flags & MWM_HINTS_FUNCTIONS) {
-               WSETUFLAG(wwin, no_closable, 1);
-               WSETUFLAG(wwin, no_miniaturizable, 1);
-               WSETUFLAG(wwin, no_resizable, 1);
+               wwin->client_flags.no_closable = 1;
+               wwin->client_flags.no_miniaturizable = 1;
+               wwin->client_flags.no_resizable = 1;
 
                if (mwm_hints->functions & MWM_FUNC_ALL) {
-                       WSETUFLAG(wwin, no_closable, 0);
-                       WSETUFLAG(wwin, no_miniaturizable, 0);
-                       WSETUFLAG(wwin, no_resizable, 0);
+                       wwin->client_flags.no_closable = 0;
+                       wwin->client_flags.no_miniaturizable = 0;
+                       wwin->client_flags.no_resizable = 0;
                }
                if (mwm_hints->functions & MWM_FUNC_RESIZE)
-                       WSETUFLAG(wwin, no_resizable, 0);
+                       wwin->client_flags.no_resizable = 0;
 
                if (mwm_hints->functions & MWM_FUNC_MOVE) {
                        /*
@@ -152,14 +154,14 @@ static void setupMWMHints(WWindow *wwin, MWMHints 
*mwm_hints)
                }
 
                if (mwm_hints->functions & MWM_FUNC_MINIMIZE)
-                       WSETUFLAG(wwin, no_miniaturizable, 0);
+                       wwin->client_flags.no_miniaturizable = 0;
 
                if (mwm_hints->functions & MWM_FUNC_MAXIMIZE) {
                        /* a window must be resizable to be maximizable */
-                       WSETUFLAG(wwin, no_resizable, 0);
+                       wwin->client_flags.no_resizable = 0;
                }
                if (mwm_hints->functions & MWM_FUNC_CLOSE)
-                       WSETUFLAG(wwin, no_closable, 0);
+                       wwin->client_flags.no_closable = 0;
        }
 }
 
diff --git a/src/window.c b/src/window.c
index 7cbad9c..b1cbd30 100644
--- a/src/window.c
+++ b/src/window.c
@@ -293,7 +293,9 @@ void wWindowSetupInitialAttributes(WWindow *wwin, int 
*level, int *workspace)
        WScreen *scr = wwin->screen_ptr;
 
        /* sets global default stuff */
-       wDefaultFillAttributes(wwin->wm_instance, wwin->wm_class, 
&wwin->client_flags, NULL, True);
+       wDefaultFillAttributes(wwin->wm_instance, wwin->wm_class, 
&wwin->user_flags, NULL, True);
+       wwin->defined_user_flags = wwin->user_flags;
+
        /*
         * Decoration setting is done in this precedence (lower to higher)
         * - use global default in the resource database
@@ -302,25 +304,25 @@ void wWindowSetupInitialAttributes(WWindow *wwin, int 
*level, int *workspace)
         * - set hints specified for the app in the resource DB
         *
         */
-       WSETUFLAG(wwin, broken_close, 0);
+       wwin->client_flags.broken_close = 0;
 
        if (wwin->protocols.DELETE_WINDOW)
-               WSETUFLAG(wwin, kill_close, 0);
+               wwin->client_flags.kill_close = 0;
        else
-               WSETUFLAG(wwin, kill_close, 1);
+               wwin->client_flags.kill_close = 1;
 
        /* transients can't be iconified or maximized */
        if (wwin->transient_for != None && wwin->transient_for != 
scr->root_win) {
-               WSETUFLAG(wwin, no_miniaturizable, 1);
-               WSETUFLAG(wwin, no_miniaturize_button, 1);
+               wwin->client_flags.no_miniaturizable = 1;
+               wwin->client_flags.no_miniaturize_button = 1;
        }
 
        /* if the window can't be resized, remove the resizebar */
        if (wwin->normal_hints->flags & (PMinSize | PMaxSize)
            && (wwin->normal_hints->min_width == wwin->normal_hints->max_width)
            && (wwin->normal_hints->min_height == 
wwin->normal_hints->max_height)) {
-               WSETUFLAG(wwin, no_resizable, 1);
-               WSETUFLAG(wwin, no_resizebar, 1);
+               wwin->client_flags.no_resizable = 1;
+               wwin->client_flags.no_resizebar = 1;
        }
 
        /* set GNUstep window attributes */
@@ -401,7 +403,9 @@ void wWindowSetupInitialAttributes(WWindow *wwin, int 
*level, int *workspace)
            && wwin->user_flags.floating && wwin->defined_user_flags.floating)
                wwin->user_flags.sunken = 0;
 
-       WSETUFLAG(wwin, no_shadeable, WFLAGP(wwin, no_titlebar));
+       /* A window that does not have a title cannot be Shaded and we don't 
let user override this */
+       wwin->client_flags.no_shadeable = WFLAGP(wwin, no_titlebar);
+       wwin->defined_user_flags.no_shadeable = 0;
 
        /* windows that have takefocus=False shouldn't take focus at all */
        if (wwin->focus_mode == WFM_NO_INPUT)
@@ -724,22 +728,22 @@ WWindow *wManageWindow(WScreen *scr, Window window)
        wwin->orig_main_window = wwin->main_window;
 
        if (wwin->flags.is_gnustep)
-               WSETUFLAG(wwin, shared_appicon, 0);
+               wwin->client_flags.shared_appicon = 0;
 
        if (wwin->main_window) {
                XTextProperty text_prop;
 
                if (XGetTextProperty(dpy, wwin->main_window, &text_prop, 
w_global.atom.wmaker.menu))
-                       WSETUFLAG(wwin, shared_appicon, 0);
+                       wwin->client_flags.shared_appicon = 0;
        }
 
        if (wwin->flags.is_dockapp)
-               WSETUFLAG(wwin, shared_appicon, 0);
+               wwin->client_flags.shared_appicon = 0;
 
        if (wwin->main_window) {
             WApplication *app = wApplicationOf(wwin->main_window);
             if (app && app->app_icon)
-               WSETUFLAG(wwin, shared_appicon, 0);
+               wwin->client_flags.shared_appicon = 0;
         }
 
        if (!withdraw && wwin->main_window && WFLAGP(wwin, shared_appicon)) {
@@ -1320,10 +1324,10 @@ WWindow *wManageInternalWindow(WScreen *scr, Window 
window, Window owner,
 
        wwin->flags.internal_window = 1;
 
-       WSETUFLAG(wwin, omnipresent, 1);
-       WSETUFLAG(wwin, no_shadeable, 1);
-       WSETUFLAG(wwin, no_resizable, 1);
-       WSETUFLAG(wwin, no_miniaturizable, 1);
+       wwin->client_flags.omnipresent = 1;
+       wwin->client_flags.no_shadeable = 1;
+       wwin->client_flags.no_resizable = 1;
+       wwin->client_flags.no_miniaturizable = 1;
 
        wwin->focus_mode = WFM_PASSIVE;
        wwin->client_win = window;
diff --git a/src/winspector.c b/src/winspector.c
index f6b1d5c..0d6d57d 100644
--- a/src/winspector.c
+++ b/src/winspector.c
@@ -1241,8 +1241,8 @@ static InspectorPanel *createInspectorForWindow(WWindow 
*wwin, int xpos, int ypo
        /* kluge to know who should get the key events */
        panel->frame->client_leader = WMWidgetXID(panel->win);
 
-       WSETUFLAG(panel->frame, no_closable, 0);
-       WSETUFLAG(panel->frame, no_close_button, 0);
+       panel->frame->client_flags.no_closable = 0;
+       panel->frame->client_flags.no_close_button = 0;
        wWindowUpdateButtonImages(panel->frame);
        wFrameWindowShowButton(panel->frame->frame, WFF_RIGHT_BUTTON);
        panel->frame->frame->on_click_right = destroyInspector;

http://repo.or.cz/w/wmaker-crm.git/commit/a8f6abc9ea0350ddfc0b6b4a76cb92be4c89a1b0

commit a8f6abc9ea0350ddfc0b6b4a76cb92be4c89a1b0
Author: Christophe CURIS <[email protected]>
Date:   Sun May 10 19:56:02 2015 +0200

    wmaker: moved the list of Application Attributes into an array, for the 
Window Inspector
    
    The Window Inspector is used to let user change a list of advanced options
    for all the windows of an application. This list was defined through many
    hard-coded things; by defining an array with everything at the beginning of
    the file it is easier to maintain (the code is simpler because it is more
    generic) and to make it evolve.
    
    Signed-off-by: Christophe CURIS <[email protected]>

diff --git a/src/winspector.c b/src/winspector.c
index 563eb70..f6b1d5c 100644
--- a/src/winspector.c
+++ b/src/winspector.c
@@ -162,6 +162,20 @@ static const struct {
        ,{ "NoLanguageButton", { .no_language_button = 1 }, N_("Disable 
language button"),
           N_("Remove the `toggle language' button of the window.") }
 #endif
+
+}, application_attr[] = {
+       { "StartHidden", { .start_hidden = 1 }, N_("Start hidden"),
+         N_("Automatically hide application when it's started.") },
+
+       { "NoAppIcon", { .no_appicon = 1 }, N_("No application icon"),
+         N_("Disable the application icon for the application.\n"
+            "Note that you won't be able to dock it anymore,\n"
+            "and any icons that are already docked will stop\n"
+            "working correctly.") },
+
+       { "SharedAppIcon", { .shared_appicon = 1 }, N_("Shared application 
icon"),
+         N_("Use a single shared application icon for all of\n"
+            "the instances of this application.\n") }
 };
 
 typedef struct InspectorPanel {
@@ -207,7 +221,7 @@ typedef struct InspectorPanel {
 
        /* 5th page. application wide attributes */
        WMFrame *appFrm;
-       WMButton *appChk[3];
+       WMButton *appChk[sizeof(application_attr) / 
sizeof(application_attr[0])];
 
        unsigned int done:1;
        unsigned int destroyed:1;
@@ -225,15 +239,13 @@ static InspectorPanel *panelList = NULL;
  */
 static WMPropList *pl_attribute[sizeof(window_attribute) / 
sizeof(window_attribute[0])] = { [0] = NULL };
 static WMPropList *pl_advoptions[sizeof(advanced_option) / 
sizeof(advanced_option[0])];
+static WMPropList *pl_appattrib[sizeof(application_attr) / 
sizeof(application_attr[0])];
 
-static WMPropList *ANoAppIcon;
 static WMPropList *AAlwaysUserIcon;
-static WMPropList *ASharedAppIcon;
 static WMPropList *AStartWorkspace;
 static WMPropList *AIcon;
 
 /* application wide options */
-static WMPropList *AStartHidden;
 static WMPropList *AnyWindow;
 static WMPropList *EmptyString;
 static WMPropList *Yes, *No;
@@ -311,11 +323,11 @@ static void make_keys(void)
        for (i = 0; i < wlengthof(advanced_option); i++)
                pl_advoptions[i] = 
WMCreatePLString(advanced_option[i].key_name);
 
+       for (i = 0; i < wlengthof(application_attr); i++)
+               pl_appattrib[i] = 
WMCreatePLString(application_attr[i].key_name);
+
        AIcon = WMCreatePLString("Icon");
-       ANoAppIcon = WMCreatePLString("NoAppIcon");
        AAlwaysUserIcon = WMCreatePLString("AlwaysUserIcon");
-       AStartHidden = WMCreatePLString("StartHidden");
-       ASharedAppIcon = WMCreatePLString("SharedAppIcon");
 
        AStartWorkspace = WMCreatePLString("StartWorkspace");
 
@@ -640,15 +652,12 @@ static void saveSettings(WMWidget *button, void 
*client_data)
                different |= insertAttribute(dict, winDic, pl_advoptions[i], 
value, flags);
        }
 
+       /* Attributes... --> Application Specific */
        if (wwin->main_window != None && wApplicationOf(wwin->main_window) != 
NULL) {
-               value = (WMGetButtonSelected(panel->appChk[0]) != 0) ? Yes : No;
-               different2 |= insertAttribute(dict, appDic, AStartHidden, 
value, flags);
-
-               value = (WMGetButtonSelected(panel->appChk[1]) != 0) ? Yes : No;
-               different2 |= insertAttribute(dict, appDic, ANoAppIcon, value, 
flags);
-
-               value = (WMGetButtonSelected(panel->appChk[2]) != 0) ? Yes : No;
-               different2 |= insertAttribute(dict, appDic, ASharedAppIcon, 
value, flags);
+               for (i = 0; i < wlengthof(application_attr); i++) {
+                       value = (WMGetButtonSelected(panel->appChk[i]) != 0) ? 
Yes : No;
+                       different2 |= insertAttribute(dict, appDic, 
pl_appattrib[i], value, flags);
+               }
        }
 
        if (wwin->fake_group) {
@@ -780,9 +789,14 @@ static void applySettings(WMWidget *button, void 
*client_data)
        /* Can't apply emulate_appicon because it will probably cause problems. 
*/
        if (wapp) {
                /* do application wide stuff */
-               WSETUFLAG(wapp->main_window_desc, start_hidden, 
WMGetButtonSelected(panel->appChk[0]));
-               WSETUFLAG(wapp->main_window_desc, no_appicon, 
WMGetButtonSelected(panel->appChk[1]));
-               WSETUFLAG(wapp->main_window_desc, shared_appicon, 
WMGetButtonSelected(panel->appChk[2]));
+               for (i = 0; i < wlengthof(application_attr); i++) {
+                       if (WMGetButtonSelected(panel->appChk[i]))
+                               
set_attr_flag(&wapp->main_window_desc->user_flags, &application_attr[i].flag);
+                       else
+                               
clear_attr_flag(&wapp->main_window_desc->user_flags, &application_attr[i].flag);
+
+                       
set_attr_flag(&wapp->main_window_desc->defined_user_flags, 
&application_attr[i].flag);
+               }
 
                if (WFLAGP(wapp->main_window_desc, no_appicon))
                        unpaint_app_icon(wapp);
@@ -907,21 +921,18 @@ static void revertSettings(WMWidget *button, void 
*client_data)
 
                WMSetButtonSelected(panel->moreChk[i], flag);
        }
+
+       /* Attributes... --> Application Specific */
        if (panel->appFrm && wapp) {
-               for (i = 0; i < wlengthof(panel->appChk); i++) {
-                       int flag = 0;
-
-                       switch (i) {
-                       case 0:
-                               flag = WFLAGP(wapp->main_window_desc, 
start_hidden);
-                               break;
-                       case 1:
-                               flag = WFLAGP(wapp->main_window_desc, 
no_appicon);
-                               break;
-                       case 2:
-                               flag = WFLAGP(wapp->main_window_desc, 
shared_appicon);
-                               break;
-                       }
+               for (i = 0; i < wlengthof(application_attr); i++) {
+                       int is_userdef, flag = 0;
+
+                       is_userdef = 
get_attr_flag(&wapp->main_window_desc->defined_user_flags, 
&application_attr[i].flag);
+                       if (is_userdef)
+                               flag = 
get_attr_flag(&wapp->main_window_desc->user_flags, &application_attr[i].flag);
+                       else
+                               flag = 
get_attr_flag(&wapp->main_window_desc->client_flags, &application_attr[i].flag);
+
                        WMSetButtonSelected(panel->appChk[i], flag);
                }
        }
@@ -1414,9 +1425,7 @@ static void create_tab_icon_workspace(WWindow *wwin, 
InspectorPanel *panel)
 static void create_tab_app_specific(WWindow *wwin, InspectorPanel *panel, int 
frame_width)
 {
        WScreen *scr = wwin->screen_ptr;
-       int i = 0, flag = 0, tmp;
-       char *caption = NULL, *descr = NULL;
-
+       int i = 0, tmp;
 
        if (wwin->main_window != None) {
                WApplication *wapp = wApplicationOf(wwin->main_window);
@@ -1426,34 +1435,23 @@ static void create_tab_app_specific(WWindow *wwin, 
InspectorPanel *panel, int fr
                WMMoveWidget(panel->appFrm, 15, 50);
                WMResizeWidget(panel->appFrm, frame_width, 240);
 
-               for (i = 0; i < wlengthof(panel->appChk); i++) {
-                       switch (i) {
-                       case 0:
-                               caption = _("Start hidden");
-                               flag = WFLAGP(wapp->main_window_desc, 
start_hidden);
-                               descr = _("Automatically hide application when 
it's started.");
-                               break;
-                       case 1:
-                               caption = _("No application icon");
-                               flag = WFLAGP(wapp->main_window_desc, 
no_appicon);
-                               descr = _("Disable the application icon for the 
application.\n"
-                                         "Note that you won't be able to dock 
it anymore,\n"
-                                         "and any icons that are already 
docked will stop\n"
-                                         "working correctly.");
-                               break;
-                       case 2:
-                               caption = _("Shared application icon");
-                               flag = WFLAGP(wapp->main_window_desc, 
shared_appicon);
-                               descr = _("Use a single shared application icon 
for all of\n"
-                                         "the instances of this 
application.\n");
-                               break;
-                       }
+               for (i = 0; i < wlengthof(application_attr); i++) {
+                       int is_userdef, flag;
+
+                       is_userdef = 
get_attr_flag(&wapp->main_window_desc->defined_user_flags, 
&application_attr[i].flag);
+                       if (is_userdef)
+                               flag = 
get_attr_flag(&wapp->main_window_desc->user_flags, &application_attr[i].flag);
+                       else
+                               flag = 
get_attr_flag(&wapp->main_window_desc->client_flags, &application_attr[i].flag);
+
                        panel->appChk[i] = WMCreateSwitchButton(panel->appFrm);
                        WMMoveWidget(panel->appChk[i], 10, 20 * (i + 1));
                        WMResizeWidget(panel->appChk[i], 205, 20);
                        WMSetButtonSelected(panel->appChk[i], flag);
-                       WMSetButtonText(panel->appChk[i], caption);
-                       WMSetBalloonTextForView(descr, 
WMWidgetView(panel->appChk[i]));
+                       WMSetButtonText(panel->appChk[i], 
_(application_attr[i].caption));
+
+                       
WMSetBalloonTextForView(_(application_attr[i].description),
+                                               WMWidgetView(panel->appChk[i]));
                }
 
                if (WFLAGP(wwin, emulate_appicon)) {

http://repo.or.cz/w/wmaker-crm.git/commit/8276ff13310a06e79a17c50bbe2602724cf68386

commit 8276ff13310a06e79a17c50bbe2602724cf68386
Author: Christophe CURIS <[email protected]>
Date:   Sun May 10 19:56:01 2015 +0200

    wmaker: moved the list of Advanced Options into an array, for the Window 
Inspector
    
    The Window Inspector is used to let user change a list of advanced options
    for a window. This list was defined through many hard-coded things; by
    defining an array with everything at the beginning of the file it is easier
    to maintain (the code is simpler because it is more generic) and to make it
    evolve in the future.
    
    Signed-off-by: Christophe CURIS <[email protected]>

diff --git a/src/winspector.c b/src/winspector.c
index ff5e26f..563eb70 100644
--- a/src/winspector.c
+++ b/src/winspector.c
@@ -108,6 +108,60 @@ static const struct {
          N_("Make the window use the whole screen space when it's\n"
                                  "maximized. The titlebar and resizebar will 
be moved\n"
                                  "to outside the screen.") }
+
+}, advanced_option[] = {
+       { "NoKeyBindings", { .no_bind_keys = 1 }, N_("Do not bind keyboard 
shortcuts"),
+         N_("Do not bind keyboard shortcuts from Window Maker\n"
+            "when this window is focused. This will allow the\n"
+            "window to receive all key combinations regardless\n"
+            "of your shortcut configuration.") },
+
+       { "NoMouseBindings", { .no_bind_mouse = 1 }, N_("Do not bind mouse 
clicks"),
+         N_("Do not bind mouse actions, such as `Alt'+drag\n"
+            "in the window (when Alt is the modifier you have\n"
+            "configured).") },
+
+       { "SkipWindowList", { .skip_window_list = 1 }, N_("Do not show in the 
window list"),
+         N_("Do not list the window in the window list menu.") },
+
+       { "SkipSwitchPanel", { .skip_switchpanel = 1 }, N_("Do not show in the 
switch panel"),
+         N_("Do not include in switch panel while cycling windows.") },
+
+       { "Unfocusable", { .no_focusable = 1 }, N_("Do not let it take focus"),
+         N_("Do not let the window take keyboard focus when you\n"
+            "click on it.") },
+
+       { "KeepInsideScreen", { .dont_move_off = 1 }, N_("Keep inside screen"),
+         N_("Do not allow the window to move itself completely\n"
+            "outside the screen. For bug compatibility.\n") },
+
+       { "NoHideOthers", { .no_hide_others = 1 }, N_("Ignore 'Hide Others'"),
+         N_("Do not hide the window when issuing the\n"
+            "`HideOthers' command.") },
+
+       { "DontSaveSession", { .dont_save_session = 1 }, N_("Ignore 'Save 
Session'"),
+         N_("Do not save the associated application in the\n"
+            "session's state, so that it won't be restarted\n"
+            "together with other applications when Window Maker\n"
+            "starts.") },
+
+       { "EmulateAppIcon", { .emulate_appicon = 1 }, N_("Emulate application 
icon"),
+         N_("Make this window act as an application that provides\n"
+            "enough information to Window Maker for a dockable\n"
+            "application icon to be created.") },
+
+       { "FocusAcrossWorkspace", { .focus_across_wksp = 1 }, N_("Focus across 
workspaces"),
+         N_("Allow Window Maker to switch workspace to satisfy\n"
+            "a focus request (annoying).") },
+
+       { "NoMiniaturizable", { .no_miniaturizable = 1 }, N_("Do not let it be 
minimized"),
+         N_("Do not let the window of this application be\n"
+            "minimized.\n") }
+
+#ifdef XKB_BUTTON_HINT
+       ,{ "NoLanguageButton", { .no_language_button = 1 }, N_("Disable 
language button"),
+          N_("Remove the `toggle language' button of the window.") }
+#endif
 };
 
 typedef struct InspectorPanel {
@@ -139,11 +193,7 @@ typedef struct InspectorPanel {
 
        /* 3rd page. more attributes */
        WMFrame *moreFrm;
-#ifdef XKB_BUTTON_HINT
-       WMButton *moreChk[12];
-#else
-       WMButton *moreChk[11];
-#endif
+       WMButton *moreChk[sizeof(advanced_option) / sizeof(advanced_option[0])];
 
        /* 4th page. icon and workspace */
        WMFrame *iconFrm;
@@ -174,24 +224,11 @@ static InspectorPanel *panelList = NULL;
  * one everytime.
  */
 static WMPropList *pl_attribute[sizeof(window_attribute) / 
sizeof(window_attribute[0])] = { [0] = NULL };
+static WMPropList *pl_advoptions[sizeof(advanced_option) / 
sizeof(advanced_option[0])];
 
-static WMPropList *ANoHideOthers;
-static WMPropList *ANoMouseBindings;
-static WMPropList *ANoKeyBindings;
 static WMPropList *ANoAppIcon;
-static WMPropList *ASkipWindowList;
-static WMPropList *ASkipSwitchPanel;
-static WMPropList *AKeepInsideScreen;
-static WMPropList *AUnfocusable;
-static WMPropList *AFocusAcrossWorkspace;
 static WMPropList *AAlwaysUserIcon;
-static WMPropList *ADontSaveSession;
-static WMPropList *AEmulateAppIcon;
 static WMPropList *ASharedAppIcon;
-static WMPropList *ANoMiniaturizable;
-#ifdef XKB_BUTTON_HINT
-static WMPropList *ANoLanguageButton;
-#endif
 static WMPropList *AStartWorkspace;
 static WMPropList *AIcon;
 
@@ -271,26 +308,14 @@ static void make_keys(void)
        for (i = 0; i < wlengthof(window_attribute); i++)
                pl_attribute[i] = 
WMCreatePLString(window_attribute[i].key_name);
 
+       for (i = 0; i < wlengthof(advanced_option); i++)
+               pl_advoptions[i] = 
WMCreatePLString(advanced_option[i].key_name);
 
        AIcon = WMCreatePLString("Icon");
-       ANoHideOthers = WMCreatePLString("NoHideOthers");
-       ANoMouseBindings = WMCreatePLString("NoMouseBindings");
-       ANoKeyBindings = WMCreatePLString("NoKeyBindings");
        ANoAppIcon = WMCreatePLString("NoAppIcon");
-       ASkipWindowList = WMCreatePLString("SkipWindowList");
-       ASkipSwitchPanel = WMCreatePLString("SkipSwitchPanel");
-       AKeepInsideScreen = WMCreatePLString("KeepInsideScreen");
-       AUnfocusable = WMCreatePLString("Unfocusable");
-       AFocusAcrossWorkspace = WMCreatePLString("FocusAcrossWorkspace");
        AAlwaysUserIcon = WMCreatePLString("AlwaysUserIcon");
        AStartHidden = WMCreatePLString("StartHidden");
-       ADontSaveSession = WMCreatePLString("DontSaveSession");
-       AEmulateAppIcon = WMCreatePLString("EmulateAppIcon");
        ASharedAppIcon = WMCreatePLString("SharedAppIcon");
-       ANoMiniaturizable = WMCreatePLString("NoMiniaturizable");
-#ifdef XKB_BUTTON_HINT
-       ANoLanguageButton = WMCreatePLString("NoLanguageButton");
-#endif
 
        AStartWorkspace = WMCreatePLString("StartWorkspace");
 
@@ -609,43 +634,11 @@ static void saveSettings(WMWidget *button, void 
*client_data)
                different |= insertAttribute(dict, winDic, pl_attribute[i], 
value, flags);
        }
 
-       value = (WMGetButtonSelected(panel->moreChk[0]) != 0) ? Yes : No;
-       different |= insertAttribute(dict, winDic, ANoKeyBindings, value, 
flags);
-
-       value = (WMGetButtonSelected(panel->moreChk[1]) != 0) ? Yes : No;
-       different |= insertAttribute(dict, winDic, ANoMouseBindings, value, 
flags);
-
-       value = (WMGetButtonSelected(panel->moreChk[2]) != 0) ? Yes : No;
-       different |= insertAttribute(dict, winDic, ASkipWindowList, value, 
flags);
-
-       value = (WMGetButtonSelected(panel->moreChk[3]) != 0) ? Yes : No;
-       different |= insertAttribute(dict, winDic, ASkipSwitchPanel, value, 
flags);
-
-       value = (WMGetButtonSelected(panel->moreChk[4]) != 0) ? Yes : No;
-       different |= insertAttribute(dict, winDic, AUnfocusable, value, flags);
-
-       value = (WMGetButtonSelected(panel->moreChk[5]) != 0) ? Yes : No;
-       different |= insertAttribute(dict, winDic, AKeepInsideScreen, value, 
flags);
-
-       value = (WMGetButtonSelected(panel->moreChk[6]) != 0) ? Yes : No;
-       different |= insertAttribute(dict, winDic, ANoHideOthers, value, flags);
-
-       value = (WMGetButtonSelected(panel->moreChk[7]) != 0) ? Yes : No;
-       different |= insertAttribute(dict, winDic, ADontSaveSession, value, 
flags);
-
-       value = (WMGetButtonSelected(panel->moreChk[8]) != 0) ? Yes : No;
-       different |= insertAttribute(dict, winDic, AEmulateAppIcon, value, 
flags);
-
-       value = (WMGetButtonSelected(panel->moreChk[9]) != 0) ? Yes : No;
-       different |= insertAttribute(dict, winDic, AFocusAcrossWorkspace, 
value, flags);
-
-       value = (WMGetButtonSelected(panel->moreChk[10]) != 0) ? Yes : No;
-       different |= insertAttribute(dict, winDic, ANoMiniaturizable, value, 
flags);
-
-#ifdef XKB_BUTTON_HINT
-       value = (WMGetButtonSelected(panel->moreChk[11]) != 0) ? Yes : No;
-       different |= insertAttribute(dict, winDic, ANoLanguageButton, value, 
flags);
-#endif
+       /* Attributes... --> Advanced Options */
+       for (i = 0; i < wlengthof(advanced_option); i++) {
+               value = (WMGetButtonSelected(panel->moreChk[i]) != 0) ? Yes : 
No;
+               different |= insertAttribute(dict, winDic, pl_advoptions[i], 
value, flags);
+       }
 
        if (wwin->main_window != None && wApplicationOf(wwin->main_window) != 
NULL) {
                value = (WMGetButtonSelected(panel->appChk[0]) != 0) ? Yes : No;
@@ -712,10 +705,10 @@ static void applySettings(WMWidget *button, void 
*client_data)
        InspectorPanel *panel = (InspectorPanel *) client_data;
        WWindow *wwin = panel->inspected;
        WApplication *wapp = wApplicationOf(wwin->main_window);
-       int skip_window_list;
-       int old_omnipresent, old_no_bind_keys, old_no_bind_mouse;
+       int old_skip_window_list, old_omnipresent, old_no_bind_keys, 
old_no_bind_mouse;
        int i;
 
+       old_skip_window_list = WFLAGP(wwin, skip_window_list);
        old_omnipresent = WFLAGP(wwin, omnipresent);
        old_no_bind_keys = WFLAGP(wwin, no_bind_keys);
        old_no_bind_mouse = WFLAGP(wwin, no_bind_mouse);
@@ -733,20 +726,15 @@ static void applySettings(WMWidget *button, void 
*client_data)
        }
 
        /* Attributes... --> Advanced Options */
-       WSETUFLAG(wwin, no_bind_keys, WMGetButtonSelected(panel->moreChk[0]));
-       WSETUFLAG(wwin, no_bind_mouse, WMGetButtonSelected(panel->moreChk[1]));
-       skip_window_list = WMGetButtonSelected(panel->moreChk[2]);
-       WSETUFLAG(wwin, skip_switchpanel, 
WMGetButtonSelected(panel->moreChk[3]));
-       WSETUFLAG(wwin, no_focusable, WMGetButtonSelected(panel->moreChk[4]));
-       WSETUFLAG(wwin, dont_move_off, WMGetButtonSelected(panel->moreChk[5]));
-       WSETUFLAG(wwin, no_hide_others, WMGetButtonSelected(panel->moreChk[6]));
-       WSETUFLAG(wwin, dont_save_session, 
WMGetButtonSelected(panel->moreChk[7]));
-       WSETUFLAG(wwin, emulate_appicon, 
WMGetButtonSelected(panel->moreChk[8]));
-       WSETUFLAG(wwin, focus_across_wksp, 
WMGetButtonSelected(panel->moreChk[9]));
-       WSETUFLAG(wwin, no_miniaturizable, 
WMGetButtonSelected(panel->moreChk[10]));
-#ifdef XKB_BUTTON_HINT
-       WSETUFLAG(wwin, no_language_button, 
WMGetButtonSelected(panel->moreChk[11]));
-#endif
+       for (i = 0; i < wlengthof(advanced_option); i++) {
+               if (WMGetButtonSelected(panel->moreChk[i]))
+                       set_attr_flag(&wwin->user_flags, 
&advanced_option[i].flag);
+               else
+                       clear_attr_flag(&wwin->user_flags, 
&advanced_option[i].flag);
+
+               set_attr_flag(&wwin->defined_user_flags, 
&advanced_option[i].flag);
+       }
+
        WSETUFLAG(wwin, always_user_icon, WMGetButtonSelected(panel->alwChk));
 
        if (WFLAGP(wwin, no_titlebar) && wwin->flags.shaded)
@@ -767,9 +755,8 @@ static void applySettings(WMWidget *button, void 
*client_data)
 
        wwin->flags.omnipresent = 0;
 
-       if (WFLAGP(wwin, skip_window_list) != skip_window_list) {
-               WSETUFLAG(wwin, skip_window_list, skip_window_list);
-               UpdateSwitchMenu(wwin->screen_ptr, wwin, skip_window_list ? 
ACTION_REMOVE : ACTION_ADD);
+       if (WFLAGP(wwin, skip_window_list) != old_skip_window_list) {
+               UpdateSwitchMenu(wwin->screen_ptr, wwin, WFLAGP(wwin, 
skip_window_list)?ACTION_REMOVE:ACTION_ADD);
        } else {
                if (WFLAGP(wwin, omnipresent) != old_omnipresent)
                        WMPostNotificationName(WMNChangedState, wwin, 
"omnipresent");
@@ -908,49 +895,16 @@ static void revertSettings(WMWidget *button, void 
*client_data)
                WMSetButtonSelected(panel->attrChk[i], flag);
        }
 
-       for (i = 0; i < wlengthof(panel->moreChk); i++) {
-               int flag = 0;
-
-               switch (i) {
-               case 0:
-                       flag = WFLAGP(wwin, no_bind_keys);
-                       break;
-               case 1:
-                       flag = WFLAGP(wwin, no_bind_mouse);
-                       break;
-               case 2:
-                       flag = WFLAGP(wwin, skip_window_list);
-                       break;
-               case 3:
-                       flag = WFLAGP(wwin, skip_switchpanel);
-                       break;
-               case 4:
-                       flag = WFLAGP(wwin, no_focusable);
-                       break;
-               case 5:
-                       flag = WFLAGP(wwin, dont_move_off);
-                       break;
-               case 6:
-                       flag = WFLAGP(wwin, no_hide_others);
-                       break;
-               case 7:
-                       flag = WFLAGP(wwin, dont_save_session);
-                       break;
-               case 8:
-                       flag = WFLAGP(wwin, emulate_appicon);
-                       break;
-               case 9:
-                       flag = WFLAGP(wwin, focus_across_wksp);
-                       break;
-               case 10:
-                       flag = WFLAGP(wwin, no_miniaturizable);
-                       break;
-#ifdef XKB_BUTTON_HINT
-               case 11:
-                       flag = WFLAGP(wwin, no_language_button);
-                       break;
-#endif
-               }
+       /* Attributes... --> Advanced Options */
+       for (i = 0; i < wlengthof(advanced_option); i++) {
+               int is_userdef, flag;
+
+               is_userdef = get_attr_flag(&wwin->defined_user_flags, 
&advanced_option[i].flag);
+               if (is_userdef)
+                       flag = get_attr_flag(&wwin->user_flags, 
&advanced_option[i].flag);
+               else
+                       flag = get_attr_flag(&wwin->client_flags, 
&advanced_option[i].flag);
+
                WMSetButtonSelected(panel->moreChk[i], flag);
        }
        if (panel->appFrm && wapp) {
@@ -1369,97 +1323,28 @@ static void create_tab_window_attributes(WWindow *wwin, 
InspectorPanel *panel, i
 static void create_tab_window_advanced(WWindow *wwin, InspectorPanel *panel, 
int frame_width)
 {
        int i = 0;
-       char *caption = NULL, *descr = NULL;
-       int flag = 0;
 
        panel->moreFrm = WMCreateFrame(panel->win);
        WMSetFrameTitle(panel->moreFrm, _("Advanced"));
        WMMoveWidget(panel->moreFrm, 15, 45);
        WMResizeWidget(panel->moreFrm, frame_width, 265);
 
-       for (i = 0; i < wlengthof(panel->moreChk); i++) {
-               switch (i) {
-               case 0:
-                       caption = _("Do not bind keyboard shortcuts");
-                       flag = WFLAGP(wwin, no_bind_keys);
-                       descr = _("Do not bind keyboard shortcuts from Window 
Maker\n"
-                                 "when this window is focused. This will allow 
the\n"
-                                 "window to receive all key combinations 
regardless\n"
-                                 "of your shortcut configuration.");
-                       break;
-               case 1:
-                       caption = _("Do not bind mouse clicks");
-                       flag = WFLAGP(wwin, no_bind_mouse);
-                       descr = _("Do not bind mouse actions, such as 
`Alt'+drag\n"
-                                 "in the window (when Alt is the modifier you 
have\n" "configured).");
-                       break;
-               case 2:
-                       caption = _("Do not show in the window list");
-                       flag = WFLAGP(wwin, skip_window_list);
-                       descr = _("Do not list the window in the window list 
menu.");
-                       break;
-               case 3:
-                       caption = _("Do not show in the switch panel");
-                       flag = WFLAGP(wwin, skip_switchpanel);
-                       descr = _("Do not include in switch panel while cycling 
windows.");
-                       break;
-               case 4:
-                       caption = _("Do not let it take focus");
-                       flag = WFLAGP(wwin, no_focusable);
-                       descr = _("Do not let the window take keyboard focus 
when you\n" "click on it.");
-                       break;
-               case 5:
-                       caption = _("Keep inside screen");
-                       flag = WFLAGP(wwin, dont_move_off);
-                       descr = _("Do not allow the window to move itself 
completely\n"
-                                 "outside the screen. For bug 
compatibility.\n");
-                       break;
-               case 6:
-                       caption = _("Ignore 'Hide Others'");
-                       flag = WFLAGP(wwin, no_hide_others);
-                       descr = _("Do not hide the window when issuing the\n" 
"`HideOthers' command.");
-                       break;
-               case 7:
-                       caption = _("Ignore 'Save Session'");
-                       flag = WFLAGP(wwin, dont_save_session);
-                       descr = _("Do not save the associated application in 
the\n"
-                                 "session's state, so that it won't be 
restarted\n"
-                                 "together with other applications when Window 
Maker\n" "starts.");
-                       break;
-               case 8:
-                       caption = _("Emulate application icon");
-                       flag = WFLAGP(wwin, emulate_appicon);
-                       descr = _("Make this window act as an application that 
provides\n"
-                                 "enough information to Window Maker for a 
dockable\n"
-                                 "application icon to be created.");
-                       break;
-               case 9:
-                       caption = _("Focus across workspaces");
-                       flag = WFLAGP(wwin, focus_across_wksp);
-                       descr = _("Allow Window Maker to switch workspace to 
satisfy\n"
-                                 "a focus request (annoying).");
-                       break;
-               case 10:
-                       caption = _("Do not let it be minimized");
-                       flag = WFLAGP(wwin, no_miniaturizable);
-                       descr = _("Do not let the window of this application 
be\n"
-                                         "minimized.\n");
-                       break;
-#ifdef XKB_BUTTON_HINT
-               case 11:
-                       caption = _("Disable language button");
-                       flag = WFLAGP(wwin, no_language_button);
-                       descr = _("Remove the `toggle language' button of the 
window.");
-                       break;
-#endif
-               }
+       for (i = 0; i < wlengthof(advanced_option); i++) {
+               int is_userdef, flag;
+
+               is_userdef = get_attr_flag(&wwin->defined_user_flags, 
&advanced_option[i].flag);
+               if (is_userdef)
+                       flag = get_attr_flag(&wwin->user_flags, 
&advanced_option[i].flag);
+               else
+                       flag = get_attr_flag(&wwin->client_flags, 
&advanced_option[i].flag);
+
                panel->moreChk[i] = WMCreateSwitchButton(panel->moreFrm);
-               WMMoveWidget(panel->moreChk[i], 10, 20 * (i + 1));
+               WMMoveWidget(panel->moreChk[i], 10, 20 * (i + 1) - 4);
                WMResizeWidget(panel->moreChk[i], frame_width - 15, 20);
                WMSetButtonSelected(panel->moreChk[i], flag);
-               WMSetButtonText(panel->moreChk[i], caption);
+               WMSetButtonText(panel->moreChk[i], 
_(advanced_option[i].caption));
 
-               WMSetBalloonTextForView(descr, WMWidgetView(panel->moreChk[i]));
+               WMSetBalloonTextForView(_(advanced_option[i].description), 
WMWidgetView(panel->moreChk[i]));
        }
 }
 

http://repo.or.cz/w/wmaker-crm.git/commit/1a068faa4993ed6ec628b4fc0e9b90381e9c5526

commit 1a068faa4993ed6ec628b4fc0e9b90381e9c5526
Author: Christophe CURIS <[email protected]>
Date:   Sun May 10 19:56:00 2015 +0200

    wmaker: moved the list of Window Attributes into an array, for the Window 
Inspector
    
    The Window Inspector is used to let user change the list of attributes for
    a window. This list of attributes was defined through many hard-coded
    things; by defining an array with everything at the beginning of the file
    it is easier to maintain (the code is simpler because it is more generic)
    and to make it evolve.
    
    Signed-off-by: Christophe CURIS <[email protected]>

diff --git a/src/winspector.c b/src/winspector.c
index 78b5cd0..ff5e26f 100644
--- a/src/winspector.c
+++ b/src/winspector.c
@@ -60,6 +60,56 @@
 #define UPDATE_DEFAULTS                1
 #define IS_BOOLEAN             2
 
+
+static const struct {
+       const char *key_name;
+       WWindowAttributes flag;
+       const char *caption;
+       const char *description;
+} window_attribute[] = {
+       { "NoTitlebar", { .no_titlebar = 1 }, N_("Disable titlebar"),
+         N_("Remove the titlebar of this window.\n"
+            "To access the window commands menu of a window\n"
+            "without it's titlebar, press Control+Esc (or the\n"
+            "equivalent shortcut, if you changed the default\n"
+            "settings).") },
+
+       { "NoResizebar", { .no_resizebar = 1 }, N_("Disable resizebar"),
+         N_("Remove the resizebar of this window.") },
+
+       { "NoCloseButton", { .no_close_button = 1 }, N_("Disable close button"),
+         N_("Remove the `close window' button of this window.") },
+
+       { "NoMiniaturizeButton", { .no_miniaturize_button = 1 }, N_("Disable 
miniaturize button"),
+         N_("Remove the `miniaturize window' button of the window.") },
+
+       { "NoBorder", { .no_border = 1 }, N_("Disable border"),
+         N_("Remove the 1 pixel black border around the window.") },
+
+       { "KeepOnTop", { .floating = 1 }, N_("Keep on top (floating)"),
+         N_("Keep the window over other windows, not allowing\n"
+            "them to cover it.") },
+
+       { "KeepOnBottom", { .sunken = 1 }, N_("Keep at bottom (sunken)"),
+         N_("Keep the window under all other windows.") },
+
+       { "Omnipresent", { .omnipresent = 1 }, N_("Omnipresent"),
+         N_("Make window present in all workspaces.") },
+
+       { "StartMiniaturized", { .start_miniaturized = 1 }, N_("Start 
miniaturized"),
+         N_("Make the window be automatically miniaturized when it's\n"
+            "first shown.") },
+
+       { "StartMaximized", { .start_maximized = 1 }, N_("Start maximized"),
+         N_("Make the window be automatically maximized when it's\n"
+            "first shown.") },
+
+       { "FullMaximize", { .full_maximize = 1 }, N_("Full screen 
maximization"),
+         N_("Make the window use the whole screen space when it's\n"
+                                 "maximized. The titlebar and resizebar will 
be moved\n"
+                                 "to outside the screen.") }
+};
+
 typedef struct InspectorPanel {
        struct InspectorPanel *nextPtr;
 
@@ -85,7 +135,7 @@ typedef struct InspectorPanel {
 
        /* second page. attributes */
        WMFrame *attrFrm;
-       WMButton *attrChk[11];
+       WMButton *attrChk[sizeof(window_attribute) / 
sizeof(window_attribute[0])];
 
        /* 3rd page. more attributes */
        WMFrame *moreFrm;
@@ -115,29 +165,28 @@ typedef struct InspectorPanel {
 } InspectorPanel;
 
 static InspectorPanel *panelList = NULL;
-static WMPropList *ANoTitlebar = NULL;
-static WMPropList *ANoResizebar;
-static WMPropList *ANoMiniaturizeButton;
-static WMPropList *ANoCloseButton;
-static WMPropList *ANoBorder;
+
+/*
+ * We are supposed to use the 'key_name' from the the 'window_attribute' 
structure when we want to
+ * save the user choice to the database, but as we will need to convert that 
name into a Property
+ * List, we use here a Cache of Property Lists, generated only once, which can 
be reused. It will
+ * also save on memory because of the re-use of the same storage space instead 
of allocating a new
+ * one everytime.
+ */
+static WMPropList *pl_attribute[sizeof(window_attribute) / 
sizeof(window_attribute[0])] = { [0] = NULL };
+
 static WMPropList *ANoHideOthers;
 static WMPropList *ANoMouseBindings;
 static WMPropList *ANoKeyBindings;
 static WMPropList *ANoAppIcon;
-static WMPropList *AKeepOnTop;
-static WMPropList *AKeepOnBottom;
-static WMPropList *AOmnipresent;
 static WMPropList *ASkipWindowList;
 static WMPropList *ASkipSwitchPanel;
 static WMPropList *AKeepInsideScreen;
 static WMPropList *AUnfocusable;
 static WMPropList *AFocusAcrossWorkspace;
 static WMPropList *AAlwaysUserIcon;
-static WMPropList *AStartMiniaturized;
-static WMPropList *AStartMaximized;
 static WMPropList *ADontSaveSession;
 static WMPropList *AEmulateAppIcon;
-static WMPropList *AFullMaximize;
 static WMPropList *ASharedAppIcon;
 static WMPropList *ANoMiniaturizable;
 #ifdef XKB_BUTTON_HINT
@@ -162,36 +211,81 @@ static void create_tab_window_advanced(WWindow *wwin, 
InspectorPanel *panel, int
 static void create_tab_icon_workspace(WWindow *wwin, InspectorPanel *panel);
 static void create_tab_app_specific(WWindow *wwin, InspectorPanel *panel, int 
frame_width);
 
+/*
+ * These 3 functions sets/clear/read a bit inside a bit-field in a generic 
manner;
+ * they uses binary operators to be as effiscient as possible, also counting 
on compiler's
+ * optimisations because the bit-field structure will fit in only 1 or 2 int 
but it is
+ * depending on the processor architecture.
+ */
+static inline void set_attr_flag(WWindowAttributes *target, const 
WWindowAttributes *flag)
+{
+       int i;
+       const unsigned char *src;
+       unsigned char *dst;
+
+       src = (const unsigned char *) flag;
+       dst = (unsigned char *) target;
+
+       for (i = 0; i < sizeof(*flag); i++)
+               dst[i] |= src[i];
+}
+
+static inline void clear_attr_flag(WWindowAttributes *target, const 
WWindowAttributes *flag)
+{
+       int i;
+       const unsigned char *src;
+       unsigned char *dst;
+
+       src = (const unsigned char *) flag;
+       dst = (unsigned char *) target;
+
+       for (i = 0; i < sizeof(*flag); i++)
+               dst[i] &= ~src[i];
+}
+
+static inline int get_attr_flag(const WWindowAttributes *from, const 
WWindowAttributes *flag)
+{
+       int i;
+       const unsigned char *xpect, *field;
+
+       field = (const unsigned char *) from;
+       xpect = (const unsigned char *) flag;
+
+       for (i = 0; i < sizeof(*flag); i++)
+               if (field[i] & xpect[i])
+                       return 1;
+
+       return 0;
+}
+
+/*
+ * This function is creating the Property List for the cache mentionned above
+ */
 static void make_keys(void)
 {
-       if (ANoTitlebar != NULL)
+       int i;
+
+       if (pl_attribute[0] != NULL)
                return;
 
+       for (i = 0; i < wlengthof(window_attribute); i++)
+               pl_attribute[i] = 
WMCreatePLString(window_attribute[i].key_name);
+
+
        AIcon = WMCreatePLString("Icon");
-       ANoTitlebar = WMCreatePLString("NoTitlebar");
-       ANoResizebar = WMCreatePLString("NoResizebar");
-       ANoMiniaturizeButton = WMCreatePLString("NoMiniaturizeButton");
-       ANoCloseButton = WMCreatePLString("NoCloseButton");
-       ANoBorder = WMCreatePLString("NoBorder");
        ANoHideOthers = WMCreatePLString("NoHideOthers");
        ANoMouseBindings = WMCreatePLString("NoMouseBindings");
        ANoKeyBindings = WMCreatePLString("NoKeyBindings");
        ANoAppIcon = WMCreatePLString("NoAppIcon");
-       AKeepOnTop = WMCreatePLString("KeepOnTop");
-       AKeepOnBottom = WMCreatePLString("KeepOnBottom");
-       AOmnipresent = WMCreatePLString("Omnipresent");
        ASkipWindowList = WMCreatePLString("SkipWindowList");
        ASkipSwitchPanel = WMCreatePLString("SkipSwitchPanel");
        AKeepInsideScreen = WMCreatePLString("KeepInsideScreen");
        AUnfocusable = WMCreatePLString("Unfocusable");
        AFocusAcrossWorkspace = WMCreatePLString("FocusAcrossWorkspace");
        AAlwaysUserIcon = WMCreatePLString("AlwaysUserIcon");
-       AStartMiniaturized = WMCreatePLString("StartMiniaturized");
-       AStartMaximized = WMCreatePLString("StartMaximized");
        AStartHidden = WMCreatePLString("StartHidden");
        ADontSaveSession = WMCreatePLString("DontSaveSession");
        AEmulateAppIcon = WMCreatePLString("EmulateAppIcon");
-       AFullMaximize = WMCreatePLString("FullMaximize");
        ASharedAppIcon = WMCreatePLString("SharedAppIcon");
        ANoMiniaturizable = WMCreatePLString("NoMiniaturizable");
 #ifdef XKB_BUTTON_HINT
@@ -509,38 +603,11 @@ static void saveSettings(WMWidget *button, void 
*client_data)
 
        flags |= IS_BOOLEAN;
 
-       value = (WMGetButtonSelected(panel->attrChk[0]) != 0) ? Yes : No;
-       different |= insertAttribute(dict, winDic, ANoTitlebar, value, flags);
-
-       value = (WMGetButtonSelected(panel->attrChk[1]) != 0) ? Yes : No;
-       different |= insertAttribute(dict, winDic, ANoResizebar, value, flags);
-
-       value = (WMGetButtonSelected(panel->attrChk[2]) != 0) ? Yes : No;
-       different |= insertAttribute(dict, winDic, ANoCloseButton, value, 
flags);
-
-       value = (WMGetButtonSelected(panel->attrChk[3]) != 0) ? Yes : No;
-       different |= insertAttribute(dict, winDic, ANoMiniaturizeButton, value, 
flags);
-
-       value = (WMGetButtonSelected(panel->attrChk[4]) != 0) ? Yes : No;
-       different |= insertAttribute(dict, winDic, ANoBorder, value, flags);
-
-       value = (WMGetButtonSelected(panel->attrChk[5]) != 0) ? Yes : No;
-       different |= insertAttribute(dict, winDic, AKeepOnTop, value, flags);
-
-       value = (WMGetButtonSelected(panel->attrChk[6]) != 0) ? Yes : No;
-       different |= insertAttribute(dict, winDic, AKeepOnBottom, value, flags);
-
-       value = (WMGetButtonSelected(panel->attrChk[7]) != 0) ? Yes : No;
-       different |= insertAttribute(dict, winDic, AOmnipresent, value, flags);
-
-       value = (WMGetButtonSelected(panel->attrChk[8]) != 0) ? Yes : No;
-       different |= insertAttribute(dict, winDic, AStartMiniaturized, value, 
flags);
-
-       value = (WMGetButtonSelected(panel->attrChk[9]) != 0) ? Yes : No;
-       different |= insertAttribute(dict, winDic, AStartMaximized, value, 
flags);
-
-       value = (WMGetButtonSelected(panel->attrChk[10]) != 0) ? Yes : No;
-       different |= insertAttribute(dict, winDic, AFullMaximize, value, flags);
+       /* Attributes... --> Window Attributes */
+       for (i = 0; i < wlengthof(window_attribute); i++) {
+               value = (WMGetButtonSelected(panel->attrChk[i]) != 0) ? Yes : 
No;
+               different |= insertAttribute(dict, winDic, pl_attribute[i], 
value, flags);
+       }
 
        value = (WMGetButtonSelected(panel->moreChk[0]) != 0) ? Yes : No;
        different |= insertAttribute(dict, winDic, ANoKeyBindings, value, 
flags);
@@ -645,8 +712,9 @@ static void applySettings(WMWidget *button, void 
*client_data)
        InspectorPanel *panel = (InspectorPanel *) client_data;
        WWindow *wwin = panel->inspected;
        WApplication *wapp = wApplicationOf(wwin->main_window);
-       int floating, sunken, skip_window_list;
+       int skip_window_list;
        int old_omnipresent, old_no_bind_keys, old_no_bind_mouse;
+       int i;
 
        old_omnipresent = WFLAGP(wwin, omnipresent);
        old_no_bind_keys = WFLAGP(wwin, no_bind_keys);
@@ -655,17 +723,14 @@ static void applySettings(WMWidget *button, void 
*client_data)
        showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
 
        /* Attributes... --> Window Attributes */
-       WSETUFLAG(wwin, no_titlebar, WMGetButtonSelected(panel->attrChk[0]));
-       WSETUFLAG(wwin, no_resizebar, WMGetButtonSelected(panel->attrChk[1]));
-       WSETUFLAG(wwin, no_close_button, 
WMGetButtonSelected(panel->attrChk[2]));
-       WSETUFLAG(wwin, no_miniaturize_button, 
WMGetButtonSelected(panel->attrChk[3]));
-       WSETUFLAG(wwin, no_border, WMGetButtonSelected(panel->attrChk[4]));
-       floating = WMGetButtonSelected(panel->attrChk[5]);
-       sunken = WMGetButtonSelected(panel->attrChk[6]);
-       WSETUFLAG(wwin, omnipresent, WMGetButtonSelected(panel->attrChk[7]));
-       WSETUFLAG(wwin, start_miniaturized, 
WMGetButtonSelected(panel->attrChk[8]));
-       WSETUFLAG(wwin, start_maximized, 
WMGetButtonSelected(panel->attrChk[9]));
-       WSETUFLAG(wwin, full_maximize, WMGetButtonSelected(panel->attrChk[10]));
+       for (i = 0; i < wlengthof(window_attribute); i++) {
+               if (WMGetButtonSelected(panel->attrChk[i]))
+                       set_attr_flag(&wwin->user_flags, 
&window_attribute[i].flag);
+               else
+                       clear_attr_flag(&wwin->user_flags, 
&window_attribute[i].flag);
+
+               set_attr_flag(&wwin->defined_user_flags, 
&window_attribute[i].flag);
+       }
 
        /* Attributes... --> Advanced Options */
        WSETUFLAG(wwin, no_bind_keys, WMGetButtonSelected(panel->moreChk[0]));
@@ -689,19 +754,17 @@ static void applySettings(WMWidget *button, void 
*client_data)
 
        WSETUFLAG(wwin, no_shadeable, WFLAGP(wwin, no_titlebar));
 
-       if (floating) {
-               if (!WFLAGP(wwin, floating))
-                       ChangeStackingLevel(wwin->frame->core, WMFloatingLevel);
-       } else if (sunken) {
-               if (!WFLAGP(wwin, sunken))
-                       ChangeStackingLevel(wwin->frame->core, WMSunkenLevel);
-       } else {
-               if (WFLAGP(wwin, floating) || WFLAGP(wwin, sunken))
-                       ChangeStackingLevel(wwin->frame->core, WMNormalLevel);
-       }
+       /*
+        * Update the window level according to AlwaysOnTop/AlwaysOnBotton
+        * if the level did not change, ChangeStackingLevel will do nothing 
anyway
+        */
+       if (WFLAGP(wwin, floating))
+               ChangeStackingLevel(wwin->frame->core, WMFloatingLevel);
+       else if (WFLAGP(wwin, sunken))
+               ChangeStackingLevel(wwin->frame->core, WMSunkenLevel);
+       else
+               ChangeStackingLevel(wwin->frame->core, WMNormalLevel);
 
-       WSETUFLAG(wwin, sunken, sunken);
-       WSETUFLAG(wwin, floating, floating);
        wwin->flags.omnipresent = 0;
 
        if (WFLAGP(wwin, skip_window_list) != skip_window_list) {
@@ -832,44 +895,16 @@ static void revertSettings(WMWidget *button, void 
*client_data)
 
        wWindowSetupInitialAttributes(wwin, &level, &workspace);
 
-       for (i = 0; i < wlengthof(panel->attrChk); i++) {
-               int flag = 0;
+       /* Attributes... --> Window Attributes */
+       for (i = 0; i < wlengthof(window_attribute); i++) {
+               int is_userdef, flag;
+
+               is_userdef = get_attr_flag(&wwin->defined_user_flags, 
&window_attribute[i].flag);
+               if (is_userdef)
+                       flag = get_attr_flag(&wwin->user_flags, 
&window_attribute[i].flag);
+               else
+                       flag = get_attr_flag(&wwin->client_flags, 
&window_attribute[i].flag);
 
-               switch (i) {
-               case 0:
-                       flag = WFLAGP(wwin, no_titlebar);
-                       break;
-               case 1:
-                       flag = WFLAGP(wwin, no_resizebar);
-                       break;
-               case 2:
-                       flag = WFLAGP(wwin, no_close_button);
-                       break;
-               case 3:
-                       flag = WFLAGP(wwin, no_miniaturize_button);
-                       break;
-               case 4:
-                       flag = WFLAGP(wwin, no_border);
-                       break;
-               case 5:
-                       flag = WFLAGP(wwin, floating);
-                       break;
-               case 6:
-                       flag = WFLAGP(wwin, sunken);
-                       break;
-               case 7:
-                       flag = WFLAGP(wwin, omnipresent);
-                       break;
-               case 8:
-                       flag = WFLAGP(wwin, start_miniaturized);
-                       break;
-               case 9:
-                       flag = WFLAGP(wwin, start_maximized != 0);
-                       break;
-               case 10:
-                       flag = WFLAGP(wwin, full_maximize);
-                       break;
-               }
                WMSetButtonSelected(panel->attrChk[i], flag);
        }
 
@@ -1306,84 +1341,28 @@ void wCloseInspectorForWindow(WWindow *wwin)
 static void create_tab_window_attributes(WWindow *wwin, InspectorPanel *panel, 
int frame_width)
 {
        int i = 0;
-       char *caption = NULL, *descr = NULL;
-       int flag = 0;
 
        panel->attrFrm = WMCreateFrame(panel->win);
        WMSetFrameTitle(panel->attrFrm, _("Attributes"));
        WMMoveWidget(panel->attrFrm, 15, 45);
        WMResizeWidget(panel->attrFrm, frame_width, 250);
 
-       for (i = 0; i < wlengthof(panel->attrChk); i++) {
-               switch (i) {
-               case 0:
-                       caption = _("Disable titlebar");
-                       flag = WFLAGP(wwin, no_titlebar);
-                       descr = _("Remove the titlebar of this window.\n"
-                                 "To access the window commands menu of a 
window\n"
-                                 "without it's titlebar, press Control+Esc (or 
the\n"
-                                 "equivalent shortcut, if you changed the 
default\n" "settings).");
-                       break;
-               case 1:
-                       caption = _("Disable resizebar");
-                       flag = WFLAGP(wwin, no_resizebar);
-                       descr = _("Remove the resizebar of this window.");
-                       break;
-               case 2:
-                       caption = _("Disable close button");
-                       flag = WFLAGP(wwin, no_close_button);
-                       descr = _("Remove the `close window' button of this 
window.");
-                       break;
-               case 3:
-                       caption = _("Disable miniaturize button");
-                       flag = WFLAGP(wwin, no_miniaturize_button);
-                       descr = _("Remove the `miniaturize window' button of 
the window.");
-                       break;
-               case 4:
-                       caption = _("Disable border");
-                       flag = WFLAGP(wwin, no_border);
-                       descr = _("Remove the 1 pixel black border around the 
window.");
-                       break;
-               case 5:
-                       caption = _("Keep on top (floating)");
-                       flag = WFLAGP(wwin, floating);
-                       descr = _("Keep the window over other windows, not 
allowing\n" "them to cover it.");
-                       break;
-               case 6:
-                       caption = _("Keep at bottom (sunken)");
-                       flag = WFLAGP(wwin, sunken);
-                       descr = _("Keep the window under all other windows.");
-                       break;
-               case 7:
-                       caption = _("Omnipresent");
-                       flag = WFLAGP(wwin, omnipresent);
-                       descr = _("Make window present in all workspaces.");
-                       break;
-               case 8:
-                       caption = _("Start miniaturized");
-                       flag = WFLAGP(wwin, start_miniaturized);
-                       descr = _("Make the window be automatically 
miniaturized when it's\n" "first shown.");
-                       break;
-               case 9:
-                       caption = _("Start maximized");
-                       flag = WFLAGP(wwin, start_maximized != 0);
-                       descr = _("Make the window be automatically maximized 
when it's\n" "first shown.");
-                       break;
-               case 10:
-                       caption = _("Full screen maximization");
-                       flag = WFLAGP(wwin, full_maximize);
-                       descr = _("Make the window use the whole screen space 
when it's\n"
-                                 "maximized. The titlebar and resizebar will 
be moved\n"
-                                 "to outside the screen.");
-                       break;
-               }
+       for (i = 0; i < wlengthof(window_attribute); i++) {
+               int is_userdef, flag;
+
+               is_userdef = get_attr_flag(&wwin->defined_user_flags, 
&window_attribute[i].flag);
+               if (is_userdef)
+                       flag = get_attr_flag(&wwin->user_flags, 
&window_attribute[i].flag);
+               else
+                       flag = get_attr_flag(&wwin->client_flags, 
&window_attribute[i].flag);
+
                panel->attrChk[i] = WMCreateSwitchButton(panel->attrFrm);
                WMMoveWidget(panel->attrChk[i], 10, 20 * (i + 1));
                WMResizeWidget(panel->attrChk[i], frame_width - 15, 20);
                WMSetButtonSelected(panel->attrChk[i], flag);
-               WMSetButtonText(panel->attrChk[i], caption);
+               WMSetButtonText(panel->attrChk[i], 
_(window_attribute[i].caption));
 
-               WMSetBalloonTextForView(descr, WMWidgetView(panel->attrChk[i]));
+               WMSetBalloonTextForView(_(window_attribute[i].description), 
WMWidgetView(panel->attrChk[i]));
        }
 }
 

-----------------------------------------------------------------------

Summary of changes:
 NEWS                       |  11 +++++
 configure.ac               |  14 ++++++
 doc/Makefile.am            |   1 +
 doc/build/Compilation.texi |   6 +++
 doc/wmaker.in              |   3 ++
 src/WindowMaker.h          |   3 ++
 src/event.c                | 106 +++++++++++++++++++++++++++++++++++++++
 src/main.c                 |   7 +++
 src/screen.c               | 120 +++++++++++++++++++++++++++++++++++++++++++--
 src/screen.h               |   3 ++
 src/winspector.c           | 104 +++++++++++++++++++--------------------
 11 files changed, 321 insertions(+), 57 deletions(-)


repo.or.cz automatic notification. Contact project admin [email protected]
if you want to unsubscribe, or site admin [email protected] if you receive
no reply.
-- 
wmaker-crm.git ("The Window Maker window manager")


-- 
To unsubscribe, send mail to [email protected].

Reply via email to