Merge lp:~canonical-dx-team/unity/unity.fix-676040 into lp:unity
- unity.fix-676040
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Gord Allott | ||||
Approved revision: | no longer in the source branch. | ||||
Merged at revision: | 680 | ||||
Proposed branch: | lp:~canonical-dx-team/unity/unity.fix-676040 | ||||
Merge into: | lp:unity | ||||
Diff against target: |
734 lines (+552/-63) (has conflicts) 6 files modified
src/QuicklistView.cpp (+89/-62) src/QuicklistView.h (+11/-1) tests/CMakeLists.txt (+18/-0) tests/ui/EventFaker.cpp (+89/-0) tests/ui/EventFaker.h (+40/-0) tests/ui/TestQuicklist.cpp (+305/-0) Text conflict in src/QuicklistView.h |
||||
To merge this branch: | bzr merge lp:~canonical-dx-team/unity/unity.fix-676040 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Gord Allott (community) | Approve | ||
Review via email: mp+42623@code.launchpad.net |
Commit message
Description of the change
This is the second part of "Quicklist menu item testing". See LP: #676040.
This creates a stand-alone test-application for interaction-tests with Quicklist-items (checkmark, radio, label). It does so by using a separate thread injecting "fake" events (not generated by a user, mouse-clicks in this case) into the event-loop of the main app-context.
The test-application stores three boolean-flags set to false, which get switched to true, if the "item-activated" signal-handlers for the dbusmenu-items underlying the Quicklist-items get correctly called. These are tested at program-exit.
It's currently missing a nicer API for EventFaker, wrapping (and hiding) all the setup needed for the separate event-injecting thread, but I wanted to avoid this being held of longer. The nicer API is in the works and probably lands in this branch before someone actually reviews it :) The program-exit right now has to be triggered by the user. That will be automated as well, since this is meant to be an unattended test.
Note: for this branch to work lp:~canonical-dx-team/nux/nux.event-automation is needed (and should be merged to nux trunk before).
Preview Diff
1 | === modified file 'src/QuicklistView.cpp' |
2 | --- src/QuicklistView.cpp 2010-12-02 16:50:33 +0000 |
3 | +++ src/QuicklistView.cpp 2010-12-03 13:43:15 +0000 |
4 | @@ -92,6 +92,7 @@ |
5 | OnMouseDrag.connect (sigc::mem_fun (this, &QuicklistView::RecvMouseDrag)); |
6 | |
7 | _mouse_down = false; |
8 | + _enable_quicklist_for_testing = false; |
9 | } |
10 | |
11 | QuicklistView::~QuicklistView () |
12 | @@ -127,6 +128,12 @@ |
13 | _item_list.clear (); |
14 | } |
15 | |
16 | +void |
17 | +QuicklistView::EnableQuicklistForTesting (bool enable_testing) |
18 | +{ |
19 | + _enable_quicklist_for_testing = enable_testing; |
20 | +} |
21 | + |
22 | void QuicklistView::ShowQuicklistWithTipAt (int anchor_tip_x, int anchor_tip_y) |
23 | { |
24 | int window_width; |
25 | @@ -193,6 +200,26 @@ |
26 | _mouse_down = false; |
27 | if (IsVisible ()) |
28 | { |
29 | + if (!_enable_quicklist_for_testing) |
30 | + { |
31 | + CancelItemsPrelightStatus (); |
32 | + CaptureMouseDownAnyWhereElse (false); |
33 | + ForceStopFocus (1, 1); |
34 | + UnGrabPointer (); |
35 | + EnableInputWindow (false); |
36 | + ShowWindow (false); |
37 | + } |
38 | + } |
39 | + return nux::eMouseEventSolved; |
40 | + } |
41 | + } |
42 | + else if ((ievent.e_event == nux::NUX_MOUSE_RELEASED) && _mouse_down) |
43 | + { |
44 | + _mouse_down = false; |
45 | + if (IsVisible ()) |
46 | + { |
47 | + if (!_enable_quicklist_for_testing) |
48 | + { |
49 | CancelItemsPrelightStatus (); |
50 | CaptureMouseDownAnyWhereElse (false); |
51 | ForceStopFocus (1, 1); |
52 | @@ -200,25 +227,10 @@ |
53 | EnableInputWindow (false); |
54 | ShowWindow (false); |
55 | } |
56 | - return nux::eMouseEventSolved; |
57 | - } |
58 | - } |
59 | - else if ((ievent.e_event == nux::NUX_MOUSE_RELEASED) && _mouse_down) |
60 | - { |
61 | - _mouse_down = false; |
62 | - if (IsVisible ()) |
63 | - { |
64 | - CancelItemsPrelightStatus (); |
65 | - CaptureMouseDownAnyWhereElse (false); |
66 | - ForceStopFocus (1, 1); |
67 | - UnGrabPointer (); |
68 | - EnableInputWindow (false); |
69 | - ShowWindow (false); |
70 | } |
71 | return nux::eMouseEventSolved; |
72 | } |
73 | - |
74 | - |
75 | + |
76 | return ret; |
77 | } |
78 | |
79 | @@ -406,12 +418,15 @@ |
80 | // Check if the mouse was released over an item and emit the signal |
81 | CheckAndEmitItemSignal (x + item->GetBaseX (), y + item->GetBaseY ()); |
82 | |
83 | - CancelItemsPrelightStatus (); |
84 | - CaptureMouseDownAnyWhereElse (false); |
85 | - ForceStopFocus (1, 1); |
86 | - UnGrabPointer (); |
87 | - EnableInputWindow (false); |
88 | - ShowWindow (false); |
89 | + if (!_enable_quicklist_for_testing) |
90 | + { |
91 | + CancelItemsPrelightStatus (); |
92 | + CaptureMouseDownAnyWhereElse (false); |
93 | + ForceStopFocus (1, 1); |
94 | + UnGrabPointer (); |
95 | + EnableInputWindow (false); |
96 | + ShowWindow (false); |
97 | + } |
98 | } |
99 | } |
100 | |
101 | @@ -459,14 +474,17 @@ |
102 | { |
103 | // Check if the mouse was released over an item and emit the signal |
104 | CheckAndEmitItemSignal (x + item->GetBaseX (), y + item->GetBaseY ()); |
105 | - |
106 | - CancelItemsPrelightStatus (); |
107 | - CaptureMouseDownAnyWhereElse (false); |
108 | - ForceStopFocus (1, 1); |
109 | - UnGrabPointer (); |
110 | - EnableInputWindow (false); |
111 | - ShowWindow (false); |
112 | - } |
113 | + |
114 | + if (!_enable_quicklist_for_testing) |
115 | + { |
116 | + CancelItemsPrelightStatus (); |
117 | + CaptureMouseDownAnyWhereElse (false); |
118 | + ForceStopFocus (1, 1); |
119 | + UnGrabPointer (); |
120 | + EnableInputWindow (false); |
121 | + ShowWindow (false); |
122 | + } |
123 | + } |
124 | } |
125 | |
126 | void QuicklistView::CancelItemsPrelightStatus () |
127 | @@ -552,12 +570,15 @@ |
128 | { |
129 | if (IsVisible ()) |
130 | { |
131 | - CancelItemsPrelightStatus (); |
132 | - CaptureMouseDownAnyWhereElse (false); |
133 | - ForceStopFocus (1, 1); |
134 | - UnGrabPointer (); |
135 | - EnableInputWindow (false); |
136 | - ShowWindow (false); |
137 | + if (!_enable_quicklist_for_testing) |
138 | + { |
139 | + CancelItemsPrelightStatus (); |
140 | + CaptureMouseDownAnyWhereElse (false); |
141 | + ForceStopFocus (1, 1); |
142 | + UnGrabPointer (); |
143 | + EnableInputWindow (false); |
144 | + ShowWindow (false); |
145 | + } |
146 | } |
147 | } |
148 | |
149 | @@ -575,12 +596,15 @@ |
150 | { |
151 | if (IsVisible ()) |
152 | { |
153 | - CancelItemsPrelightStatus (); |
154 | - CaptureMouseDownAnyWhereElse (false); |
155 | - ForceStopFocus (1, 1); |
156 | - UnGrabPointer (); |
157 | - EnableInputWindow (false); |
158 | - ShowWindow (false); |
159 | + if (!_enable_quicklist_for_testing) |
160 | + { |
161 | + CancelItemsPrelightStatus (); |
162 | + CaptureMouseDownAnyWhereElse (false); |
163 | + ForceStopFocus (1, 1); |
164 | + UnGrabPointer (); |
165 | + EnableInputWindow (false); |
166 | + ShowWindow (false); |
167 | + } |
168 | } |
169 | } |
170 | |
171 | @@ -1279,26 +1303,29 @@ |
172 | return; |
173 | |
174 | int size_above_anchor = -1; // equal to sise below |
175 | - |
176 | - if ((_item_list.size () != 0) || (_default_item_list.size () != 0)) |
177 | - { |
178 | - _top_size = 4; |
179 | - size_above_anchor = _top_size; |
180 | - int x = _anchorX - _padding; |
181 | - int y = _anchorY - _anchor_height/2 - _top_size - _corner_radius - _padding; |
182 | - |
183 | - SetBaseX (x); |
184 | - SetBaseY (y); |
185 | - } |
186 | - else |
187 | - { |
188 | - _top_size = 0; |
189 | - size_above_anchor = -1; |
190 | - int x = _anchorX - _padding; |
191 | - int y = _anchorY - _anchor_height/2 - _top_size - _corner_radius - _padding; |
192 | - |
193 | - SetBaseX (x); |
194 | - SetBaseY (y); |
195 | + |
196 | + if (!_enable_quicklist_for_testing) |
197 | + { |
198 | + if ((_item_list.size () != 0) || (_default_item_list.size () != 0)) |
199 | + { |
200 | + _top_size = 4; |
201 | + size_above_anchor = _top_size; |
202 | + int x = _anchorX - _padding; |
203 | + int y = _anchorY - _anchor_height/2 - _top_size - _corner_radius - _padding; |
204 | + |
205 | + SetBaseX (x); |
206 | + SetBaseY (y); |
207 | + } |
208 | + else |
209 | + { |
210 | + _top_size = 0; |
211 | + size_above_anchor = -1; |
212 | + int x = _anchorX - _padding; |
213 | + int y = _anchorY - _anchor_height/2 - _top_size - _corner_radius - _padding; |
214 | + |
215 | + SetBaseX (x); |
216 | + SetBaseY (y); |
217 | + } |
218 | } |
219 | |
220 | float blur_coef = 6.0f; |
221 | |
222 | === modified file 'src/QuicklistView.h' |
223 | --- src/QuicklistView.h 2010-12-02 15:14:22 +0000 |
224 | +++ src/QuicklistView.h 2010-12-03 13:43:15 +0000 |
225 | @@ -87,11 +87,17 @@ |
226 | std::list<QuicklistMenuItem*> GetChildren (); |
227 | |
228 | void TestMenuItems (DbusmenuMenuitem* root); |
229 | +<<<<<<< TREE |
230 | |
231 | // Introspection |
232 | const gchar* GetName (); |
233 | void AddProperties (GVariantBuilder *builder); |
234 | |
235 | +======= |
236 | + |
237 | + void EnableQuicklistForTesting (bool enable_testing); |
238 | + |
239 | +>>>>>>> MERGE-SOURCE |
240 | private: |
241 | void RecvCairoTextChanged (QuicklistMenuItem* item); |
242 | void RecvCairoTextColorChanged (QuicklistMenuItem* item); |
243 | @@ -135,7 +141,11 @@ |
244 | int _top_size; // size of the segment from point 13 to 14. See figure in ql_compute_full_mask_path. |
245 | |
246 | bool _mouse_down; |
247 | - |
248 | + |
249 | + //iIf true, suppress the Quicklist behaviour that is expected in Unity. |
250 | + // Keep the Quicklist on screen for testing and automation. |
251 | + bool _enable_quicklist_for_testing; |
252 | + |
253 | cairo_font_options_t* _fontOpts; |
254 | |
255 | nux::BaseTexture* _texture_bg; |
256 | |
257 | === modified file 'tests/CMakeLists.txt' |
258 | --- tests/CMakeLists.txt 2010-12-02 17:23:07 +0000 |
259 | +++ tests/CMakeLists.txt 2010-12-03 13:43:15 +0000 |
260 | @@ -83,6 +83,24 @@ |
261 | ../src/PanelHomeButton.h |
262 | ) |
263 | |
264 | +add_executable (test-quicklist |
265 | + ui/TestQuicklist.cpp |
266 | + ui/EventFaker.cpp |
267 | + ui/EventFaker.h |
268 | + ../src/QuicklistMenuItem.cpp |
269 | + ../src/QuicklistMenuItem.h |
270 | + ../src/QuicklistMenuItemCheckmark.cpp |
271 | + ../src/QuicklistMenuItemCheckmark.h |
272 | + ../src/QuicklistMenuItemLabel.cpp |
273 | + ../src/QuicklistMenuItemLabel.h |
274 | + ../src/QuicklistMenuItemRadio.cpp |
275 | + ../src/QuicklistMenuItemRadio.h |
276 | + ../src/QuicklistMenuItemSeparator.cpp |
277 | + ../src/QuicklistMenuItemSeparator.h |
278 | + ../src/QuicklistView.cpp |
279 | + ../src/QuicklistView.h |
280 | + ) |
281 | + |
282 | # |
283 | # check target |
284 | # |
285 | |
286 | === added directory 'tests/ui' |
287 | === added file 'tests/ui/EventFaker.cpp' |
288 | --- tests/ui/EventFaker.cpp 1970-01-01 00:00:00 +0000 |
289 | +++ tests/ui/EventFaker.cpp 2010-12-03 13:43:15 +0000 |
290 | @@ -0,0 +1,89 @@ |
291 | +/* |
292 | + * Copyright (C) 2010 Canonical Ltd |
293 | + * |
294 | + * This program is free software: you can redistribute it and/or modify |
295 | + * it under the terms of the GNU General Public License version 3 as |
296 | + * published by the Free Software Foundation. |
297 | + * |
298 | + * This program is distributed in the hope that it will be useful, |
299 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
300 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
301 | + * GNU General Public License for more details. |
302 | + * |
303 | + * You should have received a copy of the GNU General Public License |
304 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
305 | + * |
306 | + * Authored by: Mirco Müller <mirco.mueller@canonical.com> |
307 | + */ |
308 | + |
309 | +#include "EventFaker.h" |
310 | + |
311 | +#include "NuxGraphics/GLWindowManager.h" |
312 | +#include <X11/Xlib.h> |
313 | + |
314 | +EventFaker::EventFaker (nux::WindowThread* thread) |
315 | +{ |
316 | + _thread = thread; |
317 | +} |
318 | + |
319 | +EventFaker::~EventFaker () |
320 | +{ |
321 | +} |
322 | + |
323 | +void |
324 | +EventFaker::SendClick (nux::View* view) |
325 | +{ |
326 | + Display* display = NULL; |
327 | + int x = 0; |
328 | + int y = 0; |
329 | + |
330 | + // sanity check |
331 | + if (!view) |
332 | + return; |
333 | + |
334 | + display = nux::GetThreadGLWindow()->GetX11Display (); |
335 | + |
336 | + // get a point inside the view |
337 | + x = view->GetBaseX () + 1; |
338 | + y = view->GetBaseY () + 1; |
339 | + |
340 | + // assemble a button-click event |
341 | + XButtonEvent buttonEvent = { |
342 | + ButtonRelease, |
343 | + 0, |
344 | + False, |
345 | + display, |
346 | + 0, |
347 | + 0, |
348 | + 0, |
349 | + CurrentTime, |
350 | + x, y, |
351 | + x, y, |
352 | + 0, |
353 | + Button1, |
354 | + True |
355 | + }; |
356 | + |
357 | + // send that button-click to the "thread" |
358 | + doEvent (view, (XEvent*) &buttonEvent); |
359 | +} |
360 | + |
361 | +void |
362 | +EventFaker::doEvent (nux::View* view, |
363 | + XEvent* event) |
364 | +{ |
365 | + Display* display = NULL; |
366 | + |
367 | + // sanity check |
368 | + if (!view || !event) |
369 | + return; |
370 | + |
371 | + display = nux::GetThreadGLWindow()->GetX11Display (); |
372 | + XUngrabPointer (display, CurrentTime); |
373 | + XFlush (display); |
374 | + |
375 | + _thread->ProcessForeignEvent (event, NULL); |
376 | + |
377 | + while (g_main_context_pending (NULL)) |
378 | + g_main_context_iteration (NULL, false); |
379 | +} |
380 | |
381 | === added file 'tests/ui/EventFaker.h' |
382 | --- tests/ui/EventFaker.h 1970-01-01 00:00:00 +0000 |
383 | +++ tests/ui/EventFaker.h 2010-12-03 13:43:15 +0000 |
384 | @@ -0,0 +1,40 @@ |
385 | +/* |
386 | + * Copyright (C) 2010 Canonical Ltd |
387 | + * |
388 | + * This program is free software: you can redistribute it and/or modify |
389 | + * it under the terms of the GNU General Public License version 3 as |
390 | + * published by the Free Software Foundation. |
391 | + * |
392 | + * This program is distributed in the hope that it will be useful, |
393 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
394 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
395 | + * GNU General Public License for more details. |
396 | + * |
397 | + * You should have received a copy of the GNU General Public License |
398 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
399 | + * |
400 | + * Authored by: Mirco Müller <mirco.mueller@canonical.com> |
401 | + */ |
402 | + |
403 | +#ifndef EVENT_FAKER_H |
404 | +#define EVENT_FAKER_H |
405 | + |
406 | +#include "Nux/Nux.h" |
407 | +#include "Nux/WindowThread.h" |
408 | + |
409 | +class EventFaker |
410 | +{ |
411 | + public: |
412 | + EventFaker (nux::WindowThread* thread); |
413 | + ~EventFaker (); |
414 | + |
415 | + void SendClick (nux::View* view); |
416 | + |
417 | + void doEvent (nux::View* view, |
418 | + XEvent* event); |
419 | + |
420 | + private: |
421 | + nux::WindowThread* _thread; |
422 | +}; |
423 | + |
424 | +#endif // EVENT_FAKER_H |
425 | |
426 | === added file 'tests/ui/TestQuicklist.cpp' |
427 | --- tests/ui/TestQuicklist.cpp 1970-01-01 00:00:00 +0000 |
428 | +++ tests/ui/TestQuicklist.cpp 2010-12-03 13:43:15 +0000 |
429 | @@ -0,0 +1,305 @@ |
430 | +/* |
431 | + * Copyright (C) 2010 Canonical Ltd |
432 | + * |
433 | + * This program is free software: you can redistribute it and/or modify |
434 | + * it under the terms of the GNU General Public License version 3 as |
435 | + * published by the Free Software Foundation. |
436 | + * |
437 | + * This program is distributed in the hope that it will be useful, |
438 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
439 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
440 | + * GNU General Public License for more details. |
441 | + * |
442 | + * You should have received a copy of the GNU General Public License |
443 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
444 | + * |
445 | + * Authored by: Mirco Müller <mirco.mueller@canonical.com> |
446 | + */ |
447 | + |
448 | +#include <glib.h> |
449 | +#include <gtk/gtk.h> |
450 | +#include <dbus/dbus-glib.h> |
451 | + |
452 | +#include "Nux/Nux.h" |
453 | +#include "Nux/VLayout.h" |
454 | +#include "Nux/WindowThread.h" |
455 | + |
456 | +#include "QuicklistView.h" |
457 | +#include "QuicklistMenuItem.h" |
458 | +#include "QuicklistMenuItemLabel.h" |
459 | +#include "QuicklistMenuItemSeparator.h" |
460 | +#include "QuicklistMenuItemCheckmark.h" |
461 | +#include "QuicklistMenuItemRadio.h" |
462 | + |
463 | +#include "EventFaker.h" |
464 | +#include <X11/Xlib.h> |
465 | + |
466 | +#define WIN_WIDTH 400 |
467 | +#define WIN_HEIGHT 300 |
468 | + |
469 | +gboolean gResult[3] = {false, false, false}; |
470 | + |
471 | +QuicklistView::QuicklistView* gQuicklist = NULL; |
472 | +QuicklistMenuItemCheckmark* gCheckmark = NULL; |
473 | +QuicklistMenuItemRadio* gRadio = NULL; |
474 | +QuicklistMenuItemLabel* gLabel = NULL; |
475 | + |
476 | +void |
477 | +activatedCallback (DbusmenuMenuitem* item, |
478 | + int time, |
479 | + gpointer data) |
480 | +{ |
481 | + gboolean* result = (gboolean*) data; |
482 | + |
483 | + *result = true; |
484 | + |
485 | + g_print ("Quicklist-item activated\n"); |
486 | +} |
487 | + |
488 | +QuicklistMenuItemCheckmark* |
489 | +createCheckmarkItem () |
490 | +{ |
491 | + DbusmenuMenuitem* item = NULL; |
492 | + QuicklistMenuItemCheckmark* checkmark = NULL; |
493 | + |
494 | + item = dbusmenu_menuitem_new (); |
495 | + |
496 | + dbusmenu_menuitem_property_set (item, |
497 | + DBUSMENU_MENUITEM_PROP_LABEL, |
498 | + "Unchecked"); |
499 | + |
500 | + dbusmenu_menuitem_property_set (item, |
501 | + DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE, |
502 | + DBUSMENU_MENUITEM_TOGGLE_CHECK); |
503 | + |
504 | + dbusmenu_menuitem_property_set_bool (item, |
505 | + DBUSMENU_MENUITEM_PROP_ENABLED, |
506 | + true); |
507 | + |
508 | + dbusmenu_menuitem_property_set_int (item, |
509 | + DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, |
510 | + DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED); |
511 | + |
512 | + checkmark = new QuicklistMenuItemCheckmark (item, true); |
513 | + |
514 | + g_signal_connect (item, |
515 | + DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, |
516 | + G_CALLBACK (activatedCallback), |
517 | + &gResult[0]); |
518 | + |
519 | + return checkmark; |
520 | +} |
521 | + |
522 | +QuicklistMenuItemRadio* |
523 | +createRadioItem () |
524 | +{ |
525 | + DbusmenuMenuitem* item = NULL; |
526 | + QuicklistMenuItemRadio* radio = NULL; |
527 | + |
528 | + item = dbusmenu_menuitem_new (); |
529 | + |
530 | + dbusmenu_menuitem_property_set (item, |
531 | + DBUSMENU_MENUITEM_PROP_LABEL, |
532 | + "Radio Active"); |
533 | + |
534 | + dbusmenu_menuitem_property_set (item, |
535 | + DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE, |
536 | + DBUSMENU_MENUITEM_TOGGLE_RADIO); |
537 | + |
538 | + dbusmenu_menuitem_property_set_bool (item, |
539 | + DBUSMENU_MENUITEM_PROP_ENABLED, |
540 | + true); |
541 | + |
542 | + dbusmenu_menuitem_property_set_int (item, |
543 | + DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, |
544 | + DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED); |
545 | + |
546 | + radio = new QuicklistMenuItemRadio (item, true); |
547 | + |
548 | + g_signal_connect (item, |
549 | + DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, |
550 | + G_CALLBACK (activatedCallback), |
551 | + &gResult[1]); |
552 | + |
553 | + return radio; |
554 | +} |
555 | + |
556 | +QuicklistMenuItemLabel* |
557 | +createLabelItem () |
558 | +{ |
559 | + DbusmenuMenuitem* item = NULL; |
560 | + QuicklistMenuItemLabel* label = NULL; |
561 | + |
562 | + item = dbusmenu_menuitem_new (); |
563 | + |
564 | + dbusmenu_menuitem_property_set (item, |
565 | + DBUSMENU_MENUITEM_PROP_LABEL, |
566 | + "A Label"); |
567 | + |
568 | + dbusmenu_menuitem_property_set_bool (item, |
569 | + DBUSMENU_MENUITEM_PROP_ENABLED, |
570 | + true); |
571 | + |
572 | + label = new QuicklistMenuItemLabel (item, true); |
573 | + |
574 | + g_signal_connect (item, |
575 | + DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, |
576 | + G_CALLBACK (activatedCallback), |
577 | + &gResult[2]); |
578 | + |
579 | + return label; |
580 | +} |
581 | + |
582 | +void |
583 | +ThreadWidgetInit (nux::NThread* thread, |
584 | + void* initData) |
585 | +{ |
586 | + gQuicklist = new QuicklistView::QuicklistView (); |
587 | + gQuicklist->Reference (); |
588 | + |
589 | + gCheckmark = createCheckmarkItem (); |
590 | + gQuicklist->AddMenuItem (gCheckmark); |
591 | + gRadio = createRadioItem (); |
592 | + gQuicklist->AddMenuItem (gRadio); |
593 | + gLabel = createLabelItem (); |
594 | + gQuicklist->AddMenuItem (gLabel); |
595 | + |
596 | + gQuicklist->EnableQuicklistForTesting (true); |
597 | + |
598 | + gQuicklist->SetBaseXY (0, 0); |
599 | + gQuicklist->ShowWindow (true); |
600 | +} |
601 | + |
602 | +void |
603 | +ControlThread (nux::NThread* thread, |
604 | + void* data) |
605 | +{ |
606 | + // sleep for 3 seconds |
607 | + nux::SleepForMilliseconds (3000); |
608 | + printf ("ControlThread successfully started\n"); |
609 | + |
610 | + nux::WindowThread* mainWindowThread = NUX_STATIC_CAST (nux::WindowThread*, |
611 | + data); |
612 | + |
613 | + mainWindowThread->SetFakeEventMode (true); |
614 | + Display* display = mainWindowThread->GetWindow ().GetX11Display (); |
615 | + |
616 | + // assemble first button-click event |
617 | + XEvent buttonPressEvent; |
618 | + buttonPressEvent.xbutton.type = ButtonPress; |
619 | + buttonPressEvent.xbutton.serial = 0; |
620 | + buttonPressEvent.xbutton.send_event = False; |
621 | + buttonPressEvent.xbutton.display = display; |
622 | + buttonPressEvent.xbutton.window = 0; |
623 | + buttonPressEvent.xbutton.root = 0; |
624 | + buttonPressEvent.xbutton.subwindow = 0; |
625 | + buttonPressEvent.xbutton.time = CurrentTime; |
626 | + buttonPressEvent.xbutton.x = 50; |
627 | + buttonPressEvent.xbutton.y = 30; |
628 | + buttonPressEvent.xbutton.x_root = 0; |
629 | + buttonPressEvent.xbutton.y_root = 0; |
630 | + buttonPressEvent.xbutton.state = 0; |
631 | + buttonPressEvent.xbutton.button = Button1; |
632 | + buttonPressEvent.xbutton.same_screen = True; |
633 | + |
634 | + mainWindowThread->PumpFakeEventIntoPipe (mainWindowThread, |
635 | + (XEvent*) &buttonPressEvent); |
636 | + |
637 | + while (!mainWindowThread->ReadyForNextFakeEvent ()) |
638 | + nux::SleepForMilliseconds (10); |
639 | + |
640 | + XEvent buttonReleaseEvent; |
641 | + buttonReleaseEvent.xbutton.type = ButtonRelease; |
642 | + buttonReleaseEvent.xbutton.serial = 0; |
643 | + buttonReleaseEvent.xbutton.send_event = False; |
644 | + buttonReleaseEvent.xbutton.display = display; |
645 | + buttonReleaseEvent.xbutton.window = 0; |
646 | + buttonReleaseEvent.xbutton.root = 0; |
647 | + buttonReleaseEvent.xbutton.subwindow = 0; |
648 | + buttonReleaseEvent.xbutton.time = CurrentTime; |
649 | + buttonReleaseEvent.xbutton.x = 50; |
650 | + buttonReleaseEvent.xbutton.y = 30; |
651 | + buttonReleaseEvent.xbutton.x_root = 0; |
652 | + buttonReleaseEvent.xbutton.y_root = 0; |
653 | + buttonReleaseEvent.xbutton.state = 0; |
654 | + buttonReleaseEvent.xbutton.button = Button1; |
655 | + buttonReleaseEvent.xbutton.same_screen = True; |
656 | + |
657 | + mainWindowThread->PumpFakeEventIntoPipe (mainWindowThread, |
658 | + (XEvent*) &buttonReleaseEvent); |
659 | + |
660 | + while (!mainWindowThread->ReadyForNextFakeEvent ()) |
661 | + nux::SleepForMilliseconds (10); |
662 | + |
663 | + // assemble second button-click event |
664 | + buttonPressEvent.xbutton.time = CurrentTime; |
665 | + buttonPressEvent.xbutton.x = 50; |
666 | + buttonPressEvent.xbutton.y = 45; |
667 | + mainWindowThread->PumpFakeEventIntoPipe (mainWindowThread, |
668 | + (XEvent*) &buttonPressEvent); |
669 | + while (!mainWindowThread->ReadyForNextFakeEvent ()) |
670 | + nux::SleepForMilliseconds (10); |
671 | + |
672 | + buttonReleaseEvent.xbutton.time = CurrentTime; |
673 | + buttonReleaseEvent.xbutton.x = 50; |
674 | + buttonReleaseEvent.xbutton.y = 45; |
675 | + mainWindowThread->PumpFakeEventIntoPipe (mainWindowThread, |
676 | + (XEvent*) &buttonReleaseEvent); |
677 | + while (!mainWindowThread->ReadyForNextFakeEvent ()) |
678 | + nux::SleepForMilliseconds (10); |
679 | + |
680 | + // assemble third button-click event |
681 | + buttonPressEvent.xbutton.time = CurrentTime; |
682 | + buttonPressEvent.xbutton.x = 50; |
683 | + buttonPressEvent.xbutton.y = 60; |
684 | + mainWindowThread->PumpFakeEventIntoPipe (mainWindowThread, |
685 | + (XEvent*) &buttonPressEvent); |
686 | + while (!mainWindowThread->ReadyForNextFakeEvent ()) |
687 | + nux::SleepForMilliseconds (10); |
688 | + |
689 | + buttonReleaseEvent.xbutton.time = CurrentTime; |
690 | + buttonReleaseEvent.xbutton.x = 50; |
691 | + buttonReleaseEvent.xbutton.y = 60; |
692 | + mainWindowThread->PumpFakeEventIntoPipe (mainWindowThread, |
693 | + (XEvent*) &buttonReleaseEvent); |
694 | + while (!mainWindowThread->ReadyForNextFakeEvent ()) |
695 | + nux::SleepForMilliseconds (10); |
696 | + |
697 | + mainWindowThread->SetFakeEventMode (false); |
698 | +} |
699 | + |
700 | +int |
701 | +main (int argc, char **argv) |
702 | +{ |
703 | + nux::WindowThread* wt = NULL; |
704 | + nux::SystemThread* st = NULL; |
705 | + |
706 | + g_type_init (); |
707 | + g_thread_init (NULL); |
708 | + gtk_init (&argc, &argv); |
709 | + dbus_g_thread_init (); |
710 | + nux::NuxInitialize (0); |
711 | + |
712 | + wt = nux::CreateGUIThread (TEXT ("Unity Quicklist"), |
713 | + WIN_WIDTH, |
714 | + WIN_HEIGHT, |
715 | + 0, |
716 | + &ThreadWidgetInit, |
717 | + NULL); |
718 | + |
719 | + st = nux::CreateSystemThread (NULL, ControlThread, wt); |
720 | + if (st) |
721 | + st->Start (NULL); |
722 | + |
723 | + wt->Run (NULL); |
724 | + |
725 | + gQuicklist->UnReference (); |
726 | + delete st; |
727 | + delete wt; |
728 | + |
729 | + g_assert_cmpint (gResult[0], ==, true); |
730 | + g_assert_cmpint (gResult[1], ==, true); |
731 | + g_assert_cmpint (gResult[2], ==, true); |
732 | + |
733 | + return 0; |
734 | +} |
Okay so this test works and the code seems fine approving, :)