From 6d13d8155abd372a916bb94e9145c8c719a16b8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=8A?= =?UTF-8?q?=D1=80=20=D0=9A=D1=83=D1=80=D1=82=D0=B0=D0=BA=D0=BE=D0=B2?= Date: Thu, 2 Jul 2026 10:05:54 +0300 Subject: [PATCH 01/46] [GTK4] Implement DropTarget async drop handling Implement GTK4 DropTarget support using GtkDropTargetAsync with accept, enter/motion/leave and drop handlers. Add GTK4 drop data flow integration by matching offered GTypes, reading drop values asynchronously via gdk_drop_read_value_async/finish, and finishing drops with the selected action. Tested with DNDExample. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../gtk/org/eclipse/swt/dnd/DropTarget.java | 464 +++++++++++++++--- .../Eclipse SWT PI/gtk/library/gtk4.c | 82 ++++ .../Eclipse SWT PI/gtk/library/gtk4_stats.h | 7 + .../gtk/org/eclipse/swt/internal/gtk/OS.java | 3 + .../org/eclipse/swt/internal/gtk4/GTK4.java | 35 ++ 5 files changed, 512 insertions(+), 79 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/DropTarget.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/DropTarget.java index 6ca2c9a334a..c01333c0ee7 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/DropTarget.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/DropTarget.java @@ -14,9 +14,12 @@ package org.eclipse.swt.dnd; +import java.lang.reflect.*; + import org.eclipse.swt.*; import org.eclipse.swt.graphics.*; import org.eclipse.swt.internal.*; +import org.eclipse.swt.internal.GAsyncReadyCallbackHelper.*; import org.eclipse.swt.internal.gtk.*; import org.eclipse.swt.internal.gtk3.*; import org.eclipse.swt.internal.gtk4.*; @@ -111,11 +114,26 @@ public class DropTarget extends Widget { static Callback Drag_Data_Received; static Callback Drag_Drop; + /* GTK4 specific callbacks for GtkDropTargetAsync signals */ + static Callback DropAccept; + static Callback DropEnter; + static Callback DropMotion; + static Callback DropLeave; + static Callback Drop; + static { - Drag_Motion = new Callback(DropTarget.class, "Drag_Motion", 5); //$NON-NLS-1$ - Drag_Leave = new Callback(DropTarget.class, "Drag_Leave", 3); //$NON-NLS-1$ - Drag_Data_Received = new Callback(DropTarget.class, "Drag_Data_Received", 7); //$NON-NLS-1$ - Drag_Drop = new Callback(DropTarget.class, "Drag_Drop", 5); //$NON-NLS-1$ + if (GTK.GTK4) { + DropAccept = new Callback(DropTarget.class, "DropAccept", long.class, new Type[] {long.class, long.class}); //$NON-NLS-1$ + DropEnter = new Callback(DropTarget.class, "DropEnter", long.class, new Type[] {long.class, long.class, double.class, double.class}); //$NON-NLS-1$ + DropMotion = new Callback(DropTarget.class, "DropMotion", long.class, new Type[] {long.class, long.class, double.class, double.class}); //$NON-NLS-1$ + DropLeave = new Callback(DropTarget.class, "DropLeave", void.class, new Type[] {long.class, long.class}); //$NON-NLS-1$ + Drop = new Callback(DropTarget.class, "Drop", long.class, new Type[] {long.class, long.class, double.class, double.class}); //$NON-NLS-1$ + } else { + Drag_Motion = new Callback(DropTarget.class, "Drag_Motion", 5); //$NON-NLS-1$ + Drag_Leave = new Callback(DropTarget.class, "Drag_Leave", 3); //$NON-NLS-1$ + Drag_Data_Received = new Callback(DropTarget.class, "Drag_Data_Received", 7); //$NON-NLS-1$ + Drag_Drop = new Callback(DropTarget.class, "Drag_Drop", 5); //$NON-NLS-1$ + } } /* GTK4 specific */ @@ -157,10 +175,23 @@ public DropTarget(Control control, int style) { this.control = control; if (GTK.GTK4) { + if (DropAccept == null || DropEnter == null || DropMotion == null || DropLeave == null || Drop == null) { + DND.error(DND.ERROR_CANNOT_INIT_DROP); + } + if (control.getData(DND.DROP_TARGET_KEY) != null) { + DND.error(DND.ERROR_CANNOT_INIT_DROP); + } + control.setData(DND.DROP_TARGET_KEY, this); + int actions = opToOsOp(style); dropController = GTK4.gtk_drop_target_async_new(0, actions); - GTK4.gtk_widget_add_controller(control.handle, dropController); + + OS.g_signal_connect(dropController, OS.accept, DropAccept.getAddress(), 0); + OS.g_signal_connect(dropController, OS.drag_enter, DropEnter.getAddress(), 0); + OS.g_signal_connect(dropController, OS.drag_motion, DropMotion.getAddress(), 0); + OS.g_signal_connect(dropController, OS.drag_leave, DropLeave.getAddress(), 0); + OS.g_signal_connect(dropController, OS.drop, Drop.getAddress(), 0); } else { if (Drag_Motion == null || Drag_Leave == null || Drag_Data_Received == null || Drag_Drop == null) { DND.error(DND.ERROR_CANNOT_INIT_DROP); @@ -176,74 +207,74 @@ public DropTarget(Control control, int style) { drag_leave_handler = OS.g_signal_connect(control.handle, OS.drag_leave, Drag_Leave.getAddress(), 0); drag_data_received_handler = OS.g_signal_connect(control.handle, OS.drag_data_received, Drag_Data_Received.getAddress(), 0); drag_drop_handler = OS.g_signal_connect(control.handle, OS.drag_drop, Drag_Drop.getAddress(), 0); + } - // Dispose listeners - controlListener = event -> { - if (!DropTarget.this.isDisposed()){ - DropTarget.this.dispose(); - } - }; - control.addListener(SWT.Dispose, controlListener); - - this.addListener(SWT.Dispose, event -> onDispose()); - - Object effect = control.getData(DEFAULT_DROP_TARGET_EFFECT); - if (effect instanceof DropTargetEffect) { - dropEffect = (DropTargetEffect) effect; - } else if (control instanceof Table) { - dropEffect = new TableDropTargetEffect((Table) control); - } else if (control instanceof Tree) { - dropEffect = new TreeDropTargetEffect((Tree) control); + // Dispose listeners + controlListener = event -> { + if (!DropTarget.this.isDisposed()){ + DropTarget.this.dispose(); } + }; + control.addListener(SWT.Dispose, controlListener); + + this.addListener(SWT.Dispose, event -> onDispose()); + + Object effect = control.getData(DEFAULT_DROP_TARGET_EFFECT); + if (effect instanceof DropTargetEffect) { + dropEffect = (DropTargetEffect) effect; + } else if (control instanceof Table) { + dropEffect = new TableDropTargetEffect((Table) control); + } else if (control instanceof Tree) { + dropEffect = new TreeDropTargetEffect((Tree) control); + } - dragOverHeartbeat = () -> { - Control control1 = DropTarget.this.control; - if (control1 == null || control1.isDisposed() || dragOverStart == 0) return; - long time = System.currentTimeMillis(); - int delay = DRAGOVER_HYSTERESIS; - if (time < dragOverStart) { - delay = (int)(dragOverStart - time); - } else { - dragOverEvent.time += DRAGOVER_HYSTERESIS; - int allowedOperations = dragOverEvent.operations; - TransferData[] allowedTypes = dragOverEvent.dataTypes; - //pass a copy of data types in to listeners in case application modifies it - TransferData[] dataTypes = new TransferData[allowedTypes.length]; - System.arraycopy(allowedTypes, 0, dataTypes, 0, dataTypes.length); - - DNDEvent event = new DNDEvent(); - event.widget = dragOverEvent.widget; - event.x = dragOverEvent.x; - event.y = dragOverEvent.y; - event.time = dragOverEvent.time; - event.feedback = DND.FEEDBACK_SELECT; - event.dataTypes = dataTypes; - event.dataType = selectedDataType; - event.operations = dragOverEvent.operations; - event.detail = selectedOperation; - if (dropEffect != null) { - event.item = dropEffect.getItem(dragOverEvent.x, dragOverEvent.y); - } - selectedDataType = null; - selectedOperation = DND.DROP_NONE; - notifyListeners(DND.DragOver, event); - if (event.dataType != null) { - for (int i = 0; i < allowedTypes.length; i++) { - if (allowedTypes[i].type == event.dataType.type) { - selectedDataType = event.dataType; - break; - } + dragOverHeartbeat = () -> { + Control control1 = DropTarget.this.control; + if (control1 == null || control1.isDisposed() || dragOverStart == 0) return; + long time = System.currentTimeMillis(); + int delay = DRAGOVER_HYSTERESIS; + if (time < dragOverStart) { + delay = (int)(dragOverStart - time); + } else { + dragOverEvent.time += DRAGOVER_HYSTERESIS; + int allowedOperations = dragOverEvent.operations; + TransferData[] allowedTypes = dragOverEvent.dataTypes; + //pass a copy of data types in to listeners in case application modifies it + TransferData[] dataTypes = new TransferData[allowedTypes.length]; + System.arraycopy(allowedTypes, 0, dataTypes, 0, dataTypes.length); + + DNDEvent event = new DNDEvent(); + event.widget = dragOverEvent.widget; + event.x = dragOverEvent.x; + event.y = dragOverEvent.y; + event.time = dragOverEvent.time; + event.feedback = DND.FEEDBACK_SELECT; + event.dataTypes = dataTypes; + event.dataType = selectedDataType; + event.operations = dragOverEvent.operations; + event.detail = selectedOperation; + if (dropEffect != null) { + event.item = dropEffect.getItem(dragOverEvent.x, dragOverEvent.y); + } + selectedDataType = null; + selectedOperation = DND.DROP_NONE; + notifyListeners(DND.DragOver, event); + if (event.dataType != null) { + for (int i = 0; i < allowedTypes.length; i++) { + if (allowedTypes[i].type == event.dataType.type) { + selectedDataType = event.dataType; + break; } } - if (selectedDataType != null && (event.detail & allowedOperations) != 0) { - selectedOperation = event.detail; - } } - control1 = DropTarget.this.control; - if (control1 == null || control1.isDisposed()) return; - control1.getDisplay().timerExec(delay, dragOverHeartbeat); - }; - } + if (selectedDataType != null && (event.detail & allowedOperations) != 0) { + selectedOperation = event.detail; + } + } + control1 = DropTarget.this.control; + if (control1 == null || control1.isDisposed()) return; + control1.getDisplay().timerExec(delay, dragOverHeartbeat); + }; } static int checkStyle (int style) { @@ -285,6 +316,42 @@ static DropTarget FindDropTarget(long handle) { return (DropTarget)widget.getData(DND.DROP_TARGET_KEY); } +static DropTarget FindDropTargetGtk4(long controller) { + long widget = GTK.gtk_event_controller_get_widget(controller); + if (widget == 0) return null; + return FindDropTarget(widget); +} + +static long DropAccept(long controller, long drop) { + DropTarget target = FindDropTargetGtk4(controller); + if (target == null) return 0; + return target.dropAcceptGtk4(drop) ? 1 : 0; +} + +static long DropEnter(long controller, long drop, double x, double y) { + DropTarget target = FindDropTargetGtk4(controller); + if (target == null) return 0; + return target.dropMotionGtk4(drop, x, y, true); +} + +static long DropMotion(long controller, long drop, double x, double y) { + DropTarget target = FindDropTargetGtk4(controller); + if (target == null) return 0; + return target.dropMotionGtk4(drop, x, y, false); +} + +static void DropLeave(long controller, long drop) { + DropTarget target = FindDropTargetGtk4(controller); + if (target == null) return; + target.dropLeaveGtk4(drop); +} + +static long Drop(long controller, long drop, double x, double y) { + DropTarget target = FindDropTargetGtk4(controller); + if (target == null) return 0; + return target.dropGtk4(drop, x, y) ? 1 : 0; +} + /** * Adds the listener to the collection of listeners who will * be notified when a drag and drop operation is in progress, by sending @@ -593,12 +660,19 @@ public Transfer[] getTransfer() { void onDispose(){ if (control == null) return; - OS.g_signal_handler_disconnect(control.handle, drag_motion_handler); - OS.g_signal_handler_disconnect(control.handle, drag_leave_handler); - OS.g_signal_handler_disconnect(control.handle, drag_data_received_handler); - OS.g_signal_handler_disconnect(control.handle, drag_drop_handler); - if (transferAgents.length != 0) - GTK3.gtk_drag_dest_unset(control.handle); + if (GTK.GTK4) { + if (dropController != 0) { + GTK4.gtk_widget_remove_controller(control.handle, dropController); + dropController = 0; + } + } else { + OS.g_signal_handler_disconnect(control.handle, drag_motion_handler); + OS.g_signal_handler_disconnect(control.handle, drag_leave_handler); + OS.g_signal_handler_disconnect(control.handle, drag_data_received_handler); + OS.g_signal_handler_disconnect(control.handle, drag_drop_handler); + if (transferAgents.length != 0) + GTK3.gtk_drag_dest_unset(control.handle); + } transferAgents = null; if (controlListener != null) control.removeListener(SWT.Dispose, controlListener); @@ -609,22 +683,30 @@ void onDispose(){ int opToOsOp(int operation){ int osOperation = 0; + // GTK4 redefined the GdkDragAction values, so they differ from GTK3. + int copy = GTK.GTK4 ? GTK4.GDK_ACTION_COPY : GDK.GDK_ACTION_COPY; + int move = GTK.GTK4 ? GTK4.GDK_ACTION_MOVE : GDK.GDK_ACTION_MOVE; + int link = GTK.GTK4 ? GTK4.GDK_ACTION_LINK : GDK.GDK_ACTION_LINK; if ((operation & DND.DROP_COPY) == DND.DROP_COPY) - osOperation |= GDK.GDK_ACTION_COPY; + osOperation |= copy; if ((operation & DND.DROP_MOVE) == DND.DROP_MOVE) - osOperation |= GDK.GDK_ACTION_MOVE; + osOperation |= move; if ((operation & DND.DROP_LINK) == DND.DROP_LINK) - osOperation |= GDK.GDK_ACTION_LINK; + osOperation |= link; return osOperation; } int osOpToOp(int osOperation){ int operation = DND.DROP_NONE; - if ((osOperation & GDK.GDK_ACTION_COPY) == GDK.GDK_ACTION_COPY) + // GTK4 redefined the GdkDragAction values, so they differ from GTK3. + int copy = GTK.GTK4 ? GTK4.GDK_ACTION_COPY : GDK.GDK_ACTION_COPY; + int move = GTK.GTK4 ? GTK4.GDK_ACTION_MOVE : GDK.GDK_ACTION_MOVE; + int link = GTK.GTK4 ? GTK4.GDK_ACTION_LINK : GDK.GDK_ACTION_LINK; + if ((osOperation & copy) == copy) operation |= DND.DROP_COPY; - if ((osOperation & GDK.GDK_ACTION_MOVE) == GDK.GDK_ACTION_MOVE) + if ((osOperation & move) == move) operation |= DND.DROP_MOVE; - if ((osOperation & GDK.GDK_ACTION_LINK) == GDK.GDK_ACTION_LINK) + if ((osOperation & link) == link) operation |= DND.DROP_LINK; return operation; } @@ -825,4 +907,228 @@ void updateDragOverHover(long delay, DNDEvent event) { dragOverEvent.operations = event.operations; dragOverEvent.time = event.time; } + +/* GTK4 drop target handlers */ + +boolean dropAcceptGtk4(long drop) { + if (control == null || control.isDisposed()) return false; + long formats = GTK4.gdk_drop_get_formats(drop); + if (formats == 0) return false; + for (Transfer transfer : transferAgents) { + if (transfer == null) continue; + long gtype = ContentProviders.getInstance().getGType(transfer); + if (gtype != 0 && GTK4.gdk_content_formats_contain_gtype(formats, gtype)) { + return true; + } + } + return false; +} + +long dropMotionGtk4(long drop, double x, double y, boolean isEnter) { + int oldKeyOperation = keyOperation; + + if (isEnter) { + selectedDataType = null; + selectedOperation = DND.DROP_NONE; + } + + DNDEvent event = new DNDEvent(); + if (!setEventDataGtk4(drop, x, y, event)) { + keyOperation = -1; + return 0; + } + + int allowedOperations = event.operations; + TransferData[] allowedDataTypes = new TransferData[event.dataTypes.length]; + System.arraycopy(event.dataTypes, 0, allowedDataTypes, 0, allowedDataTypes.length); + + if (isEnter) { + event.type = DND.DragEnter; + } else if (keyOperation == oldKeyOperation) { + event.type = DND.DragOver; + event.dataType = selectedDataType; + event.detail = selectedOperation; + } else { + event.type = DND.DragOperationChanged; + event.dataType = selectedDataType; + } + updateDragOverHover(DRAGOVER_HYSTERESIS, event); + selectedDataType = null; + selectedOperation = DND.DROP_NONE; + notifyListeners(event.type, event); + if (event.detail == DND.DROP_DEFAULT) { + event.detail = (allowedOperations & DND.DROP_MOVE) != 0 ? DND.DROP_MOVE : DND.DROP_NONE; + } + if (event.dataType != null) { + for (TransferData allowedDataType : allowedDataTypes) { + if (allowedDataType.type == event.dataType.type) { + selectedDataType = event.dataType; + break; + } + } + } + if (selectedDataType != null && (allowedOperations & event.detail) != 0) { + selectedOperation = event.detail; + } + + if (isEnter) { + dragOverHeartbeat.run(); + } + return opToOsOp(selectedOperation); +} + +void dropLeaveGtk4(long drop) { + updateDragOverHover(0, null); + + if (keyOperation == -1) return; + keyOperation = -1; + + DNDEvent event = new DNDEvent(); + event.widget = this; + event.time = (int) System.currentTimeMillis(); + event.detail = DND.DROP_NONE; + notifyListeners(DND.DragLeave, event); +} + +boolean dropGtk4(long drop, double x, double y) { + // Stop the DragOver heartbeat; GTK4 does not reliably emit drag-leave after a drop. + updateDragOverHover(0, null); + + DNDEvent event = new DNDEvent(); + if (!setEventDataGtk4(drop, x, y, event)) { + keyOperation = -1; + return false; + } + keyOperation = -1; + + int allowedOperations = event.operations; + TransferData[] allowedDataTypes = new TransferData[event.dataTypes.length]; + System.arraycopy(event.dataTypes, 0, allowedDataTypes, 0, allowedDataTypes.length); + + event.dataType = selectedDataType; + event.detail = selectedOperation; + selectedDataType = null; + selectedOperation = DND.DROP_NONE; + notifyListeners(DND.DropAccept, event); + if (event.dataType != null) { + for (TransferData allowedDataType : allowedDataTypes) { + if (allowedDataType.type == event.dataType.type) { + selectedDataType = allowedDataType; + break; + } + } + } + if (selectedDataType != null && ((event.detail & allowedOperations) == event.detail)) { + selectedOperation = event.detail; + } + if (selectedOperation == DND.DROP_NONE) { + GTK4.gdk_drop_finish(drop, 0); + return false; + } + + // Find the transfer agent that supports the selected data type and request its value + Transfer selectedTransfer = null; + for (Transfer transfer : transferAgents) { + if (transfer != null && transfer.isSupportedType(selectedDataType)) { + selectedTransfer = transfer; + break; + } + } + if (selectedTransfer == null) { + GTK4.gdk_drop_finish(drop, 0); + return false; + } + + long gtype = ContentProviders.getInstance().getGType(selectedTransfer); + final TransferData dropDataType = selectedDataType; + final int dropAllowedOperations = allowedOperations; + GAsyncReadyCallbackHelper.run(new Async() { + @Override + public void async(long callback) { + GTK4.gdk_drop_read_value_async(drop, gtype, OS.G_PRIORITY_DEFAULT, 0, callback, 0); + } + @Override + public void callback(long result) { + Object object = null; + long gvalue = GTK4.gdk_drop_read_value_finish(drop, result, null); + if (gvalue != 0) { + object = ContentProviders.getInstance().getObject(gvalue); + } + + int operation = selectedOperation; + if (object == null) { + operation = DND.DROP_NONE; + } + + DNDEvent dropEvent = new DNDEvent(); + dropEvent.widget = DropTarget.this; + dropEvent.time = (int) System.currentTimeMillis(); + dropEvent.detail = operation; + dropEvent.dataType = dropDataType; + dropEvent.data = object; + operation = DND.DROP_NONE; + notifyListeners(DND.Drop, dropEvent); + if ((dropAllowedOperations & dropEvent.detail) == dropEvent.detail) { + operation = dropEvent.detail; + } + + GTK4.gdk_drop_finish(drop, opToOsOp(operation)); + } + }); + return true; +} + +boolean setEventDataGtk4(long drop, double x, double y, DNDEvent event) { + if (drop == 0) return false; + long formats = GTK4.gdk_drop_get_formats(drop); + int actions = GTK4.gdk_drop_get_actions(drop); + if (formats == 0) return false; + + // get allowed operations + int style = getStyle(); + int operations = osOpToOp(actions) & style; + if (operations == DND.DROP_NONE) return false; + + // get current operation + int operation = getOperationFromKeyState(); + keyOperation = operation; + if (operation == DND.DROP_DEFAULT) { + if ((style & DND.DROP_DEFAULT) == 0) { + operation = (operations & DND.DROP_MOVE) != 0 ? DND.DROP_MOVE : DND.DROP_NONE; + } + } else { + if ((operation & operations) == 0) operation = DND.DROP_NONE; + } + + // Get allowed transfer types + TransferData[] dataTypes = new TransferData[0]; + for (Transfer transfer : transferAgents) { + if (transfer == null) continue; + long gtype = ContentProviders.getInstance().getGType(transfer); + if (gtype == 0 || !GTK4.gdk_content_formats_contain_gtype(formats, gtype)) continue; + TransferData[] supported = transfer.getSupportedTypes(); + TransferData[] newDataTypes = new TransferData[dataTypes.length + supported.length]; + System.arraycopy(dataTypes, 0, newDataTypes, 0, dataTypes.length); + System.arraycopy(supported, 0, newDataTypes, dataTypes.length, supported.length); + dataTypes = newDataTypes; + } + if (dataTypes.length == 0) return false; + + // x and y are relative to the widget; translate to display coordinates + Point coordinates = control.toDisplay((int) x, (int) y); + + event.widget = this; + event.x = coordinates.x; + event.y = coordinates.y; + event.time = (int) System.currentTimeMillis(); + event.feedback = DND.FEEDBACK_SELECT; + event.dataTypes = dataTypes; + event.dataType = dataTypes[0]; + event.operations = operations; + event.detail = operation; + if (dropEffect != null) { + event.item = dropEffect.getItem(coordinates.x, coordinates.y); + } + return true; +} } diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c index d290dcf83fb..0d22afe9502 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c @@ -359,6 +359,18 @@ JNIEXPORT jlong JNICALL GTK4_NATIVE(gdk_1content_1formats_1builder_1new) } #endif +#ifndef NO_gdk_1content_1formats_1contain_1gtype +JNIEXPORT jboolean JNICALL GTK4_NATIVE(gdk_1content_1formats_1contain_1gtype) + (JNIEnv *env, jclass that, jlong arg0, jlong arg1) +{ + jboolean rc = 0; + GTK4_NATIVE_ENTER(env, that, gdk_1content_1formats_1contain_1gtype_FUNC); + rc = (jboolean)gdk_content_formats_contain_gtype((GdkContentFormats *)arg0, (GType)arg1); + GTK4_NATIVE_EXIT(env, that, gdk_1content_1formats_1contain_1gtype_FUNC); + return rc; +} +#endif + #ifndef NO_gdk_1content_1formats_1get_1gtypes JNIEXPORT jlong JNICALL GTK4_NATIVE(gdk_1content_1formats_1get_1gtypes) (JNIEnv *env, jclass that, jlong arg0, jlongArray arg1) @@ -613,6 +625,66 @@ JNIEXPORT void JNICALL GTK4_NATIVE(gdk_1content_1serializer_1set_1task_1data) } #endif +#ifndef NO_gdk_1drop_1finish +JNIEXPORT void JNICALL GTK4_NATIVE(gdk_1drop_1finish) + (JNIEnv *env, jclass that, jlong arg0, jint arg1) +{ + GTK4_NATIVE_ENTER(env, that, gdk_1drop_1finish_FUNC); + gdk_drop_finish((GdkDrop *)arg0, (GdkDragAction)arg1); + GTK4_NATIVE_EXIT(env, that, gdk_1drop_1finish_FUNC); +} +#endif + +#ifndef NO_gdk_1drop_1get_1actions +JNIEXPORT jint JNICALL GTK4_NATIVE(gdk_1drop_1get_1actions) + (JNIEnv *env, jclass that, jlong arg0) +{ + jint rc = 0; + GTK4_NATIVE_ENTER(env, that, gdk_1drop_1get_1actions_FUNC); + rc = (jint)gdk_drop_get_actions((GdkDrop *)arg0); + GTK4_NATIVE_EXIT(env, that, gdk_1drop_1get_1actions_FUNC); + return rc; +} +#endif + +#ifndef NO_gdk_1drop_1get_1formats +JNIEXPORT jlong JNICALL GTK4_NATIVE(gdk_1drop_1get_1formats) + (JNIEnv *env, jclass that, jlong arg0) +{ + jlong rc = 0; + GTK4_NATIVE_ENTER(env, that, gdk_1drop_1get_1formats_FUNC); + rc = (jlong)gdk_drop_get_formats((GdkDrop *)arg0); + GTK4_NATIVE_EXIT(env, that, gdk_1drop_1get_1formats_FUNC); + return rc; +} +#endif + +#ifndef NO_gdk_1drop_1read_1value_1async +JNIEXPORT void JNICALL GTK4_NATIVE(gdk_1drop_1read_1value_1async) + (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jint arg2, jlong arg3, jlong arg4, jlong arg5) +{ + GTK4_NATIVE_ENTER(env, that, gdk_1drop_1read_1value_1async_FUNC); + gdk_drop_read_value_async((GdkDrop *)arg0, (GType)arg1, arg2, (GCancellable *)arg3, (GAsyncReadyCallback)arg4, (gpointer)arg5); + GTK4_NATIVE_EXIT(env, that, gdk_1drop_1read_1value_1async_FUNC); +} +#endif + +#ifndef NO_gdk_1drop_1read_1value_1finish +JNIEXPORT jlong JNICALL GTK4_NATIVE(gdk_1drop_1read_1value_1finish) + (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlongArray arg2) +{ + jlong *lparg2=NULL; + jlong rc = 0; + GTK4_NATIVE_ENTER(env, that, gdk_1drop_1read_1value_1finish_FUNC); + if (arg2) if ((lparg2 = (*env)->GetLongArrayElements(env, arg2, NULL)) == NULL) goto fail; + rc = (jlong)gdk_drop_read_value_finish((GdkDrop *)arg0, (GAsyncResult *)arg1, (GError **)lparg2); +fail: + if (arg2 && lparg2) (*env)->ReleaseLongArrayElements(env, arg2, lparg2, 0); + GTK4_NATIVE_EXIT(env, that, gdk_1drop_1read_1value_1finish_FUNC); + return rc; +} +#endif + #ifndef NO_gdk_1paintable_1snapshot JNIEXPORT void JNICALL GTK4_NATIVE(gdk_1paintable_1snapshot) (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jint arg2, jint arg3) @@ -2841,6 +2913,16 @@ JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1widget_1pick) } #endif +#ifndef NO_gtk_1widget_1remove_1controller +JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1widget_1remove_1controller) + (JNIEnv *env, jclass that, jlong arg0, jlong arg1) +{ + GTK4_NATIVE_ENTER(env, that, gtk_1widget_1remove_1controller_FUNC); + gtk_widget_remove_controller((GtkWidget *)arg0, (GtkEventController *)arg1); + GTK4_NATIVE_EXIT(env, that, gtk_1widget_1remove_1controller_FUNC); +} +#endif + #ifndef NO_gtk_1widget_1set_1cursor JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1widget_1set_1cursor) (JNIEnv *env, jclass that, jlong arg0, jlong arg1) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h index 15d43724ca5..6766ff954b9 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h @@ -47,6 +47,7 @@ typedef enum { gdk_1content_1formats_1builder_1add_1mime_1type_FUNC, gdk_1content_1formats_1builder_1free_1to_1formats_FUNC, gdk_1content_1formats_1builder_1new_FUNC, + gdk_1content_1formats_1contain_1gtype_FUNC, gdk_1content_1formats_1get_1gtypes_FUNC, gdk_1content_1formats_1get_1mime_1types_FUNC, gdk_1content_1formats_1to_1string_FUNC, @@ -67,6 +68,11 @@ typedef enum { gdk_1content_1serializer_1return_1error_FUNC, gdk_1content_1serializer_1return_1success_FUNC, gdk_1content_1serializer_1set_1task_1data_FUNC, + gdk_1drop_1finish_FUNC, + gdk_1drop_1get_1actions_FUNC, + gdk_1drop_1get_1formats_FUNC, + gdk_1drop_1read_1value_1async_FUNC, + gdk_1drop_1read_1value_1finish_FUNC, gdk_1paintable_1snapshot_FUNC, gdk_1toplevel_1focus_FUNC, gdk_1toplevel_1get_1state_FUNC, @@ -231,6 +237,7 @@ typedef enum { gtk_1widget_1measure_FUNC, gtk_1widget_1paintable_1new_FUNC, gtk_1widget_1pick_FUNC, + gtk_1widget_1remove_1controller_FUNC, gtk_1widget_1set_1cursor_FUNC, gtk_1widget_1set_1focusable_FUNC, gtk_1widget_1set_1overflow_FUNC, diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java index 59edf503279..aa70f5a3f23 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java @@ -383,14 +383,17 @@ public static String getEnvironmentalVariable (String envVarName) { public static final byte[] delete_text = ascii("delete-text"); public static final byte[] direction_changed = ascii("direction-changed"); public static final byte[] dpi_changed = ascii("notify::scale-factor"); + public static final byte[] accept = ascii("accept"); public static final byte[] drag_begin = ascii("drag-begin"); public static final byte[] drag_data_delete = ascii("drag-data-delete"); public static final byte[] drag_data_get = ascii("drag-data-get"); public static final byte[] drag_data_received = ascii("drag-data-received"); public static final byte[] drag_drop = ascii("drag-drop"); public static final byte[] drag_end = ascii("drag-end"); + public static final byte[] drag_enter = ascii("drag-enter"); public static final byte[] drag_leave = ascii("drag-leave"); public static final byte[] drag_motion = ascii("drag-motion"); + public static final byte[] drop = ascii("drop"); public static final byte[] prepare = ascii("prepare"); public static final byte[] draw = ascii("draw"); public static final byte[] end = ascii("end"); diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java index df933e27183..ba03262b095 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java @@ -228,6 +228,36 @@ public class GTK4 { public static final native void gdk_content_formats_builder_add_mime_type(long builder, byte[] mime_type); /** @param builder cast=(GdkContentFormatsBuilder *) */ public static final native long gdk_content_formats_builder_free_to_formats(long builder); + /** + * @param formats cast=(GdkContentFormats *) + * @param type cast=(GType) + */ + public static final native boolean gdk_content_formats_contain_gtype(long formats, long type); + + /* GdkDrop */ + /** + * @param drop cast=(GdkDrop *) + * @param action cast=(GdkDragAction) + */ + public static final native void gdk_drop_finish(long drop, int action); + /** @param drop cast=(GdkDrop *) */ + public static final native int gdk_drop_get_actions(long drop); + /** @param drop cast=(GdkDrop *) */ + public static final native long gdk_drop_get_formats(long drop); + /** + * @param drop cast=(GdkDrop *) + * @param type cast=(GType) + * @param cancellable cast=(GCancellable *) + * @param callback cast=(GAsyncReadyCallback) + * @param user_data cast=(gpointer) + */ + public static final native void gdk_drop_read_value_async(long drop, long type, int io_priority, long cancellable, long callback, long user_data); + /** + * @param drop cast=(GdkDrop *) + * @param result cast=(GAsyncResult *) + * @param error cast=(GError **) + */ + public static final native long gdk_drop_read_value_finish(long drop, long result, long[] error); /* GtkFileChooser */ /** @@ -705,6 +735,11 @@ public class GTK4 { * @param controller cast=(GtkEventController *) */ public static final native void gtk_widget_add_controller(long widget, long controller); + /** + * @param widget cast=(GtkWidget *) + * @param controller cast=(GtkEventController *) + */ + public static final native void gtk_widget_remove_controller(long widget, long controller); /** @param widget cast=(GtkWidget *) */ public static final native long gtk_widget_get_first_child(long widget); /** @param widget cast=(GtkWidget *) */ From fba7f072dbf785c0bce7fb5985af860d9181930b Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Mon, 6 Jul 2026 07:31:54 +0000 Subject: [PATCH 02/46] v4974r8 --- ...-awt-cocoa-4974r7.jnilib => libswt-awt-cocoa-4974r8.jnilib} | 0 .../{libswt-cocoa-4974r7.jnilib => libswt-cocoa-4974r8.jnilib} | 0 ...wt-pi-cocoa-4974r7.jnilib => libswt-pi-cocoa-4974r8.jnilib} | 0 ...-awt-cocoa-4974r7.jnilib => libswt-awt-cocoa-4974r8.jnilib} | 0 .../{libswt-cocoa-4974r7.jnilib => libswt-cocoa-4974r8.jnilib} | 0 ...wt-pi-cocoa-4974r7.jnilib => libswt-pi-cocoa-4974r8.jnilib} | 0 .../{libswt-atk-gtk-4974r7.so => libswt-atk-gtk-4974r8.so} | 0 .../{libswt-awt-gtk-4974r7.so => libswt-awt-gtk-4974r8.so} | 0 .../{libswt-cairo-gtk-4974r7.so => libswt-cairo-gtk-4974r8.so} | 0 .../{libswt-glx-gtk-4974r7.so => libswt-glx-gtk-4974r8.so} | 0 .../{libswt-gtk-4974r7.so => libswt-gtk-4974r8.so} | 0 .../{libswt-pi3-gtk-4974r7.so => libswt-pi3-gtk-4974r8.so} | 0 ...libswt-webkit-gtk-4974r7.so => libswt-webkit-gtk-4974r8.so} | 0 .../{libswt-atk-gtk-4974r7.so => libswt-atk-gtk-4974r8.so} | 0 .../{libswt-awt-gtk-4974r7.so => libswt-awt-gtk-4974r8.so} | 0 .../{libswt-cairo-gtk-4974r7.so => libswt-cairo-gtk-4974r8.so} | 0 .../{libswt-glx-gtk-4974r7.so => libswt-glx-gtk-4974r8.so} | 0 .../{libswt-gtk-4974r7.so => libswt-gtk-4974r8.so} | 0 .../{libswt-pi3-gtk-4974r7.so => libswt-pi3-gtk-4974r8.so} | 0 ...libswt-webkit-gtk-4974r7.so => libswt-webkit-gtk-4974r8.so} | 0 .../{libswt-atk-gtk-4974r7.so => libswt-atk-gtk-4974r8.so} | 0 .../{libswt-awt-gtk-4974r7.so => libswt-awt-gtk-4974r8.so} | 0 .../{libswt-cairo-gtk-4974r7.so => libswt-cairo-gtk-4974r8.so} | 0 .../{libswt-glx-gtk-4974r7.so => libswt-glx-gtk-4974r8.so} | 0 .../{libswt-gtk-4974r7.so => libswt-gtk-4974r8.so} | 0 .../{libswt-pi3-gtk-4974r7.so => libswt-pi3-gtk-4974r8.so} | 0 ...libswt-webkit-gtk-4974r7.so => libswt-webkit-gtk-4974r8.so} | 0 .../{libswt-atk-gtk-4974r7.so => libswt-atk-gtk-4974r8.so} | 0 .../{libswt-awt-gtk-4974r7.so => libswt-awt-gtk-4974r8.so} | 0 .../{libswt-cairo-gtk-4974r7.so => libswt-cairo-gtk-4974r8.so} | 0 .../{libswt-glx-gtk-4974r7.so => libswt-glx-gtk-4974r8.so} | 0 .../{libswt-gtk-4974r7.so => libswt-gtk-4974r8.so} | 0 .../{libswt-pi3-gtk-4974r7.so => libswt-pi3-gtk-4974r8.so} | 0 .../org.eclipse.swt.gtk.linux.x86_64/libswt-pi4-gtk-4974r7.so | 3 --- .../org.eclipse.swt.gtk.linux.x86_64/libswt-pi4-gtk-4974r8.so | 3 +++ ...libswt-webkit-gtk-4974r7.so => libswt-webkit-gtk-4974r8.so} | 0 .../{swt-awt-win32-4974r7.dll => swt-awt-win32-4974r8.dll} | 0 .../{swt-gdip-win32-4974r7.dll => swt-gdip-win32-4974r8.dll} | 0 ...version-win32-4974r7.dll => swt-osversion-win32-4974r8.dll} | 0 .../{swt-wgl-win32-4974r7.dll => swt-wgl-win32-4974r8.dll} | 0 .../{swt-win32-4974r7.dll => swt-win32-4974r8.dll} | 0 .../{swt-awt-win32-4974r7.dll => swt-awt-win32-4974r8.dll} | 0 .../{swt-gdip-win32-4974r7.dll => swt-gdip-win32-4974r8.dll} | 0 ...version-win32-4974r7.dll => swt-osversion-win32-4974r8.dll} | 0 .../{swt-wgl-win32-4974r7.dll => swt-wgl-win32-4974r8.dll} | 0 .../{swt-win32-4974r7.dll => swt-win32-4974r8.dll} | 0 .../common/org/eclipse/swt/internal/Library.java | 2 +- .../org.eclipse.swt/Eclipse SWT/common/library/make_common.mak | 2 +- 48 files changed, 5 insertions(+), 5 deletions(-) rename binaries/org.eclipse.swt.cocoa.macosx.aarch64/{libswt-awt-cocoa-4974r7.jnilib => libswt-awt-cocoa-4974r8.jnilib} (100%) rename binaries/org.eclipse.swt.cocoa.macosx.aarch64/{libswt-cocoa-4974r7.jnilib => libswt-cocoa-4974r8.jnilib} (100%) rename binaries/org.eclipse.swt.cocoa.macosx.aarch64/{libswt-pi-cocoa-4974r7.jnilib => libswt-pi-cocoa-4974r8.jnilib} (100%) rename binaries/org.eclipse.swt.cocoa.macosx.x86_64/{libswt-awt-cocoa-4974r7.jnilib => libswt-awt-cocoa-4974r8.jnilib} (100%) rename binaries/org.eclipse.swt.cocoa.macosx.x86_64/{libswt-cocoa-4974r7.jnilib => libswt-cocoa-4974r8.jnilib} (100%) rename binaries/org.eclipse.swt.cocoa.macosx.x86_64/{libswt-pi-cocoa-4974r7.jnilib => libswt-pi-cocoa-4974r8.jnilib} (100%) rename binaries/org.eclipse.swt.gtk.linux.aarch64/{libswt-atk-gtk-4974r7.so => libswt-atk-gtk-4974r8.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.aarch64/{libswt-awt-gtk-4974r7.so => libswt-awt-gtk-4974r8.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.aarch64/{libswt-cairo-gtk-4974r7.so => libswt-cairo-gtk-4974r8.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.aarch64/{libswt-glx-gtk-4974r7.so => libswt-glx-gtk-4974r8.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.aarch64/{libswt-gtk-4974r7.so => libswt-gtk-4974r8.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.aarch64/{libswt-pi3-gtk-4974r7.so => libswt-pi3-gtk-4974r8.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.aarch64/{libswt-webkit-gtk-4974r7.so => libswt-webkit-gtk-4974r8.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.ppc64le/{libswt-atk-gtk-4974r7.so => libswt-atk-gtk-4974r8.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.ppc64le/{libswt-awt-gtk-4974r7.so => libswt-awt-gtk-4974r8.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.ppc64le/{libswt-cairo-gtk-4974r7.so => libswt-cairo-gtk-4974r8.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.ppc64le/{libswt-glx-gtk-4974r7.so => libswt-glx-gtk-4974r8.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.ppc64le/{libswt-gtk-4974r7.so => libswt-gtk-4974r8.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.ppc64le/{libswt-pi3-gtk-4974r7.so => libswt-pi3-gtk-4974r8.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.ppc64le/{libswt-webkit-gtk-4974r7.so => libswt-webkit-gtk-4974r8.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.riscv64/{libswt-atk-gtk-4974r7.so => libswt-atk-gtk-4974r8.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.riscv64/{libswt-awt-gtk-4974r7.so => libswt-awt-gtk-4974r8.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.riscv64/{libswt-cairo-gtk-4974r7.so => libswt-cairo-gtk-4974r8.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.riscv64/{libswt-glx-gtk-4974r7.so => libswt-glx-gtk-4974r8.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.riscv64/{libswt-gtk-4974r7.so => libswt-gtk-4974r8.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.riscv64/{libswt-pi3-gtk-4974r7.so => libswt-pi3-gtk-4974r8.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.riscv64/{libswt-webkit-gtk-4974r7.so => libswt-webkit-gtk-4974r8.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.x86_64/{libswt-atk-gtk-4974r7.so => libswt-atk-gtk-4974r8.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.x86_64/{libswt-awt-gtk-4974r7.so => libswt-awt-gtk-4974r8.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.x86_64/{libswt-cairo-gtk-4974r7.so => libswt-cairo-gtk-4974r8.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.x86_64/{libswt-glx-gtk-4974r7.so => libswt-glx-gtk-4974r8.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.x86_64/{libswt-gtk-4974r7.so => libswt-gtk-4974r8.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.x86_64/{libswt-pi3-gtk-4974r7.so => libswt-pi3-gtk-4974r8.so} (100%) delete mode 100755 binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi4-gtk-4974r7.so create mode 100755 binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi4-gtk-4974r8.so rename binaries/org.eclipse.swt.gtk.linux.x86_64/{libswt-webkit-gtk-4974r7.so => libswt-webkit-gtk-4974r8.so} (100%) rename binaries/org.eclipse.swt.win32.win32.aarch64/{swt-awt-win32-4974r7.dll => swt-awt-win32-4974r8.dll} (100%) rename binaries/org.eclipse.swt.win32.win32.aarch64/{swt-gdip-win32-4974r7.dll => swt-gdip-win32-4974r8.dll} (100%) rename binaries/org.eclipse.swt.win32.win32.aarch64/{swt-osversion-win32-4974r7.dll => swt-osversion-win32-4974r8.dll} (100%) rename binaries/org.eclipse.swt.win32.win32.aarch64/{swt-wgl-win32-4974r7.dll => swt-wgl-win32-4974r8.dll} (100%) rename binaries/org.eclipse.swt.win32.win32.aarch64/{swt-win32-4974r7.dll => swt-win32-4974r8.dll} (100%) rename binaries/org.eclipse.swt.win32.win32.x86_64/{swt-awt-win32-4974r7.dll => swt-awt-win32-4974r8.dll} (100%) rename binaries/org.eclipse.swt.win32.win32.x86_64/{swt-gdip-win32-4974r7.dll => swt-gdip-win32-4974r8.dll} (100%) rename binaries/org.eclipse.swt.win32.win32.x86_64/{swt-osversion-win32-4974r7.dll => swt-osversion-win32-4974r8.dll} (100%) rename binaries/org.eclipse.swt.win32.win32.x86_64/{swt-wgl-win32-4974r7.dll => swt-wgl-win32-4974r8.dll} (100%) rename binaries/org.eclipse.swt.win32.win32.x86_64/{swt-win32-4974r7.dll => swt-win32-4974r8.dll} (100%) diff --git a/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-awt-cocoa-4974r7.jnilib b/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-awt-cocoa-4974r8.jnilib similarity index 100% rename from binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-awt-cocoa-4974r7.jnilib rename to binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-awt-cocoa-4974r8.jnilib diff --git a/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-cocoa-4974r7.jnilib b/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-cocoa-4974r8.jnilib similarity index 100% rename from binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-cocoa-4974r7.jnilib rename to binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-cocoa-4974r8.jnilib diff --git a/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-pi-cocoa-4974r7.jnilib b/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-pi-cocoa-4974r8.jnilib similarity index 100% rename from binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-pi-cocoa-4974r7.jnilib rename to binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-pi-cocoa-4974r8.jnilib diff --git a/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-awt-cocoa-4974r7.jnilib b/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-awt-cocoa-4974r8.jnilib similarity index 100% rename from binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-awt-cocoa-4974r7.jnilib rename to binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-awt-cocoa-4974r8.jnilib diff --git a/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-cocoa-4974r7.jnilib b/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-cocoa-4974r8.jnilib similarity index 100% rename from binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-cocoa-4974r7.jnilib rename to binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-cocoa-4974r8.jnilib diff --git a/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-pi-cocoa-4974r7.jnilib b/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-pi-cocoa-4974r8.jnilib similarity index 100% rename from binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-pi-cocoa-4974r7.jnilib rename to binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-pi-cocoa-4974r8.jnilib diff --git a/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-atk-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-atk-gtk-4974r8.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-atk-gtk-4974r7.so rename to binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-atk-gtk-4974r8.so diff --git a/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-awt-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-awt-gtk-4974r8.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-awt-gtk-4974r7.so rename to binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-awt-gtk-4974r8.so diff --git a/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-cairo-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-cairo-gtk-4974r8.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-cairo-gtk-4974r7.so rename to binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-cairo-gtk-4974r8.so diff --git a/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-glx-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-glx-gtk-4974r8.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-glx-gtk-4974r7.so rename to binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-glx-gtk-4974r8.so diff --git a/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-gtk-4974r8.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-gtk-4974r7.so rename to binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-gtk-4974r8.so diff --git a/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-pi3-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-pi3-gtk-4974r8.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-pi3-gtk-4974r7.so rename to binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-pi3-gtk-4974r8.so diff --git a/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-webkit-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-webkit-gtk-4974r8.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-webkit-gtk-4974r7.so rename to binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-webkit-gtk-4974r8.so diff --git a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-atk-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-atk-gtk-4974r8.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-atk-gtk-4974r7.so rename to binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-atk-gtk-4974r8.so diff --git a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-awt-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-awt-gtk-4974r8.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-awt-gtk-4974r7.so rename to binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-awt-gtk-4974r8.so diff --git a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-cairo-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-cairo-gtk-4974r8.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-cairo-gtk-4974r7.so rename to binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-cairo-gtk-4974r8.so diff --git a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-glx-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-glx-gtk-4974r8.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-glx-gtk-4974r7.so rename to binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-glx-gtk-4974r8.so diff --git a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-gtk-4974r8.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-gtk-4974r7.so rename to binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-gtk-4974r8.so diff --git a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-pi3-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-pi3-gtk-4974r8.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-pi3-gtk-4974r7.so rename to binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-pi3-gtk-4974r8.so diff --git a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-webkit-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-webkit-gtk-4974r8.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-webkit-gtk-4974r7.so rename to binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-webkit-gtk-4974r8.so diff --git a/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-atk-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-atk-gtk-4974r8.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-atk-gtk-4974r7.so rename to binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-atk-gtk-4974r8.so diff --git a/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-awt-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-awt-gtk-4974r8.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-awt-gtk-4974r7.so rename to binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-awt-gtk-4974r8.so diff --git a/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-cairo-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-cairo-gtk-4974r8.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-cairo-gtk-4974r7.so rename to binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-cairo-gtk-4974r8.so diff --git a/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-glx-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-glx-gtk-4974r8.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-glx-gtk-4974r7.so rename to binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-glx-gtk-4974r8.so diff --git a/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-gtk-4974r8.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-gtk-4974r7.so rename to binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-gtk-4974r8.so diff --git a/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-pi3-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-pi3-gtk-4974r8.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-pi3-gtk-4974r7.so rename to binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-pi3-gtk-4974r8.so diff --git a/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-webkit-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-webkit-gtk-4974r8.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-webkit-gtk-4974r7.so rename to binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-webkit-gtk-4974r8.so diff --git a/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-atk-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-atk-gtk-4974r8.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-atk-gtk-4974r7.so rename to binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-atk-gtk-4974r8.so diff --git a/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-awt-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-awt-gtk-4974r8.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-awt-gtk-4974r7.so rename to binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-awt-gtk-4974r8.so diff --git a/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-cairo-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-cairo-gtk-4974r8.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-cairo-gtk-4974r7.so rename to binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-cairo-gtk-4974r8.so diff --git a/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-glx-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-glx-gtk-4974r8.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-glx-gtk-4974r7.so rename to binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-glx-gtk-4974r8.so diff --git a/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-gtk-4974r8.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-gtk-4974r7.so rename to binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-gtk-4974r8.so diff --git a/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi3-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi3-gtk-4974r8.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi3-gtk-4974r7.so rename to binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi3-gtk-4974r8.so diff --git a/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi4-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi4-gtk-4974r7.so deleted file mode 100755 index efb339e2204..00000000000 --- a/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi4-gtk-4974r7.so +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cc32e044c9eb741659bcf8213e1850ee201fe834aaf14edcdbdb2f8d42f9a757 -size 425088 diff --git a/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi4-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi4-gtk-4974r8.so new file mode 100755 index 00000000000..7043960fb4f --- /dev/null +++ b/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi4-gtk-4974r8.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9aefa710ccab79a8e1a85838c9dfe3b451d9fb257cf93bf11aa05bbc42bbad7c +size 425144 diff --git a/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-webkit-gtk-4974r7.so b/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-webkit-gtk-4974r8.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-webkit-gtk-4974r7.so rename to binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-webkit-gtk-4974r8.so diff --git a/binaries/org.eclipse.swt.win32.win32.aarch64/swt-awt-win32-4974r7.dll b/binaries/org.eclipse.swt.win32.win32.aarch64/swt-awt-win32-4974r8.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.aarch64/swt-awt-win32-4974r7.dll rename to binaries/org.eclipse.swt.win32.win32.aarch64/swt-awt-win32-4974r8.dll diff --git a/binaries/org.eclipse.swt.win32.win32.aarch64/swt-gdip-win32-4974r7.dll b/binaries/org.eclipse.swt.win32.win32.aarch64/swt-gdip-win32-4974r8.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.aarch64/swt-gdip-win32-4974r7.dll rename to binaries/org.eclipse.swt.win32.win32.aarch64/swt-gdip-win32-4974r8.dll diff --git a/binaries/org.eclipse.swt.win32.win32.aarch64/swt-osversion-win32-4974r7.dll b/binaries/org.eclipse.swt.win32.win32.aarch64/swt-osversion-win32-4974r8.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.aarch64/swt-osversion-win32-4974r7.dll rename to binaries/org.eclipse.swt.win32.win32.aarch64/swt-osversion-win32-4974r8.dll diff --git a/binaries/org.eclipse.swt.win32.win32.aarch64/swt-wgl-win32-4974r7.dll b/binaries/org.eclipse.swt.win32.win32.aarch64/swt-wgl-win32-4974r8.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.aarch64/swt-wgl-win32-4974r7.dll rename to binaries/org.eclipse.swt.win32.win32.aarch64/swt-wgl-win32-4974r8.dll diff --git a/binaries/org.eclipse.swt.win32.win32.aarch64/swt-win32-4974r7.dll b/binaries/org.eclipse.swt.win32.win32.aarch64/swt-win32-4974r8.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.aarch64/swt-win32-4974r7.dll rename to binaries/org.eclipse.swt.win32.win32.aarch64/swt-win32-4974r8.dll diff --git a/binaries/org.eclipse.swt.win32.win32.x86_64/swt-awt-win32-4974r7.dll b/binaries/org.eclipse.swt.win32.win32.x86_64/swt-awt-win32-4974r8.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.x86_64/swt-awt-win32-4974r7.dll rename to binaries/org.eclipse.swt.win32.win32.x86_64/swt-awt-win32-4974r8.dll diff --git a/binaries/org.eclipse.swt.win32.win32.x86_64/swt-gdip-win32-4974r7.dll b/binaries/org.eclipse.swt.win32.win32.x86_64/swt-gdip-win32-4974r8.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.x86_64/swt-gdip-win32-4974r7.dll rename to binaries/org.eclipse.swt.win32.win32.x86_64/swt-gdip-win32-4974r8.dll diff --git a/binaries/org.eclipse.swt.win32.win32.x86_64/swt-osversion-win32-4974r7.dll b/binaries/org.eclipse.swt.win32.win32.x86_64/swt-osversion-win32-4974r8.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.x86_64/swt-osversion-win32-4974r7.dll rename to binaries/org.eclipse.swt.win32.win32.x86_64/swt-osversion-win32-4974r8.dll diff --git a/binaries/org.eclipse.swt.win32.win32.x86_64/swt-wgl-win32-4974r7.dll b/binaries/org.eclipse.swt.win32.win32.x86_64/swt-wgl-win32-4974r8.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.x86_64/swt-wgl-win32-4974r7.dll rename to binaries/org.eclipse.swt.win32.win32.x86_64/swt-wgl-win32-4974r8.dll diff --git a/binaries/org.eclipse.swt.win32.win32.x86_64/swt-win32-4974r7.dll b/binaries/org.eclipse.swt.win32.win32.x86_64/swt-win32-4974r8.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.x86_64/swt-win32-4974r7.dll rename to binaries/org.eclipse.swt.win32.win32.x86_64/swt-win32-4974r8.dll diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/common/org/eclipse/swt/internal/Library.java b/bundles/org.eclipse.swt/Eclipse SWT PI/common/org/eclipse/swt/internal/Library.java index 62927e205b4..cb6dab44c27 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/common/org/eclipse/swt/internal/Library.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/common/org/eclipse/swt/internal/Library.java @@ -35,7 +35,7 @@ public class Library { /** * SWT revision number (must be >= 0) */ - static int REVISION = 7; + static int REVISION = 8; /** * The JAVA and SWT versions diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/library/make_common.mak b/bundles/org.eclipse.swt/Eclipse SWT/common/library/make_common.mak index d66419e442d..5cc4d808bbf 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/library/make_common.mak +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/library/make_common.mak @@ -14,4 +14,4 @@ maj_ver=4 min_ver=974 -rev=7 +rev=8 From 6d81b3095f1fa46bee10feb92b6ef5f9b679c3b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=8A?= =?UTF-8?q?=D1=80=20=D0=9A=D1=83=D1=80=D1=82=D0=B0=D0=BA=D0=BE=D0=B2?= Date: Tue, 7 Jul 2026 17:42:24 +0300 Subject: [PATCH 03/46] [Gtk4] Fix displaying file permissions On GTK4 widgets have no per-widget GdkWindow, so paint order is simply the parent's child-list order (first = bottom, last = top) thus the Gtk3 hack calling moveAbove from moveBelow is not needed. --- .../gtk/org/eclipse/swt/widgets/Composite.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java index e6b18fbacfb..c70707366f6 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java @@ -1409,7 +1409,17 @@ void moveAbove (long child, long sibling) { void moveBelow (long child, long sibling) { if (child == sibling) return; long parentHandle = parentingHandle (); - if (sibling == 0 && parentHandle == fixedHandle) { + /* + * GTK3-only: when sibling == 0 (move to the bottom of the z-order) the + * child would be stacked behind the scrolled content's GdkWindow, hiding + * overlay controls such as Table/Tree editors. Re-place it just above the + * scrolled content instead. + * + * Not needed on GTK4: widgets have no per-widget GdkWindow, so paint order + * is simply the parent's child-list order (first = bottom, last = top), and + * the general branch below already appends the child to the end (top). + */ + if (!GTK.GTK4 && sibling == 0 && parentHandle == fixedHandle) { moveAbove (child, scrolledHandle != 0 ? scrolledHandle : handle); return; } From 535a57194e8a892bd9053845ac09a78fbea0792a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=8A?= =?UTF-8?q?=D1=80=20=D0=9A=D1=83=D1=80=D1=82=D0=B0=D0=BA=D0=BE=D0=B2?= Date: Tue, 7 Jul 2026 22:55:20 +0300 Subject: [PATCH 04/46] [Gtk4] Support right click on ToolItem Register the click controller to listen for all buttons and hook showMenu to rightClick. --- .../gtk/org/eclipse/swt/widgets/ToolItem.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolItem.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolItem.java index d02f04f91f5..a9cafd3febf 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolItem.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolItem.java @@ -910,6 +910,22 @@ int gtk_gesture_press_event(long gesture, int n_press, double x, double y, long sendSelectionEvent(SWT.Selection, e, false); return GTK4.GTK_EVENT_SEQUENCE_CLAIMED; } + /* + * GTK4: Handle right-click (button 3) to fire SWT.MenuDetect on the parent + * ToolBar, replicating the GTK3 gtk3_event_after behavior. The gesture + * coordinates are item-local; translate them to the ToolBar's coordinate + * space and then to screen coordinates before calling parent.showMenu(). + */ + if (n_press == 1 && GTK.gtk_gesture_single_get_current_button(gesture) == 3) { + double[] destX = new double[1]; + double[] destY = new double[1]; + boolean translated = GTK4.gtk_widget_translate_coordinates(handle, parent.handle, x, y, destX, destY); + int barX = translated ? (int) destX[0] : (int) x; + int barY = translated ? (int) destY[0] : (int) y; + Point screenPt = parent.toDisplay(barX, barY); + parent.showMenu(screenPt.x, screenPt.y); + return GTK4.GTK_EVENT_SEQUENCE_CLAIMED; + } return GTK4.GTK_EVENT_SEQUENCE_NONE; } @@ -949,8 +965,8 @@ void hookEvents () { OS.g_signal_connect(motionController, OS.enter, display.enterMotionProc, ENTER); OS.g_signal_connect(motionController, OS.leave, display.leaveProc, LEAVE); - //TODO: event-after long clickController = GTK4.gtk_gesture_click_new(); + GTK.gtk_gesture_single_set_button(clickController, 0); GTK4.gtk_widget_add_controller(handle, clickController); OS.g_signal_connect(clickController, OS.pressed, display.gesturePressReleaseProc, GESTURE_PRESSED); } else { From 94de5a636b7e425b6dcbf687efc09d9242b6ad00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=8A?= =?UTF-8?q?=D1=80=20=D0=9A=D1=83=D1=80=D1=82=D0=B0=D0=BA=D0=BE=D0=B2?= Date: Tue, 7 Jul 2026 23:31:24 +0300 Subject: [PATCH 05/46] [Gtk4] Support MenuItem with SWT.CHECK click Connect activate for checkbox menues too --- .../Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java index c8f90aac219..e98a8b02291 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2023 IBM Corporation and others. + * Copyright (c) 2000, 2026 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -653,6 +653,10 @@ long gtk_activate (long widget) { } } + if (GTK.GTK4 && (style & SWT.CHECK) != 0) { + OS.g_simple_action_set_state(actionHandle, OS.g_variant_new_boolean(!getSelection())); + } + sendSelectionEvent (SWT.Selection); return 0; } @@ -684,7 +688,7 @@ void hookEvents() { super.hookEvents(); if (GTK.GTK4) { - if ((style & SWT.PUSH) != 0 || (style & SWT.RADIO) != 0) { + if ((style & SWT.PUSH) != 0 || (style & SWT.RADIO) != 0 || (style & SWT.CHECK) != 0) { OS.g_signal_connect(actionHandle, OS.activate, display.activateProc, handle); } } else { From 28ddc853f58a860d8c954e006e180bb96b52ec5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=8A?= =?UTF-8?q?=D1=80=20=D0=9A=D1=83=D1=80=D1=82=D0=B0=D0=BA=D0=BE=D0=B2?= Date: Wed, 8 Jul 2026 11:14:36 +0300 Subject: [PATCH 06/46] [Gtk4] Fix lazily populated menus being empty MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first attempt to wire submenu  SHOW/HIDE  listeners happens too early, at bar map time. On GTK4 those nested  GtkPopoverMenu  children may not be fully reachable yet, so Eclipse never receives  SWT.Show  for the cascade submenu and never runs  menuAboutToShow() . The retry in  gtk_show()  runs after the parent dropdown is actually shown, when GTK has built the widget tree, so the nested submenu popovers can be found and connected --- .../Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java index 8f5c2159541..3dc45318bb9 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java @@ -983,6 +983,10 @@ long gtk_show (long widget) { return 0; } sendEvent (SWT.Show); + /* Retry cascade submenu signal hookup once the DROP_DOWN popover is shown. */ + if (GTK.GTK4 && (style & SWT.DROP_DOWN) != 0 && popoverHandle != 0) { + connectCascadeSubMenuSignals(this, popoverHandle); + } if (OS.ubuntu_menu_proxy_get() != 0) { MenuItem[] items = getItems(); for (int i=0; i Date: Mon, 13 Jul 2026 15:56:48 +0300 Subject: [PATCH 07/46] Fix GTK accessibility relation cleanup during dispose Avoid creating a new Accessible from Control.removeRelation() while a control is already being torn down. Reuse existing accessibility objects instead to prevent GTK handle access after disposal. Fixes https://github.com/eclipse-platform/eclipse.platform.swt/issues/1367 --- .../Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java index c78a643e29c..9dc60832036 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java @@ -2501,7 +2501,9 @@ public void removePaintListener(PaintListener listener) { void removeRelation () { if (!isDescribedByLabel ()) return; /* there will not be any */ if (labelRelation != null) { - _getAccessible().removeRelation (ACC.RELATION_LABELLED_BY, labelRelation._getAccessible()); + if (accessible != null && labelRelation.accessible != null) { + accessible.removeRelation (ACC.RELATION_LABELLED_BY, labelRelation.accessible); + } labelRelation = null; } } From ef962a22339dee9d31148a0f3ce97593bf8c55ba Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Tue, 14 Jul 2026 11:18:19 +0200 Subject: [PATCH 08/46] [Cocoa ] Add NSControl[Size/StateValue] enum spellings to bridgesupport NSControlSizeRegular/Small/Mini and NSControlStateValueOn/Off/Mixed are already used and registered as swt_gen="true" in AppKitFull.bridgesupport.extras, but were missing from the actual AppKitFull.bridgesupport (only their legacy names, e.g. NSRegularControlSize/NSOnState, are present there). Since extras only carries generation flags and can't supply a value that isn't present in the underlying bridgesupport file, MacGenerator failed with "No value for enum" and silently dropped the constants on regeneration. Add the modern names to bridgesupport with the same values as their legacy counterparts, as a stand-in until the file is regenerated against a macOS SDK new enough to emit them natively. Follow-up to https://github.com/eclipse-platform/eclipse.platform.swt/pull/3304 Co-Authored-By: Claude Sonnet 5 --- .../swt/internal/cocoa/AppKitFull.bridgesupport | 6 ++++++ .../cocoa/org/eclipse/swt/internal/cocoa/OS.java | 12 +++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport index c0262de117e..cc41662c1b2 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport @@ -1877,6 +1877,12 @@ + + + + + + diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java index 40c830f8464..46076f7560c 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java @@ -2246,10 +2246,13 @@ public static Selector getSelector (long value) { public static final int NSLineBreakByWordWrapping = 0; public static final int NSLineToBezierPathElement = 1; public static final int NSControlSizeMini = 2; - +public static final int NSControlSizeRegular = 0; +public static final int NSControlSizeSmall = 1; +public static final int NSControlStateValueMixed = -1; +public static final int NSControlStateValueOff = 0; +public static final int NSControlStateValueOn = 1; public static final int NSMiterLineJoinStyle = 0; public static final int NSModalResponseCancel = 0; -public static final int NSControlStateValueMixed = -1; public static final int NSMouseEntered = 8; public static final int NSMouseExited = 9; public static final int NSMouseMoved = 5; @@ -2259,9 +2262,6 @@ public static Selector getSelector (long value) { public static final int NSNoImage = 0; public static final int NSNoTitle = 0; public static final int NSNonZeroWindingRule = 0; - -public static final int NSControlStateValueOff = 0; -public static final int NSControlStateValueOn = 1; public static final int NSOpenGLCPSurfaceOrder = 235; public static final int NSOpenGLPFAAccumSize = 14; public static final int NSOpenGLPFAAlphaSize = 11; @@ -2282,7 +2282,6 @@ public static Selector getSelector (long value) { public static final int NSPrintPanelShowsPrintSelection = 32; public static final int NSProgressIndicatorPreferredThickness = 14; public static final int NSColorSpaceModelRGB = 1; -public static final int NSControlSizeRegular = 0; public static final int NSRegularSquareBezelStyle = 2; public static final int NSResizableWindowMask = 8; public static final int NSRightMouseDown = 3; @@ -2302,7 +2301,6 @@ public static Selector getSelector (long value) { public static final int NSScrollerStyleLegacy = 0; public static final int NSScrollerStyleOverlay = 1; public static final int NSShiftKeyMask = 131072; -public static final int NSControlSizeSmall = 1; public static final int NSSquareLineCapStyle = 2; public static final int NSStatusWindowLevel = 25; public static final int NSStringDrawingUsesLineFragmentOrigin = 1; From 27659851af522bee48cd87d700ec4539c18ec5c4 Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Tue, 14 Jul 2026 12:45:02 +0200 Subject: [PATCH 09/46] [Cocoa] Remove deprecated CFURLCreateFromFSRef from bridge support The usages of deprecated CFURLCreateFromFSRef have been replaced in a recent change with URLForApplicationToOpenURL/URLForApplicationToOpenContentType and the generated code for this function has been removed. However, the the function was still declared in the bridge support which makes the MacGenerator regenerate code for that function upon execution. This change cleans up the declaration of the function in bridge support. Follow-up to https://github.com/eclipse-platform/eclipse.platform.swt/pull/3187 --- .../swt/internal/cocoa/CoreFoundationFull.bridgesupport | 5 ----- .../internal/cocoa/CoreFoundationFull.bridgesupport.extras | 5 ----- 2 files changed, 10 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/CoreFoundationFull.bridgesupport b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/CoreFoundationFull.bridgesupport index 147523b6afa..feaa3ca9fbb 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/CoreFoundationFull.bridgesupport +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/CoreFoundationFull.bridgesupport @@ -5451,11 +5451,6 @@ - - - - - diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/CoreFoundationFull.bridgesupport.extras b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/CoreFoundationFull.bridgesupport.extras index 12e14c63f54..41fc30c2ce3 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/CoreFoundationFull.bridgesupport.extras +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/CoreFoundationFull.bridgesupport.extras @@ -43,11 +43,6 @@ - - - - - From 3f4b535f6d4349bba1e15112f8b23190f2b40775 Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Tue, 14 Jul 2026 14:49:00 +0200 Subject: [PATCH 10/46] [Cocoa] Align ordering in bridgesupport and OS to MacGenerator result The entries of the AppKitFull.bridgesupport.extras and OS classes are currently not ordered according to what the MacGenerator produces. In order to have consistent MacGenerator results without ordering changes, this change applies the order of class entries that is generated by the MacGenerator. --- .../cocoa/AppKitFull.bridgesupport.extras | 14 ++++---------- .../cocoa/org/eclipse/swt/internal/cocoa/OS.java | 16 +++++----------- 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras index b43990cb1d0..d1ca0ed5bf8 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras @@ -4387,6 +4387,7 @@ + @@ -4402,6 +4403,9 @@ + + + @@ -4459,10 +4463,8 @@ - - @@ -4472,7 +4474,6 @@ - @@ -4492,8 +4493,6 @@ - - @@ -4501,7 +4500,6 @@ - @@ -4513,7 +4511,6 @@ - @@ -4533,9 +4530,6 @@ - - - diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java index 46076f7560c..8c94dfd44ea 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java @@ -2164,7 +2164,6 @@ public static Selector getSelector (long value) { public static final int NSBezelStylePushDisclosure = 14; public static final int NSBezelStyleSmallSquare = 6; public static final int NSBoldFontMask = 2; - public static final int NSBottomTabsBezelBorder = 2; public static final int NSBoxCustom = 4; public static final int NSBoxSeparator = 2; @@ -2174,9 +2173,8 @@ public static Selector getSelector (long value) { public static final int NSButtonTypeRadio = 4; public static final int NSButtonTypeSwitch = 3; public static final int NSCarriageReturnCharacter = 13; -public static final int NSDatePickerStyleClockAndCalendar = 1; - public static final int NSClosePathBezierPathElement = 3; +public static final int NSColorSpaceModelRGB = 1; public static final int NSCommandKeyMask = 1048576; public static final int NSCompositingOperationClear = 0; public static final int NSCompositingOperationCopy = 1; @@ -2186,9 +2184,11 @@ public static Selector getSelector (long value) { public static final int NSControlKeyMask = 262144; public static final int NSCriticalAlertStyle = 2; public static final int NSCurveToBezierPathElement = 2; +public static final int NSDatePickerStyleClockAndCalendar = 1; +public static final int NSDatePickerStyleTextField = 2; +public static final int NSDatePickerStyleTextFieldAndStepper = 0; public static final int NSDeleteCharacter = 127; public static final long NSDeviceIndependentModifierFlagsMask = 4294901760L; - public static final int NSDragOperationCopy = 1; public static final int NSDragOperationDelete = 32; public static final long NSDragOperationEvery = -1L; @@ -2212,7 +2212,6 @@ public static Selector getSelector (long value) { public static final int NSFocusRingTypeNone = 1; public static final int NSFontPanelModeMaskAllEffects = 1048320; public static final int NSFontPanelModeMaskAllModes = -1; - public static final int NSHelpFunctionKey = 63302; public static final int NSHelpKeyMask = 4194304; public static final int NSHourMinuteDatePickerElementFlag = 12; @@ -2229,6 +2228,7 @@ public static Selector getSelector (long value) { public static final int NSImageLeft = 2; public static final int NSImageOnly = 1; public static final int NSImageOverlaps = 6; +public static final int NSImageScaleNone = 2; public static final int NSInformationalAlertStyle = 1; public static final int NSItalicFontMask = 1; public static final int NSKeyDown = 10; @@ -2281,7 +2281,6 @@ public static Selector getSelector (long value) { public static final int NSPrintPanelShowsPageSetupAccessory = 256; public static final int NSPrintPanelShowsPrintSelection = 32; public static final int NSProgressIndicatorPreferredThickness = 14; -public static final int NSColorSpaceModelRGB = 1; public static final int NSRegularSquareBezelStyle = 2; public static final int NSResizableWindowMask = 8; public static final int NSRightMouseDown = 3; @@ -2289,7 +2288,6 @@ public static Selector getSelector (long value) { public static final int NSRightMouseUp = 4; public static final int NSRoundLineCapStyle = 1; public static final int NSRoundLineJoinStyle = 1; -public static final int NSImageScaleNone = 2; public static final int NSScrollElasticityNone = 1; public static final int NSScrollWheel = 22; public static final int NSScrollerDecrementLine = 4; @@ -2320,9 +2318,6 @@ public static Selector getSelector (long value) { public static final int NSTextAlignmentJustified = 3; public static final int NSTextAlignmentLeft = 0; public static final int NSTextAlignmentRight = IS_X86_64 ? 1 : 2; -public static final int NSDatePickerStyleTextFieldAndStepper = 0; -public static final int NSDatePickerStyleTextField = 2; - public static final int NSToolbarDisplayModeIconOnly = 2; public static final long NSTouchPhaseAny = -1L; public static final int NSTouchPhaseBegan = 1; @@ -2334,7 +2329,6 @@ public static Selector getSelector (long value) { public static final int NSUnderlineStyleNone = 0; public static final int NSUnderlineStyleSingle = 1; public static final int NSUnderlineStyleThick = 2; - public static final int NSViewHeightSizable = 16; public static final int NSViewMaxXMargin = 4; public static final int NSViewMaxYMargin = 32; From 17dedb361c112fba5368929b9da29834f52710f5 Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Tue, 14 Jul 2026 22:24:35 +0200 Subject: [PATCH 11/46] [Cocoa] Add generation instruction for file dialog cancel constant The cancel button constant for the file selection dialog has been added to the OS constants without adding the auto-generation instruction for the MacGenerator to the bridgesupport.extras. As a consequence, a MacGenerator tool execution removes the constant from the OS class. This change adds the according instruction. Follow-up to https://github.com/eclipse-platform/eclipse.platform.swt/pull/1026 --- .../eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras | 1 + 1 file changed, 1 insertion(+) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras index d1ca0ed5bf8..fcbe3ca5d02 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras @@ -4425,6 +4425,7 @@ + From 80364bcab99dd319e80bb7b4adb797951109bf93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=8A?= =?UTF-8?q?=D1=80=20=D0=9A=D1=83=D1=80=D1=82=D0=B0=D0=BA=D0=BE=D0=B2?= Date: Wed, 15 Jul 2026 13:10:10 +0300 Subject: [PATCH 12/46] [Gtk4] Fix stale/unresponsive fast-view restore buttons and toolbar raise On GTK4, widgets have no per-widget GdkWindow, so the native sibling list doubles as both paint order and Composite._getChildren() order. This caused several fast-view (minimize/restore) regressions vs GTK3: - Control.destroyWidget() only called swt_fixed_remove() when fixedHandle != 0, silently skipping the native unparent for widgets without a separate wrapper handle. Their Java objects were marked disposed while the native widget stayed alive and rendered, leaving stale toolbar/button remnants behind after a restore. - Composite.moveAbove()/moveBelow() raising a Shell-direct child to the front (e.g. a flyout pane) did not actually reorder GTK4 paint order, since the general child-list-preserving behavior needed by other callers took precedence. - ToolBar.getItemCount()/_getItems() did not account for a Menu's GtkPopover appearing as a native sibling alongside real ToolItems, causing a ClassCastException and item count/index mismatches when a context menu was attached to a fast-view toolbar. --- .../org/eclipse/swt/widgets/Composite.java | 25 ++++++++++++++++--- .../gtk/org/eclipse/swt/widgets/Control.java | 23 ++++++++++++----- .../gtk/org/eclipse/swt/widgets/ToolBar.java | 9 ++++--- 3 files changed, 44 insertions(+), 13 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java index c70707366f6..23e74f61c62 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java @@ -1396,7 +1396,20 @@ void moveAbove (long child, long sibling) { long parentHandle = parentingHandle (); if (GTK.GTK4) { if (sibling == 0) { - GTK4.gtk_widget_insert_after(child, parentHandle, 0L); + /* + * True raise-to-top-of-paint-order, scoped to Shell-direct + * children (e.g. an overlay pane raised via moveAbove(null)). + * GTK4 has no per-widget GdkWindow, so this same native sibling + * list also backs Composite._getChildren(); other code already + * relies on today's insert_after(..., NULL) behaviour to keep + * getChildren() stable for non-Shell parents, so this is not + * changed generally. + */ + if (this instanceof Shell) { + GTK4.gtk_widget_insert_before(child, parentHandle, 0L); + } else { + GTK4.gtk_widget_insert_after(child, parentHandle, 0L); + } } else { GTK4.gtk_widget_insert_before(child, parentHandle, sibling); } @@ -1416,16 +1429,20 @@ void moveBelow (long child, long sibling) { * scrolled content instead. * * Not needed on GTK4: widgets have no per-widget GdkWindow, so paint order - * is simply the parent's child-list order (first = bottom, last = top), and - * the general branch below already appends the child to the end (top). + * is simply the parent's child-list order (first = bottom, last = top). */ if (!GTK.GTK4 && sibling == 0 && parentHandle == fixedHandle) { moveAbove (child, scrolledHandle != 0 ? scrolledHandle : handle); return; } if (GTK.GTK4) { + /* Mirror image of moveAbove - see the comment there. */ if (sibling == 0) { - GTK4.gtk_widget_insert_before(child, parentHandle, 0L); + if (this instanceof Shell) { + GTK4.gtk_widget_insert_after(child, parentHandle, 0L); + } else { + GTK4.gtk_widget_insert_before(child, parentHandle, 0L); + } } else { GTK4.gtk_widget_insert_after(child, parentHandle, sibling); } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java index 9dc60832036..6671563a3cc 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java @@ -815,7 +815,13 @@ void createWidget(int index) { checkBuffered(); showWidget(); setInitialBounds(); - setZOrder(null, false, false); + if (GTK.GTK4 && !(this instanceof Shell)) { + /* moveBelow(null) now sinks Shell-direct children to the back + * (see Composite.moveAbove) - guard against undoing that. */ + setZOrder(null, false, false, !(parent instanceof Shell)); + } else { + setZOrder(null, false, false); + } if (!GTK.GTK4) setRelations(); checkMirrored(); checkBorder(); @@ -4833,10 +4839,10 @@ void destroyWidget() { // GTK windows don't have a parent, so destroy it now GTK4.gtk_window_destroy(currHandle); } else if (parent != null) { - if (fixedHandle != 0) { - // Remove widget from hierarchy by removing it from parent container - OS.swt_fixed_remove(parent.parentingHandle(), fixedHandle); - } + /* Use currHandle, not fixedHandle alone - widgets without a + * separate fixedHandle wrapper were otherwise never actually + * unparented here, leaving them alive and rendered natively. */ + OS.swt_fixed_remove(parent.parentingHandle(), currHandle); } else { assert false : "widgets must have a parent or be a GtkWindow"; } @@ -5925,7 +5931,12 @@ public boolean setParent (Composite parent) { allocation.height = height; gtk_widget_size_allocate(topHandle, allocation, -1); this.parent = parent; - setZOrder (null, false, true); + if (GTK.GTK4 && !(this instanceof Shell)) { + /* See createWidget() re: guarding fixChildren on GTK4. */ + setZOrder (null, false, true, !(parent instanceof Shell)); + } else { + setZOrder (null, false, true); + } reskin (SWT.ALL); // restore focus to the last Control that had it, if focus is now gone if (focusControlBeforeReparent != null && !focusControlBeforeReparent.isDisposed() && display.getFocusControl() == null) { diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolBar.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolBar.java index 4a9782a213c..fb63abb0903 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolBar.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolBar.java @@ -309,8 +309,10 @@ public int getItemCount () { int itemCount = 0; if (GTK.GTK4) { + /* Must match _getItems(): a Menu's GtkPopover is also parented here + * as a native child and would otherwise count as a phantom item. */ for (long child = GTK4.gtk_widget_get_first_child(handle); child != 0; child = GTK4.gtk_widget_get_next_sibling(child)) { - itemCount++; + if (display.getWidget(child) instanceof ToolItem) itemCount++; } } else { long list = GTK3.gtk_container_get_children (handle); @@ -348,8 +350,9 @@ ToolItem[] _getItems () { ArrayList childrenList = new ArrayList<>(); for (long child = GTK4.gtk_widget_get_first_child(handle); child != 0; child = GTK4.gtk_widget_get_next_sibling(child)) { Widget childWidget = display.getWidget(child); - if (childWidget != null) { - childrenList.add((ToolItem)childWidget); + /* A Menu's GtkPopover is also a native child here; skip non-ToolItems. */ + if (childWidget instanceof ToolItem toolItem) { + childrenList.add(toolItem); } } From 725c9485b9e37c3e9bc2993923db02fe15781aec Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Tue, 14 Jul 2026 11:45:50 +0200 Subject: [PATCH 13/46] [Cocoa] Correct generation for urlForApplicationToOpen[URL|ContentType] NSWorkspace.URLForApplicationToOpenURL: and URLForApplicationToOpenContentType:, introduced as a replacement for deprecated file-association API, were hand-written directly in NSWorkspace.java without registering them for MacGenerator. Since UTType.typeWithFilenameExtension: (the other new API involved, UniformTypeIdentifiers framework, macOS 12+) is not declared in any bridgesupport file, MacGenerator had no way to reproduce these methods and silently dropped them on the next regeneration. - Declare the two NSWorkspace selectors and a minimal UTType class (one method) in AppKitFull.bridgesupport/.extras by hand, since neither API exists in the SDK version the bridgesupport files were generated from, and UTType's own framework has no dedicated bridgesupport file in this project. This makes both methods regenerable instead of being a permanent manual exception. - Rename the two NSWorkspace methods to the casing MacGenerator derives from the Objective-C selector, matching existing conventions elsewhere (e.g. NSURL.URLWithString). - Introduce a proper UTType wrapper class instead of passing its handle around as a raw long, consistent with how every other Cocoa object is represented in this codebase; NSWorkspace.URLForApplicationToOpenContentType now takes a typed UTType argument. - Update Program.findAppURLForExtension() to use the generated UTType.typeWithFilenameExtension() wrapper instead of manual objc_getClass/objc_msgSend calls. Follow-up to https://github.com/eclipse-platform/eclipse.platform.swt/pull/3187 --- .../internal/cocoa/AppKitFull.bridgesupport | 10 ++++++ .../cocoa/AppKitFull.bridgesupport.extras | 14 ++++++++ .../swt/internal/cocoa/NSWorkspace.java | 23 ++++++------- .../org/eclipse/swt/internal/cocoa/OS.java | 5 +-- .../eclipse/swt/internal/cocoa/Selector.java | 4 +-- .../eclipse/swt/internal/cocoa/UTType.java | 32 +++++++++++++++++++ .../org/eclipse/swt/program/Program.java | 15 ++++----- 7 files changed, 77 insertions(+), 26 deletions(-) create mode 100644 bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/UTType.java diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport index cc41662c1b2..c9b09006ac9 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport @@ -32642,6 +32642,10 @@ + + + + @@ -32935,6 +32939,12 @@ + + + + + + diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras index fcbe3ca5d02..8778c0d26a2 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras @@ -4154,6 +4154,14 @@ + + + + + + + + @@ -4192,6 +4200,12 @@ + + + + + + diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSWorkspace.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSWorkspace.java index 9bfa02eae83..16d5910854f 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSWorkspace.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSWorkspace.java @@ -7,9 +7,6 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.swt.internal.cocoa; @@ -27,6 +24,16 @@ public NSWorkspace(id id) { super(id); } +public NSURL URLForApplicationToOpenURL(NSURL url) { + long result = OS.objc_msgSend(this.id, OS.sel_URLForApplicationToOpenURL_, url != null ? url.id : 0); + return result != 0 ? new NSURL(result) : null; +} + +public NSURL URLForApplicationToOpenContentType(UTType contentType) { + long result = OS.objc_msgSend(this.id, OS.sel_URLForApplicationToOpenContentType_, contentType != null ? contentType.id : 0); + return result != 0 ? new NSURL(result) : null; +} + public NSString fullPathForApplication(NSString appName) { long result = OS.objc_msgSend(this.id, OS.sel_fullPathForApplication_, appName != null ? appName.id : 0); return result != 0 ? new NSString(result) : null; @@ -45,16 +52,6 @@ public boolean openURL(NSURL url) { return OS.objc_msgSend_bool(this.id, OS.sel_openURL_, url != null ? url.id : 0); } -public NSURL urlForApplicationToOpenURL(NSURL url) { - long result = OS.objc_msgSend(this.id, OS.sel_URLForApplicationToOpenURL_, url != null ? url.id : 0); - return result != 0 ? new NSURL(result) : null; -} - -public NSURL urlForApplicationToOpenContentType(long contentType) { - long result = OS.objc_msgSend(this.id, OS.sel_URLForApplicationToOpenContentType_, contentType); - return result != 0 ? new NSURL(result) : null; -} - public boolean openURLs(NSArray urls, NSString bundleIdentifier, long options, NSAppleEventDescriptor descriptor, long identifiers) { return OS.objc_msgSend_bool(this.id, OS.sel_openURLs_withAppBundleIdentifier_options_additionalEventParamDescriptor_launchIdentifiers_, urls != null ? urls.id : 0, bundleIdentifier != null ? bundleIdentifier.id : 0, options, descriptor != null ? descriptor.id : 0, identifiers); } diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java index 8c94dfd44ea..bfe161cc67b 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java @@ -767,6 +767,7 @@ public static boolean isSystemDarkAppearance() { public static final long class_NSWorkspace = objc_getClass("NSWorkspace"); public static final long class_SFCertificatePanel = objc_getClass("SFCertificatePanel"); public static final long class_SFCertificateTrustPanel = objc_getClass("SFCertificateTrustPanel"); +public static final long class_UTType = objc_getClass("UTType"); public static final long class_WebDataSource = objc_getClass("WebDataSource"); public static final long class_WebFrame = objc_getClass("WebFrame"); public static final long class_WebFrameView = objc_getClass("WebFrameView"); @@ -830,9 +831,9 @@ public static Selector getSelector (long value) { public static final long sel_PMPrintSettings = Selector.sel_PMPrintSettings.value; public static final long sel_TIFFRepresentation = Selector.sel_TIFFRepresentation.value; public static final long sel_URL = Selector.sel_URL.value; -public static final long sel_URLFromPasteboard_ = Selector.sel_URLFromPasteboard_.value; -public static final long sel_URLForApplicationToOpenURL_ = Selector.sel_URLForApplicationToOpenURL_.value; public static final long sel_URLForApplicationToOpenContentType_ = Selector.sel_URLForApplicationToOpenContentType_.value; +public static final long sel_URLForApplicationToOpenURL_ = Selector.sel_URLForApplicationToOpenURL_.value; +public static final long sel_URLFromPasteboard_ = Selector.sel_URLFromPasteboard_.value; public static final long sel_URLWithString_ = Selector.sel_URLWithString_.value; public static final long sel_UTF8String = Selector.sel_UTF8String.value; public static final long sel_abortEditing = Selector.sel_abortEditing.value; diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/Selector.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/Selector.java index 589d736607e..09e0ae8c00c 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/Selector.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/Selector.java @@ -96,9 +96,9 @@ public enum Selector { , sel_PMPrintSettings("PMPrintSettings") , sel_TIFFRepresentation("TIFFRepresentation") , sel_URL("URL") - , sel_URLFromPasteboard_("URLFromPasteboard:") - , sel_URLForApplicationToOpenURL_("URLForApplicationToOpenURL:") , sel_URLForApplicationToOpenContentType_("URLForApplicationToOpenContentType:") + , sel_URLForApplicationToOpenURL_("URLForApplicationToOpenURL:") + , sel_URLFromPasteboard_("URLFromPasteboard:") , sel_URLWithString_("URLWithString:") , sel_UTF8String("UTF8String") , sel_abortEditing("abortEditing") diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/UTType.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/UTType.java new file mode 100644 index 00000000000..b836c18703f --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/UTType.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2026 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.swt.internal.cocoa; + +public class UTType extends NSObject { + +public UTType() { + super(); +} + +public UTType(long id) { + super(id); +} + +public UTType(id id) { + super(id); +} + +public static UTType typeWithFilenameExtension(NSString filenameExtension) { + long result = OS.objc_msgSend(OS.class_UTType, OS.sel_typeWithFilenameExtension_, filenameExtension != null ? filenameExtension.id : 0); + return result != 0 ? new UTType(result) : null; +} + +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT Program/cocoa/org/eclipse/swt/program/Program.java b/bundles/org.eclipse.swt/Eclipse SWT Program/cocoa/org/eclipse/swt/program/Program.java index 465abcc1180..786067fecee 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Program/cocoa/org/eclipse/swt/program/Program.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Program/cocoa/org/eclipse/swt/program/Program.java @@ -153,20 +153,17 @@ private static NSURL findAppURLForExtension(NSString ext) { // On macOS 12.0+, use the content type-based API which works reliably // for all file types including third-party ones. if (OS.VERSION >= OS.VERSION(12, 0, 0)) { - long UTTypeClass = OS.objc_getClass("UTType"); - if (UTTypeClass != 0) { - long utType = OS.objc_msgSend(UTTypeClass, OS.sel_typeWithFilenameExtension_, ext.id); - if (utType != 0) { - NSURL appURL = workspace.urlForApplicationToOpenContentType(utType); - if (appURL != null) { - return appURL; - } + UTType utType = UTType.typeWithFilenameExtension(ext); + if (utType != null) { + NSURL appURL = workspace.URLForApplicationToOpenContentType(utType); + if (appURL != null) { + return appURL; } } } // Fallback: URL-based lookup (available since macOS 10.6, deprecated in macOS 12.0) NSURL fileURL = NSURL.fileURLWithPath(NSString.stringWith("/tmp/dummy." + ext.getString())); - return workspace.urlForApplicationToOpenURL(fileURL); + return workspace.URLForApplicationToOpenURL(fileURL); } static Program getProgram(NSBundle bundle) { From a99cbe4772e4118aa8e6330a9903faa420f68f52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=8A?= =?UTF-8?q?=D1=80=20=D0=9A=D1=83=D1=80=D1=82=D0=B0=D0=BA=D0=BE=D0=B2?= Date: Thu, 16 Jul 2026 11:27:14 +0300 Subject: [PATCH 14/46] Fix spurious scrollbar on GTK4 Wayland popup menus GtkPopoverMenu inserts section-separator widgets from a GLib idle callback (gtk_menu_section_box_handle_sync_separators), but SWT popped the popover synchronously in the same call that built the items, so the popover measured its height before the separators existed, undersized itself and fell back to a scrollbar. Defer gtk_popover_popup() via display.asyncExec() so GTK's pending idle work runs first. Additionally, a bottom-of-screen menu carries GDK_ANCHOR_RESIZE_Y and is shrunk into a scrolled view when it fits neither below nor flipped above the anchor. Wayland has no global window coordinates to compute the overflow, so compare the popover's allocated height to its natural height and iteratively shift the anchor up by the shortfall, keeping the popover hidden (opacity 0) until it fits. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../gtk/org/eclipse/swt/widgets/Menu.java | 101 +++++++++++++++--- 1 file changed, 87 insertions(+), 14 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java index 3dc45318bb9..8192253cb56 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java @@ -261,6 +261,88 @@ boolean ableToSetLocation() { return hasLocation; } +/* + * GtkPopoverMenu inserts section-separator widgets from a GLib idle callback + * (gtk_menu_section_box_handle_sync_separators). Calling gtk_popover_popup() + * synchronously would measure the menu before those widgets exist, undersizing + * it into a scrollbar. Deferring via asyncExec lets that idle run first. + */ +void popupGtk4Popover(boolean hasPointingTo, int pointX, int pointY) { + if (isDisposed()) return; + display.asyncExec(() -> { + if (isDisposed()) return; + if (hasPointingTo) { + GdkRectangle popoverPosition = new GdkRectangle(); + popoverPosition.x = pointX; + popoverPosition.y = pointY; + popoverPosition.width = popoverPosition.height = 1; + GTK.gtk_popover_set_pointing_to(handle, popoverPosition); + // Hide during the fit (scheduleGtk4PopoverFit) so the menu appears + // directly at its final location without a visible jump. + GTK.gtk_widget_set_opacity(handle, 0.0); + GTK.gtk_popover_popup(handle); + scheduleGtk4PopoverFit(pointX, pointY, 0); + } else { + GTK.gtk_popover_popup(handle); + } + }); +} + +/* + * Keep a bottom-of-screen popup menu from being shrunk into a scrolled view. + * + * GtkPopover's layout carries GDK_ANCHOR_RESIZE_Y (a GtkPopoverMenu can always + * shrink), so when the menu fits neither below the anchor nor flipped above it, + * the compositor shrinks it and shows a scrollbar. Wayland has no global window + * coordinates, so we cannot compute the overflow directly; instead we compare + * the popover's allocated height to its natural height and shift the anchor up + * by the shortfall, which yields exactly that much more room below. Repeated + * until it fits (usually 2-3 passes; the bound is just a safety cap). The + * popover stays hidden until settled. + */ +static final int GTK4_POPOVER_FIT_MAX_ITERATIONS = 6; + +void scheduleGtk4PopoverFit(int pointX, int pointY, int iteration) { + display.asyncExec(() -> { + if (isDisposed()) return; + if (!GTK.gtk_widget_get_mapped(handle)) { + // Menu was dismissed before it settled; make sure it is not left + // permanently transparent for a future show. + GTK.gtk_widget_set_opacity(handle, 1.0); + return; + } + if (iteration >= GTK4_POPOVER_FIT_MAX_ITERATIONS) { + revealGtk4Popover(); + return; + } + int[] natHeight = new int[1]; + GTK4.gtk_widget_measure(handle, GTK.GTK_ORIENTATION_VERTICAL, -1, null, natHeight, null, null); + int allocated = GTK4.gtk_widget_get_height(handle); + if (natHeight[0] <= 0 || allocated <= 0) { + // Not measured/allocated yet; wait another turn. + scheduleGtk4PopoverFit(pointX, pointY, iteration + 1); + return; + } + int shortfall = natHeight[0] - allocated; + if (shortfall <= 0) { + revealGtk4Popover(); + return; + } + int newPointY = pointY - shortfall; + GdkRectangle popoverPosition = new GdkRectangle(); + popoverPosition.x = pointX; + popoverPosition.y = newPointY; + popoverPosition.width = popoverPosition.height = 1; + GTK.gtk_popover_set_pointing_to(handle, popoverPosition); + scheduleGtk4PopoverFit(pointX, newPointY, iteration + 1); + }); +} + +void revealGtk4Popover() { + if (isDisposed()) return; + GTK.gtk_widget_set_opacity(handle, 1.0); +} + void _setVisible (boolean visible) { if (visible == GTK.gtk_widget_get_mapped (handle)) return; if (visible) { @@ -307,7 +389,6 @@ void _setVisible (boolean visible) { long eventPtr = 0; if (ableToSetLocation()) { if (GTK.GTK4) { - GdkRectangle popoverPosition = new GdkRectangle(); /* * gtk_popover_set_pointing_to expects coordinates in the coordinate * space of the popover's current parent widget. @@ -323,24 +404,16 @@ void _setVisible (boolean visible) { * relative to that control - do not apply the shell to * parent.handle translation. */ + int pointX = x, pointY = y; long currentParent = GTK.gtk_widget_get_parent(handle); if (currentParent == parent.handle) { double[] relX = new double[1], relY = new double[1]; if (GTK4.gtk_widget_translate_coordinates(parent.getShell().topHandle(), parent.handle, x, y, relX, relY)) { - popoverPosition.x = (int) relX[0]; - popoverPosition.y = (int) relY[0]; - } else { - popoverPosition.x = x; - popoverPosition.y = y; + pointX = (int) relX[0]; + pointY = (int) relY[0]; } - } else { - popoverPosition.x = x; - popoverPosition.y = y; } - popoverPosition.width = popoverPosition.height = 1; - GTK.gtk_popover_set_pointing_to(handle, popoverPosition); - - GTK.gtk_popover_popup(handle); + popupGtk4Popover(true, pointX, pointY); } else { // Create the GdkEvent manually as we need to control // certain fields like the event window @@ -384,7 +457,7 @@ void _setVisible (boolean visible) { } } else { if (GTK.GTK4) { - GTK.gtk_popover_popup(handle); + popupGtk4Popover(false, 0, 0); } else { /* * GTK Feature: gtk_menu_popup is deprecated as of GTK3.22 and the new method gtk_menu_popup_at_pointer From 1603edd1255262636cfd9c99921dc9cbfbf8ef18 Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Sun, 12 Jul 2026 14:05:49 +0200 Subject: [PATCH 15/46] [Cocoa] Remove deprecated scroller part constants NSScrollerDecrementLine and NSScrollerIncrementLine are deprecated since macOS 10.14 without replacement, as scrollers do not have arrow buttons anymore since macOS 10.7. Remove the constants together with the dead switch cases in ScrollBar and Slider that handled hits on the no longer existing scroller arrows. Contributes to https://github.com/eclipse-platform/eclipse.platform.swt/issues/3214 Co-Authored-By: Claude Sonnet 5 --- .../swt/internal/cocoa/AppKitFull.bridgesupport.extras | 2 -- .../cocoa/org/eclipse/swt/internal/cocoa/OS.java | 2 -- .../cocoa/org/eclipse/swt/widgets/ScrollBar.java | 8 -------- .../Eclipse SWT/cocoa/org/eclipse/swt/widgets/Slider.java | 8 -------- 4 files changed, 20 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras index 8778c0d26a2..50395fd5c0a 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras @@ -4517,9 +4517,7 @@ - - diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java index bfe161cc67b..025253b0276 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java @@ -2291,9 +2291,7 @@ public static Selector getSelector (long value) { public static final int NSRoundLineJoinStyle = 1; public static final int NSScrollElasticityNone = 1; public static final int NSScrollWheel = 22; -public static final int NSScrollerDecrementLine = 4; public static final int NSScrollerDecrementPage = 1; -public static final int NSScrollerIncrementLine = 5; public static final int NSScrollerIncrementPage = 3; public static final int NSScrollerKnob = 2; public static final int NSScrollerKnobSlot = 6; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/ScrollBar.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/ScrollBar.java index ea25420fec6..8e29470b678 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/ScrollBar.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/ScrollBar.java @@ -481,18 +481,10 @@ void sendSelection () { int hitPart = (int)((NSScroller)view).testPart(point); Event event = new Event(); switch (hitPart) { - case OS.NSScrollerDecrementLine: - value -= increment; - event.detail = SWT.ARROW_UP; - break; case OS.NSScrollerDecrementPage: value -= pageIncrement; event.detail = SWT.PAGE_UP; break; - case OS.NSScrollerIncrementLine: - value += increment; - event.detail = SWT.ARROW_DOWN; - break; case OS.NSScrollerIncrementPage: value += pageIncrement; event.detail = SWT.PAGE_DOWN; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Slider.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Slider.java index 43e73d710fb..a6490a86622 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Slider.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Slider.java @@ -333,18 +333,10 @@ void sendSelection () { int hitPart = (int)((NSScroller)view).hitPart(); int value = getSelection (); switch (hitPart) { - case OS.NSScrollerDecrementLine: - event.detail = SWT.ARROW_UP; - value -= increment; - break; case OS.NSScrollerDecrementPage: value -= pageIncrement; event.detail = SWT.PAGE_UP; break; - case OS.NSScrollerIncrementLine: - value += increment; - event.detail = SWT.ARROW_DOWN; - break; case OS.NSScrollerIncrementPage: value += pageIncrement; event.detail = SWT.PAGE_DOWN; From 95cb073180d61d75968231a97e2a02baaedc4ed7 Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Tue, 14 Jul 2026 11:17:51 +0200 Subject: [PATCH 16/46] [Cocoa] Add generation instructions for PDF export functions The CGPDFContext* functions are all present in the CoreGraphicsFull.bridgesupport files but were never registered in the corresponding .extras files, so MacGenerator silently dropped them on the next regeneration. This adds the missing swt_gen="true" entries and reruns the MacGenerator to adopt its ordering of generated entries in the OS class. Follow-up to https://github.com/eclipse-platform/eclipse.platform.swt/pull/2882 Co-Authored-By: Claude Sonnet 5 --- .../Eclipse SWT PI/cocoa/library/os.c | 2 +- .../CoreGraphicsFull.bridgesupport.extras | 19 +++++++++++++++++++ .../org/eclipse/swt/internal/cocoa/OS.java | 16 ++++++++-------- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os.c b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os.c index 6a8d73e68c7..da6a5735fd7 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os.c @@ -1605,7 +1605,7 @@ JNIEXPORT jlong JNICALL OS_NATIVE(CGPDFContextCreateWithURL) jlong rc = 0; OS_NATIVE_ENTER(env, that, CGPDFContextCreateWithURL_FUNC); if (arg1) if ((lparg1 = getCGRectFields(env, arg1, &_arg1)) == NULL) goto fail; - rc = (jlong)CGPDFContextCreateWithURL((CFURLRef)arg0, (const CGRect *)lparg1, (CFDictionaryRef)arg2); + rc = (jlong)CGPDFContextCreateWithURL((CFURLRef)arg0, (CGRect*)lparg1, (CFDictionaryRef)arg2); fail: if (arg1 && lparg1) setCGRectFields(env, arg1, lparg1); OS_NATIVE_EXIT(env, that, CGPDFContextCreateWithURL_FUNC); diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/CoreGraphicsFull.bridgesupport.extras b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/CoreGraphicsFull.bridgesupport.extras index d694bac6a20..3702b5e3815 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/CoreGraphicsFull.bridgesupport.extras +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/CoreGraphicsFull.bridgesupport.extras @@ -247,6 +247,25 @@ + + + + + + + + + + + + + + + + + + + diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java index 025253b0276..c1f1a1c36eb 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java @@ -3174,12 +3174,6 @@ public static Selector getSelector (long value) { * @param image cast=(CGImageRef) */ public static final native void CGImageRelease(long image); -/** - * @param url cast=(CFURLRef) - * @param mediaBox cast=(const CGRect *) - * @param auxiliaryInfo cast=(CFDictionaryRef) - */ -public static final native long CGPDFContextCreateWithURL(long url, CGRect mediaBox, long auxiliaryInfo); /** * @param context cast=(CGContextRef) * @param pageInfo cast=(CFDictionaryRef) @@ -3188,11 +3182,17 @@ public static Selector getSelector (long value) { /** * @param context cast=(CGContextRef) */ -public static final native void CGPDFContextEndPage(long context); +public static final native void CGPDFContextClose(long context); +/** + * @param url cast=(CFURLRef) + * @param mediaBox cast=(CGRect*) + * @param auxiliaryInfo cast=(CFDictionaryRef) + */ +public static final native long CGPDFContextCreateWithURL(long url, CGRect mediaBox, long auxiliaryInfo); /** * @param context cast=(CGContextRef) */ -public static final native void CGPDFContextClose(long context); +public static final native void CGPDFContextEndPage(long context); /** * @param path cast=(CGMutablePathRef) * @param m cast=(CGAffineTransform*) From a87a78d75ce7f54a5dcd6e110f9d9a97081c44cf Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Fri, 17 Jul 2026 12:47:02 +0000 Subject: [PATCH 17/46] v4974r9 --- .../libswt-awt-cocoa-4974r8.jnilib | 3 --- .../libswt-awt-cocoa-4974r9.jnilib | 3 +++ .../libswt-cocoa-4974r8.jnilib | 3 --- .../libswt-cocoa-4974r9.jnilib | 3 +++ .../libswt-pi-cocoa-4974r8.jnilib | 3 --- .../libswt-pi-cocoa-4974r9.jnilib | 3 +++ .../libswt-awt-cocoa-4974r8.jnilib | 3 --- .../libswt-awt-cocoa-4974r9.jnilib | 3 +++ .../libswt-cocoa-4974r8.jnilib | 3 --- .../libswt-cocoa-4974r9.jnilib | 3 +++ .../libswt-pi-cocoa-4974r8.jnilib | 3 --- .../libswt-pi-cocoa-4974r9.jnilib | 3 +++ .../{libswt-atk-gtk-4974r8.so => libswt-atk-gtk-4974r9.so} | 0 .../{libswt-awt-gtk-4974r8.so => libswt-awt-gtk-4974r9.so} | 0 .../{libswt-cairo-gtk-4974r8.so => libswt-cairo-gtk-4974r9.so} | 0 .../{libswt-glx-gtk-4974r8.so => libswt-glx-gtk-4974r9.so} | 0 .../{libswt-gtk-4974r8.so => libswt-gtk-4974r9.so} | 0 .../{libswt-pi3-gtk-4974r8.so => libswt-pi3-gtk-4974r9.so} | 0 ...libswt-webkit-gtk-4974r8.so => libswt-webkit-gtk-4974r9.so} | 0 .../{libswt-atk-gtk-4974r8.so => libswt-atk-gtk-4974r9.so} | 0 .../{libswt-awt-gtk-4974r8.so => libswt-awt-gtk-4974r9.so} | 0 .../{libswt-cairo-gtk-4974r8.so => libswt-cairo-gtk-4974r9.so} | 0 .../{libswt-glx-gtk-4974r8.so => libswt-glx-gtk-4974r9.so} | 0 .../{libswt-gtk-4974r8.so => libswt-gtk-4974r9.so} | 0 .../{libswt-pi3-gtk-4974r8.so => libswt-pi3-gtk-4974r9.so} | 0 ...libswt-webkit-gtk-4974r8.so => libswt-webkit-gtk-4974r9.so} | 0 .../{libswt-atk-gtk-4974r8.so => libswt-atk-gtk-4974r9.so} | 0 .../{libswt-awt-gtk-4974r8.so => libswt-awt-gtk-4974r9.so} | 0 .../{libswt-cairo-gtk-4974r8.so => libswt-cairo-gtk-4974r9.so} | 0 .../{libswt-glx-gtk-4974r8.so => libswt-glx-gtk-4974r9.so} | 0 .../{libswt-gtk-4974r8.so => libswt-gtk-4974r9.so} | 0 .../{libswt-pi3-gtk-4974r8.so => libswt-pi3-gtk-4974r9.so} | 0 ...libswt-webkit-gtk-4974r8.so => libswt-webkit-gtk-4974r9.so} | 0 .../{libswt-atk-gtk-4974r8.so => libswt-atk-gtk-4974r9.so} | 0 .../{libswt-awt-gtk-4974r8.so => libswt-awt-gtk-4974r9.so} | 0 .../{libswt-cairo-gtk-4974r8.so => libswt-cairo-gtk-4974r9.so} | 0 .../{libswt-glx-gtk-4974r8.so => libswt-glx-gtk-4974r9.so} | 0 .../{libswt-gtk-4974r8.so => libswt-gtk-4974r9.so} | 0 .../{libswt-pi3-gtk-4974r8.so => libswt-pi3-gtk-4974r9.so} | 0 .../{libswt-pi4-gtk-4974r8.so => libswt-pi4-gtk-4974r9.so} | 0 ...libswt-webkit-gtk-4974r8.so => libswt-webkit-gtk-4974r9.so} | 0 .../{swt-awt-win32-4974r8.dll => swt-awt-win32-4974r9.dll} | 0 .../{swt-gdip-win32-4974r8.dll => swt-gdip-win32-4974r9.dll} | 0 ...version-win32-4974r8.dll => swt-osversion-win32-4974r9.dll} | 0 .../{swt-wgl-win32-4974r8.dll => swt-wgl-win32-4974r9.dll} | 0 .../{swt-win32-4974r8.dll => swt-win32-4974r9.dll} | 0 .../{swt-awt-win32-4974r8.dll => swt-awt-win32-4974r9.dll} | 0 .../{swt-gdip-win32-4974r8.dll => swt-gdip-win32-4974r9.dll} | 0 ...version-win32-4974r8.dll => swt-osversion-win32-4974r9.dll} | 0 .../{swt-wgl-win32-4974r8.dll => swt-wgl-win32-4974r9.dll} | 0 .../{swt-win32-4974r8.dll => swt-win32-4974r9.dll} | 0 .../common/org/eclipse/swt/internal/Library.java | 2 +- .../org.eclipse.swt/Eclipse SWT/common/library/make_common.mak | 2 +- 53 files changed, 20 insertions(+), 20 deletions(-) delete mode 100755 binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-awt-cocoa-4974r8.jnilib create mode 100755 binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-awt-cocoa-4974r9.jnilib delete mode 100755 binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-cocoa-4974r8.jnilib create mode 100755 binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-cocoa-4974r9.jnilib delete mode 100755 binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-pi-cocoa-4974r8.jnilib create mode 100755 binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-pi-cocoa-4974r9.jnilib delete mode 100755 binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-awt-cocoa-4974r8.jnilib create mode 100755 binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-awt-cocoa-4974r9.jnilib delete mode 100755 binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-cocoa-4974r8.jnilib create mode 100755 binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-cocoa-4974r9.jnilib delete mode 100755 binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-pi-cocoa-4974r8.jnilib create mode 100755 binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-pi-cocoa-4974r9.jnilib rename binaries/org.eclipse.swt.gtk.linux.aarch64/{libswt-atk-gtk-4974r8.so => libswt-atk-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.aarch64/{libswt-awt-gtk-4974r8.so => libswt-awt-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.aarch64/{libswt-cairo-gtk-4974r8.so => libswt-cairo-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.aarch64/{libswt-glx-gtk-4974r8.so => libswt-glx-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.aarch64/{libswt-gtk-4974r8.so => libswt-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.aarch64/{libswt-pi3-gtk-4974r8.so => libswt-pi3-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.aarch64/{libswt-webkit-gtk-4974r8.so => libswt-webkit-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.ppc64le/{libswt-atk-gtk-4974r8.so => libswt-atk-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.ppc64le/{libswt-awt-gtk-4974r8.so => libswt-awt-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.ppc64le/{libswt-cairo-gtk-4974r8.so => libswt-cairo-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.ppc64le/{libswt-glx-gtk-4974r8.so => libswt-glx-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.ppc64le/{libswt-gtk-4974r8.so => libswt-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.ppc64le/{libswt-pi3-gtk-4974r8.so => libswt-pi3-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.ppc64le/{libswt-webkit-gtk-4974r8.so => libswt-webkit-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.riscv64/{libswt-atk-gtk-4974r8.so => libswt-atk-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.riscv64/{libswt-awt-gtk-4974r8.so => libswt-awt-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.riscv64/{libswt-cairo-gtk-4974r8.so => libswt-cairo-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.riscv64/{libswt-glx-gtk-4974r8.so => libswt-glx-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.riscv64/{libswt-gtk-4974r8.so => libswt-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.riscv64/{libswt-pi3-gtk-4974r8.so => libswt-pi3-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.riscv64/{libswt-webkit-gtk-4974r8.so => libswt-webkit-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.x86_64/{libswt-atk-gtk-4974r8.so => libswt-atk-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.x86_64/{libswt-awt-gtk-4974r8.so => libswt-awt-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.x86_64/{libswt-cairo-gtk-4974r8.so => libswt-cairo-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.x86_64/{libswt-glx-gtk-4974r8.so => libswt-glx-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.x86_64/{libswt-gtk-4974r8.so => libswt-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.x86_64/{libswt-pi3-gtk-4974r8.so => libswt-pi3-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.x86_64/{libswt-pi4-gtk-4974r8.so => libswt-pi4-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.x86_64/{libswt-webkit-gtk-4974r8.so => libswt-webkit-gtk-4974r9.so} (100%) rename binaries/org.eclipse.swt.win32.win32.aarch64/{swt-awt-win32-4974r8.dll => swt-awt-win32-4974r9.dll} (100%) rename binaries/org.eclipse.swt.win32.win32.aarch64/{swt-gdip-win32-4974r8.dll => swt-gdip-win32-4974r9.dll} (100%) rename binaries/org.eclipse.swt.win32.win32.aarch64/{swt-osversion-win32-4974r8.dll => swt-osversion-win32-4974r9.dll} (100%) rename binaries/org.eclipse.swt.win32.win32.aarch64/{swt-wgl-win32-4974r8.dll => swt-wgl-win32-4974r9.dll} (100%) rename binaries/org.eclipse.swt.win32.win32.aarch64/{swt-win32-4974r8.dll => swt-win32-4974r9.dll} (100%) rename binaries/org.eclipse.swt.win32.win32.x86_64/{swt-awt-win32-4974r8.dll => swt-awt-win32-4974r9.dll} (100%) rename binaries/org.eclipse.swt.win32.win32.x86_64/{swt-gdip-win32-4974r8.dll => swt-gdip-win32-4974r9.dll} (100%) rename binaries/org.eclipse.swt.win32.win32.x86_64/{swt-osversion-win32-4974r8.dll => swt-osversion-win32-4974r9.dll} (100%) rename binaries/org.eclipse.swt.win32.win32.x86_64/{swt-wgl-win32-4974r8.dll => swt-wgl-win32-4974r9.dll} (100%) rename binaries/org.eclipse.swt.win32.win32.x86_64/{swt-win32-4974r8.dll => swt-win32-4974r9.dll} (100%) diff --git a/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-awt-cocoa-4974r8.jnilib b/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-awt-cocoa-4974r8.jnilib deleted file mode 100755 index e260a120925..00000000000 --- a/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-awt-cocoa-4974r8.jnilib +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3c86c4e9806966f279b43bf0aaf1a05ee32084b989dbc93c07bac6ae6524f0b2 -size 51920 diff --git a/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-awt-cocoa-4974r9.jnilib b/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-awt-cocoa-4974r9.jnilib new file mode 100755 index 00000000000..193936f7d75 --- /dev/null +++ b/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-awt-cocoa-4974r9.jnilib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b91a45d91cda3adf3f5ed3b6649f2f7db10b26d82e444be48081e1d1dba80ff0 +size 51920 diff --git a/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-cocoa-4974r8.jnilib b/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-cocoa-4974r8.jnilib deleted file mode 100755 index 109c95ad9ac..00000000000 --- a/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-cocoa-4974r8.jnilib +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d301ef8585d5cd866068833cda379455f2978e9dab1487ab6cc2d8d8a1268e43 -size 576448 diff --git a/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-cocoa-4974r9.jnilib b/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-cocoa-4974r9.jnilib new file mode 100755 index 00000000000..d2cf553084a --- /dev/null +++ b/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-cocoa-4974r9.jnilib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f6d7d7f093d1b60b02db555814c1da2a85e4e2c590a6533697d9c1d4f0673645 +size 576448 diff --git a/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-pi-cocoa-4974r8.jnilib b/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-pi-cocoa-4974r8.jnilib deleted file mode 100755 index b35950e3afd..00000000000 --- a/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-pi-cocoa-4974r8.jnilib +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a42fe403f58fe11def681c83f4b2901fd69fffc7f241f5dea2d3e02f5a6c87e6 -size 299216 diff --git a/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-pi-cocoa-4974r9.jnilib b/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-pi-cocoa-4974r9.jnilib new file mode 100755 index 00000000000..6c04d9d152d --- /dev/null +++ b/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-pi-cocoa-4974r9.jnilib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3faad221ca39561f0eb501493fa2e93f4d3f388d668904ed2269067dfe0fc71a +size 299216 diff --git a/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-awt-cocoa-4974r8.jnilib b/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-awt-cocoa-4974r8.jnilib deleted file mode 100755 index 3c47aa48318..00000000000 --- a/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-awt-cocoa-4974r8.jnilib +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:798b62759bbc4863e06ffdb6cb4e1f2dad4a25eb54969186c2e5bca427118404 -size 27184 diff --git a/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-awt-cocoa-4974r9.jnilib b/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-awt-cocoa-4974r9.jnilib new file mode 100755 index 00000000000..076d7d9f0ea --- /dev/null +++ b/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-awt-cocoa-4974r9.jnilib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dc89f6dafcfd5726e26c1f761cf51992ce1624680d6a17052841b49579b9e0b9 +size 27184 diff --git a/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-cocoa-4974r8.jnilib b/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-cocoa-4974r8.jnilib deleted file mode 100755 index 00af6b76c12..00000000000 --- a/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-cocoa-4974r8.jnilib +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:42f500c1385e93afb3079b4d5ab0274cbfb90cd9d231bf7be332f557b563563c -size 510304 diff --git a/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-cocoa-4974r9.jnilib b/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-cocoa-4974r9.jnilib new file mode 100755 index 00000000000..5af53cf85e1 --- /dev/null +++ b/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-cocoa-4974r9.jnilib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d9dc5f0aa8cf0680e8884226c7f4f4b355845b48841cc733fe6235fd6f7d58f +size 510304 diff --git a/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-pi-cocoa-4974r8.jnilib b/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-pi-cocoa-4974r8.jnilib deleted file mode 100755 index 959936fa351..00000000000 --- a/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-pi-cocoa-4974r8.jnilib +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c0e90169bfc31ead9a45414b2544309a472a37c69f36e6d134edfe81f38d8eff -size 258112 diff --git a/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-pi-cocoa-4974r9.jnilib b/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-pi-cocoa-4974r9.jnilib new file mode 100755 index 00000000000..30f122ad952 --- /dev/null +++ b/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-pi-cocoa-4974r9.jnilib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:349229fe2d62df988537749c5e5458025093f99ea43cbe2d32e964542368a806 +size 258112 diff --git a/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-atk-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-atk-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-atk-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-atk-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-awt-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-awt-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-awt-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-awt-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-cairo-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-cairo-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-cairo-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-cairo-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-glx-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-glx-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-glx-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-glx-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-pi3-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-pi3-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-pi3-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-pi3-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-webkit-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-webkit-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-webkit-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-webkit-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-atk-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-atk-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-atk-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-atk-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-awt-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-awt-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-awt-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-awt-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-cairo-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-cairo-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-cairo-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-cairo-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-glx-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-glx-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-glx-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-glx-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-pi3-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-pi3-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-pi3-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-pi3-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-webkit-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-webkit-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-webkit-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-webkit-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-atk-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-atk-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-atk-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-atk-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-awt-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-awt-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-awt-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-awt-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-cairo-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-cairo-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-cairo-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-cairo-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-glx-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-glx-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-glx-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-glx-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-pi3-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-pi3-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-pi3-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-pi3-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-webkit-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-webkit-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-webkit-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-webkit-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-atk-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-atk-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-atk-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-atk-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-awt-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-awt-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-awt-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-awt-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-cairo-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-cairo-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-cairo-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-cairo-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-glx-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-glx-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-glx-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-glx-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi3-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi3-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi3-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi3-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi4-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi4-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi4-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi4-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-webkit-gtk-4974r8.so b/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-webkit-gtk-4974r9.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-webkit-gtk-4974r8.so rename to binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-webkit-gtk-4974r9.so diff --git a/binaries/org.eclipse.swt.win32.win32.aarch64/swt-awt-win32-4974r8.dll b/binaries/org.eclipse.swt.win32.win32.aarch64/swt-awt-win32-4974r9.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.aarch64/swt-awt-win32-4974r8.dll rename to binaries/org.eclipse.swt.win32.win32.aarch64/swt-awt-win32-4974r9.dll diff --git a/binaries/org.eclipse.swt.win32.win32.aarch64/swt-gdip-win32-4974r8.dll b/binaries/org.eclipse.swt.win32.win32.aarch64/swt-gdip-win32-4974r9.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.aarch64/swt-gdip-win32-4974r8.dll rename to binaries/org.eclipse.swt.win32.win32.aarch64/swt-gdip-win32-4974r9.dll diff --git a/binaries/org.eclipse.swt.win32.win32.aarch64/swt-osversion-win32-4974r8.dll b/binaries/org.eclipse.swt.win32.win32.aarch64/swt-osversion-win32-4974r9.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.aarch64/swt-osversion-win32-4974r8.dll rename to binaries/org.eclipse.swt.win32.win32.aarch64/swt-osversion-win32-4974r9.dll diff --git a/binaries/org.eclipse.swt.win32.win32.aarch64/swt-wgl-win32-4974r8.dll b/binaries/org.eclipse.swt.win32.win32.aarch64/swt-wgl-win32-4974r9.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.aarch64/swt-wgl-win32-4974r8.dll rename to binaries/org.eclipse.swt.win32.win32.aarch64/swt-wgl-win32-4974r9.dll diff --git a/binaries/org.eclipse.swt.win32.win32.aarch64/swt-win32-4974r8.dll b/binaries/org.eclipse.swt.win32.win32.aarch64/swt-win32-4974r9.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.aarch64/swt-win32-4974r8.dll rename to binaries/org.eclipse.swt.win32.win32.aarch64/swt-win32-4974r9.dll diff --git a/binaries/org.eclipse.swt.win32.win32.x86_64/swt-awt-win32-4974r8.dll b/binaries/org.eclipse.swt.win32.win32.x86_64/swt-awt-win32-4974r9.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.x86_64/swt-awt-win32-4974r8.dll rename to binaries/org.eclipse.swt.win32.win32.x86_64/swt-awt-win32-4974r9.dll diff --git a/binaries/org.eclipse.swt.win32.win32.x86_64/swt-gdip-win32-4974r8.dll b/binaries/org.eclipse.swt.win32.win32.x86_64/swt-gdip-win32-4974r9.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.x86_64/swt-gdip-win32-4974r8.dll rename to binaries/org.eclipse.swt.win32.win32.x86_64/swt-gdip-win32-4974r9.dll diff --git a/binaries/org.eclipse.swt.win32.win32.x86_64/swt-osversion-win32-4974r8.dll b/binaries/org.eclipse.swt.win32.win32.x86_64/swt-osversion-win32-4974r9.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.x86_64/swt-osversion-win32-4974r8.dll rename to binaries/org.eclipse.swt.win32.win32.x86_64/swt-osversion-win32-4974r9.dll diff --git a/binaries/org.eclipse.swt.win32.win32.x86_64/swt-wgl-win32-4974r8.dll b/binaries/org.eclipse.swt.win32.win32.x86_64/swt-wgl-win32-4974r9.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.x86_64/swt-wgl-win32-4974r8.dll rename to binaries/org.eclipse.swt.win32.win32.x86_64/swt-wgl-win32-4974r9.dll diff --git a/binaries/org.eclipse.swt.win32.win32.x86_64/swt-win32-4974r8.dll b/binaries/org.eclipse.swt.win32.win32.x86_64/swt-win32-4974r9.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.x86_64/swt-win32-4974r8.dll rename to binaries/org.eclipse.swt.win32.win32.x86_64/swt-win32-4974r9.dll diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/common/org/eclipse/swt/internal/Library.java b/bundles/org.eclipse.swt/Eclipse SWT PI/common/org/eclipse/swt/internal/Library.java index cb6dab44c27..08ab37014f5 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/common/org/eclipse/swt/internal/Library.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/common/org/eclipse/swt/internal/Library.java @@ -35,7 +35,7 @@ public class Library { /** * SWT revision number (must be >= 0) */ - static int REVISION = 8; + static int REVISION = 9; /** * The JAVA and SWT versions diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/library/make_common.mak b/bundles/org.eclipse.swt/Eclipse SWT/common/library/make_common.mak index 5cc4d808bbf..d4df4b1fc21 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/library/make_common.mak +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/library/make_common.mak @@ -14,4 +14,4 @@ maj_ver=4 min_ver=974 -rev=8 +rev=9 From c76abe184e04e9275298d6b5111005dd2aff96bb Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Sun, 12 Jul 2026 18:26:18 +0200 Subject: [PATCH 18/46] [Cocoa] Replace deprecated NSProgressIndicatorPreferredThickness NSProgressIndicatorPreferredThickness is deprecated since macOS 10.14 in favor of using controlSize and sizeToFit. Add a binding for NSProgressIndicator#sizeToFit and use it in ProgressBar#computeSize to determine the default thickness for the progress indicator's control size, restoring the original frame afterwards. Contributes to https://github.com/eclipse-platform/eclipse.platform.swt/issues/3214 Co-Authored-By: Claude Sonnet 5 # Conflicts: # bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras # bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java --- .../swt/internal/cocoa/AppKitFull.bridgesupport.extras | 4 +++- .../eclipse/swt/internal/cocoa/NSProgressIndicator.java | 9 +++++---- .../cocoa/org/eclipse/swt/internal/cocoa/OS.java | 1 - .../cocoa/org/eclipse/swt/widgets/ProgressBar.java | 6 +++++- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras index 50395fd5c0a..512bd54578f 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras @@ -2376,6 +2376,9 @@ + + + @@ -4507,7 +4510,6 @@ - diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSProgressIndicator.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSProgressIndicator.java index 3397ada72d7..d430ad015e9 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSProgressIndicator.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSProgressIndicator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2019 IBM Corporation and others. + * Copyright (c) 2000, 2026 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -7,9 +7,6 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.swt.internal.cocoa; @@ -63,6 +60,10 @@ public void setUsesThreadedAnimation(boolean usesThreadedAnimation) { OS.objc_msgSend(this.id, OS.sel_setUsesThreadedAnimation_, usesThreadedAnimation); } +public void sizeToFit() { + OS.objc_msgSend(this.id, OS.sel_sizeToFit); +} + public void startAnimation(id sender) { OS.objc_msgSend(this.id, OS.sel_startAnimation_, sender != null ? sender.id : 0); } diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java index c1f1a1c36eb..13bbe204d10 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java @@ -2281,7 +2281,6 @@ public static Selector getSelector (long value) { public static final int NSPortraitOrientation = 0; public static final int NSPrintPanelShowsPageSetupAccessory = 256; public static final int NSPrintPanelShowsPrintSelection = 32; -public static final int NSProgressIndicatorPreferredThickness = 14; public static final int NSRegularSquareBezelStyle = 2; public static final int NSResizableWindowMask = 8; public static final int NSRightMouseDown = 3; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/ProgressBar.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/ProgressBar.java index eac59b1a91f..a01615d5b55 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/ProgressBar.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/ProgressBar.java @@ -87,7 +87,11 @@ static int checkStyle (int style) { @Override public Point computeSize (int wHint, int hHint, boolean changed) { checkWidget(); - int size = OS.NSProgressIndicatorPreferredThickness; + NSProgressIndicator widget = (NSProgressIndicator)view; + NSRect oldFrame = widget.frame(); + widget.sizeToFit(); + int size = (int)widget.frame().height; + widget.setFrame(oldFrame); int width = 0, height = 0; if ((style & SWT.HORIZONTAL) != 0) { height = size; From 2047c61737789715d81e335e60a614013db00f9a Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Mon, 20 Jul 2026 19:45:46 +0200 Subject: [PATCH 19/46] [Cocoa] Replace deprecated Alert Style and Event Modifier Flag constants The macOS AppKit framework deprecated the old-style NSAlert alert style constants in macOS 10.12 (Sierra) in favour of the NSAlertStyle enum, and the old-style NSEvent modifier flag constants in macOS 10.12 in favour of the NSEventModifierFlags option set type. This change replaces all seven deprecated constants throughout the SWT macOS/Cocoa implementation with their modern equivalents, eliminating compiler deprecation warnings and improving forward compatibility with future macOS SDK versions. Replaced constants (values are unchanged): NSWarningAlertStyle -> NSAlertStyleWarning (0) NSInformationalAlertStyle -> NSAlertStyleInformational (1) NSCriticalAlertStyle -> NSAlertStyleCritical (2) NSShiftKeyMask -> NSEventModifierFlagShift (131072) NSControlKeyMask -> NSEventModifierFlagControl (262144) NSCommandKeyMask -> NSEventModifierFlagCommand (1048576) NSHelpKeyMask -> NSEventModifierFlagHelp (4194304) Contributes to https://github.com/eclipse-platform/eclipse.platform.swt/issues/3214 --- .../cocoa/org/eclipse/swt/dnd/DropTarget.java | 2 +- .../swt/internal/cocoa/AppKitFull.bridgesupport | 14 +++++++------- .../internal/cocoa/AppKitFull.bridgesupport.extras | 14 +++++++------- .../cocoa/org/eclipse/swt/internal/cocoa/OS.java | 14 +++++++------- .../cocoa/org/eclipse/swt/widgets/Combo.java | 8 ++++---- .../cocoa/org/eclipse/swt/widgets/Control.java | 14 +++++++------- .../cocoa/org/eclipse/swt/widgets/Display.java | 12 ++++++------ .../cocoa/org/eclipse/swt/widgets/Link.java | 2 +- .../cocoa/org/eclipse/swt/widgets/Menu.java | 2 +- .../cocoa/org/eclipse/swt/widgets/MenuItem.java | 12 ++++++------ .../cocoa/org/eclipse/swt/widgets/MessageBox.java | 8 ++++---- .../cocoa/org/eclipse/swt/widgets/Sash.java | 2 +- .../cocoa/org/eclipse/swt/widgets/Shell.java | 2 +- .../cocoa/org/eclipse/swt/widgets/Table.java | 4 ++-- .../cocoa/org/eclipse/swt/widgets/Text.java | 6 +++--- .../cocoa/org/eclipse/swt/widgets/Tracker.java | 8 ++++---- .../cocoa/org/eclipse/swt/widgets/TrayItem.java | 2 +- .../cocoa/org/eclipse/swt/widgets/Tree.java | 4 ++-- .../cocoa/org/eclipse/swt/widgets/Widget.java | 6 +++--- 19 files changed, 68 insertions(+), 68 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/cocoa/org/eclipse/swt/dnd/DropTarget.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/cocoa/org/eclipse/swt/dnd/DropTarget.java index c9df3a4b9f5..d327f475414 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/cocoa/org/eclipse/swt/dnd/DropTarget.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/cocoa/org/eclipse/swt/dnd/DropTarget.java @@ -575,7 +575,7 @@ int getOperationFromKeyState() { if (currEvent != null) { long modifiers = currEvent.modifierFlags(); boolean option = (modifiers & OS.NSAlternateKeyMask) == OS.NSAlternateKeyMask; - boolean control = (modifiers & OS.NSControlKeyMask) == OS.NSControlKeyMask; + boolean control = (modifiers & OS.NSEventModifierFlagControl) == OS.NSEventModifierFlagControl; if (control && option) return DND.DROP_DEFAULT; if (control) return DND.DROP_LINK; if (option) return DND.DROP_COPY; diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport index c9b09006ac9..5466b7020c6 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport @@ -1198,6 +1198,9 @@ + + + @@ -1421,7 +1424,6 @@ - @@ -1466,7 +1468,6 @@ - @@ -1477,7 +1478,6 @@ - @@ -1545,6 +1545,10 @@ + + + + @@ -1726,7 +1730,6 @@ - @@ -1783,7 +1786,6 @@ - @@ -2207,7 +2209,6 @@ - @@ -2522,7 +2523,6 @@ - diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras index 512bd54578f..18d835f349f 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras @@ -4373,6 +4373,9 @@ + + + @@ -4405,20 +4408,17 @@ - - - @@ -4433,6 +4433,10 @@ + + + + @@ -4449,7 +4453,6 @@ - @@ -4465,7 +4468,6 @@ - @@ -4525,7 +4527,6 @@ - @@ -4562,7 +4563,6 @@ - diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java index 13bbe204d10..ea852de5a13 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java @@ -2144,6 +2144,9 @@ public static Selector getSelector (long value) { /** Constants */ public static final int NSAlertFirstButtonReturn = 1000; public static final int NSAlertSecondButtonReturn = 1001; +public static final int NSAlertStyleCritical = 2; +public static final int NSAlertStyleInformational = 1; +public static final int NSAlertStyleWarning = 0; public static final int NSAlertThirdButtonReturn = 1002; public static final int NSAlphaFirstBitmapFormat = 1; public static final int NSAlphaNonpremultipliedBitmapFormat = 2; @@ -2176,14 +2179,11 @@ public static Selector getSelector (long value) { public static final int NSCarriageReturnCharacter = 13; public static final int NSClosePathBezierPathElement = 3; public static final int NSColorSpaceModelRGB = 1; -public static final int NSCommandKeyMask = 1048576; public static final int NSCompositingOperationClear = 0; public static final int NSCompositingOperationCopy = 1; public static final int NSCompositingOperationSourceAtop = 5; public static final int NSCompositingOperationSourceOver = 2; public static final int NSContentsCellMask = 1; -public static final int NSControlKeyMask = 262144; -public static final int NSCriticalAlertStyle = 2; public static final int NSCurveToBezierPathElement = 2; public static final int NSDatePickerStyleClockAndCalendar = 1; public static final int NSDatePickerStyleTextField = 2; @@ -2198,6 +2198,10 @@ public static Selector getSelector (long value) { public static final int NSDragOperationNone = 0; public static final int NSEnterCharacter = 3; public static final int NSEvenOddWindingRule = 1; +public static final int NSEventModifierFlagCommand = 1048576; +public static final int NSEventModifierFlagControl = 262144; +public static final int NSEventModifierFlagHelp = 4194304; +public static final int NSEventModifierFlagShift = 131072; public static final int NSEventPhaseBegan = 1; public static final int NSEventPhaseCancelled = 16; public static final int NSEventPhaseEnded = 8; @@ -2214,7 +2218,6 @@ public static Selector getSelector (long value) { public static final int NSFontPanelModeMaskAllEffects = 1048320; public static final int NSFontPanelModeMaskAllModes = -1; public static final int NSHelpFunctionKey = 63302; -public static final int NSHelpKeyMask = 4194304; public static final int NSHourMinuteDatePickerElementFlag = 12; public static final int NSHourMinuteSecondDatePickerElementFlag = 14; public static final int NSImageAbove = 5; @@ -2230,7 +2233,6 @@ public static Selector getSelector (long value) { public static final int NSImageOnly = 1; public static final int NSImageOverlaps = 6; public static final int NSImageScaleNone = 2; -public static final int NSInformationalAlertStyle = 1; public static final int NSItalicFontMask = 1; public static final int NSKeyDown = 10; public static final int NSKeyUp = 11; @@ -2296,7 +2298,6 @@ public static Selector getSelector (long value) { public static final int NSScrollerKnobSlot = 6; public static final int NSScrollerStyleLegacy = 0; public static final int NSScrollerStyleOverlay = 1; -public static final int NSShiftKeyMask = 131072; public static final int NSSquareLineCapStyle = 2; public static final int NSStatusWindowLevel = 25; public static final int NSStringDrawingUsesLineFragmentOrigin = 1; @@ -2333,7 +2334,6 @@ public static Selector getSelector (long value) { public static final int NSViewMinXMargin = 1; public static final int NSViewMinYMargin = 8; public static final int NSViewWidthSizable = 2; -public static final int NSWarningAlertStyle = 0; public static final int NSWindowAbove = 1; public static final int NSWindowBelow = -1; public static final int NSWindowCollectionBehaviorFullScreenAuxiliary = 256; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Combo.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Combo.java index 0597becb231..76e216736d1 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Combo.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Combo.java @@ -1445,9 +1445,9 @@ boolean sendKeyEvent (NSEvent nsEvent, int type) { int stateMask = 0; long modifierFlags = nsEvent.modifierFlags(); if ((modifierFlags & OS.NSAlternateKeyMask) != 0) stateMask |= SWT.ALT; - if ((modifierFlags & OS.NSShiftKeyMask) != 0) stateMask |= SWT.SHIFT; - if ((modifierFlags & OS.NSControlKeyMask) != 0) stateMask |= SWT.CONTROL; - if ((modifierFlags & OS.NSCommandKeyMask) != 0) stateMask |= SWT.COMMAND; + if ((modifierFlags & OS.NSEventModifierFlagShift) != 0) stateMask |= SWT.SHIFT; + if ((modifierFlags & OS.NSEventModifierFlagControl) != 0) stateMask |= SWT.CONTROL; + if ((modifierFlags & OS.NSEventModifierFlagCommand) != 0) stateMask |= SWT.COMMAND; if (type != SWT.KeyDown) return result; short keyCode = nsEvent.keyCode (); if (stateMask == SWT.COMMAND) { @@ -1484,7 +1484,7 @@ boolean sendTrackingKeyEvent (NSEvent nsEvent, int type) { * queue. */ long modifiers = nsEvent.modifierFlags(); - if ((modifiers & OS.NSShiftKeyMask) == 0) { + if ((modifiers & OS.NSEventModifierFlagShift) == 0) { short keyCode = nsEvent.keyCode (); switch (keyCode) { case 125: /* Arrow Down */ diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Control.java index 8c2238e83cf..f28f96b24da 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Control.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Control.java @@ -1044,7 +1044,7 @@ void doCommandBySelector (long id, long sel, long selector) { * is down, because we likely triggered the current key sequence via flagsChanged. */ long modifiers = nsEvent.modifierFlags(); - if (s.keyInputHappened == false || (modifiers & OS.NSCommandKeyMask) != 0) { + if (s.keyInputHappened == false || (modifiers & OS.NSEventModifierFlagCommand) != 0) { s.keyInputHappened = true; boolean [] consume = new boolean [1]; if (translateTraversal (nsEvent.keyCode (), nsEvent, consume)) return; @@ -1363,9 +1363,9 @@ void flagsChanged (long id, long sel, long theEvent) { int keyCode = Display.translateKey (nsEvent.keyCode ()); switch (keyCode) { case SWT.ALT: mask = OS.NSAlternateKeyMask; break; - case SWT.CONTROL: mask = OS.NSControlKeyMask; break; - case SWT.COMMAND: mask = OS.NSCommandKeyMask; break; - case SWT.SHIFT: mask = OS.NSShiftKeyMask; break; + case SWT.CONTROL: mask = OS.NSEventModifierFlagControl; break; + case SWT.COMMAND: mask = OS.NSEventModifierFlagCommand; break; + case SWT.SHIFT: mask = OS.NSEventModifierFlagShift; break; case SWT.CAPS_LOCK: Event event = new Event(); event.keyCode = keyCode; @@ -2558,7 +2558,7 @@ boolean mouseEvent (long id, long sel, long theEvent, int type) { switch (nsType) { case OS.NSLeftMouseDown: - if (nsEvent.clickCount() == 1 && (nsEvent.modifierFlags() & OS.NSControlKeyMask) == 0 && (state & DRAG_DETECT) != 0 && hooks (SWT.DragDetect)) { + if (nsEvent.clickCount() == 1 && (nsEvent.modifierFlags() & OS.NSEventModifierFlagControl) == 0 && (state & DRAG_DETECT) != 0 && hooks (SWT.DragDetect)) { consume = new boolean[1]; NSPoint location = view.convertPoint_fromView_(nsEvent.locationInWindow(), null); if (!view.isFlipped ()) { @@ -4783,7 +4783,7 @@ boolean translateTraversal (int key, NSEvent theEvent, boolean [] consume) { } case 48: /* Tab */ { long modifiers = theEvent.modifierFlags (); - boolean next = (modifiers & OS.NSShiftKeyMask) == 0; + boolean next = (modifiers & OS.NSEventModifierFlagShift) == 0; detail = next ? SWT.TRAVERSE_TAB_NEXT : SWT.TRAVERSE_TAB_PREVIOUS; break; } @@ -4799,7 +4799,7 @@ boolean translateTraversal (int key, NSEvent theEvent, boolean [] consume) { case 121: /* Page down */ { all = true; long modifiers = theEvent.modifierFlags (); - if ((modifiers & OS.NSControlKeyMask) == 0) return false; + if ((modifiers & OS.NSEventModifierFlagControl) == 0) return false; detail = key == 121 /* Page down */ ? SWT.TRAVERSE_PAGE_NEXT : SWT.TRAVERSE_PAGE_PREVIOUS; break; } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java index 25f78cbc179..c2524f8e8c9 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java @@ -1103,7 +1103,7 @@ void createMainMenu () { title = NSString.stringWith(SWT.getMessage("SWT_HideOthers")); menuItem = appleMenu.addItemWithTitle(title, OS.sel_hideOtherApplications_, NSString.stringWith("h")); - menuItem.setKeyEquivalentModifierMask(OS.NSCommandKeyMask | OS.NSAlternateKeyMask); + menuItem.setKeyEquivalentModifierMask(OS.NSEventModifierFlagCommand | OS.NSAlternateKeyMask); menuItem.setTarget(applicationDelegate); title = NSString.stringWith(SWT.getMessage("SWT_ShowAll")); @@ -3924,9 +3924,9 @@ boolean performKeyEquivalent(NSWindow window, NSEvent nsEvent) { long selector = 0; long modifierFlags = nsEvent.modifierFlags(); if ((modifierFlags & OS.NSAlternateKeyMask) != 0) stateMask |= SWT.ALT; - if ((modifierFlags & OS.NSShiftKeyMask) != 0) stateMask |= SWT.SHIFT; - if ((modifierFlags & OS.NSControlKeyMask) != 0) stateMask |= SWT.CONTROL; - if ((modifierFlags & OS.NSCommandKeyMask) != 0) stateMask |= SWT.COMMAND; + if ((modifierFlags & OS.NSEventModifierFlagShift) != 0) stateMask |= SWT.SHIFT; + if ((modifierFlags & OS.NSEventModifierFlagControl) != 0) stateMask |= SWT.CONTROL; + if ((modifierFlags & OS.NSEventModifierFlagCommand) != 0) stateMask |= SWT.COMMAND; if (stateMask == SWT.COMMAND) { short keyCode = nsEvent.keyCode (); switch (keyCode) { @@ -5679,7 +5679,7 @@ void applicationSendEvent (long id, long sel, long event) { * Feature in Cocoa. The help key triggers context-sensitive help but doesn't get forwarded to the window as a key event. * If the event is destined for the key window, is the help key, and is an NSKeyDown, send it directly to the window first. */ - if (window != null && window.isKeyWindow() && nsEvent.type() == OS.NSKeyDown && (nsEvent.modifierFlags() & OS.NSHelpKeyMask) != 0) { + if (window != null && window.isKeyWindow() && nsEvent.type() == OS.NSKeyDown && (nsEvent.modifierFlags() & OS.NSEventModifierFlagHelp) != 0) { window.sendEvent(nsEvent); } @@ -5687,7 +5687,7 @@ void applicationSendEvent (long id, long sel, long event) { * Feature in Cocoa. NSKeyUp events are not delivered to the window if the command key is down. * If the event is destined for the key window, and it's a key up and the command key is down, send it directly to the window. */ - if (window != null && window.isKeyWindow() && nsEvent.type() == OS.NSKeyUp && (nsEvent.modifierFlags() & OS.NSCommandKeyMask) != 0) { + if (window != null && window.isKeyWindow() && nsEvent.type() == OS.NSKeyUp && (nsEvent.modifierFlags() & OS.NSEventModifierFlagCommand) != 0) { window.sendEvent(nsEvent); } else { objc_super super_struct = new objc_super (); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Link.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Link.java index 6d075f0136a..c1f1fd465a7 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Link.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Link.java @@ -824,7 +824,7 @@ int traversalCode (int key, NSEvent theEvent) { int bits = super.traversalCode (key, theEvent); if (key == 48 /* Tab */ && theEvent != null) { long modifierFlags = theEvent.modifierFlags(); - boolean next = (modifierFlags & OS.NSShiftKeyMask) == 0; + boolean next = (modifierFlags & OS.NSEventModifierFlagShift) == 0; if (next && focusIndex < offsets.length - 1) { return bits & ~ SWT.TRAVERSE_TAB_NEXT; } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Menu.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Menu.java index 2bdf5da08c8..9c5bbfab320 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Menu.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Menu.java @@ -389,7 +389,7 @@ void createItem (MenuItem item, int index) { long keyEquiv = 0; if (keyEquivString != null) { keyEquiv = keyEquivString.characterAtIndex(0); - if ((keyMask & OS.NSCommandKeyMask) != 0) keyEquiv |= SWT.COMMAND; + if ((keyMask & OS.NSEventModifierFlagCommand) != 0) keyEquiv |= SWT.COMMAND; if ((keyMask & OS.NSAlternateKeyMask) != 0) keyEquiv |= SWT.ALT; item.accelerator = (int) keyEquiv; } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/MenuItem.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/MenuItem.java index 512ef0ab5ca..5ddd1191c6d 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/MenuItem.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/MenuItem.java @@ -623,9 +623,9 @@ public void setAccelerator (int accelerator) { nsItem.setKeyEquivalent (nsstring.lowercaseString()); nsstring.release(); int mask = 0; - if ((accelerator & SWT.SHIFT) != 0) mask |= OS.NSShiftKeyMask; - if ((accelerator & SWT.CONTROL) != 0) mask |= OS.NSControlKeyMask; - if ((accelerator & SWT.COMMAND) != 0) mask |= OS.NSCommandKeyMask; + if ((accelerator & SWT.SHIFT) != 0) mask |= OS.NSEventModifierFlagShift; + if ((accelerator & SWT.CONTROL) != 0) mask |= OS.NSEventModifierFlagControl; + if ((accelerator & SWT.COMMAND) != 0) mask |= OS.NSEventModifierFlagCommand; if ((accelerator & SWT.ALT) != 0) mask |= OS.NSAlternateKeyMask; nsItem.setKeyEquivalentModifierMask (mask); } @@ -951,10 +951,10 @@ boolean updateAccelerator (boolean show) { if (i < buffer.length && buffer [i] == '\t') { for (j = i + 1; j < buffer.length; j++) { switch (buffer [j]) { - case '\u2303': mask |= OS.NSControlKeyMask; i++; break; + case '\u2303': mask |= OS.NSEventModifierFlagControl; i++; break; case '\u2325': mask |= OS.NSAlternateKeyMask; i++; break; - case '\u21E7': mask |= OS.NSShiftKeyMask; i++; break; - case '\u2318': mask |= OS.NSCommandKeyMask; i++; break; + case '\u21E7': mask |= OS.NSEventModifierFlagShift; i++; break; + case '\u2318': mask |= OS.NSEventModifierFlagCommand; i++; break; default: j = buffer.length; break; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/MessageBox.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/MessageBox.java index 53684bcb4d2..2358dc0186b 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/MessageBox.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/MessageBox.java @@ -151,16 +151,16 @@ public String getMessage () { */ public int open () { NSAlert alert = (NSAlert) new NSAlert().alloc().init(); - int alertType = OS.NSInformationalAlertStyle; + int alertType = OS.NSAlertStyleInformational; if ((style & SWT.ICON_ERROR) != 0) { - alertType = OS.NSCriticalAlertStyle; + alertType = OS.NSAlertStyleCritical; } if (((style & SWT.ICON_INFORMATION) != 0) || ((style & SWT.ICON_WORKING) != 0) || ((style & SWT.ICON_QUESTION) != 0)) { - alertType = OS.NSInformationalAlertStyle; + alertType = OS.NSAlertStyleInformational; alert.setIcon(NSImage.imageNamed(OS.NSImageNameInfo)); } if ((style & SWT.ICON_WARNING) != 0) { - alertType = OS.NSWarningAlertStyle; + alertType = OS.NSAlertStyleWarning; alert.setIcon(NSImage.imageNamed(OS.NSImageNameCaution)); } alert.setAlertStyle(alertType); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Sash.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Sash.java index e9792688bc5..200a9ec1e98 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Sash.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Sash.java @@ -305,7 +305,7 @@ boolean sendKeyEvent(NSEvent nsEvent, int type) { int xChange = 0, yChange = 0; int stepSize = PAGE_INCREMENT; long modifiers = nsEvent.modifierFlags(); - if ((modifiers & OS.NSControlKeyMask) != 0) stepSize = INCREMENT; + if ((modifiers & OS.NSEventModifierFlagControl) != 0) stepSize = INCREMENT; if ((style & SWT.VERTICAL) != 0) { if (keyCode == 126 || keyCode == 125) break; xChange = keyCode == 123 ? -stepSize : stepSize; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Shell.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Shell.java index 9ef9aa678ea..0029ba4b3bb 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Shell.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Shell.java @@ -2515,7 +2515,7 @@ void windowSendEvent (long id, long sel, long event) { * swallowed to handle native traversal. If we find that, force the key event to * the first responder. */ - if ((nsEvent.modifierFlags() & OS.NSControlKeyMask) != 0) { + if ((nsEvent.modifierFlags() & OS.NSEventModifierFlagControl) != 0) { NSString chars = nsEvent.characters(); if (chars != null && chars.length() == 1) { diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Table.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Table.java index 49549fcf9ca..5d6825ec32a 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Table.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Table.java @@ -258,7 +258,7 @@ boolean canDragRowsWithIndexes_atPoint(long id, long sel, long rowIndexes, NSPoi boolean drag = (state & DRAG_DETECT) != 0 && hooks (SWT.DragDetect); if (drag) { - if (!widget.isRowSelected(row) && (modifiers & (OS.NSCommandKeyMask | OS.NSShiftKeyMask | OS.NSAlternateKeyMask)) == 0) { + if (!widget.isRowSelected(row) && (modifiers & (OS.NSEventModifierFlagCommand | OS.NSEventModifierFlagShift | OS.NSAlternateKeyMask)) == 0) { NSIndexSet set = (NSIndexSet)new NSIndexSet().alloc(); set = set.initWithIndex(row); widget.selectRowIndexes (set, false); @@ -2080,7 +2080,7 @@ void mouseDown (long id, long sel, long theEvent) { // which is interpreted as a single click that clears the selection. Fix is to ignore control-click if the // view has a context menu. NSEvent event = new NSEvent(theEvent); - if ((event.modifierFlags() & OS.NSControlKeyMask) != 0) return; + if ((event.modifierFlags() & OS.NSEventModifierFlagControl) != 0) return; } super.mouseDown(id, sel, theEvent); } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Text.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Text.java index ee965adcccd..17fd2df1630 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Text.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Text.java @@ -1714,7 +1714,7 @@ boolean sendKeyEvent (NSEvent nsEvent, int type) { if (!result) return result; if (type != SWT.KeyDown) return result; long modifierFlags = nsEvent.modifierFlags(); - if ((modifierFlags & OS.NSCommandKeyMask) != 0) { + if ((modifierFlags & OS.NSEventModifierFlagCommand) != 0) { short keyCode = nsEvent.keyCode (); switch (keyCode) { case 7: /* X */ @@ -2460,8 +2460,8 @@ int traversalCode (int key, NSEvent theEvent) { bits &= ~SWT.TRAVERSE_RETURN; if (key == 48 /* Tab */ && theEvent != null) { long modifiers = theEvent.modifierFlags (); - boolean next = (modifiers & OS.NSShiftKeyMask) == 0; - if (next && (modifiers & OS.NSControlKeyMask) == 0) { + boolean next = (modifiers & OS.NSEventModifierFlagShift) == 0; + if (next && (modifiers & OS.NSEventModifierFlagControl) == 0) { bits &= ~(SWT.TRAVERSE_TAB_NEXT | SWT.TRAVERSE_TAB_PREVIOUS); } } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Tracker.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Tracker.java index aa8e2507e93..374a5f3c93d 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Tracker.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Tracker.java @@ -559,9 +559,9 @@ void key (NSEvent nsEvent) { int mask = 0; switch (keyCode) { case SWT.ALT: mask = OS.NSAlternateKeyMask; break; - case SWT.CONTROL: mask = OS.NSControlKeyMask; break; - case SWT.COMMAND: mask = OS.NSCommandKeyMask; break; - case SWT.SHIFT: mask = OS.NSShiftKeyMask; break; + case SWT.CONTROL: mask = OS.NSEventModifierFlagControl; break; + case SWT.COMMAND: mask = OS.NSEventModifierFlagCommand; break; + case SWT.SHIFT: mask = OS.NSEventModifierFlagShift; break; case SWT.CAPS_LOCK: Event event = new Event(); event.keyCode = keyCode; @@ -583,7 +583,7 @@ void key (NSEvent nsEvent) { } } - int stepSize = (modifierFlags & OS.NSControlKeyMask) != 0 ? STEPSIZE_SMALL : STEPSIZE_LARGE; + int stepSize = (modifierFlags & OS.NSEventModifierFlagControl) != 0 ? STEPSIZE_SMALL : STEPSIZE_LARGE; int xChange = 0, yChange = 0; switch (nsKeyCode) { case 53: /* Esc */ diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/TrayItem.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/TrayItem.java index 00b271bfdf7..328e6139996 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/TrayItem.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/TrayItem.java @@ -510,7 +510,7 @@ boolean shouldShowMenu (NSEvent event) { if (!(hooks(SWT.Selection) || hooks(SWT.DefaultSelection))) { return true; } - if ((event.modifierFlags() & OS.NSDeviceIndependentModifierFlagsMask) == OS.NSControlKeyMask) { + if ((event.modifierFlags() & OS.NSDeviceIndependentModifierFlagsMask) == OS.NSEventModifierFlagControl) { return true; } return false; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Tree.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Tree.java index 0a92f0beb2f..4195ef69532 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Tree.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Tree.java @@ -312,7 +312,7 @@ boolean canDragRowsWithIndexes_atPoint(long id, long sel, long rowIndexes, NSPoi boolean drag = (state & DRAG_DETECT) != 0 && hooks (SWT.DragDetect); if (drag) { - if (!widget.isRowSelected(row) && (modifiers & (OS.NSCommandKeyMask | OS.NSShiftKeyMask | OS.NSAlternateKeyMask | OS.NSControlKeyMask)) == 0) { + if (!widget.isRowSelected(row) && (modifiers & (OS.NSEventModifierFlagCommand | OS.NSEventModifierFlagShift | OS.NSAlternateKeyMask | OS.NSEventModifierFlagControl)) == 0) { NSIndexSet set = (NSIndexSet)new NSIndexSet().alloc(); set = set.initWithIndex(row); widget.selectRowIndexes (set, false); @@ -2133,7 +2133,7 @@ void mouseDown (long id, long sel, long theEvent) { // it from menuForEvent:. This has the side effect, however, of sending control-click to the NSTableView, // which is interpreted as a single click that clears the selection. Fix is to ignore control-click, NSEvent event = new NSEvent(theEvent); - if ((event.modifierFlags() & OS.NSControlKeyMask) != 0) return; + if ((event.modifierFlags() & OS.NSEventModifierFlagControl) != 0) return; } super.mouseDown(id, sel, theEvent); } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Widget.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Widget.java index 9e3b018b5f1..3804a64ecf6 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Widget.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Widget.java @@ -1879,9 +1879,9 @@ boolean setInputState (Event event, NSEvent nsEvent, int type) { } long modifierFlags = nsEvent.modifierFlags(); if ((modifierFlags & OS.NSAlternateKeyMask) != 0) event.stateMask |= SWT.ALT; - if ((modifierFlags & OS.NSShiftKeyMask) != 0) event.stateMask |= SWT.SHIFT; - if ((modifierFlags & OS.NSControlKeyMask) != 0) event.stateMask |= SWT.CONTROL; - if ((modifierFlags & OS.NSCommandKeyMask) != 0) event.stateMask |= SWT.COMMAND; + if ((modifierFlags & OS.NSEventModifierFlagShift) != 0) event.stateMask |= SWT.SHIFT; + if ((modifierFlags & OS.NSEventModifierFlagControl) != 0) event.stateMask |= SWT.CONTROL; + if ((modifierFlags & OS.NSEventModifierFlagCommand) != 0) event.stateMask |= SWT.COMMAND; long state = NSEvent.pressedMouseButtons(); if ((state & 0x1) != 0) event.stateMask |= SWT.BUTTON1; From f6ad22535013aa44c8d8831079df5112c375cc41 Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Fri, 17 Jul 2026 11:13:14 +0200 Subject: [PATCH 20/46] [Cocoa] Support architecture-specific enum values in MacGenerator Some macOS enum constants have different numeric values on x86_64 versus aarch64, since aarch64 values were inherited from iOS headers and diverge from the values in the x86_64/bridgesupport definitions. Until now, this was handled by hand-editing the generated OS.java after every MacGenerator run, since the generator had no way to express an architecture-dependent value and the divergence isn't present in the (machine-generated, non-editable) bridgesupport files themselves. MacGenerator now supports a new "swt_value_aarch64" attribute on elements in *.bridgesupport.extras files. When set, it declares the value to use on aarch64, while the regular value/value64 attribute continues to describe the x86_64 value; the generator derives the appropriate architecture-conditional expression from both. This removes the need to manually patch generated code after each run and keeps the architecture-specific knowledge in the extras file, alongside the other custom generation hints already maintained there. Follow-up to 0ffafe6d8e6bf13e386b1839f7721b07751efb38 Co-Authored-By: Claude Sonnet 5 --- .../swt/tools/internal/MacGenerator.java | 33 ++++++++++++++++--- .../cocoa/AppKitFull.bridgesupport.extras | 4 +-- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/bundles/org.eclipse.swt.tools/Mac Generation/org/eclipse/swt/tools/internal/MacGenerator.java b/bundles/org.eclipse.swt.tools/Mac Generation/org/eclipse/swt/tools/internal/MacGenerator.java index df6f5c332e1..7c666e300ff 100644 --- a/bundles/org.eclipse.swt.tools/Mac Generation/org/eclipse/swt/tools/internal/MacGenerator.java +++ b/bundles/org.eclipse.swt.tools/Mac Generation/org/eclipse/swt/tools/internal/MacGenerator.java @@ -982,6 +982,8 @@ public String[] getExtraAttributeNames(Node node) { } } else if (name.equals("class")) { return new String[]{"swt_superclass"}; + } else if (name.equals("enum")) { + return new String[]{"swt_value_aarch64"}; } else if (name.equals("struct")) { return new String[]{"swt_gen_memmove", "swt_gen_tostring"}; } else if (name.equals("retval")) { @@ -1147,10 +1149,10 @@ void generateEnums() { if (value.indexOf('.') != -1) { out("double "); } else { - if (value.equals("4294967295")) { + if (isUint32Max(value)) { out("int "); value = "-1"; - } else if (value.equals("18446744073709551615")) { + } else if (isUint64Max(value)) { out("long "); value = "-1L"; } else { @@ -1165,8 +1167,20 @@ void generateEnums() { } out(attributes.getNamedItem("name").getNodeValue()); out(" = "); - out(value); - if (isLong && !value.endsWith("L")) out("L"); + Node aarch64ValueNode = attributes.getNamedItem("swt_value_aarch64"); + if (aarch64ValueNode != null) { + out("IS_X86_64 ? "); + out(value); + if (isLong && !value.endsWith("L")) out("L"); + out(" : "); + String aarch64Value = aarch64ValueNode.getNodeValue(); + aarch64Value = isUint32Max(aarch64Value) ? "-1" : isUint64Max(aarch64Value) ? "-1L" : aarch64Value; + out(aarch64Value); + if (isLong && !aarch64Value.endsWith("L")) out("L"); + } else { + out(value); + if (isLong && !value.endsWith("L")) out("L"); + } out(";"); outln(); } else { @@ -1178,6 +1192,17 @@ void generateEnums() { } } +private static final String UINT32_MAX = "4294967295"; +private static final String UINT64_MAX = "18446744073709551615"; + +private boolean isUint32Max(String value) { + return value.equals(UINT32_MAX); +} + +private boolean isUint64Max(String value) { + return value.equals(UINT64_MAX); +} + boolean getGen(Node node) { NamedNodeMap attributes = node.getAttributes(); if (attributes == null) return false; diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras index 18d835f349f..8f5602cc4f8 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras @@ -4542,10 +4542,10 @@ - + - + From f81b654aec622535393c9976bcdcba5b4e30f93d Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Fri, 17 Jul 2026 13:47:31 +0200 Subject: [PATCH 21/46] Version bumps for 4.41 stream --- bundles/org.eclipse.swt.tools/META-INF/MANIFEST.MF | 2 +- features/org.eclipse.swt.tools.feature/feature.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bundles/org.eclipse.swt.tools/META-INF/MANIFEST.MF b/bundles/org.eclipse.swt.tools/META-INF/MANIFEST.MF index 6c5ef0ac6d0..b90424780d8 100644 --- a/bundles/org.eclipse.swt.tools/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.swt.tools/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-SymbolicName: org.eclipse.swt.tools; singleton:=true -Bundle-Version: 3.112.0.qualifier +Bundle-Version: 3.112.100.qualifier Bundle-ManifestVersion: 2 Export-Package: org.eclipse.swt.tools.internal; x-internal:=true Bundle-ActivationPolicy: lazy diff --git a/features/org.eclipse.swt.tools.feature/feature.xml b/features/org.eclipse.swt.tools.feature/feature.xml index e931cf31d75..bbd29d9849f 100644 --- a/features/org.eclipse.swt.tools.feature/feature.xml +++ b/features/org.eclipse.swt.tools.feature/feature.xml @@ -2,7 +2,7 @@ From d91b5bdde407b72e5a550dd840edd8b12f6cb5ae Mon Sep 17 00:00:00 2001 From: Federico Jeanne Date: Fri, 17 Jul 2026 09:46:27 +0200 Subject: [PATCH 22/46] CTabFolder: support circular page traversal in MRU mode without chevron When setMRUVisible(true) and all tabs fit without a chevron, navigating past the last tab with Ctrl+PageDown (TRAVERSE_PAGE_NEXT) or before the first tab with Ctrl+PageUp (TRAVERSE_PAGE_PREVIOUS) had no effect. Now navigation wraps around to the first/last visible tab respectively, matching the existing behavior of the non-MRU traversal path. Adds a new option to the CTabFolder tab in the CustomControlExample (under: Other > Activate MRU) which demonstrates the before/after behavior. Fixes https://github.com/eclipse-platform/eclipse.platform.ui/issues/4135 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../org/eclipse/swt/custom/CTabFolder.java | 2 ++ .../src/examples_control.properties | 1 + .../examples/controlexample/CTabFolderTab.java | 16 +++++++++++++++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolder.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolder.java index 1e61652cef8..03aac63eafc 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolder.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolder.java @@ -2057,6 +2057,8 @@ void onPageTraversal(Event event) { if (e.doit && !isDisposed()) { showList(chevronRect); } + } else { + index = visible [(current + offset + idx) % idx]; } } } diff --git a/examples/org.eclipse.swt.examples/src/examples_control.properties b/examples/org.eclipse.swt.examples/src/examples_control.properties index 54bc35f9c0d..ad7f2ef4442 100644 --- a/examples/org.eclipse.swt.examples/src/examples_control.properties +++ b/examples/org.eclipse.swt.examples/src/examples_control.properties @@ -232,6 +232,7 @@ Set_Min_Visible = Minimize Set_Max_Visible = Maximize Set_Unselected_Close_Visible = Close on Unselected Tabs Set_Unselected_Image_Visible = Image on Unselected Tabs +Set_MRU_Active = Activate MRU Selection_Foreground_Color = Selection Foreground Color Selection_Background_Color = Selection Background Color Item_Foreground_Color = Item Foreground Color diff --git a/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/controlexample/CTabFolderTab.java b/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/controlexample/CTabFolderTab.java index 728f988c7d4..74b7450e906 100644 --- a/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/controlexample/CTabFolderTab.java +++ b/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/controlexample/CTabFolderTab.java @@ -63,7 +63,7 @@ class CTabFolderTab extends Tab { /* Other widgets added to the "Other" group */ Button singleTabButton, imageButton, showMinButton, showMaxButton, - topRightButton, unselectedCloseButton, unselectedImageButton; + topRightButton, unselectedCloseButton, unselectedImageButton, activateMRUButton; ToolBar topRightControl; @@ -233,6 +233,12 @@ void createOtherGroup () { unselectedCloseButton.setText (ControlExample.getResourceString("Set_Unselected_Close_Visible")); unselectedCloseButton.setSelection(true); unselectedCloseButton.addSelectionListener (widgetSelectedAdapter(event -> setUnselectedCloseVisible())); + + activateMRUButton = new Button (otherGroup, SWT.CHECK); + activateMRUButton.setText (ControlExample.getResourceString("Set_MRU_Active")); + activateMRUButton.setSelection(false); + activateMRUButton.addSelectionListener (widgetSelectedAdapter(event -> setMRUActive())); + } /** @@ -412,6 +418,7 @@ void setExampleWidgetState () { setImages(); setMinimizeVisible(); setMaximizeVisible(); + setMRUActive(); setUnselectedCloseVisible(); setUnselectedImageVisible(); setSelectionBackground (); @@ -458,6 +465,13 @@ void setMaximizeVisible () { tabFolder1.setMaximizeVisible(showMaxButton.getSelection ()); setExampleWidgetSize(); } + /** + * Activates/deactivates the MRU setting + */ + void setMRUActive () { + tabFolder1.setMRUVisible(activateMRUButton.getSelection ()); + setExampleWidgetSize(); + } /** * Sets the top right control to a toolbar */ From 2cb22d1e5b56cfe6b4a75a664e66765f60b7eec9 Mon Sep 17 00:00:00 2001 From: Federico Jeanne Date: Tue, 21 Jul 2026 14:11:05 +0200 Subject: [PATCH 23/46] Version bump(s) for 4.41 stream --- examples/org.eclipse.swt.examples/META-INF/MANIFEST.MF | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/org.eclipse.swt.examples/META-INF/MANIFEST.MF b/examples/org.eclipse.swt.examples/META-INF/MANIFEST.MF index b7b9968fa3f..c078217c52e 100644 --- a/examples/org.eclipse.swt.examples/META-INF/MANIFEST.MF +++ b/examples/org.eclipse.swt.examples/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin.SWTStandaloneExampleSet.name Bundle-SymbolicName: org.eclipse.swt.examples; singleton:=true -Bundle-Version: 3.109.100.qualifier +Bundle-Version: 3.109.200.qualifier Bundle-Vendor: %providerName Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-21 From 74292744d5d8b32c8ae5316be909daf62a24784b Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Wed, 8 Jul 2026 21:01:24 +0200 Subject: [PATCH 24/46] [Win32] Avoid redundant handle creation in GC.drawImage() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GC.drawImage() operations use a temporary image handle mechanism that creates a bitmap handle scaled to the pixel size required for each drawing operation. When an image is not available at the requested zoom, the closest available zoom is used instead. Previously, a fresh handle was created for every new drawing size, even when the same underlying image data would be used. For example, an image only available at 100% zoom (such as a plain PNG without HiDPI variants) caused a new handle to be allocated and immediately discarded on every drawImage() call that requested a different size. This change introduces the concept of "nearest available zoom" on image providers: each provider now reports, for a given requested zoom, the effective zoom at which it would actually supply data. This information is stored alongside the cached temporary handle after each drawImage(). Before allocating a new temporary handle for a different draw size, the nearest available zoom is used to look up an already existing handle: first in the image's persistent handle cache, then by comparing it against the zoom recorded with the previously cached temporary handle. If a matching handle is found, it is reused instead of creating a new one. If no handle exists and the nearest available zoom is 100%, a persistent handle is created eagerly: this frees any image data previously retained for API calls such as getImageData() and makes the handle available through the regular persistent handle lookup for all subsequent calls. This applies to any image where consecutive drawImage() calls at different sizes map to the same underlying data — e.g. a 100%-only image drawn at 200% and 300%, or an image with 100% and 200% variants when drawing at sizes between 200% and 300%. Four regression tests are added to ImagesWin32Tests to verify handle reuse (positive cases), the absence of unintended reuse across different nearest-available-zoom regions (negative case), and that a persistent handle created outside of drawImage() is found and reused by the nearest-available-zoom lookup. Fixes https://github.com/eclipse-platform/eclipse.platform.swt/issues/3419 --- .../swt/graphics/ImagesWin32Tests.java | 136 +++++++++++++++++- .../win32/org/eclipse/swt/graphics/Image.java | 106 ++++++++++++-- 2 files changed, 225 insertions(+), 17 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/ImagesWin32Tests.java b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/ImagesWin32Tests.java index 6b60c2a20df..cf48800de38 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/ImagesWin32Tests.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/ImagesWin32Tests.java @@ -13,7 +13,8 @@ *******************************************************************************/ package org.eclipse.swt.graphics; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import org.eclipse.swt.*; import org.eclipse.swt.internal.*; @@ -30,9 +31,140 @@ public void testImageIconTypeShouldNotChangeAfterCallingGetHandleForDifferentZoo Image icon = Display.getDefault().getSystemImage(SWT.ICON_ERROR); try { Image.win32_getHandle(icon, 200); - assertEquals("Image type should stay to SWT.ICON", SWT.ICON, icon.type); + assertEquals(SWT.ICON, icon.type, "Image type should stay to SWT.ICON"); } finally { icon.dispose(); } } + + /** + * Tests that a GC.drawImage() handle is reused across consecutive calls at + * different pixel sizes when the image only provides 100% zoom data. Because + * every zoom request falls back to the same 100% data, the effective (nearest + * available) zoom is always 100%, and a freshly allocated handle should not be + * required for each different draw size. + *

+ * See https://github.com/eclipse-platform/eclipse.platform.swt/issues/3419 + */ + @Test + public void testDrawingHandleIsReusedForSingleZoomImageAtDifferentSizes() { + PaletteData palette = new PaletteData(0xFF0000, 0xFF00, 0xFF); + ImageData imageData = new ImageData(10, 10, 24, palette); + // Provider only has 100% data; returns null for every other zoom + Image image = new Image(Display.getDefault(), (ImageDataProvider) zoom -> zoom == 100 ? imageData : null); + long[] firstHandle = {0}; + long[] secondHandle = {0}; + try { + // 20x20 pixels → 200% zoom equivalent for a 10x10 base image + image.executeOnImageHandleAtBestFittingSize(h -> firstHandle[0] = h.handle(), 20, 20); + // 30x30 pixels → 300% zoom equivalent; provider still falls back to 100%, + // so the nearest available zoom is still 100% and the handle must be reused + image.executeOnImageHandleAtBestFittingSize(h -> secondHandle[0] = h.handle(), 30, 30); + assertNotEquals(0L, firstHandle[0], "First handle should be non-zero"); + assertEquals(firstHandle[0], secondHandle[0], + "Consecutive GC.drawImage() calls at different sizes should reuse the same " + + "handle when the nearest available zoom is the same (100% in this case)"); + } finally { + image.dispose(); + } + } + + /** + * Tests that a GC.drawImage() handle is reused across consecutive calls at + * different pixel sizes when the image provides data at 100% and 200% zoom. + * Sizes that both map to the 200% nearest available zoom (e.g. 200% and 250%) + * should share the same underlying handle without re-allocating it. + *

+ * See https://github.com/eclipse-platform/eclipse.platform.swt/issues/3419 + */ + @Test + public void testDrawingHandleIsReusedForTwoZoomImageAtSizesWithSameNearestZoom() { + PaletteData palette = new PaletteData(0xFF0000, 0xFF00, 0xFF); + ImageData imageData100 = new ImageData(10, 10, 24, palette); + ImageData imageData200 = new ImageData(20, 20, 24, palette); + // Provider has explicit data at 100% and 200%; returns null for anything else + Image image = new Image(Display.getDefault(), (ImageDataProvider) zoom -> zoom == 100 ? imageData100 : zoom == 200 ? imageData200 : null); + long[] firstHandle = {0}; + long[] secondHandle = {0}; + try { + // 20x20 pixels → exactly 200% zoom for the 10x10 base image; uses 200% data + image.executeOnImageHandleAtBestFittingSize(h -> firstHandle[0] = h.handle(), 20, 20); + // 25x25 pixels → 250% zoom equivalent; nearest available is 200%, so the + // previously cached 200% handle should be reused + image.executeOnImageHandleAtBestFittingSize(h -> secondHandle[0] = h.handle(), 25, 25); + assertNotEquals(0L, firstHandle[0], "First handle should be non-zero"); + assertEquals(firstHandle[0], secondHandle[0], + "Consecutive GC.drawImage() calls at different sizes should reuse the same " + + "handle when the nearest available zoom is the same (200% in this case)"); + } finally { + image.dispose(); + } + } + + /** + * Tests that GC.drawImage() handles differ when consecutive calls at different + * pixel sizes land in different nearest-available-zoom regions for an image + * that provides distinct data at 100% and 200%. A size mapping to 100% and a + * size mapping to 200% must not share the same native handle, as they would + * represent different pixel content. + *

+ * See https://github.com/eclipse-platform/eclipse.platform.swt/issues/3419 + */ + @Test + public void testHandlesAreDifferentForTwoZoomImageAtDifferentNearestZooms() { + PaletteData palette = new PaletteData(0xFF0000, 0xFF00, 0xFF); + ImageData imageData100 = new ImageData(10, 10, 24, palette); + ImageData imageData200 = new ImageData(20, 20, 24, palette); + // Provider has explicit data at 100% and 200%; returns null for anything else + Image image = new Image(Display.getDefault(), (ImageDataProvider) zoom -> zoom == 100 ? imageData100 : zoom == 200 ? imageData200 : null); + long[] handle100Zone = {0}; + long[] handle200Zone = {0}; + try { + // 10x10 pixels → 100% zoom for the 10x10 base image; nearest available is 100% + image.executeOnImageHandleAtBestFittingSize(h -> handle100Zone[0] = h.handle(), 10, 10); + // 20x20 pixels → 200% zoom; nearest available is 200% → must differ from the + // 100% handle since the underlying pixel data is different + image.executeOnImageHandleAtBestFittingSize(h -> handle200Zone[0] = h.handle(), 20, 20); + assertNotEquals(0L, handle100Zone[0], "First handle should be non-zero"); + assertNotEquals(handle100Zone[0], handle200Zone[0], + "GC.drawImage() calls where the nearest available zoom differs must not " + + "reuse the same handle (100% data vs 200% data)"); + } finally { + image.dispose(); + } + } + + /** + * Tests that a persistent native handle already created via + * {@link Image#win32_getHandle(Image, int)} is found and reused by + * GC.drawImage() when the nearest available zoom for the requested draw size + * maps to the same zoom. This verifies that the + * {@code imageHandleManager.get(nearestAvailableZoom)} lookup is effective and + * avoids redundant handle allocation. + *

+ * See https://github.com/eclipse-platform/eclipse.platform.swt/issues/3419 + */ + @Test + public void testDrawImageReusesExistingPersistentHandleForNearestAvailableZoom() { + PaletteData palette = new PaletteData(0xFF0000, 0xFF00, 0xFF); + ImageData imageData = new ImageData(10, 10, 24, palette); + // Provider only has 100% data; every zoom falls back to 100% + Image image = new Image(Display.getDefault(), (ImageDataProvider) zoom -> zoom == 100 ? imageData : null); + try { + // Force creation of a persistent 100% handle (as would happen via GC.drawImage + // on a 100% zoom canvas or via Image.getImageData()) + long persistentHandle = Image.win32_getHandle(image, 100); + assertNotEquals(0L, persistentHandle, "Persistent handle should be non-zero"); + long[] drawHandle = {0}; + // 20x20 pixels → 200% zoom equivalent for the 10x10 base image; nearest + // available is still 100%, so the already-cached persistent handle must be + // returned without allocating a new one + image.executeOnImageHandleAtBestFittingSize(h -> drawHandle[0] = h.handle(), 20, 20); + assertEquals(persistentHandle, drawHandle[0], + "GC.drawImage() should reuse the existing persistent handle when the " + + "nearest available zoom matches the cached handle's zoom (100% here)"); + } finally { + image.dispose(); + } + } } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java index 12a78ed8464..29e6fc94aef 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java @@ -201,28 +201,39 @@ public String toString() { } private class HandleAtSize { + record TemporaryHandleForZoom(DestroyableImageHandle handle, int zoom) {} + private InternalImageHandle handleContainer = null; - private DestroyableImageHandle temporaryHandleContainer = null; + private TemporaryHandleForZoom temporaryHandleContainer = null; private int requestedWidth = -1; private int requestedHeight = -1; public void destroy() { - if (temporaryHandleContainer != null) { - temporaryHandleContainer.destroy(); - temporaryHandleContainer = null; + TemporaryHandleForZoom previousHandle = reset(); + if (previousHandle != null) { + previousHandle.handle().destroy(); } + } + + private TemporaryHandleForZoom reset() { + TemporaryHandleForZoom previousHandle = temporaryHandleContainer; + temporaryHandleContainer = null; handleContainer = null; requestedWidth = -1; requestedHeight = -1; + return previousHandle; } public ImageHandle refresh(int width, int height) { if (!isReusable(width, height)) { - destroy(); + TemporaryHandleForZoom previousHandle = reset(); requestedWidth = width; requestedHeight = height; handleContainer = createHandleAtExactSize(width, height) - .orElseGet(() -> getOrCreateImageHandleAtClosestSize(width, height)); + .orElseGet(() -> getOrCreateImageHandleAtClosestSize(width, height, previousHandle)); + if (previousHandle != null && previousHandle.handle() != handleContainer) { + previousHandle.handle().destroy(); + } } return handleContainer; } @@ -238,23 +249,32 @@ private boolean isReusable(int width, int height) { private Optional createHandleAtExactSize(int width, int height) { Optional imageData = imageProvider.loadImageDataAtExactSize(width, height); if (imageData.isPresent()) { - temporaryHandleContainer = init(imageData.get(), -1); - return Optional.of(temporaryHandleContainer); + temporaryHandleContainer = new TemporaryHandleForZoom(init(imageData.get(), -1), 0); + return Optional.of(temporaryHandleContainer.handle()); } return Optional.empty(); } - private InternalImageHandle getOrCreateImageHandleAtClosestSize(int widthHint, int heightHint) { + private InternalImageHandle getOrCreateImageHandleAtClosestSize(int widthHint, int heightHint, TemporaryHandleForZoom previousHandle) { Rectangle bounds = getBounds(100); int imageZoomForWidth = 100 * widthHint / bounds.width; int imageZoomForHeight = 100 * heightHint / bounds.height; int imageZoom = DPIUtil.getZoomForAutoscaleProperty(Math.max(imageZoomForWidth, imageZoomForHeight)); - InternalImageHandle bestFittingHandle = imageHandleManager.get(imageZoom); - if (bestFittingHandle == null) { - ImageData bestFittingImageData = imageProvider.loadImageData(imageZoom).element(); - bestFittingHandle = temporaryHandleContainer = init(bestFittingImageData, -1); + int nearestAvailableZoom = imageProvider.nearestAvailableZoom(imageZoom); + InternalImageHandle bestFittingHandle = imageHandleManager.get(nearestAvailableZoom); + if (bestFittingHandle != null) { + return bestFittingHandle; + } + if (nearestAvailableZoom == 100) { + return getHandleInternal(100, 100); } - return bestFittingHandle; + if (previousHandle != null && previousHandle.zoom() == nearestAvailableZoom) { + temporaryHandleContainer = previousHandle; + return previousHandle.handle(); + } + ElementAtZoom imageData = imageProvider.loadImageData(imageZoom); + temporaryHandleContainer = new TemporaryHandleForZoom(init(imageData.element(), -1), imageData.zoom()); + return temporaryHandleContainer.handle(); } } @@ -957,6 +977,10 @@ public static long win32_getHandle (Image image, int zoom) { } ImageHandle getHandle (int targetZoom, int nativeZoom) { + return getHandleInternal(targetZoom, nativeZoom); +} + +InternalImageHandle getHandleInternal (int targetZoom, int nativeZoom) { if (isDisposed()) { return null; } @@ -2090,6 +2114,8 @@ protected boolean isPersistentImageHandleRequriedForImageData() { return false; } + abstract int nearestAvailableZoom(int zoom); + /** * Returns image data at the best-fitting available zoom for the given zoom. * The returned data will have a potential gray/disable style applied. @@ -2102,7 +2128,7 @@ protected boolean isPersistentImageHandleRequriedForImageData() { ElementAtZoom getClosestAvailableImageData(int zoom) { TreeSet availableZooms = new TreeSet<>(imageHandleManager.getAllZooms()); - int closestZoom = Optional.ofNullable(availableZooms.higher(zoom)).orElse(availableZooms.lower(zoom)); + int closestZoom = availableZooms.contains(zoom) ? zoom : Optional.ofNullable(availableZooms.higher(zoom)).orElse(availableZooms.lower(zoom)); ImageData imageData = imageHandleManager.get(closestZoom).getImageData(); return new ElementAtZoom<>(imageData, closestZoom); } @@ -2179,6 +2205,11 @@ protected DestroyableImageHandle newImageHandle(ZoomContext zoomContext) { ImageData resizedData = newImageData (zoomContext.targetZoom()); return newImageHandle(resizedData, zoomContext); } + + @Override + int nearestAvailableZoom(int zoom) { + return zoomForHandle; + } } private abstract class ImageFromImageDataProviderWrapper extends AbstractImageProviderWrapper { @@ -2249,6 +2280,11 @@ protected ElementAtZoom loadImageData(int zoom) { AbstractImageProviderWrapper createCopy(Image image) { return image.new PlainImageDataProviderWrapper(this.imageDataAtBaseZoom); } + + @Override + int nearestAvailableZoom(int zoom) { + return baseZoom; + } } private class MaskedImageDataProviderWrapper extends ImageFromImageDataProviderWrapper { @@ -2281,6 +2317,11 @@ protected ElementAtZoom loadImageData(int zoom) { AbstractImageProviderWrapper createCopy(Image image) { return image.new MaskedImageDataProviderWrapper(this.srcAt100, this.maskAt100); } + + @Override + int nearestAvailableZoom(int zoom) { + return 100; + } } private class ImageDataLoaderStreamProviderWrapper extends ImageFromImageDataProviderWrapper { @@ -2325,6 +2366,14 @@ protected Optional loadImageDataAtExactSize(int targetWidth, int targ } return Optional.empty(); } + + @Override + int nearestAvailableZoom(int zoom) { + if (ImageDataLoader.isDynamicallySizable(new ByteArrayInputStream(this.inputStreamData))) { + return zoom; + } + return FileFormat.DEFAULT_ZOOM; + } } private class PlainImageProviderWrapper extends AbstractImageProviderWrapper { @@ -2388,6 +2437,11 @@ protected ElementAtZoom loadImageData(int zoom) { return getClosestAvailableImageData(zoom); } + @Override + int nearestAvailableZoom(int zoom) { + return getClosestAvailableImageData(zoom).zoom(); + } + @Override protected DestroyableImageHandle newImageHandle(ZoomContext zoomContext) { int targetZoom = zoomContext.targetZoom(); @@ -2533,6 +2587,7 @@ private class ImageFileNameProviderWrapper extends BaseImageProviderWrapper loadImageData(int zoom) { ElementAtZoom fileForZoom = DPIUtil.validateAndGetImagePathAtZoom(provider, zoom); @@ -2564,6 +2619,14 @@ protected ElementAtZoom loadImageData(int zoom) { return adaptImageDataIfDisabledOrGray(imageDataAtZoom); } + @Override + int nearestAvailableZoom(int zoom) { + if (provider instanceof ImageDataAtSizeProvider) { + return zoom; + } + return DPIUtil.validateAndGetImagePathAtZoom(provider, zoom).zoom(); + } + @Override public int hashCode() { return Objects.hash(provider, styleFlag); @@ -2807,6 +2870,14 @@ protected Optional loadImageDataAtExactSize(int targetWidth, int targ } return Optional.empty(); } + + @Override + int nearestAvailableZoom(int zoom) { + if (provider instanceof ImageDataAtSizeProvider) { + return zoom; + } + return DPIUtil.validateAndGetImageDataAtZoom (provider, zoom).zoom(); + } } private class ImageGcDrawerWrapper extends DynamicImageProviderWrapper { @@ -2848,6 +2919,11 @@ protected ElementAtZoom loadImageData(int zoom) { return new ElementAtZoom<>(loadImageData(new ZoomContext(zoom)), zoom); } + @Override + int nearestAvailableZoom(int zoom) { + return zoom; + } + private ImageData loadImageData(ZoomContext zoomContext) { currentZoom = zoomContext; int targetZoom = zoomContext.targetZoom(); From 1835e73cc1ef0c3cd1f05d8c70a129d6c168fc06 Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Wed, 22 Jul 2026 14:06:33 +0200 Subject: [PATCH 25/46] [Win32] Extend GC.drawImage() handle selection with exact-zoom MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GC.drawImage() operations use a temporary image handle mechanism that selects the best-fitting native handle for each pixel size. A recent change introduced the concept of "nearest available zoom" so that handles can be reused when consecutive draw calls at different sizes map to the same underlying image data, and eagerly persists handles when the nearest available zoom is 100%. This change extends the handle-selection logic in two ways. Exact imageZoom lookup before nearestAvailableZoom: Before consulting the nearestAvailableZoom, the image's persistent handle manager is now queried at the exact imageZoom first. This ensures that a handle explicitly created for a zoom — even one the provider would not normally supply on its own — is found and reused. For example, when win32_getHandle() has been called at 200% for a 100%-only image, drawing at the 200%-equivalent pixel size now returns the pre-existing 200% handle rather than the 100% handle from nearestAvailableZoom. Monitor-zoom persistence: The condition for eagerly persisting a handle is extended from "nearestAvailableZoom == 100%" to also include any zoom that matches a current monitor. Monitor zooms are obtained from the zoom reported by each open Shell via Display.getShells(). When imageZoom or nearestAvailableZoom matches a monitor zoom, the image is likely being drawn repeatedly at that screen's native resolution, so persisting the handle avoids repeated allocations across consecutive draw calls. As a minor cleanup, getAvailableMonitorZooms() is now called once and its result reused within getExistingHandle() instead of being called twice. Two regression tests are added to ImagesWin32Tests to cover the new behaviors: one verifying that an existing handle at the exact imageZoom is preferred over a nearestAvailableZoom handle, and one verifying that drawing at the monitor zoom creates a persistent handle that is then reused via win32_getHandle() without a second native allocation. See https://github.com/eclipse-platform/eclipse.platform.swt/issues/3419 Contributes to https://github.com/eclipse-platform/eclipse.platform.swt/issues/3454 --- .../swt/graphics/ImagesWin32Tests.java | 79 +++++++++++++++++++ .../win32/org/eclipse/swt/graphics/Image.java | 36 ++++++++- 2 files changed, 111 insertions(+), 4 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/ImagesWin32Tests.java b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/ImagesWin32Tests.java index cf48800de38..33f7e3fac26 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/ImagesWin32Tests.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/ImagesWin32Tests.java @@ -134,6 +134,85 @@ public void testHandlesAreDifferentForTwoZoomImageAtDifferentNearestZooms() { } } + /** + * Tests that a GC.drawImage() handle at the exact imageZoom is returned in + * preference to a handle at nearestAvailableZoom when both are present in the + * image's handle manager. + *

+ * Explicitly creating a persistent handle at 200% via + * {@link Image#win32_getHandle(Image, int)} places it in the handle manager. + * When GC.drawImage() then targets a pixel size that maps to imageZoom=200 + * (while nearestAvailableZoom stays 100% because the provider only has 100% + * data), the 200% handle must be found first via the imageZoom lookup and + * returned instead of the 100% one. + *

+ * See https://github.com/eclipse-platform/eclipse.platform.swt/issues/3419 + */ + @Test + public void testDrawImagePrefersExistingHandleAtExactImageZoom() { + PaletteData palette = new PaletteData(0xFF0000, 0xFF00, 0xFF); + ImageData imageData = new ImageData(10, 10, 24, palette); + Image image = new Image(Display.getDefault(), (ImageDataProvider) zoom -> zoom == 100 ? imageData : null); + try { + long handle100 = Image.win32_getHandle(image, 100); + long handle200 = Image.win32_getHandle(image, 200); + assertNotEquals(0L, handle100, "100% handle should be non-zero"); + assertNotEquals(0L, handle200, "200% handle should be non-zero"); + assertNotEquals(handle100, handle200, "Handles for different zooms should be distinct native objects"); + long[] drawHandle = {0}; + // 20x20 pixels → imageZoom=200 for a 10x10 base; nearestAvailableZoom=100 + // The 200% handle already in the handle manager must be found and preferred + image.executeOnImageHandleAtBestFittingSize(h -> drawHandle[0] = h.handle(), 20, 20); + assertEquals(handle200, drawHandle[0], + "GC.drawImage() should prefer the existing handle at imageZoom=200 " + + "over the nearestAvailableZoom=100 handle"); + } finally { + image.dispose(); + } + } + + /** + * Tests that when the pixel size requested by GC.drawImage() maps to a zoom + * equal to a current monitor's zoom, a persistent handle is created for that + * zoom level and is subsequently reusable via + * {@link Image#win32_getHandle(Image, int)}. + *

+ * A shell is created so that {@code Display.getShells()} is non-empty and + * the monitor zoom is visible to the handle-selection logic. Drawing at a + * pixel size whose imageZoom equals the shell's zoom triggers the + * monitor-zoom persistence path: the handle is stored in the image's handle + * manager and can be retrieved without allocating a second native object. + * On 100%-DPI machines the new {@code imageZoom == monitorZoom} branch + * overlaps with the existing {@code nearestAvailableZoom == 100} fallback; + * on HiDPI machines the new branch is exercised in isolation. + *

+ * See https://github.com/eclipse-platform/eclipse.platform.swt/issues/3419 + */ + @Test + public void testDrawImageCreatesAndReusesPersistentHandleForMonitorZoomImageZoom() { + PaletteData palette = new PaletteData(0xFF0000, 0xFF00, 0xFF); + ImageData imageData = new ImageData(10, 10, 24, palette); + Image image = new Image(Display.getDefault(), (ImageDataProvider) zoom -> zoom == 100 ? imageData : null); + Shell shell = new Shell(Display.getDefault()); + try { + int shellZoom = shell.getZoom(); + int pixelSize = 10 * shellZoom / 100; + long[] drawHandle = {0}; + // Drawing at shellZoom's pixel size → imageZoom == shellZoom == monitorZoom + // A persistent handle must be created and stored in the handle manager + image.executeOnImageHandleAtBestFittingSize(h -> drawHandle[0] = h.handle(), pixelSize, pixelSize); + // If persisted, win32_getHandle returns the same native handle without a new allocation + long persistedHandle = Image.win32_getHandle(image, shellZoom); + assertNotEquals(0L, drawHandle[0], "Draw handle should be non-zero"); + assertEquals(persistedHandle, drawHandle[0], + "GC.drawImage() at the monitor zoom should create a persistent handle " + + "so that win32_getHandle returns the same native object"); + } finally { + image.dispose(); + shell.dispose(); + } + } + /** * Tests that a persistent native handle already created via * {@link Image#win32_getHandle(Image, int)} is found and reused by diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java index 29e6fc94aef..962da6ee715 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java @@ -18,6 +18,7 @@ import java.io.*; import java.util.*; +import java.util.List; import java.util.concurrent.*; import java.util.concurrent.atomic.*; import java.util.function.*; @@ -29,6 +30,7 @@ import org.eclipse.swt.internal.gdip.*; import org.eclipse.swt.internal.image.*; import org.eclipse.swt.internal.win32.*; +import org.eclipse.swt.widgets.*; /** * Instances of this class are graphics which have been prepared @@ -261,13 +263,10 @@ private InternalImageHandle getOrCreateImageHandleAtClosestSize(int widthHint, i int imageZoomForHeight = 100 * heightHint / bounds.height; int imageZoom = DPIUtil.getZoomForAutoscaleProperty(Math.max(imageZoomForWidth, imageZoomForHeight)); int nearestAvailableZoom = imageProvider.nearestAvailableZoom(imageZoom); - InternalImageHandle bestFittingHandle = imageHandleManager.get(nearestAvailableZoom); + InternalImageHandle bestFittingHandle = getPersistentHandle(imageZoom, nearestAvailableZoom); if (bestFittingHandle != null) { return bestFittingHandle; } - if (nearestAvailableZoom == 100) { - return getHandleInternal(100, 100); - } if (previousHandle != null && previousHandle.zoom() == nearestAvailableZoom) { temporaryHandleContainer = previousHandle; return previousHandle.handle(); @@ -277,6 +276,35 @@ private InternalImageHandle getOrCreateImageHandleAtClosestSize(int widthHint, i return temporaryHandleContainer.handle(); } + private InternalImageHandle getPersistentHandle(int imageZoom, int nearestAvailableZoom) { + InternalImageHandle bestFittingHandle = imageHandleManager.get(imageZoom); + if (bestFittingHandle != null) { + return bestFittingHandle; + } + if (getShellZooms().contains(imageZoom)) { + return getHandleInternal(imageZoom, imageZoom); + } + bestFittingHandle = imageHandleManager.get(nearestAvailableZoom); + if (bestFittingHandle != null) { + return bestFittingHandle; + } + if (nearestAvailableZoom == 100) { + return getHandleInternal(100, 100); + } + return null; + } + + private Set getShellZooms() { + if (getDevice() instanceof Display display) { + try { + return Arrays.stream(display.getShells()).map(Shell::getZoom).collect(Collectors.toSet()); + } catch (SWTException e) { + return Collections.emptySet(); + } + } + return Collections.emptySet(); + } + } private final HandleAtSize lastRequestedHandle = new HandleAtSize(); From b7f2b8ea278587d63e51b8977f717ad86d1b0545 Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Thu, 9 Jul 2026 17:41:43 +0200 Subject: [PATCH 26/46] [Win32] Improve size calculation for cropped and scaled image drawing When drawing cropped and scaled images, the calculation for the source rectangle to draw is quite error prone: - It does not distinguish between different scale factors in X and Y direction, leading to large rounding errors if the extents in one direction are highly different from the extents in the other direction - It does not apply rounding that is consistent to the scaling done by the Image class, thus leading to differently rounded sizes when scaling an image in the Image class and drawing that same image in the GC - The "error correction" to deal with rounding at fractional scale factors is too restrictive, in particular when the scale factor is less than 1, and is not applied when only one axis has a non-unity scale factor This change reimplements the source rectangle calculation as follows: - It treats the scale factors for both axes independently - It applies the same rounding method to the rectangle extents as done by the Image scaling implementation - It rounds up the scale factor when checking for the allowed size error on fractional scaling, such that a scale factor less than 1 still allows for an error of 1 in size - It applies the bounds correction whenever either axis has a non-unity scale factor, not only when both axes do A regression test is added to GCWin32Tests that verifies all three drawImage overloads (3-arg, 5-arg, and 9-arg) produce identical pixel output for a 500-wide image across a matrix of small prime heights and fractional zoom levels (100%, 125%, 150%, 175%, 200%). Fixes https://github.com/eclipse-platform/eclipse.platform.swt/issues/3454 Co-Authored-By: Claude Sonnet 4.6 --- .../eclipse/swt/graphics/GCWin32Tests.java | 72 ++++++++++++++++++- .../win32/org/eclipse/swt/graphics/GC.java | 16 +++-- 2 files changed, 80 insertions(+), 8 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/GCWin32Tests.java b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/GCWin32Tests.java index 6b4cb998c86..47b20458042 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/GCWin32Tests.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/GCWin32Tests.java @@ -14,16 +14,19 @@ package org.eclipse.swt.graphics; import static org.junit.Assert.assertEquals; -import static org.junit.jupiter.api.Assertions.assertAll; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; +import java.util.*; import java.util.concurrent.*; +import java.util.stream.*; import org.eclipse.swt.*; import org.eclipse.swt.internal.*; import org.eclipse.swt.widgets.*; import org.junit.jupiter.api.*; import org.junit.jupiter.api.extension.*; +import org.junit.jupiter.params.*; +import org.junit.jupiter.params.provider.*; @ExtendWith(PlatformSpecificExecutionExtension.class) @ExtendWith(WithMonitorSpecificScalingExtension.class) @@ -142,4 +145,69 @@ private static int renderTextAndCountNonWhitePixels(Image target, Font font, Str } return count; } + + /** + * Regression test for the size calculation in scaling/cropping GC.drawImage() + * operations with asymmetric source dimensions (smaller height than width) at + * fractional zoom levels. + *

+ * At fractional zoom levels the effective X and Y scale factors diverge because + * each axis is rounded independently (e.g. at 125%: + * scaleFactorX = 625/500 = 1.25 but + * scaleFactorY = 24/19 ≈ 1.263). + */ + @ParameterizedTest + @MethodSource("zoomAndHeightArguments") + public void drawImage_asymmetricDimensionsAtFractionalZoom(int zoom, int height) { + Display display = Display.getDefault(); + + int logicalWidth = 500; + int logicalHeight = height; + + PaletteData palette = new PaletteData(0xFF0000, 0xFF00, 0xFF); + ImageData srcData = new ImageData(logicalWidth, logicalHeight, 32, palette); + for (int y = 0; y < logicalHeight; y++) { + for (int x = 0; x < logicalWidth; x++) { + // left half red, right half blue – makes wrong-rectangle errors visible + srcData.setPixel(x, y, x < logicalWidth / 2 ? 0xFF0000 : 0x0000FF); + } + } + Image srcImage = new Image(display, srcData); + + int previousZoom = DPIUtil.getDeviceZoom(); + try { + DPIUtil.setDeviceZoom(zoom); + + Image referenceImage = new Image(display, logicalWidth + 5, logicalHeight + 5); + GC referenceGC = new GC(referenceImage); + referenceGC.drawImage(srcImage, 0, 0); + referenceGC.dispose(); + + Image testImageScaled = new Image(display, logicalWidth + 5, logicalHeight + 5); + GC testGC = new GC(testImageScaled); + testGC.drawImage(srcImage, 0, 0, logicalWidth, logicalHeight); + testGC.dispose(); + assertArrayEquals(referenceImage.getImageData(zoom).data, testImageScaled.getImageData(zoom).data); + testImageScaled.dispose(); + + Image testImageScaledCropped = new Image(display, logicalWidth + 5, logicalHeight + 5); + testGC = new GC(testImageScaledCropped); + testGC.drawImage(srcImage, 0, 0, logicalWidth, logicalHeight, 0, 0, logicalWidth, logicalHeight); + testGC.dispose(); + assertArrayEquals(referenceImage.getImageData(zoom).data, testImageScaledCropped.getImageData(zoom).data); + testImageScaledCropped.dispose(); + + referenceImage.dispose(); + } finally { + DPIUtil.setDeviceZoom(previousZoom); + srcImage.dispose(); + } + } + + private static Stream zoomAndHeightArguments() { + int[] zooms = { 25, 50, 75, 100, 125, 150, 175, 200 }; + int[] heights = IntStream.rangeClosed(4, 20).toArray(); + return Arrays.stream(zooms).boxed() + .flatMap(zoom -> Arrays.stream(heights).mapToObj(height -> Arguments.of(zoom, height))); + } } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java index e6b99131a7b..525cf88296d 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java @@ -1250,11 +1250,15 @@ private Rectangle computeSourceRectangle(ImageHandle imageHandle, Rectangle full * computed to pixels depending on the factor of the full image bounds to the * actual OS handle size that will be used. */ - float scaleFactor = Math.min(1f * imageHandle.width() / fullImageBounds.width, 1f * imageHandle.height() / fullImageBounds.height); - int closestZoomOfHandle = Math.round(scaleFactor * 100); - Rectangle srcPixels = Win32DPIUtils.pointToPixel(drawable, src, closestZoomOfHandle); - - if (closestZoomOfHandle != 100) { + float scaleFactorX = (1f * imageHandle.width()) / fullImageBounds.width; + float scaleFactorY = (1f * imageHandle.height()) / fullImageBounds.height; + int srcXPixels = Math.round(scaleFactorX * src.x); + int srcWidthPixels = Math.round(scaleFactorX * (src.x + src.width)) - srcXPixels; + int srcYPixels = Math.round(scaleFactorY * src.y); + int srcHeightPixels = Math.round(scaleFactorY * (src.y + src.height)) - srcYPixels; + Rectangle srcPixels = new Rectangle(srcXPixels, srcYPixels, srcWidthPixels, srcHeightPixels); + + if (Math.abs(scaleFactorX - 1f) >= 0.01f || Math.abs(scaleFactorY - 1f) >= 0.01f) { /* * This is a HACK! Due to rounding errors at fractional scale factors, * the coordinates may be slightly off. The workaround is to restrict @@ -1263,7 +1267,7 @@ private Rectangle computeSourceRectangle(ImageHandle imageHandle, Rectangle full int errX = srcPixels.x + srcPixels.width - imageHandle.width(); int errY = srcPixels.y + srcPixels.height - imageHandle.height(); if (errX != 0 || errY != 0) { - if (errX <= closestZoomOfHandle / 100 && errY <= closestZoomOfHandle / 100) { + if (errX <= Math.max(1, scaleFactorX) && errY <= Math.max(1, scaleFactorY)) { srcPixels.intersect(new Rectangle(0, 0, imageHandle.width(), imageHandle.height())); } else { SWT.error (SWT.ERROR_INVALID_ARGUMENT); From 57a97f2b57097fd0841bdafb33c70afb1080d1c4 Mon Sep 17 00:00:00 2001 From: Andrey Loskutov Date: Thu, 23 Jul 2026 08:51:59 +0200 Subject: [PATCH 27/46] [GTK] Fix SIGSEGV in Tree.removeAll() by disconnecting model before clearing - Added manual regression test (created with the help from Copilot and based on the original JFace based TreeCrashBug.java reproducer). Fixes https://github.com/eclipse-platform/eclipse.platform.swt/issues/3329 --- .../gtk/org/eclipse/swt/widgets/Tree.java | 10 +- .../gtk/snippets/Issue3329_TreeCrashBug.java | 155 ++++++++++++++++++ 2 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Issue3329_TreeCrashBug.java diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java index ec7d5ab9c09..be506112a4a 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java @@ -2977,7 +2977,15 @@ public void removeAll () { long selection = GTK.gtk_tree_view_get_selection (handle); OS.g_signal_handlers_block_matched (selection, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED); - GTK.gtk_tree_store_clear (modelHandle); + // Disconnect the model from the view before clearing it. + // gtk_tree_store_clear fires cell-data / row-changed callbacks for every + // row it removes. Those callbacks re-enter SWT (cellDataProc -> checkData + // -> getParentItem -> gtk_tree_model_get_path) with iterators that are + // already being freed, causing a SIGSEGV. With no model attached the view + // has nothing to render, so no callbacks are fired during the clear. + GTK.gtk_tree_view_set_model (handle, 0); + GTK.gtk_tree_store_clear (modelHandle); + GTK.gtk_tree_view_set_model (handle, modelHandle); OS.g_signal_handlers_unblock_matched (selection, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED); diff --git a/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Issue3329_TreeCrashBug.java b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Issue3329_TreeCrashBug.java new file mode 100644 index 00000000000..4668816fec8 --- /dev/null +++ b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Issue3329_TreeCrashBug.java @@ -0,0 +1,155 @@ +/******************************************************************************* + * Copyright (c) 2026 Andrey Loskutov and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Andrey Loskutov - initial API and implementation + *******************************************************************************/ +package org.eclipse.swt.tests.gtk.snippets; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeItem; + +/** + * Manual reproducer for the Tree.removeAll() crash on Linux GTK with + * SWT.VIRTUAL trees. + * + * STEPS TO REPRODUCE: 1. Run this snippet. 2. Expand any root item so its + * children become visible (this creates Java TreeItem objects with GTK iters + * backed by live GNodes). 3. Click GO. + * + * EXPECTED: Tree content refreshes cleanly. ACTUAL: SIGSEGV inside + * gtk_tree_model_get_path (libgtk-3.so.0). + * + * ROOT CAUSE (mirrors the original JFace crash test provided in the ticket): + * + * Tree.removeAll() calls gtk_tree_store_clear(). GTK fires cellDataProc + * synchronously for rows that become visible as the cursor moves during + * deletion. For an UNCACHED root item (never rendered, so no ID column value in + * the model), Tree._getItem() calls getId() which calls gtk_tree_store_set() to + * assign the ID. That gtk_tree_store_set fires a synchronous "row-changed" + * signal which re-enters cellDataProc a second time for the same row. The inner + * cellDataProc finds the item still uncached and calls checkData() -> + * sendEvent(SWT.SetData). + * + * At this point gtk_tree_store_clear has already removed (and freed the GNodes + * of) the earlier root items and their children. The Java TreeItem objects for + * those freed rows are still alive (release() is called after + * gtk_tree_store_clear returns), but their handle field contains a GtkTreeIter + * whose user_data pointer is now dangling. + * + * JFace's SetData handler calls viewer.replace() which calls + * internalFindItems() -> getTreePathFromItem() -> getParentItem() on every + * existing TreeItem widget. Calling getParentItem() on any item whose GTK row + * has been freed passes the stale GtkTreeIter to gtk_tree_model_get_path(), + * which dereferences the freed GNode -> SIGSEGV at si_addr=0x17 (null-like + * offset into freed memory). + * + * This reproducer replicates that by explicitly calling getParentItem() on the + * previously-collected child items (same as getTreePathFromItem does) inside + * the SetData listener that fires during gtk_tree_store_clear. + */ +public class Issue3329_TreeCrashBug { + + private static final int ROOT_COUNT = 40; + private static final int CHILD_COUNT = 60; + + public static void main(String[] args) { + var display = new Display(); + var shell = new Shell(display); + shell.setLayout(new GridLayout()); + + var button = new Button(shell, SWT.PUSH); + button.setText("GO"); //$NON-NLS-1$ + + var tree = new Tree(shell, SWT.VIRTUAL | SWT.BORDER); + tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + // Collect every child TreeItem as it is rendered during v1 population. + // These objects hold GTK iters (GtkTreeIter.user_data -> GNode). + // After removeAll() frees those GNodes the handles become dangling. + List prevChildren = new ArrayList<>(); + + tree.addListener(SWT.SetData, e -> { + TreeItem item = (TreeItem) e.item; + TreeItem parent = item.getParentItem(); + if (parent == null) { + item.setText("v1_" + e.index); //$NON-NLS-1$ + item.setItemCount(CHILD_COUNT); + } else { + item.setText(parent.getText() + "_" + e.index); //$NON-NLS-1$ + prevChildren.add(item); // remember this child — its GNode will be freed on removeAll() + } + }); + + tree.setItemCount(ROOT_COUNT); + + // GO button: replace the tree content with a new version. + // Crashes if at least one root was expanded (prevChildren is non-empty) + // AND there are uncached roots below the visible viewport. + button.addListener(SWT.Selection, e -> { + for (var l : tree.getListeners(SWT.SetData)) { + tree.removeListener(SWT.SetData, l); + } + + // New SetData listener registered BEFORE removeAll(). + // It fires re-entrantly from inside gtk_tree_store_clear (via the + // cellDataProc -> getId -> gtk_tree_store_set -> row-changed -> cellDataProc + // -> checkData -> SetData chain described in the root-cause comment above). + // + // At the time it fires, the earlier roots and their children have + // already been removed; prevChildren[i].handle contains a freed GNode. + // Calling getParentItem() on those items passes the stale GtkTreeIter + // to gtk_tree_model_get_path() -> SIGSEGV. + // + // This mirrors AbstractTreeViewer.getTreePathFromItem() which walks all + // existing TreeItem widgets via getParentItem() inside internalFindItems(). + tree.addListener(SWT.SetData, ev -> { + for (TreeItem child : prevChildren) { + // child is NOT disposed yet (release() happens after gtk_tree_store_clear), + // but child.handle is a stale GtkTreeIter with a freed GNode pointer. + if (!child.isDisposed()) { + child.getParentItem(); // <-- SIGSEGV on production GTK3 + // G_DISABLE_CHECKS) + } + } + TreeItem item = (TreeItem) ev.item; + TreeItem parent = item.getParentItem(); + if (parent == null) { + item.setText("v2_" + ev.index); //$NON-NLS-1$ + item.setItemCount(CHILD_COUNT); + } else { + item.setText(parent.getText() + "_" + ev.index); //$NON-NLS-1$ + } + }); + + tree.removeAll(); // triggers the crash + tree.setItemCount(ROOT_COUNT); + }); + + shell.setSize(300, 250); // small window -> more uncached (out-of-viewport) roots + shell.open(); + + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + display.dispose(); + } +} \ No newline at end of file From dfbe84bdd181484480513bf2aa7610c5d548c87d Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Sat, 25 Jul 2026 17:11:26 +0200 Subject: [PATCH 28/46] [Win32] Remove unused ImageList.remove() method The ImageList.remove(int) method has no caller anywhere in the SWT codebase and it's not public API either. Besides being dead code, its implementation was also subtly wrong: after shifting the images array down it cleared images[index] instead of the now-vacated last slot images[count], which would corrupt the images-to-native mapping if it were ever used. Rather than fixing an unreachable method, remove it entirely to avoid accidental usage of a buggy method by future callers. --- .../win32/org/eclipse/swt/internal/ImageList.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/ImageList.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/ImageList.java index 05658442854..c32726acb1b 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/ImageList.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/ImageList.java @@ -394,14 +394,6 @@ public void put (int index, Image image) { images [index] = image; } -public void remove (int index) { - int count = OS.ImageList_GetImageCount (handle); - if (!(0 <= index && index < count)) return; - zoomToHandle.values().forEach(handle -> OS.ImageList_Remove (handle, index)); - System.arraycopy (images, index + 1, images, index, --count - index); - images [index] = null; -} - public int removeRef() { return --refCount; } From 635e9531bf068b245babc87dc2cc7221be0e429b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=8A?= =?UTF-8?q?=D1=80=20=D0=9A=D1=83=D1=80=D1=82=D0=B0=D0=BA=D0=BE=D0=B2?= Date: Mon, 27 Jul 2026 18:42:20 +0300 Subject: [PATCH 29/46] Update NOTICE to list only active source code repositories --- NOTICE | 4 ---- 1 file changed, 4 deletions(-) diff --git a/NOTICE b/NOTICE index 4785673f8a9..a8ba871c77e 100644 --- a/NOTICE +++ b/NOTICE @@ -26,11 +26,7 @@ SPDX-License-Identifier: EPL-2.0 The project maintains the following source code repositories: -* https://github.com/eclipse-platform/eclipse.platform.debug.git * https://github.com/eclipse-platform/eclipse.platform.git * https://github.com/eclipse-platform/eclipse.platform.releng.aggregator.git -* https://github.com/eclipse-platform/eclipse.platform.releng.buildtools.git -* https://github.com/eclipse-platform/eclipse.platform.releng.git * https://github.com/eclipse-platform/eclipse.platform.swt.git -* https://github.com/eclipse-platform/eclipse.platform.ua.git * https://github.com/eclipse-platform/eclipse.platform.ui.git From 7b3acfde62cf5ed432628307d7ae11734ea9f118 Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Fri, 24 Jul 2026 16:27:08 +0200 Subject: [PATCH 30/46] [Win32] Fix drawImage() failing for an empty image Drawing a blank (empty) image via GC.drawImage() with a scaled source/destination region failed with a NullPointerException. The nearest-zoom lookup tried to derive the zoom from an existing image handle, but an empty image has no handle yet, so the lookup resolved to null. The nearest-zoom lookup now falls back to using an empty image at 100% zoom when no image handle exists yet, so drawing an empty image succeeds. Adds an OS-independent GC test that draws an empty image with a scaled region to guard against this regression. Fixes https://github.com/eclipse-platform/eclipse.platform.swt/issues/3442 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../win32/org/eclipse/swt/graphics/Image.java | 17 ++++++++++++++--- .../junit/Test_org_eclipse_swt_graphics_GC.java | 14 ++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java index 962da6ee715..098efadcb9d 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java @@ -175,6 +175,15 @@ Set getAllZooms() { return zoomLevelToImageHandle.keySet(); } + Integer getNearestAvailableZoom(int zoom) { + TreeSet availableZooms = new TreeSet<>(getAllZooms()); + if (availableZooms.contains(zoom)) { + return zoom; + } + Integer higher = availableZooms.higher(zoom); + return higher != null ? higher : availableZooms.lower(zoom); + } + void destroyHandles(Predicate filter) { zoomLevelToImageHandle.entrySet().removeIf(entry -> { if (filter.test(entry.getKey())) { @@ -2155,8 +2164,7 @@ protected boolean isPersistentImageHandleRequriedForImageData() { abstract AbstractImageProviderWrapper createCopy(Image image); ElementAtZoom getClosestAvailableImageData(int zoom) { - TreeSet availableZooms = new TreeSet<>(imageHandleManager.getAllZooms()); - int closestZoom = availableZooms.contains(zoom) ? zoom : Optional.ofNullable(availableZooms.higher(zoom)).orElse(availableZooms.lower(zoom)); + int closestZoom = imageHandleManager.getNearestAvailableZoom(zoom); ImageData imageData = imageHandleManager.get(closestZoom).getImageData(); return new ElementAtZoom<>(imageData, closestZoom); } @@ -2467,7 +2475,10 @@ protected ElementAtZoom loadImageData(int zoom) { @Override int nearestAvailableZoom(int zoom) { - return getClosestAvailableImageData(zoom).zoom(); + if (imageHandleManager.isEmpty()) { + return 100; + } + return imageHandleManager.getNearestAvailableZoom(zoom); } @Override diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_GC.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_GC.java index 29b2292b5ab..5d7449c8e36 100644 --- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_GC.java +++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_GC.java @@ -382,6 +382,20 @@ public void test_drawImageLorg_eclipse_swt_graphics_ImageIIIIIIII() { images.dispose(); } +/** + * See https://github.com/eclipse-platform/eclipse.platform.swt/issues/3442 + */ +@Test +public void test_drawImage_emptyImage() { + Image emptyImage = new Image(display, IMAGE_SIZE, IMAGE_SIZE); + try { + gc.drawImage(emptyImage, 0, 0, IMAGE_SIZE, IMAGE_SIZE, 0, 0, IMAGE_SIZE / 3, IMAGE_SIZE / 3); + ImageDataTestHelper.assertImageDataEqual(image.getImageData(), emptyImage.getImageData(), image.getImageData()); + } finally { + emptyImage.dispose(); + } +} + @Test public void test_drawImageLorg_eclipse_swt_graphics_ImageIIII() { From c3b682b8be0227bbc8e6fa923849b636bfac50d9 Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Tue, 28 Jul 2026 16:39:48 +0200 Subject: [PATCH 31/46] [Win32] Reinitialize tool bar item images in place on DPI change A recent change forced a full image refresh for every ToolItem on every DPI change by nulling and re-setting the image in Item.handleDPIChange in order to ensure proper resizing of the ToolItem (issue #3073). That is costly (it removes and re-adds every item's image on every zoom change) and, for tool bars, it can relocate an item to a lower free slot in the image list when a hole is present, so re-adding the native button with its previously captured image index restores a stale slot - the item then shows another item's icon or a blank one. This change reverts Item.handleDPIChange to the cheap no-op refresh and lets ToolBar.handleDPIChange reinitialize each item's image in place via ToolItem.updateImages after the buttons have been re-added and the image lists refreshed. updateImages writes the rescaled image at the item's existing image list slot (no clear/re-add, so no relocation) and forces the button width to be recomputed, which keeps issue #3073 fixed without the overhead and without the wrong-icon regression. Fixes https://github.com/eclipse-platform/eclipse.platform.swt/issues/3466 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../swt/widgets/ToolBarWin32Tests.java | 191 ++++++++++++++++++ .../common/org/eclipse/swt/widgets/Item.java | 1 - .../org/eclipse/swt/widgets/ToolBar.java | 12 +- 3 files changed, 198 insertions(+), 6 deletions(-) create mode 100644 bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/widgets/ToolBarWin32Tests.java diff --git a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/widgets/ToolBarWin32Tests.java b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/widgets/ToolBarWin32Tests.java new file mode 100644 index 00000000000..c730c22d488 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/widgets/ToolBarWin32Tests.java @@ -0,0 +1,191 @@ +/******************************************************************************* + * Copyright (c) 2026 Vector Informatik GmbH and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.swt.widgets; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.*; +import java.util.function.*; + +import org.eclipse.swt.*; +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.internal.*; +import org.eclipse.swt.layout.*; +import org.junit.jupiter.api.*; +import org.junit.jupiter.api.extension.*; + +/** + * Windows-specific tests for {@link ToolBar}'s image handling across monitor + * zoom changes. + */ +@ExtendWith(PlatformSpecificExecutionExtension.class) +class ToolBarWin32Tests { + + private static final int TIMEOUT_MILLIS = 5000; + + private record ToolItemWithExpectedColor(ToolItem toolItem, RGB expectedColor) { + } + + /** + * Regression test for a tool bar item rendering the wrong or a blank icon after + * a monitor zoom (DPI) change, as reported in issue + * #3466. + *

+ * The bug is triggered by clearing one item's image (which leaves the image + * list in a state that a later zoom change mishandles); neither disposing an + * image nor multiple monitors are required. The test observes the actual + * rendered result via public API only: each item gets a distinctly colored + * icon, and after the zoom change the dominant color under each item must still + * match that item's own icon. + */ + @Test + void testIconsRenderedCorrectlyAfterZoomChangeWithImageListHole() { + Display display = new Display(); + RGB[] colors = { new RGB(220, 40, 40), new RGB(40, 180, 40), new RGB(40, 40, 220), new RGB(230, 200, 30) }; + Image[] icons = new Image[colors.length]; + for (int i = 0; i < colors.length; i++) { + icons[i] = solidIcon(display, 16, colors[i]); + } + try { + Shell shell = new Shell(display); + shell.setLayout(new FillLayout()); + ToolBar bar = new ToolBar(shell, SWT.FLAT); + ToolItem[] items = new ToolItem[colors.length]; + for (int i = 0; i < colors.length; i++) { + items[i] = new ToolItem(bar, SWT.PUSH); + items[i].setImage(icons[i]); + } + shell.setSize(500, 90); + shell.open(); + + // Punch a hole below the other items: clear the first item's image. + items[0].setImage(null); + + int zoom = bar.getAutoscalingZoom(); + DPITestUtil.changeDPIZoom(bar.getShell(), zoom * 2); + + // Only the first item is expected to rendered blank + Set itemsToCheck = new HashSet<>(); + for (int i = 1; i < items.length; i++) { + itemsToCheck.add(new ToolItemWithExpectedColor(items[i], colors[i])); + } + // Dispatch events until every item renders its own icon color, or fail on + // timeout. With the bug an item permanently renders another item's icon or + // a blank one, so the condition is never met and the timeout triggers. + assertTrue(waitUntilIconsRenderOwnColor(display, () -> iconsRenderOwnColor(bar, itemsToCheck, colors), + TIMEOUT_MILLIS), "every tool item must render its own icon color after a zoom change"); + } finally { + for (Image icon : icons) + icon.dispose(); + display.dispose(); + } + } + + private static boolean waitUntilIconsRenderOwnColor(Display display, BooleanSupplier condition, + long timeoutMillis) { + long deadline = System.currentTimeMillis() + timeoutMillis; + while (System.currentTimeMillis() < deadline) { + if (condition.getAsBoolean()) { + return true; + } + if (!display.readAndDispatch()) { + try { + Thread.sleep(10); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + break; + } + } + } + return condition.getAsBoolean(); + } + + private static boolean iconsRenderOwnColor(ToolBar bar, Set items, RGB[] candidateColors) { + Image snapshot = renderToolBar(bar); + try { + for (ToolItemWithExpectedColor item : items) { + if (!item.expectedColor().equals(dominantIconColor(snapshot, item.toolItem().getBounds(), candidateColors))) { + return false; + } + } + return true; + } finally { + snapshot.dispose(); + } + } + + private static Image solidIcon(Display display, int size, RGB rgb) { + Image image = new Image(display, size, size); + GC gc = new GC(image); + Color color = new Color(display, rgb); + gc.setBackground(color); + gc.fillRectangle(0, 0, size, size); + gc.dispose(); + return image; + } + + private static Image renderToolBar(ToolBar bar) { + Point size = bar.getSize(); + Image snapshot = new Image(bar.getDisplay(), Math.max(1, size.x), Math.max(1, size.y)); + GC gc = new GC(snapshot); + bar.print(gc); + gc.dispose(); + return snapshot; + } + + /** + * Returns which of the given candidate icon colors dominates the area of an + * item. Each sufficiently saturated pixel is classified to its nearest + * candidate color; the candidate matching the most pixels wins. Classifying to + * a fixed palette (rather than comparing exact RGB values) makes the result + * deterministic despite anti-aliasing, DPI interpolation and theming. + */ + private static RGB dominantIconColor(Image snapshot, Rectangle bounds, RGB[] candidates) { + ImageData data = snapshot.getImageData(); + PaletteData palette = data.palette; + int[] votes = new int[candidates.length]; + int x0 = Math.max(0, bounds.x), y0 = Math.max(0, bounds.y); + int x1 = Math.min(data.width, bounds.x + bounds.width); + int y1 = Math.min(data.height, bounds.y + bounds.height); + for (int y = y0; y < y1; y++) { + for (int x = x0; x < x1; x++) { + RGB rgb = palette.getRGB(data.getPixel(x, y)); + int max = Math.max(rgb.red, Math.max(rgb.green, rgb.blue)); + int min = Math.min(rgb.red, Math.min(rgb.green, rgb.blue)); + if (max - min < 60) { + continue; // ignore low-saturation background/borders + } + int best = -1, bestDist = Integer.MAX_VALUE; + for (int c = 0; c < candidates.length; c++) { + int dr = rgb.red - candidates[c].red; + int dg = rgb.green - candidates[c].green; + int db = rgb.blue - candidates[c].blue; + int dist = dr * dr + dg * dg + db * db; + if (dist < bestDist) { + bestDist = dist; + best = c; + } + } + if (best >= 0) + votes[best]++; + } + } + int winner = -1, most = 0; + for (int c = 0; c < candidates.length; c++) { + if (votes[c] > most) { + most = votes[c]; + winner = c; + } + } + return winner < 0 ? null : candidates[winner]; + } +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Item.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Item.java index fd33f71ca76..c3e16f24878 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Item.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Item.java @@ -230,7 +230,6 @@ private void handleDPIChange(Event event) { // Refresh the image Image image = getImage(); if (image != null) { - setImage(null); setImage(image); } } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolBar.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolBar.java index 6e523eef5b3..773899aeb6e 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolBar.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolBar.java @@ -1738,6 +1738,11 @@ record ToolItemData(ToolItem toolItem, TBBUTTON button) { } } } + // Refresh the image lists so the image list for the correct zoom is used + setImageList(getImageList()); + setDisabledImageList(getDisabledImageList()); + setHotImageList(getHotImageList()); + boolean toolBarEnabled = getEnabled(); for (int i = 0; i < itemCount; i++) { ToolItem item = toolItems[i]; // If the separator is used with a control, we must reset the size to the cached value, @@ -1745,12 +1750,9 @@ record ToolItemData(ToolItem toolItem, TBBUTTON button) { if ((item.style & SWT.SEPARATOR) != 0 && item.getControl() != null) { item.setWidth(seperatorWidth[i]); } + // Make sure the tool item is resized with the new image and font size + toolItems[i].updateImages(toolItems[i].getEnabled() && toolBarEnabled); } - - // Refresh the image lists so the image list for the correct zoom is used - setImageList(getImageList()); - setDisabledImageList(getDisabledImageList()); - setHotImageList(getHotImageList()); OS.SendMessage(handle, OS.TB_AUTOSIZE, 0, 0); clearSizeCache(true); } From 80af470ab08319d97ba636bd33f5022969bf9a54 Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Tue, 28 Jul 2026 20:34:44 +0200 Subject: [PATCH 32/46] [Win32] Capture tool bar button image index after zoom refresh On a monitor zoom (DPI) change, ToolBar.handleDPIChange removes and re-adds every button so Windows re-lays out the tool bar at the new zoom. It snapshots each button with TB_GETBUTTON - including its image-list slot index (iBitmap) - and re-adds the button from that snapshot. So far the snapshot was taken before the item was notified of the zoom change. If that notification changes an item's image-list slot, the re-added button carries a stale image index and the item shows another item's icon or a blank one. With this change, we capture the button with TB_GETBUTTON after notifyListeners(ZoomChanged) instead, so the current, post-refresh image index is always the one that is re-added. This makes the image-index capture correct by construction and guards against an item's image-list slot changing while the zoom change is handled. Contributes to https://github.com/eclipse-platform/eclipse.platform.swt/issues/3466 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../win32/org/eclipse/swt/widgets/ToolBar.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolBar.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolBar.java index 773899aeb6e..68e839fcefe 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolBar.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolBar.java @@ -1712,8 +1712,6 @@ record ToolItemData(ToolItem toolItem, TBBUTTON button) { // Remove and re-add all button the let Windows resize the tool bar Stack buttondata = new Stack<>(); for (int i = itemCount - 1; i >= 0; i--) { - TBBUTTON lpButton = new TBBUTTON (); - OS.SendMessage (handle, OS.TB_GETBUTTON, i, lpButton); ToolItem item = toolItems[i]; if ((item.style & SWT.SEPARATOR) != 0 && item.getControl() != null) { // Take note of widths of separators with control, so they can be resized @@ -1721,6 +1719,13 @@ record ToolItemData(ToolItem toolItem, TBBUTTON button) { seperatorWidth[i] = item.getWidth(); } item.notifyListeners(SWT.ZoomChanged, event); + // Capture the button data AFTER handling the zoom change. The zoom refresh + // may update the item's image-list slot (iBitmap), so capturing the button + // beforehand could re-add it with a stale image index, resulting in the + // wrong (or a blank) icon being shown. Reading the button here ensures the + // current, post-refresh image index is preserved. + TBBUTTON lpButton = new TBBUTTON (); + OS.SendMessage (handle, OS.TB_GETBUTTON, i, lpButton); buttondata.push(new ToolItemData(item, lpButton)); OS.SendMessage(handle, OS.TB_DELETEBUTTON, i, 0); } From d4c07affc760e0072bc10ad478c500fe8e979b4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=8A?= =?UTF-8?q?=D1=80=20=D0=9A=D1=83=D1=80=D1=82=D0=B0=D0=BA=D0=BE=D0=B2?= Date: Wed, 29 Jul 2026 11:28:21 +0300 Subject: [PATCH 33/46] [GTK4] Re-layout Composite subtree when shown to fix collapsed content On GTK4, gtk_widget_hide() resets a widget's allocation to 0x0. A Composite that is laid out while it (or an ancestor) is hidden therefore sizes its children against a stale 0x0 client area, leaving them collapsed at their minimum size once the Composite is finally shown. The content only expands after a manual resize forces a re-layout. The size given while hidden is still stored in the parent's swt_fixed child list. When such a Composite is shown, re-run the parent's size allocation to re-apply this control's real size (restoring its client area), then re-layout its own subtree so the children pick up the now-correct client area. Fixes https://github.com/eclipse-platform/eclipse.platform.swt/issues/3450 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../gtk/org/eclipse/swt/widgets/Control.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java index 6671563a3cc..59ac7ed8968 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java @@ -6166,6 +6166,20 @@ public void setVisible (boolean visible) { if (enableWindow != 0) GDK.gdk_window_show_unraised(enableWindow); } gtk_widget_show (topHandle); + /* + * On GTK4, a Composite laid out while it (or an ancestor) is hidden can end + * up with its children sized against a stale 0x0 client area, because + * gtk_widget_hide() resets allocations to 0x0 (issue #3330) and setBounds on a + * hidden widget shows/allocates/re-hides it. The size given while hidden is + * still stored in the parent's swt_fixed child list, so re-running the parent's + * size allocation re-applies this control's real size (restoring its client + * area), after which a re-layout of its own subtree lets the children pick up + * the now-correct client area. See issue #3450. + */ + if (GTK.GTK4 && this instanceof Composite composite && composite.layout != null) { + parent.forceResize (); + composite.layout (true, true); + } } } else { /* From d83771d11c9577bbae4d3a403863a9799ea261cd Mon Sep 17 00:00:00 2001 From: Lars Vogel Date: Tue, 28 Jul 2026 18:28:03 +0200 Subject: [PATCH 34/46] [Win32] Fix wrong CTabFolder header height after zoom change Since the tab height also accounts for the top-left/top-right tab controls, it depends on Control#computeSize() of those controls. That size is only meaningful once the control has processed the zoom change itself: a control is scaled from pixels to points using its parent's zoom, and on a DPI change the folder is rescaled before its children. Measuring a child in that window mixes the old zoom's pixel size with the new zoom, which yields a too large tab height when moving from a higher to a lower zoom. Nothing recomputed the tab height afterwards, so the header stayed too high until the folder was updated for another reason, for example by selecting a different tab. Recompute the tab height when a tab control reports a zoom change. The listener is added after the control's own zoom handling is registered, so the control is already rescaled when the folder measures it again. The added test drives a tab control that reports a stale size and then sends a zoom change, so it verifies the recomputation on all platforms without requiring monitors with different scaling. Fixes https://github.com/eclipse-platform/eclipse.platform.swt/issues/3456 --- .../org/eclipse/swt/custom/CTabFolder.java | 7 ++ ...est_org_eclipse_swt_custom_CTabFolder.java | 69 +++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolder.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolder.java index 03aac63eafc..418da72a628 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolder.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolder.java @@ -172,6 +172,7 @@ public class CTabFolder extends Composite { int[] priority = new int[0]; boolean mru = false; Listener listener; + Listener tabControlZoomListener; boolean ignoreTraverse; boolean useDefaultRenderer; @@ -345,6 +346,10 @@ void init(int style) { } }; + // A tab control is rescaled after the folder itself, so its size can only be + // measured reliably once it has processed the zoom change on its own. + tabControlZoomListener = event -> updateFolder(UPDATE_TAB_HEIGHT | REDRAW); + int[] folderEvents = new int[]{ SWT.Dispose, SWT.DragDetect, @@ -4186,6 +4191,7 @@ void addTabControl(Control control, int flags, int index, boolean update) { int length = controls.length; control.addListener(SWT.Resize, listener); + control.addListener(SWT.ZoomChanged, tabControlZoomListener); //Grow all 4 arrays Control[] newControls = new Control [length + 1]; @@ -4247,6 +4253,7 @@ void removeTabControl (Control control, boolean update) { if (!control.isDisposed()) { control.removeListener(SWT.Resize, listener); + control.removeListener(SWT.ZoomChanged, tabControlZoomListener); control.setBackground (null); control.setBackgroundImage (null); if (control instanceof Composite) ((Composite) control).setBackgroundMode(SWT.INHERIT_NONE); diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_custom_CTabFolder.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_custom_CTabFolder.java index ac61c9e2984..66ca7167ca3 100644 --- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_custom_CTabFolder.java +++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_custom_CTabFolder.java @@ -45,7 +45,9 @@ import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.internal.DPIUtil; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; @@ -54,6 +56,7 @@ import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Layout; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.ToolBar; @@ -69,6 +72,7 @@ * * @see org.eclipse.swt.custom.CTabFolder */ +@SuppressWarnings("restriction") public class Test_org_eclipse_swt_custom_CTabFolder extends Test_org_eclipse_swt_widgets_Composite { @Override @@ -522,6 +526,51 @@ public void test_topRightWrapOverflow() { + "topRight.y=" + topRightBounds.y + " tab.bottom=" + (tabBounds.y + tabBounds.height)); } +/** + * A tab control is rescaled after the folder itself, so the folder must recompute + * its tab height once a tab control reports a zoom change. Test for issue 3456. + */ +@Test +public void test_tabHeightRecomputedOnTabControlZoomChange() { + makeCleanEnvironment(); + shell.setSize(800, 400); + + CTabItem item = new CTabItem(ctabFolder, SWT.NONE); + item.setText("Tab 1"); + ctabFolder.setSelection(0); + + int topRightHeight = 20; + Composite topRight = new Composite(ctabFolder, SWT.NONE); + FixedSizeLayout topRightLayout = new FixedSizeLayout(60, topRightHeight); + topRight.setLayout(topRightLayout); + ctabFolder.setTopRight(topRight, SWT.RIGHT | SWT.WRAP); + + SwtTestUtil.openShell(shell); + processEvents(); + + int defaultTabHeight = ctabFolder.getTabHeight(); + + // A taller tab control makes the folder grow its tab height + topRightLayout.height = defaultTabHeight * 3; + ctabFolder.setTabHeight(SWT.DEFAULT); + processEvents(); + int grownTabHeight = ctabFolder.getTabHeight(); + assertTrue(grownTabHeight > defaultTabHeight, "tab height should grow with the tab control"); + + // Shrinking the tab control alone leaves the tab height stale, which is the state + // the folder ends up in after measuring a control that was not yet rescaled + topRightLayout.height = topRightHeight; + assertEquals(grownTabHeight, ctabFolder.getTabHeight(), "precondition: tab height is stale"); + + Event zoomChanged = new Event(); + zoomChanged.detail = DPIUtil.getDeviceZoom(); + topRight.notifyListeners(SWT.ZoomChanged, zoomChanged); + processEvents(); + + assertEquals(defaultTabHeight, ctabFolder.getTabHeight(), + "tab height should be recomputed after a zoom change of a tab control"); +} + /** * Min/max and chevron icon can appear below tab row. * Test for bug 499215, 533582. @@ -1117,4 +1166,24 @@ public void test_moveItem_errorCases() { "out-of-range to index must be rejected"); } +/** Layout with a preferred size the test can change at will. */ +private static final class FixedSizeLayout extends Layout { + int width; + int height; + + FixedSizeLayout(int width, int height) { + this.width = width; + this.height = height; + } + + @Override + protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) { + return new Point(wHint == SWT.DEFAULT ? width : wHint, hHint == SWT.DEFAULT ? height : hHint); + } + + @Override + protected void layout(Composite composite, boolean flushCache) { + } +} + } From 4043f48ac1bd53e2650a708ea180c276ae675d63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=8A?= =?UTF-8?q?=D1=80=20=D0=9A=D1=83=D1=80=D1=82=D0=B0=D0=BA=D0=BE=D0=B2?= Date: Thu, 30 Jul 2026 15:33:32 +0300 Subject: [PATCH 35/46] [GTK4] Fix empty lazily-populated submenus (e.g. File > New) Wire nested GtkPopoverMenu SHOW/HIDE via the model's "items-changed" signal (connected in the after phase, so GTK has already rebuilt the popover) and re-discover popovers on each pass to handle GTK rebuilds. Replaces the previous fixed-count retry. Fixes https://github.com/eclipse-platform/eclipse.platform.swt/issues/3451 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../gtk/org/eclipse/swt/internal/gtk/OS.java | 1 + .../gtk/org/eclipse/swt/widgets/Display.java | 15 ++ .../gtk/org/eclipse/swt/widgets/Menu.java | 144 ++++++++++++++---- .../gtk/org/eclipse/swt/widgets/MenuItem.java | 18 +++ 4 files changed, 151 insertions(+), 27 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java index aa70f5a3f23..a070c4d1329 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java @@ -411,6 +411,7 @@ public static String getEnvironmentalVariable (String envVarName) { public static final byte[] hide = ascii("hide"); public static final byte[] icon_release = ascii("icon-release"); public static final byte[] insert_text = ascii("insert-text"); + public static final byte[] items_changed = ascii("items-changed"); public static final byte[] key_press_event = ascii("key-press-event"); public static final byte[] key_release_event = ascii("key-release-event"); public static final byte[] key_pressed = ascii("key-pressed"); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java index ab7d2e476e3..4a1bc89cce3 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java @@ -135,12 +135,14 @@ public class Display extends Device implements Executor { long changeValueProc; long snapshotDrawProc, keyPressReleaseProc, focusProc, windowActiveProc, enterMotionProc, leaveProc, scrollProc, resizeProc, layoutProc, activateProc, gesturePressReleaseProc; + long menuItemsChangedProc; long notifyProc; long computeSizeProc; Callback windowCallback2, windowCallback3, windowCallback4, windowCallback5, windowCallback6; Callback changeValue; Callback snapshotDraw, keyPressReleaseCallback, focusCallback, windowActiveCallback, enterMotionCallback, computeSizeCallback, scrollCallback, leaveCallback, resizeCallback, layoutCallback, activateCallback, gesturePressReleaseCallback; + Callback menuItemsChangedCallback; Callback notifyCallback; EventTable eventTable, filterTable; static String APP_NAME = "SWT"; //$NON-NLS-1$ @@ -3633,6 +3635,10 @@ void initializeCallbacks () { activateCallback = new Callback(this, "activateProc", void.class, new Type[] {long.class, long.class, long.class}); //$NON-NLS-1$ activateProc = activateCallback.getAddress(); + menuItemsChangedCallback = new Callback(this, "menuItemsChangedProc", void.class, new Type[] { + long.class, int.class, int.class, int.class, long.class}); //$NON-NLS-1$ + menuItemsChangedProc = menuItemsChangedCallback.getAddress(); + computeSizeCallback = new Callback(this, "computeSizeProc", void.class, new Type[] {long.class, long.class, long.class}); //$NON-NLS-1$ computeSizeProc = computeSizeCallback.getAddress(); } @@ -4671,6 +4677,10 @@ void releaseDisplay () { activateCallback = null; activateProc = 0; + menuItemsChangedCallback.dispose(); + menuItemsChangedCallback = null; + menuItemsChangedProc = 0; + computeSizeCallback.dispose(); computeSizeCallback = null; computeSizeProc = 0; @@ -6145,6 +6155,11 @@ void activateProc(long action, long parameter, long user_data) { widget.gtk_activate(user_data); } +void menuItemsChangedProc(long model, int position, int removed, int added, long user_data) { + Widget widget = getWidget(user_data); + if (widget instanceof Menu menu) menu.modelItemsChanged(); +} + void resizeProc(long handle, int width, int height) { Widget widget = getWidget(handle); if (widget != null) widget.gtk_size_allocate(handle, 0); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java index 8192253cb56..19467e4b2d3 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java @@ -944,6 +944,86 @@ long gtk_map (long widget) { return super.gtk_map(widget); } +/** + * Re-runs the CASCADE submenu SHOW/HIDE wiring after the menu structure changed + * while already mapped. The initial wiring at + * {@link #gtk_map}/{@link #gtk_show} only covers submenus that existed then; + * ones attached, replaced or rebuilt later would otherwise never get their + * {@link SWT#Show} event, making lazily-populated submenus appear empty. + */ +private void reconnectDropDownMenuSignalsIfMapped() { + if (!GTK.GTK4) return; + if ((style & SWT.BAR) != 0) { + if (handle != 0 && GTK.gtk_widget_get_mapped(handle)) { + connectDropDownMenuSignals(); + } + } else if ((style & SWT.POP_UP) != 0) { + if (handle != 0 && GTK.gtk_widget_get_mapped(handle)) { + connectCascadeSubMenuSignals(this, handle); + } + } else if ((style & SWT.DROP_DOWN) != 0) { + if (popoverHandle != 0 && GTK.gtk_widget_get_mapped(popoverHandle)) { + connectCascadeSubMenuSignals(this, popoverHandle); + } + } +} + +/** + * Hooks this menu's {@code items-changed} handler on the given {@code GMenu} + * model (no-op for {@code 0}), routing back via {@link #handle}. Connected in the + * signal's after phase so it runs once GTK's {@code GtkMenuTracker} has + * already (re)built the nested GtkPopoverMenu widgets, letting re-wiring run + * synchronously. + */ +void hookItemsChanged(long model) { + if (GTK.GTK4 && model != 0) { + long closure = OS.g_cclosure_new(display.menuItemsChangedProc, handle, 0); + OS.g_signal_connect_closure(model, OS.items_changed, closure, true); + } +} + +/** + * Called when this menu's {@code GMenuModel} emitted {@code items-changed} (its + * content was modified after creation). Re-runs the CASCADE submenu wiring from + * the nearest mapped ancestor so any nested GtkPopoverMenu GTK (re)built gets its + * {@link SWT#Show} routed to the SWT DROP_DOWN submenu. Runs synchronously (see + * {@link #hookItemsChanged(long)}); a cheap no-op if no ancestor is mapped. + */ +void modelItemsChanged() { + if (!GTK.GTK4 || isDisposed()) return; + Menu root = this; + while (root.cascade != null && root.cascade.parent != null && !root.cascade.parent.isDisposed()) { + root = root.cascade.parent; + } + root.reconnectDropDownMenuSignalsIfMapped(); +} + +/** + * Wires the SHOW/HIDE signals of the given DROP_DOWN {@code submenu} to the + * discovered {@code popover} GtkPopoverMenu widget, refreshing the SWT-side + * cache. If the submenu was previously wired to a now-stale popover (e.g. GTK + * rebuilt the widget after a model change), the stale handle is released first. + */ +private void wireSubMenuPopover(Menu submenu, long popover) { + if (submenu.popoverHandle == popover) return; + if (submenu.popoverHandle != 0) { + /* + * Release the stale popover we previously cached (mirrors deregister()). Its + * SHOW/HIDE closures are deliberately left connected: GTK normally destroys the + * widget along with the model change, and should it survive, removeWidget() above + * means its handlers no longer resolve to a widget and simply no-op. + */ + display.removeWidget(submenu.popoverHandle); + OS.g_object_unref(submenu.popoverHandle); + submenu.popoverHandle = 0; + } + OS.g_object_ref(popover); + submenu.popoverHandle = popover; + display.addWidget(popover, submenu); + OS.g_signal_connect_closure_by_id(popover, display.signalIds[SHOW], 0, display.getClosure(SHOW), false); + OS.g_signal_connect_closure_by_id(popover, display.signalIds[HIDE], 0, display.getClosure(HIDE), false); +} + private void connectDropDownMenuSignals() { if (items == null) return; long barItem = GTK4.gtk_widget_get_first_child(handle); @@ -951,17 +1031,13 @@ private void connectDropDownMenuSignals() { for (MenuItem menuItem : items) { if (barItem == 0) break; if ((menuItem.style & SWT.SEPARATOR) != 0) continue; - if (menuItem.menu != null && menuItem.menu.popoverHandle == 0) { + if (menuItem.menu != null) { long popover = findGtkPopoverMenuChild(barItem); - if (popover != 0) { - OS.g_object_ref(popover); - menuItem.menu.popoverHandle = popover; - display.addWidget(popover, menuItem.menu); - OS.g_signal_connect_closure_by_id(popover, display.signalIds[SHOW], 0, display.getClosure(SHOW), false); - OS.g_signal_connect_closure_by_id(popover, display.signalIds[HIDE], 0, display.getClosure(HIDE), false); - /* - * Also connect SHOW/HIDE signals for nested CASCADE submenus. - */ + /* Re-wire when the discovered popover differs from the cache (initial or GTK rebuilt it). */ + if (popover != 0 && menuItem.menu.popoverHandle != popover) { + wireSubMenuPopover(menuItem.menu, popover); + } + if (menuItem.menu.popoverHandle != 0) { connectCascadeSubMenuSignals(menuItem.menu); } } @@ -973,30 +1049,33 @@ private void connectCascadeSubMenuSignals(Menu menu) { connectCascadeSubMenuSignals(menu, menu.popoverHandle); } +/** + * Connects SHOW/HIDE signals for the CASCADE submenus of the given menu. A + * submenu whose GtkPopoverMenu is not (yet) present is simply skipped; the next + * pass triggered by MAP, SHOW or "items-changed" picks it up. + */ private void connectCascadeSubMenuSignals(Menu menu, long parentPopoverHandle) { if (menu == null || parentPopoverHandle == 0 || menu.items == null) return; for (MenuItem item : menu.items) { if ((item.style & SWT.CASCADE) != 0 && item.menu != null) { - /* - * item.menu is the CASCADE submenu (always SWT.DROP_DOWN style). - * Its popoverHandle is 0 until we find and register its GtkPopoverMenu. - * Skip if already connected (popoverHandle != 0). - */ - if (item.menu.popoverHandle != 0) continue; + /* Re-discover every pass: a rebuild can make GTK replace the widget, + * leaving a stale handle whose SHOW never fires (submenu appears empty). */ long nestedPopover = findNestedPopoverForModel(parentPopoverHandle, item.menu.modelHandle); if (nestedPopover != 0) { - OS.g_object_ref(nestedPopover); - item.menu.popoverHandle = nestedPopover; - display.addWidget(nestedPopover, item.menu); - OS.g_signal_connect_closure_by_id(nestedPopover, display.signalIds[SHOW], 0, display.getClosure(SHOW), false); - OS.g_signal_connect_closure_by_id(nestedPopover, display.signalIds[HIDE], 0, display.getClosure(HIDE), false); - // Recurse to handle further nested CASCADE submenus + if (item.menu.popoverHandle != nestedPopover) { + wireSubMenuPopover(item.menu, nestedPopover); + } connectCascadeSubMenuSignals(item.menu); } } } } +/** + * Recursively searches the widget subtree rooted at {@code parentWidget} for the + * nested GtkPopoverMenu whose GMenuModel is {@code targetModel}, returning its + * handle or {@code 0} if it is not (yet) present. + */ private long findNestedPopoverForModel(long parentWidget, long targetModel) { if (parentWidget == 0 || targetModel == 0) return 0; long child = GTK4.gtk_widget_get_first_child(parentWidget); @@ -1056,7 +1135,7 @@ long gtk_show (long widget) { return 0; } sendEvent (SWT.Show); - /* Retry cascade submenu signal hookup once the DROP_DOWN popover is shown. */ + /* Wire cascade submenu SHOW/HIDE signals once the DROP_DOWN popover is shown. */ if (GTK.GTK4 && (style & SWT.DROP_DOWN) != 0 && popoverHandle != 0) { connectCascadeSubMenuSignals(this, popoverHandle); } @@ -1116,15 +1195,26 @@ void hookEvents() { GTK4.gtk_shortcut_controller_set_scope(shortcutController, GTK.GTK_SHORTCUT_SCOPE_GLOBAL); GTK4.gtk_widget_add_controller(parent.handle, shortcutController); + /* + * Hook "items-changed" so content (re)built after creation re-runs the submenu + * wiring (see modelItemsChanged). Items go into per-section models and the + * signal does not propagate to the top model, so hook every section too + * (SEPARATOR sections in MenuItem.createHandle). + */ + hookItemsChanged(modelHandle); + if (sections != null && !sections.isEmpty()) { + hookItemsChanged(sections.getFirst().getSectionHandle()); + } + if ((style & SWT.DROP_DOWN) == 0) { OS.g_signal_connect_closure_by_id(handle, display.signalIds[SHOW], 0, display.getClosure(SHOW), false); OS.g_signal_connect_closure_by_id(handle, display.signalIds[HIDE], 0, display.getClosure(HIDE), false); if ((style & (SWT.BAR | SWT.POP_UP)) != 0) { /* - * Connect MAP signal on the GtkPopoverMenuBar so that once it is - * realized and its internal GtkPopoverMenuBarItem children exist, - * we can find the GtkPopoverMenu for each DROP_DOWN submenu and - * route SHOW/HIDE signals back to the SWT DROP_DOWN Menu. + * Connect MAP signal on the GtkPopoverMenuBar so that once it is realized and + * its internal GtkPopoverMenuBarItem children exist, we can find the + * GtkPopoverMenu for each DROP_DOWN submenu and route SHOW/HIDE signals back to + * the SWT DROP_DOWN Menu. */ OS.g_signal_connect_closure_by_id(handle, display.signalIds[MAP], 0, display.getClosure(MAP), false); } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java index e98a8b02291..7da844bbf40 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java @@ -264,6 +264,12 @@ void createHandle(int index) { case SWT.SEPARATOR: modelHandle = OS.g_menu_new(); handle = OS.g_menu_item_new_section(null, modelHandle); + /* + * A separator starts a new section GMenu; observe it for + * "items-changed" too so submenus added into this section later get + * wired (see Menu#hookItemsChanged and issue #3451). + */ + parent.hookItemsChanged(modelHandle); break; case SWT.RADIO: long stringVariantType = OS.g_variant_type_new(OS.G_VARIANT_TYPE_STRING); @@ -1148,6 +1154,18 @@ public void setMenu (Menu menu) { OS.g_menu_remove(section.getSectionHandle(), section.getItemPosition(this)); OS.g_menu_insert_item(section.getSectionHandle(), section.getItemPosition(this), handle); + + /* + * If a DROP_DOWN is attached while its parent is already mapped (contributions + * added/rebuilt after the parent was shown, e.g. workspace restore), wire its + * SHOW/HIDE now; otherwise SWT.Show never fires and the submenu appears empty + * (issue #3451). The g_menu calls above already emit "items-changed" on the + * section model, so this is normally redundant; go through modelItemsChanged() + * anyway so both paths re-wire from the same (root) menu. + */ + if (menu != null) { + parent.modelItemsChanged(); + } } else { long accelGroup = getAccelGroup (); if (accelGroup != 0) removeAccelerators (accelGroup); From 9ad9b7350f97284466803125dcaaf1501c8b7d09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=8A?= =?UTF-8?q?=D1=80=20=D0=9A=D1=83=D1=80=D1=82=D0=B0=D0=BA=D0=BE=D0=B2?= Date: Wed, 29 Jul 2026 13:41:31 +0300 Subject: [PATCH 36/46] GTK4: Fix empty popup for disabled CASCADE menu items On GTK4 a SWT.CASCADE menu item was created via g_menu_item_new_submenu which has no associated action. setEnabled() only manipulates the item's action, so calling setEnabled(false) on a cascade item was a no-op: the item stayed sensitive and opened an empty popover. getEnabled() also hard-coded true for cascade items. On GTK3 the same call correctly greys out the item via gtk_widget_set_sensitive. This affected e.g. Navigate > Back/Forward, which Eclipse disables when there is nothing to navigate to: on GTK4 they remained enabled and showed an empty menu. Create cascade items with a backing SimpleAction (g_menu_item_new plus g_menu_item_set_submenu) so their sensitivity can be toggled, and return the action's enabled state from getEnabled() for all GTK4 items. The activate signal is not wired for cascade items, so opening the submenu still works and navigation is not hijacked. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../gtk/org/eclipse/swt/widgets/MenuItem.java | 21 ++++++++++++++----- ...Test_org_eclipse_swt_widgets_MenuItem.java | 13 ++++++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java index 7da844bbf40..8632703218d 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java @@ -295,7 +295,22 @@ void createHandle(int index) { break; case SWT.CASCADE: modelHandle = OS.g_menu_new(); - handle = OS.g_menu_item_new_submenu(Converter.javaStringToCString(""), modelHandle); + /* + * Give the CASCADE item an action so it can be enabled/disabled like + * on the other platforms and like GTK3. A plain submenu item created + * via g_menu_item_new_submenu has no action, so its GtkModelButton is + * always sensitive: setEnabled(false) would be a no-op and the (possibly + * empty) submenu could still be opened. Attaching a SimpleAction makes + * the item follow the action's enabled state. While the action is + * enabled, activating the item still navigates into the submenu (the + * action is not triggered); while disabled, the item is insensitive and + * the submenu cannot be opened. + */ + actionHandle = OS.g_simple_action_new(Converter.javaStringToCString(String.valueOf(this.hashCode())), 0); + OS.g_action_map_add_action(parent.actionGroup, actionHandle); + actionName = String.valueOf(parent.hashCode()) + "." + String.valueOf(this.hashCode()); + handle = OS.g_menu_item_new(Converter.javaStringToCString(""), Converter.javaStringToCString(actionName)); + OS.g_menu_item_set_submenu(handle, modelHandle); break; case SWT.PUSH: default: @@ -523,10 +538,6 @@ public boolean getEnabled () { checkWidget(); if (GTK.GTK4) { - if ((style & SWT.CASCADE) != 0) { - return true; - } - return OS.g_action_get_enabled(actionHandle); } else { return GTK.gtk_widget_get_sensitive(handle); diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_MenuItem.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_MenuItem.java index 1db0b857eca..5ea3cbc497d 100644 --- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_MenuItem.java +++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_MenuItem.java @@ -195,6 +195,19 @@ public void test_setEnabledZ() { assertFalse(menuItem.getEnabled()); } +@Test +public void test_setEnabledZ_cascade() { + MenuItem cascadeItem = new MenuItem(menu, SWT.CASCADE); + Menu subMenu = new Menu(shell, SWT.DROP_DOWN); + cascadeItem.setMenu(subMenu); + assertTrue(cascadeItem.getEnabled()); + cascadeItem.setEnabled(false); + assertFalse(cascadeItem.getEnabled()); + cascadeItem.setEnabled(true); + assertTrue(cascadeItem.getEnabled()); + cascadeItem.dispose(); +} + @Tag("gtk4-todo") @Override @Test From 5ac8459f37af8efdb6a05d167ea3c9de1dec2b58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=8A?= =?UTF-8?q?=D1=80=20=D0=9A=D1=83=D1=80=D1=82=D0=B0=D0=BA=D0=BE=D0=B2?= Date: Thu, 30 Jul 2026 18:59:00 +0300 Subject: [PATCH 37/46] [GTK4] Remove menu item actions from the action group on dispose Menu inserts its action group on the shell under a prefix, so an item's action has two names: the plain one it was registered with, and the detailed menuHash.itemHash that resolves through the prefix. releaseWidget() passed the detailed name to g_action_map_remove_action(), which keys actions by their plain name, so it silently removed nothing and entries accumulated for the lifetime of the group. Store the plain name as actionId and remove by that, keeping actionName for the places that refer to an action by name (GMenuItem, GtkNamedAction). All four item styles were affected. This does not free the action itself: the reference from g_simple_action_new() is never released, and unref'ing it here leaves the top-level menu bar items without labels. Co-Authored-By: Claude Opus 5 (1M context) --- .../gtk/org/eclipse/swt/widgets/MenuItem.java | 40 ++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java index 8632703218d..b28f41db7e1 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java @@ -68,6 +68,19 @@ public class MenuItem extends Item { /** GTK4 only fields */ long modelHandle, actionHandle, shortcutHandle; Section section; + /** + * The action's own name within the parent's action group, i.e. the name + * g_simple_action_new() was given. Use this with the GActionMap API (e.g. + * g_action_map_remove_action), which keys actions by their plain name. + */ + String actionId; + /** + * The detailed action name: actionId qualified with the prefix the + * action group was inserted under (see Menu#createHandle), plus a target for + * SWT.RADIO. Use this where an action is referenced by name, such as + * g_menu_item_new() or gtk_named_action_new(), and never with the GActionMap + * API. + */ String actionName; /** @@ -273,23 +286,25 @@ void createHandle(int index) { break; case SWT.RADIO: long stringVariantType = OS.g_variant_type_new(OS.G_VARIANT_TYPE_STRING); + actionId = String.valueOf(this.hashCode()); actionHandle = OS.g_simple_action_new_stateful( - Converter.javaStringToCString(String.valueOf(this.hashCode())), + Converter.javaStringToCString(actionId), stringVariantType, OS.g_variant_new_string(Converter.javaStringToCString("untoggled"))); OS.g_action_map_add_action(parent.actionGroup, actionHandle); - actionName = String.valueOf(parent.hashCode()) + "." + String.valueOf(this.hashCode()) + "::toggled"; + actionName = String.valueOf(parent.hashCode()) + "." + actionId + "::toggled"; handle = OS.g_menu_item_new(null, Converter.javaStringToCString(actionName)); OS.g_variant_type_free(stringVariantType); break; case SWT.CHECK: long boolVariantType = OS.g_variant_type_new(OS.G_VARIANT_TYPE_BOOLEAN); + actionId = String.valueOf(this.hashCode()); actionHandle = OS.g_simple_action_new_stateful( - Converter.javaStringToCString(String.valueOf(this.hashCode())), + Converter.javaStringToCString(actionId), 0, OS.g_variant_new_boolean(false)); OS.g_action_map_add_action(parent.actionGroup, actionHandle); - actionName = String.valueOf(parent.hashCode()) + "." + String.valueOf(this.hashCode()); + actionName = String.valueOf(parent.hashCode()) + "." + actionId; handle = OS.g_menu_item_new(null, Converter.javaStringToCString(actionName)); OS.g_variant_type_free(boolVariantType); break; @@ -306,17 +321,19 @@ void createHandle(int index) { * action is not triggered); while disabled, the item is insensitive and * the submenu cannot be opened. */ - actionHandle = OS.g_simple_action_new(Converter.javaStringToCString(String.valueOf(this.hashCode())), 0); + actionId = String.valueOf(this.hashCode()); + actionHandle = OS.g_simple_action_new(Converter.javaStringToCString(actionId), 0); OS.g_action_map_add_action(parent.actionGroup, actionHandle); - actionName = String.valueOf(parent.hashCode()) + "." + String.valueOf(this.hashCode()); + actionName = String.valueOf(parent.hashCode()) + "." + actionId; handle = OS.g_menu_item_new(Converter.javaStringToCString(""), Converter.javaStringToCString(actionName)); OS.g_menu_item_set_submenu(handle, modelHandle); break; case SWT.PUSH: default: - actionHandle = OS.g_simple_action_new(Converter.javaStringToCString(String.valueOf(this.hashCode())), 0); + actionId = String.valueOf(this.hashCode()); + actionHandle = OS.g_simple_action_new(Converter.javaStringToCString(actionId), 0); OS.g_action_map_add_action(parent.actionGroup, actionHandle); - actionName = String.valueOf(parent.hashCode()) + "." + String.valueOf(this.hashCode()); + actionName = String.valueOf(parent.hashCode()) + "." + actionId; handle = OS.g_menu_item_new(null, Converter.javaStringToCString(actionName)); break; } @@ -760,7 +777,12 @@ void releaseWidget() { super.releaseWidget(); if (GTK.GTK4) { - if (parent.actionGroup != 0 && actionName != null) OS.g_action_map_remove_action(parent.actionGroup, Converter.javaStringToCString(actionName)); + /* + * Remove by actionId, not actionName: GActionMap keys actions by their own + * name, so passing the prefixed detailed name silently removes nothing and + * leaks the action for the lifetime of the parent's action group. + */ + if (parent.actionGroup != 0 && actionId != null) OS.g_action_map_remove_action(parent.actionGroup, Converter.javaStringToCString(actionId)); } else { long accelGroup = getAccelGroup(); if (accelGroup != 0) removeAccelerator(accelGroup); From 949d9dd73215aaebef60da6133e43544b8db3c1e Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Fri, 31 Jul 2026 17:01:04 +0200 Subject: [PATCH 38/46] Add BrowserFunction dispose/redefine regression tests Add two backend-agnostic regression tests for BrowserFunction lifecycle: - a disposed BrowserFunction must not be re-injected on a subsequently loaded page - redefining a function with the same name takes effect and survives navigation, and the previous definition is not resurrected Co-Authored-By: Claude Opus 4.8 --- .../Test_org_eclipse_swt_browser_Browser.java | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_browser_Browser.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_browser_Browser.java index ffef5ae21e7..651f6d0fd2d 100644 --- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_browser_Browser.java +++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_browser_Browser.java @@ -3045,6 +3045,79 @@ public void test_BrowserFunction_availableOnLoad_concurrentInstances_issue20() { assertTrue(browser2FuncAvailable.get(), "BrowserFunction for second browser missing when page load completed"); } +/** + * Regression test: a disposed BrowserFunction must no longer be available (re-injected) after a + * subsequent navigation. This verifies that deregistration removes the persistent document-created + * script (whose ID is captured asynchronously on the Edge backend). + */ +@Test +public void test_BrowserFunction_disposedFunctionRemovedAfterNavigation() { + BrowserFunction function = new BrowserFunction(browser, "disposableFunc") { + @Override + public Object function(Object[] arguments) { + return "alive"; + } + }; + + AtomicBoolean firstPageLoaded = new AtomicBoolean(false); + ProgressListener firstPageListener = completedAdapter(e -> firstPageLoaded.set(true)); + browser.addProgressListener(firstPageListener); + browser.setText("first page"); + shell.open(); + assertTrue(waitForPassCondition(firstPageLoaded::get), "First page did not load"); + // The function is registered and usable now (this also ensures its registration has settled). + assertEquals("alive", browser.evaluate("return disposableFunc();")); + browser.removeProgressListener(firstPageListener); + + // Dispose the function, then navigate: it must be gone on the new page. + function.dispose(); + AtomicBoolean secondPageLoaded = new AtomicBoolean(false); + browser.addProgressListener(completedAdapter(e -> secondPageLoaded.set(true))); + browser.setText("second page"); + assertTrue(waitForPassCondition(secondPageLoaded::get), "Second page did not load"); + + Object stillDefined = browser.evaluate("return typeof disposableFunc === 'function';"); + assertEquals(Boolean.FALSE, stillDefined, + "A disposed BrowserFunction must not be re-injected on a subsequently loaded page"); +} + +/** + * Regression test: redefining a BrowserFunction with the same name (which deregisters the previous + * one and registers the new one) must take effect and survive navigations - the newest definition + * wins and the previous one is not resurrected. + */ +@Test +public void test_BrowserFunction_redefineSameNameSurvivesNavigation() { + new BrowserFunction(browser, "f") { + @Override + public Object function(Object[] arguments) { + return "v1"; + } + }; + new BrowserFunction(browser, "f") { + @Override + public Object function(Object[] arguments) { + return "v2"; + } + }; + + AtomicBoolean firstPageLoaded = new AtomicBoolean(false); + ProgressListener firstPageListener = completedAdapter(e -> firstPageLoaded.set(true)); + browser.addProgressListener(firstPageListener); + browser.setText("first page"); + shell.open(); + assertTrue(waitForPassCondition(firstPageLoaded::get), "First page did not load"); + assertEquals("v2", browser.evaluate("return f();"), "The most recent definition of 'f' must win"); + browser.removeProgressListener(firstPageListener); + + AtomicBoolean secondPageLoaded = new AtomicBoolean(false); + browser.addProgressListener(completedAdapter(e -> secondPageLoaded.set(true))); + browser.setText("second page"); + assertTrue(waitForPassCondition(secondPageLoaded::get), "Second page did not load"); + assertEquals("v2", browser.evaluate("return f();"), + "The redefined BrowserFunction must survive navigation and the previous definition must not be resurrected"); +} + @Test @Disabled("Too fragile on CI, Display.getDefault().post(event) does not work reliably") public void test_TabTraversalOutOfBrowser() { From 974503e51fdd23652f19c1405d29cd89d5c73312 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=8A?= =?UTF-8?q?=D1=80=20=D0=9A=D1=83=D1=80=D1=82=D0=B0=D0=BA=D0=BE=D0=B2?= Date: Mon, 3 Aug 2026 13:20:45 +0300 Subject: [PATCH 39/46] [GTK4] Fix segfault when a Tree or Table shows a drop highlight gtk_tree_view_bin_snapshot() renders the highlight set by gtk_tree_view_set_drag_dest_row() through di->cssnode, but di is the private TreeViewDragInfo struct that only gtk_tree_view_enable_model_drag_dest() ever allocates, and the deref has no NULL check. SWT drives the highlight itself, from Tree.setInsertMark() and from the Tree/Table drop target effects when the drop feedback asks for FEEDBACK_SELECT or FEEDBACK_INSERT_BEFORE/AFTER, so the next repaint dereferenced NULL and crashed. GTK3 is unaffected, it did not use a CSS node here. Allocate the struct in createHandle() with an empty format list and no actions, which makes the drop target GTK installs alongside it reject every drag in gtk_drop_target_async_accept(), so GTK's own tree view drag handlers stay out of the way of SWT's DropTarget. Fixes https://github.com/eclipse-platform/eclipse.platform.swt/issues/3477 Assisted-by: Anthropic Claude Code (claude-opus-5[1m]) --- .../Eclipse SWT PI/gtk/library/gtk4.c | 20 +++++++++++++++++++ .../Eclipse SWT PI/gtk/library/gtk4_stats.h | 2 ++ .../org/eclipse/swt/internal/gtk4/GTK4.java | 10 ++++++++++ .../gtk/org/eclipse/swt/widgets/Table.java | 7 +++++++ .../gtk/org/eclipse/swt/widgets/Tree.java | 18 ++++++++++++++++- 5 files changed, 56 insertions(+), 1 deletion(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c index 0d22afe9502..4f41025f6c9 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c @@ -415,6 +415,16 @@ JNIEXPORT jlong JNICALL GTK4_NATIVE(gdk_1content_1formats_1to_1string) } #endif +#ifndef NO_gdk_1content_1formats_1unref +JNIEXPORT void JNICALL GTK4_NATIVE(gdk_1content_1formats_1unref) + (JNIEnv *env, jclass that, jlong arg0) +{ + GTK4_NATIVE_ENTER(env, that, gdk_1content_1formats_1unref_FUNC); + gdk_content_formats_unref((GdkContentFormats *)arg0); + GTK4_NATIVE_EXIT(env, that, gdk_1content_1formats_1unref_FUNC); +} +#endif + #ifndef NO_gdk_1content_1provider_1get_1value JNIEXPORT jboolean JNICALL GTK4_NATIVE(gdk_1content_1provider_1get_1value) (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlongArray arg2) @@ -2649,6 +2659,16 @@ JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1tree_1view_1column_1cell_1get_1size) } #endif +#ifndef NO_gtk_1tree_1view_1enable_1model_1drag_1dest +JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1tree_1view_1enable_1model_1drag_1dest) + (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jint arg2) +{ + GTK4_NATIVE_ENTER(env, that, gtk_1tree_1view_1enable_1model_1drag_1dest_FUNC); + gtk_tree_view_enable_model_drag_dest((GtkTreeView *)arg0, (GdkContentFormats *)arg1, (GdkDragAction)arg2); + GTK4_NATIVE_EXIT(env, that, gtk_1tree_1view_1enable_1model_1drag_1dest_FUNC); +} +#endif + #ifndef NO_gtk_1widget_1action_1set_1enabled JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1widget_1action_1set_1enabled) (JNIEnv *env, jclass that, jlong arg0, jbyteArray arg1, jboolean arg2) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h index 6766ff954b9..f240d03cae9 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h @@ -51,6 +51,7 @@ typedef enum { gdk_1content_1formats_1get_1gtypes_FUNC, gdk_1content_1formats_1get_1mime_1types_FUNC, gdk_1content_1formats_1to_1string_FUNC, + gdk_1content_1formats_1unref_FUNC, gdk_1content_1provider_1get_1value_FUNC, gdk_1content_1provider_1new_1for_1value_FUNC, gdk_1content_1provider_1new_1typed_FUNC, @@ -217,6 +218,7 @@ typedef enum { gtk_1text_1set_1tabs_FUNC, gtk_1text_1set_1visibility_FUNC, gtk_1tree_1view_1column_1cell_1get_1size_FUNC, + gtk_1tree_1view_1enable_1model_1drag_1dest_FUNC, gtk_1widget_1action_1set_1enabled_FUNC, gtk_1widget_1activate_1action_FUNC, gtk_1widget_1add_1controller_FUNC, diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java index ba03262b095..3c33dfcfb79 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java @@ -233,6 +233,8 @@ public class GTK4 { * @param type cast=(GType) */ public static final native boolean gdk_content_formats_contain_gtype(long formats, long type); + /** @param formats cast=(GdkContentFormats *) */ + public static final native void gdk_content_formats_unref(long formats); /* GdkDrop */ /** @@ -898,6 +900,14 @@ public class GTK4 { /** @param menu_button cast=(GtkMenuButton *) */ public static final native void gtk_menu_button_set_use_underline(long menu_button, boolean use_underline); + /* GtkTreeView */ + /** + * @param tree_view cast=(GtkTreeView *) + * @param formats cast=(GdkContentFormats *) + * @param actions cast=(GdkDragAction) + */ + public static final native void gtk_tree_view_enable_model_drag_dest(long tree_view, long formats, int actions); + /* GtkTreeViewColumn */ /** * @param tree_column cast=(GtkTreeViewColumn *) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java index f750fa7b97e..f75676a3650 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java @@ -711,6 +711,13 @@ void createHandle (int index) { if (!searchEnabled ()) { GTK.gtk_tree_view_set_search_column (handle, -1); } + if (GTK.GTK4) { + // Required before TableDropTargetEffect may use + // gtk_tree_view_set_drag_dest_row(), see Tree.createHandle() for details. + long formats = GTK4.gdk_content_formats_builder_free_to_formats(GTK4.gdk_content_formats_builder_new()); + GTK4.gtk_tree_view_enable_model_drag_dest(handle, formats, 0); + GTK4.gdk_content_formats_unref(formats); + } } void createItem (TableColumn column, int index) { diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java index be506112a4a..7fd132ed41c 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java @@ -881,7 +881,23 @@ void createHandle (int index) { GTK.gtk_tree_view_set_search_column (handle, -1); } - if (GTK.GTK4) bindArrowKeyBindings(); + if (GTK.GTK4) { + bindArrowKeyBindings(); + /* + * GTK renders the drop highlight requested through + * gtk_tree_view_set_drag_dest_row() from the private TreeViewDragInfo struct, + * but only gtk_tree_view_enable_model_drag_dest() ever allocates it and the + * snapshot code dereferences it without a NULL check. Driving the highlight + * ourselves, as setInsertMark() and TreeDropTargetEffect do, would therefore + * crash on the next repaint, so allocate the struct up front. The drop target + * GTK installs alongside it gets an empty format list and no actions, which + * makes it reject every drag so that GTK's own tree view drag handlers never + * compete with SWT's DropTarget. + */ + long formats = GTK4.gdk_content_formats_builder_free_to_formats(GTK4.gdk_content_formats_builder_new()); + GTK4.gtk_tree_view_enable_model_drag_dest(handle, formats, 0); + GTK4.gdk_content_formats_unref(formats); + } } /** From 04d7df1cdbc809fd88b72da0f1126ab25d5bef0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=8A?= =?UTF-8?q?=D1=80=20=D0=9A=D1=83=D1=80=D1=82=D0=B0=D0=BA=D0=BE=D0=B2?= Date: Mon, 3 Aug 2026 13:20:45 +0300 Subject: [PATCH 40/46] [GTK4] Fix DropTarget passing a formats builder as content formats setTransfer() handed the GdkContentFormatsBuilder straight to gtk_drop_target_async_set_formats(), which expects a GdkContentFormats. The drop target therefore kept a pointer to a foreign struct and matched incoming drags against it in gtk_drop_target_async_accept(), while the builder itself was never freed. Convert the builder with gdk_content_formats_builder_free_to_formats() and drop our reference afterwards, since set_formats() takes its own. Also reject a null transferAgents array and skip null agents, matching the documented contract and the GTK3 branch. Assisted-by: Anthropic Claude Code (claude-opus-5[1m]) --- .../gtk/org/eclipse/swt/dnd/DropTarget.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/DropTarget.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/DropTarget.java index c01333c0ee7..8eafce3dcc6 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/DropTarget.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/DropTarget.java @@ -753,19 +753,23 @@ public void removeDropListener(DropTargetListener listener) { * */ public void setTransfer(Transfer... transferAgents){ + if (transferAgents == null) DND.error(SWT.ERROR_NULL_ARGUMENT); if (GTK.GTK4) { this.transferAgents = transferAgents; long contentFormatsBuilder = GTK4.gdk_content_formats_builder_new(); for (Transfer agent : transferAgents) { + if (agent == null) continue; for (String typeName : agent.getTypeNames()) { GTK4.gdk_content_formats_builder_add_mime_type(contentFormatsBuilder, Converter.javaStringToCString(typeName)); } } - GTK4.gtk_drop_target_async_set_formats(dropController, contentFormatsBuilder); + // The builder is not a GdkContentFormats, it has to be converted first. + // gtk_drop_target_async_set_formats() then takes its own reference. + long formats = GTK4.gdk_content_formats_builder_free_to_formats(contentFormatsBuilder); + GTK4.gtk_drop_target_async_set_formats(dropController, formats); + GTK4.gdk_content_formats_unref(formats); } else { - if (transferAgents == null) DND.error(SWT.ERROR_NULL_ARGUMENT); - if (this.transferAgents.length != 0) { GTK3.gtk_drag_dest_unset(control.handle); } From 8599c18e5b60ab3b6902689e9f2f590316bd5198 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=8A?= =?UTF-8?q?=D1=80=20=D0=9A=D1=83=D1=80=D1=82=D0=B0=D0=BA=D0=BE=D0=B2?= Date: Mon, 3 Aug 2026 11:43:14 +0300 Subject: [PATCH 41/46] [GTK4] Fix "Cannot initialize Drag" when re-creating a DragSource The controlListener registration and addListener(SWT.Dispose, e -> onDispose()) sat inside the GTK3 else branch of the constructor, so on GTK4 onDispose() never ran and DND.DRAG_SOURCE_KEY was never cleared. A disposed DragSource stayed parked on its control, so the next new DragSource(sameControl, ...) failed the "already has a drag source" guard. DNDExample hits this on every operation checkbox toggle. The GtkDragSource controller was also a constructor local and never detached, leaving a live controller per dispose/recreate cycle. Register the dispose listeners for both backends, keeping SWT.DragDetect GTK3-only since on GTK4 the controller starts the drag itself. Promote dragSourceController to a field and remove it in onDispose(), mirroring DropTarget. Fixes https://github.com/eclipse-platform/eclipse.platform.swt/issues/3475 Co-Authored-By: Claude Opus 5 (1M context) --- .../gtk/org/eclipse/swt/dnd/DragSource.java | 50 +++++++++++-------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/DragSource.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/DragSource.java index 2918749b67e..ee334b146c2 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/DragSource.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/DragSource.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2026 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -117,6 +117,9 @@ public class DragSource extends Widget { long targetList; + /* GTK4 GtkDragSource event controller added to the control */ + long dragSourceController; + //workaround - remember action performed for DragEnd boolean moveData = false; @@ -182,7 +185,7 @@ public DragSource(Control control, int style) { } control.setData(DND.DRAG_SOURCE_KEY, this); - long dragSourceController = GTK4.gtk_drag_source_new(); + dragSourceController = GTK4.gtk_drag_source_new(); GTK4.gtk_widget_add_controller(control.handle, dragSourceController); OS.g_signal_connect(dragSourceController, OS.prepare, dragPrepareProc.getAddress(), 0); @@ -207,21 +210,6 @@ public DragSource(Control control, int style) { OS.g_signal_connect(control.handle, OS.drag_end, DragEnd.getAddress(), 0); OS.g_signal_connect(control.handle, OS.drag_data_delete, DragDataDelete.getAddress(), 0); - controlListener = event -> { - if (event.type == SWT.Dispose) { - if (!DragSource.this.isDisposed()) { - DragSource.this.dispose(); - } - } - if (event.type == SWT.DragDetect) { - if (!DragSource.this.isDisposed()) { - DragSource.this.drag(event); - } - } - }; - control.addListener (SWT.Dispose, controlListener); - control.addListener (SWT.DragDetect, controlListener); - Object effect = control.getData(DEFAULT_DRAG_SOURCE_EFFECT); if (effect instanceof DragSourceEffect) { dragEffect = (DragSourceEffect) effect; @@ -232,9 +220,26 @@ public DragSource(Control control, int style) { } else if (control instanceof List) { dragEffect = new ListDragSourceEffect((List) control); } - - this.addListener(SWT.Dispose, e -> onDispose()); } + + // Dispose listeners + controlListener = event -> { + if (event.type == SWT.Dispose) { + if (!DragSource.this.isDisposed()) { + DragSource.this.dispose(); + } + } + if (event.type == SWT.DragDetect) { + if (!DragSource.this.isDisposed()) { + DragSource.this.drag(event); + } + } + }; + control.addListener (SWT.Dispose, controlListener); + // On GTK4 the drag is started by the GtkDragSource controller, not by SWT.DragDetect. + if (!GTK.GTK4) control.addListener (SWT.DragDetect, controlListener); + + this.addListener(SWT.Dispose, e -> onDispose()); } static int checkStyle (int style) { @@ -621,7 +626,12 @@ public Transfer[] getTransfer(){ void onDispose() { if (control == null) return; - if (targetList != 0) { + if (GTK.GTK4) { + if (dragSourceController != 0) { + GTK4.gtk_widget_remove_controller(control.handle, dragSourceController); + dragSourceController = 0; + } + } else if (targetList != 0) { GTK3.gtk_target_list_unref(targetList); } targetList = 0; From 97cba5524bf3fad12263cf8c7d522a5c1e3a9132 Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Tue, 4 Aug 2026 06:40:55 +0000 Subject: [PATCH 42/46] v4974r10 --- ...awt-cocoa-4974r9.jnilib => libswt-awt-cocoa-4974r10.jnilib} | 0 ...{libswt-cocoa-4974r9.jnilib => libswt-cocoa-4974r10.jnilib} | 0 ...t-pi-cocoa-4974r9.jnilib => libswt-pi-cocoa-4974r10.jnilib} | 0 ...awt-cocoa-4974r9.jnilib => libswt-awt-cocoa-4974r10.jnilib} | 0 ...{libswt-cocoa-4974r9.jnilib => libswt-cocoa-4974r10.jnilib} | 0 ...t-pi-cocoa-4974r9.jnilib => libswt-pi-cocoa-4974r10.jnilib} | 0 .../{libswt-atk-gtk-4974r9.so => libswt-atk-gtk-4974r10.so} | 0 .../{libswt-awt-gtk-4974r9.so => libswt-awt-gtk-4974r10.so} | 0 ...{libswt-cairo-gtk-4974r9.so => libswt-cairo-gtk-4974r10.so} | 0 .../{libswt-glx-gtk-4974r9.so => libswt-glx-gtk-4974r10.so} | 0 .../{libswt-gtk-4974r9.so => libswt-gtk-4974r10.so} | 0 .../{libswt-pi3-gtk-4974r9.so => libswt-pi3-gtk-4974r10.so} | 0 ...ibswt-webkit-gtk-4974r9.so => libswt-webkit-gtk-4974r10.so} | 0 .../libswt-atk-gtk-4974r10.so | 3 +++ .../org.eclipse.swt.gtk.linux.ppc64le/libswt-atk-gtk-4974r9.so | 3 --- .../libswt-awt-gtk-4974r10.so | 3 +++ .../org.eclipse.swt.gtk.linux.ppc64le/libswt-awt-gtk-4974r9.so | 3 --- .../libswt-cairo-gtk-4974r10.so | 3 +++ .../libswt-cairo-gtk-4974r9.so | 3 --- .../libswt-glx-gtk-4974r10.so | 3 +++ .../org.eclipse.swt.gtk.linux.ppc64le/libswt-glx-gtk-4974r9.so | 3 --- .../org.eclipse.swt.gtk.linux.ppc64le/libswt-gtk-4974r10.so | 3 +++ .../org.eclipse.swt.gtk.linux.ppc64le/libswt-gtk-4974r9.so | 3 --- .../libswt-pi3-gtk-4974r10.so | 3 +++ .../org.eclipse.swt.gtk.linux.ppc64le/libswt-pi3-gtk-4974r9.so | 3 --- .../libswt-webkit-gtk-4974r10.so | 3 +++ .../libswt-webkit-gtk-4974r9.so | 3 --- .../{libswt-atk-gtk-4974r9.so => libswt-atk-gtk-4974r10.so} | 0 .../{libswt-awt-gtk-4974r9.so => libswt-awt-gtk-4974r10.so} | 0 ...{libswt-cairo-gtk-4974r9.so => libswt-cairo-gtk-4974r10.so} | 0 .../{libswt-glx-gtk-4974r9.so => libswt-glx-gtk-4974r10.so} | 0 .../{libswt-gtk-4974r9.so => libswt-gtk-4974r10.so} | 0 .../{libswt-pi3-gtk-4974r9.so => libswt-pi3-gtk-4974r10.so} | 0 ...ibswt-webkit-gtk-4974r9.so => libswt-webkit-gtk-4974r10.so} | 0 .../{libswt-atk-gtk-4974r9.so => libswt-atk-gtk-4974r10.so} | 0 .../{libswt-awt-gtk-4974r9.so => libswt-awt-gtk-4974r10.so} | 0 ...{libswt-cairo-gtk-4974r9.so => libswt-cairo-gtk-4974r10.so} | 0 .../{libswt-glx-gtk-4974r9.so => libswt-glx-gtk-4974r10.so} | 0 .../{libswt-gtk-4974r9.so => libswt-gtk-4974r10.so} | 0 .../{libswt-pi3-gtk-4974r9.so => libswt-pi3-gtk-4974r10.so} | 0 .../org.eclipse.swt.gtk.linux.x86_64/libswt-pi4-gtk-4974r10.so | 3 +++ .../org.eclipse.swt.gtk.linux.x86_64/libswt-pi4-gtk-4974r9.so | 3 --- ...ibswt-webkit-gtk-4974r9.so => libswt-webkit-gtk-4974r10.so} | 0 .../{swt-awt-win32-4974r9.dll => swt-awt-win32-4974r10.dll} | 0 .../{swt-gdip-win32-4974r9.dll => swt-gdip-win32-4974r10.dll} | 0 ...ersion-win32-4974r9.dll => swt-osversion-win32-4974r10.dll} | 0 .../{swt-wgl-win32-4974r9.dll => swt-wgl-win32-4974r10.dll} | 0 .../{swt-win32-4974r9.dll => swt-win32-4974r10.dll} | 0 .../{swt-awt-win32-4974r9.dll => swt-awt-win32-4974r10.dll} | 0 .../{swt-gdip-win32-4974r9.dll => swt-gdip-win32-4974r10.dll} | 0 ...ersion-win32-4974r9.dll => swt-osversion-win32-4974r10.dll} | 0 .../{swt-wgl-win32-4974r9.dll => swt-wgl-win32-4974r10.dll} | 0 .../{swt-win32-4974r9.dll => swt-win32-4974r10.dll} | 0 .../common/org/eclipse/swt/internal/Library.java | 2 +- .../org.eclipse.swt/Eclipse SWT/common/library/make_common.mak | 2 +- 55 files changed, 26 insertions(+), 26 deletions(-) rename binaries/org.eclipse.swt.cocoa.macosx.aarch64/{libswt-awt-cocoa-4974r9.jnilib => libswt-awt-cocoa-4974r10.jnilib} (100%) rename binaries/org.eclipse.swt.cocoa.macosx.aarch64/{libswt-cocoa-4974r9.jnilib => libswt-cocoa-4974r10.jnilib} (100%) rename binaries/org.eclipse.swt.cocoa.macosx.aarch64/{libswt-pi-cocoa-4974r9.jnilib => libswt-pi-cocoa-4974r10.jnilib} (100%) rename binaries/org.eclipse.swt.cocoa.macosx.x86_64/{libswt-awt-cocoa-4974r9.jnilib => libswt-awt-cocoa-4974r10.jnilib} (100%) rename binaries/org.eclipse.swt.cocoa.macosx.x86_64/{libswt-cocoa-4974r9.jnilib => libswt-cocoa-4974r10.jnilib} (100%) rename binaries/org.eclipse.swt.cocoa.macosx.x86_64/{libswt-pi-cocoa-4974r9.jnilib => libswt-pi-cocoa-4974r10.jnilib} (100%) rename binaries/org.eclipse.swt.gtk.linux.aarch64/{libswt-atk-gtk-4974r9.so => libswt-atk-gtk-4974r10.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.aarch64/{libswt-awt-gtk-4974r9.so => libswt-awt-gtk-4974r10.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.aarch64/{libswt-cairo-gtk-4974r9.so => libswt-cairo-gtk-4974r10.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.aarch64/{libswt-glx-gtk-4974r9.so => libswt-glx-gtk-4974r10.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.aarch64/{libswt-gtk-4974r9.so => libswt-gtk-4974r10.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.aarch64/{libswt-pi3-gtk-4974r9.so => libswt-pi3-gtk-4974r10.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.aarch64/{libswt-webkit-gtk-4974r9.so => libswt-webkit-gtk-4974r10.so} (100%) create mode 100755 binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-atk-gtk-4974r10.so delete mode 100755 binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-atk-gtk-4974r9.so create mode 100755 binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-awt-gtk-4974r10.so delete mode 100755 binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-awt-gtk-4974r9.so create mode 100755 binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-cairo-gtk-4974r10.so delete mode 100755 binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-cairo-gtk-4974r9.so create mode 100755 binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-glx-gtk-4974r10.so delete mode 100755 binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-glx-gtk-4974r9.so create mode 100755 binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-gtk-4974r10.so delete mode 100755 binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-gtk-4974r9.so create mode 100755 binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-pi3-gtk-4974r10.so delete mode 100755 binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-pi3-gtk-4974r9.so create mode 100755 binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-webkit-gtk-4974r10.so delete mode 100755 binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-webkit-gtk-4974r9.so rename binaries/org.eclipse.swt.gtk.linux.riscv64/{libswt-atk-gtk-4974r9.so => libswt-atk-gtk-4974r10.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.riscv64/{libswt-awt-gtk-4974r9.so => libswt-awt-gtk-4974r10.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.riscv64/{libswt-cairo-gtk-4974r9.so => libswt-cairo-gtk-4974r10.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.riscv64/{libswt-glx-gtk-4974r9.so => libswt-glx-gtk-4974r10.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.riscv64/{libswt-gtk-4974r9.so => libswt-gtk-4974r10.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.riscv64/{libswt-pi3-gtk-4974r9.so => libswt-pi3-gtk-4974r10.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.riscv64/{libswt-webkit-gtk-4974r9.so => libswt-webkit-gtk-4974r10.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.x86_64/{libswt-atk-gtk-4974r9.so => libswt-atk-gtk-4974r10.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.x86_64/{libswt-awt-gtk-4974r9.so => libswt-awt-gtk-4974r10.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.x86_64/{libswt-cairo-gtk-4974r9.so => libswt-cairo-gtk-4974r10.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.x86_64/{libswt-glx-gtk-4974r9.so => libswt-glx-gtk-4974r10.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.x86_64/{libswt-gtk-4974r9.so => libswt-gtk-4974r10.so} (100%) rename binaries/org.eclipse.swt.gtk.linux.x86_64/{libswt-pi3-gtk-4974r9.so => libswt-pi3-gtk-4974r10.so} (100%) create mode 100755 binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi4-gtk-4974r10.so delete mode 100755 binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi4-gtk-4974r9.so rename binaries/org.eclipse.swt.gtk.linux.x86_64/{libswt-webkit-gtk-4974r9.so => libswt-webkit-gtk-4974r10.so} (100%) rename binaries/org.eclipse.swt.win32.win32.aarch64/{swt-awt-win32-4974r9.dll => swt-awt-win32-4974r10.dll} (100%) rename binaries/org.eclipse.swt.win32.win32.aarch64/{swt-gdip-win32-4974r9.dll => swt-gdip-win32-4974r10.dll} (100%) rename binaries/org.eclipse.swt.win32.win32.aarch64/{swt-osversion-win32-4974r9.dll => swt-osversion-win32-4974r10.dll} (100%) rename binaries/org.eclipse.swt.win32.win32.aarch64/{swt-wgl-win32-4974r9.dll => swt-wgl-win32-4974r10.dll} (100%) rename binaries/org.eclipse.swt.win32.win32.aarch64/{swt-win32-4974r9.dll => swt-win32-4974r10.dll} (100%) rename binaries/org.eclipse.swt.win32.win32.x86_64/{swt-awt-win32-4974r9.dll => swt-awt-win32-4974r10.dll} (100%) rename binaries/org.eclipse.swt.win32.win32.x86_64/{swt-gdip-win32-4974r9.dll => swt-gdip-win32-4974r10.dll} (100%) rename binaries/org.eclipse.swt.win32.win32.x86_64/{swt-osversion-win32-4974r9.dll => swt-osversion-win32-4974r10.dll} (100%) rename binaries/org.eclipse.swt.win32.win32.x86_64/{swt-wgl-win32-4974r9.dll => swt-wgl-win32-4974r10.dll} (100%) rename binaries/org.eclipse.swt.win32.win32.x86_64/{swt-win32-4974r9.dll => swt-win32-4974r10.dll} (100%) diff --git a/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-awt-cocoa-4974r9.jnilib b/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-awt-cocoa-4974r10.jnilib similarity index 100% rename from binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-awt-cocoa-4974r9.jnilib rename to binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-awt-cocoa-4974r10.jnilib diff --git a/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-cocoa-4974r9.jnilib b/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-cocoa-4974r10.jnilib similarity index 100% rename from binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-cocoa-4974r9.jnilib rename to binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-cocoa-4974r10.jnilib diff --git a/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-pi-cocoa-4974r9.jnilib b/binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-pi-cocoa-4974r10.jnilib similarity index 100% rename from binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-pi-cocoa-4974r9.jnilib rename to binaries/org.eclipse.swt.cocoa.macosx.aarch64/libswt-pi-cocoa-4974r10.jnilib diff --git a/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-awt-cocoa-4974r9.jnilib b/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-awt-cocoa-4974r10.jnilib similarity index 100% rename from binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-awt-cocoa-4974r9.jnilib rename to binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-awt-cocoa-4974r10.jnilib diff --git a/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-cocoa-4974r9.jnilib b/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-cocoa-4974r10.jnilib similarity index 100% rename from binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-cocoa-4974r9.jnilib rename to binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-cocoa-4974r10.jnilib diff --git a/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-pi-cocoa-4974r9.jnilib b/binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-pi-cocoa-4974r10.jnilib similarity index 100% rename from binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-pi-cocoa-4974r9.jnilib rename to binaries/org.eclipse.swt.cocoa.macosx.x86_64/libswt-pi-cocoa-4974r10.jnilib diff --git a/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-atk-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-atk-gtk-4974r10.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-atk-gtk-4974r9.so rename to binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-atk-gtk-4974r10.so diff --git a/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-awt-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-awt-gtk-4974r10.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-awt-gtk-4974r9.so rename to binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-awt-gtk-4974r10.so diff --git a/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-cairo-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-cairo-gtk-4974r10.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-cairo-gtk-4974r9.so rename to binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-cairo-gtk-4974r10.so diff --git a/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-glx-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-glx-gtk-4974r10.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-glx-gtk-4974r9.so rename to binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-glx-gtk-4974r10.so diff --git a/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-gtk-4974r10.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-gtk-4974r9.so rename to binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-gtk-4974r10.so diff --git a/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-pi3-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-pi3-gtk-4974r10.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-pi3-gtk-4974r9.so rename to binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-pi3-gtk-4974r10.so diff --git a/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-webkit-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-webkit-gtk-4974r10.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-webkit-gtk-4974r9.so rename to binaries/org.eclipse.swt.gtk.linux.aarch64/libswt-webkit-gtk-4974r10.so diff --git a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-atk-gtk-4974r10.so b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-atk-gtk-4974r10.so new file mode 100755 index 00000000000..faec186a178 --- /dev/null +++ b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-atk-gtk-4974r10.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:02edb508272d91454044ee5fc1cdd486e2dfc52608aef1bc0578b9de50fd0404 +size 67608 diff --git a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-atk-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-atk-gtk-4974r9.so deleted file mode 100755 index 866f0196467..00000000000 --- a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-atk-gtk-4974r9.so +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6105e985fddce365478b8aeba4ed07718f2abea577deaf74f119b7c3bab73793 -size 67608 diff --git a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-awt-gtk-4974r10.so b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-awt-gtk-4974r10.so new file mode 100755 index 00000000000..ed598da0a80 --- /dev/null +++ b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-awt-gtk-4974r10.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:149f6d78e1001cc2ab7babfccc1cc13f961ae81b6e8b0d45edd3e069570d2263 +size 67504 diff --git a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-awt-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-awt-gtk-4974r9.so deleted file mode 100755 index a411e5c705a..00000000000 --- a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-awt-gtk-4974r9.so +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3e88636ff78f3c9223f1a544b8a5ff362a6c4e097dab64868d46aeb22f62ba5d -size 67504 diff --git a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-cairo-gtk-4974r10.so b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-cairo-gtk-4974r10.so new file mode 100755 index 00000000000..e52ab540d36 --- /dev/null +++ b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-cairo-gtk-4974r10.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:81267b1171b2cb056658b2d0ace25af65ef3f0d9eedbae40243c5ea64331c3a3 +size 67632 diff --git a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-cairo-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-cairo-gtk-4974r9.so deleted file mode 100755 index 6fa478024e1..00000000000 --- a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-cairo-gtk-4974r9.so +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d309cfa3c57b00ff95b458a1a582e35d295320d4c4c94232d5ad327507a61e64 -size 67632 diff --git a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-glx-gtk-4974r10.so b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-glx-gtk-4974r10.so new file mode 100755 index 00000000000..c7fab180bf5 --- /dev/null +++ b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-glx-gtk-4974r10.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2e47dd49778bfd1ba83c5716f54a9d141de08c8f6ca1ccb5405e589da0a3003f +size 67520 diff --git a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-glx-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-glx-gtk-4974r9.so deleted file mode 100755 index c045c6583aa..00000000000 --- a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-glx-gtk-4974r9.so +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6dd11de26e50342856c5db2413630cc36b64a134aaea62b56d0ee1831904980a -size 67520 diff --git a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-gtk-4974r10.so b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-gtk-4974r10.so new file mode 100755 index 00000000000..083275529a1 --- /dev/null +++ b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-gtk-4974r10.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a797c983873bc4ec333d65b66361c8c4605027171f88be1dcf2459c6cd1dac07 +size 819648 diff --git a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-gtk-4974r9.so deleted file mode 100755 index 0729bc3fea8..00000000000 --- a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-gtk-4974r9.so +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:04d777f0fc41b953a9ce0c28d1caa616c1a201e01ca111b9fa6dcff745d4d4ca -size 819648 diff --git a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-pi3-gtk-4974r10.so b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-pi3-gtk-4974r10.so new file mode 100755 index 00000000000..c237cab0b85 --- /dev/null +++ b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-pi3-gtk-4974r10.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bad4c356eff6fca4b5c3965c648383c6ae5c2873ebb06ca3580f64f7e0b98044 +size 668048 diff --git a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-pi3-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-pi3-gtk-4974r9.so deleted file mode 100755 index fe122c7e411..00000000000 --- a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-pi3-gtk-4974r9.so +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b6e053a824e7f8bb66f22adbdd19e5e650bc87b6823356f879b321e9c2ebd209 -size 668048 diff --git a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-webkit-gtk-4974r10.so b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-webkit-gtk-4974r10.so new file mode 100755 index 00000000000..e61251cf672 --- /dev/null +++ b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-webkit-gtk-4974r10.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a864f82f00d18138f1c1fa9840b2a606831a22fb7c232d7234488d7dbce401fb +size 133160 diff --git a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-webkit-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-webkit-gtk-4974r9.so deleted file mode 100755 index aeeefc3dfc5..00000000000 --- a/binaries/org.eclipse.swt.gtk.linux.ppc64le/libswt-webkit-gtk-4974r9.so +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:986bf233d8784f7a363ccbdc1861de2f43a0450711aec872297ae923465aba3b -size 133160 diff --git a/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-atk-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-atk-gtk-4974r10.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-atk-gtk-4974r9.so rename to binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-atk-gtk-4974r10.so diff --git a/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-awt-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-awt-gtk-4974r10.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-awt-gtk-4974r9.so rename to binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-awt-gtk-4974r10.so diff --git a/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-cairo-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-cairo-gtk-4974r10.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-cairo-gtk-4974r9.so rename to binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-cairo-gtk-4974r10.so diff --git a/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-glx-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-glx-gtk-4974r10.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-glx-gtk-4974r9.so rename to binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-glx-gtk-4974r10.so diff --git a/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-gtk-4974r10.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-gtk-4974r9.so rename to binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-gtk-4974r10.so diff --git a/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-pi3-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-pi3-gtk-4974r10.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-pi3-gtk-4974r9.so rename to binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-pi3-gtk-4974r10.so diff --git a/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-webkit-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-webkit-gtk-4974r10.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-webkit-gtk-4974r9.so rename to binaries/org.eclipse.swt.gtk.linux.riscv64/libswt-webkit-gtk-4974r10.so diff --git a/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-atk-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-atk-gtk-4974r10.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-atk-gtk-4974r9.so rename to binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-atk-gtk-4974r10.so diff --git a/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-awt-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-awt-gtk-4974r10.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-awt-gtk-4974r9.so rename to binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-awt-gtk-4974r10.so diff --git a/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-cairo-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-cairo-gtk-4974r10.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-cairo-gtk-4974r9.so rename to binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-cairo-gtk-4974r10.so diff --git a/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-glx-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-glx-gtk-4974r10.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-glx-gtk-4974r9.so rename to binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-glx-gtk-4974r10.so diff --git a/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-gtk-4974r10.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-gtk-4974r9.so rename to binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-gtk-4974r10.so diff --git a/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi3-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi3-gtk-4974r10.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi3-gtk-4974r9.so rename to binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi3-gtk-4974r10.so diff --git a/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi4-gtk-4974r10.so b/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi4-gtk-4974r10.so new file mode 100755 index 00000000000..24076b08fe0 --- /dev/null +++ b/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi4-gtk-4974r10.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:295115cdab2cb3953258fc7ee33abc103752931ec37412aa81d17a4241a9cea3 +size 425160 diff --git a/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi4-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi4-gtk-4974r9.so deleted file mode 100755 index 7043960fb4f..00000000000 --- a/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-pi4-gtk-4974r9.so +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9aefa710ccab79a8e1a85838c9dfe3b451d9fb257cf93bf11aa05bbc42bbad7c -size 425144 diff --git a/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-webkit-gtk-4974r9.so b/binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-webkit-gtk-4974r10.so similarity index 100% rename from binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-webkit-gtk-4974r9.so rename to binaries/org.eclipse.swt.gtk.linux.x86_64/libswt-webkit-gtk-4974r10.so diff --git a/binaries/org.eclipse.swt.win32.win32.aarch64/swt-awt-win32-4974r9.dll b/binaries/org.eclipse.swt.win32.win32.aarch64/swt-awt-win32-4974r10.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.aarch64/swt-awt-win32-4974r9.dll rename to binaries/org.eclipse.swt.win32.win32.aarch64/swt-awt-win32-4974r10.dll diff --git a/binaries/org.eclipse.swt.win32.win32.aarch64/swt-gdip-win32-4974r9.dll b/binaries/org.eclipse.swt.win32.win32.aarch64/swt-gdip-win32-4974r10.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.aarch64/swt-gdip-win32-4974r9.dll rename to binaries/org.eclipse.swt.win32.win32.aarch64/swt-gdip-win32-4974r10.dll diff --git a/binaries/org.eclipse.swt.win32.win32.aarch64/swt-osversion-win32-4974r9.dll b/binaries/org.eclipse.swt.win32.win32.aarch64/swt-osversion-win32-4974r10.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.aarch64/swt-osversion-win32-4974r9.dll rename to binaries/org.eclipse.swt.win32.win32.aarch64/swt-osversion-win32-4974r10.dll diff --git a/binaries/org.eclipse.swt.win32.win32.aarch64/swt-wgl-win32-4974r9.dll b/binaries/org.eclipse.swt.win32.win32.aarch64/swt-wgl-win32-4974r10.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.aarch64/swt-wgl-win32-4974r9.dll rename to binaries/org.eclipse.swt.win32.win32.aarch64/swt-wgl-win32-4974r10.dll diff --git a/binaries/org.eclipse.swt.win32.win32.aarch64/swt-win32-4974r9.dll b/binaries/org.eclipse.swt.win32.win32.aarch64/swt-win32-4974r10.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.aarch64/swt-win32-4974r9.dll rename to binaries/org.eclipse.swt.win32.win32.aarch64/swt-win32-4974r10.dll diff --git a/binaries/org.eclipse.swt.win32.win32.x86_64/swt-awt-win32-4974r9.dll b/binaries/org.eclipse.swt.win32.win32.x86_64/swt-awt-win32-4974r10.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.x86_64/swt-awt-win32-4974r9.dll rename to binaries/org.eclipse.swt.win32.win32.x86_64/swt-awt-win32-4974r10.dll diff --git a/binaries/org.eclipse.swt.win32.win32.x86_64/swt-gdip-win32-4974r9.dll b/binaries/org.eclipse.swt.win32.win32.x86_64/swt-gdip-win32-4974r10.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.x86_64/swt-gdip-win32-4974r9.dll rename to binaries/org.eclipse.swt.win32.win32.x86_64/swt-gdip-win32-4974r10.dll diff --git a/binaries/org.eclipse.swt.win32.win32.x86_64/swt-osversion-win32-4974r9.dll b/binaries/org.eclipse.swt.win32.win32.x86_64/swt-osversion-win32-4974r10.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.x86_64/swt-osversion-win32-4974r9.dll rename to binaries/org.eclipse.swt.win32.win32.x86_64/swt-osversion-win32-4974r10.dll diff --git a/binaries/org.eclipse.swt.win32.win32.x86_64/swt-wgl-win32-4974r9.dll b/binaries/org.eclipse.swt.win32.win32.x86_64/swt-wgl-win32-4974r10.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.x86_64/swt-wgl-win32-4974r9.dll rename to binaries/org.eclipse.swt.win32.win32.x86_64/swt-wgl-win32-4974r10.dll diff --git a/binaries/org.eclipse.swt.win32.win32.x86_64/swt-win32-4974r9.dll b/binaries/org.eclipse.swt.win32.win32.x86_64/swt-win32-4974r10.dll similarity index 100% rename from binaries/org.eclipse.swt.win32.win32.x86_64/swt-win32-4974r9.dll rename to binaries/org.eclipse.swt.win32.win32.x86_64/swt-win32-4974r10.dll diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/common/org/eclipse/swt/internal/Library.java b/bundles/org.eclipse.swt/Eclipse SWT PI/common/org/eclipse/swt/internal/Library.java index 08ab37014f5..0b1069113f5 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/common/org/eclipse/swt/internal/Library.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/common/org/eclipse/swt/internal/Library.java @@ -35,7 +35,7 @@ public class Library { /** * SWT revision number (must be >= 0) */ - static int REVISION = 9; + static int REVISION = 10; /** * The JAVA and SWT versions diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/library/make_common.mak b/bundles/org.eclipse.swt/Eclipse SWT/common/library/make_common.mak index d4df4b1fc21..672f294dafe 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/library/make_common.mak +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/library/make_common.mak @@ -14,4 +14,4 @@ maj_ver=4 min_ver=974 -rev=9 +rev=10 From 2e68c713ad8badbb64e8af0508dc3f01c3edb5da Mon Sep 17 00:00:00 2001 From: Hannes Wellmann Date: Tue, 4 Aug 2026 19:58:27 +0200 Subject: [PATCH 43/46] [Build] Migrate to new home of eclipse platformreleng Docker images --- Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 0e32bcfa3a4..02cc55870e0 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -21,10 +21,10 @@ def runOnNativeBuildAgent(String platform, Closure body) { def dockerImage = null switch (platform) { case 'gtk.linux.x86_64': - dockerImage = 'eclipse/platformreleng-debian-swtgtk3nativebuild:10' + dockerImage = 'ghcr.io/eclipse-platform/platformreleng-debian-swtgtk3nativebuild:11' break case 'gtk4.linux.x86_64': - dockerImage = 'eclipse/platformreleng-debian-swtnativebuild:12' + dockerImage = 'ghcr.io/eclipse-platform/platformreleng-debian-swtnativebuild:12' break } if (dockerImage != null) { From 4755f49b971d5af925d42d5c056f3e31b016f6e5 Mon Sep 17 00:00:00 2001 From: Lars Vogel Date: Wed, 5 Aug 2026 09:55:31 +0200 Subject: [PATCH 44/46] [Build] Run API check and javadoc only once per operating system The reusable build workflow always passed -Papi-check and -Pjavadoc, so both ran in all six PR jobs. Neither depends on the GTK version, the GDK backend or the target architecture, only on the Java sources, so the three Linux jobs and the two macOS jobs computed identical results. A new boolean input api_check (default false) now gates the two profiles, and maven.yml enables it for one job per operating system: gtk3/x11 on Linux, the single Windows job and aarch64 on macOS. The API surface still differs between the gtk, win32 and cocoa fragments, so the check stays per operating system. Fixes https://github.com/eclipse-platform/eclipse.platform.swt/issues/3484 --- .github/workflows/build.yml | 11 ++++++++++- .github/workflows/maven.yml | 5 +++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1fe23f0a77b..6c7d8542328 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,6 +28,15 @@ on: type: boolean required: false default: false + api_check: + description: | + Run the API tools check and generate the javadoc (one of true, false) + + Both only depend on the Java sources, so enable this for a single job + per operating system. + type: boolean + required: false + default: false gtk: description: | (Required on Linux only) GTK version to use (one of gtk3, gtk4) @@ -108,7 +117,7 @@ jobs: --threads 1C -DforkCount=1 '-Dnative=${{ inputs.native }}' - -Papi-check -Pjavadoc + ${{ inputs.api_check && '-Papi-check -Pjavadoc' || '' }} '-Dtycho.baseline.replace=none' --fail-at-end -DskipNativeTests=false diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 058f94f7570..92ffd031dc0 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -93,6 +93,8 @@ jobs: native: gtk.linux.x86_64 gtk: ${{ matrix.gtk }} gdk_backend: ${{ matrix.gdk_backend }} + # All Linux jobs build the same Java sources, so check the API and javadoc only once + api_check: ${{ matrix.gtk == 'gtk3' && matrix.gdk_backend == 'x11' }} performance: ${{ contains(github.event.pull_request.labels.*.name, 'performance') }} runtodotests: ${{ contains(github.event.pull_request.labels.*.name, 'runtodotests') }} @@ -110,6 +112,7 @@ jobs: runner: windows-latest java: ${{ matrix.java }} native: win32.win32.x86_64 + api_check: true performance: ${{ contains(github.event.pull_request.labels.*.name, 'performance') }} runtodotests: ${{ contains(github.event.pull_request.labels.*.name, 'runtodotests') }} @@ -128,5 +131,7 @@ jobs: runner: ${{ matrix.arch == 'x86_64' && 'macos-15-intel' || 'macos-latest' }} java: ${{ matrix.java }} native: cocoa.macosx.${{ matrix.arch }} + # Both macOS fragments compile the same Java sources, so check the API and javadoc only once + api_check: ${{ matrix.arch == 'aarch64' }} performance: ${{ contains(github.event.pull_request.labels.*.name, 'performance') }} runtodotests: ${{ contains(github.event.pull_request.labels.*.name, 'runtodotests') }} From 2de2b00fc07ae2558373f62ead1aaec6737d32e3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Aug 2026 12:12:59 +0000 Subject: [PATCH 45/46] Bump dorny/paths-filter from 4.0.2 to 4.0.3 Bumps [dorny/paths-filter](https://github.com/dorny/paths-filter) from 4.0.2 to 4.0.3. - [Release notes](https://github.com/dorny/paths-filter/releases) - [Changelog](https://github.com/dorny/paths-filter/blob/master/CHANGELOG.md) - [Commits](https://github.com/dorny/paths-filter/compare/7b450fff21473bca461d4b92ce414b9d0420d706...ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d) --- updated-dependencies: - dependency-name: dorny/paths-filter dependency-version: 4.0.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/maven.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 92ffd031dc0..7249d12cae3 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -48,7 +48,7 @@ jobs: steps: - name: Paths filter (PRs only) if: github.event.pull_request.base - uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706 # v4.0.2 + uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3 id: filter with: predicate-quantifier: 'every' From b228e3f1840833a8d272d49af143ddf112b7fe7a Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Fri, 7 Aug 2026 13:00:15 +0200 Subject: [PATCH 46/46] [Win32] Add missing null check in Table tooltip positioning #3487 Table and tree implementations contain a tooltip repositioning functionality to make a tooltip fit into a single monitor. The reason is that tooltips spanning multiple monitors of different zoom can freeze the UI thread on Windows. While in the Tree implementation the repositioning was properly guarded with a null check for the adjusted position, this check is missing in the Table implementation can lead to a NullPointerException in case the calculated result is actually null. This change fixes that by adding an according null check, which effectively skips the tooltip repositioning in case the correct monitor to fit into could not be found. Fixes https://github.com/eclipse-platform/eclipse.platform.swt/issues/3487 --- .../Eclipse SWT/win32/org/eclipse/swt/widgets/Table.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Table.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Table.java index 75b22c3c684..a9ade374d1d 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Table.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Table.java @@ -7161,9 +7161,11 @@ private LRESULT positionTooltip(NMHDR hdr, long lParam) { long hwndToolTip = OS.SendMessage(handle, OS.LVM_GETTOOLTIPS, 0, 0); int flags = OS.SWP_NOACTIVATE | OS.SWP_NOZORDER; Rectangle adjustedTooltipBounds = getDisplay().fitRectangleBoundsIntoMonitorWithCursor(toolRect); - OS.SetWindowPos(hwndToolTip, 0, adjustedTooltipBounds.x, adjustedTooltipBounds.y, - adjustedTooltipBounds.width, adjustedTooltipBounds.height, flags); - result = LRESULT.ONE; + if (adjustedTooltipBounds != null) { + OS.SetWindowPos(hwndToolTip, 0, adjustedTooltipBounds.x, adjustedTooltipBounds.y, + adjustedTooltipBounds.width, adjustedTooltipBounds.height, flags); + result = LRESULT.ONE; + } } else if (isCustomToolTip()) { RECT itemRect = getItemBounds(pinfo, item, hDC); NMTTDISPINFO lpnmtdi = new NMTTDISPINFO();