180
181 XFocusProxyWindow createFocusProxy() {
182 return new XFocusProxyWindow(this);
183 }
184
185 protected XAtomList getWMProtocols() {
186 XAtomList protocols = super.getWMProtocols();
187 protocols.add(wm_delete_window);
188 protocols.add(wm_take_focus);
189 return protocols;
190 }
191
192 public Graphics getGraphics() {
193 return getGraphics(content.surfaceData,
194 ComponentAccessor.getForeground(target),
195 ComponentAccessor.getBackground(target),
196 ComponentAccessor.getFont_NoClientCode(target));
197 }
198
199 public void setTitle(String title) {
200 if (log.isLoggable(Level.FINE)) log.fine("Title is " + title);
201 winAttr.title = title;
202 updateWMName();
203 }
204
205 protected String getWMName() {
206 if (winAttr.title == null || winAttr.title.trim().equals("")) {
207 return " ";
208 } else {
209 return winAttr.title;
210 }
211 }
212
213 void updateWMName() {
214 super.updateWMName();
215 String name = getWMName();
216 XToolkit.awtLock();
217 try {
218 if (name == null || name.trim().equals("")) {
219 name = "Java";
220 }
228 }
229
230 // NOTE: This method may be called by privileged threads.
231 // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
232 public void handleIconify() {
233 postEvent(new WindowEvent((Window)target, WindowEvent.WINDOW_ICONIFIED));
234 }
235
236 // NOTE: This method may be called by privileged threads.
237 // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
238 public void handleDeiconify() {
239 postEvent(new WindowEvent((Window)target, WindowEvent.WINDOW_DEICONIFIED));
240 }
241
242 public void handleFocusEvent(XEvent xev) {
243 super.handleFocusEvent(xev);
244 XFocusChangeEvent xfe = xev.get_xfocus();
245
246 // If we somehow received focus events forward it instead to proxy
247 // FIXME: Shouldn't we instead check for inferrior?
248 focusLog.finer("Received focus event on shell: " + xfe);
249 // focusProxy.xRequestFocus();
250 }
251
252 /***************************************************************************************
253 * I N S E T S C O D E
254 **************************************************************************************/
255
256 protected boolean isInitialReshape() {
257 return false;
258 }
259
260 Insets difference(Insets i1, Insets i2) {
261 return new Insets(i1.top-i2.top, i1.left - i2.left, i1.bottom-i2.bottom, i1.right-i2.right);
262 }
263
264 void add(Insets i1, Insets i2) {
265 i1.left += i2.left;
266 i1.top += i2.top;
267 i1.right += i2.right;
268 i1.bottom += i2.bottom;
269 }
270 boolean isNull(Insets i) {
271 return (i == null) || ((i.left | i.top | i.right | i.bottom) == 0);
272 }
273 Insets copy(Insets i) {
274 return new Insets(i.top, i.left, i.bottom, i.right);
275 }
276
277 long reparent_serial = 0;
278
279 public void handleReparentNotifyEvent(XEvent xev) {
280 XReparentEvent xe = xev.get_xreparent();
281 if (insLog.isLoggable(Level.FINE)) insLog.fine(xe.toString());
282 reparent_serial = xe.get_serial();
283 XToolkit.awtLock();
284 try {
285 long root = XlibWrapper.RootWindow(XToolkit.getDisplay(), getScreenNumber());
286
287 if (isEmbedded()) {
288 setReparented(true);
289 insets_corrected = true;
290 return;
291 }
292 Component t = (Component)target;
293 if (getDecorations() == winAttr.AWT_DECOR_NONE) {
294 setReparented(true);
295 insets_corrected = true;
296 reshape(dimensions, SET_SIZE, false);
297 } else if (xe.get_parent() == root) {
298 configure_seen = false;
299 insets_corrected = false;
300
301 /*
307 /* Work around 4775545 */
308 XWM.getWM().unshadeKludge(this);
309 insLog.fine("- WM exited");
310 } else {
311 insLog.fine(" - reparent due to hide");
312 }
313 } else { /* reparented to WM frame, figure out our insets */
314 setReparented(true);
315 insets_corrected = false;
316
317 // Check if we have insets provided by the WM
318 Insets correctWM = getWMSetInsets(null);
319 if (correctWM != null) {
320 if (insLog.isLoggable(Level.FINER)) {
321 insLog.log(Level.FINER, "wm-provided insets {0}",
322 new Object[]{String.valueOf(correctWM)});
323 }
324 // If these insets are equal to our current insets - no actions are necessary
325 Insets dimInsets = dimensions.getInsets();
326 if (correctWM.equals(dimInsets)) {
327 insLog.finer("Insets are the same as estimated - no additional reshapes necessary");
328 no_reparent_artifacts = true;
329 insets_corrected = true;
330 applyGuessedInsets();
331 return;
332 }
333 } else {
334 correctWM = XWM.getWM().getInsets(this, xe.get_window(), xe.get_parent());
335
336 if (correctWM != null) {
337 if (insLog.isLoggable(Level.FINER)) {
338 insLog.log(Level.FINER, "correctWM {0}",
339 new Object[] {String.valueOf(correctWM)});
340 }
341 } else {
342 insLog.log(Level.FINER, "correctWM insets are not available, waiting for configureNotify");
343 }
344 }
345
346 if (correctWM != null) {
347 handleCorrectInsets(correctWM);
348 }
349 }
350 } finally {
351 XToolkit.awtUnlock();
352 }
353 }
354
355 protected void handleCorrectInsets(Insets correctWM) {
356 XToolkit.awtLock();
357 try {
358 /*
359 * Ok, now see if we need adjust window size because
360 * initial insets were wrong (most likely they were).
361 */
362 Insets correction = difference(correctWM, currentInsets);
363 if (insLog.isLoggable(Level.FINEST)) {
364 insLog.log(Level.FINEST, "Corrention {0}", new Object[] {String.valueOf(correction)});
366 if (!isNull(correction)) {
367 /*
368 * Actual insets account for menubar/warning label,
369 * so we can't assign directly but must adjust them.
370 */
371 add(currentInsets, correction);
372 applyGuessedInsets();
373
374 //Fix for 6318109: PIT: Min Size is not honored properly when a
375 //smaller size is specified in setSize(), XToolkit
376 //update minimum size hints
377 updateMinSizeHints();
378
379 /*
380 * If this window has been sized by a pack() we need
381 * to keep the interior geometry intact. Since pack()
382 * computed width and height with wrong insets, we
383 * must adjust the target dimensions appropriately.
384 */
385 }
386 if (insLog.isLoggable(Level.FINER)) insLog.finer("Dimensions before reparent: " + dimensions);
387
388 dimensions.setInsets(getRealInsets());
389 insets_corrected = true;
390
391 if (isMaximized()) {
392 return;
393 }
394
395 if ((getHints().get_flags() & (USPosition | PPosition)) != 0) {
396 reshape(dimensions, SET_BOUNDS, false);
397 } else {
398 reshape(dimensions, SET_SIZE, false);
399 }
400 } finally {
401 XToolkit.awtUnlock();
402 }
403 }
404
405 public void handleMoved(WindowDimensions dims) {
406 Point loc = dims.getLocation();
488 }
489 if (userReshape) {
490 // We handle only userReshape == true cases. It means that
491 // if the window manager or any other part of the windowing
492 // system sets inappropriate size for this window, we can
493 // do nothing but accept it.
494 Rectangle reqBounds = newDimensions.getBounds();
495 Rectangle newBounds = constrainBounds(reqBounds.x, reqBounds.y, reqBounds.width, reqBounds.height);
496 Insets insets = newDimensions.getInsets();
497 // Inherit isClientSizeSet from newDimensions
498 if (newDimensions.isClientSizeSet()) {
499 newBounds = new Rectangle(newBounds.x, newBounds.y,
500 newBounds.width - insets.left - insets.right,
501 newBounds.height - insets.top - insets.bottom);
502 }
503 newDimensions = new WindowDimensions(newBounds, insets, newDimensions.isClientSizeSet());
504 }
505 XToolkit.awtLock();
506 try {
507 if (!isReparented() || !isVisible()) {
508 insLog.log(Level.FINE, "- not reparented({0}) or not visible({1}), default reshape",
509 new Object[] {Boolean.valueOf(isReparented()), Boolean.valueOf(visible)});
510
511 // Fix for 6323293.
512 // This actually is needed to preserve compatibility with previous releases -
513 // some of licensees are expecting componentMoved event on invisible one while
514 // its location changes.
515 Point oldLocation = getLocation();
516
517 Point newLocation = new Point(ComponentAccessor.getX((Component)target),
518 ComponentAccessor.getY((Component)target));
519
520 if (!newLocation.equals(oldLocation)) {
521 handleMoved(newDimensions);
522 }
523
524 dimensions = new WindowDimensions(newDimensions);
525 updateSizeHints(dimensions);
526 Rectangle client = dimensions.getClientRect();
527 checkShellRect(client);
528 setShellBounds(client);
529 if (content != null &&
763 ComponentAccessor.getHeight((Component)target));
764
765 Point newLocation = targetBounds.getLocation();
766 if (xe.get_send_event() || runningWM == XWM.NO_WM || XWM.isNonReparentingWM()) {
767 // Location, Client size + insets
768 newLocation = new Point(xe.get_x() - currentInsets.left, xe.get_y() - currentInsets.top);
769 } else {
770 // CDE/MWM/Metacity/Sawfish bug: if shell is resized using
771 // top or left border, we don't receive synthetic
772 // ConfigureNotify, only the one from X with zero
773 // coordinates. This is the workaround to get real
774 // location, 6261336
775 switch (XWM.getWMID()) {
776 case XWM.CDE_WM:
777 case XWM.MOTIF_WM:
778 case XWM.METACITY_WM:
779 case XWM.SAWFISH_WM:
780 {
781 Point xlocation = queryXLocation();
782 if (log.isLoggable(Level.FINE)) {
783 log.log(Level.FINE, "New X location: {0}", new Object[]{String.valueOf(xlocation)});
784 }
785 if (xlocation != null) {
786 newLocation = xlocation;
787 }
788 break;
789 }
790 default:
791 break;
792 }
793 }
794
795 WindowDimensions newDimensions =
796 new WindowDimensions(newLocation,
797 new Dimension(xe.get_width(), xe.get_height()),
798 copy(currentInsets),
799 true);
800
801 if (insLog.isLoggable(Level.FINER)) {
802 insLog.log(Level.FINER, "Insets are {0}, new dimensions {1}",
803 new Object[] {String.valueOf(currentInsets), String.valueOf(newDimensions)});
823 if (shellRect.height < 0) {
824 shellRect.height = 1;
825 }
826 }
827
828 private void checkShellRectPos(Rectangle shellRect) {
829 int wm = XWM.getWMID();
830 if (wm == XWM.MOTIF_WM || wm == XWM.CDE_WM) {
831 if (shellRect.x == 0 && shellRect.y == 0) {
832 shellRect.x = shellRect.y = 1;
833 }
834 }
835 }
836
837 private void checkShellRect(Rectangle shellRect) {
838 checkShellRectSize(shellRect);
839 checkShellRectPos(shellRect);
840 }
841
842 public void setShellBounds(Rectangle rec) {
843 if (insLog.isLoggable(Level.FINE)) insLog.fine("Setting shell bounds on " +
844 this + " to " + rec);
845 XToolkit.awtLock();
846 try {
847 updateSizeHints(rec.x, rec.y, rec.width, rec.height);
848 XlibWrapper.XResizeWindow(XToolkit.getDisplay(), getShell(), rec.width, rec.height);
849 XlibWrapper.XMoveWindow(XToolkit.getDisplay(), getShell(), rec.x, rec.y);
850 }
851 finally {
852 XToolkit.awtUnlock();
853 }
854 }
855 public void setShellSize(Rectangle rec) {
856 if (insLog.isLoggable(Level.FINE)) insLog.fine("Setting shell size on " +
857 this + " to " + rec);
858 XToolkit.awtLock();
859 try {
860 updateSizeHints(rec.x, rec.y, rec.width, rec.height);
861 XlibWrapper.XResizeWindow(XToolkit.getDisplay(), getShell(), rec.width, rec.height);
862 }
863 finally {
864 XToolkit.awtUnlock();
865 }
866 }
867 public void setShellPosition(Rectangle rec) {
868 if (insLog.isLoggable(Level.FINE)) insLog.fine("Setting shell position on " +
869 this + " to " + rec);
870 XToolkit.awtLock();
871 try {
872 updateSizeHints(rec.x, rec.y, rec.width, rec.height);
873 XlibWrapper.XMoveWindow(XToolkit.getDisplay(), getShell(), rec.x, rec.y);
874 }
875 finally {
876 XToolkit.awtUnlock();
877 }
878 }
879
880 void initResizability() {
881 setResizable(winAttr.initialResizability);
882 }
883 public void setResizable(boolean resizable) {
884 int fs = winAttr.functions;
885 if (!isResizable() && resizable) {
886 insets = currentInsets = new Insets(0, 0, 0, 0);
887 resetWMSetInsets();
888 if (!isEmbedded()) {
889 setReparented(false);
949
950 public int getWidth() {
951 return getSize().width;
952 }
953
954 public int getHeight() {
955 return getSize().height;
956 }
957
958 public WindowDimensions getDimensions() {
959 return dimensions;
960 }
961
962 public Point getLocationOnScreen() {
963 XToolkit.awtLock();
964 try {
965 if (configure_seen) {
966 return toGlobal(0,0);
967 } else {
968 Point location = target.getLocation();
969 if (insLog.isLoggable(Level.FINE))
970 insLog.log(Level.FINE, "getLocationOnScreen {0} not reparented: {1} ",
971 new Object[] {String.valueOf(this), String.valueOf(location)});
972 return location;
973 }
974 } finally {
975 XToolkit.awtUnlock();
976 }
977 }
978
979
980 /***************************************************************************************
981 * END OF I N S E T S C O D E
982 **************************************************************************************/
983
984 protected boolean isEventDisabled(XEvent e) {
985 switch (e.get_type()) {
986 // Do not generate MOVED/RESIZED events since we generate them by ourselves
987 case ConfigureNotify:
988 return true;
989 case EnterNotify:
990 case LeaveNotify:
991 // Disable crossing event on outer borders of Frame so
1062 }
1063 }
1064
1065 private void handleWmTakeFocus(XClientMessageEvent cl) {
1066 if (focusLog.isLoggable(Level.FINE)) {
1067 focusLog.log(Level.FINE, "WM_TAKE_FOCUS on {0}",
1068 new Object[]{String.valueOf(this)});
1069 }
1070 requestWindowFocus(cl.get_data(1), true);
1071 }
1072
1073 /**
1074 * Requests focus to this decorated top-level by requesting X input focus
1075 * to the shell window.
1076 */
1077 protected void requestXFocus(long time, boolean timeProvided) {
1078 // We have proxied focus mechanism - instead of shell the focus is held
1079 // by "proxy" - invisible mapped window. When we want to set X input focus to
1080 // toplevel set it on proxy instead.
1081 if (focusProxy == null) {
1082 if (focusLog.isLoggable(Level.FINE)) focusLog.warning("Focus proxy is null for " + this);
1083 } else {
1084 if (focusLog.isLoggable(Level.FINE)) focusLog.fine("Requesting focus to proxy: " + focusProxy);
1085 if (timeProvided) {
1086 focusProxy.xRequestFocus(time);
1087 } else {
1088 focusProxy.xRequestFocus();
1089 }
1090 }
1091 }
1092
1093 XFocusProxyWindow getFocusProxy() {
1094 return focusProxy;
1095 }
1096
1097 public void handleQuit() {
1098 postEvent(new WindowEvent((Window)target, WindowEvent.WINDOW_CLOSING));
1099 }
1100
1101 final void dumpMe() {
1102 System.err.println(">>> Peer: " + x + ", " + y + ", " + width + ", " + height);
1103 }
1104
1156 dumpContent();
1157 }
1158
1159 boolean isMaximized() {
1160 return false;
1161 }
1162
1163 boolean isOverrideRedirect() {
1164 // return false;
1165 return ((XToolkit)Toolkit.getDefaultToolkit()).isOverrideRedirect((Window)target);
1166 }
1167
1168 public boolean requestWindowFocus(long time, boolean timeProvided) {
1169 focusLog.fine("Request for decorated window focus");
1170 // If this is Frame or Dialog we can't assure focus request success - but we still can try
1171 // If this is Window and its owner Frame is active we can be sure request succedded.
1172 Window win = (Window)target;
1173 Window focusedWindow = XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow();
1174 Window activeWindow = XWindowPeer.getDecoratedOwner(focusedWindow);
1175
1176 focusLog.log(Level.FINER, "Current window is: active={0}, focused={1}",
1177 new Object[]{ Boolean.valueOf(win == activeWindow),
1178 Boolean.valueOf(win == focusedWindow)});
1179
1180 XWindowPeer toFocus = this;
1181 while (toFocus.nextTransientFor != null) {
1182 toFocus = toFocus.nextTransientFor;
1183 }
1184
1185 if (this == toFocus) {
1186 if (focusAllowedFor()) {
1187 if (win == activeWindow && win != focusedWindow) {
1188 // Happens when focus is on window child
1189 focusLog.fine("Focus is on child window - transfering it back");
1190 handleWindowFocusInSync(-1);
1191 } else {
1192 focusLog.fine("Requesting focus to this window");
1193 if (timeProvided) {
1194 requestXFocus(time);
1195 } else {
1196 requestXFocus();
1197 }
1198 }
1199 return true;
1200 } else {
1201 return false;
1202 }
1203 }
1204 else if (toFocus.focusAllowedFor()) {
1205 focusLog.fine("Requesting focus to " + toFocus);
1206 if (timeProvided) {
1207 toFocus.requestXFocus(time);
1208 } else {
1209 toFocus.requestXFocus();
1210 }
1211 return false;
1212 }
1213 else
1214 {
1215 // This might change when WM will have property to determine focus policy.
1216 // Right now, because policy is unknown we can't be sure we succedded
1217 return false;
1218 }
1219 }
1220
1221 XWindowPeer actualFocusedWindow = null;
1222 void setActualFocusedWindow(XWindowPeer actualFocusedWindow) {
1223 synchronized(getStateLock()) {
1224 this.actualFocusedWindow = actualFocusedWindow;
1225 }
|
180
181 XFocusProxyWindow createFocusProxy() {
182 return new XFocusProxyWindow(this);
183 }
184
185 protected XAtomList getWMProtocols() {
186 XAtomList protocols = super.getWMProtocols();
187 protocols.add(wm_delete_window);
188 protocols.add(wm_take_focus);
189 return protocols;
190 }
191
192 public Graphics getGraphics() {
193 return getGraphics(content.surfaceData,
194 ComponentAccessor.getForeground(target),
195 ComponentAccessor.getBackground(target),
196 ComponentAccessor.getFont_NoClientCode(target));
197 }
198
199 public void setTitle(String title) {
200 if (log.isLoggable(Level.FINE)) {
201 log.fine("Title is " + title);
202 }
203 winAttr.title = title;
204 updateWMName();
205 }
206
207 protected String getWMName() {
208 if (winAttr.title == null || winAttr.title.trim().equals("")) {
209 return " ";
210 } else {
211 return winAttr.title;
212 }
213 }
214
215 void updateWMName() {
216 super.updateWMName();
217 String name = getWMName();
218 XToolkit.awtLock();
219 try {
220 if (name == null || name.trim().equals("")) {
221 name = "Java";
222 }
230 }
231
232 // NOTE: This method may be called by privileged threads.
233 // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
234 public void handleIconify() {
235 postEvent(new WindowEvent((Window)target, WindowEvent.WINDOW_ICONIFIED));
236 }
237
238 // NOTE: This method may be called by privileged threads.
239 // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
240 public void handleDeiconify() {
241 postEvent(new WindowEvent((Window)target, WindowEvent.WINDOW_DEICONIFIED));
242 }
243
244 public void handleFocusEvent(XEvent xev) {
245 super.handleFocusEvent(xev);
246 XFocusChangeEvent xfe = xev.get_xfocus();
247
248 // If we somehow received focus events forward it instead to proxy
249 // FIXME: Shouldn't we instead check for inferrior?
250 if (focusLog.isLoggable(Level.FINER)) {
251 focusLog.finer("Received focus event on shell: " + xfe);
252 }
253 // focusProxy.xRequestFocus();
254 }
255
256 /***************************************************************************************
257 * I N S E T S C O D E
258 **************************************************************************************/
259
260 protected boolean isInitialReshape() {
261 return false;
262 }
263
264 Insets difference(Insets i1, Insets i2) {
265 return new Insets(i1.top-i2.top, i1.left - i2.left, i1.bottom-i2.bottom, i1.right-i2.right);
266 }
267
268 void add(Insets i1, Insets i2) {
269 i1.left += i2.left;
270 i1.top += i2.top;
271 i1.right += i2.right;
272 i1.bottom += i2.bottom;
273 }
274 boolean isNull(Insets i) {
275 return (i == null) || ((i.left | i.top | i.right | i.bottom) == 0);
276 }
277 Insets copy(Insets i) {
278 return new Insets(i.top, i.left, i.bottom, i.right);
279 }
280
281 long reparent_serial = 0;
282
283 public void handleReparentNotifyEvent(XEvent xev) {
284 XReparentEvent xe = xev.get_xreparent();
285 if (insLog.isLoggable(Level.FINE)) {
286 insLog.fine(xe.toString());
287 }
288 reparent_serial = xe.get_serial();
289 XToolkit.awtLock();
290 try {
291 long root = XlibWrapper.RootWindow(XToolkit.getDisplay(), getScreenNumber());
292
293 if (isEmbedded()) {
294 setReparented(true);
295 insets_corrected = true;
296 return;
297 }
298 Component t = (Component)target;
299 if (getDecorations() == winAttr.AWT_DECOR_NONE) {
300 setReparented(true);
301 insets_corrected = true;
302 reshape(dimensions, SET_SIZE, false);
303 } else if (xe.get_parent() == root) {
304 configure_seen = false;
305 insets_corrected = false;
306
307 /*
313 /* Work around 4775545 */
314 XWM.getWM().unshadeKludge(this);
315 insLog.fine("- WM exited");
316 } else {
317 insLog.fine(" - reparent due to hide");
318 }
319 } else { /* reparented to WM frame, figure out our insets */
320 setReparented(true);
321 insets_corrected = false;
322
323 // Check if we have insets provided by the WM
324 Insets correctWM = getWMSetInsets(null);
325 if (correctWM != null) {
326 if (insLog.isLoggable(Level.FINER)) {
327 insLog.log(Level.FINER, "wm-provided insets {0}",
328 new Object[]{String.valueOf(correctWM)});
329 }
330 // If these insets are equal to our current insets - no actions are necessary
331 Insets dimInsets = dimensions.getInsets();
332 if (correctWM.equals(dimInsets)) {
333 if (insLog.isLoggable(Level.FINER)) {
334 insLog.finer("Insets are the same as estimated - no additional reshapes necessary");
335 }
336 no_reparent_artifacts = true;
337 insets_corrected = true;
338 applyGuessedInsets();
339 return;
340 }
341 } else {
342 correctWM = XWM.getWM().getInsets(this, xe.get_window(), xe.get_parent());
343
344 if (insLog.isLoggable(Level.FINER)) {
345 if (correctWM != null) {
346 insLog.log(Level.FINER, "correctWM {0}",
347 new Object[] {String.valueOf(correctWM)});
348 } else {
349 insLog.log(Level.FINER, "correctWM insets are not available, waiting for configureNotify");
350 }
351 }
352 }
353
354 if (correctWM != null) {
355 handleCorrectInsets(correctWM);
356 }
357 }
358 } finally {
359 XToolkit.awtUnlock();
360 }
361 }
362
363 protected void handleCorrectInsets(Insets correctWM) {
364 XToolkit.awtLock();
365 try {
366 /*
367 * Ok, now see if we need adjust window size because
368 * initial insets were wrong (most likely they were).
369 */
370 Insets correction = difference(correctWM, currentInsets);
371 if (insLog.isLoggable(Level.FINEST)) {
372 insLog.log(Level.FINEST, "Corrention {0}", new Object[] {String.valueOf(correction)});
374 if (!isNull(correction)) {
375 /*
376 * Actual insets account for menubar/warning label,
377 * so we can't assign directly but must adjust them.
378 */
379 add(currentInsets, correction);
380 applyGuessedInsets();
381
382 //Fix for 6318109: PIT: Min Size is not honored properly when a
383 //smaller size is specified in setSize(), XToolkit
384 //update minimum size hints
385 updateMinSizeHints();
386
387 /*
388 * If this window has been sized by a pack() we need
389 * to keep the interior geometry intact. Since pack()
390 * computed width and height with wrong insets, we
391 * must adjust the target dimensions appropriately.
392 */
393 }
394 if (insLog.isLoggable(Level.FINER)) {
395 insLog.finer("Dimensions before reparent: " + dimensions);
396 }
397
398 dimensions.setInsets(getRealInsets());
399 insets_corrected = true;
400
401 if (isMaximized()) {
402 return;
403 }
404
405 if ((getHints().get_flags() & (USPosition | PPosition)) != 0) {
406 reshape(dimensions, SET_BOUNDS, false);
407 } else {
408 reshape(dimensions, SET_SIZE, false);
409 }
410 } finally {
411 XToolkit.awtUnlock();
412 }
413 }
414
415 public void handleMoved(WindowDimensions dims) {
416 Point loc = dims.getLocation();
498 }
499 if (userReshape) {
500 // We handle only userReshape == true cases. It means that
501 // if the window manager or any other part of the windowing
502 // system sets inappropriate size for this window, we can
503 // do nothing but accept it.
504 Rectangle reqBounds = newDimensions.getBounds();
505 Rectangle newBounds = constrainBounds(reqBounds.x, reqBounds.y, reqBounds.width, reqBounds.height);
506 Insets insets = newDimensions.getInsets();
507 // Inherit isClientSizeSet from newDimensions
508 if (newDimensions.isClientSizeSet()) {
509 newBounds = new Rectangle(newBounds.x, newBounds.y,
510 newBounds.width - insets.left - insets.right,
511 newBounds.height - insets.top - insets.bottom);
512 }
513 newDimensions = new WindowDimensions(newBounds, insets, newDimensions.isClientSizeSet());
514 }
515 XToolkit.awtLock();
516 try {
517 if (!isReparented() || !isVisible()) {
518 if (insLog.isLoggable(Level.FINE)) {
519 insLog.log(Level.FINE, "- not reparented({0}) or not visible({1}), default reshape",
520 new Object[] {Boolean.valueOf(isReparented()), Boolean.valueOf(visible)});
521 }
522
523 // Fix for 6323293.
524 // This actually is needed to preserve compatibility with previous releases -
525 // some of licensees are expecting componentMoved event on invisible one while
526 // its location changes.
527 Point oldLocation = getLocation();
528
529 Point newLocation = new Point(ComponentAccessor.getX((Component)target),
530 ComponentAccessor.getY((Component)target));
531
532 if (!newLocation.equals(oldLocation)) {
533 handleMoved(newDimensions);
534 }
535
536 dimensions = new WindowDimensions(newDimensions);
537 updateSizeHints(dimensions);
538 Rectangle client = dimensions.getClientRect();
539 checkShellRect(client);
540 setShellBounds(client);
541 if (content != null &&
775 ComponentAccessor.getHeight((Component)target));
776
777 Point newLocation = targetBounds.getLocation();
778 if (xe.get_send_event() || runningWM == XWM.NO_WM || XWM.isNonReparentingWM()) {
779 // Location, Client size + insets
780 newLocation = new Point(xe.get_x() - currentInsets.left, xe.get_y() - currentInsets.top);
781 } else {
782 // CDE/MWM/Metacity/Sawfish bug: if shell is resized using
783 // top or left border, we don't receive synthetic
784 // ConfigureNotify, only the one from X with zero
785 // coordinates. This is the workaround to get real
786 // location, 6261336
787 switch (XWM.getWMID()) {
788 case XWM.CDE_WM:
789 case XWM.MOTIF_WM:
790 case XWM.METACITY_WM:
791 case XWM.SAWFISH_WM:
792 {
793 Point xlocation = queryXLocation();
794 if (log.isLoggable(Level.FINE)) {
795 log.log(Level.FINE, "New X location: {0}",
796 new Object[]{String.valueOf(xlocation)});
797 }
798 if (xlocation != null) {
799 newLocation = xlocation;
800 }
801 break;
802 }
803 default:
804 break;
805 }
806 }
807
808 WindowDimensions newDimensions =
809 new WindowDimensions(newLocation,
810 new Dimension(xe.get_width(), xe.get_height()),
811 copy(currentInsets),
812 true);
813
814 if (insLog.isLoggable(Level.FINER)) {
815 insLog.log(Level.FINER, "Insets are {0}, new dimensions {1}",
816 new Object[] {String.valueOf(currentInsets), String.valueOf(newDimensions)});
836 if (shellRect.height < 0) {
837 shellRect.height = 1;
838 }
839 }
840
841 private void checkShellRectPos(Rectangle shellRect) {
842 int wm = XWM.getWMID();
843 if (wm == XWM.MOTIF_WM || wm == XWM.CDE_WM) {
844 if (shellRect.x == 0 && shellRect.y == 0) {
845 shellRect.x = shellRect.y = 1;
846 }
847 }
848 }
849
850 private void checkShellRect(Rectangle shellRect) {
851 checkShellRectSize(shellRect);
852 checkShellRectPos(shellRect);
853 }
854
855 public void setShellBounds(Rectangle rec) {
856 if (insLog.isLoggable(Level.FINE)) {
857 insLog.fine("Setting shell bounds on " + this + " to " + rec);
858 }
859 XToolkit.awtLock();
860 try {
861 updateSizeHints(rec.x, rec.y, rec.width, rec.height);
862 XlibWrapper.XResizeWindow(XToolkit.getDisplay(), getShell(), rec.width, rec.height);
863 XlibWrapper.XMoveWindow(XToolkit.getDisplay(), getShell(), rec.x, rec.y);
864 }
865 finally {
866 XToolkit.awtUnlock();
867 }
868 }
869 public void setShellSize(Rectangle rec) {
870 if (insLog.isLoggable(Level.FINE)) {
871 insLog.fine("Setting shell size on " + this + " to " + rec);
872 }
873 XToolkit.awtLock();
874 try {
875 updateSizeHints(rec.x, rec.y, rec.width, rec.height);
876 XlibWrapper.XResizeWindow(XToolkit.getDisplay(), getShell(), rec.width, rec.height);
877 }
878 finally {
879 XToolkit.awtUnlock();
880 }
881 }
882 public void setShellPosition(Rectangle rec) {
883 if (insLog.isLoggable(Level.FINE)) {
884 insLog.fine("Setting shell position on " + this + " to " + rec);
885 }
886 XToolkit.awtLock();
887 try {
888 updateSizeHints(rec.x, rec.y, rec.width, rec.height);
889 XlibWrapper.XMoveWindow(XToolkit.getDisplay(), getShell(), rec.x, rec.y);
890 }
891 finally {
892 XToolkit.awtUnlock();
893 }
894 }
895
896 void initResizability() {
897 setResizable(winAttr.initialResizability);
898 }
899 public void setResizable(boolean resizable) {
900 int fs = winAttr.functions;
901 if (!isResizable() && resizable) {
902 insets = currentInsets = new Insets(0, 0, 0, 0);
903 resetWMSetInsets();
904 if (!isEmbedded()) {
905 setReparented(false);
965
966 public int getWidth() {
967 return getSize().width;
968 }
969
970 public int getHeight() {
971 return getSize().height;
972 }
973
974 public WindowDimensions getDimensions() {
975 return dimensions;
976 }
977
978 public Point getLocationOnScreen() {
979 XToolkit.awtLock();
980 try {
981 if (configure_seen) {
982 return toGlobal(0,0);
983 } else {
984 Point location = target.getLocation();
985 if (insLog.isLoggable(Level.FINE)) {
986 insLog.log(Level.FINE, "getLocationOnScreen {0} not reparented: {1} ",
987 new Object[] {String.valueOf(this), String.valueOf(location)});
988 }
989 return location;
990 }
991 } finally {
992 XToolkit.awtUnlock();
993 }
994 }
995
996
997 /***************************************************************************************
998 * END OF I N S E T S C O D E
999 **************************************************************************************/
1000
1001 protected boolean isEventDisabled(XEvent e) {
1002 switch (e.get_type()) {
1003 // Do not generate MOVED/RESIZED events since we generate them by ourselves
1004 case ConfigureNotify:
1005 return true;
1006 case EnterNotify:
1007 case LeaveNotify:
1008 // Disable crossing event on outer borders of Frame so
1079 }
1080 }
1081
1082 private void handleWmTakeFocus(XClientMessageEvent cl) {
1083 if (focusLog.isLoggable(Level.FINE)) {
1084 focusLog.log(Level.FINE, "WM_TAKE_FOCUS on {0}",
1085 new Object[]{String.valueOf(this)});
1086 }
1087 requestWindowFocus(cl.get_data(1), true);
1088 }
1089
1090 /**
1091 * Requests focus to this decorated top-level by requesting X input focus
1092 * to the shell window.
1093 */
1094 protected void requestXFocus(long time, boolean timeProvided) {
1095 // We have proxied focus mechanism - instead of shell the focus is held
1096 // by "proxy" - invisible mapped window. When we want to set X input focus to
1097 // toplevel set it on proxy instead.
1098 if (focusProxy == null) {
1099 if (focusLog.isLoggable(Level.WARNING)) {
1100 focusLog.warning("Focus proxy is null for " + this);
1101 }
1102 } else {
1103 if (focusLog.isLoggable(Level.FINE)) {
1104 focusLog.fine("Requesting focus to proxy: " + focusProxy);
1105 }
1106 if (timeProvided) {
1107 focusProxy.xRequestFocus(time);
1108 } else {
1109 focusProxy.xRequestFocus();
1110 }
1111 }
1112 }
1113
1114 XFocusProxyWindow getFocusProxy() {
1115 return focusProxy;
1116 }
1117
1118 public void handleQuit() {
1119 postEvent(new WindowEvent((Window)target, WindowEvent.WINDOW_CLOSING));
1120 }
1121
1122 final void dumpMe() {
1123 System.err.println(">>> Peer: " + x + ", " + y + ", " + width + ", " + height);
1124 }
1125
1177 dumpContent();
1178 }
1179
1180 boolean isMaximized() {
1181 return false;
1182 }
1183
1184 boolean isOverrideRedirect() {
1185 // return false;
1186 return ((XToolkit)Toolkit.getDefaultToolkit()).isOverrideRedirect((Window)target);
1187 }
1188
1189 public boolean requestWindowFocus(long time, boolean timeProvided) {
1190 focusLog.fine("Request for decorated window focus");
1191 // If this is Frame or Dialog we can't assure focus request success - but we still can try
1192 // If this is Window and its owner Frame is active we can be sure request succedded.
1193 Window win = (Window)target;
1194 Window focusedWindow = XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow();
1195 Window activeWindow = XWindowPeer.getDecoratedOwner(focusedWindow);
1196
1197 if (focusLog.isLoggable(Level.FINER)) {
1198 focusLog.log(Level.FINER, "Current window is: active={0}, focused={1}",
1199 new Object[]{ Boolean.valueOf(win == activeWindow),
1200 Boolean.valueOf(win == focusedWindow)});
1201 }
1202
1203 XWindowPeer toFocus = this;
1204 while (toFocus.nextTransientFor != null) {
1205 toFocus = toFocus.nextTransientFor;
1206 }
1207
1208 if (this == toFocus) {
1209 if (focusAllowedFor()) {
1210 if (win == activeWindow && win != focusedWindow) {
1211 // Happens when focus is on window child
1212 if (focusLog.isLoggable(Level.FINE)) {
1213 focusLog.fine("Focus is on child window - transfering it back");
1214 }
1215 handleWindowFocusInSync(-1);
1216 } else {
1217 if (focusLog.isLoggable(Level.FINE)) {
1218 focusLog.fine("Requesting focus to this window");
1219 }
1220 if (timeProvided) {
1221 requestXFocus(time);
1222 } else {
1223 requestXFocus();
1224 }
1225 }
1226 return true;
1227 } else {
1228 return false;
1229 }
1230 }
1231 else if (toFocus.focusAllowedFor()) {
1232 if (focusLog.isLoggable(Level.FINE)) {
1233 focusLog.fine("Requesting focus to " + toFocus);
1234 }
1235 if (timeProvided) {
1236 toFocus.requestXFocus(time);
1237 } else {
1238 toFocus.requestXFocus();
1239 }
1240 return false;
1241 }
1242 else
1243 {
1244 // This might change when WM will have property to determine focus policy.
1245 // Right now, because policy is unknown we can't be sure we succedded
1246 return false;
1247 }
1248 }
1249
1250 XWindowPeer actualFocusedWindow = null;
1251 void setActualFocusedWindow(XWindowPeer actualFocusedWindow) {
1252 synchronized(getStateLock()) {
1253 this.actualFocusedWindow = actualFocusedWindow;
1254 }
|