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.
This commit is contained in:
Simon Tatham
2021-05-25 10:21:16 +01:00
parent 806e4e4088
commit b54702168b

14
gtk.c
View File

@ -2380,12 +2380,12 @@ static void set_selection(frontend *fe, GdkAtom selection)
* 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 @@ static frontend *new_window(
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",