// Coordinates are that of the shell
 void setContentBounds(WindowDimensions dims) {
   XToolkit.awtLock();
   try {
     // Bounds of content window are of the same size as bounds of Java window and with
     // location as -(insets)
     Rectangle newBounds = dims.getBounds();
     Insets in = dims.getInsets();
     if (in != null) {
       newBounds.setLocation(-in.left, -in.top);
     }
     if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
       insLog.fine("Setting content bounds {0}, old bounds {1}", newBounds, getBounds());
     }
     // Fix for 5023533:
     // Change in the size of the content window means, well, change of the size
     // Change in the location of the content window means change in insets
     boolean needHandleResize = !(newBounds.equals(getBounds()));
     reshape(newBounds);
     if (needHandleResize) {
       insLog.fine("Sending RESIZED");
       handleResize(newBounds);
     }
   } finally {
     XToolkit.awtUnlock();
   }
   validateSurface();
 }
 public void run() {
   log.fine("Wake up EDT");
   synchronized (getTreeLock()) {
     keepBlockingCT.set(false);
     getTreeLock().notifyAll();
   }
   log.fine("Wake up EDT done");
 }
Beispiel #3
0
  /*
   * Requests platform to set native focus on a frame/dialog.
   * In case of a simple window, triggers appropriate java focus change.
   */
  public boolean requestWindowFocus(CausedFocusEvent.Cause cause) {
    if (focusLog.isLoggable(PlatformLogger.FINE)) {
      focusLog.fine("requesting native focus to " + this);
    }

    if (!focusAllowedFor()) {
      focusLog.fine("focus is not allowed");
      return false;
    }

    if (platformWindow.rejectFocusRequest(cause)) {
      return false;
    }

    Window currentActive = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();

    Window opposite = LWKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow();

    // Make the owner active window.
    if (isSimpleWindow()) {
      LWWindowPeer owner = getOwnerFrameDialog(this);

      // If owner is not natively active, request native
      // activation on it w/o sending events up to java.
      if (owner != null && !owner.platformWindow.isActive()) {
        if (focusLog.isLoggable(PlatformLogger.FINE)) {
          focusLog.fine("requesting native focus to the owner " + owner);
        }
        LWWindowPeer currentActivePeer =
            (currentActive != null ? (LWWindowPeer) currentActive.getPeer() : null);

        // Ensure the opposite is natively active and suppress sending events.
        if (currentActivePeer != null && currentActivePeer.platformWindow.isActive()) {
          if (focusLog.isLoggable(PlatformLogger.FINE)) {
            focusLog.fine("the opposite is " + currentActivePeer);
          }
          currentActivePeer.skipNextFocusChange = true;
        }
        owner.skipNextFocusChange = true;

        owner.platformWindow.requestWindowFocus();
      }

      // DKFM will synthesize all the focus/activation events correctly.
      changeFocusedWindow(true, opposite);
      return true;

      // In case the toplevel is active but not focused, change focus directly,
      // as requesting native focus on it will not have effect.
    } else if (getTarget() == currentActive && !getTarget().hasFocus()) {

      changeFocusedWindow(true, opposite);
      return true;
    }

    return platformWindow.requestWindowFocus();
  }
 public boolean requestWindowFocus(long time, boolean timeProvided) {
   // Should check for active state of host application
   if (embedder != null && embedder.isActive()) {
     xembedLog.fine("Requesting focus from embedding host");
     return embedder.requestFocus();
   } else {
     xembedLog.fine("Requesting focus from X");
     return super.requestWindowFocus(time, timeProvided);
   }
 }
