shell/perf-helper: Use custom widget as content
The windows we create use a simple pattern as content, as that's easier to follow than completely empty windows. GTK4 no longer allows hooking into the drawing of arbitrary widgets, so prepare for that by using a dedicated subclass instead of a signal handler. Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2733>
This commit is contained in:
parent
54b4cfc69b
commit
1c5bc35e30
@ -63,16 +63,26 @@ G_DECLARE_FINAL_TYPE (PerfHelperWindow, perf_helper_window, PERF_HELPER, WINDOW,
|
|||||||
struct _PerfHelperWindow {
|
struct _PerfHelperWindow {
|
||||||
GtkApplicationWindow parent;
|
GtkApplicationWindow parent;
|
||||||
|
|
||||||
guint redraws : 1;
|
|
||||||
guint mapped : 1;
|
guint mapped : 1;
|
||||||
guint exposed : 1;
|
guint exposed : 1;
|
||||||
guint pending : 1;
|
guint pending : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (PerfHelperWindow, perf_helper_window, GTK_TYPE_APPLICATION_WINDOW);
|
||||||
|
|
||||||
|
#define PERF_HELPER_TYPE_WINDOW_CONTENT (perf_helper_window_content_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (PerfHelperWindowContent, perf_helper_window_content, PERF_HELPER, WINDOW_CONTENT, GtkBox)
|
||||||
|
|
||||||
|
struct _PerfHelperWindowContent {
|
||||||
|
GtkBox parent;
|
||||||
|
|
||||||
|
guint redraws : 1;
|
||||||
|
|
||||||
gint64 start_time;
|
gint64 start_time;
|
||||||
gint64 time;
|
gint64 time;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (PerfHelperWindow, perf_helper_window, GTK_TYPE_APPLICATION_WINDOW);
|
G_DEFINE_TYPE (PerfHelperWindowContent, perf_helper_window_content, GTK_TYPE_BOX);
|
||||||
|
|
||||||
static void destroy_windows (PerfHelperApp *app);
|
static void destroy_windows (PerfHelperApp *app);
|
||||||
static void finish_wait_windows (PerfHelperApp *app);
|
static void finish_wait_windows (PerfHelperApp *app);
|
||||||
@ -154,16 +164,14 @@ perf_helper_window_draw (GtkWidget *widget,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
on_child_draw (GtkWidget *widget,
|
perf_helper_window_content_draw (GtkWidget *widget,
|
||||||
cairo_t *cr,
|
cairo_t *cr)
|
||||||
gpointer user_data)
|
|
||||||
{
|
{
|
||||||
PerfHelperWindow *window;
|
PerfHelperWindowContent *content = PERF_HELPER_WINDOW_CONTENT (widget);
|
||||||
|
GtkWindow *window = GTK_WINDOW (gtk_widget_get_toplevel (widget));
|
||||||
cairo_rectangle_int_t allocation;
|
cairo_rectangle_int_t allocation;
|
||||||
double x_offset, y_offset;
|
double x_offset, y_offset;
|
||||||
|
|
||||||
window = PERF_HELPER_WINDOW (gtk_widget_get_toplevel (widget));
|
|
||||||
|
|
||||||
gtk_widget_get_allocation (widget, &allocation);
|
gtk_widget_get_allocation (widget, &allocation);
|
||||||
|
|
||||||
/* We draw an arbitrary pattern of red lines near the border of the
|
/* We draw an arbitrary pattern of red lines near the border of the
|
||||||
@ -171,9 +179,9 @@ on_child_draw (GtkWidget *widget,
|
|||||||
* is drastrically wrong.
|
* is drastrically wrong.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (window->redraws)
|
if (content->redraws)
|
||||||
{
|
{
|
||||||
double position = (window->time - window->start_time) / 1000000.;
|
double position = (content->time - content->start_time) / 1000000.;
|
||||||
x_offset = 20 * cos (2 * M_PI * position);
|
x_offset = 20 * cos (2 * M_PI * position);
|
||||||
y_offset = 20 * sin (2 * M_PI * position);
|
y_offset = 20 * sin (2 * M_PI * position);
|
||||||
}
|
}
|
||||||
@ -202,18 +210,37 @@ tick_callback (GtkWidget *widget,
|
|||||||
GdkFrameClock *frame_clock,
|
GdkFrameClock *frame_clock,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
PerfHelperWindow *window = PERF_HELPER_WINDOW (widget);
|
PerfHelperWindowContent *content = user_data;
|
||||||
|
|
||||||
if (window->start_time < 0)
|
if (content->start_time < 0)
|
||||||
window->start_time = window->time = gdk_frame_clock_get_frame_time (frame_clock);
|
content->start_time = content->time = gdk_frame_clock_get_frame_time (frame_clock);
|
||||||
else
|
else
|
||||||
window->time = gdk_frame_clock_get_frame_time (frame_clock);
|
content->time = gdk_frame_clock_get_frame_time (frame_clock);
|
||||||
|
|
||||||
gtk_widget_queue_draw (widget);
|
gtk_widget_queue_draw (widget);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GtkWidget *
|
||||||
|
perf_helper_window_content_new (gboolean redraws) {
|
||||||
|
PerfHelperWindowContent *content;
|
||||||
|
GtkWidget *widget;
|
||||||
|
|
||||||
|
content = g_object_new (PERF_HELPER_TYPE_WINDOW_CONTENT,
|
||||||
|
"visible", TRUE,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
content->redraws = redraws;
|
||||||
|
|
||||||
|
widget = GTK_WIDGET (content);
|
||||||
|
|
||||||
|
if (redraws)
|
||||||
|
gtk_widget_add_tick_callback (widget, tick_callback, content, NULL);
|
||||||
|
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
create_window (PerfHelperApp *app,
|
create_window (PerfHelperApp *app,
|
||||||
int width,
|
int width,
|
||||||
@ -230,7 +257,6 @@ create_window (PerfHelperApp *app,
|
|||||||
"application", app,
|
"application", app,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
window->redraws = redraws;
|
|
||||||
if (alpha)
|
if (alpha)
|
||||||
gtk_widget_set_visual (GTK_WIDGET (window), gdk_screen_get_rgba_visual (gdk_screen_get_default ()));
|
gtk_widget_set_visual (GTK_WIDGET (window), gdk_screen_get_rgba_visual (gdk_screen_get_default ()));
|
||||||
if (maximized)
|
if (maximized)
|
||||||
@ -245,18 +271,13 @@ create_window (PerfHelperApp *app,
|
|||||||
{
|
{
|
||||||
gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (window)),
|
gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (window)),
|
||||||
alpha ? "alpha" : "solid");
|
alpha ? "alpha" : "solid");
|
||||||
child = g_object_new (GTK_TYPE_BOX, "visible", TRUE, NULL);
|
child = perf_helper_window_content_new (redraws);
|
||||||
|
|
||||||
g_signal_connect (child, "draw", G_CALLBACK (on_child_draw), NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_container_add (GTK_CONTAINER (window), child);
|
gtk_container_add (GTK_CONTAINER (window), child);
|
||||||
|
|
||||||
gtk_widget_set_size_request (GTK_WIDGET (window), width, height);
|
gtk_widget_set_size_request (GTK_WIDGET (window), width, height);
|
||||||
gtk_widget_show (GTK_WIDGET (window));
|
gtk_widget_show (GTK_WIDGET (window));
|
||||||
|
|
||||||
if (redraws)
|
|
||||||
gtk_widget_add_tick_callback (GTK_WIDGET (window), tick_callback, NULL, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -396,6 +417,19 @@ perf_helper_app_class_init (PerfHelperAppClass *klass)
|
|||||||
gapp_class->dbus_register = perf_helper_app_dbus_register;
|
gapp_class->dbus_register = perf_helper_app_dbus_register;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
perf_helper_window_content_init (PerfHelperWindowContent *content)
|
||||||
|
{
|
||||||
|
content->start_time = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
perf_helper_window_content_class_init (PerfHelperWindowContentClass *klass) {
|
||||||
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||||
|
|
||||||
|
widget_class->draw = perf_helper_window_content_draw;
|
||||||
|
}
|
||||||
|
|
||||||
static PerfHelperApp *
|
static PerfHelperApp *
|
||||||
perf_helper_app_new (void) {
|
perf_helper_app_new (void) {
|
||||||
GApplicationFlags flags = G_APPLICATION_IS_SERVICE |
|
GApplicationFlags flags = G_APPLICATION_IS_SERVICE |
|
||||||
@ -412,7 +446,6 @@ static void
|
|||||||
perf_helper_window_init (PerfHelperWindow *window)
|
perf_helper_window_init (PerfHelperWindow *window)
|
||||||
{
|
{
|
||||||
window->pending = TRUE;
|
window->pending = TRUE;
|
||||||
window->start_time = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Loading…
Reference in New Issue
Block a user