0001: /*******************************************************************************
0002: * Copyright (c) 2000, 2007 IBM Corporation and others.
0003: * All rights reserved. This program and the accompanying materials
0004: * are made available under the terms of the Eclipse Public License v1.0
0005: * which accompanies this distribution, and is available at
0006: * http://www.eclipse.org/legal/epl-v10.html
0007: *
0008: * Contributors:
0009: * IBM Corporation - initial API and implementation
0010: *******************************************************************************/package org.eclipse.swt.widgets;
0011:
0012: import org.eclipse.swt.internal.carbon.OS;
0013: import org.eclipse.swt.internal.carbon.Rect;
0014: import org.eclipse.swt.internal.carbon.CGPoint;
0015: import org.eclipse.swt.internal.carbon.CGRect;
0016:
0017: import org.eclipse.swt.SWT;
0018: import org.eclipse.swt.events.*;
0019: import org.eclipse.swt.graphics.*;
0020:
0021: /**
0022: * Instances of this class represent the "windows"
0023: * which the desktop or "window manager" is managing.
0024: * Instances that do not have a parent (that is, they
0025: * are built using the constructor, which takes a
0026: * <code>Display</code> as the argument) are described
0027: * as <em>top level</em> shells. Instances that do have
0028: * a parent are described as <em>secondary</em> or
0029: * <em>dialog</em> shells.
0030: * <p>
0031: * Instances are always displayed in one of the maximized,
0032: * minimized or normal states:
0033: * <ul>
0034: * <li>
0035: * When an instance is marked as <em>maximized</em>, the
0036: * window manager will typically resize it to fill the
0037: * entire visible area of the display, and the instance
0038: * is usually put in a state where it can not be resized
0039: * (even if it has style <code>RESIZE</code>) until it is
0040: * no longer maximized.
0041: * </li><li>
0042: * When an instance is in the <em>normal</em> state (neither
0043: * maximized or minimized), its appearance is controlled by
0044: * the style constants which were specified when it was created
0045: * and the restrictions of the window manager (see below).
0046: * </li><li>
0047: * When an instance has been marked as <em>minimized</em>,
0048: * its contents (client area) will usually not be visible,
0049: * and depending on the window manager, it may be
0050: * "iconified" (that is, replaced on the desktop by a small
0051: * simplified representation of itself), relocated to a
0052: * distinguished area of the screen, or hidden. Combinations
0053: * of these changes are also possible.
0054: * </li>
0055: * </ul>
0056: * </p><p>
0057: * The <em>modality</em> of an instance may be specified using
0058: * style bits. The modality style bits are used to determine
0059: * whether input is blocked for other shells on the display.
0060: * The <code>PRIMARY_MODAL</code> style allows an instance to block
0061: * input to its parent. The <code>APPLICATION_MODAL</code> style
0062: * allows an instance to block input to every other shell in the
0063: * display. The <code>SYSTEM_MODAL</code> style allows an instance
0064: * to block input to all shells, including shells belonging to
0065: * different applications.
0066: * </p><p>
0067: * Note: The styles supported by this class are treated
0068: * as <em>HINT</em>s, since the window manager for the
0069: * desktop on which the instance is visible has ultimate
0070: * control over the appearance and behavior of decorations
0071: * and modality. For example, some window managers only
0072: * support resizable windows and will always assume the
0073: * RESIZE style, even if it is not set. In addition, if a
0074: * modality style is not supported, it is "upgraded" to a
0075: * more restrictive modality style that is supported. For
0076: * example, if <code>PRIMARY_MODAL</code> is not supported,
0077: * it would be upgraded to <code>APPLICATION_MODAL</code>.
0078: * A modality style may also be "downgraded" to a less
0079: * restrictive style. For example, most operating systems
0080: * no longer support <code>SYSTEM_MODAL</code> because
0081: * it can freeze up the desktop, so this is typically
0082: * downgraded to <code>APPLICATION_MODAL</code>.
0083: * <dl>
0084: * <dt><b>Styles:</b></dt>
0085: * <dd>BORDER, CLOSE, MIN, MAX, NO_TRIM, RESIZE, TITLE, ON_TOP, TOOL</dd>
0086: * <dd>APPLICATION_MODAL, MODELESS, PRIMARY_MODAL, SYSTEM_MODAL</dd>
0087: * <dt><b>Events:</b></dt>
0088: * <dd>Activate, Close, Deactivate, Deiconify, Iconify</dd>
0089: * </dl>
0090: * Class <code>SWT</code> provides two "convenience constants"
0091: * for the most commonly required style combinations:
0092: * <dl>
0093: * <dt><code>SHELL_TRIM</code></dt>
0094: * <dd>
0095: * the result of combining the constants which are required
0096: * to produce a typical application top level shell: (that
0097: * is, <code>CLOSE | TITLE | MIN | MAX | RESIZE</code>)
0098: * </dd>
0099: * <dt><code>DIALOG_TRIM</code></dt>
0100: * <dd>
0101: * the result of combining the constants which are required
0102: * to produce a typical application dialog shell: (that
0103: * is, <code>TITLE | CLOSE | BORDER</code>)
0104: * </dd>
0105: * </dl>
0106: * </p>
0107: * <p>
0108: * Note: Only one of the styles APPLICATION_MODAL, MODELESS,
0109: * PRIMARY_MODAL and SYSTEM_MODAL may be specified.
0110: * </p><p>
0111: * IMPORTANT: This class is not intended to be subclassed.
0112: * </p>
0113: *
0114: * @see Decorations
0115: * @see SWT
0116: */
0117: public class Shell extends Decorations {
0118: int shellHandle, windowGroup;
0119: boolean resized, moved, drawing, reshape, update, deferDispose,
0120: active, disposed, opened, fullScreen;
0121: int invalRgn;
0122: Control lastActive;
0123: Region region;
0124: Rect rgnRect;
0125: Rectangle normalBounds;
0126: int imHandle;
0127:
0128: static int DEFAULT_CLIENT_WIDTH = -1;
0129: static int DEFAULT_CLIENT_HEIGHT = -1;
0130:
0131: /**
0132: * Constructs a new instance of this class. This is equivalent
0133: * to calling <code>Shell((Display) null)</code>.
0134: *
0135: * @exception SWTException <ul>
0136: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
0137: * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
0138: * </ul>
0139: */
0140: public Shell() {
0141: this ((Display) null);
0142: }
0143:
0144: /**
0145: * Constructs a new instance of this class given only the style
0146: * value describing its behavior and appearance. This is equivalent
0147: * to calling <code>Shell((Display) null, style)</code>.
0148: * <p>
0149: * The style value is either one of the style constants defined in
0150: * class <code>SWT</code> which is applicable to instances of this
0151: * class, or must be built by <em>bitwise OR</em>'ing together
0152: * (that is, using the <code>int</code> "|" operator) two or more
0153: * of those <code>SWT</code> style constants. The class description
0154: * lists the style constants that are applicable to the class.
0155: * Style bits are also inherited from superclasses.
0156: * </p>
0157: *
0158: * @param style the style of control to construct
0159: *
0160: * @exception SWTException <ul>
0161: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
0162: * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
0163: * </ul>
0164: *
0165: * @see SWT#BORDER
0166: * @see SWT#CLOSE
0167: * @see SWT#MIN
0168: * @see SWT#MAX
0169: * @see SWT#RESIZE
0170: * @see SWT#TITLE
0171: * @see SWT#NO_TRIM
0172: * @see SWT#SHELL_TRIM
0173: * @see SWT#DIALOG_TRIM
0174: * @see SWT#MODELESS
0175: * @see SWT#PRIMARY_MODAL
0176: * @see SWT#APPLICATION_MODAL
0177: * @see SWT#SYSTEM_MODAL
0178: */
0179: public Shell(int style) {
0180: this ((Display) null, style);
0181: }
0182:
0183: /**
0184: * Constructs a new instance of this class given only the display
0185: * to create it on. It is created with style <code>SWT.SHELL_TRIM</code>.
0186: * <p>
0187: * Note: Currently, null can be passed in for the display argument.
0188: * This has the effect of creating the shell on the currently active
0189: * display if there is one. If there is no current display, the
0190: * shell is created on a "default" display. <b>Passing in null as
0191: * the display argument is not considered to be good coding style,
0192: * and may not be supported in a future release of SWT.</b>
0193: * </p>
0194: *
0195: * @param display the display to create the shell on
0196: *
0197: * @exception SWTException <ul>
0198: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
0199: * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
0200: * </ul>
0201: */
0202: public Shell(Display display) {
0203: this (display, SWT.SHELL_TRIM);
0204: }
0205:
0206: /**
0207: * Constructs a new instance of this class given the display
0208: * to create it on and a style value describing its behavior
0209: * and appearance.
0210: * <p>
0211: * The style value is either one of the style constants defined in
0212: * class <code>SWT</code> which is applicable to instances of this
0213: * class, or must be built by <em>bitwise OR</em>'ing together
0214: * (that is, using the <code>int</code> "|" operator) two or more
0215: * of those <code>SWT</code> style constants. The class description
0216: * lists the style constants that are applicable to the class.
0217: * Style bits are also inherited from superclasses.
0218: * </p><p>
0219: * Note: Currently, null can be passed in for the display argument.
0220: * This has the effect of creating the shell on the currently active
0221: * display if there is one. If there is no current display, the
0222: * shell is created on a "default" display. <b>Passing in null as
0223: * the display argument is not considered to be good coding style,
0224: * and may not be supported in a future release of SWT.</b>
0225: * </p>
0226: *
0227: * @param display the display to create the shell on
0228: * @param style the style of control to construct
0229: *
0230: * @exception SWTException <ul>
0231: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
0232: * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
0233: * </ul>
0234: *
0235: * @see SWT#BORDER
0236: * @see SWT#CLOSE
0237: * @see SWT#MIN
0238: * @see SWT#MAX
0239: * @see SWT#RESIZE
0240: * @see SWT#TITLE
0241: * @see SWT#NO_TRIM
0242: * @see SWT#SHELL_TRIM
0243: * @see SWT#DIALOG_TRIM
0244: * @see SWT#MODELESS
0245: * @see SWT#PRIMARY_MODAL
0246: * @see SWT#APPLICATION_MODAL
0247: * @see SWT#SYSTEM_MODAL
0248: */
0249: public Shell(Display display, int style) {
0250: this (display, null, style, 0, false);
0251: }
0252:
0253: Shell(Display display, Shell parent, int style, int handle,
0254: boolean embedded) {
0255: super ();
0256: checkSubclass();
0257: if (display == null)
0258: display = Display.getCurrent();
0259: if (display == null)
0260: display = Display.getDefault();
0261: if (!display.isValidThread()) {
0262: error(SWT.ERROR_THREAD_INVALID_ACCESS);
0263: }
0264: if (parent != null && parent.isDisposed()) {
0265: error(SWT.ERROR_INVALID_ARGUMENT);
0266: }
0267: this .style = checkStyle(style);
0268: this .parent = parent;
0269: this .display = display;
0270: if (handle != 0) {
0271: if (embedded) {
0272: this .handle = handle;
0273: } else {
0274: shellHandle = handle;
0275: state |= FOREIGN_HANDLE;
0276: }
0277: }
0278: createWidget();
0279: }
0280:
0281: /**
0282: * Constructs a new instance of this class given only its
0283: * parent. It is created with style <code>SWT.DIALOG_TRIM</code>.
0284: * <p>
0285: * Note: Currently, null can be passed in for the parent.
0286: * This has the effect of creating the shell on the currently active
0287: * display if there is one. If there is no current display, the
0288: * shell is created on a "default" display. <b>Passing in null as
0289: * the parent is not considered to be good coding style,
0290: * and may not be supported in a future release of SWT.</b>
0291: * </p>
0292: *
0293: * @param parent a shell which will be the parent of the new instance
0294: *
0295: * @exception IllegalArgumentException <ul>
0296: * <li>ERROR_INVALID_ARGUMENT - if the parent is disposed</li>
0297: * </ul>
0298: * @exception SWTException <ul>
0299: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
0300: * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
0301: * </ul>
0302: */
0303: public Shell(Shell parent) {
0304: this (parent, SWT.DIALOG_TRIM);
0305: }
0306:
0307: /**
0308: * Constructs a new instance of this class given its parent
0309: * and a style value describing its behavior and appearance.
0310: * <p>
0311: * The style value is either one of the style constants defined in
0312: * class <code>SWT</code> which is applicable to instances of this
0313: * class, or must be built by <em>bitwise OR</em>'ing together
0314: * (that is, using the <code>int</code> "|" operator) two or more
0315: * of those <code>SWT</code> style constants. The class description
0316: * lists the style constants that are applicable to the class.
0317: * Style bits are also inherited from superclasses.
0318: * </p><p>
0319: * Note: Currently, null can be passed in for the parent.
0320: * This has the effect of creating the shell on the currently active
0321: * display if there is one. If there is no current display, the
0322: * shell is created on a "default" display. <b>Passing in null as
0323: * the parent is not considered to be good coding style,
0324: * and may not be supported in a future release of SWT.</b>
0325: * </p>
0326: *
0327: * @param parent a shell which will be the parent of the new instance
0328: * @param style the style of control to construct
0329: *
0330: * @exception IllegalArgumentException <ul>
0331: * <li>ERROR_INVALID_ARGUMENT - if the parent is disposed</li>
0332: * </ul>
0333: * @exception SWTException <ul>
0334: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
0335: * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
0336: * </ul>
0337: *
0338: * @see SWT#BORDER
0339: * @see SWT#CLOSE
0340: * @see SWT#MIN
0341: * @see SWT#MAX
0342: * @see SWT#RESIZE
0343: * @see SWT#TITLE
0344: * @see SWT#NO_TRIM
0345: * @see SWT#SHELL_TRIM
0346: * @see SWT#DIALOG_TRIM
0347: * @see SWT#ON_TOP
0348: * @see SWT#TOOL
0349: * @see SWT#MODELESS
0350: * @see SWT#PRIMARY_MODAL
0351: * @see SWT#APPLICATION_MODAL
0352: * @see SWT#SYSTEM_MODAL
0353: */
0354: public Shell(Shell parent, int style) {
0355: this (parent != null ? parent.display : null, parent, style, 0,
0356: false);
0357: }
0358:
0359: public static Shell internal_new(Display display, int handle) {
0360: return new Shell(display, null, SWT.NO_TRIM, handle, false);
0361: }
0362:
0363: static int checkStyle(int style) {
0364: style = Decorations.checkStyle(style);
0365: int mask = SWT.SYSTEM_MODAL | SWT.APPLICATION_MODAL
0366: | SWT.PRIMARY_MODAL;
0367: int bits = style & ~mask;
0368: if ((style & SWT.SYSTEM_MODAL) != 0)
0369: return bits | SWT.SYSTEM_MODAL;
0370: if ((style & SWT.APPLICATION_MODAL) != 0)
0371: return bits | SWT.APPLICATION_MODAL;
0372: if ((style & SWT.PRIMARY_MODAL) != 0)
0373: return bits | SWT.PRIMARY_MODAL;
0374: return bits;
0375: }
0376:
0377: /**
0378: * Adds the listener to the collection of listeners who will
0379: * be notified when operations are performed on the receiver,
0380: * by sending the listener one of the messages defined in the
0381: * <code>ShellListener</code> interface.
0382: *
0383: * @param listener the listener which should be notified
0384: *
0385: * @exception IllegalArgumentException <ul>
0386: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
0387: * </ul>
0388: * @exception SWTException <ul>
0389: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0390: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0391: * </ul>
0392: *
0393: * @see ShellListener
0394: * @see #removeShellListener
0395: */
0396: public void addShellListener(ShellListener listener) {
0397: checkWidget();
0398: if (listener == null)
0399: error(SWT.ERROR_NULL_ARGUMENT);
0400: TypedListener typedListener = new TypedListener(listener);
0401: addListener(SWT.Activate, typedListener);
0402: addListener(SWT.Close, typedListener);
0403: addListener(SWT.Deactivate, typedListener);
0404: addListener(SWT.Iconify, typedListener);
0405: addListener(SWT.Deiconify, typedListener);
0406: }
0407:
0408: void bringToTop(boolean force) {
0409: if (getMinimized())
0410: return;
0411: if (force) {
0412: forceActive();
0413: } else {
0414: setActive();
0415: }
0416: }
0417:
0418: void checkOpen() {
0419: if (!opened)
0420: resized = false;
0421: }
0422:
0423: /**
0424: * Requests that the window manager close the receiver in
0425: * the same way it would be closed when the user clicks on
0426: * the "close box" or performs some other platform specific
0427: * key or mouse combination that indicates the window
0428: * should be removed.
0429: *
0430: * @exception SWTException <ul>
0431: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0432: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0433: * </ul>
0434: *
0435: * @see SWT#Close
0436: * @see #dispose
0437: */
0438: public void close() {
0439: checkWidget();
0440: closeWidget();
0441: }
0442:
0443: void closeWidget() {
0444: Event event = new Event();
0445: sendEvent(SWT.Close, event);
0446: if (event.doit && !isDisposed())
0447: dispose();
0448: }
0449:
0450: public Rectangle computeTrim(int x, int y, int width, int height) {
0451: checkWidget();
0452: Rectangle trim = super .computeTrim(x, y, width, height);
0453: Rect rect = new Rect();
0454: OS.GetWindowStructureWidths(shellHandle, rect);
0455: trim.x -= rect.left;
0456: trim.y -= rect.top;
0457: trim.width += rect.left + rect.right;
0458: trim.height += rect.top + rect.bottom;
0459: return trim;
0460: }
0461:
0462: void createHandle() {
0463: state |= CANVAS | GRAB | HIDDEN;
0464: int attributes = OS.kWindowStandardHandlerAttribute;
0465: attributes |= OS.kWindowCompositingAttribute;
0466: if ((style & SWT.NO_TRIM) == 0) {
0467: if ((style & SWT.CLOSE) != 0)
0468: attributes |= OS.kWindowCloseBoxAttribute;
0469: if ((style & SWT.MIN) != 0)
0470: attributes |= OS.kWindowCollapseBoxAttribute;
0471: if ((style & SWT.MAX) != 0)
0472: attributes |= OS.kWindowFullZoomAttribute;
0473: if ((style & SWT.RESIZE) != 0) {
0474: attributes |= OS.kWindowResizableAttribute;
0475: /*
0476: * Bug in the Macintosh. For some reason, a window has no title bar
0477: * and the kWindowResizableAttribute, no rubber banding feedback is
0478: * given while the window is resizing. The fix is to create the window
0479: * with kWindowLiveResizeAttribute in this case. This is inconsistent
0480: * with other windows, but the user will get feedback when resizing.
0481: */
0482: if ((style & SWT.TITLE) == 0)
0483: attributes |= OS.kWindowLiveResizeAttribute;
0484: if (!OS.__BIG_ENDIAN__())
0485: attributes |= OS.kWindowLiveResizeAttribute;
0486: }
0487: }
0488: int windowClass = OS.kDocumentWindowClass;
0489: if ((style & (SWT.CLOSE | SWT.TITLE)) == 0)
0490: windowClass = OS.kSheetWindowClass;
0491: if ((style & (SWT.APPLICATION_MODAL | SWT.PRIMARY_MODAL | SWT.SYSTEM_MODAL)) != 0) {
0492: if ((style & (SWT.CLOSE | SWT.MAX | SWT.MIN)) == 0) {
0493: windowClass = (style & SWT.TITLE) != 0 ? OS.kMovableModalWindowClass
0494: : OS.kModalWindowClass;
0495: }
0496: }
0497: if (shellHandle == 0) {
0498: Monitor monitor = getMonitor();
0499: Rectangle rect = monitor.getClientArea();
0500: int width = rect.width * 5 / 8;
0501: int height = rect.height * 5 / 8;
0502: Rect bounds = new Rect();
0503: OS.SetRect(bounds, (short) 0, (short) 0, (short) width,
0504: (short) height);
0505: int[] outWindow = new int[1];
0506: attributes &= OS.GetAvailableWindowAttributes(windowClass);
0507: OS.CreateNewWindow(windowClass, attributes, bounds,
0508: outWindow);
0509: if (outWindow[0] == 0)
0510: error(SWT.ERROR_NO_HANDLES);
0511: shellHandle = outWindow[0];
0512: OS.RepositionWindow(shellHandle, 0,
0513: OS.kWindowCascadeOnMainScreen);
0514: // OS.SetThemeWindowBackground (shellHandle, (short) OS.kThemeBrushDialogBackgroundActive, false);
0515: int[] theRoot = new int[1];
0516: OS.HIViewFindByID(OS.HIViewGetRoot(shellHandle), OS
0517: .kHIViewWindowContentID(), theRoot);
0518: /*
0519: * Bug in the Macintosh. When the window class is kMovableModalWindowClass or
0520: * kModalWindowClass, HIViewFindByID() fails to find the control identified by
0521: * kHIViewWindowContentID. The fix is to call GetRootControl() if the call
0522: * failed.
0523: */
0524: if (theRoot[0] == 0)
0525: OS.GetRootControl(shellHandle, theRoot);
0526: if (theRoot[0] == 0)
0527: error(SWT.ERROR_NO_HANDLES);
0528: if ((style & (SWT.H_SCROLL | SWT.V_SCROLL)) != 0) {
0529: createScrolledHandle(theRoot[0]);
0530: } else {
0531: createHandle(theRoot[0]);
0532: }
0533: OS.SetControlVisibility(topHandle(), false, false);
0534: } else {
0535: int[] theRoot = new int[1];
0536: OS.HIViewFindByID(shellHandle, OS.kHIViewWindowContentID(),
0537: theRoot);
0538: if (theRoot[0] == 0)
0539: OS.GetRootControl(shellHandle, theRoot);
0540: handle = OS.HIViewGetFirstSubview(theRoot[0]);
0541: if (handle == 0)
0542: error(SWT.ERROR_NO_HANDLES);
0543: if (OS.IsWindowVisible(shellHandle))
0544: state &= ~HIDDEN;
0545: }
0546: int[] outGroup = new int[1];
0547: OS.CreateWindowGroup(OS.kWindowGroupAttrHideOnCollapse,
0548: outGroup);
0549: if (outGroup[0] == 0)
0550: error(SWT.ERROR_NO_HANDLES);
0551: windowGroup = outGroup[0];
0552: int parentGroup;
0553: if ((style & SWT.ON_TOP) != 0) {
0554: parentGroup = OS
0555: .GetWindowGroupOfClass(OS.kFloatingWindowClass);
0556: } else {
0557: if (parent != null) {
0558: parentGroup = parent.getShell().windowGroup;
0559: } else {
0560: parentGroup = OS.GetWindowGroupOfClass(windowClass);
0561: }
0562: }
0563: OS.SetWindowGroup(shellHandle, parentGroup);
0564: OS.SetWindowGroupParent(windowGroup, parentGroup);
0565: OS.SetWindowGroupOwner(windowGroup, shellHandle);
0566: CGPoint inMinLimits = new CGPoint(), inMaxLimits = new CGPoint();
0567: OS.GetWindowResizeLimits(shellHandle, inMinLimits, inMaxLimits);
0568: if (DEFAULT_CLIENT_WIDTH == -1)
0569: DEFAULT_CLIENT_WIDTH = (int) inMinLimits.x;
0570: if (DEFAULT_CLIENT_HEIGHT == -1)
0571: DEFAULT_CLIENT_HEIGHT = 0;
0572: inMinLimits.y = (int) 0;
0573: int trim = SWT.TITLE | SWT.CLOSE | SWT.MIN | SWT.MAX;
0574: if ((style & SWT.NO_TRIM) != 0 || (style & trim) == 0) {
0575: inMinLimits.x = (int) 0;
0576: }
0577: OS.SetWindowResizeLimits(shellHandle, inMinLimits, inMaxLimits);
0578: int[] docID = new int[1];
0579: OS.NewTSMDocument((short) 1, new int[] { OS.kUnicodeDocument },
0580: docID, 0);
0581: if (docID[0] == 0)
0582: error(SWT.ERROR_NO_HANDLES);
0583: imHandle = docID[0];
0584: }
0585:
0586: void createWidget() {
0587: super .createWidget();
0588: resizeBounds();
0589: }
0590:
0591: void deregister() {
0592: super .deregister();
0593: int[] theRoot = new int[1];
0594: OS.GetRootControl(shellHandle, theRoot);
0595: display.removeWidget(theRoot[0]);
0596: }
0597:
0598: void destroyWidget() {
0599: int theWindow = shellHandle;
0600: /*
0601: * Bug in the Macintosh. Under certain circumstances, yet to
0602: * be determined, calling HideWindow() and then DisposeWindow()
0603: * causes a segment fault when an application is exiting. This
0604: * seems to happen to large applications. The fix is to avoid
0605: * calling HideWindow() when a shell is about to be disposed.
0606: *
0607: * Bug in the Macintosh. Disposing a window from kEventWindowDeactivated
0608: * causes a segment fault. The fix is to defer disposing the window until
0609: * the event loop becomes idle.
0610: */
0611: Display display = this .display;
0612: Composite parent = this .parent;
0613: while (!deferDispose && parent != null) {
0614: Shell shell = parent.getShell();
0615: deferDispose = shell.deferDispose;
0616: parent = shell.parent;
0617: }
0618: if (deferDispose)
0619: OS.HideWindow(shellHandle);
0620: releaseHandle();
0621: if (theWindow != 0) {
0622: if (deferDispose) {
0623: display.addDisposeWindow(theWindow);
0624: } else {
0625: OS.DisposeWindow(theWindow);
0626: }
0627: }
0628: }
0629:
0630: void drawWidget(int control, int context, int damageRgn,
0631: int visibleRgn, int theEvent) {
0632: super .drawWidget(control, context, damageRgn, visibleRgn,
0633: theEvent);
0634:
0635: /*
0636: * Bug in the Macintosh. In kEventWindowGetRegion,
0637: * Carbon assumes the origin of the Region is (0, 0)
0638: * and ignores the actual origin. This causes the
0639: * window to be shifted for a non zero origin. Also,
0640: * the size of the window is the size of the region
0641: * which may be less then the size specified in
0642: * setSize or setBounds.
0643: * The fix is to include (0, 0) and the bottom
0644: * right corner of the size in the region and to
0645: * make these points transparent.
0646: */
0647: if (region == null || region.isDisposed())
0648: return;
0649: boolean origin = region.contains(0, 0);
0650: boolean limit = region.contains(rgnRect.right - 1,
0651: rgnRect.bottom - 1);
0652: if (origin && limit)
0653: return;
0654:
0655: CGRect cgRect = new CGRect();
0656: cgRect.width = 1;
0657: cgRect.height = 1;
0658: if (!origin) {
0659: OS.CGContextClearRect(context, cgRect);
0660: }
0661: if (!limit) {
0662: cgRect.x = rgnRect.right - 1;
0663: cgRect.y = rgnRect.bottom - 1;
0664: OS.CGContextClearRect(context, cgRect);
0665: }
0666: OS.CGContextSynchronize(context);
0667: }
0668:
0669: Control findBackgroundControl() {
0670: return background != null || backgroundImage != null ? this
0671: : null;
0672: }
0673:
0674: Composite findDeferredControl() {
0675: return layoutCount > 0 ? this : null;
0676: }
0677:
0678: Cursor findCursor() {
0679: return cursor;
0680: }
0681:
0682: void fixShell(Shell newShell, Control control) {
0683: if (this == newShell)
0684: return;
0685: if (control == lastActive)
0686: setActiveControl(null);
0687: }
0688:
0689: /**
0690: * If the receiver is visible, moves it to the top of the
0691: * drawing order for the display on which it was created
0692: * (so that all other shells on that display, which are not
0693: * the receiver's children will be drawn behind it) and forces
0694: * the window manager to make the shell active.
0695: *
0696: * @exception SWTException <ul>
0697: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0698: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0699: * </ul>
0700: *
0701: * @since 2.0
0702: * @see Control#moveAbove
0703: * @see Control#setFocus
0704: * @see Control#setVisible
0705: * @see Display#getActiveShell
0706: * @see Decorations#setDefaultButton(Button)
0707: * @see Shell#open
0708: * @see Shell#setActive
0709: */
0710: public void forceActive() {
0711: checkWidget();
0712: if (!isVisible())
0713: return;
0714: OS.SelectWindow(shellHandle);
0715: OS.SetFrontProcessWithOptions(
0716: new int[] { 0, OS.kCurrentProcess },
0717: OS.kSetFrontProcessFrontWindowOnly);
0718: }
0719:
0720: public Rectangle getBounds() {
0721: checkWidget();
0722: Rect rect = new Rect();
0723: OS.GetWindowBounds(shellHandle, (short) OS.kWindowStructureRgn,
0724: rect);
0725: return new Rectangle(rect.left, rect.top, rect.right
0726: - rect.left, rect.bottom - rect.top);
0727: }
0728:
0729: int getDrawCount(int control) {
0730: if (!isTrimHandle(control))
0731: return drawCount;
0732: return 0;
0733: }
0734:
0735: public boolean getFullScreen() {
0736: checkWidget();
0737: return fullScreen;
0738: }
0739:
0740: /**
0741: * Returns the receiver's input method editor mode. This
0742: * will be the result of bitwise OR'ing together one or
0743: * more of the following constants defined in class
0744: * <code>SWT</code>:
0745: * <code>NONE</code>, <code>ROMAN</code>, <code>DBCS</code>,
0746: * <code>PHONETIC</code>, <code>NATIVE</code>, <code>ALPHA</code>.
0747: *
0748: * @return the IME mode
0749: *
0750: * @exception SWTException <ul>
0751: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0752: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0753: * </ul>
0754: *
0755: * @see SWT
0756: */
0757: public int getImeInputMode() {
0758: checkWidget();
0759: return SWT.NONE;
0760: }
0761:
0762: public Point getLocation() {
0763: checkWidget();
0764: Rect rect = new Rect();
0765: OS.GetWindowBounds(shellHandle, (short) OS.kWindowStructureRgn,
0766: rect);
0767: return new Point(rect.left, rect.top);
0768: }
0769:
0770: public boolean getMaximized() {
0771: checkWidget();
0772: //NOT DONE
0773: return !fullScreen && super .getMaximized();
0774: }
0775:
0776: public boolean getMinimized() {
0777: checkWidget();
0778: if (!getVisible())
0779: return super .getMinimized();
0780: return OS.IsWindowCollapsed(shellHandle);
0781: }
0782:
0783: /**
0784: * Returns a point describing the minimum receiver's size. The
0785: * x coordinate of the result is the minimum width of the receiver.
0786: * The y coordinate of the result is the minimum height of the
0787: * receiver.
0788: *
0789: * @return the receiver's size
0790: *
0791: * @exception SWTException <ul>
0792: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0793: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0794: * </ul>
0795: *
0796: * @since 3.1
0797: */
0798: public Point getMinimumSize() {
0799: checkWidget();
0800: Rect rect = new Rect();
0801: OS.GetWindowStructureWidths(shellHandle, rect);
0802: CGPoint inMinLimits = new CGPoint(), inMaxLimits = new CGPoint();
0803: OS.GetWindowResizeLimits(shellHandle, inMinLimits, inMaxLimits);
0804: int width = Math.max(1, (int) inMinLimits.x
0805: + (rect.left + rect.right));
0806: int height = Math.max(1, (int) inMinLimits.y
0807: + (rect.top + rect.bottom));
0808: return new Point(width, height);
0809: }
0810:
0811: float[] getParentBackground() {
0812: return null;
0813: }
0814:
0815: /**
0816: * Returns the region that defines the shape of the shell,
0817: * or null if the shell has the default shape.
0818: *
0819: * @return the region that defines the shape of the shell (or null)
0820: *
0821: * @exception SWTException <ul>
0822: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0823: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0824: * </ul>
0825: *
0826: * @since 3.0
0827: *
0828: */
0829: public Region getRegion() {
0830: checkWidget();
0831: return region;
0832: }
0833:
0834: public Shell getShell() {
0835: checkWidget();
0836: return this ;
0837: }
0838:
0839: /**
0840: * Returns an array containing all shells which are
0841: * descendants of the receiver.
0842: * <p>
0843: * @return the dialog shells
0844: *
0845: * @exception SWTException <ul>
0846: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0847: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0848: * </ul>
0849: */
0850: public Shell[] getShells() {
0851: checkWidget();
0852: int count = 0;
0853: Shell[] shells = display.getShells();
0854: for (int i = 0; i < shells.length; i++) {
0855: Control shell = shells[i];
0856: do {
0857: shell = shell.parent;
0858: } while (shell != null && shell != this );
0859: if (shell == this )
0860: count++;
0861: }
0862: int index = 0;
0863: Shell[] result = new Shell[count];
0864: for (int i = 0; i < shells.length; i++) {
0865: Control shell = shells[i];
0866: do {
0867: shell = shell.parent;
0868: } while (shell != null && shell != this );
0869: if (shell == this ) {
0870: result[index++] = shells[i];
0871: }
0872: }
0873: return result;
0874: }
0875:
0876: public Point getSize() {
0877: checkWidget();
0878: Rect rect = new Rect();
0879: OS.GetWindowBounds(shellHandle, (short) OS.kWindowStructureRgn,
0880: rect);
0881: return new Point(rect.right - rect.left, rect.bottom - rect.top);
0882: }
0883:
0884: float getThemeAlpha() {
0885: return 1;
0886: }
0887:
0888: boolean hasBorder() {
0889: return false;
0890: }
0891:
0892: void hookEvents() {
0893: super .hookEvents();
0894: int mouseProc = display.mouseProc;
0895: int windowProc = display.windowProc;
0896: int[] mask1 = new int[] { OS.kEventClassWindow,
0897: OS.kEventWindowActivated, OS.kEventClassWindow,
0898: OS.kEventWindowBoundsChanged, OS.kEventClassWindow,
0899: OS.kEventWindowClose, OS.kEventClassWindow,
0900: OS.kEventWindowCollapsed, OS.kEventClassWindow,
0901: OS.kEventWindowDeactivated, OS.kEventClassWindow,
0902: OS.kEventWindowDrawContent, OS.kEventClassWindow,
0903: OS.kEventWindowExpanded, OS.kEventClassWindow,
0904: OS.kEventWindowGetRegion, OS.kEventClassWindow,
0905: OS.kEventWindowHidden, OS.kEventClassWindow,
0906: OS.kEventWindowHitTest, OS.kEventClassWindow,
0907: OS.kEventWindowShown, OS.kEventClassWindow,
0908: OS.kEventWindowUpdate, OS.kEventClassWindow,
0909: OS.kEventWindowGetClickModality, };
0910: int windowTarget = OS.GetWindowEventTarget(shellHandle);
0911: OS.InstallEventHandler(windowTarget, windowProc,
0912: mask1.length / 2, mask1, shellHandle, null);
0913: int[] mask2 = new int[] {
0914: OS.kEventClassMouse,
0915: OS.kEventMouseDown,
0916: OS.kEventClassMouse,
0917: OS.kEventMouseDragged,
0918: // OS.kEventClassMouse, OS.kEventMouseEntered,
0919: // OS.kEventClassMouse, OS.kEventMouseExited,
0920: OS.kEventClassMouse, OS.kEventMouseMoved,
0921: OS.kEventClassMouse, OS.kEventMouseUp,
0922: OS.kEventClassMouse, OS.kEventMouseWheelMoved, };
0923: OS.InstallEventHandler(windowTarget, mouseProc,
0924: mask2.length / 2, mask2, shellHandle, null);
0925: }
0926:
0927: void invalidateVisibleRegion(int control) {
0928: resetVisibleRegion(control);
0929: invalidateChildrenVisibleRegion(control);
0930: }
0931:
0932: void invalWindowRgn(int window, int rgn) {
0933: display.needsPaint = true;
0934: if (invalRgn == 0)
0935: invalRgn = OS.NewRgn();
0936: OS.UnionRgn(rgn, invalRgn, invalRgn);
0937: }
0938:
0939: public boolean isEnabled() {
0940: checkWidget();
0941: return getEnabled();
0942: }
0943:
0944: boolean isEnabledCursor() {
0945: return true;
0946: }
0947:
0948: public boolean isVisible() {
0949: checkWidget();
0950: return getVisible();
0951: }
0952:
0953: int kEventWindowActivated(int nextHandler, int theEvent,
0954: int userData) {
0955: int result = super .kEventWindowActivated(nextHandler, theEvent,
0956: userData);
0957: if (result == OS.noErr)
0958: return result;
0959: /*
0960: * Bug in the Macintosh. Despite the that a window has scope
0961: * kWindowActivationScopeNone, it gets kEventWindowActivated
0962: * events but does not get kEventWindowDeactivated events. The
0963: * fix is to ignore kEventWindowActivated events.
0964: */
0965: int[] outScope = new int[1];
0966: OS.GetWindowActivationScope(shellHandle, outScope);
0967: if (outScope[0] == OS.kWindowActivationScopeNone)
0968: return result;
0969: if (!active) {
0970: active = true;
0971: deferDispose = true;
0972: Display display = this .display;
0973: display.activeShell = this ;
0974: display.setMenuBar(menuBar);
0975: if (menuBar != null)
0976: OS.DrawMenuBar();
0977: sendEvent(SWT.Activate);
0978: if (!isDisposed()) {
0979: if (!restoreFocus() && !traverseGroup(true))
0980: setFocus();
0981: }
0982: if (!isDisposed()) {
0983: display.activeShell = null;
0984: Shell parentShell = this ;
0985: while (parentShell.parent != null) {
0986: parentShell = (Shell) parentShell.parent;
0987: if (parentShell.fullScreen) {
0988: break;
0989: }
0990: }
0991: if (!parentShell.fullScreen || menuBar != null) {
0992: updateSystemUIMode();
0993: } else {
0994: parentShell.updateSystemUIMode();
0995: }
0996: }
0997: deferDispose = false;
0998: }
0999: return result;
1000: }
1001:
1002: int kEventWindowBoundsChanged(int nextHandler, int theEvent,
1003: int userData) {
1004: int result = super .kEventWindowBoundsChanged(nextHandler,
1005: theEvent, userData);
1006: if (result == OS.noErr)
1007: return result;
1008: int[] attributes = new int[1];
1009: OS.GetEventParameter(theEvent, OS.kEventParamAttributes,
1010: OS.typeUInt32, null, attributes.length * 4, null,
1011: attributes);
1012: if ((attributes[0] & OS.kWindowBoundsChangeOriginChanged) != 0) {
1013: moved = true;
1014: sendEvent(SWT.Move);
1015: if (isDisposed())
1016: return OS.noErr;
1017: }
1018: if ((attributes[0] & OS.kWindowBoundsChangeSizeChanged) != 0) {
1019: resized = true;
1020: resizeBounds();
1021: sendEvent(SWT.Resize);
1022: if (isDisposed())
1023: return OS.noErr;
1024: if (layout != null) {
1025: markLayout(false, false);
1026: updateLayout(false);
1027: }
1028: if (region != null && !region.isDisposed()) {
1029: OS.GetEventParameter(theEvent,
1030: OS.kEventParamCurrentBounds,
1031: OS.typeQDRectangle, null, Rect.sizeof, null,
1032: rgnRect);
1033: OS.SetRect(rgnRect, (short) 0, (short) 0,
1034: (short) (rgnRect.right - rgnRect.left),
1035: (short) (rgnRect.bottom - rgnRect.top));
1036: OS.ReshapeCustomWindow(shellHandle);
1037: }
1038: }
1039: return result;
1040: }
1041:
1042: int kEventWindowClose(int nextHandler, int theEvent, int userData) {
1043: int result = super .kEventWindowClose(nextHandler, theEvent,
1044: userData);
1045: if (result == OS.noErr)
1046: return result;
1047: if (isEnabled())
1048: closeWidget();
1049: return OS.noErr;
1050: }
1051:
1052: int kEventWindowCollapsed(int nextHandler, int theEvent,
1053: int userData) {
1054: int result = super .kEventWindowCollapsed(nextHandler, theEvent,
1055: userData);
1056: if (result == OS.noErr)
1057: return result;
1058: minimized = true;
1059: sendEvent(SWT.Iconify);
1060: return result;
1061: }
1062:
1063: int kEventWindowDeactivated(int nextHandler, int theEvent,
1064: int userData) {
1065: int result = super .kEventWindowDeactivated(nextHandler,
1066: theEvent, userData);
1067: if (result == OS.noErr)
1068: return result;
1069: if (active) {
1070: active = false;
1071: deferDispose = true;
1072: Display display = this .display;
1073: sendEvent(SWT.Deactivate);
1074: if (isDisposed())
1075: return result;
1076: saveFocus();
1077: if (savedFocus != null) {
1078: /*
1079: * Bug in the Macintosh. When ClearKeyboardFocus() is called,
1080: * the control that has focus gets two kEventControlSetFocus
1081: * events indicating that focus was lost. The fix is to ignore
1082: * both of these and send the focus lost event explicitly.
1083: */
1084: display.ignoreFocus = true;
1085: OS.ClearKeyboardFocus(shellHandle);
1086: display.ignoreFocus = false;
1087: if (!savedFocus.isDisposed())
1088: savedFocus.sendFocusEvent(SWT.FocusOut, false);
1089: }
1090: display.setMenuBar(null);
1091: deferDispose = false;
1092: }
1093: return result;
1094: }
1095:
1096: int kEventWindowDrawContent(int nextHandler, int theEvent,
1097: int userData) {
1098: drawing = true;
1099: int result = OS.CallNextEventHandler(nextHandler, theEvent);
1100: drawing = false;
1101: if (reshape) {
1102: reshape = false;
1103: OS.ReshapeCustomWindow(shellHandle);
1104: }
1105: return result;
1106: }
1107:
1108: int kEventWindowExpanded(int nextHandler, int theEvent, int userData) {
1109: int result = super .kEventWindowExpanded(nextHandler, theEvent,
1110: userData);
1111: if (result == OS.noErr)
1112: return result;
1113: minimized = false;
1114: sendEvent(SWT.Deiconify);
1115: return result;
1116: }
1117:
1118: int kEventWindowGetClickModality(int nextHandler, int theEvent,
1119: int userData) {
1120: /*
1121: * Bug in the Macintosh. When the user clicks in an Expose window that is
1122: * disabled because of a modal dialog, the modal dialog does not come to
1123: * front and is obscured by the Expose window. The fix is to select the
1124: * modal dialog.
1125: */
1126: int result = OS.CallNextEventHandler(nextHandler, theEvent);
1127: int[] modal = new int[1];
1128: OS.GetEventParameter(theEvent, OS.kEventParamModalWindow,
1129: OS.typeWindowRef, null, 4, null, modal);
1130: if (modal[0] != 0)
1131: OS.SelectWindow(modal[0]);
1132: return result;
1133: }
1134:
1135: int kEventWindowGetRegion(int nextHandler, int theEvent,
1136: int userData) {
1137: int result = super .kEventWindowGetRegion(nextHandler, theEvent,
1138: userData);
1139: if (result == OS.noErr)
1140: return result;
1141: if (region == null || region.isDisposed())
1142: return OS.eventNotHandledErr;
1143: short[] regionCode = new short[1];
1144: OS.GetEventParameter(theEvent, OS.kEventParamWindowRegionCode,
1145: OS.typeWindowRegionCode, null, 2, null, regionCode);
1146: int[] temp = new int[1];
1147: OS.GetEventParameter(theEvent, OS.kEventParamRgnHandle,
1148: OS.typeQDRgnHandle, null, 4, null, temp);
1149: int hRegion = temp[0];
1150: switch (regionCode[0]) {
1151: case OS.kWindowContentRgn:
1152: case OS.kWindowStructureRgn:
1153: OS.RectRgn(hRegion, rgnRect);
1154: OS.SectRgn(hRegion, region.handle, hRegion);
1155: /*
1156: * Bug in the Macintosh. In kEventWindowGetRegion,
1157: * Carbon assumes the origin of the Region is (0, 0)
1158: * and ignores the actual origin. This causes the
1159: * window to be shifted for a non zero origin. Also,
1160: * the size of the window is the size of the region
1161: * which may be less then the size specified in
1162: * setSize or setBounds.
1163: * The fix is to include (0, 0) and the bottom
1164: * right corner of the size in the region and to
1165: * make these points transparent.
1166: */
1167: if (!region.contains(0, 0)) {
1168: Rect r = new Rect();
1169: OS.SetRect(r, (short) 0, (short) 0, (short) 1,
1170: (short) 1);
1171: int rectRgn = OS.NewRgn();
1172: OS.RectRgn(rectRgn, r);
1173: OS.UnionRgn(rectRgn, hRegion, hRegion);
1174: OS.DisposeRgn(rectRgn);
1175: }
1176: if (!region.contains(rgnRect.right - 1, rgnRect.bottom - 1)) {
1177: Rect r = new Rect();
1178: OS.SetRect(r, (short) (rgnRect.right - 1),
1179: (short) (rgnRect.bottom - 1), rgnRect.right,
1180: rgnRect.bottom);
1181: int rectRgn = OS.NewRgn();
1182: OS.RectRgn(rectRgn, r);
1183: OS.UnionRgn(rectRgn, hRegion, hRegion);
1184: OS.DisposeRgn(rectRgn);
1185: }
1186: return OS.noErr;
1187: default:
1188: OS.DiffRgn(hRegion, hRegion, hRegion);
1189: return OS.noErr;
1190: }
1191: }
1192:
1193: int kEventWindowHidden(int nextHandler, int theEvent, int userData) {
1194: int result = super .kEventWindowHidden(nextHandler, theEvent,
1195: userData);
1196: if (result == OS.noErr)
1197: return result;
1198: Shell[] shells = getShells();
1199: for (int i = 0; i < shells.length; i++) {
1200: Shell shell = shells[i];
1201: if (!shell.isDisposed())
1202: shell.setWindowVisible(false);
1203: }
1204: return OS.eventNotHandledErr;
1205: }
1206:
1207: int kEventWindowHitTest(int nextHandler, int theEvent, int userData) {
1208: int result = super .kEventWindowHitTest(nextHandler, theEvent,
1209: userData);
1210: if (result == OS.noErr)
1211: return result;
1212: if (region == null || region.isDisposed())
1213: return OS.eventNotHandledErr;
1214: org.eclipse.swt.internal.carbon.Point pt = new org.eclipse.swt.internal.carbon.Point();
1215: int sizeof = org.eclipse.swt.internal.carbon.Point.sizeof;
1216: OS.GetEventParameter(theEvent, OS.kEventParamMouseLocation,
1217: OS.typeQDPoint, null, sizeof, null, pt);
1218: Rect rect = new Rect();
1219: OS.GetWindowBounds(shellHandle, (short) OS.kWindowContentRgn,
1220: rect);
1221: OS.SetPt(pt, (short) (pt.h - rect.left),
1222: (short) (pt.v - rect.top));
1223: int rgn = OS.NewRgn();
1224: OS.RectRgn(rgn, rgnRect);
1225: OS.SectRgn(rgn, region.handle, rgn);
1226: short inData = OS.PtInRgn(pt, rgn) ? OS.wInContent : OS.wNoHit;
1227: OS.DisposeRgn(rgn);
1228: OS.SetEventParameter(theEvent, OS.kEventParamWindowDefPart,
1229: OS.typeWindowDefPartCode, 2, new short[] { inData });
1230: return OS.noErr;
1231: }
1232:
1233: int kEventWindowShown(int nextHandler, int theEvent, int userData) {
1234: int result = super .kEventWindowShown(nextHandler, theEvent,
1235: userData);
1236: if (result == OS.noErr)
1237: return result;
1238: invalidateVisibleRegion(topHandle());
1239: Shell[] shells = getShells();
1240: for (int i = 0; i < shells.length; i++) {
1241: Shell shell = shells[i];
1242: if (!shell.isDisposed() && shell.getVisible()) {
1243: shell.setWindowVisible(true);
1244: }
1245: }
1246: return OS.eventNotHandledErr;
1247: }
1248:
1249: int kEventWindowUpdate(int nextHandler, int theEvent, int userData) {
1250: update = true;
1251: int result = OS.CallNextEventHandler(nextHandler, theEvent);
1252: update = false;
1253: if (invalRgn != 0) {
1254: OS.InvalWindowRgn(shellHandle, invalRgn);
1255: OS.DisposeRgn(invalRgn);
1256: invalRgn = 0;
1257: }
1258: return result;
1259: }
1260:
1261: void resizeBounds() {
1262: Rect rect = new Rect();
1263: OS.GetWindowBounds(shellHandle, (short) OS.kWindowContentRgn,
1264: rect);
1265: int control = scrolledHandle != 0 ? scrolledHandle : handle;
1266: setBounds(control, 0, 0, rect.right - rect.left, rect.bottom
1267: - rect.top, false, true, false);
1268: resizeClientArea();
1269: }
1270:
1271: /**
1272: * Moves the receiver to the top of the drawing order for
1273: * the display on which it was created (so that all other
1274: * shells on that display, which are not the receiver's
1275: * children will be drawn behind it), marks it visible,
1276: * sets the focus and asks the window manager to make the
1277: * shell active.
1278: *
1279: * @exception SWTException <ul>
1280: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1281: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1282: * </ul>
1283: *
1284: * @see Control#moveAbove
1285: * @see Control#setFocus
1286: * @see Control#setVisible
1287: * @see Display#getActiveShell
1288: * @see Decorations#setDefaultButton(Button)
1289: * @see Shell#setActive
1290: * @see Shell#forceActive
1291: */
1292: public void open() {
1293: checkWidget();
1294: bringToTop(false);
1295: setVisible(true);
1296: if (isDisposed())
1297: return;
1298: if (active) {
1299: if (!restoreFocus() && !traverseGroup(true))
1300: setFocus();
1301: }
1302: }
1303:
1304: void register() {
1305: super .register();
1306: int[] theRoot = new int[1];
1307: OS.GetRootControl(shellHandle, theRoot);
1308: display.addWidget(theRoot[0], this );
1309: }
1310:
1311: void releaseChildren(boolean destroy) {
1312: Shell[] shells = getShells();
1313: for (int i = 0; i < shells.length; i++) {
1314: Shell shell = shells[i];
1315: if (shell != null && !shell.isDisposed()) {
1316: shell.dispose();
1317: }
1318: }
1319: super .releaseChildren(destroy);
1320: }
1321:
1322: void releaseHandle() {
1323: super .releaseHandle();
1324: shellHandle = 0;
1325: }
1326:
1327: void releaseParent() {
1328: /* Do nothing */
1329: }
1330:
1331: void releaseWidget() {
1332: super .releaseWidget();
1333: disposed = true;
1334: if (windowGroup != 0)
1335: OS.ReleaseWindowGroup(windowGroup);
1336: display.updateQuitMenu();
1337: if (invalRgn != 0)
1338: OS.DisposeRgn(invalRgn);
1339: if (imHandle != 0)
1340: OS.DeleteTSMDocument(imHandle);
1341: imHandle = invalRgn = windowGroup = 0;
1342: lastActive = null;
1343: region = null;
1344: }
1345:
1346: /**
1347: * Removes the listener from the collection of listeners who will
1348: * be notified when operations are performed on the receiver.
1349: *
1350: * @param listener the listener which should no longer be notified
1351: *
1352: * @exception IllegalArgumentException <ul>
1353: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1354: * </ul>
1355: * @exception SWTException <ul>
1356: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1357: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1358: * </ul>
1359: *
1360: * @see ShellListener
1361: * @see #addShellListener
1362: */
1363: public void removeShellListener(ShellListener listener) {
1364: checkWidget();
1365: if (listener == null)
1366: error(SWT.ERROR_NULL_ARGUMENT);
1367: if (eventTable == null)
1368: return;
1369: eventTable.unhook(SWT.Activate, listener);
1370: eventTable.unhook(SWT.Close, listener);
1371: eventTable.unhook(SWT.Deactivate, listener);
1372: eventTable.unhook(SWT.Iconify, listener);
1373: eventTable.unhook(SWT.Deiconify, listener);
1374: }
1375:
1376: /**
1377: * If the receiver is visible, moves it to the top of the
1378: * drawing order for the display on which it was created
1379: * (so that all other shells on that display, which are not
1380: * the receiver's children will be drawn behind it) and asks
1381: * the window manager to make the shell active
1382: *
1383: * @exception SWTException <ul>
1384: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1385: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1386: * </ul>
1387: *
1388: * @since 2.0
1389: * @see Control#moveAbove
1390: * @see Control#setFocus
1391: * @see Control#setVisible
1392: * @see Display#getActiveShell
1393: * @see Decorations#setDefaultButton(Button)
1394: * @see Shell#open
1395: * @see Shell#setActive
1396: */
1397: public void setActive() {
1398: checkWidget();
1399: if (!isVisible())
1400: return;
1401: OS.SelectWindow(shellHandle);
1402: }
1403:
1404: void setActiveControl(Control control) {
1405: if (control != null && control.isDisposed())
1406: control = null;
1407: if (lastActive != null && lastActive.isDisposed())
1408: lastActive = null;
1409: if (lastActive == control)
1410: return;
1411:
1412: /*
1413: * Compute the list of controls to be activated and
1414: * deactivated by finding the first common parent
1415: * control.
1416: */
1417: Control[] activate = (control == null) ? new Control[0]
1418: : control.getPath();
1419: Control[] deactivate = (lastActive == null) ? new Control[0]
1420: : lastActive.getPath();
1421: lastActive = control;
1422: int index = 0, length = Math.min(activate.length,
1423: deactivate.length);
1424: while (index < length) {
1425: if (activate[index] != deactivate[index])
1426: break;
1427: index++;
1428: }
1429:
1430: /*
1431: * It is possible (but unlikely), that application
1432: * code could have destroyed some of the widgets. If
1433: * this happens, keep processing those widgets that
1434: * are not disposed.
1435: */
1436: for (int i = deactivate.length - 1; i >= index; --i) {
1437: if (!deactivate[i].isDisposed()) {
1438: deactivate[i].sendEvent(SWT.Deactivate);
1439: }
1440: }
1441: for (int i = activate.length - 1; i >= index; --i) {
1442: if (!activate[i].isDisposed()) {
1443: activate[i].sendEvent(SWT.Activate);
1444: }
1445: }
1446: }
1447:
1448: int setBounds(int x, int y, int width, int height, boolean move,
1449: boolean resize, boolean events) {
1450: if (fullScreen)
1451: setFullScreen(false);
1452: Rect rect = new Rect();
1453: if (!move) {
1454: OS.GetWindowBounds(shellHandle,
1455: (short) OS.kWindowStructureRgn, rect);
1456: x = rect.left;
1457: y = rect.top;
1458: }
1459: if (!resize) {
1460: OS.GetWindowBounds(shellHandle,
1461: (short) OS.kWindowStructureRgn, rect);
1462: width = rect.right - rect.left;
1463: height = rect.bottom - rect.top;
1464: } else {
1465: OS.GetWindowStructureWidths(shellHandle, rect);
1466: CGPoint inMinLimits = new CGPoint(), inMaxLimits = new CGPoint();
1467: OS.GetWindowResizeLimits(shellHandle, inMinLimits,
1468: inMaxLimits);
1469: width = Math.max(1, Math.max(width, (int) inMinLimits.x
1470: + (rect.left + rect.right)));
1471: height = Math.max(1, Math.max(height, (int) inMinLimits.y
1472: + (rect.top + rect.bottom)));
1473: }
1474: OS.SetRect(rect, (short) x, (short) y, (short) (x + width),
1475: (short) (y + height));
1476: OS.SetWindowBounds(shellHandle, (short) OS.kWindowStructureRgn,
1477: rect);
1478: return 0;
1479: }
1480:
1481: public void setEnabled(boolean enabled) {
1482: checkWidget();
1483: if (((state & DISABLED) == 0) == enabled)
1484: return;
1485: super .setEnabled(enabled);
1486: if (enabled && OS.IsWindowActive(shellHandle)) {
1487: if (!restoreFocus())
1488: traverseGroup(false);
1489: }
1490: }
1491:
1492: public void setFullScreen(boolean fullScreen) {
1493: checkWidget();
1494: this .fullScreen = fullScreen;
1495: if (fullScreen) {
1496: normalBounds = getBounds();
1497: OS.ChangeWindowAttributes(shellHandle,
1498: OS.kWindowNoTitleBarAttribute,
1499: OS.kWindowResizableAttribute
1500: | OS.kWindowLiveResizeAttribute);
1501: updateSystemUIMode();
1502: Rectangle screen = getMonitor().getBounds();
1503: if (menuBar != null
1504: && getMonitor().equals(display.getPrimaryMonitor())) {
1505: Rect rect = new Rect();
1506: int gdevice = OS.GetMainDevice();
1507: OS.GetAvailableWindowPositioningBounds(gdevice, rect);
1508: screen.height -= rect.top;
1509: screen.y += rect.top;
1510: }
1511: Rect rect = new Rect();
1512: OS.SetRect(rect, (short) screen.x, (short) screen.y,
1513: (short) (screen.x + screen.width),
1514: (short) (screen.y + screen.height));
1515: OS.SetWindowBounds(shellHandle,
1516: (short) OS.kWindowStructureRgn, rect);
1517: } else {
1518: int attributes = 0;
1519: if ((style & SWT.RESIZE) != 0) {
1520: attributes |= OS.kWindowResizableAttribute;
1521: /*
1522: * Bug in the Macintosh. For some reason, a window has no title bar
1523: * and the kWindowResizableAttribute, no rubber banding feedback is
1524: * given while the window is resizing. The fix is to create the window
1525: * with kWindowLiveResizeAttribute in this case. This is inconsistent
1526: * with other windows, but the user will get feedback when resizing.
1527: */
1528: if ((style & SWT.TITLE) == 0)
1529: attributes |= OS.kWindowLiveResizeAttribute;
1530: if (!OS.__BIG_ENDIAN__())
1531: attributes |= OS.kWindowLiveResizeAttribute;
1532: }
1533: OS.ChangeWindowAttributes(shellHandle, attributes,
1534: OS.kWindowNoTitleBarAttribute);
1535: OS.SetSystemUIMode(OS.kUIModeNormal, 0);
1536: if (maximized) {
1537: setMaximized(true);
1538: } else {
1539: Rect rect = new Rect();
1540: if (normalBounds != null)
1541: OS
1542: .SetRect(
1543: rect,
1544: (short) normalBounds.x,
1545: (short) normalBounds.y,
1546: (short) (normalBounds.x + normalBounds.width),
1547: (short) (normalBounds.y + normalBounds.height));
1548: OS.SetWindowBounds(shellHandle,
1549: (short) OS.kWindowStructureRgn, rect);
1550: }
1551: normalBounds = null;
1552: }
1553: }
1554:
1555: public void setMenuBar(Menu menu) {
1556: checkWidget();
1557: super .setMenuBar(menu);
1558: if (display.getActiveShell() == this ) {
1559: display.setMenuBar(menuBar);
1560: }
1561: }
1562:
1563: /**
1564: * Sets the input method editor mode to the argument which
1565: * should be the result of bitwise OR'ing together one or more
1566: * of the following constants defined in class <code>SWT</code>:
1567: * <code>NONE</code>, <code>ROMAN</code>, <code>DBCS</code>,
1568: * <code>PHONETIC</code>, <code>NATIVE</code>, <code>ALPHA</code>.
1569: *
1570: * @param mode the new IME mode
1571: *
1572: * @exception SWTException <ul>
1573: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1574: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1575: * </ul>
1576: *
1577: * @see SWT
1578: */
1579: public void setImeInputMode(int mode) {
1580: checkWidget();
1581: }
1582:
1583: public void setMaximized(boolean maximized) {
1584: checkWidget();
1585: super .setMaximized(maximized);
1586: org.eclipse.swt.internal.carbon.Point pt = new org.eclipse.swt.internal.carbon.Point();
1587: if (maximized) {
1588: Rect rect = new Rect();
1589: int gdevice = OS.GetMainDevice();
1590: OS.GetAvailableWindowPositioningBounds(gdevice, rect);
1591: pt.h = (short) (rect.right - rect.left);
1592: pt.v = (short) (rect.bottom - rect.top);
1593: }
1594: short inPartCode = (short) (maximized ? OS.inZoomOut
1595: : OS.inZoomIn);
1596: OS.ZoomWindowIdeal(shellHandle, inPartCode, pt);
1597: }
1598:
1599: public void setMinimized(boolean minimized) {
1600: checkWidget();
1601: if (this .minimized == minimized)
1602: return;
1603: super .setMinimized(minimized);
1604: if (!minimized && OS.IsWindowCollapsed(shellHandle)) {
1605: OS.SelectWindow(shellHandle);
1606: }
1607: OS.CollapseWindow(shellHandle, minimized);
1608: }
1609:
1610: /**
1611: * Sets the receiver's minimum size to the size specified by the arguments.
1612: * If the new minimum size is larger than the current size of the receiver,
1613: * the receiver is resized to the new minimum size.
1614: *
1615: * @param width the new minimum width for the receiver
1616: * @param height the new minimum height for the receiver
1617: *
1618: * @exception SWTException <ul>
1619: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1620: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1621: * </ul>
1622: *
1623: * @since 3.1
1624: */
1625: public void setMinimumSize(int width, int height) {
1626: checkWidget();
1627: int clientWidth = 0, clientHeight = 0;
1628: int trim = SWT.TITLE | SWT.CLOSE | SWT.MIN | SWT.MAX;
1629: if ((style & SWT.NO_TRIM) == 0 && (style & trim) != 0) {
1630: clientWidth = DEFAULT_CLIENT_WIDTH;
1631: clientHeight = DEFAULT_CLIENT_HEIGHT;
1632: }
1633: Rect rect = new Rect();
1634: OS.GetWindowStructureWidths(shellHandle, rect);
1635: CGPoint inMinLimits = new CGPoint(), inMaxLimits = new CGPoint();
1636: OS.GetWindowResizeLimits(shellHandle, inMinLimits, inMaxLimits);
1637: width = Math.max(width, clientWidth + rect.left + rect.right);
1638: height = Math
1639: .max(height, clientHeight + rect.top + rect.bottom);
1640: inMinLimits.x = width - (rect.left + rect.right);
1641: inMinLimits.y = height - (rect.top + rect.bottom);
1642: OS.SetWindowResizeLimits(shellHandle, inMinLimits, inMaxLimits);
1643: Point size = getSize();
1644: int newWidth = Math.max(size.x, width), newHeight = Math.max(
1645: size.y, height);
1646: if (newWidth != size.x || newHeight != size.y)
1647: setSize(newWidth, newHeight);
1648: }
1649:
1650: /**
1651: * Sets the receiver's minimum size to the size specified by the argument.
1652: * If the new minimum size is larger than the current size of the receiver,
1653: * the receiver is resized to the new minimum size.
1654: *
1655: * @param size the new minimum size for the receiver
1656: *
1657: * @exception IllegalArgumentException <ul>
1658: * <li>ERROR_NULL_ARGUMENT - if the point is null</li>
1659: * </ul>
1660: * @exception SWTException <ul>
1661: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1662: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1663: * </ul>
1664: *
1665: * @since 3.1
1666: */
1667: public void setMinimumSize(Point size) {
1668: checkWidget();
1669: if (size == null)
1670: error(SWT.ERROR_NULL_ARGUMENT);
1671: setMinimumSize(size.x, size.y);
1672: }
1673:
1674: /**
1675: * Sets the shape of the shell to the region specified
1676: * by the argument. When the argument is null, the
1677: * default shape of the shell is restored. The shell
1678: * must be created with the style SWT.NO_TRIM in order
1679: * to specify a region.
1680: *
1681: * @param region the region that defines the shape of the shell (or null)
1682: *
1683: * @exception IllegalArgumentException <ul>
1684: * <li>ERROR_INVALID_ARGUMENT - if the region has been disposed</li>
1685: * </ul>
1686: * @exception SWTException <ul>
1687: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1688: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1689: * </ul>
1690: *
1691: * @since 3.0
1692: *
1693: */
1694: public void setRegion(Region region) {
1695: checkWidget();
1696: if ((style & SWT.NO_TRIM) == 0)
1697: return;
1698: if (region != null && region.isDisposed())
1699: error(SWT.ERROR_INVALID_ARGUMENT);
1700: if (region == null) {
1701: rgnRect = null;
1702: } else {
1703: if (rgnRect == null) {
1704: rgnRect = new Rect();
1705: OS.GetWindowBounds(shellHandle,
1706: (short) OS.kWindowStructureRgn, rgnRect);
1707: OS.SetRect(rgnRect, (short) 0, (short) 0,
1708: (short) (rgnRect.right - rgnRect.left),
1709: (short) (rgnRect.bottom - rgnRect.top));
1710: }
1711: }
1712: this .region = region;
1713: /*
1714: * Bug in the Macintosh. Calling ReshapeCustomWindow() from a
1715: * kEventWindowDrawContent handler originating from ShowWindow()
1716: * will deadlock. The fix is to detected this case and only call
1717: * ReshapeCustomWindow() after the default handler is done.
1718: */
1719: if (drawing) {
1720: reshape = true;
1721: } else {
1722: OS.ReshapeCustomWindow(shellHandle);
1723: redrawWidget(handle, true);
1724: }
1725: }
1726:
1727: public void setText(String string) {
1728: checkWidget();
1729: if (string == null)
1730: error(SWT.ERROR_NULL_ARGUMENT);
1731: super .setText(string);
1732: char[] buffer = new char[string.length()];
1733: string.getChars(0, buffer.length, buffer, 0);
1734: int ptr = OS.CFStringCreateWithCharacters(
1735: OS.kCFAllocatorDefault, buffer, buffer.length);
1736: if (ptr == 0)
1737: error(SWT.ERROR_CANNOT_SET_TEXT);
1738: OS.SetWindowTitleWithCFString(shellHandle, ptr);
1739: OS.CFRelease(ptr);
1740: }
1741:
1742: public void setVisible(boolean visible) {
1743: checkWidget();
1744: if (visible) {
1745: if ((state & HIDDEN) == 0)
1746: return;
1747: state &= ~HIDDEN;
1748: } else {
1749: if ((state & HIDDEN) != 0)
1750: return;
1751: state |= HIDDEN;
1752: }
1753: setWindowVisible(visible);
1754: }
1755:
1756: void setWindowVisible(boolean visible) {
1757: if (OS.IsWindowVisible(shellHandle) == visible)
1758: return;
1759: if (visible) {
1760: sendEvent(SWT.Show);
1761: if (isDisposed())
1762: return;
1763: int inModalKind = OS.kWindowModalityNone;
1764: if ((style & SWT.PRIMARY_MODAL) != 0)
1765: inModalKind = OS.kWindowModalityWindowModal;
1766: if ((style & SWT.APPLICATION_MODAL) != 0)
1767: inModalKind = OS.kWindowModalityAppModal;
1768: if ((style & SWT.SYSTEM_MODAL) != 0)
1769: inModalKind = OS.kWindowModalitySystemModal;
1770: if (inModalKind != OS.kWindowModalityNone) {
1771: int inUnavailableWindow = 0;
1772: if (parent != null)
1773: inUnavailableWindow = OS
1774: .GetControlOwner(parent.handle);
1775: OS.SetWindowModality(shellHandle, inModalKind,
1776: inUnavailableWindow);
1777: }
1778: int topHandle = topHandle();
1779: OS.SetControlVisibility(topHandle, true, false);
1780: int[] scope = new int[1];
1781: if ((style & SWT.ON_TOP) != 0) {
1782: OS.GetWindowActivationScope(shellHandle, scope);
1783: OS.SetWindowActivationScope(shellHandle,
1784: OS.kWindowActivationScopeNone);
1785: }
1786: int shellHandle = this .shellHandle;
1787: OS.RetainWindow(shellHandle);
1788: OS.ShowWindow(shellHandle);
1789: OS.ReleaseWindow(shellHandle);
1790: if (isDisposed())
1791: return;
1792: if (minimized != OS.IsWindowCollapsed(shellHandle)) {
1793: OS.CollapseWindow(shellHandle, minimized);
1794: }
1795: if ((style & SWT.ON_TOP) != 0) {
1796: OS.SetWindowActivationScope(shellHandle, scope[0]);
1797: OS.BringToFront(shellHandle);
1798: }
1799: opened = true;
1800: if (!moved) {
1801: moved = true;
1802: sendEvent(SWT.Move);
1803: if (isDisposed())
1804: return;
1805: }
1806: if (!resized) {
1807: resized = true;
1808: sendEvent(SWT.Resize);
1809: if (isDisposed())
1810: return;
1811: if (layout != null) {
1812: markLayout(false, false);
1813: updateLayout(false);
1814: }
1815: }
1816: } else {
1817: /*
1818: * Bug in the Macintosh. Under certain circumstances, yet to
1819: * be determined, calling HideWindow() and then DisposeWindow()
1820: * causes a segment fault when an application is exiting. This
1821: * seems to happen to large applications. The fix is to avoid
1822: * calling HideWindow() when a shell is about to be disposed.
1823: */
1824: if (!disposed)
1825: OS.HideWindow(shellHandle);
1826: if (isDisposed())
1827: return;
1828: int topHandle = topHandle();
1829: OS.SetControlVisibility(topHandle, false, false);
1830: invalidateVisibleRegion(topHandle);
1831: sendEvent(SWT.Hide);
1832: }
1833: display.updateQuitMenu();
1834: }
1835:
1836: void setZOrder() {
1837: if (scrolledHandle != 0)
1838: OS.HIViewAddSubview(scrolledHandle, handle);
1839: }
1840:
1841: void setZOrder(Control control, boolean above) {
1842: if (above) {
1843: //NOT DONE - move one window above another
1844: OS.BringToFront(shellHandle);
1845: } else {
1846: int window = control == null ? 0 : OS
1847: .GetControlOwner(control.handle);
1848: OS.SendBehind(shellHandle, window);
1849: }
1850: }
1851:
1852: boolean traverseEscape() {
1853: if (parent == null)
1854: return false;
1855: if (!isVisible() || !isEnabled())
1856: return false;
1857: close();
1858: return true;
1859: }
1860:
1861: void updateSystemUIMode() {
1862: if (!getMonitor().equals(display.getPrimaryMonitor()))
1863: return;
1864: boolean isActive = false;
1865: Shell activeShell = display.getActiveShell();
1866: Shell current = this ;
1867: while (current != null) {
1868: if (current.equals(activeShell)) {
1869: isActive = true;
1870: break;
1871: }
1872: current = (Shell) current.parent;
1873: }
1874: if (!isActive)
1875: return;
1876: if (fullScreen) {
1877: int mode = OS.kUIModeAllHidden;
1878: if (menuBar != null) {
1879: mode = OS.kUIModeContentHidden;
1880: }
1881: OS.SetSystemUIMode(mode, 0);
1882: } else {
1883: OS.SetSystemUIMode(OS.kUIModeNormal, 0);
1884: }
1885: }
1886:
1887: }
|