Nux

Merge lp:~njpatel/nux/weak-ptrs-on-window-compostor-3.0 into lp:nux/3.0

Proposed by Neil J. Patel
Status: Merged
Approved by: Martin Mrazik
Approved revision: 655
Merged at revision: 656
Proposed branch: lp:~njpatel/nux/weak-ptrs-on-window-compostor-3.0
Merge into: lp:nux/3.0
Prerequisite: lp:~njpatel/nux/input-area-ungrab-on-destroy-3.0
Diff against target: 1438 lines (+455/-320)
7 files modified
Nux/Area.cpp (+2/-0)
Nux/WindowCompositor.cpp (+129/-207)
Nux/WindowCompositor.h (+16/-32)
configure.ac (+1/-1)
tests/gtest-nux-area.cpp (+96/-47)
tests/gtest-nux-input-area.cpp (+1/-1)
tests/gtest-nux-windowcompositor.cpp (+210/-32)
To merge this branch: bzr merge lp:~njpatel/nux/weak-ptrs-on-window-compostor-3.0
Reviewer Review Type Date Requested Status
Marco Trevisan (Treviño) Approve
Review via email: mp+125015@code.launchpad.net

Commit message

WindowCompostior: use ObjectWeakPtr to handle focus and mouse areas

So they get automatically nullified when the handled objects are destroyed,
also Make Area to unset the key-focus paths on destroy.

Description of the change

It can happen that during the WindowCompostitor::MenuEventCycle or KeyboardEventCycle computation the AreaUnderMouse is deleted, this can lead to a crash such as bug #1045059 (since when we use the area that we found, its location is no more valid). We can fix this issue using ObjectWeakPtr as they will be notified of their deletion.

At this point I've also moved the existing Area* references that were using the destroyed signal to ObjectWeakPtr's.

To post a comment you must log in.
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Everything goes as expected ;)

review: Approve
Revision history for this message
Unity Merger (unity-merger) wrote :

