dnd: Make "formats" a construct-only property

... and hide the member variable inside the DragContextPrivate.
This commit is contained in:
Benjamin Otte 2018-05-07 17:31:26 +02:00
parent 80f5fd8435
commit 34d1ebc562
8 changed files with 110 additions and 61 deletions

View 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);

View File

@ -86,7 +86,6 @@ struct _GdkDragContext {
GdkSurface *drag_surface;
GdkContentProvider *content;
GdkContentFormats *formats;
GdkDragAction actions;
GdkDragAction suggested_action;
GdkDragAction action;

View 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;

View 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;

View 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) |

View 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;

View 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);

View 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));