Reviewed by Ken.
authordarin <darin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 12 Jan 2005 23:55:08 +0000 (23:55 +0000)
committerdarin <darin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 12 Jan 2005 23:55:08 +0000 (23:55 +0000)
        - fixed <rdar://problem/3848257> WebView will draw more than AppKit asks it to, so views behind won't redraw enough (transparent WebView)

        * WebView.subproj/WebHTMLView.m:
        (-[WebHTMLView _propagateDirtyRectsToOpaqueAncestors]): As recommended by Troy Stephens, do the
        layouts here in this call, since it's before propagating the dirty rects to our ancestors.
        This fixes the bug, but we only do it if the WebView is not opaque, because otherwise we can
        optimize by only doing layouts you really need, and doing them later on is safe because we
        know we don't need to draw any of the views behind us.
        (-[WebHTMLView _layoutIfNeeded]): Added. Factored out from the method below.
        (-[WebHTMLView _web_layoutIfNeededRecursive]): Added. Like the other "layout if needed" call,
        but unconditional.
        (-[WebHTMLView _web_layoutIfNeededRecursive:testDirtyRect:]): Factored out the guts into the
        _layoutIfNeeded method above. Otherwise unchanged.
        (-[NSView _web_layoutIfNeededRecursive]): Added.

        * WebView.subproj/WebFrame.m: (-[WebFrame _updateDrawsBackground]): Call setDrawsBackground:NO
        on the scroll view when changing the frame to no longer be in "draws background" mode. This
        is needed because the frame manages the "draws background" mode of the scroll view. It won't
        have any effect if you call setDrawsBackground:NO before starting to use a WebView, but without
        it calling setDrawsBackground:NO later won't have an immediate effect (easily visible in Safari).
        This was hidden before because the HTML view was filling with transparent color, which blew away
        the fill that was done by NSScrollView.

        - fixed <rdar://problem/3921129> reproducible crash at www.funnychristmas.com in CFSet manipulation in WebImageData

        * WebCoreSupport.subproj/WebImageData.m:
        (-[WebImageData _imageSourceOptions]): Changed types so we don't need a cast.
        (+[WebImageData stopAnimationsInView:]): Instead of building a set of sets, by putting in the sets with addObject,
        build a single set using unionSet, and then iterate the objects instead of having to iterate the sets and then the
        objects in each set. The old code ended up sharing the sets with the live code, when the whole idea was to gather
        all the renderers because the process of stopping modifies the active sets.

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

WebKit/ChangeLog
WebKit/WebCoreSupport.subproj/WebImageData.m
WebKit/WebView.subproj/WebFrame.m
WebKit/WebView.subproj/WebHTMLView.m

index f4b60b37b3ec42cbb4f1a10b2ea31969d16718b0..be38146f23aafac68b80fe8b9f441b54ddcb6ea8 100644 (file)
@@ -1,3 +1,39 @@
+2005-01-12  Darin Adler  <darin@apple.com>
+
+        Reviewed by Ken.
+
+        - fixed <rdar://problem/3848257> WebView will draw more than AppKit asks it to, so views behind won't redraw enough (transparent WebView)
+
+        * WebView.subproj/WebHTMLView.m:
+        (-[WebHTMLView _propagateDirtyRectsToOpaqueAncestors]): As recommended by Troy Stephens, do the
+        layouts here in this call, since it's before propagating the dirty rects to our ancestors.
+        This fixes the bug, but we only do it if the WebView is not opaque, because otherwise we can
+        optimize by only doing layouts you really need, and doing them later on is safe because we
+        know we don't need to draw any of the views behind us.
+        (-[WebHTMLView _layoutIfNeeded]): Added. Factored out from the method below.
+        (-[WebHTMLView _web_layoutIfNeededRecursive]): Added. Like the other "layout if needed" call,
+        but unconditional.
+        (-[WebHTMLView _web_layoutIfNeededRecursive:testDirtyRect:]): Factored out the guts into the
+        _layoutIfNeeded method above. Otherwise unchanged.
+        (-[NSView _web_layoutIfNeededRecursive]): Added.
+
+        * WebView.subproj/WebFrame.m: (-[WebFrame _updateDrawsBackground]): Call setDrawsBackground:NO
+        on the scroll view when changing the frame to no longer be in "draws background" mode. This
+        is needed because the frame manages the "draws background" mode of the scroll view. It won't
+        have any effect if you call setDrawsBackground:NO before starting to use a WebView, but without
+        it calling setDrawsBackground:NO later won't have an immediate effect (easily visible in Safari).
+        This was hidden before because the HTML view was filling with transparent color, which blew away
+        the fill that was done by NSScrollView.
+
+        - fixed <rdar://problem/3921129> reproducible crash at www.funnychristmas.com in CFSet manipulation in WebImageData
+
+        * WebCoreSupport.subproj/WebImageData.m:
+        (-[WebImageData _imageSourceOptions]): Changed types so we don't need a cast.
+        (+[WebImageData stopAnimationsInView:]): Instead of building a set of sets, by putting in the sets with addObject,
+        build a single set using unionSet, and then iterate the objects instead of having to iterate the sets and then the
+        objects in each set. The old code ended up sharing the sets with the live code, when the whole idea was to gather
+        all the renderers because the process of stopping modifies the active sets.
+
 2005-01-12  Richard Williamson   <rjw@apple.com>
 
        Fixed <rdar://problem/3926825> Safari ignores GIF loop count
