Home | History | Annotate | Download | only in WebView
      1 /*
      2  * Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  * 1.  Redistributions of source code must retain the above copyright
      9  *     notice, this list of conditions and the following disclaimer.
     10  * 2.  Redistributions in binary form must reproduce the above copyright
     11  *     notice, this list of conditions and the following disclaimer in the
     12  *     documentation and/or other materials provided with the distribution.
     13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
     14  *     its contributors may be used to endorse or promote products derived
     15  *     from this software without specific prior written permission.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #import "WebClipView.h"
     30 
     31 #import "WebFrameInternal.h"
     32 #import "WebFrameView.h"
     33 #import "WebViewPrivate.h"
     34 #import <WebCore/FrameView.h>
     35 
     36 // WebClipView's entire reason for existing is to set the clip used by focus ring redrawing.
     37 // There's no easy way to prevent the focus ring from drawing outside the passed-in clip rectangle
     38 // because it expects to have to draw outside the bounds of the view it's being drawn for.
     39 // But it looks for the enclosing clip view, which gives us a hook we can use to control it.
     40 // The "additional clip" is a clip for focus ring redrawing.
     41 
     42 // FIXME: Change terminology from "additional clip" to "focus ring clip".
     43 
     44 using namespace WebCore;
     45 
     46 @interface NSView (WebViewMethod)
     47 - (WebView *)_webView;
     48 @end
     49 
     50 @interface NSClipView (WebNSClipViewDetails)
     51 - (void)_immediateScrollToPoint:(NSPoint)newOrigin;
     52 @end
     53 
     54 #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
     55 @interface NSWindow (WebNSWindowDetails)
     56 - (void)_disableDelayedWindowDisplay;
     57 - (void)_enableDelayedWindowDisplay;
     58 @end
     59 #endif
     60 
     61 @implementation WebClipView
     62 
     63 - (id)initWithFrame:(NSRect)frame
     64 {
     65     self = [super initWithFrame:frame];
     66     if (!self)
     67         return nil;
     68 
     69     // In WebHTMLView, we set a clip. This is not typical to do in an
     70     // NSView, and while correct for any one invocation of drawRect:,
     71     // it causes some bad problems if that clip is cached between calls.
     72     // The cached graphics state, which clip views keep around, does
     73     // cache the clip in this undesirable way. Consequently, we want to
     74     // release the GState for all clip views for all views contained in
     75     // a WebHTMLView. Here we do it for subframes, which use WebClipView.
     76     // See these bugs for more information:
     77     // <rdar://problem/3409315>: REGRESSSION (7B58-7B60)?: Safari draws blank frames on macosx.apple.com perf page
     78     [self releaseGState];
     79 
     80     return self;
     81 }
     82 
     83 #if USE(ACCELERATED_COMPOSITING)
     84 - (NSRect)visibleRect
     85 {
     86     if (!_isScrolling)
     87         return [super visibleRect];
     88 
     89     WebFrameView *webFrameView = (WebFrameView *)[[self superview] superview];
     90     if (![webFrameView isKindOfClass:[WebFrameView class]])
     91         return [super visibleRect];
     92 
     93     if (Frame* coreFrame = core([webFrameView webFrame])) {
     94         if (FrameView* frameView = coreFrame->view()) {
     95             if (frameView->isEnclosedInCompositingLayer())
     96                 return [self bounds];
     97         }
     98     }
     99 
    100     return [super visibleRect];
    101 }
    102 
    103 - (void)_immediateScrollToPoint:(NSPoint)newOrigin
    104 {
    105     _isScrolling = YES;
    106 
    107 #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
    108     [[self window] _disableDelayedWindowDisplay];
    109 #endif
    110 
    111     [super _immediateScrollToPoint:newOrigin];
    112 
    113 #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
    114     [[self window] _enableDelayedWindowDisplay];
    115 #endif
    116 
    117     _isScrolling = NO;
    118 }
    119 #endif
    120 
    121 - (void)resetAdditionalClip
    122 {
    123     ASSERT(_haveAdditionalClip);
    124     _haveAdditionalClip = NO;
    125 }
    126 
    127 - (void)setAdditionalClip:(NSRect)additionalClip
    128 {
    129     ASSERT(!_haveAdditionalClip);
    130     _haveAdditionalClip = YES;
    131     _additionalClip = additionalClip;
    132 }
    133 
    134 - (BOOL)hasAdditionalClip
    135 {
    136     return _haveAdditionalClip;
    137 }
    138 
    139 - (NSRect)additionalClip
    140 {
    141     ASSERT(_haveAdditionalClip);
    142     return _additionalClip;
    143 }
    144 
    145 - (NSRect)_focusRingVisibleRect
    146 {
    147     NSRect rect = [self visibleRect];
    148     if (_haveAdditionalClip) {
    149         rect = NSIntersectionRect(rect, _additionalClip);
    150     }
    151     return rect;
    152 }
    153 
    154 - (void)scrollWheel:(NSEvent *)event
    155 {
    156     NSView *docView = [self documentView];
    157     if ([docView respondsToSelector:@selector(_webView)]) {
    158 #if ENABLE(DASHBOARD_SUPPORT)
    159         WebView *wv = [docView _webView];
    160         if ([wv _dashboardBehavior:WebDashboardBehaviorAllowWheelScrolling]) {
    161             [super scrollWheel:event];
    162         }
    163 #endif
    164         return;
    165     }
    166     [super scrollWheel:event];
    167 }
    168 
    169 @end
    170