1cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block/* 2cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 3cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block * Copyright (C) 2006 David Smith (catfish.man@gmail.com) 4cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block * 5cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block * Redistribution and use in source and binary forms, with or without 6cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block * modification, are permitted provided that the following conditions 7cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block * are met: 8cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block * 9cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block * 1. Redistributions of source code must retain the above copyright 10cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block * notice, this list of conditions and the following disclaimer. 11cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block * 2. Redistributions in binary form must reproduce the above copyright 12cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block * notice, this list of conditions and the following disclaimer in the 13cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block * documentation and/or other materials provided with the distribution. 14cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 15cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block * its contributors may be used to endorse or promote products derived 16cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block * from this software without specific prior written permission. 17cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block * 18cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 19cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 22cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block */ 29cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 30cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#import "WebViewInternal.h" 31cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 32cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#import "WebFrameInternal.h" 33cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#import "WebHTMLView.h" 34cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#import "WebTextCompletionController.h" 35cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#import "WebViewData.h" 36cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#import <WebCore/Frame.h> 37cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 38cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockusing namespace WebCore; 39cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 40cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block@class NSTextInputContext; 41cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 42cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block@interface NSResponder (WebNSResponderDetails) 43cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block- (NSTextInputContext *)inputContext; 44cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block@end 45cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 46cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) 47cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block@interface NSObject (NSTextInputContextDetails) 48cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block- (BOOL)wantsToHandleMouseEvents; 49cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block- (BOOL)handleMouseEvent:(NSEvent *)event; 50cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block@end 51cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#endif 52cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 53cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block@implementation WebView (WebViewEventHandling) 54cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 55cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockstatic WebView *lastMouseoverView; 56cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 57cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block- (void)_closingEventHandling 58cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{ 59cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (lastMouseoverView == self) 60cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block lastMouseoverView = nil; 61cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block} 62cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 63cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block- (void)_setMouseDownEvent:(NSEvent *)event 64cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{ 65cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block ASSERT(!event || [event type] == NSLeftMouseDown || [event type] == NSRightMouseDown || [event type] == NSOtherMouseDown); 66cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 67cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (event == _private->mouseDownEvent) 68cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return; 69cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 70cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block [event retain]; 71cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block [_private->mouseDownEvent release]; 72cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block _private->mouseDownEvent = event; 73cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block} 74cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 75cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block- (void)mouseDown:(NSEvent *)event 76cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{ 77cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // FIXME (Viewless): This method should be shared with WebHTMLView, which needs to 78cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // do the same work in the usesDocumentViews case. We don't want to maintain two 79cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // duplicate copies of this method. 80cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 81cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (_private->usesDocumentViews) { 82cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block [super mouseDown:event]; 83cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return; 84cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 85cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 86cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // There's a chance that responding to this event will run a nested event loop, and 87cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // fetching a new event might release the old one. Retaining and then autoreleasing 88cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // the current event prevents that from causing a problem inside WebKit or AppKit code. 89cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block [[event retain] autorelease]; 90cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 91cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block RetainPtr<WebView> protector = self; 92cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if ([[self inputContext] wantsToHandleMouseEvents] && [[self inputContext] handleMouseEvent:event]) 93cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return; 94cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 95cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block _private->handlingMouseDownEvent = YES; 96cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 97cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // Record the mouse down position so we can determine drag hysteresis. 98cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block [self _setMouseDownEvent:event]; 99cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 100cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block NSInputManager *currentInputManager = [NSInputManager currentInputManager]; 101cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if ([currentInputManager wantsToHandleMouseEvents] && [currentInputManager handleMouseEvent:event]) 102cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block goto done; 103cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 104cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block [_private->completionController endRevertingChange:NO moveLeft:NO]; 105cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 106cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // If the web page handles the context menu event and menuForEvent: returns nil, we'll get control click events here. 107cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // We don't want to pass them along to KHTML a second time. 108cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (!([event modifierFlags] & NSControlKeyMask)) { 109cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block _private->ignoringMouseDraggedEvents = NO; 110cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 111cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // Don't do any mouseover while the mouse is down. 112cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block [self _cancelUpdateMouseoverTimer]; 113cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 114cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // Let WebCore get a chance to deal with the event. This will call back to us 115cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // to start the autoscroll timer if appropriate. 116cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (Frame* frame = [self _mainCoreFrame]) 117cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block frame->eventHandler()->mouseDown(event); 118cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 119cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 120cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockdone: 121cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block _private->handlingMouseDownEvent = NO; 122cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block} 123cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 124cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block- (void)mouseUp:(NSEvent *)event 125cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{ 126cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // FIXME (Viewless): This method should be shared with WebHTMLView, which needs to 127cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // do the same work in the usesDocumentViews case. We don't want to maintain two 128cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // duplicate copies of this method. 129cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 130cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (_private->usesDocumentViews) { 131cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block [super mouseUp:event]; 132cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return; 133cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 134cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 135cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // There's a chance that responding to this event will run a nested event loop, and 136cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // fetching a new event might release the old one. Retaining and then autoreleasing 137cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // the current event prevents that from causing a problem inside WebKit or AppKit code. 138cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block [[event retain] autorelease]; 139cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 140cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block [self _setMouseDownEvent:nil]; 141cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 142cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block NSInputManager *currentInputManager = [NSInputManager currentInputManager]; 143cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if ([currentInputManager wantsToHandleMouseEvents] && [currentInputManager handleMouseEvent:event]) 144cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return; 145cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 146cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block [self retain]; 147cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 148cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block [self _stopAutoscrollTimer]; 149cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (Frame* frame = [self _mainCoreFrame]) 150cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block frame->eventHandler()->mouseUp(event); 151cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block [self _updateMouseoverWithFakeEvent]; 152cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 153cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block [self release]; 154cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block} 155cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 156cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block+ (void)_updateMouseoverWithEvent:(NSEvent *)event 157cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{ 158cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block WebView *oldView = lastMouseoverView; 159cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 160cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block lastMouseoverView = nil; 161cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 162cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block NSView *contentView = [[event window] contentView]; 163cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block NSPoint locationForHitTest = [[contentView superview] convertPoint:[event locationInWindow] fromView:nil]; 164cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block for (NSView *hitView = [contentView hitTest:locationForHitTest]; hitView; hitView = [hitView superview]) { 165cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if ([hitView isKindOfClass:[WebView class]]) { 166cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block lastMouseoverView = static_cast<WebView *>(hitView); 167cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block break; 168cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 169cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 170cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 171cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (lastMouseoverView && lastMouseoverView->_private->hoverFeedbackSuspended) 172cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block lastMouseoverView = nil; 173cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 174cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (lastMouseoverView != oldView) { 175cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (Frame* oldCoreFrame = [oldView _mainCoreFrame]) { 176cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block NSEvent *oldViewEvent = [NSEvent mouseEventWithType:NSMouseMoved 177cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block location:NSMakePoint(-1, -1) 178cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block modifierFlags:[[NSApp currentEvent] modifierFlags] 179cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block timestamp:[NSDate timeIntervalSinceReferenceDate] 180cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block windowNumber:[[oldView window] windowNumber] 181cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block context:[[NSApp currentEvent] context] 182cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block eventNumber:0 clickCount:0 pressure:0]; 183cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block oldCoreFrame->eventHandler()->mouseMoved(oldViewEvent); 184cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 185cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 186cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 187cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (!lastMouseoverView) 188cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return; 189cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 190cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (Frame* coreFrame = core([lastMouseoverView mainFrame])) 191cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block coreFrame->eventHandler()->mouseMoved(event); 192cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block} 193cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 194cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block- (void)_updateMouseoverWithFakeEvent 195cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{ 196cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block [self _cancelUpdateMouseoverTimer]; 197cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 198cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block NSEvent *fakeEvent = [NSEvent mouseEventWithType:NSMouseMoved 199cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block location:[[self window] convertScreenToBase:[NSEvent mouseLocation]] 200cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block modifierFlags:[[NSApp currentEvent] modifierFlags] 201cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block timestamp:[NSDate timeIntervalSinceReferenceDate] 202cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block windowNumber:[[self window] windowNumber] 203cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block context:[[NSApp currentEvent] context] 204cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block eventNumber:0 clickCount:0 pressure:0]; 205cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 206cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block [[self class] _updateMouseoverWithEvent:fakeEvent]; 207cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block} 208cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 209cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block- (void)_cancelUpdateMouseoverTimer 210cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{ 211cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (_private->updateMouseoverTimer) { 212cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block CFRunLoopTimerInvalidate(_private->updateMouseoverTimer); 213cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block CFRelease(_private->updateMouseoverTimer); 214cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block _private->updateMouseoverTimer = NULL; 215cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 216cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block} 217cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 218cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block- (void)_stopAutoscrollTimer 219cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{ 220cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block NSTimer *timer = _private->autoscrollTimer; 221cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block _private->autoscrollTimer = nil; 222cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block [_private->autoscrollTriggerEvent release]; 223cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block _private->autoscrollTriggerEvent = nil; 224cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block [timer invalidate]; 225cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block [timer release]; 226cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block} 227cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 228cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block- (void)_setToolTip:(NSString *)toolTip 229cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{ 230cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (_private->usesDocumentViews) { 231cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block id documentView = [[[self _selectedOrMainFrame] frameView] documentView]; 232cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if ([documentView isKindOfClass:[WebHTMLView class]]) 233cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block [documentView _setToolTip:toolTip]; 234cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return; 235cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 236cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 237cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // FIXME (Viewless): Code to handle tooltips needs to move into WebView. 238cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block} 239cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 240cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block@end 241