Beispiel #5
0
  public boolean postProcessKeyEvent(KeyEvent e) {
    // Processing events only if we are in the focused window but
    // we are not focus owner since otherwise we will get
    // duplicate shortcut events in the client - one is from
    // activate_accelerator, another from forwarded event
    // FIXME: This is probably an incompatibility, protocol
    // doesn't say anything about disable accelerators when client
    // is focused.

    XWindowPeer parent = getToplevelXWindow();
    if (parent == null || !((Window) parent.getTarget()).isFocused() || target.isFocusOwner()) {
      return false;
    }

    boolean result = false;

    if (xembedLog.isLoggable(PlatformLogger.FINER)) xembedLog.finer("Post-processing event " + e);

    // Process ACCELERATORS
    AWTKeyStroke stroke = AWTKeyStroke.getAWTKeyStrokeForEvent(e);
    long accel_id = 0;
    boolean exists = false;
    synchronized (ACCEL_LOCK) {
      exists = accel_lookup.containsKey(stroke);
      if (exists) {
        accel_id = accel_lookup.get(stroke).longValue();
      }
    }
    if (exists) {
      if (xembedLog.isLoggable(PlatformLogger.FINE))
        xembedLog.fine("Activating accelerator " + accel_id);
      xembed.sendMessage(
          xembed.handle,
          XEMBED_ACTIVATE_ACCELERATOR,
          accel_id,
          0,
          0); // FIXME: How about overloaded?
      result = true;
    }

    // Process Grabs, unofficial GTK feature
    exists = false;
    GrabbedKey key = new GrabbedKey(e);
    synchronized (GRAB_LOCK) {
      exists = grabbed_keys.contains(key);
    }
    if (exists) {
      if (xembedLog.isLoggable(PlatformLogger.FINE)) xembedLog.fine("Forwarding grabbed key " + e);
      forwardKeyEvent(e);
      result = true;
    }

    return result;
  }
Beispiel #6
0
 void requestXEmbedFocus() {
   if (isXEmbedActive()) {
     xembedLog.fine("Requesting focus for client");
     postEvent(
         new InvocationEvent(
             target,
             new Runnable() {
               public void run() {
                 target.requestFocus();
               }
             }));
   } else {
     xembedLog.fine("XEmbed is not active - denying request focus");
   }
 }
Beispiel #7
0
 void focusNext() {
   if (isXEmbedActive()) {
     xembedLog.fine("Requesting focus for the next component after embedder");
     postEvent(
         new InvocationEvent(
             target,
             new Runnable() {
               public void run() {
                 KeyboardFocusManager.getCurrentKeyboardFocusManager().focusNextComponent(target);
               }
             }));
   } else {
     xembedLog.fine("XEmbed is not active - denying focus next");
   }
 }
Beispiel #8
0
 void notifyChildEmbedded() {
   xembed.sendMessage(
       xembed.handle,
       XEMBED_EMBEDDED_NOTIFY,
       getWindow(),
       Math.min(xembed.version, XEMBED_VERSION),
       0);
   if (isApplicationActive()) {
     xembedLog.fine("Sending WINDOW_ACTIVATE during initialization");
     xembed.sendMessage(xembed.handle, XEMBED_WINDOW_ACTIVATE);
     if (hasFocus()) {
       xembedLog.fine("Sending FOCUS_GAINED during initialization");
       xembed.sendMessage(xembed.handle, XEMBED_FOCUS_IN, XEMBED_FOCUS_CURRENT, 0, 0);
     }
   }
 }
  public void handleConfigureNotifyEvent(XEvent xev) {
    assert (SunToolkit.isAWTLockHeldByCurrentThread());
    XConfigureEvent xe = xev.get_xconfigure();
    if (xembedLog.isLoggable(PlatformLogger.Level.FINE)) {
      xembedLog.fine(xe.toString());
    }

    // fix for 5063031
    // if we use super.handleConfigureNotifyEvent() we would get wrong
    // size and position because embedded frame really is NOT a decorated one
    checkIfOnNewScreen(
        toGlobal(new Rectangle(xe.get_x(), xe.get_y(), xe.get_width(), xe.get_height())));

    Rectangle oldBounds = getBounds();

    synchronized (getStateLock()) {
      x = xe.get_x();
      y = xe.get_y();
      width = xe.get_width();
      height = xe.get_height();

      dimensions.setClientSize(width, height);
      dimensions.setLocation(x, y);
    }

    if (!getLocation().equals(oldBounds.getLocation())) {
      handleMoved(dimensions);
    }
    reconfigureContentWindow(dimensions);
  }
Beispiel #10
0
 public void windowLostFocus(WindowEvent e) {
   applicationActive = false;
   if (isXEmbedActive()) {
     xembedLog.fine("Sending WINDOW_DEACTIVATE");
     xembed.sendMessage(xembed.handle, XEMBED_WINDOW_DEACTIVATE);
   }
 }
 protected void traverseOutBackward() {
   if (embedder != null && embedder.isActive()) {
     if (embedder.isApplicationActive()) {
       xembedLog.fine("Traversing out Backward");
       embedder.traverseOutBackward();
     }
   }
 }
