/* 
 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */


1. Useful API:

  XWindowPeer.isModalBlocked()
    Checks if this window is blocked by any modal dialog
    For common component peers use getToplevelXWindow().isModalBlocked()

  XWindowPeer.setModalBlocked(Dialog blocker, boolean blocked)
    Implementation of WindoePeer.setModalBlocked() method
    Marks this window blocked/unblocked and adds/removes it
      from transient_for chain (see below)
    Don't call this method directly, it should be used from shared
      code only

  XWindowPeer.addToTransientFors()
  XWindowPeer.removeFromTransientFors()
    See below

2. Filtering mouse events

  Mouse events are filtered in the shared code. See
    java.awt.ModalFilter class for details

3. Filtering key events

  Key events are filtering by preventing the blocked windows
    to get native focus. All the AWT windows use global active focus
    input model (see ICCCM for details) and listens to WM_TAKE_FOCUS
    protocol. If the window manager asks AWT to set focus on the
    blocked window, in XDecoratedPeer.handleWmTakeFocus() method we
    set the focus to the window's blocker.

4. Z-order

  According to the Modality spec any modal dialog should be always on
    top of its blocked windows. It is implemented with using
    WM_TRANSIENT_FOR hint.

  WM_TRANSIENT_FOR is used to mark one window to be a child of another
    one, in particular for any kind of dialogs. When a modal dialog
    is shown it temporary becomes a child of all its blocked windows
    and thus remains on top of them.

  WM_TRANSIENT_FOR value is a single window, so we can't directly make
    a dialog be a child of several other windows. It is implemented
    as a "transient_for chain": all the blocked windows are arranged
    into a chain, each next window is transient for the prev.

  The chain is stored in XWindowPeer's fields 'prevTransientFor' and
    'nextTransientFor'. If window is not blocked both of these fields
    are set to null.

  However, the value of WM_TRANSIENT_FOR hint and prevTransientFor
    may differ sometimes. This happens when two windows are in
    different window states, usually NormalState and IconifiedState.
    Some window managers don't allow a dialog to be visible is its
    parent window is iconified. The situation is even worse: we
    don't receive any notifications when the dialog is iconified
    together with its parent frame.

  Thus we need to track all the window's state changes. Also, for
    any window state (NormalState, IconifiedState, WithdrawnState)
    a distinct chain is tracked. Below is a brief example.

  Let's consider two frames F1 and F2 and two modeless dialogs D1
    (with F1 as a parent) and D2 (F2). Their Z-order is:
    F1 - D1 - F2 - D2 (D1 is above F1, F2 is above D1, etc). Then
    a modal dialog D3 is shown and all these four windows become
    blocked by it. Transient_for chain is constructed in the
    following way: F1 - D2 - F2 - D2 - D3. Respectively, F2
    temporarily becomes a child of D1 (WM_TRANSIENT_FOR hint is
    set to F2 with a value of D1), etc.

  Then F1 is iconified (some window managers allow this action).
    F1.nextTransientFor and D1.prevTransientFor aren't changed,
    however the values of WM_TRANSIENT_FOR hint for them are
    changed: hint value for F1 is set to None, and hint value for
    D1 is set to None.

  Let's iconify another window, F2. prev/nextTransientFor field
    values aren't changed again, but WM_TRANSIENT_FOR hint is:
    the value for D2 is D1, the value for F2 is F1 (both are
    iconified).

  When either F1 or F2 is restored, the value for its hint is
    restored according to the value stored in prevTransientFor
    and nextTransientFor fields.

  Note that some window managers don't allow iconifying for
    those windows that are children of some other toplevel. That
    is any dialog can't be iconified and any blocked window
    that is not the first in the transient_for chain too.

  All the updates of the hint's value is performed in the
    XWindowPeer.setToplevelTransientFor() method.

5. Multiscreen

  All the problems with WM_TRANSIENT_FOR hint and different
    window states can be applied to different X screens (if
    Xinerama is off). For example, some window managers ignore
    the hint if window and transient_for window are on different
    screens.

  That leads to us to track a separate transient_for chain for
    every screen in the system, as well as for every window
    state. See XWindowPeer.updateTransientFor() for details.

6. See also

  Some examples how transient_for chain is constructed and
    destructed can be found in JavaDoc comments for the
    following methods: XWindowPeer.addToTransientFors(),
    XWindowPeer.removeFromTransientFors(),
    XWindowPeer.setToplevelTransientFor(),
    XWindowPeer.stateChanged().

