After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 66636 - GtkEntry and GtkText buggy if unparented with active selection
GtkEntry and GtkText buggy if unparented with active selection
Status: RESOLVED WONTFIX
Product: gtk+
Classification: Platform
Component: Widget: Other
1.2.x
Other All
: Normal major
: ---
Assigned To: gtk-bugs
gtk-bugs
: 51800 60887 94746 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2001-12-10 16:55 UTC by Sergey Vlasov
Modified: 2011-02-04 16:09 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
test program to demonstrate the bug (4.43 KB, text/plain)
2001-12-10 16:56 UTC, Sergey Vlasov
  Details
proposed patch to fix selection handling (718 bytes, patch)
2001-12-10 16:56 UTC, Sergey Vlasov
none Details | Review
Patch applied to HEAD fixing warning/crash (2.59 KB, patch)
2002-01-17 22:22 UTC, Owen Taylor
none Details | Review

Description Sergey Vlasov 2001-12-10 16:55:02 UTC
I have noticed a buggy behavior of GtkEntry and GtkText widgets
in GTK+ 1.2.10, in case they are unrealized when they own the
selection.  The problem was initially noticed in the Sylpheed
mail client (http://sylpheed.good-day.net); I have written a
small test program which exercises the bug.

The test program (test-selection.c) creates a window with
several buttons and a GtkFrame, and two GtkVBox'es, each
containing a GtkEntry and a GtkText.  The button labeled "Show
text 1" puts the first VBox into the GtkFrame.  The button
labeled "Show text 2" puts the second VBox into the GtkFrame.
The button labeled "Hide all" removes any of the VBox'es from
the GtkFrame.

Compilation command:

gcc -o test-selection -g -O2 -Wall `gtk-config --cflags` \
	test-selection.c `gtk-config --libs`

Buggy behavior observed:

1. Select some text in the first GtkEntry and check that it can
be pasted into another application.  Then click "Hide all" or
"Show text 2", and then click "Show text 1" to restore the first
GtkEntry.  At this step the text appears selected, but cannot be
pasted to another application.  Moreover, making another
selection in this GtkEntry does not work -- again, the text
appears selected but cannot be pasted to another application.

2. Restart the test program and do the same thing as in step 1,
but with GtkText instead of the GtkEntry.  It fails in the same
way: after unparenting the widget which owns the selection,
copying selection from the widget stops working.

3. Finally, restart the test program again and select some text
in the first GtkText.  Then click "Show text 2" and select some
text in either the GtkText or GtkEntry.  At this point a warning
appears, and sometimes SIGSEGV occurs:

Gdk-CRITICAL **: file gdkwindow.c: line 1390 (gdk_window_get_size):
assertion `window != NULL' failed.

Program received signal SIGSEGV, Segmentation fault.
0x400fbdf6 in gtk_text_update_text (editable=0x8087c90, start_pos=0, 
    end_pos=14) at gtktext.c:5401
5401          if (CACHE_DATA(cache).start.index < end_pos)
(gdb) where
  • #0 gtk_text_update_text
    at gtktext.c line 5401
  • #1 gtk_editable_update_text
    at gtkeditable.c line 478
  • #2 gtk_editable_selection_clear
    at gtkeditable.c line 585
  • #3 gtk_marshal_BOOL__POINTER
    at gtkmarshal.c line 28
  • #4 gtk_signal_real_emit
    at gtksignal.c line 1492
  • #5 gtk_signal_emit
    at gtksignal.c line 552
  • #6 gtk_widget_event
    at gtkwidget.c line 2864
  • #7 gtk_selection_owner_set
    at gtkselection.c line 386
  • #8 gtk_text_button_release
    at gtktext.c line 1880
  • #9 gtk_marshal_BOOL__POINTER
    at gtkmarshal.c line 28
  • #10 gtk_signal_real_emit
    at gtksignal.c line 1492
  • #11 gtk_signal_emit
    at gtksignal.c line 552
  • #12 gtk_widget_event
    at gtkwidget.c line 2864
  • #13 gtk_propagate_event
    at gtkmain.c line 1378
  • #14 gtk_main_do_event
    at gtkmain.c line 818
  • #15 gdk_event_dispatch
    at gdkevents.c line 2139
  • #16 g_get_current_time
    at eval.c line 88
  • #17 g_get_current_time
    at eval.c line 88
  • #18 g_main_run
    at eval.c line 88
  • #19 gtk_main
    at gtkmain.c line 524
  • #20 main
    at test-selection.c line 157
  • #21 __libc_start_main
    at ../sysdeps/generic/libc-start.c line 129

I have tried to investigate the source of this problem and found
that neither GtkText nor GtkEntry drop the selection ownership
when the widget is unrealized.  Because of this, the structures
in gtkselection.c (namely, the current_selections list) continue
to hold a pointer to the widget even after it is unrealized.
Later, when the widget is realized again,
gtk_selection_owner_set() finds that the widget is already
registered in current_selections and does nothing to reestablish
the selection.  Also, because gtk_text_unrealize() destroys some
internal structures, when gtk_selection_owner_set() for another
widget sends GDK_SELECTION_CLEAR to unrealized GtkText, the
program crashes.

A simple way to fix this is to add the following call to
gtk_text_unrealize() and gtk_entry_unrealize():

  gtk_editable_claim_selection (GTK_EDITABLE (widget), FALSE,                  
                                GDK_CURRENT_TIME);                        
     

The attached patch does exactly this, and after doing this
change none of the problems described above occur.

Note that gtk_text_realize() and gtk_entry_realize() call
gtk_editable_claim_selection() conditionally -- only when the
selection is not empty.  When unrealizing, though, this does not
work, because in some cases GtkText or GtkEntry can own the
selection even when it is empty.  One way to get such situation
is to delete all selected text by gtk_text_forward_delete() or
something like this -- it updates the selection boundaries but
does not drop the selection ownership when the selection ends up
empty.  So dropping the selection ownership in unrealize handler
must be done in any case, even if the selection appears empty.
Comment 1 Sergey Vlasov 2001-12-10 16:56:00 UTC
Created attachment 6199 [details]
test program to demonstrate the bug
Comment 2 Sergey Vlasov 2001-12-10 16:56:48 UTC
Created attachment 6200 [details] [review]
proposed patch to fix selection handling
Comment 3 Owen Taylor 2002-01-17 22:22:51 UTC
Created attachment 6428 [details] [review]
Patch applied to HEAD fixing warning/crash
Comment 4 Owen Taylor 2002-01-17 22:28:12 UTC
The patch applied to HEAD fixes the warning crash. Putting the
bug on 1.2.11 for backporting. The misbehavior is no
longer relevant for GTK+-1.3/2.0 because GtkTextView/GtkEntry/
GtkLabel use GtkClipboard so can handle selection when not
realized, and GtkText is only provided for temporary porting
purposes ... you need to define G_ENABLE_BROKEN to get it.

Thu Jan 17 17:02:38 2002  Owen Taylor  <otaylor@redhat.com>

	* gtk/gtkwidget.c (gtk_widget_real_unrealize): Call
	gtk_selection_remove_all() here, not in destroy/
	finalize.  (#66636, Sergey Vlasov)

	* gtk/gtkselection.c (gtk_selection_request): Fix
	reentrancy problem with multiple conversions.

	* gtk/gtkselection.c (gtk_selection_remove_all): 
	Don't remove incrs, we don't need the widget for
	maintain the incr.

	* gtk/gtkselection.c (struct _GtkIncrInfo): Remove
	the widget field from here, we don't need it.
Comment 5 Owen Taylor 2002-01-18 00:22:34 UTC
Wasn't meant to be resolved, just moved to 1.2.11 milestone.
Comment 6 Luis Villa 2002-01-29 17:52:49 UTC
*** Bug 51800 has been marked as a duplicate of this bug. ***
Comment 7 Luis Villa 2002-01-29 17:53:04 UTC
*** Bug 60887 has been marked as a duplicate of this bug. ***
Comment 8 John Fleck 2002-10-03 12:45:24 UTC
*** Bug 94746 has been marked as a duplicate of this bug. ***
Comment 9 Owen Taylor 2004-02-24 00:53:14 UTC
No 1.2.11 is planned, so closing all 1.2.11 specific bugs.
Comment 10 Owen Taylor 2004-02-24 14:08:44 UTC
*Really* close all 1.2.11 bugs, instead of just adding a comment...