Merge lp:~nick-dedekind/unity/lp857422.dash-mouse-steal into lp:unity

Proposed by Nick Dedekind
Status: Merged
Approved by: Brandon Schaefer
Approved revision: no longer in the source branch.
Merged at revision: 2715
Proposed branch: lp:~nick-dedekind/unity/lp857422.dash-mouse-steal
Merge into: lp:unity
Diff against target: 948 lines (+329/-111)
17 files modified
dash/DashController.cpp (+30/-13)
dash/DashController.h (+4/-5)
dash/DashView.cpp (+5/-0)
dash/DashView.h (+2/-0)
hud/HudAbstractView.h (+3/-1)
hud/HudController.cpp (+42/-11)
hud/HudController.h (+7/-3)
hud/HudView.cpp (+60/-65)
hud/HudView.h (+4/-5)
hud/StandaloneHud.cpp (+1/-4)
plugins/unityshell/src/unityshell.cpp (+45/-3)
plugins/unityshell/src/unityshell.h (+2/-0)
tests/autopilot/unity/emulators/dash.py (+4/-0)
tests/autopilot/unity/tests/test_dash.py (+33/-0)
tests/autopilot/unity/tests/test_hud.py (+32/-0)
tests/test_hud_controller.cpp (+2/-1)
unity-shared/ResizingBaseWindow.h (+53/-0)
To merge this branch: bzr merge lp:~nick-dedekind/unity/lp857422.dash-mouse-steal
Reviewer Review Type Date Requested Status
Brandon Schaefer (community) Approve
Review via email: mp+124221@code.launchpad.net

Commit message

Dash/Hud no longer steal mouse events outside their content area. Better draw handling of hud animation.

Description of the change

Resize input window relative to the size of the dash/hud. Now only encompasses the required content area.
Added some draw performance fixes for the hud. (only redraw when needed)

To post a comment you must log in.
Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

This is a bit of a cheeky fix.
The problem causing the events to be stolen is that the base window of the dash/hud takes the monitor geometry as it's own. The XInputWindow which is responsible for receiving the XEvents has the same geometry.

This branch side-steps this issue by resizing the XInputWindow to match the actual size of the dash/hud, so if a user clicks outside the dash, it doesnt receive the click.

Revision history for this message
Omer Akram (om26er) wrote :

Has conflicts?

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

Fixed conflicts.

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

I checked with trunk and the launcher looks the same as trunk so we are good there :).

Other then that everything looks awesome :). The tests worked for me, and it works manually for me as well. The launcher works, the Window buttons works...

