WebKit:
authorjusting <justing@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 16 Feb 2006 09:21:52 +0000 (09:21 +0000)
committerjusting <justing@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 16 Feb 2006 09:21:52 +0000 (09:21 +0000)
        Reviewed by darin

        <http://bugzilla.opendarwin.org/show_bug.cgi?id=7148>
        Add drag and drop support to DumpRenderTree

        Added a UI delegate method so that DumpRenderTree can perform dragging on its own.
        Made _updateFocusState SPI, to allow us to test the behavior and appearance of
        windows that have or don't have focus.

        * WebView/WebHTMLView.m:
        (-[WebHTMLView _updateFocusState]):
        (-[NSArray viewDidMoveToWindow]):
        (-[NSArray windowDidBecomeKey:]):
        (-[NSArray windowDidResignKey:]):
        (-[NSArray dragImage:at:offset:event:pasteboard:source:slideBack:]):
        (-[NSArray becomeFirstResponder]):
        (-[NSArray resignFirstResponder]):
        (-[WebHTMLView _formControlIsResigningFirstResponder:]):
        * WebView/WebHTMLViewInternal.h:
        * WebView/WebHTMLViewPrivate.h:
        * WebView/WebUIDelegatePrivate.h:
        * WebView/WebView.m:

WebKitTools:

        Reviewed by darin

        <http://bugzilla.opendarwin.org/show_bug.cgi?id=7148>
        Add drag and drop support to DumpRenderTree

        Intercept the drag start using the new UI delegate method, package an NSDraggingInfo,
        and send dragging updates.  Put DumpRenderTree's WebView into an offscreen window.

        * DumpRenderTree/DumpRenderTree.m:
        (main):
        (-[WaitUntilDoneDelegate webView:didCommitLoadForFrame:]):
        (-[WaitUntilDoneDelegate webView:dragImage:at:offset:event:pasteboard:source:slideBack:forView:]):
        (-[WaitUntilDoneDelegate webViewFocus:]):
        (+[LayoutTestController isSelectorExcludedFromWebScript:]):
        (+[LayoutTestController webScriptNameForSelector:]):
        (-[LayoutTestController setWindowIsKey:]):
        (-[LayoutTestController setMainFrameIsFirstResponder:]):
        (-[EventSendingController init]):
        (-[EventSendingController mouseDown]):
        (-[EventSendingController mouseUp]):
        (-[EventSendingController mouseMoveToX:Y:]):
        (dumpRenderTree):
        (-[DumpRenderTreeWindow isKeyWindow]):
        (-[DumpRenderTreeDraggingInfo initWithImage:offset:pasteboard:source:]):
        (-[DumpRenderTreeDraggingInfo dealloc]):
        (-[DumpRenderTreeDraggingInfo draggingDestinationWindow]):
        (-[DumpRenderTreeDraggingInfo draggingSourceOperationMask]):
        (-[DumpRenderTreeDraggingInfo draggingLocation]):
        (-[DumpRenderTreeDraggingInfo draggedImageLocation]):
        (-[DumpRenderTreeDraggingInfo draggedImage]):
        (-[DumpRenderTreeDraggingInfo draggingPasteboard]):
        (-[DumpRenderTreeDraggingInfo draggingSource]):
        (-[DumpRenderTreeDraggingInfo draggingSequenceNumber]):
        (-[DumpRenderTreeDraggingInfo slideDraggedImageTo:]):
        (-[DumpRenderTreeDraggingInfo namesOfPromisedFilesDroppedAtDestination:]):
        * DumpRenderTree/TextInputController.m:
        (-[TextInputController firstRectForCharactersFrom:length:]):
        (-[TextInputController characterIndexForPointX:Y:]):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@12844 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebKit/ChangeLog
WebKit/WebView/WebHTMLView.m
WebKit/WebView/WebHTMLViewInternal.h
WebKit/WebView/WebHTMLViewPrivate.h
WebKit/WebView/WebUIDelegatePrivate.h
WebKitTools/ChangeLog
WebKitTools/DumpRenderTree/DumpRenderTree.m
WebKitTools/DumpRenderTree/TextInputController.m

