[Gtk3] Bug: SWTException on Table.remove(...) for a row with focus
Describe the bug
SWTException on Table.remove(...) for a row with focus.
To Reproduce A standalone SWT snippet to reproduce the behavior:
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
public class SwtBugSnippet {
public static void main( String[] args ) {
var display = Display.getDefault();
var shell = new Shell( display );
shell.setLayout( new GridLayout() );
var button = new Button( shell, SWT.PUSH );
button.setText( "GO" );
var table = new Table( shell, SWT.VIRTUAL );
var layoutData = new GridData( 300, 300 );
layoutData.grabExcessHorizontalSpace = layoutData.grabExcessVerticalSpace = true;
table.setLayoutData( layoutData );
table.setItemCount( 2 );
table.addListener( SWT.SetData, event -> {
var item = ( TableItem ) event.item;
item.setText( "Item #" + System.identityHashCode( item ) );
} );
shell.pack();
shell.open();
table.setFocus();
button.addListener( SWT.Selection, e -> {
table.clear( 0 );
table.remove( new int[] { 0 } );
} );
while ( !shell.isDisposed() ) {
if ( !display.readAndDispatch() ) {
display.sleep();
}
}
}
}
Just press the "GO" button and the program terminates after printing this to stderr:
Exception in thread "main" org.eclipse.swt.SWTException: Widget is disposed
at org.eclipse.swt.SWT.error(SWT.java:4922)
at org.eclipse.swt.SWT.error(SWT.java:4837)
at org.eclipse.swt.SWT.error(SWT.java:4808)
at org.eclipse.swt.widgets.Widget.error(Widget.java:565)
at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:480)
at org.eclipse.swt.widgets.TableItem.setText(TableItem.java:1363)
at SwtBugSnippet.lambda$0(SwtBugSnippet.java:24)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89)
at org.eclipse.swt.widgets.Display.sendEvent(Display.java:5855)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1529)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1555)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1538)
at org.eclipse.swt.widgets.Table.checkData(Table.java:289)
at org.eclipse.swt.widgets.Table.cellDataProc(Table.java:227)
at org.eclipse.swt.widgets.Display.cellDataProc(Display.java:995)
at org.eclipse.swt.internal.gtk.GTK.gtk_list_store_remove(Native Method)
at org.eclipse.swt.widgets.Table.remove(Table.java:2772)
at SwtBugSnippet.lambda$1(SwtBugSnippet.java:34)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89)
at org.eclipse.swt.widgets.Display.sendEvent(Display.java:5855)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1529)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:5065)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:4517)
at SwtBugSnippet.main(SwtBugSnippet.java:38)
Expected behavior The row should be successfully removed without errors.
Screenshots Not applicable.
Environment:
- Select the platform(s) on which the behavior is seen:
-
- [ ] All OS
-
- [ ] Windows
-
- [x] Linux
-
- [ ] macOS
-
Additional OS info (e.g. OS version, Linux Desktop, etc) Os: Ubuntu 24.04.1 LTS Xfce: 4.18 Gtk: 3.24.41 Swt: 4.967.8
-
JRE/JDK version OpenJDK 64-Bit Server VM (build 17.0.12+7-Ubuntu-1ubuntu224.04, mixed mode, sharing)
Version since at least since Swt 4.967.8
Workaround (or) Additional context I will submit a pull request with a fix a little bit later.
A possible workaround for this bug until it's fixed is to add event hook for "row-deleted" signal in GTK3 and in to unset row focus in that hook.
Unsetting row focus can be done with gtk_tree_view_set_cursor() (here's its code for GTK3.24.41 - current GTK3 version for Ubuntu 24.04LTS).
To add hook for "row-deleted" signal use g_signal_add_emission_hook(...).
Both native methods are present in org.eclipse.swt.internal.gtk.GTK.
I have landed a generic safety net that happens to fix this case too. The snippet you created can serve as an example how to report issues in SWT . Unfortunately, we (I for sure) missed it and thus it stayed without attention for so long.