changeset 10:adba37525ee5

Notify about required session or system restarts Follow all PackageKit transactions and indicate when a session or system restart is required. Generate enum types with glib-mkenums.
author Guido Berhoerster <guido+pui@berhoerster.name>
date Fri, 06 Jul 2018 14:12:46 +0200
parents b571e7ade208
children 7f995e958703
files Makefile po/POTFILES.in po/de.po po/en.po po/id.po pui-application.c pui-application.h pui-backend.c pui-backend.h pui-types.c pui-types.c.in pui-types.h pui-types.h.in
diffstat 13 files changed, 366 insertions(+), 178 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Wed Jul 04 17:08:47 2018 +0200
+++ b/Makefile	Fri Jul 06 14:12:46 2018 +0200
@@ -50,6 +50,7 @@
 SED :=		sed
 GLIB_COMPILE_SCHEMAS := $(shell pkg-config --variable=glib_compile_schemas gio-2.0)
 GLIB_COMPILE_RESOURCES := $(shell pkg-config --variable=glib_compile_resources gio-2.0)
+GLIB_MKENUMS :=	$(shell pkg-config --variable=glib_mkenums glib-2.0)
 XSLTPROC :=	xsltproc
 DOCBOOK5_MANPAGES_STYLESHEET = http://docbook.sourceforge.net/release/xsl-ns/current/manpages/docbook.xsl
 DOCBOOK5_MANPAGES_FLAGS = --stringparam man.authors.section.enabled 0 \
@@ -113,6 +114,14 @@
 
 OBJS = $($(PACKAGE)_OBJS) $($(PACKAGE)-prefs_OBJS)
 
+ENUM_DEPS =	pui-backend.h \
+		pui-application.h
+
+ENUM_HEADER =	pui-types.h
+
+ENUM_FILES =	$(ENUM_HEADER) \
+		pui-types.c
+
 GSETTINGS_SCHEMAS = $(APPLICATION_ID).gschema.xml
 
 GRESOURCE_FILES = pui-prefs.gresource.xml
@@ -176,6 +185,14 @@
 $(PACKAGE)-prefs: $($(PACKAGE)-prefs_OBJS)
 	$(LINK.o) $^ $(LDLIBS) -o $@
 
+$(OBJS): $(ENUM_HEADER)
+
+%-types.h: %-types.h.in $(ENUM_DEPS)
+	$(GLIB_MKENUMS) --template $< >$@ $(filter-out $<,$^)
+
+%-types.c: %-types.c.in $(ENUM_DEPS)
+	$(GLIB_MKENUMS) --template $< >$@ $(filter-out $<,$^)
+
 %-resources.c: %.gresource.xml
 	$(GLIB_COMPILE_RESOURCES) --generate-dependencies $< | \
 	    while read -r resource_file; do \
@@ -231,8 +248,8 @@
 	done
 
 clean:
-	rm -f $(PACKAGE) $(OBJS) $(AUTOSTART_FILE) $(DESKTOP_FILES) $(POTFILE) \
-	    $(MOFILES) $(MANPAGES)
+	rm -f $(PACKAGE) $(OBJS) $(ENUM_FILES) $(AUTOSTART_FILE) \
+	    $(DESKTOP_FILES) $(POTFILE) $(MOFILES) $(MANPAGES)
 
 clobber: clean
 	rm -f $(patsubst %.o,%.d,$(OBJS))
--- a/po/POTFILES.in	Wed Jul 04 17:08:47 2018 +0200
+++ b/po/POTFILES.in	Fri Jul 06 14:12:46 2018 +0200
@@ -11,4 +11,4 @@
 pui-prefs-application.c
 pui-prefs-window.ui
 pui-settings.c
-pui-types.c
+pui-types.c.in
--- a/po/de.po	Wed Jul 04 17:08:47 2018 +0200
+++ b/po/de.po	Fri Jul 06 14:12:46 2018 +0200
@@ -8,7 +8,7 @@
 "Project-Id-Version: package-update-indicator 1\n"
 "Report-Msgid-Bugs-To: guido+pui@berhoerster.name\n"
 "POT-Creation-Date: 2018-07-04 13:39+0000\n"
-"PO-Revision-Date: 2018-07-04 13:39+0000\n"
+"PO-Revision-Date: 2018-07-06 12:10+0000\n"
 "Last-Translator: Guido Berhoerster <guido+pui@berhoerster.name>\n"
 "Language-Team: none\n"
 "Language: de\n"
@@ -85,71 +85,88 @@
 msgid "Translator"
 msgstr "Guido Berhörster"
 
-#: pui-application.c:71
+#: pui-application.c:73
 msgid "Enable debugging messages"
 msgstr "Debugging-Nachrichten aktivieren"
 
-#: pui-application.c:73
+#: pui-application.c:75
 msgid "Quit running instance of Package Update Indicator"
 msgstr "Beende laufende Instanz der Paketaktualisierungsanzeige"
 
-#: pui-application.c:75
+#: pui-application.c:77
 msgid "Print the version number and quit"
 msgstr "Versionsnummer zeigen und beenden"
 
-#: pui-application.c:228
+#: pui-application.c:232
 msgid "Up to Date"
 msgstr "Auf dem neuesten Stand"
 
-#: pui-application.c:229
+#: pui-application.c:233
 msgid "The system is up to date."
 msgstr "Das System ist auf dem neuesten Stand"
 
-#: pui-application.c:232
+#: pui-application.c:236
 msgid "Software Update"
 msgid_plural "Software Updates"
 msgstr[0] "Softwareaktualisierung"
 msgstr[1] "Softwareaktualisierungen"
 
-#: pui-application.c:235
+#: pui-application.c:239
 msgid "There is a software update avaliable."
 msgstr "Es ist eine Softwareaktualisierung verfügbar."
 
-#: pui-application.c:238
+#: pui-application.c:242
 #, c-format
 msgid "There are %u software updates avaliable."
 msgstr "Es sind %u Softwareaktualisierungen verfügbar."
 
-#: pui-application.c:243
+#: pui-application.c:247
 msgid "Important Software Update"
 msgid_plural "Important Software Updates"
 msgstr[0] "Wichtige Softwareaktualisierung"
 msgstr[1] "Wichtige Softwareaktualisierungen"
 
-#: pui-application.c:246
+#: pui-application.c:250
 msgid "There is an important software update available."
 msgstr "Es ist eine wichtige Softwareaktualisierung verfügbar."
 
-#: pui-application.c:249
+#: pui-application.c:253
 #, c-format
 msgid "There are %u important software updates available."
 msgstr "Es sind %u wichtige Softwareaktualisierungen verfügbar."
 
-#: pui-application.c:253
+#: pui-application.c:257
 #, c-format
 msgid "There are %u software updates available, one of them is important."
 msgstr "Es sind %u Softwareaktualisierungen verfügbar, eine davon ist wichtig."
 
-#: pui-application.c:258
+#: pui-application.c:262
 #, c-format
 msgid "There are %u software updates available, %u of them are important."
 msgstr "Es sind %u Softwareaktualisierungen verfügbar, %u davon sind wichtig."
 
-#: pui-application.c:306
+#: pui-application.c:270
+msgid "Logout Required"
+msgstr "Abmeldung erforderlich"
+
+#: pui-application.c:271
+msgid "You need to log out and back in for the update to take effect."
+msgstr ""
+"Sie müssen sich aus- und wieder einloggen, damit das Update wirksam wird."
+
+#: pui-application.c:275
+msgid "Restart Required"
+msgstr "Neutstart Erforderlich"
+
+#: pui-application.c:276
+msgid "The computer has to be restarted for the updates to take effect."
+msgstr "Der Computer muss neu gestarte werden damit die Updates wirksam werden."
+
+#: pui-application.c:324
 msgid "Install Updates"
 msgstr "Installiere Updates"
 
-#: pui-application.c:403
+#: pui-application.c:434
 msgid "Update notifications are not supported."
 msgstr "Aktualisierungsbenachrichtigungen werden nicht unterstützt."
 
--- a/po/en.po	Wed Jul 04 17:08:47 2018 +0200
+++ b/po/en.po	Fri Jul 06 14:12:46 2018 +0200
@@ -8,7 +8,7 @@
 "Project-Id-Version: package-update-indicator 1\n"
 "Report-Msgid-Bugs-To: guido+pui@berhoerster.name\n"
 "POT-Creation-Date: 2018-07-04 13:39+0000\n"
-"PO-Revision-Date: 2018-07-04 13:39+0000\n"
+"PO-Revision-Date: 2018-07-06 12:10+0000\n"
 "Last-Translator: Guido Berhoerster <guido+pui@berhoerster.name>\n"
 "Language-Team: none\n"
 "Language: en\n"
@@ -83,71 +83,87 @@
 msgid "Translator"
 msgstr "Translator"
 
-#: pui-application.c:71
+#: pui-application.c:73
 msgid "Enable debugging messages"
 msgstr "Enable debugging messages"
 
-#: pui-application.c:73
+#: pui-application.c:75
 msgid "Quit running instance of Package Update Indicator"
 msgstr "Quit running instance of Package Update Indicator"
 
-#: pui-application.c:75
+#: pui-application.c:77
 msgid "Print the version number and quit"
 msgstr "Print the version number and quit"
 
-#: pui-application.c:228
+#: pui-application.c:232
 msgid "Up to Date"
 msgstr "Up to Date"
 
-#: pui-application.c:229
+#: pui-application.c:233
 msgid "The system is up to date."
 msgstr "The system is up to date."
 
-#: pui-application.c:232
+#: pui-application.c:236
 msgid "Software Update"
 msgid_plural "Software Updates"
 msgstr[0] "Software Update"
 msgstr[1] "Software Updates"
 
-#: pui-application.c:235
+#: pui-application.c:239
 msgid "There is a software update avaliable."
 msgstr "There is a software update avaliable."
 
-#: pui-application.c:238
+#: pui-application.c:242
 #, c-format
 msgid "There are %u software updates avaliable."
 msgstr "There are %u software updates avaliable."
 
-#: pui-application.c:243
+#: pui-application.c:247
 msgid "Important Software Update"
 msgid_plural "Important Software Updates"
 msgstr[0] "Important Software Update"
 msgstr[1] "Important Software Updates"
 
-#: pui-application.c:246
+#: pui-application.c:250
 msgid "There is an important software update available."
 msgstr "There is an important software update available."
 
-#: pui-application.c:249
+#: pui-application.c:253
 #, c-format
 msgid "There are %u important software updates available."
 msgstr "There are %u important software updates available."
 
-#: pui-application.c:253
+#: pui-application.c:257
 #, c-format
 msgid "There are %u software updates available, one of them is important."
 msgstr "There are %u software updates available, one of them is important."
 
-#: pui-application.c:258
+#: pui-application.c:262
 #, c-format
 msgid "There are %u software updates available, %u of them are important."
 msgstr "There are %u software updates available, %u of them are important."
 
-#: pui-application.c:306
+#: pui-application.c:270
+msgid "Logout Required"
+msgstr "Logout Required"
+
+#: pui-application.c:271
+msgid "You need to log out and back in for the update to take effect."
+msgstr "You need to log out and back in for the update to take effect."
+
+#: pui-application.c:275
+msgid "Restart Required"
+msgstr "Restart Required"
+
+#: pui-application.c:276
+msgid "The computer has to be restarted for the updates to take effect."
+msgstr "The computer has to be restarted for the updates to take effect."
+
+#: pui-application.c:324
 msgid "Install Updates"
 msgstr "Install Updates"
 
-#: pui-application.c:403
+#: pui-application.c:434
 msgid "Update notifications are not supported."
 msgstr "Update notifications are not supported."
 
--- a/po/id.po	Wed Jul 04 17:08:47 2018 +0200
+++ b/po/id.po	Fri Jul 06 14:12:46 2018 +0200
@@ -8,7 +8,7 @@
 "Project-Id-Version: package-update-indicator 1\n"
 "Report-Msgid-Bugs-To: guido+pui@berhoerster.name\n"
 "POT-Creation-Date: 2018-07-04 13:39+0000\n"
-"PO-Revision-Date: 2018-07-04 13:39+0000\n"
+"PO-Revision-Date: 2018-07-06 12:10+0000\n"
 "Last-Translator: Guido Berhoerster <guido+pui@berhoerster.name>\n"
 "Language-Team: none\n"
 "Language: id\n"
@@ -83,75 +83,91 @@
 msgid "Translator"
 msgstr "Guido Berhörster"
 
-#: pui-application.c:71
+#: pui-application.c:73
 msgid "Enable debugging messages"
 msgstr ""
 
-#: pui-application.c:73
-msgid "Quit running instance of Package Update Indicator"
-msgstr ""
-
 #: pui-application.c:75
+msgid "Quit running instance of Package Update Indicator"
+msgstr ""
+
+#: pui-application.c:77
 msgid "Print the version number and quit"
 msgstr "Tampilkan nomor versi dan keluar"
 
-#: pui-application.c:228
+#: pui-application.c:232
 msgid "Up to Date"
 msgstr "Up-to-date"
 
-#: pui-application.c:229
+#: pui-application.c:233
 msgid "The system is up to date."
 msgstr "Sistemnya telah up-to-date."
 
-#: pui-application.c:232
+#: pui-application.c:236
 msgid "Software Update"
 msgid_plural "Software Updates"
 msgstr[0] "Pembaharuan Perangkat Lunak"
 msgstr[1] "Pembaharuan-Pembaharuan Perangkat Lunak"
 
-#: pui-application.c:235
+#: pui-application.c:239
 msgid "There is a software update avaliable."
 msgstr "Tersedia satu pembaharuan perangkat lunak."
 
-#: pui-application.c:238
+#: pui-application.c:242
 #, c-format
 msgid "There are %u software updates avaliable."
 msgstr "Tersedia %u pembaharuan-pembaharuan perangkat lunak."
 
-#: pui-application.c:243
+#: pui-application.c:247
 msgid "Important Software Update"
 msgid_plural "Important Software Updates"
 msgstr[0] "Perangkat Lunak Pembaharuan yang penting"
 msgstr[1] "Perangkat Lunak Pembaharuan-Pembaharuan yang penting"
 
-#: pui-application.c:246
+#: pui-application.c:250
 msgid "There is an important software update available."
 msgstr "Tersedia satu pembaharuan perangkat lunak yang penting."
 
-#: pui-application.c:249
+#: pui-application.c:253
 #, c-format
 msgid "There are %u important software updates available."
 msgstr "Tersedia %u pembaharuan-pembaharuan perangkat lunak yang penting."
 
-#: pui-application.c:253
+#: pui-application.c:257
 #, c-format
 msgid "There are %u software updates available, one of them is important."
 msgstr ""
 "Tersedia %u pembaharuan-pembaharuan perangkat lunak, diantaranya satu yang "
 "penting."
 
-#: pui-application.c:258
+#: pui-application.c:262
 #, c-format
 msgid "There are %u software updates available, %u of them are important."
 msgstr ""
 "Tersedia %u pembaharuan-pembaharuan perangkat lunak, diantaranya %u yang "
 "penting."
 
-#: pui-application.c:306
+#: pui-application.c:270
+msgid "Logout Required"
+msgstr "Diperlukan Log Keluar"
+
+#: pui-application.c:271
+msgid "You need to log out and back in for the update to take effect."
+msgstr ""
+
+#: pui-application.c:275
+msgid "Restart Required"
+msgstr "Diperlukan Reboot"
+
+#: pui-application.c:276
+msgid "The computer has to be restarted for the updates to take effect."
+msgstr ""
+
+#: pui-application.c:324
 msgid "Install Updates"
 msgstr "Pasang Perangkat Lunak Pembaharuan-Pembaharuan"
 
-#: pui-application.c:403
+#: pui-application.c:434
 msgid "Update notifications are not supported."
 msgstr "Pemberitahuan pembaharuan-pembaharuan tidak didukung."
 
--- a/pui-application.c	Wed Jul 04 17:08:47 2018 +0200
+++ b/pui-application.c	Fri Jul 06 14:12:46 2018 +0200
@@ -63,6 +63,8 @@
     [PUI_STATE_UP_TO_DATE] = "system-software-update",
     [PUI_STATE_NORMAL_UPDATES_AVAILABLE] = "software-update-available",
     [PUI_STATE_IMPORTANT_UPDATES_AVAILABLE] = "software-update-urgent",
+    [PUI_STATE_SESSION_RESTART_REQUIRED] = "system-log-out",
+    [PUI_STATE_SYSTEM_RESTART_REQUIRED] = "system-reboot",
     [PUI_STATE_ERROR] = "dialog-warning"
 };
 
@@ -208,6 +210,8 @@
 	switch (self->state) {
 	case PUI_STATE_INITIAL:				/* FALLTHGROUGH */
 	case PUI_STATE_UP_TO_DATE:			/* FALLTHGROUGH */
+	case PUI_STATE_SESSION_RESTART_REQUIRED:	/* FALLTHGROUGH */
+	case PUI_STATE_SYSTEM_RESTART_REQUIRED:		/* FALLTHGROUGH */
 	case PUI_STATE_ERROR:
 		g_simple_action_set_enabled(install_updates_action, FALSE);
 		break;
@@ -262,6 +266,16 @@
 			    important_updates);
 		}
 		break;
+	case PUI_STATE_SESSION_RESTART_REQUIRED:
+		title = g_strdup(_("Logout Required"));
+		body = g_strdup(_("You need to log out and back in for the "
+		    "update to take effect."));
+		break;
+	case PUI_STATE_SYSTEM_RESTART_REQUIRED:
+		title = g_strdup(_("Restart Required"));
+		body = g_strdup(_("The computer has to be restarted for the "
+		    "updates to take effect."));
+		break;
 	case PUI_STATE_ERROR:
 		title = g_strdup(self->error_message);
 		break;
@@ -276,6 +290,8 @@
 	case PUI_STATE_UP_TO_DATE:			/* FALLTHGROUGH */
 	case PUI_STATE_NORMAL_UPDATES_AVAILABLE:	/* FALLTHGROUGH */
 	case PUI_STATE_IMPORTANT_UPDATES_AVAILABLE:	/* FALLTHGROUGH */
+	case PUI_STATE_SESSION_RESTART_REQUIRED:	/* FALLTHGROUGH */
+	case PUI_STATE_SYSTEM_RESTART_REQUIRED:		/* FALLTHGROUGH */
 	case PUI_STATE_ERROR:
 		app_indicator_set_status(self->indicator,
 		    APP_INDICATOR_STATUS_ACTIVE);
@@ -291,10 +307,12 @@
 	case PUI_STATE_ERROR:
 		/* withdraw exisiting notification */
 		g_application_withdraw_notification(application,
-		    "package-updates");
+		    "package-updates-or-restart-required");
 		break;
 	case PUI_STATE_NORMAL_UPDATES_AVAILABLE:	/* FALLTHGROUGH */
-	case PUI_STATE_IMPORTANT_UPDATES_AVAILABLE:
+	case PUI_STATE_IMPORTANT_UPDATES_AVAILABLE:	/* FALLTHGROUGH */
+	case PUI_STATE_SESSION_RESTART_REQUIRED:	/* FALLTHGROUGH */
+	case PUI_STATE_SYSTEM_RESTART_REQUIRED:
 		/* create notification */
 		notification = g_notification_new(title);
 		g_notification_set_body(notification, body);
@@ -306,8 +324,8 @@
 			    _("Install Updates"),
 			    "app.install-updates");
 		}
-		g_application_send_notification(application, "package-updates",
-		    notification);
+		g_application_send_notification(application,
+		    "package-updates-or-restart-required", notification);
 		break;
 	}
 
@@ -326,6 +344,7 @@
 transition_state(PuiApplication *self)
 {
 	PuiState	state = self->state;
+	PuiRestart	restart_type;
 	guint		important_updates;
 	guint		normal_updates;
 	gchar		*old_state;
@@ -341,10 +360,14 @@
 			break;
 		}
 
-		g_object_get(self->backend,
+		g_object_get(self->backend, "restart-type", &restart_type,
 		    "important-updates", &important_updates,
 		    "normal-updates", &normal_updates, NULL);
-		if (important_updates > 0) {
+		if (restart_type == PUI_RESTART_SESSION) {
+			state = PUI_STATE_SESSION_RESTART_REQUIRED;
+		} else if (restart_type == PUI_RESTART_SYSTEM) {
+			state = PUI_STATE_SYSTEM_RESTART_REQUIRED;
+		} else if (important_updates > 0) {
 			state = PUI_STATE_IMPORTANT_UPDATES_AVAILABLE;
 		} else if (normal_updates > 0) {
 			state = PUI_STATE_NORMAL_UPDATES_AVAILABLE;
@@ -352,6 +375,14 @@
 			state = PUI_STATE_UP_TO_DATE;
 		}
 		break;
+	case PUI_STATE_SESSION_RESTART_REQUIRED:
+		g_object_get(self->backend, "restart-type", &restart_type,
+		    NULL);
+		if (restart_type == PUI_RESTART_SYSTEM) {
+			state = PUI_STATE_SYSTEM_RESTART_REQUIRED;
+		}
+		break;
+	case PUI_STATE_SYSTEM_RESTART_REQUIRED:		/* FALLTHROUGH */
 	case PUI_STATE_ERROR:
 		break;
 	}
--- a/pui-application.h	Wed Jul 04 17:08:47 2018 +0200
+++ b/pui-application.h	Fri Jul 06 14:12:46 2018 +0200
@@ -34,6 +34,17 @@
 G_DECLARE_FINAL_TYPE(PuiApplication, pui_application, PUI, APPLICATION,
     GApplication)
 
+typedef enum {
+    PUI_STATE_INITIAL,
+    PUI_STATE_UP_TO_DATE,
+    PUI_STATE_NORMAL_UPDATES_AVAILABLE,
+    PUI_STATE_IMPORTANT_UPDATES_AVAILABLE,
+    PUI_STATE_SESSION_RESTART_REQUIRED,
+    PUI_STATE_SYSTEM_RESTART_REQUIRED,
+    PUI_STATE_ERROR,
+    PUI_STATE_LAST
+} PuiState;
+
 PuiApplication *	pui_application_new(void);
 
 G_END_DECLS
--- a/pui-backend.c	Wed Jul 04 17:08:47 2018 +0200
+++ b/pui-backend.c	Fri Jul 06 14:12:46 2018 +0200
@@ -34,6 +34,7 @@
 #include "pui-common.h"
 #include "pui-backend.h"
 #include "pui-get-updates.h"
+#include "pui-types.h"
 
 #define	LOW_BATTERY_THRESHOLD	10.0
 
@@ -41,6 +42,8 @@
 	GObject		parent_instance;
 	PkControl	*pk_control;
 	GCancellable	*cancellable;
+	PkClient	*pk_client;
+	PkTransactionList *transaction_list;
 	UpClient	*up_client;
 	UpDevice	*up_device;
 	gchar		*proxy_http;
@@ -58,6 +61,7 @@
 	gboolean	use_mobile_connection;
 	guint		important_updates;
 	guint		normal_updates;
+	PuiRestart	restart_type;
 };
 
 static void	pui_backend_async_initable_iface_init(gpointer, gpointer);
