GNOME Bugzilla – Bug 702951
aisleriot card movement broken
Last modified: 2016-05-11 15:51:19 UTC
Steps to repro: 0) start aisleriot 1) make sure "Click to move" is disabled in Control menu 2) move mouse over a card, click and hold left mouse button, move mouse Actual results: Card disappears. Expected results: Card moves with mouse. The moving card is a child gdkwindow with a background pattern and a shape, which I guess the new drawing code in gtk+ has broken.
*** Bug 710162 has been marked as a duplicate of this bug. ***
Running the same aisleriot binary against gtk+ 3.8 (from F19) and gtk+ master shows that 3.8 works, master/3.10 is broken, so it's definitely a gtk+ change that broke this.
Work-arounded in aisleriot (commit 559f64c6aefb47c4435217f15c2da0a83dcdd5fb) by making the moving cards window native. Leaving open in the hope of a real fix in gtk+, since this is likely to have broken other programmes too.
Created attachment 291298 [details] Card details lost when encountering edge of window It's a webm vid of Klondike in action. Ubuntu 14.04.01, fresh install, Nouveau driver, Nvidia GX 460 video card. Gigabyte board with AMD FX-8150 cpu. This is the only app that manifests this old school defect. I think this has been going on for years. If you try to do a screenshot.. the redraw is done correctly and the card appears correctly in the screenshot and in the game.
Bug 744679 reports that """ I added gdk_window_set_debug_updates(1) on drag_begin() - and to my horror, GDK clearly showed that the cards window is actually NEVER painted. The current code appears to work (somewhat) simply because the update of the card stack to remove the dragged cards is done AFTER a non-transparent child window (the 'moving_cards_window') is plopped on top of it (all of the exercise done drag_begin() to get the card images and carefully draw them on a Cairo surface that becomes the windows background has only one effect - to mark the exact area where the cards are as being non-transparent - the generated background pattern is never actually used :P ). Not being a great expert at GDK, I used the first solution that I could find: call begin_paint and immediately end_paint, which did exactly what was wanted - to draw the Cairo background associated with the window. """
Created attachment 297090 [details] [review] Add redraw for the moving cards window This is the patch that I posted originally on the gnome-games mailing list.
So using gdk_window_set_invalidate_handler shows that the window is getting invalidated (although the coordinates in the region seem very odd sometimes), but the window's background pattern isn't being drawn...
To keep the current native subwindow approach working, this invalidate handler is probably the best you can do. Since this commit: commit 2c1633699fe5ede37ac40d1b1e1bb572a267f0af Author: Benjamin Otte <otte@redhat.com> Date: Sun Aug 15 13:49:30 2010 +0200 gdk: Rewrite background handling Now the window background is a cairo_pattern_t. The backends will try to set this as good as they can on the windowing system, but no guarantees are made on wether the windowing system supports the pattern. Also gets rid of GDK_NO_BG as undefined behavior is not a good idea to support, and GDK_NO_BG effectively made the window's contents undefined. It wasn't effectively used in GTK anyway. window backgrounds are more or less best-effort, even on X. To get this working under wayland, it probably has to be rewritten to be more along the lines drawing works in GTK+ now: - add GDK_EXPOSURE_MASK to the window - call gtk_widget_register_window - use gtk_cairo_should_draw_window in your draw function - and draw the moving card stack there.
I've reworked aisleriot not to use the child window at all.
Created attachment 297576 [details] [review] a variant of the patch, with direct cairo operations In case the aisleriot team decides to stick with the gdk window (and not use a gtk+ widget as suggested above): attached a possible variant of the invalidate handler, without the double-buffering of begin_paint/end_paint - but also without the region optimization. It draws the entire backgroud ignoring the region passed to the handler (I didn't find the proper way to apply the region yet). BTW, the gtk comment (#8 above) is in agreement with what I figured out, as well - it should not really paint the background unconditionally, because gdk cannot know what else the window owner might want to paint on it.
I missed Christian's earlier comment - ignore the patch I sent, drawing the cards directly as he did makes perfect sense and works nicely.
Nice, Thanks, Christian!
I think I'll wontfix this,then
*** Bug 766217 has been marked as a duplicate of this bug. ***