dnd: Make "formats" a construct-only property
authorBenjamin Otte <otte@redhat.com>
Mon, 7 May 2018 15:31:26 +0000 (17:31 +0200)
committerBenjamin Otte <otte@redhat.com>
Mon, 7 May 2018 16:55:09 +0000 (18:55 +0200)
... and hide the member variable inside the DragContextPrivate.

gdk/gdkdnd.c
gdk/gdkdndprivate.h
gdk/wayland/gdkdnd-wayland.c
gdk/win32/gdkdrag-win32.c
gdk/win32/gdkdrop-win32.c
gdk/x11/gdkdnd-x11.c
testsuite/gtk/notify.c
testsuite/gtk/objects-finalize.c

index ae90dbdd96b577c718995d6c7e494872e9bd613d..191ef7eb754c6997e7db4c734005c070ce510282 100644 (file)
@@ -41,6 +41,7 @@ struct _GdkDragContextPrivate
 {
   GdkDisplay *display;
   GdkDevice *device;
+  GdkContentFormats *formats;
 };
 
 static struct {
@@ -131,9 +132,11 @@ gdk_drag_context_get_display (GdkDragContext *context)
 GdkContentFormats *
 gdk_drag_context_get_formats (GdkDragContext *context)
 {
+  GdkDragContextPrivate *priv = gdk_drag_context_get_instance_private (context);
+
   g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL);
 
-  return context->formats;
+  return priv->formats;
 }
 
 /**
@@ -255,7 +258,10 @@ gdk_drag_context_set_property (GObject      *gobject,
     case PROP_CONTENT:
       context->content = g_value_dup_object (value);
       if (context->content)
-        context->formats = gdk_content_provider_ref_formats (context->content);
+        {
+          g_assert (priv->formats == NULL);
+          priv->formats = gdk_content_provider_ref_formats (context->content);
+        }
       break;
 
     case PROP_DEVICE:
@@ -264,6 +270,23 @@ gdk_drag_context_set_property (GObject      *gobject,
       priv->display = gdk_device_get_display (priv->device);
       break;
 
+    case PROP_FORMATS:
+      if (priv->formats)
+        {
+          GdkContentFormats *override = g_value_dup_boxed (value);
+          if (override)
+            {
+              gdk_content_formats_unref (priv->formats);
+              priv->formats = override;
+            }
+        }
+      else
+        {
+          priv->formats = g_value_dup_boxed (value);
+          g_assert (priv->formats != NULL);
+        }
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
       break;
@@ -294,7 +317,7 @@ gdk_drag_context_get_property (GObject    *gobject,
       break;
 
     case PROP_FORMATS:
-      g_value_set_boxed (value, context->formats);
+      g_value_set_boxed (value, priv->formats);
       break;
 
     default:
@@ -307,11 +330,12 @@ static void
 gdk_drag_context_finalize (GObject *object)
 {
   GdkDragContext *context = GDK_DRAG_CONTEXT (object);
+  GdkDragContextPrivate *priv = gdk_drag_context_get_instance_private (context);
 
   contexts = g_list_remove (contexts, context);
 
   g_clear_object (&context->content);
-  g_clear_pointer (&context->formats, gdk_content_formats_unref);
+  g_clear_pointer (&priv->formats, gdk_content_formats_unref);
 
   if (context->source_surface)
     g_object_unref (context->source_surface);
@@ -420,7 +444,8 @@ gdk_drag_context_class_init (GdkDragContextClass *klass)
                         "Formats",
                         "The possible formats for data",
                         GDK_TYPE_CONTENT_FORMATS,
-                        G_PARAM_READABLE |
+                        G_PARAM_READWRITE |
+                        G_PARAM_CONSTRUCT_ONLY |
                         G_PARAM_STATIC_STRINGS |
                         G_PARAM_EXPLICIT_NOTIFY);
 
index 9778bc00e05eaab6ae4290c419a9fb2d4a3c6fe2..8f779dabb2ae186b52a7b715408776c5a931e09c 100644 (file)
@@ -86,7 +86,6 @@ struct _GdkDragContext {
   GdkSurface *drag_surface;
 
   GdkContentProvider *content;
-  GdkContentFormats *formats;
   GdkDragAction actions;
   GdkDragAction suggested_action;
   GdkDragAction action;
index 39bd25d7db61bc713e3dcbd6f6862ff6a16a2c60..e23a8185e84bb3dc46ea9d91706f086baa501f44 100644 (file)
@@ -181,7 +181,7 @@ gdk_wayland_drop_context_set_status (GdkDragContext *context,
       const char *const *mimetypes;
       gsize i, n_mimetypes;
       
-      mimetypes = gdk_content_formats_get_mime_types (context->formats, &n_mimetypes);
+      mimetypes = gdk_content_formats_get_mime_types (gdk_drag_context_get_formats (context), &n_mimetypes);
       for (i = 0; i < n_mimetypes; i++)
         {
           if (mimetypes[i] != g_intern_static_string ("DELETE"))
@@ -474,7 +474,7 @@ _gdk_wayland_surface_drag_begin (GdkSurface          *surface,
   context_wayland->data_source =
   gdk_wayland_selection_get_data_source (surface);
 
-  mimetypes = gdk_content_formats_get_mime_types (context->formats, &n_mimetypes);
+  mimetypes = gdk_content_formats_get_mime_types (gdk_drag_context_get_formats (context), &n_mimetypes);
   for (i = 0; i < n_mimetypes; i++)
     {
       wl_data_source_offer (context_wayland->data_source, mimetypes[i]);
@@ -509,10 +509,10 @@ _gdk_wayland_drop_context_new (GdkDevice            *device,
 
   context_wayland = g_object_new (GDK_TYPE_WAYLAND_DRAG_CONTEXT,
                                   "device", device,
+                                  "formats", formats,
                                   NULL);
   context = GDK_DRAG_CONTEXT (context_wayland);
   context->is_source = FALSE;
-  context->formats = formats;
   context_wayland->offer = offer;
 
   return context;
index 4d8a3aab327c91e21be5428aff5ac22df497a79d..e490ee07fc415d9b44b96a6281c3f8c0bcdea7d6 100644 (file)
@@ -801,6 +801,7 @@ static GdkDragContext *
 gdk_drag_context_new (GdkDisplay         *display,
                       GdkContentProvider *content,
                       GdkSurface         *source_surface,
+                      GdkContentFormats  *formats,
                       GdkDragAction       actions,
                       GdkDevice          *device,
                       GdkDragProtocol     protocol)
@@ -812,6 +813,7 @@ gdk_drag_context_new (GdkDisplay         *display,
   context_win32 = g_object_new (GDK_TYPE_WIN32_DRAG_CONTEXT,
                                 "device", device ? device : gdk_seat_get_pointer (gdk_display_get_default_seat (display)),
                                 "content", content,
+                                "formats", formats,
                                 NULL);
 
   context = GDK_DRAG_CONTEXT (context_win32);
@@ -826,6 +828,8 @@ gdk_drag_context_new (GdkDisplay         *display,
   context->actions = actions;
   context_win32->protocol = protocol;
 
+  gdk_content_formats_unref (formats);
+
   return context;
 }
 
@@ -1659,7 +1663,7 @@ data_object_new (GdkDragContext *context)
   result->context = context;
   result->formats = g_array_new (FALSE, FALSE, sizeof (GdkWin32ContentFormatPair));
 
-  mime_types = gdk_content_formats_get_mime_types (context->formats, &n_mime_types);
+  mime_types = gdk_content_formats_get_mime_types (gdk_drag_context_get_formats (context), &n_mime_types);
 
   for (i = 0; i < n_mime_types; i++)
     {
@@ -1910,10 +1914,10 @@ _gdk_win32_surface_drag_begin (GdkSurface        *window,
   context = gdk_drag_context_new (gdk_surface_get_display (window),
                                   content,
                                   window,
+                                  gdk_content_formats_union_serialize_mime_types (gdk_content_provider_ref_storable_formats (content)),
                                   actions,
                                   device,
                                   use_ole2_dnd ? GDK_DRAG_PROTO_OLE2 : GDK_DRAG_PROTO_LOCAL);
-  context->formats = gdk_content_formats_union_serialize_mime_types (gdk_content_provider_ref_storable_formats (content));
 
   context_win32 = GDK_WIN32_DRAG_CONTEXT (context);
 
@@ -1944,7 +1948,9 @@ _gdk_win32_surface_drag_begin (GdkSurface        *window,
       source_drag_context *source_ctx;
       data_object         *data_obj;
 
-      source_ctx = source_context_new (context, window, context->formats);
+      source_ctx = source_context_new (context, 
+                                       window,
+                                       gdk_drag_context_get_formats (context));
       data_obj = data_object_new (context);
 
       ddd->base.item_type = GDK_WIN32_DND_THREAD_QUEUE_ITEM_DO_DRAG_DROP;
index d2a9656a86d1e85ca23935c3cf82a9d65c675591..48a78e79de7250a50f11e845d6759d90d6f02206 100644 (file)
@@ -130,11 +130,12 @@ gdk_win32_drop_context_finalize (GObject *object)
 /* Drag Contexts */
 
 static GdkDragContext *