Beispiel #12
0
  /*
   * Changes focused window on java level.
   */
  protected void changeFocusedWindow(boolean becomesFocused, Window opposite) {
    if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
      focusLog.fine((becomesFocused ? "gaining" : "loosing") + " focus window: " + this);
    }
    if (skipNextFocusChange) {
      focusLog.fine("skipping focus change");
      skipNextFocusChange = false;
      return;
    }
    if (!isFocusableWindow() && becomesFocused) {
      focusLog.fine("the window is not focusable");
      return;
    }
    if (becomesFocused) {
      synchronized (getPeerTreeLock()) {
        if (blocker != null) {
          if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
            focusLog.finest("the window is blocked by " + blocker);
          }
          return;
        }
      }
    }

    // Note, the method is not called:
    // - when the opposite (gaining focus) window is an owned/owner window.
    // - for a simple window in any case.
    if (!becomesFocused && (isGrabbing() || this.isOneOfOwnersOf(grabbingWindow))) {
      if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
        focusLog.fine("ungrabbing on " + grabbingWindow);
      }
      // ungrab a simple window if its owner looses activation.
      grabbingWindow.ungrab();
    }

    KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
    kfmPeer.setCurrentFocusedWindow(becomesFocused ? getTarget() : null);

    int eventID = becomesFocused ? WindowEvent.WINDOW_GAINED_FOCUS : WindowEvent.WINDOW_LOST_FOCUS;
    WindowEvent windowEvent =
        new TimedWindowEvent(getTarget(), eventID, opposite, System.currentTimeMillis());

    // TODO: wrap in SequencedEvent
    postEvent(windowEvent);
  }
Beispiel #13
0
 public long getNSWindowPtr() {
   final long nsWindowPtr = ptr;
   if (nsWindowPtr == 0L) {
     if (logger.isLoggable(PlatformLogger.Level.FINE)) {
       logger.fine(
           "NSWindow already disposed?", new Exception("Pointer to native NSWindow is invalid."));
     }
   }
   return nsWindowPtr;
 }
Beispiel #14
0
  /**
   * *********************************************************** Callbacks from the AWTWindow and
   * AWTView objc classes. ***********************************************************
   */
  private void deliverWindowFocusEvent(boolean gained, CPlatformWindow opposite) {
    // Fix for 7150349: ingore "gained" notifications when the app is inactive.
    if (gained && !((LWCToolkit) Toolkit.getDefaultToolkit()).isApplicationActive()) {
      focusLogger.fine("the app is inactive, so the notification is ignored");
      return;
    }

    LWWindowPeer oppositePeer = (opposite == null) ? null : opposite.getPeer();
    responder.handleWindowFocusEvent(gained, oppositePeer);
  }
Beispiel #15
0
 @Override
 public boolean rejectFocusRequest(FocusEvent.Cause cause) {
   // Cross-app activation requests are not allowed.
   if (cause != FocusEvent.Cause.MOUSE_EVENT
       && !((LWCToolkit) Toolkit.getDefaultToolkit()).isApplicationActive()) {
     focusLogger.fine("the app is inactive, so the request is rejected");
     return true;
   }
   return false;
 }
Beispiel #16
0
 void endDispatching() {
   xembedLog.fine("End dispatching for " + Long.toHexString(xembed.handle));
   XToolkit.awtLock();
   try {
     XDropTargetRegistry.getRegistry().unregisterXEmbedClient(getWindow(), xembed.handle);
     // We can't deselect input since someone else might be interested in it
     XToolkit.removeEventDispatcher(xembed.handle, xembed);
   } finally {
     XToolkit.awtUnlock();
   }
 }
 /** @inheritDoc */
 public boolean exit() {
   if (log.isLoggable(PlatformLogger.Level.FINE)) {
     log.fine(
         "exit(): blockingEDT=" + keepBlockingEDT.get() + ", blockingCT=" + keepBlockingCT.get());
   }
   if (keepBlockingEDT.compareAndSet(true, false)) {
     wakeupEDT();
     return true;
   }
   return false;
 }
