diff options
41 files changed, 518 insertions, 222 deletions
diff --git a/chrome/browser/cocoa/web_drag_source.h b/chrome/browser/cocoa/web_drag_source.h index 6532878..fdeb63f 100644 --- a/chrome/browser/cocoa/web_drag_source.h +++ b/chrome/browser/cocoa/web_drag_source.h @@ -22,6 +22,9 @@ struct WebDropData; // Our pasteboard. scoped_nsobject<NSPasteboard> pasteboard_; + + // A mask of the allowed drag operations. + NSDragOperation dragOperationMask_; } // Initialize a WebDragSource object for a drag (originating on the given @@ -29,7 +32,11 @@ struct WebDropData; // with data types appropriate for dropData. - (id)initWithContentsView:(TabContentsViewCocoa*)contentsView dropData:(const WebDropData*)dropData - pasteboard:(NSPasteboard*)pboard; + pasteboard:(NSPasteboard*)pboard + dragOperationMask:(NSDragOperation)dragOperationMask; + +// Returns a mask of the allowed drag operations. +- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal; // Call when asked to do a lazy write to the pasteboard; hook up to // -pasteboard:provideDataForType: (on the contentsView). @@ -43,7 +50,7 @@ struct WebDropData; // End the drag and clear the pasteboard; hook up to // -draggedImage:endedAt:operation:. - (void)endDragAt:(NSPoint)screenPoint - isCancelled:(BOOL)cancelled; + operation:(NSDragOperation)operation; // Drag moved; hook up to -draggedImage:movedTo:. - (void)moveDragTo:(NSPoint)screenPoint; diff --git a/chrome/browser/cocoa/web_drag_source.mm b/chrome/browser/cocoa/web_drag_source.mm index 3e66832..a426604 100644 --- a/chrome/browser/cocoa/web_drag_source.mm +++ b/chrome/browser/cocoa/web_drag_source.mm @@ -122,7 +122,8 @@ void PromiseWriterTask::Run() { - (id)initWithContentsView:(TabContentsViewCocoa*)contentsView dropData:(const WebDropData*)dropData - pasteboard:(NSPasteboard*)pboard { + pasteboard:(NSPasteboard*)pboard + dragOperationMask:(NSDragOperation)dragOperationMask { if ((self = [super init])) { contentsView_ = contentsView; DCHECK(contentsView_); @@ -133,12 +134,18 @@ void PromiseWriterTask::Run() { pasteboard_.reset([pboard retain]); DCHECK(pasteboard_.get()); + dragOperationMask_ = dragOperationMask; + [self fillPasteboard]; } return self; } +- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal { + return dragOperationMask_; +} + - (void)lazyWriteToPasteboard:(NSPasteboard*)pboard forType:(NSString*)type { // Be extra paranoid; avoid crashing. if (!dropData_.get()) { @@ -226,7 +233,7 @@ void PromiseWriterTask::Run() { } - (void)endDragAt:(NSPoint)screenPoint - isCancelled:(BOOL)cancelled { + operation:(NSDragOperation)operation { RenderViewHost* rvh = [contentsView_ tabContents]->render_view_host(); if (rvh) { rvh->DragSourceSystemDragEnded(); @@ -239,13 +246,9 @@ void PromiseWriterTask::Run() { NSRect screenFrame = [[[contentsView_ window] screen] frame]; screenPoint.y = screenFrame.size.height - screenPoint.y; - if (cancelled) { - rvh->DragSourceCancelledAt(localPoint.x, localPoint.y, - screenPoint.x, screenPoint.y); - } else { - rvh->DragSourceEndedAt(localPoint.x, localPoint.y, - screenPoint.x, screenPoint.y); - } + rvh->DragSourceEndedAt(localPoint.x, localPoint.y, + screenPoint.x, screenPoint.y, + static_cast<WebKit::WebDragOperation>(operation)); } // Make sure the pasteboard owner isn't us. diff --git a/chrome/browser/cocoa/web_drop_target.h b/chrome/browser/cocoa/web_drop_target.h index 8e91398..430a089 100644 --- a/chrome/browser/cocoa/web_drop_target.h +++ b/chrome/browser/cocoa/web_drop_target.h @@ -22,7 +22,7 @@ typedef RenderViewHost* RenderViewHostIdentifier; // Updated asynchronously during a drag to tell us whether or not we should // allow the drop. - BOOL isDropTarget_; + NSDragOperation current_operation_; // Keep track of the render view host we're dragging over. If it changes // during a drag, we need to re-send the DragEnter message. @@ -34,9 +34,10 @@ typedef RenderViewHost* RenderViewHostIdentifier; // (if necessary). - (id)initWithTabContents:(TabContents*)contents; -// Call to set whether or not we should allow the drop. Takes effect the +// Sets the current operation negotiated by the source and destination, +// which determines whether or not we should allow the drop. Takes effect the // next time |-draggingUpdated:| is called. -- (void)setIsDropTarget:(BOOL)isDropTarget; +- (void)setCurrentOperation: (NSDragOperation)operation; // Messages to send during the tracking of a drag, ususally upon receiving // calls from the view system. Communicates the drag messages to WebCore. diff --git a/chrome/browser/cocoa/web_drop_target.mm b/chrome/browser/cocoa/web_drop_target.mm index 8d450a6..b797671 100644 --- a/chrome/browser/cocoa/web_drop_target.mm +++ b/chrome/browser/cocoa/web_drop_target.mm @@ -11,6 +11,8 @@ #include "webkit/glue/webdropdata.h" #include "webkit/glue/window_open_disposition.h" +using WebKit::WebDragOperationsMask; + @implementation WebDropTarget // |contents| is the TabContents representing this tab, used to communicate @@ -25,8 +27,8 @@ // Call to set whether or not we should allow the drop. Takes effect the // next time |-draggingUpdated:| is called. -- (void)setIsDropTarget:(BOOL)isDropTarget { - isDropTarget_ = isDropTarget; +- (void)setCurrentOperation: (NSDragOperation)operation { + current_operation_ = operation; } // Given a point in window coordinates and a view in that window, return a @@ -85,13 +87,16 @@ NSPoint windowPoint = [info draggingLocation]; NSPoint viewPoint = [self flipWindowPointToView:windowPoint view:view]; NSPoint screenPoint = [self flipWindowPointToScreen:windowPoint view:view]; + NSDragOperation mask = [info draggingSourceOperationMask]; tabContents_->render_view_host()->DragTargetDragEnter(data, gfx::Point(viewPoint.x, viewPoint.y), - gfx::Point(screenPoint.x, screenPoint.y)); - - isDropTarget_ = YES; + gfx::Point(screenPoint.x, screenPoint.y), + static_cast<WebDragOperationsMask>(mask)); - return NSDragOperationCopy; + // We won't know the true operation (whether the drag is allowed) until we + // hear back from the renderer. For now, be optimistic: + current_operation_ = NSDragOperationCopy; + return current_operation_; } - (void)draggingExited:(id<NSDraggingInfo>)info { @@ -121,13 +126,13 @@ NSPoint windowPoint = [info draggingLocation]; NSPoint viewPoint = [self flipWindowPointToView:windowPoint view:view]; NSPoint screenPoint = [self flipWindowPointToScreen:windowPoint view:view]; + NSDragOperation mask = [info draggingSourceOperationMask]; tabContents_->render_view_host()->DragTargetDragOver( gfx::Point(viewPoint.x, viewPoint.y), - gfx::Point(screenPoint.x, screenPoint.y)); + gfx::Point(screenPoint.x, screenPoint.y), + static_cast<WebDragOperationsMask>(mask)); - if (!isDropTarget_) - return NSDragOperationNone; - return NSDragOperationCopy; + return current_operation_; } - (BOOL)performDragOperation:(id<NSDraggingInfo>)info diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc index 8690e6a..168e002 100644 --- a/chrome/browser/extensions/extension_host.cc +++ b/chrome/browser/extensions/extension_host.cc @@ -30,6 +30,9 @@ #include "webkit/glue/context_menu.h" +using WebKit::WebDragOperation; +using WebKit::WebDragOperationsMask; + // static bool ExtensionHost::enable_dom_automation_ = false; @@ -275,10 +278,11 @@ void ExtensionHost::ShowContextMenu(const ContextMenuParams& params) { DevToolsManager::GetInstance()->OpenDevToolsWindow(render_view_host()); } -void ExtensionHost::StartDragging(const WebDropData& drop_data) { +void ExtensionHost::StartDragging(const WebDropData& drop_data, + WebDragOperationsMask operation_mask) { } -void ExtensionHost::UpdateDragCursor(bool is_drop_target) { +void ExtensionHost::UpdateDragCursor(WebDragOperation operation) { } void ExtensionHost::GotFocus() { diff --git a/chrome/browser/extensions/extension_host.h b/chrome/browser/extensions/extension_host.h index 72aa7af..76c1014 100644 --- a/chrome/browser/extensions/extension_host.h +++ b/chrome/browser/extensions/extension_host.h @@ -113,8 +113,9 @@ class ExtensionHost : public RenderViewHostDelegate, virtual void ShowCreatedWidget(int route_id, const gfx::Rect& initial_pos); virtual void ShowContextMenu(const ContextMenuParams& params); - virtual void StartDragging(const WebDropData& drop_data); - virtual void UpdateDragCursor(bool is_drop_target); + virtual void StartDragging(const WebDropData& drop_data, + WebKit::WebDragOperationsMask allowed_operations); + virtual void UpdateDragCursor(WebKit::WebDragOperation operation); virtual void GotFocus(); virtual void TakeFocus(bool reverse); virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event); diff --git a/chrome/browser/gtk/tab_contents_drag_source.cc b/chrome/browser/gtk/tab_contents_drag_source.cc index 780c6ca..146cbd7 100644 --- a/chrome/browser/gtk/tab_contents_drag_source.cc +++ b/chrome/browser/gtk/tab_contents_drag_source.cc @@ -12,6 +12,9 @@ #include "chrome/common/gtk_util.h" #include "webkit/glue/webdropdata.h" +using WebKit::WebDragOperation; +using WebKit::WebDragOperationNone; + TabContentsDragSource::TabContentsDragSource( TabContentsView* tab_contents_view) : tab_contents_view_(tab_contents_view), @@ -170,15 +173,16 @@ gboolean TabContentsDragSource::OnDragFailed() { gfx::Point client = gtk_util::ClientPoint(GetContentNativeView()); if (tab_contents()->render_view_host()) { - tab_contents()->render_view_host()->DragSourceCancelledAt( - client.x(), client.y(), root.x(), root.y()); + tab_contents()->render_view_host()->DragSourceEndedAt( + client.x(), client.y(), root.x(), root.y(), + WebDragOperationNone); } // Let the native failure animation run. return FALSE; } -void TabContentsDragSource::OnDragEnd() { +void TabContentsDragSource::OnDragEnd(WebDragOperation operation) { MessageLoopForUI::current()->RemoveObserver(this); if (!drag_failed_) { @@ -187,7 +191,7 @@ void TabContentsDragSource::OnDragEnd() { if (tab_contents()->render_view_host()) { tab_contents()->render_view_host()->DragSourceEndedAt( - client.x(), client.y(), root.x(), root.y()); + client.x(), client.y(), root.x(), root.y(), operation); } } diff --git a/chrome/browser/gtk/tab_contents_drag_source.h b/chrome/browser/gtk/tab_contents_drag_source.h index 1d35669..1df7df8 100644 --- a/chrome/browser/gtk/tab_contents_drag_source.h +++ b/chrome/browser/gtk/tab_contents_drag_source.h @@ -10,6 +10,7 @@ #include "base/basictypes.h" #include "base/gfx/native_widget_types.h" #include "base/message_loop.h" +#include "webkit/api/public/WebDragOperation.h" class TabContents; class TabContentsView; @@ -44,9 +45,10 @@ class TabContentsDragSource : public MessageLoopForUI::Observer { static void OnDragEndThunk(GtkWidget* widget, GdkDragContext* drag_context, TabContentsDragSource* handler) { - handler->OnDragEnd(); + handler->OnDragEnd(WebKit::WebDragOperationCopy); + // TODO(snej): Pass actual operation instead of hardcoding copy } - void OnDragEnd(); + void OnDragEnd(WebKit::WebDragOperation operation); static void OnDragDataGetThunk(GtkWidget* drag_widget, GdkDragContext* context, GtkSelectionData* selection_data, diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index ba82b80..066d1cc 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -49,6 +49,9 @@ using base::TimeDelta; using webkit_glue::PasswordFormDomManager; using WebKit::WebConsoleMessage; +using WebKit::WebDragOperation; +using WebKit::WebDragOperationNone; +using WebKit::WebDragOperationsMask; using WebKit::WebFindOptions; using WebKit::WebInputEvent; using WebKit::WebTextDirection; @@ -460,7 +463,8 @@ void RenderViewHost::FillPasswordForm( void RenderViewHost::DragTargetDragEnter( const WebDropData& drop_data, const gfx::Point& client_pt, - const gfx::Point& screen_pt) { + const gfx::Point& screen_pt, + WebDragOperationsMask operations_allowed) { // Grant the renderer the ability to load the drop_data. ChildProcessSecurityPolicy* policy = ChildProcessSecurityPolicy::GetInstance(); @@ -473,12 +477,14 @@ void RenderViewHost::DragTargetDragEnter( policy->GrantUploadFile(process()->id(), path); } Send(new ViewMsg_DragTargetDragEnter(routing_id(), drop_data, client_pt, - screen_pt)); + screen_pt, operations_allowed)); } void RenderViewHost::DragTargetDragOver( - const gfx::Point& client_pt, const gfx::Point& screen_pt) { - Send(new ViewMsg_DragTargetDragOver(routing_id(), client_pt, screen_pt)); + const gfx::Point& client_pt, const gfx::Point& screen_pt, + WebDragOperationsMask operations_allowed) { + Send(new ViewMsg_DragTargetDragOver(routing_id(), client_pt, screen_pt, + operations_allowed)); } void RenderViewHost::DragTargetDragLeave() { @@ -608,22 +614,14 @@ void RenderViewHost::CopyImageAt(int x, int y) { Send(new ViewMsg_CopyImageAt(routing_id(), x, y)); } -void RenderViewHost::DragSourceCancelledAt( - int client_x, int client_y, int screen_x, int screen_y) { - Send(new ViewMsg_DragSourceEndedOrMoved( - routing_id(), - gfx::Point(client_x, client_y), - gfx::Point(screen_x, screen_y), - true, true)); -} - void RenderViewHost::DragSourceEndedAt( - int client_x, int client_y, int screen_x, int screen_y) { + int client_x, int client_y, int screen_x, int screen_y, + WebDragOperation operation) { Send(new ViewMsg_DragSourceEndedOrMoved( routing_id(), gfx::Point(client_x, client_y), gfx::Point(screen_x, screen_y), - true, false)); + true, operation)); } void RenderViewHost::DragSourceMovedTo( @@ -632,7 +630,7 @@ void RenderViewHost::DragSourceMovedTo( routing_id(), gfx::Point(client_x, client_y), gfx::Point(screen_x, screen_y), - false, false)); + false, WebDragOperationNone)); } void RenderViewHost::DragSourceSystemDragEnded() { @@ -1331,16 +1329,17 @@ void RenderViewHost::OnMsgAutofillFormSubmitted( } void RenderViewHost::OnMsgStartDragging( - const WebDropData& drop_data) { + const WebDropData& drop_data, + WebDragOperationsMask drag_operations_mask) { RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); if (view) - view->StartDragging(drop_data); + view->StartDragging(drop_data, drag_operations_mask); } -void RenderViewHost::OnUpdateDragCursor(bool is_drop_target) { +void RenderViewHost::OnUpdateDragCursor(WebDragOperation current_op) { RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); if (view) - view->UpdateDragCursor(is_drop_target); + view->UpdateDragCursor(current_op); } void RenderViewHost::OnTakeFocus(bool reverse) { diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h index f733f7b..81637aa 100644 --- a/chrome/browser/renderer_host/render_view_host.h +++ b/chrome/browser/renderer_host/render_view_host.h @@ -16,6 +16,7 @@ #include "chrome/common/notification_registrar.h" #include "chrome/common/page_zoom.h" #include "webkit/api/public/WebConsoleMessage.h" +#include "webkit/api/public/WebDragOperation.h" #include "webkit/api/public/WebTextDirection.h" #include "webkit/glue/autofill_form.h" #include "webkit/glue/password_form_dom_manager.h" @@ -238,9 +239,11 @@ class RenderViewHost : public RenderWidgetHost, // D&d drop target messages that get sent to WebKit. void DragTargetDragEnter(const WebDropData& drop_data, const gfx::Point& client_pt, - const gfx::Point& screen_pt); + const gfx::Point& screen_pt, + WebKit::WebDragOperationsMask operations_allowed); void DragTargetDragOver(const gfx::Point& client_pt, - const gfx::Point& screen_pt); + const gfx::Point& screen_pt, + WebKit::WebDragOperationsMask operations_allowed); void DragTargetDragLeave(); void DragTargetDrop(const gfx::Point& client_pt, const gfx::Point& screen_pt); @@ -306,15 +309,11 @@ class RenderViewHost : public RenderWidgetHost, // Copies the image at the specified point. void CopyImageAt(int x, int y); - // Notifies the renderer that a drag and drop was cancelled. This is - // necessary because the render may be the one that started the drag. - void DragSourceCancelledAt( - int client_x, int client_y, int screen_x, int screen_y); - - // Notifies the renderer that a drop occurred. This is necessary because the - // render may be the one that started the drag. + // Notifies the renderer that a a drag operation that it started has ended, + // either in a drop or by being cancelled. void DragSourceEndedAt( - int client_x, int client_y, int screen_x, int screen_y); + int client_x, int client_y, int screen_x, int screen_y, + WebKit::WebDragOperation operation); // Notifies the renderer that a drag and drop operation is in progress, with // droppable items positioned over the renderer's view. @@ -526,8 +525,9 @@ class RenderViewHost : public RenderWidgetHost, void OnMsgPasswordFormsSeen( const std::vector<webkit_glue::PasswordForm>& forms); void OnMsgAutofillFormSubmitted(const webkit_glue::AutofillForm& forms); - void OnMsgStartDragging(const WebDropData& drop_data); - void OnUpdateDragCursor(bool is_drop_target); + void OnMsgStartDragging(const WebDropData& drop_data, + WebKit::WebDragOperationsMask operations_allowed); + void OnUpdateDragCursor(WebKit::WebDragOperation drag_operation); void OnTakeFocus(bool reverse); void OnMsgPageHasOSDD(int32 page_id, const GURL& doc_url, bool autodetected); void OnDidGetPrintedPagesCount(int cookie, int number_pages); diff --git a/chrome/browser/renderer_host/render_view_host_delegate.h b/chrome/browser/renderer_host/render_view_host_delegate.h index 6e62289..c1e301c 100644 --- a/chrome/browser/renderer_host/render_view_host_delegate.h +++ b/chrome/browser/renderer_host/render_view_host_delegate.h @@ -12,6 +12,7 @@ #include "base/string16.h" #include "chrome/common/view_types.h" #include "net/base/load_states.h" +#include "webkit/api/public/WebDragOperation.h" #include "webkit/glue/window_open_disposition.h" class AutofillForm; @@ -111,11 +112,12 @@ class RenderViewHostDelegate { // The user started dragging content of the specified type within the // RenderView. Contextual information about the dragged content is supplied // by WebDropData. - virtual void StartDragging(const WebDropData& drop_data) = 0; + virtual void StartDragging(const WebDropData& drop_data, + WebKit::WebDragOperationsMask allowed_ops) = 0; // The page wants to update the mouse cursor during a drag & drop operation. - // |is_drop_target| is true if the mouse is over a valid drop target. - virtual void UpdateDragCursor(bool is_drop_target) = 0; + // |operation| describes the current operation (none, move, copy, link.) + virtual void UpdateDragCursor(WebKit::WebDragOperation operation) = 0; // Notification that view for this delegate got the focus. virtual void GotFocus() = 0; diff --git a/chrome/browser/tab_contents/interstitial_page.cc b/chrome/browser/tab_contents/interstitial_page.cc index f9d6ded..7421c3a 100644 --- a/chrome/browser/tab_contents/interstitial_page.cc +++ b/chrome/browser/tab_contents/interstitial_page.cc @@ -25,6 +25,9 @@ #include "net/base/escape.h" #include "views/window/window_delegate.h" +using WebKit::WebDragOperation; +using WebKit::WebDragOperationsMask; + namespace { class ResourceRequestTask : public Task { @@ -86,8 +89,9 @@ class InterstitialPage::InterstitialPageRVHViewDelegate virtual void ShowCreatedWidget(int route_id, const gfx::Rect& initial_pos); virtual void ShowContextMenu(const ContextMenuParams& params); - virtual void StartDragging(const WebDropData& drop_data); - virtual void UpdateDragCursor(bool is_drop_target); + virtual void StartDragging(const WebDropData& drop_data, + WebDragOperationsMask operations_allowed); + virtual void UpdateDragCursor(WebDragOperation operation); virtual void GotFocus(); virtual void TakeFocus(bool reverse); virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event); @@ -549,12 +553,13 @@ void InterstitialPage::InterstitialPageRVHViewDelegate::ShowContextMenu( } void InterstitialPage::InterstitialPageRVHViewDelegate::StartDragging( - const WebDropData& drop_data) { + const WebDropData& drop_data, + WebDragOperationsMask allowed_operations) { NOTREACHED() << "InterstitialPage does not support dragging yet."; } void InterstitialPage::InterstitialPageRVHViewDelegate::UpdateDragCursor( - bool is_drop_target) { + WebDragOperation) { NOTREACHED() << "InterstitialPage does not support dragging yet."; } diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.cc b/chrome/browser/tab_contents/tab_contents_view_gtk.cc index aba3c6e..892b67f 100644 --- a/chrome/browser/tab_contents/tab_contents_view_gtk.cc +++ b/chrome/browser/tab_contents/tab_contents_view_gtk.cc @@ -36,6 +36,11 @@ #include "chrome/common/notification_type.h" #include "webkit/glue/webdropdata.h" +using WebKit::WebDragOperation; +using WebKit::WebDragOperationCopy; +using WebKit::WebDragOperationNone; +using WebKit::WebDragOperationsMask; + namespace { // TODO(erg): I have no idea how to programatically figure out how wide the @@ -139,15 +144,16 @@ class WebDragDest { // This is called when the renderer responds to a drag motion event. We must // update the system drag cursor. - void UpdateDragStatus(bool is_drop_target) { + void UpdateDragStatus(WebDragOperation operation) { if (context_) { // TODO(estade): we might want to support other actions besides copy, // but that would increase the cost of getting our drag success guess // wrong. - gdk_drag_status(context_, is_drop_target ? GDK_ACTION_COPY : + is_drop_target_ = operation != WebDragOperationNone; + // TODO(snej): Pass appropriate GDK action instead of hardcoding COPY + gdk_drag_status(context_, is_drop_target_ ? GDK_ACTION_COPY : static_cast<GdkDragAction>(0), drag_over_time_); - is_drop_target_ = false; } } @@ -203,7 +209,9 @@ class WebDragDest { } else if (data_requests_ == 0) { tab_contents_->render_view_host()-> DragTargetDragOver(gtk_util::ClientPoint(widget_), - gtk_util::ScreenPoint(widget_)); + gtk_util::ScreenPoint(widget_), + WebDragOperationCopy); + // TODO(snej): Pass appropriate DragOperation instead of hardcoding drag_over_time_ = time; } @@ -266,7 +274,9 @@ class WebDragDest { tab_contents_->render_view_host()-> DragTargetDragEnter(*drop_data_.get(), gtk_util::ClientPoint(widget_), - gtk_util::ScreenPoint(widget_)); + gtk_util::ScreenPoint(widget_), + WebDragOperationCopy); + // TODO(snej): Pass appropriate DragOperation instead of hardcoding drag_over_time_ = time; } } @@ -533,8 +543,8 @@ void TabContentsViewGtk::RestoreFocus() { SetInitialFocus(); } -void TabContentsViewGtk::UpdateDragCursor(bool is_drop_target) { - drag_dest_->UpdateDragStatus(is_drop_target); +void TabContentsViewGtk::UpdateDragCursor(WebDragOperation operation) { + drag_dest_->UpdateDragStatus(operation); } void TabContentsViewGtk::GotFocus() { @@ -598,10 +608,12 @@ void TabContentsViewGtk::ShowContextMenu(const ContextMenuParams& params) { // Render view DnD ------------------------------------------------------------- -void TabContentsViewGtk::StartDragging(const WebDropData& drop_data) { +void TabContentsViewGtk::StartDragging(const WebDropData& drop_data, + WebDragOperationsMask ops) { DCHECK(GetContentNativeView()); drag_source_->StartDragging(drop_data, &last_mouse_down_); + // TODO(snej): Make use of the WebDragOperationsMask somehow } // ----------------------------------------------------------------------------- diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.h b/chrome/browser/tab_contents/tab_contents_view_gtk.h index e63e346..8e3fcf6 100644 --- a/chrome/browser/tab_contents/tab_contents_view_gtk.h +++ b/chrome/browser/tab_contents/tab_contents_view_gtk.h @@ -66,8 +66,9 @@ class TabContentsViewGtk : public TabContentsView, // Backend implementation of RenderViewHostDelegate::View. virtual void ShowContextMenu(const ContextMenuParams& params); - virtual void StartDragging(const WebDropData& drop_data); - virtual void UpdateDragCursor(bool is_drop_target); + virtual void StartDragging(const WebDropData& drop_data, + WebKit::WebDragOperationsMask allowed_ops); + virtual void UpdateDragCursor(WebKit::WebDragOperation operation); virtual void GotFocus(); virtual void TakeFocus(bool reverse); virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event); diff --git a/chrome/browser/tab_contents/tab_contents_view_mac.h b/chrome/browser/tab_contents/tab_contents_view_mac.h index a8ccaf6..d140c6c 100644 --- a/chrome/browser/tab_contents/tab_contents_view_mac.h +++ b/chrome/browser/tab_contents/tab_contents_view_mac.h @@ -69,8 +69,9 @@ class TabContentsViewMac : public TabContentsView, // Backend implementation of RenderViewHostDelegate::View. virtual void ShowContextMenu(const ContextMenuParams& params); - virtual void StartDragging(const WebDropData& drop_data); - virtual void UpdateDragCursor(bool is_drop_target); + virtual void StartDragging(const WebDropData& drop_data, + WebKit::WebDragOperationsMask allowed_operations); + virtual void UpdateDragCursor(WebKit::WebDragOperation operation); virtual void GotFocus(); virtual void TakeFocus(bool reverse); virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event); diff --git a/chrome/browser/tab_contents/tab_contents_view_mac.mm b/chrome/browser/tab_contents/tab_contents_view_mac.mm index 73c362c..ac7cded 100644 --- a/chrome/browser/tab_contents/tab_contents_view_mac.mm +++ b/chrome/browser/tab_contents/tab_contents_view_mac.mm @@ -21,12 +21,29 @@ #include "chrome/common/temp_scaffolding_stubs.h" +using WebKit::WebDragOperation; +using WebKit::WebDragOperationsMask; + +// Ensure that the WebKit::WebDragOperation enum values stay in sync with +// NSDragOperation constants, since the code below static_casts between 'em. +#define COMPILE_ASSERT_MATCHING_ENUM(name) \ + COMPILE_ASSERT(int(NS##name) == int(WebKit::Web##name), enum_mismatch_##name) +COMPILE_ASSERT_MATCHING_ENUM(DragOperationNone); +COMPILE_ASSERT_MATCHING_ENUM(DragOperationCopy); +COMPILE_ASSERT_MATCHING_ENUM(DragOperationLink); +COMPILE_ASSERT_MATCHING_ENUM(DragOperationGeneric); +COMPILE_ASSERT_MATCHING_ENUM(DragOperationPrivate); +COMPILE_ASSERT_MATCHING_ENUM(DragOperationMove); +COMPILE_ASSERT_MATCHING_ENUM(DragOperationDelete); +COMPILE_ASSERT_MATCHING_ENUM(DragOperationEvery); + @interface TabContentsViewCocoa (Private) - (id)initWithTabContentsViewMac:(TabContentsViewMac*)w; - (void)processKeyboardEvent:(NSEvent*)event; - (void)registerDragTypes; -- (void)setIsDropTarget:(BOOL)isTarget; -- (void)startDragWithDropData:(const WebDropData&)dropData; +- (void)setCurrentDragOperation:(NSDragOperation)operation; +- (void)startDragWithDropData:(const WebDropData&)dropData + dragOperationMask:(NSDragOperation)operationMask; @end // static @@ -83,11 +100,14 @@ void TabContentsViewMac::GetContainerBounds(gfx::Rect* out) const { *out = [cocoa_view_.get() NSRectToRect:[cocoa_view_.get() bounds]]; } -void TabContentsViewMac::StartDragging(const WebDropData& drop_data) { +void TabContentsViewMac::StartDragging(const WebDropData& drop_data, + WebDragOperationsMask allowed_operations) { // The drag invokes a nested event loop, but we need to continue processing // events. MessageLoop::current()->SetNestableTasksAllowed(true); - [cocoa_view_ startDragWithDropData:drop_data]; + NSDragOperation mask = static_cast<NSDragOperation>(allowed_operations); + [cocoa_view_ startDragWithDropData:drop_data + dragOperationMask:mask]; MessageLoop::current()->SetNestableTasksAllowed(false); } @@ -166,8 +186,8 @@ void TabContentsViewMac::RestoreFocus() { } } -void TabContentsViewMac::UpdateDragCursor(bool is_drop_target) { - [cocoa_view_ setIsDropTarget:is_drop_target ? YES : NO]; +void TabContentsViewMac::UpdateDragCursor(WebDragOperation operation) { + [cocoa_view_ setCurrentDragOperation: operation]; } void TabContentsViewMac::GotFocus() { @@ -269,8 +289,8 @@ void TabContentsViewMac::Observe(NotificationType type, [self registerForDraggedTypes:types]; } -- (void)setIsDropTarget:(BOOL)isTarget { - [dropTarget_ setIsDropTarget:isTarget]; +- (void)setCurrentDragOperation:(NSDragOperation)operation { + [dropTarget_ setCurrentOperation:operation]; } - (TabContents*)tabContents { @@ -325,11 +345,13 @@ void TabContentsViewMac::Observe(NotificationType type, forType:type]; } -- (void)startDragWithDropData:(const WebDropData&)dropData { +- (void)startDragWithDropData:(const WebDropData&)dropData + dragOperationMask:(NSDragOperation)operationMask { dragSource_.reset([[WebDragSource alloc] initWithContentsView:self dropData:&dropData - pasteboard:[NSPasteboard pasteboardWithName:NSDragPboard]]); + pasteboard:[NSPasteboard pasteboardWithName:NSDragPboard] + dragOperationMask:operationMask]); [dragSource_ startDrag]; } @@ -338,16 +360,14 @@ void TabContentsViewMac::Observe(NotificationType type, // Returns what kind of drag operations are available. This is a required // method for NSDraggingSource. - (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal { - // TODO(pinkerton): I think this is right... - return NSDragOperationCopy; + return [dragSource_ draggingSourceOperationMaskForLocal:isLocal]; } // Called when a drag initiated in our view ends. - (void)draggedImage:(NSImage*)anImage endedAt:(NSPoint)screenPoint operation:(NSDragOperation)operation { - [dragSource_ endDragAt:screenPoint - isCancelled:(operation == NSDragOperationNone)]; + [dragSource_ endDragAt:screenPoint operation:operation]; // Might as well throw out this object now. dragSource_.reset(); diff --git a/chrome/browser/tab_contents/web_drag_source.cc b/chrome/browser/tab_contents/web_drag_source.cc index 9cfbb2d..6f6b243 100644 --- a/chrome/browser/tab_contents/web_drag_source.cc +++ b/chrome/browser/tab_contents/web_drag_source.cc @@ -15,6 +15,9 @@ #include "chrome/common/notification_type.h" #include "chrome/common/notification_service.h" +using WebKit::WebDragOperationNone; +using WebKit::WebDragOperationCopy; + namespace { static void GetCursorPositions(gfx::NativeWindow wnd, gfx::Point* client, @@ -53,8 +56,9 @@ void WebDragSource::OnDragSourceCancel() { gfx::Point client; gfx::Point screen; GetCursorPositions(source_wnd_, &client, &screen); - render_view_host_->DragSourceCancelledAt(client.x(), client.y(), - screen.x(), screen.y()); + render_view_host_->DragSourceEndedAt(client.x(), client.y(), + screen.x(), screen.y(), + WebDragOperationNone); } void WebDragSource::OnDragSourceDrop() { @@ -65,7 +69,9 @@ void WebDragSource::OnDragSourceDrop() { gfx::Point screen; GetCursorPositions(source_wnd_, &client, &screen); render_view_host_->DragSourceEndedAt(client.x(), client.y(), - screen.x(), screen.y()); + screen.x(), screen.y(), + WebDragOperationCopy); + // TODO(jpa): This needs to be fixed to send the actual drag operation. } void WebDragSource::OnDragSourceMove() { diff --git a/chrome/browser/tab_contents/web_drop_target.cc b/chrome/browser/tab_contents/web_drop_target.cc index af39273..4494c0d 100644 --- a/chrome/browser/tab_contents/web_drop_target.cc +++ b/chrome/browser/tab_contents/web_drop_target.cc @@ -18,6 +18,8 @@ #include "webkit/glue/webdropdata.h" #include "webkit/glue/window_open_disposition.h" +using WebKit::WebDragOperationCopy; + namespace { // A helper method for getting the preferred drop effect. @@ -113,7 +115,8 @@ DWORD WebDropTarget::OnDragEnter(IDataObject* data_object, ScreenToClient(GetHWND(), &client_pt); tab_contents_->render_view_host()->DragTargetDragEnter(drop_data, gfx::Point(client_pt.x, client_pt.y), - gfx::Point(cursor_position.x, cursor_position.y)); + gfx::Point(cursor_position.x, cursor_position.y), + WebDragOperationCopy); // FIXME(snej): Send actual operation // We lie here and always return a DROPEFFECT because we don't want to // wait for the IPC call to return. @@ -135,7 +138,8 @@ DWORD WebDropTarget::OnDragOver(IDataObject* data_object, ScreenToClient(GetHWND(), &client_pt); tab_contents_->render_view_host()->DragTargetDragOver( gfx::Point(client_pt.x, client_pt.y), - gfx::Point(cursor_position.x, cursor_position.y)); + gfx::Point(cursor_position.x, cursor_position.y), + WebDragOperationCopy); // FIXME(snej): Send actual operation if (!is_drop_target_) return DROPEFFECT_NONE; diff --git a/chrome/browser/views/tab_contents/tab_contents_view_gtk.cc b/chrome/browser/views/tab_contents/tab_contents_view_gtk.cc index 1d566a3..75467ab 100644 --- a/chrome/browser/views/tab_contents/tab_contents_view_gtk.cc +++ b/chrome/browser/views/tab_contents/tab_contents_view_gtk.cc @@ -160,8 +160,10 @@ void TabContentsViewGtk::GetContainerBounds(gfx::Rect* out) const { GetBounds(out, false); } -void TabContentsViewGtk::StartDragging(const WebDropData& drop_data) { +void TabContentsViewGtk::StartDragging(const WebDropData& drop_data, + WebDragOperationsMask ops) { drag_source_->StartDragging(drop_data, &last_mouse_down_); + // TODO(snej): Make use of WebDragOperationsMask } void TabContentsViewGtk::OnContentsDestroy() { @@ -222,7 +224,7 @@ void TabContentsViewGtk::RestoreFocus() { SetInitialFocus(); } -void TabContentsViewGtk::UpdateDragCursor(bool is_drop_target) { +void TabContentsViewGtk::UpdateDragCursor(WebDragOperation operation) { NOTIMPLEMENTED(); } diff --git a/chrome/browser/views/tab_contents/tab_contents_view_win.cc b/chrome/browser/views/tab_contents/tab_contents_view_win.cc index 47a73e3..9d22dbf 100644 --- a/chrome/browser/views/tab_contents/tab_contents_view_win.cc +++ b/chrome/browser/views/tab_contents/tab_contents_view_win.cc @@ -32,6 +32,9 @@ #include "webkit/glue/plugins/webplugin_delegate_impl.h" #include "webkit/glue/webdropdata.h" +using WebKit::WebDragOperation; +using WebKit::WebDragOperationNone; +using WebKit::WebDragOperationsMask; using WebKit::WebInputEvent; namespace { @@ -132,7 +135,8 @@ void TabContentsViewWin::GetContainerBounds(gfx::Rect* out) const { GetBounds(out, false); } -void TabContentsViewWin::StartDragging(const WebDropData& drop_data) { +void TabContentsViewWin::StartDragging(const WebDropData& drop_data, + WebDragOperationsMask ops) { OSExchangeData data; // TODO(tc): Generate an appropriate drag image. @@ -189,6 +193,7 @@ void TabContentsViewWin::StartDragging(const WebDropData& drop_data) { MessageLoop::current()->SetNestableTasksAllowed(true); DoDragDrop(OSExchangeDataProviderWin::GetIDataObject(data), drag_source_, DROPEFFECT_COPY | DROPEFFECT_LINK, &effects); + // TODO(snej): Use 'ops' param instead of hardcoding dropeffects MessageLoop::current()->SetNestableTasksAllowed(old_state); drag_source_ = NULL; @@ -358,8 +363,8 @@ void TabContentsViewWin::CancelDragAndCloseTab() { close_tab_after_drag_ends_ = true; } -void TabContentsViewWin::UpdateDragCursor(bool is_drop_target) { - drop_target_->set_is_drop_target(is_drop_target); +void TabContentsViewWin::UpdateDragCursor(WebDragOperation operation) { + drop_target_->set_is_drop_target(operation != WebDragOperationNone); } void TabContentsViewWin::GotFocus() { diff --git a/chrome/browser/views/tab_contents/tab_contents_view_win.h b/chrome/browser/views/tab_contents/tab_contents_view_win.h index b2739dc..479f3c4 100644 --- a/chrome/browser/views/tab_contents/tab_contents_view_win.h +++ b/chrome/browser/views/tab_contents/tab_contents_view_win.h @@ -54,8 +54,9 @@ class TabContentsViewWin : public TabContentsView, // Backend implementation of RenderViewHostDelegate::View. virtual void ShowContextMenu(const ContextMenuParams& params); - virtual void StartDragging(const WebDropData& drop_data); - virtual void UpdateDragCursor(bool is_drop_target); + virtual void StartDragging(const WebDropData& drop_data, + WebKit::WebDragOperationsMask operations); + virtual void UpdateDragCursor(WebKit::WebDragOperation operation); virtual void GotFocus(); virtual void TakeFocus(bool reverse); virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event); diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index 43b2b9c..9e9ac815 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -331,13 +331,15 @@ IPC_BEGIN_MESSAGES(View) webkit_glue::PasswordFormDomManager::FillData) // D&d drop target messages. - IPC_MESSAGE_ROUTED3(ViewMsg_DragTargetDragEnter, + IPC_MESSAGE_ROUTED4(ViewMsg_DragTargetDragEnter, WebDropData /* drop_data */, gfx::Point /* client_pt */, - gfx::Point /* screen_pt */) - IPC_MESSAGE_ROUTED2(ViewMsg_DragTargetDragOver, + gfx::Point /* screen_pt */, + WebKit::WebDragOperationsMask /* ops_allowed */) + IPC_MESSAGE_ROUTED3(ViewMsg_DragTargetDragOver, gfx::Point /* client_pt */, - gfx::Point /* screen_pt */) + gfx::Point /* screen_pt */, + WebKit::WebDragOperationsMask /* ops_allowed */) IPC_MESSAGE_ROUTED0(ViewMsg_DragTargetDragLeave) IPC_MESSAGE_ROUTED2(ViewMsg_DragTargetDrop, gfx::Point /* client_pt */, @@ -351,7 +353,7 @@ IPC_BEGIN_MESSAGES(View) gfx::Point /* client_pt */, gfx::Point /* screen_pt */, bool /* ended */, - bool /* cancelled */) + WebKit::WebDragOperation /* drag_operation */) // Notifies the renderer that the system DoDragDrop call has ended. IPC_MESSAGE_ROUTED0(ViewMsg_DragSourceSystemDragEnded) @@ -1104,13 +1106,14 @@ IPC_BEGIN_MESSAGES(ViewHost) // WebDropData struct contains contextual information about the pieces of the // page the user dragged. The parent uses this notification to initiate a // drag session at the OS level. - IPC_MESSAGE_ROUTED1(ViewHostMsg_StartDragging, - WebDropData /* drop_data */) + IPC_MESSAGE_ROUTED2(ViewHostMsg_StartDragging, + WebDropData /* drop_data */, + WebKit::WebDragOperationsMask /* ops_allowed */) // The page wants to update the mouse cursor during a drag & drop operation. // |is_drop_target| is true if the mouse is over a valid drop target. IPC_MESSAGE_ROUTED1(ViewHostMsg_UpdateDragCursor, - bool /* is_drop_target */) + WebKit::WebDragOperation /* drag_operation */) // Tells the browser to move the focus to the next (previous if reverse is // true) focusable element. diff --git a/chrome/common/webkit_param_traits.h b/chrome/common/webkit_param_traits.h index b7e7e0b..335ba9e 100644 --- a/chrome/common/webkit_param_traits.h +++ b/chrome/common/webkit_param_traits.h @@ -27,6 +27,7 @@ #include "webkit/api/public/WebCache.h" #include "webkit/api/public/WebCompositionCommand.h" #include "webkit/api/public/WebConsoleMessage.h" +#include "webkit/api/public/WebDragOperation.h" #include "webkit/api/public/WebFindOptions.h" #include "webkit/api/public/WebInputEvent.h" #include "webkit/api/public/WebScreenInfo.h" @@ -302,6 +303,23 @@ struct ParamTraits<WebKit::WebTextDirection> { } }; +template <> + struct ParamTraits<WebKit::WebDragOperation> { + typedef WebKit::WebDragOperation param_type; + static void Write(Message* m, const param_type& p) { + m->WriteInt(p); + } + static bool Read(const Message* m, void** iter, param_type* r) { + int temp; + bool res = m->ReadInt(iter, &temp); + *r = static_cast<param_type>(temp); + return res; + } + static void Log(const param_type& p, std::wstring* l) { + l->append(StringPrintf(L"%d", p)); + } +}; + } // namespace IPC #endif // CHROME_COMMON_WEBKIT_PARAM_TRAITS_H_ diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 339c092..0e2a5ae 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -108,6 +108,8 @@ using WebKit::WebConsoleMessage; using WebKit::WebData; using WebKit::WebDataSource; using WebKit::WebDragData; +using WebKit::WebDragOperation; +using WebKit::WebDragOperationsMask; using WebKit::WebEditingAction; using WebKit::WebForm; using WebKit::WebFrame; @@ -2235,8 +2237,12 @@ void RenderView::ShowContextMenu(WebView* webview, } void RenderView::StartDragging(WebView* webview, - const WebDragData& drag_data) { - Send(new ViewHostMsg_StartDragging(routing_id_, WebDropData(drag_data))); + const WebKit::WebPoint &mouseCoords, + const WebDragData& drag_data, + WebDragOperationsMask allowed_ops) { + Send(new ViewHostMsg_StartDragging(routing_id_, + WebDropData(drag_data), + allowed_ops)); } void RenderView::TakeFocus(WebView* webview, bool reverse) { @@ -2709,12 +2715,10 @@ void RenderView::OnReservePageIDRange(int size_of_range) { void RenderView::OnDragSourceEndedOrMoved(const gfx::Point& client_point, const gfx::Point& screen_point, - bool ended, bool cancelled) { + bool ended, + WebDragOperation op) { if (ended) { - if (cancelled) - webview()->DragSourceCancelledAt(client_point, screen_point); - else - webview()->DragSourceEndedAt(client_point, screen_point); + webview()->DragSourceEndedAt(client_point, screen_point, op); } else { webview()->DragSourceMovedTo(client_point, screen_point); } @@ -2771,22 +2775,27 @@ void RenderView::OnFillPasswordForm( void RenderView::OnDragTargetDragEnter(const WebDropData& drop_data, const gfx::Point& client_point, - const gfx::Point& screen_point) { - bool is_drop_target = webview()->DragTargetDragEnter( + const gfx::Point& screen_point, + WebDragOperationsMask ops) { + WebDragOperation operation = webview()->DragTargetDragEnter( drop_data.ToDragData(), drop_data.identity, client_point, - screen_point); + screen_point, + ops); - Send(new ViewHostMsg_UpdateDragCursor(routing_id_, is_drop_target)); + Send(new ViewHostMsg_UpdateDragCursor(routing_id_, operation)); } void RenderView::OnDragTargetDragOver(const gfx::Point& client_point, - const gfx::Point& screen_point) { - bool is_drop_target = - webview()->DragTargetDragOver(client_point, screen_point); + const gfx::Point& screen_point, + WebDragOperationsMask ops) { + WebDragOperation operation = webview()->DragTargetDragOver( + client_point, + screen_point, + ops); - Send(new ViewHostMsg_UpdateDragCursor(routing_id_, is_drop_target)); + Send(new ViewHostMsg_UpdateDragCursor(routing_id_, operation)); } void RenderView::OnDragTargetDragLeave() { diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index aa6bc74..b9fbee2 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -299,7 +299,9 @@ class RenderView : public RenderWidget, const std::string& security_info, const std::string& frame_charset); virtual void StartDragging(WebView* webview, - const WebKit::WebDragData& drag_data); + const WebKit::WebPoint &mouseCoords, + const WebKit::WebDragData& drag_data, + WebKit::WebDragOperationsMask operations_mask); virtual void TakeFocus(WebView* webview, bool reverse); virtual void JSOutOfMemory(); virtual void NavigateBackForwardSoon(int offset); @@ -552,9 +554,11 @@ class RenderView : public RenderWidget, const webkit_glue::PasswordFormDomManager::FillData& form_data); void OnDragTargetDragEnter(const WebDropData& drop_data, const gfx::Point& client_pt, - const gfx::Point& screen_pt); + const gfx::Point& screen_pt, + WebKit::WebDragOperationsMask operations_allowed); void OnDragTargetDragOver(const gfx::Point& client_pt, - const gfx::Point& screen_pt); + const gfx::Point& screen_pt, + WebKit::WebDragOperationsMask operations_allowed); void OnDragTargetDragLeave(); void OnDragTargetDrop(const gfx::Point& client_pt, const gfx::Point& screen_pt); @@ -579,7 +583,8 @@ class RenderView : public RenderWidget, void OnDragSourceEndedOrMoved(const gfx::Point& client_point, const gfx::Point& screen_point, - bool ended, bool cancelled); + bool ended, + WebKit::WebDragOperation drag_operation); void OnDragSourceSystemDragEnded(); void OnInstallMissingPlugin(); void OnFileChooserResponse(const std::vector<FilePath>& file_names); diff --git a/webkit/api/public/WebDragOperation.h b/webkit/api/public/WebDragOperation.h new file mode 100644 index 0000000..1a9b9ce --- /dev/null +++ b/webkit/api/public/WebDragOperation.h @@ -0,0 +1,59 @@ +/* +* Copyright (C) 2009 Google Inc. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are +* met: +* +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above +* copyright notice, this list of conditions and the following disclaimer +* in the documentation and/or other materials provided with the +* distribution. +* * Neither the name of Google Inc. nor the names of its +* contributors may be used to endorse or promote products derived from +* this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef WebDragOperation_h +#define WebDragOperation_h + +#include <limits.h> + +namespace WebKit { + + // "Verb" of a drag-and-drop operation as negotiated between the source and + // destination. + // (These constants match their equivalents in WebCore's DragActions.h and + // should not be renumbered.) + enum WebDragOperation { + WebDragOperationNone = 0, + WebDragOperationCopy = 1, + WebDragOperationLink = 2, + WebDragOperationGeneric = 4, + WebDragOperationPrivate = 8, + WebDragOperationMove = 16, + WebDragOperationDelete = 32, + WebDragOperationEvery = UINT_MAX + }; + + // Alternate typedef to make it clear when this is being used as a mask + // with potentially multiple value bits set. + typedef WebDragOperation WebDragOperationsMask; + +} // namespace WebKit + +#endif diff --git a/webkit/data/layout_tests/platform/chromium-linux/LayoutTests/fast/events/drag-in-frames-expected.txt b/webkit/data/layout_tests/platform/chromium-linux/LayoutTests/fast/events/drag-in-frames-expected.txt new file mode 100644 index 0000000..0a2bc61 --- /dev/null +++ b/webkit/data/layout_tests/platform/chromium-linux/LayoutTests/fast/events/drag-in-frames-expected.txt @@ -0,0 +1,18 @@ +Event log + +ondragstart src +ondragenter left target +ondrag src +ondragover left target +ondrag src +ondragover left target +ondrag src +ondragenter right target +ondragleave left target +ondrag src +ondragover right target +ondrag src +ondragover right target +ondrop right target +ondragend src +These results are just "sensible" at the moment, meaning that all the events fire on the right elements, nothing more. The order in particular can rightfully change. diff --git a/webkit/data/layout_tests/platform/chromium-mac/LayoutTests/fast/events/drag-in-frames-expected.txt b/webkit/data/layout_tests/platform/chromium-mac/LayoutTests/fast/events/drag-in-frames-expected.txt new file mode 100644 index 0000000..0a2bc61 --- /dev/null +++ b/webkit/data/layout_tests/platform/chromium-mac/LayoutTests/fast/events/drag-in-frames-expected.txt @@ -0,0 +1,18 @@ +Event log + +ondragstart src +ondragenter left target +ondrag src +ondragover left target +ondrag src +ondragover left target +ondrag src +ondragenter right target +ondragleave left target +ondrag src +ondragover right target +ondrag src +ondragover right target +ondrop right target +ondragend src +These results are just "sensible" at the moment, meaning that all the events fire on the right elements, nothing more. The order in particular can rightfully change. diff --git a/webkit/data/layout_tests/platform/chromium-win/LayoutTests/fast/events/drag-in-frames-expected.txt b/webkit/data/layout_tests/platform/chromium-win/LayoutTests/fast/events/drag-in-frames-expected.txt index 78eaf8e..0a2bc61 100644 --- a/webkit/data/layout_tests/platform/chromium-win/LayoutTests/fast/events/drag-in-frames-expected.txt +++ b/webkit/data/layout_tests/platform/chromium-win/LayoutTests/fast/events/drag-in-frames-expected.txt @@ -1,16 +1,18 @@ Event log ondragstart src -ondrag src ondragenter left target ondrag src ondragover left target ondrag src +ondragover left target +ondrag src ondragenter right target ondragleave left target ondrag src ondragover right target +ondrag src ondragover right target -ondragend src ondrop right target +ondragend src These results are just "sensible" at the moment, meaning that all the events fire on the right elements, nothing more. The order in particular can rightfully change. diff --git a/webkit/glue/dragclient_impl.cc b/webkit/glue/dragclient_impl.cc index 661a7a0..75a8ba9 100644 --- a/webkit/glue/dragclient_impl.cc +++ b/webkit/glue/dragclient_impl.cc @@ -16,6 +16,7 @@ #include "webkit/glue/webview_impl.h" using WebKit::WebDragData; +using WebKit::WebPoint; void DragClientImpl::willPerformDragDestinationAction( WebCore::DragDestinationAction, @@ -59,7 +60,14 @@ void DragClientImpl::startDrag(WebCore::DragImageRef drag_image, WebDragData drag_data = webkit_glue::ChromiumDataObjectToWebDragData( static_cast<WebCore::ClipboardChromium*>(clipboard)->dataObject()); - webview_->StartDragging(drag_data); + WebCore::DragOperation drag_operation_mask; + if (!clipboard->sourceOperation(drag_operation_mask)) { + drag_operation_mask = WebCore::DragOperationEvery; + } + + webview_->StartDragging(webkit_glue::IntPointToWebPoint(event_pos), + drag_data, + static_cast<WebKit::WebDragOperationsMask>(drag_operation_mask)); } WebCore::DragImageRef DragClientImpl::createDragImageForLink( diff --git a/webkit/glue/webview.h b/webkit/glue/webview.h index 0b55232..0cd33fc 100644 --- a/webkit/glue/webview.h +++ b/webkit/glue/webview.h @@ -9,6 +9,7 @@ #include <vector> #include "base/basictypes.h" +#include "webkit/api/public/WebDragOperation.h" #include "webkit/api/public/WebWidget.h" namespace WebKit { @@ -185,15 +186,11 @@ class WebView : public WebKit::WebWidget { // Show the JavaScript console. virtual void ShowJavaScriptConsole() = 0; - // Notifies the webview that a drag has been cancelled. - virtual void DragSourceCancelledAt( - const WebKit::WebPoint& client_point, - const WebKit::WebPoint& screen_point) = 0; - - // Notifies the webview that a drag has terminated. + // Notifies the webview that a drag has ended (with a drop or a cancel). virtual void DragSourceEndedAt( const WebKit::WebPoint& client_point, - const WebKit::WebPoint& screen_point) = 0; + const WebKit::WebPoint& screen_point, + WebKit::WebDragOperation operation) = 0; // Notifies the webview that a drag and drop operation is in progress, with // dropable items over the view. @@ -206,13 +203,15 @@ class WebView : public WebKit::WebWidget { // Callback methods when a drag and drop operation is trying to drop data // on this webview. - virtual bool DragTargetDragEnter( + virtual WebKit::WebDragOperation DragTargetDragEnter( const WebKit::WebDragData& drag_data, int identity, const WebKit::WebPoint& client_point, - const WebKit::WebPoint& screen_point) = 0; - virtual bool DragTargetDragOver( + const WebKit::WebPoint& screen_point, + WebKit::WebDragOperationsMask operations_allowed) = 0; + virtual WebKit::WebDragOperation DragTargetDragOver( const WebKit::WebPoint& client_point, - const WebKit::WebPoint& screen_point) = 0; + const WebKit::WebPoint& screen_point, + WebKit::WebDragOperationsMask operations_allowed) = 0; virtual void DragTargetDragLeave() = 0; virtual void DragTargetDrop( const WebKit::WebPoint& client_point, diff --git a/webkit/glue/webview_delegate.h b/webkit/glue/webview_delegate.h index 804049d..7a8e313 100644 --- a/webkit/glue/webview_delegate.h +++ b/webkit/glue/webview_delegate.h @@ -28,6 +28,7 @@ #include <vector> +#include "webkit/api/public/WebDragOperation.h" #include "webkit/api/public/WebFrame.h" #include "webkit/api/public/WebNavigationPolicy.h" #include "webkit/api/public/WebNavigationType.h" @@ -639,10 +640,14 @@ class WebViewDelegate : virtual public WebKit::WebWidgetClient { // Starts a drag session with the supplied contextual information. // webview: The WebView sending the delegate method. + // mouseCoords: Current mouse coordinates // drop_data: a WebDropData struct which should contain all the necessary // information for dragging data out of the webview. + // drag_source_operation_mask: indicates what drag operations are allowed virtual void StartDragging(WebView* webview, - const WebKit::WebDragData& drag_data) { + const WebKit::WebPoint &mouseCoords, + const WebKit::WebDragData& drag_data, + WebKit::WebDragOperationsMask operations_mask) { } // Returns the focus to the client. diff --git a/webkit/glue/webview_impl.cc b/webkit/glue/webview_impl.cc index f38c390..cc9ebbd 100644 --- a/webkit/glue/webview_impl.cc +++ b/webkit/glue/webview_impl.cc @@ -96,6 +96,10 @@ using WebKit::WebCompositionCommand; using WebKit::WebCompositionCommandConfirm; using WebKit::WebCompositionCommandDiscard; using WebKit::WebDragData; +using WebKit::WebDragOperation; +using WebKit::WebDragOperationCopy; +using WebKit::WebDragOperationNone; +using WebKit::WebDragOperationsMask; using WebKit::WebEditingClient; using WebKit::WebFrame; using WebKit::WebInputEvent; @@ -129,10 +133,19 @@ static const double kMaxTextSizeMultiplier = 3.0; // one page group. static const char* kPageGroupName = "default"; -// The webcore drag operation type when something is trying to be dropped on -// the webview. These values are taken from Apple's windows port. -static const WebCore::DragOperation kDropTargetOperation = - static_cast<WebCore::DragOperation>(DragOperationCopy | DragOperationLink); +// Ensure that the WebKit::WebDragOperation enum values stay in sync with +// the original WebCore::DragOperation constants. +#define COMPILE_ASSERT_MATCHING_ENUM(webcore_name) \ + COMPILE_ASSERT(int(WebCore::webcore_name) == int(WebKit::Web##webcore_name),\ + dummy##webcore_name) +COMPILE_ASSERT_MATCHING_ENUM(DragOperationNone); +COMPILE_ASSERT_MATCHING_ENUM(DragOperationCopy); +COMPILE_ASSERT_MATCHING_ENUM(DragOperationLink); +COMPILE_ASSERT_MATCHING_ENUM(DragOperationGeneric); +COMPILE_ASSERT_MATCHING_ENUM(DragOperationPrivate); +COMPILE_ASSERT_MATCHING_ENUM(DragOperationMove); +COMPILE_ASSERT_MATCHING_ENUM(DragOperationDelete); +COMPILE_ASSERT_MATCHING_ENUM(DragOperationEvery); // AutocompletePopupMenuClient class AutocompletePopupMenuClient : public WebCore::PopupMenuClient { @@ -380,7 +393,8 @@ WebViewImpl::WebViewImpl(WebViewDelegate* delegate, drag_target_dispatch_(false), drag_identity_(0), drop_effect_(DROP_EFFECT_DEFAULT), - drop_accept_(false), + operations_allowed_(WebKit::WebDragOperationNone), + drag_operation_(WebKit::WebDragOperationNone), autocomplete_popup_showing_(false), is_transparent_(false) { // WebKit/win/WebView.cpp does the same thing, except they call the @@ -1495,24 +1509,16 @@ void WebViewImpl::ShowJavaScriptConsole() { page_->inspectorController()->showPanel(InspectorController::ConsolePanel); } -void WebViewImpl::DragSourceCancelledAt( - const WebPoint& client_point, - const WebPoint& screen_point) { - PlatformMouseEvent pme(webkit_glue::WebPointToIntPoint(client_point), - webkit_glue::WebPointToIntPoint(screen_point), - NoButton, MouseEventMoved, 0, false, false, false, - false, 0); - page_->mainFrame()->eventHandler()->dragSourceEndedAt(pme, DragOperationNone); -} - void WebViewImpl::DragSourceEndedAt( const WebPoint& client_point, - const WebPoint& screen_point) { + const WebPoint& screen_point, + WebDragOperation operation) { PlatformMouseEvent pme(webkit_glue::WebPointToIntPoint(client_point), webkit_glue::WebPointToIntPoint(screen_point), LeftButton, MouseEventMoved, 0, false, false, false, false, 0); - page_->mainFrame()->eventHandler()->dragSourceEndedAt(pme, DragOperationCopy); + page_->mainFrame()->eventHandler()->dragSourceEndedAt(pme, + static_cast<WebCore::DragOperation>(operation)); } void WebViewImpl::DragSourceMovedTo( @@ -1534,52 +1540,70 @@ void WebViewImpl::DragSourceSystemDragEnded() { } } -bool WebViewImpl::DragTargetDragEnter( +WebDragOperation WebViewImpl::DragTargetDragEnter( const WebDragData& web_drag_data, int identity, const WebPoint& client_point, - const WebPoint& screen_point) { + const WebPoint& screen_point, + WebDragOperation operations_allowed) { DCHECK(!current_drag_data_.get()); current_drag_data_ = webkit_glue::WebDragDataToChromiumDataObject(web_drag_data); drag_identity_ = identity; + operations_allowed_ = operations_allowed; DragData drag_data( current_drag_data_.get(), webkit_glue::WebPointToIntPoint(client_point), webkit_glue::WebPointToIntPoint(screen_point), - kDropTargetOperation); + static_cast<WebCore::DragOperation>(operations_allowed)); drop_effect_ = DROP_EFFECT_DEFAULT; drag_target_dispatch_ = true; DragOperation effect = page_->dragController()->dragEntered(&drag_data); + // Mask the operation against the drag source's allowed operations. + if ((effect & drag_data.draggingSourceOperationMask()) != effect) { + effect = DragOperationNone; + } drag_target_dispatch_ = false; if (drop_effect_ != DROP_EFFECT_DEFAULT) - return drop_accept_ = (drop_effect_ != DROP_EFFECT_NONE); - return drop_accept_ = (effect != DragOperationNone); + drag_operation_ = (drop_effect_ != DROP_EFFECT_NONE) ? + WebDragOperationCopy : WebDragOperationNone; + else + drag_operation_ = static_cast<WebDragOperation>(effect); + return drag_operation_; } -bool WebViewImpl::DragTargetDragOver( +WebDragOperation WebViewImpl::DragTargetDragOver( const WebPoint& client_point, - const WebPoint& screen_point) { + const WebPoint& screen_point, + WebDragOperation operations_allowed) { DCHECK(current_drag_data_.get()); + operations_allowed_ = operations_allowed; DragData drag_data( current_drag_data_.get(), webkit_glue::WebPointToIntPoint(client_point), webkit_glue::WebPointToIntPoint(screen_point), - kDropTargetOperation); + static_cast<WebCore::DragOperation>(operations_allowed)); drop_effect_ = DROP_EFFECT_DEFAULT; drag_target_dispatch_ = true; DragOperation effect = page_->dragController()->dragUpdated(&drag_data); + // Mask the operation against the drag source's allowed operations. + if ((effect & drag_data.draggingSourceOperationMask()) != effect) { + effect = DragOperationNone; + } drag_target_dispatch_ = false; if (drop_effect_ != DROP_EFFECT_DEFAULT) - return drop_accept_ = (drop_effect_ != DROP_EFFECT_NONE); - return drop_accept_ = (effect != DragOperationNone); + drag_operation_ = (drop_effect_ != DROP_EFFECT_NONE) ? + WebDragOperationCopy : WebDragOperationNone; + else + drag_operation_ = static_cast<WebDragOperation>(effect); + return drag_operation_; } void WebViewImpl::DragTargetDragLeave() { @@ -1589,7 +1613,7 @@ void WebViewImpl::DragTargetDragLeave() { current_drag_data_.get(), IntPoint(), IntPoint(), - kDropTargetOperation); + static_cast<WebCore::DragOperation>(operations_allowed_)); drag_target_dispatch_ = true; page_->dragController()->dragExited(&drag_data); @@ -1597,7 +1621,7 @@ void WebViewImpl::DragTargetDragLeave() { current_drag_data_ = NULL; drop_effect_ = DROP_EFFECT_DEFAULT; - drop_accept_ = false; + drag_operation_ = WebDragOperationNone; drag_identity_ = 0; } @@ -1611,9 +1635,9 @@ void WebViewImpl::DragTargetDrop( // flight, or else delayed by javascript processing in this webview. If a // drop happens before our IPC reply has reached the browser process, then // the browser forwards the drop to this webview. So only allow a drop to - // proceed if our webview drop_accept_ state is true. + // proceed if our webview drag_operation_ state is not DragOperationNone. - if (!drop_accept_) { // IPC RACE CONDITION: do not allow this drop. + if (drag_operation_ == WebDragOperationNone) { // IPC RACE CONDITION: do not allow this drop. DragTargetDragLeave(); return; } @@ -1622,7 +1646,7 @@ void WebViewImpl::DragTargetDrop( current_drag_data_.get(), webkit_glue::WebPointToIntPoint(client_point), webkit_glue::WebPointToIntPoint(screen_point), - kDropTargetOperation); + static_cast<WebCore::DragOperation>(operations_allowed_)); drag_target_dispatch_ = true; page_->dragController()->performDrag(&drag_data); @@ -1630,7 +1654,7 @@ void WebViewImpl::DragTargetDrop( current_drag_data_ = NULL; drop_effect_ = DROP_EFFECT_DEFAULT; - drop_accept_ = false; + drag_operation_ = WebDragOperationNone; drag_identity_ = 0; } @@ -1795,11 +1819,13 @@ void WebViewImpl::DidCommitLoad(bool* is_new_navigation) { observed_new_navigation_ = false; } -void WebViewImpl::StartDragging(const WebDragData& drag_data) { +void WebViewImpl::StartDragging(WebPoint event_pos, + const WebDragData& drag_data, + WebDragOperationsMask mask) { if (delegate_) { DCHECK(!doing_drag_and_drop_); doing_drag_and_drop_ = true; - delegate_->StartDragging(this, drag_data); + delegate_->StartDragging(this, event_pos, drag_data, mask); } } diff --git a/webkit/glue/webview_impl.h b/webkit/glue/webview_impl.h index 2504c1e..3c753ac 100644 --- a/webkit/glue/webview_impl.h +++ b/webkit/glue/webview_impl.h @@ -111,23 +111,23 @@ class WebViewImpl : public WebView, public base::RefCounted<WebViewImpl> { virtual void CopyImageAt(int x, int y); virtual void InspectElement(int x, int y); virtual void ShowJavaScriptConsole(); - virtual void DragSourceCancelledAt( - const WebKit::WebPoint& client_point, - const WebKit::WebPoint& screen_point); virtual void DragSourceEndedAt( const WebKit::WebPoint& client_point, - const WebKit::WebPoint& screen_point); + const WebKit::WebPoint& screen_point, + WebKit::WebDragOperation operation); virtual void DragSourceMovedTo( const WebKit::WebPoint& client_point, const WebKit::WebPoint& screen_point); virtual void DragSourceSystemDragEnded(); - virtual bool DragTargetDragEnter( + virtual WebKit::WebDragOperation DragTargetDragEnter( const WebKit::WebDragData& drag_data, int identity, const WebKit::WebPoint& client_point, - const WebKit::WebPoint& screen_point); - virtual bool DragTargetDragOver( + const WebKit::WebPoint& screen_point, + WebKit::WebDragOperationsMask operations_allowed); + virtual WebKit::WebDragOperation DragTargetDragOver( const WebKit::WebPoint& client_point, - const WebKit::WebPoint& screen_point); + const WebKit::WebPoint& screen_point, + WebKit::WebDragOperationsMask operations_allowed); virtual void DragTargetDragLeave(); virtual void DragTargetDrop( const WebKit::WebPoint& client_point, @@ -231,7 +231,9 @@ class WebViewImpl : public WebView, public base::RefCounted<WebViewImpl> { } // Start a system drag and drop operation. - void StartDragging(const WebKit::WebDragData& drag_data); + void StartDragging(WebKit::WebPoint event_pos, + const WebKit::WebDragData& drag_data, + WebKit::WebDragOperationsMask drag_source_operation_mask); // Hides the autocomplete popup if it is showing. void HideAutoCompletePopup(); @@ -369,9 +371,13 @@ class WebViewImpl : public WebView, public base::RefCounted<WebViewImpl> { DROP_EFFECT_COPY } drop_effect_; - // When true, the drag data can be dropped onto the current drop target in - // this WebView (the drop target can accept the drop). - bool drop_accept_; + // The available drag operations (copy, move link...) allowed by the source. + WebKit::WebDragOperation operations_allowed_; + + // The current drag operation as negotiated by the source and destination. + // When not equal to DragOperationNone, the drag data can be dropped onto the + // current drop target in this WebView (the drop target can accept the drop). + WebKit::WebDragOperation drag_operation_; // The autocomplete popup. Kept around and reused every-time new suggestions // should be shown. diff --git a/webkit/tools/layout_tests/test_expectations.txt b/webkit/tools/layout_tests/test_expectations.txt index 5694113..495ff44 100644 --- a/webkit/tools/layout_tests/test_expectations.txt +++ b/webkit/tools/layout_tests/test_expectations.txt @@ -2400,9 +2400,6 @@ BUG20376 WIN : LayoutTests/media/video-src-remove.html = TIMEOUT FAIL BUG20987 : LayoutTests/fast/events/pageshow-pagehide-on-back-uncached.html = FAIL BUG20987 : LayoutTests/fast/events/pageshow-pagehide.html = FAIL -// WebKit 47827:47830 -BUG20985 : LayoutTests/editing/pasteboard/files-during-page-drags.html = FAIL - // This newly added test times out on Mac: BUG20438 MAC : chrome/plugins/get-url-with-iframe-target.html = TIMEOUT BUG20438 MAC : chrome/plugins/get-url-with-iframe-target-no-crash.html = TIMEOUT diff --git a/webkit/tools/test_shell/drag_delegate.cc b/webkit/tools/test_shell/drag_delegate.cc index 5f447ef..d9c45cd 100644 --- a/webkit/tools/test_shell/drag_delegate.cc +++ b/webkit/tools/test_shell/drag_delegate.cc @@ -35,7 +35,8 @@ void TestDragDelegate::OnDragSourceDrop() { gfx::Point client; gfx::Point screen; GetCursorPositions(source_hwnd_, &client, &screen); - webview_->DragSourceEndedAt(client, screen); + webview_->DragSourceEndedAt(client, screen, WebKit::WebDragOperationCopy); + // TODO(snej): Pass the real drag operation instead } void TestDragDelegate::OnDragSourceMove() { diff --git a/webkit/tools/test_shell/drop_delegate.cc b/webkit/tools/test_shell/drop_delegate.cc index 41b4767..ce0e0dc6 100644 --- a/webkit/tools/test_shell/drop_delegate.cc +++ b/webkit/tools/test_shell/drop_delegate.cc @@ -9,6 +9,8 @@ #include "webkit/glue/webdropdata.h" #include "webkit/glue/webview.h" +using WebKit::WebDragOperation; +using WebKit::WebDragOperationCopy; using WebKit::WebPoint; // BaseDropTarget methods ---------------------------------------------------- @@ -22,11 +24,14 @@ DWORD TestDropDelegate::OnDragEnter(IDataObject* data_object, POINT client_pt = cursor_position; ScreenToClient(GetHWND(), &client_pt); - bool valid = webview_->DragTargetDragEnter( + WebDragOperation op = webview_->DragTargetDragEnter( drop_data.ToDragData(), drop_data.identity, WebPoint(client_pt.x, client_pt.y), - WebPoint(cursor_position.x, cursor_position.y)); - return valid ? DROPEFFECT_COPY : DROPEFFECT_NONE; + WebPoint(cursor_position.x, cursor_position.y), + WebDragOperationCopy); + // TODO(snej): Pass the real drag operation instead + return op ? DROPEFFECT_COPY : DROPEFFECT_NONE; + // TODO(snej): Return the real drop effect constant matching 'op' } DWORD TestDropDelegate::OnDragOver(IDataObject* data_object, @@ -35,10 +40,13 @@ DWORD TestDropDelegate::OnDragOver(IDataObject* data_object, DWORD effect) { POINT client_pt = cursor_position; ScreenToClient(GetHWND(), &client_pt); - bool valid = webview_->DragTargetDragOver( + WebDragOperation op = webview_->DragTargetDragOver( WebPoint(client_pt.x, client_pt.y), - WebPoint(cursor_position.x, cursor_position.y)); - return valid ? DROPEFFECT_COPY : DROPEFFECT_NONE; + WebPoint(cursor_position.x, cursor_position.y), + WebDragOperationCopy); + // TODO(snej): Pass the real drag operation instead + return op ? DROPEFFECT_COPY : DROPEFFECT_NONE; + // TODO(snej): Return the real drop effect constant matching 'op' } void TestDropDelegate::OnDragLeave(IDataObject* data_object) { diff --git a/webkit/tools/test_shell/event_sending_controller.cc b/webkit/tools/test_shell/event_sending_controller.cc index 42402f0..15d54f6 100644 --- a/webkit/tools/test_shell/event_sending_controller.cc +++ b/webkit/tools/test_shell/event_sending_controller.cc @@ -45,7 +45,8 @@ using WebKit::WebInputEventFactory; using base::Time; using base::TimeTicks; - +using WebKit::WebDragOperation; +using WebKit::WebDragOperationsMask; using WebKit::WebDragData; using WebKit::WebInputEvent; using WebKit::WebKeyboardEvent; @@ -62,6 +63,8 @@ int EventSendingController::last_button_number_ = -1; namespace { static WebDragData current_drag_data; +static WebDragOperation current_drag_effect; +static WebDragOperationsMask current_drag_effects_allowed; static bool replaying_saved_events = false; static std::queue<WebMouseEvent> mouse_event_queue; @@ -188,6 +191,8 @@ void EventSendingController::Reset() { // The test should have finished a drag and the mouse button state. DCHECK(current_drag_data.isNull()); current_drag_data.reset(); + current_drag_effect = WebKit::WebDragOperationNone; + current_drag_effects_allowed = WebKit::WebDragOperationNone; pressed_button_ = WebMouseEvent::ButtonNone; dragMode.Set(true); #if defined(OS_WIN) @@ -211,9 +216,17 @@ WebView* EventSendingController::webview() { } // static -void EventSendingController::DoDragDrop(const WebDragData& drag_data) { +void EventSendingController::DoDragDrop(const WebKit::WebPoint &event_pos, + const WebDragData& drag_data, + WebDragOperationsMask mask) { + WebMouseEvent event; + InitMouseEvent(WebInputEvent::MouseDown, pressed_button_, event_pos, &event); + WebPoint client_point(event.x, event.y); + WebPoint screen_point(event.globalX, event.globalY); current_drag_data = drag_data; - webview()->DragTargetDragEnter(drag_data, 0, WebPoint(), WebPoint()); + current_drag_effects_allowed = mask; + current_drag_effect = webview()->DragTargetDragEnter( + drag_data, 0, client_point, screen_point, current_drag_effects_allowed); // Finish processing events. ReplaySavedEvents(); @@ -313,14 +326,17 @@ void EventSendingController::mouseUp( WebPoint client_point(e.x, e.y); WebPoint screen_point(e.globalX, e.globalY); - bool valid = webview()->DragTargetDragOver(client_point, screen_point); - if (valid) { - webview()->DragSourceEndedAt(client_point, screen_point); + webview()->DragSourceMovedTo(client_point, screen_point); + current_drag_effect = webview()->DragTargetDragOver(client_point, + screen_point, + current_drag_effects_allowed); + if (current_drag_effect) { webview()->DragTargetDrop(client_point, screen_point); } else { - webview()->DragSourceEndedAt(client_point, screen_point); webview()->DragTargetDragLeave(); } + webview()->DragSourceEndedAt(client_point, screen_point, + current_drag_effect); current_drag_data.reset(); } @@ -357,7 +373,9 @@ void EventSendingController::DoMouseMove(const WebMouseEvent& e) { WebPoint screen_point(e.globalX, e.globalY); webview()->DragSourceMovedTo(client_point, screen_point); - webview()->DragTargetDragOver(client_point, screen_point); + current_drag_effect = webview()->DragTargetDragOver( + client_point, screen_point, + current_drag_effects_allowed); } } diff --git a/webkit/tools/test_shell/event_sending_controller.h b/webkit/tools/test_shell/event_sending_controller.h index 353c411..5f26083 100644 --- a/webkit/tools/test_shell/event_sending_controller.h +++ b/webkit/tools/test_shell/event_sending_controller.h @@ -19,6 +19,7 @@ #include "build/build_config.h" #include "base/gfx/point.h" #include "base/task.h" +#include "webkit/api/public/WebDragOperation.h" #include "webkit/api/public/WebInputEvent.h" #include "webkit/glue/cpp_bound_class.h" @@ -28,6 +29,7 @@ class WebView; namespace WebKit { class WebDragData; class WebMouseEvent; +struct WebPoint; } class EventSendingController : public CppBoundClass { @@ -40,7 +42,9 @@ class EventSendingController : public CppBoundClass { void Reset(); // Simulate drag&drop system call. - static void DoDragDrop(const WebKit::WebDragData& drag_data); + static void DoDragDrop(const WebKit::WebPoint &event_pos, + const WebKit::WebDragData& drag_data, + WebKit::WebDragOperationsMask operations_mask); // JS callback methods. void mouseDown(const CppArgumentList& args, CppVariant* result); diff --git a/webkit/tools/test_shell/test_webview_delegate.cc b/webkit/tools/test_shell/test_webview_delegate.cc index b8b2a11..63917e9 100644 --- a/webkit/tools/test_shell/test_webview_delegate.cc +++ b/webkit/tools/test_shell/test_webview_delegate.cc @@ -27,6 +27,7 @@ #include "webkit/api/public/WebFrame.h" #include "webkit/api/public/WebKit.h" #include "webkit/api/public/WebNode.h" +#include "webkit/api/public/WebPoint.h" #include "webkit/api/public/WebRange.h" #include "webkit/api/public/WebScreenInfo.h" #include "webkit/api/public/WebString.h" @@ -61,6 +62,7 @@ using WebKit::WebData; using WebKit::WebDataSource; using WebKit::WebDragData; +using WebKit::WebDragOperationsMask; using WebKit::WebEditingAction; using WebKit::WebFrame; using WebKit::WebHistoryItem; @@ -69,6 +71,7 @@ using WebKit::WebNavigationPolicy; using WebKit::WebNode; using WebKit::WebPlugin; using WebKit::WebPluginParams; +using WebKit::WebPoint; using WebKit::WebRange; using WebKit::WebRect; using WebKit::WebScreenInfo; @@ -675,7 +678,9 @@ void TestWebViewDelegate::SetStatusbarText(WebView* webview, } void TestWebViewDelegate::StartDragging(WebView* webview, - const WebDragData& drag_data) { + const WebPoint &mouse_coords, + const WebDragData& drag_data, + WebDragOperationsMask mask) { if (WebKit::layoutTestMode()) { WebDragData mutable_drag_data = drag_data; if (shell_->layout_test_controller()->ShouldAddFileToPasteboard()) { @@ -685,7 +690,7 @@ void TestWebViewDelegate::StartDragging(WebView* webview, // When running a test, we need to fake a drag drop operation otherwise // Windows waits for real mouse events to know when the drag is over. - EventSendingController::DoDragDrop(mutable_drag_data); + EventSendingController::DoDragDrop(mouse_coords, mutable_drag_data, mask); } else { // TODO(tc): Drag and drop is disabled in the test shell because we need // to be able to convert from WebDragData to an IDataObject. diff --git a/webkit/tools/test_shell/test_webview_delegate.h b/webkit/tools/test_shell/test_webview_delegate.h index d18999e..ad0beee 100644 --- a/webkit/tools/test_shell/test_webview_delegate.h +++ b/webkit/tools/test_shell/test_webview_delegate.h @@ -104,7 +104,9 @@ class TestWebViewDelegate : public WebViewDelegate, unsigned int line_no, const std::wstring& source_id); virtual void StartDragging(WebView* webview, - const WebKit::WebDragData& drag_data); + const WebKit::WebPoint &mouseCoords, + const WebKit::WebDragData& drag_data, + WebKit::WebDragOperationsMask operations_mask); virtual void ShowContextMenu(WebView* webview, ContextNodeType node_type, int x, |