No proposals found for merge of lp:~njpatel/nux/input-area-ungrab-on-destroy-3.0 into lp:nux/3.0.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Nux/Area.cpp'
--- Nux/Area.cpp 2012-05-31 21:50:05 +0000
+++ Nux/Area.cpp 2012-09-18 18:30:40 +0000
@@ -68,6 +68,8 @@
6868
69 Area::~Area()69 Area::~Area()
70 {70 {
71 ResetDownwardPathToKeyFocusArea();
72 ResetUpwardPathToKeyFocusArea();
71 }73 }
7274
73 const NString &Area::GetBaseString() const75 const NString &Area::GetBaseString() const
7476
=== modified file 'Nux/WindowCompositor.cpp'
--- Nux/WindowCompositor.cpp 2012-08-02 17:46:47 +0000
+++ Nux/WindowCompositor.cpp 2012-09-18 18:30:40 +0000
@@ -58,7 +58,6 @@
58 m_CurrentWindow = NULL;58 m_CurrentWindow = NULL;
59 m_MenuWindow = NULL;59 m_MenuWindow = NULL;
60 _mouse_over_area = NULL;60 _mouse_over_area = NULL;
61 key_focus_area_ = NULL;
62 _always_on_front_window = NULL;61 _always_on_front_window = NULL;
63 inside_event_cycle_ = false;62 inside_event_cycle_ = false;
64 inside_rendering_cycle_ = false;63 inside_rendering_cycle_ = false;
@@ -67,11 +66,8 @@
67 _pending_exclusive_input_mode_action = false;66 _pending_exclusive_input_mode_action = false;
6867
69 _dnd_area = NULL;68 _dnd_area = NULL;
70 mouse_over_area_ = NULL;
71 mouse_owner_area_ = NULL;
72 _mouse_over_menu_page = NULL;69 _mouse_over_menu_page = NULL;
73 _mouse_owner_menu_page = NULL;70 _mouse_owner_menu_page = NULL;
74 mouse_owner_base_window_ = NULL;
75 _starting_menu_event_cycle = false;71 _starting_menu_event_cycle = false;
76 _menu_is_active = false;72 _menu_is_active = false;
77 _enable_nux_new_event_architecture = true;73 _enable_nux_new_event_architecture = true;
@@ -99,12 +95,7 @@
9995
100 void WindowCompositor::BeforeDestructor()96 void WindowCompositor::BeforeDestructor()
101 {97 {
102 if (key_focus_area_)98 key_focus_area_ = NULL;
103 {
104 key_focus_area_->ResetDownwardPathToKeyFocusArea();
105 key_focus_area_->ResetUpwardPathToKeyFocusArea();
106 key_focus_area_ = NULL;
107 }
108 }99 }
109100
110 WindowCompositor::~WindowCompositor()101 WindowCompositor::~WindowCompositor()
@@ -186,17 +177,12 @@
186 {177 {
187 _view_window_list.erase(it);178 _view_window_list.erase(it);
188179
189 if (_view_window_list.size())180 if (!_view_window_list.empty())
190 m_SelectedWindow = _view_window_list.front();181 m_SelectedWindow = _view_window_list.front();
191 }182 }
192 _window_to_texture_map.erase(window.GetPointer());183 _window_to_texture_map.erase(window.GetPointer());
193 }184 }
194185
195 Area* WindowCompositor::GetMouseOwnerArea()
196 {
197 return mouse_owner_area_;
198 }
199
200 //! Get Mouse position relative to the top left corner of the window.186 //! Get Mouse position relative to the top left corner of the window.
201 Point WindowCompositor::GetMousePosition()187 Point WindowCompositor::GetMousePosition()
202 {188 {
@@ -213,24 +199,24 @@
213199
214 void WindowCompositor::GetAreaUnderMouse(const Point& mouse_position,200 void WindowCompositor::GetAreaUnderMouse(const Point& mouse_position,
215 NuxEventType event_type,201 NuxEventType event_type,
216 InputArea** area_under_mouse_pointer,202 ObjectWeakPtr<InputArea>& area_under_mouse_pointer,
217 BaseWindow** window)203 ObjectWeakPtr<BaseWindow>& window)
218 {204 {
219 *area_under_mouse_pointer = NULL;205 window = NULL;
206 area_under_mouse_pointer = NULL;
220207
221 // Go through the list of BaseWindo and find the first area over which the208 // Go through the list of BaseWindo and find the first area over which the
222 // mouse pointer is.209 // mouse pointer is.
223 WindowList::iterator window_it;210 WindowList::iterator window_it;
224
225 for (window_it = _view_window_list.begin(); window_it != _view_window_list.end(); ++window_it)211 for (window_it = _view_window_list.begin(); window_it != _view_window_list.end(); ++window_it)
226 {212 {
227 if ((*window_it).IsValid() && (*window_it)->IsVisible())213 if ((*window_it).IsValid() && (*window_it)->IsVisible())
228 {214 {
229 InputArea* area = static_cast<InputArea*>((*window_it)->FindAreaUnderMouse(mouse_position, event_type));215 Area* area = (*window_it)->FindAreaUnderMouse(mouse_position, event_type);
230 if (area)216 if (area)
231 {217 {
232 *area_under_mouse_pointer = area;218 area_under_mouse_pointer = static_cast<InputArea*>(area);
233 *window = (*window_it).GetPointer();219 window = *window_it;
234 return;220 return;
235 }221 }
236 }222 }
@@ -238,91 +224,55 @@
238224
239 // If area_under_mouse_pointer is NULL, then the mouse pointer is not over225 // If area_under_mouse_pointer is NULL, then the mouse pointer is not over
240 // any of the BaseWindow. Try the main window layout.226 // any of the BaseWindow. Try the main window layout.
241 if (*area_under_mouse_pointer == NULL)227 if (!area_under_mouse_pointer.IsValid())
242 {228 {
243 Layout* main_window_layout = window_thread_->GetLayout();229 Layout* main_window_layout = window_thread_->GetLayout();
244 if (main_window_layout)230 if (main_window_layout)
245 *area_under_mouse_pointer = static_cast<InputArea*>(main_window_layout->FindAreaUnderMouse(mouse_position, event_type));231 area_under_mouse_pointer = static_cast<InputArea*>(main_window_layout->FindAreaUnderMouse(mouse_position, event_type));
246 }232 }
247 }233 }
248234
249 void WindowCompositor::OnMouseOverViewDestroyed(Object* object)235 void WindowCompositor::SetMouseOverArea(InputArea* area)
250 {236 {
251 if (mouse_over_area_ == object)237 if (mouse_over_area_ == area)
252 {238 return;
253 mouse_over_area_ = NULL;239
254 }240 mouse_over_area_ = area;
255 }241 }
256242
257 void WindowCompositor::SetMouseOverArea(Area* area)243 void WindowCompositor::SetMouseOwnerArea(InputArea* area)
258 {
259 mouse_over_area_ = static_cast<InputArea*>(area);
260
261 mouse_over_view_connection_.disconnect();
262
263 if (mouse_over_area_)
264 {
265 mouse_over_view_connection_ = mouse_over_area_->object_destroyed.connect(sigc::mem_fun(this, &WindowCompositor::OnMouseOverViewDestroyed));
266 }
267 }
268
269 void WindowCompositor::OnMouseOwnerViewDestroyed(Object* object)
270 {
271 if (mouse_owner_area_ == object)
272 {
273 mouse_owner_area_ = NULL;
274 }
275 }
276
277 void WindowCompositor::SetMouseOwnerArea(Area* area)
278 {244 {
279 if (mouse_owner_area_ == area)245 if (mouse_owner_area_ == area)
280 return;246 return;
281247
282 mouse_owner_area_ = static_cast<InputArea*>(area);248 mouse_owner_area_ = area;
283 dnd_safety_x_ = 0;249 dnd_safety_x_ = 0;
284 dnd_safety_y_ = 0;250 dnd_safety_y_ = 0;
285
286 mouse_owner_view_connection_.disconnect();
287
288 if (mouse_owner_area_)
289 {
290 mouse_owner_view_connection_ = mouse_owner_area_->object_destroyed.connect(sigc::mem_fun(this, &WindowCompositor::OnMouseOwnerViewDestroyed));
291 }
292 }251 }
293252
294 void WindowCompositor::OnMouseOwnerBaseWindowDestroyed(Object* object)253 ObjectWeakPtr<InputArea> const& WindowCompositor::GetMouseOwnerArea() const
295 {254 {
296 if (mouse_owner_base_window_ == object)255 return mouse_owner_area_;
297 {
298 mouse_owner_base_window_ = NULL;
299 }
300 }256 }
301257
302 void WindowCompositor::SetMouseOwnerBaseWindow(BaseWindow* base_window)258 void WindowCompositor::SetMouseOwnerBaseWindow(BaseWindow* base_window)
303 {259 {
304 mouse_owner_base_window_ = base_window;260 if (mouse_owner_base_window_ != base_window)
305261 mouse_owner_base_window_ = base_window;
306 mouse_owner_basewindow_connection_.disconnect();
307
308 if (mouse_owner_base_window_)
309 {
310 mouse_owner_basewindow_connection_ = mouse_owner_base_window_->object_destroyed.connect(sigc::mem_fun(this, &WindowCompositor::OnMouseOwnerBaseWindowDestroyed));
311 }
312 }262 }
313263
314 void WindowCompositor::DndEventCycle(Event& event)264 void WindowCompositor::DndEventCycle(Event& event)
315 {265 {
316 if (event.type == NUX_DND_MOVE)266 if (event.type == NUX_DND_MOVE)
317 {267 {
318 InputArea* hit_area = NULL;268 ObjectWeakPtr<InputArea> hit_area;
319 BaseWindow* hit_base_window = NULL;269 ObjectWeakPtr<BaseWindow> hit_base_window;
320270
321 GetAreaUnderMouse(Point(event.x, event.y), event.type, &hit_area, &hit_base_window);271 GetAreaUnderMouse(Point(event.x, event.y), event.type, hit_area, hit_base_window);
322272
323 if (hit_area)273 if (hit_area.IsValid())
324 {274 {
325 SetDnDArea(hit_area);275 SetDnDArea(hit_area.GetPointer());
326 hit_area->HandleDndMove(event);276 hit_area->HandleDndMove(event);
327 }277 }
328 else278 else
@@ -356,7 +306,7 @@
356306
357 _mouse_position = Point(event.x, event.y);307 _mouse_position = Point(event.x, event.y);
358308
359 if (mouse_owner_area_ == NULL)309 if (!mouse_owner_area_.IsValid())
360 {310 {
361 // Context: The left mouse button is not down over an area.311 // Context: The left mouse button is not down over an area.
362 // We look for the area where the mouse pointer is located.312 // We look for the area where the mouse pointer is located.
@@ -370,8 +320,8 @@
370 (event.type == NUX_WINDOW_MOUSELEAVE) ||320 (event.type == NUX_WINDOW_MOUSELEAVE) ||
371 (event.type == NUX_MOUSE_RELEASED))321 (event.type == NUX_MOUSE_RELEASED))
372 {322 {
373 InputArea* hit_view = NULL; // The view under the mouse323 ObjectWeakPtr<InputArea> hit_view; // The view under the mouse
374 BaseWindow* hit_base_window = NULL; // The BaseWindow below the mouse pointer.324 ObjectWeakPtr<BaseWindow> hit_base_window; // The BaseWindow below the mouse pointer.
375325
376 // Look for the area below the mouse pointer in the BaseWindow.326 // Look for the area below the mouse pointer in the BaseWindow.
377 Area* pointer_grab_area = GetPointerGrabArea();327 Area* pointer_grab_area = GetPointerGrabArea();
@@ -379,7 +329,7 @@
379 {329 {
380 // If there is a pending mouse pointer grab, test that area only330 // If there is a pending mouse pointer grab, test that area only
381 hit_view = NUX_STATIC_CAST(InputArea*, pointer_grab_area->FindAreaUnderMouse(Point(event.x, event.y), event.type));331 hit_view = NUX_STATIC_CAST(InputArea*, pointer_grab_area->FindAreaUnderMouse(Point(event.x, event.y), event.type));
382 if ((hit_view == NULL) && (event.type == NUX_MOUSE_PRESSED))332 if (!hit_view.IsValid() && event.type == NUX_MOUSE_PRESSED)
383 {333 {
384 Geometry geo = pointer_grab_area->GetAbsoluteGeometry();334 Geometry geo = pointer_grab_area->GetAbsoluteGeometry();
385 int x = event.x - geo.x;335 int x = event.x - geo.x;
@@ -390,15 +340,15 @@
390 }340 }
391 else341 else
392 {342 {
393 GetAreaUnderMouse(Point(event.x, event.y), event.type, &hit_view, &hit_base_window);343 GetAreaUnderMouse(Point(event.x, event.y), event.type, hit_view, hit_base_window);
394 SetMouseOwnerBaseWindow(hit_base_window);344 SetMouseOwnerBaseWindow(hit_base_window.GetPointer());
395 }345 }
396346
397 Geometry hit_view_geo;347 Geometry hit_view_geo;
398 int hit_view_x = 0;348 int hit_view_x = 0;
399 int hit_view_y = 0;349 int hit_view_y = 0;
400350
401 if (hit_view)351 if (hit_view.IsValid())
402 {352 {
403 hit_view_geo = hit_view->GetAbsoluteGeometry();353 hit_view_geo = hit_view->GetAbsoluteGeometry();
404 hit_view_x = event.x - hit_view_geo.x;354 hit_view_x = event.x - hit_view_geo.x;
@@ -407,11 +357,11 @@
407357
408 if (event.type == NUX_WINDOW_MOUSELEAVE)358 if (event.type == NUX_WINDOW_MOUSELEAVE)
409 {359 {
410 if (mouse_over_area_ != NULL)360 if (mouse_over_area_.IsValid())
411 {361 {
412 // The area where the mouse was in the previous cycle and the area returned by GetAreaUnderMouse are different.362 // The area where the mouse was in the previous cycle and the area returned by GetAreaUnderMouse are different.
413 // The area from the previous cycle receive a "mouse leave signal".363 // The area from the previous cycle receive a "mouse leave signal".
414 Geometry geo = mouse_over_area_->GetAbsoluteGeometry();364 Geometry const& geo = mouse_over_area_->GetAbsoluteGeometry();
415 int x = event.x - geo.x;365 int x = event.x - geo.x;
416 int y = event.y - geo.y;366 int y = event.y - geo.y;
417367
@@ -419,28 +369,28 @@
419 SetMouseOverArea(NULL);369 SetMouseOverArea(NULL);
420 }370 }
421 }371 }
422 else if (hit_view && (event.type == NUX_MOUSE_MOVE))372 else if (hit_view.IsValid() && event.type == NUX_MOUSE_MOVE)
423 {373 {
424 bool emit_delta = true;374 bool emit_delta = true;
425 if (hit_view != mouse_over_area_)375 if (hit_view != mouse_over_area_)
426 {376 {
427 if (mouse_over_area_ != NULL)377 if (mouse_over_area_.IsValid())
428 {378 {
429 // The area where the mouse was in the previous cycle and the area returned by GetAreaUnderMouse are different.379 // The area where the mouse was in the previous cycle and the area returned by GetAreaUnderMouse are different.
430 // The area from the previous cycle receive a "mouse leave signal".380 // The area from the previous cycle receive a "mouse leave signal".
431 Geometry geo = mouse_over_area_->GetAbsoluteGeometry();381 Geometry const& geo = mouse_over_area_->GetAbsoluteGeometry();
432 int x = event.x - geo.x;382 int x = event.x - geo.x;
433 int y = event.y - geo.y;383 int y = event.y - geo.y;
434384
435 mouse_over_area_->EmitMouseLeaveSignal(x, y, event.GetMouseState(), event.GetKeyState());385 mouse_over_area_->EmitMouseLeaveSignal(x, y, event.GetMouseState(), event.GetKeyState());
436 }386 }
437 // The area we found under the mouse pointer receives a "mouse enter signal".387 // The area we found under the mouse pointer receives a "mouse enter signal".
438 SetMouseOverArea(hit_view);388 SetMouseOverArea(hit_view.GetPointer());
439389
440 if (mouse_over_area_ != GetKeyFocusArea() &&390 if (mouse_over_area_.IsValid() && mouse_over_area_ != GetKeyFocusArea() &&
441 mouse_over_area_ && mouse_over_area_->AcceptKeyNavFocusOnMouseEnter())391 mouse_over_area_->AcceptKeyNavFocusOnMouseEnter())
442 {392 {
443 SetKeyFocusArea(mouse_over_area_);393 SetKeyFocusArea(mouse_over_area_.GetPointer());
444 }394 }
445 395
446 396
@@ -451,16 +401,16 @@
451 // Send a "mouse mouse signal".401 // Send a "mouse mouse signal".
452 mouse_over_area_->EmitMouseMoveSignal(hit_view_x, hit_view_y, emit_delta ? dx : 0, emit_delta ? dy : 0, event.GetMouseState(), event.GetKeyState());402 mouse_over_area_->EmitMouseMoveSignal(hit_view_x, hit_view_y, emit_delta ? dx : 0, emit_delta ? dy : 0, event.GetMouseState(), event.GetKeyState());
453 }403 }
454 else if (hit_view && ((event.type == NUX_MOUSE_PRESSED) || (event.type == NUX_MOUSE_DOUBLECLICK)))404 else if (hit_view.IsValid() && (event.type == NUX_MOUSE_PRESSED || event.type == NUX_MOUSE_DOUBLECLICK))
455 {405 {
456 if ((event.type == NUX_MOUSE_DOUBLECLICK) && (!hit_view->DoubleClickEnabled()))406 if (event.type == NUX_MOUSE_DOUBLECLICK && !hit_view->DoubleClickEnabled())
457 {407 {
458 // If the area does not accept double click events, transform the event into a mouse pressed.408 // If the area does not accept double click events, transform the event into a mouse pressed.
459 event.type = NUX_MOUSE_PRESSED;409 event.type = NUX_MOUSE_PRESSED;
460 }410 }
461411
462 bool emit_double_click_signal = false;412 bool emit_double_click_signal = false;
463 if (mouse_over_area_ && (hit_view != mouse_over_area_))413 if (mouse_over_area_.IsValid() && hit_view != mouse_over_area_)
464 {414 {
465 // The area where the mouse was in the previous cycle and the area returned by GetAreaUnderMouse are different.415 // The area where the mouse was in the previous cycle and the area returned by GetAreaUnderMouse are different.
466 // The area from the previous cycle receive a "mouse leave signal".416 // The area from the previous cycle receive a "mouse leave signal".
@@ -473,29 +423,29 @@
473423
474 mouse_over_area_->EmitMouseLeaveSignal(x, y, event.GetMouseState(), event.GetKeyState());424 mouse_over_area_->EmitMouseLeaveSignal(x, y, event.GetMouseState(), event.GetKeyState());
475 }425 }
476 else if (mouse_over_area_ && (hit_view == mouse_over_area_) && (event.type == NUX_MOUSE_DOUBLECLICK))426 else if (mouse_over_area_.IsValid() && hit_view == mouse_over_area_ && event.type == NUX_MOUSE_DOUBLECLICK)
477 {427 {
478 // Double click is emitted, if the second click happened on the same area as the first click.428 // Double click is emitted, if the second click happened on the same area as the first click.
479 // This means mouse_over_area_ is not null and is equal to hit_view.429 // This means mouse_over_area_ is not null and is equal to hit_view.
480 emit_double_click_signal = true;430 emit_double_click_signal = true;
481 }431 }
482432
483 SetMouseOverArea(hit_view);433 SetMouseOverArea(hit_view.GetPointer());
484 SetMouseOwnerArea(hit_view);434 SetMouseOwnerArea(hit_view.GetPointer());
485 _mouse_position_on_owner = Point(hit_view_x, hit_view_y);435 _mouse_position_on_owner = Point(hit_view_x, hit_view_y);
486436
487 // In the case of a mouse down event, if there is currently a keyboard event receiver and it is different437 // In the case of a mouse down event, if there is currently a keyboard event receiver and it is different
488 // from the area returned by GetAreaUnderMouse, then stop that receiver from receiving anymore keyboard events and switch438 // from the area returned by GetAreaUnderMouse, then stop that receiver from receiving anymore keyboard events and switch
489 // make mouse_over_area_ the new receiver(if it accept keyboard events).439 // make mouse_over_area_ the new receiver(if it accept keyboard events).
490 if (mouse_over_area_ != GetKeyFocusArea() && 440 if (mouse_over_area_.IsValid() && mouse_over_area_ != GetKeyFocusArea() &&
491 mouse_over_area_ && mouse_over_area_->AcceptKeyNavFocusOnMouseDown())441 mouse_over_area_->AcceptKeyNavFocusOnMouseDown())
492 {442 {
493 InputArea* grab_area = GetKeyboardGrabArea();443 InputArea* grab_area = GetKeyboardGrabArea();
494 if (grab_area)444 if (grab_area)
495 {445 {
496 if (mouse_over_area_->IsChildOf(grab_area) /*&& mouse_over_area_->AcceptKeyboardEvent()*/)446 if (mouse_over_area_->IsChildOf(grab_area) /*&& mouse_over_area_->AcceptKeyboardEvent()*/)
497 {447 {
498 SetKeyFocusArea(mouse_over_area_);448 SetKeyFocusArea(mouse_over_area_.GetPointer());
499 }449 }
500 else450 else
501 {451 {
@@ -504,7 +454,7 @@
504 }454 }
505 else455 else
506 {456 {
507 SetKeyFocusArea(mouse_over_area_);457 SetKeyFocusArea(mouse_over_area_.GetPointer());
508 }458 }
509 }459 }
510460
@@ -517,11 +467,11 @@
517 mouse_over_area_->EmitMouseDownSignal(hit_view_x, hit_view_y, event.GetMouseState(), event.GetKeyState());467 mouse_over_area_->EmitMouseDownSignal(hit_view_x, hit_view_y, event.GetMouseState(), event.GetKeyState());
518 }468 }
519 }469 }
520 else if (hit_view && (event.type == NUX_MOUSE_WHEEL))470 else if (hit_view.IsValid() && (event.type == NUX_MOUSE_WHEEL))
521 {471 {
522 hit_view->EmitMouseWheelSignal(hit_view_x, hit_view_y, event.wheel_delta, event.GetMouseState(), event.GetKeyState());472 hit_view->EmitMouseWheelSignal(hit_view_x, hit_view_y, event.wheel_delta, event.GetMouseState(), event.GetKeyState());
523 }473 }
524 else if (hit_view && (event.type == NUX_MOUSE_RELEASED))474 else if (hit_view.IsValid() && (event.type == NUX_MOUSE_RELEASED))
525 {475 {
526 // We only get a NUX_MOUSE_RELEASED event when the mouse was pressed476 // We only get a NUX_MOUSE_RELEASED event when the mouse was pressed
527 // over another area and released here. There are a few situations that can cause 477 // over another area and released here. There are a few situations that can cause
@@ -533,11 +483,11 @@
533483
534 hit_view->EmitMouseUpSignal(hit_view_x, hit_view_y, event.GetMouseState(), event.GetKeyState());484 hit_view->EmitMouseUpSignal(hit_view_x, hit_view_y, event.GetMouseState(), event.GetKeyState());
535 }485 }
536 else if (hit_view == NULL)486 else if (!hit_view.IsValid())
537 {487 {
538 if (mouse_over_area_)488 if (mouse_over_area_.IsValid())
539 {489 {
540 Geometry geo = mouse_over_area_->GetAbsoluteGeometry();490 Geometry const& geo = mouse_over_area_->GetAbsoluteGeometry();
541 int x = event.x - geo.x;491 int x = event.x - geo.x;
542 int y = event.y - geo.y;492 int y = event.y - geo.y;
543493
@@ -570,13 +520,12 @@
570 {520 {
571 // Context: The left mouse button down over an area. All events goes to that area.521 // Context: The left mouse button down over an area. All events goes to that area.
572 // But we still need to know where the mouse is.522 // But we still need to know where the mouse is.
573523 ObjectWeakPtr<InputArea> hit_view; // The view under the mouse
574 InputArea* hit_view = NULL; // The view under the mouse524 ObjectWeakPtr<BaseWindow> hit_base_window; // The BaseWindow below the mouse pointer.
575 BaseWindow* hit_base_window = NULL; // The BaseWindow below the mouse pointer.525
576526 GetAreaUnderMouse(Point(event.x, event.y), event.type, hit_view, hit_base_window);
577 GetAreaUnderMouse(Point(event.x, event.y), event.type, &hit_view, &hit_base_window);527
578528 Geometry const& mouse_owner_geo = mouse_owner_area_->GetAbsoluteGeometry();
579 Geometry mouse_owner_geo = mouse_owner_area_->GetAbsoluteGeometry();
580 int mouse_owner_x = event.x - mouse_owner_geo.x;529 int mouse_owner_x = event.x - mouse_owner_geo.x;
581 int mouse_owner_y = event.y - mouse_owner_geo.y;530 int mouse_owner_y = event.y - mouse_owner_geo.y;
582531
@@ -605,15 +554,15 @@
605 mouse_owner_area_->EmitMouseDragSignal(mouse_owner_x, mouse_owner_y, dx, dy, event.GetMouseState(), event.GetKeyState());554 mouse_owner_area_->EmitMouseDragSignal(mouse_owner_x, mouse_owner_y, dx, dy, event.GetMouseState(), event.GetKeyState());
606 }555 }
607556
608 if ((mouse_over_area_ == mouse_owner_area_) && (hit_view != mouse_owner_area_))557 if (mouse_over_area_ == mouse_owner_area_ && hit_view != mouse_owner_area_)
609 {558 {
610 mouse_owner_area_->EmitMouseLeaveSignal(mouse_owner_x, mouse_owner_y, event.GetMouseState(), event.GetKeyState());559 mouse_owner_area_->EmitMouseLeaveSignal(mouse_owner_x, mouse_owner_y, event.GetMouseState(), event.GetKeyState());
611 SetMouseOverArea(hit_view);560 SetMouseOverArea(hit_view.GetPointer());
612 }561 }
613 else if ((mouse_over_area_ != mouse_owner_area_) && (hit_view == mouse_owner_area_))562 else if (mouse_over_area_ != mouse_owner_area_ && hit_view == mouse_owner_area_)
614 {563 {
615 mouse_owner_area_->EmitMouseEnterSignal(mouse_owner_x, mouse_owner_y, event.GetMouseState(), event.GetKeyState());564 mouse_owner_area_->EmitMouseEnterSignal(mouse_owner_x, mouse_owner_y, event.GetMouseState(), event.GetKeyState());
616 SetMouseOverArea(mouse_owner_area_);565 SetMouseOverArea(mouse_owner_area_.GetPointer());
617 }566 }
618567
619 _mouse_position_on_owner = Point(mouse_owner_x, mouse_owner_y);568 _mouse_position_on_owner = Point(mouse_owner_x, mouse_owner_y);
@@ -625,11 +574,11 @@
625 if (hit_view == mouse_owner_area_)574 if (hit_view == mouse_owner_area_)
626 {575 {
627 mouse_owner_area_->EmitMouseClickSignal(mouse_owner_x, mouse_owner_y, event.GetMouseState(), event.GetKeyState());576 mouse_owner_area_->EmitMouseClickSignal(mouse_owner_x, mouse_owner_y, event.GetMouseState(), event.GetKeyState());
628 SetMouseOverArea(mouse_owner_area_);577 SetMouseOverArea(mouse_owner_area_.GetPointer());
629 }578 }
630 else579 else
631 {580 {
632 SetMouseOverArea(hit_view);581 SetMouseOverArea(hit_view.GetPointer());
633 }582 }
634583
635 SetMouseOwnerArea(NULL);584 SetMouseOwnerArea(NULL);
@@ -823,36 +772,36 @@
823 void WindowCompositor::FindKeyFocusArea(NuxEventType event_type,772 void WindowCompositor::FindKeyFocusArea(NuxEventType event_type,
824 unsigned int key_symbol,773 unsigned int key_symbol,
825 unsigned int special_keys_state,774 unsigned int special_keys_state,
826 InputArea** key_focus_area,775 ObjectWeakPtr<InputArea>& key_focus_area,
827 BaseWindow** window)776 ObjectWeakPtr<BaseWindow>& window)
828 {777 {
829 *key_focus_area = NULL;778 key_focus_area = NULL;
830 *window = NULL;779 window = NULL;
831780
832 // Go through the list of BaseWindos and find the first area over which the mouse pointer is.781 // Go through the list of BaseWindos and find the first area over which the mouse pointer is.
833 WindowList::iterator window_it;782 WindowList::iterator window_it;
834 window_it = _view_window_list.begin();783 window_it = _view_window_list.begin();
835 while ((*key_focus_area == NULL) && (window_it != _view_window_list.end()))784 while (!key_focus_area.IsValid() && window_it != _view_window_list.end())
836 {785 {
837 if ((*window_it).IsValid() && (*window_it)->IsVisible())786 if ((*window_it).IsValid() && (*window_it)->IsVisible())
838 {787 {
839 *key_focus_area = NUX_STATIC_CAST(InputArea*, (*window_it)->FindKeyFocusArea(event_type, key_symbol, special_keys_state));788 key_focus_area = NUX_STATIC_CAST(InputArea*, (*window_it)->FindKeyFocusArea(event_type, key_symbol, special_keys_state));
840 if (key_focus_area)789 if (key_focus_area.IsValid())
841 {790 {
842 // We have found an area. We are going to exit the while loop.791 // We have found an area. We are going to exit the while loop.
843 *window = (*window_it).GetPointer();792 window = *window_it;
844 }793 }
845 }794 }
846 ++window_it;795 ++window_it;
847 }796 }
848797
849 // If key_focus_area is NULL, then try the main window layout.798 // If key_focus_area is NULL, then try the main window layout.
850 if (*key_focus_area == NULL)799 if (!key_focus_area.IsValid())
851 {800 {
852 Layout* main_window_layout = window_thread_->GetLayout();801 Layout* main_window_layout = window_thread_->GetLayout();
853 if (main_window_layout)802 if (main_window_layout)
854 {803 {
855 *key_focus_area = NUX_STATIC_CAST(InputArea*, main_window_layout->FindKeyFocusArea(event_type, key_symbol, special_keys_state));804 key_focus_area = NUX_STATIC_CAST(InputArea*, main_window_layout->FindKeyFocusArea(event_type, key_symbol, special_keys_state));
856 }805 }
857 }806 }
858 }807 }
@@ -861,21 +810,21 @@
861 unsigned int key_symbol,810 unsigned int key_symbol,
862 unsigned int special_keys_state,811 unsigned int special_keys_state,
863 InputArea* root_search_area,812 InputArea* root_search_area,
864 InputArea** key_focus_area,813 ObjectWeakPtr<InputArea>& key_focus_area,
865 BaseWindow** window)814 ObjectWeakPtr<BaseWindow>& window)
866 {815 {
867 *key_focus_area = NULL;816 key_focus_area = NULL;
868 *window = NULL;817 window = NULL;
869818
870 if (root_search_area == NULL)819 if (root_search_area == NULL)
871 {820 {
872 return;821 return;
873 }822 }
874823
875 *key_focus_area = NUX_STATIC_CAST(InputArea*, root_search_area->FindKeyFocusArea(event_type, key_symbol, special_keys_state));824 key_focus_area = NUX_STATIC_CAST(InputArea*, root_search_area->FindKeyFocusArea(event_type, key_symbol, special_keys_state));
876 if (key_focus_area)825 if (key_focus_area.IsValid())
877 {826 {
878 *window = NUX_STATIC_CAST(BaseWindow*, root_search_area->GetTopLevelViewWindow());827 window = NUX_STATIC_CAST(BaseWindow*, root_search_area->GetTopLevelViewWindow());
879 }828 }
880 }829 }
881830
@@ -908,25 +857,21 @@
908 {857 {
909 InputArea* keyboard_event_grab_view = GetKeyboardGrabArea();858 InputArea* keyboard_event_grab_view = GetKeyboardGrabArea();
910859
911 InputArea* focus_area = NULL; // The view under the mouse860 ObjectWeakPtr<InputArea> focus_area; // The view under the mouse
912 BaseWindow* base_window = NULL; // The BaseWindow below the mouse pointer.861 ObjectWeakPtr<BaseWindow> base_window; // The BaseWindow below the mouse pointer.
913862
914 if (keyboard_event_grab_view)863 if (keyboard_event_grab_view)
915 {864 {
916 // There is a keyboard grab.865 // There is a keyboard grab.
917 // Find the key focus area, under the keyboard grab area. That is to say, the key focus area is in the widget tree 866 // Find the key focus area, under the keyboard grab area. That is to say, the key focus area is in the widget tree
918 // whose root is the keyboard grab area. This phase is known as the capture phase.867 // whose root is the keyboard grab area. This phase is known as the capture phase.
919
920 FindKeyFocusAreaFrom(event.type, event.GetKeySym(), event.GetKeyState(),868 FindKeyFocusAreaFrom(event.type, event.GetKeySym(), event.GetKeyState(),
921 keyboard_event_grab_view,869 keyboard_event_grab_view, focus_area, base_window);
922 &focus_area,
923 &base_window);
924 }870 }
925 else871 else
926 {872 {
927 FindKeyFocusArea(event.type, event.GetKeySym(), event.GetKeyState(),873 FindKeyFocusArea(event.type, event.GetKeySym(), event.GetKeyState(),
928 &focus_area,874 focus_area, base_window);
929 &base_window);
930 }875 }
931876
932 KeyNavDirection direction = KEY_NAV_NONE;877 KeyNavDirection direction = KEY_NAV_NONE;
@@ -964,20 +909,20 @@
964 }909 }
965 }910 }
966911
967 if (focus_area)912 if (focus_area.IsValid())
968 {913 {
969 SetKeyFocusArea(focus_area, direction);914 SetKeyFocusArea(focus_area.GetPointer(), direction);
970 }915 }
971 else916 else
972 {917 {
973 SetKeyFocusArea(NULL, KEY_NAV_NONE);918 SetKeyFocusArea(NULL, KEY_NAV_NONE);
974 }919 }
975920
976 if (key_focus_area_)921 if (key_focus_area_.IsValid())
977 {922 {
978 if (key_focus_area_->InspectKeyEvent(event.type, event.GetKeySym(), event.GetText()))923 if (key_focus_area_->InspectKeyEvent(event.type, event.GetKeySym(), event.GetText()))
979 {924 {
980 SendKeyEvent(key_focus_area_,925 SendKeyEvent(key_focus_area_.GetPointer(),
981 event.type,926 event.type,
982 event.GetKeySym(),927 event.GetKeySym(),
983#if defined(NUX_OS_WINDOWS)928#if defined(NUX_OS_WINDOWS)
@@ -1014,25 +959,25 @@
1014 }959 }
1015 }960 }
1016 else if (event.type == NUX_KEYDOWN)961 else if (event.type == NUX_KEYDOWN)
1017 { 962 {
1018 if (direction == KEY_NAV_ENTER)963 if (direction == KEY_NAV_ENTER)
1019 {964 {
1020 if (key_focus_area_ && key_focus_area_->Type().IsDerivedFromType(InputArea::StaticObjectType))965 if (key_focus_area_.IsValid() && key_focus_area_->Type().IsDerivedFromType(InputArea::StaticObjectType))
1021 {966 {
1022 // Signal emitted from the WindowCompositor.967 // Signal emitted from the WindowCompositor.
1023 key_nav_focus_activate.emit(key_focus_area_);968 key_nav_focus_activate.emit(key_focus_area_.GetPointer());
1024 // Signal emitted from the area itsel.969 // Signal emitted from the area itsel.
1025 static_cast<InputArea*>(key_focus_area_)->key_nav_focus_activate.emit(key_focus_area_);970 key_focus_area_->key_nav_focus_activate.emit(key_focus_area_.GetPointer());
1026 }971 }
1027 }972 }
1028 else973 else
1029 {974 {
1030 InputArea* key_nav_focus = NULL;975 InputArea* key_nav_focus = NULL;
1031 Area* parent = key_focus_area_->GetParentObject();976 Area* parent = key_focus_area_->GetParentObject();
1032 977
1033 if (parent)978 if (parent)
1034 key_nav_focus = NUX_STATIC_CAST(InputArea*, parent->KeyNavIteration(direction));979 key_nav_focus = NUX_STATIC_CAST(InputArea*, parent->KeyNavIteration(direction));
1035 980
1036 while (key_nav_focus == NULL && parent != NULL)981 while (key_nav_focus == NULL && parent != NULL)
1037 {982 {
1038 parent = parent->GetParentObject();983 parent = parent->GetParentObject();
@@ -1589,10 +1534,10 @@
1589 // End 2D Drawing1534 // End 2D Drawing
1590 }1535 }
15911536
1592 if (key_focus_area_)1537 if (key_focus_area_.IsValid())
1593 {1538 {
1594 // key focus test1539 // key focus test
1595 Geometry geo= key_focus_area_->GetRootGeometry();1540 Geometry const& geo = key_focus_area_->GetRootGeometry();
1596 //GetGraphicsDisplay()->GetGraphicsEngine()->QRP_Color(geo.x, geo.y, geo.width, geo.height, color::Blue);1541 //GetGraphicsDisplay()->GetGraphicsEngine()->QRP_Color(geo.x, geo.y, geo.width, geo.height, color::Blue);
1597 }1542 }
15981543
@@ -1851,17 +1796,6 @@
1851 return true;1796 return true;
1852 }1797 }
18531798
1854 void WindowCompositor::OnKeyNavFocusDestroyed(Object* area)
1855 {
1856 if (key_focus_area_ == area)
1857 {
1858 key_focus_area_->ResetDownwardPathToKeyFocusArea();
1859 key_focus_area_->ResetUpwardPathToKeyFocusArea();
1860
1861 key_focus_area_ = NULL;
1862 }
1863 }
1864
1865 bool WindowCompositor::SetKeyFocusArea(InputArea* area, KeyNavDirection direction)1799 bool WindowCompositor::SetKeyFocusArea(InputArea* area, KeyNavDirection direction)
1866 {1800 {
1867 InputArea* keyboard_grab_area = GetKeyboardGrabArea();1801 InputArea* keyboard_grab_area = GetKeyboardGrabArea();
@@ -1886,7 +1820,7 @@
1886 return false;1820 return false;
1887 }1821 }
18881822
1889 if (key_focus_area_)1823 if (key_focus_area_.IsValid())
1890 {1824 {
1891 // This is the area that has the keyboard focus. Emit the signal 'end_key_focus'.1825 // This is the area that has the keyboard focus. Emit the signal 'end_key_focus'.
1892 key_focus_area_->end_key_focus.emit();1826 key_focus_area_->end_key_focus.emit();
@@ -1898,9 +1832,9 @@
1898 if (key_focus_area_->Type().IsDerivedFromType(InputArea::StaticObjectType))1832 if (key_focus_area_->Type().IsDerivedFromType(InputArea::StaticObjectType))
1899 {1833 {
1900 // Signal emitted from the WindowCompositor.1834 // Signal emitted from the WindowCompositor.
1901 key_nav_focus_change.emit(key_focus_area_, false, direction);1835 key_nav_focus_change.emit(key_focus_area_.GetPointer(), false, direction);
1902 // Signal emitted from the area itself.1836 // Signal emitted from the area itself.
1903 static_cast<InputArea*>(key_focus_area_)->key_nav_focus_change.emit(key_focus_area_, false, direction);1837 key_focus_area_->key_nav_focus_change.emit(key_focus_area_.GetPointer(), false, direction);
1904 // nuxDebugMsg("[WindowCompositor::SetKeyFocusArea] Area type '%s' named '%s': Lost key nav focus.",1838 // nuxDebugMsg("[WindowCompositor::SetKeyFocusArea] Area type '%s' named '%s': Lost key nav focus.",
1905 // key_focus_area_->Type().name,1839 // key_focus_area_->Type().name,
1906 // key_focus_area_->GetBaseString().GetTCharPtr());1840 // key_focus_area_->GetBaseString().GetTCharPtr());
@@ -1908,7 +1842,7 @@
19081842
1909 if (key_focus_area_->Type().IsDerivedFromType(View::StaticObjectType))1843 if (key_focus_area_->Type().IsDerivedFromType(View::StaticObjectType))
1910 {1844 {
1911 static_cast<View*>(key_focus_area_)->QueueDraw();1845 static_cast<View*>(key_focus_area_.GetPointer())->QueueDraw();
1912 }1846 }
1913 }1847 }
19141848
@@ -1926,9 +1860,9 @@
1926 if (key_focus_area_->Type().IsDerivedFromType(InputArea::StaticObjectType))1860 if (key_focus_area_->Type().IsDerivedFromType(InputArea::StaticObjectType))
1927 {1861 {
1928 // Signal emitted from the WindowCompositor.1862 // Signal emitted from the WindowCompositor.
1929 key_nav_focus_change.emit(key_focus_area_, true, direction);1863 key_nav_focus_change.emit(key_focus_area_.GetPointer(), true, direction);
1930 // Signal emitted from the area itself.1864 // Signal emitted from the area itself.
1931 static_cast<InputArea*>(key_focus_area_)->key_nav_focus_change.emit(key_focus_area_, true, direction);1865 key_focus_area_->key_nav_focus_change.emit(key_focus_area_.GetPointer(), true, direction);
1932 // nuxDebugMsg("[WindowCompositor::SetKeyFocusArea] Area type '%s' named '%s': Has key nav focus.",1866 // nuxDebugMsg("[WindowCompositor::SetKeyFocusArea] Area type '%s' named '%s': Has key nav focus.",
1933 // key_focus_area_->Type().name,1867 // key_focus_area_->Type().name,
1934 // key_focus_area_->GetBaseString().GetTCharPtr());1868 // key_focus_area_->GetBaseString().GetTCharPtr());
@@ -1936,10 +1870,10 @@
19361870
1937 if (key_focus_area_->Type().IsDerivedFromType(View::StaticObjectType))1871 if (key_focus_area_->Type().IsDerivedFromType(View::StaticObjectType))
1938 {1872 {
1939 static_cast<View*>(key_focus_area_)->QueueDraw();1873 static_cast<View*>(key_focus_area_.GetPointer())->QueueDraw();
1940 }1874 }
19411875
1942 key_focus_area_->ChildFocusChanged.emit(key_focus_area_);1876 key_focus_area_->ChildFocusChanged.emit(key_focus_area_.GetPointer());
19431877
1944 }1878 }
1945 else1879 else
@@ -1947,24 +1881,12 @@
1947 key_focus_area_ = NULL;1881 key_focus_area_ = NULL;
1948 }1882 }
19491883
1950 key_focus_area_connection_.disconnect();1884 return key_focus_area_.IsValid() ? true : false;
1951
1952 if (area)
1953 {
1954 key_focus_area_connection_ = area->object_destroyed.connect(sigc::mem_fun(this, &WindowCompositor::OnKeyNavFocusDestroyed));
1955 }
1956
1957 if (key_focus_area_ == NULL)
1958 {
1959 return false;
1960 }
1961
1962 return true;
1963 }1885 }
19641886
1965 InputArea* WindowCompositor::GetKeyFocusArea()1887 InputArea* WindowCompositor::GetKeyFocusArea()
1966 {1888 {
1967 return key_focus_area_;1889 return key_focus_area_.GetPointer();
1968 }1890 }
19691891
1970 void WindowCompositor::SetBackgroundPaintLayer(AbstractPaintLayer* bkg)1892 void WindowCompositor::SetBackgroundPaintLayer(AbstractPaintLayer* bkg)
@@ -2220,7 +2142,7 @@
2220 keyboard_grab_stack_.push_front(area);2142 keyboard_grab_stack_.push_front(area);
2221 2143
2222 // If there is any area with the key focus, cancel it.2144 // If there is any area with the key focus, cancel it.
2223 if (key_focus_area_)2145 if (key_focus_area_.IsValid())
2224 {2146 {
2225 key_focus_area_->end_key_focus.emit();2147 key_focus_area_->end_key_focus.emit();
2226 key_focus_area_->ResetUpwardPathToKeyFocusArea();2148 key_focus_area_->ResetUpwardPathToKeyFocusArea();
@@ -2228,9 +2150,9 @@
2228 if (key_focus_area_->Type().IsDerivedFromType(InputArea::StaticObjectType))2150 if (key_focus_area_->Type().IsDerivedFromType(InputArea::StaticObjectType))
2229 {2151 {
2230 // Signal emitted from the WindowCompositor.2152 // Signal emitted from the WindowCompositor.
2231 key_nav_focus_change.emit(key_focus_area_, false, KEY_NAV_NONE);2153 key_nav_focus_change.emit(key_focus_area_.GetPointer(), false, KEY_NAV_NONE);
2232 // Signal emitted from the area itself.2154 // Signal emitted from the area itself.
2233 static_cast<InputArea*>(key_focus_area_)->key_nav_focus_change.emit(key_focus_area_, false, KEY_NAV_NONE);2155 key_focus_area_->key_nav_focus_change.emit(key_focus_area_.GetPointer(), false, KEY_NAV_NONE);
2234 // nuxDebugMsg("[WindowCompositor::GrabKeyboardAdd] Area type '%s' named '%s': Lost key nav focus.",2156 // nuxDebugMsg("[WindowCompositor::GrabKeyboardAdd] Area type '%s' named '%s': Lost key nav focus.",
2235 // key_focus_area_->Type().name,2157 // key_focus_area_->Type().name,
2236 // key_focus_area_->GetBaseString().GetTCharPtr());2158 // key_focus_area_->GetBaseString().GetTCharPtr());
@@ -2239,7 +2161,7 @@
22392161
2240 if (key_focus_area_->Type().IsDerivedFromType(View::StaticObjectType))2162 if (key_focus_area_->Type().IsDerivedFromType(View::StaticObjectType))
2241 {2163 {
2242 static_cast<View*>(key_focus_area_)->QueueDraw();2164 static_cast<View*>(key_focus_area_.GetPointer())->QueueDraw();
2243 }2165 }
2244 key_focus_area_ = NULL;2166 key_focus_area_ = NULL;
2245 }2167 }
@@ -2295,7 +2217,7 @@
2295 else2217 else
2296 {2218 {
2297 // If there is any area with the key focus, cancel it.2219 // If there is any area with the key focus, cancel it.
2298 if (key_focus_area_)2220 if (key_focus_area_.IsValid())
2299 {2221 {
2300 key_focus_area_->end_key_focus.emit();2222 key_focus_area_->end_key_focus.emit();
2301 key_focus_area_->ResetUpwardPathToKeyFocusArea();2223 key_focus_area_->ResetUpwardPathToKeyFocusArea();
@@ -2303,9 +2225,9 @@
2303 if (key_focus_area_->Type().IsDerivedFromType(InputArea::StaticObjectType))2225 if (key_focus_area_->Type().IsDerivedFromType(InputArea::StaticObjectType))
2304 {2226 {
2305 // Signal emitted from the WindowCompositor.2227 // Signal emitted from the WindowCompositor.
2306 key_nav_focus_change.emit(key_focus_area_, false, KEY_NAV_NONE);2228 key_nav_focus_change.emit(key_focus_area_.GetPointer(), false, KEY_NAV_NONE);
2307 // Signal emitted from the area itself.2229 // Signal emitted from the area itself.
2308 static_cast<InputArea*>(key_focus_area_)->key_nav_focus_change.emit(key_focus_area_, false, KEY_NAV_NONE);2230 key_focus_area_->key_nav_focus_change.emit(key_focus_area_.GetPointer(), false, KEY_NAV_NONE);
2309 // nuxDebugMsg("[WindowCompositor::GrabKeyboardRemove] Area type '%s' named '%s': Lost key nav focus.",2231 // nuxDebugMsg("[WindowCompositor::GrabKeyboardRemove] Area type '%s' named '%s': Lost key nav focus.",
2310 // key_focus_area_->Type().name,2232 // key_focus_area_->Type().name,
2311 // key_focus_area_->GetBaseString().GetTCharPtr()); 2233 // key_focus_area_->GetBaseString().GetTCharPtr());
@@ -2313,7 +2235,7 @@
23132235
2314 if (key_focus_area_->Type().IsDerivedFromType(View::StaticObjectType))2236 if (key_focus_area_->Type().IsDerivedFromType(View::StaticObjectType))
2315 {2237 {
2316 static_cast<View*>(key_focus_area_)->QueueDraw();2238 static_cast<View*>(key_focus_area_.GetPointer())->QueueDraw();
2317 }2239 }
2318 key_focus_area_ = NULL;2240 key_focus_area_ = NULL;
2319 }2241 }
23202242
=== modified file 'Nux/WindowCompositor.h'
--- Nux/WindowCompositor.h 2012-06-26 13:38:50 +0000
+++ Nux/WindowCompositor.h 2012-09-18 18:30:40 +0000
@@ -127,50 +127,38 @@
127 //! Traverse the widget tree and found the area that is right below the mouse pointer.127 //! Traverse the widget tree and found the area that is right below the mouse pointer.
128 void GetAreaUnderMouse(const Point& mouse_position,128 void GetAreaUnderMouse(const Point& mouse_position,
129 NuxEventType event_type,129 NuxEventType event_type,
130 InputArea** area_under_mouse_pointer,130 ObjectWeakPtr<InputArea>& area_under_mouse_pointer,
131 BaseWindow** window);131 ObjectWeakPtr<BaseWindow>& window);
132132
133 //! Traverse the widget tree and found the area has the key focus.133 //! Traverse the widget tree and found the area has the key focus.
134 void FindKeyFocusArea(NuxEventType event_type,134 void FindKeyFocusArea(NuxEventType event_type,
135 unsigned int key_symbol,135 unsigned int key_symbol,
136 unsigned int special_keys_state,136 unsigned int special_keys_state,
137 InputArea** key_focus_area,137 ObjectWeakPtr<InputArea>& key_focus_area,
138 BaseWindow** window);138 ObjectWeakPtr<BaseWindow>& window);
139 139
140 //! Traverse the widget tree and found the area has the key focus, but start from a specified widget.140 //! Traverse the widget tree and found the area has the key focus, but start from a specified widget.
141 void FindKeyFocusAreaFrom(NuxEventType event_type,141 void FindKeyFocusAreaFrom(NuxEventType event_type,
142 unsigned int key_symbol,142 unsigned int key_symbol,
143 unsigned int special_keys_state,143 unsigned int special_keys_state,
144 InputArea* root_search_area,144 InputArea* root_search_area,
145 InputArea** key_focus_area,145 ObjectWeakPtr<InputArea>& key_focus_area,
146 BaseWindow** window);146 ObjectWeakPtr<BaseWindow>& window);
147147
148 void ResetMousePointerAreas();148 void ResetMousePointerAreas();
149149
150 //! Get the area upon which the mouse button is currently down.150 //! Get the area upon which the mouse button is currently down.
151 Area* GetMouseOwnerArea();151 ObjectWeakPtr<InputArea> const& GetMouseOwnerArea() const;
152152
153 //! Set the area upon which the mouse button is currently down.153 //! Set the area upon which the mouse button is currently down.
154 void SetMouseOwnerArea(Area* area);154 void SetMouseOwnerArea(InputArea* area);
155155
156 //! Set the area that is right below the mouse pointer.156 //! Set the area that is right below the mouse pointer.
157 void SetMouseOverArea(Area* area);157 void SetMouseOverArea(InputArea* area);
158 158
159 //! Set The BaseWindow of the area that is the mouse owner.159 //! Set The BaseWindow of the area that is the mouse owner.
160 void SetMouseOwnerBaseWindow(BaseWindow* base_window);160 void SetMouseOwnerBaseWindow(BaseWindow* base_window);
161161
162 //! Callback: called when mouse_over_area_ is destroyed.
163 void OnMouseOverViewDestroyed(Object* area);
164
165 //! Callback: called when mouse_owner_area_ is destroyed.
166 void OnMouseOwnerViewDestroyed(Object* area);
167
168 //! Callback: called when key_focus_area_ is destroyed.
169 void OnKeyNavFocusDestroyed(Object* area);
170
171 //! Callback: called when mouse_owner_basewindow_connection_ is destroyed.
172 void OnMouseOwnerBaseWindowDestroyed(Object* area);
173
174 void SendKeyEvent(InputArea* input_area, NuxEventType event_type,162 void SendKeyEvent(InputArea* input_area, NuxEventType event_type,
175 unsigned int key_sym,163 unsigned int key_sym,
176 unsigned long x11_key_code,164 unsigned long x11_key_code,
@@ -184,19 +172,14 @@
184 The InputArea that has the mouse focus also has the keyboard focus. That is if _mouse_focus_area is not Null172 The InputArea that has the mouse focus also has the keyboard focus. That is if _mouse_focus_area is not Null
185 then _mouse_focus_area is equal to _mouse_focus_area;173 then _mouse_focus_area is equal to _mouse_focus_area;
186 */174 */
187 InputArea* key_focus_area_;175 ObjectWeakPtr<InputArea> key_focus_area_;
188 InputArea* mouse_owner_area_;176 ObjectWeakPtr<InputArea> mouse_owner_area_;
189 InputArea* mouse_over_area_;177 ObjectWeakPtr<InputArea> mouse_over_area_;
190 BaseWindow* mouse_owner_base_window_;178 ObjectWeakPtr<BaseWindow> mouse_owner_base_window_;
191179
192 int dnd_safety_x_;180 int dnd_safety_x_;
193 int dnd_safety_y_;181 int dnd_safety_y_;
194182
195 sigc::connection mouse_over_view_connection_;
196 sigc::connection mouse_owner_view_connection_;
197 sigc::connection mouse_owner_basewindow_connection_;
198 sigc::connection key_focus_area_connection_;
199
200 /*!183 /*!
201 This signal is similar to Area::key_nav_focus_change. It is emitted from the WindowCompositor.184 This signal is similar to Area::key_nav_focus_change. It is emitted from the WindowCompositor.
202 The user only needs to listen to this signal to find out the area that has received the keyboard focus.\n185 The user only needs to listen to this signal to find out the area that has received the keyboard focus.\n
@@ -682,6 +665,7 @@
682 friend class VSplitter;665 friend class VSplitter;
683 friend class TableCtrl;666 friend class TableCtrl;
684 friend class View;667 friend class View;
668 friend class TestWindowCompositor;
685 };669 };
686670
687#ifdef NUX_GESTURES_SUPPORT671#ifdef NUX_GESTURES_SUPPORT
688672
=== modified file 'configure.ac'
--- configure.ac 2012-08-30 10:57:51 +0000
+++ configure.ac 2012-09-18 18:30:40 +0000
@@ -22,7 +22,7 @@
22# The number format is : year/month/day22# The number format is : year/month/day
23# e.g.: december 5th, 2011 is: 2011120523# e.g.: december 5th, 2011 is: 20111205
24# To make more than one API change in a day, add a number to the date. Like 20111205.xx24# To make more than one API change in a day, add a number to the date. Like 20111205.xx
25m4_define([nux_abi_version], [20120813.01])25m4_define([nux_abi_version], [20120914.02])
2626
27m4_define([nux_version],27m4_define([nux_version],
28 [nux_major_version.nux_minor_version.nux_micro_version])28 [nux_major_version.nux_minor_version.nux_micro_version])
2929
=== modified file 'tests/gtest-nux-area.cpp'
--- tests/gtest-nux-area.cpp 2012-03-02 02:48:48 +0000
+++ tests/gtest-nux-area.cpp 2012-09-18 18:30:40 +0000
@@ -1,11 +1,26 @@
1#include <string>1/*
2#include <fstream>2 * Copyright 2010 Inalogic® Inc.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser 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, but
9 * WITHOUT ANY WARRANTY; without even the implied warranties of
10 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the applicable version of the GNU Lesser General Public
12 * License for more details.
13 *
14 * You should have received a copy of both the GNU Lesser General Public
15 * License version 3 along with this program. If not, see
16 * <http://www.gnu.org/licenses/>
17 *
18 * Authored by: Jay Taoko <jaytaoko@inalogic.com>
19 * Marco Trevisan <marco.trevisan@canonical.com>
20 */
321
4#include <iostream>
5#include <gmock/gmock.h>22#include <gmock/gmock.h>
6#include <boost/filesystem.hpp>23#include <boost/shared_ptr.hpp>
7#include <glib.h>
8
9#include "Nux/Nux.h"24#include "Nux/Nux.h"
10#include "Nux/HLayout.h"25#include "Nux/HLayout.h"
11#include "Nux/StaticText.h"26#include "Nux/StaticText.h"
@@ -16,14 +31,39 @@
1631
17namespace {32namespace {
1833
19TEST(TestArea, TestAreaSize)34struct MockTestView : nux::TestView
20{35{
21 nux::NuxInitialize(0);36 MockTestView()
22 nux::WindowThread *wnd_thread = nux::CreateNuxWindow("Area Test", 300, 200,37 : nux::TestView("MockTestView")
23 nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL);38 {}
2439
25 nux::TestView* test_view = new nux::TestView("");40 void SetNextObjectToKeyFocusArea(nux::Area* area)
2641 {
42 TestView::SetNextObjectToKeyFocusArea(area);
43 }
44
45 nux::Area* GetNextObjectToKeyFocusArea()
46 {
47 return TestView::GetNextObjectToKeyFocusArea();
48 }
49};
50
51struct TestArea : public testing::Test
52{
53 void SetUp()
54 {
55 nux::NuxInitialize(0);
56 wnd_thread.reset(nux::CreateNuxWindow("Area Test", 300, 200, nux::WINDOWSTYLE_NORMAL,
57 NULL, false, NULL, NULL));
58 test_view = new MockTestView();
59 }
60
61 boost::shared_ptr<nux::WindowThread> wnd_thread;
62 nux::ObjectPtr<MockTestView> test_view;
63};
64
65TEST_F(TestArea, TestAreaSize)
66{
27 EXPECT_EQ(test_view->GetMinimumWidth(), nux::AREA_MIN_WIDTH);67 EXPECT_EQ(test_view->GetMinimumWidth(), nux::AREA_MIN_WIDTH);
28 EXPECT_EQ(test_view->GetMaximumWidth(), nux::AREA_MAX_WIDTH);68 EXPECT_EQ(test_view->GetMaximumWidth(), nux::AREA_MAX_WIDTH);
29 EXPECT_EQ(test_view->GetMinimumHeight(), nux::AREA_MIN_HEIGHT);69 EXPECT_EQ(test_view->GetMinimumHeight(), nux::AREA_MIN_HEIGHT);
@@ -48,29 +88,16 @@
48 EXPECT_EQ(test_view->GetMaximumWidth(), 4321);88 EXPECT_EQ(test_view->GetMaximumWidth(), 4321);
49 EXPECT_EQ(test_view->GetMinimumHeight(), 432);89 EXPECT_EQ(test_view->GetMinimumHeight(), 432);
50 EXPECT_EQ(test_view->GetMaximumHeight(), 1234);90 EXPECT_EQ(test_view->GetMaximumHeight(), 1234);
51
52 test_view->UnReference();
53 delete wnd_thread;
54}91}
5592
56TEST(TestArea, TestAreaGeometry)93TEST_F(TestArea, TestAreaGeometry)
57{94{
58 nux::NuxInitialize(0);95 static_cast<nux::Area*>(test_view.GetPointer())->SetGeometry(0, 0, 100, 100);
59 nux::WindowThread *wnd_thread = nux::CreateNuxWindow("Area Test", 300, 200,
60 nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL);
61
62 nux::TestView* test_view = new nux::TestView("");
63
64 static_cast<nux::Area*>(test_view)->SetGeometry(0, 0, 100, 100);
6596
66 EXPECT_EQ(test_view->GetBaseX(), 0);97 EXPECT_EQ(test_view->GetBaseX(), 0);
67 EXPECT_EQ(test_view->GetBaseX(), 0);98 EXPECT_EQ(test_view->GetBaseX(), 0);
68 EXPECT_EQ(test_view->GetBaseWidth(), 100);99 EXPECT_EQ(test_view->GetBaseWidth(), 100);
69 EXPECT_EQ(test_view->GetBaseHeight(), 100);100 EXPECT_EQ(test_view->GetBaseHeight(), 100);
70
71
72 test_view->UnReference();
73 delete wnd_thread;
74}101}
75102
76static bool object_destroyed = false;103static bool object_destroyed = false;
@@ -79,31 +106,53 @@
79 object_destroyed = true;106 object_destroyed = true;
80}107}
81108
82TEST(TestArea, TestUnParentKeyFocus)109TEST_F(TestArea, TestUnParentKeyFocus)
83{110{
84 nux::NuxInitialize(0);111 nux::TestView* test_view1 = new nux::TestView("");
85 nux::WindowThread *wnd_thread = nux::CreateNuxWindow("Area Test", 300, 200,
86 nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL);
87
88 nux::HLayout* layout = new nux::HLayout();112 nux::HLayout* layout = new nux::HLayout();
89 nux::TestView* test_view = new nux::TestView("");113 test_view1->object_destroyed.connect(sigc::ptr_fun(&OnObjectDestroyed));
90 test_view->object_destroyed.connect(sigc::ptr_fun(&OnObjectDestroyed));
91114
92 test_view->Reference();115 test_view1->Reference();
93 116 layout->AddView(test_view1, 1);
94 layout->AddView(test_view, 1);
95117
96 wnd_thread->SetLayout(layout);118 wnd_thread->SetLayout(layout);
97119
98 EXPECT_EQ(test_view->HasKeyFocus(), false);120 EXPECT_EQ(test_view1->HasKeyFocus(), false);
99 nux::GetWindowThread()->GetWindowCompositor().SetKeyFocusArea(test_view);121 nux::GetWindowThread()->GetWindowCompositor().SetKeyFocusArea(test_view1);
100 EXPECT_EQ(test_view->HasKeyFocus(), true);122 EXPECT_EQ(test_view1->HasKeyFocus(), true);
101 layout->RemoveChildObject(test_view);123 layout->RemoveChildObject(test_view1);
102 EXPECT_EQ(test_view->HasKeyFocus(), false);124 EXPECT_EQ(test_view1->HasKeyFocus(), false);
103 test_view->UnReference();125 test_view1->UnReference();
104 EXPECT_EQ(object_destroyed, true);126 EXPECT_EQ(object_destroyed, true);
105127}
106 delete wnd_thread;128
129TEST_F(TestArea, NextObjectToKeyFocusSetReset)
130{
131 MockTestView* parent = new MockTestView();
132 MockTestView* brother = new MockTestView();
133 MockTestView* child1 = new MockTestView();
134 MockTestView* child2 = new MockTestView();
135 MockTestView* child3 = new MockTestView();
136
137 parent->SetNextObjectToKeyFocusArea(brother);
138 ASSERT_EQ(parent->GetNextObjectToKeyFocusArea(), brother);
139
140 child1->SetParentObject(parent);
141 child1->SetNextObjectToKeyFocusArea(child2);
142 ASSERT_EQ(child1->GetNextObjectToKeyFocusArea(), child2);
143
144 child2->SetParentObject(parent);
145 child2->SetNextObjectToKeyFocusArea(child3);
146 ASSERT_EQ(child2->GetNextObjectToKeyFocusArea(), child3);
147
148 child3->SetParentObject(parent);
149 ASSERT_EQ(child3->GetNextObjectToKeyFocusArea(), nullptr);
150
151 child1->UnReference();
152 EXPECT_EQ(child2->GetNextObjectToKeyFocusArea(), nullptr);
153 EXPECT_EQ(parent->GetNextObjectToKeyFocusArea(), nullptr);
154
155 parent->UnReference();
107}156}
108157
109}158}
110159
=== modified file 'tests/gtest-nux-input-area.cpp'
--- tests/gtest-nux-input-area.cpp 2012-09-18 18:30:40 +0000
+++ tests/gtest-nux-input-area.cpp 2012-09-18 18:30:40 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright 2012 Canonical Ltd.2 * Copyright 2010 Inalogic® Inc.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3, as5 * under the terms of the GNU Lesser General Public License version 3, as
66
=== modified file 'tests/gtest-nux-windowcompositor.cpp'
--- tests/gtest-nux-windowcompositor.cpp 2012-06-26 13:38:50 +0000
+++ tests/gtest-nux-windowcompositor.cpp 2012-09-18 18:30:40 +0000
@@ -47,17 +47,109 @@
47};47};
48#endif48#endif
4949
50TEST(TestWindowCompositor, TestSetKeyFocusArea)50struct TestBaseWindow : public nux::BaseWindow
51{51{
52 nux::NuxInitialize(0);52 TestBaseWindow() : input_area(new nux::InputArea())
53 nux::WindowThread *wnd_thread = nux::CreateNuxWindow("Nux Window", 300, 200,53 {
54 nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL);54 ShowWindow(true);
5555 }
56
57 nux::Area* FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type)
58 {
59 return input_area.GetPointer();
60 }
61
62 Area* FindKeyFocusArea(unsigned int key_symbol, unsigned long x11_key_code, unsigned long special_keys_state)
63 {
64 return input_area.GetPointer();
65 }
66
67 nux::ObjectPtr<nux::InputArea> input_area;
68};
69
70struct TestHLayout : public nux::HLayout
71{
72 TestHLayout() : input_area(new nux::InputArea()) {}
73
74 nux::Area* FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type)
75 {
76 return input_area.GetPointer();
77 }
78
79 Area* FindKeyFocusArea(unsigned int key_symbol, unsigned long x11_key_code, unsigned long special_keys_state)
80 {
81 return input_area.GetPointer();
82 }
83
84 nux::ObjectPtr<nux::InputArea> input_area;
85};
86
87}
88
89namespace nux
90{
91struct TestWindowCompositor : public testing::Test
92{
93 TestWindowCompositor()
94 {}
95
96 void SetUp()
97 {
98 nux::NuxInitialize(0);
99 wnd_thread.reset(nux::CreateNuxWindow("WindowCompositor Test", 300, 200, nux::WINDOWSTYLE_NORMAL,
100 NULL, false, NULL, NULL));
101 }
102
103 void ForceSetKeyFocusArea(nux::InputArea* area)
104 {
105 nux::GetWindowCompositor().key_focus_area_ = area;
106 }
107
108 ObjectWeakPtr<InputArea> const& GetMouseOwnerArea() const
109 {
110 return nux::GetWindowCompositor().GetMouseOwnerArea();
111 }
112
113 void SetMouseOwnerArea(InputArea* area)
114 {
115 nux::GetWindowCompositor().mouse_owner_area_ = area;
116 }
117
118 InputArea* GetMouseOverArea()
119 {
120 return nux::GetWindowCompositor().mouse_over_area_.GetPointer();
121 }
122
123 void SetMouseOverArea(InputArea* area)
124 {
125 nux::GetWindowCompositor().mouse_over_area_ = area;
126 }
127
128 void GetAreaUnderMouse(const Point& mouse_position, NuxEventType event_type,
129 ObjectWeakPtr<InputArea>& area,
130 ObjectWeakPtr<BaseWindow>& window)
131 {
132 return nux::GetWindowCompositor().GetAreaUnderMouse(mouse_position, event_type, area, window);
133 }
134
135 void FindKeyFocusArea(NuxEventType event_type, unsigned int key_symbol,
136 unsigned int state,
137 ObjectWeakPtr<InputArea>& key_focus_area,
138 ObjectWeakPtr<BaseWindow>& window)
139 {
140 return nux::GetWindowCompositor().FindKeyFocusArea(event_type, key_symbol, state, key_focus_area, window);
141 }
142
143 boost::shared_ptr<nux::WindowThread> wnd_thread;
144};
145
146TEST_F(TestWindowCompositor, TestSetKeyFocusArea)
147{
56 nux::TestView* test_view0 = new nux::TestView();148 nux::TestView* test_view0 = new nux::TestView();
57 nux::TestView* test_view1 = new nux::TestView();149 nux::TestView* test_view1 = new nux::TestView();
58150
59 nux::HLayout* layout = new nux::HLayout();151 nux::HLayout* layout = new nux::HLayout();
60 152
61 layout->AddView(test_view0, 1);153 layout->AddView(test_view0, 1);
62 layout->AddView(test_view1, 1);154 layout->AddView(test_view1, 1);
63155
@@ -89,8 +181,6 @@
89 EXPECT_EQ(test_view1->registered_begin_keynav_focus_, true);181 EXPECT_EQ(test_view1->registered_begin_keynav_focus_, true);
90 EXPECT_EQ(test_view1->registered_end_keynav_focus_, false);182 EXPECT_EQ(test_view1->registered_end_keynav_focus_, false);
91 }183 }
92
93 delete wnd_thread;
94}184}
95185
96#ifdef NUX_GESTURES_SUPPORT186#ifdef NUX_GESTURES_SUPPORT
@@ -104,11 +194,8 @@
104 Check that the gesture got accepted, that window A got the gesture194 Check that the gesture got accepted, that window A got the gesture
105 events and that window B didn't get anything.195 events and that window B didn't get anything.
106 */196 */
107TEST(TestWindowCompositor, GestureEventsDelivery_1)197TEST_F(TestWindowCompositor, GestureEventsDelivery_1)
108{198{
109 nux::NuxInitialize(0);
110 nux::WindowThread *wnd_thread = nux::CreateNuxWindow("Nux Window", 500, 500,
111 nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL);
112 nux::WindowCompositor &wnd_compositor = wnd_thread->GetWindowCompositor();199 nux::WindowCompositor &wnd_compositor = wnd_thread->GetWindowCompositor();
113 nux::FakeGestureEvent fake_event;200 nux::FakeGestureEvent fake_event;
114201
@@ -159,7 +246,6 @@
159246
160 target_window->Dispose();247 target_window->Dispose();
161 innocent_window->Dispose();248 innocent_window->Dispose();
162 delete wnd_thread;
163}249}
164250
165/*251/*
@@ -171,13 +257,10 @@
171 Check that the gesture got rejected and that no window got257 Check that the gesture got rejected and that no window got
172 any gesture event.258 any gesture event.
173*/259*/
174TEST(TestWindowCompositor, GestureEventsDelivery_2)260TEST_F(TestWindowCompositor, GestureEventsDelivery_2)
175{261{
176 nux::NuxInitialize(0);
177 nux::WindowThread *wnd_thread = nux::CreateNuxWindow("Nux Window", 500, 500,
178 nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL);
179 nux::WindowCompositor &wnd_compositor = wnd_thread->GetWindowCompositor();
180 nux::FakeGestureEvent fake_event;262 nux::FakeGestureEvent fake_event;
263 nux::WindowCompositor& wnd_compositor = nux::GetWindowCompositor();
181264
182 TestWindow *subscribed_window = new TestWindow;265 TestWindow *subscribed_window = new TestWindow;
183 subscribed_window->SetBaseXY(10, 10);266 subscribed_window->SetBaseXY(10, 10);
@@ -212,7 +295,6 @@
212295
213 subscribed_window->Dispose();296 subscribed_window->Dispose();
214 innocent_window->Dispose();297 innocent_window->Dispose();
215 delete wnd_thread;
216}298}
217299
218/*300/*
@@ -225,13 +307,10 @@
225 Check that the gesture gets accepted and that only the input area behind that307 Check that the gesture gets accepted and that only the input area behind that
226 window gets the gesture events.308 window gets the gesture events.
227 */309 */
228TEST(TestWindowCompositor, GestureEventsDelivery_3)310TEST_F(TestWindowCompositor, GestureEventsDelivery_3)
229{311{
230 nux::NuxInitialize(0);
231 nux::WindowThread *wnd_thread = nux::CreateNuxWindow("Nux Window", 500, 500,
232 nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL);
233 nux::WindowCompositor &wnd_compositor = wnd_thread->GetWindowCompositor();
234 nux::FakeGestureEvent fake_event;312 nux::FakeGestureEvent fake_event;
313 nux::WindowCompositor& wnd_compositor = nux::GetWindowCompositor();
235314
236 TestWindow *window = new TestWindow;315 TestWindow *window = new TestWindow;
237 window->SetBaseXY(10, 10);316 window->SetBaseXY(10, 10);
@@ -287,20 +366,16 @@
287 ASSERT_EQ(0, other_input_area->gesture_events_received.size());366 ASSERT_EQ(0, other_input_area->gesture_events_received.size());
288367
289 window->Dispose();368 window->Dispose();
290 delete wnd_thread;
291}369}
292370
293/*371/*
294 Check that if a gesture gets its construction finished only on its end event,372 Check that if a gesture gets its construction finished only on its end event,
295 it still gets accepted and delivered.373 it still gets accepted and delivered.
296 */374 */
297TEST(TestWindowCompositor, GestureEventsDelivery_4)375TEST_F(TestWindowCompositor, GestureEventsDelivery_4)
298{376{
299 nux::NuxInitialize(0);
300 nux::WindowThread *wnd_thread = nux::CreateNuxWindow("Nux Window", 500, 500,
301 nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL);
302 nux::WindowCompositor &wnd_compositor = wnd_thread->GetWindowCompositor();
303 nux::FakeGestureEvent fake_event;377 nux::FakeGestureEvent fake_event;
378 nux::WindowCompositor& wnd_compositor = nux::GetWindowCompositor();
304379
305 TestWindow *window = new TestWindow;380 TestWindow *window = new TestWindow;
306 window->SetBaseXY(10, 10);381 window->SetBaseXY(10, 10);
@@ -356,7 +431,110 @@
356 ASSERT_EQ(0, other_input_area->gesture_events_received.size());431 ASSERT_EQ(0, other_input_area->gesture_events_received.size());
357432
358 window->Dispose();433 window->Dispose();
359 delete wnd_thread;434}
435
436TEST_F(TestWindowCompositor, KeyFocusAreaAutomaticallyUnsets)
437{
438 nux::WindowCompositor& wnd_compositor = nux::GetWindowCompositor();
439 nux::InputArea* test_area = new TestInputArea();
440
441 ForceSetKeyFocusArea(test_area);
442 ASSERT_EQ(wnd_compositor.GetKeyFocusArea(), test_area);
443
444 test_area->UnReference();
445 EXPECT_EQ(wnd_compositor.GetKeyFocusArea(), nullptr);
446}
447
448TEST_F(TestWindowCompositor, MouseOverAreaAutomaticallyUnsets)
449{
450 nux::InputArea* test_area = new TestInputArea();
451
452 SetMouseOverArea(test_area);
453 ASSERT_EQ(GetMouseOverArea(), test_area);
454
455 test_area->UnReference();
456 EXPECT_EQ(GetMouseOverArea(), nullptr);
457}
458
459TEST_F(TestWindowCompositor, MouseOwnerAreaAutomaticallyUnsets)
460{
461 nux::InputArea* test_area = new TestInputArea();
462
463 SetMouseOwnerArea(test_area);
464 ASSERT_EQ(GetMouseOwnerArea(), test_area);
465
466 test_area->UnReference();
467 EXPECT_EQ(GetMouseOwnerArea(), nullptr);
468}
469
470TEST_F(TestWindowCompositor, GetAreaUnderMouse)
471{
472 ObjectWeakPtr<InputArea> area;
473 ObjectWeakPtr<BaseWindow> window;
474
475 TestBaseWindow* test_win = new TestBaseWindow();
476
477 GetAreaUnderMouse(Point(1, 2), NUX_MOUSE_MOVE, area, window);
478
479 EXPECT_EQ(area.GetPointer(), test_win->input_area.GetPointer());
480 EXPECT_EQ(window.GetPointer(), test_win);
481
482 test_win->UnReference();
483 EXPECT_EQ(area.GetPointer(), nullptr);
484 EXPECT_EQ(window.GetPointer(), nullptr);
485}
486
487TEST_F(TestWindowCompositor, GetAreaUnderMouseFallback)
488{
489 ObjectWeakPtr<InputArea> area;
490 ObjectWeakPtr<BaseWindow> window;
491
492 TestHLayout* layout = new TestHLayout();
493 wnd_thread->SetLayout(layout);
494
495 GetAreaUnderMouse(Point(1, 2), NUX_MOUSE_MOVE, area, window);
496
497 EXPECT_EQ(area.GetPointer(), layout->input_area.GetPointer());
498 EXPECT_EQ(window.GetPointer(), nullptr);
499
500 wnd_thread->SetLayout(nullptr);
501 layout->UnReference();
502 EXPECT_EQ(area.GetPointer(), nullptr);
503}
504
505TEST_F(TestWindowCompositor, GetFocusedArea)
506{
507 ObjectWeakPtr<InputArea> area;
508 ObjectWeakPtr<BaseWindow> window;
509
510 TestBaseWindow* test_win = new TestBaseWindow();
511
512 FindKeyFocusArea(NUX_KEYUP, 0, 0, area, window);
513
514 EXPECT_EQ(area.GetPointer(), test_win->input_area.GetPointer());
515 EXPECT_EQ(window.GetPointer(), test_win);
516
517 test_win->UnReference();
518 EXPECT_EQ(area.GetPointer(), nullptr);
519 EXPECT_EQ(window.GetPointer(), nullptr);
520}
521
522TEST_F(TestWindowCompositor, GetFocusedAreaFallback)
523{
524 ObjectWeakPtr<InputArea> area;
525 ObjectWeakPtr<BaseWindow> window;
526
527 TestHLayout* layout = new TestHLayout();
528 wnd_thread->SetLayout(layout);
529
530 FindKeyFocusArea(NUX_KEYUP, 0, 0, area, window);
531
532 EXPECT_EQ(area.GetPointer(), layout->input_area.GetPointer());
533 EXPECT_EQ(window.GetPointer(), nullptr);
534
535 wnd_thread->SetLayout(nullptr);
536 layout->UnReference();
537 EXPECT_EQ(area.GetPointer(), nullptr);
360}538}
361539
362#endif // NUX_GESTURES_SUPPORT540#endif // NUX_GESTURES_SUPPORT

Subscribers

People subscribed via source and target branches