Discussion:
Custom icons per window class/name patch
(too old to reply)
Earle F. Philhower III
2003-05-18 04:34:09 UTC
Permalink
Hi Ralf,

I did some checking in between packing today and it was relatively simple
to get the res_class and res_name of a window in the winCreateWin function,
but the thing is you can't use any XLib calls: you're the server itself at
that point, and not a client!

I've done a quick-n-easy icon specifier, namely a file called
c:\windows\xwin.ini . It's a standard old format text INI file with the
[sections] being the class and identifiers=c:\file.ico being the keys.
If a res_name isn't matched, it uses the _default key for the icon. If
the res_class isn't matched, the default X icon is used...
Ex:
[XLoad]
_default=z:\tmp\xload.ico

[Fig]
_default=z:\tmp\xfig.ico
file_popup=z:\tmp\file.ico

Note you need Windoze paths since I call the API LoadImage() to get the ICO
into a handle. Use "xprop" to get the res_name and res_class of a window.

There are 2 new small files, I created them in because they need special
includes that the main files don't need or want.

Feel free to use this as a base to add a nicer UI and maybe use XPMs and other
image formats instead of plain Windoze .icos...


-Earle F. Philhower, III
***@ziplabel.com
cdrlabel - ZipLabel - FlpLabel
http://www.cdrlabel.com
Harold L Hunt II
2003-05-18 18:56:00 UTC
Permalink
Earle,

Sorry to take this back to a discussion that you guys were having
earlier... but I remember that someone wrote something along the lines
of, "most window managers include their own set of icons for X apps
since most X apps do not set an icon to be shown on the upper-left hand
corner of the window".

When taken in the context of standard X window managers, that sounds
plausible. However, Exceed and XWin-32, if I recall correctly, seem to
display upper-left hand corner icons for most X apps. I sort of doubt
that Exceed and XWin-32 come with a set of icons for common X apps, but
I could be wrong.

Can anyone concretely prove to me that there is not a way to do app
icons without having a icon config file and a set of icon files for
common X apps? I would really like to avoid the headaches of
distributing icons and a new config file, if at all possible.

I am going to hold off on committing this patch until I am convinced
that it is the best way to go.


Thanks for contributing,

Harold
Post by Earle F. Philhower III
Hi Ralf,
I did some checking in between packing today and it was relatively simple
to get the res_class and res_name of a window in the winCreateWin function,
but the thing is you can't use any XLib calls: you're the server itself at
that point, and not a client!
I've done a quick-n-easy icon specifier, namely a file called
c:\windows\xwin.ini . It's a standard old format text INI file with the
[sections] being the class and identifiers=c:\file.ico being the keys.
If a res_name isn't matched, it uses the _default key for the icon. If
the res_class isn't matched, the default X icon is used...
[XLoad]
_default=z:\tmp\xload.ico
[Fig]
_default=z:\tmp\xfig.ico
file_popup=z:\tmp\file.ico
Note you need Windoze paths since I call the API LoadImage() to get the ICO
into a handle. Use "xprop" to get the res_name and res_class of a window.
There are 2 new small files, I created them in because they need special
includes that the main files don't need or want.
Feel free to use this as a base to add a nicer UI and maybe use XPMs and other
image formats instead of plain Windoze .icos...
-Earle F. Philhower, III
cdrlabel - ZipLabel - FlpLabel
http://www.cdrlabel.com
Earle F. Philhower III
2003-05-18 19:29:26 UTC
Permalink
Howdy!
Post by Harold L Hunt II
Sorry to take this back to a discussion that you guys were having
earlier... but I remember that someone wrote something along the lines of,
"most window managers include their own set of icons for X apps since most
X apps do not set an icon to be shown on the upper-left hand corner of the
window".
When taken in the context of standard X window managers, that sounds
plausible. However, Exceed and XWin-32, if I recall correctly, seem to
display upper-left hand corner icons for most X apps. I sort of doubt
that Exceed and XWin-32 come with a set of icons for common X apps, but I
could be wrong.
Can anyone concretely prove to me that there is not a way to do app icons
without having a icon config file and a set of icon files for common X
apps? I would really like to avoid the headaches of distributing icons
and a new config file, if at all possible.
I am going to hold off on committing this patch until I am convinced that
it is the best way to go.
Yes, you're right for some apps (like the Qt ones Ralf mentioned) the icon is
included in the application itself, and it sets the WM_HINTS accordingly. You
can then check for it in the winCreateWindow section and also in the WM_HINTS
property handler if it's changed later. Others don't and then it's up to the
WM to give them one, either from a config file or some built-in defaults. If
you do an xprop on a window and the WM_HINTS doesn't have a WM_ICON listed then
any icon you're seeing is a figment of the window manager. ;)

Quick check: xload has an icon it specifies, xterm doesn't
$ xprop (on xload) icon only, no bitmask
...
WM_HINTS(WM_HINTS):
Client accepts input or input focus: False
Initial state is Normal State.
bitmap id # to use for icon: 0xa00001
...
$ xprop (on xterm) no icon
...
WM_HINTS(WM_HINTS):
Client accepts input or input focus: True
Initial state is Normal State.
...
$ xprop (on xclock) both icon and mask
...
WM_HINTS(WM_HINTS):
Client accepts input or input focus: False
Initial state is Normal State.
bitmap id # to use for icon: 0xc00001
bitmap id # of mask for icon: 0xc00003
...

So a full-fledged patch should take that bitmap ID and convert it from an
XBM to a icon resource in the wincreate() function, and give the default or
config file specified icon for xterm.

Also, I didn't intend the change to be an official patch. Using a xwin.ini
file was just expedient. The proper thing would be to do a ~/.xwinrc file
format, and not use .icos but XPMs. Now that the ugly X server parts are
there I figure its easier for someone to put on the finishing touches...


-Earle F. Philhower, III
***@ziplabel.com
cdrlabel - ZipLabel - FlpLabel
http://www.cdrlabel.com
Ralf Habacker
2003-05-19 19:33:09 UTC
Permalink
Hi Earle,
Post by Earle F. Philhower III
Howdy!
Post by Harold L Hunt II
Sorry to take this back to a discussion that you guys were having
earlier... but I remember that someone wrote something along the lines of,
"most window managers include their own set of icons for X apps since most
X apps do not set an icon to be shown on the upper-left hand corner of the
window".
Can anyone concretely prove to me that there is not a way to do app icons
without having a icon config file and a set of icon files for common X
apps? I would really like to avoid the headaches of distributing icons
and a new config file, if at all possible.
I am going to hold off on committing this patch until I am convinced that
it is the best way to go.
Yes, you're right for some apps (like the Qt ones Ralf mentioned) the icon is
included in the application itself, and it sets the WM_HINTS accordingly. You
can then check for it in the winCreateWindow section and also in the WM_HINTS
property handler if it's changed later. Others don't and then it's up to the
WM to give them one, either from a config file or some built-in defaults.
... or this has to be provided by the client application (maintainer).

Because currently I have not idea how to deal with the pixmap files provided by
WM_HINTS (I have searched several hours to find an exact spec how to access the
pixmaps, unfortunally without any success, [does noone has used this before ?])
I'm going to provide a set of icon files for kde/qt with the next kde release.
Applying my patch (icon_base_filename=application_name [1]) and the LoadImage()
feature of searching all the pathes of the PATH environment var takes the burden
from the xserver maintainer to the application maintainer (like me).

The maintainer only have to release a set of icons for example in their client
bin directory (in my cases /opt/kde3/bin), which will be added to the PATH env
var before starting the xserver.
The xserver will search this files in case of starting applications, while basic
application without any icon would use the default 'x' icon.

Perhaps some time later after releasing the xserver with the icon feature the
application maintainer could be asked to provide some icons, which will be in
the bin dir of the xfree server without the need of any additional config
directory. Optionals users can use this ini file, but no by default. The only
requirements for this is [1], which seems not very complicated for me to deal
with.
Post by Earle F. Philhower III
So a full-fledged patch should take that bitmap ID and convert it from an
XBM to a icon resource in the wincreate() function, and give the default or
config file specified icon for xterm.
This was the best, but ... see above. :-(
Post by Earle F. Philhower III
Also, I didn't intend the change to be an official patch. Using a xwin.ini
file was just expedient. The proper thing would be to do a ~/.xwinrc file
format, and not use .icos but XPMs.
KDE/qt for example uses png images by default, so there may be more formats. My
suggestion is to start with this basic implementation and to see if other people
have some ideas and knowledge to enhance this.

Great Job Earle.

Ralf
Ralf Habacker
2003-05-20 05:55:15 UTC
Permalink
Post by Ralf Habacker
Because currently I have not idea how to deal with the pixmap files
provided by WM_HINTS (I have searched several hours to find an exact spec how
to
Post by Ralf Habacker
access the pixmaps, unfortunally without any success, [does noone has used
this
Post by Ralf Habacker
before ?])
An additional note: This belongs to the already know client versus server
problem. I have taken a look into twm, how it deals with this stuff, but ... it
was on the client side. :-(

BTW: Currently I'm writing a function GetWMHints() like you have done with
GetClassHint(). This is a task I can do. :-).

BTW2: I' going to put this function and GetClassHint() in a file named
winproperty.c.


Ralf
Earle F. Philhower III
2003-05-20 02:29:18 UTC
Permalink
Howdy Ralf!
...> can then check for it in the winCreateWindow section and also in the
WM_HINTS
Post by Earle F. Philhower III
property handler if it's changed later. Others don't and then it's up
to the
Post by Earle F. Philhower III
WM to give them one, either from a config file or some built-in defaults.
... or this has to be provided by the client application (maintainer).
Because currently I have not idea how to deal with the pixmap files
provided by
WM_HINTS (I have searched several hours to find an exact spec how to
access the
pixmaps, unfortunally without any success, [does noone has used this
before ?])
I'm going to provide a set of icon files for kde/qt with the next kde release.
Applying my patch (icon_base_filename=application_name [1]) and the
LoadImage()
feature of searching all the pathes of the PATH environment var takes the
burden
from the xserver maintainer to the application maintainer (like me).
The maintainer only have to release a set of icons for example in their client
bin directory (in my cases /opt/kde3/bin), which will be added to the PATH env
var before starting the xserver.
The xserver will search this files in case of starting applications, while
basic
application without any icon would use the default 'x' icon.
I have to admit that I agree with Harold on this, that the whole idea of cygwin
is to make Windoze look like any other Unix system. As I'm looking at more
of the commercial apps I use and the newer freeware ones I see that the
majority
do provide bitmap icons in the WM_HINTS, just the really old ones like xterm
don't. Even xload has one. [I was able to patch the XC distribution to get
a local working copy of xload, one that shows your Windoze CPU utilization.
If I get the time I'll submit it to the xfree-devel list and see what they
think
of including it in the next full release...]

IMHO the odds of you getting any SW group to make a special Windoze .ico
patch and files for cygwin is pretty small. There's extra work and most
folks using X11 are using Linux or other unix systems anyway so they aren't
going to have any tools to make .icos even if they wanted to. If it's your
own app, then sure. ;)

The pixmap format's not that bad, and if you defer the icon generation until
later you can do it in the WM thread, which is a valid X client so all the
nice X*() functions are available. Since you can now make a unique window
class from the WM_CLASS res_name and res_class, changing the icon in one
won't affect other apps. You might even get X to scale and change the depth
of the image to the standard Windoze formats by rendering the Pixmap into a
drawable, and then using the raw bits. That'd be SW reuse at its best!

Oh yeah, I think there's a tiny memory leak in the patch I sent before.
You need to free() the res_name and res_class after their use, I don't
think I did that, mybad!

...
KDE/qt for example uses png images by default, so there may be more
formats. My
suggestion is to start with this basic implementation and to see if other
people
have some ideas and knowledge to enhance this.
Eating PNG and JPEG files is not that bad, if you check out the sample
code in their SDKs they each have about a 30 statement main() that
decompresses an image into a RGB buffer. That would definitely be more
friendly to the Unix folks than .ICO, and if you link dynamically you won't
blow the server size up at all.

I can see your point, but it seems like the code is just a few steps away
from being a real standard window manager. If we get that, then the only
thing the commercial X servers have on xwin is speed, and I'll trade
reliability for speed any day when doing real work.


-Earle F. Philhower, III
***@ziplabel.com
cdrlabel - ZipLabel - FlpLabel
http://www.cdrlabel.com
Ralf Habacker
2003-05-19 19:19:42 UTC
Permalink
Post by Earle F. Philhower III
Hi Ralf,
I did some checking in between packing today and it was relatively simple
to get the res_class and res_name of a window in the winCreateWin function,
but the thing is you can't use any XLib calls: you're the server itself at
that point, and not a client!
Good that there is someone, who have got this. ;-)
Post by Earle F. Philhower III
I've done a quick-n-easy icon specifier, namely a file called
c:\windows\xwin.ini . It's a standard old format text INI file with the
[sections] being the class and identifiers=c:\file.ico being the keys.
If a res_name isn't matched, it uses the _default key for the icon. If
the res_class isn't matched, the default X icon is used...
[XLoad]
_default=z:\tmp\xload.ico
[Fig]
_default=z:\tmp\xfig.ico
file_popup=z:\tmp\file.ico
Note you need Windoze paths since I call the API LoadImage() to get the ICO
into a handle. Use "xprop" to get the res_name and res_class of a window.
Feel free to use this as a base to add a nicer UI and maybe use XPMs and other
image formats instead of plain Windoze .icos...

