mirror of
https://github.com/Ponce/slackbuilds
synced 2024-10-13 08:43:42 +02:00
23b8c687d9
Signed-off-by: dsomero <xgizzmo@slackbuilds.org>
139 lines
4.8 KiB
Diff
139 lines
4.8 KiB
Diff
From e098be34aa96bbcddb786a09b13da877d2d709ad Mon Sep 17 00:00:00 2001
|
|
From: Andriy Grytsenko <andrej@rep.kiev.ua>
|
|
Date: Tue, 6 Nov 2012 05:49:19 +0200
|
|
Subject: [PATCH 03/22] [#3584608]Fix for rarely broken DnD due to FmDndDest
|
|
source caching.
|
|
|
|
The previous behavior was to cache data and reset cache when drag leaves
|
|
widget. This is completely wrong - we never get informed if we refuse drop
|
|
(for example, on wrong target) therefore drag source kept the same while
|
|
it was already changed. The only valid behavior is to keep drag context
|
|
referenced and compare it with one we get in handler and if it's changed
|
|
then reset our cache. This way we don't have to requery data again when
|
|
pointer leaves widget but still inside of application window - the drag
|
|
context is still the same, i.e. we get some optimization as a side effect.
|
|
---
|
|
src/gtk/fm-dnd-dest.c | 44 ++++++++++++++------------------------------
|
|
1 file changed, 14 insertions(+), 30 deletions(-)
|
|
|
|
diff --git a/src/gtk/fm-dnd-dest.c b/src/gtk/fm-dnd-dest.c
|
|
index 37686ce..21cf2c0 100644
|
|
--- a/src/gtk/fm-dnd-dest.c
|
|
+++ b/src/gtk/fm-dnd-dest.c
|
|
@@ -108,10 +108,10 @@ struct _FmDndDest
|
|
|
|
int info_type; /* type of src_files */
|
|
FmPathList* src_files;
|
|
+ GdkDragContext* context;
|
|
guint32 src_dev; /* UNIX dev of source fs */
|
|
const char* src_fs_id; /* filesystem id of source fs */
|
|
FmFileInfo* dest_file;
|
|
- guint idle; /* idle handler */
|
|
|
|
gboolean waiting_data;
|
|
gboolean has_handlers;
|
|
@@ -211,11 +211,6 @@ static void fm_dnd_dest_dispose(GObject *object)
|
|
|
|
fm_dnd_dest_set_widget(dd, NULL);
|
|
|
|
- if(dd->idle)
|
|
- {
|
|
- g_source_remove(dd->idle);
|
|
- dd->idle = 0;
|
|
- }
|
|
clear_src_cache(dd);
|
|
|
|
G_OBJECT_CLASS(fm_dnd_dest_parent_class)->dispose(object);
|
|
@@ -388,6 +383,11 @@ static gboolean fm_dnd_dest_files_dropped(FmDndDest* dd, int x, int y,
|
|
static void clear_src_cache(FmDndDest* dd)
|
|
{
|
|
/* free cached source files */
|
|
+ if(dd->context)
|
|
+ {
|
|
+ g_object_unref(dd->context);
|
|
+ dd->context = NULL;
|
|
+ }
|
|
if(dd->src_files)
|
|
{
|
|
fm_path_list_unref(dd->src_files);
|
|
@@ -405,16 +405,6 @@ static void clear_src_cache(FmDndDest* dd)
|
|
dd->waiting_data = FALSE;
|
|
}
|
|
|
|
-static gboolean clear_src_cache_on_idle(gpointer user_data)
|
|
-{
|
|
- GDK_THREADS_ENTER();
|
|
- /* check if dd is still valid */
|
|
- if(!g_source_is_destroyed(g_main_current_source()))
|
|
- clear_src_cache((FmDndDest*)user_data);
|
|
- GDK_THREADS_LEAVE();
|
|
- return FALSE;
|
|
-}
|
|
-
|
|
#if 0
|
|
/* the returned list can be either FmPathList or FmFileInfoList */
|
|
/* check with fm_list_is_path_list() and fm_list_is_file_info_list(). */
|
|
@@ -581,6 +571,10 @@ gboolean _on_drag_data_received(FmDndDest* dd, GdkDragContext *drag_context,
|
|
dd->src_files = files;
|
|
dd->waiting_data = FALSE;
|
|
dd->info_type = info;
|
|
+ /* keep context to verify if it's changed */
|
|
+ if(G_UNLIKELY(dd->context))
|
|
+ g_object_unref(dd->context);
|
|
+ dd->context = g_object_ref(drag_context);
|
|
return (files != NULL);
|
|
}
|
|
|
|
@@ -718,7 +712,7 @@ gboolean _on_drag_drop(FmDndDest* dd, GdkDragContext *drag_context,
|
|
}
|
|
|
|
/* see if the dragged files are cached by "drag-motion" handler */
|
|
- if(dd->src_files)
|
|
+ if(dd->src_files && drag_context == dd->context)
|
|
{
|
|
GdkDragAction action = gdk_drag_context_get_selected_action(drag_context);
|
|
/* emit files-dropped signal */
|
|
@@ -777,14 +771,6 @@ GdkDragAction fm_dnd_dest_get_default_action(FmDndDest* dd,
|
|
/* query drag sources in any case */
|
|
goto query_sources;
|
|
|
|
- /* we may have another data already so clear the cache */
|
|
- if(dd->idle)
|
|
- {
|
|
- g_source_remove(dd->idle);
|
|
- dd->idle = 0;
|
|
- clear_src_cache(dd);
|
|
- }
|
|
-
|
|
/* special support for dropping onto desktop entry */
|
|
if(fm_file_info_is_desktop_entry(dest))
|
|
{
|
|
@@ -802,8 +788,10 @@ GdkDragAction fm_dnd_dest_get_default_action(FmDndDest* dd,
|
|
if(target == dest_target_atom[FM_DND_DEST_TARGET_XDS])
|
|
return GDK_ACTION_COPY;
|
|
|
|
- if(!dd->src_files) /* we didn't have any data, cache it */
|
|
+ /* we have no valid data, query it now */
|
|
+ if(!dd->src_files || dd->context != drag_context)
|
|
{
|
|
+ clear_src_cache(dd);
|
|
query_sources:
|
|
action = 0;
|
|
if(!dd->waiting_data) /* we're still waiting for "drag-data-received" signal */
|
|
@@ -886,13 +874,9 @@ query_sources:
|
|
*/
|
|
void fm_dnd_dest_drag_leave(FmDndDest* dd, GdkDragContext* drag_context, guint time)
|
|
{
|
|
- if(dd->idle == 0)
|
|
- dd->idle = g_idle_add_full(G_PRIORITY_LOW, clear_src_cache_on_idle, dd, NULL);
|
|
}
|
|
|
|
static void on_drag_leave(GtkWidget *widget, GdkDragContext *drag_context,
|
|
guint time, FmDndDest* dd)
|
|
{
|
|
- if(dd->idle == 0)
|
|
- dd->idle = g_idle_add_full(G_PRIORITY_LOW, clear_src_cache_on_idle, dd, NULL);
|
|
}
|
|
--
|
|
1.8.0.1
|
|
|