diff options
author | Mathias Gumz <akira at fluxbox dot org> | 2012-08-28 08:51:55 (GMT) |
---|---|---|
committer | Mathias Gumz <akira at fluxbox dot org> | 2012-08-28 08:51:55 (GMT) |
commit | 541c8c407b7ba8dd10f85bb48bcb5900270b3f84 (patch) | |
tree | 71a6abc0f2a43bcfd33f80b3b30b878f234cbf05 /src | |
parent | 60a53113e05db443af4d520883ec3145680642a8 (diff) | |
download | fluxbox-541c8c407b7ba8dd10f85bb48bcb5900270b3f84.zip fluxbox-541c8c407b7ba8dd10f85bb48bcb5900270b3f84.tar.bz2 |
changed timing functions to use a monotonic increasing clock
gettimeofday() is subject to be changed on daylight-saving or to ntp-related
(think leap-seconds). even worse, it is subject to be changed BACK in time. this
is hard to fix correctly (see commit 45726d3016e and bug #3560509). it is
irrelevant for timers to know the nano-seconds since the epoch anyways.
Diffstat (limited to 'src')
-rw-r--r-- | src/AttentionNoticeHandler.cc | 2 | ||||
-rw-r--r-- | src/ClockTool.cc | 37 | ||||
-rw-r--r-- | src/FbTk/FbTime.cc | 97 | ||||
-rw-r--r-- | src/FbTk/FbTime.hh | 58 | ||||
-rw-r--r-- | src/FbTk/ImageControl.cc | 2 | ||||
-rw-r--r-- | src/FbTk/Makefile.am | 1 | ||||
-rw-r--r-- | src/FbTk/Menu.cc | 4 | ||||
-rw-r--r-- | src/FbTk/Timer.cc | 232 | ||||
-rw-r--r-- | src/FbTk/Timer.hh | 61 | ||||
-rw-r--r-- | src/Slit.cc | 2 | ||||
-rw-r--r-- | src/Toolbar.cc | 2 | ||||
-rw-r--r-- | src/TooltipWindow.cc | 17 | ||||
-rw-r--r-- | src/TooltipWindow.hh | 2 | ||||
-rw-r--r-- | src/Window.cc | 34 | ||||
-rw-r--r-- | src/Window.hh | 9 | ||||
-rw-r--r-- | src/fluxbox.cc | 11 | ||||
-rw-r--r-- | src/tests/testDemandAttention.cc | 5 | ||||
-rw-r--r-- | src/tests/titletest.cc | 5 |
18 files changed, 315 insertions, 266 deletions
diff --git a/src/AttentionNoticeHandler.cc b/src/AttentionNoticeHandler.cc index 0aaf266..1bb28b2 100644 --- a/src/AttentionNoticeHandler.cc +++ b/src/AttentionNoticeHandler.cc | |||
@@ -81,7 +81,7 @@ void AttentionNoticeHandler::addAttention(Focusable &client) { | |||
81 | RefCount<Command<void> > cmd(new ToggleFrameFocusCmd(client)); | 81 | RefCount<Command<void> > cmd(new ToggleFrameFocusCmd(client)); |
82 | Timer *timer = new Timer(); | 82 | Timer *timer = new Timer(); |
83 | timer->setCommand(cmd); | 83 | timer->setCommand(cmd); |
84 | timer->setTimeout(**timeout_res); | 84 | timer->setTimeout(**timeout_res * FbTk::FbTime::IN_MILLISECONDS); |
85 | timer->fireOnce(false); // will repeat until window has focus | 85 | timer->fireOnce(false); // will repeat until window has focus |
86 | timer->start(); | 86 | timer->start(); |
87 | 87 | ||
diff --git a/src/ClockTool.cc b/src/ClockTool.cc index 95176a2..1fcdb53 100644 --- a/src/ClockTool.cc +++ b/src/ClockTool.cc | |||
@@ -35,6 +35,7 @@ | |||
35 | #include "FbTk/Menu.hh" | 35 | #include "FbTk/Menu.hh" |
36 | #include "FbTk/MenuItem.hh" | 36 | #include "FbTk/MenuItem.hh" |
37 | #include "FbTk/I18n.hh" | 37 | #include "FbTk/I18n.hh" |
38 | #include "FbTk/FbTime.hh" | ||
38 | 39 | ||
39 | #ifdef HAVE_CONFIG_H | 40 | #ifdef HAVE_CONFIG_H |
40 | #include "config.h" | 41 | #include "config.h" |
@@ -45,16 +46,15 @@ | |||
45 | #else | 46 | #else |
46 | #include <time.h> | 47 | #include <time.h> |
47 | #endif | 48 | #endif |
48 | #include <sys/time.h> | ||
49 | #include <typeinfo> | 49 | #include <typeinfo> |
50 | 50 | #include <cstdio> | |
51 | 51 | ||
52 | namespace { | 52 | namespace { |
53 | 53 | ||
54 | static const char SWITCHES_SECONDS[] = "crsSTX+"; | 54 | const char SWITCHES_SECONDS[] = "crsSTX+"; |
55 | static const char SWITCHES_12_24H[] = "lIrkHT"; | 55 | const char SWITCHES_12_24H[] = "lIrkHT"; |
56 | static const char SWITCHES_24_12H[] = "kHTlIr"; | 56 | const char SWITCHES_24_12H[] = "kHTlIr"; |
57 | static const char SWITCH_AM_PM[] = "pP"; | 57 | const char SWITCH_AM_PM[] = "pP"; |
58 | 58 | ||
59 | /** | 59 | /** |
60 | * return true if clock shows seconds. If clock doesn't show seconds then | 60 | * return true if clock shows seconds. If clock doesn't show seconds then |
@@ -68,23 +68,13 @@ int showSeconds(const std::string& fmt_string) { | |||
68 | } | 68 | } |
69 | 69 | ||
70 | 70 | ||
71 | timeval calcNextTimeout(const std::string& fmt_string) { | 71 | uint64_t calcNextTimeout(const std::string& fmt_string) { |
72 | timeval now; | ||
73 | timeval next; | ||
74 | gettimeofday(&now, 0); | ||
75 | next.tv_sec = 60 - (now.tv_sec % 60) - 1; | ||
76 | next.tv_usec = 1000000 - now.tv_usec; | ||
77 | if (next.tv_usec >= 1000000) { | ||
78 | next.tv_sec++; | ||
79 | next.tv_usec -= 1000000; | ||
80 | } | ||
81 | 72 | ||
82 | // wake up at next second-change | 73 | if (showSeconds(fmt_string)) { // microseconds till next full second |
83 | if (showSeconds(fmt_string)) { | 74 | return FbTk::FbTime::remainingNext(FbTk::FbTime::IN_SECONDS); |
84 | next.tv_sec = 0; | 75 | } else { // microseconds until next full minute |
76 | return FbTk::FbTime::remainingNext(60L * FbTk::FbTime::IN_SECONDS); | ||
85 | } | 77 | } |
86 | |||
87 | return next; | ||
88 | } | 78 | } |
89 | 79 | ||
90 | 80 | ||
@@ -278,13 +268,10 @@ unsigned int ClockTool::height() const { | |||
278 | } | 268 | } |
279 | 269 | ||
280 | void ClockTool::updateTime() { | 270 | void ClockTool::updateTime() { |
281 | // update clock | ||
282 | timeval now; | ||
283 | gettimeofday(&now, 0); | ||
284 | time_t the_time = now.tv_sec; | ||
285 | 271 | ||
286 | m_timer.setTimeout(calcNextTimeout(*m_timeformat)); | 272 | m_timer.setTimeout(calcNextTimeout(*m_timeformat)); |
287 | 273 | ||
274 | time_t the_time = time(NULL); | ||
288 | if (the_time != -1) { | 275 | if (the_time != -1) { |
289 | char time_string[255]; | 276 | char time_string[255]; |
290 | int time_string_len; | 277 | int time_string_len; |
diff --git a/src/FbTk/FbTime.cc b/src/FbTk/FbTime.cc new file mode 100644 index 0000000..54eda75 --- /dev/null +++ b/src/FbTk/FbTime.cc | |||
@@ -0,0 +1,97 @@ | |||
1 | // FbTime.cc for FbTk - Fluxbox Toolkit | ||
2 | // Copyright (c) 2012 Mathias Gumz (akira at fluxbox dot org) | ||
3 | // | ||
4 | // Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | // copy of this software and associated documentation files (the "Software"), | ||
6 | // to deal in the Software without restriction, including without limitation | ||
7 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | // and/or sell copies of the Software, and to permit persons to whom the | ||
9 | // Software is furnished to do so, subject to the following conditions: | ||
10 | // | ||
11 | // The above copyright notice and this permission notice shall be included in | ||
12 | // all copies or substantial portions of the Software. | ||
13 | // | ||
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
20 | // DEALINGS IN THE SOFTWARE. | ||
21 | |||
22 | #include "FbTime.hh" | ||
23 | |||
24 | |||
25 | |||
26 | #ifdef HAVE_CLOCK_GETTIME // linux|*bsd|solaris | ||
27 | #include <time.h> | ||
28 | |||
29 | namespace { | ||
30 | |||
31 | uint64_t _now() { | ||
32 | |||
33 | uint64_t n = 0L; | ||
34 | timespec ts; | ||
35 | |||
36 | if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { | ||
37 | n = (ts.tv_sec * FbTk::FbTime::IN_SECONDS) + (ts.tv_nsec / 1000L); | ||
38 | } | ||
39 | |||
40 | return n; | ||
41 | } | ||
42 | |||
43 | } | ||
44 | |||
45 | #endif // HAVE_CLOCK_GETTIME | ||
46 | |||
47 | |||
48 | |||
49 | |||
50 | |||
51 | #ifdef HAVE_MACH_ABSOLUTE_TIME // macosx | ||
52 | |||
53 | // http://stackoverflow.com/questions/5167269/clock-gettime-alternative-in-mac-os-x | ||
54 | // https://github.com/ThomasHabets/monotonic_clock/blob/master/src/monotonic_mach.c | ||
55 | // http://shiftedbits.org/2008/10/01/mach_absolute_time-on-the-iphone/ | ||
56 | |||
57 | |||
58 | #include <mach/mach_time.h> | ||
59 | |||
60 | namespace { | ||
61 | |||
62 | uint64_t _now() { | ||
63 | |||
64 | // mach_absolute_time() * info.numer / info.denom yields | ||
65 | // nanoseconds. | ||
66 | |||
67 | static double micro_scale = 0.001; // 1000ms == 1ns | ||
68 | static bool initial = true; | ||
69 | |||
70 | if (initial) { | ||
71 | initial = false; | ||
72 | mach_timebase_info_data_t info; | ||
73 | if (mach_timebase_info(&info) == 0) { | ||
74 | micro_scale *= static_cast<double>info.numer / static_cast<double>(info.denom); | ||
75 | } | ||
76 | } | ||
77 | |||
78 | return static_cast<uint64_t>(mach_absolute_time() * micro_scale); | ||
79 | } | ||
80 | |||
81 | } | ||
82 | |||
83 | #endif // HAVE_MACH_ABSOLUTE_TIME | ||
84 | |||
85 | |||
86 | |||
87 | |||
88 | |||
89 | uint64_t FbTk::FbTime::now() { | ||
90 | return ::_now(); | ||
91 | } | ||
92 | |||
93 | |||
94 | uint64_t FbTk::FbTime::remainingNext(uint64_t unit) { | ||
95 | return (unit - (::_now() % unit) - 1); | ||
96 | } | ||
97 | |||
diff --git a/src/FbTk/FbTime.hh b/src/FbTk/FbTime.hh new file mode 100644 index 0000000..2b33dd8 --- /dev/null +++ b/src/FbTk/FbTime.hh | |||
@@ -0,0 +1,58 @@ | |||
1 | // FbTime.hh for FbTk - Fluxbox Toolkit | ||
2 | // Copyright (c) 2012 Mathias Gumz (akira at fluxbox dot org) | ||
3 | // | ||
4 | // Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | // copy of this software and associated documentation files (the "Software"), | ||
6 | // to deal in the Software without restriction, including without limitation | ||
7 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | // and/or sell copies of the Software, and to permit persons to whom the | ||
9 | // Software is furnished to do so, subject to the following conditions: | ||
10 | // | ||
11 | // The above copyright notice and this permission notice shall be included in | ||
12 | // all copies or substantial portions of the Software. | ||
13 | // | ||
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
20 | // DEALINGS IN THE SOFTWARE. | ||
21 | |||
22 | #ifndef FBTK_FBTIME_HH | ||
23 | #define FBTK_FBTIME_HH | ||
24 | |||
25 | |||
26 | #ifdef HAVE_CONFIG_H | ||
27 | #include "config.h" | ||
28 | #endif // HAVE_CONFIG_H | ||
29 | |||
30 | |||
31 | #ifdef HAVE_INTTYPES_H | ||
32 | #include <inttypes.h> | ||
33 | #endif // HAVE_INTTYPES_H | ||
34 | |||
35 | namespace FbTk { | ||
36 | |||
37 | // time in micro-seconds, monotonic increasing | ||
38 | // | ||
39 | // interesting links: | ||
40 | // | ||
41 | // http://www.python.org/dev/peps/pep-0418/#operating-system-time-functions | ||
42 | // http://en.cppreference.com/w/cpp/chrono | ||
43 | |||
44 | namespace FbTime { | ||
45 | |||
46 | const uint64_t IN_MILLISECONDS = 1000L; | ||
47 | const uint64_t IN_SECONDS = 1000L * 1000L; | ||
48 | |||
49 | uint64_t now(); | ||
50 | |||
51 | // calculates the remaining microseconds up to the next full 'unit' | ||
52 | uint64_t remainingNext(uint64_t unit); | ||
53 | |||
54 | } // namespace FbTime | ||
55 | |||
56 | } // namespace FbTk | ||
57 | |||
58 | #endif // FBTK_TIME_HH | ||
diff --git a/src/FbTk/ImageControl.cc b/src/FbTk/ImageControl.cc index fe6fde0..c99ef9a 100644 --- a/src/FbTk/ImageControl.cc +++ b/src/FbTk/ImageControl.cc | |||
@@ -188,7 +188,7 @@ ImageControl::ImageControl(int screen_num, | |||
188 | cache_max = cmax; | 188 | cache_max = cmax; |
189 | 189 | ||
190 | if (cache_timeout && s_timed_cache) { | 190 | if (cache_timeout && s_timed_cache) { |
191 | m_timer.setTimeout(cache_timeout); | 191 | m_timer.setTimeout(cache_timeout * FbTk::FbTime::IN_MILLISECONDS); |
192 | RefCount<Command<void> > clean_cache(new SimpleCommand<ImageControl>(*this, &ImageControl::cleanCache)); | 192 | RefCount<Command<void> > clean_cache(new SimpleCommand<ImageControl>(*this, &ImageControl::cleanCache)); |
193 | m_timer.setCommand(clean_cache); | 193 | m_timer.setCommand(clean_cache); |
194 | m_timer.start(); | 194 | m_timer.start(); |
diff --git a/src/FbTk/Makefile.am b/src/FbTk/Makefile.am index 171f27d..298b8c5 100644 --- a/src/FbTk/Makefile.am +++ b/src/FbTk/Makefile.am | |||
@@ -36,6 +36,7 @@ libFbTk_a_SOURCES = App.hh App.cc Color.cc Color.hh Command.hh \ | |||
36 | Texture.cc Texture.hh TextureRender.hh TextureRender.cc \ | 36 | Texture.cc Texture.hh TextureRender.hh TextureRender.cc \ |
37 | Shape.hh Shape.cc \ | 37 | Shape.hh Shape.cc \ |
38 | Theme.hh Theme.cc ThemeItems.cc Timer.hh Timer.cc \ | 38 | Theme.hh Theme.cc ThemeItems.cc Timer.hh Timer.cc \ |
39 | FbTime.cc FbTime.hh \ | ||
39 | XFontImp.cc XFontImp.hh \ | 40 | XFontImp.cc XFontImp.hh \ |
40 | Button.hh Button.cc \ | 41 | Button.hh Button.cc \ |
41 | TextButton.hh TextButton.cc \ | 42 | TextButton.hh TextButton.cc \ |
diff --git a/src/FbTk/Menu.cc b/src/FbTk/Menu.cc index a66b6c0..3632fc9 100644 --- a/src/FbTk/Menu.cc +++ b/src/FbTk/Menu.cc | |||
@@ -1006,7 +1006,7 @@ void Menu::motionNotifyEvent(XMotionEvent &me) { | |||
1006 | } | 1006 | } |
1007 | 1007 | ||
1008 | if (itmp->submenu()) { // start submenu open delay | 1008 | if (itmp->submenu()) { // start submenu open delay |
1009 | m_submenu_timer.setTimeout(theme()->getDelay()); | 1009 | m_submenu_timer.setTimeout(theme()->getDelay() * FbTk::FbTime::IN_MILLISECONDS); |
1010 | m_submenu_timer.start(); | 1010 | m_submenu_timer.start(); |
1011 | } else if (isItemSelectable(w)){ | 1011 | } else if (isItemSelectable(w)){ |
1012 | // else normal menu item | 1012 | // else normal menu item |
@@ -1225,7 +1225,7 @@ void Menu::closeMenu() { | |||
1225 | } | 1225 | } |
1226 | 1226 | ||
1227 | void Menu::startHide() { | 1227 | void Menu::startHide() { |
1228 | m_hide_timer.setTimeout(theme()->getDelay()); | 1228 | m_hide_timer.setTimeout(theme()->getDelay() * FbTk::FbTime::IN_MILLISECONDS); |
1229 | m_hide_timer.start(); | 1229 | m_hide_timer.start(); |
1230 | } | 1230 | } |
1231 | 1231 | ||
diff --git a/src/FbTk/Timer.cc b/src/FbTk/Timer.cc index 8b144db..6a478bd 100644 --- a/src/FbTk/Timer.cc +++ b/src/FbTk/Timer.cc | |||
@@ -1,5 +1,5 @@ | |||
1 | // Timer.cc for FbTk - Fluxbox Toolkit | 1 | // Timer.cc for FbTk - Fluxbox Toolkit |
2 | // Copyright (c) 2003 - 2006 Henrik Kinnunen (fluxgen at fluxbox dot org) | 2 | // Copyright (c) 2003 - 2012 Henrik Kinnunen (fluxgen at fluxbox dot org) |
3 | // | 3 | // |
4 | // Timer.cc for Blackbox - An X11 Window Manager | 4 | // Timer.cc for Blackbox - An X11 Window Manager |
5 | // Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net) | 5 | // Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net) |
@@ -32,10 +32,6 @@ | |||
32 | #define _GNU_SOURCE | 32 | #define _GNU_SOURCE |
33 | #endif // _GNU_SOURCE | 33 | #endif // _GNU_SOURCE |
34 | 34 | ||
35 | #ifdef HAVE_CONFIG_H | ||
36 | #include "config.h" | ||
37 | #endif // HAVE_CONFIG_H | ||
38 | |||
39 | #ifdef HAVE_CASSERT | 35 | #ifdef HAVE_CASSERT |
40 | #include <cassert> | 36 | #include <cassert> |
41 | #else | 37 | #else |
@@ -55,9 +51,48 @@ | |||
55 | # include <winsock.h> | 51 | # include <winsock.h> |
56 | #endif | 52 | #endif |
57 | 53 | ||
58 | namespace FbTk { | 54 | #include <cstdio> |
55 | #include <set> | ||
56 | |||
57 | |||
58 | namespace { | ||
59 | |||
60 | struct TimerCompare { | ||
61 | bool operator() (const FbTk::Timer* a, const FbTk::Timer* b) { | ||
62 | return a->getEndTime() < b->getEndTime(); | ||
63 | } | ||
64 | }; | ||
65 | typedef std::set<FbTk::Timer*, TimerCompare> TimerList; | ||
66 | |||
67 | TimerList s_timerlist; | ||
68 | |||
69 | |||
70 | /// add a timer to the static list | ||
71 | void addTimer(FbTk::Timer *timer) { | ||
72 | |||
73 | assert(timer); | ||
74 | int interval = timer->getInterval(); | ||
75 | |||
76 | // interval timers have their timeout change every time they are started! | ||
77 | if (interval != 0) { | ||
78 | timer->setTimeout(interval * FbTk::FbTime::IN_SECONDS); | ||
79 | } | ||
80 | |||
81 | s_timerlist.insert(timer); | ||
82 | } | ||
59 | 83 | ||
60 | Timer::TimerList Timer::m_timerlist; | 84 | /// remove a timer from the static list |
85 | void removeTimer(FbTk::Timer *timer) { | ||
86 | |||
87 | assert(timer); | ||
88 | s_timerlist.erase(timer); | ||
89 | } | ||
90 | |||
91 | |||
92 | } | ||
93 | |||
94 | |||
95 | namespace FbTk { | ||
61 | 96 | ||
62 | Timer::Timer():m_timing(false), m_once(false), m_interval(0) { | 97 | Timer::Timer():m_timing(false), m_once(false), m_interval(0) { |
63 | 98 | ||
@@ -76,22 +111,8 @@ Timer::~Timer() { | |||
76 | } | 111 | } |
77 | 112 | ||
78 | 113 | ||
79 | void Timer::setTimeout(time_t t) { | 114 | void Timer::setTimeout(uint64_t timeout) { |
80 | m_timeout.tv_sec = t / 1000; | 115 | m_timeout = timeout; |
81 | m_timeout.tv_usec = t; | ||
82 | m_timeout.tv_usec -= (m_timeout.tv_sec * 1000); | ||
83 | m_timeout.tv_usec *= 1000; | ||
84 | } | ||
85 | |||
86 | |||
87 | void Timer::setTimeout(const timeval &t) { | ||
88 | m_timeout.tv_sec = t.tv_sec; | ||
89 | m_timeout.tv_usec = t.tv_usec; | ||
90 | } | ||
91 | |||
92 | void Timer::setTimeout(unsigned int secs, unsigned int usecs) { | ||
93 | m_timeout.tv_sec = secs; | ||
94 | m_timeout.tv_usec = usecs; | ||
95 | } | 116 | } |
96 | 117 | ||
97 | void Timer::setCommand(const RefCount<Slot<void> > &cmd) { | 118 | void Timer::setCommand(const RefCount<Slot<void> > &cmd) { |
@@ -99,28 +120,24 @@ void Timer::setCommand(const RefCount<Slot<void> > &cmd) { | |||
99 | } | 120 | } |
100 | 121 | ||
101 | void Timer::start() { | 122 | void Timer::start() { |
102 | gettimeofday(&m_start, 0); | 123 | |
124 | m_start = FbTk::FbTime::now(); | ||
103 | 125 | ||
104 | // only add Timers that actually DO something | 126 | // only add Timers that actually DO something |
105 | if ((! m_timing || m_interval != 0) && m_handler) { | 127 | if ((! m_timing || m_interval != 0) && m_handler) { |
106 | m_timing = true; | 128 | m_timing = true; |
107 | addTimer(this); //add us to the list | 129 | ::addTimer(this); |
108 | } | 130 | } |
109 | } | 131 | } |
110 | 132 | ||
111 | 133 | ||
112 | void Timer::stop() { | 134 | void Timer::stop() { |
113 | m_timing = false; | 135 | m_timing = false; |
114 | removeTimer(this); //remove us from the list | 136 | ::removeTimer(this); |
115 | } | 137 | } |
116 | 138 | ||
117 | void Timer::makeEndTime(timeval &tm) const { | 139 | uint64_t Timer::getEndTime() const { |
118 | tm.tv_sec = m_start.tv_sec + m_timeout.tv_sec; | 140 | return m_start + m_timeout; |
119 | tm.tv_usec = m_start.tv_usec + m_timeout.tv_usec; | ||
120 | if (tm.tv_usec >= 1000000) { | ||
121 | tm.tv_usec -= 1000000; | ||
122 | tm.tv_sec++; | ||
123 | } | ||
124 | } | 141 | } |
125 | 142 | ||
126 | 143 | ||
@@ -129,42 +146,34 @@ void Timer::fireTimeout() { | |||
129 | (*m_handler)(); | 146 | (*m_handler)(); |
130 | } | 147 | } |
131 | 148 | ||
149 | |||
132 | void Timer::updateTimers(int fd) { | 150 | void Timer::updateTimers(int fd) { |
151 | |||
133 | fd_set rfds; | 152 | fd_set rfds; |
134 | timeval now, tm, *timeout = 0; | 153 | timeval tm; |
154 | timeval* timeout = 0; | ||
155 | TimerList::iterator it; | ||
135 | 156 | ||
136 | FD_ZERO(&rfds); | 157 | FD_ZERO(&rfds); |
137 | FD_SET(fd, &rfds); | 158 | FD_SET(fd, &rfds); |
138 | 159 | ||
139 | bool overdue = false; | 160 | bool overdue = false; |
161 | uint64_t now = FbTime::now(); | ||
162 | uint64_t end_time; | ||
140 | 163 | ||
141 | // see, if the first timer in the | 164 | // see, if the first timer in the |
142 | // list is overdue | 165 | // list is overdue |
143 | if (!m_timerlist.empty()) { | 166 | if (!s_timerlist.empty()) { |
144 | gettimeofday(&now, 0); | ||
145 | |||
146 | Timer *timer = m_timerlist.front(); | ||
147 | |||
148 | timer->makeEndTime(tm); | ||
149 | 167 | ||
150 | tm.tv_sec -= now.tv_sec; | 168 | Timer* timer = *s_timerlist.begin(); |
151 | tm.tv_usec -= now.tv_usec; | 169 | end_time = timer->getEndTime(); |
152 | 170 | ||
153 | while (tm.tv_usec < 0) { | 171 | if (end_time < now) { |
154 | if (tm.tv_sec > 0) { | ||
155 | tm.tv_sec--; | ||
156 | tm.tv_usec += 1000000; | ||
157 | } else { | ||
158 | overdue = true; | ||
159 | tm.tv_usec = 0; | ||
160 | break; | ||
161 | } | ||
162 | } | ||
163 | |||
164 | if (tm.tv_sec < 0) { // usec zero-ed above if negative | ||
165 | tm.tv_sec = 0; | ||
166 | tm.tv_usec = 0; | ||
167 | overdue = true; | 172 | overdue = true; |
173 | } else { | ||
174 | uint64_t diff = (end_time - now); | ||
175 | tm.tv_sec = diff / FbTime::IN_SECONDS; | ||
176 | tm.tv_usec = diff % FbTime::IN_SECONDS; | ||
168 | } | 177 | } |
169 | 178 | ||
170 | timeout = &tm; | 179 | timeout = &tm; |
@@ -173,100 +182,41 @@ void Timer::updateTimers(int fd) { | |||
173 | // if not overdue, wait for the next xevent via the blocking | 182 | // if not overdue, wait for the next xevent via the blocking |
174 | // select(), so OS sends fluxbox to sleep. the select() will | 183 | // select(), so OS sends fluxbox to sleep. the select() will |
175 | // time out when the next timer has to be handled | 184 | // time out when the next timer has to be handled |
176 | if (!overdue && select(fd + 1, &rfds, 0, 0, timeout) != 0) | 185 | if (!overdue && select(fd + 1, &rfds, 0, 0, timeout) != 0) { |
177 | // didn't time out! x events are pending | 186 | // didn't time out! x events are pending |
178 | return; | 187 | return; |
179 | |||
180 | TimerList::iterator it; | ||
181 | |||
182 | // check for timer timeout | ||
183 | gettimeofday(&now, 0); | ||
184 | |||
185 | // someone set the date of the machine BACK | ||
186 | // so we have to adjust the start_time | ||
187 | static time_t last_time = 0; | ||
188 | if (now.tv_sec < last_time) { | ||
189 | |||
190 | time_t delta = last_time - now.tv_sec; | ||
191 | |||
192 | for (it = m_timerlist.begin(); it != m_timerlist.end(); ++it) { | ||
193 | (*it)->m_start.tv_sec -= delta; | ||
194 | } | ||
195 | } | 188 | } |
196 | last_time = now.tv_sec; | ||
197 | |||
198 | 189 | ||
199 | //must check end ...the timer might remove | 190 | now = FbTime::now(); |
200 | //it self from the list (should be fixed in the future) | 191 | for (it = s_timerlist.begin(); it != s_timerlist.end(); ) { |
201 | for(it = m_timerlist.begin(); it != m_timerlist.end(); ) { | ||
202 | //This is to make sure we don't get an invalid iterator | ||
203 | //when we do fireTimeout | ||
204 | Timer &t = *(*it); | ||
205 | 192 | ||
206 | t.makeEndTime(tm); | 193 | // t->fireTimeout() might add timers to the list |
207 | 194 | // this invalidates 'it'. thus we store the current | |
208 | if (((now.tv_sec < tm.tv_sec) || | 195 | // item here |
209 | (now.tv_sec == tm.tv_sec && now.tv_usec < tm.tv_usec))) | 196 | Timer* t = *it; |
197 | if (now < t->getEndTime()) { | ||
210 | break; | 198 | break; |
211 | |||
212 | t.fireTimeout(); | ||
213 | // restart the current timer so that the start time is updated | ||
214 | if (! t.doOnce()) { | ||
215 | // must erase so that it's put into the right place in the list | ||
216 | it = m_timerlist.erase(it); | ||
217 | t.m_timing = false; | ||
218 | t.start(); | ||
219 | } else { | ||
220 | // Since the default stop behaviour results in the timer | ||
221 | // being removed, we must remove it here, so that the iterator | ||
222 | // lives well. Another option would be to add it to another | ||
223 | // list, and then just go through that list and stop them all. | ||
224 | it = m_timerlist.erase(it); | ||
225 | t.stop(); | ||
226 | } | 199 | } |
227 | } | ||
228 | 200 | ||
229 | } | 201 | t->fireTimeout(); |
230 | 202 | ||
231 | void Timer::addTimer(Timer *timer) { | 203 | // find the iterator to the timer again |
232 | assert(timer); | 204 | // and continue working on the list |
233 | int interval = timer->getInterval(); | 205 | it = s_timerlist.find(t); |
234 | // interval timers have their timeout change every time they are started! | 206 | it++; |
235 | timeval tm; | 207 | s_timerlist.erase(t); |
236 | if (interval != 0) { | ||
237 | tm.tv_sec = timer->getStartTime().tv_sec; | ||
238 | tm.tv_usec = timer->getStartTime().tv_usec; | ||
239 | |||
240 | // now convert to interval | ||
241 | tm.tv_sec = interval - (tm.tv_sec % interval) - 1; | ||
242 | tm.tv_usec = 1000000 - tm.tv_usec; | ||
243 | if (tm.tv_usec == 1000000) { | ||
244 | tm.tv_usec = 0; | ||
245 | tm.tv_sec += 1; | ||
246 | } | ||
247 | timer->setTimeout(tm); | ||
248 | } | ||
249 | |||
250 | // set timeval to the time-of-trigger | ||
251 | timer->makeEndTime(tm); | ||
252 | 208 | ||
253 | // timer list is sorted by trigger time (i.e. start plus timeout) | 209 | if (! t->doOnce()) { // restart the current timer |
254 | TimerList::iterator it = m_timerlist.begin(); | 210 | t->m_timing = false; |
255 | TimerList::iterator it_end = m_timerlist.end(); | 211 | t->start(); |
256 | for (; it != it_end; ++it) { | 212 | } else { |
257 | timeval trig; | 213 | t->stop(); |
258 | (*it)->makeEndTime(trig); | ||
259 | |||
260 | if ((trig.tv_sec > tm.tv_sec) || | ||
261 | (trig.tv_sec == tm.tv_sec && | ||
262 | trig.tv_usec >= tm.tv_usec)) { | ||
263 | break; | ||
264 | } | 214 | } |
265 | } | 215 | } |
266 | m_timerlist.insert(it, timer); | ||
267 | 216 | ||
268 | } | 217 | } |
269 | 218 | ||
219 | |||
270 | Command<void> *DelayedCmd::parse(const std::string &command, | 220 | Command<void> *DelayedCmd::parse(const std::string &command, |
271 | const std::string &args, bool trusted) { | 221 | const std::string &args, bool trusted) { |
272 | 222 | ||
@@ -280,7 +230,7 @@ Command<void> *DelayedCmd::parse(const std::string &command, | |||
280 | if (cmd == 0) | 230 | if (cmd == 0) |
281 | return 0; | 231 | return 0; |
282 | 232 | ||
283 | int delay = 200000; | 233 | int delay = 200; |
284 | StringUtil::fromString<int>(args.c_str() + err, delay); | 234 | StringUtil::fromString<int>(args.c_str() + err, delay); |
285 | 235 | ||
286 | return new DelayedCmd(cmd, delay); | 236 | return new DelayedCmd(cmd, delay); |
@@ -294,10 +244,7 @@ DelayedCmd::DelayedCmd(const RefCount<Slot<void> > &cmd, unsigned int timeout) { | |||
294 | } | 244 | } |
295 | 245 | ||
296 | void DelayedCmd::initTimer(unsigned int timeout) { | 246 | void DelayedCmd::initTimer(unsigned int timeout) { |
297 | timeval to; | 247 | m_timer.setTimeout(timeout * FbTime::IN_MILLISECONDS); |
298 | to.tv_sec = timeout/1000000; | ||
299 | to.tv_usec = timeout % 1000000; | ||
300 | m_timer.setTimeout(to); | ||
301 | m_timer.fireOnce(true); | 248 | m_timer.fireOnce(true); |
302 | } | 249 | } |
303 | 250 | ||
@@ -307,9 +254,4 @@ void DelayedCmd::execute() { | |||
307 | m_timer.start(); | 254 | m_timer.start(); |
308 | } | 255 | } |
309 | 256 | ||
310 | void Timer::removeTimer(Timer *timer) { | ||
311 | assert(timer); | ||
312 | m_timerlist.remove(timer); | ||
313 | } | ||
314 | |||
315 | } // end namespace FbTk | 257 | } // end namespace FbTk |
diff --git a/src/FbTk/Timer.hh b/src/FbTk/Timer.hh index 376eac0..241e327 100644 --- a/src/FbTk/Timer.hh +++ b/src/FbTk/Timer.hh | |||
@@ -27,26 +27,13 @@ | |||
27 | 27 | ||
28 | #include "RefCount.hh" | 28 | #include "RefCount.hh" |
29 | #include "Command.hh" | 29 | #include "Command.hh" |
30 | 30 | #include "FbTime.hh" | |
31 | #ifdef HAVE_CTIME | ||
32 | #include <ctime> | ||
33 | #else | ||
34 | #include <time.h> | ||
35 | #endif | ||
36 | #include <list> | ||
37 | #include <string> | ||
38 | 31 | ||
39 | #ifdef HAVE_CONFIG_H | 32 | #ifdef HAVE_CONFIG_H |
40 | #include "config.h" | 33 | #include "config.h" |
41 | #endif //HAVE_CONFIG_H | 34 | #endif //HAVE_CONFIG_H |
42 | 35 | ||
43 | #ifdef HAVE_INTTYPES_H | 36 | #include <string> |
44 | #include <inttypes.h> | ||
45 | #endif // HAVE_INTTYPES_H | ||
46 | |||
47 | #include <sys/types.h> | ||
48 | #include <sys/time.h> | ||
49 | #include <unistd.h> | ||
50 | 37 | ||
51 | namespace FbTk { | 38 | namespace FbTk { |
52 | 39 | ||
@@ -57,24 +44,21 @@ class Timer { | |||
57 | public: | 44 | public: |
58 | Timer(); | 45 | Timer(); |
59 | explicit Timer(const RefCount<Slot<void> > &handler); | 46 | explicit Timer(const RefCount<Slot<void> > &handler); |
60 | virtual ~Timer(); | 47 | ~Timer(); |
61 | 48 | ||
62 | void fireOnce(bool once) { m_once = once; } | 49 | void fireOnce(bool once) { m_once = once; } |
63 | /// set timeout | 50 | void setTimeout(uint64_t timeout); |
64 | void setTimeout(time_t val); | ||
65 | /// set timeout | ||
66 | void setTimeout(const timeval &val); | ||
67 | void setTimeout(unsigned int secs, unsigned int usecs); | ||
68 | void setCommand(const RefCount<Slot<void> > &cmd); | 51 | void setCommand(const RefCount<Slot<void> > &cmd); |
52 | |||
69 | template<typename Functor> | 53 | template<typename Functor> |
70 | void setFunctor(const Functor &functor) | 54 | void setFunctor(const Functor &functor) { |
71 | { setCommand(RefCount<Slot<void> >(new SlotImpl<Functor, void>(functor))); } | 55 | setCommand(RefCount<Slot<void> >(new SlotImpl<Functor, void>(functor))); |
72 | void setInterval(int val) { m_interval = val; } | 56 | } |
73 | /// start timing | 57 | |
58 | void setInterval(int seconds) { m_interval = seconds; } | ||
74 | void start(); | 59 | void start(); |
75 | /// stop timing | ||
76 | void stop(); | 60 | void stop(); |
77 | /// update all timers | 61 | |
78 | static void updateTimers(int file_descriptor); | 62 | static void updateTimers(int file_descriptor); |
79 | 63 | ||
80 | int isTiming() const { return m_timing; } | 64 | int isTiming() const { return m_timing; } |
@@ -82,38 +66,29 @@ public: | |||
82 | 66 | ||
83 | int doOnce() const { return m_once; } | 67 | int doOnce() const { return m_once; } |
84 | 68 | ||
85 | const timeval &getTimeout() const { return m_timeout; } | 69 | uint64_t getTimeout() const { return m_timeout; } |
86 | const timeval &getStartTime() const { return m_start; } | 70 | uint64_t getStartTime() const { return m_start; } |
87 | void makeEndTime(timeval &tm) const; | 71 | uint64_t getEndTime() const; |
88 | 72 | ||
89 | protected: | 73 | protected: |
90 | /// force a timeout | 74 | /// force a timeout |
91 | void fireTimeout(); | 75 | void fireTimeout(); |
92 | 76 | ||
93 | private: | 77 | private: |
94 | /// add a timer to the static list | ||
95 | static void addTimer(Timer *timer); | ||
96 | /// remove a timer from the static list | ||
97 | static void removeTimer(Timer *timer); | ||
98 | |||
99 | typedef std::list<Timer *> TimerList; | ||
100 | static TimerList m_timerlist; ///< list of all timers, sorted by next trigger time (start + timeout) | ||
101 | |||
102 | RefCount<Slot<void> > m_handler; ///< what to do on a timeout | 78 | RefCount<Slot<void> > m_handler; ///< what to do on a timeout |
103 | 79 | ||
104 | bool m_timing; ///< clock running? | 80 | bool m_timing; ///< clock running? |
105 | bool m_once; ///< do timeout only once? | 81 | bool m_once; ///< do timeout only once? |
106 | int m_interval; ///< Is an interval-only timer (e.g. clock) | 82 | int m_interval; ///< Is an interval-only timer (e.g. clock), in seconds |
107 | // note that intervals only take note of the seconds, not microseconds | ||
108 | 83 | ||
109 | timeval m_start; ///< start time | 84 | uint64_t m_start; ///< start time in microseconds |
110 | timeval m_timeout; ///< time length | 85 | uint64_t m_timeout; ///< time length in microseconds |
111 | }; | 86 | }; |
112 | 87 | ||
113 | /// executes a command after a specified timeout | 88 | /// executes a command after a specified timeout |
114 | class DelayedCmd: public Command<void> { | 89 | class DelayedCmd: public Command<void> { |
115 | public: | 90 | public: |
116 | DelayedCmd(const RefCount<Slot<void> > &cmd, unsigned int timeout = 200000); | 91 | DelayedCmd(const RefCount<Slot<void> > &cmd, unsigned int timeout = 200); |
117 | 92 | ||
118 | // this constructor has inverted order of parameters to avoid ambiguity with the previous | 93 | // this constructor has inverted order of parameters to avoid ambiguity with the previous |
119 | // constructor | 94 | // constructor |
diff --git a/src/Slit.cc b/src/Slit.cc index 02eb877..738a81a 100644 --- a/src/Slit.cc +++ b/src/Slit.cc | |||
@@ -279,7 +279,7 @@ Slit::Slit(BScreen &scr, FbTk::Layer &layer, const char *filename) | |||
279 | // move the frame out of sight for a moment | 279 | // move the frame out of sight for a moment |
280 | frame.window.move(-frame.window.width(), -frame.window.height()); | 280 | frame.window.move(-frame.window.width(), -frame.window.height()); |
281 | // setup timer | 281 | // setup timer |
282 | m_timer.setTimeout(200); // default timeout | 282 | m_timer.setTimeout(200L * FbTk::FbTime::IN_MILLISECONDS); // default timeout |
283 | m_timer.fireOnce(true); | 283 | m_timer.fireOnce(true); |
284 | FbTk::RefCount<FbTk::Command<void> > toggle_hidden(new FbTk::SimpleCommand<Slit>(*this, &Slit::toggleHidden)); | 284 | FbTk::RefCount<FbTk::Command<void> > toggle_hidden(new FbTk::SimpleCommand<Slit>(*this, &Slit::toggleHidden)); |
285 | m_timer.setCommand(toggle_hidden); | 285 | m_timer.setCommand(toggle_hidden); |
diff --git a/src/Toolbar.cc b/src/Toolbar.cc index a8b2c5b..1c22440 100644 --- a/src/Toolbar.cc +++ b/src/Toolbar.cc | |||
@@ -258,7 +258,7 @@ Toolbar::Toolbar(BScreen &scrn, FbTk::Layer &layer, size_t width): | |||
258 | frame.grab_x = frame.grab_y = 0; | 258 | frame.grab_x = frame.grab_y = 0; |
259 | 259 | ||
260 | // setup hide timer | 260 | // setup hide timer |
261 | m_hide_timer.setTimeout(Fluxbox::instance()->getAutoRaiseDelay()); | 261 | m_hide_timer.setTimeout(Fluxbox::instance()->getAutoRaiseDelay() * FbTk::FbTime::IN_MILLISECONDS); |
262 | FbTk::RefCount<FbTk::Command<void> > toggle_hidden(new FbTk::SimpleCommand<Toolbar>(*this, &Toolbar::toggleHidden)); | 262 | FbTk::RefCount<FbTk::Command<void> > toggle_hidden(new FbTk::SimpleCommand<Toolbar>(*this, &Toolbar::toggleHidden)); |
263 | m_hide_timer.setCommand(toggle_hidden); | 263 | m_hide_timer.setCommand(toggle_hidden); |
264 | m_hide_timer.fireOnce(true); | 264 | m_hide_timer.fireOnce(true); |
diff --git a/src/TooltipWindow.cc b/src/TooltipWindow.cc index 0fb7273..77a6e1e 100644 --- a/src/TooltipWindow.cc +++ b/src/TooltipWindow.cc | |||
@@ -55,8 +55,11 @@ void TooltipWindow::raiseTooltip() { | |||
55 | 55 | ||
56 | resize(m_lastText); | 56 | resize(m_lastText); |
57 | reconfigTheme(); | 57 | reconfigTheme(); |
58 | int h = theme()->iconbarTheme().text().font().height() + theme()->bevelWidth() * 2; | 58 | |
59 | int w = theme()->iconbarTheme().text().font().textWidth(m_lastText) + theme()->bevelWidth() * 2; | 59 | FbTk::Font& font = theme()->iconbarTheme().text().font(); |
60 | |||
61 | int h = font.height() + theme()->bevelWidth() * 2; | ||
62 | int w = font.textWidth(m_lastText) + theme()->bevelWidth() * 2; | ||
60 | 63 | ||
61 | Window root_ret; // not used | 64 | Window root_ret; // not used |
62 | Window window_ret; // not used | 65 | Window window_ret; // not used |
@@ -91,11 +94,11 @@ void TooltipWindow::raiseTooltip() { | |||
91 | show(); | 94 | show(); |
92 | clear(); | 95 | clear(); |
93 | // TODO: make this use a TextButton like TextDialog does | 96 | // TODO: make this use a TextButton like TextDialog does |
94 | theme()->iconbarTheme().text().font().drawText(*this, screen().screenNumber(), | 97 | font.drawText(*this, screen().screenNumber(), |
95 | theme()->iconbarTheme().text().textGC(), | 98 | theme()->iconbarTheme().text().textGC(), |
96 | m_lastText, | 99 | m_lastText, |
97 | theme()->bevelWidth(), | 100 | theme()->bevelWidth(), |
98 | theme()->bevelWidth() + theme()->iconbarTheme().text().font().ascent()); | 101 | theme()->bevelWidth() + font.ascent()); |
99 | } | 102 | } |
100 | 103 | ||
101 | void TooltipWindow::updateText(const FbTk::BiDiString& text) { | 104 | void TooltipWindow::updateText(const FbTk::BiDiString& text) { |
diff --git a/src/TooltipWindow.hh b/src/TooltipWindow.hh index 4d028b5..67bec90 100644 --- a/src/TooltipWindow.hh +++ b/src/TooltipWindow.hh | |||
@@ -47,7 +47,7 @@ public: | |||
47 | /// Sets the delay before the window pops up | 47 | /// Sets the delay before the window pops up |
48 | void setDelay(int delay) { | 48 | void setDelay(int delay) { |
49 | m_delay = delay; | 49 | m_delay = delay; |
50 | m_timer.setTimeout(delay); | 50 | m_timer.setTimeout(delay * FbTk::FbTime::IN_MILLISECONDS); |
51 | } | 51 | } |
52 | 52 | ||
53 | void hide(); | 53 | void hide(); |
diff --git a/src/Window.cc b/src/Window.cc index 597bc08..33a4c9e 100644 --- a/src/Window.cc +++ b/src/Window.cc | |||
@@ -416,7 +416,7 @@ void FluxboxWindow::init() { | |||
416 | 416 | ||
417 | updateMWMHintsFromClient(*m_client); | 417 | updateMWMHintsFromClient(*m_client); |
418 | 418 | ||
419 | m_timer.setTimeout(fluxbox.getAutoRaiseDelay()); | 419 | m_timer.setTimeout(fluxbox.getAutoRaiseDelay() * FbTk::FbTime::IN_MILLISECONDS); |
420 | FbTk::RefCount<FbTk::Command<void> > raise_cmd(new FbTk::SimpleCommand<FluxboxWindow>(*this, | 420 | FbTk::RefCount<FbTk::Command<void> > raise_cmd(new FbTk::SimpleCommand<FluxboxWindow>(*this, |
421 | &FluxboxWindow::raise)); | 421 | &FluxboxWindow::raise)); |
422 | m_timer.setCommand(raise_cmd); | 422 | m_timer.setCommand(raise_cmd); |
@@ -538,9 +538,7 @@ void FluxboxWindow::init() { | |||
538 | 538 | ||
539 | m_workspacesig.emit(*this); | 539 | m_workspacesig.emit(*this); |
540 | 540 | ||
541 | struct timeval now; | 541 | m_creation_time = FbTk::FbTime::now(); |
542 | gettimeofday(&now, NULL); | ||
543 | m_creation_time = now.tv_sec; | ||
544 | 542 | ||
545 | frame().frameExtentSig().emit(); | 543 | frame().frameExtentSig().emit(); |
546 | 544 | ||
@@ -1049,15 +1047,10 @@ void FluxboxWindow::grabButtons() { | |||
1049 | void FluxboxWindow::reconfigure() { | 1047 | void FluxboxWindow::reconfigure() { |
1050 | 1048 | ||
1051 | applyDecorations(); | 1049 | applyDecorations(); |
1052 | |||
1053 | setFocusFlag(m_focused); | 1050 | setFocusFlag(m_focused); |
1054 | |||
1055 | moveResize(frame().x(), frame().y(), frame().width(), frame().height()); | 1051 | moveResize(frame().x(), frame().y(), frame().width(), frame().height()); |
1056 | 1052 | m_timer.setTimeout(Fluxbox::instance()->getAutoRaiseDelay() * FbTk::FbTime::IN_MILLISECONDS); | |
1057 | m_timer.setTimeout(Fluxbox::instance()->getAutoRaiseDelay()); | ||
1058 | |||
1059 | updateButtons(); | 1053 | updateButtons(); |
1060 | |||
1061 | frame().reconfigure(); | 1054 | frame().reconfigure(); |
1062 | menu().reconfigure(); | 1055 | menu().reconfigure(); |
1063 | 1056 | ||
@@ -2200,14 +2193,14 @@ void FluxboxWindow::configureRequestEvent(XConfigureRequestEvent &cr) { | |||
2200 | // don't let misbehaving clients (e.g. MPlayer) move/resize their windows | 2193 | // don't let misbehaving clients (e.g. MPlayer) move/resize their windows |
2201 | // just after creation if the user has a saved position/size | 2194 | // just after creation if the user has a saved position/size |
2202 | if (m_creation_time) { | 2195 | if (m_creation_time) { |
2203 | struct timeval now; | 2196 | |
2204 | gettimeofday(&now, NULL); | 2197 | uint64_t now = FbTk::FbTime::now(); |
2205 | 2198 | ||
2206 | Remember& rinst = Remember::instance(); | 2199 | Remember& rinst = Remember::instance(); |
2207 | 2200 | ||
2208 | if (now.tv_sec > m_creation_time + 1) | 2201 | if (now > (m_creation_time + FbTk::FbTime::IN_SECONDS)) { |
2209 | m_creation_time = 0; | 2202 | m_creation_time = 0; |
2210 | else if (rinst.isRemembered(*client, Remember::REM_MAXIMIZEDSTATE) || | 2203 | } else if (rinst.isRemembered(*client, Remember::REM_MAXIMIZEDSTATE) || |
2211 | rinst.isRemembered(*client, Remember::REM_FULLSCREENSTATE)) { | 2204 | rinst.isRemembered(*client, Remember::REM_FULLSCREENSTATE)) { |
2212 | cr.value_mask = cr.value_mask & ~(CWWidth | CWHeight); | 2205 | cr.value_mask = cr.value_mask & ~(CWWidth | CWHeight); |
2213 | cr.value_mask = cr.value_mask & ~(CWX | CWY); | 2206 | cr.value_mask = cr.value_mask & ~(CWX | CWY); |
@@ -2300,23 +2293,18 @@ void FluxboxWindow::keyPressEvent(XKeyEvent &ke) { | |||
2300 | // e.g., typed the command in a terminal | 2293 | // e.g., typed the command in a terminal |
2301 | if (ks == XK_KP_Enter || ks == XK_Return) { | 2294 | if (ks == XK_KP_Enter || ks == XK_Return) { |
2302 | // we'll actually reset the time for this one | 2295 | // we'll actually reset the time for this one |
2303 | m_last_keypress_time.tv_sec = 0; | 2296 | m_last_keypress_time = 0; |
2304 | return; | 2297 | return; |
2305 | } | 2298 | } |
2306 | 2299 | ||
2307 | // otherwise, make a note that the user is typing | 2300 | // otherwise, make a note that the user is typing |
2308 | gettimeofday(&m_last_keypress_time, 0); | 2301 | m_last_keypress_time = FbTk::FbTime::now(); |
2309 | } | 2302 | } |
2310 | 2303 | ||
2311 | bool FluxboxWindow::isTyping() const { | 2304 | bool FluxboxWindow::isTyping() const { |
2312 | timeval now; | ||
2313 | if (gettimeofday(&now, NULL) == -1) | ||
2314 | return false; | ||
2315 | |||
2316 | unsigned int diff = 1000*(now.tv_sec - m_last_keypress_time.tv_sec); | ||
2317 | diff += (now.tv_usec - m_last_keypress_time.tv_usec)/1000; | ||
2318 | 2305 | ||
2319 | return (diff < screen().noFocusWhileTypingDelay()); | 2306 | uint64_t diff = FbTk::FbTime::now() - m_last_keypress_time; |
2307 | return ((diff / 1000) < screen().noFocusWhileTypingDelay()); | ||
2320 | } | 2308 | } |
2321 | 2309 | ||
2322 | void FluxboxWindow::buttonPressEvent(XButtonEvent &be) { | 2310 | void FluxboxWindow::buttonPressEvent(XButtonEvent &be) { |
diff --git a/src/Window.hh b/src/Window.hh index 8c97c7b..09374af 100644 --- a/src/Window.hh +++ b/src/Window.hh | |||
@@ -33,11 +33,11 @@ | |||
33 | 33 | ||
34 | #include "FbTk/DefaultValue.hh" | 34 | #include "FbTk/DefaultValue.hh" |
35 | #include "FbTk/Timer.hh" | 35 | #include "FbTk/Timer.hh" |
36 | #include "FbTk/FbTime.hh" | ||
36 | #include "FbTk/EventHandler.hh" | 37 | #include "FbTk/EventHandler.hh" |
37 | #include "FbTk/LayerItem.hh" | 38 | #include "FbTk/LayerItem.hh" |
38 | #include "FbTk/Signal.hh" | 39 | #include "FbTk/Signal.hh" |
39 | 40 | ||
40 | #include <sys/time.h> | ||
41 | #include <vector> | 41 | #include <vector> |
42 | #include <string> | 42 | #include <string> |
43 | #include <memory> | 43 | #include <memory> |
@@ -529,14 +529,15 @@ private: | |||
529 | // state and hint signals | 529 | // state and hint signals |
530 | FbTk::Signal<FluxboxWindow &> m_workspacesig, m_statesig, m_layersig, m_hintsig; | 530 | FbTk::Signal<FluxboxWindow &> m_workspacesig, m_statesig, m_layersig, m_hintsig; |
531 | 531 | ||
532 | time_t m_creation_time; | 532 | uint64_t m_creation_time; |
533 | uint64_t m_last_keypress_time; | ||
534 | FbTk::Timer m_timer; | ||
533 | 535 | ||
534 | // Window states | 536 | // Window states |
535 | bool moving, resizing, m_initialized; | 537 | bool moving, resizing, m_initialized; |
536 | 538 | ||
537 | WinClient *m_attaching_tab; | 539 | WinClient *m_attaching_tab; |
538 | 540 | ||
539 | FbTk::Timer m_timer; | ||
540 | Display *display; /// display connection | 541 | Display *display; /// display connection |
541 | 542 | ||
542 | int m_button_grab_x, m_button_grab_y; // handles last button press event for move | 543 | int m_button_grab_x, m_button_grab_y; // handles last button press event for move |
@@ -545,8 +546,6 @@ private: | |||
545 | int m_last_resize_h, m_last_resize_w; // handles height/width for resize "window" | 546 | int m_last_resize_h, m_last_resize_w; // handles height/width for resize "window" |
546 | int m_last_pressed_button; | 547 | int m_last_pressed_button; |
547 | 548 | ||
548 | timeval m_last_keypress_time; | ||
549 | |||
550 | unsigned int m_workspace_number; | 549 | unsigned int m_workspace_number; |
551 | unsigned long m_current_state; // NormalState | IconicState | Withdrawn | 550 | unsigned long m_current_state; // NormalState | IconicState | Withdrawn |
552 | 551 | ||
diff --git a/src/fluxbox.cc b/src/fluxbox.cc index 77b9881..129ac80 100644 --- a/src/fluxbox.cc +++ b/src/fluxbox.cc | |||
@@ -306,7 +306,7 @@ Fluxbox::Fluxbox(int argc, char **argv, | |||
306 | // because it could affect ongoing menu stuff so we need to reconfig in | 306 | // because it could affect ongoing menu stuff so we need to reconfig in |
307 | // the next event "round". | 307 | // the next event "round". |
308 | FbTk::RefCount<FbTk::Command<void> > reconfig_cmd(new FbTk::SimpleCommand<Fluxbox>(*this, &Fluxbox::timed_reconfigure)); | 308 | FbTk::RefCount<FbTk::Command<void> > reconfig_cmd(new FbTk::SimpleCommand<Fluxbox>(*this, &Fluxbox::timed_reconfigure)); |
309 | m_reconfig_timer.setTimeout(0, 1); | 309 | m_reconfig_timer.setTimeout(1); |
310 | m_reconfig_timer.setCommand(reconfig_cmd); | 310 | m_reconfig_timer.setCommand(reconfig_cmd); |
311 | m_reconfig_timer.fireOnce(true); | 311 | m_reconfig_timer.fireOnce(true); |
312 | 312 | ||
@@ -363,7 +363,6 @@ Fluxbox::Fluxbox(int argc, char **argv, | |||
363 | screens.push_back(i); | 363 | screens.push_back(i); |
364 | 364 | ||
365 | // find out, on what "screens" fluxbox should run | 365 | // find out, on what "screens" fluxbox should run |
366 | // FIXME(php-coder): maybe it worths moving this code to main.cc, where command line is parsed? | ||
367 | for (i = 1; i < m_argc; i++) { | 366 | for (i = 1; i < m_argc; i++) { |
368 | if (! strcmp(m_argv[i], "-screen")) { | 367 | if (! strcmp(m_argv[i], "-screen")) { |
369 | if ((++i) >= m_argc) { | 368 | if ((++i) >= m_argc) { |
@@ -507,8 +506,11 @@ void Fluxbox::initScreen(BScreen *screen) { | |||
507 | 506 | ||
508 | 507 | ||
509 | void Fluxbox::eventLoop() { | 508 | void Fluxbox::eventLoop() { |
509 | |||
510 | Display *disp = display(); | 510 | Display *disp = display(); |
511 | |||
511 | while (!m_shutdown) { | 512 | while (!m_shutdown) { |
513 | |||
512 | if (XPending(disp)) { | 514 | if (XPending(disp)) { |
513 | XEvent e; | 515 | XEvent e; |
514 | XNextEvent(disp, &e); | 516 | XNextEvent(disp, &e); |
@@ -524,8 +526,9 @@ void Fluxbox::eventLoop() { | |||
524 | handleEvent(&e); | 526 | handleEvent(&e); |
525 | } | 527 | } |
526 | } else { | 528 | } else { |
527 | FbTk::Timer::updateTimers(ConnectionNumber(disp)); //handle all timers | 529 | FbTk::Timer::updateTimers(ConnectionNumber(disp)); |
528 | } | 530 | } |
531 | |||
529 | } | 532 | } |
530 | } | 533 | } |
531 | 534 | ||
@@ -553,9 +556,11 @@ void Fluxbox::ungrab() { | |||
553 | } | 556 | } |
554 | 557 | ||
555 | void Fluxbox::handleEvent(XEvent * const e) { | 558 | void Fluxbox::handleEvent(XEvent * const e) { |
559 | |||
556 | _FB_USES_NLS; | 560 | _FB_USES_NLS; |
557 | m_last_event = *e; | 561 | m_last_event = *e; |
558 | 562 | ||
563 | |||
559 | // it is possible (e.g. during moving) for a window | 564 | // it is possible (e.g. during moving) for a window |
560 | // to mask all events to go to it | 565 | // to mask all events to go to it |
561 | if ((m_masked == e->xany.window) && m_masked_window) { | 566 | if ((m_masked == e->xany.window) && m_masked_window) { |
diff --git a/src/tests/testDemandAttention.cc b/src/tests/testDemandAttention.cc index 10fadb3..914f369 100644 --- a/src/tests/testDemandAttention.cc +++ b/src/tests/testDemandAttention.cc | |||
@@ -61,10 +61,7 @@ public: | |||
61 | FbTk::RefCount<FbTk::Command<void> > cmd(new FbTk::SimpleCommand<App> | 61 | FbTk::RefCount<FbTk::Command<void> > cmd(new FbTk::SimpleCommand<App> |
62 | (*this, | 62 | (*this, |
63 | &App::demandAttention)); | 63 | &App::demandAttention)); |
64 | timeval t; | 64 | m_timer.setTimeout(5 * FbTk::FbTime::IN_SECONDS); |
65 | t.tv_sec = 5; | ||
66 | t.tv_usec = 0; | ||
67 | m_timer.setTimeout(t); | ||
68 | m_timer.setCommand(cmd); | 65 | m_timer.setCommand(cmd); |
69 | m_timer.fireOnce(false); | 66 | m_timer.fireOnce(false); |
70 | m_timer.start(); | 67 | m_timer.start(); |
diff --git a/src/tests/titletest.cc b/src/tests/titletest.cc index 9ea94f1..e16435a 100644 --- a/src/tests/titletest.cc +++ b/src/tests/titletest.cc | |||
@@ -52,10 +52,7 @@ public: | |||
52 | FbTk::RefCount<FbTk::Command> cmd(new FbTk::SimpleCommand<App> | 52 | FbTk::RefCount<FbTk::Command> cmd(new FbTk::SimpleCommand<App> |
53 | (*this, | 53 | (*this, |
54 | &App::updateTitle)); | 54 | &App::updateTitle)); |
55 | timeval t; | 55 | m_timer.setTimeout(150 * FbTk::FbTime::IN_MILLISECONDS); |
56 | t.tv_sec = 0; | ||
57 | t.tv_usec = 150000; | ||
58 | m_timer.setTimeout(t); | ||
59 | m_timer.setCommand(cmd); | 56 | m_timer.setCommand(cmd); |
60 | m_timer.fireOnce(false); | 57 | m_timer.fireOnce(false); |
61 | m_timer.start(); | 58 | m_timer.start(); |