soo this branch looks good to me :)

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'dash/DashController.cpp'
--- dash/DashController.cpp 2012-09-17 10:00:38 +0000
+++ dash/DashController.cpp 2012-09-18 17:41:27 +0000
@@ -66,13 +66,13 @@
66 , timeline_animator_(90)66 , timeline_animator_(90)
67 , dbus_connect_cancellable_(g_cancellable_new())67 , dbus_connect_cancellable_(g_cancellable_new())
68{68{
69 SetupRelayoutCallbacks();
70 RegisterUBusInterests();69 RegisterUBusInterests();
7170
72 ensure_timeout_.Run([&]() { EnsureDash(); return false; });71 ensure_timeout_.Run([&]() { EnsureDash(); return false; });
73 timeline_animator_.animation_updated.connect(sigc::mem_fun(this, &Controller::OnViewShowHideFrame));72 timeline_animator_.animation_updated.connect(sigc::mem_fun(this, &Controller::OnViewShowHideFrame));
7473
75 SetupWindow();74 SetupWindow();
75 UScreen::GetDefault()->changed.connect([&] (int, std::vector<nux::Geometry>&) { Relayout(true); });
7676
77 Settings::Instance().changed.connect([&]()77 Settings::Instance().changed.connect([&]()
78 {78 {
@@ -97,7 +97,12 @@
9797
98void Controller::SetupWindow()98void Controller::SetupWindow()
99{99{
100 window_ = new nux::BaseWindow(dash::window_title);100 window_ = new ResizingBaseWindow(dash::window_title, [this](nux::Geometry const& geo)
101 {
102 if (view_)
103 return GetInputWindowGeometry();
104 return geo;
105 });
101 window_->SetBackgroundColor(nux::Color(0.0f, 0.0f, 0.0f, 0.0f));106 window_->SetBackgroundColor(nux::Color(0.0f, 0.0f, 0.0f, 0.0f));
102 window_->SetConfigureNotifyCallback(&Controller::OnWindowConfigure, this);107 window_->SetConfigureNotifyCallback(&Controller::OnWindowConfigure, this);
103 window_->ShowWindow(false);108 window_->ShowWindow(false);
@@ -122,19 +127,13 @@
122 layout->SetContentDistribution(nux::eStackLeft);127 layout->SetContentDistribution(nux::eStackLeft);
123 layout->SetVerticalExternalMargin(0);128 layout->SetVerticalExternalMargin(0);
124 layout->SetHorizontalExternalMargin(0);129 layout->SetHorizontalExternalMargin(0);
125
126 window_->SetLayout(layout);130 window_->SetLayout(layout);
131
132 window_->UpdateInputWindowGeometry();
133
127 ubus_manager_.UnregisterInterest(UBUS_PLACE_ENTRY_ACTIVATE_REQUEST);134 ubus_manager_.UnregisterInterest(UBUS_PLACE_ENTRY_ACTIVATE_REQUEST);
128}135}
129136
130void Controller::SetupRelayoutCallbacks()
131{
132 GdkScreen* screen = gdk_screen_get_default();
133 auto relayout_cb = sigc::mem_fun(this, &Controller::Relayout);
134 sig_manager_.Add<void, GdkScreen*>(screen, "monitors-changed", relayout_cb);
135 sig_manager_.Add<void, GdkScreen*>(screen, "size-changed", relayout_cb);
136}
137
138void Controller::RegisterUBusInterests()137void Controller::RegisterUBusInterests()
139{138{
140 ubus_manager_.RegisterInterest(UBUS_DASH_EXTERNAL_ACTIVATION,139 ubus_manager_.RegisterInterest(UBUS_DASH_EXTERNAL_ACTIVATION,
@@ -218,13 +217,19 @@
218 monitor_geo.height - panel_style.panel_height);217 monitor_geo.height - panel_style.panel_height);
219}218}
220219
221void Controller::Relayout(GdkScreen*screen)220void Controller::Relayout(bool check_monitor)
222{221{
223 EnsureDash();222 EnsureDash();
224223
224 if (check_monitor)
225 {
226 monitor_ = CLAMP(GetIdealMonitor(), 0, static_cast<int>(UScreen::GetDefault()->GetMonitors().size()-1));
227 printf("relayout on monitor:%d, monitor count:%d\n", monitor_, static_cast<int>(UScreen::GetDefault()->GetMonitors().size()));
228 }
229
225 nux::Geometry geo = GetIdealWindowGeometry();230 nux::Geometry geo = GetIdealWindowGeometry();
231 view_->Relayout();
226 window_->SetGeometry(geo);232 window_->SetGeometry(geo);
227 view_->Relayout();
228 panel::Style &panel_style = panel::Style::Instance();233 panel::Style &panel_style = panel::Style::Instance();
229 view_->SetMonitorOffset(launcher_width, panel_style.panel_height);234 view_->SetMonitorOffset(launcher_width, panel_style.panel_height);
230}235}
@@ -291,7 +296,11 @@
291 window_->ShowWindow(true);296 window_->ShowWindow(true);
292 window_->PushToFront();297 window_->PushToFront();
293 if (!Settings::Instance().is_standalone) // in standalone mode, we do not need an input window. we are one.298 if (!Settings::Instance().is_standalone) // in standalone mode, we do not need an input window. we are one.
299 {
294 window_->EnableInputWindow(true, dash::window_title, true, false);300 window_->EnableInputWindow(true, dash::window_title, true, false);
301 // update the input window geometry. This causes the input window to match the actual size of the dash.
302 window_->UpdateInputWindowGeometry();
303 }
295 window_->SetInputFocus();304 window_->SetInputFocus();
296 window_->CaptureMouseDownAnyWhereElse(true);305 window_->CaptureMouseDownAnyWhereElse(true);
297 window_->QueueDraw();306 window_->QueueDraw();
@@ -445,6 +454,14 @@
445 }454 }
446}455}
447456
457nux::Geometry Controller::GetInputWindowGeometry()
458{
459 EnsureDash();
460 nux::Geometry const& window_geo(window_->GetGeometry());
461 nux::Geometry const& view_content_geo(view_->GetContentGeometry());
462 return nux::Geometry(window_geo.x, window_geo.y, view_content_geo.width, view_content_geo.height);
463}
464
448465
449}466}
450}467}
451468
=== modified file 'dash/DashController.h'
--- dash/DashController.h 2012-09-13 10:56:42 +0000
+++ dash/DashController.h 2012-09-18 17:41:27 +0000
@@ -27,12 +27,12 @@
27#include <NuxCore/Property.h>27#include <NuxCore/Property.h>
28#include <NuxGraphics/GraphicsEngine.h>28#include <NuxGraphics/GraphicsEngine.h>
29#include <Nux/Nux.h>29#include <Nux/Nux.h>
30#include <Nux/BaseWindow.h>
3130
32#include "DashView.h"31#include "DashView.h"
33#include "unity-shared/Animator.h"32#include "unity-shared/Animator.h"
34#include "unity-shared/Introspectable.h"33#include "unity-shared/Introspectable.h"
35#include "unity-shared/UBusWrapper.h"34#include "unity-shared/UBusWrapper.h"
35#include "unity-shared/ResizingBaseWindow.h"
3636
37namespace unity37namespace unity
38{38{
@@ -60,6 +60,7 @@
60 void HideDash(bool restore_focus = true);60 void HideDash(bool restore_focus = true);
6161
62 bool IsVisible() const;62 bool IsVisible() const;
63 nux::Geometry GetInputWindowGeometry();
6364
64protected:65protected:
65 std::string GetName() const;66 std::string GetName() const;
@@ -69,12 +70,11 @@
69 void EnsureDash();70 void EnsureDash();
70 void SetupWindow();71 void SetupWindow();
71 void SetupDashView();72 void SetupDashView();
72 void SetupRelayoutCallbacks();
73 void RegisterUBusInterests();73 void RegisterUBusInterests();
7474
75 nux::Geometry GetIdealWindowGeometry();75 nux::Geometry GetIdealWindowGeometry();
76 int GetIdealMonitor();76 int GetIdealMonitor();
77 void Relayout(GdkScreen*screen=NULL);77 void Relayout(bool check_monitor =false);
7878
79 void OnMouseDownOutsideWindow(int x, int y, unsigned long bflags, unsigned long kflags);79 void OnMouseDownOutsideWindow(int x, int y, unsigned long bflags, unsigned long kflags);
80 void OnScreenUngrabbed();80 void OnScreenUngrabbed();
@@ -96,7 +96,7 @@
96 static void OnWindowConfigure(int width, int height, nux::Geometry& geo, void* data);96 static void OnWindowConfigure(int width, int height, nux::Geometry& geo, void* data);
9797
98private:98private:
99 nux::ObjectPtr<nux::BaseWindow> window_;99 nux::ObjectPtr<ResizingBaseWindow> window_;
100 int monitor_;100 int monitor_;
101101
102 bool visible_;102 bool visible_;
@@ -104,7 +104,6 @@
104 DashView* view_;104 DashView* view_;
105105
106 sigc::connection screen_ungrabbed_slot_;106 sigc::connection screen_ungrabbed_slot_;
107 glib::SignalManager sig_manager_;
108 glib::TimeoutSeconds ensure_timeout_;107 glib::TimeoutSeconds ensure_timeout_;
109 Animator timeline_animator_;108 Animator timeline_animator_;
110 UBusManager ubus_manager_;109 UBusManager ubus_manager_;
111110
=== modified file 'dash/DashView.cpp'
--- dash/DashView.cpp 2012-09-18 13:29:09 +0000
+++ dash/DashView.cpp 2012-09-18 17:41:27 +0000
@@ -1078,5 +1078,10 @@
1078 return (view == nullptr) ? this : view;1078 return (view == nullptr) ? this : view;
1079}1079}
10801080
1081nux::Geometry const& DashView::GetContentGeometry() const
1082{
1083 return content_geo_;
1084}
1085
1081}1086}
1082}1087}
10831088
=== modified file 'dash/DashView.h'
--- dash/DashView.h 2012-08-17 07:28:10 +0000
+++ dash/DashView.h 2012-09-18 17:41:27 +0000
@@ -69,6 +69,8 @@
6969
70 nux::View* default_focus() const;70 nux::View* default_focus() const;
7171
72 nux::Geometry const& GetContentGeometry() const;
73
72protected:74protected:
73 void ProcessDndEnter();75 void ProcessDndEnter();
7476
7577
=== modified file 'hud/HudAbstractView.h'
--- hud/HudAbstractView.h 2012-06-09 08:42:53 +0000
+++ hud/HudAbstractView.h 2012-09-18 17:41:27 +0000
@@ -48,8 +48,9 @@
48 virtual void SearchFinished() = 0;48 virtual void SearchFinished() = 0;
49 virtual void SetIcon(std::string const& icon_name, unsigned int tile_size, unsigned int size, unsigned int padding) = 0;49 virtual void SetIcon(std::string const& icon_name, unsigned int tile_size, unsigned int size, unsigned int padding) = 0;
50 virtual void SetQueries(Hud::Queries queries) = 0;50 virtual void SetQueries(Hud::Queries queries) = 0;
51 virtual void SetWindowGeometry(nux::Geometry const& absolute_geo, nux::Geometry const& geo) = 0;51 virtual void SetMonitorOffset(int x, int y) = 0;
52 virtual void ShowEmbeddedIcon(bool show) = 0;52 virtual void ShowEmbeddedIcon(bool show) = 0;
53 virtual nux::Geometry GetContentGeometry() = 0;
5354
54 virtual nux::View* default_focus() const = 0;55 virtual nux::View* default_focus() const = 0;
5556
@@ -58,6 +59,7 @@
58 sigc::signal<void, std::string> search_activated;59 sigc::signal<void, std::string> search_activated;
59 sigc::signal<void, Query::Ptr> query_activated;60 sigc::signal<void, Query::Ptr> query_activated;
60 sigc::signal<void, Query::Ptr> query_selected;61 sigc::signal<void, Query::Ptr> query_selected;
62 sigc::signal<void> layout_changed;
61};63};
6264
63} // namespace hud65} // namespace hud
6466
=== modified file 'hud/HudController.cpp'
--- hud/HudController.cpp 2012-09-17 10:00:38 +0000
+++ hud/HudController.cpp 2012-09-18 17:41:27 +0000
@@ -54,7 +54,7 @@
54{54{
55 LOG_DEBUG(logger) << "hud startup";55 LOG_DEBUG(logger) << "hud startup";
56 SetupWindow();56 SetupWindow();
57 UScreen::GetDefault()->changed.connect([&] (int, std::vector<nux::Geometry>&) { Relayout(); });57 UScreen::GetDefault()->changed.connect([&] (int, std::vector<nux::Geometry>&) { Relayout(true); });
5858
59 ubus.RegisterInterest(UBUS_HUD_CLOSE_REQUEST, sigc::mem_fun(this, &Controller::OnExternalHideHud));59 ubus.RegisterInterest(UBUS_HUD_CLOSE_REQUEST, sigc::mem_fun(this, &Controller::OnExternalHideHud));
6060
@@ -90,7 +90,12 @@
90 // Since BaseWindow is a View it is initially unowned. This means that the first90 // Since BaseWindow is a View it is initially unowned. This means that the first
91 // reference that is taken grabs ownership of the pointer. Since the smart pointer91 // reference that is taken grabs ownership of the pointer. Since the smart pointer
92 // references it, it becomes the owner, so no need to adopt the pointer here.92 // references it, it becomes the owner, so no need to adopt the pointer here.
93 window_ = new nux::BaseWindow("Hud");93 window_ = new ResizingBaseWindow("Hud", [this](nux::Geometry const& geo)
94 {
95 if (view_)
96 return GetInputWindowGeometry();
97 return geo;
98 });
94 window_->SetBackgroundColor(nux::Color(0.0f, 0.0f, 0.0f, 0.0f));99 window_->SetBackgroundColor(nux::Color(0.0f, 0.0f, 0.0f, 0.0f));
95 window_->SetConfigureNotifyCallback(&Controller::OnWindowConfigure, this);100 window_->SetConfigureNotifyCallback(&Controller::OnWindowConfigure, this);
96 window_->ShowWindow(false);101 window_->ShowWindow(false);
@@ -117,6 +122,8 @@
117 layout_->AddView(view_, 1, nux::MINOR_POSITION_TOP);122 layout_->AddView(view_, 1, nux::MINOR_POSITION_TOP);
118 window_->SetLayout(layout_);123 window_->SetLayout(layout_);
119124
125 window_->UpdateInputWindowGeometry();
126
120 view_->mouse_down_outside_pointer_grab_area.connect(sigc::mem_fun(this, &Controller::OnMouseDownOutsideWindow));127 view_->mouse_down_outside_pointer_grab_area.connect(sigc::mem_fun(this, &Controller::OnMouseDownOutsideWindow));
121128
122 LOG_DEBUG(logger) << "connecting to signals";129 LOG_DEBUG(logger) << "connecting to signals";
@@ -124,6 +131,7 @@
124 view_->search_activated.connect(sigc::mem_fun(this, &Controller::OnSearchActivated));131 view_->search_activated.connect(sigc::mem_fun(this, &Controller::OnSearchActivated));
125 view_->query_activated.connect(sigc::mem_fun(this, &Controller::OnQueryActivated));132 view_->query_activated.connect(sigc::mem_fun(this, &Controller::OnQueryActivated));
126 view_->query_selected.connect(sigc::mem_fun(this, &Controller::OnQuerySelected));133 view_->query_selected.connect(sigc::mem_fun(this, &Controller::OnQuerySelected));
134 view_->layout_changed.connect(sigc::bind(sigc::mem_fun(this, &Controller::Relayout), nullptr));
127 // Add to the debug introspection.135 // Add to the debug introspection.
128 AddChild(view_);136 AddChild(view_);
129}137}
@@ -155,13 +163,15 @@
155163
156void Controller::EnsureHud()164void Controller::EnsureHud()
157{165{
158 LOG_DEBUG(logger) << "Initializing Hud";
159
160 if (!window_)166 if (!window_)
167 {
168 LOG_DEBUG(logger) << "Initializing Hud Window";
161 SetupWindow();169 SetupWindow();
170 }
162171
163 if (!view_)172 if (!view_)
164 {173 {
174 LOG_DEBUG(logger) << "Initializing Hud View";
165 SetupHudView();175 SetupHudView();
166 Relayout();176 Relayout();
167 }177 }
@@ -212,16 +222,20 @@
212 return geo;222 return geo;
213}223}
214224
215void Controller::Relayout()225void Controller::Relayout(bool check_monitor)
216{226{
217 EnsureHud();227 EnsureHud();
218 nux::Geometry const& content_geo = view_->GetGeometry();228
229 if (check_monitor)
230 {
231 monitor_index_ = CLAMP(GetIdealMonitor(), 0, static_cast<int>(UScreen::GetDefault()->GetMonitors().size()-1));
232 }
219 nux::Geometry const& geo = GetIdealWindowGeometry();233 nux::Geometry const& geo = GetIdealWindowGeometry();
220234
235 view_->Relayout();
221 window_->SetGeometry(geo);236 window_->SetGeometry(geo);
222 layout_->SetMinMaxSize(content_geo.width, content_geo.height);237 panel::Style &panel_style = panel::Style::Instance();
223 view_->SetWindowGeometry(window_->GetAbsoluteGeometry(), window_->GetGeometry());238 view_->SetMonitorOffset(launcher_width, panel_style.panel_height);
224 view_->Relayout();
225}239}
226240
227void Controller::OnMouseDownOutsideWindow(int x, int y,241void Controller::OnMouseDownOutsideWindow(int x, int y,
@@ -255,7 +269,15 @@
255{269{
256 LOG_DEBUG(logger) << "External Hiding the hud";270 LOG_DEBUG(logger) << "External Hiding the hud";
257 EnsureHud();271 EnsureHud();
258 HideHud();272
273 if (variant)
274 {
275 HideHud(g_variant_get_boolean(variant));
276 }
277 else
278 {
279 HideHud();
280 }
259}281}
260282
261void Controller::ShowHideHud()283void Controller::ShowHideHud()
@@ -353,6 +375,7 @@
353 window_->ShowWindow(true);375 window_->ShowWindow(true);
354 window_->PushToFront();376 window_->PushToFront();
355 window_->EnableInputWindow(true, "Hud", true, false);377 window_->EnableInputWindow(true, "Hud", true, false);
378 window_->UpdateInputWindowGeometry();
356 window_->SetInputFocus();379 window_->SetInputFocus();
357 window_->CaptureMouseDownAnyWhereElse(true);380 window_->CaptureMouseDownAnyWhereElse(true);
358 view_->CaptureMouseDownAnyWhereElse(true);381 view_->CaptureMouseDownAnyWhereElse(true);
@@ -363,7 +386,6 @@
363 visible_ = true;386 visible_ = true;
364387
365 StartShowHideTimeline();388 StartShowHideTimeline();
366 view_->SetWindowGeometry(window_->GetAbsoluteGeometry(), window_->GetGeometry());
367389
368 // hide the launcher390 // hide the launcher
369 GVariant* message_data = g_variant_new("(b)", TRUE);391 GVariant* message_data = g_variant_new("(b)", TRUE);
@@ -504,6 +526,15 @@
504 .add("locked_to_launcher", IsLockedToLauncher(monitor_index_));526 .add("locked_to_launcher", IsLockedToLauncher(monitor_index_));
505}527}
506528
529nux::Geometry Controller::GetInputWindowGeometry()
530{
531 EnsureHud();
532 nux::Geometry const& window_geo(window_->GetGeometry());
533 nux::Geometry const& view_content_geo(view_->GetContentGeometry());
534 return nux::Geometry(window_geo.x, window_geo.y, view_content_geo.width, view_content_geo.height);
535}
536
537
507538
508}539}
509}540}
510541
=== modified file 'hud/HudController.h'
--- hud/HudController.h 2012-09-13 10:56:42 +0000
+++ hud/HudController.h 2012-09-18 17:41:27 +0000
@@ -24,14 +24,15 @@
2424
25#include <gdk/gdk.h>25#include <gdk/gdk.h>
26#include <UnityCore/Hud.h>26#include <UnityCore/Hud.h>
27#include <UnityCore/GLibSignal.h>
2728
28#include <NuxCore/Property.h>29#include <NuxCore/Property.h>
29#include <NuxGraphics/GraphicsEngine.h>30#include <NuxGraphics/GraphicsEngine.h>
30#include <Nux/Nux.h>31#include <Nux/Nux.h>
31#include <Nux/BaseWindow.h>
3232
33#include "unity-shared/Animator.h"33#include "unity-shared/Animator.h"
34#include "unity-shared/UBusWrapper.h"34#include "unity-shared/UBusWrapper.h"
35#include "unity-shared/ResizingBaseWindow.h"
35#include "HudView.h"36#include "HudView.h"
3637
37namespace unity38namespace unity
@@ -59,6 +60,8 @@
59 void HideHud(bool restore_focus = true);60 void HideHud(bool restore_focus = true);
60 bool IsVisible();61 bool IsVisible();
6162
63 nux::Geometry GetInputWindowGeometry();
64
62protected:65protected:
63 // Introspectable66 // Introspectable
64 std::string GetName() const;67 std::string GetName() const;
@@ -75,7 +78,7 @@
75 bool IsLockedToLauncher(int monitor);78 bool IsLockedToLauncher(int monitor);
7679
77 nux::Geometry GetIdealWindowGeometry();80 nux::Geometry GetIdealWindowGeometry();
78 void Relayout();81 void Relayout(bool check_monitor =false);
7982
80 void OnMouseDownOutsideWindow(int x, int y, unsigned long bflags, unsigned long kflags);83 void OnMouseDownOutsideWindow(int x, int y, unsigned long bflags, unsigned long kflags);
81 void OnScreenUngrabbed();84 void OnScreenUngrabbed();
@@ -96,8 +99,9 @@
96 void OnQueriesFinished(Hud::Queries queries);99 void OnQueriesFinished(Hud::Queries queries);
97100
98private:101private:
99 nux::ObjectPtr<nux::BaseWindow> window_;102 nux::ObjectPtr<ResizingBaseWindow> window_;
100 UBusManager ubus;103 UBusManager ubus;
104 glib::SignalManager sig_manager_;
101 Hud hud_service_;105 Hud hud_service_;
102 bool visible_;106 bool visible_;
103 bool need_show_;107 bool need_show_;
104108
=== modified file 'hud/HudView.cpp'
--- hud/HudView.cpp 2012-09-13 10:56:42 +0000
+++ hud/HudView.cpp 2012-09-18 17:41:27 +0000
@@ -61,10 +61,10 @@
61 : AbstractView()61 : AbstractView()
62 , button_views_(nullptr)62 , button_views_(nullptr)
63 , visible_(false)63 , visible_(false)
64 , timeline_animating_(false)
64 , start_time_(0)65 , start_time_(0)
65 , last_known_height_(0)66 , last_known_height_(0)
66 , current_height_(0)67 , current_height_(0)
67 , timeline_need_more_draw_(false)
68 , selected_button_(0)68 , selected_button_(0)
69 , show_embedded_icon_(true)69 , show_embedded_icon_(true)
70 , keyboard_stole_focus_(false)70 , keyboard_stole_focus_(false)
@@ -122,6 +122,12 @@
122{122{
123}123}
124124
125void View::SetMonitorOffset(int x, int y)
126{
127 renderer_.x_offset = x;
128 renderer_.y_offset = y;
129}
130
125void View::ProcessGrowShrink()131void View::ProcessGrowShrink()
126{132{
127 float diff = g_get_monotonic_time() - start_time_;133 float diff = g_get_monotonic_time() - start_time_;
@@ -129,24 +135,25 @@
129 // only animate if we are after our defined pause time135 // only animate if we are after our defined pause time
130 if (diff > pause_before_grow_length)136 if (diff > pause_before_grow_length)
131 {137 {
132 float progress = (diff - pause_before_grow_length) / grow_anim_length;138 float progress = (diff - pause_before_grow_length) / grow_anim_length;
133 int last_height = last_known_height_;139 int last_height = last_known_height_;
134 int new_height = 0;140 int new_height = 0;
135141
136 if (last_height < target_height)142 if (last_height < target_height)
137 {143 {
138 // grow144 // grow
139 new_height = last_height + ((target_height - last_height) * progress);145 new_height = last_height + ((target_height - last_height) * progress);
140 }146 }
141 else147 else
142 {148 {
143 //shrink149 //shrink
144 new_height = last_height - ((last_height - target_height) * progress);150 new_height = last_height - ((last_height - target_height) * progress);
145 }151 }
146152
147 LOG_DEBUG(logger) << "resizing to " << target_height << " (" << new_height << ")"153
154 LOG_DEBUG(logger) << "resizing to " << target_height << " (" << new_height << ")"
148 << "View height: " << GetGeometry().height;155 << "View height: " << GetGeometry().height;
149 current_height_ = new_height;156 current_height_ = new_height;
150 }157 }
151158
152 for (auto button : buttons_)159 for (auto button : buttons_)
@@ -154,14 +161,23 @@
154 button->SetSkipDraw((button->GetAbsoluteY() + button->GetBaseHeight()) > (GetAbsoluteY() + current_height_));161 button->SetSkipDraw((button->GetAbsoluteY() + button->GetBaseHeight()) > (GetAbsoluteY() + current_height_));
155 }162 }
156163
157 QueueDraw();
158
159 if (diff > grow_anim_length + pause_before_grow_length)164 if (diff > grow_anim_length + pause_before_grow_length)
160 {165 {
161 // ensure we are at our final location and update last known height166 // ensure we are at our final location and update last known height
162 current_height_ = target_height;167 current_height_ = target_height;
163 last_known_height_ = target_height;168 last_known_height_ = target_height;
164 timeline_need_more_draw_ = false;169
170 layout_changed.emit();
171 timeline_idle_.reset();
172 timeline_animating_ = false;
173 }
174 else
175 {
176 timeline_idle_.reset(new glib::Timeout(0, [this]
177 {
178 QueueDraw();
179 return false;
180 }));
165 }181 }
166}182}
167183
@@ -187,27 +203,6 @@
187 QueueDraw();203 QueueDraw();
188}204}
189205
190long View::PostLayoutManagement(long LayoutResult)
191{
192 Relayout();
193 if (GetGeometry().height != last_known_height_)
194 {
195 // Start the timeline of drawing the dash resize
196 if (timeline_need_more_draw_)
197 {
198 // already started, just reset the last known height
199 last_known_height_ = current_height_;
200 }
201
202 timeline_need_more_draw_ = true;
203 start_time_ = g_get_monotonic_time();
204 QueueDraw();
205 }
206
207 return LayoutResult;
208}
209
210
211nux::View* View::default_focus() const206nux::View* View::default_focus() const
212{207{
213 return search_bar_->text_entry();208 return search_bar_->text_entry();
@@ -361,14 +356,6 @@
361 renderer_.AboutToHide();356 renderer_.AboutToHide();
362}357}
363358
364void View::SetWindowGeometry(nux::Geometry const& absolute_geo, nux::Geometry const& geo)
365{
366 window_geometry_ = geo;
367 window_geometry_.x = 0;
368 window_geometry_.y = 0;
369 absolute_window_geometry_ = absolute_geo;
370}
371
372void View::SetupViews()359void View::SetupViews()
373{360{
374 dash::Style& style = dash::Style::Instance();361 dash::Style& style = dash::Style::Instance();
@@ -405,6 +392,17 @@
405 content_layout_->AddLayout(button_views_.GetPointer(), 1, nux::MINOR_POSITION_LEFT);392 content_layout_->AddLayout(button_views_.GetPointer(), 1, nux::MINOR_POSITION_LEFT);
406 }393 }
407394
395 content_layout_->OnGeometryChanged.connect([&](nux::Area*, nux::Geometry& geo)
396 {
397 if (!timeline_animating_)
398 {
399 timeline_animating_ = true;
400 start_time_ = g_get_monotonic_time();
401 QueueDraw();
402 }
403 });
404
405
408 layout_->AddLayout(content_layout_.GetPointer(), 1, nux::MINOR_POSITION_TOP);406 layout_->AddLayout(content_layout_.GetPointer(), 1, nux::MINOR_POSITION_TOP);
409 }407 }
410408
@@ -450,14 +448,12 @@
450448
451void View::Draw(nux::GraphicsEngine& gfx_context, bool force_draw)449void View::Draw(nux::GraphicsEngine& gfx_context, bool force_draw)
452{450{
453 if (timeline_need_more_draw_)451 if (timeline_animating_)
454 {
455 ProcessGrowShrink();452 ProcessGrowShrink();
456 }
457453
458 nux::Geometry draw_content_geo(layout_->GetGeometry());454 nux::Geometry draw_content_geo(layout_->GetGeometry());
459 draw_content_geo.height = current_height_;455 draw_content_geo.height = current_height_;
460 renderer_.DrawFull(gfx_context, draw_content_geo, absolute_window_geometry_, window_geometry_, true);456 renderer_.DrawFull(gfx_context, draw_content_geo, GetAbsoluteGeometry(), GetGeometry(), true);
461}457}
462458
463void View::DrawContent(nux::GraphicsEngine& gfx_context, bool force_draw)459void View::DrawContent(nux::GraphicsEngine& gfx_context, bool force_draw)
@@ -465,7 +461,7 @@
465 nux::Geometry draw_content_geo(layout_->GetGeometry());461 nux::Geometry draw_content_geo(layout_->GetGeometry());
466 draw_content_geo.height = current_height_;462 draw_content_geo.height = current_height_;
467463
468 renderer_.DrawInner(gfx_context, draw_content_geo, absolute_window_geometry_, window_geometry_);464 renderer_.DrawInner(gfx_context, draw_content_geo, GetAbsoluteGeometry(), GetGeometry());
469465
470 gfx_context.PushClippingRectangle(draw_content_geo);466 gfx_context.PushClippingRectangle(draw_content_geo);
471467
@@ -492,16 +488,7 @@
492 }488 }
493 gfx_context.PopClippingRectangle();489 gfx_context.PopClippingRectangle();
494490
495 renderer_.DrawInnerCleanup(gfx_context, draw_content_geo, absolute_window_geometry_, window_geometry_);491 renderer_.DrawInnerCleanup(gfx_context, draw_content_geo, GetAbsoluteGeometry(), GetGeometry());
496
497 if (timeline_need_more_draw_ && !timeline_idle_)
498 {
499 timeline_idle_.reset(new glib::Idle([&] () {
500 QueueDraw();
501 timeline_idle_.reset();
502 return false;
503 }));
504 }
505}492}
506493
507void View::MouseStealsHudButtonFocus()494void View::MouseStealsHudButtonFocus()
@@ -769,6 +756,14 @@
769 return search_bar_->text_entry();756 return search_bar_->text_entry();
770}757}
771758
759nux::Geometry View::GetContentGeometry()
760{
761 nux::Geometry geo(content_geo_);
762 geo.height = current_height_;
763 return geo;
764}
765
766
772}767}
773}768}
774769
775770
=== modified file 'hud/HudView.h'
--- hud/HudView.h 2012-09-04 18:15:34 +0000
+++ hud/HudView.h 2012-09-18 17:41:27 +0000
@@ -60,7 +60,9 @@
60 void AboutToShow();60 void AboutToShow();
61 void AboutToHide();61 void AboutToHide();
6262
63 void SetWindowGeometry(nux::Geometry const& absolute_geo, nux::Geometry const& geo);63 void SetMonitorOffset(int x, int y);
64
65 nux::Geometry GetContentGeometry();
6466
65protected:67protected:
66 virtual Area* FindKeyFocusArea(unsigned int event_type,68 virtual Area* FindKeyFocusArea(unsigned int event_type,
@@ -69,7 +71,6 @@
6971
70 void SetupViews();72 void SetupViews();
71 void OnSearchChanged(std::string const& search_string);73 void OnSearchChanged(std::string const& search_string);
72 virtual long PostLayoutManagement(long LayoutResult);
7374
74private:75private:
75 void OnMouseButtonDown(int x, int y, unsigned long button, unsigned long key);76 void OnMouseButtonDown(int x, int y, unsigned long button, unsigned long key);
@@ -110,14 +111,12 @@
110 Hud::Queries queries_;111 Hud::Queries queries_;
111 nux::Geometry content_geo_;112 nux::Geometry content_geo_;
112 OverlayRenderer renderer_;113 OverlayRenderer renderer_;
113 nux::Geometry window_geometry_;
114 nux::Geometry absolute_window_geometry_;
115 glib::Source::UniquePtr timeline_idle_;114 glib::Source::UniquePtr timeline_idle_;
115 bool timeline_animating_;
116116
117 guint64 start_time_;117 guint64 start_time_;
118 int last_known_height_;118 int last_known_height_;
119 int current_height_;119 int current_height_;
120 bool timeline_need_more_draw_;
121 int selected_button_;120 int selected_button_;
122 bool show_embedded_icon_;121 bool show_embedded_icon_;
123 bool activated_signal_sent_;122 bool activated_signal_sent_;
124123
=== modified file 'hud/StandaloneHud.cpp'
--- hud/StandaloneHud.cpp 2012-06-01 15:24:14 +0000
+++ hud/StandaloneHud.cpp 2012-09-18 17:41:27 +0000
@@ -69,7 +69,7 @@
6969
70 hud_view_ = new unity::hud::View();70 hud_view_ = new unity::hud::View();
7171
72 layout->AddView (hud_view_, 0, nux::MINOR_POSITION_TOP);72 layout->AddView (hud_view_, 1, nux::MINOR_POSITION_TOP);
73 nux::GetWindowCompositor().SetKeyFocusArea(hud_view_->default_focus());73 nux::GetWindowCompositor().SetKeyFocusArea(hud_view_->default_focus());
7474
75 nux::GetWindowThread()->SetLayout (layout);75 nux::GetWindowThread()->SetLayout (layout);
@@ -109,9 +109,6 @@
109 });109 });
110110
111 hud_service_.RequestQuery("");111 hud_service_.RequestQuery("");
112
113 hud_view_->SetWindowGeometry(layout->GetAbsoluteGeometry(), layout->GetGeometry());
114
115}112}
116113
117void TestRunner::InitWindowThread(nux::NThread* thread, void* InitData)114void TestRunner::InitWindowThread(nux::NThread* thread, void* InitData)
118115
=== modified file 'plugins/unityshell/src/unityshell.cpp'
--- plugins/unityshell/src/unityshell.cpp 2012-09-18 01:41:46 +0000
+++ plugins/unityshell/src/unityshell.cpp 2012-09-18 17:41:27 +0000
@@ -913,6 +913,33 @@
913 }913 }
914}914}
915915
916bool UnityScreen::DoesPointIntersectUnityGeos(nux::Point const& pt)
917{
918 auto launchers = launcher_controller_->launchers();
919 for (auto launcher : launchers)
920 {
921 nux::Geometry hud_geo = launcher->GetAbsoluteGeometry();
922
923 if (launcher->Hidden())
924 continue;
925
926 if (hud_geo.IsInside(pt))
927 {
928 return true;
929 }
930 }
931
932 for (nux::Geometry &panel_geo : panel_controller_->GetGeometries ())
933 {
934 if (panel_geo.IsInside(pt))
935 {
936 return true;
937 }
938 }
939
940 return false;
941}
942
916void UnityWindow::enterShowDesktop ()943void UnityWindow::enterShowDesktop ()
917{944{
918 if (!mShowdesktopHandler)945 if (!mShowdesktopHandler)
@@ -1435,12 +1462,26 @@
1435 if (CompWindow *w = screen->findWindow(ss->getSelectedWindow()))1462 if (CompWindow *w = screen->findWindow(ss->getSelectedWindow()))
1436 skip_other_plugins = UnityWindow::get(w)->handleEvent(event);1463 skip_other_plugins = UnityWindow::get(w)->handleEvent(event);
1437 }1464 }
1438 if (launcher_controller_->IsOverlayOpen())1465
1466
1467 if (dash_controller_->IsVisible())
1439 {1468 {
1440 int monitor_with_mouse = UScreen::GetDefault()->GetMonitorWithMouse();1469 nux::Point pt(event->xbutton.x_root, event->xbutton.y_root);
1441 if (overlay_monitor_ != monitor_with_mouse)1470 nux::Geometry dash_geo = dash_controller_->GetInputWindowGeometry();
1471
1472 if (!dash_geo.IsInside(pt) && !DoesPointIntersectUnityGeos(pt))
1442 {1473 {
1443 dash_controller_->HideDash(false);1474 dash_controller_->HideDash(false);
1475 }
1476 }
1477
1478 if (hud_controller_->IsVisible())
1479 {
1480 nux::Point pt(event->xbutton.x_root, event->xbutton.y_root);
1481 nux::Geometry hud_geo = hud_controller_->GetInputWindowGeometry();
1482
1483 if (!hud_geo.IsInside(pt) && !DoesPointIntersectUnityGeos(pt))
1484 {
1444 hud_controller_->HideHud(false);1485 hud_controller_->HideHud(false);
1445 }1486 }
1446 }1487 }
@@ -2683,6 +2724,7 @@
2683 return pos;2724 return pos;
2684}2725}
26852726
2727
2686bool UnityWindow::place(CompPoint& pos)2728bool UnityWindow::place(CompPoint& pos)
2687{2729{
2688 bool was_maximized = PluginAdapter::Default ()->MaximizeIfBigEnough(window);2730 bool was_maximized = PluginAdapter::Default ()->MaximizeIfBigEnough(window);
26892731
=== modified file 'plugins/unityshell/src/unityshell.h'
--- plugins/unityshell/src/unityshell.h 2012-09-18 01:41:46 +0000
+++ plugins/unityshell/src/unityshell.h 2012-09-18 17:41:27 +0000
@@ -190,6 +190,8 @@
190 switcher::Controller::Ptr switcher_controller();190 switcher::Controller::Ptr switcher_controller();
191 launcher::Controller::Ptr launcher_controller();191 launcher::Controller::Ptr launcher_controller();
192192
193 bool DoesPointIntersectUnityGeos(nux::Point const& pt);
194
193protected:195protected:
194 std::string GetName() const;196 std::string GetName() const;
195 void AddProperties(GVariantBuilder* builder);197 void AddProperties(GVariantBuilder* builder);
196198
=== modified file 'tests/autopilot/unity/emulators/dash.py'
--- tests/autopilot/unity/emulators/dash.py 2012-09-13 10:56:42 +0000
+++ tests/autopilot/unity/emulators/dash.py 2012-09-18 17:41:27 +0000
@@ -155,6 +155,10 @@
155 active_lens_name = self.view.get_lensbar().active_lens155 active_lens_name = self.view.get_lensbar().active_lens
156 return self.view.get_lensview_by_name(active_lens_name)156 return self.view.get_lensview_by_name(active_lens_name)
157157
158 @property
159 def geometry(self):
160 return (self.view.x, self.view.y, self.view.width, self.view.height)
161
158162
159class DashController(UnityIntrospectionObject):163class DashController(UnityIntrospectionObject):
160 """The main dash controller object."""164 """The main dash controller object."""
161165
=== modified file 'tests/autopilot/unity/tests/test_dash.py'
--- tests/autopilot/unity/tests/test_dash.py 2012-09-18 01:41:46 +0000
+++ tests/autopilot/unity/tests/test_dash.py 2012-09-18 17:41:27 +0000
@@ -107,6 +107,39 @@
107 self.dash.reveal_application_lens()107 self.dash.reveal_application_lens()
108 self.assertThat(self.dash.active_lens, Eventually(Equals('applications.lens')))108 self.assertThat(self.dash.active_lens, Eventually(Equals('applications.lens')))
109109
110 def test_closes_mouse_down_outside(self):
111 """Test that a mouse down outside of the dash closes the dash."""
112
113 self.dash.ensure_visible()
114 current_monitor = self.dash.monitor
115
116 (x,y,w,h) = self.dash.geometry
117 (screen_x,screen_y,screen_w,screen_h) = self.screen_geo.get_monitor_geometry(current_monitor)
118
119 self.mouse.move(x + w + (screen_w-((screen_x-x)+w))/2, y + h + (screen_h-((screen_y-y)+h))/2)
120 self.mouse.click()
121
122 self.assertThat(self.dash.visible, Eventually(Equals(False)))
123
124 def test_closes_then_focuses_window_on_mouse_down(self):
125 """If 2 windows are open with 1 maximized and the non-maxmized
126 focused. Then from the Dash clicking on the maximized window
127 must focus that window and close the dash.
128 """
129 char_win = self.start_app("Character Map")
130 self.keybinding("window/maximize")
131 self.start_app("Calculator")
132
133 self.dash.ensure_visible()
134
135 #Click bottom right of the screen
136 w = self.screen_geo.get_screen_width()
137 h = self.screen_geo.get_screen_height()
138 self.mouse.move(w,h)
139 self.mouse.click()
140
141 self.assertProperty(char_win, is_active=True)
142
110143
111class DashSearchInputTests(DashTestCase):144class DashSearchInputTests(DashTestCase):
112 """Test features involving input to the dash search"""145 """Test features involving input to the dash search"""
113146
=== modified file 'tests/autopilot/unity/tests/test_hud.py'
--- tests/autopilot/unity/tests/test_hud.py 2012-09-18 01:41:46 +0000
+++ tests/autopilot/unity/tests/test_hud.py 2012-09-18 17:41:27 +0000
@@ -409,6 +409,38 @@
409 self.keyboard.type("HasFocus")409 self.keyboard.type("HasFocus")
410 self.assertThat(self.hud.search_string, Eventually(Equals("HasFocus")))410 self.assertThat(self.hud.search_string, Eventually(Equals("HasFocus")))
411411
412 def test_closes_mouse_down_outside(self):
413 """Test that a mouse down outside of the hud closes the hud."""
414
415 self.hud.ensure_visible()
416 current_monitor = self.hud.monitor
417
418 (x,y,w,h) = self.hud.geometry
419 (screen_x,screen_y,screen_w,screen_h) = self.screen_geo.get_monitor_geometry(current_monitor)
420
421 self.mouse.move(x + w + (screen_w-((screen_x-x)+w))/2, y + h + (screen_h-((screen_y-y)+h))/2)
422 self.mouse.click()
423
424 self.assertThat(self.hud.visible, Eventually(Equals(False)))
425
426 def test_closes_then_focuses_window_on_mouse_down(self):
427 """If 2 windows are open with 1 maximized and the non-maxmized
428 focused. Then from the Hud clicking on the maximized window
429 must focus that window and close the hud.
430 """
431 char_win = self.start_app("Character Map")
432 self.keybinding("window/maximize")
433 self.start_app("Calculator")
434
435 self.hud.ensure_visible()
436
437 #Click bottom right of the screen
438 w = self.screen_geo.get_screen_width()
439 h = self.screen_geo.get_screen_height()
440 self.mouse.move(w,h)
441 self.mouse.click()
442
443 self.assertProperty(char_win, is_active=True)
412444
413class HudLauncherInteractionsTests(HudTestsBase):445class HudLauncherInteractionsTests(HudTestsBase):
414446
415447
=== modified file 'tests/test_hud_controller.cpp'
--- tests/test_hud_controller.cpp 2012-07-04 02:37:23 +0000
+++ tests/test_hud_controller.cpp 2012-09-18 17:41:27 +0000
@@ -44,12 +44,13 @@
44 MOCK_METHOD0(SearchFinished, void());44 MOCK_METHOD0(SearchFinished, void());
45 MOCK_METHOD4(SetIcon, void(std::string const&, unsigned int tile_size, unsigned int size, unsigned int padding));45 MOCK_METHOD4(SetIcon, void(std::string const&, unsigned int tile_size, unsigned int size, unsigned int padding));
46 MOCK_METHOD1(SetQueries, void(hud::Hud::Queries queries));46 MOCK_METHOD1(SetQueries, void(hud::Hud::Queries queries));
47 MOCK_METHOD2(SetWindowGeometry, void(nux::Geometry const& absolute_geo, nux::Geometry const& geo));47 MOCK_METHOD2(SetMonitorOffset, void(int x, int y));
48 MOCK_METHOD1(ShowEmbeddedIcon, void(bool show));48 MOCK_METHOD1(ShowEmbeddedIcon, void(bool show));
49 MOCK_CONST_METHOD0(default_focus, nux::View*());49 MOCK_CONST_METHOD0(default_focus, nux::View*());
50 MOCK_CONST_METHOD0(GetName, std::string());50 MOCK_CONST_METHOD0(GetName, std::string());
51 MOCK_METHOD1(AddProperties, void(GVariantBuilder*));51 MOCK_METHOD1(AddProperties, void(GVariantBuilder*));
52 MOCK_METHOD2(Draw, void(nux::GraphicsEngine&, bool));52 MOCK_METHOD2(Draw, void(nux::GraphicsEngine&, bool));
53 MOCK_METHOD0(GetContentGeometry, nux::Geometry());
5354
54};55};
5556
5657
=== added file 'unity-shared/ResizingBaseWindow.h'
--- unity-shared/ResizingBaseWindow.h 1970-01-01 00:00:00 +0000
+++ unity-shared/ResizingBaseWindow.h 2012-09-18 17:41:27 +0000
@@ -0,0 +1,53 @@
1/*
2 * Copyright (C) 2012 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Nick Dedekind <nick.dedekind@canonical.com>
17 */
18
19#ifndef RESIZEDINPUTWINDOW_BASEWINDOW_H
20#define RESIZEDINPUTWINDOW_BASEWINDOW_H
21
22#include <Nux/BaseWindow.h>
23
24namespace unity
25{
26
27class ResizingBaseWindow : public nux::BaseWindow
28{
29public:
30 ResizingBaseWindow(const char *WindowName, std::function<nux::Geometry (nux::Geometry const&)> geo_func)
31 : BaseWindow(WindowName, NUX_TRACKER_LOCATION)
32 {
33 geo_func_ = geo_func;
34 }
35
36 void UpdateInputWindowGeometry()
37 {
38 if (m_input_window && m_input_window_enabled)
39 m_input_window->SetGeometry(geo_func_(GetGeometry()));
40 }
41
42 virtual void SetGeometry(const nux::Geometry &geo)
43 {
44 Area::SetGeometry(geo);
45 UpdateInputWindowGeometry();
46 }
47
48private:
49 std::function<nux::Geometry (nux::Geometry const&)> geo_func_;
50};
51
52}
53#endif // RESIZEDINPUTWINDOW_BASEWINDOW_H