At first I've added my patch for accessing icons files directly by filename.

$ diff -ubB winmultiwindowwindow.c.orig winmultiwindowwindow.c
--- winmultiwindowwindow.c.orig 2003-05-19 21:10:18.000000000 +0200
+++ winmultiwindowwindow.c 2003-05-19 21:12:12.000000000 +0200
@@ -1399,6 +1399,10 @@
GetPrivateProfileString( res_class, res_name, "", fname, MAX_PATH,
"XWin.ini");
if (!fname[0]) /* Try the default icon instead */
GetPrivateProfileString( res_class, "_default", "", fname, MAX_PATH,
"XWin.ini");
+ if (!fname[0]) { /* at last try for an icon file located into a PATH var
located directory */
+ strcpy(fname,res_name);
+ strcat(fname,".ico");
+ }
if (fname[0]) {
HANDLE hIconFile;
/* Have a .ico filename, let's try and load it */

Ralf
Ralf Habacker
2003-05-20 07:14:28 UTC
Permalink
Hi Earle,

I've got this mail after sending my last notes, so please don't think I'm
ignoring your hints.
Post by Earle F. Philhower III
I have to admit that I agree with Harold on this, that the whole idea of
cygwin is to make Windoze look like any other Unix system. As I'm looking at
more
Post by Earle F. Philhower III
of the commercial apps I use and the newer freeware ones I see that the
majority do provide bitmap icons in the WM_HINTS, just the really old ones like
xterm
Post by Earle F. Philhower III
don't. Even xload has one. [I was able to patch the XC distribution to get
a local working copy of xload, one that shows your Windoze CPU utilization.
If I get the time I'll submit it to the xfree-devel list and see what they
think of including it in the next full release...]
I agree with you, that this would be the best solution, my suggestion was based
on my limited x related skills.
Post by Earle F. Philhower III
IMHO the odds of you getting any SW group to make a special Windoze .ico
patch and files for cygwin is pretty small. There's extra work and most
folks using X11 are using Linux or other unix systems anyway so they aren't
going to have any tools to make .icos even if they wanted to. If it's your
own app, then sure. ;)
The pixmap format's not that bad, and if you defer the icon generation until
later you can do it in the WM thread, which is a valid X client so all the
nice X*() functions are available.
Good to hear, but how to compute in detail ? Additional what about the
performance ?
Using the xclient means to transfer the image data every time icon setting will
be performed from the server to the client, which is the server, although the
data is directly asseccable on the server, isn't it ?
I assume based on the things I have learned from you, that all the image data
will be in some property on the server, which has only to be retrieved in some
mysteric way.

BTW: As a starting point I have written a GetWMHints() function similar to your
GetClassHint(). I can probably supply more such functions, If I would know which
property to retrieve.
Post by Earle F. Philhower III
Since you can now make a unique window class from the WM_CLASS res_name
and res_class, changing the icon in one won't affect other apps.
Yes, that make is more easier.
Post by Earle F. Philhower III
You might even get X to scale and change the depth
of the image to the standard Windoze formats by rendering the Pixmap into a
drawable, and then using the raw bits. That'd be SW reuse at its best!
I had taken a look into the fvwm source code, which does some pixmap
conversation, it seems to be a graphical bit processing task like changing image
depth to the CreateIcon() format and probably changing image format size)
Post by Earle F. Philhower III
Oh yeah, I think there's a tiny memory leak in the patch I sent before.
You need to free() the res_name and res_class after their use, I don't
think I did that, mybad!
...
Post by Ralf Habacker
KDE/qt for example uses png images by default, so there may be more
formats. My
suggestion is to start with this basic implementation and to see if other
people
have some ideas and knowledge to enhance this.
Eating PNG and JPEG files is not that bad, if you check out the sample
code in their SDKs they each have about a 30 statement main() that
decompresses an image into a RGB buffer. That would definitely be more
friendly to the Unix folks than .ICO, and if you link dynamically you won't
blow the server size up at all.
Using the WM_HINTS data make this obsolate, because the client application have
to convert this to the x11 pixmap format like qt does.
Post by Earle F. Philhower III
I can see your point, but it seems like the code is just a few steps away
from being a real standard window manager. If we get that, then the only
thing the commercial X servers have on xwin is speed, and I'll trade
reliability for speed any day when doing real work.
Let's go, but don't expect, that I'm a x11 guru :-)

Ralf

----------------------------------------------------------

#include <../../../../lib/X11/Xatomtype.h> // xPropWMHints

int GetWMHints(WindowPtr pWin, xPropWMHints **hints)
{
struct _Window *pwin;
struct _Property *prop;
pwin = (struct _Window*) pWin;

if (pwin->optional)
prop = (struct _Property *)pwin->optional->userProps;
else
prop = NULL;

*hints = NULL;
while (prop) {
if (prop->propertyName==XA_WM_HINTS
&& prop->type==XA_WM_HINTS
&& prop->format==32)
{
(*hints) = malloc(sizeof(xPropWMHints));
memcpy((*hints),prop->data,sizeof(xPropWMHints));
//ErrorF("hints.flags =%x\n",(*hints)->flags );
//ErrorF("hints.input =%x\n",(*hints)->input );
//ErrorF("hints.initialState=%x\n",(*hints)->initialState);
//ErrorF("hints.iconPixmap =%x\n",(*hints)->iconPixmap );
//ErrorF("hints.iconWindow =%x\n",(*hints)->iconWindow );
//ErrorF("hints.iconX =%x\n",(*hints)->iconX );
//ErrorF("hints.iconY =%x\n",(*hints)->iconY );
//ErrorF("hints.iconMask =%x\n",(*hints)->iconMask );
//ErrorF("hints.windowGroup =%x\n",(*hints)->windowGroup );
return 1;
}
else
prop = prop->next;
}

return 0;
}
Ralf Habacker
2003-05-21 11:15:35 UTC
Permalink
Hi Earle,
Post by Ralf Habacker
Good to hear, but how to compute in detail ? Additional what about the
performance ?
Using the xclient means to transfer the image data every time icon setting will
be performed from the server to the client, which is the server, although the
data is directly asseccable on the server, isn't it ?
I assume based on the things I have learned from you, that all the image data
will be in some property on the server, which has only to be retrieved in some
mysteric way.
I've got a little success.
Now I'm able to retrieve the pixmap pointer from the WM_HINTS structure and the
bitmap data, the CreateIcon returns an icon handle, but unfortunally the icon
isn't displayed.

Any hints ?

Cheers
Ralf


winCreateWindowsWindow (WindowPtr pWin)
<snip>

add the stuff below after the following two lines in winmultiwindowwindow.c:
winCreateWindowsWindow()
hIcon = LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN));
strcpy(classStr, WINDOW_CLASS_X);

------------------------------------------------------------------
{
xPropWMHints *hints;
GetWMHints(pWin, &hints);

if (hints->iconPixmap) {
PixmapPtr iconPtr;
PixmapPtr maskPtr;
char *iconData = 0;
char *maskData = 0;

iconPtr= LookupIDByType (hints->iconPixmap, RT_PIXMAP);
ErrorF("icon Pixmap found %x\n",iconPtr);
if (iconPtr) {
iconData = malloc(iconPtr->drawable.width * iconPtr->drawable.height *
(iconPtr->drawable.bitsPerPixel/8));
miGetImage((DrawablePtr)&iconPtr->drawable, 0, 0, iconPtr->drawable.width,
iconPtr->drawable.height, ZPixmap, 0xffff, iconData);
ErrorF("buffer %x\n",iconData);

maskPtr = LookupIDByType (hints->iconMask, RT_PIXMAP);
ErrorF("mask Pixmap found %x\n",maskPtr);
if (maskPtr) {
// FIXME: calc correct size
maskData = malloc((maskPtr->drawable.width * maskPtr->drawable.height) /
8 );
miGetImage((DrawablePtr)&maskPtr->drawable, 0, 0,
maskPtr->drawable.width, maskPtr->drawable.height, ZPixmap, 0xffff, maskData);
}

hIcon = CreateIcon(NULL,
iconPtr->drawable.width,
iconPtr->drawable.height,
1,
iconPtr->drawable.bitsPerPixel,
maskData, // lpbANDbits
iconData // lpbXORbits
);
free(iconData);
free(maskData);
}
}
}

------------------------------------------------------------------
Earle F. Philhower III
2003-05-23 06:18:06 UTC
Permalink
Howdy Ralf...
...Now I'm able to retrieve the pixmap pointer from the WM_HINTS structure
and the
bitmap data, the CreateIcon returns an icon handle, but unfortunally the icon
isn't displayed.
Any hints ?
I see your code, there are a few problems with it as far as what Windoze
wants in a bitmap (i.e. word alignment for starters, X bitmaps are byte
packed). But it's definitely right on track! You may want to test
ALT-TAB, if you have a 32x32 icon from X it WILL show it in the task
switcher from what I've seen...

Using your sample and just making fixed-size icons I found that only if you
make an icon of the win16x16 (the mini icon in window titles) will it
show that icon, OTW it shows a big, black box.

As a real kludge (it may be the only way, actually!) you might take the
X bitmap and make 2 icons and pack them into a memory-only resource
type of RT_GROUP_ICON, one SM_CXSMICON x SM_CYSMICON and one
SM_CXICON x SM_CYICON. You could also write your own .ICO temp file
and use the Windoze LoadImage call, but that's a pain converting
cygwin paths to Windoze paths...

I have a feeling this is one of the undocumented Windoze corners you
fear getting painted in to...

I'll look at this some more this weekend if it's not too nice...


-Earle F. Philhower, III
***@ziplabel.com
cdrlabel - ZipLabel - FlpLabel
http://www.cdrlabel.com
Ralf Habacker
2003-05-26 07:39:39 UTC
Permalink
Hi all,

while testing some KDE3 applications, I recognized that the application window
class distinction by WM_CLASS isn't enough, because kde applications uses
different icons for different windows of an application. This applications uses
the WM_WINDOW_ROLE property to distingh for example message box windows from
basic windows. Currently the icons of the main window are overwritten, because
all the windows of an application share the same window class.
The appended patch fix this. (Additional this patch fixes one segfault in
GetClassHint, I have recognized causes by a null WindowPtr)

Additional I have noticed the following issues:

1. Handling of modal dialogs and message boxes:

KDE applications support a type of depending dialogs (for example konsole and
about window) in the manner of the windows modal dialog type (not exactly),
which is used to group such windows in the task manager.
This allows the following features:
1. Hiding all application windows in case the basic one is set to hide
2. prevent displaying each window of an application in the task bar
3. moving all application related windows to another desktop
... may be more i cannot see now

KDE applications uses the WM_TRANSIENT_FOR property to distinuish normal windows
from depending windows (WM_TRANSIENT_FOR is set for a depending window).
http://tronche.com/gui/x/icccm/sec-4.html.

May be there is an solution to use modale windows for this type of windows.
Currently I have no implementation for this. This is just a hint.

2. KDE uses 16x16x16 sized icons for "modal dialogs" (48x48x16 for regular
icons), which seems to be not designed for displaying un the task bar or ALT-TAB
process switching window. Currently this type of icons are displayed wrongly.
CreateIcon() seems to stretch this icon so this result in displaying black
horizontal stripes. This problem would be solved, when issue 1. would be
implemented.

Cheers
Ralf
Earle F. Philhower III
2003-05-26 17:27:46 UTC
Permalink
Howdy Ralf,
Post by Ralf Habacker
while testing some KDE3 applications, I recognized that the application window
class distinction by WM_CLASS isn't enough, because kde applications uses
different icons for different windows of an application. This applications
uses
the WM_WINDOW_ROLE property to distingh for example message box windows from
basic windows. Currently the icons of the main window are overwritten, because
all the windows of an application share the same window class.
The appended patch fix this. (Additional this patch fixes one segfault in
GetClassHint, I have recognized causes by a null WindowPtr)
I'm not a KDE user so I can't test this directly, but are you
sure that the window role name is unique between applications?
Would it make sense to use the Windows class name a function of
both the res_role, res_name and res_class? Or is there only one
KDE "file open box" that all apps would share?

...
Post by Ralf Habacker
2. KDE uses 16x16x16 sized icons for "modal dialogs" (48x48x16 for regular
icons), which seems to be not designed for displaying un the task bar or
ALT-TAB
process switching window. Currently this type of icons are displayed wrongly.
CreateIcon() seems to stretch this icon so this result in displaying black
horizontal stripes. This problem would be solved, when issue 1. would be
implemented.
Can you check the raw bits that are being passed to the CreateBitmap
for this icon? I've run several 16x16 icon apps (ethereal and konqueror)
and they all work fine. (Of course windows will pixel double the 16x16
icon to 32x32 for the task switcher...). CreateIcon does work for
16x16 bitmaps, but if there was a 32x32 icon registered for the window
class before, maybe Windoze doesn't like swapping it for a 16x16 with
the GCL_HICON...


