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 *) ¬ify);
+
+#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].