index 424a4f99b9783c0a92e5898ea62e984d4ef5c9da..0a96e304f1dbc8cd006c34b9d451507ee534e912 100644 (file)
@@ -1,3 +1,28 @@
+2006-02-15  Justin Garcia  <justin.garcia@apple.com>
+
+        Reviewed by darin
+        
+        <http://bugzilla.opendarwin.org/show_bug.cgi?id=7148>
+        Add drag and drop support to DumpRenderTree
+        
+        Added a UI delegate method so that DumpRenderTree can perform dragging on its own.
+        Made _updateFocusState SPI, to allow us to test the behavior and appearance of
+        windows that have or don't have focus.
+
+        * WebView/WebHTMLView.m:
+        (-[WebHTMLView _updateFocusState]):
+        (-[NSArray viewDidMoveToWindow]):
+        (-[NSArray windowDidBecomeKey:]):
+        (-[NSArray windowDidResignKey:]):
+        (-[NSArray dragImage:at:offset:event:pasteboard:source:slideBack:]):
+        (-[NSArray becomeFirstResponder]):
+        (-[NSArray resignFirstResponder]):
+        (-[WebHTMLView _formControlIsResigningFirstResponder:]):
+        * WebView/WebHTMLViewInternal.h:
+        * WebView/WebHTMLViewPrivate.h:
+        * WebView/WebUIDelegatePrivate.h:
+        * WebView/WebView.m:
+
 2006-02-15  Darin Adler  <darin@apple.com>
 
         * English.lproj/StringsNotToBeLocalized.txt: Updated for recent changes.
index 69de3dd0694d0ec14dcdd470e3843a91894961b5..e8a90f7c3fbbf6c7dbe793df76bbefcea1dd4d36 100644 (file)
@@ -38,6 +38,7 @@
 #import <WebKit/WebClipView.h>
 #import <WebKit/WebDataProtocol.h>
 #import <WebKit/WebDataSourcePrivate.h>
+#import <WebKit/WebDefaultUIDelegate.h>
 #import <WebKit/WebDocumentInternal.h>
 #import <WebKit/WebDOMOperationsPrivate.h>
 #import <WebKit/WebEditingDelegate.h>
@@ -194,7 +195,6 @@ void *_NSSoftLinkingGetFrameworkFuncPtr(NSString *inUmbrellaFrameworkName,
 - (void)_deleteSelection;
 - (BOOL)_canSmartReplaceWithPasteboard:(NSPasteboard *)pasteboard;
 - (NSView *)_hitViewForEvent:(NSEvent *)event;
-- (void)updateFocusState;
 - (void)_writeSelectionWithPasteboardTypes:(NSArray *)types toPasteboard:(NSPasteboard *)pasteboard cachedAttributedString:(NSAttributedString *)attributedString;
 @end
 
@@ -627,29 +627,6 @@ void *_NSSoftLinkingGetFrameworkFuncPtr(NSString *inUmbrellaFrameworkName,
     }
 }
 
-- (void)updateFocusState
-{
-    // This method does the job of updating the view based on the view's firstResponder-ness and
-    // the window key-ness of the window containing this view. This involves four kinds of 
-    // drawing updates right now, all handled in WebCore in response to the call over the bridge. 
-    // 
-    // The four display attributes are as follows:
-    // 
-    // 1. The background color used to draw behind selected content (active | inactive color)
-    // 2. Caret blinking (blinks | does not blink)
-    // 3. The drawing of a focus ring around links in web pages.
-    // 4. Changing the tint of controls from clear to aqua/graphite and vice versa
-    //
-    // Also, this is responsible for letting the bridge know if the window has gained or lost focus
-    // so we can send focus and blur events.
-
-    BOOL windowIsKey = [[self window] isKeyWindow];
-    BOOL flag = !_private->resigningFirstResponder && windowIsKey && [self _web_firstResponderCausesFocusDisplay];
-    
-    [self _setDisplaysWithFocusAttributes:flag];
-    [self _setWindowHasFocus:windowIsKey];
-}
-
 @end
 
 @implementation WebHTMLView (WebPrivate)
@@ -1600,14 +1577,27 @@ static WebHTMLView *lastHitView = nil;
     return NSZeroRect;
 }
 
-- (void)_setWindowHasFocus:(BOOL)flag
+- (void)_updateFocusState
 {
-    [[self _bridge] setWindowHasFocus:flag];
-}
+    // This method does the job of updating the view based on the view's firstResponder-ness and
+    // the window key-ness of the window containing this view. This involves four kinds of 
+    // drawing updates right now, all handled in WebCore in response to the call over the bridge. 
+    // 
+    // The four display attributes are as follows:
+    // 
+    // 1. The background color used to draw behind selected content (active | inactive color)
+    // 2. Caret blinking (blinks | does not blink)
+    // 3. The drawing of a focus ring around links in web pages.
+    // 4. Changing the tint of controls from clear to aqua/graphite and vice versa
+    //
+    // Also, this is responsible for letting the bridge know if the window has gained or lost focus
+    // so we can send focus and blur events.
 
