280695e9a81169823b0c1bc1d6217dc60a4bfd74
[WebKit-https.git] / Source / WebKit / mac / WebView / WebClipView.mm
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