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 isTrayIconDisplayed = false;
306 canvas.dispose();
307 canvas = null;
308 popup = null;
309 balloon = null;
310 tooltip = null;
311 XToolkit.targetDisposedPeer(target, this);
312 target = null;
313 eframe = null;
314 }
315
316 public static void suppressWarningString(Window w) {
317 AWTAccessor.getWindowAccessor().setTrayIconWindow(w, true);
318 }
319
320 public void setToolTip(String tooltip) {
321 tooltipString = tooltip;
322 }
323
324 public String getTooltipString() {
325 return tooltipString;
326 }
327
328 public void updateImage() {
329 Runnable r = new Runnable() {
330 public void run() {
331 canvas.updateImage(target.getImage());
332 }
333 };
406 XToolkit.awtUnlock();
407 }
408 }
409
410 // Private method for testing purposes.
411 private Point getLocationOnScreen() {
412 return eframe.getLocationOnScreen();
413 }
414
415 public Rectangle getBounds() {
416 Point loc = getLocationOnScreen();
417 return new Rectangle(loc.x, loc.y, loc.x + TRAY_ICON_WIDTH, loc.y + TRAY_ICON_HEIGHT);
418 }
419
420 void addListeners() {
421 canvas.addMouseListener(eventProxy);
422 canvas.addMouseMotionListener(eventProxy);
423 eframe.addMouseListener(eventProxy);
424 }
425
426 void removeListeners() {
427 canvas.removeMouseListener(eventProxy);
428 canvas.removeMouseMotionListener(eventProxy);
429 eframe.removeMouseListener(eventProxy);
430 }
431
432 long getWindow() {
433 return AWTAccessor.getComponentAccessor()
434 .<XEmbeddedFramePeer>getPeer(eframe).getWindow();
435 }
436
437 public boolean isDisposed() {
438 return isDisposed;
439 }
440
441 public String getActionCommand() {
442 return target.getActionCommand();
443 }
444
445 static class TrayIconEventProxy implements MouseListener, MouseMotionListener {
446 XTrayIconPeer xtiPeer;
447
448 TrayIconEventProxy(XTrayIconPeer xtiPeer) {
449 this.xtiPeer = xtiPeer;
450 }
451
546 @SuppressWarnings("serial") // JDK-implementation class
547 static class TrayIconCanvas extends IconCanvas {
548 TrayIcon target;
549 boolean autosize;
550
551 TrayIconCanvas(TrayIcon target, int width, int height) {
552 super(width, height);
553 this.target = target;
554 }
555
556 // Invoke on EDT.
557 protected void repaintImage(boolean doClear) {
558 boolean old_autosize = autosize;
559 autosize = target.isImageAutoSize();
560
561 curW = autosize ? width : image.getWidth(observer);
562 curH = autosize ? height : image.getHeight(observer);
563
564 super.repaintImage(doClear || (old_autosize != autosize));
565 }
566
567 public void dispose() {
568 super.dispose();
569 target = null;
570 }
571 }
572
573 @SuppressWarnings("serial") // JDK-implementation class
574 public static class IconCanvas extends Canvas {
575 volatile Image image;
576 IconObserver observer;
577 int width, height;
578 int curW, curH;
579
580 IconCanvas(int width, int height) {
581 this.width = curW = width;
582 this.height = curH = height;
583 }
584
585 // Invoke on EDT.
586 public void updateImage(Image image) {
587 this.image = image;
588 if (observer == null) {
589 observer = new IconObserver();
590 }
591 repaintImage(true);
592 }
593
594 public void dispose() {
595 observer = null;
596 }
597
598 // Invoke on EDT.
599 protected void repaintImage(boolean doClear) {
600 Graphics g = getGraphics();
601 if (g != null) {
602 try {
603 if (isVisible()) {
604 if (doClear) {
605 update(g);
606 } else {
607 paint(g);
608 }
609 }
610 } finally {
611 g.dispose();
612 }
613 }
614 }
615
|