[PATCH 12/12] Cygwin/X: Update icons directly, rather than modifying the window's class

Jon TURNEY jon.turney at dronecode.org.uk
Wed May 20 04:52:30 PDT 2009


From: Joe Krahn <jkrahn at nc.rr.com>

Update icons directly to windows rather than modifying
the window's class.  Respect custom icons overriden via
the configuration file.

fd.o bugzilla #4491

Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
---
 hw/xwin/winmultiwindowicons.c    |   54 +++++++++++++++++---------------------
 hw/xwin/winprefs.c               |   35 +++++++++++-------------
 hw/xwin/winwin32rootlesswindow.c |    8 +++---
 3 files changed, 44 insertions(+), 53 deletions(-)

diff --git a/hw/xwin/winmultiwindowicons.c b/hw/xwin/winmultiwindowicons.c
index 88416bb..8200aad 100644
--- a/hw/xwin/winmultiwindowicons.c
+++ b/hw/xwin/winmultiwindowicons.c
@@ -364,43 +364,37 @@ void
 winUpdateIcon (Window id)
 {
   WindowPtr		pWin;
-  HICON			hIcon, hiconOld;
+  HICON			hIcon, hIconSmall=NULL, hIconOld;
 
   pWin = (WindowPtr) LookupIDByType (id, RT_WINDOW);
   if (!pWin) return;
-  hIcon = winOverrideIcon ((unsigned long)pWin);
+  winWindowPriv(pWin);
+  if (pWinPriv->hWnd) {
+    hIcon = winOverrideIcon ((unsigned long)pWin);
+    if (!hIcon) {
+      hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON));
+      if (!hIcon) {
+        hIcon = g_hIconX;
+        hIconSmall = g_hSmallIconX;
+      } else {
+        /* Leave undefined if not found */
+        hIconSmall = winXIconToHICON (pWin, GetSystemMetrics(SM_CXSMICON));
+      }
+    }
 
-  if (!hIcon)
-    hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON));
+    /* Set the large icon */
+    hIconOld = (HICON) SendMessage (pWinPriv->hWnd,
+                     WM_SETICON, ICON_BIG, (LPARAM) hIcon);
 
-  if (hIcon)
-    {
-      winWindowPriv(pWin);
+    /* Delete the icon if its not the default */
+    winDestroyIcon(hIconOld);
 
-      if (pWinPriv->hWnd)
-	{
-	  hiconOld = (HICON) SetClassLong (pWinPriv->hWnd,
-					   GCL_HICON,
-					   (int) hIcon);
-	  
-	  /* Delete the icon if its not the default */
-	  winDestroyIcon(hiconOld);
-	}
-    }
- 
-  hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXSMICON));
-  if (hIcon)
-    {
-      winWindowPriv(pWin);
+    /* Same for the small icon */
+    hIconOld = (HICON) SendMessage (pWinPriv->hWnd,
+                    WM_SETICON, ICON_SMALL, (LPARAM) hIconSmall);
+    winDestroyIcon(hIconOld);
 
-      if (pWinPriv->hWnd)
-	{
-	  hiconOld = (HICON) SetClassLong (pWinPriv->hWnd,
-					   GCL_HICONSM,
-					   (int) hIcon);
-	  winDestroyIcon (hiconOld);
-	}
-    }
+  }
 }
 
 void winInitGlobalIcons (void)
diff --git a/hw/xwin/winprefs.c b/hw/xwin/winprefs.c
index 8152064..fe49ae2 100644
--- a/hw/xwin/winprefs.c
+++ b/hw/xwin/winprefs.c
@@ -189,35 +189,28 @@ ReloadEnumWindowsProc (HWND hwnd, LPARAM lParam)
   /* It's our baby, either clean or dirty it */
   if (lParam==FALSE) 
     {
-      hicon = (HICON)GetClassLong(hwnd, GCL_HICON);
+      /* Reset the window's icon to undefined. */
+      hicon = (HICON)SendMessage(hwnd, WM_SETICON, ICON_BIG, 0);
 
-      /* Unselect any icon in the class structure */
-      SetClassLong (hwnd, GCL_HICON, (LONG)LoadIcon (NULL, IDI_APPLICATION));
-
-      /* If it's generated on-the-fly, get rid of it, will regen */
+      /* If the old icon is generated on-the-fly, get rid of it, will regen */
       winDestroyIcon (hicon);
-     
-      hicon = (HICON)GetClassLong(hwnd, GCL_HICONSM);
-
-      /* Unselect any icon in the class structure */
-      SetClassLong (hwnd, GCL_HICONSM, 0);
 
-      /* If it's generated on-the-fly, get rid of it, will regen */
+      /* Same for the small icon */
+      hicon = (HICON)SendMessage(hwnd, WM_SETICON, ICON_SMALL, 0);
       winDestroyIcon (hicon);
-      
-      /* Remove any menu additions, use bRevert flag */
+
+      /* Remove any menu additions; bRevert=TRUE destroys any modified menus */
       GetSystemMenu (hwnd, TRUE);
       
-      /* This window is now clean of our taint */
+      /* This window is now clean of our taint (but with undefined icons) */
     }
   else
     {
-      /* Make the icon default, dynamic, or from xwinrc */
-      SetClassLong (hwnd, GCL_HICON, (LONG)g_hIconX);
-      SetClassLong (hwnd, GCL_HICONSM, (LONG)g_hSmallIconX);
+      /* winUpdateIcon() will set the icon default, dynamic, or from xwinrc */
       wid = (Window)GetProp (hwnd, WIN_WID_PROP);
       if (wid)
 	winUpdateIcon (wid);
+
       /* Update the system menu for this window */
       SetupSysMenu ((unsigned long)hwnd);
 
@@ -241,8 +234,12 @@ ReloadPrefs (void)
   int i;
 
 #ifdef XWIN_MULTIWINDOW
-  /* First, iterate over all windows replacing their icon with system */
-  /* default one and deleting any custom system menus                 */
+  /* First, iterate over all windows, deleting their icons and custom menus.
+   * This is really only needed because winDestroyIcon() will try to
+   * destroy the old global icons, which will have changed.
+   * It is probably better to set a windows USER_DATA to flag locally defined
+   * icons, and use that to accurately know when to destroy old icons.
+   */
   EnumThreadWindows (g_dwCurrentThreadID, ReloadEnumWindowsProc, FALSE);
 #endif
   
diff --git a/hw/xwin/winwin32rootlesswindow.c b/hw/xwin/winwin32rootlesswindow.c
index 3f521d6..2b2f630 100755
--- a/hw/xwin/winwin32rootlesswindow.c
+++ b/hw/xwin/winwin32rootlesswindow.c
@@ -177,12 +177,12 @@ winMWExtWMUpdateIcon (Window id)
 
       if (pRLWinPriv->hWnd)
 	{
-	  hiconOld = (HICON) SetClassLong (pRLWinPriv->hWnd,
-					   GCL_HICON,
-					   (int) hIcon);
-	  
+
+          hiconOld = (HICON) SendMessage (pRLWinPriv->hWnd,
+                     WM_SETICON, ICON_BIG, (LPARAM) hIcon);
           winDestroyIcon(hiconOld);
 	}
+      hIcon=NULL;
     }
 }
 
-- 
1.6.1.2



More information about the xorg-devel mailing list