-Earle F. Philhower, III
***@ziplabel.com
cdrlabel - ZipLabel - FlpLabel
http://www.cdrlabel.com
Ralf Habacker
2003-05-27 21:30:22 UTC
Permalink
-----Original Message-----
III
Sent: Monday, May 26, 2003 7:28 PM
Subject: RE: Custom icons per window class/name patch
Howdy Ralf,
Post by Ralf Habacker
while testing some KDE3 applications, I recognized that the
application window
Post by Ralf Habacker
class distinction by WM_CLASS isn't enough, because kde applications uses
different icons for different windows of an application. This applications
uses
the WM_WINDOW_ROLE property to distingh for example message box windows from
basic windows. Currently the icons of the main window are
overwritten, because
Post by Ralf Habacker
all the windows of an application share the same window class.
The appended patch fix this. (Additional this patch fixes one segfault in
GetClassHint, I have recognized causes by a null WindowPtr)
I'm not a KDE user so I can't test this directly, but are you
sure that the window role name is unique between applications?
Would it make sense to use the Windows class name a function of
both the res_role, res_name and res_class? Or is there only one
KDE "file open box" that all apps would share?
The first.

1. I've done some research relating to this stuff and found some specification
of this in the "Inter-Client Communication Conventions Manual" (ICCCM) for
example on http://tronche.com/gui/x/icccm/sec-5.html:

"It is necessary that other clients be able to uniquely identify a window
(across sessions) >among all windows related to the same client-ID. For example,
a window manager can require this unique ID to restore geometry information from
a previous session, or a workspace manager could use it to restore information
about which windows are in which workspace. A client may optionally provide a
WM_WINDOW_ROLE property to uniquely identify a window within the scope specified
above. The combination of SM_CLIENT_ID and WM_WINDOW_ROLE can be used by other
clients to uniquely identify a window across sessions.

If the WM_WINDOW_ROLE property is not specified on a top level window, a client
that needs to uniquely identify that window will try to use instead the values
of WM_CLASS and WM_NAME. If a client has multiple windows with identical
WM_CLASS and WM_NAME properties, then it should provide a WM_WINDOW_ROLE
property.

The client must set the WM_WINDOW_ROLE property to a string that uniquely
identifies that window among all windows that have the same client leader
window."

The the spec. A practical hint one can find in
http://mail.gnome.org/archives/wm-spec-list/2003-January/msg00010.html, where
one of the kde core developer suggests the following:

.... WM_CLASS+WM_WINDOW_ROLE are supposed to uniquely identify every window in
an application (+PID if needed).

PID might be necessary in multi monitor environments to distingh different
sessions like starting the same xapp on two several servers, which might be have
different window setting options based on the specific machine x or gui
settings.

2. I have asked several kde apps for their implementation and recognized that
this isn't implemented very straight. Some applications defines WM_WINDOW_ROLE
application wide uniq and some does not so.

Your suggestion WM_CLASS+WM_WINDOW_ROLE appended by [+PID] will be the best for
all cases, i think.

kate:
WM_CLASS(STRING) = "kate", "kate"
WM_WINDOW_ROLE(STRING) = "kate-mainwindow#1"

khelpcenter:
WM_CLASS(STRING) = "khelpcenter", "khelpcenter"
WM_WINDOW_ROLE(STRING) = "MainWindow"

konsole:
WM_CLASS(STRING) = "konsole", "konsole"
main window - WM_WINDOW_ROLE(STRING) = "konsole-mainwindow#1"
tip of the day - WM_WINDOW_ROLE(STRING) = "unnamed"
about dialog - WM_WINDOW_ROLE(STRING) = "aboutkde"
settings dialog - WM_WINDOW_ROLE(STRING) = "unnamed"

keditbookmarks
main window - WM_WINDOW_ROLE(STRING) = "keditbookmarks-mainwindow#1"

kicker
WM_CLASS(STRING) = "kicker", "kicker"
WM_WINDOW_ROLE(STRING) = "Panel"
...
Post by Ralf Habacker
2. KDE uses 16x16x16 sized icons for "modal dialogs" (48x48x16 for regular
icons), which seems to be not designed for displaying un the task bar or
ALT-TAB
process switching window. Currently this type of icons are displayed wrongly.
CreateIcon() seems to stretch this icon so this result in displaying black
horizontal stripes. This problem would be solved, when issue 1. would be
implemented.
Can you check the raw bits that are being passed to the CreateBitmap
for this icon? I've run several 16x16 icon apps (ethereal and konqueror)
and they all work fine.
The icon_pixmap seems to be displayed fine in the window and taskbar, only in
the task switcher the result is very bad.

(Of course windows will pixel double the 16x16
icon to 32x32 for the task switcher...). CreateIcon does work for
16x16 bitmaps, but if there was a 32x32 icon registered for the window
class before, maybe Windoze doesn't like swapping it for a 16x16 with
the GCL_HICON...
The problem is kde and gnome specific. The kde3 window manager (kwin) taks
switcher displays two kind of icons: 1. a list of 16x16 pixel icons like the
windows task switcher does and 2. a higher resolution icon for the current
selected application.

The 16x16 pixel icon is provided through the regular WMHints property, the
bigger one by the _NET_WM_ICON(CARDINAL) property, which is part of the
"Extended Window Manager Hints" found in
http://www.freedesktop.org/standards/wm-spec.html


In detail from http://www.freedesktop.org/standards/wm-spec/1.3/html/x231.html

"_NET_WM_ICON
_NET_WM_ICON CARDINAL[][2+n]/32

"This is an array of possible icons for the client. This specification does not
stipulate what size these icons should be, but individual desktop environments
or toolkits may do so. The Window Manager MAY scale any of these icons to an
appropriate size.

This is an array of 32bit packed CARDINAL ARGB [alpha,red,green,blue] with high
byte being A, low byte being B. The first two cardinals are width, height. Data
is in rows, left to right and top to bottom."

I've appended an xprop dump for the KDE3 kate application. May be you can use
this.

Cheers
Ralf
Earle F. Philhower III
2003-05-24 06:44:15 UTC
Permalink
Howdy Ralf et. al.,

It wasn't too bad starting from Ralf's code to grab the pixmap info from
the WM_HINTS property to getting working X icons. The attached patch is
against
the test86 release. It converts icons in the WM_HINTS into dynamic Windows
HICONs with masks and resizing.

I've tested it against a few apps and it seems to work 100% for icon sizes of
32x32 and 48x48, and in 8, 16, and 32 bit displays under Win2K. 24-bit and
non-square icons and icons <32x32 need to be tested, but should work...
Post by Ralf Habacker
Post by Ralf Habacker
Good to hear, but how to compute in detail ? Additional what about the
performance ?
Using the xclient means to transfer the image data every time icon setting will
be performed from the server to the client, which is the server,
although the
Post by Ralf Habacker
data is directly asseccable on the server, isn't it ?
I assume based on the things I have learned from you, that all the
image data
Post by Ralf Habacker
will be in some property on the server, which has only to be retrieved
in some
Post by Ralf Habacker
mysteric way.
I've got a little success.
Now I'm able to retrieve the pixmap pointer from the WM_HINTS structure
and the
bitmap data, the CreateIcon returns an icon handle, but unfortunally the icon
isn't displayed.
...
winCreateWindowsWindow (WindowPtr pWin)
...add the stuff below after the following two lines in
winCreateWindowsWindow()
hIcon = LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN));
strcpy(classStr, WINDOW_CLASS_X);
------------------------------------------------------------------
{
xPropWMHints *hints;
GetWMHints(pWin, &hints);
...
-Earle F. Philhower, III
***@ziplabel.com
cdrlabel - ZipLabel - FlpLabel
http://www.cdrlabel.com
Colin Harrison
2003-05-24 09:54:40 UTC
Permalink
Hi Earle,

Just tried your patch.
Works fine on xeyes, xcalc etc but banged (Dr Watson and all that jazz) on
ethereal (a gtk application).
I put the .ini file in c:\windows, but I assume it can go anywhere in the
%PATH%?
I'll have a play a bit more later and come back with some better results and
trace!

Colin
Harold L Hunt II
2003-05-24 12:34:30 UTC
Permalink
Colin and Earle,

Actually, I don't see anywhere in the code where xwin.ini is referenced.
Is it even used? I am assuming that it isn't since the whole point of
this patch is to do away with a config file and separate icons for X
apps running on Windows.

Harold
Post by Ralf Habacker
Hi Earle,
Just tried your patch.
Works fine on xeyes, xcalc etc but banged (Dr Watson and all that jazz) on
ethereal (a gtk application).
I put the .ini file in c:\windows, but I assume it can go anywhere in the
%PATH%?
I'll have a play a bit more later and come back with some better results and
trace!
Colin
Harold L Hunt II
2003-05-24 13:26:15 UTC
Permalink
Okay, so there is a reference to XWin.ini in the code, but it seems to
be a mistake or an extra feature that isn't really crucial anymore.

Regarding the crash, I can reproduce this by running mozilla or
konqueror through ssh, every time.

Earle --- Please see if you can figure out what the problem is and send
a diff against the patch that you already sent in, I have already
applied them to my local tree.

Thanks for contributing,

Harold
Post by Harold L Hunt II
Colin and Earle,
Actually, I don't see anywhere in the code where xwin.ini is referenced.
Is it even used? I am assuming that it isn't since the whole point of
this patch is to do away with a config file and separate icons for X
apps running on Windows.
Harold
Post by Ralf Habacker
Hi Earle,
Just tried your patch.
Works fine on xeyes, xcalc etc but banged (Dr Watson and all that jazz) on
ethereal (a gtk application).
I put the .ini file in c:\windows, but I assume it can go anywhere in the
%PATH%?
I'll have a play a bit more later and come back with some better results and
trace!
Colin
Earle F. Philhower III
2003-05-24 17:33:47 UTC
Permalink
Howdy Colin and Harold,
Post by Colin Harrison
Just tried your patch.
Works fine on xeyes, xcalc etc but banged (Dr Watson and all that jazz) on
ethereal (a gtk application).
I put the .ini file in c:\windows, but I assume it can go anywhere in the
%PATH%?
I'll have a play a bit more later and come back with some better results and
trace!
Can you guys find an app that runs locally which causes this? I'm cut off
from real unix machines and compiling Konqueror under cygwin is a little
bit more than I'm up for. Just d/ling it would probably take all day!

My initial feeling is that this is just a pixmap depth problem: The XC
apps all use 1-bit bitmaps, and the commercial-ish apps give colored pixmaps
and that function miGetImage() doesn't downconvert, so the memory given
for the bitmap isn't enough (not is the processing right, but that won't
cause a crash, just ugliness).

Also, that xwin.ini is just vestigial, feel free to remove it from the
code unless you really want to hand-iconify apps.


-Earle F. Philhower, III
***@ziplabel.com
cdrlabel - ZipLabel - FlpLabel
http://www.cdrlabel.com
Ralf Habacker
2003-05-24 19:28:23 UTC
Permalink
Post by Earle F. Philhower III
Howdy Colin and Harold,
Post by Colin Harrison
Just tried your patch.
Works fine on xeyes, xcalc etc but banged (Dr Watson and all that jazz) on
ethereal (a gtk application).
I put the .ini file in c:\windows, but I assume it can go anywhere in the
%PATH%?
I'll have a play a bit more later and come back with some better results and
trace!
Can you guys find an app that runs locally which causes this? I'm cut off
from real unix machines and compiling Konqueror under cygwin is a little
bit more than I'm up for. Just d/ling it would probably take all day!
for example the application of the kde-cygwin port of the QT library: designer,
linguist or assistant or the applications (konqueror,kate,...) of the
KDE3-cygwin port

You can find binary releases on http://sf.net/projects/kde-cygwin

qt - http://prdownloads.sourceforge.net/kde-cygwin/qt-3.0.4-b1.tar.bz2?download

kde -
http://prdownloads.sourceforge.net/kde-cygwin/setup-kde-3.1.1-b1.exe?download
Post by Earle F. Philhower III
My initial feeling is that this is just a pixmap depth problem: The XC
apps all use 1-bit bitmaps, and the commercial-ish apps give colored pixmaps
and that function miGetImage() doesn't downconvert, so the memory given
for the bitmap isn't enough (not is the processing right, but that won't
cause a crash, just ugliness).
Right: Above applications provides a icon_pixmap with 16bit per pixels.
A hack, which fixes the segfault is shown below. winScaleXBitmapToWindows()
assums that the xpixmap has one bit depth.

static void
winScaleXBitmapToWindows( int iconSize, int effBPP, PixmapPtr pixmap, unsigned
char *image)
...
< xStride = ((pixmap->drawable.width +31)&(~31))/8;
Post by Earle F. Philhower III
xStride = ((pixmap->drawable.width * pixmap->drawable.bitsPerPixel
+31)&(~31))/8;

Unfortunally, no icon is shown in this case. There must be more fixes required.

Ralf
Harold L Hunt II
2003-05-24 19:30:48 UTC
Permalink
Ralf,

But wouldn't he have to have the SHM-enabled XWin.exe installed from the
KDE3-Cygwin port? Wouldn't that kind of negate the possibility of
testing his code, unless he recompiles with SHM and installs cygipc (or
whatever it is called these days)?

