Commit 28399bcb authored by darin's avatar darin

WebCore:

        Reviewed by John Sullivan.

        - fix http://bugs.webkit.org/show_bug.cgi?id=13303
          <rdar://problem/5126341> REGRESSION: controls in a background Safari window
          maintain active appearance if the address bar has focus (13303)

        - fix a related problem where elements could look focused in non-active windows

        - simplify secure keyboard entry logic in Frame::setIsActive

        * WebCore.exp: Add two new symbols for use by WebKit.

        * html/HTMLInputElement.cpp:
        (WebCore::HTMLInputElement::dispatchFocusEvent): Call setUseSecureKeyboardEntryWhenActive
        rather than calling setSecureKeyboardEntry directly -- does nothing if the frame is not active.
        (WebCore::HTMLInputElement::dispatchBlurEvent): Ditto.

        * page/Frame.cpp:
        (WebCore::Frame::setUseSecureKeyboardEntryWhenActive): Added. Calls
        setUseSecureKeyboardEntry only if the frame is active, but also stores away the state,
        so that the setIsActive function doesn't have to recompute it.
        (WebCore::Frame::setIsActive): Rewrote all the comments in the function. Removed the code
        to manage control tints, which are not based on the whether the frame is active but rather
        on AppKit's concept of whether the window should have "key appearance". Simplified the
        logic about when to call setUseSecureKeyboardEntry by using the value of
        m_useSecureKeyboardEntryWhenActive.
        (WebCore::FramePrivate::FramePrivate): Initialize m_useSecureKeyboardEntryWhenActive.
        * page/Frame.h: Made setSecureKeyboardEntry private and renamed it to
        setUseSecureKeyboardEntry, removed isSecureKeyboardEntry, and
        added a public setUseSecureKeyboardEntryWhenActive.
        * page/FramePrivate.h: Added m_useSecureKeyboardEntryWhenActive.
        * page/mac/FrameMac.mm: (WebCore::Frame::setUseSecureKeyboardEntry): Added an assertion,
        and removed isSecureKeyboardEntry().

        * page/FrameView.h: Added updateControlTints.
        * page/FrameView.cpp: (WebCore::FrameView::updateControlTints): Added. Code was moved
        here from setIsActive for two reasons: (1) it makes more sense in the view class, and
        (2) it needs to be called at the appropriate time for AppKit, not when active changes.

        * rendering/RenderTheme.cpp: (WebCore::RenderTheme::isFocused): Added an isActive
        check here to match the logic in the implementation of the CSS pseudo-state.
        * rendering/RenderThemeMac.mm:
        (WebCore::RenderThemeMac::updateFocusedState): Use the isFocused function instead of
        repeating the logic here. Removed the "need to add a key window test here" comment.
        (WebCore::RenderThemeMac::controlSupportsTints): Added a comment about the NSCell
        SPI that's related to the _windowChangedKeyState method we now use in WebHTMLView.

WebKit:

        Reviewed by John Sullivan.

        - fix http://bugs.webkit.org/show_bug.cgi?id=13303
          <rdar://problem/5126341> REGRESSION: controls in a background Safari window
          maintain active appearance if the address bar has focus (13303)

        * WebView/WebHTMLView.mm: (-[WebHTMLView _windowChangedKeyState]):
        Added. Calls FrameView::updateControlTints.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@20901 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 68de92f7
2007-04-16 Darin Adler <darin@apple.com>
Reviewed by John Sullivan.
- fix http://bugs.webkit.org/show_bug.cgi?id=13303
<rdar://problem/5126341> REGRESSION: controls in a background Safari window
maintain active appearance if the address bar has focus (13303)
- fix a related problem where elements could look focused in non-active windows
- simplify secure keyboard entry logic in Frame::setIsActive
* WebCore.exp: Add two new symbols for use by WebKit.
* html/HTMLInputElement.cpp:
(WebCore::HTMLInputElement::dispatchFocusEvent): Call setUseSecureKeyboardEntryWhenActive
rather than calling setSecureKeyboardEntry directly -- does nothing if the frame is not active.
(WebCore::HTMLInputElement::dispatchBlurEvent): Ditto.
* page/Frame.cpp:
(WebCore::Frame::setUseSecureKeyboardEntryWhenActive): Added. Calls
setUseSecureKeyboardEntry only if the frame is active, but also stores away the state,
so that the setIsActive function doesn't have to recompute it.
(WebCore::Frame::setIsActive): Rewrote all the comments in the function. Removed the code
to manage control tints, which are not based on the whether the frame is active but rather
on AppKit's concept of whether the window should have "key appearance". Simplified the
logic about when to call setUseSecureKeyboardEntry by using the value of
m_useSecureKeyboardEntryWhenActive.
(WebCore::FramePrivate::FramePrivate): Initialize m_useSecureKeyboardEntryWhenActive.
* page/Frame.h: Made setSecureKeyboardEntry private and renamed it to
setUseSecureKeyboardEntry, removed isSecureKeyboardEntry, and
added a public setUseSecureKeyboardEntryWhenActive.
* page/FramePrivate.h: Added m_useSecureKeyboardEntryWhenActive.
* page/mac/FrameMac.mm: (WebCore::Frame::setUseSecureKeyboardEntry): Added an assertion,
and removed isSecureKeyboardEntry().
* page/FrameView.h: Added updateControlTints.
* page/FrameView.cpp: (WebCore::FrameView::updateControlTints): Added. Code was moved
here from setIsActive for two reasons: (1) it makes more sense in the view class, and
(2) it needs to be called at the appropriate time for AppKit, not when active changes.
* rendering/RenderTheme.cpp: (WebCore::RenderTheme::isFocused): Added an isActive
check here to match the logic in the implementation of the CSS pseudo-state.
* rendering/RenderThemeMac.mm:
(WebCore::RenderThemeMac::updateFocusedState): Use the isFocused function instead of
repeating the logic here. Removed the "need to add a key window test here" comment.
(WebCore::RenderThemeMac::controlSupportsTints): Added a comment about the NSCell
SPI that's related to the _windowChangedKeyState method we now use in WebHTMLView.
2007-04-16 Darin Adler <darin@apple.com>
Reviewed by John Sullivan.
......@@ -440,6 +440,7 @@ __ZN7WebCore8parseURLERKNS_6StringE
__ZN7WebCore9FloatRectC1ERK7_NSRect
__ZN7WebCore9FrameTree11appendChildEN3WTF10PassRefPtrINS_5FrameEEE
__ZN7WebCore9FrameTree7setNameERKNS_12AtomicStringE
__ZN7WebCore9FrameView18updateControlTintsEv
__ZN7WebCore9HTMLNames10listingTagE
__ZN7WebCore9HTMLNames13blockquoteTagE
__ZN7WebCore9HTMLNames4aTagE
......@@ -571,6 +572,7 @@ __ZNK7WebCore5Frame31fontAttributesForSelectionStartEv
__ZNK7WebCore5Frame33removeEditingStyleFromBodyElementEv
__ZNK7WebCore5Frame4pageEv
__ZNK7WebCore5Frame4treeEv
__ZNK7WebCore5Frame4viewEv
__ZNK7WebCore5Frame6bridgeEv
__ZNK7WebCore5Frame6editorEv
__ZNK7WebCore5Frame6loaderEv
......
......@@ -232,7 +232,7 @@ void HTMLInputElement::dispatchFocusEvent()
if (isTextField()) {
setAutofilled(false);
if (inputType() == PASSWORD && document()->frame())
document()->frame()->setSecureKeyboardEntry(true);
document()->frame()->setUseSecureKeyboardEntryWhenActive(true);
}
HTMLGenericFormElement::dispatchFocusEvent();
}
......@@ -241,7 +241,7 @@ void HTMLInputElement::dispatchBlurEvent()
{
if (isTextField() && document()->frame()) {
if (inputType() == PASSWORD)
document()->frame()->setSecureKeyboardEntry(false);
document()->frame()->setUseSecureKeyboardEntryWhenActive(false);
document()->frame()->textFieldDidEndEditing(this);
}
HTMLGenericFormElement::dispatchBlurEvent();
......
......@@ -770,17 +770,23 @@ bool Frame::isContentEditable() const
}
#if !PLATFORM(MAC)
void Frame::setSecureKeyboardEntry(bool)
{
}
bool Frame::isSecureKeyboardEntry()
void Frame::setUseSecureKeyboardEntry(bool)
{
return false;
}
#endif
void Frame::setUseSecureKeyboardEntryWhenActive(bool usesSecureKeyboard)
{
if (d->m_useSecureKeyboardEntryWhenActive == usesSecureKeyboard)
return;
d->m_useSecureKeyboardEntryWhenActive = usesSecureKeyboard;
if (d->m_isActive)
setUseSecureKeyboardEntry(usesSecureKeyboard);
}
CSSMutableStyleDeclaration *Frame::typingStyle() const
{
return d->m_typingStyle.get();
......@@ -1480,48 +1486,34 @@ void Frame::setIsActive(bool flag)
{
if (d->m_isActive == flag)
return;
d->m_isActive = flag;
// This method does the job of updating the view based on whether the view is "active".
// This involves three kinds of drawing updates:
// 1. The background color used to draw behind selected content (active | inactive color)
// Because RenderObject::selectionBackgroundColor() and
// RenderObject::selectionForegroundColor() check if the frame is active,
// we have to update places those colors were painted.
if (d->m_view)
d->m_view->updateContents(enclosingIntRect(visibleSelectionRect()));
// 2. Caret blinking (blinks | does not blink)
// Caret appears in the active frame.
if (flag)
setSelectionFromNone();
setCaretVisible(flag);
// 3. The drawing of a focus ring around links in web pages.
Document *doc = document();
if (doc) {
Node *node = doc->focusedNode();
if (node) {
// Because CSSStyleSelector::checkOneSelector() and
// RenderTheme::isFocused() check if the frame is active, we have to
// update style and theme state that depended on those.
if (d->m_doc) {
if (Node* node = d->m_doc->focusedNode()) {
node->setChanged();
if (node->renderer() && node->renderer()->style()->hasAppearance())
theme()->stateChanged(node->renderer(), FocusState);
if (RenderObject* renderer = node->renderer())
if (renderer && renderer->style()->hasAppearance())
theme()->stateChanged(renderer, FocusState);
}
}
// 4. Changing the tint of controls from clear to aqua/graphite and vice versa. We
// do a "fake" paint. When the theme gets a paint call, it can then do an invalidate. This is only
// done if the theme supports control tinting.
if (doc && d->m_view && theme()->supportsControlTints() && renderer()) {
doc->updateLayout(); // Ensure layout is up to date.
IntRect visibleRect(enclosingIntRect(d->m_view->visibleContentRect()));
GraphicsContext context((PlatformGraphicsContext*)0);
context.setUpdatingControlTints(true);
paint(&context, visibleRect);
}
// 5. Enable or disable secure keyboard entry
if ((flag && !isSecureKeyboardEntry() && doc && doc->focusedNode() && doc->focusedNode()->hasTagName(inputTag) &&
static_cast<HTMLInputElement*>(doc->focusedNode())->inputType() == HTMLInputElement::PASSWORD) ||
(!flag && isSecureKeyboardEntry()))
setSecureKeyboardEntry(flag);
// Secure keyboard entry is set by the active frame.
if (d->m_useSecureKeyboardEntryWhenActive)
setUseSecureKeyboardEntry(flag);
}
void Frame::setWindowHasFocus(bool flag)
......@@ -1870,6 +1862,7 @@ FramePrivate::FramePrivate(Page* page, Frame* parent, Frame* thisFrame, HTMLFram
, m_caretVisible(false)
, m_caretPaint(true)
, m_isActive(false)
, m_useSecureKeyboardEntryWhenActive(false)
, m_lifeSupportTimer(thisFrame, &Frame::lifeSupportTimerFired)
, m_loader(new FrameLoader(thisFrame, frameLoaderClient))
, m_userStyleSheetLoader(0)
......
// -*- c-basic-offset: 4 -*-
/* This file is part of the KDE project
*
/*
* Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
* 1999-2001 Lars Knoll <knoll@kde.org>
* 1999-2001 Antti Koivisto <koivisto@kde.org>
* 2000-2001 Simon Hausmann <hausmann@kde.org>
* 2000-2001 Dirk Mueller <mueller@kde.org>
* 2000 Stefan Schimanski <1Stein@gmx.de>
* Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
* Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
* Copyright (C) 2007 Trolltech ASA
*
* This library is free software; you can redistribute it and/or
......@@ -42,7 +41,6 @@ class NPObject;
namespace KJS {
class Interpreter;
class JSObject;
namespace Bindings {
class Instance;
......@@ -52,28 +50,21 @@ namespace KJS {
#if PLATFORM(MAC)
#ifdef __OBJC__
@class WebCoreFrameBridge;
@class WebScriptObject;
@class NSArray;
@class NSDictionary;
@class NSFont;
@class NSImage;
@class NSMenu;
@class NSMutableDictionary;
@class NSString;
@class WebCoreFrameBridge;
@class WebScriptObject;
#else
class WebCoreFrameBridge;
class WebScriptObject;
class NSArray;
class NSDictionary;
class NSFont;
class NSImage;
class NSMenu;
class NSMutableDictionary;
class NSString;
class WebCoreFrameBridge;
typedef unsigned int NSDragOperation;
class WebScriptObject;
typedef int NSWritingDirection;
#endif
#endif
......@@ -105,9 +96,7 @@ class KURL;
class Node;
class Page;
class Range;
class RenderObject;
class RenderPart;
class RenderStyle;
class Selection;
class SelectionController;
class Settings;
......@@ -178,7 +167,7 @@ public:
// should move to FrameView
void paint(GraphicsContext*, const IntRect&);
void setPaintRestriction(PaintRestriction pr);
void setPaintRestriction(PaintRestriction);
void setUserStyleSheetLocation(const KURL&);
void setUserStyleSheet(const String& styleSheetData);
......@@ -325,8 +314,7 @@ public:
bool isContentEditable() const; // if true, everything in frame is editable
void setSecureKeyboardEntry(bool);
bool isSecureKeyboardEntry();
void setUseSecureKeyboardEntryWhenActive(bool);
CSSMutableStyleDeclaration* typingStyle() const;
void setTypingStyle(CSSMutableStyleDeclaration*);
......@@ -343,6 +331,7 @@ public:
private:
void caretBlinkTimerFired(Timer<Frame>*);
void setUseSecureKeyboardEntry(bool);
// === to be moved into the Platform directory
......@@ -359,6 +348,7 @@ public:
String matchLabelsAgainstElement(const Vector<String>& labels, Element*);
#if PLATFORM(MAC)
// === undecided, may or may not belong here
public:
......@@ -379,19 +369,19 @@ private:
// === to be moved into Chrome
public:
FloatRect customHighlightLineRect(const AtomicString& type, const FloatRect& lineRect, Node*);
void paintCustomHighlight(const AtomicString& type, const FloatRect& boxRect, const FloatRect& lineRect, bool text, bool line, Node*);
// === to be moved into Editor
public:
NSDictionary* fontAttributesForSelectionStart() const;
NSWritingDirection baseWritingDirectionForSelectionStart() const;
void setMarkedTextRange(const Range* , NSArray* attributes, NSArray* ranges);
#endif
};
} // namespace WebCore
......
......@@ -97,6 +97,7 @@ namespace WebCore {
bool m_caretVisible : 1;
bool m_caretPaint : 1;
bool m_isActive : 1;
bool m_useSecureKeyboardEntryWhenActive : 1;
RefPtr<CSSMutableStyleDeclaration> m_typingStyle;
......
/* This file is part of the KDE project
*
/*
* Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
* 1999 Lars Knoll <knoll@kde.org>
* 1999 Antti Koivisto <koivisto@kde.org>
* 2000 Dirk Mueller <mueller@kde.org>
* Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
* Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
* (C) 2006 Graham Dennis (graham.dennis@gmail.com)
* (C) 2006 Alexey Proskuryakov (ap@nypop.com)
*
......@@ -33,11 +32,13 @@
#include "Frame.h"
#include "FrameLoader.h"
#include "FrameLoaderClient.h"
#include "GraphicsContext.h"
#include "HTMLDocument.h"
#include "HTMLFrameSetElement.h"
#include "HTMLNames.h"
#include "OverflowEvent.h"
#include "RenderPart.h"
#include "RenderTheme.h"
#include "RenderView.h"
namespace WebCore {
......@@ -893,4 +894,20 @@ void FrameView::updateDashboardRegions()
}
}
void FrameView::updateControlTints()
{
// This is called when control tints are changed from aqua/graphite to clear and vice versa.
// We do a "fake" paint, and when the theme gets a paint call, it can then do an invalidate.
// This is only done if the theme supports control tinting. It's up to the theme and platform
// to define when controls get the tint and to call this function when that changes.
Document* doc = m_frame->document();
if (doc && theme()->supportsControlTints() && m_frame->renderer()) {
doc->updateLayout(); // Ensure layout is up to date.
PlatformGraphicsContext* const noContext = 0;
GraphicsContext context(noContext);
context.setUpdatingControlTints(true);
m_frame->paint(&context, enclosingIntRect(visibleContentRect()));
}
}
}
......@@ -121,6 +121,7 @@ public:
void removeSlowRepaintObject();
void updateDashboardRegions();
void updateControlTints();
void restoreScrollbar();
......
......@@ -506,11 +506,13 @@ void Frame::issueTransposeCommand()
}
const short enableRomanKeyboardsOnly = -23;
void Frame::setSecureKeyboardEntry(bool enable)
void Frame::setUseSecureKeyboardEntry(bool enable)
{
// Caller is responsible for only calling when it's an actual change.
ASSERT(enable != IsSecureEventInputEnabled());
if (enable) {
EnableSecureEventInput();
// FIXME: KeyScript is deprecated in Leopard, we need a new solution for this <rdar://problem/4727607>
// FIXME: Since KeyScript is deprecated in Leopard, we need a new solution for this. <rdar://problem/4727607>
#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
KeyScript(enableRomanKeyboardsOnly);
#endif
......@@ -522,11 +524,6 @@ void Frame::setSecureKeyboardEntry(bool enable)
}
}
bool Frame::isSecureKeyboardEntry()
{
return IsSecureEventInputEnabled();
}
static void convertAttributesToUnderlines(Vector<MarkedTextUnderline>& result, const Range* markedTextRange, NSArray* attributes, NSArray* ranges)
{
int exception = 0;
......
......@@ -23,6 +23,7 @@
#include "RenderTheme.h"
#include "Document.h"
#include "Frame.h"
#include "GraphicsContext.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
......@@ -354,9 +355,12 @@ bool RenderTheme::isEnabled(const RenderObject* o) const
bool RenderTheme::isFocused(const RenderObject* o) const
{
if (!o->element())
Node* node = o->element();
if (!node)
return false;
return o->element() == o->element()->document()->focusedNode();
Document* document = node->document();
Frame* frame = document->frame();
return node == document->focusedNode() && frame && frame->isActive();
}
bool RenderTheme::isPressed(const RenderObject* o) const
......
......@@ -257,10 +257,8 @@ void RenderThemeMac::updateEnabledState(NSCell* cell, const RenderObject* o)
void RenderThemeMac::updateFocusedState(NSCell* cell, const RenderObject* o)
{
// FIXME: Need to add a key window test here, or the element will look
// focused even when in the background.
bool oldFocused = [cell showsFirstResponder];
bool focused = (o->element() && o->document()->focusedNode() == o->element()) && (o->style()->outlineStyleIsAuto());
bool focused = isFocused(o) && o->style()->outlineStyleIsAuto();
if (focused != oldFocused)
[cell setShowsFirstResponder:focused];
}
......@@ -282,6 +280,11 @@ short RenderThemeMac::baselinePosition(const RenderObject* o) const
bool RenderThemeMac::controlSupportsTints(const RenderObject* o) const
{
// An alternate way to implement this would be to get the appropriate cell object
// and call the private _needRedrawOnWindowChangedKeyState method. An advantage of
// that would be that we would match AppKit behavior more closely, but a disadvantage
// would be that we would rely on an AppKit SPI method.
if (!isEnabled(o))
return false;
......
2007-04-16 Darin Adler <darin@apple.com>
Reviewed by John Sullivan.
- fix http://bugs.webkit.org/show_bug.cgi?id=13303
<rdar://problem/5126341> REGRESSION: controls in a background Safari window
maintain active appearance if the address bar has focus (13303)
* WebView/WebHTMLView.mm: (-[WebHTMLView _windowChangedKeyState]):
Added. Calls FrameView::updateControlTints.
2007-04-13 Oliver Hunt <oliver@apple.com>
Reviewed by Adam.
......
......@@ -82,6 +82,7 @@
#import <WebCore/FocusController.h>
#import <WebCore/Frame.h>
#import <WebCore/FrameLoader.h>
#import <WebCore/FrameView.h>
#import <WebCore/HitTestResult.h>
#import <WebCore/Image.h>
#import <WebCore/KeyboardEvent.h>
......@@ -128,6 +129,7 @@ void _NSResetKillRingOperationFlag(void);
- (NSRect)_dirtyRect;
- (void)_setDrawsOwnDescendants:(BOOL)drawsOwnDescendants;
- (void)_propagateDirtyRectsToOpaqueAncestors;
- (void)_windowChangedKeyState;
@end
@interface NSApplication (AppKitSecretsIKnowAbout)
......@@ -4892,6 +4894,18 @@ static DOMRange *unionDOMRanges(DOMRange *a, DOMRange *b)
return [super nextResponder];
}
// Despite its name, this is called at different times than windowDidBecomeKey is.
// It takes into account all the other factors that determine when NSCell draws
// with different tints, so it's the right call to use for control tints. We'd prefer
// to do this with API. <rdar://problem/5136760>
- (void)_windowChangedKeyState
{
if (Frame* frame = core([self _frame]))
if (FrameView* view = frame->view())
view->updateControlTints();
[super _windowChangedKeyState];
}
@end
@implementation WebHTMLView (WebTextSizing)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment