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 via c3ba9aeba3a3b92b9d804d2f2b3d0518d0d2fd9a (commit) via 5881d1a8baa1672c4abc9fa9d321b9b2023df1af (commit) via bed5ebea89c225434a032eb860040901ce315a09 (commit) via edc12fad9f755944648d98dcac3ee3b98eaba7f2 (commit) via af2aba6f954c1f5c62badac3598eb2fbcdbe9506 (commit) via 784f6794e5ee650883b9adc504881985cff9e2dc (commit) via 8fa16bef00f7156a9ff19d512583db33f16ac769 (commit) via 1c1909d5fea376ed40d4bbd1cbfd72177212ce1f (commit) via e14fad11626e881b104d4cc520abfdecdb82532f (commit) via 0bab67f9be51efbd178a2c8ab43ce73cbc083777 (commit) via 6ef010d974b8b45c2d0128dec59b9ec3c170af48 (commit) via 9d9b6d3fcf3553297c59c8b1fb20d2d03c9240d9 (commit) via ba3e57597192dc6548ea68adb4f92d1f60187411 (commit) from 3d6da4b2108c3a668d9a824a3a6ae9b8741f3df2 (commit) 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/c3ba9aeba3a3b92b9d804d2f2b3d0518d0d2fd9a commit c3ba9aeba3a3b92b9d804d2f2b3d0518d0d2fd9a Author: Christophe CURIS <christophe.cu...@free.fr> Date: Fri May 8 13:19:11 2015 +0200 wmaker: moved calculation of internal offset in handleDockMove outside the loop As pointed by the "checkpatch.pl" script, one line was too long in respect of the coding style. This line contains the calculation of an offset when storing a value in an array, as this offset is a constant during all the loop, this patch is calculating the offset only once before the loop and then uses this result, which should make the code faster (although gcc may already optimise this kind of things), makes it compliant with coding style, and takes the opportunity to explain the reasons behind this offset. Signed-off-by: Christophe CURIS <christophe.cu...@free.fr> diff --git a/src/dock.c b/src/dock.c index 2f325e9..99c137a 100644 --- a/src/dock.c +++ b/src/dock.c @@ -3835,12 +3835,24 @@ static void handleDockMove(WDock *dock, WAppIcon *aicon, XEvent *event) XUngrabPointer(dpy, CurrentTime); if (dock->type == WM_DRAWER) { Window wins[dock->icon_count]; + int offset_index; + + /* + * When the dock is on the Right side, the index of the icons are negative to + * reflect the fact that they are placed on the other side of the dock; we use + * an offset here so we can have an always positive index for the storage in + * the 'wins' array. + */ + if (dock->on_right_side) + offset_index = dock->icon_count - 1; + else + offset_index = 0; for (i = 0; i < dock->max_icons; i++) { tmpaicon = dock->icon_array[i]; if (tmpaicon == NULL) continue; - wins[ tmpaicon->xindex + (dock->on_right_side ? dock->icon_count - 1 : 0) ] = tmpaicon->icon->core->window; + wins[tmpaicon->xindex + offset_index] = tmpaicon->icon->core->window; } slide_windows(wins, dock->icon_count, (dock->on_right_side ? x - (dock->icon_count - 1) * ICON_SIZE : x), http://repo.or.cz/w/wmaker-crm.git/commit/5881d1a8baa1672c4abc9fa9d321b9b2023df1af commit 5881d1a8baa1672c4abc9fa9d321b9b2023df1af Author: Christophe CURIS <christophe.cu...@free.fr> Date: Fri May 8 13:19:10 2015 +0200 wmaker: moved the definition of the entries for the window menu options to an array By defining the const array with everything at the beginning of the file, it is easier to maintain and to make evolve. Signed-off-by: Christophe CURIS <christophe.cu...@free.fr> diff --git a/src/winmenu.c b/src/winmenu.c index 14cb271..c7da09d 100644 --- a/src/winmenu.c +++ b/src/winmenu.c @@ -106,10 +106,18 @@ enum { WO_KEEP_ON_TOP, WO_KEEP_AT_BOTTOM, - WO_OMNIPRESENT, - WO_ENTRIES + WO_OMNIPRESENT }; +static const char *const menu_options_entries[] = { + [WO_KEEP_ON_TOP] = N_("Keep on top"), + [WO_KEEP_AT_BOTTOM] = N_("Keep at bottom"), + [WO_OMNIPRESENT] = N_("Omnipresent") +}; + +/* + * Defines the menu entries for the Other maximization sub-menu + */ static const struct { const char *label; unsigned int shortcut_idx; @@ -320,7 +328,7 @@ static void makeShortcutCommand(WMenu * menu, WMenuEntry * entry) { WWindow *wwin = (WWindow *) entry->clientdata; WScreen *scr = wwin->screen_ptr; - int index = entry->order - WO_ENTRIES; + int index = entry->order - wlengthof(menu_options_entries); /* Parameter not used, but tell the compiler that it is ok */ (void) menu; @@ -400,8 +408,8 @@ static void updateMakeShortcutMenu(WMenu * menu, WWindow * wwin) buflen = strlen(_("Set Shortcut")) + 16; buffer = wmalloc(buflen); - for (i = WO_ENTRIES; i < smenu->entry_no; i++) { - int shortcutNo = i - WO_ENTRIES; + for (i = wlengthof(menu_options_entries); i < smenu->entry_no; i++) { + int shortcutNo = i - wlengthof(menu_options_entries); WMenuEntry *entry = smenu->entries[i]; WMArray *shortSelWindows = wwin->screen_ptr->shortcutWindows[shortcutNo]; @@ -538,17 +546,11 @@ static WMenu *makeOptionsMenu(WScreen * scr) return NULL; } - entry = wMenuAddCallback(menu, _("Keep on top"), execWindowOptionCommand, NULL); - entry->flags.indicator = 1; - entry->flags.indicator_type = MI_CHECK; - - entry = wMenuAddCallback(menu, _("Keep at bottom"), execWindowOptionCommand, NULL); - entry->flags.indicator = 1; - entry->flags.indicator_type = MI_CHECK; - - entry = wMenuAddCallback(menu, _("Omnipresent"), execWindowOptionCommand, NULL); - entry->flags.indicator = 1; - entry->flags.indicator_type = MI_CHECK; + for (i = 0; i < wlengthof(menu_options_entries); i++) { + entry = wMenuAddCallback(menu, _(menu_options_entries[i]), execWindowOptionCommand, NULL); + entry->flags.indicator = 1; + entry->flags.indicator_type = MI_CHECK; + } for (i = 0; i < MAX_WINDOW_SHORTCUTS; i++) { entry = wMenuAddCallback(menu, "", makeShortcutCommand, NULL); http://repo.or.cz/w/wmaker-crm.git/commit/bed5ebea89c225434a032eb860040901ce315a09 commit bed5ebea89c225434a032eb860040901ce315a09 Author: Christophe CURIS <christophe.cu...@free.fr> Date: Fri May 8 13:19:09 2015 +0200 wmaker: moved the definition of the list of entries for the window menu to an array By defining the const array with everything at the beginning of the file, it is easier to maintain and to make evolve (all stuff at the same place). Merged the function makeMakeShortcutMenu into makeOptionsMenu because it allows to use a simple callback in the structure like for the other submenus and because its complexity did not justify a dedicated function. Took opportunity to give a more appropriate name to the index MC_DUMMY_MOVETO which did not mean what the entry is about. As a side effect, this should close Coverity #50251 which was about saving the return value of function into a variable but not using it, which is not really good for maintainability. Signed-off-by: Christophe CURIS <christophe.cu...@free.fr> diff --git a/src/winmenu.c b/src/winmenu.c index bfba18e..14cb271 100644 --- a/src/winmenu.c +++ b/src/winmenu.c @@ -48,6 +48,18 @@ #include "xinerama.h" #include "winmenu.h" + +static WMenu *makeWorkspaceMenu(WScreen *scr); +static WMenu *makeOptionsMenu(WScreen *scr); +static WMenu *makeMaximizeMenu(WScreen *scr); + +/* + * Define the Menu entry that will be present in the Window menu + * + * The order of this list defines the order in which they will appear; + * make sure to keep the structure below aligned with the list because + * the constant index is used in many places. + */ enum { MC_MAXIMIZE, @@ -57,7 +69,7 @@ enum MC_HIDE, MC_MOVERESIZE, MC_SELECT, - MC_DUMMY_MOVETO, + MC_CHANGEWKSPC, MC_PROPERTIES, MC_OPTIONS, MC_RELAUNCH, @@ -65,6 +77,31 @@ enum MC_KILL }; +static const struct { + const char *label; + WMenu *(*generate_submenu)(WScreen *scr); +} window_menu_entries[] = { + [MC_MAXIMIZE] = { N_("Maximize"), NULL }, + [MC_OTHERMAX] = { N_("Other maximization"), makeMaximizeMenu }, + [MC_MINIATURIZE] = { N_("Miniaturize"), NULL }, + [MC_SHADE] = { N_("Shade"), NULL }, + [MC_HIDE] = { N_("Hide"), NULL }, + [MC_MOVERESIZE] = { N_("Resize/Move"), NULL }, + [MC_SELECT] = { N_("Select"), NULL }, + [MC_CHANGEWKSPC] = { N_("Move To"), makeWorkspaceMenu }, + [MC_PROPERTIES] = { N_("Attributes..."), NULL }, + [MC_OPTIONS] = { N_("Options"), makeOptionsMenu }, + [MC_RELAUNCH] = { N_("Launch"), NULL }, + [MC_CLOSE] = { N_("Close"), NULL }, + [MC_KILL] = { N_("Kill"), NULL } +}; + +/* + * Defines the menu entries for the Options sub-menu + * + * These options will be placed at the beginning of the menu, the rest will + * be populated with the Window Shortcut possibilities + */ enum { WO_KEEP_ON_TOP, @@ -478,19 +515,13 @@ static WMenu *makeWorkspaceMenu(WScreen * scr) updateWorkspaceMenu(menu); - return menu; -} - -static WMenu *makeMakeShortcutMenu(WMenu * menu) -{ - int i; - - for (i = 0; i < MAX_WINDOW_SHORTCUTS; i++) { - WMenuEntry *entry; - entry = wMenuAddCallback(menu, "", makeShortcutCommand, NULL); - - entry->flags.indicator = 1; - } + /* + * The Workspace Menu is made visible in the screen structure because + * it is updated when there is a change on workspaces. This was done + * to be efficient, avoiding re-generating completely the window menu + * and its sub-menus everytime it is needed. + */ + scr->workspace_submenu = menu; return menu; } @@ -499,6 +530,7 @@ static WMenu *makeOptionsMenu(WScreen * scr) { WMenu *menu; WMenuEntry *entry; + int i; menu = wMenuCreate(scr, NULL, False); if (!menu) { @@ -518,6 +550,11 @@ static WMenu *makeOptionsMenu(WScreen * scr) entry->flags.indicator = 1; entry->flags.indicator_type = MI_CHECK; + for (i = 0; i < MAX_WINDOW_SHORTCUTS; i++) { + entry = wMenuAddCallback(menu, "", makeShortcutCommand, NULL); + entry->flags.indicator = 1; + } + return menu; } @@ -541,49 +578,23 @@ static WMenu *makeMaximizeMenu(WScreen * scr) static WMenu *createWindowMenu(WScreen * scr) { WMenu *menu; - WMenuEntry *entry; + int i; menu = wMenuCreate(scr, NULL, False); - /* - * Warning: If you make some change that affects the order of the - * entries, you must update the command enum in the top of - * this file. - */ - entry = wMenuAddCallback(menu, _("Maximize"), execMenuCommand, NULL); - - entry = wMenuAddCallback(menu, _("Other maximization"), NULL, NULL); - wMenuEntrySetCascade(menu, entry, makeMaximizeMenu(scr)); - - entry = wMenuAddCallback(menu, _("Miniaturize"), execMenuCommand, NULL); - - entry = wMenuAddCallback(menu, _("Shade"), execMenuCommand, NULL); - entry = wMenuAddCallback(menu, _("Hide"), execMenuCommand, NULL); - - entry = wMenuAddCallback(menu, _("Resize/Move"), execMenuCommand, NULL); - - entry = wMenuAddCallback(menu, _("Select"), execMenuCommand, NULL); - - entry = wMenuAddCallback(menu, _("Move To"), NULL, NULL); - scr->workspace_submenu = makeWorkspaceMenu(scr); - if (scr->workspace_submenu) - wMenuEntrySetCascade(menu, entry, scr->workspace_submenu); - - entry = wMenuAddCallback(menu, _("Attributes..."), execMenuCommand, NULL); - - entry = wMenuAddCallback(menu, _("Options"), NULL, NULL); - wMenuEntrySetCascade(menu, entry, makeMakeShortcutMenu(makeOptionsMenu(scr))); - - /* - entry = wMenuAddCallback(menu, _("Select Shortcut"), NULL, NULL); - wMenuEntrySetCascade(menu, entry, makeMakeShortcutMenu(scr)); - */ - - entry = wMenuAddCallback(menu, _("Launch"), execMenuCommand, NULL); + for (i = 0; i < wlengthof(window_menu_entries); i++) { + WMenuEntry *entry; - entry = wMenuAddCallback(menu, _("Close"), execMenuCommand, NULL); + entry = wMenuAddCallback(menu, _(window_menu_entries[i].label), + (window_menu_entries[i].generate_submenu == NULL)?execMenuCommand:NULL, + NULL); + if (window_menu_entries[i].generate_submenu != NULL) { + WMenu *submenu; - entry = wMenuAddCallback(menu, _("Kill"), execMenuCommand, NULL); + submenu = window_menu_entries[i].generate_submenu(scr); + wMenuEntrySetCascade(menu, entry, submenu); + } + } return menu; } @@ -685,7 +696,7 @@ static void updateMenuForWindow(WMenu * menu, WWindow * wwin) menu->entries[MC_SELECT]->text = text; } - wMenuSetEnabled(menu, MC_DUMMY_MOVETO, !IS_OMNIPRESENT(wwin)); + wMenuSetEnabled(menu, MC_CHANGEWKSPC, !IS_OMNIPRESENT(wwin)); if (!wwin->flags.inspector_open) { wMenuSetEnabled(menu, MC_PROPERTIES, True); http://repo.or.cz/w/wmaker-crm.git/commit/edc12fad9f755944648d98dcac3ee3b98eaba7f2 commit edc12fad9f755944648d98dcac3ee3b98eaba7f2 Author: Rodolfo García Peñas (kix) <k...@kix.es> Date: Fri May 8 13:19:08 2015 +0200 wmaker: removed dead code related to 'GLOBAL_SUBMENU_FILE' There was the possibility to include a global sub-menu to the root menu using a dedicated file, but this does not look like it is really useful as this root menu is already defined by a user file, and the root menu is already specific enough that it does not need anything more 'global'. Furthermore, the variable enabling this feature (GLOBAL_SUBMENU_FILE) is not defined anywhere (neither from "configure", nor in "wconfig.h", ...) and is also not documented at all. Considering it was introduced a very long time ago (1999!) and was not touched anymore, this patch removes the dead code associated with it. Signed-off-by: Christophe CURIS <christophe.cu...@free.fr> diff --git a/src/rootmenu.c b/src/rootmenu.c index 8c0f0c6..499815f 100644 --- a/src/rootmenu.c +++ b/src/rootmenu.c @@ -66,7 +66,7 @@ static WMenu *readMenuPipe(WScreen * scr, char **file_name); static WMenu *readPLMenuPipe(WScreen * scr, char **file_name); static WMenu *readMenuFile(WScreen *scr, const char *file_name); static WMenu *readMenuDirectory(WScreen *scr, const char *title, char **file_name, const char *command); -static WMenu *configureMenu(WScreen * scr, WMPropList * definition, Bool includeGlobals); +static WMenu *configureMenu(WScreen *scr, WMPropList *definition); static void menu_parser_register_macros(WMenuParser parser); typedef struct Shortcut { @@ -602,7 +602,7 @@ static WMenu *constructPLMenu(WScreen *screen, const char *path) if (!pl) return NULL; - menu = configureMenu(screen, pl, False); + menu = configureMenu(screen, pl); WMReleasePropList(pl); @@ -1147,7 +1147,7 @@ static WMenu *readPLMenuPipe(WScreen * scr, char **file_name) if (!plist) return NULL; - menu = configureMenu(scr, plist, False); + menu = configureMenu(scr, plist); WMReleasePropList(plist); @@ -1462,7 +1462,7 @@ static WMenu *makeDefaultMenu(WScreen * scr) * *---------------------------------------------------------------------- */ -static WMenu *configureMenu(WScreen * scr, WMPropList * definition, Bool includeGlobals) +static WMenu *configureMenu(WScreen *scr, WMPropList *definition) { WMenu *menu = NULL; WMPropList *elem; @@ -1540,23 +1540,6 @@ static WMenu *configureMenu(WScreen * scr, WMPropList * definition, Bool include menu = wMenuCreate(scr, M_(mtitle), False); menu->on_destroy = removeShortcutsForMenu; -#ifdef GLOBAL_SUBMENU_FILE - if (includeGlobals) { - WMenu *submenu; - WMenuEntry *mentry; - - submenu = readMenuFile(scr, GLOBAL_SUBMENU_FILE); - - if (submenu) { - mentry = wMenuAddCallback(menu, submenu->frame->title, NULL, NULL); - wMenuEntrySetCascade(menu, mentry, submenu); - } - } -#else - /* Parameter not used, but tell the compiler that it is ok */ - (void) includeGlobals; -#endif - for (i = 1; i < count; i++) { elem = WMGetFromPLArray(definition, i); #if 0 @@ -1575,7 +1558,7 @@ static WMenu *configureMenu(WScreen * scr, WMPropList * definition, Bool include WMenuEntry *mentry; /* submenu */ - submenu = configureMenu(scr, elem, True); + submenu = configureMenu(scr, elem); if (submenu) { mentry = wMenuAddCallback(menu, submenu->frame->title, NULL, NULL); wMenuEntrySetCascade(menu, mentry, submenu); @@ -1670,14 +1653,14 @@ void OpenRootMenu(WScreen * scr, int x, int y, int keyboard) if (definition) { if (WMIsPLArray(definition)) { if (!scr->root_menu || w_global.domain.root_menu->timestamp > scr->root_menu->timestamp) { - menu = configureMenu(scr, definition, True); + menu = configureMenu(scr, definition); if (menu) menu->timestamp = w_global.domain.root_menu->timestamp; } else menu = NULL; } else { - menu = configureMenu(scr, definition, True); + menu = configureMenu(scr, definition); } } http://repo.or.cz/w/wmaker-crm.git/commit/af2aba6f954c1f5c62badac3598eb2fbcdbe9506 commit af2aba6f954c1f5c62badac3598eb2fbcdbe9506 Author: Christophe CURIS <christophe.cu...@free.fr> Date: Fri May 8 13:19:07 2015 +0200 wmaker: do not use strcmp twice on the same thing, in function appiconBalloon It is not really efficient to call it twice because the strings will not change, and by using the appropriate trick it can make the code smaller, with less redundancy, so less prone to bugs and easier to maintain. Signed-off-by: Christophe CURIS <christophe.cu...@free.fr> diff --git a/src/balloon.c b/src/balloon.c index 871bcd2..1e05ca7 100644 --- a/src/balloon.c +++ b/src/balloon.c @@ -522,6 +522,7 @@ static void appiconBalloon(WObjDescriptor *object) int len; WApplication *app; unsigned int app_win_cnt = 0; + const char *display_name; if (object->parent_type == WCLASS_DOCK_ICON) { if (aicon->main_window) { @@ -531,28 +532,28 @@ static void appiconBalloon(WObjDescriptor *object) } } - /* Check to see if it is a GNUstep app */ + /* + * Check to see if it is a GNUstep app, because in this case we use the instance + * instead of the class, otherwise the user will not be able to distinguish what + * is being refered. + */ if (strcmp(aicon->wm_class, "GNUstep") == 0) - len = strlen(aicon->command) + strlen(aicon->wm_instance) + 8; + display_name = aicon->wm_instance; else - len = strlen(aicon->command) + strlen(aicon->wm_class) + 8; + display_name = aicon->wm_class; + + len = strlen(aicon->command) + strlen(display_name) + 8; if (app_win_cnt > 0) len += 1 + snprintf(NULL, 0, "%u", app_win_cnt); tmp = wmalloc(len); - /* Check to see if it is a GNUstep App */ - if (strcmp(aicon->wm_class, "GNUstep") == 0) - if (app_win_cnt > 0) - snprintf(tmp, len, "%u %s\n(%s)", app_win_cnt, aicon->wm_instance, aicon->command); - else - snprintf(tmp, len, "%s\n(%s)", aicon->wm_instance, aicon->command); + if (app_win_cnt > 0) + snprintf(tmp, len, "%u %s\n(%s)", app_win_cnt, display_name, aicon->command); else - if (app_win_cnt > 0) - snprintf(tmp, len, "%u %s\n(%s)", app_win_cnt, aicon->wm_class, aicon->command); - else - snprintf(tmp, len, "%s\n(%s)", aicon->wm_class, aicon->command); + snprintf(tmp, len, "%s\n(%s)", aicon->wm_instance, aicon->command); scr->balloon->text = tmp; + } else if (aicon->command) { scr->balloon->text = wstrdup(aicon->command); } else if (aicon->wm_class) { http://repo.or.cz/w/wmaker-crm.git/commit/784f6794e5ee650883b9adc504881985cff9e2dc commit 784f6794e5ee650883b9adc504881985cff9e2dc Author: Christophe CURIS <christophe.cu...@free.fr> Date: Fri May 8 13:19:06 2015 +0200 wmaker: remove one level of pointers for the function SlideWindows The function does not need to be passed a array of pointer to windows because it does not change content of the pointers. It is more efficient to directly use an array of windows as the parameter, and simpler also. As 'SlideWindow' is also concerned, it can be simplified and turned into an inlinable function so the compiler can optimise it. Took opportunity to de-CamelCase the name of the functions to comply with the project's coding style. Signed-off-by: Christophe CURIS <christophe.cu...@free.fr> diff --git a/src/actions.c b/src/actions.c index 2349978..299bc78 100644 --- a/src/actions.c +++ b/src/actions.c @@ -1843,7 +1843,7 @@ void wArrangeIcons(WScreen *scr, Bool arrangeAll) if (aicon->x_pos != X || aicon->y_pos != Y) { #ifdef USE_ANIMATIONS if (!wPreferences.no_animations) - SlideWindow(aicon->icon->core->window, aicon->x_pos, aicon->y_pos, X, Y); + slide_window(aicon->icon->core->window, aicon->x_pos, aicon->y_pos, X, Y); #endif /* USE_ANIMATIONS */ } wAppIconMove(aicon, X, Y); diff --git a/src/appicon.c b/src/appicon.c index 14dba97..302066d 100644 --- a/src/appicon.c +++ b/src/appicon.c @@ -967,7 +967,7 @@ Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event) Bool docked = False; if (ondock) { - SlideWindow(icon->core->window, x, y, shad_x, shad_y); + slide_window(icon->core->window, x, y, shad_x, shad_y); XUnmapWindow(dpy, scr->dock_shadow); if (originalDock == NULL) { // docking an undocked appicon docked = wDockAttachIcon(lastDock, aicon, ix, iy, False); @@ -980,7 +980,7 @@ Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event) // Also fill the gap left in the drawer wDrawerFillTheGap(lastDock, aicon, False); } - SlideWindow(icon->core->window, x, y, oldX, oldY); + slide_window(icon->core->window, x, y, oldX, oldY); } } else { // moving a docked appicon to a dock @@ -1016,7 +1016,7 @@ Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event) // Trust the appicon is inserted at exactly the same place, so its oldX/oldY are consistent with its "new" location? } - SlideWindow(icon->core->window, x, y, oldX, oldY); + slide_window(icon->core->window, x, y, oldX, oldY); wDockReattachIcon(originalDock, aicon, aicon->xindex, aicon->yindex); } else { diff --git a/src/dock.c b/src/dock.c index e72c0c8..2f325e9 100644 --- a/src/dock.c +++ b/src/dock.c @@ -3271,7 +3271,7 @@ void wDockTrackWindowLaunch(WDock *dock, Window window) XMapWindow(dpy, aicon->icon->core->window); aicon->launching = 1; wAppIconPaint(aicon); - SlideWindow(aicon->icon->core->window, x0, y0, icon->x_pos, icon->y_pos); + slide_window(aicon->icon->core->window, x0, y0, icon->x_pos, icon->y_pos); XUnmapWindow(dpy, aicon->icon->core->window); wAppIconDestroy(aicon); } @@ -3834,15 +3834,15 @@ static void handleDockMove(WDock *dock, WAppIcon *aicon, XEvent *event) break; XUngrabPointer(dpy, CurrentTime); if (dock->type == WM_DRAWER) { - Window *wins[dock->icon_count]; + Window wins[dock->icon_count]; for (i = 0; i < dock->max_icons; i++) { tmpaicon = dock->icon_array[i]; if (tmpaicon == NULL) continue; - wins[ tmpaicon->xindex + (dock->on_right_side ? dock->icon_count - 1 : 0) ] = &tmpaicon->icon->core->window; + wins[ tmpaicon->xindex + (dock->on_right_side ? dock->icon_count - 1 : 0) ] = tmpaicon->icon->core->window; } - SlideWindows(wins, dock->icon_count, + slide_windows(wins, dock->icon_count, (dock->on_right_side ? x - (dock->icon_count - 1) * ICON_SIZE : x), y, (dock->on_right_side ? shad_x - (dock->icon_count - 1) * ICON_SIZE : shad_x), @@ -4665,7 +4665,7 @@ void wSlideAppicons(WAppIcon **appicons, int n, int to_the_left) { int i; int leftmost = -1, min_index = 9999, from_x = -1; // leftmost and from_x initialized to avoid warning - Window *wins[n]; + Window wins[n]; WAppIcon *aicon; if (n < 1) @@ -4684,10 +4684,10 @@ void wSlideAppicons(WAppIcon **appicons, int n, int to_the_left) for (i = 0; i < n; i++) { aicon = appicons[i]; - wins[aicon->xindex - min_index] = &aicon->icon->core->window; + wins[aicon->xindex - min_index] = aicon->icon->core->window; } aicon = appicons[leftmost]; - SlideWindows(wins, n, from_x, aicon->y_pos, aicon->x_pos, aicon->y_pos); + slide_windows(wins, n, from_x, aicon->y_pos, aicon->x_pos, aicon->y_pos); } diff --git a/src/misc.c b/src/misc.c index 4144c7d..99341d3 100644 --- a/src/misc.c +++ b/src/misc.c @@ -145,7 +145,7 @@ void move_window(Window win, int from_x, int from_y, int to_x, int to_y) if (wPreferences.no_animations) XMoveWindow(dpy, win, to_x, to_y); else - SlideWindow(win, from_x, from_y, to_x, to_y); + slide_window(win, from_x, from_y, to_x, to_y); #else XMoveWindow(dpy, win, to_x, to_y); @@ -155,16 +155,10 @@ void move_window(Window win, int from_x, int from_y, int to_x, int to_y) #endif } -void SlideWindow(Window win, int from_x, int from_y, int to_x, int to_y) -{ - Window *wins[1] = { &win }; - SlideWindows(wins, 1, from_x, from_y, to_x, to_y); -} - /* wins is an array of Window, sorted from left to right, the first is * going to be moved from (from_x,from_y) to (to_x,to_y) and the * following windows are going to be offset by (ICON_SIZE*i,0) */ -void SlideWindows(Window *wins[], int n, int from_x, int from_y, int to_x, int to_y) +void slide_windows(Window wins[], int n, int from_x, int from_y, int to_x, int to_y) { time_t time0 = time(NULL); float dx, dy, x = from_x, y = from_y, px, py; @@ -243,7 +237,7 @@ void SlideWindows(Window *wins[], int n, int from_x, int from_y, int to_x, int t } for (i = 0; i < n; i++) { - XMoveWindow(dpy, *wins[i], (int)x + i * ICON_SIZE, (int)y); + XMoveWindow(dpy, wins[i], (int)x + i * ICON_SIZE, (int)y); } XFlush(dpy); if (slide_delay > 0) { @@ -255,7 +249,7 @@ void SlideWindows(Window *wins[], int n, int from_x, int from_y, int to_x, int t break; } for (i = 0; i < n; i++) { - XMoveWindow(dpy, *wins[i], to_x + i * ICON_SIZE, to_y); + XMoveWindow(dpy, wins[i], to_x + i * ICON_SIZE, to_y); } XSync(dpy, 0); diff --git a/src/misc.h b/src/misc.h index 36f08a0..c4b9825 100644 --- a/src/misc.h +++ b/src/misc.h @@ -30,10 +30,14 @@ Bool wGetIconName(Display *dpy, Window win, char **iconname); Bool UpdateDomainFile(WDDomain * domain); void move_window(Window win, int from_x, int from_y, int to_x, int to_y); -void SlideWindow(Window win, int from_x, int from_y, int to_x, int to_y); -void SlideWindows(Window *wins[], int n, int from_x, int from_y, int to_x, int to_y); +void slide_windows(Window wins[], int n, int from_x, int from_y, int to_x, int to_y); void ParseWindowName(WMPropList *value, char **winstance, char **wclass, const char *where); +static inline void slide_window(Window win, int from_x, int from_y, int to_x, int to_y) +{ + slide_windows(&win, 1, from_x, from_y, to_x, to_y); +} + /* Helper is a 'wmsetbg' subprocess with sets the background for the current workspace */ Bool start_bg_helper(WScreen *scr); void SendHelperMessage(WScreen *scr, char type, int workspace, const char *msg); diff --git a/src/wsmap.c b/src/wsmap.c index 3e84c98..40281a7 100644 --- a/src/wsmap.c +++ b/src/wsmap.c @@ -96,17 +96,17 @@ void wWorkspaceMapUpdate(WScreen *scr) static void workspace_map_slide(WWorkspaceMap *wsmap) { if (wsmap->edge == WD_TOP) - SlideWindow(WMWidgetXID(wsmap->win), 0, -1 * wsmap->wsheight, wsmap->xcount, wsmap->ycount); + slide_window(WMWidgetXID(wsmap->win), 0, -1 * wsmap->wsheight, wsmap->xcount, wsmap->ycount); else - SlideWindow(WMWidgetXID(wsmap->win), 0, wsmap->scr->scr_height, wsmap->xcount, wsmap->ycount); + slide_window(WMWidgetXID(wsmap->win), 0, wsmap->scr->scr_height, wsmap->xcount, wsmap->ycount); } static void workspace_map_unslide(WWorkspaceMap *wsmap) { if (wsmap->edge == WD_TOP) - SlideWindow(WMWidgetXID(wsmap->win), wsmap->xcount, wsmap->ycount, 0, -1 * wsmap->wsheight); + slide_window(WMWidgetXID(wsmap->win), wsmap->xcount, wsmap->ycount, 0, -1 * wsmap->wsheight); else - SlideWindow(WMWidgetXID(wsmap->win), wsmap->xcount, wsmap->ycount, 0, wsmap->scr->scr_height); + slide_window(WMWidgetXID(wsmap->win), wsmap->xcount, wsmap->ycount, 0, wsmap->scr->scr_height); } static void workspace_map_destroy(WWorkspaceMap *wsmap) http://repo.or.cz/w/wmaker-crm.git/commit/8fa16bef00f7156a9ff19d512583db33f16ac769 commit 8fa16bef00f7156a9ff19d512583db33f16ac769 Author: Christophe CURIS <christophe.cu...@free.fr> Date: Fri May 8 13:19:05 2015 +0200 wmaker: reorganisation of the control flow of the function 'findDock' Changed the code to return as soon as the result is known because it makes the code simpler to understand, which is good for maintainability. Signed-off-by: Christophe CURIS <christophe.cu...@free.fr> diff --git a/src/dock.c b/src/dock.c index e985152..e72c0c8 100644 --- a/src/dock.c +++ b/src/dock.c @@ -2042,29 +2042,29 @@ static WDock *findDock(WScreen *scr, XEvent *event, int *icon_pos) WDock *dock; int i; - *icon_pos = -1; - dock = scr->dock; if (dock != NULL) { for (i = 0; i < dock->max_icons; i++) { - if (dock->icon_array[i] - && dock->icon_array[i]->icon->core->window == event->xclient.window) { + if (dock->icon_array[i] && + dock->icon_array[i]->icon->core->window == event->xclient.window) { *icon_pos = i; - break; + return dock; } } } - if (*icon_pos < 0 && (dock = scr->workspaces[scr->current_workspace]->clip) != NULL) { + + dock = scr->workspaces[scr->current_workspace]->clip; + if (dock != NULL) { for (i = 0; i < dock->max_icons; i++) { - if (dock->icon_array[i] - && dock->icon_array[i]->icon->core->window == event->xclient.window) { + if (dock->icon_array[i] && + dock->icon_array[i]->icon->core->window == event->xclient.window) { *icon_pos = i; - break; + return dock; } } } - if (*icon_pos >= 0) - return dock; + + *icon_pos = -1; return NULL; } http://repo.or.cz/w/wmaker-crm.git/commit/1c1909d5fea376ed40d4bbd1cbfd72177212ce1f commit 1c1909d5fea376ed40d4bbd1cbfd72177212ce1f Author: Christophe CURIS <christophe.cu...@free.fr> Date: Fri May 8 13:19:04 2015 +0200 wmaker: took as much assignation as possible outside 'if' statements It is generally considered bad practice to place an assignation inside the expression for an "if" statement because it is often a source of bug, because of possible typos and because it makes reviewing code more complicated. This patch fixes as much cases as possible to make the code easier to read. Signed-off-by: Christophe CURIS <christophe.cu...@free.fr> diff --git a/src/appmenu.c b/src/appmenu.c index 3a08e62..bc70896 100644 --- a/src/appmenu.c +++ b/src/appmenu.c @@ -139,7 +139,8 @@ static WMenu *parseMenuCommand(WScreen * scr, Window win, char **slist, int coun } wstrlcpy(title, &slist[*index][pos], sizeof(title)); } - if (!(data = malloc(sizeof(WAppMenuData)))) { + data = malloc(sizeof(WAppMenuData)); + if (data == NULL) { wwarning(_("appmenu: out of memory creating menu for window %lx"), win); wMenuDestroy(menu, True); return NULL; diff --git a/src/dialog.c b/src/dialog.c index 56cd3db..cb444ee 100644 --- a/src/dialog.c +++ b/src/dialog.c @@ -262,7 +262,8 @@ ScanFiles(const char *dir, const char *prefix, unsigned acceptmask, unsigned dec char *fullfilename, *suffix; prefixlen = strlen(prefix); - if ((d = opendir(dir)) != NULL) { + d = opendir(dir); + if (d != NULL) { while ((de = readdir(d)) != NULL) { if (strlen(de->d_name) > prefixlen && !strncmp(prefix, de->d_name, prefixlen) && @@ -298,12 +299,14 @@ static WMArray *GenerateVariants(const char *complete) while (*complete == ' ') ++complete; - if ((pos = strrchr(complete, ' ')) != NULL) { + pos = strrchr(complete, ' '); + if (pos != NULL) { complete = pos + 1; firstWord = False; } - if ((pos = strrchr(complete, '/')) != NULL) { + pos = strrchr(complete, '/'); + if (pos != NULL) { tmp = wstrndup((char *)complete, pos - complete + 1); if (*tmp == '~' && *(tmp + 1) == '/' && getenv("HOME")) { dir = wstrdup(getenv("HOME")); diff --git a/src/dock.c b/src/dock.c index d4aca09..e985152 100644 --- a/src/dock.c +++ b/src/dock.c @@ -1530,7 +1530,8 @@ static WMPropList *dockSaveState(WDock *dock) if (!btn || btn->attracted) continue; - if ((icon_info = make_icon_state(dock->icon_array[i]))) { + icon_info = make_icon_state(dock->icon_array[i]); + if (icon_info != NULL) { WMAddToPLArray(list, icon_info); WMReleasePropList(icon_info); } @@ -2042,7 +2043,9 @@ static WDock *findDock(WScreen *scr, XEvent *event, int *icon_pos) int i; *icon_pos = -1; - if ((dock = scr->dock) != NULL) { + + dock = scr->dock; + if (dock != NULL) { for (i = 0; i < dock->max_icons; i++) { if (dock->icon_array[i] && dock->icon_array[i]->icon->core->window == event->xclient.window) { @@ -2669,7 +2672,8 @@ Bool wDockSnapIcon(WDock *dock, WAppIcon *icon, int req_x, int req_y, int *ret_x * it wants to be (ex_x) and slide them. */ j = 0; for (i = 1; i < dock->max_icons; i++) { - if ((aicon = dock->icon_array[ i ]) && aicon != icon && + aicon = dock->icon_array[i]; + if ((aicon != NULL) && (aicon != icon) && ((ex_x <= aicon->xindex && aicon->xindex < index_of_hole) || (index_of_hole < aicon->xindex && aicon->xindex <= ex_x))) aicons_to_shift[ j++ ] = aicon; @@ -3048,7 +3052,8 @@ static pid_t execCommand(WAppIcon *btn, const char *command, WSavedState *state) return 0; } - if ((pid = fork()) == 0) { + pid = fork(); + if (pid == 0) { char **args; int i; @@ -3752,7 +3757,9 @@ static void handleDockMove(WDock *dock, WAppIcon *aicon, XEvent *event) { for (i = 0; i < dock->max_icons; i++) { int new_y, new_index, j, ok; - if ((tmpaicon = dock->icon_array[i]) == NULL) + + tmpaicon = dock->icon_array[i]; + if (tmpaicon == NULL) continue; if (onScreen(scr, tmpaicon->x_pos, tmpaicon->y_pos)) continue; @@ -3830,7 +3837,8 @@ static void handleDockMove(WDock *dock, WAppIcon *aicon, XEvent *event) Window *wins[dock->icon_count]; for (i = 0; i < dock->max_icons; i++) { - if ((tmpaicon = dock->icon_array[i]) == NULL) + tmpaicon = dock->icon_array[i]; + if (tmpaicon == NULL) continue; wins[ tmpaicon->xindex + (dock->on_right_side ? dock->icon_count - 1 : 0) ] = &tmpaicon->icon->core->window; } @@ -4420,7 +4428,8 @@ static void drawerDestroy(WDock *drawer) if (drawer->icon_count == 2) { /* Drawer contains a single appicon: dock it where the drawer was */ for (i = 1; i < drawer->max_icons; i++) { - if ((aicon = drawer->icon_array[i])) + aicon = drawer->icon_array[i]; + if (aicon != NULL) break; } @@ -4431,7 +4440,8 @@ static void drawerDestroy(WDock *drawer) } else if (drawer->icon_count > 2) { icons = WMCreateArray(drawer->icon_count - 1); for (i = 1; i < drawer->max_icons; i++) { - if (!(aicon = drawer->icon_array[i])) + aicon = drawer->icon_array[i]; + if (aicon == NULL) continue; WMAddToArray(icons, aicon); } @@ -4559,7 +4569,9 @@ static void swapDrawer(WDock *drawer, int new_x) for (i = 0; i < drawer->max_icons; i++) { WAppIcon *ai; - if ((ai = drawer->icon_array[i]) == NULL) + + ai = drawer->icon_array[i]; + if (ai == NULL) continue; ai->xindex *= -1; /* so A B C becomes C B A */ ai->x_pos = new_x + ai->xindex * ICON_SIZE; diff --git a/src/event.c b/src/event.c index ce316ee..dbb927b 100644 --- a/src/event.c +++ b/src/event.c @@ -582,7 +582,8 @@ static void handleMapRequest(XEvent * ev) WScreen *scr = NULL; Window window = ev->xmaprequest.window; - if ((wwin = wWindowFor(window))) { + wwin = wWindowFor(window); + if (wwin != NULL) { if (wwin->flags.shaded) { wUnshadeWindow(wwin); } @@ -931,7 +932,8 @@ static void handleConfigureRequest(XEvent * event) { WWindow *wwin; - if (!(wwin = wWindowFor(event->xconfigurerequest.window))) { + wwin = wWindowFor(event->xconfigurerequest.window); + if (wwin == NULL) { /* * Configure request for unmapped window */ diff --git a/src/monitor.c b/src/monitor.c index f06ff51..c784dd3 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -103,7 +103,8 @@ int MonitorLoop(int argc, char **argv) } do { - if ((exited = waitpid(-1, &status, 0)) < 0) { + exited = waitpid(-1, &status, 0); + if (exited < 0) { werror(_("Error during monitoring of Window Maker process.")); error = True; break; diff --git a/src/osdep_bsd.c b/src/osdep_bsd.c index ad504ad..992f061 100644 --- a/src/osdep_bsd.c +++ b/src/osdep_bsd.c @@ -102,17 +102,20 @@ Bool GetCommandForPid(int pid, char ***argv, int *argc) #if defined( OPENBSD ) /* kvm descriptor */ - if ((kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, kvmerr)) == NULL) + kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, kvmerr); + if (kd == NULL) return False; procs = 0; /* the process we are interested in */ - if ((kp = kvm_getprocs(kd, KERN_PROC_PID, pid, sizeof(*kp), &procs)) == NULL || procs == 0) + kp = kvm_getprocs(kd, KERN_PROC_PID, pid, sizeof(*kp), &procs); + if (kp == NULL || procs == 0) /* if kvm_getprocs() bombs out or does not find the process */ return False; /* get its argv */ - if ((nargv = kvm_getargv(kd, kp, 0)) == NULL) + nargv = kvm_getargv(kd, kp, 0); + if (nargv == NULL) return False; /* flatten nargv into args */ diff --git a/src/osdep_linux.c b/src/osdep_linux.c index bb1ef2e..890ba6a 100644 --- a/src/osdep_linux.c +++ b/src/osdep_linux.c @@ -38,7 +38,8 @@ Bool GetCommandForPid(int pid, char ***argv, int *argc) while (1) { /* not switching this to stdio yet, as this does not need * to be portable, and i'm lazy */ - if ((fd = open(buf, O_RDONLY)) != -1) + fd = open(buf, O_RDONLY); + if (fd != -1) break; if (errno == EINTR) continue; @@ -46,7 +47,8 @@ Bool GetCommandForPid(int pid, char ***argv, int *argc) } while (1) { - if ((count = read(fd, buf, sizeof(buf))) != -1) + count = read(fd, buf, sizeof(buf)); + if (count != -1) break; if (errno == EINTR) continue; diff --git a/src/screen.c b/src/screen.c index 51e2317..10a1fc9 100644 --- a/src/screen.c +++ b/src/screen.c @@ -841,16 +841,16 @@ void wScreenSaveState(WScreen * scr) if (!wPreferences.flags.nodock) { wDockSaveState(scr, old_state); } else { - if ((foo = WMGetFromPLDictionary(old_state, dDock)) != NULL) { + foo = WMGetFromPLDictionary(old_state, dDock); + if (foo != NULL) WMPutInPLDictionary(scr->session_state, dDock, foo); - } } if (!wPreferences.flags.noclip) { wClipSaveState(scr); } else { - if ((foo = WMGetFromPLDictionary(old_state, dClip)) != NULL) { + foo = WMGetFromPLDictionary(old_state, dClip); + if (foo != NULL) WMPutInPLDictionary(scr->session_state, dClip, foo); - } } wWorkspaceSaveState(scr, old_state); @@ -858,21 +858,22 @@ void wScreenSaveState(WScreen * scr) if (!wPreferences.flags.nodrawer) { wDrawersSaveState(scr); } else { - if ((foo = WMGetFromPLDictionary(old_state, dDrawers)) != NULL) { + foo = WMGetFromPLDictionary(old_state, dDrawers); + if (foo != NULL) WMPutInPLDictionary(scr->session_state, dDrawers, foo); - } } if (wPreferences.save_session_on_exit) { wSessionSaveState(scr); } else { - if ((foo = WMGetFromPLDictionary(old_state, dApplications)) != NULL) { + foo = WMGetFromPLDictionary(old_state, dApplications); + if (foo != NULL) WMPutInPLDictionary(scr->session_state, dApplications, foo); - } - if ((foo = WMGetFromPLDictionary(old_state, dWorkspace)) != NULL) { + + foo = WMGetFromPLDictionary(old_state, dWorkspace); + if (foo != NULL) WMPutInPLDictionary(scr->session_state, dWorkspace, foo); - } } /* clean up */ diff --git a/src/session.c b/src/session.c index 2af8fd0..90109a3 100644 --- a/src/session.c +++ b/src/session.c @@ -128,9 +128,9 @@ static int getBool(WMPropList * value) if (!WMIsPLString(value)) { return 0; } - if (!(val = WMGetFromPLString(value))) { + val = WMGetFromPLString(value); + if (val == NULL) return 0; - } if ((val[1] == '\0' && (val[0] == 'y' || val[0] == 'Y')) || strcasecmp(val, "YES") == 0) { @@ -299,7 +299,8 @@ void wSessionSaveState(WScreen * scr) || WFLAGP(wwin, shared_appicon)) && !WFLAGP(wwin, dont_save_session)) { /* A entry for this application was not yet saved. Save one. */ - if ((win_info = makeWindowState(wwin, wapp)) != NULL) { + win_info = makeWindowState(wwin, wapp); + if (win_info != NULL) { WMAddToPLArray(list, win_info); WMReleasePropList(win_info); /* If we were succesful in saving the info for this window @@ -346,7 +347,8 @@ static pid_t execCommand(WScreen *scr, char *command) return 0; } - if ((pid = fork()) == 0) { + pid = fork(); + if (pid == 0) { char **args; int i; @@ -392,13 +394,21 @@ static WSavedState *getWindowState(WScreen * scr, WMPropList * win_state) state->workspace--; } } - if ((value = WMGetFromPLDictionary(win_state, sShaded)) != NULL) + + value = WMGetFromPLDictionary(win_state, sShaded); + if (value != NULL) state->shaded = getBool(value); - if ((value = WMGetFromPLDictionary(win_state, sMiniaturized)) != NULL) + + value = WMGetFromPLDictionary(win_state, sMiniaturized); + if (value != NULL) state->miniaturized = getBool(value); - if ((value = WMGetFromPLDictionary(win_state, sHidden)) != NULL) + + value = WMGetFromPLDictionary(win_state, sHidden); + if (value != NULL) state->hidden = getBool(value); - if ((value = WMGetFromPLDictionary(win_state, sShortcutMask)) != NULL) { + + value = WMGetFromPLDictionary(win_state, sShortcutMask); + if (value != NULL) { mask = getInt(value); state->window_shortcuts = mask; } diff --git a/src/wdefaults.c b/src/wdefaults.c index c2d9eb8..b57b016 100644 --- a/src/wdefaults.c +++ b/src/wdefaults.c @@ -568,14 +568,16 @@ void wDefaultChangeIcon(const char *instance, const char *class, const char *fil icon_value = WMCreatePLDictionary(AIcon, value, NULL); WMReleasePropList(value); - if ((def_win = WMGetFromPLDictionary(dict, AnyWindow)) != NULL) + def_win = WMGetFromPLDictionary(dict, AnyWindow); + if (def_win != NULL) def_icon = WMGetFromPLDictionary(def_win, AIcon); if (def_icon && !strcmp(WMGetFromPLString(def_icon), file)) same = 1; } - if ((attr = WMGetFromPLDictionary(dict, key)) != NULL) { + attr = WMGetFromPLDictionary(dict, key); + if (attr != NULL) { if (WMIsPLDictionary(attr)) { if (icon_value != NULL && !same) WMMergePLDictionaries(attr, icon_value, False); diff --git a/src/winspector.c b/src/winspector.c index a3c384f..78b5cd0 100644 --- a/src/winspector.c +++ b/src/winspector.c @@ -376,7 +376,8 @@ static int getBool(WMPropList *value) if (!WMIsPLString(value)) return 0; - if (!(val = WMGetFromPLString(value))) + val = WMGetFromPLString(value); + if (val == NULL) return 0; if ((val[1] == '\0' && @@ -407,7 +408,8 @@ insertAttribute(WMPropList *dict, WMPropList *window, WMPropList *attr, WMPropLi int update = 0, modified = 0; if (!(flags & UPDATE_DEFAULTS) && dict) { - if ((def_win = WMGetFromPLDictionary(dict, AnyWindow)) != NULL) + def_win = WMGetFromPLDictionary(dict, AnyWindow); + if (def_win != NULL) def_value = WMGetFromPLDictionary(def_win, attr); } diff --git a/src/workspace.c b/src/workspace.c index 69db16c..c6052b3 100644 --- a/src/workspace.c +++ b/src/workspace.c @@ -492,7 +492,8 @@ void wWorkspaceForceChange(WScreen * scr, int workspace) wWorkspaceMenuUpdate(scr, scr->clip_ws_menu); - if ((tmp = scr->focused_window) != NULL) { + tmp = scr->focused_window; + if (tmp != NULL) { WWindow **toUnmap; int toUnmapSize, toUnmapCount; @@ -856,10 +857,11 @@ void wWorkspaceSaveState(WScreen * scr, WMPropList * old_state) WMPutInPLDictionary(wks_state, dClip, pstr); WMReleasePropList(pstr); } else if (old_wks_state != NULL) { - if ((foo = WMGetFromPLArray(old_wks_state, i)) != NULL) { - if ((bar = WMGetFromPLDictionary(foo, dClip)) != NULL) { + foo = WMGetFromPLArray(old_wks_state, i); + if (foo != NULL) { + bar = WMGetFromPLDictionary(foo, dClip); + if (bar != NULL) WMPutInPLDictionary(wks_state, dClip, bar); - } } } WMAddToPLArray(parr, wks_state); http://repo.or.cz/w/wmaker-crm.git/commit/e14fad11626e881b104d4cc520abfdecdb82532f commit e14fad11626e881b104d4cc520abfdecdb82532f Author: Christophe CURIS <christophe.cu...@free.fr> Date: Fri May 8 13:19:03 2015 +0200 wmaker: fix warnings from compiler when animations are disabled The code for animating stuff needs some parameters in a few functions, which are not used when animations are disabled at compile time, so the compiler issues some warnings about them. This patch adds the appropriate statements to disable declaration that are not needed in this case, and tell the compiler it is ok to not use the parameters not needed, thus fixing the warnings. Signed-off-by: Christophe CURIS <christophe.cu...@free.fr> diff --git a/src/actions.c b/src/actions.c index d69f900..2349978 100644 --- a/src/actions.c +++ b/src/actions.c @@ -57,6 +57,7 @@ static void find_Maximus_geometry(WWindow *wwin, WArea usableArea, int *new_x, i static void save_old_geometry(WWindow *wwin, int directions); /******* Local Variables *******/ +#ifdef USE_ANIMATIONS static struct { int steps; int delay; @@ -68,10 +69,12 @@ static struct { { SHADE_STEPS_US, SHADE_DELAY_US } }; -#define UNSHADE 0 -#define SHADE 1 #define SHADE_STEPS shadePars[(int)wPreferences.shade_speed].steps #define SHADE_DELAY shadePars[(int)wPreferences.shade_speed].delay +#endif + +#define UNSHADE 0 +#define SHADE 1 static int compareTimes(Time t1, Time t2) { @@ -1061,6 +1064,7 @@ static WWindow *recursiveTransientFor(WWindow *wwin) return wwin; } +#ifdef USE_ANIMATIONS static int getAnimationGeometry(WWindow *wwin, int *ix, int *iy, int *iw, int *ih) { if (wwin->screen_ptr->flags.startup || wPreferences.no_animations @@ -1087,6 +1091,7 @@ static int getAnimationGeometry(WWindow *wwin, int *ix, int *iy, int *iw, int *i } return 1; } +#endif /* USE_ANIMATIONS */ void wIconifyWindow(WWindow *wwin) { @@ -1397,6 +1402,11 @@ static void hideWindow(WIcon *icon, int icon_x, int icon_y, WWindow *wwin, int a wwin->frame->core->width, wwin->frame->core->height, icon_x, icon_y, icon->core->width, icon->core->height); } +#else + /* Tell the compiler it is normal that those parameters are not used in this case */ + (void) icon_x; + (void) icon_y; + (void) animate; #endif wwin->flags.skip_next_animation = 0; @@ -1575,6 +1585,12 @@ static void unhideWindow(WIcon *icon, int icon_x, int icon_y, WWindow *wwin, int wwin->frame_x, wwin->frame_y, wwin->frame->core->width, wwin->frame->core->height); } +#else + /* Tell the compiler it is normal that those parameters are not used in this case */ + (void) icon; + (void) icon_x; + (void) icon_y; + (void) animate; #endif wwin->flags.skip_next_animation = 0; if (wwin->screen_ptr->current_workspace == wwin->frame->workspace) { diff --git a/src/misc.c b/src/misc.c index bc324df..4144c7d 100644 --- a/src/misc.c +++ b/src/misc.c @@ -148,6 +148,10 @@ void move_window(Window win, int from_x, int from_y, int to_x, int to_y) SlideWindow(win, from_x, from_y, to_x, to_y); #else XMoveWindow(dpy, win, to_x, to_y); + + /* Tell the compiler it is normal that those parameters are not used in this case */ + (void) from_x; + (void) from_y; #endif } http://repo.or.cz/w/wmaker-crm.git/commit/0bab67f9be51efbd178a2c8ab43ce73cbc083777 commit 0bab67f9be51efbd178a2c8ab43ce73cbc083777 Author: Christophe CURIS <christophe.cu...@free.fr> Date: Fri May 8 13:19:02 2015 +0200 configure: Added option to disable animations The old behaviour was to expect the user to go modify manually a source file which is not a great idea because that's typically the kind of things in charge of the configure script. Signed-off-by: Christophe CURIS <christophe.cu...@free.fr> diff --git a/README b/README index e85083b..7195e5f 100644 --- a/README +++ b/README @@ -201,7 +201,8 @@ while keeping a nice appearance and good functionality, follow the items bellow: - edit wconfig.h and disable the NUMLOCK_HACK and the features you don't use anyway (keep in mind that some of the #defines might not work, as they are not fully supported). Make sure to always keep NumLock and ScrollLock turned off. -- turn on DisableAnimations. You can also #undefine ANIMATIONS in wconfig.h +- turn on DisableAnimations. You can also specify --disable-animation at compile + time to the configure script. - strip down the default IconPath and PixmapPath entries to contain only the paths that you really have in your system. - do not use large images in the root background diff --git a/configure.ac b/configure.ac index 6a02376..491bdc7 100644 --- a/configure.ac +++ b/configure.ac @@ -289,6 +289,18 @@ AC_ARG_WITH(incs-from, AS_HELP_STRING([--with-incs-from], [pass compiler flags t dnl Features Configuration dnl ====================== +AC_ARG_ENABLE([animations], + [AS_HELP_STRING([--disable-animations], [disable permanently animations @<:@default=enabled@:>@])], + [AS_CASE(["$enableval"], + [yes|no], [], + [AC_MSG_ERROR([bad value $enableval for --enable-animations])])], + [enable_animations="yes"]) +AS_IF([test "x$enable_animations" = "xno"], + [unsupported="$unsupported Animations"], + [AC_DEFINE([USE_ANIMATIONS], [1], [Defined when user did not request to disable animations]) + supported_core="$supported_core Animations"]) + + AC_ARG_ENABLE([mwm-hints], [AS_HELP_STRING([--disable-mwm-hints], [disable support for Motif WM hints @<:@default=enabled@:>@])], [AS_CASE(["$enableval"], diff --git a/doc/build/Compilation.texi b/doc/build/Compilation.texi index 4db3ae0..095718c 100644 --- a/doc/build/Compilation.texi +++ b/doc/build/Compilation.texi @@ -566,6 +566,10 @@ screen size. @subsection Feature Selection @table @option +@item --disable-animations +Disable animations permanently, by not compiling the corresponding code into @sc{Window Maker}. +When enabled (the default), you still have a run-time configuration option in @emph{WPrefs}. + @item --disable-mwm-hints Disable support for Motif's MWM Window Manager hints. These attributes were introduced by the Motif toolkit to ask for special window appearance requests. diff --git a/src/wconfig.h.in b/src/wconfig.h.in index be0295c..bac5072 100644 --- a/src/wconfig.h.in +++ b/src/wconfig.h.in @@ -33,9 +33,6 @@ * Also check the features you can enable through configure. */ -/* If you want animations for iconification, shading, icon arrangement etc. */ -#define USE_ANIMATIONS - /* * Undefine BALLOON_TEXT if you don't want balloons for showing extra * information, like window titles that are not fully visible. http://repo.or.cz/w/wmaker-crm.git/commit/6ef010d974b8b45c2d0128dec59b9ec3c170af48 commit 6ef010d974b8b45c2d0128dec59b9ec3c170af48 Author: Christophe CURIS <christophe.cu...@free.fr> Date: Fri May 8 13:19:01 2015 +0200 Code refactoring: replaced macro 'ANIMATIONS' by 'USE_ANIMATIONS' for consistency The usual way to define a macro in is to name macro with 'USE_xxx' when they are used to enable a feature 'xxx'. Signed-off-by: Christophe CURIS <christophe.cu...@free.fr> diff --git a/src/actions.c b/src/actions.c index 1d46b03..d69f900 100644 --- a/src/actions.c +++ b/src/actions.c @@ -82,7 +82,7 @@ static int compareTimes(Time t1, Time t2) return (diff < 60000) ? 1 : -1; } -#ifdef ANIMATIONS +#ifdef USE_ANIMATIONS static void shade_animate(WWindow *wwin, Bool what); #else static inline void shade_animate(WWindow *wwin, Bool what) @@ -254,7 +254,7 @@ void wShadeWindow(WWindow *wwin) WMPostNotificationName(WMNChangedState, wwin, "shade"); -#ifdef ANIMATIONS +#ifdef USE_ANIMATIONS if (!wwin->screen_ptr->flags.startup) { /* Catch up with events not processed while animation was running */ ProcessPendingEvents(); @@ -763,7 +763,7 @@ void wUnfullscreenWindow(WWindow *wwin) } } -#ifdef ANIMATIONS +#ifdef USE_ANIMATIONS static void animateResizeFlip(WScreen *scr, int x, int y, int w, int h, int fx, int fy, int fw, int fh, int steps) { #define FRAMES (MINIATURIZE_ANIMATION_FRAMES_F) @@ -974,7 +974,7 @@ void animateResize(WScreen *scr, int x, int y, int w, int h, int fx, int fy, int break; } } -#endif /* ANIMATIONS */ +#endif /* USE_ANIMATIONS */ static void flushExpose(void) { @@ -1174,7 +1174,7 @@ void wIconifyWindow(WWindow *wwin) unmapTransientsFor(wwin); if (present) { -#ifdef ANIMATIONS +#ifdef USE_ANIMATIONS int ix, iy, iw, ih; #endif XUngrabPointer(dpy, CurrentTime); @@ -1189,7 +1189,7 @@ void wIconifyWindow(WWindow *wwin) wClientSetState(wwin, IconicState, wwin->icon->icon_win); flushExpose(); -#ifdef ANIMATIONS +#ifdef USE_ANIMATIONS if (getAnimationGeometry(wwin, &ix, &iy, &iw, &ih)) animateResize(wwin->screen_ptr, wwin->frame_x, wwin->frame_y, wwin->frame->core->width, wwin->frame->core->height, ix, iy, iw, ih); @@ -1231,7 +1231,7 @@ void wIconifyWindow(WWindow *wwin) } else if (wPreferences.focus_mode != WKF_CLICK) { wSetFocusTo(wwin->screen_ptr, NULL); } -#ifdef ANIMATIONS +#ifdef USE_ANIMATIONS if (!wwin->screen_ptr->flags.startup) { /* Catch up with events not processed while animation was running */ Window clientwin = wwin->client_win; @@ -1307,7 +1307,7 @@ void wDeiconifyWindow(WWindow *wwin) /* if the window is in another workspace, do it silently */ if (!netwm_hidden) { -#ifdef ANIMATIONS +#ifdef USE_ANIMATIONS int ix, iy, iw, ih; if (getAnimationGeometry(wwin, &ix, &iy, &iw, &ih)) animateResize(wwin->screen_ptr, ix, iy, iw, ih, @@ -1340,7 +1340,7 @@ void wDeiconifyWindow(WWindow *wwin) wSetFocusTo(wwin->screen_ptr, wwin); -#ifdef ANIMATIONS +#ifdef USE_ANIMATIONS if (!wwin->screen_ptr->flags.startup) { /* Catch up with events not processed while animation was running */ Window clientwin = wwin->client_win; @@ -1390,7 +1390,7 @@ static void hideWindow(WIcon *icon, int icon_x, int icon_y, WWindow *wwin, int a wClientSetState(wwin, IconicState, icon->icon_win); flushExpose(); -#ifdef ANIMATIONS +#ifdef USE_ANIMATIONS if (!wwin->screen_ptr->flags.startup && !wPreferences.no_animations && !wwin->flags.skip_next_animation && animate) { animateResize(wwin->screen_ptr, wwin->frame_x, wwin->frame_y, @@ -1568,7 +1568,7 @@ static void unhideWindow(WIcon *icon, int icon_x, int icon_y, WWindow *wwin, int wwin->flags.hidden = 0; -#ifdef ANIMATIONS +#ifdef USE_ANIMATIONS if (!wwin->screen_ptr->flags.startup && !wPreferences.no_animations && animate) { animateResize(wwin->screen_ptr, icon_x, icon_y, icon->core->width, icon->core->height, @@ -1825,10 +1825,10 @@ void wArrangeIcons(WScreen *scr, Bool arrangeAll) head = wGetHeadForWindow(aicon->icon->owner); if (aicon->x_pos != X || aicon->y_pos != Y) { -#ifdef ANIMATIONS +#ifdef USE_ANIMATIONS if (!wPreferences.no_animations) SlideWindow(aicon->icon->core->window, aicon->x_pos, aicon->y_pos, X, Y); -#endif /* ANIMATIONS */ +#endif /* USE_ANIMATIONS */ } wAppIconMove(aicon, X, Y); vars[head].pi++; @@ -1946,7 +1946,7 @@ void wMakeWindowVisible(WWindow *wwin) * Do the animation while shading (called with what = SHADE) * or unshading (what = UNSHADE). */ -#ifdef ANIMATIONS +#ifdef USE_ANIMATIONS static void shade_animate(WWindow *wwin, Bool what) { int y, s, w, h; diff --git a/src/misc.c b/src/misc.c index 137d78e..bc324df 100644 --- a/src/misc.c +++ b/src/misc.c @@ -141,7 +141,7 @@ static void eatExpose(void) void move_window(Window win, int from_x, int from_y, int to_x, int to_y) { -#ifdef ANIMATIONS +#ifdef USE_ANIMATIONS if (wPreferences.no_animations) XMoveWindow(dpy, win, to_x, to_y); else diff --git a/src/wconfig.h.in b/src/wconfig.h.in index 4a56e04..be0295c 100644 --- a/src/wconfig.h.in +++ b/src/wconfig.h.in @@ -34,7 +34,7 @@ */ /* If you want animations for iconification, shading, icon arrangement etc. */ -#define ANIMATIONS +#define USE_ANIMATIONS /* * Undefine BALLOON_TEXT if you don't want balloons for showing extra http://repo.or.cz/w/wmaker-crm.git/commit/9d9b6d3fcf3553297c59c8b1fb20d2d03c9240d9 commit 9d9b6d3fcf3553297c59c8b1fb20d2d03c9240d9 Author: Christophe CURIS <christophe.cu...@free.fr> Date: Fri May 8 13:19:00 2015 +0200 wmaker: fix incorrect type for variable in the global preference structure As pointed by the new check script, the preference "show_clip_title" is defined as a Boolean value in the preference loading function, which uses the callback function "getBool", which expect a variable of type "char", but the variable was not defined with that type. This patch changes the type for the appropriate one to avoid possible problems. Signed-off-by: Christophe CURIS <christophe.cu...@free.fr> diff --git a/src/WindowMaker.h b/src/WindowMaker.h index 0a1d81f..ccdb6c8 100644 --- a/src/WindowMaker.h +++ b/src/WindowMaker.h @@ -459,7 +459,7 @@ extern struct WPreferences { union WTexture *wsmbackTexture; - int show_clip_title; + char show_clip_title; struct { unsigned int nodock:1; /* don't display the dock */ http://repo.or.cz/w/wmaker-crm.git/commit/ba3e57597192dc6548ea68adb4f92d1f60187411 commit ba3e57597192dc6548ea68adb4f92d1f60187411 Author: Christophe CURIS <christophe.cu...@free.fr> Date: Fri May 8 13:18:59 2015 +0200 wmaker: add script to check the call-back function used when loading configuration Because the C compiler cannot check the consistency between the type of the variable being pointed to, and the type expected by the call-back function that is used to parse and store the value from the configuration file, there is a risk of mismatch that can cause Window Maker to misbehave due to data corruption, which depends strongly on the configuration values and the architecture on which Window Maker is running. This patch introduces a script that checks the consistency where possible, to raise the issues when performing "make check". Signed-off-by: Christophe CURIS <christophe.cu...@free.fr> diff --git a/Makefile.am b/Makefile.am index 5b52d1a..d0b6688 100644 --- a/Makefile.am +++ b/Makefile.am @@ -40,6 +40,7 @@ EXTRA_DIST = TODO BUGS BUGFORM FAQ INSTALL \ email-clients.txt checkpatch.pl update-changelog.pl \ script/check-cmdline-options-doc.sh \ script/check-translation-sources.sh \ + script/check-wmaker-loaddef-callbacks.sh \ script/generate-mapfile-from-header.sh \ script/generate-po-from-template.sh \ script/generate-txt-from-texi.sh \ diff --git a/script/check-wmaker-loaddef-callbacks.sh b/script/check-wmaker-loaddef-callbacks.sh new file mode 100755 index 0000000..1cc9541 --- /dev/null +++ b/script/check-wmaker-loaddef-callbacks.sh @@ -0,0 +1,470 @@ +#!/bin/sh +########################################################################### +# +# Window Maker window manager +# +# Copyright (c) 2015 Christophe CURIS +# Copyright (c) 2015 Window Maker Team +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see <http://www.gnu.org/licenses/>. +# +########################################################################### +# +# check-wmaker-loaddef-callbacks.sh: +# Compare the type defined in a variable against the type use for the +# associated call-back function. +# +# To load the configuration file, Window Maker is using a list of the known +# keywords in a structure with the name of the keyword, the call-back +# function that converts the string (from file) into the appropriate type, +# and a pointer to the variable where the result is saved. +# +# Because the structure requires a little bit of genericity to be usefull, +# it is not possible to provide the C compiler with the information to +# check that the variable from the pointer has the same type as what the +# conversion call-back assumes, so this script does that check for us. +# +# Unfortunately, the script cannot be completely generic and smart, but +# it still tries to be, despite being made explicitely for the case of the +# structures "staticOptionList" and "optionList" from Window Maker's source +# file "src/defaults.c" +# +########################################################################### +# +# For portability, we stick to the same sh+awk constraint as Autotools to +# limit problems, see for example: +# http://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Portable-Shell.html +# +########################################################################### + +# Report an error on stderr and exit with status 2 to tell make that we could +# not do what we were asked +arg_error() { + echo "`basename $0`: $@" >&2 + exit 2 +} + +# print help and exit with success status +print_help() { + echo "$0: check variable type against call-back expectation for WMaker's defaults.c" + echo "Usage: $0 options..." + echo "valid options are:" + echo " --callback \"name=type\" : specify that function 'name' expects a variable of 'type'" + echo " --field-callback idx : index (from 1) of the callback function in the struct" + echo " --field-value-ptr idx : index (from 1) of the pointer-to-value in the struct" + echo " --source file : C source file with the array to check" + echo " --structure name : name of the variable with the array of struct to check" + echo " --struct-def name=file : specify to get definition of struct 'name' from 'file'" + exit 0 +} + +# Extract command line arguments +while [ $# -gt 0 ]; do + case $1 in + --callback) + shift + deflist="$1," + while [ -n "$deflist" ]; do + name_and_type=`echo "$deflist" | cut -d, -f1 | sed -e 's/^[ \t]*//;s/[ \t]*$//' ` + deflist=`echo "$deflist" | cut -d, -f2-` + echo "$name_and_type" | grep '^[A-Za-z][A-Za-z_0-9]*[ \t]*=[^=][^=]*$' > /dev/null || \ + arg_error "invalid callback function type specification '$name_and_type' (options: --callback)" + name=`echo "$name_and_type" | sed -e 's/=.*$// ; s/[ \t]//g' ` + type=`echo "$name_and_type" | sed -e 's/^[^=]*=// ; s/^[ \t]*// ; s/[ \t][ \t]*/ /g' ` + awk_callback_types="$awk_callback_types + callback[\"$name\"] = \"$type\";" + done + ;; + + --field-callback) + shift + [ -z "$field_callback" ] || arg_error "field number specified more than once (option: --field-callback)" + field_callback="$1" + ;; + + --field-value-ptr) + shift + [ -z "$field_value" ] || arg_error "field number specified more than once (option: --field-value-ptr)" + field_value="$1" + ;; + + --source) + shift + [ -z "$source_file" ] || arg_error "only 1 source file can be used (option: --source)" + source_file="$1" + ;; + + --structure) + shift + [ -z "$struct_name" ] || arg_error "only 1 structure can be checked (option: --structure)" + struct_name="$1" + ;; + + --struct-def) + shift + echo "$1" | grep '^[A-Za-z][A-Z_a-z0-9]*=' > /dev/null || arg_error "invalid syntax in \"$1\" for --struct-def" + [ -r "`echo $1 | sed -e 's/^[^=]*=//' `" ] || arg_error "file not readable in struct-def \"$1\"" + list_struct_def="$list_struct_def +$1" + ;; + + -h|-help|--help) print_help ;; + -*) arg_error "unknow option '$1'" ;; + + *) + arg_error "argument '$1' is not understood" + ;; + esac + shift +done + +# Check consistency of command-line +[ -z "$source_file" ] && arg_error "no source file given (option: --source)" +[ -z "$struct_name" ] && arg_error "no variable name given for the array to check (option: --structure)" +[ -z "$field_value" ] && arg_error "index of the value pointer in the struct no specified (option: --field-value-ptr)" +[ -z "$field_callback" ] && arg_error "index of the call-back in the struct no specified (option: --field-callback)" + +echo "$field_value" | grep '^[1-9][0-9]*$' > /dev/null || arg_error "invalid index for the value pointer, expecting a number (option: --field-value-ptr)" +echo "$field_callback" | grep '^[1-9][0-9]*$' > /dev/null || arg_error "invalid index for the call-back function, expecting a number (option: --field-callback)" + +########################################################################### + +# This AWK script is extracting the types associated with the field members +# from a specific structure defined in the parsed C source file +awk_extract_struct=' +# Parse all the lines until the end of current structure is found +function parse_structure(prefix) { + while (getline) { + + # Discard C comments, with support for multi-line comments + while (1) { + idx = index($0, "/*"); + if (idx == 0) { break; } + + comment = substr($0, idx+2); + $0 = substr($0, 1, idx-1); + while (1) { + idx = index(comment, "*/"); + if (idx > 0) { break; } + getline comment; + } + $0 = $0 substr(comment, idx+2); + } + + # skip line that define nothing interresting + if (/^[ \t]*$/) { continue; } + gsub(/^[ \t]+/, ""); + if (/^#/) { continue; } + gsub(/[ \t]+$/, ""); + + # end of current structure: extract the name and return it + if (/^[ \t]*\}/) { + gsub(/^\}[ \t]*/, ""); + name = $0; + gsub(/[ \t]*;.*$/, "", name); + gsub(/^[^;]*;/, ""); + return name; + } + + # Handle structure inside structure + if (/^(struct|union)[ \t]+\{/) { + name = parse_structure(prefix ",!"); + + # Update the name tracking the content of this struct to contain the name + # of the struct itself + match_prefix = "^" prefix ",!:"; + for (var_id in member) { + if (var_id !~ match_prefix) { continue; } + new_id = var_id; + gsub(/,!:/, ":" name ".", new_id); + member[new_id] = member[var_id]; + delete member[var_id]; + } + continue; + } + + if (!/;$/) { + print "Warning: line " FILENAME ":" NR " not understood inside struct" > "/dev/stderr"; + continue; + } + + # 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); + + # 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; + } + + # Pack the type to have something consistent + gsub(/^[ \t]+/, ""); + gsub(/[ \t]+$/, ""); + gsub(/[ \t]*\*[ \t]*/, "*"); + gsub(/[ \t]+/, " "); + + # 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; + } + } +} + +# The name of the variable is at the end, so find all structure definition +/^([a-z]*[ \t][ \t]*)*struct[ \t]/ { + + # Discard all words to find the first ; or { + gsub(/^([A-Za-z_0-9]*[ \t][ \t]*)+/, ""); + + # If not an { it is probably not what we are looking for + if (/^[^\{]/) { next; } + + # Read everything until we find the end of the structure; we assume a + # definition is limited to one line + name = parse_structure("@"); + + # If the name is what we expect, generate the appropriate stuff + if (name == expected_name) { + struct_found++; + for (i in member) { + $0 = i; + gsub(/^@:/, expected_name "."); + print " variable[\"" $0 "\"] = \"" member[i] "\";"; + } + } + + # Purge the array to not mix fields between the different structures + for (i in member) { delete member[i]; } +} + +# Check that everything was ok +END { + if (struct_found == 0) { + print "Error: structure \"" expected_name "\" was not found in " FILENAME > "/dev/stderr"; + exit 1; + } else if (struct_found > 1) { + print "Error: structure \"" expected_name "\" was defined more than once in " FILENAME > "/dev/stderr"; + exit 1; + } +} + +# Do not print anything else than what is generated while parsing structures +{ } +' + +# Extract the information for all the structures specified on the command line +awk_array_types=`echo "$list_struct_def" | while + IFS="=" read name file +do + [ -z "$name" ] && continue + + awk_script=" +BEGIN { + struct_found = 0; + expected_name = \"$name\"; +} +$awk_extract_struct" + + echo " # $file" + + awk "$awk_script" "$file" + [ $? -ne 0 ] && exit $? + +done` + +########################################################################### + +# Parse the source file to extract the list of call-back functions that are +# used; take the opportunity to extract information about the variable +# being pointed to now to avoid re-parsing too many times the file +awk_check_callbacks=' +# Search the final } for the current element in the array, then split the +# elements into the array "entry_elements" and remove that content from $0 +function get_array_element_and_split() { + nb_elements = 1; + entry_elements[nb_elements] = ""; + + $0 = substr($0, 2); + count_braces = 1; + while (count_braces > 0) { + char = substr($0, 1, 1); + $0 = substr($0, 2); + if (char == "{") { + count_braces++; + } else if (char == "}") { + count_braces--; + } else if (char ~ /[ \t]/) { + # Just discard + } else if (char == ",") { + if (count_braces == 1) { nb_elements++; entry_elements[nb_elements] = ""; } + } else if (char == "\"") { + entry_elements[nb_elements] = entry_elements[nb_elements] extract_string_to_element(); + } else if (char == "/") { + if (substr($0, 1, 1) == "/") { + getline; + while (/^#/) { getline; } + } else if (substr($0, 1, 1) == "*") { + $0 = substr($0, 2); + skip_long_comment(); + } else { + entry_elements[nb_elements] = entry_elements[nb_elements] char; + } + } else if (char == "") { + getline; + while (/^#/) { print "skip: " $0; getline; } + } else { + entry_elements[nb_elements] = entry_elements[nb_elements] char; + } + } +} + +# When a string enclosed in "" is encountered as part of the elements of the +# array, it requires special treatment, not to extract the information (we are +# unlikely to care about these fields) but to avoid mis-parsing the fields +function extract_string_to_element() { + content = "\""; + while (1) { + char = substr($0, 1, 1); + $0 = substr($0, 2); + if (char == "\\") { + content = content char substr($0, 1, 1); + $0 = substr($0, 2); + } else if (char == "\"") { + break; + } else if (char == "") { + getline; + } else { + content = content char; + } + } + return content "\""; +} + +# Wherever a long C comment (/* comment */) is encounter, it is discarded +function skip_long_comment() { + while (1) { + idx = index($0, "*/"); + if (idx > 0) { + $0 = substr($0, idx + 2); + break; + } + getline; + } +} + +# Search for the definition of an array with the good name +/^[ \t]*([A-Z_a-z][A-Z_a-z0-9*]*[ \t]+)+'$struct_name'[ \t]*\[\][ \t]*=[ \t]*\{/ { + struct_found++; + + $0 = substr($0, index($0, "{") + 1); + + # Parse all the elements of the array + while (1) { + + # Search for start of an element + while (1) { + gsub(/^[ \t]+/, ""); + if (substr($0, 1, 1) == "{") { break; } + if (substr($0, 1, 1) == "}") { break; } + if (substr($0, 1, 1) == "#") { getline; continue; } + if ($0 == "") { getline; continue; } + + # Remove comments + if (substr($0, 1, 2) == "//") { getline; continue; } + if (substr($0, 1, 2) == "/*") { + $0 = substr($0, 3); + skip_long_comment(); + } else { + print "Warning: line " NR " not understood in " FILENAME ", skipped" > "/dev/stderr"; + getline; + } + } + + # Did we find the end of the array? + if (substr($0, 1, 1) == "}") { break; } + + # Grab the whole content of the entry + entry_start_line = NR; + get_array_element_and_split(); + gsub(/^[ \t]*,/, ""); + + # Extract the 2 fields we are interrested in + if ((entry_elements[src_fvalue] != "NULL") && (entry_elements[src_ffunct] != "NULL")) { + + if (substr(entry_elements[src_fvalue], 1, 1) == "&") { + entry_elements[src_fvalue] = substr(entry_elements[src_fvalue], 2); + } else { + print "Warning: value field used in entry at line " entry_start_line " does not looke like a pointer" > "/dev/stderr"; + } + + if (variable[entry_elements[src_fvalue]] == "") { + print "Warning: type is not known for \"" entry_elements[src_fvalue] "\" at line " entry_start_line ", cannot check" > "/dev/stderr"; + } else if (callback[entry_elements[src_ffunct]] == "") { + print "Error: expected type for callback function \"" entry_elements[src_ffunct] "\" is not known, from " FILENAME ":" entry_start_line > "/dev/stderr"; + error_count++; + } else if (callback[entry_elements[src_ffunct]] != variable[entry_elements[src_fvalue]]) { + print "Error: type mismatch between function and variable in " FILENAME ":" entry_start_line > "/dev/stderr"; + print " Function: " entry_elements[src_ffunct] " expects \"" callback[entry_elements[src_ffunct]] "\"" > "/dev/stderr"; + print " Variable: " entry_elements[src_fvalue] " has type \"" variable[entry_elements[src_fvalue]] "\"" > "/dev/stderr"; + error_count++; + } + + } + } +} + +# Final checks +END { + if (error_count > 0) { exit 1; } + if (struct_found == 0) { + print "Error: structure \"'$struct_name'\" was not found in " FILENAME > "/dev/stderr"; + exit 1; + } else if (struct_found > 1) { + print "Error: structure \"'$struct_name'\" was defined more than once in " FILENAME > "/dev/stderr"; + exit 1; + } +} + +# Do not print anything else than what is generated while parsing the structure +{ } +' + +awk_script="BEGIN { +$awk_array_types +$awk_callback_types + + # Info on structure to be checked + src_fvalue = $field_value; + src_ffunct = $field_callback; + + # For checks + struct_found = 0; + error_count = 0; +} +$awk_check_callbacks" + +awk "$awk_script" "$source_file" || exit $? diff --git a/src/Makefile.am b/src/Makefile.am index 7fe9db7..771282e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -165,3 +165,32 @@ wmaker_LDADD = \ @XLIBS@ \ @LIBM@ \ @INTLIBS@ + +###################################################################### + +# Create a 'silent rule' for our make check the same way automake does +AM_V_CHKOPTS = $(am__v_CHKOPTS_$(V)) +am__v_CHKOPTS_ = $(am__v_CHKOPTS_$(AM_DEFAULT_VERBOSITY)) +am__v_CHKOPTS_0 = @echo " CHK $@" ; +am__v_CHKOPTS_1 = + +check-local: defaults-callbacks-static defaults-callbacks-dynamic + +# Check that the callback functions used to load the configuration match +# the type of the variable where the value will be stored +defaults-callbacks-static: + $(AM_V_CHKOPTS)$(top_srcdir)/script/check-wmaker-loaddef-callbacks.sh \ + --source "$(srcdir)/defaults.c" --structure "staticOptionList" \ + --field-value-ptr 4 --field-callback 5 \ + --struct-def "wPreferences=$(srcdir)/WindowMaker.h" \ + --callback "getBool=char, getEnum=char, getInt=int" \ + --callback "getModMask=int" + +defaults-callbacks-dynamic: + $(AM_V_CHKOPTS)$(top_srcdir)/script/check-wmaker-loaddef-callbacks.sh \ + --source "$(srcdir)/defaults.c" --structure "optionList" \ + --field-value-ptr 4 --field-callback 5 \ + --struct-def "wPreferences=$(srcdir)/WindowMaker.h" \ + --struct-def "legacy_minipreview_config=$(srcdir)/defaults.c" \ + --callback "getBool=char, getEnum=char, getInt=int" \ + --callback "getPathList=char*, getCoord=WCoord" ----------------------------------------------------------------------- Summary of changes: Makefile.am | 1 + README | 3 +- configure.ac | 12 + doc/build/Compilation.texi | 4 + script/check-wmaker-loaddef-callbacks.sh | 470 +++++++++++++++++++++++++++++++ src/Makefile.am | 29 ++ src/WindowMaker.h | 2 +- src/actions.c | 50 ++-- src/appicon.c | 6 +- src/appmenu.c | 3 +- src/balloon.c | 27 +- src/dialog.c | 9 +- src/dock.c | 76 +++-- src/event.c | 6 +- src/misc.c | 20 +- src/misc.h | 8 +- src/monitor.c | 3 +- src/osdep_bsd.c | 9 +- src/osdep_linux.c | 6 +- src/rootmenu.c | 31 +- src/screen.c | 21 +- src/session.c | 26 +- src/wconfig.h.in | 3 - src/wdefaults.c | 6 +- src/winmenu.c | 149 +++++----- src/winspector.c | 6 +- src/workspace.c | 10 +- src/wsmap.c | 8 +- 28 files changed, 793 insertions(+), 211 deletions(-) create mode 100755 script/check-wmaker-loaddef-callbacks.sh repo.or.cz automatic notification. Contact project admin crma...@gmail.com if you want to unsubscribe, or site admin ad...@repo.or.cz if you receive no reply. -- wmaker-crm.git ("The Window Maker window manager") -- To unsubscribe, send mail to wmaker-dev-unsubscr...@lists.windowmaker.org.