1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
* vi:set noexpandtab tabstop=8 shiftwidth=8:
*
* Copyright (C) 2013 Matthias Clasen <mclasen@redhat.com>
* Copyright (C) 2019 Richard Hughes <richard@hughsie.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include "config.h"
#include "gs-app-tile.h"
#include "gs-common.h"
typedef struct {
GsApp *app;
guint app_state_changed_idle_id;
} GsAppTilePrivate;
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GsAppTile, gs_app_tile, GTK_TYPE_BUTTON)
GsApp *
gs_app_tile_get_app (GsAppTile *self)
{
GsAppTilePrivate *priv = gs_app_tile_get_instance_private (self);
g_return_val_if_fail (GS_IS_APP_TILE (self), NULL);
return priv->app;
}
static gboolean
gs_app_tile_state_changed_idle_cb (gpointer user_data)
{
GsAppTile *self = GS_APP_TILE (user_data);
GsAppTileClass *klass = GS_APP_TILE_GET_CLASS (self);
GsAppTilePrivate *priv = gs_app_tile_get_instance_private (self);
priv->app_state_changed_idle_id = 0;
klass->refresh (self);
return G_SOURCE_REMOVE;
}
static void
gs_app_tile_state_changed_cb (GsApp *app, GParamSpec *pspec, GsAppTile *self)
{
GsAppTilePrivate *priv = gs_app_tile_get_instance_private (self);
g_clear_handle_id (&priv->app_state_changed_idle_id, g_source_remove);
priv->app_state_changed_idle_id = g_idle_add (gs_app_tile_state_changed_idle_cb, self);
}
void
gs_app_tile_set_app (GsAppTile *self, GsApp *app)
{
GsAppTileClass *klass = GS_APP_TILE_GET_CLASS (self);
GsAppTilePrivate *priv = gs_app_tile_get_instance_private (self);
g_return_if_fail (GS_IS_APP_TILE (self));
g_return_if_fail (!app || GS_IS_APP (app));
/* cancel pending refresh */
g_clear_handle_id (&priv->app_state_changed_idle_id, g_source_remove);
/* disconnect old app */
if (priv->app != NULL)
g_signal_handlers_disconnect_by_func (priv->app, gs_app_tile_state_changed_cb, self);
g_set_object (&priv->app, app);
/* optional refresh */
if (klass->refresh != NULL && priv->app != NULL) {
g_signal_connect (app, "notify::state",
G_CALLBACK (gs_app_tile_state_changed_cb), self);
g_signal_connect (app, "notify::name",
G_CALLBACK (gs_app_tile_state_changed_cb), self);
g_signal_connect (app, "notify::summary",
G_CALLBACK (gs_app_tile_state_changed_cb), self);
g_signal_connect (app, "notify::key-colors",
G_CALLBACK (gs_app_tile_state_changed_cb), self);
klass->refresh (self);
}
}
static void
gs_app_tile_finalize (GObject *object)
{
GsAppTile *self = GS_APP_TILE (object);
GsAppTilePrivate *priv = gs_app_tile_get_instance_private (self);
if (priv->app != NULL)
g_signal_handlers_disconnect_by_func (priv->app, gs_app_tile_state_changed_cb, self);
g_clear_handle_id (&priv->app_state_changed_idle_id, g_source_remove);
g_clear_object (&priv->app);
G_OBJECT_CLASS (gs_app_tile_parent_class)->finalize (object);
}
void
gs_app_tile_class_init (GsAppTileClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = gs_app_tile_finalize;
}
void
gs_app_tile_init (GsAppTile *self)
{
GsAppTilePrivate *priv = gs_app_tile_get_instance_private (self);
priv->app_state_changed_idle_id = 0;
}
GtkWidget *
gs_app_tile_new (GsApp *app)
{
GsAppTile *self = g_object_new (GS_TYPE_APP_TILE, NULL);
gs_app_tile_set_app (self, app);
return GTK_WIDGET (self);
}
|