2006-10-24 Dan Williams <dcbw@redhat.com>

Reduce the number of times the Gnome applet wakes up, especially when
	it's doing absolutely nothing and is hidden.  Initial patch by
	Chris Aillon.

	* gnome/applet/applet-dbus.c
		- (nma_dbus_filter): when NM isn't around, or when it goes away,
			kill the redraw timeout.  When NM starts up, start the redraw
			timeout.  Also, if we get kicked off the bus for some reason,
			start the reconnection timeout if one's not already running.
		- (nma_dbus_init): better handling of error conditions, don't leak
			a half-initialized dbus connection
		- (nma_dbus_connection_watcher): consolidate places we reinitialize
			the applet's data, just call nm_dbus_init_helper()
		- (nma_start_dbus_connection_watch): new function, starts a periodic
			timeout that calls nma_dbus_connection_watcher()
		- (nma_dbus_init_helper): if we get a successful connection, kill the
			reconnection timeout, and don't start the reconnection timeout
			unconditionally anymore

	* gnome/applet/applet-dbus.h
		- Expose nma_start_dbus_connection_watch()

	* gnome/applet/applet.c
		- (nma_update_state): no longer static, called from applet-dbus.c for
			immediate UI updates on certain events
		- (nma_set_running): new function; take over setting applet->running,
			when not running (ie, NM is not active), don't activate the redraw
			timeout because we're not showing the applet anyway.  When we are
			running (ie, NM is active), and only when we're running, start the
			redraw timeout.
		- (nma_destroy): kill the redraw timeout by setting 'not running', and
			kill any reconnection timeout
		- (nma_get_instance): move one-off dbus initialization code here since
			nm_dbus_init_helper() gets called more than once, possibly by the
			reconnection timeout function too.  And, when we start up, if we
			can't get a connection to the bus, start the reconnection timeout.
			But don't start the redraw timeout yet, only do that when we get
			NM's state and find out if it's running or not.

	* gnome/applet/applet.h
		- Add the reconnection GSource ID
		- Add prototypes for nma_set_running() and the no-longer-static
			nma_update_state()


git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@2084 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams 2006-10-25 03:57:41 +00:00
parent 76a78cba54
commit 9fa4a67aa5
5 changed files with 184 additions and 73 deletions

View file

@ -1,3 +1,49 @@
2006-10-24 Dan Williams <dcbw@redhat.com>
Reduce the number of times the Gnome applet wakes up, especially when
it's doing absolutely nothing and is hidden. Initial patch by
Chris Aillon.
* gnome/applet/applet-dbus.c
- (nma_dbus_filter): when NM isn't around, or when it goes away,
kill the redraw timeout. When NM starts up, start the redraw
timeout. Also, if we get kicked off the bus for some reason,
start the reconnection timeout if one's not already running.
- (nma_dbus_init): better handling of error conditions, don't leak
a half-initialized dbus connection
- (nma_dbus_connection_watcher): consolidate places we reinitialize
the applet's data, just call nm_dbus_init_helper()
- (nma_start_dbus_connection_watch): new function, starts a periodic
timeout that calls nma_dbus_connection_watcher()
- (nma_dbus_init_helper): if we get a successful connection, kill the
reconnection timeout, and don't start the reconnection timeout
unconditionally anymore
* gnome/applet/applet-dbus.h
- Expose nma_start_dbus_connection_watch()
* gnome/applet/applet.c
- (nma_update_state): no longer static, called from applet-dbus.c for
immediate UI updates on certain events
- (nma_set_running): new function; take over setting applet->running,
when not running (ie, NM is not active), don't activate the redraw
timeout because we're not showing the applet anyway. When we are
running (ie, NM is active), and only when we're running, start the
redraw timeout.
- (nma_destroy): kill the redraw timeout by setting 'not running', and
kill any reconnection timeout
- (nma_get_instance): move one-off dbus initialization code here since
nm_dbus_init_helper() gets called more than once, possibly by the
reconnection timeout function too. And, when we start up, if we
can't get a connection to the bus, start the reconnection timeout.
But don't start the redraw timeout yet, only do that when we get
NM's state and find out if it's running or not.
* gnome/applet/applet.h
- Add the reconnection GSource ID
- Add prototypes for nma_set_running() and the no-longer-static
nma_update_state()
2006-10-24 Dan Williams <dcbw@redhat.com>
* src/vpn-daemons/nm-dbus-vpnc.c

View file

@ -72,7 +72,9 @@ static DBusHandlerResult nma_dbus_filter (DBusConnection *connection, DBusMessag
{
dbus_connection_unref (applet->connection);
applet->connection = NULL;
applet->nm_running = FALSE;
nma_set_running (applet, FALSE);
if (!applet->connection_timeout_id)
nma_start_dbus_connection_watch (applet);
}
else if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameOwnerChanged"))
{
@ -94,18 +96,25 @@ static DBusHandlerResult nma_dbus_filter (DBusConnection *connection, DBusMessag
if (!old_owner_good && new_owner_good && !applet->nm_running)
{
/* NetworkManager started up */
applet->nm_running = TRUE;
nma_set_running (applet, TRUE);
nma_set_state (applet, NM_STATE_DISCONNECTED);
nma_dbus_update_nm_state (applet);
nma_dbus_update_devices (applet);
nma_dbus_update_dialup (applet);
nma_dbus_vpn_update_vpn_connections (applet);
/* Immediate redraw */
nma_update_state (applet);
}
else if (old_owner_good && !new_owner_good)
{
applet->nm_running = FALSE;
nma_set_state (applet, NM_STATE_DISCONNECTED);
nma_set_running (applet, FALSE);
nmi_passphrase_dialog_destroy (applet);
/* One last redraw to capture new state before sleeping */
nma_update_state (applet);
}
}
}
@ -322,68 +331,94 @@ static DBusConnection * nma_dbus_init (NMApplet *applet)
DBusError error;
DBusObjectPathVTable vtable = { NULL, &nmi_dbus_info_message_handler, NULL, NULL, NULL, NULL };
int acquisition;
dbus_bool_t success = FALSE;
g_return_val_if_fail (applet != NULL, NULL);
dbus_error_init (&error);
connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
if (dbus_error_is_set (&error))
{
if (dbus_error_is_set (&error)) {
nm_warning ("%s raised:\n %s\n\n", error.name, error.message);
dbus_error_free (&error);
return NULL;
goto error;
}
dbus_error_init (&error);
acquisition = dbus_bus_request_name (connection, NMI_DBUS_SERVICE, DBUS_NAME_FLAG_REPLACE_EXISTING, &error);
if (dbus_error_is_set (&error))
{
nm_warning ("nma_dbus_init() could not acquire its service. dbus_bus_acquire_service() says: '%s'", error.message);
dbus_error_free (&error);
return NULL;
acquisition = dbus_bus_request_name (connection,
NMI_DBUS_SERVICE,
DBUS_NAME_FLAG_REPLACE_EXISTING,
&error);
if (dbus_error_is_set (&error)) {
nm_warning ("could not acquire its service. dbus_bus_acquire_service()"
" says: '%s'",
error.message);
goto error;
}
if (acquisition == DBUS_REQUEST_NAME_REPLY_EXISTS)
return NULL;
goto error;
if (!dbus_connection_register_object_path (connection, NMI_DBUS_PATH, &vtable, applet))
{
nm_warning ("nma_dbus_init() could not register a handler for NetworkManagerInfo. Not enough memory?");
return NULL;
success = dbus_connection_register_object_path (connection,
NMI_DBUS_PATH,
&vtable,
applet);
if (!success) {
nm_warning ("could not register a messgae handler for the"
" NetworkManagerInfo service. Not enough memory?");
goto error;
}
if (!dbus_connection_add_filter (connection, nma_dbus_filter, applet, NULL))
return NULL;
success = dbus_connection_add_filter (connection, nma_dbus_filter, applet, NULL);
if (!success)
goto error;
dbus_connection_set_exit_on_disconnect (connection, FALSE);
dbus_connection_setup_with_g_main (connection, NULL);
dbus_error_init (&error);
dbus_bus_add_match(connection,
"type='signal',"
"interface='" DBUS_INTERFACE_DBUS "',"
"sender='" DBUS_SERVICE_DBUS "'",
&error);
if (dbus_error_is_set (&error))
dbus_error_free (&error);
if (dbus_error_is_set (&error)) {
nm_warning ("Could not register signal handlers. '%s'",
error.message);
goto error;
}
dbus_error_init (&error);
dbus_bus_add_match(connection,
"type='signal',"
"interface='" NM_DBUS_INTERFACE "',"
"path='" NM_DBUS_PATH "',"
"sender='" NM_DBUS_SERVICE "'",
&error);
if (dbus_error_is_set (&error))
dbus_error_free (&error);
if (dbus_error_is_set (&error)) {
nm_warning ("Could not register signal handlers. '%s'",
error.message);
goto error;
}
dbus_error_init (&error);
dbus_bus_add_match(connection,
"type='signal',"
"interface='" NM_DBUS_INTERFACE_VPN "',"
"path='" NM_DBUS_PATH_VPN "',"
"sender='" NM_DBUS_SERVICE "'",
&error);
if (dbus_error_is_set (&error)) {
nm_warning ("Could not register signal handlers. '%s'",
error.message);
goto error;
}
return connection;
error:
if (dbus_error_is_set (&error))
dbus_error_free (&error);
return (connection);
if (connection)
dbus_connection_unref (connection);
return NULL;
}
@ -393,62 +428,62 @@ static DBusConnection * nma_dbus_init (NMApplet *applet)
* Try to reconnect if we ever get disconnected from the bus
*
*/
static gboolean nma_dbus_connection_watcher (gpointer user_data)
static gboolean
nma_dbus_connection_watcher (gpointer user_data)
{
NMApplet *applet = (NMApplet *)user_data;
NMApplet * applet = (NMApplet *)user_data;
g_return_val_if_fail (applet != NULL, TRUE);
if (!applet->connection)
{
if ((applet->connection = nma_dbus_init (applet)))
{
applet->nm_running = nma_dbus_nm_is_running (applet->connection);
if (applet->nm_running)
{
nma_set_state (applet, NM_STATE_DISCONNECTED);
nma_dbus_update_nm_state (applet);
nma_dbus_update_devices (applet);
nma_dbus_update_dialup (applet);
nma_dbus_vpn_update_vpn_connections (applet);
}
}
nma_dbus_init_helper (applet);
if (applet->connection) {
applet->connection_timeout_id = 0;
return FALSE; /* Remove timeout */
}
return (TRUE);
return TRUE;
}
void
nma_start_dbus_connection_watch (NMApplet *applet)
{
if (applet->connection_timeout_id)
g_source_remove (applet->connection_timeout_id);
applet->connection_timeout_id = g_timeout_add (5000,
(GSourceFunc) nma_dbus_connection_watcher,
applet);
}
/*
* nma_dbus_worker
* nma_dbus_init_helper
*
* Thread worker function that periodically grabs the NetworkManager state
* and updates our local applet state to reflect that.
* Set up the applet's NMI dbus methods and dbus connection
*
*/
void nma_dbus_init_helper (NMApplet *applet)
void
nma_dbus_init_helper (NMApplet *applet)
{
GSource * timeout_source;
g_return_if_fail (applet != NULL);
dbus_g_thread_init ();
applet->connection = nma_dbus_init (applet);
applet->nmi_methods = nmi_dbus_nmi_methods_setup ();
if (applet->connection) {
if (applet->connection_timeout_id) {
g_source_remove (applet->connection_timeout_id);
applet->connection_timeout_id = 0;
}
timeout_source = g_timeout_source_new (2000);
g_source_set_callback (timeout_source, nma_dbus_connection_watcher, applet, NULL);
g_source_attach (timeout_source, NULL);
if (nma_dbus_nm_is_running (applet->connection)) {
nma_set_running (applet, TRUE);
nma_dbus_update_nm_state (applet);
nma_dbus_update_devices (applet);
nma_dbus_update_dialup (applet);
nma_dbus_vpn_update_vpn_connections (applet);
if (applet->connection && nma_dbus_nm_is_running (applet->connection))
{
applet->nm_running = TRUE;
nma_dbus_update_nm_state (applet);
nma_dbus_update_devices (applet);
nma_dbus_update_dialup (applet);
nma_dbus_vpn_update_vpn_connections (applet);
/* Immediate redraw */
nma_update_state (applet);
}
}
g_source_unref (timeout_source);
}

View file

@ -35,6 +35,7 @@ static inline gboolean message_is_error (DBusMessage *msg)
}
void nma_dbus_init_helper (NMApplet *applet);
void nma_start_dbus_connection_watch (NMApplet *applet);
void nma_dbus_enable_wireless (NMApplet *applet, gboolean enabled);
void nma_dbus_enable_networking (NMApplet *applet, gboolean enabled);
void nma_free_gui_data_model (NMApplet *applet);

View file

@ -80,7 +80,6 @@ static gboolean nma_icons_init (NMApplet *applet);
static void nma_icons_free (NMApplet *applet);
static void nma_context_menu_update (NMApplet *applet);
static GtkWidget * nma_get_instance (NMApplet *applet);
static void nma_update_state (NMApplet *applet);
static void nma_dropdown_menu_deactivate_cb (GtkWidget *menu, NMApplet *applet);
static G_GNUC_NORETURN void nma_destroy (NMApplet *applet);
static GType nma_get_type (void); /* for G_DEFINE_TYPE */
@ -1050,7 +1049,7 @@ static gboolean animation_timeout (NMApplet *applet)
* and what our icon on the panel should look like for each type.
*
*/
static void nma_update_state (NMApplet *applet)
void nma_update_state (NMApplet *applet)
{
gboolean show_applet = TRUE;
gboolean need_animation = FALSE;
@ -2135,6 +2134,29 @@ static inline void nma_enable_networking_set_active (NMApplet *applet)
}
/*
* nma_set_running
*
* Set whether NM is running to TRUE or FALSE.
*
*/
void nma_set_running (NMApplet *applet, gboolean running)
{
if (running == applet->nm_running)
return;
applet->nm_running = running;
/* if NM became active, start drawing our icon, else stop drawing it */
if (applet->nm_running && !applet->redraw_timeout_id)
applet->redraw_timeout_id = g_timeout_add (1000, (GSourceFunc) nma_redraw_timeout, applet);
else if (!applet->nm_running && applet->redraw_timeout_id)
{
g_source_remove (applet->redraw_timeout_id);
applet->redraw_timeout_id = 0;
}
}
/*
* nma_set_state
*
@ -2460,10 +2482,10 @@ static void G_GNUC_NORETURN nma_destroy (NMApplet *applet)
}
#endif
if (applet->redraw_timeout_id > 0)
{
gtk_timeout_remove (applet->redraw_timeout_id);
applet->redraw_timeout_id = 0;
nma_set_running (applet, FALSE);
if (applet->connection_timeout_id) {
g_source_remove (applet->connection_timeout_id);
applet->connection_timeout_id = 0;
}
if (applet->gconf_client)
@ -2500,6 +2522,8 @@ static GtkWidget * nma_get_instance (NMApplet *applet)
applet->nm_state = NM_STATE_DISCONNECTED;
applet->tooltips = NULL;
applet->passphrase_dialog = NULL;
applet->connection_timeout_id = 0;
applet->redraw_timeout_id = 0;
#ifdef ENABLE_NOTIFY
applet->notification = NULL;
#endif
@ -2533,7 +2557,12 @@ static GtkWidget * nma_get_instance (NMApplet *applet)
*/
nma_compat_convert_oldformat_entries (applet->gconf_client);
/* D-Bus init stuff */
dbus_g_thread_init ();
applet->nmi_methods = nmi_dbus_nmi_methods_setup ();
nma_dbus_init_helper (applet);
if (!applet->connection)
nma_start_dbus_connection_watch (applet);
/* Load pixmaps and create applet widgets */
nma_setup_widgets (applet);
@ -2541,9 +2570,6 @@ static GtkWidget * nma_get_instance (NMApplet *applet)
g_signal_connect (applet, "destroy", G_CALLBACK (nma_destroy), NULL);
g_signal_connect (applet, "style-set", G_CALLBACK (nma_theme_change_cb), NULL);
/* Start redraw timeout */
applet->redraw_timeout_id = g_timeout_add (1000, (GtkFunction) nma_redraw_timeout, applet);
return GTK_WIDGET (applet);
}

View file

@ -81,6 +81,7 @@ typedef struct
guint gconf_vpn_notify_id;
char * glade_file;
guint redraw_timeout_id;
guint connection_timeout_id;
/* Data model elements */
gboolean is_adhoc;
@ -152,6 +153,8 @@ VPNConnection * nma_get_first_active_vpn_connection (NMApplet *applet);
void nma_enable_wireless_set_active (NMApplet *applet);
void nma_set_state (NMApplet *applet, NMState state);
void nma_set_running (NMApplet *applet, gboolean running);
void nma_update_state (NMApplet *applet);
int nm_null_safe_strcmp (const char *s1, const char *s2);