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]>
---
 src/winspector.c | 347 ++++++++++++++++++++++++++-----------------------------
 1 file changed, 163 insertions(+), 184 deletions(-)

diff --git a/src/winspector.c b/src/winspector.c
index 78b5cd0..8413836 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 }, M_("Disable titlebar"),
+         M_("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 }, M_("Disable resizebar"),
+         M_("Remove the resizebar of this window.") },
+
+       { "NoCloseButton", { .no_close_button = 1 }, M_("Disable close button"),
+         M_("Remove the `close window' button of this window.") },
+
+       { "NoMiniaturizeButton", { .no_miniaturize_button = 1 }, M_("Disable 
miniaturize button"),
+         M_("Remove the `miniaturize window' button of the window.") },
+
+       { "NoBorder", { .no_border = 1 }, M_("Disable border"),
+         M_("Remove the 1 pixel black border around the window.") },
+
+       { "KeepOnTop", { .floating = 1 }, M_("Keep on top (floating)"),
+         M_("Keep the window over other windows, not allowing\n"
+            "them to cover it.") },
+
+       { "KeepOnBottom", { .sunken = 1 }, M_("Keep at bottom (sunken)"),
+         M_("Keep the window under all other windows.") },
+
+       { "Omnipresent", { .omnipresent = 1 }, M_("Omnipresent"),
+         M_("Make window present in all workspaces.") },
+
+       { "StartMiniaturized", { .start_miniaturized = 1 }, M_("Start 
miniaturized"),
+         M_("Make the window be automatically miniaturized when it's\n"
+            "first shown.") },
+
+       { "StartMaximized", { .start_maximized = 1 }, M_("Start maximized"),
+         M_("Make the window be automatically maximized when it's\n"
+            "first shown.") },
+
+       { "FullMaximize", { .full_maximize = 1 }, M_("Full screen 
maximization"),
+         M_("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]));
        }
 }
 
-- 
2.1.4


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

Reply via email to