blob: 72737df0691720b6932367e8d33c733c44180f3b [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2003-2007 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 */
25package sun.awt.X11;
26
27import java.awt.Component;
28import java.awt.Rectangle;
29import java.awt.Insets;
30
31import java.awt.event.ComponentEvent;
32
33import java.util.logging.Level;
34import java.util.logging.Logger;
35
36import sun.awt.ComponentAccessor;
37
38/**
39 * This class implements window which serves as content window for decorated frames.
40 * Its purpose to provide correct events dispatching for the complex
41 * constructs such as decorated frames.
42 */
43public class XContentWindow extends XWindow implements XConstants {
44 private static Logger insLog = Logger.getLogger("sun.awt.X11.insets.XContentWindow");
45
46 XDecoratedPeer parentFrame;
47
48 // A list of expose events that come when the parentFrame is iconified
49 private java.util.List<SavedExposeEvent> iconifiedExposeEvents = new java.util.ArrayList<SavedExposeEvent>();
50
51 XContentWindow(XDecoratedPeer parentFrame, Rectangle bounds) {
52 super((Component)parentFrame.getTarget(), parentFrame.getShell(), bounds);
53 this.parentFrame = parentFrame;
54 }
55
56 void preInit(XCreateWindowParams params) {
57 super.preInit(params);
58 params.putIfNull(BIT_GRAVITY, Integer.valueOf(NorthWestGravity));
59 Long eventMask = (Long)params.get(EVENT_MASK);
60 if (eventMask != null) {
61 eventMask = eventMask & ~(StructureNotifyMask);
62 params.put(EVENT_MASK, eventMask);
63 }
64 }
65
66 void initialize() {
67 xSetVisible(true);
68 }
69 protected String getWMName() {
70 return "Content window";
71 }
72 protected boolean isEventDisabled(XEvent e) {
73 switch (e.get_type()) {
74 // Override parentFrame to receive MouseEnter/Exit
75 case EnterNotify:
76 case LeaveNotify:
77 return false;
78 // We handle ConfigureNotify specifically in XDecoratedPeer
79 case ConfigureNotify:
80 return true;
81 // We don't want SHOWN/HIDDEN on content window since it will duplicate XDecoratedPeer
82 case MapNotify:
83 case UnmapNotify:
84 return true;
85 default:
86 return super.isEventDisabled(e) || parentFrame.isEventDisabled(e);
87 }
88 }
89
90 // Coordinates are that of the shell
91 void setContentBounds(WindowDimensions dims) {
92 XToolkit.awtLock();
93 try {
94 // Bounds of content window are of the same size as bounds of Java window and with
95 // location as -(insets)
96 Rectangle newBounds = dims.getBounds();
97 Insets in = dims.getInsets();
98 if (in != null) {
99 newBounds.setLocation(-in.left, -in.top);
100 }
101 if (insLog.isLoggable(Level.FINE)) insLog.log(Level.FINE, "Setting content bounds {0}, old bounds {1}",
102 new Object[] {newBounds, getBounds()});
103 // Fix for 5023533:
104 // Change in the size of the content window means, well, change of the size
105 // Change in the location of the content window means change in insets
106 boolean needHandleResize = !(newBounds.equals(getBounds()));
107 reshape(newBounds);
108 if (needHandleResize) {
109 insLog.fine("Sending RESIZED");
110 handleResize(newBounds);
111 }
112 } finally {
113 XToolkit.awtUnlock();
114 }
115 validateSurface();
116 }
117
118 // NOTE: This method may be called by privileged threads.
119 // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
120 public void handleResize(Rectangle bounds) {
121 ComponentAccessor.setWidth((Component)target, bounds.width);
122 ComponentAccessor.setHeight((Component)target, bounds.height);
123 postEvent(new ComponentEvent(target, ComponentEvent.COMPONENT_RESIZED));
124 }
125
126
127 public void handleExposeEvent(Component target, int x, int y, int w, int h) {
128 // TODO: ?
129 // get rid of 'istanceof' by subclassing:
130 // XContentWindow -> XFrameContentWindow
131
132 // Expose event(s) that result from deiconification
133 // come before a deicinofication notification.
134 // We reorder these events by saving all expose events
135 // that come when the frame is iconified. Then we
136 // actually handle saved expose events on deiconification.
137
138 if (parentFrame instanceof XFramePeer &&
139 (((XFramePeer)parentFrame).getState() & java.awt.Frame.ICONIFIED) != 0) {
140 // Save expose events if the frame is iconified
141 // in order to handle them on deiconification.
142 iconifiedExposeEvents.add(new SavedExposeEvent(target, x, y, w, h));
143 } else {
144 // Normal case: [it is not a frame or] the frame is not iconified.
145 super.handleExposeEvent(target, x, y, w, h);
146 }
147 }
148
149 void purgeIconifiedExposeEvents() {
150 for (SavedExposeEvent evt : iconifiedExposeEvents) {
151 super.handleExposeEvent(evt.target, evt.x, evt.y, evt.w, evt.h);
152 }
153 iconifiedExposeEvents.clear();
154 }
155
156 private static class SavedExposeEvent {
157 Component target;
158 int x, y, w, h;
159 SavedExposeEvent(Component target, int x, int y, int w, int h) {
160 this.target = target;
161 this.x = x;
162 this.y = y;
163 this.w = w;
164 this.h = h;
165 }
166 }
167
168 public String toString() {
169 return getClass().getName() + "[" + getBounds() + "]";
170 }
171}