aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathias Gumz <akira at fluxbox dot org>2013-01-26 08:21:47 (GMT)
committerMathias Gumz <akira at fluxbox dot org>2013-01-26 08:21:47 (GMT)
commit716532dd47d718cb548da5f65b53a8b744ce235f (patch)
tree683de0875820ce361e2c02efc69d3ad103f3f90a
parente7bfc639323bf5d4b207323b6e2fd275dcb5d825 (diff)
downloadfluxbox_pavel-716532dd47d718cb548da5f65b53a8b744ce235f.zip
fluxbox_pavel-716532dd47d718cb548da5f65b53a8b744ce235f.tar.bz2
Calculates timeouts of ClockTool based upon System Clock
Users expect time switches to happen upon system clock times. Calculating the timeout for the next refresh of the shown time via the monotonic clock is wrong: The monotonic clock yields values based upon some arbitrary point in time which might be off a little bit to the system clock, a 'full' minute of the monotonic clock might be in the midst of a system clock minute.
-rw-r--r--src/ClockTool.cc9
-rw-r--r--src/FbTk/FbTime.cc24
-rw-r--r--src/FbTk/FbTime.hh15
-rw-r--r--src/FbTk/Timer.cc6
-rw-r--r--src/Window.cc8
5 files changed, 36 insertions, 26 deletions
diff --git a/src/ClockTool.cc b/src/ClockTool.cc
index 3591f4f..b4792fe 100644
--- a/src/ClockTool.cc
+++ b/src/ClockTool.cc
@@ -70,12 +70,13 @@ int showSeconds(const std::string& fmt_string) {
70 70
71uint64_t calcNextTimeout(const std::string& fmt_string) { 71uint64_t calcNextTimeout(const std::string& fmt_string) {
72 72
73 if (showSeconds(fmt_string)) { // microseconds till next full second 73 uint64_t now = FbTk::FbTime::system();
74 return FbTk::FbTime::remainingNext(FbTk::FbTime::IN_SECONDS); 74 uint64_t unit = FbTk::FbTime::IN_SECONDS;
75 if (!showSeconds(fmt_string)) { // microseconds till next full minute
76 unit *= 60L;
75 } 77 }
76 78
77 // microseconds until next full minute 79 return FbTk::FbTime::remainingNext(now, unit);
78 return FbTk::FbTime::remainingNext(60L * FbTk::FbTime::IN_SECONDS);
79} 80}
80 81
81 82
diff --git a/src/FbTk/FbTime.cc b/src/FbTk/FbTime.cc
index d0ef731..c86edb1 100644
--- a/src/FbTk/FbTime.cc
+++ b/src/FbTk/FbTime.cc
@@ -21,6 +21,8 @@
21 21
22#include "FbTime.hh" 22#include "FbTime.hh"
23 23
24#include <cstdlib>
25#include <sys/time.h>
24 26
25 27
26#ifdef HAVE_CLOCK_GETTIME // linux|*bsd|solaris 28#ifdef HAVE_CLOCK_GETTIME // linux|*bsd|solaris
@@ -28,16 +30,16 @@
28 30
29namespace { 31namespace {
30 32
31uint64_t _now() { 33uint64_t _mono() {
32 34
33 uint64_t n = 0L; 35 uint64_t t = 0L;
34 timespec ts; 36 timespec ts;
35 37
36 if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { 38 if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
37 n = (ts.tv_sec * FbTk::FbTime::IN_SECONDS) + (ts.tv_nsec / 1000L); 39 t = (ts.tv_sec * FbTk::FbTime::IN_SECONDS) + (ts.tv_nsec / 1000L);
38 } 40 }
39 41
40 return n; 42 return t;
41} 43}
42 44
43} 45}
@@ -59,7 +61,7 @@ uint64_t _now() {
59 61
60namespace { 62namespace {
61 63
62uint64_t _now() { 64uint64_t _mono() {
63 65
64 // mach_absolute_time() * info.numer / info.denom yields 66 // mach_absolute_time() * info.numer / info.denom yields
65 // nanoseconds. 67 // nanoseconds.
@@ -85,13 +87,15 @@ uint64_t _now() {
85 87
86 88
87 89
88 90uint64_t FbTk::FbTime::mono() {
89uint64_t FbTk::FbTime::now() { 91 return ::_mono();
90 return ::_now();
91} 92}
92 93
93 94
94uint64_t FbTk::FbTime::remainingNext(uint64_t unit) { 95uint64_t FbTk::FbTime::system() {
95 return (unit - (::_now() % unit) - 1); 96 static timeval v;
97 gettimeofday(&v, NULL);
98 return (v.tv_sec * FbTk::FbTime::IN_SECONDS) + v.tv_usec;
96} 99}
97 100
101
diff --git a/src/FbTk/FbTime.hh b/src/FbTk/FbTime.hh
index 2b33dd8..3d80b12 100644
--- a/src/FbTk/FbTime.hh
+++ b/src/FbTk/FbTime.hh
@@ -34,7 +34,7 @@
34 34
35namespace FbTk { 35namespace FbTk {
36 36
37// time in micro-seconds, monotonic increasing 37// time in micro-seconds
38// 38//
39// interesting links: 39// interesting links:
40// 40//
@@ -44,12 +44,17 @@ namespace FbTk {
44namespace FbTime { 44namespace FbTime {
45 45
46 const uint64_t IN_MILLISECONDS = 1000L; 46 const uint64_t IN_MILLISECONDS = 1000L;
47 const uint64_t IN_SECONDS = 1000L * 1000L; 47 const uint64_t IN_SECONDS = 1000L * IN_MILLISECONDS;
48 const uint64_t IN_MINUTES = 60 * IN_SECONDS;
48 49
49 uint64_t now(); 50 uint64_t mono(); // point in time, always monotonic
51 uint64_t system(); // system time, might jump (DST, leap seconds)
50 52
51 // calculates the remaining microseconds up to the next full 'unit' 53 // calculates the remaining microseconds from 'now' up to the
52 uint64_t remainingNext(uint64_t unit); 54 // next full 'unit'
55 inline uint64_t remainingNext(uint64_t now, uint64_t unit) {
56 return (unit - (now % unit) - 1);
57 }
53 58
54} // namespace FbTime 59} // namespace FbTime
55 60
diff --git a/src/FbTk/Timer.cc b/src/FbTk/Timer.cc
index 2404773..1bec893 100644
--- a/src/FbTk/Timer.cc
+++ b/src/FbTk/Timer.cc
@@ -117,7 +117,7 @@ void Timer::start() {
117 // it from s_timerlist before restarting it 117 // it from s_timerlist before restarting it
118 stop(); 118 stop();
119 119
120 m_start = FbTk::FbTime::now(); 120 m_start = FbTk::FbTime::mono();
121 121
122 // interval timers have their timeout change every 122 // interval timers have their timeout change every
123 // time they are started! 123 // time they are started!
@@ -158,7 +158,7 @@ void Timer::updateTimers(int fd) {
158 FD_SET(fd, &rfds); 158 FD_SET(fd, &rfds);
159 159
160 bool overdue = false; 160 bool overdue = false;
161 uint64_t now = FbTime::now(); 161 uint64_t now = FbTime::mono();
162 uint64_t end_time; 162 uint64_t end_time;
163 163
164 // search for overdue timers 164 // search for overdue timers
@@ -192,7 +192,7 @@ void Timer::updateTimers(int fd) {
192 192
193 static std::vector<FbTk::Timer*> timeouts; 193 static std::vector<FbTk::Timer*> timeouts;
194 194
195 now = FbTime::now(); 195 now = FbTime::mono();
196 for (it = s_timerlist.begin(); it != s_timerlist.end(); ++it ) { 196 for (it = s_timerlist.begin(); it != s_timerlist.end(); ++it ) {
197 if (now < (*it)->getEndTime()) { 197 if (now < (*it)->getEndTime()) {
198 break; 198 break;
diff --git a/src/Window.cc b/src/Window.cc
index a15c6e0..1ee8853 100644
--- a/src/Window.cc
+++ b/src/Window.cc
@@ -550,7 +550,7 @@ void FluxboxWindow::init() {
550 550
551 m_workspacesig.emit(*this); 551 m_workspacesig.emit(*this);
552 552
553 m_creation_time = FbTk::FbTime::now(); 553 m_creation_time = FbTk::FbTime::mono();
554 554
555 frame().frameExtentSig().emit(); 555 frame().frameExtentSig().emit();
556 556
@@ -2206,7 +2206,7 @@ void FluxboxWindow::configureRequestEvent(XConfigureRequestEvent &cr) {
2206 // just after creation if the user has a saved position/size 2206 // just after creation if the user has a saved position/size
2207 if (m_creation_time) { 2207 if (m_creation_time) {
2208 2208
2209 uint64_t now = FbTk::FbTime::now(); 2209 uint64_t now = FbTk::FbTime::mono();
2210 2210
2211 Remember& rinst = Remember::instance(); 2211 Remember& rinst = Remember::instance();
2212 2212
@@ -2310,12 +2310,12 @@ void FluxboxWindow::keyPressEvent(XKeyEvent &ke) {
2310 } 2310 }
2311 2311
2312 // otherwise, make a note that the user is typing 2312 // otherwise, make a note that the user is typing
2313 m_last_keypress_time = FbTk::FbTime::now(); 2313 m_last_keypress_time = FbTk::FbTime::mono();
2314} 2314}
2315 2315
2316bool FluxboxWindow::isTyping() const { 2316bool FluxboxWindow::isTyping() const {
2317 2317
2318 uint64_t diff = FbTk::FbTime::now() - m_last_keypress_time; 2318 uint64_t diff = FbTk::FbTime::mono() - m_last_keypress_time;
2319 return ((diff / 1000) < screen().noFocusWhileTypingDelay()); 2319 return ((diff / 1000) < screen().noFocusWhileTypingDelay());
2320} 2320}
2321 2321