1 | /* GTK - The GIMP Toolkit |
2 | * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald |
3 | * |
4 | * This library is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU Lesser General Public |
6 | * License as published by the Free Software Foundation; either |
7 | * version 2 of the License, or (at your option) any later version. |
8 | * |
9 | * This library is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | * Lesser General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU Lesser General Public |
15 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. |
16 | */ |
17 | |
18 | /* |
19 | * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS |
20 | * file for a list of people on the GTK+ Team. See the ChangeLog |
21 | * files for a list of changes. These files are distributed with |
22 | * GTK+ at ftp://ftp.gtk.org/pub/gtk/. |
23 | */ |
24 | |
25 | #ifndef __GTK_WIDGET_PRIVATE_H__ |
26 | #define __GTK_WIDGET_PRIVATE_H__ |
27 | |
28 | #include "gtkwidget.h" |
29 | |
30 | #include "gtkactionmuxerprivate.h" |
31 | #include "gtkatcontextprivate.h" |
32 | #include "gtkcsstypesprivate.h" |
33 | #include "gtkeventcontrollerprivate.h" |
34 | #include "gtklistlistmodelprivate.h" |
35 | #include "gtkrootprivate.h" |
36 | #include "gtksizerequestcacheprivate.h" |
37 | #include "gtkwindowprivate.h" |
38 | #include "gtkgesture.h" |
39 | |
40 | #include "gsk/gskrendernodeprivate.h" |
41 | |
42 | G_BEGIN_DECLS |
43 | |
44 | typedef gboolean (*GtkSurfaceTransformChangedCallback) (GtkWidget *widget, |
45 | const graphene_matrix_t *surface_transform, |
46 | gpointer user_data); |
47 | |
48 | #define GTK_STATE_FLAGS_BITS 15 |
49 | |
50 | typedef struct _GtkWidgetSurfaceTransformData |
51 | { |
52 | GtkWidget *tracked_parent; |
53 | guint parent_surface_transform_changed_id; |
54 | |
55 | gboolean cached_surface_transform_valid; |
56 | |
57 | graphene_matrix_t cached_surface_transform; |
58 | GList *callbacks; |
59 | } GtkWidgetSurfaceTransformData; |
60 | |
61 | struct _GtkWidgetPrivate |
62 | { |
63 | /* The state of the widget. Needs to be able to hold all GtkStateFlags bits |
64 | * (defined in "gtkenums.h"). |
65 | */ |
66 | guint state_flags : GTK_STATE_FLAGS_BITS; |
67 | |
68 | guint direction : 2; |
69 | |
70 | guint in_destruction : 1; |
71 | guint realized : 1; |
72 | guint mapped : 1; |
73 | guint visible : 1; |
74 | guint sensitive : 1; |
75 | guint can_focus : 1; |
76 | guint focusable : 1; |
77 | guint has_focus : 1; |
78 | guint focus_on_click : 1; |
79 | guint has_default : 1; |
80 | guint receives_default : 1; |
81 | guint has_grab : 1; |
82 | guint child_visible : 1; |
83 | guint can_target : 1; |
84 | |
85 | /* Queue-resize related flags */ |
86 | guint resize_needed : 1; /* queue_resize() has been called but no get_preferred_size() yet */ |
87 | guint alloc_needed : 1; /* this widget needs a size_allocate() call */ |
88 | guint alloc_needed_on_child : 1; /* 0 or more children - or this widget - need a size_allocate() call */ |
89 | |
90 | /* Queue-draw related flags */ |
91 | guint draw_needed : 1; |
92 | /* Expand-related flags */ |
93 | guint need_compute_expand : 1; /* Need to recompute computed_[hv]_expand */ |
94 | guint computed_hexpand : 1; /* computed results (composite of child flags) */ |
95 | guint computed_vexpand : 1; |
96 | guint hexpand : 1; /* application-forced expand */ |
97 | guint vexpand : 1; |
98 | guint hexpand_set : 1; /* whether to use application-forced */ |
99 | guint vexpand_set : 1; /* instead of computing from children */ |
100 | guint has_tooltip : 1; |
101 | |
102 | /* SizeGroup related flags */ |
103 | guint have_size_groups : 1; |
104 | |
105 | /* Alignment */ |
106 | guint halign : 4; |
107 | guint valign : 4; |
108 | |
109 | guint user_alpha : 8; |
110 | |
111 | GtkOverflow overflow; |
112 | |
113 | #ifdef G_ENABLE_CONSISTENCY_CHECKS |
114 | /* Number of gtk_widget_push_verify_invariants () */ |
115 | guint8 verifying_invariants_count; |
116 | #endif |
117 | |
118 | int width_request; |
119 | int height_request; |
120 | |
121 | /* Animations and other things to update on clock ticks */ |
122 | guint clock_tick_id; |
123 | guint8 n_active; |
124 | GList *tick_callbacks; |
125 | |
126 | void (* resize_func) (GtkWidget *); |
127 | GtkBorder margin; |
128 | |
129 | /* Surface relative transform updates callbacks */ |
130 | GtkWidgetSurfaceTransformData *surface_transform_data; |
131 | |
132 | /* The widget's name. If the widget does not have a name |
133 | * (the name is NULL), then its name (as returned by |
134 | * "gtk_widget_get_name") is its class's name. |
135 | * Among other things, the widget name is used to determine |
136 | * the style to use for a widget. |
137 | */ |
138 | char *name; |
139 | |
140 | /* The root this widget belongs to or %NULL if widget is not |
141 | * rooted or is a GtkRoot itself. |
142 | */ |
143 | GtkRoot *root; |
144 | |
145 | /* The style for the widget. The style contains the |
146 | * colors the widget should be drawn in for each state |
147 | * along with graphics contexts used to draw with and |
148 | * the font to use for text. |
149 | */ |
150 | GtkCssNode *cssnode; |
151 | GtkStyleContext *context; |
152 | |
153 | /* The widget's allocated size */ |
154 | GskTransform *allocated_transform; |
155 | int allocated_width; |
156 | int allocated_height; |
157 | int allocated_size_baseline; |
158 | |
159 | int width; |
160 | int height; |
161 | int baseline; |
162 | GskTransform *transform; |
163 | |
164 | /* The widget's requested sizes */ |
165 | SizeRequestCache requests; |
166 | |
167 | /* The render node we draw or %NULL if not yet created.*/ |
168 | GskRenderNode *render_node; |
169 | |
170 | /* The layout manager, or %NULL */ |
171 | GtkLayoutManager *layout_manager; |
172 | |
173 | GSList *paintables; |
174 | |
175 | GList *event_controllers; |
176 | |
177 | /* Widget tree */ |
178 | GtkWidget *parent; |
179 | GtkWidget *prev_sibling; |
180 | GtkWidget *next_sibling; |
181 | GtkWidget *first_child; |
182 | GtkWidget *last_child; |
183 | |
184 | /* only created on-demand */ |
185 | GtkListListModel *children_observer; |
186 | GtkListListModel *controller_observer; |
187 | GtkActionMuxer *muxer; |
188 | |
189 | GtkWidget *focus_child; |
190 | |
191 | /* Pointer cursor */ |
192 | GdkCursor *cursor; |
193 | |
194 | /* Tooltip */ |
195 | char *tooltip_markup; |
196 | char *tooltip_text; |
197 | |
198 | /* Accessibility */ |
199 | GtkATContext *at_context; |
200 | GtkAccessibleRole accessible_role; |
201 | }; |
202 | |
203 | typedef struct |
204 | { |
205 | GBytes *data; |
206 | GSList *children; |
207 | GtkBuilderScope *scope; |
208 | } GtkWidgetTemplate; |
209 | |
210 | struct _GtkWidgetClassPrivate |
211 | { |
212 | GtkWidgetTemplate *template; |
213 | GListStore *shortcuts; |
214 | GType layout_manager_type; |
215 | GtkWidgetAction *actions; |
216 | GtkAccessibleRole accessible_role; |
217 | guint activate_signal; |
218 | GQuark css_name; |
219 | }; |
220 | |
221 | void gtk_widget_root (GtkWidget *widget); |
222 | void gtk_widget_unroot (GtkWidget *widget); |
223 | GtkCssNode * gtk_widget_get_css_node (GtkWidget *widget); |
224 | void _gtk_widget_set_visible_flag (GtkWidget *widget, |
225 | gboolean visible); |
226 | gboolean _gtk_widget_get_alloc_needed (GtkWidget *widget); |
227 | gboolean gtk_widget_needs_allocate (GtkWidget *widget); |
228 | void gtk_widget_ensure_resize (GtkWidget *widget); |
229 | void gtk_widget_ensure_allocate (GtkWidget *widget); |
230 | void _gtk_widget_scale_changed (GtkWidget *widget); |
231 | |
232 | GdkSurface * gtk_widget_get_surface (GtkWidget *widget); |
233 | |
234 | void gtk_widget_render (GtkWidget *widget, |
235 | GdkSurface *surface, |
236 | const cairo_region_t *region); |
237 | |
238 | void _gtk_widget_add_sizegroup (GtkWidget *widget, |
239 | gpointer group); |
240 | void _gtk_widget_remove_sizegroup (GtkWidget *widget, |
241 | gpointer group); |
242 | GSList *_gtk_widget_get_sizegroups (GtkWidget *widget); |
243 | |
244 | void _gtk_widget_set_has_default (GtkWidget *widget, |
245 | gboolean has_default); |
246 | void _gtk_widget_set_has_grab (GtkWidget *widget, |
247 | gboolean has_grab); |
248 | |
249 | gboolean gtk_widget_has_grab (GtkWidget *widget); |
250 | |
251 | void _gtk_widget_propagate_display_changed (GtkWidget *widget, |
252 | GdkDisplay *previous_display); |
253 | |
254 | void _gtk_widget_set_device_surface (GtkWidget *widget, |
255 | GdkDevice *device, |
256 | GdkSurface *pointer_window); |
257 | void _gtk_widget_synthesize_crossing (GtkWidget *from, |
258 | GtkWidget *to, |
259 | GdkDevice *device, |
260 | GdkCrossingMode mode); |
261 | |
262 | GtkStyleContext * _gtk_widget_peek_style_context (GtkWidget *widget); |
263 | |
264 | gboolean _gtk_widget_captured_event (GtkWidget *widget, |
265 | GdkEvent *event, |
266 | GtkWidget *target); |
267 | |
268 | void gtk_widget_css_changed (GtkWidget *widget, |
269 | GtkCssStyleChange *change); |
270 | void gtk_widget_system_setting_changed (GtkWidget *widget, |
271 | GtkSystemSetting setting); |
272 | void gtk_system_setting_changed (GdkDisplay *display, |
273 | GtkSystemSetting setting); |
274 | |
275 | void _gtk_widget_update_parent_muxer (GtkWidget *widget); |
276 | GtkActionMuxer * _gtk_widget_get_action_muxer (GtkWidget *widget, |
277 | gboolean create); |
278 | |
279 | gboolean gtk_widget_has_tick_callback (GtkWidget *widget); |
280 | |
281 | gboolean gtk_widget_has_size_request (GtkWidget *widget); |
282 | |
283 | void gtk_widget_reset_controllers (GtkWidget *widget); |
284 | |
285 | GtkEventController **gtk_widget_list_controllers (GtkWidget *widget, |
286 | GtkPropagationPhase phase, |
287 | guint *out_n_controllers); |
288 | |
289 | gboolean gtk_widget_query_tooltip (GtkWidget *widget, |
290 | int x, |
291 | int y, |
292 | gboolean keyboard_mode, |
293 | GtkTooltip *tooltip); |
294 | |
295 | void gtk_widget_snapshot (GtkWidget *widget, |
296 | GtkSnapshot *snapshot); |
297 | void gtk_widget_adjust_size_request (GtkWidget *widget, |
298 | GtkOrientation orientation, |
299 | int *minimum_size, |
300 | int *natural_size); |
301 | void gtk_widget_adjust_baseline_request (GtkWidget *widget, |
302 | int *minimum_baseline, |
303 | int *natural_baseline); |
304 | |
305 | typedef void (*GtkCallback) (GtkWidget *widget, |
306 | gpointer data); |
307 | |
308 | void gtk_widget_forall (GtkWidget *widget, |
309 | GtkCallback callback, |
310 | gpointer user_data); |
311 | |
312 | void gtk_widget_focus_sort (GtkWidget *widget, |
313 | GtkDirectionType direction, |
314 | GPtrArray *focus_order); |
315 | gboolean gtk_widget_focus_move (GtkWidget *widget, |
316 | GtkDirectionType direction); |
317 | void gtk_widget_set_has_focus (GtkWidget *widget, |
318 | gboolean has_focus); |
319 | void gtk_widget_get_surface_allocation (GtkWidget *widget, |
320 | GtkAllocation *allocation); |
321 | |
322 | |
323 | GtkWidget * gtk_widget_common_ancestor (GtkWidget *widget_a, |
324 | GtkWidget *widget_b); |
325 | |
326 | void gtk_widget_set_active_state (GtkWidget *widget, |
327 | gboolean active); |
328 | |
329 | void gtk_widget_cancel_event_sequence (GtkWidget *widget, |
330 | GtkGesture *gesture, |
331 | GdkEventSequence *sequence, |
332 | GtkEventSequenceState state); |
333 | gboolean gtk_widget_event (GtkWidget *widget, |
334 | GdkEvent *event, |
335 | GtkWidget *target); |
336 | gboolean gtk_widget_run_controllers (GtkWidget *widget, |
337 | GdkEvent *event, |
338 | GtkWidget *target, |
339 | double x, |
340 | double y, |
341 | GtkPropagationPhase phase); |
342 | void gtk_widget_handle_crossing (GtkWidget *widget, |
343 | const GtkCrossingData *crossing, |
344 | double x, |
345 | double y); |
346 | |
347 | |
348 | guint gtk_widget_add_surface_transform_changed_callback (GtkWidget *widget, |
349 | GtkSurfaceTransformChangedCallback callback, |
350 | gpointer user_data, |
351 | GDestroyNotify notify); |
352 | |
353 | void gtk_widget_remove_surface_transform_changed_callback (GtkWidget *widget, |
354 | guint id); |
355 | |
356 | gboolean gtk_widget_can_activate (GtkWidget *widget); |
357 | |
358 | /* focus vfuncs for non-focusable containers with focusable children */ |
359 | gboolean gtk_widget_grab_focus_child (GtkWidget *widget); |
360 | gboolean gtk_widget_focus_child (GtkWidget *widget, |
361 | GtkDirectionType direction); |
362 | /* focus vfuncs for focusable widgets with children that don't receive focus */ |
363 | gboolean gtk_widget_grab_focus_self (GtkWidget *widget); |
364 | gboolean gtk_widget_focus_self (GtkWidget *widget, |
365 | GtkDirectionType direction); |
366 | |
367 | void gtk_widget_update_orientation (GtkWidget *widget, |
368 | GtkOrientation orientation); |
369 | |
370 | void gtk_widget_realize_at_context (GtkWidget *widget); |
371 | void gtk_widget_unrealize_at_context (GtkWidget *widget); |
372 | |
373 | gboolean gtk_widget_update_pango_context (GtkWidget *widget, |
374 | PangoContext *context, |
375 | GtkTextDirection direction); |
376 | |
377 | /* inline getters */ |
378 | |
379 | static inline GtkWidget * |
380 | _gtk_widget_get_parent (GtkWidget *widget) |
381 | { |
382 | return widget->priv->parent; |
383 | } |
384 | |
385 | static inline GtkWidget * |
386 | _gtk_widget_get_focus_child (GtkWidget *widget) |
387 | { |
388 | return widget->priv->focus_child; |
389 | } |
390 | |
391 | static inline gboolean |
392 | _gtk_widget_get_visible (GtkWidget *widget) |
393 | { |
394 | return widget->priv->visible; |
395 | } |
396 | |
397 | static inline gboolean |
398 | _gtk_widget_get_child_visible (GtkWidget *widget) |
399 | { |
400 | return widget->priv->child_visible; |
401 | } |
402 | |
403 | static inline gboolean |
404 | _gtk_widget_get_mapped (GtkWidget *widget) |
405 | { |
406 | return widget->priv->mapped; |
407 | } |
408 | |
409 | static inline gboolean |
410 | _gtk_widget_get_realized (GtkWidget *widget) |
411 | { |
412 | return widget->priv->realized; |
413 | } |
414 | |
415 | static inline GtkStateFlags |
416 | _gtk_widget_get_state_flags (GtkWidget *widget) |
417 | { |
418 | return widget->priv->state_flags; |
419 | } |
420 | |
421 | extern GtkTextDirection gtk_default_direction; |
422 | |
423 | static inline GtkTextDirection |
424 | _gtk_widget_get_direction (GtkWidget *widget) |
425 | { |
426 | if (widget->priv->direction == GTK_TEXT_DIR_NONE) |
427 | return gtk_default_direction; |
428 | else |
429 | return widget->priv->direction; |
430 | } |
431 | |
432 | static inline GtkRoot * |
433 | _gtk_widget_get_root (GtkWidget *widget) |
434 | { |
435 | return widget->priv->root; |
436 | } |
437 | |
438 | static inline GdkDisplay * |
439 | _gtk_widget_get_display (GtkWidget *widget) |
440 | { |
441 | GtkRoot *root = _gtk_widget_get_root (widget); |
442 | |
443 | if (root == NULL) |
444 | return gdk_display_get_default (); |
445 | |
446 | return gtk_root_get_display (root); |
447 | } |
448 | |
449 | static inline GtkStyleContext * |
450 | _gtk_widget_get_style_context (GtkWidget *widget) |
451 | { |
452 | if (G_LIKELY (widget->priv->context)) |
453 | return widget->priv->context; |
454 | |
455 | return gtk_widget_get_style_context (widget); |
456 | } |
457 | |
458 | static inline gpointer |
459 | _gtk_widget_peek_request_cache (GtkWidget *widget) |
460 | { |
461 | return &widget->priv->requests; |
462 | } |
463 | |
464 | static inline GtkWidget * |
465 | _gtk_widget_get_prev_sibling (GtkWidget *widget) |
466 | { |
467 | return widget->priv->prev_sibling; |
468 | } |
469 | |
470 | static inline GtkWidget * |
471 | _gtk_widget_get_next_sibling (GtkWidget *widget) |
472 | { |
473 | return widget->priv->next_sibling; |
474 | } |
475 | |
476 | static inline GtkWidget * |
477 | _gtk_widget_get_first_child (GtkWidget *widget) |
478 | { |
479 | return widget->priv->first_child; |
480 | } |
481 | |
482 | static inline GtkWidget * |
483 | _gtk_widget_get_last_child (GtkWidget *widget) |
484 | { |
485 | return widget->priv->last_child; |
486 | } |
487 | |
488 | static inline gboolean |
489 | _gtk_widget_is_sensitive (GtkWidget *widget) |
490 | { |
491 | return !(widget->priv->state_flags & GTK_STATE_FLAG_INSENSITIVE); |
492 | } |
493 | |
494 | G_END_DECLS |
495 | |
496 | #endif /* __GTK_WIDGET_PRIVATE_H__ */ |
497 | |