зеркало из https://github.com/mozilla/pjs.git
Fix bug 277923: crash on scrolling in Camino on page load, because we destroy the scrollbars while in a native scrollbar tracking loop. Fixed by posting a fake mouseup event when we detect that the scrollbar is going away. r=pinkerton. Only affects Camino, so no need for approval.
Also remove the USE_OPAQUE_VIEWS #ifdefs from nsChildView, and add an explanatory comment now that we understand the issue better.
This commit is contained in:
Родитель
54d32d1a6b
Коммит
5c40815762
|
@ -67,8 +67,6 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "nsCursorManager.h"
|
#include "nsCursorManager.h"
|
||||||
|
|
||||||
// #define USE_OPAQUE_VIEWS 1
|
|
||||||
|
|
||||||
#define NSAppKitVersionNumber10_2 663
|
#define NSAppKitVersionNumber10_2 663
|
||||||
|
|
||||||
// category of NSView methods to quiet warnings
|
// category of NSView methods to quiet warnings
|
||||||
|
@ -2262,6 +2260,11 @@ nsChildView::Idle()
|
||||||
// an empty fallback port.
|
// an empty fallback port.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSString*)description
|
||||||
|
{
|
||||||
|
return [NSString stringWithFormat:@"ChildView %p, gecko child %p, frame %@", self, mGeckoChild, NSStringFromRect([self frame])];
|
||||||
|
}
|
||||||
|
|
||||||
// Find the nearest scrollable view for this ChildView
|
// Find the nearest scrollable view for this ChildView
|
||||||
// (recall that views are not refcounted)
|
// (recall that views are not refcounted)
|
||||||
- (nsIScrollableView*) getScrollableView
|
- (nsIScrollableView*) getScrollableView
|
||||||
|
@ -2385,16 +2388,17 @@ nsChildView::Idle()
|
||||||
|
|
||||||
// -isOpaque
|
// -isOpaque
|
||||||
//
|
//
|
||||||
// XXXdwh. Quickdraw views are transparent by default. Since Gecko does its own blending if/when
|
// NSQuickDrawViews do not correctly update if opaque, because of a known incompatibility
|
||||||
// opacity is specified, we would like to optimize here by turning off the transparency of the view.
|
// between the way that NSQuickDrawView is implemented, and the NSWindow update mechanism.
|
||||||
// But we can't. :(
|
// This is unlikely to change in future.
|
||||||
|
//
|
||||||
|
// It's unfortunate, because it's expensive to redraw every parent view when updating
|
||||||
|
// a portion of any given NSQDView. However, there is no efficient workaround. See
|
||||||
|
// bug 166932.
|
||||||
|
//
|
||||||
- (BOOL)isOpaque
|
- (BOOL)isOpaque
|
||||||
{
|
{
|
||||||
#ifdef USE_OPAQUE_VIEWS
|
|
||||||
return YES;
|
|
||||||
#else
|
|
||||||
return mIsPluginView;
|
return mIsPluginView;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)setIsPluginView:(BOOL)aIsPlugin
|
-(void)setIsPluginView:(BOOL)aIsPlugin
|
||||||
|
@ -2487,9 +2491,6 @@ nsChildView::Idle()
|
||||||
ConvertCocoaToGeckoRect(aRect, r);
|
ConvertCocoaToGeckoRect(aRect, r);
|
||||||
nsCOMPtr<nsIRenderingContext> rendContext = getter_AddRefs(mGeckoChild->GetRenderingContext());
|
nsCOMPtr<nsIRenderingContext> rendContext = getter_AddRefs(mGeckoChild->GetRenderingContext());
|
||||||
mGeckoChild->UpdateWidget(r, rendContext);
|
mGeckoChild->UpdateWidget(r, rendContext);
|
||||||
#ifdef USE_OPAQUE_VIEWS
|
|
||||||
[self flushRect:aRect];
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
// If >10.3, only paint the sub-rects that need it. This avoids the
|
// If >10.3, only paint the sub-rects that need it. This avoids the
|
||||||
// nasty coalesced updates that result in big white areas.
|
// nasty coalesced updates that result in big white areas.
|
||||||
|
@ -2502,9 +2503,6 @@ nsChildView::Idle()
|
||||||
ConvertCocoaToGeckoRect(rects[i], r);
|
ConvertCocoaToGeckoRect(rects[i], r);
|
||||||
nsCOMPtr<nsIRenderingContext> rendContext = getter_AddRefs(mGeckoChild->GetRenderingContext());
|
nsCOMPtr<nsIRenderingContext> rendContext = getter_AddRefs(mGeckoChild->GetRenderingContext());
|
||||||
mGeckoChild->UpdateWidget(r, rendContext);
|
mGeckoChild->UpdateWidget(r, rendContext);
|
||||||
#ifdef USE_OPAQUE_VIEWS
|
|
||||||
[self flushRect:rects[i]];
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,8 @@ public:
|
||||||
nsNativeScrollbar();
|
nsNativeScrollbar();
|
||||||
virtual ~nsNativeScrollbar();
|
virtual ~nsNativeScrollbar();
|
||||||
|
|
||||||
|
NS_IMETHOD Destroy();
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
NS_DECL_NSINATIVESCROLLBAR
|
NS_DECL_NSINATIVESCROLLBAR
|
||||||
|
|
||||||
|
@ -110,6 +112,9 @@ private:
|
||||||
// the nsNativeScrollbar that created this view. It retains this NSView, so
|
// the nsNativeScrollbar that created this view. It retains this NSView, so
|
||||||
// the link back to it must be weak. [WEAK]
|
// the link back to it must be weak. [WEAK]
|
||||||
nsNativeScrollbar* mGeckoChild;
|
nsNativeScrollbar* mGeckoChild;
|
||||||
|
|
||||||
|
// YES when we're in a tracking loop
|
||||||
|
BOOL mInTracking;
|
||||||
}
|
}
|
||||||
|
|
||||||
// default initializer
|
// default initializer
|
||||||
|
@ -117,6 +122,8 @@ private:
|
||||||
// overridden parent class initializer
|
// overridden parent class initializer
|
||||||
- (id)initWithFrame:(NSRect)frameRect;
|
- (id)initWithFrame:(NSRect)frameRect;
|
||||||
|
|
||||||
|
- (void)scrollbarDestroyed;
|
||||||
|
|
||||||
- (IBAction)scroll:(NSScroller*)sender;
|
- (IBAction)scroll:(NSScroller*)sender;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -76,6 +76,12 @@ nsNativeScrollbar::~nsNativeScrollbar()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsNativeScrollbar::Destroy()
|
||||||
|
{
|
||||||
|
[mView scrollbarDestroyed];
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// CreateCocoaView
|
// CreateCocoaView
|
||||||
|
@ -105,7 +111,7 @@ nsNativeScrollbar::GetQuickDrawPort ( )
|
||||||
// pray we're always a child of a NSQuickDrawView
|
// pray we're always a child of a NSQuickDrawView
|
||||||
if ( [mParentView isKindOfClass: [ChildView class]] ) {
|
if ( [mParentView isKindOfClass: [ChildView class]] ) {
|
||||||
NSQuickDrawView* parent = NS_STATIC_CAST(NSQuickDrawView*, mParentView);
|
NSQuickDrawView* parent = NS_STATIC_CAST(NSQuickDrawView*, mParentView);
|
||||||
return [parent qdPort];
|
return (GrafPtr)[parent qdPort];
|
||||||
}
|
}
|
||||||
|
|
||||||
return nsnull;
|
return nsnull;
|
||||||
|
@ -531,15 +537,15 @@ nsNativeScrollbar::IsEnabled(PRBool *aState)
|
||||||
//
|
//
|
||||||
- (id)initWithFrame:(NSRect)frameRect geckoChild:(nsNativeScrollbar*)inChild
|
- (id)initWithFrame:(NSRect)frameRect geckoChild:(nsNativeScrollbar*)inChild
|
||||||
{
|
{
|
||||||
[super initWithFrame:frameRect];
|
if ((self = [super initWithFrame:frameRect]))
|
||||||
|
{
|
||||||
NS_ASSERTION(inChild, "Need to provide a tether between this and a nsChildView class");
|
NS_ASSERTION(inChild, "Need to provide a tether between this and a nsChildView class");
|
||||||
mGeckoChild = inChild;
|
mGeckoChild = inChild;
|
||||||
|
|
||||||
// make ourselves the target of the scroll and set the action message
|
// make ourselves the target of the scroll and set the action message
|
||||||
[self setTarget:self];
|
[self setTarget:self];
|
||||||
[self setAction:@selector(scroll:)];
|
[self setAction:@selector(scroll:)];
|
||||||
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -552,7 +558,10 @@ nsNativeScrollbar::IsEnabled(PRBool *aState)
|
||||||
- (id)initWithFrame:(NSRect)frameRect
|
- (id)initWithFrame:(NSRect)frameRect
|
||||||
{
|
{
|
||||||
NS_WARNING("You're calling the wrong initializer. You really want -initWithFrame:geckoChild");
|
NS_WARNING("You're calling the wrong initializer. You really want -initWithFrame:geckoChild");
|
||||||
return [self initWithFrame:frameRect geckoChild:nsnull];
|
if ((self = [self initWithFrame:frameRect geckoChild:nsnull]))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -601,6 +610,34 @@ nsNativeScrollbar::IsEnabled(PRBool *aState)
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// -scrollbarDestroyed
|
||||||
|
//
|
||||||
|
// the gecko nsNativeScrollbar is being destroyed.
|
||||||
|
//
|
||||||
|
- (void)scrollbarDestroyed
|
||||||
|
{
|
||||||
|
mGeckoChild = nsnull;
|
||||||
|
|
||||||
|
if (mInTracking)
|
||||||
|
{
|
||||||
|
// To get out of the NSScroller tracking loop, we post a fake mouseup event.
|
||||||
|
// We have to do this here, before we are ripped out of the view hierarchy.
|
||||||
|
[NSApp postEvent:[NSEvent mouseEventWithType:NSLeftMouseUp
|
||||||
|
location:[NSEvent mouseLocation]
|
||||||
|
modifierFlags:0
|
||||||
|
timestamp:[[NSApp currentEvent] timestamp]
|
||||||
|
windowNumber:[[self window] windowNumber]
|
||||||
|
context:NULL
|
||||||
|
eventNumber:0
|
||||||
|
clickCount:0
|
||||||
|
pressure:1.0]
|
||||||
|
atStart:YES];
|
||||||
|
|
||||||
|
mInTracking = NO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// -scroll
|
// -scroll
|
||||||
|
@ -616,5 +653,51 @@ nsNativeScrollbar::IsEnabled(PRBool *aState)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// -trackKnob:
|
||||||
|
//
|
||||||
|
// overridden to toggle mInTracking on and off
|
||||||
|
//
|
||||||
|
- (void)trackKnob:(NSEvent *)theEvent
|
||||||
|
{
|
||||||
|
mInTracking = YES;
|
||||||
|
NS_DURING // be sure we always turn mInTracking off.
|
||||||
|
[super trackKnob:theEvent];
|
||||||
|
NS_HANDLER
|
||||||
|
NS_ENDHANDLER
|
||||||
|
mInTracking = NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// -trackScrollButtons:
|
||||||
|
//
|
||||||
|
// overridden to toggle mInTracking on and off
|
||||||
|
//
|
||||||
|
- (void)trackScrollButtons:(NSEvent *)theEvent
|
||||||
|
{
|
||||||
|
mInTracking = YES;
|
||||||
|
NS_DURING // be sure we always turn mInTracking off.
|
||||||
|
[super trackScrollButtons:theEvent];
|
||||||
|
NS_HANDLER
|
||||||
|
NS_ENDHANDLER
|
||||||
|
mInTracking = NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// -trackPagingArea:
|
||||||
|
//
|
||||||
|
// this method is not documented, but was seen in sampling. We have
|
||||||
|
// to override it to toggle mInTracking.
|
||||||
|
//
|
||||||
|
- (void)trackPagingArea:(id)theEvent
|
||||||
|
{
|
||||||
|
mInTracking = YES;
|
||||||
|
NS_DURING // be sure we always turn mInTracking off.
|
||||||
|
[super trackPagingArea:theEvent];
|
||||||
|
NS_HANDLER
|
||||||
|
NS_ENDHANDLER
|
||||||
|
mInTracking = NO;
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче