* now all event targets of the focus window get into the focus list - that

way, we always send only one message per event, no matter how many targets
  there are in the window (the focus event list was not always maintained
  correctly before, too).
* the current mouse filter eats all B_MOUSE_UP events, and therefore, the
  temporary event targets were never removed.
* changed the way BWindow::_DistributeMessage() recognizes if it should forward
  the event - not yet final, though.
* naming is now more consistent (events -> event_mask).
* some minor cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15058 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2005-11-21 16:25:23 +00:00
parent 3cace414ad
commit 82d8744887
2 changed files with 90 additions and 61 deletions
+86 -58
View File
@@ -37,13 +37,13 @@
struct EventDispatcher::event_target {
BMessenger messenger;
int32 token;
uint32 events;
uint32 event_mask;
uint32 options;
uint32 temporary_events;
uint32 temporary_event_mask;
uint32 temporary_options;
};
static const char* kTokenName = "_token_";
static const char* kTokenName = "_token";
static const float kMouseMovedImportance = 0.1f;
static const float kMouseTransitImportance = 1.0f;
@@ -168,12 +168,11 @@ EventDispatcher::SetFocus(const BMessenger* messenger)
if (fHasFocus) {
fFocus = *messenger;
// add all B_POINTER_EVENTS tokens that target this messenger
// add all tokens that target this messenger
for (int32 i = fListeners.CountItems(); i-- > 0;) {
event_target* target = fListeners.ItemAt(i);
if (((target->events | target->temporary_events) & B_POINTER_EVENTS) != 0
&& target->messenger == fFocus)
if (target->messenger == fFocus)
fFocusTokens.AddItem((void *)target->token);
}
}
@@ -209,30 +208,30 @@ EventDispatcher::_FindListener(const BMessenger& messenger, int32 token,
*/
bool
EventDispatcher::_AddListener(const BMessenger& messenger, int32 token,
uint32 events, uint32 options, bool temporary)
uint32 eventMask, uint32 options, bool temporary)
{
BAutolock _(this);
event_target* target = _FindListener(messenger, token);
if (target != NULL) {
// we already have this target, update its event mask
if (temporary) {
if (events != 0)
target->temporary_events = events;
if (eventMask != 0)
target->temporary_event_mask = eventMask;
target->temporary_options = options;
} else {
if (events != 0)
target->events = events;
if (eventMask != 0)
target->event_mask = eventMask;
target->options = options;
}
return true;
}
if (events == 0)
if (eventMask == 0)
return false;
ETRACE(("events: add listener: token %ld, events = %ld, options = %ld, %s\n",
token, events, options, temporary ? "temporary" : "permanent"));
ETRACE(("events: add listener: token %ld, eventMask = %ld, options = %ld, %s\n",
token, eventMask, options, temporary ? "temporary" : "permanent"));
// we need a new target
@@ -244,24 +243,24 @@ EventDispatcher::_AddListener(const BMessenger& messenger, int32 token,
target->token = token;
if (temporary) {
target->events = 0;
target->event_mask = 0;
target->options = 0;
target->temporary_events = events;
target->temporary_event_mask = eventMask;
target->temporary_options = options;
if (options & B_SUSPEND_VIEW_FOCUS)
fSuspendFocus = true;
} else {
target->events = events;
target->event_mask = eventMask;
target->options = options;
target->temporary_events = 0;
target->temporary_event_mask = 0;
target->temporary_options = 0;
}
bool success = fListeners.AddItem(target);
if (success) {
if ((events & B_POINTER_EVENTS) != 0
&& fHasFocus && fFocus == messenger) {
if (fHasFocus && fFocus == messenger) {
// add this token to the current token list
ETRACE((" add token %ld to focus list\n", token));
fFocusTokens.AddItem((void *)token);
}
} else
@@ -271,47 +270,61 @@ EventDispatcher::_AddListener(const BMessenger& messenger, int32 token,
}
void
EventDispatcher::_RemoveTemporaryListener(event_target* target, int32 index)
{
if (target->event_mask == 0) {
// this is only a temporary target
fListeners.RemoveItemAt(index);
ETRACE(("events: remove temp. listener: token %ld, eventMask = %ld, options = %ld\n",
target->token, target->temporary_event_mask, target->temporary_options));
if (fHasFocus && fFocus == target->messenger) {
// remove this token from the current token list
ETRACE((" remove token %ld from focus list\n",
target->token));
fFocusTokens.RemoveItem((void *)target->token);
}
delete target;
} else if (target->temporary_event_mask != 0) {
ETRACE(("events: clear temp. listener: token %ld, eventMask = %ld, options = %ld\n",
target->token, target->temporary_event_mask, target->temporary_options));
target->temporary_event_mask = 0;
target->temporary_options = 0;
}
}
void
EventDispatcher::_RemoveTemporaryListeners()
{
for (int32 i = fListeners.CountItems(); i-- > 0;) {
event_target* target = fListeners.ItemAt(i);
if (target->events == 0) {
// this is only a temporary target
fListeners.RemoveItemAt(i);
ETRACE(("events: remove temp. listener: token %ld, events = %ld, options = %ld\n",
target->token, target->temporary_events, target->temporary_options));
if ((target->temporary_events & B_POINTER_EVENTS) != 0
&& fHasFocus && fFocus == target->messenger) {
// remove this token from the current token list
fFocusTokens.RemoveItem((void *)target->token);
}
delete target;
} else {
target->temporary_events = 0;
target->temporary_options = 0;
}
_RemoveTemporaryListener(target, i);
}
}
bool
EventDispatcher::AddListener(const BMessenger& messenger, int32 token,
uint32 events, uint32 options)
uint32 eventMask, uint32 options)
{
return _AddListener(messenger, token, events, options, false);
options &= B_NO_POINTER_HISTORY;
// that's currently the only allowed option
return _AddListener(messenger, token, eventMask, options, false);
}
bool
EventDispatcher::AddTemporaryListener(const BMessenger& messenger,
int32 token, uint32 events, uint32 options)
int32 token, uint32 eventMask, uint32 options)
{
return _AddListener(messenger, token, events, options, true);
return _AddListener(messenger, token, eventMask, options, true);
}
@@ -326,13 +339,20 @@ EventDispatcher::RemoveListener(const BMessenger& messenger, int32 token)
if (target == NULL)
return;
if (target->temporary_events != 0) {
if (target->temporary_event_mask != 0) {
// we still need this event
target->events = 0;
target->event_mask = 0;
target->options = 0;
return;
}
if (fHasFocus && fFocus == target->messenger) {
// remove this token from the current token list
ETRACE((" remove token %ld from focus list\n",
target->token));
fFocusTokens.RemoveItem((void *)target->token);
}
fListeners.RemoveItemAt(index);
delete target;
}
@@ -348,15 +368,7 @@ EventDispatcher::RemoveTemporaryListener(const BMessenger& messenger, int32 toke
if (target == NULL)
return;
if (target->events != 0) {
// we still need this event
target->temporary_events = 0;
target->temporary_options = 0;
return;
}
fListeners.RemoveItemAt(index);
delete target;
_RemoveTemporaryListener(target, index);
}
@@ -459,6 +471,7 @@ EventDispatcher::_AddTokens(BMessage* message, BList& tokens)
int32 count = tokens.CountItems();
for (int32 i = count; i-- > 0;) {
int32 token = (int32)tokens.ItemAt(i);
ETRACE((" add token %ld\n", token));
if (message->AddInt32(kTokenName, token) != B_OK)
count--;
@@ -536,8 +549,15 @@ EventDispatcher::_EventLoop()
case B_MOUSE_DOWN:
case B_MOUSE_UP:
if (fMouseFilter != NULL
&& fMouseFilter->Filter(event, NULL) == B_SKIP_MESSAGE)
&& fMouseFilter->Filter(event, NULL) == B_SKIP_MESSAGE) {
// this is a work-around if the wrong B_MOUSE_UP
// event is filtered out
if (event->what == B_MOUSE_UP) {
fSuspendFocus = false;
_RemoveTemporaryListeners();
}
break;
}
pointerEvent = true;
@@ -559,13 +579,21 @@ EventDispatcher::_EventLoop()
keyboardEvent = true;
if (fHasFocus && _AddTokens(event, fFocusTokens)) {
// if tokens were added, we need to explicetly suspend
// focus in the event - if not, the event is simply not
// forwarded to the target
addedTokens = true;
if (fSuspendFocus)
event->AddBool("_suspend_focus", true);
}
// supposed to fall through
default:
if (fHasFocus && !fSuspendFocus) {
addedTokens |= _AddTokens(event, fFocusTokens);
if (fHasFocus && (!fSuspendFocus || addedTokens))
_SendMessage(fFocus, event, kStandardImportance);
}
break;
}
@@ -585,7 +613,7 @@ EventDispatcher::_EventLoop()
|| (sendToLastFocus && target->messenger == fLastFocus))
continue;
uint32 effectiveEvents = target->events | target->temporary_events;
uint32 effectiveEvents = target->event_mask | target->temporary_event_mask;
// make sure only those interested listeners get the message
if ((keyboardEvent && (effectiveEvents & B_KEYBOARD_EVENTS) == 0)
+4 -3
View File
@@ -30,9 +30,9 @@ class EventDispatcher : public BLocker {
void SetFocus(const BMessenger* messenger);
bool AddListener(const BMessenger& messenger, int32 token,
uint32 events, uint32 options);
uint32 eventMask, uint32 options);
bool AddTemporaryListener(const BMessenger& messenger,
int32 token, uint32 events, uint32 options);
int32 token, uint32 eventMask, uint32 options);
void RemoveListener(const BMessenger& messenger, int32 token);
void RemoveTemporaryListener(const BMessenger& messenger, int32 token);
@@ -58,7 +58,8 @@ class EventDispatcher : public BLocker {
event_target* _FindListener(const BMessenger& messenger, int32 token,
int32* _index = NULL);
bool _AddListener(const BMessenger& messenger, int32 token,
uint32 events, uint32 options, bool temporary);
uint32 eventMask, uint32 options, bool temporary);
void _RemoveTemporaryListener(event_target* target, int32 index);
void _RemoveTemporaryListeners();
void _EventLoop();