Advertisement
Guest User

Replace panel/PanelTray.cpp with this.

a guest
Apr 16th, 2014
23
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.65 KB | None | 0 0
  1. /*
  2. * Copyright (C) 2010-2012 Canonical Ltd
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 3 as
  6. * published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. *
  16. * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
  17. * Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
  18. */
  19.  
  20. #include <array>
  21.  
  22. #include "PanelTray.h"
  23. #include "unity-shared/PanelStyle.h"
  24. #include "unity-shared/UnitySettings.h"
  25.  
  26. #include <NuxCore/Logger.h>
  27.  
  28. DECLARE_LOGGER(logger, "unity.panel.tray");
  29. namespace
  30. {
  31. const std::string SETTINGS_NAME = "com.canonical.Unity.Panel";
  32. const int PADDING = 3;
  33. const std::array<std::string, 2> WHITELIST {{ "JavaEmbeddedFrame", "Wine" }};
  34. }
  35.  
  36. namespace unity
  37. {
  38.  
  39. PanelTray::PanelTray(int monitor)
  40. : View(NUX_TRACKER_LOCATION)
  41. , window_(gtk_window_new(GTK_WINDOW_TOPLEVEL))
  42. , monitor_(monitor)
  43. {
  44. int panel_height = panel::Style::Instance().PanelHeight(monitor_);
  45.  
  46. auto gtkwindow = glib::object_cast<GtkWindow>(window_);
  47. gtk_window_set_type_hint(gtkwindow, GDK_WINDOW_TYPE_HINT_DOCK);
  48. gtk_window_set_has_resize_grip(gtkwindow, FALSE);
  49. gtk_window_set_keep_above(gtkwindow, TRUE);
  50. gtk_window_set_skip_pager_hint(gtkwindow, TRUE);
  51. gtk_window_set_skip_taskbar_hint(gtkwindow, TRUE);
  52. gtk_window_resize(gtkwindow, 1, panel_height);
  53. gtk_window_move(gtkwindow, -panel_height,-panel_height);
  54. gtk_widget_set_name(window_, "UnityPanelApplet");
  55.  
  56. gtk_widget_set_visual(window_, gdk_screen_get_rgba_visual(gdk_screen_get_default()));
  57. gtk_widget_realize(window_);
  58. gtk_widget_set_app_paintable(window_, TRUE);
  59. draw_signal_.Connect(window_, "draw", sigc::mem_fun(this, &PanelTray::OnTrayDraw));
  60.  
  61. if (!g_getenv("UNITY_PANEL_TRAY_DISABLE"))
  62. {
  63. tray_ = na_tray_new_for_screen(gdk_screen_get_default(),
  64. GTK_ORIENTATION_HORIZONTAL,
  65. (NaTrayFilterCallback)FilterTrayCallback,
  66. this);
  67. na_tray_set_icon_size(tray_, panel_height);
  68.  
  69. icon_removed_signal_.Connect(na_tray_get_manager(tray_), "tray_icon_removed",
  70. sigc::mem_fun(this, &PanelTray::OnTrayIconRemoved));
  71.  
  72. gtk_container_add(GTK_CONTAINER(window_.RawPtr()), GTK_WIDGET(tray_.RawPtr()));
  73. gtk_widget_show(GTK_WIDGET(tray_.RawPtr()));
  74. }
  75.  
  76. SetMinMaxSize(1, panel_height);
  77. }
  78.  
  79. PanelTray::~PanelTray()
  80. {
  81. if (gtk_widget_get_realized(window_))
  82. {
  83. // We call Release since we're deleting the window here manually,
  84. // and we don't want the smart pointer to try and delete it as well.
  85. gtk_widget_destroy(window_.Release());
  86. // We also need to release the tray to avoid the extra unref and invalid read.
  87. tray_.Release();
  88. }
  89. }
  90.  
  91. Window PanelTray::xid()
  92. {
  93. if (!window_ || !gtk_widget_get_realized(window_))
  94. return 0;
  95.  
  96. return gdk_x11_window_get_xid(gtk_widget_get_window(window_));
  97. }
  98.  
  99. void PanelTray::Draw(nux::GraphicsEngine& gfx_context, bool force_draw)
  100. {
  101. nux::Geometry const& geo = GetAbsoluteGeometry();
  102.  
  103. gfx_context.PushClippingRectangle(geo);
  104. nux::GetPainter().PaintBackground(gfx_context, geo);
  105. gfx_context.PopClippingRectangle();
  106.  
  107. if (geo != last_geo_)
  108. {
  109. last_geo_ = geo;
  110. gtk_window_move(GTK_WINDOW(window_.RawPtr()), geo.x + PADDING, geo.y);
  111. }
  112. }
  113.  
  114. void PanelTray::Sync()
  115. {
  116. if (tray_)
  117. {
  118. SetMinMaxSize(WidthOfTray() + (PADDING * 2), panel::Style::Instance().PanelHeight(monitor_));
  119. QueueRelayout();
  120. QueueDraw();
  121.  
  122. if (!children_.empty())
  123. gtk_widget_show(window_);
  124. else
  125. gtk_widget_hide(window_);
  126. }
  127. }
  128.  
  129. gboolean PanelTray::FilterTrayCallback(NaTray* tray, NaTrayChild* icon, PanelTray* self)
  130. {
  131. glib::String title(na_tray_child_get_title(icon));
  132.  
  133. glib::String res_class;
  134. glib::String res_name;
  135. na_tray_child_get_wm_class(icon, &res_name, &res_class);
  136.  
  137. bool accept = FilterTray(title.Str(), res_name.Str(), res_class.Str());
  138.  
  139. if (accept)
  140. {
  141. if (na_tray_child_has_alpha(icon))
  142. na_tray_child_set_composited(icon, TRUE);
  143.  
  144. self->children_.push_back(icon);
  145. self->sync_idle_.reset(new glib::Idle(sigc::mem_fun(self, &PanelTray::IdleSync)));
  146. }
  147.  
  148. LOG_DEBUG(logger) << "TrayChild "
  149. << (accept ? "Accepted: " : "Rejected: ")
  150. << na_tray_child_get_title(icon) << " "
  151. << res_name << " " << res_class;
  152.  
  153. return accept ? TRUE : FALSE;
  154. }
  155.  
  156. bool PanelTray::FilterTray(std::string const& title, std::string const& res_name, std::string const& res_class)
  157. {
  158. return true;
  159. for (auto const& item : WHITELIST)
  160. if (title.find(item) == 0 || res_name.find(item) == 0 || res_class.find(item) == 0)
  161. return true;
  162.  
  163. return false;
  164. }
  165.  
  166. void PanelTray::OnTrayIconRemoved(NaTrayManager* manager, NaTrayChild* removed)
  167. {
  168. for (auto child : children_)
  169. {
  170. if (child == removed)
  171. {
  172. sync_idle_.reset(new glib::Idle(sigc::mem_fun(this, &PanelTray::IdleSync)));
  173. children_.remove(child);
  174. break;
  175. }
  176. }
  177. }
  178.  
  179. bool PanelTray::IdleSync()
  180. {
  181. int width = WidthOfTray();
  182. gtk_window_resize(GTK_WINDOW(window_.RawPtr()), width, panel::Style::Instance().PanelHeight(monitor_));
  183. Sync();
  184.  
  185. return false;
  186. }
  187.  
  188. int PanelTray::WidthOfTray()
  189. {
  190. int width = 0;
  191. for (auto child: children_)
  192. {
  193. int w = gtk_widget_get_allocated_width(GTK_WIDGET(child));
  194. width += w > 24 ? w : 24;
  195. }
  196. return width;
  197. }
  198.  
  199. gboolean PanelTray::OnTrayDraw(GtkWidget* widget, cairo_t* cr)
  200. {
  201. GtkAllocation alloc;
  202.  
  203. gtk_widget_get_allocation(widget, &alloc);
  204.  
  205. cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
  206. cairo_paint(cr);
  207.  
  208. cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
  209. cairo_set_source_rgba(cr, 0.0f, 0.0f, 0.0f, 0.0f);
  210. cairo_rectangle(cr, 0, 0, alloc.width, alloc.height);
  211. cairo_fill(cr);
  212.  
  213. gtk_container_propagate_draw(GTK_CONTAINER(widget),
  214. gtk_bin_get_child(GTK_BIN(widget)),
  215. cr);
  216.  
  217. return FALSE;
  218. }
  219.  
  220. std::string PanelTray::GetName() const
  221. {
  222. return "Tray";
  223. }
  224.  
  225. void PanelTray::AddProperties(debug::IntrospectionData& introspection)
  226. {
  227. introspection
  228. .add(GetAbsoluteGeometry())
  229. .add("children_count", children_.size());
  230. }
  231.  
  232. } // namespace unity
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement