mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-10 10:50:10 +00:00
menutracker: reduce allocations and signal emission
When handling action-added callbacks the code was previously using a freeze_notify/thaw_notify in all cases. This turns out to allocate a significant amount of memory when called a lot. That said, it shouldn't be getting called this much but given the current state of affairs elsewhere in GtkActionMuxer, this brought temporary allocations down from 9MiB to 9KiB in gnome-text-editor after showing the context menu a few times. Related #4422
This commit is contained in:
parent
348e34f221
commit
00d5f72d6e
@ -286,7 +286,7 @@ gtk_menu_tracker_item_update_visibility (GtkMenuTrackerItem *self)
|
|||||||
if (visible != self->is_visible)
|
if (visible != self->is_visible)
|
||||||
{
|
{
|
||||||
self->is_visible = visible;
|
self->is_visible = visible;
|
||||||
g_object_notify (G_OBJECT (self), "is-visible");
|
g_object_notify_by_pspec (G_OBJECT (self), gtk_menu_tracker_item_pspecs[PROP_IS_VISIBLE]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,9 +300,17 @@ gtk_menu_tracker_item_action_added (GtkActionObserver *observer,
|
|||||||
{
|
{
|
||||||
GtkMenuTrackerItem *self = GTK_MENU_TRACKER_ITEM (observer);
|
GtkMenuTrackerItem *self = GTK_MENU_TRACKER_ITEM (observer);
|
||||||
GVariant *action_target;
|
GVariant *action_target;
|
||||||
|
gboolean old_sensitive;
|
||||||
|
gboolean old_toggled;
|
||||||
|
GtkMenuTrackerItemRole old_role;
|
||||||
|
guint n_changed;
|
||||||
|
|
||||||
GTK_NOTE(ACTIONS, g_message ("menutracker: action %s added", action_name));
|
GTK_NOTE(ACTIONS, g_message ("menutracker: action %s added", action_name));
|
||||||
|
|
||||||
|
old_sensitive = self->sensitive;
|
||||||
|
old_toggled = self->toggled;
|
||||||
|
old_role = self->role;
|
||||||
|
|
||||||
action_target = g_menu_item_get_attribute_value (self->item, G_MENU_ATTRIBUTE_TARGET, NULL);
|
action_target = g_menu_item_get_attribute_value (self->item, G_MENU_ATTRIBUTE_TARGET, NULL);
|
||||||
|
|
||||||
self->can_activate = (action_target == NULL && parameter_type == NULL) ||
|
self->can_activate = (action_target == NULL && parameter_type == NULL) ||
|
||||||
@ -340,17 +348,28 @@ gtk_menu_tracker_item_action_added (GtkActionObserver *observer,
|
|||||||
self->role = GTK_MENU_TRACKER_ITEM_ROLE_CHECK;
|
self->role = GTK_MENU_TRACKER_ITEM_ROLE_CHECK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Avoid freeze/thaw_notify as they are quite expensive in runtime/memory
|
||||||
|
* unless we have more than one property to update. Additionally, only
|
||||||
|
* notify on properties that have changed to avoid extraneous signal
|
||||||
|
* emission. This code can get run a lot!
|
||||||
|
*/
|
||||||
|
n_changed = (old_role != self->role)
|
||||||
|
+ (old_toggled != self->toggled)
|
||||||
|
+ (old_sensitive != self->sensitive);
|
||||||
|
|
||||||
|
if (n_changed > 1)
|
||||||
g_object_freeze_notify (G_OBJECT (self));
|
g_object_freeze_notify (G_OBJECT (self));
|
||||||
|
|
||||||
if (self->sensitive)
|
if (self->sensitive != old_sensitive)
|
||||||
g_object_notify_by_pspec (G_OBJECT (self), gtk_menu_tracker_item_pspecs[PROP_SENSITIVE]);
|
g_object_notify_by_pspec (G_OBJECT (self), gtk_menu_tracker_item_pspecs[PROP_SENSITIVE]);
|
||||||
|
|
||||||
if (self->toggled)
|
if (self->toggled != old_toggled)
|
||||||
g_object_notify_by_pspec (G_OBJECT (self), gtk_menu_tracker_item_pspecs[PROP_TOGGLED]);
|
g_object_notify_by_pspec (G_OBJECT (self), gtk_menu_tracker_item_pspecs[PROP_TOGGLED]);
|
||||||
|
|
||||||
if (self->role != GTK_MENU_TRACKER_ITEM_ROLE_NORMAL)
|
if (self->role != old_role)
|
||||||
g_object_notify_by_pspec (G_OBJECT (self), gtk_menu_tracker_item_pspecs[PROP_ROLE]);
|
g_object_notify_by_pspec (G_OBJECT (self), gtk_menu_tracker_item_pspecs[PROP_ROLE]);
|
||||||
|
|
||||||
|
if (n_changed > 1)
|
||||||
g_object_thaw_notify (G_OBJECT (self));
|
g_object_thaw_notify (G_OBJECT (self));
|
||||||
|
|
||||||
if (action_target)
|
if (action_target)
|
||||||
|
Loading…
Reference in New Issue
Block a user