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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package sun.awt.X11;
26
27 import java.awt.*;
28
29 import java.awt.event.ComponentEvent;
30 import java.awt.event.InvocationEvent;
31 import java.awt.event.WindowEvent;
32
33 import sun.awt.IconInfo;
34 import sun.util.logging.PlatformLogger;
35
36 import sun.awt.AWTAccessor;
37 import sun.awt.SunToolkit;
38
39 abstract class XDecoratedPeer extends XWindowPeer {
40 private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11.XDecoratedPeer");
41 private static final PlatformLogger insLog = PlatformLogger.getLogger("sun.awt.X11.insets.XDecoratedPeer");
42 private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.awt.X11.focus.XDecoratedPeer");
43 private static final PlatformLogger iconLog = PlatformLogger.getLogger("sun.awt.X11.icon.XDecoratedPeer");
44
45 // Set to true when we get the first ConfigureNotify after being
46 // reparented - indicates that WM has adopted the top-level.
47 boolean configure_seen;
48 boolean insets_corrected;
49
50 XIconWindow iconWindow;
51 WindowDimensions dimensions;
52 XContentWindow content;
53 Insets currentInsets;
54 XFocusProxyWindow focusProxy;
55
56 XDecoratedPeer(Window target) {
57 super(target);
58 }
59
60 XDecoratedPeer(XCreateWindowParams params) {
61 super(params);
62 }
63
64 public long getShell() {
65 return window;
66 }
67
68 public long getContentWindow() {
69 return (content == null) ? window : content.getWindow();
70 }
71
72 void preInit(XCreateWindowParams params) {
73 super.preInit(params);
74 winAttr.initialFocus = true;
75
76 currentInsets = new Insets(0,0,0,0);
77 applyGuessedInsets();
78
79 Rectangle bounds = (Rectangle)params.get(BOUNDS);
80 dimensions = new WindowDimensions(bounds, getRealInsets(), false);
81 params.put(BOUNDS, dimensions.getClientRect());
82 if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
83 insLog.fine("Initial dimensions {0}", dimensions);
84 }
85
86 // Deny default processing of these events on the shell - proxy will take care of
87 // them instead
88 Long eventMask = (Long)params.get(EVENT_MASK);
89 params.add(EVENT_MASK, Long.valueOf(eventMask.longValue() & ~(XConstants.FocusChangeMask | XConstants.KeyPressMask | XConstants.KeyReleaseMask)));
90 }
91
92 void postInit(XCreateWindowParams params) {
93 // The size hints must be set BEFORE mapping the window (see 6895647)
94 updateSizeHints(dimensions);
95
96 // The super method maps the window if it's visible on the shared level
280 insLog.finer("FRAME_EXTENTS: {0}", wm_set_insets);
281 }
282
283 if (wm_set_insets != null) {
284 wm_set_insets = copy(wm_set_insets);
285 }
286 return wm_set_insets;
287 }
288
289 private void resetWMSetInsets() {
290 wm_set_insets = null;
291 }
292
293 public void handlePropertyNotify(XEvent xev) {
294 super.handlePropertyNotify(xev);
295
296 XPropertyEvent ev = xev.get_xproperty();
297 if (ev.get_atom() == XWM.XA_KDE_NET_WM_FRAME_STRUT.getAtom()
298 || ev.get_atom() == XWM.XA_NET_FRAME_EXTENTS.getAtom())
299 {
300 getWMSetInsets(XAtom.get(ev.get_atom()));
301 }
302 }
303
304 long reparent_serial = 0;
305
306 public void handleReparentNotifyEvent(XEvent xev) {
307 XReparentEvent xe = xev.get_xreparent();
308 if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
309 insLog.fine(xe.toString());
310 }
311 reparent_serial = xe.get_serial();
312 XToolkit.awtLock();
313 try {
314 long root = XlibWrapper.RootWindow(XToolkit.getDisplay(), getScreenNumber());
315
316 if (isEmbedded()) {
317 setReparented(true);
318 insets_corrected = true;
319 return;
320 }
353 Insets dimInsets = dimensions.getInsets();
354 if (correctWM.equals(dimInsets)) {
355 insLog.finer("Insets are the same as estimated - no additional reshapes necessary");
356 no_reparent_artifacts = true;
357 insets_corrected = true;
358 applyGuessedInsets();
359 return;
360 }
361 } else {
362 correctWM = XWM.getWM().getInsets(this, xe.get_window(), xe.get_parent());
363
364 if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
365 if (correctWM != null) {
366 insLog.finer("correctWM {0}", correctWM);
367 } else {
368 insLog.finer("correctWM insets are not available, waiting for configureNotify");
369 }
370 }
371 }
372
373 if (correctWM != null) {
374 handleCorrectInsets(correctWM);
375 }
376 }
377 } finally {
378 XToolkit.awtUnlock();
379 }
380 }
381
382 protected void handleCorrectInsets(Insets correctWM) {
383 XToolkit.awtLock();
384 try {
385 /*
386 * Ok, now see if we need adjust window size because
387 * initial insets were wrong (most likely they were).
388 */
389 Insets correction = difference(correctWM, currentInsets);
390 if (insLog.isLoggable(PlatformLogger.Level.FINEST)) {
391 insLog.finest("Corrention {0}", correction);
392 }
393 if (!isNull(correction)) {
647 /**
648 * @see java.awt.peer.ComponentPeer#setBounds
649 */
650 public void setBounds(int x, int y, int width, int height, int op) {
651 // TODO: Rewrite with WindowDimensions
652 reshape(x, y, width, height, op, true);
653 validateSurface();
654 }
655
656 // Coordinates are that of the shell
657 void reconfigureContentWindow(WindowDimensions dims) {
658 if (content == null) {
659 insLog.fine("WARNING: Content window is null");
660 return;
661 }
662 content.setContentBounds(dims);
663 }
664
665 boolean no_reparent_artifacts = false;
666 public void handleConfigureNotifyEvent(XEvent xev) {
667 assert (SunToolkit.isAWTLockHeldByCurrentThread());
668 XConfigureEvent xe = xev.get_xconfigure();
669 if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
670 insLog.fine("Configure notify {0}", xe);
671 }
672
673 // XXX: should really only consider synthetic events, but
674 if (isReparented()) {
675 configure_seen = true;
676 }
677
678 if (!isMaximized()
679 && (xe.get_serial() == reparent_serial || xe.get_window() != getShell())
680 && !no_reparent_artifacts)
681 {
682 insLog.fine("- reparent artifact, skipping");
683 return;
684 }
685 no_reparent_artifacts = false;
686
|
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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package sun.awt.X11;
26
27 import java.awt.*;
28
29 import java.awt.event.ComponentEvent;
30 import java.awt.event.InvocationEvent;
31 import java.awt.event.WindowEvent;
32 import java.util.Collections;
33 import java.util.HashMap;
34 import java.util.Map;
35
36 import sun.awt.IconInfo;
37 import sun.util.logging.PlatformLogger;
38
39 import sun.awt.AWTAccessor;
40 import sun.awt.SunToolkit;
41
42 abstract class XDecoratedPeer extends XWindowPeer {
43 private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11.XDecoratedPeer");
44 private static final PlatformLogger insLog = PlatformLogger.getLogger("sun.awt.X11.insets.XDecoratedPeer");
45 private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.awt.X11.focus.XDecoratedPeer");
46 private static final PlatformLogger iconLog = PlatformLogger.getLogger("sun.awt.X11.icon.XDecoratedPeer");
47
48 // Set to true when we get the first ConfigureNotify after being
49 // reparented - indicates that WM has adopted the top-level.
50 boolean configure_seen;
51 boolean insets_corrected;
52
53 XIconWindow iconWindow;
54 WindowDimensions dimensions;
55 XContentWindow content;
56 Insets currentInsets;
57 XFocusProxyWindow focusProxy;
58 static final Map<Class<?>,Insets> lastKnownInsets =
59 Collections.synchronizedMap(new HashMap<>());
60
61 XDecoratedPeer(Window target) {
62 super(target);
63 }
64
65 XDecoratedPeer(XCreateWindowParams params) {
66 super(params);
67 }
68
69 public long getShell() {
70 return window;
71 }
72
73 public long getContentWindow() {
74 return (content == null) ? window : content.getWindow();
75 }
76
77 void preInit(XCreateWindowParams params) {
78 super.preInit(params);
79 winAttr.initialFocus = true;
80
81 currentInsets = new Insets(0,0,0,0);
82 if (XWM.getWMID() == XWM.UNITY_COMPIZ_WM) {
83 currentInsets = lastKnownInsets.get(getClass());
84 }
85 applyGuessedInsets();
86
87 Rectangle bounds = (Rectangle)params.get(BOUNDS);
88 dimensions = new WindowDimensions(bounds, getRealInsets(), false);
89 params.put(BOUNDS, dimensions.getClientRect());
90 if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
91 insLog.fine("Initial dimensions {0}", dimensions);
92 }
93
94 // Deny default processing of these events on the shell - proxy will take care of
95 // them instead
96 Long eventMask = (Long)params.get(EVENT_MASK);
97 params.add(EVENT_MASK, Long.valueOf(eventMask.longValue() & ~(XConstants.FocusChangeMask | XConstants.KeyPressMask | XConstants.KeyReleaseMask)));
98 }
99
100 void postInit(XCreateWindowParams params) {
101 // The size hints must be set BEFORE mapping the window (see 6895647)
102 updateSizeHints(dimensions);
103
104 // The super method maps the window if it's visible on the shared level
288 insLog.finer("FRAME_EXTENTS: {0}", wm_set_insets);
289 }
290
291 if (wm_set_insets != null) {
292 wm_set_insets = copy(wm_set_insets);
293 }
294 return wm_set_insets;
295 }
296
297 private void resetWMSetInsets() {
298 wm_set_insets = null;
299 }
300
301 public void handlePropertyNotify(XEvent xev) {
302 super.handlePropertyNotify(xev);
303
304 XPropertyEvent ev = xev.get_xproperty();
305 if (ev.get_atom() == XWM.XA_KDE_NET_WM_FRAME_STRUT.getAtom()
306 || ev.get_atom() == XWM.XA_NET_FRAME_EXTENTS.getAtom())
307 {
308 if (XWM.getWMID() != XWM.UNITY_COMPIZ_WM) {
309 getWMSetInsets(XAtom.get(ev.get_atom()));
310 } else {
311 if(!isReparented()) {
312 return;
313 }
314 wm_set_insets = null;
315 Insets in = getWMSetInsets(XAtom.get(ev.get_atom()));
316 if (isNull(in)) {
317 return;
318 }
319 if (!isEmbedded() && !isTargetUndecorated()) {
320 lastKnownInsets.put(getClass(), in);
321 }
322 if (!in.equals(dimensions.getInsets())) {
323 handleCorrectInsets(in);
324 }
325 insets_corrected = true;
326 }
327 }
328 }
329
330 long reparent_serial = 0;
331
332 public void handleReparentNotifyEvent(XEvent xev) {
333 XReparentEvent xe = xev.get_xreparent();
334 if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
335 insLog.fine(xe.toString());
336 }
337 reparent_serial = xe.get_serial();
338 XToolkit.awtLock();
339 try {
340 long root = XlibWrapper.RootWindow(XToolkit.getDisplay(), getScreenNumber());
341
342 if (isEmbedded()) {
343 setReparented(true);
344 insets_corrected = true;
345 return;
346 }
379 Insets dimInsets = dimensions.getInsets();
380 if (correctWM.equals(dimInsets)) {
381 insLog.finer("Insets are the same as estimated - no additional reshapes necessary");
382 no_reparent_artifacts = true;
383 insets_corrected = true;
384 applyGuessedInsets();
385 return;
386 }
387 } else {
388 correctWM = XWM.getWM().getInsets(this, xe.get_window(), xe.get_parent());
389
390 if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
391 if (correctWM != null) {
392 insLog.finer("correctWM {0}", correctWM);
393 } else {
394 insLog.finer("correctWM insets are not available, waiting for configureNotify");
395 }
396 }
397 }
398
399 if (correctWM != null && XWM.getWMID() != XWM.UNITY_COMPIZ_WM) {
400 handleCorrectInsets(correctWM);
401 }
402 }
403 } finally {
404 XToolkit.awtUnlock();
405 }
406 }
407
408 protected void handleCorrectInsets(Insets correctWM) {
409 XToolkit.awtLock();
410 try {
411 /*
412 * Ok, now see if we need adjust window size because
413 * initial insets were wrong (most likely they were).
414 */
415 Insets correction = difference(correctWM, currentInsets);
416 if (insLog.isLoggable(PlatformLogger.Level.FINEST)) {
417 insLog.finest("Corrention {0}", correction);
418 }
419 if (!isNull(correction)) {
673 /**
674 * @see java.awt.peer.ComponentPeer#setBounds
675 */
676 public void setBounds(int x, int y, int width, int height, int op) {
677 // TODO: Rewrite with WindowDimensions
678 reshape(x, y, width, height, op, true);
679 validateSurface();
680 }
681
682 // Coordinates are that of the shell
683 void reconfigureContentWindow(WindowDimensions dims) {
684 if (content == null) {
685 insLog.fine("WARNING: Content window is null");
686 return;
687 }
688 content.setContentBounds(dims);
689 }
690
691 boolean no_reparent_artifacts = false;
692 public void handleConfigureNotifyEvent(XEvent xev) {
693 if (XWM.getWMID() == XWM.UNITY_COMPIZ_WM && !insets_corrected) {
694 return;
695 }
696 assert (SunToolkit.isAWTLockHeldByCurrentThread());
697 XConfigureEvent xe = xev.get_xconfigure();
698 if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
699 insLog.fine("Configure notify {0}", xe);
700 }
701
702 // XXX: should really only consider synthetic events, but
703 if (isReparented()) {
704 configure_seen = true;
705 }
706
707 if (!isMaximized()
708 && (xe.get_serial() == reparent_serial || xe.get_window() != getShell())
709 && !no_reparent_artifacts)
710 {
711 insLog.fine("- reparent artifact, skipping");
712 return;
713 }
714 no_reparent_artifacts = false;
715
|