Harold
Post by Ralf Habacker
Post by Earle F. Philhower III
Howdy Colin and Harold,
Post by Colin Harrison
Just tried your patch.
Works fine on xeyes, xcalc etc but banged (Dr Watson and all that jazz) on
ethereal (a gtk application).
I put the .ini file in c:\windows, but I assume it can go anywhere in the
%PATH%?
I'll have a play a bit more later and come back with some better results and
trace!
Can you guys find an app that runs locally which causes this? I'm cut off
from real unix machines and compiling Konqueror under cygwin is a little
bit more than I'm up for. Just d/ling it would probably take all day!
for example the application of the kde-cygwin port of the QT library: designer,
linguist or assistant or the applications (konqueror,kate,...) of the
KDE3-cygwin port
You can find binary releases on http://sf.net/projects/kde-cygwin
qt - http://prdownloads.sourceforge.net/kde-cygwin/qt-3.0.4-b1.tar.bz2?download
kde -
http://prdownloads.sourceforge.net/kde-cygwin/setup-kde-3.1.1-b1.exe?download
Post by Earle F. Philhower III
My initial feeling is that this is just a pixmap depth problem: The XC
apps all use 1-bit bitmaps, and the commercial-ish apps give colored pixmaps
and that function miGetImage() doesn't downconvert, so the memory given
for the bitmap isn't enough (not is the processing right, but that won't
cause a crash, just ugliness).
Right: Above applications provides a icon_pixmap with 16bit per pixels.
A hack, which fixes the segfault is shown below. winScaleXBitmapToWindows()
assums that the xpixmap has one bit depth.
static void
winScaleXBitmapToWindows( int iconSize, int effBPP, PixmapPtr pixmap, unsigned
char *image)
...
< xStride = ((pixmap->drawable.width +31)&(~31))/8;
Post by Earle F. Philhower III
xStride = ((pixmap->drawable.width * pixmap->drawable.bitsPerPixel
+31)&(~31))/8;
Unfortunally, no icon is shown in this case. There must be more fixes required.
Ralf
Ralf Habacker
2003-05-25 11:55:24 UTC
Permalink
Harold
Post by Harold L Hunt II
But wouldn't he have to have the SHM-enabled XWin.exe installed from the
KDE3-Cygwin port? Wouldn't that kind of negate the possibility of
testing his code, unless he recompiles with SHM and installs cygipc (or
whatever it is called these days)?
XSHM is used for pixmap caching, in my exprerience qt/kde works without this
support, but will be slower.

BTW: I have read a thread in the cygwin list regarding to distribute cygipc with
cygwin. If this would happen, does this mean, that the official cygwin xfree
release will support XSHM at some time in the future ? (This would make the
non-standard xfree on kde-cygwin obsolate)

Ralf
Post by Harold L Hunt II
Post by Ralf Habacker
Post by Earle F. Philhower III
Howdy Colin and Harold,
Post by Colin Harrison
Just tried your patch.
Works fine on xeyes, xcalc etc but banged (Dr Watson and all that jazz) on
ethereal (a gtk application).
I put the .ini file in c:\windows, but I assume it can go anywhere in the
%PATH%?
I'll have a play a bit more later and come back with some better
results and
Post by Ralf Habacker
Post by Earle F. Philhower III
Post by Colin Harrison
trace!
Can you guys find an app that runs locally which causes this? I'm cut off
from real unix machines and compiling Konqueror under cygwin is a little
bit more than I'm up for. Just d/ling it would probably take all day!
for example the application of the kde-cygwin port of the QT
library: designer,
Post by Ralf Habacker
linguist or assistant or the applications (konqueror,kate,...) of the
KDE3-cygwin port
You can find binary releases on http://sf.net/projects/kde-cygwin
qt -
http://prdownloads.sourceforge.net/kde-cygwin/qt-3.0.4-b1.tar.bz2?download
Post by Harold L Hunt II
kde -
http://prdownloads.sourceforge.net/kde-cygwin/setup-kde-3.1.1-b1.exe?download
Post by Ralf Habacker
My initial feeling is that this is just a pixmap depth problem: The XC
apps all use 1-bit bitmaps, and the commercial-ish apps give colored pixmaps
and that function miGetImage() doesn't downconvert, so the memory given
for the bitmap isn't enough (not is the processing right, but that won't
cause a crash, just ugliness).
Right: Above applications provides a icon_pixmap with 16bit per pixels.
A hack, which fixes the segfault is shown below. winScaleXBitmapToWindows()
assums that the xpixmap has one bit depth.
static void
winScaleXBitmapToWindows( int iconSize, int effBPP, PixmapPtr pixmap, unsigned
char *image)
...
< xStride = ((pixmap->drawable.width +31)&(~31))/8;
Post by Ralf Habacker
xStride = ((pixmap->drawable.width * pixmap->drawable.bitsPerPixel
+31)&(~31))/8;
Unfortunally, no icon is shown in this case. There must be more fixes required.
Ralf
Colin Harrison
2003-05-24 20:31:40 UTC
Permalink
Hi

Ralf's hack stops the crash.
xeyes, xclock etc have good icons.
ethereal mozilla etc have 'scrambled icons' (for want of a better word!).

However, the normal XFree applications do now look pretty impressive!

Great stuff.

Colin
Earle F. Philhower III
2003-05-24 21:18:29 UTC
Permalink
Try the following replacement X->Windoze function. I'm not sure of the
color mapping, but Mozilla, ethereal, gftp, and others come up more or less
OK!

/* Scale an X icon bitmap into a Windoze icon bitmap */
static void
winScaleXBitmapToWindows( int iconSize, int effBPP, PixmapPtr pixmap,
unsigned char *image)
{
int row, column, effXBPP;
unsigned char *outPtr;
unsigned char *iconData = 0;
int stride, xStride;
float factX, factY;
int posX, posY;
unsigned char *ptr;
unsigned int zero;
unsigned int color;

if (pixmap->drawable.bitsPerPixel==15)
effXBPP = 16;
else
effXBPP = pixmap->drawable.bitsPerPixel;

stride = ((iconSize * effBPP + 31)&(~31))/8; /* Need 32-bit aligned rows */
xStride = ((pixmap->drawable.width * effXBPP + 31)&(~31))/8;

iconData = malloc( xStride * pixmap->drawable.height );
miGetImage((DrawablePtr)&(pixmap->drawable), 0, 0,
pixmap->drawable.width, pixmap->drawable.height,
ZPixmap, 0xffff, iconData);

/* Keep aspect ratio */
factX = ((float)pixmap->drawable.width)/((float)iconSize);
factY = ((float)pixmap->drawable.height)/((float)iconSize);
if (factX>factY) factY = factX;
else factX = factY;

/* Out-of-bounds, fill icon with zero */
zero = 0;
ErrorF("%d bpp %d x %d!\n",
effXBPP,pixmap->drawable.width,pixmap->drawable.height );

for (row=0; row<iconSize; row++) {
outPtr = image+stride*row;
for (column=0; column<iconSize; column++) {
posX = factX * column;
posY = factY * row;

ptr = iconData + posY*xStride;
if ( effXBPP == 1 ) {
ptr += posX/8;

/* Out of X icon bounds, leave space blank */
if (posX>=pixmap->drawable.width || posY>=pixmap->drawable.height)
ptr = &zero;

if ((*ptr) & (1<<(posX&7)))
switch (effBPP) {
case 32: *(outPtr++) = 0;
case 24: *(outPtr++) = 0;
case 16: *(outPtr++) = 0;
case 8: *(outPtr++) = 0;
break;
case 1:
outPtr[column/8] &= ~(1<<(7-(column&7)));
break;
}
else
switch (effBPP) {
case 32: *(outPtr++) = 255;
case 24: *(outPtr++) = 255;
case 16: *(outPtr++) = 255;
case 8: *(outPtr++) = 255;
break;
case 1:
outPtr[column/8] |= (1<<(7-(column&7)));
break;
}
} else if (effXBPP == 24 || effXBPP == 32) {
ptr += posX*((effXBPP==32)?4:3);
/* Out of X icon bounds, leave space blank */
if (posX>=pixmap->drawable.width || posY>=pixmap->drawable.height)
ptr = &zero;
color = ((*ptr)<<16)+((*(ptr+1))<<8)+((*(ptr+2))<<0);
switch (effBPP) {
case 32:
*(outPtr++) = *(ptr++);
*(outPtr++) = *(ptr++);
*(outPtr++) = *(ptr++);
*(outPtr++) = 0;
break;
case 24:
*(outPtr++) = *(ptr++);
*(outPtr++) = *(ptr++);
*(outPtr++) = *(ptr++);
break;
case 16:
color = (((*ptr)>>2)<<10) + (((*(ptr+1))>>2)<<5) +
(((*(ptr+2))>>2));
*(outPtr++) = (color>>8);
*(outPtr++) = (color&255);
break;
case 8:
color = (((*ptr))) + (((*(ptr+1)))) + (((*(ptr+2))));
color /= 3;
*(outPtr) = color;
break;
case 1:
if (color)
outPtr[column/8] |= (1<<(7-(column&7)));
else
outPtr[column/8] &= ~(1<<(7-(column&7)));
}


} else if ( effXBPP == 16 ) {
ptr += posX*2;

/* Out of X icon bounds, leave space blank */
if (posX>=pixmap->drawable.width || posY>=pixmap->drawable.height)
ptr = &zero;
color = ((*ptr)<<8)+(*(ptr+1));
switch (effBPP) {
case 32:
*(outPtr++) = (color & 31) << 2;
*(outPtr++) = ((color>>5) & 31) << 2;
*(outPtr++) = ((color>>10) & 31) << 2;
*(outPtr++) = 0;
break;
case 24:
*(outPtr++) = (color & 31) << 2;
*(outPtr++) = ((color>>5) & 31) << 2;
*(outPtr++) = ((color>>10) & 31) << 2;
break;
case 16:
*(outPtr++) = *(ptr++);
*(outPtr++) = *(ptr++);
break;
case 8:
*(outPtr++) = (( (color & 31) + ((color>>5) & 31) + ((color>>10)
& 31))/3) << 2;
break;
case 1:
if (color)
outPtr[column/8] |= (1<<(7-(column&7)));
else
outPtr[column/8] &= ~(1<<(7-(column&7)));
break;
} /* end switch(effbpp) */
} /* end if effxbpp==16) */
} /* end for column */
} /* end for row */
free(iconData);
}
Post by Colin Harrison
Hi
Ralf's hack stops the crash.
xeyes, xclock etc have good icons.
ethereal mozilla etc have 'scrambled icons' (for want of a better word!).
However, the normal XFree applications do now look pretty impressive!
Great stuff.
Colin
-Earle F. Philhower, III
***@ziplabel.com
cdrlabel - ZipLabel - FlpLabel
http://www.cdrlabel.com
Colin Harrison
2003-05-24 21:54:40 UTC
Permalink
Hi

Earle's replacement X->Windoze function is ace, my test results are:-

xterm X icon
xeyes 'eyes' icon
xclock 'clock' icon
ethereal 'their weird e' icon
Mozilla 'coloured.. maybe wrong, too pixelly to tell!' icon?
Qt (say hello example) X icon
Konqueror 'coloured file' icon
RealPlayer(linux realplay) X icon
acroread(linux acrobat) 'correct, but low resolution!' icon


Running on XP Pro at 1280x1024 Screen, Color quality 16 bit.

That's a pretty impressive piece of code.

Colin
Earle F. Philhower III
2003-05-24 22:34:01 UTC
Permalink
Howdy! Thanks to the use Harold's linux box I was able to get the
colors correct for all the apps I've tried under 16 and 32 bit color
(mozilla, gftp, ethereal). For some reasons ethereal and some other
apps register a 16x16 pixmap. Maybe they do a WM_HINTS to change
it to a bigger one after the window is created, if that's the case the
code does not yet have that hook put it.

Most tests have 24-bpp icons, if someone has a 16-bpp icon it would
be a good thing to test! And 8bpp display modes are funky, I don't do
colormap lookups or anything like that. Feel free to fix that if you
still have a video card with 256K of RAM. ;)

---------8<----------------
/* Scale an X icon bitmap into a Windoze icon bitmap */
static void
winScaleXBitmapToWindows( int iconSize, int effBPP, PixmapPtr pixmap,
unsigned char *image)
{
int row, column, effXBPP, effXDepth;
unsigned char *outPtr;
unsigned char *iconData = 0;
int stride, xStride;
float factX, factY;
int posX, posY;
unsigned char *ptr;
unsigned int zero;
unsigned int color;


if (pixmap->drawable.bitsPerPixel==15)
effXBPP = 16;
else
effXBPP = pixmap->drawable.bitsPerPixel;

if (pixmap->drawable.depth==15)
effXDepth = 16;
else
effXDepth = pixmap->drawable.depth;

stride = ((iconSize * effBPP + 31)&(~31))/8; /* Need 32-bit aligned rows */
xStride = ((pixmap->drawable.width * effXBPP + 31)&(~31))/8;

iconData = malloc( xStride * pixmap->drawable.height );
miGetImage((DrawablePtr)&(pixmap->drawable), 0, 0,
pixmap->drawable.width, pixmap->drawable.height,
ZPixmap, 0xffffffff, iconData);

/* Keep aspect ratio */
factX = ((float)pixmap->drawable.width)/((float)iconSize);
factY = ((float)pixmap->drawable.height)/((float)iconSize);
if (factX>factY) factY = factX;
else factX = factY;

/* Out-of-bounds, fill icon with zero */
zero = 0;

for (row=0; row<iconSize; row++) {
outPtr = image+stride*row;
for (column=0; column<iconSize; column++) {
posX = factX * column;
posY = factY * row;

ptr = iconData + posY*xStride;
if ( effXBPP == 1 ) {
ptr += posX/8;

/* Out of X icon bounds, leave space blank */
if (posX>=pixmap->drawable.width || posY>=pixmap->drawable.height)
ptr = &zero;

if ((*ptr) & (1<<(posX&7)))
switch (effBPP) {
case 32: *(outPtr++) = 0;
case 24: *(outPtr++) = 0;
case 16: *(outPtr++) = 0;
case 8: *(outPtr++) = 0;
break;
case 1:
outPtr[column/8] &= ~(1<<(7-(column&7)));
break;
}
else
switch (effBPP) {
case 32: *(outPtr++) = 255;
case 24: *(outPtr++) = 255;
case 16: *(outPtr++) = 255;
case 8: *(outPtr++) = 255;
break;
case 1:
outPtr[column/8] |= (1<<(7-(column&7)));
break;
}
} else if (effXDepth == 24 || effXDepth == 32) {
ptr += posX*(effXBPP/8);
/* Out of X icon bounds, leave space blank */
if (posX>=pixmap->drawable.width || posY>=pixmap->drawable.height)
ptr = &zero;
color = ((*ptr)<<16)+((*(ptr+1))<<8)+((*(ptr+2))<<0);
switch (effBPP) {
case 32:
*(outPtr++) = *(ptr++); // alpha
*(outPtr++) = *(ptr++); // green
*(outPtr++) = *(ptr++); // red
*(outPtr++) = *(ptr++); // blue
break;
case 24:
*(outPtr++) = *(ptr++);
*(outPtr++) = *(ptr++);
*(outPtr++) = *(ptr++);
break;
case 16:
color = (((*ptr)>>2)<<10) + (((*(ptr+1))>>2)<<5) +
(((*(ptr+2))>>2));
*(outPtr++) = (color>>8);
*(outPtr++) = (color&255);
break;
case 8:
color = (((*ptr))) + (((*(ptr+1)))) + (((*(ptr+2))));
color /= 3;
*(outPtr++) = color;
break;
case 1:
if (color)
outPtr[column/8] |= (1<<(7-(column&7)));
else
outPtr[column/8] &= ~(1<<(7-(column&7)));
}
} else if ( effXDepth == 16 ) {
ptr += posX*(effXBPP/8);

/* Out of X icon bounds, leave space blank */
if (posX>=pixmap->drawable.width || posY>=pixmap->drawable.height)
ptr = &zero;
color = ((*ptr)<<8)+(*(ptr+1));
switch (effBPP) {
case 32:
*(outPtr++) = 0; // alpha
*(outPtr++) = (color & 31) << 2;
*(outPtr++) = ((color>>5) & 31) << 2;
*(outPtr++) = ((color>>10) & 31) << 2;
break;
case 24:
*(outPtr++) = (color & 31) << 2;
*(outPtr++) = ((color>>5) & 31) << 2;
*(outPtr++) = ((color>>10) & 31) << 2;
break;
case 16:
*(outPtr++) = *(ptr++);
*(outPtr++) = *(ptr++);
break;
case 8:
*(outPtr++) = (( (color & 31) + ((color>>5) & 31) + ((color>>10)
& 31))/3) << 2;
break;
case 1:
if (color)
outPtr[column/8] |= (1<<(7-(column&7)));
else
outPtr[column/8] &= ~(1<<(7-(column&7)));
break;
} /* end switch(effbpp) */
} /* end if effxbpp==16) */
} /* end for column */
} /* end for row */
free(iconData);
}
Post by Colin Harrison
Hi
Earle's replacement X->Windoze function is ace, my test results are:-
xterm X icon
xeyes 'eyes' icon
xclock 'clock' icon
ethereal 'their weird e' icon
Mozilla 'coloured.. maybe wrong, too pixelly to tell!' icon?
Qt (say hello example) X icon
Konqueror 'coloured file' icon
RealPlayer(linux realplay) X icon
acroread(linux acrobat) 'correct, but low resolution!' icon
Running on XP Pro at 1280x1024 Screen, Color quality 16 bit.
That's a pretty impressive piece of code.
Colin
-Earle F. Philhower, III
***@ziplabel.com
cdrlabel - ZipLabel - FlpLabel
http://www.cdrlabel.com
Ralf Habacker
2003-05-25 11:54:48 UTC
Permalink
Post by Earle F. Philhower III
Howdy! Thanks to the use Harold's linux box I was able to get the
colors correct for all the apps I've tried under 16 and 32 bit color
(mozilla, gftp, ethereal). For some reasons ethereal and some other
apps register a 16x16 pixmap. Maybe they do a WM_HINTS to change
it to a bigger one after the window is created, if that's the case the
code does not yet have that hook put it.
Most tests have 24-bpp icons, if someone has a 16-bpp icon it would
be a good thing to test!
Qt-application like designer, linguist and assistant provides icons with 16bbp.
It may be installed on the linux box.


Ralf
Ralf Habacker
2003-05-25 13:43:54 UTC
Permalink
Hi Erle,
Post by Ralf Habacker
Post by Earle F. Philhower III
Most tests have 24-bpp icons, if someone has a 16-bpp icon it would
be a good thing to test!
Qt-application like designer, linguist and assistant provides icons with 16bbp.
It may be installed on the linux box.
after applying your last patch I've checked the above mentioned applications.
The icons are shown without any errors.

Great work.

Cheers
Ralf
Earle F. Philhower III
2003-05-25 02:50:28 UTC
Permalink
Here's an even better version, it listens to the WM_HINTS events and
changes the window icon on-the-fly. Konqueror uses this, maybe other
apps do too.

You should untgz this file over the last one I sent (true_x_icons.tar.bz2)
as the 2 winmulti*.c files had to be modified.
Post by Colin Harrison
Hi
Earle's replacement X->Windoze function is ace, my test results are:-
xterm X icon
xeyes 'eyes' icon
xclock 'clock' icon
ethereal 'their weird e' icon
Mozilla 'coloured.. maybe wrong, too pixelly to tell!' icon?
Qt (say hello example) X icon
Konqueror 'coloured file' icon
RealPlayer(linux realplay) X icon
acroread(linux acrobat) 'correct, but low resolution!' icon
Running on XP Pro at 1280x1024 Screen, Color quality 16 bit.
That's a pretty impressive piece of code.
Colin
-Earle F. Philhower, III
***@ziplabel.com
cdrlabel - ZipLabel - FlpLabel
http://www.cdrlabel.com
Colin Harrison
2003-05-25 05:44:09 UTC
Permalink
Hi,

It all works for me.

Thanks

Colin
Ralf Habacker
2003-05-25 13:42:22 UTC
Permalink
Harold,
Post by Ralf Habacker
Post by Harold L Hunt II
But wouldn't he have to have the SHM-enabled XWin.exe installed from the
KDE3-Cygwin port? Wouldn't that kind of negate the possibility of
testing his code, unless he recompiles with SHM and installs cygipc (or
whatever it is called these days)?
XSHM is used for pixmap caching, in my exprerience qt/kde works without this
support, but will be slower.
This statement belongs to the xserver.

On the client side the shm (XShm...) related symbols in libXext are required. It
may be possible to patch the kde/qt sources to provide a dummy wrapper, if the
x11 distribution does not provide this symbol.

Ralf
Colin Harrison
2003-05-26 10:11:50 UTC
Permalink
Hi,

Tried Ralf's patch..works well for me.
I didn't dig that deep into running remote KDE apps when I last tested!

Note (for Harold?): Ralf's .dif doesn't quite match the upgrades via Earle's
patches and
winmultiwindowwindow.c gains some redundant functions/variables that could
be removed.


Colin
Ralf Habacker
2003-05-27 05:45:11 UTC
Permalink
Hi Colin,
Post by Colin Harrison
Hi,
Tried Ralf's patch..works well for me.
I didn't dig that deep into running remote KDE apps when I last tested!
In the meantime I found an additional issue with kicker, which is more a windows
decoration problem than a custom icon problem, so I will report this on a
separate thread. In short: kicker is an "panel" type application without any
decoration, with the cygwin/xfree server it has a window with full decoration.
Post by Colin Harrison
Note (for Harold?): Ralf's .dif doesn't quite match the upgrades via Earle's
patches
Huh, where was the problem ? I've build it after applying all recent patches
from Erle.
Post by Colin Harrison
and winmultiwindowwindow.c gains some redundant functions/variables that could
be removed.
Ralf
Colin Harrison
2003-05-26 21:57:34 UTC
Permalink
Hi,

As a sanity check I've rolled up all the changes from the test86 release
into a .diff file.

Includes the two patches from Earle:

http://cygwin.com/ml/cygwin-xfree/2003-05/msg00446.html
http://cygwin.com/ml/cygwin-xfree/2003-05/msg00472.html

And one from Ralf:
http://cygwin.com/ml/cygwin-xfree/2003-05/msg00484.html

With a little TLC to keep it all tidy.

It's all in a .diff file which will update the two new files if you touch
winclass.h and winclass.c to create them as empty files first.

This can be used to get anyone quickly up to speed on this one.


Colin
Harold L Hunt II
2003-05-26 22:11:23 UTC
Permalink
Colin,

Thanks, this may come in handy. I am finishing up working some overtime
for the holiday weekend... after that I might be able to play around
with all of these patches and try to get a test release out.

Harold
Post by Colin Harrison
Hi,
As a sanity check I've rolled up all the changes from the test86 release
into a .diff file.
http://cygwin.com/ml/cygwin-xfree/2003-05/msg00446.html
http://cygwin.com/ml/cygwin-xfree/2003-05/msg00472.html
http://cygwin.com/ml/cygwin-xfree/2003-05/msg00484.html
With a little TLC to keep it all tidy.
It's all in a .diff file which will update the two new files if you touch
winclass.h and winclass.c to create them as empty files first.
This can be used to get anyone quickly up to speed on this one.
Colin
------------------------------------------------------------------------
Igor Pechtchanski
2003-05-27 01:35:32 UTC
Permalink
Post by Colin Harrison
As a sanity check I've rolled up all the changes from the test86 release
into a .diff file.
[snip]
It's all in a .diff file which will update the two new files if you touch
winclass.h and winclass.c to create them as empty files first.
Colin,

FYI, you can give a "-N" parameter to "diff" to make it compare previously
non-existent files against /dev/null. Running that through "patch" will
then create the files as necessary.
Igor
--
http://cs.nyu.edu/~pechtcha/
|\ _,,,---,,_ ***@cs.nyu.edu
ZZZzz /,`.-'`' -. ;-;;,_ ***@watson.ibm.com
|,4- ) )-,_. ,\ ( `'-' Igor Pechtchanski
'---''(_/--' `-'\_) fL a.k.a JaguaR-R-R-r-r-r-.-.-. Meow!

"I have since come to realize that being between your mentor and his route
to the bathroom is a major career booster." -- Patrick Naughton
Earle F. Philhower, III
2003-05-27 21:13:02 UTC
Permalink
I just did some runs with the commercial apps I use at work, and can see that many do *not* create custom classes or window_roles for each type of window. I think the best thing to do for the class naming is to just use an incrementing number and make each window its own class. Then when the window is deleted we will just UnregisterClass(GetClassName(hwnd)) and NOT have any GDI leaks. We have a GDI leak now because of this, so it will kill two birds with one stone. Under NT or later this leak shouldn't be a problem, but 95 based OSes share a common 16-bit pool amongst all apps, and may run out causing really bad things to happen if the server is running for a long time.

We also have a GDI leak on the HICONs which need to be properly disposed of before they're lost completely. With a separate class per window this will be easier, since no window will share a HICON with another.

The class, name, and role can still be used for the 2nd chance iconification of windows (the LoadImage() call referencing xwin.ini).

I'll throw a patch together tonight for this unless someone beats me to it.
--
-Earle F. Philhower, III
***@ziplabel.com
http://www.ziplabel.com
Ralf Habacker
2003-05-27 22:01:25 UTC
Permalink
Post by Earle F. Philhower, III
I just did some runs with the commercial apps I use at work, and can
see that many do *not* create custom classes or window_roles for each
type of window.
KDE and gnome apps does.
Post by Earle F. Philhower, III
I think the best thing to do for the class naming is
to just use an incrementing number and make each window its own
class.
This was my first attempt.
Post by Earle F. Philhower, III
Then when the window is deleted we will just
UnregisterClass(GetClassName(hwnd)) and NOT have any GDI leaks.

... because of not freeing the Window Class after destroying a window ?

There is no need for this. MSDN says, you can call UnregisterClass() after every
window destroying.

"If the class could not be found or if a window still exists that was created
with the class, the return value is zero. To get extended error information,
call GetLastError.

Before calling this function, an application must destroy all windows created
with the specified class. All window classes that an application registers are
unregistered when it terminates.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/WinUI/Win
dowsUserInterface/Windowing/WindowClasses/WindowClassReference/WindowClassFuncti
ons/UnregisterClass.asp
Post by Earle F. Philhower, III
We have a GDI leak now because of this, so it will kill two birds with
one stone. Under NT or later this leak shouldn't be a problem, but
95 based OSes share a common 16-bit pool amongst all apps, and may
run out causing really bad things to happen if the server is running
for a long time.
We also have a GDI leak on the HICONs which need to be properly
disposed of before they're lost completely.
With a separate class per window this will be easier, since no window will
share a HICON
Post by Earle F. Philhower, III
with another.
... but there are many more windows with the default x icon and not with the
icon of the basic application window. Fixing this means adding some stuff to
deal the stuff, the Window Class concept does.

I have some questions about this:

1. Does UnregisterClass() frees the assigned ICON or has it to be free'd
manually ?

2. The CreateIcon() and LoadImage() stuff does not frees the previous icon.
Could this not be fixed ? Does this not fix mostly GDI leaks ?

3. Every time a WMhints message comes in a new icon will be created. What about
checking if this icon was already created and avoid every time recreating ? The
pixmap id could be stored in the private window area.
Post by Earle F. Philhower, III
The class, name, and role can still be used for the 2nd chance
iconification of windows (the LoadImage() call referencing xwin.ini).
You mean canceling the wm-hints pixmap features ? That means excluding all x
apps, which does provide such informations.
Post by Earle F. Philhower, III
I'll throw a patch together tonight for this unless someone beats me to it.
Any comments ?

Cheers

Ralf
Earle F. Philhower III
2003-05-28 04:38:53 UTC
Permalink
Howdy, it's probably bad form to reply to your own posts but here goes:

Attached is a patch from the clean test 86 release (xwin-20030518-1426.tar.bz2)

The changes are as follows:
* Colin's key un-sticker for when you unfocus an X window with a key depressed
* Custom icons on a per-window basis
- Each window created in its own class (to allow custom icon)
- Class name = fn(res_name, res_class, res_role, <incrementing counter>)
- Icon is created on-the-fly using the routines I sent before
- On destroy of a window free the icon (if not x default) and class
- Also still have XWIN.INI support, but seems silly to me at this point,
I would just remove it completely and wait for a real ~/.xwinrc file
parser and PNG files...
* Set XIconSizes() to the Windows approved 16, 32, and 48. It doesn't seem
to be looked at by anything, but it is in the XLib documents as something
a WM should set.
* Removed several misc compile warnings and turned off debug messages for
GetWindowName (probably leftover from local debugging?)

TBD:
* KDE's proprietary icon format (it should be pretty easy to hack the
present code to support it, all the real work is already done...)
* Handle icon customization better, through ~/.xinitrc and PNG/JPG/etc.
* Small icon bitmask problem?


