2014-07-19 06:47:36 +00:00
|
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2014 Red Hat, Inc.
|
|
|
|
|
*
|
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
#include <glib/gi18n-lib.h>
|
|
|
|
|
|
|
|
|
|
#include "misc-info.h"
|
|
|
|
|
#include "window.h"
|
2014-10-11 01:40:53 +00:00
|
|
|
|
#include "object-tree.h"
|
2019-04-03 22:50:24 +00:00
|
|
|
|
#include "type-info.h"
|
2014-07-19 06:47:36 +00:00
|
|
|
|
|
|
|
|
|
#include "gtktypebuiltins.h"
|
|
|
|
|
#include "gtktreeview.h"
|
2014-07-24 12:29:12 +00:00
|
|
|
|
#include "gtkbuildable.h"
|
2014-07-19 06:47:36 +00:00
|
|
|
|
#include "gtklabel.h"
|
|
|
|
|
#include "gtkframe.h"
|
2014-10-24 11:49:37 +00:00
|
|
|
|
#include "gtkbutton.h"
|
2019-04-03 22:50:24 +00:00
|
|
|
|
#include "gtkmenubutton.h"
|
2014-10-24 11:49:37 +00:00
|
|
|
|
#include "gtkwidgetprivate.h"
|
|
|
|
|
|
2014-07-19 06:47:36 +00:00
|
|
|
|
|
|
|
|
|
struct _GtkInspectorMiscInfoPrivate {
|
2014-10-11 01:40:53 +00:00
|
|
|
|
GtkInspectorObjectTree *object_tree;
|
2014-07-19 06:47:36 +00:00
|
|
|
|
|
2014-07-24 12:14:54 +00:00
|
|
|
|
GObject *object;
|
2014-07-19 06:47:36 +00:00
|
|
|
|
|
2019-05-28 22:34:47 +00:00
|
|
|
|
GtkWidget *swin;
|
2015-01-09 05:07:01 +00:00
|
|
|
|
GtkWidget *address;
|
2019-04-03 22:50:24 +00:00
|
|
|
|
GtkWidget *type;
|
|
|
|
|
GtkWidget *type_popover;
|
2014-11-13 02:58:08 +00:00
|
|
|
|
GtkWidget *refcount_row;
|
|
|
|
|
GtkWidget *refcount;
|
2014-07-24 12:14:54 +00:00
|
|
|
|
GtkWidget *state_row;
|
2014-07-19 06:47:36 +00:00
|
|
|
|
GtkWidget *state;
|
2014-07-24 12:29:12 +00:00
|
|
|
|
GtkWidget *buildable_id_row;
|
|
|
|
|
GtkWidget *buildable_id;
|
2014-10-24 11:49:37 +00:00
|
|
|
|
GtkWidget *mnemonic_label_row;
|
|
|
|
|
GtkWidget *mnemonic_label;
|
2015-12-01 03:27:27 +00:00
|
|
|
|
GtkWidget *request_mode_row;
|
|
|
|
|
GtkWidget *request_mode;
|
2014-09-06 14:36:05 +00:00
|
|
|
|
GtkWidget *allocated_size_row;
|
|
|
|
|
GtkWidget *allocated_size;
|
2016-01-23 03:24:46 +00:00
|
|
|
|
GtkWidget *baseline_row;
|
|
|
|
|
GtkWidget *baseline;
|
2019-05-28 19:43:01 +00:00
|
|
|
|
GtkWidget *surface_row;
|
|
|
|
|
GtkWidget *surface;
|
|
|
|
|
GtkWidget *surface_button;
|
|
|
|
|
GtkWidget *renderer_row;
|
|
|
|
|
GtkWidget *renderer;
|
|
|
|
|
GtkWidget *renderer_button;
|
2016-03-10 21:21:35 +00:00
|
|
|
|
GtkWidget *frame_clock_row;
|
|
|
|
|
GtkWidget *frame_clock;
|
|
|
|
|
GtkWidget *frame_clock_button;
|
2014-10-24 11:49:37 +00:00
|
|
|
|
GtkWidget *tick_callback_row;
|
|
|
|
|
GtkWidget *tick_callback;
|
2014-11-13 03:50:52 +00:00
|
|
|
|
GtkWidget *framerate_row;
|
|
|
|
|
GtkWidget *framerate;
|
|
|
|
|
GtkWidget *framecount_row;
|
|
|
|
|
GtkWidget *framecount;
|
2014-10-24 11:49:37 +00:00
|
|
|
|
GtkWidget *accessible_role_row;
|
|
|
|
|
GtkWidget *accessible_role;
|
2015-03-19 11:00:01 +00:00
|
|
|
|
GtkWidget *accessible_name_row;
|
|
|
|
|
GtkWidget *accessible_name;
|
|
|
|
|
GtkWidget *accessible_description_row;
|
|
|
|
|
GtkWidget *accessible_description;
|
2014-10-24 11:49:37 +00:00
|
|
|
|
GtkWidget *mapped_row;
|
|
|
|
|
GtkWidget *mapped;
|
|
|
|
|
GtkWidget *realized_row;
|
|
|
|
|
GtkWidget *realized;
|
|
|
|
|
GtkWidget *is_toplevel_row;
|
|
|
|
|
GtkWidget *is_toplevel;
|
|
|
|
|
GtkWidget *child_visible_row;
|
|
|
|
|
GtkWidget *child_visible;
|
2014-11-13 01:44:22 +00:00
|
|
|
|
|
|
|
|
|
guint update_source_id;
|
2014-11-13 03:50:52 +00:00
|
|
|
|
gint64 last_frame;
|
2014-07-19 06:47:36 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum
|
|
|
|
|
{
|
|
|
|
|
PROP_0,
|
2014-10-11 01:40:53 +00:00
|
|
|
|
PROP_OBJECT_TREE
|
2014-07-19 06:47:36 +00:00
|
|
|
|
};
|
2014-09-06 14:36:05 +00:00
|
|
|
|
|
2019-05-28 22:34:47 +00:00
|
|
|
|
G_DEFINE_TYPE_WITH_PRIVATE (GtkInspectorMiscInfo, gtk_inspector_misc_info, GTK_TYPE_WIDGET)
|
2014-07-19 06:47:36 +00:00
|
|
|
|
|
|
|
|
|
static gchar *
|
|
|
|
|
format_state_flags (GtkStateFlags state)
|
|
|
|
|
{
|
|
|
|
|
GFlagsClass *fclass;
|
|
|
|
|
GString *str;
|
|
|
|
|
gint i;
|
|
|
|
|
|
|
|
|
|
str = g_string_new ("");
|
|
|
|
|
|
|
|
|
|
if (state)
|
|
|
|
|
{
|
|
|
|
|
fclass = g_type_class_ref (GTK_TYPE_STATE_FLAGS);
|
|
|
|
|
for (i = 0; i < fclass->n_values; i++)
|
|
|
|
|
{
|
|
|
|
|
if (state & fclass->values[i].value)
|
|
|
|
|
{
|
|
|
|
|
if (str->len)
|
|
|
|
|
g_string_append (str, " | ");
|
|
|
|
|
g_string_append (str, fclass->values[i].value_nick);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
g_type_class_unref (fclass);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
g_string_append (str, "normal");
|
|
|
|
|
|
|
|
|
|
return g_string_free (str, FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
state_flags_changed (GtkWidget *w, GtkStateFlags old_flags, GtkInspectorMiscInfo *sl)
|
|
|
|
|
{
|
|
|
|
|
gchar *s;
|
|
|
|
|
|
|
|
|
|
s = format_state_flags (gtk_widget_get_state_flags (w));
|
|
|
|
|
gtk_label_set_label (GTK_LABEL (sl->priv->state), s);
|
|
|
|
|
g_free (s);
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-06 14:36:05 +00:00
|
|
|
|
static void
|
2017-07-11 07:58:21 +00:00
|
|
|
|
allocation_changed (GtkWidget *w,
|
2018-08-16 04:53:03 +00:00
|
|
|
|
int width,
|
|
|
|
|
int height,
|
2017-07-11 07:58:21 +00:00
|
|
|
|
int baseline,
|
|
|
|
|
GtkInspectorMiscInfo *sl)
|
2014-09-06 14:36:05 +00:00
|
|
|
|
{
|
2016-01-21 03:52:05 +00:00
|
|
|
|
GtkAllocation alloc;
|
2014-10-24 11:49:37 +00:00
|
|
|
|
gchar *size_label;
|
2015-12-01 03:27:27 +00:00
|
|
|
|
GEnumClass *class;
|
|
|
|
|
GEnumValue *value;
|
2014-10-24 11:49:37 +00:00
|
|
|
|
|
2016-01-21 03:52:05 +00:00
|
|
|
|
gtk_widget_get_allocation (w, &alloc);
|
|
|
|
|
size_label = g_strdup_printf ("%d × %d +%d +%d",
|
|
|
|
|
alloc.width, alloc.height,
|
|
|
|
|
alloc.x, alloc.y);
|
2014-09-06 14:36:05 +00:00
|
|
|
|
|
|
|
|
|
gtk_label_set_label (GTK_LABEL (sl->priv->allocated_size), size_label);
|
|
|
|
|
g_free (size_label);
|
2014-10-24 11:49:37 +00:00
|
|
|
|
|
2016-01-23 03:24:46 +00:00
|
|
|
|
size_label = g_strdup_printf ("%d", gtk_widget_get_allocated_baseline (w));
|
|
|
|
|
gtk_label_set_label (GTK_LABEL (sl->priv->baseline), size_label);
|
|
|
|
|
g_free (size_label);
|
|
|
|
|
|
2015-12-01 03:27:27 +00:00
|
|
|
|
class = G_ENUM_CLASS (g_type_class_ref (GTK_TYPE_SIZE_REQUEST_MODE));
|
|
|
|
|
value = g_enum_get_value (class, gtk_widget_get_request_mode (w));
|
|
|
|
|
gtk_label_set_label (GTK_LABEL (sl->priv->request_mode), value->value_nick);
|
|
|
|
|
g_type_class_unref (class);
|
2014-09-06 14:36:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-07-19 06:47:36 +00:00
|
|
|
|
static void
|
|
|
|
|
disconnect_each_other (gpointer still_alive,
|
|
|
|
|
GObject *for_science)
|
|
|
|
|
{
|
|
|
|
|
if (GTK_INSPECTOR_IS_MISC_INFO (still_alive))
|
|
|
|
|
{
|
|
|
|
|
GtkInspectorMiscInfo *self = GTK_INSPECTOR_MISC_INFO (still_alive);
|
2014-07-24 12:14:54 +00:00
|
|
|
|
self->priv->object = NULL;
|
2014-07-19 06:47:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_signal_handlers_disconnect_matched (still_alive, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, for_science);
|
|
|
|
|
g_object_weak_unref (still_alive, disconnect_each_other, for_science);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2014-07-24 12:14:54 +00:00
|
|
|
|
show_object (GtkInspectorMiscInfo *sl,
|
|
|
|
|
GObject *object,
|
2014-07-19 06:47:36 +00:00
|
|
|
|
const gchar *tab)
|
|
|
|
|
{
|
2019-02-13 18:04:00 +00:00
|
|
|
|
g_object_set_data_full (G_OBJECT (sl->priv->object_tree), "next-tab", g_strdup (tab), g_free);
|
2019-05-08 02:44:24 +00:00
|
|
|
|
gtk_inspector_object_tree_activate_object (sl->priv->object_tree, object);
|
2014-07-19 06:47:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-10-24 11:49:37 +00:00
|
|
|
|
static void
|
|
|
|
|
show_mnemonic_label (GtkWidget *button, GtkInspectorMiscInfo *sl)
|
|
|
|
|
{
|
|
|
|
|
GtkWidget *widget;
|
|
|
|
|
|
|
|
|
|
widget = g_object_get_data (G_OBJECT (button), "mnemonic-label");
|
|
|
|
|
if (widget)
|
2014-11-22 11:46:28 +00:00
|
|
|
|
show_object (sl, G_OBJECT (widget), "properties");
|
2014-10-24 11:49:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-05-28 19:43:01 +00:00
|
|
|
|
static void
|
|
|
|
|
show_surface (GtkWidget *button, GtkInspectorMiscInfo *sl)
|
|
|
|
|
{
|
|
|
|
|
GObject *surface;
|
|
|
|
|
|
|
|
|
|
surface = (GObject *)gtk_native_get_surface (GTK_NATIVE (sl->priv->object));
|
|
|
|
|
if (surface)
|
|
|
|
|
show_object (sl, G_OBJECT (surface), "properties");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
show_renderer (GtkWidget *button, GtkInspectorMiscInfo *sl)
|
|
|
|
|
{
|
|
|
|
|
GObject *renderer;
|
|
|
|
|
|
|
|
|
|
renderer = (GObject *)gtk_native_get_renderer (GTK_NATIVE (sl->priv->object));
|
|
|
|
|
if (renderer)
|
|
|
|
|
show_object (sl, G_OBJECT (renderer), "properties");
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-10 21:21:35 +00:00
|
|
|
|
static void
|
|
|
|
|
show_frame_clock (GtkWidget *button, GtkInspectorMiscInfo *sl)
|
|
|
|
|
{
|
|
|
|
|
GObject *clock;
|
|
|
|
|
|
|
|
|
|
clock = (GObject *)gtk_widget_get_frame_clock (GTK_WIDGET (sl->priv->object));
|
|
|
|
|
if (clock)
|
|
|
|
|
show_object (sl, G_OBJECT (clock), "properties");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2019-05-28 19:43:01 +00:00
|
|
|
|
update_surface (GtkInspectorMiscInfo *sl)
|
2016-03-10 21:21:35 +00:00
|
|
|
|
{
|
2019-05-28 19:43:01 +00:00
|
|
|
|
if (GTK_IS_NATIVE (sl->priv->object))
|
|
|
|
|
{
|
|
|
|
|
GObject *obj;
|
|
|
|
|
char *tmp;
|
2016-03-10 21:21:35 +00:00
|
|
|
|
|
2019-05-28 19:43:01 +00:00
|
|
|
|
gtk_widget_show (sl->priv->surface_row);
|
|
|
|
|
|
|
|
|
|
obj = (GObject *)gtk_native_get_surface (GTK_NATIVE (sl->priv->object));
|
|
|
|
|
tmp = g_strdup_printf ("%p", obj);
|
|
|
|
|
gtk_label_set_label (GTK_LABEL (sl->priv->surface), tmp);
|
|
|
|
|
g_free (tmp);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
gtk_widget_hide (sl->priv->surface_row);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
update_renderer (GtkInspectorMiscInfo *sl)
|
|
|
|
|
{
|
|
|
|
|
if (GTK_IS_NATIVE (sl->priv->object))
|
2016-03-10 21:21:35 +00:00
|
|
|
|
{
|
2019-05-28 19:43:01 +00:00
|
|
|
|
GObject *obj;
|
|
|
|
|
char *tmp;
|
|
|
|
|
|
|
|
|
|
gtk_widget_show (sl->priv->renderer_row);
|
|
|
|
|
|
|
|
|
|
obj = (GObject *)gtk_native_get_surface (GTK_NATIVE (sl->priv->object));
|
|
|
|
|
tmp = g_strdup_printf ("%p", obj);
|
|
|
|
|
gtk_label_set_label (GTK_LABEL (sl->priv->renderer), tmp);
|
2016-03-10 21:21:35 +00:00
|
|
|
|
g_free (tmp);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2019-05-28 19:43:01 +00:00
|
|
|
|
gtk_widget_hide (sl->priv->renderer_row);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
update_frame_clock (GtkInspectorMiscInfo *sl)
|
|
|
|
|
{
|
|
|
|
|
if (GTK_IS_ROOT (sl->priv->object))
|
|
|
|
|
{
|
|
|
|
|
GObject *clock;
|
|
|
|
|
|
|
|
|
|
gtk_widget_show (sl->priv->frame_clock_row);
|
|
|
|
|
|
|
|
|
|
clock = (GObject *)gtk_widget_get_frame_clock (GTK_WIDGET (sl->priv->object));
|
|
|
|
|
if (clock)
|
|
|
|
|
{
|
|
|
|
|
gchar *tmp;
|
|
|
|
|
tmp = g_strdup_printf ("%p", clock);
|
|
|
|
|
gtk_label_set_label (GTK_LABEL (sl->priv->frame_clock), tmp);
|
|
|
|
|
g_free (tmp);
|
|
|
|
|
gtk_widget_set_sensitive (sl->priv->frame_clock_button, TRUE);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
gtk_label_set_label (GTK_LABEL (sl->priv->frame_clock), "NULL");
|
|
|
|
|
gtk_widget_set_sensitive (sl->priv->frame_clock_button, FALSE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
gtk_widget_hide (sl->priv->frame_clock_row);
|
2016-03-10 21:21:35 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-13 01:44:22 +00:00
|
|
|
|
static gboolean
|
|
|
|
|
update_info (gpointer data)
|
|
|
|
|
{
|
|
|
|
|
GtkInspectorMiscInfo *sl = data;
|
2014-11-13 02:58:08 +00:00
|
|
|
|
gchar *tmp;
|
2019-04-03 22:50:24 +00:00
|
|
|
|
GType gtype;
|
2014-11-13 01:44:22 +00:00
|
|
|
|
|
2015-01-09 05:07:01 +00:00
|
|
|
|
tmp = g_strdup_printf ("%p", sl->priv->object);
|
|
|
|
|
gtk_label_set_text (GTK_LABEL (sl->priv->address), tmp);
|
|
|
|
|
g_free (tmp);
|
|
|
|
|
|
2019-04-03 22:50:24 +00:00
|
|
|
|
gtype = G_TYPE_FROM_INSTANCE (sl->priv->object);
|
|
|
|
|
|
2019-05-18 04:58:46 +00:00
|
|
|
|
gtk_menu_button_set_label (GTK_MENU_BUTTON (sl->priv->type), g_type_name (gtype));
|
2019-04-03 22:50:24 +00:00
|
|
|
|
gtk_inspector_type_popover_set_gtype (GTK_INSPECTOR_TYPE_POPOVER (sl->priv->type_popover),
|
|
|
|
|
gtype);
|
|
|
|
|
|
2014-11-13 02:58:08 +00:00
|
|
|
|
if (G_IS_OBJECT (sl->priv->object))
|
|
|
|
|
{
|
|
|
|
|
tmp = g_strdup_printf ("%d", sl->priv->object->ref_count);
|
|
|
|
|
gtk_label_set_text (GTK_LABEL (sl->priv->refcount), tmp);
|
|
|
|
|
g_free (tmp);
|
|
|
|
|
}
|
2015-01-09 05:07:01 +00:00
|
|
|
|
|
2014-11-13 01:44:22 +00:00
|
|
|
|
if (GTK_IS_WIDGET (sl->priv->object))
|
|
|
|
|
{
|
|
|
|
|
AtkObject *accessible;
|
|
|
|
|
AtkRole role;
|
|
|
|
|
GList *list, *l;
|
|
|
|
|
|
|
|
|
|
gtk_container_forall (GTK_CONTAINER (sl->priv->mnemonic_label), (GtkCallback)gtk_widget_destroy, NULL);
|
|
|
|
|
list = gtk_widget_list_mnemonic_labels (GTK_WIDGET (sl->priv->object));
|
|
|
|
|
for (l = list; l; l = l->next)
|
|
|
|
|
{
|
|
|
|
|
GtkWidget *button;
|
|
|
|
|
|
|
|
|
|
tmp = g_strdup_printf ("%p (%s)", l->data, g_type_name_from_instance ((GTypeInstance*)l->data));
|
|
|
|
|
button = gtk_button_new_with_label (tmp);
|
2014-11-13 02:58:08 +00:00
|
|
|
|
g_free (tmp);
|
2014-11-13 01:44:22 +00:00
|
|
|
|
gtk_widget_show (button);
|
|
|
|
|
gtk_container_add (GTK_CONTAINER (sl->priv->mnemonic_label), button);
|
|
|
|
|
g_object_set_data (G_OBJECT (button), "mnemonic-label", l->data);
|
|
|
|
|
g_signal_connect (button, "clicked", G_CALLBACK (show_mnemonic_label), sl);
|
|
|
|
|
}
|
|
|
|
|
g_list_free (list);
|
|
|
|
|
|
|
|
|
|
gtk_widget_set_visible (sl->priv->tick_callback, gtk_widget_has_tick_callback (GTK_WIDGET (sl->priv->object)));
|
|
|
|
|
|
|
|
|
|
accessible = ATK_OBJECT (gtk_widget_get_accessible (GTK_WIDGET (sl->priv->object)));
|
|
|
|
|
role = atk_object_get_role (accessible);
|
|
|
|
|
gtk_label_set_text (GTK_LABEL (sl->priv->accessible_role), atk_role_get_name (role));
|
2015-03-19 11:00:01 +00:00
|
|
|
|
gtk_label_set_text (GTK_LABEL (sl->priv->accessible_name), atk_object_get_name (accessible));
|
|
|
|
|
gtk_label_set_text (GTK_LABEL (sl->priv->accessible_description), atk_object_get_description (accessible));
|
2014-11-13 01:44:22 +00:00
|
|
|
|
gtk_widget_set_visible (sl->priv->mapped, gtk_widget_get_mapped (GTK_WIDGET (sl->priv->object)));
|
|
|
|
|
gtk_widget_set_visible (sl->priv->realized, gtk_widget_get_realized (GTK_WIDGET (sl->priv->object)));
|
2019-05-20 03:31:03 +00:00
|
|
|
|
gtk_widget_set_visible (sl->priv->is_toplevel, GTK_IS_ROOT (sl->priv->object));
|
2014-11-13 01:44:22 +00:00
|
|
|
|
gtk_widget_set_visible (sl->priv->child_visible, gtk_widget_get_child_visible (GTK_WIDGET (sl->priv->object)));
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-28 19:43:01 +00:00
|
|
|
|
update_surface (sl);
|
|
|
|
|
update_renderer (sl);
|
|
|
|
|
update_frame_clock (sl);
|
|
|
|
|
|
2014-11-13 02:58:08 +00:00
|
|
|
|
if (GTK_IS_BUILDABLE (sl->priv->object))
|
|
|
|
|
{
|
|
|
|
|
gtk_label_set_text (GTK_LABEL (sl->priv->buildable_id),
|
|
|
|
|
gtk_buildable_get_name (GTK_BUILDABLE (sl->priv->object)));
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-13 03:50:52 +00:00
|
|
|
|
if (GDK_IS_FRAME_CLOCK (sl->priv->object))
|
|
|
|
|
{
|
|
|
|
|
GdkFrameClock *clock;
|
|
|
|
|
gint64 frame;
|
|
|
|
|
gint64 frame_time;
|
|
|
|
|
gint64 history_start;
|
|
|
|
|
gint64 history_len;
|
|
|
|
|
gint64 previous_frame_time;
|
|
|
|
|
GdkFrameTimings *previous_timings;
|
|
|
|
|
|
|
|
|
|
clock = GDK_FRAME_CLOCK (sl->priv->object);
|
|
|
|
|
frame = gdk_frame_clock_get_frame_counter (clock);
|
|
|
|
|
frame_time = gdk_frame_clock_get_frame_time (clock);
|
|
|
|
|
|
2015-03-24 12:34:10 +00:00
|
|
|
|
tmp = g_strdup_printf ("%"G_GINT64_FORMAT, frame);
|
2014-11-13 03:50:52 +00:00
|
|
|
|
gtk_label_set_label (GTK_LABEL (sl->priv->framecount), tmp);
|
|
|
|
|
g_free (tmp);
|
|
|
|
|
|
|
|
|
|
history_start = gdk_frame_clock_get_history_start (clock);
|
|
|
|
|
history_len = frame - history_start;
|
|
|
|
|
|
|
|
|
|
if (history_len > 0 && sl->priv->last_frame != frame)
|
|
|
|
|
{
|
|
|
|
|
previous_timings = gdk_frame_clock_get_timings (clock, history_start);
|
|
|
|
|
previous_frame_time = gdk_frame_timings_get_frame_time (previous_timings);
|
|
|
|
|
tmp = g_strdup_printf ("%4.1f ⁄ s", (G_USEC_PER_SEC * history_len) / (double) (frame_time - previous_frame_time));
|
|
|
|
|
gtk_label_set_label (GTK_LABEL (sl->priv->framerate), tmp);
|
|
|
|
|
g_free (tmp);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
gtk_label_set_label (GTK_LABEL (sl->priv->framerate), "—");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sl->priv->last_frame = frame;
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-13 01:44:22 +00:00
|
|
|
|
return G_SOURCE_CONTINUE;
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-19 06:47:36 +00:00
|
|
|
|
void
|
|
|
|
|
gtk_inspector_misc_info_set_object (GtkInspectorMiscInfo *sl,
|
|
|
|
|
GObject *object)
|
|
|
|
|
{
|
2014-07-24 12:14:54 +00:00
|
|
|
|
if (sl->priv->object)
|
2014-07-19 06:47:36 +00:00
|
|
|
|
{
|
2014-07-24 12:14:54 +00:00
|
|
|
|
g_signal_handlers_disconnect_by_func (sl->priv->object, state_flags_changed, sl);
|
2014-09-06 14:36:05 +00:00
|
|
|
|
g_signal_handlers_disconnect_by_func (sl->priv->object, allocation_changed, sl);
|
2014-07-24 12:14:54 +00:00
|
|
|
|
disconnect_each_other (sl->priv->object, G_OBJECT (sl));
|
|
|
|
|
disconnect_each_other (sl, sl->priv->object);
|
|
|
|
|
sl->priv->object = NULL;
|
2014-07-19 06:47:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gtk_widget_show (GTK_WIDGET (sl));
|
|
|
|
|
|
2014-07-24 12:14:54 +00:00
|
|
|
|
sl->priv->object = object;
|
2014-07-19 06:47:36 +00:00
|
|
|
|
g_object_weak_ref (G_OBJECT (sl), disconnect_each_other, object);
|
2014-07-24 12:14:54 +00:00
|
|
|
|
g_object_weak_ref (object, disconnect_each_other, sl);
|
2014-07-19 06:47:36 +00:00
|
|
|
|
|
2014-07-24 12:14:54 +00:00
|
|
|
|
if (GTK_IS_WIDGET (object))
|
|
|
|
|
{
|
2014-11-13 02:58:08 +00:00
|
|
|
|
gtk_widget_show (sl->priv->refcount_row);
|
2014-07-24 12:14:54 +00:00
|
|
|
|
gtk_widget_show (sl->priv->state_row);
|
2015-12-01 03:27:27 +00:00
|
|
|
|
gtk_widget_show (sl->priv->request_mode_row);
|
2014-09-06 14:36:05 +00:00
|
|
|
|
gtk_widget_show (sl->priv->allocated_size_row);
|
2016-01-23 03:24:46 +00:00
|
|
|
|
gtk_widget_show (sl->priv->baseline_row);
|
2014-11-13 01:44:22 +00:00
|
|
|
|
gtk_widget_show (sl->priv->mnemonic_label_row);
|
2014-10-24 11:49:37 +00:00
|
|
|
|
gtk_widget_show (sl->priv->tick_callback_row);
|
|
|
|
|
gtk_widget_show (sl->priv->accessible_role_row);
|
2015-03-19 11:00:01 +00:00
|
|
|
|
gtk_widget_show (sl->priv->accessible_name_row);
|
|
|
|
|
gtk_widget_show (sl->priv->accessible_description_row);
|
2014-10-24 11:49:37 +00:00
|
|
|
|
gtk_widget_show (sl->priv->mapped_row);
|
|
|
|
|
gtk_widget_show (sl->priv->realized_row);
|
|
|
|
|
gtk_widget_show (sl->priv->is_toplevel_row);
|
|
|
|
|
gtk_widget_show (sl->priv->is_toplevel_row);
|
2016-03-10 21:21:35 +00:00
|
|
|
|
gtk_widget_show (sl->priv->frame_clock_row);
|
2014-11-13 01:44:22 +00:00
|
|
|
|
|
|
|
|
|
g_signal_connect_object (object, "state-flags-changed", G_CALLBACK (state_flags_changed), sl, 0);
|
|
|
|
|
state_flags_changed (GTK_WIDGET (sl->priv->object), 0, sl);
|
|
|
|
|
|
|
|
|
|
g_signal_connect_object (object, "size-allocate", G_CALLBACK (allocation_changed), sl, 0);
|
2018-08-16 04:53:03 +00:00
|
|
|
|
allocation_changed (GTK_WIDGET (sl->priv->object), 0, 0, -1, sl);
|
2014-07-24 12:14:54 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
gtk_widget_hide (sl->priv->state_row);
|
2015-12-11 22:11:07 +00:00
|
|
|
|
gtk_widget_hide (sl->priv->request_mode_row);
|
2014-10-24 11:49:37 +00:00
|
|
|
|
gtk_widget_hide (sl->priv->mnemonic_label_row);
|
2014-09-06 14:36:05 +00:00
|
|
|
|
gtk_widget_hide (sl->priv->allocated_size_row);
|
2016-01-23 03:24:46 +00:00
|
|
|
|
gtk_widget_hide (sl->priv->baseline_row);
|
2014-10-24 11:49:37 +00:00
|
|
|
|
gtk_widget_hide (sl->priv->tick_callback_row);
|
|
|
|
|
gtk_widget_hide (sl->priv->accessible_role_row);
|
2015-03-19 11:00:01 +00:00
|
|
|
|
gtk_widget_hide (sl->priv->accessible_name_row);
|
|
|
|
|
gtk_widget_hide (sl->priv->accessible_description_row);
|
2014-10-24 11:49:37 +00:00
|
|
|
|
gtk_widget_hide (sl->priv->mapped_row);
|
|
|
|
|
gtk_widget_hide (sl->priv->realized_row);
|
|
|
|
|
gtk_widget_hide (sl->priv->is_toplevel_row);
|
|
|
|
|
gtk_widget_hide (sl->priv->child_visible_row);
|
2016-03-10 21:21:35 +00:00
|
|
|
|
gtk_widget_hide (sl->priv->frame_clock_row);
|
2014-07-24 12:14:54 +00:00
|
|
|
|
}
|
2014-07-19 06:47:36 +00:00
|
|
|
|
|
2014-07-24 12:29:12 +00:00
|
|
|
|
if (GTK_IS_BUILDABLE (object))
|
|
|
|
|
{
|
|
|
|
|
gtk_widget_show (sl->priv->buildable_id_row);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
gtk_widget_hide (sl->priv->buildable_id_row);
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-13 03:50:52 +00:00
|
|
|
|
if (GDK_IS_FRAME_CLOCK (object))
|
|
|
|
|
{
|
|
|
|
|
gtk_widget_show (sl->priv->framecount_row);
|
|
|
|
|
gtk_widget_show (sl->priv->framerate_row);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
gtk_widget_hide (sl->priv->framecount_row);
|
|
|
|
|
gtk_widget_hide (sl->priv->framerate_row);
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-13 02:58:08 +00:00
|
|
|
|
update_info (sl);
|
2014-07-19 06:47:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gtk_inspector_misc_info_init (GtkInspectorMiscInfo *sl)
|
|
|
|
|
{
|
|
|
|
|
sl->priv = gtk_inspector_misc_info_get_instance_private (sl);
|
|
|
|
|
gtk_widget_init_template (GTK_WIDGET (sl));
|
2019-04-03 22:50:24 +00:00
|
|
|
|
|
|
|
|
|
sl->priv->type_popover = g_object_new (GTK_TYPE_INSPECTOR_TYPE_POPOVER, NULL);
|
|
|
|
|
gtk_menu_button_set_popover (GTK_MENU_BUTTON (sl->priv->type),
|
|
|
|
|
sl->priv->type_popover);
|
|
|
|
|
|
2014-07-19 06:47:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-11-13 01:44:22 +00:00
|
|
|
|
static void
|
|
|
|
|
map (GtkWidget *widget)
|
|
|
|
|
{
|
|
|
|
|
GtkInspectorMiscInfo *sl = GTK_INSPECTOR_MISC_INFO (widget);
|
|
|
|
|
|
|
|
|
|
GTK_WIDGET_CLASS (gtk_inspector_misc_info_parent_class)->map (widget);
|
|
|
|
|
|
2018-02-02 14:51:47 +00:00
|
|
|
|
sl->priv->update_source_id = g_timeout_add_seconds (1, update_info, sl);
|
2014-11-13 01:44:22 +00:00
|
|
|
|
update_info (sl);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
unmap (GtkWidget *widget)
|
|
|
|
|
{
|
|
|
|
|
GtkInspectorMiscInfo *sl = GTK_INSPECTOR_MISC_INFO (widget);
|
|
|
|
|
|
|
|
|
|
g_source_remove (sl->priv->update_source_id);
|
|
|
|
|
sl->priv->update_source_id = 0;
|
|
|
|
|
|
|
|
|
|
GTK_WIDGET_CLASS (gtk_inspector_misc_info_parent_class)->unmap (widget);
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-19 06:47:36 +00:00
|
|
|
|
static void
|
|
|
|
|
get_property (GObject *object,
|
|
|
|
|
guint param_id,
|
|
|
|
|
GValue *value,
|
|
|
|
|
GParamSpec *pspec)
|
|
|
|
|
{
|
|
|
|
|
GtkInspectorMiscInfo *sl = GTK_INSPECTOR_MISC_INFO (object);
|
|
|
|
|
|
|
|
|
|
switch (param_id)
|
|
|
|
|
{
|
2014-10-11 01:40:53 +00:00
|
|
|
|
case PROP_OBJECT_TREE:
|
|
|
|
|
g_value_take_object (value, sl->priv->object_tree);
|
2014-07-19 06:47:36 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
set_property (GObject *object,
|
|
|
|
|
guint param_id,
|
|
|
|
|
const GValue *value,
|
|
|
|
|
GParamSpec *pspec)
|
|
|
|
|
{
|
|
|
|
|
GtkInspectorMiscInfo *sl = GTK_INSPECTOR_MISC_INFO (object);
|
|
|
|
|
|
|
|
|
|
switch (param_id)
|
|
|
|
|
{
|
2014-10-11 01:40:53 +00:00
|
|
|
|
case PROP_OBJECT_TREE:
|
|
|
|
|
sl->priv->object_tree = g_value_get_object (value);
|
2014-07-19 06:47:36 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-28 22:34:47 +00:00
|
|
|
|
static void
|
|
|
|
|
measure (GtkWidget *widget,
|
|
|
|
|
GtkOrientation orientation,
|
|
|
|
|
int for_size,
|
|
|
|
|
int *minimum,
|
|
|
|
|
int *natural,
|
|
|
|
|
int *minimum_baseline,
|
|
|
|
|
int *natural_baseline)
|
|
|
|
|
{
|
|
|
|
|
GtkInspectorMiscInfo *sl = GTK_INSPECTOR_MISC_INFO (widget);
|
|
|
|
|
|
|
|
|
|
gtk_widget_measure (sl->priv->swin,
|
|
|
|
|
orientation,
|
|
|
|
|
for_size,
|
|
|
|
|
minimum, natural,
|
|
|
|
|
minimum_baseline, natural_baseline);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
size_allocate (GtkWidget *widget,
|
|
|
|
|
int width,
|
|
|
|
|
int height,
|
|
|
|
|
int baseline)
|
|
|
|
|
{
|
|
|
|
|
GtkInspectorMiscInfo *sl = GTK_INSPECTOR_MISC_INFO (widget);
|
|
|
|
|
|
|
|
|
|
gtk_widget_size_allocate (sl->priv->swin,
|
|
|
|
|
&(GtkAllocation) { 0, 0, width, height },
|
|
|
|
|
baseline);
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-19 06:47:36 +00:00
|
|
|
|
static void
|
|
|
|
|
gtk_inspector_misc_info_class_init (GtkInspectorMiscInfoClass *klass)
|
|
|
|
|
{
|
|
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
|
|
|
|
|
|
|
|
|
object_class->get_property = get_property;
|
|
|
|
|
object_class->set_property = set_property;
|
|
|
|
|
|
2014-11-13 01:44:22 +00:00
|
|
|
|
widget_class->map = map;
|
|
|
|
|
widget_class->unmap = unmap;
|
2019-05-28 22:34:47 +00:00
|
|
|
|
widget_class->measure = measure;
|
|
|
|
|
widget_class->size_allocate = size_allocate;
|
2014-11-13 01:44:22 +00:00
|
|
|
|
|
2014-10-11 01:40:53 +00:00
|
|
|
|
g_object_class_install_property (object_class, PROP_OBJECT_TREE,
|
2014-11-22 18:02:56 +00:00
|
|
|
|
g_param_spec_object ("object-tree", "Object Tree", "Object tree",
|
2014-07-19 06:47:36 +00:00
|
|
|
|
GTK_TYPE_WIDGET, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
|
|
|
|
|
2014-11-30 20:59:53 +00:00
|
|
|
|
gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/libgtk/inspector/misc-info.ui");
|
2019-05-28 22:34:47 +00:00
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, swin);
|
2015-01-09 05:07:01 +00:00
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, address);
|
2019-04-03 22:50:24 +00:00
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, type);
|
2014-11-13 02:58:08 +00:00
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, refcount_row);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, refcount);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, state_row);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, state);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, buildable_id_row);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, buildable_id);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, mnemonic_label_row);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, mnemonic_label);
|
2015-12-01 03:27:27 +00:00
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, request_mode_row);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, request_mode);
|
2014-11-13 02:58:08 +00:00
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, allocated_size_row);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, allocated_size);
|
2016-01-23 03:24:46 +00:00
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, baseline_row);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, baseline);
|
2019-05-28 19:43:01 +00:00
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, surface_row);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, surface);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, surface_button);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, renderer_row);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, renderer);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, renderer_button);
|
2016-03-10 21:21:35 +00:00
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, frame_clock_row);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, frame_clock);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, frame_clock_button);
|
2014-11-13 02:58:08 +00:00
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, tick_callback_row);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, tick_callback);
|
2014-11-13 03:50:52 +00:00
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, framecount_row);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, framecount);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, framerate_row);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, framerate);
|
2014-11-13 02:58:08 +00:00
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, accessible_role_row);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, accessible_role);
|
2015-03-19 11:00:01 +00:00
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, accessible_name_row);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, accessible_name);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, accessible_description_row);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, accessible_description);
|
2014-11-13 02:58:08 +00:00
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, mapped_row);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, mapped);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, realized_row);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, realized);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, is_toplevel_row);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, is_toplevel);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, child_visible_row);
|
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMiscInfo, child_visible);
|
2014-07-19 06:47:36 +00:00
|
|
|
|
|
2019-05-28 19:43:01 +00:00
|
|
|
|
gtk_widget_class_bind_template_callback (widget_class, show_surface);
|
|
|
|
|
gtk_widget_class_bind_template_callback (widget_class, show_renderer);
|
2016-03-10 21:21:35 +00:00
|
|
|
|
gtk_widget_class_bind_template_callback (widget_class, show_frame_clock);
|
2014-07-19 06:47:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// vim: set et sw=2 ts=2:
|
2014-11-13 01:44:22 +00:00
|
|
|
|
|