Implement the BWindow::task_loop again. I know that this is code duplication, but look at
the TODO item for an explanation. We could do this as a hack in Looper.cpp though. Also implement the determine_target function (incomplete). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12082 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+121
-54
@@ -67,6 +67,8 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Globals ---------------------------------------------------------------------
|
// Globals ---------------------------------------------------------------------
|
||||||
|
using BPrivate::gDefaultTokens;
|
||||||
|
|
||||||
static property_info windowPropInfo[] =
|
static property_info windowPropInfo[] =
|
||||||
{
|
{
|
||||||
{ "Feel", { B_GET_PROPERTY, 0 },
|
{ "Feel", { B_GET_PROPERTY, 0 },
|
||||||
@@ -2261,111 +2263,126 @@ void BWindow::InitData( BRect frame, const char* title, window_look look,
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// TODO: This here is a nearly full code duplication to BLooper::task_loop
|
||||||
|
// but with one little difference: It uses the determine_target function
|
||||||
|
// to tell what the later target of a message will be, if no explicit target
|
||||||
|
// is supplied. This is important because we need to call the right targets
|
||||||
|
// MessageFilter. For B_KEY_DOWN messages for example, not the BWindow but the
|
||||||
|
// focus view will be the target of the message. This means that also the
|
||||||
|
// focus views MessageFilters have to be checked before DispatchMessage and
|
||||||
|
// not the ones of this BWindow.
|
||||||
|
|
||||||
void BWindow::task_looper()
|
void BWindow::task_looper()
|
||||||
{
|
{
|
||||||
STRACE(("info: BWindow::task_looper() started.\n"));
|
STRACE(("info: BWindow::task_looper() started.\n"));
|
||||||
BLooper::task_looper();
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
// Check that looper is locked (should be)
|
// Check that looper is locked (should be)
|
||||||
AssertLocked();
|
AssertLocked();
|
||||||
|
// Unlock the looper
|
||||||
Unlock();
|
Unlock();
|
||||||
|
|
||||||
using namespace BPrivate;
|
|
||||||
bool dispatchNextMessage = false;
|
|
||||||
BMessage *msg;
|
|
||||||
|
|
||||||
// loop: As long as we are not terminating.
|
// loop: As long as we are not terminating.
|
||||||
while (!fTerminating)
|
while (!fTerminating)
|
||||||
{
|
{
|
||||||
STRACE(("info: BWindow::task_looper() waiting for message.\n"));
|
// TODO: timeout determination algo
|
||||||
msg = MessageFromPort();
|
// 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)
|
if (msg)
|
||||||
{
|
{
|
||||||
// Add to queue
|
// Add to queue
|
||||||
fQueue->AddMessage(msg);
|
fQueue->AddMessage(msg);
|
||||||
STRACE(("info: BWindow::task_looper() queued a message.\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get message count from port
|
|
||||||
STRACE(("info: BWindow::task_looper() getting port_count...\n"));
|
|
||||||
int32 msgCount = port_count(fMsgPort);
|
|
||||||
if (msgCount > 0){
|
|
||||||
fQueue->Lock();
|
|
||||||
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
|
|
||||||
STRACE(("info: BWindow::task_looper() zero-wait pre-fetch messages...\n"));
|
|
||||||
msg = MessageFromPort(0);
|
|
||||||
|
|
||||||
// Add messages to queue
|
|
||||||
if (msg)
|
|
||||||
fQueue->AddMessage(msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
STRACE(("info: BWindow::task_looper() pre-fetching complete.\n"));
|
// Get message count from port
|
||||||
// loop as long as there are messages in the queue and
|
int32 msgCount = port_count(fMsgPort);
|
||||||
// and we are not terminating.
|
for (int32 i = 0; i < msgCount; ++i)
|
||||||
dispatchNextMessage = true;
|
{
|
||||||
|
// 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
|
||||||
|
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.
|
||||||
|
bool dispatchNextMessage = true;
|
||||||
while (!fTerminating && dispatchNextMessage)
|
while (!fTerminating && dispatchNextMessage)
|
||||||
{
|
{
|
||||||
fQueue->Lock();
|
// Get next message from queue (assign to fLastMessage)
|
||||||
fLastMessage = fQueue->NextMessage();
|
fLastMessage = fQueue->NextMessage();
|
||||||
fQueue->Unlock();
|
|
||||||
|
// Lock the looper
|
||||||
Lock();
|
Lock();
|
||||||
|
|
||||||
// TODO: add code for drag & drop
|
|
||||||
if (!fLastMessage)
|
if (!fLastMessage)
|
||||||
{
|
{
|
||||||
// No more messages: Unlock the looper and terminate the
|
// No more messages: Unlock the looper and terminate the
|
||||||
// dispatch loop.
|
// dispatch loop.
|
||||||
STRACE(("info: BWindow::task_looper() no more pre-fetched messages.\n"));
|
|
||||||
dispatchNextMessage = false;
|
dispatchNextMessage = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
STRACE(("info: BWindow::task_looper() dispatching...\n"));
|
|
||||||
STRACE(("info: BWindow::task_looper() "));
|
|
||||||
|
|
||||||
// Get the target handler
|
// Get the target handler
|
||||||
|
// Use BMessage friend functions to determine if we are using the
|
||||||
|
// preferred handler, or if a target has been specified
|
||||||
BHandler* handler;
|
BHandler* handler;
|
||||||
if (_use_preferred_target_(fLastMessage))
|
if (_use_preferred_target_(fLastMessage))
|
||||||
|
{
|
||||||
handler = fPreferred;
|
handler = fPreferred;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
gDefaultTokens.GetToken(_get_message_target_(fLastMessage),
|
{
|
||||||
B_HANDLER_TOKEN, (void**)&handler);
|
/**
|
||||||
|
@note Here is where all the token stuff starts to
|
||||||
if (!handler)
|
make sense. How, exactly, do we determine
|
||||||
handler = this;
|
what the target BHandler is? If we look at
|
||||||
|
BMessage, we see an int32 field, fTarget.
|
||||||
|
Amazingly, we happen to have a global mapping
|
||||||
|
of BHandler pointers to int32s!
|
||||||
|
*/
|
||||||
|
gDefaultTokens.GetToken(_get_message_target_(fLastMessage),
|
||||||
|
B_HANDLER_TOKEN,
|
||||||
|
(void**)&handler);
|
||||||
|
}
|
||||||
|
|
||||||
// Is this a scripting message?
|
if (!handler)
|
||||||
|
{
|
||||||
|
handler = determine_target(msg, handler, _use_preferred_target_(fLastMessage));
|
||||||
|
if (!handler)
|
||||||
|
handler = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is this a scripting message? (BMessage::HasSpecifiers())
|
||||||
if (fLastMessage->HasSpecifiers())
|
if (fLastMessage->HasSpecifiers())
|
||||||
{
|
{
|
||||||
int32 index = 0;
|
int32 index = 0;
|
||||||
// Make sure the current specifier is kosher
|
// Make sure the current specifier is kosher
|
||||||
if (fLastMessage->GetCurrentSpecifier(&index) == B_OK)
|
if (fLastMessage->GetCurrentSpecifier(&index) == B_OK)
|
||||||
|
{
|
||||||
handler = resolve_specifier(handler, fLastMessage);
|
handler = resolve_specifier(handler, fLastMessage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
STRACE(("info: BWindow::task_looper() no handler for dispatch.\n"));
|
{
|
||||||
|
}
|
||||||
|
|
||||||
if (handler)
|
if (handler)
|
||||||
{
|
{
|
||||||
// Do filtering
|
// Do filtering
|
||||||
handler = top_level_filter(fLastMessage, handler);
|
handler = top_level_filter(fLastMessage, handler);
|
||||||
if (handler && handler->Looper() == this)
|
if (handler && handler->Looper() == this)
|
||||||
|
{
|
||||||
DispatchMessage(fLastMessage, handler);
|
DispatchMessage(fLastMessage, handler);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// empty our message buffer
|
|
||||||
fLink->Flush();
|
|
||||||
|
|
||||||
|
// Unlock the looper
|
||||||
Unlock();
|
Unlock();
|
||||||
|
|
||||||
// Delete the current message (fLastMessage)
|
// Delete the current message (fLastMessage)
|
||||||
@@ -2383,9 +2400,8 @@ void BWindow::task_looper()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
window_type BWindow::composeType(window_look look,
|
window_type BWindow::composeType(window_look look,
|
||||||
@@ -2578,6 +2594,9 @@ void BWindow::setFocus(BView *focusView, bool notifyInputServer)
|
|||||||
{
|
{
|
||||||
// what am I suppose to do here??
|
// what am I suppose to do here??
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: find out why R5 does this
|
||||||
|
SetPreferredHandler(fFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -2616,6 +2635,54 @@ void BWindow::activateView( BView *aView, bool active ){
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
BHandler *
|
||||||
|
BWindow::determine_target(BMessage *msg, BHandler *target, bool pref)
|
||||||
|
{
|
||||||
|
// TODO: this is mostly guessed; check for correctness.
|
||||||
|
// I think this function is used to determine if a BView will be
|
||||||
|
// the target of a message. This is used in the BLooper::task_loop
|
||||||
|
// to determine what BHandler will dispatch the message and what filters
|
||||||
|
// should be checked before doing so.
|
||||||
|
|
||||||
|
printf("determine_target: %x, %x, %s\n", msg, target, pref ? "true" : "false");
|
||||||
|
|
||||||
|
switch (msg->what) {
|
||||||
|
case B_KEY_DOWN:
|
||||||
|
case B_KEY_UP:
|
||||||
|
case B_UNMAPPED_KEY_DOWN:
|
||||||
|
case B_UNMAPPED_KEY_UP:
|
||||||
|
case B_MODIFIERS_CHANGED:
|
||||||
|
case B_MOUSE_WHEEL_CHANGED:
|
||||||
|
// these messages will be dispatched by the focus view later
|
||||||
|
return fFocus;
|
||||||
|
|
||||||
|
case B_MOUSE_DOWN:
|
||||||
|
case B_MOUSE_UP:
|
||||||
|
case B_MOUSE_MOVED:
|
||||||
|
// TODO: find out how to determine the target for these
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_PULSE:
|
||||||
|
case B_QUIT_REQUESTED:
|
||||||
|
// TODO: test wether R5 will let BView dispatch these messages
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_VIEW_RESIZED:
|
||||||
|
case B_VIEW_MOVED: {
|
||||||
|
int32 token = B_NULL_TOKEN;
|
||||||
|
msg->FindInt32("_token", &token);
|
||||||
|
BView *view = findView(top_view, token);
|
||||||
|
if (view)
|
||||||
|
return view;
|
||||||
|
} break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
bool BWindow::handleKeyDown( const char key, uint32 modifiers){
|
bool BWindow::handleKeyDown( const char key, uint32 modifiers){
|
||||||
|
|
||||||
// TODO: ask people if using 'raw_char' is OK ?
|
// TODO: ask people if using 'raw_char' is OK ?
|
||||||
|
|||||||
Reference in New Issue
Block a user