From 1a068faa4993ed6ec628b4fc0e9b90381e9c5526 Mon Sep 17 00:00:00 2001 From: Christophe CURIS Date: Sun, 10 May 2015 19:56:00 +0200 Subject: [PATCH] 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 --- src/winspector.c | 347 ++++++++++++++++++++++------------------------- 1 file changed, 163 insertions(+), 184 deletions(-) diff --git a/src/winspector.c b/src/winspector.c index 78b5cd0f..ff5e26f3 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])); } }