bizarre DnD behavior



I'm trying my hand at debugging a gtk+ app called file-roller. When it
works properly, it is a graphical interface to archives (zip, tarball,
etc...) for the gnome desktop. Disclaimer: I am a GTK+ beginner.

I'm attempting to understand some odd behavior when I drag some files
out of the graphical representation of the archive contents and onto the
desktop. From a very high level, dragging and dropping in file-roller
works like this:

The drag_begin signal is connected to a handler that checks which files
are being dragged out of the archive and spawns off a thread to begin
decompressing them to a temporary directory.

The drag_end signal is connected to a handler that checks if the
aforementioned extraction process is still going and, if that is the
case, sets a flag indicating that the extraction process should be
interrupted and the entire drag operation broken off.

The drag_data_get signal is connected to a handler that has two steps:
1. It waits for the thread spawned off in drag_begin to finish or for
the interruption flag to be set.
2. When either of the above conditions is met, it either stops the
extraction process (if the flag is set) or passes the url list of
extracted files to the drop target (if the extract operation completed
in time).

Here is the odd behavior:

When I drag a bunch of files out of the window and onto the desktop,
everything works properly. The drag_begin handler is called properly,
and when I let go of the mouse button the drag_data_get handler is
called. Steps 1 and 2 complete successfully.

However, if I drag a bunch of files out of the file-roller window,
across the desktop, across another window (e.g. Firefox, file-roller
itself, a GNOME Terminal, etc...), and back onto the desktop,
file-roller goes nuts. It reports that the drag_begin signal handler
completes successfully, but for every movement of the mouse after the
cursor reaches the desktop for a second time, file-roller shows that the
drag_data_get handler is called and then stops in the middle of step 1.
Here is the relevant code for step 1:

        while (window->extracting_dragged_files
               && ! window->extracting_dragged_files_interrupted)
                while (window->extracting_dragged_files
                       && ! window->extracting_dragged_files_interrupted
                       && gtk_events_pending ())
                        gtk_main_iteration ();

Once I let go of the mouse button, the drag_end handler kicks in and all
of the instances of the drag_data_get handler terminate.

So what is going on here? Why is drag_data_get being called dozens of
times before I let go of the mouse button? This contradicts what I know
about DnD. Also, I was under the impression that gtk+ is not thread
safe. Considering that multiple instances of the handler seem to be
running at once in different threads, is it safe to call
gtk_main_iteration()?


Thanks,

Eric





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]