eventhandlermac.mm
来自「linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自Web」· MM 代码 · 共 656 行 · 第 1/2 页
MM
656 行
FrameView* topFrameView = m_frame->view(); NSView *topView = topFrameView ? topFrameView->platformWidget() : nil; if (!topView || !findViewInSubviews(topView, mouseDownView)) { m_mouseDownView = nil; return nil; } return mouseDownView;}bool EventHandler::eventActivatedView(const PlatformMouseEvent& event) const{ return m_activationEventNumber == event.eventNumber();}bool EventHandler::eventLoopHandleMouseDragged(const MouseEventWithHitTestResults&){ NSView *view = mouseDownViewIfStillGood(); if (!view) return false; if (!m_mouseDownWasInSubframe) { m_sendingEventToSubview = true; BEGIN_BLOCK_OBJC_EXCEPTIONS; [view mouseDragged:currentEvent().get()]; END_BLOCK_OBJC_EXCEPTIONS; m_sendingEventToSubview = false; } return true;} PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const { NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:NSDragPboard]; // Must be done before ondragstart adds types and data to the pboard, // also done for security, as it erases data from the last drag [pasteboard declareTypes:[NSArray array] owner:nil]; return ClipboardMac::create(true, pasteboard, ClipboardWritable, m_frame);} bool EventHandler::eventLoopHandleMouseUp(const MouseEventWithHitTestResults&){ NSView *view = mouseDownViewIfStillGood(); if (!view) return false; if (!m_mouseDownWasInSubframe) { m_sendingEventToSubview = true; BEGIN_BLOCK_OBJC_EXCEPTIONS; [view mouseUp:currentEvent().get()]; END_BLOCK_OBJC_EXCEPTIONS; m_sendingEventToSubview = false; } return true;} bool EventHandler::passSubframeEventToSubframe(MouseEventWithHitTestResults& event, Frame* subframe, HitTestResult* hoveredNode){ BEGIN_BLOCK_OBJC_EXCEPTIONS; switch ([currentEvent().get() type]) { case NSMouseMoved: // Since we're passing in currentEvent() here, we can call // handleMouseMoveEvent() directly, since the save/restore of // currentEvent() that mouseMoved() does would have no effect. subframe->eventHandler()->handleMouseMoveEvent(currentEvent().get(), hoveredNode); return true; case NSLeftMouseDown: { Node* node = event.targetNode(); if (!node) return false; RenderObject* renderer = node->renderer(); if (!renderer || !renderer->isWidget()) return false; Widget* widget = static_cast<RenderWidget*>(renderer)->widget(); if (!widget || !widget->isFrameView()) return false; if (!passWidgetMouseDownEventToWidget(static_cast<RenderWidget*>(renderer))) return false; m_mouseDownWasInSubframe = true; return true; } case NSLeftMouseUp: { if (!m_mouseDownWasInSubframe) return false; NSView *view = mouseDownViewIfStillGood(); if (!view) return false; ASSERT(!m_sendingEventToSubview); m_sendingEventToSubview = true; [view mouseUp:currentEvent().get()]; m_sendingEventToSubview = false; return true; } case NSLeftMouseDragged: { if (!m_mouseDownWasInSubframe) return false; NSView *view = mouseDownViewIfStillGood(); if (!view) return false; ASSERT(!m_sendingEventToSubview); m_sendingEventToSubview = true; [view mouseDragged:currentEvent().get()]; m_sendingEventToSubview = false; return true; } default: return false; } END_BLOCK_OBJC_EXCEPTIONS; return false;}bool EventHandler::passWheelEventToWidget(PlatformWheelEvent&, Widget* widget){ BEGIN_BLOCK_OBJC_EXCEPTIONS; if ([currentEvent().get() type] != NSScrollWheel || m_sendingEventToSubview || !widget) return false; NSView* nodeView = widget->platformWidget(); ASSERT(nodeView); ASSERT([nodeView superview]); NSView *view = [nodeView hitTest:[[nodeView superview] convertPoint:[currentEvent().get() locationInWindow] fromView:nil]]; if (!view) // We probably hit the border of a RenderWidget return false; m_sendingEventToSubview = true; [view scrollWheel:currentEvent().get()]; m_sendingEventToSubview = false; return true; END_BLOCK_OBJC_EXCEPTIONS; return false;}void EventHandler::mouseDown(NSEvent *event){ FrameView* v = m_frame->view(); if (!v || m_sendingEventToSubview) return; BEGIN_BLOCK_OBJC_EXCEPTIONS; m_frame->loader()->resetMultipleFormSubmissionProtection(); m_mouseDownView = nil; RetainPtr<NSEvent> oldCurrentEvent = currentEvent(); currentEvent() = event; m_mouseDown = PlatformMouseEvent(event); handleMousePressEvent(event); ASSERT(currentEvent() == event); currentEvent() = oldCurrentEvent; END_BLOCK_OBJC_EXCEPTIONS;}void EventHandler::mouseDragged(NSEvent *event){ FrameView* v = m_frame->view(); if (!v || m_sendingEventToSubview) return; BEGIN_BLOCK_OBJC_EXCEPTIONS; RetainPtr<NSEvent> oldCurrentEvent = currentEvent(); currentEvent() = event; handleMouseMoveEvent(event); ASSERT(currentEvent() == event); currentEvent() = oldCurrentEvent; END_BLOCK_OBJC_EXCEPTIONS;}void EventHandler::mouseUp(NSEvent *event){ FrameView* v = m_frame->view(); if (!v || m_sendingEventToSubview) return; BEGIN_BLOCK_OBJC_EXCEPTIONS; RetainPtr<NSEvent> oldCurrentEvent = currentEvent(); currentEvent() = event; // Our behavior here is a little different that Qt. Qt always sends // a mouse release event, even for a double click. To correct problems // in khtml's DOM click event handling we do not send a release here // for a double click. Instead we send that event from FrameView's // handleMouseDoubleClickEvent. Note also that the third click of // a triple click is treated as a single click, but the fourth is then // treated as another double click. Hence the "% 2" below. int clickCount = [event clickCount]; if (clickCount > 0 && clickCount % 2 == 0) handleMouseDoubleClickEvent(event); else handleMouseReleaseEvent(event); ASSERT(currentEvent() == event); currentEvent() = oldCurrentEvent; m_mouseDownView = nil; END_BLOCK_OBJC_EXCEPTIONS;}/* A hack for the benefit of AK's PopUpButton, which uses the Carbon menu manager, which thus eats all subsequent events after it is starts its modal tracking loop. After the interaction is done, this routine is used to fix things up. When a mouse down started us tracking in the widget, we post a fake mouse up to balance the mouse down we started with. When a key down started us tracking in the widget, we post a fake key up to balance things out. In addition, we post a fake mouseMoved to get the cursor in sync with whatever we happen to be over after the tracking is done. */void EventHandler::sendFakeEventsAfterWidgetTracking(NSEvent *initiatingEvent){ FrameView* view = m_frame->view(); if (!view) return; BEGIN_BLOCK_OBJC_EXCEPTIONS; m_sendingEventToSubview = false; int eventType = [initiatingEvent type]; if (eventType == NSLeftMouseDown || eventType == NSKeyDown) { NSEvent *fakeEvent = nil; if (eventType == NSLeftMouseDown) { fakeEvent = [NSEvent mouseEventWithType:NSLeftMouseUp location:[initiatingEvent locationInWindow] modifierFlags:[initiatingEvent modifierFlags] timestamp:[initiatingEvent timestamp] windowNumber:[initiatingEvent windowNumber] context:[initiatingEvent context] eventNumber:[initiatingEvent eventNumber] clickCount:[initiatingEvent clickCount] pressure:[initiatingEvent pressure]]; [NSApp postEvent:fakeEvent atStart:YES]; } else { // eventType == NSKeyDown fakeEvent = [NSEvent keyEventWithType:NSKeyUp location:[initiatingEvent locationInWindow] modifierFlags:[initiatingEvent modifierFlags] timestamp:[initiatingEvent timestamp] windowNumber:[initiatingEvent windowNumber] context:[initiatingEvent context] characters:[initiatingEvent characters] charactersIgnoringModifiers:[initiatingEvent charactersIgnoringModifiers] isARepeat:[initiatingEvent isARepeat] keyCode:[initiatingEvent keyCode]]; [NSApp postEvent:fakeEvent atStart:YES]; } // FIXME: We should really get the current modifierFlags here, but there's no way to poll // them in Cocoa, and because the event stream was stolen by the Carbon menu code we have // no up-to-date cache of them anywhere. fakeEvent = [NSEvent mouseEventWithType:NSMouseMoved location:[[view->platformWidget() window] convertScreenToBase:[NSEvent mouseLocation]] modifierFlags:[initiatingEvent modifierFlags] timestamp:[initiatingEvent timestamp] windowNumber:[initiatingEvent windowNumber] context:[initiatingEvent context] eventNumber:0 clickCount:0 pressure:0]; [NSApp postEvent:fakeEvent atStart:YES]; } END_BLOCK_OBJC_EXCEPTIONS;}void EventHandler::mouseMoved(NSEvent *event){ // Reject a mouse moved if the button is down - screws up tracking during autoscroll // These happen because WebKit sometimes has to fake up moved events. if (!m_frame->view() || m_mousePressed || m_sendingEventToSubview) return; BEGIN_BLOCK_OBJC_EXCEPTIONS; RetainPtr<NSEvent> oldCurrentEvent = currentEvent(); currentEvent() = event; mouseMoved(PlatformMouseEvent(event)); ASSERT(currentEvent() == event); currentEvent() = oldCurrentEvent; END_BLOCK_OBJC_EXCEPTIONS;}bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe){ return passSubframeEventToSubframe(mev, subframe);}bool EventHandler::passMouseMoveEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe, HitTestResult* hoveredNode){ return passSubframeEventToSubframe(mev, subframe, hoveredNode);}bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe){ return passSubframeEventToSubframe(mev, subframe);}unsigned EventHandler::accessKeyModifiers(){ // Control+Option key combinations are usually unused on Mac OS X, but not when VoiceOver is enabled. // So, we use Control in this case, even though it conflicts with Emacs-style key bindings. // See <https://bugs.webkit.org/show_bug.cgi?id=21107> for more detail. if (AXObjectCache::accessibilityEnhancedUserInterfaceEnabled()) return PlatformKeyboardEvent::CtrlKey; return PlatformKeyboardEvent::CtrlKey | PlatformKeyboardEvent::AltKey;}}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?