Merge lp:~unity-team/unity/panel-fixes-2010-12-07 into lp:unity

Proposed by Neil J. Patel
Status: Merged
Approved by: Gord Allott
Approved revision: no longer in the source branch.
Merged at revision: 722
Proposed branch: lp:~unity-team/unity/panel-fixes-2010-12-07
Merge into: lp:unity
Diff against target: 1845 lines (+1499/-47)
20 files modified
src/IndicatorObjectEntryProxy.h (+2/-1)
src/IndicatorObjectEntryProxyRemote.cpp (+3/-2)
src/IndicatorObjectFactory.h (+1/-0)
src/IndicatorObjectFactoryRemote.cpp (+3/-1)
src/PanelIndicatorObjectEntryView.cpp (+8/-4)
src/PanelIndicatorObjectEntryView.h (+7/-0)
src/PanelIndicatorObjectView.cpp (+7/-0)
src/PanelIndicatorObjectView.h (+1/-1)
src/PanelMenuView.cpp (+671/-0)
src/PanelMenuView.h (+103/-0)
src/PanelView.cpp (+48/-32)
src/PanelView.h (+3/-0)
src/PluginAdapter.cpp (+77/-4)
src/PluginAdapter.h (+10/-1)
src/WindowButtons.cpp (+254/-0)
src/WindowButtons.h (+63/-0)
src/WindowManager.cpp (+171/-0)
src/WindowManager.h (+57/-0)
src/unity.cpp (+2/-1)
tests/CMakeLists.txt (+8/-0)
To merge this branch: bzr merge lp:~unity-team/unity/panel-fixes-2010-12-07
Reviewer Review Type Date Requested Status
Unity Team Pending
Review via email: mp+44015@code.launchpad.net

Description of the change

This implements the panel menubar as per spec.

The things to check for:

1. Unmaximised window + no mouse hover over panel = Application name
2. Unmaximised window + mouse hover over panel = Menus (and they work)
3. Unmaximised window + no mouse hover + Alt+F (or whatever) = Menus show
4. Maximised window + no mouse = no decorations + usable close/min/restore buttons + window *title*
5. Maximised window + mouse = no decs + usable close/min/restore buttons + menu
6. Maximised window + no mouse + Alt+F (i.e.) = no decs + usable buttons + menu
7. Maximised window + click on restore = restored decorations on floating window

