Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(388)

Side by Side Diff: chrome/test/base/interactive_test_utils_mac.mm

Issue 1747803003: MacViews: Implement Tab Dragging (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removed debug logging, use CGEvents for drag-n-drop. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/test/base/interactive_test_utils.h" 5 #include "chrome/test/base/interactive_test_utils.h"
6 6
7 #include <Carbon/Carbon.h> 7 #include <Carbon/Carbon.h>
8 #import <Cocoa/Cocoa.h> 8 #import <Cocoa/Cocoa.h>
9 9
10 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
11 #include "chrome/app/chrome_command_ids.h" 11 #include "chrome/app/chrome_command_ids.h"
12 #include "content/public/test/test_utils.h"
12 #import "ui/base/test/windowed_nsnotification_observer.h" 13 #import "ui/base/test/windowed_nsnotification_observer.h"
14 #include "ui/gfx/animation/tween.h"
15 #include "ui/gfx/mac/coordinate_conversion.h"
16
17 namespace {
18
19 bool WaitForEvent(
20 bool (^dispatch_event_block)(const base::Closure& quit_closure)) {
21 scoped_refptr<content::MessageLoopRunner> runner =
22 new content::MessageLoopRunner;
23 bool result = dispatch_event_block(runner->QuitClosure());
24 runner->Run();
25 return result;
26 }
27
28 bool MouseMove(const gfx::Point& p) {
29 return WaitForEvent(^(const base::Closure& quit_closure) {
30 return ui_controls::SendMouseMoveNotifyWhenDone(p.x(), p.y(), quit_closure);
31 });
32 }
33
34 bool MouseDown() {
35 return WaitForEvent(^(const base::Closure& quit_closure) {
36 return ui_controls::SendMouseEventsNotifyWhenDone(
37 ui_controls::LEFT, ui_controls::DOWN, quit_closure);
38 });
39 }
40
41 bool MouseUp() {
42 return WaitForEvent(^(const base::Closure& quit_closure) {
43 return ui_controls::SendMouseEventsNotifyWhenDone(
44 ui_controls::LEFT, ui_controls::UP, quit_closure);
45 });
46 }
47
48 } // namespace
13 49
14 namespace ui_test_utils { 50 namespace ui_test_utils {
15 51
16 void HideNativeWindow(gfx::NativeWindow window) { 52 void HideNativeWindow(gfx::NativeWindow window) {
17 [window orderOut:nil]; 53 [window orderOut:nil];
18 } 54 }
19 55
20 bool ShowAndFocusNativeWindow(gfx::NativeWindow window) { 56 bool ShowAndFocusNativeWindow(gfx::NativeWindow window) {
21 // Make sure an unbundled program can get the input focus. 57 // Make sure an unbundled program can get the input focus.
22 ProcessSerialNumber psn = { 0, kCurrentProcess }; 58 ProcessSerialNumber psn = { 0, kCurrentProcess };
(...skipping 14 matching lines...) Expand all
37 // This is because normal AppKit menu updating does not get invoked when 73 // This is because normal AppKit menu updating does not get invoked when
38 // events are sent via ui_test_utils::SendKeyPressSync. 74 // events are sent via ui_test_utils::SendKeyPressSync.
39 BOOL notification_observed = [async_waiter wait]; 75 BOOL notification_observed = [async_waiter wait];
40 base::RunLoop().RunUntilIdle(); // There may be other events queued. Flush. 76 base::RunLoop().RunUntilIdle(); // There may be other events queued. Flush.
41 NSMenu* file_menu = [[[NSApp mainMenu] itemWithTag:IDC_FILE_MENU] submenu]; 77 NSMenu* file_menu = [[[NSApp mainMenu] itemWithTag:IDC_FILE_MENU] submenu];
42 [[file_menu delegate] menuNeedsUpdate:file_menu]; 78 [[file_menu delegate] menuNeedsUpdate:file_menu];
43 79
44 return !async_waiter || notification_observed; 80 return !async_waiter || notification_observed;
45 } 81 }
46 82
83 void DragAndDrop(const gfx::Point& from,
84 const gfx::Point& to,
85 base::TimeDelta delay,
86 unsigned int steps) {
87 DCHECK_GE(steps, 1u);
88 const bool enable_cgevents = ui_controls::SendMouseEventsAsCGEvents();
89 ui_controls::SetSendMouseEventsAsCGEvents(true);
90
91 auto queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
92 scoped_refptr<content::MessageLoopRunner> runner =
93 new content::MessageLoopRunner;
94
95 dispatch_async(queue, ^{
96 scoped_ptr<base::MessageLoop> loop(
97 new base::MessageLoop(base::MessageLoop::TYPE_DEFAULT));
98
99 MouseMove(from);
100 MouseDown();
101
102 // If steps is greater than 1, then we need to use CGEvents, otherwise
103 // the CocoaWindowMoveLoop won't actually work, as the window dragged works
104 // on the WindowServer level.
105 for (unsigned int i = 1; i <= steps; ++i) {
106 const double progress = double(i) / steps;
107 const gfx::Point p(
108 gfx::Tween::IntValueBetween(progress, from.x(), to.x()),
109 gfx::Tween::IntValueBetween(progress, from.y(), to.y()));
110 MouseMove(p);
111 }
112
113 // specify a delay if there's a non-zero drag'n'drop delay, like
114 // kTearDuration in tab_strip_drag_controller.mm
115 usleep(delay.InMicroseconds());
116
117 MouseUp();
118
119 // FIXME(mblsha): Need to find a way to wait until CocoaWindowMoveLoop is
120 // finished.
121 usleep(100000.0);
themblsha 2016/03/03 17:56:51 Now the code works very reliably with the exceptio
tapted 2016/03/04 06:33:08 There's a BridgedNativeWidgetTestApi which has acc
themblsha 2016/03/09 17:40:22 Done.
122
123 dispatch_async(dispatch_get_main_queue(), ^{
124 runner->Quit();
125 });
126 });
127
128 // we need to run the loop on the main thread, so the mouse events will be
129 // actually processed
130 runner->Run();
131
132 ui_controls::SetSendMouseEventsAsCGEvents(enable_cgevents);
133 }
134
47 } // namespace ui_test_utils 135 } // namespace ui_test_utils
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698