-- (void)_setDisplaysWithFocusAttributes:(BOOL)flag
-{
-    [[self _bridge] setDisplaysWithFocusAttributes:flag];
+    BOOL windowIsKey = [[self window] isKeyWindow];
+    BOOL displaysWithFocusAttributes = !_private->resigningFirstResponder && windowIsKey && [self _web_firstResponderCausesFocusDisplay];
+    
+    [[self _bridge] setWindowHasFocus:windowIsKey];
+    [[self _bridge] setDisplaysWithFocusAttributes:displaysWithFocusAttributes];
 }
 
 - (unsigned)highlightAllMatchesForString:(NSString *)string caseSensitive:(BOOL)caseFlag
@@ -2192,7 +2182,7 @@ static WebHTMLView *lastHitView = nil;
             // at the time this code is running. However, it will be there on the next
             // crank of the run loop. Doing this helps to make a blinking caret appear 
             // in a new, empty window "automatic".
-            [self performSelector:@selector(updateFocusState) withObject:nil afterDelay:0];
+            [self performSelector:@selector(_updateFocusState) withObject:nil afterDelay:0];
 
             [[self _pluginController] startAllPlugins];
     
@@ -2535,7 +2525,7 @@ static WebHTMLView *lastHitView = nil;
 {
     ASSERT([notification object] == [self window]);
     [self addMouseMovedObserver];
-    [self updateFocusState];
+    [self _updateFocusState];
 }
 
 - (void)windowDidResignKey: (NSNotification *)notification
@@ -2543,7 +2533,7 @@ static WebHTMLView *lastHitView = nil;
     ASSERT([notification object] == [self window]);
     [_private->compController endRevertingChange:NO moveLeft:NO];
     [self removeMouseMovedObserver];
-    [self updateFocusState];
+    [self _updateFocusState];
 }
 
 - (void)windowWillClose:(NSNotification *)notification
@@ -2658,16 +2648,22 @@ done:
        pasteboard:(NSPasteboard *)pasteboard
            source:(id)source
         slideBack:(BOOL)slideBack
-{   
+{
+    WebView *webView = [self _webView];
     [self _stopAutoscrollTimer];
-    
+
     _private->initiatedDrag = YES;
-    [[self _webView] _setInitiatedDrag:YES];
-    
+    [webView _setInitiatedDrag:YES];
+
     // Retain this view during the drag because it may be released before the drag ends.
     [self retain];
 
-    [super dragImage:dragImage at:at offset:offset event:event pasteboard:pasteboard source:source slideBack:slideBack];
+    id UIDelegate = [webView UIDelegate];
+    // If a delegate takes over the drag but never calls draggedImage: endedAt:, we'll leak the WebHTMLView.
+    if ([UIDelegate respondsToSelector:@selector(webView:dragImage:at:offset:event:pasteboard:source:slideBack:forView:)])
+        [UIDelegate webView:webView dragImage:dragImage at:at offset:offset event:event pasteboard:pasteboard source:source slideBack:slideBack forView:self];
+    else
+        [super dragImage:dragImage at:at offset:offset event:event pasteboard:pasteboard source:source slideBack:slideBack];
 }
 
 - (void)mouseDragged:(NSEvent *)event
@@ -2989,7 +2985,7 @@ done:
     if (view)
         [[self window] makeFirstResponder:view];
     [[[self _web_parentWebFrameView] webFrame] _clearSelectionInOtherFrames];
-    [self updateFocusState];
+    [self _updateFocusState];
     [self _updateFontPanel];
     _private->startNewKillRingSequence = YES;
     return YES;
@@ -3009,7 +3005,7 @@ done:
                 [self deselectAll];
             }
         }
-        [self updateFocusState];
+        [self _updateFocusState];
         _private->resigningFirstResponder = NO;
     }
     return resign;
