mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-29 08:31:35 -08:00
Reduce GTK tool-bar switching delay by avoiding selective show/hide of widgets.
* src/gtkutil.c (xg_get_tool_bar_widgets): Use NULL for a missing image or label in the container. (xg_make_tool_item): Replace VERT_ONLY arg with HORIZ, TEXT_IMAGE. (xg_show_toolbar_item): Function deleted. (xg_tool_item_stale_p): New function. (update_frame_tool_bar): Calculate tool-bar style once per call. Instead of hiding text labels, omit them. Don't use xg_show_toolbar_item; create new GtkToolItems from scratch if necessary, instead of trying to re-use them. This avoids an annoying animation when changing tool-bars.
This commit is contained in:
parent
8d68c659a6
commit
3afff00e6f
2 changed files with 109 additions and 156 deletions
|
|
@ -1,3 +1,16 @@
|
|||
2011-01-01 Chong Yidong <cyd@stupidchicken.com>
|
||||
|
||||
* gtkutil.c (xg_get_tool_bar_widgets): Use NULL for a missing
|
||||
image or label in the container.
|
||||
(xg_make_tool_item): Replace VERT_ONLY arg with HORIZ, TEXT_IMAGE.
|
||||
(xg_show_toolbar_item): Function deleted.
|
||||
(xg_tool_item_stale_p): New function.
|
||||
(update_frame_tool_bar): Calculate tool-bar style once per call.
|
||||
Instead of hiding text labels, omit them. Don't use
|
||||
xg_show_toolbar_item; create new GtkToolItems from scratch if
|
||||
necessary, instead of trying to re-use them. This avoids an
|
||||
annoying animation when changing tool-bars.
|
||||
|
||||
2010-12-31 Jan Djärv <jan.h.d@swipnet.se>
|
||||
|
||||
* nsfns.m (ns_set_name_as_filename): Always use buffer name for
|
||||
|
|
|
|||
252
src/gtkutil.c
252
src/gtkutil.c
|
|
@ -3664,7 +3664,8 @@ xg_get_tool_bar_widgets (GtkWidget *vb, GtkWidget **wimage)
|
|||
{
|
||||
GList *clist = gtk_container_get_children (GTK_CONTAINER (vb));
|
||||
GtkWidget *c1 = (GtkWidget *) clist->data;
|
||||
GtkWidget *c2 = (GtkWidget *) clist->next->data;
|
||||
GtkWidget *c2 = clist->next ? (GtkWidget *) clist->next->data : NULL;
|
||||
|
||||
*wimage = GTK_IS_IMAGE (c1) ? c1 : c2;
|
||||
g_list_free (clist);
|
||||
return GTK_IS_LABEL (c1) ? c1 : c2;
|
||||
|
|
@ -4039,28 +4040,17 @@ xg_make_tool_item (FRAME_PTR f,
|
|||
GtkWidget *wimage,
|
||||
GtkWidget **wbutton,
|
||||
const char *label,
|
||||
int i,
|
||||
int vert_only)
|
||||
int i, int horiz, int text_image)
|
||||
{
|
||||
GtkToolItem *ti = gtk_tool_item_new ();
|
||||
Lisp_Object style = Ftool_bar_get_system_style ();
|
||||
int both_horiz = EQ (style, Qboth_horiz);
|
||||
int text_image = EQ (style, Qtext_image_horiz);
|
||||
|
||||
GtkWidget *vb = both_horiz || text_image
|
||||
? gtk_hbox_new (FALSE, 0) : gtk_vbox_new (FALSE, 0);
|
||||
GtkWidget *vb = horiz ? gtk_hbox_new (FALSE, 0) : gtk_vbox_new (FALSE, 0);
|
||||
GtkWidget *wb = gtk_button_new ();
|
||||
GtkWidget *weventbox = gtk_event_box_new ();
|
||||
|
||||
/* We are not letting Gtk+ alter display on this, we only keep it here
|
||||
so we can get it later in xg_show_toolbar_item. */
|
||||
gtk_tool_item_set_is_important (ti, !vert_only);
|
||||
|
||||
if (wimage && ! text_image)
|
||||
if (wimage && !text_image)
|
||||
gtk_box_pack_start (GTK_BOX (vb), wimage, TRUE, TRUE, 0);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (vb), gtk_label_new (label), TRUE, TRUE, 0);
|
||||
|
||||
if (label)
|
||||
gtk_box_pack_start (GTK_BOX (vb), gtk_label_new (label), TRUE, TRUE, 0);
|
||||
if (wimage && text_image)
|
||||
gtk_box_pack_start (GTK_BOX (vb), wimage, TRUE, TRUE, 0);
|
||||
|
||||
|
|
@ -4121,58 +4111,49 @@ xg_make_tool_item (FRAME_PTR f,
|
|||
return ti;
|
||||
}
|
||||
|
||||
static void
|
||||
xg_show_toolbar_item (GtkToolItem *ti)
|
||||
static int
|
||||
xg_tool_item_stale_p (GtkWidget *wbutton, const char *stock_name,
|
||||
const char *icon_name, const struct image *img,
|
||||
const char *label, int horiz)
|
||||
{
|
||||
Lisp_Object style = Ftool_bar_get_system_style ();
|
||||
int both_horiz = EQ (style, Qboth_horiz);
|
||||
int text_image = EQ (style, Qtext_image_horiz);
|
||||
|
||||
int horiz = both_horiz || text_image;
|
||||
int vert_only = ! gtk_tool_item_get_is_important (ti);
|
||||
int show_label = ! EQ (style, Qimage) && ! (vert_only && horiz);
|
||||
int show_image = ! EQ (style, Qtext);
|
||||
|
||||
GtkWidget *weventbox = XG_BIN_CHILD (ti);
|
||||
GtkWidget *wbutton = XG_BIN_CHILD (weventbox);
|
||||
GtkWidget *vb = XG_BIN_CHILD (wbutton);
|
||||
gpointer old;
|
||||
GtkWidget *wimage;
|
||||
GtkWidget *vb = XG_BIN_CHILD (wbutton);
|
||||
GtkWidget *wlbl = xg_get_tool_bar_widgets (vb, &wimage);
|
||||
GtkWidget *new_box = NULL;
|
||||
|
||||
if (GTK_IS_VBOX (vb) && horiz)
|
||||
new_box = gtk_hbox_new (FALSE, 0);
|
||||
else if (GTK_IS_HBOX (vb) && !horiz && show_label && show_image)
|
||||
new_box = gtk_vbox_new (FALSE, 0);
|
||||
|
||||
if (!new_box && horiz)
|
||||
gtk_box_reorder_child (GTK_BOX (vb), wlbl, text_image ? 0 : 1);
|
||||
else if (new_box)
|
||||
/* Check if the tool icon matches. */
|
||||
if (stock_name)
|
||||
{
|
||||
g_object_ref (G_OBJECT (wimage));
|
||||
g_object_ref (G_OBJECT (wlbl));
|
||||
gtk_container_remove (GTK_CONTAINER (vb), wimage);
|
||||
gtk_container_remove (GTK_CONTAINER (vb), wlbl);
|
||||
gtk_widget_destroy (GTK_WIDGET (vb));
|
||||
if (! text_image)
|
||||
gtk_box_pack_start (GTK_BOX (new_box), wimage, TRUE, TRUE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (new_box), wlbl, TRUE, TRUE, 0);
|
||||
if (text_image)
|
||||
gtk_box_pack_start (GTK_BOX (new_box), wimage, TRUE, TRUE, 0);
|
||||
gtk_container_add (GTK_CONTAINER (wbutton), new_box);
|
||||
g_object_unref (G_OBJECT (wimage));
|
||||
g_object_unref (G_OBJECT (wlbl));
|
||||
vb = new_box;
|
||||
old = g_object_get_data (G_OBJECT (wimage),
|
||||
XG_TOOL_BAR_STOCK_NAME);
|
||||
if (!old || strcmp (old, stock_name))
|
||||
return 1;
|
||||
}
|
||||
else if (icon_name)
|
||||
{
|
||||
old = g_object_get_data (G_OBJECT (wimage),
|
||||
XG_TOOL_BAR_ICON_NAME);
|
||||
if (!old || strcmp (old, icon_name))
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Pixmap old_img
|
||||
= (Pixmap) g_object_get_data (G_OBJECT (wimage),
|
||||
XG_TOOL_BAR_IMAGE_DATA);
|
||||
if (old_img != img->pixmap)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (show_label) gtk_widget_show (wlbl);
|
||||
else gtk_widget_hide (wlbl);
|
||||
if (show_image) gtk_widget_show (wimage);
|
||||
else gtk_widget_hide (wimage);
|
||||
gtk_widget_show (GTK_WIDGET (weventbox));
|
||||
gtk_widget_show (GTK_WIDGET (vb));
|
||||
gtk_widget_show (GTK_WIDGET (wbutton));
|
||||
gtk_widget_show (GTK_WIDGET (ti));
|
||||
/* Check button configuration and label. */
|
||||
if ((horiz ? GTK_IS_VBOX (vb) : GTK_IS_HBOX (vb))
|
||||
|| (label ? (wlbl == NULL) : (wlbl != NULL)))
|
||||
return 1;
|
||||
|
||||
/* Ensure label is correct. */
|
||||
if (label)
|
||||
gtk_label_set_text (GTK_LABEL (wlbl), label);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -4225,7 +4206,7 @@ xg_update_tool_bar_sizes (FRAME_PTR f)
|
|||
void
|
||||
update_frame_tool_bar (FRAME_PTR f)
|
||||
{
|
||||
int i;
|
||||
int i, j;
|
||||
struct x_output *x = f->output_data.x;
|
||||
int hmargin = 0, vmargin = 0;
|
||||
GtkToolbar *wtoolbar;
|
||||
|
|
@ -4233,6 +4214,9 @@ update_frame_tool_bar (FRAME_PTR f)
|
|||
GtkTextDirection dir;
|
||||
int pack_tool_bar = x->handlebox_widget == NULL;
|
||||
|
||||
Lisp_Object style;
|
||||
int text_image, horiz;
|
||||
|
||||
if (! FRAME_GTK_WIDGET (f))
|
||||
return;
|
||||
|
||||
|
|
@ -4268,7 +4252,11 @@ update_frame_tool_bar (FRAME_PTR f)
|
|||
wtoolbar = GTK_TOOLBAR (x->toolbar_widget);
|
||||
dir = gtk_widget_get_direction (GTK_WIDGET (wtoolbar));
|
||||
|
||||
for (i = 0; i < f->n_tool_bar_items; ++i)
|
||||
style = Ftool_bar_get_system_style ();
|
||||
text_image = EQ (style, Qtext_image_horiz);
|
||||
horiz = EQ (style, Qboth_horiz) || text_image;
|
||||
|
||||
for (i = j = 0; i < f->n_tool_bar_items; ++i)
|
||||
{
|
||||
int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
|
||||
int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
|
||||
|
|
@ -4284,11 +4272,14 @@ update_frame_tool_bar (FRAME_PTR f)
|
|||
Lisp_Object rtl;
|
||||
GtkWidget *wbutton = NULL;
|
||||
Lisp_Object specified_file;
|
||||
const char *label = (STRINGP (PROP (TOOL_BAR_ITEM_LABEL))
|
||||
? SSDATA (PROP (TOOL_BAR_ITEM_LABEL)) : "");
|
||||
int vert_only = ! NILP (PROP (TOOL_BAR_ITEM_VERT_ONLY));
|
||||
const char *label
|
||||
= (EQ (style, Qimage) || (vert_only && horiz)) ? NULL
|
||||
: STRINGP (PROP (TOOL_BAR_ITEM_LABEL))
|
||||
? SSDATA (PROP (TOOL_BAR_ITEM_LABEL))
|
||||
: "";
|
||||
|
||||
ti = gtk_toolbar_get_nth_item (GTK_TOOLBAR (wtoolbar), i);
|
||||
ti = gtk_toolbar_get_nth_item (GTK_TOOLBAR (wtoolbar), j);
|
||||
|
||||
/* If this is a separator, use a gtk separator item. */
|
||||
if (EQ (PROP (TOOL_BAR_ITEM_TYPE), Qt))
|
||||
|
|
@ -4299,9 +4290,9 @@ update_frame_tool_bar (FRAME_PTR f)
|
|||
gtk_container_remove (GTK_CONTAINER (wtoolbar),
|
||||
GTK_WIDGET (ti));
|
||||
ti = gtk_separator_tool_item_new ();
|
||||
gtk_toolbar_insert (GTK_TOOLBAR (wtoolbar), ti, i);
|
||||
gtk_toolbar_insert (GTK_TOOLBAR (wtoolbar), ti, j);
|
||||
}
|
||||
gtk_widget_show (GTK_WIDGET (ti));
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -4313,14 +4304,15 @@ update_frame_tool_bar (FRAME_PTR f)
|
|||
ti = NULL;
|
||||
}
|
||||
|
||||
if (ti)
|
||||
wbutton = XG_BIN_CHILD (XG_BIN_CHILD (ti));
|
||||
if (ti) wbutton = XG_BIN_CHILD (XG_BIN_CHILD (ti));
|
||||
|
||||
/* Ignore invalid image specifications. */
|
||||
image = PROP (TOOL_BAR_ITEM_IMAGES);
|
||||
if (!valid_image_p (image))
|
||||
{
|
||||
if (wbutton) gtk_widget_hide (wbutton);
|
||||
if (ti)
|
||||
gtk_container_remove (GTK_CONTAINER (wtoolbar),
|
||||
GTK_WIDGET (ti));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -4356,16 +4348,13 @@ update_frame_tool_bar (FRAME_PTR f)
|
|||
|
||||
if (stock_name == NULL && icon_name == NULL)
|
||||
{
|
||||
/* No stock image, or stock item not known. Try regular image. */
|
||||
|
||||
/* If image is a vector, choose the image according to the
|
||||
/* No stock image, or stock item not known. Try regular
|
||||
image. If image is a vector, choose it according to the
|
||||
button state. */
|
||||
if (dir == GTK_TEXT_DIR_RTL
|
||||
&& !NILP (rtl = PROP (TOOL_BAR_ITEM_RTL_IMAGE))
|
||||
&& STRINGP (rtl))
|
||||
{
|
||||
image = find_rtl_image (f, image, rtl);
|
||||
}
|
||||
image = find_rtl_image (f, image, rtl);
|
||||
|
||||
if (VECTORP (image))
|
||||
{
|
||||
|
|
@ -4391,21 +4380,31 @@ update_frame_tool_bar (FRAME_PTR f)
|
|||
if (img->load_failed_p || img->pixmap == None)
|
||||
{
|
||||
if (ti)
|
||||
gtk_widget_hide_all (GTK_WIDGET (ti));
|
||||
else
|
||||
{
|
||||
/* Insert an empty (non-image) button */
|
||||
ti = xg_make_tool_item (f, NULL, NULL, "", i, 0);
|
||||
gtk_toolbar_insert (GTK_TOOLBAR (wtoolbar), ti, i);
|
||||
}
|
||||
gtk_container_remove (GTK_CONTAINER (wtoolbar),
|
||||
GTK_WIDGET (ti));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* If there is an existing widget, check if it's stale; if so,
|
||||
remove it and make a new tool item from scratch. */
|
||||
if (ti && xg_tool_item_stale_p (wbutton, stock_name, icon_name,
|
||||
img, label, horiz))
|
||||
{
|
||||
gtk_container_remove (GTK_CONTAINER (wtoolbar),
|
||||
GTK_WIDGET (ti));
|
||||
ti = NULL;
|
||||
}
|
||||
|
||||
if (ti == NULL)
|
||||
{
|
||||
GtkWidget *w;
|
||||
if (stock_name)
|
||||
|
||||
/* Save the image so we can see if an update is needed the
|
||||
next time we call xg_tool_item_match_p. */
|
||||
if (EQ (style, Qtext))
|
||||
w = NULL;
|
||||
else if (stock_name)
|
||||
{
|
||||
w = gtk_image_new_from_stock (stock_name, icon_size);
|
||||
g_object_set_data_full (G_OBJECT (w), XG_TOOL_BAR_STOCK_NAME,
|
||||
|
|
@ -4422,93 +4421,34 @@ update_frame_tool_bar (FRAME_PTR f)
|
|||
else
|
||||
{
|
||||
w = xg_get_image_for_pixmap (f, img, x->widget, NULL);
|
||||
/* Save the image so we can see if an update is needed when
|
||||
this function is called again. */
|
||||
g_object_set_data (G_OBJECT (w), XG_TOOL_BAR_IMAGE_DATA,
|
||||
(gpointer)img->pixmap);
|
||||
}
|
||||
|
||||
gtk_misc_set_padding (GTK_MISC (w), hmargin, vmargin);
|
||||
ti = xg_make_tool_item (f, w, &wbutton, label, i, vert_only);
|
||||
gtk_toolbar_insert (GTK_TOOLBAR (wtoolbar), ti, i);
|
||||
gtk_widget_set_sensitive (wbutton, enabled_p);
|
||||
if (w) gtk_misc_set_padding (GTK_MISC (w), hmargin, vmargin);
|
||||
ti = xg_make_tool_item (f, w, &wbutton, label, i, horiz, text_image);
|
||||
gtk_toolbar_insert (GTK_TOOLBAR (wtoolbar), ti, j);
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkWidget *vb = XG_BIN_CHILD (wbutton);
|
||||
GtkWidget *wimage;
|
||||
GtkWidget *wlbl = xg_get_tool_bar_widgets (vb, &wimage);
|
||||
|
||||
Pixmap old_img = (Pixmap) g_object_get_data (G_OBJECT (wimage),
|
||||
XG_TOOL_BAR_IMAGE_DATA);
|
||||
gpointer old_stock_name = g_object_get_data (G_OBJECT (wimage),
|
||||
XG_TOOL_BAR_STOCK_NAME);
|
||||
gpointer old_icon_name = g_object_get_data (G_OBJECT (wimage),
|
||||
XG_TOOL_BAR_ICON_NAME);
|
||||
gtk_label_set_text (GTK_LABEL (wlbl), label);
|
||||
gtk_tool_item_set_is_important (ti, !vert_only);
|
||||
if (stock_name &&
|
||||
(! old_stock_name || strcmp (old_stock_name, stock_name) != 0))
|
||||
{
|
||||
gtk_image_set_from_stock (GTK_IMAGE (wimage),
|
||||
stock_name, icon_size);
|
||||
g_object_set_data_full (G_OBJECT (wimage), XG_TOOL_BAR_STOCK_NAME,
|
||||
(gpointer) xstrdup (stock_name),
|
||||
(GDestroyNotify) xfree);
|
||||
g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_IMAGE_DATA,
|
||||
NULL);
|
||||
g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_ICON_NAME,
|
||||
NULL);
|
||||
}
|
||||
else if (icon_name &&
|
||||
(! old_icon_name || strcmp (old_icon_name, icon_name) != 0))
|
||||
{
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (wimage),
|
||||
icon_name, icon_size);
|
||||
g_object_set_data_full (G_OBJECT (wimage), XG_TOOL_BAR_ICON_NAME,
|
||||
(gpointer) xstrdup (icon_name),
|
||||
(GDestroyNotify) xfree);
|
||||
g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_IMAGE_DATA,
|
||||
NULL);
|
||||
g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_STOCK_NAME,
|
||||
NULL);
|
||||
}
|
||||
else if (img && old_img != img->pixmap)
|
||||
{
|
||||
(void) xg_get_image_for_pixmap (f, img, x->widget,
|
||||
GTK_IMAGE (wimage));
|
||||
g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_IMAGE_DATA,
|
||||
(gpointer)img->pixmap);
|
||||
|
||||
g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_STOCK_NAME,
|
||||
NULL);
|
||||
g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_ICON_NAME,
|
||||
NULL);
|
||||
}
|
||||
|
||||
gtk_misc_set_padding (GTK_MISC (wimage), hmargin, vmargin);
|
||||
|
||||
gtk_widget_set_sensitive (wbutton, enabled_p);
|
||||
}
|
||||
xg_show_toolbar_item (ti);
|
||||
|
||||
#undef PROP
|
||||
|
||||
gtk_widget_set_sensitive (wbutton, enabled_p);
|
||||
j++;
|
||||
}
|
||||
|
||||
/* Remove buttons not longer needed. We just hide them so they
|
||||
can be reused later on. */
|
||||
/* Remove buttons not longer needed. */
|
||||
do
|
||||
{
|
||||
ti = gtk_toolbar_get_nth_item (GTK_TOOLBAR (wtoolbar), i++);
|
||||
if (ti) gtk_widget_hide_all (GTK_WIDGET (ti));
|
||||
ti = gtk_toolbar_get_nth_item (GTK_TOOLBAR (wtoolbar), j++);
|
||||
if (ti)
|
||||
gtk_container_remove (GTK_CONTAINER (wtoolbar), GTK_WIDGET (ti));
|
||||
} while (ti != NULL);
|
||||
|
||||
if (f->n_tool_bar_items != 0)
|
||||
{
|
||||
if (pack_tool_bar)
|
||||
xg_pack_tool_bar (f, f->tool_bar_position);
|
||||
gtk_widget_show (x->toolbar_widget);
|
||||
gtk_widget_show (x->handlebox_widget);
|
||||
gtk_widget_show_all (GTK_WIDGET (x->handlebox_widget));
|
||||
if (xg_update_tool_bar_sizes (f))
|
||||
xg_height_or_width_changed (f);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue