Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LightweightSystem#setUpdateManager does't dispose old UpdateManager #605

Open
ptziegler opened this issue Oct 31, 2024 · 0 comments
Open
Labels
good first issue Good for newcomers

Comments

@ptziegler
Copy link
Contributor

Based on https://bugs.eclipse.org/bugs/show_bug.cgi?id=250255

Steps To Reproduce:

public class EditableFigureCanvasTest extends TestCase {
  private static final class TestUpdateManager extends UpdateManager {
    @Override
    public void addDirtyRegion(IFigure figure, int x, int y, int w, int h) {
      
    }

    @Override
    public void addInvalidFigure(IFigure figure) {
      
    }

    @Override
    public void performUpdate() {
      
    }

    @Override
    public void performUpdate(Rectangle exposed) {
      
    }

    @Override
    public void setGraphicsSource(GraphicsSource gs) {
      
    }

    @Override
    public void setRoot(IFigure figure) {
      
    }

    @Override
    public boolean isDisposed() {
      return super.isDisposed();
    }
  }

  @Test
  public void test_setUpdateManager() {
    //test if old updateManager is disposed
    Display.getDefault().syncExec(new Runnable() {
      public void run() {
        //test if bug still exists
        LightweightSystem lightweightSystem = new LightweightSystem();
        TestUpdateManager um = new TestUpdateManager();
        lightweightSystem.setUpdateManager(um);
        lightweightSystem.setUpdateManager(new TestUpdateManager());
        assertFalse("bug is fixed, remove workaround",um.isDisposed());
           }
    });
  }
}

To Produce a widget is disposed exception setup a canvas:

  1. create a canvas
  2. add an update listener to the UpdateManager
  3. access the canvas inside listener
  4. dispose canvas after replacing the UpdateManager

More information:
If the widget is disposed after setting the new UpdateManager, the old UpdateManager is not disposed and will execute its pending updates and validations. This will result in a widget is disposed error.


Generally, I don't think disposing the old UpdateManager is a good idea, as we have no idea where else it might be used (perhaps a different LWS?). Instead, I think it's sufficient to simply remove UpdateListener from the old manager to solve this problem.

After a quick glance, I noticed that there is a conceptional problem with replacing the UpdateManager. The UpdateManager is hooked to the FigureCanvas upon creation. But this is only done for the initial manager, meaning that the new UpdateManager won't receive any of the new events and any further updates are lost once the old one is disposed.

getLightweightSystem().getUpdateManager().addUpdateListener(new UpdateListener() {
@Override
public void notifyPainting(Rectangle damage, java.util.Map<IFigure, Rectangle> dirtyRegions) {
// nothing to do for now
}
@Override
public void notifyValidating() {
if (!isDisposed()) {
layoutViewport();
}
}
});

A more prudent approach would be to have the LightweightSystem fire an event, whenever the update manager is replaced. The FigureCanvas listens to this event and then updates the listener accordingly. Any listeners added outside Draw2D have to be removed by the client (perhaps even via the same event).

@ptziegler ptziegler added the good first issue Good for newcomers label Oct 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

1 participant