Merge lp:~brandontschaefer/unity/lp.1101310-fix-launcher-resize-window-buttons into lp:unity

Proposed by Brandon Schaefer
Status: Rejected
Rejected by: Brandon Schaefer
Proposed branch: lp:~brandontschaefer/unity/lp.1101310-fix-launcher-resize-window-buttons
Merge into: lp:unity
Prerequisite: lp:~brandontschaefer/unity/move-window-buttons-unity-shared
Diff against target: 2131 lines (+1015/-845)
20 files modified
dash/CMakeLists.txt (+1/-1)
dash/DashView.cpp (+17/-9)
dash/DashView.h (+12/-7)
hud/CMakeLists.txt (+1/-1)
hud/HudView.cpp (+6/-0)
hud/HudView.h (+3/-0)
panel/CMakeLists.txt (+0/-1)
panel/PanelMenuView.cpp (+2/-1)
panel/PanelMenuView.h (+1/-1)
panel/WindowButtonPriv.h (+0/-84)
panel/WindowButtons.cpp (+0/-662)
panel/WindowButtons.h (+0/-76)
tests/autopilot/unity/tests/test_panel.py (+16/-0)
tests/test_window_buttons.cpp (+2/-2)
unity-shared/CMakeLists.txt (+2/-0)
unity-shared/OverlayWindowButtons.cpp (+76/-0)
unity-shared/OverlayWindowButtons.h (+53/-0)
unity-shared/WindowButtonPriv.h (+84/-0)
unity-shared/WindowButtons.cpp (+662/-0)
unity-shared/WindowButtons.h (+77/-0)
To merge this branch: bzr merge lp:~brandontschaefer/unity/lp.1101310-fix-launcher-resize-window-buttons
Reviewer Review Type Date Requested Status
Unity Team Pending
Review via email: mp+145243@code.launchpad.net

This proposal supersedes a proposal from 2013-01-28.

Description of the change

=== Problem ===

When the launcher icons were resized the dash view would take up that extra space. The problem with this is the panel height is part of the dash view. So part of the window buttons are under the dash view which means no mouse events get to them. Meaning they no longer work :).

=== Fix ===

So to start, we can't fix this by telling the dash view to ignore the panel because the preview needs to draw over them. This means the dash view must be over the panel.

So the new fix, is to have the DashView/HudView hold the OverlayWindowButtons, which can now tell it to the area that is under the mouse. Making the buttons work again (yay!).

=== Test ===

There is an AP test

To post a comment you must log in.
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote : Posted in a previous version of this proposal

To help with review, since most of the diff +/- is due to just moving the WindowButton* to unity-shared:

New class OverlayWindowButtons:
1156 === added file 'unity-shared/OverlayWindowButtons.cpp'
1237 === added file 'unity-shared/OverlayWindowButtons.h'

Test:
1094 === modified file 'tests/autopilot/unity/tests/test_panel.py'

DashView changes:
11 === modified file 'dash/DashView.cpp'

HudView changes:
159 === modified file 'hud/HudView.cpp'

Those are most of the real changes.

Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

Yay for me messing up the history of the branch....new one coming soon to fix this ridiculousness... (Rejected)

Unmerged revisions

3070. By Brandon Schaefer

* The main reason, is the DashView has to take up the PanelHeight, so when the
  launcher icons are resized, part of the window buttons get cut off from mouse events.
* Move WindowButtons over to unity-shared, it is now shared between the dash/hud/panel
* Created a class OverlayWindowButtons which will sit in the DashView/HudView
  to handle mouse events for the window buttons.
