| Index: Source/WebCore/platform/chromium/PopupContainer.cpp
|
| ===================================================================
|
| --- Source/WebCore/platform/chromium/PopupContainer.cpp (revision 115617)
|
| +++ Source/WebCore/platform/chromium/PopupContainer.cpp (working copy)
|
| @@ -134,7 +134,7 @@
|
| IntSize targetSize(m_listBox->width() + kBorderSize * 2,
|
| m_listBox->height() + kBorderSize * 2);
|
|
|
| - IntRect widgetRect;
|
| + IntRect widgetRectInScreen;
|
| ChromeClientChromium* chromeClient = chromeClientChromium();
|
| if (chromeClient) {
|
| // If the popup would extend past the bottom of the screen, open upwards
|
| @@ -142,44 +142,44 @@
|
| FloatRect screen = screenAvailableRect(m_frameView.get());
|
| // Use popupInitialCoordinate.x() + rightOffset because RTL position
|
| // needs to be considered.
|
| - widgetRect = chromeClient->rootViewToScreen(IntRect(popupInitialCoordinate.x() + rightOffset, popupInitialCoordinate.y(), targetSize.width(), targetSize.height()));
|
| + widgetRectInScreen = chromeClient->rootViewToScreen(IntRect(popupInitialCoordinate.x() + rightOffset, popupInitialCoordinate.y(), targetSize.width(), targetSize.height()));
|
|
|
| // If we have multiple screens and the browser rect is in one screen, we have
|
| // to clip the window width to the screen width.
|
| // When clipping, we also need to set a maximum width for the list box.
|
| FloatRect windowRect = chromeClient->windowRect();
|
| - if (windowRect.x() >= screen.x() && windowRect.maxX() <= screen.maxX() && (widgetRect.x() < screen.x() || widgetRect.maxX() > screen.maxX())) {
|
| + if (windowRect.x() >= screen.x() && windowRect.maxX() <= screen.maxX() && (widgetRectInScreen.x() < screen.x() || widgetRectInScreen.maxX() > screen.maxX())) {
|
| // First, inverse the popup alignment if it does not fit the screen - this might fix things (or make them better).
|
| - IntRect inverseWidgetRect = chromeClient->rootViewToScreen(IntRect(popupInitialCoordinate.x() + (isRTL ? 0 : rtlOffset), popupInitialCoordinate.y(), targetSize.width(), targetSize.height()));
|
| + IntRect inverseWidgetRectInScreen = chromeClient->rootViewToScreen(IntRect(popupInitialCoordinate.x() + (isRTL ? 0 : rtlOffset), popupInitialCoordinate.y(), targetSize.width(), targetSize.height()));
|
| IntRect enclosingScreen = enclosingIntRect(screen);
|
| - unsigned originalCutoff = max(enclosingScreen.x() - widgetRect.x(), 0) + max(widgetRect.maxX() - enclosingScreen.maxX(), 0);
|
| - unsigned inverseCutoff = max(enclosingScreen.x() - inverseWidgetRect.x(), 0) + max(inverseWidgetRect.maxX() - enclosingScreen.maxX(), 0);
|
| + unsigned originalCutoff = max(enclosingScreen.x() - widgetRectInScreen.x(), 0) + max(widgetRectInScreen.maxX() - enclosingScreen.maxX(), 0);
|
| + unsigned inverseCutoff = max(enclosingScreen.x() - inverseWidgetRectInScreen.x(), 0) + max(inverseWidgetRectInScreen.maxX() - enclosingScreen.maxX(), 0);
|
|
|
| // Accept the inverse popup alignment if the trimmed content gets shorter than that in the original alignment case.
|
| if (inverseCutoff < originalCutoff)
|
| - widgetRect = inverseWidgetRect;
|
| + widgetRectInScreen = inverseWidgetRectInScreen;
|
|
|
| - if (widgetRect.x() < screen.x()) {
|
| - unsigned widgetRight = widgetRect.maxX();
|
| - widgetRect.setWidth(widgetRect.maxX() - screen.x());
|
| - widgetRect.setX(widgetRight - widgetRect.width());
|
| - listBox()->setMaxWidthAndLayout(max(widgetRect.width() - kBorderSize * 2, 0));
|
| - } else if (widgetRect.maxX() > screen.maxX()) {
|
| - widgetRect.setWidth(screen.maxX() - widgetRect.x());
|
| - listBox()->setMaxWidthAndLayout(max(widgetRect.width() - kBorderSize * 2, 0));
|
| + if (widgetRectInScreen.x() < screen.x()) {
|
| + unsigned widgetRight = widgetRectInScreen.maxX();
|
| + widgetRectInScreen.setWidth(widgetRectInScreen.maxX() - screen.x());
|
| + widgetRectInScreen.setX(widgetRight - widgetRectInScreen.width());
|
| + listBox()->setMaxWidthAndLayout(max(widgetRectInScreen.width() - kBorderSize * 2, 0));
|
| + } else if (widgetRectInScreen.maxX() > screen.maxX()) {
|
| + widgetRectInScreen.setWidth(screen.maxX() - widgetRectInScreen.x());
|
| + listBox()->setMaxWidthAndLayout(max(widgetRectInScreen.width() - kBorderSize * 2, 0));
|
| }
|
| }
|
|
|
| // Calculate Y axis size.
|
| - if (widgetRect.maxY() > static_cast<int>(screen.maxY())) {
|
| - if (widgetRect.y() - widgetRect.height() - targetControlHeight > 0) {
|
| + if (widgetRectInScreen.maxY() > static_cast<int>(screen.maxY())) {
|
| + if (widgetRectInScreen.y() - widgetRectInScreen.height() - targetControlHeight > 0) {
|
| // There is enough room to open upwards.
|
| - widgetRect.move(0, -(widgetRect.height() + targetControlHeight));
|
| + widgetRectInScreen.move(0, -(widgetRectInScreen.height() + targetControlHeight));
|
| } else {
|
| // Figure whether upwards or downwards has more room and set the
|
| // maximum number of items.
|
| - int spaceAbove = widgetRect.y() - targetControlHeight;
|
| - int spaceBelow = screen.maxY() - widgetRect.y();
|
| + int spaceAbove = widgetRectInScreen.y() - targetControlHeight;
|
| + int spaceBelow = screen.maxY() - widgetRectInScreen.y();
|
| if (spaceAbove > spaceBelow)
|
| m_listBox->setMaxHeight(spaceAbove);
|
| else
|
| @@ -189,15 +189,16 @@
|
| // We don't have to recompute X axis, so we only replace Y axis
|
| // in widgetRect.
|
| IntRect frameInScreen = chromeClient->rootViewToScreen(frameRect());
|
| - widgetRect.setY(frameInScreen.y());
|
| - widgetRect.setHeight(frameInScreen.height());
|
| + widgetRectInScreen.setY(frameInScreen.y());
|
| + widgetRectInScreen.setHeight(frameInScreen.height());
|
| // And move upwards if necessary.
|
| if (spaceAbove > spaceBelow)
|
| - widgetRect.move(0, -(widgetRect.height() + targetControlHeight));
|
| + widgetRectInScreen.move(0, -(widgetRectInScreen.height() + targetControlHeight));
|
| }
|
| }
|
| }
|
| - return widgetRect;
|
| +
|
| + return widgetRectInScreen;
|
| }
|
|
|
| void PopupContainer::showPopup(FrameView* view)
|
| @@ -207,7 +208,7 @@
|
|
|
| ChromeClientChromium* chromeClient = chromeClientChromium();
|
| if (chromeClient) {
|
| - IntRect popupRect = frameRect();
|
| + IntRect popupRect = m_originalFrameRect;
|
| chromeClient->popupOpened(this, layoutAndCalculateWidgetRect(popupRect.height(), popupRect.location()), false);
|
| m_popupOpen = true;
|
| }
|
| @@ -400,29 +401,33 @@
|
| location.move(0, r.height());
|
|
|
| m_originalFrameRect = IntRect(location, r.size());
|
| - setFrameRect(m_originalFrameRect);
|
| +
|
| + // Position at (0, 0) since the frameRect().location() is relative to the parent WebWidget.
|
| + setFrameRect(IntRect(IntPoint(), r.size()));
|
| showPopup(v);
|
| }
|
|
|
| void PopupContainer::refresh(const IntRect& targetControlRect)
|
| {
|
| - IntPoint location = m_frameView->contentsToWindow(targetControlRect.location());
|
| + listBox()->setBaseWidth(max(m_originalFrameRect.width() - kBorderSize * 2, 0));
|
| + listBox()->updateFromElement();
|
| +
|
| + IntPoint locationInWindow = m_frameView->contentsToWindow(targetControlRect.location());
|
| +
|
| // Move it below the select widget.
|
| - location.move(0, targetControlRect.height());
|
| + locationInWindow.move(0, targetControlRect.height());
|
|
|
| - listBox()->setBaseWidth(max(m_originalFrameRect.width() - kBorderSize * 2, 0));
|
| + IntRect widgetRectInScreen = layoutAndCalculateWidgetRect(targetControlRect.height(), locationInWindow);
|
|
|
| - listBox()->updateFromElement();
|
| - // Store the original size to check if we need to request the location.
|
| - IntSize originalSize = size();
|
| - IntRect widgetRect = layoutAndCalculateWidgetRect(targetControlRect.height(), location);
|
| - if (originalSize != widgetRect.size()) {
|
| - ChromeClientChromium* chromeClient = chromeClientChromium();
|
| - if (chromeClient) {
|
| - IntPoint widgetLocation = chromeClient->screenToRootView(widgetRect.location());
|
| - widgetRect.setLocation(widgetLocation);
|
| - setFrameRect(widgetRect);
|
| - }
|
| + // Reset the size (which can be set to the PopupListBox size in layoutAndGetRTLOffset(), exceeding the available widget rectangle.)
|
| + if (size() != widgetRectInScreen.size())
|
| + resize(widgetRectInScreen.size());
|
| +
|
| + ChromeClientChromium* chromeClient = chromeClientChromium();
|
| + if (chromeClient) {
|
| + // Update the WebWidget location (which is relative to the screen origin).
|
| + if (widgetRectInScreen != chromeClient->windowRect())
|
| + chromeClient->setWindowRect(widgetRectInScreen);
|
| }
|
|
|
| invalidate();
|
|
|