Commit 8ecf5b48 authored by Pavel Cisler's avatar Pavel Cisler Committed by Pavel Cisler

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.
parent d140e4fc
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:
......
......@@ -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;
......@@ -1114,6 +1100,22 @@ nautilus_icon_dnd_begin_drag (NautilusIconContainer *container,
x_offset, y_offset);
}
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,
......@@ -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 */
......
......@@ -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;
};
......
......@@ -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;
......@@ -1114,6 +1100,22 @@ nautilus_icon_dnd_begin_drag (NautilusIconContainer *container,
x_offset, y_offset);
}
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,
......@@ -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 */
......
......@@ -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;
};
......
......@@ -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;
......@@ -1114,6 +1100,22 @@ nautilus_icon_dnd_begin_drag (NautilusIconContainer *container,
x_offset, y_offset);
}
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,
......@@ -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,