Next big step in the event handling:
* RootLayer's mouse event processing is now at its minimum - the EventDispatcher handles them now. As a result, a window will now get only one message per event. * RootLayer adds "_view_token" to mouse moved messages that specify the view currently under the cursor. * There is now a mouse event layer in RootLayer that gets preferred when it's set - this is now used for the window moving instead of the previous mechanism. * changed the previous DistributeMessage() to an UnpackMessage() method following Adi's suggestion. * caveat: some things might be functionally broken in RootLayer now because of removing the mouse notification stuff. * "be:transit" handling is now done completely client side by BWindow::_SanitizeMessage(() (similar to what the input_server does). This should also make the mechanism pretty robust, since every B_MOUSE_MOVED message can now trigger the view transit (in case a message is lost). B_WINDOW_ACTIVATED messages should be generated client side as well. * renamed AS_LAYER_GET_MOUSE_COORDS to AS_GET_MOUSE as it's not a layer specific command, and also gets the mouse buttons. * B_MOUSE_* messages from the up server now contain only a "screen_where" field; "where" (in window's coordinates) and "be:view_where" are added in BMessage::_SanitizeMessage(). * messages that don't have a valid target in the looper are now dropped instead of being sent to the looper - this should be done in BLooper as well, though. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15087 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -226,6 +226,7 @@ public:
|
||||
|
||||
private:
|
||||
typedef BLooper inherited;
|
||||
struct unpack_cookie;
|
||||
class Shortcut;
|
||||
|
||||
friend class BApplication;
|
||||
@@ -267,7 +268,10 @@ private:
|
||||
void AddShortcut(uint32 key, uint32 modifiers,
|
||||
BMenuItem* item);
|
||||
BHandler* _DetermineTarget(BMessage* message, BHandler* target);
|
||||
bool _DistributeMessage(BMessage* message, BHandler* target);
|
||||
bool _UnpackMessage(unpack_cookie& state, BMessage** _message,
|
||||
BHandler** _target, bool* _usePreferred);
|
||||
void _SanitizeMessage(BMessage* message, BHandler* target,
|
||||
bool usePreferred);
|
||||
|
||||
bool InUpdate();
|
||||
void _DequeueAll();
|
||||
|
||||
@@ -186,6 +186,7 @@ enum {
|
||||
AS_RUN_BE_ABOUT,
|
||||
AS_SET_MOUSE_MODE,
|
||||
AS_GET_MOUSE_MODE,
|
||||
AS_GET_MOUSE,
|
||||
|
||||
// Hook function messages
|
||||
AS_WORKSPACE_ACTIVATED,
|
||||
@@ -260,7 +261,6 @@ enum {
|
||||
AS_LAYER_END_RECT_TRACK,
|
||||
AS_LAYER_DRAG_RECT,
|
||||
AS_LAYER_DRAG_IMAGE,
|
||||
AS_LAYER_GET_MOUSE_COORDS,
|
||||
AS_LAYER_SCROLL,
|
||||
AS_LAYER_SET_LINE_MODE,
|
||||
AS_LAYER_GET_LINE_MODE,
|
||||
|
||||
@@ -1353,12 +1353,9 @@ BView::GetMouse(BPoint *location, uint32 *buttons, bool checkMessageQueue)
|
||||
case B_MOUSE_UP:
|
||||
case B_MOUSE_DOWN:
|
||||
case B_MOUSE_MOVED:
|
||||
{
|
||||
msg->FindPoint("where", location);
|
||||
msg->FindPoint("screen_where", location);
|
||||
msg->FindInt32("buttons", (int32 *)buttons);
|
||||
|
||||
// ToDo: the "where" coordinates are screen coordinates
|
||||
// unlike R5 - this might break applications!
|
||||
ConvertFromScreen(location);
|
||||
|
||||
queue->RemoveMessage(msg);
|
||||
@@ -1366,7 +1363,6 @@ BView::GetMouse(BPoint *location, uint32 *buttons, bool checkMessageQueue)
|
||||
|
||||
queue->Unlock();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
queue->Unlock();
|
||||
@@ -1375,8 +1371,8 @@ BView::GetMouse(BPoint *location, uint32 *buttons, bool checkMessageQueue)
|
||||
// If no mouse update message has been found in the message queue,
|
||||
// we get the current mouse location and buttons from the app_server
|
||||
|
||||
fOwner->fLink->StartMessage(AS_LAYER_GET_MOUSE_COORDS);
|
||||
|
||||
fOwner->fLink->StartMessage(AS_GET_MOUSE);
|
||||
|
||||
int32 code;
|
||||
if (fOwner->fLink->FlushWithReply(code) == B_OK
|
||||
&& code == SERVER_TRUE) {
|
||||
|
||||
+226
-117
@@ -43,6 +43,18 @@
|
||||
#endif
|
||||
|
||||
|
||||
struct BWindow::unpack_cookie {
|
||||
unpack_cookie();
|
||||
|
||||
BMessage* message;
|
||||
int32 index;
|
||||
BHandler* focus;
|
||||
int32 focus_token;
|
||||
int32 last_view_token;
|
||||
bool found_focus;
|
||||
bool tokens_scanned;
|
||||
};
|
||||
|
||||
class BWindow::Shortcut {
|
||||
public:
|
||||
Shortcut(uint32 key, uint32 modifiers, BMenuItem* item);
|
||||
@@ -135,6 +147,22 @@ _set_menu_sem_(BWindow *window, sem_id sem)
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
BWindow::unpack_cookie::unpack_cookie()
|
||||
:
|
||||
message((BMessage*)~0UL),
|
||||
// message == NULL is our exit condition
|
||||
index(0),
|
||||
focus_token(B_NULL_TOKEN),
|
||||
last_view_token(B_NULL_TOKEN),
|
||||
found_focus(false),
|
||||
tokens_scanned(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
BWindow::Shortcut::Shortcut(uint32 key, uint32 modifiers, BMenuItem* item)
|
||||
:
|
||||
fKey(PrepareKey(key)),
|
||||
@@ -810,38 +838,24 @@ BWindow::DispatchMessage(BMessage *msg, BHandler *target)
|
||||
case B_MOUSE_DOWN:
|
||||
{
|
||||
BPoint where;
|
||||
uint32 modifiers;
|
||||
uint32 buttons;
|
||||
int32 clicks;
|
||||
msg->FindPoint("where", &where);
|
||||
msg->FindInt32("modifiers", (int32 *)&modifiers);
|
||||
msg->FindInt32("buttons", (int32 *)&buttons);
|
||||
msg->FindInt32("clicks", &clicks);
|
||||
msg->FindPoint("be:view_where", &where);
|
||||
|
||||
if (target && target != this && target != fTopView) {
|
||||
if (BView *view = dynamic_cast<BView *>(target)) {
|
||||
view->ConvertFromScreen(&where);
|
||||
view->MouseDown(where);
|
||||
} else
|
||||
target->MessageReceived(msg);
|
||||
}
|
||||
if (BView *view = dynamic_cast<BView *>(target))
|
||||
view->MouseDown(where);
|
||||
else
|
||||
target->MessageReceived(msg);
|
||||
break;
|
||||
}
|
||||
|
||||
case B_MOUSE_UP:
|
||||
{
|
||||
BPoint where;
|
||||
uint32 modifiers;
|
||||
msg->FindPoint("where", &where);
|
||||
msg->FindInt32("modifiers", (int32 *)&modifiers);
|
||||
msg->FindPoint("be:view_where", &where);
|
||||
|
||||
if (target && target != this && target != fTopView) {
|
||||
if (BView *view = dynamic_cast<BView *>(target)) {
|
||||
view->ConvertFromScreen(&where);
|
||||
view->MouseUp(where);
|
||||
} else
|
||||
target->MessageReceived(msg);
|
||||
}
|
||||
if (BView *view = dynamic_cast<BView *>(target))
|
||||
view->MouseUp(where);
|
||||
else
|
||||
target->MessageReceived(msg);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -850,24 +864,14 @@ BWindow::DispatchMessage(BMessage *msg, BHandler *target)
|
||||
BPoint where;
|
||||
uint32 buttons;
|
||||
uint32 transit;
|
||||
msg->FindPoint("where", &where);
|
||||
msg->FindPoint("be:view_where", &where);
|
||||
msg->FindInt32("buttons", (int32 *)&buttons);
|
||||
msg->FindInt32("transit", (int32 *)&transit);
|
||||
if (target && target != this && target != fTopView) {
|
||||
if (BView *view = dynamic_cast<BView *>(target)) {
|
||||
if (fLastMouseMovedView != view) {
|
||||
if (fLastMouseMovedView) {
|
||||
BPoint p(where);
|
||||
fLastMouseMovedView->ConvertFromScreen(&p);
|
||||
fLastMouseMovedView->MouseMoved(p, B_EXITED_VIEW, NULL);
|
||||
}
|
||||
fLastMouseMovedView = view;
|
||||
}
|
||||
view->ConvertFromScreen(&where);
|
||||
view->MouseMoved(where, transit, NULL);
|
||||
} else
|
||||
target->MessageReceived(msg);
|
||||
}
|
||||
msg->FindInt32("be:transit", (int32 *)&transit);
|
||||
|
||||
if (BView *view = dynamic_cast<BView *>(target))
|
||||
view->MouseMoved(where, transit, NULL);
|
||||
else
|
||||
target->MessageReceived(msg);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2167,36 +2171,39 @@ BWindow::_DequeueAll()
|
||||
}
|
||||
|
||||
|
||||
/*! This here is a nearly full code duplication to BLooper::task_looper()
|
||||
but with one little difference: It uses the _DetermineTarget() method
|
||||
to tell what the later target of a message will be, if no explicit target
|
||||
is supplied.
|
||||
This is important because the app_server sends all events to the preferred
|
||||
handler, and these must be correctly retargeted and eventually distributed
|
||||
to several handlers using _DistributeMessage().
|
||||
/*! This here is an almost complete code duplication to BLooper::task_looper()
|
||||
but with some important differences:
|
||||
a) it uses the _DetermineTarget() method to tell what the later target of
|
||||
a message will be, if no explicit target is supplied.
|
||||
b) it calls _UnpackMessage() and _SanitizeMessage() to duplicate the message
|
||||
to all of its intended targets, and to add all fields the target would
|
||||
expect in such a message.
|
||||
|
||||
This is important because the app_server sends all input events to the
|
||||
preferred handler, and expects them to be correctly distributed to their
|
||||
intended targets.
|
||||
*/
|
||||
void
|
||||
BWindow::task_looper()
|
||||
{
|
||||
STRACE(("info: BWindow::task_looper() started.\n"));
|
||||
|
||||
// Check that looper is locked (should be)
|
||||
// Check that looper is locked (should be)
|
||||
AssertLocked();
|
||||
// Unlock the looper
|
||||
Unlock();
|
||||
|
||||
if (IsLocked())
|
||||
debugger("window must not be locked!");
|
||||
|
||||
// loop: As long as we are not terminating.
|
||||
// loop: As long as we are not terminating.
|
||||
while (!fTerminating) {
|
||||
// TODO: timeout determination algo
|
||||
// Read from message port (how do we determine what the timeout is?)
|
||||
BMessage* msg = MessageFromPort();
|
||||
|
||||
// Did we get a message?
|
||||
// Did we get a message?
|
||||
if (msg) {
|
||||
// Add to queue
|
||||
// Add to queue
|
||||
fQueue->AddMessage(msg);
|
||||
} else
|
||||
continue;
|
||||
@@ -2204,22 +2211,22 @@ BWindow::task_looper()
|
||||
// Get message count from port
|
||||
int32 msgCount = port_count(fMsgPort);
|
||||
for (int32 i = 0; i < msgCount; ++i) {
|
||||
// Read 'count' messages from port (so we will not block)
|
||||
// We use zero as our timeout since we know there is stuff there
|
||||
// Read 'count' messages from port (so we will not block)
|
||||
// We use zero as our timeout since we know there is stuff there
|
||||
msg = MessageFromPort(0);
|
||||
// Add messages to queue
|
||||
// Add messages to queue
|
||||
if (msg)
|
||||
fQueue->AddMessage(msg);
|
||||
}
|
||||
|
||||
// loop: As long as there are messages in the queue and the port is
|
||||
// empty... and we are not terminating, of course.
|
||||
// loop: As long as there are messages in the queue and the port is
|
||||
// empty... and we are not terminating, of course.
|
||||
bool dispatchNextMessage = true;
|
||||
while (!fTerminating && dispatchNextMessage) {
|
||||
// Get next message from queue (assign to fLastMessage)
|
||||
fLastMessage = fQueue->NextMessage();
|
||||
|
||||
// Lock the looper
|
||||
// Lock the looper
|
||||
Lock();
|
||||
if (!fLastMessage) {
|
||||
// No more messages: Unlock the looper and terminate the
|
||||
@@ -2241,40 +2248,41 @@ BWindow::task_looper()
|
||||
B_HANDLER_TOKEN, (void **)&handler);
|
||||
}
|
||||
|
||||
// if a target was given, and we should not use the preferred
|
||||
// handler, we can just use that one
|
||||
if (handler == NULL || usePreferred)
|
||||
handler = _DetermineTarget(fLastMessage, handler);
|
||||
if (!usePreferred || _DistributeMessage(fLastMessage, handler)) {
|
||||
if (handler == NULL)
|
||||
handler = this;
|
||||
|
||||
// Is this a scripting message? (BMessage::HasSpecifiers())
|
||||
if (fLastMessage->HasSpecifiers()) {
|
||||
int32 index = 0;
|
||||
// Make sure the current specifier is kosher
|
||||
if (fLastMessage->GetCurrentSpecifier(&index) == B_OK)
|
||||
handler = resolve_specifier(handler, fLastMessage);
|
||||
}
|
||||
unpack_cookie cookie;
|
||||
while (_UnpackMessage(cookie, &fLastMessage, &handler, &usePreferred)) {
|
||||
// if there is no target handler, the message is dropped
|
||||
if (handler != NULL) {
|
||||
// Is this a scripting message?
|
||||
if (fLastMessage->HasSpecifiers()) {
|
||||
int32 index = 0;
|
||||
// Make sure the current specifier is kosher
|
||||
if (fLastMessage->GetCurrentSpecifier(&index) == B_OK)
|
||||
handler = resolve_specifier(handler, fLastMessage);
|
||||
}
|
||||
|
||||
if (handler) {
|
||||
// Do filtering and dispatch message
|
||||
handler = _TopLevelFilter(fLastMessage, handler);
|
||||
if (handler && handler->Looper() == this)
|
||||
if (handler != NULL)
|
||||
handler = _TopLevelFilter(fLastMessage, handler);
|
||||
|
||||
if (handler != NULL) {
|
||||
_SanitizeMessage(fLastMessage, handler, usePreferred);
|
||||
DispatchMessage(fLastMessage, handler);
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the current message
|
||||
delete fLastMessage;
|
||||
fLastMessage = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Unlock();
|
||||
|
||||
// Delete the current message (fLastMessage)
|
||||
delete fLastMessage;
|
||||
fLastMessage = NULL;
|
||||
|
||||
// Are any messages on the port?
|
||||
// Are any messages on the port?
|
||||
if (port_count(fMsgPort) > 0) {
|
||||
// Do outer loop
|
||||
// Do outer loop
|
||||
dispatchNextMessage = false;
|
||||
}
|
||||
}
|
||||
@@ -2409,8 +2417,6 @@ BWindow::_SetFocus(BView *focusView, bool notifyInputServer)
|
||||
BHandler *
|
||||
BWindow::_DetermineTarget(BMessage *message, BHandler *target)
|
||||
{
|
||||
// TODO: this is mostly guessed; check for correctness.
|
||||
|
||||
switch (message->what) {
|
||||
case B_KEY_DOWN:
|
||||
case B_KEY_UP:
|
||||
@@ -2428,14 +2434,24 @@ BWindow::_DetermineTarget(BMessage *message, BHandler *target)
|
||||
case B_UNMAPPED_KEY_DOWN:
|
||||
case B_UNMAPPED_KEY_UP:
|
||||
case B_MODIFIERS_CHANGED:
|
||||
// these messages will be dispatched by the focus view later
|
||||
// these messages should be dispatched by the focus view
|
||||
return CurrentFocus();
|
||||
|
||||
case B_MOUSE_DOWN:
|
||||
case B_MOUSE_UP:
|
||||
case B_MOUSE_MOVED:
|
||||
case B_MOUSE_WHEEL_CHANGED:
|
||||
// TODO: the app_server should tell us which view is the target
|
||||
// is there a token of the view that is currently under the mouse?
|
||||
int32 token;
|
||||
if (message->FindInt32("_view_token", &token) == B_OK) {
|
||||
BHandler* handler;
|
||||
if (gDefaultTokens.GetToken(token, B_HANDLER_TOKEN,
|
||||
(void**)&handler) == B_OK) {
|
||||
BView* view = dynamic_cast<BView*>(handler);
|
||||
if (view != NULL)
|
||||
return view;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case B_PULSE:
|
||||
@@ -2443,19 +2459,6 @@ BWindow::_DetermineTarget(BMessage *message, BHandler *target)
|
||||
// TODO: test wether R5 will let BView dispatch these messages
|
||||
return this;
|
||||
|
||||
case B_VIEW_RESIZED:
|
||||
case B_VIEW_MOVED:
|
||||
{
|
||||
int32 token;
|
||||
if (message->FindInt32("_token", &token) != B_OK)
|
||||
token = B_NULL_TOKEN;
|
||||
|
||||
BView *view = _FindView(token);
|
||||
if (view)
|
||||
return view;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -2471,44 +2474,150 @@ BWindow::_DetermineTarget(BMessage *message, BHandler *target)
|
||||
Returns \c true in case the message should still be dispatched
|
||||
*/
|
||||
bool
|
||||
BWindow::_DistributeMessage(BMessage* message, BHandler* focus)
|
||||
BWindow::_UnpackMessage(unpack_cookie& cookie, BMessage** _message, BHandler** _target,
|
||||
bool* _usePreferred)
|
||||
{
|
||||
bool foundFocus = false;
|
||||
int32 focusToken = B_NULL_TOKEN;
|
||||
if (focus != NULL)
|
||||
focusToken = _get_object_token_(focus);
|
||||
if (cookie.message == NULL)
|
||||
return false;
|
||||
|
||||
int32 index = 0;
|
||||
int32 token;
|
||||
for (; message->FindInt32("_token", index, &token) == B_OK; index++) {
|
||||
if (token == focusToken)
|
||||
foundFocus = true;
|
||||
if (cookie.index == 0 && !cookie.tokens_scanned) {
|
||||
if (!*_usePreferred) {
|
||||
// we only consider messages targeted at the preferred handler
|
||||
cookie.message = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
// initialize our cookie
|
||||
cookie.message = *_message;
|
||||
cookie.focus = *_target;
|
||||
|
||||
if (cookie.focus != NULL)
|
||||
cookie.focus_token = _get_object_token_(*_target);
|
||||
|
||||
if (fLastMouseMovedView != NULL && cookie.message->what == B_MOUSE_MOVED)
|
||||
cookie.last_view_token = _get_object_token_(fLastMouseMovedView);
|
||||
|
||||
*_usePreferred = false;
|
||||
}
|
||||
|
||||
_DequeueAll();
|
||||
|
||||
// distribute the message to all targets specified in the
|
||||
// message directly (but not to the focus view)
|
||||
|
||||
for (int32 token; !cookie.tokens_scanned
|
||||
&& cookie.message->FindInt32("_token", cookie.index, &token) == B_OK;
|
||||
cookie.index++) {
|
||||
// focus view is preferred and should get its message directly
|
||||
if (token == cookie.focus_token) {
|
||||
cookie.found_focus = true;
|
||||
continue;
|
||||
}
|
||||
if (token == cookie.last_view_token)
|
||||
continue;
|
||||
|
||||
BView* target = _FindView(token);
|
||||
if (target == NULL)
|
||||
continue;
|
||||
|
||||
BMessenger messenger(target);
|
||||
messenger.SendMessage(message);
|
||||
*_message = new BMessage(*cookie.message);
|
||||
*_target = target;
|
||||
cookie.index++;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (index > 0) {
|
||||
if (foundFocus) {
|
||||
// the focus view already got this message
|
||||
return false;
|
||||
}
|
||||
cookie.tokens_scanned = true;
|
||||
|
||||
// if there is a last mouse moved view, and the new focus is
|
||||
// different, the previous view wants to get its B_EXITED_VIEW
|
||||
// message
|
||||
if (cookie.last_view_token != B_NULL_TOKEN && fLastMouseMovedView != cookie.focus) {
|
||||
*_message = new BMessage(*cookie.message);
|
||||
*_target = fLastMouseMovedView;
|
||||
cookie.last_view_token = B_NULL_TOKEN;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cookie.index > 0) {
|
||||
// should this message still be dispatched by the focus view?
|
||||
bool feedFocus;
|
||||
if (message->FindBool("_feed_focus", &feedFocus) != B_OK
|
||||
|| feedFocus == false)
|
||||
if (!cookie.found_focus
|
||||
&& (cookie.message->FindBool("_feed_focus", &feedFocus) != B_OK
|
||||
|| feedFocus == false)) {
|
||||
delete cookie.message;
|
||||
cookie.message = NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
*_message = cookie.message;
|
||||
*_target = cookie.focus;
|
||||
*_usePreferred = true;
|
||||
cookie.message = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BWindow::_SanitizeMessage(BMessage* message, BHandler* target, bool usePreferred)
|
||||
{
|
||||
if (target == NULL)
|
||||
return;
|
||||
|
||||
switch (message->what) {
|
||||
case B_MOUSE_MOVED:
|
||||
case B_MOUSE_UP:
|
||||
case B_MOUSE_DOWN:
|
||||
BPoint where;
|
||||
if (message->FindPoint("screen_where", &where) != B_OK)
|
||||
break;
|
||||
|
||||
// add local window coordinates
|
||||
message->AddPoint("where", ConvertFromScreen(where));
|
||||
|
||||
BView* view = dynamic_cast<BView*>(target);
|
||||
if (view != NULL) {
|
||||
// add local view coordinates
|
||||
message->AddPoint("be:view_where", view->ConvertFromScreen(where));
|
||||
|
||||
// is there a token of the view that is currently under the mouse?
|
||||
BView* viewUnderMouse = NULL;
|
||||
int32 token;
|
||||
if (message->FindInt32("_view_token", &token) == B_OK) {
|
||||
BHandler* handler;
|
||||
if (gDefaultTokens.GetToken(token, B_HANDLER_TOKEN,
|
||||
(void**)&handler) == B_OK)
|
||||
viewUnderMouse = dynamic_cast<BView*>(handler);
|
||||
}
|
||||
|
||||
// add transit information
|
||||
int32 transit;
|
||||
if (message->FindInt32("be:transit", &transit) != B_OK) {
|
||||
if (viewUnderMouse == view) {
|
||||
// the mouse is over the target view
|
||||
if (fLastMouseMovedView != view)
|
||||
transit = B_ENTERED_VIEW;
|
||||
else
|
||||
transit = B_INSIDE_VIEW;
|
||||
} else {
|
||||
// the mouse is not over the target view
|
||||
if (view == fLastMouseMovedView)
|
||||
transit = B_EXITED_VIEW;
|
||||
else
|
||||
transit = B_OUTSIDE_VIEW;
|
||||
}
|
||||
|
||||
message->AddInt32("be:transit", transit);
|
||||
}
|
||||
|
||||
if (usePreferred || viewUnderMouse == NULL)
|
||||
fLastMouseMovedView = viewUnderMouse;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BWindow::_HandleKeyDown(char key, uint32 modifiers)
|
||||
{
|
||||
|
||||
@@ -210,7 +210,7 @@ Desktop::Init()
|
||||
fRootLayer->Lock();
|
||||
fRootLayer->MouseEventHandler(message);
|
||||
fRootLayer->Unlock();
|
||||
return B_SKIP_MESSAGE;
|
||||
return B_DISPATCH_MESSAGE;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
+19
-18
@@ -424,7 +424,7 @@ Layer::SetName(const char* name)
|
||||
fName.SetTo(name);
|
||||
}
|
||||
|
||||
// SetUserClipping
|
||||
|
||||
void
|
||||
Layer::SetUserClipping(const BRegion& region)
|
||||
{
|
||||
@@ -434,7 +434,7 @@ Layer::SetUserClipping(const BRegion& region)
|
||||
_RebuildDrawingRegion();
|
||||
}
|
||||
|
||||
// SetFlags
|
||||
|
||||
void
|
||||
Layer::SetFlags(uint32 flags)
|
||||
{
|
||||
@@ -442,7 +442,15 @@ Layer::SetFlags(uint32 flags)
|
||||
fDrawState->SetSubPixelPrecise(fFlags & B_SUBPIXEL_PRECISE);
|
||||
}
|
||||
|
||||
// Draw
|
||||
|
||||
void
|
||||
Layer::SetEventMask(uint32 eventMask, uint32 options)
|
||||
{
|
||||
fEventMask = eventMask;
|
||||
fEventOptions = options;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Layer::Draw(const BRect &rect)
|
||||
{
|
||||
@@ -823,55 +831,46 @@ Layer::CopyBits(BRect& src, BRect& dst, int32 xOffset, int32 yOffset)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Layer::MouseDown(const BMessage *msg)
|
||||
{
|
||||
if (Window() && !IsTopLayer()) {
|
||||
Window()->SendMessageToClient(msg, fViewToken);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Layer::MouseUp(const BMessage *msg)
|
||||
{
|
||||
if (Window() && !IsTopLayer()) {
|
||||
Window()->SendMessageToClient(msg, fViewToken);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Layer::MouseMoved(const BMessage *msg)
|
||||
{
|
||||
if (Window() && !IsTopLayer()) {
|
||||
Window()->SendMessageToClient(msg, fViewToken);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Layer::MouseWheelChanged(const BMessage *msg)
|
||||
{
|
||||
if (Window() && !IsTopLayer()) {
|
||||
Window()->SendMessageToClient(msg, fViewToken);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Layer::WorkspaceActivated(int32 index, bool active)
|
||||
{
|
||||
// Empty
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Layer::WorkspacesChanged(uint32 oldWorkspaces, uint32 newWorkspaces)
|
||||
{
|
||||
// Empty
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Layer::Activated(bool active)
|
||||
{
|
||||
// Empty
|
||||
}
|
||||
|
||||
|
||||
@@ -881,6 +880,7 @@ Layer::ScrollingOffset() const
|
||||
return fScrollingOffset;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Layer::SetDrawingOrigin(BPoint origin)
|
||||
{
|
||||
@@ -1497,6 +1497,7 @@ Layer::_AllRedraw(const BRegion &invalid)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Layer::_AddToViewsWithInvalidCoords() const
|
||||
{
|
||||
|
||||
@@ -182,15 +182,12 @@ class Layer {
|
||||
DrawingEngine* GetDrawingEngine() const
|
||||
{ return fDriver; }
|
||||
|
||||
// flags
|
||||
void SetEventMask(uint32 eventMask, uint32 options);
|
||||
uint32 EventMask() const
|
||||
{ return fEventMask; }
|
||||
uint32 EventOptions() const
|
||||
{ return fEventOptions; }
|
||||
inline void QuietlySetEventMask(uint32 em)
|
||||
{ fEventMask = em; }
|
||||
inline void QuietlySetEventOptions(uint32 eo)
|
||||
{ fEventOptions = eo; }
|
||||
|
||||
inline uint32 ResizeMode() const
|
||||
{ return fResizeMode; }
|
||||
inline uint32 Flags() const
|
||||
|
||||
+46
-275
@@ -61,17 +61,13 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount,
|
||||
|
||||
fDesktop(desktop),
|
||||
fDragMessage(NULL),
|
||||
fLastLayerUnderMouse(this),
|
||||
fNotifyLayer(NULL),
|
||||
fMouseEventLayer(NULL),
|
||||
fSavedEventMask(0),
|
||||
fSavedEventOptions(0),
|
||||
fAllRegionsLock("root layer region lock"),
|
||||
|
||||
fDirtyForRedraw(),
|
||||
|
||||
fButtons(0),
|
||||
fLastMousePosition(0.0, 0.0),
|
||||
|
||||
fActiveWksIndex(0),
|
||||
fWsCount(0),
|
||||
fWorkspace(new Workspace*[kMaxWorkspaceCount]),
|
||||
@@ -371,18 +367,17 @@ bool RootLayer::SetActiveWorkspace(int32 index)
|
||||
return false;
|
||||
|
||||
// you cannot switch workspaces on R5 if there is an event mask BView
|
||||
if (fNotifyLayer && fNotifyLayer->Owner())
|
||||
return false;
|
||||
// if (fNotifyLayer && fNotifyLayer->Owner())
|
||||
// return false;
|
||||
|
||||
// if you're dragging something you are allowed to change workspaces only if
|
||||
// the Layer being dragged is a B_NORMAL_WINDOW_FEEL WinBorder.
|
||||
WinBorder *draggedWinBorder = dynamic_cast<WinBorder*>(fNotifyLayer);
|
||||
if (fNotifyLayer) {
|
||||
WinBorder *draggedWinBorder = dynamic_cast<WinBorder*>(fMouseEventLayer);
|
||||
if (fMouseEventLayer != NULL) {
|
||||
if (draggedWinBorder) {
|
||||
if (draggedWinBorder->Feel() != B_NORMAL_WINDOW_FEEL)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -478,9 +473,9 @@ RootLayer::SetWinBorderWorskpaces(WinBorder *winBorder, uint32 oldIndex, uint32
|
||||
{
|
||||
// if the active notify Layer is somehow related to winBorder, then
|
||||
// this window/WinBorder is not allowed to leave this workspace.
|
||||
if (fNotifyLayer && (fNotifyLayer == winBorder || fNotifyLayer->Owner() == winBorder)) {
|
||||
newIndex |= (0x00000001UL << fActiveWksIndex);
|
||||
}
|
||||
// TODO: this looks wrong: I doubt the window is supposed to open in two workspaces then
|
||||
// if (fNotifyLayer && (fNotifyLayer == winBorder || fNotifyLayer->Owner() == winBorder))
|
||||
// newIndex |= (0x00000001UL << fActiveWksIndex);
|
||||
|
||||
uint32 localOldIndex = oldIndex;
|
||||
uint32 localNewIndex = newIndex;
|
||||
@@ -851,25 +846,13 @@ RootLayer::SetActive(WinBorder* newActive, bool activate)
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Workspace related methods
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Input related methods
|
||||
//---------------------------------------------------------------------------
|
||||
// #pragma mark - Input related methods
|
||||
|
||||
|
||||
void
|
||||
RootLayer::_ProcessMouseMovedEvent(BMessage *msg)
|
||||
RootLayer::_ProcessMouseMovedEvent(BMessage *msg, BPoint where, Layer* target)
|
||||
{
|
||||
BPoint where(0,0);
|
||||
msg->FindPoint("where", &where);
|
||||
|
||||
Layer* target = LayerAt(where);
|
||||
if (target == NULL) {
|
||||
CRITICAL("RootLayer::_ProcessMouseMovedEvent() 'target' can't be null.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// change focus in FFM mode
|
||||
WinBorder* winBorderTarget = dynamic_cast<WinBorder*>(target);
|
||||
if (winBorderTarget) {
|
||||
@@ -886,266 +869,60 @@ RootLayer::_ProcessMouseMovedEvent(BMessage *msg)
|
||||
}
|
||||
}
|
||||
|
||||
// add the layer under mouse to the list of layers to be notified on mouse moved
|
||||
bool alreadyPresent = fMouseNotificationList.HasItem(target);
|
||||
if (!alreadyPresent)
|
||||
fMouseNotificationList.AddItem(target);
|
||||
target->MouseMoved(msg);
|
||||
}
|
||||
|
||||
int32 count = fMouseNotificationList.CountItems();
|
||||
int32 viewAction;
|
||||
Layer *lay;
|
||||
for (int32 i = 0; i <= count; i++) {
|
||||
lay = static_cast<Layer*>(fMouseNotificationList.ItemAt(i));
|
||||
if (lay) {
|
||||
// set transit state
|
||||
if (lay == target)
|
||||
if (lay == fLastLayerUnderMouse)
|
||||
viewAction = B_INSIDE_VIEW;
|
||||
else
|
||||
viewAction = B_ENTERED_VIEW;
|
||||
else
|
||||
if (lay == fLastLayerUnderMouse)
|
||||
viewAction = B_EXITED_VIEW;
|
||||
else
|
||||
viewAction = B_OUTSIDE_VIEW;
|
||||
|
||||
msg->AddInt32("transit", viewAction);
|
||||
lay->MouseMoved(msg);
|
||||
void
|
||||
RootLayer::MouseEventHandler(BMessage *event)
|
||||
{
|
||||
BPoint where;
|
||||
if (event->FindPoint("where", &where) != B_OK)
|
||||
return;
|
||||
|
||||
Layer* layer = fMouseEventLayer;
|
||||
if (layer == NULL) {
|
||||
if (fWMState.Focus != NULL) {
|
||||
layer = fWMState.Focus->LayerAt(where);
|
||||
if (layer != NULL)
|
||||
event->AddInt32("_view_token", layer->ViewToken());
|
||||
}
|
||||
if (layer == NULL) {
|
||||
layer = LayerAt(where);
|
||||
if (layer == NULL)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!alreadyPresent)
|
||||
fMouseNotificationList.RemoveItem(target);
|
||||
|
||||
fLastLayerUnderMouse = target;
|
||||
fLastMousePosition = where;
|
||||
}
|
||||
|
||||
void
|
||||
RootLayer::MouseEventHandler(BMessage *msg)
|
||||
{
|
||||
switch (msg->what) {
|
||||
case B_MOUSE_DOWN: {
|
||||
//printf("RootLayer::MouseEventHandler(B_MOUSE_DOWN)\n");
|
||||
|
||||
BPoint where(0,0);
|
||||
|
||||
msg->FindPoint("where", &where);
|
||||
// We'll need this so that GetMouse can query for which buttons are down.
|
||||
msg->FindInt32("buttons", &fButtons);
|
||||
|
||||
where.ConstrainTo(Frame());
|
||||
|
||||
if (fLastMousePosition != where) {
|
||||
// If this happens, it's input server's fault.
|
||||
// There might be additional fields an application expects in B_MOUSE_MOVED
|
||||
// message, and in this way it won't get them.
|
||||
int64 when = 0;
|
||||
int32 buttons = 0;
|
||||
|
||||
msg->FindInt64("when", &when);
|
||||
msg->FindInt32("buttons", &buttons);
|
||||
|
||||
BMessage mouseMovedMsg(B_MOUSE_MOVED);
|
||||
mouseMovedMsg.AddInt64("when", when);
|
||||
mouseMovedMsg.AddInt32("buttons", buttons);
|
||||
mouseMovedMsg.AddPoint("where", where);
|
||||
|
||||
_ProcessMouseMovedEvent(msg);
|
||||
}
|
||||
|
||||
if (fLastLayerUnderMouse == NULL) {
|
||||
CRITICAL("RootLayer::MouseEventHandler(B_MOUSE_DOWN) fLastLayerUnderMouse is null!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (fLastLayerUnderMouse == this)
|
||||
break;
|
||||
|
||||
int32 count = fMouseNotificationList.CountItems();
|
||||
Layer *lay;
|
||||
for (int32 i = 0; i <= count; i++) {
|
||||
lay = static_cast<Layer*>(fMouseNotificationList.ItemAt(i));
|
||||
if (lay)
|
||||
// NOTE: testing under R5 shows that it doesn't matter if a window is created
|
||||
// with B_ASYNCHRONOUS_CONTROLS flag or not. B_MOUSE_DOWN is always transmited.
|
||||
lay->MouseDown(msg);
|
||||
}
|
||||
|
||||
// get the pointer for one of the first RootLayer's descendants
|
||||
Layer *primaryTarget = LayerAt(where, false);
|
||||
primaryTarget->MouseDown(msg);
|
||||
|
||||
switch (event->what) {
|
||||
case B_MOUSE_DOWN:
|
||||
layer->MouseDown(event);
|
||||
break;
|
||||
}
|
||||
case B_MOUSE_UP: {
|
||||
//printf("RootLayer::MouseEventHandler(B_MOUSE_UP)\n");
|
||||
|
||||
BPoint where(0,0);
|
||||
|
||||
msg->FindPoint("where", &where);
|
||||
|
||||
where.ConstrainTo(fFrame);
|
||||
|
||||
if (fLastMousePosition != where) {
|
||||
// If this happens, it's input server's fault.
|
||||
// There might be additional fields an application expects in B_MOUSE_MOVED
|
||||
// message, and in this way it won't get them.
|
||||
int64 when = 0;
|
||||
int32 buttons = 0;
|
||||
|
||||
msg->FindInt64("when", &when);
|
||||
msg->FindInt32("buttons", &buttons);
|
||||
|
||||
BMessage mouseMovedMsg(B_MOUSE_MOVED);
|
||||
mouseMovedMsg.AddInt64("when", when);
|
||||
mouseMovedMsg.AddInt32("buttons", buttons);
|
||||
mouseMovedMsg.AddPoint("where", where);
|
||||
|
||||
_ProcessMouseMovedEvent(msg);
|
||||
}
|
||||
|
||||
if (fLastLayerUnderMouse == NULL) {
|
||||
CRITICAL("RootLayer::MouseEventHandler(B_MOUSE_UP) fLastLayerUnderMouse is null!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
bool foundCurrent = fMouseNotificationList.HasItem(fLastLayerUnderMouse);
|
||||
int32 count = fMouseNotificationList.CountItems();
|
||||
Layer *lay;
|
||||
for (int32 i = 0; i <= count; i++) {
|
||||
lay = static_cast<Layer*>(fMouseNotificationList.ItemAt(i));
|
||||
if (lay)
|
||||
lay->MouseUp(msg);
|
||||
}
|
||||
ClearNotifyLayer();
|
||||
|
||||
if (!foundCurrent)
|
||||
fLastLayerUnderMouse->MouseUp(msg);
|
||||
|
||||
// TODO: This is a quick fix to avoid the endless loop with windows created
|
||||
// with the B_ASYNCHRONOUS_CONTROLS flag, but please someone have a look into this.
|
||||
fButtons = 0;
|
||||
|
||||
case B_MOUSE_UP:
|
||||
layer->MouseUp(event);
|
||||
SetMouseEventLayer(NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
case B_MOUSE_MOVED:
|
||||
_ProcessMouseMovedEvent(msg);
|
||||
_ProcessMouseMovedEvent(event, where, layer);
|
||||
break;
|
||||
|
||||
case B_MOUSE_WHEEL_CHANGED: {
|
||||
//printf("RootLayer::MouseEventHandler(B_MOUSE_WHEEL_CHANGED)\n");
|
||||
// FEATURE: This is a tentative change: mouse wheel messages are always sent to the window
|
||||
// under the cursor. It's pretty stupid to send it to the active window unless a particular
|
||||
// view has locked focus via SetMouseEventMask
|
||||
|
||||
if (fLastLayerUnderMouse == NULL) {
|
||||
CRITICAL("RootLayer::MouseEventHandler(B_MOUSE_DOWN) fLastLayerUnderMouse is null!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
fLastLayerUnderMouse->MouseWheelChanged(msg);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
printf("RootLayer::MouseEventHandler(): WARNING: unknown message\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
RootLayer::AddToInputNotificationLists(Layer *lay, uint32 mask, uint32 options)
|
||||
{
|
||||
if (!lay)
|
||||
return false;
|
||||
|
||||
bool returnValue = true;
|
||||
|
||||
Lock();
|
||||
|
||||
if (mask & B_POINTER_EVENTS) {
|
||||
if (!fMouseNotificationList.HasItem(lay))
|
||||
fMouseNotificationList.AddItem(lay);
|
||||
}
|
||||
else {
|
||||
if (options == 0)
|
||||
fMouseNotificationList.RemoveItem(lay);
|
||||
}
|
||||
|
||||
if (mask & B_KEYBOARD_EVENTS) {
|
||||
if (!fKeyboardNotificationList.HasItem(lay))
|
||||
fKeyboardNotificationList.AddItem(lay);
|
||||
}
|
||||
else {
|
||||
if (options == 0)
|
||||
fKeyboardNotificationList.RemoveItem(lay);
|
||||
}
|
||||
|
||||
// TODO: set options!!!
|
||||
// B_NO_POINTER_HISTORY only! How? By telling to the input_server?
|
||||
|
||||
Unlock();
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
bool
|
||||
RootLayer::SetNotifyLayer(Layer *lay, uint32 mask, uint32 options)
|
||||
{
|
||||
if (!lay)
|
||||
return false;
|
||||
|
||||
bool returnValue = true;
|
||||
|
||||
Lock();
|
||||
|
||||
fNotifyLayer = lay;
|
||||
fSavedEventMask = lay->EventMask();
|
||||
fSavedEventOptions = lay->EventOptions();
|
||||
|
||||
AddToInputNotificationLists(lay, mask, options);
|
||||
|
||||
// TODO: set other options!!!
|
||||
// B_SUSPEND_VIEW_FOCUS
|
||||
// B_LOCK_WINDOW_FOCUS
|
||||
Unlock();
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
void
|
||||
RootLayer::ClearNotifyLayer()
|
||||
RootLayer::SetMouseEventLayer(Layer* layer)
|
||||
{
|
||||
if (fNotifyLayer) {
|
||||
Lock();
|
||||
// remove from notification list.
|
||||
AddToInputNotificationLists(fNotifyLayer, 0UL, 0UL);
|
||||
// set event masks
|
||||
fNotifyLayer->QuietlySetEventMask(fSavedEventMask);
|
||||
fNotifyLayer->QuietlySetEventOptions(fSavedEventOptions);
|
||||
// add to notification list with event masks set my BView::SetEventMask()
|
||||
AddToInputNotificationLists(fNotifyLayer, fSavedEventMask, fSavedEventOptions);
|
||||
|
||||
fNotifyLayer = NULL;
|
||||
fSavedEventMask = 0UL;
|
||||
fSavedEventOptions = 0UL;
|
||||
|
||||
Unlock();
|
||||
}
|
||||
fMouseEventLayer = layer;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RootLayer::LayerRemoved(Layer* layer)
|
||||
{
|
||||
if (layer == fNotifyLayer)
|
||||
fNotifyLayer = NULL;
|
||||
// TODO: this must not happen!!! Fix this, quickly!
|
||||
if (layer == fLastLayerUnderMouse)
|
||||
fLastLayerUnderMouse = NULL;
|
||||
if (fMouseEventLayer == layer)
|
||||
fMouseEventLayer = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -1158,7 +935,7 @@ RootLayer::SetDragMessage(BMessage* msg)
|
||||
}
|
||||
|
||||
if (msg)
|
||||
fDragMessage = new BMessage(*msg);
|
||||
fDragMessage = new BMessage(*msg);
|
||||
}
|
||||
|
||||
|
||||
@@ -1245,12 +1022,6 @@ RootLayer::hide_winBorder(WinBorder *winBorder)
|
||||
void
|
||||
RootLayer::change_winBorder_feel(WinBorder *winBorder, int32 newFeel)
|
||||
{
|
||||
// if the notify Layer is somehow related to winBorder, then
|
||||
// this window/WinBorder is not allowed to change feel.
|
||||
if (fNotifyLayer && (fNotifyLayer == winBorder || fNotifyLayer->Owner() == winBorder)) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool isVisible = false;
|
||||
bool isVisibleInActiveWorkspace = false;
|
||||
|
||||
|
||||
@@ -96,16 +96,11 @@ public:
|
||||
|
||||
void SetBGColor(const RGBColor &col);
|
||||
RGBColor BGColor(void) const;
|
||||
|
||||
inline int32 Buttons(void) { return fButtons; }
|
||||
|
||||
|
||||
void SetDragMessage(BMessage *msg);
|
||||
BMessage* DragMessage(void) const;
|
||||
|
||||
bool AddToInputNotificationLists(Layer *lay, uint32 mask,
|
||||
uint32 options);
|
||||
bool SetNotifyLayer(Layer *lay, uint32 mask, uint32 options);
|
||||
void ClearNotifyLayer();
|
||||
void SetMouseEventLayer(Layer* layer);
|
||||
|
||||
void LayerRemoved(Layer* layer);
|
||||
|
||||
@@ -139,25 +134,19 @@ friend class Desktop;
|
||||
|
||||
// Input related methods
|
||||
void MouseEventHandler(BMessage *msg);
|
||||
void _ProcessMouseMovedEvent(BMessage *msg);
|
||||
void _ProcessMouseMovedEvent(BMessage *msg, BPoint where, Layer* target);
|
||||
|
||||
Desktop* fDesktop;
|
||||
BMessage* fDragMessage;
|
||||
Layer* fLastLayerUnderMouse;
|
||||
Layer* fMouseEventLayer;
|
||||
|
||||
Layer* fNotifyLayer;
|
||||
uint32 fSavedEventMask;
|
||||
uint32 fSavedEventOptions;
|
||||
BList fMouseNotificationList;
|
||||
BList fKeyboardNotificationList;
|
||||
|
||||
BLocker fAllRegionsLock;
|
||||
|
||||
BRegion fDirtyForRedraw;
|
||||
|
||||
int32 fButtons;
|
||||
BPoint fLastMousePosition;
|
||||
|
||||
int32 fActiveWksIndex;
|
||||
int32 fWsCount;
|
||||
Workspace** fWorkspace;
|
||||
|
||||
@@ -718,9 +718,7 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
|
||||
link.Read<uint32>(&eventMask);
|
||||
if (link.Read<uint32>(&options) == B_OK) {
|
||||
printf("got %s: eventMask = %ld, options = %ld\n", fCurrentLayer->Name(), eventMask, options);
|
||||
fCurrentLayer->QuietlySetEventMask(eventMask);
|
||||
fCurrentLayer->QuietlySetEventOptions(options);
|
||||
fCurrentLayer->SetEventMask(eventMask, options);
|
||||
|
||||
if (eventMask != 0 || options != 0) {
|
||||
fDesktop->EventDispatcher().AddListener(FocusMessenger(),
|
||||
@@ -749,8 +747,7 @@ printf("got %s: eventMask = %ld, options = %ld\n", fCurrentLayer->Name(), eventM
|
||||
}
|
||||
}
|
||||
|
||||
if (rootLayer)
|
||||
rootLayer->SetNotifyLayer(fCurrentLayer, eventMask, options);
|
||||
// TODO: support B_LOCK_WINDOW_FOCUS option in RootLayer
|
||||
break;
|
||||
}
|
||||
case AS_LAYER_MOVE_TO:
|
||||
@@ -1602,23 +1599,25 @@ if (rootLayer)
|
||||
DTRACE(("ServerWindow %s: Message AS_DRAG_RECT unimplemented\n", Title()));
|
||||
break;
|
||||
}
|
||||
case AS_LAYER_GET_MOUSE_COORDS:
|
||||
case AS_GET_MOUSE:
|
||||
{
|
||||
DTRACE(("ServerWindow %s: Message AS_GET_MOUSE_COORDS\n", fTitle));
|
||||
|
||||
fLink.StartMessage(SERVER_TRUE);
|
||||
DTRACE(("ServerWindow %s: Message AS_GET_MOUSE\n", fTitle));
|
||||
|
||||
// Returns
|
||||
// 1) BPoint mouse location
|
||||
// 2) int32 button state
|
||||
|
||||
fLink.Attach<BPoint>(fDesktop->HWInterface()->GetCursorPosition());
|
||||
fLink.Attach<int32>(fDesktop->RootLayer()->Buttons());
|
||||
BPoint where;
|
||||
int32 buttons;
|
||||
fDesktop->EventDispatcher().GetMouse(where, buttons);
|
||||
|
||||
fLink.StartMessage(B_OK);
|
||||
fLink.Attach<BPoint>(where);
|
||||
fLink.Attach<int32>(buttons);
|
||||
fLink.Flush();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case AS_DW_GET_SYNC_DATA:
|
||||
{
|
||||
// TODO: Use token or get rid of it.
|
||||
@@ -2116,6 +2115,9 @@ ServerWindow::_MessageLooper()
|
||||
status_t
|
||||
ServerWindow::SendMessageToClient(const BMessage* msg, int32 target) const
|
||||
{
|
||||
if (target == B_NULL_TOKEN)
|
||||
target = fClientToken;
|
||||
|
||||
#ifndef USING_MESSAGE4
|
||||
ssize_t size = msg->FlattenedSize();
|
||||
char* buffer = new(nothrow) char[size];
|
||||
|
||||
@@ -481,7 +481,7 @@ WinBorder::MouseDown(const BMessage *msg)
|
||||
if (action == DEC_MOVETOBACK) {
|
||||
GetRootLayer()->SetActive(this, false);
|
||||
} else {
|
||||
GetRootLayer()->SetNotifyLayer(this, B_POINTER_EVENTS, 0UL);
|
||||
GetRootLayer()->SetMouseEventLayer(this);
|
||||
GetRootLayer()->SetActive(this);
|
||||
}
|
||||
} else if (target != NULL) {
|
||||
|
||||
Reference in New Issue
Block a user