diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | src/FbTk/Menu.cc | 32 | ||||
-rw-r--r-- | src/FbTk/Menu.hh | 2 | ||||
-rw-r--r-- | src/FocusControl.cc | 22 |
4 files changed, 46 insertions, 16 deletions
@@ -1,5 +1,11 @@ | |||
1 | (Format: Year/Month/Day) | 1 | (Format: Year/Month/Day) |
2 | Changes for 1.0rc3: | 2 | Changes for 1.0rc3: |
3 | *07/01/21: | ||
4 | * Several fixes for menu behavior (Mark) | ||
5 | - always give focus to the menu with the highlighted item | ||
6 | - revert focus to menu when no other windows will take it | ||
7 | - don't reopen closed submenus when moving the menu | ||
8 | FocusControl.cc FbTk/Menu.cc/hh | ||
3 | *07/01/20: | 9 | *07/01/20: |
4 | * Make sure styles don't change the lastwallpaper in fbsetbg (Mark) | 10 | * Make sure styles don't change the lastwallpaper in fbsetbg (Mark) |
5 | RootTheme.cc | 11 | RootTheme.cc |
diff --git a/src/FbTk/Menu.cc b/src/FbTk/Menu.cc index e7fc6d8..5ee329b 100644 --- a/src/FbTk/Menu.cc +++ b/src/FbTk/Menu.cc | |||
@@ -73,7 +73,7 @@ using std::endl; | |||
73 | 73 | ||
74 | namespace FbTk { | 74 | namespace FbTk { |
75 | 75 | ||
76 | static Menu *shown = 0; | 76 | Menu *Menu::shown = 0; |
77 | 77 | ||
78 | Menu *Menu::s_focused = 0; | 78 | Menu *Menu::s_focused = 0; |
79 | 79 | ||
@@ -365,12 +365,14 @@ void Menu::enterSubmenu() { | |||
365 | } | 365 | } |
366 | 366 | ||
367 | void Menu::enterParent() { | 367 | void Menu::enterParent() { |
368 | if (!validIndex(m_which_press) || parent() == 0) | 368 | if (parent() == 0) |
369 | return; | 369 | return; |
370 | 370 | ||
371 | Menu *submenu = menuitems[m_which_press]->submenu(); | 371 | if (validIndex(m_which_press)) { |
372 | if (submenu) | 372 | Menu *submenu = menuitems[m_which_press]->submenu(); |
373 | submenu->internal_hide(); | 373 | if (submenu) |
374 | submenu->internal_hide(); | ||
375 | } | ||
374 | 376 | ||
375 | m_active_index = -1; | 377 | m_active_index = -1; |
376 | //clearItem(m_which_press); | 378 | //clearItem(m_which_press); |
@@ -570,6 +572,13 @@ void Menu::hide() { | |||
570 | } | 572 | } |
571 | 573 | ||
572 | void Menu::grabInputFocus() { | 574 | void Menu::grabInputFocus() { |
575 | // if there's a submenu open, focus it instead | ||
576 | if (validIndex(m_which_sub) && | ||
577 | menuitems[m_which_sub]->submenu()->isVisible()) { | ||
578 | menuitems[m_which_sub]->submenu()->grabInputFocus(); | ||
579 | return; | ||
580 | } | ||
581 | |||
573 | s_focused = this; | 582 | s_focused = this; |
574 | 583 | ||
575 | // grab input focus | 584 | // grab input focus |
@@ -632,7 +641,8 @@ void Menu::move(int x, int y) { | |||
632 | if (alpha() < 255) | 641 | if (alpha() < 255) |
633 | clearWindow(); | 642 | clearWindow(); |
634 | 643 | ||
635 | if (m_which_sub != -1) | 644 | if (validIndex(m_which_sub) && |
645 | menuitems[m_which_sub]->submenu()->isVisible()) | ||
636 | drawSubmenu(m_which_sub); | 646 | drawSubmenu(m_which_sub); |
637 | } | 647 | } |
638 | 648 | ||
@@ -846,6 +856,10 @@ void Menu::handleEvent(XEvent &event) { | |||
846 | } else if (event.type == FocusIn) { | 856 | } else if (event.type == FocusIn) { |
847 | if (s_focused != this) | 857 | if (s_focused != this) |
848 | s_focused = this; | 858 | s_focused = this; |
859 | // if there's a submenu open, focus it instead | ||
860 | if (validIndex(m_which_sub) && | ||
861 | menuitems[m_which_sub]->submenu()->isVisible()) | ||
862 | menuitems[m_which_sub]->submenu()->grabInputFocus(); | ||
849 | } | 863 | } |
850 | } | 864 | } |
851 | 865 | ||
@@ -881,7 +895,8 @@ void Menu::buttonReleaseEvent(XButtonEvent &re) { | |||
881 | if (m_moving) { | 895 | if (m_moving) { |
882 | m_moving = false; | 896 | m_moving = false; |
883 | 897 | ||
884 | if (m_which_sub != -1) | 898 | if (validIndex(m_which_sub) && |
899 | menuitems[m_which_sub]->submenu()->isVisible()) | ||
885 | drawSubmenu(m_which_sub); | 900 | drawSubmenu(m_which_sub); |
886 | 901 | ||
887 | if (alpha() < 255) { | 902 | if (alpha() < 255) { |
@@ -933,7 +948,8 @@ void Menu::motionNotifyEvent(XMotionEvent &me) { | |||
933 | // clear current highlighted item | 948 | // clear current highlighted item |
934 | clearItem(m_active_index); | 949 | clearItem(m_active_index); |
935 | 950 | ||
936 | if (m_which_sub >= 0) | 951 | if (validIndex(m_which_sub) && |
952 | menuitems[m_which_sub]->submenu()->isVisible()) | ||
937 | drawSubmenu(m_which_sub); | 953 | drawSubmenu(m_which_sub); |
938 | } else { | 954 | } else { |
939 | // we dont call ::move here 'cause we dont want to update transparency | 955 | // we dont call ::move here 'cause we dont want to update transparency |
diff --git a/src/FbTk/Menu.hh b/src/FbTk/Menu.hh index 28eb70a..94a1e6f 100644 --- a/src/FbTk/Menu.hh +++ b/src/FbTk/Menu.hh | |||
@@ -160,6 +160,7 @@ public: | |||
160 | bool isItemSelectable(unsigned int index) const; | 160 | bool isItemSelectable(unsigned int index) const; |
161 | inline const MenuTheme &theme() const { return m_theme; } | 161 | inline const MenuTheme &theme() const { return m_theme; } |
162 | inline unsigned char alpha() const { return theme().alpha(); } | 162 | inline unsigned char alpha() const { return theme().alpha(); } |
163 | inline static Menu *shownMenu() { return shown; } | ||
163 | inline static Menu *focused() { return s_focused; } | 164 | inline static Menu *focused() { return s_focused; } |
164 | /// @return menuitem at index | 165 | /// @return menuitem at index |
165 | inline const MenuItem *find(unsigned int index) const { return menuitems[index]; } | 166 | inline const MenuItem *find(unsigned int index) const { return menuitems[index]; } |
@@ -235,6 +236,7 @@ private: | |||
235 | int m_active_index; ///< current highlighted index | 236 | int m_active_index; ///< current highlighted index |
236 | 237 | ||
237 | Drawable m_root_pm; | 238 | Drawable m_root_pm; |
239 | static Menu *shown; ///< used for determining if there's a menu open at all | ||
238 | static Menu *s_focused; ///< holds current input focused menu, so one can determine if a menu is focused | 240 | static Menu *s_focused; ///< holds current input focused menu, so one can determine if a menu is focused |
239 | bool m_need_update; | 241 | bool m_need_update; |
240 | Timer m_submenu_timer; | 242 | Timer m_submenu_timer; |
diff --git a/src/FocusControl.cc b/src/FocusControl.cc index 9c82e3e..61d6e87 100644 --- a/src/FocusControl.cc +++ b/src/FocusControl.cc | |||
@@ -405,14 +405,20 @@ void FocusControl::revertFocus(BScreen &screen) { | |||
405 | // if setting focus fails, or isn't possible, fallback correctly | 405 | // if setting focus fails, or isn't possible, fallback correctly |
406 | if (!(next_focus && next_focus->focus())) { | 406 | if (!(next_focus && next_focus->focus())) { |
407 | setFocusedWindow(0); // so we don't get dangling m_focused_window pointer | 407 | setFocusedWindow(0); // so we don't get dangling m_focused_window pointer |
408 | switch (screen.focusControl().focusModel()) { | 408 | // if there's a menu open, focus it |
409 | case FocusControl::MOUSEFOCUS: | 409 | if (FbTk::Menu::shownMenu()) |
410 | XSetInputFocus(screen.rootWindow().display(), | 410 | FbTk::Menu::shownMenu()->grabInputFocus(); |
411 | PointerRoot, None, CurrentTime); | 411 | else { |
412 | break; | 412 | switch (screen.focusControl().focusModel()) { |
413 | case FocusControl::CLICKFOCUS: | 413 | case FocusControl::MOUSEFOCUS: |
414 | screen.rootWindow().setInputFocus(RevertToPointerRoot, CurrentTime); | 414 | XSetInputFocus(screen.rootWindow().display(), |
415 | break; | 415 | PointerRoot, None, CurrentTime); |
416 | break; | ||
417 | case FocusControl::CLICKFOCUS: | ||
418 | screen.rootWindow().setInputFocus(RevertToPointerRoot, | ||
419 | CurrentTime); | ||
420 | break; | ||
421 | } | ||
416 | } | 422 | } |
417 | } | 423 | } |
418 | 424 | ||