void BWebPage::skipToLastMessage(BMessage*& message) { // NOTE: All messages that are fast-forwarded like this // need to be flagged with the intended target BWebPage, // or else we steal or process messages intended for another // BWebPage here! bool first = true; BMessageQueue* queue = Looper()->MessageQueue(); int32 index = 0; while (BMessage* nextMessage = queue->FindMessage(message->what, index)) { BHandler* target = 0; nextMessage->FindPointer("target", reinterpret_cast<void**>(&target)); if (target != this) { index++; continue; } if (!first) delete message; message = nextMessage; queue->RemoveMessage(message); first = false; } }
void BWebPage::MessageReceived(BMessage* message) { switch (message->what) { case HANDLE_SHUTDOWN: // NOTE: This message never arrives here when the BApplication is already // processing B_QUIT_REQUESTED. Then the view will be detached and instruct // the BWebPage handler to shut itself down, but BApplication will not // process additional messages. That's why the windows containing WebViews // are detaching the views already in their QuitRequested() hooks and // LauncherApp calls these hooks already in its own QuitRequested() hook. Looper()->RemoveHandler(this); delete this; // TOAST! return; case HANDLE_LOAD_URL: handleLoadURL(message); break; case HANDLE_RELOAD: handleReload(message); break; case HANDLE_GO_BACK: handleGoBack(message); break; case HANDLE_GO_FORWARD: handleGoForward(message); break; case HANDLE_STOP_LOADING: handleStop(message); break; case HANDLE_SET_VISIBLE: handleSetVisible(message); break; case HANDLE_DRAW: { bool first = true; BMessageQueue* queue = Looper()->MessageQueue(); BRect updateRect; message->FindRect("update rect", &updateRect); int32 index = 0; while (BMessage* nextMessage = queue->FindMessage(message->what, index)) { BHandler* target = 0; nextMessage->FindPointer("target", reinterpret_cast<void**>(&target)); if (target != this) { index++; continue; } if (!first) { delete message; first = false; } message = nextMessage; queue->RemoveMessage(message); BRect rect; message->FindRect("update rect", &rect); updateRect = updateRect | rect; } paint(updateRect, false); break; } case HANDLE_FRAME_RESIZED: skipToLastMessage(message); handleFrameResized(message); break; case HANDLE_FOCUSED: handleFocused(message); break; case HANDLE_ACTIVATED: handleActivated(message); break; case B_MOUSE_MOVED: skipToLastMessage(message); // fall through case B_MOUSE_DOWN: case B_MOUSE_UP: handleMouseEvent(message); break; case B_MOUSE_WHEEL_CHANGED: handleMouseWheelChanged(message); break; case B_KEY_DOWN: case B_KEY_UP: handleKeyEvent(message); break; case HANDLE_CHANGE_ZOOM_FACTOR: handleChangeZoomFactor(message); break; case HANDLE_FIND_STRING: handleFindString(message); break; case HANDLE_SET_STATUS_MESSAGE: { BString status; if (message->FindString("string", &status) == B_OK) setStatusMessage(status); break; } case HANDLE_RESEND_NOTIFICATIONS: handleResendNotifications(message); break; case HANDLE_SEND_EDITING_CAPABILITIES: handleSendEditingCapabilities(message); break; case HANDLE_SEND_PAGE_SOURCE: handleSendPageSource(message); break; case B_REFS_RECEIVED: { RefPtr<FileChooser>* chooser; if (message->FindPointer("chooser", reinterpret_cast<void**>(&chooser)) == B_OK) { entry_ref ref; BPath path; Vector<String> filenames; for (int32 i = 0; message->FindRef("refs", i, &ref) == B_OK; i++) { path.SetTo(&ref); filenames.append(String(path.Path())); } (*chooser)->chooseFiles(filenames); delete chooser; } break; } case B_CANCEL: { int32 oldWhat; BFilePanel* panel; if (message->FindPointer("source", reinterpret_cast<void**>(&panel)) == B_OK && message->FindInt32("old_what", &oldWhat) == B_OK && oldWhat == B_REFS_RECEIVED) { // TODO: Eventually it would be nice to reuse the same file panel... // At least don't leak the file panel for now. delete panel; } break; } default: BHandler::MessageReceived(message); } }