RFC: api change for insert-text (Re: Bug report for signal "insert-text")



i have it fixed, but i would like everyone's comments on the fix before
i commit it.  don't let the talk of marshalling and C data types scare
you, the real thing i need comments on is the fact that i want to watch
for changes in argument values for this signal and change the its call
signature (removing a parameter).

On Tue, 2003-11-04 at 05:13, Thomas Bayen wrote:

As I read the doc, the fourth parameter to the callback function should
be the insert position inside the text. But instead it is a very high 
number. I believe it is a pointer to the real value. I used 
$wid->get_position instead as a work-around. But worse: In 
http://developer.gnome.org/doc/API/2.0/gtk/GtkEditable.html#GtkEditable-insert-text

I read that this is an in-out-parameter. So it is not possible to change 
this value (to modify the text in an own callback) because of this bug.

------------------------------------------------------------------------
    $self->{entry}->signal_connect('insert-text'=>sub{
      my($entry,$new,$len,$pos)= _;
      my $text=$entry->get_text;
      substr($text,$entry->get_position,0)=$new;
      if($text !~ /^-?(\d)*$/){
        $entry->signal_stop_emission_by_name('insert-text');
        Gtk2::Gdk::beep($entry);
      }
    });


i've solved this with a custom marshaller for the insert-text signal,
but this solution raises more questions.  (isn't that wonderful?)


the attached patch against cvs HEAD[1] adds a custom marshaller for
insert-text in Gtk2/xs/GtkEditable.xs.  for this to be used properly,
the patch also fixes Glib to consider dashes and underscores equivalent
when hashing the signal names, by introducing and using two new public
xs functions, gperl_str_eq() and gperl_str_hash() (gperl_str_eq() used
to be streq_enums() in GType.xs).


the extra questions arise in figuring out how to handle the marshalling
of this rather non-standard signal: you are (apparently) allowed to edit
the text in the string passed to insert-text, and you are supposed to
write through the position pointer.  what's a proper way to handle this
in perl?

in perl subroutines, @_ is passed by reference, and modifying a value in
@_ modifies the caller's version of it.  the idiom my (@params) = @_; is
a way to emulate pass-by-value.

in light of this, my custom marshaller gives you the values passed in,
and the retrieves the values again after calling the subroutine, and
puts those back in the marshalled values.  since the marshaller gets a
GValue containing the string instead of just a pointer, this means we
can actually alter the length of the string, as well.

also, string lengths are useless in perl, so the third argument to the
handler is pointless.  thus, my marshaller *changes* *the* *call*
*signature* of the signal to remove that unused parameter.


an example of using this is also attached.


[1] it's a unified diff with context, so you should be able to apply it
by hand to the 1.00 sources if HEAD is out of the question.

-- 
muppet <scott at asofyet dot org>

Attachment: insert-text.patch
Description: Text document

Attachment: insert-text-test.pl
Description: Text Data



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]