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" |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 118 | 120 |
| 119 // Messages to send during the tracking of a drag, usually upon receiving | 121 // Messages to send during the tracking of a drag, usually upon receiving |
| 120 // calls from the view system. Communicates the drag messages to WebCore. | 122 // calls from the view system. Communicates the drag messages to WebCore. |
| 121 | 123 |
| 122 - (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)info | 124 - (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)info |
| 123 view:(NSView*)view { | 125 view:(NSView*)view { |
| 124 // Save off the RVH so we can tell if it changes during a drag. If it does, | 126 // 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:. | 127 // we need to send a new enter message in draggingUpdated:. |
| 126 currentRVH_ = webContents_->GetRenderViewHost(); | 128 currentRVH_ = webContents_->GetRenderViewHost(); |
| 127 | 129 |
| 130 // Create the appropriate mouse locations for WebCore. The draggingLocation | |
| 131 // is in window coordinates. Both need to be flipped. | |
| 132 NSPoint windowPoint = [info draggingLocation]; | |
| 133 NSPoint viewPoint = [self flipWindowPointToView:windowPoint view:view]; | |
| 134 NSPoint screenPoint = [self flipWindowPointToScreen:windowPoint view:view]; | |
| 135 gfx::Point transformedPt; | |
| 136 currentRWHForDrag_ = | |
| 137 webContents_->GetInputEventRouter() | |
| 138 ->GetRenderWidgetHostAtPoint( | |
| 139 webContents_->GetRenderViewHost()->GetWidget()->GetView(), | |
| 140 gfx::Point(viewPoint.x, viewPoint.y), &transformedPt) | |
| 141 ->GetWeakPtr(); | |
| 142 | |
| 128 // Fill out a DropData from pasteboard. | 143 // Fill out a DropData from pasteboard. |
| 129 std::unique_ptr<DropData> dropData; | 144 std::unique_ptr<DropData> dropData; |
| 130 dropData.reset(new DropData()); | 145 dropData.reset(new DropData()); |
| 131 [self populateDropData:dropData.get() | 146 [self populateDropData:dropData.get() |
| 132 fromPasteboard:[info draggingPasteboard]]; | 147 fromPasteboard:[info draggingPasteboard]]; |
| 133 // TODO(paulmeyer): This will need to target the correct specific | 148 currentRWHForDrag_->FilterDropData(dropData.get()); |
|
dcheng
2016/11/17 17:44:19
This filters URLs from the drag, and the filtering
| |
| 134 // RenderWidgetHost to work with OOPIFs. See crbug.com/647249. | |
| 135 currentRVH_->GetWidget()->FilterDropData(dropData.get()); | |
| 136 | 149 |
| 137 NSDragOperation mask = [info draggingSourceOperationMask]; | 150 NSDragOperation mask = [info draggingSourceOperationMask]; |
| 138 | 151 |
| 139 // Give the delegate an opportunity to cancel the drag. | 152 // Give the delegate an opportunity to cancel the drag. |
| 140 canceled_ = !webContents_->GetDelegate()->CanDragEnter( | 153 canceled_ = !webContents_->GetDelegate()->CanDragEnter( |
| 141 webContents_, | 154 webContents_, |
| 142 *dropData, | 155 *dropData, |
| 143 static_cast<WebDragOperationsMask>(mask)); | 156 static_cast<WebDragOperationsMask>(mask)); |
| 144 if (canceled_) | 157 if (canceled_) |
| 145 return NSDragOperationNone; | 158 return NSDragOperationNone; |
| 146 | 159 |
| 147 if ([self onlyAllowsNavigation]) { | 160 if ([self onlyAllowsNavigation]) { |
| 148 if ([[info draggingPasteboard] containsURLDataConvertingTextToURL:YES]) | 161 if ([[info draggingPasteboard] containsURLDataConvertingTextToURL:YES]) |
| 149 return NSDragOperationCopy; | 162 return NSDragOperationCopy; |
| 150 return NSDragOperationNone; | 163 return NSDragOperationNone; |
| 151 } | 164 } |
| 152 | 165 |
| 153 if (delegate_) { | 166 if (delegate_) { |
| 154 delegate_->DragInitialize(webContents_); | 167 delegate_->DragInitialize(webContents_); |
| 155 delegate_->OnDragEnter(); | 168 delegate_->OnDragEnter(); |
| 156 } | 169 } |
| 157 | 170 |
| 158 dropData_.swap(dropData); | 171 dropData_.swap(dropData); |
| 159 | 172 |
| 160 // Create the appropriate mouse locations for WebCore. The draggingLocation | 173 currentRWHForDrag_->DragTargetDragEnter( |
| 161 // is in window coordinates. Both need to be flipped. | 174 *dropData_, transformedPt, gfx::Point(screenPoint.x, screenPoint.y), |
| 162 NSPoint windowPoint = [info draggingLocation]; | 175 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 | 176 |
| 174 // We won't know the true operation (whether the drag is allowed) until we | 177 // We won't know the true operation (whether the drag is allowed) until we |
| 175 // hear back from the renderer. For now, be optimistic: | 178 // hear back from the renderer. For now, be optimistic: |
| 176 currentOperation_ = NSDragOperationCopy; | 179 currentOperation_ = NSDragOperationCopy; |
| 177 return currentOperation_; | 180 return currentOperation_; |
| 178 } | 181 } |
| 179 | 182 |
| 180 - (void)draggingExited:(id<NSDraggingInfo>)info { | 183 - (void)draggingExited:(id<NSDraggingInfo>)info { |
| 181 DCHECK(currentRVH_); | 184 DCHECK(currentRVH_); |
| 182 if (currentRVH_ != webContents_->GetRenderViewHost()) | 185 if (currentRVH_ != webContents_->GetRenderViewHost()) |
| 183 return; | 186 return; |
| 184 | 187 |
| 185 if (canceled_) | 188 if (canceled_) |
| 186 return; | 189 return; |
| 187 | 190 |
| 188 if ([self onlyAllowsNavigation]) | 191 if ([self onlyAllowsNavigation]) |
| 189 return; | 192 return; |
| 190 | 193 |
| 191 if (delegate_) | 194 if (delegate_) |
| 192 delegate_->OnDragLeave(); | 195 delegate_->OnDragLeave(); |
| 193 | 196 |
| 194 // TODO(paulmeyer): This will need to target the correct specific | 197 if (currentRWHForDrag_) { |
| 195 // RenderWidgetHost to work with OOPIFs. See crbug.com/647249. | 198 currentRWHForDrag_->DragTargetDragLeave(); |
| 196 webContents_->GetRenderViewHost()->GetWidget()->DragTargetDragLeave(); | 199 currentRWHForDrag_.reset(); |
| 200 } | |
| 197 dropData_.reset(); | 201 dropData_.reset(); |
| 198 } | 202 } |
| 199 | 203 |
| 200 - (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)info | 204 - (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)info |
| 201 view:(NSView*)view { | 205 view:(NSView*)view { |
| 202 DCHECK(currentRVH_); | 206 NSPoint windowPoint = [info draggingLocation]; |
| 203 if (currentRVH_ != webContents_->GetRenderViewHost()) | 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 webContents_->GetInputEventRouter()->GetRenderWidgetHostAtPoint( | |
| 212 webContents_->GetRenderViewHost()->GetWidget()->GetView(), | |
| 213 gfx::Point(viewPoint.x, viewPoint.y), &transformedPt); | |
|
dcheng
2016/11/17 17:44:19
This block feels like it should be a helper.
If t
| |
| 214 | |
| 215 if (targetRWH != currentRWHForDrag_.get()) { | |
| 216 if (currentRWHForDrag_) | |
| 217 currentRWHForDrag_->DragTargetDragLeave(); | |
| 204 [self draggingEntered:info view:view]; | 218 [self draggingEntered:info view:view]; |
| 219 } | |
| 205 | 220 |
| 206 if (canceled_) | 221 if (canceled_) |
| 207 return NSDragOperationNone; | 222 return NSDragOperationNone; |
| 208 | 223 |
| 209 if ([self onlyAllowsNavigation]) { | 224 if ([self onlyAllowsNavigation]) { |
| 210 if ([[info draggingPasteboard] containsURLDataConvertingTextToURL:YES]) | 225 if ([[info draggingPasteboard] containsURLDataConvertingTextToURL:YES]) |
| 211 return NSDragOperationCopy; | 226 return NSDragOperationCopy; |
| 212 return NSDragOperationNone; | 227 return NSDragOperationNone; |
| 213 } | 228 } |
| 214 | 229 |
| 215 // Create the appropriate mouse locations for WebCore. The draggingLocation | 230 // Create the appropriate mouse locations for WebCore. The draggingLocation |
| 216 // is in window coordinates. | 231 // 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]; | 232 NSDragOperation mask = [info draggingSourceOperationMask]; |
| 221 // TODO(paulmeyer): This will need to target the correct specific | 233 targetRWH->DragTargetDragOver( |
| 222 // RenderWidgetHost to work with OOPIFs. See crbug.com/647249. | 234 transformedPt, gfx::Point(screenPoint.x, screenPoint.y), |
| 223 webContents_->GetRenderViewHost()->GetWidget()->DragTargetDragOver( | 235 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 | 236 |
| 229 if (delegate_) | 237 if (delegate_) |
| 230 delegate_->OnDragOver(); | 238 delegate_->OnDragOver(); |
| 231 | 239 |
| 232 return currentOperation_; | 240 return currentOperation_; |
| 233 } | 241 } |
| 234 | 242 |
| 235 - (BOOL)performDragOperation:(id<NSDraggingInfo>)info | 243 - (BOOL)performDragOperation:(id<NSDraggingInfo>)info |
| 236 view:(NSView*)view { | 244 view:(NSView*)view { |
| 237 if (currentRVH_ != webContents_->GetRenderViewHost()) | 245 NSPoint windowPoint = [info draggingLocation]; |
| 246 NSPoint viewPoint = [self flipWindowPointToView:windowPoint view:view]; | |
| 247 NSPoint screenPoint = [self flipWindowPointToScreen:windowPoint view:view]; | |
| 248 gfx::Point transformedPt; | |
| 249 content::RenderWidgetHostImpl* targetRWH = | |
| 250 webContents_->GetInputEventRouter()->GetRenderWidgetHostAtPoint( | |
| 251 webContents_->GetRenderViewHost()->GetWidget()->GetView(), | |
| 252 gfx::Point(viewPoint.x, viewPoint.y), &transformedPt); | |
|
Avi (use Gerrit)
2016/11/17 02:50:28
You do this three times; can you abstract it out?
paulmeyer
2016/11/17 16:01:52
Done.
paulmeyer
2016/11/17 17:32:11
Actually, I'd like to do this abstraction in a fol
dcheng
2016/11/17 17:44:19
We should abstract it out: as-is, this logic doesn
| |
| 253 | |
| 254 if (targetRWH != currentRWHForDrag_.get()) { | |
| 255 if (currentRWHForDrag_) | |
| 256 currentRWHForDrag_->DragTargetDragLeave(); | |
| 238 [self draggingEntered:info view:view]; | 257 [self draggingEntered:info view:view]; |
| 258 } | |
| 239 | 259 |
| 240 // Check if we only allow navigation and navigate to a url on the pasteboard. | 260 // Check if we only allow navigation and navigate to a url on the pasteboard. |
| 241 if ([self onlyAllowsNavigation]) { | 261 if ([self onlyAllowsNavigation]) { |
| 242 NSPasteboard* pboard = [info draggingPasteboard]; | 262 NSPasteboard* pboard = [info draggingPasteboard]; |
| 243 if ([pboard containsURLDataConvertingTextToURL:YES]) { | 263 if ([pboard containsURLDataConvertingTextToURL:YES]) { |
| 244 GURL url; | 264 GURL url; |
| 245 ui::PopulateURLAndTitleFromPasteboard(&url, NULL, pboard, YES); | 265 ui::PopulateURLAndTitleFromPasteboard(&url, NULL, pboard, YES); |
| 246 webContents_->OpenURL( | 266 webContents_->OpenURL( |
| 247 OpenURLParams(url, Referrer(), WindowOpenDisposition::CURRENT_TAB, | 267 OpenURLParams(url, Referrer(), WindowOpenDisposition::CURRENT_TAB, |
| 248 ui::PAGE_TRANSITION_AUTO_BOOKMARK, false)); | 268 ui::PAGE_TRANSITION_AUTO_BOOKMARK, false)); |
| 249 return YES; | 269 return YES; |
| 250 } else { | 270 } else { |
| 251 return NO; | 271 return NO; |
| 252 } | 272 } |
| 253 } | 273 } |
| 254 | 274 |
| 255 if (delegate_) | 275 if (delegate_) |
| 256 delegate_->OnDrop(); | 276 delegate_->OnDrop(); |
| 257 | 277 |
| 258 currentRVH_ = NULL; | 278 currentRVH_ = NULL; |
| 259 | 279 |
| 260 // Create the appropriate mouse locations for WebCore. The draggingLocation | 280 targetRWH->DragTargetDrop(*dropData_, transformedPt, |
| 261 // is in window coordinates. Both need to be flipped. | 281 gfx::Point(screenPoint.x, screenPoint.y), |
| 262 NSPoint windowPoint = [info draggingLocation]; | 282 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 | 283 |
| 271 dropData_.reset(); | 284 dropData_.reset(); |
| 272 | 285 |
| 273 return YES; | 286 return YES; |
| 274 } | 287 } |
| 275 | 288 |
| 276 // Given |data|, which should not be nil, fill it in using the contents of the | 289 // 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 | 290 // given pasteboard. The types handled by this method should be kept in sync |
| 278 // with [WebContentsViewCocoa registerDragTypes]. | 291 // with [WebContentsViewCocoa registerDragTypes]. |
| 279 - (void)populateDropData:(DropData*)data | 292 - (void)populateDropData:(DropData*)data |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 333 // Get custom MIME data. | 346 // Get custom MIME data. |
| 334 if ([types containsObject:ui::kWebCustomDataPboardType]) { | 347 if ([types containsObject:ui::kWebCustomDataPboardType]) { |
| 335 NSData* customData = [pboard dataForType:ui::kWebCustomDataPboardType]; | 348 NSData* customData = [pboard dataForType:ui::kWebCustomDataPboardType]; |
| 336 ui::ReadCustomDataIntoMap([customData bytes], | 349 ui::ReadCustomDataIntoMap([customData bytes], |
| 337 [customData length], | 350 [customData length], |
| 338 &data->custom_data); | 351 &data->custom_data); |
| 339 } | 352 } |
| 340 } | 353 } |
| 341 | 354 |
| 342 @end | 355 @end |
| OLD | NEW |