Beispiel #18
0
 @Override
 public void setBackground(Color c) {
   if (log.isLoggable(PlatformLogger.Level.FINE)) {
     log.fine("target=" + target + ", old=" + background + ", new=" + c);
   }
   background = c;
   if (xtext != null) {
     if (xtext.getBackground() != c) {
       xtext.setBackground(c);
     }
     xtext.setSelectedTextColor(c);
   }
   repaintText();
 }
Beispiel #19
0
 void forwardKeyEvent(KeyEvent e) {
   xembedLog.fine("Try to forward key event");
   byte[] bdata = getBData(e);
   long data = Native.toData(bdata);
   if (data == 0) {
     return;
   }
   try {
     XKeyEvent ke = new XKeyEvent(data);
     ke.set_window(xembed.handle);
     if (xembedLog.isLoggable(PlatformLogger.FINE))
       xembedLog.fine("Forwarding native key event: " + ke);
     XToolkit.awtLock();
     try {
       XlibWrapper.XSendEvent(
           XToolkit.getDisplay(), xembed.handle, false, XConstants.NoEventMask, data);
     } finally {
       XToolkit.awtUnlock();
     }
   } finally {
     XlibWrapper.unsafe.freeMemory(data);
   }
 }
Beispiel #20
0
 void canvasFocusLost(FocusEvent e) {
   if (isXEmbedActive() && !e.isTemporary()) {
     xembedLog.fine("Forwarding FOCUS_LOST");
     int num = 0;
     if (AccessController.doPrivileged(new GetBooleanAction("sun.awt.xembed.testing"))) {
       Component opp = e.getOppositeComponent();
       try {
         num = Integer.parseInt(opp.getName());
       } catch (NumberFormatException nfe) {
       }
     }
     xembed.sendMessage(xembed.handle, XEMBED_FOCUS_OUT, num, 0, 0);
   }
 }
Beispiel #21
0
 void canvasFocusGained(FocusEvent e) {
   if (isXEmbedActive()) {
     xembedLog.fine("Forwarding FOCUS_GAINED");
     int flavor = XEMBED_FOCUS_CURRENT;
     if (e instanceof CausedFocusEvent) {
       CausedFocusEvent ce = (CausedFocusEvent) e;
       if (ce.getCause() == CausedFocusEvent.Cause.TRAVERSAL_FORWARD) {
         flavor = XEMBED_FOCUS_FIRST;
       } else if (ce.getCause() == CausedFocusEvent.Cause.TRAVERSAL_BACKWARD) {
         flavor = XEMBED_FOCUS_LAST;
       }
     }
     xembed.sendMessage(xembed.handle, XEMBED_FOCUS_IN, flavor, 0, 0);
   }
 }
    public void propertyChange(PropertyChangeEvent e) {
      boolean isDisposed = (Boolean) e.getNewValue();
      if (isDisposed != true) {
        if (log.isLoggable(PlatformLogger.Level.FINE)) {
          log.fine(" Assertion (newValue != true) failed for AppContext.GUI_DISPOSED ");
        }
      }
      AppContext appContext = AppContext.getAppContext();
      synchronized (appContext) {
        appContext.remove(ACTIVE_WINDOWS_KEY);
        appContext.removePropertyChangeListener(AppContext.GUI_DISPOSED, this);

        KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
        kfm.removePropertyChangeListener("activeWindow", activeWindowListener);
      }
    }
Beispiel #23
0
  void initDispatching() {
    if (xembedLog.isLoggable(PlatformLogger.FINE))
      xembedLog.fine("Init embedding for " + Long.toHexString(xembed.handle));
    XToolkit.awtLock();
    try {
      XToolkit.addEventDispatcher(xembed.handle, xembed);
      XlibWrapper.XSelectInput(
          XToolkit.getDisplay(),
          xembed.handle,
          XConstants.StructureNotifyMask | XConstants.PropertyChangeMask);

      XDropTargetRegistry.getRegistry().registerXEmbedClient(getWindow(), xembed.handle);
    } finally {
      XToolkit.awtUnlock();
    }
    xembed.processXEmbedInfo();

    notifyChildEmbedded();
  }
  public void updateGC() {
    int scrn = getScreenImOn();
    if (screenLog.isLoggable(PlatformLogger.Level.FINER)) {
      log.finer("Screen number: " + scrn);
    }

    // get current GD
    Win32GraphicsDevice oldDev = (Win32GraphicsDevice) winGraphicsConfig.getDevice();

    Win32GraphicsDevice newDev;
    GraphicsDevice devs[] = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
    // Occasionally during device addition/removal getScreenImOn can return
    // a non-existing screen number. Use the default device in this case.
    if (scrn >= devs.length) {
      newDev =
          (Win32GraphicsDevice)
              GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
    } else {
      newDev = (Win32GraphicsDevice) devs[scrn];
    }

    // Set winGraphicsConfig to the default GC for the monitor this Window
    // is now mostly on.
    winGraphicsConfig = (Win32GraphicsConfig) newDev.getDefaultConfiguration();
    if (screenLog.isLoggable(PlatformLogger.Level.FINE)) {
      if (winGraphicsConfig == null) {
        screenLog.fine("Assertion (winGraphicsConfig != null) failed");
      }
    }

    // if on a different display, take off old GD and put on new GD
    if (oldDev != newDev) {
      oldDev.removeDisplayChangedListener(this);
      newDev.addDisplayChangedListener(this);
    }

    AWTAccessor.getComponentAccessor()
        .setGraphicsConfiguration((Component) target, winGraphicsConfig);
  }
Beispiel #25
0
 void detachChild() {
   if (xembedLog.isLoggable(PlatformLogger.FINE))
     xembedLog.fine("Detaching child " + Long.toHexString(xembed.handle));
   /**
    * XEmbed specification: "The embedder can unmap the client and reparent the client window to
    * the root window. If the client receives an ReparentNotify event, it should check the parent
    * field of the XReparentEvent structure. If this is the root window of the window's screen,
    * then the protocol is finished and there is no further interaction. If it is a window other
    * than the root window, then the protocol continues with the new parent acting as the embedder
    * window."
    */
   XToolkit.awtLock();
   try {
     XlibWrapper.XUnmapWindow(XToolkit.getDisplay(), xembed.handle);
     XlibWrapper.XReparentWindow(
         XToolkit.getDisplay(), xembed.handle, XToolkit.getDefaultRootWindow(), 0, 0);
   } finally {
     XToolkit.awtUnlock();
   }
   endDispatching();
   xembed.handle = 0;
 }
Beispiel #26
0
  protected boolean focusAllowedFor() {
    Window window = getTarget();
    // TODO: check if modal blocked

    boolean allowed =
        (getBlocker() == null) && window.isVisible() && window.isEnabled() && isFocusableWindow();

    focusLog.fine(
        "Checking whether the focus is allowed ["
            + allowed
            + "] for "
            + window.getName()
            + "; blocker: "
            + ((getBlocker() == null) ? "null" : getBlocker().getClass().getName())
            + "; window.isVisible: "
            + window.isVisible()
            + "; window.isEnabled: "
            + window.isEnabled()
            + "; isFocusableWindow: "
            + isFocusableWindow());

    return allowed;
  }
Beispiel #27
0
 public void handleClientMessage(XEvent xev) {
   super.handleClientMessage(xev);
   XClientMessageEvent msg = xev.get_xclient();
   if (xembedLog.isLoggable(PlatformLogger.FINER))
     xembedLog.finer("Client message to embedder: " + msg);
   if (msg.get_message_type() == xembed.XEmbed.getAtom()) {
     if (xembedLog.isLoggable(PlatformLogger.FINE))
       xembedLog.fine(xembed.XEmbedMessageToString(msg));
   }
   if (isXEmbedActive()) {
     switch ((int) msg.get_data(1)) {
       case XEMBED_REQUEST_FOCUS:
         requestXEmbedFocus();
         break;
       case XEMBED_FOCUS_NEXT:
         focusNext();
         break;
       case XEMBED_FOCUS_PREV:
         focusPrev();
         break;
       case XEMBED_REGISTER_ACCELERATOR:
         registerAccelerator(msg.get_data(2), msg.get_data(3), msg.get_data(4));
         break;
       case XEMBED_UNREGISTER_ACCELERATOR:
         unregisterAccelerator(msg.get_data(2));
         break;
       case NON_STANDARD_XEMBED_GTK_GRAB_KEY:
         grabKey(msg.get_data(3), msg.get_data(4));
         break;
       case NON_STANDARD_XEMBED_GTK_UNGRAB_KEY:
         ungrabKey(msg.get_data(3), msg.get_data(4));
         break;
     }
   } else {
     xembedLog.finer("But XEmbed is not Active!");
   }
 }
