Bug Summary

File:ctk/ctkheaderbar.c
Warning:line 842, column 3
Value stored to 'size' is never read

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 ctkheaderbar.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-173409-43638-1 -x c ctkheaderbar.c
1/*
2 * Copyright (c) 2013 Red Hat, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
12 * License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 *
18 */
19
20#include "config.h"
21
22#include "ctkheaderbar.h"
23#include "ctkheaderbarprivate.h"
24#include "ctkintl.h"
25#include "ctkprivate.h"
26#include "ctktypebuiltins.h"
27#include "ctkwidgetprivate.h"
28#include "ctkcssnodeprivate.h"
29#include "ctkcsscustomgadgetprivate.h"
30#include "ctkwindowprivate.h"
31#include "ctkwidgetprivate.h"
32#include "ctkcontainerprivate.h"
33#include "a11y/ctkheaderbaraccessible.h"
34
35#include <string.h>
36
37/**
38 * SECTION:ctkheaderbar
39 * @Short_description: A box with a centered child
40 * @Title: CtkHeaderBar
41 * @See_also: #CtkBox, #CtkActionBar
42 *
43 * CtkHeaderBar is similar to a horizontal #CtkBox. It allows children to
44 * be placed at the start or the end. In addition, it allows a title and
45 * subtitle to be displayed. The title will be centered with respect to
46 * the width of the box, even if the children at either side take up
47 * different amounts of space. The height of the titlebar will be
48 * set to provide sufficient space for the subtitle, even if none is
49 * currently set. If a subtitle is not needed, the space reservation
50 * can be turned off with ctk_header_bar_set_has_subtitle().
51 *
52 * CtkHeaderBar can add typical window frame controls, such as minimize,
53 * maximize and close buttons, or the window icon.
54 *
55 * For these reasons, CtkHeaderBar is the natural choice for use as the custom
56 * titlebar widget of a #CtkWindow (see ctk_window_set_titlebar()), as it gives
57 * features typical of titlebars while allowing the addition of child widgets.
58 */
59
60#define DEFAULT_SPACING6 6
61#define MIN_TITLE_CHARS5 5
62
63struct _CtkHeaderBarPrivate
64{
65 gchar *title;
66 gchar *subtitle;
67 CtkWidget *title_label;
68 CtkWidget *subtitle_label;
69 CtkWidget *label_box;
70 CtkWidget *label_sizing_box;
71 CtkWidget *subtitle_sizing_label;
72 CtkWidget *custom_title;
73 gint spacing;
74 gboolean has_subtitle;
75
76 GList *children;
77
78 gboolean shows_wm_decorations;
79 gchar *decoration_layout;
80 gboolean decoration_layout_set;
81
82 CtkWidget *titlebar_start_box;
83 CtkWidget *titlebar_end_box;
84
85 CtkWidget *titlebar_start_separator;
86 CtkWidget *titlebar_end_separator;
87
88 CtkWidget *titlebar_icon;
89
90 CtkCssGadget *gadget;
91};
92
93typedef struct _Child Child;
94struct _Child
95{
96 CtkWidget *widget;
97 CtkPackType pack_type;
98};
99
100enum {
101 PROP_0,
102 PROP_TITLE,
103 PROP_SUBTITLE,
104 PROP_HAS_SUBTITLE,
105 PROP_CUSTOM_TITLE,
106 PROP_SPACING,
107 PROP_SHOW_CLOSE_BUTTON,
108 PROP_DECORATION_LAYOUT,
109 PROP_DECORATION_LAYOUT_SET,
110 LAST_PROP
111};
112
113enum {
114 CHILD_PROP_0,
115 CHILD_PROP_PACK_TYPE,
116 CHILD_PROP_POSITION
117};
118
119static GParamSpec *header_bar_props[LAST_PROP] = { NULL((void*)0), };
120
121static void ctk_header_bar_buildable_init (CtkBuildableIface *iface);
122
123G_DEFINE_TYPE_WITH_CODE (CtkHeaderBar, ctk_header_bar, CTK_TYPE_CONTAINER,static void ctk_header_bar_init (CtkHeaderBar *self); static void
ctk_header_bar_class_init (CtkHeaderBarClass *klass); static
GType ctk_header_bar_get_type_once (void); static gpointer ctk_header_bar_parent_class
= ((void*)0); static gint CtkHeaderBar_private_offset; static
void ctk_header_bar_class_intern_init (gpointer klass) { ctk_header_bar_parent_class
= g_type_class_peek_parent (klass); if (CtkHeaderBar_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &CtkHeaderBar_private_offset
); ctk_header_bar_class_init ((CtkHeaderBarClass*) klass); } __attribute__
((__unused__)) static inline gpointer ctk_header_bar_get_instance_private
(CtkHeaderBar *self) { return (((gpointer) ((guint8*) (self)
+ (glong) (CtkHeaderBar_private_offset)))); } GType ctk_header_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_header_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_header_bar_get_type_once (void
) { GType g_define_type_id = g_type_register_static_simple ((
ctk_container_get_type ()), g_intern_static_string ("CtkHeaderBar"
), sizeof (CtkHeaderBarClass), (GClassInitFunc)(void (*)(void
)) ctk_header_bar_class_intern_init, sizeof (CtkHeaderBar), (
GInstanceInitFunc)(void (*)(void)) ctk_header_bar_init, (GTypeFlags
) 0); { {{ CtkHeaderBar_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CtkHeaderBarPrivate)); } { const GInterfaceInfo
g_implement_interface_info = { (GInterfaceInitFunc)(void (*)
(void)) ctk_header_bar_buildable_init, ((void*)0), ((void*)0)
}; g_type_add_interface_static (g_define_type_id, (ctk_buildable_get_type
()), &g_implement_interface_info); };} } return g_define_type_id
; }
124 G_ADD_PRIVATE (CtkHeaderBar)static void ctk_header_bar_init (CtkHeaderBar *self); static void
ctk_header_bar_class_init (CtkHeaderBarClass *klass); static
GType ctk_header_bar_get_type_once (void); static gpointer ctk_header_bar_parent_class
= ((void*)0); static gint CtkHeaderBar_private_offset; static
void ctk_header_bar_class_intern_init (gpointer klass) { ctk_header_bar_parent_class
= g_type_class_peek_parent (klass); if (CtkHeaderBar_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &CtkHeaderBar_private_offset
); ctk_header_bar_class_init ((CtkHeaderBarClass*) klass); } __attribute__
((__unused__)) static inline gpointer ctk_header_bar_get_instance_private
(CtkHeaderBar *self) { return (((gpointer) ((guint8*) (self)
+ (glong) (CtkHeaderBar_private_offset)))); } GType ctk_header_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_header_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_header_bar_get_type_once (void
) { GType g_define_type_id = g_type_register_static_simple ((
ctk_container_get_type ()), g_intern_static_string ("CtkHeaderBar"
), sizeof (CtkHeaderBarClass), (GClassInitFunc)(void (*)(void
)) ctk_header_bar_class_intern_init, sizeof (CtkHeaderBar), (
GInstanceInitFunc)(void (*)(void)) ctk_header_bar_init, (GTypeFlags
) 0); { {{ CtkHeaderBar_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CtkHeaderBarPrivate)); } { const GInterfaceInfo
g_implement_interface_info = { (GInterfaceInitFunc)(void (*)
(void)) ctk_header_bar_buildable_init, ((void*)0), ((void*)0)
}; g_type_add_interface_static (g_define_type_id, (ctk_buildable_get_type
()), &g_implement_interface_info); };} } return g_define_type_id
; }
125 G_IMPLEMENT_INTERFACE (CTK_TYPE_BUILDABLE,static void ctk_header_bar_init (CtkHeaderBar *self); static void
ctk_header_bar_class_init (CtkHeaderBarClass *klass); static
GType ctk_header_bar_get_type_once (void); static gpointer ctk_header_bar_parent_class
= ((void*)0); static gint CtkHeaderBar_private_offset; static
void ctk_header_bar_class_intern_init (gpointer klass) { ctk_header_bar_parent_class
= g_type_class_peek_parent (klass); if (CtkHeaderBar_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &CtkHeaderBar_private_offset
); ctk_header_bar_class_init ((CtkHeaderBarClass*) klass); } __attribute__
((__unused__)) static inline gpointer ctk_header_bar_get_instance_private
(CtkHeaderBar *self) { return (((gpointer) ((guint8*) (self)
+ (glong) (CtkHeaderBar_private_offset)))); } GType ctk_header_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_header_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_header_bar_get_type_once (void
) { GType g_define_type_id = g_type_register_static_simple ((
ctk_container_get_type ()), g_intern_static_string ("CtkHeaderBar"
), sizeof (CtkHeaderBarClass), (GClassInitFunc)(void (*)(void
)) ctk_header_bar_class_intern_init, sizeof (CtkHeaderBar), (
GInstanceInitFunc)(void (*)(void)) ctk_header_bar_init, (GTypeFlags
) 0); { {{ CtkHeaderBar_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CtkHeaderBarPrivate)); } { const GInterfaceInfo
g_implement_interface_info = { (GInterfaceInitFunc)(void (*)
(void)) ctk_header_bar_buildable_init, ((void*)0), ((void*)0)
}; g_type_add_interface_static (g_define_type_id, (ctk_buildable_get_type
()), &g_implement_interface_info); };} } return g_define_type_id
; }
126 ctk_header_bar_buildable_init))static void ctk_header_bar_init (CtkHeaderBar *self); static void
ctk_header_bar_class_init (CtkHeaderBarClass *klass); static
GType ctk_header_bar_get_type_once (void); static gpointer ctk_header_bar_parent_class
= ((void*)0); static gint CtkHeaderBar_private_offset; static
void ctk_header_bar_class_intern_init (gpointer klass) { ctk_header_bar_parent_class
= g_type_class_peek_parent (klass); if (CtkHeaderBar_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &CtkHeaderBar_private_offset
); ctk_header_bar_class_init ((CtkHeaderBarClass*) klass); } __attribute__
((__unused__)) static inline gpointer ctk_header_bar_get_instance_private
(CtkHeaderBar *self) { return (((gpointer) ((guint8*) (self)
+ (glong) (CtkHeaderBar_private_offset)))); } GType ctk_header_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_header_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_header_bar_get_type_once (void
) { GType g_define_type_id = g_type_register_static_simple ((
ctk_container_get_type ()), g_intern_static_string ("CtkHeaderBar"
), sizeof (CtkHeaderBarClass), (GClassInitFunc)(void (*)(void
)) ctk_header_bar_class_intern_init, sizeof (CtkHeaderBar), (
GInstanceInitFunc)(void (*)(void)) ctk_header_bar_init, (GTypeFlags
) 0); { {{ CtkHeaderBar_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CtkHeaderBarPrivate)); } { const GInterfaceInfo
g_implement_interface_info = { (GInterfaceInitFunc)(void (*)
(void)) ctk_header_bar_buildable_init, ((void*)0), ((void*)0)
}; g_type_add_interface_static (g_define_type_id, (ctk_buildable_get_type
()), &g_implement_interface_info); };} } return g_define_type_id
; }
;
127
128static void
129init_sizing_box (CtkHeaderBar *bar)
130{
131 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar);
132 CtkWidget *w;
133 CtkStyleContext *context;
134
135 /* We use this box to always request size for the two labels (title
136 * and subtitle) as if they were always visible, but then allocate
137 * the real label box with its actual size, to keep it center-aligned
138 * in case we have only the title.
139 */
140 w = ctk_box_new (CTK_ORIENTATION_VERTICAL, 0);
141 ctk_widget_show (w);
142 priv->label_sizing_box = g_object_ref_sink (w)((__typeof__ (w)) (g_object_ref_sink) (w));
143
144 w = ctk_label_new (NULL((void*)0));
145 ctk_widget_show (w);
146 context = ctk_widget_get_style_context (w);
147 ctk_style_context_add_class (context, CTK_STYLE_CLASS_TITLE"title");
148 ctk_box_pack_start (CTK_BOX (priv->label_sizing_box)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->label_sizing_box)), ((ctk_box_get_type ()))))))
, w, FALSE(0), FALSE(0), 0);
149 ctk_label_set_line_wrap (CTK_LABEL (w)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((w)), ((ctk_label_get_type ()))))))
, FALSE(0));
150 ctk_label_set_single_line_mode (CTK_LABEL (w)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((w)), ((ctk_label_get_type ()))))))
, TRUE(!(0)));
151 ctk_label_set_ellipsize (CTK_LABEL (w)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((w)), ((ctk_label_get_type ()))))))
, PANGO_ELLIPSIZE_END);
152 ctk_label_set_width_chars (CTK_LABEL (w)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((w)), ((ctk_label_get_type ()))))))
, MIN_TITLE_CHARS5);
153
154 w = ctk_label_new (NULL((void*)0));
155 context = ctk_widget_get_style_context (w);
156 ctk_style_context_add_class (context, CTK_STYLE_CLASS_SUBTITLE"subtitle");
157 ctk_box_pack_start (CTK_BOX (priv->label_sizing_box)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->label_sizing_box)), ((ctk_box_get_type ()))))))
, w, FALSE(0), FALSE(0), 0);
158 ctk_label_set_line_wrap (CTK_LABEL (w)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((w)), ((ctk_label_get_type ()))))))
, FALSE(0));
159 ctk_label_set_single_line_mode (CTK_LABEL (w)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((w)), ((ctk_label_get_type ()))))))
, TRUE(!(0)));
160 ctk_label_set_ellipsize (CTK_LABEL (w)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((w)), ((ctk_label_get_type ()))))))
, PANGO_ELLIPSIZE_END);
161 ctk_widget_set_visible (w, priv->has_subtitle || (priv->subtitle && priv->subtitle[0]));
162 priv->subtitle_sizing_label = w;
163}
164
165static CtkWidget *
166create_title_box (const char *title,
167 const char *subtitle,
168 CtkWidget **ret_title_label,
169 CtkWidget **ret_subtitle_label)
170{
171 CtkWidget *label_box;
172 CtkWidget *title_label;
173 CtkWidget *subtitle_label;
174 CtkStyleContext *context;
175
176 label_box = ctk_box_new (CTK_ORIENTATION_VERTICAL, 0);
177 ctk_widget_set_valign (label_box, CTK_ALIGN_CENTER);
178 ctk_widget_show (label_box);
179
180 title_label = ctk_label_new (title);
181 context = ctk_widget_get_style_context (title_label);
182 ctk_style_context_add_class (context, CTK_STYLE_CLASS_TITLE"title");
183 ctk_label_set_line_wrap (CTK_LABEL (title_label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((title_label)), ((ctk_label_get_type ()))))))
, FALSE(0));
184 ctk_label_set_single_line_mode (CTK_LABEL (title_label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((title_label)), ((ctk_label_get_type ()))))))
, TRUE(!(0)));
185 ctk_label_set_ellipsize (CTK_LABEL (title_label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((title_label)), ((ctk_label_get_type ()))))))
, PANGO_ELLIPSIZE_END);
186 ctk_box_pack_start (CTK_BOX (label_box)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((label_box)), ((ctk_box_get_type ()))))))
, title_label, FALSE(0), FALSE(0), 0);
187 ctk_widget_show (title_label);
188 ctk_label_set_width_chars (CTK_LABEL (title_label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((title_label)), ((ctk_label_get_type ()))))))
, MIN_TITLE_CHARS5);
189
190 subtitle_label = ctk_label_new (subtitle);
191 context = ctk_widget_get_style_context (subtitle_label);
192 ctk_style_context_add_class (context, CTK_STYLE_CLASS_SUBTITLE"subtitle");
193 ctk_label_set_line_wrap (CTK_LABEL (subtitle_label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((subtitle_label)), ((ctk_label_get_type ()))))))
, FALSE(0));
194 ctk_label_set_single_line_mode (CTK_LABEL (subtitle_label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((subtitle_label)), ((ctk_label_get_type ()))))))
, TRUE(!(0)));
195 ctk_label_set_ellipsize (CTK_LABEL (subtitle_label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((subtitle_label)), ((ctk_label_get_type ()))))))
, PANGO_ELLIPSIZE_END);
196 ctk_box_pack_start (CTK_BOX (label_box)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((label_box)), ((ctk_box_get_type ()))))))
, subtitle_label, FALSE(0), FALSE(0), 0);
197 ctk_widget_set_no_show_all (subtitle_label, TRUE(!(0)));
198 ctk_widget_set_visible (subtitle_label, subtitle && subtitle[0]);
199
200 if (ret_title_label)
201 *ret_title_label = title_label;
202 if (ret_subtitle_label)
203 *ret_subtitle_label = subtitle_label;
204
205 return label_box;
206}
207
208gboolean
209_ctk_header_bar_update_window_icon (CtkHeaderBar *bar,
210 CtkWindow *window)
211{
212 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar);
213 GdkPixbuf *pixbuf;
214 gint scale;
215
216 if (priv->titlebar_icon == NULL((void*)0))
217 return FALSE(0);
218
219 scale = ctk_widget_get_scale_factor (priv->titlebar_icon);
220 if (CTK_IS_BUTTON (ctk_widget_get_parent (priv->titlebar_icon))(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(ctk_widget_get_parent (priv->titlebar_icon))); GType __t =
((ctk_button_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; }))))
)
221 pixbuf = ctk_window_get_icon_for_size (window, scale * 16);
222 else
223 pixbuf = ctk_window_get_icon_for_size (window, scale * 20);
224
225 if (pixbuf)
226 {
227 cairo_surface_t *surface;
228
229 surface = cdk_cairo_surface_create_from_pixbuf (pixbuf, scale, ctk_widget_get_window (priv->titlebar_icon));
230
231 ctk_image_set_from_surface (CTK_IMAGE (priv->titlebar_icon)((((CtkImage*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->titlebar_icon)), ((ctk_image_get_type ()))))))
, surface);
232 cairo_surface_destroy (surface);
233 g_object_unref (pixbuf);
234 ctk_widget_show (priv->titlebar_icon);
235
236 return TRUE(!(0));
237 }
238
239 return FALSE(0);
240}
241
242static void
243_ctk_header_bar_update_separator_visibility (CtkHeaderBar *bar)
244{
245 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar);
246 gboolean have_visible_at_start = FALSE(0);
247 gboolean have_visible_at_end = FALSE(0);
248 GList *l;
249
250 for (l = priv->children; l != NULL((void*)0); l = l->next)
251 {
252 Child *child = l->data;
253
254 if (ctk_widget_get_visible (child->widget))
255 {
256 if (child->pack_type == CTK_PACK_START)
257 have_visible_at_start = TRUE(!(0));
258 else
259 have_visible_at_end = TRUE(!(0));
260 }
261 }
262
263 if (priv->titlebar_start_separator != NULL((void*)0))
264 ctk_widget_set_visible (priv->titlebar_start_separator, have_visible_at_start);
265
266 if (priv->titlebar_end_separator != NULL((void*)0))
267 ctk_widget_set_visible (priv->titlebar_end_separator, have_visible_at_end);
268}
269
270void
271_ctk_header_bar_update_window_buttons (CtkHeaderBar *bar)
272{
273 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar);
274 CtkWidget *widget = CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((bar)), ((ctk_widget_get_type ()))))))
, *toplevel;
275 CtkWindow *window;
276 CtkTextDirection direction;
277 gchar *layout_desc;
278 gchar **tokens, **t;
279 gint i, j;
280 GMenuModel *menu;
281 gboolean shown_by_shell;
282 gboolean is_sovereign_window;
283
284 toplevel = ctk_widget_get_toplevel (widget);
285 if (!ctk_widget_is_toplevel (toplevel))
286 return;
287
288 if (priv->titlebar_start_box)
289 {
290 ctk_widget_unparent (priv->titlebar_start_box);
291 priv->titlebar_start_box = NULL((void*)0);
292 priv->titlebar_start_separator = NULL((void*)0);
293 }
294 if (priv->titlebar_end_box)
295 {
296 ctk_widget_unparent (priv->titlebar_end_box);
297 priv->titlebar_end_box = NULL((void*)0);
298 priv->titlebar_end_separator = NULL((void*)0);
299 }
300
301 priv->titlebar_icon = NULL((void*)0);
302
303 if (!priv->shows_wm_decorations)
304 return;
305
306 direction = ctk_widget_get_direction (widget);
307
308 g_object_get (ctk_widget_get_settings (widget),
309 "ctk-shell-shows-app-menu", &shown_by_shell,
310 "ctk-decoration-layout", &layout_desc,
311 NULL((void*)0));
312
313 if (priv->decoration_layout_set)
314 {
315 g_free (layout_desc);
316 layout_desc = g_strdup (priv->decoration_layout)g_strdup_inline (priv->decoration_layout);
317 }
318
319 window = CTK_WINDOW (toplevel)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((toplevel)), ((ctk_window_get_type ()))))))
;
320
321 if (!shown_by_shell && ctk_window_get_application (window))
322 menu = ctk_application_get_app_menu (ctk_window_get_application (window));
323 else
324 menu = NULL((void*)0);
325
326 is_sovereign_window = (!ctk_window_get_modal (window) &&
327 ctk_window_get_transient_for (window) == NULL((void*)0) &&
328 ctk_window_get_type_hint (window) == CDK_WINDOW_TYPE_HINT_NORMAL);
329
330 tokens = g_strsplit (layout_desc, ":", 2);
331 if (tokens)
332 {
333 for (i = 0; i < 2; i++)
334 {
335 CtkWidget *box;
336 CtkWidget *separator;
337 int n_children = 0;
338
339 if (tokens[i] == NULL((void*)0))
340 break;
341
342 t = g_strsplit (tokens[i], ",", -1);
343
344 separator = ctk_separator_new (CTK_ORIENTATION_VERTICAL);
345 ctk_widget_set_no_show_all (separator, TRUE(!(0)));
346 ctk_style_context_add_class (ctk_widget_get_style_context (separator), "titlebutton");
347
348 box = ctk_box_new (CTK_ORIENTATION_HORIZONTAL, priv->spacing);
349
350 for (j = 0; t[j]; j++)
351 {
352 CtkWidget *button = NULL((void*)0);
353 CtkWidget *image = NULL((void*)0);
354 AtkObject *accessible;
355
356 if (strcmp (t[j], "icon") == 0 &&
357 is_sovereign_window)
358 {
359 button = ctk_image_new ();
360 ctk_widget_set_valign (button, CTK_ALIGN_CENTER);
361 priv->titlebar_icon = button;
362 ctk_style_context_add_class (ctk_widget_get_style_context (button), "titlebutton");
363 ctk_style_context_add_class (ctk_widget_get_style_context (button), "icon");
364 ctk_widget_set_size_request (button, 20, 20);
365 ctk_widget_show (button);
366
367 if (!_ctk_header_bar_update_window_icon (bar, window))
368 {
369 ctk_widget_destroy (button);
370 priv->titlebar_icon = NULL((void*)0);
371 button = NULL((void*)0);
372 }
373 }
374 else if (strcmp (t[j], "menu") == 0 &&
375 menu != NULL((void*)0) &&
376 is_sovereign_window)
377 {
378 button = ctk_menu_button_new ();
379 ctk_widget_set_valign (button, CTK_ALIGN_CENTER);
380 ctk_menu_button_set_menu_model (CTK_MENU_BUTTON (button)((((CtkMenuButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((button)), ((ctk_menu_button_get_type ()))))))
, menu);
381 ctk_menu_button_set_use_popover (CTK_MENU_BUTTON (button)((((CtkMenuButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((button)), ((ctk_menu_button_get_type ()))))))
, TRUE(!(0)));
382 ctk_style_context_add_class (ctk_widget_get_style_context (button), "titlebutton");
383 ctk_style_context_add_class (ctk_widget_get_style_context (button), "appmenu");
384 image = ctk_image_new ();
385 ctk_container_add (CTK_CONTAINER (button)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((button)), ((ctk_container_get_type ()))))))
, image);
386 ctk_widget_set_can_focus (button, FALSE(0));
387 ctk_widget_show_all (button);
388
389 accessible = ctk_widget_get_accessible (button);
390 if (CTK_IS_ACCESSIBLE (accessible)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(accessible)); GType __t = ((ctk_accessible_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; }))))
)
391 atk_object_set_name (accessible, _("Application menu")((char *) g_dgettext ("ctk30", "Application menu")));
392
393 priv->titlebar_icon = image;
394 if (!_ctk_header_bar_update_window_icon (bar, window))
395 ctk_image_set_from_icon_name (CTK_IMAGE (priv->titlebar_icon)((((CtkImage*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->titlebar_icon)), ((ctk_image_get_type ()))))))
,
396 "application-x-executable-symbolic", CTK_ICON_SIZE_MENU);
397 }
398 else if (strcmp (t[j], "minimize") == 0 &&
399 is_sovereign_window)
400 {
401 button = ctk_button_new ();
402 ctk_widget_set_valign (button, CTK_ALIGN_CENTER);
403 ctk_style_context_add_class (ctk_widget_get_style_context (button), "titlebutton");
404 ctk_style_context_add_class (ctk_widget_get_style_context (button), "minimize");
405 image = ctk_image_new_from_icon_name ("window-minimize-symbolic", CTK_ICON_SIZE_MENU);
406 g_object_set (image, "use-fallback", TRUE(!(0)), NULL((void*)0));
407 ctk_container_add (CTK_CONTAINER (button)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((button)), ((ctk_container_get_type ()))))))
, image);
408 ctk_widget_set_can_focus (button, FALSE(0));
409 ctk_widget_show_all (button);
410 g_signal_connect_swapped (button, "clicked",g_signal_connect_data ((button), ("clicked"), (((GCallback) (
ctk_window_iconify))), (window), ((void*)0), G_CONNECT_SWAPPED
)
411 G_CALLBACK (ctk_window_iconify), window)g_signal_connect_data ((button), ("clicked"), (((GCallback) (
ctk_window_iconify))), (window), ((void*)0), G_CONNECT_SWAPPED
)
;
412
413 accessible = ctk_widget_get_accessible (button);
414 if (CTK_IS_ACCESSIBLE (accessible)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(accessible)); GType __t = ((ctk_accessible_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; }))))
)
415 atk_object_set_name (accessible, _("Minimize")((char *) g_dgettext ("ctk30", "Minimize")));
416 }
417 else if (strcmp (t[j], "maximize") == 0 &&
418 ctk_window_get_resizable (window) &&
419 is_sovereign_window)
420 {
421 const gchar *icon_name;
422 gboolean maximized = ctk_window_is_maximized (window);
423
424 icon_name = maximized ? "window-restore-symbolic" : "window-maximize-symbolic";
425 button = ctk_button_new ();
426 ctk_widget_set_valign (button, CTK_ALIGN_CENTER);
427 ctk_style_context_add_class (ctk_widget_get_style_context (button), "titlebutton");
428 ctk_style_context_add_class (ctk_widget_get_style_context (button), "maximize");
429 image = ctk_image_new_from_icon_name (icon_name, CTK_ICON_SIZE_MENU);
430 g_object_set (image, "use-fallback", TRUE(!(0)), NULL((void*)0));
431 ctk_container_add (CTK_CONTAINER (button)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((button)), ((ctk_container_get_type ()))))))
, image);
432 ctk_widget_set_can_focus (button, FALSE(0));
433 ctk_widget_show_all (button);
434 g_signal_connect_swapped (button, "clicked",g_signal_connect_data ((button), ("clicked"), (((GCallback) (
_ctk_window_toggle_maximized))), (window), ((void*)0), G_CONNECT_SWAPPED
)
435 G_CALLBACK (_ctk_window_toggle_maximized), window)g_signal_connect_data ((button), ("clicked"), (((GCallback) (
_ctk_window_toggle_maximized))), (window), ((void*)0), G_CONNECT_SWAPPED
)
;
436
437 accessible = ctk_widget_get_accessible (button);
438 if (CTK_IS_ACCESSIBLE (accessible)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(accessible)); GType __t = ((ctk_accessible_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; }))))
)
439 atk_object_set_name (accessible, maximized ? _("Restore")((char *) g_dgettext ("ctk30", "Restore")) : _("Maximize")((char *) g_dgettext ("ctk30", "Maximize")));
440 }
441 else if (strcmp (t[j], "close") == 0 &&
442 ctk_window_get_deletable (window))
443 {
444 button = ctk_button_new ();
445 ctk_widget_set_valign (button, CTK_ALIGN_CENTER);
446 image = ctk_image_new_from_icon_name ("window-close-symbolic", CTK_ICON_SIZE_MENU);
447 ctk_style_context_add_class (ctk_widget_get_style_context (button), "titlebutton");
448 ctk_style_context_add_class (ctk_widget_get_style_context (button), "close");
449 g_object_set (image, "use-fallback", TRUE(!(0)), NULL((void*)0));
450 ctk_container_add (CTK_CONTAINER (button)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((button)), ((ctk_container_get_type ()))))))
, image);
451 ctk_widget_set_can_focus (button, FALSE(0));
452 ctk_widget_show_all (button);
453 g_signal_connect_swapped (button, "clicked",g_signal_connect_data ((button), ("clicked"), (((GCallback) (
ctk_window_close))), (window), ((void*)0), G_CONNECT_SWAPPED)
454 G_CALLBACK (ctk_window_close), window)g_signal_connect_data ((button), ("clicked"), (((GCallback) (
ctk_window_close))), (window), ((void*)0), G_CONNECT_SWAPPED)
;
455
456 accessible = ctk_widget_get_accessible (button);
457 if (CTK_IS_ACCESSIBLE (accessible)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(accessible)); GType __t = ((ctk_accessible_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; }))))
)
458 atk_object_set_name (accessible, _("Close")((char *) g_dgettext ("ctk30", "Close")));
459 }
460
461 if (button)
462 {
463 ctk_box_pack_start (CTK_BOX (box)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((box)), ((ctk_box_get_type ()))))))
, button, FALSE(0), FALSE(0), 0);
464 n_children ++;
465 }
466 }
467 g_strfreev (t);
468
469 if (n_children == 0)
470 {
471 g_object_ref_sink (box)((__typeof__ (box)) (g_object_ref_sink) (box));
472 g_object_unref (box);
473 g_object_ref_sink (separator)((__typeof__ (separator)) (g_object_ref_sink) (separator));
474 g_object_unref (separator);
475 continue;
476 }
477
478 ctk_box_pack_start (CTK_BOX (box)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((box)), ((ctk_box_get_type ()))))))
, separator, FALSE(0), FALSE(0), 0);
479 if (i == 1)
480 ctk_box_reorder_child (CTK_BOX (box)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((box)), ((ctk_box_get_type ()))))))
, separator, 0);
481
482 if ((direction == CTK_TEXT_DIR_LTR && i == 0) ||
483 (direction == CTK_TEXT_DIR_RTL && i == 1))
484 {
485 ctk_style_context_add_class (ctk_widget_get_style_context (box), CTK_STYLE_CLASS_LEFT"left");
486 ctk_css_node_insert_after (ctk_widget_get_css_node (CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((bar)), ((ctk_widget_get_type ()))))))
),
487 ctk_widget_get_css_node (box),
488 NULL((void*)0));
489 }
490 else
491 {
492 ctk_style_context_add_class (ctk_widget_get_style_context (box), CTK_STYLE_CLASS_RIGHT"right");
493 ctk_css_node_insert_before (ctk_widget_get_css_node (CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((bar)), ((ctk_widget_get_type ()))))))
),
494 ctk_widget_get_css_node (box),
495 NULL((void*)0));
496 }
497
498 ctk_widget_show (box);
499 ctk_widget_set_parent (box, CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((bar)), ((ctk_widget_get_type ()))))))
);
500
501 if (i == 0)
502 {
503 priv->titlebar_start_box = box;
504 priv->titlebar_start_separator = separator;
505 }
506 else
507 {
508 priv->titlebar_end_box = box;
509 priv->titlebar_end_separator = separator;
510 }
511 }
512 g_strfreev (tokens);
513 }
514 g_free (layout_desc);
515
516 _ctk_header_bar_update_separator_visibility (bar);
517}
518
519gboolean
520_ctk_header_bar_shows_app_menu (CtkHeaderBar *bar)
521{
522 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar);
523 CtkWindow *window;
524 gchar *layout_desc;
525 gboolean ret;
526
527 window = CTK_WINDOW (ctk_widget_get_toplevel (CTK_WIDGET (bar)))((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_widget_get_toplevel (((((CtkWidget*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((bar)), ((ctk_widget_get_type ())))))))))
, ((ctk_window_get_type ()))))))
;
528 ctk_widget_style_get (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
,
529 "decoration-button-layout", &layout_desc,
530 NULL((void*)0));
531
532 ret = priv->shows_wm_decorations &&
533 (layout_desc && strstr (layout_desc, "menu"));
534
535 g_free (layout_desc);
536
537 return ret;
538}
539
540/* As an intended side effect, this function allows @child
541 * to be the title/label box */
542static void
543ctk_header_bar_reorder_css_node (CtkHeaderBar *bar,
544 CtkPackType pack_type,
545 CtkWidget *widget)
546{
547 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar);
548 CtkWidget *previous_widget;
549 GList *l;
550
551 if (pack_type == CTK_PACK_START)
552 previous_widget = priv->titlebar_start_box;
553 else
554 previous_widget = priv->titlebar_end_box;
555
556 for (l = priv->children; l; l = l->next)
557 {
558 Child *iter = l->data;
559
560 if (iter->widget == widget)
561 break;
562
563 if (iter->pack_type == pack_type)
564 previous_widget = iter->widget;
565 }
566
567 if ((pack_type == CTK_PACK_START)
568 ^ (ctk_widget_get_direction (CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((bar)), ((ctk_widget_get_type ()))))))
) == CTK_TEXT_DIR_LTR))
569 ctk_css_node_insert_after (ctk_widget_get_css_node (CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((bar)), ((ctk_widget_get_type ()))))))
),
570 ctk_widget_get_css_node (widget),
571 previous_widget ? ctk_widget_get_css_node (previous_widget) : NULL((void*)0));
572 else
573 ctk_css_node_insert_before (ctk_widget_get_css_node (CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((bar)), ((ctk_widget_get_type ()))))))
),
574 ctk_widget_get_css_node (widget),
575 previous_widget ? ctk_widget_get_css_node (previous_widget) : NULL((void*)0));
576}
577
578static void
579construct_label_box (CtkHeaderBar *bar)
580{
581 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar);
582
583 g_assert (priv->label_box == NULL)do { if (priv->label_box == ((void*)0)) ; else g_assertion_message_expr
("Ctk", "ctkheaderbar.c", 583, ((const char*) (__func__)), "priv->label_box == NULL"
); } while (0)
;
584
585 priv->label_box = create_title_box (priv->title,
586 priv->subtitle,
587 &priv->title_label,
588 &priv->subtitle_label);
589 ctk_header_bar_reorder_css_node (bar, CTK_PACK_START, priv->label_box);
590 ctk_widget_set_parent (priv->label_box, CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((bar)), ((ctk_widget_get_type ()))))))
);
591}
592
593static gint
594count_visible_children (CtkHeaderBar *bar)
595{
596 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar);
597 GList *l;
598 Child *child;
599 gint n;
600
601 n = 0;
602 for (l = priv->children; l; l = l->next)
603 {
604 child = l->data;
605 if (ctk_widget_get_visible (child->widget))
606 n++;
607 }
608
609 return n;
610}
611
612static gboolean
613add_child_size (CtkWidget *child,
614 CtkOrientation orientation,
615 gint *minimum,
616 gint *natural)
617{
618 gint child_minimum, child_natural;
619
620 if (!ctk_widget_get_visible (child))
621 return FALSE(0);
622
623 if (orientation == CTK_ORIENTATION_HORIZONTAL)
624 ctk_widget_get_preferred_width (child, &child_minimum, &child_natural);
625 else
626 ctk_widget_get_preferred_height (child, &child_minimum, &child_natural);
627
628 if (CTK_ORIENTATION_HORIZONTAL == orientation)
629 {
630 *minimum += child_minimum;
631 *natural += child_natural;
632 }
633 else
634 {
635 *minimum = MAX (*minimum, child_minimum)(((*minimum) > (child_minimum)) ? (*minimum) : (child_minimum
))
;
636 *natural = MAX (*natural, child_natural)(((*natural) > (child_natural)) ? (*natural) : (child_natural
))
;
637 }
638
639 return TRUE(!(0));
640}
641
642static void
643ctk_header_bar_get_size (CtkWidget *widget,
644 CtkOrientation orientation,
645 gint *minimum_size,
646 gint *natural_size)
647{
648 CtkHeaderBar *bar = CTK_HEADER_BAR (widget)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_header_bar_get_type ()))))))
;
649 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar);
650 GList *l;
651 gint nvis_children;
652 gint minimum, natural;
653 gint center_min, center_nat;
654
655 minimum = natural = 0;
656 nvis_children = 0;
657
658 for (l = priv->children; l; l = l->next)
659 {
660 Child *child = l->data;
661
662 if (add_child_size (child->widget, orientation, &minimum, &natural))
663 nvis_children += 1;
664 }
665
666 center_min = center_nat = 0;
667 if (priv->label_box != NULL((void*)0))
668 {
669 if (orientation == CTK_ORIENTATION_HORIZONTAL)
670 add_child_size (priv->label_box, orientation, &center_min, &center_nat);
671 else
672 add_child_size (priv->label_sizing_box, orientation, &center_min, &center_nat);
673
674 if (_ctk_widget_get_visible (priv->label_sizing_box))
675 nvis_children += 1;
676 }
677
678 if (priv->custom_title != NULL((void*)0))
679 {
680 if (add_child_size (priv->custom_title, orientation, &center_min, &center_nat))
681 nvis_children += 1;
682 }
683
684 if (priv->titlebar_start_box != NULL((void*)0))
685 {
686 if (add_child_size (priv->titlebar_start_box, orientation, &minimum, &natural))
687 nvis_children += 1;
688 }
689
690 if (priv->titlebar_end_box != NULL((void*)0))
691 {
692 if (add_child_size (priv->titlebar_end_box, orientation, &minimum, &natural))
693 nvis_children += 1;
694 }
695
696 if (orientation == CTK_ORIENTATION_HORIZONTAL)
697 {
698 minimum += center_min;
699 natural += center_nat;
700 }
701 else
702 {
703 minimum = MAX (minimum, center_min)(((minimum) > (center_min)) ? (minimum) : (center_min));
704 natural = MAX (natural, center_nat)(((natural) > (center_nat)) ? (natural) : (center_nat));
705 }
706
707 if (nvis_children > 0 && orientation == CTK_ORIENTATION_HORIZONTAL)
708 {
709 minimum += nvis_children * priv->spacing;
710 natural += nvis_children * priv->spacing;
711 }
712
713 *minimum_size = minimum;
714 *natural_size = natural;
715}
716
717static void
718ctk_header_bar_compute_size_for_orientation (CtkWidget *widget,
719 gint avail_size,
720 gint *minimum_size,
721 gint *natural_size)
722{
723 CtkHeaderBar *bar = CTK_HEADER_BAR (widget)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_header_bar_get_type ()))))))
;
724 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar);
725 GList *children;
726 gint required_size = 0;
727 gint required_natural = 0;
728 gint child_size;
729 gint child_natural;
730 gint nvis_children;
731
732 nvis_children = 0;
733
734 for (children = priv->children; children != NULL((void*)0); children = children->next)
735 {
736 Child *child = children->data;
737
738 if (ctk_widget_get_visible (child->widget))
739 {
740 ctk_widget_get_preferred_width_for_height (child->widget,
741 avail_size, &child_size, &child_natural);
742
743 required_size += child_size;
744 required_natural += child_natural;
745
746 nvis_children += 1;
747 }
748 }
749
750 if (priv->label_box != NULL((void*)0))
751 {
752 ctk_widget_get_preferred_width (priv->label_sizing_box,
753 &child_size, &child_natural);
754 required_size += child_size;
755 required_natural += child_natural;
756 }
757
758 if (priv->custom_title != NULL((void*)0) &&
759 ctk_widget_get_visible (priv->custom_title))
760 {
761 ctk_widget_get_preferred_width (priv->custom_title,
762 &child_size, &child_natural);
763 required_size += child_size;
764 required_natural += child_natural;
765 }
766
767 if (priv->titlebar_start_box != NULL((void*)0))
768 {
769 ctk_widget_get_preferred_width (priv->titlebar_start_box,
770 &child_size, &child_natural);
771 required_size += child_size;
772 required_natural += child_natural;
773 nvis_children += 1;
774 }
775
776 if (priv->titlebar_end_box != NULL((void*)0))
777 {
778 ctk_widget_get_preferred_width (priv->titlebar_end_box,
779 &child_size, &child_natural);
780 required_size += child_size;
781 required_natural += child_natural;
782 nvis_children += 1;
783 }
784
785 if (nvis_children > 0)
786 {
787 required_size += nvis_children * priv->spacing;
788 required_natural += nvis_children * priv->spacing;
789 }
790
791 *minimum_size = required_size;
792 *natural_size = required_natural;
793}
794
795static void
796ctk_header_bar_compute_size_for_opposing_orientation (CtkWidget *widget,
797 gint avail_size,
798 gint *minimum_size,
799 gint *natural_size)
800{
801 CtkHeaderBar *bar = CTK_HEADER_BAR (widget)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_header_bar_get_type ()))))))
;
802 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar);
803 Child *child;
804 GList *children;
805 gint nvis_children;
806 gint computed_minimum = 0;
807 gint computed_natural = 0;
808 CtkRequestedSize *sizes;
809 CtkPackType packing;
810 gint size = 0;
811 gint i;
812 gint child_size;
813 gint child_minimum;
814 gint child_natural;
815 gint center_min, center_nat;
816
817 nvis_children = count_visible_children (bar);
818
819 if (nvis_children <= 0)
820 return;
821
822 sizes = g_newa (CtkRequestedSize, nvis_children)((CtkRequestedSize*) __builtin_alloca (sizeof (CtkRequestedSize
) * (gsize) (nvis_children)))
;
823
824 /* Retrieve desired size for visible children */
825 for (i = 0, children = priv->children; children; children = children->next)
826 {
827 child = children->data;
828
829 if (ctk_widget_get_visible (child->widget))
830 {
831 ctk_widget_get_preferred_width (child->widget,
832 &sizes[i].minimum_size,
833 &sizes[i].natural_size);
834
835 size -= sizes[i].minimum_size;
836 sizes[i].data = child;
837 i += 1;
838 }
839 }
840
841 /* Bring children up to size first */
842 size = ctk_distribute_natural_allocation (MAX (0, avail_size)(((0) > (avail_size)) ? (0) : (avail_size)), nvis_children, sizes);
Value stored to 'size' is never read
843
844 /* Allocate child positions. */
845 for (packing = CTK_PACK_START; packing <= CTK_PACK_END; ++packing)
846 {
847 for (i = 0, children = priv->children; children; children = children->next)
848 {
849 child = children->data;
850
851 /* If widget is not visible, skip it. */
852 if (!ctk_widget_get_visible (child->widget))
853 continue;
854
855 /* If widget is packed differently skip it, but still increment i,
856 * since widget is visible and will be handled in next loop
857 * iteration.
858 */
859 if (child->pack_type != packing)
860 {
861 i++;
862 continue;
863 }
864
865 child_size = sizes[i].minimum_size;
866
867 ctk_widget_get_preferred_height_for_width (child->widget,
868 child_size, &child_minimum, &child_natural);
869
870 computed_minimum = MAX (computed_minimum, child_minimum)(((computed_minimum) > (child_minimum)) ? (computed_minimum
) : (child_minimum))
;
871 computed_natural = MAX (computed_natural, child_natural)(((computed_natural) > (child_natural)) ? (computed_natural
) : (child_natural))
;
872 }
873 i += 1;
874 }
875
876 center_min = center_nat = 0;
877 if (priv->label_box != NULL((void*)0))
878 {
879 ctk_widget_get_preferred_height (priv->label_sizing_box,
880 &center_min, &center_nat);
881 }
882
883 if (priv->custom_title != NULL((void*)0) &&
884 ctk_widget_get_visible (priv->custom_title))
885 {
886 ctk_widget_get_preferred_height (priv->custom_title,
887 &center_min, &center_nat);
888 }
889
890 if (priv->titlebar_start_box != NULL((void*)0))
891 {
892 ctk_widget_get_preferred_height (priv->titlebar_start_box,
893 &child_minimum, &child_natural);
894 computed_minimum = MAX (computed_minimum, child_minimum)(((computed_minimum) > (child_minimum)) ? (computed_minimum
) : (child_minimum))
;
895 computed_natural = MAX (computed_natural, child_natural)(((computed_natural) > (child_natural)) ? (computed_natural
) : (child_natural))
;
896 }
897
898 if (priv->titlebar_end_box != NULL((void*)0))
899 {
900 ctk_widget_get_preferred_height (priv->titlebar_end_box,
901 &child_minimum, &child_natural);
902 computed_minimum = MAX (computed_minimum, child_minimum)(((computed_minimum) > (child_minimum)) ? (computed_minimum
) : (child_minimum))
;
903 computed_natural = MAX (computed_natural, child_natural)(((computed_natural) > (child_natural)) ? (computed_natural
) : (child_natural))
;
904 }
905
906 *minimum_size = computed_minimum;
907 *natural_size = computed_natural;
908}
909
910static void
911ctk_header_bar_get_content_size (CtkCssGadget *gadget,
912 CtkOrientation orientation,
913 gint for_size,
914 gint *minimum,
915 gint *natural,
916 gint *minimum_baseline G_GNUC_UNUSED__attribute__ ((__unused__)),
917 gint *natural_baseline G_GNUC_UNUSED__attribute__ ((__unused__)),
918 gpointer unused G_GNUC_UNUSED__attribute__ ((__unused__)))
919{
920 CtkWidget *widget = ctk_css_gadget_get_owner (gadget);
921
922 if (for_size < 0)
923 ctk_header_bar_get_size (widget, orientation, minimum, natural);
924 else if (orientation == CTK_ORIENTATION_HORIZONTAL)
925 ctk_header_bar_compute_size_for_orientation (widget, for_size, minimum, natural);
926 else
927 ctk_header_bar_compute_size_for_opposing_orientation (widget, for_size, minimum, natural);
928}
929
930static void
931ctk_header_bar_get_preferred_width (CtkWidget *widget,
932 gint *minimum,
933 gint *natural)
934{
935 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (CTK_HEADER_BAR (widget)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_header_bar_get_type ()))))))
);
936
937 ctk_css_gadget_get_preferred_size (priv->gadget,
938 CTK_ORIENTATION_HORIZONTAL,
939 -1,
940 minimum, natural,
941 NULL((void*)0), NULL((void*)0));
942}
943
944static void
945ctk_header_bar_get_preferred_height (CtkWidget *widget,
946 gint *minimum,
947 gint *natural)
948{
949 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (CTK_HEADER_BAR (widget)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_header_bar_get_type ()))))))
);
950
951 ctk_css_gadget_get_preferred_size (priv->gadget,
952 CTK_ORIENTATION_VERTICAL,
953 -1,
954 minimum, natural,
955 NULL((void*)0), NULL((void*)0));
956}
957
958static void
959ctk_header_bar_get_preferred_width_for_height (CtkWidget *widget,
960 gint height,
961 gint *minimum,
962 gint *natural)
963{
964 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (CTK_HEADER_BAR (widget)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_header_bar_get_type ()))))))
);
965
966 ctk_css_gadget_get_preferred_size (priv->gadget,
967 CTK_ORIENTATION_HORIZONTAL,
968 height,
969 minimum, natural,
970 NULL((void*)0), NULL((void*)0));
971}
972
973static void
974ctk_header_bar_get_preferred_height_for_width (CtkWidget *widget,
975 gint width,
976 gint *minimum,
977 gint *natural)
978{
979 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (CTK_HEADER_BAR (widget)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_header_bar_get_type ()))))))
);
980
981 ctk_css_gadget_get_preferred_size (priv->gadget,
982 CTK_ORIENTATION_VERTICAL,
983 width,
984 minimum, natural,
985 NULL((void*)0), NULL((void*)0));
986}
987
988static void
989ctk_header_bar_size_allocate (CtkWidget *widget,
990 CtkAllocation *allocation)
991{
992 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (CTK_HEADER_BAR (widget)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_header_bar_get_type ()))))))
);
993 CtkAllocation clip;
994
995 ctk_widget_set_allocation (widget, allocation);
996
997 ctk_css_gadget_allocate (priv->gadget, allocation, ctk_widget_get_allocated_baseline (widget), &clip);
998
999 ctk_widget_set_clip (widget, &clip);
1000}
1001
1002static void
1003ctk_header_bar_allocate_contents (CtkCssGadget *gadget,
1004 const CtkAllocation *allocation,
1005 int baseline G_GNUC_UNUSED__attribute__ ((__unused__)),
1006 CtkAllocation *out_clip,
1007 gpointer unused G_GNUC_UNUSED__attribute__ ((__unused__)))
1008{
1009 CtkWidget *widget = ctk_css_gadget_get_owner (gadget);
1010 CtkWidget *title_widget;
1011 CtkHeaderBar *bar = CTK_HEADER_BAR (widget)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_header_bar_get_type ()))))))
;
1012 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar);
1013 CtkRequestedSize *sizes;
1014 gint width, height;
1015 gint nvis_children;
1016 gint title_minimum_size;
1017 gint title_natural_size;
1018 gboolean title_expands = FALSE(0);
1019 gint start_width, end_width;
1020 gint uniform_expand_bonus[2] = { 0 };
1021 gint leftover_expand_bonus[2] = { 0 };
1022 gint nexpand_children[2] = { 0 };
1023 gint side[2];
1024 GList *l;
1025 gint i;
1026 Child *child;
1027 CtkPackType packing;
1028 CtkAllocation child_allocation;
1029 gint x;
1030 gint child_size;
1031 CtkTextDirection direction;
1032
1033 direction = ctk_widget_get_direction (widget);
1034 nvis_children = count_visible_children (bar);
1035 sizes = g_newa (CtkRequestedSize, nvis_children)((CtkRequestedSize*) __builtin_alloca (sizeof (CtkRequestedSize
) * (gsize) (nvis_children)))
;
1036
1037 width = allocation->width - nvis_children * priv->spacing;
1038 height = allocation->height;
1039
1040 i = 0;
1041 for (l = priv->children; l; l = l->next)
1042 {
1043 child = l->data;
1044 if (!ctk_widget_get_visible (child->widget))
1045 continue;
1046
1047 if (ctk_widget_compute_expand (child->widget, CTK_ORIENTATION_HORIZONTAL))
1048 nexpand_children[child->pack_type]++;
1049
1050 ctk_widget_get_preferred_width_for_height (child->widget,
1051 height,
1052 &sizes[i].minimum_size,
1053 &sizes[i].natural_size);
1054 width -= sizes[i].minimum_size;
1055 i++;
1056 }
1057
1058 title_minimum_size = 0;
1059 title_natural_size = 0;
1060
1061 if (priv->custom_title != NULL((void*)0) &&
1062 ctk_widget_get_visible (priv->custom_title))
1063 title_widget = priv->custom_title;
1064 else if (priv->label_box != NULL((void*)0))
1065 title_widget = priv->label_box;
1066 else
1067 title_widget = NULL((void*)0);
1068
1069 if (title_widget)
1070 {
1071 ctk_widget_get_preferred_width_for_height (title_widget,
1072 height,
1073 &title_minimum_size,
1074 &title_natural_size);
1075 width -= title_natural_size;
1076
1077 title_expands = ctk_widget_compute_expand (title_widget, CTK_ORIENTATION_HORIZONTAL);
1078 }
1079
1080 start_width = 0;
1081 if (priv->titlebar_start_box != NULL((void*)0))
1082 {
1083 gint min, nat;
1084 ctk_widget_get_preferred_width_for_height (priv->titlebar_start_box,
1085 height,
1086 &min, &nat);
1087 start_width = nat + priv->spacing;
1088 }
1089 width -= start_width;
1090
1091 end_width = 0;
1092 if (priv->titlebar_end_box != NULL((void*)0))
1093 {
1094 gint min, nat;
1095 ctk_widget_get_preferred_width_for_height (priv->titlebar_end_box,
1096 height,
1097 &min, &nat);
1098 end_width = nat + priv->spacing;
1099 }
1100 width -= end_width;
1101
1102 width = ctk_distribute_natural_allocation (MAX (0, width)(((0) > (width)) ? (0) : (width)), nvis_children, sizes);
1103
1104 /* compute the nominal size of the children filling up each side of
1105 * the title in titlebar
1106 */
1107 side[0] = start_width;
1108 side[1] = end_width;
1109 for (packing = CTK_PACK_START; packing <= CTK_PACK_END; packing++)
1110 {
1111 i = 0;
1112 for (l = priv->children; l != NULL((void*)0); l = l->next)
1113 {
1114 child = l->data;
1115 if (!ctk_widget_get_visible (child->widget))
1116 continue;
1117
1118 if (child->pack_type == packing)
1119 side[packing] += sizes[i].minimum_size + priv->spacing;
1120
1121 i++;
1122 }
1123 }
1124
1125 /* figure out how much space is left on each side of the title,
1126 * and earkmark that space for the expanded children.
1127 *
1128 * If the title itself is expanded, then it gets half the spoils
1129 * from each side.
1130 */
1131 for (packing = CTK_PACK_START; packing <= CTK_PACK_END; packing++)
1132 {
1133 gint side_free_space;
1134
1135 side_free_space = allocation->width / 2 - title_natural_size / 2 - side[packing];
1136
1137 if (side_free_space > 0 && nexpand_children[packing] > 0)
1138 {
1139 width -= side_free_space;
1140
1141 if (title_expands)
1142 side_free_space -= side_free_space / 2;
1143
1144 side[packing] += side_free_space;
1145 uniform_expand_bonus[packing] = side_free_space / nexpand_children[packing];
1146 leftover_expand_bonus[packing] = side_free_space % nexpand_children[packing];
1147 }
1148 }
1149
1150 /* allocate the children on both sides of the title */
1151 for (packing = CTK_PACK_START; packing <= CTK_PACK_END; packing++)
1152 {
1153 child_allocation.y = allocation->y;
1154 child_allocation.height = height;
1155 if (packing == CTK_PACK_START)
1156 x = allocation->x + start_width;
1157 else
1158 x = allocation->x + allocation->width - end_width;
1159
1160 i = 0;
1161 for (l = priv->children; l != NULL((void*)0); l = l->next)
1162 {
1163 child = l->data;
1164 if (!ctk_widget_get_visible (child->widget))
1165 continue;
1166
1167 if (child->pack_type != packing)
1168 goto next;
1169
1170 child_size = sizes[i].minimum_size;
1171
1172 /* if this child is expanded, give it extra space from the reserves */
1173 if (ctk_widget_compute_expand (child->widget, CTK_ORIENTATION_HORIZONTAL))
1174 {
1175 gint expand_bonus;
1176
1177 expand_bonus = uniform_expand_bonus[packing];
1178
1179 if (leftover_expand_bonus[packing] > 0)
1180 {
1181 expand_bonus++;
1182 leftover_expand_bonus[packing]--;
1183 }
1184
1185 child_size += expand_bonus;
1186 }
1187
1188 child_allocation.width = child_size;
1189
1190 if (packing == CTK_PACK_START)
1191 {
1192 child_allocation.x = x;
1193 x += child_size;
1194 x += priv->spacing;
1195 }
1196 else
1197 {
1198 x -= child_size;
1199 child_allocation.x = x;
1200 x -= priv->spacing;
1201 }
1202
1203 if (direction == CTK_TEXT_DIR_RTL)
1204 child_allocation.x = allocation->x + allocation->width - (child_allocation.x - allocation->x) - child_allocation.width;
1205
1206 ctk_widget_size_allocate (child->widget, &child_allocation);
1207
1208 next:
1209 i++;
1210 }
1211 }
1212
1213 /* We don't enforce css borders on the center widget, to make
1214 * title/subtitle combinations fit without growing the header
1215 */
1216 child_allocation.y = allocation->y;
1217 child_allocation.height = allocation->height;
1218
1219 child_size = MIN (allocation->width - side[0] - side[1], title_natural_size)(((allocation->width - side[0] - side[1]) < (title_natural_size
)) ? (allocation->width - side[0] - side[1]) : (title_natural_size
))
;
1220
1221 child_allocation.x = allocation->x + (allocation->width - child_size) / 2;
1222 child_allocation.width = child_size;
1223
1224 /* if the title widget is expanded, then grow it by all the available
1225 * free space, and recenter it
1226 */
1227 if (title_expands && width > 0)
1228 {
1229 child_allocation.width += width;
1230 child_allocation.x -= width / 2;
1231 }
1232
1233 if (allocation->x + side[0] > child_allocation.x)
1234 child_allocation.x = allocation->x + side[0];
1235 else if (allocation->x + allocation->width - side[1] < child_allocation.x + child_allocation.width)
1236 child_allocation.x = allocation->x + allocation->width - side[1] - child_allocation.width;
1237
1238 if (direction == CTK_TEXT_DIR_RTL)
1239 child_allocation.x = allocation->x + allocation->width - (child_allocation.x - allocation->x) - child_allocation.width;
1240
1241 if (title_widget != NULL((void*)0))
1242 ctk_widget_size_allocate (title_widget, &child_allocation);
1243
1244 child_allocation.y = allocation->y;
1245 child_allocation.height = height;
1246
1247 if (priv->titlebar_start_box)
1248 {
1249 gboolean left = (direction == CTK_TEXT_DIR_LTR);
1250 if (left)
1251 child_allocation.x = allocation->x;
1252 else
1253 child_allocation.x = allocation->x + allocation->width - start_width + priv->spacing;
1254 child_allocation.width = start_width - priv->spacing;
1255 ctk_widget_size_allocate (priv->titlebar_start_box, &child_allocation);
1256 }
1257
1258 if (priv->titlebar_end_box)
1259 {
1260 gboolean left = (direction != CTK_TEXT_DIR_LTR);
1261 if (left)
1262 child_allocation.x = allocation->x;
1263 else
1264 child_allocation.x = allocation->x + allocation->width - end_width + priv->spacing;
1265 child_allocation.width = end_width - priv->spacing;
1266 ctk_widget_size_allocate (priv->titlebar_end_box, &child_allocation);
1267 }
1268
1269 ctk_container_get_children_clip (CTK_CONTAINER (widget)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_container_get_type ()))))))
, out_clip);
1270}
1271
1272/**
1273 * ctk_header_bar_set_title:
1274 * @bar: a #CtkHeaderBar
1275 * @title: (allow-none): a title, or %NULL
1276 *
1277 * Sets the title of the #CtkHeaderBar. The title should help a user
1278 * identify the current view. A good title should not include the
1279 * application name.
1280 *
1281 * Since: 3.10
1282 */
1283void
1284ctk_header_bar_set_title (CtkHeaderBar *bar,
1285 const gchar *title)
1286{
1287 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar);
1288 gchar *new_title;
1289
1290 g_return_if_fail (CTK_IS_HEADER_BAR (bar))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bar)); GType __t = ((ctk_header_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_HEADER_BAR (bar)"); return; } } while (0)
;
1291
1292 new_title = g_strdup (title)g_strdup_inline (title);
1293 g_free (priv->title);
1294 priv->title = new_title;
1295
1296 if (priv->title_label != NULL((void*)0))
1297 {
1298 ctk_label_set_label (CTK_LABEL (priv->title_label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->title_label)), ((ctk_label_get_type ()))))))
, priv->title);
1299 ctk_widget_queue_resize (CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((bar)), ((ctk_widget_get_type ()))))))
);
1300 }
1301
1302 g_object_notify_by_pspec (G_OBJECT (bar)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((bar)), (((GType) ((20) << (2))))))))
, header_bar_props[PROP_TITLE]);
1303}
1304
1305/**
1306 * ctk_header_bar_get_title:
1307 * @bar: a #CtkHeaderBar
1308 *
1309 * Retrieves the title of the header. See ctk_header_bar_set_title().
1310 *
1311 * Returns: (nullable): the title of the header, or %NULL if none has
1312 * been set explicitly. The returned string is owned by the widget
1313 * and must not be modified or freed.
1314 *
1315 * Since: 3.10
1316 */
1317const gchar *
1318ctk_header_bar_get_title (CtkHeaderBar *bar)
1319{
1320 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar);
1321
1322 g_return_val_if_fail (CTK_IS_HEADER_BAR (bar), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bar)); GType __t = ((ctk_header_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_HEADER_BAR (bar)"); return (((void*)0)); } } while
(0)
;
1323
1324 return priv->title;
1325}
1326
1327/**
1328 * ctk_header_bar_set_subtitle:
1329 * @bar: a #CtkHeaderBar
1330 * @subtitle: (allow-none): a subtitle, or %NULL
1331 *
1332 * Sets the subtitle of the #CtkHeaderBar. The title should give a user
1333 * an additional detail to help him identify the current view.
1334 *
1335 * Note that CtkHeaderBar by default reserves room for the subtitle,
1336 * even if none is currently set. If this is not desired, set the
1337 * #CtkHeaderBar:has-subtitle property to %FALSE.
1338 *
1339 * Since: 3.10
1340 */
1341void
1342ctk_header_bar_set_subtitle (CtkHeaderBar *bar,
1343 const gchar *subtitle)
1344{
1345 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar);
1346 gchar *new_subtitle;
1347
1348 g_return_if_fail (CTK_IS_HEADER_BAR (bar))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bar)); GType __t = ((ctk_header_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_HEADER_BAR (bar)"); return; } } while (0)
;
1349
1350 new_subtitle = g_strdup (subtitle)g_strdup_inline (subtitle);
1351 g_free (priv->subtitle);
1352 priv->subtitle = new_subtitle;
1353
1354 if (priv->subtitle_label != NULL((void*)0))
1355 {
1356 ctk_label_set_label (CTK_LABEL (priv->subtitle_label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->subtitle_label)), ((ctk_label_get_type ()))))))
, priv->subtitle);
1357 ctk_widget_set_visible (priv->subtitle_label, priv->subtitle && priv->subtitle[0]);
1358 ctk_widget_queue_resize (CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((bar)), ((ctk_widget_get_type ()))))))
);
1359 }
1360
1361 ctk_widget_set_visible (priv->subtitle_sizing_label, priv->has_subtitle || (priv->subtitle && priv->subtitle[0]));
1362
1363 g_object_notify_by_pspec (G_OBJECT (bar)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((bar)), (((GType) ((20) << (2))))))))
, header_bar_props[PROP_SUBTITLE]);
1364}
1365
1366/**
1367 * ctk_header_bar_get_subtitle:
1368 * @bar: a #CtkHeaderBar
1369 *
1370 * Retrieves the subtitle of the header. See ctk_header_bar_set_subtitle().
1371 *
1372 * Returns: (nullable): the subtitle of the header, or %NULL if none has
1373 * been set explicitly. The returned string is owned by the widget
1374 * and must not be modified or freed.
1375 *
1376 * Since: 3.10
1377 */
1378const gchar *
1379ctk_header_bar_get_subtitle (CtkHeaderBar *bar)
1380{
1381 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar);
1382
1383 g_return_val_if_fail (CTK_IS_HEADER_BAR (bar), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bar)); GType __t = ((ctk_header_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_HEADER_BAR (bar)"); return (((void*)0)); } } while
(0)
;
1384
1385 return priv->subtitle;
1386}
1387
1388/**
1389 * ctk_header_bar_set_custom_title:
1390 * @bar: a #CtkHeaderBar
1391 * @title_widget: (allow-none): a custom widget to use for a title
1392 *
1393 * Sets a custom title for the #CtkHeaderBar.
1394 *
1395 * The title should help a user identify the current view. This
1396 * supersedes any title set by ctk_header_bar_set_title() or
1397 * ctk_header_bar_set_subtitle(). To achieve the same style as
1398 * the builtin title and subtitle, use the “title” and “subtitle”
1399 * style classes.
1400 *
1401 * You should set the custom title to %NULL, for the header title
1402 * label to be visible again.
1403 *
1404 * Since: 3.10
1405 */
1406void
1407ctk_header_bar_set_custom_title (CtkHeaderBar *bar,
1408 CtkWidget *title_widget)
1409{
1410 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar);
1411
1412 g_return_if_fail (CTK_IS_HEADER_BAR (bar))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bar)); GType __t = ((ctk_header_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_HEADER_BAR (bar)"); return; } } while (0)
;
1413 if (title_widget)
1414 g_return_if_fail (CTK_IS_WIDGET (title_widget))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((title_widget)); GType __t = ((ctk_widget_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_WIDGET (title_widget)"); return; } } while (0)
;
1415
1416 /* No need to do anything if the custom widget stays the same */
1417 if (priv->custom_title == title_widget)
1418 return;
1419
1420 if (priv->custom_title)
1421 {
1422 CtkWidget *custom = priv->custom_title;
1423
1424 priv->custom_title = NULL((void*)0);
1425 ctk_widget_unparent (custom);
1426 }
1427
1428 if (title_widget != NULL((void*)0))
1429 {
1430 priv->custom_title = title_widget;
1431
1432 ctk_header_bar_reorder_css_node (bar, CTK_PACK_START, priv->custom_title);
1433 ctk_widget_set_parent (priv->custom_title, CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((bar)), ((ctk_widget_get_type ()))))))
);
1434 ctk_widget_set_valign (priv->custom_title, CTK_ALIGN_CENTER);
1435
1436 if (priv->label_box != NULL((void*)0))
1437 {
1438 CtkWidget *label_box = priv->label_box;
1439
1440 priv->label_box = NULL((void*)0);
1441 priv->title_label = NULL((void*)0);
1442 priv->subtitle_label = NULL((void*)0);
1443 ctk_widget_unparent (label_box);
1444 }
1445
1446 }
1447 else
1448 {
1449 if (priv->label_box == NULL((void*)0))
1450 construct_label_box (bar);
1451 }
1452
1453 ctk_widget_queue_resize (CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((bar)), ((ctk_widget_get_type ()))))))
);
1454
1455 g_object_notify_by_pspec (G_OBJECT (bar)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((bar)), (((GType) ((20) << (2))))))))
, header_bar_props[PROP_CUSTOM_TITLE]);
1456}
1457
1458/**
1459 * ctk_header_bar_get_custom_title:
1460 * @bar: a #CtkHeaderBar
1461 *
1462 * Retrieves the custom title widget of the header. See
1463 * ctk_header_bar_set_custom_title().
1464 *
1465 * Returns: (nullable) (transfer none): the custom title widget
1466 * of the header, or %NULL if none has been set explicitly.
1467 *
1468 * Since: 3.10
1469 */
1470CtkWidget *
1471ctk_header_bar_get_custom_title (CtkHeaderBar *bar)
1472{
1473 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar);
1474
1475 g_return_val_if_fail (CTK_IS_HEADER_BAR (bar), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bar)); GType __t = ((ctk_header_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_HEADER_BAR (bar)"); return (((void*)0)); } } while
(0)
;
1476
1477 return priv->custom_title;
1478}
1479
1480static void
1481ctk_header_bar_destroy (CtkWidget *widget)
1482{
1483 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (CTK_HEADER_BAR (widget)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_header_bar_get_type ()))))))
);
1484
1485 if (priv->label_sizing_box)
1486 {
1487 ctk_widget_destroy (priv->label_sizing_box);
1488 g_clear_object (&priv->label_sizing_box)do { _Static_assert (sizeof *((&priv->label_sizing_box
)) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(((&priv->label_sizing_box))) _pp = ((&priv->label_sizing_box
)); __typeof__ (*((&priv->label_sizing_box))) _ptr = *
_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); } while
(0)
;
1489 }
1490
1491 if (priv->custom_title)
1492 {
1493 ctk_widget_unparent (priv->custom_title);
1494 priv->custom_title = NULL((void*)0);
1495 }
1496
1497 if (priv->label_box)
1498 {
1499 ctk_widget_unparent (priv->label_box);
1500 priv->label_box = NULL((void*)0);
1501 }
1502
1503 if (priv->titlebar_start_box)
1504 {
1505 ctk_widget_unparent (priv->titlebar_start_box);
1506 priv->titlebar_start_box = NULL((void*)0);
1507 priv->titlebar_start_separator = NULL((void*)0);
1508 }
1509
1510 if (priv->titlebar_end_box)
1511 {
1512 ctk_widget_unparent (priv->titlebar_end_box);
1513 priv->titlebar_end_box = NULL((void*)0);
1514 priv->titlebar_end_separator = NULL((void*)0);
1515 }
1516
1517 CTK_WIDGET_CLASS (ctk_header_bar_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_header_bar_parent_class)), ((ctk_widget_get_type ())
)))))
->destroy (widget);
1518}
1519
1520static void
1521ctk_header_bar_finalize (GObject *object)
1522{
1523 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (CTK_HEADER_BAR (object)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((ctk_header_bar_get_type ()))))))
);
1524
1525 g_free (priv->title);
1526 g_free (priv->subtitle);
1527 g_free (priv->decoration_layout);
1528
1529 g_clear_object (&priv->gadget)do { _Static_assert (sizeof *((&priv->gadget)) == sizeof
(gpointer), "Expression evaluates to false"); __typeof__ (((
&priv->gadget))) _pp = ((&priv->gadget)); __typeof__
(*((&priv->gadget))) _ptr = *_pp; *_pp = ((void*)0); if
(_ptr) (g_object_unref) (_ptr); } while (0)
;
1530
1531 G_OBJECT_CLASS (ctk_header_bar_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_header_bar_parent_class)), (((GType) ((20) << (
2))))))))
->finalize (object);
1532}
1533
1534static void
1535ctk_header_bar_get_property (GObject *object,
1536 guint prop_id,
1537 GValue *value,
1538 GParamSpec *pspec)
1539{
1540 CtkHeaderBar *bar = CTK_HEADER_BAR (object)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((ctk_header_bar_get_type ()))))))
;
1541 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar);
1542
1543 switch (prop_id)
1544 {
1545 case PROP_TITLE:
1546 g_value_set_string (value, priv->title);
1547 break;
1548
1549 case PROP_SUBTITLE:
1550 g_value_set_string (value, priv->subtitle);
1551 break;
1552
1553 case PROP_CUSTOM_TITLE:
1554 g_value_set_object (value, priv->custom_title);
1555 break;
1556
1557 case PROP_SPACING:
1558 g_value_set_int (value, priv->spacing);
1559 break;
1560
1561 case PROP_SHOW_CLOSE_BUTTON:
1562 g_value_set_boolean (value, ctk_header_bar_get_show_close_button (bar));
1563 break;
1564
1565 case PROP_HAS_SUBTITLE:
1566 g_value_set_boolean (value, ctk_header_bar_get_has_subtitle (bar));
1567 break;
1568
1569 case PROP_DECORATION_LAYOUT:
1570 g_value_set_string (value, ctk_header_bar_get_decoration_layout (bar));
1571 break;
1572
1573 case PROP_DECORATION_LAYOUT_SET:
1574 g_value_set_boolean (value, priv->decoration_layout_set);
1575 break;
1576
1577 default:
1578 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'"
, "ctkheaderbar.c", 1578, ("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)
;
1579 break;
1580 }
1581}
1582
1583static void
1584ctk_header_bar_set_property (GObject *object,
1585 guint prop_id,
1586 const GValue *value,
1587 GParamSpec *pspec)
1588{
1589 CtkHeaderBar *bar = CTK_HEADER_BAR (object)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((ctk_header_bar_get_type ()))))))
;
1590 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar);
1591
1592 switch (prop_id)
1593 {
1594 case PROP_TITLE:
1595 ctk_header_bar_set_title (bar, g_value_get_string (value));
1596 break;
1597
1598 case PROP_SUBTITLE:
1599 ctk_header_bar_set_subtitle (bar, g_value_get_string (value));
1600 break;
1601
1602 case PROP_CUSTOM_TITLE:
1603 ctk_header_bar_set_custom_title (bar, g_value_get_object (value));
1604 break;
1605
1606 case PROP_SPACING:
1607 if (priv->spacing != g_value_get_int (value))
1608 {
1609 priv->spacing = g_value_get_int (value);
1610 ctk_widget_queue_resize (CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((bar)), ((ctk_widget_get_type ()))))))
);
1611 g_object_notify_by_pspec (object, pspec);
1612 }
1613 break;
1614
1615 case PROP_SHOW_CLOSE_BUTTON:
1616 ctk_header_bar_set_show_close_button (bar, g_value_get_boolean (value));
1617 break;
1618
1619 case PROP_HAS_SUBTITLE:
1620 ctk_header_bar_set_has_subtitle (bar, g_value_get_boolean (value));
1621 break;
1622
1623 case PROP_DECORATION_LAYOUT:
1624 ctk_header_bar_set_decoration_layout (bar, g_value_get_string (value));
1625 break;
1626
1627 case PROP_DECORATION_LAYOUT_SET:
1628 priv->decoration_layout_set = g_value_get_boolean (value);
1629 break;
1630
1631 default:
1632 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'"
, "ctkheaderbar.c", 1632, ("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)
;
1633 break;
1634 }
1635}
1636
1637static void
1638notify_child_cb (GObject *child G_GNUC_UNUSED__attribute__ ((__unused__)),
1639 GParamSpec *pspec G_GNUC_UNUSED__attribute__ ((__unused__)),
1640 CtkHeaderBar *bar)
1641{
1642 _ctk_header_bar_update_separator_visibility (bar);
1643}
1644
1645static void
1646ctk_header_bar_pack (CtkHeaderBar *bar,
1647 CtkWidget *widget,
1648 CtkPackType pack_type)
1649{
1650 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar);
1651 Child *child;
1652
1653 g_return_if_fail (ctk_widget_get_parent (widget) == NULL)do { if ((ctk_widget_get_parent (widget) == ((void*)0))) { } else
{ g_return_if_fail_warning ("Ctk", ((const char*) (__func__)
), "ctk_widget_get_parent (widget) == NULL"); return; } } while
(0)
;
1654
1655 child = g_new (Child, 1)((Child *) g_malloc_n ((1), sizeof (Child)));
1656 child->widget = widget;
1657 child->pack_type = pack_type;
1658
1659 priv->children = g_list_append (priv->children, child);
1660
1661 ctk_widget_freeze_child_notify (widget);
1662 ctk_header_bar_reorder_css_node (bar, CTK_PACK_START, widget);
1663 ctk_widget_set_parent (widget, CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((bar)), ((ctk_widget_get_type ()))))))
);
1664 g_signal_connect (widget, "notify::visible", G_CALLBACK (notify_child_cb), bar)g_signal_connect_data ((widget), ("notify::visible"), (((GCallback
) (notify_child_cb))), (bar), ((void*)0), (GConnectFlags) 0)
;
1665 ctk_widget_child_notify (widget, "pack-type");
1666 ctk_widget_child_notify (widget, "position");
1667 ctk_widget_thaw_child_notify (widget);
1668
1669 _ctk_header_bar_update_separator_visibility (bar);
1670}
1671
1672static void
1673ctk_header_bar_add (CtkContainer *container,
1674 CtkWidget *child)
1675{
1676 ctk_header_bar_pack (CTK_HEADER_BAR (container)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_header_bar_get_type ()))))))
, child, CTK_PACK_START);
1677}
1678
1679static GList *
1680find_child_link (CtkHeaderBar *bar,
1681 CtkWidget *widget,
1682 gint *position)
1683{
1684 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar);
1685 GList *l;
1686 Child *child;
1687 gint i;
1688
1689 for (l = priv->children, i = 0; l; l = l->next, i++)
1690 {
1691 child = l->data;
1692 if (child->widget == widget)
1693 {
1694 if (position)
1695 *position = i;
1696 return l;
1697 }
1698 }
1699
1700 return NULL((void*)0);
1701}
1702
1703static void
1704ctk_header_bar_remove (CtkContainer *container,
1705 CtkWidget *widget)
1706{
1707 CtkHeaderBar *bar = CTK_HEADER_BAR (container)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_header_bar_get_type ()))))))
;
1708 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar);
1709 GList *l;
1710 Child *child;
1711
1712 l = find_child_link (bar, widget, NULL((void*)0));
1713 if (l)
1714 {
1715 child = l->data;
1716 g_signal_handlers_disconnect_by_func (widget, notify_child_cb, bar)g_signal_handlers_disconnect_matched ((widget), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (notify_child_cb), (bar))
;
1717 ctk_widget_unparent (child->widget);
1718 priv->children = g_list_delete_link (priv->children, l);
1719 g_free (child);
1720 ctk_widget_queue_resize (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
);
1721 _ctk_header_bar_update_separator_visibility (bar);
1722 }
1723}
1724
1725static void
1726ctk_header_bar_forall (CtkContainer *container,
1727 gboolean include_internals,
1728 CtkCallback callback,
1729 gpointer callback_data)
1730{
1731 CtkHeaderBar *bar = CTK_HEADER_BAR (container)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_header_bar_get_type ()))))))
;
1732 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar);
1733 Child *child;
1734 GList *children;
1735
1736 if (include_internals && priv->titlebar_start_box != NULL((void*)0))
1737 (* callback) (priv->titlebar_start_box, callback_data);
1738
1739 children = priv->children;
1740 while (children)
1741 {
1742 child = children->data;
1743 children = children->next;
1744 if (child->pack_type == CTK_PACK_START)
1745 (* callback) (child->widget, callback_data);
1746 }
1747
1748 if (priv->custom_title != NULL((void*)0))
1749 (* callback) (priv->custom_title, callback_data);
1750
1751 if (include_internals && priv->label_box != NULL((void*)0))
1752 (* callback) (priv->label_box, callback_data);
1753
1754 children = priv->children;
1755 while (children)
1756 {
1757 child = children->data;
1758 children = children->next;
1759 if (child->pack_type == CTK_PACK_END)
1760 (* callback) (child->widget, callback_data);
1761 }
1762
1763 if (include_internals && priv->titlebar_end_box != NULL((void*)0))
1764 (* callback) (priv->titlebar_end_box, callback_data);
1765}
1766
1767static void
1768ctk_header_bar_reorder_child (CtkHeaderBar *bar,
1769 CtkWidget *widget,
1770 gint position)
1771{
1772 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar);
1773 GList *l;
1774 gint old_position;
1775 Child *child;
1776
1777 l = find_child_link (bar, widget, &old_position);
1778
1779 if (l == NULL((void*)0))
1780 return;
1781
1782 if (old_position == position)
1783 return;
1784
1785 child = l->data;
1786 priv->children = g_list_delete_link (priv->children, l);
1787
1788 if (position < 0)
1789 l = NULL((void*)0);
1790 else
1791 l = g_list_nth (priv->children, position);
1792
1793 priv->children = g_list_insert_before (priv->children, l, child);
1794 ctk_header_bar_reorder_css_node (bar, child->pack_type, widget);
1795 ctk_widget_child_notify (widget, "position");
1796 ctk_widget_queue_resize (widget);
1797}
1798
1799static GType
1800ctk_header_bar_child_type (CtkContainer *container G_GNUC_UNUSED__attribute__ ((__unused__)))
1801{
1802 return CTK_TYPE_WIDGET(ctk_widget_get_type ());
1803}
1804
1805static void
1806ctk_header_bar_get_child_property (CtkContainer *container,
1807 CtkWidget *widget,
1808 guint property_id,
1809 GValue *value,
1810 GParamSpec *pspec)
1811{
1812 CtkHeaderBar *bar = CTK_HEADER_BAR (container)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_header_bar_get_type ()))))))
;
1813 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (bar);
1814 GList *l;
1815 Child *child;
1816
1817 l = find_child_link (bar, widget, NULL((void*)0));
1818 if (l == NULL((void*)0))
1819 {
1820 g_param_value_set_default (pspec, value);
1821 return;
1822 }
1823
1824 child = l->data;
1825
1826 switch (property_id)
1827 {
1828 case CHILD_PROP_PACK_TYPE:
1829 g_value_set_enum (value, child->pack_type);
1830 break;
1831
1832 case CHILD_PROP_POSITION:
1833 g_value_set_int (value, g_list_position (priv->children, l));
1834 break;
1835
1836 default:
1837 CTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec)do { GObject *_glib__object = (GObject*) ((container)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((property_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "ctkheaderbar.c", 1837, ("child 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)
;
1838 break;
1839 }
1840}
1841
1842static void
1843ctk_header_bar_set_child_property (CtkContainer *container,
1844 CtkWidget *widget,
1845 guint property_id,
1846 const GValue *value,
1847 GParamSpec *pspec)
1848{
1849 CtkHeaderBar *bar = CTK_HEADER_BAR (container)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_header_bar_get_type ()))))))
;
1850 GList *l;
1851 Child *child;
1852
1853 l = find_child_link (bar, widget, NULL((void*)0));
1854 if (l == NULL((void*)0))
1855 return;
1856
1857 child = l->data;
1858
1859 switch (property_id)
1860 {
1861 case CHILD_PROP_PACK_TYPE:
1862 child->pack_type = g_value_get_enum (value);
1863 _ctk_header_bar_update_separator_visibility (bar);
1864 ctk_widget_queue_resize (widget);
1865 break;
1866
1867 case CHILD_PROP_POSITION:
1868 ctk_header_bar_reorder_child (bar, widget, g_value_get_int (value));
1869 break;
1870
1871 default:
1872 CTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec)do { GObject *_glib__object = (GObject*) ((container)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((property_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "ctkheaderbar.c", 1872, ("child 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)
;
1873 break;
1874 }
1875}
1876
1877static gint
1878ctk_header_bar_draw (CtkWidget *widget,
1879 cairo_t *cr)
1880{
1881 CtkHeaderBarPrivate *priv = ctk_header_bar_get_instance_private (CTK_HEADER_BAR (widget)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_header_bar_get_type ()))))))
);
1882
1883 ctk_css_gadget_draw (priv->gadget, cr);
1884
1885 return FALSE(0);
1886}
1887
1888static gboolean
1889ctk_header_bar_render_contents (CtkCssGadget *gadget,
1890 cairo_t *cr,
1891 int x G_GNUC_UNUSED__attribute__ ((__unused__)),
1892 int y G_GNUC_UNUSED__attribute__ ((__unused__)),
1893 int width G_GNUC_UNUSED__attribute__ ((__unused__)),
1894 int height G_GNUC_UNUSED__attribute__ ((__unused__)),
1895 gpointer unused G_GNUC_UNUSED__attribute__ ((__unused__)))
1896{
1897 CtkWidget *widget = ctk_css_gadget_get_owner (gadget);
1898
1899 CTK_WIDGET_CLASS (ctk_header_bar_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_header_bar_parent_class)), ((ctk_widget_get_type ())
)))))
->draw (widget, cr);
1900
1901 return FALSE(0);
1902}
1903
1904static void
1905ctk_header_bar_realize (CtkWidget *widget)
1906{
1907 CtkSettings *settings;
1908
1909 CTK_WIDGET_CLASS (ctk_header_bar_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_header_bar_parent_class)), ((ctk_widget_get_type ())
)))))
->realize (widget);
1910
1911 settings = ctk_widget_get_settings (widget);
1912 g_signal_connect_swapped (settings, "notify::ctk-shell-shows-app-menu",g_signal_connect_data ((settings), ("notify::ctk-shell-shows-app-menu"
), (((GCallback) (_ctk_header_bar_update_window_buttons))), (
widget), ((void*)0), G_CONNECT_SWAPPED)
1913 G_CALLBACK (_ctk_header_bar_update_window_buttons), widget)g_signal_connect_data ((settings), ("notify::ctk-shell-shows-app-menu"
), (((GCallback) (_ctk_header_bar_update_window_buttons))), (
widget), ((void*)0), G_CONNECT_SWAPPED)
;
1914 g_signal_connect_swapped (settings, "notify::ctk-decoration-layout",g_signal_connect_data ((settings), ("notify::ctk-decoration-layout"
), (((GCallback) (_ctk_header_bar_update_window_buttons))), (
widget), ((void*)0), G_CONNECT_SWAPPED)
1915 G_CALLBACK (_ctk_header_bar_update_window_buttons), widget)g_signal_connect_data ((settings), ("notify::ctk-decoration-layout"
), (((GCallback) (_ctk_header_bar_update_window_buttons))), (
widget), ((void*)0), G_CONNECT_SWAPPED)
;
1916 _ctk_header_bar_update_window_buttons (CTK_HEADER_BAR (widget)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_header_bar_get_type ()))))))
);
1917}
1918
1919static void
1920ctk_header_bar_unrealize (CtkWidget *widget)
1921{
1922 CtkSettings *settings;
1923
1924 settings = ctk_widget_get_settings (widget);
1925
1926 g_signal_handlers_disconnect_by_func (settings, _ctk_header_bar_update_window_buttons, widget)g_signal_handlers_disconnect_matched ((settings), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (_ctk_header_bar_update_window_buttons), (widget))
;
1927
1928 CTK_WIDGET_CLASS (ctk_header_bar_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_header_bar_parent_class)), ((ctk_widget_get_type ())
)))))
->unrealize (widget);
1929}
1930
1931static gboolean
1932window_state_changed (CtkWidget *window G_GNUC_UNUSED__attribute__ ((__unused__)),
1933 CdkEventWindowState *event,
1934 gpointer data)
1935{
1936 CtkHeaderBar *bar = CTK_HEADER_BAR (data)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((data)), ((ctk_header_bar_get_type ()))))))
;
1937
1938 if (event->changed_mask & (CDK_WINDOW_STATE_FULLSCREEN |
1939 CDK_WINDOW_STATE_MAXIMIZED |
1940 CDK_WINDOW_STATE_TILED |
1941 CDK_WINDOW_STATE_TOP_TILED |
1942 CDK_WINDOW_STATE_RIGHT_TILED |
1943 CDK_WINDOW_STATE_BOTTOM_TILED |
1944 CDK_WINDOW_STATE_LEFT_TILED))
1945 _ctk_header_bar_update_window_buttons (bar);
1946
1947 return FALSE(0);
1948}
1949
1950static void
1951ctk_header_bar_hierarchy_changed (CtkWidget *widget,
1952 CtkWidget *previous_toplevel)
1953{
1954 CtkWidget *toplevel;
1955 CtkHeaderBar *bar = CTK_HEADER_BAR (widget)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_header_bar_get_type ()))))))
;
1956
1957 toplevel = ctk_widget_get_toplevel (widget);
1958
1959 if (previous_toplevel)
1960 g_signal_handlers_disconnect_by_func (previous_toplevel,g_signal_handlers_disconnect_matched ((previous_toplevel), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (window_state_changed), (widget))
1961 window_state_changed, widget)g_signal_handlers_disconnect_matched ((previous_toplevel), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (window_state_changed), (widget))
;
1962
1963 if (toplevel)
1964 g_signal_connect_after (toplevel, "window-state-event",g_signal_connect_data ((toplevel), ("window-state-event"), ((
(GCallback) (window_state_changed))), (widget), ((void*)0), G_CONNECT_AFTER
)
1965 G_CALLBACK (window_state_changed), widget)g_signal_connect_data ((toplevel), ("window-state-event"), ((
(GCallback) (window_state_changed))), (widget), ((void*)0), G_CONNECT_AFTER
)
;
1966
1967 _ctk_header_bar_update_window_buttons (bar);
1968}
1969
1970static void
1971ctk_header_bar_direction_changed (CtkWidget *widget,
1972 CtkTextDirection previous_direction)
1973{
1974 CTK_WIDGET_CLASS (ctk_header_bar_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_header_bar_parent_class)), ((ctk_widget_get_type ())
)))))
->direction_changed (widget, previous_direction);
1975
1976 ctk_css_node_reverse_children (ctk_widget_get_css_node (widget));
1977}
1978
1979static void
1980ctk_header_bar_class_init (CtkHeaderBarClass *class)
1981{
1982 GObjectClass *object_class = G_OBJECT_CLASS (class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((class)), (((GType) ((20) << (2))))))))
;
1983 CtkWidgetClass *widget_class = CTK_WIDGET_CLASS (class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((class)), ((ctk_widget_get_type ()))))))
;
1984 CtkContainerClass *container_class = CTK_CONTAINER_CLASS (class)((((CtkContainerClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((class)), ((ctk_container_get_type ()))))))
;
1985
1986 object_class->finalize = ctk_header_bar_finalize;
1987 object_class->get_property = ctk_header_bar_get_property;
1988 object_class->set_property = ctk_header_bar_set_property;
1989
1990 widget_class->destroy = ctk_header_bar_destroy;
1991 widget_class->size_allocate = ctk_header_bar_size_allocate;
1992 widget_class->get_preferred_width = ctk_header_bar_get_preferred_width;
1993 widget_class->get_preferred_height = ctk_header_bar_get_preferred_height;
1994 widget_class->get_preferred_height_for_width = ctk_header_bar_get_preferred_height_for_width;
1995 widget_class->get_preferred_width_for_height = ctk_header_bar_get_preferred_width_for_height;
1996 widget_class->draw = ctk_header_bar_draw;
1997 widget_class->realize = ctk_header_bar_realize;
1998 widget_class->unrealize = ctk_header_bar_unrealize;
1999 widget_class->hierarchy_changed = ctk_header_bar_hierarchy_changed;
2000 widget_class->direction_changed = ctk_header_bar_direction_changed;
2001
2002 container_class->add = ctk_header_bar_add;
2003 container_class->remove = ctk_header_bar_remove;
2004 container_class->forall = ctk_header_bar_forall;
2005 container_class->child_type = ctk_header_bar_child_type;
2006 container_class->set_child_property = ctk_header_bar_set_child_property;
2007 container_class->get_child_property = ctk_header_bar_get_child_property;
2008 ctk_container_class_handle_border_width (container_class);
2009
2010 ctk_container_class_install_child_property (container_class,
2011 CHILD_PROP_PACK_TYPE,
2012 g_param_spec_enum ("pack-type",
2013 P_("Pack type")g_dgettext("ctk30" "-properties","Pack type"),
2014 P_("A CtkPackType indicating whether the child is packed with reference to the start or end of the parent")g_dgettext("ctk30" "-properties","A CtkPackType indicating whether the child is packed with reference to the start or end of the parent"
)
,
2015 CTK_TYPE_PACK_TYPE(ctk_pack_type_get_type ()), CTK_PACK_START,
2016 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
2017 ctk_container_class_install_child_property (container_class,
2018 CHILD_PROP_POSITION,
2019 g_param_spec_int ("position",
2020 P_("Position")g_dgettext("ctk30" "-properties","Position"),
2021 P_("The index of the child in the parent")g_dgettext("ctk30" "-properties","The index of the child in the parent"
)
,
2022 -1, G_MAXINT2147483647, 0,
2023 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
2024
2025 header_bar_props[PROP_TITLE] =
2026 g_param_spec_string ("title",
2027 P_("Title")g_dgettext("ctk30" "-properties","Title"),
2028 P_("The title to display")g_dgettext("ctk30" "-properties","The title to display"),
2029 NULL((void*)0),
2030 G_PARAM_READWRITE);
2031
2032 header_bar_props[PROP_SUBTITLE] =
2033 g_param_spec_string ("subtitle",
2034 P_("Subtitle")g_dgettext("ctk30" "-properties","Subtitle"),
2035 P_("The subtitle to display")g_dgettext("ctk30" "-properties","The subtitle to display"),
2036 NULL((void*)0),
2037 G_PARAM_READWRITE);
2038
2039 header_bar_props[PROP_CUSTOM_TITLE] =
2040 g_param_spec_object ("custom-title",
2041 P_("Custom Title")g_dgettext("ctk30" "-properties","Custom Title"),
2042 P_("Custom title widget to display")g_dgettext("ctk30" "-properties","Custom title widget to display"
)
,
2043 CTK_TYPE_WIDGET(ctk_widget_get_type ()),
2044 G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB
)
);
2045
2046 header_bar_props[PROP_SPACING] =
2047 g_param_spec_int ("spacing",
2048 P_("Spacing")g_dgettext("ctk30" "-properties","Spacing"),
2049 P_("The amount of space between children")g_dgettext("ctk30" "-properties","The amount of space between children"
)
,
2050 0, G_MAXINT2147483647,
2051 DEFAULT_SPACING6,
2052 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
2053
2054 /**
2055 * CtkHeaderBar:show-close-button:
2056 *
2057 * Whether to show window decorations.
2058 *
2059 * Which buttons are actually shown and where is determined
2060 * by the #CtkHeaderBar:decoration-layout property, and by
2061 * the state of the window (e.g. a close button will not be
2062 * shown if the window can't be closed).
2063 */
2064 header_bar_props[PROP_SHOW_CLOSE_BUTTON] =
2065 g_param_spec_boolean ("show-close-button",
2066 P_("Show decorations")g_dgettext("ctk30" "-properties","Show decorations"),
2067 P_("Whether to show window decorations")g_dgettext("ctk30" "-properties","Whether to show window decorations"
)
,
2068 FALSE(0),
2069 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
2070
2071 /**
2072 * CtkHeaderBar:decoration-layout:
2073 *
2074 * The decoration layout for buttons. If this property is
2075 * not set, the #CtkSettings:ctk-decoration-layout setting
2076 * is used.
2077 *
2078 * See ctk_header_bar_set_decoration_layout() for information
2079 * about the format of this string.
2080 *
2081 * Since: 3.12
2082 */
2083 header_bar_props[PROP_DECORATION_LAYOUT] =
2084 g_param_spec_string ("decoration-layout",
2085 P_("Decoration Layout")g_dgettext("ctk30" "-properties","Decoration Layout"),
2086 P_("The layout for window decorations")g_dgettext("ctk30" "-properties","The layout for window decorations"
)
,
2087 NULL((void*)0),
2088 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB);
2089
2090 /**
2091 * CtkHeaderBar:decoration-layout-set:
2092 *
2093 * Set to %TRUE if #CtkHeaderBar:decoration-layout is set.
2094 *
2095 * Since: 3.12
2096 */
2097 header_bar_props[PROP_DECORATION_LAYOUT_SET] =
2098 g_param_spec_boolean ("decoration-layout-set",
2099 P_("Decoration Layout Set")g_dgettext("ctk30" "-properties","Decoration Layout Set"),
2100 P_("Whether the decoration-layout property has been set")g_dgettext("ctk30" "-properties","Whether the decoration-layout property has been set"
)
,
2101 FALSE(0),
2102 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB);
2103
2104 /**
2105 * CtkHeaderBar:has-subtitle:
2106 *
2107 * If %TRUE, reserve space for a subtitle, even if none
2108 * is currently set.
2109 *
2110 * Since: 3.12
2111 */
2112 header_bar_props[PROP_HAS_SUBTITLE] =
2113 g_param_spec_boolean ("has-subtitle",
2114 P_("Has Subtitle")g_dgettext("ctk30" "-properties","Has Subtitle"),
2115 P_("Whether to reserve space for a subtitle")g_dgettext("ctk30" "-properties","Whether to reserve space for a subtitle"
)
,
2116 TRUE(!(0)),
2117 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
2118
2119 g_object_class_install_properties (object_class, LAST_PROP, header_bar_props);
2120
2121 ctk_widget_class_set_accessible_type (widget_class, CTK_TYPE_HEADER_BAR_ACCESSIBLE(ctk_header_bar_accessible_get_type ()));
2122 ctk_widget_class_set_accessible_role (widget_class, ATK_ROLE_PANEL);
2123 ctk_widget_class_set_css_name (widget_class, "headerbar");
2124}
2125
2126static void
2127ctk_header_bar_init (CtkHeaderBar *bar)
2128{
2129 CtkHeaderBarPrivate *priv;
2130 CtkCssNode *widget_node;
2131
2132 priv = ctk_header_bar_get_instance_private (bar);
2133
2134 ctk_widget_set_has_window (CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((bar)), ((ctk_widget_get_type ()))))))
, FALSE(0));
2135
2136 priv->title = NULL((void*)0);
2137 priv->subtitle = NULL((void*)0);
2138 priv->custom_title = NULL((void*)0);
2139 priv->children = NULL((void*)0);
2140 priv->spacing = DEFAULT_SPACING6;
2141 priv->has_subtitle = TRUE(!(0));
2142 priv->decoration_layout = NULL((void*)0);
2143 priv->decoration_layout_set = FALSE(0);
2144
2145 init_sizing_box (bar);
2146 construct_label_box (bar);
2147
2148 widget_node = ctk_widget_get_css_node (CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((bar)), ((ctk_widget_get_type ()))))))
);
2149 priv->gadget = ctk_css_custom_gadget_new_for_node (widget_node,
2150 CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((bar)), ((ctk_widget_get_type ()))))))
,
2151 ctk_header_bar_get_content_size,
2152 ctk_header_bar_allocate_contents,
2153 ctk_header_bar_render_contents,
2154 NULL((void*)0),
2155 NULL((void*)0));
2156
2157}
2158
2159static void
2160ctk_header_bar_buildable_add_child (CtkBuildable *buildable,
2161 CtkBuilder *builder G_GNUC_UNUSED__attribute__ ((__unused__)),
2162 GObject *child,
2163 const gchar *type)
2164{
2165 if (type && strcmp (type, "title") == 0)
2166 ctk_header_bar_set_custom_title (CTK_HEADER_BAR (buildable)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((buildable)), ((ctk_header_bar_get_type ()))))))
, CTK_WIDGET (child)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((child)), ((ctk_widget_get_type ()))))))
);
2167 else if (!type)
2168 ctk_container_add (CTK_CONTAINER (buildable)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((buildable)), ((ctk_container_get_type ()))))))
, CTK_WIDGET (child)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((child)), ((ctk_widget_get_type ()))))))
);
2169 else
2170 CTK_BUILDER_WARN_INVALID_CHILD_TYPE (CTK_HEADER_BAR (buildable), type)g_warning ("'%s' is not a valid child type of '%s'", type, g_type_name
((((((GTypeClass*) (((GTypeInstance*) (((((CtkHeaderBar*) (void
*) g_type_check_instance_cast ((GTypeInstance*) ((buildable)
), ((ctk_header_bar_get_type ()))))))))->g_class))->g_type
)))))
;
2171}
2172
2173static void
2174ctk_header_bar_buildable_init (CtkBuildableIface *iface)
2175{
2176 iface->add_child = ctk_header_bar_buildable_add_child;
2177}
2178
2179/**
2180 * ctk_header_bar_pack_start:
2181 * @bar: A #CtkHeaderBar
2182 * @child: the #CtkWidget to be added to @bar
2183 *
2184 * Adds @child to @bar, packed with reference to the
2185 * start of the @bar.
2186 *
2187 * Since: 3.10
2188 */
2189void
2190ctk_header_bar_pack_start (CtkHeaderBar *bar,
2191 CtkWidget *child)
2192{
2193 ctk_header_bar_pack (bar, child, CTK_PACK_START);
2194}
2195
2196/**
2197 * ctk_header_bar_pack_end:
2198 * @bar: A #CtkHeaderBar
2199 * @child: the #CtkWidget to be added to @bar
2200 *
2201 * Adds @child to @bar, packed with reference to the
2202 * end of the @bar.
2203 *
2204 * Since: 3.10
2205 */
2206void
2207ctk_header_bar_pack_end (CtkHeaderBar *bar,
2208 CtkWidget *child)
2209{
2210 ctk_header_bar_pack (bar, child, CTK_PACK_END);
2211}
2212
2213/**
2214 * ctk_header_bar_new:
2215 *
2216 * Creates a new #CtkHeaderBar widget.
2217 *
2218 * Returns: a new #CtkHeaderBar
2219 *
2220 * Since: 3.10
2221 */
2222CtkWidget *
2223ctk_header_bar_new (void)
2224{
2225 return CTK_WIDGET (g_object_new (CTK_TYPE_HEADER_BAR, NULL))((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((g_object_new ((ctk_header_bar_get_type ()), ((void*)0)))
), ((ctk_widget_get_type ()))))))
;
2226}
2227
2228/**
2229 * ctk_header_bar_get_show_close_button:
2230 * @bar: a #CtkHeaderBar
2231 *
2232 * Returns whether this header bar shows the standard window
2233 * decorations.
2234 *
2235 * Returns: %TRUE if the decorations are shown
2236 *
2237 * Since: 3.10
2238 */
2239gboolean
2240ctk_header_bar_get_show_close_button (CtkHeaderBar *bar)
2241{
2242 CtkHeaderBarPrivate *priv;
2243
2244 g_return_val_if_fail (CTK_IS_HEADER_BAR (bar), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bar)); GType __t = ((ctk_header_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_HEADER_BAR (bar)"); return ((0)); } } while (0)
;
2245
2246 priv = ctk_header_bar_get_instance_private (bar);
2247
2248 return priv->shows_wm_decorations;
2249}
2250
2251/**
2252 * ctk_header_bar_set_show_close_button:
2253 * @bar: a #CtkHeaderBar
2254 * @setting: %TRUE to show standard window decorations
2255 *
2256 * Sets whether this header bar shows the standard window decorations,
2257 * including close, maximize, and minimize.
2258 *
2259 * Since: 3.10
2260 */
2261void
2262ctk_header_bar_set_show_close_button (CtkHeaderBar *bar,
2263 gboolean setting)
2264{
2265 CtkHeaderBarPrivate *priv;
2266
2267 g_return_if_fail (CTK_IS_HEADER_BAR (bar))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bar)); GType __t = ((ctk_header_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_HEADER_BAR (bar)"); return; } } while (0)
;
2268
2269 priv = ctk_header_bar_get_instance_private (bar);
2270
2271 setting = setting != FALSE(0);
2272
2273 if (priv->shows_wm_decorations == setting)
2274 return;
2275
2276 priv->shows_wm_decorations = setting;
2277 _ctk_header_bar_update_window_buttons (bar);
2278 g_object_notify_by_pspec (G_OBJECT (bar)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((bar)), (((GType) ((20) << (2))))))))
, header_bar_props[PROP_SHOW_CLOSE_BUTTON]);
2279}
2280
2281/**
2282 * ctk_header_bar_set_has_subtitle:
2283 * @bar: a #CtkHeaderBar
2284 * @setting: %TRUE to reserve space for a subtitle
2285 *
2286 * Sets whether the header bar should reserve space
2287 * for a subtitle, even if none is currently set.
2288 *
2289 * Since: 3.12
2290 */
2291void
2292ctk_header_bar_set_has_subtitle (CtkHeaderBar *bar,
2293 gboolean setting)
2294{
2295 CtkHeaderBarPrivate *priv;
2296
2297 g_return_if_fail (CTK_IS_HEADER_BAR (bar))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bar)); GType __t = ((ctk_header_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_HEADER_BAR (bar)"); return; } } while (0)
;
2298
2299 priv = ctk_header_bar_get_instance_private (bar);
2300
2301 setting = setting != FALSE(0);
2302
2303 if (priv->has_subtitle == setting)
2304 return;
2305
2306 priv->has_subtitle = setting;
2307 ctk_widget_set_visible (priv->subtitle_sizing_label, setting || (priv->subtitle && priv->subtitle[0]));
2308
2309 ctk_widget_queue_resize (CTK_WIDGET (bar)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((bar)), ((ctk_widget_get_type ()))))))
);
2310
2311 g_object_notify_by_pspec (G_OBJECT (bar)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((bar)), (((GType) ((20) << (2))))))))
, header_bar_props[PROP_HAS_SUBTITLE]);
2312}
2313
2314/**
2315 * ctk_header_bar_get_has_subtitle:
2316 * @bar: a #CtkHeaderBar
2317 *
2318 * Retrieves whether the header bar reserves space for
2319 * a subtitle, regardless if one is currently set or not.
2320 *
2321 * Returns: %TRUE if the header bar reserves space
2322 * for a subtitle
2323 *
2324 * Since: 3.12
2325 */
2326gboolean
2327ctk_header_bar_get_has_subtitle (CtkHeaderBar *bar)
2328{
2329 CtkHeaderBarPrivate *priv;
2330
2331 g_return_val_if_fail (CTK_IS_HEADER_BAR (bar), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bar)); GType __t = ((ctk_header_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_HEADER_BAR (bar)"); return ((0)); } } while (0)
;
2332
2333 priv = ctk_header_bar_get_instance_private (bar);
2334
2335 return priv->has_subtitle;
2336}
2337
2338/**
2339 * ctk_header_bar_set_decoration_layout:
2340 * @bar: a #CtkHeaderBar
2341 * @layout: (allow-none): a decoration layout, or %NULL to
2342 * unset the layout
2343 *
2344 * Sets the decoration layout for this header bar, overriding
2345 * the #CtkSettings:ctk-decoration-layout setting.
2346 *
2347 * There can be valid reasons for overriding the setting, such
2348 * as a header bar design that does not allow for buttons to take
2349 * room on the right, or only offers room for a single close button.
2350 * Split header bars are another example for overriding the
2351 * setting.
2352 *
2353 * The format of the string is button names, separated by commas.
2354 * A colon separates the buttons that should appear on the left
2355 * from those on the right. Recognized button names are minimize,
2356 * maximize, close, icon (the window icon) and menu (a menu button
2357 * for the fallback app menu).
2358 *
2359 * For example, “menu:minimize,maximize,close” specifies a menu
2360 * on the left, and minimize, maximize and close buttons on the right.
2361 *
2362 * Since: 3.12
2363 */
2364void
2365ctk_header_bar_set_decoration_layout (CtkHeaderBar *bar,
2366 const gchar *layout)
2367{
2368 CtkHeaderBarPrivate *priv;
2369
2370 g_return_if_fail (CTK_IS_HEADER_BAR (bar))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bar)); GType __t = ((ctk_header_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_HEADER_BAR (bar)"); return; } } while (0)
;
2371
2372 priv = ctk_header_bar_get_instance_private (bar);
2373
2374 g_free (priv->decoration_layout);
2375 priv->decoration_layout = g_strdup (layout)g_strdup_inline (layout);
2376 priv->decoration_layout_set = (layout != NULL((void*)0));
2377
2378 _ctk_header_bar_update_window_buttons (bar);
2379
2380 g_object_notify_by_pspec (G_OBJECT (bar)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((bar)), (((GType) ((20) << (2))))))))
, header_bar_props[PROP_DECORATION_LAYOUT]);
2381 g_object_notify_by_pspec (G_OBJECT (bar)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((bar)), (((GType) ((20) << (2))))))))
, header_bar_props[PROP_DECORATION_LAYOUT_SET]);
2382}
2383
2384/**
2385 * ctk_header_bar_get_decoration_layout:
2386 * @bar: a #CtkHeaderBar
2387 *
2388 * Gets the decoration layout set with
2389 * ctk_header_bar_set_decoration_layout().
2390 *
2391 * Returns: the decoration layout
2392 *
2393 * Since: 3.12
2394 */
2395const gchar *
2396ctk_header_bar_get_decoration_layout (CtkHeaderBar *bar)
2397{
2398 CtkHeaderBarPrivate *priv;
2399
2400 g_return_val_if_fail (CTK_IS_HEADER_BAR (bar), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bar)); GType __t = ((ctk_header_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_HEADER_BAR (bar)"); return (((void*)0)); } } while
(0)
;
2401
2402 priv = ctk_header_bar_get_instance_private (bar);
2403
2404 return priv->decoration_layout;
2405}