summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/mac/ScrollViewMac.mm
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform/mac/ScrollViewMac.mm')
-rw-r--r--WebCore/platform/mac/ScrollViewMac.mm454
1 files changed, 84 insertions, 370 deletions
diff --git a/WebCore/platform/mac/ScrollViewMac.mm b/WebCore/platform/mac/ScrollViewMac.mm
index 1caa433..6d477e2 100644
--- a/WebCore/platform/mac/ScrollViewMac.mm
+++ b/WebCore/platform/mac/ScrollViewMac.mm
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2004, 2006, 2007, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,333 +26,146 @@
#import "config.h"
#import "ScrollView.h"
+#import "BlockExceptions.h"
#import "FloatRect.h"
#import "IntRect.h"
-#import "BlockExceptions.h"
#import "Logging.h"
+#import "NotImplemented.h"
#import "WebCoreFrameView.h"
-/*
- This class implementation does NOT actually emulate the Qt ScrollView.
- It does provide an implementation that khtml will use to interact with
- WebKit's WebFrameView documentView and our NSScrollView subclass.
+using namespace std;
- ScrollView's view is a NSScrollView (or subclass of NSScrollView)
- in most cases. That scrollview is a subview of an
- WebCoreFrameView. The WebCoreFrameView's documentView will also be
- the scroll view's documentView.
-
- The WebCoreFrameView's size is the frame size. The WebCoreFrameView's documentView
- corresponds to the frame content size. The scrollview itself is autosized to the
- WebCoreFrameView's size (see Widget::resize).
-*/
+@interface NSWindow (WebWindowDetails)
+- (BOOL)_needsToResetDragMargins;
+- (void)_setNeedsToResetDragMargins:(BOOL)needs;
+@end
namespace WebCore {
-int ScrollView::visibleWidth() const
-{
- NSScrollView *view = (NSScrollView *)getView();
-
- BEGIN_BLOCK_OBJC_EXCEPTIONS;
- if ([view isKindOfClass:[NSScrollView class]])
- return (int)[view documentVisibleRect].size.width;
- else
- return (int)[view bounds].size.width;
- END_BLOCK_OBJC_EXCEPTIONS;
-
- return 0;
-}
-
-int ScrollView::visibleHeight() const
-{
- NSScrollView *view = (NSScrollView *)getView();
-
- BEGIN_BLOCK_OBJC_EXCEPTIONS;
- if ([view isKindOfClass:[NSScrollView class]])
- return (int)[view documentVisibleRect].size.height;
- else
- return (int)[view bounds].size.height;
- END_BLOCK_OBJC_EXCEPTIONS;
-
- return 0;
-}
-
-FloatRect ScrollView::visibleContentRect() const
+inline NSScrollView<WebCoreFrameScrollView> *ScrollView::scrollView() const
{
- NSScrollView *view = (NSScrollView *)getView();
-
- BEGIN_BLOCK_OBJC_EXCEPTIONS;
- if ([view isKindOfClass:[NSScrollView class]])
- return [view documentVisibleRect];
- else
- return [view visibleRect];
- END_BLOCK_OBJC_EXCEPTIONS;
-
- return FloatRect();
+ ASSERT(!platformWidget() || [platformWidget() isKindOfClass:[NSScrollView class]]);
+ ASSERT(!platformWidget() || [platformWidget() conformsToProtocol:@protocol(WebCoreFrameScrollView)]);
+ return static_cast<NSScrollView<WebCoreFrameScrollView> *>(platformWidget());
}
-FloatRect ScrollView::visibleContentRectConsideringExternalScrollers() const
+NSView *ScrollView::documentView() const
{
BEGIN_BLOCK_OBJC_EXCEPTIONS;
- if (NSView *docView = getDocumentView())
- return [docView visibleRect];
+ return [scrollView() documentView];
END_BLOCK_OBJC_EXCEPTIONS;
-
- return FloatRect();
+ return nil;
}
-
-int ScrollView::contentsWidth() const
+void ScrollView::platformAddChild(Widget* child)
{
- NSView *docView, *view = getView();
- docView = getDocumentView();
-
BEGIN_BLOCK_OBJC_EXCEPTIONS;
- if (docView)
- return (int)[docView bounds].size.width;
- else
- return (int)[view bounds].size.width;
+ NSView *parentView = documentView();
+ NSView *childView = child->getOuterView();
+ ASSERT(![parentView isDescendantOf:childView]);
+
+ // Suppress the resetting of drag margins since we know we can't affect them.
+ NSWindow *window = [parentView window];
+ BOOL resetDragMargins = [window _needsToResetDragMargins];
+ [window _setNeedsToResetDragMargins:NO];
+ if ([childView superview] != parentView)
+ [parentView addSubview:childView];
+ [window _setNeedsToResetDragMargins:resetDragMargins];
END_BLOCK_OBJC_EXCEPTIONS;
-
- return 0;
}
-int ScrollView::contentsHeight() const
+void ScrollView::platformRemoveChild(Widget* child)
{
- NSView *docView, *view = getView();
- docView = getDocumentView();
-
- BEGIN_BLOCK_OBJC_EXCEPTIONS;
- if (docView)
- return (int)[docView bounds].size.height;
- else
- return (int)[view bounds].size.height;
- END_BLOCK_OBJC_EXCEPTIONS;
-
- return 0;
+ child->removeFromSuperview();
}
-int ScrollView::contentsX() const
+void ScrollView::platformSetScrollbarModes()
{
- NSView *view = getView();
-
BEGIN_BLOCK_OBJC_EXCEPTIONS;
- if ([view isKindOfClass:[NSScrollView class]])
- return (int)[(NSScrollView *)view documentVisibleRect].origin.x;
- else
- return (int)[view visibleRect].origin.x;
+ [scrollView() setScrollingModes:m_horizontalScrollbarMode vertical:m_verticalScrollbarMode andLock:NO];
END_BLOCK_OBJC_EXCEPTIONS;
-
- return 0;
}
-int ScrollView::contentsY() const
+void ScrollView::platformScrollbarModes(ScrollbarMode& horizontal, ScrollbarMode& vertical) const
{
- NSView *view = getView();
-
BEGIN_BLOCK_OBJC_EXCEPTIONS;
- if ([view isKindOfClass:[NSScrollView class]])
- return (int)[(NSScrollView *)view documentVisibleRect].origin.y;
- else
- return (int)[view visibleRect].origin.y;
+ [scrollView() scrollingModes:&horizontal vertical:&vertical];
END_BLOCK_OBJC_EXCEPTIONS;
-
- return 0;
}
-
-IntSize ScrollView::scrollOffset() const
-{
- NSView *view = getView();
- BEGIN_BLOCK_OBJC_EXCEPTIONS;
- if ([view isKindOfClass:[NSScrollView class]])
- return IntPoint([[(NSScrollView *)view contentView] visibleRect].origin) - IntPoint();
- END_BLOCK_OBJC_EXCEPTIONS;
- return IntSize();
-}
-
-void ScrollView::scrollBy(int dx, int dy)
-{
- setContentsPos(contentsX() + dx, contentsY() + dy);
-}
-
-void ScrollView::scrollRectIntoViewRecursively(const IntRect& r)
-{
- NSRect rect = r;
-
- BEGIN_BLOCK_OBJC_EXCEPTIONS;
- NSView *docView;
- NSView *view = getView();
- docView = getDocumentView();
- if (docView)
- view = docView;
-
- NSView *originalView = view;
- while (view) {
- if ([view isKindOfClass:[NSClipView class]]) {
- NSClipView *clipView = (NSClipView *)view;
- NSView *documentView = [clipView documentView];
- [documentView scrollRectToVisible:[documentView convertRect:rect fromView:originalView]];
- }
-
- view = [view superview];
- }
-
- END_BLOCK_OBJC_EXCEPTIONS;
-}
-
-void ScrollView::setContentsPos(int x, int y)
+void ScrollView::platformSetCanBlitOnScroll()
{
- x = (x < 0) ? 0 : x;
- y = (y < 0) ? 0 : y;
- NSPoint p = NSMakePoint(x,y);
-
BEGIN_BLOCK_OBJC_EXCEPTIONS;
- NSView *docView;
- NSView *view = getView();
- docView = getDocumentView();
- if (docView)
- view = docView;
- [view scrollPoint:p];
+ [[scrollView() contentView] setCopiesOnScroll:canBlitOnScroll()];
END_BLOCK_OBJC_EXCEPTIONS;
}
-void ScrollView::setVScrollbarMode(ScrollbarMode vMode)
+IntRect ScrollView::platformVisibleContentRect(bool includeScrollbars) const
{
- NSView* view = getView();
-
- BEGIN_BLOCK_OBJC_EXCEPTIONS;
- if ([view conformsToProtocol:@protocol(WebCoreFrameView)]) {
- NSView<WebCoreFrameView>* frameView = (NSView<WebCoreFrameView>*)view;
- [frameView setVerticalScrollingMode: (WebCoreScrollbarMode)vMode];
+ BEGIN_BLOCK_OBJC_EXCEPTIONS;
+ if (includeScrollbars) {
+ if (NSView* documentView = this->documentView())
+ return enclosingIntRect([documentView visibleRect]);
}
- END_BLOCK_OBJC_EXCEPTIONS;
+ return enclosingIntRect([scrollView() documentVisibleRect]);
+ END_BLOCK_OBJC_EXCEPTIONS;
+ return IntRect();
}
-void ScrollView::setHScrollbarMode(ScrollbarMode hMode)
+IntSize ScrollView::platformContentsSize() const
{
- NSView* view = getView();
-
BEGIN_BLOCK_OBJC_EXCEPTIONS;
- if ([view conformsToProtocol:@protocol(WebCoreFrameView)]) {
- NSView<WebCoreFrameView>* frameView = (NSView<WebCoreFrameView>*)view;
- [frameView setHorizontalScrollingMode: (WebCoreScrollbarMode)hMode];
- }
+ if (NSView* documentView = this->documentView())
+ return enclosingIntRect([documentView bounds]).size();
END_BLOCK_OBJC_EXCEPTIONS;
+ return IntSize();
}
-void ScrollView::setScrollbarsMode(ScrollbarMode mode)
+void ScrollView::platformSetContentsSize()
{
- NSView* view = getView();
-
BEGIN_BLOCK_OBJC_EXCEPTIONS;
- if ([view conformsToProtocol:@protocol(WebCoreFrameView)]) {
- NSView<WebCoreFrameView>* frameView = (NSView<WebCoreFrameView>*)view;
- [frameView setScrollingMode: (WebCoreScrollbarMode)mode];
- }
+ int w = m_contentsSize.width();
+ int h = m_contentsSize.height();
+ LOG(Frames, "%p %@ at w %d h %d\n", documentView(), [(id)[documentView() class] className], w, h);
+ NSSize tempSize = { max(0, w), max(0, h) }; // workaround for 4213314
+ [documentView() setFrameSize:tempSize];
END_BLOCK_OBJC_EXCEPTIONS;
}
-ScrollbarMode ScrollView::vScrollbarMode() const
+void ScrollView::platformSetScrollbarsSuppressed(bool repaintOnUnsuppress)
{
- NSView* view = getView();
-
BEGIN_BLOCK_OBJC_EXCEPTIONS;
- if ([view conformsToProtocol:@protocol(WebCoreFrameView)]) {
- NSView<WebCoreFrameView>* frameView = (NSView<WebCoreFrameView>*)view;
- return (ScrollbarMode)[frameView verticalScrollingMode];
- }
+ [scrollView() setScrollBarsSuppressed:m_scrollbarsSuppressed
+ repaintOnUnsuppress:repaintOnUnsuppress];
END_BLOCK_OBJC_EXCEPTIONS;
-
- return ScrollbarAuto;
}
-ScrollbarMode ScrollView::hScrollbarMode() const
+void ScrollView::platformSetScrollPosition(const IntPoint& scrollPoint)
{
- NSView* view = getView();
-
BEGIN_BLOCK_OBJC_EXCEPTIONS;
- if ([view conformsToProtocol:@protocol(WebCoreFrameView)]) {
- NSView<WebCoreFrameView>* frameView = (NSView<WebCoreFrameView>*)view;
- return (ScrollbarMode)[frameView horizontalScrollingMode];
- }
+ NSPoint tempPoint = { max(0, scrollPoint.x()), max(0, scrollPoint.y()) }; // Don't use NSMakePoint to work around 4213314.
+ [documentView() scrollPoint:tempPoint];
END_BLOCK_OBJC_EXCEPTIONS;
-
- return ScrollbarAuto;
}
-void ScrollView::suppressScrollbars(bool suppressed, bool repaintOnUnsuppress)
+bool ScrollView::platformScroll(ScrollDirection, ScrollGranularity)
{
- NSView* view = getView();
-
- BEGIN_BLOCK_OBJC_EXCEPTIONS;
- if ([view conformsToProtocol:@protocol(WebCoreFrameView)]) {
- NSView<WebCoreFrameView>* frameView = (NSView<WebCoreFrameView>*)view;
- [frameView setScrollBarsSuppressed: suppressed
- repaintOnUnsuppress: repaintOnUnsuppress];
- }
- END_BLOCK_OBJC_EXCEPTIONS;
+ // FIXME: It would be nice to implement this so that all of the code in WebFrameView could go away.
+ notImplemented();
+ return true;
}
-void ScrollView::addChild(Widget* child)
-{
- ASSERT(child != this);
-
- NSView *thisView = getView();
- NSView *thisDocView = getDocumentView();
- if (thisDocView)
- thisView = thisDocView;
-
-#ifndef NDEBUG
- NSView *subview = child->getOuterView();
-
- LOG(Frames, "Adding %p %@ with size w %d h %d\n", subview,
- [(id)[subview class] className], (int)[subview frame].size.width, (int)[subview frame].size.height);
-#endif
- child->addToSuperview(thisView);
-}
-
-void ScrollView::removeChild(Widget* child)
-{
- child->removeFromSuperview();
-}
-
-void ScrollView::resizeContents(int w, int h)
-{
- BEGIN_BLOCK_OBJC_EXCEPTIONS;
- int _w = w;
- int _h = h;
-
- LOG(Frames, "%p %@ at w %d h %d\n", getView(), [(id)[getView() class] className], w, h);
- NSView *view = getView();
- if ([view isKindOfClass:[NSScrollView class]]){
- view = getDocumentView();
-
- LOG(Frames, "%p %@ at w %d h %d\n", view, [(id)[view class] className], w, h);
- if (_w < 0)
- _w = 0;
- if (_h < 0)
- _h = 0;
-
- NSSize tempSize = { _w, _h }; // workaround for 4213314
- [view setFrameSize:tempSize];
- } else {
- resize (_w, _h);
- }
- END_BLOCK_OBJC_EXCEPTIONS;
-}
-
-void ScrollView::updateContents(const IntRect &rect, bool now)
+void ScrollView::platformRepaintContentRectangle(const IntRect& rect, bool now)
{
BEGIN_BLOCK_OBJC_EXCEPTIONS;
- NSView *view = getView();
-
- if ([view isKindOfClass:[NSScrollView class]])
- view = getDocumentView();
-
+ NSView *view = documentView();
NSRect visibleRect = visibleContentRect();
+ // FIXME: I don't think this intersection is necessary any more now that
+ // selection doesn't call this method directly (but has to go through FrameView's
+ // repaintContentRectangle, which does the intersection test also). Leaving it in
+ // for now until I'm sure.
// Checking for rect visibility is an important optimization for the case of
// Select All of a large document. AppKit does not do this check, and so ends
// up building a large complicated NSRegion if we don't perform the check.
@@ -368,134 +181,35 @@ void ScrollView::updateContents(const IntRect &rect, bool now)
END_BLOCK_OBJC_EXCEPTIONS;
}
-void ScrollView::update()
-{
- BEGIN_BLOCK_OBJC_EXCEPTIONS;
-
- NSView *view = getView();
- [[view window] displayIfNeeded];
- [[view window] flushWindowIfNeeded];
-
- END_BLOCK_OBJC_EXCEPTIONS;
-}
-
// "Containing Window" means the NSWindow's coord system, which is origin lower left
-IntPoint ScrollView::contentsToWindow(const IntPoint& contentsPoint) const
-{
- BEGIN_BLOCK_OBJC_EXCEPTIONS;
-
- NSView *docView;
- NSView *view = getView();
-
- docView = getDocumentView();
- if (docView)
- view = docView;
-
- NSPoint tempPoint = { contentsPoint.x(), contentsPoint.y() }; // workaround for 4213314
- NSPoint np = [view convertPoint:tempPoint toView: nil];
- return IntPoint(np);
-
- END_BLOCK_OBJC_EXCEPTIONS;
-
- return IntPoint();
-}
-
-IntPoint ScrollView::windowToContents(const IntPoint& point) const
+IntRect ScrollView::platformContentsToScreen(const IntRect& rect) const
{
BEGIN_BLOCK_OBJC_EXCEPTIONS;
-
- NSView *docView;
- NSView *view = getView();
-
- docView = getDocumentView();
- if (docView)
- view = docView;
-
- NSPoint tempPoint = { point.x(), point.y() }; // workaround for 4213314
- NSPoint np = [view convertPoint:tempPoint fromView: nil];
-
- return IntPoint(np);
-
- END_BLOCK_OBJC_EXCEPTIONS;
-
- return IntPoint();
-}
-
-IntRect ScrollView::contentsToWindow(const IntRect& contentsRect) const
-{
- BEGIN_BLOCK_OBJC_EXCEPTIONS;
-
- NSView* docView;
- NSView* view = getView();
-
- docView = getDocumentView();
- if (docView)
- view = docView;
-
- NSRect nr = [view convertRect:contentsRect toView: nil];
- return IntRect(nr);
-
- END_BLOCK_OBJC_EXCEPTIONS;
-
- return IntRect();
-}
-
-IntRect ScrollView::windowToContents(const IntRect& rect) const
-{
- BEGIN_BLOCK_OBJC_EXCEPTIONS;
-
- NSView* docView;
- NSView* view = getView();
-
- docView = getDocumentView();
- if (docView)
- view = docView;
-
- NSRect nr = [view convertRect:rect fromView: nil];
-
- return IntRect(nr);
-
+ if (NSView* documentView = this->documentView()) {
+ NSRect tempRect = rect;
+ tempRect = [documentView convertRect:tempRect toView:nil];
+ tempRect.origin = [[documentView window] convertBaseToScreen:tempRect.origin];
+ return enclosingIntRect(tempRect);
+ }
END_BLOCK_OBJC_EXCEPTIONS;
-
return IntRect();
}
-void ScrollView::setStaticBackground(bool b)
-{
- NSScrollView *view = (NSScrollView *)getView();
- BEGIN_BLOCK_OBJC_EXCEPTIONS;
- if ([view isKindOfClass:[NSScrollView class]])
- [[view contentView] setCopiesOnScroll: !b];
- END_BLOCK_OBJC_EXCEPTIONS;
-}
-
-NSView *ScrollView::getDocumentView() const
+IntPoint ScrollView::platformScreenToContents(const IntPoint& point) const
{
- id view = getView();
-
BEGIN_BLOCK_OBJC_EXCEPTIONS;
- if ([view respondsToSelector:@selector(documentView)])
- return [view documentView];
+ if (NSView* documentView = this->documentView()) {
+ NSPoint windowCoord = [[documentView window] convertScreenToBase: point];
+ return IntPoint([documentView convertPoint:windowCoord fromView:nil]);
+ }
END_BLOCK_OBJC_EXCEPTIONS;
-
- return nil;
-}
-
-PlatformScrollbar* ScrollView::scrollbarUnderMouse(const PlatformMouseEvent& mouseEvent)
-{
- // On Mac, the ScrollView is really the "document", so events will never flow into it to get to the scrollers.
- return 0;
-}
-
-bool ScrollView::inWindow() const
-{
- return [getView() window];
+ return IntPoint();
}
-void ScrollView::wheelEvent(PlatformWheelEvent&)
+bool ScrollView::platformIsOffscreen() const
{
- // Do nothing. NSScrollView handles doing the scroll for us.
+ return ![platformWidget() window] || ![[platformWidget() window] isVisible];
}
}