Have I said input event handling is done?
* didn't realize that mouse events always go to the view under the mouse, not only if its the focus window (FFM can really do harm, after all :-)). * removed a TODO from the list: EventDispatcher::Target is now a public class EventTarget, and every ServerWindow has one. * as a result, EventDispatcher no longer manages targets itself, it just maintains a list of them. You no longer set messengers, you only set targets. * customization of the message filters, they no longer inherit from BMessageFilter (but EventFilter). * a message target is no longer set explicetly anywhere, it's only changed in the message filters if needed. * therefore, no more locking mess in the EventDispatcher needed. * this also made the EventDispatcher::fLastFocus stuff superfluous. * moved the RootLayer::MouseEventHandler() into the message filter. * Replaced RootLayer::_ChildAt() with WindowAt(). * WindowLayer now has an idea if it has focus or not, it no longer needs to query the RootLayer for this - maybe we should rename "focus" to "active", though (as far as layers are concerned). * the "_view_token" data is now added from the EventDispatcher, not the (Window)Layer class anymore. * removed Layer::MouseWheelChanged() as we currently don't need it (if the need arises, we can add it back later again) * there is still no mouse moved message sent when opening a window under the cursor, though... git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15228 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+116
-27
@@ -49,26 +49,46 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
class KeyboardFilter : public BMessageFilter {
|
class KeyboardFilter : public EventFilter {
|
||||||
public:
|
public:
|
||||||
KeyboardFilter(Desktop* desktop);
|
KeyboardFilter(Desktop* desktop);
|
||||||
|
|
||||||
virtual filter_result Filter(BMessage* message, BHandler** _target);
|
virtual filter_result Filter(BMessage* message, EventTarget** _target,
|
||||||
|
int32* _viewToken);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Desktop* fDesktop;
|
||||||
|
EventTarget* fLastFocus;
|
||||||
|
bigtime_t fTimestamp;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MouseFilter : public EventFilter {
|
||||||
|
public:
|
||||||
|
MouseFilter(Desktop* desktop);
|
||||||
|
|
||||||
|
virtual filter_result Filter(BMessage* message, EventTarget** _target,
|
||||||
|
int32* _viewToken);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Desktop* fDesktop;
|
Desktop* fDesktop;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
KeyboardFilter::KeyboardFilter(Desktop* desktop)
|
KeyboardFilter::KeyboardFilter(Desktop* desktop)
|
||||||
: BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE),
|
:
|
||||||
fDesktop(desktop)
|
fDesktop(desktop),
|
||||||
|
fLastFocus(NULL),
|
||||||
|
fTimestamp(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
filter_result
|
filter_result
|
||||||
KeyboardFilter::Filter(BMessage* message, BHandler** /*_target*/)
|
KeyboardFilter::Filter(BMessage* message, EventTarget** _target,
|
||||||
|
int32* /*_viewToken*/)
|
||||||
{
|
{
|
||||||
int32 key;
|
int32 key;
|
||||||
int32 modifiers;
|
int32 modifiers;
|
||||||
@@ -123,6 +143,93 @@ KeyboardFilter::Filter(BMessage* message, BHandler** /*_target*/)
|
|||||||
return B_SKIP_MESSAGE;
|
return B_SKIP_MESSAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bigtime_t now = system_time();
|
||||||
|
|
||||||
|
::RootLayer* rootLayer = fDesktop->RootLayer();
|
||||||
|
rootLayer->Lock();
|
||||||
|
|
||||||
|
EventTarget* focus = NULL;
|
||||||
|
if (rootLayer->Focus() != NULL)
|
||||||
|
focus = &rootLayer->Focus()->Window()->EventTarget();
|
||||||
|
|
||||||
|
// TODO: this is a try to not steal focus from the current window
|
||||||
|
// in case you enter some text and a window pops up you haven't
|
||||||
|
// triggered yourself (like a pop-up window in your browser while
|
||||||
|
// you're typing a password in another window) - maybe this should
|
||||||
|
// be done differently, though (using something like B_LOCK_WINDOW_FOCUS)
|
||||||
|
|
||||||
|
if (focus != fLastFocus && now - fTimestamp > 100000) {
|
||||||
|
// if the time span between the key presses is very short
|
||||||
|
// we keep our previous focus alive - this is save even
|
||||||
|
// if the target doesn't exist anymore, as we don't reset
|
||||||
|
// it, and the event focus passed in is always valid (or NULL)
|
||||||
|
*_target = focus;
|
||||||
|
fLastFocus = focus;
|
||||||
|
}
|
||||||
|
|
||||||
|
rootLayer->Unlock();
|
||||||
|
|
||||||
|
// we always allow to switch focus after the enter key has pressed
|
||||||
|
if (key == B_ENTER)
|
||||||
|
fTimestamp = 0;
|
||||||
|
else
|
||||||
|
fTimestamp = now;
|
||||||
|
|
||||||
|
return B_DISPATCH_MESSAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
MouseFilter::MouseFilter(Desktop* desktop)
|
||||||
|
:
|
||||||
|
fDesktop(desktop)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
filter_result
|
||||||
|
MouseFilter::Filter(BMessage* message, EventTarget** _target, int32* _viewToken)
|
||||||
|
{
|
||||||
|
BPoint where;
|
||||||
|
if (message->FindPoint("where", &where) != B_OK)
|
||||||
|
return B_DISPATCH_MESSAGE;
|
||||||
|
|
||||||
|
::RootLayer* rootLayer = fDesktop->RootLayer();
|
||||||
|
|
||||||
|
rootLayer->Lock();
|
||||||
|
|
||||||
|
WindowLayer* window = rootLayer->MouseEventWindow();
|
||||||
|
if (window == NULL)
|
||||||
|
window = rootLayer->WindowAt(where);
|
||||||
|
|
||||||
|
if (window != NULL) {
|
||||||
|
// dispatch event in the window layers
|
||||||
|
switch (message->what) {
|
||||||
|
case B_MOUSE_DOWN:
|
||||||
|
window->MouseDown(message, where, _viewToken);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_MOUSE_UP:
|
||||||
|
window->MouseUp(message, where, _viewToken);
|
||||||
|
rootLayer->SetMouseEventWindow(NULL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_MOUSE_MOVED:
|
||||||
|
window->MouseMoved(message, where, _viewToken);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*_viewToken != B_NULL_TOKEN)
|
||||||
|
*_target = &window->Window()->EventTarget();
|
||||||
|
else
|
||||||
|
*_target = NULL;
|
||||||
|
} else
|
||||||
|
*_target = NULL;
|
||||||
|
|
||||||
|
rootLayer->Unlock();
|
||||||
|
|
||||||
return B_DISPATCH_MESSAGE;
|
return B_DISPATCH_MESSAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,28 +292,7 @@ Desktop::Init()
|
|||||||
fEventDispatcher.SetTo(gInputManager->GetStream());
|
fEventDispatcher.SetTo(gInputManager->GetStream());
|
||||||
fEventDispatcher.SetHWInterface(fVirtualScreen.HWInterface());
|
fEventDispatcher.SetHWInterface(fVirtualScreen.HWInterface());
|
||||||
|
|
||||||
// temporary hack to get things started
|
fEventDispatcher.SetMouseFilter(new MouseFilter(this));
|
||||||
class MouseFilter : public BMessageFilter {
|
|
||||||
public:
|
|
||||||
MouseFilter(::RootLayer* layer)
|
|
||||||
: BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE),
|
|
||||||
fRootLayer(layer)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual filter_result
|
|
||||||
Filter(BMessage* message, BHandler** /*_target*/)
|
|
||||||
{
|
|
||||||
fRootLayer->Lock();
|
|
||||||
fRootLayer->MouseEventHandler(message);
|
|
||||||
fRootLayer->Unlock();
|
|
||||||
return B_DISPATCH_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
::RootLayer* fRootLayer;
|
|
||||||
};
|
|
||||||
fEventDispatcher.SetMouseFilter(new MouseFilter(fRootLayer));
|
|
||||||
fEventDispatcher.SetKeyboardFilter(new KeyboardFilter(this));
|
fEventDispatcher.SetKeyboardFilter(new KeyboardFilter(this));
|
||||||
|
|
||||||
// take care of setting the default cursor
|
// take care of setting the default cursor
|
||||||
@@ -560,6 +646,9 @@ Desktop::RemoveWindowLayer(WindowLayer *windowLayer)
|
|||||||
Unlock();
|
Unlock();
|
||||||
|
|
||||||
RootLayer()->RemoveWindowLayer(windowLayer);
|
RootLayer()->RemoveWindowLayer(windowLayer);
|
||||||
|
|
||||||
|
if (windowLayer->Window() != NULL)
|
||||||
|
EventDispatcher().RemoveTarget(windowLayer->Window()->EventTarget());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+102
-246
@@ -12,6 +12,8 @@
|
|||||||
#include "HWInterface.h"
|
#include "HWInterface.h"
|
||||||
#include "InputManager.h"
|
#include "InputManager.h"
|
||||||
|
|
||||||
|
#include <TokenSpace.h>
|
||||||
|
|
||||||
#include <Autolock.h>
|
#include <Autolock.h>
|
||||||
#include <MessageFilter.h>
|
#include <MessageFilter.h>
|
||||||
#include <View.h>
|
#include <View.h>
|
||||||
@@ -29,11 +31,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// TODO: the Target class could be made public, and ServerWindow could inherit
|
|
||||||
// from it - this would especially be nice if we didn't have to lock the root
|
|
||||||
// layer when messing with ServerWindow children (because then, RootLayer's
|
|
||||||
// mouse filter could almost be moved completely to the window).
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
The differentiation between messenger and token looks odd, but it
|
The differentiation between messenger and token looks odd, but it
|
||||||
really has a reason as well:
|
really has a reason as well:
|
||||||
@@ -42,40 +39,7 @@
|
|||||||
view(s).
|
view(s).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class EventDispatcher::Target {
|
struct event_listener {
|
||||||
public:
|
|
||||||
Target(const BMessenger& messenger);
|
|
||||||
~Target();
|
|
||||||
|
|
||||||
BMessenger& Messenger() { return fMessenger; }
|
|
||||||
|
|
||||||
event_listener* FindListener(int32 token, int32* _index = NULL);
|
|
||||||
bool AddListener(int32 token, uint32 eventMask, uint32 options,
|
|
||||||
bool temporary);
|
|
||||||
void RemoveListener(event_listener* listener, bool temporary);
|
|
||||||
|
|
||||||
bool RemoveListener(int32 token);
|
|
||||||
bool RemoveTemporaryListener(int32 token);
|
|
||||||
void RemoveTemporaryListeners();
|
|
||||||
|
|
||||||
bool IsNeeded() const { return fFocusOrLastFocus || !fListeners.IsEmpty(); }
|
|
||||||
|
|
||||||
void SetFocusOrLastFocus(bool focus) { fFocusOrLastFocus = focus; }
|
|
||||||
bool FocusOrLastFocus() const { return fFocusOrLastFocus; }
|
|
||||||
|
|
||||||
int32 CountListeners() const { return fListeners.CountItems(); }
|
|
||||||
event_listener* ListenerAt(int32 index) const { return fListeners.ItemAt(index); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool _RemoveTemporaryListener(event_listener* listener, int32 index);
|
|
||||||
|
|
||||||
BObjectList<event_listener> fListeners;
|
|
||||||
BMessenger fMessenger;
|
|
||||||
bool fFocusOrLastFocus;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
struct EventDispatcher::event_listener {
|
|
||||||
int32 token;
|
int32 token;
|
||||||
uint32 event_mask;
|
uint32 event_mask;
|
||||||
uint32 options;
|
uint32 options;
|
||||||
@@ -93,22 +57,27 @@ static const float kStandardImportance = 0.9f;
|
|||||||
static const float kListenerImportance = 0.8f;
|
static const float kListenerImportance = 0.8f;
|
||||||
|
|
||||||
|
|
||||||
EventDispatcher::Target::Target(const BMessenger& messenger)
|
EventTarget::EventTarget()
|
||||||
:
|
:
|
||||||
fListeners(2, true),
|
fListeners(2, true)
|
||||||
fMessenger(messenger),
|
|
||||||
fFocusOrLastFocus(false)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EventDispatcher::Target::~Target()
|
EventTarget::~EventTarget()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EventDispatcher::event_listener*
|
void
|
||||||
EventDispatcher::Target::FindListener(int32 token, int32* _index)
|
EventTarget::SetTo(const BMessenger& messenger)
|
||||||
|
{
|
||||||
|
fMessenger = messenger;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
event_listener*
|
||||||
|
EventTarget::FindListener(int32 token, int32* _index)
|
||||||
{
|
{
|
||||||
for (int32 i = fListeners.CountItems(); i-- > 0;) {
|
for (int32 i = fListeners.CountItems(); i-- > 0;) {
|
||||||
event_listener* listener = fListeners.ItemAt(i);
|
event_listener* listener = fListeners.ItemAt(i);
|
||||||
@@ -125,7 +94,7 @@ EventDispatcher::Target::FindListener(int32 token, int32* _index)
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
EventDispatcher::Target::_RemoveTemporaryListener(event_listener* listener, int32 index)
|
EventTarget::_RemoveTemporaryListener(event_listener* listener, int32 index)
|
||||||
{
|
{
|
||||||
if (listener->event_mask == 0) {
|
if (listener->event_mask == 0) {
|
||||||
// this is only a temporary target
|
// this is only a temporary target
|
||||||
@@ -150,7 +119,7 @@ EventDispatcher::Target::_RemoveTemporaryListener(event_listener* listener, int3
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
EventDispatcher::Target::RemoveTemporaryListeners()
|
EventTarget::RemoveTemporaryListeners()
|
||||||
{
|
{
|
||||||
for (int32 index = CountListeners(); index-- > 0;) {
|
for (int32 index = CountListeners(); index-- > 0;) {
|
||||||
event_listener* listener = ListenerAt(index);
|
event_listener* listener = ListenerAt(index);
|
||||||
@@ -161,7 +130,7 @@ EventDispatcher::Target::RemoveTemporaryListeners()
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
EventDispatcher::Target::RemoveTemporaryListener(int32 token)
|
EventTarget::RemoveTemporaryListener(int32 token)
|
||||||
{
|
{
|
||||||
int32 index;
|
int32 index;
|
||||||
event_listener* listener = FindListener(token, &index);
|
event_listener* listener = FindListener(token, &index);
|
||||||
@@ -173,7 +142,7 @@ EventDispatcher::Target::RemoveTemporaryListener(int32 token)
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
EventDispatcher::Target::RemoveListener(int32 token)
|
EventTarget::RemoveListener(int32 token)
|
||||||
{
|
{
|
||||||
int32 index;
|
int32 index;
|
||||||
event_listener* listener = FindListener(token, &index);
|
event_listener* listener = FindListener(token, &index);
|
||||||
@@ -194,7 +163,7 @@ EventDispatcher::Target::RemoveListener(int32 token)
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
EventDispatcher::Target::AddListener(int32 token, uint32 eventMask,
|
EventTarget::AddListener(int32 token, uint32 eventMask,
|
||||||
uint32 options, bool temporary)
|
uint32 options, bool temporary)
|
||||||
{
|
{
|
||||||
event_listener* listener = new (std::nothrow) event_listener;
|
event_listener* listener = new (std::nothrow) event_listener;
|
||||||
@@ -231,15 +200,12 @@ EventDispatcher::EventDispatcher()
|
|||||||
fStream(NULL),
|
fStream(NULL),
|
||||||
fThread(-1),
|
fThread(-1),
|
||||||
fCursorThread(-1),
|
fCursorThread(-1),
|
||||||
|
fPreviousMouseTarget(NULL),
|
||||||
fFocus(NULL),
|
fFocus(NULL),
|
||||||
fLastFocus(NULL),
|
|
||||||
fTransit(false),
|
|
||||||
fSuspendFocus(false),
|
fSuspendFocus(false),
|
||||||
fMouseFilter(NULL),
|
fMouseFilter(NULL),
|
||||||
fKeyboardFilter(NULL),
|
fKeyboardFilter(NULL),
|
||||||
fTargets(10, true),
|
fTargets(10),
|
||||||
// the list owns its items
|
|
||||||
fListenerLock("listener lock"),
|
|
||||||
fCursorLock("cursor loop lock"),
|
fCursorLock("cursor loop lock"),
|
||||||
fHWInterface(NULL)
|
fHWInterface(NULL)
|
||||||
{
|
{
|
||||||
@@ -321,101 +287,20 @@ EventDispatcher::_Run()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Removes any reference to the target, but doesn't delete it.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
EventDispatcher::_UnsetLastFocus()
|
EventDispatcher::RemoveTarget(EventTarget& target)
|
||||||
{
|
|
||||||
if (fLastFocus == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
fLastFocus->SetFocusOrLastFocus(false);
|
|
||||||
if (!fLastFocus->IsNeeded())
|
|
||||||
_RemoveTarget(fLastFocus);
|
|
||||||
|
|
||||||
fLastFocus = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
EventDispatcher::SetFocus(const BMessenger* messenger)
|
|
||||||
{
|
{
|
||||||
BAutolock _(this);
|
BAutolock _(this);
|
||||||
BAutolock _temp(fListenerLock);
|
|
||||||
|
|
||||||
ETRACE(("EventDispatcher::SetFocus(messenger = %p)\n", messenger));
|
if (fFocus == &target)
|
||||||
|
|
||||||
if ((messenger == NULL && fFocus == NULL)
|
|
||||||
|| (messenger != NULL && fFocus != NULL && fFocus->Messenger() == *messenger))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// update last focus
|
|
||||||
|
|
||||||
if (fLastFocus != NULL)
|
|
||||||
_UnsetLastFocus();
|
|
||||||
|
|
||||||
fLastFocus = fFocus;
|
|
||||||
|
|
||||||
// update focus
|
|
||||||
|
|
||||||
if (messenger != NULL) {
|
|
||||||
fFocus = _FindTarget(*messenger);
|
|
||||||
if (fFocus == NULL) {
|
|
||||||
// we need a new target for this focus
|
|
||||||
fFocus = _AddTarget(*messenger);
|
|
||||||
if (fFocus == NULL)
|
|
||||||
printf("EventDispatcher: could not set focus!\n");
|
|
||||||
}
|
|
||||||
if (fFocus != NULL)
|
|
||||||
fFocus->SetFocusOrLastFocus(true);
|
|
||||||
} else
|
|
||||||
fFocus = NULL;
|
fFocus = NULL;
|
||||||
|
if (fPreviousMouseTarget == &target)
|
||||||
|
fPreviousMouseTarget = NULL;
|
||||||
|
|
||||||
fFocusGotExitTransit = true;
|
fTargets.RemoveItem(&target);
|
||||||
fTransit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
EventDispatcher::Target*
|
|
||||||
EventDispatcher::_FindTarget(const BMessenger& messenger, int32* _index)
|
|
||||||
{
|
|
||||||
for (int32 i = fTargets.CountItems(); i-- > 0;) {
|
|
||||||
Target* target = fTargets.ItemAt(i);
|
|
||||||
|
|
||||||
if (target->Messenger() == messenger) {
|
|
||||||
if (_index)
|
|
||||||
*_index = i;
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
EventDispatcher::Target*
|
|
||||||
EventDispatcher::_AddTarget(const BMessenger& messenger)
|
|
||||||
{
|
|
||||||
Target* target = new (std::nothrow) Target(messenger);
|
|
||||||
if (target == NULL) {
|
|
||||||
printf("EventDispatcher: could not create new target!\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool success = fTargets.AddItem(target);
|
|
||||||
if (!success) {
|
|
||||||
printf("EventDispatcher: could not add new target!\n");
|
|
||||||
delete target;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
EventDispatcher::_RemoveTarget(Target* target)
|
|
||||||
{
|
|
||||||
// the list owns its items and will delete the target itself
|
|
||||||
fTargets.RemoveItem(target);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -427,19 +312,15 @@ EventDispatcher::_RemoveTarget(Target* target)
|
|||||||
leaves the event mask untouched and just updates the options.
|
leaves the event mask untouched and just updates the options.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
EventDispatcher::_AddListener(const BMessenger& messenger, int32 token,
|
EventDispatcher::_AddListener(EventTarget& target, int32 token,
|
||||||
uint32 eventMask, uint32 options, bool temporary)
|
uint32 eventMask, uint32 options, bool temporary)
|
||||||
{
|
{
|
||||||
BAutolock _(fListenerLock);
|
BAutolock _(this);
|
||||||
Target* target = _FindTarget(messenger);
|
|
||||||
if (target == NULL) {
|
|
||||||
// we need a new target for this messenger
|
|
||||||
target = _AddTarget(messenger);
|
|
||||||
if (target == NULL)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
event_listener* listener = target->FindListener(token);
|
if (!fTargets.HasItem(&target))
|
||||||
|
fTargets.AddItem(&target);
|
||||||
|
|
||||||
|
event_listener* listener = target.FindListener(token);
|
||||||
if (listener != NULL) {
|
if (listener != NULL) {
|
||||||
// we already have this target, update its event mask
|
// we already have this target, update its event mask
|
||||||
if (temporary) {
|
if (temporary) {
|
||||||
@@ -463,10 +344,10 @@ EventDispatcher::_AddListener(const BMessenger& messenger, int32 token,
|
|||||||
|
|
||||||
// we need a new target
|
// we need a new target
|
||||||
|
|
||||||
bool success = target->AddListener(token, eventMask, options, temporary);
|
bool success = target.AddListener(token, eventMask, options, temporary);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
if (!target->IsNeeded())
|
if (target.IsEmpty())
|
||||||
_RemoveTarget(target);
|
fTargets.RemoveItem(&target);
|
||||||
} else {
|
} else {
|
||||||
if (options & B_SUSPEND_VIEW_FOCUS)
|
if (options & B_SUSPEND_VIEW_FOCUS)
|
||||||
fSuspendFocus = true;
|
fSuspendFocus = true;
|
||||||
@@ -480,7 +361,7 @@ void
|
|||||||
EventDispatcher::_RemoveTemporaryListeners()
|
EventDispatcher::_RemoveTemporaryListeners()
|
||||||
{
|
{
|
||||||
for (int32 i = fTargets.CountItems(); i-- > 0;) {
|
for (int32 i = fTargets.CountItems(); i-- > 0;) {
|
||||||
Target* target = fTargets.ItemAt(i);
|
EventTarget* target = fTargets.ItemAt(i);
|
||||||
|
|
||||||
target->RemoveTemporaryListeners();
|
target->RemoveTemporaryListeners();
|
||||||
}
|
}
|
||||||
@@ -488,61 +369,48 @@ EventDispatcher::_RemoveTemporaryListeners()
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
EventDispatcher::AddListener(const BMessenger& messenger, int32 token,
|
EventDispatcher::AddListener(EventTarget& target, int32 token,
|
||||||
uint32 eventMask, uint32 options)
|
uint32 eventMask, uint32 options)
|
||||||
{
|
{
|
||||||
options &= B_NO_POINTER_HISTORY;
|
options &= B_NO_POINTER_HISTORY;
|
||||||
// that's currently the only allowed option
|
// that's currently the only allowed option
|
||||||
|
|
||||||
return _AddListener(messenger, token, eventMask, options, false);
|
return _AddListener(target, token, eventMask, options, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
EventDispatcher::AddTemporaryListener(const BMessenger& messenger,
|
EventDispatcher::AddTemporaryListener(EventTarget& target,
|
||||||
int32 token, uint32 eventMask, uint32 options)
|
int32 token, uint32 eventMask, uint32 options)
|
||||||
{
|
{
|
||||||
return _AddListener(messenger, token, eventMask, options, true);
|
return _AddListener(target, token, eventMask, options, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
EventDispatcher::RemoveListener(const BMessenger& messenger, int32 token)
|
EventDispatcher::RemoveListener(EventTarget& target, int32 token)
|
||||||
{
|
{
|
||||||
BAutolock _(fListenerLock);
|
BAutolock _(this);
|
||||||
ETRACE(("events: remove listener token %ld\n", token));
|
ETRACE(("events: remove listener token %ld\n", token));
|
||||||
|
|
||||||
int32 index;
|
if (target.RemoveListener(token) && target.IsEmpty())
|
||||||
Target* target = _FindTarget(messenger, &index);
|
fTargets.RemoveItem(&target);
|
||||||
if (target == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (target->RemoveListener(token) && !target->IsNeeded()) {
|
|
||||||
fTargets.RemoveItemAt(index);
|
|
||||||
delete target;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
EventDispatcher::RemoveTemporaryListener(const BMessenger& messenger, int32 token)
|
EventDispatcher::RemoveTemporaryListener(EventTarget& target, int32 token)
|
||||||
{
|
{
|
||||||
BAutolock _(fListenerLock);
|
BAutolock _(this);
|
||||||
|
ETRACE(("events: remove temporary listener token %ld\n", token));
|
||||||
|
|
||||||
int32 index;
|
if (target.RemoveTemporaryListener(token) && target.IsEmpty())
|
||||||
Target* target = _FindTarget(messenger, &index);
|
fTargets.RemoveItem(&target);
|
||||||
if (target == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (target->RemoveTemporaryListener(token) && !target->IsNeeded()) {
|
|
||||||
fTargets.RemoveItemAt(index);
|
|
||||||
delete target;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
EventDispatcher::SetMouseFilter(BMessageFilter* filter)
|
EventDispatcher::SetMouseFilter(EventFilter* filter)
|
||||||
{
|
{
|
||||||
BAutolock _(this);
|
BAutolock _(this);
|
||||||
|
|
||||||
@@ -555,7 +423,7 @@ EventDispatcher::SetMouseFilter(BMessageFilter* filter)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
EventDispatcher::SetKeyboardFilter(BMessageFilter* filter)
|
EventDispatcher::SetKeyboardFilter(EventFilter* filter)
|
||||||
{
|
{
|
||||||
BAutolock _(this);
|
BAutolock _(this);
|
||||||
|
|
||||||
@@ -633,13 +501,10 @@ EventDispatcher::_SendMessage(BMessenger& messenger, BMessage* message,
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
EventDispatcher::_AddTokens(BMessage* message, Target* target, uint32 eventMask)
|
EventDispatcher::_AddTokens(BMessage* message, EventTarget* target, uint32 eventMask)
|
||||||
{
|
{
|
||||||
_RemoveTokens(message);
|
_RemoveTokens(message);
|
||||||
|
|
||||||
BAutolock _(fListenerLock);
|
|
||||||
// temporary lock
|
|
||||||
|
|
||||||
int32 count = target->CountListeners();
|
int32 count = target->CountListeners();
|
||||||
for (int32 i = count; i-- > 0;) {
|
for (int32 i = count; i-- > 0;) {
|
||||||
event_listener* listener = target->ListenerAt(i);
|
event_listener* listener = target->ListenerAt(i);
|
||||||
@@ -696,7 +561,8 @@ EventDispatcher::_EventLoop()
|
|||||||
|
|
||||||
BAutolock _(this);
|
BAutolock _(this);
|
||||||
|
|
||||||
bool sendToLastFocus = false;
|
EventTarget* current = NULL;
|
||||||
|
EventTarget* previous = NULL;
|
||||||
bool pointerEvent = false;
|
bool pointerEvent = false;
|
||||||
bool keyboardEvent = false;
|
bool keyboardEvent = false;
|
||||||
bool addedTokens = false;
|
bool addedTokens = false;
|
||||||
@@ -704,45 +570,37 @@ EventDispatcher::_EventLoop()
|
|||||||
switch (event->what) {
|
switch (event->what) {
|
||||||
case B_MOUSE_MOVED:
|
case B_MOUSE_MOVED:
|
||||||
{
|
{
|
||||||
|
BPoint where;
|
||||||
|
if (event->FindPoint("where", &where) == B_OK)
|
||||||
|
fLastCursorPosition = where;
|
||||||
|
|
||||||
if (!HasCursorThread()) {
|
if (!HasCursorThread()) {
|
||||||
// there is no cursor thread, we need to move the cursor ourselves
|
// there is no cursor thread, we need to move the cursor ourselves
|
||||||
BAutolock _(fCursorLock);
|
BAutolock _(fCursorLock);
|
||||||
|
|
||||||
BPoint where;
|
if (fHWInterface != NULL) {
|
||||||
if (fHWInterface != NULL && event->FindPoint("where", &where) == B_OK)
|
fHWInterface->MoveCursorTo(fLastCursorPosition.x,
|
||||||
fHWInterface->MoveCursorTo(where.x, where.y);
|
fLastCursorPosition.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fTransit) {
|
|
||||||
// target has changed, we need to add the be:transit field
|
|
||||||
// to the message
|
|
||||||
if (fLastFocus != NULL) {
|
|
||||||
addedTokens = _AddTokens(event, fLastFocus, B_POINTER_EVENTS);
|
|
||||||
_SendMessage(fLastFocus->Messenger(), event,
|
|
||||||
kMouseTransitImportance);
|
|
||||||
sendToLastFocus = true;
|
|
||||||
|
|
||||||
// we no longer need the last focus messenger
|
|
||||||
_UnsetLastFocus();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fTransit = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
BPoint where;
|
|
||||||
if (event->FindPoint("where", &where) == B_OK)
|
|
||||||
fLastCursorPosition = where;
|
|
||||||
|
|
||||||
// supposed to fall through
|
// supposed to fall through
|
||||||
}
|
}
|
||||||
case B_MOUSE_DOWN:
|
case B_MOUSE_DOWN:
|
||||||
case B_MOUSE_UP:
|
case B_MOUSE_UP:
|
||||||
|
{
|
||||||
#ifdef TRACE_EVENTS
|
#ifdef TRACE_EVENTS
|
||||||
if (event->what != B_MOUSE_MOVED)
|
if (event->what != B_MOUSE_MOVED)
|
||||||
printf("mouse up/down event, focus = %p\n", fFocus);
|
printf("mouse up/down event, previous target = %p\n", fPreviousMouseTarget);
|
||||||
#endif
|
#endif
|
||||||
if (fMouseFilter != NULL
|
pointerEvent = true;
|
||||||
&& fMouseFilter->Filter(event, NULL) == B_SKIP_MESSAGE) {
|
|
||||||
|
if (fMouseFilter == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
EventTarget* mouseTarget = fPreviousMouseTarget;
|
||||||
|
int32 viewToken = B_NULL_TOKEN;
|
||||||
|
if (fMouseFilter->Filter(event, &mouseTarget, &viewToken) == B_SKIP_MESSAGE) {
|
||||||
// this is a work-around if the wrong B_MOUSE_UP
|
// this is a work-around if the wrong B_MOUSE_UP
|
||||||
// event is filtered out
|
// event is filtered out
|
||||||
if (event->what == B_MOUSE_UP) {
|
if (event->what == B_MOUSE_UP) {
|
||||||
@@ -763,31 +621,30 @@ EventDispatcher::_EventLoop()
|
|||||||
event->RemoveName("where");
|
event->RemoveName("where");
|
||||||
event->AddPoint("screen_where", fLastCursorPosition);
|
event->AddPoint("screen_where", fLastCursorPosition);
|
||||||
|
|
||||||
pointerEvent = true;
|
if (event->what == B_MOUSE_MOVED
|
||||||
|
&& fPreviousMouseTarget != NULL
|
||||||
if (fFocus != NULL) {
|
&& mouseTarget != fPreviousMouseTarget) {
|
||||||
int32 viewToken;
|
// target has changed, we need to notify the previous target
|
||||||
|
// that the mouse has exited its views
|
||||||
addedTokens |= _AddTokens(event, fFocus, B_POINTER_EVENTS);
|
addedTokens = _AddTokens(event, fPreviousMouseTarget,
|
||||||
if (addedTokens)
|
B_POINTER_EVENTS);
|
||||||
_SetFeedFocus(event);
|
_SendMessage(fPreviousMouseTarget->Messenger(), event,
|
||||||
else if (fFocusGotExitTransit) {
|
kMouseTransitImportance);
|
||||||
// TODO: this is a temporary hack to not continue to
|
previous = fPreviousMouseTarget;
|
||||||
// send mouse messages to the client when the mouse
|
|
||||||
// pointer is not over it
|
|
||||||
if (event->FindInt32("_view_token", &viewToken) != B_OK)
|
|
||||||
break;
|
|
||||||
|
|
||||||
fFocusGotExitTransit = false;
|
|
||||||
} else if (event->what == B_MOUSE_MOVED) {
|
|
||||||
if (event->FindInt32("_view_token", &viewToken) != B_OK)
|
|
||||||
fFocusGotExitTransit = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_SendMessage(fFocus->Messenger(), event, event->what == B_MOUSE_MOVED
|
current = fPreviousMouseTarget = mouseTarget;
|
||||||
|
|
||||||
|
if (current != NULL) {
|
||||||
|
addedTokens |= _AddTokens(event, current, B_POINTER_EVENTS);
|
||||||
|
if (viewToken != B_NULL_TOKEN)
|
||||||
|
event->AddInt32("_view_token", viewToken);
|
||||||
|
|
||||||
|
_SendMessage(current->Messenger(), event, event->what == B_MOUSE_MOVED
|
||||||
? kMouseMovedImportance : kStandardImportance);
|
? kMouseMovedImportance : kStandardImportance);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case B_KEY_DOWN:
|
case B_KEY_DOWN:
|
||||||
case B_KEY_UP:
|
case B_KEY_UP:
|
||||||
@@ -797,12 +654,12 @@ EventDispatcher::_EventLoop()
|
|||||||
ETRACE(("key event, focus = %p\n", fFocus));
|
ETRACE(("key event, focus = %p\n", fFocus));
|
||||||
|
|
||||||
if (fKeyboardFilter != NULL
|
if (fKeyboardFilter != NULL
|
||||||
&& fKeyboardFilter->Filter(event, NULL) == B_SKIP_MESSAGE)
|
&& fKeyboardFilter->Filter(event, &fFocus) == B_SKIP_MESSAGE)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
keyboardEvent = true;
|
keyboardEvent = true;
|
||||||
|
|
||||||
if (fFocus != NULL && _AddTokens(event, fFocus, B_KEYBOARD_EVENTS)) {
|
if (current != NULL && _AddTokens(event, fFocus, B_KEYBOARD_EVENTS)) {
|
||||||
// if tokens were added, we need to explicetly suspend
|
// if tokens were added, we need to explicetly suspend
|
||||||
// focus in the event - if not, the event is simply not
|
// focus in the event - if not, the event is simply not
|
||||||
// forwarded to the target
|
// forwarded to the target
|
||||||
@@ -815,8 +672,10 @@ EventDispatcher::_EventLoop()
|
|||||||
// supposed to fall through
|
// supposed to fall through
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (fFocus != NULL && (!fSuspendFocus || addedTokens))
|
current = fFocus;
|
||||||
_SendMessage(fFocus->Messenger(), event, kStandardImportance);
|
|
||||||
|
if (current != NULL && (!fSuspendFocus || addedTokens))
|
||||||
|
_SendMessage(current->Messenger(), event, kStandardImportance);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -833,13 +692,11 @@ EventDispatcher::_EventLoop()
|
|||||||
event->RemoveName("_view_token");
|
event->RemoveName("_view_token");
|
||||||
}
|
}
|
||||||
|
|
||||||
BAutolock _temp(fListenerLock);
|
|
||||||
|
|
||||||
for (int32 i = fTargets.CountItems(); i-- > 0;) {
|
for (int32 i = fTargets.CountItems(); i-- > 0;) {
|
||||||
Target* target = fTargets.ItemAt(i);
|
EventTarget* target = fTargets.ItemAt(i);
|
||||||
|
|
||||||
// we already sent the event to the all focus and last focus tokens
|
// we already sent the event to the all focus and last focus tokens
|
||||||
if (fFocus == target || (sendToLastFocus && fLastFocus == target))
|
if (current == target || previous == target)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// don't send the message if there are no tokens for this event
|
// don't send the message if there are no tokens for this event
|
||||||
@@ -851,7 +708,6 @@ EventDispatcher::_EventLoop()
|
|||||||
? kMouseMovedImportance : kListenerImportance)) {
|
? kMouseMovedImportance : kListenerImportance)) {
|
||||||
// the target doesn't seem to exist anymore, let's remove it
|
// the target doesn't seem to exist anymore, let's remove it
|
||||||
fTargets.RemoveItemAt(i);
|
fTargets.RemoveItemAt(i);
|
||||||
delete target;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,14 +10,52 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <Locker.h>
|
#include <Locker.h>
|
||||||
|
#include <MessageFilter.h>
|
||||||
#include <Messenger.h>
|
#include <Messenger.h>
|
||||||
#include <ObjectList.h>
|
#include <ObjectList.h>
|
||||||
|
|
||||||
class BMessageFilter;
|
|
||||||
|
|
||||||
class EventStream;
|
class EventStream;
|
||||||
class HWInterface;
|
class HWInterface;
|
||||||
|
|
||||||
|
struct event_listener;
|
||||||
|
|
||||||
|
|
||||||
|
class EventTarget {
|
||||||
|
public:
|
||||||
|
EventTarget();
|
||||||
|
~EventTarget();
|
||||||
|
|
||||||
|
void SetTo(const BMessenger& messenger);
|
||||||
|
BMessenger& Messenger() { return fMessenger; }
|
||||||
|
|
||||||
|
event_listener* FindListener(int32 token, int32* _index = NULL);
|
||||||
|
bool AddListener(int32 token, uint32 eventMask, uint32 options,
|
||||||
|
bool temporary);
|
||||||
|
void RemoveListener(event_listener* listener, bool temporary);
|
||||||
|
|
||||||
|
bool RemoveListener(int32 token);
|
||||||
|
bool RemoveTemporaryListener(int32 token);
|
||||||
|
void RemoveTemporaryListeners();
|
||||||
|
|
||||||
|
bool IsEmpty() const { return fListeners.IsEmpty(); }
|
||||||
|
|
||||||
|
int32 CountListeners() const { return fListeners.CountItems(); }
|
||||||
|
event_listener* ListenerAt(int32 index) const
|
||||||
|
{ return fListeners.ItemAt(index); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _RemoveTemporaryListener(event_listener* listener, int32 index);
|
||||||
|
|
||||||
|
BObjectList<event_listener> fListeners;
|
||||||
|
BMessenger fMessenger;
|
||||||
|
};
|
||||||
|
|
||||||
|
class EventFilter {
|
||||||
|
public:
|
||||||
|
virtual filter_result Filter(BMessage* event, EventTarget** _target,
|
||||||
|
int32* _viewToken = NULL) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
class EventDispatcher : public BLocker {
|
class EventDispatcher : public BLocker {
|
||||||
public:
|
public:
|
||||||
@@ -27,17 +65,17 @@ class EventDispatcher : public BLocker {
|
|||||||
status_t SetTo(EventStream* stream);
|
status_t SetTo(EventStream* stream);
|
||||||
status_t InitCheck();
|
status_t InitCheck();
|
||||||
|
|
||||||
void SetFocus(const BMessenger* messenger);
|
void RemoveTarget(EventTarget& target);
|
||||||
|
|
||||||
bool AddListener(const BMessenger& messenger, int32 token,
|
bool AddListener(EventTarget& target, int32 token,
|
||||||
uint32 eventMask, uint32 options);
|
uint32 eventMask, uint32 options);
|
||||||
bool AddTemporaryListener(const BMessenger& messenger,
|
bool AddTemporaryListener(EventTarget& target,
|
||||||
int32 token, uint32 eventMask, uint32 options);
|
int32 token, uint32 eventMask, uint32 options);
|
||||||
void RemoveListener(const BMessenger& messenger, int32 token);
|
void RemoveListener(EventTarget& target, int32 token);
|
||||||
void RemoveTemporaryListener(const BMessenger& messenger, int32 token);
|
void RemoveTemporaryListener(EventTarget& target, int32 token);
|
||||||
|
|
||||||
void SetMouseFilter(BMessageFilter* filter);
|
void SetMouseFilter(EventFilter* filter);
|
||||||
void SetKeyboardFilter(BMessageFilter* filter);
|
void SetKeyboardFilter(EventFilter* filter);
|
||||||
|
|
||||||
void GetMouse(BPoint& where, int32& buttons);
|
void GetMouse(BPoint& where, int32& buttons);
|
||||||
|
|
||||||
@@ -45,26 +83,20 @@ class EventDispatcher : public BLocker {
|
|||||||
void SetHWInterface(HWInterface* interface);
|
void SetHWInterface(HWInterface* interface);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct event_listener;
|
|
||||||
class Target;
|
|
||||||
|
|
||||||
status_t _Run();
|
status_t _Run();
|
||||||
void _Unset();
|
void _Unset();
|
||||||
|
|
||||||
bool _SendMessage(BMessenger& messenger, BMessage* message, float importance);
|
bool _SendMessage(BMessenger& messenger, BMessage* message, float importance);
|
||||||
|
|
||||||
bool _AddTokens(BMessage* message, Target* target, uint32 eventMask);
|
bool _AddTokens(BMessage* message, EventTarget* target, uint32 eventMask);
|
||||||
void _RemoveTokens(BMessage* message);
|
void _RemoveTokens(BMessage* message);
|
||||||
void _SetFeedFocus(BMessage* message);
|
void _SetFeedFocus(BMessage* message);
|
||||||
void _UnsetFeedFocus(BMessage* message);
|
void _UnsetFeedFocus(BMessage* message);
|
||||||
|
|
||||||
void _UnsetLastFocus();
|
void _SetMouseTarget(const BMessenger* messenger);
|
||||||
|
void _UnsetLastMouseTarget();
|
||||||
|
|
||||||
Target* _FindTarget(const BMessenger& messenger, int32* _index = NULL);
|
bool _AddListener(EventTarget& target, int32 token,
|
||||||
Target* _AddTarget(const BMessenger& messenger);
|
|
||||||
void _RemoveTarget(Target* target);
|
|
||||||
|
|
||||||
bool _AddListener(const BMessenger& messenger, int32 token,
|
|
||||||
uint32 eventMask, uint32 options, bool temporary);
|
uint32 eventMask, uint32 options, bool temporary);
|
||||||
void _RemoveTemporaryListeners();
|
void _RemoveTemporaryListeners();
|
||||||
|
|
||||||
@@ -79,22 +111,18 @@ class EventDispatcher : public BLocker {
|
|||||||
thread_id fThread;
|
thread_id fThread;
|
||||||
thread_id fCursorThread;
|
thread_id fCursorThread;
|
||||||
|
|
||||||
Target* fFocus;
|
EventTarget* fPreviousMouseTarget;
|
||||||
Target* fLastFocus;
|
EventTarget* fFocus;
|
||||||
bool fTransit;
|
|
||||||
bool fFocusGotExitTransit;
|
|
||||||
bool fSuspendFocus;
|
bool fSuspendFocus;
|
||||||
|
|
||||||
BMessageFilter* fMouseFilter;
|
EventFilter* fMouseFilter;
|
||||||
BMessageFilter* fKeyboardFilter;
|
EventFilter* fKeyboardFilter;
|
||||||
|
|
||||||
BObjectList<Target> fTargets;
|
BObjectList<EventTarget> fTargets;
|
||||||
|
|
||||||
BPoint fLastCursorPosition;
|
BPoint fLastCursorPosition;
|
||||||
int32 fLastButtons;
|
int32 fLastButtons;
|
||||||
|
|
||||||
BLocker fListenerLock;
|
|
||||||
// temporary locker until we have an actual locking model
|
|
||||||
BLocker fCursorLock;
|
BLocker fCursorLock;
|
||||||
HWInterface* fHWInterface;
|
HWInterface* fHWInterface;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -834,26 +834,23 @@ Layer::CopyBits(BRect& src, BRect& dst, int32 xOffset, int32 yOffset)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Layer::MouseDown(BMessage *msg, BPoint where)
|
Layer::MouseDown(BMessage *msg, BPoint where, int32* _viewToken)
|
||||||
{
|
{
|
||||||
|
*_viewToken = ViewToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Layer::MouseUp(BMessage *msg, BPoint where)
|
Layer::MouseUp(BMessage *msg, BPoint where, int32* _viewToken)
|
||||||
{
|
{
|
||||||
|
*_viewToken = ViewToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Layer::MouseMoved(BMessage *msg, BPoint where)
|
Layer::MouseMoved(BMessage *msg, BPoint where, int32* _viewToken)
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Layer::MouseWheelChanged(BMessage *msg, BPoint where)
|
|
||||||
{
|
{
|
||||||
|
*_viewToken = ViewToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -151,10 +151,9 @@ class Layer {
|
|||||||
int32 xOffset, int32 yOffset);
|
int32 xOffset, int32 yOffset);
|
||||||
|
|
||||||
// input handling
|
// input handling
|
||||||
virtual void MouseDown(BMessage *msg, BPoint where);
|
virtual void MouseDown(BMessage *msg, BPoint where, int32* _viewToken);
|
||||||
virtual void MouseUp(BMessage *msg, BPoint where);
|
virtual void MouseUp(BMessage *msg, BPoint where, int32* _viewToken);
|
||||||
virtual void MouseMoved(BMessage *msg, BPoint where);
|
virtual void MouseMoved(BMessage *msg, BPoint where, int32* _viewToken);
|
||||||
virtual void MouseWheelChanged(BMessage *msg, BPoint where);
|
|
||||||
|
|
||||||
virtual void WorkspaceActivated(int32 index, bool active);
|
virtual void WorkspaceActivated(int32 index, bool active);
|
||||||
virtual void WorkspacesChanged(uint32 oldWorkspaces, uint32 newWorkspaces);
|
virtual void WorkspacesChanged(uint32 oldWorkspaces, uint32 newWorkspaces);
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ RootLayer::RootLayer(const char *name, Desktop *desktop, DrawingEngine *driver)
|
|||||||
: Layer(BRect(0, 0, 0, 0), name, 0, B_FOLLOW_ALL, B_WILL_DRAW, driver),
|
: Layer(BRect(0, 0, 0, 0), name, 0, B_FOLLOW_ALL, B_WILL_DRAW, driver),
|
||||||
fDesktop(desktop),
|
fDesktop(desktop),
|
||||||
fDragMessage(NULL),
|
fDragMessage(NULL),
|
||||||
fMouseEventLayer(NULL),
|
fMouseEventWindow(NULL),
|
||||||
fAllRegionsLock("root layer region lock"),
|
fAllRegionsLock("root layer region lock"),
|
||||||
|
|
||||||
fDirtyForRedraw(),
|
fDirtyForRedraw(),
|
||||||
@@ -172,20 +172,15 @@ RootLayer::_SetFocus(WindowLayer* focus, BRegion& update)
|
|||||||
|
|
||||||
if (fFocus != NULL) {
|
if (fFocus != NULL) {
|
||||||
update.Include(&fFocus->VisibleRegion());
|
update.Include(&fFocus->VisibleRegion());
|
||||||
//fFocus->SetFocus(false);
|
fFocus->SetFocus(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
fFocus = focus;
|
fFocus = focus;
|
||||||
|
|
||||||
if (focus != NULL) {
|
if (focus != NULL) {
|
||||||
// TODO: the unlocking is evil, but there is currently no cleaner way to do this, ugh...
|
|
||||||
// (this is also responsible for an occasional crash on quit)
|
|
||||||
Unlock();
|
|
||||||
fDesktop->EventDispatcher().SetFocus(&focus->Window()->FocusMessenger());
|
|
||||||
Lock();
|
|
||||||
update.Include(&focus->VisibleRegion());
|
update.Include(&focus->VisibleRegion());
|
||||||
} else
|
focus->SetFocus(true);
|
||||||
fDesktop->EventDispatcher().SetFocus(NULL);
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -194,6 +189,8 @@ RootLayer::_SetFocus(WindowLayer* focus, BRegion& update)
|
|||||||
bool
|
bool
|
||||||
RootLayer::SetFocus(WindowLayer* focus)
|
RootLayer::SetFocus(WindowLayer* focus)
|
||||||
{
|
{
|
||||||
|
BAutolock _(fAllRegionsLock);
|
||||||
|
|
||||||
BRegion update;
|
BRegion update;
|
||||||
bool success = _SetFocus(focus, update);
|
bool success = _SetFocus(focus, update);
|
||||||
if (!success)
|
if (!success)
|
||||||
@@ -524,15 +521,15 @@ RootLayer::_WindowsChanged(BRegion& region)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Layer*
|
WindowLayer*
|
||||||
RootLayer::_ChildAt(BPoint where)
|
RootLayer::WindowAt(BPoint where)
|
||||||
{
|
{
|
||||||
if (VisibleRegion().Contains(where))
|
if (VisibleRegion().Contains(where))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (Layer* child = LastChild(); child; child = child->PreviousLayer()) {
|
for (Layer* child = LastChild(); child; child = child->PreviousLayer()) {
|
||||||
if (child->FullVisible().Contains(where))
|
if (child->FullVisible().Contains(where))
|
||||||
return child;
|
return dynamic_cast<WindowLayer*>(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -543,48 +540,17 @@ RootLayer::_ChildAt(BPoint where)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
RootLayer::MouseEventHandler(BMessage *event)
|
RootLayer::SetMouseEventWindow(WindowLayer* window)
|
||||||
{
|
{
|
||||||
BPoint where;
|
fMouseEventWindow = window;
|
||||||
if (event->FindPoint("where", &where) != B_OK)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Layer* layer = fMouseEventLayer;
|
|
||||||
if (layer == NULL) {
|
|
||||||
layer = _ChildAt(where);
|
|
||||||
if (layer == NULL)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (event->what) {
|
|
||||||
case B_MOUSE_DOWN:
|
|
||||||
layer->MouseDown(event, where);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_MOUSE_UP:
|
|
||||||
layer->MouseUp(event, where);
|
|
||||||
SetMouseEventLayer(NULL);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_MOUSE_MOVED:
|
|
||||||
layer->MouseMoved(event, where);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
RootLayer::SetMouseEventLayer(Layer* layer)
|
|
||||||
{
|
|
||||||
fMouseEventLayer = layer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
RootLayer::LayerRemoved(Layer* layer)
|
RootLayer::LayerRemoved(Layer* layer)
|
||||||
{
|
{
|
||||||
if (fMouseEventLayer == layer)
|
if (fMouseEventWindow == layer)
|
||||||
fMouseEventLayer = NULL;
|
fMouseEventWindow = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ class RootLayer : public Layer {
|
|||||||
void HideWindowLayer(WindowLayer* windowLayer);
|
void HideWindowLayer(WindowLayer* windowLayer);
|
||||||
void ShowWindowLayer(WindowLayer* windowLayer, bool toFront = true);
|
void ShowWindowLayer(WindowLayer* windowLayer, bool toFront = true);
|
||||||
|
|
||||||
// void RevealNewWMState(Workspace::State &oldWMState);
|
|
||||||
bool SetFocus(WindowLayer* focus);
|
bool SetFocus(WindowLayer* focus);
|
||||||
WindowLayer* Focus() const { return fFocus; }
|
WindowLayer* Focus() const { return fFocus; }
|
||||||
WindowLayer* Front() const { return fFront; }
|
WindowLayer* Front() const { return fFront; }
|
||||||
@@ -67,15 +66,13 @@ class RootLayer : public Layer {
|
|||||||
void SetWorkspacesLayer(Layer* layer) { fWorkspacesLayer = layer; }
|
void SetWorkspacesLayer(Layer* layer) { fWorkspacesLayer = layer; }
|
||||||
Layer* WorkspacesLayer() const { return fWorkspacesLayer; }
|
Layer* WorkspacesLayer() const { return fWorkspacesLayer; }
|
||||||
|
|
||||||
#if 0
|
|
||||||
void SetBGColor(const RGBColor &col);
|
|
||||||
RGBColor BGColor(void) const;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void SetDragMessage(BMessage *msg);
|
void SetDragMessage(BMessage *msg);
|
||||||
BMessage* DragMessage() const;
|
BMessage* DragMessage() const;
|
||||||
|
|
||||||
void SetMouseEventLayer(Layer* layer);
|
WindowLayer* WindowAt(BPoint where);
|
||||||
|
|
||||||
|
WindowLayer* MouseEventWindow() const { return fMouseEventWindow; }
|
||||||
|
void SetMouseEventWindow(WindowLayer* layer);
|
||||||
|
|
||||||
void LayerRemoved(Layer* layer);
|
void LayerRemoved(Layer* layer);
|
||||||
|
|
||||||
@@ -100,8 +97,6 @@ class RootLayer : public Layer {
|
|||||||
void AddWindowLayer(WindowLayer* windowLayer);
|
void AddWindowLayer(WindowLayer* windowLayer);
|
||||||
void RemoveWindowLayer(WindowLayer* windowLayer);
|
void RemoveWindowLayer(WindowLayer* windowLayer);
|
||||||
|
|
||||||
void MouseEventHandler(BMessage *msg);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _SetFocus(WindowLayer* focus, BRegion& update);
|
bool _SetFocus(WindowLayer* focus, BRegion& update);
|
||||||
void _SetFront(WindowLayer* front, BRegion& update);
|
void _SetFront(WindowLayer* front, BRegion& update);
|
||||||
@@ -112,11 +107,9 @@ class RootLayer : public Layer {
|
|||||||
void _WindowsChanged(BRegion& region);
|
void _WindowsChanged(BRegion& region);
|
||||||
void _UpdateWorkspace(Workspace& workspace);
|
void _UpdateWorkspace(Workspace& workspace);
|
||||||
|
|
||||||
Layer* _ChildAt(BPoint where);
|
|
||||||
|
|
||||||
Desktop* fDesktop;
|
Desktop* fDesktop;
|
||||||
BMessage* fDragMessage;
|
BMessage* fDragMessage;
|
||||||
Layer* fMouseEventLayer;
|
WindowLayer* fMouseEventWindow;
|
||||||
|
|
||||||
BLocker fAllRegionsLock;
|
BLocker fAllRegionsLock;
|
||||||
|
|
||||||
|
|||||||
@@ -159,6 +159,8 @@ ServerWindow::ServerWindow(const char *title, ServerApp *app,
|
|||||||
BMessenger::Private(fHandlerMessenger).SetTo(fClientTeam,
|
BMessenger::Private(fHandlerMessenger).SetTo(fClientTeam,
|
||||||
looperPort, clientToken);
|
looperPort, clientToken);
|
||||||
|
|
||||||
|
fEventTarget.SetTo(fFocusMessenger);
|
||||||
|
|
||||||
fDeathSemaphore = create_sem(0, "window death");
|
fDeathSemaphore = create_sem(0, "window death");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -680,7 +682,7 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fCurrentLayer->EventMask() != 0) {
|
if (fCurrentLayer->EventMask() != 0) {
|
||||||
fDesktop->EventDispatcher().RemoveListener(FocusMessenger(),
|
fDesktop->EventDispatcher().RemoveListener(EventTarget(),
|
||||||
fCurrentLayer->ViewToken());
|
fCurrentLayer->ViewToken());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -721,6 +723,8 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
|
|||||||
case AS_LAYER_SET_EVENT_MASK:
|
case AS_LAYER_SET_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()));
|
||||||
|
rootLayer->Unlock();
|
||||||
|
// we don't want RootLayer to be locked while we play with the events
|
||||||
|
|
||||||
uint32 eventMask, options;
|
uint32 eventMask, options;
|
||||||
|
|
||||||
@@ -729,33 +733,38 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
|
|||||||
fCurrentLayer->SetEventMask(eventMask, options);
|
fCurrentLayer->SetEventMask(eventMask, options);
|
||||||
|
|
||||||
if (eventMask != 0 || options != 0) {
|
if (eventMask != 0 || options != 0) {
|
||||||
fDesktop->EventDispatcher().AddListener(FocusMessenger(),
|
fDesktop->EventDispatcher().AddListener(EventTarget(),
|
||||||
fCurrentLayer->ViewToken(), eventMask, options);
|
fCurrentLayer->ViewToken(), eventMask, options);
|
||||||
} else {
|
} else {
|
||||||
fDesktop->EventDispatcher().RemoveListener(FocusMessenger(),
|
fDesktop->EventDispatcher().RemoveListener(EventTarget(),
|
||||||
fCurrentLayer->ViewToken());
|
fCurrentLayer->ViewToken());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rootLayer->Lock();
|
||||||
break;
|
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()));
|
||||||
|
rootLayer->Unlock();
|
||||||
|
// we don't want RootLayer to be locked while we play with the events
|
||||||
|
|
||||||
uint32 eventMask, options;
|
uint32 eventMask, options;
|
||||||
|
|
||||||
link.Read<uint32>(&eventMask);
|
link.Read<uint32>(&eventMask);
|
||||||
if (link.Read<uint32>(&options) == B_OK) {
|
if (link.Read<uint32>(&options) == B_OK) {
|
||||||
if (eventMask != 0 || options != 0) {
|
if (eventMask != 0 || options != 0) {
|
||||||
fDesktop->EventDispatcher().AddTemporaryListener(FocusMessenger(),
|
fDesktop->EventDispatcher().AddTemporaryListener(EventTarget(),
|
||||||
fCurrentLayer->ViewToken(), eventMask, options);
|
fCurrentLayer->ViewToken(), eventMask, options);
|
||||||
} else {
|
} else {
|
||||||
fDesktop->EventDispatcher().RemoveTemporaryListener(FocusMessenger(),
|
fDesktop->EventDispatcher().RemoveTemporaryListener(EventTarget(),
|
||||||
fCurrentLayer->ViewToken());
|
fCurrentLayer->ViewToken());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: support B_LOCK_WINDOW_FOCUS option in RootLayer
|
// TODO: support B_LOCK_WINDOW_FOCUS option in RootLayer
|
||||||
|
rootLayer->Lock();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AS_LAYER_MOVE_TO:
|
case AS_LAYER_MOVE_TO:
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#define SERVER_WINDOW_H
|
#define SERVER_WINDOW_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "EventDispatcher.h"
|
||||||
#include "MessageLooper.h"
|
#include "MessageLooper.h"
|
||||||
|
|
||||||
#include <PortLink.h>
|
#include <PortLink.h>
|
||||||
@@ -59,6 +60,8 @@ public:
|
|||||||
virtual bool Run();
|
virtual bool Run();
|
||||||
virtual port_id MessagePort() const { return fMessagePort; }
|
virtual port_id MessagePort() const { return fMessagePort; }
|
||||||
|
|
||||||
|
::EventTarget& EventTarget() { return fEventTarget; }
|
||||||
|
|
||||||
void ReplaceDecorator();
|
void ReplaceDecorator();
|
||||||
void Show();
|
void Show();
|
||||||
void Hide();
|
void Hide();
|
||||||
@@ -135,6 +138,7 @@ private:
|
|||||||
port_id fClientLooperPort;
|
port_id fClientLooperPort;
|
||||||
BMessenger fFocusMessenger;
|
BMessenger fFocusMessenger;
|
||||||
BMessenger fHandlerMessenger;
|
BMessenger fHandlerMessenger;
|
||||||
|
::EventTarget fEventTarget;
|
||||||
|
|
||||||
BMessage fClientViewsWithInvalidCoords;
|
BMessage fClientViewsWithInvalidCoords;
|
||||||
|
|
||||||
|
|||||||
@@ -70,6 +70,8 @@ WindowLayer::WindowLayer(const BRect &frame,
|
|||||||
fMouseButtons(0),
|
fMouseButtons(0),
|
||||||
fLastMousePosition(-1.0, -1.0),
|
fLastMousePosition(-1.0, -1.0),
|
||||||
|
|
||||||
|
fIsFocus(false),
|
||||||
|
|
||||||
fIsClosing(false),
|
fIsClosing(false),
|
||||||
fIsMinimizing(false),
|
fIsMinimizing(false),
|
||||||
fIsZooming(false),
|
fIsZooming(false),
|
||||||
@@ -148,7 +150,7 @@ WindowLayer::Draw(const BRect& updateRect)
|
|||||||
|
|
||||||
// if we have a visible region, it is decorator's one.
|
// if we have a visible region, it is decorator's one.
|
||||||
if (fDecorator) {
|
if (fDecorator) {
|
||||||
fDecorator->SetFocus(GetRootLayer()->Focus() == this);
|
fDecorator->SetFocus(IsFocus());
|
||||||
fDecorator->Draw(updateRect);
|
fDecorator->Draw(updateRect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -389,7 +391,7 @@ WindowLayer::GetSizeLimits(float* minWidth, float* maxWidth,
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
WindowLayer::MouseDown(BMessage *msg, BPoint where)
|
WindowLayer::MouseDown(BMessage *msg, BPoint where, int32* _viewToken)
|
||||||
{
|
{
|
||||||
Desktop* desktop = Window()->App()->GetDesktop();
|
Desktop* desktop = Window()->App()->GetDesktop();
|
||||||
|
|
||||||
@@ -403,8 +405,8 @@ WindowLayer::MouseDown(BMessage *msg, BPoint where)
|
|||||||
if (fDecorator)
|
if (fDecorator)
|
||||||
action = _ActionFor(msg);
|
action = _ActionFor(msg);
|
||||||
|
|
||||||
// deactivate border buttons on first click(select)
|
// deactivate border buttons on first click (select)
|
||||||
if (GetRootLayer()->Focus() != this && action != DEC_MOVETOBACK
|
if (!IsFocus() && action != DEC_MOVETOBACK
|
||||||
&& action != DEC_RESIZE && action != DEC_SLIDETAB)
|
&& action != DEC_RESIZE && action != DEC_SLIDETAB)
|
||||||
action = DEC_DRAG;
|
action = DEC_DRAG;
|
||||||
|
|
||||||
@@ -454,12 +456,12 @@ WindowLayer::MouseDown(BMessage *msg, BPoint where)
|
|||||||
if (action == DEC_MOVETOBACK) {
|
if (action == DEC_MOVETOBACK) {
|
||||||
desktop->SendBehindWindow(this, NULL);
|
desktop->SendBehindWindow(this, NULL);
|
||||||
} else {
|
} else {
|
||||||
GetRootLayer()->SetMouseEventLayer(this);
|
GetRootLayer()->SetMouseEventWindow(this);
|
||||||
desktop->ActivateWindow(this);
|
desktop->ActivateWindow(this);
|
||||||
}
|
}
|
||||||
} else if (target != NULL) {
|
} else if (target != NULL) {
|
||||||
// clicking a simple Layer.
|
// clicking a simple Layer.
|
||||||
if (GetRootLayer()->Focus() != this) {
|
if (!IsFocus()) {
|
||||||
DesktopSettings desktopSettings(desktop);
|
DesktopSettings desktopSettings(desktop);
|
||||||
|
|
||||||
// not in FFM mode?
|
// not in FFM mode?
|
||||||
@@ -470,14 +472,13 @@ WindowLayer::MouseDown(BMessage *msg, BPoint where)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
msg->AddInt32("_view_token", target->ViewToken());
|
target->MouseDown(msg, where, _viewToken);
|
||||||
target->MouseDown(msg, where);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
WindowLayer::MouseUp(BMessage *msg, BPoint where)
|
WindowLayer::MouseUp(BMessage *msg, BPoint where, int32* _viewToken)
|
||||||
{
|
{
|
||||||
bool invalidate = false;
|
bool invalidate = false;
|
||||||
if (fDecorator) {
|
if (fDecorator) {
|
||||||
@@ -517,15 +518,13 @@ WindowLayer::MouseUp(BMessage *msg, BPoint where)
|
|||||||
fIsSlidingTab = false;
|
fIsSlidingTab = false;
|
||||||
|
|
||||||
Layer* target = LayerAt(where);
|
Layer* target = LayerAt(where);
|
||||||
if (target != NULL && target != this) {
|
if (target != NULL && target != this)
|
||||||
msg->AddInt32("_view_token", target->ViewToken());
|
target->MouseUp(msg, where, _viewToken);
|
||||||
target->MouseUp(msg, where);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
WindowLayer::MouseMoved(BMessage *msg, BPoint where)
|
WindowLayer::MouseMoved(BMessage *msg, BPoint where, int32* _viewToken)
|
||||||
{
|
{
|
||||||
if (fDecorator) {
|
if (fDecorator) {
|
||||||
// TODO: present behavior is not fine!
|
// TODO: present behavior is not fine!
|
||||||
@@ -560,14 +559,12 @@ WindowLayer::MouseMoved(BMessage *msg, BPoint where)
|
|||||||
Desktop* desktop = Window()->App()->GetDesktop();
|
Desktop* desktop = Window()->App()->GetDesktop();
|
||||||
DesktopSettings desktopSettings(desktop);
|
DesktopSettings desktopSettings(desktop);
|
||||||
|
|
||||||
if (desktopSettings.MouseMode() != B_NORMAL_MOUSE && GetRootLayer()->Focus() != this)
|
if (desktopSettings.MouseMode() != B_NORMAL_MOUSE && !IsFocus())
|
||||||
GetRootLayer()->SetFocus(this);
|
GetRootLayer()->SetFocus(this);
|
||||||
|
|
||||||
Layer* target = LayerAt(where);
|
Layer* target = LayerAt(where);
|
||||||
if (target != NULL && target != this) {
|
if (target != NULL && target != this)
|
||||||
msg->AddInt32("_view_token", target->ViewToken());
|
target->MouseMoved(msg, where, _viewToken);
|
||||||
target->MouseMoved(msg, where);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -84,9 +84,9 @@ class WindowLayer : public Layer {
|
|||||||
float* minHeight,
|
float* minHeight,
|
||||||
float* maxHeight) const;
|
float* maxHeight) const;
|
||||||
|
|
||||||
virtual void MouseDown(BMessage *msg, BPoint where);
|
virtual void MouseDown(BMessage *msg, BPoint where, int32* _viewToken);
|
||||||
virtual void MouseUp(BMessage *msg, BPoint where);
|
virtual void MouseUp(BMessage *msg, BPoint where, int32* _viewToken);
|
||||||
virtual void MouseMoved(BMessage *msg, BPoint where);
|
virtual void MouseMoved(BMessage *msg, BPoint where, int32* _viewToken);
|
||||||
|
|
||||||
// click_type ActionFor(const BMessage *msg)
|
// click_type ActionFor(const BMessage *msg)
|
||||||
// { return _ActionFor(evt); }
|
// { return _ActionFor(evt); }
|
||||||
@@ -100,6 +100,9 @@ class WindowLayer : public Layer {
|
|||||||
void UpdateFont();
|
void UpdateFont();
|
||||||
void UpdateScreen();
|
void UpdateScreen();
|
||||||
|
|
||||||
|
bool IsFocus() const { return fIsFocus; }
|
||||||
|
void SetFocus(bool focus) { fIsFocus = focus; }
|
||||||
|
|
||||||
inline Decorator* GetDecorator() const { return fDecorator; }
|
inline Decorator* GetDecorator() const { return fDecorator; }
|
||||||
|
|
||||||
inline int32 Look() const { return fLook; }
|
inline int32 Look() const { return fLook; }
|
||||||
@@ -151,6 +154,8 @@ class WindowLayer : public Layer {
|
|||||||
BPoint fLastMousePosition;
|
BPoint fLastMousePosition;
|
||||||
BPoint fResizingClickOffset;
|
BPoint fResizingClickOffset;
|
||||||
|
|
||||||
|
bool fIsFocus;
|
||||||
|
|
||||||
bool fIsClosing;
|
bool fIsClosing;
|
||||||
bool fIsMinimizing;
|
bool fIsMinimizing;
|
||||||
bool fIsZooming;
|
bool fIsZooming;
|
||||||
|
|||||||
Reference in New Issue
Block a user