eclipse.platform.swt icon indicating copy to clipboard operation
eclipse.platform.swt copied to clipboard

[Gtk3] Bug: SWTException on Table.remove(...) for a row with focus

Open om-11-2024 opened this issue 1 year ago • 1 comments

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:

  1. Select the platform(s) on which the behavior is seen:
    • [ ] All OS
    • [ ] Windows
    • [x] Linux
    • [ ] macOS
  1. 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

  2. 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.

om-11-2024 avatar Nov 21 '24 13:11 om-11-2024

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.

om-11-2024 avatar Jan 23 '25 10:01 om-11-2024

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.

akurtakov avatar Sep 01 '25 13:09 akurtakov