Author: juha
Date: 2007-08-13 17:13:37 +0000 (Mon, 13 Aug 2007)
New Revision: 25980
Modified:
xfcalendar/branches/xfce_4_4/panel-plugin/oc_config.c
xfcalendar/branches/xfce_4_4/panel-plugin/orageclock.c
xfcalendar/branches/xfce_4_4/panel-plugin/orageclock.h
Log:
Bug 3363: Orage clock now wakes up only when needed.
This fix sacrifies a little of accuracy to save wakeups.
If seconds are not visible clock wakes up only once per minute.
Modified: xfcalendar/branches/xfce_4_4/panel-plugin/oc_config.c
===================================================================
--- xfcalendar/branches/xfce_4_4/panel-plugin/oc_config.c 2007-08-12
22:36:43 UTC (rev 25979)
+++ xfcalendar/branches/xfce_4_4/panel-plugin/oc_config.c 2007-08-13
17:13:37 UTC (rev 25980)
@@ -400,6 +400,7 @@
gtk_widget_destroy(dlg);
xfce_panel_plugin_unblock_menu(clock->plugin);
oc_write_rc_file(clock->plugin, clock);
+ oc_init_timer(clock);
}
void oc_properties_dialog(XfcePanelPlugin *plugin, Clock *clock)
@@ -408,6 +409,10 @@
xfce_panel_plugin_block_menu(plugin);
+ clock->interval = 200; /* 0,2 sec, so that we can show quick feedback
+ * on the panel */
+ oc_disable_tuning(clock);
+ oc_start_timer(clock);
dlg = gtk_dialog_new_with_buttons(_("Properties"),
GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(plugin))),
GTK_DIALOG_DESTROY_WITH_PARENT |
Modified: xfcalendar/branches/xfce_4_4/panel-plugin/orageclock.c
===================================================================
--- xfcalendar/branches/xfce_4_4/panel-plugin/orageclock.c 2007-08-12
22:36:43 UTC (rev 25979)
+++ xfcalendar/branches/xfce_4_4/panel-plugin/orageclock.c 2007-08-13
17:13:37 UTC (rev 25980)
@@ -94,6 +94,9 @@
utf8_strftime(res, sizeof(res), line->data->str, &clock->now);
/* gtk_label_set_text call takes almost
* 100 % of the time wasted in this procedure
+ * Note that even though we only wake up when needed, we
+ * may not have to update all lines, so this check still
+ * probably is worth doing
* */
if (strcmp(res, line->prev)) {
gtk_label_set_text(GTK_LABEL(line->label), res);
@@ -106,6 +109,177 @@
return(TRUE);
}
+static gboolean oc_get_time_delay(Clock *clock)
+{
+ clock->timeout_id = g_timeout_add_full(G_PRIORITY_DEFAULT_IDLE
+ , clock->interval, (GSourceFunc)oc_get_time, clock, NULL);
+ oc_get_time(clock);
+ return(FALSE); /* this is one time only timer */
+}
+
+gboolean oc_start_timer(Clock *clock)
+{
+ time_t t;
+ gint delay_time = 0;
+
+ oc_get_time(clock);
+ time(&t);
+ localtime_r(&t, &clock->now);
+ if (clock->interval >= 60000)
+ delay_time = (clock->interval-clock->now.tm_sec*1000);
+ if (clock->delay_timeout_id) {
+ g_source_remove(clock->delay_timeout_id);
+ clock->delay_timeout_id = 0;
+ }
+ if (clock->timeout_id) {
+ g_source_remove(clock->timeout_id);
+ clock->timeout_id = 0;
+ }
+ clock->delay_timeout_id = g_timeout_add_full(G_PRIORITY_DEFAULT_IDLE
+ , delay_time, (GSourceFunc)oc_get_time_delay, clock, NULL);
+ return(TRUE);
+}
+
+static gboolean oc_end_tuning(Clock *clock)
+{
+ /* if we have longer than 1 sec timer, we need to reschedule it regularly
+ * since it will fall down slowly but surely
+ * */
+ if (clock->adjust_timeout_id) {
+ g_source_remove(clock->adjust_timeout_id);
+ clock->adjust_timeout_id = 0;
+ }
+ if (clock->interval >= 60000) {
+ clock->adjust_timeout_id = g_timeout_add_full(G_PRIORITY_DEFAULT_IDLE
+ , 60*60*1000, (GSourceFunc)oc_start_timer, clock, NULL);
+ }
+ g_free(clock->tune);
+ clock->tune = NULL;
+}
+
+static gboolean oc_next_level_tuning(Clock *clock)
+{
+ TimeTuning *tune = clock->tune;
+ gboolean continue_tuning = TRUE;
+
+ if (clock->interval == OC_CONFIG_INTERVAL) /* setup active => no changes */
+ return(FALSE);
+ switch (tune->level) {
+ case 0: /* second now; let's set interval to minute */
+ clock->interval = 60*1000;
+ break;
+ case 1: /* minute now; let's set it to hour */
+ clock->interval = 60*60*1000;
+ break;
+ default: /* no point tune more */
+ break;
+ }
+ if (tune->level < 2) {
+ tune->level++;
+ oc_start_timer(clock);
+ oc_start_tuning(clock);
+ }
+ else {
+ continue_tuning = FALSE;
+ oc_end_tuning(clock);
+ }
+ return(continue_tuning);
+}
+
+static gboolean oc_tune_time(Clock *clock)
+{
+ /* idea is that we compare the panel string three times and
+ * if all of those are the same, we can tune the timer since we know
+ * that we do not have to check it so often. Time in panel plugin is
+ * not changing anyway. So we adjust the timers and check again */
+ gboolean continue_tuning = TRUE;
+ TimeTuning *tune = clock->tune;
+
+ if (clock->interval == OC_CONFIG_INTERVAL) /* setup active => no changes */
+ return(FALSE);
+ switch (tune->cnt) {
+ case 0: /* first time we come here */
+ strncpy(tune->prev[0], clock->line[0].prev, OC_MAX_LINE_LENGTH);
+ strncpy(tune->prev[1], clock->line[1].prev, OC_MAX_LINE_LENGTH);
+ strncpy(tune->prev[2], clock->line[2].prev, OC_MAX_LINE_LENGTH);
+ strncpy(tune->tooltip_prev,
clock->tooltip_prev,OC_MAX_LINE_LENGTH);
+ break;
+ case 1:
+ case 2:
+ case 3: /* FIXME: two may be enough ?? */
+ if (strncmp(tune->prev[0], clock->line[0].prev, OC_MAX_LINE_LENGTH)
+ || strncmp(tune->prev[1], clock->line[1].prev, OC_MAX_LINE_LENGTH)
+ || strncmp(tune->prev[2], clock->line[2].prev, OC_MAX_LINE_LENGTH)
+ || strncmp(tune->tooltip_prev, clock->tooltip_prev
+ ,OC_MAX_LINE_LENGTH)) {
+ /* time has changed. But it may change due to bigger time
+ * change. For example if we are checking seconds and time
+ * only shows minutes, this can change if hour happens to
+ * change. So we need to check the change twice to be sure */
+ if (tune->changed_once) { /* this is the second trial already
*/
+ continue_tuning = FALSE;
+ oc_end_tuning(clock);
+ }
+ else { /* need to try again */
+ tune->changed_once = TRUE;
+ tune->cnt = -1; /* this gets incremented to 0 below */
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ if (continue_tuning)
+ if (tune->cnt == 3)
+ continue_tuning = oc_next_level_tuning(clock);
+ else
+ tune->cnt++;
+
+ return(continue_tuning);
+}
+
+void oc_disable_tuning(Clock *clock)
+{
+ TimeTuning *tune = clock->tune;
+
+ if (tune == NULL)
+ return;
+ if (tune->timeout_id) {
+ g_source_remove(tune->timeout_id);
+ tune->timeout_id = 0;
+ }
+ if (clock->adjust_timeout_id) {
+ g_source_remove(clock->adjust_timeout_id);
+ clock->adjust_timeout_id = 0;
+ }
+}
+
+void oc_start_tuning(Clock *clock)
+{
+ TimeTuning *tune = clock->tune;
+
+ if (clock->interval == OC_CONFIG_INTERVAL) /* setup active => no changes */
+ return;
+ tune->cnt = 0;
+ tune->changed_once = FALSE;
+ if (tune->timeout_id) {
+ g_source_remove(tune->timeout_id);
+ tune->timeout_id = 0;
+ }
+ tune->timeout_id = g_timeout_add_full(G_PRIORITY_DEFAULT_IDLE
+ , 2*clock->interval, (GSourceFunc)oc_tune_time, clock, NULL);
+}
+
+void oc_init_timer(Clock *clock)
+{
+ clock->interval = OC_BASE_INTERVAL;
+ if (clock->tune == NULL)
+ clock->tune = g_new0(TimeTuning, 1);
+ clock->tune->level = 0;
+ oc_start_timer(clock);
+ oc_start_tuning(clock);
+}
+
static void oc_update_size(Clock *clock, int size)
{
/* keep in sync with systray */
@@ -424,9 +598,7 @@
clock->tips = gtk_tooltips_new();
g_object_ref(clock->tips);
gtk_object_sink(GTK_OBJECT(clock->tips));
- oc_get_time(clock);
- clock->timeout_id = g_timeout_add_full(G_PRIORITY_DEFAULT_IDLE
- , 200, (GSourceFunc) oc_get_time, clock, NULL);
+ oc_init_timer(clock);
return(clock);
}
Modified: xfcalendar/branches/xfce_4_4/panel-plugin/orageclock.h
===================================================================
--- xfcalendar/branches/xfce_4_4/panel-plugin/orageclock.h 2007-08-12
22:36:43 UTC (rev 25979)
+++ xfcalendar/branches/xfce_4_4/panel-plugin/orageclock.h 2007-08-13
17:13:37 UTC (rev 25980)
@@ -20,9 +20,20 @@
#define OC_NAME "orageclock panel plugin"
#define OC_MAX_LINES 3 /* changing this causes trouble. don't do it */
#define OC_MAX_LINE_LENGTH 100
+#define OC_BASE_INTERVAL 1000 /* best accurance of the clock */
+#define OC_CONFIG_INTERVAL 200 /* special fast interval used in setup */
+typedef struct _timetuning
+{
+ gint level; /* 0 = seconds, 1 = minutes, 2 = hours */
+ gint cnt;
+ gboolean changed_once;
+ gint timeout_id;
+ gchar prev[OC_MAX_LINES][OC_MAX_LINE_LENGTH+1];
+ gchar tooltip_prev[OC_MAX_LINE_LENGTH+1];
+} TimeTuning;
-typedef struct
+typedef struct _clockline
{
GtkWidget *label;
gboolean show;
@@ -31,7 +42,7 @@
gchar prev[OC_MAX_LINE_LENGTH+1];
} ClockLine;
-typedef struct
+typedef struct _clock
{
XfcePanelPlugin *plugin;
@@ -56,7 +67,12 @@
GtkTooltips *tips;
int timeout_id;
+ int delay_timeout_id;
+ int adjust_timeout_id;
+ int interval;
struct tm now;
+
+ TimeTuning *tune;
} Clock;
void oc_properties_dialog(XfcePanelPlugin *plugin, Clock *clock);
@@ -69,3 +85,8 @@
void oc_show_line_set(Clock *clock, gint lno);
void oc_line_font_set(Clock *clock, gint lno);
void oc_write_rc_file(XfcePanelPlugin *plugin, Clock *clock);
+gboolean oc_start_timer(Clock *clock);
+void oc_start_tuning(Clock *clock);
+void oc_disable_tuning(Clock *clock);
+void oc_init_timer(Clock *clock);
+
_______________________________________________
Xfce4-commits mailing list
[email protected]
http://foo-projects.org/mailman/listinfo/xfce4-commits