Selection in GtkTextBuffer

I've recently played around with GtkTextBuffer. It's a rather nice text editing widget (or rather widget part). Unfortunately it misses one functionality, which is also missing from GtkEditable derived widgets: A signal for selection changes. There are two workarounds:

  1. You can setup a notification on the has-selection property like this:

    buffer.connect("notify", on_buffer_notify)
    
    def on_buffer_notify(buffer, prop):
        if prop.name == "has-selection":
            if buffer.get_has_selection():
                ...
            else:
                ...
    

    This method only works if you are interested in whether there is a selection or not, not if you are interested in any selection changes. Also, this method works only for GtkTextBuffers, not for GtkEditables.

  2. Tomboy uses a timeout to check the selection status:

    namespace Tomboy
    {
        public class NoteWindow : ForcedPresentWindow
        {
                    ...
            public NoteWindow (Note note) :
                base (note.Title)
            {
                            ...
                // Sensitize the Link toolbar button on text selection
                mark_set_timeout = new InterruptableTimeout();
                mark_set_timeout.Timeout  = UpdateLinkButtonSensitivity;
                            ...
                    }
    
                    ...
    
            void UpdateLinkButtonSensitivity (object sender, EventArgs args)
            {
                link_button.Sensitive = (note.Buffer.Selection != null);
            }
    
                    ...
            }
    }
    

This method works, but seems a bit complicated, when a simple signal should do the trick.

Filed as bug #448261.


by Miroslav Rajcic
Thursday, 19 July 2007 08:55

Just stumbled on your blog and seen your problem.

Signal notification of selection change works fine for me with following code:

//track movement of "insert" and "selection_bound" marks,

g_signal_connect (buffer, "mark-set", G_CALLBACK(textview_selection_changed), NULL);

....

void textview_selection_changed(GtkTextBuffer *textbuffer, GtkTextIter *arg1, GtkTextMark *arg2, gpointer user_data);