@@ -1518,68 +1518,80 @@ public void setImage(int index, Image image) {
15181518 surface = imageList .getSurface (imageIndex );
15191519 pixbuf = ImageList .createPixbuf (surface );
15201520 }
1521-
1522- int modelIndex = parent .columnCount == 0 ? Tree .FIRST_COLUMN : parent .columns [index ].modelIndex ;
1523- long parentHandle = parent .handle ;
1524- long column = GTK .gtk_tree_view_get_column (parentHandle , index );
1525- long pixbufRenderer = parent .getPixbufRenderer (column );
1526- int [] currentWidth = new int [1 ];
1527- int [] currentHeight = new int [1 ];
1528- GTK .gtk_cell_renderer_get_fixed_size (pixbufRenderer , currentWidth , currentHeight );
1529- if (!parent .pixbufSizeSet ) {
1530- if (image != null ) {
1531- int iWidth , iHeight ;
1532- if (DPIUtil .useCairoAutoScale ()) {
1533- iWidth = image .getBounds ().width ;
1534- iHeight = image .getBounds ().height ;
1535- } else {
1536- iWidth = image .getBoundsInPixels ().width ;
1537- iHeight = image .getBoundsInPixels ().height ;
1538- }
1539- if (iWidth > currentWidth [0 ] || iHeight > currentHeight [0 ]) {
1540- GTK .gtk_cell_renderer_set_fixed_size (pixbufRenderer , iWidth , iHeight );
1541- parent .pixbufSizeSet = true ;
1542- parent .pixbufHeight = iHeight ;
1543- parent .pixbufWidth = iWidth ;
1544- /*
1545- * Feature in GTK: a Tree with the style SWT.VIRTUAL has
1546- * fixed-height-mode enabled. This will limit the size of
1547- * any cells, including renderers. In order to prevent
1548- * images from disappearing/being cropped, we re-create
1549- * the renderers when the first image is set. Fix for
1550- * bug 480261.
1551- */
1552- if ((parent .style & SWT .VIRTUAL ) != 0 ) {
1521+ try {
1522+ int modelIndex = parent .columnCount == 0 ? Tree .FIRST_COLUMN : parent .columns [index ].modelIndex ;
1523+ long parentHandle = parent .handle ;
1524+ long column = GTK .gtk_tree_view_get_column (parentHandle , index );
1525+ long pixbufRenderer = parent .getPixbufRenderer (column );
1526+ int [] currentWidth = new int [1 ];
1527+ int [] currentHeight = new int [1 ];
1528+ GTK .gtk_cell_renderer_get_fixed_size (pixbufRenderer , currentWidth , currentHeight );
1529+ if (!parent .pixbufSizeSet ) {
1530+ if (image != null ) {
1531+ int iWidth , iHeight ;
1532+ if (DPIUtil .useCairoAutoScale ()) {
1533+ iWidth = image .getBounds ().width ;
1534+ iHeight = image .getBounds ().height ;
1535+ } else {
1536+ iWidth = image .getBoundsInPixels ().width ;
1537+ iHeight = image .getBoundsInPixels ().height ;
1538+ }
1539+ if (iWidth > currentWidth [0 ] || iHeight > currentHeight [0 ]) {
1540+ GTK .gtk_cell_renderer_set_fixed_size (pixbufRenderer , iWidth , iHeight );
1541+ parent .pixbufSizeSet = true ;
1542+ parent .pixbufHeight = iHeight ;
1543+ parent .pixbufWidth = iWidth ;
15531544 /*
1554- * Only re-create SWT.CHECK renderers if this is the first column.
1555- * Otherwise check-boxes will be rendered in columns they are not
1556- * supposed to be rendered in. See bug 513761.
1545+ * Feature in GTK: a Tree with the style SWT.VIRTUAL has
1546+ * fixed-height-mode enabled. This will limit the size of
1547+ * any cells, including renderers. In order to prevent
1548+ * images from disappearing/being cropped, we re-create
1549+ * the renderers when the first image is set. Fix for
1550+ * bug 480261.
15571551 */
1558- boolean check = modelIndex == Tree .FIRST_COLUMN && (parent .style & SWT .CHECK ) != 0 ;
1559- parent .createRenderers (column , modelIndex , check , parent .style );
1552+ if ((parent .style & SWT .VIRTUAL ) != 0 ) {
1553+ /*
1554+ * Only re-create SWT.CHECK renderers if this is the first column.
1555+ * Otherwise check-boxes will be rendered in columns they are not
1556+ * supposed to be rendered in. See bug 513761.
1557+ */
1558+ boolean check = modelIndex == Tree .FIRST_COLUMN && (parent .style & SWT .CHECK ) != 0 ;
1559+ // Renderers can't be replaced during render on GTK 3.24.41
1560+ // https://github.com/eclipse-platform/eclipse.platform.swt/issues/678
1561+ getDisplay ().asyncExec (() -> {
1562+ // Do not perform request if it is no longer applicable
1563+ if (parent .isDisposed () || Math .max (1 , parent .getColumnCount ()) <= index ) return ;
1564+ // On multiple resize requests, perform only the last one
1565+ if (parent .pixbufHeight != iHeight || parent .pixbufWidth != iWidth ) return ;
1566+ int modelIndexAsync = parent .columnCount == 0 ? Tree .FIRST_COLUMN : parent .columns [index ].modelIndex ;
1567+ long columnAsync = GTK .gtk_tree_view_get_column (parent .handle , index );
1568+ parent .createRenderers (columnAsync , modelIndexAsync , check , parent .style );
1569+ });
1570+ }
15601571 }
15611572 }
1573+ } else {
1574+ /*
1575+ * Bug 483112: We check to see if the cached value is greater than the size of the pixbufRenderer.
1576+ * If it is, then we change the size of the pixbufRenderer accordingly.
1577+ * Bug 489025: There is a corner case where the below is triggered when current(Width|Height) is -1,
1578+ * which results in icons being set to 0. Fix is to compare only positive sizes.
1579+ */
1580+ if (parent .pixbufWidth > Math .max (currentWidth [0 ], 0 ) || parent .pixbufHeight > Math .max (currentHeight [0 ], 0 )) {
1581+ GTK .gtk_cell_renderer_set_fixed_size (pixbufRenderer , parent .pixbufWidth , parent .pixbufHeight );
1582+ }
15621583 }
1563- } else {
1584+
1585+ GTK .gtk_tree_store_set (parent .modelHandle , handle , modelIndex + Tree .CELL_PIXBUF , pixbuf , -1 );
1586+ } finally {
15641587 /*
1565- * Bug 483112: We check to see if the cached value is greater than the size of the pixbufRenderer.
1566- * If it is, then we change the size of the pixbufRenderer accordingly.
1567- * Bug 489025: There is a corner case where the below is triggered when current(Width|Height) is -1,
1568- * which results in icons being set to 0. Fix is to compare only positive sizes.
1588+ * Bug 573633: gtk_tree_store_set() will reference the handle. So we unref the pixbuf here,
1589+ * and leave the destruction of the handle to be done later on by the GTK+ tree.
15691590 */
1570- if (parent . pixbufWidth > Math . max ( currentWidth [ 0 ], 0 ) || parent . pixbufHeight > Math . max ( currentHeight [ 0 ], 0 ) ) {
1571- GTK . gtk_cell_renderer_set_fixed_size ( pixbufRenderer , parent . pixbufWidth , parent . pixbufHeight );
1591+ if (pixbuf != 0 ) {
1592+ OS . g_object_unref ( pixbuf );
15721593 }
15731594 }
1574-
1575- GTK .gtk_tree_store_set (parent .modelHandle , handle , modelIndex + Tree .CELL_PIXBUF , pixbuf , -1 );
1576- /*
1577- * Bug 573633: gtk_tree_store_set() will reference the handle. So we unref the pixbuf here,
1578- * and leave the destruction of the handle to be done later on by the GTK+ tree.
1579- */
1580- if (pixbuf != 0 ) {
1581- OS .g_object_unref (pixbuf );
1582- }
15831595 GTK .gtk_tree_store_set (parent .modelHandle , handle , modelIndex + Tree .CELL_SURFACE , surface , -1 );
15841596 cached = true ;
15851597 updated = true ;
0 commit comments