 Chromium Code Reviews
 Chromium Code Reviews Issue 14122008:
  Enable touch-initiated drag-drop work on Windows  (Closed) 
  Base URL: http://git.chromium.org/chromium/src.git@master
    
  
    Issue 14122008:
  Enable touch-initiated drag-drop work on Windows  (Closed) 
  Base URL: http://git.chromium.org/chromium/src.git@master| Index: content/browser/web_contents/web_contents_drag_win.cc | 
| diff --git a/content/browser/web_contents/web_contents_drag_win.cc b/content/browser/web_contents/web_contents_drag_win.cc | 
| index 0b7fac48c7a486125726f73665ee01b93f3bd8a9..10519394769ab1f35d92c6a757fb146acd042491 100644 | 
| --- a/content/browser/web_contents/web_contents_drag_win.cc | 
| +++ b/content/browser/web_contents/web_contents_drag_win.cc | 
| @@ -18,6 +18,7 @@ | 
| #include "base/utf_string_conversions.h" | 
| #include "content/browser/download/drag_download_file.h" | 
| #include "content/browser/download/drag_download_util.h" | 
| +#include "content/browser/renderer_host/render_widget_host_view_win.h" | 
| #include "content/browser/web_contents/web_drag_dest_win.h" | 
| #include "content/browser/web_contents/web_drag_source_win.h" | 
| #include "content/browser/web_contents/web_drag_utils_win.h" | 
| @@ -49,6 +50,7 @@ namespace { | 
| HHOOK msg_hook = NULL; | 
| DWORD drag_out_thread_id = 0; | 
| bool mouse_up_received = false; | 
| +const int kMaxAbsoluteCoordinate = 65535; | 
| LRESULT CALLBACK MsgFilterProc(int code, WPARAM wparam, LPARAM lparam) { | 
| if (code == base::MessagePumpForUI::kMessageFilterCode && | 
| @@ -164,8 +166,18 @@ void WebContentsDragWin::StartDragging(const WebDropData& drop_data, | 
| const GURL& page_url = web_contents_->GetURL(); | 
| const std::string& page_encoding = web_contents_->GetEncoding(); | 
| + RenderWidgetHostViewWin* rwhv = | 
| + static_cast<RenderWidgetHostViewWin*> | 
| + (web_contents_->GetRenderWidgetHostView()); | 
| // If it is not drag-out, do the drag-and-drop in the current UI thread. | 
| if (drop_data.download_metadata.empty()) { | 
| + // If RWHV has a valid long press gesture, since DoDragDrop will run into | 
| + // itself loop and start a dragging session if and only if a mouse button | 
| + // is down and then moves, so we need to programmatically send out | 
| + // mouse down event and adjust the cursor position for DoDragDrop. | 
| + if (rwhv->has_valid_long_press_gesture()) | 
| + SendMouseEventForTouchDnD(); | 
| + | 
| if (DoDragging(drop_data, ops, page_url, page_encoding, | 
| image, image_offset)) | 
| EndDragging(); | 
| @@ -407,6 +419,48 @@ void WebContentsDragWin::CloseThread() { | 
| drag_drop_thread_.reset(); | 
| } | 
| +void WebContentsDragWin::SendMouseEventForTouchDnD() { | 
| + RenderWidgetHostViewWin* rwhv = | 
| + static_cast<RenderWidgetHostViewWin*> | 
| + (web_contents_->GetRenderWidgetHostView()); | 
| + | 
| + if (!rwhv) | 
| + return; | 
| + | 
| + RECT screen_rect; | 
| + ::GetWindowRect(::GetDesktopWindow(), &screen_rect); | 
| + int screen_width = screen_rect.right - screen_rect.left; | 
| + int screen_height = screen_rect.bottom - screen_rect.top; | 
| + gfx::Point last_touch_position = rwhv->GetLastTouchEventLocation(); | 
| + | 
| + // Map the screen coordinate to the normalized absolute coordinate. | 
| + int absolute_x = | 
| + last_touch_position.x() * kMaxAbsoluteCoordinate / screen_width; | 
| + int absolute_y = | 
| + last_touch_position.y() * kMaxAbsoluteCoordinate / screen_height; | 
| + | 
| + // Send MOUSEEVENTF_RIGHTDOWN event followed by MOUSEEVENTF_MOVE event. | 
| + // | 
| + // The reason why not to merge these 2 mouse events into one is, we don't | 
| + // want DoDragDrop to get mouse event firstly which lead to drop the drag | 
| + // source. | 
| + // | 
| + // On Windows, once a touch point is removed from screen after long press, | 
| + // a MOUSEEVENTF_RIGHTUP event will be sent out, so we send the down event | 
| + // paired with it to complete DoDragDrop session. | 
| + INPUT ip; | 
| 
dcheng
2013/04/15 18:07:37
Initialize this with = {}? The current code leaves
 | 
| + ip.type = INPUT_MOUSE; | 
| + 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
 | 
| + ip.mi.time = 0; | 
| + ip.mi.dx = absolute_x; | 
| + ip.mi.dy = absolute_y; | 
| + ::SendInput(1, &ip, sizeof(INPUT)); | 
| + | 
| + // Send MOUSEEVENTF_MOVE input event. | 
| + ip.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; | 
| + ::SendInput(1, &ip, sizeof(INPUT)); | 
| +} | 
| + | 
| void WebContentsDragWin::OnWaitForData() { | 
| DCHECK(drag_drop_thread_id_ == base::PlatformThread::CurrentId()); |