A while loop in StartWindozeCycle() was checking the value of the panel
pointer and setting a flag to break out of the loop if it were NULL.
The current iteration of the loop was allowed to continue, however, with
the result that the null pointer could be passed to one of the
switchpanel functions and cause a segfault.
To reproduce, close all windows except one. Open the inspector and set
the window's "Do not show in the switch panel" flag. Then close the
inspector and press alt-tab to open the switchpanel. As there is only
one window and it is not allowed to appear in the switchpanel, a null
panel pointer is returned, then later passed to wSwitchPanelSelectNext()
causing wmaker to crash.
The fix is to break out of the loop immediately instead of setting the
done flag.
new window positions top left, top right, bottom left and bottom right
these new maximized positions are combinations of left, right, top and
bottom maximized positions
if a window was at x=0 or y=0, the original condition return
false and the window is not moved to original position,
but if width or height from old_geometry is set then wmaker
already saved old_geometry, and we can trust x=0 or y=0 is
original position.
- remove extern declaration in source file, use header instead
- add inclusion of header defining the functions of the file to
get the compiler to cross-check them
- marked static the functions that should not be visible ouside
their file
This is the correct way to tell that a function takes no
arguments, because an empty parameter list tells the compiler
that it is not yet defined, and is tolerated only for
compatibility with very old C compilers for whom prototypes
were not yet a defined language element.
The functions are now grouped by source file (groups in alphabetic
order) with the traditional separation mark. This makes the file
easier to work with.
The equality comparison (a == b) is known to be a dangerous trap
when floating-point arithmetics are involved. In the current case
the offending operation can be done with integers directly.
Some header were creating variable, this is a bad practice which
is likely to not behave as expected. This creates one distinct
variable in each object file that used the header, and:
- on well behaved compiler, this ends up in a link error (see
commit 39fdb451ba for an example)
- on bad behaving compiler, this can be linked as multiple local
variable, thus having strange effects when running program
- on insouciant compiler (who said gcc?) the variables are
silently merged, hiding portability issues
Autoconf provides the necessary stuff to detect if inline keyword
is supported, and to detect special syntaxes, so let's use this
and remove the multiple local definitions, this makes code simpler.
When using the formula [sizeof(array) / sizeof( x )] to get the number
of element in a static array, it is better to use array[0] for 'x'
instead of the base type of array:
- in case the base type would change someday;
- if the compiler were deciding to insert padding somewhere
Considering the number of headers we have, it is a good idea to
avoid possible problems. For details, you may read:
http://en.wikipedia.org/wiki/Include_guard
All headers should be ok now.
The automake documentation states that using substitution inside the
list of SOURCES will not work and calls for not doing it. The use
of 'EXTRA_xxx' made things look like they worked but is probably not
enough for corner cases.
This patches switches to the conditional method which will be safe.
This patch includes info about XRandR extension in the info panel
dialog. If wmaker was compiled with xrandr support, then the dialog
show the XRandR info. The info includes if the X-Server supports or not
XRandR (wmaker could be compiled with XRandR support, but the X Server
may not include XRandR extension).
The string was separated in two by Christophe Curis to allow translation,
as suggested by Alexey I. Froloff.
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.
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.
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.
Behaves essentially the same, only a bit more consistently.
Known differences:
1. An AppIcon will now always end up undocked if moved while Mod1 is pressed.
2. Moving a docked AppIcon with Mod1 pressed (undocking it) used to auto-expand the clip,
as clip expansion happened first, while looking for a snapping position,
and the test on Mod1 being pressed happened only later