From 55d6d70ee59eb2e2473c2195b5e6b26ee29380d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 18 Nov 2005 15:50:30 +0000 Subject: [PATCH] * 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 --- src/servers/app/EventDispatcher.cpp | 58 +++++++++++++++++++++++++---- src/servers/app/EventDispatcher.h | 15 ++++---- src/servers/app/Layer.h | 2 + src/servers/app/ServerWindow.cpp | 45 +++++++++++++++------- 4 files changed, 91 insertions(+), 29 deletions(-) diff --git a/src/servers/app/EventDispatcher.cpp b/src/servers/app/EventDispatcher.cpp index 7cf48e3003..1d96b3a67c 100644 --- a/src/servers/app/EventDispatcher.cpp +++ b/src/servers/app/EventDispatcher.cpp @@ -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; } diff --git a/src/servers/app/EventDispatcher.h b/src/servers/app/EventDispatcher.h index d5a1b070b6..ddb5a2fd73 100644 --- a/src/servers/app/EventDispatcher.h +++ b/src/servers/app/EventDispatcher.h @@ -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(); diff --git a/src/servers/app/Layer.h b/src/servers/app/Layer.h index 5c975f2648..0d0c0b3b21 100644 --- a/src/servers/app/Layer.h +++ b/src/servers/app/Layer.h @@ -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); diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index 9e08c7716e..a3686533e6 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -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(&mask); - link.Read(&options); + link.Read(&eventMask); + if (link.Read(&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(&mask); - link.Read(&options); + link.Read(&eventMask); + if (link.Read(&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: