X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkdnd-quartz.c;h=57601055703f225ccc7b96fdb4f321e7752bdbdc;hb=1865b9a1116d166c9abc5c75f5d01270574007c5;hp=f541cf1689378e068992dd970ab5eed034f1b8a9;hpb=96d8f85dcc2781575836740386512d448337b44a;p=~andy%2Fgtk diff --git a/gtk/gtkdnd-quartz.c b/gtk/gtkdnd-quartz.c index f541cf168..576010557 100644 --- a/gtk/gtkdnd-quartz.c +++ b/gtk/gtkdnd-quartz.c @@ -12,9 +12,7 @@ * 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, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ /* @@ -34,16 +32,16 @@ #include "gtkdnd.h" #include "gtkiconfactory.h" #include "gtkicontheme.h" -#include "gtkimage.h" +#include "gtkimageprivate.h" #include "gtkinvisible.h" #include "gtkmain.h" -#include "gtkplug.h" #include "gtkstock.h" #include "gtkwindow.h" #include "gtkintl.h" #include "gtkquartz.h" #include "gdk/quartz/gdkquartz.h" #include "gtkselectionprivate.h" +#include "gtksettings.h" typedef struct _GtkDragSourceSite GtkDragSourceSite; typedef struct _GtkDragSourceInfo GtkDragSourceInfo; @@ -147,6 +145,7 @@ struct _GtkDragFindData selection_data.data = NULL; selection_data.length = -1; selection_data.target = _gtk_quartz_pasteboard_type_to_atom (type); + selection_data.display = gdk_display_get_default (); if (gtk_target_list_find (info->target_list, selection_data.target, @@ -179,6 +178,16 @@ struct _GtkDragFindData @end +/** + * gtk_drag_get_data: (method) + * @widget: the widget that will receive the + * #GtkWidget::drag-data-received signal. + * @context: the drag context + * @target: the target (form of the data) to retrieve. + * @time_: a timestamp for retrieving the data. This will + * generally be the time received in a #GtkWidget::drag-motion" + * or #GtkWidget::drag-drop" signal. + */ void gtk_drag_get_data (GtkWidget *widget, GdkDragContext *context, @@ -235,6 +244,14 @@ gtk_drag_get_data (GtkWidget *widget, } } +/** + * gtk_drag_finish: (method) + * @context: the drag context. + * @success: a flag indicating whether the drop was successful + * @del: a flag indicating whether the source should delete the + * original data. (This should be %TRUE for a move) + * @time_: the timestamp from the #GtkWidget::drag-drop signal. + */ void gtk_drag_finish (GdkDragContext *context, gboolean success, @@ -314,6 +331,10 @@ gtk_drag_clear_source_info (GdkDragContext *context) g_object_set_qdata (G_OBJECT (context), dest_info_quark, NULL); } +/** + * gtk_drag_get_source_widget: (method) + * @context: a (destination side) drag context + */ GtkWidget * gtk_drag_get_source_widget (GdkDragContext *context) { @@ -347,7 +368,7 @@ gtk_drag_highlight_draw (GtkWidget *widget, { int width = gtk_widget_get_allocated_width (widget); int height = gtk_widget_get_allocated_height (widget); - GtkStyleContext *context; + GtkStyleContext *context = gtk_widget_get_style_context (widget); gtk_style_context_save (context); gtk_style_context_add_class (context, GTK_STYLE_CLASS_DND); @@ -366,14 +387,10 @@ gtk_drag_highlight_draw (GtkWidget *widget, return FALSE; } -/************************************************************* - * gtk_drag_highlight: - * Highlight the given widget in the default manner. - * arguments: - * widget: - * results: - *************************************************************/ - +/** + * gtk_drag_highlight: (method) + * @widget: a widget to highlight + */ void gtk_drag_highlight (GtkWidget *widget) { @@ -386,14 +403,10 @@ gtk_drag_highlight (GtkWidget *widget) gtk_widget_queue_draw (widget); } -/************************************************************* - * gtk_drag_unhighlight: - * Refresh the given widget to remove the highlight. - * arguments: - * widget: - * results: - *************************************************************/ - +/** + * gtk_drag_unhighlight: (method) + * @widget: a widget to remove the highlight from. + */ void gtk_drag_unhighlight (GtkWidget *widget) { @@ -470,6 +483,17 @@ gtk_drag_dest_site_destroy (gpointer data) g_free (site); } +/** + * gtk_drag_dest_set: (method) + * @widget: a #GtkWidget + * @flags: which types of default drag behavior to use + * @targets: (allow-none) (array length=n_targets): a pointer to an array of #GtkTargetEntrys + * indicating the drop types that this @widget will accept, or %NULL. + * Later you can access the list with gtk_drag_dest_get_target_list() + * and gtk_drag_dest_find_target(). + * @n_targets: the number of entries in @targets + * @actions: a bitmask of possible actions for a drop onto this @widget. + */ void gtk_drag_dest_set (GtkWidget *widget, GtkDestDefaults flags, @@ -511,6 +535,16 @@ gtk_drag_dest_set (GtkWidget *widget, site, gtk_drag_dest_site_destroy); } +/** + * gtk_drag_dest_set_proxy: (method) + * @widget: a #GtkWidget + * @proxy_window: the window to which to forward drag events + * @protocol: the drag protocol which the @proxy_window accepts + * (You can use gdk_drag_get_protocol() to determine this) + * @use_coordinates: If %TRUE, send the same coordinates to the + * destination, because it is an embedded + * subwindow. + */ void gtk_drag_dest_set_proxy (GtkWidget *widget, GdkWindow *proxy_window, @@ -520,6 +554,10 @@ gtk_drag_dest_set_proxy (GtkWidget *widget, g_warning ("gtk_drag_dest_set_proxy is not supported on Mac OS X."); } +/** + * gtk_drag_dest_unset: (method) + * @widget: a #GtkWidget + */ void gtk_drag_dest_unset (GtkWidget *widget) { @@ -541,6 +579,10 @@ gtk_drag_dest_unset (GtkWidget *widget) g_object_set_data (G_OBJECT (widget), I_("gtk-drag-dest"), NULL); } +/** + * gtk_drag_dest_get_target_list: (method) + * @widget: a #GtkWidget + */ GtkTargetList* gtk_drag_dest_get_target_list (GtkWidget *widget) { @@ -553,6 +595,11 @@ gtk_drag_dest_get_target_list (GtkWidget *widget) return site ? site->target_list : NULL; } +/** + * gtk_drag_dest_set_target_list: (method) + * @widget: a #GtkWidget that's a drag destination + * @target_list: (allow-none): list of droppable targets, or %NULL for none + */ void gtk_drag_dest_set_target_list (GtkWidget *widget, GtkTargetList *target_list) @@ -581,6 +628,10 @@ gtk_drag_dest_set_target_list (GtkWidget *widget, register_types (widget, site); } +/** + * gtk_drag_dest_add_text_targets: (method) + * @widget: a #GtkWidget that's a drag destination + */ void gtk_drag_dest_add_text_targets (GtkWidget *widget) { @@ -596,6 +647,11 @@ gtk_drag_dest_add_text_targets (GtkWidget *widget) gtk_target_list_unref (target_list); } + +/** + * gtk_drag_dest_add_image_targets: (method) + * @widget: a #GtkWidget that's a drag destination + */ void gtk_drag_dest_add_image_targets (GtkWidget *widget) { @@ -611,6 +667,10 @@ gtk_drag_dest_add_image_targets (GtkWidget *widget) gtk_target_list_unref (target_list); } +/** + * gtk_drag_dest_add_uri_targets: (method) + * @widget: a #GtkWidget that's a drag destination + */ void gtk_drag_dest_add_uri_targets (GtkWidget *widget) { @@ -878,6 +938,11 @@ gtk_drag_dest_drop (GtkWidget *widget, return (site->flags & GTK_DEST_DEFAULT_DROP) ? TRUE : retval; } +/** + * gtk_drag_dest_set_track_motion: (method) + * @widget: a #GtkWidget that's a drag destination + * @track_motion: whether to accept all targets + */ void gtk_drag_dest_set_track_motion (GtkWidget *widget, gboolean track_motion) @@ -893,6 +958,10 @@ gtk_drag_dest_set_track_motion (GtkWidget *widget, site->track_motion = track_motion != FALSE; } +/** + * gtk_drag_dest_get_track_motion: (method) + * @widget: a #GtkWidget that's a drag destination + */ gboolean gtk_drag_dest_get_track_motion (GtkWidget *widget) { @@ -991,6 +1060,13 @@ _gtk_drag_dest_handle_event (GtkWidget *toplevel, } +/** + * gtk_drag_dest_find_target: (method) + * @widget: drag destination widget + * @context: drag context + * @target_list: (allow-none): list of droppable targets, or %NULL to use + * gtk_drag_dest_get_target_list (@widget). + */ GdkAtom gtk_drag_dest_find_target (GtkWidget *widget, GdkDragContext *context, @@ -1071,7 +1147,7 @@ gtk_drag_begin_idle (gpointer arg) [types release]; if ((nswindow = get_toplevel_nswindow (info->source_widget)) == NULL) - return FALSE; + return G_SOURCE_REMOVE; /* Ref the context. It's unreffed when the drag has been aborted */ g_object_ref (info->context); @@ -1080,13 +1156,18 @@ gtk_drag_begin_idle (gpointer arg) point = [info->nsevent locationInWindow]; drag_image = _gtk_quartz_create_image_from_pixbuf (info->icon_pixbuf); + if (drag_image == NULL) + { + g_object_unref (info->context); + return G_SOURCE_REMOVE; + } point.x -= info->hot_x; point.y -= info->hot_y; [nswindow dragImage:drag_image at:point - offset:NSMakeSize(0, 0) + offset:NSZeroSize event:info->nsevent pasteboard:pasteboard source:nswindow @@ -1097,8 +1178,15 @@ gtk_drag_begin_idle (gpointer arg) [pool release]; - return FALSE; + return G_SOURCE_REMOVE; } +/* Fake protocol to let us call GdkNSView gdkWindow without including + * gdk/GdkNSView.h (which we can't because it pulls in the internal-only + * gdkwindow.h). + */ +@protocol GdkNSView +- (GdkWindow *)gdkWindow; +@end static GdkDragContext * gtk_drag_begin_internal (GtkWidget *widget, @@ -1109,20 +1197,71 @@ gtk_drag_begin_internal (GtkWidget *widget, GdkEvent *event) { GtkDragSourceInfo *info; + GdkDevice *pointer; + GdkWindow *window; GdkDragContext *context; - NSWindow *nswindow; + NSWindow *nswindow = get_toplevel_nswindow (widget); + NSPoint point = {0, 0}; + gdouble x, y; + double time = (double)g_get_real_time (); + NSEvent *nsevent; + NSTimeInterval nstime; + + if (event) + { + if (gdk_event_get_coords (event, &x, &y)) + { + /* We need to translate (x, y) to coordinates relative to the + * toplevel GdkWindow, which should be the GdkWindow backing + * nswindow. Then, we convert to the NSWindow coordinate system. + */ + GdkWindow *window = event->any.window; + GdkWindow *toplevel = gdk_window_get_effective_toplevel (window); + + while (window != toplevel) + { + double old_x = x; + double old_y = y; + + gdk_window_coords_to_parent (window, old_x, old_y, + &x, &y); + window = gdk_window_get_effective_parent (window); + } + + point.x = x; + point.y = gdk_window_get_height (window) - y; + } + time = (double)gdk_event_get_time (event); + } + + nstime = [[NSDate dateWithTimeIntervalSince1970: time / 1000] timeIntervalSinceReferenceDate]; + nsevent = [NSEvent mouseEventWithType: NSLeftMouseDown + location: point + modifierFlags: 0 + timestamp: nstime + windowNumber: [nswindow windowNumber] + context: [nswindow graphicsContext] + eventNumber: 0 + clickCount: 1 + pressure: 0.0 ]; - context = gdk_drag_begin (gtk_widget_get_window (widget), NULL); + window = [(id)[nswindow contentView] gdkWindow]; + g_return_val_if_fail (nsevent != NULL, NULL); + + context = gdk_drag_begin (window, NULL); + g_return_val_if_fail (context != NULL, NULL); info = gtk_drag_get_source_info (context, TRUE); - + info->nsevent = nsevent; + [info->nsevent retain]; + info->source_widget = g_object_ref (widget); info->widget = g_object_ref (widget); info->target_list = target_list; gtk_target_list_ref (target_list); info->possible_actions = actions; - + g_signal_emit_by_name (widget, "drag-begin", info->context); /* Ensure that we have an icon before we start the drag; the @@ -1132,45 +1271,53 @@ gtk_drag_begin_internal (GtkWidget *widget, if (!info->icon_pixbuf) { if (!site || site->icon_type == GTK_IMAGE_EMPTY) - gtk_drag_set_icon_default (context); + gtk_drag_set_icon_default (context); else - switch (site->icon_type) - { - case GTK_IMAGE_PIXBUF: - gtk_drag_set_icon_pixbuf (context, - site->icon_data.pixbuf.pixbuf, - -2, -2); - break; - case GTK_IMAGE_STOCK: - gtk_drag_set_icon_stock (context, - site->icon_data.stock.stock_id, - -2, -2); - break; - case GTK_IMAGE_ICON_NAME: - gtk_drag_set_icon_name (context, - site->icon_data.name.icon_name, - -2, -2); - break; - case GTK_IMAGE_EMPTY: - default: - g_assert_not_reached(); - break; - } + { + switch (site->icon_type) + { + case GTK_IMAGE_PIXBUF: + gtk_drag_set_icon_pixbuf (context, + site->icon_data.pixbuf.pixbuf, + -2, -2); + break; + case GTK_IMAGE_STOCK: + gtk_drag_set_icon_stock (context, + site->icon_data.stock.stock_id, + -2, -2); + break; + case GTK_IMAGE_ICON_NAME: + gtk_drag_set_icon_name (context, + site->icon_data.name.icon_name, + -2, -2); + break; + case GTK_IMAGE_EMPTY: + default: + g_assert_not_reached(); + break; + } + } } - nswindow = get_toplevel_nswindow (widget); - info->nsevent = [nswindow currentEvent]; - [info->nsevent retain]; - /* drag will begin in an idle handler to avoid nested run loops */ g_idle_add_full (G_PRIORITY_HIGH_IDLE, gtk_drag_begin_idle, context, NULL); - gdk_pointer_ungrab (0); + pointer = gdk_drag_context_get_device (info->context); + gdk_device_ungrab (pointer, 0); return context; } +/** + * gtk_drag_begin: (method) + * @widget: the source widget. + * @targets: The targets (data formats) in which the + * source can provide the data. + * @actions: A bitmask of the allowed drag actions for this drag. + * @button: The button the user clicked to start the drag. + * @event: The event that triggered the start of the drag. + */ GdkDragContext * gtk_drag_begin (GtkWidget *widget, GtkTargetList *targets, @@ -1246,6 +1393,15 @@ gtk_drag_source_event_cb (GtkWidget *widget, return retval; } +/** + * gtk_drag_source_set: (method) + * @widget: a #GtkWidget + * @start_button_mask: the bitmask of buttons that can start the drag + * @targets: (allow-none) (array length=n_targets): the table of targets that the drag will support, + * may be %NULL + * @n_targets: the number of items in @targets + * @actions: the bitmask of possible actions for a drag from this widget + */ void gtk_drag_source_set (GtkWidget *widget, GdkModifierType start_button_mask, @@ -1297,14 +1453,10 @@ gtk_drag_source_set (GtkWidget *widget, site->actions = actions; } -/************************************************************* - * gtk_drag_source_unset - * Unregister this widget as a drag source. - * arguments: - * widget: - * results: - *************************************************************/ - +/** + * gtk_drag_source_unset: (method) + * @widget: a #GtkWidget + */ void gtk_drag_source_unset (GtkWidget *widget) { @@ -1323,6 +1475,10 @@ gtk_drag_source_unset (GtkWidget *widget) } } +/** + * gtk_drag_source_get_target_list: (method) + * @widget: a #GtkWidget + */ GtkTargetList * gtk_drag_source_get_target_list (GtkWidget *widget) { @@ -1336,6 +1492,11 @@ gtk_drag_source_get_target_list (GtkWidget *widget) } +/** + * 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 + */ void gtk_drag_source_set_target_list (GtkWidget *widget, GtkTargetList *target_list) @@ -1388,6 +1549,10 @@ gtk_drag_source_add_text_targets (GtkWidget *widget) gtk_target_list_unref (target_list); } +/** + * gtk_drag_source_add_image_targets: (method) + * @widget: a #GtkWidget that's is a drag source + */ void gtk_drag_source_add_image_targets (GtkWidget *widget) { @@ -1403,6 +1568,10 @@ gtk_drag_source_add_image_targets (GtkWidget *widget) gtk_target_list_unref (target_list); } +/** + * gtk_drag_source_add_uri_targets: (method) + * @widget: a #GtkWidget that's is a drag source + */ void gtk_drag_source_add_uri_targets (GtkWidget *widget) { @@ -1453,6 +1622,11 @@ gtk_drag_source_site_destroy (gpointer data) g_free (site); } +/** + * gtk_drag_source_set_icon_pixbuf: (method) + * @widget: a #GtkWidget + * @pixbuf: the #GdkPixbuf for the drag icon + */ void gtk_drag_source_set_icon_pixbuf (GtkWidget *widget, GdkPixbuf *pixbuf) @@ -1774,6 +1948,9 @@ gtk_drag_set_icon_default (GdkDragContext *context) static void gtk_drag_source_info_destroy (GtkDragSourceInfo *info) { + NSPasteboard *pasteboard; + NSAutoreleasePool *pool; + if (info->icon_pixbuf) g_object_unref (info->icon_pixbuf); @@ -1788,17 +1965,28 @@ gtk_drag_source_info_destroy (GtkDragSourceInfo *info) gtk_target_list_unref (info->target_list); + pool = [[NSAutoreleasePool alloc] init]; + + /* Empty the pasteboard, so that it will not accidentally access + * info->context after it has been destroyed. + */ + pasteboard = [NSPasteboard pasteboardWithName: NSDragPboard]; + [pasteboard declareTypes: nil owner: nil]; + + [pool release]; + gtk_drag_clear_source_info (info->context); g_object_unref (info->context); g_free (info); + info = NULL; } static gboolean drag_drop_finished_idle_cb (gpointer data) { gtk_drag_source_info_destroy (data); - return FALSE; + return G_SOURCE_REMOVE; } static void @@ -1851,7 +2039,14 @@ _gtk_drag_source_handle_event (GtkWidget *widget, } } - +/** + * gtk_drag_check_threshold: (method) + * @widget: a #GtkWidget + * @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 + */ gboolean gtk_drag_check_threshold (GtkWidget *widget, gint start_x,