all repos — fluxbox @ ec9cd21ddaf53b836e9a92d5c329feb18f12ba22

custom fork of the fluxbox windowmanager

some code simplification and bug fixes
mainly, using a non-zero menuDelayClose allowed you to have multiple submenus open
markt markt
commit

ec9cd21ddaf53b836e9a92d5c329feb18f12ba22

parent

d07fd13f3b553aecab22e86866f1efb9b4df5cd6

3 files changed, 85 insertions(+), 148 deletions(-)

jump to
M ChangeLogChangeLog

@@ -1,5 +1,8 @@

(Format: Year/Month/Day) Changes for 1.0rc3: +*07/02/28: + * Fixed some strange menu behaviors (Mark) + FbTk/Menu.cc/hh *07/02/27: * Respect external tabs in ArrangeWindows (thanks to Tomas Janousek <tomi at nomi dot cz>
M src/FbTk/Menu.ccsrc/FbTk/Menu.cc

@@ -114,9 +114,7 @@

menu.x_move = menu.y_move = 0; - m_which_sub = - m_which_press = - m_which_sbl = -1; + m_which_sub = -1; menu.frame_pixmap = menu.title_pixmap =

@@ -273,94 +271,91 @@ void Menu::lower() {

menu.window.lower(); } -void Menu::nextItem() { +void Menu::nextItem(int failsafe) { if (menuitems.empty()) return; - int old_which_press = m_which_press; - m_active_index = -1; - if (validIndex(old_which_press) && - menuitems[old_which_press] != 0) { - if (menuitems[old_which_press]->submenu()) { + if (failsafe == -1) + failsafe = m_active_index; + + int old_active_index = m_active_index; + m_active_index += 1; + if (!validIndex(m_active_index)) + m_active_index = 0; + + if (validIndex(old_active_index) && + menuitems[old_active_index] != 0) { + if (menuitems[old_active_index]->submenu()) { // we need to do this explicitly on the menu.window // since it might hide the parent if we use Menu::hide - menuitems[old_which_press]->submenu()->internal_hide(); + menuitems[old_active_index]->submenu()->internal_hide(); } - clearItem(old_which_press); + clearItem(old_active_index); } - // restore old in case we changed m_which_press - m_which_press = old_which_press + 1; - if (!validIndex(m_which_press)) - m_which_press = 0; - - - if (menuitems[m_which_press] == 0) { + if (menuitems[m_active_index] == 0) { m_active_index = -1; return; } - if (!isItemSelectable(m_which_press)) { - nextItem(); + if (!isItemSelectable(m_active_index) && m_active_index != failsafe) { + nextItem(failsafe); return; } - m_active_index = m_which_press; - - clearItem(m_which_press); + clearItem(m_active_index); } -void Menu::prevItem() { +void Menu::prevItem(int failsafe) { if (menuitems.empty()) return; - int old_which_press = m_which_press; - m_active_index = -1; - if (validIndex(old_which_press)) { - if (menuitems[old_which_press]->submenu()) { + if (failsafe == -1) + failsafe = m_active_index; + + int old_active_index = m_active_index; + m_active_index -= 1; + if (!validIndex(m_active_index)) + m_active_index = menuitems.size() - 1; + + if (validIndex(old_active_index)) { + if (menuitems[old_active_index]->submenu()) { // we need to do this explicitly on the menu.window // since it might hide the parent if we use Menu::hide - menuitems[old_which_press]->submenu()->internal_hide(); + menuitems[old_active_index]->submenu()->internal_hide(); } - clearItem(old_which_press); + clearItem(old_active_index); } - // restore old in case we changed m_which_press - m_which_press = old_which_press - 1; - if (!validIndex(m_which_press)) - m_which_press = menuitems.size() - 1; - - if (menuitems[m_which_press] == 0) { + if (menuitems[m_active_index] == 0) { m_active_index = -1; return; } - if (!isItemSelectable(m_which_press)) { - prevItem(); + if (!isItemSelectable(m_active_index) && m_active_index != failsafe) { + prevItem(failsafe); return; } - m_active_index = m_which_press; - - clearItem(m_which_press); + clearItem(m_active_index); } void Menu::enterSubmenu() { - if (!validIndex(m_which_press)) + if (!validIndex(m_active_index)) return; - Menu *submenu = menuitems[m_which_press]->submenu(); + Menu *submenu = menuitems[m_active_index]->submenu(); if (submenu == 0) return; if (submenu->menuitems.size() == 0) return; - drawSubmenu(m_which_press); + drawSubmenu(m_active_index); submenu->grabInputFocus(); - submenu->m_which_press = -1; // so we land on 0 after nextItem() + submenu->m_active_index = -1; // so we land on 0 after nextItem() submenu->nextItem(); }

@@ -368,15 +363,13 @@ void Menu::enterParent() {

if (parent() == 0) return; - if (validIndex(m_which_press)) { - Menu *submenu = menuitems[m_which_press]->submenu(); + if (validIndex(m_active_index)) { + Menu *submenu = menuitems[m_active_index]->submenu(); if (submenu) submenu->internal_hide(); } m_active_index = -1; - //clearItem(m_which_press); - m_which_press = -1; // dont select any in this // hide self m_visible = false; menu.window.hide();

@@ -619,7 +612,7 @@ if (shown && shown->menu.window == menu.window)

shown = (Menu *) 0; m_torn = m_visible = false; - m_which_sub = m_which_press = m_which_sub = -1; + m_which_sub = -1; menu.window.hide(); }

@@ -751,18 +744,6 @@ m_which_sub = -1;

} -#ifdef NOT_USED -bool Menu::hasSubmenu(unsigned int index) const { - if (index >= menuitems.size()) //boundary check - return false; - - if (!menuitems[index]->submenu()) //has submenu? - return false; - - return true; -} -#endif // NOT_USED - int Menu::drawItem(FbDrawable &drawable, unsigned int index, bool highlight, bool exclusive_drawable) {

@@ -872,9 +853,6 @@ int sbl = (be.x / menu.item_w), i = (be.y / theme().itemHeight());

int w = (sbl * menu.persub) + i; if (validIndex(w) && isItemSelectable(static_cast<unsigned int>(w))) { - m_which_press = i; - m_which_sbl = sbl; - MenuItem *item = menuitems[w]; if (item->submenu()) {

@@ -913,19 +891,19 @@ } else if (re.window == menu.frame) {

int sbl = (re.x / menu.item_w), i = (re.y / theme().itemHeight()), ix = sbl * menu.item_w, iy = i * theme().itemHeight(), - w = (sbl * menu.persub) + i, - p = (m_which_sbl * menu.persub) + m_which_press; + w = (sbl * menu.persub) + i; if (validIndex(w) && isItemSelectable(static_cast<unsigned int>(w))) { - if (p == w && isItemEnabled(w)) { - if (re.x > ix && re.x < (signed) (ix + menu.item_w) && - re.y > iy && re.y < (signed) (iy + theme().itemHeight())) { - menuitems[w]->click(re.button, re.time); - itemSelected(re.button, w); - } + if (m_active_index == w && isItemEnabled(w) && + re.x > ix && re.x < (signed) (ix + menu.item_w) && + re.y > iy && re.y < (signed) (iy + theme().itemHeight())) { + menuitems[w]->click(re.button, re.time); } - clearItem(p); + int old = m_active_index; + m_active_index = w; + clearItem(old); + clearItem(w); } } }

@@ -938,11 +916,6 @@ stopHide();

if (! m_moving) { // if not m_moving: start m_moving operation - if (m_parent && (! m_torn)) { - m_parent->m_which_sub = -1; - m_parent->clearItem(m_parent->m_which_sub); // clear - } - m_moving = m_torn = true; // clear current highlighted item clearItem(m_active_index);

@@ -962,76 +935,44 @@ int sbl = (me.x / menu.item_w),

i = (me.y / theme().itemHeight()), w = (sbl * menu.persub) + i; - if (w == m_active_index) + if (w == m_active_index || !validIndex(w)) return; // if another menu is focused, change focus to this one, so arrow keys // work as expected if (s_focused != this && s_focused != 0) grabInputFocus(); - - if (validIndex(m_active_index) && w != m_active_index) { - int old_active_index = m_active_index; - m_active_index = -1; - MenuItem *item = menuitems[old_active_index]; - - if (item != 0) { - - clearItem(old_active_index); - - if (item->submenu()) { - if (item->submenu()->isVisible() && - !item->submenu()->isTorn()) { - // setup hide timer for submenu - item->submenu()->startHide(); - m_which_sub = -1; - } - } - - } - - } - - - m_which_press = i; - m_which_sbl = sbl; - - m_active_index = -1; - - if (!validIndex(w)) - return; - MenuItem *itmp = menuitems[w]; - - m_active_index = w; - if (itmp == 0) return; - if (itmp->submenu()) { - // if submenu, - // draw item highlighted and - // start submenu open delay - + if (itmp->isEnabled()) { + int old = m_active_index; + m_active_index = w; clearItem(w); + clearItem(old); - if (theme().menuMode() == MenuTheme::DELAY_OPEN) { - // setup show menu timer - timeval timeout; - timeout.tv_sec = 0; - timeout.tv_usec = theme().delayOpen() * 1000; // transformed to usec - m_submenu_timer.setTimeout(timeout); - m_submenu_timer.start(); + MenuItem *item = validIndex(m_which_sub) ? menuitems[m_which_sub] : 0; + if (item != 0 && item->submenu() && item->submenu()->isVisible() && + !item->submenu()->isTorn()) { + // setup hide timer for submenu + item->submenu()->startHide(); } + } + + if (itmp->submenu() && theme().menuMode() == MenuTheme::DELAY_OPEN) { + // start submenu open delay + timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = theme().delayOpen() * 1000; // transformed to usec + m_submenu_timer.setTimeout(timeout); + m_submenu_timer.start(); } else if (isItemSelectable(w)){ // else normal menu item // draw highlighted m_submenu_timer.stop(); - if (itmp->isEnabled()) { - clearItem(w); - } } }

@@ -1099,13 +1040,12 @@ hide();

break; case XK_Return: // send fake button 1 click - if (validIndex(m_which_press) && - isItemEnabled(m_which_press)) { + if (validIndex(m_active_index) && + isItemEnabled(m_active_index)) { if (event.state & ShiftMask) - menuitems[m_which_press]->click(3, event.time); + menuitems[m_active_index]->click(3, event.time); else - menuitems[m_which_press]->click(1, event.time); - itemSelected(1, m_which_press); + menuitems[m_active_index]->click(1, event.time); m_need_update = true; updateMenu(); }

@@ -1143,12 +1083,9 @@

void Menu::openSubmenu() { - if (!isVisible() || ! validIndex(m_which_press) || - ! validIndex(m_which_sbl)) - return; - - int item = m_which_sbl * menu.persub + m_which_press; - if (!validIndex(item) || !menuitems[item]->isEnabled()) + int item = m_active_index; + if (!isVisible() || !validIndex(item) || !menuitems[item]->isEnabled() || + s_focused != this && s_focused && s_focused->isVisible()) return; clearItem(item);
M src/FbTk/Menu.hhsrc/FbTk/Menu.hh

@@ -88,9 +88,9 @@ virtual void raise();

/// lower this window virtual void lower(); /// select next item - void nextItem(); + void nextItem(int failsafe = -1); /// select previous item - void prevItem(); + void prevItem(int failsafe = -1); void enterSubmenu(); void enterParent();

@@ -152,9 +152,7 @@ inline unsigned int width() const { return menu.window.width(); }

inline unsigned int height() const { return menu.window.height(); } inline size_t numberOfItems() const { return menuitems.size(); } inline int currentSubmenu() const { return m_which_sub; } -#ifdef NOT_USED - bool hasSubmenu(unsigned int index) const; -#endif + bool isItemSelected(unsigned int index) const; bool isItemEnabled(unsigned int index) const; bool isItemSelectable(unsigned int index) const;

@@ -184,7 +182,6 @@ else

titleWindow().raise(); } - virtual void itemSelected(int button, unsigned int index) { } // renders item onto pm int drawItem(FbDrawable &pm, unsigned int index, bool highlight = false,

@@ -220,7 +217,7 @@ bool m_torn; ///< torn from parent

bool m_internal_menu; ///< whether we should destroy this menu or if it's managed somewhere else bool m_title_vis; ///< title visibility - int m_which_sub, m_which_press, m_which_sbl; + int m_which_sub; Alignment m_alignment; struct _menu {