Tk Source Code

Artifact [4be4f8c5]
Login

Artifact 4be4f8c5429da22da3e8a78807062763944d1288566f14c56d511a56b6faac78:

Attachment "win-cb.tk.patch" to ticket [3c6660b6] added by bll 2020-05-20 17:26:45.
--- win/ttkWinXPTheme.c	2019-12-23 08:50:26.437957908 -0800
+++ win/ttkWinXPTheme.c	2020-05-20 10:11:33.589093504 -0700
@@ -371,6 +371,10 @@
  * <<NOTE-GetThemePartSize>>:
  *	This gives bogus metrics for some parts (in particular,
  *	BP_PUSHBUTTONS).  Set the IGNORE_THEMESIZE flag to skip this call.
+ *
+ * <<NOTE-GetThemePartSize-2>>:
+ *      It seems that fetching the part size more than once on checkbuttons
+ *      and radiobuttons does not work properly.
  */

 typedef struct 	/* XP element specifications */
@@ -388,6 +392,7 @@
 #   define 	HEAP_ELEMENT	 0x20000000 /* ElementInfo is on heap */
 #   define 	HALF_HEIGHT	 0x10000000 /* Used by GenericSizedElements */
 #   define 	HALF_WIDTH	 0x08000000 /* Used by GenericSizedElements */
+#   define      FETCH_ONCE       0x04000000U /* Used by GenericElementSize See NOTE-GetThemePartSize-2 */
 } ElementInfo;

 typedef struct
@@ -405,6 +410,12 @@
     HDC		hDC;
     HWND	hwnd;

+    /*
+     * To work around fetch of size returning wrong data
+     */
+    SIZE        origSize;
+    int         fetched;
+
     /* For TkWinDrawableReleaseDC: */
     Drawable	drawable;
     TkWinDCState dcState;
@@ -418,6 +429,7 @@
     elementData->procs = procs;
     elementData->info = info;
     elementData->hTheme = elementData->hDC = 0;
+    elementData->fetched = 0;

     return elementData;
 }
@@ -505,19 +517,28 @@
 	return;

     if (!(elementData->info->flags & IGNORE_THEMESIZE)) {
-	result = elementData->procs->GetThemePartSize(
-	    elementData->hTheme,
-	    elementData->hDC,
-	    elementData->info->partId,
-	    Ttk_StateTableLookup(elementData->info->statemap, 0),
-	    NULL /*RECT *prc*/,
-	    TS_TRUE,
-	    &size);
+        if ((elementData->info->flags & FETCH_ONCE) && elementData->fetched) {
+            size = elementData->origSize;
+            result = 0; /* non-negative is success */
+        } else {
+	  result = elementData->procs->GetThemePartSize(
+	      elementData->hTheme,
+	      elementData->hDC,
+	      elementData->info->partId,
+	      Ttk_StateTableLookup(elementData->info->statemap, 0),
+	      NULL /*RECT *prc*/,
+	      TS_TRUE,
+	      &size);
+        }

 	if (SUCCEEDED(result)) {
 	    *widthPtr = size.cx;
 	    *heightPtr = size.cy;
 	}
+        if ((elementData->info->flags & FETCH_ONCE) && ! elementData->fetched) {
+            elementData->origSize = size;
+            elementData->fetched = 1;
+        }
     }

     /* See NOTE-GetThemeMargins
@@ -960,9 +981,9 @@

 static ElementInfo ElementInfoTable[] = {
     { "Checkbutton.indicator", &GenericElementSpec, L"BUTTON",
-    	BP_CHECKBOX, checkbox_statemap, PAD(0, 0, 4, 0), PAD_MARGINS },
+    	BP_CHECKBOX, checkbox_statemap, PAD(0, 0, 4, 0), PAD_MARGINS | FETCH_ONCE },
     { "Radiobutton.indicator", &GenericElementSpec, L"BUTTON",
-    	BP_RADIOBUTTON, radiobutton_statemap, PAD(0, 0, 4, 0), PAD_MARGINS },
+    	BP_RADIOBUTTON, radiobutton_statemap, PAD(0, 0, 4, 0), PAD_MARGINS | FETCH_ONCE },
     { "Button.button", &GenericElementSpec, L"BUTTON",
     	BP_PUSHBUTTON, pushbutton_statemap, PAD(3, 3, 3, 3), IGNORE_THEMESIZE },
     { "Labelframe.border", &GenericElementSpec, L"BUTTON",