* X11GLNative.cs: Implemented Icon property for WMs that do not

respect _NET_WM_ICON (e.g. Gnome/Metacity/Compiz).
This commit is contained in:
the_fiddler 2009-10-19 10:42:28 +00:00
parent a05d06b2d8
commit 0c9657c5e7

View file

@ -512,6 +512,36 @@ namespace OpenTK.Platform.X11
#endregion #endregion
#region DeleteIconPixmaps
static void DeleteIconPixmaps(IntPtr display, IntPtr window)
{
IntPtr wmHints_ptr = Functions.XGetWMHints(display, window);
if (wmHints_ptr != IntPtr.Zero)
{
XWMHints wmHints = (XWMHints)Marshal.PtrToStructure(wmHints_ptr, typeof(XWMHints));
XWMHintsFlags flags = (XWMHintsFlags)wmHints.flags.ToInt32();
if ((flags & XWMHintsFlags.IconPixmapHint) != 0)
{
wmHints.flags = new IntPtr((int)(flags & ~XWMHintsFlags.IconPixmapHint));
Functions.XFreePixmap(display, wmHints.icon_pixmap);
}
if ((flags & XWMHintsFlags.IconMaskHint) != 0)
{
wmHints.flags = new IntPtr((int)(flags & ~XWMHintsFlags.IconMaskHint));
Functions.XFreePixmap(display, wmHints.icon_mask);
}
Functions.XSetWMHints(display, window, ref wmHints);
Functions.XFree(wmHints_ptr);
}
}
#endregion
#endregion #endregion
#region INativeWindow Members #region INativeWindow Members
@ -792,21 +822,20 @@ namespace OpenTK.Platform.X11
if (value == icon) if (value == icon)
return; return;
// Note: it seems that Gnome/Metacity does not respect the _NET_WM_ICON hint.
// For this reason, we'll also set the icon using XSetWMHints.
if (value == null) if (value == null)
{ {
Functions.XDeleteProperty(window.Display, window.WindowHandle, _atom_net_wm_icon); Functions.XDeleteProperty(window.Display, window.WindowHandle, _atom_net_wm_icon);
DeleteIconPixmaps(window.Display, window.WindowHandle);
} }
else else
{ {
Bitmap bitmap; // Set _NET_WM_ICON
int size; Bitmap bitmap = value.ToBitmap();
IntPtr[] data; int size = bitmap.Width * bitmap.Height + 2;
int index; IntPtr[] data = new IntPtr[size];
int index = 0;
bitmap = icon.ToBitmap();
index = 0;
size = bitmap.Width * bitmap.Height + 2;
data = new IntPtr[size];
data[index++] = (IntPtr)bitmap.Width; data[index++] = (IntPtr)bitmap.Width;
data[index++] = (IntPtr)bitmap.Height; data[index++] = (IntPtr)bitmap.Height;
@ -818,9 +847,28 @@ namespace OpenTK.Platform.X11
Functions.XChangeProperty(window.Display, window.WindowHandle, Functions.XChangeProperty(window.Display, window.WindowHandle,
_atom_net_wm_icon, _atom_xa_cardinal, 32, _atom_net_wm_icon, _atom_xa_cardinal, 32,
PropertyMode.Replace, data, size); PropertyMode.Replace, data, size);
// Set XWMHints
DeleteIconPixmaps(window.Display, window.WindowHandle);
IntPtr wmHints_ptr = Functions.XGetWMHints(window.Display, window.WindowHandle);
if (wmHints_ptr == IntPtr.Zero)
wmHints_ptr = Functions.XAllocWMHints();
XWMHints wmHints = (XWMHints)Marshal.PtrToStructure(wmHints_ptr, typeof(XWMHints));
wmHints.flags = new IntPtr(wmHints.flags.ToInt32() | (int)(XWMHintsFlags.IconPixmapHint | XWMHintsFlags.IconMaskHint));
wmHints.icon_pixmap = Functions.CreatePixmapFromImage(window.Display, bitmap);
wmHints.icon_mask = Functions.CreateMaskFromImage(window.Display, bitmap);
Functions.XSetWMHints(window.Display, window.WindowHandle, ref wmHints);
Functions.XFree (wmHints_ptr);
Functions.XSync(window.Display, false);
} }
icon = value; icon = value;
if (IconChanged != null)
IconChanged(this, EventArgs.Empty); IconChanged(this, EventArgs.Empty);
} }
} }