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

Side by Side Diff: content/browser/web_contents/web_contents_drag_win.cc

Issue 14122008: Enable touch-initiated drag-drop work on Windows (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 7 years, 8 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 "content/browser/web_contents/web_contents_drag_win.h" 5 #include "content/browser/web_contents/web_contents_drag_win.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 8
9 #include <string> 9 #include <string>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/file_util.h" 12 #include "base/file_util.h"
13 #include "base/files/file_path.h" 13 #include "base/files/file_path.h"
14 #include "base/message_loop.h" 14 #include "base/message_loop.h"
15 #include "base/pickle.h" 15 #include "base/pickle.h"
16 #include "base/threading/platform_thread.h" 16 #include "base/threading/platform_thread.h"
17 #include "base/threading/thread.h" 17 #include "base/threading/thread.h"
18 #include "base/utf_string_conversions.h" 18 #include "base/utf_string_conversions.h"
19 #include "content/browser/download/drag_download_file.h" 19 #include "content/browser/download/drag_download_file.h"
20 #include "content/browser/download/drag_download_util.h" 20 #include "content/browser/download/drag_download_util.h"
21 #include "content/browser/renderer_host/render_widget_host_view_win.h"
21 #include "content/browser/web_contents/web_drag_dest_win.h" 22 #include "content/browser/web_contents/web_drag_dest_win.h"
22 #include "content/browser/web_contents/web_drag_source_win.h" 23 #include "content/browser/web_contents/web_drag_source_win.h"
23 #include "content/browser/web_contents/web_drag_utils_win.h" 24 #include "content/browser/web_contents/web_drag_utils_win.h"
24 #include "content/public/browser/browser_thread.h" 25 #include "content/public/browser/browser_thread.h"
25 #include "content/public/browser/content_browser_client.h" 26 #include "content/public/browser/content_browser_client.h"
26 #include "content/public/browser/web_contents.h" 27 #include "content/public/browser/web_contents.h"
27 #include "content/public/browser/web_contents_view.h" 28 #include "content/public/browser/web_contents_view.h"
28 #include "content/public/browser/web_drag_dest_delegate.h" 29 #include "content/public/browser/web_drag_dest_delegate.h"
29 #include "net/base/net_util.h" 30 #include "net/base/net_util.h"
30 #include "third_party/skia/include/core/SkBitmap.h" 31 #include "third_party/skia/include/core/SkBitmap.h"
(...skipping 11 matching lines...) Expand all
42 using WebKit::WebDragOperationCopy; 43 using WebKit::WebDragOperationCopy;
43 using WebKit::WebDragOperationLink; 44 using WebKit::WebDragOperationLink;
44 using WebKit::WebDragOperationMove; 45 using WebKit::WebDragOperationMove;
45 46
46 namespace content { 47 namespace content {
47 namespace { 48 namespace {
48 49
49 HHOOK msg_hook = NULL; 50 HHOOK msg_hook = NULL;
50 DWORD drag_out_thread_id = 0; 51 DWORD drag_out_thread_id = 0;
51 bool mouse_up_received = false; 52 bool mouse_up_received = false;
53 const int kMaxAbsoluteCoordinate = 65535;
52 54
53 LRESULT CALLBACK MsgFilterProc(int code, WPARAM wparam, LPARAM lparam) { 55 LRESULT CALLBACK MsgFilterProc(int code, WPARAM wparam, LPARAM lparam) {
54 if (code == base::MessagePumpForUI::kMessageFilterCode && 56 if (code == base::MessagePumpForUI::kMessageFilterCode &&
55 !mouse_up_received) { 57 !mouse_up_received) {
56 MSG* msg = reinterpret_cast<MSG*>(lparam); 58 MSG* msg = reinterpret_cast<MSG*>(lparam);
57 // We do not care about WM_SYSKEYDOWN and WM_SYSKEYUP because when ALT key 59 // We do not care about WM_SYSKEYDOWN and WM_SYSKEYUP because when ALT key
58 // is pressed down on drag-and-drop, it means to create a link. 60 // is pressed down on drag-and-drop, it means to create a link.
59 if (msg->message == WM_MOUSEMOVE || msg->message == WM_LBUTTONUP || 61 if (msg->message == WM_MOUSEMOVE || msg->message == WM_LBUTTONUP ||
60 msg->message == WM_KEYDOWN || msg->message == WM_KEYUP) { 62 msg->message == WM_KEYDOWN || msg->message == WM_KEYUP) {
61 // Forward the message from the UI thread to the drag-and-drop thread. 63 // Forward the message from the UI thread to the drag-and-drop thread.
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 WebDragOperationsMask ops, 159 WebDragOperationsMask ops,
158 const gfx::ImageSkia& image, 160 const gfx::ImageSkia& image,
159 const gfx::Vector2d& image_offset) { 161 const gfx::Vector2d& image_offset) {
160 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 162 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
161 163
162 drag_source_ = new WebDragSource(source_window_, web_contents_); 164 drag_source_ = new WebDragSource(source_window_, web_contents_);
163 165
164 const GURL& page_url = web_contents_->GetURL(); 166 const GURL& page_url = web_contents_->GetURL();
165 const std::string& page_encoding = web_contents_->GetEncoding(); 167 const std::string& page_encoding = web_contents_->GetEncoding();
166 168
169 RenderWidgetHostViewWin* rwhv =
170 static_cast<RenderWidgetHostViewWin*>
171 (web_contents_->GetRenderWidgetHostView());
167 // If it is not drag-out, do the drag-and-drop in the current UI thread. 172 // If it is not drag-out, do the drag-and-drop in the current UI thread.
168 if (drop_data.download_metadata.empty()) { 173 if (drop_data.download_metadata.empty()) {
174 // If RWHV has a valid long press gesture, since DoDragDrop will run into
175 // itself loop and start a dragging session if and only if a mouse button
176 // is down and then moves, so we need to programmatically send out
177 // mouse down event and adjust the cursor position for DoDragDrop.
178 if (rwhv->has_valid_long_press_gesture())
179 SendMouseEventForTouchDnD();
180
169 if (DoDragging(drop_data, ops, page_url, page_encoding, 181 if (DoDragging(drop_data, ops, page_url, page_encoding,
170 image, image_offset)) 182 image, image_offset))
171 EndDragging(); 183 EndDragging();
172 return; 184 return;
173 } 185 }
174 186
175 // Start a background thread to do the drag-and-drop. 187 // Start a background thread to do the drag-and-drop.
176 DCHECK(!drag_drop_thread_.get()); 188 DCHECK(!drag_drop_thread_.get());
177 drag_drop_thread_.reset(new DragDropThread(this)); 189 drag_drop_thread_.reset(new DragDropThread(this));
178 base::Thread::Options options; 190 base::Thread::Options options;
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 412
401 drag_source_->CancelDrag(); 413 drag_source_->CancelDrag();
402 } 414 }
403 415
404 void WebContentsDragWin::CloseThread() { 416 void WebContentsDragWin::CloseThread() {
405 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 417 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
406 418
407 drag_drop_thread_.reset(); 419 drag_drop_thread_.reset();
408 } 420 }
409 421
422 void WebContentsDragWin::SendMouseEventForTouchDnD() {
423 RenderWidgetHostViewWin* rwhv =
424 static_cast<RenderWidgetHostViewWin*>
425 (web_contents_->GetRenderWidgetHostView());
426
427 if (!rwhv)
428 return;
429
430 RECT screen_rect;
431 ::GetWindowRect(::GetDesktopWindow(), &screen_rect);
432 int screen_width = screen_rect.right - screen_rect.left;
433 int screen_height = screen_rect.bottom - screen_rect.top;
434 gfx::Point last_touch_position = rwhv->GetLastTouchEventLocation();
435
436 // Map the screen coordinate to the normalized absolute coordinate.
437 int absolute_x =
438 last_touch_position.x() * kMaxAbsoluteCoordinate / screen_width;
439 int absolute_y =
440 last_touch_position.y() * kMaxAbsoluteCoordinate / screen_height;
441
442 // Send MOUSEEVENTF_RIGHTDOWN event followed by MOUSEEVENTF_MOVE event.
443 //
444 // The reason why not to merge these 2 mouse events into one is, we don't
445 // want DoDragDrop to get mouse event firstly which lead to drop the drag
446 // source.
447 //
448 // On Windows, once a touch point is removed from screen after long press,
449 // a MOUSEEVENTF_RIGHTUP event will be sent out, so we send the down event
450 // paired with it to complete DoDragDrop session.
451 INPUT ip;
dcheng 2013/04/15 18:07:37 Initialize this with = {}? The current code leaves
452 ip.type = INPUT_MOUSE;
453 ip.mi.dwFlags = MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_ABSOLUTE;
dcheng 2013/04/15 18:07:37 Why do we use the right mouse button? How come we
Hongbo Min 2013/04/16 01:13:44 The reason is, if we just simulate left mouse butt
dcheng 2013/04/16 01:27:28 Who's triggering the right mouse button up event t
454 ip.mi.time = 0;
455 ip.mi.dx = absolute_x;
456 ip.mi.dy = absolute_y;
457 ::SendInput(1, &ip, sizeof(INPUT));
458
459 // Send MOUSEEVENTF_MOVE input event.
460 ip.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
461 ::SendInput(1, &ip, sizeof(INPUT));
462 }
463
410 void WebContentsDragWin::OnWaitForData() { 464 void WebContentsDragWin::OnWaitForData() {
411 DCHECK(drag_drop_thread_id_ == base::PlatformThread::CurrentId()); 465 DCHECK(drag_drop_thread_id_ == base::PlatformThread::CurrentId());
412 466
413 // When the left button is release and we start to wait for the data, end 467 // When the left button is release and we start to wait for the data, end
414 // the dragging before DoDragDrop returns. This makes the page leave the drag 468 // the dragging before DoDragDrop returns. This makes the page leave the drag
415 // mode so that it can start to process the normal input events. 469 // mode so that it can start to process the normal input events.
416 BrowserThread::PostTask( 470 BrowserThread::PostTask(
417 BrowserThread::UI, 471 BrowserThread::UI,
418 FROM_HERE, 472 FROM_HERE,
419 base::Bind(&WebContentsDragWin::EndDragging, this)); 473 base::Bind(&WebContentsDragWin::EndDragging, this));
420 } 474 }
421 475
422 void WebContentsDragWin::OnDataObjectDisposed() { 476 void WebContentsDragWin::OnDataObjectDisposed() {
423 DCHECK(drag_drop_thread_id_ == base::PlatformThread::CurrentId()); 477 DCHECK(drag_drop_thread_id_ == base::PlatformThread::CurrentId());
424 478
425 // The drag-and-drop thread is only closed after OLE is done with 479 // The drag-and-drop thread is only closed after OLE is done with
426 // DataObjectImpl. 480 // DataObjectImpl.
427 BrowserThread::PostTask( 481 BrowserThread::PostTask(
428 BrowserThread::UI, 482 BrowserThread::UI,
429 FROM_HERE, 483 FROM_HERE,
430 base::Bind(&WebContentsDragWin::CloseThread, this)); 484 base::Bind(&WebContentsDragWin::CloseThread, this));
431 } 485 }
432 486
433 } // namespace content 487 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698