mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-02-26 17:07:47 +01:00
Add off-screen drag & drop support (issue #1032).
git-svn-id: https://chromiumembedded.googlecode.com/svn/branches/1916@1707 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
dceb7fcaa3
commit
998fa796ca
@ -104,6 +104,8 @@
|
||||
'tests/cefclient/cefclient.h',
|
||||
'tests/cefclient/binding_test.cpp',
|
||||
'tests/cefclient/binding_test.h',
|
||||
'tests/cefclient/bytes_write_handler.cpp',
|
||||
'tests/cefclient/bytes_write_handler.h',
|
||||
'tests/cefclient/client_app.cpp',
|
||||
'tests/cefclient/client_app.h',
|
||||
'tests/cefclient/client_app_delegates.cpp',
|
||||
@ -117,6 +119,7 @@
|
||||
'tests/cefclient/dialog_test.h',
|
||||
'tests/cefclient/dom_test.cpp',
|
||||
'tests/cefclient/dom_test.h',
|
||||
'tests/cefclient/dragdrop_events.h',
|
||||
'tests/cefclient/osrenderer.h',
|
||||
'tests/cefclient/osrenderer.cpp',
|
||||
'tests/cefclient/performance_test.cpp',
|
||||
@ -136,6 +139,8 @@
|
||||
'cefclient_sources_win': [
|
||||
'tests/cefclient/cefclient.exe.manifest',
|
||||
'tests/cefclient/cefclient.rc',
|
||||
'tests/cefclient/cefclient_osr_dragdrop_win.h',
|
||||
'tests/cefclient/cefclient_osr_dragdrop_win.cpp',
|
||||
'tests/cefclient/cefclient_osr_widget_win.h',
|
||||
'tests/cefclient/cefclient_osr_widget_win.cpp',
|
||||
'tests/cefclient/cefclient_win.cpp',
|
||||
|
@ -39,6 +39,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "include/capi/cef_base_capi.h"
|
||||
#include "include/capi/cef_drag_data_capi.h"
|
||||
#include "include/capi/cef_frame_capi.h"
|
||||
#include "include/capi/cef_process_message_capi.h"
|
||||
#include "include/capi/cef_request_context_capi.h"
|
||||
@ -453,6 +454,70 @@ typedef struct _cef_browser_host_t {
|
||||
///
|
||||
void (CEF_CALLBACK *handle_key_event_after_text_input_client)(
|
||||
struct _cef_browser_host_t* self, cef_event_handle_t keyEvent);
|
||||
|
||||
///
|
||||
// Call this function when the user drags the mouse into the web view (before
|
||||
// calling DragTargetDragOver/DragTargetLeave/DragTargetDrop). |drag_data|
|
||||
// should not contain file contents as this type of data is not allowed to be
|
||||
// dragged into the web view. File contents can be removed using
|
||||
// cef_drag_data_t::ResetFileContents (for example, if |drag_data| comes from
|
||||
// cef_render_handler_t::StartDragging). This function is only used when
|
||||
// window rendering is disabled.
|
||||
///
|
||||
void (CEF_CALLBACK *drag_target_drag_enter)(struct _cef_browser_host_t* self,
|
||||
struct _cef_drag_data_t* drag_data,
|
||||
const struct _cef_mouse_event_t* event,
|
||||
cef_drag_operations_mask_t allowed_ops);
|
||||
|
||||
///
|
||||
// Call this function each time the mouse is moved across the web view during
|
||||
// a drag operation (after calling DragTargetDragEnter and before calling
|
||||
// DragTargetDragLeave/DragTargetDrop). This function is only used when window
|
||||
// rendering is disabled.
|
||||
///
|
||||
void (CEF_CALLBACK *drag_target_drag_over)(struct _cef_browser_host_t* self,
|
||||
const struct _cef_mouse_event_t* event,
|
||||
cef_drag_operations_mask_t allowed_ops);
|
||||
|
||||
///
|
||||
// Call this function when the user drags the mouse out of the web view (after
|
||||
// calling DragTargetDragEnter). This function is only used when window
|
||||
// rendering is disabled.
|
||||
///
|
||||
void (CEF_CALLBACK *drag_target_drag_leave)(struct _cef_browser_host_t* self);
|
||||
|
||||
///
|
||||
// Call this function when the user completes the drag operation by dropping
|
||||
// the object onto the web view (after calling DragTargetDragEnter). The
|
||||
// object being dropped is |drag_data|, given as an argument to the previous
|
||||
// DragTargetDragEnter call. This function is only used when window rendering
|
||||
// is disabled.
|
||||
///
|
||||
void (CEF_CALLBACK *drag_target_drop)(struct _cef_browser_host_t* self,
|
||||
const struct _cef_mouse_event_t* event);
|
||||
|
||||
///
|
||||
// Call this function when the drag operation started by a
|
||||
// cef_render_handler_t::StartDragging call has ended either in a drop or by
|
||||
// being cancelled. |x| and |y| are mouse coordinates relative to the upper-
|
||||
// left corner of the view. If the web view is both the drag source and the
|
||||
// drag target then all DragTarget* functions should be called before
|
||||
// DragSource* mthods. This function is only used when window rendering is
|
||||
// disabled.
|
||||
///
|
||||
void (CEF_CALLBACK *drag_source_ended_at)(struct _cef_browser_host_t* self,
|
||||
int x, int y, cef_drag_operations_mask_t op);
|
||||
|
||||
///
|
||||
// Call this function when the drag operation started by a
|
||||
// cef_render_handler_t::StartDragging call has completed. This function may
|
||||
// be called immediately without first calling DragSourceEndedAt to cancel a
|
||||
// drag operation. If the web view is both the drag source and the drag target
|
||||
// then all DragTarget* functions should be called before DragSource* mthods.
|
||||
// This function is only used when window rendering is disabled.
|
||||
///
|
||||
void (CEF_CALLBACK *drag_source_system_drag_ended)(
|
||||
struct _cef_browser_host_t* self);
|
||||
} cef_browser_host_t;
|
||||
|
||||
|
||||
|
@ -39,6 +39,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "include/capi/cef_base_capi.h"
|
||||
#include "include/capi/cef_stream_capi.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -55,6 +56,16 @@ typedef struct _cef_drag_data_t {
|
||||
///
|
||||
cef_base_t base;
|
||||
|
||||
///
|
||||
// Returns a copy of the current object.
|
||||
///
|
||||
struct _cef_drag_data_t* (CEF_CALLBACK *clone)(struct _cef_drag_data_t* self);
|
||||
|
||||
///
|
||||
// Returns true (1) if this object is read-only.
|
||||
///
|
||||
int (CEF_CALLBACK *is_read_only)(struct _cef_drag_data_t* self);
|
||||
|
||||
///
|
||||
// Returns true (1) if the drag data is a link.
|
||||
///
|
||||
@ -120,15 +131,79 @@ typedef struct _cef_drag_data_t {
|
||||
cef_string_userfree_t (CEF_CALLBACK *get_file_name)(
|
||||
struct _cef_drag_data_t* self);
|
||||
|
||||
///
|
||||
// Write the contents of the file being dragged out of the web view into
|
||||
// |writer|. Returns the number of bytes sent to |writer|. If |writer| is NULL
|
||||
// this function will return the size of the file contents in bytes. Call
|
||||
// get_file_name() to get a suggested name for the file.
|
||||
///
|
||||
size_t (CEF_CALLBACK *get_file_contents)(struct _cef_drag_data_t* self,
|
||||
struct _cef_stream_writer_t* writer);
|
||||
|
||||
///
|
||||
// Retrieve the list of file names that are being dragged into the browser
|
||||
// window.
|
||||
///
|
||||
int (CEF_CALLBACK *get_file_names)(struct _cef_drag_data_t* self,
|
||||
cef_string_list_t names);
|
||||
|
||||
///
|
||||
// Set the link URL that is being dragged.
|
||||
///
|
||||
void (CEF_CALLBACK *set_link_url)(struct _cef_drag_data_t* self,
|
||||
const cef_string_t* url);
|
||||
|
||||
///
|
||||
// Set the title associated with the link being dragged.
|
||||
///
|
||||
void (CEF_CALLBACK *set_link_title)(struct _cef_drag_data_t* self,
|
||||
const cef_string_t* title);
|
||||
|
||||
///
|
||||
// Set the metadata associated with the link being dragged.
|
||||
///
|
||||
void (CEF_CALLBACK *set_link_metadata)(struct _cef_drag_data_t* self,
|
||||
const cef_string_t* data);
|
||||
|
||||
///
|
||||
// Set the plain text fragment that is being dragged.
|
||||
///
|
||||
void (CEF_CALLBACK *set_fragment_text)(struct _cef_drag_data_t* self,
|
||||
const cef_string_t* text);
|
||||
|
||||
///
|
||||
// Set the text/html fragment that is being dragged.
|
||||
///
|
||||
void (CEF_CALLBACK *set_fragment_html)(struct _cef_drag_data_t* self,
|
||||
const cef_string_t* html);
|
||||
|
||||
///
|
||||
// Set the base URL that the fragment came from.
|
||||
///
|
||||
void (CEF_CALLBACK *set_fragment_base_url)(struct _cef_drag_data_t* self,
|
||||
const cef_string_t* base_url);
|
||||
|
||||
///
|
||||
// Reset the file contents. You should do this before calling
|
||||
// cef_browser_host_t::DragTargetDragEnter as the web view does not allow us
|
||||
// to drag in this kind of data.
|
||||
///
|
||||
void (CEF_CALLBACK *reset_file_contents)(struct _cef_drag_data_t* self);
|
||||
|
||||
///
|
||||
// Add a file that is being dragged into the webview.
|
||||
///
|
||||
void (CEF_CALLBACK *add_file)(struct _cef_drag_data_t* self,
|
||||
const cef_string_t* path, const cef_string_t* display_name);
|
||||
} cef_drag_data_t;
|
||||
|
||||
|
||||
///
|
||||
// Create a new cef_drag_data_t object.
|
||||
///
|
||||
CEF_EXPORT cef_drag_data_t* cef_drag_data_create();
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -40,6 +40,7 @@
|
||||
|
||||
#include "include/capi/cef_base_capi.h"
|
||||
#include "include/capi/cef_browser_capi.h"
|
||||
#include "include/capi/cef_drag_data_capi.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -122,6 +123,31 @@ typedef struct _cef_render_handler_t {
|
||||
void (CEF_CALLBACK *on_cursor_change)(struct _cef_render_handler_t* self,
|
||||
struct _cef_browser_t* browser, cef_cursor_handle_t cursor);
|
||||
|
||||
///
|
||||
// Called when the user starts dragging content in the web view. Contextual
|
||||
// information about the dragged content is supplied by |drag_data|. OS APIs
|
||||
// that run a system message loop may be used within the StartDragging call.
|
||||
//
|
||||
// Return false (0) to abort the drag operation. Don't call any of
|
||||
// cef_browser_host_t::DragSource*Ended* functions after returning false (0).
|
||||
//
|
||||
// Return true (1) to handle the drag operation. Call
|
||||
// cef_browser_host_t::DragSourceEndedAt and DragSourceSystemDragEnded either
|
||||
// synchronously or asynchronously to inform the web view that the drag
|
||||
// operation has ended.
|
||||
///
|
||||
int (CEF_CALLBACK *start_dragging)(struct _cef_render_handler_t* self,
|
||||
struct _cef_browser_t* browser, struct _cef_drag_data_t* drag_data,
|
||||
cef_drag_operations_mask_t allowed_ops, int x, int y);
|
||||
|
||||
///
|
||||
// Called when the web view wants to update the mouse cursor during a drag &
|
||||
// drop operation. |operation| describes the allowed operation (none, move,
|
||||
// copy, link).
|
||||
///
|
||||
void (CEF_CALLBACK *update_drag_cursor)(struct _cef_render_handler_t* self,
|
||||
struct _cef_browser_t* browser, cef_drag_operations_mask_t operation);
|
||||
|
||||
///
|
||||
// Called when the scroll offset has changed.
|
||||
///
|
||||
|
@ -39,6 +39,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "include/cef_base.h"
|
||||
#include "include/cef_drag_data.h"
|
||||
#include "include/cef_frame.h"
|
||||
#include "include/cef_process_message.h"
|
||||
#include "include/cef_request_context.h"
|
||||
@ -218,6 +219,7 @@ class CefRunFileDialogCallback : public virtual CefBase {
|
||||
/*--cef(source=library)--*/
|
||||
class CefBrowserHost : public virtual CefBase {
|
||||
public:
|
||||
typedef cef_drag_operations_mask_t DragOperationsMask;
|
||||
typedef cef_file_dialog_mode_t FileDialogMode;
|
||||
typedef cef_mouse_button_type_t MouseButtonType;
|
||||
typedef cef_paint_element_type_t PaintElementType;
|
||||
@ -503,6 +505,72 @@ class CefBrowserHost : public virtual CefBase {
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void HandleKeyEventAfterTextInputClient(CefEventHandle keyEvent) =0;
|
||||
|
||||
///
|
||||
// Call this method when the user drags the mouse into the web view (before
|
||||
// calling DragTargetDragOver/DragTargetLeave/DragTargetDrop).
|
||||
// |drag_data| should not contain file contents as this type of data is not
|
||||
// allowed to be dragged into the web view. File contents can be removed using
|
||||
// CefDragData::ResetFileContents (for example, if |drag_data| comes from
|
||||
// CefRenderHandler::StartDragging).
|
||||
// This method is only used when window rendering is disabled.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void DragTargetDragEnter(CefRefPtr<CefDragData> drag_data,
|
||||
const CefMouseEvent& event,
|
||||
DragOperationsMask allowed_ops) =0;
|
||||
|
||||
///
|
||||
// Call this method each time the mouse is moved across the web view during
|
||||
// a drag operation (after calling DragTargetDragEnter and before calling
|
||||
// DragTargetDragLeave/DragTargetDrop).
|
||||
// This method is only used when window rendering is disabled.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void DragTargetDragOver(const CefMouseEvent& event,
|
||||
DragOperationsMask allowed_ops) =0;
|
||||
|
||||
///
|
||||
// Call this method when the user drags the mouse out of the web view (after
|
||||
// calling DragTargetDragEnter).
|
||||
// This method is only used when window rendering is disabled.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void DragTargetDragLeave() =0;
|
||||
|
||||
///
|
||||
// Call this method when the user completes the drag operation by dropping
|
||||
// the object onto the web view (after calling DragTargetDragEnter).
|
||||
// The object being dropped is |drag_data|, given as an argument to
|
||||
// the previous DragTargetDragEnter call.
|
||||
// This method is only used when window rendering is disabled.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void DragTargetDrop(const CefMouseEvent& event) =0;
|
||||
|
||||
///
|
||||
// Call this method when the drag operation started by a
|
||||
// CefRenderHandler::StartDragging call has ended either in a drop or
|
||||
// by being cancelled. |x| and |y| are mouse coordinates relative to the
|
||||
// upper-left corner of the view. If the web view is both the drag source
|
||||
// and the drag target then all DragTarget* methods should be called before
|
||||
// DragSource* mthods.
|
||||
// This method is only used when window rendering is disabled.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void DragSourceEndedAt(int x, int y, DragOperationsMask op) =0;
|
||||
|
||||
///
|
||||
// Call this method when the drag operation started by a
|
||||
// CefRenderHandler::StartDragging call has completed. This method may be
|
||||
// called immediately without first calling DragSourceEndedAt to cancel a
|
||||
// drag operation. If the web view is both the drag source and the drag
|
||||
// target then all DragTarget* methods should be called before DragSource*
|
||||
// mthods.
|
||||
// This method is only used when window rendering is disabled.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void DragSourceSystemDragEnded() =0;
|
||||
};
|
||||
|
||||
#endif // CEF_INCLUDE_CEF_BROWSER_H_
|
||||
|
@ -39,6 +39,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "include/cef_base.h"
|
||||
#include "include/cef_stream.h"
|
||||
#include <vector>
|
||||
|
||||
///
|
||||
@ -48,6 +49,24 @@
|
||||
/*--cef(source=library)--*/
|
||||
class CefDragData : public virtual CefBase {
|
||||
public:
|
||||
///
|
||||
// Create a new CefDragData object.
|
||||
///
|
||||
/*--cef()--*/
|
||||
static CefRefPtr<CefDragData> Create();
|
||||
|
||||
///
|
||||
// Returns a copy of the current object.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual CefRefPtr<CefDragData> Clone() =0;
|
||||
|
||||
///
|
||||
// Returns true if this object is read-only.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual bool IsReadOnly() =0;
|
||||
|
||||
///
|
||||
// Returns true if the drag data is a link.
|
||||
///
|
||||
@ -109,12 +128,71 @@ class CefDragData : public virtual CefBase {
|
||||
/*--cef()--*/
|
||||
virtual CefString GetFileName() =0;
|
||||
|
||||
///
|
||||
// Write the contents of the file being dragged out of the web view into
|
||||
// |writer|. Returns the number of bytes sent to |writer|. If |writer| is
|
||||
// NULL this method will return the size of the file contents in bytes.
|
||||
// Call GetFileName() to get a suggested name for the file.
|
||||
///
|
||||
/*--cef(optional_param=writer)--*/
|
||||
virtual size_t GetFileContents(CefRefPtr<CefStreamWriter> writer) =0;
|
||||
|
||||
///
|
||||
// Retrieve the list of file names that are being dragged into the browser
|
||||
// window.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual bool GetFileNames(std::vector<CefString>& names) =0;
|
||||
|
||||
///
|
||||
// Set the link URL that is being dragged.
|
||||
///
|
||||
/*--cef(optional_param=url)--*/
|
||||
virtual void SetLinkURL(const CefString& url) =0;
|
||||
|
||||
///
|
||||
// Set the title associated with the link being dragged.
|
||||
///
|
||||
/*--cef(optional_param=title)--*/
|
||||
virtual void SetLinkTitle(const CefString& title) =0;
|
||||
|
||||
///
|
||||
// Set the metadata associated with the link being dragged.
|
||||
///
|
||||
/*--cef(optional_param=data)--*/
|
||||
virtual void SetLinkMetadata(const CefString& data) =0;
|
||||
|
||||
///
|
||||
// Set the plain text fragment that is being dragged.
|
||||
///
|
||||
/*--cef(optional_param=text)--*/
|
||||
virtual void SetFragmentText(const CefString& text) =0;
|
||||
|
||||
///
|
||||
// Set the text/html fragment that is being dragged.
|
||||
///
|
||||
/*--cef(optional_param=html)--*/
|
||||
virtual void SetFragmentHtml(const CefString& html) =0;
|
||||
|
||||
///
|
||||
// Set the base URL that the fragment came from.
|
||||
///
|
||||
/*--cef(optional_param=base_url)--*/
|
||||
virtual void SetFragmentBaseURL(const CefString& base_url) =0;
|
||||
|
||||
///
|
||||
// Reset the file contents. You should do this before calling
|
||||
// CefBrowserHost::DragTargetDragEnter as the web view does not allow us to
|
||||
// drag in this kind of data.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void ResetFileContents() =0;
|
||||
|
||||
///
|
||||
// Add a file that is being dragged into the webview.
|
||||
///
|
||||
/*--cef(optional_param=display_name)--*/
|
||||
virtual void AddFile(const CefString& path, const CefString& display_name) =0;
|
||||
};
|
||||
|
||||
#endif // CEF_INCLUDE_CEF_DRAG_DATA_H_
|
||||
|
@ -40,6 +40,7 @@
|
||||
|
||||
#include "include/cef_base.h"
|
||||
#include "include/cef_browser.h"
|
||||
#include "include/cef_drag_data.h"
|
||||
#include <vector>
|
||||
|
||||
///
|
||||
@ -49,6 +50,8 @@
|
||||
/*--cef(source=client)--*/
|
||||
class CefRenderHandler : public virtual CefBase {
|
||||
public:
|
||||
typedef cef_drag_operations_mask_t DragOperation;
|
||||
typedef cef_drag_operations_mask_t DragOperationsMask;
|
||||
typedef cef_paint_element_type_t PaintElementType;
|
||||
typedef std::vector<CefRect> RectList;
|
||||
|
||||
@ -128,6 +131,35 @@ class CefRenderHandler : public virtual CefBase {
|
||||
virtual void OnCursorChange(CefRefPtr<CefBrowser> browser,
|
||||
CefCursorHandle cursor) {}
|
||||
|
||||
///
|
||||
// Called when the user starts dragging content in the web view. Contextual
|
||||
// information about the dragged content is supplied by |drag_data|.
|
||||
// OS APIs that run a system message loop may be used within the
|
||||
// StartDragging call.
|
||||
//
|
||||
// Return false to abort the drag operation. Don't call any of
|
||||
// CefBrowserHost::DragSource*Ended* methods after returning false.
|
||||
//
|
||||
// Return true to handle the drag operation. Call
|
||||
// CefBrowserHost::DragSourceEndedAt and DragSourceSystemDragEnded either
|
||||
// synchronously or asynchronously to inform the web view that the drag
|
||||
// operation has ended.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual bool StartDragging(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefDragData> drag_data,
|
||||
DragOperationsMask allowed_ops,
|
||||
int x, int y) { return false; }
|
||||
|
||||
///
|
||||
// Called when the web view wants to update the mouse cursor during a
|
||||
// drag & drop operation. |operation| describes the allowed operation
|
||||
// (none, move, copy, link).
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void UpdateDragCursor(CefRefPtr<CefBrowser> browser,
|
||||
DragOperation operation) {}
|
||||
|
||||
///
|
||||
// Called when the scroll offset has changed.
|
||||
///
|
||||
|
@ -930,7 +930,7 @@ void CefBrowserHostImpl::WasHidden(bool hidden) {
|
||||
if (!widget)
|
||||
return;
|
||||
|
||||
if (hidden)
|
||||
if (hidden)
|
||||
widget->WasHidden();
|
||||
else
|
||||
widget->WasShown();
|
||||
@ -1729,6 +1729,190 @@ void CefBrowserHostImpl::HandleKeyEventAfterTextInputClient(
|
||||
}
|
||||
#endif // !defined(OS_MACOSX)
|
||||
|
||||
void CefBrowserHostImpl::DragTargetDragEnter(CefRefPtr<CefDragData> drag_data,
|
||||
const CefMouseEvent& event,
|
||||
CefBrowserHost::DragOperationsMask allowed_ops) {
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::Bind(&CefBrowserHostImpl::DragTargetDragEnter, this, drag_data,
|
||||
event, allowed_ops));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!drag_data.get()) {
|
||||
NOTREACHED();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsWindowRenderingDisabled()) {
|
||||
NOTREACHED() << "Window rendering is not disabled";
|
||||
return;
|
||||
}
|
||||
|
||||
content::RenderViewHost* rvh =
|
||||
web_contents() ? web_contents()->GetRenderViewHost() : NULL;
|
||||
if (!rvh)
|
||||
return;
|
||||
|
||||
int screenX, screenY;
|
||||
|
||||
if (!client_->GetRenderHandler()->GetScreenPoint(
|
||||
this, event.x, event.y, screenX, screenY)) {
|
||||
screenX = event.x;
|
||||
screenY = event.y;
|
||||
}
|
||||
|
||||
CefDragDataImpl* data_impl = static_cast<CefDragDataImpl*>(drag_data.get());
|
||||
CefDragDataImpl::AutoLock lock_scope(data_impl);
|
||||
const content::DropData& drop_data = data_impl->drop_data();
|
||||
gfx::Point client_pt(event.x, event.y);
|
||||
gfx::Point screen_pt(screenX, screenY);
|
||||
blink::WebDragOperationsMask ops =
|
||||
static_cast<blink::WebDragOperationsMask>(allowed_ops);
|
||||
int modifiers = CefBrowserHostImpl::TranslateModifiers(event.modifiers);
|
||||
|
||||
rvh->DragTargetDragEnter(drop_data, client_pt, screen_pt, ops, modifiers);
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::DragTargetDragOver(const CefMouseEvent& event,
|
||||
CefBrowserHost::DragOperationsMask allowed_ops) {
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::Bind(&CefBrowserHostImpl::DragTargetDragOver, this, event,
|
||||
allowed_ops));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsWindowRenderingDisabled()) {
|
||||
NOTREACHED() << "Window rendering is not disabled";
|
||||
return;
|
||||
}
|
||||
|
||||
content::RenderViewHost* rvh =
|
||||
web_contents() ? web_contents()->GetRenderViewHost() : NULL;
|
||||
if (!rvh)
|
||||
return;
|
||||
|
||||
int screenX, screenY;
|
||||
|
||||
if (!client_->GetRenderHandler()->GetScreenPoint(
|
||||
this, event.x, event.y, screenX, screenY)) {
|
||||
screenX = event.x;
|
||||
screenY = event.y;
|
||||
}
|
||||
|
||||
gfx::Point client_pt(event.x, event.y);
|
||||
gfx::Point screen_pt(screenX, screenY);
|
||||
blink::WebDragOperationsMask ops =
|
||||
static_cast<blink::WebDragOperationsMask>(allowed_ops);
|
||||
int modifiers = CefBrowserHostImpl::TranslateModifiers(event.modifiers);
|
||||
|
||||
rvh->DragTargetDragOver(client_pt, screen_pt, ops, modifiers);
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::DragTargetDragLeave() {
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::Bind(&CefBrowserHostImpl::DragTargetDragLeave, this));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsWindowRenderingDisabled()) {
|
||||
NOTREACHED() << "Window rendering is not disabled";
|
||||
return;
|
||||
}
|
||||
|
||||
content::RenderViewHost* rvh =
|
||||
web_contents() ? web_contents()->GetRenderViewHost() : NULL;
|
||||
if (!rvh)
|
||||
return;
|
||||
|
||||
rvh->DragTargetDragLeave();
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::DragTargetDrop(const CefMouseEvent& event) {
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::Bind(&CefBrowserHostImpl::DragTargetDrop, this, event));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsWindowRenderingDisabled()) {
|
||||
NOTREACHED() << "Window rendering is not disabled";
|
||||
return;
|
||||
}
|
||||
|
||||
content::RenderViewHost* rvh =
|
||||
web_contents() ? web_contents()->GetRenderViewHost() : NULL;
|
||||
if (!rvh)
|
||||
return;
|
||||
|
||||
int screenX, screenY;
|
||||
|
||||
if (!client_->GetRenderHandler()->GetScreenPoint(
|
||||
this, event.x, event.y, screenX, screenY)) {
|
||||
screenX = event.x;
|
||||
screenY = event.y;
|
||||
}
|
||||
|
||||
gfx::Point client_pt(event.x, event.y);
|
||||
gfx::Point screen_pt(screenX, screenY);
|
||||
int modifiers = CefBrowserHostImpl::TranslateModifiers(event.modifiers);
|
||||
|
||||
rvh->DragTargetDrop(client_pt, screen_pt, modifiers);
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::DragSourceSystemDragEnded() {
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::Bind(&CefBrowserHostImpl::DragSourceSystemDragEnded, this));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsWindowRenderingDisabled()) {
|
||||
NOTREACHED() << "Window rendering is not disabled";
|
||||
return;
|
||||
}
|
||||
|
||||
content::RenderViewHost* rvh =
|
||||
web_contents() ? web_contents()->GetRenderViewHost() : NULL;
|
||||
if (!rvh)
|
||||
return;
|
||||
|
||||
rvh->DragSourceSystemDragEnded();
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::DragSourceEndedAt(
|
||||
int x, int y, CefBrowserHost::DragOperationsMask op) {
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::Bind(&CefBrowserHostImpl::DragSourceEndedAt, this, x, y, op));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsWindowRenderingDisabled()) {
|
||||
NOTREACHED() << "Window rendering is not disabled";
|
||||
return;
|
||||
}
|
||||
|
||||
content::RenderViewHost* rvh =
|
||||
web_contents() ? web_contents()->GetRenderViewHost() : NULL;
|
||||
if (!rvh)
|
||||
return;
|
||||
|
||||
int screenX, screenY;
|
||||
|
||||
if (!client_->GetRenderHandler()->GetScreenPoint(
|
||||
this, x, y, screenX, screenY)) {
|
||||
screenX = x;
|
||||
screenY = y;
|
||||
}
|
||||
|
||||
blink::WebDragOperation drag_op = static_cast<blink::WebDragOperation>(op);
|
||||
|
||||
rvh->DragSourceEndedAt(x, y, screenX, screenY, drag_op);
|
||||
}
|
||||
|
||||
// content::WebContentsDelegate methods.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@ -1921,9 +2105,12 @@ bool CefBrowserHostImpl::CanDragEnter(
|
||||
blink::WebDragOperationsMask mask) {
|
||||
CefRefPtr<CefDragHandler> handler = client_->GetDragHandler();
|
||||
if (handler.get()) {
|
||||
CefRefPtr<CefDragData> drag_data(new CefDragDataImpl(data));
|
||||
if (handler->OnDragEnter(this, drag_data,
|
||||
static_cast<CefDragHandler::DragOperationsMask>(mask))) {
|
||||
CefRefPtr<CefDragDataImpl> drag_data(new CefDragDataImpl(data));
|
||||
drag_data->SetReadOnly(true);
|
||||
if (handler->OnDragEnter(
|
||||
this,
|
||||
drag_data.get(),
|
||||
static_cast<CefDragHandler::DragOperationsMask>(mask))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -2046,7 +2233,7 @@ void CefBrowserHostImpl::RequestMediaAccessPermission(
|
||||
// Based on chrome/browser/media/media_stream_devices_controller.cc
|
||||
bool microphone_requested =
|
||||
(request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE);
|
||||
bool webcam_requested =
|
||||
bool webcam_requested =
|
||||
(request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE);
|
||||
if (microphone_requested || webcam_requested) {
|
||||
switch (request.request_type) {
|
||||
@ -2089,8 +2276,9 @@ void CefBrowserHostImpl::RenderFrameCreated(
|
||||
|
||||
void CefBrowserHostImpl::RenderFrameDeleted(
|
||||
content::RenderFrameHost* render_frame_host) {
|
||||
browser_info_->remove_render_frame_id(render_frame_host->GetProcess()->GetID(),
|
||||
render_frame_host->GetRoutingID());
|
||||
browser_info_->remove_render_frame_id(
|
||||
render_frame_host->GetProcess()->GetID(),
|
||||
render_frame_host->GetRoutingID());
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::RenderViewCreated(
|
||||
@ -2515,7 +2703,7 @@ void CefBrowserHostImpl::DetachAllFrames() {
|
||||
void CefBrowserHostImpl::SetFocusedFrame(int64 frame_id) {
|
||||
CefRefPtr<CefFrameHostImpl> unfocused_frame;
|
||||
CefRefPtr<CefFrameHostImpl> focused_frame;
|
||||
|
||||
|
||||
{
|
||||
base::AutoLock lock_scope(state_lock_);
|
||||
|
||||
|
@ -171,6 +171,15 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
OVERRIDE;
|
||||
virtual void HandleKeyEventAfterTextInputClient(CefEventHandle keyEvent)
|
||||
OVERRIDE;
|
||||
virtual void DragTargetDragEnter(CefRefPtr<CefDragData> drag_data,
|
||||
const CefMouseEvent& event,
|
||||
DragOperationsMask allowed_ops);
|
||||
virtual void DragTargetDragOver(const CefMouseEvent& event,
|
||||
DragOperationsMask allowed_ops);
|
||||
virtual void DragTargetDragLeave();
|
||||
virtual void DragTargetDrop(const CefMouseEvent& event);
|
||||
virtual void DragSourceSystemDragEnded();
|
||||
virtual void DragSourceEndedAt(int x, int y, DragOperationsMask op);
|
||||
|
||||
// CefBrowser methods.
|
||||
virtual CefRefPtr<CefBrowserHost> GetHost() OVERRIDE;
|
||||
|
@ -3,11 +3,15 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "libcef/browser/browser_host_impl.h"
|
||||
#include "libcef/browser/render_widget_host_view_osr.h"
|
||||
#include "libcef/browser/web_contents_view_osr.h"
|
||||
#include "libcef/common/drag_data_impl.h"
|
||||
|
||||
#include "content/public/browser/render_widget_host.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/common/drop_data.h"
|
||||
#include "ui/base/dragdrop/drag_utils.h"
|
||||
|
||||
CefWebContentsViewOSR::CefWebContentsViewOSR(
|
||||
content::WebContents* web_contents,
|
||||
@ -134,8 +138,46 @@ void CefWebContentsViewOSR::StartDragging(
|
||||
const gfx::ImageSkia& image,
|
||||
const gfx::Vector2d& image_offset,
|
||||
const content::DragEventSourceInfo& event_info) {
|
||||
// Dragging is not supported when window rendering is disabled.
|
||||
web_contents_->SystemDragEnded();
|
||||
CefRefPtr<CefBrowserHostImpl> browser;
|
||||
CefRefPtr<CefRenderHandler> handler;
|
||||
bool handled = false;
|
||||
CefRenderWidgetHostViewOSR* view =
|
||||
static_cast<CefRenderWidgetHostViewOSR*>(view_);
|
||||
if (view)
|
||||
browser = view->get_browser_impl();
|
||||
if (browser.get())
|
||||
handler = browser->GetClient()->GetRenderHandler();
|
||||
DCHECK(handler.get());
|
||||
if (handler.get()) {
|
||||
CefRefPtr<CefDragDataImpl> drag_data(new CefDragDataImpl(drop_data));
|
||||
drag_data->SetReadOnly(true);
|
||||
base::MessageLoop::ScopedNestableTaskAllower allow(
|
||||
base::MessageLoop::current());
|
||||
handled = handler->StartDragging(browser->GetBrowser(),
|
||||
drag_data.get(),
|
||||
static_cast<CefRenderHandler::DragOperationsMask>(allowed_ops),
|
||||
event_info.event_location.x(),
|
||||
event_info.event_location.y());
|
||||
}
|
||||
if (!handled)
|
||||
web_contents_->SystemDragEnded();
|
||||
}
|
||||
|
||||
void CefWebContentsViewOSR::UpdateDragCursor(
|
||||
blink::WebDragOperation operation) {
|
||||
CefRefPtr<CefBrowserHostImpl> browser;
|
||||
CefRefPtr<CefRenderHandler> handler;
|
||||
CefRenderWidgetHostViewOSR* view =
|
||||
static_cast<CefRenderWidgetHostViewOSR*>(view_);
|
||||
if (view)
|
||||
browser = view->get_browser_impl();
|
||||
if (browser.get())
|
||||
handler = browser->GetClient()->GetRenderHandler();
|
||||
DCHECK(handler.get());
|
||||
if (handler.get()) {
|
||||
handler->UpdateDragCursor(browser->GetBrowser(),
|
||||
static_cast<CefRenderHandler::DragOperation>(operation));
|
||||
}
|
||||
}
|
||||
|
||||
void CefWebContentsViewOSR::ShowPopupMenu(
|
||||
|
@ -67,6 +67,7 @@ class CefWebContentsViewOSR : public content::WebContentsViewPort,
|
||||
const gfx::ImageSkia& image,
|
||||
const gfx::Vector2d& image_offset,
|
||||
const content::DragEventSourceInfo& event_info) OVERRIDE;
|
||||
virtual void UpdateDragCursor(blink::WebDragOperation operation) OVERRIDE;
|
||||
virtual void ShowPopupMenu(
|
||||
const gfx::Rect& bounds,
|
||||
int item_height,
|
||||
|
@ -2,55 +2,126 @@
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "libcef/browser/stream_impl.h"
|
||||
#include "libcef/common/drag_data_impl.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "net/base/net_util.h"
|
||||
|
||||
#define CHECK_READONLY_RETURN_VOID() \
|
||||
if (read_only_) { \
|
||||
NOTREACHED() << "object is read only"; \
|
||||
return; \
|
||||
}
|
||||
|
||||
CefDragDataImpl::CefDragDataImpl(const content::DropData& data)
|
||||
: data_(data) {
|
||||
: data_(data),
|
||||
read_only_(false) {
|
||||
}
|
||||
|
||||
CefDragDataImpl::CefDragDataImpl()
|
||||
: read_only_(false) {
|
||||
}
|
||||
|
||||
CefRefPtr<CefDragData> CefDragData::Create() {
|
||||
return new CefDragDataImpl();
|
||||
}
|
||||
|
||||
CefRefPtr<CefDragData> CefDragDataImpl::Clone() {
|
||||
CefDragDataImpl* drag_data = NULL;
|
||||
{
|
||||
AutoLock lock_scope(this);
|
||||
drag_data = new CefDragDataImpl(data_);
|
||||
}
|
||||
return drag_data;
|
||||
}
|
||||
|
||||
bool CefDragDataImpl::IsReadOnly() {
|
||||
AutoLock lock_scope(this);
|
||||
return read_only_;
|
||||
}
|
||||
|
||||
bool CefDragDataImpl::IsLink() {
|
||||
AutoLock lock_scope(this);
|
||||
return (data_.url.is_valid() && data_.file_description_filename.empty());
|
||||
}
|
||||
|
||||
bool CefDragDataImpl::IsFragment() {
|
||||
AutoLock lock_scope(this);
|
||||
return (!data_.url.is_valid() && data_.file_description_filename.empty() &&
|
||||
data_.filenames.empty());
|
||||
}
|
||||
|
||||
bool CefDragDataImpl::IsFile() {
|
||||
AutoLock lock_scope(this);
|
||||
return (!data_.file_description_filename.empty() || !data_.filenames.empty());
|
||||
}
|
||||
|
||||
CefString CefDragDataImpl::GetLinkURL() {
|
||||
AutoLock lock_scope(this);
|
||||
return data_.url.spec();
|
||||
}
|
||||
|
||||
CefString CefDragDataImpl::GetLinkTitle() {
|
||||
AutoLock lock_scope(this);
|
||||
return data_.url_title;
|
||||
}
|
||||
|
||||
CefString CefDragDataImpl::GetLinkMetadata() {
|
||||
AutoLock lock_scope(this);
|
||||
return data_.download_metadata;
|
||||
}
|
||||
|
||||
CefString CefDragDataImpl::GetFragmentText() {
|
||||
AutoLock lock_scope(this);
|
||||
return data_.text.is_null() ? CefString() : CefString(data_.text.string());
|
||||
}
|
||||
|
||||
CefString CefDragDataImpl::GetFragmentHtml() {
|
||||
AutoLock lock_scope(this);
|
||||
return data_.html.is_null() ? CefString() : CefString(data_.html.string());
|
||||
}
|
||||
|
||||
CefString CefDragDataImpl::GetFragmentBaseURL() {
|
||||
AutoLock lock_scope(this);
|
||||
return data_.html_base_url.spec();
|
||||
}
|
||||
|
||||
CefString CefDragDataImpl::GetFileName() {
|
||||
return data_.file_description_filename;
|
||||
AutoLock lock_scope(this);
|
||||
if (data_.file_description_filename.empty())
|
||||
return CefString();
|
||||
|
||||
base::FilePath file_name(CefString(data_.file_description_filename));
|
||||
// Images without ALT text will only have a file extension so we need to
|
||||
// synthesize one from the provided extension and URL.
|
||||
if (file_name.BaseName().RemoveExtension().empty()) {
|
||||
CefString extension = file_name.Extension();
|
||||
// Retrieve the name from the URL.
|
||||
CefString suggested_file_name =
|
||||
net::GetSuggestedFilename(data_.url, "", "", "", "", "");
|
||||
file_name = base::FilePath(suggested_file_name).ReplaceExtension(extension);
|
||||
}
|
||||
return file_name.value();
|
||||
}
|
||||
|
||||
size_t CefDragDataImpl::GetFileContents(CefRefPtr<CefStreamWriter> writer) {
|
||||
AutoLock lock_scope(this);
|
||||
if (data_.file_contents.empty())
|
||||
return 0;
|
||||
|
||||
char* data = const_cast<char*>(data_.file_contents.c_str());
|
||||
size_t size = data_.file_contents.size();
|
||||
|
||||
if (!writer.get())
|
||||
return size;
|
||||
|
||||
return writer->Write(data, 1, size);
|
||||
}
|
||||
|
||||
bool CefDragDataImpl::GetFileNames(std::vector<CefString>& names) {
|
||||
AutoLock lock_scope(this);
|
||||
if (data_.filenames.empty())
|
||||
return false;
|
||||
|
||||
@ -61,3 +132,62 @@ bool CefDragDataImpl::GetFileNames(std::vector<CefString>& names) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CefDragDataImpl::SetLinkURL(const CefString& url) {
|
||||
AutoLock lock_scope(this);
|
||||
CHECK_READONLY_RETURN_VOID();
|
||||
data_.url = GURL(url.ToString());
|
||||
}
|
||||
|
||||
void CefDragDataImpl::SetLinkTitle(const CefString& title) {
|
||||
AutoLock lock_scope(this);
|
||||
CHECK_READONLY_RETURN_VOID();
|
||||
data_.url_title = title.ToString16();
|
||||
}
|
||||
|
||||
void CefDragDataImpl::SetLinkMetadata(const CefString& data) {
|
||||
AutoLock lock_scope(this);
|
||||
CHECK_READONLY_RETURN_VOID();
|
||||
data_.download_metadata = data.ToString16();
|
||||
}
|
||||
|
||||
void CefDragDataImpl::SetFragmentText(const CefString& text) {
|
||||
AutoLock lock_scope(this);
|
||||
CHECK_READONLY_RETURN_VOID();
|
||||
data_.text = base::NullableString16(text.ToString16(), false);
|
||||
}
|
||||
|
||||
void CefDragDataImpl::SetFragmentHtml(const CefString& fragment) {
|
||||
AutoLock lock_scope(this);
|
||||
CHECK_READONLY_RETURN_VOID();
|
||||
data_.html = base::NullableString16(fragment.ToString16(), false);
|
||||
}
|
||||
|
||||
void CefDragDataImpl::SetFragmentBaseURL(const CefString& fragment) {
|
||||
AutoLock lock_scope(this);
|
||||
CHECK_READONLY_RETURN_VOID();
|
||||
data_.html_base_url = GURL(fragment.ToString());
|
||||
}
|
||||
|
||||
void CefDragDataImpl::ResetFileContents() {
|
||||
AutoLock lock_scope(this);
|
||||
CHECK_READONLY_RETURN_VOID();
|
||||
data_.file_contents.erase();
|
||||
data_.file_description_filename.erase();
|
||||
}
|
||||
|
||||
void CefDragDataImpl::AddFile(const CefString& path,
|
||||
const CefString& display_name) {
|
||||
AutoLock lock_scope(this);
|
||||
CHECK_READONLY_RETURN_VOID();
|
||||
data_.filenames.push_back(ui::FileInfo(base::FilePath(path),
|
||||
base::FilePath(display_name)));
|
||||
}
|
||||
|
||||
void CefDragDataImpl::SetReadOnly(bool read_only) {
|
||||
AutoLock lock_scope(this);
|
||||
if (read_only_ == read_only)
|
||||
return;
|
||||
|
||||
read_only_ = read_only;
|
||||
}
|
||||
|
@ -14,7 +14,10 @@
|
||||
// Implementation of CefDragData.
|
||||
class CefDragDataImpl : public CefDragData {
|
||||
public:
|
||||
CefDragDataImpl();
|
||||
explicit CefDragDataImpl(const content::DropData& data);
|
||||
virtual CefRefPtr<CefDragData> Clone();
|
||||
virtual bool IsReadOnly();
|
||||
|
||||
virtual bool IsLink();
|
||||
virtual bool IsFragment();
|
||||
@ -26,12 +29,33 @@ class CefDragDataImpl : public CefDragData {
|
||||
virtual CefString GetFragmentHtml();
|
||||
virtual CefString GetFragmentBaseURL();
|
||||
virtual CefString GetFileName();
|
||||
virtual size_t GetFileContents(CefRefPtr<CefStreamWriter> writer);
|
||||
virtual bool GetFileNames(std::vector<CefString>& names);
|
||||
|
||||
virtual void SetLinkURL(const CefString& url);
|
||||
virtual void SetLinkTitle(const CefString& title);
|
||||
virtual void SetLinkMetadata(const CefString& data);
|
||||
virtual void SetFragmentText(const CefString& text);
|
||||
virtual void SetFragmentHtml(const CefString& fragment);
|
||||
virtual void SetFragmentBaseURL(const CefString& fragment);
|
||||
virtual void ResetFileContents();
|
||||
virtual void AddFile(const CefString& path, const CefString& display_name);
|
||||
|
||||
// This method is not safe. Use Lock/Unlock to get mutually exclusive access.
|
||||
const content::DropData& drop_data() {
|
||||
return data_;
|
||||
}
|
||||
|
||||
void SetReadOnly(bool read_only);
|
||||
|
||||
protected:
|
||||
content::DropData data_;
|
||||
|
||||
// True if this object is read-only.
|
||||
bool read_only_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(CefDragDataImpl);
|
||||
IMPLEMENT_LOCKING(CefDragDataImpl);
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_COMMON_DRAG_DATA_IMPL_H_
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include "libcef_dll/cpptoc/browser_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/browser_host_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/drag_data_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/request_context_cpptoc.h"
|
||||
#include "libcef_dll/ctocpp/client_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/run_file_dialog_callback_ctocpp.h"
|
||||
@ -633,6 +634,122 @@ void CEF_CALLBACK browser_host_handle_key_event_after_text_input_client(
|
||||
keyEvent);
|
||||
}
|
||||
|
||||
void CEF_CALLBACK browser_host_drag_target_drag_enter(
|
||||
struct _cef_browser_host_t* self, struct _cef_drag_data_t* drag_data,
|
||||
const struct _cef_mouse_event_t* event,
|
||||
cef_drag_operations_mask_t allowed_ops) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Verify param: drag_data; type: refptr_same
|
||||
DCHECK(drag_data);
|
||||
if (!drag_data)
|
||||
return;
|
||||
// Verify param: event; type: struct_byref_const
|
||||
DCHECK(event);
|
||||
if (!event)
|
||||
return;
|
||||
|
||||
// Translate param: event; type: struct_byref_const
|
||||
CefMouseEvent eventObj;
|
||||
if (event)
|
||||
eventObj.Set(*event, false);
|
||||
|
||||
// Execute
|
||||
CefBrowserHostCppToC::Get(self)->DragTargetDragEnter(
|
||||
CefDragDataCppToC::Unwrap(drag_data),
|
||||
eventObj,
|
||||
allowed_ops);
|
||||
}
|
||||
|
||||
void CEF_CALLBACK browser_host_drag_target_drag_over(
|
||||
struct _cef_browser_host_t* self, const struct _cef_mouse_event_t* event,
|
||||
cef_drag_operations_mask_t allowed_ops) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Verify param: event; type: struct_byref_const
|
||||
DCHECK(event);
|
||||
if (!event)
|
||||
return;
|
||||
|
||||
// Translate param: event; type: struct_byref_const
|
||||
CefMouseEvent eventObj;
|
||||
if (event)
|
||||
eventObj.Set(*event, false);
|
||||
|
||||
// Execute
|
||||
CefBrowserHostCppToC::Get(self)->DragTargetDragOver(
|
||||
eventObj,
|
||||
allowed_ops);
|
||||
}
|
||||
|
||||
void CEF_CALLBACK browser_host_drag_target_drag_leave(
|
||||
struct _cef_browser_host_t* self) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
|
||||
// Execute
|
||||
CefBrowserHostCppToC::Get(self)->DragTargetDragLeave();
|
||||
}
|
||||
|
||||
void CEF_CALLBACK browser_host_drag_target_drop(
|
||||
struct _cef_browser_host_t* self, const struct _cef_mouse_event_t* event) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Verify param: event; type: struct_byref_const
|
||||
DCHECK(event);
|
||||
if (!event)
|
||||
return;
|
||||
|
||||
// Translate param: event; type: struct_byref_const
|
||||
CefMouseEvent eventObj;
|
||||
if (event)
|
||||
eventObj.Set(*event, false);
|
||||
|
||||
// Execute
|
||||
CefBrowserHostCppToC::Get(self)->DragTargetDrop(
|
||||
eventObj);
|
||||
}
|
||||
|
||||
void CEF_CALLBACK browser_host_drag_source_ended_at(
|
||||
struct _cef_browser_host_t* self, int x, int y,
|
||||
cef_drag_operations_mask_t op) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
|
||||
// Execute
|
||||
CefBrowserHostCppToC::Get(self)->DragSourceEndedAt(
|
||||
x,
|
||||
y,
|
||||
op);
|
||||
}
|
||||
|
||||
void CEF_CALLBACK browser_host_drag_source_system_drag_ended(
|
||||
struct _cef_browser_host_t* self) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
|
||||
// Execute
|
||||
CefBrowserHostCppToC::Get(self)->DragSourceSystemDragEnded();
|
||||
}
|
||||
|
||||
|
||||
// CONSTRUCTOR - Do not edit by hand.
|
||||
|
||||
@ -679,6 +796,13 @@ CefBrowserHostCppToC::CefBrowserHostCppToC(CefBrowserHost* cls)
|
||||
browser_host_handle_key_event_before_text_input_client;
|
||||
struct_.struct_.handle_key_event_after_text_input_client =
|
||||
browser_host_handle_key_event_after_text_input_client;
|
||||
struct_.struct_.drag_target_drag_enter = browser_host_drag_target_drag_enter;
|
||||
struct_.struct_.drag_target_drag_over = browser_host_drag_target_drag_over;
|
||||
struct_.struct_.drag_target_drag_leave = browser_host_drag_target_drag_leave;
|
||||
struct_.struct_.drag_target_drop = browser_host_drag_target_drop;
|
||||
struct_.struct_.drag_source_ended_at = browser_host_drag_source_ended_at;
|
||||
struct_.struct_.drag_source_system_drag_ended =
|
||||
browser_host_drag_source_system_drag_ended;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
@ -11,11 +11,54 @@
|
||||
//
|
||||
|
||||
#include "libcef_dll/cpptoc/drag_data_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/stream_writer_cpptoc.h"
|
||||
#include "libcef_dll/transfer_util.h"
|
||||
|
||||
|
||||
// GLOBAL FUNCTIONS - Body may be edited by hand.
|
||||
|
||||
CEF_EXPORT cef_drag_data_t* cef_drag_data_create() {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
CefRefPtr<CefDragData> _retval = CefDragData::Create();
|
||||
|
||||
// Return type: refptr_same
|
||||
return CefDragDataCppToC::Wrap(_retval);
|
||||
}
|
||||
|
||||
|
||||
// MEMBER FUNCTIONS - Body may be edited by hand.
|
||||
|
||||
struct _cef_drag_data_t* CEF_CALLBACK drag_data_clone(
|
||||
struct _cef_drag_data_t* self) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return NULL;
|
||||
|
||||
// Execute
|
||||
CefRefPtr<CefDragData> _retval = CefDragDataCppToC::Get(self)->Clone();
|
||||
|
||||
// Return type: refptr_same
|
||||
return CefDragDataCppToC::Wrap(_retval);
|
||||
}
|
||||
|
||||
int CEF_CALLBACK drag_data_is_read_only(struct _cef_drag_data_t* self) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return 0;
|
||||
|
||||
// Execute
|
||||
bool _retval = CefDragDataCppToC::Get(self)->IsReadOnly();
|
||||
|
||||
// Return type: bool
|
||||
return _retval;
|
||||
}
|
||||
|
||||
int CEF_CALLBACK drag_data_is_link(struct _cef_drag_data_t* self) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
@ -163,6 +206,23 @@ cef_string_userfree_t CEF_CALLBACK drag_data_get_file_name(
|
||||
return _retval.DetachToUserFree();
|
||||
}
|
||||
|
||||
size_t CEF_CALLBACK drag_data_get_file_contents(struct _cef_drag_data_t* self,
|
||||
struct _cef_stream_writer_t* writer) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return 0;
|
||||
// Unverified params: writer
|
||||
|
||||
// Execute
|
||||
size_t _retval = CefDragDataCppToC::Get(self)->GetFileContents(
|
||||
CefStreamWriterCppToC::Unwrap(writer));
|
||||
|
||||
// Return type: simple
|
||||
return _retval;
|
||||
}
|
||||
|
||||
int CEF_CALLBACK drag_data_get_file_names(struct _cef_drag_data_t* self,
|
||||
cef_string_list_t names) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
@ -191,11 +251,127 @@ int CEF_CALLBACK drag_data_get_file_names(struct _cef_drag_data_t* self,
|
||||
return _retval;
|
||||
}
|
||||
|
||||
void CEF_CALLBACK drag_data_set_link_url(struct _cef_drag_data_t* self,
|
||||
const cef_string_t* url) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Unverified params: url
|
||||
|
||||
// Execute
|
||||
CefDragDataCppToC::Get(self)->SetLinkURL(
|
||||
CefString(url));
|
||||
}
|
||||
|
||||
void CEF_CALLBACK drag_data_set_link_title(struct _cef_drag_data_t* self,
|
||||
const cef_string_t* title) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Unverified params: title
|
||||
|
||||
// Execute
|
||||
CefDragDataCppToC::Get(self)->SetLinkTitle(
|
||||
CefString(title));
|
||||
}
|
||||
|
||||
void CEF_CALLBACK drag_data_set_link_metadata(struct _cef_drag_data_t* self,
|
||||
const cef_string_t* data) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Unverified params: data
|
||||
|
||||
// Execute
|
||||
CefDragDataCppToC::Get(self)->SetLinkMetadata(
|
||||
CefString(data));
|
||||
}
|
||||
|
||||
void CEF_CALLBACK drag_data_set_fragment_text(struct _cef_drag_data_t* self,
|
||||
const cef_string_t* text) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Unverified params: text
|
||||
|
||||
// Execute
|
||||
CefDragDataCppToC::Get(self)->SetFragmentText(
|
||||
CefString(text));
|
||||
}
|
||||
|
||||
void CEF_CALLBACK drag_data_set_fragment_html(struct _cef_drag_data_t* self,
|
||||
const cef_string_t* html) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Unverified params: html
|
||||
|
||||
// Execute
|
||||
CefDragDataCppToC::Get(self)->SetFragmentHtml(
|
||||
CefString(html));
|
||||
}
|
||||
|
||||
void CEF_CALLBACK drag_data_set_fragment_base_url(struct _cef_drag_data_t* self,
|
||||
const cef_string_t* base_url) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Unverified params: base_url
|
||||
|
||||
// Execute
|
||||
CefDragDataCppToC::Get(self)->SetFragmentBaseURL(
|
||||
CefString(base_url));
|
||||
}
|
||||
|
||||
void CEF_CALLBACK drag_data_reset_file_contents(struct _cef_drag_data_t* self) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
|
||||
// Execute
|
||||
CefDragDataCppToC::Get(self)->ResetFileContents();
|
||||
}
|
||||
|
||||
void CEF_CALLBACK drag_data_add_file(struct _cef_drag_data_t* self,
|
||||
const cef_string_t* path, const cef_string_t* display_name) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Verify param: path; type: string_byref_const
|
||||
DCHECK(path);
|
||||
if (!path)
|
||||
return;
|
||||
// Unverified params: display_name
|
||||
|
||||
// Execute
|
||||
CefDragDataCppToC::Get(self)->AddFile(
|
||||
CefString(path),
|
||||
CefString(display_name));
|
||||
}
|
||||
|
||||
|
||||
// CONSTRUCTOR - Do not edit by hand.
|
||||
|
||||
CefDragDataCppToC::CefDragDataCppToC(CefDragData* cls)
|
||||
: CefCppToC<CefDragDataCppToC, CefDragData, cef_drag_data_t>(cls) {
|
||||
struct_.struct_.clone = drag_data_clone;
|
||||
struct_.struct_.is_read_only = drag_data_is_read_only;
|
||||
struct_.struct_.is_link = drag_data_is_link;
|
||||
struct_.struct_.is_fragment = drag_data_is_fragment;
|
||||
struct_.struct_.is_file = drag_data_is_file;
|
||||
@ -206,7 +382,16 @@ CefDragDataCppToC::CefDragDataCppToC(CefDragData* cls)
|
||||
struct_.struct_.get_fragment_html = drag_data_get_fragment_html;
|
||||
struct_.struct_.get_fragment_base_url = drag_data_get_fragment_base_url;
|
||||
struct_.struct_.get_file_name = drag_data_get_file_name;
|
||||
struct_.struct_.get_file_contents = drag_data_get_file_contents;
|
||||
struct_.struct_.get_file_names = drag_data_get_file_names;
|
||||
struct_.struct_.set_link_url = drag_data_set_link_url;
|
||||
struct_.struct_.set_link_title = drag_data_set_link_title;
|
||||
struct_.struct_.set_link_metadata = drag_data_set_link_metadata;
|
||||
struct_.struct_.set_fragment_text = drag_data_set_fragment_text;
|
||||
struct_.struct_.set_fragment_html = drag_data_set_fragment_html;
|
||||
struct_.struct_.set_fragment_base_url = drag_data_set_fragment_base_url;
|
||||
struct_.struct_.reset_file_contents = drag_data_reset_file_contents;
|
||||
struct_.struct_.add_file = drag_data_add_file;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include "libcef_dll/cpptoc/render_handler_cpptoc.h"
|
||||
#include "libcef_dll/ctocpp/browser_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/drag_data_ctocpp.h"
|
||||
|
||||
|
||||
// MEMBER FUNCTIONS - Body may be edited by hand.
|
||||
@ -265,6 +266,55 @@ void CEF_CALLBACK render_handler_on_cursor_change(
|
||||
cursor);
|
||||
}
|
||||
|
||||
int CEF_CALLBACK render_handler_start_dragging(
|
||||
struct _cef_render_handler_t* self, cef_browser_t* browser,
|
||||
cef_drag_data_t* drag_data, cef_drag_operations_mask_t allowed_ops, int x,
|
||||
int y) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return 0;
|
||||
// Verify param: browser; type: refptr_diff
|
||||
DCHECK(browser);
|
||||
if (!browser)
|
||||
return 0;
|
||||
// Verify param: drag_data; type: refptr_diff
|
||||
DCHECK(drag_data);
|
||||
if (!drag_data)
|
||||
return 0;
|
||||
|
||||
// Execute
|
||||
bool _retval = CefRenderHandlerCppToC::Get(self)->StartDragging(
|
||||
CefBrowserCToCpp::Wrap(browser),
|
||||
CefDragDataCToCpp::Wrap(drag_data),
|
||||
allowed_ops,
|
||||
x,
|
||||
y);
|
||||
|
||||
// Return type: bool
|
||||
return _retval;
|
||||
}
|
||||
|
||||
void CEF_CALLBACK render_handler_update_drag_cursor(
|
||||
struct _cef_render_handler_t* self, cef_browser_t* browser,
|
||||
cef_drag_operations_mask_t operation) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Verify param: browser; type: refptr_diff
|
||||
DCHECK(browser);
|
||||
if (!browser)
|
||||
return;
|
||||
|
||||
// Execute
|
||||
CefRenderHandlerCppToC::Get(self)->UpdateDragCursor(
|
||||
CefBrowserCToCpp::Wrap(browser),
|
||||
operation);
|
||||
}
|
||||
|
||||
void CEF_CALLBACK render_handler_on_scroll_offset_changed(
|
||||
struct _cef_render_handler_t* self, cef_browser_t* browser) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
@ -296,6 +346,8 @@ CefRenderHandlerCppToC::CefRenderHandlerCppToC(CefRenderHandler* cls)
|
||||
struct_.struct_.on_popup_size = render_handler_on_popup_size;
|
||||
struct_.struct_.on_paint = render_handler_on_paint;
|
||||
struct_.struct_.on_cursor_change = render_handler_on_cursor_change;
|
||||
struct_.struct_.start_dragging = render_handler_start_dragging;
|
||||
struct_.struct_.update_drag_cursor = render_handler_update_drag_cursor;
|
||||
struct_.struct_.on_scroll_offset_changed =
|
||||
render_handler_on_scroll_offset_changed;
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "libcef_dll/cpptoc/run_file_dialog_callback_cpptoc.h"
|
||||
#include "libcef_dll/ctocpp/browser_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/browser_host_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/drag_data_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/request_context_ctocpp.h"
|
||||
#include "libcef_dll/transfer_util.h"
|
||||
|
||||
@ -487,6 +488,83 @@ void CefBrowserHostCToCpp::HandleKeyEventAfterTextInputClient(
|
||||
keyEvent);
|
||||
}
|
||||
|
||||
void CefBrowserHostCToCpp::DragTargetDragEnter(CefRefPtr<CefDragData> drag_data,
|
||||
const CefMouseEvent& event, DragOperationsMask allowed_ops) {
|
||||
if (CEF_MEMBER_MISSING(struct_, drag_target_drag_enter))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: drag_data; type: refptr_same
|
||||
DCHECK(drag_data.get());
|
||||
if (!drag_data.get())
|
||||
return;
|
||||
|
||||
// Execute
|
||||
struct_->drag_target_drag_enter(struct_,
|
||||
CefDragDataCToCpp::Unwrap(drag_data),
|
||||
&event,
|
||||
allowed_ops);
|
||||
}
|
||||
|
||||
void CefBrowserHostCToCpp::DragTargetDragOver(const CefMouseEvent& event,
|
||||
DragOperationsMask allowed_ops) {
|
||||
if (CEF_MEMBER_MISSING(struct_, drag_target_drag_over))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
struct_->drag_target_drag_over(struct_,
|
||||
&event,
|
||||
allowed_ops);
|
||||
}
|
||||
|
||||
void CefBrowserHostCToCpp::DragTargetDragLeave() {
|
||||
if (CEF_MEMBER_MISSING(struct_, drag_target_drag_leave))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
struct_->drag_target_drag_leave(struct_);
|
||||
}
|
||||
|
||||
void CefBrowserHostCToCpp::DragTargetDrop(const CefMouseEvent& event) {
|
||||
if (CEF_MEMBER_MISSING(struct_, drag_target_drop))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
struct_->drag_target_drop(struct_,
|
||||
&event);
|
||||
}
|
||||
|
||||
void CefBrowserHostCToCpp::DragSourceEndedAt(int x, int y,
|
||||
DragOperationsMask op) {
|
||||
if (CEF_MEMBER_MISSING(struct_, drag_source_ended_at))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
struct_->drag_source_ended_at(struct_,
|
||||
x,
|
||||
y,
|
||||
op);
|
||||
}
|
||||
|
||||
void CefBrowserHostCToCpp::DragSourceSystemDragEnded() {
|
||||
if (CEF_MEMBER_MISSING(struct_, drag_source_system_drag_ended))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
struct_->drag_source_system_drag_ended(struct_);
|
||||
}
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
template<> long CefCToCpp<CefBrowserHostCToCpp, CefBrowserHost,
|
||||
|
@ -81,6 +81,14 @@ class CefBrowserHostCToCpp
|
||||
CefEventHandle keyEvent) OVERRIDE;
|
||||
virtual void HandleKeyEventAfterTextInputClient(
|
||||
CefEventHandle keyEvent) OVERRIDE;
|
||||
virtual void DragTargetDragEnter(CefRefPtr<CefDragData> drag_data,
|
||||
const CefMouseEvent& event, DragOperationsMask allowed_ops) OVERRIDE;
|
||||
virtual void DragTargetDragOver(const CefMouseEvent& event,
|
||||
DragOperationsMask allowed_ops) OVERRIDE;
|
||||
virtual void DragTargetDragLeave() OVERRIDE;
|
||||
virtual void DragTargetDrop(const CefMouseEvent& event) OVERRIDE;
|
||||
virtual void DragSourceEndedAt(int x, int y, DragOperationsMask op) OVERRIDE;
|
||||
virtual void DragSourceSystemDragEnded() OVERRIDE;
|
||||
};
|
||||
|
||||
#endif // USING_CEF_SHARED
|
||||
|
@ -11,11 +11,51 @@
|
||||
//
|
||||
|
||||
#include "libcef_dll/ctocpp/drag_data_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/stream_writer_ctocpp.h"
|
||||
#include "libcef_dll/transfer_util.h"
|
||||
|
||||
|
||||
// STATIC METHODS - Body may be edited by hand.
|
||||
|
||||
CefRefPtr<CefDragData> CefDragData::Create() {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
cef_drag_data_t* _retval = cef_drag_data_create();
|
||||
|
||||
// Return type: refptr_same
|
||||
return CefDragDataCToCpp::Wrap(_retval);
|
||||
}
|
||||
|
||||
|
||||
// VIRTUAL METHODS - Body may be edited by hand.
|
||||
|
||||
CefRefPtr<CefDragData> CefDragDataCToCpp::Clone() {
|
||||
if (CEF_MEMBER_MISSING(struct_, clone))
|
||||
return NULL;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
cef_drag_data_t* _retval = struct_->clone(struct_);
|
||||
|
||||
// Return type: refptr_same
|
||||
return CefDragDataCToCpp::Wrap(_retval);
|
||||
}
|
||||
|
||||
bool CefDragDataCToCpp::IsReadOnly() {
|
||||
if (CEF_MEMBER_MISSING(struct_, is_read_only))
|
||||
return false;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
int _retval = struct_->is_read_only(struct_);
|
||||
|
||||
// Return type: bool
|
||||
return _retval?true:false;
|
||||
}
|
||||
|
||||
bool CefDragDataCToCpp::IsLink() {
|
||||
if (CEF_MEMBER_MISSING(struct_, is_link))
|
||||
return false;
|
||||
@ -160,6 +200,22 @@ CefString CefDragDataCToCpp::GetFileName() {
|
||||
return _retvalStr;
|
||||
}
|
||||
|
||||
size_t CefDragDataCToCpp::GetFileContents(CefRefPtr<CefStreamWriter> writer) {
|
||||
if (CEF_MEMBER_MISSING(struct_, get_file_contents))
|
||||
return 0;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Unverified params: writer
|
||||
|
||||
// Execute
|
||||
size_t _retval = struct_->get_file_contents(struct_,
|
||||
CefStreamWriterCToCpp::Unwrap(writer));
|
||||
|
||||
// Return type: simple
|
||||
return _retval;
|
||||
}
|
||||
|
||||
bool CefDragDataCToCpp::GetFileNames(std::vector<CefString>& names) {
|
||||
if (CEF_MEMBER_MISSING(struct_, get_file_names))
|
||||
return false;
|
||||
@ -187,6 +243,113 @@ bool CefDragDataCToCpp::GetFileNames(std::vector<CefString>& names) {
|
||||
return _retval?true:false;
|
||||
}
|
||||
|
||||
void CefDragDataCToCpp::SetLinkURL(const CefString& url) {
|
||||
if (CEF_MEMBER_MISSING(struct_, set_link_url))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Unverified params: url
|
||||
|
||||
// Execute
|
||||
struct_->set_link_url(struct_,
|
||||
url.GetStruct());
|
||||
}
|
||||
|
||||
void CefDragDataCToCpp::SetLinkTitle(const CefString& title) {
|
||||
if (CEF_MEMBER_MISSING(struct_, set_link_title))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Unverified params: title
|
||||
|
||||
// Execute
|
||||
struct_->set_link_title(struct_,
|
||||
title.GetStruct());
|
||||
}
|
||||
|
||||
void CefDragDataCToCpp::SetLinkMetadata(const CefString& data) {
|
||||
if (CEF_MEMBER_MISSING(struct_, set_link_metadata))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Unverified params: data
|
||||
|
||||
// Execute
|
||||
struct_->set_link_metadata(struct_,
|
||||
data.GetStruct());
|
||||
}
|
||||
|
||||
void CefDragDataCToCpp::SetFragmentText(const CefString& text) {
|
||||
if (CEF_MEMBER_MISSING(struct_, set_fragment_text))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Unverified params: text
|
||||
|
||||
// Execute
|
||||
struct_->set_fragment_text(struct_,
|
||||
text.GetStruct());
|
||||
}
|
||||
|
||||
void CefDragDataCToCpp::SetFragmentHtml(const CefString& html) {
|
||||
if (CEF_MEMBER_MISSING(struct_, set_fragment_html))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Unverified params: html
|
||||
|
||||
// Execute
|
||||
struct_->set_fragment_html(struct_,
|
||||
html.GetStruct());
|
||||
}
|
||||
|
||||
void CefDragDataCToCpp::SetFragmentBaseURL(const CefString& base_url) {
|
||||
if (CEF_MEMBER_MISSING(struct_, set_fragment_base_url))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Unverified params: base_url
|
||||
|
||||
// Execute
|
||||
struct_->set_fragment_base_url(struct_,
|
||||
base_url.GetStruct());
|
||||
}
|
||||
|
||||
void CefDragDataCToCpp::ResetFileContents() {
|
||||
if (CEF_MEMBER_MISSING(struct_, reset_file_contents))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
struct_->reset_file_contents(struct_);
|
||||
}
|
||||
|
||||
void CefDragDataCToCpp::AddFile(const CefString& path,
|
||||
const CefString& display_name) {
|
||||
if (CEF_MEMBER_MISSING(struct_, add_file))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: path; type: string_byref_const
|
||||
DCHECK(!path.empty());
|
||||
if (path.empty())
|
||||
return;
|
||||
// Unverified params: display_name
|
||||
|
||||
// Execute
|
||||
struct_->add_file(struct_,
|
||||
path.GetStruct(),
|
||||
display_name.GetStruct());
|
||||
}
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
template<> long CefCToCpp<CefDragDataCToCpp, CefDragData,
|
||||
|
@ -33,6 +33,8 @@ class CefDragDataCToCpp
|
||||
virtual ~CefDragDataCToCpp() {}
|
||||
|
||||
// CefDragData methods
|
||||
virtual CefRefPtr<CefDragData> Clone() OVERRIDE;
|
||||
virtual bool IsReadOnly() OVERRIDE;
|
||||
virtual bool IsLink() OVERRIDE;
|
||||
virtual bool IsFragment() OVERRIDE;
|
||||
virtual bool IsFile() OVERRIDE;
|
||||
@ -43,7 +45,17 @@ class CefDragDataCToCpp
|
||||
virtual CefString GetFragmentHtml() OVERRIDE;
|
||||
virtual CefString GetFragmentBaseURL() OVERRIDE;
|
||||
virtual CefString GetFileName() OVERRIDE;
|
||||
virtual size_t GetFileContents(CefRefPtr<CefStreamWriter> writer) OVERRIDE;
|
||||
virtual bool GetFileNames(std::vector<CefString>& names) OVERRIDE;
|
||||
virtual void SetLinkURL(const CefString& url) OVERRIDE;
|
||||
virtual void SetLinkTitle(const CefString& title) OVERRIDE;
|
||||
virtual void SetLinkMetadata(const CefString& data) OVERRIDE;
|
||||
virtual void SetFragmentText(const CefString& text) OVERRIDE;
|
||||
virtual void SetFragmentHtml(const CefString& html) OVERRIDE;
|
||||
virtual void SetFragmentBaseURL(const CefString& base_url) OVERRIDE;
|
||||
virtual void ResetFileContents() OVERRIDE;
|
||||
virtual void AddFile(const CefString& path,
|
||||
const CefString& display_name) OVERRIDE;
|
||||
};
|
||||
|
||||
#endif // USING_CEF_SHARED
|
||||
|
@ -11,6 +11,7 @@
|
||||
//
|
||||
|
||||
#include "libcef_dll/cpptoc/browser_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/drag_data_cpptoc.h"
|
||||
#include "libcef_dll/ctocpp/render_handler_ctocpp.h"
|
||||
|
||||
|
||||
@ -202,6 +203,53 @@ void CefRenderHandlerCToCpp::OnCursorChange(CefRefPtr<CefBrowser> browser,
|
||||
cursor);
|
||||
}
|
||||
|
||||
bool CefRenderHandlerCToCpp::StartDragging(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefDragData> drag_data, DragOperationsMask allowed_ops, int x,
|
||||
int y) {
|
||||
if (CEF_MEMBER_MISSING(struct_, start_dragging))
|
||||
return false;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: browser; type: refptr_diff
|
||||
DCHECK(browser.get());
|
||||
if (!browser.get())
|
||||
return false;
|
||||
// Verify param: drag_data; type: refptr_diff
|
||||
DCHECK(drag_data.get());
|
||||
if (!drag_data.get())
|
||||
return false;
|
||||
|
||||
// Execute
|
||||
int _retval = struct_->start_dragging(struct_,
|
||||
CefBrowserCppToC::Wrap(browser),
|
||||
CefDragDataCppToC::Wrap(drag_data),
|
||||
allowed_ops,
|
||||
x,
|
||||
y);
|
||||
|
||||
// Return type: bool
|
||||
return _retval?true:false;
|
||||
}
|
||||
|
||||
void CefRenderHandlerCToCpp::UpdateDragCursor(CefRefPtr<CefBrowser> browser,
|
||||
DragOperation operation) {
|
||||
if (CEF_MEMBER_MISSING(struct_, update_drag_cursor))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: browser; type: refptr_diff
|
||||
DCHECK(browser.get());
|
||||
if (!browser.get())
|
||||
return;
|
||||
|
||||
// Execute
|
||||
struct_->update_drag_cursor(struct_,
|
||||
CefBrowserCppToC::Wrap(browser),
|
||||
operation);
|
||||
}
|
||||
|
||||
void CefRenderHandlerCToCpp::OnScrollOffsetChanged(
|
||||
CefRefPtr<CefBrowser> browser) {
|
||||
if (CEF_MEMBER_MISSING(struct_, on_scroll_offset_changed))
|
||||
|
@ -50,6 +50,11 @@ class CefRenderHandlerCToCpp
|
||||
int height) OVERRIDE;
|
||||
virtual void OnCursorChange(CefRefPtr<CefBrowser> browser,
|
||||
CefCursorHandle cursor) OVERRIDE;
|
||||
virtual bool StartDragging(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefDragData> drag_data, DragOperationsMask allowed_ops, int x,
|
||||
int y) OVERRIDE;
|
||||
virtual void UpdateDragCursor(CefRefPtr<CefBrowser> browser,
|
||||
DragOperation operation) OVERRIDE;
|
||||
virtual void OnScrollOffsetChanged(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||
};
|
||||
|
||||
|
92
tests/cefclient/bytes_write_handler.cpp
Normal file
92
tests/cefclient/bytes_write_handler.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#include "cefclient/bytes_write_handler.h"
|
||||
|
||||
#include "cefclient/util.h"
|
||||
|
||||
BytesWriteHandler::BytesWriteHandler(size_t grow)
|
||||
: grow_(grow),
|
||||
datasize_(grow),
|
||||
offset_(0) {
|
||||
ASSERT(grow > 0); // NOLINT(readability/check)
|
||||
data_ = malloc(grow);
|
||||
ASSERT(data_ != NULL);
|
||||
}
|
||||
|
||||
BytesWriteHandler::~BytesWriteHandler() {
|
||||
AutoLock lock_scope(this);
|
||||
if (data_)
|
||||
free(data_);
|
||||
}
|
||||
|
||||
size_t BytesWriteHandler::Write(const void* ptr, size_t size, size_t n) {
|
||||
AutoLock lock_scope(this);
|
||||
size_t rv;
|
||||
if (offset_ + static_cast<int64>(size * n) >= datasize_ &&
|
||||
Grow(size * n) == 0) {
|
||||
rv = 0;
|
||||
} else {
|
||||
memcpy(reinterpret_cast<char*>(data_) + offset_, ptr, size * n);
|
||||
offset_ += size * n;
|
||||
rv = n;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int BytesWriteHandler::Seek(int64 offset, int whence) {
|
||||
int rv = -1L;
|
||||
AutoLock lock_scope(this);
|
||||
switch (whence) {
|
||||
case SEEK_CUR:
|
||||
if (offset_ + offset > datasize_ || offset_ + offset < 0)
|
||||
break;
|
||||
offset_ += offset;
|
||||
rv = 0;
|
||||
break;
|
||||
case SEEK_END: {
|
||||
int64 offset_abs = abs(offset);
|
||||
if (offset_abs > datasize_)
|
||||
break;
|
||||
offset_ = datasize_ - offset_abs;
|
||||
rv = 0;
|
||||
break;
|
||||
}
|
||||
case SEEK_SET:
|
||||
if (offset > datasize_ || offset < 0)
|
||||
break;
|
||||
offset_ = offset;
|
||||
rv = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int64 BytesWriteHandler::Tell() {
|
||||
AutoLock lock_scope(this);
|
||||
return offset_;
|
||||
}
|
||||
|
||||
int BytesWriteHandler::Flush() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t BytesWriteHandler::Grow(size_t size) {
|
||||
AutoLock lock_scope(this);
|
||||
size_t rv;
|
||||
size_t s = (size > grow_ ? size : grow_);
|
||||
void* tmp = realloc(data_, datasize_ + s);
|
||||
ASSERT(tmp != NULL);
|
||||
if (tmp) {
|
||||
data_ = tmp;
|
||||
datasize_ += s;
|
||||
rv = datasize_;
|
||||
} else {
|
||||
rv = 0;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
37
tests/cefclient/bytes_write_handler.h
Normal file
37
tests/cefclient/bytes_write_handler.h
Normal file
@ -0,0 +1,37 @@
|
||||
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_TESTS_CEFCLIENT_BYTES_WRITE_HANDLER_H_
|
||||
#define CEF_TESTS_CEFCLIENT_BYTES_WRITE_HANDLER_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/cef_stream.h"
|
||||
|
||||
class BytesWriteHandler : public CefWriteHandler {
|
||||
public:
|
||||
explicit BytesWriteHandler(size_t grow);
|
||||
virtual ~BytesWriteHandler();
|
||||
|
||||
virtual size_t Write(const void* ptr, size_t size, size_t n) OVERRIDE;
|
||||
virtual int Seek(int64 offset, int whence) OVERRIDE;
|
||||
virtual int64 Tell() OVERRIDE;
|
||||
virtual int Flush() OVERRIDE;
|
||||
virtual bool MayBlock() OVERRIDE { return false; }
|
||||
|
||||
void* GetData() { return data_; }
|
||||
int64 GetDataSize() { return offset_; }
|
||||
|
||||
protected:
|
||||
size_t Grow(size_t size);
|
||||
|
||||
size_t grow_;
|
||||
void* data_;
|
||||
int64 datasize_;
|
||||
int64 offset_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(BytesWriteHandler);
|
||||
IMPLEMENT_LOCKING(BytesWriteHandler);
|
||||
};
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_BYTES_WRITE_HANDLER_H_
|
649
tests/cefclient/cefclient_osr_dragdrop_win.cpp
Normal file
649
tests/cefclient/cefclient_osr_dragdrop_win.cpp
Normal file
@ -0,0 +1,649 @@
|
||||
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#include "cefclient/cefclient_osr_dragdrop_win.h"
|
||||
|
||||
#include <shellapi.h>
|
||||
#include <shlobj.h>
|
||||
#include <windowsx.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include "include/cef_runnable.h"
|
||||
#include "cefclient/bytes_write_handler.h"
|
||||
#include "cefclient/cefclient_osr_widget_win.h"
|
||||
#include "cefclient/resource.h"
|
||||
#include "cefclient/util.h"
|
||||
|
||||
namespace {
|
||||
|
||||
DWORD DragOperationToDropEffect(CefRenderHandler::DragOperation allowed_ops) {
|
||||
DWORD effect = DROPEFFECT_NONE;
|
||||
if (allowed_ops & DRAG_OPERATION_COPY)
|
||||
effect |= DROPEFFECT_COPY;
|
||||
if (allowed_ops & DRAG_OPERATION_LINK)
|
||||
effect |= DROPEFFECT_LINK;
|
||||
if (allowed_ops & DRAG_OPERATION_MOVE)
|
||||
effect |= DROPEFFECT_MOVE;
|
||||
return effect;
|
||||
}
|
||||
|
||||
CefRenderHandler::DragOperationsMask DropEffectToDragOperation(DWORD effect) {
|
||||
DWORD operation = DRAG_OPERATION_NONE;
|
||||
if (effect & DROPEFFECT_COPY)
|
||||
operation |= DRAG_OPERATION_COPY;
|
||||
if (effect & DROPEFFECT_LINK)
|
||||
operation |= DRAG_OPERATION_LINK;
|
||||
if (effect & DROPEFFECT_MOVE)
|
||||
operation |= DRAG_OPERATION_MOVE;
|
||||
return static_cast<CefRenderHandler::DragOperationsMask>(operation);
|
||||
}
|
||||
|
||||
CefMouseEvent ToMouseEvent(POINTL p, DWORD key_state, HWND hWnd) {
|
||||
CefMouseEvent ev;
|
||||
POINT screen_point = { p.x, p.y };
|
||||
ScreenToClient(hWnd, &screen_point);
|
||||
ev.x = screen_point.x;
|
||||
ev.y = screen_point.y;
|
||||
ev.modifiers = OSRWindow::GetCefMouseModifiers(key_state);
|
||||
return ev;
|
||||
}
|
||||
|
||||
|
||||
void GetStorageForBytes(STGMEDIUM* storage, const void* data, size_t bytes) {
|
||||
HANDLE handle = GlobalAlloc(GPTR, static_cast<int>(bytes));
|
||||
if (handle) {
|
||||
memcpy(handle, data, bytes);
|
||||
}
|
||||
|
||||
storage->hGlobal = handle;
|
||||
storage->tymed = TYMED_HGLOBAL;
|
||||
storage->pUnkForRelease = NULL;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void GetStorageForString(STGMEDIUM* stgmed, const std::basic_string<T>& data) {
|
||||
GetStorageForBytes(stgmed, data.c_str(),
|
||||
(data.size() + 1) * sizeof(std::basic_string<T>::value_type));
|
||||
}
|
||||
|
||||
void GetStorageForFileDescriptor(STGMEDIUM* storage,
|
||||
const std::wstring& file_name) {
|
||||
ASSERT(!file_name.empty());
|
||||
HANDLE hdata = GlobalAlloc(GPTR, sizeof(FILEGROUPDESCRIPTOR));
|
||||
|
||||
FILEGROUPDESCRIPTOR* descriptor =
|
||||
reinterpret_cast<FILEGROUPDESCRIPTOR*>(hdata);
|
||||
descriptor->cItems = 1;
|
||||
descriptor->fgd[0].dwFlags = FD_LINKUI;
|
||||
wcsncpy_s(descriptor->fgd[0].cFileName, MAX_PATH, file_name.c_str(),
|
||||
std::min(file_name.size(), static_cast<size_t>(MAX_PATH - 1u)));
|
||||
|
||||
storage->tymed = TYMED_HGLOBAL;
|
||||
storage->hGlobal = hdata;
|
||||
storage->pUnkForRelease = NULL;
|
||||
}
|
||||
|
||||
// Helper method for converting from text/html to MS CF_HTML.
|
||||
// Documentation for the CF_HTML format is available at
|
||||
// http://msdn.microsoft.com/en-us/library/aa767917(VS.85).aspx
|
||||
std::string HtmlToCFHtml(const std::string& html, const std::string& base_url) {
|
||||
if (html.empty())
|
||||
return std::string();
|
||||
|
||||
#define MAX_DIGITS 10
|
||||
#define MAKE_NUMBER_FORMAT_1(digits) MAKE_NUMBER_FORMAT_2(digits)
|
||||
#define MAKE_NUMBER_FORMAT_2(digits) "%0" #digits "u"
|
||||
#define NUMBER_FORMAT MAKE_NUMBER_FORMAT_1(MAX_DIGITS)
|
||||
|
||||
static const char* header = "Version:0.9\r\n"
|
||||
"StartHTML:" NUMBER_FORMAT "\r\n"
|
||||
"EndHTML:" NUMBER_FORMAT "\r\n"
|
||||
"StartFragment:" NUMBER_FORMAT "\r\n"
|
||||
"EndFragment:" NUMBER_FORMAT "\r\n";
|
||||
static const char* source_url_prefix = "SourceURL:";
|
||||
|
||||
static const char* start_markup = "<html>\r\n<body>\r\n<!--StartFragment-->";
|
||||
static const char* end_markup = "<!--EndFragment-->\r\n</body>\r\n</html>";
|
||||
|
||||
// Calculate offsets
|
||||
size_t start_html_offset = strlen(header) - strlen(NUMBER_FORMAT) * 4 +
|
||||
MAX_DIGITS * 4;
|
||||
if (!base_url.empty()) {
|
||||
start_html_offset += strlen(source_url_prefix) + base_url.length()
|
||||
+ 2; // Add 2 for \r\n.
|
||||
}
|
||||
size_t start_fragment_offset = start_html_offset + strlen(start_markup);
|
||||
size_t end_fragment_offset = start_fragment_offset + html.length();
|
||||
size_t end_html_offset = end_fragment_offset + strlen(end_markup);
|
||||
char raw_result[1024];
|
||||
_snprintf(raw_result, sizeof(1024),
|
||||
header,
|
||||
start_html_offset,
|
||||
end_html_offset,
|
||||
start_fragment_offset,
|
||||
end_fragment_offset);
|
||||
std::string result = raw_result;
|
||||
if (!base_url.empty()) {
|
||||
result.append(source_url_prefix);
|
||||
result.append(base_url);
|
||||
result.append("\r\n");
|
||||
}
|
||||
result.append(start_markup);
|
||||
result.append(html);
|
||||
result.append(end_markup);
|
||||
|
||||
#undef MAX_DIGITS
|
||||
#undef MAKE_NUMBER_FORMAT_1
|
||||
#undef MAKE_NUMBER_FORMAT_2
|
||||
#undef NUMBER_FORMAT
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void CFHtmlExtractMetadata(const std::string& cf_html,
|
||||
std::string* base_url,
|
||||
size_t* html_start,
|
||||
size_t* fragment_start,
|
||||
size_t* fragment_end) {
|
||||
// Obtain base_url if present.
|
||||
if (base_url) {
|
||||
static std::string src_url_str("SourceURL:");
|
||||
size_t line_start = cf_html.find(src_url_str);
|
||||
if (line_start != std::string::npos) {
|
||||
size_t src_end = cf_html.find("\n", line_start);
|
||||
size_t src_start = line_start + src_url_str.length();
|
||||
if (src_end != std::string::npos && src_start != std::string::npos) {
|
||||
*base_url = cf_html.substr(src_start, src_end - src_start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find the markup between "<!--StartFragment-->" and "<!--EndFragment-->".
|
||||
// If the comments cannot be found, like copying from OpenOffice Writer,
|
||||
// we simply fall back to using StartFragment/EndFragment bytecount values
|
||||
// to determine the fragment indexes.
|
||||
std::string cf_html_lower = cf_html;
|
||||
size_t markup_start = cf_html_lower.find("<html", 0);
|
||||
if (html_start) {
|
||||
*html_start = markup_start;
|
||||
}
|
||||
size_t tag_start = cf_html.find("<!--StartFragment", markup_start);
|
||||
if (tag_start == std::string::npos) {
|
||||
static std::string start_fragment_str("StartFragment:");
|
||||
size_t start_fragment_start = cf_html.find(start_fragment_str);
|
||||
if (start_fragment_start != std::string::npos) {
|
||||
*fragment_start = static_cast<size_t>(atoi(cf_html.c_str() +
|
||||
start_fragment_start + start_fragment_str.length()));
|
||||
}
|
||||
|
||||
static std::string end_fragment_str("EndFragment:");
|
||||
size_t end_fragment_start = cf_html.find(end_fragment_str);
|
||||
if (end_fragment_start != std::string::npos) {
|
||||
*fragment_end = static_cast<size_t>(atoi(cf_html.c_str() +
|
||||
end_fragment_start + end_fragment_str.length()));
|
||||
}
|
||||
} else {
|
||||
*fragment_start = cf_html.find('>', tag_start) + 1;
|
||||
size_t tag_end = cf_html.rfind("<!--EndFragment", std::string::npos);
|
||||
*fragment_end = cf_html.rfind('<', tag_end);
|
||||
}
|
||||
}
|
||||
|
||||
void CFHtmlToHtml(const std::string& cf_html,
|
||||
std::string* html,
|
||||
std::string* base_url) {
|
||||
size_t frag_start = std::string::npos;
|
||||
size_t frag_end = std::string::npos;
|
||||
|
||||
CFHtmlExtractMetadata(cf_html, base_url, NULL, &frag_start, &frag_end);
|
||||
|
||||
if (html && frag_start != std::string::npos &&
|
||||
frag_end != std::string::npos) {
|
||||
*html = cf_html.substr(frag_start, frag_end - frag_start);
|
||||
}
|
||||
}
|
||||
|
||||
const DWORD moz_url_format = ::RegisterClipboardFormat(L"text/x-moz-url");
|
||||
const DWORD html_format = ::RegisterClipboardFormat(L"HTML Format");
|
||||
const DWORD file_desc_format =
|
||||
::RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR);
|
||||
const DWORD file_contents_format =
|
||||
::RegisterClipboardFormat(CFSTR_FILECONTENTS);
|
||||
|
||||
bool DragDataToDataObject(CefRefPtr<CefDragData> drag_data,
|
||||
IDataObject** data_object) {
|
||||
const int kMaxDataObjects = 10;
|
||||
FORMATETC fmtetcs[kMaxDataObjects];
|
||||
STGMEDIUM stgmeds[kMaxDataObjects];
|
||||
FORMATETC fmtetc = { 0, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
|
||||
int curr_index = 0;
|
||||
CefString text = drag_data->GetFragmentText();
|
||||
if (!text.empty()) {
|
||||
fmtetc.cfFormat = CF_UNICODETEXT;
|
||||
fmtetcs[curr_index] = fmtetc;
|
||||
GetStorageForString(&stgmeds[curr_index], text.ToWString());
|
||||
curr_index++;
|
||||
}
|
||||
if (drag_data->IsLink() && !drag_data->GetLinkURL().empty()) {
|
||||
std::wstring x_moz_url_str = drag_data->GetLinkURL().ToWString();
|
||||
x_moz_url_str += '\n';
|
||||
x_moz_url_str += drag_data->GetLinkTitle().ToWString();
|
||||
fmtetc.cfFormat = moz_url_format;
|
||||
fmtetcs[curr_index] = fmtetc;
|
||||
GetStorageForString(&stgmeds[curr_index], x_moz_url_str);
|
||||
curr_index++;
|
||||
}
|
||||
CefString html = drag_data->GetFragmentHtml();
|
||||
if (!html.empty()) {
|
||||
CefString base_url = drag_data->GetFragmentBaseURL();
|
||||
std::string cfhtml = HtmlToCFHtml(html.ToString(), base_url.ToString());
|
||||
fmtetc.cfFormat = html_format;
|
||||
fmtetcs[curr_index] = fmtetc;
|
||||
GetStorageForString(&stgmeds[curr_index], cfhtml);
|
||||
curr_index++;
|
||||
}
|
||||
|
||||
size_t bufferSize = drag_data->GetFileContents(NULL);
|
||||
if (bufferSize) {
|
||||
CefRefPtr<BytesWriteHandler> handler = new BytesWriteHandler(bufferSize);
|
||||
CefRefPtr<CefStreamWriter> writer =
|
||||
CefStreamWriter::CreateForHandler(handler.get());
|
||||
drag_data->GetFileContents(writer);
|
||||
ASSERT(handler->GetDataSize() == bufferSize);
|
||||
CefString fileName = drag_data->GetFileName();
|
||||
GetStorageForFileDescriptor(&stgmeds[curr_index], fileName.ToWString());
|
||||
fmtetc.cfFormat = file_desc_format;
|
||||
fmtetcs[curr_index] = fmtetc;
|
||||
curr_index++;
|
||||
GetStorageForBytes(&stgmeds[curr_index], handler->GetData(),
|
||||
handler->GetDataSize());
|
||||
fmtetc.cfFormat = file_contents_format;
|
||||
fmtetcs[curr_index] = fmtetc;
|
||||
curr_index++;
|
||||
}
|
||||
ASSERT(curr_index < kMaxDataObjects);
|
||||
|
||||
CComPtr<IDataObject> obj =
|
||||
DataObjectWin::Create(fmtetcs, stgmeds, curr_index);
|
||||
(*data_object) = obj.Detach();
|
||||
return true;
|
||||
}
|
||||
|
||||
CefRefPtr<CefDragData> DataObjectToDragData(IDataObject* data_object) {
|
||||
CefRefPtr<CefDragData> drag_data = CefDragData::Create();
|
||||
IEnumFORMATETC* enumFormats = NULL;
|
||||
HRESULT res = data_object->EnumFormatEtc(DATADIR_GET, &enumFormats);
|
||||
if (res != S_OK)
|
||||
return drag_data;
|
||||
enumFormats->Reset();
|
||||
const int kCelt = 10;
|
||||
|
||||
ULONG celtFetched;
|
||||
do {
|
||||
celtFetched = kCelt;
|
||||
FORMATETC rgelt[kCelt];
|
||||
res = enumFormats->Next(kCelt, rgelt, &celtFetched);
|
||||
for (unsigned i = 0; i < celtFetched; i++) {
|
||||
CLIPFORMAT format = rgelt[i].cfFormat;
|
||||
if (!(format == CF_UNICODETEXT ||
|
||||
format == CF_TEXT ||
|
||||
format == moz_url_format ||
|
||||
format == html_format ||
|
||||
format == CF_HDROP)
|
||||
|| rgelt[i].tymed != TYMED_HGLOBAL)
|
||||
continue;
|
||||
STGMEDIUM medium;
|
||||
if (data_object->GetData(&rgelt[i], &medium) == S_OK) {
|
||||
if (!medium.hGlobal) {
|
||||
ReleaseStgMedium(&medium);
|
||||
continue;
|
||||
}
|
||||
void* hGlobal = GlobalLock(medium.hGlobal);
|
||||
if (!hGlobal) {
|
||||
ReleaseStgMedium(&medium);
|
||||
continue;
|
||||
}
|
||||
if (format == CF_UNICODETEXT) {
|
||||
CefString text;
|
||||
text.FromWString((std::wstring::value_type*)hGlobal);
|
||||
drag_data->SetFragmentText(text);
|
||||
} else if (format == CF_TEXT) {
|
||||
CefString text;
|
||||
text.FromString((std::string::value_type*)hGlobal);
|
||||
drag_data->SetFragmentText(text);
|
||||
} else if (format == moz_url_format) {
|
||||
std::wstring html((std::wstring::value_type*)hGlobal);
|
||||
size_t pos = html.rfind('\n');
|
||||
CefString url(html.substr(0, pos));
|
||||
CefString title(html.substr(pos + 1));
|
||||
drag_data->SetLinkURL(url);
|
||||
drag_data->SetLinkTitle(title);
|
||||
} else if (format == html_format) {
|
||||
std::string cf_html((std::string::value_type*)hGlobal);
|
||||
std::string base_url;
|
||||
std::string html;
|
||||
CFHtmlToHtml(cf_html, &html, &base_url);
|
||||
drag_data->SetFragmentHtml(html);
|
||||
drag_data->SetFragmentBaseURL(base_url);
|
||||
}
|
||||
if (format == CF_HDROP) {
|
||||
HDROP hdrop = (HDROP)hGlobal;
|
||||
const int kMaxFilenameLen = 4096;
|
||||
const unsigned num_files = DragQueryFileW(hdrop, 0xffffffff, 0, 0);
|
||||
for (unsigned int i = 0; i < num_files; ++i) {
|
||||
wchar_t filename[kMaxFilenameLen];
|
||||
if (!DragQueryFileW(hdrop, i, filename, kMaxFilenameLen))
|
||||
continue;
|
||||
WCHAR* name = wcsrchr(filename, '\\');
|
||||
drag_data->AddFile(filename, (name ? name + 1 : filename));
|
||||
}
|
||||
}
|
||||
if (medium.hGlobal)
|
||||
GlobalUnlock(medium.hGlobal);
|
||||
if (format == CF_HDROP)
|
||||
DragFinish((HDROP)hGlobal);
|
||||
else
|
||||
ReleaseStgMedium(&medium);
|
||||
}
|
||||
}
|
||||
} while (res == S_OK);
|
||||
enumFormats->Release();
|
||||
return drag_data;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
CComPtr<DropTargetWin> DropTargetWin::Create(DragEvents* callback, HWND hWnd) {
|
||||
return CComPtr<DropTargetWin>(new DropTargetWin(callback, hWnd));
|
||||
}
|
||||
|
||||
HRESULT DropTargetWin::DragEnter(IDataObject* data_object,
|
||||
DWORD key_state,
|
||||
POINTL cursor_position,
|
||||
DWORD* effect) {
|
||||
if (!callback_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
CefRefPtr<CefDragData> drag_data = current_drag_data_;
|
||||
if (!drag_data) {
|
||||
drag_data = DataObjectToDragData(data_object);
|
||||
}
|
||||
CefMouseEvent ev = ToMouseEvent(cursor_position, key_state, hWnd_);
|
||||
CefBrowserHost::DragOperationsMask mask = DropEffectToDragOperation(*effect);
|
||||
mask = callback_->OnDragEnter(drag_data, ev, mask);
|
||||
*effect = DragOperationToDropEffect(mask);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
CefBrowserHost::DragOperationsMask DropTargetWin::StartDragging(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefDragData> drag_data,
|
||||
CefRenderHandler::DragOperationsMask allowed_ops,
|
||||
int x, int y) {
|
||||
CComPtr<IDataObject> dataObject;
|
||||
DWORD resEffect = DROPEFFECT_NONE;
|
||||
if (DragDataToDataObject(drag_data, &dataObject)) {
|
||||
CComPtr<IDropSource> dropSource = DropSourceWin::Create();
|
||||
DWORD effect = DragOperationToDropEffect(allowed_ops);
|
||||
current_drag_data_ = drag_data->Clone();
|
||||
current_drag_data_->ResetFileContents();
|
||||
HRESULT res = DoDragDrop(dataObject, dropSource, effect, &resEffect);
|
||||
if (res != DRAGDROP_S_DROP)
|
||||
resEffect = DROPEFFECT_NONE;
|
||||
current_drag_data_ = NULL;
|
||||
}
|
||||
return DropEffectToDragOperation(resEffect);
|
||||
}
|
||||
|
||||
HRESULT DropTargetWin::DragOver(DWORD key_state,
|
||||
POINTL cursor_position,
|
||||
DWORD* effect) {
|
||||
if (!callback_)
|
||||
return E_UNEXPECTED;
|
||||
CefMouseEvent ev = ToMouseEvent(cursor_position, key_state, hWnd_);
|
||||
CefBrowserHost::DragOperationsMask mask = DropEffectToDragOperation(*effect);
|
||||
mask = callback_->OnDragOver(ev, mask);
|
||||
*effect = DragOperationToDropEffect(mask);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT DropTargetWin::DragLeave() {
|
||||
if (!callback_)
|
||||
return E_UNEXPECTED;
|
||||
callback_->OnDragLeave();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT DropTargetWin::Drop(IDataObject* data_object,
|
||||
DWORD key_state,
|
||||
POINTL cursor_position,
|
||||
DWORD* effect) {
|
||||
if (!callback_)
|
||||
return E_UNEXPECTED;
|
||||
CefMouseEvent ev = ToMouseEvent(cursor_position, key_state, hWnd_);
|
||||
CefBrowserHost::DragOperationsMask mask = DropEffectToDragOperation(*effect);
|
||||
mask = callback_->OnDrop(ev, mask);
|
||||
*effect = DragOperationToDropEffect(mask);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
CComPtr<DropSourceWin> DropSourceWin::Create() {
|
||||
return CComPtr<DropSourceWin>(new DropSourceWin());
|
||||
}
|
||||
|
||||
HRESULT DropSourceWin::GiveFeedback(DWORD dwEffect) {
|
||||
return DRAGDROP_S_USEDEFAULTCURSORS;
|
||||
}
|
||||
|
||||
HRESULT DropSourceWin::QueryContinueDrag(BOOL fEscapePressed,
|
||||
DWORD grfKeyState) {
|
||||
if (fEscapePressed) {
|
||||
return DRAGDROP_S_CANCEL;
|
||||
}
|
||||
|
||||
if (!(grfKeyState & MK_LBUTTON)) {
|
||||
return DRAGDROP_S_DROP;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT DragEnumFormatEtc::CreateEnumFormatEtc(UINT cfmt,
|
||||
FORMATETC* afmt,
|
||||
IEnumFORMATETC** ppEnumFormatEtc) {
|
||||
if (cfmt == 0 || afmt == 0 || ppEnumFormatEtc == 0)
|
||||
return E_INVALIDARG;
|
||||
|
||||
*ppEnumFormatEtc = new DragEnumFormatEtc(afmt, cfmt);
|
||||
|
||||
return (*ppEnumFormatEtc) ? S_OK : E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
HRESULT DragEnumFormatEtc::Next(ULONG celt,
|
||||
FORMATETC* pFormatEtc,
|
||||
ULONG* pceltFetched) {
|
||||
ULONG copied = 0;
|
||||
|
||||
// copy the FORMATETC structures into the caller's buffer
|
||||
while (m_nIndex < m_nNumFormats && copied < celt) {
|
||||
DeepCopyFormatEtc(&pFormatEtc[copied], &m_pFormatEtc[m_nIndex]);
|
||||
copied++;
|
||||
m_nIndex++;
|
||||
}
|
||||
|
||||
// store result
|
||||
if (pceltFetched != 0)
|
||||
*pceltFetched = copied;
|
||||
|
||||
// did we copy all that was requested?
|
||||
return (copied == celt) ? S_OK : S_FALSE;
|
||||
}
|
||||
HRESULT DragEnumFormatEtc::Skip(ULONG celt) {
|
||||
m_nIndex += celt;
|
||||
return (m_nIndex <= m_nNumFormats) ? S_OK : S_FALSE;
|
||||
}
|
||||
HRESULT DragEnumFormatEtc::Reset(void) {
|
||||
m_nIndex = 0;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT DragEnumFormatEtc::Clone(IEnumFORMATETC** ppEnumFormatEtc) {
|
||||
HRESULT hResult;
|
||||
|
||||
// make a duplicate enumerator
|
||||
hResult = CreateEnumFormatEtc(m_nNumFormats, m_pFormatEtc, ppEnumFormatEtc);
|
||||
|
||||
if (hResult == S_OK) {
|
||||
// manually set the index state
|
||||
reinterpret_cast<DragEnumFormatEtc*>(*ppEnumFormatEtc)->m_nIndex = m_nIndex;
|
||||
}
|
||||
|
||||
return hResult;
|
||||
}
|
||||
|
||||
DragEnumFormatEtc::DragEnumFormatEtc(FORMATETC* pFormatEtc, int nNumFormats) {
|
||||
AddRef();
|
||||
|
||||
m_nIndex = 0;
|
||||
m_nNumFormats = nNumFormats;
|
||||
m_pFormatEtc = new FORMATETC[nNumFormats];
|
||||
|
||||
// make a new copy of each FORMATETC structure
|
||||
for (int i = 0; i < nNumFormats; i++) {
|
||||
DeepCopyFormatEtc(&m_pFormatEtc[i], &pFormatEtc[i]);
|
||||
}
|
||||
}
|
||||
DragEnumFormatEtc::~DragEnumFormatEtc() {
|
||||
// first free any DVTARGETDEVICE structures
|
||||
for (ULONG i = 0; i < m_nNumFormats; i++) {
|
||||
if (m_pFormatEtc[i].ptd)
|
||||
CoTaskMemFree(m_pFormatEtc[i].ptd);
|
||||
}
|
||||
|
||||
// now free the main array
|
||||
delete[] m_pFormatEtc;
|
||||
}
|
||||
|
||||
void DragEnumFormatEtc::DeepCopyFormatEtc(FORMATETC* dest, FORMATETC* source) {
|
||||
// copy the source FORMATETC into dest
|
||||
*dest = *source;
|
||||
if (source->ptd) {
|
||||
// allocate memory for the DVTARGETDEVICE if necessary
|
||||
dest->ptd = reinterpret_cast<DVTARGETDEVICE*>(
|
||||
CoTaskMemAlloc(sizeof(DVTARGETDEVICE)));
|
||||
|
||||
// copy the contents of the source DVTARGETDEVICE into dest->ptd
|
||||
*(dest->ptd) = *(source->ptd);
|
||||
}
|
||||
}
|
||||
|
||||
CComPtr<DataObjectWin> DataObjectWin::Create(FORMATETC* fmtetc,
|
||||
STGMEDIUM* stgmed,
|
||||
int count) {
|
||||
return CComPtr<DataObjectWin>(new DataObjectWin(fmtetc, stgmed, count));
|
||||
}
|
||||
|
||||
HRESULT DataObjectWin::GetDataHere(FORMATETC* pFormatEtc, STGMEDIUM* pmedium) {
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT DataObjectWin::QueryGetData(FORMATETC* pFormatEtc) {
|
||||
return (LookupFormatEtc(pFormatEtc) == -1) ? DV_E_FORMATETC : S_OK;
|
||||
}
|
||||
|
||||
HRESULT DataObjectWin::GetCanonicalFormatEtc(FORMATETC* pFormatEct,
|
||||
FORMATETC* pFormatEtcOut) {
|
||||
pFormatEtcOut->ptd = NULL;
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT DataObjectWin::SetData(FORMATETC* pFormatEtc,
|
||||
STGMEDIUM* pMedium,
|
||||
BOOL fRelease) {
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT DataObjectWin::DAdvise(FORMATETC* pFormatEtc,
|
||||
DWORD advf,
|
||||
IAdviseSink*,
|
||||
DWORD*) {
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT DataObjectWin::DUnadvise(DWORD dwConnection) {
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT DataObjectWin::EnumDAdvise(IEnumSTATDATA **ppEnumAdvise) {
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT DataObjectWin::EnumFormatEtc(DWORD dwDirection,
|
||||
IEnumFORMATETC** ppEnumFormatEtc) {
|
||||
return DragEnumFormatEtc::CreateEnumFormatEtc(m_nNumFormats, m_pFormatEtc,
|
||||
ppEnumFormatEtc);
|
||||
}
|
||||
|
||||
HRESULT DataObjectWin::GetData(FORMATETC* pFormatEtc, STGMEDIUM* pMedium) {
|
||||
int idx;
|
||||
|
||||
// try to match the specified FORMATETC with one of our supported formats
|
||||
if ((idx = LookupFormatEtc(pFormatEtc)) == -1)
|
||||
return DV_E_FORMATETC;
|
||||
|
||||
// found a match - transfer data into supplied storage medium
|
||||
pMedium->tymed = m_pFormatEtc[idx].tymed;
|
||||
pMedium->pUnkForRelease = 0;
|
||||
|
||||
// copy the data into the caller's storage medium
|
||||
switch (m_pFormatEtc[idx].tymed) {
|
||||
case TYMED_HGLOBAL:
|
||||
pMedium->hGlobal = DupGlobalMem(m_pStgMedium[idx].hGlobal);
|
||||
break;
|
||||
|
||||
default:
|
||||
return DV_E_FORMATETC;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HGLOBAL DataObjectWin::DupGlobalMem(HGLOBAL hMem) {
|
||||
DWORD len = GlobalSize(hMem);
|
||||
PVOID source = GlobalLock(hMem);
|
||||
PVOID dest = GlobalAlloc(GMEM_FIXED, len);
|
||||
|
||||
memcpy(dest, source, len);
|
||||
GlobalUnlock(hMem);
|
||||
return dest;
|
||||
}
|
||||
|
||||
int DataObjectWin::LookupFormatEtc(FORMATETC* pFormatEtc) {
|
||||
// check each of our formats in turn to see if one matches
|
||||
for (int i = 0; i < m_nNumFormats; i++) {
|
||||
if ((m_pFormatEtc[i].tymed & pFormatEtc->tymed) &&
|
||||
m_pFormatEtc[i].cfFormat == pFormatEtc->cfFormat &&
|
||||
m_pFormatEtc[i].dwAspect == pFormatEtc->dwAspect) {
|
||||
// return index of stored format
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// error, format not found
|
||||
return -1;
|
||||
}
|
||||
|
||||
DataObjectWin::DataObjectWin(FORMATETC* fmtetc, STGMEDIUM* stgmed, int count)
|
||||
: ref_count_(0) {
|
||||
m_nNumFormats = count;
|
||||
|
||||
m_pFormatEtc = new FORMATETC[count];
|
||||
m_pStgMedium = new STGMEDIUM[count];
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
m_pFormatEtc[i] = fmtetc[i];
|
||||
m_pStgMedium[i] = stgmed[i];
|
||||
}
|
||||
}
|
178
tests/cefclient/cefclient_osr_dragdrop_win.h
Normal file
178
tests/cefclient/cefclient_osr_dragdrop_win.h
Normal file
@ -0,0 +1,178 @@
|
||||
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_DRAGDROP_WIN_H_
|
||||
#define CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_DRAGDROP_WIN_H_
|
||||
#pragma once
|
||||
|
||||
#include <atlcomcli.h>
|
||||
#include <objidl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "cefclient/dragdrop_events.h"
|
||||
|
||||
#define DEFAULT_QUERY_INTERFACE(__Class) \
|
||||
HRESULT __stdcall QueryInterface(const IID& iid, void** object) { \
|
||||
*object = NULL; \
|
||||
if (IsEqualIID(iid, IID_IUnknown)) { \
|
||||
IUnknown* obj = this; \
|
||||
*object = obj; \
|
||||
} else if (IsEqualIID(iid, IID_ ## __Class)) { \
|
||||
__Class* obj = this; \
|
||||
*object = obj; \
|
||||
} else { \
|
||||
return E_NOINTERFACE; \
|
||||
} \
|
||||
AddRef(); \
|
||||
return S_OK; \
|
||||
}
|
||||
#define IUNKNOWN_IMPLEMENTATION \
|
||||
ULONG __stdcall AddRef() { \
|
||||
return ++ref_count_; \
|
||||
} \
|
||||
ULONG __stdcall Release() { \
|
||||
if (--ref_count_ == 0) { \
|
||||
delete this; \
|
||||
return 0U; \
|
||||
} \
|
||||
return ref_count_; \
|
||||
} \
|
||||
protected: \
|
||||
ULONG ref_count_;
|
||||
|
||||
|
||||
class DropTargetWin : public IDropTarget {
|
||||
public:
|
||||
static CComPtr<DropTargetWin> Create(DragEvents* callback, HWND hWnd);
|
||||
|
||||
CefBrowserHost::DragOperationsMask StartDragging(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefDragData> drag_data,
|
||||
CefRenderHandler::DragOperationsMask allowed_ops,
|
||||
int x, int y);
|
||||
|
||||
// IDropTarget implementation:
|
||||
HRESULT __stdcall DragEnter(IDataObject* data_object,
|
||||
DWORD key_state,
|
||||
POINTL cursor_position,
|
||||
DWORD* effect);
|
||||
|
||||
HRESULT __stdcall DragOver(DWORD key_state,
|
||||
POINTL cursor_position,
|
||||
DWORD* effect);
|
||||
|
||||
HRESULT __stdcall DragLeave();
|
||||
|
||||
HRESULT __stdcall Drop(IDataObject* data_object,
|
||||
DWORD key_state,
|
||||
POINTL cursor_position,
|
||||
DWORD* effect);
|
||||
|
||||
DEFAULT_QUERY_INTERFACE(IDropTarget)
|
||||
IUNKNOWN_IMPLEMENTATION()
|
||||
|
||||
protected:
|
||||
explicit DropTargetWin(DragEvents* callback, HWND hWnd) :
|
||||
ref_count_(0),
|
||||
callback_(callback),
|
||||
hWnd_(hWnd) {}
|
||||
virtual ~DropTargetWin() {}
|
||||
|
||||
private:
|
||||
DragEvents* callback_;
|
||||
HWND hWnd_;
|
||||
|
||||
CefRefPtr<CefDragData> current_drag_data_;
|
||||
};
|
||||
|
||||
class DropSourceWin : public IDropSource {
|
||||
public:
|
||||
static CComPtr<DropSourceWin> Create();
|
||||
|
||||
// IDropSource implementation:
|
||||
HRESULT __stdcall GiveFeedback(DWORD dwEffect);
|
||||
|
||||
HRESULT __stdcall QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState);
|
||||
|
||||
DEFAULT_QUERY_INTERFACE(IDropSource)
|
||||
IUNKNOWN_IMPLEMENTATION()
|
||||
protected:
|
||||
explicit DropSourceWin() : ref_count_(0) {}
|
||||
virtual ~DropSourceWin() {}
|
||||
};
|
||||
|
||||
class DragEnumFormatEtc : public IEnumFORMATETC {
|
||||
public:
|
||||
static HRESULT CreateEnumFormatEtc(UINT cfmt,
|
||||
FORMATETC* afmt,
|
||||
IEnumFORMATETC** ppEnumFormatEtc);
|
||||
|
||||
//
|
||||
// IEnumFormatEtc members
|
||||
//
|
||||
HRESULT __stdcall Next(ULONG celt,
|
||||
FORMATETC * pFormatEtc,
|
||||
ULONG * pceltFetched);
|
||||
HRESULT __stdcall Skip(ULONG celt);
|
||||
HRESULT __stdcall Reset(void);
|
||||
HRESULT __stdcall Clone(IEnumFORMATETC ** ppEnumFormatEtc);
|
||||
|
||||
//
|
||||
// Construction / Destruction
|
||||
//
|
||||
DragEnumFormatEtc(FORMATETC *pFormatEtc, int nNumFormats);
|
||||
~DragEnumFormatEtc();
|
||||
|
||||
static void DeepCopyFormatEtc(FORMATETC *dest, FORMATETC *source);
|
||||
|
||||
DEFAULT_QUERY_INTERFACE(IEnumFORMATETC)
|
||||
IUNKNOWN_IMPLEMENTATION()
|
||||
|
||||
private:
|
||||
ULONG m_nIndex; // current enumerator index
|
||||
ULONG m_nNumFormats; // number of FORMATETC members
|
||||
FORMATETC* m_pFormatEtc; // array of FORMATETC objects
|
||||
};
|
||||
|
||||
class DataObjectWin : public IDataObject {
|
||||
public:
|
||||
static CComPtr<DataObjectWin> Create(FORMATETC* fmtetc,
|
||||
STGMEDIUM* stgmed,
|
||||
int count);
|
||||
|
||||
// IDataObject memberS
|
||||
HRESULT __stdcall GetDataHere(FORMATETC* pFormatEtc, STGMEDIUM *pmedium);
|
||||
HRESULT __stdcall QueryGetData(FORMATETC* pFormatEtc);
|
||||
HRESULT __stdcall GetCanonicalFormatEtc(FORMATETC* pFormatEct,
|
||||
FORMATETC* pFormatEtcOut);
|
||||
HRESULT __stdcall SetData(FORMATETC* pFormatEtc,
|
||||
STGMEDIUM* pMedium,
|
||||
BOOL fRelease);
|
||||
HRESULT __stdcall DAdvise(FORMATETC* pFormatEtc,
|
||||
DWORD advf,
|
||||
IAdviseSink*,
|
||||
DWORD*);
|
||||
HRESULT __stdcall DUnadvise(DWORD dwConnection);
|
||||
HRESULT __stdcall EnumDAdvise(IEnumSTATDATA **ppEnumAdvise);
|
||||
|
||||
HRESULT __stdcall EnumFormatEtc(DWORD dwDirection,
|
||||
IEnumFORMATETC **ppEnumFormatEtc);
|
||||
HRESULT __stdcall GetData(FORMATETC *pFormatEtc, STGMEDIUM *pMedium);
|
||||
|
||||
DEFAULT_QUERY_INTERFACE(IDataObject)
|
||||
IUNKNOWN_IMPLEMENTATION()
|
||||
|
||||
protected:
|
||||
int m_nNumFormats;
|
||||
FORMATETC* m_pFormatEtc;
|
||||
STGMEDIUM* m_pStgMedium;
|
||||
|
||||
static HGLOBAL DupGlobalMem(HGLOBAL hMem);
|
||||
|
||||
int LookupFormatEtc(FORMATETC *pFormatEtc);
|
||||
|
||||
explicit DataObjectWin(FORMATETC *fmtetc, STGMEDIUM *stgmed, int count);
|
||||
};
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_DRAGDROP_WIN_H_
|
@ -19,7 +19,8 @@ class OSRBrowserProvider {
|
||||
};
|
||||
|
||||
// The client OpenGL view.
|
||||
@interface ClientOpenGLView : NSOpenGLView {
|
||||
@interface ClientOpenGLView
|
||||
: NSOpenGLView <NSDraggingSource, NSDraggingDestination> {
|
||||
@public
|
||||
NSTrackingArea* tracking_area_;
|
||||
OSRBrowserProvider* browser_provider_;
|
||||
@ -30,6 +31,13 @@ class OSRBrowserProvider {
|
||||
|
||||
bool was_last_mouse_down_on_view_;
|
||||
|
||||
// Drag and drop
|
||||
CefRefPtr<CefDragData> current_drag_data_;
|
||||
NSDragOperation current_drag_op_;
|
||||
NSDragOperation current_allowed_ops_;
|
||||
NSPasteboard* pasteboard_;
|
||||
CFStringRef fileUTI_;
|
||||
|
||||
// Event monitor for scroll wheel end event.
|
||||
id endWheelMonitor_;
|
||||
}
|
||||
@ -42,6 +50,8 @@ class OSRBrowserProvider {
|
||||
- (BOOL)isKeyUpEvent:(NSEvent*)event;
|
||||
- (BOOL)isKeyPadEvent:(NSEvent*)event;
|
||||
- (CefRefPtr<CefBrowser>)getBrowser;
|
||||
- (BOOL)startDragging:(CefRefPtr<CefDragData>)drag_data
|
||||
allowed_ops:(NSDragOperation)ops point:(NSPoint)p;
|
||||
@end
|
||||
|
||||
// Handler for off-screen rendering windows.
|
||||
@ -84,6 +94,15 @@ class ClientOSRHandler : public ClientHandler::RenderHandler {
|
||||
virtual void OnCursorChange(CefRefPtr<CefBrowser> browser,
|
||||
CefCursorHandle cursor) OVERRIDE;
|
||||
|
||||
virtual bool StartDragging(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefDragData> drag_data,
|
||||
CefRenderHandler::DragOperationsMask allowed_ops,
|
||||
int x, int y) OVERRIDE;
|
||||
|
||||
virtual void UpdateDragCursor(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRenderHandler::DragOperation operation)OVERRIDE;
|
||||
|
||||
CefWindowHandle view() { return view_; }
|
||||
|
||||
private:
|
||||
|
@ -6,11 +6,15 @@
|
||||
#import <objc/runtime.h>
|
||||
#include <OpenGL/gl.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "cefclient/cefclient_osr_widget_mac.h"
|
||||
|
||||
#include "include/cef_application_mac.h"
|
||||
#include "include/cef_browser.h"
|
||||
#include "include/cef_client.h"
|
||||
#include "include/cef_url.h"
|
||||
#include "cefclient/bytes_write_handler.h"
|
||||
#include "cefclient/cefclient.h"
|
||||
#include "cefclient/osrenderer.h"
|
||||
#include "cefclient/resource_util.h"
|
||||
@ -40,6 +44,11 @@ static BOOL SupportsBackingPropertiesChangedNotification() {
|
||||
}
|
||||
|
||||
@interface ClientOpenGLView ()
|
||||
- (void)resetDragDrop;
|
||||
- (void)fillPasteboard;
|
||||
- (void)populateDropData:(CefRefPtr<CefDragData>)data
|
||||
fromPasteboard:(NSPasteboard*)pboard;
|
||||
- (NSPoint)flipWindowPointToView:(const NSPoint&)windowPoint;
|
||||
- (float)getDeviceScaleFactor;
|
||||
- (void)windowDidChangeBackingProperties:(NSNotification*)notification;
|
||||
|
||||
@ -74,6 +83,9 @@ static CefRect convertRect(const NSRect& target, const NSRect& frame) {
|
||||
rect.size.height);
|
||||
}
|
||||
|
||||
static NSString* const kCEFDragDummyPboardType = @"org.CEF.drag-dummy-type";
|
||||
static NSString* const kNSURLTitlePboardType = @"public.url-name";
|
||||
|
||||
} // namespace
|
||||
|
||||
ClientOSRHandler::ClientOSRHandler(ClientOpenGLView* view,
|
||||
@ -274,6 +286,26 @@ void ClientOSRHandler::OnCursorChange(CefRefPtr<CefBrowser> browser,
|
||||
[cursor set];
|
||||
}
|
||||
|
||||
bool ClientOSRHandler::StartDragging(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefDragData> drag_data,
|
||||
CefRenderHandler::DragOperationsMask allowed_ops,
|
||||
int x, int y) {
|
||||
REQUIRE_UI_THREAD();
|
||||
if (!view_)
|
||||
return false;
|
||||
return [view_ startDragging:drag_data
|
||||
allowed_ops:static_cast<NSDragOperation>(allowed_ops)
|
||||
point:NSMakePoint(x, y)];
|
||||
}
|
||||
|
||||
void ClientOSRHandler::UpdateDragCursor(CefRefPtr<CefBrowser> browser,
|
||||
CefRenderHandler::DragOperation operation) {
|
||||
REQUIRE_UI_THREAD();
|
||||
if (!view_)
|
||||
return;
|
||||
view_->current_drag_op_ = operation;
|
||||
}
|
||||
|
||||
void ClientOSRHandler::SetLoading(bool isLoading) {
|
||||
}
|
||||
|
||||
@ -313,6 +345,16 @@ void ClientOSRHandler::SetLoading(bool isLoading) {
|
||||
[self setWantsBestResolutionOpenGLSurface:YES];
|
||||
}
|
||||
|
||||
[self resetDragDrop];
|
||||
|
||||
NSArray* types = [NSArray arrayWithObjects:
|
||||
kCEFDragDummyPboardType,
|
||||
NSStringPboardType,
|
||||
NSFilenamesPboardType,
|
||||
NSPasteboardTypeString,
|
||||
nil];
|
||||
[self registerForDraggedTypes:types];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@ -804,7 +846,318 @@ void ClientOSRHandler::SetLoading(bool isLoading) {
|
||||
}
|
||||
}
|
||||
|
||||
// Drag and drop
|
||||
|
||||
- (BOOL)startDragging:(CefRefPtr<CefDragData>)drag_data
|
||||
allowed_ops:(NSDragOperation)ops
|
||||
point:(NSPoint)position {
|
||||
ASSERT(!pasteboard_);
|
||||
ASSERT(!fileUTI_);
|
||||
ASSERT(!current_drag_data_.get());
|
||||
|
||||
[self resetDragDrop];
|
||||
|
||||
current_allowed_ops_ = ops;
|
||||
current_drag_data_ = drag_data;
|
||||
|
||||
[self fillPasteboard];
|
||||
|
||||
NSEvent* currentEvent = [NSApp currentEvent];
|
||||
NSWindow* window = [self window];
|
||||
NSTimeInterval eventTime = [currentEvent timestamp];
|
||||
|
||||
NSEvent* dragEvent = [NSEvent mouseEventWithType:NSLeftMouseDragged
|
||||
location:position
|
||||
modifierFlags:NSLeftMouseDraggedMask
|
||||
timestamp:eventTime
|
||||
windowNumber:[window windowNumber]
|
||||
context:nil
|
||||
eventNumber:0
|
||||
clickCount:1
|
||||
pressure:1.0];
|
||||
|
||||
[window dragImage:nil
|
||||
at:position
|
||||
offset:NSZeroSize
|
||||
event:dragEvent
|
||||
pasteboard:pasteboard_
|
||||
source:self
|
||||
slideBack:YES];
|
||||
return YES;
|
||||
}
|
||||
|
||||
// NSDraggingSource Protocol
|
||||
|
||||
- (NSDragOperation)draggingSession:(NSDraggingSession *)session
|
||||
sourceOperationMaskForDraggingContext:(NSDraggingContext)context {
|
||||
switch(context) {
|
||||
case NSDraggingContextOutsideApplication:
|
||||
return current_allowed_ops_;
|
||||
|
||||
case NSDraggingContextWithinApplication:
|
||||
default:
|
||||
return current_allowed_ops_;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray*)namesOfPromisedFilesDroppedAtDestination:(NSURL*)dropDest {
|
||||
if (![dropDest isFileURL])
|
||||
return nil;
|
||||
|
||||
if (!current_drag_data_)
|
||||
return nil;
|
||||
|
||||
size_t expected_size = current_drag_data_->GetFileContents(NULL);
|
||||
if (expected_size == 0)
|
||||
return nil;
|
||||
|
||||
std::string path = [[dropDest path] UTF8String];
|
||||
path.append("/");
|
||||
path.append(current_drag_data_->GetFileName().ToString());
|
||||
|
||||
CefRefPtr<CefStreamWriter> writer = CefStreamWriter::CreateForFile(path);
|
||||
if (!writer)
|
||||
return nil;
|
||||
|
||||
if (current_drag_data_->GetFileContents(writer) != expected_size)
|
||||
return nil;
|
||||
|
||||
return @[ [NSString stringWithUTF8String:path.c_str()] ];
|
||||
}
|
||||
|
||||
- (void)draggedImage:(NSImage*)anImage
|
||||
endedAt:(NSPoint)screenPoint
|
||||
operation:(NSDragOperation)operation {
|
||||
|
||||
if (operation == (NSDragOperationMove | NSDragOperationCopy))
|
||||
operation &= ~NSDragOperationMove;
|
||||
|
||||
NSPoint windowPoint = [[self window] convertScreenToBase: screenPoint];
|
||||
NSPoint pt = [self flipWindowPointToView:windowPoint];
|
||||
CefRenderHandler::DragOperation op =
|
||||
static_cast<CefRenderHandler::DragOperation>(operation);
|
||||
browser_provider_->GetBrowser()->GetHost()->DragSourceEndedAt(pt.x, pt.y, op);
|
||||
browser_provider_->GetBrowser()->GetHost()->DragSourceSystemDragEnded();
|
||||
[self resetDragDrop];
|
||||
}
|
||||
|
||||
// NSDraggingDestination Protocol
|
||||
|
||||
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)info {
|
||||
CefRefPtr<CefDragData> drag_data;
|
||||
if (!current_drag_data_) {
|
||||
drag_data = CefDragData::Create();
|
||||
[self populateDropData:drag_data
|
||||
fromPasteboard:[info draggingPasteboard]];
|
||||
} else {
|
||||
drag_data = current_drag_data_->Clone();
|
||||
drag_data->ResetFileContents();
|
||||
}
|
||||
|
||||
NSPoint windowPoint = [info draggingLocation];
|
||||
NSPoint viewPoint = [self flipWindowPointToView:windowPoint];
|
||||
NSDragOperation mask = [info draggingSourceOperationMask];
|
||||
CefMouseEvent ev;
|
||||
ev.x = viewPoint.x;
|
||||
ev.y = viewPoint.y;
|
||||
ev.modifiers = [NSEvent modifierFlags];
|
||||
CefBrowserHost::DragOperationsMask allowed_ops =
|
||||
static_cast<CefBrowserHost::DragOperationsMask>(mask);
|
||||
browser_provider_->GetBrowser()->GetHost()->DragTargetDragEnter(
|
||||
drag_data, ev, allowed_ops);
|
||||
browser_provider_->GetBrowser()->GetHost()->DragTargetDragOver(ev,
|
||||
allowed_ops);
|
||||
|
||||
current_drag_op_ = NSDragOperationCopy;
|
||||
return current_drag_op_;
|
||||
}
|
||||
|
||||
- (void)draggingExited:(id <NSDraggingInfo>)sender {
|
||||
browser_provider_->GetBrowser()->GetHost()->DragTargetDragLeave();
|
||||
}
|
||||
|
||||
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)info {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)performDragOperation:(id <NSDraggingInfo>)info {
|
||||
NSPoint windowPoint = [info draggingLocation];
|
||||
NSPoint viewPoint = [self flipWindowPointToView:windowPoint];
|
||||
CefMouseEvent ev;
|
||||
ev.x = viewPoint.x;
|
||||
ev.y = viewPoint.y;
|
||||
ev.modifiers = [NSEvent modifierFlags];
|
||||
browser_provider_->GetBrowser()->GetHost()->DragTargetDrop(ev);
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)info {
|
||||
NSPoint windowPoint = [info draggingLocation];
|
||||
NSPoint viewPoint = [self flipWindowPointToView:windowPoint];
|
||||
NSDragOperation mask = [info draggingSourceOperationMask];
|
||||
CefMouseEvent ev;
|
||||
ev.x = viewPoint.x;
|
||||
ev.y = viewPoint.y;
|
||||
ev.modifiers = [NSEvent modifierFlags];
|
||||
CefBrowserHost::DragOperationsMask allowed_ops =
|
||||
static_cast<CefBrowserHost::DragOperationsMask>(mask);
|
||||
browser_provider_->GetBrowser()->GetHost()->DragTargetDragOver(ev,
|
||||
allowed_ops);
|
||||
|
||||
return current_drag_op_;
|
||||
}
|
||||
|
||||
// NSPasteboardOwner Protocol
|
||||
|
||||
- (void)pasteboard:(NSPasteboard *)pboard provideDataForType:(NSString *)type {
|
||||
if (!current_drag_data_) {
|
||||
return;
|
||||
}
|
||||
|
||||
// URL.
|
||||
if ([type isEqualToString:NSURLPboardType]) {
|
||||
ASSERT(current_drag_data_->IsLink());
|
||||
NSString* strUrl = [NSString stringWithUTF8String:
|
||||
current_drag_data_->GetLinkURL().ToString().c_str()];
|
||||
NSURL* url = [NSURL URLWithString:strUrl];
|
||||
[url writeToPasteboard:pboard];
|
||||
// URL title.
|
||||
} else if ([type isEqualToString:kNSURLTitlePboardType]) {
|
||||
NSString* strTitle = [NSString stringWithUTF8String:
|
||||
current_drag_data_->GetLinkTitle().ToString().c_str()];
|
||||
[pboard setString:strTitle forType:kNSURLTitlePboardType];
|
||||
|
||||
// File contents.
|
||||
} else if ([type isEqualToString:(NSString*)fileUTI_]) {
|
||||
size_t size = current_drag_data_->GetFileContents(NULL);
|
||||
ASSERT(size > 0);
|
||||
CefRefPtr<BytesWriteHandler> handler = new BytesWriteHandler(size);
|
||||
CefRefPtr<CefStreamWriter> writer =
|
||||
CefStreamWriter::CreateForHandler(handler.get());
|
||||
current_drag_data_->GetFileContents(writer);
|
||||
ASSERT(handler->GetDataSize() == size);
|
||||
|
||||
[pboard setData:[NSData dataWithBytes:handler->GetData()
|
||||
length:handler->GetDataSize()]
|
||||
forType:(NSString*)fileUTI_];
|
||||
|
||||
// Plain text.
|
||||
} else if ([type isEqualToString:NSStringPboardType]) {
|
||||
NSString* strTitle = [NSString stringWithUTF8String:
|
||||
current_drag_data_->GetFragmentText().ToString().c_str()];
|
||||
[pboard setString:strTitle forType:NSStringPboardType];
|
||||
|
||||
} else if ([type isEqualToString:kCEFDragDummyPboardType]) {
|
||||
// The dummy type _was_ promised and someone decided to call the bluff.
|
||||
[pboard setData:[NSData data]
|
||||
forType:kCEFDragDummyPboardType];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Utility - private
|
||||
- (void)resetDragDrop {
|
||||
current_drag_op_ = NSDragOperationNone;
|
||||
current_allowed_ops_ = NSDragOperationNone;
|
||||
current_drag_data_ = NULL;
|
||||
if (fileUTI_) {
|
||||
CFRelease(fileUTI_);
|
||||
fileUTI_ = NULL;
|
||||
}
|
||||
if (pasteboard_) {
|
||||
[pasteboard_ release];
|
||||
pasteboard_ = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)fillPasteboard {
|
||||
ASSERT(!pasteboard_);
|
||||
pasteboard_ = [[NSPasteboard pasteboardWithName:NSDragPboard] retain];
|
||||
|
||||
[pasteboard_ declareTypes:@[ kCEFDragDummyPboardType ]
|
||||
owner:self];
|
||||
|
||||
// URL (and title).
|
||||
if (current_drag_data_->IsLink()) {
|
||||
[pasteboard_ addTypes:@[ NSURLPboardType, kNSURLTitlePboardType ]
|
||||
owner:self];
|
||||
}
|
||||
|
||||
// MIME type.
|
||||
CefString mimeType;
|
||||
size_t contents_size = current_drag_data_->GetFileContents(NULL);
|
||||
CefString download_metadata = current_drag_data_->GetLinkMetadata();
|
||||
CefString file_name = current_drag_data_->GetFileName();
|
||||
|
||||
// File.
|
||||
if (contents_size > 0) {
|
||||
std::string file_name = current_drag_data_->GetFileName().ToString();
|
||||
size_t sep = file_name.find_last_of(".");
|
||||
CefString extension = file_name.substr(sep + 1);
|
||||
|
||||
mimeType = CefGetMimeType(extension);
|
||||
|
||||
if (!mimeType.empty()) {
|
||||
CFStringRef mimeTypeCF;
|
||||
mimeTypeCF = CFStringCreateWithCString(kCFAllocatorDefault,
|
||||
mimeType.ToString().c_str(), kCFStringEncodingUTF8);
|
||||
fileUTI_ = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType,
|
||||
mimeTypeCF, NULL);
|
||||
CFRelease(mimeTypeCF);
|
||||
// File (HFS) promise.
|
||||
NSArray* fileUTIList = @[ (NSString*)fileUTI_ ];
|
||||
[pasteboard_ addTypes:@[ NSFilesPromisePboardType ] owner:self];
|
||||
[pasteboard_ setPropertyList:fileUTIList
|
||||
forType:NSFilesPromisePboardType];
|
||||
|
||||
[pasteboard_ addTypes:fileUTIList owner:self];
|
||||
}
|
||||
}
|
||||
|
||||
// Plain text.
|
||||
if (!current_drag_data_->GetFragmentText().empty()) {
|
||||
[pasteboard_ addTypes:@[ NSStringPboardType ]
|
||||
owner:self];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)populateDropData:(CefRefPtr<CefDragData>)data
|
||||
fromPasteboard:(NSPasteboard*)pboard {
|
||||
ASSERT(data);
|
||||
ASSERT(pboard);
|
||||
ASSERT(data && !data->IsReadOnly());
|
||||
NSArray* types = [pboard types];
|
||||
|
||||
// Get plain text.
|
||||
if ([types containsObject:NSStringPboardType]) {
|
||||
data->SetFragmentText(
|
||||
[[pboard stringForType:NSStringPboardType] UTF8String]);
|
||||
}
|
||||
|
||||
// Get files.
|
||||
if ([types containsObject:NSFilenamesPboardType]) {
|
||||
NSArray* files = [pboard propertyListForType:NSFilenamesPboardType];
|
||||
if ([files isKindOfClass:[NSArray class]] && [files count]) {
|
||||
for (NSUInteger i = 0; i < [files count]; i++) {
|
||||
NSString* filename = [files objectAtIndex:i];
|
||||
BOOL exists = [[NSFileManager defaultManager]
|
||||
fileExistsAtPath:filename];
|
||||
if (exists) {
|
||||
data->AddFile([filename UTF8String], CefString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (NSPoint)flipWindowPointToView:(const NSPoint&)windowPoint {
|
||||
NSPoint viewPoint = [self convertPoint:windowPoint fromView:nil];
|
||||
NSRect viewFrame = [self frame];
|
||||
viewPoint.y = viewFrame.size.height - viewPoint.y;
|
||||
return viewPoint;
|
||||
}
|
||||
|
||||
- (float)getDeviceScaleFactor {
|
||||
float deviceScaleFactor = 1;
|
||||
NSWindow* window = [self window];
|
||||
|
@ -44,6 +44,9 @@ bool OSRWindow::CreateWidget(HWND hWndParent, const RECT& rect,
|
||||
// Reference released in OnDestroyed().
|
||||
AddRef();
|
||||
|
||||
drop_target_ = DropTargetWin::Create(this, hWnd_);
|
||||
HRESULT register_res = RegisterDragDrop(hWnd_, drop_target_);
|
||||
ASSERT(register_res == S_OK);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -53,7 +56,10 @@ void OSRWindow::DestroyWidget() {
|
||||
}
|
||||
|
||||
void OSRWindow::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
|
||||
RevokeDragDrop(hWnd_);
|
||||
drop_target_ = NULL;
|
||||
DisableGL();
|
||||
::DestroyWindow(hWnd_);
|
||||
}
|
||||
|
||||
bool OSRWindow::GetRootScreenRect(CefRefPtr<CefBrowser> browser,
|
||||
@ -149,6 +155,29 @@ void OSRWindow::OnCursorChange(CefRefPtr<CefBrowser> browser,
|
||||
SetCursor(cursor);
|
||||
}
|
||||
|
||||
bool OSRWindow::StartDragging(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefDragData> drag_data,
|
||||
CefRenderHandler::DragOperationsMask allowed_ops,
|
||||
int x, int y) {
|
||||
if (!drop_target_)
|
||||
return false;
|
||||
current_drag_op_ = DRAG_OPERATION_NONE;
|
||||
CefBrowserHost::DragOperationsMask result =
|
||||
drop_target_->StartDragging(browser, drag_data, allowed_ops, x, y);
|
||||
current_drag_op_ = DRAG_OPERATION_NONE;
|
||||
POINT pt = {};
|
||||
GetCursorPos(&pt);
|
||||
ScreenToClient(hWnd_, &pt);
|
||||
browser->GetHost()->DragSourceEndedAt(pt.x, pt.y, result);
|
||||
browser->GetHost()->DragSourceSystemDragEnded();
|
||||
return true;
|
||||
}
|
||||
|
||||
void OSRWindow::UpdateDragCursor(CefRefPtr<CefBrowser> browser,
|
||||
CefRenderHandler::DragOperation operation) {
|
||||
current_drag_op_ = operation;
|
||||
}
|
||||
|
||||
void OSRWindow::Invalidate() {
|
||||
if (!CefCurrentlyOn(TID_UI)) {
|
||||
CefPostTask(TID_UI, NewCefRunnableMethod(this, &OSRWindow::Invalidate));
|
||||
@ -167,6 +196,34 @@ void OSRWindow::Invalidate() {
|
||||
kRenderDelay);
|
||||
}
|
||||
|
||||
CefBrowserHost::DragOperationsMask
|
||||
OSRWindow::OnDragEnter(CefRefPtr<CefDragData> drag_data,
|
||||
CefMouseEvent ev,
|
||||
CefBrowserHost::DragOperationsMask effect) {
|
||||
browser_provider_->GetBrowser()->GetHost()->DragTargetDragEnter(
|
||||
drag_data, ev, effect);
|
||||
browser_provider_->GetBrowser()->GetHost()->DragTargetDragOver(ev, effect);
|
||||
return current_drag_op_;
|
||||
}
|
||||
|
||||
CefBrowserHost::DragOperationsMask OSRWindow::OnDragOver(CefMouseEvent ev,
|
||||
CefBrowserHost::DragOperationsMask effect) {
|
||||
browser_provider_->GetBrowser()->GetHost()->DragTargetDragOver(ev, effect);
|
||||
return current_drag_op_;
|
||||
}
|
||||
|
||||
void OSRWindow::OnDragLeave() {
|
||||
browser_provider_->GetBrowser()->GetHost()->DragTargetDragLeave();
|
||||
}
|
||||
|
||||
CefBrowserHost::DragOperationsMask
|
||||
OSRWindow::OnDrop(CefMouseEvent ev,
|
||||
CefBrowserHost::DragOperationsMask effect) {
|
||||
browser_provider_->GetBrowser()->GetHost()->DragTargetDragOver(ev, effect);
|
||||
browser_provider_->GetBrowser()->GetHost()->DragTargetDrop(ev);
|
||||
return current_drag_op_;
|
||||
}
|
||||
|
||||
OSRWindow::OSRWindow(OSRBrowserProvider* browser_provider, bool transparent)
|
||||
: renderer_(transparent),
|
||||
browser_provider_(browser_provider),
|
||||
@ -174,7 +231,8 @@ OSRWindow::OSRWindow(OSRBrowserProvider* browser_provider, bool transparent)
|
||||
hDC_(NULL),
|
||||
hRC_(NULL),
|
||||
painting_popup_(false),
|
||||
render_task_pending_(false) {
|
||||
render_task_pending_(false),
|
||||
current_drag_op_(DRAG_OPERATION_NONE) {
|
||||
}
|
||||
|
||||
OSRWindow::~OSRWindow() {
|
||||
|
@ -7,6 +7,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "include/cef_render_handler.h"
|
||||
#include "cefclient/cefclient_osr_dragdrop_win.h"
|
||||
#include "cefclient/client_handler.h"
|
||||
#include "cefclient/osrenderer.h"
|
||||
|
||||
@ -18,7 +19,8 @@ class OSRBrowserProvider {
|
||||
virtual ~OSRBrowserProvider() {}
|
||||
};
|
||||
|
||||
class OSRWindow : public ClientHandler::RenderHandler {
|
||||
class OSRWindow : public ClientHandler::RenderHandler,
|
||||
public DragEvents {
|
||||
public:
|
||||
// Create a new OSRWindow instance. |browser_provider| must outlive this
|
||||
// object.
|
||||
@ -64,9 +66,31 @@ class OSRWindow : public ClientHandler::RenderHandler {
|
||||
int height) OVERRIDE;
|
||||
virtual void OnCursorChange(CefRefPtr<CefBrowser> browser,
|
||||
CefCursorHandle cursor) OVERRIDE;
|
||||
virtual bool StartDragging(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefDragData> drag_data,
|
||||
CefRenderHandler::DragOperationsMask allowed_ops,
|
||||
int x, int y) OVERRIDE;
|
||||
|
||||
virtual void UpdateDragCursor(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRenderHandler::DragOperation operation) OVERRIDE;
|
||||
|
||||
// DragEvents methods
|
||||
virtual CefBrowserHost::DragOperationsMask OnDragEnter(
|
||||
CefRefPtr<CefDragData> drag_data,
|
||||
CefMouseEvent ev,
|
||||
CefBrowserHost::DragOperationsMask effect) OVERRIDE;
|
||||
virtual CefBrowserHost::DragOperationsMask OnDragOver(CefMouseEvent ev,
|
||||
CefBrowserHost::DragOperationsMask effect) OVERRIDE;
|
||||
virtual void OnDragLeave() OVERRIDE;
|
||||
virtual CefBrowserHost::DragOperationsMask OnDrop(CefMouseEvent ev,
|
||||
CefBrowserHost::DragOperationsMask effect) OVERRIDE;
|
||||
|
||||
void Invalidate();
|
||||
|
||||
static int GetCefKeyboardModifiers(WPARAM wparam, LPARAM lparam);
|
||||
static int GetCefMouseModifiers(WPARAM wparam);
|
||||
|
||||
private:
|
||||
OSRWindow(OSRBrowserProvider* browser_provider, bool transparent);
|
||||
virtual ~OSRWindow();
|
||||
@ -78,8 +102,6 @@ class OSRWindow : public ClientHandler::RenderHandler {
|
||||
static ATOM RegisterOSRClass(HINSTANCE hInstance, LPCTSTR className);
|
||||
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
static int GetCefKeyboardModifiers(WPARAM wparam, LPARAM lparam);
|
||||
static int GetCefMouseModifiers(WPARAM wparam);
|
||||
static bool isKeyDown(WPARAM wparam);
|
||||
bool IsOverPopupWidget(int x, int y) const;
|
||||
int GetPopupXOffset() const;
|
||||
@ -92,6 +114,9 @@ class OSRWindow : public ClientHandler::RenderHandler {
|
||||
HDC hDC_;
|
||||
HGLRC hRC_;
|
||||
|
||||
CComPtr<DropTargetWin> drop_target_;
|
||||
CefRenderHandler::DragOperation current_drag_op_;
|
||||
|
||||
bool painting_popup_;
|
||||
bool render_task_pending_;
|
||||
|
||||
|
@ -240,7 +240,7 @@ void ClientHandler::OnDownloadUpdated(
|
||||
|
||||
bool ClientHandler::OnDragEnter(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefDragData> dragData,
|
||||
DragOperationsMask mask) {
|
||||
CefDragHandler::DragOperationsMask mask) {
|
||||
REQUIRE_UI_THREAD();
|
||||
|
||||
// Forbid dragging of link URLs.
|
||||
@ -568,6 +568,22 @@ void ClientHandler::OnCursorChange(CefRefPtr<CefBrowser> browser,
|
||||
m_OSRHandler->OnCursorChange(browser, cursor);
|
||||
}
|
||||
|
||||
bool ClientHandler::StartDragging(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefDragData> drag_data,
|
||||
CefRenderHandler::DragOperationsMask allowed_ops,
|
||||
int x, int y) {
|
||||
if (!m_OSRHandler.get())
|
||||
return false;
|
||||
return m_OSRHandler->StartDragging(browser, drag_data, allowed_ops, x, y);
|
||||
}
|
||||
|
||||
void ClientHandler::UpdateDragCursor(CefRefPtr<CefBrowser> browser,
|
||||
CefRenderHandler::DragOperation operation) {
|
||||
if (!m_OSRHandler.get())
|
||||
return;
|
||||
m_OSRHandler->UpdateDragCursor(browser, operation);
|
||||
}
|
||||
|
||||
void ClientHandler::SetMainHwnd(CefWindowHandle hwnd) {
|
||||
AutoLock lock_scope(this);
|
||||
m_MainHwnd = hwnd;
|
||||
|
@ -116,7 +116,7 @@ class ClientHandler : public CefClient,
|
||||
// CefDragHandler methods
|
||||
virtual bool OnDragEnter(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefDragData> dragData,
|
||||
DragOperationsMask mask) OVERRIDE;
|
||||
CefDragHandler::DragOperationsMask mask) OVERRIDE;
|
||||
|
||||
// CefGeolocationHandler methods
|
||||
virtual void OnRequestGeolocationPermission(
|
||||
@ -198,6 +198,13 @@ class ClientHandler : public CefClient,
|
||||
int height) OVERRIDE;
|
||||
virtual void OnCursorChange(CefRefPtr<CefBrowser> browser,
|
||||
CefCursorHandle cursor) OVERRIDE;
|
||||
virtual bool StartDragging(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefDragData> drag_data,
|
||||
CefRenderHandler::DragOperationsMask allowed_ops,
|
||||
int x, int y) OVERRIDE;
|
||||
virtual void UpdateDragCursor(CefRefPtr<CefBrowser> browser,
|
||||
CefRenderHandler::DragOperation operation)
|
||||
OVERRIDE;
|
||||
|
||||
void SetMainHwnd(CefWindowHandle hwnd);
|
||||
CefWindowHandle GetMainHwnd() { return m_MainHwnd; }
|
||||
|
24
tests/cefclient/dragdrop_events.h
Normal file
24
tests/cefclient/dragdrop_events.h
Normal file
@ -0,0 +1,24 @@
|
||||
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_TESTS_CEFCLIENT_DRAGDROP_EVENTS_H_
|
||||
#define CEF_TESTS_CEFCLIENT_DRAGDROP_EVENTS_H_
|
||||
#pragma once
|
||||
#include "include/cef_render_handler.h"
|
||||
#include "cefclient/client_handler.h"
|
||||
|
||||
class DragEvents {
|
||||
public:
|
||||
virtual CefBrowserHost::DragOperationsMask OnDragEnter(
|
||||
CefRefPtr<CefDragData> drag_data,
|
||||
CefMouseEvent ev,
|
||||
CefBrowserHost::DragOperationsMask effect) = 0;
|
||||
virtual CefBrowserHost::DragOperationsMask OnDragOver(CefMouseEvent ev,
|
||||
CefBrowserHost::DragOperationsMask effect) = 0;
|
||||
virtual void OnDragLeave() = 0;
|
||||
virtual CefBrowserHost::DragOperationsMask OnDrop(CefMouseEvent ev,
|
||||
CefBrowserHost::DragOperationsMask effect) = 0;
|
||||
};
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_DRAGDROP_EVENTS_H_
|
@ -6,6 +6,25 @@
|
||||
body {background:rgba(255, 0, 0, 0.5); }
|
||||
input {-webkit-appearance: none; }
|
||||
#LI11select {width: 75px;}
|
||||
.dropdiv {
|
||||
width:50px;
|
||||
height:50px;
|
||||
border:1px solid #aaaaaa;
|
||||
float: left;
|
||||
}
|
||||
#dragdiv {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background-color: green;
|
||||
margin: 10px;
|
||||
}
|
||||
#draghere {
|
||||
position: relative;
|
||||
z-index: -1;
|
||||
top: 7px;
|
||||
left: 7px;
|
||||
opacity: 0.4;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
function getElement(id) { return document.getElementById(id); }
|
||||
@ -24,9 +43,27 @@
|
||||
param += event.button;
|
||||
|
||||
// Results in a call to the OnQuery method in os_rendering_unittest.cc.
|
||||
window.testQuery({request: param});
|
||||
if (window.testQuery)
|
||||
window.testQuery({request: param});
|
||||
}
|
||||
|
||||
function allowDrop(ev) {
|
||||
ev.preventDefault();
|
||||
}
|
||||
|
||||
function drag(ev) {
|
||||
ev.dataTransfer.setData("Text",ev.target.id);
|
||||
}
|
||||
|
||||
function drop(ev) {
|
||||
var data=ev.dataTransfer.getData("Text");
|
||||
ev.target.innerHTML = '';
|
||||
var dragged = document.getElementById(data);
|
||||
dragged.setAttribute('draggable', 'false');
|
||||
ev.target.appendChild(dragged);
|
||||
if (window.testQuery)
|
||||
window.testQuery({request: "osrdrop"});
|
||||
}
|
||||
</script>
|
||||
<body onfocus='onEventTest(event)' onblur='onEventTest(event)' onload='load();'>
|
||||
<h1 id='LI00' onclick="onEventTest(event)">
|
||||
@ -56,6 +93,12 @@
|
||||
<li id='LI10' title='EXPECTED_TOOLTIP'>Mouse over this element will
|
||||
trigger show a tooltip</li>
|
||||
</ol>
|
||||
<div class="dropdiv" id="dropdiv" ondrop="drop(event)" ondragover="allowDrop(event)">
|
||||
<span id="draghere">Drag here</span>
|
||||
</div>
|
||||
<div class="dropdiv">
|
||||
<div id="dragdiv" draggable="true" ondragstart="drag(event)"></div>
|
||||
</div>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
@ -75,6 +75,8 @@ const CefRect kEditBoxRect(412, 245, 60, 22);
|
||||
const CefRect kNavigateButtonRect(360, 271, 140, 22);
|
||||
const CefRect kSelectRect(467, 22, 75, 20);
|
||||
const CefRect kExpandedSelectRect(467, 42, 81, 322);
|
||||
const CefRect kDropDivRect(8, 332, 52, 52);
|
||||
const CefRect kDragDivRect(71, 342, 30, 30);
|
||||
const int kDefaultVerticalScrollbarWidth = 17;
|
||||
const int kVerticalScrollbarWidth = GetSystemMetrics(SM_CXVSCROLL);
|
||||
const int kHorizontalScrollbarWidth = GetSystemMetrics(SM_CXHSCROLL);
|
||||
@ -83,11 +85,15 @@ const CefRect kEditBoxRect(429, 228, 60, 25);
|
||||
const CefRect kNavigateButtonRect(375, 251, 138, 28);
|
||||
const CefRect kSelectRect(461, 21, 87, 26);
|
||||
const CefRect kExpandedSelectRect(467, 42, 80, 262);
|
||||
const CefRect kDropDivRect(8, 312, 52, 52);
|
||||
const CefRect kDragDivRect(71, 324, 30, 30);
|
||||
#elif defined(OS_LINUX)
|
||||
const CefRect kEditBoxRect(434, 246, 60, 20);
|
||||
const CefRect kNavigateButtonRect(380, 271, 140, 22);
|
||||
const CefRect kSelectRect(467, 22, 75, 20);
|
||||
const CefRect kExpandedSelectRect(467, 42, 79, 322);
|
||||
const CefRect kDropDivRect(8, 332, 52, 52);
|
||||
const CefRect kDragDivRect(71, 342, 30, 30);
|
||||
const int kDefaultVerticalScrollbarWidth = 14;
|
||||
const int kVerticalScrollbarWidth = 14;
|
||||
const int kHorizontalScrollbarWidth = 14;
|
||||
@ -187,6 +193,12 @@ enum OSRTestType {
|
||||
OSR_TEST_POPUP_HIDE_ON_ESC,
|
||||
// scrolling inside the popup should trigger repaint for popup area
|
||||
OSR_TEST_POPUP_SCROLL_INSIDE,
|
||||
// clicking and moving the mouse will call StartDragging
|
||||
OSR_TEST_DRAG_DROP_START_DRAGGING,
|
||||
// starting dragging over the drop region will call UpdateDragCursor
|
||||
OSR_TEST_DRAG_DROP_UPDATE_CURSOR,
|
||||
// dropping element inside drop region will move the element
|
||||
OSR_TEST_DRAG_DROP_DROP,
|
||||
};
|
||||
|
||||
// Used in the browser process.
|
||||
@ -276,6 +288,10 @@ class OSRTestHandler : public RoutingTestHandler,
|
||||
EXPECT_STREQ(messageStr.c_str(), "osrmousemove");
|
||||
DestroySucceededTestSoon();
|
||||
break;
|
||||
case OSR_TEST_DRAG_DROP_DROP:
|
||||
EXPECT_STREQ(messageStr.c_str(), "osrdrop");
|
||||
DestroySucceededTestSoon();
|
||||
break;
|
||||
default:
|
||||
// Intentionally left blank
|
||||
break;
|
||||
@ -304,7 +320,7 @@ class OSRTestHandler : public RoutingTestHandler,
|
||||
CefRefPtr<CefRequest> request) OVERRIDE {
|
||||
std::string url = request->GetURL();
|
||||
|
||||
if (url.find("http://tests/osrtest") == 0) {
|
||||
if (url.find(kTestUrl) == 0) {
|
||||
// Show the osr test contents
|
||||
CefRefPtr<CefStreamReader> stream =
|
||||
GetBinaryResourceReader("osr_test.html");
|
||||
@ -426,18 +442,22 @@ class OSRTestHandler : public RoutingTestHandler,
|
||||
// Send events after the first full repaint
|
||||
switch (test_type_) {
|
||||
case OSR_TEST_PAINT:
|
||||
// test that we have a full repaint
|
||||
EXPECT_EQ(dirtyRects.size(), 1U);
|
||||
EXPECT_TRUE(IsFullRepaint(dirtyRects[0]));
|
||||
EXPECT_EQ(*(reinterpret_cast<const uint32*>(buffer)), 0xffff8080);
|
||||
DestroySucceededTestSoon();
|
||||
if (StartTest()) {
|
||||
// test that we have a full repaint
|
||||
EXPECT_EQ(dirtyRects.size(), 1U);
|
||||
EXPECT_TRUE(IsFullRepaint(dirtyRects[0]));
|
||||
EXPECT_EQ(*(reinterpret_cast<const uint32*>(buffer)), 0xffff8080);
|
||||
DestroySucceededTestSoon();
|
||||
}
|
||||
break;
|
||||
case OSR_TEST_TRANSPARENCY:
|
||||
// test that we have a full repaint
|
||||
EXPECT_EQ(dirtyRects.size(), 1U);
|
||||
EXPECT_TRUE(IsFullRepaint(dirtyRects[0]));
|
||||
EXPECT_EQ(*(reinterpret_cast<const uint32*>(buffer)), 0x7f7f0000U);
|
||||
DestroySucceededTestSoon();
|
||||
if (StartTest()) {
|
||||
// test that we have a full repaint
|
||||
EXPECT_EQ(dirtyRects.size(), 1U);
|
||||
EXPECT_TRUE(IsFullRepaint(dirtyRects[0]));
|
||||
EXPECT_EQ(*(reinterpret_cast<const uint32*>(buffer)), 0x7f7f0000U);
|
||||
DestroySucceededTestSoon();
|
||||
}
|
||||
break;
|
||||
case OSR_TEST_FOCUS:
|
||||
if (StartTest()) {
|
||||
@ -629,17 +649,19 @@ class OSRTestHandler : public RoutingTestHandler,
|
||||
// 1) vertical scrollbar
|
||||
// 2) discovered new area (bottom side)
|
||||
// 3) the whole visible rect.
|
||||
EXPECT_EQ(dirtyRects.size(), 3U);
|
||||
EXPECT_EQ(dirtyRects[0], CefRect(0, 0,
|
||||
kOsrWidth - kVerticalScrollbarWidth, kHorizontalScrollbarWidth));
|
||||
EXPECT_EQ(3U, dirtyRects.size());
|
||||
if (dirtyRects.size() == 3U) {
|
||||
EXPECT_EQ(dirtyRects[0], CefRect(0, 0,
|
||||
kOsrWidth - kVerticalScrollbarWidth, kHorizontalScrollbarWidth));
|
||||
|
||||
EXPECT_EQ(dirtyRects[1], CefRect(0, kHorizontalScrollbarWidth,
|
||||
kOsrWidth, kOsrHeight - 2 * kHorizontalScrollbarWidth));
|
||||
EXPECT_EQ(dirtyRects[1], CefRect(0, kHorizontalScrollbarWidth,
|
||||
kOsrWidth, kOsrHeight - 2 * kHorizontalScrollbarWidth));
|
||||
|
||||
EXPECT_EQ(dirtyRects[2],
|
||||
CefRect(0, kOsrHeight - kHorizontalScrollbarWidth,
|
||||
kOsrWidth - kVerticalScrollbarWidth,
|
||||
kHorizontalScrollbarWidth));
|
||||
EXPECT_EQ(dirtyRects[2],
|
||||
CefRect(0, kOsrHeight - kHorizontalScrollbarWidth,
|
||||
kOsrWidth - kVerticalScrollbarWidth,
|
||||
kHorizontalScrollbarWidth));
|
||||
}
|
||||
#elif defined(OS_MACOSX)
|
||||
// On Mac, when scrollbars are Always on, there is a single update of
|
||||
// the whole view
|
||||
@ -779,6 +801,29 @@ class OSRTestHandler : public RoutingTestHandler,
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OSR_TEST_DRAG_DROP_START_DRAGGING:
|
||||
case OSR_TEST_DRAG_DROP_UPDATE_CURSOR:
|
||||
case OSR_TEST_DRAG_DROP_DROP:
|
||||
{
|
||||
// trigger the StartDragging event
|
||||
if (StartTest()) {
|
||||
// move the mouse over the element to drag
|
||||
CefMouseEvent mouse_event;
|
||||
mouse_event.x = MiddleX(kDragDivRect);
|
||||
mouse_event.y = MiddleY(kDragDivRect);
|
||||
mouse_event.modifiers = 0;
|
||||
browser->GetHost()->SendMouseMoveEvent(mouse_event, false);
|
||||
// click on the element to drag
|
||||
mouse_event.modifiers = EVENTFLAG_LEFT_MOUSE_BUTTON;
|
||||
browser->GetHost()->SendMouseClickEvent(mouse_event, MBT_LEFT,
|
||||
false, 1);
|
||||
// move the mouse to start dragging
|
||||
mouse_event.x -= 5;
|
||||
mouse_event.y -= 5;
|
||||
browser->GetHost()->SendMouseMoveEvent(mouse_event, false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -791,6 +836,60 @@ class OSRTestHandler : public RoutingTestHandler,
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool StartDragging(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefDragData> drag_data,
|
||||
DragOperationsMask allowed_ops,
|
||||
int x, int y) {
|
||||
if (test_type_ == OSR_TEST_DRAG_DROP_START_DRAGGING && started()) {
|
||||
DestroySucceededTestSoon();
|
||||
return false;
|
||||
} else if ((test_type_ == OSR_TEST_DRAG_DROP_UPDATE_CURSOR ||
|
||||
test_type_ == OSR_TEST_DRAG_DROP_DROP) && started()) {
|
||||
// place the mouse over the drop area to trigger UpdateDragCursor
|
||||
CefRefPtr<CefDragData> data = drag_data->Clone();
|
||||
data->ResetFileContents();
|
||||
CefMouseEvent ev;
|
||||
ev.x = MiddleX(kDragDivRect) - 5;
|
||||
ev.y = MiddleY(kDragDivRect) - 5;
|
||||
ev.modifiers = EVENTFLAG_LEFT_MOUSE_BUTTON;
|
||||
browser->GetHost()->DragTargetDragEnter(data, ev, allowed_ops);
|
||||
|
||||
ev.x = MiddleX(kDropDivRect);
|
||||
ev.y = MiddleY(kDropDivRect);
|
||||
browser->GetHost()->SendMouseMoveEvent(ev, false);
|
||||
browser->GetHost()->DragTargetDragOver(ev, allowed_ops);
|
||||
|
||||
ev.x += 5;
|
||||
ev.y += 5;
|
||||
browser->GetHost()->SendMouseMoveEvent(ev, false);
|
||||
browser->GetHost()->DragTargetDragOver(ev, allowed_ops);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void UpdateDragCursor(CefRefPtr<CefBrowser> browser,
|
||||
DragOperation operation) {
|
||||
if (test_type_ == OSR_TEST_DRAG_DROP_UPDATE_CURSOR && started()) {
|
||||
if (operation != DRAG_OPERATION_NONE) {
|
||||
browser->GetHost()->DragSourceEndedAt(MiddleX(kDropDivRect),
|
||||
MiddleY(kDropDivRect),
|
||||
DRAG_OPERATION_NONE);
|
||||
browser->GetHost()->DragSourceSystemDragEnded();
|
||||
DestroySucceededTestSoon();
|
||||
}
|
||||
} else if (test_type_ == OSR_TEST_DRAG_DROP_DROP && started()) {
|
||||
CefMouseEvent ev;
|
||||
ev.x = MiddleX(kDropDivRect);
|
||||
ev.y = MiddleY(kDropDivRect);
|
||||
ev.modifiers = 0;
|
||||
browser->GetHost()->SendMouseClickEvent(ev, MBT_LEFT, true, 1);
|
||||
browser->GetHost()->DragTargetDrop(ev);
|
||||
browser->GetHost()->DragSourceEndedAt(ev.x, ev.y, operation);
|
||||
browser->GetHost()->DragSourceSystemDragEnded();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnScrollOffsetChanged(CefRefPtr<CefBrowser> browser) OVERRIDE {
|
||||
if (test_type_ == OSR_TEST_SCROLLING && started()) {
|
||||
DestroySucceededTestSoon();
|
||||
@ -948,3 +1047,6 @@ OSR_TEST(PopupHideOnClick, OSR_TEST_POPUP_HIDE_ON_CLICK);
|
||||
OSR_TEST(PopupHideOnScroll, OSR_TEST_POPUP_HIDE_ON_SCROLL);
|
||||
OSR_TEST(PopupHideOnEsc, OSR_TEST_POPUP_HIDE_ON_ESC);
|
||||
OSR_TEST(PopupScrollInside, OSR_TEST_POPUP_SCROLL_INSIDE);
|
||||
OSR_TEST(DragDropStartDragging, OSR_TEST_DRAG_DROP_START_DRAGGING);
|
||||
OSR_TEST(DragDropUpdateCursor, OSR_TEST_DRAG_DROP_UPDATE_CURSOR);
|
||||
OSR_TEST(DragDropDropElement, OSR_TEST_DRAG_DROP_DROP);
|
||||
|
Loading…
x
Reference in New Issue
Block a user