* 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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user