Beispiel #28
0
 void childDestroyed() {
   xembedLog.fine("Child " + Long.toHexString(xembed.handle) + " has self-destroyed.");
   endDispatching();
   xembed.handle = 0;
 }
  /** @inheritDoc */
  @Override
  public boolean enter() {
    if (log.isLoggable(PlatformLogger.Level.FINE)) {
      log.fine(
          "enter(): blockingEDT=" + keepBlockingEDT.get() + ", blockingCT=" + keepBlockingCT.get());
    }

    if (!keepBlockingEDT.compareAndSet(false, true)) {
      log.fine("The secondary loop is already running, aborting");
      return false;
    }

    final Runnable run =
        new Runnable() {
          public void run() {
            log.fine("Starting a new event pump");
            if (filter == null) {
              dispatchThread.pumpEvents(condition);
            } else {
              dispatchThread.pumpEventsForFilter(condition, filter);
            }
          }
        };

    // We have two mechanisms for blocking: if we're on the
    // dispatch thread, start a new event pump; if we're
    // on any other thread, call wait() on the treelock

    Thread currentThread = Thread.currentThread();
    if (currentThread == dispatchThread) {
      if (log.isLoggable(PlatformLogger.Level.FINEST)) {
        log.finest("On dispatch thread: " + dispatchThread);
      }
      if (interval != 0) {
        if (log.isLoggable(PlatformLogger.Level.FINEST)) {
          log.finest("scheduling the timer for " + interval + " ms");
        }
        timer.schedule(
            timerTask =
                new TimerTask() {
                  @Override
                  public void run() {
                    if (keepBlockingEDT.compareAndSet(true, false)) {
                      wakeupEDT();
                    }
                  }
                },
            interval);
      }
      // Dispose SequencedEvent we are dispatching on the the current
      // AppContext, to prevent us from hang - see 4531693 for details
      SequencedEvent currentSE =
          KeyboardFocusManager.getCurrentKeyboardFocusManager().getCurrentSequencedEvent();
      if (currentSE != null) {
        if (log.isLoggable(PlatformLogger.Level.FINE)) {
          log.fine("Dispose current SequencedEvent: " + currentSE);
        }
        currentSE.dispose();
      }
      // In case the exit() method is called before starting
      // new event pump it will post the waking event to EDT.
      // The event will be handled after the the new event pump
      // starts. Thus, the enter() method will not hang.
      //
      // Event pump should be privileged. See 6300270.
      AccessController.doPrivileged(
          new PrivilegedAction() {
            public Object run() {
              run.run();
              return null;
            }
          });
    } else {
      if (log.isLoggable(PlatformLogger.Level.FINEST)) {
        log.finest("On non-dispatch thread: " + currentThread);
      }
      synchronized (getTreeLock()) {
        if (filter != null) {
          dispatchThread.addEventFilter(filter);
        }
        try {
          EventQueue eq = dispatchThread.getEventQueue();
          eq.postEvent(new PeerEvent(this, run, PeerEvent.PRIORITY_EVENT));
          keepBlockingCT.set(true);
          if (interval > 0) {
            long currTime = System.currentTimeMillis();
            while (keepBlockingCT.get()
                && ((extCondition != null) ? extCondition.evaluate() : true)
                && (currTime + interval > System.currentTimeMillis())) {
              getTreeLock().wait(interval);
            }
          } else {
            while (keepBlockingCT.get()
                && ((extCondition != null) ? extCondition.evaluate() : true)) {
              getTreeLock().wait();
            }
          }
          if (log.isLoggable(PlatformLogger.Level.FINE)) {
            log.fine("waitDone " + keepBlockingEDT.get() + " " + keepBlockingCT.get());
          }
        } catch (InterruptedException e) {
          if (log.isLoggable(PlatformLogger.Level.FINE)) {
            log.fine("Exception caught while waiting: " + e);
          }
        } finally {
          if (filter != null) {
            dispatchThread.removeEventFilter(filter);
          }
        }
        // If the waiting process has been stopped because of the
        // time interval passed or an exception occurred, the state
        // should be changed
        keepBlockingEDT.set(false);
        keepBlockingCT.set(false);
      }
    }

    return true;
  }