static void
gcal_event_widget_drag_begin (GtkWidget      *widget,
                              GdkDragContext *context)
{
  GcalEventWidget *self;
  cairo_surface_t *surface;
  GdkWindow *window;
  GdkDevice *device;
  gint x, y;
  GtkAllocation allocation;

  self = GCAL_EVENT_WIDGET (widget);
  window = gtk_widget_get_window (widget);
  device = gdk_drag_context_get_device (context);

  if (self->read_only)
    {
      gtk_drag_cancel (context);
      return;
    }

  /* Setup the drag n' drop icon */
  surface = get_dnd_icon (widget);

  gtk_drag_set_icon_surface (context, surface);

  /* reposition drag surface to the point the GCalEvent was */
  gtk_widget_get_allocation (widget, &allocation);
  gdk_window_get_device_position (window, device, &x, &y, NULL);
  gdk_drag_context_set_hotspot (context, x - allocation.x, y - allocation.y);

  g_clear_pointer (&surface, cairo_surface_destroy);
}
Beispiel #2
0
void DragAndDropHandler::startDrag(Ref<SelectionData>&& selection, DragOperation dragOperation, RefPtr<ShareableBitmap>&& dragImage)
{
#if GTK_CHECK_VERSION(3, 16, 0)
    m_draggingSelectionData = WTFMove(selection);
    GRefPtr<GtkTargetList> targetList = PasteboardHelper::singleton().targetListForSelectionData(*m_draggingSelectionData);
#else
    RefPtr<SelectionData> selectionData = WTFMove(selection);
    GRefPtr<GtkTargetList> targetList = PasteboardHelper::singleton().targetListForSelectionData(*selectionData);
#endif

    GUniquePtr<GdkEvent> currentEvent(gtk_get_current_event());
    GdkDragContext* context = gtk_drag_begin(m_page.viewWidget(), targetList.get(), dragOperationToGdkDragActions(dragOperation),
        GDK_BUTTON_PRIMARY, currentEvent.get());

#if GTK_CHECK_VERSION(3, 16, 0)
    // WebCore::EventHandler does not support more than one DnD operation at the same time for
    // a given page, so we should cancel any previous operation whose context we might have
    // stored, should we receive a new startDrag event before finishing a previous DnD operation.
    if (m_dragContext)
        gtk_drag_cancel(m_dragContext.get());
    m_dragContext = context;
#else
    // We don't have gtk_drag_cancel() in GTK+ < 3.16, so we use the old code.
    // See https://bugs.webkit.org/show_bug.cgi?id=138468
    m_draggingSelectionDataMap.set(context, WTFMove(selectionData));
#endif

    if (dragImage) {
        RefPtr<cairo_surface_t> image(dragImage->createCairoSurface());
        // Use the center of the drag image as hotspot.
        cairo_surface_set_device_offset(image.get(), -cairo_image_surface_get_width(image.get()) / 2, -cairo_image_surface_get_height(image.get()) / 2);
        gtk_drag_set_icon_surface(context, image.get());
    } else
        gtk_drag_set_icon_default(context);
}