The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

125 lines
4.3KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-11 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. extern Display* display;
  19. //==============================================================================
  20. class SystemTrayIconComponent::Pimpl
  21. {
  22. public:
  23. Pimpl (const Image& image_, Window windowH)
  24. : image (image_)
  25. {
  26. ScopedXLock xlock;
  27. Screen* const screen = XDefaultScreenOfDisplay (display);
  28. const int screenNumber = XScreenNumberOfScreen (screen);
  29. String screenAtom ("_NET_SYSTEM_TRAY_S");
  30. screenAtom << screenNumber;
  31. Atom selectionAtom = XInternAtom (display, screenAtom.toUTF8(), false);
  32. XGrabServer (display);
  33. Window managerWin = XGetSelectionOwner (display, selectionAtom);
  34. if (managerWin != None)
  35. XSelectInput (display, managerWin, StructureNotifyMask);
  36. XUngrabServer (display);
  37. XFlush (display);
  38. if (managerWin != None)
  39. {
  40. XEvent ev = { 0 };
  41. ev.xclient.type = ClientMessage;
  42. ev.xclient.window = managerWin;
  43. ev.xclient.message_type = XInternAtom (display, "_NET_SYSTEM_TRAY_OPCODE", False);
  44. ev.xclient.format = 32;
  45. ev.xclient.data.l[0] = CurrentTime;
  46. ev.xclient.data.l[1] = 0 /*SYSTEM_TRAY_REQUEST_DOCK*/;
  47. ev.xclient.data.l[2] = windowH;
  48. ev.xclient.data.l[3] = 0;
  49. ev.xclient.data.l[4] = 0;
  50. XSendEvent (display, managerWin, False, NoEventMask, &ev);
  51. XSync (display, False);
  52. }
  53. // For older KDE's ...
  54. long atomData = 1;
  55. Atom trayAtom = XInternAtom (display, "KWM_DOCKWINDOW", false);
  56. XChangeProperty (display, windowH, trayAtom, trayAtom, 32, PropModeReplace, (unsigned char*) &atomData, 1);
  57. // For more recent KDE's...
  58. trayAtom = XInternAtom (display, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", false);
  59. XChangeProperty (display, windowH, trayAtom, XA_WINDOW, 32, PropModeReplace, (unsigned char*) &windowH, 1);
  60. // A minimum size must be specified for GNOME and Xfce, otherwise the icon is displayed with a width of 1
  61. XSizeHints* hints = XAllocSizeHints();
  62. hints->flags = PMinSize;
  63. hints->min_width = 22;
  64. hints->min_height = 22;
  65. XSetWMNormalHints (display, windowH, hints);
  66. XFree (hints);
  67. }
  68. Image image;
  69. private:
  70. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl)
  71. };
  72. //==============================================================================
  73. void SystemTrayIconComponent::setIconImage (const Image& newImage)
  74. {
  75. pimpl = nullptr;
  76. if (newImage.isValid())
  77. {
  78. if (! isOnDesktop())
  79. addToDesktop (0);
  80. pimpl = new Pimpl (newImage, (Window) getWindowHandle());
  81. setVisible (true);
  82. toFront (false);
  83. }
  84. repaint();
  85. }
  86. void SystemTrayIconComponent::paint (Graphics& g)
  87. {
  88. if (pimpl != nullptr)
  89. g.drawImageWithin (pimpl->image, 0, 0, getWidth(), getHeight(),
  90. RectanglePlacement::xLeft | RectanglePlacement::yTop | RectanglePlacement::onlyReduceInSize, false);
  91. }
  92. void SystemTrayIconComponent::setIconTooltip (const String& /* tooltip */)
  93. {
  94. // xxx not yet implemented!
  95. }