* EventDispatcher::AddListener() now honors the BView semantics and will only

update the options in case the specified eventMask was zero.
* Added missing EventDispatcher::RemoveTemporaryTarget().
* Layers setting their event mask are now added to the EventDispatcher.
* The RootLayer is no longer contacted for SetEventMask() - it still handles
  SetMouseEventMask(), tough - as a result, SetEventMask() temporarily doesn't
  work anymore.
* Added Layer::ViewToken() method.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15023 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2005-11-18 15:50:30 +00:00
parent 4ad46aa954
commit 55d6d70ee5
4 changed files with 91 additions and 29 deletions
+50 -8
View File
@@ -183,7 +183,8 @@ EventDispatcher::SetFocus(const BMessenger* messenger)
EventDispatcher::event_target* EventDispatcher::event_target*
EventDispatcher::_FindListener(BMessenger& messenger, int32 token, int32* _index) EventDispatcher::_FindListener(const BMessenger& messenger, int32 token,
int32* _index)
{ {
for (int32 i = fListeners.CountItems(); i-- > 0;) { for (int32 i = fListeners.CountItems(); i-- > 0;) {
event_target* target = fListeners.ItemAt(i); event_target* target = fListeners.ItemAt(i);
@@ -199,8 +200,15 @@ EventDispatcher::_FindListener(BMessenger& messenger, int32 token, int32* _index
} }
/*!
\brief Adds the specified listener or updates its event mask and options
if already added.
It follows the BView semantics in that specifiying an event mask of zero
leaves the event mask untouched and just updates the options.
*/
bool bool
EventDispatcher::_AddListener(BMessenger& messenger, int32 token, EventDispatcher::_AddListener(const BMessenger& messenger, int32 token,
uint32 events, uint32 options, bool temporary) uint32 events, uint32 options, bool temporary)
{ {
BAutolock _(this); BAutolock _(this);
@@ -208,16 +216,21 @@ EventDispatcher::_AddListener(BMessenger& messenger, int32 token,
if (target != NULL) { if (target != NULL) {
// we already have this target, update its event mask // we already have this target, update its event mask
if (temporary) { if (temporary) {
target->temporary_events = events; if (events != 0)
target->temporary_events = events;
target->temporary_options = options; target->temporary_options = options;
} else { } else {
target->events = events; if (events != 0)
target->events = events;
target->options = options; target->options = options;
} }
return true; return true;
} }
if (events == 0)
return false;
// we need a new target // we need a new target
target = new (std::nothrow) event_target; target = new (std::nothrow) event_target;
@@ -278,7 +291,7 @@ EventDispatcher::_RemoveTemporaryListeners()
bool bool
EventDispatcher::AddListener(BMessenger& messenger, int32 token, EventDispatcher::AddListener(const BMessenger& messenger, int32 token,
uint32 events, uint32 options) uint32 events, uint32 options)
{ {
return _AddListener(messenger, token, events, options, false); return _AddListener(messenger, token, events, options, false);
@@ -286,15 +299,15 @@ EventDispatcher::AddListener(BMessenger& messenger, int32 token,
bool bool
EventDispatcher::AddTemporaryListener(BMessenger& messenger, int32 token, EventDispatcher::AddTemporaryListener(const BMessenger& messenger,
uint32 events, uint32 options) int32 token, uint32 events, uint32 options)
{ {
return _AddListener(messenger, token, events, options, true); return _AddListener(messenger, token, events, options, true);
} }
void void
EventDispatcher::RemoveListener(BMessenger& messenger, int32 token) EventDispatcher::RemoveListener(const BMessenger& messenger, int32 token)
{ {
BAutolock _(this); BAutolock _(this);
@@ -303,6 +316,35 @@ EventDispatcher::RemoveListener(BMessenger& messenger, int32 token)
if (target == NULL) if (target == NULL)
return; return;
if (target->temporary_events != 0) {
// we still need this event
target->events = 0;
target->options = 0;
return;
}
fListeners.RemoveItemAt(index);
delete target;
}
void
EventDispatcher::RemoveTemporaryListener(const BMessenger& messenger, int32 token)
{
BAutolock _(this);
int32 index;
event_target* target = _FindListener(messenger, token, &index);
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); fListeners.RemoveItemAt(index);
delete target; delete target;
} }
+8 -7
View File
@@ -29,11 +29,12 @@ class EventDispatcher : public BLocker {
void SetFocus(const BMessenger* messenger); void SetFocus(const BMessenger* messenger);
bool AddListener(BMessenger& messenger, int32 token, bool AddListener(const BMessenger& messenger, int32 token,
uint32 events, uint32 options); uint32 events, uint32 options);
bool AddTemporaryListener(BMessenger& messenger, int32 token, bool AddTemporaryListener(const BMessenger& messenger,
uint32 events, uint32 options); int32 token, uint32 events, uint32 options);
void RemoveListener(BMessenger& messenger, int32 token); void RemoveListener(const BMessenger& messenger, int32 token);
void RemoveTemporaryListener(const BMessenger& messenger, int32 token);
void SetMouseFilter(BMessageFilter* filter); void SetMouseFilter(BMessageFilter* filter);
void SetKeyboardFilter(BMessageFilter* filter); void SetKeyboardFilter(BMessageFilter* filter);
@@ -54,10 +55,10 @@ class EventDispatcher : public BLocker {
void _RemoveTokens(BMessage* message); void _RemoveTokens(BMessage* message);
void _SetToken(BMessage* message, int32 token); void _SetToken(BMessage* message, int32 token);
event_target* _FindListener(BMessenger& messenger, int32 token, event_target* _FindListener(const BMessenger& messenger, int32 token,
int32* _index = NULL); int32* _index = NULL);
bool _AddListener(BMessenger& messenger, int32 token, uint32 events, bool _AddListener(const BMessenger& messenger, int32 token,
uint32 options, bool temporary); uint32 events, uint32 options, bool temporary);
void _RemoveTemporaryListeners(); void _RemoveTemporaryListeners();
void _EventLoop(); void _EventLoop();
+2
View File
@@ -71,6 +71,8 @@ class Layer {
inline const char* Name() const inline const char* Name() const
{ return fName.String(); } { return fName.String(); }
int32 ViewToken() const { return fViewToken; }
// children handling // children handling
void AddChild(Layer* child, ServerWindow* serverWin); void AddChild(Layer* child, ServerWindow* serverWin);
void RemoveChild(Layer* child); void RemoveChild(Layer* child);
+31 -14
View File
@@ -666,6 +666,11 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
rootLayer->TriggerRedraw(); rootLayer->TriggerRedraw();
} }
if (fCurrentLayer->EventMask() != 0) {
fDesktop->EventDispatcher().RemoveListener(Messenger(),
fCurrentLayer->ViewToken());
}
#ifdef DEBUG_SERVERWINDOW #ifdef DEBUG_SERVERWINDOW
parent->PrintTree(); parent->PrintTree();
#endif #endif
@@ -704,30 +709,42 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
{ {
STRACE(("ServerWindow %s: Message AS_LAYER_SET_MOUSE_EVENT_MASK: Layer name: %s\n", fTitle, fCurrentLayer->Name())); STRACE(("ServerWindow %s: Message AS_LAYER_SET_MOUSE_EVENT_MASK: Layer name: %s\n", fTitle, fCurrentLayer->Name()));
uint32 mask; uint32 eventMask, options;
uint32 options;
link.Read<uint32>(&mask); link.Read<uint32>(&eventMask);
link.Read<uint32>(&options); if (link.Read<uint32>(&options) == B_OK) {
fCurrentLayer->QuietlySetEventMask(eventMask);
fCurrentLayer->QuietlySetEventOptions(options);
fCurrentLayer->QuietlySetEventMask(mask); if (eventMask != 0 || options != 0) {
fCurrentLayer->QuietlySetEventOptions(options); fDesktop->EventDispatcher().AddListener(Messenger(),
fCurrentLayer->ViewToken(), eventMask, options);
if (rootLayer) } else {
rootLayer->AddToInputNotificationLists(fCurrentLayer, mask, options); fDesktop->EventDispatcher().RemoveListener(Messenger(),
fCurrentLayer->ViewToken());
}
}
break;
} }
case AS_LAYER_SET_MOUSE_EVENT_MASK: case AS_LAYER_SET_MOUSE_EVENT_MASK:
{ {
STRACE(("ServerWindow %s: Message AS_LAYER_SET_MOUSE_EVENT_MASK: Layer name: %s\n", fTitle, fCurrentLayer->Name())); STRACE(("ServerWindow %s: Message AS_LAYER_SET_MOUSE_EVENT_MASK: Layer name: %s\n", fTitle, fCurrentLayer->Name()));
uint32 mask; uint32 eventMask, options;
uint32 options;
link.Read<uint32>(&mask); link.Read<uint32>(&eventMask);
link.Read<uint32>(&options); if (link.Read<uint32>(&options) == B_OK) {
if (eventMask != 0 || options != 0) {
fDesktop->EventDispatcher().AddTemporaryListener(Messenger(),
fCurrentLayer->ViewToken(), eventMask, options);
} else {
fDesktop->EventDispatcher().RemoveTemporaryListener(Messenger(),
fCurrentLayer->ViewToken());
}
}
if (rootLayer) if (rootLayer)
rootLayer->SetNotifyLayer(fCurrentLayer, mask, options); rootLayer->SetNotifyLayer(fCurrentLayer, eventMask, options);
break; break;
} }
case AS_LAYER_MOVE_TO: case AS_LAYER_MOVE_TO: