Custom icons per window class/name patch

Earle F. Philhower III earle@ziplabel.com
Wed May 28 05:22:00 GMT 2003


Howdy Ralf, I'm condensing a bunch of your messages into one longer one...

At 11:30 PM 5/27/2003 +0200, you wrote:
>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:
>...
>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.

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...

>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"

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"

> > 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...


>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!


>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!
...
 > 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.

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...


> > 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...

> > 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.

 > 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.

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.

> > 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.

>I have some questions about this:
>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

>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...

>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.

> > 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.

>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...

>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
  earle@ziplabel.com
  cdrlabel - ZipLabel - FlpLabel
  http://www.cdrlabel.com



More information about the Cygwin-xfree mailing list