all repos — fluxbox @ ec7fe513c8ca241836fab4632fc56faedd0f1863

custom fork of the fluxbox windowmanager

Trigger ClockTool every second, independent of the format string

It's hard to hit right moment to update the clock correctly: Either we are a
bit too early and the 'old time' is the same as the 'new time' and the clock
looks 'a bit off' or we are too late and the clock is 'a bit off'. This is
especially the case for format strings which do not show the second and thus
are updated only at the full minute (see bug #1082): if fluxbox does not
update the clock 'now' it would do it one minute later and thus the clock
might show the wrong time for roughly 1 minute.

Instead of coming up with something immensely clever we just trigger the
ClockTool every second. If no update of the shown time is needed fluxbox won't
do anything.

Some minor code reordering as byproduct.
Mathias Gumz akira at fluxbox dot org
commit

ec7fe513c8ca241836fab4632fc56faedd0f1863

parent

ac27c8cb4235b548ac1d1a5d5472d04a198bddf2

2 files changed, 44 insertions(+), 63 deletions(-)

jump to
M src/ClockTool.ccsrc/ClockTool.cc

@@ -56,26 +56,10 @@ const char SWITCHES_12_24H[] = "lIrkHT";

const char SWITCHES_24_12H[] = "kHTlIr"; const char SWITCH_AM_PM[] = "pP"; -/** - * return true if clock shows seconds. If clock doesn't show seconds then - * there is no need to wake up every second to redraw the clock. - */ - -int showSeconds(const std::string& fmt_string) { - - return FbTk::StringUtil::findCharFromAlphabetAfterTrigger( - fmt_string, '%', SWITCHES_SECONDS, sizeof(SWITCHES_SECONDS), 0) != std::string::npos; -} - - -uint64_t calcNextTimeout(const std::string& fmt_string) { +uint64_t calcNextTimeout() { uint64_t now = FbTk::FbTime::system(); uint64_t unit = FbTk::FbTime::IN_SECONDS; - if (!showSeconds(fmt_string)) { // microseconds till next full minute - unit *= 60L; - } - return FbTk::FbTime::remainingNext(now, unit); }

@@ -161,7 +145,7 @@ m_timeformat(screen.resourceManager(), std::string("%k:%M"),

screen.name() + ".strftimeFormat", screen.altName() + ".StrftimeFormat"), m_stringconvertor(FbTk::StringConvertor::ToFbString) { // attach signals - m_tracker.join(theme.reconfigSig(), FbTk::MemFun(*this, &ClockTool::themeReconfigured)); + m_tracker.join(theme.reconfigSig(), FbTk::MemFun(*this, &ClockTool::updateTime)); std::string time_locale = setlocale(LC_TIME, NULL); size_t pos = time_locale.find('.');

@@ -172,12 +156,9 @@ m_stringconvertor.setSource(time_locale);

_FB_USES_NLS; - m_timer.setTimeout(calcNextTimeout(*m_timeformat)); - FbTk::RefCount<FbTk::Command<void> > update_graphic(new FbTk::SimpleCommand<ClockTool>(*this, &ClockTool::updateTime)); m_timer.setCommand(update_graphic); - m_timer.start(); m_button.setGC(m_theme->textGC());

@@ -189,8 +170,7 @@ menu.insert(item);

FbTk::RefCount<FbTk::Command<void> > editformat_cmd(new EditClockFormatCmd()); menu.insert(_FB_XTEXT(Toolbar, ClockEditFormat, "Edit Clock Format", "edit Clock Format") , editformat_cmd); - - themeReconfigured(); + updateTime(); } ClockTool::~ClockTool() {

@@ -226,29 +206,29 @@ }

void ClockTool::setTimeFormat(const std::string &format) { *m_timeformat = format; - themeReconfigured(); + updateTime(); } void ClockTool::themeReconfigured() { - updateTime(); // + 2 to make the entire text fit inside // we only replace numbers with zeros because everything else should be // relatively static. If we replace all text with zeros then widths of + // proportional fonts with some strftime formats will be considerably off. - FbTk::FbString text(m_button.text().logical()); + const FbTk::FbString& t = m_button.text().logical(); + size_t s = t.size() + 2; + FbTk::FbString text(s, '0'); - int textlen = text.size(); - for (int i=0; i < textlen; ++i) { - if (isdigit(text[i])) // don't bother replacing zeros - text[i] = '0'; + for (size_t i = 0; i < (s - 2); ++i) { + if (!isdigit(t[i])) + text[i] = t[i]; } - text.append("00"); // pad unsigned int new_width = m_button.width(); unsigned int new_height = m_button.height(); translateSize(orientation(), new_width, new_height); - new_width = m_theme->font().textWidth(text.c_str(), text.size()); + new_width = m_theme->font().textWidth(text.c_str(), s); translateSize(orientation(), new_width, new_height); if (new_width != m_button.width() || new_height != m_button.height()) { resize(new_width, new_height);

@@ -271,41 +251,44 @@ }

void ClockTool::updateTime() { - m_timer.setTimeout(calcNextTimeout(*m_timeformat)); + time_t t = time(NULL); - time_t the_time = time(NULL); - if (the_time != -1) { - char time_string[255]; - int time_string_len; - struct tm *time_type = localtime(&the_time); - if (time_type == 0) - return; + if (t != -1) { + + char buf[255]; + int len; + struct tm* type; + FbTk::FbString text; + + if ((type = localtime(&t)) == 0) + goto restart_timer; #ifdef HAVE_STRFTIME - time_string_len = strftime(time_string, 255, m_timeformat->c_str(), time_type); - if( time_string_len == 0) - return; - std::string text = m_stringconvertor.recode(time_string); - if (m_button.text().logical() == text) - return; - m_button.setText(text); + len = strftime(buf, sizeof(buf), m_timeformat->c_str(), type); + if (len == 0) + goto restart_timer; - unsigned int new_width = m_theme->font().textWidth(time_string, time_string_len) + 2; - if (new_width > m_button.width()) { - resize(new_width, m_button.height()); - resizeSig().emit(); - } + text = m_stringconvertor.recode(buf); + if (m_button.text().logical() == text) + goto restart_timer; + #else // dont have strftime so we have to set it to hour:minut // sprintf(time_string, "%d:%d", ); #endif // HAVE_STRFTIME + + m_button.setText(text); + themeReconfigured(); } + +restart_timer: + m_timer.setTimeout(calcNextTimeout()); + m_timer.start(); } // Just change things that affect the size void ClockTool::updateSizing() { m_button.setBorderWidth(m_theme->border().width()); - // resizes if new timeformat themeReconfigured(); }
M src/ClockTool.hhsrc/ClockTool.hh

@@ -72,18 +72,16 @@ void renderTheme(int alpha);

void reRender(); void updateSizing(); - FbTk::TextButton m_button; - - const FbTk::ThemeProxy<ToolTheme> &m_theme; - BScreen &m_screen; - Pixmap m_pixmap; - FbTk::Timer m_timer; - - FbTk::Resource<std::string> m_timeformat; + FbTk::TextButton m_button; - FbTk::StringConvertor m_stringconvertor; + const FbTk::ThemeProxy<ToolTheme>& m_theme; + BScreen& m_screen; + Pixmap m_pixmap; + FbTk::Timer m_timer; - FbTk::SignalTracker m_tracker; + FbTk::Resource<std::string> m_timeformat; + FbTk::StringConvertor m_stringconvertor; + FbTk::SignalTracker m_tracker; }; #endif // CLOCKTOOL_HH