shithub: puzzles

Download patch

ref: b54702168b5c0759604302f198d85bc28af40feb
parent: 806e4e4088be9f03da78aba8eb8cdda23d7c9cb6
author: Simon Tatham <anakin@pobox.com>
date: Tue May 25 06:21:16 EDT 2021

GTK3: fix window redraw after copying to clipboard.

I just found out, in GTK3 under X11, that if you use the 'Copy' menu
item to copy a text representation of the game to the clipboard,
afterwards the puzzle window is no longer redrawn.

That was pretty mysterious, and I still don't _fully_ understand it.
But I think the main point is that when you set the GtkDrawingArea to
be the owner of an X11 selection, that requires it to have an X11
window of its own, where previously it was managing fine as a logical
subrectangle of its containing GtkWindow. And apparently switching
strategies half way through the run is confusing to GTK, and causes
redraws to silently stop working.

The easy workaround is to make fe->window rather than fe->area the
thing that owns GTK selections and receives the followup events. That
must already have an X window, so nothing has to be changed when we
make it a selection owner half way through the run.

--- a/gtk.c
+++ b/gtk.c
@@ -2380,12 +2380,12 @@
      * COMPOUND_TEXT or UTF8_STRING.
      */
 
-    if (gtk_selection_owner_set(fe->area, selection, CurrentTime)) {
-	gtk_selection_clear_targets(fe->area, selection);
-	gtk_selection_add_target(fe->area, selection,
+    if (gtk_selection_owner_set(fe->window, selection, CurrentTime)) {
+	gtk_selection_clear_targets(fe->window, selection);
+	gtk_selection_add_target(fe->window, selection,
 				 GDK_SELECTION_TYPE_STRING, 1);
-	gtk_selection_add_target(fe->area, selection, compound_text_atom, 1);
-	gtk_selection_add_target(fe->area, selection, utf8_string_atom, 1);
+	gtk_selection_add_target(fe->window, selection, compound_text_atom, 1);
+	gtk_selection_add_target(fe->window, selection, utf8_string_atom, 1);
     }
 }
 
@@ -3503,9 +3503,9 @@
                      G_CALLBACK(button_event), fe);
     g_signal_connect(G_OBJECT(fe->area), "motion_notify_event",
                      G_CALLBACK(motion_event), fe);
-    g_signal_connect(G_OBJECT(fe->area), "selection_get",
+    g_signal_connect(G_OBJECT(fe->window), "selection_get",
                      G_CALLBACK(selection_get), fe);
-    g_signal_connect(G_OBJECT(fe->area), "selection_clear_event",
+    g_signal_connect(G_OBJECT(fe->window), "selection_clear_event",
                      G_CALLBACK(selection_clear), fe);
 #if GTK_CHECK_VERSION(3,0,0)
     g_signal_connect(G_OBJECT(fe->area), "draw",