mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-06 08:40:56 +00:00
Bug 516924 - Don't pass our ChildViews to drawWithFrame:inView: when drawing NSCells (e.g. buttons) because that causes Cocoa to think our views have focus rings, so it starts repainting unnecessarily when we invalidate rects near the view boundaries. r=josh
This commit is contained in:
parent
6edbc5a226
commit
8eea03961f
@ -2332,6 +2332,8 @@ NSEvent* gLastDragEvent = nil;
|
|||||||
mGestureState = eGestureState_None;
|
mGestureState = eGestureState_None;
|
||||||
mCumulativeMagnification = 0.0;
|
mCumulativeMagnification = 0.0;
|
||||||
mCumulativeRotation = 0.0;
|
mCumulativeRotation = 0.0;
|
||||||
|
|
||||||
|
[self setFocusRingType:NSFocusRingTypeNone];
|
||||||
}
|
}
|
||||||
|
|
||||||
// register for things we'll take from other applications
|
// register for things we'll take from other applications
|
||||||
@ -2545,21 +2547,6 @@ NSEvent* gLastDragEvent = nil;
|
|||||||
[super viewDidMoveToWindow];
|
[super viewDidMoveToWindow];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Needed to deal with the consequences of calling [NSCell
|
|
||||||
// drawWithFrame:inView:] with a ChildView object as the inView parameter
|
|
||||||
// (this can happen in nsNativeThemeCocoa.mm): drawWithFrame:inView:
|
|
||||||
// expects an NSControl as its inView parameter, and may call [NSControl
|
|
||||||
// currentEditor] on it. But since a ChildView object (like an NSView object)
|
|
||||||
// isn't a control, it doesn't have a "current editor", or a currentEditor
|
|
||||||
// method. So calling currentEditor on it will trigger a Objective-C
|
|
||||||
// "unrecognized selector" exception. To prevent this, ChildView needs its
|
|
||||||
// own currentEditor method. Since a ChildView object never has a "current
|
|
||||||
// editor", it should always return nil.
|
|
||||||
- (NSText*)currentEditor
|
|
||||||
{
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)scrollRect:(NSRect)aRect by:(NSSize)offset
|
- (void)scrollRect:(NSRect)aRect by:(NSSize)offset
|
||||||
{
|
{
|
||||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||||
|
@ -50,6 +50,8 @@
|
|||||||
|
|
||||||
#include "gfxASurface.h"
|
#include "gfxASurface.h"
|
||||||
|
|
||||||
|
@class CellDrawView;
|
||||||
|
|
||||||
class nsNativeThemeCocoa : private nsNativeTheme,
|
class nsNativeThemeCocoa : private nsNativeTheme,
|
||||||
public nsITheme
|
public nsITheme
|
||||||
{
|
{
|
||||||
@ -148,6 +150,7 @@ private:
|
|||||||
NSSearchFieldCell* mSearchFieldCell;
|
NSSearchFieldCell* mSearchFieldCell;
|
||||||
NSPopUpButtonCell* mDropdownCell;
|
NSPopUpButtonCell* mDropdownCell;
|
||||||
NSComboBoxCell* mComboBoxCell;
|
NSComboBoxCell* mComboBoxCell;
|
||||||
|
CellDrawView* mCellDrawView;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // nsNativeThemeCocoa_h_
|
#endif // nsNativeThemeCocoa_h_
|
||||||
|
@ -81,6 +81,34 @@ extern "C" {
|
|||||||
- (int)_realControlTint { return [self controlTint]; }
|
- (int)_realControlTint { return [self controlTint]; }
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
// The purpose of this class is to provide objects that can be used when drawing
|
||||||
|
// NSCells using drawWithFrame:inView: without causing any harm. The only
|
||||||
|
// messages that will be sent to such an object are "isFlipped" and
|
||||||
|
// "currentEditor": isFlipped needs to return YES in order to avoid drawing bugs
|
||||||
|
// on 10.4 (see bug 465069); currentEditor (which isn't even a method of
|
||||||
|
// NSView) will be called when drawing search fields, and we only provide it in
|
||||||
|
// order to prevent "unrecognized selector" exceptions.
|
||||||
|
// There's no need to pass the actual NSView that we're drawing into to
|
||||||
|
// drawWithFrame:inView:. What's more, doing so even causes unnecessary
|
||||||
|
// invalidations as soon as we draw a focusring!
|
||||||
|
@interface CellDrawView : NSView
|
||||||
|
|
||||||
|
@end;
|
||||||
|
|
||||||
|
@implementation CellDrawView
|
||||||
|
|
||||||
|
- (BOOL)isFlipped
|
||||||
|
{
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSText*)currentEditor
|
||||||
|
{
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
static void DrawFocusRing(NSRect rect, float radius)
|
static void DrawFocusRing(NSRect rect, float radius)
|
||||||
{
|
{
|
||||||
NSSetFocusRingStyle(NSFocusRingOnly);
|
NSSetFocusRingStyle(NSFocusRingOnly);
|
||||||
@ -171,18 +199,6 @@ static void InflateControlRect(NSRect* rect, NSControlSize cocoaControlSize, con
|
|||||||
rect->size.height += buttonMargins[bottomMargin] + buttonMargins[topMargin];
|
rect->size.height += buttonMargins[bottomMargin] + buttonMargins[topMargin];
|
||||||
}
|
}
|
||||||
|
|
||||||
static NSView* NativeViewForFrame(nsIFrame* aFrame)
|
|
||||||
{
|
|
||||||
if (!aFrame)
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
nsIWidget* widget = aFrame->GetWindow();
|
|
||||||
if (!widget)
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
return (NSView*)widget->GetNativeData(NS_NATIVE_WIDGET);
|
|
||||||
}
|
|
||||||
|
|
||||||
static NSWindow* NativeWindowForFrame(nsIFrame* aFrame,
|
static NSWindow* NativeWindowForFrame(nsIFrame* aFrame,
|
||||||
nsIWidget** aTopLevelWidget = NULL)
|
nsIWidget** aTopLevelWidget = NULL)
|
||||||
{
|
{
|
||||||
@ -249,6 +265,8 @@ nsNativeThemeCocoa::nsNativeThemeCocoa()
|
|||||||
[mComboBoxCell setEditable:YES];
|
[mComboBoxCell setEditable:YES];
|
||||||
[mComboBoxCell setFocusRingType:NSFocusRingTypeExterior];
|
[mComboBoxCell setFocusRingType:NSFocusRingTypeExterior];
|
||||||
|
|
||||||
|
mCellDrawView = [[CellDrawView alloc] init];
|
||||||
|
|
||||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,6 +280,7 @@ nsNativeThemeCocoa::~nsNativeThemeCocoa()
|
|||||||
[mSearchFieldCell release];
|
[mSearchFieldCell release];
|
||||||
[mDropdownCell release];
|
[mDropdownCell release];
|
||||||
[mComboBoxCell release];
|
[mComboBoxCell release];
|
||||||
|
[mCellDrawView release];
|
||||||
|
|
||||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||||
}
|
}
|
||||||
@ -621,9 +640,7 @@ nsNativeThemeCocoa::DrawCheckboxOrRadio(CGContextRef cgContext, PRBool inCheckbo
|
|||||||
|
|
||||||
DrawCellWithSnapping(cell, cgContext, drawRect,
|
DrawCellWithSnapping(cell, cgContext, drawRect,
|
||||||
inCheckbox ? checkboxSettings : radioSettings,
|
inCheckbox ? checkboxSettings : radioSettings,
|
||||||
VerticalAlignFactor(aFrame),
|
VerticalAlignFactor(aFrame), mCellDrawView, NO);
|
||||||
NativeViewForFrame(aFrame),
|
|
||||||
NO);
|
|
||||||
|
|
||||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||||
}
|
}
|
||||||
@ -664,7 +681,7 @@ nsNativeThemeCocoa::DrawSearchField(CGContextRef cgContext, const HIRect& inBoxR
|
|||||||
[cell setShowsFirstResponder:IsFocused(aFrame)];
|
[cell setShowsFirstResponder:IsFocused(aFrame)];
|
||||||
|
|
||||||
DrawCellWithSnapping(cell, cgContext, inBoxRect, searchFieldSettings,
|
DrawCellWithSnapping(cell, cgContext, inBoxRect, searchFieldSettings,
|
||||||
VerticalAlignFactor(aFrame), NativeViewForFrame(aFrame),
|
VerticalAlignFactor(aFrame), mCellDrawView,
|
||||||
IsFrameRTL(aFrame));
|
IsFrameRTL(aFrame));
|
||||||
|
|
||||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||||
@ -720,12 +737,12 @@ nsNativeThemeCocoa::DrawPushButton(CGContextRef cgContext, const HIRect& inBoxRe
|
|||||||
[mPushButtonCell setBezelStyle:NSShadowlessSquareBezelStyle];
|
[mPushButtonCell setBezelStyle:NSShadowlessSquareBezelStyle];
|
||||||
DrawCellWithScaling(mPushButtonCell, cgContext, inBoxRect, NSRegularControlSize,
|
DrawCellWithScaling(mPushButtonCell, cgContext, inBoxRect, NSRegularControlSize,
|
||||||
NSZeroSize, NSMakeSize(14, 0), NULL,
|
NSZeroSize, NSMakeSize(14, 0), NULL,
|
||||||
NativeViewForFrame(aFrame), IsFrameRTL(aFrame));
|
mCellDrawView, IsFrameRTL(aFrame));
|
||||||
} else {
|
} else {
|
||||||
[mPushButtonCell setBezelStyle:NSRoundedBezelStyle];
|
[mPushButtonCell setBezelStyle:NSRoundedBezelStyle];
|
||||||
|
|
||||||
DrawCellWithSnapping(mPushButtonCell, cgContext, inBoxRect, pushButtonSettings,
|
DrawCellWithSnapping(mPushButtonCell, cgContext, inBoxRect, pushButtonSettings,
|
||||||
0.5f, NativeViewForFrame(aFrame), IsFrameRTL(aFrame), 1.0f);
|
0.5f, mCellDrawView, IsFrameRTL(aFrame), 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DRAW_IN_FRAME_DEBUG
|
#if DRAW_IN_FRAME_DEBUG
|
||||||
@ -882,7 +899,7 @@ nsNativeThemeCocoa::DrawDropdown(CGContextRef cgContext, const HIRect& inBoxRect
|
|||||||
|
|
||||||
const CellRenderSettings& settings = isEditable ? editableMenulistSettings : dropdownSettings;
|
const CellRenderSettings& settings = isEditable ? editableMenulistSettings : dropdownSettings;
|
||||||
DrawCellWithSnapping(cell, cgContext, inBoxRect, settings,
|
DrawCellWithSnapping(cell, cgContext, inBoxRect, settings,
|
||||||
0.5f, NativeViewForFrame(aFrame), IsFrameRTL(aFrame));
|
0.5f, mCellDrawView, IsFrameRTL(aFrame));
|
||||||
|
|
||||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user