@@ -76,6 +80,7 @@
     PROP_0,
     PROP_IMPORTANT_UPDATES,
     PROP_NORMAL_UPDATES,
+    PROP_RESTART_TYPE,
     PROP_REFRESH_INTERVAL,
     PROP_USE_MOBILE_CONNECTION,
     PROP_LAST
@@ -276,6 +281,9 @@
 	case PROP_NORMAL_UPDATES:
 		g_value_set_uint(value, self->normal_updates);
 		break;
+	case PROP_RESTART_TYPE:
+		g_value_set_enum(value, self->restart_type);
+		break;
 	case PROP_REFRESH_INTERVAL:
 		g_value_set_uint(value, self->refresh_interval);
 		break;
@@ -298,6 +306,14 @@
 		self->periodic_check_id = 0;
 	}
 
+	if (self->transaction_list != NULL) {
+		g_clear_object(&self->transaction_list);
+	}
+
+	if (self->pk_client != NULL) {
+		g_clear_object(&self->pk_client);
+	}
+
 	if (self->cancellable != NULL) {
 		g_cancellable_cancel(self->cancellable);
 		g_clear_object(&self->cancellable);
@@ -353,6 +369,11 @@
 	    "Number of available normal updates", 0, G_MAXUINT, 0,
 	    G_PARAM_READABLE);
 
+	properties[PROP_RESTART_TYPE] =
+	    g_param_spec_enum("restart-type", "Type of restart required",
+	    "The Type of restart required", PUI_TYPE_RESTART, PUI_RESTART_NONE,
+	    G_PARAM_READABLE);
+
 	properties[PROP_REFRESH_INTERVAL] =
 	    g_param_spec_uint("refresh-interval", "Refresh interval",
 	    "Interval in seconds for refreshing the package cache", 0,
@@ -382,6 +403,8 @@
 {
 	self->pk_control = pk_control_new();
 
+	self->pk_client = pk_client_new();
+
 	self->inhibited = TRUE;
 
 	self->up_client = up_client_new();
@@ -470,6 +493,8 @@
 {
 	PuiBackend	*self = user_data;
 
+	g_debug("number of updates changed");
+
 	/*
 	 * schedule a check after a short delay so that a rapid succession of
 	 * signals is coalesced
@@ -489,11 +514,85 @@
 {
 	PuiBackend	*self = user_data;
 
+	/*
+	 * do not restart package-update-indicator if a session or system
+	 * restart is required since that iformation would be lost across the
+	 * restart, rather keep running and risk errors when interacting with
+	 * a newer version of the PackageKit daemon
+	 */
+	if (self->restart_type > PUI_RESTART_NONE) {
+		return;
+	}
+
 	g_debug("emitting signal restart-required");
 	g_signal_emit(self, signals[RESTART_REQUIRED], 0);
 }
 
 static void
+on_transaction_adopt_finish(GObject *source_object, GAsyncResult *result,
+    gpointer user_data)
+{
+	PuiBackend	*self = user_data;
+	PkClient	*pk_client = PK_CLIENT(source_object);
+	PkResults	*results;
+	GError		*error = NULL;
+	PkRestartEnum	restart;
+
+	results = pk_client_generic_finish(pk_client, result, &error);
+	if (results == NULL) {
+		g_warning("failed to get transaction results: %s",
+		    error->message);
+		g_error_free(error);
+		goto out;
+	}
+
+	/* check if transaction requires a restart */
+	restart = pk_results_get_require_restart_worst(results);
+	switch (restart) {
+	case PK_RESTART_ENUM_SESSION:		/* FALLTHROUGH */
+	case PK_RESTART_ENUM_SECURITY_SESSION:
+		if (self->restart_type < PUI_RESTART_SESSION) {
+			self->restart_type = PUI_RESTART_SESSION;
+			g_object_notify_by_pspec(G_OBJECT(self),
+			    properties[PROP_RESTART_TYPE]);
+			g_signal_emit(self, signals[STATE_CHANGED], 0);
+		}
+		break;
+	case PK_RESTART_ENUM_SYSTEM:		/* FALLTHROUGH */
+	case PK_RESTART_ENUM_SECURITY_SYSTEM:
+		if (self->restart_type < PUI_RESTART_SYSTEM) {
+			self->restart_type = PUI_RESTART_SYSTEM;
+			g_object_notify_by_pspec(G_OBJECT(self),
+			    properties[PROP_RESTART_TYPE]);
+			g_signal_emit(self, signals[STATE_CHANGED], 0);
+		}
+		break;
+	default:
+		/* do nothing */
+		break;
+	}
+
+	g_debug("transaction finished, required restart: %s",
+	    pk_restart_enum_to_string(restart));
+
+out:
+	if (results != NULL) {
+		g_object_unref(results);
+	}
+}
+
+static void
+on_transaction_list_added(PkTransactionList *transaction_list,
+    const gchar *transaction_id, gpointer user_data)
+{
+	PuiBackend	*self = user_data;
+
+	/* adopt transaction in order to monitor it for restart requirements */
+	pk_client_adopt_async(self->pk_client, transaction_id, NULL, NULL,
+	    NULL, on_transaction_adopt_finish, user_data);
+}
+
+static void
 pui_backend_init_async(GAsyncInitable *initable, int io_priority,
     GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
 {
@@ -546,6 +645,10 @@
 	/* get notifications when an application restart is required */
 	g_signal_connect(self->pk_control, "restart-schedule",
 	    G_CALLBACK(on_restart_schedule), self);
+	/* get notifications when a transactions are added */
+	self->transaction_list = pk_transaction_list_new();
+	g_signal_connect(self->transaction_list, "added",
+	    G_CALLBACK(on_transaction_list_added), self);
 
 	check_inhibit(self);
 
--- a/pui-backend.h	Wed Jul 04 17:08:47 2018 +0200
+++ b/pui-backend.h	Fri Jul 06 14:12:46 2018 +0200
@@ -39,6 +39,13 @@
     PUI_BACKEND_ERROR_GET_UPDATES_NOT_IMPLEMENTED
 };
 
+typedef enum {
+    PUI_RESTART_NONE,
+    PUI_RESTART_SESSION,
+    PUI_RESTART_SYSTEM,
+    PUI_RESTART_LAST
+} PuiRestart;
+
 GQuark		pui_backend_error_quark(void);
 void		pui_backend_new_async(GCancellable *, GAsyncReadyCallback,
     gpointer);
--- a/pui-types.c	Wed Jul 04 17:08:47 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2018 Guido Berhoerster <guido+pui@berhoerster.name>
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "pui-types.h"
-
-#define	PUI_DEFINE_ENUM_VALUE(valuename, valuenick) \
-    { valuename, #valuename, #valuenick },
-#define PUI_DEFINE_ENUM_TYPE(EnumName, enum_name, values) \
-    GType                                                                     \
-    enum_name##_get_type(void)                                                \
-    {                                                                         \
-    	static volatile gsize g_define_type_id__volatile = 0;                 \
-    	static const GEnumValue v[] = {                                       \
-    	    values                                                            \
-    	    { 0 }                                                             \
-    	};                                                                    \
-    	GType		g_define_type_id;                                     \
-    	if (g_once_init_enter(&g_define_type_id__volatile)) {                 \
-    		g_define_type_id =                                            \
-    		    g_enum_register_static(g_intern_static_string(#EnumName), \
-    		    v);                                                       \
-    		g_once_init_leave(&g_define_type_id__volatile,                \
-    		    g_define_type_id);                                        \
-    	}                                                                     \
-    	return (g_define_type_id__volatile);                                  \
-    }
-
-PUI_DEFINE_ENUM_TYPE(PuiState, pui_state,
-    PUI_DEFINE_ENUM_VALUE(PUI_STATE_UP_TO_DATE, "up-to-date")
-    PUI_DEFINE_ENUM_VALUE(PUI_STATE_NORMAL_UPDATES_AVAILABLE,
-    "normal-updates-available")
-    PUI_DEFINE_ENUM_VALUE(PUI_STATE_IMPORTANT_UPDATES_AVAILABLE,
-    "important-updates-available")
-    PUI_DEFINE_ENUM_VALUE(PUI_STATE_ERROR, "error"))
-
-gchar *
-pui_types_enum_to_string(GType type, gint value)
-{
-	GTypeClass	*type_class;
-	GEnumValue	*enum_value;
-
-	type_class = g_type_class_ref(type);
-
-	g_return_val_if_fail(G_IS_ENUM_CLASS(type_class), NULL);
-
-	enum_value = g_enum_get_value(G_ENUM_CLASS(type_class), value);
-	if (enum_value == NULL) {
-		return (g_strdup_printf("%d", value));
-	}
-
-	return (g_strdup(enum_value->value_nick));
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pui-types.c.in	Fri Jul 06 14:12:46 2018 +0200
@@ -0,0 +1,61 @@
+/*** BEGIN file-header ***/
+#include "pui-types.h"
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+
+/* enumerations from "@filename@" */
+#include "@filename@"
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+
+GType
+@enum_name@_get_type (void)
+{
+	static volatile gsize g_define_type_id__volatile;
+	GType		g_@type@_type_id;
+
+	if (g_once_init_enter(&g_define_type_id__volatile)) {
+		static const G@Type@Value values[] = {
+/*** END value-header ***/
+
+/*** BEGIN value-production ***/
+		    { @VALUENAME@, "@VALUENAME@", "@valuenick@" },
+/*** END value-production ***/
+
+/*** BEGIN value-tail ***/
+		    { 0 }
+		};
+
+		g_@type@_type_id = g_@type@_register_static(
+		    g_intern_static_string("@EnumName@"), values);
+
+		g_once_init_leave(&g_define_type_id__volatile,
+		    g_@type@_type_id);
+	}
+
+	return (g_define_type_id__volatile);
+}
+/*** END value-tail ***/
+
+/*** BEGIN file-tail ***/
+
+gchar *
+pui_types_enum_to_string(GType type, gint value)
+{
+	GTypeClass	*type_class;
+	GEnumValue	*enum_value;
+
+	type_class = g_type_class_ref(type);
+
+	g_return_val_if_fail(G_IS_ENUM_CLASS(type_class), NULL);
+
+	enum_value = g_enum_get_value(G_ENUM_CLASS(type_class), value);
+	if (enum_value == NULL) {
+		return (g_strdup_printf("%d", value));
+	}
+
+	return (g_strdup(enum_value->value_nick));
+}
+/*** END file-tail ***/
--- a/pui-types.h	Wed Jul 04 17:08:47 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2018 Guido Berhoerster <guido+pui@berhoerster.name>
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef	PUI_TYPES_H
-#define	PUI_TYPES_H
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define	PUI_TYPE_STATE	(pui_state_get_type())
-
-typedef enum {
-    PUI_STATE_INITIAL,
-    PUI_STATE_UP_TO_DATE,
-    PUI_STATE_NORMAL_UPDATES_AVAILABLE,
-    PUI_STATE_IMPORTANT_UPDATES_AVAILABLE,
-    PUI_STATE_ERROR,
-    PUI_STATE_LAST
-} PuiState;
-
-GType	pui_state_get_type(void);
-gchar *	pui_types_enum_to_string(GType, gint);
-
-G_END_DECLS
-
-#endif /* !PUI_TYPES_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pui-types.h.in	Fri Jul 06 14:12:46 2018 +0200
@@ -0,0 +1,28 @@
+/*** BEGIN file-header ***/
+#ifndef	PUI_TYPES_H
+#define	PUI_TYPES_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+
+/* enumerations from "@filename@" */
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+
+#define	@ENUMPREFIX@_TYPE_@ENUMSHORT@	(@enum_name@_get_type())
+GType	@enum_name@_get_type(void) G_GNUC_CONST;
+/*** END value-header ***/
+
+/*** BEGIN file-tail ***/
+
+gchar *	pui_types_enum_to_string(GType, gint);
+
+G_END_DECLS
+
+#endif /* !PUI_TYPES_H */
+/*** END file-tail ***/