The keyboard focus is now always updated if the message is a B_[UNMAPPED_]KEY_DOWN or a
B_MODIFIERS_CHANGED message. This fixes bug #175 (which was probably caused by a bug in our old BMessage implementation, see TODO item in line 141). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16414 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+53
-38
@@ -59,6 +59,8 @@ class KeyboardFilter : public EventFilter {
|
||||
int32* _viewToken, BMessage* latestMouseMoved);
|
||||
|
||||
private:
|
||||
void _UpdateFocus(int32 key, EventTarget** _target);
|
||||
|
||||
Desktop* fDesktop;
|
||||
EventTarget* fLastFocus;
|
||||
bigtime_t fTimestamp;
|
||||
@@ -88,23 +90,63 @@ KeyboardFilter::KeyboardFilter(Desktop* desktop)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
KeyboardFilter::_UpdateFocus(int32 key, EventTarget** _target)
|
||||
{
|
||||
if (!fDesktop->LockSingleWindow())
|
||||
return;
|
||||
|
||||
bigtime_t now = system_time();
|
||||
|
||||
EventTarget* focus = NULL;
|
||||
if (fDesktop->FocusWindow() != NULL)
|
||||
focus = &fDesktop->FocusWindow()->EventTarget();
|
||||
|
||||
// TODO: this is a try to not steal focus from the current window
|
||||
// in case you enter some text and a window pops up you haven't
|
||||
// triggered yourself (like a pop-up window in your browser while
|
||||
// you're typing a password in another window) - maybe this should
|
||||
// be done differently, though (using something like B_LOCK_WINDOW_FOCUS)
|
||||
// (at least B_WINDOW_ACTIVATED must be postponed)
|
||||
|
||||
if (focus != fLastFocus && now - fTimestamp > 100000) {
|
||||
// if the time span between the key presses is very short
|
||||
// we keep our previous focus alive - this is save even
|
||||
// if the target doesn't exist anymore, as we don't reset
|
||||
// it, and the event focus passed in is always valid (or NULL)
|
||||
*_target = focus;
|
||||
fLastFocus = focus;
|
||||
}
|
||||
|
||||
fDesktop->UnlockSingleWindow();
|
||||
|
||||
// we always allow to switch focus after the enter key has pressed
|
||||
if (key == B_ENTER)
|
||||
fTimestamp = 0;
|
||||
else
|
||||
fTimestamp = now;
|
||||
}
|
||||
|
||||
|
||||
filter_result
|
||||
KeyboardFilter::Filter(BMessage* message, EventTarget** _target,
|
||||
int32* /*_viewToken*/, BMessage* /*latestMouseMoved*/)
|
||||
{
|
||||
int32 key;
|
||||
int32 key = 0;
|
||||
int32 modifiers;
|
||||
|
||||
if (message->what != B_KEY_DOWN
|
||||
|| message->FindInt32("key", &key) != B_OK
|
||||
|| message->FindInt32("modifiers", &modifiers) != B_OK)
|
||||
return B_DISPATCH_MESSAGE;
|
||||
if (message->what == B_KEY_DOWN
|
||||
&& message->FindInt32("key", &key) == B_OK
|
||||
&& message->FindInt32("modifiers", &modifiers) == B_OK) {
|
||||
// TODO: for some reason, one of the above is failing when pressing
|
||||
// a modifier key at least with the old BMessage implementation
|
||||
// (a message dump shows all entries, though)
|
||||
// Try again with BMessage4!
|
||||
|
||||
// Check for safe video mode (F12 + l-cmd + l-ctrl + l-shift)
|
||||
if (key == 0x0d
|
||||
&& (modifiers & (B_LEFT_COMMAND_KEY
|
||||
| B_LEFT_CONTROL_KEY | B_LEFT_SHIFT_KEY)) != 0)
|
||||
{
|
||||
| B_LEFT_CONTROL_KEY | B_LEFT_SHIFT_KEY)) != 0) {
|
||||
// TODO: Set to Safe Mode in KeyboardEventHandler:B_KEY_DOWN.
|
||||
STRACE(("Safe Video Mode invoked - code unimplemented\n"));
|
||||
return B_SKIP_MESSAGE;
|
||||
@@ -144,39 +186,12 @@ KeyboardFilter::Filter(BMessage* message, EventTarget** _target,
|
||||
fDesktop->GetDrawingEngine()->DumpToFile(filename);
|
||||
return B_SKIP_MESSAGE;
|
||||
}
|
||||
|
||||
bigtime_t now = system_time();
|
||||
|
||||
if (!fDesktop->LockSingleWindow())
|
||||
return B_DISPATCH_MESSAGE;
|
||||
|
||||
EventTarget* focus = NULL;
|
||||
if (fDesktop->FocusWindow() != NULL)
|
||||
focus = &fDesktop->FocusWindow()->EventTarget();
|
||||
|
||||
// TODO: this is a try to not steal focus from the current window
|
||||
// in case you enter some text and a window pops up you haven't
|
||||
// triggered yourself (like a pop-up window in your browser while
|
||||
// you're typing a password in another window) - maybe this should
|
||||
// be done differently, though (using something like B_LOCK_WINDOW_FOCUS)
|
||||
// (at least B_WINDOW_ACTIVATED must be postponed)
|
||||
|
||||
if (focus != fLastFocus && now - fTimestamp > 100000) {
|
||||
// if the time span between the key presses is very short
|
||||
// we keep our previous focus alive - this is save even
|
||||
// if the target doesn't exist anymore, as we don't reset
|
||||
// it, and the event focus passed in is always valid (or NULL)
|
||||
*_target = focus;
|
||||
fLastFocus = focus;
|
||||
}
|
||||
|
||||
fDesktop->UnlockSingleWindow();
|
||||
|
||||
// we always allow to switch focus after the enter key has pressed
|
||||
if (key == B_ENTER)
|
||||
fTimestamp = 0;
|
||||
else
|
||||
fTimestamp = now;
|
||||
if (message->what == B_KEY_DOWN
|
||||
|| message->what == B_MODIFIERS_CHANGED
|
||||
|| message->what == B_UNMAPPED_KEY_DOWN)
|
||||
_UpdateFocus(key, _target);
|
||||
|
||||
return B_DISPATCH_MESSAGE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user