[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[albireo-dev] resize/relayout problem again
|
The return of the undead bug:
To reproduce:
- On Windows.
- Set the Parameters.borderFlag = SWT.BORDER.
- Run the application, open the "Relayout example view" and maximize it.
Then close.
- Run the application again.
I got a screenshot like this; the background of the part that is covered by
the borderlessChild but not by the AWT Frame is not repainted.
This mostly fixes it. There is still a race condition in it (I got a wrong
display once in 40 times); I'll try to see if I can fix that.
Bruno
Index: src/org/eclipse/albireo/core/SwingControl.java
===================================================================
RCS file: /cvsroot/technology/org.eclipse.albireo/org.eclipse.albireo.core/src/org/eclipse/albireo/core/SwingControl.java,v
retrieving revision 1.75
diff -c -3 -r1.75 SwingControl.java
*** src/org/eclipse/albireo/core/SwingControl.java 29 Apr 2008 20:12:05 -0000 1.75
--- src/org/eclipse/albireo/core/SwingControl.java 30 Apr 2008 15:42:52 -0000
***************
*** 694,731 ****
Platform.isGtk() || Platform.isCarbon();
/**
* Propagate the width and height from SWT to the AWT frame.
* Only used if !AUTOMATIC_SET_AWT_SIZE.
*/
! private void setAWTSize(final int width, final int height) {
assert Display.getCurrent() != null; // On SWT event thread
- if (verboseSizeLayout)
- System.err.println("SWT thread: Preparing to set size: " + width + " x " + height + " for " + swingComponent);
// Get the AWT time of the notification that triggered this processing.
final Integer onBehalfAWTTime = (Integer)onBehalfAWTTimes.get(Thread.currentThread());
! // Shortcut to post a Runnable that has no effect.
! // (lastValidatedAWTTime can only increase until the Runnable is
! // actually run.)
! if (onBehalfAWTTime == null
! || lastValidatedAWTTime - onBehalfAWTTime.intValue() < 0) {
// Switch to the AWT thread.
! EventQueue.invokeLater(
! new Runnable() {
! public void run() {
! // Compare the AWT time of the notification with the
! // time at which the rootpane was last validated.
! if (onBehalfAWTTime == null
! || lastValidatedAWTTime - onBehalfAWTTime.intValue() < 0) {
! // Set the frame's (and thus also the rootpane's) size.
! if (verboseSizeLayout)
! System.err.println("SWT->AWT thread: Setting size: " + width + " x " + height + " for " + swingComponent);
! if (frame != null) {
! frame.setBounds(0, 0, Math.max(width, 0), Math.max(height, 0));
! frame.validate();
! }
! }
! }
! });
}
}
--- 694,804 ----
Platform.isGtk() || Platform.isCarbon();
/**
+ * This class represents a queue of requests to set the AWT frame's size.
+ * Multiple requests are automatically merged, by using the last among
+ * the specified sizes, and the OR of the preconditions.
+ */
+ class SetAWTSizeQueue implements Runnable {
+ private boolean pending /* = false */;
+ // If pending:
+ // The AWT time of the notification that triggered this request
+ // (null means unknown, i.e. execute the request unconditionally).
+ private Integer onBehalfAWTTime;
+ // If pending:
+ // The size to which the frame shall be resized.
+ private int width;
+ private int height;
+ /**
+ * Creates an empty queue.
+ */
+ SetAWTSizeQueue() {
+ pending = false;
+ }
+ /**
+ * Enqueues a request to this queue.
+ * @param onBehalfAWTTime The AWT time of the notification that
+ * triggered this request, or null.
+ * @param width The size to which the frame shall be resized.
+ * @param height The size to which the frame shall be resized.
+ * @return true if this queue needs to be started as a Runnable
+ */
+ synchronized boolean enqueue(Integer onBehalfAWTTime, int width, int height) {
+ assert Display.getCurrent() != null; // On SWT event thread
+ if (verboseSizeLayout)
+ System.err.println("SWT thread: Preparing to set size: " + width + " x " + height + " for " + swingComponent);
+ boolean wasPending = this.pending;
+ // Shortcut to avoid posting a Runnable that has no effect.
+ // (lastValidatedAWTTime can only increase until the Runnable is
+ // actually run.)
+ boolean effective = (onBehalfAWTTime == null
+ || lastValidatedAWTTime - onBehalfAWTTime.intValue() < 0);
+ if (wasPending || effective) {
+ // Use the last specified size.
+ this.width = width;
+ this.height = height;
+ // Use the OR of the old onBehalfAWTTime and the new onBehalfAWTTime.
+ if (wasPending) {
+ this.onBehalfAWTTime =
+ (this.onBehalfAWTTime == null || onBehalfAWTTime == null
+ ? null
+ : (this.onBehalfAWTTime.intValue() - onBehalfAWTTime.intValue() < 0
+ ? onBehalfAWTTime
+ : this.onBehalfAWTTime));
+ } else {
+ this.onBehalfAWTTime = onBehalfAWTTime;
+ }
+ this.pending = true;
+ return !wasPending;
+ } else {
+ // Avoid posting a Runnable that has no effect.
+ return false;
+ }
+ }
+ /**
+ * Returns the enqueued request and removes it from the queue.
+ * @return The size to which the frame shall be resized, or null if
+ * if does not need to be resized after all.
+ */
+ private synchronized Dimension dequeue() {
+ assert EventQueue.isDispatchThread(); // On AWT event thread
+ if (pending) {
+ pending = false;
+ // Compare the AWT time of the notification with the
+ // time at which the rootpane was last validated.
+ if (onBehalfAWTTime == null
+ || lastValidatedAWTTime - onBehalfAWTTime.intValue() < 0) {
+ return new Dimension(width, height);
+ }
+ }
+ return null;
+ }
+ // Implementation of Runnable.
+ public void run() {
+ Dimension size = dequeue();
+ if (size != null) {
+ // Set the frame's (and thus also the rootpane's) size.
+ if (verboseSizeLayout)
+ System.err.println("SWT->AWT thread: Setting size: " + size.width + " x " + size.height + " for " + swingComponent);
+ if (frame != null) {
+ frame.setBounds(0, 0, Math.max(size.width, 0), Math.max(size.height, 0));
+ frame.validate();
+ }
+ }
+ }
+ }
+ private SetAWTSizeQueue setAWTSizeQueue = new SetAWTSizeQueue();
+
+ /**
* Propagate the width and height from SWT to the AWT frame.
* Only used if !AUTOMATIC_SET_AWT_SIZE.
*/
! private void setAWTSize(int width, int height) {
assert Display.getCurrent() != null; // On SWT event thread
// Get the AWT time of the notification that triggered this processing.
final Integer onBehalfAWTTime = (Integer)onBehalfAWTTimes.get(Thread.currentThread());
! if (setAWTSizeQueue.enqueue(onBehalfAWTTime, width, height)) {
// Switch to the AWT thread.
! EventQueue.invokeLater(setAWTSizeQueue);
}
}