Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 #import "content/browser/web_contents/web_drag_dest_mac.h" | 5 #import "content/browser/web_contents/web_drag_dest_mac.h" |
| 6 | 6 |
| 7 #import <Carbon/Carbon.h> | 7 #import <Carbon/Carbon.h> |
| 8 | 8 |
| 9 #include "base/strings/sys_string_conversions.h" | 9 #include "base/strings/sys_string_conversions.h" |
| 10 #include "content/browser/renderer_host/render_view_host_impl.h" | 10 #include "content/browser/renderer_host/render_view_host_impl.h" |
| 11 #include "content/browser/renderer_host/render_widget_host_impl.h" | |
| 12 #include "content/browser/renderer_host/render_widget_host_input_event_router.h" | |
| 11 #include "content/browser/web_contents/web_contents_impl.h" | 13 #include "content/browser/web_contents/web_contents_impl.h" |
| 12 #include "content/public/browser/web_contents_delegate.h" | 14 #include "content/public/browser/web_contents_delegate.h" |
| 13 #include "content/public/browser/web_drag_dest_delegate.h" | 15 #include "content/public/browser/web_drag_dest_delegate.h" |
| 14 #include "content/public/common/drop_data.h" | 16 #include "content/public/common/drop_data.h" |
| 15 #include "third_party/WebKit/public/platform/WebInputEvent.h" | 17 #include "third_party/WebKit/public/platform/WebInputEvent.h" |
| 16 #import "third_party/mozilla/NSPasteboard+Utils.h" | 18 #import "third_party/mozilla/NSPasteboard+Utils.h" |
| 17 #include "ui/base/clipboard/custom_data_helper.h" | 19 #include "ui/base/clipboard/custom_data_helper.h" |
| 18 #include "ui/base/cocoa/cocoa_base_utils.h" | 20 #include "ui/base/cocoa/cocoa_base_utils.h" |
| 19 #import "ui/base/dragdrop/cocoa_dnd_util.h" | 21 #import "ui/base/dragdrop/cocoa_dnd_util.h" |
| 20 #include "ui/base/window_open_disposition.h" | 22 #include "ui/base/window_open_disposition.h" |
| 23 #include "ui/gfx/geometry/point.h" | |
| 21 | 24 |
| 22 using blink::WebDragOperationsMask; | 25 using blink::WebDragOperationsMask; |
| 23 using content::DropData; | 26 using content::DropData; |
| 24 using content::OpenURLParams; | 27 using content::OpenURLParams; |
| 25 using content::Referrer; | 28 using content::Referrer; |
| 26 using content::WebContentsImpl; | 29 using content::WebContentsImpl; |
| 27 | 30 |
| 28 namespace { | 31 namespace { |
| 29 | 32 |
| 30 int GetModifierFlags() { | 33 int GetModifierFlags() { |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 118 | 121 |
| 119 // Messages to send during the tracking of a drag, usually upon receiving | 122 // Messages to send during the tracking of a drag, usually upon receiving |
| 120 // calls from the view system. Communicates the drag messages to WebCore. | 123 // calls from the view system. Communicates the drag messages to WebCore. |
| 121 | 124 |
| 122 - (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)info | 125 - (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)info |
| 123 view:(NSView*)view { | 126 view:(NSView*)view { |
| 124 // Save off the RVH so we can tell if it changes during a drag. If it does, | 127 // Save off the RVH so we can tell if it changes during a drag. If it does, |
| 125 // we need to send a new enter message in draggingUpdated:. | 128 // we need to send a new enter message in draggingUpdated:. |
| 126 currentRVH_ = webContents_->GetRenderViewHost(); | 129 currentRVH_ = webContents_->GetRenderViewHost(); |
| 127 | 130 |
| 131 // Create the appropriate mouse locations for WebCore. The draggingLocation | |
| 132 // is in window coordinates. Both need to be flipped. | |
| 133 NSPoint windowPoint = [info draggingLocation]; | |
| 134 NSPoint viewPoint = [self flipWindowPointToView:windowPoint view:view]; | |
| 135 NSPoint screenPoint = [self flipWindowPointToScreen:windowPoint view:view]; | |
|
dcheng
2016/11/17 19:59:02
Can these three lines be moved into the helper as
paulmeyer
2016/11/17 20:46:43
Maybe... though I wasn't sure exactly how it shoul
| |
| 136 gfx::Point transformedPt; | |
| 137 currentRWHForDrag_ = | |
| 138 [self GetRenderWidgetHostAtPoint:viewPoint transformedPt:&transformedPt] | |
| 139 ->GetWeakPtr(); | |
| 140 | |
| 128 // Fill out a DropData from pasteboard. | 141 // Fill out a DropData from pasteboard. |
| 129 std::unique_ptr<DropData> dropData; | 142 std::unique_ptr<DropData> dropData; |
| 130 dropData.reset(new DropData()); | 143 dropData.reset(new DropData()); |
| 131 [self populateDropData:dropData.get() | 144 [self populateDropData:dropData.get() |
| 132 fromPasteboard:[info draggingPasteboard]]; | 145 fromPasteboard:[info draggingPasteboard]]; |
| 133 // TODO(paulmeyer): This will need to target the correct specific | 146 currentRWHForDrag_->FilterDropData(dropData.get()); |
|
dcheng
2016/11/17 19:59:02
I think this still needs a TODO: it means we pull
paulmeyer
2016/11/17 20:46:43
Added TODO.
| |
| 134 // RenderWidgetHost to work with OOPIFs. See crbug.com/647249. | |
| 135 currentRVH_->GetWidget()->FilterDropData(dropData.get()); | |
| 136 | 147 |
| 137 NSDragOperation mask = [info draggingSourceOperationMask]; | 148 NSDragOperation mask = [info draggingSourceOperationMask]; |
| 138 | 149 |
| 139 // Give the delegate an opportunity to cancel the drag. | 150 // Give the delegate an opportunity to cancel the drag. |
| 140 canceled_ = !webContents_->GetDelegate()->CanDragEnter( | 151 canceled_ = !webContents_->GetDelegate()->CanDragEnter( |
| 141 webContents_, | 152 webContents_, |
| 142 *dropData, | 153 *dropData, |
| 143 static_cast<WebDragOperationsMask>(mask)); | 154 static_cast<WebDragOperationsMask>(mask)); |
| 144 if (canceled_) | 155 if (canceled_) |
| 145 return NSDragOperationNone; | 156 return NSDragOperationNone; |
| 146 | 157 |
| 147 if ([self onlyAllowsNavigation]) { | 158 if ([self onlyAllowsNavigation]) { |
| 148 if ([[info draggingPasteboard] containsURLDataConvertingTextToURL:YES]) | 159 if ([[info draggingPasteboard] containsURLDataConvertingTextToURL:YES]) |
| 149 return NSDragOperationCopy; | 160 return NSDragOperationCopy; |
| 150 return NSDragOperationNone; | 161 return NSDragOperationNone; |
| 151 } | 162 } |
| 152 | 163 |
| 153 if (delegate_) { | 164 if (delegate_) { |
| 154 delegate_->DragInitialize(webContents_); | 165 delegate_->DragInitialize(webContents_); |
| 155 delegate_->OnDragEnter(); | 166 delegate_->OnDragEnter(); |
| 156 } | 167 } |
| 157 | 168 |
| 158 dropData_.swap(dropData); | 169 dropData_.swap(dropData); |
| 159 | 170 |
| 160 // Create the appropriate mouse locations for WebCore. The draggingLocation | 171 currentRWHForDrag_->DragTargetDragEnter( |
| 161 // is in window coordinates. Both need to be flipped. | 172 *dropData_, transformedPt, gfx::Point(screenPoint.x, screenPoint.y), |
| 162 NSPoint windowPoint = [info draggingLocation]; | 173 static_cast<WebDragOperationsMask>(mask), GetModifierFlags()); |
| 163 NSPoint viewPoint = [self flipWindowPointToView:windowPoint view:view]; | |
| 164 NSPoint screenPoint = [self flipWindowPointToScreen:windowPoint view:view]; | |
| 165 // TODO(paulmeyer): This will need to target the correct specific | |
| 166 // RenderWidgetHost to work with OOPIFs. See crbug.com/647249. | |
| 167 webContents_->GetRenderViewHost()->GetWidget()->DragTargetDragEnter( | |
| 168 *dropData_, | |
| 169 gfx::Point(viewPoint.x, viewPoint.y), | |
| 170 gfx::Point(screenPoint.x, screenPoint.y), | |
| 171 static_cast<WebDragOperationsMask>(mask), | |
| 172 GetModifierFlags()); | |
| 173 | 174 |
| 174 // We won't know the true operation (whether the drag is allowed) until we | 175 // We won't know the true operation (whether the drag is allowed) until we |
| 175 // hear back from the renderer. For now, be optimistic: | 176 // hear back from the renderer. For now, be optimistic: |
| 176 currentOperation_ = NSDragOperationCopy; | 177 currentOperation_ = NSDragOperationCopy; |
| 177 return currentOperation_; | 178 return currentOperation_; |
| 178 } | 179 } |
| 179 | 180 |
| 180 - (void)draggingExited:(id<NSDraggingInfo>)info { | 181 - (void)draggingExited:(id<NSDraggingInfo>)info { |
| 181 DCHECK(currentRVH_); | 182 DCHECK(currentRVH_); |
| 182 if (currentRVH_ != webContents_->GetRenderViewHost()) | 183 if (currentRVH_ != webContents_->GetRenderViewHost()) |
| 183 return; | 184 return; |
| 184 | 185 |
| 185 if (canceled_) | 186 if (canceled_) |
| 186 return; | 187 return; |
| 187 | 188 |
| 188 if ([self onlyAllowsNavigation]) | 189 if ([self onlyAllowsNavigation]) |
| 189 return; | 190 return; |
| 190 | 191 |
| 191 if (delegate_) | 192 if (delegate_) |
| 192 delegate_->OnDragLeave(); | 193 delegate_->OnDragLeave(); |
| 193 | 194 |
| 194 // TODO(paulmeyer): This will need to target the correct specific | 195 if (currentRWHForDrag_) { |
| 195 // RenderWidgetHost to work with OOPIFs. See crbug.com/647249. | 196 currentRWHForDrag_->DragTargetDragLeave(); |
| 196 webContents_->GetRenderViewHost()->GetWidget()->DragTargetDragLeave(); | 197 currentRWHForDrag_.reset(); |
| 198 } | |
| 197 dropData_.reset(); | 199 dropData_.reset(); |
| 198 } | 200 } |
| 199 | 201 |
| 200 - (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)info | 202 - (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)info |
| 201 view:(NSView*)view { | 203 view:(NSView*)view { |
| 202 DCHECK(currentRVH_); | 204 // Create the appropriate mouse locations for WebCore. The draggingLocation |
| 203 if (currentRVH_ != webContents_->GetRenderViewHost()) | 205 // is in window coordinates. Both need to be flipped. |
| 206 NSPoint windowPoint = [info draggingLocation]; | |
| 207 NSPoint viewPoint = [self flipWindowPointToView:windowPoint view:view]; | |
| 208 NSPoint screenPoint = [self flipWindowPointToScreen:windowPoint view:view]; | |
| 209 gfx::Point transformedPt; | |
| 210 content::RenderWidgetHostImpl* targetRWH = | |
| 211 [self GetRenderWidgetHostAtPoint:viewPoint transformedPt:&transformedPt]; | |
| 212 | |
| 213 if (targetRWH != currentRWHForDrag_.get()) { | |
| 214 if (currentRWHForDrag_) | |
| 215 currentRWHForDrag_->DragTargetDragLeave(); | |
| 204 [self draggingEntered:info view:view]; | 216 [self draggingEntered:info view:view]; |
|
dcheng
2016/11/17 19:59:02
The various delegates for dragging can now be invo
paulmeyer
2016/11/17 20:46:43
Added TODO.
| |
| 217 } | |
| 205 | 218 |
| 206 if (canceled_) | 219 if (canceled_) |
| 207 return NSDragOperationNone; | 220 return NSDragOperationNone; |
| 208 | 221 |
| 209 if ([self onlyAllowsNavigation]) { | 222 if ([self onlyAllowsNavigation]) { |
| 210 if ([[info draggingPasteboard] containsURLDataConvertingTextToURL:YES]) | 223 if ([[info draggingPasteboard] containsURLDataConvertingTextToURL:YES]) |
| 211 return NSDragOperationCopy; | 224 return NSDragOperationCopy; |
| 212 return NSDragOperationNone; | 225 return NSDragOperationNone; |
| 213 } | 226 } |
| 214 | 227 |
| 215 // Create the appropriate mouse locations for WebCore. The draggingLocation | |
| 216 // is in window coordinates. | |
| 217 NSPoint windowPoint = [info draggingLocation]; | |
| 218 NSPoint viewPoint = [self flipWindowPointToView:windowPoint view:view]; | |
| 219 NSPoint screenPoint = [self flipWindowPointToScreen:windowPoint view:view]; | |
| 220 NSDragOperation mask = [info draggingSourceOperationMask]; | 228 NSDragOperation mask = [info draggingSourceOperationMask]; |
| 221 // TODO(paulmeyer): This will need to target the correct specific | 229 targetRWH->DragTargetDragOver( |
| 222 // RenderWidgetHost to work with OOPIFs. See crbug.com/647249. | 230 transformedPt, gfx::Point(screenPoint.x, screenPoint.y), |
| 223 webContents_->GetRenderViewHost()->GetWidget()->DragTargetDragOver( | 231 static_cast<WebDragOperationsMask>(mask), GetModifierFlags()); |
| 224 gfx::Point(viewPoint.x, viewPoint.y), | |
| 225 gfx::Point(screenPoint.x, screenPoint.y), | |
| 226 static_cast<WebDragOperationsMask>(mask), | |
| 227 GetModifierFlags()); | |
| 228 | 232 |
| 229 if (delegate_) | 233 if (delegate_) |
| 230 delegate_->OnDragOver(); | 234 delegate_->OnDragOver(); |
| 231 | 235 |
| 232 return currentOperation_; | 236 return currentOperation_; |
| 233 } | 237 } |
| 234 | 238 |
| 235 - (BOOL)performDragOperation:(id<NSDraggingInfo>)info | 239 - (BOOL)performDragOperation:(id<NSDraggingInfo>)info |
| 236 view:(NSView*)view { | 240 view:(NSView*)view { |
| 237 if (currentRVH_ != webContents_->GetRenderViewHost()) | 241 // Create the appropriate mouse locations for WebCore. The draggingLocation |
| 242 // is in window coordinates. Both need to be flipped. | |
| 243 NSPoint windowPoint = [info draggingLocation]; | |
| 244 NSPoint viewPoint = [self flipWindowPointToView:windowPoint view:view]; | |
| 245 NSPoint screenPoint = [self flipWindowPointToScreen:windowPoint view:view]; | |
| 246 gfx::Point transformedPt; | |
| 247 content::RenderWidgetHostImpl* targetRWH = | |
| 248 [self GetRenderWidgetHostAtPoint:viewPoint transformedPt:&transformedPt]; | |
| 249 | |
| 250 if (targetRWH != currentRWHForDrag_.get()) { | |
| 251 if (currentRWHForDrag_) | |
| 252 currentRWHForDrag_->DragTargetDragLeave(); | |
| 238 [self draggingEntered:info view:view]; | 253 [self draggingEntered:info view:view]; |
| 254 } | |
| 239 | 255 |
| 240 // Check if we only allow navigation and navigate to a url on the pasteboard. | 256 // Check if we only allow navigation and navigate to a url on the pasteboard. |
| 241 if ([self onlyAllowsNavigation]) { | 257 if ([self onlyAllowsNavigation]) { |
| 242 NSPasteboard* pboard = [info draggingPasteboard]; | 258 NSPasteboard* pboard = [info draggingPasteboard]; |
| 243 if ([pboard containsURLDataConvertingTextToURL:YES]) { | 259 if ([pboard containsURLDataConvertingTextToURL:YES]) { |
| 244 GURL url; | 260 GURL url; |
| 245 ui::PopulateURLAndTitleFromPasteboard(&url, NULL, pboard, YES); | 261 ui::PopulateURLAndTitleFromPasteboard(&url, NULL, pboard, YES); |
| 246 webContents_->OpenURL( | 262 webContents_->OpenURL( |
| 247 OpenURLParams(url, Referrer(), WindowOpenDisposition::CURRENT_TAB, | 263 OpenURLParams(url, Referrer(), WindowOpenDisposition::CURRENT_TAB, |
| 248 ui::PAGE_TRANSITION_AUTO_BOOKMARK, false)); | 264 ui::PAGE_TRANSITION_AUTO_BOOKMARK, false)); |
| 249 return YES; | 265 return YES; |
| 250 } else { | 266 } else { |
| 251 return NO; | 267 return NO; |
| 252 } | 268 } |
| 253 } | 269 } |
| 254 | 270 |
| 255 if (delegate_) | 271 if (delegate_) |
| 256 delegate_->OnDrop(); | 272 delegate_->OnDrop(); |
| 257 | 273 |
| 258 currentRVH_ = NULL; | 274 currentRVH_ = NULL; |
| 259 | 275 |
| 260 // Create the appropriate mouse locations for WebCore. The draggingLocation | 276 targetRWH->DragTargetDrop(*dropData_, transformedPt, |
| 261 // is in window coordinates. Both need to be flipped. | 277 gfx::Point(screenPoint.x, screenPoint.y), |
| 262 NSPoint windowPoint = [info draggingLocation]; | 278 GetModifierFlags()); |
| 263 NSPoint viewPoint = [self flipWindowPointToView:windowPoint view:view]; | |
| 264 NSPoint screenPoint = [self flipWindowPointToScreen:windowPoint view:view]; | |
| 265 // TODO(paulmeyer): This will need to target the correct specific | |
| 266 // RenderWidgetHost to work with OOPIFs. See crbug.com/647249. | |
| 267 webContents_->GetRenderViewHost()->GetWidget()->DragTargetDrop( | |
| 268 *dropData_, gfx::Point(viewPoint.x, viewPoint.y), | |
| 269 gfx::Point(screenPoint.x, screenPoint.y), GetModifierFlags()); | |
| 270 | 279 |
| 271 dropData_.reset(); | 280 dropData_.reset(); |
| 272 | 281 |
| 273 return YES; | 282 return YES; |
| 274 } | 283 } |
| 275 | 284 |
| 285 - (content::RenderWidgetHostImpl*) | |
| 286 GetRenderWidgetHostAtPoint:(const NSPoint&)viewPoint | |
| 287 transformedPt:(gfx::Point*)transformedPt { | |
| 288 return webContents_->GetInputEventRouter()->GetRenderWidgetHostAtPoint( | |
| 289 webContents_->GetRenderViewHost()->GetWidget()->GetView(), | |
| 290 gfx::Point(viewPoint.x, viewPoint.y), transformedPt); | |
| 291 } | |
| 292 | |
| 276 // Given |data|, which should not be nil, fill it in using the contents of the | 293 // Given |data|, which should not be nil, fill it in using the contents of the |
| 277 // given pasteboard. The types handled by this method should be kept in sync | 294 // given pasteboard. The types handled by this method should be kept in sync |
| 278 // with [WebContentsViewCocoa registerDragTypes]. | 295 // with [WebContentsViewCocoa registerDragTypes]. |
| 279 - (void)populateDropData:(DropData*)data | 296 - (void)populateDropData:(DropData*)data |
| 280 fromPasteboard:(NSPasteboard*)pboard { | 297 fromPasteboard:(NSPasteboard*)pboard { |
| 281 DCHECK(data); | 298 DCHECK(data); |
| 282 DCHECK(pboard); | 299 DCHECK(pboard); |
| 283 NSArray* types = [pboard types]; | 300 NSArray* types = [pboard types]; |
| 284 | 301 |
| 285 data->did_originate_from_renderer = | 302 data->did_originate_from_renderer = |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 333 // Get custom MIME data. | 350 // Get custom MIME data. |
| 334 if ([types containsObject:ui::kWebCustomDataPboardType]) { | 351 if ([types containsObject:ui::kWebCustomDataPboardType]) { |
| 335 NSData* customData = [pboard dataForType:ui::kWebCustomDataPboardType]; | 352 NSData* customData = [pboard dataForType:ui::kWebCustomDataPboardType]; |
| 336 ui::ReadCustomDataIntoMap([customData bytes], | 353 ui::ReadCustomDataIntoMap([customData bytes], |
| 337 [customData length], | 354 [customData length], |
| 338 &data->custom_data); | 355 &data->custom_data); |
| 339 } | 356 } |
| 340 } | 357 } |
| 341 | 358 |
| 342 @end | 359 @end |
| OLD | NEW |