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
1=== modified file 'Nux/Area.cpp'
2--- Nux/Area.cpp 2012-05-31 21:50:05 +0000
3+++ Nux/Area.cpp 2012-09-18 18:30:40 +0000
4@@ -68,6 +68,8 @@
5
6 Area::~Area()
7 {
8+ ResetDownwardPathToKeyFocusArea();
9+ ResetUpwardPathToKeyFocusArea();
10 }
11
12 const NString &Area::GetBaseString() const
13
14=== modified file 'Nux/WindowCompositor.cpp'
15--- Nux/WindowCompositor.cpp 2012-08-02 17:46:47 +0000
16+++ Nux/WindowCompositor.cpp 2012-09-18 18:30:40 +0000
17@@ -58,7 +58,6 @@
18 m_CurrentWindow = NULL;
19 m_MenuWindow = NULL;
20 _mouse_over_area = NULL;
21- key_focus_area_ = NULL;
22 _always_on_front_window = NULL;
23 inside_event_cycle_ = false;
24 inside_rendering_cycle_ = false;
25@@ -67,11 +66,8 @@
26 _pending_exclusive_input_mode_action = false;
27
28 _dnd_area = NULL;
29- mouse_over_area_ = NULL;
30- mouse_owner_area_ = NULL;
31 _mouse_over_menu_page = NULL;
32 _mouse_owner_menu_page = NULL;
33- mouse_owner_base_window_ = NULL;
34 _starting_menu_event_cycle = false;
35 _menu_is_active = false;
36 _enable_nux_new_event_architecture = true;
37@@ -99,12 +95,7 @@
38
39 void WindowCompositor::BeforeDestructor()
40 {
41- if (key_focus_area_)
42- {
43- key_focus_area_->ResetDownwardPathToKeyFocusArea();
44- key_focus_area_->ResetUpwardPathToKeyFocusArea();
45- key_focus_area_ = NULL;
46- }
47+ key_focus_area_ = NULL;
48 }
49
50 WindowCompositor::~WindowCompositor()
51@@ -186,17 +177,12 @@
52 {
53 _view_window_list.erase(it);
54
55- if (_view_window_list.size())
56+ if (!_view_window_list.empty())
57 m_SelectedWindow = _view_window_list.front();
58 }
59 _window_to_texture_map.erase(window.GetPointer());
60 }
61
62- Area* WindowCompositor::GetMouseOwnerArea()
63- {
64- return mouse_owner_area_;
65- }
66-
67 //! Get Mouse position relative to the top left corner of the window.
68 Point WindowCompositor::GetMousePosition()
69 {
70@@ -213,24 +199,24 @@
71
72 void WindowCompositor::GetAreaUnderMouse(const Point& mouse_position,
73 NuxEventType event_type,
74- InputArea** area_under_mouse_pointer,
75- BaseWindow** window)
76+ ObjectWeakPtr<InputArea>& area_under_mouse_pointer,
77+ ObjectWeakPtr<BaseWindow>& window)
78 {
79- *area_under_mouse_pointer = NULL;
80+ window = NULL;
81+ area_under_mouse_pointer = NULL;
82
83 // Go through the list of BaseWindo and find the first area over which the
84 // mouse pointer is.
85 WindowList::iterator window_it;
86-
87 for (window_it = _view_window_list.begin(); window_it != _view_window_list.end(); ++window_it)
88 {
89 if ((*window_it).IsValid() && (*window_it)->IsVisible())
90 {
91- InputArea* area = static_cast<InputArea*>((*window_it)->FindAreaUnderMouse(mouse_position, event_type));
92+ Area* area = (*window_it)->FindAreaUnderMouse(mouse_position, event_type);
93 if (area)
94 {
95- *area_under_mouse_pointer = area;
96- *window = (*window_it).GetPointer();
97+ area_under_mouse_pointer = static_cast<InputArea*>(area);
98+ window = *window_it;
99 return;
100 }
101 }
102@@ -238,91 +224,55 @@
103
104 // If area_under_mouse_pointer is NULL, then the mouse pointer is not over
105 // any of the BaseWindow. Try the main window layout.
106- if (*area_under_mouse_pointer == NULL)
107+ if (!area_under_mouse_pointer.IsValid())
108 {
109 Layout* main_window_layout = window_thread_->GetLayout();
110 if (main_window_layout)
111- *area_under_mouse_pointer = static_cast<InputArea*>(main_window_layout->FindAreaUnderMouse(mouse_position, event_type));
112- }
113- }
114-
115- void WindowCompositor::OnMouseOverViewDestroyed(Object* object)
116- {
117- if (mouse_over_area_ == object)
118- {
119- mouse_over_area_ = NULL;
120- }
121- }
122-
123- void WindowCompositor::SetMouseOverArea(Area* area)
124- {
125- mouse_over_area_ = static_cast<InputArea*>(area);
126-
127- mouse_over_view_connection_.disconnect();
128-
129- if (mouse_over_area_)
130- {
131- mouse_over_view_connection_ = mouse_over_area_->object_destroyed.connect(sigc::mem_fun(this, &WindowCompositor::OnMouseOverViewDestroyed));
132- }
133- }
134-
135- void WindowCompositor::OnMouseOwnerViewDestroyed(Object* object)
136- {
137- if (mouse_owner_area_ == object)
138- {
139- mouse_owner_area_ = NULL;
140- }
141- }
142-
143- void WindowCompositor::SetMouseOwnerArea(Area* area)
144+ area_under_mouse_pointer = static_cast<InputArea*>(main_window_layout->FindAreaUnderMouse(mouse_position, event_type));
145+ }
146+ }
147+
148+ void WindowCompositor::SetMouseOverArea(InputArea* area)
149+ {
150+ if (mouse_over_area_ == area)
151+ return;
152+
153+ mouse_over_area_ = area;
154+ }
155+
156+ void WindowCompositor::SetMouseOwnerArea(InputArea* area)
157 {
158 if (mouse_owner_area_ == area)
159 return;
160
161- mouse_owner_area_ = static_cast<InputArea*>(area);
162+ mouse_owner_area_ = area;
163 dnd_safety_x_ = 0;
164 dnd_safety_y_ = 0;
165-
166- mouse_owner_view_connection_.disconnect();
167-
168- if (mouse_owner_area_)
169- {
170- mouse_owner_view_connection_ = mouse_owner_area_->object_destroyed.connect(sigc::mem_fun(this, &WindowCompositor::OnMouseOwnerViewDestroyed));
171- }
172 }
173
174- void WindowCompositor::OnMouseOwnerBaseWindowDestroyed(Object* object)
175+ ObjectWeakPtr<InputArea> const& WindowCompositor::GetMouseOwnerArea() const
176 {
177- if (mouse_owner_base_window_ == object)
178- {
179- mouse_owner_base_window_ = NULL;
180- }
181+ return mouse_owner_area_;
182 }
183
184 void WindowCompositor::SetMouseOwnerBaseWindow(BaseWindow* base_window)
185 {
186- mouse_owner_base_window_ = base_window;
187-
188- mouse_owner_basewindow_connection_.disconnect();
189-
190- if (mouse_owner_base_window_)
191- {
192- mouse_owner_basewindow_connection_ = mouse_owner_base_window_->object_destroyed.connect(sigc::mem_fun(this, &WindowCompositor::OnMouseOwnerBaseWindowDestroyed));
193- }
194+ if (mouse_owner_base_window_ != base_window)
195+ mouse_owner_base_window_ = base_window;
196 }
197
198 void WindowCompositor::DndEventCycle(Event& event)
199 {
200 if (event.type == NUX_DND_MOVE)
201 {
202- InputArea* hit_area = NULL;
203- BaseWindow* hit_base_window = NULL;
204-
205- GetAreaUnderMouse(Point(event.x, event.y), event.type, &hit_area, &hit_base_window);
206-
207- if (hit_area)
208+ ObjectWeakPtr<InputArea> hit_area;
209+ ObjectWeakPtr<BaseWindow> hit_base_window;
210+
211+ GetAreaUnderMouse(Point(event.x, event.y), event.type, hit_area, hit_base_window);
212+
213+ if (hit_area.IsValid())
214 {
215- SetDnDArea(hit_area);
216+ SetDnDArea(hit_area.GetPointer());
217 hit_area->HandleDndMove(event);
218 }
219 else
220@@ -356,7 +306,7 @@
221
222 _mouse_position = Point(event.x, event.y);
223
224- if (mouse_owner_area_ == NULL)
225+ if (!mouse_owner_area_.IsValid())
226 {
227 // Context: The left mouse button is not down over an area.
228 // We look for the area where the mouse pointer is located.
229@@ -370,8 +320,8 @@
230 (event.type == NUX_WINDOW_MOUSELEAVE) ||
231 (event.type == NUX_MOUSE_RELEASED))
232 {
233- InputArea* hit_view = NULL; // The view under the mouse
234- BaseWindow* hit_base_window = NULL; // The BaseWindow below the mouse pointer.
235+ ObjectWeakPtr<InputArea> hit_view; // The view under the mouse
236+ ObjectWeakPtr<BaseWindow> hit_base_window; // The BaseWindow below the mouse pointer.
237
238 // Look for the area below the mouse pointer in the BaseWindow.
239 Area* pointer_grab_area = GetPointerGrabArea();
240@@ -379,7 +329,7 @@
241 {
242 // If there is a pending mouse pointer grab, test that area only
243 hit_view = NUX_STATIC_CAST(InputArea*, pointer_grab_area->FindAreaUnderMouse(Point(event.x, event.y), event.type));
244- if ((hit_view == NULL) && (event.type == NUX_MOUSE_PRESSED))
245+ if (!hit_view.IsValid() && event.type == NUX_MOUSE_PRESSED)
246 {
247 Geometry geo = pointer_grab_area->GetAbsoluteGeometry();
248 int x = event.x - geo.x;
249@@ -390,15 +340,15 @@
250 }
251 else
252 {
253- GetAreaUnderMouse(Point(event.x, event.y), event.type, &hit_view, &hit_base_window);
254- SetMouseOwnerBaseWindow(hit_base_window);
255+ GetAreaUnderMouse(Point(event.x, event.y), event.type, hit_view, hit_base_window);
256+ SetMouseOwnerBaseWindow(hit_base_window.GetPointer());
257 }
258
259 Geometry hit_view_geo;
260 int hit_view_x = 0;
261 int hit_view_y = 0;
262
263- if (hit_view)
264+ if (hit_view.IsValid())
265 {
266 hit_view_geo = hit_view->GetAbsoluteGeometry();
267 hit_view_x = event.x - hit_view_geo.x;
268@@ -407,11 +357,11 @@
269
270 if (event.type == NUX_WINDOW_MOUSELEAVE)
271 {
272- if (mouse_over_area_ != NULL)
273+ if (mouse_over_area_.IsValid())
274 {
275 // The area where the mouse was in the previous cycle and the area returned by GetAreaUnderMouse are different.
276 // The area from the previous cycle receive a "mouse leave signal".
277- Geometry geo = mouse_over_area_->GetAbsoluteGeometry();
278+ Geometry const& geo = mouse_over_area_->GetAbsoluteGeometry();
279 int x = event.x - geo.x;
280 int y = event.y - geo.y;
281
282@@ -419,28 +369,28 @@
283 SetMouseOverArea(NULL);
284 }
285 }
286- else if (hit_view && (event.type == NUX_MOUSE_MOVE))
287+ else if (hit_view.IsValid() && event.type == NUX_MOUSE_MOVE)
288 {
289 bool emit_delta = true;
290 if (hit_view != mouse_over_area_)
291 {
292- if (mouse_over_area_ != NULL)
293+ if (mouse_over_area_.IsValid())
294 {
295 // The area where the mouse was in the previous cycle and the area returned by GetAreaUnderMouse are different.
296 // The area from the previous cycle receive a "mouse leave signal".
297- Geometry geo = mouse_over_area_->GetAbsoluteGeometry();
298+ Geometry const& geo = mouse_over_area_->GetAbsoluteGeometry();
299 int x = event.x - geo.x;
300 int y = event.y - geo.y;
301
302 mouse_over_area_->EmitMouseLeaveSignal(x, y, event.GetMouseState(), event.GetKeyState());
303 }
304 // The area we found under the mouse pointer receives a "mouse enter signal".
305- SetMouseOverArea(hit_view);
306+ SetMouseOverArea(hit_view.GetPointer());
307
308- if (mouse_over_area_ != GetKeyFocusArea() &&
309- mouse_over_area_ && mouse_over_area_->AcceptKeyNavFocusOnMouseEnter())
310+ if (mouse_over_area_.IsValid() && mouse_over_area_ != GetKeyFocusArea() &&
311+ mouse_over_area_->AcceptKeyNavFocusOnMouseEnter())
312 {
313- SetKeyFocusArea(mouse_over_area_);
314+ SetKeyFocusArea(mouse_over_area_.GetPointer());
315 }
316
317
318@@ -451,16 +401,16 @@
319 // Send a "mouse mouse signal".
320 mouse_over_area_->EmitMouseMoveSignal(hit_view_x, hit_view_y, emit_delta ? dx : 0, emit_delta ? dy : 0, event.GetMouseState(), event.GetKeyState());
321 }
322- else if (hit_view && ((event.type == NUX_MOUSE_PRESSED) || (event.type == NUX_MOUSE_DOUBLECLICK)))
323+ else if (hit_view.IsValid() && (event.type == NUX_MOUSE_PRESSED || event.type == NUX_MOUSE_DOUBLECLICK))
324 {
325- if ((event.type == NUX_MOUSE_DOUBLECLICK) && (!hit_view->DoubleClickEnabled()))
326+ if (event.type == NUX_MOUSE_DOUBLECLICK && !hit_view->DoubleClickEnabled())
327 {
328 // If the area does not accept double click events, transform the event into a mouse pressed.
329 event.type = NUX_MOUSE_PRESSED;
330 }
331
332 bool emit_double_click_signal = false;
333- if (mouse_over_area_ && (hit_view != mouse_over_area_))
334+ if (mouse_over_area_.IsValid() && hit_view != mouse_over_area_)
335 {
336 // The area where the mouse was in the previous cycle and the area returned by GetAreaUnderMouse are different.
337 // The area from the previous cycle receive a "mouse leave signal".
338@@ -473,29 +423,29 @@
339
340 mouse_over_area_->EmitMouseLeaveSignal(x, y, event.GetMouseState(), event.GetKeyState());
341 }
342- else if (mouse_over_area_ && (hit_view == mouse_over_area_) && (event.type == NUX_MOUSE_DOUBLECLICK))
343+ else if (mouse_over_area_.IsValid() && hit_view == mouse_over_area_ && event.type == NUX_MOUSE_DOUBLECLICK)
344 {
345 // Double click is emitted, if the second click happened on the same area as the first click.
346 // This means mouse_over_area_ is not null and is equal to hit_view.
347 emit_double_click_signal = true;
348 }
349
350- SetMouseOverArea(hit_view);
351- SetMouseOwnerArea(hit_view);
352+ SetMouseOverArea(hit_view.GetPointer());
353+ SetMouseOwnerArea(hit_view.GetPointer());
354 _mouse_position_on_owner = Point(hit_view_x, hit_view_y);
355
356 // In the case of a mouse down event, if there is currently a keyboard event receiver and it is different
357 // from the area returned by GetAreaUnderMouse, then stop that receiver from receiving anymore keyboard events and switch
358 // make mouse_over_area_ the new receiver(if it accept keyboard events).
359- if (mouse_over_area_ != GetKeyFocusArea() &&
360- mouse_over_area_ && mouse_over_area_->AcceptKeyNavFocusOnMouseDown())
361+ if (mouse_over_area_.IsValid() && mouse_over_area_ != GetKeyFocusArea() &&
362+ mouse_over_area_->AcceptKeyNavFocusOnMouseDown())
363 {
364 InputArea* grab_area = GetKeyboardGrabArea();
365 if (grab_area)
366 {
367 if (mouse_over_area_->IsChildOf(grab_area) /*&& mouse_over_area_->AcceptKeyboardEvent()*/)
368 {
369- SetKeyFocusArea(mouse_over_area_);
370+ SetKeyFocusArea(mouse_over_area_.GetPointer());
371 }
372 else
373 {
374@@ -504,7 +454,7 @@
375 }
376 else
377 {
378- SetKeyFocusArea(mouse_over_area_);
379+ SetKeyFocusArea(mouse_over_area_.GetPointer());
380 }
381 }
382
383@@ -517,11 +467,11 @@
384 mouse_over_area_->EmitMouseDownSignal(hit_view_x, hit_view_y, event.GetMouseState(), event.GetKeyState());
385 }
386 }
387- else if (hit_view && (event.type == NUX_MOUSE_WHEEL))
388+ else if (hit_view.IsValid() && (event.type == NUX_MOUSE_WHEEL))
389 {
390 hit_view->EmitMouseWheelSignal(hit_view_x, hit_view_y, event.wheel_delta, event.GetMouseState(), event.GetKeyState());
391 }
392- else if (hit_view && (event.type == NUX_MOUSE_RELEASED))
393+ else if (hit_view.IsValid() && (event.type == NUX_MOUSE_RELEASED))
394 {
395 // We only get a NUX_MOUSE_RELEASED event when the mouse was pressed
396 // over another area and released here. There are a few situations that can cause
397@@ -533,11 +483,11 @@
398
399 hit_view->EmitMouseUpSignal(hit_view_x, hit_view_y, event.GetMouseState(), event.GetKeyState());
400 }
401- else if (hit_view == NULL)
402+ else if (!hit_view.IsValid())
403 {
404- if (mouse_over_area_)
405+ if (mouse_over_area_.IsValid())
406 {
407- Geometry geo = mouse_over_area_->GetAbsoluteGeometry();
408+ Geometry const& geo = mouse_over_area_->GetAbsoluteGeometry();
409 int x = event.x - geo.x;
410 int y = event.y - geo.y;
411
412@@ -570,13 +520,12 @@
413 {
414 // Context: The left mouse button down over an area. All events goes to that area.
415 // But we still need to know where the mouse is.
416-
417- InputArea* hit_view = NULL; // The view under the mouse
418- BaseWindow* hit_base_window = NULL; // The BaseWindow below the mouse pointer.
419-
420- GetAreaUnderMouse(Point(event.x, event.y), event.type, &hit_view, &hit_base_window);
421-
422- Geometry mouse_owner_geo = mouse_owner_area_->GetAbsoluteGeometry();
423+ ObjectWeakPtr<InputArea> hit_view; // The view under the mouse
424+ ObjectWeakPtr<BaseWindow> hit_base_window; // The BaseWindow below the mouse pointer.
425+
426+ GetAreaUnderMouse(Point(event.x, event.y), event.type, hit_view, hit_base_window);
427+
428+ Geometry const& mouse_owner_geo = mouse_owner_area_->GetAbsoluteGeometry();
429 int mouse_owner_x = event.x - mouse_owner_geo.x;
430 int mouse_owner_y = event.y - mouse_owner_geo.y;
431
432@@ -605,15 +554,15 @@
433 mouse_owner_area_->EmitMouseDragSignal(mouse_owner_x, mouse_owner_y, dx, dy, event.GetMouseState(), event.GetKeyState());
434 }
435
436- if ((mouse_over_area_ == mouse_owner_area_) && (hit_view != mouse_owner_area_))
437+ if (mouse_over_area_ == mouse_owner_area_ && hit_view != mouse_owner_area_)
438 {
439 mouse_owner_area_->EmitMouseLeaveSignal(mouse_owner_x, mouse_owner_y, event.GetMouseState(), event.GetKeyState());
440- SetMouseOverArea(hit_view);
441+ SetMouseOverArea(hit_view.GetPointer());
442 }
443- else if ((mouse_over_area_ != mouse_owner_area_) && (hit_view == mouse_owner_area_))
444+ else if (mouse_over_area_ != mouse_owner_area_ && hit_view == mouse_owner_area_)
445 {
446 mouse_owner_area_->EmitMouseEnterSignal(mouse_owner_x, mouse_owner_y, event.GetMouseState(), event.GetKeyState());
447- SetMouseOverArea(mouse_owner_area_);
448+ SetMouseOverArea(mouse_owner_area_.GetPointer());
449 }
450
451 _mouse_position_on_owner = Point(mouse_owner_x, mouse_owner_y);
452@@ -625,11 +574,11 @@
453 if (hit_view == mouse_owner_area_)
454 {
455 mouse_owner_area_->EmitMouseClickSignal(mouse_owner_x, mouse_owner_y, event.GetMouseState(), event.GetKeyState());
456- SetMouseOverArea(mouse_owner_area_);
457+ SetMouseOverArea(mouse_owner_area_.GetPointer());
458 }
459 else
460 {
461- SetMouseOverArea(hit_view);
462+ SetMouseOverArea(hit_view.GetPointer());
463 }
464
465 SetMouseOwnerArea(NULL);
466@@ -823,36 +772,36 @@
467 void WindowCompositor::FindKeyFocusArea(NuxEventType event_type,
468 unsigned int key_symbol,
469 unsigned int special_keys_state,
470- InputArea** key_focus_area,
471- BaseWindow** window)
472+ ObjectWeakPtr<InputArea>& key_focus_area,
473+ ObjectWeakPtr<BaseWindow>& window)
474 {
475- *key_focus_area = NULL;
476- *window = NULL;
477+ key_focus_area = NULL;
478+ window = NULL;
479
480 // Go through the list of BaseWindos and find the first area over which the mouse pointer is.
481 WindowList::iterator window_it;
482 window_it = _view_window_list.begin();
483- while ((*key_focus_area == NULL) && (window_it != _view_window_list.end()))
484+ while (!key_focus_area.IsValid() && window_it != _view_window_list.end())
485 {
486 if ((*window_it).IsValid() && (*window_it)->IsVisible())
487 {
488- *key_focus_area = NUX_STATIC_CAST(InputArea*, (*window_it)->FindKeyFocusArea(event_type, key_symbol, special_keys_state));
489- if (key_focus_area)
490+ key_focus_area = NUX_STATIC_CAST(InputArea*, (*window_it)->FindKeyFocusArea(event_type, key_symbol, special_keys_state));
491+ if (key_focus_area.IsValid())
492 {
493 // We have found an area. We are going to exit the while loop.
494- *window = (*window_it).GetPointer();
495+ window = *window_it;
496 }
497 }
498 ++window_it;
499 }
500
501 // If key_focus_area is NULL, then try the main window layout.
502- if (*key_focus_area == NULL)
503+ if (!key_focus_area.IsValid())
504 {
505 Layout* main_window_layout = window_thread_->GetLayout();
506 if (main_window_layout)
507 {
508- *key_focus_area = NUX_STATIC_CAST(InputArea*, main_window_layout->FindKeyFocusArea(event_type, key_symbol, special_keys_state));
509+ key_focus_area = NUX_STATIC_CAST(InputArea*, main_window_layout->FindKeyFocusArea(event_type, key_symbol, special_keys_state));
510 }
511 }
512 }
513@@ -861,21 +810,21 @@
514 unsigned int key_symbol,
515 unsigned int special_keys_state,
516 InputArea* root_search_area,
517- InputArea** key_focus_area,
518- BaseWindow** window)
519+ ObjectWeakPtr<InputArea>& key_focus_area,
520+ ObjectWeakPtr<BaseWindow>& window)
521 {
522- *key_focus_area = NULL;
523- *window = NULL;
524+ key_focus_area = NULL;
525+ window = NULL;
526
527 if (root_search_area == NULL)
528 {
529 return;
530 }
531
532- *key_focus_area = NUX_STATIC_CAST(InputArea*, root_search_area->FindKeyFocusArea(event_type, key_symbol, special_keys_state));
533- if (key_focus_area)
534+ key_focus_area = NUX_STATIC_CAST(InputArea*, root_search_area->FindKeyFocusArea(event_type, key_symbol, special_keys_state));
535+ if (key_focus_area.IsValid())
536 {
537- *window = NUX_STATIC_CAST(BaseWindow*, root_search_area->GetTopLevelViewWindow());
538+ window = NUX_STATIC_CAST(BaseWindow*, root_search_area->GetTopLevelViewWindow());
539 }
540 }
541
542@@ -908,25 +857,21 @@
543 {
544 InputArea* keyboard_event_grab_view = GetKeyboardGrabArea();
545
546- InputArea* focus_area = NULL; // The view under the mouse
547- BaseWindow* base_window = NULL; // The BaseWindow below the mouse pointer.
548+ ObjectWeakPtr<InputArea> focus_area; // The view under the mouse
549+ ObjectWeakPtr<BaseWindow> base_window; // The BaseWindow below the mouse pointer.
550
551 if (keyboard_event_grab_view)
552 {
553 // There is a keyboard grab.
554 // Find the key focus area, under the keyboard grab area. That is to say, the key focus area is in the widget tree
555 // whose root is the keyboard grab area. This phase is known as the capture phase.
556-
557 FindKeyFocusAreaFrom(event.type, event.GetKeySym(), event.GetKeyState(),
558- keyboard_event_grab_view,
559- &focus_area,
560- &base_window);
561+ keyboard_event_grab_view, focus_area, base_window);
562 }
563 else
564 {
565 FindKeyFocusArea(event.type, event.GetKeySym(), event.GetKeyState(),
566- &focus_area,
567- &base_window);
568+ focus_area, base_window);
569 }
570
571 KeyNavDirection direction = KEY_NAV_NONE;
572@@ -964,20 +909,20 @@
573 }
574 }
575
576- if (focus_area)
577+ if (focus_area.IsValid())
578 {
579- SetKeyFocusArea(focus_area, direction);
580+ SetKeyFocusArea(focus_area.GetPointer(), direction);
581 }
582 else
583 {
584 SetKeyFocusArea(NULL, KEY_NAV_NONE);
585 }
586
587- if (key_focus_area_)
588+ if (key_focus_area_.IsValid())
589 {
590 if (key_focus_area_->InspectKeyEvent(event.type, event.GetKeySym(), event.GetText()))
591 {
592- SendKeyEvent(key_focus_area_,
593+ SendKeyEvent(key_focus_area_.GetPointer(),
594 event.type,
595 event.GetKeySym(),
596 #if defined(NUX_OS_WINDOWS)
597@@ -1014,25 +959,25 @@
598 }
599 }
600 else if (event.type == NUX_KEYDOWN)
601- {
602+ {
603 if (direction == KEY_NAV_ENTER)
604 {
605- if (key_focus_area_ && key_focus_area_->Type().IsDerivedFromType(InputArea::StaticObjectType))
606+ if (key_focus_area_.IsValid() && key_focus_area_->Type().IsDerivedFromType(InputArea::StaticObjectType))
607 {
608 // Signal emitted from the WindowCompositor.
609- key_nav_focus_activate.emit(key_focus_area_);
610+ key_nav_focus_activate.emit(key_focus_area_.GetPointer());
611 // Signal emitted from the area itsel.
612- static_cast<InputArea*>(key_focus_area_)->key_nav_focus_activate.emit(key_focus_area_);
613+ key_focus_area_->key_nav_focus_activate.emit(key_focus_area_.GetPointer());
614 }
615 }
616 else
617 {
618 InputArea* key_nav_focus = NULL;
619 Area* parent = key_focus_area_->GetParentObject();
620-
621+
622 if (parent)
623 key_nav_focus = NUX_STATIC_CAST(InputArea*, parent->KeyNavIteration(direction));
624-
625+
626 while (key_nav_focus == NULL && parent != NULL)
627 {
628 parent = parent->GetParentObject();
629@@ -1589,10 +1534,10 @@
630 // End 2D Drawing
631 }
632
633- if (key_focus_area_)
634+ if (key_focus_area_.IsValid())
635 {
636 // key focus test
637- Geometry geo= key_focus_area_->GetRootGeometry();
638+ Geometry const& geo = key_focus_area_->GetRootGeometry();
639 //GetGraphicsDisplay()->GetGraphicsEngine()->QRP_Color(geo.x, geo.y, geo.width, geo.height, color::Blue);
640 }
641
642@@ -1851,17 +1796,6 @@
643 return true;
644 }
645
646- void WindowCompositor::OnKeyNavFocusDestroyed(Object* area)
647- {
648- if (key_focus_area_ == area)
649- {
650- key_focus_area_->ResetDownwardPathToKeyFocusArea();
651- key_focus_area_->ResetUpwardPathToKeyFocusArea();
652-
653- key_focus_area_ = NULL;
654- }
655- }
656-
657 bool WindowCompositor::SetKeyFocusArea(InputArea* area, KeyNavDirection direction)
658 {
659 InputArea* keyboard_grab_area = GetKeyboardGrabArea();
660@@ -1886,7 +1820,7 @@
661 return false;
662 }
663
664- if (key_focus_area_)
665+ if (key_focus_area_.IsValid())
666 {
667 // This is the area that has the keyboard focus. Emit the signal 'end_key_focus'.
668 key_focus_area_->end_key_focus.emit();
669@@ -1898,9 +1832,9 @@
670 if (key_focus_area_->Type().IsDerivedFromType(InputArea::StaticObjectType))
671 {
672 // Signal emitted from the WindowCompositor.
673- key_nav_focus_change.emit(key_focus_area_, false, direction);
674+ key_nav_focus_change.emit(key_focus_area_.GetPointer(), false, direction);
675 // Signal emitted from the area itself.
676- static_cast<InputArea*>(key_focus_area_)->key_nav_focus_change.emit(key_focus_area_, false, direction);
677+ key_focus_area_->key_nav_focus_change.emit(key_focus_area_.GetPointer(), false, direction);
678 // nuxDebugMsg("[WindowCompositor::SetKeyFocusArea] Area type '%s' named '%s': Lost key nav focus.",
679 // key_focus_area_->Type().name,
680 // key_focus_area_->GetBaseString().GetTCharPtr());
681@@ -1908,7 +1842,7 @@
682
683 if (key_focus_area_->Type().IsDerivedFromType(View::StaticObjectType))
684 {
685- static_cast<View*>(key_focus_area_)->QueueDraw();
686+ static_cast<View*>(key_focus_area_.GetPointer())->QueueDraw();
687 }
688 }
689
690@@ -1926,9 +1860,9 @@
691 if (key_focus_area_->Type().IsDerivedFromType(InputArea::StaticObjectType))
692 {
693 // Signal emitted from the WindowCompositor.
694- key_nav_focus_change.emit(key_focus_area_, true, direction);
695+ key_nav_focus_change.emit(key_focus_area_.GetPointer(), true, direction);
696 // Signal emitted from the area itself.
697- static_cast<InputArea*>(key_focus_area_)->key_nav_focus_change.emit(key_focus_area_, true, direction);
698+ key_focus_area_->key_nav_focus_change.emit(key_focus_area_.GetPointer(), true, direction);
699 // nuxDebugMsg("[WindowCompositor::SetKeyFocusArea] Area type '%s' named '%s': Has key nav focus.",
700 // key_focus_area_->Type().name,
701 // key_focus_area_->GetBaseString().GetTCharPtr());
702@@ -1936,10 +1870,10 @@
703
704 if (key_focus_area_->Type().IsDerivedFromType(View::StaticObjectType))
705 {
706- static_cast<View*>(key_focus_area_)->QueueDraw();
707+ static_cast<View*>(key_focus_area_.GetPointer())->QueueDraw();
708 }
709
710- key_focus_area_->ChildFocusChanged.emit(key_focus_area_);
711+ key_focus_area_->ChildFocusChanged.emit(key_focus_area_.GetPointer());
712
713 }
714 else
715@@ -1947,24 +1881,12 @@
716 key_focus_area_ = NULL;
717 }
718
719- key_focus_area_connection_.disconnect();
720-
721- if (area)
722- {
723- key_focus_area_connection_ = area->object_destroyed.connect(sigc::mem_fun(this, &WindowCompositor::OnKeyNavFocusDestroyed));
724- }
725-
726- if (key_focus_area_ == NULL)
727- {
728- return false;
729- }
730-
731- return true;
732+ return key_focus_area_.IsValid() ? true : false;
733 }
734
735 InputArea* WindowCompositor::GetKeyFocusArea()
736 {
737- return key_focus_area_;
738+ return key_focus_area_.GetPointer();
739 }
740
741 void WindowCompositor::SetBackgroundPaintLayer(AbstractPaintLayer* bkg)
742@@ -2220,7 +2142,7 @@
743 keyboard_grab_stack_.push_front(area);
744
745 // If there is any area with the key focus, cancel it.
746- if (key_focus_area_)
747+ if (key_focus_area_.IsValid())
748 {
749 key_focus_area_->end_key_focus.emit();
750 key_focus_area_->ResetUpwardPathToKeyFocusArea();
751@@ -2228,9 +2150,9 @@
752 if (key_focus_area_->Type().IsDerivedFromType(InputArea::StaticObjectType))
753 {
754 // Signal emitted from the WindowCompositor.
755- key_nav_focus_change.emit(key_focus_area_, false, KEY_NAV_NONE);
756+ key_nav_focus_change.emit(key_focus_area_.GetPointer(), false, KEY_NAV_NONE);
757 // Signal emitted from the area itself.
758- static_cast<InputArea*>(key_focus_area_)->key_nav_focus_change.emit(key_focus_area_, false, KEY_NAV_NONE);
759+ key_focus_area_->key_nav_focus_change.emit(key_focus_area_.GetPointer(), false, KEY_NAV_NONE);
760 // nuxDebugMsg("[WindowCompositor::GrabKeyboardAdd] Area type '%s' named '%s': Lost key nav focus.",
761 // key_focus_area_->Type().name,
762 // key_focus_area_->GetBaseString().GetTCharPtr());
763@@ -2239,7 +2161,7 @@
764
765 if (key_focus_area_->Type().IsDerivedFromType(View::StaticObjectType))
766 {
767- static_cast<View*>(key_focus_area_)->QueueDraw();
768+ static_cast<View*>(key_focus_area_.GetPointer())->QueueDraw();
769 }
770 key_focus_area_ = NULL;
771 }
772@@ -2295,7 +2217,7 @@
773 else
774 {
775 // If there is any area with the key focus, cancel it.
776- if (key_focus_area_)
777+ if (key_focus_area_.IsValid())
778 {
779 key_focus_area_->end_key_focus.emit();
780 key_focus_area_->ResetUpwardPathToKeyFocusArea();
781@@ -2303,9 +2225,9 @@
782 if (key_focus_area_->Type().IsDerivedFromType(InputArea::StaticObjectType))
783 {
784 // Signal emitted from the WindowCompositor.
785- key_nav_focus_change.emit(key_focus_area_, false, KEY_NAV_NONE);
786+ key_nav_focus_change.emit(key_focus_area_.GetPointer(), false, KEY_NAV_NONE);
787 // Signal emitted from the area itself.
788- static_cast<InputArea*>(key_focus_area_)->key_nav_focus_change.emit(key_focus_area_, false, KEY_NAV_NONE);
789+ key_focus_area_->key_nav_focus_change.emit(key_focus_area_.GetPointer(), false, KEY_NAV_NONE);
790 // nuxDebugMsg("[WindowCompositor::GrabKeyboardRemove] Area type '%s' named '%s': Lost key nav focus.",
791 // key_focus_area_->Type().name,
792 // key_focus_area_->GetBaseString().GetTCharPtr());
793@@ -2313,7 +2235,7 @@
794
795 if (key_focus_area_->Type().IsDerivedFromType(View::StaticObjectType))
796 {
797- static_cast<View*>(key_focus_area_)->QueueDraw();
798+ static_cast<View*>(key_focus_area_.GetPointer())->QueueDraw();
799 }
800 key_focus_area_ = NULL;
801 }
802
803=== modified file 'Nux/WindowCompositor.h'
804--- Nux/WindowCompositor.h 2012-06-26 13:38:50 +0000
805+++ Nux/WindowCompositor.h 2012-09-18 18:30:40 +0000
806@@ -127,50 +127,38 @@
807 //! Traverse the widget tree and found the area that is right below the mouse pointer.
808 void GetAreaUnderMouse(const Point& mouse_position,
809 NuxEventType event_type,
810- InputArea** area_under_mouse_pointer,
811- BaseWindow** window);
812+ ObjectWeakPtr<InputArea>& area_under_mouse_pointer,
813+ ObjectWeakPtr<BaseWindow>& window);
814
815 //! Traverse the widget tree and found the area has the key focus.
816 void FindKeyFocusArea(NuxEventType event_type,
817 unsigned int key_symbol,
818 unsigned int special_keys_state,
819- InputArea** key_focus_area,
820- BaseWindow** window);
821-
822+ ObjectWeakPtr<InputArea>& key_focus_area,
823+ ObjectWeakPtr<BaseWindow>& window);
824+
825 //! Traverse the widget tree and found the area has the key focus, but start from a specified widget.
826 void FindKeyFocusAreaFrom(NuxEventType event_type,
827 unsigned int key_symbol,
828 unsigned int special_keys_state,
829 InputArea* root_search_area,
830- InputArea** key_focus_area,
831- BaseWindow** window);
832+ ObjectWeakPtr<InputArea>& key_focus_area,
833+ ObjectWeakPtr<BaseWindow>& window);
834
835 void ResetMousePointerAreas();
836
837 //! Get the area upon which the mouse button is currently down.
838- Area* GetMouseOwnerArea();
839+ ObjectWeakPtr<InputArea> const& GetMouseOwnerArea() const;
840
841 //! Set the area upon which the mouse button is currently down.
842- void SetMouseOwnerArea(Area* area);
843+ void SetMouseOwnerArea(InputArea* area);
844
845 //! Set the area that is right below the mouse pointer.
846- void SetMouseOverArea(Area* area);
847-
848+ void SetMouseOverArea(InputArea* area);
849+
850 //! Set The BaseWindow of the area that is the mouse owner.
851 void SetMouseOwnerBaseWindow(BaseWindow* base_window);
852
853- //! Callback: called when mouse_over_area_ is destroyed.
854- void OnMouseOverViewDestroyed(Object* area);
855-
856- //! Callback: called when mouse_owner_area_ is destroyed.
857- void OnMouseOwnerViewDestroyed(Object* area);
858-
859- //! Callback: called when key_focus_area_ is destroyed.
860- void OnKeyNavFocusDestroyed(Object* area);
861-
862- //! Callback: called when mouse_owner_basewindow_connection_ is destroyed.
863- void OnMouseOwnerBaseWindowDestroyed(Object* area);
864-
865 void SendKeyEvent(InputArea* input_area, NuxEventType event_type,
866 unsigned int key_sym,
867 unsigned long x11_key_code,
868@@ -184,19 +172,14 @@
869 The InputArea that has the mouse focus also has the keyboard focus. That is if _mouse_focus_area is not Null
870 then _mouse_focus_area is equal to _mouse_focus_area;
871 */
872- InputArea* key_focus_area_;
873- InputArea* mouse_owner_area_;
874- InputArea* mouse_over_area_;
875- BaseWindow* mouse_owner_base_window_;
876+ ObjectWeakPtr<InputArea> key_focus_area_;
877+ ObjectWeakPtr<InputArea> mouse_owner_area_;
878+ ObjectWeakPtr<InputArea> mouse_over_area_;
879+ ObjectWeakPtr<BaseWindow> mouse_owner_base_window_;
880
881 int dnd_safety_x_;
882 int dnd_safety_y_;
883
884- sigc::connection mouse_over_view_connection_;
885- sigc::connection mouse_owner_view_connection_;
886- sigc::connection mouse_owner_basewindow_connection_;
887- sigc::connection key_focus_area_connection_;
888-
889 /*!
890 This signal is similar to Area::key_nav_focus_change. It is emitted from the WindowCompositor.
891 The user only needs to listen to this signal to find out the area that has received the keyboard focus.\n
892@@ -682,6 +665,7 @@
893 friend class VSplitter;
894 friend class TableCtrl;
895 friend class View;
896+ friend class TestWindowCompositor;
897 };
898
899 #ifdef NUX_GESTURES_SUPPORT
900
901=== modified file 'configure.ac'
902--- configure.ac 2012-08-30 10:57:51 +0000
903+++ configure.ac 2012-09-18 18:30:40 +0000
904@@ -22,7 +22,7 @@
905 # The number format is : year/month/day
906 # e.g.: december 5th, 2011 is: 20111205
907 # To make more than one API change in a day, add a number to the date. Like 20111205.xx
908-m4_define([nux_abi_version], [20120813.01])
909+m4_define([nux_abi_version], [20120914.02])
910
911 m4_define([nux_version],
912 [nux_major_version.nux_minor_version.nux_micro_version])
913
914=== modified file 'tests/gtest-nux-area.cpp'
915--- tests/gtest-nux-area.cpp 2012-03-02 02:48:48 +0000
916+++ tests/gtest-nux-area.cpp 2012-09-18 18:30:40 +0000
917@@ -1,11 +1,26 @@
918-#include <string>
919-#include <fstream>
920+/*
921+ * Copyright 2010 Inalogic® Inc.
922+ *
923+ * This program is free software: you can redistribute it and/or modify it
924+ * under the terms of the GNU Lesser General Public License version 3, as
925+ * published by the Free Software Foundation.
926+ *
927+ * This program is distributed in the hope that it will be useful, but
928+ * WITHOUT ANY WARRANTY; without even the implied warranties of
929+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
930+ * PURPOSE. See the applicable version of the GNU Lesser General Public
931+ * License for more details.
932+ *
933+ * You should have received a copy of both the GNU Lesser General Public
934+ * License version 3 along with this program. If not, see
935+ * <http://www.gnu.org/licenses/>
936+ *
937+ * Authored by: Jay Taoko <jaytaoko@inalogic.com>
938+ * Marco Trevisan <marco.trevisan@canonical.com>
939+ */
940
941-#include <iostream>
942 #include <gmock/gmock.h>
943-#include <boost/filesystem.hpp>
944-#include <glib.h>
945-
946+#include <boost/shared_ptr.hpp>
947 #include "Nux/Nux.h"
948 #include "Nux/HLayout.h"
949 #include "Nux/StaticText.h"
950@@ -16,14 +31,39 @@
951
952 namespace {
953
954-TEST(TestArea, TestAreaSize)
955-{
956- nux::NuxInitialize(0);
957- nux::WindowThread *wnd_thread = nux::CreateNuxWindow("Area Test", 300, 200,
958- nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL);
959-
960- nux::TestView* test_view = new nux::TestView("");
961-
962+struct MockTestView : nux::TestView
963+{
964+ MockTestView()
965+ : nux::TestView("MockTestView")
966+ {}
967+
968+ void SetNextObjectToKeyFocusArea(nux::Area* area)
969+ {
970+ TestView::SetNextObjectToKeyFocusArea(area);
971+ }
972+
973+ nux::Area* GetNextObjectToKeyFocusArea()
974+ {
975+ return TestView::GetNextObjectToKeyFocusArea();
976+ }
977+};
978+
979+struct TestArea : public testing::Test
980+{
981+ void SetUp()
982+ {
983+ nux::NuxInitialize(0);
984+ wnd_thread.reset(nux::CreateNuxWindow("Area Test", 300, 200, nux::WINDOWSTYLE_NORMAL,
985+ NULL, false, NULL, NULL));
986+ test_view = new MockTestView();
987+ }
988+
989+ boost::shared_ptr<nux::WindowThread> wnd_thread;
990+ nux::ObjectPtr<MockTestView> test_view;
991+};
992+
993+TEST_F(TestArea, TestAreaSize)
994+{
995 EXPECT_EQ(test_view->GetMinimumWidth(), nux::AREA_MIN_WIDTH);
996 EXPECT_EQ(test_view->GetMaximumWidth(), nux::AREA_MAX_WIDTH);
997 EXPECT_EQ(test_view->GetMinimumHeight(), nux::AREA_MIN_HEIGHT);
998@@ -48,29 +88,16 @@
999 EXPECT_EQ(test_view->GetMaximumWidth(), 4321);
1000 EXPECT_EQ(test_view->GetMinimumHeight(), 432);
1001 EXPECT_EQ(test_view->GetMaximumHeight(), 1234);
1002-
1003- test_view->UnReference();
1004- delete wnd_thread;
1005 }
1006
1007-TEST(TestArea, TestAreaGeometry)
1008+TEST_F(TestArea, TestAreaGeometry)
1009 {
1010- nux::NuxInitialize(0);
1011- nux::WindowThread *wnd_thread = nux::CreateNuxWindow("Area Test", 300, 200,
1012- nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL);
1013-
1014- nux::TestView* test_view = new nux::TestView("");
1015-
1016- static_cast<nux::Area*>(test_view)->SetGeometry(0, 0, 100, 100);
1017+ static_cast<nux::Area*>(test_view.GetPointer())->SetGeometry(0, 0, 100, 100);
1018
1019 EXPECT_EQ(test_view->GetBaseX(), 0);
1020 EXPECT_EQ(test_view->GetBaseX(), 0);
1021 EXPECT_EQ(test_view->GetBaseWidth(), 100);
1022 EXPECT_EQ(test_view->GetBaseHeight(), 100);
1023-
1024-
1025- test_view->UnReference();
1026- delete wnd_thread;
1027 }
1028
1029 static bool object_destroyed = false;
1030@@ -79,31 +106,53 @@
1031 object_destroyed = true;
1032 }
1033
1034-TEST(TestArea, TestUnParentKeyFocus)
1035+TEST_F(TestArea, TestUnParentKeyFocus)
1036 {
1037- nux::NuxInitialize(0);
1038- nux::WindowThread *wnd_thread = nux::CreateNuxWindow("Area Test", 300, 200,
1039- nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL);
1040-
1041+ nux::TestView* test_view1 = new nux::TestView("");
1042 nux::HLayout* layout = new nux::HLayout();
1043- nux::TestView* test_view = new nux::TestView("");
1044- test_view->object_destroyed.connect(sigc::ptr_fun(&OnObjectDestroyed));
1045+ test_view1->object_destroyed.connect(sigc::ptr_fun(&OnObjectDestroyed));
1046
1047- test_view->Reference();
1048-
1049- layout->AddView(test_view, 1);
1050+ test_view1->Reference();
1051+ layout->AddView(test_view1, 1);
1052
1053 wnd_thread->SetLayout(layout);
1054
1055- EXPECT_EQ(test_view->HasKeyFocus(), false);
1056- nux::GetWindowThread()->GetWindowCompositor().SetKeyFocusArea(test_view);
1057- EXPECT_EQ(test_view->HasKeyFocus(), true);
1058- layout->RemoveChildObject(test_view);
1059- EXPECT_EQ(test_view->HasKeyFocus(), false);
1060- test_view->UnReference();
1061+ EXPECT_EQ(test_view1->HasKeyFocus(), false);
1062+ nux::GetWindowThread()->GetWindowCompositor().SetKeyFocusArea(test_view1);
1063+ EXPECT_EQ(test_view1->HasKeyFocus(), true);
1064+ layout->RemoveChildObject(test_view1);
1065+ EXPECT_EQ(test_view1->HasKeyFocus(), false);
1066+ test_view1->UnReference();
1067 EXPECT_EQ(object_destroyed, true);
1068-
1069- delete wnd_thread;
1070+}
1071+
1072+TEST_F(TestArea, NextObjectToKeyFocusSetReset)
1073+{
1074+ MockTestView* parent = new MockTestView();
1075+ MockTestView* brother = new MockTestView();
1076+ MockTestView* child1 = new MockTestView();
1077+ MockTestView* child2 = new MockTestView();
1078+ MockTestView* child3 = new MockTestView();
1079+
1080+ parent->SetNextObjectToKeyFocusArea(brother);
1081+ ASSERT_EQ(parent->GetNextObjectToKeyFocusArea(), brother);
1082+
1083+ child1->SetParentObject(parent);
1084+ child1->SetNextObjectToKeyFocusArea(child2);
1085+ ASSERT_EQ(child1->GetNextObjectToKeyFocusArea(), child2);
1086+
1087+ child2->SetParentObject(parent);
1088+ child2->SetNextObjectToKeyFocusArea(child3);
1089+ ASSERT_EQ(child2->GetNextObjectToKeyFocusArea(), child3);
1090+
1091+ child3->SetParentObject(parent);
1092+ ASSERT_EQ(child3->GetNextObjectToKeyFocusArea(), nullptr);
1093+
1094+ child1->UnReference();
1095+ EXPECT_EQ(child2->GetNextObjectToKeyFocusArea(), nullptr);
1096+ EXPECT_EQ(parent->GetNextObjectToKeyFocusArea(), nullptr);
1097+
1098+ parent->UnReference();
1099 }
1100
1101 }
1102
1103=== modified file 'tests/gtest-nux-input-area.cpp'
1104--- tests/gtest-nux-input-area.cpp 2012-09-18 18:30:40 +0000
1105+++ tests/gtest-nux-input-area.cpp 2012-09-18 18:30:40 +0000
1106@@ -1,5 +1,5 @@
1107 /*
1108- * Copyright 2012 Canonical Ltd.
1109+ * Copyright 2010 Inalogic® Inc.
1110 *
1111 * This program is free software: you can redistribute it and/or modify it
1112 * under the terms of the GNU Lesser General Public License version 3, as
1113
1114=== modified file 'tests/gtest-nux-windowcompositor.cpp'
1115--- tests/gtest-nux-windowcompositor.cpp 2012-06-26 13:38:50 +0000
1116+++ tests/gtest-nux-windowcompositor.cpp 2012-09-18 18:30:40 +0000
1117@@ -47,17 +47,109 @@
1118 };
1119 #endif
1120
1121-TEST(TestWindowCompositor, TestSetKeyFocusArea)
1122-{
1123- nux::NuxInitialize(0);
1124- nux::WindowThread *wnd_thread = nux::CreateNuxWindow("Nux Window", 300, 200,
1125- nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL);
1126-
1127+struct TestBaseWindow : public nux::BaseWindow
1128+{
1129+ TestBaseWindow() : input_area(new nux::InputArea())
1130+ {
1131+ ShowWindow(true);
1132+ }
1133+
1134+ nux::Area* FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type)
1135+ {
1136+ return input_area.GetPointer();
1137+ }
1138+
1139+ Area* FindKeyFocusArea(unsigned int key_symbol, unsigned long x11_key_code, unsigned long special_keys_state)
1140+ {
1141+ return input_area.GetPointer();
1142+ }
1143+
1144+ nux::ObjectPtr<nux::InputArea> input_area;
1145+};
1146+
1147+struct TestHLayout : public nux::HLayout
1148+{
1149+ TestHLayout() : input_area(new nux::InputArea()) {}
1150+
1151+ nux::Area* FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type)
1152+ {
1153+ return input_area.GetPointer();
1154+ }
1155+
1156+ Area* FindKeyFocusArea(unsigned int key_symbol, unsigned long x11_key_code, unsigned long special_keys_state)
1157+ {
1158+ return input_area.GetPointer();
1159+ }
1160+
1161+ nux::ObjectPtr<nux::InputArea> input_area;
1162+};
1163+
1164+}
1165+
1166+namespace nux
1167+{
1168+struct TestWindowCompositor : public testing::Test
1169+{
1170+ TestWindowCompositor()
1171+ {}
1172+
1173+ void SetUp()
1174+ {
1175+ nux::NuxInitialize(0);
1176+ wnd_thread.reset(nux::CreateNuxWindow("WindowCompositor Test", 300, 200, nux::WINDOWSTYLE_NORMAL,
1177+ NULL, false, NULL, NULL));
1178+ }
1179+
1180+ void ForceSetKeyFocusArea(nux::InputArea* area)
1181+ {
1182+ nux::GetWindowCompositor().key_focus_area_ = area;
1183+ }
1184+
1185+ ObjectWeakPtr<InputArea> const& GetMouseOwnerArea() const
1186+ {
1187+ return nux::GetWindowCompositor().GetMouseOwnerArea();
1188+ }
1189+
1190+ void SetMouseOwnerArea(InputArea* area)
1191+ {
1192+ nux::GetWindowCompositor().mouse_owner_area_ = area;
1193+ }
1194+
1195+ InputArea* GetMouseOverArea()
1196+ {
1197+ return nux::GetWindowCompositor().mouse_over_area_.GetPointer();
1198+ }
1199+
1200+ void SetMouseOverArea(InputArea* area)
1201+ {
1202+ nux::GetWindowCompositor().mouse_over_area_ = area;
1203+ }
1204+
1205+ void GetAreaUnderMouse(const Point& mouse_position, NuxEventType event_type,
1206+ ObjectWeakPtr<InputArea>& area,
1207+ ObjectWeakPtr<BaseWindow>& window)
1208+ {
1209+ return nux::GetWindowCompositor().GetAreaUnderMouse(mouse_position, event_type, area, window);
1210+ }
1211+
1212+ void FindKeyFocusArea(NuxEventType event_type, unsigned int key_symbol,
1213+ unsigned int state,
1214+ ObjectWeakPtr<InputArea>& key_focus_area,
1215+ ObjectWeakPtr<BaseWindow>& window)
1216+ {
1217+ return nux::GetWindowCompositor().FindKeyFocusArea(event_type, key_symbol, state, key_focus_area, window);
1218+ }
1219+
1220+ boost::shared_ptr<nux::WindowThread> wnd_thread;
1221+};
1222+
1223+TEST_F(TestWindowCompositor, TestSetKeyFocusArea)
1224+{
1225 nux::TestView* test_view0 = new nux::TestView();
1226 nux::TestView* test_view1 = new nux::TestView();
1227
1228 nux::HLayout* layout = new nux::HLayout();
1229-
1230+
1231 layout->AddView(test_view0, 1);
1232 layout->AddView(test_view1, 1);
1233
1234@@ -89,8 +181,6 @@
1235 EXPECT_EQ(test_view1->registered_begin_keynav_focus_, true);
1236 EXPECT_EQ(test_view1->registered_end_keynav_focus_, false);
1237 }
1238-
1239- delete wnd_thread;
1240 }
1241
1242 #ifdef NUX_GESTURES_SUPPORT
1243@@ -104,11 +194,8 @@
1244 Check that the gesture got accepted, that window A got the gesture
1245 events and that window B didn't get anything.
1246 */
1247-TEST(TestWindowCompositor, GestureEventsDelivery_1)
1248+TEST_F(TestWindowCompositor, GestureEventsDelivery_1)
1249 {
1250- nux::NuxInitialize(0);
1251- nux::WindowThread *wnd_thread = nux::CreateNuxWindow("Nux Window", 500, 500,
1252- nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL);
1253 nux::WindowCompositor &wnd_compositor = wnd_thread->GetWindowCompositor();
1254 nux::FakeGestureEvent fake_event;
1255
1256@@ -159,7 +246,6 @@
1257
1258 target_window->Dispose();
1259 innocent_window->Dispose();
1260- delete wnd_thread;
1261 }
1262
1263 /*
1264@@ -171,13 +257,10 @@
1265 Check that the gesture got rejected and that no window got
1266 any gesture event.
1267 */
1268-TEST(TestWindowCompositor, GestureEventsDelivery_2)
1269+TEST_F(TestWindowCompositor, GestureEventsDelivery_2)
1270 {
1271- nux::NuxInitialize(0);
1272- nux::WindowThread *wnd_thread = nux::CreateNuxWindow("Nux Window", 500, 500,
1273- nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL);
1274- nux::WindowCompositor &wnd_compositor = wnd_thread->GetWindowCompositor();
1275 nux::FakeGestureEvent fake_event;
1276+ nux::WindowCompositor& wnd_compositor = nux::GetWindowCompositor();
1277
1278 TestWindow *subscribed_window = new TestWindow;
1279 subscribed_window->SetBaseXY(10, 10);
1280@@ -212,7 +295,6 @@
1281
1282 subscribed_window->Dispose();
1283 innocent_window->Dispose();
1284- delete wnd_thread;
1285 }
1286
1287 /*
1288@@ -225,13 +307,10 @@
1289 Check that the gesture gets accepted and that only the input area behind that
1290 window gets the gesture events.
1291 */
1292-TEST(TestWindowCompositor, GestureEventsDelivery_3)
1293+TEST_F(TestWindowCompositor, GestureEventsDelivery_3)
1294 {
1295- nux::NuxInitialize(0);
1296- nux::WindowThread *wnd_thread = nux::CreateNuxWindow("Nux Window", 500, 500,
1297- nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL);
1298- nux::WindowCompositor &wnd_compositor = wnd_thread->GetWindowCompositor();
1299 nux::FakeGestureEvent fake_event;
1300+ nux::WindowCompositor& wnd_compositor = nux::GetWindowCompositor();
1301
1302 TestWindow *window = new TestWindow;
1303 window->SetBaseXY(10, 10);
1304@@ -287,20 +366,16 @@
1305 ASSERT_EQ(0, other_input_area->gesture_events_received.size());
1306
1307 window->Dispose();
1308- delete wnd_thread;
1309 }
1310
1311 /*
1312 Check that if a gesture gets its construction finished only on its end event,
1313 it still gets accepted and delivered.
1314 */
1315-TEST(TestWindowCompositor, GestureEventsDelivery_4)
1316+TEST_F(TestWindowCompositor, GestureEventsDelivery_4)
1317 {
1318- nux::NuxInitialize(0);
1319- nux::WindowThread *wnd_thread = nux::CreateNuxWindow("Nux Window", 500, 500,
1320- nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL);
1321- nux::WindowCompositor &wnd_compositor = wnd_thread->GetWindowCompositor();
1322 nux::FakeGestureEvent fake_event;
1323+ nux::WindowCompositor& wnd_compositor = nux::GetWindowCompositor();
1324
1325 TestWindow *window = new TestWindow;
1326 window->SetBaseXY(10, 10);
1327@@ -356,7 +431,110 @@
1328 ASSERT_EQ(0, other_input_area->gesture_events_received.size());
1329
1330 window->Dispose();
1331- delete wnd_thread;
1332+}
1333+
1334+TEST_F(TestWindowCompositor, KeyFocusAreaAutomaticallyUnsets)
1335+{
1336+ nux::WindowCompositor& wnd_compositor = nux::GetWindowCompositor();
1337+ nux::InputArea* test_area = new TestInputArea();
1338+
1339+ ForceSetKeyFocusArea(test_area);
1340+ ASSERT_EQ(wnd_compositor.GetKeyFocusArea(), test_area);
1341+
1342+ test_area->UnReference();
1343+ EXPECT_EQ(wnd_compositor.GetKeyFocusArea(), nullptr);
1344+}
1345+
1346+TEST_F(TestWindowCompositor, MouseOverAreaAutomaticallyUnsets)
1347+{
1348+ nux::InputArea* test_area = new TestInputArea();
1349+
1350+ SetMouseOverArea(test_area);
1351+ ASSERT_EQ(GetMouseOverArea(), test_area);
1352+
1353+ test_area->UnReference();
1354+ EXPECT_EQ(GetMouseOverArea(), nullptr);
1355+}
1356+
1357+TEST_F(TestWindowCompositor, MouseOwnerAreaAutomaticallyUnsets)
1358+{
1359+ nux::InputArea* test_area = new TestInputArea();
1360+
1361+ SetMouseOwnerArea(test_area);
1362+ ASSERT_EQ(GetMouseOwnerArea(), test_area);
1363+
1364+ test_area->UnReference();
1365+ EXPECT_EQ(GetMouseOwnerArea(), nullptr);
1366+}
1367+
1368+TEST_F(TestWindowCompositor, GetAreaUnderMouse)
1369+{
1370+ ObjectWeakPtr<InputArea> area;
1371+ ObjectWeakPtr<BaseWindow> window;
1372+
1373+ TestBaseWindow* test_win = new TestBaseWindow();
1374+
1375+ GetAreaUnderMouse(Point(1, 2), NUX_MOUSE_MOVE, area, window);
1376+
1377+ EXPECT_EQ(area.GetPointer(), test_win->input_area.GetPointer());
1378+ EXPECT_EQ(window.GetPointer(), test_win);
1379+
1380+ test_win->UnReference();
1381+ EXPECT_EQ(area.GetPointer(), nullptr);
1382+ EXPECT_EQ(window.GetPointer(), nullptr);
1383+}
1384+
1385+TEST_F(TestWindowCompositor, GetAreaUnderMouseFallback)
1386+{
1387+ ObjectWeakPtr<InputArea> area;
1388+ ObjectWeakPtr<BaseWindow> window;
1389+
1390+ TestHLayout* layout = new TestHLayout();
1391+ wnd_thread->SetLayout(layout);
1392+
1393+ GetAreaUnderMouse(Point(1, 2), NUX_MOUSE_MOVE, area, window);
1394+
1395+ EXPECT_EQ(area.GetPointer(), layout->input_area.GetPointer());
1396+ EXPECT_EQ(window.GetPointer(), nullptr);
1397+
1398+ wnd_thread->SetLayout(nullptr);
1399+ layout->UnReference();
1400+ EXPECT_EQ(area.GetPointer(), nullptr);
1401+}
1402+
1403+TEST_F(TestWindowCompositor, GetFocusedArea)
1404+{
1405+ ObjectWeakPtr<InputArea> area;
1406+ ObjectWeakPtr<BaseWindow> window;
1407+
1408+ TestBaseWindow* test_win = new TestBaseWindow();
1409+
1410+ FindKeyFocusArea(NUX_KEYUP, 0, 0, area, window);
1411+
1412+ EXPECT_EQ(area.GetPointer(), test_win->input_area.GetPointer());
1413+ EXPECT_EQ(window.GetPointer(), test_win);
1414+
1415+ test_win->UnReference();
1416+ EXPECT_EQ(area.GetPointer(), nullptr);
1417+ EXPECT_EQ(window.GetPointer(), nullptr);
1418+}
1419+
1420+TEST_F(TestWindowCompositor, GetFocusedAreaFallback)
1421+{
1422+ ObjectWeakPtr<InputArea> area;
1423+ ObjectWeakPtr<BaseWindow> window;
1424+
1425+ TestHLayout* layout = new TestHLayout();
1426+ wnd_thread->SetLayout(layout);
1427+
1428+ FindKeyFocusArea(NUX_KEYUP, 0, 0, area, window);
1429+
1430+ EXPECT_EQ(area.GetPointer(), layout->input_area.GetPointer());
1431+ EXPECT_EQ(window.GetPointer(), nullptr);
1432+
1433+ wnd_thread->SetLayout(nullptr);
1434+ layout->UnReference();
1435+ EXPECT_EQ(area.GetPointer(), nullptr);
1436 }
1437
1438 #endif // NUX_GESTURES_SUPPORT

Subscribers

People subscribed via source and target branches