public void setResizable(boolean resizable) { int fs = winAttr.functions; if (!isResizable() && resizable) { insets = currentInsets = new Insets(0, 0, 0, 0); resetWMSetInsets(); if (!isEmbedded()) { setReparented(false); } winAttr.isResizable = resizable; if ((fs & MWM_FUNC_ALL) != 0) { fs &= ~(MWM_FUNC_RESIZE | MWM_FUNC_MAXIMIZE); } else { fs |= (MWM_FUNC_RESIZE | MWM_FUNC_MAXIMIZE); } winAttr.functions = fs; XWM.setShellResizable(this); } else if (isResizable() && !resizable) { insets = currentInsets = new Insets(0, 0, 0, 0); resetWMSetInsets(); if (!isEmbedded()) { setReparented(false); } winAttr.isResizable = resizable; if ((fs & MWM_FUNC_ALL) != 0) { fs |= (MWM_FUNC_RESIZE | MWM_FUNC_MAXIMIZE); } else { fs &= ~(MWM_FUNC_RESIZE | MWM_FUNC_MAXIMIZE); } winAttr.functions = fs; XWM.setShellNotResizable(this, dimensions, dimensions.getScreenBounds(), false); } }
private void checkShellRectPos(Rectangle shellRect) { int wm = XWM.getWMID(); if (wm == XWM.MOTIF_WM || wm == XWM.CDE_WM) { if (shellRect.x == 0 && shellRect.y == 0) { shellRect.x = shellRect.y = 1; } } }
void setIconHints(java.util.List<XIconInfo> icons) { if (!XWM.getWM().setNetWMIcon(this, icons)) { if (icons.size() > 0) { if (iconWindow == null) { iconWindow = new XIconWindow(this); } iconWindow.setIconImages(icons); } } }
public void setVisible(boolean vis) { if (log.isLoggable(Level.FINER)) { log.log( Level.FINER, "Setting {0} to visible {1}", new Object[] {String.valueOf(this), Boolean.valueOf(vis)}); } if (vis && !isVisible()) { XWM.setShellDecor(this); super.setVisible(vis); if (winAttr.isResizable) { // Fix for 4320050: Minimum size for java.awt.Frame is not being enforced. // We need to update frame's minimum size, not to reset it XWM.removeSizeHints(this, XlibWrapper.PMaxSize); updateMinimumSize(); } } else { super.setVisible(vis); } }
private void updateMinSizeHints() { if (isResizable()) { Dimension minimumSize = getTargetMinimumSize(); if (minimumSize != null) { Insets insets = getRealInsets(); int minWidth = minimumSize.width - insets.left - insets.right; int minHeight = minimumSize.height - insets.top - insets.bottom; if (minWidth < 0) minWidth = 0; if (minHeight < 0) minHeight = 0; setSizeHints( XlibWrapper.PMinSize | (isLocationByPlatform() ? 0 : (XlibWrapper.PPosition | XlibWrapper.USPosition)), getX(), getY(), minWidth, minHeight); if (isVisible()) { Rectangle bounds = getShellBounds(); int nw = (bounds.width < minWidth) ? minWidth : bounds.width; int nh = (bounds.height < minHeight) ? minHeight : bounds.height; if (nw != bounds.width || nh != bounds.height) { setShellSize(new Rectangle(0, 0, nw, nh)); } } } else { boolean isMinSizeSet = isMinSizeSet(); XWM.removeSizeHints(this, XlibWrapper.PMinSize); /* Some WMs need remap to redecorate the window */ if (isMinSizeSet && isShowing() && XWM.needRemap(this)) { /* * Do the re/mapping at the Xlib level. Since we essentially * work around a WM bug we don't want this hack to be exposed * to Intrinsics (i.e. don't mess with grabs, callbacks etc). */ xSetVisible(false); XToolkit.XSync(); xSetVisible(true); } } } }
protected Insets guessInsets() { if (isEmbedded()) { return new Insets(0, 0, 0, 0); } else { if (currentInsets.top > 0) { /* insets were set on wdata by System Properties */ return copy(currentInsets); } else { Insets res = getWMSetInsets(null); if (res == null) { res = XWM.getWM().guessInsets(this); } return res; } } }
public void handleConfigureNotifyEvent(XEvent xev) { assert (SunToolkit.isAWTLockHeldByCurrentThread()); XConfigureEvent xe = xev.get_xconfigure(); if (insLog.isLoggable(Level.FINE)) { insLog.log(Level.FINE, "Configure notify {0}", new Object[] {String.valueOf(xe)}); } // XXX: should really only consider synthetic events, but if (isReparented()) { configure_seen = true; } if (!isMaximized() && (xe.get_serial() == reparent_serial || xe.get_window() != getShell()) && !no_reparent_artifacts) { insLog.fine("- reparent artifact, skipping"); return; } no_reparent_artifacts = false; /** * When there is a WM we receive some CN before being visible and after. We should skip all CN * which are before being visible, because we assume the gravity is in action while it is not * yet. * * <p>When there is no WM we receive CN only _before_ being visible. We should process these * CNs. */ if (!isVisible() && XWM.getWMID() != XWM.NO_WM) { insLog.fine(" - not visible, skipping"); return; } /* * Some window managers configure before we are reparented and * the send event flag is set! ugh... (Enlighetenment for one, * possibly MWM as well). If we haven't been reparented yet * this is just the WM shuffling us into position. Ignore * it!!!! or we wind up in a bogus location. */ int runningWM = XWM.getWMID(); if (insLog.isLoggable(Level.FINE)) { insLog.log( Level.FINE, "reparented={0}, visible={1}, WM={2}, decorations={3}", new Object[] {isReparented(), isVisible(), runningWM, getDecorations()}); } if (!isReparented() && isVisible() && runningWM != XWM.NO_WM && !XWM.isNonReparentingWM() && getDecorations() != winAttr.AWT_DECOR_NONE) { insLog.fine("- visible but not reparented, skipping"); return; } // Last chance to correct insets if (!insets_corrected && getDecorations() != winAttr.AWT_DECOR_NONE) { long parent = XlibUtil.getParentWindow(window); Insets correctWM = (parent != -1) ? XWM.getWM().getInsets(this, window, parent) : null; if (insLog.isLoggable(Level.FINER)) { if (correctWM != null) { insLog.finer("Configure notify - insets : " + correctWM); } else { insLog.finer("Configure notify - insets are still not available"); } } if (correctWM != null) { handleCorrectInsets(correctWM); } else { // Only one attempt to correct insets is made (to lower risk) // if insets are still not available we simply set the flag insets_corrected = true; } } updateChildrenSizes(); // Bounds of the window Rectangle targetBounds = new Rectangle( ComponentAccessor.getX((Component) target), ComponentAccessor.getY((Component) target), ComponentAccessor.getWidth((Component) target), ComponentAccessor.getHeight((Component) target)); Point newLocation = targetBounds.getLocation(); if (xe.get_send_event() || runningWM == XWM.NO_WM || XWM.isNonReparentingWM()) { // Location, Client size + insets newLocation = new Point(xe.get_x() - currentInsets.left, xe.get_y() - currentInsets.top); } else { // CDE/MWM/Metacity/Sawfish bug: if shell is resized using // top or left border, we don't receive synthetic // ConfigureNotify, only the one from X with zero // coordinates. This is the workaround to get real // location, 6261336 switch (XWM.getWMID()) { case XWM.CDE_WM: case XWM.MOTIF_WM: case XWM.METACITY_WM: case XWM.SAWFISH_WM: { Point xlocation = queryXLocation(); if (log.isLoggable(Level.FINE)) { log.log(Level.FINE, "New X location: {0}", new Object[] {String.valueOf(xlocation)}); } if (xlocation != null) { newLocation = xlocation; } break; } default: break; } } WindowDimensions newDimensions = new WindowDimensions( newLocation, new Dimension(xe.get_width(), xe.get_height()), copy(currentInsets), true); if (insLog.isLoggable(Level.FINER)) { insLog.log( Level.FINER, "Insets are {0}, new dimensions {1}", new Object[] {String.valueOf(currentInsets), String.valueOf(newDimensions)}); } checkIfOnNewScreen(newDimensions.getBounds()); Point oldLocation = getLocation(); dimensions = newDimensions; if (!newLocation.equals(oldLocation)) { handleMoved(newDimensions); } reconfigureContentWindow(newDimensions); updateChildrenSizes(); }
// Coordinates are that of the target // Called only on Toolkit thread public void reshape(WindowDimensions newDimensions, int op, boolean userReshape) { if (insLog.isLoggable(Level.FINE)) { insLog.fine( "Reshaping " + this + " to " + newDimensions + " op " + op + " user reshape " + userReshape); } if (userReshape) { // We handle only userReshape == true cases. It means that // if the window manager or any other part of the windowing // system sets inappropriate size for this window, we can // do nothing but accept it. Rectangle reqBounds = newDimensions.getBounds(); Rectangle newBounds = constrainBounds(reqBounds.x, reqBounds.y, reqBounds.width, reqBounds.height); Insets insets = newDimensions.getInsets(); Rectangle clientBounds = new Rectangle( newBounds.x, newBounds.y, newBounds.width - insets.left - insets.right, newBounds.height - insets.top - insets.bottom); newDimensions = new WindowDimensions( newDimensions.isClientSizeSet() ? clientBounds : newBounds, insets, newDimensions.isClientSizeSet()); } XToolkit.awtLock(); try { if (!isReparented() || !isVisible()) { insLog.log( Level.FINE, "- not reparented({0}) or not visible({1}), default reshape", new Object[] {Boolean.valueOf(isReparented()), Boolean.valueOf(visible)}); // Fix for 6323293. // This actually is needed to preserve compatibility with previous releases - // some of licensees are expecting componentMoved event on invisible one while // its location changes. Point oldLocation = getLocation(); Point newLocation = new Point( ComponentAccessor.getX((Component) target), ComponentAccessor.getY((Component) target)); if (!newLocation.equals(oldLocation)) { handleMoved(newDimensions); } dimensions = new WindowDimensions(newDimensions); updateSizeHints(dimensions); Rectangle client = dimensions.getClientRect(); checkShellRect(client); setShellBounds(client); if (content != null && !content.getSize().equals(newDimensions.getSize())) { reconfigureContentWindow(newDimensions); } return; } int wm = XWM.getWMID(); updateChildrenSizes(); applyGuessedInsets(); Rectangle shellRect = newDimensions.getClientRect(); if (gravityBug()) { Insets in = newDimensions.getInsets(); shellRect.translate(in.left, in.top); } if ((op & NO_EMBEDDED_CHECK) == 0 && isEmbedded()) { shellRect.setLocation(0, 0); } checkShellRectSize(shellRect); if (!isEmbedded()) { checkShellRectPos(shellRect); } op = op & ~NO_EMBEDDED_CHECK; if (op == SET_LOCATION) { setShellPosition(shellRect); } else if (isResizable()) { if (op == SET_BOUNDS) { setShellBounds(shellRect); } else { setShellSize(shellRect); } } else { XWM.setShellNotResizable(this, newDimensions, shellRect, true); if (op == SET_BOUNDS) { setShellPosition(shellRect); } } reconfigureContentWindow(newDimensions); } finally { XToolkit.awtUnlock(); } }
boolean gravityBug() { return XWM.configureGravityBuggy(); }
public void handleReparentNotifyEvent(XEvent xev) { XReparentEvent xe = xev.get_xreparent(); if (insLog.isLoggable(Level.FINE)) insLog.fine(xe.toString()); reparent_serial = xe.get_serial(); XToolkit.awtLock(); try { long root = XlibWrapper.RootWindow(XToolkit.getDisplay(), getScreenNumber()); if (isEmbedded()) { setReparented(true); insets_corrected = true; return; } Component t = (Component) target; if (getDecorations() == winAttr.AWT_DECOR_NONE) { setReparented(true); insets_corrected = true; reshape(dimensions, SET_SIZE, false); } else if (xe.get_parent() == root) { configure_seen = false; insets_corrected = false; /* * We can be repareted to root for two reasons: * . setVisible(false) * . WM exited */ if (isVisible()) { /* WM exited */ /* Work around 4775545 */ XWM.getWM().unshadeKludge(this); insLog.fine("- WM exited"); } else { insLog.fine(" - reparent due to hide"); } } else { /* reparented to WM frame, figure out our insets */ setReparented(true); insets_corrected = false; // Check if we have insets provided by the WM Insets correctWM = getWMSetInsets(null); if (correctWM != null) { if (insLog.isLoggable(Level.FINER)) { insLog.log( Level.FINER, "wm-provided insets {0}", new Object[] {String.valueOf(correctWM)}); } // If these insets are equal to our current insets - no actions are necessary Insets dimInsets = dimensions.getInsets(); if (correctWM.equals(dimInsets)) { insLog.finer("Insets are the same as estimated - no additional reshapes necessary"); no_reparent_artifacts = true; insets_corrected = true; applyGuessedInsets(); return; } } else { correctWM = XWM.getWM().getInsets(this, xe.get_window(), xe.get_parent()); if (correctWM != null) { if (insLog.isLoggable(Level.FINER)) { insLog.log(Level.FINER, "correctWM {0}", new Object[] {String.valueOf(correctWM)}); } } else { insLog.log( Level.FINER, "correctWM insets are not available, waiting for configureNotify"); } } if (correctWM != null) { handleCorrectInsets(correctWM); } } } finally { XToolkit.awtUnlock(); } }
/** * We should always grab both keyboard and pointer to control event flow on popups. This also * simplifies synthetic grab implementation. The active grab overrides activated automatic grab. */ public boolean grabInput() { if (grabLog.isLoggable(Level.FINE)) { grabLog.log(Level.FINE, "Grab input on {0}", new Object[] {String.valueOf(this)}); } XToolkit.awtLock(); try { if (XAwtState.getGrabWindow() == this && XAwtState.isManualGrab()) { grabLog.fine(" Already Grabbed"); return true; } // 6273031: PIT. Choice drop down does not close once it is right clicked to show a popup menu // remember previous window having grab and if it's not null ungrab it. XBaseWindow prevGrabWindow = XAwtState.getGrabWindow(); final int eventMask = (int) (ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | ButtonMotionMask); final int ownerEvents = 1; int ptrGrab = XlibWrapper.XGrabPointer( XToolkit.getDisplay(), getContentWindow(), ownerEvents, eventMask, GrabModeAsync, GrabModeAsync, None, (XWM.isMotif() ? XToolkit.arrowCursor : None), CurrentTime); // Check grab results to be consistent with X server grab if (ptrGrab != GrabSuccess) { XlibWrapper.XUngrabPointer(XToolkit.getDisplay(), CurrentTime); XAwtState.setGrabWindow(null); grabLog.fine(" Grab Failure - mouse"); return false; } int keyGrab = XlibWrapper.XGrabKeyboard( XToolkit.getDisplay(), getContentWindow(), ownerEvents, GrabModeAsync, GrabModeAsync, CurrentTime); if (keyGrab != GrabSuccess) { XlibWrapper.XUngrabPointer(XToolkit.getDisplay(), CurrentTime); XlibWrapper.XUngrabKeyboard(XToolkit.getDisplay(), CurrentTime); XAwtState.setGrabWindow(null); grabLog.fine(" Grab Failure - keyboard"); return false; } if (prevGrabWindow != null) { prevGrabWindow.ungrabInputImpl(); } XAwtState.setGrabWindow(this); grabLog.fine(" Grab - success"); return true; } finally { XToolkit.awtUnlock(); } }