--- gnome-panel-2.14.2/applets/clock/clock.c	2006-05-29 22:48:22.000000000 +0200
+++ gnome-panel-2.14.2_cambiado/applets/clock/clock.c	2006-07-29 11:30:01.000000000 +0200
@@ -46,6 +46,7 @@
 #include <unistd.h>
 #include <dirent.h>
 #include <string.h>
+#include <sys/time.h>
 #include <time.h>
 #include <langinfo.h>
 
@@ -131,6 +132,7 @@ struct _ClockData {
 	/* preferences */
 	ClockFormat  format;
 	char        *custom_format;
+	char		 recalculate;
 	gboolean     showseconds;
 	gboolean     showdate;
 	gboolean     gmt_time;
@@ -140,6 +142,7 @@ struct _ClockData {
 
 	/* runtime data */
         time_t             current_time;
+	suseconds_t		   current_utime;
 	char              *timeformat;
 	guint              timeout;
 	PanelAppletOrient  orient;
@@ -162,7 +165,7 @@ struct _ClockData {
 };
 
 static void  update_clock (ClockData * cd);
-static float get_itime    (time_t current_time);
+static float get_itime    (time_t current_time,suseconds_t current_utime);
 
 static void set_atk_name_description (GtkWidget *widget,
                                       const char *name,
@@ -212,31 +215,52 @@ static int
 clock_timeout_callback (gpointer data)
 {
 	ClockData *cd = data;
-	time_t new_time;
+	struct timeval mytime;
+	unsigned int deciseconds;
+	int timeouttime;
+	
+	update_clock (cd);
 
-        time (&new_time);
+	if (!(cd->recalculate)) {
+		return TRUE;
+	}
 
-	if (!cd->showseconds &&
-	    cd->format != CLOCK_FORMAT_UNIX &&
-	    cd->format != CLOCK_FORMAT_CUSTOM) {
-		if (cd->format == CLOCK_FORMAT_INTERNET && 
-		    (long)get_itime (new_time) !=
-		    (long)get_itime (cd->current_time)) {
-			update_clock (cd);
-		} else if ((cd->format == CLOCK_FORMAT_12 ||
-			    cd->format == CLOCK_FORMAT_24) &&
-			   new_time / 60 != cd->current_time / 60) {
-			update_clock (cd);
+	gettimeofday(&mytime,NULL);
+	
+	if (cd->format == CLOCK_FORMAT_INTERNET) {
+		if (cd->showseconds) { // if we show seconds, we put a timer of INTERNETSECOND ms
+			timeouttime = INTERNETSECOND;
+			cd->recalculate=0;
+		} else { // if not, calculate how many ms rests until next interval
+			deciseconds=(((unsigned int) mytime.tv_sec) * 10 + ((unsigned int) mytime.tv_usec) / 100000)%864;
+			if (deciseconds<11) { // if we have to wait less than 1100 ms, then stay with that timer
+				cd->recalculate=0;
+				timeouttime=86400;
+			} else {
+				timeouttime = 100*(874-(deciseconds%864)); // one more second to ensure that the change
+			}	// is made AFTER the clock has changed
 		}
 	} else {
-		update_clock (cd);
+		if ((cd->showseconds)||(cd->format == CLOCK_FORMAT_UNIX)) {
+			timeouttime = 1000;
+			cd->recalculate=0;
+		} else {
+			if ((mytime.tv_sec%60)<2) { // if we have to wait less than 2000 ms, then stay with that timer
+				cd->recalculate=0;
+				timeouttime=60000;
+			} else {
+				timeouttime = 1000*(61-((mytime.tv_sec%60)));
+			}
+		}
 	}
-
-	return TRUE;
+	
+	cd->timeout=g_timeout_add(timeouttime,clock_timeout_callback,data);
+		
+	return FALSE; // disable current timer, so we wait only for the new timer
 }
 
 static float
-get_itime (time_t current_time)
+get_itime (time_t current_time,suseconds_t current_utime)
 {
 	struct tm *tm;
 	float itime;
@@ -245,7 +269,7 @@ get_itime (time_t current_time)
 	/* BMT (Biel Mean Time) is GMT+1 */
 	bmt = current_time + 3600;
 	tm = gmtime (&bmt);
-	itime = (tm->tm_hour*3600.0 + tm->tm_min*60.0 + tm->tm_sec)/86.4;
+	itime = (tm->tm_hour*360000.0 + tm->tm_min*6000.0 + tm->tm_sec*100 + current_utime/10000)/8640;
 
 	return itime;
 }
@@ -373,8 +397,11 @@ update_clock (ClockData * cd)
 	struct tm *tm;
 	char date[256], hour[256];
 	char *utf8, *loc;
-
-	time (&cd->current_time);
+	struct timeval mytime;
+	
+	gettimeofday(&mytime,NULL);
+	cd->current_time=mytime.tv_sec;
+	cd->current_utime=mytime.tv_usec;
 	
 	if (cd->gmt_time)
 		tm = gmtime (&cd->current_time);
@@ -390,7 +417,7 @@ update_clock (ClockData * cd)
 			g_snprintf (hour, sizeof(hour), "%lu", (unsigned long)cd->current_time);
 		}
 	} else if (cd->format == CLOCK_FORMAT_INTERNET) {
-		float itime = get_itime (cd->current_time);
+		float itime = get_itime (cd->current_time,cd->current_utime);
 		if (cd->showseconds)
 			g_snprintf (hour, sizeof (hour), "@%3.2f", itime);
 		else
@@ -445,25 +472,19 @@ refresh_clock (ClockData *cd)
 static void
 refresh_clock_timeout(ClockData *cd)
 {
-	int timeouttime;
 
 	unfix_size (cd);
 	
 	update_timeformat (cd);
 
-	if (cd->timeout)
+	if (cd->timeout) {
 		g_source_remove (cd->timeout);
-
-	update_clock (cd);
+		cd->timeout=0;
+	}
 	
-	if (cd->format == CLOCK_FORMAT_INTERNET)
-		timeouttime = INTERNETSECOND;
-	else
-		timeouttime = 1000;
+	cd->recalculate=1;
 	
-	cd->timeout = g_timeout_add (timeouttime,
-	                             clock_timeout_callback,
-	                             cd);
+	clock_timeout_callback(cd);
 }
 
 static void
@@ -482,7 +503,7 @@ destroy_clock(GtkWidget * widget, ClockD
 
 	if (cd->timeout)
 		g_source_remove (cd->timeout);
-        cd->timeout = 0;
+    cd->timeout = 0;
 
 #ifdef HAVE_LIBECAL
         if (cd->client)
@@ -1770,7 +1791,7 @@ copy_time (BonoboUIComponent *uic,
 		g_snprintf (string, sizeof(string), "%lu",
 			    (unsigned long)cd->current_time);
 	} else if (cd->format == CLOCK_FORMAT_INTERNET) {
-		float itime = get_itime (cd->current_time);
+		float itime = get_itime (cd->current_time,cd->current_utime);
 		if (cd->showseconds)
 			g_snprintf (string, sizeof (string), "@%3.2f", itime);
 		else
@@ -2242,6 +2263,8 @@ fill_clock_applet (PanelApplet *applet)
 	panel_applet_set_flags (applet, PANEL_APPLET_EXPAND_MINOR);
 	
 	cd = g_new0 (ClockData, 1);
+	cd->timeout=0;
+	cd->recalculate=1;
 	cd->fixed_width = -1;
 	cd->fixed_height = -1;
 