@@ -4841,12 +4837,12 @@ static DOMRange *unionDOMRanges(DOMRange *a, DOMRange *b)
 
 - (void)_formControlIsResigningFirstResponder:(NSView *)formControl
 {
-    // set resigningFirstResponder so updateFocusState behaves the same way it does when
+    // set resigningFirstResponder so _updateFocusState behaves the same way it does when
     // the WebHTMLView itself is resigningFirstResponder; don't use the primary selection feedback.
     // If the first responder is in the process of being set on the WebHTMLView itself, it will
-    // get another chance at updateFocusState in its own becomeFirstResponder method.
+    // get another chance at _updateFocusState in its own becomeFirstResponder method.
     _private->resigningFirstResponder = YES;
-    [self updateFocusState];
+    [self _updateFocusState];
     _private->resigningFirstResponder = NO;
 }
 
index 4bf3ab7a43ca44c5ea5ba635d3c194f42db56213..cbc27db3e3e5d67caabe4cc62f0e19582f7a6d4e 100644 (file)
@@ -56,7 +56,7 @@
     NSEvent *keyDownEvent; // Kept only during handling of the event.
 
     NSURL *draggingImageURL;
-    unsigned int dragSourceActionMask;
+    unsigned dragSourceActionMask;
     
     NSSize lastLayoutSize;
     NSSize lastLayoutFrameSize;
index f927daa96122737e5ad7b5421575edb137a93ae2..634c768e41a4ee4268d494b3cf12817d9c80d947 100644 (file)
@@ -92,9 +92,8 @@
 - (NSImage *)_selectionDraggingImage;
 - (NSRect)_selectionDraggingRect;
 
-// Made into SPI so that DumpRenderTree could test the behavior and appearance of a WebHTMLView that is focused.
-- (void)_setWindowHasFocus:(BOOL)flag;
-- (void)_setDisplaysWithFocusAttributes:(BOOL)flag;
+// SPI for DumpRenderTree
+- (void)_updateFocusState;
 
 // These methods might end up moving into a protocol, so different document types can specify
 // whether or not they implement the protocol.
index 4fcfff3f1eee68d454c93d421eb6db373d7c37fa..2f20f6388872a9ba933ef8a5a143074ebc4806ea 100644 (file)
 // FIXME: Should we indicate a distinction between navigation and close?
 - (BOOL)webView:(WebView *)sender runBeforeUnloadConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame;
 
+- (void)webView:(WebView *)sender dragImage:(NSImage *)anImage at:(NSPoint)viewLocation offset:(NSSize)initialOffset event:(NSEvent *)event pasteboard:(NSPasteboard *)pboard source:(id)sourceObj slideBack:(BOOL)slideFlag forView:(NSView *)view;
+
 @end
index 1c240f44820da4f746ef7ea45e1a56da92c6ca3c..4b147dfc222e23fbe6a74aeaab93ced3c1768270 100644 (file)
@@ -1,3 +1,44 @@
+2006-02-15  Justin Garcia  <justin.garcia@apple.com>
+
+        Reviewed by darin
+        
+        <http://bugzilla.opendarwin.org/show_bug.cgi?id=7148>
+        Add drag and drop support to DumpRenderTree
+        
+        Intercept the drag start using the new UI delegate method, package an NSDraggingInfo,
+        and send dragging updates.  Put DumpRenderTree's WebView into an offscreen window.
+
+        * DumpRenderTree/DumpRenderTree.m:
+        (main):
+        (-[WaitUntilDoneDelegate webView:didCommitLoadForFrame:]):
+        (-[WaitUntilDoneDelegate webView:dragImage:at:offset:event:pasteboard:source:slideBack:forView:]):
+        (-[WaitUntilDoneDelegate webViewFocus:]):
+        (+[LayoutTestController isSelectorExcludedFromWebScript:]):
+        (+[LayoutTestController webScriptNameForSelector:]):
+        (-[LayoutTestController setWindowIsKey:]):
+        (-[LayoutTestController setMainFrameIsFirstResponder:]):
+        (-[EventSendingController init]):
+        (-[EventSendingController mouseDown]):
+        (-[EventSendingController mouseUp]):
+        (-[EventSendingController mouseMoveToX:Y:]):
+        (dumpRenderTree):
+        (-[DumpRenderTreeWindow isKeyWindow]):
+        (-[DumpRenderTreeDraggingInfo initWithImage:offset:pasteboard:source:]):
+        (-[DumpRenderTreeDraggingInfo dealloc]):
+        (-[DumpRenderTreeDraggingInfo draggingDestinationWindow]):
+        (-[DumpRenderTreeDraggingInfo draggingSourceOperationMask]):
+        (-[DumpRenderTreeDraggingInfo draggingLocation]):
+        (-[DumpRenderTreeDraggingInfo draggedImageLocation]):
+        (-[DumpRenderTreeDraggingInfo draggedImage]):
+        (-[DumpRenderTreeDraggingInfo draggingPasteboard]):
+        (-[DumpRenderTreeDraggingInfo draggingSource]):
+        (-[DumpRenderTreeDraggingInfo draggingSequenceNumber]):
+        (-[DumpRenderTreeDraggingInfo slideDraggedImageTo:]):
+        (-[DumpRenderTreeDraggingInfo namesOfPromisedFilesDroppedAtDestination:]):
+        * DumpRenderTree/TextInputController.m:
+        (-[TextInputController firstRectForCharactersFrom:length:]):
+        (-[TextInputController characterIndexForPointX:Y:]):
+        
 2006-02-15  Geoffrey Garen  <ggaren@apple.com>
 
         Reviewed by Eric.
index cd682e6deef27df35d1bd4f369611a3fa681b095..dbe69aa859a84d0d99a55bdc11d6b3099a0033ec 100644 (file)
@@ -28,6 +28,7 @@
 
 #import <WebKit/DOMExtensions.h>
 #import <WebKit/DOMRange.h>
+#import <WebKit/WebBackForwardList.h>
 #import <WebKit/WebCoreStatistics.h>
 #import <WebKit/WebDataSource.h>
 #import <WebKit/WebEditingDelegate.h>
 #import "NavigationController.h"
 #import "AppleScriptController.h"
 
+@interface DumpRenderTreeWindow : NSWindow
+@end
+
+@interface DumpRenderTreeDraggingInfo : NSObject <NSDraggingInfo>
+{
+@private
+    NSSize offset;
+    NSImage *draggedImage;
+    NSPasteboard *draggingPasteboard;
+    id draggingSource;
+}
+- (id)initWithImage:(NSImage *)image offset:(NSSize)offset pasteboard:(NSPasteboard *)pasteboard source:(id)source; 
+- (NSWindow *)draggingDestinationWindow;
+- (NSDragOperation)draggingSourceOperationMask;
+- (NSPoint)draggingLocation;
+- (NSPoint)draggedImageLocation;
+- (NSImage *)draggedImage;
+- (NSPasteboard *)draggingPasteboard;
+- (id)draggingSource;
+- (int)draggingSequenceNumber;
+- (void)slideDraggedImageTo:(NSPoint)screenPoint;
+- (NSArray *)namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropDestination;
+@end
+
 @interface DumpRenderTreePasteboard : NSPasteboard
 @end
 
 
 @interface EventSendingController : NSObject
 {
-    NSPoint last;
     BOOL down;
     int clickCount;
     NSTimeInterval lastClick;
 }
-
 @end
 
 static void dumpRenderTree(const char *filename);
@@ -86,6 +109,9 @@ static int dumpTree = YES;
 static BOOL printSeparators;
 static NSString *currentTest = nil;
 static NSPasteboard *localPasteboard;
+static BOOL windowIsKey = YES;
+static NSPoint lastMousePosition;
+static DumpRenderTreeDraggingInfo *draggingInfo;
 
 static CMProfileRef currentColorProfile = 0;
 static void restoreColorSpace(int ignored)
@@ -140,6 +166,7 @@ int main(int argc, const char *argv[])
     [NSApplication sharedApplication];
 
     class_poseAs(objc_getClass("DumpRenderTreePasteboard"), objc_getClass("NSPasteboard"));
+    class_poseAs(objc_getClass("DumpRenderTreeWindow"), objc_getClass("NSWindow"));
     
     struct option options[] = {
         {"pixel-tests", no_argument, &dumpPixels, YES},
@@ -193,14 +220,26 @@ int main(int argc, const char *argv[])
     localPasteboard = [NSPasteboard pasteboardWithUniqueName];
     navigationController = [[NavigationController alloc] init];
 
-    WebView *webView = [[WebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)];
+    NSRect rect = NSMakeRect(0, 0, 800, 600);
+    
+    WebView *webView = [[WebView alloc] initWithFrame:rect];
     WaitUntilDoneDelegate *delegate = [[WaitUntilDoneDelegate alloc] init];
     EditingDelegate *editingDelegate = [[EditingDelegate alloc] init];
     [webView setFrameLoadDelegate:delegate];
     [webView setEditingDelegate:editingDelegate];
     [webView setUIDelegate:delegate];
     frame = [webView mainFrame];
-    
+
+    // The back/forward cache is causing problems due to layouts during transition from one page to another.
+    // So, turn it off for now, but we might want to turn it back on some day.
+    [[webView backForwardList] setPageCacheSize:0];
+
+    // To make things like certain NSViews, dragging, and plug-ins work, put the WebView a window, but put it off-screen so you don't see it.
+    NSRect windowRect = NSOffsetRect(rect, -10000, -10000);
+    NSWindow *window = [[NSWindow alloc] initWithContentRect:windowRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES];
+    [[window contentView] addSubview:webView];
+    [window orderBack:nil];
+
     [webView setContinuousSpellCheckingEnabled:YES];
     
     // For reasons that are not entirely clear, the following pair of calls makes WebView handle its
@@ -234,6 +273,13 @@ int main(int argc, const char *argv[])
     [webView setUIDelegate:nil];
     frame = nil;
 
+    // Work around problem where registering drag types leaves an outstanding
+    // "perform selector" on the window, which retains the window. It's a bit
+    // inelegant and perhaps dangerous to just blow them all away, but in practice
+    // it probably won't cause any trouble (and this is just a test tool, after all).
+    [NSObject cancelPreviousPerformRequestsWithTarget:window];
+    
+    [window release];
     [webView release];
     [delegate release];
     [editingDelegate release];
@@ -329,11 +375,12 @@ static void dump(void)
 {
     if (frame == f)
         readyToDump = NO;
-        
-    if ([[[frame frameView] documentView] isKindOfClass:[WebHTMLView class]]) {
-        [(WebHTMLView *)[[frame frameView] documentView] _setWindowHasFocus:YES];
-        [(WebHTMLView *)[[frame frameView] documentView] _setDisplaysWithFocusAttributes:YES];
-    }
+
+    windowIsKey = YES;
+    NSView *documentView = [[frame frameView] documentView];
+    [[[frame webView] window] makeFirstResponder:documentView];
+    if ([documentView isKindOfClass:[WebHTMLView class]])
+        [(WebHTMLView *)documentView _updateFocusState];
 }
 
 - (void)webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame
@@ -380,6 +427,24 @@ static void dump(void)
         printf("TITLE CHANGED: %s\n", [title UTF8String]);
 }
 
+- (void)webView:(WebView *)sender dragImage:(NSImage *)anImage at:(NSPoint)viewLocation offset:(NSSize)initialOffset event:(NSEvent *)event pasteboard:(NSPasteboard *)pboard source:(id)sourceObj slideBack:(BOOL)slideFlag forView:(NSView *)view
+{
+    // A new drag was started before the old one ended.  Probably shouldn't happen.
+    if (draggingInfo) {
+        [[draggingInfo draggingSource] draggedImage:[draggingInfo draggedImage] endedAt:lastMousePosition operation:NSDragOperationNone];
+        [draggingInfo release];
+    }
+    draggingInfo = [[DumpRenderTreeDraggingInfo alloc] initWithImage:anImage offset:initialOffset pasteboard:pboard source:sourceObj];
+}
+
+- (void)webViewFocus:(WebView *)webView
+{
+    windowIsKey = YES;
+    NSView *documentView = [[frame frameView] documentView];
+    if ([documentView isKindOfClass:[WebHTMLView class]])
+        [(WebHTMLView *)documentView _updateFocusState];
+}
+
 @end
 
 @interface DOMNode (dumpPath)
@@ -518,18 +583,18 @@ static void dump(void)
             || aSelector == @selector(notifyDone)
             || aSelector == @selector(dumpAsText)
             || aSelector == @selector(dumpTitleChanges)
-            || aSelector == @selector(setWindowHasFocus:)
-            || aSelector == @selector(setDisplaysWithFocusAttributes:))
+            || aSelector == @selector(setWindowIsKey:)
+            || aSelector == @selector(setMainFrameIsFirstResponder:))
         return NO;
     return YES;
 }
 
 + (NSString *)webScriptNameForSelector:(SEL)aSelector
 {
-    if (aSelector == @selector(setWindowHasFocus:))
-        return @"setWindowHasFocus";
-    if (aSelector == @selector(setDisplaysWithFocusAttributes:))
-        return @"setDisplaysWithFocusAttributes";
+    if (aSelector == @selector(setWindowIsKey:))
+        return @"setWindowIsKey";
+    if (aSelector == @selector(setMainFrameIsFirstResponder:))
+        return @"setMainFrameIsFirstResponder";
     return nil;
 }
 
@@ -555,16 +620,23 @@ static void dump(void)
     dumpTitleChanges = YES;
 }
 
-- (void)setWindowHasFocus:(BOOL)flag
+- (void)setWindowIsKey:(BOOL)flag
 {
-    if ([[[frame frameView] documentView] isKindOfClass:[WebHTMLView class]])
-        [(WebHTMLView *)[[frame frameView] documentView] _setWindowHasFocus:flag];
+    windowIsKey = flag;
+    NSView *documentView = [[frame frameView] documentView];
+    if ([documentView isKindOfClass:[WebHTMLView class]])
+        [(WebHTMLView *)documentView _updateFocusState];
 }
 
-- (void)setDisplaysWithFocusAttributes:(BOOL)flag
+- (void)setMainFrameIsFirstResponder:(BOOL)flag
 {
-    if ([[[frame frameView] documentView] isKindOfClass:[WebHTMLView class]])
-        [(WebHTMLView *)[[frame frameView] documentView] _setDisplaysWithFocusAttributes:flag];
+    NSView *documentView = [[frame frameView] documentView];
+    
+    NSResponder *firstResponder = flag ? documentView : nil;
+    [[[frame webView] window] makeFirstResponder:firstResponder];
+        
+    if ([documentView isKindOfClass:[WebHTMLView class]])
+        [(WebHTMLView *)documentView _updateFocusState];
 }
 
 - (id)invokeUndefinedMethodFromWebScript:(NSString *)name withArguments:(NSArray *)args
@@ -594,7 +666,7 @@ static void dump(void)
 
 - (id)init
 {
-    last = NSMakePoint(0, 0);
+    lastMousePosition = NSMakePoint(0, 0);
     down = NO;
     clickCount = 0;
     lastClick = 0;
@@ -608,7 +680,7 @@ static void dump(void)
         clickCount = 1;
     else
         clickCount++;
-    NSEvent *event = [NSEvent mouseEventWithType:NSLeftMouseDown location:last modifierFlags:nil timestamp:GetCurrentEventTime() windowNumber:0 context:[NSGraphicsContext currentContext] eventNumber:nil clickCount:clickCount pressure:nil];
+    NSEvent *event = [NSEvent mouseEventWithType:NSLeftMouseDown location:lastMousePosition modifierFlags:nil timestamp:GetCurrentEventTime() windowNumber:0 context:[NSGraphicsContext currentContext] eventNumber:nil clickCount:clickCount pressure:nil];
 
     NSView *subView = [[frame webView] hitTest:[event locationInWindow]];
     if (subView) {
@@ -620,25 +692,39 @@ static void dump(void)
 - (void)mouseUp
 {
     [[[frame frameView] documentView] layout];
-    NSEvent *event = [NSEvent mouseEventWithType:NSLeftMouseUp location:last modifierFlags:nil timestamp:GetCurrentEventTime() windowNumber:0 context:[NSGraphicsContext currentContext] eventNumber:nil clickCount:clickCount pressure:nil];
+    NSEvent *event = [NSEvent mouseEventWithType:NSLeftMouseUp location:lastMousePosition modifierFlags:nil timestamp:GetCurrentEventTime() windowNumber:0 context:[NSGraphicsContext currentContext] eventNumber:nil clickCount:clickCount pressure:nil];
 
     NSView *subView = [[frame webView] hitTest:[event locationInWindow]];
     if (subView) {
         [subView mouseUp:event];
         down = NO;
         lastClick = [event timestamp];
+        if (draggingInfo) {
+            WebView *webView = [frame webView];
+            
+            NSDragOperation dragOperation = [webView draggingUpdated:draggingInfo];
+            
+            [[draggingInfo draggingSource] draggedImage:[draggingInfo draggedImage] endedAt:lastMousePosition operation:dragOperation];
+            if (dragOperation != NSDragOperationNone)
+                [webView performDragOperation:draggingInfo];
+            [draggingInfo release];
+            draggingInfo = nil;
+        }
     }
 }
 
 - (void)mouseMoveToX:(int)x Y:(int)y
 {
-    last = NSMakePoint(x, [[frame webView] frame].size.height - y);
-    NSEvent *event = [NSEvent mouseEventWithType:(down ? NSLeftMouseDragged : NSMouseMoved) location:last modifierFlags:nil timestamp:GetCurrentEventTime() windowNumber:0 context:[NSGraphicsContext currentContext] eventNumber:nil clickCount:(down ? clickCount : 0) pressure:nil];
+    lastMousePosition = NSMakePoint(x, [[frame webView] frame].size.height - y);
+    NSEvent *event = [NSEvent mouseEventWithType:(down ? NSLeftMouseDragged : NSMouseMoved) location:lastMousePosition modifierFlags:nil timestamp:GetCurrentEventTime() windowNumber:0 context:[NSGraphicsContext currentContext] eventNumber:nil clickCount:(down ? clickCount : 0) pressure:nil];
 
     NSView *subView = [[frame webView] hitTest:[event locationInWindow]];
     if (subView) {
-        if (down)
+        if (down) {
             [subView mouseDragged:event];
+            [[draggingInfo draggingSource] draggedImage:[draggingInfo draggedImage] movedTo:lastMousePosition];
+            [[frame webView] draggingUpdated:draggingInfo];
+        }
         else
             [subView mouseMoved:event];
     }
@@ -681,6 +767,9 @@ static void dumpRenderTree(const char *filename)
     }
     pool = [[NSAutoreleasePool alloc] init];
     [[frame webView] setSelectedDOMRange:nil affinity:NSSelectionAffinityDownstream];
+    if (draggingInfo)
+        [draggingInfo release];
+    draggingInfo = nil;
     [pool release];
 }
 
@@ -711,3 +800,87 @@ static NSString *md5HashStringForBitmap(NSBitmapImageRep *bitmap)
 }
 
 @end
+
+@implementation DumpRenderTreeWindow
+
+- (BOOL)isKeyWindow
+{
+    return windowIsKey;
+}
+
+@end
+
+@implementation DumpRenderTreeDraggingInfo
+
+- (id)initWithImage:(NSImage *)anImage offset:(NSSize)o pasteboard:(NSPasteboard *)pboard source:(id)source
+{
+    draggedImage = [anImage retain];
+    draggingPasteboard = [pboard retain];
+    draggingSource = [source retain];
+    offset = o;
+    
+    return [super init];
+}
+
+- (void)dealloc
+{
+    [draggedImage release];
+    [draggingPasteboard release];
+    [draggingSource release];
+    [super dealloc];
+}
+
+- (NSWindow *)draggingDestinationWindow 
+{
+    return [[frame webView] window];
+}
+
+- (NSDragOperation)draggingSourceOperationMask 
+{
+    return [draggingSource draggingSourceOperationMaskForLocal:YES];
+}
+
+- (NSPoint)draggingLocation
+{ 
+    return lastMousePosition; 
+}
+
+- (NSPoint)draggedImageLocation 
+{
+    return NSMakePoint(lastMousePosition.x + offset.width, lastMousePosition.y + offset.height);
+}
+
+- (NSImage *)draggedImage
+{
+    return draggedImage;
+}
+
+- (NSPasteboard *)draggingPasteboard
+{
+    return draggingPasteboard;
+}
+
+- (id)draggingSource
+{
+    return draggingSource;
+}
+
+- (int)draggingSequenceNumber
+{
+    NSLog(@"DumpRenderTree doesn't support draggingSequenceNumber");
+    return 0;
+}
+
+- (void)slideDraggedImageTo:(NSPoint)screenPoint
+{
+    NSLog(@"DumpRenderTree doesn't support slideDraggedImageTo:");
+}
+
+- (NSArray *)namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropDestination
+{
+    NSLog(@"DumpRenderTree doesn't support namesOfPromisedFilesDroppedAtDestination:");
+    return nil;
+}
+
+@end
+
index 6093e878571554422c13ed445781b98dd45b5733..d28d7c8908a93cf7a5840787f5de22d692042cd3 100644 (file)
 
     if (textInput) {
         NSRect rect = [textInput firstRectForCharacterRange:NSMakeRange(from, length)];
+        if (rect.origin.x || rect.origin.y || rect.size.width || rect.size.height) {
+            rect.origin = [[webView window] convertScreenToBase:rect.origin];
+            rect = [webView convertRect:rect fromView:nil];
+        }
         return [NSArray arrayWithObjects:
                     [NSNumber numberWithFloat:rect.origin.x],
                     [NSNumber numberWithFloat:rect.origin.y],
 {
     NSObject <NSTextInput> *textInput = [self textInput];
 
-    if (textInput)
-        return [textInput characterIndexForPoint:NSMakePoint(x, y)];
+    if (textInput) {
+        NSPoint point = NSMakePoint(x, y);
+        point = [webView convertPoint:point toView:nil];
+        point = [[webView window] convertBaseToScreen:point];
+        return [textInput characterIndexForPoint:point];
+    }
 
     return 0;
 }