Buttons failed to draw when selected with the keyboard, and
sometimes when selected by touch, for three reasons:
1) GL short-circuits if the last extra rectangle and the
curent extra rectangle match. When buttons change color,
the rectangles do match, but the picture still needs to
be redrawn.
2) Buttons do not have cursor rings, so the button's bounds
was not passed to GL.
3) The timeout logic to switch from a focused state to a normal
state was incorrect.
This adds a flag to GLWebViewState::setExtra that can skip the
equal rectangle case. Note that the equal rectangle test hides
a more serious bug where the setExtra is called repeatedly -- so
it would be worthwhile to examine this further.
The logic that determines if the cursor is a button was split
out so that the cursor ring can be associated with a button even
if the cursor is hidden.
bug:
3364248
Change-Id: I75944cb045486c128743aa13922d20758ccf783f
}
void GLWebViewState::setExtra(BaseLayerAndroid* layer, SkPicture& picture,
- const IntRect& rect)
+ const IntRect& rect, bool allowSame)
{
android::Mutex::Autolock lock(m_baseLayerLock);
if (!m_baseLayerUpdate)
layer->setExtra(picture);
- if (m_lastInval == rect)
+ if (!allowSame && m_lastInval == rect)
return;
if (!rect.isEmpty())
unsigned int paintBaseLayerContent(SkCanvas* canvas);
void setBaseLayer(BaseLayerAndroid* layer, const IntRect& rect);
- void setExtra(BaseLayerAndroid*, SkPicture&, const IntRect&);
+ void setExtra(BaseLayerAndroid*, SkPicture&, const IntRect&, bool allowSame);
void scheduleUpdate(const double& currentTime, const SkIRect& viewport, float scale);
TiledPage* sibling(TiledPage* page);
inval->unite(m_lastBounds);
}
-bool CursorRing::setup()
+void CursorRing::setIsButton(const CachedNode* node)
{
- m_node->localCursorRings(m_frame, &m_rings);
- if (!m_rings.size()) {
- DBG_NAV_LOG("!rings.size()");
- m_viewImpl->m_hasCursorBounds = false;
- return false;
- }
m_isButton = false;
m_viewImpl->gButtonMutex.lock();
// If this is a button drawn by us (rather than webkit) do not draw the
// Should be in sync with recordButtons, since that will be called
// before this.
if (m_viewImpl->m_buttons.size() > 0) {
- WebCore::Node* cursorPointer = (WebCore::Node*) m_node->nodePointer();
+ WebCore::Node* cursorPointer = (WebCore::Node*) node->nodePointer();
Container* end = m_viewImpl->m_buttons.end();
for (Container* ptr = m_viewImpl->m_buttons.begin(); ptr != end; ptr++) {
if (ptr->matches(cursorPointer)) {
}
}
m_viewImpl->gButtonMutex.unlock();
+}
+
+bool CursorRing::setup()
+{
+ m_node->localCursorRings(m_frame, &m_rings);
+ if (!m_rings.size()) {
+ DBG_NAV_LOG("!rings.size()");
+ m_viewImpl->m_hasCursorBounds = false;
+ return false;
+ }
+ setIsButton(m_node);
m_bounds = m_node->localBounds(m_frame);
m_viewImpl->updateCursorBounds(m_root, m_frame, m_node);
CursorRing(WebViewCore* core) : m_viewImpl(core) {}
virtual ~CursorRing() {}
virtual void draw(SkCanvas* , LayerAndroid* , IntRect* );
+ void setIsButton(const CachedNode* );
bool setup();
private:
friend class WebView;
if (hasFocus) {
if (pressed || m_ring.m_isPressed)
state = RenderSkinAndroid::kPressed;
- else if (SkTime::GetMSecs() < m_ringAnimationEnd
- && m_ringAnimationEnd != UINT_MAX) {
+ else if (SkTime::GetMSecs() < m_ringAnimationEnd)
state = RenderSkinAndroid::kFocused;
- }
}
}
ptr->updateFocusState(state);
resetCursorRing();
return false;
}
+ m_ring.setIsButton(node);
if (node->isHidden()) {
DBG_NAV_LOG("node->isHidden()");
m_viewImpl->m_hasCursorBounds = false;
SkPicture picture;
IntRect rect(0, 0, 0, 0);
+ bool allowSame = false;
if (extra) {
LayerAndroid mainPicture(m_navPictureUI);
PictureSet* content = m_baseLayer->content();
content->height());
extra->draw(canvas, &mainPicture, &rect);
picture.endRecording();
+ } else if (extras == DrawExtrasCursorRing && m_ring.m_isButton) {
+ const CachedFrame* cachedFrame;
+ const CachedNode* cachedCursor = root->currentCursor(&cachedFrame);
+ if (cachedCursor) {
+ rect = cachedCursor->bounds(cachedFrame);
+ allowSame = true;
+ }
}
- m_glWebViewState->setExtra(m_baseLayer, picture, rect);
+ m_glWebViewState->setExtra(m_baseLayer, picture, rect, allowSame);
LayerAndroid* compositeLayer = compositeRoot();
if (compositeLayer)