various changes to menu behavior
markt markt
4 files changed,
46 insertions(+),
16 deletions(-)
M
ChangeLog
→
ChangeLog
@@ -1,5 +1,11 @@
(Format: Year/Month/Day) Changes for 1.0rc3: +*07/01/21: + * Several fixes for menu behavior (Mark) + - always give focus to the menu with the highlighted item + - revert focus to menu when no other windows will take it + - don't reopen closed submenus when moving the menu + FocusControl.cc FbTk/Menu.cc/hh *07/01/20: * Make sure styles don't change the lastwallpaper in fbsetbg (Mark) RootTheme.cc
M
src/FbTk/Menu.cc
→
src/FbTk/Menu.cc
@@ -73,7 +73,7 @@ #endif // DEBUG
namespace FbTk { -static Menu *shown = 0; +Menu *Menu::shown = 0; Menu *Menu::s_focused = 0;@@ -365,12 +365,14 @@ submenu->nextItem();
} void Menu::enterParent() { - if (!validIndex(m_which_press) || parent() == 0) + if (parent() == 0) return; - Menu *submenu = menuitems[m_which_press]->submenu(); - if (submenu) - submenu->internal_hide(); + if (validIndex(m_which_press)) { + Menu *submenu = menuitems[m_which_press]->submenu(); + if (submenu) + submenu->internal_hide(); + } m_active_index = -1; //clearItem(m_which_press);@@ -570,6 +572,13 @@
} void Menu::grabInputFocus() { + // if there's a submenu open, focus it instead + if (validIndex(m_which_sub) && + menuitems[m_which_sub]->submenu()->isVisible()) { + menuitems[m_which_sub]->submenu()->grabInputFocus(); + return; + } + s_focused = this; // grab input focus@@ -632,7 +641,8 @@
if (alpha() < 255) clearWindow(); - if (m_which_sub != -1) + if (validIndex(m_which_sub) && + menuitems[m_which_sub]->submenu()->isVisible()) drawSubmenu(m_which_sub); }@@ -846,6 +856,10 @@ s_focused = 0;
} else if (event.type == FocusIn) { if (s_focused != this) s_focused = this; + // if there's a submenu open, focus it instead + if (validIndex(m_which_sub) && + menuitems[m_which_sub]->submenu()->isVisible()) + menuitems[m_which_sub]->submenu()->grabInputFocus(); } }@@ -881,7 +895,8 @@ if (re.window == menu.title) {
if (m_moving) { m_moving = false; - if (m_which_sub != -1) + if (validIndex(m_which_sub) && + menuitems[m_which_sub]->submenu()->isVisible()) drawSubmenu(m_which_sub); if (alpha() < 255) {@@ -933,7 +948,8 @@ m_moving = m_torn = true;
// clear current highlighted item clearItem(m_active_index); - if (m_which_sub >= 0) + if (validIndex(m_which_sub) && + menuitems[m_which_sub]->submenu()->isVisible()) drawSubmenu(m_which_sub); } else { // we dont call ::move here 'cause we dont want to update transparency
M
src/FbTk/Menu.hh
→
src/FbTk/Menu.hh
@@ -160,6 +160,7 @@ bool isItemEnabled(unsigned int index) const;
bool isItemSelectable(unsigned int index) const; inline const MenuTheme &theme() const { return m_theme; } inline unsigned char alpha() const { return theme().alpha(); } + inline static Menu *shownMenu() { return shown; } inline static Menu *focused() { return s_focused; } /// @return menuitem at index inline const MenuItem *find(unsigned int index) const { return menuitems[index]; }@@ -235,6 +236,7 @@
int m_active_index; ///< current highlighted index Drawable m_root_pm; + static Menu *shown; ///< used for determining if there's a menu open at all static Menu *s_focused; ///< holds current input focused menu, so one can determine if a menu is focused bool m_need_update; Timer m_submenu_timer;
M
src/FocusControl.cc
→
src/FocusControl.cc
@@ -405,14 +405,20 @@
// if setting focus fails, or isn't possible, fallback correctly if (!(next_focus && next_focus->focus())) { setFocusedWindow(0); // so we don't get dangling m_focused_window pointer - switch (screen.focusControl().focusModel()) { - case FocusControl::MOUSEFOCUS: - XSetInputFocus(screen.rootWindow().display(), - PointerRoot, None, CurrentTime); - break; - case FocusControl::CLICKFOCUS: - screen.rootWindow().setInputFocus(RevertToPointerRoot, CurrentTime); - break; + // if there's a menu open, focus it + if (FbTk::Menu::shownMenu()) + FbTk::Menu::shownMenu()->grabInputFocus(); + else { + switch (screen.focusControl().focusModel()) { + case FocusControl::MOUSEFOCUS: + XSetInputFocus(screen.rootWindow().display(), + PointerRoot, None, CurrentTime); + break; + case FocusControl::CLICKFOCUS: + screen.rootWindow().setInputFocus(RevertToPointerRoot, + CurrentTime); + break; + } } }