Re: Autoupdating EntryCompletion (was Selectively trapping keypresses)
- From: muppet <scott asofyet org>
- To: Jeffrey Ratcliffe <jeffrey ratcliffe gmail com>
- Cc: gtk-perl-list gnome org
- Subject: Re: Autoupdating EntryCompletion (was Selectively trapping keypresses)
- Date: Thu, 19 Apr 2007 01:01:34 -0400
On Apr 17, 2007, at 10:42 AM, Jeffrey Ratcliffe wrote:
On 17/04/07, muppet <scott asofyet org> wrote:
I couldn't reproduce that after tinkering for just a few moments,
but i think
i see it in the code...
Replace "one" with "twelve" twice, and during the second replacement,
the error comes.
Any change to a TreeModel invalidates existing TreeIters.
$cmp_model -> signal_connect('row-inserted' => sub {
my ($model, $path, $iter) = @_;
my ($val) = $cmp_model->get($iter, 0);
warn "inserted $val\n";
# Weed out duplicates
my $iter2 = $cmp_model->iter_next($iter);
while ($iter2) {
my ($val2) = $cmp_model->get($iter2, 0);
warn "list $val2\n";
if ($val eq $val2) {
warn "removing $val2\n";
$cmp_model->remove ($iter2);
warn "removed $val2\n";
I can add a return statement here, as there will only ever one
duplicate, and then there are no problems with iters. But the error
still comes.
I spent a few minutes running this code under gdb with the --g-fatal-
warnings option...
The EntryCompletion uses a TreeModelFilter to narrow down the
contents of the completion model to match what you've already typed.
By the time we're doing that, the completion model is in a rather
hosed state, and we get warnings about iters not being valid.
Specifically, the iter's stamp does not match the model, which means
that something Very Bad has happened.
The basic situation in which i've seen this happen before is
modifying the model while iterating over it, which is exactly what
your row-inserted handler is doing. I can't pinpoint exactly *how*
it is getting corrupted; it would take a lot of tracing and digging
through unfamiliar code, since the error happens quite a way after
the actual corruption occurs, and i'm just not up for that tonight.
On a hunch that the problem stems from modifying the completion model
in a handler for a signal that is emitted when the model is
modified... i tried a slightly different approach.
Your code is unconditionally adding the user's text to the completion
model, and then scraping out any duplicates. Why let the duplicates
in there in the first place?
I removed the entire row-inserted handler, and did this, instead:
sub update_completion_model {
my ($model, $new_value) = @_;
# If not already in there, append.
my $iter = $model->get_iter_first;
while ($iter) {
my $old_value = $model->get ($iter, 0);
return if $old_value eq $new_value;
$iter = $model->iter_next ($iter);
}
$model->insert_with_values (-1, 0, $new_value);
}
$slist -> get_model -> signal_connect('row-changed' => sub {
my ($model, $path, $iter) = @_;
my $text = $slist->get_model->get($iter, 0);
update_completion_model ($cmp_model, $text);
});
And i can no longer trigger the assertion failures.
--
If the monkey could type one keystroke every nanosecond, the expected
waiting time until the monkey types out Hamlet is so long that the
estimated age of the universe is insignificant by comparison ... this
is not a practical method for writing plays.
-- Gian-Carlo Rota
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]