* TODO: We need to refactor the PanelMenuView to extract window button logic
  (dealing with overlays).

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'dash/CMakeLists.txt'
2--- dash/CMakeLists.txt 2012-12-19 20:53:12 +0000
3+++ dash/CMakeLists.txt 2013-01-28 20:54:23 +0000
4@@ -56,4 +56,4 @@
5 # Standalone variant
6 #
7 add_executable (dash StandaloneDash.cpp)
8-target_link_libraries (dash dash-lib unity-shared)
9+target_link_libraries (dash dash-lib unity-shared unity-shared-standalone)
10
11=== modified file 'dash/DashView.cpp'
12--- dash/DashView.cpp 2013-01-15 21:53:55 +0000
13+++ dash/DashView.cpp 2013-01-28 20:54:23 +0000
14@@ -20,6 +20,7 @@
15
16 #include "DashView.h"
17 #include "DashViewPrivate.h"
18+#include "FilterExpanderLabel.h"
19
20 #include <math.h>
21
22@@ -31,13 +32,12 @@
23 #include <UnityCore/GLibWrapper.h>
24 #include <UnityCore/RadioOptionFilter.h>
25
26-#include "FilterExpanderLabel.h"
27 #include "unity-shared/DashStyle.h"
28 #include "unity-shared/KeyboardUtil.h"
29-#include "unity-shared/UnitySettings.h"
30-#include "unity-shared/UBusMessages.h"
31 #include "unity-shared/PreviewStyle.h"
32 #include "unity-shared/PanelStyle.h"
33+#include "unity-shared/UBusMessages.h"
34+#include "unity-shared/UnitySettings.h"
35
36 namespace unity
37 {
38@@ -126,6 +126,7 @@
39 , animate_split_value_(0.0)
40 , animate_preview_container_value_(0.0)
41 , animate_preview_value_(0.0)
42+ , overlay_window_buttons_(new OverlayWindowButtons())
43 {
44 renderer_.SetOwner(this);
45 renderer_.need_redraw.connect([this] () {
46@@ -493,6 +494,8 @@
47 ClosePreview();
48 }
49
50+ overlay_window_buttons_->AboutToShow();
51+
52 renderer_.AboutToShow();
53 }
54
55@@ -520,6 +523,8 @@
56 {
57 ClosePreview();
58 }
59+
60+ overlay_window_buttons_->AboutToHide();
61 }
62
63 void DashView::SetupViews()
64@@ -728,6 +733,8 @@
65 nux::GetPainter().PopBackgroundStack();
66 }
67
68+ overlay_window_buttons_->QueueDraw();
69+
70 graphics_engine.PopClippingRectangle();
71
72 renderer_.DrawInnerCleanup(graphics_engine, content_geo_, renderer_geo_abs, renderer_geo);
73@@ -1089,11 +1096,6 @@
74 geo.width += style.GetDashRightTileWidth();
75 geo.height += style.GetDashBottomTileHeight();
76 }
77-
78- if (!geo.IsPointInside(x, y))
79- {
80- ubus_manager_.SendMessage(UBUS_PLACE_VIEW_CLOSE_REQUEST);
81- }
82 }
83
84 void DashView::OnActivateRequest(GVariant* args)
85@@ -1518,6 +1520,7 @@
86 wrapper.add("right-border-width", style.GetDashRightTileWidth());
87 wrapper.add("bottom-border-height", style.GetDashBottomTileHeight());
88 wrapper.add("preview_displaying", preview_displaying_);
89+ wrapper.add("dash_maximized", style.always_maximised());
90 }
91
92 nux::Area* DashView::KeyNavIteration(nux::KeyNavDirection direction)
93@@ -1719,7 +1722,12 @@
94 nux::Area* DashView::FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type)
95 {
96 nux::Area* view = nullptr;
97- if (preview_displaying_)
98+
99+ if (overlay_window_buttons_->GetGeometry().IsInside(mouse_position))
100+ {
101+ return overlay_window_buttons_->FindAreaUnderMouse(mouse_position, event_type);
102+ }
103+ else if (preview_displaying_)
104 {
105 nux::Point newpos = mouse_position;
106 view = dynamic_cast<nux::Area*>(preview_container_.GetPointer())->FindAreaUnderMouse(newpos, event_type);
107
108=== modified file 'dash/DashView.h'
109--- dash/DashView.h 2012-12-17 09:28:31 +0000
110+++ dash/DashView.h 2013-01-28 20:54:23 +0000
111@@ -28,17 +28,20 @@
112 #include <UnityCore/HomeLens.h>
113 #include <UnityCore/GLibSource.h>
114
115-#include "unity-shared/BackgroundEffectHelper.h"
116-#include "unity-shared/SearchBar.h"
117-#include "unity-shared/Introspectable.h"
118-#include "unity-shared/BGHash.h"
119 #include "LensBar.h"
120 #include "LensView.h"
121-#include "unity-shared/UBusWrapper.h"
122-#include "unity-shared/OverlayRenderer.h"
123-#include "UnityCore/Preview.h"
124 #include "previews/PreviewContainer.h"
125 #include "PreviewStateMachine.h"
126+#include "UnityCore/Preview.h"
127+
128+#include "unity-shared/BackgroundEffectHelper.h"
129+#include "unity-shared/BGHash.h"
130+#include "unity-shared/Introspectable.h"
131+#include "unity-shared/OverlayRenderer.h"
132+#include "unity-shared/SearchBar.h"
133+#include "unity-shared/UBusWrapper.h"
134+#include "unity-shared/OverlayWindowButtons.h"
135+
136
137 namespace na = nux::animation;
138
139@@ -185,6 +188,8 @@
140
141 std::unique_ptr<na::AnimateValue<float>> preview_animation_;
142 float animate_preview_value_;
143+
144+ nux::ObjectPtr<OverlayWindowButtons> overlay_window_buttons_;
145 };
146
147
148
149=== modified file 'hud/CMakeLists.txt'
150--- hud/CMakeLists.txt 2012-12-19 20:53:12 +0000
151+++ hud/CMakeLists.txt 2013-01-28 20:54:23 +0000
152@@ -34,4 +34,4 @@
153 # Standalone variant
154 #
155 add_executable (hud StandaloneHud.cpp)
156-target_link_libraries (hud hud-lib unity-shared)
157+target_link_libraries (hud hud-lib unity-shared unity-shared-standalone)
158
159=== modified file 'hud/HudView.cpp'
160--- hud/HudView.cpp 2013-01-09 13:17:04 +0000
161+++ hud/HudView.cpp 2013-01-28 20:54:23 +0000
162@@ -67,6 +67,7 @@
163 , selected_button_(0)
164 , show_embedded_icon_(true)
165 , keyboard_stole_focus_(false)
166+ , overlay_window_buttons_(new OverlayWindowButtons())
167 {
168 renderer_.SetOwner(this);
169 renderer_.need_redraw.connect([this] () {
170@@ -345,12 +346,14 @@
171 void View::AboutToShow()
172 {
173 visible_ = true;
174+ overlay_window_buttons_->AboutToShow();
175 renderer_.AboutToShow();
176 }
177
178 void View::AboutToHide()
179 {
180 visible_ = false;
181+ overlay_window_buttons_->AboutToHide();
182 renderer_.AboutToHide();
183 }
184
185@@ -484,6 +487,9 @@
186 {
187 GetLayout()->ProcessDraw(gfx_context, force_draw);
188 }
189+
190+ overlay_window_buttons_->QueueDraw();
191+
192 gfx_context.PopClippingRectangle();
193
194 renderer_.DrawInnerCleanup(gfx_context, draw_content_geo, GetAbsoluteGeometry(), GetGeometry());
195
196=== modified file 'hud/HudView.h'
197--- hud/HudView.h 2012-11-28 14:23:01 +0000
198+++ hud/HudView.h 2013-01-28 20:54:23 +0000
199@@ -29,6 +29,7 @@
200 #include "HudButton.h"
201 #include "HudAbstractView.h"
202 #include "unity-shared/OverlayRenderer.h"
203+#include "unity-shared/OverlayWindowButtons.h"
204 #include "unity-shared/SearchBar.h"
205 #include "unity-shared/UBusWrapper.h"
206
207@@ -121,6 +122,8 @@
208 bool show_embedded_icon_;
209 bool activated_signal_sent_;
210 bool keyboard_stole_focus_;
211+
212+ nux::ObjectPtr<OverlayWindowButtons> overlay_window_buttons_;
213 };
214
215
216
217=== modified file 'panel/CMakeLists.txt'
218--- panel/CMakeLists.txt 2012-12-19 20:53:12 +0000
219+++ panel/CMakeLists.txt 2013-01-28 20:54:23 +0000
220@@ -24,7 +24,6 @@
221 PanelTitlebarGrabAreaView.cpp
222 PanelTray.cpp
223 PanelView.cpp
224- WindowButtons.cpp
225 )
226
227 add_library (panel-lib STATIC ${PANEL_SOURCES})
228
229=== modified file 'panel/PanelMenuView.cpp'
230--- panel/PanelMenuView.cpp 2013-01-09 14:16:07 +0000
231+++ panel/PanelMenuView.cpp 2013-01-28 20:54:23 +0000
232@@ -356,8 +356,9 @@
233 WindowManager& wm = WindowManager::Default();
234 bool screen_grabbed = (wm.IsExpoActive() || wm.IsScaleActive());
235
236+ // TODO: We need to refactor this code to extract the window button logic
237 if (overlay_showing_)
238- return true;
239+ return false;
240
241 if (we_control_active_ && is_maximized_ && !screen_grabbed &&
242 !launcher_keynav_ && !switcher_showing_)
243
244=== modified file 'panel/PanelMenuView.h'
245--- panel/PanelMenuView.h 2012-12-12 18:07:08 +0000
246+++ panel/PanelMenuView.h 2013-01-28 20:54:23 +0000
247@@ -28,7 +28,7 @@
248
249 #include "PanelIndicatorsView.h"
250 #include "unity-shared/StaticCairoText.h"
251-#include "WindowButtons.h"
252+#include "unity-shared/WindowButtons.h"
253 #include "PanelTitlebarGrabAreaView.h"
254 #include "unity-shared/UBusWrapper.h"
255
256
257=== removed file 'panel/WindowButtonPriv.h'
258--- panel/WindowButtonPriv.h 2012-12-14 14:41:16 +0000
259+++ panel/WindowButtonPriv.h 1970-01-01 00:00:00 +0000
260@@ -1,84 +0,0 @@
261-// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
262-/*
263- * Copyright (C) 2010-2012 Canonical Ltd
264- *
265- * This program is free software: you can redistribute it and/or modify
266- * it under the terms of the GNU General Public License version 3 as
267- * published by the Free Software Foundation.
268- *
269- * This program is distributed in the hope that it will be useful,
270- * but WITHOUT ANY WARRANTY; without even the implied warranty of
271- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
272- * GNU General Public License for more details.
273- *
274- * You should have received a copy of the GNU General Public License
275- * along with this program. If not, see <http://www.gnu.org/licenses/>.
276- *
277- * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
278- * Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
279- */
280-
281-#ifndef WINDOW_BUTTON_PRIVATE_H
282-#define WINDOW_BUTTON_PRIVATE_H
283-
284-#include <Nux/Button.h>
285-
286-#include "unity-shared/PanelStyle.h"
287-#include "unity-shared/UBusWrapper.h"
288-#include "unity-shared/Introspectable.h"
289-
290-namespace unity
291-{
292-class WindowButtons;
293-
294-namespace internal
295-{
296-
297-class WindowButton : public nux::Button, public debug::Introspectable
298-{
299- // A single window button
300-public:
301- WindowButton(panel::WindowButtonType type);
302-
303- panel::WindowButtonType GetType() const;
304- void SetVisualState(nux::ButtonVisualState new_state);
305-
306- nux::RWProperty<bool> enabled;
307- nux::Property<bool> overlay_mode;
308-
309-protected:
310- void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);
311- std::string GetName() const;
312- void AddProperties(GVariantBuilder* builder);
313-
314-private:
315- void UpdateSize();
316- void LoadImages();
317- bool EnabledSetter(bool enabled);
318- static nux::ObjectPtr<nux::BaseTexture> GetDashWindowButton(panel::WindowButtonType type, panel::WindowState state);
319-
320- inline WindowButtons* Parent() const
321- {
322- return static_cast<WindowButtons*>(GetParentObject());
323- }
324-
325-private:
326- panel::WindowButtonType type_;
327-
328- nux::ObjectPtr<nux::BaseTexture> normal_tex_;
329- nux::ObjectPtr<nux::BaseTexture> prelight_tex_;
330- nux::ObjectPtr<nux::BaseTexture> pressed_tex_;
331- nux::ObjectPtr<nux::BaseTexture> unfocused_tex_;
332- nux::ObjectPtr<nux::BaseTexture> unfocused_prelight_tex_;
333- nux::ObjectPtr<nux::BaseTexture> unfocused_pressed_tex_;
334- nux::ObjectPtr<nux::BaseTexture> disabled_tex_;
335- nux::ObjectPtr<nux::BaseTexture> normal_dash_tex_;
336- nux::ObjectPtr<nux::BaseTexture> prelight_dash_tex_;
337- nux::ObjectPtr<nux::BaseTexture> pressed_dash_tex_;
338- nux::ObjectPtr<nux::BaseTexture> disabled_dash_tex_;
339-};
340-
341-} // internal namespace
342-} // unity namespace
343-
344-#endif // WINDOW_BUTTON_PRIVATE_H
345
346=== removed file 'panel/WindowButtons.cpp'
347--- panel/WindowButtons.cpp 2012-12-17 19:35:34 +0000
348+++ panel/WindowButtons.cpp 1970-01-01 00:00:00 +0000
349@@ -1,662 +0,0 @@
350-// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
351-/*
352- * Copyright (C) 2010-2012 Canonical Ltd
353- *
354- * This program is free software: you can redistribute it and/or modify
355- * it under the terms of the GNU General Public License version 3 as
356- * published by the Free Software Foundation.
357- *
358- * This program is distributed in the hope that it will be useful,
359- * but WITHOUT ANY WARRANTY; without even the implied warranty of
360- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
361- * GNU General Public License for more details.
362- *
363- * You should have received a copy of the GNU General Public License
364- * along with this program. If not, see <http://www.gnu.org/licenses/>.
365- *
366- * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
367- * Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
368- */
369-
370-#include "config.h"
371-
372-#include <Nux/Nux.h>
373-#include <array>
374-
375-#include <UnityCore/GLibWrapper.h>
376-#include <UnityCore/Variant.h>
377-
378-#include "WindowButtons.h"
379-#include "WindowButtonPriv.h"
380-
381-#include "unity-shared/UBusMessages.h"
382-#include "unity-shared/WindowManager.h"
383-
384-namespace unity
385-{
386-
387-namespace internal
388-{
389-WindowButton::WindowButton(panel::WindowButtonType type)
390- : nux::Button("", NUX_TRACKER_LOCATION)
391- , enabled(sigc::mem_fun(this, &WindowButton::IsViewEnabled),
392- sigc::mem_fun(this, &WindowButton::EnabledSetter))
393- , overlay_mode(false)
394- , type_(type)
395-{
396- overlay_mode.changed.connect([this] (bool) { UpdateSize(); QueueDraw(); });
397- SetAcceptKeyNavFocusOnMouseDown(false);
398- panel::Style::Instance().changed.connect(sigc::mem_fun(this, &WindowButton::LoadImages));
399- LoadImages();
400-}
401-
402-void WindowButton::SetVisualState(nux::ButtonVisualState new_state)
403-{
404- if (new_state != visual_state_)
405- {
406- visual_state_ = new_state;
407- QueueDraw();
408- }
409-}
410-
411-void WindowButton::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
412-{
413- nux::Geometry const& geo = GetGeometry();
414- nux::BaseTexture* tex = nullptr;
415-
416- GfxContext.PushClippingRectangle(geo);
417-
418- if (overlay_mode())
419- {
420- if (!enabled())
421- {
422- tex = disabled_dash_tex_.GetPointer();
423- }
424- else
425- {
426- switch (visual_state_)
427- {
428- case nux::VISUAL_STATE_PRESSED:
429- tex = pressed_dash_tex_.GetPointer();
430- break;
431- case nux::VISUAL_STATE_PRELIGHT:
432- tex = prelight_dash_tex_.GetPointer();
433- break;
434- default:
435- tex = normal_dash_tex_.GetPointer();
436- }
437- }
438- }
439- else if (!enabled())
440- {
441- tex = disabled_tex_.GetPointer();
442- }
443- else if (!Parent()->focused())
444- {
445- switch (visual_state_)
446- {
447- case nux::VISUAL_STATE_PRESSED:
448- tex = unfocused_pressed_tex_.GetPointer();
449- break;
450- case nux::VISUAL_STATE_PRELIGHT:
451- tex = unfocused_prelight_tex_.GetPointer();
452- break;
453- default:
454- tex = unfocused_tex_.GetPointer();
455- }
456- }
457- else
458- {
459- switch (visual_state_)
460- {
461- case nux::VISUAL_STATE_PRESSED:
462- tex = pressed_tex_.GetPointer();
463- break;
464- case nux::VISUAL_STATE_PRELIGHT:
465- tex = prelight_tex_.GetPointer();
466- break;
467- default:
468- tex = normal_tex_.GetPointer();
469- }
470- }
471-
472- if (tex)
473- {
474- nux::TexCoordXForm texxform;
475- GfxContext.QRP_1Tex(geo.x, geo.y, geo.width, geo.height,
476- tex->GetDeviceTexture(), texxform,
477- nux::color::White * Parent()->opacity());
478- }
479-
480- GfxContext.PopClippingRectangle();
481-}
482-
483-void WindowButton::UpdateSize()
484-{
485- int panel_height = panel::Style::Instance().panel_height;
486- nux::BaseTexture* tex;
487- tex = (overlay_mode()) ? normal_dash_tex_.GetPointer() : normal_tex_.GetPointer();
488- int width = 0;
489- int height = 0;
490-
491- if (tex)
492- {
493- width = std::min(panel_height, tex->GetWidth());
494- height = std::min(panel_height, tex->GetHeight());
495- }
496-
497- SetMinMaxSize(width, height);
498-}
499-
500-void WindowButton::LoadImages()
501-{
502- panel::Style& style = panel::Style::Instance();
503-
504- normal_tex_ = style.GetWindowButton(type_, panel::WindowState::NORMAL);
505- prelight_tex_ = style.GetWindowButton(type_, panel::WindowState::PRELIGHT);
506- pressed_tex_ = style.GetWindowButton(type_, panel::WindowState::PRESSED);
507- unfocused_tex_ = style.GetWindowButton(type_, panel::WindowState::UNFOCUSED);
508- disabled_tex_ = style.GetWindowButton(type_, panel::WindowState::DISABLED);
509- unfocused_prelight_tex_ = style.GetWindowButton(type_, panel::WindowState::UNFOCUSED_PRELIGHT);
510- unfocused_pressed_tex_ = style.GetWindowButton(type_, panel::WindowState::UNFOCUSED_PRESSED);
511- normal_dash_tex_ = GetDashWindowButton(type_, panel::WindowState::NORMAL);
512- prelight_dash_tex_ = GetDashWindowButton(type_, panel::WindowState::PRELIGHT);
513- pressed_dash_tex_ = GetDashWindowButton(type_, panel::WindowState::PRESSED);
514- disabled_dash_tex_ = GetDashWindowButton(type_, panel::WindowState::DISABLED);
515-
516- UpdateSize();
517- QueueDraw();
518-}
519-
520-nux::ObjectPtr<nux::BaseTexture> WindowButton::GetDashWindowButton(panel::WindowButtonType type, panel::WindowState state)
521-{
522- nux::ObjectPtr<nux::BaseTexture> texture;
523- static const std::array<std::string, 4> names = {{ "close_dash", "minimize_dash", "unmaximize_dash", "maximize_dash" }};
524- static const std::array<std::string, 4> states = {{ "", "_prelight", "_pressed", "_disabled" }};
525-
526- std::string subpath = names[static_cast<int>(type)] + states[static_cast<int>(state)] + ".png";
527-
528- glib::String filename(g_build_filename(PKGDATADIR, subpath.c_str(), NULL));
529- texture.Adopt(nux::CreateTexture2DFromFile(filename, -1, true));
530-
531- if (!texture)
532- texture = panel::Style::Instance().GetFallbackWindowButton(type, state);
533-
534- return texture;
535-}
536-
537-panel::WindowButtonType WindowButton::GetType() const
538-{
539- return type_;
540-}
541-
542-bool WindowButton::EnabledSetter(bool new_value)
543-{
544- if (enabled() == new_value)
545- return false;
546-
547- SetEnableView(new_value);
548- QueueDraw();
549- return true;
550-}
551-
552-std::string WindowButton::GetName() const
553-{
554- return "WindowButton";
555-}
556-
557-void WindowButton::AddProperties(GVariantBuilder* builder)
558-{
559- std::string type_name;
560- std::string state_name;
561-
562- switch (type_)
563- {
564- case panel::WindowButtonType::CLOSE:
565- type_name = "Close";
566- break;
567- case panel::WindowButtonType::MINIMIZE:
568- type_name = "Minimize";
569- break;
570- case panel::WindowButtonType::MAXIMIZE:
571- type_name = "Maximize";
572- break;
573- case panel::WindowButtonType::UNMAXIMIZE:
574- type_name = "Unmaximize";
575- break;
576- }
577-
578- switch (visual_state_)
579- {
580- case nux::VISUAL_STATE_PRESSED:
581- state_name = "pressed";
582- break;
583- case nux::VISUAL_STATE_PRELIGHT:
584- state_name = "prelight";
585- break;
586- default:
587- state_name = "normal";
588- }
589-
590- variant::BuilderWrapper(builder).add(GetAbsoluteGeometry())
591- .add("type", type_name)
592- .add("visible", IsVisible() && Parent()->opacity() != 0.0f)
593- .add("sensitive", Parent()->GetInputEventSensitivity())
594- .add("enabled", enabled())
595- .add("visual_state", state_name)
596- .add("opacity", Parent()->opacity())
597- .add("focused", Parent()->focused())
598- .add("overlay_mode", overlay_mode());
599-}
600-} // Internal Namespace
601-
602-
603-WindowButtons::WindowButtons()
604- : HLayout("", NUX_TRACKER_LOCATION)
605- , monitor(0)
606- , controlled_window(0)
607- , opacity(1.0f, sigc::mem_fun(this, &WindowButtons::OpacitySetter))
608- , focused(true)
609-{
610- controlled_window.changed.connect(sigc::mem_fun(this, &WindowButtons::OnControlledWindowChanged));
611- focused.changed.connect(sigc::hide(sigc::mem_fun(this, &WindowButtons::QueueDraw)));
612-
613- auto lambda_enter = [&](int x, int y, unsigned long button_flags, unsigned long key_flags)
614- {
615- mouse_enter.emit(x, y, button_flags, key_flags);
616- };
617-
618- auto lambda_leave = [&](int x, int y, unsigned long button_flags, unsigned long key_flags)
619- {
620- mouse_leave.emit(x, y, button_flags, key_flags);
621- };
622-
623- auto lambda_moved = [&](int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags)
624- {
625- mouse_move.emit(x, y, dx, dy, button_flags, key_flags);
626- };
627-
628- internal::WindowButton* but;
629- but = new internal::WindowButton(panel::WindowButtonType::CLOSE);
630- AddView(but, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX);
631- AddChild(but);
632- but->click.connect(sigc::mem_fun(this, &WindowButtons::OnCloseClicked));
633- but->mouse_enter.connect(lambda_enter);
634- but->mouse_leave.connect(lambda_leave);
635- but->mouse_move.connect(lambda_moved);
636-
637- but = new internal::WindowButton(panel::WindowButtonType::MINIMIZE);
638- AddView(but, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX);
639- AddChild(but);
640- but->click.connect(sigc::mem_fun(this, &WindowButtons::OnMinimizeClicked));
641- but->mouse_enter.connect(lambda_enter);
642- but->mouse_leave.connect(lambda_leave);
643- but->mouse_move.connect(lambda_moved);
644-
645- but = new internal::WindowButton(panel::WindowButtonType::UNMAXIMIZE);
646- AddView(but, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX);
647- AddChild(but);
648- but->click.connect(sigc::mem_fun(this, &WindowButtons::OnRestoreClicked));
649- but->mouse_enter.connect(lambda_enter);
650- but->mouse_leave.connect(lambda_leave);
651- but->mouse_move.connect(lambda_moved);
652-
653- but = new internal::WindowButton(panel::WindowButtonType::MAXIMIZE);
654- AddView(but, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX);
655- AddChild(but);
656- but->click.connect(sigc::mem_fun(this, &WindowButtons::OnMaximizeClicked));
657- but->mouse_enter.connect(lambda_enter);
658- but->mouse_leave.connect(lambda_leave);
659- but->mouse_move.connect(lambda_moved);
660- but->SetVisible(false);
661-
662- SetContentDistribution(nux::MAJOR_POSITION_START);
663-
664- ubus_manager_.RegisterInterest(UBUS_OVERLAY_SHOWN, sigc::mem_fun(this, &WindowButtons::OnOverlayShown));
665- ubus_manager_.RegisterInterest(UBUS_OVERLAY_HIDDEN, sigc::mem_fun(this, &WindowButtons::OnOverlayHidden));
666- Settings::Instance().form_factor.changed.connect(sigc::mem_fun(this, &WindowButtons::OnDashSettingsUpdated));
667-}
668-
669-nux::Area* WindowButtons::FindAreaUnderMouse(const nux::Point& mouse, nux::NuxEventType event_type)
670-{
671- if (!GetInputEventSensitivity())
672- return nullptr;
673-
674- /* The first button should be clickable on the left space too, to
675- * make Fitts happy. All also on their top side. See bug #839690 */
676- bool first_found = false;
677-
678- for (auto area : GetChildren())
679- {
680- if (area->IsVisible())
681- {
682- nux::Geometry const& geo = area->GetAbsoluteGeometry();
683-
684- if (!first_found)
685- {
686- first_found = true;
687-
688- if (mouse.x < geo.x && mouse.y < (geo.y + geo.height))
689- return area;
690- }
691-
692- if (geo.IsPointInside(mouse.x, mouse.y))
693- return area;
694-
695- if (mouse.x >= geo.x && mouse.x <= (geo.x + geo.width) && mouse.y <= geo.y)
696- return area;
697- }
698- }
699-
700- return nullptr;
701-}
702-
703-void WindowButtons::OnCloseClicked(nux::Button *button)
704-{
705- auto win_button = dynamic_cast<internal::WindowButton*>(button);
706-
707- if (!win_button || !win_button->enabled())
708- return;
709-
710- if (win_button->overlay_mode())
711- {
712- ubus_manager_.SendMessage(UBUS_PLACE_VIEW_CLOSE_REQUEST);
713- }
714- else
715- {
716- WindowManager::Default().Close(controlled_window());
717- }
718-
719- close_clicked.emit();
720-}
721-
722-void WindowButtons::OnMinimizeClicked(nux::Button *button)
723-{
724- auto win_button = dynamic_cast<internal::WindowButton*>(button);
725-
726- if (!win_button || !win_button->enabled())
727- return;
728-
729- if (!win_button->overlay_mode())
730- WindowManager::Default().Minimize(controlled_window());
731-
732- minimize_clicked.emit();
733-}
734-
735-void WindowButtons::OnRestoreClicked(nux::Button *button)
736-{
737- auto win_button = dynamic_cast<internal::WindowButton*>(button);
738-
739- if (!win_button || !win_button->enabled())
740- return;
741-
742- if (win_button->overlay_mode())
743- {
744- Settings::Instance().form_factor = FormFactor::DESKTOP;
745- }
746- else
747- {
748- WindowManager& wm = WindowManager::Default();
749- Window to_restore = controlled_window();
750-
751- wm.Raise(to_restore);
752- wm.Activate(to_restore);
753- wm.Restore(to_restore);
754- }
755-
756- restore_clicked.emit();
757-}
758-
759-void WindowButtons::OnMaximizeClicked(nux::Button *button)
760-{
761- auto win_button = dynamic_cast<internal::WindowButton*>(button);
762-
763- if (!win_button || !win_button->enabled())
764- return;
765-
766- if (win_button->overlay_mode())
767- {
768- Settings::Instance().form_factor = FormFactor::NETBOOK;
769- }
770-
771- maximize_clicked.emit();
772-}
773-
774-void WindowButtons::OnOverlayShown(GVariant* data)
775-{
776- internal::WindowButton* maximize_button = nullptr;
777- internal::WindowButton* restore_button = nullptr;
778- glib::String overlay_identity;
779- gboolean can_maximise = FALSE;
780- gint32 overlay_monitor = 0;
781- g_variant_get(data, UBUS_OVERLAY_FORMAT_STRING,
782- &overlay_identity, &can_maximise, &overlay_monitor);
783-
784- if (overlay_monitor != monitor())
785- {
786- for (auto area : GetChildren())
787- {
788- auto button = dynamic_cast<internal::WindowButton*>(area);
789-
790- if (button)
791- button->enabled = false;
792- }
793-
794- return;
795- }
796-
797- active_overlay_ = overlay_identity.Str();
798-
799- for (auto area : GetChildren())
800- {
801- auto button = dynamic_cast<internal::WindowButton*>(area);
802-
803- if (button)
804- {
805- if (button->GetType() == panel::WindowButtonType::CLOSE)
806- button->enabled = true;
807-
808- if (button->GetType() == panel::WindowButtonType::UNMAXIMIZE)
809- restore_button = button;
810-
811- if (button->GetType() == panel::WindowButtonType::MAXIMIZE)
812- maximize_button = button;
813-
814- if (button->GetType() == panel::WindowButtonType::MINIMIZE)
815- button->enabled = false;
816-
817- button->overlay_mode = true;
818- }
819- }
820-
821- if (restore_button && maximize_button)
822- {
823- Settings &dash_settings = Settings::Instance();
824- bool maximizable = (dash_settings.form_factor() == FormFactor::DESKTOP);
825-
826- restore_button->enabled = can_maximise;
827- maximize_button->enabled = can_maximise;
828-
829- if (maximizable != maximize_button->IsVisible())
830- {
831- if (maximize_button->IsVisible())
832- restore_button->SetVisualState(maximize_button->GetVisualState());
833- else if (restore_button->IsVisible())
834- maximize_button->SetVisualState(restore_button->GetVisualState());
835-
836- restore_button->SetVisible(!maximizable);
837- maximize_button->SetVisible(maximizable);
838-
839- QueueDraw();
840- }
841- }
842-}
843-
844-void WindowButtons::OnOverlayHidden(GVariant* data)
845-{
846- internal::WindowButton* maximize_button = nullptr;
847- internal::WindowButton* restore_button = nullptr;
848-
849- glib::String overlay_identity;
850- gboolean can_maximise = FALSE;
851- gint32 overlay_monitor = 0;
852- g_variant_get(data, UBUS_OVERLAY_FORMAT_STRING,
853- &overlay_identity, &can_maximise, &overlay_monitor);
854-
855- if (overlay_monitor != monitor())
856- {
857- for (auto area : GetChildren())
858- {
859- auto button = dynamic_cast<internal::WindowButton*>(area);
860-
861- if (button)
862- button->enabled = true;
863- }
864- }
865-
866- if (active_overlay_ != overlay_identity.Str())
867- return;
868-
869- active_overlay_ = "";
870-
871- WindowManager& wm = WindowManager::Default();
872- for (auto area : GetChildren())
873- {
874- auto button = dynamic_cast<internal::WindowButton*>(area);
875-
876- if (button)
877- {
878- if (controlled_window())
879- {
880- if (button->GetType() == panel::WindowButtonType::CLOSE)
881- button->enabled = wm.IsWindowClosable(controlled_window());
882-
883- if (button->GetType() == panel::WindowButtonType::MINIMIZE)
884- button->enabled = wm.IsWindowMinimizable(controlled_window());
885- }
886-
887- if (button->GetType() == panel::WindowButtonType::UNMAXIMIZE)
888- restore_button = button;
889-
890- if (button->GetType() == panel::WindowButtonType::MAXIMIZE)
891- maximize_button = button;
892-
893- button->overlay_mode = false;
894- }
895- }
896-
897- if (restore_button && maximize_button)
898- {
899- restore_button->enabled = true;
900- maximize_button->enabled = true;
901-
902- if (!restore_button->IsVisible())
903- {
904- restore_button->SetVisualState(maximize_button->GetVisualState());
905-
906- restore_button->SetVisible(true);
907- maximize_button->SetVisible(false);
908-
909- QueueDraw();
910- }
911- }
912-}
913-
914-void WindowButtons::OnDashSettingsUpdated(FormFactor form_factor)
915-{
916- internal::WindowButton* maximize_button = nullptr;
917- internal::WindowButton* restore_button = nullptr;
918-
919- for (auto area : GetChildren())
920- {
921- auto button = dynamic_cast<internal::WindowButton*>(area);
922-
923- if (button)
924- {
925- if (!button->overlay_mode())
926- break;
927-
928- if (button->GetType() == panel::WindowButtonType::UNMAXIMIZE)
929- restore_button = button;
930-
931- if (button->GetType() == panel::WindowButtonType::MAXIMIZE)
932- maximize_button = button;
933-
934- if (restore_button && maximize_button)
935- break;
936- }
937- }
938-
939- if (restore_button && restore_button->overlay_mode() && maximize_button)
940- {
941- bool maximizable = (form_factor == FormFactor::DESKTOP);
942-
943- if (maximizable != maximize_button->IsVisible())
944- {
945- if (maximize_button->IsVisible())
946- restore_button->SetVisualState(maximize_button->GetVisualState());
947- else if (restore_button->IsVisible())
948- maximize_button->SetVisualState(restore_button->GetVisualState());
949-
950- restore_button->SetVisible(!maximizable);
951- maximize_button->SetVisible(maximizable);
952-
953- QueueRelayout();
954- }
955- }
956-}
957-
958-bool WindowButtons::OpacitySetter(double& target, double new_value)
959-{
960- double opacity = CLAMP(new_value, 0.0f, 1.0f);
961-
962- if (opacity != target)
963- {
964- target = opacity;
965- SetInputEventSensitivity(opacity != 0.0f);
966- QueueDraw();
967-
968- return true;
969- }
970-
971- return false;
972-}
973-
974-void WindowButtons::OnControlledWindowChanged(Window xid)
975-{
976- if (xid && active_overlay_.empty())
977- {
978- WindowManager& wm = WindowManager::Default();
979- for (auto area : GetChildren())
980- {
981- auto button = dynamic_cast<internal::WindowButton*>(area);
982-
983- if (!button)
984- continue;
985-
986- if (button->GetType() == panel::WindowButtonType::CLOSE)
987- button->enabled = wm.IsWindowClosable(xid);
988-
989- if (button->GetType() == panel::WindowButtonType::MINIMIZE)
990- button->enabled = wm.IsWindowMinimizable(xid);
991- }
992- }
993-}
994-
995-std::string WindowButtons::GetName() const
996-{
997- return "WindowButtons";
998-}
999-
1000-void WindowButtons::AddProperties(GVariantBuilder* builder)
1001-{
1002- variant::BuilderWrapper(builder).add(GetAbsoluteGeometry())
1003- .add("monitor", monitor())
1004- .add("opacity", opacity())
1005- .add("visible", opacity() != 0.0f)
1006- .add("sensitive", GetInputEventSensitivity())
1007- .add("focused", focused())
1008- .add("controlled_window", controlled_window());
1009-}
1010-
1011-} // unity namespace
1012
1013=== removed file 'panel/WindowButtons.h'
1014--- panel/WindowButtons.h 2012-12-14 17:19:44 +0000
1015+++ panel/WindowButtons.h 1970-01-01 00:00:00 +0000
1016@@ -1,76 +0,0 @@
1017-// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1018-/*
1019- * Copyright (C) 2010-2012 Canonical Ltd
1020- *
1021- * This program is free software: you can redistribute it and/or modify
1022- * it under the terms of the GNU General Public License version 3 as
1023- * published by the Free Software Foundation.
1024- *
1025- * This program is distributed in the hope that it will be useful,
1026- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1027- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1028- * GNU General Public License for more details.
1029- *
1030- * You should have received a copy of the GNU General Public License
1031- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1032- *
1033- * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
1034- * Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
1035- */
1036-
1037-#ifndef WINDOW_BUTTONS_H
1038-#define WINDOW_BUTTONS_H
1039-
1040-#include <Nux/HLayout.h>
1041-#include <Nux/Button.h>
1042-
1043-#include "unity-shared/Introspectable.h"
1044-#include "unity-shared/UBusWrapper.h"
1045-#include "unity-shared/UnitySettings.h"
1046-
1047-namespace unity
1048-{
1049-class WindowButtons : public nux::HLayout, public debug::Introspectable
1050-{
1051- // These are the [close][minimize][restore] buttons on the panel when there
1052- // is a maximized window
1053-
1054-public:
1055- WindowButtons();
1056-
1057- nux::Property<int> monitor;
1058- nux::Property<Window> controlled_window;
1059- nux::Property<double> opacity;
1060- nux::Property<bool> focused;
1061-
1062- virtual nux::Area* FindAreaUnderMouse(const nux::Point& mouse_pos, nux::NuxEventType event_type);
1063-
1064- sigc::signal<void> close_clicked;
1065- sigc::signal<void> minimize_clicked;
1066- sigc::signal<void> restore_clicked;
1067- sigc::signal<void> maximize_clicked;
1068- sigc::signal<void, int, int, int, int, unsigned long, unsigned long> mouse_move;
1069- sigc::signal<void, int, int, unsigned long, unsigned long> mouse_enter;
1070- sigc::signal<void, int, int, unsigned long, unsigned long> mouse_leave;
1071-
1072-protected:
1073- std::string GetName() const;
1074- void AddProperties(GVariantBuilder* builder);
1075-
1076-private:
1077- void OnCloseClicked(nux::Button *button);
1078- void OnMinimizeClicked(nux::Button *button);
1079- void OnRestoreClicked(nux::Button *button);
1080- void OnMaximizeClicked(nux::Button *button);
1081- void OnOverlayShown(GVariant* data);
1082- void OnOverlayHidden(GVariant* data);
1083- void OnDashSettingsUpdated(FormFactor form_factor);
1084- void OnControlledWindowChanged(Window xid);
1085- bool OpacitySetter(double& target, double new_value);
1086-
1087- std::string active_overlay_;
1088- UBusManager ubus_manager_;
1089-};
1090-}
1091-
1092-#endif
1093
1094=== modified file 'tests/autopilot/unity/tests/test_panel.py'
1095--- tests/autopilot/unity/tests/test_panel.py 2013-01-25 09:49:47 +0000
1096+++ tests/autopilot/unity/tests/test_panel.py 2013-01-28 20:54:23 +0000
1097@@ -298,6 +298,22 @@
1098 self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(True)))
1099 self.assertWinButtonsInOverlayMode(True)
1100
1101+ def test_window_buttons_work_in_dash_after_launcher_resize(self):
1102+ """When the launcher icons are resized, the window
1103+ buttons must still work in the dash."""
1104+
1105+ self.set_unity_option("icon_size", 25)
1106+ self.dash.ensure_visible()
1107+ self.addCleanup(self.dash.ensure_hidden)
1108+
1109+ dash_max = self.dash.view.dash_maximized
1110+ if dash_max:
1111+ self.panel.window_buttons.maximize.mouse_click()
1112+ else:
1113+ self.panel.window_buttons.unmaximize.mouse_click()
1114+
1115+ self.assertThat(dash_max, Eventually(Equals(self.dash.view.dash_maximized)))
1116+
1117 def test_window_buttons_show_with_hud(self):
1118 """Window buttons must be shown when the HUD is open."""
1119 self.hud.ensure_visible()
1120
1121=== modified file 'tests/test_window_buttons.cpp'
1122--- tests/test_window_buttons.cpp 2012-12-14 17:19:44 +0000
1123+++ tests/test_window_buttons.cpp 2013-01-28 20:54:23 +0000
1124@@ -24,8 +24,8 @@
1125 #include "PanelStyle.h"
1126 #include "StandaloneWindowManager.h"
1127 #include "UnitySettings.h"
1128-#include "WindowButtons.h"
1129-#include "WindowButtonPriv.h"
1130+#include "unity-shared/WindowButtons.h"
1131+#include "unity-shared/WindowButtonPriv.h"
1132
1133 namespace unity
1134 {
1135
1136=== modified file 'unity-shared/CMakeLists.txt'
1137--- unity-shared/CMakeLists.txt 2012-12-19 20:53:12 +0000
1138+++ unity-shared/CMakeLists.txt 2013-01-28 20:54:23 +0000
1139@@ -39,6 +39,7 @@
1140 LayoutSystem.cpp
1141 LineSeparator.cpp
1142 OverlayRenderer.cpp
1143+ OverlayWindowButtons.cpp
1144 PanelStyle.cpp
1145 PlacesVScrollBar.cpp
1146 PlacesOverlayVScrollBar.cpp
1147@@ -61,6 +62,7 @@
1148 UnityWindowView.cpp
1149 UserThumbnailProvider.cpp
1150 VScrollBarOverlayWindow.cpp
1151+ WindowButtons.cpp
1152 WindowManager.cpp
1153 XPathQueryPart.cpp
1154 )
1155
1156=== added file 'unity-shared/OverlayWindowButtons.cpp'
1157--- unity-shared/OverlayWindowButtons.cpp 1970-01-01 00:00:00 +0000
1158+++ unity-shared/OverlayWindowButtons.cpp 2013-01-28 20:54:23 +0000
1159@@ -0,0 +1,76 @@
1160+/*
1161+ * Copyright (C) 2010 Canonical Ltd
1162+ *
1163+ * This program is free software: you can redistribute it and/or modify
1164+ * it under the terms of the GNU General Public License version 3 as
1165+ * published by the Free Software Foundation.
1166+ *
1167+ * This program is distributed in the hope that it will be useful,
1168+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1169+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1170+ * GNU General Public License for more details.
1171+ *
1172+ * You should have received a copy of the GNU General Public License
1173+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1174+ *
1175+ * Authored by: Brandon Schaefer <brandon.schaefer@canonical.com>
1176+ *
1177+ */
1178+
1179+#include "OverlayWindowButtons.h"
1180+#include "PanelStyle.h"
1181+#include "UScreen.h"
1182+
1183+const int MAIN_LEFT_PADDING = 4;
1184+const int MENUBAR_PADDING = 4;
1185+
1186+namespace unity
1187+{
1188+
1189+OverlayWindowButtons::OverlayWindowButtons()
1190+ : nux::BaseWindow("OverlayWindowButtons")
1191+ , window_buttons_(new WindowButtons())
1192+{
1193+ UpdateGeometry();
1194+ SetBackgroundColor(nux::color::Transparent);
1195+}
1196+
1197+void OverlayWindowButtons::UpdateGeometry()
1198+{
1199+ int monitor = unity::UScreen::GetDefault()->GetMonitorWithMouse();
1200+ nux::Geometry const& geo = unity::UScreen::GetDefault()->GetMonitorGeometry(monitor);
1201+
1202+ SetX(geo.x + MAIN_LEFT_PADDING);
1203+ SetY(geo.y + MENUBAR_PADDING);
1204+ SetHeight(panel::Style::Instance().panel_height);
1205+
1206+ window_buttons_->monitor = monitor;
1207+}
1208+
1209+void OverlayWindowButtons::AboutToShow()
1210+{
1211+ UpdateGeometry();
1212+ ShowWindow(true);
1213+ PushToFront();
1214+ QueueDraw();
1215+}
1216+
1217+void OverlayWindowButtons::AboutToHide()
1218+{
1219+ ShowWindow(false);
1220+ PushToBack();
1221+ QueueDraw();
1222+}
1223+
1224+nux::Area* OverlayWindowButtons::FindAreaUnderMouse(nux::Point const& mouse_position,
1225+ nux::NuxEventType event_type)
1226+{
1227+ return window_buttons_->FindAreaUnderMouse(mouse_position, event_type);
1228+}
1229+
1230+void OverlayWindowButtons::Draw(nux::GraphicsEngine& gfx_context, bool force_draw)
1231+{
1232+ window_buttons_->ProcessDraw(gfx_context, true);
1233+}
1234+
1235+} // namespace unity
1236
1237=== added file 'unity-shared/OverlayWindowButtons.h'
1238--- unity-shared/OverlayWindowButtons.h 1970-01-01 00:00:00 +0000
1239+++ unity-shared/OverlayWindowButtons.h 2013-01-28 20:54:23 +0000
1240@@ -0,0 +1,53 @@
1241+/*
1242+ * Copyright (C) 2010 Canonical Ltd
1243+ *
1244+ * This program is free software: you can redistribute it and/or modify
1245+ * it under the terms of the GNU General Public License version 3 as
1246+ * published by the Free Software Foundation.
1247+ *
1248+ * This program is distributed in the hope that it will be useful,
1249+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1250+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1251+ * GNU General Public License for more details.
1252+ *
1253+ * You should have received a copy of the GNU General Public License
1254+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1255+ *
1256+ * Authored by: Brandon Schaefer <brandon.schaefer@canonical.com>
1257+ *
1258+ */
1259+
1260+#ifndef OVERLAY_WINDOW_BUTTONS
1261+#define OVERLAY_WINDOW_BUTTONS
1262+
1263+#include "Nux/Nux.h"
1264+#include "Nux/BaseWindow.h"
1265+
1266+#include "WindowButtons.h"
1267+
1268+namespace unity
1269+{
1270+
1271+class OverlayWindowButtons : public nux::BaseWindow
1272+{
1273+public:
1274+ OverlayWindowButtons();
1275+
1276+ void AboutToShow();
1277+ void AboutToHide();
1278+
1279+ nux::Area* FindAreaUnderMouse(nux::Point const& mouse_position,
1280+ nux::NuxEventType event_type);
1281+
1282+protected:
1283+ void Draw(nux::GraphicsEngine& gfx_context, bool force_draw);
1284+
1285+private:
1286+ void UpdateGeometry();
1287+
1288+ nux::ObjectPtr<WindowButtons> window_buttons_;
1289+};
1290+
1291+} // namespace unity
1292+
1293+#endif // OVERLAY_WINDOW_BUTTONS
1294
1295=== added file 'unity-shared/WindowButtonPriv.h'
1296--- unity-shared/WindowButtonPriv.h 1970-01-01 00:00:00 +0000
1297+++ unity-shared/WindowButtonPriv.h 2013-01-28 20:54:23 +0000
1298@@ -0,0 +1,84 @@
1299+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1300+/*
1301+ * Copyright (C) 2010-2012 Canonical Ltd
1302+ *
1303+ * This program is free software: you can redistribute it and/or modify
1304+ * it under the terms of the GNU General Public License version 3 as
1305+ * published by the Free Software Foundation.
1306+ *
1307+ * This program is distributed in the hope that it will be useful,
1308+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1309+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1310+ * GNU General Public License for more details.
1311+ *
1312+ * You should have received a copy of the GNU General Public License
1313+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1314+ *
1315+ * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
1316+ * Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
1317+ */
1318+
1319+#ifndef WINDOW_BUTTON_PRIVATE_H
1320+#define WINDOW_BUTTON_PRIVATE_H
1321+
1322+#include <Nux/Button.h>
1323+
1324+#include "PanelStyle.h"
1325+#include "UBusWrapper.h"
1326+#include "Introspectable.h"
1327+
1328+namespace unity
1329+{
1330+class WindowButtons;
1331+
1332+namespace internal
1333+{
1334+
1335+class WindowButton : public nux::Button, public debug::Introspectable
1336+{
1337+ // A single window button
1338+public:
1339+ WindowButton(panel::WindowButtonType type);
1340+
1341+ panel::WindowButtonType GetType() const;
1342+ void SetVisualState(nux::ButtonVisualState new_state);
1343+
1344+ nux::RWProperty<bool> enabled;
1345+ nux::Property<bool> overlay_mode;
1346+
1347+protected:
1348+ void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);
1349+ std::string GetName() const;
1350+ void AddProperties(GVariantBuilder* builder);
1351+
1352+private:
1353+ void UpdateSize();
1354+ void LoadImages();
1355+ bool EnabledSetter(bool enabled);
1356+ static nux::ObjectPtr<nux::BaseTexture> GetDashWindowButton(panel::WindowButtonType type, panel::WindowState state);
1357+
1358+ inline WindowButtons* Parent() const
1359+ {
1360+ return static_cast<WindowButtons*>(GetParentObject());
1361+ }
1362+
1363+private:
1364+ panel::WindowButtonType type_;
1365+
1366+ nux::ObjectPtr<nux::BaseTexture> normal_tex_;
1367+ nux::ObjectPtr<nux::BaseTexture> prelight_tex_;
1368+ nux::ObjectPtr<nux::BaseTexture> pressed_tex_;
1369+ nux::ObjectPtr<nux::BaseTexture> unfocused_tex_;
1370+ nux::ObjectPtr<nux::BaseTexture> unfocused_prelight_tex_;
1371+ nux::ObjectPtr<nux::BaseTexture> unfocused_pressed_tex_;
1372+ nux::ObjectPtr<nux::BaseTexture> disabled_tex_;
1373+ nux::ObjectPtr<nux::BaseTexture> normal_dash_tex_;
1374+ nux::ObjectPtr<nux::BaseTexture> prelight_dash_tex_;
1375+ nux::ObjectPtr<nux::BaseTexture> pressed_dash_tex_;
1376+ nux::ObjectPtr<nux::BaseTexture> disabled_dash_tex_;
1377+};
1378+
1379+} // internal namespace
1380+} // unity namespace
1381+
1382+#endif // WINDOW_BUTTON_PRIVATE_H
1383
1384=== added file 'unity-shared/WindowButtons.cpp'
1385--- unity-shared/WindowButtons.cpp 1970-01-01 00:00:00 +0000
1386+++ unity-shared/WindowButtons.cpp 2013-01-28 20:54:23 +0000
1387@@ -0,0 +1,662 @@
1388+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1389+/*
1390+ * Copyright (C) 2010-2012 Canonical Ltd
1391+ *
1392+ * This program is free software: you can redistribute it and/or modify
1393+ * it under the terms of the GNU General Public License version 3 as
1394+ * published by the Free Software Foundation.
1395+ *
1396+ * This program is distributed in the hope that it will be useful,
1397+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1398+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1399+ * GNU General Public License for more details.
1400+ *
1401+ * You should have received a copy of the GNU General Public License
1402+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1403+ *
1404+ * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
1405+ * Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
1406+ */
1407+
1408+#include "config.h"
1409+
1410+#include <Nux/Nux.h>
1411+#include <array>
1412+
1413+#include <UnityCore/GLibWrapper.h>
1414+#include <UnityCore/Variant.h>
1415+
1416+#include "WindowButtons.h"
1417+#include "WindowButtonPriv.h"
1418+
1419+#include "unity-shared/UBusMessages.h"
1420+#include "unity-shared/WindowManager.h"
1421+
1422+namespace unity
1423+{
1424+
1425+namespace internal
1426+{
1427+WindowButton::WindowButton(panel::WindowButtonType type)
1428+ : nux::Button("", NUX_TRACKER_LOCATION)
1429+ , enabled(sigc::mem_fun(this, &WindowButton::IsViewEnabled),
1430+ sigc::mem_fun(this, &WindowButton::EnabledSetter))
1431+ , overlay_mode(false)
1432+ , type_(type)
1433+{
1434+ overlay_mode.changed.connect([this] (bool) { UpdateSize(); QueueDraw(); });
1435+ SetAcceptKeyNavFocusOnMouseDown(false);
1436+ panel::Style::Instance().changed.connect(sigc::mem_fun(this, &WindowButton::LoadImages));
1437+ LoadImages();
1438+}
1439+
1440+void WindowButton::SetVisualState(nux::ButtonVisualState new_state)
1441+{
1442+ if (new_state != visual_state_)
1443+ {
1444+ visual_state_ = new_state;
1445+ QueueDraw();
1446+ }
1447+}
1448+
1449+void WindowButton::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
1450+{
1451+ nux::Geometry const& geo = GetGeometry();
1452+ nux::BaseTexture* tex = nullptr;
1453+
1454+ GfxContext.PushClippingRectangle(geo);
1455+
1456+ if (overlay_mode())
1457+ {
1458+ if (!enabled())
1459+ {
1460+ tex = disabled_dash_tex_.GetPointer();
1461+ }
1462+ else
1463+ {
1464+ switch (visual_state_)
1465+ {
1466+ case nux::VISUAL_STATE_PRESSED:
1467+ tex = pressed_dash_tex_.GetPointer();
1468+ break;
1469+ case nux::VISUAL_STATE_PRELIGHT:
1470+ tex = prelight_dash_tex_.GetPointer();
1471+ break;
1472+ default:
1473+ tex = normal_dash_tex_.GetPointer();
1474+ }
1475+ }
1476+ }
1477+ else if (!enabled())
1478+ {
1479+ tex = disabled_tex_.GetPointer();
1480+ }
1481+ else if (!Parent()->focused())
1482+ {
1483+ switch (visual_state_)
1484+ {
1485+ case nux::VISUAL_STATE_PRESSED:
1486+ tex = unfocused_pressed_tex_.GetPointer();
1487+ break;
1488+ case nux::VISUAL_STATE_PRELIGHT:
1489+ tex = unfocused_prelight_tex_.GetPointer();
1490+ break;
1491+ default:
1492+ tex = unfocused_tex_.GetPointer();
1493+ }
1494+ }
1495+ else
1496+ {
1497+ switch (visual_state_)
1498+ {
1499+ case nux::VISUAL_STATE_PRESSED:
1500+ tex = pressed_tex_.GetPointer();
1501+ break;
1502+ case nux::VISUAL_STATE_PRELIGHT:
1503+ tex = prelight_tex_.GetPointer();
1504+ break;
1505+ default:
1506+ tex = normal_tex_.GetPointer();
1507+ }
1508+ }
1509+
1510+ if (tex)
1511+ {
1512+ nux::TexCoordXForm texxform;
1513+ GfxContext.QRP_1Tex(geo.x, geo.y, geo.width, geo.height,
1514+ tex->GetDeviceTexture(), texxform,
1515+ nux::color::White * Parent()->opacity());
1516+ }
1517+
1518+ GfxContext.PopClippingRectangle();
1519+}
1520+
1521+void WindowButton::UpdateSize()
1522+{
1523+ int panel_height = panel::Style::Instance().panel_height;
1524+ nux::BaseTexture* tex;
1525+ tex = (overlay_mode()) ? normal_dash_tex_.GetPointer() : normal_tex_.GetPointer();
1526+ int width = 0;
1527+ int height = 0;
1528+
1529+ if (tex)
1530+ {
1531+ width = std::min(panel_height, tex->GetWidth());
1532+ height = std::min(panel_height, tex->GetHeight());
1533+ }
1534+
1535+ SetMinMaxSize(width, height);
1536+}
1537+
1538+void WindowButton::LoadImages()
1539+{
1540+ panel::Style& style = panel::Style::Instance();
1541+
1542+ normal_tex_ = style.GetWindowButton(type_, panel::WindowState::NORMAL);
1543+ prelight_tex_ = style.GetWindowButton(type_, panel::WindowState::PRELIGHT);
1544+ pressed_tex_ = style.GetWindowButton(type_, panel::WindowState::PRESSED);
1545+ unfocused_tex_ = style.GetWindowButton(type_, panel::WindowState::UNFOCUSED);
1546+ disabled_tex_ = style.GetWindowButton(type_, panel::WindowState::DISABLED);
1547+ unfocused_prelight_tex_ = style.GetWindowButton(type_, panel::WindowState::UNFOCUSED_PRELIGHT);
1548+ unfocused_pressed_tex_ = style.GetWindowButton(type_, panel::WindowState::UNFOCUSED_PRESSED);
1549+ normal_dash_tex_ = GetDashWindowButton(type_, panel::WindowState::NORMAL);
1550+ prelight_dash_tex_ = GetDashWindowButton(type_, panel::WindowState::PRELIGHT);
1551+ pressed_dash_tex_ = GetDashWindowButton(type_, panel::WindowState::PRESSED);
1552+ disabled_dash_tex_ = GetDashWindowButton(type_, panel::WindowState::DISABLED);
1553+
1554+ UpdateSize();
1555+ QueueDraw();
1556+}
1557+
1558+nux::ObjectPtr<nux::BaseTexture> WindowButton::GetDashWindowButton(panel::WindowButtonType type, panel::WindowState state)
1559+{
1560+ nux::ObjectPtr<nux::BaseTexture> texture;
1561+ static const std::array<std::string, 4> names = {{ "close_dash", "minimize_dash", "unmaximize_dash", "maximize_dash" }};
1562+ static const std::array<std::string, 4> states = {{ "", "_prelight", "_pressed", "_disabled" }};
1563+
1564+ std::string subpath = names[static_cast<int>(type)] + states[static_cast<int>(state)] + ".png";
1565+
1566+ glib::String filename(g_build_filename(PKGDATADIR, subpath.c_str(), NULL));
1567+ texture.Adopt(nux::CreateTexture2DFromFile(filename, -1, true));
1568+
1569+ if (!texture)
1570+ texture = panel::Style::Instance().GetFallbackWindowButton(type, state);
1571+
1572+ return texture;
1573+}
1574+
1575+panel::WindowButtonType WindowButton::GetType() const
1576+{
1577+ return type_;
1578+}
1579+
1580+bool WindowButton::EnabledSetter(bool new_value)
1581+{
1582+ if (enabled() == new_value)
1583+ return false;
1584+
1585+ SetEnableView(new_value);
1586+ QueueDraw();
1587+ return true;
1588+}
1589+
1590+std::string WindowButton::GetName() const
1591+{
1592+ return "WindowButton";
1593+}
1594+
1595+void WindowButton::AddProperties(GVariantBuilder* builder)
1596+{
1597+ std::string type_name;
1598+ std::string state_name;
1599+
1600+ switch (type_)
1601+ {
1602+ case panel::WindowButtonType::CLOSE:
1603+ type_name = "Close";
1604+ break;
1605+ case panel::WindowButtonType::MINIMIZE:
1606+ type_name = "Minimize";
1607+ break;
1608+ case panel::WindowButtonType::MAXIMIZE:
1609+ type_name = "Maximize";
1610+ break;
1611+ case panel::WindowButtonType::UNMAXIMIZE:
1612+ type_name = "Unmaximize";
1613+ break;
1614+ }
1615+
1616+ switch (visual_state_)
1617+ {
1618+ case nux::VISUAL_STATE_PRESSED:
1619+ state_name = "pressed";
1620+ break;
1621+ case nux::VISUAL_STATE_PRELIGHT:
1622+ state_name = "prelight";
1623+ break;
1624+ default:
1625+ state_name = "normal";
1626+ }
1627+
1628+ variant::BuilderWrapper(builder).add(GetAbsoluteGeometry())
1629+ .add("type", type_name)
1630+ .add("visible", IsVisible() && Parent()->opacity() != 0.0f)
1631+ .add("sensitive", Parent()->GetInputEventSensitivity())
1632+ .add("enabled", enabled())
1633+ .add("visual_state", state_name)
1634+ .add("opacity", Parent()->opacity())
1635+ .add("focused", Parent()->focused())
1636+ .add("overlay_mode", overlay_mode());
1637+}
1638+} // Internal Namespace
1639+
1640+
1641+WindowButtons::WindowButtons()
1642+ : HLayout("", NUX_TRACKER_LOCATION)
1643+ , monitor(0)
1644+ , controlled_window(0)
1645+ , opacity(1.0f, sigc::mem_fun(this, &WindowButtons::OpacitySetter))
1646+ , focused(true)
1647+{
1648+ controlled_window.changed.connect(sigc::mem_fun(this, &WindowButtons::OnControlledWindowChanged));
1649+ focused.changed.connect(sigc::hide(sigc::mem_fun(this, &WindowButtons::QueueDraw)));
1650+
1651+ auto lambda_enter = [&](int x, int y, unsigned long button_flags, unsigned long key_flags)
1652+ {
1653+ mouse_enter.emit(x, y, button_flags, key_flags);
1654+ };
1655+
1656+ auto lambda_leave = [&](int x, int y, unsigned long button_flags, unsigned long key_flags)
1657+ {
1658+ mouse_leave.emit(x, y, button_flags, key_flags);
1659+ };
1660+
1661+ auto lambda_moved = [&](int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags)
1662+ {
1663+ mouse_move.emit(x, y, dx, dy, button_flags, key_flags);
1664+ };
1665+
1666+ internal::WindowButton* but;
1667+ but = new internal::WindowButton(panel::WindowButtonType::CLOSE);
1668+ AddView(but, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX);
1669+ AddChild(but);
1670+ but->click.connect(sigc::mem_fun(this, &WindowButtons::OnCloseClicked));
1671+ but->mouse_enter.connect(lambda_enter);
1672+ but->mouse_leave.connect(lambda_leave);
1673+ but->mouse_move.connect(lambda_moved);
1674+
1675+ but = new internal::WindowButton(panel::WindowButtonType::MINIMIZE);
1676+ AddView(but, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX);
1677+ AddChild(but);
1678+ but->click.connect(sigc::mem_fun(this, &WindowButtons::OnMinimizeClicked));
1679+ but->mouse_enter.connect(lambda_enter);
1680+ but->mouse_leave.connect(lambda_leave);
1681+ but->mouse_move.connect(lambda_moved);
1682+
1683+ but = new internal::WindowButton(panel::WindowButtonType::UNMAXIMIZE);
1684+ AddView(but, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX);
1685+ AddChild(but);
1686+ but->click.connect(sigc::mem_fun(this, &WindowButtons::OnRestoreClicked));
1687+ but->mouse_enter.connect(lambda_enter);
1688+ but->mouse_leave.connect(lambda_leave);
1689+ but->mouse_move.connect(lambda_moved);
1690+
1691+ but = new internal::WindowButton(panel::WindowButtonType::MAXIMIZE);
1692+ AddView(but, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX);
1693+ AddChild(but);
1694+ but->click.connect(sigc::mem_fun(this, &WindowButtons::OnMaximizeClicked));
1695+ but->mouse_enter.connect(lambda_enter);
1696+ but->mouse_leave.connect(lambda_leave);
1697+ but->mouse_move.connect(lambda_moved);
1698+ but->SetVisible(false);
1699+
1700+ SetContentDistribution(nux::MAJOR_POSITION_START);
1701+
1702+ ubus_manager_.RegisterInterest(UBUS_OVERLAY_SHOWN, sigc::mem_fun(this, &WindowButtons::OnOverlayShown));
1703+ ubus_manager_.RegisterInterest(UBUS_OVERLAY_HIDDEN, sigc::mem_fun(this, &WindowButtons::OnOverlayHidden));
1704+ Settings::Instance().form_factor.changed.connect(sigc::mem_fun(this, &WindowButtons::OnDashSettingsUpdated));
1705+}
1706+
1707+nux::Area* WindowButtons::FindAreaUnderMouse(const nux::Point& mouse, nux::NuxEventType event_type)
1708+{
1709+ if (!GetInputEventSensitivity())
1710+ return nullptr;
1711+
1712+ /* The first button should be clickable on the left space too, to
1713+ * make Fitts happy. All also on their top side. See bug #839690 */
1714+ bool first_found = false;
1715+
1716+ for (auto area : GetChildren())
1717+ {
1718+ if (area->IsVisible())
1719+ {
1720+ nux::Geometry const& geo = area->GetAbsoluteGeometry();
1721+
1722+ if (!first_found)
1723+ {
1724+ first_found = true;
1725+
1726+ if (mouse.x < geo.x && mouse.y < (geo.y + geo.height))
1727+ return area;
1728+ }
1729+
1730+ if (geo.IsPointInside(mouse.x, mouse.y))
1731+ return area;
1732+
1733+ if (mouse.x >= geo.x && mouse.x <= (geo.x + geo.width) && mouse.y <= geo.y)
1734+ return area;
1735+ }
1736+ }
1737+
1738+ return nullptr;
1739+}
1740+
1741+void WindowButtons::OnCloseClicked(nux::Button *button)
1742+{
1743+ auto win_button = dynamic_cast<internal::WindowButton*>(button);
1744+
1745+ if (!win_button || !win_button->enabled())
1746+ return;
1747+
1748+ if (win_button->overlay_mode())
1749+ {
1750+ ubus_manager_.SendMessage(UBUS_PLACE_VIEW_CLOSE_REQUEST);
1751+ }
1752+ else
1753+ {
1754+ WindowManager::Default().Close(controlled_window());
1755+ }
1756+
1757+ close_clicked.emit();
1758+}
1759+
1760+void WindowButtons::OnMinimizeClicked(nux::Button *button)
1761+{
1762+ auto win_button = dynamic_cast<internal::WindowButton*>(button);
1763+
1764+ if (!win_button || !win_button->enabled())
1765+ return;
1766+
1767+ if (!win_button->overlay_mode())
1768+ WindowManager::Default().Minimize(controlled_window());
1769+
1770+ minimize_clicked.emit();
1771+}
1772+
1773+void WindowButtons::OnRestoreClicked(nux::Button *button)
1774+{
1775+ auto win_button = dynamic_cast<internal::WindowButton*>(button);
1776+
1777+ if (!win_button || !win_button->enabled())
1778+ return;
1779+
1780+ if (win_button->overlay_mode())
1781+ {
1782+ Settings::Instance().form_factor = FormFactor::DESKTOP;
1783+ }
1784+ else
1785+ {
1786+ WindowManager& wm = WindowManager::Default();
1787+ Window to_restore = controlled_window();
1788+
1789+ wm.Raise(to_restore);
1790+ wm.Activate(to_restore);
1791+ wm.Restore(to_restore);
1792+ }
1793+
1794+ restore_clicked.emit();
1795+}
1796+
1797+void WindowButtons::OnMaximizeClicked(nux::Button *button)
1798+{
1799+ auto win_button = dynamic_cast<internal::WindowButton*>(button);
1800+
1801+ if (!win_button || !win_button->enabled())
1802+ return;
1803+
1804+ if (win_button->overlay_mode())
1805+ {
1806+ Settings::Instance().form_factor = FormFactor::NETBOOK;
1807+ }
1808+
1809+ maximize_clicked.emit();
1810+}
1811+
1812+void WindowButtons::OnOverlayShown(GVariant* data)
1813+{
1814+ internal::WindowButton* maximize_button = nullptr;
1815+ internal::WindowButton* restore_button = nullptr;
1816+ glib::String overlay_identity;
1817+ gboolean can_maximise = FALSE;
1818+ gint32 overlay_monitor = 0;
1819+ g_variant_get(data, UBUS_OVERLAY_FORMAT_STRING,
1820+ &overlay_identity, &can_maximise, &overlay_monitor);
1821+
1822+ if (overlay_monitor != monitor())
1823+ {
1824+ for (auto area : GetChildren())
1825+ {
1826+ auto button = dynamic_cast<internal::WindowButton*>(area);
1827+
1828+ if (button)
1829+ button->enabled = false;
1830+ }
1831+
1832+ return;
1833+ }
1834+
1835+ active_overlay_ = overlay_identity.Str();
1836+
1837+ for (auto area : GetChildren())
1838+ {
1839+ auto button = dynamic_cast<internal::WindowButton*>(area);
1840+
1841+ if (button)
1842+ {
1843+ if (button->GetType() == panel::WindowButtonType::CLOSE)
1844+ button->enabled = true;
1845+
1846+ if (button->GetType() == panel::WindowButtonType::UNMAXIMIZE)
1847+ restore_button = button;
1848+
1849+ if (button->GetType() == panel::WindowButtonType::MAXIMIZE)
1850+ maximize_button = button;
1851+
1852+ if (button->GetType() == panel::WindowButtonType::MINIMIZE)
1853+ button->enabled = false;
1854+
1855+ button->overlay_mode = true;
1856+ }
1857+ }
1858+
1859+ if (restore_button && maximize_button)
1860+ {
1861+ Settings &dash_settings = Settings::Instance();
1862+ bool maximizable = (dash_settings.form_factor() == FormFactor::DESKTOP);
1863+
1864+ restore_button->enabled = can_maximise;
1865+ maximize_button->enabled = can_maximise;
1866+
1867+ if (maximizable != maximize_button->IsVisible())
1868+ {
1869+ if (maximize_button->IsVisible())
1870+ restore_button->SetVisualState(maximize_button->GetVisualState());
1871+ else if (restore_button->IsVisible())
1872+ maximize_button->SetVisualState(restore_button->GetVisualState());
1873+
1874+ restore_button->SetVisible(!maximizable);
1875+ maximize_button->SetVisible(maximizable);
1876+
1877+ QueueDraw();
1878+ }
1879+ }
1880+}
1881+
1882+void WindowButtons::OnOverlayHidden(GVariant* data)
1883+{
1884+ internal::WindowButton* maximize_button = nullptr;
1885+ internal::WindowButton* restore_button = nullptr;
1886+
1887+ glib::String overlay_identity;
1888+ gboolean can_maximise = FALSE;
1889+ gint32 overlay_monitor = 0;
1890+ g_variant_get(data, UBUS_OVERLAY_FORMAT_STRING,
1891+ &overlay_identity, &can_maximise, &overlay_monitor);
1892+
1893+ if (overlay_monitor != monitor())
1894+ {
1895+ for (auto area : GetChildren())
1896+ {
1897+ auto button = dynamic_cast<internal::WindowButton*>(area);
1898+
1899+ if (button)
1900+ button->enabled = true;
1901+ }
1902+ }
1903+
1904+ if (active_overlay_ != overlay_identity.Str())
1905+ return;
1906+
1907+ active_overlay_ = "";
1908+
1909+ WindowManager& wm = WindowManager::Default();
1910+ for (auto area : GetChildren())
1911+ {
1912+ auto button = dynamic_cast<internal::WindowButton*>(area);
1913+
1914+ if (button)
1915+ {
1916+ if (controlled_window())
1917+ {
1918+ if (button->GetType() == panel::WindowButtonType::CLOSE)
1919+ button->enabled = wm.IsWindowClosable(controlled_window());
1920+
1921+ if (button->GetType() == panel::WindowButtonType::MINIMIZE)
1922+ button->enabled = wm.IsWindowMinimizable(controlled_window());
1923+ }
1924+
1925+ if (button->GetType() == panel::WindowButtonType::UNMAXIMIZE)
1926+ restore_button = button;
1927+
1928+ if (button->GetType() == panel::WindowButtonType::MAXIMIZE)
1929+ maximize_button = button;
1930+
1931+ button->overlay_mode = false;
1932+ }
1933+ }
1934+
1935+ if (restore_button && maximize_button)
1936+ {
1937+ restore_button->enabled = true;
1938+ maximize_button->enabled = true;
1939+
1940+ if (!restore_button->IsVisible())
1941+ {
1942+ restore_button->SetVisualState(maximize_button->GetVisualState());
1943+
1944+ restore_button->SetVisible(true);
1945+ maximize_button->SetVisible(false);
1946+
1947+ QueueDraw();
1948+ }
1949+ }
1950+}
1951+
1952+void WindowButtons::OnDashSettingsUpdated(FormFactor form_factor)
1953+{
1954+ internal::WindowButton* maximize_button = nullptr;
1955+ internal::WindowButton* restore_button = nullptr;
1956+
1957+ for (auto area : GetChildren())
1958+ {
1959+ auto button = dynamic_cast<internal::WindowButton*>(area);
1960+
1961+ if (button)
1962+ {
1963+ if (!button->overlay_mode())
1964+ break;
1965+
1966+ if (button->GetType() == panel::WindowButtonType::UNMAXIMIZE)
1967+ restore_button = button;
1968+
1969+ if (button->GetType() == panel::WindowButtonType::MAXIMIZE)
1970+ maximize_button = button;
1971+
1972+ if (restore_button && maximize_button)
1973+ break;
1974+ }
1975+ }
1976+
1977+ if (restore_button && restore_button->overlay_mode() && maximize_button)
1978+ {
1979+ bool maximizable = (form_factor == FormFactor::DESKTOP);
1980+
1981+ if (maximizable != maximize_button->IsVisible())
1982+ {
1983+ if (maximize_button->IsVisible())
1984+ restore_button->SetVisualState(maximize_button->GetVisualState());
1985+ else if (restore_button->IsVisible())
1986+ maximize_button->SetVisualState(restore_button->GetVisualState());
1987+
1988+ restore_button->SetVisible(!maximizable);
1989+ maximize_button->SetVisible(maximizable);
1990+
1991+ QueueRelayout();
1992+ }
1993+ }
1994+}
1995+
1996+bool WindowButtons::OpacitySetter(double& target, double new_value)
1997+{
1998+ double opacity = CLAMP(new_value, 0.0f, 1.0f);
1999+
2000+ if (opacity != target)
2001+ {
2002+ target = opacity;
2003+ SetInputEventSensitivity(opacity != 0.0f);
2004+ QueueDraw();
2005+
2006+ return true;
2007+ }
2008+
2009+ return false;
2010+}
2011+
2012+void WindowButtons::OnControlledWindowChanged(Window xid)
2013+{
2014+ if (xid && active_overlay_.empty())
2015+ {
2016+ WindowManager& wm = WindowManager::Default();
2017+ for (auto area : GetChildren())
2018+ {
2019+ auto button = dynamic_cast<internal::WindowButton*>(area);
2020+
2021+ if (!button)
2022+ continue;
2023+
2024+ if (button->GetType() == panel::WindowButtonType::CLOSE)
2025+ button->enabled = wm.IsWindowClosable(xid);
2026+
2027+ if (button->GetType() == panel::WindowButtonType::MINIMIZE)
2028+ button->enabled = wm.IsWindowMinimizable(xid);
2029+ }
2030+ }
2031+}
2032+
2033+std::string WindowButtons::GetName() const
2034+{
2035+ return "WindowButtons";
2036+}
2037+
2038+void WindowButtons::AddProperties(GVariantBuilder* builder)
2039+{
2040+ variant::BuilderWrapper(builder).add(GetAbsoluteGeometry())
2041+ .add("monitor", monitor())
2042+ .add("opacity", opacity())
2043+ .add("visible", opacity() != 0.0f)
2044+ .add("sensitive", GetInputEventSensitivity())
2045+ .add("focused", focused())
2046+ .add("controlled_window", controlled_window());
2047+}
2048+
2049+} // unity namespace
2050
2051=== added file 'unity-shared/WindowButtons.h'
2052--- unity-shared/WindowButtons.h 1970-01-01 00:00:00 +0000
2053+++ unity-shared/WindowButtons.h 2013-01-28 20:54:23 +0000
2054@@ -0,0 +1,77 @@
2055+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2056+/*
2057+ * Copyright (C) 2010-2012 Canonical Ltd
2058+ *
2059+ * This program is free software: you can redistribute it and/or modify
2060+ * it under the terms of the GNU General Public License version 3 as
2061+ * published by the Free Software Foundation.
2062+ *
2063+ * This program is distributed in the hope that it will be useful,
2064+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2065+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2066+ * GNU General Public License for more details.
2067+ *
2068+ * You should have received a copy of the GNU General Public License
2069+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2070+ *
2071+ * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
2072+ * Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
2073+ */
2074+
2075+#ifndef WINDOW_BUTTONS_H
2076+#define WINDOW_BUTTONS_H
2077+
2078+#include <Nux/HLayout.h>
2079+#include <Nux/Button.h>
2080+
2081+#include "Introspectable.h"
2082+#include "UBusWrapper.h"
2083+#include "UnitySettings.h"
2084+#include "PluginAdapter.h"
2085+
2086+namespace unity
2087+{
2088+class WindowButtons : public nux::HLayout, public debug::Introspectable
2089+{
2090+ // These are the [close][minimize][restore] buttons on the panel when there
2091+ // is a maximized window
2092+
2093+public:
2094+ WindowButtons();
2095+
2096+ nux::Property<int> monitor;
2097+ nux::Property<Window> controlled_window;
2098+ nux::Property<double> opacity;
2099+ nux::Property<bool> focused;
2100+
2101+ virtual nux::Area* FindAreaUnderMouse(const nux::Point& mouse_pos, nux::NuxEventType event_type);
2102+
2103+ sigc::signal<void> close_clicked;
2104+ sigc::signal<void> minimize_clicked;
2105+ sigc::signal<void> restore_clicked;
2106+ sigc::signal<void> maximize_clicked;
2107+ sigc::signal<void, int, int, int, int, unsigned long, unsigned long> mouse_move;
2108+ sigc::signal<void, int, int, unsigned long, unsigned long> mouse_enter;
2109+ sigc::signal<void, int, int, unsigned long, unsigned long> mouse_leave;
2110+
2111+protected:
2112+ std::string GetName() const;
2113+ void AddProperties(GVariantBuilder* builder);
2114+
2115+private:
2116+ void OnCloseClicked(nux::Button *button);
2117+ void OnMinimizeClicked(nux::Button *button);
2118+ void OnRestoreClicked(nux::Button *button);
2119+ void OnMaximizeClicked(nux::Button *button);
2120+ void OnOverlayShown(GVariant* data);
2121+ void OnOverlayHidden(GVariant* data);
2122+ void OnDashSettingsUpdated(FormFactor form_factor);
2123+ void OnControlledWindowChanged(Window xid);
2124+ bool OpacitySetter(double& target, double new_value);
2125+
2126+ std::string active_overlay_;
2127+ UBusManager ubus_manager_;
2128+};
2129+}
2130+
2131+#endif