Notes:

 - Windows that were already undecorated should be unaffected by max/restore (i.e. restore shouldn't add decorations, chromium with non-system-borders enabled is a good test)
 - Transmission goes weird when trying to restore decorations, need to investigate
 - Interaction is weird with desktop, sometimes you get "Unknown"

To post a comment you must log in.
Revision history for this message
Neil J. Patel (njpatel) wrote :

Oh, some of the linked bugs are because of reusing the same branch, please ignore that.

Revision history for this message
Gord Allott (gordallott) wrote :

noting: Nux: [Object::UnReference] Error on object allocated at /home/gord/canonical/unity/panel-fixes-2010-12-07/src/PanelMenuView.cpp [63]: Nux: Assertion failed: 0 : [Object::UnReference] Never call UnReference on an object with a floating reference. Call Dispose() instead.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/IndicatorObjectEntryProxy.h'
--- src/IndicatorObjectEntryProxy.h 2010-11-11 15:07:58 +0000
+++ src/IndicatorObjectEntryProxy.h 2010-12-17 10:43:24 +0000
@@ -36,7 +36,8 @@
36 virtual void ShowMenu (int x, int y, guint32 timestamp, guint32 button) = 0;36 virtual void ShowMenu (int x, int y, guint32 timestamp, guint32 button) = 0;
3737
38 // Signals38 // Signals
39 sigc::signal<void> Updated;39 sigc::signal<void> updated;
40 sigc::signal<void, bool> active_changed;
4041
41public:42public:
42 bool label_visible;43 bool label_visible;
4344
=== modified file 'src/IndicatorObjectEntryProxyRemote.cpp'
--- src/IndicatorObjectEntryProxyRemote.cpp 2010-11-17 20:12:42 +0000
+++ src/IndicatorObjectEntryProxyRemote.cpp 2010-12-17 10:43:24 +0000
@@ -104,7 +104,8 @@
104104
105 _active = active;105 _active = active;
106106
107 Updated.emit ();107 active_changed.emit (active);
108 updated.emit ();
108}109}
109110
110bool111bool
@@ -141,7 +142,7 @@
141 icon_sensitive = __image_sensitive;142 icon_sensitive = __image_sensitive;
142 icon_visible = __image_visible;143 icon_visible = __image_visible;
143144
144 Updated.emit ();145 updated.emit ();
145}146}
146147
147const char *148const char *
148149
=== modified file 'src/IndicatorObjectFactory.h'
--- src/IndicatorObjectFactory.h 2010-12-07 13:55:04 +0000
+++ src/IndicatorObjectFactory.h 2010-12-17 10:43:24 +0000
@@ -45,6 +45,7 @@
45 sigc::signal<void, IndicatorObjectProxy *> OnObjectRemoved;45 sigc::signal<void, IndicatorObjectProxy *> OnObjectRemoved;
46 sigc::signal<void, int, int> OnMenuPointerMoved;46 sigc::signal<void, int, int> OnMenuPointerMoved;
47 sigc::signal<void, const char *> OnEntryActivateRequest;47 sigc::signal<void, const char *> OnEntryActivateRequest;
48 sigc::signal<void, const char *> OnEntryActivated;
4849
49protected:50protected:
50 std::vector<IndicatorObjectProxy *>_indicators;51 std::vector<IndicatorObjectProxy *>_indicators;
5152
=== modified file 'src/IndicatorObjectFactoryRemote.cpp'
--- src/IndicatorObjectFactoryRemote.cpp 2010-12-13 19:53:58 +0000
+++ src/IndicatorObjectFactoryRemote.cpp 2010-12-17 10:43:24 +0000
@@ -239,7 +239,9 @@
239239
240 entry->SetActive (g_strcmp0 (entry_id, entry->GetId ()) == 0);240 entry->SetActive (g_strcmp0 (entry_id, entry->GetId ()) == 0);
241 }241 }
242 } 242 }
243
244 IndicatorObjectFactory::OnEntryActivated.emit (entry_id);
243}245}
244246
245void247void
246248
=== modified file 'src/PanelIndicatorObjectEntryView.cpp'
--- src/PanelIndicatorObjectEntryView.cpp 2010-12-07 15:01:07 +0000
+++ src/PanelIndicatorObjectEntryView.cpp 2010-12-17 10:43:24 +0000
@@ -31,9 +31,6 @@
31#include <gtk/gtk.h>31#include <gtk/gtk.h>
32#include <time.h>32#include <time.h>
3333
34#define PANEL_HEIGHT 24
35#define PADDING 6
36#define SPACING 3
3734
38static void draw_menu_bg (cairo_t *cr, int width, int height);35static void draw_menu_bg (cairo_t *cr, int width, int height);
3936
@@ -43,7 +40,8 @@
43 _proxy (proxy),40 _proxy (proxy),
44 _util_cg (CAIRO_FORMAT_ARGB32, 1, 1)41 _util_cg (CAIRO_FORMAT_ARGB32, 1, 1)
45{42{
46 _proxy->Updated.connect (sigc::mem_fun (this, &PanelIndicatorObjectEntryView::Refresh));43 _proxy->active_changed.connect (sigc::mem_fun (this, &PanelIndicatorObjectEntryView::OnActiveChanged));
44 _proxy->updated.connect (sigc::mem_fun (this, &PanelIndicatorObjectEntryView::Refresh));
4745
48 InputArea::OnMouseDown.connect (sigc::mem_fun (this, &PanelIndicatorObjectEntryView::OnMouseDown));46 InputArea::OnMouseDown.connect (sigc::mem_fun (this, &PanelIndicatorObjectEntryView::OnMouseDown));
49 47
@@ -55,6 +53,12 @@
55}53}
5654
57void55void
56PanelIndicatorObjectEntryView::OnActiveChanged (bool is_active)
57{
58 active_changed.emit (this, is_active);
59}
60
61void
58PanelIndicatorObjectEntryView::OnMouseDown (int x, int y, long button_flags, long key_flags)62PanelIndicatorObjectEntryView::OnMouseDown (int x, int y, long button_flags, long key_flags)
59{63{
60 if (_proxy->GetActive ())64 if (_proxy->GetActive ())
6165
=== modified file 'src/PanelIndicatorObjectEntryView.h'
--- src/PanelIndicatorObjectEntryView.h 2010-12-07 13:55:04 +0000
+++ src/PanelIndicatorObjectEntryView.h 2010-12-17 10:43:24 +0000
@@ -28,6 +28,10 @@
2828
29#include "Introspectable.h"29#include "Introspectable.h"
3030
31#define PANEL_HEIGHT 24
32#define PADDING 6
33#define SPACING 3
34
31class PanelIndicatorObjectEntryView : public nux::TextureArea, public Introspectable35class PanelIndicatorObjectEntryView : public nux::TextureArea, public Introspectable
32{36{
33public:37public:
@@ -37,10 +41,13 @@
37 void Refresh ();41 void Refresh ();
38 void OnMouseDown (int x, int y, long button_flags, long key_flags);42 void OnMouseDown (int x, int y, long button_flags, long key_flags);
39 void Activate ();43 void Activate ();
44 void OnActiveChanged (bool is_active);
4045
41 const gchar * GetName ();46 const gchar * GetName ();
42 void AddProperties (GVariantBuilder *builder);47 void AddProperties (GVariantBuilder *builder);
4348
49 sigc::signal<void, PanelIndicatorObjectEntryView *, bool> active_changed;
50
44public:51public:
45 IndicatorObjectEntryProxy *_proxy;52 IndicatorObjectEntryProxy *_proxy;
46private:53private:
4754
=== modified file 'src/PanelIndicatorObjectView.cpp'
--- src/PanelIndicatorObjectView.cpp 2010-12-02 11:55:02 +0000
+++ src/PanelIndicatorObjectView.cpp 2010-12-17 10:43:24 +0000
@@ -30,6 +30,13 @@
3030
31#include <glib.h>31#include <glib.h>
3232
33PanelIndicatorObjectView::PanelIndicatorObjectView ()
34: View (NUX_TRACKER_LOCATION),
35 _proxy (NULL),
36 _entries ()
37{
38}
39
33PanelIndicatorObjectView::PanelIndicatorObjectView (IndicatorObjectProxy *proxy)40PanelIndicatorObjectView::PanelIndicatorObjectView (IndicatorObjectProxy *proxy)
34: View (NUX_TRACKER_LOCATION),41: View (NUX_TRACKER_LOCATION),
35 _proxy (proxy),42 _proxy (proxy),
3643
=== modified file 'src/PanelIndicatorObjectView.h'
--- src/PanelIndicatorObjectView.h 2010-12-02 11:55:02 +0000
+++ src/PanelIndicatorObjectView.h 2010-12-17 10:43:24 +0000
@@ -29,6 +29,7 @@
29class PanelIndicatorObjectView : public nux::View, public Introspectable29class PanelIndicatorObjectView : public nux::View, public Introspectable
30{30{
31public:31public:
32 PanelIndicatorObjectView ();
32 PanelIndicatorObjectView (IndicatorObjectProxy *proxy);33 PanelIndicatorObjectView (IndicatorObjectProxy *proxy);
33 ~PanelIndicatorObjectView ();34 ~PanelIndicatorObjectView ();
3435
@@ -47,7 +48,6 @@
47 const gchar * GetChildsName ();48 const gchar * GetChildsName ();
48 void AddProperties (GVariantBuilder *builder);49 void AddProperties (GVariantBuilder *builder);
4950
50private:
51 IndicatorObjectProxy *_proxy;51 IndicatorObjectProxy *_proxy;
52 std::vector<PanelIndicatorObjectEntryView *> _entries;52 std::vector<PanelIndicatorObjectEntryView *> _entries;
53};53};
5454
=== added file 'src/PanelMenuView.cpp'
--- src/PanelMenuView.cpp 1970-01-01 00:00:00 +0000
+++ src/PanelMenuView.cpp 2010-12-17 10:43:24 +0000
@@ -0,0 +1,671 @@
1/*
2 * Copyright (C) 2010 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 */
18#include <glib.h>
19#include <pango/pangocairo.h>
20#include <gtk/gtk.h>
21
22#include "Nux/Nux.h"
23#include "Nux/HLayout.h"
24#include "Nux/VLayout.h"
25#include <Nux/TextureArea.h>
26
27#include "NuxGraphics/GLThread.h"
28#include "Nux/BaseWindow.h"
29#include "Nux/WindowCompositor.h"
30
31#include "PanelMenuView.h"
32
33#include "WindowManager.h"
34
35#include "IndicatorObjectEntryProxy.h"
36
37#include <gio/gdesktopappinfo.h>
38
39#define BUTTONS_WIDTH 72
40
41static void on_active_window_changed (BamfMatcher *matcher,
42 BamfView *old_view,
43 BamfView *new_view,
44 PanelMenuView *self);
45
46
47PanelMenuView::PanelMenuView ()
48: _matcher (NULL),
49 _title_layer (NULL),
50 _util_cg (CAIRO_FORMAT_ARGB32, 1, 1),
51 _gradient_texture (NULL),
52 _title_tex (NULL),
53 _is_inside (false),
54 _is_maximized (false),
55 _last_active_view (NULL)
56{
57 WindowManager *win_manager;
58
59 _matcher = bamf_matcher_get_default ();
60 g_signal_connect (_matcher, "active-window-changed",
61 G_CALLBACK (on_active_window_changed), this);
62
63 _menu_layout = new nux::HLayout ("", NUX_TRACKER_LOCATION);
64
65 /* This is for our parent and for PanelView to read indicator entries, we
66 * shouldn't touch this again
67 */
68 _layout = _menu_layout;
69
70 _window_buttons = new WindowButtons ();
71 _window_buttons->NeedRedraw ();
72 _window_buttons->close_clicked.connect (sigc::mem_fun (this, &PanelMenuView::OnCloseClicked));
73 _window_buttons->minimize_clicked.connect (sigc::mem_fun (this, &PanelMenuView::OnMinimizeClicked));
74 _window_buttons->restore_clicked.connect (sigc::mem_fun (this, &PanelMenuView::OnRestoreClicked));
75 _window_buttons->redraw_signal.connect (sigc::mem_fun (this, &PanelMenuView::OnWindowButtonsRedraw));
76
77 win_manager = WindowManager::Default ();
78 win_manager->window_maximized.connect (sigc::mem_fun (this, &PanelMenuView::OnWindowMaximized));
79 win_manager->window_restored.connect (sigc::mem_fun (this, &PanelMenuView::OnWindowRestored));
80 win_manager->window_unmapped.connect (sigc::mem_fun (this, &PanelMenuView::OnWindowUnmapped));
81
82 Refresh ();
83}
84
85PanelMenuView::~PanelMenuView ()
86{
87 if (_title_layer)
88 delete _title_layer;
89 if (_title_tex)
90 _title_tex->UnReference ();
91
92 _menu_layout->UnReference ();
93 _window_buttons->UnReference ();
94}
95
96void
97PanelMenuView::FullRedraw ()
98{
99 _menu_layout->NeedRedraw ();
100 _window_buttons->NeedRedraw ();
101 NeedRedraw ();
102}
103
104void
105PanelMenuView::SetProxy (IndicatorObjectProxy *proxy)
106{
107 _proxy = proxy;
108 printf ("IndicatorAdded: %s\n", _proxy->GetName ().c_str ());
109
110 _proxy->OnEntryAdded.connect (sigc::mem_fun (this, &PanelMenuView::OnEntryAdded));
111 _proxy->OnEntryMoved.connect (sigc::mem_fun (this, &PanelMenuView::OnEntryMoved));
112 _proxy->OnEntryRemoved.connect (sigc::mem_fun (this, &PanelMenuView::OnEntryRemoved));
113}
114
115long
116PanelMenuView::ProcessEvent (nux::IEvent &ievent, long TraverseInfo, long ProcessEventInfo)
117{
118 long ret = TraverseInfo;
119 nux::Geometry geo = GetGeometry ();
120
121 if (geo.IsPointInside (ievent.e_x, ievent.e_y))
122 {
123 if (_is_inside != true)
124 {
125 _is_inside = true;
126 FullRedraw ();
127 }
128 }
129 else
130 {
131 if (_is_inside != false)
132 {
133 _is_inside = false;
134 FullRedraw ();
135 }
136 }
137
138 if (_is_maximized)
139 ret = _window_buttons->ProcessEvent (ievent, ret, ProcessEventInfo);
140 ret = _menu_layout->ProcessEvent (ievent, ret, ProcessEventInfo);
141
142 return ret;
143}
144
145long PanelMenuView::PostLayoutManagement (long LayoutResult)
146{
147 long res = View::PostLayoutManagement (LayoutResult);
148 int w = _window_buttons->GetContentWidth ();
149
150 nux::Geometry geo = GetGeometry ();
151
152 _window_buttons->SetGeometry (geo.x + PADDING, geo.y, w, geo.height);
153 _window_buttons->ComputeLayout2 ();
154
155 /* Explicitly set the size and position of the widgets */
156 geo.x += PADDING + w + PADDING;
157 geo.width -= PADDING + w + PADDING;
158
159 _menu_layout->SetGeometry (geo.x, geo.y, geo.width, geo.height);
160 _menu_layout->ComputeLayout2();
161
162 Refresh ();
163
164 return res;
165}
166
167void
168PanelMenuView::Draw (nux::GraphicsEngine& GfxContext, bool force_draw)
169{
170 nux::Geometry geo = GetGeometry ();
171 int button_width = PADDING + _window_buttons->GetContentWidth () + PADDING;
172 float factor = 4;
173 button_width /= factor;
174
175 GfxContext.PushClippingRectangle (geo);
176
177 /* "Clear" out the background */
178 nux::ROPConfig rop;
179 rop.Blend = true;
180 rop.SrcBlend = GL_ONE;
181 rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA;
182
183 nux::ColorLayer layer (nux::Color (0x00000000), true, rop);
184 gPainter.PushDrawLayer (GfxContext, GetGeometry (), &layer);
185
186 if (_is_maximized)
187 {
188 if (!_is_inside)
189 gPainter.PushDrawLayer (GfxContext, GetGeometry (), _title_layer);
190 }
191 else
192 {
193 if (_is_inside || _last_active_view)
194 {
195 if (_gradient_texture == NULL)
196 {
197 nux::NTextureData texture_data (nux::BITFMT_R8G8B8A8, geo.width, 1, 1);
198 nux::ImageSurface surface = texture_data.GetSurface (0);
199 nux::SURFACE_LOCKED_RECT lockrect;
200 BYTE *dest;
201 int num_row;
202
203 _gradient_texture = nux::GetThreadGLDeviceFactory ()->CreateSystemCapableDeviceTexture (texture_data.GetWidth (), texture_data.GetHeight (), 1, texture_data.GetFormat ());
204
205 _gradient_texture->LockRect (0, &lockrect, 0);
206
207 dest = (BYTE *) lockrect.pBits;
208 num_row = surface.GetBlockHeight ();
209
210 for (int y = 0; y < num_row; y++)
211 {
212 for (int x = 0; x < geo.width; x++)
213 {
214 *(dest + y * lockrect.Pitch + 4*x + 0) = 223; //red
215 *(dest + y * lockrect.Pitch + 4*x + 1) = 219; //green
216 *(dest + y * lockrect.Pitch + 4*x + 2) = 210; //blue
217
218 if (x < button_width * (factor - 1))
219 {
220 *(dest + y * lockrect.Pitch + 4*x + 3) = 0xff;
221 }
222 else if (x < button_width * factor)
223 {
224 *(dest + y * lockrect.Pitch + 4*x + 3) = 255 - 255 * (((float)x-(button_width * (factor -1)))/(float)(button_width));
225 }
226 else
227 {
228 *(dest + y * lockrect.Pitch + 4*x + 3) = 0x00;
229 }
230 }
231 }
232 _gradient_texture->UnlockRect (0);
233 }
234 GfxContext.GetRenderStates ().SetBlend(true, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
235
236 nux::TexCoordXForm texxform0;
237 nux::TexCoordXForm texxform1;
238
239 // Modulate the checkboard and the gradient texture
240 GfxContext.QRP_2TexMod(geo.x, geo.y,
241 geo.width, geo.height,
242 _gradient_texture, texxform0,
243 nux::Color::White,
244 _title_tex->GetDeviceTexture (),
245 texxform1,
246 nux::Color::White);
247
248 GfxContext.GetRenderStates ().SetBlend(false);
249
250 // The previous blend is too aggressive on the texture and therefore there
251 // is a slight loss of clarity. This fixes that
252 geo.width = button_width * (factor - 1);
253 gPainter.PushDrawLayer (GfxContext, geo, _title_layer);
254 geo = GetGeometry ();
255 }
256 else
257 {
258 gPainter.PushDrawLayer (GfxContext,
259 geo,
260 _title_layer);
261 }
262 }
263
264 gPainter.PopBackground ();
265
266 GfxContext.PopClippingRectangle();
267}
268
269void
270PanelMenuView::DrawContent (nux::GraphicsEngine &GfxContext, bool force_draw)
271{
272 nux::Geometry geo = GetGeometry ();
273
274 GfxContext.PushClippingRectangle (geo);
275
276 if (_is_inside || _last_active_view)
277 {
278 _layout->ProcessDraw (GfxContext, force_draw);
279 }
280
281 if (_is_maximized)
282 {
283 _window_buttons->ProcessDraw (GfxContext, true);
284 }
285
286 GfxContext.PopClippingRectangle();
287}
288
289gchar *
290PanelMenuView::GetActiveViewName ()
291{
292 gchar *label = NULL;
293
294 if (_is_maximized)
295 {
296 BamfWindow *window = bamf_matcher_get_active_window (_matcher);
297
298 if (BAMF_IS_WINDOW (window))
299 label = g_strdup (bamf_view_get_name (BAMF_VIEW (window)));
300 }
301
302 if (!label)
303 {
304 BamfApplication *app = bamf_matcher_get_active_application (_matcher);
305 if (BAMF_IS_APPLICATION (app))
306 {
307 const gchar *filename;
308
309 filename = bamf_application_get_desktop_file (app);
310
311 if (filename && g_strcmp0 (filename, "") != 0)
312 {
313 GDesktopAppInfo *info;
314
315 info = g_desktop_app_info_new_from_filename (bamf_application_get_desktop_file (app));
316
317 if (info)
318 {
319 label = g_strdup (g_app_info_get_display_name (G_APP_INFO (info)));
320 g_object_unref (info);
321 }
322 else
323 {
324 g_warning ("Unable to get GDesktopAppInfo for %s",
325 bamf_application_get_desktop_file (app));
326 }
327 }
328
329 if (label == NULL)
330 {
331 BamfView *active_view;
332
333 active_view = (BamfView *)bamf_matcher_get_active_window (_matcher);
334 if (BAMF_IS_VIEW (active_view))
335 label = g_strdup (bamf_view_get_name (active_view));
336 else
337 label = g_strdup ("");
338 }
339 }
340 else
341 {
342 label = g_strdup (" ");
343 }
344 }
345
346 return label;
347}
348
349void
350PanelMenuView::Refresh ()
351{
352 nux::Geometry geo = GetGeometry ();
353 char *label = GetActiveViewName ();
354 PangoLayout *layout = NULL;
355 PangoFontDescription *desc = NULL;
356 GtkSettings *settings = gtk_settings_get_default ();
357 cairo_t *cr;
358 char *font_description = NULL;
359 GdkScreen *screen = gdk_screen_get_default ();
360 int dpi = 0;
361
362 int x = 0;
363 int y = 0;
364 int width = geo.width;
365 int height = geo.height;
366 int text_width = 0;
367 int text_height = 0;
368
369 if (label)
370 {
371 PangoContext *cxt;
372 PangoRectangle log_rect;
373
374 cr = _util_cg.GetContext ();
375
376 g_object_get (settings,
377 "gtk-font-name", &font_description,
378 "gtk-xft-dpi", &dpi,
379 NULL);
380 desc = pango_font_description_from_string (font_description);
381 pango_font_description_set_weight (desc, PANGO_WEIGHT_BOLD);
382
383 layout = pango_cairo_create_layout (cr);
384 pango_layout_set_font_description (layout, desc);
385 pango_layout_set_text (layout, label, -1);
386
387 cxt = pango_layout_get_context (layout);
388 pango_cairo_context_set_font_options (cxt, gdk_screen_get_font_options (screen));
389 pango_cairo_context_set_resolution (cxt, (float)dpi/(float)PANGO_SCALE);
390 pango_layout_context_changed (layout);
391
392 pango_layout_get_extents (layout, NULL, &log_rect);
393 text_width = log_rect.width / PANGO_SCALE;
394 text_height = log_rect.height / PANGO_SCALE;
395
396 pango_font_description_free (desc);
397 g_free (font_description);
398 cairo_destroy (cr);
399 }
400
401 nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, width, height);
402 cr = cairo_graphics.GetContext();
403 cairo_set_line_width (cr, 1);
404
405 x = PADDING;
406 y = 0;
407
408 if (_is_maximized)
409 x += _window_buttons->GetContentWidth () + PADDING + PADDING;
410
411 if (label)
412 {
413 pango_cairo_update_layout (cr, layout);
414
415 // Once for the homies that couldn't be here
416 cairo_set_source_rgb (cr, 50/255.0f, 50/255.0f, 45/255.0f);
417 cairo_move_to (cr, x, ((height - text_height)/2)-1);
418 pango_cairo_show_layout (cr, layout);
419 cairo_stroke (cr);
420
421 // Once again for the homies that could
422 cairo_set_source_rgba (cr, 223/255.0f, 219/255.0f, 210/255.0f, 1.0f);
423 cairo_move_to (cr, x, (height - text_height)/2);
424 pango_cairo_show_layout (cr, layout);
425 cairo_stroke (cr);
426 }
427
428 cairo_destroy (cr);
429 if (layout)
430 g_object_unref (layout);
431
432 nux::NBitmapData* bitmap = cairo_graphics.GetBitmap();
433
434 // The Texture is created with a reference count of 1.
435 nux::BaseTexture* texture2D = nux::GetThreadGLDeviceFactory ()->CreateSystemCapableTexture ();
436 texture2D->Update(bitmap);
437 delete bitmap;
438
439 if (_title_layer)
440 delete _title_layer;
441
442 nux::TexCoordXForm texxform;
443 texxform.SetTexCoordType (nux::TexCoordXForm::OFFSET_COORD);
444 texxform.SetWrap (nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT);
445
446 nux::ROPConfig rop;
447 rop.Blend = true;
448 rop.SrcBlend = GL_ONE;
449 rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA;
450 _title_layer = new nux::TextureLayer (texture2D->GetDeviceTexture(),
451 texxform,
452 nux::Color::White,
453 false,
454 rop);
455
456
457 if (_title_tex)
458 _title_tex->UnReference ();
459
460 _title_tex = texture2D;
461
462 g_free (label);
463}
464
465void
466PanelMenuView::OnActiveChanged (PanelIndicatorObjectEntryView *view,
467 bool is_active)
468{
469 if (is_active)
470 _last_active_view = view;
471 else
472 {
473 if (_last_active_view == view)
474 {
475 _last_active_view = NULL;
476 }
477 }
478 FullRedraw ();
479}
480
481void
482PanelMenuView::OnEntryAdded (IndicatorObjectEntryProxy *proxy)
483{
484 PanelIndicatorObjectEntryView *view = new PanelIndicatorObjectEntryView (proxy);
485 view->active_changed.connect (sigc::mem_fun (this, &PanelMenuView::OnActiveChanged));
486 _menu_layout->AddView (view, 0, nux::eCenter, nux::eFull);
487 _menu_layout->SetContentDistribution (nux::eStackLeft);
488
489 _entries.push_back (view);
490
491 AddChild (view);
492
493 this->ComputeChildLayout ();
494 NeedRedraw ();
495}
496
497void
498PanelMenuView::OnEntryMoved (IndicatorObjectEntryProxy *proxy)
499{
500 printf ("ERROR: Moving IndicatorObjectEntry not supported\n");
501}
502
503void
504PanelMenuView::OnEntryRemoved(IndicatorObjectEntryProxy *proxy)
505{
506 std::vector<PanelIndicatorObjectEntryView *>::iterator it;
507
508 for (it = _entries.begin(); it != _entries.end(); it++)
509 {
510 PanelIndicatorObjectEntryView *view = static_cast<PanelIndicatorObjectEntryView *> (*it);
511 if (view->_proxy == proxy)
512 {
513 RemoveChild (view);
514 _entries.erase (it);
515 _menu_layout->RemoveChildObject (view);
516
517 break;
518 }
519 }
520
521 this->ComputeChildLayout ();
522 NeedRedraw ();
523}
524
525void
526PanelMenuView::AllMenusClosed ()
527{
528 _is_inside = false;
529 _last_active_view = false;
530
531 FullRedraw ();
532}
533
534void
535PanelMenuView::OnActiveWindowChanged (BamfView *old_view,
536 BamfView *new_view)
537{
538 _is_maximized = false;
539
540 if (BAMF_IS_WINDOW (new_view))
541 {
542 BamfWindow *window = BAMF_WINDOW (new_view);
543 _is_maximized = WindowManager::Default ()->IsWindowMaximized (bamf_window_get_xid (window));
544 }
545
546 Refresh ();
547 FullRedraw ();
548}
549
550void
551PanelMenuView::OnWindowUnmapped (guint32 xid)
552{
553 _decor_map.erase (xid);
554}
555
556void
557PanelMenuView::OnWindowMaximized (guint xid)
558{
559 BamfWindow *window;
560
561 window = bamf_matcher_get_active_window (_matcher);
562 if (BAMF_IS_WINDOW (window) && bamf_window_get_xid (window) == xid)
563 {
564 // We could probably just check if a key is available, but who wants to do that
565 if (_decor_map.find (xid) == _decor_map.end ())
566 _decor_map[xid] = WindowManager::Default ()->IsWindowDecorated (xid);
567
568 if (_decor_map[xid])
569 {
570 WindowManager::Default ()->Undecorate (xid);
571 }
572
573 _is_maximized = true;
574
575 Refresh ();
576 FullRedraw ();
577 }
578}
579
580void
581PanelMenuView::OnWindowRestored (guint xid)
582{
583 BamfWindow *window;
584
585 window = bamf_matcher_get_active_window (_matcher);
586 if (BAMF_IS_WINDOW (window) && bamf_window_get_xid (window) == xid)
587 {
588 _is_maximized = false;
589
590 if (_decor_map[xid])
591 {
592 WindowManager::Default ()->Decorate (xid);
593 }
594
595 Refresh ();
596 FullRedraw ();
597 }
598}
599
600void
601PanelMenuView::OnCloseClicked ()
602{
603 BamfWindow *window;
604
605 window = bamf_matcher_get_active_window (_matcher);
606 if (BAMF_IS_WINDOW (window))
607 WindowManager::Default ()->Close (bamf_window_get_xid (window));
608}
609
610void
611PanelMenuView::OnMinimizeClicked ()
612{
613 BamfWindow *window;
614
615 window = bamf_matcher_get_active_window (_matcher);
616 if (BAMF_IS_WINDOW (window))
617 WindowManager::Default ()->Minimize (bamf_window_get_xid (window));
618}
619
620void
621PanelMenuView::OnRestoreClicked ()
622{
623 BamfWindow *window;
624
625 window = bamf_matcher_get_active_window (_matcher);
626 if (BAMF_IS_WINDOW (window))
627 WindowManager::Default ()->Restore (bamf_window_get_xid (window));
628}
629
630void
631PanelMenuView::OnWindowButtonsRedraw ()
632{
633 FullRedraw ();
634}
635
636// Introspectable
637const gchar *
638PanelMenuView::GetName ()
639{
640 return "MenuView";
641}
642
643const gchar *
644PanelMenuView::GetChildsName ()
645{
646 return "entries";
647}
648
649void
650PanelMenuView::AddProperties (GVariantBuilder *builder)
651{
652 nux::Geometry geo = GetGeometry ();
653
654 /* Now some props from ourselves */
655 g_variant_builder_add (builder, "{sv}", "x", g_variant_new_int32 (geo.x));
656 g_variant_builder_add (builder, "{sv}", "y", g_variant_new_int32 (geo.y));
657 g_variant_builder_add (builder, "{sv}", "width", g_variant_new_int32 (geo.width));
658 g_variant_builder_add (builder, "{sv}", "height", g_variant_new_int32 (geo.height));
659}
660
661/*
662 * C code for callbacks
663 */
664static void
665on_active_window_changed (BamfMatcher *matcher,
666 BamfView *old_view,
667 BamfView *new_view,
668 PanelMenuView *self)
669{
670 self->OnActiveWindowChanged (old_view, new_view);
671}
0672
=== added file 'src/PanelMenuView.h'
--- src/PanelMenuView.h 1970-01-01 00:00:00 +0000
+++ src/PanelMenuView.h 2010-12-17 10:43:24 +0000
@@ -0,0 +1,103 @@
1/*
2 * Copyright (C) 2010 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 */
18
19#ifndef PANEL_MENU_VIEW_H
20#define PANEL_MENU_VIEW_H
21
22#include <Nux/View.h>
23#include <map>
24
25#include "IndicatorObjectProxy.h"
26#include "Introspectable.h"
27#include "PanelIndicatorObjectView.h"
28#include "StaticCairoText.h"
29#include "WindowButtons.h"
30
31#include <libbamf/libbamf.h>
32
33class PanelMenuView : public PanelIndicatorObjectView
34{
35public:
36 // This contains all the menubar logic for the Panel. Mainly it contains
37 // the following states:
38 // 1. Unmaximized window + no mouse hover
39 // 2. Unmaximized window + mouse hover
40 // 3. Unmaximized window + active menu (Alt+F/arrow key nav)
41 // 4. Maximized window + no mouse hover
42 // 5. Maximized window + mouse hover
43 // 6. Maximized window + active menu
44 //
45 // It also deals with undecorating maximized windows (and redecorating them
46 // on unmaximize)
47
48 PanelMenuView ();
49 ~PanelMenuView ();
50
51 void FullRedraw ();
52
53 virtual long ProcessEvent (nux::IEvent &ievent, long TraverseInfo, long ProcessEventInfo);
54 virtual void Draw (nux::GraphicsEngine& GfxContext, bool force_draw);
55 virtual void DrawContent (nux::GraphicsEngine &GfxContext, bool force_draw);
56 virtual long PostLayoutManagement (long LayoutResult);
57
58 void SetProxy (IndicatorObjectProxy *proxy);
59
60 void OnEntryAdded (IndicatorObjectEntryProxy *proxy);
61 void OnEntryMoved (IndicatorObjectEntryProxy *proxy);
62 void OnEntryRemoved (IndicatorObjectEntryProxy *proxy);
63 void OnActiveChanged (PanelIndicatorObjectEntryView *view, bool is_active);
64 void OnActiveWindowChanged (BamfView *old_view, BamfView *new_view);
65
66 void OnWindowUnmapped (guint xid);
67 void OnWindowMaximized (guint32 xid);
68 void OnWindowRestored (guint32 xid);
69
70 void Refresh ();
71 void AllMenusClosed ();
72
73 void OnCloseClicked ();
74 void OnMinimizeClicked ();
75 void OnRestoreClicked ();
76 void OnWindowButtonsRedraw ();
77
78protected:
79 const gchar * GetName ();
80 const gchar * GetChildsName ();
81 void AddProperties (GVariantBuilder *builder);
82
83private:
84 gchar * GetActiveViewName ();
85
86private:
87 BamfMatcher* _matcher;
88
89 nux::AbstractPaintLayer *_title_layer;
90 nux::HLayout *_menu_layout;
91 nux::CairoGraphics _util_cg;
92 nux::IntrusiveSP<nux::IOpenGLBaseTexture> _gradient_texture;
93 nux::BaseTexture *_title_tex;
94
95 bool _is_inside;
96 bool _is_maximized;
97 PanelIndicatorObjectEntryView *_last_active_view;
98
99 WindowButtons *_window_buttons;
100
101 std::map<guint32, bool> _decor_map;
102};
103#endif
0104
=== modified file 'src/PanelView.cpp'
--- src/PanelView.cpp 2010-12-09 17:58:53 +0000
+++ src/PanelView.cpp 2010-12-17 10:43:24 +0000
@@ -46,13 +46,17 @@
46 // Home button46 // Home button
47 _home_button = new PanelHomeButton ();47 _home_button = new PanelHomeButton ();
48 _layout->AddView (_home_button, 0, nux::eCenter, nux::eFull);48 _layout->AddView (_home_button, 0, nux::eCenter, nux::eFull);
49
50 AddChild (_home_button);49 AddChild (_home_button);
5150
51 _menu_view = new PanelMenuView ();
52 _layout->AddView (_menu_view, 1, nux::eCenter, nux::eFull);
53 AddChild (_menu_view);
54
52 _remote = new IndicatorObjectFactoryRemote ();55 _remote = new IndicatorObjectFactoryRemote ();
53 _remote->OnObjectAdded.connect (sigc::mem_fun (this, &PanelView::OnObjectAdded));56 _remote->OnObjectAdded.connect (sigc::mem_fun (this, &PanelView::OnObjectAdded));
54 _remote->OnMenuPointerMoved.connect (sigc::mem_fun (this, &PanelView::OnMenuPointerMoved));57 _remote->OnMenuPointerMoved.connect (sigc::mem_fun (this, &PanelView::OnMenuPointerMoved));
55 _remote->OnEntryActivateRequest.connect (sigc::mem_fun (this, &PanelView::OnEntryActivateRequest));58 _remote->OnEntryActivateRequest.connect (sigc::mem_fun (this, &PanelView::OnEntryActivateRequest));
59 _remote->IndicatorObjectFactory::OnEntryActivated.connect (sigc::mem_fun (this, &PanelView::OnEntryActivated));
56}60}
5761
58PanelView::~PanelView ()62PanelView::~PanelView ()
@@ -204,7 +208,11 @@
204208
205 // Appmenu is treated differently as it needs to expand209 // Appmenu is treated differently as it needs to expand
206 // We could do this in a more special way, but who has the time for special?210 // We could do this in a more special way, but who has the time for special?
207 _layout->AddView (view, (g_strstr_len (proxy->GetName ().c_str (), -1, "appmenu") != NULL), nux::eCenter, nux::eFull);211 if (g_strstr_len (proxy->GetName ().c_str (), -1, "appmenu") != NULL)
212 _menu_view->SetProxy (proxy);
213 else
214 _layout->AddView (view, 0, nux::eCenter, nux::eFull);
215
208 _layout->SetContentDistribution (nux::eStackLeft);216 _layout->SetContentDistribution (nux::eStackLeft);
209 217
210 AddChild (view);218 AddChild (view);
@@ -224,40 +232,40 @@
224 232
225 if (x >= geo.x && x <= (geo.x + geo.width)233 if (x >= geo.x && x <= (geo.x + geo.width)
226 && y >= geo.y && y <= (geo.y + geo.height))234 && y >= geo.y && y <= (geo.y + geo.height))
235 {
236 std::list<Area *>::iterator it;
237
238 std::list<Area *> my_children = _layout->GetChildren ();
239 for (it = my_children.begin(); it != my_children.end(); it++)
227 {240 {
228 std::list<Area *>::iterator it;241 PanelIndicatorObjectView *view = static_cast<PanelIndicatorObjectView *> (*it);
242
243 if (view->_layout == NULL)
244 continue;
229245
230 std::list<Area *> my_children = _layout->GetChildren ();246 geo = view->GetGeometry ();
231 for (it = my_children.begin(); it != my_children.end(); it++)247 if (x >= geo.x && x <= (geo.x + geo.width)
248 && y >= geo.y && y <= (geo.y + geo.height))
232 {249 {
233 PanelIndicatorObjectView *view = static_cast<PanelIndicatorObjectView *> (*it);250 std::list<Area *>::iterator it2;
234 251
235 if (view->_layout == NULL)252 std::list<Area *> its_children = view->_layout->GetChildren ();
236 continue;253 for (it2 = its_children.begin(); it2 != its_children.end(); it2++)
237254 {
238 geo = view->GetGeometry ();255 PanelIndicatorObjectEntryView *entry = static_cast<PanelIndicatorObjectEntryView *> (*it2);
239 if (x >= geo.x && x <= (geo.x + geo.width)256
240 && y >= geo.y && y <= (geo.y + geo.height))257 geo = entry->GetGeometry ();
258 if (x >= geo.x && x <= (geo.x + geo.width)
259 && y >= geo.y && y <= (geo.y + geo.height))
241 {260 {
242 std::list<Area *>::iterator it2;261 entry->OnMouseDown (x, y, 0, 0);
243
244 std::list<Area *> its_children = view->_layout->GetChildren ();
245 for (it2 = its_children.begin(); it2 != its_children.end(); it2++)
246 {
247 PanelIndicatorObjectEntryView *entry = static_cast<PanelIndicatorObjectEntryView *> (*it2);
248
249 geo = entry->GetGeometry ();
250 if (x >= geo.x && x <= (geo.x + geo.width)
251 && y >= geo.y && y <= (geo.y + geo.height))
252 {
253 entry->OnMouseDown (x, y, 0, 0);
254 break;
255 }
256 }
257 break;262 break;
258 }263 }
264 }
265 break;
259 }266 }
260 }267 }
268 }
261}269}
262270
263void271void
@@ -281,10 +289,18 @@
281 PanelIndicatorObjectEntryView *entry = static_cast<PanelIndicatorObjectEntryView *> (*it2);289 PanelIndicatorObjectEntryView *entry = static_cast<PanelIndicatorObjectEntryView *> (*it2);
282290
283 if (g_strcmp0 (entry->GetName (), entry_id) == 0)291 if (g_strcmp0 (entry->GetName (), entry_id) == 0)
284 {292 {
285 entry->Activate ();293 g_debug ("%s: Activating: %s", G_STRFUNC, entry_id);
286 break;294 entry->Activate ();
287 }295 break;
296 }
288 }297 }
289 }298 }
290}299}
300
301void
302PanelView::OnEntryActivated (const char *entry_id)
303{
304 if (g_strcmp0 (entry_id, "") == 0)
305 _menu_view->AllMenusClosed ();
306}
291307
=== modified file 'src/PanelView.h'
--- src/PanelView.h 2010-12-07 13:55:04 +0000
+++ src/PanelView.h 2010-12-17 10:43:24 +0000
@@ -24,6 +24,7 @@
24#include <NuxGraphics/GraphicsEngine.h>24#include <NuxGraphics/GraphicsEngine.h>
2525
26#include "PanelHomeButton.h"26#include "PanelHomeButton.h"
27#include "PanelMenuView.h"
27#include "IndicatorObjectFactoryRemote.h"28#include "IndicatorObjectFactoryRemote.h"
28#include "Introspectable.h"29#include "Introspectable.h"
2930
@@ -43,6 +44,7 @@
43 void OnObjectAdded (IndicatorObjectProxy *proxy);44 void OnObjectAdded (IndicatorObjectProxy *proxy);
44 void OnMenuPointerMoved (int x, int y);45 void OnMenuPointerMoved (int x, int y);
45 void OnEntryActivateRequest (const char *entry_id);46 void OnEntryActivateRequest (const char *entry_id);
47 void OnEntryActivated (const char *entry_id);
46 48
47 PanelHomeButton * HomeButton ();49 PanelHomeButton * HomeButton ();
4850
@@ -59,6 +61,7 @@
59 IndicatorObjectFactoryRemote *_remote;61 IndicatorObjectFactoryRemote *_remote;
6062
61 PanelHomeButton *_home_button;63 PanelHomeButton *_home_button;
64 PanelMenuView *_menu_view;
62 nux::AbstractPaintLayer *_bg_layer;65 nux::AbstractPaintLayer *_bg_layer;
63 nux::HLayout *_layout;66 nux::HLayout *_layout;
6467
6568
=== modified file 'src/PluginAdapter.cpp'
--- src/PluginAdapter.cpp 2010-12-17 10:03:18 +0000
+++ src/PluginAdapter.cpp 2010-12-17 10:43:24 +0000
@@ -65,9 +65,15 @@
65PluginAdapter::NotifyStateChange (CompWindow *window, unsigned int state, unsigned int last_state)65PluginAdapter::NotifyStateChange (CompWindow *window, unsigned int state, unsigned int last_state)
66{66{
67 if (!(last_state & MAXIMIZE_STATE) && (state & MAXIMIZE_STATE))67 if (!(last_state & MAXIMIZE_STATE) && (state & MAXIMIZE_STATE))
68 window_maximized.emit (window);68 {
69 PluginAdapter::window_maximized.emit (window);
70 WindowManager::window_maximized.emit (window->id ());
71 }
69 else if ((last_state & MAXIMIZE_STATE) && !(state & MAXIMIZE_STATE))72 else if ((last_state & MAXIMIZE_STATE) && !(state & MAXIMIZE_STATE))
70 window_restored.emit (window);73 {
74 PluginAdapter::window_restored.emit (window);
75 WindowManager::window_restored.emit (window->id ());
76 }
71}77}
7278
73void 79void
@@ -94,10 +100,12 @@
94 window_shown.emit (window);100 window_shown.emit (window);
95 break;101 break;
96 case CompWindowNotifyMap:102 case CompWindowNotifyMap:
97 window_mapped.emit (window);103 PluginAdapter::window_mapped.emit (window);
104 WindowManager::window_mapped.emit (window->id ());
98 break;105 break;
99 case CompWindowNotifyUnmap:106 case CompWindowNotifyUnmap:
100 window_unmapped.emit (window);107 PluginAdapter::window_unmapped.emit (window);
108 WindowManager::window_unmapped.emit (window->id ());
101 break;109 break;
102 default:110 default:
103 break;111 break;
@@ -216,3 +224,68 @@
216 224
217 m_ExpoAction->initiate () (m_ExpoAction, 0, argument);225 m_ExpoAction->initiate () (m_ExpoAction, 0, argument);
218}226}
227
228// WindowManager implementation
229bool
230PluginAdapter::IsWindowMaximized (guint xid)
231{
232 Window win = (Window)xid;
233 CompWindow *window;
234
235 window = m_Screen->findWindow (win);
236 if (window)
237 {
238 return window->state () & MAXIMIZE_STATE;
239 }
240
241 return false;
242}
243
244bool
245PluginAdapter::IsWindowDecorated (guint32 xid)
246{
247 Window win = (Window)xid;
248 CompWindow *window;
249
250 window = m_Screen->findWindow (win);
251 if (window)
252 {
253 unsigned int decor = window->mwmDecor ();
254
255 return decor & (MwmDecorAll | MwmDecorTitle);
256 }
257 return true;
258}
259
260void
261PluginAdapter::Restore (guint32 xid)
262{
263 Window win = (Window)xid;
264 CompWindow *window;
265
266 window = m_Screen->findWindow (win);
267 if (window)
268 window->maximize (0);
269}
270
271void
272PluginAdapter::Minimize (guint32 xid)
273{
274 Window win = (Window)xid;
275 CompWindow *window;
276
277 window = m_Screen->findWindow (win);
278 if (window)
279 window->minimize ();
280}
281
282void
283PluginAdapter::Close (guint32 xid)
284{
285 Window win = (Window)xid;
286 CompWindow *window;
287
288 window = m_Screen->findWindow (win);
289 if (window)
290 window->close (CurrentTime);
291}
219292
=== modified file 'src/PluginAdapter.h'
--- src/PluginAdapter.h 2010-12-17 10:03:18 +0000
+++ src/PluginAdapter.h 2010-12-17 10:43:24 +0000
@@ -24,7 +24,9 @@
2424
25#include <sigc++/sigc++.h>25#include <sigc++/sigc++.h>
2626
27class PluginAdapter : public sigc::trackable27#include "WindowManager.h"
28
29class PluginAdapter : public sigc::trackable, public WindowManager
28{30{
29public:31public:
30 static PluginAdapter * Default ();32 static PluginAdapter * Default ();
@@ -52,6 +54,13 @@
52 void NotifyResized (CompWindow *window, int x, int y, int w, int h);54 void NotifyResized (CompWindow *window, int x, int y, int w, int h);
53 void NotifyStateChange (CompWindow *window, unsigned int state, unsigned int last_state);55 void NotifyStateChange (CompWindow *window, unsigned int state, unsigned int last_state);
54 56
57 // WindowManager implementation
58 bool IsWindowMaximized (guint xid);
59 bool IsWindowDecorated (guint xid);
60 void Restore (guint32 xid);
61 void Minimize (guint32 xid);
62 void Close (guint32 xid);
63
55 sigc::signal<void, CompWindow *> window_maximized;64 sigc::signal<void, CompWindow *> window_maximized;
56 sigc::signal<void, CompWindow *> window_restored;65 sigc::signal<void, CompWindow *> window_restored;
57 sigc::signal<void, CompWindow *> window_minimized;66 sigc::signal<void, CompWindow *> window_minimized;
5867
=== added file 'src/WindowButtons.cpp'
--- src/WindowButtons.cpp 1970-01-01 00:00:00 +0000
+++ src/WindowButtons.cpp 2010-12-17 10:43:24 +0000
@@ -0,0 +1,254 @@
1/*
2 * Copyright (C) 2010 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 */
18
19#include "Nux/Nux.h"
20#include "Nux/HLayout.h"
21#include "Nux/VLayout.h"
22#include "Nux/Button.h"
23
24#include "NuxGraphics/GLThread.h"
25#include "Nux/BaseWindow.h"
26#include "Nux/WindowCompositor.h"
27
28#include "WindowButtons.h"
29
30#include <glib.h>
31
32
33// FIXME: This will be all automatic in the future
34#define AMBIANCE "/usr/share/themes/Ambiance/metacity-1"
35
36enum
37{
38 BUTTON_CLOSE=0,
39 BUTTON_MINIMISE,
40 BUTTON_UNMAXIMISE
41};
42
43class WindowButton : public nux::Button
44{
45 // A single window button
46public:
47 WindowButton (int type)
48 : nux::Button ("X", NUX_TRACKER_LOCATION),
49 _normal_tex (NULL),
50 _prelight_tex (NULL),
51 _pressed_tex (NULL)
52 {
53 if (type == BUTTON_CLOSE)
54 LoadImages ("close");
55 else if (type == BUTTON_MINIMISE)
56 LoadImages ("minimize");
57 else
58 LoadImages ("unmaximize");
59 }
60
61 ~WindowButton ()
62 {
63 _normal_tex->UnReference ();
64 _prelight_tex->UnReference ();
65 _pressed_tex->UnReference ();
66 }
67
68 void Draw (nux::GraphicsEngine &GfxContext, bool force_draw)
69 {
70 nux::Geometry geo = GetGeometry ();
71 nux::BaseTexture *tex;
72 nux::TexCoordXForm texxform;
73
74 GfxContext.PushClippingRectangle (geo);
75
76 if (HasMouseFocus ())
77 {
78 tex = _pressed_tex;
79 }
80 else if (IsMouseInside ())
81 {
82 tex = _prelight_tex;
83 }
84 else
85 {
86 tex = _normal_tex;
87 }
88
89 GfxContext.GetRenderStates ().SetSeparateBlend (true,
90 GL_SRC_ALPHA,
91 GL_ONE_MINUS_SRC_ALPHA,
92 GL_ONE_MINUS_DST_ALPHA,
93 GL_ONE);
94 GfxContext.GetRenderStates ().SetColorMask (true, true, true, true);
95 if (tex)
96 GfxContext.QRP_GLSL_1Tex (geo.x,
97 geo.y,
98 (float)geo.width,
99 (float)geo.height,
100 tex->GetDeviceTexture (),
101 texxform,
102 nux::Color::White);
103 GfxContext.GetRenderStates ().SetSeparateBlend (false,
104 GL_SRC_ALPHA,
105 GL_ONE_MINUS_SRC_ALPHA,
106 GL_ONE_MINUS_DST_ALPHA,
107 GL_ONE);
108 GfxContext.PopClippingRectangle();
109 }
110
111 void LoadImages (const char *name)
112 {
113 //FIXME: We need to somehow be theme aware. Or, at least support the themes
114 // we know and have a good default fallback
115 gchar *filename;
116 GError *error = NULL;
117 GdkPixbuf *_normal;
118 GdkPixbuf *_prelight;
119 GdkPixbuf *_pressed;
120
121 filename = g_strdup_printf ("%s/%s.png", AMBIANCE, name);
122 _normal = gdk_pixbuf_new_from_file (filename, &error);
123 if (error)
124 {
125 g_warning ("Unable to load window button %s: %s", filename, error->message);
126 g_error_free (error);
127 error = NULL;
128 }
129 else
130 _normal_tex = nux::CreateTextureFromPixbuf (_normal);
131 g_free (filename);
132 g_object_unref (_normal);
133
134 filename = g_strdup_printf ("%s/%s_focused_prelight.png", AMBIANCE, name);
135 _prelight = gdk_pixbuf_new_from_file (filename, &error);
136 if (error)
137 {
138 g_warning ("Unable to load window button %s: %s", filename, error->message);
139 g_error_free (error);
140 error = NULL;
141 }
142 else
143 _prelight_tex = nux::CreateTextureFromPixbuf (_prelight);
144 g_free (filename);
145 g_object_unref (_prelight);
146
147 filename = g_strdup_printf ("%s/%s_focused_pressed.png", AMBIANCE, name);
148 _pressed = gdk_pixbuf_new_from_file (filename, &error);
149 if (error)
150 {
151 g_warning ("Unable to load window button %s: %s", name, error->message);
152 g_error_free (error);
153 error = NULL;
154 }
155 else
156 _pressed_tex = nux::CreateTextureFromPixbuf (_pressed);
157 g_free (filename);
158 g_object_unref (_pressed);
159
160 if (_normal_tex)
161 SetMinimumSize (_normal_tex->GetWidth (), _normal_tex->GetHeight ());
162 }
163
164private:
165 nux::BaseTexture *_normal_tex;
166 nux::BaseTexture *_prelight_tex;
167 nux::BaseTexture *_pressed_tex;
168};
169
170
171WindowButtons::WindowButtons ()
172: HLayout ("", NUX_TRACKER_LOCATION)
173{
174 WindowButton *but;
175
176 but = new WindowButton (BUTTON_CLOSE);
177 AddView (but, 0, nux::eCenter, nux::eFix);
178 but->sigClick.connect (sigc::mem_fun (this, &WindowButtons::OnCloseClicked));
179 but->OnMouseEnter.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseEnter));
180 but->OnMouseLeave.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseLeave));
181
182 but = new WindowButton (BUTTON_MINIMISE);
183 AddView (but, 0, nux::eCenter, nux::eFix);
184 but->sigClick.connect (sigc::mem_fun (this, &WindowButtons::OnMinimizeClicked));
185 but->OnMouseEnter.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseEnter));
186 but->OnMouseLeave.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseLeave));
187
188 but = new WindowButton (BUTTON_UNMAXIMISE);
189 AddView (but, 0, nux::eCenter, nux::eFix);
190 but->sigClick.connect (sigc::mem_fun (this, &WindowButtons::OnRestoreClicked));
191 but->OnMouseEnter.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseEnter));
192 but->OnMouseLeave.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseLeave));
193
194 SetContentDistribution (nux::eStackLeft);
195}
196
197
198WindowButtons::~WindowButtons ()
199{
200}
201
202void
203WindowButtons::OnCloseClicked ()
204{
205 close_clicked.emit ();
206}
207
208void
209WindowButtons::OnMinimizeClicked ()
210{
211 minimize_clicked.emit ();
212}
213
214void
215WindowButtons::OnRestoreClicked ()
216{
217 restore_clicked.emit ();
218}
219
220const gchar *
221WindowButtons::GetName ()
222{
223 return "window-buttons";
224}
225
226const gchar *
227WindowButtons::GetChildsName ()
228{
229 return "";
230}
231
232void
233WindowButtons::AddProperties (GVariantBuilder *builder)
234{
235 nux::Geometry geo = GetGeometry ();
236
237 /* Now some props from ourselves */
238 g_variant_builder_add (builder, "{sv}", "x", g_variant_new_int32 (geo.x));
239 g_variant_builder_add (builder, "{sv}", "y", g_variant_new_int32 (geo.y));
240 g_variant_builder_add (builder, "{sv}", "width", g_variant_new_int32 (geo.width));
241 g_variant_builder_add (builder, "{sv}", "height", g_variant_new_int32 (geo.height));
242}
243
244void WindowButtons::RecvMouseEnter (int x, int y, unsigned long button_flags, unsigned long key_flags)
245{
246 redraw_signal.emit ();
247}
248
249void WindowButtons::RecvMouseLeave (int x, int y, unsigned long button_flags, unsigned long key_flags)
250{
251 redraw_signal.emit ();
252}
253
254
0255
=== added file 'src/WindowButtons.h'
--- src/WindowButtons.h 1970-01-01 00:00:00 +0000
+++ src/WindowButtons.h 2010-12-17 10:43:24 +0000
@@ -0,0 +1,63 @@
1/*
2 * Copyright (C) 2010 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 */
18
19#ifndef WINDOW_BUTTONS_H
20#define WINDOW_BUTTONS_H
21
22#include <Nux/View.h>
23
24#include "Introspectable.h"
25
26class WindowButtons : public nux::HLayout, public Introspectable
27{
28 // These are the [close][minimize][restore] buttons on the panel when there
29 // is a maximized window
30
31public:
32 WindowButtons ();
33 ~WindowButtons ();
34
35 sigc::signal<void> close_clicked;
36 sigc::signal<void> minimize_clicked;
37 sigc::signal<void> restore_clicked;
38 sigc::signal<void> redraw_signal;
39
40protected:
41 const gchar * GetName ();
42 const gchar * GetChildsName ();
43 void AddProperties (GVariantBuilder *builder);
44
45
46 // For testing the buttons
47 void RecvMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags);
48 void RecvMouseUp (int x, int y, unsigned long button_flags, unsigned long key_flags);
49 void RecvMouseEnter (int x, int y, unsigned long button_flags, unsigned long key_flags);
50 void RecvMouseLeave (int x, int y, unsigned long button_flags, unsigned long key_flags);
51 void RecvMouseClick (int x, int y, unsigned long button_flags, unsigned long key_flags);
52 void RecvMouseMove (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags);
53
54private:
55 void OnCloseClicked ();
56 void OnMinimizeClicked ();
57 void OnRestoreClicked ();
58
59private:
60 nux::HLayout *_layout;
61};
62
63#endif
064
=== added file 'src/WindowManager.cpp'
--- src/WindowManager.cpp 1970-01-01 00:00:00 +0000
+++ src/WindowManager.cpp 2010-12-17 10:43:24 +0000
@@ -0,0 +1,171 @@
1/*
2 * Copyright (C) 2010 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 */
18
19#include "WindowManager.h"
20
21#include <gdk/gdkx.h>
22
23typedef struct {
24 unsigned long flags;
25 unsigned long functions;
26 unsigned long decorations;
27 long input_mode;
28 unsigned long status;
29} MotifWmHints, MwmHints;
30
31#define MWM_HINTS_FUNCTIONS (1L << 0)
32#define MWM_HINTS_DECORATIONS (1L << 1)
33#define _XA_MOTIF_WM_HINTS "_MOTIF_WM_HINTS"
34
35static void gdk_window_set_mwm_hints (Window xid,
36 MotifWmHints *new_hints);
37
38
39static WindowManager *window_manager = NULL;
40
41class WindowManagerDummy : public WindowManager
42{
43 bool IsWindowMaximized (guint32 xid)
44 {
45 return false;
46 }
47
48 bool IsWindowDecorated (guint32 xid)
49 {
50 return true;
51 }
52
53 void Restore (guint32 xid)
54 {
55 g_debug ("%s", G_STRFUNC);
56 }
57
58 void Minimize (guint32 xid)
59 {
60 g_debug ("%s", G_STRFUNC);
61 }
62
63 void Close (guint32 xid)
64 {
65 g_debug ("%s", G_STRFUNC);
66 }
67};
68
69WindowManager *
70WindowManager::Default ()
71{
72 if (!window_manager)
73 window_manager = new WindowManagerDummy ();
74
75 return window_manager;
76}
77
78void
79WindowManager::SetDefault (WindowManager *manager)
80{
81 window_manager = manager;
82}
83
84void
85WindowManager::Decorate (guint32 xid)
86{
87 MotifWmHints hints = { 0 };
88
89 hints.flags = MWM_HINTS_DECORATIONS;
90 hints.decorations = GDK_DECOR_ALL;
91
92 gdk_window_set_mwm_hints (xid, &hints);
93}
94
95void
96WindowManager::Undecorate (guint32 xid)
97{
98 MotifWmHints hints = { 0 };
99
100 hints.flags = MWM_HINTS_DECORATIONS;
101 hints.decorations = 0;
102
103 gdk_window_set_mwm_hints (xid, &hints);
104}
105
106/*
107 * Copied over C code
108 */
109static void
110gdk_window_set_mwm_hints (Window xid,
111 MotifWmHints *new_hints)
112{
113 GdkDisplay *display = gdk_display_get_default();
114 Atom hints_atom = None;
115 guchar *data = NULL;
116 MotifWmHints *hints = NULL;
117 Atom type = None;
118 gint format;
119 gulong nitems;
120 gulong bytes_after;
121
122 g_return_if_fail (GDK_IS_DISPLAY (display));
123
124 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
125 _XA_MOTIF_WM_HINTS);
126
127 gdk_error_trap_push ();
128 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
129 xid,
130 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
131 False, AnyPropertyType, &type, &format, &nitems,
132 &bytes_after, &data);
133 gdk_flush ();
134 if (gdk_error_trap_pop ())
135 {
136 g_debug ("ERROR: Cannot set decorations");
137 return;
138 }
139
140 if (type != hints_atom || !data)
141 hints = new_hints;
142 else
143 {
144 hints = (MotifWmHints *)data;
145
146 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
147 {
148 hints->flags |= MWM_HINTS_FUNCTIONS;
149 hints->functions = new_hints->functions;
150 }
151 if (new_hints->flags & MWM_HINTS_DECORATIONS)
152 {
153 hints->flags |= MWM_HINTS_DECORATIONS;
154 hints->decorations = new_hints->decorations;
155 }
156 }
157
158 gdk_error_trap_push ();
159 XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
160 xid,
161 hints_atom, hints_atom, 32, PropModeReplace,
162 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
163 gdk_flush ();
164 if (gdk_error_trap_pop ())
165 {
166 g_debug ("ERROR: Setting decorations");
167 }
168
169 if (data)
170 XFree (data);
171}
0172
=== added file 'src/WindowManager.h'
--- src/WindowManager.h 1970-01-01 00:00:00 +0000
+++ src/WindowManager.h 2010-12-17 10:43:24 +0000
@@ -0,0 +1,57 @@
1/*
2 * Copyright (C) 2010 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 */
18
19#ifndef WINDOW_MANAGER_H
20#define WINDOW_MANAGER_H
21
22#include <glib.h>
23#include <sigc++/sigc++.h>
24
25class WindowManager
26{
27 // This is a glue interface that breaks the dependancy of Unity with Compiz
28 // Basically it has a default implementation that does nothing useful, but
29 // the idea is that unity.cpp uses SetDefault() early enough in it's
30 // initialization so the things that require it get a usable implementation
31 //
32 // Currently only the Panel uses it but hopefully we'll get more of
33 // PluginAdaptor features moved into here and also get the Launcher to use
34 // it.
35
36public:
37 static WindowManager * Default ();
38 static void SetDefault (WindowManager *manager);
39
40 virtual bool IsWindowMaximized (guint32 xid) = 0;
41 virtual bool IsWindowDecorated (guint32 xid) = 0;
42
43 virtual void Restore (guint32 xid) = 0;
44 virtual void Minimize (guint32 xid) = 0;
45 virtual void Close (guint32 xid) = 0;
46
47 virtual void Decorate (guint32 xid);
48 virtual void Undecorate (guint32 xid);
49
50 // Signals
51 sigc::signal<void, guint32> window_mapped;
52 sigc::signal<void, guint32> window_unmapped;
53 sigc::signal<void, guint32> window_maximized;
54 sigc::signal<void, guint32> window_restored;
55};
56
57#endif // WINDOW_MANAGER_H
058
=== modified file 'src/unity.cpp'
--- src/unity.cpp 2010-12-16 21:07:28 +0000
+++ src/unity.cpp 2010-12-17 10:43:24 +0000
@@ -395,6 +395,8 @@
395 GLScreenInterface::setHandler (gScreen);395 GLScreenInterface::setHandler (gScreen);
396396
397 PluginAdapter::Initialize (screen);397 PluginAdapter::Initialize (screen);
398 WindowManager::SetDefault (PluginAdapter::Default ());
399
398 StartupNotifyService::Default ()->SetSnDisplay (screen->snDisplay (), screen->screenNum ());400 StartupNotifyService::Default ()->SetSnDisplay (screen->snDisplay (), screen->screenNum ());
399401
400 nux::NuxInitialize (0);402 nux::NuxInitialize (0);
@@ -410,7 +412,6 @@
410412
411 debugger = new IntrospectionDBusInterface (this);413 debugger = new IntrospectionDBusInterface (this);
412414
413
414 optionSetLauncherAutohideNotify (boost::bind (&UnityScreen::optionChanged, this, _1, _2));415 optionSetLauncherAutohideNotify (boost::bind (&UnityScreen::optionChanged, this, _1, _2));
415 optionSetLauncherFloatNotify (boost::bind (&UnityScreen::optionChanged, this, _1, _2));416 optionSetLauncherFloatNotify (boost::bind (&UnityScreen::optionChanged, this, _1, _2));
416417
417418
=== modified file 'tests/CMakeLists.txt'
--- tests/CMakeLists.txt 2010-12-13 09:54:54 +0000
+++ tests/CMakeLists.txt 2010-12-17 10:43:24 +0000
@@ -82,6 +82,14 @@
82 ../src/Introspectable.h82 ../src/Introspectable.h
83 ../src/PanelHomeButton.cpp83 ../src/PanelHomeButton.cpp
84 ../src/PanelHomeButton.h84 ../src/PanelHomeButton.h
85 ../src/PanelMenuView.cpp
86 ../src/PanelMenuView.h
87 ../src/StaticCairoText.cpp
88 ../src/StaticCairoText.h
89 ../src/WindowButtons.cpp
90 ../src/WindowButtons.h
91 ../src/WindowManager.cpp
92 ../src/WindowManager.h
85 ../libunity/ubus-server.c93 ../libunity/ubus-server.c
86 ../libunity/ubus-server.h94 ../libunity/ubus-server.h
87 )95 )