Merge lp:~3v1n0/unity/switcher-glowing-decorations into lp:unity

Proposed by Marco Trevisan (Treviño)
Status: Merged
Approved by: Marco Trevisan (Treviño)
Approved revision: no longer in the source branch.
Merged at revision: 2901
Proposed branch: lp:~3v1n0/unity/switcher-glowing-decorations
Merge into: lp:unity
Diff against target: 3056 lines (+1103/-457)
26 files modified
launcher/CMakeLists.txt (+0/-1)
launcher/Launcher.cpp (+1/-1)
launcher/StandaloneSwitcher.cpp (+3/-1)
launcher/SwitcherController.cpp (+3/-3)
launcher/SwitcherController.h (+1/-1)
launcher/SwitcherView.cpp (+82/-120)
launcher/SwitcherView.h (+8/-9)
panel/PanelMenuView.cpp (+3/-11)
plugins/unityshell/src/unityshell.cpp (+188/-122)
plugins/unityshell/src/unityshell.h (+10/-3)
plugins/unityshell/src/unityshell_glow.cpp (+3/-3)
tests/CMakeLists.txt (+2/-0)
tests/autopilot/unity/emulators/screen.py (+8/-0)
tests/autopilot/unity/emulators/switcher.py (+11/-1)
tests/autopilot/unity/tests/test_switcher.py (+31/-8)
tests/test_layout_system.cpp (+158/-0)
tests/test_main.cpp (+0/-2)
unity-shared/AbstractIconRenderer.h (+1/-2)
unity-shared/CMakeLists.txt (+1/-0)
unity-shared/LayoutSystem.cpp (+57/-58)
unity-shared/LayoutSystem.h (+19/-22)
unity-shared/PluginAdapter.cpp (+216/-73)
unity-shared/PluginAdapter.h (+8/-1)
unity-shared/StandaloneWindowManager.cpp (+231/-15)
unity-shared/StandaloneWindowManager.h (+45/-0)
unity-shared/WindowManager.h (+13/-0)
To merge this branch: bzr merge lp:~3v1n0/unity/switcher-glowing-decorations
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Needs Fixing
Andrea Azzarone (community) Approve
John Lea (community) design Approve
Thomi Richards Pending
Review via email: mp+134019@code.launchpad.net

Commit message

UnityWindow: draw fake decorations on spread windows in switcher

Description of the change

Implemented the fake decorations in applications switcher spread, to match design specifications: now the selected window draws a decoration with full-size title and uses real glow.

To do this, I had to refactor a little the unityshell's UnityWindow code to allow to reuse the scale decoration code for both the scale and the switcher. This fixes also a redraw issue in scale, correctly damaging the changed areas.

Some cleanup and refactor of the PluginAdapter code that now has two different functions to check if a window is generally decorated (HasDecorations) and if it is actually decorated (IsDecorated). It also saves the decoration extents values in an Atom for maximized windows, so that we're always able to get the decoration size of a window (all this is needed to draw a correct decoration on maximized windows).

Added new unit tests for the layout system (this required some rework of StandaloneWindowManager), added new and updated autopilot tests.

Result: http://i.imgur.com/SuTo4.png

To post a comment you must log in.
Revision history for this message
Andrea Azzarone (azzar1) wrote :

3026 lines (+1085/-455) 26 files modified

I hate you :)

1893 + typedef std::vector<LayoutWindow::Ptr> List;

You call it List but it's a vector. I really don't like it.

868 + if (launcher->Hidden() || launcher_hide_mode == LAUNCHER_HIDE_NEVER || launcher_hide_mode == LAUNCHER_HIDE_AUTOHIDE)

Does it makes sense? launcher_hide_mode can be LAUNCHER_HIDE_NEVER or LAUNCHER_HIDE_AUTOHIDE so this expression evaluates always true, right?

Bookmark: line 1068 (I'll continue the review later)

Please next time consider to have a different branch for style changes :)

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

> 3026 lines (+1085/-455) 26 files modified
>
> I hate you :)

:-P

> 1893 + typedef std::vector<LayoutWindow::Ptr> List;
>
> You call it List but it's a vector. I really don't like it.

It was already called List, so I kept the name it had... But I can change it to vector if you prefer.

> 868 + if (launcher->Hidden() || launcher_hide_mode == LAUNCHER_HIDE_NEVER
> || launcher_hide_mode == LAUNCHER_HIDE_AUTOHIDE)
>
> Does it makes sense? launcher_hide_mode can be LAUNCHER_HIDE_NEVER or
> LAUNCHER_HIDE_AUTOHIDE so this expression evaluates always true, right?

Yeah, you're right... I just did a replacement of the old variable, but this seems to be wrong, I guess that the logic should just be: continue if (launcher->options()->hide_mode == LAUNCHER_HIDE_AUTOHIDE && launcher->Hidden())... Fixing it.

> Please next time consider to have a different branch for style changes :)

You know, it was all mixed... It was hard to split.

Revision history for this message
John Lea (johnlea) :
review: Approve (design)
Revision history for this message
Andrea Azzarone (azzar1) wrote :