-Earle F. Philhower, III
***@ziplabel.com
cdrlabel - ZipLabel - FlpLabel
http://www.cdrlabel.com
Harold L Hunt II
2003-05-28 04:52:53 UTC
Permalink
Earle,

Thanks. I will work on merging the remaining changes in this patch into
my tree tomorrow. I hope to make a test release tomorrow so that we can
all get back into synch.

Thanks for your great contributions,

Harold
Post by Earle F. Philhower III
Attached is a patch from the clean test 86 release
(xwin-20030518-1426.tar.bz2)
* Colin's key un-sticker for when you unfocus an X window with a key depressed
* Custom icons on a per-window basis
- Each window created in its own class (to allow custom icon)
- Class name = fn(res_name, res_class, res_role, <incrementing counter>)
- Icon is created on-the-fly using the routines I sent before
- On destroy of a window free the icon (if not x default) and class
- Also still have XWIN.INI support, but seems silly to me at this point,
I would just remove it completely and wait for a real ~/.xwinrc file
parser and PNG files...
* Set XIconSizes() to the Windows approved 16, 32, and 48. It doesn't seem
to be looked at by anything, but it is in the XLib documents as something
a WM should set.
* Removed several misc compile warnings and turned off debug messages for
GetWindowName (probably leftover from local debugging?)
* KDE's proprietary icon format (it should be pretty easy to hack the
present code to support it, all the real work is already done...)
* Handle icon customization better, through ~/.xinitrc and PNG/JPG/etc.
* Small icon bitmask problem?
-Earle F. Philhower, III
cdrlabel - ZipLabel - FlpLabel
http://www.cdrlabel.com
------------------------------------------------------------------------
Colin Harrison
2003-05-27 21:52:53 UTC
Permalink
Hi Ralf,
Post by Ralf Habacker
Huh, where was the problem ? I've build it after applying all recent
patches from Earle.
When I applied Earle's and your patches in sequence, clean, from Harold's
test86 sources I got some minor hiccups on the last .dif.


I've noticed that KDE icons have problems in their transparent
backgrounds(e.g. konqueror). I suspect that the colour mask (xor)
algorithm's from Earle may have a minor weakness with some pixmap sources
(png's or KDE types?). I'm no expert in bit mangling graphics formats, and
Earl's algorithms look tricky to me, so I'll put my hands up here.

Mind you, the icon handling is pretty impressive as it stands!

I'll try and capture hicons/CreateBitmap data that goes wrong (I'm
displaying 16 bit 1280x1024 incase this is device dependent?)

Colin
Ralf Habacker
2003-05-27 22:09:33 UTC
Permalink
Post by Earle F. Philhower III
Hi Ralf,
Post by Ralf Habacker
Huh, where was the problem ? I've build it after applying all recent
patches from Earle.
When I applied Earle's and your patches in sequence, clean, from Harold's
test86 sources I got some minor hiccups on the last .dif.
I have seen, that you have got already this problems. Thanks.
Post by Earle F. Philhower III
I've noticed that KDE icons have problems in their transparent
backgrounds(e.g. konqueror). I suspect that the colour mask (xor)
algorithm's from Earle may have a minor weakness with some pixmap sources
(png's or KDE types?).
probably caused by 16x16x16 pixmaps.
Post by Earle F. Philhower III
I'm no expert in bit mangling graphics formats, and
Earl's algorithms look tricky to me, so I'll put my hands up here.
Mind you, the icon handling is pretty impressive as it stands!
I'll try and capture hicons/CreateBitmap data that goes wrong (I'm
displaying 16 bit 1280x1024 incase this is device dependent?)
I don*t know, what*'s was going wrong, but anyway, streching the 16x16 bit
images the 32x32 for the task switcher will not give good results.
KDE apps uses the _NET_WM_ICON property to provide a higher sized image. See my
other mail for more informations.

Is there anyone there who has a linux machine with KDE 3 running, which could be
accessed through the internet, so that Erle could connect to this machine and
try by himself ?

BTW: One could use the KDE 3.1.1 release from the kde-cygwin port, but I don't
know I this would be to heavy ? I'm using this for testing this icon stuff. It
need some more time for starting a kde application, but with a fast machine it
would be possible.
Harold L Hunt II
2003-05-28 02:53:30 UTC
Permalink
I have merged Earle's changes to the icon handling, but I can't tell if
there is a consensus to merge Ralf's role patch. Has it been decided
that the role patch will need to be more robust? Should I just apply it
anyway so that we all have the same code base to work from?

Harold
Earle F. Philhower III
2003-05-28 03:06:48 UTC
Permalink
Howdy Harold...
Post by Harold L Hunt II
I have merged Earle's changes to the icon handling, but I can't tell if
there is a consensus to merge Ralf's role patch. Has it been decided that
the role patch will need to be more robust? Should I just apply it anyway
so that we all have the same code base to work from?
From what Ralf mentioned about the ICCCM it seems the wm_role needs
to be taken into account in addition to the other naming rules, not
just by itself which is what his original change did. Ralf may have
more to say...

FWIW the more I read about X11 windows and how it compares to Windoze
windows, the more it seems that a unique class per window, not just per
class and name is needed. A WM_HINT with an icon is a property of a
single window, not all windows of a specific class. The res_class and
res_name are really just for WMs who want to do things like reposition
windows or override application icons, and are not guaranteed to be
unique.

That's the great thing about standards, there are just so many to pick
from! :) WM_HINTS.icon is too good for KDE apps, WM_ROLE is sometimes
used, sometimes not, and everybody has their own icon size. It almost
makes the Windoze conventions seem sensible!


-Earle F. Philhower, III
***@ziplabel.com
cdrlabel - ZipLabel - FlpLabel
http://www.cdrlabel.com
Earle F. Philhower III
2003-05-28 04:46:02 UTC
Permalink
Howdy Colin,
Post by Colin Harrison
I've noticed that KDE icons have problems in their transparent
backgrounds(e.g. konqueror). I suspect that the colour mask (xor)
algorithm's from Earle may have a minor weakness with some pixmap sources
(png's or KDE types?). I'm no expert in bit mangling graphics formats, and
Earl's algorithms look tricky to me, so I'll put my hands up here.
They're pretty standard and unoptimized, but since they are only called a very
few times during a heavy-weight process, and for 32x32 images it's not a big
deal. It just steps over the destination image, figures out which pixel in the
source image that pixel maps to, and then does any color space conversions.
A nicer way would be to promote all images to 32 bits and then do some 2d
bilinear filtering. 8) It's sure nice to have a 1BOPS machine for under 1K$.
Post by Colin Harrison
Mind you, the icon handling is pretty impressive as it stands!
I'll try and capture hicons/CreateBitmap data that goes wrong (I'm
displaying 16 bit 1280x1024 incase this is device dependent?)
Can you try again at 32bpp and see if things are munged? I didn't notice
any problems with the quickie konqueror runs I did (over a 56k modem, you
don't wanna do a long konqueror remote run, trust me) at 32bpp with the
16x16 icons. That would narrow down where to look by a lot.


-Earle F. Philhower, III
***@ziplabel.com
cdrlabel - ZipLabel - FlpLabel
http://www.cdrlabel.com
Earle F. Philhower III
2003-05-28 05:15:44 UTC
Permalink
Howdy Ralf, I'm condensing a bunch of your messages into one longer one...
Post by Ralf Habacker
1. I've done some research relating to this stuff and found some specification
of this in the "Inter-Client Communication Conventions Manual" (ICCCM) for
...
The the spec. A practical hint one can find in
http://mail.gnome.org/archives/wm-spec-list/2003-January/msg00010.html, where
.... WM_CLASS+WM_WINDOW_ROLE are supposed to uniquely identify every window in
an application (+PID if needed).
PID might be necessary in multi monitor environments to distingh different
sessions like starting the same xapp on two several servers, which might
be have
different window setting options based on the specific machine x or gui
settings.
What's I think connection ID would be better than PID, they're not guaranteed
unique across different machines. FWIW I just used the incrementing counter
like you tried before, and seems hunkey dorey as long as you clean up after
yourself in the destroy...
Post by Ralf Habacker
2. I have asked several kde apps for their implementation and recognized that
this isn't implemented very straight. Some applications defines WM_WINDOW_ROLE
application wide uniq and some does not so.
Your suggestion WM_CLASS+WM_WINDOW_ROLE appended by [+PID] will be the
best for
all cases, i think.
WM_CLASS(STRING) = "kate", "kate"
WM_WINDOW_ROLE(STRING) = "kate-mainwindow#1"
WM_CLASS(STRING) = "khelpcenter", "khelpcenter"
WM_WINDOW_ROLE(STRING) = "MainWindow"
WM_CLASS(STRING) = "konsole", "konsole"
main window - WM_WINDOW_ROLE(STRING) = "konsole-mainwindow#1"
tip of the day - WM_WINDOW_ROLE(STRING) = "unnamed"
about dialog - WM_WINDOW_ROLE(STRING) = "aboutkde"
settings dialog - WM_WINDOW_ROLE(STRING) = "unnamed"
keditbookmarks
main window - WM_WINDOW_ROLE(STRING) = "keditbookmarks-mainwindow#1"
kicker
WM_CLASS(STRING) = "kicker", "kicker"
WM_WINDOW_ROLE(STRING) = "Panel"
I think the only thing consistent is the inconsistency. :) And as far as I've
seen in the commercial and non-KDE apps is that nobody but KDE sets that role,
even to "unnamed"
Post by Ralf Habacker
Post by Earle F. Philhower III
Can you check the raw bits that are being passed to the CreateBitmap
for this icon? I've run several 16x16 icon apps (ethereal and konqueror)
and they all work fine.
The icon_pixmap seems to be displayed fine in the window and taskbar, only in
the task switcher the result is very bad.
Are you sure about this? Windoze will expand 16x16 icons and their masks,
maybe the 16x16 icon is bad too but it's too small to see? A windows
magnifier app might be handy here...
Post by Ralf Habacker
The problem is kde and gnome specific. The kde3 window manager (kwin) taks
switcher displays two kind of icons: 1. a list of 16x16 pixel icons like the
windows task switcher does and 2. a higher resolution icon for the current
selected application.
The 16x16 pixel icon is provided through the regular WMHints property, the
bigger one by the _NET_WM_ICON(CARDINAL) property, which is part of the
"Extended Window Manager Hints" found in
http://www.freedesktop.org/standards/wm-spec.html
Ahhh, another window manager standard. So many to choose from!
Post by Ralf Habacker
In detail
from http://www.freedesktop.org/standards/wm-spec/1.3/html/x231.html
"_NET_WM_ICON
_NET_WM_ICON CARDINAL[][2+n]/32
"This is an array of possible icons for the client....
This is an array of 32bit packed CARDINAL ARGB [alpha,red,green,blue] with
high
byte being A, low byte being B. The first two cardinals are width, height.
Data
is in rows, left to right and top to bottom."
...
I've appended an xprop dump for the KDE3 kate application. May be you can use
this.
Looks like about a 30 minute job to parse this guy into separate icon sizes and
choose the largest one and feed that into the resize routine. It makes it
easier
that they're all 32-bit quantities, no format conversions necessary, and there
is no reason not to write a nice 2d bilinear or quadratic scaler to give some
really sharp icons!
...
Post by Ralf Habacker
I just did some runs with the commercial apps I use at work, and can
Post by Earle F. Philhower III
see that many do *not* create custom classes or window_roles for each
type of window.
KDE and gnome apps does.
Yup, seems to be neither rhyme nor reason about it. The apps I'm using have
been ported using some Tk, some MainFrame(tm) Windoze porting layers, and
maybe some über-hacks...
Post by Ralf Habacker
Post by Earle F. Philhower III
I think the best thing to do for the class naming is
to just use an incrementing number and make each window its own
class.
This was my first attempt.
It's in the patch I sent a few mins ago, it seems to work OK and not leave
things dangling if you clean up the HICONs and WNDCLASSes...
Post by Ralf Habacker
Post by Earle F. Philhower III
Then when the window is deleted we will just
UnregisterClass(GetClassName(hwnd)) and NOT have any GDI leaks.
... because of not freeing the Window Class after destroying a window ?
There is no need for this. MSDN says, you can call UnregisterClass() after
every
window destroying.
"If the class could not be found or if a window still exists that was created
with the class, the return value is zero. To get extended error information,
call GetLastError."
Good catch, I didn't notice that. I've learned to not trust Windoze to
give me an error when I do something bad, though, from much experience.
The UnregisterClass() is safe to call and fail, but the DestroyIcon call
isn't, and I can guarantee bad stuff if you kill an icon that's selected
into a DC (or will be selected in the future for some window drawing) under
older Windoze versions.
Post by Ralf Habacker
We have a GDI leak now because of this, so it will kill two birds with
Post by Earle F. Philhower III
one stone. Under NT or later this leak shouldn't be a problem, but
95 based OSes share a common 16-bit pool amongst all apps, and may
run out causing really bad things to happen if the server is running
for a long time.
This is actually a silly concern, Windows 98 won't run long enough
anyway for this to happen without a reboot. My W2K box at work, though,
has an emacs that's been running for about 3 weeks so far, and I'd really
hate to have my X session crap out after a long debugging session.
Post by Ralf Habacker
Post by Earle F. Philhower III
We also have a GDI leak on the HICONs which need to be properly
...... but there are many more windows with the default x icon and not
with the
icon of the basic application window. Fixing this means adding some stuff to
deal the stuff, the Window Class concept does.
I'm not sure I understand you here, but FWIW the patch sent does take
care to load one copy of the "X" icon and never frees it, but will always
free an icon in a class that's destroyed or when it is overwritten by
another one.
Post by Ralf Habacker
1. Does UnregisterClass() frees the assigned ICON or has it to be free'd
manually ?
Nope, that's up to us. See the winDeleteWindow() function in winmultiwindow.c
Post by Ralf Habacker
2. The CreateIcon() and LoadImage() stuff does not frees the previous icon.
Could this not be fixed ? Does this not fix mostly GDI leaks ?
Yup, fixed but there are still the classes floating around. AFAIK that's a
GDI resource too, if not then it's what's called a "system resource" under W95
OSes...
Post by Ralf Habacker
3. Every time a WMhints message comes in a new icon will be created. What
about
checking if this icon was already created and avoid every time recreating
? The
pixmap id could be stored in the private window area.
Possibly, but it won't save much time and if you delete the old icon you're
still as good as before, with no bookkeeping needed.
Post by Ralf Habacker
Post by Earle F. Philhower III
The class, name, and role can still be used for the 2nd chance
iconification of windows (the LoadImage() call referencing xwin.ini).
You mean canceling the wm-hints pixmap features ? That means excluding all x
apps, which does provide such informations.
It's still there, but the .ini file is really, really non-unix. It also
uses Windoze paths and .ICO type files. IMHO what is really needed is
something like a ~/.fvwmrc, with cygwin based paths and .png and .jpg
support.
Post by Ralf Habacker
I don*t know, what*'s was going wrong, but anyway, streching the 16x16 bit
images the 32x32 for the task switcher will not give good results.
KDE apps uses the _NET_WM_ICON property to provide a higher sized image.
See my
other mail for more informations.
What's weird is that everyone says the KDE icons are 16-bit color, but when I
look at the wm_hints.pixmap it's always a 24-bit color one. If they use the
standard png_decompress() or whatever, that goes to RGB by default so it would
make sense to leave it at 24bpp. konqueror, mozilla, and ethereal were
tested...
Post by Ralf Habacker
Is there anyone there who has a linux machine with KDE 3 running, which
could be
accessed through the internet, so that Erle could connect to this machine and
try by himself ?
BTW: One could use the KDE 3.1.1 release from the kde-cygwin port, but I don't
know I this would be to heavy ? I'm using this for testing this icon stuff. It
need some more time for starting a kde application, but with a fast machine it
would be possible.
I'll see if I can get this going locally, because any remote work thru my 56k
modem is unpleasant to say the least. Toutefois, I think pretty much anyone
should be able to put in support for the _NET_ICON format since the 24/32bpp
scaler seems to be working pretty well.


-Earle F. Philhower, III
***@ziplabel.com
cdrlabel - ZipLabel - FlpLabel
http://www.cdrlabel.com
Colin Harrison
2003-05-28 07:16:14 UTC
Permalink
Hi Earle,

Attached is a compressed .rtf file containing a capture of icons I get at 32
bits colour via XWin.
It shows the task switcher icons with:-
1) A putty session (not via XWin!)
2) mozilla (ok, with switcher selection border)
3) konqueror (showing transparency fault)
4) xeyes and xclock (ok)
5) xterm (wrong ico, as deliberately showing a local c:\windows\ethereal.ico
using XWin.ini)
6) ethereal (showing transparency fault)

File should open in Word etc.

Colin
Colin Harrison
2003-05-28 14:21:22 UTC
Permalink
Hi Earle,

Some more icons from XWin, the ghostview one show the bug at its best, yet
the others are all superb?
Post by Colin Harrison
Attached is a compressed .rtf file containing a capture of icons I get at
32
Post by Colin Harrison
bits colour via XWin.
It shows the task switcher icons with:-
1) A putty session (not via XWin!), the way I ssh to my remote boxes, to
run..
2) KEdit
3) ghostview (!)
4) KCalc
5) acroread

All 16 bit colour this time (my usual setting, speed before beauty!)

File should open in WordPad etc.

Colin
Alexander Gottwald
2003-05-28 14:30:45 UTC
Permalink
Post by Colin Harrison
File should open in WordPad etc.
What about posting the images as gif, png or jpg or even better,
just posting a link to the image?

bye
ago
--
***@s1999.tu-chemnitz.de
http://www.gotti.org ICQ: 126018723
Earle F. Philhower III
2003-05-28 14:30:38 UTC
Permalink
Howdy Colin,
...It shows the task switcher icons with:-
3) ghostview (!)
3) konqueror (showing transparency fault)
4) xeyes and xclock (ok)
Are you sure you have all the patches in? #4 xclock is actually a watch
icon, with a black strap at the top and bottom whenever I run under 16 or 32
bit mode

#3 gv looks more like ghostview has a 50% grey dither around the icon, no?
In that case because of the scaling artifacts from xxx->32 you'll get that
kind of effect, especially at 1-bit deep.

I'll see if I can find anything since it's common between 32 and 16 bit
modes. Icons larger than 16x16 seem to have OK 1-bit masks, it's pretty
odd!


-Earle F. Philhower, III
***@ziplabel.com
cdrlabel - ZipLabel - FlpLabel
http://www.cdrlabel.com
Colin Harrison
2003-05-28 14:32:26 UTC
Permalink
Hi Earle,

Oops disregard this ..ghostview has a duff icon anyway...I just checked in a
KDE linux session.
Post by Colin Harrison
Some more icons from XWin, the ghostview one show the bug at its best, yet
the others are all superb?
i.e. they are all superb!

'You can't make a silk purse out of a sow's ear'

Colin
Colin Harrison
2003-05-28 15:28:53 UTC
Permalink
Hi Earle,

Disregard ghostview icon as per my previous post(s)!

I rebuilt clean from Harold's test86 source with your from_86.diff.bz2 patch
this morning, to be sure my
exe/results were up-to-date.

I don't get the xclock watch icon on my remote linux boxes either, (RedHat
8.0 and 7.3, KDE) using
XFree86-4.2.0-72 and XFree86-4.2.0-8 which are RH's latest released rpms for
these disto versions!
Cygwin is at 4.2.0-1. Looks like a red herring anyway, I can't fault any
'normal' (as in longstanding) X app icon handling through XWin!

I think I'm splitting hairs anyway by pushing my testing beyond XWin's
boundaries (i.e. handling clients outside cygwin, that should be handled via
XDMCP)?

Colin
Earle F. Philhower, III
2003-05-28 15:54:21 UTC
Permalink
Howdy Colin et. al,

There is a quick, easy fix for the 16x16 bitmask icon problem.
At winmultiwindowwindow.c, line 1961 there's an if statement:
if (iconPtr->drawable.width > 16 || iconPtr->drawable.height > 16)
iconSize = 32;
else
iconSize = 16;

Replace it completely with just
iconSize = 32

and all your problems are solved. There are assumptions that
are made in the scaler that aren't valid for sub 32-bit wide
icons or masks, and since the scaler can increase as well as
decrease the image, it all works just fine.

---------- Original Message -------------
Subject: RE: Custom icons per window class/name patch
From: "Colin Harrison" <***@virgin.net>
..
I don't get the xclock watch icon on my remote linux boxes either, (RedHat
8.0 and 7.3, KDE) using
XFree86-4.2.0-72 and XFree86-4.2.0-8 which are RH's latest released rpms for
these disto versions!
Cygwin is at 4.2.0-1. Looks like a red herring anyway, I can't fault any
'normal' (as in longstanding) X app icon handling through XWin!
----------------
Could be, it's not too big of a deal anyway since the masks seem to be
OK (OTW you would have a non-white clock face...)
--
-Earle F. Philhower, III
***@ziplabel.com
http://www.ziplabel.com
Colin Harrison
2003-05-28 16:12:11 UTC
Permalink
Hi Earle,

Just about to try your patch.

I'm going cross-eyed starring at these icon!
I think that there is a black outline to xeyes and xclock icons that maybe
gets lost in the wash!
KDE show them with an outline (maybe it's an add-on effect?)
Also think xclock has a watch icon now, after all, not a clock (I'm seeing 4
eyes now!)!!
I need a new big widescreen monitor and a new pair of specs!

I'll maybe try it on a friend's machine, he always has the most expensive
kit, being a graphics designer.


Colin
Colin Harrison
2003-05-28 16:37:53 UTC
Permalink
Hi Earle,

Your fix is good.
No more transparent background problems on ethereal or konqueror icons.

I'm off to get my eyes tested!

Thanks

Colin
Colin Harrison
2003-05-28 17:35:07 UTC
Permalink
Hi Earle et al,

Just some (final?) results to show how good icon handling now is.
Notice the xclock and xeyes now have their correct border and
woopee it is a watch not a clock!

(It's a tiny attached file, 20K...honest Alexander!)

Captured at 16 bit colour 1280x1024 display.
Post by Colin Harrison
Attached is a compressed .rtf file containing a capture of icons I get at
16
Post by Colin Harrison
bits colour via XWin.
It shows the task switcher icons with:-
1) A putty session (not via XWin!)
2) Six remote apps via XWin listed 'xxxxx &' in putty session.

File should open in WordPad etc.

Colin
Earle F. Philhower III
2003-05-29 00:55:33 UTC
Permalink
Howdy Colin, glad to hear it's working 100%. The original problem
was the endianness of Windoze 1-bit bitmap when using a non-32-bit
wide destination. I think the code was writing into the unused
portion of the 32-bits and you got garbage in the real mask part.

I found some kde apps on a linux box and did some peeking, it seems
that not many register a small 16x16 icon, and that konqueror, for
example, only gives a 16x16 icon in its _NET_WM_ICON property anyway.
Very strange, maybe that _NET_ICON thing isn't commonplace? Things
like KPAINT, KCALC, and KILLUSTRATOR (great name, the kill-ustrator)
have big icons by default in WM_HINTS.

------------

Today I also got to test a fix for the missed ButtonRelease problem
(dragging an Xterm scrollbar outside of its window and releasing
the button does not tell Xterm it was released, leading to "interesting"
problems). One thing I had to do that I don't like is to use a local
copy of what the winmultiwindowwindow.c thinks is the button state.
(i.e. LBUTTON=down, MBUTTON=up, RBUTTON=up) It did seem to work the
entire day of hard use w/o any problems, but I have the suspicion that
it might sometimes get out-of-sync w/the X server and send two
ButtonReleases. That'd be better than the present situation but could
still cause problems with pasting twice...

Is there a simple mi* or dix* call to get this info directly instead
of keeping a cached copy? I did a grep but didn't find anything
promising. You can't call XQueryPointer() since that's only legal for
a client to do. I suppose I could post something to the WM thread
but that's a real ugly kludge.


