76 canvas = new TrayIconCanvas(target, TRAY_ICON_WIDTH, TRAY_ICON_HEIGHT);
77
78 eframe = new XTrayIconEmbeddedFrame();
79
80 eframe.setSize(TRAY_ICON_WIDTH, TRAY_ICON_HEIGHT);
81 eframe.add(canvas);
82
83 // Fix for 6317038: as EmbeddedFrame is instance of Frame, it is blocked
84 // by modal dialogs, but in the case of TrayIcon it shouldn't. So we
85 // set ModalExclusion property on it.
86 AccessController.doPrivileged(new PrivilegedAction<Object>() {
87 public Object run() {
88 eframe.setModalExclusionType(Dialog.ModalExclusionType.TOOLKIT_EXCLUDE);
89 return null;
90 }
91 });
92
93
94 if (XWM.getWMID() != XWM.METACITY_WM) {
95 parentXED = dummyXED; // We don't like to leave it 'null'.
96
97 } else {
98 parentXED = new XEventDispatcher() {
99 // It's executed under AWTLock.
100 public void dispatchEvent(XEvent ev) {
101 if (isDisposed() || ev.get_type() != XConstants.ConfigureNotify) {
102 return;
103 }
104
105 XConfigureEvent ce = ev.get_xconfigure();
106
107 if (ctrLog.isLoggable(PlatformLogger.Level.FINE)) {
108 ctrLog.fine("ConfigureNotify on parent of {0}: {1}x{2}+{3}+{4} (old: {5}+{6})",
109 XTrayIconPeer.this, ce.get_width(), ce.get_height(),
110 ce.get_x(), ce.get_y(), old_x, old_y);
111 }
112
113 // A workaround for Gnome/Metacity (it doesn't affect the behaviour on KDE).
114 // On Metacity the EmbeddedFrame's parent window bounds are larger
115 // than TrayIcon size required (that is we need a square but a rectangle
116 // is provided by the Panel Notification Area). The parent's background color
283 SunToolkit.executeOnEDTAndWait(target, new Runnable() {
284 public void run() {
285 disposeOnEDT();
286 }
287 });
288 } catch (InterruptedException ie) {
289 } catch (InvocationTargetException ite) {}
290 }
291 }
292
293 private void disposeOnEDT() {
294 // All actions that is to be synchronized with disposal
295 // should be executed either under AWTLock, or on EDT.
296 // isDisposed value must be checked.
297 XToolkit.awtLock();
298 isDisposed = true;
299 XToolkit.awtUnlock();
300
301 removeXED(getWindow(), eframeXED);
302 removeXED(eframeParentID, parentXED);
303 eframe.realDispose();
304 balloon.dispose();
305 isTrayIconDisplayed = false;
306 XToolkit.targetDisposedPeer(target, this);
307 }
308
309 public static void suppressWarningString(Window w) {
310 AWTAccessor.getWindowAccessor().setTrayIconWindow(w, true);
311 }
312
313 public void setToolTip(String tooltip) {
314 tooltipString = tooltip;
315 }
316
317 public String getTooltipString() {
318 return tooltipString;
319 }
320
321 public void updateImage() {
322 Runnable r = new Runnable() {
323 public void run() {
324 canvas.updateImage(target.getImage());
325 }
326 };
399 XToolkit.awtUnlock();
400 }
401 }
402
403 // Private method for testing purposes.
404 private Point getLocationOnScreen() {
405 return eframe.getLocationOnScreen();
406 }
407
408 public Rectangle getBounds() {
409 Point loc = getLocationOnScreen();
410 return new Rectangle(loc.x, loc.y, loc.x + TRAY_ICON_WIDTH, loc.y + TRAY_ICON_HEIGHT);
411 }
412
413 void addListeners() {
414 canvas.addMouseListener(eventProxy);
415 canvas.addMouseMotionListener(eventProxy);
416 eframe.addMouseListener(eventProxy);
417 }
418
419 long getWindow() {
420 return AWTAccessor.getComponentAccessor()
421 .<XEmbeddedFramePeer>getPeer(eframe).getWindow();
422 }
423
424 public boolean isDisposed() {
425 return isDisposed;
426 }
427
428 public String getActionCommand() {
429 return target.getActionCommand();
430 }
431
432 static class TrayIconEventProxy implements MouseListener, MouseMotionListener {
433 XTrayIconPeer xtiPeer;
434
435 TrayIconEventProxy(XTrayIconPeer xtiPeer) {
436 this.xtiPeer = xtiPeer;
437 }
438
533 @SuppressWarnings("serial") // JDK-implementation class
534 static class TrayIconCanvas extends IconCanvas {
535 TrayIcon target;
536 boolean autosize;
537
538 TrayIconCanvas(TrayIcon target, int width, int height) {
539 super(width, height);
540 this.target = target;
541 }
542
543 // Invoke on EDT.
544 protected void repaintImage(boolean doClear) {
545 boolean old_autosize = autosize;
546 autosize = target.isImageAutoSize();
547
548 curW = autosize ? width : image.getWidth(observer);
549 curH = autosize ? height : image.getHeight(observer);
550
551 super.repaintImage(doClear || (old_autosize != autosize));
552 }
553 }
554
555 @SuppressWarnings("serial") // JDK-implementation class
556 public static class IconCanvas extends Canvas {
557 volatile Image image;
558 IconObserver observer;
559 int width, height;
560 int curW, curH;
561
562 IconCanvas(int width, int height) {
563 this.width = curW = width;
564 this.height = curH = height;
565 }
566
567 // Invoke on EDT.
568 public void updateImage(Image image) {
569 this.image = image;
570 if (observer == null) {
571 observer = new IconObserver();
572 }
573 repaintImage(true);
574 }
575
576 // Invoke on EDT.
577 protected void repaintImage(boolean doClear) {
578 Graphics g = getGraphics();
579 if (g != null) {
580 try {
581 if (isVisible()) {
582 if (doClear) {
583 update(g);
584 } else {
585 paint(g);
586 }
587 }
588 } finally {
589 g.dispose();
590 }
591 }
592 }
593
|
76 canvas = new TrayIconCanvas(target, TRAY_ICON_WIDTH, TRAY_ICON_HEIGHT);
77
78 eframe = new XTrayIconEmbeddedFrame();
79
80 eframe.setSize(TRAY_ICON_WIDTH, TRAY_ICON_HEIGHT);
81 eframe.add(canvas);
82
83 // Fix for 6317038: as EmbeddedFrame is instance of Frame, it is blocked
84 // by modal dialogs, but in the case of TrayIcon it shouldn't. So we
85 // set ModalExclusion property on it.
86 AccessController.doPrivileged(new PrivilegedAction<Object>() {
87 public Object run() {
88 eframe.setModalExclusionType(Dialog.ModalExclusionType.TOOLKIT_EXCLUDE);
89 return null;
90 }
91 });
92
93
94 if (XWM.getWMID() != XWM.METACITY_WM) {
95 parentXED = dummyXED; // We don't like to leave it 'null'.
96 } else {
97 parentXED = new XEventDispatcher() {
98 // It's executed under AWTLock.
99 public void dispatchEvent(XEvent ev) {
100 if (isDisposed() || ev.get_type() != XConstants.ConfigureNotify) {
101 return;
102 }
103
104 XConfigureEvent ce = ev.get_xconfigure();
105
106 if (ctrLog.isLoggable(PlatformLogger.Level.FINE)) {
107 ctrLog.fine("ConfigureNotify on parent of {0}: {1}x{2}+{3}+{4} (old: {5}+{6})",
108 XTrayIconPeer.this, ce.get_width(), ce.get_height(),
109 ce.get_x(), ce.get_y(), old_x, old_y);
110 }
111
112 // A workaround for Gnome/Metacity (it doesn't affect the behaviour on KDE).
113 // On Metacity the EmbeddedFrame's parent window bounds are larger
114 // than TrayIcon size required (that is we need a square but a rectangle
115 // is provided by the Panel Notification Area). The parent's background color
282 SunToolkit.executeOnEDTAndWait(target, new Runnable() {
283 public void run() {
284 disposeOnEDT();
285 }
286 });
287 } catch (InterruptedException ie) {
288 } catch (InvocationTargetException ite) {}
289 }
290 }
291
292 private void disposeOnEDT() {
293 // All actions that is to be synchronized with disposal
294 // should be executed either under AWTLock, or on EDT.
295 // isDisposed value must be checked.
296 XToolkit.awtLock();
297 isDisposed = true;
298 XToolkit.awtUnlock();
299
300 removeXED(getWindow(), eframeXED);
301 removeXED(eframeParentID, parentXED);
302 removeListeners();
303 eframe.realDispose();
304 balloon.dispose();
305 tooltip.dispose();
306 isTrayIconDisplayed = false;
307 canvas.dispose();
308 canvas = null;
309 popup = null;
310 balloon = null;
311 tooltip = null;
312 XToolkit.targetDisposedPeer(target, this);
313 target = null;
314 eframe = null;
315 }
316
317 public static void suppressWarningString(Window w) {
318 AWTAccessor.getWindowAccessor().setTrayIconWindow(w, true);
319 }
320
321 public void setToolTip(String tooltip) {
322 tooltipString = tooltip;
323 }
324
325 public String getTooltipString() {
326 return tooltipString;
327 }
328
329 public void updateImage() {
330 Runnable r = new Runnable() {
331 public void run() {
332 canvas.updateImage(target.getImage());
333 }
334 };
407 XToolkit.awtUnlock();
408 }
409 }
410
411 // Private method for testing purposes.
412 private Point getLocationOnScreen() {
413 return eframe.getLocationOnScreen();
414 }
415
416 public Rectangle getBounds() {
417 Point loc = getLocationOnScreen();
418 return new Rectangle(loc.x, loc.y, loc.x + TRAY_ICON_WIDTH, loc.y + TRAY_ICON_HEIGHT);
419 }
420
421 void addListeners() {
422 canvas.addMouseListener(eventProxy);
423 canvas.addMouseMotionListener(eventProxy);
424 eframe.addMouseListener(eventProxy);
425 }
426
427 void removeListeners() {
428 canvas.removeMouseListener(eventProxy);
429 canvas.removeMouseMotionListener(eventProxy);
430 eframe.removeMouseListener(eventProxy);
431 }
432
433 long getWindow() {
434 return AWTAccessor.getComponentAccessor()
435 .<XEmbeddedFramePeer>getPeer(eframe).getWindow();
436 }
437
438 public boolean isDisposed() {
439 return isDisposed;
440 }
441
442 public String getActionCommand() {
443 return target.getActionCommand();
444 }
445
446 static class TrayIconEventProxy implements MouseListener, MouseMotionListener {
447 XTrayIconPeer xtiPeer;
448
449 TrayIconEventProxy(XTrayIconPeer xtiPeer) {
450 this.xtiPeer = xtiPeer;
451 }
452
547 @SuppressWarnings("serial") // JDK-implementation class
548 static class TrayIconCanvas extends IconCanvas {
549 TrayIcon target;
550 boolean autosize;
551
552 TrayIconCanvas(TrayIcon target, int width, int height) {
553 super(width, height);
554 this.target = target;
555 }
556
557 // Invoke on EDT.
558 protected void repaintImage(boolean doClear) {
559 boolean old_autosize = autosize;
560 autosize = target.isImageAutoSize();
561
562 curW = autosize ? width : image.getWidth(observer);
563 curH = autosize ? height : image.getHeight(observer);
564
565 super.repaintImage(doClear || (old_autosize != autosize));
566 }
567
568 public void dispose() {
569 super.dispose();
570 target = null;
571 }
572 }
573
574 @SuppressWarnings("serial") // JDK-implementation class
575 public static class IconCanvas extends Canvas {
576 volatile Image image;
577 IconObserver observer;
578 int width, height;
579 int curW, curH;
580
581 IconCanvas(int width, int height) {
582 this.width = curW = width;
583 this.height = curH = height;
584 }
585
586 // Invoke on EDT.
587 public void updateImage(Image image) {
588 this.image = image;
589 if (observer == null) {
590 observer = new IconObserver();
591 }
592 repaintImage(true);
593 }
594
595 public void dispose() {
596 observer = null;
597 }
598
599 // Invoke on EDT.
600 protected void repaintImage(boolean doClear) {
601 Graphics g = getGraphics();
602 if (g != null) {
603 try {
604 if (isVisible()) {
605 if (doClear) {
606 update(g);
607 } else {
608 paint(g);
609 }
610 }
611 } finally {
612 g.dispose();
613 }
614 }
615 }
616
|