Widget part of fix for bug 297343: avoid re-entrant -[NSWindow makeKeyAndOrderFront:] calls by postponing the focus and activate calls into Gecko so that they get called the next time through the event loop, when window visibility and key status are correct. This allows embedder code that implements to nsIEmbeddingWindow::SetFocus() to check those and avoid re-entrant/redundant makeKeyAndOrderFront: calls. r=mento. Only affects Camino.

This commit is contained in:
smfr%smfr.org 2005-09-30 00:59:29 +00:00
parent c3a4817fe8
commit 4361539600
6 changed files with 177 additions and 127 deletions

View File

@ -52,20 +52,26 @@ class nsIWidget;
@protocol mozView
// access the nsIWidget associated with this view. DOES NOT ADDREF.
- (nsIWidget*) widget;
- (nsIWidget*)widget;
// access the native cocoa window (NSWindow) that this view
// is in. It's necessary for a gecko NSView to keep track of the
// window because |-window| returns nil when the view has been
// removed from the view hierarchy (as is the case when it's hidden,
// since you can't just hide a view, that would make too much sense).
- (NSWindow*) getNativeWindow;
- (void) setNativeWindow: (NSWindow*)aWindow;
- (NSWindow*)getNativeWindow;
- (void)setNativeWindow:(NSWindow*)aWindow;
// return a context menu for this view
- (NSMenu*)getContextMenu;
// calls setNeedsDisplay, with the rect in inRectValue if supplied.
// Allows callers to do a delayed invalidate using
// -performSelector:withObject:afterDelay:
- (void)setNeedsDisplayWithValue:(NSValue*)inRectValue;
// called when our corresponding Gecko view goes away
- (void)widgetDestroyed;
@end

View File

@ -34,8 +34,9 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef Window_h__
#define Window_h__
#ifndef nsChildView_h__
#define nsChildView_h__
#import "mozView.h"
@ -71,6 +72,7 @@ class nsChildView;
@interface ChildView : NSQuickDrawView<mozView, NSTextInput>
{
@private
NSWindow* mWindow; // shortcut to the top window, [WEAK]
// the nsChildView that created the view. It retains this NSView, so
@ -131,6 +133,14 @@ public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIEVENTSINK
// nsIKBStateControl interface
NS_IMETHOD ResetInputState();
NS_IMETHOD SetIMEOpenState(PRBool aState);
NS_IMETHOD GetIMEOpenState(PRBool* aState);
NS_IMETHOD SetIMEEnabled(PRBool aState);
NS_IMETHOD GetIMEEnabled(PRBool* aState);
NS_IMETHOD CancelIMEComposition();
// nsIWidget interface
NS_IMETHOD Create(nsIWidget *aParent,
@ -202,10 +212,10 @@ public:
NS_IMETHOD DispatchEvent(nsGUIEvent* event, nsEventStatus & aStatus);
virtual PRBool DispatchMouseEvent(nsMouseEvent &aEvent);
virtual void StartDraw(nsIRenderingContext* aRenderingContext = nsnull);
virtual void EndDraw();
NS_IMETHOD Update();
virtual void UpdateWidget(nsRect& aRect, nsIRenderingContext* aContext);
virtual void StartDraw(nsIRenderingContext* aRenderingContext = nsnull);
virtual void EndDraw();
NS_IMETHOD Update();
virtual void UpdateWidget(nsRect& aRect, nsIRenderingContext* aContext);
virtual void ConvertToDeviceCoordinates(nscoord &aX, nscoord &aY);
void LocalToWindowCoordinate(nsPoint& aPoint) { ConvertToDeviceCoordinates(aPoint.x, aPoint.y); }
@ -219,6 +229,7 @@ public:
NS_IMETHOD SetPreferredSize(PRInt32 aWidth, PRInt32 aHeight);
NS_IMETHOD SetCursor(nsCursor aCursor);
NS_IMETHOD SetCursor(imgIContainer* aCursor, PRUint32 aHotspotX, PRUint32 aHotspotY);
NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener, PRBool aDoCapture, PRBool aConsumeRollupEvent);
NS_IMETHOD SetTitle(const nsAString& title);
@ -247,48 +258,34 @@ public:
void LiveResizeStarted();
void LiveResizeEnded();
public:
// nsIKBStateControl interface
NS_IMETHOD ResetInputState();
NS_IMETHOD SetIMEOpenState(PRBool aState);
NS_IMETHOD GetIMEOpenState(PRBool* aState);
NS_IMETHOD SetIMEEnabled(PRBool aState);
NS_IMETHOD GetIMEEnabled(PRBool* aState);
NS_IMETHOD CancelIMEComposition();
protected:
PRBool ReportDestroyEvent();
PRBool ReportMoveEvent();
PRBool ReportSizeEvent();
PRBool ReportDestroyEvent();
PRBool ReportMoveEvent();
PRBool ReportSizeEvent();
NS_IMETHOD CalcOffset(PRInt32 &aX,PRInt32 &aY);
virtual PRBool OnPaint(nsPaintEvent & aEvent);
// our own impl of ::ScrollRect() that uses CopyBits so that it looks good. On
// Carbon, this just calls ::ScrollWindowRect()
void ScrollBits ( Rect & foo, PRInt32 inLeftDelta, PRInt32 inTopDelta ) ;
virtual PRBool OnPaint(nsPaintEvent & aEvent);
// override to create different kinds of child views. Autoreleases, so
// caller must retain.
virtual NSView* CreateCocoaView(NSRect inFrame);
void TearDownView();
virtual NSView* CreateCocoaView(NSRect inFrame);
void TearDownView();
// Find a quickdraw port in which to draw (needed by GFX until it
// is converted to Cocoa). This MUST be overridden if CreateCocoaView()
// does not create something that inherits from NSQuickDrawView!
virtual GrafPtr GetQuickDrawPort() ;
virtual GrafPtr GetQuickDrawPort(); // gets plugin port or view's port
/* protected: */
public:
#if DEBUG
const char* gInstanceClassName;
#endif
// return qdPort for a focussed ChildView, and null otherwise
GrafPtr GetChildViewQuickDrawPort();
id mView; // my parallel cocoa view, [STRONG]
protected:
NSView* mParentView;
NSView<mozView>* mView; // my parallel cocoa view (ChildView or NativeScrollbarView), [STRONG]
NSView<mozView>* mParentView;
nsIWidget* mParentWidget;
nsIFontMetrics* mFontMetrics;
@ -312,12 +309,4 @@ public:
};
#if DEBUG
#define WIDGET_SET_CLASSNAME(n) gInstanceClassName = (n)
#else
#define WIDGET_SET_CLASSNAME(n)
#endif
#endif // Window_h__
#endif // nsChildView_h__

View File

