Merge lp:~unity-team/unity/panel-fixes-2010-12-07 into lp:unity
- panel-fixes-2010-12-07
- Merge into trunk
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 | ||||||||||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Unity Team | Pending | ||
Review via email: mp+44015@code.launchpad.net |
Commit message
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"
Neil J. Patel (njpatel) wrote : | # |
Gord Allott (gordallott) wrote : | # |
noting: Nux: [Object:
Preview Diff
1 | === modified file 'src/IndicatorObjectEntryProxy.h' |
2 | --- src/IndicatorObjectEntryProxy.h 2010-11-11 15:07:58 +0000 |
3 | +++ src/IndicatorObjectEntryProxy.h 2010-12-17 10:43:24 +0000 |
4 | @@ -36,7 +36,8 @@ |
5 | virtual void ShowMenu (int x, int y, guint32 timestamp, guint32 button) = 0; |
6 | |
7 | // Signals |
8 | - sigc::signal<void> Updated; |
9 | + sigc::signal<void> updated; |
10 | + sigc::signal<void, bool> active_changed; |
11 | |
12 | public: |
13 | bool label_visible; |
14 | |
15 | === modified file 'src/IndicatorObjectEntryProxyRemote.cpp' |
16 | --- src/IndicatorObjectEntryProxyRemote.cpp 2010-11-17 20:12:42 +0000 |
17 | +++ src/IndicatorObjectEntryProxyRemote.cpp 2010-12-17 10:43:24 +0000 |
18 | @@ -104,7 +104,8 @@ |
19 | |
20 | _active = active; |
21 | |
22 | - Updated.emit (); |
23 | + active_changed.emit (active); |
24 | + updated.emit (); |
25 | } |
26 | |
27 | bool |
28 | @@ -141,7 +142,7 @@ |
29 | icon_sensitive = __image_sensitive; |
30 | icon_visible = __image_visible; |
31 | |
32 | - Updated.emit (); |
33 | + updated.emit (); |
34 | } |
35 | |
36 | const char * |
37 | |
38 | === modified file 'src/IndicatorObjectFactory.h' |
39 | --- src/IndicatorObjectFactory.h 2010-12-07 13:55:04 +0000 |
40 | +++ src/IndicatorObjectFactory.h 2010-12-17 10:43:24 +0000 |
41 | @@ -45,6 +45,7 @@ |
42 | sigc::signal<void, IndicatorObjectProxy *> OnObjectRemoved; |
43 | sigc::signal<void, int, int> OnMenuPointerMoved; |
44 | sigc::signal<void, const char *> OnEntryActivateRequest; |
45 | + sigc::signal<void, const char *> OnEntryActivated; |
46 | |
47 | protected: |
48 | std::vector<IndicatorObjectProxy *>_indicators; |
49 | |
50 | === modified file 'src/IndicatorObjectFactoryRemote.cpp' |
51 | --- src/IndicatorObjectFactoryRemote.cpp 2010-12-13 19:53:58 +0000 |
52 | +++ src/IndicatorObjectFactoryRemote.cpp 2010-12-17 10:43:24 +0000 |
53 | @@ -239,7 +239,9 @@ |
54 | |
55 | entry->SetActive (g_strcmp0 (entry_id, entry->GetId ()) == 0); |
56 | } |
57 | - } |
58 | + } |
59 | + |
60 | + IndicatorObjectFactory::OnEntryActivated.emit (entry_id); |
61 | } |
62 | |
63 | void |
64 | |
65 | === modified file 'src/PanelIndicatorObjectEntryView.cpp' |
66 | --- src/PanelIndicatorObjectEntryView.cpp 2010-12-07 15:01:07 +0000 |
67 | +++ src/PanelIndicatorObjectEntryView.cpp 2010-12-17 10:43:24 +0000 |
68 | @@ -31,9 +31,6 @@ |
69 | #include <gtk/gtk.h> |
70 | #include <time.h> |
71 | |
72 | -#define PANEL_HEIGHT 24 |
73 | -#define PADDING 6 |
74 | -#define SPACING 3 |
75 | |
76 | static void draw_menu_bg (cairo_t *cr, int width, int height); |
77 | |
78 | @@ -43,7 +40,8 @@ |
79 | _proxy (proxy), |
80 | _util_cg (CAIRO_FORMAT_ARGB32, 1, 1) |
81 | { |
82 | - _proxy->Updated.connect (sigc::mem_fun (this, &PanelIndicatorObjectEntryView::Refresh)); |
83 | + _proxy->active_changed.connect (sigc::mem_fun (this, &PanelIndicatorObjectEntryView::OnActiveChanged)); |
84 | + _proxy->updated.connect (sigc::mem_fun (this, &PanelIndicatorObjectEntryView::Refresh)); |
85 | |
86 | InputArea::OnMouseDown.connect (sigc::mem_fun (this, &PanelIndicatorObjectEntryView::OnMouseDown)); |
87 | |
88 | @@ -55,6 +53,12 @@ |
89 | } |
90 | |
91 | void |
92 | +PanelIndicatorObjectEntryView::OnActiveChanged (bool is_active) |
93 | +{ |
94 | + active_changed.emit (this, is_active); |
95 | +} |
96 | + |
97 | +void |
98 | PanelIndicatorObjectEntryView::OnMouseDown (int x, int y, long button_flags, long key_flags) |
99 | { |
100 | if (_proxy->GetActive ()) |
101 | |
102 | === modified file 'src/PanelIndicatorObjectEntryView.h' |
103 | --- src/PanelIndicatorObjectEntryView.h 2010-12-07 13:55:04 +0000 |
104 | +++ src/PanelIndicatorObjectEntryView.h 2010-12-17 10:43:24 +0000 |
105 | @@ -28,6 +28,10 @@ |
106 | |
107 | #include "Introspectable.h" |
108 | |
109 | +#define PANEL_HEIGHT 24 |
110 | +#define PADDING 6 |
111 | +#define SPACING 3 |
112 | + |
113 | class PanelIndicatorObjectEntryView : public nux::TextureArea, public Introspectable |
114 | { |
115 | public: |
116 | @@ -37,10 +41,13 @@ |
117 | void Refresh (); |
118 | void OnMouseDown (int x, int y, long button_flags, long key_flags); |
119 | void Activate (); |
120 | + void OnActiveChanged (bool is_active); |
121 | |
122 | const gchar * GetName (); |
123 | void AddProperties (GVariantBuilder *builder); |
124 | |
125 | + sigc::signal<void, PanelIndicatorObjectEntryView *, bool> active_changed; |
126 | + |
127 | public: |
128 | IndicatorObjectEntryProxy *_proxy; |
129 | private: |
130 | |
131 | === modified file 'src/PanelIndicatorObjectView.cpp' |
132 | --- src/PanelIndicatorObjectView.cpp 2010-12-02 11:55:02 +0000 |
133 | +++ src/PanelIndicatorObjectView.cpp 2010-12-17 10:43:24 +0000 |
134 | @@ -30,6 +30,13 @@ |
135 | |
136 | #include <glib.h> |
137 | |
138 | +PanelIndicatorObjectView::PanelIndicatorObjectView () |
139 | +: View (NUX_TRACKER_LOCATION), |
140 | + _proxy (NULL), |
141 | + _entries () |
142 | +{ |
143 | +} |
144 | + |
145 | PanelIndicatorObjectView::PanelIndicatorObjectView (IndicatorObjectProxy *proxy) |
146 | : View (NUX_TRACKER_LOCATION), |
147 | _proxy (proxy), |
148 | |
149 | === modified file 'src/PanelIndicatorObjectView.h' |
150 | --- src/PanelIndicatorObjectView.h 2010-12-02 11:55:02 +0000 |
151 | +++ src/PanelIndicatorObjectView.h 2010-12-17 10:43:24 +0000 |
152 | @@ -29,6 +29,7 @@ |
153 | class PanelIndicatorObjectView : public nux::View, public Introspectable |
154 | { |
155 | public: |
156 | + PanelIndicatorObjectView (); |
157 | PanelIndicatorObjectView (IndicatorObjectProxy *proxy); |
158 | ~PanelIndicatorObjectView (); |
159 | |
160 | @@ -47,7 +48,6 @@ |
161 | const gchar * GetChildsName (); |
162 | void AddProperties (GVariantBuilder *builder); |
163 | |
164 | -private: |
165 | IndicatorObjectProxy *_proxy; |
166 | std::vector<PanelIndicatorObjectEntryView *> _entries; |
167 | }; |
168 | |
169 | === added file 'src/PanelMenuView.cpp' |
170 | --- src/PanelMenuView.cpp 1970-01-01 00:00:00 +0000 |
171 | +++ src/PanelMenuView.cpp 2010-12-17 10:43:24 +0000 |
172 | @@ -0,0 +1,671 @@ |
173 | +/* |
174 | + * Copyright (C) 2010 Canonical Ltd |
175 | + * |
176 | + * This program is free software: you can redistribute it and/or modify |
177 | + * it under the terms of the GNU General Public License version 3 as |
178 | + * published by the Free Software Foundation. |
179 | + * |
180 | + * This program is distributed in the hope that it will be useful, |
181 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
182 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
183 | + * GNU General Public License for more details. |
184 | + * |
185 | + * You should have received a copy of the GNU General Public License |
186 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
187 | + * |
188 | + * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> |
189 | + */ |
190 | +#include <glib.h> |
191 | +#include <pango/pangocairo.h> |
192 | +#include <gtk/gtk.h> |
193 | + |
194 | +#include "Nux/Nux.h" |
195 | +#include "Nux/HLayout.h" |
196 | +#include "Nux/VLayout.h" |
197 | +#include <Nux/TextureArea.h> |
198 | + |
199 | +#include "NuxGraphics/GLThread.h" |
200 | +#include "Nux/BaseWindow.h" |
201 | +#include "Nux/WindowCompositor.h" |
202 | + |
203 | +#include "PanelMenuView.h" |
204 | + |
205 | +#include "WindowManager.h" |
206 | + |
207 | +#include "IndicatorObjectEntryProxy.h" |
208 | + |
209 | +#include <gio/gdesktopappinfo.h> |
210 | + |
211 | +#define BUTTONS_WIDTH 72 |
212 | + |
213 | +static void on_active_window_changed (BamfMatcher *matcher, |
214 | + BamfView *old_view, |
215 | + BamfView *new_view, |
216 | + PanelMenuView *self); |
217 | + |
218 | + |
219 | +PanelMenuView::PanelMenuView () |
220 | +: _matcher (NULL), |
221 | + _title_layer (NULL), |
222 | + _util_cg (CAIRO_FORMAT_ARGB32, 1, 1), |
223 | + _gradient_texture (NULL), |
224 | + _title_tex (NULL), |
225 | + _is_inside (false), |
226 | + _is_maximized (false), |
227 | + _last_active_view (NULL) |
228 | +{ |
229 | + WindowManager *win_manager; |
230 | + |
231 | + _matcher = bamf_matcher_get_default (); |
232 | + g_signal_connect (_matcher, "active-window-changed", |
233 | + G_CALLBACK (on_active_window_changed), this); |
234 | + |
235 | + _menu_layout = new nux::HLayout ("", NUX_TRACKER_LOCATION); |
236 | + |
237 | + /* This is for our parent and for PanelView to read indicator entries, we |
238 | + * shouldn't touch this again |
239 | + */ |
240 | + _layout = _menu_layout; |
241 | + |
242 | + _window_buttons = new WindowButtons (); |
243 | + _window_buttons->NeedRedraw (); |
244 | + _window_buttons->close_clicked.connect (sigc::mem_fun (this, &PanelMenuView::OnCloseClicked)); |
245 | + _window_buttons->minimize_clicked.connect (sigc::mem_fun (this, &PanelMenuView::OnMinimizeClicked)); |
246 | + _window_buttons->restore_clicked.connect (sigc::mem_fun (this, &PanelMenuView::OnRestoreClicked)); |
247 | + _window_buttons->redraw_signal.connect (sigc::mem_fun (this, &PanelMenuView::OnWindowButtonsRedraw)); |
248 | + |
249 | + win_manager = WindowManager::Default (); |
250 | + win_manager->window_maximized.connect (sigc::mem_fun (this, &PanelMenuView::OnWindowMaximized)); |
251 | + win_manager->window_restored.connect (sigc::mem_fun (this, &PanelMenuView::OnWindowRestored)); |
252 | + win_manager->window_unmapped.connect (sigc::mem_fun (this, &PanelMenuView::OnWindowUnmapped)); |
253 | + |
254 | + Refresh (); |
255 | +} |
256 | + |
257 | +PanelMenuView::~PanelMenuView () |
258 | +{ |
259 | + if (_title_layer) |
260 | + delete _title_layer; |
261 | + if (_title_tex) |
262 | + _title_tex->UnReference (); |
263 | + |
264 | + _menu_layout->UnReference (); |
265 | + _window_buttons->UnReference (); |
266 | +} |
267 | + |
268 | +void |
269 | +PanelMenuView::FullRedraw () |
270 | +{ |
271 | + _menu_layout->NeedRedraw (); |
272 | + _window_buttons->NeedRedraw (); |
273 | + NeedRedraw (); |
274 | +} |
275 | + |
276 | +void |
277 | +PanelMenuView::SetProxy (IndicatorObjectProxy *proxy) |
278 | +{ |
279 | + _proxy = proxy; |
280 | + printf ("IndicatorAdded: %s\n", _proxy->GetName ().c_str ()); |
281 | + |
282 | + _proxy->OnEntryAdded.connect (sigc::mem_fun (this, &PanelMenuView::OnEntryAdded)); |
283 | + _proxy->OnEntryMoved.connect (sigc::mem_fun (this, &PanelMenuView::OnEntryMoved)); |
284 | + _proxy->OnEntryRemoved.connect (sigc::mem_fun (this, &PanelMenuView::OnEntryRemoved)); |
285 | +} |
286 | + |
287 | +long |
288 | +PanelMenuView::ProcessEvent (nux::IEvent &ievent, long TraverseInfo, long ProcessEventInfo) |
289 | +{ |
290 | + long ret = TraverseInfo; |
291 | + nux::Geometry geo = GetGeometry (); |
292 | + |
293 | + if (geo.IsPointInside (ievent.e_x, ievent.e_y)) |
294 | + { |
295 | + if (_is_inside != true) |
296 | + { |
297 | + _is_inside = true; |
298 | + FullRedraw (); |
299 | + } |
300 | + } |
301 | + else |
302 | + { |
303 | + if (_is_inside != false) |
304 | + { |
305 | + _is_inside = false; |
306 | + FullRedraw (); |
307 | + } |
308 | + } |
309 | + |
310 | + if (_is_maximized) |
311 | + ret = _window_buttons->ProcessEvent (ievent, ret, ProcessEventInfo); |
312 | + ret = _menu_layout->ProcessEvent (ievent, ret, ProcessEventInfo); |
313 | + |
314 | + return ret; |
315 | +} |
316 | + |
317 | +long PanelMenuView::PostLayoutManagement (long LayoutResult) |
318 | +{ |
319 | + long res = View::PostLayoutManagement (LayoutResult); |
320 | + int w = _window_buttons->GetContentWidth (); |
321 | + |
322 | + nux::Geometry geo = GetGeometry (); |
323 | + |
324 | + _window_buttons->SetGeometry (geo.x + PADDING, geo.y, w, geo.height); |
325 | + _window_buttons->ComputeLayout2 (); |
326 | + |
327 | + /* Explicitly set the size and position of the widgets */ |
328 | + geo.x += PADDING + w + PADDING; |
329 | + geo.width -= PADDING + w + PADDING; |
330 | + |
331 | + _menu_layout->SetGeometry (geo.x, geo.y, geo.width, geo.height); |
332 | + _menu_layout->ComputeLayout2(); |
333 | + |
334 | + Refresh (); |
335 | + |
336 | + return res; |
337 | +} |
338 | + |
339 | +void |
340 | +PanelMenuView::Draw (nux::GraphicsEngine& GfxContext, bool force_draw) |
341 | +{ |
342 | + nux::Geometry geo = GetGeometry (); |
343 | + int button_width = PADDING + _window_buttons->GetContentWidth () + PADDING; |
344 | + float factor = 4; |
345 | + button_width /= factor; |
346 | + |
347 | + GfxContext.PushClippingRectangle (geo); |
348 | + |
349 | + /* "Clear" out the background */ |
350 | + nux::ROPConfig rop; |
351 | + rop.Blend = true; |
352 | + rop.SrcBlend = GL_ONE; |
353 | + rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; |
354 | + |
355 | + nux::ColorLayer layer (nux::Color (0x00000000), true, rop); |
356 | + gPainter.PushDrawLayer (GfxContext, GetGeometry (), &layer); |
357 | + |
358 | + if (_is_maximized) |
359 | + { |
360 | + if (!_is_inside) |
361 | + gPainter.PushDrawLayer (GfxContext, GetGeometry (), _title_layer); |
362 | + } |
363 | + else |
364 | + { |
365 | + if (_is_inside || _last_active_view) |
366 | + { |
367 | + if (_gradient_texture == NULL) |
368 | + { |
369 | + nux::NTextureData texture_data (nux::BITFMT_R8G8B8A8, geo.width, 1, 1); |
370 | + nux::ImageSurface surface = texture_data.GetSurface (0); |
371 | + nux::SURFACE_LOCKED_RECT lockrect; |
372 | + BYTE *dest; |
373 | + int num_row; |
374 | + |
375 | + _gradient_texture = nux::GetThreadGLDeviceFactory ()->CreateSystemCapableDeviceTexture (texture_data.GetWidth (), texture_data.GetHeight (), 1, texture_data.GetFormat ()); |
376 | + |
377 | + _gradient_texture->LockRect (0, &lockrect, 0); |
378 | + |
379 | + dest = (BYTE *) lockrect.pBits; |
380 | + num_row = surface.GetBlockHeight (); |
381 | + |
382 | + for (int y = 0; y < num_row; y++) |
383 | + { |
384 | + for (int x = 0; x < geo.width; x++) |
385 | + { |
386 | + *(dest + y * lockrect.Pitch + 4*x + 0) = 223; //red |
387 | + *(dest + y * lockrect.Pitch + 4*x + 1) = 219; //green |
388 | + *(dest + y * lockrect.Pitch + 4*x + 2) = 210; //blue |
389 | + |
390 | + if (x < button_width * (factor - 1)) |
391 | + { |
392 | + *(dest + y * lockrect.Pitch + 4*x + 3) = 0xff; |
393 | + } |
394 | + else if (x < button_width * factor) |
395 | + { |
396 | + *(dest + y * lockrect.Pitch + 4*x + 3) = 255 - 255 * (((float)x-(button_width * (factor -1)))/(float)(button_width)); |
397 | + } |
398 | + else |
399 | + { |
400 | + *(dest + y * lockrect.Pitch + 4*x + 3) = 0x00; |
401 | + } |
402 | + } |
403 | + } |
404 | + _gradient_texture->UnlockRect (0); |
405 | + } |
406 | + GfxContext.GetRenderStates ().SetBlend(true, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
407 | + |
408 | + nux::TexCoordXForm texxform0; |
409 | + nux::TexCoordXForm texxform1; |
410 | + |
411 | + // Modulate the checkboard and the gradient texture |
412 | + GfxContext.QRP_2TexMod(geo.x, geo.y, |
413 | + geo.width, geo.height, |
414 | + _gradient_texture, texxform0, |
415 | + nux::Color::White, |
416 | + _title_tex->GetDeviceTexture (), |
417 | + texxform1, |
418 | + nux::Color::White); |
419 | + |
420 | + GfxContext.GetRenderStates ().SetBlend(false); |
421 | + |
422 | + // The previous blend is too aggressive on the texture and therefore there |
423 | + // is a slight loss of clarity. This fixes that |
424 | + geo.width = button_width * (factor - 1); |
425 | + gPainter.PushDrawLayer (GfxContext, geo, _title_layer); |
426 | + geo = GetGeometry (); |
427 | + } |
428 | + else |
429 | + { |
430 | + gPainter.PushDrawLayer (GfxContext, |
431 | + geo, |
432 | + _title_layer); |
433 | + } |
434 | + } |
435 | + |
436 | + gPainter.PopBackground (); |
437 | + |
438 | + GfxContext.PopClippingRectangle(); |
439 | +} |
440 | + |
441 | +void |
442 | +PanelMenuView::DrawContent (nux::GraphicsEngine &GfxContext, bool force_draw) |
443 | +{ |
444 | + nux::Geometry geo = GetGeometry (); |
445 | + |
446 | + GfxContext.PushClippingRectangle (geo); |
447 | + |
448 | + if (_is_inside || _last_active_view) |
449 | + { |
450 | + _layout->ProcessDraw (GfxContext, force_draw); |
451 | + } |
452 | + |
453 | + if (_is_maximized) |
454 | + { |
455 | + _window_buttons->ProcessDraw (GfxContext, true); |
456 | + } |
457 | + |
458 | + GfxContext.PopClippingRectangle(); |
459 | +} |
460 | + |
461 | +gchar * |
462 | +PanelMenuView::GetActiveViewName () |
463 | +{ |
464 | + gchar *label = NULL; |
465 | + |
466 | + if (_is_maximized) |
467 | + { |
468 | + BamfWindow *window = bamf_matcher_get_active_window (_matcher); |
469 | + |
470 | + if (BAMF_IS_WINDOW (window)) |
471 | + label = g_strdup (bamf_view_get_name (BAMF_VIEW (window))); |
472 | + } |
473 | + |
474 | + if (!label) |
475 | + { |
476 | + BamfApplication *app = bamf_matcher_get_active_application (_matcher); |
477 | + if (BAMF_IS_APPLICATION (app)) |
478 | + { |
479 | + const gchar *filename; |
480 | + |
481 | + filename = bamf_application_get_desktop_file (app); |
482 | + |
483 | + if (filename && g_strcmp0 (filename, "") != 0) |
484 | + { |
485 | + GDesktopAppInfo *info; |
486 | + |
487 | + info = g_desktop_app_info_new_from_filename (bamf_application_get_desktop_file (app)); |
488 | + |
489 | + if (info) |
490 | + { |
491 | + label = g_strdup (g_app_info_get_display_name (G_APP_INFO (info))); |
492 | + g_object_unref (info); |
493 | + } |
494 | + else |
495 | + { |
496 | + g_warning ("Unable to get GDesktopAppInfo for %s", |
497 | + bamf_application_get_desktop_file (app)); |
498 | + } |
499 | + } |
500 | + |
501 | + if (label == NULL) |
502 | + { |
503 | + BamfView *active_view; |
504 | + |
505 | + active_view = (BamfView *)bamf_matcher_get_active_window (_matcher); |
506 | + if (BAMF_IS_VIEW (active_view)) |
507 | + label = g_strdup (bamf_view_get_name (active_view)); |
508 | + else |
509 | + label = g_strdup (""); |
510 | + } |
511 | + } |
512 | + else |
513 | + { |
514 | + label = g_strdup (" "); |
515 | + } |
516 | + } |
517 | + |
518 | + return label; |
519 | +} |
520 | + |
521 | +void |
522 | +PanelMenuView::Refresh () |
523 | +{ |
524 | + nux::Geometry geo = GetGeometry (); |
525 | + char *label = GetActiveViewName (); |
526 | + PangoLayout *layout = NULL; |
527 | + PangoFontDescription *desc = NULL; |
528 | + GtkSettings *settings = gtk_settings_get_default (); |
529 | + cairo_t *cr; |
530 | + char *font_description = NULL; |
531 | + GdkScreen *screen = gdk_screen_get_default (); |
532 | + int dpi = 0; |
533 | + |
534 | + int x = 0; |
535 | + int y = 0; |
536 | + int width = geo.width; |
537 | + int height = geo.height; |
538 | + int text_width = 0; |
539 | + int text_height = 0; |
540 | + |
541 | + if (label) |
542 | + { |
543 | + PangoContext *cxt; |
544 | + PangoRectangle log_rect; |
545 | + |
546 | + cr = _util_cg.GetContext (); |
547 | + |
548 | + g_object_get (settings, |
549 | + "gtk-font-name", &font_description, |
550 | + "gtk-xft-dpi", &dpi, |
551 | + NULL); |
552 | + desc = pango_font_description_from_string (font_description); |
553 | + pango_font_description_set_weight (desc, PANGO_WEIGHT_BOLD); |
554 | + |
555 | + layout = pango_cairo_create_layout (cr); |
556 | + pango_layout_set_font_description (layout, desc); |
557 | + pango_layout_set_text (layout, label, -1); |
558 | + |
559 | + cxt = pango_layout_get_context (layout); |
560 | + pango_cairo_context_set_font_options (cxt, gdk_screen_get_font_options (screen)); |
561 | + pango_cairo_context_set_resolution (cxt, (float)dpi/(float)PANGO_SCALE); |
562 | + pango_layout_context_changed (layout); |
563 | + |
564 | + pango_layout_get_extents (layout, NULL, &log_rect); |
565 | + text_width = log_rect.width / PANGO_SCALE; |
566 | + text_height = log_rect.height / PANGO_SCALE; |
567 | + |
568 | + pango_font_description_free (desc); |
569 | + g_free (font_description); |
570 | + cairo_destroy (cr); |
571 | + } |
572 | + |
573 | + nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, width, height); |
574 | + cr = cairo_graphics.GetContext(); |
575 | + cairo_set_line_width (cr, 1); |
576 | + |
577 | + x = PADDING; |
578 | + y = 0; |
579 | + |
580 | + if (_is_maximized) |
581 | + x += _window_buttons->GetContentWidth () + PADDING + PADDING; |
582 | + |
583 | + if (label) |
584 | + { |
585 | + pango_cairo_update_layout (cr, layout); |
586 | + |
587 | + // Once for the homies that couldn't be here |
588 | + cairo_set_source_rgb (cr, 50/255.0f, 50/255.0f, 45/255.0f); |
589 | + cairo_move_to (cr, x, ((height - text_height)/2)-1); |
590 | + pango_cairo_show_layout (cr, layout); |
591 | + cairo_stroke (cr); |
592 | + |
593 | + // Once again for the homies that could |
594 | + cairo_set_source_rgba (cr, 223/255.0f, 219/255.0f, 210/255.0f, 1.0f); |
595 | + cairo_move_to (cr, x, (height - text_height)/2); |
596 | + pango_cairo_show_layout (cr, layout); |
597 | + cairo_stroke (cr); |
598 | + } |
599 | + |
600 | + cairo_destroy (cr); |
601 | + if (layout) |
602 | + g_object_unref (layout); |
603 | + |
604 | + nux::NBitmapData* bitmap = cairo_graphics.GetBitmap(); |
605 | + |
606 | + // The Texture is created with a reference count of 1. |
607 | + nux::BaseTexture* texture2D = nux::GetThreadGLDeviceFactory ()->CreateSystemCapableTexture (); |
608 | + texture2D->Update(bitmap); |
609 | + delete bitmap; |
610 | + |
611 | + if (_title_layer) |
612 | + delete _title_layer; |
613 | + |
614 | + nux::TexCoordXForm texxform; |
615 | + texxform.SetTexCoordType (nux::TexCoordXForm::OFFSET_COORD); |
616 | + texxform.SetWrap (nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT); |
617 | + |
618 | + nux::ROPConfig rop; |
619 | + rop.Blend = true; |
620 | + rop.SrcBlend = GL_ONE; |
621 | + rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; |
622 | + _title_layer = new nux::TextureLayer (texture2D->GetDeviceTexture(), |
623 | + texxform, |
624 | + nux::Color::White, |
625 | + false, |
626 | + rop); |
627 | + |
628 | + |
629 | + if (_title_tex) |
630 | + _title_tex->UnReference (); |
631 | + |
632 | + _title_tex = texture2D; |
633 | + |
634 | + g_free (label); |
635 | +} |
636 | + |
637 | +void |
638 | +PanelMenuView::OnActiveChanged (PanelIndicatorObjectEntryView *view, |
639 | + bool is_active) |
640 | +{ |
641 | + if (is_active) |
642 | + _last_active_view = view; |
643 | + else |
644 | + { |
645 | + if (_last_active_view == view) |
646 | + { |
647 | + _last_active_view = NULL; |
648 | + } |
649 | + } |
650 | + FullRedraw (); |
651 | +} |
652 | + |
653 | +void |
654 | +PanelMenuView::OnEntryAdded (IndicatorObjectEntryProxy *proxy) |
655 | +{ |
656 | + PanelIndicatorObjectEntryView *view = new PanelIndicatorObjectEntryView (proxy); |
657 | + view->active_changed.connect (sigc::mem_fun (this, &PanelMenuView::OnActiveChanged)); |
658 | + _menu_layout->AddView (view, 0, nux::eCenter, nux::eFull); |
659 | + _menu_layout->SetContentDistribution (nux::eStackLeft); |
660 | + |
661 | + _entries.push_back (view); |
662 | + |
663 | + AddChild (view); |
664 | + |
665 | + this->ComputeChildLayout (); |
666 | + NeedRedraw (); |
667 | +} |
668 | + |
669 | +void |
670 | +PanelMenuView::OnEntryMoved (IndicatorObjectEntryProxy *proxy) |
671 | +{ |
672 | + printf ("ERROR: Moving IndicatorObjectEntry not supported\n"); |
673 | +} |
674 | + |
675 | +void |
676 | +PanelMenuView::OnEntryRemoved(IndicatorObjectEntryProxy *proxy) |
677 | +{ |
678 | + std::vector<PanelIndicatorObjectEntryView *>::iterator it; |
679 | + |
680 | + for (it = _entries.begin(); it != _entries.end(); it++) |
681 | + { |
682 | + PanelIndicatorObjectEntryView *view = static_cast<PanelIndicatorObjectEntryView *> (*it); |
683 | + if (view->_proxy == proxy) |
684 | + { |
685 | + RemoveChild (view); |
686 | + _entries.erase (it); |
687 | + _menu_layout->RemoveChildObject (view); |
688 | + |
689 | + break; |
690 | + } |
691 | + } |
692 | + |
693 | + this->ComputeChildLayout (); |
694 | + NeedRedraw (); |
695 | +} |
696 | + |
697 | +void |
698 | +PanelMenuView::AllMenusClosed () |
699 | +{ |
700 | + _is_inside = false; |
701 | + _last_active_view = false; |
702 | + |
703 | + FullRedraw (); |
704 | +} |
705 | + |
706 | +void |
707 | +PanelMenuView::OnActiveWindowChanged (BamfView *old_view, |
708 | + BamfView *new_view) |
709 | +{ |
710 | + _is_maximized = false; |
711 | + |
712 | + if (BAMF_IS_WINDOW (new_view)) |
713 | + { |
714 | + BamfWindow *window = BAMF_WINDOW (new_view); |
715 | + _is_maximized = WindowManager::Default ()->IsWindowMaximized (bamf_window_get_xid (window)); |
716 | + } |
717 | + |
718 | + Refresh (); |
719 | + FullRedraw (); |
720 | +} |
721 | + |
722 | +void |
723 | +PanelMenuView::OnWindowUnmapped (guint32 xid) |
724 | +{ |
725 | + _decor_map.erase (xid); |
726 | +} |
727 | + |
728 | +void |
729 | +PanelMenuView::OnWindowMaximized (guint xid) |
730 | +{ |
731 | + BamfWindow *window; |
732 | + |
733 | + window = bamf_matcher_get_active_window (_matcher); |
734 | + if (BAMF_IS_WINDOW (window) && bamf_window_get_xid (window) == xid) |
735 | + { |
736 | + // We could probably just check if a key is available, but who wants to do that |
737 | + if (_decor_map.find (xid) == _decor_map.end ()) |
738 | + _decor_map[xid] = WindowManager::Default ()->IsWindowDecorated (xid); |
739 | + |
740 | + if (_decor_map[xid]) |
741 | + { |
742 | + WindowManager::Default ()->Undecorate (xid); |
743 | + } |
744 | + |
745 | + _is_maximized = true; |
746 | + |
747 | + Refresh (); |
748 | + FullRedraw (); |
749 | + } |
750 | +} |
751 | + |
752 | +void |
753 | +PanelMenuView::OnWindowRestored (guint xid) |
754 | +{ |
755 | + BamfWindow *window; |
756 | + |
757 | + window = bamf_matcher_get_active_window (_matcher); |
758 | + if (BAMF_IS_WINDOW (window) && bamf_window_get_xid (window) == xid) |
759 | + { |
760 | + _is_maximized = false; |
761 | + |
762 | + if (_decor_map[xid]) |
763 | + { |
764 | + WindowManager::Default ()->Decorate (xid); |
765 | + } |
766 | + |
767 | + Refresh (); |
768 | + FullRedraw (); |
769 | + } |
770 | +} |
771 | + |
772 | +void |
773 | +PanelMenuView::OnCloseClicked () |
774 | +{ |
775 | + BamfWindow *window; |
776 | + |
777 | + window = bamf_matcher_get_active_window (_matcher); |
778 | + if (BAMF_IS_WINDOW (window)) |
779 | + WindowManager::Default ()->Close (bamf_window_get_xid (window)); |
780 | +} |
781 | + |
782 | +void |
783 | +PanelMenuView::OnMinimizeClicked () |
784 | +{ |
785 | + BamfWindow *window; |
786 | + |
787 | + window = bamf_matcher_get_active_window (_matcher); |
788 | + if (BAMF_IS_WINDOW (window)) |
789 | + WindowManager::Default ()->Minimize (bamf_window_get_xid (window)); |
790 | +} |
791 | + |
792 | +void |
793 | +PanelMenuView::OnRestoreClicked () |
794 | +{ |
795 | + BamfWindow *window; |
796 | + |
797 | + window = bamf_matcher_get_active_window (_matcher); |
798 | + if (BAMF_IS_WINDOW (window)) |
799 | + WindowManager::Default ()->Restore (bamf_window_get_xid (window)); |
800 | +} |
801 | + |
802 | +void |
803 | +PanelMenuView::OnWindowButtonsRedraw () |
804 | +{ |
805 | + FullRedraw (); |
806 | +} |
807 | + |
808 | +// Introspectable |
809 | +const gchar * |
810 | +PanelMenuView::GetName () |
811 | +{ |
812 | + return "MenuView"; |
813 | +} |
814 | + |
815 | +const gchar * |
816 | +PanelMenuView::GetChildsName () |
817 | +{ |
818 | + return "entries"; |
819 | +} |
820 | + |
821 | +void |
822 | +PanelMenuView::AddProperties (GVariantBuilder *builder) |
823 | +{ |
824 | + nux::Geometry geo = GetGeometry (); |
825 | + |
826 | + /* Now some props from ourselves */ |
827 | + g_variant_builder_add (builder, "{sv}", "x", g_variant_new_int32 (geo.x)); |
828 | + g_variant_builder_add (builder, "{sv}", "y", g_variant_new_int32 (geo.y)); |
829 | + g_variant_builder_add (builder, "{sv}", "width", g_variant_new_int32 (geo.width)); |
830 | + g_variant_builder_add (builder, "{sv}", "height", g_variant_new_int32 (geo.height)); |
831 | +} |
832 | + |
833 | +/* |
834 | + * C code for callbacks |
835 | + */ |
836 | +static void |
837 | +on_active_window_changed (BamfMatcher *matcher, |
838 | + BamfView *old_view, |
839 | + BamfView *new_view, |
840 | + PanelMenuView *self) |
841 | +{ |
842 | + self->OnActiveWindowChanged (old_view, new_view); |
843 | +} |
844 | |
845 | === added file 'src/PanelMenuView.h' |
846 | --- src/PanelMenuView.h 1970-01-01 00:00:00 +0000 |
847 | +++ src/PanelMenuView.h 2010-12-17 10:43:24 +0000 |
848 | @@ -0,0 +1,103 @@ |
849 | +/* |
850 | + * Copyright (C) 2010 Canonical Ltd |
851 | + * |
852 | + * This program is free software: you can redistribute it and/or modify |
853 | + * it under the terms of the GNU General Public License version 3 as |
854 | + * published by the Free Software Foundation. |
855 | + * |
856 | + * This program is distributed in the hope that it will be useful, |
857 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
858 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
859 | + * GNU General Public License for more details. |
860 | + * |
861 | + * You should have received a copy of the GNU General Public License |
862 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
863 | + * |
864 | + * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> |
865 | + */ |
866 | + |
867 | +#ifndef PANEL_MENU_VIEW_H |
868 | +#define PANEL_MENU_VIEW_H |
869 | + |
870 | +#include <Nux/View.h> |
871 | +#include <map> |
872 | + |
873 | +#include "IndicatorObjectProxy.h" |
874 | +#include "Introspectable.h" |
875 | +#include "PanelIndicatorObjectView.h" |
876 | +#include "StaticCairoText.h" |
877 | +#include "WindowButtons.h" |
878 | + |
879 | +#include <libbamf/libbamf.h> |
880 | + |
881 | +class PanelMenuView : public PanelIndicatorObjectView |
882 | +{ |
883 | +public: |
884 | + // This contains all the menubar logic for the Panel. Mainly it contains |
885 | + // the following states: |
886 | + // 1. Unmaximized window + no mouse hover |
887 | + // 2. Unmaximized window + mouse hover |
888 | + // 3. Unmaximized window + active menu (Alt+F/arrow key nav) |
889 | + // 4. Maximized window + no mouse hover |
890 | + // 5. Maximized window + mouse hover |
891 | + // 6. Maximized window + active menu |
892 | + // |
893 | + // It also deals with undecorating maximized windows (and redecorating them |
894 | + // on unmaximize) |
895 | + |
896 | + PanelMenuView (); |
897 | + ~PanelMenuView (); |
898 | + |
899 | + void FullRedraw (); |
900 | + |
901 | + virtual long ProcessEvent (nux::IEvent &ievent, long TraverseInfo, long ProcessEventInfo); |
902 | + virtual void Draw (nux::GraphicsEngine& GfxContext, bool force_draw); |
903 | + virtual void DrawContent (nux::GraphicsEngine &GfxContext, bool force_draw); |
904 | + virtual long PostLayoutManagement (long LayoutResult); |
905 | + |
906 | + void SetProxy (IndicatorObjectProxy *proxy); |
907 | + |
908 | + void OnEntryAdded (IndicatorObjectEntryProxy *proxy); |
909 | + void OnEntryMoved (IndicatorObjectEntryProxy *proxy); |
910 | + void OnEntryRemoved (IndicatorObjectEntryProxy *proxy); |
911 | + void OnActiveChanged (PanelIndicatorObjectEntryView *view, bool is_active); |
912 | + void OnActiveWindowChanged (BamfView *old_view, BamfView *new_view); |
913 | + |
914 | + void OnWindowUnmapped (guint xid); |
915 | + void OnWindowMaximized (guint32 xid); |
916 | + void OnWindowRestored (guint32 xid); |
917 | + |
918 | + void Refresh (); |
919 | + void AllMenusClosed (); |
920 | + |
921 | + void OnCloseClicked (); |
922 | + void OnMinimizeClicked (); |
923 | + void OnRestoreClicked (); |
924 | + void OnWindowButtonsRedraw (); |
925 | + |
926 | +protected: |
927 | + const gchar * GetName (); |
928 | + const gchar * GetChildsName (); |
929 | + void AddProperties (GVariantBuilder *builder); |
930 | + |
931 | +private: |
932 | + gchar * GetActiveViewName (); |
933 | + |
934 | +private: |
935 | + BamfMatcher* _matcher; |
936 | + |
937 | + nux::AbstractPaintLayer *_title_layer; |
938 | + nux::HLayout *_menu_layout; |
939 | + nux::CairoGraphics _util_cg; |
940 | + nux::IntrusiveSP<nux::IOpenGLBaseTexture> _gradient_texture; |
941 | + nux::BaseTexture *_title_tex; |
942 | + |
943 | + bool _is_inside; |
944 | + bool _is_maximized; |
945 | + PanelIndicatorObjectEntryView *_last_active_view; |
946 | + |
947 | + WindowButtons *_window_buttons; |
948 | + |
949 | + std::map<guint32, bool> _decor_map; |
950 | +}; |
951 | +#endif |
952 | |
953 | === modified file 'src/PanelView.cpp' |
954 | --- src/PanelView.cpp 2010-12-09 17:58:53 +0000 |
955 | +++ src/PanelView.cpp 2010-12-17 10:43:24 +0000 |
956 | @@ -46,13 +46,17 @@ |
957 | // Home button |
958 | _home_button = new PanelHomeButton (); |
959 | _layout->AddView (_home_button, 0, nux::eCenter, nux::eFull); |
960 | - |
961 | AddChild (_home_button); |
962 | |
963 | + _menu_view = new PanelMenuView (); |
964 | + _layout->AddView (_menu_view, 1, nux::eCenter, nux::eFull); |
965 | + AddChild (_menu_view); |
966 | + |
967 | _remote = new IndicatorObjectFactoryRemote (); |
968 | _remote->OnObjectAdded.connect (sigc::mem_fun (this, &PanelView::OnObjectAdded)); |
969 | _remote->OnMenuPointerMoved.connect (sigc::mem_fun (this, &PanelView::OnMenuPointerMoved)); |
970 | _remote->OnEntryActivateRequest.connect (sigc::mem_fun (this, &PanelView::OnEntryActivateRequest)); |
971 | + _remote->IndicatorObjectFactory::OnEntryActivated.connect (sigc::mem_fun (this, &PanelView::OnEntryActivated)); |
972 | } |
973 | |
974 | PanelView::~PanelView () |
975 | @@ -204,7 +208,11 @@ |
976 | |
977 | // Appmenu is treated differently as it needs to expand |
978 | // We could do this in a more special way, but who has the time for special? |
979 | - _layout->AddView (view, (g_strstr_len (proxy->GetName ().c_str (), -1, "appmenu") != NULL), nux::eCenter, nux::eFull); |
980 | + if (g_strstr_len (proxy->GetName ().c_str (), -1, "appmenu") != NULL) |
981 | + _menu_view->SetProxy (proxy); |
982 | + else |
983 | + _layout->AddView (view, 0, nux::eCenter, nux::eFull); |
984 | + |
985 | _layout->SetContentDistribution (nux::eStackLeft); |
986 | |
987 | AddChild (view); |
988 | @@ -224,40 +232,40 @@ |
989 | |
990 | if (x >= geo.x && x <= (geo.x + geo.width) |
991 | && y >= geo.y && y <= (geo.y + geo.height)) |
992 | + { |
993 | + std::list<Area *>::iterator it; |
994 | + |
995 | + std::list<Area *> my_children = _layout->GetChildren (); |
996 | + for (it = my_children.begin(); it != my_children.end(); it++) |
997 | { |
998 | - std::list<Area *>::iterator it; |
999 | + PanelIndicatorObjectView *view = static_cast<PanelIndicatorObjectView *> (*it); |
1000 | + |
1001 | + if (view->_layout == NULL) |
1002 | + continue; |
1003 | |
1004 | - std::list<Area *> my_children = _layout->GetChildren (); |
1005 | - for (it = my_children.begin(); it != my_children.end(); it++) |
1006 | + geo = view->GetGeometry (); |
1007 | + if (x >= geo.x && x <= (geo.x + geo.width) |
1008 | + && y >= geo.y && y <= (geo.y + geo.height)) |
1009 | { |
1010 | - PanelIndicatorObjectView *view = static_cast<PanelIndicatorObjectView *> (*it); |
1011 | - |
1012 | - if (view->_layout == NULL) |
1013 | - continue; |
1014 | - |
1015 | - geo = view->GetGeometry (); |
1016 | - if (x >= geo.x && x <= (geo.x + geo.width) |
1017 | - && y >= geo.y && y <= (geo.y + geo.height)) |
1018 | + std::list<Area *>::iterator it2; |
1019 | + |
1020 | + std::list<Area *> its_children = view->_layout->GetChildren (); |
1021 | + for (it2 = its_children.begin(); it2 != its_children.end(); it2++) |
1022 | + { |
1023 | + PanelIndicatorObjectEntryView *entry = static_cast<PanelIndicatorObjectEntryView *> (*it2); |
1024 | + |
1025 | + geo = entry->GetGeometry (); |
1026 | + if (x >= geo.x && x <= (geo.x + geo.width) |
1027 | + && y >= geo.y && y <= (geo.y + geo.height)) |
1028 | { |
1029 | - std::list<Area *>::iterator it2; |
1030 | - |
1031 | - std::list<Area *> its_children = view->_layout->GetChildren (); |
1032 | - for (it2 = its_children.begin(); it2 != its_children.end(); it2++) |
1033 | - { |
1034 | - PanelIndicatorObjectEntryView *entry = static_cast<PanelIndicatorObjectEntryView *> (*it2); |
1035 | - |
1036 | - geo = entry->GetGeometry (); |
1037 | - if (x >= geo.x && x <= (geo.x + geo.width) |
1038 | - && y >= geo.y && y <= (geo.y + geo.height)) |
1039 | - { |
1040 | - entry->OnMouseDown (x, y, 0, 0); |
1041 | - break; |
1042 | - } |
1043 | - } |
1044 | + entry->OnMouseDown (x, y, 0, 0); |
1045 | break; |
1046 | } |
1047 | + } |
1048 | + break; |
1049 | } |
1050 | } |
1051 | + } |
1052 | } |
1053 | |
1054 | void |
1055 | @@ -281,10 +289,18 @@ |
1056 | PanelIndicatorObjectEntryView *entry = static_cast<PanelIndicatorObjectEntryView *> (*it2); |
1057 | |
1058 | if (g_strcmp0 (entry->GetName (), entry_id) == 0) |
1059 | - { |
1060 | - entry->Activate (); |
1061 | - break; |
1062 | - } |
1063 | + { |
1064 | + g_debug ("%s: Activating: %s", G_STRFUNC, entry_id); |
1065 | + entry->Activate (); |
1066 | + break; |
1067 | + } |
1068 | } |
1069 | } |
1070 | } |
1071 | + |
1072 | +void |
1073 | +PanelView::OnEntryActivated (const char *entry_id) |
1074 | +{ |
1075 | + if (g_strcmp0 (entry_id, "") == 0) |
1076 | + _menu_view->AllMenusClosed (); |
1077 | +} |
1078 | |
1079 | === modified file 'src/PanelView.h' |
1080 | --- src/PanelView.h 2010-12-07 13:55:04 +0000 |
1081 | +++ src/PanelView.h 2010-12-17 10:43:24 +0000 |
1082 | @@ -24,6 +24,7 @@ |
1083 | #include <NuxGraphics/GraphicsEngine.h> |
1084 | |
1085 | #include "PanelHomeButton.h" |
1086 | +#include "PanelMenuView.h" |
1087 | #include "IndicatorObjectFactoryRemote.h" |
1088 | #include "Introspectable.h" |
1089 | |
1090 | @@ -43,6 +44,7 @@ |
1091 | void OnObjectAdded (IndicatorObjectProxy *proxy); |
1092 | void OnMenuPointerMoved (int x, int y); |
1093 | void OnEntryActivateRequest (const char *entry_id); |
1094 | + void OnEntryActivated (const char *entry_id); |
1095 | |
1096 | PanelHomeButton * HomeButton (); |
1097 | |
1098 | @@ -59,6 +61,7 @@ |
1099 | IndicatorObjectFactoryRemote *_remote; |
1100 | |
1101 | PanelHomeButton *_home_button; |
1102 | + PanelMenuView *_menu_view; |
1103 | nux::AbstractPaintLayer *_bg_layer; |
1104 | nux::HLayout *_layout; |
1105 | |
1106 | |
1107 | === modified file 'src/PluginAdapter.cpp' |
1108 | --- src/PluginAdapter.cpp 2010-12-17 10:03:18 +0000 |
1109 | +++ src/PluginAdapter.cpp 2010-12-17 10:43:24 +0000 |
1110 | @@ -65,9 +65,15 @@ |
1111 | PluginAdapter::NotifyStateChange (CompWindow *window, unsigned int state, unsigned int last_state) |
1112 | { |
1113 | if (!(last_state & MAXIMIZE_STATE) && (state & MAXIMIZE_STATE)) |
1114 | - window_maximized.emit (window); |
1115 | + { |
1116 | + PluginAdapter::window_maximized.emit (window); |
1117 | + WindowManager::window_maximized.emit (window->id ()); |
1118 | + } |
1119 | else if ((last_state & MAXIMIZE_STATE) && !(state & MAXIMIZE_STATE)) |
1120 | - window_restored.emit (window); |
1121 | + { |
1122 | + PluginAdapter::window_restored.emit (window); |
1123 | + WindowManager::window_restored.emit (window->id ()); |
1124 | + } |
1125 | } |
1126 | |
1127 | void |
1128 | @@ -94,10 +100,12 @@ |
1129 | window_shown.emit (window); |
1130 | break; |
1131 | case CompWindowNotifyMap: |
1132 | - window_mapped.emit (window); |
1133 | + PluginAdapter::window_mapped.emit (window); |
1134 | + WindowManager::window_mapped.emit (window->id ()); |
1135 | break; |
1136 | case CompWindowNotifyUnmap: |
1137 | - window_unmapped.emit (window); |
1138 | + PluginAdapter::window_unmapped.emit (window); |
1139 | + WindowManager::window_unmapped.emit (window->id ()); |
1140 | break; |
1141 | default: |
1142 | break; |
1143 | @@ -216,3 +224,68 @@ |
1144 | |
1145 | m_ExpoAction->initiate () (m_ExpoAction, 0, argument); |
1146 | } |
1147 | + |
1148 | +// WindowManager implementation |
1149 | +bool |
1150 | +PluginAdapter::IsWindowMaximized (guint xid) |
1151 | +{ |
1152 | + Window win = (Window)xid; |
1153 | + CompWindow *window; |
1154 | + |
1155 | + window = m_Screen->findWindow (win); |
1156 | + if (window) |
1157 | + { |
1158 | + return window->state () & MAXIMIZE_STATE; |
1159 | + } |
1160 | + |
1161 | + return false; |
1162 | +} |
1163 | + |
1164 | +bool |
1165 | +PluginAdapter::IsWindowDecorated (guint32 xid) |
1166 | +{ |
1167 | + Window win = (Window)xid; |
1168 | + CompWindow *window; |
1169 | + |
1170 | + window = m_Screen->findWindow (win); |
1171 | + if (window) |
1172 | + { |
1173 | + unsigned int decor = window->mwmDecor (); |
1174 | + |
1175 | + return decor & (MwmDecorAll | MwmDecorTitle); |
1176 | + } |
1177 | + return true; |
1178 | +} |
1179 | + |
1180 | +void |
1181 | +PluginAdapter::Restore (guint32 xid) |
1182 | +{ |
1183 | + Window win = (Window)xid; |
1184 | + CompWindow *window; |
1185 | + |
1186 | + window = m_Screen->findWindow (win); |
1187 | + if (window) |
1188 | + window->maximize (0); |
1189 | +} |
1190 | + |
1191 | +void |
1192 | +PluginAdapter::Minimize (guint32 xid) |
1193 | +{ |
1194 | + Window win = (Window)xid; |
1195 | + CompWindow *window; |
1196 | + |
1197 | + window = m_Screen->findWindow (win); |
1198 | + if (window) |
1199 | + window->minimize (); |
1200 | +} |
1201 | + |
1202 | +void |
1203 | +PluginAdapter::Close (guint32 xid) |
1204 | +{ |
1205 | + Window win = (Window)xid; |
1206 | + CompWindow *window; |
1207 | + |
1208 | + window = m_Screen->findWindow (win); |
1209 | + if (window) |
1210 | + window->close (CurrentTime); |
1211 | +} |
1212 | |
1213 | === modified file 'src/PluginAdapter.h' |
1214 | --- src/PluginAdapter.h 2010-12-17 10:03:18 +0000 |
1215 | +++ src/PluginAdapter.h 2010-12-17 10:43:24 +0000 |
1216 | @@ -24,7 +24,9 @@ |
1217 | |
1218 | #include <sigc++/sigc++.h> |
1219 | |
1220 | -class PluginAdapter : public sigc::trackable |
1221 | +#include "WindowManager.h" |
1222 | + |
1223 | +class PluginAdapter : public sigc::trackable, public WindowManager |
1224 | { |
1225 | public: |
1226 | static PluginAdapter * Default (); |
1227 | @@ -52,6 +54,13 @@ |
1228 | void NotifyResized (CompWindow *window, int x, int y, int w, int h); |
1229 | void NotifyStateChange (CompWindow *window, unsigned int state, unsigned int last_state); |
1230 | |
1231 | + // WindowManager implementation |
1232 | + bool IsWindowMaximized (guint xid); |
1233 | + bool IsWindowDecorated (guint xid); |
1234 | + void Restore (guint32 xid); |
1235 | + void Minimize (guint32 xid); |
1236 | + void Close (guint32 xid); |
1237 | + |
1238 | sigc::signal<void, CompWindow *> window_maximized; |
1239 | sigc::signal<void, CompWindow *> window_restored; |
1240 | sigc::signal<void, CompWindow *> window_minimized; |
1241 | |
1242 | === added file 'src/WindowButtons.cpp' |
1243 | --- src/WindowButtons.cpp 1970-01-01 00:00:00 +0000 |
1244 | +++ src/WindowButtons.cpp 2010-12-17 10:43:24 +0000 |
1245 | @@ -0,0 +1,254 @@ |
1246 | +/* |
1247 | + * Copyright (C) 2010 Canonical Ltd |
1248 | + * |
1249 | + * This program is free software: you can redistribute it and/or modify |
1250 | + * it under the terms of the GNU General Public License version 3 as |
1251 | + * published by the Free Software Foundation. |
1252 | + * |
1253 | + * This program is distributed in the hope that it will be useful, |
1254 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1255 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1256 | + * GNU General Public License for more details. |
1257 | + * |
1258 | + * You should have received a copy of the GNU General Public License |
1259 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1260 | + * |
1261 | + * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> |
1262 | + */ |
1263 | + |
1264 | +#include "Nux/Nux.h" |
1265 | +#include "Nux/HLayout.h" |
1266 | +#include "Nux/VLayout.h" |
1267 | +#include "Nux/Button.h" |
1268 | + |
1269 | +#include "NuxGraphics/GLThread.h" |
1270 | +#include "Nux/BaseWindow.h" |
1271 | +#include "Nux/WindowCompositor.h" |
1272 | + |
1273 | +#include "WindowButtons.h" |
1274 | + |
1275 | +#include <glib.h> |
1276 | + |
1277 | + |
1278 | +// FIXME: This will be all automatic in the future |
1279 | +#define AMBIANCE "/usr/share/themes/Ambiance/metacity-1" |
1280 | + |
1281 | +enum |
1282 | +{ |
1283 | + BUTTON_CLOSE=0, |
1284 | + BUTTON_MINIMISE, |
1285 | + BUTTON_UNMAXIMISE |
1286 | +}; |
1287 | + |
1288 | +class WindowButton : public nux::Button |
1289 | +{ |
1290 | + // A single window button |
1291 | +public: |
1292 | + WindowButton (int type) |
1293 | + : nux::Button ("X", NUX_TRACKER_LOCATION), |
1294 | + _normal_tex (NULL), |
1295 | + _prelight_tex (NULL), |
1296 | + _pressed_tex (NULL) |
1297 | + { |
1298 | + if (type == BUTTON_CLOSE) |
1299 | + LoadImages ("close"); |
1300 | + else if (type == BUTTON_MINIMISE) |
1301 | + LoadImages ("minimize"); |
1302 | + else |
1303 | + LoadImages ("unmaximize"); |
1304 | + } |
1305 | + |
1306 | + ~WindowButton () |
1307 | + { |
1308 | + _normal_tex->UnReference (); |
1309 | + _prelight_tex->UnReference (); |
1310 | + _pressed_tex->UnReference (); |
1311 | + } |
1312 | + |
1313 | + void Draw (nux::GraphicsEngine &GfxContext, bool force_draw) |
1314 | + { |
1315 | + nux::Geometry geo = GetGeometry (); |
1316 | + nux::BaseTexture *tex; |
1317 | + nux::TexCoordXForm texxform; |
1318 | + |
1319 | + GfxContext.PushClippingRectangle (geo); |
1320 | + |
1321 | + if (HasMouseFocus ()) |
1322 | + { |
1323 | + tex = _pressed_tex; |
1324 | + } |
1325 | + else if (IsMouseInside ()) |
1326 | + { |
1327 | + tex = _prelight_tex; |
1328 | + } |
1329 | + else |
1330 | + { |
1331 | + tex = _normal_tex; |
1332 | + } |
1333 | + |
1334 | + GfxContext.GetRenderStates ().SetSeparateBlend (true, |
1335 | + GL_SRC_ALPHA, |
1336 | + GL_ONE_MINUS_SRC_ALPHA, |
1337 | + GL_ONE_MINUS_DST_ALPHA, |
1338 | + GL_ONE); |
1339 | + GfxContext.GetRenderStates ().SetColorMask (true, true, true, true); |
1340 | + if (tex) |
1341 | + GfxContext.QRP_GLSL_1Tex (geo.x, |
1342 | + geo.y, |
1343 | + (float)geo.width, |
1344 | + (float)geo.height, |
1345 | + tex->GetDeviceTexture (), |
1346 | + texxform, |
1347 | + nux::Color::White); |
1348 | + GfxContext.GetRenderStates ().SetSeparateBlend (false, |
1349 | + GL_SRC_ALPHA, |
1350 | + GL_ONE_MINUS_SRC_ALPHA, |
1351 | + GL_ONE_MINUS_DST_ALPHA, |
1352 | + GL_ONE); |
1353 | + GfxContext.PopClippingRectangle(); |
1354 | + } |
1355 | + |
1356 | + void LoadImages (const char *name) |
1357 | + { |
1358 | + //FIXME: We need to somehow be theme aware. Or, at least support the themes |
1359 | + // we know and have a good default fallback |
1360 | + gchar *filename; |
1361 | + GError *error = NULL; |
1362 | + GdkPixbuf *_normal; |
1363 | + GdkPixbuf *_prelight; |
1364 | + GdkPixbuf *_pressed; |
1365 | + |
1366 | + filename = g_strdup_printf ("%s/%s.png", AMBIANCE, name); |
1367 | + _normal = gdk_pixbuf_new_from_file (filename, &error); |
1368 | + if (error) |
1369 | + { |
1370 | + g_warning ("Unable to load window button %s: %s", filename, error->message); |
1371 | + g_error_free (error); |
1372 | + error = NULL; |
1373 | + } |
1374 | + else |
1375 | + _normal_tex = nux::CreateTextureFromPixbuf (_normal); |
1376 | + g_free (filename); |
1377 | + g_object_unref (_normal); |
1378 | + |
1379 | + filename = g_strdup_printf ("%s/%s_focused_prelight.png", AMBIANCE, name); |
1380 | + _prelight = gdk_pixbuf_new_from_file (filename, &error); |
1381 | + if (error) |
1382 | + { |
1383 | + g_warning ("Unable to load window button %s: %s", filename, error->message); |
1384 | + g_error_free (error); |
1385 | + error = NULL; |
1386 | + } |
1387 | + else |
1388 | + _prelight_tex = nux::CreateTextureFromPixbuf (_prelight); |
1389 | + g_free (filename); |
1390 | + g_object_unref (_prelight); |
1391 | + |
1392 | + filename = g_strdup_printf ("%s/%s_focused_pressed.png", AMBIANCE, name); |
1393 | + _pressed = gdk_pixbuf_new_from_file (filename, &error); |
1394 | + if (error) |
1395 | + { |
1396 | + g_warning ("Unable to load window button %s: %s", name, error->message); |
1397 | + g_error_free (error); |
1398 | + error = NULL; |
1399 | + } |
1400 | + else |
1401 | + _pressed_tex = nux::CreateTextureFromPixbuf (_pressed); |
1402 | + g_free (filename); |
1403 | + g_object_unref (_pressed); |
1404 | + |
1405 | + if (_normal_tex) |
1406 | + SetMinimumSize (_normal_tex->GetWidth (), _normal_tex->GetHeight ()); |
1407 | + } |
1408 | + |
1409 | +private: |
1410 | + nux::BaseTexture *_normal_tex; |
1411 | + nux::BaseTexture *_prelight_tex; |
1412 | + nux::BaseTexture *_pressed_tex; |
1413 | +}; |
1414 | + |
1415 | + |
1416 | +WindowButtons::WindowButtons () |
1417 | +: HLayout ("", NUX_TRACKER_LOCATION) |
1418 | +{ |
1419 | + WindowButton *but; |
1420 | + |
1421 | + but = new WindowButton (BUTTON_CLOSE); |
1422 | + AddView (but, 0, nux::eCenter, nux::eFix); |
1423 | + but->sigClick.connect (sigc::mem_fun (this, &WindowButtons::OnCloseClicked)); |
1424 | + but->OnMouseEnter.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseEnter)); |
1425 | + but->OnMouseLeave.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseLeave)); |
1426 | + |
1427 | + but = new WindowButton (BUTTON_MINIMISE); |
1428 | + AddView (but, 0, nux::eCenter, nux::eFix); |
1429 | + but->sigClick.connect (sigc::mem_fun (this, &WindowButtons::OnMinimizeClicked)); |
1430 | + but->OnMouseEnter.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseEnter)); |
1431 | + but->OnMouseLeave.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseLeave)); |
1432 | + |
1433 | + but = new WindowButton (BUTTON_UNMAXIMISE); |
1434 | + AddView (but, 0, nux::eCenter, nux::eFix); |
1435 | + but->sigClick.connect (sigc::mem_fun (this, &WindowButtons::OnRestoreClicked)); |
1436 | + but->OnMouseEnter.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseEnter)); |
1437 | + but->OnMouseLeave.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseLeave)); |
1438 | + |
1439 | + SetContentDistribution (nux::eStackLeft); |
1440 | +} |
1441 | + |
1442 | + |
1443 | +WindowButtons::~WindowButtons () |
1444 | +{ |
1445 | +} |
1446 | + |
1447 | +void |
1448 | +WindowButtons::OnCloseClicked () |
1449 | +{ |
1450 | + close_clicked.emit (); |
1451 | +} |
1452 | + |
1453 | +void |
1454 | +WindowButtons::OnMinimizeClicked () |
1455 | +{ |
1456 | + minimize_clicked.emit (); |
1457 | +} |
1458 | + |
1459 | +void |
1460 | +WindowButtons::OnRestoreClicked () |
1461 | +{ |
1462 | + restore_clicked.emit (); |
1463 | +} |
1464 | + |
1465 | +const gchar * |
1466 | +WindowButtons::GetName () |
1467 | +{ |
1468 | + return "window-buttons"; |
1469 | +} |
1470 | + |
1471 | +const gchar * |
1472 | +WindowButtons::GetChildsName () |
1473 | +{ |
1474 | + return ""; |
1475 | +} |
1476 | + |
1477 | +void |
1478 | +WindowButtons::AddProperties (GVariantBuilder *builder) |
1479 | +{ |
1480 | + nux::Geometry geo = GetGeometry (); |
1481 | + |
1482 | + /* Now some props from ourselves */ |
1483 | + g_variant_builder_add (builder, "{sv}", "x", g_variant_new_int32 (geo.x)); |
1484 | + g_variant_builder_add (builder, "{sv}", "y", g_variant_new_int32 (geo.y)); |
1485 | + g_variant_builder_add (builder, "{sv}", "width", g_variant_new_int32 (geo.width)); |
1486 | + g_variant_builder_add (builder, "{sv}", "height", g_variant_new_int32 (geo.height)); |
1487 | +} |
1488 | + |
1489 | +void WindowButtons::RecvMouseEnter (int x, int y, unsigned long button_flags, unsigned long key_flags) |
1490 | +{ |
1491 | + redraw_signal.emit (); |
1492 | +} |
1493 | + |
1494 | +void WindowButtons::RecvMouseLeave (int x, int y, unsigned long button_flags, unsigned long key_flags) |
1495 | +{ |
1496 | + redraw_signal.emit (); |
1497 | +} |
1498 | + |
1499 | + |
1500 | |
1501 | === added file 'src/WindowButtons.h' |
1502 | --- src/WindowButtons.h 1970-01-01 00:00:00 +0000 |
1503 | +++ src/WindowButtons.h 2010-12-17 10:43:24 +0000 |
1504 | @@ -0,0 +1,63 @@ |
1505 | +/* |
1506 | + * Copyright (C) 2010 Canonical Ltd |
1507 | + * |
1508 | + * This program is free software: you can redistribute it and/or modify |
1509 | + * it under the terms of the GNU General Public License version 3 as |
1510 | + * published by the Free Software Foundation. |
1511 | + * |
1512 | + * This program is distributed in the hope that it will be useful, |
1513 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1514 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1515 | + * GNU General Public License for more details. |
1516 | + * |
1517 | + * You should have received a copy of the GNU General Public License |
1518 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1519 | + * |
1520 | + * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> |
1521 | + */ |
1522 | + |
1523 | +#ifndef WINDOW_BUTTONS_H |
1524 | +#define WINDOW_BUTTONS_H |
1525 | + |
1526 | +#include <Nux/View.h> |
1527 | + |
1528 | +#include "Introspectable.h" |
1529 | + |
1530 | +class WindowButtons : public nux::HLayout, public Introspectable |
1531 | +{ |
1532 | + // These are the [close][minimize][restore] buttons on the panel when there |
1533 | + // is a maximized window |
1534 | + |
1535 | +public: |
1536 | + WindowButtons (); |
1537 | + ~WindowButtons (); |
1538 | + |
1539 | + sigc::signal<void> close_clicked; |
1540 | + sigc::signal<void> minimize_clicked; |
1541 | + sigc::signal<void> restore_clicked; |
1542 | + sigc::signal<void> redraw_signal; |
1543 | + |
1544 | +protected: |
1545 | + const gchar * GetName (); |
1546 | + const gchar * GetChildsName (); |
1547 | + void AddProperties (GVariantBuilder *builder); |
1548 | + |
1549 | + |
1550 | + // For testing the buttons |
1551 | + void RecvMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags); |
1552 | + void RecvMouseUp (int x, int y, unsigned long button_flags, unsigned long key_flags); |
1553 | + void RecvMouseEnter (int x, int y, unsigned long button_flags, unsigned long key_flags); |
1554 | + void RecvMouseLeave (int x, int y, unsigned long button_flags, unsigned long key_flags); |
1555 | + void RecvMouseClick (int x, int y, unsigned long button_flags, unsigned long key_flags); |
1556 | + void RecvMouseMove (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); |
1557 | + |
1558 | +private: |
1559 | + void OnCloseClicked (); |
1560 | + void OnMinimizeClicked (); |
1561 | + void OnRestoreClicked (); |
1562 | + |
1563 | +private: |
1564 | + nux::HLayout *_layout; |
1565 | +}; |
1566 | + |
1567 | +#endif |
1568 | |
1569 | === added file 'src/WindowManager.cpp' |
1570 | --- src/WindowManager.cpp 1970-01-01 00:00:00 +0000 |
1571 | +++ src/WindowManager.cpp 2010-12-17 10:43:24 +0000 |
1572 | @@ -0,0 +1,171 @@ |
1573 | +/* |
1574 | + * Copyright (C) 2010 Canonical Ltd |
1575 | + * |
1576 | + * This program is free software: you can redistribute it and/or modify |
1577 | + * it under the terms of the GNU General Public License version 3 as |
1578 | + * published by the Free Software Foundation. |
1579 | + * |
1580 | + * This program is distributed in the hope that it will be useful, |
1581 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1582 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1583 | + * GNU General Public License for more details. |
1584 | + * |
1585 | + * You should have received a copy of the GNU General Public License |
1586 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1587 | + * |
1588 | + * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> |
1589 | + */ |
1590 | + |
1591 | +#include "WindowManager.h" |
1592 | + |
1593 | +#include <gdk/gdkx.h> |
1594 | + |
1595 | +typedef struct { |
1596 | + unsigned long flags; |
1597 | + unsigned long functions; |
1598 | + unsigned long decorations; |
1599 | + long input_mode; |
1600 | + unsigned long status; |
1601 | +} MotifWmHints, MwmHints; |
1602 | + |
1603 | +#define MWM_HINTS_FUNCTIONS (1L << 0) |
1604 | +#define MWM_HINTS_DECORATIONS (1L << 1) |
1605 | +#define _XA_MOTIF_WM_HINTS "_MOTIF_WM_HINTS" |
1606 | + |
1607 | +static void gdk_window_set_mwm_hints (Window xid, |
1608 | + MotifWmHints *new_hints); |
1609 | + |
1610 | + |
1611 | +static WindowManager *window_manager = NULL; |
1612 | + |
1613 | +class WindowManagerDummy : public WindowManager |
1614 | +{ |
1615 | + bool IsWindowMaximized (guint32 xid) |
1616 | + { |
1617 | + return false; |
1618 | + } |
1619 | + |
1620 | + bool IsWindowDecorated (guint32 xid) |
1621 | + { |
1622 | + return true; |
1623 | + } |
1624 | + |
1625 | + void Restore (guint32 xid) |
1626 | + { |
1627 | + g_debug ("%s", G_STRFUNC); |
1628 | + } |
1629 | + |
1630 | + void Minimize (guint32 xid) |
1631 | + { |
1632 | + g_debug ("%s", G_STRFUNC); |
1633 | + } |
1634 | + |
1635 | + void Close (guint32 xid) |
1636 | + { |
1637 | + g_debug ("%s", G_STRFUNC); |
1638 | + } |
1639 | +}; |
1640 | + |
1641 | +WindowManager * |
1642 | +WindowManager::Default () |
1643 | +{ |
1644 | + if (!window_manager) |
1645 | + window_manager = new WindowManagerDummy (); |
1646 | + |
1647 | + return window_manager; |
1648 | +} |
1649 | + |
1650 | +void |
1651 | +WindowManager::SetDefault (WindowManager *manager) |
1652 | +{ |
1653 | + window_manager = manager; |
1654 | +} |
1655 | + |
1656 | +void |
1657 | +WindowManager::Decorate (guint32 xid) |
1658 | +{ |
1659 | + MotifWmHints hints = { 0 }; |
1660 | + |
1661 | + hints.flags = MWM_HINTS_DECORATIONS; |
1662 | + hints.decorations = GDK_DECOR_ALL; |
1663 | + |
1664 | + gdk_window_set_mwm_hints (xid, &hints); |
1665 | +} |
1666 | + |
1667 | +void |
1668 | +WindowManager::Undecorate (guint32 xid) |
1669 | +{ |
1670 | + MotifWmHints hints = { 0 }; |
1671 | + |
1672 | + hints.flags = MWM_HINTS_DECORATIONS; |
1673 | + hints.decorations = 0; |
1674 | + |
1675 | + gdk_window_set_mwm_hints (xid, &hints); |
1676 | +} |
1677 | + |
1678 | +/* |
1679 | + * Copied over C code |
1680 | + */ |
1681 | +static void |
1682 | +gdk_window_set_mwm_hints (Window xid, |
1683 | + MotifWmHints *new_hints) |
1684 | +{ |
1685 | + GdkDisplay *display = gdk_display_get_default(); |
1686 | + Atom hints_atom = None; |
1687 | + guchar *data = NULL; |
1688 | + MotifWmHints *hints = NULL; |
1689 | + Atom type = None; |
1690 | + gint format; |
1691 | + gulong nitems; |
1692 | + gulong bytes_after; |
1693 | + |
1694 | + g_return_if_fail (GDK_IS_DISPLAY (display)); |
1695 | + |
1696 | + hints_atom = gdk_x11_get_xatom_by_name_for_display (display, |
1697 | + _XA_MOTIF_WM_HINTS); |
1698 | + |
1699 | + gdk_error_trap_push (); |
1700 | + XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), |
1701 | + xid, |
1702 | + hints_atom, 0, sizeof (MotifWmHints)/sizeof (long), |
1703 | + False, AnyPropertyType, &type, &format, &nitems, |
1704 | + &bytes_after, &data); |
1705 | + gdk_flush (); |
1706 | + if (gdk_error_trap_pop ()) |
1707 | + { |
1708 | + g_debug ("ERROR: Cannot set decorations"); |
1709 | + return; |
1710 | + } |
1711 | + |
1712 | + if (type != hints_atom || !data) |
1713 | + hints = new_hints; |
1714 | + else |
1715 | + { |
1716 | + hints = (MotifWmHints *)data; |
1717 | + |
1718 | + if (new_hints->flags & MWM_HINTS_FUNCTIONS) |
1719 | + { |
1720 | + hints->flags |= MWM_HINTS_FUNCTIONS; |
1721 | + hints->functions = new_hints->functions; |
1722 | + } |
1723 | + if (new_hints->flags & MWM_HINTS_DECORATIONS) |
1724 | + { |
1725 | + hints->flags |= MWM_HINTS_DECORATIONS; |
1726 | + hints->decorations = new_hints->decorations; |
1727 | + } |
1728 | + } |
1729 | + |
1730 | + gdk_error_trap_push (); |
1731 | + XChangeProperty (GDK_DISPLAY_XDISPLAY (display), |
1732 | + xid, |
1733 | + hints_atom, hints_atom, 32, PropModeReplace, |
1734 | + (guchar *)hints, sizeof (MotifWmHints)/sizeof (long)); |
1735 | + gdk_flush (); |
1736 | + if (gdk_error_trap_pop ()) |
1737 | + { |
1738 | + g_debug ("ERROR: Setting decorations"); |
1739 | + } |
1740 | + |
1741 | + if (data) |
1742 | + XFree (data); |
1743 | +} |
1744 | |
1745 | === added file 'src/WindowManager.h' |
1746 | --- src/WindowManager.h 1970-01-01 00:00:00 +0000 |
1747 | +++ src/WindowManager.h 2010-12-17 10:43:24 +0000 |
1748 | @@ -0,0 +1,57 @@ |
1749 | +/* |
1750 | + * Copyright (C) 2010 Canonical Ltd |
1751 | + * |
1752 | + * This program is free software: you can redistribute it and/or modify |
1753 | + * it under the terms of the GNU General Public License version 3 as |
1754 | + * published by the Free Software Foundation. |
1755 | + * |
1756 | + * This program is distributed in the hope that it will be useful, |
1757 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1758 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1759 | + * GNU General Public License for more details. |
1760 | + * |
1761 | + * You should have received a copy of the GNU General Public License |
1762 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1763 | + * |
1764 | + * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> |
1765 | + */ |
1766 | + |
1767 | +#ifndef WINDOW_MANAGER_H |
1768 | +#define WINDOW_MANAGER_H |
1769 | + |
1770 | +#include <glib.h> |
1771 | +#include <sigc++/sigc++.h> |
1772 | + |
1773 | +class WindowManager |
1774 | +{ |
1775 | + // This is a glue interface that breaks the dependancy of Unity with Compiz |
1776 | + // Basically it has a default implementation that does nothing useful, but |
1777 | + // the idea is that unity.cpp uses SetDefault() early enough in it's |
1778 | + // initialization so the things that require it get a usable implementation |
1779 | + // |
1780 | + // Currently only the Panel uses it but hopefully we'll get more of |
1781 | + // PluginAdaptor features moved into here and also get the Launcher to use |
1782 | + // it. |
1783 | + |
1784 | +public: |
1785 | + static WindowManager * Default (); |
1786 | + static void SetDefault (WindowManager *manager); |
1787 | + |
1788 | + virtual bool IsWindowMaximized (guint32 xid) = 0; |
1789 | + virtual bool IsWindowDecorated (guint32 xid) = 0; |
1790 | + |
1791 | + virtual void Restore (guint32 xid) = 0; |
1792 | + virtual void Minimize (guint32 xid) = 0; |
1793 | + virtual void Close (guint32 xid) = 0; |
1794 | + |
1795 | + virtual void Decorate (guint32 xid); |
1796 | + virtual void Undecorate (guint32 xid); |
1797 | + |
1798 | + // Signals |
1799 | + sigc::signal<void, guint32> window_mapped; |
1800 | + sigc::signal<void, guint32> window_unmapped; |
1801 | + sigc::signal<void, guint32> window_maximized; |
1802 | + sigc::signal<void, guint32> window_restored; |
1803 | +}; |
1804 | + |
1805 | +#endif // WINDOW_MANAGER_H |
1806 | |
1807 | === modified file 'src/unity.cpp' |
1808 | --- src/unity.cpp 2010-12-16 21:07:28 +0000 |
1809 | +++ src/unity.cpp 2010-12-17 10:43:24 +0000 |
1810 | @@ -395,6 +395,8 @@ |
1811 | GLScreenInterface::setHandler (gScreen); |
1812 | |
1813 | PluginAdapter::Initialize (screen); |
1814 | + WindowManager::SetDefault (PluginAdapter::Default ()); |
1815 | + |
1816 | StartupNotifyService::Default ()->SetSnDisplay (screen->snDisplay (), screen->screenNum ()); |
1817 | |
1818 | nux::NuxInitialize (0); |
1819 | @@ -410,7 +412,6 @@ |
1820 | |
1821 | debugger = new IntrospectionDBusInterface (this); |
1822 | |
1823 | - |
1824 | optionSetLauncherAutohideNotify (boost::bind (&UnityScreen::optionChanged, this, _1, _2)); |
1825 | optionSetLauncherFloatNotify (boost::bind (&UnityScreen::optionChanged, this, _1, _2)); |
1826 | |
1827 | |
1828 | === modified file 'tests/CMakeLists.txt' |
1829 | --- tests/CMakeLists.txt 2010-12-13 09:54:54 +0000 |
1830 | +++ tests/CMakeLists.txt 2010-12-17 10:43:24 +0000 |
1831 | @@ -82,6 +82,14 @@ |
1832 | ../src/Introspectable.h |
1833 | ../src/PanelHomeButton.cpp |
1834 | ../src/PanelHomeButton.h |
1835 | + ../src/PanelMenuView.cpp |
1836 | + ../src/PanelMenuView.h |
1837 | + ../src/StaticCairoText.cpp |
1838 | + ../src/StaticCairoText.h |
1839 | + ../src/WindowButtons.cpp |
1840 | + ../src/WindowButtons.h |
1841 | + ../src/WindowManager.cpp |
1842 | + ../src/WindowManager.h |
1843 | ../libunity/ubus-server.c |
1844 | ../libunity/ubus-server.h |
1845 | ) |
Oh, some of the linked bugs are because of reusing the same branch, please ignore that.