* 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::_FindListener(BMessenger& messenger, int32 token, int32* _index)
EventDispatcher::_FindListener(const BMessenger& messenger, int32 token,
int32* _index)
{
for (int32 i = fListeners.CountItems(); i-- > 0;) {
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
EventDispatcher::_AddListener(BMessenger& messenger, int32 token,
EventDispatcher::_AddListener(const BMessenger& messenger, int32 token,
uint32 events, uint32 options, bool temporary)
{
BAutolock _(this);
@@ -208,16 +216,21 @@ EventDispatcher::_AddListener(BMessenger& messenger, int32 token,
if (target != NULL) {
// we already have this target, update its event mask
if (temporary) {
target->temporary_events = events;
if (events != 0)
target->temporary_events = events;
target->temporary_options = options;
} else {
target->events = events;
if (events != 0)
target->events = events;
target->options = options;
}
return true;
}
if (events == 0)
return false;
// we need a new target
target = new (std::nothrow) event_target;
@@ -278,7 +291,7 @@ EventDispatcher::_RemoveTemporaryListeners()
bool
EventDispatcher::AddListener(BMessenger& messenger, int32 token,
EventDispatcher::AddListener(const BMessenger& messenger, int32 token,
uint32 events, uint32 options)
{
return _AddListener(messenger, token, events, options, false);
@@ -286,15 +299,15 @@ EventDispatcher::AddListener(BMessenger& messenger, int32 token,
bool
EventDispatcher::AddTemporaryListener(BMessenger& messenger, int32 token,
uint32 events, uint32 options)
EventDispatcher::AddTemporaryListener(const BMessenger& messenger,
int32 token, uint32 events, uint32 options)
{
return _AddListener(messenger, token, events, options, true);
}
void
EventDispatcher::RemoveListener(BMessenger& messenger, int32 token)
EventDispatcher::RemoveListener(const BMessenger& messenger, int32 token)
{
BAutolock _(this);
@@ -303,6 +316,35 @@ EventDispatcher::RemoveListener(BMessenger& messenger, int32 token)
if (target == NULL)
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);
delete target;
}
+8 -7
View File
@@ -29,11 +29,12 @@ class EventDispatcher : public BLocker {
void SetFocus(const BMessenger* messenger);
bool AddListener(BMessenger& messenger, int32 token,
bool AddListener(const BMessenger& messenger, int32 token,
uint32 events, uint32 options);
bool AddTemporaryListener(BMessenger& messenger, int32 token,
uint32 events, uint32 options);
void RemoveListener(BMessenger& messenger, int32 token);
bool AddTemporaryListener(const BMessenger& messenger,
int32 token, uint32 events, uint32 options);
void RemoveListener(const BMessenger& messenger, int32 token);
void RemoveTemporaryListener(const BMessenger& messenger, int32 token);
void SetMouseFilter(BMessageFilter* filter);
void SetKeyboardFilter(BMessageFilter* filter);
@@ -54,10 +55,10 @@ class EventDispatcher : public BLocker {
void _RemoveTokens(BMessage* message);
void _SetToken(BMessage* message, int32 token);
event_target* _FindListener(BMessenger& messenger, int32 token,
event_target* _FindListener(const BMessenger& messenger, int32 token,
int32* _index = NULL);
bool _AddListener(BMessenger& messenger, int32 token, uint32 events,
uint32 options, bool temporary);
bool _AddListener(const BMessenger& messenger, int32 token,
uint32 events, uint32 options, bool temporary);
void _RemoveTemporaryListeners();
void _EventLoop();
+2
View File
@@ -71,6 +71,8 @@ class Layer {
inline const char* Name() const
{ return fName.String(); }
int32 ViewToken() const { return fViewToken; }
// children handling
void AddChild(Layer* child, ServerWindow* serverWin);
void RemoveChild(Layer* child);
+31 -14
View File
@@ -666,6 +666,11 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
rootLayer->TriggerRedraw();
}
if (fCurrentLayer->EventMask() != 0) {
fDesktop->EventDispatcher().RemoveListener(Messenger(),
fCurrentLayer->ViewToken());
}
#ifdef DEBUG_SERVERWINDOW
parent->PrintTree();
#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()));
uint32 mask;
uint32 options;
uint32 eventMask, options;
link.Read<uint32>(&mask);
link.Read<uint32>(&options);
link.Read<uint32>(&eventMask);
if (link.Read<uint32>(&options) == B_OK) {
fCurrentLayer->QuietlySetEventMask(eventMask);
fCurrentLayer->QuietlySetEventOptions(options);
fCurrentLayer->QuietlySetEventMask(mask);
fCurrentLayer->QuietlySetEventOptions(options);
if (rootLayer)
rootLayer->AddToInputNotificationLists(fCurrentLayer, mask, options);
if (eventMask != 0 || options != 0) {
fDesktop->EventDispatcher().AddListener(Messenger(),
fCurrentLayer->ViewToken(), eventMask, options);
} else {
fDesktop->EventDispatcher().RemoveListener(Messenger(),
fCurrentLayer->ViewToken());
}
}
break;
}
case AS_LAYER_SET_MOUSE_EVENT_MASK:
{
STRACE(("ServerWindow %s: Message AS_LAYER_SET_MOUSE_EVENT_MASK: Layer name: %s\n", fTitle, fCurrentLayer->Name()));
uint32 mask;
uint32 options;
uint32 eventMask, options;
link.Read<uint32>(&mask);
link.Read<uint32>(&options);
link.Read<uint32>(&eventMask);
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)
rootLayer->SetNotifyLayer(fCurrentLayer, mask, options);
rootLayer->SetNotifyLayer(fCurrentLayer, eventMask, options);
break;
}
case AS_LAYER_MOVE_TO: