summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--WebCore/config.h2
-rw-r--r--WebCore/rendering/InlineTextBox.cpp53
-rw-r--r--WebCore/rendering/InlineTextBox.h10
-rw-r--r--WebCore/rendering/RenderText.cpp17
-rw-r--r--WebKit/android/jni/WebHistory.cpp4
-rw-r--r--WebKit/android/jni/WebViewCore.cpp53
-rw-r--r--WebKit/android/jni/WebViewCore.h8
-rw-r--r--WebKit/android/nav/SelectText.cpp10
-rw-r--r--WebKit/android/nav/WebView.cpp5
9 files changed, 133 insertions, 29 deletions
diff --git a/WebCore/config.h b/WebCore/config.h
index b2af90a..7174c4b 100644
--- a/WebCore/config.h
+++ b/WebCore/config.h
@@ -148,6 +148,8 @@
#define ANDROID_FIX
+#define ANDROID_DISABLE_ROUNDING_HACKS
+
// Ensure that the fixed elements are always relative to the top document.
#define ANDROID_FIXED_ELEMENTS
diff --git a/WebCore/rendering/InlineTextBox.cpp b/WebCore/rendering/InlineTextBox.cpp
index 575bdf2..2bec8a1 100644
--- a/WebCore/rendering/InlineTextBox.cpp
+++ b/WebCore/rendering/InlineTextBox.cpp
@@ -158,8 +158,15 @@ IntRect InlineTextBox::selectionRect(int tx, int ty, int startPos, int endPos)
ePos = len;
}
+#ifdef ANDROID_DISABLE_ROUNDING_HACKS
+ TextRun textRun = TextRun(characters, len, textObj->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride);
+ if (m_disableRoundingHacks)
+ textRun.disableRoundingHacks();
+ IntRect r = enclosingIntRect(f.selectionRectForText(textRun, IntPoint(), selHeight, sPos, ePos));
+#else
IntRect r = enclosingIntRect(f.selectionRectForText(TextRun(characters, len, textObj->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride),
IntPoint(), selHeight, sPos, ePos));
+#endif
int logicalWidth = r.width();
if (r.x() > m_logicalWidth)
@@ -555,6 +562,10 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty)
adjustCharactersAndLengthForHyphen(charactersWithHyphen, styleToUse, characters, length);
TextRun textRun(characters, length, textRenderer()->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride || styleToUse->visuallyOrdered());
+#ifdef ANDROID_DISABLE_ROUNDING_HACKS
+ if (m_disableRoundingHacks)
+ textRun.disableRoundingHacks();
+#endif
int sPos = 0;
int ePos = 0;
@@ -689,9 +700,17 @@ void InlineTextBox::paintSelection(GraphicsContext* context, const IntPoint& box
int selHeight = selectionHeight();
IntPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
context->clip(IntRect(localOrigin, IntSize(m_logicalWidth, selHeight)));
+#ifdef ANDROID_DISABLE_ROUNDING_HACKS
+ TextRun textRun = TextRun(characters, length, textRenderer()->allowTabs(), textPos(), m_toAdd,
+ !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
+ if (m_disableRoundingHacks)
+ textRun.disableRoundingHacks();
+ context->drawHighlightForText(font, textRun, localOrigin, selHeight, c, style->colorSpace(), sPos, ePos);
+#else
context->drawHighlightForText(font, TextRun(characters, length, textRenderer()->allowTabs(), textPos(), m_toAdd,
!isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()),
localOrigin, selHeight, c, style->colorSpace(), sPos, ePos);
+#endif
context->restore();
}
@@ -713,9 +732,17 @@ void InlineTextBox::paintCompositionBackground(GraphicsContext* context, const I
int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
int selHeight = selectionHeight();
IntPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
+#ifdef ANDROID_DISABLE_ROUNDING_HACKS
+ TextRun textRun = TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd,
+ !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
+ if (m_disableRoundingHacks)
+ textRun.disableRoundingHacks();
+ context->drawHighlightForText(font, textRun, localOrigin, selHeight, c, style->colorSpace(), sPos, ePos);
+#else
context->drawHighlightForText(font, TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd,
!isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()),
localOrigin, selHeight, c, style->colorSpace(), sPos, ePos);
+#endif
context->restore();
}
@@ -876,6 +903,10 @@ void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, const IntP
int selHeight = selectionHeight();
IntPoint startPoint(boxOrigin.x(), boxOrigin.y() - deltaY);
TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
+#ifdef ANDROID_DISABLE_ROUNDING_HACKS
+ if (m_disableRoundingHacks)
+ run.disableRoundingHacks();
+#endif
IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, startPoint, selHeight, startPosition, endPosition));
start = markerRect.x() - startPoint.x();
@@ -920,6 +951,10 @@ void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, const IntPoint& bo
int sPos = max(marker.startOffset - m_start, (unsigned)0);
int ePos = min(marker.endOffset - m_start, (unsigned)m_len);
TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
+#ifdef ANDROID_DISABLE_ROUNDING_HACKS
+ if (m_disableRoundingHacks)
+ run.disableRoundingHacks();
+#endif
// Always compute and store the rect associated with this marker. The computed rect is in absolute coordinates.
IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, IntPoint(m_x, selectionTop()), selHeight, sPos, ePos));
@@ -948,6 +983,10 @@ void InlineTextBox::computeRectForReplacementMarker(const DocumentMarker& marker
int sPos = max(marker.startOffset - m_start, (unsigned)0);
int ePos = min(marker.endOffset - m_start, (unsigned)m_len);
TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
+#ifdef ANDROID_DISABLE_ROUNDING_HACKS
+ if (m_disableRoundingHacks)
+ run.disableRoundingHacks();
+#endif
IntPoint startPoint = IntPoint(m_x, y);
// Compute and store the rect associated with this marker.
@@ -1099,8 +1138,15 @@ int InlineTextBox::offsetForPosition(int lineOffset, bool includePartialGlyphs)
RenderText* text = toRenderText(renderer());
RenderStyle* style = text->style(m_firstLine);
const Font* f = &style->font();
+#ifdef ANDROID_DISABLE_ROUNDING_HACKS
+ TextRun textRun = TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
+ if (m_disableRoundingHacks)
+ textRun.disableRoundingHacks();
+ return f->offsetForPosition(textRun, lineOffset - logicalLeft(), includePartialGlyphs);
+#else
return f->offsetForPosition(TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()),
lineOffset - logicalLeft(), includePartialGlyphs);
+#endif
}
int InlineTextBox::positionForOffset(int offset) const
@@ -1116,8 +1162,15 @@ int InlineTextBox::positionForOffset(int offset) const
int from = !isLeftToRightDirection() ? offset - m_start : 0;
int to = !isLeftToRightDirection() ? m_len : offset - m_start;
// FIXME: Do we need to add rightBearing here?
+#ifdef ANDROID_DISABLE_ROUNDING_HACKS
+ TextRun textRun = TextRun(text->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride);
+ if (m_disableRoundingHacks)
+ textRun.disableRoundingHacks();
+ return enclosingIntRect(f.selectionRectForText(textRun, IntPoint(logicalLeft(), 0), 0, from, to)).right();
+#else
return enclosingIntRect(f.selectionRectForText(TextRun(text->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride),
IntPoint(logicalLeft(), 0), 0, from, to)).right();
+#endif
}
bool InlineTextBox::containsCaretOffset(int offset) const
diff --git a/WebCore/rendering/InlineTextBox.h b/WebCore/rendering/InlineTextBox.h
index bc2219b..e19da2e 100644
--- a/WebCore/rendering/InlineTextBox.h
+++ b/WebCore/rendering/InlineTextBox.h
@@ -39,13 +39,20 @@ Color correctedTextColor(Color textColor, Color backgroundColor);
class InlineTextBox : public InlineBox {
public:
+#ifdef ANDROID_DISABLE_ROUNDING_HACKS
+ InlineTextBox(RenderObject* obj, bool disableRoundingHacks = false)
+#else
InlineTextBox(RenderObject* obj)
+#endif
: InlineBox(obj)
, m_prevTextBox(0)
, m_nextTextBox(0)
, m_start(0)
, m_len(0)
, m_truncation(cNoTruncation)
+#ifdef ANDROID_DISABLE_ROUNDING_HACKS
+ , m_disableRoundingHacks(disableRoundingHacks)
+#endif
{
}
@@ -139,6 +146,9 @@ private:
unsigned short m_truncation; // Where to truncate when text overflow is applied. We use special constants to
// denote no truncation (the whole run paints) and full truncation (nothing paints at all).
+#ifdef ANDROID_DISABLE_ROUNDING_HACKS
+ bool m_disableRoundingHacks;
+#endif
protected:
void paintCompositionBackground(GraphicsContext*, const IntPoint& boxOrigin, RenderStyle*, const Font&, int startPos, int endPos);
diff --git a/WebCore/rendering/RenderText.cpp b/WebCore/rendering/RenderText.cpp
index 7635d07..b1e9413 100644
--- a/WebCore/rendering/RenderText.cpp
+++ b/WebCore/rendering/RenderText.cpp
@@ -1158,10 +1158,27 @@ void RenderText::dirtyLineBoxes(bool fullLayout)
}
m_linesDirty = false;
}
+#ifdef ANDROID_DISABLE_ROUNDING_HACKS
+static bool disableRoundingHacks(RenderText* renderText)
+{
+ RenderObject* renderer = renderText;
+ while (renderer) {
+ if (renderer->isTextControl()) {
+ return true;
+ }
+ renderer = renderer->parent();
+ }
+ return false;
+}
+#endif
InlineTextBox* RenderText::createTextBox()
{
+#ifdef ANDROID_DISABLE_ROUNDING_HACKS
+ return new (renderArena()) InlineTextBox(this, disableRoundingHacks(this));
+#else
return new (renderArena()) InlineTextBox(this);
+#endif
}
InlineTextBox* RenderText::createInlineTextBox()
diff --git a/WebKit/android/jni/WebHistory.cpp b/WebKit/android/jni/WebHistory.cpp
index 7f3e4e3..52d9f61 100644
--- a/WebKit/android/jni/WebHistory.cpp
+++ b/WebKit/android/jni/WebHistory.cpp
@@ -168,8 +168,8 @@ static void WebHistoryInflate(JNIEnv* env, jobject obj, jint frame, jbyteArray d
// Inflate the history tree into one HistoryItem or null if the inflation
// failed.
RefPtr<WebCore::HistoryItem> newItem = WebCore::HistoryItem::create();
- RefPtr<WebHistoryItem> bridge = adoptRef(new WebHistoryItem(env, obj, newItem.get()));
- newItem->setBridge(bridge.get());
+ WebHistoryItem* bridge = new WebHistoryItem(env, obj, newItem.get());
+ newItem->setBridge(bridge);
// Inflate the item recursively. If it fails, that is ok. We'll have an
// incomplete HistoryItem but that is better than crashing due to a null
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp
index 110ce94..3de3810 100644
--- a/WebKit/android/jni/WebViewCore.cpp
+++ b/WebKit/android/jni/WebViewCore.cpp
@@ -2579,9 +2579,25 @@ public:
// Response used for a multiple selection listbox if the user did not change
// anything, in which case -2 is used.
+ // Also used by a listbox which has single selection but a size is set.
virtual void replyInt(int index)
{
- LOG_ASSERT(-2 == index, "ListBoxReply::replyInt should only be called with -2");
+ if (-2 == index) {
+ // Special value for cancel. Do nothing.
+ return;
+ }
+ // If the select element no longer exists, due to a page change, etc,
+ // silently return.
+ if (!m_select || !CacheBuilder::validNode(m_viewImpl->m_mainFrame,
+ m_frame, m_select))
+ return;
+ // Use a pointer to HTMLSelectElement's superclass, where
+ // listToOptionIndex is public
+ SelectElement* selectElement = m_select;
+ int optionIndex = selectElement->listToOptionIndex(index);
+ m_select->setSelectedIndex(optionIndex, true);
+ m_select->dispatchFormControlChangeEvent();
+ m_viewImpl->contentInvalidate(m_select->getRect());
}
// Response if the listbox allows multiple selection. array stores the listIndices
@@ -2750,8 +2766,9 @@ bool WebViewCore::key(const PlatformKeyboardEvent& event)
return eventHandler->keyEvent(event);
}
-// For when the user clicks the trackball
-void WebViewCore::click(WebCore::Frame* frame, WebCore::Node* node) {
+// For when the user clicks the trackball, presses dpad center, or types into an
+// unfocused textfield. In the latter case, 'fake' will be true
+void WebViewCore::click(WebCore::Frame* frame, WebCore::Node* node, bool fake) {
if (!node) {
WebCore::IntPoint pt = m_mousePos;
pt.move(m_scrollOffsetX, m_scrollOffsetY);
@@ -2768,7 +2785,7 @@ void WebViewCore::click(WebCore::Frame* frame, WebCore::Node* node) {
= static_cast<EditorClientAndroid*>(
m_mainFrame->editor()->client());
client->setShouldChangeSelectedRange(false);
- handleMouseClick(frame, node);
+ handleMouseClick(frame, node, fake);
client->setShouldChangeSelectedRange(true);
}
}
@@ -2874,7 +2891,7 @@ void WebViewCore::touchUp(int touchGeneration,
}
DBG_NAV_LOGD("touchGeneration=%d handleMouseClick frame=%p node=%p"
" x=%d y=%d", touchGeneration, frame, node, x, y);
- handleMouseClick(frame, node);
+ handleMouseClick(frame, node, false);
}
// Return the RenderLayer for the given RenderObject only if the layer is
@@ -2923,7 +2940,9 @@ static void scrollLayer(WebCore::RenderObject* renderer, WebCore::IntPoint* pos)
}
// Common code for both clicking with the trackball and touchUp
-bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* nodePtr)
+// Also used when typing into a non-focused textfield to give the textfield focus,
+// in which case, 'fake' is set to true
+bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* nodePtr, bool fake)
{
m_lastClickWasOnTextInput = false;
bool valid = framePtr == NULL
@@ -3023,14 +3042,16 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node
autoFill->formFieldFocused(static_cast<HTMLFormControlElement*>(focusNode));
}
#endif
- RenderTextControl* rtc
- = static_cast<RenderTextControl*> (renderer);
- requestKeyboardWithSelection(focusNode, rtc->selectionStart(),
- rtc->selectionEnd());
- } else {
+ if (!fake) {
+ RenderTextControl* rtc
+ = static_cast<RenderTextControl*> (renderer);
+ requestKeyboardWithSelection(focusNode, rtc->selectionStart(),
+ rtc->selectionEnd());
+ }
+ } else if (!fake) {
requestKeyboard(false);
}
- } else {
+ } else if (!fake){
// If the selection is contentEditable, show the keyboard so the
// user can type. Otherwise hide the keyboard because no text
// input is needed.
@@ -3040,7 +3061,7 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node
clearTextEntry();
}
}
- } else {
+ } else if (!fake) {
// There is no focusNode, so the keyboard is not needed.
clearTextEntry();
}
@@ -3537,7 +3558,7 @@ static jboolean Key(JNIEnv *env, jobject obj, jint keyCode, jint unichar,
unichar, repeatCount, isDown, isShift, isAlt, isSym));
}
-static void Click(JNIEnv *env, jobject obj, int framePtr, int nodePtr)
+static void Click(JNIEnv *env, jobject obj, int framePtr, int nodePtr, jboolean fake)
{
#ifdef ANDROID_INSTRUMENT
TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter);
@@ -3546,7 +3567,7 @@ static void Click(JNIEnv *env, jobject obj, int framePtr, int nodePtr)
LOG_ASSERT(viewImpl, "viewImpl not set in Click");
viewImpl->click(reinterpret_cast<WebCore::Frame*>(framePtr),
- reinterpret_cast<WebCore::Node*>(nodePtr));
+ reinterpret_cast<WebCore::Node*>(nodePtr), fake);
}
static void ContentInvalidateAll(JNIEnv *env, jobject obj)
@@ -4160,7 +4181,7 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = {
(void*) FocusBoundsChanged } ,
{ "nativeKey", "(IIIZZZZ)Z",
(void*) Key },
- { "nativeClick", "(II)V",
+ { "nativeClick", "(IIZ)V",
(void*) Click },
{ "nativeContentInvalidateAll", "()V",
(void*) ContentInvalidateAll },
diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h
index ae5a65f..dc93de9 100644
--- a/WebKit/android/jni/WebViewCore.h
+++ b/WebKit/android/jni/WebViewCore.h
@@ -325,9 +325,11 @@ namespace android {
bool key(const WebCore::PlatformKeyboardEvent& event);
/**
- * Handle (trackball) click event from Java
+ * Handle (trackball) click event / dpad center press from Java.
+ * Also used when typing into an unfocused textfield, in which case 'fake'
+ * will be true.
*/
- void click(WebCore::Frame* frame, WebCore::Node* node);
+ void click(WebCore::Frame* frame, WebCore::Node* node, bool fake);
/**
* Handle touch event
@@ -630,7 +632,7 @@ namespace android {
SkPicture* rebuildPicture(const SkIRect& inval);
void rebuildPictureSet(PictureSet* );
void sendNotifyProgressFinished();
- bool handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* nodePtr);
+ bool handleMouseClick(WebCore::Frame*, WebCore::Node*, bool);
WebCore::HTMLAnchorElement* retrieveAnchorElement(int x, int y);
WebCore::HTMLElement* retrieveElement(int x, int y,
const WebCore::QualifiedName& );
diff --git a/WebKit/android/nav/SelectText.cpp b/WebKit/android/nav/SelectText.cpp
index f2d7521..ff69ddd 100644
--- a/WebKit/android/nav/SelectText.cpp
+++ b/WebKit/android/nav/SelectText.cpp
@@ -608,11 +608,11 @@ public:
}
// cx and cy are the distances from the tested center
// The center distance is used when the test point is over the text
- int cx = INT_MAX;
- int cy = INT_MAX;
- if (ignoreColumn && dy == 0 && mDy == 0) {
- cy = std::abs(((testBounds.fTop + testBounds.fBottom) >> 1)
+ int cx = std::abs(((testBounds.fLeft + testBounds.fRight) >> 1)
+ - mFocusX);
+ int cy = std::abs(((testBounds.fTop + testBounds.fBottom) >> 1)
- mFocusY);
+ if (ignoreColumn && dy == 0 && mDy == 0) {
if (mCy < cy) {
#ifdef EXTRA_NOISY_LOGGING
DBG_NAV_LOGD("FirstCheck reject cy=%d mCy=%d", cy, mCy);
@@ -621,8 +621,6 @@ public:
}
if (mCy == cy) {
if (dx == 0 && mDx == 0) {
- cx = std::abs(((testBounds.fLeft + testBounds.fRight) >> 1)
- - mFocusX);
if (mCx < cx) {
#ifdef EXTRA_NOISY_LOGGING
DBG_NAV_LOGD("FirstCheck reject cx=%d mCx=%d", cx, mCx);
diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp
index 8252bb8..76feacd 100644
--- a/WebKit/android/nav/WebView.cpp
+++ b/WebKit/android/nav/WebView.cpp
@@ -840,8 +840,9 @@ bool moveCursor(int keyCode, int count, bool ignoreScroll)
m_viewImpl->updateCursorBounds(root, cachedFrame, cachedNode);
root->setCursor(const_cast<CachedFrame*>(cachedFrame),
const_cast<CachedNode*>(cachedNode));
- bool clearTextEntry = cachedNode != root->currentFocus()
- && cachedNode->wantsKeyEvents();
+ const CachedNode* focus = root->currentFocus();
+ bool clearTextEntry = cachedNode != focus && focus
+ && cachedNode->nodePointer() != focus->nodePointer() && focus->isTextInput();
sendMoveMouseIfLatest(clearTextEntry);
sendMoveSelection((WebCore::Frame*) cachedFrame->framePointer(),
(WebCore::Node*) cachedNode->nodePointer());