| Gtk2-Ex-WidgetBits documentation | view source | Contained in the Gtk2-Ex-WidgetBits distribution. |
Gtk2::Ex::FreezeChildNotify -- freeze Gtk child property notifies in scope guard style
use Gtk2::Ex::FreezeChildNotify;
{ my $freezer = Gtk2::Ex::FreezeChildNotify->new ($widget);
$parent->child_set_property ($widget, foo => 123);
$parent->child_set_property ($widget, bar => 456);
# child-notify signals emitted when $freezer goes out of scope
}
# or multiple widgets in one FreezeChildNotify
{
my $freezer = Gtk2::Ex::FreezeChildNotify->new ($widget1, $widget2);
$parent->child_set_property ($widget, foo => 999);
$parent->child_set_property ($widget, bar => 666);
}
Gtk2::Ex::FreezeChildNotify applies a freeze_child_notify to given
widgets, with automatic corresponding thaw_child_notify at the end of a
block, no matter how it's exited, whether a goto, early return,
die, etc.
This protects against an error throw leaving the widget permanently frozen.
Even in a simple bit of code an error can be thrown for a bad property name
in a child_set_property, or while calculating a value. (Though as of
Glib-Perl 1.222 an invalid argument type to child_set_property generally
only provokes warnings.)
FreezeChildNotify works by having thaw_child_notify in the destroy code
of the FreezeChildNotify object.
FreezeChildNotify only holds weak references to its widgets, so the mere fact they're due for later thawing doesn't keep them alive if nothing else cares whether they live or die. The effect is that frozen widgets can be garbage collected within a freeze block at the same point they would be without any freezing, instead of extending their life to the end of the block.
It works to have multiple freeze/thaws, done either with FreezeChildNotify
or with explicit freeze_child_notify calls. Gtk2::Widget simply
counts outstanding freezes, which means they don't have to nest, so multiple
freezes can overlap in any fashion. If you're freezing for an extended time
then a FreezeChildNotify object is a good way not to lose track of the
thaws, although anything except a short freeze for a handful of
child_set_property calls would be unusual.
$freezer = Gtk2::Ex::FreezeChildNotify->new ($widget,...)Do a $widget->freeze_child_notify on each given widget and return a
FreezeChildNotify object which, when it's destroyed, will
$widget->thaw_child_notify each. So something like
$widget->freeze_child_notify;
$parent->child_set_property ($widget, foo => 1);
$parent->child_set_property ($widget, bar => 2);
$widget->thaw_child_notify;
becomes instead
{ my $freezer = Gtk2::Ex::FreezeChildNotify->new ($widget);
$parent->child_set_property ($widget, foo => 1);
$parent->child_set_property ($widget, bar => 2);
} # automatic thaw when $freezer goes out of scope
$freezer->add ($widget,...)Add additional widgets to the freezer, calling
$widget->freeze_child_notify on each, and setting up for
thaw_child_notify the same as in new above.
If the widgets to be frozen are not known in advance then it's good to
create an empty freezer with new then add widgets as required.
When there's multiple widgets in a freezer it's unspecified what order the
thaw_child_notify calls are made. What would be good? First-in
first-out, or a stack? You can create multiple FreezeChildNotify objects
and arrange blocks or explicit discards to destroy them in a particular
order if it matters.
Glib::Ex::FreezeNotify does corresponding freezes on plain property
notifies.
There's quite a few general purpose block-scope cleanup systems if you want
more than just thaws.
Scope::Guard,
AtExit (AtExit),
End,
ReleaseAction,
Sub::ScopeFinalizer
and Guard use the destructor style.
Hook::Scope
and B::Hooks::EndOfScope
manipulate the code in a block.
Unwind::Protect uses an eval and re-throw.
Gtk2::Widget, Glib::Ex::FreezeNotify
Copyright 2008, 2009, 2010, 2011 Kevin Ryde
Gtk2-Ex-WidgetBits is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version.
Gtk2-Ex-WidgetBits is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with Gtk2-Ex-WidgetBits. If not, see http://www.gnu.org/licenses/.
| Gtk2-Ex-WidgetBits documentation | view source | Contained in the Gtk2-Ex-WidgetBits distribution. |