Fix bug triggering global keyboard shortcuts when a combobox popup is open

When a combobox popup is open, it creates a new non-foreground top window
(which is sibling of the window where the combobox widget is). When the
popup receives a key press, and it doesn't use it, the key is passed to
its parent (a ui::Manager), and then the latter has to process it.

Before this commit, CustomizedGuiManager::onProcessMessage() was
filtering shortcuts for foreground window, but it was working only
when the key was pressed in the foreground window itself (not when a
combination of foreground and background windows were open). Now the
filter is done in Manager::onProcessMessage() (which returns true,
i.e. key was used, for every pressed key when a foreground window
is found in its children hierarchy).
This commit is contained in:
David Capello 2015-05-04 11:25:42 -03:00
parent ac8387a408
commit 883629b563
4 changed files with 27 additions and 24 deletions

View File

@ -402,8 +402,6 @@ bool CustomizedGuiManager::onProcessMessage(Message* msg)
break;
case kKeyDownMessage: {
Window* toplevel_window = getTopWindow();
#ifdef _DEBUG
// Left Shift+Ctrl+Q generates a crash (useful to test the anticrash feature)
if (msg->ctrlPressed() &&
@ -414,13 +412,11 @@ bool CustomizedGuiManager::onProcessMessage(Message* msg)
}
#endif
// If there is a foreground window as top level...
if (toplevel_window &&
toplevel_window != App::instance()->getMainWindow() &&
toplevel_window->isForeground()) {
// We just do not process keyboard shortcuts for menus and tools
break;
}
// Call base impl to check if there is a foreground window as
// top level that needs keys. (In this way we just do not
// process keyboard shortcuts for menus and tools).
if (Manager::onProcessMessage(msg))
return true;
for (const Key* key : *KeyboardShortcuts::instance()) {
if (key->isPressed(msg)) {

View File

@ -705,7 +705,11 @@ bool Timeline::onProcessMessage(Message* msg)
else {
m_state = STATE_STANDBY;
}
used = true;
// Don't use this key, so it's caught by CancelCommand.
// TODO The deselection of the current range should be
// handled in CancelCommand itself.
//used = true;
break;
case kKeySpace: {

View File

@ -920,24 +920,28 @@ bool Manager::onProcessMessage(Message* msg)
// Continue sending the message to the children of all windows
// (until a desktop or foreground window).
UI_FOREACH_WIDGET(getChildren(), it) {
Window* w = static_cast<Window*>(*it);
Window* win = nullptr;
for (Widget* manchild : getChildren()) {
win = static_cast<Window*>(manchild);
// Send to the window.
UI_FOREACH_WIDGET(w->getChildren(), it2)
if ((*it2)->sendMessage(msg))
for (auto winchild : win->getChildren())
if (winchild->sendMessage(msg))
return true;
if (w->isForeground() ||
w->isDesktop())
if (win->isForeground() ||
win->isDesktop())
break;
}
// Check the focus movement.
if (msg->type() == kKeyDownMessage)
move_focus(this, msg);
return true;
// Check the focus movement for foreground (non-desktop) windows.
if (win->isForeground()) {
if (msg->type() == kKeyDownMessage)
move_focus(this, msg);
return true;
}
else
return false;
}
}

View File

@ -241,12 +241,11 @@ void Window::openWindow()
void Window::openWindowInForeground()
{
m_isForeground = true;
openWindow();
MessageLoop loop(getManager());
m_isForeground = true;
while (!(this->flags & JI_HIDDEN))
loop.pumpMessages();