GNOME Bugzilla – Bug 307559
drag and drop files move freezes on slow X terminals
Last modified: 2018-02-13 13:25:37 UTC
Version details: Gnome nautilus 2.10.1 Distribution/Version: Gentoo Linux unstable 1. have a slow X-terminal 2. Open two directories in two windows in icon mode. Have some images in one of them. 3. Use rectangular selection for selecting many images. 4. Try to drop images to second window. Actual result: While mouse pointer dragging icons crosses window boundary, nautilus freezes (it means - mouse pointer is moving, but flying preview and frames for other images in selection stops moving). If you will drop images now, copy of images in source directory is created instead. If you return to original window (without releasing the mouse button), icon again start moving. Trying to moving across windows boundary more times, say 6-8 times, you finally see, that it works - icons continue in moving and destination file view gets framed.
It seems, that freee occurs not exactly on window boundary but in following situation: - Machine is slow enough, that new mouse motion event happens before redrawing of flying icons and black frame around destination file view is complete. It seems, that is a dead lock between redrawing of flying icons and redrawing of drop frame around file view in original window (destination window is black framed and when you are still in original window, it is framed as destination). If you move mouse fast enough, that next redraw has no collision between destination frame around file view and flyng icon.
Do you still have this slow machine and could give a recent version of nautilus a try?
It is easily reproducible even with a fast machine and trickle utility. You just need port 6000 open on your X server (/etc/gdm/gdm.schemas security/DisallowTCP or sysconfig in openSUSE). DISPLAY={my machine name}:0 trickle -s -l 100 -d 500 -u 500 nautilus Wait for launch, open two windows and slowly drag any icon without dropping. Most parts of this bug remain unfixed in nautilus 2.30.1: - Drag icon up. If the icon view has a scroll bar and icon reaches the icon view border, then the icon is catched and released when scroll bar reaches one of ends. - Drag the icon to another window and slowly return to your home window. Icon is again catched and cannot pass the frame. You have to go few pixels back and then try to pass border a bit faster. The bug seems to be a race condition dead loc of frame (un)emphasizing and the icon animation. I guess that icon animation keeps grab and the icon view frame emphasizing (just a thin frame) rendering needs grab to be released.
Thanks for the follow up.
Another way to reproduce: Launch gdb and use these commands: set pagination off attach {nautilus pid} break gdk_draw_rectangle commands continue end continue Now take any nautilus window in icon mode and try to move any icon slowly outside to another window. The icon cannot pass the boundary. If the window has a scroll bar, it scrolls to the end first and then the icon is released.
Created attachment 165976 [details] [review] patch to reproduce and debug the problem usleep() in attached patch exhibits the problem on all systems and allows to debug it. Here is the log if things run well: drag_motion_callback() x=337, y=226 drag_motion_callback() going to nautilus_icon_container_ensure_drag_data() drag_motion_callback() going to nautilus_icon_container_position_shadow() drag_motion_callback() going to nautilus_icon_dnd_update_drop_target() drag_motion_callback() going to set_up_auto_scroll_if_needed() drag_motion_callback() going to nautilus_icon_container_get_drop_action() drag_motion_callback() going to start_dnd_highlight() drag_motion_callback() going to gdk_drag_status() drag_motion_callback() going to return drag_highlight_expose() entered drag_highlight_expose() goes to draw rectangle x=0, y=6017, w=482, h=253 drag_highlight_expose() done And here when things are broken: auto_scroll_timeout_callback() is going to dnd_highlight_queue_redraw() 1 dnd_highlight_queue_redraw() drag_highlight_expose() entered drag_highlight_expose() goes to draw rectangle x=0, y=6017, w=482, h=253 drag_highlight_expose() done As you can see, drag_motion_callback() is never called for some reason.
I just debugged half of the problem: When you reach the autoscroll boundary limit near the file view frame, autoscroll is activated. The callback is called 100ms after the last motion. The callback calls dnd_highlight_queue_redraw(). This command redraws the view and generates expose event. Processing of expose event takes precedence over motion callback. If processing of expose event takes more than 100ms, new autoscroll timeout happens before the motion callback can be processed and the system is overflooded by autoscroll timeout callbacks. Motion callback is never called and autoscroll is never stopped. Dead lock happens. A work-around that prevents freeze when no autoscroll happens: Comment out the first dnd_highlight_queue_redraw() inside auto_scroll_timeout_callback(). This is not yet a real solution: It creates an artifact in the first scrolling step (rectangle created in drag_highlight_expose() is visibly scrolled up), and it does not prevent freeze when autoscroll is needed.
My guess is that we do sync I/O in a DnD callback, which may dead lock things as reported. We indeed seem to do so in selection_is_image_file() (from nautilus-icon-dnd.c).
Comment on attachment 165976 [details] [review] patch to reproduce and debug the problem Not really a patch, rejecting so it goes out of the review queue.
Trying a modified version of comment 5 reproducer (use cairo_rectangle) and gtk-dilatory (ftp://ftp.suse.com/pub/people/sbrabec/gtk-dilatory/index.html), it seems, that this bug is fixes.