|
1 /* |
|
2 * Copyright (C) 2005, 2008, 2010 Apple 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 * 1. Redistributions of source code must retain the above copyright |
|
8 * notice, this list of conditions and the following disclaimer. |
|
9 * 2. Redistributions in binary form must reproduce the above copyright |
|
10 * notice, this list of conditions and the following disclaimer in the |
|
11 * documentation and/or other materials provided with the distribution. |
|
12 * |
|
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
|
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
|
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
|
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
|
23 * THE POSSIBILITY OF SUCH DAMAGE. |
|
24 */ |
|
25 |
|
26 #import "WebDynamicScrollBarsViewInternal.h" |
|
27 |
|
28 #import "WebDocument.h" |
|
29 #import "WebFrameInternal.h" |
|
30 #import "WebFrameView.h" |
|
31 #import "WebHTMLViewInternal.h" |
|
32 #import <WebCore/Frame.h> |
|
33 #import <WebCore/FrameView.h> |
|
34 #import <WebKitSystemInterface.h> |
|
35 |
|
36 using namespace WebCore; |
|
37 |
|
38 // FIXME: <rdar://problem/5898985> Mail expects a constant of this name to exist. |
|
39 const int WebCoreScrollbarAlwaysOn = ScrollbarAlwaysOn; |
|
40 |
|
41 #ifndef __OBJC2__ |
|
42 // In <rdar://problem/7814899> we saw crashes because WebDynamicScrollBarsView increased in size, breaking ABI compatiblity. |
|
43 COMPILE_ASSERT(sizeof(WebDynamicScrollBarsView) == 0x8c, WebDynamicScrollBarsView_is_expected_size); |
|
44 #endif |
|
45 |
|
46 struct WebDynamicScrollBarsViewPrivate { |
|
47 unsigned inUpdateScrollersLayoutPass; |
|
48 |
|
49 WebCore::ScrollbarMode hScroll; |
|
50 WebCore::ScrollbarMode vScroll; |
|
51 |
|
52 bool hScrollModeLocked; |
|
53 bool vScrollModeLocked; |
|
54 bool suppressLayout; |
|
55 bool suppressScrollers; |
|
56 bool inUpdateScrollers; |
|
57 bool verticallyPinnedByPreviousWheelEvent; |
|
58 bool horizontallyPinnedByPreviousWheelEvent; |
|
59 |
|
60 bool allowsScrollersToOverlapContent; |
|
61 bool alwaysHideHorizontalScroller; |
|
62 bool alwaysHideVerticalScroller; |
|
63 bool horizontalScrollingAllowedButScrollerHidden; |
|
64 bool verticalScrollingAllowedButScrollerHidden; |
|
65 }; |
|
66 |
|
67 @implementation WebDynamicScrollBarsView |
|
68 |
|
69 - (id)initWithFrame:(NSRect)frame |
|
70 { |
|
71 if (!(self = [super initWithFrame:frame])) |
|
72 return nil; |
|
73 |
|
74 _private = new WebDynamicScrollBarsViewPrivate; |
|
75 memset(_private, 0, sizeof(WebDynamicScrollBarsViewPrivate)); |
|
76 return self; |
|
77 } |
|
78 |
|
79 - (id)initWithCoder:(NSCoder *)aDecoder |
|
80 { |
|
81 if (!(self = [super initWithCoder:aDecoder])) |
|
82 return nil; |
|
83 |
|
84 _private = new WebDynamicScrollBarsViewPrivate; |
|
85 memset(_private, 0, sizeof(WebDynamicScrollBarsViewPrivate)); |
|
86 return self; |
|
87 } |
|
88 |
|
89 - (void)dealloc |
|
90 { |
|
91 delete _private; |
|
92 [super dealloc]; |
|
93 } |
|
94 |
|
95 - (void)finalize |
|
96 { |
|
97 delete _private; |
|
98 [super finalize]; |
|
99 } |
|
100 |
|
101 - (void)setAllowsHorizontalScrolling:(BOOL)flag |
|
102 { |
|
103 if (_private->hScrollModeLocked) |
|
104 return; |
|
105 if (flag && _private->hScroll == ScrollbarAlwaysOff) |
|
106 _private->hScroll = ScrollbarAuto; |
|
107 else if (!flag && _private->hScroll != ScrollbarAlwaysOff) |
|
108 _private->hScroll = ScrollbarAlwaysOff; |
|
109 [self updateScrollers]; |
|
110 } |
|
111 |
|
112 - (void)setAllowsScrollersToOverlapContent:(BOOL)flag |
|
113 { |
|
114 if (_private->allowsScrollersToOverlapContent == flag) |
|
115 return; |
|
116 |
|
117 _private->allowsScrollersToOverlapContent = flag; |
|
118 |
|
119 [[self contentView] setFrame:[self contentViewFrame]]; |
|
120 [[self documentView] setNeedsLayout:YES]; |
|
121 [[self documentView] layout]; |
|
122 } |
|
123 |
|
124 - (void)setAlwaysHideHorizontalScroller:(BOOL)shouldBeHidden |
|
125 { |
|
126 if (_private->alwaysHideHorizontalScroller == shouldBeHidden) |
|
127 return; |
|
128 |
|
129 _private->alwaysHideHorizontalScroller = shouldBeHidden; |
|
130 [self updateScrollers]; |
|
131 } |
|
132 |
|
133 - (void)setAlwaysHideVerticalScroller:(BOOL)shouldBeHidden |
|
134 { |
|
135 if (_private->alwaysHideVerticalScroller == shouldBeHidden) |
|
136 return; |
|
137 |
|
138 _private->alwaysHideVerticalScroller = shouldBeHidden; |
|
139 [self updateScrollers]; |
|
140 } |
|
141 |
|
142 - (BOOL)horizontalScrollingAllowed |
|
143 { |
|
144 return _private->horizontalScrollingAllowedButScrollerHidden || [self hasHorizontalScroller]; |
|
145 } |
|
146 |
|
147 - (BOOL)verticalScrollingAllowed |
|
148 { |
|
149 return _private->verticalScrollingAllowedButScrollerHidden || [self hasVerticalScroller]; |
|
150 } |
|
151 |
|
152 @end |
|
153 |
|
154 @implementation WebDynamicScrollBarsView (WebInternal) |
|
155 |
|
156 - (NSRect)contentViewFrame |
|
157 { |
|
158 NSRect frame = [[self contentView] frame]; |
|
159 |
|
160 if ([self hasHorizontalScroller]) |
|
161 frame.size.height = (_private->allowsScrollersToOverlapContent ? NSMaxY([[self horizontalScroller] frame]) : NSMinY([[self horizontalScroller] frame])); |
|
162 if ([self hasVerticalScroller]) |
|
163 frame.size.width = (_private->allowsScrollersToOverlapContent ? NSMaxX([[self verticalScroller] frame]) : NSMinX([[self verticalScroller] frame])); |
|
164 return frame; |
|
165 } |
|
166 |
|
167 - (void)tile |
|
168 { |
|
169 [super tile]; |
|
170 |
|
171 // [super tile] sets the contentView size so that it does not overlap with the scrollers, |
|
172 // we want to re-set the contentView to overlap scrollers before displaying. |
|
173 if (_private->allowsScrollersToOverlapContent) |
|
174 [[self contentView] setFrame:[self contentViewFrame]]; |
|
175 } |
|
176 |
|
177 - (void)setSuppressLayout:(BOOL)flag |
|
178 { |
|
179 _private->suppressLayout = flag; |
|
180 } |
|
181 |
|
182 - (void)setScrollBarsSuppressed:(BOOL)suppressed repaintOnUnsuppress:(BOOL)repaint |
|
183 { |
|
184 _private->suppressScrollers = suppressed; |
|
185 |
|
186 // This code was originally changes for a Leopard performance imporvement. We decided to |
|
187 // ifdef it to fix correctness issues on Tiger documented in <rdar://problem/5441823>. |
|
188 #ifndef BUILDING_ON_TIGER |
|
189 if (suppressed) { |
|
190 [[self verticalScroller] setNeedsDisplay:NO]; |
|
191 [[self horizontalScroller] setNeedsDisplay:NO]; |
|
192 } |
|
193 |
|
194 if (!suppressed && repaint) |
|
195 [super reflectScrolledClipView:[self contentView]]; |
|
196 #else |
|
197 if (suppressed || repaint) { |
|
198 [[self verticalScroller] setNeedsDisplay:!suppressed]; |
|
199 [[self horizontalScroller] setNeedsDisplay:!suppressed]; |
|
200 } |
|
201 #endif |
|
202 } |
|
203 |
|
204 static const unsigned cMaxUpdateScrollbarsPass = 2; |
|
205 |
|
206 - (void)updateScrollers |
|
207 { |
|
208 NSView *documentView = [self documentView]; |
|
209 |
|
210 // If we came in here with the view already needing a layout, then go ahead and do that |
|
211 // first. (This will be the common case, e.g., when the page changes due to window resizing for example). |
|
212 // This layout will not re-enter updateScrollers and does not count towards our max layout pass total. |
|
213 if (!_private->suppressLayout && !_private->suppressScrollers && [documentView isKindOfClass:[WebHTMLView class]]) { |
|
214 WebHTMLView* htmlView = (WebHTMLView*)documentView; |
|
215 if ([htmlView _needsLayout]) { |
|
216 _private->inUpdateScrollers = YES; |
|
217 [(id <WebDocumentView>)documentView layout]; |
|
218 _private->inUpdateScrollers = NO; |
|
219 } |
|
220 } |
|
221 |
|
222 BOOL hasHorizontalScroller = [self hasHorizontalScroller]; |
|
223 BOOL hasVerticalScroller = [self hasVerticalScroller]; |
|
224 |
|
225 BOOL newHasHorizontalScroller = hasHorizontalScroller; |
|
226 BOOL newHasVerticalScroller = hasVerticalScroller; |
|
227 |
|
228 if (!documentView) { |
|
229 newHasHorizontalScroller = NO; |
|
230 newHasVerticalScroller = NO; |
|
231 } |
|
232 |
|
233 if (_private->hScroll != ScrollbarAuto) |
|
234 newHasHorizontalScroller = (_private->hScroll == ScrollbarAlwaysOn); |
|
235 if (_private->vScroll != ScrollbarAuto) |
|
236 newHasVerticalScroller = (_private->vScroll == ScrollbarAlwaysOn); |
|
237 |
|
238 if (!documentView || _private->suppressLayout || _private->suppressScrollers || (_private->hScroll != ScrollbarAuto && _private->vScroll != ScrollbarAuto)) { |
|
239 _private->horizontalScrollingAllowedButScrollerHidden = newHasHorizontalScroller && _private->alwaysHideHorizontalScroller; |
|
240 if (_private->horizontalScrollingAllowedButScrollerHidden) |
|
241 newHasHorizontalScroller = NO; |
|
242 |
|
243 _private->verticalScrollingAllowedButScrollerHidden = newHasVerticalScroller && _private->alwaysHideVerticalScroller; |
|
244 if (_private->verticalScrollingAllowedButScrollerHidden) |
|
245 newHasVerticalScroller = NO; |
|
246 |
|
247 _private->inUpdateScrollers = YES; |
|
248 if (hasHorizontalScroller != newHasHorizontalScroller) |
|
249 [self setHasHorizontalScroller:newHasHorizontalScroller]; |
|
250 if (hasVerticalScroller != newHasVerticalScroller) |
|
251 [self setHasVerticalScroller:newHasVerticalScroller]; |
|
252 if (_private->suppressScrollers) { |
|
253 [[self verticalScroller] setNeedsDisplay:NO]; |
|
254 [[self horizontalScroller] setNeedsDisplay:NO]; |
|
255 } |
|
256 _private->inUpdateScrollers = NO; |
|
257 return; |
|
258 } |
|
259 |
|
260 BOOL needsLayout = NO; |
|
261 |
|
262 NSSize documentSize = [documentView frame].size; |
|
263 NSSize visibleSize = [self documentVisibleRect].size; |
|
264 NSSize frameSize = [self frame].size; |
|
265 |
|
266 // When in HiDPI with a scale factor > 1, the visibleSize and frameSize may be non-integral values, |
|
267 // while the documentSize (set by WebCore) will be integral. Round up the non-integral sizes so that |
|
268 // the mismatch won't cause unwanted scrollbars to appear. This can result in slightly cut off content, |
|
269 // but it will always be less than one pixel, which should not be noticeable. |
|
270 visibleSize.width = ceilf(visibleSize.width); |
|
271 visibleSize.height = ceilf(visibleSize.height); |
|
272 frameSize.width = ceilf(frameSize.width); |
|
273 frameSize.height = ceilf(frameSize.height); |
|
274 |
|
275 if (_private->hScroll == ScrollbarAuto) { |
|
276 newHasHorizontalScroller = documentSize.width > visibleSize.width; |
|
277 if (newHasHorizontalScroller && !_private->inUpdateScrollersLayoutPass && documentSize.height <= frameSize.height && documentSize.width <= frameSize.width) |
|
278 newHasHorizontalScroller = NO; |
|
279 } |
|
280 |
|
281 if (_private->vScroll == ScrollbarAuto) { |
|
282 newHasVerticalScroller = documentSize.height > visibleSize.height; |
|
283 if (newHasVerticalScroller && !_private->inUpdateScrollersLayoutPass && documentSize.height <= frameSize.height && documentSize.width <= frameSize.width) |
|
284 newHasVerticalScroller = NO; |
|
285 } |
|
286 |
|
287 // Unless in ScrollbarsAlwaysOn mode, if we ever turn one scrollbar off, always turn the other one off too. |
|
288 // Never ever try to both gain/lose a scrollbar in the same pass. |
|
289 if (!newHasHorizontalScroller && hasHorizontalScroller && _private->vScroll != ScrollbarAlwaysOn) |
|
290 newHasVerticalScroller = NO; |
|
291 if (!newHasVerticalScroller && hasVerticalScroller && _private->hScroll != ScrollbarAlwaysOn) |
|
292 newHasHorizontalScroller = NO; |
|
293 |
|
294 _private->horizontalScrollingAllowedButScrollerHidden = newHasHorizontalScroller && _private->alwaysHideHorizontalScroller; |
|
295 if (_private->horizontalScrollingAllowedButScrollerHidden) |
|
296 newHasHorizontalScroller = NO; |
|
297 |
|
298 _private->verticalScrollingAllowedButScrollerHidden = newHasVerticalScroller && _private->alwaysHideVerticalScroller; |
|
299 if (_private->verticalScrollingAllowedButScrollerHidden) |
|
300 newHasVerticalScroller = NO; |
|
301 |
|
302 if (hasHorizontalScroller != newHasHorizontalScroller) { |
|
303 _private->inUpdateScrollers = YES; |
|
304 [self setHasHorizontalScroller:newHasHorizontalScroller]; |
|
305 _private->inUpdateScrollers = NO; |
|
306 needsLayout = YES; |
|
307 } |
|
308 |
|
309 if (hasVerticalScroller != newHasVerticalScroller) { |
|
310 _private->inUpdateScrollers = YES; |
|
311 [self setHasVerticalScroller:newHasVerticalScroller]; |
|
312 _private->inUpdateScrollers = NO; |
|
313 needsLayout = YES; |
|
314 } |
|
315 |
|
316 if (needsLayout && _private->inUpdateScrollersLayoutPass < cMaxUpdateScrollbarsPass && |
|
317 [documentView conformsToProtocol:@protocol(WebDocumentView)]) { |
|
318 _private->inUpdateScrollersLayoutPass++; |
|
319 [(id <WebDocumentView>)documentView setNeedsLayout:YES]; |
|
320 [(id <WebDocumentView>)documentView layout]; |
|
321 NSSize newDocumentSize = [documentView frame].size; |
|
322 if (NSEqualSizes(documentSize, newDocumentSize)) { |
|
323 // The layout with the new scroll state had no impact on |
|
324 // the document's overall size, so updateScrollers didn't get called. |
|
325 // Recur manually. |
|
326 [self updateScrollers]; |
|
327 } |
|
328 _private->inUpdateScrollersLayoutPass--; |
|
329 } |
|
330 } |
|
331 |
|
332 // Make the horizontal and vertical scroll bars come and go as needed. |
|
333 - (void)reflectScrolledClipView:(NSClipView *)clipView |
|
334 { |
|
335 if (clipView == [self contentView]) { |
|
336 // Prevent appearance of trails because of overlapping views |
|
337 if (_private->allowsScrollersToOverlapContent) |
|
338 [self setDrawsBackground:NO]; |
|
339 |
|
340 // FIXME: This hack here prevents infinite recursion that takes place when we |
|
341 // gyrate between having a vertical scroller and not having one. A reproducible |
|
342 // case is clicking on the "the Policy Routing text" link at |
|
343 // http://www.linuxpowered.com/archive/howto/Net-HOWTO-8.html. |
|
344 // The underlying cause is some problem in the NSText machinery, but I was not |
|
345 // able to pin it down. |
|
346 NSGraphicsContext *currentContext = [NSGraphicsContext currentContext]; |
|
347 if (!_private->inUpdateScrollers && (!currentContext || [currentContext isDrawingToScreen])) |
|
348 [self updateScrollers]; |
|
349 } |
|
350 |
|
351 // This code was originally changed for a Leopard performance imporvement. We decided to |
|
352 // ifdef it to fix correctness issues on Tiger documented in <rdar://problem/5441823>. |
|
353 #ifndef BUILDING_ON_TIGER |
|
354 // Update the scrollers if they're not being suppressed. |
|
355 if (!_private->suppressScrollers) |
|
356 [super reflectScrolledClipView:clipView]; |
|
357 #else |
|
358 [super reflectScrolledClipView:clipView]; |
|
359 |
|
360 // Validate the scrollers if they're being suppressed. |
|
361 if (_private->suppressScrollers) { |
|
362 [[self verticalScroller] setNeedsDisplay:NO]; |
|
363 [[self horizontalScroller] setNeedsDisplay:NO]; |
|
364 } |
|
365 #endif |
|
366 |
|
367 #if USE(ACCELERATED_COMPOSITING) && defined(BUILDING_ON_LEOPARD) |
|
368 NSView *documentView = [self documentView]; |
|
369 if ([documentView isKindOfClass:[WebHTMLView class]]) { |
|
370 WebHTMLView *htmlView = (WebHTMLView *)documentView; |
|
371 if ([htmlView _isUsingAcceleratedCompositing]) |
|
372 [htmlView _updateLayerHostingViewPosition]; |
|
373 } |
|
374 #endif |
|
375 } |
|
376 |
|
377 - (BOOL)allowsHorizontalScrolling |
|
378 { |
|
379 return _private->hScroll != ScrollbarAlwaysOff; |
|
380 } |
|
381 |
|
382 - (BOOL)allowsVerticalScrolling |
|
383 { |
|
384 return _private->vScroll != ScrollbarAlwaysOff; |
|
385 } |
|
386 |
|
387 - (void)scrollingModes:(WebCore::ScrollbarMode*)hMode vertical:(WebCore::ScrollbarMode*)vMode |
|
388 { |
|
389 *hMode = _private->hScroll; |
|
390 *vMode = _private->vScroll; |
|
391 } |
|
392 |
|
393 - (ScrollbarMode)horizontalScrollingMode |
|
394 { |
|
395 return _private->hScroll; |
|
396 } |
|
397 |
|
398 - (ScrollbarMode)verticalScrollingMode |
|
399 { |
|
400 return _private->vScroll; |
|
401 } |
|
402 |
|
403 - (void)setHorizontalScrollingMode:(ScrollbarMode)horizontalMode andLock:(BOOL)lock |
|
404 { |
|
405 [self setScrollingModes:horizontalMode vertical:[self verticalScrollingMode] andLock:lock]; |
|
406 } |
|
407 |
|
408 - (void)setVerticalScrollingMode:(ScrollbarMode)verticalMode andLock:(BOOL)lock |
|
409 { |
|
410 [self setScrollingModes:[self horizontalScrollingMode] vertical:verticalMode andLock:lock]; |
|
411 } |
|
412 |
|
413 // Mail uses this method, so we cannot remove it. |
|
414 - (void)setVerticalScrollingMode:(ScrollbarMode)verticalMode |
|
415 { |
|
416 [self setScrollingModes:[self horizontalScrollingMode] vertical:verticalMode andLock:NO]; |
|
417 } |
|
418 |
|
419 - (void)setScrollingModes:(ScrollbarMode)horizontalMode vertical:(ScrollbarMode)verticalMode andLock:(BOOL)lock |
|
420 { |
|
421 BOOL update = NO; |
|
422 if (verticalMode != _private->vScroll && !_private->vScrollModeLocked) { |
|
423 _private->vScroll = verticalMode; |
|
424 update = YES; |
|
425 } |
|
426 |
|
427 if (horizontalMode != _private->hScroll && !_private->hScrollModeLocked) { |
|
428 _private->hScroll = horizontalMode; |
|
429 update = YES; |
|
430 } |
|
431 |
|
432 if (lock) |
|
433 [self setScrollingModesLocked:YES]; |
|
434 |
|
435 if (update) |
|
436 [self updateScrollers]; |
|
437 } |
|
438 |
|
439 - (void)setHorizontalScrollingModeLocked:(BOOL)locked |
|
440 { |
|
441 _private->hScrollModeLocked = locked; |
|
442 } |
|
443 |
|
444 - (void)setVerticalScrollingModeLocked:(BOOL)locked |
|
445 { |
|
446 _private->vScrollModeLocked = locked; |
|
447 } |
|
448 |
|
449 - (void)setScrollingModesLocked:(BOOL)locked |
|
450 { |
|
451 _private->hScrollModeLocked = _private->vScrollModeLocked = locked; |
|
452 } |
|
453 |
|
454 - (BOOL)horizontalScrollingModeLocked |
|
455 { |
|
456 return _private->hScrollModeLocked; |
|
457 } |
|
458 |
|
459 - (BOOL)verticalScrollingModeLocked |
|
460 { |
|
461 return _private->vScrollModeLocked; |
|
462 } |
|
463 |
|
464 - (BOOL)autoforwardsScrollWheelEvents |
|
465 { |
|
466 return YES; |
|
467 } |
|
468 |
|
469 - (void)scrollWheel:(NSEvent *)event |
|
470 { |
|
471 float deltaX; |
|
472 float deltaY; |
|
473 BOOL isContinuous; |
|
474 WKGetWheelEventDeltas(event, &deltaX, &deltaY, &isContinuous); |
|
475 |
|
476 BOOL isLatchingEvent = WKIsLatchingWheelEvent(event); |
|
477 |
|
478 if (fabsf(deltaY) > fabsf(deltaX)) { |
|
479 if (![self allowsVerticalScrolling]) { |
|
480 [[self nextResponder] scrollWheel:event]; |
|
481 return; |
|
482 } |
|
483 |
|
484 if (isLatchingEvent && !_private->verticallyPinnedByPreviousWheelEvent) { |
|
485 double verticalPosition = [[self verticalScroller] doubleValue]; |
|
486 if ((deltaY >= 0.0 && verticalPosition == 0.0) || (deltaY <= 0.0 && verticalPosition == 1.0)) |
|
487 return; |
|
488 } |
|
489 } else { |
|
490 if (![self allowsHorizontalScrolling]) { |
|
491 [[self nextResponder] scrollWheel:event]; |
|
492 return; |
|
493 } |
|
494 |
|
495 if (isLatchingEvent && !_private->horizontallyPinnedByPreviousWheelEvent) { |
|
496 double horizontalPosition = [[self horizontalScroller] doubleValue]; |
|
497 if ((deltaX >= 0.0 && horizontalPosition == 0.0) || (deltaX <= 0.0 && horizontalPosition == 1.0)) |
|
498 return; |
|
499 } |
|
500 } |
|
501 |
|
502 // Calling super can release the last reference. <rdar://problem/7400263> |
|
503 // Hold a reference so the code following the super call will not crash. |
|
504 [self retain]; |
|
505 |
|
506 [super scrollWheel:event]; |
|
507 |
|
508 if (!isLatchingEvent) { |
|
509 double verticalPosition = [[self verticalScroller] doubleValue]; |
|
510 double horizontalPosition = [[self horizontalScroller] doubleValue]; |
|
511 |
|
512 _private->verticallyPinnedByPreviousWheelEvent = (verticalPosition == 0.0 || verticalPosition == 1.0); |
|
513 _private->horizontallyPinnedByPreviousWheelEvent = (horizontalPosition == 0.0 || horizontalPosition == 1.0); |
|
514 } |
|
515 |
|
516 [self release]; |
|
517 } |
|
518 |
|
519 - (BOOL)accessibilityIsIgnored |
|
520 { |
|
521 id docView = [self documentView]; |
|
522 if ([docView isKindOfClass:[WebFrameView class]] && ![(WebFrameView *)docView allowsScrolling]) |
|
523 return YES; |
|
524 |
|
525 return [super accessibilityIsIgnored]; |
|
526 } |
|
527 |
|
528 @end |