Bug Summary

File:ctk/ctkmenubar.c
Warning:line 553, column 49
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ctkmenubar.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/ctk -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I .. -D G_LOG_DOMAIN="Ctk" -D G_LOG_USE_STRUCTURED=1 -D CTK_VERSION="3.25.5" -D CTK_BINARY_VERSION="3.0.0" -D CTK_COMPILATION -D CTK_PRINT_BACKEND_ENABLE_UNSUPPORTED -D CTK_LIBDIR="/usr/lib" -D CTK_LOCALEDIR="/usr/share/locale" -D CTK_DATADIR="/usr/share" -D CTK_DATA_PREFIX="/usr" -D CTK_SYSCONFDIR="/usr/etc" -D CTK_HOST="x86_64-pc-linux-gnu" -D CTK_PRINT_BACKENDS="file,cups" -D X11_DATA_PREFIX="/usr" -D ISO_CODES_PREFIX="" -I .. -I ../ctk -I .. -I ../cdk -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -D G_ENABLE_DEBUG -D G_ENABLE_CONSISTENCY_CHECKS -D GLIB_MIN_REQUIRED_VERSION=GLIB_VERSION_2_66 -D GLIB_MAX_ALLOWED_VERSION=GLIB_VERSION_2_66 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/atk-1.0 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/gio-unix-2.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/pango-1.0 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -D PIC -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/ctk -ferror-limit 19 -fvisibility=hidden -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2024-09-19-172619-43637-1 -x c ctkmenubar.c
1/* CTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/*
19 * Modified by the CTK+ Team and others 1997-2000. See the AUTHORS
20 * file for a list of people on the CTK+ Team. See the ChangeLog
21 * files for a list of changes. These files are distributed with
22 * CTK+ at ftp://ftp.ctk.org/pub/ctk/.
23 */
24
25/**
26 * SECTION:ctkmenubar
27 * @Title: CtkMenuBar
28 * @Short_description: A subclass of CtkMenuShell which holds CtkMenuItem widgets
29 * @See_also: #CtkMenuShell, #CtkMenu, #CtkMenuItem
30 *
31 * The #CtkMenuBar is a subclass of #CtkMenuShell which contains one or
32 * more #CtkMenuItems. The result is a standard menu bar which can hold
33 * many menu items.
34 *
35 * # CSS nodes
36 *
37 * CtkMenuBar has a single CSS node with name menubar.
38 */
39
40#include "config.h"
41
42#include "ctkmenubar.h"
43
44#include "ctkbindings.h"
45#include "ctkcsscustomgadgetprivate.h"
46#include "ctkmain.h"
47#include "ctkmarshalers.h"
48#include "ctkmenuitemprivate.h"
49#include "ctkmenuprivate.h"
50#include "ctkmenushellprivate.h"
51#include "ctkrender.h"
52#include "ctksettings.h"
53#include "ctksizerequest.h"
54#include "ctkwindow.h"
55#include "ctkcontainerprivate.h"
56#include "ctkintl.h"
57#include "ctkprivate.h"
58#include "ctktypebuiltins.h"
59#include "ctkwidgetprivate.h"
60
61#define MENU_BAR_POPUP_DELAY0 0
62
63/* Properties */
64enum {
65 PROP_0,
66 PROP_PACK_DIRECTION,
67 PROP_CHILD_PACK_DIRECTION
68};
69
70struct _CtkMenuBarPrivate
71{
72 CtkPackDirection pack_direction;
73 CtkPackDirection child_pack_direction;
74
75 CtkCssGadget *gadget;
76};
77
78
79static void ctk_menu_bar_set_property (GObject *object,
80 guint prop_id,
81 const GValue *value,
82 GParamSpec *pspec);
83static void ctk_menu_bar_get_property (GObject *object,
84 guint prop_id,
85 GValue *value,
86 GParamSpec *pspec);
87static void ctk_menu_bar_finalize (GObject *object);
88static void ctk_menu_bar_get_preferred_width (CtkWidget *widget,
89 gint *minimum,
90 gint *natural);
91static void ctk_menu_bar_get_preferred_height (CtkWidget *widget,
92 gint *minimum,
93 gint *natural);
94static void ctk_menu_bar_get_preferred_width_for_height (CtkWidget *widget,
95 gint height,
96 gint *minimum,
97 gint *natural);
98static void ctk_menu_bar_get_preferred_height_for_width (CtkWidget *widget,
99 gint width,
100 gint *minimum,
101 gint *natural);
102static void ctk_menu_bar_size_allocate (CtkWidget *widget,
103 CtkAllocation *allocation);
104static gint ctk_menu_bar_draw (CtkWidget *widget,
105 cairo_t *cr);
106static void ctk_menu_bar_hierarchy_changed (CtkWidget *widget,
107 CtkWidget *old_toplevel);
108static gint ctk_menu_bar_get_popup_delay (CtkMenuShell *menu_shell);
109static void ctk_menu_bar_move_current (CtkMenuShell *menu_shell,
110 CtkMenuDirectionType direction);
111
112static void ctk_menu_bar_measure (CtkCssGadget *gadget,
113 CtkOrientation orientation,
114 int for_size,
115 int *minimum,
116 int *natural,
117 int *minimum_baseline,
118 int *natural_baseline,
119 gpointer data);
120static void ctk_menu_bar_allocate (CtkCssGadget *gadget,
121 const CtkAllocation *allocation,
122 int baseline,
123 CtkAllocation *out_clip,
124 gpointer data);
125static gboolean ctk_menu_bar_render (CtkCssGadget *gadget,
126 cairo_t *cr,
127 int x,
128 int y,
129 int width,
130 int height,
131 gpointer data);
132
133G_DEFINE_TYPE_WITH_PRIVATE (CtkMenuBar, ctk_menu_bar, CTK_TYPE_MENU_SHELL)static void ctk_menu_bar_init (CtkMenuBar *self); static void
ctk_menu_bar_class_init (CtkMenuBarClass *klass); static GType
ctk_menu_bar_get_type_once (void); static gpointer ctk_menu_bar_parent_class
= ((void*)0); static gint CtkMenuBar_private_offset; static void
ctk_menu_bar_class_intern_init (gpointer klass) { ctk_menu_bar_parent_class
= g_type_class_peek_parent (klass); if (CtkMenuBar_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &CtkMenuBar_private_offset
); ctk_menu_bar_class_init ((CtkMenuBarClass*) klass); } __attribute__
((__unused__)) static inline gpointer ctk_menu_bar_get_instance_private
(CtkMenuBar *self) { return (((gpointer) ((guint8*) (self) +
(glong) (CtkMenuBar_private_offset)))); } GType ctk_menu_bar_get_type
(void) { static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= ctk_menu_bar_get_type_once (); (__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id
) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType ctk_menu_bar_get_type_once (void
) { GType g_define_type_id = g_type_register_static_simple ((
ctk_menu_shell_get_type ()), g_intern_static_string ("CtkMenuBar"
), sizeof (CtkMenuBarClass), (GClassInitFunc)(void (*)(void))
ctk_menu_bar_class_intern_init, sizeof (CtkMenuBar), (GInstanceInitFunc
)(void (*)(void)) ctk_menu_bar_init, (GTypeFlags) 0); { {{ CtkMenuBar_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (CtkMenuBarPrivate
)); };} } return g_define_type_id; }
134
135static void
136ctk_menu_bar_class_init (CtkMenuBarClass *class)
137{
138 GObjectClass *gobject_class;
139 CtkWidgetClass *widget_class;
140 CtkMenuShellClass *menu_shell_class;
141 CtkContainerClass *container_class;
142
143 CtkBindingSet *binding_set;
144
145 gobject_class = (GObjectClass*) class;
146 widget_class = (CtkWidgetClass*) class;
147 menu_shell_class = (CtkMenuShellClass*) class;
148 container_class = (CtkContainerClass*) class;
149
150 gobject_class->get_property = ctk_menu_bar_get_property;
151 gobject_class->set_property = ctk_menu_bar_set_property;
152 gobject_class->finalize = ctk_menu_bar_finalize;
153
154 widget_class->get_preferred_width = ctk_menu_bar_get_preferred_width;
155 widget_class->get_preferred_height = ctk_menu_bar_get_preferred_height;
156 widget_class->get_preferred_width_for_height = ctk_menu_bar_get_preferred_width_for_height;
157 widget_class->get_preferred_height_for_width = ctk_menu_bar_get_preferred_height_for_width;
158 widget_class->size_allocate = ctk_menu_bar_size_allocate;
159 widget_class->draw = ctk_menu_bar_draw;
160 widget_class->hierarchy_changed = ctk_menu_bar_hierarchy_changed;
161
162 menu_shell_class->submenu_placement = CTK_TOP_BOTTOM;
163 menu_shell_class->get_popup_delay = ctk_menu_bar_get_popup_delay;
164 menu_shell_class->move_current = ctk_menu_bar_move_current;
165
166 binding_set = ctk_binding_set_by_class (class);
167 ctk_binding_entry_add_signal (binding_set,
168 CDK_KEY_Left0xff51, 0,
169 "move-current", 1,
170 CTK_TYPE_MENU_DIRECTION_TYPE(ctk_menu_direction_type_get_type ()),
171 CTK_MENU_DIR_PREV);
172 ctk_binding_entry_add_signal (binding_set,
173 CDK_KEY_KP_Left0xff96, 0,
174 "move-current", 1,
175 CTK_TYPE_MENU_DIRECTION_TYPE(ctk_menu_direction_type_get_type ()),
176 CTK_MENU_DIR_PREV);
177 ctk_binding_entry_add_signal (binding_set,
178 CDK_KEY_Right0xff53, 0,
179 "move-current", 1,
180 CTK_TYPE_MENU_DIRECTION_TYPE(ctk_menu_direction_type_get_type ()),
181 CTK_MENU_DIR_NEXT);
182 ctk_binding_entry_add_signal (binding_set,
183 CDK_KEY_KP_Right0xff98, 0,
184 "move-current", 1,
185 CTK_TYPE_MENU_DIRECTION_TYPE(ctk_menu_direction_type_get_type ()),
186 CTK_MENU_DIR_NEXT);
187 ctk_binding_entry_add_signal (binding_set,
188 CDK_KEY_Up0xff52, 0,
189 "move-current", 1,
190 CTK_TYPE_MENU_DIRECTION_TYPE(ctk_menu_direction_type_get_type ()),
191 CTK_MENU_DIR_PARENT);
192 ctk_binding_entry_add_signal (binding_set,
193 CDK_KEY_KP_Up0xff97, 0,
194 "move-current", 1,
195 CTK_TYPE_MENU_DIRECTION_TYPE(ctk_menu_direction_type_get_type ()),
196 CTK_MENU_DIR_PARENT);
197 ctk_binding_entry_add_signal (binding_set,
198 CDK_KEY_Down0xff54, 0,
199 "move-current", 1,
200 CTK_TYPE_MENU_DIRECTION_TYPE(ctk_menu_direction_type_get_type ()),
201 CTK_MENU_DIR_CHILD);
202 ctk_binding_entry_add_signal (binding_set,
203 CDK_KEY_KP_Down0xff99, 0,
204 "move-current", 1,
205 CTK_TYPE_MENU_DIRECTION_TYPE(ctk_menu_direction_type_get_type ()),
206 CTK_MENU_DIR_CHILD);
207
208 /**
209 * CtkMenuBar:pack-direction:
210 *
211 * The pack direction of the menubar. It determines how
212 * menuitems are arranged in the menubar.
213 *
214 * Since: 2.8
215 */
216 g_object_class_install_property (gobject_class,
217 PROP_PACK_DIRECTION,
218 g_param_spec_enum ("pack-direction",
219 P_("Pack direction")g_dgettext("ctk30" "-properties","Pack direction"),
220 P_("The pack direction of the menubar")g_dgettext("ctk30" "-properties","The pack direction of the menubar"
)
,
221 CTK_TYPE_PACK_DIRECTION(ctk_pack_direction_get_type ()),
222 CTK_PACK_DIRECTION_LTR,
223 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY));
224
225 /**
226 * CtkMenuBar:child-pack-direction:
227 *
228 * The child pack direction of the menubar. It determines how
229 * the widgets contained in child menuitems are arranged.
230 *
231 * Since: 2.8
232 */
233 g_object_class_install_property (gobject_class,
234 PROP_CHILD_PACK_DIRECTION,
235 g_param_spec_enum ("child-pack-direction",
236 P_("Child Pack direction")g_dgettext("ctk30" "-properties","Child Pack direction"),
237 P_("The child pack direction of the menubar")g_dgettext("ctk30" "-properties","The child pack direction of the menubar"
)
,
238 CTK_TYPE_PACK_DIRECTION(ctk_pack_direction_get_type ()),
239 CTK_PACK_DIRECTION_LTR,
240 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY));
241
242
243 /**
244 * CtkMenuBar:shadow-type:
245 *
246 * The style of the shadow around the menubar.
247 *
248 * Deprecated: 3.20: Use CSS to determine the shadow; the value of
249 * this style property is ignored.
250 */
251 ctk_widget_class_install_style_property (widget_class,
252 g_param_spec_enum ("shadow-type",
253 P_("Shadow type")g_dgettext("ctk30" "-properties","Shadow type"),
254 P_("Style of bevel around the menubar")g_dgettext("ctk30" "-properties","Style of bevel around the menubar"
)
,
255 CTK_TYPE_SHADOW_TYPE(ctk_shadow_type_get_type ()),
256 CTK_SHADOW_OUT,
257 CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_DEPRECATED));
258
259 /**
260 * CtkMenuBar:internal-padding:
261 *
262 * Amount of border space between the menubar shadow and the menu items
263 *
264 * Deprecated: 3.8: use the standard padding CSS property (through objects
265 * like #CtkStyleContext and #CtkCssProvider); the value of this style
266 * property is ignored.
267 */
268 ctk_widget_class_install_style_property (widget_class,
269 g_param_spec_int ("internal-padding",
270 P_("Internal padding")g_dgettext("ctk30" "-properties","Internal padding"),
271 P_("Amount of border space between the menubar shadow and the menu items")g_dgettext("ctk30" "-properties","Amount of border space between the menubar shadow and the menu items"
)
,
272 0,
273 G_MAXINT2147483647,
274 0,
275 CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_DEPRECATED));
276
277 ctk_container_class_handle_border_width (container_class);
278 ctk_widget_class_set_accessible_role (widget_class, ATK_ROLE_MENU_BAR);
279 ctk_widget_class_set_css_name (widget_class, "menubar");
280}
281
282static void
283ctk_menu_bar_init (CtkMenuBar *menu_bar)
284{
285 CtkMenuBarPrivate *priv;
286 CtkWidget *widget;
287 CtkCssNode *widget_node;
288
289 priv = menu_bar->priv = ctk_menu_bar_get_instance_private (menu_bar);
290
291 widget = CTK_WIDGET (menu_bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menu_bar)), ((ctk_widget_get_type ()))))))
;
292 widget_node = ctk_widget_get_css_node (widget);
293 priv->gadget = ctk_css_custom_gadget_new_for_node (widget_node,
294 widget,
295 ctk_menu_bar_measure,
296 ctk_menu_bar_allocate,
297 ctk_menu_bar_render,
298 NULL((void*)0), NULL((void*)0));
299}
300
301/**
302 * ctk_menu_bar_new:
303 *
304 * Creates a new #CtkMenuBar
305 *
306 * Returns: the new menu bar, as a #CtkWidget
307 */
308CtkWidget*
309ctk_menu_bar_new (void)
310{
311 return g_object_new (CTK_TYPE_MENU_BAR(ctk_menu_bar_get_type ()), NULL((void*)0));
312}
313
314static void
315ctk_menu_bar_finalize (GObject *object)
316{
317 CtkMenuBar *menu_bar = CTK_MENU_BAR (object)((((CtkMenuBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((ctk_menu_bar_get_type ()))))))
;
318
319 g_clear_object (&menu_bar->priv->gadget)do { _Static_assert (sizeof *((&menu_bar->priv->gadget
)) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(((&menu_bar->priv->gadget))) _pp = ((&menu_bar
->priv->gadget)); __typeof__ (*((&menu_bar->priv
->gadget))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
320
321 G_OBJECT_CLASS (ctk_menu_bar_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_menu_bar_parent_class)), (((GType) ((20) << (2
))))))))
->finalize (object);
322}
323
324static void
325ctk_menu_bar_set_property (GObject *object,
326 guint prop_id,
327 const GValue *value,
328 GParamSpec *pspec)
329{
330 CtkMenuBar *menubar = CTK_MENU_BAR (object)((((CtkMenuBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((ctk_menu_bar_get_type ()))))))
;
331
332 switch (prop_id)
333 {
334 case PROP_PACK_DIRECTION:
335 ctk_menu_bar_set_pack_direction (menubar, g_value_get_enum (value));
336 break;
337 case PROP_CHILD_PACK_DIRECTION:
338 ctk_menu_bar_set_child_pack_direction (menubar, g_value_get_enum (value));
339 break;
340 default:
341 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "ctkmenubar.c", 341, ("property"), _glib__property_id, _glib__pspec
->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (
_glib__pspec))->g_class))->g_type)))), (g_type_name (((
(((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
342 break;
343 }
344}
345
346static void
347ctk_menu_bar_get_property (GObject *object,
348 guint prop_id,
349 GValue *value,
350 GParamSpec *pspec)
351{
352 CtkMenuBar *menubar = CTK_MENU_BAR (object)((((CtkMenuBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((ctk_menu_bar_get_type ()))))))
;
353
354 switch (prop_id)
355 {
356 case PROP_PACK_DIRECTION:
357 g_value_set_enum (value, ctk_menu_bar_get_pack_direction (menubar));
358 break;
359 case PROP_CHILD_PACK_DIRECTION:
360 g_value_set_enum (value, ctk_menu_bar_get_child_pack_direction (menubar));
361 break;
362 default:
363 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "ctkmenubar.c", 363, ("property"), _glib__property_id, _glib__pspec
->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (
_glib__pspec))->g_class))->g_type)))), (g_type_name (((
(((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
364 break;
365 }
366}
367
368static void
369ctk_menu_bar_measure (CtkCssGadget *gadget,
370 CtkOrientation orientation,
371 int size,
372 int *minimum,
373 int *natural,
374 int *minimum_baseline G_GNUC_UNUSED__attribute__ ((__unused__)),
375 int *natural_baseline G_GNUC_UNUSED__attribute__ ((__unused__)),
376 gpointer data G_GNUC_UNUSED__attribute__ ((__unused__)))
377{
378 CtkWidget *widget = ctk_css_gadget_get_owner (gadget);
379 CtkMenuBar *menu_bar;
380 CtkMenuBarPrivate *priv;
381 CtkMenuShell *menu_shell;
382 CtkWidget *child;
383 GList *children;
384 gboolean use_toggle_size, use_maximize;
385 gint child_minimum, child_natural;
386
387 *minimum = 0;
388 *natural = 0;
389
390 menu_bar = CTK_MENU_BAR (widget)((((CtkMenuBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_menu_bar_get_type ()))))))
;
391 menu_shell = CTK_MENU_SHELL (widget)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_menu_shell_get_type ()))))))
;
392 priv = menu_bar->priv;
393
394 children = menu_shell->priv->children;
395
396 if (priv->child_pack_direction == CTK_PACK_DIRECTION_LTR ||
397 priv->child_pack_direction == CTK_PACK_DIRECTION_RTL)
398 use_toggle_size = (orientation == CTK_ORIENTATION_HORIZONTAL);
399 else
400 use_toggle_size = (orientation == CTK_ORIENTATION_VERTICAL);
401
402 if (priv->pack_direction == CTK_PACK_DIRECTION_LTR ||
403 priv->pack_direction == CTK_PACK_DIRECTION_RTL)
404 use_maximize = (orientation == CTK_ORIENTATION_VERTICAL);
405 else
406 use_maximize = (orientation == CTK_ORIENTATION_HORIZONTAL);
407
408 while (children)
409 {
410 child = children->data;
411 children = children->next;
412
413 if (ctk_widget_get_visible (child))
414 {
415 _ctk_widget_get_preferred_size_for_size (child, orientation, size, &child_minimum, &child_natural, NULL((void*)0), NULL((void*)0));
416
417 if (use_toggle_size)
418 {
419 gint toggle_size;
420
421 ctk_menu_item_toggle_size_request (CTK_MENU_ITEM (child)((((CtkMenuItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((child)), ((ctk_menu_item_get_type ()))))))
,
422 &toggle_size);
423
424 child_minimum += toggle_size;
425 child_natural += toggle_size;
426 }
427
428 if (use_maximize)
429 {
430 *minimum = MAX (*minimum, child_minimum)(((*minimum) > (child_minimum)) ? (*minimum) : (child_minimum
))
;
431 *natural = MAX (*natural, child_natural)(((*natural) > (child_natural)) ? (*natural) : (child_natural
))
;
432 }
433 else
434 {
435 *minimum += child_minimum;
436 *natural += child_natural;
437 }
438 }
439 }
440}
441
442static void
443ctk_menu_bar_get_preferred_width (CtkWidget *widget,
444 gint *minimum,
445 gint *natural)
446{
447 ctk_css_gadget_get_preferred_size (CTK_MENU_BAR (widget)((((CtkMenuBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_menu_bar_get_type ()))))))
->priv->gadget,
448 CTK_ORIENTATION_HORIZONTAL,
449 -1,
450 minimum, natural,
451 NULL((void*)0), NULL((void*)0));
452}
453
454static void
455ctk_menu_bar_get_preferred_height (CtkWidget *widget,
456 gint *minimum,
457 gint *natural)
458{
459 ctk_css_gadget_get_preferred_size (CTK_MENU_BAR (widget)((((CtkMenuBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_menu_bar_get_type ()))))))
->priv->gadget,
460 CTK_ORIENTATION_VERTICAL,
461 -1,
462 minimum, natural,
463 NULL((void*)0), NULL((void*)0));
464}
465
466static void
467ctk_menu_bar_get_preferred_width_for_height (CtkWidget *widget,
468 gint height,
469 gint *minimum,
470 gint *natural)
471{
472 ctk_css_gadget_get_preferred_size (CTK_MENU_BAR (widget)((((CtkMenuBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_menu_bar_get_type ()))))))
->priv->gadget,
473 CTK_ORIENTATION_HORIZONTAL,
474 height,
475 minimum, natural,
476 NULL((void*)0), NULL((void*)0));
477}
478
479static void
480ctk_menu_bar_get_preferred_height_for_width (CtkWidget *widget,
481 gint width,
482 gint *minimum,
483 gint *natural)
484{
485 ctk_css_gadget_get_preferred_size (CTK_MENU_BAR (widget)((((CtkMenuBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_menu_bar_get_type ()))))))
->priv->gadget,
486 CTK_ORIENTATION_VERTICAL,
487 width,
488 minimum, natural,
489 NULL((void*)0), NULL((void*)0));
490}
491
492static void
493ctk_menu_bar_allocate (CtkCssGadget *gadget,
494 const CtkAllocation *allocation,
495 int baseline G_GNUC_UNUSED__attribute__ ((__unused__)),
496 CtkAllocation *out_clip G_GNUC_UNUSED__attribute__ ((__unused__)),
497 gpointer data G_GNUC_UNUSED__attribute__ ((__unused__)))
498{
499 CtkWidget *widget = ctk_css_gadget_get_owner (gadget);
500 CtkMenuBar *menu_bar;
501 CtkMenuShell *menu_shell;
502 CtkMenuBarPrivate *priv;
503 CtkWidget *child;
504 GList *children;
505 CtkAllocation remaining_space;
506 GArray *requested_sizes;
507 gint toggle_size;
508 guint i;
509
510 menu_bar = CTK_MENU_BAR (widget)((((CtkMenuBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_menu_bar_get_type ()))))))
;
511 menu_shell = CTK_MENU_SHELL (widget)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_menu_shell_get_type ()))))))
;
512 priv = menu_bar->priv;
513
514 if (!menu_shell->priv->children)
515 return;
516
517 remaining_space = *allocation;
518 requested_sizes = g_array_new (FALSE(0), FALSE(0), sizeof (CtkRequestedSize));
519
520 if (priv->pack_direction == CTK_PACK_DIRECTION_LTR ||
521 priv->pack_direction == CTK_PACK_DIRECTION_RTL)
522 {
523 int size = remaining_space.width;
524 gboolean ltr = (ctk_widget_get_direction (widget) == CTK_TEXT_DIR_LTR) == (priv->pack_direction == CTK_PACK_DIRECTION_LTR);
525
526 for (children = menu_shell->priv->children; children; children = children->next)
527 {
528 CtkRequestedSize request;
529 child = children->data;
530
531 if (!ctk_widget_get_visible (child))
532 continue;
533
534 request.data = child;
535 ctk_widget_get_preferred_width_for_height (child,
536 remaining_space.height,
537 &request.minimum_size,
538 &request.natural_size);
539 ctk_menu_item_toggle_size_request (CTK_MENU_ITEM (child)((((CtkMenuItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((child)), ((ctk_menu_item_get_type ()))))))
,
540 &toggle_size);
541 request.minimum_size += toggle_size;
542 request.natural_size += toggle_size;
543
544 ctk_menu_item_toggle_size_allocate (CTK_MENU_ITEM (child)((((CtkMenuItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((child)), ((ctk_menu_item_get_type ()))))))
, toggle_size);
545
546 g_array_append_val (requested_sizes, request)g_array_append_vals (requested_sizes, &(request), 1);
547
548 size -= request.minimum_size;
549 }
550
551 size = ctk_distribute_natural_allocation (size,
552 requested_sizes->len,
553 (CtkRequestedSize *) requested_sizes->data);
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
554
555 for (i = 0; i < requested_sizes->len; i++)
556 {
557 CtkAllocation child_allocation = remaining_space;
558 CtkRequestedSize *request = &g_array_index (requested_sizes, CtkRequestedSize, i)(((CtkRequestedSize*) (void *) (requested_sizes)->data) [(
i)])
;
559
560 child_allocation.width = request->minimum_size;
561 remaining_space.width -= request->minimum_size;
562
563 if (i + 1 == requested_sizes->len && CTK_IS_MENU_ITEM (request->data)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(request->data)); GType __t = ((ctk_menu_item_get_type ())
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))
&&
564 CTK_MENU_ITEM (request->data)((((CtkMenuItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((request->data)), ((ctk_menu_item_get_type ()))))))
->priv->right_justify)
565 ltr = !ltr;
566
567 if (ltr)
568 remaining_space.x += request->minimum_size;
569 else
570 child_allocation.x += remaining_space.width;
571
572 ctk_widget_size_allocate (request->data, &child_allocation);
573 }
574 }
575 else
576 {
577 int size = remaining_space.height;
578 gboolean ttb = (priv->pack_direction == CTK_PACK_DIRECTION_TTB);
579
580 for (children = menu_shell->priv->children; children; children = children->next)
581 {
582 CtkRequestedSize request;
583 child = children->data;
584
585 if (!ctk_widget_get_visible (child))
586 continue;
587
588 request.data = child;
589 ctk_widget_get_preferred_height_for_width (child,
590 remaining_space.width,
591 &request.minimum_size,
592 &request.natural_size);
593 ctk_menu_item_toggle_size_request (CTK_MENU_ITEM (child)((((CtkMenuItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((child)), ((ctk_menu_item_get_type ()))))))
,
594 &toggle_size);
595 request.minimum_size += toggle_size;
596 request.natural_size += toggle_size;
597
598 ctk_menu_item_toggle_size_allocate (CTK_MENU_ITEM (child)((((CtkMenuItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((child)), ((ctk_menu_item_get_type ()))))))
, toggle_size);
599
600 g_array_append_val (requested_sizes, request)g_array_append_vals (requested_sizes, &(request), 1);
601
602 size -= request.minimum_size;
603 }
604
605 size = ctk_distribute_natural_allocation (size,
606 requested_sizes->len,
607 (CtkRequestedSize *) requested_sizes->data);
608
609 for (i = 0; i < requested_sizes->len; i++)
610 {
611 CtkAllocation child_allocation = remaining_space;
612 CtkRequestedSize *request = &g_array_index (requested_sizes, CtkRequestedSize, i)(((CtkRequestedSize*) (void *) (requested_sizes)->data) [(
i)])
;
613
614 child_allocation.height = request->minimum_size;
615 remaining_space.height -= request->minimum_size;
616
617 if (i + 1 == requested_sizes->len && CTK_IS_MENU_ITEM (request->data)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(request->data)); GType __t = ((ctk_menu_item_get_type ())
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))
&&
618 CTK_MENU_ITEM (request->data)((((CtkMenuItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((request->data)), ((ctk_menu_item_get_type ()))))))
->priv->right_justify)
619 ttb = !ttb;
620
621 if (ttb)
622 remaining_space.y += request->minimum_size;
623 else
624 child_allocation.y += remaining_space.height;
625
626 ctk_widget_size_allocate (request->data, &child_allocation);
627 }
628 }
629
630 g_array_free (requested_sizes, TRUE(!(0)));
631}
632
633static void
634ctk_menu_bar_size_allocate (CtkWidget *widget,
635 CtkAllocation *allocation)
636{
637 CtkMenuBar *menu_bar;
638 CtkAllocation clip, content_allocation;
639
640 menu_bar = CTK_MENU_BAR (widget)((((CtkMenuBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_menu_bar_get_type ()))))))
;
641 ctk_widget_set_allocation (widget, allocation);
642
643 if (ctk_widget_get_realized (widget))
644 cdk_window_move_resize (ctk_widget_get_window (widget),
645 allocation->x, allocation->y,
646 allocation->width, allocation->height);
647
648 content_allocation = *allocation;
649 content_allocation.x = content_allocation.y = 0;
650 ctk_css_gadget_allocate (menu_bar->priv->gadget,
651 &content_allocation,
652 ctk_widget_get_allocated_baseline (widget),
653 &clip);
654
655 clip.x += allocation->x;
656 clip.y += allocation->y;
657 ctk_widget_set_clip (widget, &clip);
658}
659
660static gboolean
661ctk_menu_bar_render (CtkCssGadget *gadget,
662 cairo_t *cr,
663 int x G_GNUC_UNUSED__attribute__ ((__unused__)),
664 int y G_GNUC_UNUSED__attribute__ ((__unused__)),
665 int width G_GNUC_UNUSED__attribute__ ((__unused__)),
666 int height G_GNUC_UNUSED__attribute__ ((__unused__)),
667 gpointer data G_GNUC_UNUSED__attribute__ ((__unused__)))
668{
669 CtkWidget *widget = ctk_css_gadget_get_owner (gadget);
670
671 CTK_WIDGET_CLASS (ctk_menu_bar_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_menu_bar_parent_class)), ((ctk_widget_get_type ())))
)))
->draw (widget, cr);
672
673 return FALSE(0);
674}
675
676static gboolean
677ctk_menu_bar_draw (CtkWidget *widget,
678 cairo_t *cr)
679{
680 ctk_css_gadget_draw (CTK_MENU_BAR (widget)((((CtkMenuBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_menu_bar_get_type ()))))))
->priv->gadget, cr);
681
682 return FALSE(0);
683}
684
685static GList *
686get_menu_bars (CtkWindow *window)
687{
688 return g_object_get_data (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, "ctk-menu-bar-list");
689}
690
691GList *
692_ctk_menu_bar_get_viewable_menu_bars (CtkWindow *window)
693{
694 GList *menu_bars;
695 GList *viewable_menu_bars = NULL((void*)0);
696
697 for (menu_bars = get_menu_bars (window);
698 menu_bars;
699 menu_bars = menu_bars->next)
700 {
701 CtkWidget *widget = menu_bars->data;
702 gboolean viewable = TRUE(!(0));
703
704 while (widget)
705 {
706 if (!ctk_widget_get_mapped (widget))
707 viewable = FALSE(0);
708
709 widget = ctk_widget_get_parent (widget);
710 }
711
712 if (viewable)
713 viewable_menu_bars = g_list_prepend (viewable_menu_bars, menu_bars->data);
714 }
715
716 return g_list_reverse (viewable_menu_bars);
717}
718
719static void
720set_menu_bars (CtkWindow *window,
721 GList *menubars)
722{
723 g_object_set_data (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, I_("ctk-menu-bar-list")g_intern_static_string ("ctk-menu-bar-list"), menubars);
724}
725
726static void
727add_to_window (CtkWindow *window,
728 CtkMenuBar *menubar)
729{
730 GList *menubars = get_menu_bars (window);
731
732 set_menu_bars (window, g_list_prepend (menubars, menubar));
733}
734
735static void
736remove_from_window (CtkWindow *window,
737 CtkMenuBar *menubar)
738{
739 GList *menubars = get_menu_bars (window);
740
741 menubars = g_list_remove (menubars, menubar);
742 set_menu_bars (window, menubars);
743}
744
745static void
746ctk_menu_bar_hierarchy_changed (CtkWidget *widget,
747 CtkWidget *old_toplevel)
748{
749 CtkWidget *toplevel;
750 CtkMenuBar *menubar;
751
752 menubar = CTK_MENU_BAR (widget)((((CtkMenuBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_menu_bar_get_type ()))))))
;
753
754 toplevel = ctk_widget_get_toplevel (widget);
755
756 if (old_toplevel)
757 remove_from_window (CTK_WINDOW (old_toplevel)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((old_toplevel)), ((ctk_window_get_type ()))))))
, menubar);
758
759 if (ctk_widget_is_toplevel (toplevel))
760 add_to_window (CTK_WINDOW (toplevel)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((toplevel)), ((ctk_window_get_type ()))))))
, menubar);
761}
762
763/**
764 * _ctk_menu_bar_cycle_focus:
765 * @menubar: a #CtkMenuBar
766 * @dir: direction in which to cycle the focus
767 *
768 * Move the focus between menubars in the toplevel.
769 **/
770void
771_ctk_menu_bar_cycle_focus (CtkMenuBar *menubar,
772 CtkDirectionType dir)
773{
774 CtkWidget *toplevel = ctk_widget_get_toplevel (CTK_WIDGET (menubar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menubar)), ((ctk_widget_get_type ()))))))
);
775 CtkMenuItem *to_activate = NULL((void*)0);
776
777 if (ctk_widget_is_toplevel (toplevel))
778 {
779 GList *tmp_menubars = _ctk_menu_bar_get_viewable_menu_bars (CTK_WINDOW (toplevel)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((toplevel)), ((ctk_window_get_type ()))))))
);
780 GList *menubars;
781 GList *current;
782
783 menubars = _ctk_container_focus_sort (CTK_CONTAINER (toplevel)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((toplevel)), ((ctk_container_get_type ()))))))
, tmp_menubars,
784 dir, CTK_WIDGET (menubar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menubar)), ((ctk_widget_get_type ()))))))
);
785 g_list_free (tmp_menubars);
786
787 if (menubars)
788 {
789 current = g_list_find (menubars, menubar);
790
791 if (current && current->next)
792 {
793 CtkMenuShell *new_menushell = CTK_MENU_SHELL (current->next->data)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((current->next->data)), ((ctk_menu_shell_get_type (
)))))))
;
794 if (new_menushell->priv->children)
795 to_activate = new_menushell->priv->children->data;
796 }
797 }
798
799 g_list_free (menubars);
800 }
801
802 ctk_menu_shell_cancel (CTK_MENU_SHELL (menubar)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menubar)), ((ctk_menu_shell_get_type ()))))))
);
803
804 if (to_activate)
805 g_signal_emit_by_name (to_activate, "activate_item");
806}
807
808static gint
809ctk_menu_bar_get_popup_delay (CtkMenuShell *menu_shell G_GNUC_UNUSED__attribute__ ((__unused__)))
810{
811 return MENU_BAR_POPUP_DELAY0;
812}
813
814static void
815ctk_menu_bar_move_current (CtkMenuShell *menu_shell,
816 CtkMenuDirectionType direction)
817{
818 CtkMenuBar *menubar = CTK_MENU_BAR (menu_shell)((((CtkMenuBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menu_shell)), ((ctk_menu_bar_get_type ()))))))
;
819 CtkTextDirection text_dir;
820 CtkPackDirection pack_dir;
821
822 text_dir = ctk_widget_get_direction (CTK_WIDGET (menubar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menubar)), ((ctk_widget_get_type ()))))))
);
823 pack_dir = ctk_menu_bar_get_pack_direction (menubar);
824
825 if (pack_dir == CTK_PACK_DIRECTION_LTR || pack_dir == CTK_PACK_DIRECTION_RTL)
826 {
827 if ((text_dir == CTK_TEXT_DIR_RTL) == (pack_dir == CTK_PACK_DIRECTION_LTR))
828 {
829 switch (direction)
830 {
831 case CTK_MENU_DIR_PREV:
832 direction = CTK_MENU_DIR_NEXT;
833 break;
834 case CTK_MENU_DIR_NEXT:
835 direction = CTK_MENU_DIR_PREV;
836 break;
837 default: ;
838 }
839 }
840 }
841 else
842 {
843 switch (direction)
844 {
845 case CTK_MENU_DIR_PARENT:
846 if ((text_dir == CTK_TEXT_DIR_LTR) == (pack_dir == CTK_PACK_DIRECTION_TTB))
847 direction = CTK_MENU_DIR_PREV;
848 else
849 direction = CTK_MENU_DIR_NEXT;
850 break;
851 case CTK_MENU_DIR_CHILD:
852 if ((text_dir == CTK_TEXT_DIR_LTR) == (pack_dir == CTK_PACK_DIRECTION_TTB))
853 direction = CTK_MENU_DIR_NEXT;
854 else
855 direction = CTK_MENU_DIR_PREV;
856 break;
857 case CTK_MENU_DIR_PREV:
858 if (text_dir == CTK_TEXT_DIR_RTL)
859 direction = CTK_MENU_DIR_CHILD;
860 else
861 direction = CTK_MENU_DIR_PARENT;
862 break;
863 case CTK_MENU_DIR_NEXT:
864 if (text_dir == CTK_TEXT_DIR_RTL)
865 direction = CTK_MENU_DIR_PARENT;
866 else
867 direction = CTK_MENU_DIR_CHILD;
868 break;
869 default: ;
870 }
871 }
872
873 CTK_MENU_SHELL_CLASS (ctk_menu_bar_parent_class)((((CtkMenuShellClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_menu_bar_parent_class)), ((ctk_menu_shell_get_type (
)))))))
->move_current (menu_shell, direction);
874}
875
876/**
877 * ctk_menu_bar_get_pack_direction:
878 * @menubar: a #CtkMenuBar
879 *
880 * Retrieves the current pack direction of the menubar.
881 * See ctk_menu_bar_set_pack_direction().
882 *
883 * Returns: the pack direction
884 *
885 * Since: 2.8
886 */
887CtkPackDirection
888ctk_menu_bar_get_pack_direction (CtkMenuBar *menubar)
889{
890 g_return_val_if_fail (CTK_IS_MENU_BAR (menubar),do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((menubar)); GType __t = ((ctk_menu_bar_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_MENU_BAR (menubar)"); return (CTK_PACK_DIRECTION_LTR
); } } while (0)
891 CTK_PACK_DIRECTION_LTR)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((menubar)); GType __t = ((ctk_menu_bar_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_MENU_BAR (menubar)"); return (CTK_PACK_DIRECTION_LTR
); } } while (0)
;
892
893 return menubar->priv->pack_direction;
894}
895
896/**
897 * ctk_menu_bar_set_pack_direction:
898 * @menubar: a #CtkMenuBar
899 * @pack_dir: a new #CtkPackDirection
900 *
901 * Sets how items should be packed inside a menubar.
902 *
903 * Since: 2.8
904 */
905void
906ctk_menu_bar_set_pack_direction (CtkMenuBar *menubar,
907 CtkPackDirection pack_dir)
908{
909 CtkMenuBarPrivate *priv;
910 GList *l;
911
912 g_return_if_fail (CTK_IS_MENU_BAR (menubar))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((menubar)); GType __t = ((ctk_menu_bar_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_MENU_BAR (menubar)"); return; } } while (0)
;
913
914 priv = menubar->priv;
915
916 if (priv->pack_direction != pack_dir)
917 {
918 priv->pack_direction = pack_dir;
919
920 ctk_widget_queue_resize (CTK_WIDGET (menubar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menubar)), ((ctk_widget_get_type ()))))))
);
921
922 for (l = CTK_MENU_SHELL (menubar)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menubar)), ((ctk_menu_shell_get_type ()))))))
->priv->children; l; l = l->next)
923 ctk_widget_queue_resize (CTK_WIDGET (l->data)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((l->data)), ((ctk_widget_get_type ()))))))
);
924
925 g_object_notify (G_OBJECT (menubar)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menubar)), (((GType) ((20) << (2))))))))
, "pack-direction");
926 }
927}
928
929/**
930 * ctk_menu_bar_get_child_pack_direction:
931 * @menubar: a #CtkMenuBar
932 *
933 * Retrieves the current child pack direction of the menubar.
934 * See ctk_menu_bar_set_child_pack_direction().
935 *
936 * Returns: the child pack direction
937 *
938 * Since: 2.8
939 */
940CtkPackDirection
941ctk_menu_bar_get_child_pack_direction (CtkMenuBar *menubar)
942{
943 g_return_val_if_fail (CTK_IS_MENU_BAR (menubar),do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((menubar)); GType __t = ((ctk_menu_bar_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_MENU_BAR (menubar)"); return (CTK_PACK_DIRECTION_LTR
); } } while (0)
944 CTK_PACK_DIRECTION_LTR)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((menubar)); GType __t = ((ctk_menu_bar_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_MENU_BAR (menubar)"); return (CTK_PACK_DIRECTION_LTR
); } } while (0)
;
945
946 return menubar->priv->child_pack_direction;
947}
948
949/**
950 * ctk_menu_bar_set_child_pack_direction:
951 * @menubar: a #CtkMenuBar
952 * @child_pack_dir: a new #CtkPackDirection
953 *
954 * Sets how widgets should be packed inside the children of a menubar.
955 *
956 * Since: 2.8
957 */
958void
959ctk_menu_bar_set_child_pack_direction (CtkMenuBar *menubar,
960 CtkPackDirection child_pack_dir)
961{
962 CtkMenuBarPrivate *priv;
963 GList *l;
964
965 g_return_if_fail (CTK_IS_MENU_BAR (menubar))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((menubar)); GType __t = ((ctk_menu_bar_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_MENU_BAR (menubar)"); return; } } while (0)
;
966
967 priv = menubar->priv;
968
969 if (priv->child_pack_direction != child_pack_dir)
970 {
971 priv->child_pack_direction = child_pack_dir;
972
973 ctk_widget_queue_resize (CTK_WIDGET (menubar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menubar)), ((ctk_widget_get_type ()))))))
);
974
975 for (l = CTK_MENU_SHELL (menubar)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menubar)), ((ctk_menu_shell_get_type ()))))))
->priv->children; l; l = l->next)
976 ctk_widget_queue_resize (CTK_WIDGET (l->data)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((l->data)), ((ctk_widget_get_type ()))))))
);
977
978 g_object_notify (G_OBJECT (menubar)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menubar)), (((GType) ((20) << (2))))))))
, "child-pack-direction");
979 }
980}
981
982/**
983 * ctk_menu_bar_new_from_model:
984 * @model: a #GMenuModel
985 *
986 * Creates a new #CtkMenuBar and populates it with menu items
987 * and submenus according to @model.
988 *
989 * The created menu items are connected to actions found in the
990 * #CtkApplicationWindow to which the menu bar belongs - typically
991 * by means of being contained within the #CtkApplicationWindows
992 * widget hierarchy.
993 *
994 * Returns: a new #CtkMenuBar
995 *
996 * Since: 3.4
997 */
998CtkWidget *
999ctk_menu_bar_new_from_model (GMenuModel *model)
1000{
1001 CtkWidget *menubar;
1002
1003 g_return_val_if_fail (G_IS_MENU_MODEL (model), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((model)); GType __t = ((g_menu_model_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "G_IS_MENU_MODEL (model)"); return (((void*)0)); } } while
(0)
;
1004
1005 menubar = ctk_menu_bar_new ();
1006 ctk_menu_shell_bind_model (CTK_MENU_SHELL (menubar)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menubar)), ((ctk_menu_shell_get_type ()))))))
, model, NULL((void*)0), FALSE(0));
1007
1008 return menubar;
1009}