예제 #1
0
 @Override
 protected void setVisibleImpl(final boolean visible) {
   if (!visible && warningWindow != null) {
     warningWindow.setVisible(false, false);
   }
   updateFocusableWindowState();
   super.setVisibleImpl(visible);
   // TODO: update graphicsConfig, see 4868278
   platformWindow.setVisible(visible);
   if (isSimpleWindow()) {
     KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
     if (visible) {
       if (!getTarget().isAutoRequestFocus()) {
         return;
       } else {
         requestWindowFocus(CausedFocusEvent.Cause.ACTIVATION);
       }
       // Focus the owner in case this window is focused.
     } else if (kfmPeer.getCurrentFocusedWindow() == getTarget()) {
       // Transfer focus to the owner.
       LWWindowPeer owner = getOwnerFrameDialog(LWWindowPeer.this);
       if (owner != null) {
         owner.requestWindowFocus(CausedFocusEvent.Cause.ACTIVATION);
       }
     }
   }
 }
예제 #2
0
 // MouseDown in non-client area
 @Override
 public void notifyNCMouseDown() {
   // Ungrab except for a click on a Dialog with the grabbing owner
   if (grabbingWindow != null && !grabbingWindow.isOneOfOwnersOf(this)) {
     grabbingWindow.ungrab();
   }
 }
예제 #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();
  }
예제 #4
0
  public LWWindowPeer(
      Window target,
      PlatformComponent platformComponent,
      PlatformWindow platformWindow,
      PeerType peerType) {
    super(target, platformComponent);
    this.platformWindow = platformWindow;
    this.peerType = peerType;

    Window owner = target.getOwner();
    LWWindowPeer ownerPeer =
        owner == null ? null : (LWWindowPeer) AWTAccessor.getComponentAccessor().getPeer(owner);
    PlatformWindow ownerDelegate = (ownerPeer != null) ? ownerPeer.getPlatformWindow() : null;

    // The delegate.initialize() needs a non-null GC on X11.
    GraphicsConfiguration gc = getTarget().getGraphicsConfiguration();
    synchronized (getStateLock()) {
      // graphicsConfig should be updated according to the real window
      // bounds when the window is shown, see 4868278
      this.graphicsConfig = gc;
    }

    if (!target.isFontSet()) {
      target.setFont(DEFAULT_FONT);
    }

    if (!target.isBackgroundSet()) {
      target.setBackground(SystemColor.window);
    } else {
      // first we check if user provided alpha for background. This is
      // similar to what Apple's Java do.
      // Since JDK7 we should rely on setOpacity() only.
      // this.opacity = c.getAlpha();
    }

    if (!target.isForegroundSet()) {
      target.setForeground(SystemColor.windowText);
      // we should not call setForeground because it will call a repaint
      // which the peer may not be ready to do yet.
    }

    platformWindow.initialize(target, this, ownerDelegate);

    // Init warning window(for applets)
    SecurityWarningWindow warn = null;
    if (target.getWarningString() != null) {
      // accessSystemTray permission allows to display TrayIcon, TrayIcon tooltip
      // and TrayIcon balloon windows without a warning window.
      if (!AWTAccessor.getWindowAccessor().isTrayIconWindow(target)) {
        LWToolkit toolkit = (LWToolkit) Toolkit.getDefaultToolkit();
        warn = toolkit.createSecurityWarning(target, this);
      }
    }

    warningWindow = warn;
  }
예제 #5
0
 private boolean isFocusableWindow() {
   boolean focusable = getTarget().isFocusableWindow();
   if (isSimpleWindow()) {
     LWWindowPeer ownerPeer = getOwnerFrameDialog(this);
     if (ownerPeer == null) {
       return false;
     }
     return focusable && ownerPeer.getTarget().isFocusableWindow();
   }
   return focusable;
 }
예제 #6
0
 /*
  * Retrieves the owner of the peer.
  * Note: this method returns the owner which can be activated, (i.e. the instance
  * of Frame or Dialog may be returned).
  */
 static LWWindowPeer getOwnerFrameDialog(LWWindowPeer peer) {
   Window owner = (peer != null ? peer.getTarget().getOwner() : null);
   while (owner != null && !(owner instanceof Frame || owner instanceof Dialog)) {
     owner = owner.getOwner();
   }
   return owner == null ? null : (LWWindowPeer) AWTAccessor.getComponentAccessor().getPeer(owner);
 }
예제 #7
0
 // MouseDown in non-client area
 @Override
 public void notifyNCMouseDown() {
   // Ungrab except for a click on a Dialog with the grabbing owner
   if (grabbingWindow != null && grabbingWindow != getOwnerFrameDialog(this)) {
     grabbingWindow.ungrab();
   }
 }
예제 #8
0
 static LWWindowPeer getOwnerFrameDialog(LWWindowPeer peer) {
   Window owner = (peer != null ? peer.getTarget().getOwner() : null);
   while (owner != null && !(owner instanceof Frame || owner instanceof Dialog)) {
     owner = owner.getOwner();
   }
   return owner != null ? (LWWindowPeer) owner.getPeer() : null;
 }
예제 #9
0
 private boolean isOneOfOwnersOf(LWWindowPeer peer) {
   Window owner = (peer != null ? peer.getTarget().getOwner() : null);
   while (owner != null) {
     if ((LWWindowPeer) owner.getPeer() == this) {
       return true;
     }
     owner = owner.getOwner();
   }
   return false;
 }
예제 #10
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);
  }