-gdk_drop_context_new (GdkDisplay      *display,
-                      GdkSurface      *source_surface,
-                      GdkSurface      *dest_surface,
-                      GdkDragAction    actions,
-                      GdkDragProtocol  protocol)
+gdk_drop_context_new (GdkDisplay        *display,
+                      GdkSurface        *source_surface,
+                      GdkSurface        *dest_surface,
+                      GdkContentFormats *formats,
+                      GdkDragAction      actions,
+                      GdkDragProtocol    protocol)
 {
   GdkWin32DropContext *context_win32;
   GdkWin32Display *win32_display = GDK_WIN32_DISPLAY (display);
@@ -142,6 +143,7 @@ gdk_drop_context_new (GdkDisplay      *display,
 
   context_win32 = g_object_new (GDK_TYPE_WIN32_DROP_CONTEXT,
                                 "device", gdk_seat_get_pointer (gdk_display_get_default_seat (display)),
+                                "formats", formats,
                                 NULL);
 
   context = GDK_DRAG_CONTEXT (context_win32);
@@ -159,6 +161,8 @@ gdk_drop_context_new (GdkDisplay      *display,
   context->actions = actions;
   context_win32->protocol = protocol;
 
+  gdk_content_formats_unref (formats);
+
   return context;
 }
 
@@ -431,11 +435,11 @@ idroptarget_dragenter (LPDROPTARGET This,
                                    */
                                   source_context ? source_context->source_surface : NULL,
                                   ctx->dest_surface,
+                                  query_targets (pDataObj, context_win32->droptarget_w32format_contentformat_map),
                                   GDK_ACTION_DEFAULT | GDK_ACTION_COPY | GDK_ACTION_MOVE,
                                   GDK_DRAG_PROTO_OLE2);
   context_win32 = GDK_WIN32_DROP_CONTEXT (context);
   g_array_set_size (context_win32->droptarget_w32format_contentformat_map, 0);
-  context->formats = query_targets (pDataObj, context_win32->droptarget_w32format_contentformat_map);
   g_set_object (&context_win32->local_source_context, GDK_WIN32_DRAG_CONTEXT (source_context));
 
   ctx->context = context;
@@ -718,17 +722,17 @@ gdk_dropfiles_filter (GdkWin32Display *display,
 
       window = gdk_win32_handle_table_lookup (msg->hwnd);
 
-      context = gdk_drop_context_new (display,
+      context = gdk_drop_context_new (GDK_DISPLAY (display),
                                       NULL,
                                       window,
+                                      gdk_content_formats_new ((const char *[2]) {
+                                                                 "text/uri-list",
+                                                                 NULL
+                                                               }, 1),
                                       GDK_ACTION_COPY,
                                       GDK_DRAG_PROTO_WIN32_DROPFILES);
       context_win32 = GDK_WIN32_DROP_CONTEXT (context);
       /* WM_DROPFILES drops are always file names */
-      context->formats = gdk_content_formats_new ((const char *[2]) {
-                                                    "text/uri-list",
-                                                    NULL
-                                                  }, 1);
 
 
       context->suggested_action = GDK_ACTION_COPY;
@@ -1221,9 +1225,9 @@ _gdk_win32_local_send_enter (GdkDragContext *context,
   new_context = gdk_drop_context_new (gdk_surface_get_display (context->source_surface),
                                       context->source_surface,
                                       context->dest_surface,
+                                      gdk_content_formats_ref (gdk_drag_context_get_formats (context)),
                                       context->actions,
                                       GDK_DRAG_PROTO_LOCAL);
-  new_context->formats = gdk_content_formats_ref (context->formats);
 
   gdk_surface_set_events (new_context->source_surface,
                           gdk_surface_get_events (new_context->source_surface) |
index 93c39bf532eb5af958d494099b77eab2d1d5d77d..befcaf65911b5a572ee30a0d9cdcda0f3484e323 100644 (file)
@@ -482,17 +482,15 @@ gdk_drag_context_find (GdkDisplay *display,
 static void
 precache_target_list (GdkDragContext *context)
 {
-  if (context->formats)
-    {
-      const char * const *atoms;
-      gsize n_atoms;
+  GdkContentFormats *formats = gdk_drag_context_get_formats (context);
+  const char * const *atoms;
+  gsize n_atoms;
 
-      atoms = gdk_content_formats_get_mime_types (context->formats, &n_atoms);
+  atoms = gdk_content_formats_get_mime_types (formats, &n_atoms);
 
-      _gdk_x11_precache_atoms (gdk_drag_context_get_display (context),
-                               (const gchar **) atoms,
-                               n_atoms);
-    }
+  _gdk_x11_precache_atoms (gdk_drag_context_get_display (context),
+                           (const gchar **) atoms,
+                           n_atoms);
 }
 
 /* Utility functions */
@@ -1145,7 +1143,7 @@ xdnd_set_targets (GdkX11DragContext *context_x11)
   gsize i, n_atoms;
   GdkDisplay *display = gdk_drag_context_get_display (context);
 
-  atoms = gdk_content_formats_get_mime_types (context->formats, &n_atoms);
+  atoms = gdk_content_formats_get_mime_types (gdk_drag_context_get_formats (context), &n_atoms);
   atomlist = g_new (Atom, n_atoms);
   for (i = 0; i < n_atoms; i++)
     atomlist[i] = gdk_x11_get_xatom_by_name_for_display (display, atoms[i]);
@@ -1332,7 +1330,7 @@ xdnd_send_enter (GdkX11DragContext *context_x11)
   GDK_DISPLAY_NOTE (display, DND,
            g_message ("Sending enter source window %#lx XDND protocol version %d\n",
                       GDK_SURFACE_XID (context_x11->ipc_surface), context_x11->version));
-  atoms = gdk_content_formats_get_mime_types (context->formats, &n_atoms);
+  atoms = gdk_content_formats_get_mime_types (gdk_drag_context_get_formats (context), &n_atoms);
 
   if (n_atoms > 3)
     {
@@ -1735,6 +1733,7 @@ xdnd_enter_filter (const XEvent *xevent,
   gulong nitems, after;
   guchar *data;
   Atom *atoms;
+  GdkContentFormats *content_formats;
   GPtrArray *formats;
   guint32 source_surface;
   gboolean get_types;
@@ -1771,24 +1770,6 @@ xdnd_enter_filter (const XEvent *xevent,
     }
 
   seat = gdk_display_get_default_seat (display);
-  context_x11 = g_object_new (GDK_TYPE_X11_DRAG_CONTEXT,
-                              "device", gdk_seat_get_pointer (seat),
-                              NULL);
-  context = (GdkDragContext *)context_x11;
-
-  context_x11->protocol = GDK_DRAG_PROTO_XDND;
-  context_x11->version = version;
-
-  /* FIXME: Should extend DnD protocol to have device info */
-
-  context->source_surface = gdk_x11_surface_foreign_new_for_display (display, source_surface);
-  if (!context->source_surface)
-    {
-      g_object_unref (context);
-      return GDK_FILTER_REMOVE;
-    }
-  context->dest_surface = event->any.surface;
-  g_object_ref (context->dest_surface);
 
   formats = g_ptr_array_new ();
   if (get_types)
@@ -1803,8 +1784,6 @@ xdnd_enter_filter (const XEvent *xevent,
 
       if (gdk_x11_display_error_trap_pop (display) || (format != 32) || (type != XA_ATOM))
         {
-          g_object_unref (context);
-
           if (data)
             XFree (data);
 
@@ -1826,14 +1805,33 @@ xdnd_enter_filter (const XEvent *xevent,
                            (gpointer) gdk_x11_get_xatom_name_for_display (display,
                                                                           xevent->xclient.data.l[2 + i]));
     }
-  context->formats = gdk_content_formats_new ((const char **) formats->pdata, formats->len);
+  content_formats = gdk_content_formats_new ((const char **) formats->pdata, formats->len);
   g_ptr_array_unref (formats);
 
 #ifdef G_ENABLE_DEBUG
   if (GDK_DISPLAY_DEBUG_CHECK (display, DND))
-    print_target_list (context->formats);
+    print_target_list (content_formats);
 #endif /* G_ENABLE_DEBUG */
 
+  context_x11 = g_object_new (GDK_TYPE_X11_DRAG_CONTEXT,
+                              "device", gdk_seat_get_pointer (seat),
+                              "formats", content_formats,
+                              NULL);
+  context = (GdkDragContext *)context_x11;
+
+  context_x11->protocol = GDK_DRAG_PROTO_XDND;
+  context_x11->version = version;
+
+  /* FIXME: Should extend DnD protocol to have device info */
+
+  context->source_surface = gdk_x11_surface_foreign_new_for_display (display, source_surface);
+  if (!context->source_surface)
+    {
+      g_object_unref (context);
+      return GDK_FILTER_REMOVE;
+    }
+  context->dest_surface = event->any.surface;
+  g_object_ref (context->dest_surface);
   xdnd_manage_source_filter (context, context->source_surface, TRUE);
   xdnd_read_actions (context_x11);
 
@@ -1844,6 +1842,8 @@ xdnd_enter_filter (const XEvent *xevent,
 
   display_x11->current_dest_drag = context;
 
+  gdk_content_formats_unref (content_formats);
+
   return GDK_FILTER_TRANSLATE;
 }
 
@@ -2345,11 +2345,12 @@ gdk_x11_drag_context_drag_motion (GdkDragContext *context,
 
             case GDK_DRAG_PROTO_ROOTWIN:
               {
+                GdkContentFormats *formats = gdk_drag_context_get_formats (context);
                 /* GTK+ traditionally has used application/x-rootwin-drop,
                  * but the XDND spec specifies x-rootwindow-drop.
                  */
-                if (gdk_content_formats_contain_mime_type (context->formats, "application/x-rootwindow-drop") ||
-                    gdk_content_formats_contain_mime_type (context->formats, "application/x-rootwin-drop"))
+                if (gdk_content_formats_contain_mime_type (formats, "application/x-rootwindow-drop") ||
+                    gdk_content_formats_contain_mime_type (formats, "application/x-rootwin-drop"))
                   context->action = context->suggested_action;
                 else
                   context->action = 0;
index 1b88db8f418392bf1d5f259bfb593978cd918588..2738cca4ae4b9debdd92eac30a9162da532591ee 100644 (file)
@@ -411,7 +411,14 @@ test_type (gconstpointer data)
   else if (g_str_equal (g_type_name (type), "GdkClipboard"))
     instance = g_object_new (type, "display", display, NULL);
   else if (g_str_equal (g_type_name (type), "GdkDragContext"))
-    instance = g_object_new (type, "device", gdk_seat_get_pointer (gdk_display_get_default_seat (gdk_display_get_default ())), NULL);
+    {
+      GdkContentFormats *formats = gdk_content_formats_new_for_gtype (G_TYPE_STRING);
+      instance = g_object_new (type,
+                               "device", gdk_seat_get_pointer (gdk_display_get_default_seat (gdk_display_get_default ())),
+                               "formats", formats,
+                               NULL);
+      gdk_content_formats_unref (formats);
+    }
   else
     instance = g_object_new (type, NULL);
 
index bb3af68031ee02b69934f2d4754bd4e53231550a..a712ee8aba4f287e9b65d29882165a796562ffc5 100644 (file)
@@ -55,7 +55,14 @@ test_finalize_object (gconstpointer data)
   if (g_str_equal (g_type_name (test_type), "GdkClipboard"))
     object = g_object_new (test_type, "display", gdk_display_get_default (), NULL);
   else if (g_str_equal (g_type_name (test_type), "GdkDragContext"))
-    object = g_object_new (test_type, "device", gdk_seat_get_pointer (gdk_display_get_default_seat (gdk_display_get_default ())), NULL);
+    {
+      GdkContentFormats *formats = gdk_content_formats_new_for_gtype (G_TYPE_STRING);
+      object = g_object_new (test_type,
+                             "device", gdk_seat_get_pointer (gdk_display_get_default_seat (gdk_display_get_default ())),
+                             "formats", formats,
+                             NULL);
+      gdk_content_formats_unref (formats);
+    }
   else
     object = g_object_new (test_type, NULL);
   g_assert (G_IS_OBJECT (object));