~3v1n0/unity/lim-panel

« back to all changes in this revision

Viewing changes to plugins/unityshell/src/PanelIndicatorAppmenuView.cpp

  • Committer: Marco Trevisan (Treviño)
  • Date: 2012-02-25 20:34:30 UTC
  • Revision ID: mail@3v1n0.net-20120225203430-yd7iqi4lfhtmnplp
Pushing back removed changes

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
 
2
/*
 
3
 * Copyright (C) 2012 Canonical Ltd
 
4
 *
 
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.
 
8
 *
 
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.
 
13
 *
 
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/>.
 
16
 *
 
17
 * Authored by: Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
 
18
 */
 
19
 
 
20
#include <UnityCore/Variant.h>
 
21
#include <UnityCore/GLibWrapper.h>
 
22
#include <libbamf/libbamf.h>
 
23
 
 
24
#include "PanelIndicatorAppmenuView.h"
 
25
#include "WindowManager.h"
 
26
#include "PanelStyle.h"
 
27
 
 
28
namespace unity
 
29
{
 
30
namespace
 
31
{
 
32
  const std::string MENU_ATOM = "_UBUNTU_APPMENU_UNIQUE_NAME";
 
33
}
 
34
 
 
35
using indicator::Entry;
 
36
 
 
37
PanelIndicatorAppmenuView::PanelIndicatorAppmenuView(Entry::Ptr const& proxy)
 
38
  : PanelIndicatorEntryView(proxy, 0, APPMENU)
 
39
  , xid_(0)
 
40
  , has_menu_(false)
 
41
{
 
42
  spacing_ = 2;
 
43
  right_padding_ = 7; 
 
44
}
 
45
 
 
46
void PanelIndicatorAppmenuView::Activate(int button)
 
47
{
 
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()))
 
51
  {
 
52
    SetActiveState(true, 1);
 
53
  }
 
54
}
 
55
 
 
56
void PanelIndicatorAppmenuView::ShowMenu(int button)
 
57
{
 
58
  if (xid_ && has_menu_)
 
59
  {
 
60
    WindowManager::Default()->Raise(xid_);
 
61
    WindowManager::Default()->Activate(xid_);
 
62
 
 
63
    proxy_->ShowMenu(xid_,
 
64
                     GetAbsoluteX(),
 
65
                     GetAbsoluteY() + panel::Style::Instance().panel_height,
 
66
                     button,
 
67
                     time(nullptr));
 
68
  }
 
69
}
 
70
 
 
71
std::string PanelIndicatorAppmenuView::GetLabel()
 
72
{
 
73
  glib::String escaped(g_markup_escape_text(label_.c_str(), -1));
 
74
 
 
75
  std::ostringstream bold_label;
 
76
  bold_label << "<b>" << escaped.Str() << "</b>";
 
77
 
 
78
  return bold_label.str();
 
79
}
 
80
 
 
81
bool PanelIndicatorAppmenuView::IsLabelSensitive() const
 
82
{
 
83
  return (!label_.empty() && has_menu_);
 
84
}
 
85
 
 
86
bool PanelIndicatorAppmenuView::IsLabelVisible() const
 
87
{
 
88
  return !label_.empty();
 
89
}
 
90
 
 
91
bool PanelIndicatorAppmenuView::IsIconSensitive() const
 
92
{
 
93
  return has_menu_;
 
94
}
 
95
 
 
96
bool PanelIndicatorAppmenuView::IsIconVisible() const
 
97
{
 
98
  return has_menu_;
 
99
}
 
100
 
 
101
void PanelIndicatorAppmenuView::SetLabel(std::string const& label)
 
102
{
 
103
  if (label_ != label)
 
104
  {
 
105
    label_ = label;
 
106
    Refresh();
 
107
  }
 
108
}
 
109
 
 
110
void PanelIndicatorAppmenuView::SetControlledWindow(Window xid)
 
111
{
 
112
  if (xid_ != xid)
 
113
  {
 
114
    xid_ = xid;
 
115
    CheckWindowMenu();
 
116
  }
 
117
}
 
118
 
 
119
bool PanelIndicatorAppmenuView::CheckWindowMenu()
 
120
{
 
121
  /* FIXME this is a temporary workaround */
 
122
  has_menu_ = true;
 
123
  glib::Object<BamfMatcher> matcher(bamf_matcher_get_default());
 
124
  BamfWindow *win = bamf_matcher_get_active_window(matcher);
 
125
 
 
126
  if (BAMF_IS_WINDOW(win))
 
127
  {
 
128
    if (xid_ == bamf_window_get_xid(win))
 
129
    {
 
130
      has_menu_ = proxy_->image_sensitive();
 
131
    }
 
132
  }
 
133
 
 
134
  /* FIXME re-enable this when all the clients will support the APPMENU atom.
 
135
  has_menu_ = false;
 
136
 
 
137
  if (!xid_)
 
138
    return false;
 
139
 
 
140
  glib::Object<BamfMatcher> matcher(bamf_matcher_get_default());
 
141
 
 
142
  GList* windows = bamf_matcher_get_windows(matcher);
 
143
 
 
144
  for (GList* l = windows; l; l = l->next)
 
145
  {
 
146
    if (BAMF_IS_WINDOW(l->data))
 
147
    {
 
148
      auto window = static_cast<BamfWindow*>(l->data);
 
149
 
 
150
      if (bamf_window_get_xid(window) == xid_)
 
151
      {
 
152
        glib::String property(bamf_window_get_utf8_prop(window, MENU_ATOM.c_str()));
 
153
        has_menu_ = bool(property);
 
154
        break;
 
155
      }
 
156
    }
 
157
  }
 
158
 
 
159
  g_list_free(windows);*/
 
160
 
 
161
  return has_menu_;
 
162
}
 
163
 
 
164
void PanelIndicatorAppmenuView::DrawEntryPrelight(cairo_t* cr, unsigned int width, unsigned int height)
 
165
{
 
166
  nux::Rect const& geo = proxy_->geometry();
 
167
 
 
168
  if (geo == nux::Geometry())
 
169
    return;
 
170
 
 
171
  GtkStyleContext* style_context = panel::Style::Instance().GetStyleContext();
 
172
  int flair_width = std::min(geo.width, GetMinimumWidth());
 
173
 
 
174
  cairo_translate (cr, geo.x - GetAbsoluteX(), geo.y - height);
 
175
 
 
176
  gtk_style_context_save(style_context);
 
177
 
 
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);
 
182
 
 
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);
 
187
 
 
188
  cairo_save(cr);
 
189
  cairo_push_group(cr);
 
190
 
 
191
  gtk_render_background(style_context, cr, 0, 0, flair_width, height);
 
192
  gtk_render_frame(style_context, cr, 0, 0, flair_width, height);
 
193
 
 
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);
 
199
 
 
200
  cairo_rectangle(cr, 0, 0, flair_width, height);
 
201
  cairo_set_source(cr, pat);
 
202
  cairo_mask(cr, mask);
 
203
 
 
204
  cairo_pattern_destroy(pat);
 
205
  cairo_pattern_destroy(mask);
 
206
  cairo_restore(cr);
 
207
 
 
208
  gtk_widget_path_free(widget_path);
 
209
 
 
210
  gtk_style_context_restore(style_context);
 
211
}
 
212
 
 
213
std::string PanelIndicatorAppmenuView::GetName() const
 
214
{
 
215
  return "appmenu";
 
216
}
 
217
 
 
218
void PanelIndicatorAppmenuView::AddProperties(GVariantBuilder* builder)
 
219
{
 
220
  PanelIndicatorEntryView::AddProperties(builder);
 
221
 
 
222
  variant::BuilderWrapper(builder)
 
223
  .add("controlled-window", xid_)
 
224
  .add("has_menu", has_menu_);
 
225
}
 
226
 
 
227
} // NAMESPACE