1
// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
3
* Copyright (C) 2012 Canonical Ltd
5
* This program is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License version 3 as
7
* published by the Free Software Foundation.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17
* Authored by: Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
20
#include <UnityCore/Variant.h>
21
#include <UnityCore/GLibWrapper.h>
22
#include <libbamf/libbamf.h>
24
#include "PanelIndicatorAppmenuView.h"
25
#include "WindowManager.h"
26
#include "PanelStyle.h"
32
const std::string MENU_ATOM = "_UBUNTU_APPMENU_UNIQUE_NAME";
35
using indicator::Entry;
37
PanelIndicatorAppmenuView::PanelIndicatorAppmenuView(Entry::Ptr const& proxy)
38
: PanelIndicatorEntryView(proxy, 0, APPMENU)
46
void PanelIndicatorAppmenuView::Activate(int button)
48
/* If the button is 0, the entry is activated using a keyboard shortcut,
49
* so we need to check the fucus status of the entry */
50
if (button != 0 || (button == 0 && IsFocused()))
52
SetActiveState(true, 1);
56
void PanelIndicatorAppmenuView::ShowMenu(int button)
58
if (xid_ && has_menu_)
60
WindowManager::Default()->Raise(xid_);
61
WindowManager::Default()->Activate(xid_);
63
proxy_->ShowMenu(xid_,
65
GetAbsoluteY() + panel::Style::Instance().panel_height,
71
std::string PanelIndicatorAppmenuView::GetLabel()
73
glib::String escaped(g_markup_escape_text(label_.c_str(), -1));
75
std::ostringstream bold_label;
76
bold_label << "<b>" << escaped.Str() << "</b>";
78
return bold_label.str();
81
bool PanelIndicatorAppmenuView::IsLabelSensitive() const
83
return (!label_.empty() && has_menu_);
86
bool PanelIndicatorAppmenuView::IsLabelVisible() const
88
return !label_.empty();
91
bool PanelIndicatorAppmenuView::IsIconSensitive() const
96
bool PanelIndicatorAppmenuView::IsIconVisible() const
101
void PanelIndicatorAppmenuView::SetLabel(std::string const& label)
110
void PanelIndicatorAppmenuView::SetControlledWindow(Window xid)
119
bool PanelIndicatorAppmenuView::CheckWindowMenu()
121
/* FIXME this is a temporary workaround */
123
glib::Object<BamfMatcher> matcher(bamf_matcher_get_default());
124
BamfWindow *win = bamf_matcher_get_active_window(matcher);
126
if (BAMF_IS_WINDOW(win))
128
if (xid_ == bamf_window_get_xid(win))
130
has_menu_ = proxy_->image_sensitive();
134
/* FIXME re-enable this when all the clients will support the APPMENU atom.
140
glib::Object<BamfMatcher> matcher(bamf_matcher_get_default());
142
GList* windows = bamf_matcher_get_windows(matcher);
144
for (GList* l = windows; l; l = l->next)
146
if (BAMF_IS_WINDOW(l->data))
148
auto window = static_cast<BamfWindow*>(l->data);
150
if (bamf_window_get_xid(window) == xid_)
152
glib::String property(bamf_window_get_utf8_prop(window, MENU_ATOM.c_str()));
153
has_menu_ = bool(property);
159
g_list_free(windows);*/
164
void PanelIndicatorAppmenuView::DrawEntryPrelight(cairo_t* cr, unsigned int width, unsigned int height)
166
nux::Rect const& geo = proxy_->geometry();
168
if (geo == nux::Geometry())
171
GtkStyleContext* style_context = panel::Style::Instance().GetStyleContext();
172
int flair_width = std::min(geo.width, GetMinimumWidth());
174
cairo_translate (cr, geo.x - GetAbsoluteX(), geo.y - height);
176
gtk_style_context_save(style_context);
178
GtkWidgetPath* widget_path = gtk_widget_path_new();
179
gtk_widget_path_iter_set_name(widget_path, -1 , "UnityPanelWidget");
180
gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_BAR);
181
gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_ITEM);
183
gtk_style_context_set_path(style_context, widget_path);
184
gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR);
185
gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM);
186
gtk_style_context_set_state(style_context, GTK_STATE_FLAG_PRELIGHT);
189
cairo_push_group(cr);
191
gtk_render_background(style_context, cr, 0, 0, flair_width, height);
192
gtk_render_frame(style_context, cr, 0, 0, flair_width, height);
194
cairo_pattern_t* pat = cairo_pop_group(cr);
195
cairo_pattern_t* mask = cairo_pattern_create_linear(0, 0, 0, height);
196
cairo_pattern_add_color_stop_rgba(mask, 0.0f, 0, 0, 0, 0.0f);
197
cairo_pattern_add_color_stop_rgba(mask, 0.6f, 0, 0, 0, 0.0f);
198
cairo_pattern_add_color_stop_rgba(mask, 1.0f, 0, 0, 0, 1.0f);
200
cairo_rectangle(cr, 0, 0, flair_width, height);
201
cairo_set_source(cr, pat);
202
cairo_mask(cr, mask);
204
cairo_pattern_destroy(pat);
205
cairo_pattern_destroy(mask);
208
gtk_widget_path_free(widget_path);
210
gtk_style_context_restore(style_context);
213
std::string PanelIndicatorAppmenuView::GetName() const
218
void PanelIndicatorAppmenuView::AddProperties(GVariantBuilder* builder)
220
PanelIndicatorEntryView::AddProperties(builder);
222
variant::BuilderWrapper(builder)
223
.add("controlled-window", xid_)
224
.add("has_menu", has_menu_);