GNOME Bugzilla – Bug 643732
Source view is created with a GtkTextBuffer instead of GtkSourceBuffer
Last modified: 2013-09-26 17:32:58 UTC
Created attachment 182307 [details] Test program to illustrate bug When constructing a GtkSourceView with g_object_new() instead of the usual gtk_source_view_new(), it is initialized with an empty GtkTextBuffer instead of an empty GtkSourceBuffer. This is primarily a problem when building a source view with GtkBuilder. I have attached a small program that demonstrates the bug. When constructing the GtkSourceView with g_object_new(), the following warnings are given: GLib-GObject-WARNING **: invalid cast from `GtkTextBuffer' to `GtkSourceBuffer' when retrieving the buffer and casting it to a GtkSourceBuffer, and GtkSourceView-CRITICAL **: gtk_source_buffer_set_language: assertion `GTK_IS_SOURCE_BUFFER (buffer)' failed when trying a GtkSourceBuffer function on it. In addition, the text in the buffer is not highlighted. Exchanging the offending g_object_new() call with a call to gtk_source_view_new() doesn't generate the warnings, and the text in the buffer is highlighted.
Created attachment 240168 [details] [review] GtkSourceView: construct with a GtkSourceBuffer instead of a GtkTextBuffer In constructed(), gtk_text_view_get_buffer() was called. Since no buffer is created at this point, a GtkTextBuffer was created implicitly by gtk_text_view_get_buffer(). Now a GtkSourceBuffer is created explicitly in constructed(). This simplifies gtk_source_view_new() and gtk_source_view_new_with_buffer().
Review of attachment 240168 [details] [review]: ::: gtksourceview/gtksourceview.c @@ +260,3 @@ gtk_source_view_constructed (GObject *object) { + GtkSourceBuffer *buffer = gtk_source_buffer_new (NULL); It is not clear to me how this works: it is creating a new buffer and setting it unconditionally on the view, even if a buffer was specified with new_with_buffer
Yes, it is not really optimized. If new_with_buffer() is used, the buffer created in constructed is finalized and replaced by the new one. It was already the case with the TextBuffer, but it seems that, with the patch, the TextBuffer is still created and finalized (so it's worse than before, but at least we have a SourceBuffer in the end). The latter problem can maybe be solved in GtkTextView. In other words, in: + return g_object_new (GTK_SOURCE_TYPE_VIEW, + "buffer", buffer, + NULL); the buffer property is set after constructed(), since it's not a constructed property (if I understand correctly).
For the record: <swilmet> maybe a cleaner solution would be to override gtk_text_view_get_buffer() <swilmet> because if the buffer is null, get_buffer() creates it (a GtkTextBuffer) <swilmet> but the virtual pointer get_buffer doesn't exist (some tests) <swilmet> overriding get_buffer() doesn't work well, another hack is needed to avoid an infinite loop <swilmet> but having a virtual method create_buffer() that unconditionnaly creates a new buffer, that works <swilmet> but it means a new function in the API <swilmet> unless a simple pointer in the class struct is sufficient <swilmet> the infinite loop is because get_buffer() must call set_buffer(), which then call get_buffer(), etc <swilmet> the cleaner solution is to call create_buffer() in get_buffer() <swilmet> (if the buffer is null)
If bug #667466 is fixed, the situation would be a little better.
Re bug #667466: Actually, despite what my original bug report said, the biggest problem is not now GtkBuilder, but creating a GtkSourceView in Python or JS through GObject introspection.
*** Bug 706859 has been marked as a duplicate of this bug. ***
*** Bug 708094 has been marked as a duplicate of this bug. ***
Fixed in the master branch. This will be available for GtkSourceView 3.12.