예제 #11
0
  /*
   * Called by the delegate to dispatch the event to Java. Event
   * coordinates are relative to non-client window are, i.e. the top-left
   * point of the client area is (insets.top, insets.left).
   */
  @Override
  public void notifyMouseEvent(
      PlatformWindow eventPlatformWindow,
      int id,
      long when,
      int button,
      int x,
      int y,
      int screenX,
      int screenY,
      int modifiers,
      int clickCount,
      boolean popupTrigger,
      byte[] bdata) {
    // TODO: fill "bdata" member of AWTEvent
    Rectangle r = getBounds();
    // findPeerAt() expects parent coordinates
    LWComponentPeer<?, ?> targetPeer = findPeerAt(r.x + x, r.y + y);

    if (id == MouseEvent.MOUSE_EXITED) {
      isMouseOver = false;
      if (lastMouseEventPeer != null) {
        if (lastMouseEventPeer.isEnabled()) {
          Point lp = lastMouseEventPeer.windowToLocal(x, y, this);
          Component target = lastMouseEventPeer.getTarget();
          postMouseExitedEvent(
              target, when, modifiers, lp, screenX, screenY, clickCount, popupTrigger, button);
        }

        // Sometimes we may get MOUSE_EXITED after lastCommonMouseEventPeer is switched
        // to a peer from another window. So we must first check if this peer is
        // the same as lastWindowPeer
        if (lastCommonMouseEventPeer != null
            && lastCommonMouseEventPeer.getWindowPeerOrSelf() == this) {
          lastCommonMouseEventPeer = null;
        }
        lastMouseEventPeer = null;
      }
    } else if (id == MouseEvent.MOUSE_ENTERED) {
      isMouseOver = true;
      if (targetPeer != null) {
        if (targetPeer.isEnabled()) {
          Point lp = targetPeer.windowToLocal(x, y, this);
          Component target = targetPeer.getTarget();
          postMouseEnteredEvent(
              target, when, modifiers, lp, screenX, screenY, clickCount, popupTrigger, button);
        }
        lastCommonMouseEventPeer = targetPeer;
        lastMouseEventPeer = targetPeer;
      }
    } else {

      LWWindowPeer topmostWindowPeer =
          eventPlatformWindow != null ? eventPlatformWindow.getPeer() : null;

      // topmostWindowPeer == null condition is added for the backward
      // compatibility with applets. It can be removed when the
      // getTopmostPlatformWindowUnderMouse() method will be properly
      // implemented in CPlatformEmbeddedFrame class
      if (topmostWindowPeer == this || topmostWindowPeer == null) {
        generateMouseEnterExitEventsForComponents(
            when, button, x, y, screenX, screenY, modifiers, clickCount, popupTrigger, targetPeer);
      } else {
        LWComponentPeer<?, ?> topmostTargetPeer = topmostWindowPeer.findPeerAt(r.x + x, r.y + y);
        topmostWindowPeer.generateMouseEnterExitEventsForComponents(
            when,
            button,
            x,
            y,
            screenX,
            screenY,
            modifiers,
            clickCount,
            popupTrigger,
            topmostTargetPeer);
      }

      // TODO: fill "bdata" member of AWTEvent

      int eventButtonMask = (button > 0) ? MouseEvent.getMaskForButton(button) : 0;
      int otherButtonsPressed = modifiers & ~eventButtonMask;

      // For pressed/dragged/released events OS X treats other
      // mouse buttons as if they were BUTTON2, so we do the same
      int targetIdx = (button > 3) ? MouseEvent.BUTTON2 - 1 : button - 1;

      // MOUSE_ENTERED/EXITED are generated for the components strictly under
      // mouse even when dragging. That's why we first update lastMouseEventPeer
      // based on initial targetPeer value and only then recalculate targetPeer
      // for MOUSE_DRAGGED/RELEASED events
      if (id == MouseEvent.MOUSE_PRESSED) {

        // Ungrab only if this window is not an owned window of the grabbing one.
        if (!isGrabbing() && grabbingWindow != null && !grabbingWindow.isOneOfOwnersOf(this)) {
          grabbingWindow.ungrab();
        }
        if (otherButtonsPressed == 0) {
          mouseClickButtons = eventButtonMask;
        } else {
          mouseClickButtons |= eventButtonMask;
        }

        // The window should be focused on mouse click. If it gets activated by the native platform,
        // this request will be no op. It will take effect when:
        // 1. A simple not focused window is clicked.
        // 2. An active but not focused owner frame/dialog is clicked.
        // The mouse event then will trigger a focus request "in window" to the component, so the
        // window
        // should gain focus before.
        requestWindowFocus(CausedFocusEvent.Cause.MOUSE_EVENT);

        mouseDownTarget[targetIdx] = targetPeer;
      } else if (id == MouseEvent.MOUSE_DRAGGED) {
        // Cocoa dragged event has the information about which mouse
        // button is being dragged. Use it to determine the peer that
        // should receive the dragged event.
        targetPeer = mouseDownTarget[targetIdx];
        mouseClickButtons &= ~modifiers;
      } else if (id == MouseEvent.MOUSE_RELEASED) {
        // TODO: currently, mouse released event goes to the same component
        // that received corresponding mouse pressed event. For most cases,
        // it's OK, however, we need to make sure that our behavior is consistent
        // with 1.6 for cases where component in question have been
        // hidden/removed in between of mouse pressed/released events.
        targetPeer = mouseDownTarget[targetIdx];

        if ((modifiers & eventButtonMask) == 0) {
          mouseDownTarget[targetIdx] = null;
        }

        // mouseClickButtons is updated below, after MOUSE_CLICK is sent
      }

      if (targetPeer == null) {
        // TODO This can happen if this window is invisible. this is correct behavior in this case?
        targetPeer = this;
      }

      Point lp = targetPeer.windowToLocal(x, y, this);
      if (targetPeer.isEnabled()) {
        MouseEvent event =
            new MouseEvent(
                targetPeer.getTarget(),
                id,
                when,
                modifiers,
                lp.x,
                lp.y,
                screenX,
                screenY,
                clickCount,
                popupTrigger,
                button);
        postEvent(event);
      }

      if (id == MouseEvent.MOUSE_RELEASED) {
        if ((mouseClickButtons & eventButtonMask) != 0 && targetPeer.isEnabled()) {
          postEvent(
              new MouseEvent(
                  targetPeer.getTarget(),
                  MouseEvent.MOUSE_CLICKED,
                  when,
                  modifiers,
                  lp.x,
                  lp.y,
                  screenX,
                  screenY,
                  clickCount,
                  popupTrigger,
                  button));
        }
        mouseClickButtons &= ~eventButtonMask;
      }
    }
    notifyUpdateCursor();
  }
예제 #12
0
 @Override
 public void notifyActivation(boolean activation, LWWindowPeer opposite) {
   Window oppositeWindow = (opposite == null) ? null : opposite.getTarget();
   changeFocusedWindow(activation, oppositeWindow);
 }
예제 #13
0
 void grab() {
   if (grabbingWindow != null && !isGrabbing()) {
     grabbingWindow.ungrab();
   }
   grabbingWindow = this;
 }
예제 #14
0
  /*
   * Called by the delegate to dispatch the event to Java. Event
   * coordinates are relative to non-client window are, i.e. the top-left
   * point of the client area is (insets.top, insets.left).
   */
  @Override
  public void notifyMouseEvent(
      int id,
      long when,
      int button,
      int x,
      int y,
      int screenX,
      int screenY,
      int modifiers,
      int clickCount,
      boolean popupTrigger,
      byte[] bdata) {
    // TODO: fill "bdata" member of AWTEvent
    Rectangle r = getBounds();
    // findPeerAt() expects parent coordinates
    LWComponentPeer targetPeer = findPeerAt(r.x + x, r.y + y);
    LWWindowPeer lastWindowPeer =
        (lastMouseEventPeer != null) ? lastMouseEventPeer.getWindowPeerOrSelf() : null;
    LWWindowPeer curWindowPeer = (targetPeer != null) ? targetPeer.getWindowPeerOrSelf() : null;

    if (id == MouseEvent.MOUSE_EXITED) {
      // Sometimes we may get MOUSE_EXITED after lastMouseEventPeer is switched
      // to a peer from another window. So we must first check if this peer is
      // the same as lastWindowPeer
      if (lastWindowPeer == this) {
        if (isEnabled()) {
          Point lp = lastMouseEventPeer.windowToLocal(x, y, lastWindowPeer);
          Component target = lastMouseEventPeer.getTarget();
          postMouseEnteredExitedEvent(
              target,
              MouseEvent.MOUSE_EXITED,
              when,
              modifiers,
              lp,
              screenX,
              screenY,
              clickCount,
              popupTrigger,
              button);
        }
        lastMouseEventPeer = null;
      }
    } else {
      if (targetPeer != lastMouseEventPeer) {
        // lastMouseEventPeer may be null if mouse was out of Java windows
        if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) {
          // Sometimes, MOUSE_EXITED is not sent by delegate (or is sent a bit
          // later), in which case lastWindowPeer is another window
          if (lastWindowPeer != this) {
            Point oldp = lastMouseEventPeer.windowToLocal(x, y, lastWindowPeer);
            // Additionally translate from this to lastWindowPeer coordinates
            Rectangle lr = lastWindowPeer.getBounds();
            oldp.x += r.x - lr.x;
            oldp.y += r.y - lr.y;
            Component target = lastMouseEventPeer.getTarget();
            postMouseEnteredExitedEvent(
                target,
                MouseEvent.MOUSE_EXITED,
                when,
                modifiers,
                oldp,
                screenX,
                screenY,
                clickCount,
                popupTrigger,
                button);
          } else {
            Point oldp = lastMouseEventPeer.windowToLocal(x, y, this);
            Component target = lastMouseEventPeer.getTarget();
            postMouseEnteredExitedEvent(
                target,
                MouseEvent.MOUSE_EXITED,
                when,
                modifiers,
                oldp,
                screenX,
                screenY,
                clickCount,
                popupTrigger,
                button);
          }
        }
        lastMouseEventPeer = targetPeer;
        if (targetPeer != null && targetPeer.isEnabled() && id != MouseEvent.MOUSE_ENTERED) {
          Point newp = targetPeer.windowToLocal(x, y, curWindowPeer);
          Component target = targetPeer.getTarget();
          postMouseEnteredExitedEvent(
              target,
              MouseEvent.MOUSE_ENTERED,
              when,
              modifiers,
              newp,
              screenX,
              screenY,
              clickCount,
              popupTrigger,
              button);
        }
      }
      // TODO: fill "bdata" member of AWTEvent

      int eventButtonMask = (button > 0) ? MouseEvent.getMaskForButton(button) : 0;
      int otherButtonsPressed = modifiers & ~eventButtonMask;

      // For pressed/dragged/released events OS X treats other
      // mouse buttons as if they were BUTTON2, so we do the same
      int targetIdx = (button > 3) ? MouseEvent.BUTTON2 - 1 : button - 1;

      // MOUSE_ENTERED/EXITED are generated for the components strictly under
      // mouse even when dragging. That's why we first update lastMouseEventPeer
      // based on initial targetPeer value and only then recalculate targetPeer
      // for MOUSE_DRAGGED/RELEASED events
      if (id == MouseEvent.MOUSE_PRESSED) {

        // Ungrab only if this window is not an owned window of the grabbing one.
        if (!isGrabbing()
            && grabbingWindow != null
            && grabbingWindow != getOwnerFrameDialog(this)) {
          grabbingWindow.ungrab();
        }
        if (otherButtonsPressed == 0) {
          mouseClickButtons = eventButtonMask;
        } else {
          mouseClickButtons |= eventButtonMask;
        }

        mouseDownTarget[targetIdx] = targetPeer;
      } else if (id == MouseEvent.MOUSE_DRAGGED) {
        // Cocoa dragged event has the information about which mouse
        // button is being dragged. Use it to determine the peer that
        // should receive the dragged event.
        targetPeer = mouseDownTarget[targetIdx];
        mouseClickButtons &= ~modifiers;
      } else if (id == MouseEvent.MOUSE_RELEASED) {
        // TODO: currently, mouse released event goes to the same component
        // that received corresponding mouse pressed event. For most cases,
        // it's OK, however, we need to make sure that our behavior is consistent
        // with 1.6 for cases where component in question have been
        // hidden/removed in between of mouse pressed/released events.
        targetPeer = mouseDownTarget[targetIdx];

        if ((modifiers & eventButtonMask) == 0) {
          mouseDownTarget[targetIdx] = null;
        }

        // mouseClickButtons is updated below, after MOUSE_CLICK is sent
      }

      // check if we receive mouseEvent from outside the window's bounds
      // it can be either mouseDragged or mouseReleased
      if (curWindowPeer == null) {
        // TODO This can happen if this window is invisible. this is correct behavior in this case?
        curWindowPeer = this;
      }
      if (targetPeer == null) {
        // TODO This can happen if this window is invisible. this is correct behavior in this case?
        targetPeer = this;
      }

      Point lp = targetPeer.windowToLocal(x, y, curWindowPeer);
      if (targetPeer.isEnabled()) {
        if (id == MouseEvent.MOUSE_ENTERED || id == MouseEvent.MOUSE_EXITED) {
          postMouseEnteredExitedEvent(
              targetPeer.getTarget(),
              id,
              when,
              modifiers,
              lp,
              screenX,
              screenY,
              clickCount,
              popupTrigger,
              button);

        } else {
          MouseEvent event =
              new MouseEvent(
                  targetPeer.getTarget(),
                  id,
                  when,
                  modifiers,
                  lp.x,
                  lp.y,
                  screenX,
                  screenY,
                  clickCount,
                  popupTrigger,
                  button);
          postEvent(event);
        }
      }

      if (id == MouseEvent.MOUSE_RELEASED) {
        if ((mouseClickButtons & eventButtonMask) != 0 && targetPeer.isEnabled()) {
          postEvent(
              new MouseEvent(
                  targetPeer.getTarget(),
                  MouseEvent.MOUSE_CLICKED,
                  when,
                  modifiers,
                  lp.x,
                  lp.y,
                  screenX,
                  screenY,
                  clickCount,
                  popupTrigger,
                  button));
        }
        mouseClickButtons &= ~eventButtonMask;
      }
    }
    notifyUpdateCursor();
  }