]> Pileus Git - ~andy/gtk/blob - gtk/gtksizegroup.c
Make sure that the quarks are initialized before using them. (#353736)
[~andy/gtk] / gtk / gtksizegroup.c
1 /* GTK - The GIMP Toolkit
2  * gtksizegroup.c: 
3  * Copyright (C) 2001 Red Hat Software
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include <config.h>
22 #include "gtkcontainer.h"
23 #include "gtkintl.h"
24 #include "gtkprivate.h"
25 #include "gtksizegroup.h"
26 #include "gtkalias.h"
27
28 enum {
29   PROP_0,
30   PROP_MODE,
31   PROP_IGNORE_HIDDEN
32 };
33
34 static void gtk_size_group_set_property (GObject      *object,
35                                          guint         prop_id,
36                                          const GValue *value,
37                                          GParamSpec   *pspec);
38 static void gtk_size_group_get_property (GObject      *object,
39                                          guint         prop_id,
40                                          GValue       *value,
41                                          GParamSpec   *pspec);
42
43 static void add_group_to_closure  (GtkSizeGroup      *group,
44                                    GtkSizeGroupMode   mode,
45                                    GSList           **groups,
46                                    GSList           **widgets);
47 static void add_widget_to_closure (GtkWidget         *widget,
48                                    GtkSizeGroupMode   mode,
49                                    GSList           **groups,
50                                    GSList           **widgets);
51
52 static GQuark size_groups_quark;
53 static const gchar size_groups_tag[] = "gtk-size-groups";
54
55 static GQuark visited_quark;
56 static const gchar visited_tag[] = "gtk-size-group-visited";
57
58 static GSList *
59 get_size_groups (GtkWidget *widget)
60 {
61   return g_object_get_qdata (G_OBJECT (widget), size_groups_quark);
62 }
63
64 static void
65 set_size_groups (GtkWidget *widget,
66                  GSList    *groups)
67 {
68   g_object_set_qdata (G_OBJECT (widget), size_groups_quark, groups);
69 }
70
71 static void
72 mark_visited (gpointer object)
73 {
74   g_object_set_qdata (object, visited_quark, "visited");
75 }
76
77 static void
78 mark_unvisited (gpointer object)
79 {
80   g_object_set_qdata (object, visited_quark, NULL);
81 }
82
83 static gboolean
84 is_visited (gpointer object)
85 {
86   return g_object_get_qdata (object, visited_quark) != NULL;
87 }
88
89 static void
90 add_group_to_closure (GtkSizeGroup    *group,
91                       GtkSizeGroupMode mode,
92                       GSList         **groups,
93                       GSList         **widgets)
94 {
95   GSList *tmp_widgets;
96   
97   *groups = g_slist_prepend (*groups, group);
98   mark_visited (group);
99
100   tmp_widgets = group->widgets;
101   while (tmp_widgets)
102     {
103       GtkWidget *tmp_widget = tmp_widgets->data;
104       
105       if (!is_visited (tmp_widget))
106         add_widget_to_closure (tmp_widget, mode, groups, widgets);
107       
108       tmp_widgets = tmp_widgets->next;
109     }
110 }
111
112 static void
113 add_widget_to_closure (GtkWidget       *widget,
114                        GtkSizeGroupMode mode,
115                        GSList         **groups,
116                        GSList         **widgets)
117 {
118   GSList *tmp_groups;
119
120   *widgets = g_slist_prepend (*widgets, widget);
121   mark_visited (widget);
122
123   tmp_groups = get_size_groups (widget);
124   while (tmp_groups)
125     {
126       GtkSizeGroup *tmp_group = tmp_groups->data;
127       
128       if ((tmp_group->mode == GTK_SIZE_GROUP_BOTH || tmp_group->mode == mode) &&
129           !is_visited (tmp_group))
130         add_group_to_closure (tmp_group, mode, groups, widgets);
131
132       tmp_groups = tmp_groups->next;
133     }
134 }
135
136 static void
137 real_queue_resize (GtkWidget *widget)
138 {
139   GTK_PRIVATE_SET_FLAG (widget, GTK_ALLOC_NEEDED);
140   GTK_PRIVATE_SET_FLAG (widget, GTK_REQUEST_NEEDED);
141   
142   if (widget->parent)
143     _gtk_container_queue_resize (GTK_CONTAINER (widget->parent));
144   else if (GTK_WIDGET_TOPLEVEL (widget) && GTK_IS_CONTAINER (widget))
145     _gtk_container_queue_resize (GTK_CONTAINER (widget));
146 }
147
148 static void
149 reset_group_sizes (GSList *groups)
150 {
151   GSList *tmp_list = groups;
152   while (tmp_list)
153     {
154       GtkSizeGroup *tmp_group = tmp_list->data;
155
156       tmp_group->have_width = FALSE;
157       tmp_group->have_height = FALSE;
158       
159       tmp_list = tmp_list->next;
160     }
161 }
162
163 static void
164 queue_resize_on_widget (GtkWidget *widget,
165                         gboolean   check_siblings)
166 {
167   GtkWidget *parent = widget;
168   GSList *tmp_list;
169
170   while (parent)
171     {
172       GSList *widget_groups;
173       GSList *groups;
174       GSList *widgets;
175       
176       if (widget == parent && !check_siblings)
177         {
178           real_queue_resize (widget);
179           parent = parent->parent;
180           continue;
181         }
182       
183       widget_groups = get_size_groups (parent);
184       if (!widget_groups)
185         {
186           if (widget == parent)
187             real_queue_resize (widget);
188
189           parent = parent->parent;
190           continue;
191         }
192
193       groups = NULL;
194       widgets = NULL;
195           
196       add_widget_to_closure (parent, GTK_SIZE_GROUP_HORIZONTAL, &groups, &widgets);
197       g_slist_foreach (widgets, (GFunc)mark_unvisited, NULL);
198       g_slist_foreach (groups, (GFunc)mark_unvisited, NULL);
199
200       reset_group_sizes (groups);
201               
202       tmp_list = widgets;
203       while (tmp_list)
204         {
205           if (tmp_list->data == parent)
206             {
207               if (widget == parent)
208                 real_queue_resize (parent);
209             }
210           else
211             queue_resize_on_widget (tmp_list->data, FALSE);
212
213           tmp_list = tmp_list->next;
214         }
215       
216       g_slist_free (widgets);
217       g_slist_free (groups);
218               
219       groups = NULL;
220       widgets = NULL;
221               
222       add_widget_to_closure (parent, GTK_SIZE_GROUP_VERTICAL, &groups, &widgets);
223       g_slist_foreach (widgets, (GFunc)mark_unvisited, NULL);
224       g_slist_foreach (groups, (GFunc)mark_unvisited, NULL);
225
226       reset_group_sizes (groups);
227               
228       tmp_list = widgets;
229       while (tmp_list)
230         {
231           if (tmp_list->data == parent)
232             {
233               if (widget == parent)
234                 real_queue_resize (parent);
235             }
236           else
237             queue_resize_on_widget (tmp_list->data, FALSE);
238
239           tmp_list = tmp_list->next;
240         }
241       
242       g_slist_free (widgets);
243       g_slist_free (groups);
244       
245       parent = parent->parent;
246     }
247 }
248
249 static void
250 queue_resize_on_group (GtkSizeGroup *size_group)
251 {
252   if (size_group->widgets)
253     queue_resize_on_widget (size_group->widgets->data, TRUE);
254 }
255
256 static void
257 initialize_size_group_quarks (void)
258 {
259   if (!size_groups_quark)
260     {
261       size_groups_quark = g_quark_from_static_string (size_groups_tag);
262       visited_quark = g_quark_from_string (visited_tag);
263     }
264 }
265
266 static void
267 gtk_size_group_class_init (GtkSizeGroupClass *klass)
268 {
269   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
270
271   gobject_class->set_property = gtk_size_group_set_property;
272   gobject_class->get_property = gtk_size_group_get_property;
273   
274   g_object_class_install_property (gobject_class,
275                                    PROP_MODE,
276                                    g_param_spec_enum ("mode",
277                                                       P_("Mode"),
278                                                       P_("The directions in which the size group affects the requested sizes"
279                                                         " of its component widgets"),
280                                                       GTK_TYPE_SIZE_GROUP_MODE,
281                                                       GTK_SIZE_GROUP_HORIZONTAL,                                                      GTK_PARAM_READWRITE));
282
283   /**
284    * GtkSizeGroup:ignore-hidden:
285    *
286    * If %TRUE, unmapped widgets are ignored when determining 
287    * the size of the group.
288    *
289    * Since: 2.8
290    */
291   g_object_class_install_property (gobject_class,
292                                    PROP_IGNORE_HIDDEN,
293                                    g_param_spec_boolean ("ignore-hidden",
294                                                          P_("Ignore hidden"),
295                                                          P_("If TRUE, unmapped widgets are ignored "
296                                                             "when determining the size of the group"),
297                                                          FALSE,
298                                                          GTK_PARAM_READWRITE));
299   
300   initialize_size_group_quarks ();
301 }
302
303 static void
304 gtk_size_group_init (GtkSizeGroup *size_group)
305 {
306   size_group->widgets = NULL;
307   size_group->mode = GTK_SIZE_GROUP_HORIZONTAL;
308   size_group->have_width = 0;
309   size_group->have_height = 0;
310   size_group->ignore_hidden = 0;
311 }
312
313 G_DEFINE_TYPE (GtkSizeGroup, gtk_size_group, G_TYPE_OBJECT)
314
315 static void
316 gtk_size_group_set_property (GObject      *object,
317                              guint         prop_id,
318                              const GValue *value,
319                              GParamSpec   *pspec)
320 {
321   GtkSizeGroup *size_group = GTK_SIZE_GROUP (object);
322
323   switch (prop_id)
324     {
325     case PROP_MODE:
326       gtk_size_group_set_mode (size_group, g_value_get_enum (value));
327       break;
328     case PROP_IGNORE_HIDDEN:
329       gtk_size_group_set_ignore_hidden (size_group, g_value_get_boolean (value));
330       break;
331     default:
332       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
333       break;
334     }
335 }
336
337 static void
338 gtk_size_group_get_property (GObject      *object,
339                              guint         prop_id,
340                              GValue       *value,
341                              GParamSpec   *pspec)
342 {
343   GtkSizeGroup *size_group = GTK_SIZE_GROUP (object);
344
345   switch (prop_id)
346     {
347     case PROP_MODE:
348       g_value_set_enum (value, size_group->mode);
349       break;
350     case PROP_IGNORE_HIDDEN:
351       g_value_set_boolean (value, size_group->ignore_hidden);
352       break;
353     default:
354       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
355       break;
356     }
357 }
358
359 /**
360  * gtk_size_group_new:
361  * @mode: the mode for the new size group.
362  * 
363  * Create a new #GtkSizeGroup.
364  
365  * Return value: a newly created #GtkSizeGroup
366  **/
367 GtkSizeGroup *
368 gtk_size_group_new (GtkSizeGroupMode mode)
369 {
370   GtkSizeGroup *size_group = g_object_new (GTK_TYPE_SIZE_GROUP, NULL);
371
372   size_group->mode = mode;
373
374   return size_group;
375 }
376
377 /**
378  * gtk_size_group_set_mode:
379  * @size_group: a #GtkSizeGroup
380  * @mode: the mode to set for the size group.
381  * 
382  * Sets the #GtkSizeGroupMode of the size group. The mode of the size
383  * group determines whether the widgets in the size group should
384  * all have the same horizontal requisition (%GTK_SIZE_GROUP_MODE_HORIZONTAL)
385  * all have the same vertical requisition (%GTK_SIZE_GROUP_MODE_VERTICAL),
386  * or should all have the same requisition in both directions
387  * (%GTK_SIZE_GROUP_MODE_BOTH).
388  **/
389 void
390 gtk_size_group_set_mode (GtkSizeGroup     *size_group,
391                          GtkSizeGroupMode  mode)
392 {
393   g_return_if_fail (GTK_IS_SIZE_GROUP (size_group));
394
395   if (size_group->mode != mode)
396     {
397       if (size_group->mode != GTK_SIZE_GROUP_NONE)
398         queue_resize_on_group (size_group);
399       size_group->mode = mode;
400       if (size_group->mode != GTK_SIZE_GROUP_NONE)
401         queue_resize_on_group (size_group);
402
403       g_object_notify (G_OBJECT (size_group), "mode");
404     }
405 }
406
407 /**
408  * gtk_size_group_get_mode:
409  * @size_group: a #GtkSizeGroup
410  * 
411  * Gets the current mode of the size group. See gtk_size_group_set_mode().
412  * 
413  * Return value: the current mode of the size group.
414  **/
415 GtkSizeGroupMode
416 gtk_size_group_get_mode (GtkSizeGroup *size_group)
417 {
418   g_return_val_if_fail (GTK_IS_SIZE_GROUP (size_group), GTK_SIZE_GROUP_BOTH);
419
420   return size_group->mode;
421 }
422
423 /**
424  * gtk_size_group_set_ignore_hidden:
425  * @size_group: a #GtkSizeGroup
426  * @ignore_hidden: whether unmapped widgets should be ignored
427  *   when calculating the size
428  * 
429  * Sets whether unmapped widgets should be ignored when
430  * calculating the size.
431  *
432  * Since: 2.8 
433  */
434 void
435 gtk_size_group_set_ignore_hidden (GtkSizeGroup *size_group,
436                                   gboolean      ignore_hidden)
437 {
438   g_return_if_fail (GTK_IS_SIZE_GROUP (size_group));
439   
440   ignore_hidden = ignore_hidden != FALSE;
441
442   if (size_group->ignore_hidden != ignore_hidden)
443     {
444       size_group->ignore_hidden = ignore_hidden;
445
446       g_object_notify (G_OBJECT (size_group), "ignore-hidden");
447     }
448 }
449
450 /**
451  * gtk_size_group_get_ignore_hidden:
452  * @size_group: a #GtkSizeGroup
453  *
454  * Returns if invisible widgets are ignored when calculating the size.
455  *
456  * Returns: %TRUE if invisible widgets are ignored.
457  *
458  * Since: 2.8
459  */
460 gboolean
461 gtk_size_group_get_ignore_hidden (GtkSizeGroup *size_group)
462 {
463   g_return_val_if_fail (GTK_IS_SIZE_GROUP (size_group), FALSE);
464
465   return size_group->ignore_hidden;
466 }
467
468 static void
469 gtk_size_group_widget_destroyed (GtkWidget    *widget,
470                                  GtkSizeGroup *size_group)
471 {
472   gtk_size_group_remove_widget (size_group, widget);
473 }
474
475 /**
476  * gtk_size_group_add_widget:
477  * @size_group: a #GtkSizeGroup
478  * @widget: the #GtkWidget to add
479  * 
480  * Adds a widget to a #GtkSizeGroup. In the future, the requisition
481  * of the widget will be determined as the maximum of its requisition
482  * and the requisition of the other widgets in the size group.
483  * Whether this applies horizontally, vertically, or in both directions
484  * depends on the mode of the size group. See gtk_size_group_set_mode().
485  **/
486 void
487 gtk_size_group_add_widget (GtkSizeGroup     *size_group,
488                            GtkWidget        *widget)
489 {
490   GSList *groups;
491   
492   g_return_if_fail (GTK_IS_SIZE_GROUP (size_group));
493   g_return_if_fail (GTK_IS_WIDGET (widget));
494   
495   groups = get_size_groups (widget);
496
497   if (!g_slist_find (groups, size_group))
498     {
499       groups = g_slist_prepend (groups, size_group);
500       set_size_groups (widget, groups);
501
502       size_group->widgets = g_slist_prepend (size_group->widgets, widget);
503
504       g_signal_connect (widget, "destroy",
505                         G_CALLBACK (gtk_size_group_widget_destroyed),
506                         size_group);
507
508       g_object_ref (size_group);
509     }
510   
511   queue_resize_on_group (size_group);
512 }
513
514 /**
515  * gtk_size_group_remove_widget:
516  * @size_group: a #GtkSizeGrup
517  * @widget: the #GtkWidget to remove
518  * 
519  * Removes a widget from a #GtkSizeGroup.
520  **/
521 void
522 gtk_size_group_remove_widget (GtkSizeGroup *size_group,
523                               GtkWidget    *widget)
524 {
525   GSList *groups;
526   
527   g_return_if_fail (GTK_IS_SIZE_GROUP (size_group));
528   g_return_if_fail (GTK_IS_WIDGET (widget));
529   g_return_if_fail (g_slist_find (size_group->widgets, widget));
530
531   g_signal_handlers_disconnect_by_func (widget,
532                                         gtk_size_group_widget_destroyed,
533                                         size_group);
534   
535   groups = get_size_groups (widget);
536   groups = g_slist_remove (groups, size_group);
537   set_size_groups (widget, groups);
538
539   size_group->widgets = g_slist_remove (size_group->widgets, widget);
540   queue_resize_on_group (size_group);
541   gtk_widget_queue_resize (widget);
542
543   g_object_unref (size_group);
544 }
545
546 /**
547  * gtk_size_group_get_widgets:
548  * @size_group: a #GtkSizeGrup
549  * 
550  * Returns the list of widgets associated with @size_group.
551  *
552  * Return value: a #GSList of widgets. The list is owned by GTK+ 
553  *   and should not be modified.
554  *
555  * Since: 2.10
556  **/
557 GSList *
558 gtk_size_group_get_widgets (GtkSizeGroup *size_group)
559 {
560   return size_group->widgets;
561 }
562
563 static gint
564 get_base_dimension (GtkWidget        *widget,
565                     GtkSizeGroupMode  mode)
566 {
567   GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (widget, FALSE);
568
569   if (mode == GTK_SIZE_GROUP_HORIZONTAL)
570     {
571       if (aux_info && aux_info->width > 0)
572         return aux_info->width;
573       else
574         return widget->requisition.width;
575     }
576   else
577     {
578       if (aux_info && aux_info->height > 0)
579         return aux_info->height;
580       else
581         return widget->requisition.height;
582     }
583 }
584
585 static void
586 do_size_request (GtkWidget *widget)
587 {
588   if (GTK_WIDGET_REQUEST_NEEDED (widget))
589     {
590       gtk_widget_ensure_style (widget);      
591       GTK_PRIVATE_UNSET_FLAG (widget, GTK_REQUEST_NEEDED);
592       g_signal_emit_by_name (widget,
593                              "size_request",
594                              &widget->requisition);
595     }
596 }
597
598 static gint
599 compute_base_dimension (GtkWidget        *widget,
600                         GtkSizeGroupMode  mode)
601 {
602   do_size_request (widget);
603
604   return get_base_dimension (widget, mode);
605 }
606
607 static gint
608 compute_dimension (GtkWidget        *widget,
609                    GtkSizeGroupMode  mode)
610 {
611   GSList *widgets = NULL;
612   GSList *groups = NULL;
613   GSList *tmp_list;
614   gint result = 0;
615
616   add_widget_to_closure (widget, mode, &groups, &widgets);
617
618   g_slist_foreach (widgets, (GFunc)mark_unvisited, NULL);
619   g_slist_foreach (groups, (GFunc)mark_unvisited, NULL);
620   
621   g_slist_foreach (widgets, (GFunc)g_object_ref, NULL);
622   
623   if (!groups)
624     {
625       result = compute_base_dimension (widget, mode);
626     }
627   else
628     {
629       GtkSizeGroup *group = groups->data;
630
631       if (mode == GTK_SIZE_GROUP_HORIZONTAL && group->have_width)
632         result = group->requisition.width;
633       else if (mode == GTK_SIZE_GROUP_VERTICAL && group->have_height)
634         result = group->requisition.height;
635       else
636         {
637           tmp_list = widgets;
638           while (tmp_list)
639             {
640               GtkWidget *tmp_widget = tmp_list->data;
641
642               gint dimension = compute_base_dimension (tmp_widget, mode);
643
644               if (GTK_WIDGET_MAPPED (tmp_widget) || !group->ignore_hidden)
645                 {
646                   if (dimension > result)
647                     result = dimension;
648                 }
649
650               tmp_list = tmp_list->next;
651             }
652
653           tmp_list = groups;
654           while (tmp_list)
655             {
656               GtkSizeGroup *tmp_group = tmp_list->data;
657
658               if (mode == GTK_SIZE_GROUP_HORIZONTAL)
659                 {
660                   tmp_group->have_width = TRUE;
661                   tmp_group->requisition.width = result;
662                 }
663               else
664                 {
665                   tmp_group->have_height = TRUE;
666                   tmp_group->requisition.height = result;
667                 }
668               
669               tmp_list = tmp_list->next;
670             }
671         }
672     }
673
674   g_slist_foreach (widgets, (GFunc)g_object_unref, NULL);
675
676   g_slist_free (widgets);
677   g_slist_free (groups);
678
679   return result;
680 }
681
682 static gint
683 get_dimension (GtkWidget        *widget,
684                GtkSizeGroupMode  mode)
685 {
686   GSList *widgets = NULL;
687   GSList *groups = NULL;
688   gint result = 0;
689
690   add_widget_to_closure (widget, mode, &groups, &widgets);
691
692   g_slist_foreach (widgets, (GFunc)mark_unvisited, NULL);
693   g_slist_foreach (groups, (GFunc)mark_unvisited, NULL);  
694
695   if (!groups)
696     {
697       result = get_base_dimension (widget, mode);
698     }
699   else
700     {
701       GtkSizeGroup *group = groups->data;
702
703       if (mode == GTK_SIZE_GROUP_HORIZONTAL && group->have_width)
704         result = group->requisition.width;
705       else if (mode == GTK_SIZE_GROUP_VERTICAL && group->have_height)
706         result = group->requisition.height;
707     }
708
709   g_slist_free (widgets);
710   g_slist_free (groups);
711
712   return result;
713 }
714
715 static void
716 get_fast_child_requisition (GtkWidget      *widget,
717                             GtkRequisition *requisition)
718 {
719   GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (widget, FALSE);
720   
721   *requisition = widget->requisition;
722   
723   if (aux_info)
724     {
725       if (aux_info->width > 0)
726         requisition->width = aux_info->width;
727       if (aux_info && aux_info->height > 0)
728         requisition->height = aux_info->height;
729     }
730 }
731
732 /**
733  * _gtk_size_group_get_child_requisition:
734  * @widget: a #GtkWidget
735  * @requisition: location to store computed requisition.
736  * 
737  * Retrieve the "child requisition" of the widget, taking account grouping
738  * of the widget's requisition with other widgets.
739  **/
740 void
741 _gtk_size_group_get_child_requisition (GtkWidget      *widget,
742                                        GtkRequisition *requisition)
743 {
744   initialize_size_group_quarks ();
745
746   if (requisition)
747     {
748       if (get_size_groups (widget))
749         {
750           requisition->width = get_dimension (widget, GTK_SIZE_GROUP_HORIZONTAL);
751           requisition->height = get_dimension (widget, GTK_SIZE_GROUP_VERTICAL);
752
753           /* Only do the full computation if we actually have size groups */
754         }
755       else
756         get_fast_child_requisition (widget, requisition);
757     }
758 }
759
760 /**
761  * _gtk_size_group_compute_requisition:
762  * @widget: a #GtkWidget
763  * @requisition: location to store computed requisition.
764  * 
765  * Compute the requisition of a widget taking into account grouping of
766  * the widget's requisition with other widgets.
767  **/
768 void
769 _gtk_size_group_compute_requisition (GtkWidget      *widget,
770                                      GtkRequisition *requisition)
771 {
772   gint width;
773   gint height;
774
775   initialize_size_group_quarks ();
776
777   if (get_size_groups (widget))
778     {
779       /* Only do the full computation if we actually have size groups */
780       
781       width = compute_dimension (widget, GTK_SIZE_GROUP_HORIZONTAL);
782       height = compute_dimension (widget, GTK_SIZE_GROUP_VERTICAL);
783
784       if (requisition)
785         {
786           requisition->width = width;
787           requisition->height = height;
788         }
789     }
790   else
791     {
792       do_size_request (widget);
793       
794       if (requisition)
795         get_fast_child_requisition (widget, requisition);
796     }
797 }
798
799 /**
800  * _gtk_size_group_queue_resize:
801  * @widget: a #GtkWidget
802  * 
803  * Queue a resize on a widget, and on all other widgets grouped with this widget.
804  **/
805 void
806 _gtk_size_group_queue_resize (GtkWidget *widget)
807 {
808   initialize_size_group_quarks ();
809
810   queue_resize_on_widget (widget, TRUE);
811 }
812
813 #define __GTK_SIZE_GROUP_C__
814 #include "gtkaliasdef.c"