index b28719e114f949d3763d85ef6be95e3802b87d5c..cdfdc3a84a95aa379594fa765b653dc39e155876 100644 (file)
@@ -157,9 +157,9 @@ static CFDictionaryRef imageSourceOptions;
 - (CFDictionaryRef)_imageSourceOptions
 {
     if (!imageSourceOptions) {
-        CFStringRef keys[1] = { kCGImageSourceShouldCache };
-        CFBooleanRef values[1] = { kCFBooleanTrue };
-        imageSourceOptions = CFDictionaryCreate (NULL, (const void **)&keys, (const void **)&values, 1, 
+        const void * keys[1] = { kCGImageSourceShouldCache };
+        const void * values[1] = { kCFBooleanTrue };
+        imageSourceOptions = CFDictionaryCreate (NULL, keys, values, 1, 
                 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
     }
     return imageSourceOptions;
@@ -174,9 +174,9 @@ static CFDictionaryRef imageSourceOptions;
        CFStringRef colorModel = CFDictionaryGetValue (props, kCGImagePropertyColorModel);
        
        if (colorModel) {
-           if (CFStringCompare (colorModel, (CFStringRef)@"RGB", 0) == kCFCompareEqualTo)
+           if (CFStringCompare (colorModel, CFSTR("RGB"), 0) == kCFCompareEqualTo)
                uncorrectedColorSpace = CGColorSpaceCreateDisplayRGB();
-           else if (CFStringCompare (colorModel, (CFStringRef)@"Gray", 0) == kCFCompareEqualTo)
+           else if (CFStringCompare (colorModel, CFSTR("Gray"), 0) == kCFCompareEqualTo)
                uncorrectedColorSpace = CGColorSpaceCreateDisplayGray();
        }
        
@@ -654,7 +654,7 @@ CGPatternCallbacks patternCallbacks = { 0, drawPattern, NULL };
         frameDurationsSize = num;
     }
     else if (frameDurations[currentFrame] == 0.f) {
-            frameDurations[currentFrame] = [self _frameDurationAt:currentFrame];
+        frameDurations[currentFrame] = [self _frameDurationAt:currentFrame];
     }
 
     return frameDurations[currentFrame];
@@ -683,25 +683,17 @@ static NSMutableSet *activeAnimations;
     // in the view.  It is necessary to gather the all renderers to stop
     // before actually stopping them because the process of stopping them
     // will modify the active animations and animating renderer collections.
-    NSSet *renderersInView;
     while ((animation = [objectEnumerator nextObject])) {
-       renderersInView = (NSSet *)CFDictionaryGetValue (animation->animatingRenderers, aView);
+       NSSet *renderersInView = (NSSet *)CFDictionaryGetValue (animation->animatingRenderers, aView);
         if (renderersInView) {
            if (!renderersToStop)
                renderersToStop = [[NSMutableSet alloc] init];
-            [renderersToStop addObject: renderersInView];
+            [renderersToStop unionSet:renderersInView];
         }
     }
 
     // Now tell them all to stop drawing.
-    if (renderersToStop) {
-        objectEnumerator = [renderersToStop objectEnumerator];
-        while ((renderersInView = [objectEnumerator nextObject])) {
-            [renderersInView makeObjectsPerformSelector:@selector(stopAnimation)];
-        }
-        
-        [renderersToStop release];
-    }
+    [renderersToStop makeObjectsPerformSelector:@selector(stopAnimation)];
 }
 
 - (void)addAnimatingRenderer:(WebImageRenderer *)r inView:(NSView *)view
index b18132afe46e42d2b523bb187050e079ce21b3d2..15f901de3b8724862489bfec054c35d0bb933529 100644 (file)
@@ -2531,7 +2531,10 @@ static CFAbsoluteTime _timeOfLastCompletedLoad;
 
 - (void)_updateDrawsBackground
 {
-    [[self _bridge] setDrawsBackground:[[self webView] drawsBackground]];
+    BOOL drawsBackground = [[self webView] drawsBackground];
+    if (!drawsBackground)
+        [[[self frameView] _scrollView] setDrawsBackground:NO];
+    [[self _bridge] setDrawsBackground:drawsBackground];
     [_private->children makeObjectsPerformSelector:@selector(_updateDrawsBackground)];
 }
 
index 71a6a8565ef26c5f9d877becb43c3c5412c16275..f9ed94e59e4d80ae64fd3f390018e9c675aaafca 100644 (file)
@@ -73,6 +73,7 @@ void _NSResetKillRingOperationFlag(void);
 - (void)_recursiveDisplayAllDirtyWithLockFocus:(BOOL)needsLockFocus visRect:(NSRect)visRect;
 - (NSRect)_dirtyRect;
 - (void)_setDrawsOwnDescendants:(BOOL)drawsOwnDescendants;
+- (void)_propagateDirtyRectsToOpaqueAncestors;
 @end
 
 @interface NSApplication (AppKitSecretsIKnowAbout)
@@ -169,6 +170,7 @@ static BOOL forceRealHitTest = NO;
 @interface NSView (WebHTMLViewFileInternal)
 - (void)_web_setPrintingModeRecursive;
 - (void)_web_clearPrintingModeRecursive;
+- (void)_web_layoutIfNeededRecursive;
 - (void)_web_layoutIfNeededRecursive:(NSRect)rect testDirtyRect:(bool)testDirtyRect;
 @end
 
@@ -557,6 +559,19 @@ static BOOL forceRealHitTest = NO;
     _private->subviewsSetAside = NO;
 }
 
+// This is called when we are about to draw, but before our dirty rect is propagated to our ancestors.
+// That's the perfect time to do a layout, except that ideally we'd want to be sure that we're dirty
+// before doing it. As a compromise, when we're opaque we do the layout only when actually asked to
+// draw, but when we're transparent we do the layout at this stage so views behind us know that they
+// need to be redrawn (in case the layout causes some things to get dirtied).
+- (void)_propagateDirtyRectsToOpaqueAncestors
+{
+    if (![[self _webView] drawsBackground]) {
+        [self _web_layoutIfNeededRecursive];
+    }
+    [super _propagateDirtyRectsToOpaqueAncestors];
+}
+
 // Don't let AppKit even draw subviews. We take care of that.
 - (void)_recursiveDisplayRectIfNeededIgnoringOpacity:(NSRect)rect isVisibleRect:(BOOL)isVisibleRect rectIsVisibleRectForView:(NSView *)visibleView topView:(BOOL)topView
 {
@@ -1162,6 +1177,22 @@ static WebHTMLView *lastHitView = nil;
     [super _web_clearPrintingModeRecursive];
 }
 
+- (void)_layoutIfNeeded
+{
+    ASSERT(!_private->subviewsSetAside);
+
+    if ([[self _bridge] needsLayout])
+        _private->needsLayout = YES;
+    if (_private->needsToApplyStyles || _private->needsLayout)
+        [self layout];
+}
+
+- (void)_web_layoutIfNeededRecursive
+{
+    [self _layoutIfNeeded];
+    [super _web_layoutIfNeededRecursive];
+}
+
 - (void)_web_layoutIfNeededRecursive:(NSRect)displayRect testDirtyRect:(bool)testDirtyRect
 {
     ASSERT(!_private->subviewsSetAside);
@@ -1173,14 +1204,11 @@ static WebHTMLView *lastHitView = nil;
             displayRect = NSIntersectionRect(displayRect, dirtyRect);
         }
         if (!NSIsEmptyRect(displayRect)) {
-            if ([[self _bridge] needsLayout])
-                _private->needsLayout = YES;
-            if (_private->needsToApplyStyles || _private->needsLayout)
-                [self layout];
+            [self _layoutIfNeeded];
         }
     }
 
-    [super _web_layoutIfNeededRecursive: displayRect testDirtyRect: NO];
+    [super _web_layoutIfNeededRecursive:displayRect testDirtyRect:NO];
 }
 
 - (NSRect)_selectionRect
@@ -1354,6 +1382,11 @@ static WebHTMLView *lastHitView = nil;
     [_subviews makeObjectsPerformSelector:@selector(_web_clearPrintingModeRecursive)];
 }
 
+- (void)_web_layoutIfNeededRecursive
+{
+    [_subviews makeObjectsPerformSelector:@selector(_web_layoutIfNeededRecursive)];
+}
+
 - (void)_web_layoutIfNeededRecursive: (NSRect)rect testDirtyRect:(bool)testDirtyRect
 {
     unsigned index, count;