blob: da2f625a8f43bc5ee458d9aaeacc4bbdfbde0a16 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26
271. Useful API:
28
29 XWindowPeer.isModalBlocked()
30 Checks if this window is blocked by any modal dialog
31 For common component peers use getToplevelXWindow().isModalBlocked()
32
33 XWindowPeer.setModalBlocked(Dialog blocker, boolean blocked)
34 Implementation of WindoePeer.setModalBlocked() method
35 Marks this window blocked/unblocked and adds/removes it
36 from transient_for chain (see below)
37 Don't call this method directly, it should be used from shared
38 code only
39
40 XWindowPeer.addToTransientFors()
41 XWindowPeer.removeFromTransientFors()
42 See below
43
442. Filtering mouse events
45
46 Mouse events are filtered in the shared code. See
47 java.awt.ModalFilter class for details
48
493. Filtering key events
50
51 Key events are filtering by preventing the blocked windows
52 to get native focus. All the AWT windows use global active focus
53 input model (see ICCCM for details) and listens to WM_TAKE_FOCUS
54 protocol. If the window manager asks AWT to set focus on the
55 blocked window, in XDecoratedPeer.handleWmTakeFocus() method we
56 set the focus to the window's blocker.
57
584. Z-order
59
60 According to the Modality spec any modal dialog should be always on
61 top of its blocked windows. It is implemented with using
62 WM_TRANSIENT_FOR hint.
63
64 WM_TRANSIENT_FOR is used to mark one window to be a child of another
65 one, in particular for any kind of dialogs. When a modal dialog
66 is shown it temporary becomes a child of all its blocked windows
67 and thus remains on top of them.
68
69 WM_TRANSIENT_FOR value is a single window, so we can't directly make
70 a dialog be a child of several other windows. It is implemented
71 as a "transient_for chain": all the blocked windows are arranged
72 into a chain, each next window is transient for the prev.
73
74 The chain is stored in XWindowPeer's fields 'prevTransientFor' and
75 'nextTransientFor'. If window is not blocked both of these fields
76 are set to null.
77
78 However, the value of WM_TRANSIENT_FOR hint and prevTransientFor
79 may differ sometimes. This happens when two windows are in
80 different window states, usually NormalState and IconifiedState.
81 Some window managers don't allow a dialog to be visible is its
82 parent window is iconified. The situation is even worse: we
83 don't receive any notifications when the dialog is iconified
84 together with its parent frame.
85
86 Thus we need to track all the window's state changes. Also, for
87 any window state (NormalState, IconifiedState, WithdrawnState)
88 a distinct chain is tracked. Below is a brief example.
89
90 Let's consider two frames F1 and F2 and two modeless dialogs D1
91 (with F1 as a parent) and D2 (F2). Their Z-order is:
92 F1 - D1 - F2 - D2 (D1 is above F1, F2 is above D1, etc). Then
93 a modal dialog D3 is shown and all these four windows become
94 blocked by it. Transient_for chain is constructed in the
95 following way: F1 - D2 - F2 - D2 - D3. Respectively, F2
96 temporarily becomes a child of D1 (WM_TRANSIENT_FOR hint is
97 set to F2 with a value of D1), etc.
98
99 Then F1 is iconified (some window managers allow this action).
100 F1.nextTransientFor and D1.prevTransientFor aren't changed,
101 however the values of WM_TRANSIENT_FOR hint for them are
102 changed: hint value for F1 is set to None, and hint value for
103 D1 is set to None.
104
105 Let's iconify another window, F2. prev/nextTransientFor field
106 values aren't changed again, but WM_TRANSIENT_FOR hint is:
107 the value for D2 is D1, the value for F2 is F1 (both are
108 iconified).
109
110 When either F1 or F2 is restored, the value for its hint is
111 restored according to the value stored in prevTransientFor
112 and nextTransientFor fields.
113
114 Note that some window managers don't allow iconifying for
115 those windows that are children of some other toplevel. That
116 is any dialog can't be iconified and any blocked window
117 that is not the first in the transient_for chain too.
118
119 All the updates of the hint's value is performed in the
120 XWindowPeer.setToplevelTransientFor() method.
121
1225. Multiscreen
123
124 All the problems with WM_TRANSIENT_FOR hint and different
125 window states can be applied to different X screens (if
126 Xinerama is off). For example, some window managers ignore
127 the hint if window and transient_for window are on different
128 screens.
129
130 That leads to us to track a separate transient_for chain for
131 every screen in the system, as well as for every window
132 state. See XWindowPeer.updateTransientFor() for details.
133
1346. See also
135
136 Some examples how transient_for chain is constructed and
137 destructed can be found in JavaDoc comments for the
138 following methods: XWindowPeer.addToTransientFors(),
139 XWindowPeer.removeFromTransientFors(),
140 XWindowPeer.setToplevelTransientFor(),
141 XWindowPeer.stateChanged().
142