From 1dd4b27d30a9a96032dffa3946f478ce4cba85b9 Mon Sep 17 00:00:00 2001 From: fluxgen <fluxgen> Date: Fri, 19 Dec 2003 14:58:48 +0000 Subject: timedRender so we can remove flicker while changing current client in window --- src/IconbarTool.cc | 57 ++++++++++++++++++++++++++++++++++++++++++++---------- src/IconbarTool.hh | 8 ++++++-- 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/src/IconbarTool.cc b/src/IconbarTool.cc index 1f6d491..8602a2b 100644 --- a/src/IconbarTool.cc +++ b/src/IconbarTool.cc @@ -20,7 +20,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: IconbarTool.cc,v 1.23 2003/12/18 18:03:21 fluxgen Exp $ +// $Id: IconbarTool.cc,v 1.24 2003/12/19 14:58:48 fluxgen Exp $ #include "IconbarTool.hh" @@ -33,6 +33,7 @@ #include "FbMenu.hh" #include "BoolMenuItem.hh" #include "CommandParser.hh" +#include "WinClient.hh" #include "FbTk/Menu.hh" #include "FbTk/MenuItem.hh" @@ -272,6 +273,14 @@ IconbarTool::IconbarTool(const FbTk::FbWindow &parent, IconbarTheme &theme, BScr screen.clientListSig().attach(this); screen.iconListSig().attach(this); screen.currentWorkspaceSig().attach(this); + // setup focus timer + FbTk::RefCount<FbTk::Command> timer_cmd(new FbTk::SimpleCommand<IconbarTool>(*this, &IconbarTool::timedRender)); + timeval to; + to.tv_sec = 0; + to.tv_usec = 1; // so it updates next event round + m_focus_timer.setCommand(timer_cmd); + m_focus_timer.setTimeout(to); + m_focus_timer.fireOnce(true); update(0); } @@ -392,7 +401,10 @@ void IconbarTool::update(FbTk::Subject *subj) { // we handle everything except die signal here FluxboxWindow::WinSubject *winsubj = static_cast<FluxboxWindow::WinSubject *>(subj); if (subj == &(winsubj->win().focusSig())) { - renderWindow(winsubj->win()); + // start focus timer, so we can update without flicker + m_focus_timer.start(); + + //renderWindow(winsubj->win()); return; } else if (subj == &(winsubj->win().workspaceSig())) { // we can ignore this signal if we're in ALLWINDOWS mode @@ -441,9 +453,9 @@ void IconbarTool::update(FbTk::Subject *subj) { mode() != ALLWINDOWS && mode() != ICONS) { remove_all = true; // remove and readd all windows }/* else if (&m_screen.iconListSig() == screen_subj && - (mode() == ALLWINDOWS || mode() == ICONS || mode() == WORKSPACE)) { + (mode() == ALLWINDOWS || mode() == ICONS || mode() == WORKSPACE)) { remove_all = true; - }*/ + }*/ } // lock graphic update @@ -477,19 +489,23 @@ void IconbarTool::update(FbTk::Subject *subj) { } -void IconbarTool::renderWindow(FluxboxWindow &win) { - +IconButton *IconbarTool::findButton(FluxboxWindow &win) { + IconList::iterator icon_it = m_icon_list.begin(); IconList::iterator icon_it_end = m_icon_list.end(); for (; icon_it != icon_it_end; ++icon_it) { if (&(*icon_it)->win() == &win) - break; + return *icon_it; } - if (icon_it == m_icon_list.end()) - return; + return 0; +} - renderButton(*(*icon_it)); +void IconbarTool::renderWindow(FluxboxWindow &win) { + IconButton *button = findButton(win); + if (button == 0) + return; + renderButton(*button); } void IconbarTool::renderTheme() { @@ -546,6 +562,7 @@ void IconbarTool::renderButton(IconButton &button) { button.setPixmap(*m_rc_use_pixmap); if (button.win().isFocused()) { // focused texture + m_icon_container.setSelected(m_icon_container.find(&button)); button.setGC(m_theme.focusedText().textGC()); button.setFont(m_theme.focusedText().font()); button.setJustify(m_theme.focusedText().justify()); @@ -559,6 +576,9 @@ void IconbarTool::renderButton(IconButton &button) { button.setBorderColor(m_theme.focusedBorder().color()); } else { // unfocused + if (m_icon_container.selected() == &button) + m_icon_container.setSelected(-1); + button.setGC(m_theme.unfocusedText().textGC()); button.setFont(m_theme.unfocusedText().font()); button.setJustify(m_theme.unfocusedText().justify()); @@ -696,4 +716,21 @@ void IconbarTool::addList(std::list<FluxboxWindow *> &winlist) { addWindow(**it); } +void IconbarTool::timedRender() { + WinClient *client = Fluxbox::instance()->getFocusedWindow(); + if (client == 0 || client->fbwindow() == 0) + return; + + IconButton *button = findButton(*client->fbwindow()); + IconButton *current_button = static_cast<IconButton *>(m_icon_container.selected()); + // if old window is the same as the new focused window then ignore this render + // else render old client and new client + if (button == current_button) + return; + if (button != 0) + renderButton(*button); + if (current_button != 0) + renderButton(*current_button); + +} diff --git a/src/IconbarTool.hh b/src/IconbarTool.hh index d60d14b..0f2574e 100644 --- a/src/IconbarTool.hh +++ b/src/IconbarTool.hh @@ -20,7 +20,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: IconbarTool.hh,v 1.11 2003/12/12 14:36:22 fluxgen Exp $ +// $Id: IconbarTool.hh,v 1.12 2003/12/19 14:57:44 fluxgen Exp $ #ifndef ICONBARTOOL_HH #define ICONBARTOOL_HH @@ -76,6 +76,8 @@ public: Mode mode() const { return *m_rc_mode; } Container::Alignment alignment() const { return m_icon_container.alignment(); } private: + /// @return button associated with window + IconButton *findButton(FluxboxWindow &win); /// render single button that holds win void renderWindow(FluxboxWindow &win); @@ -97,6 +99,8 @@ private: void updateAllWindows(); /// add a list of windows void addList(std::list<FluxboxWindow *> &winlist); + /// so we can update current window without flicker + void timedRender(); BScreen &m_screen; Container m_icon_container; @@ -111,7 +115,7 @@ private: FbTk::Resource<Container::Alignment> m_rc_alignment; ///< alignment of buttons FbTk::Resource<int> m_rc_client_width; ///< size of client button in LEFT/RIGHT mode FbTk::Resource<bool> m_rc_use_pixmap; ///< if iconbar should use win pixmap or not - + FbTk::Timer m_focus_timer; ///< so we can update current window without flicker while changing attached clients FbMenu m_menu; }; -- cgit v0.11.2