-Earle F. Philhower, III
***@ziplabel.com
cdrlabel - ZipLabel - FlpLabel
http://www.cdrlabel.com
Harold L Hunt II
2003-05-29 04:04:18 UTC
Permalink
Earle,

Whatever you do, don't send a patch for the mouse release fix until I
can make another test release. I am getting swamped with patches here.
Thanks.

Harold
Post by Earle F. Philhower III
Howdy Colin, glad to hear it's working 100%. The original problem
was the endianness of Windoze 1-bit bitmap when using a non-32-bit
wide destination. I think the code was writing into the unused
portion of the 32-bits and you got garbage in the real mask part.
I found some kde apps on a linux box and did some peeking, it seems
that not many register a small 16x16 icon, and that konqueror, for
example, only gives a 16x16 icon in its _NET_WM_ICON property anyway.
Very strange, maybe that _NET_ICON thing isn't commonplace? Things
like KPAINT, KCALC, and KILLUSTRATOR (great name, the kill-ustrator)
have big icons by default in WM_HINTS.
------------
Today I also got to test a fix for the missed ButtonRelease problem
(dragging an Xterm scrollbar outside of its window and releasing
the button does not tell Xterm it was released, leading to "interesting"
problems). One thing I had to do that I don't like is to use a local
copy of what the winmultiwindowwindow.c thinks is the button state.
(i.e. LBUTTON=down, MBUTTON=up, RBUTTON=up) It did seem to work the
entire day of hard use w/o any problems, but I have the suspicion that
it might sometimes get out-of-sync w/the X server and send two
ButtonReleases. That'd be better than the present situation but could
still cause problems with pasting twice...
Is there a simple mi* or dix* call to get this info directly instead
of keeping a cached copy? I did a grep but didn't find anything
promising. You can't call XQueryPointer() since that's only legal for
a client to do. I suppose I could post something to the WM thread
but that's a real ugly kludge.
-Earle F. Philhower, III
cdrlabel - ZipLabel - FlpLabel
http://www.cdrlabel.com
Earle F. Philhower III
2003-05-29 04:45:46 UTC
Permalink
Howdy Harold,
Whatever you do, don't send a patch for the mouse release fix until I can
make another test release. I am getting swamped with patches here. Thanks.
OK, truce!


-Earle F. Philhower, III
***@ziplabel.com
cdrlabel - ZipLabel - FlpLabel
http://www.cdrlabel.com
Harold L Hunt II
2003-05-29 06:37:13 UTC
Permalink
Okay, test release posted.

Please replace local source with source from test release, reapply local
patches to test source, and submit new patches as needed. :)

I have made lots of style fixes to the source, so you might as well
replace all files... otherwise diffs will be useless for me as they were
quoting hundreds of lines of source that were logically equivalent but
stylistically different. [Anybody about to send me a diff command that
ignores whitespace, don't... that isn't what I am looking for.]

Harold
Post by Earle F. Philhower III
Howdy Harold,
Post by Harold L Hunt II
Whatever you do, don't send a patch for the mouse release fix until I
can make another test release. I am getting swamped with patches
here. Thanks.
OK, truce!
-Earle F. Philhower, III
cdrlabel - ZipLabel - FlpLabel
http://www.cdrlabel.com
Alexander Gottwald
2003-05-29 10:31:28 UTC
Permalink
Post by Harold L Hunt II
Okay, test release posted.
Please replace local source with source from test release, reapply local
patches to test source, and submit new patches as needed. :)
Harold, can you import your local tree to the cvs on sourceforge? So we can
easily do updates and keep the merging problems at a minimum.

bye
ago
--
***@informatik.tu-chemnitz.de
http://www.gotti.org ICQ: 126018723
Earle F. Philhower III
2003-05-30 02:32:32 UTC
Permalink
Howdy Harold, let me just say thanks for the efforts you've been giving
while trying to herd cats^Wpatches...
11) Try, in vain, to maintain a uniform coding style and
variable/function naming convention. I am mostly winning the
curly-brace (curly braces on separate lines please), indenting (emacs
...
Please replace local source with source from test release, reapply local
patches to test source, and submit new patches as needed. :)
I have made lots of style fixes to the source, so you might as well
replace all files... otherwise diffs will be useless for me as they were
quoting hundreds of lines of source that were logically equivalent but
stylistically different. [Anybody about to send me a diff command that
ignores whitespace, don't... that isn't what I am looking for.]
All the old changes look to work great! I got my Debussy and NCVerilog icons,
title bars, etc. without a single change.

I am also attaching what I hope is a style-conforming patch for the missed
mouseup messages. The problem is that Windows will not give you a
WM_[LMR]BUTTON[UP/DOWN] unless the mouse is over a window you own. To get
around this I put in a check in the WM_TIMER which is already in there to
kludge WM_MOUSEMOVEs when the pointer is not in an X owned window. It's
gone through 2 days of me beating on it for real work and it seems OK.

-Earle F. Philhower, III
***@ziplabel.com
cdrlabel - ZipLabel - FlpLabel
http://www.cdrlabel.com
Colin Harrison
2003-05-31 00:42:37 UTC
Permalink
Hi Earle,

Just to say this patch works fine for me.

Thanks

Colin
Harold L Hunt II
2003-05-31 03:45:52 UTC
Permalink
Earle,

Any reason we shouldn't install a message hook when the user presses and
holds a mouse button or modifier key?

On a related note, what is up with
winmultiwindowwindow.c/winTopLevelWindowProc()/WM[NC]MOUSELEAVE and the
SetTimer call? This must have been something that Kensuke did without
me looking too closely :) It looks like it is used to move the X cursor
out of the screen view when the user moves the mouse out of the X
window... but it never calls KillTimer in the processing of WM_TIMER,
which is strange. It looks like this could also be used to move the
mouse cursor if it shows up over another X window... but that should be
handled by the WM_MOUSEMOVE processing for that new window.

Do you see any reason we can't get rid of these timers? I would really
like to avoid them if possible.

Harold
Post by Ralf Habacker
Hi Earle,
Just to say this patch works fine for me.
Thanks
Colin
Earle F. Philhower III
2003-05-31 05:14:09 UTC
Permalink
Howdy Harold,
Post by Harold L Hunt II
Any reason we shouldn't install a message hook when the user presses and
holds a mouse button or modifier key?
I'm not sure what you mean by this, do a mouse capture? This may change
the semantics,
because then any drop-target window won't get any mouse messages since only
one window
is allowed to see the mouse moves/buttons.
Post by Harold L Hunt II
On a related note, what is up with
winmultiwindowwindow.c/winTopLevelWindowProc()/WM[NC]MOUSELEAVE and the
SetTimer call? This must have been something that Kensuke did without me
looking too closely :) It looks like it is used to move the X cursor out
of the screen view when the user moves the mouse out of the X window...
but it never calls KillTimer in the processing of WM_TIMER, which is
strange. It looks like this could also be used to move the mouse cursor
if it shows up over another X window... but that should be handled by the
WM_MOUSEMOVE processing for that new window.
Do you see any reason we can't get rid of these timers? I would really
like to avoid them if possible.
I think what he was trying to do was to update the mouse position in the
root window when
the mouse isn't over any X window, since you only get mousemoves if the
mouse is over your
window. Removing the timers would kill things like xeyes and the
drag-n-drop icon movements
in some of the KDE/QT/whatever apps. In multi-window-mode the root window
would then only
get messages when the mouse was inside the client area of one of the apps...

Even if he doesn't KillTimer, since he is reusing the event id it shouldn't
cause any
kind of leak. And he does kill it on a mousemove on the initiating window.

However I think he has a bug here, it seems he will create a timer for each
X window, not one for the entire application. You can test this by
restarting the
server and running xeyes. Move your cursor around on the desktop, outside
the window
and see how the eyes only update once per second or so. Now, open up 20 x
terms and
move your mouse through each, just to start their timers. Finally, with
those 20
windows up move your mouse outside them on the Windoze desktop and you'll
notice the eyes are following in real time, much faster than before. As
bugs go
it's pretty benign, and would take another global variable to hold the timer ID
to fix...


-Earle F. Philhower, III
***@ziplabel.com
cdrlabel - ZipLabel - FlpLabel
http://www.cdrlabel.com
Harold L Hunt II
2003-05-31 19:14:10 UTC
Permalink
Earle,
Post by Earle F. Philhower III
Howdy Harold,
Post by Harold L Hunt II
Any reason we shouldn't install a message hook when the user presses
and holds a mouse button or modifier key?
I'm not sure what you mean by this, do a mouse capture? This may change
the semantics,
because then any drop-target window won't get any mouse messages since
only one window
is allowed to see the mouse moves/buttons.
No no, you do it with a message hook, like here:

http://www.codeproject.com/dll/trackuseridle.asp

I have written a message hook before that trapped all keyboard input and
played morse code over the system speaker. Obviously, morse code is
really hard to distinquish at 30 wpm! However, the hook worked just
fine. We would have to have a seperate DLL that was installed in the
hook chain... and it would be a good idea to make that DLL either a
MinGW or MSVCRT DLL, rather than having it depend upon Cygwin. The
reasoning for that is that hooks, if written poorly, can effect the
whole system. However, they are just fine if kept small and fast.
Post by Earle F. Philhower III
Post by Harold L Hunt II
On a related note, what is up with
winmultiwindowwindow.c/winTopLevelWindowProc()/WM[NC]MOUSELEAVE and
the SetTimer call? This must have been something that Kensuke did
without me looking too closely :) It looks like it is used to move
the X cursor out of the screen view when the user moves the mouse out
of the X window... but it never calls KillTimer in the processing of
WM_TIMER, which is strange. It looks like this could also be used to
move the mouse cursor if it shows up over another X window... but that
should be handled by the WM_MOUSEMOVE processing for that new window.
Do you see any reason we can't get rid of these timers? I would
really like to avoid them if possible.
I think what he was trying to do was to update the mouse position in the
root window when
the mouse isn't over any X window, since you only get mousemoves if the
mouse is over your
window. Removing the timers would kill things like xeyes and the
drag-n-drop icon movements
in some of the KDE/QT/whatever apps. In multi-window-mode the root
window would then only
get messages when the mouse was inside the client area of one of the apps...
Okay, this would work with hooks too.
Post by Earle F. Philhower III
Even if he doesn't KillTimer, since he is reusing the event id it
shouldn't cause any
kind of leak. And he does kill it on a mousemove on the initiating window.
Weird, when I did a search for KillTimer I didn't find anything. I must
have missed it. In any case, what I was looking for was a KillTimer
call win WM_MOUSEMOVE, which is there. No worries.
Post by Earle F. Philhower III
However I think he has a bug here, it seems he will create a timer for each
X window, not one for the entire application. You can test this by
restarting the
server and running xeyes. Move your cursor around on the desktop,
outside the window
and see how the eyes only update once per second or so. Now, open up 20
x terms and
move your mouse through each, just to start their timers. Finally, with
those 20
windows up move your mouse outside them on the Windoze desktop and you'll
notice the eyes are following in real time, much faster than before. As
bugs go
it's pretty benign, and would take another global variable to hold the timer ID
to fix...
Yes! That was what I was thinking too.

The global variable that he was using as a timer id should have been a
constant, however, we don't need to specify a timer id when passing a
NULL hwnd to SetTimer, so I changed the global variable to track the
value returned by SetTimer. This value is then passed to KillTimer to
destroy the timer when we see client mouse movement. This is great
because it eliminates lots of timers that could show up when users had
lots of windows open.

Thanks for the help,

Harold
Lev Bishop
2003-05-31 23:06:11 UTC
Permalink
More interesting stuff with timers, held keys, held mouse buttons:
Firstly, the timer doesn't even get created every time. I can demonstrate
this by starting xwin with just one xterm, and running xeyes. Normally if
I move the mouse out of the xterm then about half a second later the x
cursor gets deleted and the xeyes continue to update. But if I move the
mouse really quickly out of the xterm (helps that I have mouse sensitivity
set at the highest setting) then sometimes the cursor is not deleted and
xeyes don't update until I move mouse back into the xterm. So occasionally
the timer is not created, it seems. As a secondary phenomenon, if I do
this fast movement out of the xterm while at the same time holding a mouse
button, then the windows mouse cursor not shown either (ie the mouse is
invisible) until I release the click.

Secondly, the recent fix whereby all x keys get forced released on losing
focus doesn't seem to be strictly correct either. If I put focus on my
xterm and then hold, say shift or control, and while holding it click on
the desktop to remove focus from xterm and then click back on the xterm,
the xterm behaves as if shift and control are not pressed. Of course this
is rarely a problem but perhaps it could be an issue if there are any X
applications that make use of shift-drag/drop or control-drag/drop, etc,
like windows does. Might also be a problem for people using the windows
accessibility options such as "sticky keys".

So, all things considered, the message hook idea sounds better than using
a timer, and while you're at it, you could do the right thing(tm)
concerning keydown, keyup instead of just force-releasing all keys.
With this, might it in fact be possible to remove most of the
event-handling stuff out of each client-window message loop and just use
the hook to pass these messages directly to the root window. (Ie install
the hook once, at server-startup, and then you receive all the mouse and
keboard events, just like in the non-rootless, non-multiwindow case). I
don't know enough about the multiwindow implementation to know if this is
sensible.

Lev

Continue reading on narkive:
Loading...