OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/browser/ui/gtk/tab_contents_drag_source.h" | 5 #include "chrome/browser/ui/gtk/tab_contents_drag_source.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
10 #include "base/mime_util.h" | 10 #include "base/mime_util.h" |
11 #include "base/threading/thread_restrictions.h" | 11 #include "base/threading/thread_restrictions.h" |
12 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
13 #include "chrome/browser/download/download_util.h" | 13 #include "chrome/browser/download/download_util.h" |
14 #include "chrome/browser/ui/gtk/gtk_util.h" | |
15 #include "content/browser/download/drag_download_file.h" | 14 #include "content/browser/download/drag_download_file.h" |
16 #include "content/browser/download/drag_download_util.h" | 15 #include "content/browser/download/drag_download_util.h" |
17 #include "content/browser/renderer_host/render_view_host.h" | 16 #include "content/browser/renderer_host/render_view_host.h" |
18 #include "content/browser/renderer_host/render_view_host_delegate.h" | 17 #include "content/browser/renderer_host/render_view_host_delegate.h" |
| 18 #include "content/browser/tab_contents/drag_utils_gtk.h" |
19 #include "content/browser/tab_contents/tab_contents.h" | 19 #include "content/browser/tab_contents/tab_contents.h" |
20 #include "content/browser/tab_contents/tab_contents_view.h" | 20 #include "content/browser/tab_contents/tab_contents_view.h" |
21 #include "net/base/file_stream.h" | 21 #include "net/base/file_stream.h" |
22 #include "net/base/net_util.h" | 22 #include "net/base/net_util.h" |
23 #include "ui/base/dragdrop/gtk_dnd_util.h" | 23 #include "ui/base/dragdrop/gtk_dnd_util.h" |
| 24 #include "ui/base/gtk/gtk_screen_utils.h" |
24 #include "ui/gfx/gtk_util.h" | 25 #include "ui/gfx/gtk_util.h" |
25 #include "webkit/glue/webdropdata.h" | 26 #include "webkit/glue/webdropdata.h" |
26 | 27 |
27 using WebKit::WebDragOperation; | 28 using WebKit::WebDragOperation; |
28 using WebKit::WebDragOperationsMask; | 29 using WebKit::WebDragOperationsMask; |
29 using WebKit::WebDragOperationNone; | 30 using WebKit::WebDragOperationNone; |
30 | 31 |
31 TabContentsDragSource::TabContentsDragSource(TabContents* tab_contents) | 32 TabContentsDragSource::TabContentsDragSource(TabContents* tab_contents) |
32 : tab_contents_(tab_contents), | 33 : tab_contents_(tab_contents), |
33 drag_pixbuf_(NULL), | 34 drag_pixbuf_(NULL), |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 targets_mask |= ui::DIRECT_SAVE_FILE; | 96 targets_mask |= ui::DIRECT_SAVE_FILE; |
96 } | 97 } |
97 | 98 |
98 // NOTE: Begin a drag even if no targets present. Otherwise, things like | 99 // NOTE: Begin a drag even if no targets present. Otherwise, things like |
99 // draggable list elements will not work. | 100 // draggable list elements will not work. |
100 | 101 |
101 drop_data_.reset(new WebDropData(drop_data)); | 102 drop_data_.reset(new WebDropData(drop_data)); |
102 | 103 |
103 // The image we get from WebKit makes heavy use of alpha-shading. This looks | 104 // The image we get from WebKit makes heavy use of alpha-shading. This looks |
104 // bad on non-compositing WMs. Fall back to the default drag icon. | 105 // bad on non-compositing WMs. Fall back to the default drag icon. |
105 if (!image.isNull() && gtk_util::IsScreenComposited()) | 106 if (!image.isNull() && ui::IsScreenComposited()) |
106 drag_pixbuf_ = gfx::GdkPixbufFromSkBitmap(&image); | 107 drag_pixbuf_ = gfx::GdkPixbufFromSkBitmap(&image); |
107 image_offset_ = image_offset; | 108 image_offset_ = image_offset; |
108 | 109 |
109 GtkTargetList* list = ui::GetTargetListFromCodeMask(targets_mask); | 110 GtkTargetList* list = ui::GetTargetListFromCodeMask(targets_mask); |
110 if (targets_mask & ui::CHROME_WEBDROP_FILE_CONTENTS) { | 111 if (targets_mask & ui::CHROME_WEBDROP_FILE_CONTENTS) { |
111 // Looking up the mime type can hit the disk. http://crbug.com/84896 | 112 // Looking up the mime type can hit the disk. http://crbug.com/84896 |
112 base::ThreadRestrictions::ScopedAllowIO allow_io; | 113 base::ThreadRestrictions::ScopedAllowIO allow_io; |
113 drag_file_mime_type_ = gdk_atom_intern( | 114 drag_file_mime_type_ = gdk_atom_intern( |
114 mime_util::GetDataMimeType(drop_data.file_contents).c_str(), FALSE); | 115 mime_util::GetDataMimeType(drop_data.file_contents).c_str(), FALSE); |
115 gtk_target_list_add(list, drag_file_mime_type_, | 116 gtk_target_list_add(list, drag_file_mime_type_, |
116 0, ui::CHROME_WEBDROP_FILE_CONTENTS); | 117 0, ui::CHROME_WEBDROP_FILE_CONTENTS); |
117 } | 118 } |
118 | 119 |
119 drag_failed_ = false; | 120 drag_failed_ = false; |
120 // If we don't pass an event, GDK won't know what event time to start grabbing | 121 // If we don't pass an event, GDK won't know what event time to start grabbing |
121 // mouse events. Technically it's the mouse motion event and not the mouse | 122 // mouse events. Technically it's the mouse motion event and not the mouse |
122 // down event that causes the drag, but there's no reliable way to know | 123 // down event that causes the drag, but there's no reliable way to know |
123 // *which* motion event initiated the drag, so this will have to do. | 124 // *which* motion event initiated the drag, so this will have to do. |
124 // TODO(estade): This can sometimes be very far off, e.g. if the user clicks | 125 // TODO(estade): This can sometimes be very far off, e.g. if the user clicks |
125 // and holds and doesn't start dragging for a long time. I doubt it matters | 126 // and holds and doesn't start dragging for a long time. I doubt it matters |
126 // much, but we should probably look into the possibility of getting the | 127 // much, but we should probably look into the possibility of getting the |
127 // initiating event from webkit. | 128 // initiating event from webkit. |
128 drag_context_ = gtk_drag_begin(drag_widget_, list, | 129 drag_context_ = gtk_drag_begin(drag_widget_, list, |
129 gtk_util::WebDragOpToGdkDragAction(allowed_ops), | 130 content::WebDragOpToGdkDragAction(allowed_ops), |
130 1, // Drags are always initiated by the left button. | 131 1, // Drags are always initiated by the left button. |
131 reinterpret_cast<GdkEvent*>(last_mouse_down)); | 132 reinterpret_cast<GdkEvent*>(last_mouse_down)); |
132 // The drag adds a ref; let it own the list. | 133 // The drag adds a ref; let it own the list. |
133 gtk_target_list_unref(list); | 134 gtk_target_list_unref(list); |
134 | 135 |
135 // Sometimes the drag fails to start; |context| will be NULL and we won't | 136 // Sometimes the drag fails to start; |context| will be NULL and we won't |
136 // get a drag-end signal. | 137 // get a drag-end signal. |
137 if (!drag_context_) { | 138 if (!drag_context_) { |
138 drag_failed_ = true; | 139 drag_failed_ = true; |
139 drop_data_.reset(); | 140 drop_data_.reset(); |
140 tab_contents_->SystemDragEnded(); | 141 tab_contents_->SystemDragEnded(); |
141 return; | 142 return; |
142 } | 143 } |
143 | 144 |
144 MessageLoopForUI::current()->AddObserver(this); | 145 MessageLoopForUI::current()->AddObserver(this); |
145 } | 146 } |
146 | 147 |
147 void TabContentsDragSource::WillProcessEvent(GdkEvent* event) { | 148 void TabContentsDragSource::WillProcessEvent(GdkEvent* event) { |
148 // No-op. | 149 // No-op. |
149 } | 150 } |
150 | 151 |
151 void TabContentsDragSource::DidProcessEvent(GdkEvent* event) { | 152 void TabContentsDragSource::DidProcessEvent(GdkEvent* event) { |
152 if (event->type != GDK_MOTION_NOTIFY) | 153 if (event->type != GDK_MOTION_NOTIFY) |
153 return; | 154 return; |
154 | 155 |
155 GdkEventMotion* event_motion = reinterpret_cast<GdkEventMotion*>(event); | 156 GdkEventMotion* event_motion = reinterpret_cast<GdkEventMotion*>(event); |
156 gfx::Point client = gtk_util::ClientPoint(GetContentNativeView()); | 157 gfx::Point client = ui::ClientPoint(GetContentNativeView()); |
157 | 158 |
158 if (tab_contents_->render_view_host()) { | 159 if (tab_contents_->render_view_host()) { |
159 tab_contents_->render_view_host()->DragSourceMovedTo( | 160 tab_contents_->render_view_host()->DragSourceMovedTo( |
160 client.x(), client.y(), | 161 client.x(), client.y(), |
161 static_cast<int>(event_motion->x_root), | 162 static_cast<int>(event_motion->x_root), |
162 static_cast<int>(event_motion->y_root)); | 163 static_cast<int>(event_motion->y_root)); |
163 } | 164 } |
164 } | 165 } |
165 | 166 |
166 void TabContentsDragSource::OnDragDataGet(GtkWidget* sender, | 167 void TabContentsDragSource::OnDragDataGet(GtkWidget* sender, |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 default: | 265 default: |
265 NOTREACHED(); | 266 NOTREACHED(); |
266 } | 267 } |
267 } | 268 } |
268 | 269 |
269 gboolean TabContentsDragSource::OnDragFailed(GtkWidget* sender, | 270 gboolean TabContentsDragSource::OnDragFailed(GtkWidget* sender, |
270 GdkDragContext* context, | 271 GdkDragContext* context, |
271 GtkDragResult result) { | 272 GtkDragResult result) { |
272 drag_failed_ = true; | 273 drag_failed_ = true; |
273 | 274 |
274 gfx::Point root = gtk_util::ScreenPoint(GetContentNativeView()); | 275 gfx::Point root = ui::ScreenPoint(GetContentNativeView()); |
275 gfx::Point client = gtk_util::ClientPoint(GetContentNativeView()); | 276 gfx::Point client = ui::ClientPoint(GetContentNativeView()); |
276 | 277 |
277 if (tab_contents_->render_view_host()) { | 278 if (tab_contents_->render_view_host()) { |
278 tab_contents_->render_view_host()->DragSourceEndedAt( | 279 tab_contents_->render_view_host()->DragSourceEndedAt( |
279 client.x(), client.y(), root.x(), root.y(), | 280 client.x(), client.y(), root.x(), root.y(), |
280 WebDragOperationNone); | 281 WebDragOperationNone); |
281 } | 282 } |
282 | 283 |
283 // Let the native failure animation run. | 284 // Let the native failure animation run. |
284 return FALSE; | 285 return FALSE; |
285 } | 286 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 } | 334 } |
334 | 335 |
335 MessageLoopForUI::current()->RemoveObserver(this); | 336 MessageLoopForUI::current()->RemoveObserver(this); |
336 | 337 |
337 if (!download_url_.is_empty()) { | 338 if (!download_url_.is_empty()) { |
338 gdk_property_delete(drag_context->source_window, | 339 gdk_property_delete(drag_context->source_window, |
339 ui::GetAtomForTarget(ui::DIRECT_SAVE_FILE)); | 340 ui::GetAtomForTarget(ui::DIRECT_SAVE_FILE)); |
340 } | 341 } |
341 | 342 |
342 if (!drag_failed_) { | 343 if (!drag_failed_) { |
343 gfx::Point root = gtk_util::ScreenPoint(GetContentNativeView()); | 344 gfx::Point root = ui::ScreenPoint(GetContentNativeView()); |
344 gfx::Point client = gtk_util::ClientPoint(GetContentNativeView()); | 345 gfx::Point client = ui::ClientPoint(GetContentNativeView()); |
345 | 346 |
346 if (tab_contents_->render_view_host()) { | 347 if (tab_contents_->render_view_host()) { |
347 tab_contents_->render_view_host()->DragSourceEndedAt( | 348 tab_contents_->render_view_host()->DragSourceEndedAt( |
348 client.x(), client.y(), root.x(), root.y(), | 349 client.x(), client.y(), root.x(), root.y(), |
349 gtk_util::GdkDragActionToWebDragOp(drag_context->action)); | 350 content::GdkDragActionToWebDragOp(drag_context->action)); |
350 } | 351 } |
351 } | 352 } |
352 | 353 |
353 tab_contents_->SystemDragEnded(); | 354 tab_contents_->SystemDragEnded(); |
354 | 355 |
355 drop_data_.reset(); | 356 drop_data_.reset(); |
356 drag_context_ = NULL; | 357 drag_context_ = NULL; |
357 } | 358 } |
358 | 359 |
359 gfx::NativeView TabContentsDragSource::GetContentNativeView() const { | 360 gfx::NativeView TabContentsDragSource::GetContentNativeView() const { |
360 return tab_contents_->view()->GetContentNativeView(); | 361 return tab_contents_->view()->GetContentNativeView(); |
361 } | 362 } |
362 | 363 |
363 gboolean TabContentsDragSource::OnDragIconExpose(GtkWidget* sender, | 364 gboolean TabContentsDragSource::OnDragIconExpose(GtkWidget* sender, |
364 GdkEventExpose* event) { | 365 GdkEventExpose* event) { |
365 cairo_t* cr = gdk_cairo_create(event->window); | 366 cairo_t* cr = gdk_cairo_create(event->window); |
366 gdk_cairo_rectangle(cr, &event->area); | 367 gdk_cairo_rectangle(cr, &event->area); |
367 cairo_clip(cr); | 368 cairo_clip(cr); |
368 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); | 369 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); |
369 gdk_cairo_set_source_pixbuf(cr, drag_pixbuf_, 0, 0); | 370 gdk_cairo_set_source_pixbuf(cr, drag_pixbuf_, 0, 0); |
370 cairo_paint(cr); | 371 cairo_paint(cr); |
371 cairo_destroy(cr); | 372 cairo_destroy(cr); |
372 | 373 |
373 return TRUE; | 374 return TRUE; |
374 } | 375 } |
OLD | NEW |