sysprof: add progressbar while loading

And try to keep some of the window disabled during the loading process.
This commit is contained in:
Christian Hergert
2023-08-07 14:32:49 -07:00
parent 170122abc8
commit 65515cfe64
5 changed files with 283 additions and 125 deletions

View File

@ -64,6 +64,7 @@ sysprof_sources = [
'sysprof-time-span-layer.c',
'sysprof-traceables-utility.c',
'sysprof-tree-expander.c',
'sysprof-util.c',
'sysprof-value-axis.c',
'sysprof-weighted-callgraph-view.c',
'sysprof-window.c',

View File

@ -0,0 +1,68 @@
/* sysprof-util.c
*
* Copyright 2023 Christian Hergert <chergert@redhat.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "config.h"
#include "sysprof-util.h"
static gboolean
hide_callback (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer user_data)
{
gint64 *begin_time = user_data;
double fraction;
g_assert (GTK_IS_WIDGET (widget));
g_assert (begin_time != NULL);
fraction = (g_get_monotonic_time () - *begin_time) / (double)G_USEC_PER_SEC;
if (fraction > 1)
{
gtk_widget_set_visible (widget, FALSE);
gtk_widget_set_opacity (widget, 1);
return G_SOURCE_REMOVE;
}
if (fraction < 0)
fraction = 0;
gtk_widget_set_opacity (widget, 1.-fraction);
return G_SOURCE_CONTINUE;
}
void
_gtk_widget_hide_with_fade (GtkWidget *widget)
{
gint64 begin_time;
g_return_if_fail (GTK_IS_WIDGET (widget));
if (!gtk_widget_get_visible (widget))
return;
begin_time = g_get_monotonic_time ();
gtk_widget_add_tick_callback (widget,
hide_callback,
g_memdup2 (&begin_time, sizeof begin_time),
g_free);
}

View File

@ -0,0 +1,29 @@
/* sysprof-util.h
*
* Copyright 2023 Christian Hergert <chergert@redhat.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#pragma once
#include <gtk/gtk.h>
G_BEGIN_DECLS
void _gtk_widget_hide_with_fade (GtkWidget *widget);
G_END_DECLS

View File

@ -38,6 +38,7 @@
#include "sysprof-samples-section.h"
#include "sysprof-sidebar.h"
#include "sysprof-storage-section.h"
#include "sysprof-util.h"
#include "sysprof-window.h"
struct _SysprofWindow
@ -50,6 +51,7 @@ struct _SysprofWindow
GtkToggleButton *show_right_sidebar;
GtkWidget *left_split_overlay;
GtkWidget *right_split_overlay;
GtkProgressBar *progress_bar;
guint disposed : 1;
};
@ -57,6 +59,7 @@ struct _SysprofWindow
enum {
PROP_0,
PROP_DOCUMENT,
PROP_IS_LOADED,
PROP_SESSION,
N_PROPS
};
@ -93,6 +96,33 @@ sysprof_window_update_zoom_actions (SysprofWindow *self)
visible_time->end_nsec < document_time->end_nsec);
}
static void
sysprof_window_update_action_state (SysprofWindow *self)
{
g_assert (SYSPROF_IS_WINDOW (self));
if (self->session == NULL)
{
gtk_widget_action_set_enabled (GTK_WIDGET (self), "win.open-capture", FALSE);
gtk_widget_action_set_enabled (GTK_WIDGET (self), "win.record-capture", FALSE);
gtk_widget_action_set_enabled (GTK_WIDGET (self), "session.zoom-one", FALSE);
gtk_widget_action_set_enabled (GTK_WIDGET (self), "session.zoom-out", FALSE);
gtk_widget_action_set_enabled (GTK_WIDGET (self), "session.zoom-in", FALSE);
gtk_widget_action_set_enabled (GTK_WIDGET (self), "session.seek-forward", FALSE);
gtk_widget_action_set_enabled (GTK_WIDGET (self), "session.seek-backward", FALSE);
gtk_widget_action_set_enabled (GTK_WIDGET (self), "win.save-capture", FALSE);
}
else
{
gtk_widget_action_set_enabled (GTK_WIDGET (self), "win.open-capture", TRUE);
gtk_widget_action_set_enabled (GTK_WIDGET (self), "win.record-capture", TRUE);
gtk_widget_action_set_enabled (GTK_WIDGET (self), "win.save-capture", TRUE);
gtk_widget_action_set_enabled (GTK_WIDGET (self), "session.zoom-in", TRUE);
sysprof_window_update_zoom_actions (self);
}
}
static void
sysprof_window_open_file_cb (GObject *object,
GAsyncResult *result,
@ -223,9 +253,10 @@ sysprof_window_set_document (SysprofWindow *self,
g_action_map_add_action (G_ACTION_MAP (self), G_ACTION (action));
}
sysprof_window_update_zoom_actions (self);
sysprof_window_update_action_state (self);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DOCUMENT]);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_IS_LOADED]);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SESSION]);
}
@ -464,6 +495,10 @@ sysprof_window_get_property (GObject *object,
g_value_set_object (value, sysprof_window_get_document (self));
break;
case PROP_IS_LOADED:
g_value_set_boolean (value, !!sysprof_window_get_document (self));
break;
case PROP_SESSION:
g_value_set_object (value, sysprof_window_get_session (self));
break;
@ -507,6 +542,11 @@ sysprof_window_class_init (SysprofWindowClass *klass)
SYSPROF_TYPE_DOCUMENT,
(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
properties [PROP_IS_LOADED] =
g_param_spec_boolean ("is-loaded", NULL, NULL,
FALSE,
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
properties[PROP_SESSION] =
g_param_spec_object ("session", NULL, NULL,
SYSPROF_TYPE_SESSION,
@ -516,9 +556,10 @@ sysprof_window_class_init (SysprofWindowClass *klass)
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/sysprof/sysprof-window.ui");
gtk_widget_class_bind_template_child (widget_class, SysprofWindow, show_right_sidebar);
gtk_widget_class_bind_template_child (widget_class, SysprofWindow, left_split_overlay);
gtk_widget_class_bind_template_child (widget_class, SysprofWindow, progress_bar);
gtk_widget_class_bind_template_child (widget_class, SysprofWindow, right_split_overlay);
gtk_widget_class_bind_template_child (widget_class, SysprofWindow, show_right_sidebar);
gtk_widget_class_bind_template_callback (widget_class, main_view_notify_sidebar);
@ -567,6 +608,8 @@ sysprof_window_init (SysprofWindow *self)
gtk_widget_init_template (GTK_WIDGET (self));
sysprof_window_update_action_state (self);
show_left_sidebar = g_property_action_new ("show-left-sidebar",
self->left_split_overlay,
"show-sidebar");
@ -642,6 +685,8 @@ sysprof_window_load_cb (GObject *object,
g_application_release (G_APPLICATION (app));
_gtk_widget_hide_with_fade (GTK_WIDGET (self->progress_bar));
if (!(document = sysprof_document_loader_load_finish (loader, result, &error)))
{
GtkWidget *dialog;
@ -658,8 +703,6 @@ sysprof_window_load_cb (GObject *object,
}
sysprof_window_set_document (self, document);
gtk_widget_set_sensitive (GTK_WIDGET (self), TRUE);
}
static void
@ -692,8 +735,10 @@ sysprof_window_open (SysprofApplication *app,
self = g_object_new (SYSPROF_TYPE_WINDOW,
"application", app,
"sensitive", FALSE,
NULL);
g_object_bind_property (loader, "fraction",
self->progress_bar, "fraction",
G_BINDING_SYNC_CREATE);
sysprof_document_loader_load_async (loader,
NULL,
sysprof_window_load_cb,

View File

@ -46,6 +46,9 @@
<property name="max-sidebar-width">200</property>
<property name="sidebar">
<object class="AdwNavigationPage">
<binding name="sensitive">
<lookup name="is-loaded">SysprofWindow</lookup>
</binding>
<property name="child">
<object class="AdwToolbarView">
<child type="top">
@ -165,129 +168,141 @@
</object>
</child>
<property name="content">
<object class="GtkStack" id="section_stack">
<property name="vexpand">true</property>
<child>
<object class="SysprofSamplesSection">
<property name="category">callgraph</property>
<property name="icon-name">org.gnome.Sysprof-symbolic</property>
<binding name="session">
<lookup name="session">SysprofWindow</lookup>
</binding>
<object class="GtkOverlay">
<child type="overlay">
<object class="GtkProgressBar" id="progress_bar">
<property name="hexpand">true</property>
<style>
<class name="osd"/>
</style>
</object>
</child>
<child>
<object class="SysprofMemorySection">
<property name="category">callgraph</property>
<property name="icon-name">memory-allocations-symbolic</property>
<binding name="session">
<lookup name="session">SysprofWindow</lookup>
</binding>
</object>
</child>
<child>
<object class="SysprofLogsSection">
<property name="category">processes</property>
<property name="icon-name">system-log-symbolic</property>
<binding name="session">
<lookup name="session">SysprofWindow</lookup>
</binding>
</object>
</child>
<child>
<object class="SysprofMarksSection">
<property name="category">processes</property>
<property name="icon-name">mark-chart-symbolic</property>
<binding name="session">
<lookup name="session">SysprofWindow</lookup>
</binding>
</object>
</child>
<child>
<object class="SysprofProcessesSection">
<property name="category">processes</property>
<property name="icon-name">application-x-executable-symbolic</property>
<binding name="session">
<lookup name="session">SysprofWindow</lookup>
</binding>
</object>
</child>
<child>
<object class="SysprofDBusSection">
<property name="title" translatable="yes">D-Bus</property>
<property name="category">processes</property>
<property name="icon-name">dbus-symbolic</property>
<binding name="session">
<lookup name="session">SysprofWindow</lookup>
</binding>
</object>
</child>
<child>
<object class="SysprofCpuSection">
<property name="title" translatable="yes">CPU</property>
<property name="category">counters</property>
<property name="icon-name">system-run-symbolic</property>
<binding name="session">
<lookup name="session">SysprofWindow</lookup>
</binding>
</object>
</child>
<child>
<object class="SysprofEnergySection">
<property name="title" translatable="yes">Energy</property>
<property name="category">counters</property>
<property name="icon-name">energy-symbolic</property>
<binding name="session">
<lookup name="session">SysprofWindow</lookup>
</binding>
</object>
</child>
<child>
<object class="SysprofGraphicsSection">
<property name="title" translatable="yes">Graphics</property>
<property name="category">counters</property>
<property name="icon-name">graphics-symbolic</property>
<binding name="session">
<lookup name="session">SysprofWindow</lookup>
</binding>
</object>
</child>
<child>
<object class="SysprofNetworkSection">
<property name="title" translatable="yes">Network</property>
<property name="category">counters</property>
<property name="icon-name">network-transmit-receive-symbolic</property>
<binding name="session">
<lookup name="session">SysprofWindow</lookup>
</binding>
</object>
</child>
<child>
<object class="SysprofStorageSection">
<property name="title" translatable="yes">Storage</property>
<property name="category">counters</property>
<property name="icon-name">storage-symbolic</property>
<binding name="session">
<lookup name="session">SysprofWindow</lookup>
</binding>
</object>
</child>
<child>
<object class="SysprofFilesSection">
<property name="category">auxiliary</property>
<property name="icon-name">folder-symbolic</property>
<binding name="session">
<lookup name="session">SysprofWindow</lookup>
</binding>
</object>
</child>
<child>
<object class="SysprofMetadataSection">
<property name="category">auxiliary</property>
<property name="icon-name">metadata-symbolic</property>
<binding name="session">
<lookup name="session">SysprofWindow</lookup>
</binding>
<object class="GtkStack" id="section_stack">
<property name="vexpand">true</property>
<child>
<object class="SysprofSamplesSection">
<property name="category">callgraph</property>
<property name="icon-name">org.gnome.Sysprof-symbolic</property>
<binding name="session">
<lookup name="session">SysprofWindow</lookup>
</binding>
</object>
</child>
<child>
<object class="SysprofMemorySection">
<property name="category">callgraph</property>
<property name="icon-name">memory-allocations-symbolic</property>
<binding name="session">
<lookup name="session">SysprofWindow</lookup>
</binding>
</object>
</child>
<child>
<object class="SysprofLogsSection">
<property name="category">processes</property>
<property name="icon-name">system-log-symbolic</property>
<binding name="session">
<lookup name="session">SysprofWindow</lookup>
</binding>
</object>
</child>
<child>
<object class="SysprofMarksSection">
<property name="category">processes</property>
<property name="icon-name">mark-chart-symbolic</property>
<binding name="session">
<lookup name="session">SysprofWindow</lookup>
</binding>
</object>
</child>
<child>
<object class="SysprofProcessesSection">
<property name="category">processes</property>
<property name="icon-name">application-x-executable-symbolic</property>
<binding name="session">
<lookup name="session">SysprofWindow</lookup>
</binding>
</object>
</child>
<child>
<object class="SysprofDBusSection">
<property name="title" translatable="yes">D-Bus</property>
<property name="category">processes</property>
<property name="icon-name">dbus-symbolic</property>
<binding name="session">
<lookup name="session">SysprofWindow</lookup>
</binding>
</object>
</child>
<child>
<object class="SysprofCpuSection">
<property name="title" translatable="yes">CPU</property>
<property name="category">counters</property>
<property name="icon-name">system-run-symbolic</property>
<binding name="session">
<lookup name="session">SysprofWindow</lookup>
</binding>
</object>
</child>
<child>
<object class="SysprofEnergySection">
<property name="title" translatable="yes">Energy</property>
<property name="category">counters</property>
<property name="icon-name">energy-symbolic</property>
<binding name="session">
<lookup name="session">SysprofWindow</lookup>
</binding>
</object>
</child>
<child>
<object class="SysprofGraphicsSection">
<property name="title" translatable="yes">Graphics</property>
<property name="category">counters</property>
<property name="icon-name">graphics-symbolic</property>
<binding name="session">
<lookup name="session">SysprofWindow</lookup>
</binding>
</object>
</child>
<child>
<object class="SysprofNetworkSection">
<property name="title" translatable="yes">Network</property>
<property name="category">counters</property>
<property name="icon-name">network-transmit-receive-symbolic</property>
<binding name="session">
<lookup name="session">SysprofWindow</lookup>
</binding>
</object>
</child>
<child>
<object class="SysprofStorageSection">
<property name="title" translatable="yes">Storage</property>
<property name="category">counters</property>
<property name="icon-name">storage-symbolic</property>
<binding name="session">
<lookup name="session">SysprofWindow</lookup>
</binding>
</object>
</child>
<child>
<object class="SysprofFilesSection">
<property name="category">auxiliary</property>
<property name="icon-name">folder-symbolic</property>
<binding name="session">
<lookup name="session">SysprofWindow</lookup>
</binding>
</object>
</child>
<child>
<object class="SysprofMetadataSection">
<property name="category">auxiliary</property>
<property name="icon-name">metadata-symbolic</property>
<binding name="session">
<lookup name="session">SysprofWindow</lookup>
</binding>
</object>
</child>
</object>
</child>
</object>