| File: | ctk/ctkemojicompletion.c |
| Warning: | line 598, column 22 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* ctkemojicompletion.c: An Emoji picker widget | |||
| 2 | * Copyright 2017, Red Hat, Inc. | |||
| 3 | * | |||
| 4 | * This library is free software; you can redistribute it and/or | |||
| 5 | * modify it under the terms of the GNU Lesser General Public | |||
| 6 | * License as published by the Free Software Foundation; either | |||
| 7 | * version 2 of the License, or (at your option) any later version. | |||
| 8 | * | |||
| 9 | * This library is distributed in the hope that it will be useful, | |||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| 12 | * Lesser General Public License for more details. | |||
| 13 | * | |||
| 14 | * You should have received a copy of the GNU Lesser General Public | |||
| 15 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. | |||
| 16 | */ | |||
| 17 | ||||
| 18 | #include "config.h" | |||
| 19 | ||||
| 20 | #include "ctkemojicompletion.h" | |||
| 21 | ||||
| 22 | #include "ctkentryprivate.h" | |||
| 23 | #include "ctkbox.h" | |||
| 24 | #include "ctkcssprovider.h" | |||
| 25 | #include "ctklistbox.h" | |||
| 26 | #include "ctklabel.h" | |||
| 27 | #include "ctkpopover.h" | |||
| 28 | #include "ctkintl.h" | |||
| 29 | #include "ctkprivate.h" | |||
| 30 | #include "ctkgesturelongpress.h" | |||
| 31 | #include "ctkflowbox.h" | |||
| 32 | #include "ctkstack.h" | |||
| 33 | ||||
| 34 | struct _CtkEmojiCompletion | |||
| 35 | { | |||
| 36 | CtkPopover parent_instance; | |||
| 37 | ||||
| 38 | CtkEntry *entry; | |||
| 39 | char *text; | |||
| 40 | guint length; | |||
| 41 | guint offset; | |||
| 42 | gulong changed_id; | |||
| 43 | guint n_matches; | |||
| 44 | ||||
| 45 | CtkWidget *list; | |||
| 46 | CtkWidget *active; | |||
| 47 | CtkWidget *active_variation; | |||
| 48 | ||||
| 49 | GVariant *data; | |||
| 50 | ||||
| 51 | CtkGesture *long_press; | |||
| 52 | }; | |||
| 53 | ||||
| 54 | struct _CtkEmojiCompletionClass { | |||
| 55 | CtkPopoverClass parent_class; | |||
| 56 | }; | |||
| 57 | ||||
| 58 | static void connect_signals (CtkEmojiCompletion *completion, | |||
| 59 | CtkEntry *entry); | |||
| 60 | static void disconnect_signals (CtkEmojiCompletion *completion); | |||
| 61 | static int populate_completion (CtkEmojiCompletion *completion, | |||
| 62 | const char *text, | |||
| 63 | guint offset); | |||
| 64 | ||||
| 65 | #define MAX_ROWS5 5 | |||
| 66 | ||||
| 67 | G_DEFINE_TYPE (CtkEmojiCompletion, ctk_emoji_completion, CTK_TYPE_POPOVER)static void ctk_emoji_completion_init (CtkEmojiCompletion *self ); static void ctk_emoji_completion_class_init (CtkEmojiCompletionClass *klass); static GType ctk_emoji_completion_get_type_once (void ); static gpointer ctk_emoji_completion_parent_class = ((void *)0); static gint CtkEmojiCompletion_private_offset; static void ctk_emoji_completion_class_intern_init (gpointer klass) { ctk_emoji_completion_parent_class = g_type_class_peek_parent (klass); if (CtkEmojiCompletion_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkEmojiCompletion_private_offset ); ctk_emoji_completion_class_init ((CtkEmojiCompletionClass* ) klass); } __attribute__ ((__unused__)) static inline gpointer ctk_emoji_completion_get_instance_private (CtkEmojiCompletion *self) { return (((gpointer) ((guint8*) (self) + (glong) (CtkEmojiCompletion_private_offset )))); } GType ctk_emoji_completion_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_emoji_completion_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_emoji_completion_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple ((ctk_popover_get_type ()), g_intern_static_string ("CtkEmojiCompletion" ), sizeof (CtkEmojiCompletionClass), (GClassInitFunc)(void (* )(void)) ctk_emoji_completion_class_intern_init, sizeof (CtkEmojiCompletion ), (GInstanceInitFunc)(void (*)(void)) ctk_emoji_completion_init , (GTypeFlags) 0); { {{};} } return g_define_type_id; } | |||
| 68 | ||||
| 69 | static void | |||
| 70 | ctk_emoji_completion_finalize (GObject *object) | |||
| 71 | { | |||
| 72 | CtkEmojiCompletion *completion = CTK_EMOJI_COMPLETION (object)((((CtkEmojiCompletion*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((object)), ((ctk_emoji_completion_get_type ( ))))))); | |||
| 73 | ||||
| 74 | disconnect_signals (completion); | |||
| 75 | ||||
| 76 | g_free (completion->text); | |||
| 77 | g_variant_unref (completion->data); | |||
| 78 | ||||
| 79 | g_clear_object (&completion->long_press)do { _Static_assert (sizeof *((&completion->long_press )) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (((&completion->long_press))) _pp = ((&completion ->long_press)); __typeof__ (*((&completion->long_press ))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref ) (_ptr); } while (0); | |||
| 80 | ||||
| 81 | G_OBJECT_CLASS (ctk_emoji_completion_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_emoji_completion_parent_class)), (((GType) ((20) << (2))))))))->finalize (object); | |||
| 82 | } | |||
| 83 | ||||
| 84 | static void | |||
| 85 | update_completion (CtkEmojiCompletion *completion) | |||
| 86 | { | |||
| 87 | const char *text; | |||
| 88 | guint length; | |||
| 89 | guint n_matches; | |||
| 90 | ||||
| 91 | n_matches = 0; | |||
| 92 | ||||
| 93 | text = ctk_entry_get_text (CTK_ENTRY (completion->entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->entry)), ((ctk_entry_get_type ()))))))); | |||
| 94 | length = strlen (text); | |||
| 95 | ||||
| 96 | if (length > 0) | |||
| 97 | { | |||
| 98 | gboolean found_candidate = FALSE(0); | |||
| 99 | const char *p; | |||
| 100 | ||||
| 101 | p = text + length; | |||
| 102 | do | |||
| 103 | { | |||
| 104 | next: | |||
| 105 | p = g_utf8_prev_char (p); | |||
| 106 | if (*p == ':') | |||
| 107 | { | |||
| 108 | if (p + 1 == text + length) | |||
| 109 | goto next; | |||
| 110 | ||||
| 111 | if (p == text || !g_unichar_isalnum (g_utf8_get_char (p - 1))) | |||
| 112 | { | |||
| 113 | found_candidate = TRUE(!(0)); | |||
| 114 | } | |||
| 115 | ||||
| 116 | break; | |||
| 117 | } | |||
| 118 | } | |||
| 119 | while (g_unichar_isalnum (g_utf8_get_char (p)) || *p == '_'); | |||
| 120 | ||||
| 121 | if (found_candidate) | |||
| 122 | n_matches = populate_completion (completion, p, 0); | |||
| 123 | } | |||
| 124 | ||||
| 125 | if (n_matches > 0) | |||
| 126 | ctk_popover_popup (CTK_POPOVER (completion)((((CtkPopover*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion)), ((ctk_popover_get_type ()))))))); | |||
| 127 | else | |||
| 128 | ctk_popover_popdown (CTK_POPOVER (completion)((((CtkPopover*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion)), ((ctk_popover_get_type ()))))))); | |||
| 129 | } | |||
| 130 | ||||
| 131 | static void | |||
| 132 | entry_changed (CtkEntry *entry G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
| 133 | CtkEmojiCompletion *completion) | |||
| 134 | { | |||
| 135 | update_completion (completion); | |||
| 136 | } | |||
| 137 | ||||
| 138 | static void | |||
| 139 | emoji_activated (CtkWidget *row, | |||
| 140 | CtkEmojiCompletion *completion) | |||
| 141 | { | |||
| 142 | const char *emoji; | |||
| 143 | guint length; | |||
| 144 | ||||
| 145 | ctk_popover_popdown (CTK_POPOVER (completion)((((CtkPopover*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion)), ((ctk_popover_get_type ()))))))); | |||
| 146 | ||||
| 147 | emoji = (const char *)g_object_get_data (G_OBJECT (row)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((row)), (((GType) ((20) << (2)))))))), "text"); | |||
| 148 | ||||
| 149 | g_signal_handler_block (completion->entry, completion->changed_id); | |||
| 150 | ||||
| 151 | length = g_utf8_strlen (ctk_entry_get_text (completion->entry), -1); | |||
| 152 | ctk_entry_set_positions (completion->entry, length - completion->length, length); | |||
| 153 | ctk_entry_enter_text (completion->entry, emoji); | |||
| 154 | ||||
| 155 | g_signal_handler_unblock (completion->entry, completion->changed_id); | |||
| 156 | } | |||
| 157 | ||||
| 158 | static void | |||
| 159 | row_activated (CtkListBox *list G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
| 160 | CtkListBoxRow *row, | |||
| 161 | gpointer data) | |||
| 162 | { | |||
| 163 | CtkEmojiCompletion *completion = data; | |||
| 164 | ||||
| 165 | emoji_activated (CTK_WIDGET (row)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((row)), ((ctk_widget_get_type ())))))), completion); | |||
| 166 | } | |||
| 167 | ||||
| 168 | static void | |||
| 169 | child_activated (CtkFlowBox *box G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
| 170 | CtkFlowBoxChild *child, | |||
| 171 | gpointer data) | |||
| 172 | { | |||
| 173 | CtkEmojiCompletion *completion = data; | |||
| 174 | ||||
| 175 | emoji_activated (CTK_WIDGET (child)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((child)), ((ctk_widget_get_type ())))))), completion); | |||
| 176 | } | |||
| 177 | ||||
| 178 | static void | |||
| 179 | move_active_row (CtkEmojiCompletion *completion, | |||
| 180 | int direction) | |||
| 181 | { | |||
| 182 | CtkWidget *child; | |||
| 183 | CtkWidget *base; | |||
| 184 | GList *children, *l, *active, *last; | |||
| 185 | ||||
| 186 | active = NULL((void*)0); | |||
| 187 | last = NULL((void*)0); | |||
| 188 | children = ctk_container_get_children (CTK_CONTAINER (completion->list)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->list)), ((ctk_container_get_type ()))))))); | |||
| 189 | for (l = children; l; l = l->next) | |||
| 190 | { | |||
| 191 | child = l->data; | |||
| 192 | ||||
| 193 | if (completion->active == child) | |||
| 194 | active = l; | |||
| 195 | ||||
| 196 | if (l->next == NULL((void*)0)) | |||
| 197 | last = l; | |||
| 198 | ||||
| 199 | ctk_widget_unset_state_flags (child, CTK_STATE_FLAG_PRELIGHT); | |||
| 200 | base = CTK_WIDGET (g_object_get_data (G_OBJECT (child), "base"))((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((child)), (((GType) ((20) << (2)))) )))), "base"))), ((ctk_widget_get_type ())))))); | |||
| 201 | ctk_widget_unset_state_flags (base, CTK_STATE_FLAG_PRELIGHT); | |||
| 202 | } | |||
| 203 | ||||
| 204 | if (completion->active != NULL((void*)0)) | |||
| 205 | { | |||
| 206 | if (direction == 1) | |||
| 207 | completion->active = (active && active->next) ? active->next->data : NULL((void*)0); | |||
| 208 | else | |||
| 209 | completion->active = (active && active->prev) ? active->prev->data : NULL((void*)0); | |||
| 210 | } | |||
| 211 | ||||
| 212 | if (completion->active == NULL((void*)0)) | |||
| 213 | { | |||
| 214 | if (direction == 1) | |||
| 215 | completion->active = children->data; | |||
| 216 | else | |||
| 217 | completion->active = last->data; | |||
| 218 | } | |||
| 219 | ||||
| 220 | if (completion->active != NULL((void*)0)) | |||
| 221 | ctk_widget_set_state_flags (completion->active, CTK_STATE_FLAG_PRELIGHT, FALSE(0)); | |||
| 222 | ||||
| 223 | if (completion->active_variation) | |||
| 224 | { | |||
| 225 | ctk_widget_unset_state_flags (completion->active_variation, CTK_STATE_FLAG_PRELIGHT); | |||
| 226 | completion->active_variation = NULL((void*)0); | |||
| 227 | } | |||
| 228 | ||||
| 229 | g_list_free (children); | |||
| 230 | } | |||
| 231 | ||||
| 232 | static void | |||
| 233 | activate_active_row (CtkEmojiCompletion *completion) | |||
| 234 | { | |||
| 235 | if (CTK_IS_FLOW_BOX_CHILD (completion->active_variation)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (completion->active_variation)); GType __t = ((ctk_flow_box_child_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; }))))) | |||
| 236 | emoji_activated (completion->active_variation, completion); | |||
| 237 | else if (completion->active != NULL((void*)0)) | |||
| 238 | emoji_activated (completion->active, completion); | |||
| 239 | } | |||
| 240 | ||||
| 241 | static void | |||
| 242 | show_variations (CtkEmojiCompletion *completion, | |||
| 243 | CtkWidget *row, | |||
| 244 | gboolean visible) | |||
| 245 | { | |||
| 246 | CtkWidget *stack; | |||
| 247 | CtkWidget *box; | |||
| 248 | gboolean is_visible; | |||
| 249 | ||||
| 250 | if (!row) | |||
| 251 | return; | |||
| 252 | ||||
| 253 | stack = CTK_WIDGET (g_object_get_data (G_OBJECT (row), "stack"))((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((row)), (((GType) ((20) << (2)))))) )), "stack"))), ((ctk_widget_get_type ())))))); | |||
| 254 | box = ctk_stack_get_child_by_name (CTK_STACK (stack)((((CtkStack*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((stack)), ((ctk_stack_get_type ())))))), "variations"); | |||
| 255 | if (!box) | |||
| 256 | return; | |||
| 257 | ||||
| 258 | is_visible = ctk_stack_get_visible_child (CTK_STACK (stack)((((CtkStack*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((stack)), ((ctk_stack_get_type ()))))))) == box; | |||
| 259 | if (is_visible == visible) | |||
| 260 | return; | |||
| 261 | ||||
| 262 | if (visible) | |||
| 263 | ctk_widget_unset_state_flags (row, CTK_STATE_FLAG_PRELIGHT); | |||
| 264 | else | |||
| 265 | ctk_widget_set_state_flags (row, CTK_STATE_FLAG_PRELIGHT, FALSE(0)); | |||
| 266 | ||||
| 267 | ctk_stack_set_visible_child_name (CTK_STACK (stack)((((CtkStack*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((stack)), ((ctk_stack_get_type ())))))), visible ? "variations" : "text"); | |||
| 268 | if (completion->active_variation) | |||
| 269 | { | |||
| 270 | ctk_widget_unset_state_flags (completion->active_variation, CTK_STATE_FLAG_PRELIGHT); | |||
| 271 | completion->active_variation = NULL((void*)0); | |||
| 272 | } | |||
| 273 | } | |||
| 274 | ||||
| 275 | static gboolean | |||
| 276 | move_active_variation (CtkEmojiCompletion *completion, | |||
| 277 | int direction) | |||
| 278 | { | |||
| 279 | CtkWidget *base; | |||
| 280 | CtkWidget *stack; | |||
| 281 | CtkWidget *box; | |||
| 282 | CtkWidget *next; | |||
| 283 | GList *children, *l, *active; | |||
| 284 | ||||
| 285 | if (!completion->active) | |||
| 286 | return FALSE(0); | |||
| 287 | ||||
| 288 | base = CTK_WIDGET (g_object_get_data (G_OBJECT (completion->active), "base"))((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((completion->active)), (((GType) ((20) << (2)))))))), "base"))), ((ctk_widget_get_type ())))) )); | |||
| 289 | stack = CTK_WIDGET (g_object_get_data (G_OBJECT (completion->active), "stack"))((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((completion->active)), (((GType) ((20) << (2)))))))), "stack"))), ((ctk_widget_get_type ()))) ))); | |||
| 290 | box = ctk_stack_get_child_by_name (CTK_STACK (stack)((((CtkStack*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((stack)), ((ctk_stack_get_type ())))))), "variations"); | |||
| 291 | ||||
| 292 | if (ctk_stack_get_visible_child (CTK_STACK (stack)((((CtkStack*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((stack)), ((ctk_stack_get_type ()))))))) != box) | |||
| 293 | return FALSE(0); | |||
| 294 | ||||
| 295 | next = NULL((void*)0); | |||
| 296 | ||||
| 297 | active = NULL((void*)0); | |||
| 298 | children = ctk_container_get_children (CTK_CONTAINER (box)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box)), ((ctk_container_get_type ()))))))); | |||
| 299 | for (l = children; l; l = l->next) | |||
| 300 | { | |||
| 301 | if (l->data == completion->active_variation) | |||
| 302 | active = l; | |||
| 303 | } | |||
| 304 | ||||
| 305 | if (!completion->active_variation) | |||
| 306 | next = base; | |||
| 307 | else if (completion->active_variation == base && direction == 1) | |||
| 308 | next = children->data; | |||
| 309 | else if (completion->active_variation == children->data && direction == -1) | |||
| 310 | next = base; | |||
| 311 | else if (direction == 1) | |||
| 312 | next = (active && active->next) ? active->next->data : NULL((void*)0); | |||
| 313 | else if (direction == -1) | |||
| 314 | next = (active && active->prev) ? active->prev->data : NULL((void*)0); | |||
| 315 | ||||
| 316 | if (next) | |||
| 317 | { | |||
| 318 | if (completion->active_variation) | |||
| 319 | ctk_widget_unset_state_flags (completion->active_variation, CTK_STATE_FLAG_PRELIGHT); | |||
| 320 | completion->active_variation = next; | |||
| 321 | ctk_widget_set_state_flags (completion->active_variation, CTK_STATE_FLAG_PRELIGHT, FALSE(0)); | |||
| 322 | } | |||
| 323 | ||||
| 324 | g_list_free (children); | |||
| 325 | ||||
| 326 | return next != NULL((void*)0); | |||
| 327 | } | |||
| 328 | ||||
| 329 | static gboolean | |||
| 330 | entry_key_press (CtkEntry *entry G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
| 331 | CdkEventKey *event, | |||
| 332 | CtkEmojiCompletion *completion) | |||
| 333 | { | |||
| 334 | guint keyval; | |||
| 335 | ||||
| 336 | if (!ctk_widget_get_visible (CTK_WIDGET (completion)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion)), ((ctk_widget_get_type ())))))))) | |||
| ||||
| 337 | return FALSE(0); | |||
| 338 | ||||
| 339 | cdk_event_get_keyval ((CdkEvent*)event, &keyval); | |||
| 340 | ||||
| 341 | if (keyval == CDK_KEY_Escape0xff1b) | |||
| 342 | { | |||
| 343 | ctk_popover_popdown (CTK_POPOVER (completion)((((CtkPopover*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion)), ((ctk_popover_get_type ()))))))); | |||
| 344 | return TRUE(!(0)); | |||
| 345 | } | |||
| 346 | ||||
| 347 | if (keyval == CDK_KEY_Tab0xff09) | |||
| 348 | { | |||
| 349 | guint offset; | |||
| 350 | show_variations (completion, completion->active, FALSE(0)); | |||
| 351 | ||||
| 352 | offset = completion->offset + MAX_ROWS5; | |||
| 353 | if (offset >= completion->n_matches) | |||
| 354 | offset = 0; | |||
| 355 | populate_completion (completion, completion->text, offset); | |||
| 356 | return TRUE(!(0)); | |||
| 357 | } | |||
| 358 | ||||
| 359 | if (keyval == CDK_KEY_Up0xff52) | |||
| 360 | { | |||
| 361 | show_variations (completion, completion->active, FALSE(0)); | |||
| 362 | ||||
| 363 | move_active_row (completion, -1); | |||
| 364 | return TRUE(!(0)); | |||
| 365 | } | |||
| 366 | ||||
| 367 | if (keyval == CDK_KEY_Down0xff54) | |||
| 368 | { | |||
| 369 | show_variations (completion, completion->active, FALSE(0)); | |||
| 370 | ||||
| 371 | move_active_row (completion, 1); | |||
| 372 | return TRUE(!(0)); | |||
| 373 | } | |||
| 374 | ||||
| 375 | if (keyval == CDK_KEY_Return0xff0d || | |||
| 376 | keyval == CDK_KEY_KP_Enter0xff8d || | |||
| 377 | keyval == CDK_KEY_ISO_Enter0xfe34) | |||
| 378 | { | |||
| 379 | activate_active_row (completion); | |||
| 380 | return TRUE(!(0)); | |||
| 381 | } | |||
| 382 | ||||
| 383 | if (keyval == CDK_KEY_Right0xff53) | |||
| 384 | { | |||
| 385 | show_variations (completion, completion->active, TRUE(!(0))); | |||
| 386 | move_active_variation (completion, 1); | |||
| 387 | return TRUE(!(0)); | |||
| 388 | } | |||
| 389 | ||||
| 390 | if (keyval == CDK_KEY_Left0xff51) | |||
| 391 | { | |||
| 392 | if (!move_active_variation (completion, -1)) | |||
| 393 | show_variations (completion, completion->active, FALSE(0)); | |||
| 394 | return TRUE(!(0)); | |||
| 395 | } | |||
| 396 | ||||
| 397 | return FALSE(0); | |||
| 398 | } | |||
| 399 | ||||
| 400 | static gboolean | |||
| 401 | entry_focus_out (CtkWidget *entry, | |||
| 402 | GParamSpec *pspec G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
| 403 | CtkEmojiCompletion *completion) | |||
| 404 | { | |||
| 405 | if (!ctk_widget_has_focus (entry)) | |||
| 406 | ctk_popover_popdown (CTK_POPOVER (completion)((((CtkPopover*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion)), ((ctk_popover_get_type ()))))))); | |||
| 407 | return FALSE(0); | |||
| 408 | } | |||
| 409 | ||||
| 410 | static void | |||
| 411 | connect_signals (CtkEmojiCompletion *completion, | |||
| 412 | CtkEntry *entry) | |||
| 413 | { | |||
| 414 | completion->entry = entry; | |||
| 415 | ||||
| 416 | completion->changed_id = g_signal_connect (entry, "changed", G_CALLBACK (entry_changed), completion)g_signal_connect_data ((entry), ("changed"), (((GCallback) (entry_changed ))), (completion), ((void*)0), (GConnectFlags) 0); | |||
| 417 | g_signal_connect (entry, "key-press-event", G_CALLBACK (entry_key_press), completion)g_signal_connect_data ((entry), ("key-press-event"), (((GCallback ) (entry_key_press))), (completion), ((void*)0), (GConnectFlags ) 0); | |||
| 418 | g_signal_connect (entry, "notify::has-focus", G_CALLBACK (entry_focus_out), completion)g_signal_connect_data ((entry), ("notify::has-focus"), (((GCallback ) (entry_focus_out))), (completion), ((void*)0), (GConnectFlags ) 0); | |||
| 419 | } | |||
| 420 | ||||
| 421 | static void | |||
| 422 | disconnect_signals (CtkEmojiCompletion *completion) | |||
| 423 | { | |||
| 424 | g_signal_handlers_disconnect_by_func (completion->entry, entry_changed, completion)g_signal_handlers_disconnect_matched ((completion->entry), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (entry_changed), (completion)); | |||
| 425 | g_signal_handlers_disconnect_by_func (completion->entry, entry_key_press, completion)g_signal_handlers_disconnect_matched ((completion->entry), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (entry_key_press), (completion)); | |||
| 426 | g_signal_handlers_disconnect_by_func (completion->entry, entry_focus_out, completion)g_signal_handlers_disconnect_matched ((completion->entry), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (entry_focus_out), (completion)); | |||
| 427 | ||||
| 428 | completion->entry = NULL((void*)0); | |||
| 429 | } | |||
| 430 | ||||
| 431 | static gboolean | |||
| 432 | has_variations (GVariant *emoji_data) | |||
| 433 | { | |||
| 434 | GVariant *codes; | |||
| 435 | gsize i; | |||
| 436 | gboolean has_variations; | |||
| 437 | ||||
| 438 | has_variations = FALSE(0); | |||
| 439 | codes = g_variant_get_child_value (emoji_data, 0); | |||
| 440 | for (i = 0; i < g_variant_n_children (codes); i++) | |||
| 441 | { | |||
| 442 | gunichar code; | |||
| 443 | g_variant_get_child (codes, i, "u", &code); | |||
| 444 | if (code == 0) | |||
| 445 | { | |||
| 446 | has_variations = TRUE(!(0)); | |||
| 447 | break; | |||
| 448 | } | |||
| 449 | } | |||
| 450 | g_variant_unref (codes); | |||
| 451 | ||||
| 452 | return has_variations; | |||
| 453 | } | |||
| 454 | ||||
| 455 | static void | |||
| 456 | get_text (GVariant *emoji_data, | |||
| 457 | gunichar modifier, | |||
| 458 | char *text, | |||
| 459 | gsize length G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
| 460 | { | |||
| 461 | GVariant *codes; | |||
| 462 | int i; | |||
| 463 | char *p; | |||
| 464 | ||||
| 465 | p = text; | |||
| 466 | codes = g_variant_get_child_value (emoji_data, 0); | |||
| 467 | for (i = 0; i < g_variant_n_children (codes); i++) | |||
| 468 | { | |||
| 469 | gunichar code; | |||
| 470 | ||||
| 471 | g_variant_get_child (codes, i, "u", &code); | |||
| 472 | if (code == 0) | |||
| 473 | code = modifier; | |||
| 474 | if (code != 0) | |||
| 475 | p += g_unichar_to_utf8 (code, p); | |||
| 476 | } | |||
| 477 | g_variant_unref (codes); | |||
| 478 | p += g_unichar_to_utf8 (0xFE0F, p); /* U+FE0F is the Emoji variation selector */ | |||
| 479 | p[0] = 0; | |||
| 480 | } | |||
| 481 | ||||
| 482 | static void | |||
| 483 | add_emoji_variation (CtkWidget *box, | |||
| 484 | GVariant *emoji_data, | |||
| 485 | gunichar modifier) | |||
| 486 | { | |||
| 487 | CtkWidget *child; | |||
| 488 | CtkWidget *label; | |||
| 489 | PangoAttrList *attrs; | |||
| 490 | char text[64]; | |||
| 491 | ||||
| 492 | get_text (emoji_data, modifier, text, 64); | |||
| 493 | ||||
| 494 | label = ctk_label_new (text); | |||
| 495 | ctk_widget_show (label); | |||
| 496 | attrs = pango_attr_list_new (); | |||
| 497 | pango_attr_list_insert (attrs, pango_attr_scale_new (PANGO_SCALE_X_LARGE((double)1.44))); | |||
| 498 | ctk_label_set_attributes (CTK_LABEL (label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((label)), ((ctk_label_get_type ())))))), attrs); | |||
| 499 | pango_attr_list_unref (attrs); | |||
| 500 | ||||
| 501 | child = ctk_flow_box_child_new (); | |||
| 502 | ctk_widget_show (child); | |||
| 503 | ctk_style_context_add_class (ctk_widget_get_style_context (child), "emoji"); | |||
| 504 | g_object_set_data_full (G_OBJECT (child)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((child)), (((GType) ((20) << (2)))))))), "text", g_strdup (text)g_strdup_inline (text), g_free); | |||
| 505 | g_object_set_data_full (G_OBJECT (child)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((child)), (((GType) ((20) << (2)))))))), "emoji-data", | |||
| 506 | g_variant_ref (emoji_data), | |||
| 507 | (GDestroyNotify)g_variant_unref); | |||
| 508 | if (modifier != 0) | |||
| 509 | g_object_set_data (G_OBJECT (child)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((child)), (((GType) ((20) << (2)))))))), "modifier", GUINT_TO_POINTER (modifier)((gpointer) (gulong) (modifier))); | |||
| 510 | ||||
| 511 | ctk_container_add (CTK_CONTAINER (child)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((child)), ((ctk_container_get_type ())))))), label); | |||
| 512 | ctk_flow_box_insert (CTK_FLOW_BOX (box)((((CtkFlowBox*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box)), ((ctk_flow_box_get_type ())))))), child, -1); | |||
| 513 | } | |||
| 514 | ||||
| 515 | static void | |||
| 516 | add_emoji (CtkWidget *list, | |||
| 517 | GVariant *emoji_data, | |||
| 518 | CtkEmojiCompletion *completion) | |||
| 519 | { | |||
| 520 | CtkWidget *child; | |||
| 521 | CtkWidget *label; | |||
| 522 | CtkWidget *box; | |||
| 523 | PangoAttrList *attrs; | |||
| 524 | char text[64]; | |||
| 525 | const char *shortname; | |||
| 526 | CtkWidget *stack; | |||
| 527 | gunichar modifier; | |||
| 528 | ||||
| 529 | get_text (emoji_data, 0, text, 64); | |||
| 530 | ||||
| 531 | label = ctk_label_new (text); | |||
| 532 | ctk_widget_show (label); | |||
| 533 | attrs = pango_attr_list_new (); | |||
| 534 | pango_attr_list_insert (attrs, pango_attr_scale_new (PANGO_SCALE_X_LARGE((double)1.44))); | |||
| 535 | ctk_label_set_attributes (CTK_LABEL (label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((label)), ((ctk_label_get_type ())))))), attrs); | |||
| 536 | pango_attr_list_unref (attrs); | |||
| 537 | ctk_style_context_add_class (ctk_widget_get_style_context (label), "emoji"); | |||
| 538 | ||||
| 539 | child = ctk_list_box_row_new (); | |||
| 540 | ctk_widget_show (child); | |||
| 541 | ctk_widget_set_focus_on_click (child, FALSE(0)); | |||
| 542 | box = ctk_box_new (CTK_ORIENTATION_HORIZONTAL, 10); | |||
| 543 | ctk_widget_show (box); | |||
| 544 | ctk_container_add (CTK_CONTAINER (child)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((child)), ((ctk_container_get_type ())))))), box); | |||
| 545 | ctk_box_pack_start (CTK_BOX (box)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box)), ((ctk_box_get_type ())))))), label, FALSE(0), FALSE(0), 0); | |||
| 546 | g_object_set_data (G_OBJECT (child)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((child)), (((GType) ((20) << (2)))))))), "base", label); | |||
| 547 | ||||
| 548 | stack = ctk_stack_new (); | |||
| 549 | ctk_widget_show (stack); | |||
| 550 | ctk_stack_set_homogeneous (CTK_STACK (stack)((((CtkStack*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((stack)), ((ctk_stack_get_type ())))))), TRUE(!(0))); | |||
| 551 | ctk_stack_set_transition_type (CTK_STACK (stack)((((CtkStack*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((stack)), ((ctk_stack_get_type ())))))), CTK_STACK_TRANSITION_TYPE_OVER_RIGHT_LEFT); | |||
| 552 | ctk_box_pack_start (CTK_BOX (box)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box)), ((ctk_box_get_type ())))))), stack, FALSE(0), FALSE(0), 0); | |||
| 553 | g_object_set_data (G_OBJECT (child)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((child)), (((GType) ((20) << (2)))))))), "stack", stack); | |||
| 554 | ||||
| 555 | g_variant_get_child (emoji_data, 2, "&s", &shortname); | |||
| 556 | label = ctk_label_new (shortname); | |||
| 557 | ctk_widget_show (label); | |||
| 558 | ctk_label_set_xalign (CTK_LABEL (label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((label)), ((ctk_label_get_type ())))))), 0); | |||
| 559 | ||||
| 560 | ctk_stack_add_named (CTK_STACK (stack)((((CtkStack*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((stack)), ((ctk_stack_get_type ())))))), label, "text"); | |||
| 561 | ||||
| 562 | if (has_variations (emoji_data)) | |||
| 563 | { | |||
| 564 | box = ctk_flow_box_new (); | |||
| 565 | ctk_widget_show (box); | |||
| 566 | ctk_flow_box_set_homogeneous (CTK_FLOW_BOX (box)((((CtkFlowBox*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box)), ((ctk_flow_box_get_type ())))))), TRUE(!(0))); | |||
| 567 | ctk_flow_box_set_min_children_per_line (CTK_FLOW_BOX (box)((((CtkFlowBox*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box)), ((ctk_flow_box_get_type ())))))), 5); | |||
| 568 | ctk_flow_box_set_max_children_per_line (CTK_FLOW_BOX (box)((((CtkFlowBox*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box)), ((ctk_flow_box_get_type ())))))), 5); | |||
| 569 | ctk_flow_box_set_activate_on_single_click (CTK_FLOW_BOX (box)((((CtkFlowBox*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box)), ((ctk_flow_box_get_type ())))))), TRUE(!(0))); | |||
| 570 | ctk_flow_box_set_selection_mode (CTK_FLOW_BOX (box)((((CtkFlowBox*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((box)), ((ctk_flow_box_get_type ())))))), CTK_SELECTION_NONE); | |||
| 571 | g_signal_connect (box, "child-activated", G_CALLBACK (child_activated), completion)g_signal_connect_data ((box), ("child-activated"), (((GCallback ) (child_activated))), (completion), ((void*)0), (GConnectFlags ) 0); | |||
| 572 | for (modifier = 0x1f3fb; modifier <= 0x1f3ff; modifier++) | |||
| 573 | add_emoji_variation (box, emoji_data, modifier); | |||
| 574 | ||||
| 575 | ctk_stack_add_named (CTK_STACK (stack)((((CtkStack*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((stack)), ((ctk_stack_get_type ())))))), box, "variations"); | |||
| 576 | } | |||
| 577 | ||||
| 578 | g_object_set_data_full (G_OBJECT (child)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((child)), (((GType) ((20) << (2)))))))), "text", g_strdup (text)g_strdup_inline (text), g_free); | |||
| 579 | g_object_set_data_full (G_OBJECT (child)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((child)), (((GType) ((20) << (2)))))))), "emoji-data", | |||
| 580 | g_variant_ref (emoji_data), (GDestroyNotify)g_variant_unref); | |||
| 581 | ctk_style_context_add_class (ctk_widget_get_style_context (child), "emoji-completion-row"); | |||
| 582 | ||||
| 583 | ctk_list_box_insert (CTK_LIST_BOX (list)((((CtkListBox*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((list)), ((ctk_list_box_get_type ())))))), child, -1); | |||
| 584 | } | |||
| 585 | ||||
| 586 | static int | |||
| 587 | populate_completion (CtkEmojiCompletion *completion, | |||
| 588 | const char *text, | |||
| 589 | guint offset) | |||
| 590 | { | |||
| 591 | GList *children, *l; | |||
| 592 | guint n_matches; | |||
| 593 | guint n_added; | |||
| 594 | GVariantIter iter; | |||
| 595 | GVariant *item; | |||
| 596 | ||||
| 597 | g_free (completion->text); | |||
| 598 | completion->text = g_strdup (text)g_strdup_inline (text); | |||
| ||||
| 599 | completion->length = g_utf8_strlen (text, -1); | |||
| 600 | completion->offset = offset; | |||
| 601 | ||||
| 602 | children = ctk_container_get_children (CTK_CONTAINER (completion->list)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->list)), ((ctk_container_get_type ()))))))); | |||
| 603 | for (l = children; l; l = l->next) | |||
| 604 | ctk_widget_destroy (CTK_WIDGET (l->data)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((l->data)), ((ctk_widget_get_type ()))))))); | |||
| 605 | g_list_free (children); | |||
| 606 | ||||
| 607 | completion->active = NULL((void*)0); | |||
| 608 | ||||
| 609 | n_matches = 0; | |||
| 610 | n_added = 0; | |||
| 611 | g_variant_iter_init (&iter, completion->data); | |||
| 612 | while ((item = g_variant_iter_next_value (&iter))) | |||
| 613 | { | |||
| 614 | const char *shortname; | |||
| 615 | ||||
| 616 | g_variant_get_child (item, 2, "&s", &shortname); | |||
| 617 | if (g_str_has_prefix (shortname, text)(__builtin_constant_p (text)? __extension__ ({ const char * const __str = (shortname); const char * const __prefix = (text); gboolean __result = (0); if (__str == ((void*)0) || __prefix == ((void *)0)) __result = (g_str_has_prefix) (__str, __prefix); else { const size_t __str_len = strlen (((__str) + !(__str))); const size_t __prefix_len = strlen (((__prefix) + !(__prefix))); if (__str_len >= __prefix_len) __result = memcmp (((__str) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len) == 0; } __result; }) : (g_str_has_prefix) (shortname, text) )) | |||
| 618 | { | |||
| 619 | n_matches++; | |||
| 620 | ||||
| 621 | if (n_matches > offset && n_added < MAX_ROWS5) | |||
| 622 | { | |||
| 623 | add_emoji (completion->list, item, completion); | |||
| 624 | n_added++; | |||
| 625 | } | |||
| 626 | } | |||
| 627 | } | |||
| 628 | ||||
| 629 | completion->n_matches = n_matches; | |||
| 630 | ||||
| 631 | if (n_added > 0) | |||
| 632 | { | |||
| 633 | GList *children; | |||
| 634 | ||||
| 635 | children = ctk_container_get_children (CTK_CONTAINER (completion->list)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion->list)), ((ctk_container_get_type ()))))))); | |||
| 636 | completion->active = children->data; | |||
| 637 | g_list_free (children); | |||
| 638 | ctk_widget_set_state_flags (completion->active, CTK_STATE_FLAG_PRELIGHT, FALSE(0)); | |||
| 639 | } | |||
| 640 | ||||
| 641 | return n_added; | |||
| 642 | } | |||
| 643 | ||||
| 644 | static void | |||
| 645 | long_pressed_cb (CtkGesture *gesture G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
| 646 | double x G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
| 647 | double y, | |||
| 648 | gpointer data) | |||
| 649 | { | |||
| 650 | CtkEmojiCompletion *completion = data; | |||
| 651 | CtkWidget *row; | |||
| 652 | ||||
| 653 | row = CTK_WIDGET (ctk_list_box_get_row_at_y (CTK_LIST_BOX (completion->list), y))((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((ctk_list_box_get_row_at_y (((((CtkListBox*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((completion->list)), ((ctk_list_box_get_type ())))))), y))), ((ctk_widget_get_type ())))))); | |||
| 654 | if (!row) | |||
| 655 | return; | |||
| 656 | ||||
| 657 | show_variations (completion, row, TRUE(!(0))); | |||
| 658 | } | |||
| 659 | ||||
| 660 | static void | |||
| 661 | ctk_emoji_completion_init (CtkEmojiCompletion *completion) | |||
| 662 | { | |||
| 663 | GBytes *bytes = NULL((void*)0); | |||
| 664 | ||||
| 665 | ctk_widget_init_template (CTK_WIDGET (completion)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion)), ((ctk_widget_get_type ()))))))); | |||
| 666 | ||||
| 667 | bytes = g_resources_lookup_data ("/org/ctk/libctk/emoji/emoji.data", 0, NULL((void*)0)); | |||
| 668 | completion->data = g_variant_ref_sink (g_variant_new_from_bytes (G_VARIANT_TYPE ("a(auss)")(g_variant_type_checked_ (("a(auss)"))), bytes, TRUE(!(0)))); | |||
| 669 | g_bytes_unref (bytes); | |||
| 670 | ||||
| 671 | completion->long_press = ctk_gesture_long_press_new (completion->list); | |||
| 672 | g_signal_connect (completion->long_press, "pressed", G_CALLBACK (long_pressed_cb), completion)g_signal_connect_data ((completion->long_press), ("pressed" ), (((GCallback) (long_pressed_cb))), (completion), ((void*)0 ), (GConnectFlags) 0); | |||
| 673 | } | |||
| 674 | ||||
| 675 | static void | |||
| 676 | ctk_emoji_completion_class_init (CtkEmojiCompletionClass *klass) | |||
| 677 | { | |||
| 678 | GObjectClass *object_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((klass)), (((GType) ((20) << (2)))))))); | |||
| 679 | CtkWidgetClass *widget_class = CTK_WIDGET_CLASS (klass)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((klass)), ((ctk_widget_get_type ())))))); | |||
| 680 | ||||
| 681 | object_class->finalize = ctk_emoji_completion_finalize; | |||
| 682 | ||||
| 683 | ctk_widget_class_set_template_from_resource (widget_class, "/org/ctk/libctk/ui/ctkemojicompletion.ui"); | |||
| 684 | ||||
| 685 | ctk_widget_class_bind_template_child (widget_class, CtkEmojiCompletion, list)ctk_widget_class_bind_template_child_full (widget_class, "list" , (0), ((glong) __builtin_offsetof(CtkEmojiCompletion, list)) ); | |||
| 686 | ||||
| 687 | ctk_widget_class_bind_template_callback (widget_class, row_activated)ctk_widget_class_bind_template_callback_full (((((CtkWidgetClass *) (void *) g_type_check_class_cast ((GTypeClass*) ((widget_class )), ((ctk_widget_get_type ())))))), "row_activated", ((GCallback ) (row_activated))); | |||
| 688 | } | |||
| 689 | ||||
| 690 | CtkWidget * | |||
| 691 | ctk_emoji_completion_new (CtkEntry *entry) | |||
| 692 | { | |||
| 693 | CtkEmojiCompletion *completion; | |||
| 694 | ||||
| 695 | completion = CTK_EMOJI_COMPLETION (g_object_new (CTK_TYPE_EMOJI_COMPLETION,((((CtkEmojiCompletion*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((g_object_new ((ctk_emoji_completion_get_type ()), "relative-to", entry, ((void*)0)))), ((ctk_emoji_completion_get_type ())))))) | |||
| 696 | "relative-to", entry,((((CtkEmojiCompletion*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((g_object_new ((ctk_emoji_completion_get_type ()), "relative-to", entry, ((void*)0)))), ((ctk_emoji_completion_get_type ())))))) | |||
| 697 | NULL))((((CtkEmojiCompletion*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((g_object_new ((ctk_emoji_completion_get_type ()), "relative-to", entry, ((void*)0)))), ((ctk_emoji_completion_get_type ())))))); | |||
| 698 | ||||
| 699 | connect_signals (completion, entry); | |||
| 700 | ||||
| 701 | return CTK_WIDGET (completion)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((completion)), ((ctk_widget_get_type ())))))); | |||
| 702 | } |