1 | /* |
2 | * Copyright (c) 2014 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 | #include <glib/gi18n-lib.h> |
20 | |
21 | #include "misc-info.h" |
22 | |
23 | #include "measuregraph.h" |
24 | #include "window.h" |
25 | #include "type-info.h" |
26 | |
27 | #include "gtktypebuiltins.h" |
28 | #include "gtktreeview.h" |
29 | #include "gtkbuildable.h" |
30 | #include "gtklabel.h" |
31 | #include "gtkframe.h" |
32 | #include "gtkbutton.h" |
33 | #include "gtkmenubutton.h" |
34 | #include "gtkwidgetprivate.h" |
35 | #include "gtkbinlayout.h" |
36 | |
37 | |
38 | struct _GtkInspectorMiscInfo |
39 | { |
40 | GtkWidget parent; |
41 | |
42 | GObject *object; |
43 | |
44 | GtkWidget *swin; |
45 | GtkWidget *address; |
46 | GtkWidget *type; |
47 | GtkWidget *type_popover; |
48 | GtkWidget *refcount_row; |
49 | GtkWidget *refcount; |
50 | GtkWidget *state_row; |
51 | GtkWidget *state; |
52 | GtkWidget *direction_row; |
53 | GtkWidget *direction; |
54 | GtkWidget *buildable_id_row; |
55 | GtkWidget *buildable_id; |
56 | GtkWidget *mnemonic_label_row; |
57 | GtkWidget *mnemonic_label; |
58 | GtkWidget *request_mode_row; |
59 | GtkWidget *request_mode; |
60 | GtkWidget *measure_row; |
61 | GtkWidget *measure_expand_toggle; |
62 | GtkWidget *measure_picture; |
63 | GdkPaintable *measure_graph; |
64 | GtkWidget *allocated_size_row; |
65 | GtkWidget *allocated_size; |
66 | GtkWidget *baseline_row; |
67 | GtkWidget *baseline; |
68 | GtkWidget *surface_row; |
69 | GtkWidget *surface; |
70 | GtkWidget *surface_button; |
71 | GtkWidget *renderer_row; |
72 | GtkWidget *renderer; |
73 | GtkWidget *renderer_button; |
74 | GtkWidget *frame_clock_row; |
75 | GtkWidget *frame_clock; |
76 | GtkWidget *frame_clock_button; |
77 | GtkWidget *tick_callback_row; |
78 | GtkWidget *tick_callback; |
79 | GtkWidget *framerate_row; |
80 | GtkWidget *framerate; |
81 | GtkWidget *framecount_row; |
82 | GtkWidget *framecount; |
83 | GtkWidget *mapped_row; |
84 | GtkWidget *mapped; |
85 | GtkWidget *realized_row; |
86 | GtkWidget *realized; |
87 | GtkWidget *is_toplevel_row; |
88 | GtkWidget *is_toplevel; |
89 | GtkWidget *child_visible_row; |
90 | GtkWidget *child_visible; |
91 | |
92 | guint update_source_id; |
93 | gint64 last_frame; |
94 | }; |
95 | |
96 | typedef struct _GtkInspectorMiscInfoClass |
97 | { |
98 | GtkWidgetClass parent_class; |
99 | } GtkInspectorMiscInfoClass; |
100 | |
101 | G_DEFINE_TYPE (GtkInspectorMiscInfo, gtk_inspector_misc_info, GTK_TYPE_WIDGET) |
102 | |
103 | static char * |
104 | format_state_flags (GtkStateFlags state) |
105 | { |
106 | GFlagsClass *fclass; |
107 | GString *str; |
108 | int i; |
109 | |
110 | str = g_string_new (init: "" ); |
111 | |
112 | if (state) |
113 | { |
114 | fclass = g_type_class_ref (type: GTK_TYPE_STATE_FLAGS); |
115 | for (i = 0; i < fclass->n_values; i++) |
116 | { |
117 | if (state & fclass->values[i].value) |
118 | { |
119 | if (str->len) |
120 | g_string_append (string: str, val: " | " ); |
121 | g_string_append (string: str, val: fclass->values[i].value_nick); |
122 | } |
123 | } |
124 | g_type_class_unref (g_class: fclass); |
125 | } |
126 | else |
127 | g_string_append (string: str, val: "normal" ); |
128 | |
129 | return g_string_free (string: str, FALSE); |
130 | } |
131 | |
132 | static void |
133 | state_flags_changed (GtkWidget *w, GtkStateFlags old_flags, GtkInspectorMiscInfo *sl) |
134 | { |
135 | char *s; |
136 | |
137 | s = format_state_flags (state: gtk_widget_get_state_flags (widget: w)); |
138 | gtk_label_set_label (GTK_LABEL (sl->state), str: s); |
139 | g_free (mem: s); |
140 | } |
141 | |
142 | static void |
143 | update_allocation (GtkWidget *w, |
144 | GtkInspectorMiscInfo *sl) |
145 | { |
146 | GtkAllocation alloc; |
147 | char *size_label; |
148 | GEnumClass *class; |
149 | GEnumValue *value; |
150 | |
151 | gtk_widget_get_allocation (widget: w, allocation: &alloc); |
152 | size_label = g_strdup_printf (format: "%d × %d +%d +%d" , |
153 | alloc.width, alloc.height, |
154 | alloc.x, alloc.y); |
155 | |
156 | gtk_label_set_label (GTK_LABEL (sl->allocated_size), str: size_label); |
157 | g_free (mem: size_label); |
158 | |
159 | size_label = g_strdup_printf (format: "%d" , gtk_widget_get_allocated_baseline (widget: w)); |
160 | gtk_label_set_label (GTK_LABEL (sl->baseline), str: size_label); |
161 | g_free (mem: size_label); |
162 | |
163 | class = G_ENUM_CLASS (g_type_class_ref (GTK_TYPE_SIZE_REQUEST_MODE)); |
164 | value = g_enum_get_value (enum_class: class, value: gtk_widget_get_request_mode (widget: w)); |
165 | gtk_label_set_label (GTK_LABEL (sl->request_mode), str: value->value_nick); |
166 | g_type_class_unref (g_class: class); |
167 | |
168 | gtk_inspector_measure_graph_measure (self: GTK_INSPECTOR_MEASURE_GRAPH (ptr: sl->measure_graph), widget: w); |
169 | } |
170 | |
171 | static void |
172 | disconnect_each_other (gpointer still_alive, |
173 | GObject *for_science) |
174 | { |
175 | if (GTK_INSPECTOR_IS_MISC_INFO (still_alive)) |
176 | { |
177 | GtkInspectorMiscInfo *self = GTK_INSPECTOR_MISC_INFO (still_alive); |
178 | self->object = NULL; |
179 | } |
180 | |
181 | g_signal_handlers_disconnect_matched (instance: still_alive, mask: G_SIGNAL_MATCH_DATA, signal_id: 0, detail: 0, NULL, NULL, data: for_science); |
182 | g_object_weak_unref (object: still_alive, notify: disconnect_each_other, data: for_science); |
183 | } |
184 | |
185 | static void |
186 | show_mnemonic_label (GtkWidget *button, GtkInspectorMiscInfo *sl) |
187 | { |
188 | GtkInspectorWindow *iw; |
189 | GtkWidget *widget; |
190 | |
191 | iw = GTK_INSPECTOR_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (sl), GTK_TYPE_INSPECTOR_WINDOW)); |
192 | |
193 | widget = g_object_get_data (G_OBJECT (button), key: "mnemonic-label" ); |
194 | if (widget) |
195 | gtk_inspector_window_push_object (iw, G_OBJECT (widget), kind: CHILD_KIND_OTHER, position: 0); |
196 | } |
197 | |
198 | static void |
199 | show_surface (GtkWidget *button, GtkInspectorMiscInfo *sl) |
200 | { |
201 | GtkInspectorWindow *iw; |
202 | GObject *surface; |
203 | |
204 | iw = GTK_INSPECTOR_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (sl), GTK_TYPE_INSPECTOR_WINDOW)); |
205 | |
206 | surface = (GObject *)gtk_native_get_surface (self: GTK_NATIVE (ptr: sl->object)); |
207 | if (surface) |
208 | gtk_inspector_window_push_object (iw, object: surface, kind: CHILD_KIND_OTHER, position: 0); |
209 | } |
210 | |
211 | static void |
212 | show_renderer (GtkWidget *button, GtkInspectorMiscInfo *sl) |
213 | { |
214 | GtkInspectorWindow *iw; |
215 | GObject *renderer; |
216 | |
217 | iw = GTK_INSPECTOR_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (sl), GTK_TYPE_INSPECTOR_WINDOW)); |
218 | |
219 | renderer = (GObject *)gtk_native_get_renderer (self: GTK_NATIVE (ptr: sl->object)); |
220 | if (renderer) |
221 | gtk_inspector_window_push_object (iw, object: renderer, kind: CHILD_KIND_OTHER, position: 0); |
222 | } |
223 | |
224 | static void |
225 | show_frame_clock (GtkWidget *button, GtkInspectorMiscInfo *sl) |
226 | { |
227 | GtkInspectorWindow *iw; |
228 | GObject *clock; |
229 | |
230 | iw = GTK_INSPECTOR_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (sl), GTK_TYPE_INSPECTOR_WINDOW)); |
231 | |
232 | clock = (GObject *)gtk_widget_get_frame_clock (GTK_WIDGET (sl->object)); |
233 | if (clock) |
234 | gtk_inspector_window_push_object (iw, object: clock, kind: CHILD_KIND_OTHER, position: 0); |
235 | } |
236 | |
237 | static void |
238 | update_surface (GtkInspectorMiscInfo *sl) |
239 | { |
240 | if (GTK_IS_NATIVE (ptr: sl->object)) |
241 | { |
242 | GObject *obj; |
243 | char *tmp; |
244 | |
245 | gtk_widget_show (widget: sl->surface_row); |
246 | |
247 | obj = (GObject *)gtk_native_get_surface (self: GTK_NATIVE (ptr: sl->object)); |
248 | tmp = g_strdup_printf (format: "%p" , obj); |
249 | gtk_label_set_label (GTK_LABEL (sl->surface), str: tmp); |
250 | g_free (mem: tmp); |
251 | } |
252 | else |
253 | { |
254 | gtk_widget_hide (widget: sl->surface_row); |
255 | } |
256 | } |
257 | |
258 | static void |
259 | update_renderer (GtkInspectorMiscInfo *sl) |
260 | { |
261 | if (GTK_IS_NATIVE (ptr: sl->object)) |
262 | { |
263 | GObject *obj; |
264 | char *tmp; |
265 | |
266 | gtk_widget_show (widget: sl->renderer_row); |
267 | |
268 | obj = (GObject *)gtk_native_get_surface (self: GTK_NATIVE (ptr: sl->object)); |
269 | tmp = g_strdup_printf (format: "%p" , obj); |
270 | gtk_label_set_label (GTK_LABEL (sl->renderer), str: tmp); |
271 | g_free (mem: tmp); |
272 | } |
273 | else |
274 | { |
275 | gtk_widget_hide (widget: sl->renderer_row); |
276 | } |
277 | } |
278 | |
279 | static void |
280 | update_frame_clock (GtkInspectorMiscInfo *sl) |
281 | { |
282 | if (GTK_IS_ROOT (ptr: sl->object)) |
283 | { |
284 | GObject *clock; |
285 | |
286 | gtk_widget_show (widget: sl->frame_clock_row); |
287 | |
288 | clock = (GObject *)gtk_widget_get_frame_clock (GTK_WIDGET (sl->object)); |
289 | if (clock) |
290 | { |
291 | char *tmp; |
292 | tmp = g_strdup_printf (format: "%p" , clock); |
293 | gtk_label_set_label (GTK_LABEL (sl->frame_clock), str: tmp); |
294 | g_free (mem: tmp); |
295 | gtk_widget_set_sensitive (widget: sl->frame_clock_button, TRUE); |
296 | } |
297 | else |
298 | { |
299 | gtk_label_set_label (GTK_LABEL (sl->frame_clock), str: "NULL" ); |
300 | gtk_widget_set_sensitive (widget: sl->frame_clock_button, FALSE); |
301 | } |
302 | } |
303 | else |
304 | { |
305 | gtk_widget_hide (widget: sl->frame_clock_row); |
306 | } |
307 | } |
308 | |
309 | static void |
310 | update_direction (GtkInspectorMiscInfo *sl) |
311 | { |
312 | GtkWidget *widget = GTK_WIDGET (sl->object); |
313 | |
314 | switch (widget->priv->direction) |
315 | { |
316 | case GTK_TEXT_DIR_LTR: |
317 | gtk_label_set_label (GTK_LABEL (sl->direction), str: "Left-to-Right" ); |
318 | break; |
319 | case GTK_TEXT_DIR_RTL: |
320 | gtk_label_set_label (GTK_LABEL (sl->direction), str: "Right-to-Left" ); |
321 | break; |
322 | case GTK_TEXT_DIR_NONE: |
323 | if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) |
324 | gtk_label_set_label (GTK_LABEL (sl->direction), str: "Left-to-Right (inherited)" ); |
325 | else |
326 | gtk_label_set_label (GTK_LABEL (sl->direction), str: "Right-to-Left (inherited)" ); |
327 | break; |
328 | default: |
329 | g_assert_not_reached (); |
330 | } |
331 | } |
332 | |
333 | static gboolean |
334 | update_info (gpointer data) |
335 | { |
336 | GtkInspectorMiscInfo *sl = data; |
337 | char *tmp; |
338 | GType gtype; |
339 | |
340 | tmp = g_strdup_printf (format: "%p" , sl->object); |
341 | gtk_label_set_text (GTK_LABEL (sl->address), str: tmp); |
342 | g_free (mem: tmp); |
343 | |
344 | gtype = G_TYPE_FROM_INSTANCE (sl->object); |
345 | |
346 | gtk_menu_button_set_label (GTK_MENU_BUTTON (sl->type), label: g_type_name (type: gtype)); |
347 | gtk_inspector_type_popover_set_gtype (self: GTK_INSPECTOR_TYPE_POPOVER (ptr: sl->type_popover), |
348 | gtype); |
349 | |
350 | if (G_IS_OBJECT (sl->object)) |
351 | { |
352 | tmp = g_strdup_printf (format: "%d" , sl->object->ref_count); |
353 | gtk_label_set_text (GTK_LABEL (sl->refcount), str: tmp); |
354 | g_free (mem: tmp); |
355 | } |
356 | |
357 | if (GTK_IS_WIDGET (sl->object)) |
358 | { |
359 | GtkWidget *child; |
360 | GList *list, *l; |
361 | |
362 | update_direction (sl); |
363 | |
364 | while ((child = gtk_widget_get_first_child (widget: sl->mnemonic_label))) |
365 | gtk_box_remove (GTK_BOX (sl->mnemonic_label), child); |
366 | |
367 | list = gtk_widget_list_mnemonic_labels (GTK_WIDGET (sl->object)); |
368 | for (l = list; l; l = l->next) |
369 | { |
370 | GtkWidget *button; |
371 | |
372 | tmp = g_strdup_printf (format: "%p (%s)" , l->data, g_type_name_from_instance (instance: (GTypeInstance*)l->data)); |
373 | button = gtk_button_new_with_label (label: tmp); |
374 | g_free (mem: tmp); |
375 | gtk_widget_show (widget: button); |
376 | gtk_box_append (GTK_BOX (sl->mnemonic_label), child: button); |
377 | g_object_set_data (G_OBJECT (button), key: "mnemonic-label" , data: l->data); |
378 | g_signal_connect (button, "clicked" , G_CALLBACK (show_mnemonic_label), sl); |
379 | } |
380 | g_list_free (list); |
381 | |
382 | gtk_widget_set_visible (widget: sl->tick_callback, visible: gtk_widget_has_tick_callback (GTK_WIDGET (sl->object))); |
383 | } |
384 | |
385 | update_surface (sl); |
386 | update_renderer (sl); |
387 | update_frame_clock (sl); |
388 | |
389 | if (GTK_IS_BUILDABLE (sl->object)) |
390 | { |
391 | gtk_label_set_text (GTK_LABEL (sl->buildable_id), |
392 | str: gtk_buildable_get_buildable_id (GTK_BUILDABLE (sl->object))); |
393 | } |
394 | |
395 | if (GDK_IS_FRAME_CLOCK (sl->object)) |
396 | { |
397 | GdkFrameClock *clock; |
398 | gint64 frame; |
399 | gint64 frame_time; |
400 | gint64 history_start; |
401 | gint64 history_len; |
402 | gint64 previous_frame_time; |
403 | GdkFrameTimings *previous_timings; |
404 | |
405 | clock = GDK_FRAME_CLOCK (sl->object); |
406 | frame = gdk_frame_clock_get_frame_counter (frame_clock: clock); |
407 | frame_time = gdk_frame_clock_get_frame_time (frame_clock: clock); |
408 | |
409 | tmp = g_strdup_printf (format: "%" G_GINT64_FORMAT, frame); |
410 | gtk_label_set_label (GTK_LABEL (sl->framecount), str: tmp); |
411 | g_free (mem: tmp); |
412 | |
413 | history_start = gdk_frame_clock_get_history_start (frame_clock: clock); |
414 | history_len = frame - history_start; |
415 | |
416 | if (history_len > 0 && sl->last_frame != frame) |
417 | { |
418 | previous_timings = gdk_frame_clock_get_timings (frame_clock: clock, frame_counter: history_start); |
419 | previous_frame_time = gdk_frame_timings_get_frame_time (timings: previous_timings); |
420 | tmp = g_strdup_printf (format: "%4.1f ⁄ s" , (G_USEC_PER_SEC * history_len) / (double) (frame_time - previous_frame_time)); |
421 | gtk_label_set_label (GTK_LABEL (sl->framerate), str: tmp); |
422 | g_free (mem: tmp); |
423 | } |
424 | else |
425 | { |
426 | gtk_label_set_label (GTK_LABEL (sl->framerate), str: "—" ); |
427 | } |
428 | |
429 | sl->last_frame = frame; |
430 | } |
431 | |
432 | return G_SOURCE_CONTINUE; |
433 | } |
434 | |
435 | static GdkContentProvider * |
436 | measure_picture_drag_prepare (GtkDragSource *source, |
437 | double x, |
438 | double y, |
439 | gpointer unused) |
440 | { |
441 | GtkWidget *picture; |
442 | GdkPaintable *measure_graph; |
443 | GdkTexture *texture; |
444 | |
445 | picture = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source)); |
446 | measure_graph = gtk_picture_get_paintable (self: GTK_PICTURE (ptr: picture)); |
447 | if (!GTK_IS_INSPECTOR_MEASURE_GRAPH (ptr: measure_graph)) |
448 | return NULL; |
449 | |
450 | texture = gtk_inspector_measure_graph_get_texture (self: GTK_INSPECTOR_MEASURE_GRAPH (ptr: measure_graph)); |
451 | if (texture == NULL) |
452 | return NULL; |
453 | |
454 | return gdk_content_provider_new_typed (GDK_TYPE_TEXTURE, texture); |
455 | } |
456 | |
457 | static void |
458 | update_measure_picture (GtkPicture *picture, |
459 | GtkToggleButton *toggle) |
460 | { |
461 | GdkPaintable *paintable = gtk_picture_get_paintable (self: picture); |
462 | |
463 | if (gtk_toggle_button_get_active (toggle_button: toggle) || |
464 | (gdk_paintable_get_intrinsic_width (paintable) <= 200 && |
465 | gdk_paintable_get_intrinsic_height (paintable) <= 100)) |
466 | { |
467 | gtk_picture_set_can_shrink (self: picture, FALSE); |
468 | gtk_widget_set_size_request (GTK_WIDGET (picture), width: -1, height: -1); |
469 | } |
470 | else |
471 | { |
472 | gtk_picture_set_can_shrink (self: picture, TRUE); |
473 | gtk_widget_set_size_request (GTK_WIDGET (picture), |
474 | width: -1, |
475 | MIN (100, 200 / gdk_paintable_get_intrinsic_aspect_ratio (paintable))); |
476 | } |
477 | } |
478 | |
479 | void |
480 | gtk_inspector_misc_info_set_object (GtkInspectorMiscInfo *sl, |
481 | GObject *object) |
482 | { |
483 | if (sl->object) |
484 | { |
485 | g_signal_handlers_disconnect_by_func (sl->object, state_flags_changed, sl); |
486 | disconnect_each_other (still_alive: sl->object, G_OBJECT (sl)); |
487 | disconnect_each_other (still_alive: sl, for_science: sl->object); |
488 | sl->object = NULL; |
489 | } |
490 | |
491 | gtk_widget_show (GTK_WIDGET (sl)); |
492 | |
493 | sl->object = object; |
494 | g_object_weak_ref (G_OBJECT (sl), notify: disconnect_each_other, data: object); |
495 | g_object_weak_ref (object, notify: disconnect_each_other, data: sl); |
496 | |
497 | if (GTK_IS_WIDGET (object)) |
498 | { |
499 | gtk_widget_show (widget: sl->refcount_row); |
500 | gtk_widget_show (widget: sl->state_row); |
501 | gtk_widget_show (widget: sl->direction_row); |
502 | gtk_widget_show (widget: sl->request_mode_row); |
503 | gtk_widget_show (widget: sl->measure_row); |
504 | gtk_widget_show (widget: sl->allocated_size_row); |
505 | gtk_widget_show (widget: sl->baseline_row); |
506 | gtk_widget_show (widget: sl->mnemonic_label_row); |
507 | gtk_widget_show (widget: sl->tick_callback_row); |
508 | gtk_widget_show (widget: sl->mapped_row); |
509 | gtk_widget_show (widget: sl->realized_row); |
510 | gtk_widget_show (widget: sl->is_toplevel_row); |
511 | gtk_widget_show (widget: sl->is_toplevel_row); |
512 | gtk_widget_show (widget: sl->frame_clock_row); |
513 | |
514 | g_signal_connect_object (instance: object, detailed_signal: "state-flags-changed" , G_CALLBACK (state_flags_changed), gobject: sl, connect_flags: 0); |
515 | state_flags_changed (GTK_WIDGET (sl->object), old_flags: 0, sl); |
516 | |
517 | update_allocation (GTK_WIDGET (sl->object), sl); |
518 | update_measure_picture (picture: GTK_PICTURE (ptr: sl->measure_picture), GTK_TOGGLE_BUTTON (sl->measure_expand_toggle)); |
519 | } |
520 | else |
521 | { |
522 | gtk_widget_hide (widget: sl->state_row); |
523 | gtk_widget_hide (widget: sl->direction_row); |
524 | gtk_widget_hide (widget: sl->request_mode_row); |
525 | gtk_widget_hide (widget: sl->measure_row); |
526 | gtk_inspector_measure_graph_clear (self: GTK_INSPECTOR_MEASURE_GRAPH (ptr: sl->measure_graph)); |
527 | gtk_widget_hide (widget: sl->mnemonic_label_row); |
528 | gtk_widget_hide (widget: sl->allocated_size_row); |
529 | gtk_widget_hide (widget: sl->baseline_row); |
530 | gtk_widget_hide (widget: sl->tick_callback_row); |
531 | gtk_widget_hide (widget: sl->mapped_row); |
532 | gtk_widget_hide (widget: sl->realized_row); |
533 | gtk_widget_hide (widget: sl->is_toplevel_row); |
534 | gtk_widget_hide (widget: sl->child_visible_row); |
535 | gtk_widget_hide (widget: sl->frame_clock_row); |
536 | } |
537 | |
538 | if (GTK_IS_BUILDABLE (object)) |
539 | { |
540 | gtk_widget_show (widget: sl->buildable_id_row); |
541 | } |
542 | else |
543 | { |
544 | gtk_widget_hide (widget: sl->buildable_id_row); |
545 | } |
546 | |
547 | if (GDK_IS_FRAME_CLOCK (object)) |
548 | { |
549 | gtk_widget_show (widget: sl->framecount_row); |
550 | gtk_widget_show (widget: sl->framerate_row); |
551 | } |
552 | else |
553 | { |
554 | gtk_widget_hide (widget: sl->framecount_row); |
555 | gtk_widget_hide (widget: sl->framerate_row); |
556 | } |
557 | |
558 | update_info (data: sl); |
559 | } |
560 | |
561 | static void |
562 | gtk_inspector_misc_info_init (GtkInspectorMiscInfo *sl) |
563 | { |
564 | gtk_widget_init_template (GTK_WIDGET (sl)); |
565 | |
566 | sl->type_popover = g_object_new (GTK_TYPE_INSPECTOR_TYPE_POPOVER, NULL); |
567 | gtk_menu_button_set_popover (GTK_MENU_BUTTON (sl->type), |
568 | popover: sl->type_popover); |
569 | |
570 | } |
571 | |
572 | static void |
573 | map (GtkWidget *widget) |
574 | { |
575 | GtkInspectorMiscInfo *sl = GTK_INSPECTOR_MISC_INFO (widget); |
576 | |
577 | GTK_WIDGET_CLASS (gtk_inspector_misc_info_parent_class)->map (widget); |
578 | |
579 | sl->update_source_id = g_timeout_add_seconds (interval: 1, function: update_info, data: sl); |
580 | update_info (data: sl); |
581 | } |
582 | |
583 | static void |
584 | unmap (GtkWidget *widget) |
585 | { |
586 | GtkInspectorMiscInfo *sl = GTK_INSPECTOR_MISC_INFO (widget); |
587 | |
588 | g_source_remove (tag: sl->update_source_id); |
589 | sl->update_source_id = 0; |
590 | |
591 | GTK_WIDGET_CLASS (gtk_inspector_misc_info_parent_class)->unmap (widget); |
592 | } |
593 | |
594 | static void |
595 | dispose (GObject *o) |
596 | { |
597 | GtkInspectorMiscInfo *sl = GTK_INSPECTOR_MISC_INFO (o); |
598 | |
599 | g_clear_pointer (&sl->swin, gtk_widget_unparent); |
600 | |
601 | G_OBJECT_CLASS (gtk_inspector_misc_info_parent_class)->dispose (o); |
602 | } |
603 | |
604 | static void |
605 | gtk_inspector_misc_info_class_init (GtkInspectorMiscInfoClass *klass) |
606 | { |
607 | GObjectClass *object_class = G_OBJECT_CLASS (klass); |
608 | GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); |
609 | |
610 | object_class->dispose = dispose; |
611 | |
612 | widget_class->map = map; |
613 | widget_class->unmap = unmap; |
614 | |
615 | gtk_widget_class_set_template_from_resource (widget_class, resource_name: "/org/gtk/libgtk/inspector/misc-info.ui" ); |
616 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, swin); |
617 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, address); |
618 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, type); |
619 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, refcount_row); |
620 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, refcount); |
621 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, state_row); |
622 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, state); |
623 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, direction_row); |
624 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, direction); |
625 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, buildable_id_row); |
626 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, buildable_id); |
627 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, mnemonic_label_row); |
628 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, mnemonic_label); |
629 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, request_mode_row); |
630 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, request_mode); |
631 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, measure_row); |
632 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, measure_expand_toggle); |
633 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, measure_picture); |
634 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, measure_graph); |
635 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, allocated_size_row); |
636 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, allocated_size); |
637 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, baseline_row); |
638 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, baseline); |
639 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, surface_row); |
640 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, surface); |
641 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, surface_button); |
642 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, renderer_row); |
643 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, renderer); |
644 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, renderer_button); |
645 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, frame_clock_row); |
646 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, frame_clock); |
647 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, frame_clock_button); |
648 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, tick_callback_row); |
649 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, tick_callback); |
650 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, framecount_row); |
651 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, framecount); |
652 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, framerate_row); |
653 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, framerate); |
654 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, mapped_row); |
655 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, mapped); |
656 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, realized_row); |
657 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, realized); |
658 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, is_toplevel_row); |
659 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, is_toplevel); |
660 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, child_visible_row); |
661 | gtk_widget_class_bind_template_child (widget_class, GtkInspectorMiscInfo, child_visible); |
662 | |
663 | gtk_widget_class_bind_template_callback (widget_class, update_measure_picture); |
664 | gtk_widget_class_bind_template_callback (widget_class, measure_picture_drag_prepare); |
665 | gtk_widget_class_bind_template_callback (widget_class, show_surface); |
666 | gtk_widget_class_bind_template_callback (widget_class, show_renderer); |
667 | gtk_widget_class_bind_template_callback (widget_class, show_frame_clock); |
668 | |
669 | gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT); |
670 | } |
671 | |
672 | // vim: set et sw=2 ts=2: |
673 | |