various changes to menu behavior

This commit is contained in:
markt 2007-01-21 18:43:22 +00:00
parent 5503545d8f
commit feb56381d7
4 changed files with 46 additions and 16 deletions

View file

@ -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

View file

@ -73,7 +73,7 @@ using std::endl;
namespace FbTk {
static Menu *shown = 0;
Menu *Menu::shown = 0;
Menu *Menu::s_focused = 0;
@ -365,12 +365,14 @@ void Menu::enterSubmenu() {
}
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::hide() {
}
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 @@ void Menu::move(int x, int y) {
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 @@ void Menu::handleEvent(XEvent &event) {
} 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 @@ void Menu::buttonReleaseEvent(XButtonEvent &re) {
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 @@ void Menu::motionNotifyEvent(XMotionEvent &me) {
// 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

View file

@ -160,6 +160,7 @@ public:
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 @@ private:
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;

View file

@ -405,14 +405,20 @@ void FocusControl::revertFocus(BScreen &screen) {
// 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;
}
}
}