diff options
author | Pavel Cisler <pavel@eazel.com> | 2000-04-12 18:33:04 +0000 |
---|---|---|
committer | Pavel Cisler <pce@src.gnome.org> | 2000-04-12 18:33:04 +0000 |
commit | 8ecf5b4898c50b0f7641f444cdc1f71eab1385c6 (patch) | |
tree | bd6145dbedc4c91af61e7951b5e210f024005cc0 | |
parent | d140e4fc8da174b0d71a4f53957252cf2a5a2d45 (diff) | |
download | nautilus-8ecf5b4898c50b0f7641f444cdc1f71eab1385c6.tar.gz |
Fix a problem where drag actions did't update properly when dragging
2000-04-11 Pavel Cisler <pavel@eazel.com>
* libnautilus/nautilus-icon-dnd.c:
* libnautilus/nautilus-icon-dnd.h:
Fix a problem where drag actions did't update properly when dragging
between two windows. The pointer to the private GtkDragStatus needs
to be global, not stored in the drag originator widget.
-rw-r--r-- | ChangeLog-20000414 | 8 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-icon-dnd.c | 163 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-icon-dnd.h | 8 | ||||
-rw-r--r-- | libnautilus-private/nautilus-icon-dnd.c | 163 | ||||
-rw-r--r-- | libnautilus-private/nautilus-icon-dnd.h | 8 | ||||
-rw-r--r-- | libnautilus/nautilus-icon-dnd.c | 163 | ||||
-rw-r--r-- | libnautilus/nautilus-icon-dnd.h | 8 |
7 files changed, 245 insertions, 276 deletions
diff --git a/ChangeLog-20000414 b/ChangeLog-20000414 index 3fdc877eb..929479a35 100644 --- a/ChangeLog-20000414 +++ b/ChangeLog-20000414 @@ -1,3 +1,11 @@ +2000-04-11 Pavel Cisler <pavel@eazel.com> + + * libnautilus/nautilus-icon-dnd.c: + * libnautilus/nautilus-icon-dnd.h: + Fix a problem where drag actions did't update properly when dragging + between two windows. The pointer to the private GtkDragStatus needs + to be global, not stored in the drag originator widget. + 2000-04-11 Andy Hertzfeld <andy@eazel.com> * components/services/startup/eazel-register.c: diff --git a/libnautilus-extensions/nautilus-icon-dnd.c b/libnautilus-extensions/nautilus-icon-dnd.c index f3cd41f97..81dabe433 100644 --- a/libnautilus-extensions/nautilus-icon-dnd.c +++ b/libnautilus-extensions/nautilus-icon-dnd.c @@ -54,6 +54,10 @@ static gboolean drag_drop_callback (GtkWidget *widget, static void nautilus_icon_dnd_update_drop_target (NautilusIconContainer *container, GdkDragContext *context, int x, int y); +static gboolean drag_motion_callback (GtkWidget *widget, + GdkDragContext *context, + int x, int y, + guint32 time); typedef struct { @@ -509,22 +513,6 @@ nautilus_icon_container_ensure_drag_data (NautilusIconContainer *container, } } -static gboolean -drag_motion_callback (GtkWidget *widget, - GdkDragContext *context, - int x, int y, - guint32 time) -{ - nautilus_icon_dnd_update_drop_action (widget); - nautilus_icon_container_ensure_drag_data (NAUTILUS_ICON_CONTAINER (widget), context, time); - nautilus_icon_container_position_shadow (NAUTILUS_ICON_CONTAINER (widget), x, y); - nautilus_icon_dnd_update_drop_target (NAUTILUS_ICON_CONTAINER (widget), context, x, y); - - gdk_drag_status (context, context->suggested_action, time); - - return TRUE; -} - static void drag_end_callback (GtkWidget *widget, GdkDragContext *context, @@ -903,6 +891,51 @@ drag_leave_callback (GtkWidget *widget, gnome_canvas_item_hide (dnd_info->shadow); } +/* During drag&drop keep a saved pointer to the private drag context. + * We also replace the severely broken gtk_drag_get_event_actions. + * To do this we copy a lot of code from gtkdnd.c. + * + * This is a hack-workaround to deal with the inability to override + * drag action feedback in gtk and will be removed once the appropriate + * interface gets added to gtkdnd to do this in a clean way. + * For now we need to mirror the code here + * to allow us to control the drop action based on the modifier + * key state, drop target and other drag&drop state. + * + * FIXME: + */ + +typedef struct GtkDragDestInfo GtkDragDestInfo; +typedef struct GtkDragStatus GtkDragStatus; + +typedef struct GtkDragSourceInfo +{ + GtkWidget *widget; + GtkTargetList *target_list; /* Targets for drag data */ + GdkDragAction possible_actions; /* Actions allowed by source */ + GdkDragContext *context; /* drag context */ + GtkWidget *icon_window; /* Window for drag */ + GtkWidget *ipc_widget; /* GtkInvisible for grab, message passing */ + GdkCursor *cursor; /* Cursor for drag */ + gint hot_x, hot_y; /* Hot spot for drag */ + gint button; /* mouse button starting drag */ + + gint status; /* drag status !!! GtkDragStatus in real life*/ + GdkEvent *last_event; /* motion event waiting for response */ + + gint start_x, start_y; /* Initial position */ + gint cur_x, cur_y; /* Current Position */ + + GList *selections; /* selections we've claimed */ + + GtkDragDestInfo *proxy_dest; /* Set if this is a proxy drag */ + + guint drop_timeout; /* Timeout for aborting drop */ + guint destroy_icon : 1; /* If true, destroy icon_window + */ +} GtkDragSourceInfo; +static GtkDragSourceInfo *saved_drag_source_info; + void nautilus_icon_dnd_init (NautilusIconContainer *container, GdkBitmap *stipple) @@ -945,7 +978,7 @@ nautilus_icon_dnd_init (NautilusIconContainer *container, GTK_SIGNAL_FUNC (drag_leave_callback), NULL); container->details->dnd_info = dnd_info; - container->details->dnd_info->saved_drag_source_info = NULL; + saved_drag_source_info = NULL; } @@ -972,50 +1005,6 @@ nautilus_icon_dnd_fini (NautilusIconContainer *container) } -/* During drag&drop keep a saved pointer to the private drag context. - * We also replace the severely broken gtk_drag_get_event_actions. - * To do this we copy a lot of code from gtkdnd.c. - * - * This is a hack-workaround to deal with the inability to override - * drag action feedback in gtk and will be removed once the appropriate - * interface gets added to gtkdnd to do this in a clean way. - * For now we need to mirror the code here - * to allow us to control the drop action based on the modifier - * key state, drop target and other drag&drop state. - * - * FIXME: - */ - -typedef struct GtkDragDestInfo GtkDragDestInfo; -typedef struct GtkDragStatus GtkDragStatus; - -typedef struct GtkDragSourceInfo -{ - GtkWidget *widget; - GtkTargetList *target_list; /* Targets for drag data */ - GdkDragAction possible_actions; /* Actions allowed by source */ - GdkDragContext *context; /* drag context */ - GtkWidget *icon_window; /* Window for drag */ - GtkWidget *ipc_widget; /* GtkInvisible for grab, message passing */ - GdkCursor *cursor; /* Cursor for drag */ - gint hot_x, hot_y; /* Hot spot for drag */ - gint button; /* mouse button starting drag */ - - gint status; /* drag status !!! GtkDragStatus in real life*/ - GdkEvent *last_event; /* motion event waiting for response */ - - gint start_x, start_y; /* Initial position */ - gint cur_x, cur_y; /* Current Position */ - - GList *selections; /* selections we've claimed */ - - GtkDragDestInfo *proxy_dest; /* Set if this is a proxy drag */ - - guint drop_timeout; /* Timeout for aborting drop */ - guint destroy_icon : 1; /* If true, destroy icon_window - */ -} GtkDragSourceInfo; - static GtkDragSourceInfo * nautilus_icon_dnd_get_drag_source_info (GtkWidget *widget, GdkDragContext *context) { @@ -1040,7 +1029,6 @@ nautilus_icon_dnd_begin_drag (NautilusIconContainer *container, int x_offset, y_offset; ArtDRect world_rect; ArtIRect window_rect; - GtkDragSourceInfo *info; g_return_if_fail (NAUTILUS_IS_ICON_CONTAINER (container)); g_return_if_fail (event != NULL); @@ -1064,15 +1052,13 @@ nautilus_icon_dnd_begin_drag (NautilusIconContainer *container, (GdkEvent *) event); /* set up state for overriding the broken gtk_drag_get_event_actions call */ - info = nautilus_icon_dnd_get_drag_source_info (GTK_WIDGET (container), context); - container->details->dnd_info->saved_drag_source_info = info; - - g_assert (info != NULL); - - gtk_signal_connect (GTK_OBJECT (info ? info->ipc_widget : NULL), "key_press_event", - GTK_SIGNAL_FUNC (nautilus_icon_drag_key_callback), info); - gtk_signal_connect (GTK_OBJECT (info ? info->ipc_widget : NULL), "key_release_event", - GTK_SIGNAL_FUNC (nautilus_icon_drag_key_callback), info); + saved_drag_source_info = nautilus_icon_dnd_get_drag_source_info (GTK_WIDGET (container), context); + g_assert (saved_drag_source_info != NULL); + + gtk_signal_connect (GTK_OBJECT (saved_drag_source_info ? saved_drag_source_info->ipc_widget : NULL), "key_press_event", + GTK_SIGNAL_FUNC (nautilus_icon_drag_key_callback), saved_drag_source_info); + gtk_signal_connect (GTK_OBJECT (saved_drag_source_info ? saved_drag_source_info->ipc_widget : NULL), "key_release_event", + GTK_SIGNAL_FUNC (nautilus_icon_drag_key_callback), saved_drag_source_info); container->details->dnd_info->current_drop_target_icon = NULL; @@ -1115,6 +1101,22 @@ nautilus_icon_dnd_begin_drag (NautilusIconContainer *container, } static gboolean +drag_motion_callback (GtkWidget *widget, + GdkDragContext *context, + int x, int y, + guint32 time) +{ + nautilus_icon_dnd_update_drop_action (widget); + nautilus_icon_container_ensure_drag_data (NAUTILUS_ICON_CONTAINER (widget), context, time); + nautilus_icon_container_position_shadow (NAUTILUS_ICON_CONTAINER (widget), x, y); + nautilus_icon_dnd_update_drop_target (NAUTILUS_ICON_CONTAINER (widget), context, x, y); + + gdk_drag_status (context, context->suggested_action, time); + + return TRUE; +} + +static gboolean drag_drop_callback (GtkWidget *widget, GdkDragContext *context, int x, @@ -1123,7 +1125,6 @@ drag_drop_callback (GtkWidget *widget, gpointer data) { NautilusIconDndInfo *dnd_info; - GtkDragSourceInfo *info; dnd_info = NAUTILUS_ICON_CONTAINER (widget)->details->dnd_info; @@ -1149,16 +1150,13 @@ drag_drop_callback (GtkWidget *widget, nautilus_icon_container_free_drag_data (NAUTILUS_ICON_CONTAINER (widget)); - info = NAUTILUS_ICON_CONTAINER (widget)->details->dnd_info->saved_drag_source_info; - g_assert (info != NULL); - - if (info != NULL) { - gtk_signal_disconnect_by_func (GTK_OBJECT (info->ipc_widget), + if (saved_drag_source_info != NULL) { + gtk_signal_disconnect_by_func (GTK_OBJECT (saved_drag_source_info->ipc_widget), GTK_SIGNAL_FUNC (nautilus_icon_drag_key_callback), - info); + saved_drag_source_info); } - NAUTILUS_ICON_CONTAINER (widget)->details->dnd_info->saved_drag_source_info = NULL; + saved_drag_source_info = NULL; NAUTILUS_ICON_CONTAINER (widget)->details->dnd_info->current_drop_target_icon = NULL; return FALSE; @@ -1202,13 +1200,10 @@ nautilus_icon_dnd_modifier_based_action () void nautilus_icon_dnd_update_drop_action (GtkWidget *widget) { - GtkDragSourceInfo *info; - - info = NAUTILUS_ICON_CONTAINER (widget)->details->dnd_info->saved_drag_source_info; - if (info == NULL) + if (saved_drag_source_info == NULL) return; - info->possible_actions = nautilus_icon_dnd_modifier_based_action (); + saved_drag_source_info->possible_actions = nautilus_icon_dnd_modifier_based_action (); } /* Replacement for broken gtk_drag_get_event_actions */ diff --git a/libnautilus-extensions/nautilus-icon-dnd.h b/libnautilus-extensions/nautilus-icon-dnd.h index 821dd3d9b..ec7069630 100644 --- a/libnautilus-extensions/nautilus-icon-dnd.h +++ b/libnautilus-extensions/nautilus-icon-dnd.h @@ -72,14 +72,6 @@ struct NautilusIconDndInfo { /* Shadow for the icons being dragged. */ GnomeCanvasItem *shadow; - - /* During drag&drop keep a saved pointer to the private drag context. - * This is a hack-workaround to deal with the inability to override - * drag action feedback in gtk and will be removed once the appropriate - * interface gets added to gtkdnd to do this in a clean way - */ - gpointer saved_drag_source_info; - /* last highlighted drop target*/ gpointer current_drop_target_icon; }; diff --git a/libnautilus-private/nautilus-icon-dnd.c b/libnautilus-private/nautilus-icon-dnd.c index f3cd41f97..81dabe433 100644 --- a/libnautilus-private/nautilus-icon-dnd.c +++ b/libnautilus-private/nautilus-icon-dnd.c @@ -54,6 +54,10 @@ static gboolean drag_drop_callback (GtkWidget *widget, static void nautilus_icon_dnd_update_drop_target (NautilusIconContainer *container, GdkDragContext *context, int x, int y); +static gboolean drag_motion_callback (GtkWidget *widget, + GdkDragContext *context, + int x, int y, + guint32 time); typedef struct { @@ -509,22 +513,6 @@ nautilus_icon_container_ensure_drag_data (NautilusIconContainer *container, } } -static gboolean -drag_motion_callback (GtkWidget *widget, - GdkDragContext *context, - int x, int y, - guint32 time) -{ - nautilus_icon_dnd_update_drop_action (widget); - nautilus_icon_container_ensure_drag_data (NAUTILUS_ICON_CONTAINER (widget), context, time); - nautilus_icon_container_position_shadow (NAUTILUS_ICON_CONTAINER (widget), x, y); - nautilus_icon_dnd_update_drop_target (NAUTILUS_ICON_CONTAINER (widget), context, x, y); - - gdk_drag_status (context, context->suggested_action, time); - - return TRUE; -} - static void drag_end_callback (GtkWidget *widget, GdkDragContext *context, @@ -903,6 +891,51 @@ drag_leave_callback (GtkWidget *widget, gnome_canvas_item_hide (dnd_info->shadow); } +/* During drag&drop keep a saved pointer to the private drag context. + * We also replace the severely broken gtk_drag_get_event_actions. + * To do this we copy a lot of code from gtkdnd.c. + * + * This is a hack-workaround to deal with the inability to override + * drag action feedback in gtk and will be removed once the appropriate + * interface gets added to gtkdnd to do this in a clean way. + * For now we need to mirror the code here + * to allow us to control the drop action based on the modifier + * key state, drop target and other drag&drop state. + * + * FIXME: + */ + +typedef struct GtkDragDestInfo GtkDragDestInfo; +typedef struct GtkDragStatus GtkDragStatus; + +typedef struct GtkDragSourceInfo +{ + GtkWidget *widget; + GtkTargetList *target_list; /* Targets for drag data */ + GdkDragAction possible_actions; /* Actions allowed by source */ + GdkDragContext *context; /* drag context */ + GtkWidget *icon_window; /* Window for drag */ + GtkWidget *ipc_widget; /* GtkInvisible for grab, message passing */ + GdkCursor *cursor; /* Cursor for drag */ + gint hot_x, hot_y; /* Hot spot for drag */ + gint button; /* mouse button starting drag */ + + gint status; /* drag status !!! GtkDragStatus in real life*/ + GdkEvent *last_event; /* motion event waiting for response */ + + gint start_x, start_y; /* Initial position */ + gint cur_x, cur_y; /* Current Position */ + + GList *selections; /* selections we've claimed */ + + GtkDragDestInfo *proxy_dest; /* Set if this is a proxy drag */ + + guint drop_timeout; /* Timeout for aborting drop */ + guint destroy_icon : 1; /* If true, destroy icon_window + */ +} GtkDragSourceInfo; +static GtkDragSourceInfo *saved_drag_source_info; + void nautilus_icon_dnd_init (NautilusIconContainer *container, GdkBitmap *stipple) @@ -945,7 +978,7 @@ nautilus_icon_dnd_init (NautilusIconContainer *container, GTK_SIGNAL_FUNC (drag_leave_callback), NULL); container->details->dnd_info = dnd_info; - container->details->dnd_info->saved_drag_source_info = NULL; + saved_drag_source_info = NULL; } @@ -972,50 +1005,6 @@ nautilus_icon_dnd_fini (NautilusIconContainer *container) } -/* During drag&drop keep a saved pointer to the private drag context. - * We also replace the severely broken gtk_drag_get_event_actions. - * To do this we copy a lot of code from gtkdnd.c. - * - * This is a hack-workaround to deal with the inability to override - * drag action feedback in gtk and will be removed once the appropriate - * interface gets added to gtkdnd to do this in a clean way. - * For now we need to mirror the code here - * to allow us to control the drop action based on the modifier - * key state, drop target and other drag&drop state. - * - * FIXME: - */ - -typedef struct GtkDragDestInfo GtkDragDestInfo; -typedef struct GtkDragStatus GtkDragStatus; - -typedef struct GtkDragSourceInfo -{ - GtkWidget *widget; - GtkTargetList *target_list; /* Targets for drag data */ - GdkDragAction possible_actions; /* Actions allowed by source */ - GdkDragContext *context; /* drag context */ - GtkWidget *icon_window; /* Window for drag */ - GtkWidget *ipc_widget; /* GtkInvisible for grab, message passing */ - GdkCursor *cursor; /* Cursor for drag */ - gint hot_x, hot_y; /* Hot spot for drag */ - gint button; /* mouse button starting drag */ - - gint status; /* drag status !!! GtkDragStatus in real life*/ - GdkEvent *last_event; /* motion event waiting for response */ - - gint start_x, start_y; /* Initial position */ - gint cur_x, cur_y; /* Current Position */ - - GList *selections; /* selections we've claimed */ - - GtkDragDestInfo *proxy_dest; /* Set if this is a proxy drag */ - - guint drop_timeout; /* Timeout for aborting drop */ - guint destroy_icon : 1; /* If true, destroy icon_window - */ -} GtkDragSourceInfo; - static GtkDragSourceInfo * nautilus_icon_dnd_get_drag_source_info (GtkWidget *widget, GdkDragContext *context) { @@ -1040,7 +1029,6 @@ nautilus_icon_dnd_begin_drag (NautilusIconContainer *container, int x_offset, y_offset; ArtDRect world_rect; ArtIRect window_rect; - GtkDragSourceInfo *info; g_return_if_fail (NAUTILUS_IS_ICON_CONTAINER (container)); g_return_if_fail (event != NULL); @@ -1064,15 +1052,13 @@ nautilus_icon_dnd_begin_drag (NautilusIconContainer *container, (GdkEvent *) event); /* set up state for overriding the broken gtk_drag_get_event_actions call */ - info = nautilus_icon_dnd_get_drag_source_info (GTK_WIDGET (container), context); - container->details->dnd_info->saved_drag_source_info = info; - - g_assert (info != NULL); - - gtk_signal_connect (GTK_OBJECT (info ? info->ipc_widget : NULL), "key_press_event", - GTK_SIGNAL_FUNC (nautilus_icon_drag_key_callback), info); - gtk_signal_connect (GTK_OBJECT (info ? info->ipc_widget : NULL), "key_release_event", - GTK_SIGNAL_FUNC (nautilus_icon_drag_key_callback), info); + saved_drag_source_info = nautilus_icon_dnd_get_drag_source_info (GTK_WIDGET (container), context); + g_assert (saved_drag_source_info != NULL); + + gtk_signal_connect (GTK_OBJECT (saved_drag_source_info ? saved_drag_source_info->ipc_widget : NULL), "key_press_event", + GTK_SIGNAL_FUNC (nautilus_icon_drag_key_callback), saved_drag_source_info); + gtk_signal_connect (GTK_OBJECT (saved_drag_source_info ? saved_drag_source_info->ipc_widget : NULL), "key_release_event", + GTK_SIGNAL_FUNC (nautilus_icon_drag_key_callback), saved_drag_source_info); container->details->dnd_info->current_drop_target_icon = NULL; @@ -1115,6 +1101,22 @@ nautilus_icon_dnd_begin_drag (NautilusIconContainer *container, } static gboolean +drag_motion_callback (GtkWidget *widget, + GdkDragContext *context, + int x, int y, + guint32 time) +{ + nautilus_icon_dnd_update_drop_action (widget); + nautilus_icon_container_ensure_drag_data (NAUTILUS_ICON_CONTAINER (widget), context, time); + nautilus_icon_container_position_shadow (NAUTILUS_ICON_CONTAINER (widget), x, y); + nautilus_icon_dnd_update_drop_target (NAUTILUS_ICON_CONTAINER (widget), context, x, y); + + gdk_drag_status (context, context->suggested_action, time); + + return TRUE; +} + +static gboolean drag_drop_callback (GtkWidget *widget, GdkDragContext *context, int x, @@ -1123,7 +1125,6 @@ drag_drop_callback (GtkWidget *widget, gpointer data) { NautilusIconDndInfo *dnd_info; - GtkDragSourceInfo *info; dnd_info = NAUTILUS_ICON_CONTAINER (widget)->details->dnd_info; @@ -1149,16 +1150,13 @@ drag_drop_callback (GtkWidget *widget, nautilus_icon_container_free_drag_data (NAUTILUS_ICON_CONTAINER (widget)); - info = NAUTILUS_ICON_CONTAINER (widget)->details->dnd_info->saved_drag_source_info; - g_assert (info != NULL); - - if (info != NULL) { - gtk_signal_disconnect_by_func (GTK_OBJECT (info->ipc_widget), + if (saved_drag_source_info != NULL) { + gtk_signal_disconnect_by_func (GTK_OBJECT (saved_drag_source_info->ipc_widget), GTK_SIGNAL_FUNC (nautilus_icon_drag_key_callback), - info); + saved_drag_source_info); } - NAUTILUS_ICON_CONTAINER (widget)->details->dnd_info->saved_drag_source_info = NULL; + saved_drag_source_info = NULL; NAUTILUS_ICON_CONTAINER (widget)->details->dnd_info->current_drop_target_icon = NULL; return FALSE; @@ -1202,13 +1200,10 @@ nautilus_icon_dnd_modifier_based_action () void nautilus_icon_dnd_update_drop_action (GtkWidget *widget) { - GtkDragSourceInfo *info; - - info = NAUTILUS_ICON_CONTAINER (widget)->details->dnd_info->saved_drag_source_info; - if (info == NULL) + if (saved_drag_source_info == NULL) return; - info->possible_actions = nautilus_icon_dnd_modifier_based_action (); + saved_drag_source_info->possible_actions = nautilus_icon_dnd_modifier_based_action (); } /* Replacement for broken gtk_drag_get_event_actions */ diff --git a/libnautilus-private/nautilus-icon-dnd.h b/libnautilus-private/nautilus-icon-dnd.h index 821dd3d9b..ec7069630 100644 --- a/libnautilus-private/nautilus-icon-dnd.h +++ b/libnautilus-private/nautilus-icon-dnd.h @@ -72,14 +72,6 @@ struct NautilusIconDndInfo { /* Shadow for the icons being dragged. */ GnomeCanvasItem *shadow; - - /* During drag&drop keep a saved pointer to the private drag context. - * This is a hack-workaround to deal with the inability to override - * drag action feedback in gtk and will be removed once the appropriate - * interface gets added to gtkdnd to do this in a clean way - */ - gpointer saved_drag_source_info; - /* last highlighted drop target*/ gpointer current_drop_target_icon; }; diff --git a/libnautilus/nautilus-icon-dnd.c b/libnautilus/nautilus-icon-dnd.c index f3cd41f97..81dabe433 100644 --- a/libnautilus/nautilus-icon-dnd.c +++ b/libnautilus/nautilus-icon-dnd.c @@ -54,6 +54,10 @@ static gboolean drag_drop_callback (GtkWidget *widget, static void nautilus_icon_dnd_update_drop_target (NautilusIconContainer *container, GdkDragContext *context, int x, int y); +static gboolean drag_motion_callback (GtkWidget *widget, + GdkDragContext *context, + int x, int y, + guint32 time); typedef struct { @@ -509,22 +513,6 @@ nautilus_icon_container_ensure_drag_data (NautilusIconContainer *container, } } -static gboolean -drag_motion_callback (GtkWidget *widget, - GdkDragContext *context, - int x, int y, - guint32 time) -{ - nautilus_icon_dnd_update_drop_action (widget); - nautilus_icon_container_ensure_drag_data (NAUTILUS_ICON_CONTAINER (widget), context, time); - nautilus_icon_container_position_shadow (NAUTILUS_ICON_CONTAINER (widget), x, y); - nautilus_icon_dnd_update_drop_target (NAUTILUS_ICON_CONTAINER (widget), context, x, y); - - gdk_drag_status (context, context->suggested_action, time); - - return TRUE; -} - static void drag_end_callback (GtkWidget *widget, GdkDragContext *context, @@ -903,6 +891,51 @@ drag_leave_callback (GtkWidget *widget, gnome_canvas_item_hide (dnd_info->shadow); } +/* During drag&drop keep a saved pointer to the private drag context. + * We also replace the severely broken gtk_drag_get_event_actions. + * To do this we copy a lot of code from gtkdnd.c. + * + * This is a hack-workaround to deal with the inability to override + * drag action feedback in gtk and will be removed once the appropriate + * interface gets added to gtkdnd to do this in a clean way. + * For now we need to mirror the code here + * to allow us to control the drop action based on the modifier + * key state, drop target and other drag&drop state. + * + * FIXME: + */ + +typedef struct GtkDragDestInfo GtkDragDestInfo; +typedef struct GtkDragStatus GtkDragStatus; + +typedef struct GtkDragSourceInfo +{ + GtkWidget *widget; + GtkTargetList *target_list; /* Targets for drag data */ + GdkDragAction possible_actions; /* Actions allowed by source */ + GdkDragContext *context; /* drag context */ + GtkWidget *icon_window; /* Window for drag */ + GtkWidget *ipc_widget; /* GtkInvisible for grab, message passing */ + GdkCursor *cursor; /* Cursor for drag */ + gint hot_x, hot_y; /* Hot spot for drag */ + gint button; /* mouse button starting drag */ + + gint status; /* drag status !!! GtkDragStatus in real life*/ + GdkEvent *last_event; /* motion event waiting for response */ + + gint start_x, start_y; /* Initial position */ + gint cur_x, cur_y; /* Current Position */ + + GList *selections; /* selections we've claimed */ + + GtkDragDestInfo *proxy_dest; /* Set if this is a proxy drag */ + + guint drop_timeout; /* Timeout for aborting drop */ + guint destroy_icon : 1; /* If true, destroy icon_window + */ +} GtkDragSourceInfo; +static GtkDragSourceInfo *saved_drag_source_info; + void nautilus_icon_dnd_init (NautilusIconContainer *container, GdkBitmap *stipple) @@ -945,7 +978,7 @@ nautilus_icon_dnd_init (NautilusIconContainer *container, GTK_SIGNAL_FUNC (drag_leave_callback), NULL); container->details->dnd_info = dnd_info; - container->details->dnd_info->saved_drag_source_info = NULL; + saved_drag_source_info = NULL; } @@ -972,50 +1005,6 @@ nautilus_icon_dnd_fini (NautilusIconContainer *container) } -/* During drag&drop keep a saved pointer to the private drag context. - * We also replace the severely broken gtk_drag_get_event_actions. - * To do this we copy a lot of code from gtkdnd.c. - * - * This is a hack-workaround to deal with the inability to override - * drag action feedback in gtk and will be removed once the appropriate - * interface gets added to gtkdnd to do this in a clean way. - * For now we need to mirror the code here - * to allow us to control the drop action based on the modifier - * key state, drop target and other drag&drop state. - * - * FIXME: - */ - -typedef struct GtkDragDestInfo GtkDragDestInfo; -typedef struct GtkDragStatus GtkDragStatus; - -typedef struct GtkDragSourceInfo -{ - GtkWidget *widget; - GtkTargetList *target_list; /* Targets for drag data */ - GdkDragAction possible_actions; /* Actions allowed by source */ - GdkDragContext *context; /* drag context */ - GtkWidget *icon_window; /* Window for drag */ - GtkWidget *ipc_widget; /* GtkInvisible for grab, message passing */ - GdkCursor *cursor; /* Cursor for drag */ - gint hot_x, hot_y; /* Hot spot for drag */ - gint button; /* mouse button starting drag */ - - gint status; /* drag status !!! GtkDragStatus in real life*/ - GdkEvent *last_event; /* motion event waiting for response */ - - gint start_x, start_y; /* Initial position */ - gint cur_x, cur_y; /* Current Position */ - - GList *selections; /* selections we've claimed */ - - GtkDragDestInfo *proxy_dest; /* Set if this is a proxy drag */ - - guint drop_timeout; /* Timeout for aborting drop */ - guint destroy_icon : 1; /* If true, destroy icon_window - */ -} GtkDragSourceInfo; - static GtkDragSourceInfo * nautilus_icon_dnd_get_drag_source_info (GtkWidget *widget, GdkDragContext *context) { @@ -1040,7 +1029,6 @@ nautilus_icon_dnd_begin_drag (NautilusIconContainer *container, int x_offset, y_offset; ArtDRect world_rect; ArtIRect window_rect; - GtkDragSourceInfo *info; g_return_if_fail (NAUTILUS_IS_ICON_CONTAINER (container)); g_return_if_fail (event != NULL); @@ -1064,15 +1052,13 @@ nautilus_icon_dnd_begin_drag (NautilusIconContainer *container, (GdkEvent *) event); /* set up state for overriding the broken gtk_drag_get_event_actions call */ - info = nautilus_icon_dnd_get_drag_source_info (GTK_WIDGET (container), context); - container->details->dnd_info->saved_drag_source_info = info; - - g_assert (info != NULL); - - gtk_signal_connect (GTK_OBJECT (info ? info->ipc_widget : NULL), "key_press_event", - GTK_SIGNAL_FUNC (nautilus_icon_drag_key_callback), info); - gtk_signal_connect (GTK_OBJECT (info ? info->ipc_widget : NULL), "key_release_event", - GTK_SIGNAL_FUNC (nautilus_icon_drag_key_callback), info); + saved_drag_source_info = nautilus_icon_dnd_get_drag_source_info (GTK_WIDGET (container), context); + g_assert (saved_drag_source_info != NULL); + + gtk_signal_connect (GTK_OBJECT (saved_drag_source_info ? saved_drag_source_info->ipc_widget : NULL), "key_press_event", + GTK_SIGNAL_FUNC (nautilus_icon_drag_key_callback), saved_drag_source_info); + gtk_signal_connect (GTK_OBJECT (saved_drag_source_info ? saved_drag_source_info->ipc_widget : NULL), "key_release_event", + GTK_SIGNAL_FUNC (nautilus_icon_drag_key_callback), saved_drag_source_info); container->details->dnd_info->current_drop_target_icon = NULL; @@ -1115,6 +1101,22 @@ nautilus_icon_dnd_begin_drag (NautilusIconContainer *container, } static gboolean +drag_motion_callback (GtkWidget *widget, + GdkDragContext *context, + int x, int y, + guint32 time) +{ + nautilus_icon_dnd_update_drop_action (widget); + nautilus_icon_container_ensure_drag_data (NAUTILUS_ICON_CONTAINER (widget), context, time); + nautilus_icon_container_position_shadow (NAUTILUS_ICON_CONTAINER (widget), x, y); + nautilus_icon_dnd_update_drop_target (NAUTILUS_ICON_CONTAINER (widget), context, x, y); + + gdk_drag_status (context, context->suggested_action, time); + + return TRUE; +} + +static gboolean drag_drop_callback (GtkWidget *widget, GdkDragContext *context, int x, @@ -1123,7 +1125,6 @@ drag_drop_callback (GtkWidget *widget, gpointer data) { NautilusIconDndInfo *dnd_info; - GtkDragSourceInfo *info; dnd_info = NAUTILUS_ICON_CONTAINER (widget)->details->dnd_info; @@ -1149,16 +1150,13 @@ drag_drop_callback (GtkWidget *widget, nautilus_icon_container_free_drag_data (NAUTILUS_ICON_CONTAINER (widget)); - info = NAUTILUS_ICON_CONTAINER (widget)->details->dnd_info->saved_drag_source_info; - g_assert (info != NULL); - - if (info != NULL) { - gtk_signal_disconnect_by_func (GTK_OBJECT (info->ipc_widget), + if (saved_drag_source_info != NULL) { + gtk_signal_disconnect_by_func (GTK_OBJECT (saved_drag_source_info->ipc_widget), GTK_SIGNAL_FUNC (nautilus_icon_drag_key_callback), - info); + saved_drag_source_info); } - NAUTILUS_ICON_CONTAINER (widget)->details->dnd_info->saved_drag_source_info = NULL; + saved_drag_source_info = NULL; NAUTILUS_ICON_CONTAINER (widget)->details->dnd_info->current_drop_target_icon = NULL; return FALSE; @@ -1202,13 +1200,10 @@ nautilus_icon_dnd_modifier_based_action () void nautilus_icon_dnd_update_drop_action (GtkWidget *widget) { - GtkDragSourceInfo *info; - - info = NAUTILUS_ICON_CONTAINER (widget)->details->dnd_info->saved_drag_source_info; - if (info == NULL) + if (saved_drag_source_info == NULL) return; - info->possible_actions = nautilus_icon_dnd_modifier_based_action (); + saved_drag_source_info->possible_actions = nautilus_icon_dnd_modifier_based_action (); } /* Replacement for broken gtk_drag_get_event_actions */ diff --git a/libnautilus/nautilus-icon-dnd.h b/libnautilus/nautilus-icon-dnd.h index 821dd3d9b..ec7069630 100644 --- a/libnautilus/nautilus-icon-dnd.h +++ b/libnautilus/nautilus-icon-dnd.h @@ -72,14 +72,6 @@ struct NautilusIconDndInfo { /* Shadow for the icons being dragged. */ GnomeCanvasItem *shadow; - - /* During drag&drop keep a saved pointer to the private drag context. - * This is a hack-workaround to deal with the inability to override - * drag action feedback in gtk and will be removed once the appropriate - * interface gets added to gtkdnd to do this in a clean way - */ - gpointer saved_drag_source_info; - /* last highlighted drop target*/ gpointer current_drop_target_icon; }; |