📄 kwqkhtmlpart.cpp
字号:
QKeyEvent qEvent(*event); bool result = !node->dispatchKeyEvent(&qEvent); // We want to send both a down and a press for the initial key event. // To get KHTML to do this, we send a second KeyPress QKeyEvent with "is repeat" set to true, // which causes it to send a press to the DOM. // That's not a great hack; it would be good to do this in a better way. if (event->type() == QEvent::KeyPress && !event->isAutoRepeat()) { QKeyEvent repeatEvent(*event); if (!node->dispatchKeyEvent(&repeatEvent)) { result = true; } } ASSERT(_currentEvent == (NSEvent*)event); _currentEvent = oldCurrentEvent; return result;}// This does the same kind of work that KHTMLPart::openURL does, except it relies on the fact// that a higher level already checked that the URLs match and the scrolling is the right thing to do.void KWQKHTMLPart::scrollToAnchor(const KURL &URL){ cancelRedirection(); m_url = URL; started(0); if (!gotoAnchor(URL.encodedHtmlRef())) gotoAnchor(URL.ref()); // It's important to model this as a load that starts and immediately finishes. // Otherwise, the parent frame may think we never finished loading. d->m_bComplete = false; checkCompleted();}bool KWQKHTMLPart::closeURL(){ saveDocumentState(); return KHTMLPart::closeURL();}void KWQKHTMLPart::khtmlMousePressEvent(MousePressEvent *event){ // If we got the event back, that must mean it wasn't prevented, // so it's allowed to start a drag or selection. _mouseDownMayStartDrag = true; _mouseDownMayStartSelect = true; if (!passWidgetMouseDownEventToWidget(event)) { // We don't do this at the start of mouse down handling (before calling into WebCore), // because we don't want to do it until we know we didn't hit a widget. GtkWidget *view = d->m_view->getDocumentView(); if (_currentEvent->clickCount() <= 1 && _bridge->firstResponder() != view) { _bridge->makeFirstResponder(view); } KHTMLPart::khtmlMousePressEvent(event); }}void KWQKHTMLPart::khtmlMouseDoubleClickEvent(MouseDoubleClickEvent *event){ if (!passWidgetMouseDownEventToWidget(event)) { KHTMLPart::khtmlMouseDoubleClickEvent(event); }}bool KWQKHTMLPart::passWidgetMouseDownEventToWidget(khtml::MouseEvent *event){ // Figure out which view to send the event to. RenderObject *target = event->innerNode().handle() ? event->innerNode().handle()->renderer() : 0; if (!target) return false; QWidget* widget = RenderLayer::gScrollBar; if (!widget) { if (!target->isWidget()) return false; widget = static_cast<RenderWidget *>(target)->widget(); } // Doubleclick events don't exist in Cocoa. Since passWidgetMouseDownEventToWidget will // just pass _currentEvent down to the widget, we don't want to call it for events that // don't correspond to Cocoa events. The mousedown/ups will have already been passed on as // part of the pressed/released handling. if (!MouseDoubleClickEvent::test(event)) return passWidgetMouseDownEventToWidget(widget); else return true;}bool KWQKHTMLPart::passWidgetMouseDownEventToWidget(RenderWidget *renderWidget){ return passWidgetMouseDownEventToWidget(renderWidget->widget());}bool KWQKHTMLPart::passWidgetMouseDownEventToWidget(QWidget* widget){ // FIXME: this method always returns true if (!widget) { ERROR("hit a RenderWidget without a corresponding QWidget, means a frame is half-constructed"); return true; }#if 0 KWQ_BLOCK_EXCEPTIONS; NSView *nodeView = widget->getView(); ASSERT(nodeView); ASSERT([nodeView superview]); NSView *topView = nodeView; NSView *superview; while ((superview = [topView superview])) { topView = superview; } NSView *view = [nodeView hitTest:[[nodeView superview] convertPoint:[_currentEvent locationInWindow] fromView:topView]]; if (view == nil) { ERROR("KHTML says we hit a RenderWidget, but AppKit doesn't agree we hit the corresponding NSView"); return true; } if ([_bridge firstResponder] == view) { // In the case where we just became first responder, we should send the mouseDown: // to the NSTextField, not the NSTextField's editor. This code makes sure that happens. // If we don't do this, we see a flash of selected text when clicking in a text field. if (_firstResponderAtMouseDownTime != view && [view isKindOfClass:[NSTextView class]]) { NSView *superview = view; while (superview != nodeView) { superview = [superview superview]; ASSERT(superview); if ([superview isKindOfClass:[NSControl class]]) { NSControl *control = superview; if ([control currentEditor] == view) { view = superview; } break; } } } } else { // Normally [NSWindow sendEvent:] handles setting the first responder. // But in our case, the event was sent to the view representing the entire web page. if ([_currentEvent clickCount] <= 1 && [view acceptsFirstResponder] && [view needsPanelToBecomeKey]) { [_bridge makeFirstResponder:view]; } } // We need to "defer loading" and defer timers while we are tracking the mouse. // That's because we don't want the new page to load while the user is holding the mouse down. BOOL wasDeferringLoading = [_bridge defersLoading]; if (!wasDeferringLoading) { [_bridge setDefersLoading:YES]; } BOOL wasDeferringTimers = QObject::defersTimers(); if (!wasDeferringTimers) { QObject::setDefersTimers(true); } ASSERT(!_sendingEventToSubview); _sendingEventToSubview = true; [view mouseDown:_currentEvent]; _sendingEventToSubview = false; if (!wasDeferringTimers) { QObject::setDefersTimers(false); } if (!wasDeferringLoading) { [_bridge setDefersLoading:NO]; } // Remember which view we sent the event to, so we can direct the release event properly. _mouseDownView = view; _mouseDownWasInSubframe = false; KWQ_UNBLOCK_EXCEPTIONS;#endif return true;}bool KWQKHTMLPart::lastEventIsMouseUp(){#if 0 // Many AK widgets run their own event loops and consume events while the mouse is down. // When they finish, currentEvent is the mouseUp that they exited on. We need to update // the khtml state with this mouseUp, which khtml never saw. This method lets us detect // that state. KWQ_BLOCK_EXCEPTIONS; NSEvent *currentEventAfterHandlingMouseDown = [NSApp currentEvent]; if (_currentEvent != currentEventAfterHandlingMouseDown) { if ([currentEventAfterHandlingMouseDown type] == NSLeftMouseUp) { return true; } } KWQ_UNBLOCK_EXCEPTIONS;#endif return false;} // Note that this does the same kind of check as [target isDescendantOf:superview].// There are two differences: This is a lot slower because it has to walk the whole// tree, and this works in cases where the target has already been deallocated.#if 0 static bool findViewInSubviews(NSView *superview, NSView *target){ KWQ_BLOCK_EXCEPTIONS; NSEnumerator *e = [[superview subviews] objectEnumerator]; NSView *subview; while ((subview = [e nextObject])) { if (subview == target || findViewInSubviews(subview, target)) { return true; } } KWQ_UNBLOCK_EXCEPTIONS; return false;}#endif NSView *KWQKHTMLPart::mouseDownViewIfStillGood(){#if 0 // Since we have no way of tracking the lifetime of _mouseDownView, we have to assume that // it could be deallocated already. We search for it in our subview tree; if we don't find // it, we set it to nil. NSView *mouseDownView = _mouseDownView; if (!mouseDownView) { return nil; } KHTMLView *topKHTMLView = d->m_view; NSView *topView = topKHTMLView ? topKHTMLView->getView() : nil; if (!topView || !findViewInSubviews(topView, mouseDownView)) { _mouseDownView = nil; return nil; } return mouseDownView;#endif return 0;}#if 0// The link drag hysteresis is much larger than the others because there// needs to be enough space to cancel the link press without starting a link drag,// and because dragging links is rare.#define LinkDragHysteresis 40.0#define ImageDragHysteresis 5.0#define TextDragHysteresis 3.0#define GeneralDragHysterisis 3.0bool KWQKHTMLPart::dragHysteresisExceeded(float dragLocationX, float dragLocationY) const{ int dragX, dragY; d->m_view->viewportToContents((int)dragLocationX, (int)dragLocationY, dragX, dragY); float deltaX = QABS(dragX - _mouseDownX); float deltaY = QABS(dragY - _mouseDownY); float threshold = GeneralDragHysterisis; if (_dragSrcIsImage) { threshold = ImageDragHysteresis; } else if (_dragSrcIsLink) { threshold = LinkDragHysteresis; } else if (_dragSrcInSelection) { threshold = TextDragHysteresis; } return deltaX >= threshold || deltaY >= threshold;}// returns if we should continue "default processing", i.e., whether eventhandler canceledbool KWQKHTMLPart::dispatchDragSrcEvent(int eventId, const QPoint &loc) const{ bool noDefaultProc = d->m_view->dispatchDragEvent(eventId, _dragSrc.handle(), loc, _dragClipboard); return !noDefaultProc;}#endifvoid KWQKHTMLPart::khtmlMouseMoveEvent(MouseMoveEvent *event){#if 0 // See WebCore-146.1/kwq/KWQKHTMLPart.mm#endif KHTMLPart::khtmlMouseMoveEvent(event);}#if 0void KWQKHTMLPart::dragSourceMovedTo(const QPoint &loc){ if (!_dragSrc.isNull() && _dragSrcMayBeDHTML) { // for now we don't care if event handler cancels default behavior, since there is none dispatchDragSrcEvent(EventImpl::DRAG_EVENT, loc); }}void KWQKHTMLPart::dragSourceEndedAt(const QPoint &loc){ if (!_dragSrc.isNull() && _dragSrcMayBeDHTML) { // for now we don't care if event handler cancels default behavior, since there is none dispatchDragSrcEvent(EventImpl::DRAGEND_EVENT, loc); } freeClipboard(); _dragSrc = 0;}bool KWQKHTMLPart::dispatchCPPEvent(int eventId, KWQClipboard::AccessPolicy policy){ NodeImpl *target = d->m_selection.start().element(); if (!target) { target = docImpl()->body(); } KWQClipboard *clipboard = new KWQClipboard(false, [NSPasteboard generalPasteboard], (KWQClipboard::AccessPolicy)policy); clipboard->ref(); int exceptioncode = 0; EventImpl *evt = new ClipboardEventImpl(static_cast<EventImpl::EventId>(eventId), true, true, clipboard); evt->ref(); target->dispatchEvent(evt, exceptioncode, true); bool noDefaultProcessing = evt->defaultPrevented(); evt->deref(); // invalidate clipboard here for security clipboard->setAccessPolicy(KWQClipboard::Numb); clipboard->deref(); return !noDefaultProcessing;}// In the next three functions, for now, we send the "before" event to gain some compatibility with WinIE.// WinIE uses onbeforecut and onbeforepaste to enables the cut and paste menu items, but we don't yet. They// also send onbeforecopy, apparently for symmetry, but it doesn't affect the menu items. The return of these// routines should not block the sending of non-"before" event.bool KWQKHTMLPart::tryCut(){ // Must be done before oncut adds types and data to the pboard, // also done for security, as it erases data from the last copy/paste. [[NSPasteboard generalPasteboard] declareTypes:[NSArray array] owner:nil]; dispatchCPPEvent(EventImpl::BEFORECUT_EVENT, KWQClipboard::Writable); return !dispatchCPPEvent(EventImpl::CUT_EVENT, KWQClipboard::Writable);}bool KWQKHTMLPart::tryCopy(){ // Must be done before oncopy adds types and data to the pboard, // also done for security, as it erases data from the last copy/paste. [[NSPasteboard generalPasteboard] declareTypes:[NSArray array] owner:nil]; dispatchCPPEvent(EventImpl::BEFORECOPY_EVENT, KWQClipboard::Writable); return !dispatchCPPEvent(EventImpl::COPY_EVENT, KWQClipboard::Writable);}bool KWQKHTMLPart::tryPaste(){ dispatchCPPEvent(EventImpl::BEFOREPASTE_EVENT, KWQClipboard::Readable); return !dispatchCPPEvent(EventImpl::PASTE_EVENT, KWQClipboard::Readable);}#endifvoid KWQKHTMLPart::khtmlMouseReleaseEvent(MouseReleaseEvent *event){#if 0 NSView *view = mouseDownViewIfStillGood(); if (!view) { KHTMLPart::khtmlMouseReleaseEvent(event); return; } _sendingEventToSubview = true; KWQ_BLOCK_EXCEPTIONS; [view mouseUp:_currentEvent]; KWQ_UNBLOCK_EXCEPTIONS; _sendingEventToSubview = false;#endif KHTMLPart::khtmlMouseReleaseEvent(event); }void KWQKHTMLPart::clearTimers(KHTMLView *view){ if (view) { view->unscheduleRelayout(); if (view->part()) { DocumentImpl* document = view->part()->xmlDocImpl(); if (document && document->renderer() && document->renderer()->layer()) document->renderer()->layer()->suspendMarquees(); } }}void KWQKHTMLPart::clearTimers(){ clearTimers(d->m_view);}bool KWQKHTMLPart::passSubframeEventToSubframe(DOM::NodeImpl::MouseEvent &event){#if 0 KWQ_BLOCK_EXCEPTIONS; switch ([_currentEvent type]) { case NSLeftMouseDown: { NodeImpl *node = event.innerNode.handle(); if (!node) { return false; } RenderPart *renderPart = dynamic_cast<RenderPart *>(node->renderer()); if (!renderPart) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -