-
-
sfernandez
Site Admin
- Posts: 2027
- Joined:
Re: Disable keyboard shortscuts when in gui elements
Correct me if I'm wrong, but doing this has the same problem as using the KeyTrigger, because if you have the focus in a TextBox, and press the 'R' key, IView::KeyDown() will return false (TextBox only handles specific keys it needs like backspace or delete, arrow keys...), so if there is a shortcut associated with the 'R' key it will be executed. Then the 'R' key is translated into the corresponding char and sent to the IView::Char(), and TextInput event is generated, so TextBox writes the 'r' letter too.The current state is that we are handling half of the shortcuts only after IView::KeyDown() returned explicit "false", outside Noesis. Which is working perfectly fine for actions which are entirely independent from the UI, with no unwanted side effects.
Totally agree, that is why we are trying to offer the best approach with the tools we have available in Noesis.And maintaining keybindings in two different systems is not desirable either.
As I said before that is not the case, because KeyDown will always occur before TextInput. Which leads me to another possible solution, that could be more in line with what you are explaining. Implement a ShortcutTrigger that listens to TextInput event and fires the action on the KeyUp event, if no TextBox handled the TextInput event, something like this:Trying to move the shortcut definitions to Noesis scope has led up to using KeyTrigger (as the only available tool), but with the result of evaluation order of shortcuts and text input getting flipped
Code: Select all
void ShortcutTrigger::OnAttached()
{
ParentClass::OnAttached();
Noesis::UIElement* source = GetAssociatedObject();
if (source != 0)
{
source->TextInput() += MakeDelegate(this, &ShortcutTrigger::OnTextInput);
source->KeyUp() += MakeDelegate(this, &ShortcutTrigger::OnKeyUp);
}
}
void ShortcutTrigger::OnDetaching()
{
Noesis::UIElement* source = GetAssociatedObject();
if (source != 0)
{
source->TextInput() -= MakeDelegate(this, &ShortcutTrigger::OnTextInput);
source->KeyUp() -= MakeDelegate(this, &ShortcutTrigger::OnKeyUp);
}
ParentClass::OnDetaching();
}
bool ShortcutTrigger::CheckModifiers() const
{
Noesis::Keyboard* keyboard = GetAssociatedObject()->GetKeyboard();
return GetModifiers() == keyboard->GetModifiers();
}
void ShortcutTrigger::OnTextInput(Noesis::BaseComponent*, const Noesis::TextCompositionEventArgs&)
{
mTextInputIgnored = true;
}
void ShortcutTrigger::OnKeyUp(Noesis::BaseComponent*, const Noesis::KeyEventArgs& e)
{
if (e.key == GetKey() && CheckModifiers() && mTextInputIgnored)
{
mTextInputIgnored = false;
InvokeActions(0);
}
}
Re: Disable keyboard shortscuts when in gui elements
You are correct, it wasn't handled by IView::KeyDown(). But we are checking for return values both of IView::KeyDown() or IView::Char() before continuing to process the input, so it did actually do something plausible for us.Correct me if I'm wrong, but doing this has the same problem as using the KeyTrigger, because if you have the focus in a TextBox, and press the 'R' key, IView::KeyDown() will return false
The Idea of waiting on TextCompositionEvent in "ShortcutTrigger" is effectively doing the same. Doesn't exactly need to wait for KeyUp, but may already enter half-triggered state in KeyDown and trigger on TextCompositionEvent already.
But it does fall for another trap. Any logic trying to argue over TextCompositionEvents is then incapable of handling dead keys (e.g. ^), as TextCompositionEvent isn't triggered until UTF8 composite is passed to IView::Char(). (Win32Display from NoesisApp has skipped mapping any potentially dead keys (VK_OEM_*), so that doesn't show. And none are dead on US keyboard layout.)
So at least for dead key support, it's back to explicitly ignoring key presses if the source (or in fact anything in the event route) is potentially a handler of a followup TextCompositionEvent. There is no way around probing whether the scene is currently in text input mode or not, prior to deciding how to handle the key down event.
-
-
sfernandez
Site Admin
- Posts: 2027
- Joined:
Re: Disable keyboard shortscuts when in gui elements
I understand what you are saying, you're right using TextInput won't work when a shortcut references a dead key.
Taking into account your comments...
I think it is better to try to solve the specific problem here: don't trigger shortcuts if a TextBox (or PasswordBox) has the focus (as I exposed before).
Do you have any suggestion on how to improve that approach?
Taking into account your comments...
I've been doing more tests and I verified that WPF's TextBox only sets Handled to true for KeyDown event on some specific keys, and TextInput event. The KeyUp event simply bubbles up for all keys. So without breaking that behavior, implementing a shortcut trigger that works on all the scenarios you have exposed can't rely on those events being handled by inner controls.it's that the TextBox should (be able to) consume the input it can handle before shortcuts are triggered
I think it is better to try to solve the specific problem here: don't trigger shortcuts if a TextBox (or PasswordBox) has the focus (as I exposed before).
Do you have any suggestion on how to improve that approach?
Who is online
Users browsing this forum: sfernandez and 1 guest