LGTM. Works here.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'launcher/CMakeLists.txt'
2--- launcher/CMakeLists.txt 2012-11-13 22:39:49 +0000
3+++ launcher/CMakeLists.txt 2012-11-15 18:52:31 +0000
4@@ -91,7 +91,6 @@
5 SwitcherController.cpp
6 SwitcherModel.cpp
7 SwitcherView.cpp
8- LayoutSystem.cpp
9 )
10
11 add_library (switcher-lib STATIC ${SWITCHER_SOURCES})
12
13=== modified file 'launcher/Launcher.cpp'
14--- launcher/Launcher.cpp 2012-11-13 22:39:49 +0000
15+++ launcher/Launcher.cpp 2012-11-15 18:52:31 +0000
16@@ -1369,7 +1369,7 @@
17 bool Launcher::OnUpdateDragManagerTimeout()
18 {
19 #ifdef USE_X11
20- if (display() == 0)
21+ if (!display())
22 return false;
23
24 if (!_selection_atom)
25
26=== modified file 'launcher/StandaloneSwitcher.cpp'
27--- launcher/StandaloneSwitcher.cpp 2012-11-08 09:12:24 +0000
28+++ launcher/StandaloneSwitcher.cpp 2012-11-15 18:52:31 +0000
29@@ -34,6 +34,7 @@
30 #include "SwitcherController.h"
31 #include "MockLauncherIcon.h"
32 #include "unity-shared/BackgroundEffectHelper.h"
33+#include "unity-shared/UnitySettings.h"
34
35 using namespace unity::switcher;
36 using namespace unity::ui;
37@@ -277,7 +278,7 @@
38
39 layout->SetContentDistribution(nux::MAJOR_POSITION_CENTER);
40
41- nux::BaseTexture *background = nux::CreateTexture2DFromFile("/usr/share/backgrounds/Grey_day_by_Drew__.jpg", -1, true);
42+ nux::BaseTexture *background = nux::CreateTexture2DFromFile("/usr/share/backgrounds/warty-final-ubuntu.png", -1, true);
43 nux::GetGraphicsDisplay()->GetGpuDevice()->backup_texture0_ = background->GetDeviceTexture();
44
45
46@@ -290,6 +291,7 @@
47 gtk_init(&argc, &argv);
48 nux::NuxInitialize(0);
49
50+ unity::Settings settings;
51 BackgroundEffectHelper::blur_type = unity::BLUR_ACTIVE;
52 nux::WindowThread* wt = nux::CreateGUIThread(TEXT("Unity Switcher"), 1200, 600, 0, &ThreadWidgetInit, 0);
53
54
55=== modified file 'launcher/SwitcherController.cpp'
56--- launcher/SwitcherController.cpp 2012-11-06 18:19:09 +0000
57+++ launcher/SwitcherController.cpp 2012-11-15 18:52:31 +0000
58@@ -30,7 +30,7 @@
59 {
60 using launcher::AbstractLauncherIcon;
61 using launcher::ActionArg;
62-using ui::LayoutWindowList;
63+using ui::LayoutWindow;
64
65 namespace
66 {
67@@ -398,11 +398,11 @@
68 }
69 }
70
71-LayoutWindowList Controller::ExternalRenderTargets()
72+LayoutWindow::Vector Controller::ExternalRenderTargets()
73 {
74 if (!view_)
75 {
76- LayoutWindowList result;
77+ LayoutWindow::Vector result;
78 return result;
79 }
80 return view_->ExternalTargets();
81
82=== modified file 'launcher/SwitcherController.h'
83--- launcher/SwitcherController.h 2012-11-06 18:19:09 +0000
84+++ launcher/SwitcherController.h 2012-11-15 18:52:31 +0000
85@@ -90,7 +90,7 @@
86
87 SwitcherView * GetView ();
88
89- ui::LayoutWindowList ExternalRenderTargets ();
90+ ui::LayoutWindow::Vector ExternalRenderTargets ();
91
92 guint GetSwitcherInputWindowId() const;
93
94
95=== modified file 'launcher/SwitcherView.cpp'
96--- launcher/SwitcherView.cpp 2012-11-06 18:19:09 +0000
97+++ launcher/SwitcherView.cpp 2012-11-15 18:52:31 +0000
98@@ -17,19 +17,13 @@
99 */
100
101 #include "config.h"
102-
103 #include "SwitcherView.h"
104 #include "unity-shared/IconRenderer.h"
105-#include "LayoutSystem.h"
106-
107 #include "unity-shared/TimeUtil.h"
108
109+#include <Nux/Nux.h>
110 #include <UnityCore/Variant.h>
111
112-#include <NuxCore/Object.h>
113-#include <Nux/Nux.h>
114-#include <Nux/WindowCompositor.h>
115-
116 namespace unity
117 {
118 using namespace ui;
119@@ -41,36 +35,27 @@
120 NUX_IMPLEMENT_OBJECT_TYPE(SwitcherView);
121
122 SwitcherView::SwitcherView()
123- : UnityWindowView()
124+ : render_boxes(false)
125+ , border_size(50)
126+ , flat_spacing(10)
127+ , icon_size(128)
128+ , minimum_spacing(10)
129+ , tile_size(150)
130+ , vertical_size(tile_size + 80)
131+ , text_size(15)
132+ , animation_length(250)
133+ , monitor(-1)
134+ , spread_size(3.5f)
135+ , icon_renderer_(std::make_shared<IconRenderer>())
136+ , text_view_(new nux::StaticCairoText(""))
137+ , animation_draw_(false)
138 , target_sizes_set_(false)
139 {
140- icon_renderer_ = AbstractIconRenderer::Ptr(new IconRenderer());
141 icon_renderer_->pip_style = OVER_TILE;
142-
143- layout_system_ = LayoutSystem::Ptr (new LayoutSystem ());
144- border_size = 50;
145- flat_spacing = 10;
146- icon_size = 128;
147- minimum_spacing = 10;
148- tile_size = 150;
149- vertical_size = tile_size + 80;
150- text_size = 15;
151- animation_length = 250;
152- monitor = -1;
153- spread_size = 3.5f;
154- render_boxes = false;
155-
156- animation_draw_ = false;
157-
158 save_time_.tv_sec = 0;
159 save_time_.tv_nsec = 0;
160
161- render_targets_.clear ();
162-
163- rounding_texture_.Adopt(nux::CreateTexture2DFromFile(PKGDATADIR"/switcher_round_rect.png", -1, true));
164-
165- text_view_ = new nux::StaticCairoText("Testing");
166- text_view_->SetMaximumWidth ((int) (tile_size * spread_size));
167+ text_view_->SetMaximumWidth(tile_size * spread_size);
168 text_view_->SetLines(1);
169 text_view_->SetTextColor(nux::color::White);
170 text_view_->SetFont("Ubuntu Bold 10");
171@@ -99,15 +84,13 @@
172 .add("text-size", text_size)
173 .add("animation-length", animation_length)
174 .add("spread-size", (float)spread_size)
175- .add("label", text_view_->GetText());
176+ .add("label", text_view_->GetText())
177+ .add("label_visible", text_view_->IsVisible());
178 }
179
180-
181-
182-LayoutWindowList SwitcherView::ExternalTargets ()
183+LayoutWindow::Vector SwitcherView::ExternalTargets ()
184 {
185- LayoutWindowList result = render_targets_;
186- return result;
187+ return render_targets_;
188 }
189
190 void SwitcherView::SetModel(SwitcherModel::Ptr model)
191@@ -120,15 +103,10 @@
192 if (!model->Selection())
193 return;
194
195- if (model->detail_selection)
196- {
197- Window detail_window = model->DetailSelectionWindow();
198- text_view_->SetText(model->Selection()->NameForWindow(detail_window));
199- }
200- else
201- {
202+ text_view_->SetVisible(!model->detail_selection);
203+
204+ if (!model->detail_selection)
205 text_view_->SetText(model->Selection()->tooltip_text());
206- }
207 }
208
209 void SwitcherView::OnIconSizeChanged (int size)
210@@ -149,37 +127,28 @@
211 clock_gettime(CLOCK_MONOTONIC, &save_time_);
212 }
213
214-void SwitcherView::OnDetailSelectionIndexChanged (unsigned int index)
215+void SwitcherView::OnDetailSelectionIndexChanged(unsigned int index)
216 {
217- if (model_->detail_selection)
218- {
219- Window detail_window = model_->DetailSelectionWindow();
220- text_view_->SetText(model_->Selection()->NameForWindow(detail_window));
221- }
222 QueueDraw ();
223 }
224
225-void SwitcherView::OnDetailSelectionChanged (bool detail)
226+void SwitcherView::OnDetailSelectionChanged(bool detail)
227 {
228+ text_view_->SetVisible(!detail);
229
230- if (detail)
231- {
232- Window detail_window = model_->DetailSelectionWindow();
233- text_view_->SetText(model_->Selection()->NameForWindow(detail_window));
234- }
235- else
236- {
237+ if (!detail)
238 text_view_->SetText(model_->Selection()->tooltip_text());
239- }
240- SaveLast ();
241- QueueDraw ();
242+
243+ SaveLast();
244+ QueueDraw();
245 }
246
247 void SwitcherView::OnSelectionChanged(AbstractLauncherIcon::Ptr const& selection)
248 {
249 if (selection)
250 text_view_->SetText(selection->tooltip_text());
251- SaveLast ();
252+
253+ SaveLast();
254 QueueDraw();
255 }
256
257@@ -250,43 +219,52 @@
258 return result;
259 }
260
261-nux::Geometry SwitcherView::UpdateRenderTargets (nux::Point const& center, timespec const& current)
262+nux::Geometry SwitcherView::UpdateRenderTargets(nux::Point const& center, timespec const& current)
263 {
264- std::vector<Window> xids = model_->DetailXids ();
265+ std::vector<Window> const& xids = model_->DetailXids();
266
267 int ms_since_change = TimeUtil::TimeDelta(&current, &save_time_);
268- float progress = MIN (1.0f, (float) ms_since_change / (float) animation_length());
269+ float progress = std::min<float>(1.0f, ms_since_change / static_cast<float>(animation_length()));
270
271 for (Window window : xids)
272 {
273- LayoutWindow::Ptr layout_window (new LayoutWindow (window));
274-
275- if (window == model_->DetailSelectionWindow ())
276- layout_window->alpha = 1.0f * progress;
277- else
278- layout_window->alpha = 0.9f * progress;
279-
280- render_targets_.push_back (layout_window);
281+ auto layout_window = std::make_shared<LayoutWindow>(window);
282+ bool selected = (window == model_->DetailSelectionWindow());
283+ layout_window->selected = selected;
284+ layout_window->alpha = (selected ? 1.0f : 0.9f) * progress;
285+
286+ render_targets_.push_back(layout_window);
287 }
288
289 nux::Geometry max_bounds;
290-
291- nux::Geometry absolute = GetAbsoluteGeometry ();
292- nux::Size spread_size = SpreadSize();
293+ nux::Geometry const& absolute = GetAbsoluteGeometry();
294+ nux::Size const& spread_size = SpreadSize();
295 max_bounds.x = absolute.x + center.x - spread_size.width / 2;
296 max_bounds.y = absolute.y + center.y - spread_size.height / 2;
297 max_bounds.width = spread_size.width;
298 max_bounds.height = spread_size.height;
299
300 nux::Geometry final_bounds;
301- layout_system_->LayoutWindows (render_targets_, max_bounds, final_bounds);
302+ layout_system_.LayoutWindows(render_targets_, max_bounds, final_bounds);
303+
304+ if (progress < 1.0f)
305+ {
306+ // Animate the windows thumbnail sizes to make them grow with the switcher
307+ for (LayoutWindow::Ptr const& win : render_targets_)
308+ {
309+ auto old_geo = win->result;
310+ win->result = old_geo * progress;
311+ win->result.x += (old_geo.width - win->result.width) / 4;
312+ win->result.y += (old_geo.height - win->result.height) / 4;
313+ }
314+ }
315
316 return final_bounds;
317 }
318
319 void SwitcherView::OffsetRenderTargets (int x, int y)
320 {
321- for (LayoutWindow::Ptr target : render_targets_)
322+ for (LayoutWindow::Ptr const& target : render_targets_)
323 {
324 target->result.x += x;
325 target->result.y += y;
326@@ -295,14 +273,11 @@
327
328 nux::Size SwitcherView::SpreadSize()
329 {
330- nux::Geometry base = GetGeometry();
331- nux::Size result (base.width - border_size * 2, base.height - border_size * 2);
332+ nux::Geometry const& base = GetGeometry();
333+ nux::Size result(base.width - border_size * 2, base.height - border_size * 2);
334
335 int width_padding = std::max(model_->Size() - 1, 0) * minimum_spacing + tile_size;
336- int height_padding = text_size;
337-
338 result.width -= width_padding;
339- result.height -= height_padding;
340
341 return result;
342 }
343@@ -384,33 +359,33 @@
344 std::list<RenderArg> SwitcherView::RenderArgsFlat(nux::Geometry& background_geo, int selection, timespec const& current)
345 {
346 std::list<RenderArg> results;
347- nux::Geometry base = GetGeometry();
348+ nux::Geometry const& base = GetGeometry();
349
350 render_targets_.clear ();
351
352 bool detail_selection = model_->detail_selection;
353
354 background_geo.y = base.y + base.height / 2 - (vertical_size / 2);
355- background_geo.height = vertical_size + text_size;
356+ background_geo.height = vertical_size;
357
358+ if (text_view_->IsVisible())
359+ background_geo.height += text_size;
360
361 if (model_)
362 {
363-
364 int size = model_->Size();
365 int padded_tile_size = tile_size + flat_spacing * 2;
366 int max_width = base.width - border_size * 2;
367
368- nux::Geometry spread_bounds;
369 int spread_padded_width = 0;
370 if (detail_selection)
371 {
372- spread_bounds = UpdateRenderTargets (nux::Point (0, 0), current);
373+ nux::Geometry const& spread_bounds = UpdateRenderTargets(nux::Point(), current);
374 // remove extra space consumed by spread
375 spread_padded_width = spread_bounds.width + 100;
376 max_width -= spread_padded_width - tile_size;
377
378- int expansion = MAX (0, spread_bounds.height - icon_size);
379+ int expansion = std::max(0, spread_bounds.height - icon_size);
380 background_geo.y -= expansion / 2;
381 background_geo.height += expansion;
382 }
383@@ -445,13 +420,12 @@
384
385 GetFlatIconPositions (n_flat_icons, size, selection, first_flat, last_flat, half_fold_left, half_fold_right);
386
387- SwitcherModel::iterator it;
388 int i = 0;
389 int y = base.y + base.height / 2;
390 x += border_size;
391- for (it = model_->begin(); it != model_->end(); ++it)
392+ for (auto const& icon : *model_)
393 {
394- RenderArg arg = CreateBaseArgForIcon(*it);
395+ RenderArg arg = CreateBaseArgForIcon(icon);
396
397 float scalar = partial_overflow_scalar;
398
399@@ -559,13 +533,13 @@
400 nux::Geometry base = GetGeometry();
401
402 GfxContext.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER);
403- std::list<RenderArg>::iterator it;
404- for (it = last_args_.begin(); it != last_args_.end(); ++it)
405+
406+ for (auto const& arg : last_args_)
407 {
408- if (model_->Selection() == it->icon)
409+ if (text_view_->IsVisible() && model_->Selection() == arg.icon)
410 {
411 int view_width = text_view_->GetBaseWidth();
412- int start_x = it->render_center.x - view_width / 2;
413+ int start_x = arg.render_center.x - view_width / 2;
414
415 internal_clip.Expand (-10, -10);
416 if (start_x < internal_clip.x)
417@@ -575,12 +549,12 @@
418
419 text_view_->SetBaseX(start_x);
420 }
421- if (it->y_rotation < 0)
422- icon_renderer_->RenderIcon(GfxContext, *it, base, base);
423+
424+ if (arg.y_rotation < 0)
425+ icon_renderer_->RenderIcon(GfxContext, arg, base, base);
426 }
427
428- std::list<RenderArg>::reverse_iterator rit;
429- for (rit = last_args_.rbegin(); rit != last_args_.rend(); ++rit)
430+ for (auto rit = last_args_.rbegin(); rit != last_args_.rend(); ++rit)
431 {
432 if (rit->y_rotation >= 0)
433 icon_renderer_->RenderIcon(GfxContext, *rit, base, base);
434@@ -589,7 +563,7 @@
435 if (render_boxes)
436 {
437 float val = 0.1f;
438- for (LayoutWindow::Ptr layout : ExternalTargets())
439+ for (LayoutWindow::Ptr const& layout : ExternalTargets())
440 {
441 gPainter.Paint2DQuadColor(GfxContext, layout->result, nux::Color(val, val, val ,val));
442 val += 0.1f;
443@@ -598,36 +572,24 @@
444 val = 0.1f;
445 }
446
447- for (rit = last_args_.rbegin(); rit != last_args_.rend(); ++rit)
448+ for (auto rit = last_args_.rbegin(); rit != last_args_.rend(); ++rit)
449 {
450 nux::Geometry tmp (rit->render_center.x - 1, rit->render_center.y - 1, 2, 2);
451 gPainter.Paint2DQuadColor(GfxContext, tmp, nux::color::Red);
452 }
453 }
454
455- // render orange box that will encirlce active item(s)
456- for (LayoutWindow::Ptr window : ExternalTargets())
457+ if (text_view_->IsVisible())
458 {
459- nux::Geometry const& geo_absolute = GetAbsoluteGeometry();
460- if (window->alpha >= 1.0f)
461- {
462- nux::Geometry orange_box = window->result;
463- orange_box.Expand(5, 5);
464- orange_box.x -= geo_absolute.x;
465- orange_box.y -= geo_absolute.y;
466-
467- gPainter.PaintTextureShape(GfxContext, orange_box, rounding_texture_.GetPointer(), 6, 6, 6, 6, false);
468- }
469+ text_view_->SetBaseY(last_background_.y + last_background_.height - 45);
470+ text_view_->Draw(GfxContext, force_draw);
471 }
472
473- text_view_->SetBaseY(last_background_.y + last_background_.height - 45);
474- text_view_->Draw(GfxContext, force_draw);
475-
476 int ms_since_change = TimeUtil::TimeDelta(&current_, &save_time_);
477
478 if (ms_since_change < animation_length && !redraw_idle_)
479 {
480- redraw_idle_.reset(new glib::Idle([&] () {
481+ redraw_idle_.reset(new glib::Idle([this] () {
482 QueueDraw();
483 animation_draw_ = true;
484 redraw_idle_.reset();
485@@ -649,7 +611,7 @@
486 // implementation is enough.
487
488 int i = 0;
489- for (auto arg : last_args_)
490+ for (auto const& arg : last_args_)
491 {
492 if (x < (arg.logical_center.x - half_size)
493 || x > (arg.logical_center.x + half_size))
494
495=== modified file 'launcher/SwitcherView.h'
496--- launcher/SwitcherView.h 2012-11-06 18:19:09 +0000
497+++ launcher/SwitcherView.h 2012-11-15 18:52:31 +0000
498@@ -23,7 +23,7 @@
499 #include "SwitcherModel.h"
500 #include "unity-shared/AbstractIconRenderer.h"
501 #include "unity-shared/StaticCairoText.h"
502-#include "LayoutSystem.h"
503+#include "unity-shared/LayoutSystem.h"
504 #include "unity-shared/BackgroundEffectHelper.h"
505 #include "unity-shared/UnityWindowView.h"
506
507@@ -50,7 +50,7 @@
508
509 SwitcherView();
510
511- ui::LayoutWindowList ExternalTargets ();
512+ ui::LayoutWindow::Vector ExternalTargets();
513
514 void SetModel(SwitcherModel::Ptr model);
515 SwitcherModel::Ptr GetModel();
516@@ -109,13 +109,14 @@
517
518 void SaveLast ();
519
520- ui::LayoutSystem::Ptr layout_system_;
521+ SwitcherModel::Ptr model_;
522+ ui::LayoutSystem layout_system_;
523 ui::AbstractIconRenderer::Ptr icon_renderer_;
524- SwitcherModel::Ptr model_;
525+ nux::ObjectPtr<nux::StaticCairoText> text_view_;
526+
527+ bool animation_draw_;
528 bool target_sizes_set_;
529
530- nux::ObjectPtr<nux::BaseTexture> rounding_texture_;
531- nux::ObjectPtr<nux::StaticCairoText> text_view_;
532
533 std::list<ui::RenderArg> last_args_;
534 std::list<ui::RenderArg> saved_args_;
535@@ -123,13 +124,11 @@
536 nux::Geometry last_background_;
537 nux::Geometry saved_background_;
538
539- ui::LayoutWindowList render_targets_;
540+ ui::LayoutWindow::Vector render_targets_;
541
542 timespec current_;
543 timespec save_time_;
544
545- bool animation_draw_;
546-
547 glib::Source::UniquePtr redraw_idle_;
548 };
549
550
551=== modified file 'panel/PanelMenuView.cpp'
552--- panel/PanelMenuView.cpp 2012-11-12 16:23:54 +0000
553+++ panel/PanelMenuView.cpp 2012-11-15 18:52:31 +0000
554@@ -743,13 +743,6 @@
555 cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
556
557 gtk_style_context_save(style_context);
558-
559- GtkWidgetPath* widget_path = gtk_widget_path_new();
560- gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_BAR);
561- gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_ITEM);
562- gtk_widget_path_iter_set_name(widget_path, -1 , "UnityPanelWidget");
563-
564- gtk_style_context_set_path(style_context, widget_path);
565 gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR);
566 gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM);
567
568@@ -781,7 +774,6 @@
569
570 x += text_width;
571
572- gtk_widget_path_free(widget_path);
573 gtk_style_context_restore(style_context);
574 }
575
576@@ -1054,7 +1046,7 @@
577 // if we've just started tracking this window and it is maximized, let's
578 // make sure it's undecorated just in case it slipped by us earlier
579 // (I'm looking at you, Chromium!)
580- if (_is_maximized && wm.IsWindowDecorated(xid))
581+ if (_is_maximized && wm.HasWindowDecorations(xid))
582 {
583 wm.Undecorate(xid);
584 _maximized_set.insert(xid);
585@@ -1185,7 +1177,7 @@
586
587 // update the state of the window in the _decor_map
588 WindowManager& wm = WindowManager::Default();
589- _decor_map[xid] = wm.IsWindowDecorated(xid);
590+ _decor_map[xid] = wm.HasWindowDecorations(xid);
591
592 if (_decor_map[xid])
593 wm.Undecorate(xid);
594@@ -1659,7 +1651,7 @@
595 {
596 Window xid = bamf_window_get_xid(window);
597
598- _decor_map[xid] = wm.IsWindowDecorated(xid);
599+ _decor_map[xid] = wm.HasWindowDecorations(xid);
600
601 if (_decor_map[xid])
602 wm.Undecorate(xid);
603
604=== modified file 'plugins/unityshell/src/unityshell.cpp'
605--- plugins/unityshell/src/unityshell.cpp 2012-11-06 18:19:09 +0000
606+++ plugins/unityshell/src/unityshell.cpp 2012-11-15 18:52:31 +0000
607@@ -77,7 +77,6 @@
608 using launcher::AbstractLauncherIcon;
609 using launcher::Launcher;
610 using ui::LayoutWindow;
611-using ui::LayoutWindowList;
612 using util::Timer;
613
614 DECLARE_LOGGER(logger, "unity.shell.compiz");
615@@ -104,17 +103,17 @@
616 const std::string RELAYOUT_TIMEOUT = "relayout-timeout";
617 } // namespace local
618
619-namespace scale
620+namespace win
621 {
622 namespace decoration
623 {
624 const unsigned CLOSE_SIZE = 19;
625 const unsigned ITEMS_PADDING = 5;
626 const unsigned RADIUS = 8;
627-const unsigned GLOW = 30;
628+const unsigned GLOW = 5;
629 const nux::Color GLOW_COLOR(221, 72, 20);
630 } // decoration namespace
631-} // scale namespace
632+} // win namespace
633
634 } // anon namespace
635
636@@ -403,6 +402,10 @@
637 sigc::mem_fun(this, &UnityScreen::OnMinimizeDurationChanged)
638 );
639
640+ WindowManager& wm = WindowManager::Default();
641+ wm.initiate_spread.connect(sigc::mem_fun(this, &UnityScreen::OnInitiateSpread));
642+ wm.terminate_spread.connect(sigc::mem_fun(this, &UnityScreen::OnTerminateSpread));
643+
644 AddChild(&screen_introspection_);
645 }
646 }
647@@ -463,6 +466,22 @@
648
649 }
650
651+void UnityScreen::OnInitiateSpread()
652+{
653+ UnityWindow::SetupSharedTextures();
654+
655+ for (auto const& swin : ScaleScreen::get(screen)->getWindows())
656+ UnityWindow::get(swin->window)->OnInitiateSpread();
657+}
658+
659+void UnityScreen::OnTerminateSpread()
660+{
661+ for (auto const& swin : ScaleScreen::get(screen)->getWindows())
662+ UnityWindow::get(swin->window)->OnTerminateSpread();
663+
664+ UnityWindow::CleanupSharedTextures();
665+}
666+
667 void UnityScreen::EnsureSuperKeybindings()
668 {
669 for (auto action : _shortcut_actions)
670@@ -700,12 +719,12 @@
671 // Reload the windows themed textures
672 UnityWindow::CleanupSharedTextures();
673
674- if (WindowManager::Default().IsScaleActive())
675+ if (!fake_decorated_windows_.empty())
676 {
677 UnityWindow::SetupSharedTextures();
678
679- for (auto const& swin : ScaleScreen::get(screen)->getWindows())
680- UnityWindow::get(swin->window)->CleanupCachedTextures();
681+ for (UnityWindow* uwin : fake_decorated_windows_)
682+ uwin->CleanupCachedTextures();
683 }
684 }
685
686@@ -778,18 +797,18 @@
687 }
688 }
689
690- if (switcher_controller_->Visible ())
691+ if (switcher_controller_->Visible())
692 {
693- LayoutWindowList targets = switcher_controller_->ExternalRenderTargets ();
694+ LayoutWindow::Vector const& targets = switcher_controller_->ExternalRenderTargets();
695
696- for (LayoutWindow::Ptr target : targets)
697+ for (LayoutWindow::Ptr const& target : targets)
698 {
699- CompWindow* window = screen->findWindow(target->xid);
700- if (window)
701+ if (CompWindow* window = screen->findWindow(target->xid))
702 {
703- UnityWindow *unity_window = UnityWindow::get (window);
704-
705- unity_window->paintThumbnail (target->result, target->alpha);
706+ UnityWindow *unity_window = UnityWindow::get(window);
707+ double scale = target->result.width / static_cast<double>(target->geo.width);
708+ unity_window->paintThumbnail(target->result, target->alpha, scale,
709+ target->decoration_height, target->selected);
710 }
711 }
712 }
713@@ -853,28 +872,6 @@
714 && !fullscreen_windows_.empty () && (!(screen->grabbed () && !screen->otherGrabExist (NULL))));
715 }
716
717-void UnityWindow::paintThumbnail (nux::Geometry const& bounding, float alpha)
718-{
719- GLMatrix matrix;
720- matrix.toScreenSpace (UnityScreen::get (screen)->_last_output, -DEFAULT_Z_CAMERA);
721-
722- nux::Geometry geo = bounding;
723- last_bound = geo;
724-
725- GLWindowPaintAttrib attrib = gWindow->lastPaintAttrib ();
726- attrib.opacity = (GLushort) (alpha * G_MAXUSHORT);
727-
728- paintThumb (attrib,
729- matrix,
730- 0,
731- geo.x,
732- geo.y,
733- geo.width,
734- geo.height,
735- geo.width,
736- geo.height);
737-}
738-
739 void UnityScreen::EnableCancelAction(CancelActionTarget target, bool enabled, int modifiers)
740 {
741 if (enabled)
742@@ -1172,7 +1169,10 @@
743 }
744
745 if (old_state != close_icon_state_)
746- DoAddDamage();
747+ {
748+ auto const& g = close_button_geo_;
749+ cWindow->addDamageRect(CompRect(g.x, g.y, g.width, g.height));
750+ }
751 }
752 break;
753
754@@ -1181,7 +1181,8 @@
755 close_button_geo_.IsPointInside(event->xbutton.x_root, event->xbutton.y_root))
756 {
757 close_icon_state_ = panel::WindowState::PRESSED;
758- DoAddDamage();
759+ auto const& g = close_button_geo_;
760+ cWindow->addDamageRect(CompRect(g.x, g.y, g.width, g.height));
761 handled = true;
762 }
763 else if (event->xbutton.button == Button2 &&
764@@ -1199,7 +1200,8 @@
765 if (close_icon_state_ != panel::WindowState::NORMAL)
766 {
767 close_icon_state_ = panel::WindowState::NORMAL;
768- DoAddDamage();
769+ auto const& g = close_button_geo_;
770+ cWindow->addDamageRect(CompRect(g.x, g.y, g.width, g.height));
771 }
772
773 if (was_pressed)
774@@ -1424,6 +1426,7 @@
775 if (qm)
776 {
777 QuicklistView* view = qm->Current();
778+
779 if (view)
780 {
781 nux::Geometry const& geo = view->GetAbsoluteGeometry();
782@@ -1433,6 +1436,20 @@
783 view->QueueDraw();
784 }
785 }
786+
787+ if (switcher_controller_ && switcher_controller_->Visible())
788+ {
789+ unity::switcher::SwitcherView* view = switcher_controller_->GetView();
790+
791+ if (G_LIKELY(view))
792+ {
793+ nux::Geometry const& geo = view->GetAbsoluteGeometry();
794+ CompRegion switcher_region(geo.x, geo.y, geo.width, geo.height);
795+
796+ if (damage.intersects(switcher_region))
797+ view->QueueDraw();
798+ }
799+ }
800 }
801
802 /* Grab changed nux regions and add damage rects for them */
803@@ -1879,6 +1896,7 @@
804 show_mode = switcher::ShowMode::CURRENT_VIEWPORT;
805 }
806
807+ UnityWindow::SetupSharedTextures();
808 SetUpAndShowSwitcher(show_mode);
809
810 return true;
811@@ -2110,27 +2128,29 @@
812 void UnityScreen::OnSwitcherStart(GVariant* data)
813 {
814 if (switcher_controller_->Visible())
815+ {
816 SaveInputThenFocus(switcher_controller_->GetSwitcherInputWindowId());
817+ UnityWindow::SetupSharedTextures();
818+ }
819 }
820
821 void UnityScreen::OnSwitcherEnd(GVariant* data)
822 {
823 RestoreWindow(data);
824+ UnityWindow::CleanupSharedTextures();
825+
826+ for (UnityWindow* uwin : fake_decorated_windows_)
827+ uwin->CleanupCachedTextures();
828 }
829
830 void UnityScreen::RestoreWindow(GVariant* data)
831 {
832- bool preserve_focus = false;
833-
834- if (data)
835- {
836- preserve_focus = g_variant_get_boolean(data);
837- }
838+ bool preserve_focus = data ? g_variant_get_boolean(data) : false;
839
840 // Return input-focus to previously focused window (before key-nav-mode was
841 // entered)
842 if (preserve_focus)
843- PluginAdapter::Default().RestoreInputFocus ();
844+ PluginAdapter::Default().RestoreInputFocus();
845 }
846
847 bool UnityScreen::SaveInputThenFocus(const guint xid)
848@@ -2446,11 +2466,8 @@
849
850 if (WindowManager::Default().IsScaleActive() && ScaleScreen::get(screen)->getSelectedWindow() == window->id())
851 {
852- nux::Geometry scaled_geo = GetScaledGeometry();
853- int inside_glow = scale::decoration::RADIUS/4;
854- scaled_geo.Expand(-inside_glow, -inside_glow);
855- glow::Quads const& quads = computeGlowQuads(scaled_geo, glow_texture_, scale::decoration::GLOW);
856- paintGlow(matrix, attrib, region, quads, glow_texture_, scale::decoration::GLOW_COLOR, mask);
857+ nux::Geometry const& scaled_geo = GetScaledGeometry();
858+ paintInnerGlow(scaled_geo, matrix, attrib, mask);
859 }
860
861 return gWindow->glPaint(wAttrib, matrix, region, mask);
862@@ -2759,8 +2776,8 @@
863 nux::Point result(pos.x(), pos.y());
864
865 // seriously why does compiz not track monitors XRandR style???
866- auto monitors = UScreen::GetDefault()->GetMonitors();
867- for (auto monitor : monitors)
868+ auto const& monitors = UScreen::GetDefault()->GetMonitors();
869+ for (auto const& monitor : monitors)
870 {
871 if (monitor.IsInside(result))
872 {
873@@ -2769,12 +2786,13 @@
874 }
875 }
876
877- auto launchers = us->launcher_controller_->launchers();
878- for (auto launcher : launchers)
879+ auto const& launchers = us->launcher_controller_->launchers();
880+
881+ for (auto const& launcher : launchers)
882 {
883 nux::Geometry geo = launcher->GetAbsoluteGeometry();
884
885- if (launcher->Hidden() || launcher->options()->hide_mode == LAUNCHER_HIDE_NEVER || launcher->options()->hide_mode == LAUNCHER_HIDE_AUTOHIDE)
886+ if (launcher->options()->hide_mode == LAUNCHER_HIDE_AUTOHIDE && launcher->Hidden())
887 continue;
888
889 if (geo.IsInside(result))
890@@ -2786,7 +2804,7 @@
891 }
892 }
893
894- for (nux::Geometry &geo : us->panel_controller_->GetGeometries ())
895+ for (nux::Geometry const& geo : us->panel_controller_->GetGeometries())
896 {
897 if (geo.IsInside(result))
898 {
899@@ -3543,9 +3561,6 @@
900 }
901 }
902 }
903- WindowManager& wm = WindowManager::Default();
904- wm.initiate_spread.connect(sigc::mem_fun(this, &UnityWindow::OnInitiateSpread));
905- wm.terminate_spread.connect(sigc::mem_fun(this, &UnityWindow::OnTerminateSpread));
906 }
907
908
909@@ -3560,6 +3575,7 @@
910 .add(scaled ? GetScaledGeometry() : wm.GetWindowGeometry(xid))
911 .add("xid", xid)
912 .add("title", wm.GetWindowName(xid))
913+ .add("fake_decorated", uScreen->fake_decorated_windows_.find(this) != uScreen->fake_decorated_windows_.end())
914 .add("scaled", scaled)
915 .add("scaled_close_x", close_button_geo_.x)
916 .add("scaled_close_y", close_button_geo_.y)
917@@ -3618,7 +3634,7 @@
918 cairo_pop_group_to_source(context.cr_);
919
920 // Round window decoration top border
921- const double radius = scale::decoration::RADIUS * aspect;
922+ const double radius = win::decoration::RADIUS * aspect;
923
924 cairo_new_sub_path(context.cr_);
925 cairo_line_to(context.cr_, 0, context.h_);
926@@ -3653,6 +3669,7 @@
927 pango_layout_context_changed(layout);
928
929 decoration_title_ = WindowManager::Default().GetWindowName(window->id());
930+
931 pango_layout_set_height(layout, height);
932 pango_layout_set_width(layout, -1); //avoid wrap lines
933 pango_layout_set_auto_dir(layout, false);
934@@ -3663,13 +3680,6 @@
935
936 GtkStyleContext* style_context = style.GetStyleContext();
937 gtk_style_context_save(style_context);
938-
939- std::shared_ptr<GtkWidgetPath> widget_path(gtk_widget_path_new(), gtk_widget_path_free);
940- gtk_widget_path_append_type(widget_path.get(), GTK_TYPE_MENU_BAR);
941- gtk_widget_path_append_type(widget_path.get(), GTK_TYPE_MENU_ITEM);
942- gtk_widget_path_iter_set_name(widget_path.get(), -1 , "UnityPanelWidget");
943-
944- gtk_style_context_set_path(style_context, widget_path.get());
945 gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR);
946 gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM);
947
948@@ -3680,7 +3690,6 @@
949 int text_height = lRect.height / PANGO_SCALE;
950 int text_space = width - x;
951 y += (height - text_height) / 2.0f;
952-
953 if (text_width > text_space)
954 {
955 // Cut the text with fade
956@@ -3711,11 +3720,12 @@
957 if (decoration_tex_)
958 return;
959
960- auto const& border_extents = window->border();
961+ auto& wm = WindowManager::Default();
962+ auto const& deco_size = wm.GetWindowDecorationSize(window->id(), WindowManager::Edge::TOP);
963
964- if (WindowManager::Default().IsWindowDecorated(window->id()) && border_extents.top > 0)
965+ if (deco_size.height)
966 {
967- CairoContext context(window->borderRect().width(), window->border().top);
968+ CairoContext context(deco_size.width, deco_size.height);
969 RenderDecoration(context);
970 decoration_tex_ = context.pixmap_texture_;
971 }
972@@ -3733,7 +3743,7 @@
973 for (std::string const& file : files)
974 {
975 CompString file_name = file;
976- CompSize size(scale::decoration::CLOSE_SIZE, scale::decoration::CLOSE_SIZE);
977+ CompSize size(win::decoration::CLOSE_SIZE, win::decoration::CLOSE_SIZE);
978 texture = GLTexture::readImageToTexture(file_name, plugin, size);
979 if (!texture.empty())
980 break;
981@@ -3748,7 +3758,7 @@
982 suffix = "_pressed";
983
984 CompString file_name(PKGDATADIR"/close_dash" + suffix + ".png");
985- CompSize size(scale::decoration::CLOSE_SIZE, scale::decoration::CLOSE_SIZE);
986+ CompSize size(win::decoration::CLOSE_SIZE, win::decoration::CLOSE_SIZE);
987 texture = GLTexture::readImageToTexture(file_name, plugin, size);
988 }
989 }
990@@ -3781,30 +3791,8 @@
991 decoration_title_.clear();
992 }
993
994-void UnityWindow::scalePaintDecoration(GLWindowPaintAttrib const& attrib,
995- GLMatrix const& transform,
996- CompRegion const& region,
997- unsigned int mask)
998+void UnityWindow::paintFakeDecoration(nux::Geometry const& geo, GLWindowPaintAttrib const& attrib, GLMatrix const& transform, unsigned int mask, bool highlighted, double scale)
999 {
1000- ScaleWindow* scale_win = ScaleWindow::get(window);
1001- scale_win->scalePaintDecoration(attrib, transform, region, mask);
1002-
1003- if (!scale_win->hasSlot()) // animation not finished
1004- return;
1005-
1006- ScaleScreen* ss = ScaleScreen::get(screen);
1007- auto state = ss->getState();
1008-
1009- if (state != ScaleScreen::Wait && state != ScaleScreen::Out)
1010- return;
1011-
1012- auto const& scaled_geo = GetScaledGeometry();
1013- auto const& pos = scale_win->getCurrentPosition();
1014-
1015- const bool highlighted = (ss->getSelectedWindow() == window->id());
1016- int x = scaled_geo.x;
1017- int y = scaled_geo.y;
1018-
1019 mask |= PAINT_WINDOW_BLEND_MASK;
1020
1021 if (!highlighted)
1022@@ -3812,22 +3800,24 @@
1023 BuildDecorationTexture();
1024
1025 if (decoration_tex_)
1026- DrawTexture(decoration_tex_->texture_, attrib, transform, mask, x, y, pos.scale);
1027+ DrawTexture(decoration_tex_->texture_, attrib, transform, mask, geo.x, geo.y, scale);
1028
1029 close_button_geo_.Set(0, 0, 0, 0);
1030 }
1031 else
1032 {
1033- auto const& decoration_extents = window->border();
1034- unsigned width = scaled_geo.width;
1035- unsigned height = decoration_extents.top;
1036+ Window xid = window->id();
1037+ auto& wm = WindowManager::Default();
1038+ auto const& deco_top = wm.GetWindowDecorationSize(xid, WindowManager::Edge::TOP);
1039+ unsigned width = geo.width;
1040+ unsigned height = deco_top.height;
1041 bool redraw_decoration = true;
1042
1043 if (decoration_selected_tex_)
1044 {
1045 if (decoration_selected_tex_->w_ == width && decoration_selected_tex_->h_ == height)
1046 {
1047- if (decoration_title_ == WindowManager::Default().GetWindowName(window->id()))
1048+ if (decoration_title_ == wm.GetWindowName(xid))
1049 redraw_decoration = false;
1050 }
1051 }
1052@@ -3837,24 +3827,26 @@
1053 if (width != 0 && height != 0)
1054 {
1055 CairoContext context(width, height);
1056- RenderDecoration(context, pos.scale);
1057+ RenderDecoration(context, scale);
1058
1059 // Draw window title
1060- int text_x = scale::decoration::ITEMS_PADDING * 2 + scale::decoration::CLOSE_SIZE;
1061- RenderText(context, text_x, 0.0, width - scale::decoration::ITEMS_PADDING, height);
1062+ int text_x = win::decoration::ITEMS_PADDING * 2 + win::decoration::CLOSE_SIZE;
1063+ RenderText(context, text_x, 0.0, width - win::decoration::ITEMS_PADDING, height);
1064 decoration_selected_tex_ = context.pixmap_texture_;
1065+ uScreen->damageRegion(CompRegion(geo.x, geo.y, width, height));
1066 }
1067 else
1068 {
1069 decoration_selected_tex_.reset();
1070+ redraw_decoration = false;
1071 }
1072 }
1073
1074 if (decoration_selected_tex_)
1075- DrawTexture(decoration_selected_tex_->texture_, attrib, transform, mask, x, y);
1076+ DrawTexture(decoration_selected_tex_->texture_, attrib, transform, mask, geo.x, geo.y);
1077
1078- x += scale::decoration::ITEMS_PADDING;
1079- y += (height - scale::decoration::CLOSE_SIZE) / 2.0f;
1080+ int x = geo.x + win::decoration::ITEMS_PADDING;
1081+ int y = geo.y + (height - win::decoration::CLOSE_SIZE) / 2.0f;
1082
1083 switch (close_icon_state_)
1084 {
1085@@ -3872,8 +3864,34 @@
1086 break;
1087 }
1088
1089- close_button_geo_.Set(x, y, scale::decoration::CLOSE_SIZE, scale::decoration::CLOSE_SIZE);
1090+ close_button_geo_.Set(x, y, win::decoration::CLOSE_SIZE, win::decoration::CLOSE_SIZE);
1091 }
1092+
1093+ uScreen->fake_decorated_windows_.insert(this);
1094+}
1095+
1096+void UnityWindow::scalePaintDecoration(GLWindowPaintAttrib const& attrib,
1097+ GLMatrix const& transform,
1098+ CompRegion const& region,
1099+ unsigned int mask)
1100+{
1101+ ScaleWindow* scale_win = ScaleWindow::get(window);
1102+ scale_win->scalePaintDecoration(attrib, transform, region, mask);
1103+
1104+ if (!scale_win->hasSlot()) // animation not finished
1105+ return;
1106+
1107+ ScaleScreen* ss = ScaleScreen::get(screen);
1108+ auto state = ss->getState();
1109+
1110+ if (state != ScaleScreen::Wait && state != ScaleScreen::Out)
1111+ return;
1112+
1113+ auto const& scaled_geo = GetScaledGeometry();
1114+ auto const& pos = scale_win->getCurrentPosition();
1115+
1116+ bool highlighted = (ss->getSelectedWindow() == window->id());
1117+ paintFakeDecoration(scaled_geo, attrib, transform, mask, highlighted, pos.scale);
1118 }
1119
1120 nux::Geometry UnityWindow::GetScaledGeometry()
1121@@ -3884,10 +3902,10 @@
1122 auto const& border_rect = window->borderRect();
1123 auto const& deco_ext = window->border();
1124
1125- const unsigned width = std::floor(border_rect.width() * pos.scale);
1126- const unsigned height = std::floor(border_rect.height() * pos.scale);
1127- const int x = pos.x() + window->x() - std::floor(deco_ext.left * pos.scale);
1128- const int y = pos.y() + window->y() - std::floor(deco_ext.top * pos.scale);
1129+ const unsigned width = std::round(border_rect.width() * pos.scale);
1130+ const unsigned height = std::round(border_rect.height() * pos.scale);
1131+ const int x = pos.x() + window->x() - std::round(deco_ext.left * pos.scale);
1132+ const int y = pos.y() + window->y() - std::round(deco_ext.top * pos.scale);
1133
1134 return nux::Geometry(x, y, width, height);
1135 }
1136@@ -3896,12 +3914,11 @@
1137 {
1138 close_icon_state_ = panel::WindowState::NORMAL;
1139 middle_clicked_ = false;
1140- SetupSharedTextures();
1141
1142 WindowManager& wm = WindowManager::Default();
1143 Window xid = window->id();
1144
1145- if (wm.IsWindowDecorated(xid))
1146+ if (wm.HasWindowDecorations(xid))
1147 wm.Decorate(xid);
1148 }
1149
1150@@ -3910,17 +3927,65 @@
1151 WindowManager& wm = WindowManager::Default();
1152 Window xid = window->id();
1153
1154- if (wm.IsWindowDecorated(xid) && wm.IsWindowMaximized(xid))
1155+ if (wm.IsWindowMaximized(xid))
1156 wm.Undecorate(xid);
1157
1158 CleanupCachedTextures();
1159 }
1160
1161+void UnityWindow::paintInnerGlow(nux::Geometry glow_geo, GLMatrix const& matrix, GLWindowPaintAttrib const& attrib, unsigned mask)
1162+{
1163+ unsigned glow_size = win::decoration::GLOW;
1164+
1165+ if (!glow_size)
1166+ return;
1167+
1168+ if (win::decoration::RADIUS > 0)
1169+ {
1170+ // We paint the glow below the window edges to correctly
1171+ // render the rounded corners
1172+ glow_size += win::decoration::RADIUS;
1173+ int inside_glow = win::decoration::RADIUS / 4;
1174+ glow_geo.Expand(-inside_glow, -inside_glow);
1175+ }
1176+
1177+ glow::Quads const& quads = computeGlowQuads(glow_geo, glow_texture_, glow_size);
1178+ paintGlow(matrix, attrib, quads, glow_texture_, win::decoration::GLOW_COLOR, mask);
1179+}
1180+
1181+void UnityWindow::paintThumbnail(nux::Geometry const& geo, float alpha, float scale_ratio, unsigned deco_height, bool selected)
1182+{
1183+ GLMatrix matrix;
1184+ matrix.toScreenSpace(UnityScreen::get(screen)->_last_output, -DEFAULT_Z_CAMERA);
1185+ last_bound = geo;
1186+
1187+ GLWindowPaintAttrib attrib = gWindow->lastPaintAttrib();
1188+ attrib.opacity = (alpha * G_MAXUSHORT);
1189+ unsigned mask = gWindow->lastMask();
1190+ nux::Geometry thumb_geo = geo;
1191+
1192+ if (selected)
1193+ paintInnerGlow(thumb_geo, matrix, attrib, mask);
1194+
1195+ thumb_geo.y += std::round(deco_height * 0.5f * scale_ratio);
1196+ nux::Geometry const& g = thumb_geo;
1197+
1198+ paintThumb(attrib, matrix, mask, g.x, g.y, g.width, g.height, g.width, g.height);
1199+
1200+ mask |= PAINT_WINDOW_BLEND_MASK;
1201+ attrib.opacity = OPAQUE;
1202+
1203+ // The thumbnail is still animating, don't draw the decoration as selected
1204+ if (selected && alpha < 1.0f)
1205+ selected = false;
1206+
1207+ paintFakeDecoration(geo, attrib, matrix, mask, selected, scale_ratio);
1208+}
1209+
1210 UnityWindow::~UnityWindow()
1211 {
1212- UnityScreen* us = UnityScreen::get(screen);
1213- if (us->newFocusedWindow && (UnityWindow::get(us->newFocusedWindow) == this))
1214- us->newFocusedWindow = NULL;
1215+ if (uScreen->newFocusedWindow && UnityWindow::get(uScreen->newFocusedWindow) == this)
1216+ uScreen->newFocusedWindow = NULL;
1217
1218 if (!window->destroyed ())
1219 {
1220@@ -3937,8 +4002,9 @@
1221 ShowdesktopHandler::animating_windows.remove (static_cast <ShowdesktopHandlerWindowInterface *> (this));
1222
1223 if (window->state () & CompWindowStateFullscreenMask)
1224- UnityScreen::get (screen)->fullscreen_windows_.remove(window);
1225+ uScreen->fullscreen_windows_.remove(window);
1226
1227+ uScreen->fake_decorated_windows_.erase(this);
1228 PluginAdapter::Default().OnWindowClosed(window);
1229 }
1230
1231@@ -4045,7 +4111,7 @@
1232 gfloat version = 0.0f;
1233 gint32 i;
1234
1235- for (i = 0; isdigit(version_string[i]); i++)
1236+ for (i = 0; isdigit(version_string[i]); ++i)
1237 version = version * 10.0f + (version_string[i] - 48);
1238
1239 if ((version_string[i] == '.' || version_string[i] == ',') &&
1240
1241=== modified file 'plugins/unityshell/src/unityshell.h'
1242--- plugins/unityshell/src/unityshell.h 2012-11-06 18:19:09 +0000
1243+++ plugins/unityshell/src/unityshell.h 2012-11-15 18:52:31 +0000
1244@@ -68,6 +68,7 @@
1245
1246 namespace unity
1247 {
1248+class UnityWindow;
1249
1250 /* base screen class */
1251 class UnityScreen :
1252@@ -233,6 +234,9 @@
1253 void OnSwitcherStart(GVariant* data);
1254 void OnSwitcherEnd(GVariant* data);
1255
1256+ void OnInitiateSpread();
1257+ void OnTerminateSpread();
1258+
1259 void RestoreWindow(GVariant* data);
1260 bool SaveInputThenFocus(const guint xid);
1261
1262@@ -328,6 +332,7 @@
1263 bool panel_texture_has_changed_;
1264 bool paint_panel_;
1265 nux::ObjectPtr<nux::IOpenGLBaseTexture> panel_texture_;
1266+ std::set<UnityWindow*> fake_decorated_windows_;
1267
1268 bool scale_just_activated_;
1269 WindowMinimizeSpeedController minimize_speed_controller_;
1270@@ -387,7 +392,7 @@
1271 CompPoint tryNotIntersectUI(CompPoint& pos);
1272 nux::Geometry GetScaledGeometry();
1273
1274- void paintThumbnail(nux::Geometry const& bounding, float alpha);
1275+ void paintThumbnail(nux::Geometry const& bounding, float alpha, float scale_ratio, unsigned deco_height, bool selected);
1276
1277 void enterShowDesktop();
1278 void leaveShowDesktop();
1279@@ -449,9 +454,11 @@
1280 void DrawTexture(GLTexture::List const& textures, GLWindowPaintAttrib const&,
1281 GLMatrix const&, unsigned mask, int x, int y, double aspect = 1.0f);
1282
1283+ void paintFakeDecoration(nux::Geometry const& geo, GLWindowPaintAttrib const& attrib, GLMatrix const& transform, unsigned int mask, bool highlighted, double scale);
1284+ void paintInnerGlow(nux::Geometry glow_geo, GLMatrix const&, GLWindowPaintAttrib const&, unsigned mask);
1285 glow::Quads computeGlowQuads(nux::Geometry const& geo, GLTexture::List const& texture, int glow_size);
1286- void paintGlow(GLMatrix const&, GLWindowPaintAttrib const&, CompRegion const&,
1287- glow::Quads const&, GLTexture::List const&, nux::Color const&, unsigned mask);
1288+ void paintGlow(GLMatrix const&, GLWindowPaintAttrib const&, glow::Quads const&,
1289+ GLTexture::List const&, nux::Color const&, unsigned mask);
1290
1291 void BuildDecorationTexture();
1292 void CleanupCachedTextures();
1293
1294=== modified file 'plugins/unityshell/src/unityshell_glow.cpp'
1295--- plugins/unityshell/src/unityshell_glow.cpp 2012-10-05 14:32:39 +0000
1296+++ plugins/unityshell/src/unityshell_glow.cpp 2012-11-15 18:52:31 +0000
1297@@ -39,9 +39,8 @@
1298
1299 void
1300 UnityWindow::paintGlow(GLMatrix const& transform, GLWindowPaintAttrib const& attrib,
1301- CompRegion const& paintRegion, glow::Quads const& glow_quads,
1302- GLTexture::List const& outline_texture, nux::Color const& color,
1303- unsigned mask)
1304+ glow::Quads const& glow_quads, GLTexture::List const& outline_texture,
1305+ nux::Color const& color, unsigned mask)
1306 {
1307 GLushort colorData[4];
1308 colorData[0] = color.red * 0xffff;
1309@@ -144,6 +143,7 @@
1310 CompRect *box;
1311 GLTexture::Matrix *quadMatrix;
1312
1313+ glow_size = glow_size * texture::GLOW_SIZE / (texture::GLOW_SIZE - texture::GLOW_OFFSET);
1314 glow_offset = (glow_size * texture::GLOW_OFFSET / texture::GLOW_SIZE) + 1;
1315
1316 /* Top left corner */
1317
1318=== removed file 'resources/switcher_round_rect.png'
1319Binary files resources/switcher_round_rect.png 2011-09-22 15:00:17 +0000 and resources/switcher_round_rect.png 1970-01-01 00:00:00 +0000 differ
1320=== modified file 'tests/CMakeLists.txt'
1321--- tests/CMakeLists.txt 2012-11-13 23:03:47 +0000
1322+++ tests/CMakeLists.txt 2012-11-15 18:52:31 +0000
1323@@ -136,6 +136,7 @@
1324 test_favorite_store_private.cpp
1325 test_home_lens.cpp
1326 test_launcher_entry_remote.cpp
1327+ test_layout_system.cpp
1328 test_model_iterator.cpp
1329 test_previews.cpp
1330 test_ubus.cpp
1331@@ -152,6 +153,7 @@
1332 set (GTEST_XLESS_LIBS
1333 gtest
1334 unity-shared
1335+ unity-shared-standalone
1336 launcher-lib
1337 ${GMOCK_LIB}
1338 ${GMOCK_MAIN_LIB}
1339
1340=== modified file 'tests/autopilot/unity/emulators/screen.py'
1341--- tests/autopilot/unity/emulators/screen.py 2012-11-06 18:19:09 +0000
1342+++ tests/autopilot/unity/emulators/screen.py 2012-11-15 18:52:31 +0000
1343@@ -27,6 +27,14 @@
1344 """Return the available scaled windows, or None."""
1345 return self.get_children_by_type(Window, scaled=True)
1346
1347+ def window(self, xid):
1348+ """Return the window with given xid."""
1349+ windows = self.get_children_by_type(Window, xid=xid)
1350+ if len(windows):
1351+ return windows[0]
1352+
1353+ return None
1354+
1355
1356 class Window(UnityIntrospectionObject):
1357 """An individual window."""
1358
1359=== modified file 'tests/autopilot/unity/emulators/switcher.py'
1360--- tests/autopilot/unity/emulators/switcher.py 2012-07-10 20:41:57 +0000
1361+++ tests/autopilot/unity/emulators/switcher.py 2012-11-15 18:52:31 +0000
1362@@ -72,6 +72,16 @@
1363 return self.controller.model.selection_index
1364
1365 @property
1366+ def label(self):
1367+ """The current switcher label"""
1368+ return self.controller.view.label
1369+
1370+ @property
1371+ def label_visible(self):
1372+ """The switcher label visibility"""
1373+ return self.controller.view.label_visible
1374+
1375+ @property
1376 def mode(self):
1377 """Returns the SwitcherMode that the switcher is currently in."""
1378 if not self.visible:
1379@@ -126,7 +136,7 @@
1380 If no icon matches, a ValueError will be raised.
1381
1382 """
1383- if self.mode != SwitcherMode.NORMAL:
1384+ if self.mode == SwitcherMode.DETAIL:
1385 raise RuntimeError("Switcher must be initiated in normal mode before calling this method.")
1386
1387 if direction not in (self.DIRECTION_BACKWARDS, self.DIRECTION_FORWARDS):
1388
1389=== modified file 'tests/autopilot/unity/tests/test_switcher.py'
1390--- tests/autopilot/unity/tests/test_switcher.py 2012-11-06 18:19:09 +0000
1391+++ tests/autopilot/unity/tests/test_switcher.py 2012-11-15 18:52:31 +0000
1392@@ -14,7 +14,7 @@
1393 from testtools.matchers import Equals, Contains, Not
1394 from time import sleep
1395
1396-from unity.emulators.switcher import SwitcherMode
1397+from unity.emulators.switcher import Switcher, SwitcherMode
1398 from unity.tests import UnityTestCase
1399
1400 logger = logging.getLogger(__name__)
1401@@ -75,7 +75,7 @@
1402 def tearDown(self):
1403 super(SwitcherTests, self).tearDown()
1404
1405- def test_witcher_starts_in_normal_mode(self):
1406+ def test_switcher_starts_in_normal_mode(self):
1407 """Switcher must start in normal (i.e.- not details) mode."""
1408 self.start_app("Character Map")
1409
1410@@ -83,15 +83,38 @@
1411 self.addCleanup(self.switcher.terminate)
1412 self.assertProperty(self.switcher, mode=SwitcherMode.NORMAL)
1413
1414- def test_first_detail_mode_has_correct_label(self):
1415- """Starting switcher in details mode must show the focused window title."""
1416- window = self.start_app_window("Text Editor")
1417- title = window.title
1418-
1419+ def test_label_matches_application_name(self):
1420+ """The switcher label must match the selected application name in normal mode."""
1421+ windows = self.start_applications()
1422+ self.switcher.initiate()
1423+ self.addCleanup(self.switcher.terminate)
1424+
1425+ for win in windows:
1426+ app_name = win.application.name
1427+ self.switcher.select_icon(Switcher.DIRECTION_FORWARDS, tooltip_text=app_name)
1428+ self.assertThat(self.switcher.label_visible, Eventually(Equals(True)))
1429+ self.assertThat(self.switcher.label, Eventually(Equals(app_name)))
1430+
1431+ def test_application_window_is_fake_decorated(self):
1432+ """When the switcher is in details mode must not show the focused window title."""
1433+ window = self.start_app_window("Text Editor")
1434+ self.switcher.initiate()
1435+ self.addCleanup(self.switcher.terminate)
1436+
1437+ self.switcher.select_icon(Switcher.DIRECTION_BACKWARDS, tooltip_text=window.application.name)
1438+
1439+ self.switcher.show_details()
1440+ self.assertThat(self.switcher.label_visible, Eventually(Equals(False)))
1441+ self.assertThat(self.screen.window(window.x_id).fake_decorated, Eventually(Equals(True)))
1442+
1443+ def test_application_window_is_fake_decorated_in_detail_mode(self):
1444+ """Starting switcher in details mode must not show the focused window title."""
1445+ window = self.start_app_window("Text Editor")
1446 self.switcher.initiate(SwitcherMode.DETAIL)
1447 self.addCleanup(self.switcher.terminate)
1448
1449- self.assertThat(self.switcher.controller.view.label, Eventually(Equals(title)))
1450+ self.assertThat(self.switcher.label_visible, Eventually(Equals(False)))
1451+ self.assertThat(self.screen.window(window.x_id).fake_decorated, Eventually(Equals(True)))
1452
1453 def test_switcher_move_next(self):
1454 """Test that pressing the next icon binding moves to the next icon"""
1455
1456=== added file 'tests/test_layout_system.cpp'
1457--- tests/test_layout_system.cpp 1970-01-01 00:00:00 +0000
1458+++ tests/test_layout_system.cpp 2012-11-15 18:52:31 +0000
1459@@ -0,0 +1,158 @@
1460+/*
1461+ * Copyright 2012 Canonical Ltd.
1462+ *
1463+ * This program is free software: you can redistribute it and/or modify it
1464+ * under the terms of the GNU General Public License version 3, as published
1465+ * by the Free Software Foundation.
1466+ *
1467+ * This program is distributed in the hope that it will be useful, but
1468+ * WITHOUT ANY WARRANTY; without even the implied warranties of
1469+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
1470+ * PURPOSE. See the GNU General Public License for more details.
1471+ *
1472+ * You should have received a copy of the GNU General Public License
1473+ * version 3 along with this program. If not, see
1474+ * <http://www.gnu.org/licenses/>
1475+ *
1476+ * Authored by: Marco Trevisan (Treviño) <marco.trevisan@canonical.com>
1477+ */
1478+
1479+#include <gmock/gmock.h>
1480+#include "LayoutSystem.h"
1481+#include "StandaloneWindowManager.h"
1482+
1483+namespace unity
1484+{
1485+namespace ui
1486+{
1487+namespace
1488+{
1489+StandaloneWindowManager* wm = nullptr;
1490+
1491+StandaloneWindow::Ptr AddFakeWindowToWM(Window xid, nux::Geometry const& geo = nux::Geometry(1, 2, 30, 40))
1492+{
1493+ const unsigned top_deco = 5;
1494+ auto fake_window = std::make_shared<StandaloneWindow>(xid);
1495+ fake_window->geo = geo;
1496+ fake_window->deco_sizes[unsigned(WindowManager::Edge::TOP)] = nux::Size(geo.width, top_deco);
1497+
1498+ if (!wm)
1499+ wm = dynamic_cast<StandaloneWindowManager*>(&WindowManager::Default());
1500+
1501+ wm->AddStandaloneWindow(fake_window);
1502+
1503+ return fake_window;
1504+}
1505+
1506+TEST(TestLayoutWindow, InitializationNormalWindow)
1507+{
1508+ const Window xid = g_random_int();
1509+ auto fake_window = AddFakeWindowToWM(xid);
1510+
1511+ LayoutWindow lwin(xid);
1512+ EXPECT_EQ(lwin.xid, xid);
1513+ EXPECT_EQ(lwin.geo, fake_window->geo);
1514+ EXPECT_EQ(lwin.decoration_height, 0);
1515+ EXPECT_EQ(lwin.selected, false);
1516+ EXPECT_EQ(lwin.aspect_ratio, fake_window->geo.width / static_cast<float>(fake_window->geo.height));
1517+}
1518+
1519+TEST(TestLayoutWindow, InitializationMinimizedNormalWindow)
1520+{
1521+ const Window xid = g_random_int();
1522+ auto fake_window = AddFakeWindowToWM(xid);
1523+ wm->Minimize(xid);
1524+
1525+ LayoutWindow lwin(xid);
1526+ EXPECT_EQ(lwin.xid, xid);
1527+ EXPECT_EQ(lwin.geo, fake_window->geo);
1528+ EXPECT_EQ(lwin.decoration_height, 0);
1529+ EXPECT_EQ(lwin.selected, false);
1530+ EXPECT_EQ(lwin.aspect_ratio, fake_window->geo.width / static_cast<float>(fake_window->geo.height));
1531+}
1532+
1533+TEST(TestLayoutWindow, InitializationMaximizedWindow)
1534+{
1535+ const Window xid = g_random_int();
1536+ auto fake_window = AddFakeWindowToWM(xid);
1537+ wm->Maximize(xid);
1538+
1539+ nux::Geometry expected_geo(fake_window->geo);
1540+ unsigned top_deco = wm->GetWindowDecorationSize(xid, WindowManager::Edge::TOP).height;
1541+ expected_geo.height += top_deco;
1542+
1543+ LayoutWindow lwin(xid);
1544+ EXPECT_EQ(lwin.xid, xid);
1545+ EXPECT_EQ(lwin.geo, expected_geo);
1546+ EXPECT_EQ(lwin.decoration_height, top_deco);
1547+ EXPECT_EQ(lwin.selected, false);
1548+ EXPECT_EQ(lwin.aspect_ratio, expected_geo.width / static_cast<float>(expected_geo.height));
1549+}
1550+
1551+TEST(TestLayoutWindow, InitializationMinimizedMaximizedWindow)
1552+{
1553+ const Window xid = g_random_int();
1554+ auto fake_window = AddFakeWindowToWM(xid);
1555+ wm->Maximize(xid);
1556+ wm->Minimize(xid);
1557+
1558+ LayoutWindow lwin(xid);
1559+ EXPECT_EQ(lwin.xid, xid);
1560+ EXPECT_EQ(lwin.geo, fake_window->geo);
1561+ EXPECT_EQ(lwin.decoration_height, 0);
1562+ EXPECT_EQ(lwin.selected, false);
1563+ EXPECT_EQ(lwin.aspect_ratio, fake_window->geo.width / static_cast<float>(fake_window->geo.height));
1564+}
1565+
1566+struct TestLayoutSystem : testing::Test
1567+{
1568+ TestLayoutSystem()
1569+ {
1570+ Window xid = 1;
1571+ AddFakeWindowToWM(xid, nux::Geometry(4, 5, 500, 600));
1572+ lwindows.push_back(std::make_shared<LayoutWindow>(xid));
1573+
1574+ xid = 2;
1575+ AddFakeWindowToWM(xid, nux::Geometry(10, 20, 800, 300));
1576+ lwindows.push_back(std::make_shared<LayoutWindow>(xid));
1577+ }
1578+
1579+ LayoutSystem ls;
1580+ LayoutWindow::Vector lwindows;
1581+};
1582+
1583+TEST_F(TestLayoutSystem, Initialization)
1584+{
1585+ EXPECT_EQ(ls.spacing, 8);
1586+ EXPECT_EQ(ls.max_row_height, 400);
1587+}
1588+
1589+TEST_F(TestLayoutSystem, LayoutWindows)
1590+{
1591+ nux::Geometry max_bounds(0, 0, 200, 100);
1592+ nux::Geometry final_bounds;
1593+ ls.LayoutWindows(lwindows, max_bounds, final_bounds);
1594+
1595+ nux::Geometry const& win_new_geo1 = lwindows.at(0)->result;
1596+ nux::Geometry const& win_new_geo2 = lwindows.at(1)->result;
1597+
1598+ EXPECT_EQ(max_bounds.Intersect(final_bounds), final_bounds);
1599+ EXPECT_NE(lwindows.at(0)->geo, win_new_geo1);
1600+ EXPECT_NE(lwindows.at(1)->geo, win_new_geo1);
1601+
1602+ // Computing the area occupied by the grouped windows
1603+ unsigned min_start_x = std::min(win_new_geo1.x, win_new_geo2.x);
1604+ unsigned min_start_y = std::min(win_new_geo1.y, win_new_geo2.y);
1605+ unsigned max_last_x = std::max(win_new_geo1.x + win_new_geo1.width,
1606+ win_new_geo2.x + win_new_geo2.width);
1607+ unsigned max_last_y = std::max(win_new_geo1.y + win_new_geo1.height,
1608+ win_new_geo2.y + win_new_geo2.height);
1609+
1610+ nux::Geometry windows_area(min_start_x, min_start_y, max_last_x - min_start_x, max_last_y - min_start_y);
1611+
1612+ EXPECT_EQ(final_bounds.Intersect(windows_area), windows_area);
1613+}
1614+
1615+}
1616+}
1617+}
1618
1619=== modified file 'tests/test_main.cpp'
1620--- tests/test_main.cpp 2012-11-06 18:19:09 +0000
1621+++ tests/test_main.cpp 2012-11-15 18:52:31 +0000
1622@@ -4,8 +4,6 @@
1623 #include <NuxCore/Logger.h>
1624 #include <Nux/Nux.h>
1625
1626-#include "unity-shared/WindowManager.h"
1627-
1628 int main(int argc, char** argv)
1629 {
1630 ::testing::InitGoogleTest(&argc, argv);
1631
1632=== modified file 'unity-shared/AbstractIconRenderer.h'
1633--- unity-shared/AbstractIconRenderer.h 2012-05-07 00:49:31 +0000
1634+++ unity-shared/AbstractIconRenderer.h 2012-11-15 18:52:31 +0000
1635@@ -21,7 +21,6 @@
1636 #define ABSTRACTICONRENDERER_H
1637
1638 #include <Nux/Nux.h>
1639-#include <boost/shared_ptr.hpp>
1640
1641 #include "IconTextureSource.h"
1642
1643@@ -102,7 +101,7 @@
1644 class AbstractIconRenderer
1645 {
1646 public:
1647- typedef boost::shared_ptr<AbstractIconRenderer> Ptr;
1648+ typedef std::shared_ptr<AbstractIconRenderer> Ptr;
1649
1650 virtual ~AbstractIconRenderer() {}
1651
1652
1653=== modified file 'unity-shared/CMakeLists.txt'
1654--- unity-shared/CMakeLists.txt 2012-11-13 22:39:49 +0000
1655+++ unity-shared/CMakeLists.txt 2012-11-15 18:52:31 +0000
1656@@ -44,6 +44,7 @@
1657 Introspectable.cpp
1658 IntrospectableWrappers.cpp
1659 JSONParser.cpp
1660+ LayoutSystem.cpp
1661 LineSeparator.cpp
1662 OverlayRenderer.cpp
1663 PanelStyle.cpp
1664
1665=== renamed file 'launcher/LayoutSystem.cpp' => 'unity-shared/LayoutSystem.cpp'
1666--- launcher/LayoutSystem.cpp 2012-10-11 01:44:15 +0000
1667+++ unity-shared/LayoutSystem.cpp 2012-11-15 18:52:31 +0000
1668@@ -23,40 +23,24 @@
1669 namespace ui {
1670
1671 LayoutSystem::LayoutSystem()
1672-{
1673- spacing = 8;
1674- max_row_height = 400;
1675-}
1676-
1677-LayoutSystem::~LayoutSystem()
1678-{
1679-}
1680-
1681-void LayoutSystem::LayoutWindows(LayoutWindowList windows,
1682- nux::Geometry const& max_bounds,
1683- nux::Geometry& final_bounds)
1684-{
1685- unsigned int size = windows.size();
1686-
1687- if (size == 0)
1688+ : spacing(8)
1689+ , max_row_height(400)
1690+{}
1691+
1692+void LayoutSystem::LayoutWindows(LayoutWindow::Vector const& windows, nux::Geometry const& max_bounds, nux::Geometry& final_bounds)
1693+{
1694+ if (windows.empty())
1695 return;
1696
1697- WindowManager& wm = WindowManager::Default();
1698- for (auto window : windows)
1699- {
1700- window->geo = wm.GetWindowGeometry(window->xid);
1701- window->aspect_ratio = (float)window->geo.width / (float)window->geo.height;
1702- }
1703-
1704 LayoutGridWindows(windows, max_bounds, final_bounds);
1705 }
1706
1707-nux::Size LayoutSystem::GridSizeForWindows(LayoutWindowList windows, nux::Geometry const& max_bounds)
1708+nux::Size LayoutSystem::GridSizeForWindows(LayoutWindow::Vector const& windows, nux::Geometry const& max_bounds)
1709 {
1710- int count = (int)windows.size();
1711+ unsigned count = windows.size();
1712
1713- int width = 1;
1714- int height = 1;
1715+ unsigned width = 1;
1716+ unsigned height = 1;
1717
1718 if (count == 2)
1719 {
1720@@ -83,14 +67,14 @@
1721 }
1722 }
1723
1724- return nux::Size (width, height);
1725+ return nux::Size(width, height);
1726 }
1727
1728-nux::Geometry LayoutSystem::CompressAndPadRow (LayoutWindowList const& windows, nux::Geometry const& max_bounds)
1729+nux::Geometry LayoutSystem::CompressAndPadRow(LayoutWindow::Vector const& windows, nux::Geometry const& max_bounds)
1730 {
1731 int total_width = 0;
1732 int max_height = 0;
1733- for (LayoutWindow::Ptr window : windows)
1734+ for (LayoutWindow::Ptr const& window : windows)
1735 {
1736 window->result.x = total_width;
1737 total_width += spacing + window->result.width;
1738@@ -99,17 +83,17 @@
1739
1740 total_width -= spacing;
1741
1742- int x1 = G_MAXINT;
1743- int y1 = G_MAXINT;
1744- int x2 = G_MININT;
1745- int y2 = G_MININT;
1746+ int x1 = std::numeric_limits<int>::max();
1747+ int y1 = std::numeric_limits<int>::max();
1748+ int x2 = std::numeric_limits<int>::min();
1749+ int y2 = std::numeric_limits<int>::min();
1750
1751 int offset = std::max (0, (max_bounds.width - total_width) / 2);
1752- for (LayoutWindow::Ptr window : windows)
1753+ for (LayoutWindow::Ptr const& window : windows)
1754 {
1755 window->result.x += max_bounds.x + offset;
1756 window->result.y = max_bounds.y + (max_height - window->result.height) / 2;
1757-
1758+
1759 x1 = std::min (window->result.x, x1);
1760 y1 = std::min (window->result.y, y1);
1761 x2 = std::max (window->result.x + window->result.width, x2);
1762@@ -119,13 +103,13 @@
1763 return nux::Geometry (x1, y1, x2 - x1, y2 - y1);
1764 }
1765
1766-nux::Geometry LayoutSystem::LayoutRow (LayoutWindowList const& row, nux::Geometry const& row_bounds)
1767+nux::Geometry LayoutSystem::LayoutRow(LayoutWindow::Vector const& row, nux::Geometry const& row_bounds)
1768 {
1769 nux::Geometry unpadded_bounds = row_bounds;
1770 unpadded_bounds.width -= spacing * (row.size () - 1);
1771
1772 int combined_width = 0;
1773- for (LayoutWindow::Ptr window : row)
1774+ for (LayoutWindow::Ptr const& window : row)
1775 {
1776 float scalar = unpadded_bounds.height / (float)window->geo.height;
1777 combined_width += window->geo.width * scalar;
1778@@ -138,11 +122,11 @@
1779
1780 // precision of X,Y is relatively unimportant as the Compression stage will fix any issues, sizing
1781 // is however set at this point.
1782- for (LayoutWindow::Ptr window : row)
1783+ for (LayoutWindow::Ptr const& window : row)
1784 {
1785 // we dont allow scaling up
1786- float final_scalar = std::min (1.0f, (unpadded_bounds.height / (float)window->geo.height) * global_scalar);
1787-
1788+ float final_scalar = std::min(1.0f, (unpadded_bounds.height / (float)window->geo.height) * global_scalar);
1789+
1790 window->result.x = x;
1791 window->result.y = y;
1792 window->result.width = window->geo.width * final_scalar;
1793@@ -154,14 +138,14 @@
1794 return CompressAndPadRow (row, row_bounds);
1795 }
1796
1797-std::vector<LayoutWindowList> LayoutSystem::GetRows (LayoutWindowList const& windows, nux::Geometry const& max_bounds)
1798+std::vector<LayoutWindow::Vector> LayoutSystem::GetRows(LayoutWindow::Vector const& windows, nux::Geometry const& max_bounds)
1799 {
1800- std::vector<LayoutWindowList> rows;
1801+ std::vector<LayoutWindow::Vector> rows;
1802
1803 int size = (int)windows.size();
1804
1805 float total_aspect = 0;
1806- for (LayoutWindow::Ptr window : windows)
1807+ for (LayoutWindow::Ptr const& window : windows)
1808 {
1809 total_aspect += window->aspect_ratio;
1810 }
1811@@ -173,7 +157,7 @@
1812 }
1813 else
1814 {
1815- nux::Size grid_size = GridSizeForWindows (windows, max_bounds);
1816+ nux::Size const& grid_size = GridSizeForWindows(windows, max_bounds);
1817
1818 int width = grid_size.width;
1819 int height = grid_size.height;
1820@@ -188,7 +172,7 @@
1821
1822 float row_aspect = 0.0f;
1823
1824- LayoutWindowList row_accum;
1825+ LayoutWindow::Vector row_accum;
1826
1827 int i;
1828 for (i = 0; i < size; ++i)
1829@@ -234,33 +218,34 @@
1830 return rows;
1831 }
1832
1833-void LayoutSystem::LayoutGridWindows (LayoutWindowList const& windows, nux::Geometry const& max_bounds, nux::Geometry& final_bounds)
1834+void LayoutSystem::LayoutGridWindows(LayoutWindow::Vector const& windows, nux::Geometry const& max_bounds, nux::Geometry& final_bounds)
1835 {
1836- std::vector<LayoutWindowList> rows = GetRows(windows, max_bounds);
1837-
1838+ std::vector<LayoutWindow::Vector> const& rows = GetRows(windows, max_bounds);
1839+
1840 int height = rows.size();
1841 int non_spacing_height = max_bounds.height - ((height - 1) * spacing);
1842 int row_height = std::min (max_row_height(), non_spacing_height / height);
1843 int start_y = max_bounds.y;
1844 int low_y = 0;
1845
1846- for (LayoutWindowList row : rows)
1847+ for (LayoutWindow::Vector const& row : rows)
1848 {
1849- nux::Geometry row_max_bounds (max_bounds.x, start_y, max_bounds.width, row_height);
1850- nux::Geometry row_final_bounds = LayoutRow (row, row_max_bounds);
1851+ nux::Geometry row_max_bounds(max_bounds.x, start_y, max_bounds.width, row_height);
1852+ nux::Geometry const& row_final_bounds = LayoutRow(row, row_max_bounds);
1853
1854 low_y = row_final_bounds.y + row_final_bounds.height;
1855
1856 start_y += row_final_bounds.height + spacing;
1857 }
1858
1859- int x1 = G_MAXINT;
1860- int y1 = G_MAXINT;
1861- int x2 = G_MININT;
1862- int y2 = G_MININT;
1863+ int x1 = std::numeric_limits<int>::max();
1864+ int y1 = std::numeric_limits<int>::max();
1865+ int x2 = std::numeric_limits<int>::min();
1866+ int y2 = std::numeric_limits<int>::min();
1867
1868 int offset = (max_bounds.height - (low_y - max_bounds.y)) / 2;
1869- for (auto window : windows)
1870+
1871+ for (auto const& window : windows)
1872 {
1873 window->result.y += offset;
1874
1875@@ -274,9 +259,23 @@
1876 }
1877
1878 LayoutWindow::LayoutWindow(Window xid)
1879- : xid (xid)
1880+ : xid(xid)
1881+ , geo(WindowManager::Default().GetWindowGeometry(xid))
1882+ , decoration_height(0)
1883+ , selected(false)
1884+ , aspect_ratio(geo.width / static_cast<float>(geo.height))
1885 {
1886+ auto& wm = WindowManager::Default();
1887
1888+ if (wm.IsWindowMaximized(xid) && !wm.IsWindowMinimized(xid))
1889+ {
1890+ // Maximized windows are not decorated, so we define an extra decoration
1891+ // height to be used to correctly render the window with a fake decoration
1892+ auto const& deco_size = wm.GetWindowDecorationSize(xid, WindowManager::Edge::TOP);
1893+ decoration_height = deco_size.height;
1894+ geo.height += decoration_height;
1895+ aspect_ratio = geo.width / static_cast<float>(geo.height);
1896+ }
1897 }
1898
1899 }
1900
1901=== renamed file 'launcher/LayoutSystem.h' => 'unity-shared/LayoutSystem.h'
1902--- launcher/LayoutSystem.h 2012-10-11 01:44:15 +0000
1903+++ unity-shared/LayoutSystem.h 2012-11-15 18:52:31 +0000
1904@@ -20,7 +20,7 @@
1905 #ifndef UNITYSHELL_LAYOUTSYSTEM_H
1906 #define UNITYSHELL_LAYOUTSYSTEM_H
1907
1908-#include <boost/shared_ptr.hpp>
1909+#include <memory>
1910 #include <sigc++/sigc++.h>
1911 #include <Nux/Nux.h>
1912
1913@@ -29,48 +29,45 @@
1914 namespace unity {
1915 namespace ui {
1916
1917-class LayoutWindow
1918+struct LayoutWindow
1919 {
1920-public:
1921- typedef boost::shared_ptr<LayoutWindow> Ptr;
1922+ typedef std::shared_ptr<LayoutWindow> Ptr;
1923+ typedef std::vector<LayoutWindow::Ptr> Vector;
1924
1925- LayoutWindow (Window xid);
1926+ LayoutWindow(Window xid);
1927
1928 Window xid;
1929
1930 nux::Geometry geo;
1931 nux::Geometry result;
1932+ unsigned decoration_height;
1933
1934+ bool selected;
1935 float aspect_ratio;
1936 float alpha;
1937 };
1938
1939-typedef std::vector<LayoutWindow::Ptr> LayoutWindowList;
1940-
1941 class LayoutSystem
1942 {
1943 public:
1944- typedef boost::shared_ptr<LayoutSystem> Ptr;
1945-
1946 nux::Property<int> spacing;
1947 nux::Property<int> max_row_height;
1948
1949- LayoutSystem ();
1950- ~LayoutSystem ();
1951+ LayoutSystem();
1952
1953- void LayoutWindows (LayoutWindowList windows, nux::Geometry const& max_bounds, nux::Geometry& final_bounds);
1954+ void LayoutWindows(LayoutWindow::Vector const& windows, nux::Geometry const& max_bounds, nux::Geometry& final_bounds);
1955
1956 protected:
1957- void LayoutGridWindows (LayoutWindowList const& windows, nux::Geometry const& max_bounds, nux::Geometry& final_bounds);
1958-
1959- nux::Geometry LayoutRow (LayoutWindowList const& row, nux::Geometry const& row_bounds);
1960- nux::Geometry CompressAndPadRow (LayoutWindowList const& windows, nux::Geometry const& max_bounds);
1961-
1962- std::vector<LayoutWindowList> GetRows (LayoutWindowList const& windows, nux::Geometry const& max_bounds);
1963-
1964- nux::Size GridSizeForWindows (LayoutWindowList windows, nux::Geometry const& max_bounds);
1965-
1966- nux::Geometry ScaleBoxIntoBox (nux::Geometry const& bounds, nux::Geometry const& box);
1967+ void LayoutGridWindows(LayoutWindow::Vector const& windows, nux::Geometry const& max_bounds, nux::Geometry& final_bounds);
1968+
1969+ nux::Geometry LayoutRow(LayoutWindow::Vector const& row, nux::Geometry const& row_bounds);
1970+ nux::Geometry CompressAndPadRow(LayoutWindow::Vector const& windows, nux::Geometry const& max_bounds);
1971+
1972+ std::vector<LayoutWindow::Vector> GetRows(LayoutWindow::Vector const& windows, nux::Geometry const& max_bounds);
1973+
1974+ nux::Size GridSizeForWindows(LayoutWindow::Vector const& windows, nux::Geometry const& max_bounds);
1975+
1976+ nux::Geometry ScaleBoxIntoBox(nux::Geometry const& bounds, nux::Geometry const& box);
1977 };
1978
1979 }
1980
1981=== modified file 'unity-shared/PluginAdapter.cpp'
1982--- unity-shared/PluginAdapter.cpp 2012-11-06 18:19:09 +0000
1983+++ unity-shared/PluginAdapter.cpp 2012-11-15 18:52:31 +0000
1984@@ -32,6 +32,7 @@
1985 {
1986 const int THRESHOLD_HEIGHT = 600;
1987 const int THRESHOLD_WIDTH = 1024;
1988+const char* _UNITY_FRAME_EXTENTS = "_UNITY_FRAME_EXTENTS";
1989
1990 std::shared_ptr<PluginAdapter> global_instance;
1991 }
1992@@ -41,7 +42,6 @@
1993 #define MWM_HINTS_FUNCTIONS (1L << 0)
1994 #define MWM_HINTS_DECORATIONS (1L << 1)
1995 #define MWM_HINTS_UNDECORATED_UNITY 0x80
1996-#define _XA_MOTIF_WM_HINTS "_MOTIF_WM_HINTS"
1997
1998
1999 WindowManagerPtr create_window_manager()
2000@@ -145,21 +145,29 @@
2001
2002 void PluginAdapter::NotifyNewDecorationState(Window xid)
2003 {
2004- bool wasTracked = (_window_decoration_state.find(xid) != _window_decoration_state.end());
2005+ auto deco_state_it = _window_decoration_state.find(xid);
2006+ bool wasTracked = (deco_state_it != _window_decoration_state.end());
2007 bool wasDecorated = false;
2008
2009 if (wasTracked)
2010- wasDecorated = _window_decoration_state[xid];
2011+ {
2012+ wasDecorated = deco_state_it->second;
2013+ _window_decoration_state.erase(deco_state_it);
2014+ }
2015
2016- bool decorated = IsWindowDecorated(xid);
2017+ bool decorated = HasWindowDecorations(xid);
2018
2019 if (decorated == wasDecorated)
2020 return;
2021
2022 if (decorated && (!wasDecorated || !wasTracked))
2023+ {
2024 window_decorated.emit(xid);
2025+ }
2026 else if (wasDecorated || !wasTracked)
2027+ {
2028 window_undecorated.emit(xid);
2029+ }
2030 }
2031
2032 void PluginAdapter::Notify(CompWindow* window, CompWindowNotify notify)
2033@@ -212,6 +220,16 @@
2034 _vp_switch_started = false;
2035 screen_viewport_switch_ended.emit();
2036 }
2037+ else if (IsScaleActive() && g_strcmp0(plugin, "scale") == 0 &&
2038+ g_strcmp0(event, "activate") == 0)
2039+ {
2040+ // If the scale plugin is activated again while is already grabbing the screen
2041+ // it means that is switching the view (i.e. switching from a spread application
2042+ // to another), so we need to notify our clients that it has really terminated
2043+ // and initiated again.
2044+ terminate_spread.emit();
2045+ initiate_spread.emit();
2046+ }
2047 }
2048
2049 void MultiActionList::AddNewAction(std::string const& name, CompAction* a, bool primary)
2050@@ -424,7 +442,7 @@
2051 return false;
2052 }
2053
2054-bool PluginAdapter::IsWindowDecorated(Window window_id) const
2055+unsigned long PluginAdapter::GetMwnDecorations(Window window_id) const
2056 {
2057 Display* display = m_Screen->dpy();
2058 MotifWmHints* hints = NULL;
2059@@ -432,35 +450,61 @@
2060 gint format;
2061 gulong nitems;
2062 gulong bytes_after;
2063- bool ret = true;
2064-
2065- Atom hints_atom = XInternAtom(display, _XA_MOTIF_WM_HINTS, false);
2066-
2067- if (XGetWindowProperty(display, window_id, hints_atom, 0,
2068+ unsigned long decorations = 0;
2069+
2070+ if (XGetWindowProperty(display, window_id, Atoms::mwmHints, 0,
2071 sizeof(MotifWmHints) / sizeof(long), False,
2072- hints_atom, &type, &format, &nitems, &bytes_after,
2073+ Atoms::mwmHints, &type, &format, &nitems, &bytes_after,
2074 (guchar**)&hints) != Success)
2075- return false;
2076+ {
2077+ return decorations;
2078+ }
2079+
2080+ decorations |= (MwmDecorAll | MwmDecorTitle);
2081
2082 if (!hints)
2083- return ret;
2084+ return decorations;
2085
2086 /* Check for the presence of the high bit
2087 * if present, it means that we undecorated
2088 * this window, so don't mark it as undecorated */
2089- if (type == hints_atom && format != 0 &&
2090- hints->flags & MWM_HINTS_DECORATIONS)
2091+ if (type == Atoms::mwmHints && format != 0 && hints->flags & MWM_HINTS_DECORATIONS)
2092 {
2093- /* Must have both bits set */
2094- ret = (hints->decorations & (MwmDecorAll | MwmDecorTitle)) ||
2095- (hints->decorations & MWM_HINTS_UNDECORATED_UNITY);
2096- // This is mildly evil and we should look for another solution.
2097- PluginAdapter* non_const_this = const_cast<PluginAdapter*>(this);
2098- non_const_this->_window_decoration_state[window_id] = ret;
2099+ decorations = hints->decorations;
2100 }
2101
2102 XFree(hints);
2103- return ret;
2104+ return decorations;
2105+}
2106+
2107+bool PluginAdapter::HasWindowDecorations(Window window_id) const
2108+{
2109+ auto deco_state_it = _window_decoration_state.find(window_id);
2110+
2111+ if (deco_state_it != _window_decoration_state.end())
2112+ return deco_state_it->second;
2113+
2114+ unsigned long decorations = GetMwnDecorations(window_id);
2115+
2116+ /* Must have both bits set */
2117+ bool decorated = (decorations & (MwmDecorAll | MwmDecorTitle)) ||
2118+ (decorations & MWM_HINTS_UNDECORATED_UNITY);
2119+
2120+ _window_decoration_state[window_id] = decorated;
2121+
2122+ return decorated;
2123+}
2124+
2125+bool PluginAdapter::IsWindowDecorated(Window window_id) const
2126+{
2127+ bool decorated = GetMwnDecorations(window_id) & (MwmDecorAll | MwmDecorTitle);
2128+
2129+ if (decorated && GetCardinalProperty(window_id, Atoms::frameExtents).empty())
2130+ {
2131+ decorated = false;
2132+ }
2133+
2134+ return decorated;
2135 }
2136
2137 bool PluginAdapter::IsWindowOnCurrentDesktop(Window window_id) const
2138@@ -588,6 +632,14 @@
2139 return false;
2140 }
2141
2142+bool PluginAdapter::IsWindowMinimized(Window window_id) const
2143+{
2144+ if (CompWindow* window = m_Screen->findWindow(window_id))
2145+ return window->minimized();
2146+
2147+ return false;
2148+}
2149+
2150 bool PluginAdapter::IsWindowMinimizable(Window window_id) const
2151 {
2152 CompWindow* window = m_Screen->findWindow(window_id);
2153@@ -606,6 +658,12 @@
2154 return false;
2155 }
2156
2157+void PluginAdapter::Maximize(Window window_id)
2158+{
2159+ if (CompWindow* window = m_Screen->findWindow(window_id))
2160+ window->maximize(MAXIMIZE_STATE);
2161+}
2162+
2163 void PluginAdapter::Restore(Window window_id)
2164 {
2165 CompWindow* window = m_Screen->findWindow(window_id);
2166@@ -633,6 +691,13 @@
2167 window->minimize();
2168 }
2169
2170+void PluginAdapter::UnMinimize(Window window_id)
2171+{
2172+ CompWindow* window = m_Screen->findWindow(window_id);
2173+ if (window && (window->actions() & CompWindowActionMinimizeMask))
2174+ window->unminimize();
2175+}
2176+
2177 void PluginAdapter::Close(Window window_id)
2178 {
2179 CompWindow* window = m_Screen->findWindow(window_id);
2180@@ -799,12 +864,7 @@
2181
2182 void PluginAdapter::SetWindowIconGeometry(Window window, nux::Geometry const& geo)
2183 {
2184- long data[4];
2185-
2186- data[0] = geo.x;
2187- data[1] = geo.y;
2188- data[2] = geo.width;
2189- data[3] = geo.height;
2190+ long data[4] = {geo.x, geo.y, geo.width, geo.height};
2191
2192 XChangeProperty(m_Screen->dpy(), window, Atoms::wmIconGeometry,
2193 XA_CARDINAL, 32, PropModeReplace,
2194@@ -860,38 +920,79 @@
2195
2196 nux::Geometry PluginAdapter::GetWindowGeometry(Window window_id) const
2197 {
2198- nux::Geometry geo;
2199- CompWindow* window = m_Screen->findWindow(window_id);
2200- if (window)
2201+ if (CompWindow* window = m_Screen->findWindow(window_id))
2202 {
2203- geo.x = window->borderRect().x();
2204- geo.y = window->borderRect().y();
2205- geo.width = window->borderRect().width();
2206- geo.height = window->borderRect().height();
2207+ auto const& b = window->borderRect();
2208+ return nux::Geometry(b.x(), b.y(), b.width(), b.height());
2209 }
2210- return geo;
2211+
2212+ return nux::Geometry();
2213 }
2214
2215 nux::Geometry PluginAdapter::GetWindowSavedGeometry(Window window_id) const
2216 {
2217- nux::Geometry geo(0, 0, 1, 1);
2218- CompWindow* window = m_Screen->findWindow(window_id);
2219- if (window)
2220+ if (CompWindow* window = m_Screen->findWindow(window_id))
2221 {
2222 XWindowChanges &wc = window->saveWc();
2223- geo.x = wc.x;
2224- geo.y = wc.y;
2225- geo.width = wc.width;
2226- geo.height = wc.height;
2227+ return nux::Geometry(wc.x, wc.y, wc.width, wc.height);
2228 }
2229
2230- return geo;
2231+ return nux::Geometry(0, 0, 1, 1);
2232 }
2233
2234 nux::Geometry PluginAdapter::GetScreenGeometry() const
2235 {
2236- nux::Geometry geo(0, 0, m_Screen->width(), m_Screen->height());
2237- return geo;
2238+ return nux::Geometry(0, 0, m_Screen->width(), m_Screen->height());
2239+}
2240+
2241+nux::Size PluginAdapter::GetWindowDecorationSize(Window window_id, WindowManager::Edge edge) const
2242+{
2243+ if (CompWindow* window = m_Screen->findWindow(window_id))
2244+ {
2245+ if (HasWindowDecorations(window_id))
2246+ {
2247+ auto const& win_rect = window->borderRect();
2248+
2249+ if (IsWindowDecorated(window_id))
2250+ {
2251+ auto const& extents = window->border();
2252+
2253+ switch (edge)
2254+ {
2255+ case Edge::LEFT:
2256+ return nux::Size(extents.left, win_rect.height());
2257+ case Edge::TOP:
2258+ return nux::Size(win_rect.width(), extents.top);
2259+ case Edge::RIGHT:
2260+ return nux::Size(extents.right, win_rect.height());
2261+ case Edge::BOTTOM:
2262+ return nux::Size(win_rect.width(), extents.bottom);
2263+ }
2264+ }
2265+ else
2266+ {
2267+ Atom unity_extents = gdk_x11_get_xatom_by_name(_UNITY_FRAME_EXTENTS);
2268+ auto const& extents = GetCardinalProperty(window_id, unity_extents);
2269+
2270+ if (extents.size() == 4)
2271+ {
2272+ switch (edge)
2273+ {
2274+ case Edge::LEFT:
2275+ return nux::Size(extents[unsigned(Edge::LEFT)], win_rect.height());
2276+ case Edge::TOP:
2277+ return nux::Size(win_rect.width(), extents[unsigned(Edge::TOP)]);
2278+ case Edge::RIGHT:
2279+ return nux::Size(extents[unsigned(Edge::RIGHT)], win_rect.height());
2280+ case Edge::BOTTOM:
2281+ return nux::Size(win_rect.width(), extents[unsigned(Edge::BOTTOM)]);
2282+ }
2283+ }
2284+ }
2285+ }
2286+ }
2287+
2288+ return nux::Size();
2289 }
2290
2291 nux::Geometry PluginAdapter::GetWorkAreaGeometry(Window window_id) const
2292@@ -981,7 +1082,6 @@
2293 void PluginAdapter::SetMwmWindowHints(Window xid, MotifWmHints* new_hints) const
2294 {
2295 Display* display = m_Screen->dpy();
2296- Atom hints_atom = None;
2297 MotifWmHints* data = NULL;
2298 MotifWmHints* hints = NULL;
2299 Atom type = None;
2300@@ -989,18 +1089,16 @@
2301 gulong nitems;
2302 gulong bytes_after;
2303
2304- hints_atom = XInternAtom(display, _XA_MOTIF_WM_HINTS, false);
2305-
2306 if (XGetWindowProperty(display,
2307 xid,
2308- hints_atom, 0, sizeof(MotifWmHints) / sizeof(long),
2309+ Atoms::mwmHints, 0, sizeof(MotifWmHints) / sizeof(long),
2310 False, AnyPropertyType, &type, &format, &nitems,
2311 &bytes_after, (guchar**)&data) != Success)
2312 {
2313 return;
2314 }
2315
2316- if (type != hints_atom || !data)
2317+ if (type != Atoms::mwmHints || !data)
2318 {
2319 hints = new_hints;
2320 }
2321@@ -1020,9 +1118,7 @@
2322 }
2323 }
2324
2325- XChangeProperty(display,
2326- xid,
2327- hints_atom, hints_atom, 32, PropModeReplace,
2328+ XChangeProperty(display, xid, Atoms::mwmHints, Atoms::mwmHints, 32, PropModeReplace,
2329 (guchar*)hints, sizeof(MotifWmHints) / sizeof(long));
2330
2331 if (data)
2332@@ -1031,16 +1127,41 @@
2333
2334 void PluginAdapter::Decorate(Window window_id) const
2335 {
2336+ if (!HasWindowDecorations(window_id))
2337+ return;
2338+
2339 MotifWmHints hints = { 0 };
2340
2341 hints.flags = MWM_HINTS_DECORATIONS;
2342 hints.decorations = GDK_DECOR_ALL & ~(MWM_HINTS_UNDECORATED_UNITY);
2343
2344 SetMwmWindowHints(window_id, &hints);
2345+
2346+ // Removing the saved windows extents
2347+ Atom atom = gdk_x11_get_xatom_by_name(_UNITY_FRAME_EXTENTS);
2348+ XDeleteProperty(m_Screen->dpy(), window_id, atom);
2349 }
2350
2351 void PluginAdapter::Undecorate(Window window_id) const
2352 {
2353+ if (!IsWindowDecorated(window_id))
2354+ return;
2355+
2356+ if (CompWindow* window = m_Screen->findWindow(window_id))
2357+ {
2358+ // Saving the previous window extents values
2359+ long extents[4];
2360+ auto const& border = window->border();
2361+ extents[unsigned(Edge::LEFT)] = border.left;
2362+ extents[unsigned(Edge::RIGHT)] = border.right;
2363+ extents[unsigned(Edge::TOP)] = border.top;
2364+ extents[unsigned(Edge::BOTTOM)] = border.bottom;
2365+
2366+ Atom atom = gdk_x11_get_xatom_by_name(_UNITY_FRAME_EXTENTS);
2367+ XChangeProperty(m_Screen->dpy(), window_id, atom, XA_CARDINAL, 32,
2368+ PropModeReplace, (unsigned char*) extents, 4);
2369+ }
2370+
2371 MotifWmHints hints = { 0 };
2372
2373 /* Set the high bit to indicate that we undecorated this
2374@@ -1265,13 +1386,11 @@
2375 std::string name;
2376 Atom visibleNameAtom;
2377
2378- visibleNameAtom = XInternAtom(m_Screen->dpy(), "_NET_WM_VISIBLE_NAME", 0);
2379+ visibleNameAtom = gdk_x11_get_xatom_by_name("_NET_WM_VISIBLE_NAME");
2380 name = GetUtf8Property(window_id, visibleNameAtom);
2381+
2382 if (name.empty())
2383- {
2384- Atom wmNameAtom = XInternAtom(m_Screen->dpy(), "_NET_WM_NAME", 0);
2385- name = GetUtf8Property(window_id, wmNameAtom);
2386- }
2387+ name = GetUtf8Property(window_id, Atoms::wmName);
2388
2389 if (name.empty())
2390 name = GetTextProperty(window_id, XA_WM_NAME);
2391@@ -1281,27 +1400,25 @@
2392
2393 std::string PluginAdapter::GetUtf8Property(Window window_id, Atom atom) const
2394 {
2395- Atom type;
2396- int result, format;
2397- unsigned long nItems, bytesAfter;
2398- char *val;
2399- std::string retval;
2400- Atom utf8StringAtom;
2401+ Atom type;
2402+ int result, format;
2403+ unsigned long n_items, bytes_after;
2404+ char *val = nullptr;
2405+ std::string retval;
2406
2407- utf8StringAtom = XInternAtom(m_Screen->dpy(), "UTF8_STRING", 0);
2408 result = XGetWindowProperty(m_Screen->dpy(), window_id, atom, 0L, 65536, False,
2409- utf8StringAtom, &type, &format, &nItems,
2410- &bytesAfter, reinterpret_cast<unsigned char **>(&val));
2411+ Atoms::utf8String, &type, &format, &n_items,
2412+ &bytes_after, reinterpret_cast<unsigned char **>(&val));
2413
2414 if (result != Success)
2415 return retval;
2416
2417- if (type == utf8StringAtom && format == 8 && val && nItems > 0)
2418+ if (type == Atoms::utf8String && format == 8 && val && n_items > 0)
2419 {
2420- retval = std::string(val, nItems);
2421+ retval = std::string(val, n_items);
2422 }
2423- if (val)
2424- XFree(val);
2425+
2426+ XFree(val);
2427
2428 return retval;
2429 }
2430@@ -1310,8 +1427,8 @@
2431 {
2432 XTextProperty text;
2433 std::string retval;
2434-
2435 text.nitems = 0;
2436+
2437 if (XGetTextProperty(m_Screen->dpy(), window_id, &text, atom))
2438 {
2439 if (text.value)
2440@@ -1324,4 +1441,30 @@
2441 return retval;
2442 }
2443
2444+std::vector<long> PluginAdapter::GetCardinalProperty(Window window_id, Atom atom) const
2445+{
2446+ Atom type;
2447+ int result, format;
2448+ unsigned long n_items, bytes_after;
2449+ long *buf = nullptr;
2450+
2451+ result = XGetWindowProperty(m_Screen->dpy(), window_id, atom, 0L, 65536, False,
2452+ XA_CARDINAL, &type, &format, &n_items, &bytes_after,
2453+ reinterpret_cast<unsigned char **>(&buf));
2454+
2455+ std::unique_ptr<long[], int(*)(void*)> buffer(buf, XFree);
2456+
2457+ if (result == Success && type == XA_CARDINAL && format == 32 && buffer && n_items > 0)
2458+ {
2459+ std::vector<long> values(n_items);
2460+
2461+ for (unsigned i = 0; i < n_items; ++i)
2462+ values[i] = buffer[i];
2463+
2464+ return values;
2465+ }
2466+
2467+ return std::vector<long>();
2468+}
2469+
2470 } // namespace unity
2471
2472=== modified file 'unity-shared/PluginAdapter.h'
2473--- unity-shared/PluginAdapter.h 2012-11-06 18:19:09 +0000
2474+++ unity-shared/PluginAdapter.h 2012-11-15 18:52:31 +0000
2475@@ -133,12 +133,16 @@
2476 bool IsWindowVisible(Window window_id) const;
2477 bool IsWindowOnTop(Window window_id) const;
2478 bool IsWindowClosable(Window window_id) const;
2479+ bool IsWindowMinimized(Window window_id) const;
2480 bool IsWindowMinimizable(Window window_id) const;
2481 bool IsWindowMaximizable(Window window_id) const;
2482+ bool HasWindowDecorations(Window window_id) const;
2483
2484+ void Maximize(Window window_id);
2485 void Restore(Window window_id);
2486 void RestoreAt(Window window_id, int x, int y);
2487 void Minimize(Window window_id);
2488+ void UnMinimize(Window window_id);
2489 void Close(Window window_id);
2490 void Activate(Window window_id);
2491 void Raise(Window window_id);
2492@@ -166,6 +170,7 @@
2493 nux::Geometry GetWindowSavedGeometry(Window window_id) const;
2494 nux::Geometry GetScreenGeometry() const;
2495 nux::Geometry GetWorkAreaGeometry(Window window_id = 0) const;
2496+ nux::Size GetWindowDecorationSize(Window window_id, Edge) const;
2497 std::string GetWindowName(Window window_id) const;
2498
2499 void CheckWindowIntersections(nux::Geometry const& region, bool &active, bool &any);
2500@@ -191,11 +196,13 @@
2501
2502 bool CheckWindowIntersection(nux::Geometry const& region, CompWindow* window) const;
2503 void SetMwmWindowHints(Window xid, MotifWmHints* new_hints) const;
2504+ unsigned long GetMwnDecorations(Window xid) const;
2505
2506 Window GetTopMostValidWindowInViewport() const;
2507
2508 std::string GetTextProperty(Window xid, Atom atom) const;
2509 std::string GetUtf8Property(Window xid, Atom atom) const;
2510+ std::vector<long> GetCardinalProperty(Window xid, Atom atom) const;
2511
2512 CompScreen* m_Screen;
2513 MultiActionList m_ExpoActionList;
2514@@ -215,7 +222,7 @@
2515 bool _in_show_desktop;
2516 CompWindow* _last_focused_window;
2517
2518- std::map<Window, unsigned int> _window_decoration_state;
2519+ mutable std::map<Window, unsigned int> _window_decoration_state;
2520 };
2521
2522 }
2523
2524=== modified file 'unity-shared/StandaloneWindowManager.cpp'
2525--- unity-shared/StandaloneWindowManager.cpp 2012-11-06 18:19:09 +0000
2526+++ unity-shared/StandaloneWindowManager.cpp 2012-11-15 18:52:31 +0000
2527@@ -16,6 +16,7 @@
2528 *
2529 * Authored by: Jason Smith <jason.smith@canonical.com>
2530 * Tim Penhey <tim.penhey@canonical.com>
2531+ * Marco Trevisan (Treviño) <marco.trevisan@canonical.com>
2532 */
2533
2534 #include <glib.h>
2535@@ -32,6 +33,25 @@
2536 {
2537 DECLARE_LOGGER(logger, "unity.wm");
2538
2539+StandaloneWindow::StandaloneWindow(Window xid)
2540+ : xid(xid)
2541+ , name("StandaloneWindow " + std::to_string(xid))
2542+ , geo(0, 0, 10, 10)
2543+ , current_desktop(0)
2544+ , monitor(0)
2545+ , active(true)
2546+ , mapped(true)
2547+ , visible(true)
2548+ , maximized(false)
2549+ , minimized(false)
2550+ , decorated(true)
2551+ , has_decorations(true)
2552+ , on_top(false)
2553+ , closable(true)
2554+ , minimizable(false)
2555+ , maximizable(false)
2556+{}
2557+
2558 WindowManagerPtr create_window_manager()
2559 {
2560 return WindowManagerPtr(new StandaloneWindowManager);
2561@@ -42,26 +62,42 @@
2562 , in_show_desktop_(false)
2563 , scale_active_(false)
2564 , scale_active_for_group_(false)
2565-{
2566-}
2567+ , current_desktop_(0)
2568+{}
2569
2570 Window StandaloneWindowManager::GetActiveWindow() const
2571 {
2572+ for (auto const& it : standalone_windows_)
2573+ if (it.second->active)
2574+ return it.second->Xid();
2575+
2576 return 0;
2577 }
2578
2579 bool StandaloneWindowManager::IsWindowMaximized(Window window_id) const
2580 {
2581+ auto it = standalone_windows_.find(window_id);
2582+ if (it != standalone_windows_.end())
2583+ return it->second->maximized;
2584+
2585 return false;
2586 }
2587
2588 bool StandaloneWindowManager::IsWindowDecorated(Window window_id) const
2589 {
2590+ auto it = standalone_windows_.find(window_id);
2591+ if (it != standalone_windows_.end() && it->second->has_decorations)
2592+ return it->second->decorated;
2593+
2594 return false;
2595 }
2596
2597 bool StandaloneWindowManager::IsWindowOnCurrentDesktop(Window window_id) const
2598 {
2599+ auto it = standalone_windows_.find(window_id);
2600+ if (it != standalone_windows_.end())
2601+ return (it->second->current_desktop == current_desktop_);
2602+
2603 return false;
2604 }
2605
2606@@ -72,31 +108,73 @@
2607
2608 bool StandaloneWindowManager::IsWindowMapped(Window window_id) const
2609 {
2610+ auto it = standalone_windows_.find(window_id);
2611+ if (it != standalone_windows_.end())
2612+ return it->second->mapped;
2613+
2614 return false;
2615 }
2616
2617 bool StandaloneWindowManager::IsWindowVisible(Window window_id) const
2618 {
2619+ auto it = standalone_windows_.find(window_id);
2620+ if (it != standalone_windows_.end())
2621+ return it->second->visible;
2622+
2623 return false;
2624 }
2625
2626 bool StandaloneWindowManager::IsWindowOnTop(Window window_id) const
2627 {
2628+ auto it = standalone_windows_.find(window_id);
2629+ if (it != standalone_windows_.end())
2630+ return it->second->on_top;
2631+
2632 return false;
2633 }
2634
2635 bool StandaloneWindowManager::IsWindowClosable(Window window_id) const
2636 {
2637+ auto it = standalone_windows_.find(window_id);
2638+ if (it != standalone_windows_.end())
2639+ return it->second->closable;
2640+
2641+ return false;
2642+}
2643+
2644+bool StandaloneWindowManager::IsWindowMinimized(Window window_id) const
2645+{
2646+ auto it = standalone_windows_.find(window_id);
2647+ if (it != standalone_windows_.end())
2648+ return it->second->minimized;
2649+
2650 return false;
2651 }
2652
2653 bool StandaloneWindowManager::IsWindowMinimizable(Window window_id) const
2654 {
2655+ auto it = standalone_windows_.find(window_id);
2656+ if (it != standalone_windows_.end())
2657+ return it->second->minimizable;
2658+
2659 return false;
2660 }
2661
2662 bool StandaloneWindowManager::IsWindowMaximizable(Window window_id) const
2663 {
2664+ auto it = standalone_windows_.find(window_id);
2665+ if (it != standalone_windows_.end())
2666+ return it->second->maximizable;
2667+
2668+ return false;
2669+}
2670+
2671+bool StandaloneWindowManager::HasWindowDecorations(Window window_id) const
2672+{
2673+ auto it = standalone_windows_.find(window_id);
2674+ if (it != standalone_windows_.end())
2675+ return it->second->has_decorations;
2676+
2677 return false;
2678 }
2679
2680@@ -110,20 +188,101 @@
2681 return in_show_desktop_;
2682 }
2683
2684+void StandaloneWindowManager::Decorate(Window window_id) const
2685+{
2686+ auto it = standalone_windows_.find(window_id);
2687+ if (it != standalone_windows_.end())
2688+ {
2689+ it->second->decorated = it->second->has_decorations;
2690+ }
2691+}
2692+
2693+void StandaloneWindowManager::Undecorate(Window window_id) const
2694+{
2695+ auto it = standalone_windows_.find(window_id);
2696+ if (it != standalone_windows_.end())
2697+ {
2698+ it->second->decorated = false;
2699+ }
2700+}
2701+
2702+void StandaloneWindowManager::Maximize(Window window_id)
2703+{
2704+ auto it = standalone_windows_.find(window_id);
2705+ if (it != standalone_windows_.end())
2706+ {
2707+ it->second->maximized = true;
2708+ Undecorate(window_id);
2709+ }
2710+}
2711+
2712 void StandaloneWindowManager::Restore(Window window_id)
2713-{}
2714+{
2715+ auto it = standalone_windows_.find(window_id);
2716+ if (it != standalone_windows_.end())
2717+ {
2718+ it->second->maximized = false;
2719+ Decorate(window_id);
2720+ }
2721+}
2722
2723 void StandaloneWindowManager::RestoreAt(Window window_id, int x, int y)
2724-{}
2725+{
2726+ auto it = standalone_windows_.find(window_id);
2727+ if (it != standalone_windows_.end())
2728+ {
2729+ Restore(window_id);
2730+ it->second->geo.x = x;
2731+ it->second->geo.y = y;
2732+ }
2733+}
2734+
2735+void StandaloneWindowManager::UnMinimize(Window window_id)
2736+{
2737+ auto it = standalone_windows_.find(window_id);
2738+ if (it != standalone_windows_.end())
2739+ {
2740+ it->second->minimized = false;
2741+
2742+ if (it->second->maximized)
2743+ {
2744+ Undecorate(window_id);
2745+ }
2746+ }
2747+}
2748
2749 void StandaloneWindowManager::Minimize(Window window_id)
2750-{}
2751+{
2752+ auto it = standalone_windows_.find(window_id);
2753+ if (it != standalone_windows_.end())
2754+ {
2755+ it->second->minimized = true;
2756+
2757+ if (it->second->maximized)
2758+ {
2759+ Decorate(window_id);
2760+ }
2761+ }
2762+}
2763
2764 void StandaloneWindowManager::Close(Window window_id)
2765-{}
2766+{
2767+ standalone_windows_.erase(window_id);
2768+}
2769
2770 void StandaloneWindowManager::Activate(Window window_id)
2771-{}
2772+{
2773+ auto old = std::find_if(standalone_windows_.begin(), standalone_windows_.end(),
2774+ [this] (std::pair<Window, StandaloneWindow::Ptr> const& it)
2775+ { return it.second->active; });
2776+
2777+ if (old != standalone_windows_.end())
2778+ old->second->active = false;
2779+
2780+ auto it = standalone_windows_.find(window_id);
2781+ if (it != standalone_windows_.end())
2782+ it->second->active = true;
2783+}
2784
2785 void StandaloneWindowManager::Raise(Window window_id)
2786 {}
2787@@ -197,32 +356,52 @@
2788 }
2789
2790 void StandaloneWindowManager::MoveResizeWindow(Window window_id, nux::Geometry geometry)
2791-{}
2792+{
2793+ auto it = standalone_windows_.find(window_id);
2794+ if (it != standalone_windows_.end())
2795+ it->second->geo = geometry;
2796+}
2797
2798 void StandaloneWindowManager::StartMove(Window window_id, int x, int y)
2799-{}
2800+{
2801+ auto it = standalone_windows_.find(window_id);
2802+ if (it != standalone_windows_.end())
2803+ {
2804+ it->second->geo.x = x;
2805+ it->second->geo.y = y;
2806+ }
2807+}
2808
2809 int StandaloneWindowManager::GetWindowMonitor(Window window_id) const
2810 {
2811+ auto it = standalone_windows_.find(window_id);
2812+ if (it != standalone_windows_.end())
2813+ return it->second->monitor;
2814+
2815 return -1;
2816 }
2817
2818 nux::Geometry StandaloneWindowManager::GetWindowGeometry(Window window_id) const
2819 {
2820- nux::Geometry geo(0, 0, 1, 1);
2821- return geo;
2822+ auto it = standalone_windows_.find(window_id);
2823+ if (it != standalone_windows_.end())
2824+ return it->second->geo;
2825+
2826+ return nux::Geometry(0, 0, 1, 1);
2827 }
2828
2829 nux::Geometry StandaloneWindowManager::GetWindowSavedGeometry(Window window_id) const
2830 {
2831- nux::Geometry geo(0, 0, 1, 1);
2832- return geo;
2833+ auto it = standalone_windows_.find(window_id);
2834+ if (it != standalone_windows_.end())
2835+ return it->second->geo;
2836+
2837+ return nux::Geometry();
2838 }
2839
2840 nux::Geometry StandaloneWindowManager::GetScreenGeometry() const
2841 {
2842- nux::Geometry geo(0, 0, 1, 1);
2843- return geo;
2844+ return nux::Geometry(0, 0, 1024, 768);
2845 }
2846
2847 nux::Geometry StandaloneWindowManager::GetWorkAreaGeometry(Window window_id) const
2848@@ -231,6 +410,15 @@
2849 return geo;
2850 }
2851
2852+nux::Size StandaloneWindowManager::GetWindowDecorationSize(Window window_id, WindowManager::Edge edge) const
2853+{
2854+ auto it = standalone_windows_.find(window_id);
2855+ if (it != standalone_windows_.end())
2856+ return it->second->deco_sizes[unsigned(edge)];
2857+
2858+ return nux::Size();
2859+}
2860+
2861 unsigned long long StandaloneWindowManager::GetWindowActiveNumber(Window window_id) const
2862 {
2863 return 0;
2864@@ -262,9 +450,37 @@
2865
2866 std::string StandaloneWindowManager::GetWindowName(Window window_id) const
2867 {
2868+ auto it = standalone_windows_.find(window_id);
2869+ if (it != standalone_windows_.end())
2870+ return it->second->name;
2871+
2872 return "";
2873 }
2874
2875+// Mock functions
2876+
2877+void StandaloneWindowManager::SetCurrentDesktop(unsigned desktop_id)
2878+{
2879+ current_desktop_ = desktop_id;
2880+}
2881+
2882+void StandaloneWindowManager::AddStandaloneWindow(StandaloneWindow::Ptr const& window)
2883+{
2884+ if (!window)
2885+ return;
2886+
2887+ if (standalone_windows_.empty())
2888+ window->active = true;
2889+
2890+ standalone_windows_[window->Xid()] = window;
2891+}
2892+
2893+std::map<Window, StandaloneWindow::Ptr> StandaloneWindowManager::GetStandaloneWindows() const
2894+{
2895+ return standalone_windows_;
2896+}
2897+
2898+
2899 void StandaloneWindowManager::AddProperties(GVariantBuilder* builder)
2900 {
2901 unity::variant::BuilderWrapper wrapper(builder);
2902
2903=== modified file 'unity-shared/StandaloneWindowManager.h'
2904--- unity-shared/StandaloneWindowManager.h 2012-10-19 09:51:55 +0000
2905+++ unity-shared/StandaloneWindowManager.h 2012-11-15 18:52:31 +0000
2906@@ -15,16 +15,47 @@
2907 * along with this program. If not, see <http://www.gnu.org/licenses/>.
2908 *
2909 * Authored by: Tim Penhey <tim.penhey@canonical.com>
2910+ * Marco Trevisan (Treviño) <marco.trevisan@canonical.com>
2911 */
2912
2913 #ifndef UNITYSHARED_STANDALONE_WINDOW_MANAGER_H
2914 #define UNITYSHARED_STANDALONE_WINDOW_MANAGER_H
2915
2916 #include "unity-shared/WindowManager.h"
2917+#include <map>
2918
2919 namespace unity
2920 {
2921
2922+struct StandaloneWindow
2923+{
2924+ typedef std::shared_ptr<StandaloneWindow> Ptr;
2925+ StandaloneWindow(Window xid);
2926+
2927+private:
2928+ Window xid;
2929+
2930+public:
2931+ Window Xid() const { return xid; }
2932+
2933+ std::string name;
2934+ nux::Geometry geo;
2935+ nux::Size deco_sizes[4];
2936+ unsigned current_desktop;
2937+ unsigned monitor;
2938+ bool active;
2939+ bool mapped;
2940+ bool visible;
2941+ bool maximized;
2942+ bool minimized;
2943+ bool decorated;
2944+ bool has_decorations;
2945+ bool on_top;
2946+ bool closable;
2947+ bool minimizable;
2948+ bool maximizable;
2949+};
2950+
2951 class StandaloneWindowManager : public WindowManager
2952 {
2953 public:
2954@@ -40,21 +71,28 @@
2955 virtual bool IsWindowVisible(Window window_id) const;
2956 virtual bool IsWindowOnTop(Window window_id) const;
2957 virtual bool IsWindowClosable(Window window_id) const;
2958+ virtual bool IsWindowMinimized(Window window_id) const;
2959 virtual bool IsWindowMinimizable(Window window_id) const;
2960 virtual bool IsWindowMaximizable(Window window_id) const;
2961+ virtual bool HasWindowDecorations(Window) const;
2962
2963 virtual void ShowDesktop();
2964 virtual bool InShowDesktop() const;
2965
2966+ virtual void Maximize(Window window_id);
2967 virtual void Restore(Window window_id);
2968 virtual void RestoreAt(Window window_id, int x, int y);
2969 virtual void Minimize(Window window_id);
2970+ virtual void UnMinimize(Window window_id);
2971 virtual void Close(Window window_id);
2972
2973 virtual void Activate(Window window_id);
2974 virtual void Raise(Window window_id);
2975 virtual void Lower(Window window_id);
2976
2977+ virtual void Decorate(Window window_id) const;
2978+ virtual void Undecorate(Window window_id) const;
2979+
2980 virtual void TerminateScale();
2981 virtual bool IsScaleActive() const;
2982 virtual bool IsScaleActiveForGroup() const;
2983@@ -79,6 +117,7 @@
2984 virtual int GetWindowMonitor(Window window_id) const;
2985 virtual nux::Geometry GetWindowGeometry(Window window_id) const;
2986 virtual nux::Geometry GetWindowSavedGeometry(Window window_id) const;
2987+ virtual nux::Size GetWindowDecorationSize(Window window_id, Edge) const;
2988 virtual nux::Geometry GetScreenGeometry() const;
2989 virtual nux::Geometry GetWorkAreaGeometry(Window window_id) const;
2990
2991@@ -98,6 +137,10 @@
2992 // Mock functions
2993 void SetScaleActive(bool scale_active);
2994 void SetScaleActiveForGroup(bool scale_active_for_group);
2995+ void SetCurrentDesktop(unsigned desktop_id);
2996+
2997+ void AddStandaloneWindow(StandaloneWindow::Ptr const& window);
2998+ std::map<Window, StandaloneWindow::Ptr> GetStandaloneWindows() const;
2999
3000 protected:
3001 virtual void AddProperties(GVariantBuilder* builder);
3002@@ -107,6 +150,8 @@
3003 bool in_show_desktop_;
3004 bool scale_active_;
3005 bool scale_active_for_group_;
3006+ unsigned current_desktop_;
3007+ std::map<Window, StandaloneWindow::Ptr> standalone_windows_;
3008 };
3009
3010 }
3011
3012=== modified file 'unity-shared/WindowManager.h'
3013--- unity-shared/WindowManager.h 2012-10-24 08:21:17 +0000
3014+++ unity-shared/WindowManager.h 2012-11-15 18:52:31 +0000
3015@@ -62,6 +62,14 @@
3016 ForceUnminimizeOnCurrentDesktop
3017 };
3018
3019+ enum class Edge : unsigned
3020+ {
3021+ LEFT,
3022+ RIGHT,
3023+ TOP,
3024+ BOTTOM
3025+ };
3026+
3027 static WindowManager& Default();
3028
3029 virtual Window GetActiveWindow() const = 0;
3030@@ -74,15 +82,19 @@
3031 virtual bool IsWindowVisible(Window window_id) const = 0;
3032 virtual bool IsWindowOnTop(Window window_id) const = 0;
3033 virtual bool IsWindowClosable(Window window_id) const = 0;
3034+ virtual bool IsWindowMinimized(Window window_id) const = 0;
3035 virtual bool IsWindowMinimizable(Window window_id) const = 0;
3036 virtual bool IsWindowMaximizable(Window window_id) const = 0;
3037+ virtual bool HasWindowDecorations(Window window_id) const = 0;
3038
3039 virtual void ShowDesktop() = 0;
3040 virtual bool InShowDesktop() const = 0;
3041
3042+ virtual void Maximize(Window window_id) = 0;
3043 virtual void Restore(Window window_id) = 0;
3044 virtual void RestoreAt(Window window_id, int x, int y) = 0;
3045 virtual void Minimize(Window window_id) = 0;
3046+ virtual void UnMinimize(Window window_id) = 0;
3047 virtual void Close(Window window_id) = 0;
3048
3049 virtual void Activate(Window window_id) = 0;
3050@@ -117,6 +129,7 @@
3051 virtual int GetWindowMonitor(Window window_id) const = 0;
3052 virtual nux::Geometry GetWindowGeometry(Window window_id) const = 0;
3053 virtual nux::Geometry GetWindowSavedGeometry(Window window_id) const = 0;
3054+ virtual nux::Size GetWindowDecorationSize(Window window_id, Edge) const = 0;
3055 virtual nux::Geometry GetScreenGeometry() const = 0;
3056 virtual nux::Geometry GetWorkAreaGeometry(Window window_id = 0) const = 0;
3057