@ -78,6 +78,9 @@
@interface ChildView(Private)
// sets up our view, attaching it to its owning gecko view
- (id)initWithFrame:(NSRect)inFrame geckoChild:(nsChildView*)inChild eventSink:(nsIEventSink*)inSink;
// sends gecko an ime composition event
- (nsRect) sendCompositionEvent:(PRInt32)aEventType;
@ -88,9 +91,6 @@
markedRange:(NSRange)markRange
doCommit:(BOOL)doCommit;
// sets up our view, attaching it to its owning gecko view
- (id)initWithFrame:(NSRect)inFrame geckoChild:(nsChildView*)inChild eventSink:(nsIEventSink*)inSink;
// convert from one event system to the other for event dispatching
- (void) convertEvent:(NSEvent*)inEvent message:(PRInt32)inMsg toGeckoEvent:(nsInputEvent*)outGeckoEvent;
@ -111,6 +111,9 @@
- (void)flushRect:(NSRect)inRect;
- (BOOL)isRectObscuredBySubview:(NSRect)inRect;
- (void)sendActivateEvent;
- (void)sendDeactivateEvent;
#if USE_CLICK_HOLD_CONTEXTMENU
// called on a timer two seconds after a mouse down to see if we should display
// a context menu (click-hold)
@ -300,8 +303,6 @@ nsChildView::nsChildView() : nsBaseWidget()
, mPluginPort(nsnull)
, mVisRgn(nsnull)
{
WIDGET_SET_CLASSNAME("nsChildView");
SetBackgroundColor(NS_RGB(255, 255, 255));
SetForegroundColor(NS_RGB(0, 0, 0));
}
@ -432,7 +433,7 @@ nsresult nsChildView::StandardCreate(nsIWidget *aParent,
// if this is a ChildView, make sure that our per-window data
// is set up
if ([mView isKindOfClass:[ChildView class]])
[mView ensureWindowData];
[(ChildView*)mView ensureWindowData];
return NS_OK;
}
@ -520,6 +521,8 @@ NS_IMETHODIMP nsChildView::Destroy()
return NS_OK;
mDestroyCalled = PR_TRUE;
[mView widgetDestroyed];
nsBaseWidget::OnDestroy();
nsBaseWidget::Destroy();
@ -573,18 +576,19 @@ void* nsChildView::GetNativeData(PRUint32 aDataType)
break;
case NS_NATIVE_GRAPHIC: // quickdraw port
// XXX this can return NULL if we are not the focused view
retVal = [mView qdPort];
// XXX qdPort is invalid if we have not locked focus
retVal = GetChildViewQuickDrawPort();
break;
case NS_NATIVE_REGION:
{
if (!mVisRgn)
mVisRgn = ::NewRgn();
GrafPtr port = (GrafPtr)[mView qdPort];
if (port && mVisRgn)
::GetPortVisibleRegion(port, mVisRgn);
// XXX qdPort is invalid if we have not locked focus
GrafPtr grafPort = GetChildViewQuickDrawPort();
if (grafPort && mVisRgn)
::GetPortVisibleRegion(grafPort, mVisRgn);
retVal = (void*)mVisRgn;
break;
}
@ -608,7 +612,8 @@ void* nsChildView::GetNativeData(PRUint32 aDataType)
if (mPluginPort == nsnull)
{
mPluginPort = new nsPluginPort;
[mView setIsPluginView: YES];
if ([mView isKindOfClass:[ChildView class]])
[(ChildView*)mView setIsPluginView: YES];
}
NSWindow* window = [mView getNativeWindow];
@ -717,21 +722,6 @@ NS_IMETHODIMP nsChildView::IsEnabled(PRBool *aState)
return NS_OK;
}
static Boolean WeAreFrontProcess()
{
ProcessSerialNumber thisPSN;
ProcessSerialNumber frontPSN;
(void)::GetCurrentProcess(&thisPSN);
if (::GetFrontProcess(&frontPSN) == noErr)
{
if ((frontPSN.highLongOfPSN == thisPSN.highLongOfPSN) &&
(frontPSN.lowLongOfPSN == thisPSN.lowLongOfPSN))
return true;
}
return false;
}
//-------------------------------------------------------------------------
//
// Set the focus on this component
@ -810,12 +800,20 @@ nsIMenuBar* nsChildView::GetMenuBar()
//
// Override to set the cursor on the mac
//
NS_METHOD nsChildView::SetCursor(nsCursor aCursor)
NS_IMETHODIMP nsChildView::SetCursor(nsCursor aCursor)
{
nsBaseWidget::SetCursor(aCursor);
[[nsCursorManager sharedInstance] setCursor: aCursor];
return NS_OK;
} // nsChildView::SetCursor
}
// implement to fix "hidden virtual function" warning
NS_IMETHODIMP nsChildView::SetCursor(imgIContainer* aCursor,
PRUint32 aHotspotX, PRUint32 aHotspotY)
{
return nsBaseWidget::SetCursor(aCursor, aHotspotX, aHotspotY);
}
#pragma mark -
//-------------------------------------------------------------------------
@ -1418,7 +1416,9 @@ nsChildView::UpdateWidget(nsRect& aRect, nsIRenderingContext* aContext)
// For updating widgets, we _always_ want to use the NSQuickDrawView's port,
// since that's the correct port for gecko to use to make rendering contexts.
// The plugin is the only thing that uses the plugin port.
GrafPtr curPort = (GrafPtr)[mView qdPort];
GrafPtr curPort = GetChildViewQuickDrawPort();
if (!curPort) return;
StPortSetter port(curPort);
// initialize the paint event
@ -1880,7 +1880,7 @@ NS_IMETHODIMP nsChildView::ScreenToWidget(const nsRect& aGlobalRect, nsRect& aLo
* @param nscoord -- Y coordinate to convert
* @return NONE
*/
void nsChildView::ConvertToDeviceCoordinates(nscoord &aX, nscoord &aY)
void nsChildView::ConvertToDeviceCoordinates(nscoord &aX, nscoord &aY)
{
PRInt32 offX = 0, offY = 0;
this->CalcOffset(offX,offY);
@ -2001,8 +2001,17 @@ nsChildView::GetQuickDrawPort()
{
if (mPluginPort)
return mPluginPort->port;
else
return (GrafPtr) [mView qdPort];
return GetChildViewQuickDrawPort();
}
GrafPtr
nsChildView::GetChildViewQuickDrawPort()
{
if ([mView isKindOfClass:[ChildView class]])
return (GrafPtr)[(ChildView*)mView qdPort];
return nsnull;
}
#pragma mark -
@ -2036,7 +2045,7 @@ nsChildView::DragEvent(PRUint32 aMessage, PRInt16 aMouseGlobalX, PRInt16 aMouseG
// ensure that this is going to a ChildView (not something else like a
// scrollbar). I think it's safe to just bail at this point if it's not
// what we expect it to be
if ( ![mView isKindOfClass:[ChildView class]] ) {
if (![mView isKindOfClass:[ChildView class]]) {
*_retval = PR_FALSE;
return NS_OK;
}
@ -2060,13 +2069,12 @@ nsChildView::DragEvent(PRUint32 aMessage, PRInt16 aMouseGlobalX, PRInt16 aMouseG
// convert to window coords
dragLoc = [[mView window] convertScreenToBase:dragLoc];
// and fill in the event
[mView convertLocation:dragLoc message:aMessage modifiers:0 toGeckoEvent:&geckoEvent];
[(ChildView*)mView convertLocation:dragLoc message:aMessage modifiers:0 toGeckoEvent:&geckoEvent];
DispatchWindowEvent(geckoEvent);
// we handled the event
*_retval = PR_TRUE;
return NS_OK;
}
@ -2136,6 +2144,12 @@ nsChildView::Idle()
SetPort(NULL); // Bullet-proof against future changes in NSQDView
}
- (void)widgetDestroyed
{
mGeckoChild = nsnull;
mEventSink = nsnull;
}
//
// -widget
// mozView method
@ -2428,10 +2442,8 @@ nsChildView::Idle()
- (void)drawRect:(NSRect)aRect
{
PRBool isVisible;
mGeckoChild->IsVisible(isVisible);
if (!isVisible) {
if (!mGeckoChild || NS_FAILED(mGeckoChild->IsVisible(isVisible)) || !isVisible)
return;
}
// Workaround for the fact that NSQuickDrawViews can't be opaque; see if the rect
// being drawn is covered by a subview, and, if so, just bail.
@ -2851,9 +2863,13 @@ nsChildView::Idle()
return [self getContextMenu];
}
-(NSMenu*)getContextMenu
- (NSMenu*)getContextMenu
{
return [[self superview] getContextMenu];
NSView* superView = [self superview];
if ([superView respondsToSelector:@selector(getContextMenu)])
return [(NSView<mozView>*)superView getContextMenu];
return nil;
}
- (TopLevelWindowData*)ensureWindowData
@ -2989,7 +3005,7 @@ static void ConvertCocoaKeyEventToMacEvent(NSEvent* cocoaEvent, EventRecord& mac
doCommit:(BOOL) doCommit
{
#ifdef DEBUG_IME
NSLog(@"****in sendTextEvent; string = %@", aString);
NSLog(@"****in sendTextEvent; string = '%@'", aString);
NSLog(@" markRange = %d, %d; selRange = %d, %d", markRange.location, markRange.length, selRange.location, selRange.length);
#endif
@ -3011,7 +3027,7 @@ static void ConvertCocoaKeyEventToMacEvent(NSEvent* cocoaEvent, EventRecord& mac
- (void)insertText:(id)insertString
{
#if DEBUG_IME
NSLog(@"****in insertText: %@", insertString);
NSLog(@"****in insertText: '%@'", insertString);
NSLog(@" markRange = %d, %d; selRange = %d, %d", mMarkedRange.location, mMarkedRange.length, mSelectedRange.location, mSelectedRange.length);
#endif
@ -3078,7 +3094,10 @@ static void ConvertCocoaKeyEventToMacEvent(NSEvent* cocoaEvent, EventRecord& mac
}
- (void) doCommandBySelector:(SEL)aSelector
{
{
#if DEBUG_IME
NSLog(@"**** in doCommandBySelector %s", aSelector);
#endif
[super doCommandBySelector:aSelector];
}
@ -3087,7 +3106,7 @@ static void ConvertCocoaKeyEventToMacEvent(NSEvent* cocoaEvent, EventRecord& mac
#if DEBUG_IME
NSLog(@"****in setMarkedText location: %d, length: %d", selRange.location, selRange.length);
NSLog(@" markRange = %d, %d; selRange = %d, %d", mMarkedRange.location, mMarkedRange.length, mSelectedRange.location, mSelectedRange.length);
NSLog(@" aString = %@", aString);
NSLog(@" aString = '%@'", aString);
#endif
if ( ![aString isKindOfClass:[NSAttributedString class]] )
@ -3251,6 +3270,11 @@ static void ConvertCocoaKeyEventToMacEvent(NSEvent* cocoaEvent, EventRecord& mac
return 0;
}
// need to declare this because AppKit does not make it available as API or SPI
//static NSString* const NSMarkedClauseSegmentAttributeName = @"NSMarkedClauseSegment";
//static NSString* const NSTextInputReplacementRangeAttributeName = @"NSTextInputReplacementRangeAttributeName";
- (NSArray*) validAttributesForMarkedText
{
#if DEBUG_IME
@ -3258,6 +3282,7 @@ static void ConvertCocoaKeyEventToMacEvent(NSEvent* cocoaEvent, EventRecord& mac
NSLog(@" markRange = %d, %d; selectRange = %d, %d", mMarkedRange.location, mMarkedRange.length, mSelectedRange.location, mSelectedRange.length);
#endif
//return [NSArray arrayWithObjects:NSUnderlineStyleAttributeName, NSMarkedClauseSegmentAttributeName, NSTextInputReplacementRangeAttributeName, nil];
return [NSArray array]; // empty array; we don't support any attributes right now
}
// end NSTextInput
@ -3268,8 +3293,6 @@ static void ConvertCocoaKeyEventToMacEvent(NSEvent* cocoaEvent, EventRecord& mac
// Handle matching cocoa IME with gecko key events. Sends a key down and key press
// event to gecko.
//
// NOTE: diacriticals (opt-e, e) aren't fully handled.
//
- (void)keyDown:(NSEvent*)theEvent
{
PRBool isKeyDownEventHandled = PR_TRUE;
@ -3416,6 +3439,8 @@ static void ConvertCocoaKeyEventToMacEvent(NSEvent* cocoaEvent, EventRecord& mac
// This method is called when we are about to be focused.
- (BOOL)becomeFirstResponder
{
if (!mGeckoChild) return NO; // we've been destroyed
nsFocusEvent event(PR_TRUE, NS_GOTFOCUS, mGeckoChild);
mGeckoChild->DispatchWindowEvent(event);
@ -3425,6 +3450,8 @@ static void ConvertCocoaKeyEventToMacEvent(NSEvent* cocoaEvent, EventRecord& mac
// This method is called when are are about to lose focus.
- (BOOL)resignFirstResponder
{
if (!mGeckoChild) return NO; // we've been destroyed
nsFocusEvent event(PR_TRUE, NS_LOSTFOCUS, mGeckoChild);
mGeckoChild->DispatchWindowEvent(event);
@ -3433,20 +3460,47 @@ static void ConvertCocoaKeyEventToMacEvent(NSEvent* cocoaEvent, EventRecord& mac
- (void)viewsWindowDidBecomeKey
{
// When unhiding the app, -windowBecameKey: gets called when two bits of window
// state are incorrect (on Tiger):
//
// 1. [window isVisible] returns YES even though it's not on the screen
// 2. [NSApp keyWindow] is not the right window yet
//
// Because this state is not correct at this time, we postpone sending
// the events into gecko (which in turn propagate into the host app)
// until the next time through the event loop, when we're off this stack
// and Cocoa has got its story straight.
[self performSelector:@selector(sendActivateEvent) withObject:nil afterDelay:0];
}
- (void)viewsWindowDidResignKey
{
[self performSelector:@selector(sendDeactivateEvent) withObject:nil afterDelay:0];
}
- (void)sendActivateEvent
{
if (!mGeckoChild)
return; // we've been destroyed
nsFocusEvent focusEvent(PR_TRUE, NS_GOTFOCUS, mGeckoChild);
mGeckoChild->DispatchWindowEvent(focusEvent);
nsFocusEvent activateEvent(PR_TRUE, NS_ACTIVATE, mGeckoChild);
mGeckoChild->DispatchWindowEvent(activateEvent);
}
- (void)viewsWindowDidResignKey
- (void)sendDeactivateEvent
{
nsFocusEvent event(PR_TRUE, NS_LOSTFOCUS, mGeckoChild);
mGeckoChild->DispatchWindowEvent(event);
}
if (!mGeckoChild)
return; // we've been destroyed
nsFocusEvent deactivateEvent(PR_TRUE, NS_DEACTIVATE, mGeckoChild);
mGeckoChild->DispatchWindowEvent(deactivateEvent);
nsFocusEvent unfocusEvent(PR_TRUE, NS_LOSTFOCUS, mGeckoChild);
mGeckoChild->DispatchWindowEvent(unfocusEvent);
}
//-------------------------------------------------------------------------
//

View File

@ -290,7 +290,6 @@ nsCocoaWindow::nsCocoaWindow()
{
#if 0
mMacEventHandler.reset(new nsMacEventHandler(this));
WIDGET_SET_CLASSNAME("nsCocoaWindow");
// create handlers for drag&drop
mDragTrackingHandlerUPP = NewDragTrackingHandlerUPP(DragTrackingHandler);

View File

@ -39,15 +39,16 @@
#ifndef nsNativeScrollbar_h__
#define nsNativeScrollbar_h__
#include "nsINativeScrollbar.h"
#include "nsChildView.h"
#include <Controls.h>
#include "nsINativeScrollbar.h"
#include "nsIContent.h"
#import "mozView.h"
class nsIScrollbarMediator;
@class NativeScrollbarView;
//
// nsNativeScrollbar
@ -65,8 +66,6 @@ public:
nsNativeScrollbar();
virtual ~nsNativeScrollbar();
NS_IMETHOD Destroy();
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSINATIVESCROLLBAR
@ -93,6 +92,8 @@ protected:
void UpdateScroller();
NativeScrollbarView* ScrollbarView() const { return (NativeScrollbarView*)mView; }
// DATA
private:
@ -126,8 +127,6 @@ private:
// overridden parent class initializer
- (id)initWithFrame:(NSRect)frameRect;
- (void)scrollbarDestroyed;
- (IBAction)scroll:(NSScroller*)sender;
@end

View File

@ -35,9 +35,6 @@
*
* ***** END LICENSE BLOCK ***** */
#include <ControlDefinitions.h>
#include "nsNativeScrollbar.h"
#include "nsIDeviceContext.h"
@ -69,7 +66,6 @@ nsNativeScrollbar::nsNativeScrollbar()
, mLineIncrement(0)
, mIsEnabled(PR_TRUE)
{
WIDGET_SET_CLASSNAME("nsNativeScrollbar");
}
@ -77,13 +73,6 @@ nsNativeScrollbar::~nsNativeScrollbar()
{
}
NS_IMETHODIMP
nsNativeScrollbar::Destroy()
{
[mView scrollbarDestroyed];
return NS_OK;
}
//
// CreateCocoaView
//
@ -198,7 +187,7 @@ nsNativeScrollbar::DoScroll(NSScrollerPart inPart)
//
case NSScrollerKnob:
case NSScrollerKnobSlot:
newPos = (int) ([mView floatValue] * mMaxValue);
newPos = (int) ([ScrollbarView() floatValue] * mMaxValue);
UpdateContentPosition(newPos);
if ( mMediator ) {
PRInt32 op = oldPos, np = mValue;
@ -293,6 +282,8 @@ nsNativeScrollbar::GetMaxRange(PRUint32* aMaxRange)
NS_IMETHODIMP
nsNativeScrollbar::SetPosition(PRUint32 aPos)
{
NativeScrollbarView* scrollbarView = ScrollbarView();
if ((PRInt32)aPos < 0)
aPos = 0;
@ -305,9 +296,9 @@ nsNativeScrollbar::SetPosition(PRUint32 aPos)
// mValue = ((PRInt32)aPos) > mMaxValue ? mMaxValue : ((int)aPos);
mValue = aPos;
if ( mMaxValue )
[mView setFloatValue:(mValue / (float)mMaxValue)];
[scrollbarView setFloatValue:(mValue / (float)mMaxValue)];
else
[mView setFloatValue:0.0];
[scrollbarView setFloatValue:0.0];
return NS_OK;
}
@ -448,13 +439,16 @@ nsNativeScrollbar::RecreateHorizontalScrollbar()
orientation.size.width = 100;
orientation.size.height = 16;
NativeScrollbarView* scrollbarView = ScrollbarView();
// save off the old values and get rid of the previous view. Hiding
// it removes it from the parent hierarchy.
NSRect oldBounds = [mView bounds];
float oldValue = [mView floatValue];
float oldProportion = [mView knobProportion];
NSRect oldBounds = [scrollbarView bounds];
float oldValue = [scrollbarView floatValue];
float oldProportion = [scrollbarView knobProportion];
mVisible = PR_TRUE; // ensure that hide does the work
Show(PR_FALSE);
scrollbarView = nil;
[mView release];
// create the new horizontal scroller, init it, hook it up to the
@ -462,7 +456,9 @@ nsNativeScrollbar::RecreateHorizontalScrollbar()
mView = [[NativeScrollbarView alloc] initWithFrame:orientation geckoChild:this];
[mView setNativeWindow: [mParentView getNativeWindow]];
[mView setFrame:oldBounds];
[mView setFloatValue:oldValue knobProportion:oldProportion];
scrollbarView = ScrollbarView();
[scrollbarView setFloatValue:oldValue knobProportion:oldProportion];
Show(PR_TRUE);
Enable(PR_TRUE);
}
@ -519,18 +515,20 @@ nsNativeScrollbar::IsEnabled(PRBool *aState)
void
nsNativeScrollbar::UpdateScroller()
{
NativeScrollbarView* scrollbarView = ScrollbarView();
// Update the current value based on the new range. We need to recompute the
// float value in case we had to set the value to 0 because gecko cheated
// and set the position before it set the max value.
float knobProp = 1.0f;
if ((mVisibleImageSize + mMaxValue) > 0)
knobProp = (float)mVisibleImageSize / (float)(mVisibleImageSize + mMaxValue);
[mView setFloatValue:(mValue / (float)mMaxValue) knobProportion:knobProp];
[scrollbarView setFloatValue:(mValue / (float)mMaxValue) knobProportion:knobProp];
BOOL enableScrollbar = (mIsEnabled && (mMaxValue > 0));
[mView setEnabled:enableScrollbar];
[scrollbarView setEnabled:enableScrollbar];
[mView setNeedsDisplay:YES];
[scrollbarView setNeedsDisplay:YES];
}
@ -639,11 +637,11 @@ nsNativeScrollbar::UpdateScroller()
}
//
// -scrollbarDestroyed
// -widgetDestroyed
//
// the gecko nsNativeScrollbar is being destroyed.
//
- (void)scrollbarDestroyed
- (void)widgetDestroyed
{
mGeckoChild = nsnull;
@ -666,6 +664,11 @@ nsNativeScrollbar::UpdateScroller()
}
}
// getContextMenu, from mozView protocol
- (NSMenu*)getContextMenu
{
return nil;
}
//
// -scroll