The history is actually loaded from a file into a property list that
is then converted to an array. The intermediate property list was
not freed, which led to memory leak.
It looks like it was a tentative of optimisation to avoid duplicating
an already allocated string and re-use the pointer instead, but this
means it is not possible to free the original container as it would
free the string too.
There is a better way to do this, but it requires an API change on the
WUtil library so it is left for a future improvment.
The previous code limited the number of entries that were read into
the history array, but the user is expecting a maximum on the
number of entries displayed. This can make a little difference in
two cases:
- if there are duplicate entries (dups are checked for and removed)
- if some entries are not strings (unlikely, but not impossible)
The new code just stops adding history entries when the user
specified count is reached.
When menus are read in the PropList format, they are loaded into a
temporary PropList object, which is parsed into the internal menu
structure, and the PropList object is no more used. There were two
cases where this temp object was not freed.
A common argument to all these functions is the name of the key to
operate on, and this name is never modified by the functions. Marking
it as const reflects this, and can allow compiler to generate better
results thanks to this info.
The addition of the const attributes is actually an API change, so
we have to reflect this for the next official release.
Because the change on 'wusergnusteppath' may impact users of the API,
we won't only change REVISION like it was done for WRaster lib.
The first optimisation is to compute only once the path, and then
always re-use the value which did not change anyway.
The second optimisation is to avoid a lot of excessive function
calls, including alloc+free that are not necessary and participate
in memory fragmentation.
According to the way its value is being used everywhere, that is
what would be expected, so let's make it official.
Please note that this may introduce warnings on user code using
this function ("...discard const...") but that's an opportunity
for them to check that their code is not doing anything wrong.
The internal function 'unescapestr' is used to transform strings which
may contain escape sequences (\x) into their plain representation.
There are a few cases where the function can misbehave (typically parse
after the end of string, thus writing past the end of the reserved
result area) which can be a source of problem later. The new code
should be safer.
The previous syntax used an explicit cast to remove the CONST
attribute, but the right way is to keep the attribute and store
the result in a variable which is defined properly.
This makes the WUtil API as much const-correct as possible for
the arguments being given to its functions.
This does not make it totally correct as it does not changes the
const-ness on returned values because the goal of this patch is
to make no visible change to existing program that would use this
library.
Note that the argument is also stored as-is in the PLData structure
but only for debugging purpose (warning display to user), hence the
choice to not duplicate it. As a side effect, it was 'const'-ified
too to reflect that.
As a side note, in 'wfindfileinlist' the first argument should be:
const char * const *path_list
However, due to limited support for const in plain C, that would
introduce warnings in user code. For compatibility issues, this
was not implemented.
A number of functions do not actually modify the strings given as
parameter, but only read or duplicate it. In this case it is a good
practice to mark that parameter as pointer-to-const to let the
compiler known about it, to be able to perform appropriate
optimisations.
Prototype of function changed in commit
d1e1c13fa3
but two of them were not updated in the source.
Thanks to Rodolfo García Peñas for taking the time to test and report.
The addition of 'const' to parameters of library's functions is an
API change, although this will break neither the binary interface
nor the compilation of program using the library; the other changes
also have no impact on the compiled library object.
All these functions expects agruments like color or list-of-points
that should not be modified (and are not) by the function; added
the corresponding qualifier to reflect that.
An enum is always a better idea as it allows the compiler to do
some checks, and as this info is internal only to the WRLib it
will not change the API.
The functions are declared in different files but they were called
in another file which re-declared the prototypes. This is dangerous
as it can lead to misaligned prototypes when functions changes.
They are now grouped in the library internal header 'imgformat.h'
The config-file-keyword was defined in an array, but the user displayed
string was defined at another place, thus requiring special care when
modifying the list, to keep the same number of entries, in the same
order, ...
This was an open call for subtle bugs, so the keyword and user string
are now at a single place, making updates on the list easier and the
GUI generation code smaller.
If the switchpanel was opened with either FocusNextKey or FocusPrevKey
shortcut, and the user presses GroupNextKey or GroupPrevKey, skip over
windows of a different class when cycling through windows in the
switchpanel.
In the case where the switchpanel was opened with FocusNextKey or
FocusPrevKey initially, the check can be skipped because all the
available choices are necessarily of the same class already.
The hasModifier flag was set if the FocusNextKey or FocusPrevKey
shortcuts had modifiers, depending on which shortcut was used to open
the switchpanel.
The switchpanel can also be opened with the GroupNextKey or GroupPrevKey
shortcuts, so we should account for those when setting hasModifier.
Window Maker's behaviour changes when StrictWindozeCycle is active. As
a rule we try not to set the default value of new options such that they
would change the behaviour expected by users.
In this case, however, the switchpanel was not working as intended.
Users who prefer the old method can set StrictWindozeCycle off with
wdwrite WindowMaker StrictWindozeCycle NO
As the name implies, StartWindozeCycle() cycles windows in the same way
that a popular commercially-available operating system does. However
Window Maker's handling of the shift key in the switchpanel does not
currently mirror that of its commercial counterpart.
In the popular operating system:
Holding alt and shift then pressing and releasing tab will highlight
the previous window in the switcher.
Releasing shift with alt still held will not close the switcher.
The window change is commited when alt is released.
In Window Maker:
Holding alt and shift then pressing and releasing tab will highlight
the previous window in the switchpanel.
Releasing shift with alt still held will close the switchpanel and commit
the window change.
This patch adds the StrictWindozeCycle boolean preference. When it is
set to YES the switchpanel will remain open as long as alt is held even
if shift is pressed and released.
The default case is moved to the bottom of the switch case.
The default case should be removed, because the icon has always
a right value, because the icon creation always uses a real value:
kix@debian:~/src/wmaker/wmaker-crm/src$ grep wAppIconCreateForDock *c
appicon.c:WAppIcon *wAppIconCreateForDock(WScreen *scr, char *command, char *wm_instance, char *wm_class, int tile)
dock.c: btn = wAppIconCreateForDock(scr, NULL, "Logo", "WMClip", TILE_CLIP);
dock.c: btn = wAppIconCreateForDock(scr, NULL, "Logo", "WMDock", TILE_NORMAL);
dock.c: btn = wAppIconCreateForDock(scr, NULL, name, "WMDrawer", TILE_DRAWER);
dock.c: aicon = wAppIconCreateForDock(scr, command, winstance, wclass, TILE_NORMAL);
(1)dock.c: aicon = wAppIconCreateForDock(dock->screen_ptr, NULL,
kix@debian:~/src/wmaker/wmaker-crm/src$
kix@debian:~/src/wmaker/wmaker-crm/src$ grep TILE_ *c | grep -v ICON_TILE_SIZE
***[2]appicon.c: tile = TILE_CLIP;
dock.c: btn = wAppIconCreateForDock(scr, NULL, "Logo", "WMClip", TILE_CLIP);
dock.c: btn = wAppIconCreateForDock(scr, NULL, "Logo", "WMDock", TILE_NORMAL);
dock.c: btn = wAppIconCreateForDock(scr, NULL, name, "WMDrawer", TILE_DRAWER);
dock.c: aicon = wAppIconCreateForDock(scr, command, winstance, wclass, TILE_NORMAL);
(2)dock.c: wm_instance, wm_class, TILE_NORMAL);
***[3]icon.c: icon->tile_type = TILE_NORMAL;
icon.c: case TILE_NORMAL:
icon.c: case TILE_CLIP:
icon.c: case TILE_DRAWER:
kix@debian:~/src/wmaker/wmaker-crm/src$ grep tile_type *c
icon.c: icon->tile_type = TILE_NORMAL;
***[1]icon.c: icon->tile_type = tile;
icon.c: switch (icon->tile_type) {
icon.c: wwarning("Unknown tile type: %d.\n", icon->tile_type);
kix@debian:~/src/wmaker/wmaker-crm/src$
There are only three cases without value (asterisk in the line start) set
as preprocessor variable. (1) and (2) is the same call. These are the three cases:
Case [1]:
-------------8<--------------
WIcon *icon_create_for_dock(WScreen *scr, char *command, char *wm_instance, char *wm_class, int tile)
{
WIcon *icon;
icon = icon_create_core(scr, 0, 0);
icon->tile_type = tile;
-------------8<--------------
Calls to icon_create_for_dock, is only call in appicon.c:
-------------8<--------------
kix@debian:~/src/wmaker/wmaker-crm/src$ grep icon_create_for_dock *c
appicon.c: aicon->icon = icon_create_for_dock(scr, command, wm_instance, wm_class, tile);
icon.c:WIcon *icon_create_for_dock(WScreen *scr, char *command, char *wm_instance, char *wm_class, int tile)
kix@debian:~/src/wmaker/wmaker-crm/src$
-------------8<--------------
The call:
-------------8<--------------
WAppIcon *wAppIconCreateForDock(WScreen *scr, char *command, char *wm_instance, char *wm_class, int tile)
{
[snip]
if (strcmp(wm_class, "WMDock") == 0 && wPreferences.flags.clip_merged_in_dock)
tile = TILE_CLIP;
aicon->icon = icon_create_for_dock(scr, command, wm_instance, wm_class, tile);
-------------8<--------------
And the calls to wAppIconCreateForDock() are checked before.
The case [2] is just the line:
-------------8<--------------
WAppIcon *wAppIconCreateForDock(WScreen *scr, char *command, char *wm_instance, char *wm_class, int tile)
{
[snip]
if (strcmp(wm_class, "WMDock") == 0 && wPreferences.flags.clip_merged_in_dock)
*** tile = TILE_CLIP;
aicon->icon = icon_create_for_dock(scr, command, wm_instance, wm_class, tile);
-------------8<--------------
Then, is sure too.
The case [3] is:
-------------8<--------------
WIcon *icon_create_for_wwindow(WWindow *wwin)
{
[snip]
icon->tile_type = TILE_NORMAL;
-------------8<--------------
All windows have TILE_NORMAL.
Then, all cases are secure.
WMMergePLDictionaries() and WMSubtractPLDictionaries() are declared to
return WMPropList * but are set to call the wassertr macro when their
arguments do not pass a sanity check. The wassertr macro eventually
calls return with no return value, triggering a compiler warning if
-Wreturn-type is used.
Change wassertr to wassertrv and force a return of NULL in the error
case.
When first using the wmdrawer panel of WPrefs the settings
ClipAutoexpandDelay
ClipAutocollapseDelay
ClipAutoraiseDelay
ClipAutolowerDelay
are not yet saved in the user's config file and 'value' ends up
being undefined in showData() leading to a crash in adjustButtonSelectionBasedOnValue().
This patch is a workaround to make it possible to choose the config values for the
first time using WPrefs.
The dock will have the up-right and down-left arrows to change workspaces and
the clip will be disabled. That is, if option ClipMergedInDock is set to yes in
GNUstep/Defaults/WindowMaker.
[not thoroughly tested]
No more ghost dock when switching sides: the real swap happens
immediately, you can still adjust vertically afterwards. Removed two
functions in superfluous that are no longer used
Drawers are horizontal docks, and they can themselves only live in the dock
To use them, right click on the dock or a docked appicon and select "Add
a drawer". Then move appicons into the drawer (drag them with the
mouse). You may change the icon of the drawer. By default, drawers
auto-expand and -collapse, and auto-raise/lower. This can be customized
in the same way as for the clip.
Set DisableDrawers to YES in G/D/WindowMaker if you do not want to see
the menu entry to add a drawer.
Just discovered this bug: the auto-attract icon functionality will not
work (to be precise, it crashes WM!) if the clip is disabled
(NoClip=YES). Will fix shortly, of course.