Compare commits
274 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e16a3b6232 | |||
| 20dddd83d6 | |||
| 6cc5331e6b | |||
| ee2b1601ff | |||
| 2c317b99a2 | |||
| da2e184639 | |||
| 9576222b47 | |||
| 7738a05bd2 | |||
| 93b5b487ae | |||
| 7588655a42 | |||
| 007713c0ba | |||
| f0c1c3349f | |||
| 0dba6e5759 | |||
| 60cd7cd96c | |||
| 2b504201e3 | |||
| 3fcbe8d5f3 | |||
| 105acfe908 | |||
| 1caf197a0d | |||
| 0a49726c73 | |||
| dd0cc9df9f | |||
| 789f6f3941 | |||
| 2c231f4336 | |||
| 3c50e5324f | |||
| 3182063ffe | |||
| 5910e5ac6d | |||
| b2b89f6c57 | |||
| 5ac24db049 | |||
| 192a24fa1f | |||
| 2426b9e23a | |||
| 64848aebf4 | |||
| fcceac6d11 | |||
| 975f6529b1 | |||
| 357e215fb8 | |||
| 4716c9ae2f | |||
| 5aad3d7d0e | |||
| fe36c24b07 | |||
| 682068f887 | |||
| e8eb1df29f | |||
| 82dc7b903c | |||
| b020a3fcf9 | |||
| cb88de5938 | |||
| 94b1e72aa3 | |||
| 20b92638ec | |||
| dccb83c9ec | |||
| d668d2fa25 | |||
| 34f1ae8fad | |||
| 042537cf0d | |||
| d03f38470e | |||
| a7d72cf69b | |||
| 256139baab | |||
| a935aae6f1 | |||
| 9955d686ee | |||
| a9da41c66a | |||
| 4d8691b762 | |||
| 806e159b8b | |||
| 794ee0b8c0 | |||
| 2b7de841a9 | |||
| 45309811c5 | |||
| 2b695ac8d1 | |||
| cb03969c5f | |||
| 57e71a6a69 | |||
| 15b5a404b8 | |||
| 4056a40d2d | |||
| c1e9523f0e | |||
| 4c1ccfd7be | |||
| 823e00dec9 | |||
| 3e51966ea9 | |||
| e292767a01 | |||
| 75c433fb5f | |||
| 83867f9cbf | |||
| ea9f0df67b | |||
| 15c7980ba6 | |||
| de5fde1e12 | |||
| a83b360224 | |||
| 4d55d23c1a | |||
| 2b6162116d | |||
| b2ca947934 | |||
| 3eaf88b84c | |||
| 9e9eae3ad4 | |||
| 903afcbddd | |||
| d37612a476 | |||
| f5daecf353 | |||
| b76940bab5 | |||
| ec255f9bb1 | |||
| 9dc6be4fb0 | |||
| 186b783f9d | |||
| 2f3518c80d | |||
| 4a7f68e79e | |||
| 65af983ddb | |||
| f0dc5e0be5 | |||
| f0cbd175cd | |||
| 99aa47185e | |||
| 898e29c989 | |||
| cf1700fd13 | |||
| 112aed590f | |||
| 6763443c5d | |||
| 7d99339c39 | |||
| f33fe6daed | |||
| c7dc17d837 | |||
| a51ee20ed9 | |||
| 8d3e1eb314 | |||
| c941a2d9c6 | |||
| 1c03bbeb9c | |||
| a4059cd02d | |||
| eab6df31ac | |||
| 8a085fcc5a | |||
| 7668669d56 | |||
| 5e57b3d07a | |||
| 187a701a99 | |||
| d5f4579384 | |||
| 0297039b38 | |||
| 5206a92522 | |||
| 233ec1a5d6 | |||
| 579d8e427b | |||
| 9c11c60530 | |||
| 66c8da4750 | |||
| 05a9b72fc8 | |||
| 4fe5710456 | |||
| ac5b4a6307 | |||
| 5ce7bfbbd8 | |||
| 7646d1b22c | |||
| 61db81ab8e | |||
| 24d7586163 | |||
| b150625105 | |||
| 5787146238 | |||
| 8a72031e99 | |||
| 201a791076 | |||
| 359003670a | |||
| 6b7c5174ed | |||
| 8a521accbc | |||
| d116bbf0c8 | |||
| 42e440a111 | |||
| 13adb2591c | |||
| 7b73824dfe | |||
| 403aba82a9 | |||
| a053d7ddb1 | |||
| c878f650ce | |||
| 2d2cdeae88 | |||
| 009228471c | |||
| 379166e1ff | |||
| a59a20c1d4 | |||
| fb4b5c666b | |||
| b59c70aaeb | |||
| 6fcae42dde | |||
| 2ee087f25f | |||
| 9cc29efa25 | |||
| a04d314910 | |||
| f83f7a2b4d | |||
| edb175cf75 | |||
| 1eefaf8b41 | |||
| 0224517806 | |||
| 27c521cce8 | |||
| 62b87182c5 | |||
| c95659bf32 | |||
| 865fc9c925 | |||
| a1f4f52fcb | |||
| bdb4bf00c5 | |||
| aca252837d | |||
| 8b058572f0 | |||
| df050c51bb | |||
| bd20ae4fa5 | |||
| 818b456f9f | |||
| c1c8abf275 | |||
| c1029535ca | |||
| a5ca5eb865 | |||
| 2227d2a2b5 | |||
| 61559e38f4 | |||
| 134fca47e3 | |||
| 4630dd8d68 | |||
| d2f7d1b1d7 | |||
| cfa9e6da4a | |||
| ceca2f9202 | |||
| bf98ebcb12 | |||
| 1a5dece09c | |||
| 8e8254feae | |||
| 90cda9e307 | |||
| fdfa371d90 | |||
| deb16c1a00 | |||
| 8c3736709e | |||
| f459164f8a | |||
| 00169a06bf | |||
| e09f2b8b56 | |||
| 092c115ff0 | |||
| 5144d15168 | |||
| 5a6ab8cbd3 | |||
| 8c73f882af | |||
| 78832c65b5 | |||
| e8b830a3dd | |||
| 38974d7d2b | |||
| f6f331efe3 | |||
| dbb3727b03 | |||
| 508570864d | |||
| 96c77b61c1 | |||
| 2b819c830b | |||
| f3be49838f | |||
| e9067ae2db | |||
| f898bee032 | |||
| 6a7f39e6d2 | |||
| dfb2cbdfdb | |||
| f960eb6ab4 | |||
| 60fc2c6a7a | |||
| 3080592234 | |||
| 532fdde720 | |||
| f8399588e9 | |||
| ad019be75b | |||
| e505dab487 | |||
| 1262184269 | |||
| 46f42fc53d | |||
| cb26cd7391 | |||
| 1a3eeb1233 | |||
| e1f74c8f69 | |||
| 58106af54d | |||
| 1e000c3dac | |||
| 19ee9b4c57 | |||
| 1075607528 | |||
| d2bd9b0850 | |||
| 74d445636c | |||
| 7048790931 | |||
| b9034015d7 | |||
| c7b70b122a | |||
| 6e01a49d10 | |||
| c290bd6367 | |||
| 853063bea7 | |||
| 69e3fee5e2 | |||
| aa276a181e | |||
| 583705b4ae | |||
| cd7303d47c | |||
| 0f9cbf49ac | |||
| a309e74be7 | |||
| ccaf70e1b7 | |||
| 2fd9431f23 | |||
| 3f33a0ed27 | |||
| 4ea18a22e6 | |||
| 746dc5c3a2 | |||
| 17131f1137 | |||
| 07c889c5ea | |||
| b0d9a6ff20 | |||
| 802c7975e2 | |||
| 6e602e052b | |||
| 025eee112c | |||
| 70cdd4e951 | |||
| 75b789f20f | |||
| ac09500d74 | |||
| a76b187a5b | |||
| 45679d7bc3 | |||
| 6dc8fc3a4d | |||
| e53e0f461e | |||
| 37b849b808 | |||
| e03bdbe307 | |||
| 9b01d9a784 | |||
| b4c689ecd6 | |||
| 78a0913f0f | |||
| 74722fb10e | |||
| 3891ce36fe | |||
| 5a940408fe | |||
| efce8c2899 | |||
| ea9f2abcc4 | |||
| 993d6388ee | |||
| 5ad4b75ae2 | |||
| 24ef9df0f1 | |||
| 5d49b11ffd | |||
| 8e3db48482 | |||
| fdcfe0e80a | |||
| 8137dea8c1 | |||
| b15c31a3f7 | |||
| a52757874e | |||
| e9203eeef7 | |||
| 337057eb35 | |||
| 2803a15a51 | |||
| d145032cb6 | |||
| 2612331282 | |||
| d3fd071809 | |||
| 303c9becf8 | |||
| 6bf46c8f30 |
+75
-50
@@ -119,48 +119,76 @@ get_image_paintable (GtkImage *image)
|
||||
}
|
||||
|
||||
static void
|
||||
drag_begin (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
gpointer data)
|
||||
drag_begin (GtkDragSource *source,
|
||||
GdkDrag *drag,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GdkPaintable *paintable;
|
||||
|
||||
paintable = get_image_paintable (GTK_IMAGE (widget));
|
||||
if (paintable)
|
||||
{
|
||||
gtk_drag_set_icon_paintable (drag, paintable, -2, -2);
|
||||
gtk_drag_source_set_icon (source, paintable, -2, -2);
|
||||
g_object_unref (paintable);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
drag_data_get (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
GtkSelectionData *selection_data,
|
||||
guint info,
|
||||
gpointer data)
|
||||
static void
|
||||
get_texture (GValue *value,
|
||||
gpointer data)
|
||||
{
|
||||
GdkPaintable *paintable;
|
||||
GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (data));
|
||||
|
||||
paintable = get_image_paintable (GTK_IMAGE (widget));
|
||||
if (GDK_IS_TEXTURE (paintable))
|
||||
gtk_selection_data_set_texture (selection_data, GDK_TEXTURE (paintable));
|
||||
g_value_set_object (value, paintable);
|
||||
}
|
||||
|
||||
static GdkContentProvider *
|
||||
prepare_drag (GtkDragSource *source,
|
||||
double x,
|
||||
double y,
|
||||
GtkWidget *image)
|
||||
{
|
||||
return gdk_content_provider_new_with_callback (GDK_TYPE_TEXTURE, get_texture, image);
|
||||
}
|
||||
|
||||
static void
|
||||
drag_data_received (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
GtkSelectionData *selection_data,
|
||||
gpointer data)
|
||||
got_texture (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
if (gtk_selection_data_get_length (selection_data) > 0)
|
||||
{
|
||||
GdkTexture *texture;
|
||||
GdkDrop *drop = GDK_DROP (source);
|
||||
GtkWidget *image = data;
|
||||
const GValue *value;
|
||||
GError *error = NULL;
|
||||
|
||||
texture = gtk_selection_data_get_texture (selection_data);
|
||||
gtk_image_set_from_paintable (GTK_IMAGE (data), GDK_PAINTABLE (texture));
|
||||
g_object_unref (texture);
|
||||
value = gdk_drop_read_value_finish (drop, result, &error);
|
||||
if (value)
|
||||
{
|
||||
GdkTexture *texture = g_value_get_object (value);
|
||||
gtk_image_set_from_paintable (GTK_IMAGE (image), GDK_PAINTABLE (texture));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_print ("Failed to get data: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
drag_drop (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
int x,
|
||||
int y,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
if (gdk_drop_has_value (drop, GDK_TYPE_TEXTURE))
|
||||
{
|
||||
gdk_drop_read_value_async (drop, GDK_TYPE_TEXTURE, G_PRIORITY_DEFAULT, NULL, got_texture, widget);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -171,12 +199,8 @@ copy_image (GSimpleAction *action,
|
||||
GdkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (data));
|
||||
GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (data));
|
||||
|
||||
g_print ("copy image\n");
|
||||
if (GDK_IS_TEXTURE (paintable))
|
||||
{
|
||||
g_print ("set clipboard\n");
|
||||
gdk_clipboard_set_texture (clipboard, GDK_TEXTURE (paintable));
|
||||
}
|
||||
gdk_clipboard_set_texture (clipboard, GDK_TEXTURE (paintable));
|
||||
|
||||
if (paintable)
|
||||
g_object_unref (paintable);
|
||||
@@ -247,6 +271,9 @@ do_clipboard (GtkWidget *do_widget)
|
||||
{ "paste", paste_image, NULL, NULL, NULL },
|
||||
};
|
||||
GActionGroup *actions;
|
||||
GtkDragSource *source;
|
||||
GtkDropTarget *dest;
|
||||
GdkContentFormats *formats;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
@@ -305,22 +332,21 @@ do_clipboard (GtkWidget *do_widget)
|
||||
|
||||
/* Create the first image */
|
||||
image = gtk_image_new_from_icon_name ("dialog-warning");
|
||||
gtk_image_set_pixel_size (GTK_IMAGE (image), 48);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), image);
|
||||
|
||||
/* make image a drag source */
|
||||
gtk_drag_source_set (image, GDK_BUTTON1_MASK, NULL, GDK_ACTION_COPY);
|
||||
gtk_drag_source_add_image_targets (image);
|
||||
g_signal_connect (image, "drag-begin",
|
||||
G_CALLBACK (drag_begin), image);
|
||||
g_signal_connect (image, "drag-data-get",
|
||||
G_CALLBACK (drag_data_get), image);
|
||||
source = gtk_drag_source_new ();
|
||||
g_signal_connect (source, "prepare", G_CALLBACK (prepare_drag), NULL);
|
||||
g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (source));
|
||||
|
||||
/* accept drops on image */
|
||||
gtk_drag_dest_set (image, GTK_DEST_DEFAULT_ALL,
|
||||
NULL, GDK_ACTION_COPY);
|
||||
gtk_drag_dest_add_image_targets (image);
|
||||
g_signal_connect (image, "drag-data-received",
|
||||
G_CALLBACK (drag_data_received), image);
|
||||
formats = gdk_content_formats_new_for_gtype (GDK_TYPE_TEXTURE);
|
||||
dest = gtk_drop_target_new (formats, GDK_ACTION_COPY);
|
||||
gdk_content_formats_unref (formats);
|
||||
g_signal_connect (dest, "drag-drop", G_CALLBACK (drag_drop), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (dest));
|
||||
|
||||
/* context menu on image */
|
||||
gesture = gtk_gesture_click_new ();
|
||||
@@ -337,22 +363,21 @@ do_clipboard (GtkWidget *do_widget)
|
||||
|
||||
/* Create the second image */
|
||||
image = gtk_image_new_from_icon_name ("process-stop");
|
||||
gtk_image_set_pixel_size (GTK_IMAGE (image), 48);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), image);
|
||||
|
||||
/* make image a drag source */
|
||||
gtk_drag_source_set (image, GDK_BUTTON1_MASK, NULL, GDK_ACTION_COPY);
|
||||
gtk_drag_source_add_image_targets (image);
|
||||
g_signal_connect (image, "drag-begin",
|
||||
G_CALLBACK (drag_begin), image);
|
||||
g_signal_connect (image, "drag-data-get",
|
||||
G_CALLBACK (drag_data_get), image);
|
||||
source = gtk_drag_source_new ();
|
||||
g_signal_connect (source, "prepare", G_CALLBACK (prepare_drag), NULL);
|
||||
g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (source));
|
||||
|
||||
/* accept drops on image */
|
||||
gtk_drag_dest_set (image, GTK_DEST_DEFAULT_ALL,
|
||||
NULL, GDK_ACTION_COPY);
|
||||
gtk_drag_dest_add_image_targets (image);
|
||||
g_signal_connect (image, "drag-data-received",
|
||||
G_CALLBACK (drag_data_received), image);
|
||||
formats = gdk_content_formats_new_for_gtype (GDK_TYPE_TEXTURE);
|
||||
dest = gtk_drop_target_new (formats, GDK_ACTION_COPY);
|
||||
gdk_content_formats_unref (formats);
|
||||
g_signal_connect (dest, "drag-drop", G_CALLBACK (drag_drop), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (dest));
|
||||
|
||||
/* context menu on image */
|
||||
gesture = gtk_gesture_click_new ();
|
||||
|
||||
@@ -97,6 +97,7 @@ do_infobar (GtkWidget *do_widget)
|
||||
gtk_label_set_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar))), label);
|
||||
gtk_info_bar_set_default_response (GTK_INFO_BAR (bar), GTK_RESPONSE_OK);
|
||||
|
||||
button = gtk_toggle_button_new_with_label ("Question");
|
||||
g_object_bind_property (bar, "revealed", button, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
|
||||
|
||||
@@ -5,9 +5,6 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
/* Drag 'n Drop */
|
||||
static const char *target_table[] = {
|
||||
"text/uri-list"
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -76,30 +73,11 @@ search_text_changed (GtkEntry *entry, IconBrowserWindow *win)
|
||||
gtk_tree_model_filter_refilter (win->filter_model);
|
||||
}
|
||||
|
||||
static GdkPixbuf *
|
||||
get_icon (GtkWidget *image, const gchar *name, gint size)
|
||||
{
|
||||
GtkIconInfo *info;
|
||||
GtkStyleContext *context;
|
||||
GdkTexture *texture;
|
||||
GdkPixbuf *pixbuf;
|
||||
|
||||
context = gtk_widget_get_style_context (image);
|
||||
info = gtk_icon_theme_lookup_icon (gtk_icon_theme_get_default (), name, size, 0);
|
||||
texture = GDK_TEXTURE (gtk_icon_info_load_symbolic_for_context (info, context, NULL, NULL));
|
||||
pixbuf = gdk_pixbuf_get_from_texture (texture);
|
||||
g_object_unref (texture);
|
||||
g_object_unref (info);
|
||||
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
static void
|
||||
set_image (GtkWidget *image, const gchar *name, gint size)
|
||||
{
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (image), name);
|
||||
gtk_image_set_pixel_size (GTK_IMAGE (image), size);
|
||||
gtk_drag_source_set_icon_name (image, name);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -365,78 +343,107 @@ search_mode_toggled (GObject *searchbar, GParamSpec *pspec, IconBrowserWindow *w
|
||||
gtk_list_box_unselect_all (GTK_LIST_BOX (win->context_list));
|
||||
}
|
||||
|
||||
static void
|
||||
get_image_data (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
GtkSelectionData *selection,
|
||||
guint target_info,
|
||||
gpointer data)
|
||||
static GdkPaintable *
|
||||
get_image_paintable (GtkImage *image)
|
||||
{
|
||||
GtkWidget *image;
|
||||
const gchar *name;
|
||||
gint size;
|
||||
GdkPixbuf *pixbuf;
|
||||
const gchar *icon_name;
|
||||
GtkIconTheme *icon_theme;
|
||||
GtkIconInfo *icon_info;
|
||||
int size;
|
||||
|
||||
image = gtk_bin_get_child (GTK_BIN (widget));
|
||||
|
||||
name = gtk_image_get_icon_name (GTK_IMAGE (image));
|
||||
size = gtk_image_get_pixel_size (GTK_IMAGE (image));
|
||||
|
||||
pixbuf = get_icon (image, name, size);
|
||||
gtk_selection_data_set_pixbuf (selection, pixbuf);
|
||||
g_object_unref (pixbuf);
|
||||
switch (gtk_image_get_storage_type (image))
|
||||
{
|
||||
case GTK_IMAGE_PAINTABLE:
|
||||
return g_object_ref (gtk_image_get_paintable (image));
|
||||
case GTK_IMAGE_ICON_NAME:
|
||||
icon_name = gtk_image_get_icon_name (image);
|
||||
size = gtk_image_get_pixel_size (image);
|
||||
icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (image)));
|
||||
icon_info = gtk_icon_theme_lookup_icon (icon_theme, icon_name, size,
|
||||
GTK_ICON_LOOKUP_FORCE_SIZE | GTK_ICON_LOOKUP_GENERIC_FALLBACK);
|
||||
if (icon_info == NULL)
|
||||
return NULL;
|
||||
return gtk_icon_info_load_icon (icon_info, NULL);
|
||||
default:
|
||||
g_warning ("Image storage type %d not handled",
|
||||
gtk_image_get_storage_type (image));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_scalable_image_data (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
GtkSelectionData *selection,
|
||||
guint target_info,
|
||||
gpointer data)
|
||||
drag_begin (GtkDragSource *source,
|
||||
GdkDrag *drag,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
gchar *uris[2];
|
||||
GtkIconInfo *info;
|
||||
GtkWidget *image;
|
||||
GFile *file;
|
||||
const gchar *name;
|
||||
GdkPaintable *paintable;
|
||||
|
||||
image = gtk_bin_get_child (GTK_BIN (widget));
|
||||
name = gtk_image_get_icon_name (GTK_IMAGE (image));
|
||||
paintable = get_image_paintable (GTK_IMAGE (widget));
|
||||
if (paintable)
|
||||
{
|
||||
int w, h;
|
||||
|
||||
w = gdk_paintable_get_intrinsic_width (paintable);
|
||||
h = gdk_paintable_get_intrinsic_height (paintable);
|
||||
gtk_drag_source_set_icon (source, paintable, w, h);
|
||||
g_object_unref (paintable);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_texture (GValue *value,
|
||||
gpointer data)
|
||||
{
|
||||
GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (data));
|
||||
|
||||
if (GDK_IS_TEXTURE (paintable))
|
||||
g_value_set_object (value, paintable);
|
||||
}
|
||||
|
||||
static void
|
||||
get_file (GValue *value,
|
||||
gpointer data)
|
||||
{
|
||||
const char *name;
|
||||
GtkIconInfo *info;
|
||||
GFile *file;
|
||||
|
||||
name = gtk_image_get_icon_name (GTK_IMAGE (data));
|
||||
|
||||
info = gtk_icon_theme_lookup_icon (gtk_icon_theme_get_default (), name, -1, 0);
|
||||
file = g_file_new_for_path (gtk_icon_info_get_filename (info));
|
||||
uris[0] = g_file_get_uri (file);
|
||||
uris[1] = NULL;
|
||||
|
||||
gtk_selection_data_set_uris (selection, uris);
|
||||
|
||||
g_free (uris[0]);
|
||||
g_object_unref (info);
|
||||
g_value_set_object (value, file);
|
||||
g_object_unref (file);
|
||||
g_object_unref (info);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_image_dnd (GtkWidget *image)
|
||||
{
|
||||
gtk_drag_source_set (image, GDK_BUTTON1_MASK, NULL, GDK_ACTION_COPY);
|
||||
gtk_drag_source_add_image_targets (image);
|
||||
g_signal_connect (image, "drag-data-get", G_CALLBACK (get_image_data), NULL);
|
||||
GdkContentProvider *content;
|
||||
GtkDragSource *source;
|
||||
|
||||
source = gtk_drag_source_new ();
|
||||
content = gdk_content_provider_new_with_callback (GDK_TYPE_TEXTURE, get_texture, image);
|
||||
gtk_drag_source_set_content (source, content);
|
||||
g_object_unref (content);
|
||||
g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (source));
|
||||
}
|
||||
|
||||
static void
|
||||
setup_scalable_image_dnd (GtkWidget *image)
|
||||
{
|
||||
GtkWidget *parent;
|
||||
GdkContentFormats *targets;
|
||||
GdkContentProvider *content;
|
||||
GtkDragSource *source;
|
||||
|
||||
parent = gtk_widget_get_parent (image);
|
||||
targets = gdk_content_formats_new (target_table, G_N_ELEMENTS (target_table));
|
||||
gtk_drag_source_set (parent, GDK_BUTTON1_MASK,
|
||||
targets,
|
||||
GDK_ACTION_COPY);
|
||||
gdk_content_formats_unref (targets);
|
||||
source = gtk_drag_source_new ();
|
||||
content = gdk_content_provider_new_with_callback (G_TYPE_FILE, get_file, image);
|
||||
gtk_drag_source_set_content (source, content);
|
||||
g_object_unref (content);
|
||||
|
||||
g_signal_connect (parent, "drag-data-get", G_CALLBACK (get_scalable_image_data), NULL);
|
||||
g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (source));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -446,8 +453,7 @@ icon_browser_window_init (IconBrowserWindow *win)
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (win));
|
||||
|
||||
list = gdk_content_formats_new (NULL, 0);
|
||||
list = gtk_content_formats_add_text_targets (list);
|
||||
list = gdk_content_formats_new_for_gtype (G_TYPE_STRING);
|
||||
gtk_icon_view_enable_model_drag_source (GTK_ICON_VIEW (win->list),
|
||||
GDK_BUTTON1_MASK,
|
||||
list,
|
||||
@@ -459,7 +465,6 @@ icon_browser_window_init (IconBrowserWindow *win)
|
||||
setup_image_dnd (win->image3);
|
||||
setup_image_dnd (win->image4);
|
||||
setup_image_dnd (win->image5);
|
||||
setup_image_dnd (win->image6);
|
||||
setup_scalable_image_dnd (win->image6);
|
||||
|
||||
win->contexts = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, context_free);
|
||||
|
||||
@@ -344,6 +344,13 @@
|
||||
<xi:include href="xml/gtkpadcontroller.xml" />
|
||||
</chapter>
|
||||
|
||||
<chapter>
|
||||
<title>Data exchange, clipboards and Drag-and-Drop</title>
|
||||
<xi:include href="xml/gtkdragsource.xml"/>
|
||||
<xi:include href="xml/gtkdragicon.xml"/>
|
||||
<xi:include href="xml/gtkdroptarget.xml"/>
|
||||
</chapter>
|
||||
|
||||
</part>
|
||||
|
||||
<part id="gtkbase">
|
||||
@@ -352,7 +359,6 @@
|
||||
<xi:include href="xml/gtkfeatures.xml" />
|
||||
<xi:include href="xml/gtkaccelgroup.xml" />
|
||||
<xi:include href="xml/gtkaccelmap.xml" />
|
||||
<xi:include href="xml/gtkdnd.xml" />
|
||||
<xi:include href="xml/gtksettings.xml" />
|
||||
<xi:include href="xml/gtkbindings.xml" />
|
||||
<xi:include href="xml/gtkenums.xml" />
|
||||
|
||||
@@ -5001,49 +5001,6 @@ GTK_TYPE_SELECTION_DATA
|
||||
gtk_selection_data_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkdnd</FILE>
|
||||
<TITLE>Drag and Drop</TITLE>
|
||||
GtkDestDefaults
|
||||
GtkDragResult
|
||||
|
||||
<SUBSECTION Destination Side>
|
||||
gtk_drag_dest_set
|
||||
gtk_drag_dest_unset
|
||||
gtk_drag_dest_find_target
|
||||
gtk_drag_dest_get_target_list
|
||||
gtk_drag_dest_set_target_list
|
||||
gtk_drag_dest_add_text_targets
|
||||
gtk_drag_dest_add_image_targets
|
||||
gtk_drag_dest_add_uri_targets
|
||||
gtk_drag_dest_set_track_motion
|
||||
gtk_drag_dest_get_track_motion
|
||||
gtk_drag_get_data
|
||||
gtk_drag_get_source_widget
|
||||
gtk_drag_highlight
|
||||
gtk_drag_unhighlight
|
||||
|
||||
<SUBSECTION Source Side>
|
||||
gtk_drag_begin
|
||||
gtk_drag_cancel
|
||||
gtk_drag_set_icon_widget
|
||||
gtk_drag_set_icon_paintable
|
||||
gtk_drag_set_icon_name
|
||||
gtk_drag_set_icon_gicon
|
||||
gtk_drag_set_icon_default
|
||||
gtk_drag_check_threshold
|
||||
gtk_drag_source_set
|
||||
gtk_drag_source_set_icon_name
|
||||
gtk_drag_source_set_icon_gicon
|
||||
gtk_drag_source_set_icon_paintable
|
||||
gtk_drag_source_unset
|
||||
gtk_drag_source_set_target_list
|
||||
gtk_drag_source_get_target_list
|
||||
gtk_drag_source_add_text_targets
|
||||
gtk_drag_source_add_image_targets
|
||||
gtk_drag_source_add_uri_targets
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkbindings</FILE>
|
||||
<TITLE>Bindings</TITLE>
|
||||
@@ -7191,3 +7148,69 @@ gtk_constraint_guide_get_max_size
|
||||
GTK_TYPE_CONSTRAINT_GUIDE
|
||||
gtk_constraint_guide_get_tyoe
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkdragsource</FILE>
|
||||
GtkDragSource
|
||||
gtk_drag_source_new
|
||||
gtk_drag_source_set_content
|
||||
gtk_drag_source_get_content
|
||||
gtk_drag_source_set_actions
|
||||
gtk_drag_source_get_actions
|
||||
gtk_drag_source_set_icon
|
||||
gtk_drag_source_drag_cancel
|
||||
gtk_drag_source_get_drag
|
||||
gtk_drag_check_threshold
|
||||
<SUBSECTION Standard>
|
||||
GTK_TYPE_DRAG_SOURCE
|
||||
GTK_DRAG_SOURCE
|
||||
GTK_DRAG_SOURCE_CLASS
|
||||
GTK_IS_DRAG_SOURCE
|
||||
GTK_IS_DRAG_SOURCE_CLASS
|
||||
GTK_DRAG_SOURCE_GET_CLASS
|
||||
<SUBSECTION Private>
|
||||
gtk_drag_source_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkdroptarget</FILE>
|
||||
GtkDropTarget
|
||||
gtk_drop_target_new
|
||||
gtk_drop_target_set_formats
|
||||
gtk_drop_target_get_formats
|
||||
gtk_drop_target_set_actions
|
||||
gtk_drop_target_get_actions
|
||||
gtk_drop_target_get_drop
|
||||
gtk_drop_target_find_mimetype
|
||||
gtk_drop_target_read_selection
|
||||
gtk_drop_target_read_selection_finish
|
||||
gtk_drag_highlight
|
||||
gtk_drag_unhighlight
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GTK_TYPE_DROP_TARGET
|
||||
GTK_DROP_TARGET
|
||||
GTK_DROP_TARGET_CLASS
|
||||
GTK_IS_DROP_TARGET
|
||||
GTK_IS_DROP_TARGET_CLASS
|
||||
GTK_DROP_TARGET_GET_CLASS
|
||||
<SUBSECTION Private>
|
||||
gtk_drop_target_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkdragicon</FILE>
|
||||
GtkDragIcon
|
||||
gtk_drag_icon_new_for_drag
|
||||
gtk_drag_icon_set_from_paintable
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GTK_TYPE_DRAG_ICON
|
||||
GTK_DRAG_ICON
|
||||
GTK_DRAG_ICON_CLASS
|
||||
GTK_IS_DRAG_ICON
|
||||
GTK_IS_DRAG_ICON_CLASS
|
||||
GTK_DRAG_ICON_GET_CLASS
|
||||
<SUBSECTION Private>
|
||||
gtk_drag_icon_get_type
|
||||
</SECTION>
|
||||
|
||||
@@ -57,7 +57,10 @@ gtk_constraint_target_get_type
|
||||
gtk_container_get_type
|
||||
gtk_css_provider_get_type
|
||||
gtk_dialog_get_type
|
||||
gtk_drag_icon_get_type
|
||||
gtk_drag_source_get_type
|
||||
gtk_drawing_area_get_type
|
||||
gtk_drop_target_get_type
|
||||
gtk_editable_get_type
|
||||
gtk_entry_buffer_get_type
|
||||
gtk_entry_completion_get_type
|
||||
|
||||
@@ -48,7 +48,6 @@ private_headers = [
|
||||
'gtkcssfontfeaturesvalueprivate.h',
|
||||
'gtkcssfontvariationsvalueprivate.h',
|
||||
'gtkcssiconthemevalueprivate.h',
|
||||
'gtkcssimagebuiltinprivate.h',
|
||||
'gtkcssimagecrossfadeprivate.h',
|
||||
'gtkcssimagefallbackprivate.h',
|
||||
'gtkcssimageiconthemeprivate.h',
|
||||
@@ -97,7 +96,6 @@ private_headers = [
|
||||
'gtkcsswidgetnodeprivate.h',
|
||||
'gtkcsswin32sizevalueprivate.h',
|
||||
'gtkdialogprivate.h',
|
||||
'gtkdndprivate.h',
|
||||
'gtkentryprivate.h',
|
||||
'gtkeventcontrollerlegacyprivate.h',
|
||||
'gtkeventcontrollerprivate.h',
|
||||
|
||||
@@ -903,6 +903,37 @@
|
||||
gtk_tooltip_set_custom().
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Switch to the new DND api</title>
|
||||
<para>
|
||||
The source-side DND apis in GTK 4 have been changed to use an event controller, #GtkDragSource.
|
||||
</para>
|
||||
<para>
|
||||
Instead of calling gtk_drag_source_set() and connecting to #GtkWidget signals, you create
|
||||
a #GtkDragSource object, attach it to the widget with gtk_widget_add_controller(), and connect
|
||||
to #GtkDragSource signals. Instead of calling gtk_drag_begin() on a widget to start a drag
|
||||
manually, call gdk_drag_begin().
|
||||
</para>
|
||||
<para>
|
||||
The ::drag-data-get signal has been replaced by the #GtkDragSource::prepare signal, which
|
||||
returns a #GdkContentProvider for the drag operation.
|
||||
</para>
|
||||
<para>
|
||||
The destination-side DND apis in GTK 4 have also been changed to use and event controller,
|
||||
#GTkDropTarget.
|
||||
</para>
|
||||
<para>
|
||||
Instead of calling gtk_drag_dest_set() and connecting to #GtkWidget signals, you create
|
||||
a #GtkDropTarget object, attach it to the widget with gtk_widget_add_controller(), and
|
||||
connect to #GtkDropTarget signals.
|
||||
</para>
|
||||
<para>
|
||||
The ::drag-motion signal has been renamed to #GtkDragSource::accept, and instead of
|
||||
::drag-data-received, you need to use async read methods on the #GdkDrop object, such
|
||||
as gdk_drop_read_value_async() or gdk_drop_read_text_async().
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
</chapter>
|
||||
|
||||
+100
-13
@@ -42,29 +42,116 @@
|
||||
#include "filetransferportalprivate.h"
|
||||
|
||||
static GDBusProxy *file_transfer_proxy = NULL;
|
||||
static gboolean done;
|
||||
static guint timeout_id;
|
||||
|
||||
static void
|
||||
got_proxy (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
file_transfer_proxy = g_dbus_proxy_new_for_bus_finish (result, &error);
|
||||
if (!file_transfer_proxy)
|
||||
{
|
||||
g_message ("failed to get file transfer portal proxy: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
if (timeout_id)
|
||||
{
|
||||
g_source_remove (timeout_id);
|
||||
timeout_id = 0;
|
||||
}
|
||||
|
||||
done = TRUE;
|
||||
g_main_context_wakeup (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
got_bus (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GDBusConnection **bus = data;
|
||||
GError *error = NULL;
|
||||
|
||||
*bus = g_bus_get_finish (result, &error);
|
||||
if (!*bus)
|
||||
{
|
||||
g_message ("failed to get session bus connection: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
if (timeout_id)
|
||||
{
|
||||
g_source_remove (timeout_id);
|
||||
timeout_id = 0;
|
||||
}
|
||||
|
||||
done = TRUE;
|
||||
g_main_context_wakeup (NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
give_up_on_proxy (gpointer data)
|
||||
{
|
||||
GCancellable *cancellable = data;
|
||||
|
||||
g_cancellable_cancel (cancellable);
|
||||
|
||||
timeout_id = 0;
|
||||
|
||||
done = TRUE;
|
||||
g_main_context_wakeup (NULL);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static GDBusProxy *
|
||||
ensure_file_transfer_portal (void)
|
||||
{
|
||||
if (file_transfer_proxy == NULL)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GCancellable *cancellable;
|
||||
GDBusConnection *bus = NULL;
|
||||
|
||||
file_transfer_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES
|
||||
| G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS
|
||||
| G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
|
||||
NULL,
|
||||
"org.freedesktop.portal.Documents",
|
||||
"/org/freedesktop/portal/documents",
|
||||
"org.freedesktop.portal.FileTransfer",
|
||||
NULL, &error);
|
||||
cancellable = g_cancellable_new ();
|
||||
|
||||
done = FALSE;
|
||||
timeout_id = g_timeout_add (500, give_up_on_proxy, cancellable);
|
||||
g_bus_get (G_BUS_TYPE_SESSION,
|
||||
cancellable,
|
||||
got_bus,
|
||||
&bus);
|
||||
|
||||
if (error)
|
||||
while (!done)
|
||||
g_main_context_iteration (NULL, TRUE);
|
||||
|
||||
if (bus)
|
||||
{
|
||||
g_debug ("Failed to get proxy: %s", error->message);
|
||||
g_error_free (error);
|
||||
done = FALSE;
|
||||
timeout_id = g_timeout_add (500, give_up_on_proxy, cancellable);
|
||||
g_dbus_proxy_new (bus,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES
|
||||
| G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS
|
||||
| G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
|
||||
NULL,
|
||||
"org.freedesktop.portal.Documents",
|
||||
"/org/freedesktop/portal/documents",
|
||||
"org.freedesktop.portal.FileTransfer",
|
||||
cancellable,
|
||||
got_proxy,
|
||||
NULL);
|
||||
|
||||
while (!done)
|
||||
g_main_context_iteration (NULL, TRUE);
|
||||
|
||||
g_clear_object (&bus);
|
||||
}
|
||||
|
||||
g_clear_object (&cancellable);
|
||||
}
|
||||
|
||||
if (file_transfer_proxy)
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "gdkcontentformats.h"
|
||||
#include "filetransferportalprivate.h"
|
||||
#include "gdktexture.h"
|
||||
#include "gdkrgbaprivate.h"
|
||||
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
@@ -848,6 +849,63 @@ file_uri_deserializer (GdkContentDeserializer *deserializer)
|
||||
g_object_unref (output);
|
||||
}
|
||||
|
||||
static void
|
||||
color_deserializer_finish (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer deserializer)
|
||||
{
|
||||
GOutputStream *stream = G_OUTPUT_STREAM (source);
|
||||
GError *error = NULL;
|
||||
gssize written;
|
||||
|
||||
written = g_output_stream_splice_finish (stream, result, &error);
|
||||
if (written < 0)
|
||||
{
|
||||
gdk_content_deserializer_return_error (deserializer, error);
|
||||
return;
|
||||
}
|
||||
else if (written == 0)
|
||||
{
|
||||
GdkRGBA black = GDK_RGBA ("000");
|
||||
|
||||
/* Never return NULL, we only return that on error */
|
||||
g_value_set_boxed (gdk_content_deserializer_get_value (deserializer), &black);
|
||||
}
|
||||
else
|
||||
{
|
||||
guint16 *data;
|
||||
GdkRGBA rgba;
|
||||
|
||||
data = (guint16 *)g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (stream));
|
||||
rgba.red = data[0] / 65535.0;
|
||||
rgba.green = data[1] / 65535.0;
|
||||
rgba.blue = data[2] / 65535.0;
|
||||
rgba.alpha = data[3] / 65535.0;
|
||||
|
||||
g_value_set_boxed (gdk_content_deserializer_get_value (deserializer), &rgba);
|
||||
}
|
||||
gdk_content_deserializer_return_success (deserializer);
|
||||
}
|
||||
|
||||
static void
|
||||
color_deserializer (GdkContentDeserializer *deserializer)
|
||||
{
|
||||
GOutputStream *output;
|
||||
guint16 *data;
|
||||
|
||||
data = g_new0 (guint16, 4);
|
||||
output = g_memory_output_stream_new (data, 4 * sizeof (guint16), NULL, g_free);
|
||||
|
||||
g_output_stream_splice_async (output,
|
||||
gdk_content_deserializer_get_input_stream (deserializer),
|
||||
G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
|
||||
gdk_content_deserializer_get_priority (deserializer),
|
||||
gdk_content_deserializer_get_cancellable (deserializer),
|
||||
color_deserializer_finish,
|
||||
deserializer);
|
||||
g_object_unref (output);
|
||||
}
|
||||
|
||||
static void
|
||||
init (void)
|
||||
{
|
||||
@@ -956,5 +1014,11 @@ init (void)
|
||||
string_deserializer,
|
||||
(gpointer) "ASCII",
|
||||
NULL);
|
||||
|
||||
gdk_content_register_deserializer ("application/x-color",
|
||||
GDK_TYPE_RGBA,
|
||||
color_deserializer,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "gdkcontentprovider.h"
|
||||
|
||||
#include "gdkcontentformats.h"
|
||||
#include "gdkcontentserializer.h"
|
||||
#include "gdkintl.h"
|
||||
#include "gdkcontentproviderimpl.h"
|
||||
|
||||
@@ -280,3 +281,232 @@ gdk_content_provider_new_for_bytes (const char *mime_type,
|
||||
|
||||
return GDK_CONTENT_PROVIDER (content);
|
||||
}
|
||||
|
||||
#define GDK_TYPE_CONTENT_PROVIDER_CALLBACK (gdk_content_provider_callback_get_type ())
|
||||
#define GDK_CONTENT_PROVIDER_CALLBACK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_CONTENT_PROVIDER_CALLBACK, GdkContentProviderCallback))
|
||||
|
||||
typedef struct _GdkContentProviderCallback GdkContentProviderCallback;
|
||||
typedef struct _GdkContentProviderCallbackClass GdkContentProviderCallbackClass;
|
||||
|
||||
struct _GdkContentProviderCallback
|
||||
{
|
||||
GdkContentProvider parent;
|
||||
|
||||
GType type;
|
||||
GdkContentProviderGetValueFunc func;
|
||||
gpointer data;
|
||||
};
|
||||
|
||||
struct _GdkContentProviderCallbackClass
|
||||
{
|
||||
GdkContentProviderClass parent_class;
|
||||
};
|
||||
|
||||
GType gdk_content_provider_callback_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_DEFINE_TYPE (GdkContentProviderCallback, gdk_content_provider_callback, GDK_TYPE_CONTENT_PROVIDER)
|
||||
|
||||
static GdkContentFormats *
|
||||
gdk_content_provider_callback_ref_formats (GdkContentProvider *provider)
|
||||
{
|
||||
GdkContentProviderCallback *callback = GDK_CONTENT_PROVIDER_CALLBACK (provider);
|
||||
|
||||
return gdk_content_formats_new_for_gtype (callback->type);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_content_provider_callback_get_value (GdkContentProvider *provider,
|
||||
GValue *value,
|
||||
GError **error)
|
||||
{
|
||||
GdkContentProviderCallback *callback = GDK_CONTENT_PROVIDER_CALLBACK (provider);
|
||||
|
||||
if (G_VALUE_HOLDS (value, callback->type) && callback->func != NULL)
|
||||
{
|
||||
callback->func (value, callback->data);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return GDK_CONTENT_PROVIDER_CLASS (gdk_content_provider_callback_parent_class)->get_value (provider, value, error);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_content_provider_callback_class_init (GdkContentProviderCallbackClass *class)
|
||||
{
|
||||
GdkContentProviderClass *provider_class = GDK_CONTENT_PROVIDER_CLASS (class);
|
||||
|
||||
provider_class->ref_formats = gdk_content_provider_callback_ref_formats;
|
||||
provider_class->get_value = gdk_content_provider_callback_get_value;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_content_provider_callback_init (GdkContentProviderCallback *content)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_content_provider_new_for_callback:
|
||||
* @type: the type that the callback provides
|
||||
* @func: callback to populate a #GValue
|
||||
* @data: (closure): data that gets passed to @func
|
||||
*
|
||||
* Create a content provider that provides data that is provided via a callback.
|
||||
*
|
||||
* Returns: a new #GdkContentProvider
|
||||
**/
|
||||
GdkContentProvider *
|
||||
gdk_content_provider_new_with_callback (GType type,
|
||||
GdkContentProviderGetValueFunc func,
|
||||
gpointer data)
|
||||
{
|
||||
GdkContentProviderCallback *content;
|
||||
|
||||
content = g_object_new (GDK_TYPE_CONTENT_PROVIDER_CALLBACK, NULL);
|
||||
content->type = type;
|
||||
content->func = func;
|
||||
content->data = data;
|
||||
|
||||
return GDK_CONTENT_PROVIDER (content);
|
||||
}
|
||||
|
||||
#define GDK_TYPE_CONTENT_PROVIDER_CALLBACK2 (gdk_content_provider_callback2_get_type ())
|
||||
#define GDK_CONTENT_PROVIDER_CALLBACK2(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_CONTENT_PROVIDER_CALLBACK2, GdkContentProviderCallback2))
|
||||
|
||||
typedef struct _GdkContentProviderCallback2 GdkContentProviderCallback2;
|
||||
typedef struct _GdkContentProviderCallback2Class GdkContentProviderCallback2Class;
|
||||
|
||||
struct _GdkContentProviderCallback2
|
||||
{
|
||||
GdkContentProvider parent;
|
||||
|
||||
GdkContentFormats *formats;
|
||||
GdkContentProviderGetBytesFunc func;
|
||||
gpointer data;
|
||||
};
|
||||
|
||||
struct _GdkContentProviderCallback2Class
|
||||
{
|
||||
GdkContentProviderClass parent_class;
|
||||
};
|
||||
|
||||
GType gdk_content_provider_callback2_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_DEFINE_TYPE (GdkContentProviderCallback2, gdk_content_provider_callback2, GDK_TYPE_CONTENT_PROVIDER)
|
||||
|
||||
static GdkContentFormats *
|
||||
gdk_content_provider_callback2_ref_formats (GdkContentProvider *provider)
|
||||
{
|
||||
GdkContentProviderCallback2 *callback = GDK_CONTENT_PROVIDER_CALLBACK2 (provider);
|
||||
|
||||
return gdk_content_formats_ref (callback->formats);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_content_provider_callback2_write_mime_type_done (GObject *stream,
|
||||
GAsyncResult *result,
|
||||
gpointer task)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (!g_output_stream_write_all_finish (G_OUTPUT_STREAM (stream), result, NULL, &error))
|
||||
g_task_return_error (task, error);
|
||||
else
|
||||
g_task_return_boolean (task, TRUE);
|
||||
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_content_provider_callback2_write_mime_type_async (GdkContentProvider *provider,
|
||||
const char *mime_type,
|
||||
GOutputStream *stream,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkContentProviderCallback2 *content = GDK_CONTENT_PROVIDER_CALLBACK2 (provider);
|
||||
GTask *task;
|
||||
GBytes *bytes;
|
||||
|
||||
task = g_task_new (content, cancellable, callback, user_data);
|
||||
g_task_set_priority (task, io_priority);
|
||||
g_task_set_source_tag (task, gdk_content_provider_callback2_write_mime_type_async);
|
||||
|
||||
if (!gdk_content_formats_contain_mime_type (content->formats, mime_type))
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("Cannot provide contents as “%s”"), mime_type);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
bytes = content->func (mime_type, content->data);
|
||||
if (!bytes)
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("Failed to get contents as “%s”"), mime_type);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
g_object_set_data_full (G_OBJECT (task), "bytes", bytes, (GDestroyNotify)g_bytes_unref);
|
||||
|
||||
g_output_stream_write_all_async (stream,
|
||||
g_bytes_get_data (bytes, NULL),
|
||||
g_bytes_get_size (bytes),
|
||||
io_priority,
|
||||
cancellable,
|
||||
gdk_content_provider_callback2_write_mime_type_done,
|
||||
task);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_content_provider_callback2_write_mime_type_finish (GdkContentProvider *provider,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (g_task_is_valid (result, provider), FALSE);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gdk_content_provider_callback2_write_mime_type_async, FALSE);
|
||||
|
||||
return g_task_propagate_boolean (G_TASK (result), error);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_content_provider_callback2_class_init (GdkContentProviderCallback2Class *class)
|
||||
{
|
||||
GdkContentProviderClass *provider_class = GDK_CONTENT_PROVIDER_CLASS (class);
|
||||
|
||||
provider_class->ref_formats = gdk_content_provider_callback2_ref_formats;
|
||||
provider_class->write_mime_type_async = gdk_content_provider_callback2_write_mime_type_async;
|
||||
provider_class->write_mime_type_finish = gdk_content_provider_callback2_write_mime_type_finish;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_content_provider_callback2_init (GdkContentProviderCallback2 *content)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_content_provider_new_with_formats:
|
||||
* @formats: formats to advertise
|
||||
* @func: callback to populate a #GValue
|
||||
* @data: data that gets passed to @func
|
||||
*
|
||||
* Create a content provider that provides data that is provided via a callback.
|
||||
*
|
||||
* Returns: a new #GdkContentProvider
|
||||
**/
|
||||
GdkContentProvider *
|
||||
gdk_content_provider_new_with_formats (GdkContentFormats *formats,
|
||||
GdkContentProviderGetBytesFunc func,
|
||||
gpointer data)
|
||||
{
|
||||
GdkContentProviderCallback2 *content;
|
||||
content = g_object_new (GDK_TYPE_CONTENT_PROVIDER_CALLBACK2, NULL);
|
||||
content->formats = gdk_content_formats_union_serialize_mime_types (gdk_content_formats_ref (formats));
|
||||
content->func = func;
|
||||
content->data = data;
|
||||
|
||||
return GDK_CONTENT_PROVIDER (content);
|
||||
}
|
||||
|
||||
@@ -35,6 +35,21 @@ GDK_AVAILABLE_IN_ALL
|
||||
GdkContentProvider * gdk_content_provider_new_for_bytes (const char *mime_type,
|
||||
GBytes *bytes);
|
||||
|
||||
typedef void (*GdkContentProviderGetValueFunc) (GValue *value,
|
||||
gpointer data);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkContentProvider * gdk_content_provider_new_with_callback (GType type,
|
||||
GdkContentProviderGetValueFunc func,
|
||||
gpointer data);
|
||||
|
||||
typedef GBytes * (*GdkContentProviderGetBytesFunc) (const char *mime_type,
|
||||
gpointer data);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkContentProvider * gdk_content_provider_new_with_formats (GdkContentFormats *formats,
|
||||
GdkContentProviderGetBytesFunc func,
|
||||
gpointer data);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "gdkpixbuf.h"
|
||||
#include "filetransferportalprivate.h"
|
||||
#include "gdktextureprivate.h"
|
||||
#include "gdkrgba.h"
|
||||
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <string.h>
|
||||
@@ -862,6 +863,48 @@ file_text_serializer (GdkContentSerializer *serializer)
|
||||
gdk_content_serializer_set_task_data (serializer, path, g_free);
|
||||
}
|
||||
|
||||
static void
|
||||
color_serializer_finish (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer serializer)
|
||||
{
|
||||
GOutputStream *stream = G_OUTPUT_STREAM (source);
|
||||
GError *error = NULL;
|
||||
|
||||
if (!g_output_stream_write_all_finish (stream, result, NULL, &error))
|
||||
gdk_content_serializer_return_error (serializer, error);
|
||||
else
|
||||
gdk_content_serializer_return_success (serializer);
|
||||
}
|
||||
|
||||
static void
|
||||
color_serializer (GdkContentSerializer *serializer)
|
||||
{
|
||||
const GValue *value;
|
||||
GdkRGBA *rgba;
|
||||
guint16 *data;
|
||||
|
||||
value = gdk_content_serializer_get_value (serializer);
|
||||
rgba = g_value_get_boxed (value);
|
||||
data = g_new0 (guint16, 4);
|
||||
if (rgba)
|
||||
{
|
||||
data[0] = (guint16) (rgba->red * 65535);
|
||||
data[1] = (guint16) (rgba->green * 65535);
|
||||
data[2] = (guint16) (rgba->blue * 65535);
|
||||
data[3] = (guint16) (rgba->alpha * 65535);
|
||||
}
|
||||
|
||||
g_output_stream_write_all_async (gdk_content_serializer_get_output_stream (serializer),
|
||||
data,
|
||||
4 * sizeof (guint16),
|
||||
gdk_content_serializer_get_priority (serializer),
|
||||
gdk_content_serializer_get_cancellable (serializer),
|
||||
color_serializer_finish,
|
||||
serializer);
|
||||
gdk_content_serializer_set_task_data (serializer, data, g_free);
|
||||
}
|
||||
|
||||
static void
|
||||
init (void)
|
||||
{
|
||||
@@ -984,5 +1027,11 @@ init (void)
|
||||
string_serializer,
|
||||
(gpointer) "ASCII",
|
||||
NULL);
|
||||
|
||||
gdk_content_register_serializer (GDK_TYPE_RGBA,
|
||||
"application/x-color",
|
||||
color_serializer,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
||||
+17
-7
@@ -90,20 +90,30 @@ G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GdkDrag, gdk_drag, G_TYPE_OBJECT)
|
||||
|
||||
/**
|
||||
* SECTION:dnd
|
||||
* @title: Drag And Drop
|
||||
* @short_description: Functions for controlling drag and drop handling
|
||||
* @Title: Drag And Drop
|
||||
* @Short_description: Functions for controlling drag and drop handling
|
||||
*
|
||||
* These functions provide a low level interface for drag and drop.
|
||||
* These functions provide a low-level interface for drag and drop.
|
||||
*
|
||||
* The GdkDrag object represents the source side of an ongoing DND operation.
|
||||
* It is created when a drag is started, and stays alive for duration of
|
||||
* the DND operation.
|
||||
* the DND operation. After a drag has been started with gdk_drag_begin(),
|
||||
* the caller gets informed about the status of the ongoing drag operation
|
||||
* with signals on the #GtkDrag object.
|
||||
*
|
||||
* The GdkDrop object represents the target side of an ongoing DND operation.
|
||||
* Possible drop sites get informed about the status of the ongoing drag operation
|
||||
* with events of type %GDK_DRAG_ENTER, %GDK_DRAG_LEAVE, %GDK_DRAG_MOTION and
|
||||
* %GDK_DROP_START. The #GdkDrop object can be obtained from these #GdkEvents
|
||||
* using gdk_event_get_drop().
|
||||
*
|
||||
* The actual data transfer is initiated from the target side via an async
|
||||
* read, using one of the GdkDrop functions for this purpose: gdk_drop_read_async(),
|
||||
* gdk_drop_read_value_async() or gdk_drop_read_text_async().
|
||||
*
|
||||
* GTK+ provides a higher level abstraction based on top of these functions,
|
||||
* and so they are not normally needed in GTK+ applications. See the
|
||||
* [Drag and Drop][gtk4-Drag-and-Drop] section of the GTK+ documentation
|
||||
* GTK provides a higher level abstraction based on top of these functions,
|
||||
* and so they are not normally needed in GTK applications. See the
|
||||
* [Drag and Drop][gtk4-Drag-and-Drop] section of the GTK documentation
|
||||
* for more information.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1001,3 +1001,30 @@ gdk_drop_emit_drop_event (GdkDrop *self,
|
||||
gdk_drop_do_emit_event (event, dont_queue);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drop_has_value:
|
||||
* @self: a #GdkDrop
|
||||
* @type: the type to check
|
||||
*
|
||||
* Returns whether calling gdk_drop_read_value_async() for @type
|
||||
* can succeed.
|
||||
*
|
||||
* Returns: %TRUE if the data can be deserialized to the given type
|
||||
*/
|
||||
gboolean
|
||||
gdk_drop_has_value (GdkDrop *self,
|
||||
GType type)
|
||||
{
|
||||
GdkContentFormats *formats;
|
||||
gboolean ret;
|
||||
|
||||
formats = gdk_content_formats_ref (gdk_drop_get_formats (self));
|
||||
formats = gdk_content_formats_union_deserialize_gtypes (formats);
|
||||
|
||||
ret = gdk_content_formats_contain_gtype (formats, type);
|
||||
|
||||
gdk_content_formats_unref (formats);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -92,6 +92,9 @@ char * gdk_drop_read_text_finish (GdkDrop
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_drop_has_value (GdkDrop *self,
|
||||
GType type);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -1013,6 +1013,13 @@ gdk_event_set_coords (GdkEvent *event,
|
||||
event->touchpad_pinch.x = x;
|
||||
event->touchpad_pinch.y = y;
|
||||
break;
|
||||
case GDK_DRAG_ENTER:
|
||||
case GDK_DRAG_LEAVE:
|
||||
case GDK_DRAG_MOTION:
|
||||
case GDK_DROP_START:
|
||||
event->dnd.x = x;
|
||||
event->dnd.y = y;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
+2
-2
@@ -248,10 +248,10 @@ gdk_seat_get_capabilities (GdkSeat *seat)
|
||||
* elsewhere.
|
||||
* @event: (nullable): the event that is triggering the grab, or %NULL if none
|
||||
* is available.
|
||||
* @prepare_func: (nullable) (scope call) (closure prepare_func_data): function to
|
||||
* @prepare_func: (nullable) (scope call): function to
|
||||
* prepare the surface to be grabbed, it can be %NULL if @surface is
|
||||
* visible before this call.
|
||||
* @prepare_func_data: user data to pass to @prepare_func
|
||||
* @prepare_func_data: (closure): user data to pass to @prepare_func
|
||||
*
|
||||
* Grabs the seat so that all events corresponding to the given @capabilities
|
||||
* are passed to this application until the seat is ungrabbed with gdk_seat_ungrab(),
|
||||
|
||||
+7
-1
@@ -3583,7 +3583,13 @@ gdk_surface_register_dnd (GdkSurface *surface)
|
||||
*
|
||||
* Starts a drag and creates a new drag context for it.
|
||||
*
|
||||
* This function is called by the drag source.
|
||||
* This function is called by the drag source. After this call, you
|
||||
* probably want to set up the drag icon using the surface returned
|
||||
* by gdk_drag_get_drag_surface().
|
||||
*
|
||||
* Note: if @actions include %GDK_ACTION_MOVE, you need to listen for
|
||||
* the #GdkDrag::dnd-finished signal and delete the data at the source
|
||||
* if gdk_drag_get_selected_action() returns %GDK_ACTION_MOVE.
|
||||
*
|
||||
* Returns: (transfer full) (nullable): a newly created #GdkDrag or
|
||||
* %NULL on error.
|
||||
|
||||
+14
-16
@@ -680,7 +680,6 @@ gdk_quartz_keymap_translate_keyboard_state (GdkKeymap *keymap,
|
||||
{
|
||||
guint tmp_keyval;
|
||||
GdkModifierType bit;
|
||||
guint tmp_modifiers = 0;
|
||||
|
||||
if (keyval)
|
||||
*keyval = 0;
|
||||
@@ -694,24 +693,23 @@ gdk_quartz_keymap_translate_keyboard_state (GdkKeymap *keymap,
|
||||
if (hardware_keycode < 0 || hardware_keycode >= NUM_KEYCODES)
|
||||
return FALSE;
|
||||
|
||||
/* Check if modifiers modify the keyval */
|
||||
for (bit = GDK_SHIFT_MASK; bit < GDK_BUTTON1_MASK; bit <<= 1)
|
||||
{
|
||||
if (translate_keysym (hardware_keycode,
|
||||
(bit == GDK_MOD1_MASK) ? 0 : group,
|
||||
state & ~bit,
|
||||
NULL, NULL) !=
|
||||
translate_keysym (hardware_keycode,
|
||||
(bit == GDK_MOD1_MASK) ? 1 : group,
|
||||
state | bit,
|
||||
NULL, NULL))
|
||||
tmp_modifiers |= bit;
|
||||
}
|
||||
|
||||
tmp_keyval = translate_keysym (hardware_keycode, group, state, level, effective_group);
|
||||
|
||||
/* Check if modifiers modify the keyval */
|
||||
if (consumed_modifiers)
|
||||
*consumed_modifiers = tmp_modifiers;
|
||||
{
|
||||
guint tmp_modifiers = (state & GDK_MODIFIER_MASK);
|
||||
|
||||
for (bit = 1; bit <= tmp_modifiers; bit <<= 1)
|
||||
{
|
||||
if ((bit & tmp_modifiers) &&
|
||||
translate_keysym (hardware_keycode, group, state & ~bit,
|
||||
NULL, NULL) == tmp_keyval)
|
||||
tmp_modifiers &= ~bit;
|
||||
}
|
||||
|
||||
*consumed_modifiers = tmp_modifiers;
|
||||
}
|
||||
|
||||
if (keyval)
|
||||
*keyval = tmp_keyval;
|
||||
|
||||
@@ -4109,7 +4109,7 @@ gdk_wayland_surface_is_exported (GdkSurface *surface)
|
||||
* gdk_wayland_surface_export_handle:
|
||||
* @surface: the #GdkSurface to obtain a handle for
|
||||
* @callback: callback to call with the handle
|
||||
* @user_data: user data for @callback
|
||||
* @user_data: (closure): user data for @callback
|
||||
* @destroy_func: destroy notify for @user_data
|
||||
*
|
||||
* Asynchronously obtains a handle for a surface that can be passed
|
||||
|
||||
+26
-21
@@ -1061,6 +1061,7 @@ xdnd_send_enter (GdkX11Drag *drag_x11)
|
||||
{
|
||||
GdkDrag *drag = GDK_DRAG (drag_x11);
|
||||
GdkDisplay *display = gdk_drag_get_display (drag);
|
||||
GdkContentFormats *formats;
|
||||
const char * const *atoms;
|
||||
gsize i, n_atoms;
|
||||
XEvent xev;
|
||||
@@ -1080,7 +1081,10 @@ xdnd_send_enter (GdkX11Drag *drag_x11)
|
||||
GDK_DISPLAY_NOTE (display, DND,
|
||||
g_message ("Sending enter source window %#lx XDND protocol version %d\n",
|
||||
GDK_SURFACE_XID (drag_x11->ipc_surface), drag_x11->version));
|
||||
atoms = gdk_content_formats_get_mime_types (gdk_drag_get_formats (drag), &n_atoms);
|
||||
formats = gdk_content_formats_ref (gdk_drag_get_formats (drag));
|
||||
formats = gdk_content_formats_union_serialize_mime_types (formats);
|
||||
|
||||
atoms = gdk_content_formats_get_mime_types (formats, &n_atoms);
|
||||
|
||||
if (n_atoms > 3)
|
||||
{
|
||||
@@ -1300,8 +1304,7 @@ xdnd_precache_atoms (GdkDisplay *display)
|
||||
/* Source side */
|
||||
|
||||
static void
|
||||
gdk_drag_do_leave (GdkX11Drag *drag_x11,
|
||||
guint32 time)
|
||||
gdk_drag_do_leave (GdkX11Drag *drag_x11)
|
||||
{
|
||||
if (drag_x11->proxy_xid)
|
||||
{
|
||||
@@ -1502,27 +1505,10 @@ gdk_x11_drag_drag_motion (GdkDrag *drag,
|
||||
}
|
||||
}
|
||||
|
||||
/* When we have a Xdnd target, make sure our XdndActionList
|
||||
* matches the current actions;
|
||||
*/
|
||||
if (protocol == GDK_DRAG_PROTO_XDND && drag_x11->xdnd_actions != gdk_drag_get_actions (drag))
|
||||
{
|
||||
if (proxy_xid)
|
||||
{
|
||||
GdkDisplay *display = gdk_drag_get_display (drag);
|
||||
GdkDrop *drop = GDK_X11_DISPLAY (display)->current_drop;
|
||||
|
||||
if (drop && GDK_SURFACE_XID (gdk_drop_get_surface (drop)) == proxy_xid)
|
||||
gdk_x11_drop_read_actions (drop);
|
||||
else
|
||||
xdnd_set_actions (drag_x11);
|
||||
}
|
||||
}
|
||||
|
||||
if (drag_x11->proxy_xid != proxy_xid)
|
||||
{
|
||||
/* Send a leave to the last destination */
|
||||
gdk_drag_do_leave (drag_x11, time);
|
||||
gdk_drag_do_leave (drag_x11);
|
||||
drag_x11->drag_status = GDK_DRAG_STATUS_DRAG;
|
||||
|
||||
/* Check if new destination accepts drags, and which protocol */
|
||||
@@ -1558,6 +1544,23 @@ gdk_x11_drag_drag_motion (GdkDrag *drag,
|
||||
drag_x11->current_action = gdk_drag_get_selected_action (drag);
|
||||
}
|
||||
|
||||
/* When we have a Xdnd target, make sure our XdndActionList
|
||||
* matches the current actions;
|
||||
*/
|
||||
if (protocol == GDK_DRAG_PROTO_XDND && drag_x11->xdnd_actions != gdk_drag_get_actions (drag))
|
||||
{
|
||||
if (proxy_xid)
|
||||
{
|
||||
GdkDisplay *display = gdk_drag_get_display (drag);
|
||||
GdkDrop *drop = GDK_X11_DISPLAY (display)->current_drop;
|
||||
|
||||
if (drop && GDK_SURFACE_XID (gdk_drop_get_surface (drop)) == proxy_xid)
|
||||
gdk_x11_drop_read_actions (drop);
|
||||
else
|
||||
xdnd_set_actions (drag_x11);
|
||||
}
|
||||
}
|
||||
|
||||
/* Send a drag-motion event */
|
||||
|
||||
drag_x11->last_x = x_root;
|
||||
@@ -1814,6 +1817,7 @@ struct _GdkDragAnim {
|
||||
static void
|
||||
gdk_drag_anim_destroy (GdkDragAnim *anim)
|
||||
{
|
||||
gdk_surface_hide (anim->drag->drag_surface);
|
||||
g_object_unref (anim->drag);
|
||||
g_slice_free (GdkDragAnim, anim);
|
||||
}
|
||||
@@ -2137,6 +2141,7 @@ static void
|
||||
gdk_x11_drag_cancel (GdkDrag *drag,
|
||||
GdkDragCancelReason reason)
|
||||
{
|
||||
gdk_drag_do_leave (GDK_X11_DRAG (drag));
|
||||
drag_ungrab (drag);
|
||||
gdk_drag_drop_done (drag, FALSE);
|
||||
}
|
||||
|
||||
+13
-2
@@ -747,7 +747,7 @@ gdk_x11_drop_status (GdkDrop *drop,
|
||||
GdkDragAction actions)
|
||||
{
|
||||
GdkX11Drop *drop_x11 = GDK_X11_DROP (drop);
|
||||
GdkDragAction possible_actions;
|
||||
GdkDragAction possible_actions, suggested_action;
|
||||
XEvent xev;
|
||||
GdkDisplay *display;
|
||||
|
||||
@@ -755,6 +755,17 @@ gdk_x11_drop_status (GdkDrop *drop,
|
||||
|
||||
possible_actions = actions & gdk_drop_get_actions (drop);
|
||||
|
||||
if (drop_x11->suggested_action != 0)
|
||||
suggested_action = drop_x11->suggested_action;
|
||||
else if (possible_actions & GDK_ACTION_COPY)
|
||||
suggested_action = GDK_ACTION_COPY;
|
||||
else if (possible_actions & GDK_ACTION_MOVE)
|
||||
suggested_action = GDK_ACTION_MOVE;
|
||||
else if (possible_actions & GDK_ACTION_ASK)
|
||||
suggested_action = GDK_ACTION_ASK;
|
||||
else
|
||||
suggested_action = 0;
|
||||
|
||||
xev.xclient.type = ClientMessage;
|
||||
xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "XdndStatus");
|
||||
xev.xclient.format = 32;
|
||||
@@ -764,7 +775,7 @@ gdk_x11_drop_status (GdkDrop *drop,
|
||||
xev.xclient.data.l[1] = (possible_actions != 0) ? (2 | 1) : 0;
|
||||
xev.xclient.data.l[2] = 0;
|
||||
xev.xclient.data.l[3] = 0;
|
||||
xev.xclient.data.l[4] = xdnd_action_to_atom (display, possible_actions);
|
||||
xev.xclient.data.l[4] = xdnd_action_to_atom (display, suggested_action);
|
||||
|
||||
if (gdk_drop_get_drag (drop))
|
||||
{
|
||||
|
||||
@@ -90,8 +90,8 @@
|
||||
#include <gtk/gtkcustomlayout.h>
|
||||
#include <gtk/gtkdebug.h>
|
||||
#include <gtk/gtkdialog.h>
|
||||
#include <gtk/gtkdnd.h>
|
||||
#include <gtk/gtkdragdest.h>
|
||||
#include <gtk/gtkdragicon.h>
|
||||
#include <gtk/gtkdragsource.h>
|
||||
#include <gtk/gtkdrawingarea.h>
|
||||
#include <gtk/gtkeditable.h>
|
||||
|
||||
@@ -412,7 +412,7 @@ gtk_builder_cscope_init (GtkBuilderCScope *self)
|
||||
* Calling this function is only necessary if you want to add custom
|
||||
* callbacks via gtk_builder_cscope_add_callback_symbol().
|
||||
*
|
||||
* Returns: a new #GtkBuilderCScope
|
||||
* Returns: (transfer full): a new #GtkBuilderCScope
|
||||
**/
|
||||
GtkBuilderScope *
|
||||
gtk_builder_cscope_new (void)
|
||||
@@ -502,7 +502,7 @@ gtk_builder_cscope_add_callback_symbols (GtkBuilderCScope *self,
|
||||
* Fetches a symbol previously added to @self
|
||||
* with gtk_builder_cscope_add_callback_symbol().
|
||||
*
|
||||
* Returns: (nullable): The callback symbol in @builder for @callback_name, or %NULL
|
||||
* Returns: (nullable) (transfer none): The callback symbol in @builder for @callback_name, or %NULL
|
||||
*/
|
||||
GCallback
|
||||
gtk_builder_cscope_lookup_callback_symbol (GtkBuilderCScope *self,
|
||||
|
||||
+119
-133
@@ -72,7 +72,6 @@
|
||||
#endif
|
||||
|
||||
#include "gtkcalendar.h"
|
||||
#include "gtkdnd.h"
|
||||
#include "gtkdragdest.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkmain.h"
|
||||
@@ -87,6 +86,10 @@
|
||||
#include "gtkgesturedrag.h"
|
||||
#include "gtkeventcontrollerscroll.h"
|
||||
#include "gtkeventcontrollerkey.h"
|
||||
#include "gtkdragsource.h"
|
||||
#include "gtknative.h"
|
||||
#include "gtkicontheme.h"
|
||||
#include "gtkdragicon.h"
|
||||
|
||||
#define TIMEOUT_INITIAL 500
|
||||
#define TIMEOUT_REPEAT 50
|
||||
@@ -248,7 +251,6 @@ struct _GtkCalendarPrivate
|
||||
guint need_timer : 1;
|
||||
|
||||
guint in_drag : 1;
|
||||
guint drag_highlight : 1;
|
||||
|
||||
guint32 timer;
|
||||
gint click_child;
|
||||
@@ -329,22 +331,17 @@ static gboolean gtk_calendar_query_tooltip (GtkWidget *widget,
|
||||
gboolean keyboard_mode,
|
||||
GtkTooltip *tooltip);
|
||||
|
||||
static void gtk_calendar_drag_data_get (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
GtkSelectionData *selection_data);
|
||||
static void gtk_calendar_drag_data_received (GtkWidget *widget,
|
||||
static gboolean gtk_calendar_drag_accept (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
GtkSelectionData *selection_data);
|
||||
static gboolean gtk_calendar_drag_motion (GtkWidget *widget,
|
||||
GtkCalendar *calendar);
|
||||
static void gtk_calendar_drag_leave (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
gint x,
|
||||
gint y);
|
||||
static void gtk_calendar_drag_leave (GtkWidget *widget,
|
||||
GdkDrop *drop);
|
||||
static gboolean gtk_calendar_drag_drop (GtkWidget *widget,
|
||||
GtkCalendar *calendar);
|
||||
static gboolean gtk_calendar_drag_drop (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
gint x,
|
||||
gint y);
|
||||
int x,
|
||||
int y,
|
||||
GtkCalendar *calendar);
|
||||
|
||||
|
||||
static void calendar_start_spinning (GtkCalendar *calendar,
|
||||
@@ -392,12 +389,6 @@ gtk_calendar_class_init (GtkCalendarClass *class)
|
||||
widget_class->grab_notify = gtk_calendar_grab_notify;
|
||||
widget_class->query_tooltip = gtk_calendar_query_tooltip;
|
||||
|
||||
widget_class->drag_data_get = gtk_calendar_drag_data_get;
|
||||
widget_class->drag_motion = gtk_calendar_drag_motion;
|
||||
widget_class->drag_leave = gtk_calendar_drag_leave;
|
||||
widget_class->drag_drop = gtk_calendar_drag_drop;
|
||||
widget_class->drag_data_received = gtk_calendar_drag_data_received;
|
||||
|
||||
/**
|
||||
* GtkCalendar:year:
|
||||
*
|
||||
@@ -675,6 +666,8 @@ gtk_calendar_init (GtkCalendar *calendar)
|
||||
#else
|
||||
gchar *week_start;
|
||||
#endif
|
||||
GdkContentFormats *formats;
|
||||
GtkDropTarget *dest;
|
||||
|
||||
gtk_widget_set_can_focus (widget, TRUE);
|
||||
|
||||
@@ -792,11 +785,17 @@ gtk_calendar_init (GtkCalendar *calendar)
|
||||
priv->click_child = -1;
|
||||
|
||||
priv->in_drag = 0;
|
||||
priv->drag_highlight = 0;
|
||||
|
||||
gtk_drag_dest_set (widget, 0, NULL, GDK_ACTION_COPY);
|
||||
gtk_drag_dest_add_text_targets (widget);
|
||||
formats = gdk_content_formats_new_for_gtype (G_TYPE_STRING);
|
||||
dest = gtk_drop_target_new (formats, GDK_ACTION_COPY);
|
||||
gdk_content_formats_unref (formats);
|
||||
|
||||
g_signal_connect (dest, "accept", G_CALLBACK (gtk_calendar_drag_accept), calendar);
|
||||
g_signal_connect (dest, "drag-leave", G_CALLBACK (gtk_calendar_drag_leave), calendar);
|
||||
g_signal_connect (dest, "drag-drop", G_CALLBACK (gtk_calendar_drag_drop), calendar);
|
||||
|
||||
gtk_widget_add_controller (widget, GTK_EVENT_CONTROLLER (dest));
|
||||
|
||||
priv->year_before = 0;
|
||||
|
||||
/* Translate to calendar:YM if you want years to be displayed
|
||||
@@ -2395,7 +2394,6 @@ calendar_snapshot_arrow (GtkCalendar *calendar,
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (calendar);
|
||||
GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
|
||||
GtkCssImageBuiltinType image_type;
|
||||
GtkStyleContext *context;
|
||||
GtkStateFlags state;
|
||||
GdkRectangle rect;
|
||||
@@ -2418,19 +2416,11 @@ calendar_snapshot_arrow (GtkCalendar *calendar,
|
||||
rect.x, rect.y,
|
||||
rect.width, rect.height);
|
||||
|
||||
if (arrow == ARROW_MONTH_LEFT || arrow == ARROW_YEAR_LEFT)
|
||||
image_type = GTK_CSS_IMAGE_BUILTIN_ARROW_LEFT;
|
||||
else
|
||||
image_type = GTK_CSS_IMAGE_BUILTIN_ARROW_RIGHT;
|
||||
|
||||
gtk_snapshot_save (snapshot);
|
||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT(
|
||||
rect.x + (rect.width - 8) / 2,
|
||||
rect.y + (rect.height - 8) / 2));
|
||||
gtk_css_style_snapshot_icon (gtk_style_context_lookup_style (context),
|
||||
snapshot,
|
||||
8, 8,
|
||||
image_type);
|
||||
gtk_css_style_snapshot_icon (gtk_style_context_lookup_style (context), snapshot, 8, 8);
|
||||
gtk_snapshot_restore (snapshot);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
@@ -2670,6 +2660,27 @@ gtk_calendar_drag_begin (GtkGestureDrag *gesture,
|
||||
priv->in_drag = TRUE;
|
||||
}
|
||||
|
||||
static GdkContentProvider *
|
||||
get_calendar_content (GtkCalendar *calendar)
|
||||
{
|
||||
GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
|
||||
GDate *date;
|
||||
gchar str[128];
|
||||
GValue value = G_VALUE_INIT;
|
||||
GdkContentProvider *content;
|
||||
|
||||
date = g_date_new_dmy (priv->selected_day, priv->month + 1, priv->year);
|
||||
g_date_strftime (str, 127, "%x", date);
|
||||
g_free (date);
|
||||
|
||||
g_value_init (&value, G_TYPE_STRING);
|
||||
g_value_set_string (&value, str);
|
||||
content = gdk_content_provider_new_for_value (&value);
|
||||
g_value_unset (&value);
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_calendar_drag_update (GtkGestureDrag *gesture,
|
||||
double x,
|
||||
@@ -2680,8 +2691,12 @@ gtk_calendar_drag_update (GtkGestureDrag *gesture,
|
||||
GtkCalendar *calendar = GTK_CALENDAR (widget);
|
||||
GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
|
||||
gdouble start_x, start_y;
|
||||
GdkContentProvider *content;
|
||||
GdkDevice *device;
|
||||
GdkDrag *drag;
|
||||
GdkContentFormats *targets;
|
||||
GtkIconTheme *theme;
|
||||
GdkPaintable *paintable;
|
||||
GdkSurface *surface;
|
||||
|
||||
if (!priv->in_drag)
|
||||
return;
|
||||
@@ -2691,19 +2706,22 @@ gtk_calendar_drag_update (GtkGestureDrag *gesture,
|
||||
|
||||
gtk_gesture_drag_get_start_point (gesture, &start_x, &start_y);
|
||||
|
||||
gtk_event_controller_reset (GTK_EVENT_CONTROLLER (gesture));
|
||||
surface = gtk_native_get_surface (gtk_widget_get_native (widget));
|
||||
device = gtk_gesture_get_device (GTK_GESTURE (gesture));
|
||||
|
||||
targets = gdk_content_formats_new (NULL, 0);
|
||||
targets = gtk_content_formats_add_text_targets (targets);
|
||||
drag = gtk_drag_begin (widget,
|
||||
gtk_gesture_get_device (GTK_GESTURE (gesture)),
|
||||
targets, GDK_ACTION_COPY,
|
||||
start_x, start_y);
|
||||
content = get_calendar_content (calendar);
|
||||
|
||||
drag = gdk_drag_begin (surface, device, content, GDK_ACTION_COPY, start_x, start_y);
|
||||
|
||||
theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (widget));
|
||||
paintable = gtk_icon_theme_load_icon (theme, "text-x-generic", 32, 0, NULL);
|
||||
gtk_drag_icon_set_from_paintable (drag, paintable, 0, 0);
|
||||
g_clear_object (&paintable);
|
||||
|
||||
g_object_unref (content);
|
||||
g_object_unref (drag);
|
||||
|
||||
priv->in_drag = 0;
|
||||
gdk_content_formats_unref (targets);
|
||||
|
||||
gtk_drag_set_icon_default (drag);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -2923,24 +2941,6 @@ gtk_calendar_grab_notify (GtkWidget *widget,
|
||||
* Drag and Drop *
|
||||
****************************************/
|
||||
|
||||
static void
|
||||
gtk_calendar_drag_data_get (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
GtkSelectionData *selection_data)
|
||||
{
|
||||
GtkCalendar *calendar = GTK_CALENDAR (widget);
|
||||
GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
|
||||
GDate *date;
|
||||
gchar str[128];
|
||||
gsize len;
|
||||
|
||||
date = g_date_new_dmy (priv->selected_day, priv->month + 1, priv->year);
|
||||
len = g_date_strftime (str, 127, "%x", date);
|
||||
gtk_selection_data_set_text (selection_data, str, len);
|
||||
|
||||
g_free (date);
|
||||
}
|
||||
|
||||
/* Get/set whether drag_motion requested the drag data and
|
||||
* drag_data_received should thus not actually insert the data,
|
||||
* since the data doesn’t result from a drop.
|
||||
@@ -2962,87 +2962,33 @@ get_status_pending (GdkDrop *drop)
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_calendar_drag_leave (GtkWidget *widget,
|
||||
GdkDrop *drop)
|
||||
gtk_calendar_drag_leave (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
GtkCalendar *calendar)
|
||||
{
|
||||
GtkCalendar *calendar = GTK_CALENDAR (widget);
|
||||
GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
|
||||
|
||||
priv->drag_highlight = 0;
|
||||
gtk_drag_unhighlight (widget);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_calendar_drag_motion (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
GtkCalendar *calendar = GTK_CALENDAR (widget);
|
||||
GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
|
||||
GdkAtom target;
|
||||
|
||||
if (!priv->drag_highlight)
|
||||
{
|
||||
priv->drag_highlight = 1;
|
||||
gtk_drag_highlight (widget);
|
||||
}
|
||||
|
||||
target = gtk_drag_dest_find_target (widget, drop, NULL);
|
||||
if (target == NULL || gdk_drop_get_actions (drop) == 0)
|
||||
gdk_drop_status (drop, 0);
|
||||
else if (get_status_pending (drop) == 0)
|
||||
{
|
||||
set_status_pending (drop, gdk_drop_get_actions (drop));
|
||||
gtk_drag_get_data (widget, drop, target);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_calendar_drag_drop (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
GdkAtom target;
|
||||
|
||||
target = gtk_drag_dest_find_target (widget, drop, NULL);
|
||||
if (target != NULL)
|
||||
{
|
||||
gtk_drag_get_data (widget, drop, target);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_calendar_drag_data_received (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
GtkSelectionData *selection_data)
|
||||
got_text (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GtkCalendar *calendar = GTK_CALENDAR (widget);
|
||||
GtkDropTarget *dest = GTK_DROP_TARGET (data);
|
||||
GtkCalendar *calendar = GTK_CALENDAR (gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest)));
|
||||
GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
|
||||
GdkDrop *drop = GDK_DROP (source);
|
||||
guint day, month, year;
|
||||
gchar *str;
|
||||
GDate *date;
|
||||
GdkDragAction suggested_action;
|
||||
|
||||
suggested_action = get_status_pending (drop);
|
||||
set_status_pending (drop, 0);
|
||||
|
||||
str = gdk_drop_read_text_finish (drop, result, NULL);
|
||||
|
||||
if (suggested_action)
|
||||
{
|
||||
set_status_pending (drop, 0);
|
||||
|
||||
/* We are getting this data due to a request in drag_motion,
|
||||
* rather than due to a request in drag_drop, so we are just
|
||||
* supposed to call drag_status, not actually paste in the
|
||||
* data.
|
||||
*/
|
||||
str = (gchar*) gtk_selection_data_get_text (selection_data);
|
||||
|
||||
if (str)
|
||||
{
|
||||
date = g_date_new ();
|
||||
@@ -3054,14 +3000,13 @@ gtk_calendar_drag_data_received (GtkWidget *widget,
|
||||
}
|
||||
else
|
||||
suggested_action = 0;
|
||||
|
||||
gdk_drop_status (drop, suggested_action);
|
||||
|
||||
if (suggested_action == 0)
|
||||
gtk_drop_target_deny_drop (dest, drop);
|
||||
return;
|
||||
}
|
||||
|
||||
date = g_date_new ();
|
||||
str = (gchar*) gtk_selection_data_get_text (selection_data);
|
||||
if (str)
|
||||
{
|
||||
g_date_set_parse (date, str);
|
||||
@@ -3073,6 +3018,7 @@ gtk_calendar_drag_data_received (GtkWidget *widget,
|
||||
g_warning ("Received invalid date data");
|
||||
g_date_free (date);
|
||||
gdk_drop_finish (drop, 0);
|
||||
gtk_drop_target_deny_drop (dest, drop);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3083,7 +3029,6 @@ gtk_calendar_drag_data_received (GtkWidget *widget,
|
||||
|
||||
gdk_drop_finish (drop, suggested_action);
|
||||
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (calendar));
|
||||
if (!(priv->display_flags & GTK_CALENDAR_NO_MONTH_CHANGE)
|
||||
&& (priv->display_flags & GTK_CALENDAR_SHOW_HEADING))
|
||||
@@ -3092,6 +3037,47 @@ gtk_calendar_drag_data_received (GtkWidget *widget,
|
||||
g_object_thaw_notify (G_OBJECT (calendar));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_calendar_drag_accept (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
GtkCalendar *calendar)
|
||||
{
|
||||
GdkAtom target;
|
||||
|
||||
target = gtk_drop_target_find_mimetype (dest);
|
||||
if (!target || gdk_drop_get_actions (drop) == 0)
|
||||
{
|
||||
gdk_drop_status (drop, 0);
|
||||
return FALSE;
|
||||
}
|
||||
else if (get_status_pending (drop) == 0)
|
||||
{
|
||||
set_status_pending (drop, gdk_drop_get_actions (drop));
|
||||
gdk_drop_read_text_async (drop, NULL, got_text, dest);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_calendar_drag_drop (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
int x,
|
||||
int y,
|
||||
GtkCalendar *calendar)
|
||||
{
|
||||
GdkAtom target;
|
||||
|
||||
target = gtk_drop_target_find_mimetype (dest);
|
||||
if (target != NULL)
|
||||
{
|
||||
set_status_pending (drop, 0);
|
||||
gdk_drop_read_text_async (drop, NULL, got_text, dest);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/****************************************
|
||||
* Public API *
|
||||
|
||||
@@ -406,7 +406,6 @@ gtk_cell_renderer_toggle_snapshot (GtkCellRenderer *cell,
|
||||
gint xpad, ypad;
|
||||
GtkStateFlags state;
|
||||
GtkBorder padding, border;
|
||||
GtkCssImageBuiltinType image_type;
|
||||
|
||||
gtk_cell_renderer_toggle_get_size (cell, widget, cell_area,
|
||||
&x_offset, &y_offset,
|
||||
@@ -452,32 +451,12 @@ gtk_cell_renderer_toggle_snapshot (GtkCellRenderer *cell,
|
||||
gtk_style_context_get_padding (context, &padding);
|
||||
gtk_style_context_get_border (context, &border);
|
||||
|
||||
if (priv->radio)
|
||||
{
|
||||
if (state & GTK_STATE_FLAG_INCONSISTENT)
|
||||
image_type = GTK_CSS_IMAGE_BUILTIN_OPTION_INCONSISTENT;
|
||||
else if (state & GTK_STATE_FLAG_CHECKED)
|
||||
image_type = GTK_CSS_IMAGE_BUILTIN_OPTION;
|
||||
else
|
||||
image_type = GTK_CSS_IMAGE_BUILTIN_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (state & GTK_STATE_FLAG_INCONSISTENT)
|
||||
image_type = GTK_CSS_IMAGE_BUILTIN_CHECK_INCONSISTENT;
|
||||
else if (state & GTK_STATE_FLAG_CHECKED)
|
||||
image_type = GTK_CSS_IMAGE_BUILTIN_CHECK;
|
||||
else
|
||||
image_type = GTK_CSS_IMAGE_BUILTIN_NONE;
|
||||
}
|
||||
|
||||
gtk_snapshot_translate (snapshot,
|
||||
&GRAPHENE_POINT_INIT (cell_area->x + x_offset + xpad + padding.left + border.left,
|
||||
cell_area->y + y_offset + ypad + padding.top + border.top));
|
||||
gtk_css_style_snapshot_icon (gtk_style_context_lookup_style (context), snapshot,
|
||||
width - padding.left - padding.right - border.left - border.right,
|
||||
height - padding.top - padding.bottom - border.top - border.bottom,
|
||||
image_type);
|
||||
height - padding.top - padding.bottom - border.top - border.bottom);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
|
||||
@@ -98,7 +98,6 @@ static void
|
||||
gtk_check_button_update_node_state (GtkWidget *widget)
|
||||
{
|
||||
GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (widget));
|
||||
GtkCssImageBuiltinType image_type;
|
||||
GtkStateFlags state;
|
||||
|
||||
if (!priv->indicator_widget)
|
||||
@@ -106,17 +105,6 @@ gtk_check_button_update_node_state (GtkWidget *widget)
|
||||
|
||||
state = gtk_widget_get_state_flags (widget);
|
||||
|
||||
/* XXX: This is somewhat awkward here, but there's no better
|
||||
* way to update the icon
|
||||
*/
|
||||
if (state & GTK_STATE_FLAG_CHECKED)
|
||||
image_type = GTK_IS_RADIO_BUTTON (widget) ? GTK_CSS_IMAGE_BUILTIN_OPTION : GTK_CSS_IMAGE_BUILTIN_CHECK;
|
||||
else if (state & GTK_STATE_FLAG_INCONSISTENT)
|
||||
image_type = GTK_IS_RADIO_BUTTON (widget) ? GTK_CSS_IMAGE_BUILTIN_OPTION_INCONSISTENT : GTK_CSS_IMAGE_BUILTIN_CHECK_INCONSISTENT;
|
||||
else
|
||||
image_type = GTK_CSS_IMAGE_BUILTIN_NONE;
|
||||
|
||||
gtk_icon_set_image (GTK_ICON (priv->indicator_widget), image_type);
|
||||
gtk_widget_set_state_flags (priv->indicator_widget, state, TRUE);
|
||||
}
|
||||
|
||||
|
||||
+54
-97
@@ -36,7 +36,6 @@
|
||||
#include "gtkcolorchooserprivate.h"
|
||||
#include "gtkcolorchooserdialog.h"
|
||||
#include "gtkcolorswatchprivate.h"
|
||||
#include "gtkdnd.h"
|
||||
#include "gtkdragdest.h"
|
||||
#include "gtkdragsource.h"
|
||||
#include "gtkintl.h"
|
||||
@@ -45,6 +44,9 @@
|
||||
#include "gtkprivate.h"
|
||||
#include "gtksnapshot.h"
|
||||
#include "gtkstylecontext.h"
|
||||
#include "gtkdragsource.h"
|
||||
#include "gtkdragdest.h"
|
||||
#include "gtkeventcontroller.h"
|
||||
|
||||
|
||||
/**
|
||||
@@ -121,21 +123,6 @@ static void gtk_color_button_get_property (GObject *object,
|
||||
static void gtk_color_button_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
/* source side drag signals */
|
||||
static void gtk_color_button_drag_begin (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
gpointer data);
|
||||
static void gtk_color_button_drag_data_get (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
GtkSelectionData *selection_data,
|
||||
GtkColorButton *button);
|
||||
|
||||
/* target side drag signals */
|
||||
static void gtk_color_button_drag_data_received (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
GtkSelectionData *selection_data,
|
||||
GtkColorButton *button);
|
||||
|
||||
|
||||
static guint color_button_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
@@ -245,91 +232,64 @@ gtk_color_button_class_init (GtkColorButtonClass *klass)
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_color_button_drag_data_received (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
GtkSelectionData *selection_data,
|
||||
GtkColorButton *button)
|
||||
got_color (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GtkColorButtonPrivate *priv = gtk_color_button_get_instance_private (button);
|
||||
gint length;
|
||||
guint16 *dropped;
|
||||
GdkDrop *drop = GDK_DROP (source);
|
||||
const GValue *value;
|
||||
|
||||
length = gtk_selection_data_get_length (selection_data);
|
||||
|
||||
if (length < 0)
|
||||
return;
|
||||
|
||||
/* We accept drops with the wrong format, since the KDE color
|
||||
* chooser incorrectly drops application/x-color with format 8.
|
||||
*/
|
||||
if (length != 8)
|
||||
value = gdk_drop_read_value_finish (drop, result, NULL);
|
||||
if (value)
|
||||
{
|
||||
g_warning ("%s: Received invalid color data", G_STRFUNC);
|
||||
return;
|
||||
GdkRGBA *color = g_value_get_boxed (value);
|
||||
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (data), color);
|
||||
gdk_drop_finish (drop, GDK_ACTION_COPY);
|
||||
}
|
||||
else
|
||||
gdk_drop_finish (drop, 0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_color_button_drag_drop (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
int x,
|
||||
int y,
|
||||
GtkColorButton *button)
|
||||
{
|
||||
if (gdk_drop_has_value (drop, GDK_TYPE_RGBA))
|
||||
{
|
||||
gdk_drop_read_value_async (drop, GDK_TYPE_RGBA, G_PRIORITY_DEFAULT, NULL, got_color, button);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
dropped = (guint16 *) gtk_selection_data_get_data (selection_data);
|
||||
|
||||
priv->rgba.red = dropped[0] / 65535.;
|
||||
priv->rgba.green = dropped[1] / 65535.;
|
||||
priv->rgba.blue = dropped[2] / 65535.;
|
||||
priv->rgba.alpha = dropped[3] / 65535.;
|
||||
|
||||
gtk_color_swatch_set_rgba (GTK_COLOR_SWATCH (priv->swatch), &priv->rgba);
|
||||
|
||||
g_signal_emit (button, color_button_signals[COLOR_SET], 0);
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (button));
|
||||
g_object_notify (G_OBJECT (button), "rgba");
|
||||
g_object_thaw_notify (G_OBJECT (button));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
set_color_icon (GdkDrag *drag,
|
||||
const GdkRGBA *rgba)
|
||||
gtk_color_button_drag_begin (GtkDragSource *source,
|
||||
GdkDrag *drag,
|
||||
GtkColorButton *button)
|
||||
{
|
||||
GtkColorButtonPrivate *priv = gtk_color_button_get_instance_private (button);
|
||||
GtkSnapshot *snapshot;
|
||||
GdkPaintable *paintable;
|
||||
|
||||
snapshot = gtk_snapshot_new ();
|
||||
gtk_snapshot_append_color (snapshot,
|
||||
rgba,
|
||||
&GRAPHENE_RECT_INIT(0, 0, 48, 32));
|
||||
gtk_snapshot_append_color (snapshot, &priv->rgba, &GRAPHENE_RECT_INIT(0, 0, 48, 32));
|
||||
paintable = gtk_snapshot_free_to_paintable (snapshot, NULL);
|
||||
|
||||
gtk_drag_set_icon_paintable (drag, paintable, 0, 0);
|
||||
gtk_drag_source_set_icon (source, paintable, 0, 0);
|
||||
|
||||
g_object_unref (paintable);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_color_button_drag_begin (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
gpointer data)
|
||||
get_rgba_value (GValue *value,
|
||||
gpointer data)
|
||||
{
|
||||
GtkColorButton *button = data;
|
||||
GtkColorButtonPrivate *priv = gtk_color_button_get_instance_private (button);
|
||||
|
||||
set_color_icon (drag, &priv->rgba);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_color_button_drag_data_get (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
GtkSelectionData *selection_data,
|
||||
GtkColorButton *button)
|
||||
{
|
||||
GtkColorButtonPrivate *priv = gtk_color_button_get_instance_private (button);
|
||||
guint16 dropped[4];
|
||||
|
||||
dropped[0] = (guint16) (priv->rgba.red * 65535);
|
||||
dropped[1] = (guint16) (priv->rgba.green * 65535);
|
||||
dropped[2] = (guint16) (priv->rgba.blue * 65535);
|
||||
dropped[3] = (guint16) (priv->rgba.alpha * 65535);
|
||||
|
||||
gtk_selection_data_set (selection_data,
|
||||
gtk_selection_data_get_target (selection_data),
|
||||
16, (guchar *)dropped, 8);
|
||||
GtkColorButtonPrivate *priv = gtk_color_button_get_instance_private (GTK_COLOR_BUTTON (data));
|
||||
g_value_set_boxed (value, &priv->rgba);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -340,6 +300,9 @@ gtk_color_button_init (GtkColorButton *button)
|
||||
PangoRectangle rect;
|
||||
GtkStyleContext *context;
|
||||
GdkContentFormats *targets;
|
||||
GdkContentProvider *content;
|
||||
GtkDragSource *source;
|
||||
GtkDropTarget *dest;
|
||||
|
||||
priv->button = gtk_button_new ();
|
||||
g_signal_connect (priv->button, "clicked", G_CALLBACK (gtk_color_button_clicked), button);
|
||||
@@ -364,23 +327,17 @@ gtk_color_button_init (GtkColorButton *button)
|
||||
priv->use_alpha = FALSE;
|
||||
|
||||
targets = gdk_content_formats_new (drop_types, G_N_ELEMENTS (drop_types));
|
||||
gtk_drag_dest_set (priv->button,
|
||||
GTK_DEST_DEFAULT_MOTION |
|
||||
GTK_DEST_DEFAULT_HIGHLIGHT |
|
||||
GTK_DEST_DEFAULT_DROP,
|
||||
targets,
|
||||
GDK_ACTION_COPY);
|
||||
gtk_drag_source_set (priv->button,
|
||||
GDK_BUTTON1_MASK|GDK_BUTTON3_MASK,
|
||||
targets,
|
||||
GDK_ACTION_COPY);
|
||||
dest = gtk_drop_target_new (targets, GDK_ACTION_COPY);
|
||||
g_signal_connect (dest, "drag-drop", G_CALLBACK (gtk_color_button_drag_drop), button);
|
||||
gtk_widget_add_controller (GTK_WIDGET (button), GTK_EVENT_CONTROLLER (dest));
|
||||
gdk_content_formats_unref (targets);
|
||||
g_signal_connect (priv->button, "drag-begin",
|
||||
G_CALLBACK (gtk_color_button_drag_begin), button);
|
||||
g_signal_connect (priv->button, "drag-data-received",
|
||||
G_CALLBACK (gtk_color_button_drag_data_received), button);
|
||||
g_signal_connect (priv->button, "drag-data-get",
|
||||
G_CALLBACK (gtk_color_button_drag_data_get), button);
|
||||
|
||||
source = gtk_drag_source_new ();
|
||||
content = gdk_content_provider_new_with_callback (GDK_TYPE_RGBA, get_rgba_value, button);
|
||||
gtk_drag_source_set_content (source, content);
|
||||
g_object_unref (content);
|
||||
g_signal_connect (source, "drag-begin", G_CALLBACK (gtk_color_button_drag_begin), button);
|
||||
gtk_widget_add_controller (priv->button, GTK_EVENT_CONTROLLER (source));
|
||||
|
||||
context = gtk_widget_get_style_context (GTK_WIDGET (priv->button));
|
||||
gtk_style_context_add_class (context, "color");
|
||||
|
||||
+83
-86
@@ -22,7 +22,6 @@
|
||||
#include "gtkbox.h"
|
||||
#include "gtkcolorchooserprivate.h"
|
||||
#include "gtkcssnodeprivate.h"
|
||||
#include "gtkdnd.h"
|
||||
#include "gtkdragdest.h"
|
||||
#include "gtkdragsource.h"
|
||||
#include "gtkgesturelongpress.h"
|
||||
@@ -40,6 +39,7 @@
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkeventcontrollerkey.h"
|
||||
#include "gtknative.h"
|
||||
#include "gtkdragsource.h"
|
||||
|
||||
#include "a11y/gtkcolorswatchaccessibleprivate.h"
|
||||
|
||||
@@ -66,6 +66,7 @@ typedef struct
|
||||
GtkWidget *overlay_widget;
|
||||
|
||||
GtkWidget *popover;
|
||||
GtkDropTarget *dest;
|
||||
} GtkColorSwatchPrivate;
|
||||
|
||||
enum
|
||||
@@ -73,7 +74,8 @@ enum
|
||||
PROP_ZERO,
|
||||
PROP_RGBA,
|
||||
PROP_SELECTABLE,
|
||||
PROP_HAS_MENU
|
||||
PROP_HAS_MENU,
|
||||
PROP_CAN_DROP
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkColorSwatch, gtk_color_swatch, GTK_TYPE_WIDGET)
|
||||
@@ -113,87 +115,57 @@ swatch_snapshot (GtkWidget *widget,
|
||||
gtk_widget_snapshot_child (widget, priv->overlay_widget, snapshot);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
drag_set_color_icon (GdkDrag *drag,
|
||||
const GdkRGBA *color)
|
||||
gtk_color_swatch_drag_begin (GtkDragSource *source,
|
||||
GdkDrag *drag,
|
||||
GtkColorSwatch *swatch)
|
||||
{
|
||||
GtkColorSwatchPrivate *priv = gtk_color_swatch_get_instance_private (swatch);
|
||||
GtkSnapshot *snapshot;
|
||||
GdkPaintable *paintable;
|
||||
|
||||
snapshot = gtk_snapshot_new ();
|
||||
gtk_snapshot_append_color (snapshot,
|
||||
color,
|
||||
&GRAPHENE_RECT_INIT(0, 0, 48, 32));
|
||||
gtk_snapshot_append_color (snapshot, &priv->color, &GRAPHENE_RECT_INIT(0, 0, 48, 32));
|
||||
paintable = gtk_snapshot_free_to_paintable (snapshot, NULL);
|
||||
|
||||
gtk_drag_set_icon_paintable (drag, paintable, 4, 4);
|
||||
gtk_drag_source_set_icon (source, paintable, 0, 0);
|
||||
|
||||
g_object_unref (paintable);
|
||||
}
|
||||
|
||||
static void
|
||||
swatch_drag_begin (GtkWidget *widget,
|
||||
GdkDrag *drag)
|
||||
got_color (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GtkColorSwatch *swatch = GTK_COLOR_SWATCH (widget);
|
||||
GdkRGBA color;
|
||||
GdkDrop *drop = GDK_DROP (source);
|
||||
const GValue *value;
|
||||
|
||||
gtk_color_swatch_get_rgba (swatch, &color);
|
||||
drag_set_color_icon (drag, &color);
|
||||
}
|
||||
|
||||
static void
|
||||
swatch_drag_data_get (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
GtkSelectionData *selection_data)
|
||||
{
|
||||
GtkColorSwatch *swatch = GTK_COLOR_SWATCH (widget);
|
||||
guint16 vals[4];
|
||||
GdkRGBA color;
|
||||
|
||||
gtk_color_swatch_get_rgba (swatch, &color);
|
||||
|
||||
vals[0] = color.red * 0xffff;
|
||||
vals[1] = color.green * 0xffff;
|
||||
vals[2] = color.blue * 0xffff;
|
||||
vals[3] = color.alpha * 0xffff;
|
||||
|
||||
gtk_selection_data_set (selection_data,
|
||||
g_intern_static_string ("application/x-color"),
|
||||
16, (guchar *)vals, 8);
|
||||
}
|
||||
|
||||
static void
|
||||
swatch_drag_data_received (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
GtkSelectionData *selection_data)
|
||||
{
|
||||
gint length;
|
||||
guint16 *vals;
|
||||
GdkRGBA color;
|
||||
|
||||
length = gtk_selection_data_get_length (selection_data);
|
||||
|
||||
if (length < 0)
|
||||
return;
|
||||
|
||||
/* We accept drops with the wrong format, since the KDE color
|
||||
* chooser incorrectly drops application/x-color with format 8.
|
||||
*/
|
||||
if (length != 8)
|
||||
value = gdk_drop_read_value_finish (drop, result, NULL);
|
||||
if (value)
|
||||
{
|
||||
g_warning ("Received invalid color data");
|
||||
return;
|
||||
GdkRGBA *color = g_value_get_boxed (value);
|
||||
gtk_color_swatch_set_rgba (GTK_COLOR_SWATCH (data), color);
|
||||
gdk_drop_finish (drop, GDK_ACTION_COPY);
|
||||
}
|
||||
else
|
||||
gdk_drop_finish (drop, 0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
swatch_drag_drop (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
int x,
|
||||
int y,
|
||||
GtkColorSwatch *swatch)
|
||||
{
|
||||
if (gdk_drop_has_value (drop, GDK_TYPE_RGBA))
|
||||
{
|
||||
gdk_drop_read_value_async (drop, GDK_TYPE_RGBA, G_PRIORITY_DEFAULT, NULL, got_color, swatch);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
vals = (guint16 *) gtk_selection_data_get_data (selection_data);
|
||||
|
||||
color.red = (gdouble)vals[0] / 0xffff;
|
||||
color.green = (gdouble)vals[1] / 0xffff;
|
||||
color.blue = (gdouble)vals[2] / 0xffff;
|
||||
color.alpha = (gdouble)vals[3] / 0xffff;
|
||||
|
||||
gtk_color_swatch_set_rgba (GTK_COLOR_SWATCH (widget), &color);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -455,6 +427,9 @@ swatch_get_property (GObject *object,
|
||||
case PROP_HAS_MENU:
|
||||
g_value_set_boolean (value, priv->has_menu);
|
||||
break;
|
||||
case PROP_CAN_DROP:
|
||||
g_value_set_boolean (value, priv->dest != NULL);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -481,6 +456,9 @@ swatch_set_property (GObject *object,
|
||||
case PROP_HAS_MENU:
|
||||
priv->has_menu = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_CAN_DROP:
|
||||
gtk_color_swatch_set_can_drop (swatch, g_value_get_boolean (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -495,7 +473,7 @@ swatch_finalize (GObject *object)
|
||||
|
||||
g_free (priv->icon);
|
||||
gtk_widget_unparent (priv->overlay_widget);
|
||||
|
||||
|
||||
G_OBJECT_CLASS (gtk_color_swatch_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@@ -523,9 +501,6 @@ gtk_color_swatch_class_init (GtkColorSwatchClass *class)
|
||||
|
||||
widget_class->measure = gtk_color_swatch_measure;
|
||||
widget_class->snapshot = swatch_snapshot;
|
||||
widget_class->drag_begin = swatch_drag_begin;
|
||||
widget_class->drag_data_get = swatch_drag_data_get;
|
||||
widget_class->drag_data_received = swatch_drag_data_received;
|
||||
widget_class->popup_menu = swatch_popup_menu;
|
||||
widget_class->size_allocate = swatch_size_allocate;
|
||||
widget_class->state_flags_changed = swatch_state_flags_changed;
|
||||
@@ -539,6 +514,9 @@ gtk_color_swatch_class_init (GtkColorSwatchClass *class)
|
||||
g_object_class_install_property (object_class, PROP_HAS_MENU,
|
||||
g_param_spec_boolean ("has-menu", P_("Has Menu"), P_("Whether the swatch should offer customization"),
|
||||
TRUE, GTK_PARAM_READWRITE));
|
||||
g_object_class_install_property (object_class, PROP_CAN_DROP,
|
||||
g_param_spec_boolean ("can-drop", P_("Can Drop"), P_("Whether the swatch should accept drops"),
|
||||
FALSE, GTK_PARAM_READWRITE));
|
||||
|
||||
gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_COLOR_SWATCH_ACCESSIBLE);
|
||||
gtk_widget_class_set_css_name (widget_class, I_("colorswatch"));
|
||||
@@ -600,6 +578,14 @@ static const char *dnd_targets[] = {
|
||||
"application/x-color"
|
||||
};
|
||||
|
||||
static void
|
||||
get_rgba_value (GValue *value,
|
||||
gpointer data)
|
||||
{
|
||||
GtkColorSwatchPrivate *priv = gtk_color_swatch_get_instance_private (GTK_COLOR_SWATCH (data));
|
||||
g_value_set_boxed (value, &priv->color);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_color_swatch_set_rgba (GtkColorSwatch *swatch,
|
||||
const GdkRGBA *color)
|
||||
@@ -611,12 +597,16 @@ gtk_color_swatch_set_rgba (GtkColorSwatch *swatch,
|
||||
|
||||
if (!priv->has_color)
|
||||
{
|
||||
GdkContentFormats *targets = gdk_content_formats_new (dnd_targets, G_N_ELEMENTS (dnd_targets));
|
||||
gtk_drag_source_set (GTK_WIDGET (swatch),
|
||||
GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
|
||||
targets,
|
||||
GDK_ACTION_COPY | GDK_ACTION_MOVE);
|
||||
gdk_content_formats_unref (targets);
|
||||
GdkContentProvider *content;
|
||||
GtkDragSource *source;
|
||||
|
||||
source = gtk_drag_source_new ();
|
||||
content = gdk_content_provider_new_with_callback (GDK_TYPE_RGBA, get_rgba_value, swatch);
|
||||
gtk_drag_source_set_content (source, content);
|
||||
g_object_unref (content);
|
||||
g_signal_connect (source, "drag-begin", G_CALLBACK (gtk_color_swatch_drag_begin), swatch);
|
||||
|
||||
gtk_widget_add_controller (GTK_WIDGET (swatch), GTK_EVENT_CONTROLLER (source));
|
||||
}
|
||||
|
||||
priv->has_color = TRUE;
|
||||
@@ -676,21 +666,28 @@ void
|
||||
gtk_color_swatch_set_can_drop (GtkColorSwatch *swatch,
|
||||
gboolean can_drop)
|
||||
{
|
||||
if (can_drop)
|
||||
GtkColorSwatchPrivate *priv = gtk_color_swatch_get_instance_private (swatch);
|
||||
|
||||
if (can_drop == (priv->dest != NULL))
|
||||
return;
|
||||
|
||||
if (can_drop && !priv->dest)
|
||||
{
|
||||
GdkContentFormats *targets = gdk_content_formats_new (dnd_targets, G_N_ELEMENTS (dnd_targets));
|
||||
gtk_drag_dest_set (GTK_WIDGET (swatch),
|
||||
GTK_DEST_DEFAULT_HIGHLIGHT |
|
||||
GTK_DEST_DEFAULT_MOTION |
|
||||
GTK_DEST_DEFAULT_DROP,
|
||||
targets,
|
||||
GDK_ACTION_COPY);
|
||||
GdkContentFormats *targets;
|
||||
|
||||
targets = gdk_content_formats_new (dnd_targets, G_N_ELEMENTS (dnd_targets));
|
||||
priv->dest = gtk_drop_target_new (targets, GDK_ACTION_COPY);
|
||||
g_signal_connect (priv->dest, "drag-drop", G_CALLBACK (swatch_drag_drop), swatch);
|
||||
gtk_widget_add_controller (GTK_WIDGET (swatch), GTK_EVENT_CONTROLLER (priv->dest));
|
||||
gdk_content_formats_unref (targets);
|
||||
}
|
||||
else
|
||||
if (!can_drop && priv->dest)
|
||||
{
|
||||
gtk_drag_dest_unset (GTK_WIDGET (swatch));
|
||||
gtk_widget_remove_controller (GTK_WIDGET (swatch), GTK_EVENT_CONTROLLER (priv->dest));
|
||||
priv->dest = NULL;
|
||||
}
|
||||
|
||||
g_object_notify (G_OBJECT (swatch), "can-drop");
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+2
-2
@@ -480,8 +480,8 @@ gtk_container_get_request_mode (GtkWidget *widget)
|
||||
/**
|
||||
* gtk_container_forall: (virtual forall)
|
||||
* @container: a #GtkContainer
|
||||
* @callback: (scope call) (closure callback_data): a callback
|
||||
* @callback_data: callback user data
|
||||
* @callback: (scope call): a callback
|
||||
* @callback_data: (closure): callback user data
|
||||
*
|
||||
* Invokes @callback on each direct child of @container, including
|
||||
* children that are considered “internal” (implementation details
|
||||
|
||||
@@ -79,6 +79,15 @@ gtk_css_animated_style_is_static (GtkCssStyle *style)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GtkCssStaticStyle *
|
||||
gtk_css_animated_style_get_static_style (GtkCssStyle *style)
|
||||
{
|
||||
/* This is called a lot, so we avoid a dynamic type check here */
|
||||
GtkCssAnimatedStyle *animated = (GtkCssAnimatedStyle *) style;
|
||||
|
||||
return (GtkCssStaticStyle *)animated->style;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_animated_style_dispose (GObject *object)
|
||||
{
|
||||
@@ -123,6 +132,7 @@ gtk_css_animated_style_class_init (GtkCssAnimatedStyleClass *klass)
|
||||
style_class->get_value = gtk_css_animated_style_get_value;
|
||||
style_class->get_section = gtk_css_animated_style_get_section;
|
||||
style_class->is_static = gtk_css_animated_style_is_static;
|
||||
style_class->get_static_style = gtk_css_animated_style_get_static_style;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -35,10 +35,10 @@ static GtkCssValue *gtk_css_font_features_value_new_empty (void);
|
||||
|
||||
static void
|
||||
gtk_css_font_features_value_add_feature (GtkCssValue *value,
|
||||
const char *name,
|
||||
GtkCssValue *val)
|
||||
const char *name,
|
||||
int num)
|
||||
{
|
||||
g_hash_table_insert (value->features, g_strdup (name), val);
|
||||
g_hash_table_insert (value->features, g_strdup (name), GINT_TO_POINTER (num));
|
||||
}
|
||||
|
||||
|
||||
@@ -57,29 +57,7 @@ gtk_css_value_font_features_compute (GtkCssValue *specified,
|
||||
GtkCssStyle *style,
|
||||
GtkCssStyle *parent_style)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
gpointer name, val;
|
||||
GtkCssValue *computed_val;
|
||||
GtkCssValue *result;
|
||||
gboolean changes = FALSE;
|
||||
|
||||
result = gtk_css_font_features_value_new_empty ();
|
||||
|
||||
g_hash_table_iter_init (&iter, specified->features);
|
||||
while (g_hash_table_iter_next (&iter, &name, &val))
|
||||
{
|
||||
computed_val = _gtk_css_value_compute (val, property_id, provider, style, parent_style);
|
||||
changes |= computed_val != val;
|
||||
gtk_css_font_features_value_add_feature (result, name, computed_val);
|
||||
}
|
||||
|
||||
if (!changes)
|
||||
{
|
||||
_gtk_css_value_unref (result);
|
||||
result = _gtk_css_value_ref (specified);
|
||||
}
|
||||
|
||||
return result;
|
||||
return _gtk_css_value_ref (specified);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -96,10 +74,8 @@ gtk_css_value_font_features_equal (const GtkCssValue *value1,
|
||||
while (g_hash_table_iter_next (&iter, &name, &val1))
|
||||
{
|
||||
val2 = g_hash_table_lookup (value2->features, name);
|
||||
if (val2 == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!_gtk_css_value_equal (val1, val2))
|
||||
if (val1 != val2)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -113,9 +89,10 @@ gtk_css_value_font_features_transition (GtkCssValue *start,
|
||||
double progress)
|
||||
{
|
||||
const char *name;
|
||||
GtkCssValue *start_val, *end_val;
|
||||
gpointer start_val, end_val;
|
||||
GHashTableIter iter;
|
||||
GtkCssValue *result, *transition;
|
||||
gpointer transition;
|
||||
GtkCssValue *result;
|
||||
|
||||
/* XXX: For value that are only in start or end but not both,
|
||||
* we don't transition but just keep the value.
|
||||
@@ -129,11 +106,11 @@ gtk_css_value_font_features_transition (GtkCssValue *start,
|
||||
{
|
||||
end_val = g_hash_table_lookup (end->features, name);
|
||||
if (end_val == NULL)
|
||||
transition = _gtk_css_value_ref (start_val);
|
||||
transition = start_val;
|
||||
else
|
||||
transition = _gtk_css_value_transition (start_val, end_val, property_id, progress);
|
||||
transition = progress > 0.5 ? start_val : end_val;
|
||||
|
||||
gtk_css_font_features_value_add_feature (result, name, transition);
|
||||
gtk_css_font_features_value_add_feature (result, name, GPOINTER_TO_INT (transition));
|
||||
}
|
||||
|
||||
g_hash_table_iter_init (&iter, end->features);
|
||||
@@ -143,7 +120,7 @@ gtk_css_value_font_features_transition (GtkCssValue *start,
|
||||
if (start_val != NULL)
|
||||
continue;
|
||||
|
||||
gtk_css_font_features_value_add_feature (result, name, _gtk_css_value_ref (end_val));
|
||||
gtk_css_font_features_value_add_feature (result, name, GPOINTER_TO_INT (end_val));
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -155,7 +132,7 @@ gtk_css_value_font_features_print (const GtkCssValue *value,
|
||||
{
|
||||
GHashTableIter iter;
|
||||
const char *name;
|
||||
GtkCssValue *val;
|
||||
gpointer val;
|
||||
gboolean first = TRUE;
|
||||
|
||||
if (value == default_font_features)
|
||||
@@ -172,7 +149,7 @@ gtk_css_value_font_features_print (const GtkCssValue *value,
|
||||
else
|
||||
g_string_append (string, ", ");
|
||||
g_string_append_printf (string, "\"%s\" ", name);
|
||||
_gtk_css_value_print (val, string);
|
||||
g_string_append_printf (string, "%d", GPOINTER_TO_INT (val));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,7 +203,7 @@ is_valid_opentype_tag (const char *s)
|
||||
GtkCssValue *
|
||||
gtk_css_font_features_value_parse (GtkCssParser *parser)
|
||||
{
|
||||
GtkCssValue *result, *val;
|
||||
GtkCssValue *result;
|
||||
char *name;
|
||||
int num;
|
||||
|
||||
@@ -252,16 +229,12 @@ gtk_css_font_features_value_parse (GtkCssParser *parser)
|
||||
}
|
||||
|
||||
if (gtk_css_parser_try_ident (parser, "on"))
|
||||
val = _gtk_css_number_value_new (1.0, GTK_CSS_NUMBER);
|
||||
num = 1;
|
||||
else if (gtk_css_parser_try_ident (parser, "off"))
|
||||
val = _gtk_css_number_value_new (0.0, GTK_CSS_NUMBER);
|
||||
num = 0;
|
||||
else if (gtk_css_parser_has_integer (parser))
|
||||
{
|
||||
if (gtk_css_parser_consume_integer (parser, &num))
|
||||
{
|
||||
val = _gtk_css_number_value_new ((double)num, GTK_CSS_NUMBER);
|
||||
}
|
||||
else
|
||||
if (!gtk_css_parser_consume_integer (parser, &num))
|
||||
{
|
||||
g_free (name);
|
||||
_gtk_css_value_unref (result);
|
||||
@@ -269,9 +242,9 @@ gtk_css_font_features_value_parse (GtkCssParser *parser)
|
||||
}
|
||||
}
|
||||
else
|
||||
val = _gtk_css_number_value_new (1.0, GTK_CSS_NUMBER);
|
||||
num = 1;
|
||||
|
||||
gtk_css_font_features_value_add_feature (result, name, val);
|
||||
gtk_css_font_features_value_add_feature (result, name, num);
|
||||
g_free (name);
|
||||
} while (gtk_css_parser_try_token (parser, GTK_CSS_TOKEN_COMMA));
|
||||
|
||||
@@ -301,7 +274,7 @@ gtk_css_font_features_value_get_features (GtkCssValue *value)
|
||||
first = FALSE;
|
||||
else
|
||||
g_string_append (string, ", ");
|
||||
g_string_append_printf (string, "%s %d", name, (int)_gtk_css_number_value_get (val, 100));
|
||||
g_string_append_printf (string, "%s %d", name, GPOINTER_TO_INT (val));
|
||||
}
|
||||
|
||||
return g_string_free (string, FALSE);
|
||||
|
||||
@@ -56,29 +56,7 @@ gtk_css_value_font_variations_compute (GtkCssValue *specified,
|
||||
GtkCssStyle *style,
|
||||
GtkCssStyle *parent_style)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
gpointer name, coord;
|
||||
GtkCssValue *computed_coord;
|
||||
GtkCssValue *result;
|
||||
gboolean changes = FALSE;
|
||||
|
||||
result = gtk_css_font_variations_value_new_empty ();
|
||||
|
||||
g_hash_table_iter_init (&iter, specified->axes);
|
||||
while (g_hash_table_iter_next (&iter, &name, &coord))
|
||||
{
|
||||
computed_coord = _gtk_css_value_compute (coord, property_id, provider, style, parent_style);
|
||||
changes |= computed_coord != coord;
|
||||
gtk_css_font_variations_value_add_axis (result, name, computed_coord);
|
||||
}
|
||||
|
||||
if (!changes)
|
||||
{
|
||||
_gtk_css_value_unref (result);
|
||||
result = _gtk_css_value_ref (specified);
|
||||
}
|
||||
|
||||
return result;
|
||||
return _gtk_css_value_ref (specified);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
||||
@@ -1,670 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012 Red Hat Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkcssimagebuiltinprivate.h"
|
||||
|
||||
#include "gtkcssenumvalueprivate.h"
|
||||
#include "gtkcssnumbervalueprivate.h"
|
||||
#include "gtkcssrgbavalueprivate.h"
|
||||
#include "gtkcssstyleprivate.h"
|
||||
#include "gtkhslaprivate.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "fallback-c89.c"
|
||||
|
||||
G_DEFINE_TYPE (GtkCssImageBuiltin, gtk_css_image_builtin, GTK_TYPE_CSS_IMAGE)
|
||||
|
||||
static GtkCssImage *the_one_true_image;
|
||||
|
||||
static void
|
||||
gtk_css_image_builtin_draw_check (GtkCssImage *image,
|
||||
cairo_t *cr,
|
||||
double width,
|
||||
double height,
|
||||
gboolean checked,
|
||||
gboolean inconsistent)
|
||||
{
|
||||
GtkCssImageBuiltin *builtin = GTK_CSS_IMAGE_BUILTIN (image);
|
||||
gint x, y, exterior_size, interior_size, pad;
|
||||
|
||||
exterior_size = MIN (width, height);
|
||||
|
||||
if (exterior_size % 2 == 0) /* Ensure odd */
|
||||
exterior_size -= 1;
|
||||
|
||||
pad = 1 + MAX (1, (exterior_size - 2) / 9);
|
||||
interior_size = MAX (1, exterior_size - 2 * pad);
|
||||
|
||||
if (interior_size < 7)
|
||||
pad = MAX (0, (exterior_size - interior_size) / 2);
|
||||
|
||||
x = - (1 + exterior_size - (gint) width) / 2;
|
||||
y = - (1 + exterior_size - (gint) height) / 2;
|
||||
|
||||
gdk_cairo_set_source_rgba (cr, &builtin->fg_color);
|
||||
|
||||
if (inconsistent)
|
||||
{
|
||||
int line_thickness = MAX (1, (3 + interior_size * 2) / 7);
|
||||
|
||||
cairo_rectangle (cr,
|
||||
x + pad,
|
||||
y + pad + (1 + interior_size - line_thickness) / 2,
|
||||
interior_size,
|
||||
line_thickness);
|
||||
cairo_fill (cr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (checked)
|
||||
{
|
||||
cairo_save (cr);
|
||||
cairo_translate (cr,
|
||||
x + pad, y + pad);
|
||||
|
||||
cairo_scale (cr, interior_size / 7., interior_size / 7.);
|
||||
|
||||
cairo_rectangle (cr, 0, 0, 7, 7);
|
||||
cairo_clip (cr);
|
||||
|
||||
cairo_move_to (cr, 7.0, 0.0);
|
||||
cairo_line_to (cr, 7.5, 1.0);
|
||||
cairo_curve_to (cr, 5.3, 2.0,
|
||||
4.3, 4.0,
|
||||
3.5, 7.0);
|
||||
cairo_curve_to (cr, 3.0, 5.7,
|
||||
1.3, 4.7,
|
||||
0.0, 4.7);
|
||||
cairo_line_to (cr, 0.2, 3.5);
|
||||
cairo_curve_to (cr, 1.1, 3.5,
|
||||
2.3, 4.3,
|
||||
3.0, 5.0);
|
||||
cairo_curve_to (cr, 1.0, 3.9,
|
||||
2.4, 4.1,
|
||||
3.2, 4.9);
|
||||
cairo_curve_to (cr, 3.5, 3.1,
|
||||
5.2, 2.0,
|
||||
7.0, 0.0);
|
||||
|
||||
cairo_fill (cr);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_image_builtin_draw_option (GtkCssImage *image,
|
||||
cairo_t *cr,
|
||||
double width,
|
||||
double height,
|
||||
gboolean checked,
|
||||
gboolean inconsistent)
|
||||
{
|
||||
GtkCssImageBuiltin *builtin = GTK_CSS_IMAGE_BUILTIN (image);
|
||||
gint x, y, exterior_size, interior_size, pad;
|
||||
|
||||
exterior_size = MIN (width, height);
|
||||
|
||||
if (exterior_size % 2 == 0) /* Ensure odd */
|
||||
exterior_size -= 1;
|
||||
|
||||
x = - (1 + exterior_size - width) / 2;
|
||||
y = - (1 + exterior_size - height) / 2;
|
||||
|
||||
gdk_cairo_set_source_rgba (cr, &builtin->fg_color);
|
||||
|
||||
pad = 1 + MAX (1, 2 * (exterior_size - 2) / 9);
|
||||
interior_size = MAX (1, exterior_size - 2 * pad);
|
||||
|
||||
if (interior_size < 7)
|
||||
pad = MAX (0, (exterior_size - interior_size) / 2);
|
||||
|
||||
if (inconsistent)
|
||||
{
|
||||
gint line_thickness;
|
||||
|
||||
line_thickness = MAX (1, (3 + interior_size * 2) / 7);
|
||||
|
||||
cairo_rectangle (cr,
|
||||
x + pad,
|
||||
y + pad + (interior_size - line_thickness) / 2.,
|
||||
interior_size,
|
||||
line_thickness);
|
||||
cairo_fill (cr);
|
||||
}
|
||||
else if (checked)
|
||||
{
|
||||
cairo_new_sub_path (cr);
|
||||
cairo_arc (cr,
|
||||
x + pad + interior_size / 2.,
|
||||
y + pad + interior_size / 2.,
|
||||
interior_size / 2.,
|
||||
0, 2 * G_PI);
|
||||
cairo_fill (cr);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_image_builtin_draw_arrow (GtkCssImage *image,
|
||||
cairo_t *cr,
|
||||
double width,
|
||||
double height,
|
||||
GtkCssImageBuiltinType image_type)
|
||||
{
|
||||
GtkCssImageBuiltin *builtin = GTK_CSS_IMAGE_BUILTIN (image);
|
||||
double line_width;
|
||||
double size;
|
||||
|
||||
size = MIN (width, height);
|
||||
|
||||
cairo_translate (cr, width / 2.0, height / 2.0);
|
||||
switch ((guint) image_type)
|
||||
{
|
||||
case GTK_CSS_IMAGE_BUILTIN_ARROW_UP:
|
||||
break;
|
||||
case GTK_CSS_IMAGE_BUILTIN_ARROW_DOWN:
|
||||
cairo_rotate (cr, G_PI);
|
||||
break;
|
||||
case GTK_CSS_IMAGE_BUILTIN_ARROW_LEFT:
|
||||
cairo_rotate (cr, 3 * G_PI / 2);
|
||||
break;
|
||||
case GTK_CSS_IMAGE_BUILTIN_ARROW_RIGHT:
|
||||
cairo_rotate (cr, G_PI / 2);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
line_width = size / 3.0 / sqrt (2);
|
||||
cairo_set_line_width (cr, line_width);
|
||||
cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
|
||||
cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
|
||||
|
||||
cairo_scale (cr,
|
||||
(size / (size + line_width)),
|
||||
(size / (size + line_width)));
|
||||
|
||||
cairo_move_to (cr, -size / 2.0, size / 4.0);
|
||||
cairo_rel_line_to (cr, size / 2.0, -size / 2.0);
|
||||
cairo_rel_line_to (cr, size / 2.0, size / 2.0);
|
||||
|
||||
gdk_cairo_set_source_rgba (cr, &builtin->fg_color);
|
||||
cairo_stroke (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_image_builtin_draw_expander (GtkCssImage *image,
|
||||
cairo_t *cr,
|
||||
double width,
|
||||
double height,
|
||||
gboolean horizontal,
|
||||
gboolean is_rtl,
|
||||
gboolean expanded)
|
||||
{
|
||||
GtkCssImageBuiltin *builtin = GTK_CSS_IMAGE_BUILTIN (image);
|
||||
double vertical_overshoot;
|
||||
int diameter;
|
||||
double radius;
|
||||
double interp; /* interpolation factor for center position */
|
||||
double x_double_horz, y_double_horz;
|
||||
double x_double_vert, y_double_vert;
|
||||
double x_double, y_double;
|
||||
gdouble angle;
|
||||
gint line_width;
|
||||
gdouble progress;
|
||||
|
||||
line_width = 1;
|
||||
progress = expanded ? 1 : 0;
|
||||
|
||||
if (!horizontal)
|
||||
{
|
||||
if (is_rtl)
|
||||
angle = (G_PI) - ((G_PI / 2) * progress);
|
||||
else
|
||||
angle = (G_PI / 2) * progress;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_rtl)
|
||||
angle = (G_PI / 2) + ((G_PI / 2) * progress);
|
||||
else
|
||||
angle = (G_PI / 2) - ((G_PI / 2) * progress);
|
||||
}
|
||||
|
||||
interp = progress;
|
||||
|
||||
/* Compute distance that the stroke extends beyonds the end
|
||||
* of the triangle we draw.
|
||||
*/
|
||||
vertical_overshoot = line_width / 2.0 * (1. / tan (G_PI / 8));
|
||||
|
||||
/* For odd line widths, we end the vertical line of the triangle
|
||||
* at a half pixel, so we round differently.
|
||||
*/
|
||||
if (line_width % 2 == 1)
|
||||
vertical_overshoot = ceil (0.5 + vertical_overshoot) - 0.5;
|
||||
else
|
||||
vertical_overshoot = ceil (vertical_overshoot);
|
||||
|
||||
/* Adjust the size of the triangle we draw so that the entire stroke fits
|
||||
*/
|
||||
diameter = (gint) MAX (3, width - 2 * vertical_overshoot);
|
||||
|
||||
/* If the line width is odd, we want the diameter to be even,
|
||||
* and vice versa, so force the sum to be odd. This relationship
|
||||
* makes the point of the triangle look right.
|
||||
*/
|
||||
diameter -= (1 - (diameter + line_width) % 2);
|
||||
|
||||
radius = diameter / 2.;
|
||||
|
||||
/* Adjust the center so that the stroke is properly aligned with
|
||||
* the pixel grid. The center adjustment is different for the
|
||||
* horizontal and vertical orientations. For intermediate positions
|
||||
* we interpolate between the two.
|
||||
*/
|
||||
x_double_vert = floor ((width / 2) - (radius + line_width) / 2.) + (radius + line_width) / 2.;
|
||||
y_double_vert = (height / 2) - 0.5;
|
||||
|
||||
x_double_horz = (width / 2) - 0.5;
|
||||
y_double_horz = floor ((height / 2) - (radius + line_width) / 2.) + (radius + line_width) / 2.;
|
||||
|
||||
x_double = x_double_vert * (1 - interp) + x_double_horz * interp;
|
||||
y_double = y_double_vert * (1 - interp) + y_double_horz * interp;
|
||||
|
||||
cairo_translate (cr, x_double, y_double);
|
||||
cairo_rotate (cr, angle);
|
||||
|
||||
cairo_move_to (cr, - radius / 2., - radius);
|
||||
cairo_line_to (cr, radius / 2., 0);
|
||||
cairo_line_to (cr, - radius / 2., radius);
|
||||
cairo_close_path (cr);
|
||||
|
||||
cairo_set_line_width (cr, line_width);
|
||||
|
||||
gdk_cairo_set_source_rgba (cr, &builtin->fg_color);
|
||||
|
||||
cairo_fill (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
color_shade (const GdkRGBA *color,
|
||||
gdouble factor,
|
||||
GdkRGBA *color_return)
|
||||
{
|
||||
GtkHSLA hsla;
|
||||
|
||||
_gtk_hsla_init_from_rgba (&hsla, color);
|
||||
_gtk_hsla_shade (&hsla, &hsla, factor);
|
||||
_gdk_rgba_init_from_hsla (color_return, &hsla);
|
||||
}
|
||||
|
||||
static void
|
||||
render_dot (cairo_t *cr,
|
||||
const GdkRGBA *lighter,
|
||||
const GdkRGBA *darker,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
gdouble size)
|
||||
{
|
||||
size = CLAMP ((gint) size, 2, 3);
|
||||
|
||||
if (size == 2)
|
||||
{
|
||||
gdk_cairo_set_source_rgba (cr, lighter);
|
||||
cairo_rectangle (cr, x, y, 1, 1);
|
||||
cairo_rectangle (cr, x + 1, y + 1, 1, 1);
|
||||
cairo_fill (cr);
|
||||
}
|
||||
else if (size == 3)
|
||||
{
|
||||
gdk_cairo_set_source_rgba (cr, lighter);
|
||||
cairo_rectangle (cr, x, y, 2, 1);
|
||||
cairo_rectangle (cr, x, y, 1, 2);
|
||||
cairo_fill (cr);
|
||||
|
||||
gdk_cairo_set_source_rgba (cr, darker);
|
||||
cairo_rectangle (cr, x + 1, y + 1, 2, 1);
|
||||
cairo_rectangle (cr, x + 2, y, 1, 2);
|
||||
cairo_fill (cr);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_image_builtin_draw_pane_separator (GtkCssImage *image,
|
||||
cairo_t *cr,
|
||||
double width,
|
||||
double height)
|
||||
{
|
||||
GtkCssImageBuiltin *builtin = GTK_CSS_IMAGE_BUILTIN (image);
|
||||
GdkRGBA lighter, darker;
|
||||
gint xx, yy;
|
||||
|
||||
cairo_set_line_width (cr, 1.0);
|
||||
|
||||
color_shade (&builtin->bg_color, 0.7, &darker);
|
||||
color_shade (&builtin->bg_color, 1.3, &lighter);
|
||||
|
||||
if (width > height)
|
||||
for (xx = width / 2 - 15; xx <= width / 2 + 15; xx += 5)
|
||||
render_dot (cr, &lighter, &darker, xx, height / 2 - 1, 3);
|
||||
else
|
||||
for (yy = height / 2 - 15; yy <= height / 2 + 15; yy += 5)
|
||||
render_dot (cr, &lighter, &darker, width / 2 - 1, yy, 3);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_image_builtin_draw_handle (GtkCssImage *image,
|
||||
cairo_t *cr,
|
||||
double width,
|
||||
double height)
|
||||
{
|
||||
GtkCssImageBuiltin *builtin = GTK_CSS_IMAGE_BUILTIN (image);
|
||||
GdkRGBA lighter, darker;
|
||||
gint xx, yy;
|
||||
|
||||
cairo_set_line_width (cr, 1.0);
|
||||
|
||||
color_shade (&builtin->bg_color, 0.7, &darker);
|
||||
color_shade (&builtin->bg_color, 1.3, &lighter);
|
||||
|
||||
for (yy = 0; yy < height; yy += 3)
|
||||
for (xx = 0; xx < width; xx += 6)
|
||||
{
|
||||
render_dot (cr, &lighter, &darker, xx, yy, 2);
|
||||
render_dot (cr, &lighter, &darker, xx + 3, yy + 1, 2);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_image_builtin_draw_spinner (GtkCssImage *image,
|
||||
cairo_t *cr,
|
||||
double width,
|
||||
double height)
|
||||
{
|
||||
GtkCssImageBuiltin *builtin = GTK_CSS_IMAGE_BUILTIN (image);
|
||||
guint num_steps;
|
||||
gdouble radius;
|
||||
gdouble half;
|
||||
gint i;
|
||||
|
||||
radius = MIN (width / 2, height / 2);
|
||||
|
||||
cairo_translate (cr, width / 2, height / 2);
|
||||
|
||||
num_steps = 12;
|
||||
|
||||
cairo_set_line_width (cr, 2.0);
|
||||
|
||||
half = num_steps / 2;
|
||||
|
||||
for (i = 0; i < num_steps; i++)
|
||||
{
|
||||
gint inset = 0.7 * radius;
|
||||
/* transparency is a function of time and intial value */
|
||||
gdouble t = 1.0 - (gdouble) i / num_steps;
|
||||
gdouble xscale = - sin (i * G_PI / half);
|
||||
gdouble yscale = - cos (i * G_PI / half);
|
||||
|
||||
cairo_move_to (cr,
|
||||
(radius - inset) * xscale,
|
||||
(radius - inset) * yscale);
|
||||
cairo_line_to (cr,
|
||||
radius * xscale,
|
||||
radius * yscale);
|
||||
|
||||
cairo_set_source_rgba (cr,
|
||||
builtin->fg_color.red,
|
||||
builtin->fg_color.green,
|
||||
builtin->fg_color.blue,
|
||||
builtin->fg_color.alpha * t);
|
||||
|
||||
cairo_stroke (cr);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_image_builtin_real_snapshot (GtkCssImage *image,
|
||||
GtkSnapshot *snapshot,
|
||||
double width,
|
||||
double height)
|
||||
{
|
||||
/* It's a builtin image, other code will draw things */
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_builtin_parse (GtkCssImage *image,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
if (!gtk_css_parser_try_ident (parser, "builtin"))
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Expected 'builtin'");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_image_builtin_print (GtkCssImage *image,
|
||||
GString *string)
|
||||
{
|
||||
g_string_append (string, "builtin");
|
||||
}
|
||||
|
||||
static GtkCssImage *
|
||||
gtk_css_image_builtin_compute (GtkCssImage *image,
|
||||
guint property_id,
|
||||
GtkStyleProvider *provider,
|
||||
GtkCssStyle *style,
|
||||
GtkCssStyle *parent_style)
|
||||
{
|
||||
GtkCssImageBuiltin *result;
|
||||
|
||||
result = g_object_new (GTK_TYPE_CSS_IMAGE_BUILTIN, NULL);
|
||||
|
||||
result->fg_color = *_gtk_css_rgba_value_get_rgba (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_COLOR));
|
||||
result->bg_color = *_gtk_css_rgba_value_get_rgba (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BACKGROUND_COLOR));
|
||||
|
||||
return GTK_CSS_IMAGE (result);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_builtin_equal (GtkCssImage *image1,
|
||||
GtkCssImage *image2)
|
||||
{
|
||||
GtkCssImageBuiltin *builtin1 = (GtkCssImageBuiltin *) image1;
|
||||
GtkCssImageBuiltin *builtin2 = (GtkCssImageBuiltin *) image2;
|
||||
|
||||
return gdk_rgba_equal (&builtin1->fg_color, &builtin2->fg_color)
|
||||
&& gdk_rgba_equal (&builtin1->bg_color, &builtin2->bg_color);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_image_builtin_dispose (GObject *object)
|
||||
{
|
||||
if (the_one_true_image == GTK_CSS_IMAGE (object))
|
||||
the_one_true_image = NULL;
|
||||
|
||||
G_OBJECT_CLASS (gtk_css_image_builtin_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_image_builtin_class_init (GtkCssImageBuiltinClass *klass)
|
||||
{
|
||||
GtkCssImageClass *image_class = GTK_CSS_IMAGE_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
image_class->snapshot = gtk_css_image_builtin_real_snapshot;
|
||||
image_class->parse = gtk_css_image_builtin_parse;
|
||||
image_class->print = gtk_css_image_builtin_print;
|
||||
image_class->compute = gtk_css_image_builtin_compute;
|
||||
image_class->equal = gtk_css_image_builtin_equal;
|
||||
|
||||
object_class->dispose = gtk_css_image_builtin_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_image_builtin_init (GtkCssImageBuiltin *builtin)
|
||||
{
|
||||
/* white background */
|
||||
builtin->bg_color.red = builtin->bg_color.green = builtin->bg_color.blue = builtin->bg_color.alpha = 1.0;
|
||||
/* black foreground */
|
||||
builtin->fg_color.alpha = 1.0;
|
||||
}
|
||||
|
||||
GtkCssImage *
|
||||
gtk_css_image_builtin_new (void)
|
||||
{
|
||||
if (the_one_true_image == NULL)
|
||||
the_one_true_image = g_object_new (GTK_TYPE_CSS_IMAGE_BUILTIN, NULL);
|
||||
else
|
||||
g_object_ref (the_one_true_image);
|
||||
|
||||
return the_one_true_image;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_image_builtin_draw (GtkCssImage *image,
|
||||
cairo_t *cr,
|
||||
double width,
|
||||
double height,
|
||||
GtkCssImageBuiltinType image_type)
|
||||
{
|
||||
if (!GTK_IS_CSS_IMAGE_BUILTIN (image))
|
||||
{
|
||||
_gtk_css_image_draw (image, cr, width, height);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (image_type)
|
||||
{
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
case GTK_CSS_IMAGE_BUILTIN_NONE:
|
||||
break;
|
||||
case GTK_CSS_IMAGE_BUILTIN_CHECK:
|
||||
case GTK_CSS_IMAGE_BUILTIN_CHECK_INCONSISTENT:
|
||||
gtk_css_image_builtin_draw_check (image, cr,
|
||||
width, height,
|
||||
image_type == GTK_CSS_IMAGE_BUILTIN_CHECK,
|
||||
image_type == GTK_CSS_IMAGE_BUILTIN_CHECK_INCONSISTENT);
|
||||
break;
|
||||
case GTK_CSS_IMAGE_BUILTIN_OPTION:
|
||||
case GTK_CSS_IMAGE_BUILTIN_OPTION_INCONSISTENT:
|
||||
gtk_css_image_builtin_draw_option (image, cr,
|
||||
width, height,
|
||||
image_type == GTK_CSS_IMAGE_BUILTIN_OPTION,
|
||||
image_type == GTK_CSS_IMAGE_BUILTIN_OPTION_INCONSISTENT);
|
||||
break;
|
||||
case GTK_CSS_IMAGE_BUILTIN_ARROW_UP:
|
||||
case GTK_CSS_IMAGE_BUILTIN_ARROW_DOWN:
|
||||
case GTK_CSS_IMAGE_BUILTIN_ARROW_LEFT:
|
||||
case GTK_CSS_IMAGE_BUILTIN_ARROW_RIGHT:
|
||||
gtk_css_image_builtin_draw_arrow (image, cr,
|
||||
width, height,
|
||||
image_type);
|
||||
break;
|
||||
case GTK_CSS_IMAGE_BUILTIN_EXPANDER_HORIZONTAL_LEFT:
|
||||
gtk_css_image_builtin_draw_expander (image, cr,
|
||||
width, height,
|
||||
TRUE, FALSE, FALSE);
|
||||
break;
|
||||
case GTK_CSS_IMAGE_BUILTIN_EXPANDER_VERTICAL_LEFT:
|
||||
gtk_css_image_builtin_draw_expander (image, cr,
|
||||
width, height,
|
||||
FALSE, FALSE, FALSE);
|
||||
break;
|
||||
case GTK_CSS_IMAGE_BUILTIN_EXPANDER_HORIZONTAL_RIGHT:
|
||||
gtk_css_image_builtin_draw_expander (image, cr,
|
||||
width, height,
|
||||
TRUE, TRUE, FALSE);
|
||||
break;
|
||||
case GTK_CSS_IMAGE_BUILTIN_EXPANDER_VERTICAL_RIGHT:
|
||||
gtk_css_image_builtin_draw_expander (image, cr,
|
||||
width, height,
|
||||
FALSE, TRUE, FALSE);
|
||||
break;
|
||||
case GTK_CSS_IMAGE_BUILTIN_EXPANDER_HORIZONTAL_LEFT_EXPANDED:
|
||||
gtk_css_image_builtin_draw_expander (image, cr,
|
||||
width, height,
|
||||
TRUE, FALSE, TRUE);
|
||||
break;
|
||||
case GTK_CSS_IMAGE_BUILTIN_EXPANDER_VERTICAL_LEFT_EXPANDED:
|
||||
gtk_css_image_builtin_draw_expander (image, cr,
|
||||
width, height,
|
||||
FALSE, FALSE, TRUE);
|
||||
break;
|
||||
case GTK_CSS_IMAGE_BUILTIN_EXPANDER_HORIZONTAL_RIGHT_EXPANDED:
|
||||
gtk_css_image_builtin_draw_expander (image, cr,
|
||||
width, height,
|
||||
TRUE, TRUE, TRUE);
|
||||
break;
|
||||
case GTK_CSS_IMAGE_BUILTIN_EXPANDER_VERTICAL_RIGHT_EXPANDED:
|
||||
gtk_css_image_builtin_draw_expander (image, cr,
|
||||
width, height,
|
||||
FALSE, TRUE, TRUE);
|
||||
break;
|
||||
case GTK_CSS_IMAGE_BUILTIN_PANE_SEPARATOR:
|
||||
gtk_css_image_builtin_draw_pane_separator (image, cr,
|
||||
width, height);
|
||||
break;
|
||||
case GTK_CSS_IMAGE_BUILTIN_HANDLE:
|
||||
gtk_css_image_builtin_draw_handle (image, cr,
|
||||
width, height);
|
||||
break;
|
||||
case GTK_CSS_IMAGE_BUILTIN_SPINNER:
|
||||
gtk_css_image_builtin_draw_spinner (image, cr,
|
||||
width, height);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_image_builtin_snapshot (GtkCssImage *image,
|
||||
GtkSnapshot *snapshot,
|
||||
double width,
|
||||
double height,
|
||||
GtkCssImageBuiltinType image_type)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_CSS_IMAGE (image));
|
||||
g_return_if_fail (snapshot != NULL);
|
||||
g_return_if_fail (width > 0);
|
||||
g_return_if_fail (height > 0);
|
||||
|
||||
if (!GTK_IS_CSS_IMAGE_BUILTIN (image))
|
||||
{
|
||||
gtk_css_image_snapshot (image, snapshot, width, height);
|
||||
return;
|
||||
}
|
||||
|
||||
if (image_type != GTK_CSS_IMAGE_BUILTIN_NONE)
|
||||
{
|
||||
cairo_t *cr = gtk_snapshot_append_cairo (snapshot,
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
gtk_css_image_builtin_draw (image, cr, width, height, image_type);
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012 Red Hat Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef __GTK_CSS_IMAGE_BUILTIN_PRIVATE_H__
|
||||
#define __GTK_CSS_IMAGE_BUILTIN_PRIVATE_H__
|
||||
|
||||
#include "gtk/gtkcssimageprivate.h"
|
||||
#include "gtk/gtkicontheme.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_CSS_IMAGE_BUILTIN (gtk_css_image_builtin_get_type ())
|
||||
#define GTK_CSS_IMAGE_BUILTIN(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_IMAGE_BUILTIN, GtkCssImageBuiltin))
|
||||
#define GTK_CSS_IMAGE_BUILTIN_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_IMAGE_BUILTIN, GtkCssImageBuiltinClass))
|
||||
#define GTK_IS_CSS_IMAGE_BUILTIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_IMAGE_BUILTIN))
|
||||
#define GTK_IS_CSS_IMAGE_BUILTIN_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_IMAGE_BUILTIN))
|
||||
#define GTK_CSS_IMAGE_BUILTIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_IMAGE_BUILTIN, GtkCssImageBuiltinClass))
|
||||
|
||||
typedef struct _GtkCssImageBuiltin GtkCssImageBuiltin;
|
||||
typedef struct _GtkCssImageBuiltinClass GtkCssImageBuiltinClass;
|
||||
|
||||
struct _GtkCssImageBuiltin
|
||||
{
|
||||
GtkCssImage parent;
|
||||
|
||||
GdkRGBA fg_color;
|
||||
GdkRGBA bg_color;
|
||||
};
|
||||
|
||||
struct _GtkCssImageBuiltinClass
|
||||
{
|
||||
GtkCssImageClass parent_class;
|
||||
};
|
||||
|
||||
GType gtk_css_image_builtin_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkCssImage * gtk_css_image_builtin_new (void);
|
||||
|
||||
void gtk_css_image_builtin_draw (GtkCssImage *image,
|
||||
cairo_t *cr,
|
||||
double width,
|
||||
double height,
|
||||
GtkCssImageBuiltinType image_type);
|
||||
void gtk_css_image_builtin_snapshot (GtkCssImage *image,
|
||||
GtkSnapshot *snapshot,
|
||||
double width,
|
||||
double height,
|
||||
GtkCssImageBuiltinType image_type);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_IMAGE_BUILTIN_PRIVATE_H__ */
|
||||
+57
-195
@@ -23,6 +23,21 @@
|
||||
#include "gtkcssnodeprivate.h"
|
||||
#include "gtkwidgetpath.h"
|
||||
|
||||
void
|
||||
gtk_css_matcher_print (const GtkCssMatcher *matcher,
|
||||
GString *string)
|
||||
{
|
||||
matcher->klass->print (matcher, string);
|
||||
}
|
||||
|
||||
char *
|
||||
gtk_css_matcher_to_string (const GtkCssMatcher *matcher)
|
||||
{
|
||||
GString *string = g_string_new ("");
|
||||
gtk_css_matcher_print (matcher, string);
|
||||
return g_string_free (string, FALSE);
|
||||
}
|
||||
|
||||
/* GTK_CSS_MATCHER_WIDGET_PATH */
|
||||
|
||||
static gboolean
|
||||
@@ -57,19 +72,26 @@ gtk_css_matcher_widget_path_get_previous (GtkCssMatcher *matcher,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GtkStateFlags
|
||||
gtk_css_matcher_widget_path_get_state (const GtkCssMatcher *matcher)
|
||||
static gboolean
|
||||
gtk_css_matcher_widget_path_has_state (const GtkCssMatcher *matcher,
|
||||
GtkStateFlags state)
|
||||
{
|
||||
const GtkWidgetPath *siblings;
|
||||
GtkStateFlags path_state;
|
||||
|
||||
if (matcher->path.decl)
|
||||
return gtk_css_node_declaration_get_state (matcher->path.decl);
|
||||
|
||||
siblings = gtk_widget_path_iter_get_siblings (matcher->path.path, matcher->path.index);
|
||||
if (siblings && matcher->path.sibling_index != gtk_widget_path_iter_get_sibling_index (matcher->path.path, matcher->path.index))
|
||||
return gtk_widget_path_iter_get_state (siblings, matcher->path.sibling_index);
|
||||
path_state = gtk_css_node_declaration_get_state (matcher->path.decl);
|
||||
else
|
||||
return gtk_widget_path_iter_get_state (matcher->path.path, matcher->path.index);
|
||||
{
|
||||
const GtkWidgetPath *siblings;
|
||||
|
||||
siblings = gtk_widget_path_iter_get_siblings (matcher->path.path, matcher->path.index);
|
||||
if (siblings && matcher->path.sibling_index != gtk_widget_path_iter_get_sibling_index (matcher->path.path, matcher->path.index))
|
||||
path_state = gtk_widget_path_iter_get_state (siblings, matcher->path.sibling_index);
|
||||
else
|
||||
path_state = gtk_widget_path_iter_get_state (matcher->path.path, matcher->path.index);
|
||||
}
|
||||
|
||||
return (path_state & state) == state;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -158,15 +180,25 @@ gtk_css_matcher_widget_path_has_position (const GtkCssMatcher *matcher,
|
||||
return x / a >= 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_matcher_widget_path_print (const GtkCssMatcher *matcher,
|
||||
GString *string)
|
||||
{
|
||||
char *s = gtk_widget_path_to_string (matcher->path.path);
|
||||
g_string_append (string, s);
|
||||
g_free (s);
|
||||
}
|
||||
|
||||
static const GtkCssMatcherClass GTK_CSS_MATCHER_WIDGET_PATH = {
|
||||
GTK_CSS_MATCHER_TYPE_WIDGET_PATH,
|
||||
gtk_css_matcher_widget_path_get_parent,
|
||||
gtk_css_matcher_widget_path_get_previous,
|
||||
gtk_css_matcher_widget_path_get_state,
|
||||
gtk_css_matcher_widget_path_has_state,
|
||||
gtk_css_matcher_widget_path_has_name,
|
||||
gtk_css_matcher_widget_path_has_class,
|
||||
gtk_css_matcher_widget_path_has_id,
|
||||
gtk_css_matcher_widget_path_has_position,
|
||||
FALSE
|
||||
gtk_css_matcher_widget_path_print
|
||||
};
|
||||
|
||||
gboolean
|
||||
@@ -234,10 +266,11 @@ gtk_css_matcher_node_get_previous (GtkCssMatcher *matcher,
|
||||
return gtk_css_node_init_matcher (node, matcher);
|
||||
}
|
||||
|
||||
static GtkStateFlags
|
||||
gtk_css_matcher_node_get_state (const GtkCssMatcher *matcher)
|
||||
static gboolean
|
||||
gtk_css_matcher_node_has_state (const GtkCssMatcher *matcher,
|
||||
GtkStateFlags state)
|
||||
{
|
||||
return matcher->node.node_state;
|
||||
return (matcher->node.node_state & state) == state;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -334,15 +367,23 @@ gtk_css_matcher_node_has_position (const GtkCssMatcher *matcher,
|
||||
a, b);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_matcher_node_print (const GtkCssMatcher *matcher,
|
||||
GString *string)
|
||||
{
|
||||
gtk_css_node_print (matcher->node.node, 0, string, 0);
|
||||
}
|
||||
|
||||
static const GtkCssMatcherClass GTK_CSS_MATCHER_NODE = {
|
||||
GTK_CSS_MATCHER_TYPE_NODE,
|
||||
gtk_css_matcher_node_get_parent,
|
||||
gtk_css_matcher_node_get_previous,
|
||||
gtk_css_matcher_node_get_state,
|
||||
gtk_css_matcher_node_has_state,
|
||||
gtk_css_matcher_node_has_name,
|
||||
gtk_css_matcher_node_has_class,
|
||||
gtk_css_matcher_node_has_id,
|
||||
gtk_css_matcher_node_has_position,
|
||||
FALSE
|
||||
gtk_css_matcher_node_print
|
||||
};
|
||||
|
||||
void
|
||||
@@ -357,182 +398,3 @@ _gtk_css_matcher_node_init (GtkCssMatcher *matcher,
|
||||
matcher->node.classes = gtk_css_node_declaration_get_classes (gtk_css_node_get_declaration (node),
|
||||
&matcher->node.n_classes);
|
||||
}
|
||||
|
||||
/* GTK_CSS_MATCHER_WIDGET_ANY */
|
||||
|
||||
static gboolean
|
||||
gtk_css_matcher_any_get_parent (GtkCssMatcher *matcher,
|
||||
const GtkCssMatcher *child)
|
||||
{
|
||||
_gtk_css_matcher_any_init (matcher);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_matcher_any_get_previous (GtkCssMatcher *matcher,
|
||||
const GtkCssMatcher *next)
|
||||
{
|
||||
_gtk_css_matcher_any_init (matcher);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GtkStateFlags
|
||||
gtk_css_matcher_any_get_state (const GtkCssMatcher *matcher)
|
||||
{
|
||||
/* XXX: This gets tricky when we implement :not() */
|
||||
|
||||
return GTK_STATE_FLAG_ACTIVE | GTK_STATE_FLAG_PRELIGHT | GTK_STATE_FLAG_SELECTED
|
||||
| GTK_STATE_FLAG_INSENSITIVE | GTK_STATE_FLAG_INCONSISTENT
|
||||
| GTK_STATE_FLAG_FOCUSED | GTK_STATE_FLAG_BACKDROP | GTK_STATE_FLAG_LINK
|
||||
| GTK_STATE_FLAG_VISITED;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_matcher_any_has_name (const GtkCssMatcher *matcher,
|
||||
/*interned*/ const char *name)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_matcher_any_has_class (const GtkCssMatcher *matcher,
|
||||
GQuark class_name)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_matcher_any_has_id (const GtkCssMatcher *matcher,
|
||||
const char *id)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_matcher_any_has_position (const GtkCssMatcher *matcher,
|
||||
gboolean forward,
|
||||
int a,
|
||||
int b)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const GtkCssMatcherClass GTK_CSS_MATCHER_ANY = {
|
||||
gtk_css_matcher_any_get_parent,
|
||||
gtk_css_matcher_any_get_previous,
|
||||
gtk_css_matcher_any_get_state,
|
||||
gtk_css_matcher_any_has_name,
|
||||
gtk_css_matcher_any_has_class,
|
||||
gtk_css_matcher_any_has_id,
|
||||
gtk_css_matcher_any_has_position,
|
||||
TRUE
|
||||
};
|
||||
|
||||
void
|
||||
_gtk_css_matcher_any_init (GtkCssMatcher *matcher)
|
||||
{
|
||||
matcher->klass = >K_CSS_MATCHER_ANY;
|
||||
}
|
||||
|
||||
/* GTK_CSS_MATCHER_WIDGET_SUPERSET */
|
||||
|
||||
static gboolean
|
||||
gtk_css_matcher_superset_get_parent (GtkCssMatcher *matcher,
|
||||
const GtkCssMatcher *child)
|
||||
{
|
||||
_gtk_css_matcher_any_init (matcher);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_matcher_superset_get_previous (GtkCssMatcher *matcher,
|
||||
const GtkCssMatcher *next)
|
||||
{
|
||||
_gtk_css_matcher_any_init (matcher);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GtkStateFlags
|
||||
gtk_css_matcher_superset_get_state (const GtkCssMatcher *matcher)
|
||||
{
|
||||
/* XXX: This gets tricky when we implement :not() */
|
||||
|
||||
if (matcher->superset.relevant & GTK_CSS_CHANGE_STATE)
|
||||
return _gtk_css_matcher_get_state (matcher->superset.subset);
|
||||
else
|
||||
return GTK_STATE_FLAG_ACTIVE | GTK_STATE_FLAG_PRELIGHT | GTK_STATE_FLAG_SELECTED
|
||||
| GTK_STATE_FLAG_INSENSITIVE | GTK_STATE_FLAG_INCONSISTENT
|
||||
| GTK_STATE_FLAG_FOCUSED | GTK_STATE_FLAG_BACKDROP | GTK_STATE_FLAG_LINK
|
||||
| GTK_STATE_FLAG_VISITED;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_matcher_superset_has_name (const GtkCssMatcher *matcher,
|
||||
/*interned*/ const char *name)
|
||||
{
|
||||
if (matcher->superset.relevant & GTK_CSS_CHANGE_NAME)
|
||||
return _gtk_css_matcher_has_name (matcher->superset.subset, name);
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_matcher_superset_has_class (const GtkCssMatcher *matcher,
|
||||
GQuark class_name)
|
||||
{
|
||||
if (matcher->superset.relevant & GTK_CSS_CHANGE_CLASS)
|
||||
return _gtk_css_matcher_has_class (matcher->superset.subset, class_name);
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_matcher_superset_has_id (const GtkCssMatcher *matcher,
|
||||
const char *id)
|
||||
{
|
||||
if (matcher->superset.relevant & GTK_CSS_CHANGE_NAME)
|
||||
return _gtk_css_matcher_has_id (matcher->superset.subset, id);
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_matcher_superset_has_position (const GtkCssMatcher *matcher,
|
||||
gboolean forward,
|
||||
int a,
|
||||
int b)
|
||||
{
|
||||
if (matcher->superset.relevant & GTK_CSS_CHANGE_POSITION)
|
||||
return _gtk_css_matcher_has_position (matcher->superset.subset, forward, a, b);
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const GtkCssMatcherClass GTK_CSS_MATCHER_SUPERSET = {
|
||||
gtk_css_matcher_superset_get_parent,
|
||||
gtk_css_matcher_superset_get_previous,
|
||||
gtk_css_matcher_superset_get_state,
|
||||
gtk_css_matcher_superset_has_name,
|
||||
gtk_css_matcher_superset_has_class,
|
||||
gtk_css_matcher_superset_has_id,
|
||||
gtk_css_matcher_superset_has_position,
|
||||
FALSE
|
||||
};
|
||||
|
||||
void
|
||||
_gtk_css_matcher_superset_init (GtkCssMatcher *matcher,
|
||||
const GtkCssMatcher *subset,
|
||||
GtkCssChange relevant)
|
||||
{
|
||||
g_return_if_fail (subset != NULL);
|
||||
g_return_if_fail ((relevant & ~(GTK_CSS_CHANGE_CLASS | GTK_CSS_CHANGE_NAME | GTK_CSS_CHANGE_POSITION | GTK_CSS_CHANGE_STATE)) == 0);
|
||||
|
||||
matcher->superset.klass = >K_CSS_MATCHER_SUPERSET;
|
||||
matcher->superset.subset = subset;
|
||||
matcher->superset.relevant = relevant;
|
||||
}
|
||||
|
||||
|
||||
+18
-23
@@ -29,13 +29,20 @@ typedef struct _GtkCssMatcherSuperset GtkCssMatcherSuperset;
|
||||
typedef struct _GtkCssMatcherWidgetPath GtkCssMatcherWidgetPath;
|
||||
typedef struct _GtkCssMatcherClass GtkCssMatcherClass;
|
||||
|
||||
typedef enum {
|
||||
GTK_CSS_MATCHER_TYPE_NODE,
|
||||
GTK_CSS_MATCHER_TYPE_WIDGET_PATH
|
||||
} GtkCssMatcherType;
|
||||
|
||||
struct _GtkCssMatcherClass {
|
||||
GtkCssMatcherType type;
|
||||
gboolean (* get_parent) (GtkCssMatcher *matcher,
|
||||
const GtkCssMatcher *child);
|
||||
gboolean (* get_previous) (GtkCssMatcher *matcher,
|
||||
const GtkCssMatcher *next);
|
||||
|
||||
GtkStateFlags (* get_state) (const GtkCssMatcher *matcher);
|
||||
gboolean (* has_state) (const GtkCssMatcher *matcher,
|
||||
GtkStateFlags state);
|
||||
gboolean (* has_name) (const GtkCssMatcher *matcher,
|
||||
/*interned*/const char*name);
|
||||
gboolean (* has_class) (const GtkCssMatcher *matcher,
|
||||
@@ -46,7 +53,8 @@ struct _GtkCssMatcherClass {
|
||||
gboolean forward,
|
||||
int a,
|
||||
int b);
|
||||
gboolean is_any;
|
||||
void (* print) (const GtkCssMatcher *matcher,
|
||||
GString *string);
|
||||
};
|
||||
|
||||
struct _GtkCssMatcherWidgetPath {
|
||||
@@ -67,17 +75,10 @@ struct _GtkCssMatcherNode {
|
||||
guint n_classes;
|
||||
};
|
||||
|
||||
struct _GtkCssMatcherSuperset {
|
||||
const GtkCssMatcherClass *klass;
|
||||
const GtkCssMatcher *subset;
|
||||
GtkCssChange relevant;
|
||||
};
|
||||
|
||||
union _GtkCssMatcher {
|
||||
const GtkCssMatcherClass *klass;
|
||||
GtkCssMatcherWidgetPath path;
|
||||
GtkCssMatcherNode node;
|
||||
GtkCssMatcherSuperset superset;
|
||||
};
|
||||
|
||||
gboolean _gtk_css_matcher_init (GtkCssMatcher *matcher,
|
||||
@@ -85,10 +86,10 @@ gboolean _gtk_css_matcher_init (GtkCssMatcher *match
|
||||
const GtkCssNodeDeclaration *decl) G_GNUC_WARN_UNUSED_RESULT;
|
||||
void _gtk_css_matcher_node_init (GtkCssMatcher *matcher,
|
||||
GtkCssNode *node);
|
||||
void _gtk_css_matcher_any_init (GtkCssMatcher *matcher);
|
||||
void _gtk_css_matcher_superset_init (GtkCssMatcher *matcher,
|
||||
const GtkCssMatcher *subset,
|
||||
GtkCssChange relevant);
|
||||
|
||||
void gtk_css_matcher_print (const GtkCssMatcher *matcher,
|
||||
GString *string);
|
||||
char * gtk_css_matcher_to_string (const GtkCssMatcher *matcher);
|
||||
|
||||
|
||||
static inline gboolean
|
||||
@@ -105,10 +106,11 @@ _gtk_css_matcher_get_previous (GtkCssMatcher *matcher,
|
||||
return next->klass->get_previous (matcher, next);
|
||||
}
|
||||
|
||||
static inline GtkStateFlags
|
||||
_gtk_css_matcher_get_state (const GtkCssMatcher *matcher)
|
||||
static inline gboolean
|
||||
_gtk_css_matcher_has_state (const GtkCssMatcher *matcher,
|
||||
GtkStateFlags state)
|
||||
{
|
||||
return matcher->klass->get_state (matcher);
|
||||
return matcher->klass->has_state (matcher, state);
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
@@ -141,13 +143,6 @@ _gtk_css_matcher_has_position (const GtkCssMatcher *matcher,
|
||||
return matcher->klass->has_position (matcher, forward, a, b);
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
_gtk_css_matcher_matches_any (const GtkCssMatcher *matcher)
|
||||
{
|
||||
return matcher->klass->is_any;
|
||||
}
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_MATCHER_PRIVATE_H__ */
|
||||
|
||||
+46
-13
@@ -87,6 +87,11 @@
|
||||
* if we need to change things. */
|
||||
#define GTK_CSS_RADICAL_CHANGE (GTK_CSS_CHANGE_ID | GTK_CSS_CHANGE_NAME | GTK_CSS_CHANGE_CLASS | GTK_CSS_CHANGE_SOURCE | GTK_CSS_CHANGE_PARENT_STYLE)
|
||||
|
||||
/* When these change, we need to recompute the change flags for the new style
|
||||
* since they may have changed.
|
||||
*/
|
||||
#define GTK_CSS_CHANGE_NEEDS_RECOMPUTE (GTK_CSS_RADICAL_CHANGE & ~GTK_CSS_CHANGE_PARENT_STYLE)
|
||||
|
||||
G_DEFINE_TYPE (GtkCssNode, gtk_css_node, G_TYPE_OBJECT)
|
||||
|
||||
enum {
|
||||
@@ -348,12 +353,14 @@ store_in_global_parent_cache (GtkCssNode *node,
|
||||
}
|
||||
|
||||
static GtkCssStyle *
|
||||
gtk_css_node_create_style (GtkCssNode *cssnode)
|
||||
gtk_css_node_create_style (GtkCssNode *cssnode,
|
||||
GtkCssChange change)
|
||||
{
|
||||
const GtkCssNodeDeclaration *decl;
|
||||
GtkCssMatcher matcher;
|
||||
GtkCssStyle *parent;
|
||||
GtkCssStyle *style;
|
||||
GtkCssChange style_change;
|
||||
|
||||
decl = gtk_css_node_get_declaration (cssnode);
|
||||
|
||||
@@ -363,14 +370,26 @@ gtk_css_node_create_style (GtkCssNode *cssnode)
|
||||
|
||||
parent = cssnode->parent ? cssnode->parent->style : NULL;
|
||||
|
||||
if (change & GTK_CSS_CHANGE_NEEDS_RECOMPUTE)
|
||||
{
|
||||
/* Need to recompute the change flags */
|
||||
style_change = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
style_change = gtk_css_static_style_get_change (gtk_css_style_get_static_style (cssnode->style));
|
||||
}
|
||||
|
||||
if (gtk_css_node_init_matcher (cssnode, &matcher))
|
||||
style = gtk_css_static_style_new_compute (gtk_css_node_get_style_provider (cssnode),
|
||||
&matcher,
|
||||
parent);
|
||||
parent,
|
||||
style_change);
|
||||
else
|
||||
style = gtk_css_static_style_new_compute (gtk_css_node_get_style_provider (cssnode),
|
||||
NULL,
|
||||
parent);
|
||||
parent,
|
||||
style_change);
|
||||
|
||||
store_in_global_parent_cache (cssnode, decl, style);
|
||||
|
||||
@@ -407,17 +426,10 @@ gtk_css_node_real_update_style (GtkCssNode *cssnode,
|
||||
{
|
||||
GtkCssStyle *static_style, *new_static_style, *new_style;
|
||||
|
||||
if (GTK_IS_CSS_ANIMATED_STYLE (style))
|
||||
{
|
||||
static_style = GTK_CSS_ANIMATED_STYLE (style)->style;
|
||||
}
|
||||
else
|
||||
{
|
||||
static_style = style;
|
||||
}
|
||||
static_style = GTK_CSS_STYLE (gtk_css_style_get_static_style (style));
|
||||
|
||||
if (gtk_css_style_needs_recreation (static_style, change))
|
||||
new_static_style = gtk_css_node_create_style (cssnode);
|
||||
new_static_style = gtk_css_node_create_style (cssnode, change);
|
||||
else
|
||||
new_static_style = g_object_ref (static_style);
|
||||
|
||||
@@ -1138,9 +1150,30 @@ void
|
||||
gtk_css_node_set_state (GtkCssNode *cssnode,
|
||||
GtkStateFlags state_flags)
|
||||
{
|
||||
GtkStateFlags old_state;
|
||||
|
||||
old_state = gtk_css_node_declaration_get_state (cssnode->decl);
|
||||
|
||||
if (gtk_css_node_declaration_set_state (&cssnode->decl, state_flags))
|
||||
{
|
||||
gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_STATE);
|
||||
GtkStateFlags states = old_state ^ state_flags;
|
||||
GtkCssChange change = 0;
|
||||
|
||||
if (states & GTK_STATE_FLAG_PRELIGHT)
|
||||
change |= GTK_CSS_CHANGE_HOVER;
|
||||
if (states & GTK_STATE_FLAG_INSENSITIVE)
|
||||
change |= GTK_CSS_CHANGE_DISABLED;
|
||||
if (states & GTK_STATE_FLAG_BACKDROP)
|
||||
change |= GTK_CSS_CHANGE_BACKDROP;
|
||||
if (states & GTK_STATE_FLAG_SELECTED)
|
||||
change |= GTK_CSS_CHANGE_SELECTED;
|
||||
if (states & ~(GTK_STATE_FLAG_PRELIGHT |
|
||||
GTK_STATE_FLAG_INSENSITIVE |
|
||||
GTK_STATE_FLAG_BACKDROP |
|
||||
GTK_STATE_FLAG_SELECTED))
|
||||
change |= GTK_CSS_CHANGE_STATE;
|
||||
|
||||
gtk_css_node_invalidate (cssnode, change);
|
||||
g_object_notify_by_pspec (G_OBJECT (cssnode), cssnode_properties[PROP_STATE]);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-88
@@ -99,7 +99,6 @@ struct GtkCssRuleset
|
||||
GtkCssSelector *selector;
|
||||
GtkCssSelectorTree *selector_match;
|
||||
PropertyValue *styles;
|
||||
GtkBitmask *set_styles;
|
||||
guint n_styles;
|
||||
guint owns_styles : 1;
|
||||
};
|
||||
@@ -236,8 +235,6 @@ gtk_css_ruleset_init_copy (GtkCssRuleset *new,
|
||||
/* First copy takes over ownership */
|
||||
if (ruleset->owns_styles)
|
||||
ruleset->owns_styles = FALSE;
|
||||
if (new->set_styles)
|
||||
new->set_styles = _gtk_bitmask_copy (new->set_styles);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -256,8 +253,6 @@ gtk_css_ruleset_clear (GtkCssRuleset *ruleset)
|
||||
}
|
||||
g_free (ruleset->styles);
|
||||
}
|
||||
if (ruleset->set_styles)
|
||||
_gtk_bitmask_free (ruleset->set_styles);
|
||||
if (ruleset->selector)
|
||||
_gtk_css_selector_free (ruleset->selector);
|
||||
|
||||
@@ -274,13 +269,6 @@ gtk_css_ruleset_add (GtkCssRuleset *ruleset,
|
||||
|
||||
g_return_if_fail (ruleset->owns_styles || ruleset->n_styles == 0);
|
||||
|
||||
if (ruleset->set_styles == NULL)
|
||||
ruleset->set_styles = _gtk_bitmask_new ();
|
||||
|
||||
ruleset->set_styles = _gtk_bitmask_set (ruleset->set_styles,
|
||||
_gtk_css_style_property_get_id (property),
|
||||
TRUE);
|
||||
|
||||
ruleset->owns_styles = TRUE;
|
||||
|
||||
for (i = 0; i < ruleset->n_styles; i++)
|
||||
@@ -437,62 +425,6 @@ verify_tree_match_results (GtkCssProvider *provider,
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
verify_tree_get_change_results (GtkCssProvider *provider,
|
||||
const GtkCssMatcher *matcher,
|
||||
GtkCssChange change)
|
||||
{
|
||||
#ifdef VERIFY_TREE
|
||||
{
|
||||
GtkCssProviderPrivate *priv = gtk_css_provider_get_instance_private (provider);
|
||||
GtkCssChange verify_change = 0;
|
||||
GPtrArray *tree_rules;
|
||||
int i;
|
||||
|
||||
tree_rules = _gtk_css_selector_tree_match_all (priv->tree, matcher);
|
||||
if (tree_rules)
|
||||
{
|
||||
verify_tree_match_results (provider, matcher, tree_rules);
|
||||
|
||||
for (i = tree_rules->len - 1; i >= 0; i--)
|
||||
{
|
||||
GtkCssRuleset *ruleset;
|
||||
|
||||
ruleset = tree_rules->pdata[i];
|
||||
|
||||
verify_change |= _gtk_css_selector_get_change (ruleset->selector);
|
||||
}
|
||||
|
||||
g_ptr_array_free (tree_rules, TRUE);
|
||||
}
|
||||
|
||||
if (change != verify_change)
|
||||
{
|
||||
GString *s;
|
||||
|
||||
s = g_string_new ("");
|
||||
g_string_append (s, "expected change ");
|
||||
gtk_css_change_print (verify_change, s);
|
||||
g_string_append (s, ", but it was ");
|
||||
gtk_css_change_print (change, s);
|
||||
if ((change & ~verify_change) != 0)
|
||||
{
|
||||
g_string_append (s, ", unexpectedly set: ");
|
||||
gtk_css_change_print (change & ~verify_change, s);
|
||||
}
|
||||
if ((~change & verify_change) != 0)
|
||||
{
|
||||
g_string_append_printf (s, ", unexpectedly not set: ");
|
||||
gtk_css_change_print (~change & verify_change, s);
|
||||
}
|
||||
g_warning (s->str);
|
||||
g_string_free (s, TRUE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_style_provider_get_color (GtkStyleProvider *provider,
|
||||
const char *name)
|
||||
@@ -563,14 +495,7 @@ gtk_css_style_provider_lookup (GtkStyleProvider *provider,
|
||||
}
|
||||
|
||||
if (change)
|
||||
{
|
||||
GtkCssMatcher change_matcher;
|
||||
|
||||
_gtk_css_matcher_superset_init (&change_matcher, matcher, GTK_CSS_CHANGE_NAME | GTK_CSS_CHANGE_CLASS);
|
||||
|
||||
*change = _gtk_css_selector_tree_get_change_all (priv->tree, &change_matcher);
|
||||
verify_tree_get_change_results (css_provider, &change_matcher, *change);
|
||||
}
|
||||
*change = _gtk_css_selector_tree_get_change_all (priv->tree, matcher);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1059,18 +984,6 @@ gtk_css_provider_postprocess (GtkCssProvider *css_provider)
|
||||
|
||||
priv->tree = _gtk_css_selector_tree_builder_build (builder);
|
||||
_gtk_css_selector_tree_builder_free (builder);
|
||||
|
||||
#ifndef VERIFY_TREE
|
||||
for (i = 0; i < priv->rulesets->len; i++)
|
||||
{
|
||||
GtkCssRuleset *ruleset;
|
||||
|
||||
ruleset = &g_array_index (priv->rulesets, GtkCssRuleset, i);
|
||||
|
||||
_gtk_css_selector_free (ruleset->selector);
|
||||
ruleset->selector = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+78
-29
@@ -62,7 +62,8 @@ struct _GtkCssSelectorClass {
|
||||
int (* compare_one) (const GtkCssSelector *a,
|
||||
const GtkCssSelector *b);
|
||||
|
||||
guint is_simple :1;
|
||||
guint is_simple : 1;
|
||||
guint ignore_for_change : 1;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
@@ -294,11 +295,6 @@ gtk_css_selector_descendant_foreach_matcher (const GtkCssSelector *selector
|
||||
|
||||
if (func (selector, &ancestor, data))
|
||||
return TRUE;
|
||||
|
||||
/* any matchers are dangerous here, as we may loop forever, but
|
||||
we can terminate now as all possible matches have already been added */
|
||||
if (_gtk_css_matcher_matches_any (matcher))
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
@@ -319,7 +315,8 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_DESCENDANT = {
|
||||
gtk_css_selector_default_add_specificity,
|
||||
gtk_css_selector_default_hash_one,
|
||||
gtk_css_selector_default_compare_one,
|
||||
FALSE
|
||||
FALSE,
|
||||
TRUE
|
||||
};
|
||||
|
||||
/* CHILD */
|
||||
@@ -360,7 +357,8 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_CHILD = {
|
||||
gtk_css_selector_default_add_specificity,
|
||||
gtk_css_selector_default_hash_one,
|
||||
gtk_css_selector_default_compare_one,
|
||||
FALSE
|
||||
FALSE,
|
||||
TRUE
|
||||
};
|
||||
|
||||
/* SIBLING */
|
||||
@@ -386,11 +384,6 @@ gtk_css_selector_sibling_foreach_matcher (const GtkCssSelector *selector,
|
||||
|
||||
if (func (selector, matcher, data))
|
||||
return TRUE;
|
||||
|
||||
/* any matchers are dangerous here, as we may loop forever, but
|
||||
we can terminate now as all possible matches have already been added */
|
||||
if (_gtk_css_matcher_matches_any (matcher))
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
@@ -411,7 +404,8 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_SIBLING = {
|
||||
gtk_css_selector_default_add_specificity,
|
||||
gtk_css_selector_default_hash_one,
|
||||
gtk_css_selector_default_compare_one,
|
||||
FALSE
|
||||
FALSE,
|
||||
TRUE
|
||||
};
|
||||
|
||||
/* ADJACENT */
|
||||
@@ -452,7 +446,8 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_ADJACENT = {
|
||||
gtk_css_selector_default_add_specificity,
|
||||
gtk_css_selector_default_hash_one,
|
||||
gtk_css_selector_default_compare_one,
|
||||
FALSE
|
||||
FALSE,
|
||||
TRUE
|
||||
};
|
||||
|
||||
/* SIMPLE SELECTOR DEFINE */
|
||||
@@ -465,7 +460,8 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_ADJACENT = {
|
||||
comp_func, \
|
||||
increase_id_specificity, \
|
||||
increase_class_specificity, \
|
||||
increase_element_specificity) \
|
||||
increase_element_specificity, \
|
||||
ignore_for_change) \
|
||||
static void \
|
||||
gtk_css_selector_ ## n ## _print (const GtkCssSelector *selector, \
|
||||
GString *string) \
|
||||
@@ -524,7 +520,8 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_ ## c = { \
|
||||
gtk_css_selector_ ## n ## _add_specificity, \
|
||||
hash_func, \
|
||||
comp_func, \
|
||||
TRUE \
|
||||
TRUE, \
|
||||
ignore_for_change \
|
||||
};\
|
||||
\
|
||||
static const GtkCssSelectorClass GTK_CSS_SELECTOR_NOT_ ## c = { \
|
||||
@@ -536,7 +533,8 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_NOT_ ## c = { \
|
||||
gtk_css_selector_ ## n ## _add_specificity, \
|
||||
hash_func, \
|
||||
comp_func, \
|
||||
TRUE \
|
||||
TRUE, \
|
||||
ignore_for_change \
|
||||
};
|
||||
|
||||
/* ANY */
|
||||
@@ -559,7 +557,7 @@ match_any (const GtkCssSelector *selector,
|
||||
#define GTK_CSS_CHANGE_ANY 0
|
||||
DEFINE_SIMPLE_SELECTOR(any, ANY, print_any, match_any,
|
||||
gtk_css_selector_default_hash_one, gtk_css_selector_default_compare_one,
|
||||
FALSE, FALSE, FALSE)
|
||||
FALSE, FALSE, FALSE, TRUE)
|
||||
#undef GTK_CSS_CHANGE_ANY
|
||||
|
||||
/* NAME */
|
||||
@@ -592,7 +590,7 @@ comp_name (const GtkCssSelector *a,
|
||||
b->name.name);
|
||||
}
|
||||
|
||||
DEFINE_SIMPLE_SELECTOR(name, NAME, print_name, match_name, hash_name, comp_name, FALSE, FALSE, TRUE)
|
||||
DEFINE_SIMPLE_SELECTOR(name, NAME, print_name, match_name, hash_name, comp_name, FALSE, FALSE, TRUE, FALSE)
|
||||
|
||||
/* CLASS */
|
||||
|
||||
@@ -629,7 +627,7 @@ comp_class (const GtkCssSelector *a,
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_SIMPLE_SELECTOR(class, CLASS, print_class, match_class, hash_class, comp_class, FALSE, TRUE, FALSE)
|
||||
DEFINE_SIMPLE_SELECTOR(class, CLASS, print_class, match_class, hash_class, comp_class, FALSE, TRUE, FALSE, FALSE)
|
||||
|
||||
/* ID */
|
||||
|
||||
@@ -666,7 +664,7 @@ comp_id (const GtkCssSelector *a,
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_SIMPLE_SELECTOR(id, ID, print_id, match_id, hash_id, comp_id, TRUE, FALSE, FALSE)
|
||||
DEFINE_SIMPLE_SELECTOR(id, ID, print_id, match_id, hash_id, comp_id, TRUE, FALSE, FALSE, FALSE)
|
||||
|
||||
const gchar *
|
||||
gtk_css_pseudoclass_name (GtkStateFlags state)
|
||||
@@ -711,7 +709,7 @@ static gboolean
|
||||
match_pseudoclass_state (const GtkCssSelector *selector,
|
||||
const GtkCssMatcher *matcher)
|
||||
{
|
||||
return (_gtk_css_matcher_get_state (matcher) & selector->state.state) == selector->state.state;
|
||||
return _gtk_css_matcher_has_state (matcher, selector->state.state);
|
||||
}
|
||||
|
||||
static guint
|
||||
@@ -728,10 +726,34 @@ comp_pseudoclass_state (const GtkCssSelector *a,
|
||||
return a->state.state - b->state.state;
|
||||
}
|
||||
|
||||
#define GTK_CSS_CHANGE_PSEUDOCLASS_HOVER GTK_CSS_CHANGE_HOVER
|
||||
DEFINE_SIMPLE_SELECTOR(pseudoclass_hover, PSEUDOCLASS_HOVER, print_pseudoclass_state,
|
||||
match_pseudoclass_state, hash_pseudoclass_state, comp_pseudoclass_state,
|
||||
FALSE, TRUE, FALSE, TRUE)
|
||||
#undef GTK_CSS_CHANGE_PSEUDOCLASS_HOVER
|
||||
|
||||
#define GTK_CSS_CHANGE_PSEUDOCLASS_DISABLED GTK_CSS_CHANGE_DISABLED
|
||||
DEFINE_SIMPLE_SELECTOR(pseudoclass_disabled, PSEUDOCLASS_DISABLED, print_pseudoclass_state,
|
||||
match_pseudoclass_state, hash_pseudoclass_state, comp_pseudoclass_state,
|
||||
FALSE, TRUE, FALSE, TRUE)
|
||||
#undef GTK_CSS_CHANGE_PSEUDOCLASS_DISABLED
|
||||
|
||||
#define GTK_CSS_CHANGE_PSEUDOCLASS_BACKDROP GTK_CSS_CHANGE_BACKDROP
|
||||
DEFINE_SIMPLE_SELECTOR(pseudoclass_backdrop, PSEUDOCLASS_BACKDROP, print_pseudoclass_state,
|
||||
match_pseudoclass_state, hash_pseudoclass_state, comp_pseudoclass_state,
|
||||
FALSE, TRUE, FALSE, TRUE)
|
||||
#undef GTK_CSS_CHANGE_PSEUDOCLASS_BACKDROP
|
||||
|
||||
#define GTK_CSS_CHANGE_PSEUDOCLASS_SELECTED GTK_CSS_CHANGE_SELECTED
|
||||
DEFINE_SIMPLE_SELECTOR(pseudoclass_selected, PSEUDOCLASS_SELECTED, print_pseudoclass_state,
|
||||
match_pseudoclass_state, hash_pseudoclass_state, comp_pseudoclass_state,
|
||||
FALSE, TRUE, FALSE, TRUE)
|
||||
#undef GTK_CSS_CHANGE_PSEUDOCLASS_SELECTED
|
||||
|
||||
#define GTK_CSS_CHANGE_PSEUDOCLASS_STATE GTK_CSS_CHANGE_STATE
|
||||
DEFINE_SIMPLE_SELECTOR(pseudoclass_state, PSEUDOCLASS_STATE, print_pseudoclass_state,
|
||||
match_pseudoclass_state, hash_pseudoclass_state, comp_pseudoclass_state,
|
||||
FALSE, TRUE, FALSE)
|
||||
FALSE, TRUE, FALSE, TRUE)
|
||||
#undef GTK_CSS_CHANGE_PSEUDOCLASS_STATE
|
||||
|
||||
/* PSEUDOCLASS FOR POSITION */
|
||||
@@ -885,7 +907,7 @@ change_pseudoclass_position (const GtkCssSelector *selector)
|
||||
#define GTK_CSS_CHANGE_PSEUDOCLASS_POSITION change_pseudoclass_position(selector)
|
||||
DEFINE_SIMPLE_SELECTOR(pseudoclass_position, PSEUDOCLASS_POSITION, print_pseudoclass_position,
|
||||
match_pseudoclass_position, hash_pseudoclass_position, comp_pseudoclass_position,
|
||||
FALSE, TRUE, FALSE)
|
||||
FALSE, TRUE, FALSE, TRUE)
|
||||
#undef GTK_CSS_CHANGE_PSEUDOCLASS_POSITION
|
||||
/* API */
|
||||
|
||||
@@ -1288,9 +1310,26 @@ gtk_css_selector_parse_selector_pseudo_class (GtkCssParser *parser,
|
||||
{
|
||||
if (pseudo_classes[i].state_flag)
|
||||
{
|
||||
selector = gtk_css_selector_new (negate ? >K_CSS_SELECTOR_NOT_PSEUDOCLASS_STATE
|
||||
: >K_CSS_SELECTOR_PSEUDOCLASS_STATE,
|
||||
selector);
|
||||
if (pseudo_classes[i].state_flag == GTK_STATE_FLAG_PRELIGHT)
|
||||
selector = gtk_css_selector_new (negate ? >K_CSS_SELECTOR_NOT_PSEUDOCLASS_HOVER
|
||||
: >K_CSS_SELECTOR_PSEUDOCLASS_HOVER,
|
||||
selector);
|
||||
else if (pseudo_classes[i].state_flag == GTK_STATE_FLAG_INSENSITIVE)
|
||||
selector = gtk_css_selector_new (negate ? >K_CSS_SELECTOR_NOT_PSEUDOCLASS_DISABLED
|
||||
: >K_CSS_SELECTOR_PSEUDOCLASS_DISABLED,
|
||||
selector);
|
||||
else if (pseudo_classes[i].state_flag == GTK_STATE_FLAG_BACKDROP)
|
||||
selector = gtk_css_selector_new (negate ? >K_CSS_SELECTOR_NOT_PSEUDOCLASS_BACKDROP
|
||||
: >K_CSS_SELECTOR_PSEUDOCLASS_BACKDROP,
|
||||
selector);
|
||||
else if (pseudo_classes[i].state_flag == GTK_STATE_FLAG_SELECTED)
|
||||
selector = gtk_css_selector_new (negate ? >K_CSS_SELECTOR_NOT_PSEUDOCLASS_SELECTED
|
||||
: >K_CSS_SELECTOR_PSEUDOCLASS_SELECTED,
|
||||
selector);
|
||||
else
|
||||
selector = gtk_css_selector_new (negate ? >K_CSS_SELECTOR_NOT_PSEUDOCLASS_STATE
|
||||
: >K_CSS_SELECTOR_PSEUDOCLASS_STATE,
|
||||
selector);
|
||||
selector->state.state = pseudo_classes[i].state_flag;
|
||||
}
|
||||
else
|
||||
@@ -1687,6 +1726,16 @@ _gtk_css_selector_matches (const GtkCssSelector *selector,
|
||||
return gtk_css_selector_foreach (selector, matcher, gtk_css_selector_foreach_match, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_selector_match_for_change (const GtkCssSelector *selector,
|
||||
const GtkCssMatcher *matcher)
|
||||
{
|
||||
if (selector->class->ignore_for_change)
|
||||
return TRUE;
|
||||
|
||||
return selector->class->match_one (selector, matcher);
|
||||
}
|
||||
|
||||
/* Computes specificity according to CSS 2.1.
|
||||
* The arguments must be initialized to 0 */
|
||||
static void
|
||||
@@ -1870,7 +1919,7 @@ gtk_css_selector_tree_get_change (const GtkCssSelectorTree *tree,
|
||||
GtkCssChange change = 0;
|
||||
const GtkCssSelectorTree *prev;
|
||||
|
||||
if (!gtk_css_selector_match (&tree->selector, matcher))
|
||||
if (!gtk_css_selector_match_for_change (&tree->selector, matcher))
|
||||
return 0;
|
||||
|
||||
if (!tree->selector.class->is_simple)
|
||||
|
||||
+12
-4
@@ -83,6 +83,12 @@ gtk_css_static_style_dispose (GObject *object)
|
||||
G_OBJECT_CLASS (gtk_css_static_style_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static GtkCssStaticStyle *
|
||||
gtk_css_static_style_get_static_style (GtkCssStyle *style)
|
||||
{
|
||||
return (GtkCssStaticStyle *)style;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_static_style_class_init (GtkCssStaticStyleClass *klass)
|
||||
{
|
||||
@@ -93,6 +99,7 @@ gtk_css_static_style_class_init (GtkCssStaticStyleClass *klass)
|
||||
|
||||
style_class->get_value = gtk_css_static_style_get_value;
|
||||
style_class->get_section = gtk_css_static_style_get_section;
|
||||
style_class->get_static_style = gtk_css_static_style_get_static_style;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -158,7 +165,8 @@ gtk_css_static_style_get_default (void)
|
||||
settings = gtk_settings_get_default ();
|
||||
default_style = gtk_css_static_style_new_compute (GTK_STYLE_PROVIDER (settings),
|
||||
NULL,
|
||||
NULL);
|
||||
NULL,
|
||||
TRUE);
|
||||
g_object_set_data_full (G_OBJECT (settings), I_("gtk-default-style"),
|
||||
default_style, clear_default_style);
|
||||
}
|
||||
@@ -169,11 +177,11 @@ gtk_css_static_style_get_default (void)
|
||||
GtkCssStyle *
|
||||
gtk_css_static_style_new_compute (GtkStyleProvider *provider,
|
||||
const GtkCssMatcher *matcher,
|
||||
GtkCssStyle *parent)
|
||||
GtkCssStyle *parent,
|
||||
GtkCssChange change)
|
||||
{
|
||||
GtkCssStaticStyle *result;
|
||||
GtkCssLookup lookup;
|
||||
GtkCssChange change = GTK_CSS_CHANGE_ANY_SELF | GTK_CSS_CHANGE_ANY_SIBLING | GTK_CSS_CHANGE_ANY_PARENT;
|
||||
|
||||
_gtk_css_lookup_init (&lookup);
|
||||
|
||||
@@ -181,7 +189,7 @@ gtk_css_static_style_new_compute (GtkStyleProvider *provider,
|
||||
gtk_style_provider_lookup (provider,
|
||||
matcher,
|
||||
&lookup,
|
||||
&change);
|
||||
change == 0 ? &change : NULL);
|
||||
|
||||
result = g_object_new (GTK_TYPE_CSS_STATIC_STYLE, NULL);
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@ G_BEGIN_DECLS
|
||||
#define GTK_IS_CSS_STATIC_STYLE_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_STATIC_STYLE))
|
||||
#define GTK_CSS_STATIC_STYLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_STATIC_STYLE, GtkCssStaticStyleClass))
|
||||
|
||||
typedef struct _GtkCssStaticStyle GtkCssStaticStyle;
|
||||
typedef struct _GtkCssStaticStyleClass GtkCssStaticStyleClass;
|
||||
|
||||
struct _GtkCssStaticStyle
|
||||
@@ -55,7 +54,8 @@ GType gtk_css_static_style_get_type (void) G_GNUC_CO
|
||||
GtkCssStyle * gtk_css_static_style_get_default (void);
|
||||
GtkCssStyle * gtk_css_static_style_new_compute (GtkStyleProvider *provider,
|
||||
const GtkCssMatcher *matcher,
|
||||
GtkCssStyle *parent);
|
||||
GtkCssStyle *parent,
|
||||
GtkCssChange change);
|
||||
|
||||
void gtk_css_static_style_compute_value (GtkCssStaticStyle *style,
|
||||
GtkStyleProvider *provider,
|
||||
|
||||
@@ -89,6 +89,14 @@ gtk_css_style_is_static (GtkCssStyle *style)
|
||||
return GTK_CSS_STYLE_GET_CLASS (style)->is_static (style);
|
||||
}
|
||||
|
||||
GtkCssStaticStyle *
|
||||
gtk_css_style_get_static_style (GtkCssStyle *style)
|
||||
{
|
||||
gtk_internal_return_val_if_fail (GTK_IS_CSS_STYLE (style), NULL);
|
||||
|
||||
return GTK_CSS_STYLE_GET_CLASS (style)->get_static_style (style);
|
||||
}
|
||||
|
||||
/*
|
||||
* gtk_css_style_print:
|
||||
* @style: a #GtkCssStyle
|
||||
|
||||
@@ -56,6 +56,8 @@ struct _GtkCssStyleClass
|
||||
guint id);
|
||||
/* TRUE if this style will require changes based on timestamp */
|
||||
gboolean (* is_static) (GtkCssStyle *style);
|
||||
|
||||
GtkCssStaticStyle * (* get_static_style) (GtkCssStyle *style);
|
||||
};
|
||||
|
||||
GType gtk_css_style_get_type (void) G_GNUC_CONST;
|
||||
@@ -74,6 +76,7 @@ gboolean gtk_css_style_print (GtkCssStyle
|
||||
PangoAttrList * gtk_css_style_get_pango_attributes (GtkCssStyle *style);
|
||||
|
||||
PangoFontDescription * gtk_css_style_get_pango_font (GtkCssStyle *style);
|
||||
GtkCssStaticStyle * gtk_css_style_get_static_style (GtkCssStyle *style);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -372,33 +372,3 @@ _gtk_css_style_property_get_initial_value (GtkCssStyleProperty *property)
|
||||
|
||||
return property->initial_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_css_style_property_get_mask_affecting:
|
||||
* @flags: the flags that are affected
|
||||
*
|
||||
* Computes a bitmask for all properties that have at least one of @flags
|
||||
* set.
|
||||
*
|
||||
* Returns: (transfer full): A #GtkBitmask with the bit set for every
|
||||
* property that has at least one of @flags set.
|
||||
*/
|
||||
GtkBitmask *
|
||||
_gtk_css_style_property_get_mask_affecting (GtkCssAffects affects)
|
||||
{
|
||||
GtkBitmask *result;
|
||||
guint i;
|
||||
|
||||
result = _gtk_bitmask_new ();
|
||||
|
||||
for (i = 0; i < _gtk_css_style_property_get_n_properties (); i++)
|
||||
{
|
||||
GtkCssStyleProperty *prop = _gtk_css_style_property_lookup_by_id (i);
|
||||
|
||||
if (_gtk_css_style_property_get_affects (prop) & affects)
|
||||
result = _gtk_bitmask_set (result, i, TRUE);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,6 @@
|
||||
#include "gtkcssfontfeaturesvalueprivate.h"
|
||||
#include "gtkcssiconthemevalueprivate.h"
|
||||
#include "gtkcssimageprivate.h"
|
||||
#include "gtkcssimagebuiltinprivate.h"
|
||||
#include "gtkcssimagevalueprivate.h"
|
||||
#include "gtkcssinitialvalueprivate.h"
|
||||
#include "gtkcssenumvalueprivate.h"
|
||||
@@ -677,16 +676,6 @@ css_image_value_parse (GtkCssStyleProperty *property,
|
||||
return _gtk_css_image_value_new (image);
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
css_image_value_parse_with_builtin (GtkCssStyleProperty *property,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
if (gtk_css_parser_try_ident (parser, "builtin"))
|
||||
return _gtk_css_image_value_new (gtk_css_image_builtin_new ());
|
||||
|
||||
return css_image_value_parse (property, parser);
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
background_image_value_parse_one (GtkCssParser *parser)
|
||||
{
|
||||
@@ -1512,9 +1501,9 @@ _gtk_css_style_property_init_properties (void)
|
||||
G_TYPE_NONE,
|
||||
GTK_STYLE_PROPERTY_ANIMATED,
|
||||
GTK_CSS_AFFECTS_ICON | GTK_CSS_AFFECTS_SYMBOLIC_ICON,
|
||||
css_image_value_parse_with_builtin,
|
||||
css_image_value_parse,
|
||||
NULL,
|
||||
_gtk_css_image_value_new (gtk_css_image_builtin_new ()));
|
||||
_gtk_css_image_value_new (NULL));
|
||||
gtk_css_style_property_register ("-gtk-icon-size",
|
||||
GTK_CSS_PROPERTY_ICON_SIZE,
|
||||
G_TYPE_NONE,
|
||||
|
||||
@@ -80,9 +80,6 @@ void _gtk_css_style_property_print_value (GtkCssStyleProp
|
||||
GtkCssValue *value,
|
||||
GString *string);
|
||||
|
||||
GtkBitmask * _gtk_css_style_property_get_mask_affecting
|
||||
(GtkCssAffects affects);
|
||||
|
||||
/* XXX - find a better place for these */
|
||||
GtkCssValue * gtk_css_font_family_value_parse (GtkCssParser *parser);
|
||||
GtkCssValue * gtk_css_font_size_value_parse (GtkCssParser *parser);
|
||||
|
||||
+38
-9
@@ -74,19 +74,20 @@ _gtk_css_change_for_sibling (GtkCssChange match)
|
||||
| GTK_CSS_CHANGE_LAST_CHILD \
|
||||
| GTK_CSS_CHANGE_NTH_CHILD \
|
||||
| GTK_CSS_CHANGE_NTH_LAST_CHILD \
|
||||
| GTK_CSS_CHANGE_STATE )
|
||||
| GTK_CSS_CHANGE_STATE \
|
||||
| GTK_CSS_CHANGE_HOVER \
|
||||
| GTK_CSS_CHANGE_DISABLED \
|
||||
| GTK_CSS_CHANGE_SELECTED \
|
||||
| GTK_CSS_CHANGE_BACKDROP)
|
||||
|
||||
#define KEEP_STATES ( ~(BASE_STATES|GTK_CSS_CHANGE_SOURCE|GTK_CSS_CHANGE_PARENT_STYLE) \
|
||||
| GTK_CSS_CHANGE_NTH_CHILD \
|
||||
| GTK_CSS_CHANGE_NTH_LAST_CHILD)
|
||||
|
||||
#define SIBLING_SHIFT 8
|
||||
|
||||
return (match & KEEP_STATES) | ((match & BASE_STATES) << SIBLING_SHIFT);
|
||||
return (match & KEEP_STATES) | ((match & BASE_STATES) << GTK_CSS_CHANGE_SIBLING_SHIFT);
|
||||
|
||||
#undef BASE_STATES
|
||||
#undef KEEP_STATES
|
||||
#undef SIBLING_SHIFT
|
||||
}
|
||||
|
||||
GtkCssChange
|
||||
@@ -100,6 +101,10 @@ _gtk_css_change_for_child (GtkCssChange match)
|
||||
| GTK_CSS_CHANGE_NTH_CHILD \
|
||||
| GTK_CSS_CHANGE_NTH_LAST_CHILD \
|
||||
| GTK_CSS_CHANGE_STATE \
|
||||
| GTK_CSS_CHANGE_HOVER \
|
||||
| GTK_CSS_CHANGE_DISABLED \
|
||||
| GTK_CSS_CHANGE_BACKDROP \
|
||||
| GTK_CSS_CHANGE_SELECTED \
|
||||
| GTK_CSS_CHANGE_SIBLING_CLASS \
|
||||
| GTK_CSS_CHANGE_SIBLING_NAME \
|
||||
| GTK_CSS_CHANGE_SIBLING_ID \
|
||||
@@ -107,14 +112,18 @@ _gtk_css_change_for_child (GtkCssChange match)
|
||||
| GTK_CSS_CHANGE_SIBLING_LAST_CHILD \
|
||||
| GTK_CSS_CHANGE_SIBLING_NTH_CHILD \
|
||||
| GTK_CSS_CHANGE_SIBLING_NTH_LAST_CHILD \
|
||||
| GTK_CSS_CHANGE_SIBLING_STATE )
|
||||
| GTK_CSS_CHANGE_SIBLING_STATE \
|
||||
| GTK_CSS_CHANGE_SIBLING_HOVER \
|
||||
| GTK_CSS_CHANGE_SIBLING_DISABLED \
|
||||
| GTK_CSS_CHANGE_SIBLING_BACKDROP \
|
||||
| GTK_CSS_CHANGE_SIBLING_SELECTED)
|
||||
|
||||
#define PARENT_SHIFT 16
|
||||
#define KEEP_STATES (~(BASE_STATES|GTK_CSS_CHANGE_SOURCE|GTK_CSS_CHANGE_PARENT_STYLE))
|
||||
|
||||
return (match & ~(BASE_STATES|GTK_CSS_CHANGE_SOURCE|GTK_CSS_CHANGE_PARENT_STYLE)) | ((match & BASE_STATES) << PARENT_SHIFT);
|
||||
return (match & KEEP_STATES) | ((match & BASE_STATES) << GTK_CSS_CHANGE_PARENT_SHIFT);
|
||||
|
||||
#undef BASE_STATES
|
||||
#undef PARENT_SHIFT
|
||||
#undef KEEP_STATES
|
||||
}
|
||||
|
||||
void
|
||||
@@ -133,6 +142,11 @@ gtk_css_change_print (GtkCssChange change,
|
||||
{ GTK_CSS_CHANGE_NTH_CHILD, "nth-child" },
|
||||
{ GTK_CSS_CHANGE_NTH_LAST_CHILD, "nth-last-child" },
|
||||
{ GTK_CSS_CHANGE_STATE, "state" },
|
||||
{ GTK_CSS_CHANGE_HOVER, "hover" },
|
||||
{ GTK_CSS_CHANGE_DISABLED, "disabled" },
|
||||
{ GTK_CSS_CHANGE_BACKDROP, "backdrop" },
|
||||
{ GTK_CSS_CHANGE_SELECTED, "selected" },
|
||||
|
||||
{ GTK_CSS_CHANGE_SIBLING_CLASS, "sibling-class" },
|
||||
{ GTK_CSS_CHANGE_SIBLING_NAME, "sibling-name" },
|
||||
{ GTK_CSS_CHANGE_SIBLING_ID, "sibling-id" },
|
||||
@@ -141,6 +155,11 @@ gtk_css_change_print (GtkCssChange change,
|
||||
{ GTK_CSS_CHANGE_SIBLING_NTH_CHILD, "sibling-nth-child" },
|
||||
{ GTK_CSS_CHANGE_SIBLING_NTH_LAST_CHILD, "sibling-nth-last-child" },
|
||||
{ GTK_CSS_CHANGE_SIBLING_STATE, "sibling-state" },
|
||||
{ GTK_CSS_CHANGE_SIBLING_HOVER, "sibling-hover" },
|
||||
{ GTK_CSS_CHANGE_SIBLING_DISABLED, "sibling-disabled" },
|
||||
{ GTK_CSS_CHANGE_SIBLING_BACKDROP, "sibling-backdrop" },
|
||||
{ GTK_CSS_CHANGE_SIBLING_SELECTED, "sibling-selected" },
|
||||
|
||||
{ GTK_CSS_CHANGE_PARENT_CLASS, "parent-class" },
|
||||
{ GTK_CSS_CHANGE_PARENT_NAME, "parent-name" },
|
||||
{ GTK_CSS_CHANGE_PARENT_ID, "parent-id" },
|
||||
@@ -149,6 +168,11 @@ gtk_css_change_print (GtkCssChange change,
|
||||
{ GTK_CSS_CHANGE_PARENT_NTH_CHILD, "parent-nth-child" },
|
||||
{ GTK_CSS_CHANGE_PARENT_NTH_LAST_CHILD, "parent-nth-last-child" },
|
||||
{ GTK_CSS_CHANGE_PARENT_STATE, "parent-state" },
|
||||
{ GTK_CSS_CHANGE_PARENT_HOVER, "parent-hover" },
|
||||
{ GTK_CSS_CHANGE_PARENT_DISABLED, "parent-disabled" },
|
||||
{ GTK_CSS_CHANGE_PARENT_BACKDROP, "parent-backdrop" },
|
||||
{ GTK_CSS_CHANGE_PARENT_SELECTED, "parent-selected" },
|
||||
|
||||
{ GTK_CSS_CHANGE_PARENT_SIBLING_CLASS, "parent-sibling-" },
|
||||
{ GTK_CSS_CHANGE_PARENT_SIBLING_NAME, "parent-sibling-name" },
|
||||
{ GTK_CSS_CHANGE_PARENT_SIBLING_ID, "parent-sibling-id" },
|
||||
@@ -157,6 +181,11 @@ gtk_css_change_print (GtkCssChange change,
|
||||
{ GTK_CSS_CHANGE_PARENT_SIBLING_NTH_CHILD, "parent-sibling-nth-child" },
|
||||
{ GTK_CSS_CHANGE_PARENT_SIBLING_NTH_LAST_CHILD, "parent-sibling-nth-last-child" },
|
||||
{ GTK_CSS_CHANGE_PARENT_SIBLING_STATE, "parent-sibling-state" },
|
||||
{ GTK_CSS_CHANGE_PARENT_SIBLING_HOVER, "parent-sibling-hover" },
|
||||
{ GTK_CSS_CHANGE_PARENT_SIBLING_DISABLED, "parent-sibling-disabled" },
|
||||
{ GTK_CSS_CHANGE_PARENT_SIBLING_BACKDROP, "parent-sibling-backdrop" },
|
||||
{ GTK_CSS_CHANGE_PARENT_SIBLING_SELECTED, "parent-sibling-selected" },
|
||||
|
||||
{ GTK_CSS_CHANGE_SOURCE, "source" },
|
||||
{ GTK_CSS_CHANGE_PARENT_STYLE, "parent-style" },
|
||||
{ GTK_CSS_CHANGE_TIMESTAMP, "timestamp" },
|
||||
|
||||
+80
-70
@@ -27,6 +27,7 @@ typedef union _GtkCssMatcher GtkCssMatcher;
|
||||
typedef struct _GtkCssNode GtkCssNode;
|
||||
typedef struct _GtkCssNodeDeclaration GtkCssNodeDeclaration;
|
||||
typedef struct _GtkCssStyle GtkCssStyle;
|
||||
typedef struct _GtkCssStaticStyle GtkCssStaticStyle;
|
||||
|
||||
#define GTK_CSS_CHANGE_CLASS (1ULL << 0)
|
||||
#define GTK_CSS_CHANGE_NAME (1ULL << 1)
|
||||
@@ -36,61 +37,93 @@ typedef struct _GtkCssStyle GtkCssStyle;
|
||||
#define GTK_CSS_CHANGE_NTH_CHILD (1ULL << 5)
|
||||
#define GTK_CSS_CHANGE_NTH_LAST_CHILD (1ULL << 6)
|
||||
#define GTK_CSS_CHANGE_STATE (1ULL << 7)
|
||||
#define GTK_CSS_CHANGE_SIBLING_CLASS (1ULL << 8)
|
||||
#define GTK_CSS_CHANGE_SIBLING_NAME (1ULL << 9)
|
||||
#define GTK_CSS_CHANGE_SIBLING_ID (1ULL << 10)
|
||||
#define GTK_CSS_CHANGE_SIBLING_FIRST_CHILD (1ULL << 11)
|
||||
#define GTK_CSS_CHANGE_SIBLING_LAST_CHILD (1ULL << 12)
|
||||
#define GTK_CSS_CHANGE_SIBLING_NTH_CHILD (1ULL << 13)
|
||||
#define GTK_CSS_CHANGE_SIBLING_NTH_LAST_CHILD (1ULL << 14)
|
||||
#define GTK_CSS_CHANGE_SIBLING_STATE (1ULL << 15)
|
||||
#define GTK_CSS_CHANGE_PARENT_CLASS (1ULL << 16)
|
||||
#define GTK_CSS_CHANGE_PARENT_NAME (1ULL << 17)
|
||||
#define GTK_CSS_CHANGE_PARENT_ID (1ULL << 18)
|
||||
#define GTK_CSS_CHANGE_PARENT_FIRST_CHILD (1ULL << 19)
|
||||
#define GTK_CSS_CHANGE_PARENT_LAST_CHILD (1ULL << 20)
|
||||
#define GTK_CSS_CHANGE_PARENT_NTH_CHILD (1ULL << 21)
|
||||
#define GTK_CSS_CHANGE_PARENT_NTH_LAST_CHILD (1ULL << 22)
|
||||
#define GTK_CSS_CHANGE_PARENT_STATE (1ULL << 23)
|
||||
#define GTK_CSS_CHANGE_PARENT_SIBLING_CLASS (1ULL << 24)
|
||||
#define GTK_CSS_CHANGE_PARENT_SIBLING_ID (1ULL << 25)
|
||||
#define GTK_CSS_CHANGE_PARENT_SIBLING_NAME (1ULL << 26)
|
||||
#define GTK_CSS_CHANGE_PARENT_SIBLING_FIRST_CHILD (1ULL << 27)
|
||||
#define GTK_CSS_CHANGE_PARENT_SIBLING_LAST_CHILD (1ULL << 28)
|
||||
#define GTK_CSS_CHANGE_PARENT_SIBLING_NTH_CHILD (1ULL << 29)
|
||||
#define GTK_CSS_CHANGE_PARENT_SIBLING_NTH_LAST_CHILD (1ULL << 30)
|
||||
#define GTK_CSS_CHANGE_PARENT_SIBLING_STATE (1ULL << 31)
|
||||
#define GTK_CSS_CHANGE_HOVER (1ULL << 8)
|
||||
#define GTK_CSS_CHANGE_DISABLED (1ULL << 9)
|
||||
#define GTK_CSS_CHANGE_BACKDROP (1ULL << 10)
|
||||
#define GTK_CSS_CHANGE_SELECTED (1ULL << 11)
|
||||
|
||||
#define GTK_CSS_CHANGE_SIBLING_SHIFT 12
|
||||
|
||||
#define GTK_CSS_CHANGE_SIBLING_CLASS (1ULL << 12)
|
||||
#define GTK_CSS_CHANGE_SIBLING_NAME (1ULL << 13)
|
||||
#define GTK_CSS_CHANGE_SIBLING_ID (1ULL << 14)
|
||||
#define GTK_CSS_CHANGE_SIBLING_FIRST_CHILD (1ULL << 15)
|
||||
#define GTK_CSS_CHANGE_SIBLING_LAST_CHILD (1ULL << 16)
|
||||
#define GTK_CSS_CHANGE_SIBLING_NTH_CHILD (1ULL << 17)
|
||||
#define GTK_CSS_CHANGE_SIBLING_NTH_LAST_CHILD (1ULL << 18)
|
||||
#define GTK_CSS_CHANGE_SIBLING_STATE (1ULL << 19)
|
||||
#define GTK_CSS_CHANGE_SIBLING_HOVER (1ULL << 20)
|
||||
#define GTK_CSS_CHANGE_SIBLING_DISABLED (1ULL << 21)
|
||||
#define GTK_CSS_CHANGE_SIBLING_BACKDROP (1ULL << 22)
|
||||
#define GTK_CSS_CHANGE_SIBLING_SELECTED (1ULL << 23)
|
||||
|
||||
#define GTK_CSS_CHANGE_PARENT_SHIFT (GTK_CSS_CHANGE_SIBLING_SHIFT + GTK_CSS_CHANGE_SIBLING_SHIFT)
|
||||
|
||||
#define GTK_CSS_CHANGE_PARENT_CLASS (1ULL << 24)
|
||||
#define GTK_CSS_CHANGE_PARENT_NAME (1ULL << 25)
|
||||
#define GTK_CSS_CHANGE_PARENT_ID (1ULL << 26)
|
||||
#define GTK_CSS_CHANGE_PARENT_FIRST_CHILD (1ULL << 27)
|
||||
#define GTK_CSS_CHANGE_PARENT_LAST_CHILD (1ULL << 28)
|
||||
#define GTK_CSS_CHANGE_PARENT_NTH_CHILD (1ULL << 29)
|
||||
#define GTK_CSS_CHANGE_PARENT_NTH_LAST_CHILD (1ULL << 30)
|
||||
#define GTK_CSS_CHANGE_PARENT_STATE (1ULL << 31)
|
||||
#define GTK_CSS_CHANGE_PARENT_HOVER (1ULL << 32)
|
||||
#define GTK_CSS_CHANGE_PARENT_DISABLED (1ULL << 33)
|
||||
#define GTK_CSS_CHANGE_PARENT_BACKDROP (1ULL << 34)
|
||||
#define GTK_CSS_CHANGE_PARENT_SELECTED (1ULL << 35)
|
||||
|
||||
#define GTK_CSS_CHANGE_PARENT_SIBLING_SHIFT (GTK_CSS_CHANGE_PARENT_SHIFT + GTK_CSS_CHANGE_SIBLING_SHIFT)
|
||||
|
||||
#define GTK_CSS_CHANGE_PARENT_SIBLING_CLASS (1ULL << 36)
|
||||
#define GTK_CSS_CHANGE_PARENT_SIBLING_ID (1ULL << 37)
|
||||
#define GTK_CSS_CHANGE_PARENT_SIBLING_NAME (1ULL << 38)
|
||||
#define GTK_CSS_CHANGE_PARENT_SIBLING_FIRST_CHILD (1ULL << 39)
|
||||
#define GTK_CSS_CHANGE_PARENT_SIBLING_LAST_CHILD (1ULL << 40)
|
||||
#define GTK_CSS_CHANGE_PARENT_SIBLING_NTH_CHILD (1ULL << 41)
|
||||
#define GTK_CSS_CHANGE_PARENT_SIBLING_NTH_LAST_CHILD (1ULL << 42)
|
||||
#define GTK_CSS_CHANGE_PARENT_SIBLING_STATE (1ULL << 43)
|
||||
#define GTK_CSS_CHANGE_PARENT_SIBLING_HOVER (1ULL << 44)
|
||||
#define GTK_CSS_CHANGE_PARENT_SIBLING_DISABLED (1ULL << 45)
|
||||
#define GTK_CSS_CHANGE_PARENT_SIBLING_BACKDROP (1ULL << 46)
|
||||
#define GTK_CSS_CHANGE_PARENT_SIBLING_SELECTED (1ULL << 47)
|
||||
|
||||
/* add more */
|
||||
#define GTK_CSS_CHANGE_SOURCE (1ULL << 32)
|
||||
#define GTK_CSS_CHANGE_PARENT_STYLE (1ULL << 33)
|
||||
#define GTK_CSS_CHANGE_TIMESTAMP (1ULL << 34)
|
||||
#define GTK_CSS_CHANGE_ANIMATIONS (1ULL << 35)
|
||||
#define GTK_CSS_CHANGE_SOURCE (1ULL << 48)
|
||||
#define GTK_CSS_CHANGE_PARENT_STYLE (1ULL << 49)
|
||||
#define GTK_CSS_CHANGE_TIMESTAMP (1ULL << 50)
|
||||
#define GTK_CSS_CHANGE_ANIMATIONS (1ULL << 51)
|
||||
|
||||
#define GTK_CSS_CHANGE_RESERVED_BIT (1ULL << 62) /* Used internally in gtkcssselector.c */
|
||||
#define GTK_CSS_CHANGE_RESERVED_BIT (1ULL << 62)
|
||||
|
||||
typedef guint64 GtkCssChange;
|
||||
|
||||
#define GTK_CSS_CHANGE_POSITION (GTK_CSS_CHANGE_FIRST_CHILD | GTK_CSS_CHANGE_LAST_CHILD | \
|
||||
GTK_CSS_CHANGE_NTH_CHILD | GTK_CSS_CHANGE_NTH_LAST_CHILD)
|
||||
#define GTK_CSS_CHANGE_SIBLING_POSITION (GTK_CSS_CHANGE_SIBLING_FIRST_CHILD | GTK_CSS_CHANGE_SIBLING_LAST_CHILD | \
|
||||
GTK_CSS_CHANGE_SIBLING_NTH_CHILD | GTK_CSS_CHANGE_SIBLING_NTH_LAST_CHILD)
|
||||
#define GTK_CSS_CHANGE_PARENT_POSITION (GTK_CSS_CHANGE_PARENT_FIRST_CHILD | GTK_CSS_CHANGE_PARENT_LAST_CHILD | \
|
||||
GTK_CSS_CHANGE_PARENT_NTH_CHILD | GTK_CSS_CHANGE_PARENT_NTH_LAST_CHILD)
|
||||
#define GTK_CSS_CHANGE_PARENT_SIBLING_POSITION (GTK_CSS_CHANGE_PARENT_SIBLING_FIRST_CHILD | GTK_CSS_CHANGE_PARENT_SIBLING_LAST_CHILD | \
|
||||
GTK_CSS_CHANGE_PARENT_SIBLING_NTH_CHILD | GTK_CSS_CHANGE_PARENT_SIBLING_NTH_LAST_CHILD)
|
||||
#define GTK_CSS_CHANGE_POSITION (GTK_CSS_CHANGE_FIRST_CHILD | \
|
||||
GTK_CSS_CHANGE_LAST_CHILD | \
|
||||
GTK_CSS_CHANGE_NTH_CHILD | \
|
||||
GTK_CSS_CHANGE_NTH_LAST_CHILD)
|
||||
#define GTK_CSS_CHANGE_SIBLING_POSITION (GTK_CSS_CHANGE_POSITION << GTK_CSS_CHANGE_SIBLING_SHIFT)
|
||||
|
||||
#define GTK_CSS_CHANGE_ANY_SELF (GTK_CSS_CHANGE_CLASS | \
|
||||
GTK_CSS_CHANGE_NAME | \
|
||||
GTK_CSS_CHANGE_ID | \
|
||||
GTK_CSS_CHANGE_POSITION | \
|
||||
GTK_CSS_CHANGE_STATE | \
|
||||
GTK_CSS_CHANGE_DISABLED | \
|
||||
GTK_CSS_CHANGE_BACKDROP | \
|
||||
GTK_CSS_CHANGE_SELECTED | \
|
||||
GTK_CSS_CHANGE_HOVER)
|
||||
#define GTK_CSS_CHANGE_ANY_SIBLING (GTK_CSS_CHANGE_ANY_SELF << GTK_CSS_CHANGE_SIBLING_SHIFT)
|
||||
#define GTK_CSS_CHANGE_ANY_PARENT (GTK_CSS_CHANGE_ANY_SELF << GTK_CSS_CHANGE_PARENT_SHIFT)
|
||||
#define GTK_CSS_CHANGE_ANY_PARENT_SIBLING (GTK_CSS_CHANGE_ANY_SELF << GTK_CSS_CHANGE_PARENT_SIBLING_SHIFT)
|
||||
|
||||
#define GTK_CSS_CHANGE_ANY ((1 << 19) - 1)
|
||||
#define GTK_CSS_CHANGE_ANY_SELF (GTK_CSS_CHANGE_CLASS | GTK_CSS_CHANGE_NAME | GTK_CSS_CHANGE_ID | GTK_CSS_CHANGE_POSITION | GTK_CSS_CHANGE_STATE)
|
||||
#define GTK_CSS_CHANGE_ANY_SIBLING (GTK_CSS_CHANGE_SIBLING_CLASS | GTK_CSS_CHANGE_SIBLING_NAME | \
|
||||
GTK_CSS_CHANGE_SIBLING_ID | \
|
||||
GTK_CSS_CHANGE_SIBLING_POSITION | GTK_CSS_CHANGE_SIBLING_STATE)
|
||||
#define GTK_CSS_CHANGE_ANY_PARENT (GTK_CSS_CHANGE_PARENT_CLASS | GTK_CSS_CHANGE_PARENT_SIBLING_CLASS | \
|
||||
GTK_CSS_CHANGE_PARENT_NAME | GTK_CSS_CHANGE_PARENT_SIBLING_NAME | \
|
||||
GTK_CSS_CHANGE_PARENT_ID | GTK_CSS_CHANGE_PARENT_SIBLING_ID | \
|
||||
GTK_CSS_CHANGE_PARENT_POSITION | GTK_CSS_CHANGE_PARENT_SIBLING_POSITION | \
|
||||
GTK_CSS_CHANGE_PARENT_STATE | GTK_CSS_CHANGE_PARENT_SIBLING_STATE)
|
||||
#define GTK_CSS_CHANGE_ANY (GTK_CSS_CHANGE_ANY_SELF | \
|
||||
GTK_CSS_CHANGE_ANY_SIBLING | \
|
||||
GTK_CSS_CHANGE_ANY_PARENT | \
|
||||
GTK_CSS_CHANGE_ANY_PARENT_SIBLING | \
|
||||
GTK_CSS_CHANGE_SOURCE | \
|
||||
GTK_CSS_CHANGE_PARENT_STYLE | \
|
||||
GTK_CSS_CHANGE_TIMESTAMP | \
|
||||
GTK_CSS_CHANGE_ANIMATIONS)
|
||||
|
||||
/*
|
||||
* GtkCssAffects:
|
||||
@@ -247,29 +280,6 @@ enum { /*< skip >*/
|
||||
GTK_CSS_PROPERTY_N_PROPERTIES
|
||||
};
|
||||
|
||||
typedef enum /*< skip >*/ {
|
||||
GTK_CSS_IMAGE_BUILTIN_NONE,
|
||||
GTK_CSS_IMAGE_BUILTIN_CHECK,
|
||||
GTK_CSS_IMAGE_BUILTIN_CHECK_INCONSISTENT,
|
||||
GTK_CSS_IMAGE_BUILTIN_OPTION,
|
||||
GTK_CSS_IMAGE_BUILTIN_OPTION_INCONSISTENT,
|
||||
GTK_CSS_IMAGE_BUILTIN_ARROW_UP,
|
||||
GTK_CSS_IMAGE_BUILTIN_ARROW_DOWN,
|
||||
GTK_CSS_IMAGE_BUILTIN_ARROW_LEFT,
|
||||
GTK_CSS_IMAGE_BUILTIN_ARROW_RIGHT,
|
||||
GTK_CSS_IMAGE_BUILTIN_EXPANDER_HORIZONTAL_LEFT,
|
||||
GTK_CSS_IMAGE_BUILTIN_EXPANDER_VERTICAL_LEFT,
|
||||
GTK_CSS_IMAGE_BUILTIN_EXPANDER_HORIZONTAL_RIGHT,
|
||||
GTK_CSS_IMAGE_BUILTIN_EXPANDER_VERTICAL_RIGHT,
|
||||
GTK_CSS_IMAGE_BUILTIN_EXPANDER_HORIZONTAL_LEFT_EXPANDED,
|
||||
GTK_CSS_IMAGE_BUILTIN_EXPANDER_VERTICAL_LEFT_EXPANDED,
|
||||
GTK_CSS_IMAGE_BUILTIN_EXPANDER_HORIZONTAL_RIGHT_EXPANDED,
|
||||
GTK_CSS_IMAGE_BUILTIN_EXPANDER_VERTICAL_RIGHT_EXPANDED,
|
||||
GTK_CSS_IMAGE_BUILTIN_PANE_SEPARATOR,
|
||||
GTK_CSS_IMAGE_BUILTIN_HANDLE,
|
||||
GTK_CSS_IMAGE_BUILTIN_SPINNER
|
||||
} GtkCssImageBuiltinType;
|
||||
|
||||
typedef enum /*< skip >*/ {
|
||||
GTK_CSS_AREA_BORDER_BOX,
|
||||
GTK_CSS_AREA_PADDING_BOX,
|
||||
|
||||
-1425
File diff suppressed because it is too large
Load Diff
-102
@@ -1,102 +0,0 @@
|
||||
/* -*- Mode: C; c-file-style: "gnu"; tab-width: 8 -*- */
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_DND_H__
|
||||
#define __GTK_DND_H__
|
||||
|
||||
|
||||
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gtk/gtk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gtk/gtkwidget.h>
|
||||
#include <gtk/gtkselection.h>
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* Destination side */
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drag_get_data (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
GdkAtom target);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkWidget *gtk_drag_get_source_widget (GdkDrag *drag);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drag_highlight (GtkWidget *widget);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drag_unhighlight (GtkWidget *widget);
|
||||
|
||||
/* Source side */
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDrag *gtk_drag_begin (GtkWidget *widget,
|
||||
GdkDevice *device,
|
||||
GdkContentFormats *targets,
|
||||
GdkDragAction actions,
|
||||
gint x,
|
||||
gint y);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drag_cancel (GdkDrag *drag);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drag_set_icon_widget (GdkDrag *drag,
|
||||
GtkWidget *widget,
|
||||
gint hot_x,
|
||||
gint hot_y);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drag_set_icon_paintable (GdkDrag *drag,
|
||||
GdkPaintable *paintable,
|
||||
int hot_x,
|
||||
int hot_y);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drag_set_icon_name (GdkDrag *drag,
|
||||
const gchar *icon_name,
|
||||
gint hot_x,
|
||||
gint hot_y);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drag_set_icon_gicon (GdkDrag *drag,
|
||||
GIcon *icon,
|
||||
gint hot_x,
|
||||
gint hot_y);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drag_set_icon_default (GdkDrag *drag);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_drag_check_threshold (GtkWidget *widget,
|
||||
gint start_x,
|
||||
gint start_y,
|
||||
gint current_x,
|
||||
gint current_y);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_DND_H__ */
|
||||
@@ -1,59 +0,0 @@
|
||||
/* -*- Mode: C; c-file-style: "gnu"; tab-width: 8 -*- */
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2015 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_DND_PRIVATE_H__
|
||||
#define __GTK_DND_PRIVATE_H__
|
||||
|
||||
#include "gtkdnd.h"
|
||||
|
||||
#include "gtkdragdest.h"
|
||||
#include "gtkimagedefinitionprivate.h"
|
||||
#include "gtkselection.h"
|
||||
#include "gtkwidget.h"
|
||||
|
||||
typedef struct _GtkDragDestSite GtkDragDestSite;
|
||||
struct _GtkDragDestSite
|
||||
{
|
||||
GtkDestDefaults flags;
|
||||
GdkContentFormats *target_list;
|
||||
GdkDragAction actions;
|
||||
guint do_proxy : 1;
|
||||
guint proxy_coords : 1;
|
||||
guint have_drag : 1;
|
||||
guint track_motion : 1;
|
||||
};
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GdkDrag * gtk_drag_begin_internal (GtkWidget *widget,
|
||||
GdkDevice *device,
|
||||
GtkImageDefinition *icon,
|
||||
GdkContentFormats *target_list,
|
||||
GdkDragAction actions,
|
||||
int x,
|
||||
int y);
|
||||
void gtk_drag_set_icon_definition (GdkDrag *drag,
|
||||
GtkImageDefinition *def,
|
||||
gint hot_x,
|
||||
gint hot_y);
|
||||
void _gtk_drag_dest_handle_event (GtkWidget *toplevel,
|
||||
GdkEvent *event);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_DND_PRIVATE_H__ */
|
||||
+961
-317
File diff suppressed because it is too large
Load Diff
+42
-49
@@ -37,65 +37,58 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* GtkDestDefaults:
|
||||
* @GTK_DEST_DEFAULT_MOTION: If set for a widget, GTK+, during a drag over this
|
||||
* widget will check if the drag matches this widget’s list of possible formats
|
||||
* and actions.
|
||||
* GTK+ will then call gdk_drag_status() as appropriate.
|
||||
* @GTK_DEST_DEFAULT_HIGHLIGHT: If set for a widget, GTK+ will draw a highlight on
|
||||
* this widget as long as a drag is over this widget and the widget drag format
|
||||
* and action are acceptable.
|
||||
* @GTK_DEST_DEFAULT_DROP: If set for a widget, when a drop occurs, GTK+ will
|
||||
* will check if the drag matches this widget’s list of possible formats and
|
||||
* actions. If so, GTK+ will call gtk_drag_get_data() on behalf of the widget.
|
||||
* Whether or not the drop is successful, GTK+ will call gdk_drag_finish(). If
|
||||
* the action was a move, then if the drag was successful, then %TRUE will be
|
||||
* passed for the @delete parameter to gdk_drag_finish().
|
||||
* @GTK_DEST_DEFAULT_ALL: If set, specifies that all default actions should
|
||||
* be taken.
|
||||
*
|
||||
* The #GtkDestDefaults enumeration specifies the various
|
||||
* types of action that will be taken on behalf
|
||||
* of the user for a drag destination site.
|
||||
*/
|
||||
typedef enum {
|
||||
GTK_DEST_DEFAULT_MOTION = 1 << 0,
|
||||
GTK_DEST_DEFAULT_HIGHLIGHT = 1 << 1,
|
||||
GTK_DEST_DEFAULT_DROP = 1 << 2,
|
||||
GTK_DEST_DEFAULT_ALL = 0x07
|
||||
} GtkDestDefaults;
|
||||
typedef struct _GtkDropTarget GtkDropTarget;
|
||||
|
||||
|
||||
#define GTK_TYPE_DROP_TARGET (gtk_drop_target_get_type ())
|
||||
#define GTK_DROP_TARGET(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_DROP_TARGET, GtkDropTarget))
|
||||
#define GTK_DROP_TARGET_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GTK_TYPE_DROP_TARGET, GtkDropTargetClass))
|
||||
#define GTK_IS_DROP_TARGET(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTK_TYPE_DROP_TARGET))
|
||||
#define GTK_IS_DROP_TARGET_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GTK_TYPE_DROP_TARGET))
|
||||
#define GTK_DROP_TARGET_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GTK_TYPE_DROP_TARGET, GtkDropTargetClass))
|
||||
|
||||
typedef struct _GtkDropTargetClass GtkDropTargetClass;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drag_dest_set (GtkWidget *widget,
|
||||
GtkDestDefaults flags,
|
||||
GdkContentFormats *targets,
|
||||
GdkDragAction actions);
|
||||
GType gtk_drop_target_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drag_dest_unset (GtkWidget *widget);
|
||||
GtkDropTarget *gtk_drop_target_new (GdkContentFormats *formats,
|
||||
GdkDragAction actions);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
const char * gtk_drag_dest_find_target (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
GdkContentFormats *target_list);
|
||||
void gtk_drop_target_set_formats (GtkDropTarget *dest,
|
||||
GdkContentFormats *formats);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkContentFormats* gtk_drag_dest_get_target_list (GtkWidget *widget);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drag_dest_set_target_list (GtkWidget *widget,
|
||||
GdkContentFormats *target_list);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drag_dest_add_text_targets (GtkWidget *widget);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drag_dest_add_image_targets (GtkWidget *widget);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drag_dest_add_uri_targets (GtkWidget *widget);
|
||||
GdkContentFormats *gtk_drop_target_get_formats (GtkDropTarget *dest);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drag_dest_set_track_motion (GtkWidget *widget,
|
||||
gboolean track_motion);
|
||||
void gtk_drop_target_set_actions (GtkDropTarget *dest,
|
||||
GdkDragAction actions);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_drag_dest_get_track_motion (GtkWidget *widget);
|
||||
GdkDragAction gtk_drop_target_get_actions (GtkDropTarget *dest);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDrop *gtk_drop_target_get_drop (GtkDropTarget *dest);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
const char *gtk_drop_target_find_mimetype (GtkDropTarget *dest);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drop_target_read_selection (GtkDropTarget *dest,
|
||||
GdkAtom target,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkSelectionData *gtk_drop_target_read_selection_finish
|
||||
(GtkDropTarget *dest,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drop_target_deny_drop (GtkDropTarget *dest,
|
||||
GdkDrop *drop);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2020 Matthias Clasen
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_DRAG_DEST_PRIVATE_H__
|
||||
#define __GTK_DRAG_DEST_PRIVATE_H__
|
||||
|
||||
#include "gtkdragdest.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
void gtk_drag_dest_handle_event (GtkWidget *toplevel,
|
||||
GdkEvent *event);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
@@ -23,8 +23,25 @@
|
||||
#include "gtkintl.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkcssnodeprivate.h"
|
||||
#include "gtknativeprivate.h"
|
||||
#include "gtkpicture.h"
|
||||
|
||||
|
||||
/**
|
||||
* SECTION:gtkdragicon
|
||||
* @Short_description: A toplevel to use as drag icon
|
||||
* @Title: GtkDragIcon
|
||||
*
|
||||
* GtkDragIcon is a #GtkNative implementation with the sole purpose
|
||||
* to serve as a drag icon during DND operations. A drag icon moves
|
||||
* with the pointer during a drag operation and is destroyed when
|
||||
* the drag ends.
|
||||
*
|
||||
* To set up a drag icon and associate it with an ongoing drag operation,
|
||||
* use gtk_drag_icon_set_from_paintable(). It is also possible to create
|
||||
* a GtkDragIcon with gtk_drag_icon_new_for_drag(() and populate it
|
||||
* with widgets yourself.
|
||||
*/
|
||||
struct _GtkDragIcon
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
@@ -374,6 +391,63 @@ gtk_drag_icon_new (void)
|
||||
return g_object_new (GTK_TYPE_DRAG_ICON, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_icon_new_for_drag:
|
||||
* @drag: a #GtkDrag
|
||||
*
|
||||
* Creates a #GtkDragIcon and associates it with the drag operation.
|
||||
*
|
||||
* Returns: the new #GtkDragIcon
|
||||
*/
|
||||
GtkWidget *
|
||||
gtk_drag_icon_new_for_drag (GdkDrag *drag)
|
||||
{
|
||||
GtkWidget *icon;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DRAG (drag), NULL);
|
||||
|
||||
icon = g_object_new (GTK_TYPE_DRAG_ICON, NULL);
|
||||
|
||||
gtk_drag_icon_set_surface (GTK_DRAG_ICON (icon), gdk_drag_get_drag_surface (drag));
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_icon_set_from_paintable:
|
||||
* @drag: a #GdkDrag
|
||||
* @paintable: a #GdkPaintable to display
|
||||
* @hot_x: X coordinate of the hotspot
|
||||
* @hot_y: Y coordinate of the hotspot
|
||||
*
|
||||
* Creates a #GtkDragIcon that shows @paintable, and associates
|
||||
* it with the drag operation. The hotspot position on the paintable
|
||||
* is aligned with the hotspot of the cursor.
|
||||
*/
|
||||
void
|
||||
gtk_drag_icon_set_from_paintable (GdkDrag *drag,
|
||||
GdkPaintable *paintable,
|
||||
int hot_x,
|
||||
int hot_y)
|
||||
{
|
||||
GtkWidget *icon;
|
||||
GtkWidget *picture;
|
||||
|
||||
gdk_drag_set_hotspot (drag, hot_x, hot_y);
|
||||
|
||||
icon = gtk_drag_icon_new_for_drag (drag);
|
||||
|
||||
picture = gtk_picture_new_for_paintable (paintable);
|
||||
gtk_picture_set_can_shrink (GTK_PICTURE (picture), FALSE);
|
||||
gtk_container_add (GTK_CONTAINER (icon), picture);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (drag),
|
||||
"icon",
|
||||
g_object_ref_sink (icon),
|
||||
(GDestroyNotify)gtk_widget_destroy);
|
||||
gtk_widget_show (icon);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_drag_icon_set_surface (GtkDragIcon *icon,
|
||||
GdkSurface *surface)
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright © 2020 Matthias Clasen
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef __GTK_DRAG_ICON_H__
|
||||
#define __GTK_DRAG_ICON_H__
|
||||
|
||||
|
||||
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gtk/gtk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <gtk/gtkwidget.h>
|
||||
#include <gtk/gtkcontainer.h>
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_DRAG_ICON (gtk_drag_icon_get_type ())
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
G_DECLARE_FINAL_TYPE (GtkDragIcon, gtk_drag_icon, GTK, DRAG_ICON, GtkContainer)
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkWidget * gtk_drag_icon_new_for_drag (GdkDrag *drag);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drag_icon_set_from_paintable (GdkDrag *drag,
|
||||
GdkPaintable *paintable,
|
||||
int hot_x,
|
||||
int hot_y);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
#endif /* __GTK_DRAG_ICON_H__ */
|
||||
@@ -26,14 +26,10 @@
|
||||
#define __GTK_DRAG_ICON_PRIVATE_H__
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gtk/gtkdragicon.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_DRAG_ICON (gtk_drag_icon_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GtkDragIcon, gtk_drag_icon, GTK, DRAG_ICON, GtkContainer)
|
||||
|
||||
GtkWidget * gtk_drag_icon_new (void);
|
||||
|
||||
void gtk_drag_icon_set_surface (GtkDragIcon *icon,
|
||||
|
||||
+599
-287
@@ -26,365 +26,677 @@
|
||||
|
||||
#include "gtkdragsource.h"
|
||||
|
||||
#include "gtkdnd.h"
|
||||
#include "gtkdndprivate.h"
|
||||
#include "gtkgesturedrag.h"
|
||||
#include "gtkgesturesingleprivate.h"
|
||||
#include "gtkimagedefinitionprivate.h"
|
||||
#include "gtknative.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkstylecontext.h"
|
||||
#include "gtkimageprivate.h"
|
||||
#include "gtkdragiconprivate.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkmarshalers.h"
|
||||
#include "gtkicontheme.h"
|
||||
#include "gtkpicture.h"
|
||||
#include "gtksettingsprivate.h"
|
||||
#include "gtkgesturesingle.h"
|
||||
|
||||
/**
|
||||
* SECTION:gtkdragsource
|
||||
* @Short_description: Event controller to initiate DND operations
|
||||
* @Title: GtkDragSource
|
||||
*
|
||||
* GtkDragSource is an auxiliary object that is used to initiate
|
||||
* Drag-And-Drop operations. It can be set up with the necessary
|
||||
* ingredients for a DND operation ahead of time. This includes
|
||||
* the source for the data that is being transferred, in the form
|
||||
* of a #GdkContentProvider, the desired action, and the icon to
|
||||
* use during the drag operation. After setting it up, the drag
|
||||
* source must be added to a widget as an event controller, using
|
||||
* gtk_widget_add_controller().
|
||||
*
|
||||
* Setting up the content provider and icon ahead of time only
|
||||
* makes sense when the data does not change. More commonly, you
|
||||
* will want to set them up just in time. To do so, #GtkDragSource
|
||||
* has #GtkDragSource::prepare and #GtkDragSource::drag-begin signals.
|
||||
* The ::prepare signal is emitted before a drag is started, and
|
||||
* can be used to set the content provider and actions that the
|
||||
* drag should be started with. The ::drag-begin signal is emitted
|
||||
* after the #GdkDrag object has been created, and can be used
|
||||
* to set up the drag icon.
|
||||
*
|
||||
* During the DND operation, GtkDragSource emits signals that
|
||||
* can be used to obtain updates about the status of the operation,
|
||||
* but it is not normally necessary to connect to any signals,
|
||||
* except for one case: when the supported actions include
|
||||
* %GDK_DRAG_MOVE, you need to listen for the
|
||||
* #GtkDragSource::drag-end signal and delete the
|
||||
* data after it has been transferred.
|
||||
*/
|
||||
|
||||
typedef struct _GtkDragSourceSite GtkDragSourceSite;
|
||||
|
||||
struct _GtkDragSourceSite
|
||||
struct _GtkDragSource
|
||||
{
|
||||
GdkModifierType start_button_mask;
|
||||
GdkContentFormats *target_list; /* Targets for drag data */
|
||||
GdkDragAction actions; /* Possible actions */
|
||||
GtkGestureSingle parent_instance;
|
||||
|
||||
GtkImageDefinition *image_def;
|
||||
GtkGesture *drag_gesture;
|
||||
GdkContentProvider *content;
|
||||
GdkDragAction actions;
|
||||
|
||||
GdkPaintable *paintable;
|
||||
int hot_x;
|
||||
int hot_y;
|
||||
|
||||
gdouble start_x;
|
||||
gdouble start_y;
|
||||
|
||||
GdkDrag *drag;
|
||||
};
|
||||
|
||||
static void
|
||||
gtk_drag_source_gesture_begin (GtkGesture *gesture,
|
||||
GdkEventSequence *sequence,
|
||||
gpointer data)
|
||||
|
||||
struct _GtkDragSourceClass
|
||||
{
|
||||
GtkDragSourceSite *site = data;
|
||||
guint button;
|
||||
GtkGestureSingleClass parent_class;
|
||||
|
||||
if (gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture)))
|
||||
button = 1;
|
||||
else
|
||||
button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
|
||||
GdkContentProvider *(* prepare) (GtkDragSource *source,
|
||||
double x,
|
||||
double y);
|
||||
};
|
||||
|
||||
g_assert (button >= 1);
|
||||
enum {
|
||||
PROP_CONTENT = 1,
|
||||
PROP_ACTIONS,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
if (!site->start_button_mask ||
|
||||
!(site->start_button_mask & (GDK_BUTTON1_MASK << (button - 1))))
|
||||
gtk_gesture_set_state (gesture, GTK_EVENT_SEQUENCE_DENIED);
|
||||
static GParamSpec *properties[NUM_PROPERTIES];
|
||||
|
||||
enum {
|
||||
PREPARE,
|
||||
DRAG_BEGIN,
|
||||
DRAG_END,
|
||||
DRAG_CANCEL,
|
||||
NUM_SIGNALS
|
||||
};
|
||||
|
||||
static guint signals[NUM_SIGNALS];
|
||||
|
||||
static void gtk_drag_source_dnd_finished_cb (GdkDrag *drag,
|
||||
GtkDragSource *source);
|
||||
static void gtk_drag_source_cancel_cb (GdkDrag *drag,
|
||||
GdkDragCancelReason reason,
|
||||
GtkDragSource *source);
|
||||
|
||||
static GdkContentProvider *gtk_drag_source_prepare (GtkDragSource *source,
|
||||
double x,
|
||||
double y);
|
||||
|
||||
static void gtk_drag_source_drag_begin (GtkDragSource *source);
|
||||
|
||||
G_DEFINE_TYPE (GtkDragSource, gtk_drag_source, GTK_TYPE_GESTURE_SINGLE);
|
||||
|
||||
static void
|
||||
gtk_drag_source_init (GtkDragSource *source)
|
||||
{
|
||||
source->actions = GDK_ACTION_COPY;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_drag_source_gesture_update (GtkGesture *gesture,
|
||||
GdkEventSequence *sequence,
|
||||
gpointer data)
|
||||
gtk_drag_source_finalize (GObject *object)
|
||||
{
|
||||
gdouble start_x, start_y, offset_x, offset_y;
|
||||
GtkDragSourceSite *site = data;
|
||||
GtkDragSource *source = GTK_DRAG_SOURCE (object);
|
||||
|
||||
g_clear_object (&source->content);
|
||||
g_clear_object (&source->paintable);
|
||||
|
||||
G_OBJECT_CLASS (gtk_drag_source_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_drag_source_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkDragSource *source = GTK_DRAG_SOURCE (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CONTENT:
|
||||
gtk_drag_source_set_content (source, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_ACTIONS:
|
||||
gtk_drag_source_set_actions (source, g_value_get_flags (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_drag_source_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkDragSource *source = GTK_DRAG_SOURCE (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CONTENT:
|
||||
g_value_set_object (value, gtk_drag_source_get_content (source));
|
||||
break;
|
||||
|
||||
case PROP_ACTIONS:
|
||||
g_value_set_flags (value, gtk_drag_source_get_actions (source));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_drag_source_filter_event (GtkEventController *controller,
|
||||
const GdkEvent *event)
|
||||
{
|
||||
/* Let touchpad swipe events go through, only if they match n-points */
|
||||
if (gdk_event_get_event_type (event) == GDK_TOUCHPAD_SWIPE)
|
||||
{
|
||||
guint n_points;
|
||||
guint n_fingers;
|
||||
|
||||
g_object_get (G_OBJECT (controller), "n-points", &n_points, NULL);
|
||||
gdk_event_get_touchpad_gesture_n_fingers (event, &n_fingers);
|
||||
|
||||
if (n_fingers == n_points)
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return GTK_EVENT_CONTROLLER_CLASS (gtk_drag_source_parent_class)->filter_event (controller, event);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_drag_source_begin (GtkGesture *gesture,
|
||||
GdkEventSequence *sequence)
|
||||
{
|
||||
GtkDragSource *source = GTK_DRAG_SOURCE (gesture);
|
||||
GdkEventSequence *current;
|
||||
|
||||
current = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
|
||||
|
||||
gtk_gesture_get_point (gesture, current, &source->start_x, &source->start_y);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_drag_source_update (GtkGesture *gesture,
|
||||
GdkEventSequence *sequence)
|
||||
{
|
||||
GtkDragSource *source = GTK_DRAG_SOURCE (gesture);
|
||||
GtkWidget *widget;
|
||||
double x, y;
|
||||
|
||||
if (!gtk_gesture_is_recognized (gesture))
|
||||
return;
|
||||
|
||||
gtk_gesture_get_point (gesture, sequence, &x, &y);
|
||||
|
||||
widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
if (gtk_gesture_is_recognized (site->drag_gesture))
|
||||
if (gtk_drag_check_threshold (widget, source->start_x, source->start_y, x, y))
|
||||
{
|
||||
gtk_gesture_drag_get_start_point (GTK_GESTURE_DRAG (site->drag_gesture),
|
||||
&start_x, &start_y);
|
||||
gtk_gesture_drag_get_offset (GTK_GESTURE_DRAG (site->drag_gesture),
|
||||
&offset_x, &offset_y);
|
||||
|
||||
if (gtk_drag_check_threshold (widget, start_x, start_y,
|
||||
start_x + offset_x, start_y + offset_y))
|
||||
{
|
||||
GdkDevice *device = gtk_gesture_get_device (site->drag_gesture);
|
||||
|
||||
gtk_event_controller_reset (GTK_EVENT_CONTROLLER (site->drag_gesture));
|
||||
|
||||
gtk_drag_begin_internal (widget,
|
||||
device,
|
||||
site->image_def, site->target_list,
|
||||
site->actions,
|
||||
start_x, start_y);
|
||||
}
|
||||
gtk_drag_source_drag_begin (source);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_drag_source_site_destroy (gpointer data)
|
||||
gtk_drag_source_class_init (GtkDragSourceClass *class)
|
||||
{
|
||||
GtkDragSourceSite *site = data;
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GtkEventControllerClass *controller_class = GTK_EVENT_CONTROLLER_CLASS (class);
|
||||
GtkGestureClass *gesture_class = GTK_GESTURE_CLASS (class);
|
||||
|
||||
if (site->target_list)
|
||||
gdk_content_formats_unref (site->target_list);
|
||||
object_class->finalize = gtk_drag_source_finalize;
|
||||
object_class->set_property = gtk_drag_source_set_property;
|
||||
object_class->get_property = gtk_drag_source_get_property;
|
||||
|
||||
gtk_image_definition_unref (site->image_def);
|
||||
/* This gets called only during widget finalization.
|
||||
* And widget finalization takes care of gestures. */
|
||||
g_slice_free (GtkDragSourceSite, site);
|
||||
controller_class->filter_event = gtk_drag_source_filter_event;
|
||||
|
||||
gesture_class->begin = gtk_drag_source_begin;
|
||||
gesture_class->update = gtk_drag_source_update;
|
||||
gesture_class->end = NULL;
|
||||
|
||||
class->prepare = gtk_drag_source_prepare;
|
||||
|
||||
/**
|
||||
* GtkDragSource:content:
|
||||
*
|
||||
* The data that is offered by drag operations from this source,
|
||||
* in the form of a #GdkContentProvider.
|
||||
*/
|
||||
properties[PROP_CONTENT] =
|
||||
g_param_spec_object ("content",
|
||||
P_("Content"),
|
||||
P_("The content provider for the dragged data"),
|
||||
GDK_TYPE_CONTENT_PROVIDER,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GtkDragSource:actions:
|
||||
*
|
||||
* The actions that are supported by drag operations from the source.
|
||||
*
|
||||
* Note that you must handle the #GtkDragSource::drag-end signal
|
||||
* if the actions include %GDK_ACTION_MOVE.
|
||||
*/
|
||||
properties[PROP_ACTIONS] =
|
||||
g_param_spec_flags ("actions",
|
||||
P_("Actions"),
|
||||
P_("Supported actions"),
|
||||
GDK_TYPE_DRAG_ACTION, GDK_ACTION_COPY,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
|
||||
|
||||
/**
|
||||
* GtkDragSource::prepare:
|
||||
* @source: the #GtkDragSource
|
||||
* @x: the X coordinate of the drag starting point
|
||||
* @y: the Y coordinate fo the drag starting point
|
||||
*
|
||||
* The ::prepare signal is emitted when a drag is about to be initiated.
|
||||
* It returns the * #GdkContentProvider to use for the drag that is about
|
||||
* to start. The default handler for this signal returns the value of
|
||||
* the #GtkDragSource::content property, so if you set up that property
|
||||
* ahead of time, you don't need to connect to this signal.
|
||||
*
|
||||
* Returns: (transfer full) (nullable): a #GdkContentProvider, or %NULL
|
||||
*/
|
||||
signals[PREPARE] =
|
||||
g_signal_new (I_("prepare"),
|
||||
G_TYPE_FROM_CLASS (class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkDragSourceClass, prepare),
|
||||
g_signal_accumulator_first_wins, NULL,
|
||||
NULL,
|
||||
GDK_TYPE_CONTENT_PROVIDER, 2,
|
||||
G_TYPE_DOUBLE, G_TYPE_DOUBLE);
|
||||
|
||||
/**
|
||||
* GtkDragSource::drag-begin:
|
||||
* @source: the #GtkDragSource
|
||||
* @drag: the #GtkDrag object
|
||||
*
|
||||
* The ::drag-begin signal is emitted on the drag source when a drag
|
||||
* is started. It can be used to e.g. set a custom drag icon with
|
||||
* gtk_drag_source_set_icon().
|
||||
*/
|
||||
signals[DRAG_BEGIN] =
|
||||
g_signal_new (I_("drag-begin"),
|
||||
G_TYPE_FROM_CLASS (class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE, 1,
|
||||
GDK_TYPE_DRAG);
|
||||
|
||||
/**
|
||||
* GtkDragSource::drag-end:
|
||||
* @source: the #GtkDragSource
|
||||
* @drag: the #GtkDrag object
|
||||
* @delete_data: %TRUE if the drag was performing %GDK_ACTION_MOVE,
|
||||
* and the data should be deleted
|
||||
*
|
||||
* The ::drag-end signal is emitted on the drag source when a drag is
|
||||
* finished. A typical reason to connect to this signal is to undo
|
||||
* things done in #GtkDragSource::prepare or #GtkDragSource::drag-begin.
|
||||
*/
|
||||
signals[DRAG_END] =
|
||||
g_signal_new (I_("drag-end"),
|
||||
G_TYPE_FROM_CLASS (class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE, 2,
|
||||
GDK_TYPE_DRAG,
|
||||
G_TYPE_BOOLEAN);
|
||||
|
||||
/**
|
||||
* GtkDragSource::drag-cancel:
|
||||
* @source: the #GtkDragSource
|
||||
* @drag: the #GtkDrag object
|
||||
* @reason: information on why the drag failed
|
||||
*
|
||||
* The ::drag-cancel signal is emitted on the drag source when a drag has
|
||||
* failed. The signal handler may handle a failed drag operation based on
|
||||
* the type of error. It should return %TRUE if the failure has been handled
|
||||
* and the default "drag operation failed" animation should not be shown.
|
||||
*
|
||||
* Returns: %TRUE if the failed drag operation has been already handled
|
||||
*/
|
||||
signals[DRAG_CANCEL] =
|
||||
g_signal_new (I_("drag-cancel"),
|
||||
G_TYPE_FROM_CLASS (class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
_gtk_boolean_handled_accumulator, NULL,
|
||||
_gtk_marshal_BOOLEAN__OBJECT_ENUM,
|
||||
G_TYPE_BOOLEAN, 2,
|
||||
GDK_TYPE_DRAG,
|
||||
GDK_TYPE_DRAG_CANCEL_REASON);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_source_set: (method)
|
||||
* @widget: a #GtkWidget
|
||||
* @start_button_mask: the bitmask of buttons that can start the drag
|
||||
* @targets: (allow-none): the targets that the drag will support,
|
||||
* may be %NULL
|
||||
* @actions: the bitmask of possible actions for a drag from this widget
|
||||
*
|
||||
* Sets up a widget so that GTK+ will start a drag operation when the user
|
||||
* clicks and drags on the widget. The widget must have a window.
|
||||
*/
|
||||
void
|
||||
gtk_drag_source_set (GtkWidget *widget,
|
||||
GdkModifierType start_button_mask,
|
||||
GdkContentFormats *targets,
|
||||
GdkDragAction actions)
|
||||
static GdkContentProvider *
|
||||
gtk_drag_source_prepare (GtkDragSource *source,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
GtkDragSourceSite *site;
|
||||
if (source->actions == 0)
|
||||
return NULL;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
if (source->content == NULL)
|
||||
return NULL;
|
||||
|
||||
site = g_object_get_data (G_OBJECT (widget), "gtk-site-data");
|
||||
return g_object_ref (source->content);
|
||||
}
|
||||
|
||||
if (site)
|
||||
static void
|
||||
drag_end (GtkDragSource *source,
|
||||
gboolean success)
|
||||
{
|
||||
gboolean delete_data;
|
||||
|
||||
g_signal_handlers_disconnect_by_func (source->drag, gtk_drag_source_dnd_finished_cb, source);
|
||||
g_signal_handlers_disconnect_by_func (source->drag, gtk_drag_source_cancel_cb, source);
|
||||
|
||||
delete_data = success && gdk_drag_get_selected_action (source->drag) == GDK_ACTION_MOVE;
|
||||
|
||||
g_signal_emit (source, signals[DRAG_END], 0, source->drag, delete_data);
|
||||
|
||||
gdk_drag_drop_done (source->drag, success);
|
||||
g_clear_object (&source->drag);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_drag_source_dnd_finished_cb (GdkDrag *drag,
|
||||
GtkDragSource *source)
|
||||
{
|
||||
drag_end (source, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_drag_source_cancel_cb (GdkDrag *drag,
|
||||
GdkDragCancelReason reason,
|
||||
GtkDragSource *source)
|
||||
{
|
||||
gboolean success = FALSE;
|
||||
|
||||
g_signal_emit (source, signals[DRAG_CANCEL], 0, source->drag, reason, &success);
|
||||
drag_end (source, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_drag_source_drag_begin (GtkDragSource *source)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GdkDevice *device;
|
||||
int x, y;
|
||||
GtkNative *native;
|
||||
GdkSurface *surface;
|
||||
double px, py;
|
||||
int dx, dy;
|
||||
GdkContentProvider *content = NULL;
|
||||
|
||||
widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
|
||||
device = gtk_gesture_get_device (GTK_GESTURE (source));
|
||||
|
||||
if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
|
||||
device = gdk_device_get_associated_device (device);
|
||||
|
||||
native = gtk_widget_get_native (widget);
|
||||
surface = gtk_native_get_surface (native);
|
||||
|
||||
gtk_widget_translate_coordinates (widget, GTK_WIDGET (native), source->start_x, source->start_y, &x, &y);
|
||||
gdk_surface_get_device_position (surface, device, &px, &py, NULL);
|
||||
|
||||
dx = round (px) - x;
|
||||
dy = round (py) - y;
|
||||
|
||||
g_signal_emit (source, signals[PREPARE], 0, source->start_x, source->start_y, &content);
|
||||
if (!content)
|
||||
return;
|
||||
|
||||
source->drag = gdk_drag_begin (surface, device, content, source->actions, dx, dy);
|
||||
|
||||
g_object_unref (content);
|
||||
|
||||
if (source->drag == NULL)
|
||||
return;
|
||||
|
||||
gtk_widget_reset_controllers (widget);
|
||||
|
||||
g_signal_emit (source, signals[DRAG_BEGIN], 0, source->drag);
|
||||
|
||||
if (!source->paintable)
|
||||
{
|
||||
if (site->target_list)
|
||||
gdk_content_formats_unref (site->target_list);
|
||||
}
|
||||
else
|
||||
{
|
||||
site = g_slice_new0 (GtkDragSourceSite);
|
||||
site->image_def = gtk_image_definition_new_empty ();
|
||||
site->drag_gesture = gtk_gesture_drag_new ();
|
||||
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (site->drag_gesture),
|
||||
GTK_PHASE_CAPTURE);
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (site->drag_gesture), 0);
|
||||
g_signal_connect (site->drag_gesture, "begin",
|
||||
G_CALLBACK (gtk_drag_source_gesture_begin),
|
||||
site);
|
||||
g_signal_connect (site->drag_gesture, "update",
|
||||
G_CALLBACK (gtk_drag_source_gesture_update),
|
||||
site);
|
||||
gtk_widget_add_controller (widget, GTK_EVENT_CONTROLLER (site->drag_gesture));
|
||||
|
||||
g_object_set_data_full (G_OBJECT (widget),
|
||||
I_("gtk-site-data"),
|
||||
site, gtk_drag_source_site_destroy);
|
||||
GtkIconTheme *theme;
|
||||
|
||||
theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (widget));
|
||||
source->paintable = gtk_icon_theme_load_icon (theme, "text-x-generic", 32, 0, NULL);
|
||||
source->hot_x = 0;
|
||||
source->hot_y = 0;
|
||||
}
|
||||
|
||||
site->start_button_mask = start_button_mask;
|
||||
gtk_drag_icon_set_from_paintable (source->drag, source->paintable, source->hot_x, source->hot_y);
|
||||
|
||||
if (targets)
|
||||
site->target_list = gdk_content_formats_ref (targets);
|
||||
else
|
||||
site->target_list = NULL;
|
||||
|
||||
site->actions = actions;
|
||||
g_signal_connect (source->drag, "dnd-finished",
|
||||
G_CALLBACK (gtk_drag_source_dnd_finished_cb), source);
|
||||
g_signal_connect (source->drag, "cancel",
|
||||
G_CALLBACK (gtk_drag_source_cancel_cb), source);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_source_unset: (method)
|
||||
* @widget: a #GtkWidget
|
||||
* gtk_drag_source_new:
|
||||
*
|
||||
* Undoes the effects of gtk_drag_source_set().
|
||||
* Creates a new #GtkDragSource object.
|
||||
*
|
||||
* Returns: the new #GtkDragSource
|
||||
*/
|
||||
void
|
||||
gtk_drag_source_unset (GtkWidget *widget)
|
||||
GtkDragSource *
|
||||
gtk_drag_source_new (void)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
|
||||
g_object_set_data (G_OBJECT (widget), I_("gtk-site-data"), NULL);
|
||||
return g_object_new (GTK_TYPE_DRAG_SOURCE, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_source_get_target_list: (method)
|
||||
* @widget: a #GtkWidget
|
||||
* gtk_drag_source_get_content:
|
||||
* @source: a #GtkDragSource
|
||||
*
|
||||
* Gets the list of targets this widget can provide for
|
||||
* drag-and-drop.
|
||||
* Gets the current content provider of a #GtkDragSource.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): the #GdkContentFormats, or %NULL if none
|
||||
* Returns: (transfer none): the #GtkContentProvider of @source
|
||||
*/
|
||||
GdkContentFormats *
|
||||
gtk_drag_source_get_target_list (GtkWidget *widget)
|
||||
GdkContentProvider *
|
||||
gtk_drag_source_get_content (GtkDragSource *source)
|
||||
{
|
||||
GtkDragSourceSite *site;
|
||||
g_return_val_if_fail (GTK_IS_DRAG_SOURCE (source), NULL);
|
||||
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
|
||||
|
||||
site = g_object_get_data (G_OBJECT (widget), "gtk-site-data");
|
||||
|
||||
return site ? site->target_list : NULL;
|
||||
return source->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_source_set_target_list: (method)
|
||||
* @widget: a #GtkWidget that’s a drag source
|
||||
* @target_list: (allow-none): list of draggable targets, or %NULL for none
|
||||
* gtk_drag_source_set_content:
|
||||
* @source: a #GtkDragSource
|
||||
* @content: (nullable): a #GtkContentProvider, or %NULL
|
||||
*
|
||||
* Changes the target types that this widget offers for drag-and-drop.
|
||||
* The widget must first be made into a drag source with
|
||||
* gtk_drag_source_set().
|
||||
* Sets a content provider on a #GtkDragSource.
|
||||
*
|
||||
* When the data is requested in the cause of a
|
||||
* DND operation, it will be obtained from the
|
||||
* content provider.
|
||||
*
|
||||
* This function can be called before a drag is started,
|
||||
* or in a handler for the #GtkDragSource::prepare signal.
|
||||
*
|
||||
* You may consider setting the content provider back to
|
||||
* %NULL in a #GTkDragSource::drag-end signal handler.
|
||||
*/
|
||||
void
|
||||
gtk_drag_source_set_target_list (GtkWidget *widget,
|
||||
GdkContentFormats *target_list)
|
||||
gtk_drag_source_set_content (GtkDragSource *source,
|
||||
GdkContentProvider *content)
|
||||
{
|
||||
GtkDragSourceSite *site;
|
||||
g_return_if_fail (GTK_IS_DRAG_SOURCE (source));
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
if (!g_set_object (&source->content, content))
|
||||
return;
|
||||
|
||||
site = g_object_get_data (G_OBJECT (widget), "gtk-site-data");
|
||||
if (site == NULL)
|
||||
g_object_notify_by_pspec (G_OBJECT (source), properties[PROP_CONTENT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_source_get_actions:
|
||||
* @source: a #GtkDragSource
|
||||
*
|
||||
* Gets the actions that are currently set on the #GtkDragSource.
|
||||
*
|
||||
* Returns: the actions set on @source
|
||||
*/
|
||||
GdkDragAction
|
||||
gtk_drag_source_get_actions (GtkDragSource *source)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_DRAG_SOURCE (source), 0);
|
||||
|
||||
return source->actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_source_set_actions:
|
||||
* @source: a #GtkDragSource
|
||||
* @actions: the actions to offer
|
||||
*
|
||||
* Sets the actions on the #GtkDragSource.
|
||||
*
|
||||
* During a DND operation, the actions are offered
|
||||
* to potential drop targets. If @actions include
|
||||
* %GDK_ACTION_MOVE, you need to listen to the
|
||||
* #GtkDraGSource::drag-end signal and handle
|
||||
* @delete_data being %TRUE.
|
||||
*
|
||||
* This function can be called before a drag is started,
|
||||
* or in a handler for the #GtkDragSource::prepare signal.
|
||||
*/
|
||||
void
|
||||
gtk_drag_source_set_actions (GtkDragSource *source,
|
||||
GdkDragAction actions)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_DRAG_SOURCE (source));
|
||||
|
||||
if (source->actions == actions)
|
||||
return;
|
||||
|
||||
source->actions = actions;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (source), properties[PROP_ACTIONS]);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_source_set_icon:
|
||||
* @source: a #GtkDragSource
|
||||
* @paintable: (nullable): the #GtkPaintable to use as icon, or %NULL
|
||||
* @hot_x: the hotspot X coordinate on the icon
|
||||
* @hot_y: the hotspot Y coordinate on the icon
|
||||
*
|
||||
* Sets a paintable to use as icon during DND operations.
|
||||
*
|
||||
* The hotspot coordinates determine the point on the icon
|
||||
* that gets aligned with the hotspot of the cursor.
|
||||
*
|
||||
* If @paintable is %NULL, a default icon is used.
|
||||
*
|
||||
* This function can be called before a drag is started, or in
|
||||
* a #GtkDragSource::prepare or #GtkDragSource::drag-begin signal handler.
|
||||
*/
|
||||
void
|
||||
gtk_drag_source_set_icon (GtkDragSource *source,
|
||||
GdkPaintable *paintable,
|
||||
int hot_x,
|
||||
int hot_y)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_DRAG_SOURCE (source));
|
||||
|
||||
g_set_object (&source->paintable, paintable);
|
||||
|
||||
source->hot_x = hot_x;
|
||||
source->hot_y = hot_y;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_source_get_drag:
|
||||
* @source: a #GtkDragSource
|
||||
*
|
||||
* Returns the underlying #GtkDrag object for an ongoing drag.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): the #GdkDrag of the current drag operation, or %NULL
|
||||
*/
|
||||
GdkDrag *
|
||||
gtk_drag_source_get_drag (GtkDragSource *source)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_DRAG_SOURCE (source), NULL);
|
||||
|
||||
return source->drag;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_source_drag_cancel:
|
||||
* @source: a #GtkDragSource
|
||||
*
|
||||
* Cancels a currently ongoing drag operation.
|
||||
*/
|
||||
void
|
||||
gtk_drag_source_drag_cancel (GtkDragSource *source)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_DRAG_SOURCE (source));
|
||||
|
||||
if (source->drag)
|
||||
{
|
||||
g_warning ("gtk_drag_source_set_target_list() requires the widget "
|
||||
"to already be a drag source.");
|
||||
return;
|
||||
gboolean success = FALSE;
|
||||
|
||||
g_signal_emit (source, signals[DRAG_CANCEL], 0, source->drag, GDK_DRAG_CANCEL_ERROR, &success);
|
||||
drag_end (source, FALSE);
|
||||
}
|
||||
|
||||
if (target_list)
|
||||
gdk_content_formats_ref (target_list);
|
||||
|
||||
if (site->target_list)
|
||||
gdk_content_formats_unref (site->target_list);
|
||||
|
||||
site->target_list = target_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_source_add_text_targets: (method)
|
||||
* @widget: a #GtkWidget that’s is a drag source
|
||||
*
|
||||
* Add the text targets supported by #GtkSelectionData to
|
||||
* the target list of the drag source. The targets
|
||||
* are added with @info = 0. If you need another value,
|
||||
* use gtk_content_formats_add_text_targets() and
|
||||
* gtk_drag_source_set_target_list().
|
||||
*/
|
||||
void
|
||||
gtk_drag_source_add_text_targets (GtkWidget *widget)
|
||||
{
|
||||
GdkContentFormats *target_list;
|
||||
|
||||
target_list = gtk_drag_source_get_target_list (widget);
|
||||
if (target_list)
|
||||
gdk_content_formats_ref (target_list);
|
||||
else
|
||||
target_list = gdk_content_formats_new (NULL, 0);
|
||||
target_list = gtk_content_formats_add_text_targets (target_list);
|
||||
gtk_drag_source_set_target_list (widget, target_list);
|
||||
gdk_content_formats_unref (target_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_source_add_image_targets: (method)
|
||||
* @widget: a #GtkWidget that’s is a drag source
|
||||
*
|
||||
* Add the writable image targets supported by #GtkSelectionData to
|
||||
* the target list of the drag source. The targets
|
||||
* are added with @info = 0. If you need another value,
|
||||
* use gtk_target_list_add_image_targets() and
|
||||
* gtk_drag_source_set_target_list().
|
||||
*/
|
||||
void
|
||||
gtk_drag_source_add_image_targets (GtkWidget *widget)
|
||||
{
|
||||
GdkContentFormats *target_list;
|
||||
|
||||
target_list = gtk_drag_source_get_target_list (widget);
|
||||
if (target_list)
|
||||
gdk_content_formats_ref (target_list);
|
||||
else
|
||||
target_list = gdk_content_formats_new (NULL, 0);
|
||||
target_list = gtk_content_formats_add_image_targets (target_list, TRUE);
|
||||
gtk_drag_source_set_target_list (widget, target_list);
|
||||
gdk_content_formats_unref (target_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_source_add_uri_targets: (method)
|
||||
* @widget: a #GtkWidget that’s is a drag source
|
||||
*
|
||||
* Add the URI targets supported by #GtkSelectionData to
|
||||
* the target list of the drag source. The targets
|
||||
* are added with @info = 0. If you need another value,
|
||||
* use gtk_content_formats_add_uri_targets() and
|
||||
* gtk_drag_source_set_target_list().
|
||||
*/
|
||||
void
|
||||
gtk_drag_source_add_uri_targets (GtkWidget *widget)
|
||||
{
|
||||
GdkContentFormats *target_list;
|
||||
|
||||
target_list = gtk_drag_source_get_target_list (widget);
|
||||
if (target_list)
|
||||
gdk_content_formats_ref (target_list);
|
||||
else
|
||||
target_list = gdk_content_formats_new (NULL, 0);
|
||||
target_list = gtk_content_formats_add_uri_targets (target_list);
|
||||
gtk_drag_source_set_target_list (widget, target_list);
|
||||
gdk_content_formats_unref (target_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_source_set_icon_name: (method)
|
||||
* gtk_drag_check_threshold: (method)
|
||||
* @widget: a #GtkWidget
|
||||
* @icon_name: name of icon to use
|
||||
*
|
||||
* Sets the icon that will be used for drags from a particular source
|
||||
* to a themed icon. See the docs for #GtkIconTheme for more details.
|
||||
*/
|
||||
void
|
||||
gtk_drag_source_set_icon_name (GtkWidget *widget,
|
||||
const gchar *icon_name)
|
||||
{
|
||||
GtkDragSourceSite *site;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
g_return_if_fail (icon_name != NULL);
|
||||
|
||||
site = g_object_get_data (G_OBJECT (widget), "gtk-site-data");
|
||||
g_return_if_fail (site != NULL);
|
||||
|
||||
gtk_image_definition_unref (site->image_def);
|
||||
site->image_def = gtk_image_definition_new_icon_name (icon_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_source_set_icon_gicon: (method)
|
||||
* @widget: a #GtkWidget
|
||||
* @icon: A #GIcon
|
||||
* @start_x: X coordinate of start of drag
|
||||
* @start_y: Y coordinate of start of drag
|
||||
* @current_x: current X coordinate
|
||||
* @current_y: current Y coordinate
|
||||
*
|
||||
* Sets the icon that will be used for drags from a particular source
|
||||
* to @icon. See the docs for #GtkIconTheme for more details.
|
||||
*/
|
||||
void
|
||||
gtk_drag_source_set_icon_gicon (GtkWidget *widget,
|
||||
GIcon *icon)
|
||||
{
|
||||
GtkDragSourceSite *site;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
g_return_if_fail (icon != NULL);
|
||||
|
||||
site = g_object_get_data (G_OBJECT (widget), "gtk-site-data");
|
||||
g_return_if_fail (site != NULL);
|
||||
|
||||
gtk_image_definition_unref (site->image_def);
|
||||
site->image_def = gtk_image_definition_new_gicon (icon);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_source_set_icon_paintable: (method)
|
||||
* @widget: a #GtkWidget
|
||||
* @paintable: A #GdkPaintable
|
||||
* Checks to see if a mouse drag starting at (@start_x, @start_y) and ending
|
||||
* at (@current_x, @current_y) has passed the GTK drag threshold, and thus
|
||||
* should trigger the beginning of a drag-and-drop operation.
|
||||
*
|
||||
* Sets the icon that will be used for drags from a particular source
|
||||
* to @paintable.
|
||||
* Returns: %TRUE if the drag threshold has been passed.
|
||||
*/
|
||||
void
|
||||
gtk_drag_source_set_icon_paintable (GtkWidget *widget,
|
||||
GdkPaintable *paintable)
|
||||
gboolean
|
||||
gtk_drag_check_threshold (GtkWidget *widget,
|
||||
int start_x,
|
||||
int start_y,
|
||||
int current_x,
|
||||
int current_y)
|
||||
{
|
||||
GtkDragSourceSite *site;
|
||||
gint drag_threshold;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
g_return_if_fail (GDK_IS_PAINTABLE (paintable));
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
|
||||
|
||||
site = g_object_get_data (G_OBJECT (widget), "gtk-site-data");
|
||||
g_return_if_fail (site != NULL);
|
||||
drag_threshold = gtk_settings_get_dnd_drag_threshold (gtk_widget_get_settings (widget));
|
||||
|
||||
gtk_image_definition_unref (site->image_def);
|
||||
site->image_def = gtk_image_definition_new_paintable (paintable);
|
||||
return (ABS (current_x - start_x) > drag_threshold ||
|
||||
ABS (current_y - start_y) > drag_threshold);
|
||||
}
|
||||
|
||||
|
||||
+37
-22
@@ -37,36 +37,51 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drag_source_set (GtkWidget *widget,
|
||||
GdkModifierType start_button_mask,
|
||||
GdkContentFormats *targets,
|
||||
GdkDragAction actions);
|
||||
#define GTK_TYPE_DRAG_SOURCE (gtk_drag_source_get_type ())
|
||||
#define GTK_DRAG_SOURCE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_DRAG_SOURCE, GtkDragSource))
|
||||
#define GTK_DRAG_SOURCE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GTK_TYPE_DRAG_SOURCE, GtkDragSourceClass))
|
||||
#define GTK_IS_DRAG_SOURCE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTK_TYPE_DRAG_SOURCE))
|
||||
#define GTK_IS_DRAG_SOURCE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GTK_TYPE_DRAG_SOURCE))
|
||||
#define GTK_DRAG_SOURCE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GTK_TYPE_DRAG_SOURCE, GtkDragSourceClass))
|
||||
|
||||
typedef struct _GtkDragSource GtkDragSource;
|
||||
typedef struct _GtkDragSourceClass GtkDragSourceClass;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drag_source_unset (GtkWidget *widget);
|
||||
GType gtk_drag_source_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkContentFormats * gtk_drag_source_get_target_list (GtkWidget *widget);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drag_source_set_target_list (GtkWidget *widget,
|
||||
GdkContentFormats *target_list);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drag_source_add_text_targets (GtkWidget *widget);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drag_source_add_image_targets (GtkWidget *widget);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drag_source_add_uri_targets (GtkWidget *widget);
|
||||
GtkDragSource *gtk_drag_source_new (void);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drag_source_set_icon_name (GtkWidget *widget,
|
||||
const gchar *icon_name);
|
||||
void gtk_drag_source_set_content (GtkDragSource *source,
|
||||
GdkContentProvider *content);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drag_source_set_icon_gicon (GtkWidget *widget,
|
||||
GIcon *icon);
|
||||
GdkContentProvider *gtk_drag_source_get_content (GtkDragSource *source);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drag_source_set_icon_paintable (GtkWidget *widget,
|
||||
GdkPaintable *paintable);
|
||||
void gtk_drag_source_set_actions (GtkDragSource *source,
|
||||
GdkDragAction actions);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDragAction gtk_drag_source_get_actions (GtkDragSource *source);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drag_source_set_icon (GtkDragSource *source,
|
||||
GdkPaintable *paintable,
|
||||
int hot_x,
|
||||
int hot_y);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_drag_source_drag_cancel (GtkDragSource *source);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDrag * gtk_drag_source_get_drag (GtkDragSource *source);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_drag_check_threshold (GtkWidget *widget,
|
||||
int start_x,
|
||||
int start_y,
|
||||
int current_x,
|
||||
int current_y);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -411,9 +411,9 @@ gtk_drawing_area_get_content_height (GtkDrawingArea *self)
|
||||
/**
|
||||
* gtk_drawing_area_set_draw_func:
|
||||
* @self: a #GtkDrawingArea
|
||||
* @draw_func: (closure user_data) (allow-none): callback that lets you draw
|
||||
* @draw_func: (allow-none): callback that lets you draw
|
||||
* the drawing area's contents
|
||||
* @user_data: user data passed to @draw_func
|
||||
* @user_data: (closure): user data passed to @draw_func
|
||||
* @destroy: destroy notifier for @user_data
|
||||
*
|
||||
* Setting a draw function is the main thing you want to do when using a drawing
|
||||
|
||||
+25
-22
@@ -38,8 +38,6 @@
|
||||
#include "gtkcelllayout.h"
|
||||
#include "gtkcssnodeprivate.h"
|
||||
#include "gtkdebug.h"
|
||||
#include "gtkdnd.h"
|
||||
#include "gtkdndprivate.h"
|
||||
#include "gtkeditable.h"
|
||||
#include "gtkemojichooser.h"
|
||||
#include "gtkemojicompletion.h"
|
||||
@@ -70,6 +68,9 @@
|
||||
#include "gtkwindow.h"
|
||||
#include "gtknative.h"
|
||||
#include "gtkgestureclick.h"
|
||||
#include "gtkdragsource.h"
|
||||
#include "gtkdragicon.h"
|
||||
#include "gtkwidgetpaintable.h"
|
||||
|
||||
#include "a11y/gtkentryaccessible.h"
|
||||
|
||||
@@ -172,7 +173,7 @@ struct _EntryIconInfo
|
||||
guint in_drag : 1;
|
||||
|
||||
GdkDragAction actions;
|
||||
GdkContentFormats *target_list;
|
||||
GdkContentProvider *content;
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -1320,8 +1321,7 @@ gtk_entry_finalize (GObject *object)
|
||||
if (icon_info == NULL)
|
||||
continue;
|
||||
|
||||
if (icon_info->target_list != NULL)
|
||||
gdk_content_formats_unref (icon_info->target_list);
|
||||
g_clear_object (&icon_info->content);
|
||||
|
||||
gtk_widget_unparent (icon_info->widget);
|
||||
|
||||
@@ -1462,17 +1462,25 @@ icon_drag_update_cb (GtkGestureDrag *gesture,
|
||||
pos = get_icon_position_from_controller (entry, GTK_EVENT_CONTROLLER (gesture));
|
||||
icon_info = priv->icons[pos];
|
||||
|
||||
if (icon_info->target_list != NULL &&
|
||||
gtk_drag_check_threshold (icon_info->widget,
|
||||
start_x, start_y,
|
||||
x, y))
|
||||
if (icon_info->content != NULL &&
|
||||
gtk_drag_check_threshold (icon_info->widget, start_x, start_y, x, y))
|
||||
{
|
||||
GdkPaintable *paintable;
|
||||
GdkSurface *surface;
|
||||
GdkDevice *device;
|
||||
GdkDrag *drag;
|
||||
|
||||
icon_info->in_drag = TRUE;
|
||||
gtk_drag_begin (GTK_WIDGET (entry),
|
||||
gtk_gesture_get_device (GTK_GESTURE (gesture)),
|
||||
icon_info->target_list,
|
||||
icon_info->actions,
|
||||
start_x, start_y);
|
||||
|
||||
surface = gtk_native_get_surface (gtk_widget_get_native (GTK_WIDGET (entry)));
|
||||
device = gtk_gesture_get_device (GTK_GESTURE (gesture));
|
||||
|
||||
drag = gdk_drag_begin (surface, device, icon_info->content, icon_info->actions, start_x, start_y);
|
||||
paintable = gtk_widget_paintable_new (icon_info->widget);
|
||||
gtk_drag_icon_set_from_paintable (drag, paintable, -2, -2);
|
||||
g_object_unref (paintable);
|
||||
|
||||
g_object_unref (drag);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2722,7 +2730,7 @@ gtk_entry_get_icon_at_pos (GtkEntry *entry,
|
||||
* gtk_entry_set_icon_drag_source:
|
||||
* @entry: a #GtkEntry
|
||||
* @icon_pos: icon position
|
||||
* @formats: the targets (data formats) in which the data can be provided
|
||||
* @provider: a #GdkContentProvider
|
||||
* @actions: a bitmask of the allowed drag actions
|
||||
*
|
||||
* Sets up the icon at the given position so that GTK+ will start a drag
|
||||
@@ -2742,7 +2750,7 @@ gtk_entry_get_icon_at_pos (GtkEntry *entry,
|
||||
void
|
||||
gtk_entry_set_icon_drag_source (GtkEntry *entry,
|
||||
GtkEntryIconPosition icon_pos,
|
||||
GdkContentFormats *formats,
|
||||
GdkContentProvider *provider,
|
||||
GdkDragAction actions)
|
||||
{
|
||||
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
|
||||
@@ -2754,12 +2762,7 @@ gtk_entry_set_icon_drag_source (GtkEntry *entry,
|
||||
if ((icon_info = priv->icons[icon_pos]) == NULL)
|
||||
icon_info = construct_icon_info (GTK_WIDGET (entry), icon_pos);
|
||||
|
||||
if (icon_info->target_list)
|
||||
gdk_content_formats_unref (icon_info->target_list);
|
||||
icon_info->target_list = formats;
|
||||
if (icon_info->target_list)
|
||||
gdk_content_formats_ref (icon_info->target_list);
|
||||
|
||||
g_set_object (&icon_info->content, provider);
|
||||
icon_info->actions = actions;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -266,7 +266,7 @@ gchar * gtk_entry_get_icon_tooltip_markup (GtkEntry *
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_entry_set_icon_drag_source (GtkEntry *entry,
|
||||
GtkEntryIconPosition icon_pos,
|
||||
GdkContentFormats *formats,
|
||||
GdkContentProvider *provider,
|
||||
GdkDragAction actions);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gint gtk_entry_get_current_icon_drag_source (GtkEntry *entry);
|
||||
|
||||
@@ -693,31 +693,6 @@ typedef enum
|
||||
GTK_TREE_VIEW_GRID_LINES_BOTH
|
||||
} GtkTreeViewGridLines;
|
||||
|
||||
/**
|
||||
* GtkDragResult:
|
||||
* @GTK_DRAG_RESULT_SUCCESS: The drag operation was successful.
|
||||
* @GTK_DRAG_RESULT_NO_TARGET: No suitable drag target.
|
||||
* @GTK_DRAG_RESULT_USER_CANCELLED: The user cancelled the drag operation.
|
||||
* @GTK_DRAG_RESULT_TIMEOUT_EXPIRED: The drag operation timed out.
|
||||
* @GTK_DRAG_RESULT_GRAB_BROKEN: The pointer or keyboard grab used
|
||||
* for the drag operation was broken.
|
||||
* @GTK_DRAG_RESULT_ERROR: The drag operation failed due to some
|
||||
* unspecified error.
|
||||
*
|
||||
* Gives an indication why a drag operation failed.
|
||||
* The value can by obtained by connecting to the
|
||||
* #GtkWidget::drag-failed signal.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GTK_DRAG_RESULT_SUCCESS,
|
||||
GTK_DRAG_RESULT_NO_TARGET,
|
||||
GTK_DRAG_RESULT_USER_CANCELLED,
|
||||
GTK_DRAG_RESULT_TIMEOUT_EXPIRED,
|
||||
GTK_DRAG_RESULT_GRAB_BROKEN,
|
||||
GTK_DRAG_RESULT_ERROR
|
||||
} GtkDragResult;
|
||||
|
||||
/**
|
||||
* GtkSizeGroupMode:
|
||||
* @GTK_SIZE_GROUP_NONE: group has no effect
|
||||
|
||||
+19
-18
@@ -115,7 +115,6 @@
|
||||
#include "gtkbox.h"
|
||||
#include "gtkbuildable.h"
|
||||
#include "gtkcontainerprivate.h"
|
||||
#include "gtkdnd.h"
|
||||
#include "gtkdragdest.h"
|
||||
#include "gtkiconprivate.h"
|
||||
#include "gtkgestureclick.h"
|
||||
@@ -193,12 +192,12 @@ static void gtk_expander_size_allocate (GtkWidget *widget,
|
||||
int baseline);
|
||||
static gboolean gtk_expander_focus (GtkWidget *widget,
|
||||
GtkDirectionType direction);
|
||||
static gboolean gtk_expander_drag_motion (GtkWidget *widget,
|
||||
static gboolean gtk_expander_drag_accept (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
gint x,
|
||||
gint y);
|
||||
static void gtk_expander_drag_leave (GtkWidget *widget,
|
||||
GdkDrop *drop);
|
||||
GtkExpander *expander);
|
||||
static void gtk_expander_drag_leave (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
GtkExpander *expander);
|
||||
|
||||
static void gtk_expander_add (GtkContainer *container,
|
||||
GtkWidget *widget);
|
||||
@@ -268,8 +267,6 @@ gtk_expander_class_init (GtkExpanderClass *klass)
|
||||
widget_class->destroy = gtk_expander_destroy;
|
||||
widget_class->size_allocate = gtk_expander_size_allocate;
|
||||
widget_class->focus = gtk_expander_focus;
|
||||
widget_class->drag_motion = gtk_expander_drag_motion;
|
||||
widget_class->drag_leave = gtk_expander_drag_leave;
|
||||
widget_class->measure = gtk_expander_measure;
|
||||
|
||||
container_class->add = gtk_expander_add;
|
||||
@@ -350,6 +347,8 @@ gtk_expander_init (GtkExpander *expander)
|
||||
{
|
||||
GtkExpanderPrivate *priv = gtk_expander_get_instance_private (expander);
|
||||
GtkGesture *gesture;
|
||||
GtkDropTarget *dest;
|
||||
GdkContentFormats *formats;
|
||||
|
||||
gtk_widget_set_can_focus (GTK_WIDGET (expander), TRUE);
|
||||
|
||||
@@ -375,8 +374,12 @@ gtk_expander_init (GtkExpander *expander)
|
||||
GTK_STYLE_CLASS_HORIZONTAL);
|
||||
gtk_container_add (GTK_CONTAINER (priv->title_widget), priv->arrow_widget);
|
||||
|
||||
gtk_drag_dest_set (GTK_WIDGET (expander), 0, NULL, 0);
|
||||
gtk_drag_dest_set_track_motion (GTK_WIDGET (expander), TRUE);
|
||||
formats = gdk_content_formats_new (NULL, 0);
|
||||
dest = gtk_drop_target_new (formats, 0);
|
||||
gdk_content_formats_unref (formats);
|
||||
g_signal_connect (dest, "accept", G_CALLBACK (gtk_expander_drag_accept), expander);
|
||||
g_signal_connect (dest, "drag-leave", G_CALLBACK (gtk_expander_drag_leave), expander);
|
||||
gtk_widget_add_controller (GTK_WIDGET (expander), GTK_EVENT_CONTROLLER (dest));
|
||||
|
||||
gesture = gtk_gesture_click_new ();
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture),
|
||||
@@ -544,12 +547,10 @@ expand_timeout (gpointer data)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_expander_drag_motion (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
gint x,
|
||||
gint y)
|
||||
gtk_expander_drag_accept (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
GtkExpander *expander)
|
||||
{
|
||||
GtkExpander *expander = GTK_EXPANDER (widget);
|
||||
GtkExpanderPrivate *priv = gtk_expander_get_instance_private (expander);
|
||||
|
||||
if (!priv->expanded && !priv->expand_timer)
|
||||
@@ -562,10 +563,10 @@ gtk_expander_drag_motion (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_expander_drag_leave (GtkWidget *widget,
|
||||
GdkDrop *drop)
|
||||
gtk_expander_drag_leave (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
GtkExpander *expander)
|
||||
{
|
||||
GtkExpander *expander = GTK_EXPANDER (widget);
|
||||
GtkExpanderPrivate *priv = gtk_expander_get_instance_private (expander);
|
||||
|
||||
if (priv->expand_timer)
|
||||
|
||||
+88
-56
@@ -37,7 +37,6 @@
|
||||
#include "gtkcellrendererpixbuf.h"
|
||||
#include "gtkcombobox.h"
|
||||
#include "gtkcssiconthemevalueprivate.h"
|
||||
#include "gtkdnd.h"
|
||||
#include "gtkdragdest.h"
|
||||
#include "gtkicontheme.h"
|
||||
#include "gtkimage.h"
|
||||
@@ -61,6 +60,7 @@
|
||||
#include "gtksettings.h"
|
||||
#include "gtkstylecontextprivate.h"
|
||||
#include "gtkbitmaskprivate.h"
|
||||
#include "gtkeventcontroller.h"
|
||||
|
||||
/**
|
||||
* SECTION:gtkfilechooserbutton
|
||||
@@ -267,9 +267,11 @@ static void gtk_file_chooser_button_finalize (GObject *ob
|
||||
|
||||
/* GtkWidget Functions */
|
||||
static void gtk_file_chooser_button_destroy (GtkWidget *widget);
|
||||
static void gtk_file_chooser_button_drag_data_received (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
GtkSelectionData *data);
|
||||
static gboolean gtk_file_chooser_button_drag_drop (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
int x,
|
||||
int y,
|
||||
GtkWidget *widget);
|
||||
static void gtk_file_chooser_button_show (GtkWidget *widget);
|
||||
static void gtk_file_chooser_button_hide (GtkWidget *widget);
|
||||
static void gtk_file_chooser_button_root (GtkWidget *widget);
|
||||
@@ -366,7 +368,6 @@ gtk_file_chooser_button_class_init (GtkFileChooserButtonClass * class)
|
||||
gobject_class->finalize = gtk_file_chooser_button_finalize;
|
||||
|
||||
widget_class->destroy = gtk_file_chooser_button_destroy;
|
||||
widget_class->drag_data_received = gtk_file_chooser_button_drag_data_received;
|
||||
widget_class->show = gtk_file_chooser_button_show;
|
||||
widget_class->hide = gtk_file_chooser_button_hide;
|
||||
widget_class->map = gtk_file_chooser_button_map;
|
||||
@@ -443,7 +444,9 @@ gtk_file_chooser_button_init (GtkFileChooserButton *button)
|
||||
GtkFileChooserButtonPrivate *priv = gtk_file_chooser_button_get_instance_private (button);
|
||||
GtkWidget *box;
|
||||
GtkWidget *icon;
|
||||
GdkContentFormatsBuilder *builder;
|
||||
GdkContentFormats *target_list;
|
||||
GtkDropTarget *dest;
|
||||
|
||||
priv->button = gtk_button_new ();
|
||||
g_signal_connect (priv->button, "clicked", G_CALLBACK (button_clicked_cb), button);
|
||||
@@ -495,13 +498,13 @@ gtk_file_chooser_button_init (GtkFileChooserButton *button)
|
||||
NULL, NULL);
|
||||
|
||||
/* DnD */
|
||||
target_list = gdk_content_formats_new (NULL, 0);
|
||||
target_list = gtk_content_formats_add_uri_targets (target_list);
|
||||
target_list = gtk_content_formats_add_text_targets (target_list);
|
||||
gtk_drag_dest_set (GTK_WIDGET (button),
|
||||
(GTK_DEST_DEFAULT_ALL),
|
||||
target_list,
|
||||
GDK_ACTION_COPY);
|
||||
builder = gdk_content_formats_builder_new ();
|
||||
gdk_content_formats_builder_add_gtype (builder, G_TYPE_STRING);
|
||||
gdk_content_formats_builder_add_gtype (builder, GDK_TYPE_FILE_LIST);
|
||||
target_list = gdk_content_formats_builder_free_to_formats (builder);
|
||||
dest = gtk_drop_target_new (target_list, GDK_ACTION_COPY);
|
||||
g_signal_connect (dest, "drag-drop", G_CALLBACK (gtk_file_chooser_button_drag_drop), button);
|
||||
gtk_widget_add_controller (GTK_WIDGET (button), GTK_EVENT_CONTROLLER (dest));
|
||||
gdk_content_formats_unref (target_list);
|
||||
}
|
||||
|
||||
@@ -1146,62 +1149,91 @@ dnd_select_folder_get_info_cb (GCancellable *cancellable,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_file_chooser_button_drag_data_received (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
GtkSelectionData *data)
|
||||
dnd_select_file (GtkFileChooserButton *button,
|
||||
GFile *file)
|
||||
{
|
||||
GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (widget);
|
||||
GtkFileChooserButtonPrivate *priv = gtk_file_chooser_button_get_instance_private (button);
|
||||
GFile *file;
|
||||
gchar *text;
|
||||
struct DndSelectFolderData *info;
|
||||
|
||||
if (GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->drag_data_received != NULL)
|
||||
GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->drag_data_received (widget,
|
||||
drop,
|
||||
data);
|
||||
info = g_new0 (struct DndSelectFolderData, 1);
|
||||
info->button = g_object_ref (button);
|
||||
info->i = 0;
|
||||
info->uris = g_new0 (char *, 2);
|
||||
info->selected = FALSE;
|
||||
info->file_system = priv->fs;
|
||||
g_object_get (priv->chooser, "action", &info->action, NULL);
|
||||
|
||||
if (widget == NULL || gtk_selection_data_get_length (data) < 0)
|
||||
return;
|
||||
info->file = g_object_ref (file);
|
||||
|
||||
if (gtk_selection_data_targets_include_uri (data))
|
||||
if (priv->dnd_select_folder_cancellable)
|
||||
g_cancellable_cancel (priv->dnd_select_folder_cancellable);
|
||||
|
||||
priv->dnd_select_folder_cancellable =
|
||||
_gtk_file_system_get_info (priv->fs, info->file,
|
||||
"standard::type",
|
||||
dnd_select_folder_get_info_cb, info);
|
||||
}
|
||||
|
||||
static void
|
||||
got_file (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (data);
|
||||
GdkDrop *drop = GDK_DROP (source);
|
||||
const GValue *value;
|
||||
|
||||
value = gdk_drop_read_value_finish (drop, result, NULL);
|
||||
if (value)
|
||||
{
|
||||
gchar **uris;
|
||||
struct DndSelectFolderData *info;
|
||||
GFile *file;
|
||||
|
||||
uris = gtk_selection_data_get_uris (data);
|
||||
|
||||
if (uris != NULL)
|
||||
{
|
||||
info = g_new0 (struct DndSelectFolderData, 1);
|
||||
info->button = g_object_ref (button);
|
||||
info->i = 0;
|
||||
info->uris = uris;
|
||||
info->selected = FALSE;
|
||||
info->file_system = priv->fs;
|
||||
g_object_get (priv->chooser, "action", &info->action, NULL);
|
||||
|
||||
info->file = g_file_new_for_uri (info->uris[info->i]);
|
||||
|
||||
if (priv->dnd_select_folder_cancellable)
|
||||
g_cancellable_cancel (priv->dnd_select_folder_cancellable);
|
||||
|
||||
priv->dnd_select_folder_cancellable =
|
||||
_gtk_file_system_get_info (priv->fs, info->file,
|
||||
"standard::type",
|
||||
dnd_select_folder_get_info_cb, info);
|
||||
}
|
||||
file = g_value_get_object (value);
|
||||
dnd_select_file (button, file);
|
||||
}
|
||||
else if (gtk_selection_data_targets_include_text (data))
|
||||
}
|
||||
|
||||
static void
|
||||
got_text (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (data);
|
||||
GdkDrop *drop = GDK_DROP (source);
|
||||
char *str;
|
||||
|
||||
str = gdk_drop_read_text_finish (drop, result, NULL);
|
||||
if (str)
|
||||
{
|
||||
text = (char*) gtk_selection_data_get_text (data);
|
||||
file = g_file_new_for_uri (text);
|
||||
gtk_file_chooser_select_file (GTK_FILE_CHOOSER (priv->chooser), file, NULL);
|
||||
GFile *file;
|
||||
|
||||
file = g_file_new_for_uri (str);
|
||||
dnd_select_file (button, file);
|
||||
g_object_unref (file);
|
||||
g_free (text);
|
||||
g_signal_emit (button, file_chooser_button_signals[FILE_SET], 0);
|
||||
}
|
||||
|
||||
gdk_drop_finish (drop, GDK_ACTION_COPY);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_file_chooser_button_drag_drop (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
int x,
|
||||
int y,
|
||||
GtkWidget *button)
|
||||
{
|
||||
if (gdk_drop_has_value (drop, G_TYPE_FILE))
|
||||
{
|
||||
gdk_drop_read_value_async (drop, G_TYPE_FILE, G_PRIORITY_DEFAULT, NULL, got_file, button);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gdk_drop_read_text_async (drop, NULL, got_text, button);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+33
-61
@@ -1982,25 +1982,26 @@ out:
|
||||
}
|
||||
|
||||
static void
|
||||
file_list_drag_data_received_cb (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
GtkSelectionData *selection_data,
|
||||
gpointer user_data)
|
||||
file_list_drag_data_received_cb (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (user_data);
|
||||
GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (impl);
|
||||
GtkDropTarget *dest = GTK_DROP_TARGET (source);
|
||||
GtkWidget *widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest));
|
||||
GdkDrop *drop = gtk_drop_target_get_drop (dest);
|
||||
GdkDrag *drag = gdk_drop_get_drag (drop);
|
||||
gchar **uris;
|
||||
char *uri;
|
||||
GFile *file;
|
||||
GtkSelectionData *selection_data;
|
||||
|
||||
selection_data = gtk_drop_target_read_selection_finish (dest, result, NULL);
|
||||
|
||||
/* Allow only drags from other widgets; see bug #533891. */
|
||||
if (gdk_drop_get_drag (drop) &&
|
||||
gtk_drag_get_source_widget (gdk_drop_get_drag (drop)) == widget)
|
||||
{
|
||||
g_signal_stop_emission_by_name (widget, "drag-data-received");
|
||||
return;
|
||||
}
|
||||
|
||||
if (drag && gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (drag)) == widget)
|
||||
return;
|
||||
|
||||
/* Parse the text/uri-list string, navigate to the first one */
|
||||
uris = gtk_selection_data_get_uris (selection_data);
|
||||
@@ -2025,60 +2026,34 @@ file_list_drag_data_received_cb (GtkWidget *widget,
|
||||
file_list_drag_data_received_get_info_cb,
|
||||
data);
|
||||
}
|
||||
|
||||
g_signal_stop_emission_by_name (widget, "drag-data-received");
|
||||
}
|
||||
|
||||
/* Don't do anything with the drag_drop signal */
|
||||
static gboolean
|
||||
file_list_drag_drop_cb (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
gint x,
|
||||
gint y,
|
||||
file_list_drag_drop_cb (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
int x,
|
||||
int y,
|
||||
GtkFileChooserWidget *impl)
|
||||
{
|
||||
g_signal_stop_emission_by_name (widget, "drag-drop");
|
||||
const char *target = g_intern_static_string ("text/uri-list");
|
||||
|
||||
gtk_drop_target_read_selection (dest, target, NULL, file_list_drag_data_received_cb, impl);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
file_list_drag_begin_cb (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
GtkFileChooserWidget *impl)
|
||||
{
|
||||
GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (impl);
|
||||
|
||||
gtk_places_sidebar_set_drop_targets_visible (GTK_PLACES_SIDEBAR (priv->places_sidebar),
|
||||
TRUE,
|
||||
drag);
|
||||
}
|
||||
|
||||
/* Disable the normal tree drag motion handler, it makes it look like you're
|
||||
dropping the dragged item onto a tree item */
|
||||
static gboolean
|
||||
file_list_drag_motion_cb (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
gint x,
|
||||
gint y,
|
||||
file_list_drag_accept_cb (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
GtkFileChooserWidget *impl)
|
||||
{
|
||||
g_signal_stop_emission_by_name (widget, "drag-motion");
|
||||
g_signal_stop_emission_by_name (dest, "accept");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
file_list_drag_end_cb (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (user_data);
|
||||
GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (impl);
|
||||
|
||||
gtk_places_sidebar_set_drop_targets_visible (GTK_PLACES_SIDEBAR (priv->places_sidebar),
|
||||
FALSE,
|
||||
drag);
|
||||
}
|
||||
|
||||
/* Sensitizes the "Copy file’s location" and other context menu items if there is actually
|
||||
* a selection active.
|
||||
*/
|
||||
@@ -8468,14 +8443,9 @@ gtk_file_chooser_widget_class_init (GtkFileChooserWidgetClass *class)
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, box);
|
||||
|
||||
/* And a *lot* of callbacks to bind ... */
|
||||
gtk_widget_class_bind_template_callback (widget_class, file_list_drag_drop_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, file_list_drag_data_received_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, list_popup_menu_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, file_list_query_tooltip_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, list_row_activated);
|
||||
gtk_widget_class_bind_template_callback (widget_class, file_list_drag_begin_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, file_list_drag_motion_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, file_list_drag_end_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, list_selection_changed);
|
||||
gtk_widget_class_bind_template_callback (widget_class, list_cursor_changed);
|
||||
gtk_widget_class_bind_template_callback (widget_class, browse_files_tree_view_keynav_failed_cb);
|
||||
@@ -8510,23 +8480,25 @@ post_process_ui (GtkFileChooserWidget *impl)
|
||||
GtkCellRenderer *cell;
|
||||
GList *cells;
|
||||
GFile *file;
|
||||
GtkDropTarget *dest;
|
||||
GdkContentFormats *formats;
|
||||
|
||||
/* Setup file list treeview */
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->browse_files_tree_view));
|
||||
gtk_tree_selection_set_select_function (selection,
|
||||
list_select_func,
|
||||
impl, NULL);
|
||||
formats = gdk_content_formats_new_for_gtype (GDK_TYPE_FILE_LIST);
|
||||
gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (priv->browse_files_tree_view),
|
||||
GDK_BUTTON1_MASK,
|
||||
NULL,
|
||||
formats,
|
||||
GDK_ACTION_COPY | GDK_ACTION_MOVE);
|
||||
gtk_drag_source_add_uri_targets (priv->browse_files_tree_view);
|
||||
|
||||
gtk_drag_dest_set (priv->browse_files_tree_view,
|
||||
GTK_DEST_DEFAULT_ALL,
|
||||
NULL,
|
||||
GDK_ACTION_COPY | GDK_ACTION_MOVE);
|
||||
gtk_drag_dest_add_uri_targets (priv->browse_files_tree_view);
|
||||
|
||||
dest = gtk_drop_target_new (formats, GDK_ACTION_COPY | GDK_ACTION_MOVE);
|
||||
g_signal_connect (dest, "accept", G_CALLBACK (file_list_drag_accept_cb), impl);
|
||||
g_signal_connect (dest, "drag-drop", G_CALLBACK (file_list_drag_drop_cb), impl);
|
||||
gtk_widget_add_controller (priv->browse_files_tree_view, GTK_EVENT_CONTROLLER (dest));
|
||||
gdk_content_formats_unref (formats);
|
||||
|
||||
/* File browser treemodel columns are shared between GtkFileChooser implementations,
|
||||
* so we don't set cell renderer attributes in GtkBuilder, but rather keep that
|
||||
|
||||
@@ -458,7 +458,7 @@ gtk_filter_list_model_augment (GtkRbTree *filter,
|
||||
* gtk_filter_list_model_new:
|
||||
* @model: the model to sort
|
||||
* @filter_func: (allow-none): filter function or %NULL to not filter items
|
||||
* @user_data: user data passed to @filter_func
|
||||
* @user_data: (closure): user data passed to @filter_func
|
||||
* @user_destroy: destroy notifier for @user_data
|
||||
*
|
||||
* Creates a new #GtkFilterListModel that will filter @model using the given
|
||||
@@ -511,7 +511,7 @@ gtk_filter_list_model_new_for_type (GType item_type)
|
||||
* gtk_filter_list_model_set_filter_func:
|
||||
* @self: a #GtkFilterListModel
|
||||
* @filter_func: (allow-none): filter function or %NULL to not filter items
|
||||
* @user_data: user data passed to @filter_func
|
||||
* @user_data: (closure): user data passed to @filter_func
|
||||
* @user_destroy: destroy notifier for @user_data
|
||||
*
|
||||
* Sets the function used to filter items. The function will be called for every
|
||||
|
||||
+5
-5
@@ -4045,7 +4045,7 @@ gtk_flow_box_check_model_compat (GtkFlowBox *box)
|
||||
* @box: a #GtkFlowBox
|
||||
* @model: (allow-none): the #GListModel to be bound to @box
|
||||
* @create_widget_func: a function that creates widgets for items
|
||||
* @user_data: user data passed to @create_widget_func
|
||||
* @user_data: (closure): user data passed to @create_widget_func
|
||||
* @user_data_free_func: function for freeing @user_data
|
||||
*
|
||||
* Binds @model to @box.
|
||||
@@ -4583,9 +4583,9 @@ gtk_flow_box_get_selection_mode (GtkFlowBox *box)
|
||||
/**
|
||||
* gtk_flow_box_set_filter_func:
|
||||
* @box: a #GtkFlowBox
|
||||
* @filter_func: (closure user_data) (allow-none): callback that
|
||||
* @filter_func: (allow-none): callback that
|
||||
* lets you filter which children to show
|
||||
* @user_data: user data passed to @filter_func
|
||||
* @user_data: (closure): user data passed to @filter_func
|
||||
* @destroy: destroy notifier for @user_data
|
||||
*
|
||||
* By setting a filter function on the @box one can decide dynamically
|
||||
@@ -4663,8 +4663,8 @@ gtk_flow_box_invalidate_filter (GtkFlowBox *box)
|
||||
/**
|
||||
* gtk_flow_box_set_sort_func:
|
||||
* @box: a #GtkFlowBox
|
||||
* @sort_func: (closure user_data) (allow-none): the sort function
|
||||
* @user_data: user data passed to @sort_func
|
||||
* @sort_func: (allow-none): the sort function
|
||||
* @user_data: (closure): user data passed to @sort_func
|
||||
* @destroy: destroy notifier for @user_data
|
||||
*
|
||||
* By setting a sort function on the @box, one can dynamically
|
||||
|
||||
@@ -407,7 +407,7 @@ gtk_font_chooser_set_show_preview_entry (GtkFontChooser *fontchooser,
|
||||
* gtk_font_chooser_set_filter_func:
|
||||
* @fontchooser: a #GtkFontChooser
|
||||
* @filter: (allow-none): a #GtkFontFilterFunc, or %NULL
|
||||
* @user_data: data to pass to @filter
|
||||
* @user_data: (closure): data to pass to @filter
|
||||
* @destroy: function to call to free @data when it is no longer needed
|
||||
*
|
||||
* Adds a filter function that decides which fonts to display
|
||||
|
||||
@@ -716,6 +716,8 @@ gtk_font_chooser_widget_dispose (GObject *object)
|
||||
GtkFontChooserWidget *self = GTK_FONT_CHOOSER_WIDGET (object);
|
||||
GtkFontChooserWidgetPrivate *priv = gtk_font_chooser_widget_get_instance_private (self);
|
||||
|
||||
if (priv->family_face_list)
|
||||
gtk_tree_view_set_model (GTK_TREE_VIEW (priv->family_face_list), NULL);
|
||||
g_clear_pointer (&priv->stack, gtk_widget_unparent);
|
||||
|
||||
G_OBJECT_CLASS (gtk_font_chooser_widget_parent_class)->dispose (object);
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include "gtkgesturelongpressprivate.h"
|
||||
#include "gtkgestureprivate.h"
|
||||
#include "gtkmarshalers.h"
|
||||
#include "gtkdnd.h"
|
||||
#include "gtkdragsource.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkmarshalers.h"
|
||||
|
||||
+1
-15
@@ -36,8 +36,6 @@
|
||||
struct _GtkIcon
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
GtkCssImageBuiltinType image;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GtkIcon, gtk_icon, GTK_TYPE_WIDGET)
|
||||
@@ -46,7 +44,6 @@ static void
|
||||
gtk_icon_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
GtkIcon *self = GTK_ICON (widget);
|
||||
GtkCssStyle *style = gtk_css_node_get_style (gtk_widget_get_css_node (widget));
|
||||
int width, height;
|
||||
|
||||
@@ -54,10 +51,7 @@ gtk_icon_snapshot (GtkWidget *widget,
|
||||
height = gtk_widget_get_height (widget);
|
||||
|
||||
if (width > 0 && height > 0)
|
||||
gtk_css_style_snapshot_icon (style,
|
||||
snapshot,
|
||||
width, height,
|
||||
self->image);
|
||||
gtk_css_style_snapshot_icon (style, snapshot, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -87,7 +81,6 @@ gtk_icon_class_init (GtkIconClass *klass)
|
||||
static void
|
||||
gtk_icon_init (GtkIcon *self)
|
||||
{
|
||||
self->image = GTK_CSS_IMAGE_BUILTIN_NONE;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
@@ -98,13 +91,6 @@ gtk_icon_new (const char *css_name)
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_icon_set_image (GtkIcon *self,
|
||||
GtkCssImageBuiltinType image)
|
||||
{
|
||||
self->image = image;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_icon_set_css_name (GtkIcon *self,
|
||||
const char *css_name)
|
||||
|
||||
@@ -31,9 +31,6 @@ G_DECLARE_FINAL_TYPE (GtkIcon, gtk_icon, GTK, ICON, GtkWidget)
|
||||
|
||||
GtkWidget * gtk_icon_new (const char *css_name);
|
||||
|
||||
void gtk_icon_set_image (GtkIcon *self,
|
||||
GtkCssImageBuiltinType image);
|
||||
|
||||
void gtk_icon_set_css_name (GtkIcon *self,
|
||||
const char *css_name);
|
||||
|
||||
|
||||
+4
-6
@@ -3638,7 +3638,6 @@ gtk_icon_info_load_symbolic_svg (GtkIconInfo *icon_info,
|
||||
gchar *width;
|
||||
gchar *height;
|
||||
char *escaped_file_data;
|
||||
gint symbolic_size;
|
||||
double alpha;
|
||||
gchar alphastr[G_ASCII_DTOSTR_BUF_SIZE];
|
||||
|
||||
@@ -3707,9 +3706,8 @@ gtk_icon_info_load_symbolic_svg (GtkIconInfo *icon_info,
|
||||
g_object_unref (pixbuf);
|
||||
}
|
||||
|
||||
symbolic_size = MAX (icon_info->symbolic_width, icon_info->symbolic_height);
|
||||
|
||||
GTK_NOTE (ICONTHEME,
|
||||
GTK_NOTE (ICONTHEME, {
|
||||
int symbolic_size = MAX (icon_info->symbolic_width, icon_info->symbolic_height);
|
||||
if (icon_info->dir_type == ICON_THEME_DIR_UNTHEMED)
|
||||
g_message ("Symbolic icon %s is not in an icon theme directory",
|
||||
icon_info->key.icon_names ? icon_info->key.icon_names[0] : icon_info->filename);
|
||||
@@ -3717,8 +3715,8 @@ gtk_icon_info_load_symbolic_svg (GtkIconInfo *icon_info,
|
||||
g_message ("Symbolic icon %s of size %d is in an icon theme directory of size %d",
|
||||
icon_info->key.icon_names ? icon_info->key.icon_names[0] : icon_info->filename,
|
||||
symbolic_size,
|
||||
icon_info->dir_size * icon_info->dir_scale)
|
||||
);
|
||||
icon_info->dir_size * icon_info->dir_scale);
|
||||
});
|
||||
|
||||
width = g_strdup_printf ("%d", icon_info->symbolic_width);
|
||||
height = g_strdup_printf ("%d", icon_info->symbolic_height);
|
||||
|
||||
+170
-194
@@ -30,7 +30,6 @@
|
||||
#include "gtkcellrenderertext.h"
|
||||
#include "gtkcombobox.h"
|
||||
#include "gtkcssnodeprivate.h"
|
||||
#include "gtkdnd.h"
|
||||
#include "gtkdragdest.h"
|
||||
#include "gtkdragsource.h"
|
||||
#include "gtkentry.h"
|
||||
@@ -48,6 +47,11 @@
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkwindow.h"
|
||||
#include "gtkeventcontrollerkey.h"
|
||||
#include "gtkdragsource.h"
|
||||
#include "gtkdragdest.h"
|
||||
#include "gtkdragicon.h"
|
||||
#include "gtkselectionprivate.h"
|
||||
#include "gtknative.h"
|
||||
|
||||
#include "a11y/gtkiconviewaccessibleprivate.h"
|
||||
|
||||
@@ -279,30 +283,28 @@ static void update_text_cell (GtkIco
|
||||
static void update_pixbuf_cell (GtkIconView *icon_view);
|
||||
|
||||
/* Source side drag signals */
|
||||
static void gtk_icon_view_drag_begin (GtkWidget *widget,
|
||||
GdkDrag *drag);
|
||||
static void gtk_icon_view_drag_end (GtkWidget *widget,
|
||||
GdkDrag *drag);
|
||||
static void gtk_icon_view_drag_data_get (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
GtkSelectionData *selection_data);
|
||||
static void gtk_icon_view_drag_data_delete (GtkWidget *widget,
|
||||
GdkDrag *drag);
|
||||
static void gtk_icon_view_dnd_finished_cb (GdkDrag *drag,
|
||||
GtkWidget *widget);
|
||||
static GBytes * gtk_icon_view_drag_data_get (const char *mime_type,
|
||||
gpointer data);
|
||||
|
||||
/* Target side drag signals */
|
||||
static void gtk_icon_view_drag_leave (GtkWidget *widget,
|
||||
GdkDrop *drop);
|
||||
static gboolean gtk_icon_view_drag_motion (GtkWidget *widget,
|
||||
static void gtk_icon_view_drag_leave (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
gint x,
|
||||
gint y);
|
||||
static gboolean gtk_icon_view_drag_drop (GtkWidget *widget,
|
||||
GtkIconView *icon_view);
|
||||
static void gtk_icon_view_drag_motion (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
gint x,
|
||||
gint y);
|
||||
static void gtk_icon_view_drag_data_received (GtkWidget *widget,
|
||||
int x,
|
||||
int y,
|
||||
GtkIconView *icon_view);
|
||||
static gboolean gtk_icon_view_drag_drop (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
GtkSelectionData *selection_data);
|
||||
int x,
|
||||
int y,
|
||||
GtkIconView *icon_view);
|
||||
static void gtk_icon_view_drag_data_received (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data);
|
||||
static gboolean gtk_icon_view_maybe_begin_drag (GtkIconView *icon_view,
|
||||
double x,
|
||||
double y,
|
||||
@@ -360,14 +362,6 @@ gtk_icon_view_class_init (GtkIconViewClass *klass)
|
||||
widget_class->measure = gtk_icon_view_measure;
|
||||
widget_class->size_allocate = gtk_icon_view_size_allocate;
|
||||
widget_class->snapshot = gtk_icon_view_snapshot;
|
||||
widget_class->drag_begin = gtk_icon_view_drag_begin;
|
||||
widget_class->drag_end = gtk_icon_view_drag_end;
|
||||
widget_class->drag_data_get = gtk_icon_view_drag_data_get;
|
||||
widget_class->drag_data_delete = gtk_icon_view_drag_data_delete;
|
||||
widget_class->drag_leave = gtk_icon_view_drag_leave;
|
||||
widget_class->drag_motion = gtk_icon_view_drag_motion;
|
||||
widget_class->drag_drop = gtk_icon_view_drag_drop;
|
||||
widget_class->drag_data_received = gtk_icon_view_drag_data_received;
|
||||
|
||||
container_class->remove = gtk_icon_view_remove;
|
||||
container_class->forall = gtk_icon_view_forall;
|
||||
@@ -1033,6 +1027,8 @@ gtk_icon_view_dispose (GObject *object)
|
||||
|
||||
g_clear_object (&priv->key_controller);
|
||||
|
||||
g_clear_pointer (&priv->source_formats, gdk_content_formats_unref);
|
||||
|
||||
G_OBJECT_CLASS (gtk_icon_view_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
@@ -1761,9 +1757,14 @@ gtk_icon_view_snapshot (GtkWidget *widget,
|
||||
break;
|
||||
}
|
||||
|
||||
gtk_snapshot_render_focus (snapshot, context,
|
||||
gtk_style_context_save_to_node (context, icon_view->priv->dndnode);
|
||||
gtk_style_context_set_state (context, gtk_style_context_get_state (context) | GTK_STATE_FLAG_DROP_ACTIVE);
|
||||
|
||||
gtk_snapshot_render_frame (snapshot, context,
|
||||
rect.x, rect.y,
|
||||
rect.width, rect.height);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
}
|
||||
|
||||
if (icon_view->priv->doing_rubberband)
|
||||
@@ -5712,35 +5713,6 @@ unset_reorderable (GtkIconView *icon_view)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_source_row (GdkDrag *drag,
|
||||
GtkTreeModel *model,
|
||||
GtkTreePath *source_row)
|
||||
{
|
||||
if (source_row)
|
||||
g_object_set_data_full (G_OBJECT (drag),
|
||||
I_("gtk-icon-view-source-row"),
|
||||
gtk_tree_row_reference_new (model, source_row),
|
||||
(GDestroyNotify) gtk_tree_row_reference_free);
|
||||
else
|
||||
g_object_set_data_full (G_OBJECT (drag),
|
||||
I_("gtk-icon-view-source-row"),
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static GtkTreePath*
|
||||
get_source_row (GdkDrag *drag)
|
||||
{
|
||||
GtkTreeRowReference *ref;
|
||||
|
||||
ref = g_object_get_data (G_OBJECT (drag), "gtk-icon-view-source-row");
|
||||
|
||||
if (ref)
|
||||
return gtk_tree_row_reference_get_path (ref);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkTreeRowReference *dest_row;
|
||||
@@ -5886,7 +5858,7 @@ drag_scroll_timeout (gpointer data)
|
||||
|
||||
static gboolean
|
||||
set_destination (GtkIconView *icon_view,
|
||||
GdkDrop *drop,
|
||||
GtkDropTarget *dest,
|
||||
gint x,
|
||||
gint y,
|
||||
GdkDragAction *suggested_action,
|
||||
@@ -5919,8 +5891,7 @@ set_destination (GtkIconView *icon_view,
|
||||
return FALSE; /* no longer a drop site */
|
||||
}
|
||||
|
||||
*target = gtk_drag_dest_find_target (widget, drop,
|
||||
gtk_drag_dest_get_target_list (widget));
|
||||
*target = gtk_drop_target_find_mimetype (dest);
|
||||
if (*target == NULL)
|
||||
return FALSE;
|
||||
|
||||
@@ -6030,11 +6001,14 @@ gtk_icon_view_maybe_begin_drag (GtkIconView *icon_view,
|
||||
double y,
|
||||
GdkDevice *device)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (icon_view);
|
||||
GdkDrag *drag;
|
||||
GtkTreePath *path = NULL;
|
||||
GtkTreeModel *model;
|
||||
gboolean retval = FALSE;
|
||||
GdkContentProvider *content;
|
||||
GdkPaintable *icon;
|
||||
GtkIconViewItem *item;
|
||||
GdkSurface *surface;
|
||||
GdkDrag *drag;
|
||||
|
||||
if (!icon_view->priv->source_set)
|
||||
goto out;
|
||||
@@ -6055,16 +6029,19 @@ gtk_icon_view_maybe_begin_drag (GtkIconView *icon_view,
|
||||
|
||||
icon_view->priv->pressed_button = -1;
|
||||
|
||||
path = gtk_icon_view_get_path_at_pos (icon_view,
|
||||
icon_view->priv->press_start_x,
|
||||
icon_view->priv->press_start_y);
|
||||
item = _gtk_icon_view_get_item_at_coords (icon_view,
|
||||
icon_view->priv->press_start_x,
|
||||
icon_view->priv->press_start_y,
|
||||
TRUE,
|
||||
NULL);
|
||||
|
||||
if (path == NULL)
|
||||
if (item == NULL)
|
||||
goto out;
|
||||
|
||||
path = gtk_tree_path_new_from_indices (item->index, -1);
|
||||
|
||||
if (!GTK_IS_TREE_DRAG_SOURCE (model) ||
|
||||
!gtk_tree_drag_source_row_draggable (GTK_TREE_DRAG_SOURCE (model),
|
||||
path))
|
||||
!gtk_tree_drag_source_row_draggable (GTK_TREE_DRAG_SOURCE (model), path))
|
||||
goto out;
|
||||
|
||||
/* FIXME Check whether we're a start button, if not return FALSE and
|
||||
@@ -6075,14 +6052,35 @@ gtk_icon_view_maybe_begin_drag (GtkIconView *icon_view,
|
||||
|
||||
retval = TRUE;
|
||||
|
||||
drag = gtk_drag_begin (widget,
|
||||
surface = gtk_native_get_surface (gtk_widget_get_native (GTK_WIDGET (icon_view)));
|
||||
|
||||
content = gdk_content_provider_new_with_formats (icon_view->priv->source_formats,
|
||||
gtk_icon_view_drag_data_get,
|
||||
icon_view);
|
||||
|
||||
drag = gdk_drag_begin (surface,
|
||||
device,
|
||||
gtk_drag_source_get_target_list (widget),
|
||||
icon_view->priv->source_actions,
|
||||
content,
|
||||
icon_view->priv->source_actions,
|
||||
icon_view->priv->press_start_x,
|
||||
icon_view->priv->press_start_y);
|
||||
|
||||
set_source_row (drag, model, path);
|
||||
g_object_unref (content);
|
||||
|
||||
g_signal_connect (drag, "dnd-finished", G_CALLBACK (gtk_icon_view_dnd_finished_cb), icon_view);
|
||||
|
||||
icon_view->priv->source_item = gtk_tree_row_reference_new (model, path);
|
||||
|
||||
x = icon_view->priv->press_start_x - item->cell_area.x + icon_view->priv->item_padding;
|
||||
y = icon_view->priv->press_start_y - item->cell_area.y + icon_view->priv->item_padding;
|
||||
|
||||
icon = gtk_icon_view_create_drag_icon (icon_view, path);
|
||||
gtk_drag_icon_set_from_paintable (drag, icon, x, y);
|
||||
g_object_unref (icon);
|
||||
|
||||
icon_view->priv->drag = drag;
|
||||
|
||||
g_object_unref (drag);
|
||||
|
||||
out:
|
||||
if (path)
|
||||
@@ -6092,71 +6090,28 @@ gtk_icon_view_maybe_begin_drag (GtkIconView *icon_view,
|
||||
}
|
||||
|
||||
/* Source side drag signals */
|
||||
static void
|
||||
gtk_icon_view_drag_begin (GtkWidget *widget,
|
||||
GdkDrag *drag)
|
||||
static GBytes *
|
||||
gtk_icon_view_drag_data_get (const char *mime_type,
|
||||
gpointer data)
|
||||
{
|
||||
GtkIconView *icon_view;
|
||||
GtkIconViewItem *item;
|
||||
GdkPaintable *icon;
|
||||
gint x, y;
|
||||
GtkTreePath *path;
|
||||
|
||||
icon_view = GTK_ICON_VIEW (widget);
|
||||
|
||||
/* if the user uses a custom DnD impl, we don't set the icon here */
|
||||
if (!icon_view->priv->dest_set && !icon_view->priv->source_set)
|
||||
return;
|
||||
|
||||
item = _gtk_icon_view_get_item_at_coords (icon_view,
|
||||
icon_view->priv->press_start_x,
|
||||
icon_view->priv->press_start_y,
|
||||
TRUE,
|
||||
NULL);
|
||||
|
||||
g_return_if_fail (item != NULL);
|
||||
|
||||
x = icon_view->priv->press_start_x - item->cell_area.x + icon_view->priv->item_padding;
|
||||
y = icon_view->priv->press_start_y - item->cell_area.y + icon_view->priv->item_padding;
|
||||
|
||||
path = gtk_tree_path_new_from_indices (item->index, -1);
|
||||
icon = gtk_icon_view_create_drag_icon (icon_view, path);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
gtk_drag_set_icon_paintable (drag, icon, x, y);
|
||||
|
||||
g_object_unref (icon);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_view_drag_end (GtkWidget *widget,
|
||||
GdkDrag *drag)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_view_drag_data_get (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
GtkSelectionData *selection_data)
|
||||
{
|
||||
GtkIconView *icon_view;
|
||||
GtkIconView *icon_view = data;
|
||||
GtkTreeModel *model;
|
||||
GtkTreePath *source_row;
|
||||
GtkSelectionData sdata = { 0, };
|
||||
|
||||
sdata.target = g_intern_string (mime_type);
|
||||
|
||||
icon_view = GTK_ICON_VIEW (widget);
|
||||
model = gtk_icon_view_get_model (icon_view);
|
||||
|
||||
if (model == NULL)
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
if (!icon_view->priv->source_set)
|
||||
return;
|
||||
|
||||
source_row = get_source_row (drag);
|
||||
return NULL;
|
||||
|
||||
source_row = gtk_tree_row_reference_get_path (icon_view->priv->source_item);
|
||||
if (source_row == NULL)
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
/* We can implement the GTK_TREE_MODEL_ROW target generically for
|
||||
* any model; for DragSource models there are some other formats
|
||||
@@ -6164,29 +6119,31 @@ gtk_icon_view_drag_data_get (GtkWidget *widget,
|
||||
*/
|
||||
|
||||
if (GTK_IS_TREE_DRAG_SOURCE (model) &&
|
||||
gtk_tree_drag_source_drag_data_get (GTK_TREE_DRAG_SOURCE (model),
|
||||
source_row,
|
||||
selection_data))
|
||||
gtk_tree_drag_source_drag_data_get (GTK_TREE_DRAG_SOURCE (model), source_row, &sdata))
|
||||
goto done;
|
||||
|
||||
/* If drag_data_get does nothing, try providing row data. */
|
||||
if (gtk_selection_data_get_target (selection_data) == g_intern_static_string ("GTK_TREE_MODEL_ROW"))
|
||||
gtk_tree_set_row_drag_data (selection_data,
|
||||
model,
|
||||
source_row);
|
||||
if (gtk_selection_data_get_target (&sdata) == g_intern_static_string ("GTK_TREE_MODEL_ROW"))
|
||||
gtk_tree_set_row_drag_data (&sdata, model, source_row);
|
||||
|
||||
done:
|
||||
gtk_tree_path_free (source_row);
|
||||
|
||||
return g_bytes_new_take ((gpointer)gtk_selection_data_get_data (&sdata),
|
||||
gtk_selection_data_get_length (&sdata));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_view_drag_data_delete (GtkWidget *widget,
|
||||
GdkDrag *drag)
|
||||
gtk_icon_view_dnd_finished_cb (GdkDrag *drag,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GtkTreeModel *model;
|
||||
GtkIconView *icon_view;
|
||||
GtkTreePath *source_row;
|
||||
|
||||
if (gdk_drag_get_selected_action (drag) != GDK_ACTION_MOVE)
|
||||
return;
|
||||
|
||||
icon_view = GTK_ICON_VIEW (widget);
|
||||
model = gtk_icon_view_get_model (icon_view);
|
||||
|
||||
@@ -6196,28 +6153,24 @@ gtk_icon_view_drag_data_delete (GtkWidget *widget,
|
||||
if (!icon_view->priv->source_set)
|
||||
return;
|
||||
|
||||
source_row = get_source_row (drag);
|
||||
|
||||
source_row = gtk_tree_row_reference_get_path (icon_view->priv->source_item);
|
||||
if (source_row == NULL)
|
||||
return;
|
||||
|
||||
gtk_tree_drag_source_drag_data_delete (GTK_TREE_DRAG_SOURCE (model),
|
||||
source_row);
|
||||
gtk_tree_drag_source_drag_data_delete (GTK_TREE_DRAG_SOURCE (model), source_row);
|
||||
|
||||
gtk_tree_path_free (source_row);
|
||||
|
||||
set_source_row (drag, NULL, NULL);
|
||||
g_clear_pointer (&icon_view->priv->source_item, gtk_tree_row_reference_free);
|
||||
icon_view->priv->drag = NULL;
|
||||
}
|
||||
|
||||
/* Target side drag signals */
|
||||
static void
|
||||
gtk_icon_view_drag_leave (GtkWidget *widget,
|
||||
GdkDrop *drop)
|
||||
gtk_icon_view_drag_leave (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
GtkIconView *icon_view)
|
||||
{
|
||||
GtkIconView *icon_view;
|
||||
|
||||
icon_view = GTK_ICON_VIEW (widget);
|
||||
|
||||
/* unset any highlight row */
|
||||
gtk_icon_view_set_drag_dest_item (icon_view,
|
||||
NULL,
|
||||
@@ -6226,26 +6179,24 @@ gtk_icon_view_drag_leave (GtkWidget *widget,
|
||||
remove_scroll_timeout (icon_view);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_icon_view_drag_motion (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
gint x,
|
||||
gint y)
|
||||
static void
|
||||
gtk_icon_view_drag_motion (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
int x,
|
||||
int y,
|
||||
GtkIconView *icon_view)
|
||||
{
|
||||
GtkTreePath *path = NULL;
|
||||
GtkIconViewDropPosition pos;
|
||||
GtkIconView *icon_view;
|
||||
GdkDragAction suggested_action = 0;
|
||||
GdkAtom target;
|
||||
gboolean empty;
|
||||
|
||||
icon_view = GTK_ICON_VIEW (widget);
|
||||
|
||||
if (!set_destination (icon_view, drop, x, y, &suggested_action, &target))
|
||||
return FALSE;
|
||||
|
||||
icon_view->priv->event_last_x = x;
|
||||
icon_view->priv->event_last_y = y;
|
||||
if (!set_destination (icon_view, dest, x, y, &suggested_action, &target))
|
||||
{
|
||||
gdk_drop_status (drop, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_icon_view_get_drag_dest_item (icon_view, &path, &pos);
|
||||
|
||||
@@ -6271,7 +6222,7 @@ gtk_icon_view_drag_motion (GtkWidget *widget,
|
||||
* determining whether to accept the drop
|
||||
*/
|
||||
set_status_pending (drop, suggested_action);
|
||||
gtk_drag_get_data (widget, drop, target);
|
||||
gtk_drop_target_read_selection (dest, target, NULL, gtk_icon_view_drag_data_received, icon_view);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -6282,27 +6233,24 @@ gtk_icon_view_drag_motion (GtkWidget *widget,
|
||||
|
||||
if (path)
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_icon_view_drag_drop (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
gint x,
|
||||
gint y)
|
||||
gtk_icon_view_drag_drop (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
int x,
|
||||
int y,
|
||||
GtkIconView *icon_view)
|
||||
{
|
||||
GtkIconView *icon_view;
|
||||
GtkTreePath *path;
|
||||
GdkDragAction suggested_action = 0;
|
||||
GdkAtom target = NULL;
|
||||
GtkTreeModel *model;
|
||||
gboolean drop_append_mode;
|
||||
|
||||
icon_view = GTK_ICON_VIEW (widget);
|
||||
model = gtk_icon_view_get_model (icon_view);
|
||||
|
||||
remove_scroll_timeout (GTK_ICON_VIEW (widget));
|
||||
remove_scroll_timeout (icon_view);
|
||||
|
||||
if (!icon_view->priv->dest_set)
|
||||
return FALSE;
|
||||
@@ -6310,7 +6258,7 @@ gtk_icon_view_drag_drop (GtkWidget *widget,
|
||||
if (!check_model_dnd (model, GTK_TYPE_TREE_DRAG_DEST, "drag-drop"))
|
||||
return FALSE;
|
||||
|
||||
if (!set_destination (icon_view, drop, x, y, &suggested_action, &target))
|
||||
if (!set_destination (icon_view, dest, x, y, &suggested_action, &target))
|
||||
return FALSE;
|
||||
|
||||
path = get_logical_destination (icon_view, &drop_append_mode);
|
||||
@@ -6333,7 +6281,7 @@ gtk_icon_view_drag_drop (GtkWidget *widget,
|
||||
|
||||
if (target != NULL)
|
||||
{
|
||||
gtk_drag_get_data (widget, drop, target);
|
||||
gtk_drop_target_read_selection (dest, target, NULL, gtk_icon_view_drag_data_received, icon_view);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
@@ -6341,16 +6289,16 @@ gtk_icon_view_drag_drop (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static GdkDragAction
|
||||
gtk_icon_view_get_action (GtkWidget *treeview,
|
||||
gtk_icon_view_get_action (GtkWidget *widget,
|
||||
GdkDrop *drop)
|
||||
{
|
||||
GtkIconView *iconview = GTK_ICON_VIEW (widget);
|
||||
GdkDrag *drag = gdk_drop_get_drag (drop);
|
||||
GtkWidget *source_widget = gtk_drag_get_source_widget (drag);
|
||||
GdkDragAction actions;
|
||||
|
||||
actions = gdk_drop_get_actions (drop);
|
||||
|
||||
if (source_widget == treeview &&
|
||||
if (drag == iconview->priv->drag &&
|
||||
actions & GDK_ACTION_MOVE)
|
||||
return GDK_ACTION_MOVE;
|
||||
|
||||
@@ -6367,25 +6315,31 @@ gtk_icon_view_get_action (GtkWidget *treeview,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_view_drag_data_received (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
GtkSelectionData *selection_data)
|
||||
gtk_icon_view_drag_data_received (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GtkDropTarget *dest = GTK_DROP_TARGET (source);
|
||||
GtkIconView *icon_view = data;
|
||||
GdkDrop *drop = gtk_drop_target_get_drop (dest);
|
||||
GtkTreePath *path;
|
||||
GtkTreeModel *model;
|
||||
GtkIconView *icon_view;
|
||||
GtkTreePath *dest_row;
|
||||
GdkDragAction suggested_action;
|
||||
gboolean drop_append_mode;
|
||||
|
||||
icon_view = GTK_ICON_VIEW (widget);
|
||||
GtkSelectionData *selection_data;
|
||||
|
||||
selection_data = gtk_drop_target_read_selection_finish (dest, result, NULL);
|
||||
if (!selection_data)
|
||||
return;
|
||||
|
||||
model = gtk_icon_view_get_model (icon_view);
|
||||
|
||||
if (!check_model_dnd (model, GTK_TYPE_TREE_DRAG_DEST, "drag-data-received"))
|
||||
return;
|
||||
goto out;
|
||||
|
||||
if (!icon_view->priv->dest_set)
|
||||
return;
|
||||
goto out;
|
||||
|
||||
suggested_action = get_status_pending (drop);
|
||||
|
||||
@@ -6419,18 +6373,18 @@ gtk_icon_view_drag_data_received (GtkWidget *widget,
|
||||
gtk_icon_view_set_drag_dest_item (icon_view,
|
||||
NULL,
|
||||
GTK_ICON_VIEW_DROP_LEFT);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
dest_row = get_dest_row (drop);
|
||||
|
||||
if (dest_row == NULL)
|
||||
return;
|
||||
goto out;
|
||||
|
||||
if (gtk_selection_data_get_length (selection_data) >= 0)
|
||||
{
|
||||
suggested_action = gtk_icon_view_get_action (widget, drop);
|
||||
suggested_action = gtk_icon_view_get_action (GTK_WIDGET (icon_view), drop);
|
||||
|
||||
if (suggested_action &&
|
||||
!gtk_tree_drag_dest_drag_data_received (GTK_TREE_DRAG_DEST (model),
|
||||
@@ -6445,9 +6399,13 @@ gtk_icon_view_drag_data_received (GtkWidget *widget,
|
||||
|
||||
/* drop dest_row */
|
||||
set_dest_row (drop, NULL, NULL, FALSE, FALSE);
|
||||
|
||||
out:
|
||||
gtk_selection_data_free (selection_data);
|
||||
}
|
||||
|
||||
/* Drag-and-Drop support */
|
||||
|
||||
/**
|
||||
* gtk_icon_view_enable_model_drag_source:
|
||||
* @icon_view: a #GtkIconView
|
||||
@@ -6467,9 +6425,7 @@ gtk_icon_view_enable_model_drag_source (GtkIconView *icon_view,
|
||||
{
|
||||
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
|
||||
|
||||
gtk_drag_source_set (GTK_WIDGET (icon_view), 0, formats, actions);
|
||||
|
||||
icon_view->priv->start_button_mask = start_button_mask;
|
||||
icon_view->priv->source_formats = gdk_content_formats_ref (formats);
|
||||
icon_view->priv->source_actions = actions;
|
||||
|
||||
icon_view->priv->source_set = TRUE;
|
||||
@@ -6486,21 +6442,37 @@ gtk_icon_view_enable_model_drag_source (GtkIconView *icon_view,
|
||||
*
|
||||
* Turns @icon_view into a drop destination for automatic DND. Calling this
|
||||
* method sets #GtkIconView:reorderable to %FALSE.
|
||||
*
|
||||
* Returns: (transfer none): the drop target that was attached
|
||||
**/
|
||||
void
|
||||
GtkDropTarget *
|
||||
gtk_icon_view_enable_model_drag_dest (GtkIconView *icon_view,
|
||||
GdkContentFormats *formats,
|
||||
GdkDragAction actions)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
|
||||
g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), NULL);
|
||||
GtkCssNode *widget_node;
|
||||
|
||||
gtk_drag_dest_set (GTK_WIDGET (icon_view), 0, formats, actions);
|
||||
icon_view->priv->dest = gtk_drop_target_new (formats, actions);
|
||||
g_signal_connect (icon_view->priv->dest, "drag-leave", G_CALLBACK (gtk_icon_view_drag_leave), icon_view);
|
||||
g_signal_connect (icon_view->priv->dest, "drag-motion", G_CALLBACK (gtk_icon_view_drag_motion), icon_view);
|
||||
g_signal_connect (icon_view->priv->dest, "drag-drop", G_CALLBACK (gtk_icon_view_drag_drop), icon_view);
|
||||
gtk_widget_add_controller (GTK_WIDGET (icon_view), GTK_EVENT_CONTROLLER (icon_view->priv->dest));
|
||||
|
||||
icon_view->priv->dest_actions = actions;
|
||||
|
||||
icon_view->priv->dest_set = TRUE;
|
||||
|
||||
unset_reorderable (icon_view);
|
||||
|
||||
widget_node = gtk_widget_get_css_node (GTK_WIDGET (icon_view));
|
||||
icon_view->priv->dndnode = gtk_css_node_new ();
|
||||
gtk_css_node_set_name (icon_view->priv->dndnode, I_("dndtarget"));
|
||||
gtk_css_node_set_parent (icon_view->priv->dndnode, widget_node);
|
||||
gtk_css_node_set_state (icon_view->priv->dndnode, gtk_css_node_get_state (widget_node));
|
||||
g_object_unref (icon_view->priv->dndnode);
|
||||
|
||||
return icon_view->priv->dest;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -6517,7 +6489,7 @@ gtk_icon_view_unset_model_drag_source (GtkIconView *icon_view)
|
||||
|
||||
if (icon_view->priv->source_set)
|
||||
{
|
||||
gtk_drag_source_unset (GTK_WIDGET (icon_view));
|
||||
g_clear_pointer (&icon_view->priv->source_formats, gdk_content_formats_unref);
|
||||
icon_view->priv->source_set = FALSE;
|
||||
}
|
||||
|
||||
@@ -6538,8 +6510,12 @@ gtk_icon_view_unset_model_drag_dest (GtkIconView *icon_view)
|
||||
|
||||
if (icon_view->priv->dest_set)
|
||||
{
|
||||
gtk_drag_dest_unset (GTK_WIDGET (icon_view));
|
||||
gtk_widget_remove_controller (GTK_WIDGET (icon_view), GTK_EVENT_CONTROLLER (icon_view->priv->dest));
|
||||
icon_view->priv->dest = NULL;
|
||||
icon_view->priv->dest_set = FALSE;
|
||||
|
||||
gtk_css_node_set_parent (icon_view->priv->dndnode, NULL);
|
||||
icon_view->priv->dndnode = NULL;
|
||||
}
|
||||
|
||||
unset_reorderable (icon_view);
|
||||
|
||||
+3
-1
@@ -28,6 +28,8 @@
|
||||
#include <gtk/gtkcellarea.h>
|
||||
#include <gtk/gtkselection.h>
|
||||
#include <gtk/gtktooltip.h>
|
||||
#include <gtk/gtkdragsource.h>
|
||||
#include <gtk/gtkdragdest.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -218,7 +220,7 @@ void gtk_icon_view_enable_model_drag_source (GtkIconView
|
||||
GdkContentFormats *formats,
|
||||
GdkDragAction actions);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_icon_view_enable_model_drag_dest (GtkIconView *icon_view,
|
||||
GtkDropTarget * gtk_icon_view_enable_model_drag_dest (GtkIconView *icon_view,
|
||||
GdkContentFormats *formats,
|
||||
GdkDragAction actions);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "gtk/gtkcssnodeprivate.h"
|
||||
#include "gtk/gtkgestureclick.h"
|
||||
#include "gtk/gtkeventcontrollermotion.h"
|
||||
#include "gtk/gtkdragsource.h"
|
||||
|
||||
#ifndef __GTK_ICON_VIEW_PRIVATE_H__
|
||||
#define __GTK_ICON_VIEW_PRIVATE_H__
|
||||
@@ -132,9 +133,16 @@ struct _GtkIconViewPrivate
|
||||
gint press_start_x;
|
||||
gint press_start_y;
|
||||
|
||||
GdkContentFormats *source_formats;
|
||||
GtkDropTarget *dest;
|
||||
GtkCssNode *dndnode;
|
||||
|
||||
GdkDrag *drag;
|
||||
|
||||
GdkDragAction source_actions;
|
||||
GdkDragAction dest_actions;
|
||||
|
||||
GtkTreeRowReference *source_item;
|
||||
GtkTreeRowReference *dest_item;
|
||||
GtkIconViewDropPosition dest_pos;
|
||||
|
||||
|
||||
@@ -592,7 +592,8 @@ gtk_im_context_wayland_get_preedit_string (GtkIMContext *context,
|
||||
if (str)
|
||||
*str = g_strdup (preedit_str);
|
||||
if (cursor_pos)
|
||||
*cursor_pos = context_wayland->current_preedit.cursor_begin;
|
||||
*cursor_pos = g_utf8_strlen (preedit_str,
|
||||
context_wayland->current_preedit.cursor_begin);
|
||||
|
||||
if (attrs)
|
||||
{
|
||||
|
||||
+22
-82
@@ -32,7 +32,6 @@
|
||||
#include "gtkcssnodeprivate.h"
|
||||
#include "gtkcssshadowsvalueprivate.h"
|
||||
#include "gtkcssstylepropertyprivate.h"
|
||||
#include "gtkdnd.h"
|
||||
#include "gtkeventcontrollermotion.h"
|
||||
#include "gtkgesturedrag.h"
|
||||
#include "gtkgestureclick.h"
|
||||
@@ -54,6 +53,8 @@
|
||||
#include "gtkwindow.h"
|
||||
#include "gtkpopovermenu.h"
|
||||
#include "gtknative.h"
|
||||
#include "gtkdragsource.h"
|
||||
#include "gtkdragicon.h"
|
||||
|
||||
#include "a11y/gtklabelaccessibleprivate.h"
|
||||
|
||||
@@ -501,9 +502,6 @@ static gboolean gtk_label_mnemonic_activate (GtkWidget *widget,
|
||||
static void gtk_label_setup_mnemonic (GtkLabel *label,
|
||||
GtkWidget *toplevel,
|
||||
guint last_key);
|
||||
static void gtk_label_drag_data_get (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
GtkSelectionData *selection_data);
|
||||
|
||||
static void gtk_label_buildable_interface_init (GtkBuildableIface *iface);
|
||||
static gboolean gtk_label_buildable_custom_tag_start (GtkBuildable *buildable,
|
||||
@@ -652,7 +650,6 @@ gtk_label_class_init (GtkLabelClass *class)
|
||||
widget_class->unroot = gtk_label_unroot;
|
||||
widget_class->mnemonic_activate = gtk_label_mnemonic_activate;
|
||||
widget_class->popup_menu = gtk_label_popup_menu;
|
||||
widget_class->drag_data_get = gtk_label_drag_data_get;
|
||||
widget_class->grab_focus = gtk_label_grab_focus;
|
||||
widget_class->focus = gtk_label_focus;
|
||||
widget_class->get_request_mode = gtk_label_get_request_mode;
|
||||
@@ -4597,16 +4594,10 @@ connect_mnemonics_visible_notify (GtkLabel *label)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
drag_begin_cb (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
gpointer data)
|
||||
static GdkPaintable *
|
||||
get_selection_paintable (GtkLabel *label)
|
||||
{
|
||||
GtkLabel *label = GTK_LABEL (widget);
|
||||
GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
|
||||
GdkPaintable *paintable = NULL;
|
||||
|
||||
g_signal_handlers_disconnect_by_func (widget, drag_begin_cb, NULL);
|
||||
|
||||
if ((priv->select_info->selection_anchor !=
|
||||
priv->select_info->selection_end) &&
|
||||
@@ -4628,20 +4619,10 @@ drag_begin_cb (GtkWidget *widget,
|
||||
if (start > len)
|
||||
start = len;
|
||||
|
||||
paintable = gtk_text_util_create_drag_icon (widget,
|
||||
priv->text + start,
|
||||
end - start);
|
||||
return gtk_text_util_create_drag_icon (GTK_WIDGET (label), priv->text + start, end - start);
|
||||
}
|
||||
|
||||
if (paintable)
|
||||
{
|
||||
gtk_drag_set_icon_paintable (drag, paintable, 0, 0);
|
||||
g_object_unref (paintable);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_drag_set_icon_default (drag);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -4734,27 +4715,27 @@ gtk_label_drag_gesture_update (GtkGestureDrag *gesture,
|
||||
|
||||
if (info->in_drag)
|
||||
{
|
||||
if (gtk_drag_check_threshold (widget,
|
||||
info->drag_start_x,
|
||||
info->drag_start_y,
|
||||
x, y))
|
||||
if (gtk_drag_check_threshold (widget, info->drag_start_x, info->drag_start_y, x, y))
|
||||
{
|
||||
GdkContentFormats *target_list = gdk_content_formats_new (NULL, 0);
|
||||
GdkDrag *drag;
|
||||
GdkSurface *surface;
|
||||
GdkDevice *device;
|
||||
|
||||
target_list = gtk_content_formats_add_text_targets (target_list);
|
||||
surface = gtk_native_get_surface (gtk_widget_get_native (widget));
|
||||
device = gtk_gesture_get_device (GTK_GESTURE (gesture));
|
||||
|
||||
g_signal_connect (widget, "drag-begin",
|
||||
G_CALLBACK (drag_begin_cb), NULL);
|
||||
gtk_drag_begin (widget,
|
||||
gtk_gesture_get_device (GTK_GESTURE (gesture)),
|
||||
target_list,
|
||||
GDK_ACTION_COPY,
|
||||
info->drag_start_x,
|
||||
info->drag_start_y);
|
||||
drag = gdk_drag_begin (surface,
|
||||
device,
|
||||
info->provider,
|
||||
GDK_ACTION_COPY,
|
||||
info->drag_start_x,
|
||||
info->drag_start_y);
|
||||
|
||||
gtk_drag_icon_set_from_paintable (drag, get_selection_paintable (label), 0, 0);
|
||||
|
||||
g_object_unref (drag);
|
||||
|
||||
info->in_drag = FALSE;
|
||||
|
||||
gdk_content_formats_unref (target_list);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -5140,47 +5121,6 @@ gtk_label_get_selectable (GtkLabel *label)
|
||||
return priv->select_info && priv->select_info->selectable;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_label_set_selection_text (GtkLabel *label,
|
||||
GtkSelectionData *selection_data)
|
||||
{
|
||||
GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
|
||||
|
||||
if (priv->select_info &&
|
||||
(priv->select_info->selection_anchor !=
|
||||
priv->select_info->selection_end) &&
|
||||
priv->text)
|
||||
{
|
||||
gint start, end;
|
||||
gint len;
|
||||
|
||||
start = MIN (priv->select_info->selection_anchor,
|
||||
priv->select_info->selection_end);
|
||||
end = MAX (priv->select_info->selection_anchor,
|
||||
priv->select_info->selection_end);
|
||||
|
||||
len = strlen (priv->text);
|
||||
|
||||
if (end > len)
|
||||
end = len;
|
||||
|
||||
if (start > len)
|
||||
start = len;
|
||||
|
||||
gtk_selection_data_set_text (selection_data,
|
||||
priv->text + start,
|
||||
end - start);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_label_drag_data_get (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
GtkSelectionData *selection_data)
|
||||
{
|
||||
gtk_label_set_selection_text (GTK_LABEL (widget), selection_data);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_label_select_region_index (GtkLabel *label,
|
||||
gint anchor_index,
|
||||
|
||||
+78
-36
@@ -124,10 +124,6 @@ static void gtk_link_button_set_property (GObject *object,
|
||||
GParamSpec *pspec);
|
||||
static void gtk_link_button_clicked (GtkButton *button);
|
||||
static gboolean gtk_link_button_popup_menu (GtkWidget *widget);
|
||||
static void gtk_link_button_drag_data_get_cb (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
GtkSelectionData *selection,
|
||||
gpointer user_data);
|
||||
static gboolean gtk_link_button_query_tooltip_cb (GtkWidget *widget,
|
||||
gint x,
|
||||
gint y,
|
||||
@@ -251,31 +247,97 @@ gtk_link_button_get_menu_model (void)
|
||||
return G_MENU_MODEL (menu);
|
||||
}
|
||||
|
||||
#define GTK_TYPE_LINK_CONTENT (gtk_link_content_get_type ())
|
||||
#define GTK_LINK_CONTENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_LINK_CONTENT, GtkLinkContent))
|
||||
|
||||
typedef struct _GtkLinkContent GtkLinkContent;
|
||||
typedef struct _GtkLinkContentClass GtkLinkContentClass;
|
||||
|
||||
struct _GtkLinkContent
|
||||
{
|
||||
GdkContentProvider parent;
|
||||
GtkLinkButton *link;
|
||||
};
|
||||
|
||||
struct _GtkLinkContentClass
|
||||
{
|
||||
GdkContentProviderClass parent_class;
|
||||
};
|
||||
|
||||
GType gtk_link_content_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_DEFINE_TYPE (GtkLinkContent, gtk_link_content, GDK_TYPE_CONTENT_PROVIDER)
|
||||
|
||||
static GdkContentFormats *
|
||||
gtk_link_content_ref_formats (GdkContentProvider *provider)
|
||||
{
|
||||
GtkLinkContent *content = GTK_LINK_CONTENT (provider);
|
||||
|
||||
if (content->link)
|
||||
return gdk_content_formats_union (gdk_content_formats_new_for_gtype (G_TYPE_STRING),
|
||||
gdk_content_formats_new (link_drop_types, G_N_ELEMENTS (link_drop_types)));
|
||||
else
|
||||
return gdk_content_formats_new (NULL, 0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_link_content_get_value (GdkContentProvider *provider,
|
||||
GValue *value,
|
||||
GError **error)
|
||||
{
|
||||
GtkLinkContent *content = GTK_LINK_CONTENT (provider);
|
||||
|
||||
if (G_VALUE_HOLDS (value, G_TYPE_STRING) &&
|
||||
content->link != NULL)
|
||||
{
|
||||
GtkLinkButtonPrivate *priv = gtk_link_button_get_instance_private (content->link);
|
||||
char *uri;
|
||||
|
||||
uri = g_strdup_printf ("%s\r\n", priv->uri);
|
||||
g_value_set_string (value, uri);
|
||||
g_free (uri);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return GDK_CONTENT_PROVIDER_CLASS (gtk_link_content_parent_class)->get_value (provider, value, error);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_link_content_class_init (GtkLinkContentClass *class)
|
||||
{
|
||||
GdkContentProviderClass *provider_class = GDK_CONTENT_PROVIDER_CLASS (class);
|
||||
|
||||
provider_class->ref_formats = gtk_link_content_ref_formats;
|
||||
provider_class->get_value = gtk_link_content_get_value;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_link_content_init (GtkLinkContent *content)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_link_button_init (GtkLinkButton *link_button)
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
GdkContentFormats *targets;
|
||||
GtkGesture *gesture;
|
||||
GdkContentProvider *content;
|
||||
GtkDragSource *source;
|
||||
|
||||
gtk_button_set_relief (GTK_BUTTON (link_button), GTK_RELIEF_NONE);
|
||||
gtk_widget_set_state_flags (GTK_WIDGET (link_button), GTK_STATE_FLAG_LINK, FALSE);
|
||||
gtk_widget_set_has_tooltip (GTK_WIDGET (link_button), TRUE);
|
||||
|
||||
g_signal_connect (link_button, "drag-data-get",
|
||||
G_CALLBACK (gtk_link_button_drag_data_get_cb), NULL);
|
||||
|
||||
g_signal_connect (link_button, "query-tooltip",
|
||||
G_CALLBACK (gtk_link_button_query_tooltip_cb), NULL);
|
||||
|
||||
/* enable drag source */
|
||||
targets = gdk_content_formats_new (link_drop_types, G_N_ELEMENTS (link_drop_types));
|
||||
gtk_drag_source_set (GTK_WIDGET (link_button),
|
||||
GDK_BUTTON1_MASK,
|
||||
targets,
|
||||
GDK_ACTION_COPY);
|
||||
gdk_content_formats_unref (targets);
|
||||
gtk_drag_source_set_icon_name (GTK_WIDGET (link_button), "text-x-generic");
|
||||
source = gtk_drag_source_new ();
|
||||
content = g_object_new (GTK_TYPE_LINK_CONTENT, NULL);
|
||||
GTK_LINK_CONTENT (content)->link = link_button;
|
||||
gtk_drag_source_set_content (source, content);
|
||||
g_object_unref (content);
|
||||
gtk_widget_add_controller (GTK_WIDGET (link_button), GTK_EVENT_CONTROLLER (source));
|
||||
|
||||
gesture = gtk_gesture_click_new ();
|
||||
gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (gesture), FALSE);
|
||||
@@ -449,26 +511,6 @@ gtk_link_button_popup_menu (GtkWidget *widget)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_link_button_drag_data_get_cb (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
GtkSelectionData *selection,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkLinkButton *link_button = GTK_LINK_BUTTON (widget);
|
||||
GtkLinkButtonPrivate *priv = gtk_link_button_get_instance_private (link_button);
|
||||
gchar *uri;
|
||||
|
||||
uri = g_strdup_printf ("%s\r\n", priv->uri);
|
||||
gtk_selection_data_set (selection,
|
||||
gtk_selection_data_get_target (selection),
|
||||
8,
|
||||
(guchar *) uri,
|
||||
strlen (uri));
|
||||
|
||||
g_free (uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_link_button_new:
|
||||
* @uri: a valid URI
|
||||
|
||||
+10
-20
@@ -25,7 +25,7 @@
|
||||
#include "gtkbuildable.h"
|
||||
#include "gtkcontainerprivate.h"
|
||||
#include "gtkcssnodeprivate.h"
|
||||
#include "gtkdnd.h"
|
||||
#include "gtkdragdest.h"
|
||||
#include "gtkgestureclick.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkmain.h"
|
||||
@@ -264,8 +264,6 @@ static void gtk_list_box_size_allocate (GtkWidget
|
||||
int width,
|
||||
int height,
|
||||
int baseline);
|
||||
static void gtk_list_box_drag_leave (GtkWidget *widget,
|
||||
GdkDrop *drop);
|
||||
static void gtk_list_box_activate_cursor_row (GtkListBox *box);
|
||||
static void gtk_list_box_toggle_cursor_row (GtkListBox *box);
|
||||
static void gtk_list_box_move_cursor (GtkListBox *box,
|
||||
@@ -452,7 +450,6 @@ gtk_list_box_class_init (GtkListBoxClass *klass)
|
||||
widget_class->get_request_mode = gtk_list_box_get_request_mode;
|
||||
widget_class->measure = gtk_list_box_measure;
|
||||
widget_class->size_allocate = gtk_list_box_size_allocate;
|
||||
widget_class->drag_leave = gtk_list_box_drag_leave;
|
||||
container_class->add = gtk_list_box_add;
|
||||
container_class->remove = gtk_list_box_remove;
|
||||
container_class->forall = gtk_list_box_forall;
|
||||
@@ -1126,8 +1123,8 @@ gtk_list_box_get_selection_mode (GtkListBox *box)
|
||||
/**
|
||||
* gtk_list_box_set_filter_func:
|
||||
* @box: a #GtkListBox
|
||||
* @filter_func: (closure user_data) (allow-none): callback that lets you filter which rows to show
|
||||
* @user_data: user data passed to @filter_func
|
||||
* @filter_func: (allow-none): callback that lets you filter which rows to show
|
||||
* @user_data: (closure): user data passed to @filter_func
|
||||
* @destroy: destroy notifier for @user_data
|
||||
*
|
||||
* By setting a filter function on the @box one can decide dynamically which
|
||||
@@ -1166,8 +1163,8 @@ gtk_list_box_set_filter_func (GtkListBox *box,
|
||||
/**
|
||||
* gtk_list_box_set_header_func:
|
||||
* @box: a #GtkListBox
|
||||
* @update_header: (closure user_data) (allow-none): callback that lets you add row headers
|
||||
* @user_data: user data passed to @update_header
|
||||
* @update_header: (allow-none): callback that lets you add row headers
|
||||
* @user_data: (closure): user data passed to @update_header
|
||||
* @destroy: destroy notifier for @user_data
|
||||
*
|
||||
* By setting a header function on the @box one can dynamically add headers
|
||||
@@ -1321,8 +1318,8 @@ gtk_list_box_invalidate_headers (GtkListBox *box)
|
||||
/**
|
||||
* gtk_list_box_set_sort_func:
|
||||
* @box: a #GtkListBox
|
||||
* @sort_func: (closure user_data) (allow-none): the sort function
|
||||
* @user_data: user data passed to @sort_func
|
||||
* @sort_func: (allow-none): the sort function
|
||||
* @user_data: (closure): user data passed to @sort_func
|
||||
* @destroy: destroy notifier for @user_data
|
||||
*
|
||||
* By setting a sort function on the @box one can dynamically reorder the rows
|
||||
@@ -2728,7 +2725,7 @@ gtk_list_box_drag_unhighlight_row (GtkListBox *box)
|
||||
if (priv->drag_highlighted_row == NULL)
|
||||
return;
|
||||
|
||||
gtk_drag_unhighlight (GTK_WIDGET (priv->drag_highlighted_row));
|
||||
gtk_widget_unset_state_flags (GTK_WIDGET (priv->drag_highlighted_row), GTK_STATE_FLAG_DROP_ACTIVE);
|
||||
g_clear_object (&priv->drag_highlighted_row);
|
||||
}
|
||||
|
||||
@@ -2757,17 +2754,10 @@ gtk_list_box_drag_highlight_row (GtkListBox *box,
|
||||
return;
|
||||
|
||||
gtk_list_box_drag_unhighlight_row (box);
|
||||
gtk_drag_highlight (GTK_WIDGET (row));
|
||||
gtk_widget_set_state_flags (GTK_WIDGET (row), GTK_STATE_FLAG_DROP_ACTIVE, FALSE);
|
||||
priv->drag_highlighted_row = g_object_ref (row);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_box_drag_leave (GtkWidget *widget,
|
||||
GdkDrop *drop)
|
||||
{
|
||||
gtk_list_box_drag_unhighlight_row (GTK_LIST_BOX (widget));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_box_activate_cursor_row (GtkListBox *box)
|
||||
{
|
||||
@@ -3591,7 +3581,7 @@ gtk_list_box_check_model_compat (GtkListBox *box)
|
||||
* @model: (nullable): the #GListModel to be bound to @box
|
||||
* @create_widget_func: (nullable): a function that creates widgets for items
|
||||
* or %NULL in case you also passed %NULL as @model
|
||||
* @user_data: user data passed to @create_widget_func
|
||||
* @user_data: (closure): user data passed to @create_widget_func
|
||||
* @user_data_free_func: function for freeing @user_data
|
||||
*
|
||||
* Binds @model to @box.
|
||||
|
||||
+74
-17
@@ -116,7 +116,7 @@
|
||||
#include "gtkaccelmapprivate.h"
|
||||
#include "gtkbox.h"
|
||||
#include "gtkdebug.h"
|
||||
#include "gtkdndprivate.h"
|
||||
#include "gtkdragdestprivate.h"
|
||||
#include "gtkmain.h"
|
||||
#include "gtkmediafileprivate.h"
|
||||
#include "gtkmodulesprivate.h"
|
||||
@@ -1044,6 +1044,7 @@ gtk_main (void)
|
||||
typedef struct {
|
||||
GMainLoop *store_loop;
|
||||
guint n_clipboards;
|
||||
guint timeout_id;
|
||||
} ClipboardStore;
|
||||
|
||||
static void
|
||||
@@ -1071,16 +1072,26 @@ clipboard_store_finished (GObject *source,
|
||||
g_main_loop_quit (store->store_loop);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
sync_timed_out_cb (ClipboardStore *store)
|
||||
{
|
||||
store->timeout_id = 0;
|
||||
g_main_loop_quit (store->store_loop);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_main_sync (void)
|
||||
{
|
||||
ClipboardStore store = { NULL, };
|
||||
GSList *displays, *l;
|
||||
GCancellable *cancel;
|
||||
guint store_timeout;
|
||||
|
||||
/* Try storing all clipboard data we have */
|
||||
displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
|
||||
if (displays == NULL)
|
||||
return;
|
||||
|
||||
cancel = g_cancellable_new ();
|
||||
|
||||
for (l = displays; l; l = l->next)
|
||||
@@ -1098,17 +1109,16 @@ gtk_main_sync (void)
|
||||
g_slist_free (displays);
|
||||
|
||||
store.store_loop = g_main_loop_new (NULL, TRUE);
|
||||
store_timeout = g_timeout_add_seconds (10, (GSourceFunc) g_main_loop_quit, store.store_loop);
|
||||
g_source_set_name_by_id (store_timeout, "[gtk] gtk_main_sync clipboard store timeout");
|
||||
store.timeout_id = g_timeout_add_seconds (10, (GSourceFunc) sync_timed_out_cb, &store);
|
||||
g_source_set_name_by_id (store.timeout_id, "[gtk] gtk_main_sync clipboard store timeout");
|
||||
|
||||
if (g_main_loop_is_running (store.store_loop))
|
||||
g_main_loop_run (store.store_loop);
|
||||
|
||||
g_cancellable_cancel (cancel);
|
||||
g_object_unref (cancel);
|
||||
g_source_remove (store_timeout);
|
||||
g_main_loop_unref (store.store_loop);
|
||||
store.store_loop = NULL;
|
||||
g_clear_handle_id (&store.timeout_id, g_source_remove);
|
||||
g_clear_pointer (&store.store_loop, g_main_loop_unref);
|
||||
|
||||
/* Synchronize the recent manager singleton */
|
||||
_gtk_recent_manager_sync ();
|
||||
@@ -1676,6 +1686,20 @@ is_focus_event (GdkEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_dnd_event (GdkEvent *event)
|
||||
{
|
||||
switch ((guint) event->any.type)
|
||||
{
|
||||
case GDK_DRAG_ENTER:
|
||||
case GDK_DRAG_LEAVE:
|
||||
case GDK_DRAG_MOTION:
|
||||
case GDK_DROP_START:
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
set_widget_active_state (GtkWidget *target,
|
||||
@@ -1818,6 +1842,25 @@ handle_key_event (GdkEvent *event)
|
||||
return focus_widget ? focus_widget : event_widget;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
handle_dnd_event (GdkEvent *event)
|
||||
{
|
||||
GtkWidget *event_widget;
|
||||
GtkWidget *target;
|
||||
gdouble x, y;
|
||||
GtkWidget *native;
|
||||
|
||||
event_widget = gtk_get_event_widget (event);
|
||||
|
||||
if (!gdk_event_get_coords (event, &x, &y))
|
||||
return event_widget;
|
||||
|
||||
native = GTK_WIDGET (gtk_widget_get_native (event_widget));
|
||||
target = gtk_widget_pick (native, x, y, GTK_PICK_DEFAULT);
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_main_do_event:
|
||||
* @event: An event to process (normally passed by GDK)
|
||||
@@ -1914,6 +1957,8 @@ gtk_main_do_event (GdkEvent *event)
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
else if (is_dnd_event (event))
|
||||
target_widget = handle_dnd_event (event);
|
||||
|
||||
if (!target_widget)
|
||||
goto cleanup;
|
||||
@@ -2028,12 +2073,17 @@ gtk_main_do_event (GdkEvent *event)
|
||||
/* Crossing event propagation happens during picking */
|
||||
break;
|
||||
|
||||
case GDK_DRAG_ENTER:
|
||||
case GDK_DRAG_LEAVE:
|
||||
case GDK_DRAG_MOTION:
|
||||
case GDK_DROP_START:
|
||||
_gtk_drag_dest_handle_event (target_widget, event);
|
||||
if (gtk_propagate_event (target_widget, event))
|
||||
break;
|
||||
G_GNUC_FALLTHROUGH;
|
||||
|
||||
case GDK_DRAG_ENTER:
|
||||
case GDK_DRAG_LEAVE:
|
||||
gtk_drag_dest_handle_event (target_widget, event);
|
||||
break;
|
||||
|
||||
case GDK_EVENT_LAST:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
@@ -2623,14 +2673,19 @@ propagate_event_down (GtkWidget *widget,
|
||||
return handled_event;
|
||||
}
|
||||
|
||||
void
|
||||
gboolean
|
||||
gtk_propagate_event_internal (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
GtkWidget *topmost)
|
||||
{
|
||||
/* Propagate the event down and up */
|
||||
if (!propagate_event_down (widget, event, topmost))
|
||||
propagate_event_up (widget, event, topmost);
|
||||
if (propagate_event_down (widget, event, topmost))
|
||||
return TRUE;
|
||||
|
||||
if (propagate_event_up (widget, event, topmost))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2657,8 +2712,10 @@ gtk_propagate_event_internal (GtkWidget *widget,
|
||||
* certainly better ways to achieve your goals. For example, use
|
||||
* gtk_widget_queue_draw() instead
|
||||
* of making up expose events.
|
||||
*
|
||||
* Returns: %TRUE if the event was handled
|
||||
*/
|
||||
void
|
||||
gboolean
|
||||
gtk_propagate_event (GtkWidget *widget,
|
||||
GdkEvent *event)
|
||||
{
|
||||
@@ -2666,8 +2723,8 @@ gtk_propagate_event (GtkWidget *widget,
|
||||
GtkWidget *event_widget, *topmost = NULL;
|
||||
GdkDevice *device;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
g_return_if_fail (event != NULL);
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
|
||||
g_return_val_if_fail (event != NULL, FALSE);
|
||||
|
||||
event_widget = gtk_get_event_widget (event);
|
||||
window_group = gtk_main_get_window_group (event_widget);
|
||||
@@ -2679,5 +2736,5 @@ gtk_propagate_event (GtkWidget *widget,
|
||||
if (!topmost)
|
||||
topmost = gtk_window_group_get_current_grab (window_group);
|
||||
|
||||
gtk_propagate_event_internal (widget, event, topmost);
|
||||
return gtk_propagate_event_internal (widget, event, topmost);
|
||||
}
|
||||
|
||||
+1
-1
@@ -160,7 +160,7 @@ GtkWidget *gtk_get_event_target_with_type (GdkEvent *event,
|
||||
GType type);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_propagate_event (GtkWidget *widget,
|
||||
gboolean gtk_propagate_event (GtkWidget *widget,
|
||||
GdkEvent *event);
|
||||
|
||||
|
||||
|
||||
@@ -424,7 +424,7 @@ gtk_map_list_model_augment (GtkRbTree *map,
|
||||
* @item_type: the #GType to use as the model's item type
|
||||
* @model: (allow-none): The model to map or %NULL for none
|
||||
* @map_func: (allow-none): map function or %NULL to not map items
|
||||
* @user_data: user data passed to @map_func
|
||||
* @user_data: (closure): user data passed to @map_func
|
||||
* @user_destroy: destroy notifier for @user_data
|
||||
*
|
||||
* Creates a new #GtkMapListModel for the given arguments.
|
||||
@@ -501,7 +501,7 @@ gtk_map_list_model_init_items (GtkMapListModel *self)
|
||||
* gtk_map_list_model_set_map_func:
|
||||
* @self: a #GtkMapListModel
|
||||
* @map_func: (allow-none): map function or %NULL to not map items
|
||||
* @user_data: user data passed to @map_func
|
||||
* @user_data: (closure): user data passed to @map_func
|
||||
* @user_destroy: destroy notifier for @user_data
|
||||
*
|
||||
* Sets the function used to map items. The function will be called whenever
|
||||
|
||||
@@ -58,6 +58,7 @@ OBJECT:VOID
|
||||
STRING:DOUBLE
|
||||
STRING:STRING
|
||||
VOID:BOOLEAN,BOOLEAN,BOOLEAN
|
||||
VOID:BOXED
|
||||
VOID:BOXED,BOXED
|
||||
VOID:BOXED,BOXED,POINTER
|
||||
VOID:BOXED,ENUM
|
||||
|
||||
+1
-1
@@ -1035,7 +1035,7 @@ gtk_menu_button_add_child (GtkMenuButton *menu_button,
|
||||
* @func: (nullable): function to call when a popuop is about to
|
||||
* be shown, but none has been provided via other means, or %NULL
|
||||
* to reset to default behavior.
|
||||
* @user_data: (nullable): user data to pass to @callback
|
||||
* @user_data: (closure): user data to pass to @func.
|
||||
* @destroy_notify: (nullable): destroy notify for @user_data
|
||||
*
|
||||
* Sets @func to be called when a popup is about to be shown.
|
||||
|
||||
@@ -583,7 +583,6 @@ gtk_menu_section_box_new_section (GtkMenuTrackerItem *item,
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (box->item_box)), "inline-buttons");
|
||||
|
||||
spacer = gtk_icon_new ("none");
|
||||
gtk_icon_set_image (GTK_ICON (spacer), GTK_CSS_IMAGE_BUILTIN_NONE);
|
||||
gtk_container_add (GTK_CONTAINER (box->item_box), spacer);
|
||||
gtk_size_group_add_widget (box->indicators, spacer);
|
||||
|
||||
|
||||
@@ -377,6 +377,16 @@ gtk_menu_tool_button_set_popover (GtkMenuToolButton *button,
|
||||
g_object_notify (G_OBJECT (button), "popover");
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_menu_tool_button_get_popover:
|
||||
* @menu_button: a #GtkMenuToolButton
|
||||
*
|
||||
* Returns the #GtkPopover that pops out of the button.
|
||||
* If the button is not using a #GtkPopover, this function
|
||||
* returns %NULL.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): a #GtkPopover or %NULL
|
||||
**/
|
||||
GtkWidget *
|
||||
gtk_menu_tool_button_get_popover (GtkMenuToolButton *button)
|
||||
{
|
||||
|
||||
@@ -352,12 +352,6 @@ update_end_indicator (GtkModelButton *self)
|
||||
if (!self->end_indicator)
|
||||
return;
|
||||
|
||||
if (self->role == GTK_BUTTON_ROLE_NORMAL &&
|
||||
(self->menu_name != NULL || self->popover != NULL))
|
||||
{
|
||||
gtk_icon_set_image (GTK_ICON (self->end_indicator), GTK_CSS_IMAGE_BUILTIN_ARROW_RIGHT);
|
||||
}
|
||||
|
||||
context = gtk_widget_get_style_context (self->end_indicator);
|
||||
|
||||
if (is_ltr)
|
||||
@@ -398,15 +392,6 @@ update_start_indicator (GtkModelButton *self)
|
||||
if (!self->start_indicator)
|
||||
return;
|
||||
|
||||
if (self->role == GTK_BUTTON_ROLE_CHECK)
|
||||
gtk_icon_set_image (GTK_ICON (self->start_indicator), GTK_CSS_IMAGE_BUILTIN_CHECK);
|
||||
else if (self->role == GTK_BUTTON_ROLE_RADIO)
|
||||
gtk_icon_set_image (GTK_ICON (self->start_indicator), GTK_CSS_IMAGE_BUILTIN_OPTION);
|
||||
else if (self->role == GTK_BUTTON_ROLE_TITLE)
|
||||
gtk_icon_set_image (GTK_ICON (self->start_indicator), GTK_CSS_IMAGE_BUILTIN_ARROW_LEFT);
|
||||
else
|
||||
gtk_icon_set_image (GTK_ICON (self->start_indicator), GTK_CSS_IMAGE_BUILTIN_NONE);
|
||||
|
||||
gtk_widget_set_state_flags (self->start_indicator, get_start_indicator_state (self), TRUE);
|
||||
|
||||
context = gtk_widget_get_style_context (self->start_indicator);
|
||||
|
||||
+178
-191
@@ -33,8 +33,8 @@
|
||||
#include "gtkbuildable.h"
|
||||
#include "gtkbutton.h"
|
||||
#include "gtkcssstylepropertyprivate.h"
|
||||
#include "gtkdnd.h"
|
||||
#include "gtkdragdest.h"
|
||||
#include "gtkdragicon.h"
|
||||
#include "gtkeventcontrollermotion.h"
|
||||
#include "gtkgestureclick.h"
|
||||
#include "gtkgizmoprivate.h"
|
||||
@@ -52,6 +52,10 @@
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkwidgetpath.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkdragsource.h"
|
||||
#include "gtkwidgetpaintable.h"
|
||||
#include "gtkselectionprivate.h"
|
||||
#include "gtknative.h"
|
||||
|
||||
#include "a11y/gtknotebookaccessible.h"
|
||||
|
||||
@@ -234,7 +238,6 @@ struct _GtkNotebookPrivate
|
||||
GtkNotebookPage *detached_tab;
|
||||
GdkContentFormats *source_targets;
|
||||
GtkWidget *action_widget[N_ACTION_WIDGETS];
|
||||
GtkWidget *dnd_child;
|
||||
GtkWidget *menu;
|
||||
GtkWidget *menu_box;
|
||||
|
||||
@@ -695,29 +698,22 @@ static gboolean gtk_notebook_focus (GtkWidget *widget,
|
||||
GtkDirectionType direction);
|
||||
|
||||
/*** Drag and drop Methods ***/
|
||||
static void gtk_notebook_drag_begin (GtkWidget *widget,
|
||||
GdkDrag *drag);
|
||||
static void gtk_notebook_drag_end (GtkWidget *widget,
|
||||
GdkDrag *drag);
|
||||
static gboolean gtk_notebook_drag_failed (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
GtkDragResult result);
|
||||
static gboolean gtk_notebook_drag_motion (GtkWidget *widget,
|
||||
static void gtk_notebook_dnd_finished_cb (GdkDrag *drag,
|
||||
GtkWidget *widget);
|
||||
static void gtk_notebook_drag_cancel_cb (GdkDrag *drag,
|
||||
GdkDragCancelReason reason,
|
||||
GtkWidget *widget);
|
||||
static void gtk_notebook_drag_motion (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
gint x,
|
||||
gint y);
|
||||
static void gtk_notebook_drag_leave (GtkWidget *widget,
|
||||
GdkDrop *drop);
|
||||
static gboolean gtk_notebook_drag_drop (GtkWidget *widget,
|
||||
int x,
|
||||
int y);
|
||||
static void gtk_notebook_drag_leave (GtkDropTarget *dest);
|
||||
static gboolean gtk_notebook_drag_drop (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
gint x,
|
||||
gint y);
|
||||
static void gtk_notebook_drag_data_get (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
GtkSelectionData *data);
|
||||
static void gtk_notebook_drag_data_received (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
GtkSelectionData *data);
|
||||
int x,
|
||||
int y);
|
||||
static GBytes * gtk_notebook_drag_data_get (const char *mime_type,
|
||||
gpointer data);
|
||||
|
||||
/*** GtkContainer Methods ***/
|
||||
static void gtk_notebook_add (GtkContainer *container,
|
||||
@@ -964,14 +960,6 @@ gtk_notebook_class_init (GtkNotebookClass *class)
|
||||
widget_class->grab_notify = gtk_notebook_grab_notify;
|
||||
widget_class->state_flags_changed = gtk_notebook_state_flags_changed;
|
||||
widget_class->focus = gtk_notebook_focus;
|
||||
widget_class->drag_begin = gtk_notebook_drag_begin;
|
||||
widget_class->drag_end = gtk_notebook_drag_end;
|
||||
widget_class->drag_motion = gtk_notebook_drag_motion;
|
||||
widget_class->drag_leave = gtk_notebook_drag_leave;
|
||||
widget_class->drag_drop = gtk_notebook_drag_drop;
|
||||
widget_class->drag_data_get = gtk_notebook_drag_data_get;
|
||||
widget_class->drag_data_received = gtk_notebook_drag_data_received;
|
||||
widget_class->drag_failed = gtk_notebook_drag_failed;
|
||||
widget_class->compute_expand = gtk_notebook_compute_expand;
|
||||
|
||||
container_class->add = gtk_notebook_add;
|
||||
@@ -1306,6 +1294,7 @@ gtk_notebook_init (GtkNotebook *notebook)
|
||||
GtkEventController *controller;
|
||||
GtkGesture *gesture;
|
||||
GtkLayoutManager *layout;
|
||||
GtkDropTarget *dest;
|
||||
|
||||
gtk_widget_set_can_focus (GTK_WIDGET (notebook), TRUE);
|
||||
|
||||
@@ -1337,14 +1326,6 @@ gtk_notebook_init (GtkNotebook *notebook)
|
||||
priv->detached_tab = NULL;
|
||||
priv->has_scrolled = FALSE;
|
||||
|
||||
targets = gdk_content_formats_new (dst_notebook_targets, G_N_ELEMENTS (dst_notebook_targets));
|
||||
gtk_drag_dest_set (GTK_WIDGET (notebook), 0,
|
||||
targets,
|
||||
GDK_ACTION_MOVE);
|
||||
gdk_content_formats_unref (targets);
|
||||
|
||||
gtk_drag_dest_set_track_motion (GTK_WIDGET (notebook), TRUE);
|
||||
|
||||
priv->header_widget = g_object_new (GTK_TYPE_BOX,
|
||||
"css-name", "header",
|
||||
NULL);
|
||||
@@ -1366,6 +1347,14 @@ gtk_notebook_init (GtkNotebook *notebook)
|
||||
gtk_widget_set_vexpand (priv->stack_widget, TRUE);
|
||||
gtk_widget_set_parent (priv->stack_widget, GTK_WIDGET (notebook));
|
||||
|
||||
targets = gdk_content_formats_new (dst_notebook_targets, G_N_ELEMENTS (dst_notebook_targets));
|
||||
dest = gtk_drop_target_new (targets, GDK_ACTION_MOVE);
|
||||
g_signal_connect (dest, "drag-motion", G_CALLBACK (gtk_notebook_drag_motion), NULL);
|
||||
g_signal_connect (dest, "drag-leave", G_CALLBACK (gtk_notebook_drag_leave), NULL);
|
||||
g_signal_connect (dest, "drag-drop", G_CALLBACK (gtk_notebook_drag_drop), NULL);
|
||||
gtk_widget_add_controller (GTK_WIDGET (priv->tabs_widget), GTK_EVENT_CONTROLLER (dest));
|
||||
gdk_content_formats_unref (targets);
|
||||
|
||||
gesture = gtk_gesture_click_new ();
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), 0);
|
||||
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture), GTK_PHASE_CAPTURE);
|
||||
@@ -1835,7 +1824,6 @@ gtk_notebook_get_property (GObject *object,
|
||||
* gtk_notebook_drag_motion
|
||||
* gtk_notebook_drag_drop
|
||||
* gtk_notebook_drag_data_get
|
||||
* gtk_notebook_drag_data_received
|
||||
*/
|
||||
static void
|
||||
remove_switch_tab_timer (GtkNotebook *notebook)
|
||||
@@ -2881,12 +2869,43 @@ gtk_notebook_motion (GtkEventController *controller,
|
||||
if (page->detachable &&
|
||||
check_threshold (notebook, priv->mouse_x, priv->mouse_y))
|
||||
{
|
||||
GdkSurface *surface;
|
||||
GdkDevice *device;
|
||||
GdkContentProvider *content;
|
||||
GdkDrag *drag;
|
||||
GdkPaintable *paintable;
|
||||
|
||||
priv->detached_tab = priv->cur_page;
|
||||
|
||||
gtk_drag_begin (widget,
|
||||
gtk_get_current_event_device (),
|
||||
priv->source_targets, GDK_ACTION_MOVE,
|
||||
priv->drag_begin_x, priv->drag_begin_y);
|
||||
surface = gtk_native_get_surface (gtk_widget_get_native (GTK_WIDGET (notebook)));
|
||||
device = gtk_get_current_event_device ();
|
||||
|
||||
content = gdk_content_provider_new_with_formats (priv->source_targets,
|
||||
gtk_notebook_drag_data_get,
|
||||
widget);
|
||||
drag = gdk_drag_begin (surface, device, content, GDK_ACTION_MOVE, priv->drag_begin_x, priv->drag_begin_y);
|
||||
g_object_unref (content);
|
||||
|
||||
g_signal_connect (drag, "dnd-finished", G_CALLBACK (gtk_notebook_dnd_finished_cb), notebook);
|
||||
g_signal_connect (drag, "cancel", G_CALLBACK (gtk_notebook_drag_cancel_cb), notebook);
|
||||
|
||||
paintable = gtk_widget_paintable_new (priv->detached_tab->tab_widget);
|
||||
gtk_drag_icon_set_from_paintable (drag, paintable, -2, -2);
|
||||
g_object_unref (paintable);
|
||||
|
||||
if (priv->dnd_timer)
|
||||
{
|
||||
g_source_remove (priv->dnd_timer);
|
||||
priv->dnd_timer = 0;
|
||||
}
|
||||
|
||||
priv->operation = DRAG_OPERATION_DETACH;
|
||||
tab_drag_end (notebook, priv->cur_page);
|
||||
|
||||
g_object_set_data (G_OBJECT (drag), "gtk-notebook-drag-origin", notebook);
|
||||
|
||||
g_object_unref (drag);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3088,46 +3107,8 @@ update_arrow_nodes (GtkNotebook *notebook)
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_notebook_drag_begin (GtkWidget *widget,
|
||||
GdkDrag *drag)
|
||||
{
|
||||
GtkNotebook *notebook = GTK_NOTEBOOK (widget);
|
||||
GtkNotebookPrivate *priv = notebook->priv;
|
||||
graphene_rect_t bounds;
|
||||
GtkWidget *tab_label;
|
||||
|
||||
if (priv->dnd_timer)
|
||||
{
|
||||
g_source_remove (priv->dnd_timer);
|
||||
priv->dnd_timer = 0;
|
||||
}
|
||||
|
||||
g_assert (priv->cur_page != NULL);
|
||||
|
||||
priv->operation = DRAG_OPERATION_DETACH;
|
||||
|
||||
tab_label = priv->detached_tab->tab_label;
|
||||
|
||||
tab_drag_end (notebook, priv->cur_page);
|
||||
g_object_ref (tab_label);
|
||||
gtk_widget_unparent (tab_label);
|
||||
|
||||
priv->dnd_child = tab_label;
|
||||
if (gtk_widget_compute_bounds (priv->dnd_child, priv->dnd_child, &bounds))
|
||||
gtk_widget_set_size_request (priv->dnd_child,
|
||||
ceilf (bounds.size.width),
|
||||
ceilf (bounds.size.height));
|
||||
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (priv->dnd_child), "background");
|
||||
|
||||
gtk_drag_set_icon_widget (drag, tab_label, -2, -2);
|
||||
g_object_set_data (G_OBJECT (priv->dnd_child), "drag-context", drag);
|
||||
g_object_unref (tab_label);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_notebook_drag_end (GtkWidget *widget,
|
||||
GdkDrag *drag)
|
||||
gtk_notebook_dnd_finished_cb (GdkDrag *drag,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GtkNotebook *notebook = GTK_NOTEBOOK (widget);
|
||||
GtkNotebookPrivate *priv = notebook->priv;
|
||||
@@ -3148,17 +3129,9 @@ gtk_notebook_drag_end (GtkWidget *widget,
|
||||
}
|
||||
else if (priv->detached_tab)
|
||||
{
|
||||
gtk_widget_set_size_request (priv->dnd_child, -1, -1);
|
||||
g_object_ref (priv->dnd_child);
|
||||
gtk_widget_unparent (priv->dnd_child);
|
||||
gtk_widget_set_parent (priv->dnd_child, priv->detached_tab->tab_widget);
|
||||
g_object_unref (priv->dnd_child);
|
||||
gtk_notebook_switch_page (notebook, priv->detached_tab);
|
||||
}
|
||||
|
||||
gtk_style_context_remove_class (gtk_widget_get_style_context (priv->dnd_child), "background");
|
||||
priv->dnd_child = NULL;
|
||||
|
||||
priv->operation = DRAG_OPERATION_NONE;
|
||||
}
|
||||
|
||||
@@ -3169,17 +3142,17 @@ gtk_notebook_create_window (GtkNotebook *notebook,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_notebook_drag_failed (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
GtkDragResult result)
|
||||
static void
|
||||
gtk_notebook_drag_cancel_cb (GdkDrag *drag,
|
||||
GdkDragCancelReason reason,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GtkNotebook *notebook = GTK_NOTEBOOK (widget);
|
||||
GtkNotebookPrivate *priv = notebook->priv;
|
||||
|
||||
priv->rootwindow_drop = FALSE;
|
||||
|
||||
if (result == GTK_DRAG_RESULT_NO_TARGET)
|
||||
if (reason == GDK_DRAG_CANCEL_NO_TARGET)
|
||||
{
|
||||
GtkNotebook *dest_notebook = NULL;
|
||||
|
||||
@@ -3188,11 +3161,7 @@ gtk_notebook_drag_failed (GtkWidget *widget,
|
||||
|
||||
if (dest_notebook)
|
||||
do_detach_tab (notebook, dest_notebook, priv->detached_tab->child);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -3219,19 +3188,20 @@ gtk_notebook_switch_tab_timeout (gpointer data)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_notebook_drag_motion (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
gint x,
|
||||
gint y)
|
||||
static void
|
||||
gtk_notebook_drag_motion (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
GtkWidget *tabs = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest));
|
||||
GtkWidget *widget = gtk_widget_get_ancestor (tabs, GTK_TYPE_NOTEBOOK);
|
||||
GtkNotebook *notebook = GTK_NOTEBOOK (widget);
|
||||
GtkNotebookPrivate *priv = notebook->priv;
|
||||
graphene_rect_t position;
|
||||
GtkNotebookArrow arrow;
|
||||
GdkAtom target, tab_target;
|
||||
GList *tab;
|
||||
gboolean retval = FALSE;
|
||||
|
||||
arrow = gtk_notebook_get_arrow (notebook, x, y);
|
||||
if (arrow != ARROW_NONE)
|
||||
@@ -3240,41 +3210,46 @@ gtk_notebook_drag_motion (GtkWidget *widget,
|
||||
gtk_notebook_set_scroll_timer (notebook);
|
||||
gdk_drop_status (drop, 0);
|
||||
|
||||
retval = TRUE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
stop_scrolling (notebook);
|
||||
target = gtk_drag_dest_find_target (widget, drop, NULL);
|
||||
target = gtk_drop_target_find_mimetype (dest);
|
||||
tab_target = g_intern_static_string ("GTK_NOTEBOOK_TAB");
|
||||
|
||||
if (target == tab_target)
|
||||
{
|
||||
GQuark group, source_group;
|
||||
GtkNotebook *source;
|
||||
GtkWidget *source_child;
|
||||
GdkDrag *drag = gdk_drop_get_drag (drop);
|
||||
|
||||
retval = TRUE;
|
||||
|
||||
source = GTK_NOTEBOOK (gtk_drag_get_source_widget (gdk_drop_get_drag (drop)));
|
||||
g_assert (source->priv->cur_page != NULL);
|
||||
source_child = source->priv->cur_page->child;
|
||||
|
||||
group = notebook->priv->group;
|
||||
source_group = source->priv->group;
|
||||
|
||||
if (group != 0 && group == source_group &&
|
||||
!(widget == source_child ||
|
||||
gtk_widget_is_ancestor (widget, source_child)))
|
||||
if (!drag)
|
||||
{
|
||||
gdk_drop_status (drop, GDK_ACTION_MOVE);
|
||||
goto out;
|
||||
gdk_drop_status (drop, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* it's a tab, but doesn't share
|
||||
* ID with this notebook */
|
||||
gdk_drop_status (drop, 0);
|
||||
GtkNotebook *source = GTK_NOTEBOOK (g_object_get_data (G_OBJECT (drag), "gtk-notebook-drag-origin"));
|
||||
|
||||
g_assert (source->priv->cur_page != NULL);
|
||||
source_child = source->priv->cur_page->child;
|
||||
|
||||
group = notebook->priv->group;
|
||||
source_group = source->priv->group;
|
||||
|
||||
if (group != 0 && group == source_group &&
|
||||
!(widget == source_child ||
|
||||
gtk_widget_is_ancestor (widget, source_child)))
|
||||
{
|
||||
gdk_drop_status (drop, GDK_ACTION_MOVE);
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* it's a tab, but doesn't share
|
||||
* ID with this notebook */
|
||||
gdk_drop_status (drop, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3285,8 +3260,6 @@ gtk_notebook_drag_motion (GtkWidget *widget,
|
||||
priv->mouse_x = x;
|
||||
priv->mouse_y = y;
|
||||
|
||||
retval = TRUE;
|
||||
|
||||
if (tab != priv->switch_tab)
|
||||
remove_switch_tab_timer (notebook);
|
||||
|
||||
@@ -3303,40 +3276,86 @@ gtk_notebook_drag_motion (GtkWidget *widget,
|
||||
remove_switch_tab_timer (notebook);
|
||||
}
|
||||
|
||||
out:
|
||||
return retval;
|
||||
out:;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_notebook_drag_leave (GtkWidget *widget,
|
||||
GdkDrop *drop)
|
||||
gtk_notebook_drag_leave (GtkDropTarget *dest)
|
||||
{
|
||||
GtkWidget *tabs = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest));
|
||||
GtkWidget *widget = gtk_widget_get_ancestor (tabs, GTK_TYPE_NOTEBOOK);
|
||||
GtkNotebook *notebook = GTK_NOTEBOOK (widget);
|
||||
|
||||
remove_switch_tab_timer (notebook);
|
||||
stop_scrolling (notebook);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_notebook_drag_drop (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
gint x,
|
||||
gint y)
|
||||
static void
|
||||
got_page (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GtkNotebook *notebook = GTK_NOTEBOOK (data);
|
||||
GdkDrop *drop = GDK_DROP (source);
|
||||
GdkDrag *drag = gdk_drop_get_drag (drop);
|
||||
GtkWidget *source_widget;
|
||||
GInputStream *stream;
|
||||
const char *mime_type;
|
||||
|
||||
source_widget = GTK_WIDGET (drag ? g_object_get_data (G_OBJECT (drag), "gtk-notebook-drag-origin") : NULL);
|
||||
|
||||
stream = gdk_drop_read_finish (drop, result, &mime_type, NULL);
|
||||
|
||||
if (stream)
|
||||
{
|
||||
GBytes *bytes;
|
||||
GtkWidget **child;
|
||||
|
||||
bytes = g_input_stream_read_bytes (stream, sizeof (gpointer), NULL, NULL);
|
||||
child = (gpointer)g_bytes_get_data (bytes, NULL);
|
||||
|
||||
do_detach_tab (GTK_NOTEBOOK (source_widget), notebook, *child);
|
||||
gdk_drop_finish (drop, GDK_ACTION_MOVE);
|
||||
|
||||
g_bytes_unref (bytes);
|
||||
g_object_unref (stream);
|
||||
}
|
||||
else
|
||||
gdk_drop_finish (drop, 0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_notebook_drag_drop (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
GtkWidget *tabs = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest));
|
||||
GtkWidget *widget = gtk_widget_get_ancestor (tabs, GTK_TYPE_NOTEBOOK);
|
||||
GtkNotebook *notebook = GTK_NOTEBOOK (widget);
|
||||
GdkDrag *drag = gdk_drop_get_drag (drop);
|
||||
GtkWidget *source_widget;
|
||||
GdkAtom target, tab_target;
|
||||
|
||||
target = gtk_drag_dest_find_target (widget, drop, NULL);
|
||||
source_widget = GTK_WIDGET (drag ? g_object_get_data (G_OBJECT (drag), "gtk-notebook-drag-origin") : NULL);
|
||||
|
||||
target = gtk_drop_target_find_mimetype (dest);
|
||||
tab_target = g_intern_static_string ("GTK_NOTEBOOK_TAB");
|
||||
|
||||
if (target == tab_target)
|
||||
if (GTK_IS_NOTEBOOK (source_widget) &&
|
||||
target == tab_target &&
|
||||
(gdk_drop_get_actions (drop) & GDK_ACTION_MOVE))
|
||||
{
|
||||
notebook->priv->mouse_x = x;
|
||||
notebook->priv->mouse_y = y;
|
||||
gtk_drag_get_data (widget, drop, target);
|
||||
|
||||
gdk_drop_read_async (drop, (const char *[]) { "GTK_NOTEBOOK_TAB", NULL }, G_PRIORITY_DEFAULT, NULL, got_page, notebook);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gdk_drop_finish (drop, 0);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -3419,57 +3438,32 @@ do_detach_tab (GtkNotebook *from,
|
||||
gtk_notebook_set_current_page (to, page_num);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_notebook_drag_data_get (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
GtkSelectionData *data)
|
||||
static GBytes *
|
||||
gtk_notebook_drag_data_get (const char *mime_type,
|
||||
gpointer data)
|
||||
{
|
||||
GtkNotebook *notebook = GTK_NOTEBOOK (widget);
|
||||
GtkNotebook *notebook = GTK_NOTEBOOK (data);
|
||||
GtkNotebookPrivate *priv = notebook->priv;
|
||||
GdkAtom target;
|
||||
GtkSelectionData sdata = { 0, };
|
||||
|
||||
target = gtk_selection_data_get_target (data);
|
||||
if (target == g_intern_static_string ("GTK_NOTEBOOK_TAB"))
|
||||
sdata.target = g_intern_string (mime_type);
|
||||
|
||||
if (sdata.target == g_intern_static_string ("GTK_NOTEBOOK_TAB"))
|
||||
{
|
||||
gtk_selection_data_set (data,
|
||||
target,
|
||||
gtk_selection_data_set (&sdata,
|
||||
sdata.target,
|
||||
8,
|
||||
(void*) &priv->detached_tab->child,
|
||||
sizeof (gpointer));
|
||||
priv->rootwindow_drop = FALSE;
|
||||
}
|
||||
else if (target == g_intern_static_string ("application/x-rootwindow-drop"))
|
||||
else if (sdata.target == g_intern_static_string ("application/x-rootwindow-drop"))
|
||||
{
|
||||
gtk_selection_data_set (data, target, 8, NULL, 0);
|
||||
gtk_selection_data_set (&sdata, sdata.target, 8, NULL, 0);
|
||||
priv->rootwindow_drop = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_notebook_drag_data_received (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
GtkSelectionData *data)
|
||||
{
|
||||
GtkNotebook *notebook;
|
||||
GdkDrag *drag;
|
||||
GtkWidget *source_widget;
|
||||
GtkWidget **child;
|
||||
|
||||
notebook = GTK_NOTEBOOK (widget);
|
||||
drag = gdk_drop_get_drag (drop);
|
||||
source_widget = gtk_drag_get_source_widget (drag);
|
||||
|
||||
if (source_widget &&
|
||||
(gdk_drop_get_actions (drop) & GDK_ACTION_MOVE) &&
|
||||
gtk_selection_data_get_target (data) == g_intern_static_string ("GTK_NOTEBOOK_TAB"))
|
||||
{
|
||||
child = (void*) gtk_selection_data_get_data (data);
|
||||
|
||||
do_detach_tab (GTK_NOTEBOOK (source_widget), notebook, *child);
|
||||
gdk_drop_finish (drop, GDK_ACTION_MOVE);
|
||||
}
|
||||
else
|
||||
gdk_drop_finish (drop, 0);
|
||||
return g_bytes_new_take (sdata.data, sdata.length);
|
||||
}
|
||||
|
||||
/* Private GtkContainer Methods :
|
||||
@@ -4249,17 +4243,8 @@ gtk_notebook_real_remove (GtkNotebook *notebook,
|
||||
}
|
||||
|
||||
if (priv->detached_tab == list->data)
|
||||
{
|
||||
priv->detached_tab = NULL;
|
||||
priv->detached_tab = NULL;
|
||||
|
||||
if (priv->operation == DRAG_OPERATION_DETACH && !priv->remove_in_detach)
|
||||
{
|
||||
GdkDrag *drag;
|
||||
|
||||
drag = (GdkDrag *)g_object_get_data (G_OBJECT (priv->dnd_child), "drag-context");
|
||||
gtk_drag_cancel (drag);
|
||||
}
|
||||
}
|
||||
if (priv->switch_tab == list)
|
||||
priv->switch_tab = NULL;
|
||||
|
||||
@@ -7099,15 +7084,17 @@ gtk_notebook_get_tab_detachable (GtkNotebook *notebook,
|
||||
* |[<!-- language="C" -->
|
||||
* static void
|
||||
* on_drag_data_received (GtkWidget *widget,
|
||||
* GdkDrag *drag,
|
||||
* GdkDrop *drop,
|
||||
* GtkSelectionData *data,
|
||||
* guint time,
|
||||
* gpointer user_data)
|
||||
* {
|
||||
* GtkDrag *drag;
|
||||
* GtkWidget *notebook;
|
||||
* GtkWidget **child;
|
||||
*
|
||||
* notebook = gtk_drag_get_source_widget (drag);
|
||||
* drag = gtk_drop_get_drag (drop);
|
||||
* notebook = g_object_get_data (drag, "gtk-notebook-drag-origin");
|
||||
* child = (void*) gtk_selection_data_get_data (data);
|
||||
*
|
||||
* // process_widget (*child);
|
||||
|
||||
+1
-4
@@ -1326,10 +1326,7 @@ gtk_paned_render_handle (GtkGizmo *gizmo,
|
||||
height = gtk_widget_get_height (widget);
|
||||
|
||||
if (width > 0 && height > 0)
|
||||
gtk_css_style_snapshot_icon (style,
|
||||
snapshot,
|
||||
width, height,
|
||||
GTK_CSS_IMAGE_BUILTIN_PANE_SEPARATOR);
|
||||
gtk_css_style_snapshot_icon (style, snapshot, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+13
-35
@@ -24,7 +24,6 @@
|
||||
|
||||
#include "gtkbox.h"
|
||||
#include "gtkcssnodeprivate.h"
|
||||
#include "gtkdnd.h"
|
||||
#include "gtkdragsource.h"
|
||||
#include "gtkicontheme.h"
|
||||
#include "gtkimage.h"
|
||||
@@ -37,6 +36,7 @@
|
||||
#include "gtkwidgetpath.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkeventcontrollerscroll.h"
|
||||
#include "gtkdragsource.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -1240,15 +1240,8 @@ set_button_image (GtkPathBar *path_bar,
|
||||
static void
|
||||
button_data_free (ButtonData *button_data)
|
||||
{
|
||||
if (button_data->file)
|
||||
g_object_unref (button_data->file);
|
||||
button_data->file = NULL;
|
||||
|
||||
g_clear_object (&button_data->file);
|
||||
g_free (button_data->dir_name);
|
||||
button_data->dir_name = NULL;
|
||||
|
||||
button_data->button = NULL;
|
||||
|
||||
g_free (button_data);
|
||||
}
|
||||
|
||||
@@ -1312,25 +1305,6 @@ find_button_type (GtkPathBar *path_bar,
|
||||
return NORMAL_BUTTON;
|
||||
}
|
||||
|
||||
static void
|
||||
button_drag_data_get_cb (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
GtkSelectionData *selection_data,
|
||||
gpointer data)
|
||||
{
|
||||
ButtonData *button_data;
|
||||
char *uris[2];
|
||||
|
||||
button_data = data;
|
||||
|
||||
uris[0] = g_file_get_uri (button_data->file);
|
||||
uris[1] = NULL;
|
||||
|
||||
gtk_selection_data_set_uris (selection_data, uris);
|
||||
|
||||
g_free (uris[0]);
|
||||
}
|
||||
|
||||
static ButtonData *
|
||||
make_directory_button (GtkPathBar *path_bar,
|
||||
const char *dir_name,
|
||||
@@ -1341,6 +1315,9 @@ make_directory_button (GtkPathBar *path_bar,
|
||||
AtkObject *atk_obj;
|
||||
GtkWidget *child = NULL;
|
||||
ButtonData *button_data;
|
||||
GValue value = G_VALUE_INIT;
|
||||
GdkContentProvider *content;
|
||||
GtkDragSource *source;
|
||||
|
||||
file_is_hidden = !! file_is_hidden;
|
||||
/* Is it a special button? */
|
||||
@@ -1387,13 +1364,14 @@ make_directory_button (GtkPathBar *path_bar,
|
||||
g_object_weak_ref (G_OBJECT (button_data->button),
|
||||
(GWeakNotify) button_data_free, button_data);
|
||||
|
||||
gtk_drag_source_set (button_data->button,
|
||||
GDK_BUTTON1_MASK,
|
||||
NULL,
|
||||
GDK_ACTION_COPY);
|
||||
gtk_drag_source_add_uri_targets (button_data->button);
|
||||
g_signal_connect (button_data->button, "drag-data-get",
|
||||
G_CALLBACK (button_drag_data_get_cb), button_data);
|
||||
g_value_init (&value, G_TYPE_FILE);
|
||||
g_value_set_object (&value, button_data->file);
|
||||
source = gtk_drag_source_new ();
|
||||
content = gdk_content_provider_new_for_value (&value);
|
||||
gtk_drag_source_set_content (source, content);
|
||||
g_object_unref (content);
|
||||
gtk_widget_add_controller (button_data->button, GTK_EVENT_CONTROLLER (source));
|
||||
g_value_unset (&value);
|
||||
|
||||
return button_data;
|
||||
}
|
||||
|
||||
+126
-135
@@ -52,7 +52,6 @@
|
||||
#include "gtklistbox.h"
|
||||
#include "gtkselection.h"
|
||||
#include "gtkdragdest.h"
|
||||
#include "gtkdnd.h"
|
||||
#include "gtkseparator.h"
|
||||
#include "gtkentry.h"
|
||||
#include "gtkgesturelongpress.h"
|
||||
@@ -63,6 +62,10 @@
|
||||
#include "gtkgestureclick.h"
|
||||
#include "gtkgesturedrag.h"
|
||||
#include "gtknative.h"
|
||||
#include "gtkdragsource.h"
|
||||
#include "gtkdragicon.h"
|
||||
#include "gtkwidgetpaintable.h"
|
||||
#include "gtkselectionprivate.h"
|
||||
|
||||
/*< private >
|
||||
* SECTION:gtkplacessidebar
|
||||
@@ -309,16 +312,6 @@ enum {
|
||||
DND_TEXT_URI_LIST
|
||||
};
|
||||
|
||||
/* Target types for dragging from the shortcuts list */
|
||||
static const char *dnd_source_targets[] = {
|
||||
"DND_GTK_SIDEBAR_ROW"
|
||||
};
|
||||
|
||||
/* Target types for dropping into the shortcuts list */
|
||||
static const char *dnd_drop_targets [] = {
|
||||
"DND_GTK_SIDEBAR_ROW"
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GtkPlacesSidebar, gtk_places_sidebar, GTK_TYPE_WIDGET);
|
||||
|
||||
static void
|
||||
@@ -1641,21 +1634,25 @@ update_possible_drop_targets (GtkPlacesSidebar *sidebar,
|
||||
g_list_free (rows);
|
||||
}
|
||||
|
||||
static void drag_data_received_callback (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data);
|
||||
|
||||
static gboolean
|
||||
get_drag_data (GtkWidget *list_box,
|
||||
GdkDrop *drop,
|
||||
GtkDropTarget *dest,
|
||||
GtkListBoxRow *row)
|
||||
{
|
||||
GdkAtom target;
|
||||
|
||||
target = gtk_drag_dest_find_target (list_box, drop, NULL);
|
||||
target = gtk_drop_target_find_mimetype (dest);
|
||||
|
||||
if (target == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (row)
|
||||
g_object_set_data_full (G_OBJECT (drop), "places-sidebar-row", g_object_ref (row), g_object_unref);
|
||||
gtk_drag_get_data (list_box, drop, target);
|
||||
g_object_set_data_full (G_OBJECT (dest), "places-sidebar-row", g_object_ref (row), g_object_unref);
|
||||
gtk_drop_target_read_selection (dest, target, NULL, drag_data_received_callback, list_box);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1678,7 +1675,8 @@ start_drop_feedback (GtkPlacesSidebar *sidebar,
|
||||
GtkSidebarRow *row,
|
||||
GdkDrag *drag)
|
||||
{
|
||||
if (sidebar->drag_data_info != DND_GTK_SIDEBAR_ROW)
|
||||
if (sidebar->drag_data_received &&
|
||||
sidebar->drag_data_info != DND_GTK_SIDEBAR_ROW)
|
||||
{
|
||||
gtk_sidebar_row_reveal (GTK_SIDEBAR_ROW (sidebar->new_bookmark_row));
|
||||
/* If the state is permanent, don't change it. The application controls it. */
|
||||
@@ -1719,48 +1717,22 @@ stop_drop_feedback (GtkPlacesSidebar *sidebar)
|
||||
sidebar->drag_data_info = DND_UNKNOWN;
|
||||
}
|
||||
|
||||
static void
|
||||
drag_begin_callback (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkPlacesSidebar *sidebar = GTK_PLACES_SIDEBAR (user_data);
|
||||
GtkAllocation allocation;
|
||||
GtkWidget *drag_widget;
|
||||
|
||||
gtk_widget_get_allocation (sidebar->drag_row, &allocation);
|
||||
gtk_widget_hide (sidebar->drag_row);
|
||||
|
||||
drag_widget = GTK_WIDGET (gtk_sidebar_row_clone (GTK_SIDEBAR_ROW (sidebar->drag_row)));
|
||||
sidebar->drag_row_height = allocation.height;
|
||||
gtk_widget_set_size_request (drag_widget, allocation.width, allocation.height);
|
||||
|
||||
gtk_widget_set_opacity (drag_widget, 0.8);
|
||||
|
||||
gtk_drag_set_icon_widget (drag,
|
||||
drag_widget,
|
||||
sidebar->drag_row_x,
|
||||
sidebar->drag_row_y);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_placeholder_row (GtkPlacesSidebar *sidebar)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_SIDEBAR_ROW,
|
||||
"placeholder", TRUE,
|
||||
NULL);
|
||||
return g_object_new (GTK_TYPE_SIDEBAR_ROW, "placeholder", TRUE, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
drag_motion_callback (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
gint x,
|
||||
gint y,
|
||||
gpointer user_data)
|
||||
static void
|
||||
drag_motion_callback (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
gint x,
|
||||
gint y,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkPlacesSidebar *sidebar = GTK_PLACES_SIDEBAR (user_data);
|
||||
gint action;
|
||||
GtkListBoxRow *row;
|
||||
GtkPlacesSidebar *sidebar = GTK_PLACES_SIDEBAR (user_data);
|
||||
GtkPlacesSidebarPlaceType place_type;
|
||||
gchar *drop_target_uri = NULL;
|
||||
gint row_index;
|
||||
@@ -1776,7 +1748,7 @@ drag_motion_callback (GtkWidget *widget,
|
||||
|
||||
/* Nothing to do if no drag data */
|
||||
if (!sidebar->drag_data_received &&
|
||||
!get_drag_data (sidebar->list_box, drop, row))
|
||||
!get_drag_data (sidebar->list_box, dest, row))
|
||||
goto out;
|
||||
|
||||
/* Nothing to do if the target is not valid drop destination */
|
||||
@@ -1791,7 +1763,6 @@ drag_motion_callback (GtkWidget *widget,
|
||||
if (sidebar->row_placeholder == NULL)
|
||||
{
|
||||
sidebar->row_placeholder = create_placeholder_row (sidebar);
|
||||
gtk_widget_show (sidebar->row_placeholder);
|
||||
g_object_ref_sink (sidebar->row_placeholder);
|
||||
}
|
||||
else if (GTK_WIDGET (row) == sidebar->row_placeholder)
|
||||
@@ -1822,7 +1793,7 @@ drag_motion_callback (GtkWidget *widget,
|
||||
* of the row, we need to increase the order-index.
|
||||
*/
|
||||
row_placeholder_index = row_index;
|
||||
gtk_widget_translate_coordinates (widget, GTK_WIDGET (row),
|
||||
gtk_widget_translate_coordinates (GTK_WIDGET (sidebar), GTK_WIDGET (row),
|
||||
x, y,
|
||||
&dest_x, &dest_y);
|
||||
|
||||
@@ -1879,12 +1850,7 @@ drag_motion_callback (GtkWidget *widget,
|
||||
|
||||
out:
|
||||
start_drop_feedback (sidebar, GTK_SIDEBAR_ROW (row), drag);
|
||||
|
||||
g_signal_stop_emission_by_name (sidebar->list_box, "drag-motion");
|
||||
|
||||
gdk_drop_status (drop, action);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Takes an array of URIs and turns it into a list of GFile */
|
||||
@@ -1950,42 +1916,41 @@ drop_files_as_bookmarks (GtkPlacesSidebar *sidebar,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
drag_data_get_callback (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
GtkSelectionData *data,
|
||||
gpointer user_data)
|
||||
static GBytes *
|
||||
drag_data_get_callback (const char *mimetype,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkPlacesSidebar *sidebar = GTK_PLACES_SIDEBAR (user_data);
|
||||
GdkAtom target = gtk_selection_data_get_target (data);
|
||||
|
||||
if (target == g_intern_static_string ("DND_GTK_SIDEBAR_ROW"))
|
||||
{
|
||||
gtk_selection_data_set (data,
|
||||
target,
|
||||
8,
|
||||
(void*)&sidebar->drag_row,
|
||||
sizeof (gpointer));
|
||||
}
|
||||
if (mimetype == g_intern_static_string ("DND_GTK_SIDEBAR_ROW"))
|
||||
return g_bytes_new ((gpointer)&sidebar->drag_row, sizeof (gpointer));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
drag_data_received_callback (GtkWidget *list_box,
|
||||
GdkDrop *drop,
|
||||
GtkSelectionData *selection_data,
|
||||
gpointer user_data)
|
||||
drag_data_received_callback (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkDropTarget *dest = GTK_DROP_TARGET (source);
|
||||
GtkWidget *list_box = user_data;
|
||||
GtkPlacesSidebar *sidebar = GTK_PLACES_SIDEBAR (gtk_widget_get_ancestor (list_box, GTK_TYPE_PLACES_SIDEBAR));
|
||||
GdkDrop *drop = gtk_drop_target_get_drop (dest);
|
||||
GdkDrag *drag = gdk_drop_get_drag (drop);
|
||||
gint target_order_index;
|
||||
GtkPlacesSidebarPlaceType target_place_type;
|
||||
GtkPlacesSidebarSectionType target_section_type;
|
||||
gchar *target_uri;
|
||||
GtkPlacesSidebar *sidebar = GTK_PLACES_SIDEBAR (user_data);
|
||||
GtkListBoxRow *target_row;
|
||||
GdkDragAction real_action;
|
||||
GtkSelectionData *selection_data;
|
||||
|
||||
selection_data = gtk_drop_target_read_selection_finish (dest, result, NULL);
|
||||
|
||||
if (!sidebar->drag_data_received)
|
||||
{
|
||||
if (gtk_selection_data_targets_include_uri (selection_data))
|
||||
if (gtk_selection_data_get_target (selection_data) == g_intern_static_string ("text/uri-list"))
|
||||
{
|
||||
gchar **uris;
|
||||
|
||||
@@ -2001,19 +1966,22 @@ drag_data_received_callback (GtkWidget *list_box,
|
||||
{
|
||||
sidebar->drag_list = NULL;
|
||||
if (gtk_selection_data_get_target (selection_data) == g_intern_static_string ("DND_GTK_SIDEBAR_ROW"))
|
||||
sidebar->drag_data_info = DND_GTK_SIDEBAR_ROW;
|
||||
{
|
||||
sidebar->drag_data_info = DND_GTK_SIDEBAR_ROW;
|
||||
}
|
||||
}
|
||||
sidebar->drag_data_received = TRUE;
|
||||
}
|
||||
|
||||
g_signal_stop_emission_by_name (list_box, "drag-data-received");
|
||||
|
||||
if (!sidebar->drop_occurred)
|
||||
return;
|
||||
goto out_free;
|
||||
|
||||
target_row = g_object_get_data (G_OBJECT (drop), "places-sidebar-row");
|
||||
target_row = g_object_get_data (G_OBJECT (dest), "places-sidebar-row");
|
||||
if (target_row == NULL)
|
||||
return;
|
||||
goto out_free;
|
||||
|
||||
if (!check_valid_drop_target (sidebar, GTK_SIDEBAR_ROW (target_row), drag))
|
||||
goto out_free;
|
||||
|
||||
g_object_get (target_row,
|
||||
"place-type", &target_place_type,
|
||||
@@ -2021,12 +1989,8 @@ drag_data_received_callback (GtkWidget *list_box,
|
||||
"order-index", &target_order_index,
|
||||
"uri", &target_uri,
|
||||
NULL);
|
||||
|
||||
real_action = 0;
|
||||
|
||||
if (!check_valid_drop_target (sidebar, GTK_SIDEBAR_ROW (target_row), gdk_drop_get_drag (drop)))
|
||||
goto out;
|
||||
|
||||
if (sidebar->drag_data_info == DND_GTK_SIDEBAR_ROW)
|
||||
{
|
||||
GtkWidget **source_row;
|
||||
@@ -2081,18 +2045,20 @@ drag_data_received_callback (GtkWidget *list_box,
|
||||
|
||||
out:
|
||||
sidebar->drop_occurred = FALSE;
|
||||
g_object_set_data (G_OBJECT (drop), "places-sidebar-row", NULL);
|
||||
g_object_set_data (G_OBJECT (dest), "places-sidebar-row", NULL);
|
||||
gdk_drop_finish (drop, real_action);
|
||||
stop_drop_feedback (sidebar);
|
||||
g_free (target_uri);
|
||||
|
||||
out_free:
|
||||
gtk_selection_data_free (selection_data);
|
||||
}
|
||||
|
||||
static void
|
||||
drag_end_callback (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
gpointer user_data)
|
||||
dnd_finished_cb (GdkDrag *drag,
|
||||
GtkPlacesSidebar *sidebar)
|
||||
{
|
||||
stop_drop_feedback (GTK_PLACES_SIDEBAR (user_data));
|
||||
stop_drop_feedback (sidebar);
|
||||
}
|
||||
|
||||
/* This functions is called every time the drag source leaves
|
||||
@@ -2105,8 +2071,8 @@ drag_end_callback (GtkWidget *widget,
|
||||
* but that's not true, because this function is called also before drag_drop,
|
||||
* which needs the data from the drag so we cannot free the drag data here.
|
||||
* So now one could think we could just do nothing here, and wait for
|
||||
* drag-end or drag-failed signals and just stop_drop_feedback there. But that
|
||||
* is also not true, since when the drag comes from a diferent widget than the
|
||||
* drag-end or drag-cancel signals and just stop_drop_feedback there. But that
|
||||
* is also not true, since when the drag comes from a different widget than the
|
||||
* sidebar, when the drag stops the last drag signal we receive is drag-leave.
|
||||
* So here what we will do is restore the state of the sidebar as if no drag
|
||||
* is being done (and if the application didnt request for permanent hints with
|
||||
@@ -2114,9 +2080,9 @@ drag_end_callback (GtkWidget *widget,
|
||||
* we build new drag data in drag_data_received.
|
||||
*/
|
||||
static void
|
||||
drag_leave_callback (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
gpointer user_data)
|
||||
drag_leave_callback (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkPlacesSidebar *sidebar = GTK_PLACES_SIDEBAR (user_data);
|
||||
|
||||
@@ -2133,20 +2099,20 @@ drag_leave_callback (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
drag_drop_callback (GtkWidget *list_box,
|
||||
GdkDrop *drop,
|
||||
gint x,
|
||||
gint y,
|
||||
gpointer user_data)
|
||||
drag_drop_callback (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
int x,
|
||||
int y,
|
||||
gpointer user_data)
|
||||
{
|
||||
gboolean retval = FALSE;
|
||||
GtkPlacesSidebar *sidebar = GTK_PLACES_SIDEBAR (user_data);
|
||||
gboolean retval = FALSE;
|
||||
GtkListBoxRow *row;
|
||||
|
||||
row = gtk_list_box_get_row_at_y (GTK_LIST_BOX (sidebar->list_box), y);
|
||||
sidebar->drop_occurred = TRUE;
|
||||
retval = get_drag_data (sidebar->list_box, drop, row);
|
||||
g_signal_stop_emission_by_name (sidebar->list_box, "drag-drop");
|
||||
|
||||
retval = get_drag_data (sidebar->list_box, dest, row);
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -3778,6 +3744,13 @@ on_row_dragged (GtkGestureDrag *gesture,
|
||||
{
|
||||
gdouble start_x, start_y;
|
||||
gint drag_x, drag_y;
|
||||
GdkContentProvider *content;
|
||||
GdkSurface *surface;
|
||||
GdkDevice *device;
|
||||
GtkAllocation allocation;
|
||||
GtkWidget *drag_widget;
|
||||
GdkPaintable *paintable;
|
||||
GdkDrag *drag;
|
||||
|
||||
gtk_gesture_drag_get_start_point (gesture, &start_x, &start_y);
|
||||
gtk_widget_translate_coordinates (GTK_WIDGET (row),
|
||||
@@ -3787,10 +3760,35 @@ on_row_dragged (GtkGestureDrag *gesture,
|
||||
|
||||
sidebar->dragging_over = TRUE;
|
||||
|
||||
gtk_drag_begin (GTK_WIDGET (sidebar),
|
||||
gtk_gesture_get_device (GTK_GESTURE (gesture)),
|
||||
sidebar->source_targets, GDK_ACTION_MOVE,
|
||||
drag_x, drag_y);
|
||||
content = gdk_content_provider_new_with_formats (sidebar->source_targets,
|
||||
drag_data_get_callback,
|
||||
sidebar);
|
||||
|
||||
surface = gtk_native_get_surface (gtk_widget_get_native (GTK_WIDGET (sidebar)));
|
||||
device = gtk_gesture_get_device (GTK_GESTURE (gesture));
|
||||
|
||||
drag = gdk_drag_begin (surface, device, content, GDK_ACTION_MOVE, drag_x, drag_y);
|
||||
|
||||
g_object_unref (content);
|
||||
|
||||
g_signal_connect (drag, "dnd-finished", G_CALLBACK (dnd_finished_cb), sidebar);
|
||||
|
||||
gtk_widget_get_allocation (sidebar->drag_row, &allocation);
|
||||
gtk_widget_hide (sidebar->drag_row);
|
||||
|
||||
drag_widget = GTK_WIDGET (gtk_sidebar_row_clone (GTK_SIDEBAR_ROW (sidebar->drag_row)));
|
||||
sidebar->drag_row_height = allocation.height;
|
||||
gtk_widget_set_size_request (drag_widget, allocation.width, allocation.height);
|
||||
|
||||
gtk_widget_set_opacity (drag_widget, 0.8);
|
||||
|
||||
paintable = gtk_widget_paintable_new (drag_widget);
|
||||
gtk_drag_icon_set_from_paintable (drag, paintable, sidebar->drag_row_x, sidebar->drag_row_y);
|
||||
g_object_unref (paintable);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (drag), "row-widget", drag_widget, (GDestroyNotify)gtk_widget_destroy);
|
||||
|
||||
g_object_unref (drag);
|
||||
}
|
||||
|
||||
g_object_unref (sidebar);
|
||||
@@ -4022,11 +4020,13 @@ shell_shows_desktop_changed (GtkSettings *settings,
|
||||
static void
|
||||
gtk_places_sidebar_init (GtkPlacesSidebar *sidebar)
|
||||
{
|
||||
GdkContentFormats *target_list;
|
||||
GdkContentFormats *formats;
|
||||
GtkDropTarget *dest;
|
||||
gboolean show_desktop;
|
||||
GtkStyleContext *context;
|
||||
GtkEventController *controller;
|
||||
GtkGesture *gesture;
|
||||
GdkContentFormatsBuilder *builder;
|
||||
|
||||
sidebar->cancellable = g_cancellable_new ();
|
||||
|
||||
@@ -4079,31 +4079,22 @@ gtk_places_sidebar_init (GtkPlacesSidebar *sidebar)
|
||||
gtk_widget_add_controller (GTK_WIDGET (sidebar), GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
/* DND support */
|
||||
gtk_drag_dest_set (sidebar->list_box,
|
||||
0,
|
||||
NULL,
|
||||
GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK);
|
||||
target_list = gdk_content_formats_new (dnd_drop_targets, G_N_ELEMENTS (dnd_drop_targets));
|
||||
target_list = gtk_content_formats_add_uri_targets (target_list);
|
||||
gtk_drag_dest_set_target_list (sidebar->list_box, target_list);
|
||||
gdk_content_formats_unref (target_list);
|
||||
sidebar->source_targets = gdk_content_formats_new (dnd_source_targets, G_N_ELEMENTS (dnd_source_targets));
|
||||
sidebar->source_targets = gtk_content_formats_add_text_targets (sidebar->source_targets);
|
||||
builder = gdk_content_formats_builder_new ();
|
||||
gdk_content_formats_builder_add_mime_type (builder, "DND_GTK_SIDEBAR_ROW");
|
||||
gdk_content_formats_builder_add_gtype (builder, GDK_TYPE_FILE_LIST);
|
||||
formats = gdk_content_formats_builder_free_to_formats (builder);
|
||||
dest = gtk_drop_target_new (formats, GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK);
|
||||
gdk_content_formats_unref (formats);
|
||||
g_signal_connect (dest, "drag-motion", G_CALLBACK (drag_motion_callback), sidebar);
|
||||
g_signal_connect (dest, "drag-drop", G_CALLBACK (drag_drop_callback), sidebar);
|
||||
g_signal_connect (dest, "drag-leave", G_CALLBACK (drag_leave_callback), sidebar);
|
||||
gtk_widget_add_controller (sidebar->list_box, GTK_EVENT_CONTROLLER (dest));
|
||||
|
||||
builder = gdk_content_formats_builder_new ();
|
||||
gdk_content_formats_builder_add_mime_type (builder, "DND_GTK_SIDEBAR_ROW");
|
||||
gdk_content_formats_builder_add_gtype (builder, G_TYPE_STRING);
|
||||
sidebar->source_targets = gdk_content_formats_builder_free_to_formats (builder);
|
||||
|
||||
g_signal_connect (sidebar->list_box, "drag-begin",
|
||||
G_CALLBACK (drag_begin_callback), sidebar);
|
||||
g_signal_connect (sidebar->list_box, "drag-motion",
|
||||
G_CALLBACK (drag_motion_callback), sidebar);
|
||||
g_signal_connect (sidebar->list_box, "drag-data-get",
|
||||
G_CALLBACK (drag_data_get_callback), sidebar);
|
||||
g_signal_connect (sidebar->list_box, "drag-data-received",
|
||||
G_CALLBACK (drag_data_received_callback), sidebar);
|
||||
g_signal_connect (sidebar->list_box, "drag-drop",
|
||||
G_CALLBACK (drag_drop_callback), sidebar);
|
||||
g_signal_connect (sidebar->list_box, "drag-end",
|
||||
G_CALLBACK (drag_end_callback), sidebar);
|
||||
g_signal_connect (sidebar->list_box, "drag-leave",
|
||||
G_CALLBACK (drag_leave_callback), sidebar);
|
||||
sidebar->drag_row = NULL;
|
||||
sidebar->row_placeholder = NULL;
|
||||
sidebar->dragging_over = FALSE;
|
||||
|
||||
+2
-1
@@ -1482,7 +1482,8 @@ gtk_popover_set_relative_to (GtkPopover *popover,
|
||||
|
||||
if (priv->relative_to)
|
||||
{
|
||||
g_signal_connect (priv->relative_to, "size-allocate", G_CALLBACK (size_changed), popover);
|
||||
g_signal_connect_object (priv->relative_to, "size-allocate",
|
||||
G_CALLBACK (size_changed), popover, 0);
|
||||
gtk_css_node_set_parent (gtk_widget_get_css_node (GTK_WIDGET (popover)),
|
||||
gtk_widget_get_css_node (relative_to));
|
||||
gtk_widget_set_parent (GTK_WIDGET (popover), relative_to);
|
||||
|
||||
@@ -633,7 +633,7 @@ gtk_popover_menu_set_menu_model (GtkPopoverMenu *popover,
|
||||
*
|
||||
* Returns the menu model used to populate the popover.
|
||||
*
|
||||
* Returns: the menu model of @popover
|
||||
* Returns: (transfer none): the menu model of @popover
|
||||
*/
|
||||
GMenuModel *
|
||||
gtk_popover_menu_get_menu_model (GtkPopoverMenu *popover)
|
||||
|
||||
+1
-1
@@ -693,7 +693,7 @@ gtk_print_job_get_property (GObject *object,
|
||||
* gtk_print_job_send:
|
||||
* @job: a GtkPrintJob
|
||||
* @callback: function to call when the job completes or an error occurs
|
||||
* @user_data: user data that gets passed to @callback
|
||||
* @user_data: (closure): user data that gets passed to @callback
|
||||
* @dnotify: destroy notify for @user_data
|
||||
*
|
||||
* Sends the print job off to the printer.
|
||||
|
||||
@@ -460,7 +460,7 @@ gtk_print_settings_set_int (GtkPrintSettings *settings,
|
||||
* gtk_print_settings_foreach:
|
||||
* @settings: a #GtkPrintSettings
|
||||
* @func: (scope call): the function to call
|
||||
* @user_data: user data for @func
|
||||
* @user_data: (closure): user data for @func
|
||||
*
|
||||
* Calls @func for each key-value pair of @settings.
|
||||
*/
|
||||
|
||||
+1
-1
@@ -90,7 +90,7 @@ gboolean _gtk_translate_keyboard_accel_state (GdkKeymap *keymap,
|
||||
gint *level,
|
||||
GdkModifierType *consumed_modifiers);
|
||||
|
||||
void gtk_propagate_event_internal (GtkWidget *widget,
|
||||
gboolean gtk_propagate_event_internal (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
GtkWidget *topmost);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user