mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
Linux: cefclient: Add OSR drag&drop implementation (issue #2008)
This commit is contained in:
@ -880,6 +880,21 @@ void GetWidgetRectInScreen(GtkWidget* widget, GdkRectangle* r) {
|
||||
r->height = widget->allocation.height;
|
||||
}
|
||||
|
||||
CefBrowserHost::DragOperationsMask
|
||||
GetDragOperationsMask(GdkDragContext* drag_context) {
|
||||
int allowed_ops = DRAG_OPERATION_NONE;
|
||||
GdkDragAction drag_action = gdk_drag_context_get_actions(drag_context);
|
||||
if (drag_action & GDK_ACTION_COPY)
|
||||
allowed_ops |= DRAG_OPERATION_COPY;
|
||||
if (drag_action & GDK_ACTION_MOVE)
|
||||
allowed_ops |= DRAG_OPERATION_MOVE;
|
||||
if (drag_action & GDK_ACTION_LINK)
|
||||
allowed_ops |= DRAG_OPERATION_LINK;
|
||||
if (drag_action & GDK_ACTION_PRIVATE)
|
||||
allowed_ops |= DRAG_OPERATION_PRIVATE;
|
||||
return static_cast<CefBrowserHost::DragOperationsMask>(allowed_ops);
|
||||
}
|
||||
|
||||
class ScopedGLContext {
|
||||
public:
|
||||
ScopedGLContext(GtkWidget* widget, bool swap_buffers)
|
||||
@ -921,10 +936,27 @@ BrowserWindowOsrGtk::BrowserWindowOsrGtk(BrowserWindow::Delegate* delegate,
|
||||
hidden_(false),
|
||||
gl_enabled_(false),
|
||||
painting_popup_(false),
|
||||
device_scale_factor_(1.0f) {
|
||||
device_scale_factor_(1.0f),
|
||||
drag_trigger_event_(NULL),
|
||||
drag_data_(NULL),
|
||||
drag_operation_(DRAG_OPERATION_NONE),
|
||||
drag_context_(NULL),
|
||||
drag_targets_(gtk_target_list_new(NULL, 0)),
|
||||
drag_leave_(false),
|
||||
drag_drop_(false) {
|
||||
client_handler_ = new ClientHandlerOsr(this, this, startup_url);
|
||||
}
|
||||
|
||||
BrowserWindowOsrGtk::~BrowserWindowOsrGtk() {
|
||||
if (drag_trigger_event_) {
|
||||
gdk_event_free(drag_trigger_event_);
|
||||
}
|
||||
if (drag_context_) {
|
||||
g_object_unref(drag_context_);
|
||||
}
|
||||
gtk_target_list_unref(drag_targets_);
|
||||
}
|
||||
|
||||
void BrowserWindowOsrGtk::CreateBrowser(
|
||||
ClientWindowHandle parent_handle,
|
||||
const CefRect& rect,
|
||||
@ -1052,6 +1084,8 @@ void BrowserWindowOsrGtk::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
|
||||
// Detach |this| from the ClientHandlerOsr.
|
||||
static_cast<ClientHandlerOsr*>(client_handler_.get())->DetachOsrDelegate();
|
||||
|
||||
UnregisterDragDrop();
|
||||
|
||||
// Disconnect all signal handlers that reference |this|.
|
||||
g_signal_handlers_disconnect_matched(glarea_, G_SIGNAL_MATCH_DATA, 0, 0,
|
||||
NULL, NULL, this);
|
||||
@ -1194,14 +1228,48 @@ bool BrowserWindowOsrGtk::StartDragging(
|
||||
CefRenderHandler::DragOperationsMask allowed_ops,
|
||||
int x, int y) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
// TODO(port): Implement drag&drop support.
|
||||
return false;
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (!drag_data->HasImage()) {
|
||||
LOG(ERROR) << "Drag image representation not available";
|
||||
return false;
|
||||
}
|
||||
|
||||
DragReset();
|
||||
drag_data_ = drag_data;
|
||||
|
||||
// Begin drag.
|
||||
if (drag_trigger_event_) {
|
||||
LOG(ERROR) << "Dragging started, but last mouse event is missing";
|
||||
DragReset();
|
||||
return false;
|
||||
}
|
||||
drag_context_ = gtk_drag_begin(glarea_, drag_targets_, GDK_ACTION_COPY,
|
||||
1, // left mouse button
|
||||
drag_trigger_event_);
|
||||
if (!drag_context_) {
|
||||
LOG(ERROR) << "GTK drag begin failed";
|
||||
DragReset();
|
||||
return false;
|
||||
}
|
||||
g_object_ref(drag_context_);
|
||||
|
||||
// Send drag enter event.
|
||||
CefMouseEvent ev;
|
||||
ev.x = x;
|
||||
ev.y = y;
|
||||
ev.modifiers = EVENTFLAG_LEFT_MOUSE_BUTTON;
|
||||
browser->GetHost()->DragTargetDragEnter(drag_data, ev, allowed_ops);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BrowserWindowOsrGtk::UpdateDragCursor(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRenderHandler::DragOperation operation) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
REQUIRE_MAIN_THREAD();
|
||||
drag_operation_ = operation;
|
||||
}
|
||||
|
||||
void BrowserWindowOsrGtk::OnImeCompositionRangeChanged(
|
||||
@ -1263,6 +1331,8 @@ void BrowserWindowOsrGtk::Create(ClientWindowHandle parent_handle) {
|
||||
g_signal_connect(G_OBJECT(glarea_), "focus_out_event",
|
||||
G_CALLBACK(&BrowserWindowOsrGtk::FocusEvent), this);
|
||||
|
||||
RegisterDragDrop();
|
||||
|
||||
gtk_container_add(GTK_CONTAINER(parent_handle), glarea_);
|
||||
|
||||
// Make the GlArea visible in the parent container.
|
||||
@ -1332,6 +1402,16 @@ gint BrowserWindowOsrGtk::ClickEvent(GtkWidget* widget,
|
||||
}
|
||||
|
||||
host->SendMouseClickEvent(mouse_event, button_type, mouse_up, click_count);
|
||||
|
||||
// Save mouse event that can be a possible trigger for drag.
|
||||
if (!self->drag_context_ && button_type == MBT_LEFT) {
|
||||
if (self->drag_trigger_event_) {
|
||||
gdk_event_free(self->drag_trigger_event_);
|
||||
}
|
||||
self->drag_trigger_event_ =
|
||||
gdk_event_copy(reinterpret_cast<GdkEvent*>(event));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -1412,6 +1492,12 @@ gint BrowserWindowOsrGtk::MoveEvent(GtkWidget* widget,
|
||||
x = (gint)event->x;
|
||||
y = (gint)event->y;
|
||||
state = (GdkModifierType)event->state;
|
||||
if (x == 0 && y == 0) {
|
||||
// Invalid coordinates of (0,0) appear from time to time in
|
||||
// enter-notify-event and leave-notify-event events. Sending them may
|
||||
// cause StartDragging to never get called, so just ignore these.
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
CefMouseEvent mouse_event;
|
||||
@ -1422,8 +1508,18 @@ gint BrowserWindowOsrGtk::MoveEvent(GtkWidget* widget,
|
||||
mouse_event.modifiers = GetCefStateModifiers(state);
|
||||
|
||||
bool mouse_leave = (event->type == GDK_LEAVE_NOTIFY);
|
||||
|
||||
host->SendMouseMoveEvent(mouse_event, mouse_leave);
|
||||
|
||||
// Save mouse event that can be a possible trigger for drag.
|
||||
if (!self->drag_context_ &&
|
||||
(mouse_event.modifiers & EVENTFLAG_LEFT_MOUSE_BUTTON)) {
|
||||
if (self->drag_trigger_event_) {
|
||||
gdk_event_free(self->drag_trigger_event_);
|
||||
}
|
||||
self->drag_trigger_event_ =
|
||||
gdk_event_copy(reinterpret_cast<GdkEvent*>(event));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -1531,4 +1627,328 @@ void BrowserWindowOsrGtk::DisableGL() {
|
||||
gl_enabled_ = false;
|
||||
}
|
||||
|
||||
void BrowserWindowOsrGtk::RegisterDragDrop() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
// Succession of CEF d&d calls:
|
||||
// 1. DragTargetDragEnter
|
||||
// 2. DragTargetDragOver
|
||||
// 3. DragTargetDragLeave - optional
|
||||
// 4. DragSourceSystemDragEnded - optional, to cancel dragging
|
||||
// 5. DragTargetDrop
|
||||
// 6. DragSourceEndedAt
|
||||
// 7. DragSourceSystemDragEnded
|
||||
|
||||
// Succession of GTK d&d events:
|
||||
// 1. drag-begin-event, drag-data-get
|
||||
// 2. drag-motion
|
||||
// 3. drag-leave
|
||||
// 4. drag-failed
|
||||
// 5. drag-drop, drag-data-received
|
||||
// 6. 7. drag-end-event
|
||||
|
||||
// Using gtk_drag_begin in StartDragging instead of calling
|
||||
// gtk_drag_source_set here. Doing so because when using gtk_drag_source_set
|
||||
// then StartDragging is being called very late, about ten DragMotion events
|
||||
// after DragBegin, and drag icon can be set only when beginning drag.
|
||||
// Default values for drag threshold are set to 8 pixels in both GTK and
|
||||
// Chromium, but doesn't work as expected.
|
||||
// --OFF--
|
||||
// gtk_drag_source_set(glarea_, GDK_BUTTON1_MASK, NULL, 0, GDK_ACTION_COPY);
|
||||
|
||||
// Source widget events.
|
||||
g_signal_connect(G_OBJECT(glarea_), "drag_begin",
|
||||
G_CALLBACK(&BrowserWindowOsrGtk::DragBegin), this);
|
||||
g_signal_connect(G_OBJECT(glarea_), "drag_data_get",
|
||||
G_CALLBACK(&BrowserWindowOsrGtk::DragDataGet), this);
|
||||
g_signal_connect(G_OBJECT(glarea_), "drag_end",
|
||||
G_CALLBACK(&BrowserWindowOsrGtk::DragEnd), this);
|
||||
|
||||
// Destination widget and its events.
|
||||
gtk_drag_dest_set(glarea_,
|
||||
(GtkDestDefaults) 0,
|
||||
(GtkTargetEntry*) NULL,
|
||||
0,
|
||||
(GdkDragAction) GDK_ACTION_COPY);
|
||||
g_signal_connect(G_OBJECT(glarea_), "drag_motion",
|
||||
G_CALLBACK(&BrowserWindowOsrGtk::DragMotion), this);
|
||||
g_signal_connect(G_OBJECT(glarea_), "drag_leave",
|
||||
G_CALLBACK(&BrowserWindowOsrGtk::DragLeave), this);
|
||||
g_signal_connect(G_OBJECT(glarea_), "drag_failed",
|
||||
G_CALLBACK(&BrowserWindowOsrGtk::DragFailed), this);
|
||||
g_signal_connect(G_OBJECT(glarea_), "drag_drop",
|
||||
G_CALLBACK(&BrowserWindowOsrGtk::DragDrop), this);
|
||||
g_signal_connect(G_OBJECT(glarea_), "drag_data_received",
|
||||
G_CALLBACK(&BrowserWindowOsrGtk::DragDataReceived), this);
|
||||
}
|
||||
|
||||
void BrowserWindowOsrGtk::UnregisterDragDrop() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
gtk_drag_dest_unset(glarea_);
|
||||
// Drag events are unregistered in OnBeforeClose by calling
|
||||
// g_signal_handlers_disconnect_matched.
|
||||
}
|
||||
|
||||
void BrowserWindowOsrGtk::DragReset() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
if (drag_trigger_event_) {
|
||||
gdk_event_free(drag_trigger_event_);
|
||||
drag_trigger_event_ = NULL;
|
||||
}
|
||||
drag_data_ = NULL;
|
||||
drag_operation_ = DRAG_OPERATION_NONE;
|
||||
if (drag_context_) {
|
||||
g_object_unref(drag_context_);
|
||||
drag_context_ = NULL;
|
||||
}
|
||||
drag_leave_ = false;
|
||||
drag_drop_ = false;
|
||||
}
|
||||
|
||||
// static
|
||||
void BrowserWindowOsrGtk::DragBegin(GtkWidget* widget,
|
||||
GdkDragContext* drag_context,
|
||||
BrowserWindowOsrGtk* self) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
// Load drag icon.
|
||||
if (!self->drag_data_->HasImage()) {
|
||||
LOG(ERROR) << "Failed to set drag icon, drag image not available";
|
||||
return;
|
||||
}
|
||||
int pixel_width = 0;
|
||||
int pixel_height = 0;
|
||||
CefRefPtr<CefBinaryValue> image_binary =
|
||||
self->drag_data_->GetImage()->GetAsPNG(self->device_scale_factor_,
|
||||
true,
|
||||
pixel_width,
|
||||
pixel_height);
|
||||
if (!image_binary) {
|
||||
LOG(ERROR) << "Failed to set drag icon, drag image error";
|
||||
return;
|
||||
}
|
||||
size_t image_size = image_binary->GetSize();
|
||||
guint8* image_buffer = (guint8*) malloc(image_size); // must free
|
||||
image_binary->GetData((void*) image_buffer, image_size, 0);
|
||||
GdkPixbufLoader* loader = NULL; // must unref
|
||||
GError* error = NULL; // must free
|
||||
GdkPixbuf* pixbuf = NULL; // owned by loader
|
||||
gboolean success = FALSE;
|
||||
loader = gdk_pixbuf_loader_new_with_type("png", &error);
|
||||
if (error == NULL && loader) {
|
||||
success = gdk_pixbuf_loader_write(loader, image_buffer, image_size, NULL);
|
||||
if (success) {
|
||||
success = gdk_pixbuf_loader_close(loader, NULL);
|
||||
if (success) {
|
||||
pixbuf = gdk_pixbuf_loader_get_pixbuf(loader);
|
||||
if (pixbuf) {
|
||||
CefPoint image_hotspot = self->drag_data_->GetImageHotspot();
|
||||
int hotspot_x = image_hotspot.x;
|
||||
int hotspot_y = image_hotspot.y;
|
||||
gtk_drag_set_icon_pixbuf(drag_context, pixbuf, hotspot_x, hotspot_y);
|
||||
} else {
|
||||
LOG(ERROR) << "Failed to set drag icon, pixbuf error";
|
||||
}
|
||||
} else {
|
||||
LOG(ERROR) << "Failed to set drag icon, loader close error";
|
||||
}
|
||||
} else {
|
||||
LOG(ERROR) << "Failed to set drag icon, loader write error";
|
||||
}
|
||||
} else {
|
||||
LOG(ERROR) << "Failed to set drag icon, loader creation error";
|
||||
}
|
||||
if (loader) {
|
||||
g_object_unref(loader); // unref
|
||||
}
|
||||
if (error) {
|
||||
g_error_free(error); // free
|
||||
}
|
||||
free(image_buffer); // free
|
||||
}
|
||||
|
||||
// static
|
||||
void BrowserWindowOsrGtk::DragDataGet(GtkWidget* widget,
|
||||
GdkDragContext* drag_context,
|
||||
GtkSelectionData* data,
|
||||
guint info,
|
||||
guint time,
|
||||
BrowserWindowOsrGtk* self) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
// No drag targets are set so this callback is never called.
|
||||
}
|
||||
|
||||
// static
|
||||
void BrowserWindowOsrGtk::DragEnd(GtkWidget* widget,
|
||||
GdkDragContext* drag_context,
|
||||
BrowserWindowOsrGtk* self) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (self->browser_) {
|
||||
// Sometimes there is DragEnd event generated without prior DragDrop.
|
||||
// Maybe related to drag-leave bug described in comments in DragLeave.
|
||||
if (!self->drag_drop_) {
|
||||
// Real coordinates not available.
|
||||
self->browser_->GetHost()->DragSourceEndedAt(-1, -1,
|
||||
self->drag_operation_);
|
||||
}
|
||||
self->browser_->GetHost()->DragSourceSystemDragEnded();
|
||||
}
|
||||
|
||||
self->DragReset();
|
||||
}
|
||||
|
||||
// static
|
||||
gboolean BrowserWindowOsrGtk::DragMotion(GtkWidget* widget,
|
||||
GdkDragContext* drag_context,
|
||||
gint x,
|
||||
gint y,
|
||||
guint time,
|
||||
BrowserWindowOsrGtk* self) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
// MoveEvent is never called during drag & drop, so must call
|
||||
// SendMouseMoveEvent here.
|
||||
CefMouseEvent mouse_event;
|
||||
mouse_event.x = x;
|
||||
mouse_event.y = y;
|
||||
mouse_event.modifiers = EVENTFLAG_LEFT_MOUSE_BUTTON;
|
||||
self->ApplyPopupOffset(mouse_event.x, mouse_event.y);
|
||||
DeviceToLogical(mouse_event, self->device_scale_factor_);
|
||||
if (self->browser_) {
|
||||
bool mouse_leave = self->drag_leave_;
|
||||
self->browser_->GetHost()->SendMouseMoveEvent(mouse_event, mouse_leave);
|
||||
}
|
||||
|
||||
// Mouse event.
|
||||
CefMouseEvent ev;
|
||||
ev.x = x;
|
||||
ev.y = y;
|
||||
ev.modifiers = EVENTFLAG_LEFT_MOUSE_BUTTON;
|
||||
|
||||
CefBrowserHost::DragOperationsMask allowed_ops =
|
||||
GetDragOperationsMask(drag_context);
|
||||
|
||||
// Send drag enter event if needed.
|
||||
if (self->drag_leave_ && self->browser_) {
|
||||
self->browser_->GetHost()->DragTargetDragEnter(self->drag_data_, ev,
|
||||
allowed_ops);
|
||||
}
|
||||
|
||||
// Send drag over event.
|
||||
if (self->browser_) {
|
||||
self->browser_->GetHost()->DragTargetDragOver(ev, allowed_ops);
|
||||
}
|
||||
|
||||
// Update GTK drag status.
|
||||
if (widget == self->glarea_) {
|
||||
gdk_drag_status(drag_context, GDK_ACTION_COPY, time);
|
||||
if (self->drag_leave_) {
|
||||
self->drag_leave_ = false;
|
||||
}
|
||||
return TRUE;
|
||||
} else {
|
||||
LOG(WARNING) << "Invalid drag destination widget";
|
||||
gdk_drag_status(drag_context, (GdkDragAction) 0, time);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void BrowserWindowOsrGtk::DragLeave(GtkWidget* widget,
|
||||
GdkDragContext* drag_context,
|
||||
guint time,
|
||||
BrowserWindowOsrGtk* self) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
// There is no drag-enter event in GTK. The first drag-motion event
|
||||
// after drag-leave will be a drag-enter event.
|
||||
|
||||
// There seems to be a bug during GTK drop, drag-leave event is generated
|
||||
// just before drag-drop. A solution is to call DragTargetDragEnter
|
||||
// and DragTargetDragOver in DragDrop when drag_leave_ is true.
|
||||
|
||||
// Send drag leave event.
|
||||
if (self->browser_) {
|
||||
self->browser_->GetHost()->DragTargetDragLeave();
|
||||
}
|
||||
|
||||
self->drag_leave_ = true;
|
||||
}
|
||||
|
||||
// static
|
||||
gboolean BrowserWindowOsrGtk::DragFailed(GtkWidget* widget,
|
||||
GdkDragContext* drag_context,
|
||||
GtkDragResult result,
|
||||
BrowserWindowOsrGtk* self) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
// Send drag end coordinates and system drag ended event.
|
||||
if (self->browser_) {
|
||||
// Real coordinates not available.
|
||||
self->browser_->GetHost()->DragSourceEndedAt(-1, -1,
|
||||
self->drag_operation_);
|
||||
self->browser_->GetHost()->DragSourceSystemDragEnded();
|
||||
}
|
||||
|
||||
self->DragReset();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// static
|
||||
gboolean BrowserWindowOsrGtk::DragDrop(GtkWidget* widget,
|
||||
GdkDragContext* drag_context,
|
||||
gint x,
|
||||
gint y,
|
||||
guint time,
|
||||
BrowserWindowOsrGtk* self) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
// Finish GTK drag.
|
||||
gtk_drag_finish(drag_context, TRUE, FALSE, time);
|
||||
|
||||
// Mouse event.
|
||||
CefMouseEvent ev;
|
||||
ev.x = x;
|
||||
ev.y = y;
|
||||
ev.modifiers = EVENTFLAG_LEFT_MOUSE_BUTTON;
|
||||
|
||||
CefBrowserHost::DragOperationsMask allowed_ops =
|
||||
GetDragOperationsMask(drag_context);
|
||||
|
||||
// Send drag enter/over events if needed (read comment in DragLeave).
|
||||
if (self->drag_leave_ && self->browser_) {
|
||||
self->browser_->GetHost()->DragTargetDragEnter(self->drag_data_, ev,
|
||||
allowed_ops);
|
||||
self->browser_->GetHost()->DragTargetDragOver(ev, allowed_ops);
|
||||
}
|
||||
|
||||
// Send drag drop event.
|
||||
if (self->browser_) {
|
||||
self->browser_->GetHost()->DragTargetDrop(ev);
|
||||
}
|
||||
|
||||
// Send drag end coordinates.
|
||||
if (self->browser_) {
|
||||
self->browser_->GetHost()->DragSourceEndedAt(x, y, self->drag_operation_);
|
||||
}
|
||||
|
||||
self->drag_drop_ = true;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// static
|
||||
void BrowserWindowOsrGtk::DragDataReceived(GtkWidget* widget,
|
||||
GdkDragContext* drag_context,
|
||||
gint x,
|
||||
gint y,
|
||||
GtkSelectionData* data,
|
||||
guint info,
|
||||
guint time,
|
||||
BrowserWindowOsrGtk* self) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
// This callback is never called because DragDrop does not call
|
||||
// gtk_drag_get_data, as only dragging inside web view is supported.
|
||||
}
|
||||
|
||||
} // namespace client
|
||||
|
@ -82,6 +82,8 @@ class BrowserWindowOsrGtk : public BrowserWindow,
|
||||
const CefRenderHandler::RectList& character_bounds) OVERRIDE;
|
||||
|
||||
private:
|
||||
~BrowserWindowOsrGtk();
|
||||
|
||||
// Create the GTK GlArea.
|
||||
void Create(ClientWindowHandle parent_handle);
|
||||
|
||||
@ -113,6 +115,51 @@ class BrowserWindowOsrGtk : public BrowserWindow,
|
||||
void EnableGL();
|
||||
void DisableGL();
|
||||
|
||||
// Drag & drop
|
||||
void RegisterDragDrop();
|
||||
void UnregisterDragDrop();
|
||||
void DragReset();
|
||||
static void DragBegin(GtkWidget* widget,
|
||||
GdkDragContext* drag_context,
|
||||
BrowserWindowOsrGtk* self);
|
||||
static void DragDataGet(GtkWidget* widget,
|
||||
GdkDragContext* drag_context,
|
||||
GtkSelectionData* data,
|
||||
guint info,
|
||||
guint time,
|
||||
BrowserWindowOsrGtk* self);
|
||||
static void DragEnd(GtkWidget* widget,
|
||||
GdkDragContext* drag_context,
|
||||
BrowserWindowOsrGtk* self);
|
||||
static gboolean DragMotion(GtkWidget* widget,
|
||||
GdkDragContext* drag_context,
|
||||
gint x,
|
||||
gint y,
|
||||
guint time,
|
||||
BrowserWindowOsrGtk* self);
|
||||
static void DragLeave(GtkWidget* widget,
|
||||
GdkDragContext* drag_context,
|
||||
guint time,
|
||||
BrowserWindowOsrGtk* self);
|
||||
static gboolean DragFailed(GtkWidget* widget,
|
||||
GdkDragContext* drag_context,
|
||||
GtkDragResult result,
|
||||
BrowserWindowOsrGtk* self);
|
||||
static gboolean DragDrop(GtkWidget* widget,
|
||||
GdkDragContext* drag_context,
|
||||
gint x,
|
||||
gint y,
|
||||
guint time,
|
||||
BrowserWindowOsrGtk* self);
|
||||
static void DragDataReceived(GtkWidget* widget,
|
||||
GdkDragContext* drag_context,
|
||||
gint x,
|
||||
gint y,
|
||||
GtkSelectionData* data,
|
||||
guint info,
|
||||
guint time,
|
||||
BrowserWindowOsrGtk* self);
|
||||
|
||||
// The below members will only be accessed on the main thread which should be
|
||||
// the same as the CEF UI thread.
|
||||
OsrRenderer renderer_;
|
||||
@ -123,6 +170,15 @@ class BrowserWindowOsrGtk : public BrowserWindow,
|
||||
|
||||
float device_scale_factor_;
|
||||
|
||||
// Drag & drop
|
||||
GdkEvent* drag_trigger_event_; // mouse event, a possible trigger for drag
|
||||
CefRefPtr<CefDragData> drag_data_;
|
||||
CefRenderHandler::DragOperation drag_operation_;
|
||||
GdkDragContext* drag_context_;
|
||||
GtkTargetList* drag_targets_;
|
||||
bool drag_leave_;
|
||||
bool drag_drop_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(BrowserWindowOsrGtk);
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user