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