[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.21-584-g1e41756

eric at webkit.org eric at webkit.org
Fri Feb 26 22:16:32 UTC 2010


The following commit has been merged in the webkit-1.1 branch:
commit 4f953638a6e23d9f9d94ad04f5b3e48b5649b53c
Author: eric at webkit.org <eric at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Feb 10 03:25:43 2010 +0000

    2010-02-09  Avi Drissman  <avi at chromium.org>
    
            Reviewed by Timothy Hatcher.
    
            [Chromium] RenderTheme does not draw focus rings on SL for checkboxes, radio buttons
            https://bugs.webkit.org/show_bug.cgi?id=34544
    
            Covered by layout tests when run on SL.
    
            * platform/chromium/ThemeChromiumMac.mm:
            (-[TCMVisibleView _focusRingVisibleRect]):
            (-[TCMVisibleView _focusRingClipAncestor]):
            (FocusIndicationFix::currentOSHasSetFocusRingStyleInBitmapBug):
            (FocusIndicationFix::swizzleFocusView):
            (FocusIndicationFix::ScopedFixer::ScopedFixer):
            (FocusIndicationFix::ScopedFixer::~ScopedFixer):
            (+[NSView TCMInterposing_focusView]):
            (WebCore::paintCheckbox):
            (WebCore::paintRadio):
            (WebCore::paintButton):
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@54582 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index d0f88f9..9637902 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,24 @@
+2010-02-09  Avi Drissman  <avi at chromium.org>
+
+        Reviewed by Timothy Hatcher.
+
+        [Chromium] RenderTheme does not draw focus rings on SL for checkboxes, radio buttons
+        https://bugs.webkit.org/show_bug.cgi?id=34544
+
+        Covered by layout tests when run on SL.
+
+        * platform/chromium/ThemeChromiumMac.mm:
+        (-[TCMVisibleView _focusRingVisibleRect]):
+        (-[TCMVisibleView _focusRingClipAncestor]):
+        (FocusIndicationFix::currentOSHasSetFocusRingStyleInBitmapBug):
+        (FocusIndicationFix::swizzleFocusView):
+        (FocusIndicationFix::ScopedFixer::ScopedFixer):
+        (FocusIndicationFix::ScopedFixer::~ScopedFixer):
+        (+[NSView TCMInterposing_focusView]):
+        (WebCore::paintCheckbox):
+        (WebCore::paintRadio):
+        (WebCore::paintButton):
+
 2010-02-09  Anton Muhin  <antonm at chromium.org>
 
         Reviewed by Nate Chapin.
diff --git a/WebCore/platform/chromium/ThemeChromiumMac.mm b/WebCore/platform/chromium/ThemeChromiumMac.mm
index 1c14207..15a8382 100644
--- a/WebCore/platform/chromium/ThemeChromiumMac.mm
+++ b/WebCore/platform/chromium/ThemeChromiumMac.mm
@@ -33,6 +33,7 @@
 #import "ScrollView.h"
 #import "WebCoreSystemInterface.h"
 #include <wtf/StdLibExtras.h>
+#import <objc/runtime.h>
 
 using namespace std;
 
@@ -47,6 +48,8 @@ using namespace std;
 //   rendering.
 // - In updateStates() the code to update the cells' inactive state.
 // - In paintButton() the code to save/restore the window's default button cell.
+// - The Snow Leopard focus ring bug fix and its use around every call to
+//   -[NSButtonCell drawWithFrame:inView:].
 //
 // For all other differences, if it was introduced in this file, then the
 // maintainer forgot to include it in the list; otherwise it is an update that
@@ -54,6 +57,129 @@ using namespace std;
 
 // FIXME: Default buttons really should be more like push buttons and not like buttons.
 
+// --- START fix for Snow Leopard focus ring bug ---
+
+// There is a bug in the Cocoa focus ring drawing code. The code calls +[NSView
+// focusView] (to get the currently focused view) and then calls an NSRect-
+// returning method on that view to obtain a clipping rect. However, if there is
+// no focused view (as there won't be if the destination is a context), the rect
+// returned from the method invocation on nil is garbage.
+//
+// The garbage fortunately does not clip the focus ring on Leopard, but
+// unfortunately does so on Snow Leopard. Therefore, if a runtime test shows
+// that focus ring drawing fails, we swizzle NSView to ensure it returns a valid
+// view with a valid clipping rectangle.
+//
+// FIXME: After the referenced bug is fixed on all supported platforms, remove
+// this code.
+//
+// References:
+//  <http://crbug.com/27493>
+//  <rdar://problem/7604051> (<http://openradar.appspot.com/7604051>)
+
+ at interface TCMVisibleView : NSView
+
+ at end
+
+ at implementation TCMVisibleView
+
+- (struct CGRect)_focusRingVisibleRect
+{
+    return CGRectZero;
+}
+
+- (id)_focusRingClipAncestor
+{
+    return self;
+}
+
+ at end
+
+ at interface NSView (TCMInterposing)
++ (NSView *)TCMInterposing_focusView;
+ at end
+
+namespace FocusIndicationFix {
+
+bool currentOSHasSetFocusRingStyleInBitmapBug()
+{
+    UInt32 pixel = 0;
+    UInt32* pixelPlane = &pixel;
+    UInt32** pixelPlanes = &pixelPlane;
+    NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:(UInt8**)pixelPlanes
+                                                                       pixelsWide:1
+                                                                       pixelsHigh:1
+                                                                    bitsPerSample:8
+                                                                  samplesPerPixel:4
+                                                                         hasAlpha:YES
+                                                                         isPlanar:NO
+                                                                   colorSpaceName:NSCalibratedRGBColorSpace
+                                                                     bitmapFormat:NSAlphaFirstBitmapFormat
+                                                                      bytesPerRow:4
+                                                                     bitsPerPixel:32];
+    [NSGraphicsContext saveGraphicsState];
+    [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:bitmap]];
+    NSSetFocusRingStyle(NSFocusRingOnly);
+    NSRectFill(NSMakeRect(0, 0, 1, 1));
+    [NSGraphicsContext restoreGraphicsState];
+    [bitmap release];
+
+    return !pixel;
+}
+
+bool swizzleFocusView()
+{
+    if (!currentOSHasSetFocusRingStyleInBitmapBug())
+        return false;
+
+    Class nsview = [NSView class];
+    Method m1 = class_getClassMethod(nsview, @selector(focusView));
+    Method m2 = class_getClassMethod(nsview, @selector(TCMInterposing_focusView));
+    if (m1 && m2) {
+        method_exchangeImplementations(m1, m2);
+        return true;
+    }
+
+    return false;
+}
+
+static bool interpose = false;
+
+// A class to restrict the amount of time spent messing with interposing. It
+// only stacks one-deep.
+class ScopedFixer {
+public:
+    ScopedFixer()
+    {
+        static bool swizzled = swizzleFocusView();
+        interpose = swizzled;
+    }
+
+    ~ScopedFixer()
+    {
+        interpose = false;
+    }
+};
+
+}  // namespace FocusIndicationFix
+
+ at implementation NSView (TCMInterposing)
+
++ (NSView *)TCMInterposing_focusView
+{
+    NSView *view = [self TCMInterposing_focusView];  // call original (was swizzled)
+    if (!view && FocusIndicationFix::interpose) {
+        static TCMVisibleView* fixedView = [[TCMVisibleView alloc] init];
+        view = fixedView;
+    }
+
+    return view;
+}
+
+ at end
+
+// --- END fix for Snow Leopard focus ring bug ---
+
 namespace WebCore {
 
 // Pick up utility function from RenderThemeChromiumMac.
@@ -241,7 +367,10 @@ static void paintCheckbox(ControlStates states, GraphicsContext* context, const
         context->translate(-inflatedRect.x(), -inflatedRect.y());
     }
 
-    [checkboxCell drawWithFrame:NSRect(inflatedRect) inView:FlippedView()];
+    {
+        FocusIndicationFix::ScopedFixer fix;
+        [checkboxCell drawWithFrame:NSRect(inflatedRect) inView:FlippedView()];
+    }
     [checkboxCell setControlView:nil];
 
     context->restore();
@@ -319,7 +448,10 @@ static void paintRadio(ControlStates states, GraphicsContext* context, const Int
     }
 
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [radioCell drawWithFrame:NSRect(inflatedRect) inView:FlippedView()];
+    {
+        FocusIndicationFix::ScopedFixer fix;
+        [radioCell drawWithFrame:NSRect(inflatedRect) inView:FlippedView()];
+    }
     [radioCell setControlView:nil];
     END_BLOCK_OBJC_EXCEPTIONS
 
@@ -429,7 +561,10 @@ static void paintButton(ControlPart part, ControlStates states, GraphicsContext*
         }
     }
 
-    [buttonCell drawWithFrame:NSRect(inflatedRect) inView:FlippedView()];
+    {
+        FocusIndicationFix::ScopedFixer fix;
+        [buttonCell drawWithFrame:NSRect(inflatedRect) inView:FlippedView()];
+    }
     [buttonCell setControlView:nil];
 
     END_BLOCK_OBJC_EXCEPTIONS

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list