Bug 557087 (4/6) - Make widget aware of the new disabled state rule. r=roc a=sicking
authorMounir Lamouri <mounir.lamouri@gmail.com>
Mon, 20 Sep 2010 03:16:49 +0200
changeset 54344 d0024dcc97310c58886b241cc97e55e86489df10
parent 54343 a89e21dcff9a6766a54ee9a16042965b53f2fec6
child 54345 f3f0428af2810c2e8c3cbfd8e6ed8f841c3b1d6c
push id15858
push usermlamouri@mozilla.com
push dateMon, 20 Sep 2010 03:35:23 +0000
treeherdermozilla-central@8b47f3cabf9f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, sicking
bugs557087
milestone2.0b7pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 557087 (4/6) - Make widget aware of the new disabled state rule. r=roc a=sicking
widget/src/cocoa/nsNativeThemeCocoa.h
widget/src/cocoa/nsNativeThemeCocoa.mm
widget/src/gtk2/nsNativeThemeGTK.cpp
widget/src/qt/nsNativeThemeQt.cpp
widget/src/windows/nsNativeThemeWin.cpp
widget/src/xpwidgets/nsNativeTheme.h
--- a/widget/src/cocoa/nsNativeThemeCocoa.h
+++ b/widget/src/cocoa/nsNativeThemeCocoa.h
@@ -98,45 +98,43 @@ public:
 protected:  
 
   nsresult GetSystemColor(PRUint8 aWidgetType, nsILookAndFeel::nsColorID& aColorID);
   nsresult GetSystemFont(PRUint8 aWidgetType, nsSystemFontID& aFont);
   nsIntMargin RTLAwareMargin(const nsIntMargin& aMargin, nsIFrame* aFrame);
 
   // HITheme drawing routines
   void DrawFrame(CGContextRef context, HIThemeFrameKind inKind,
-                 const HIRect& inBoxRect, PRBool inIsDisabled,
-                 PRInt32 inState);
+                 const HIRect& inBoxRect, PRBool inReadOnly, PRInt32 inState);
   void DrawProgress(CGContextRef context, const HIRect& inBoxRect,
                     PRBool inIsIndeterminate, PRBool inIsHorizontal,
                     PRInt32 inValue, PRInt32 inMaxValue, nsIFrame* aFrame);
   void DrawTab(CGContextRef context, HIRect inBoxRect, PRInt32 inState,
                nsIFrame* aFrame);
   void DrawTabPanel(CGContextRef context, const HIRect& inBoxRect, nsIFrame* aFrame);
   void DrawScale(CGContextRef context, const HIRect& inBoxRect,
-                 PRBool inIsDisabled, PRInt32 inState,
-                 PRBool inDirection, PRBool inIsReverse,
-                 PRInt32 inCurrentValue,
-                 PRInt32 inMinValue, PRInt32 inMaxValue,
+                 PRInt32 inState, PRBool inDirection, PRBool inIsReverse,
+                 PRInt32 inCurrentValue, PRInt32 inMinValue, PRInt32 inMaxValue,
                  nsIFrame* aFrame);
   void DrawCheckboxOrRadio(CGContextRef cgContext, PRBool inCheckbox,
                            const HIRect& inBoxRect, PRBool inSelected,
-                           PRBool inDisabled, PRInt32 inState, nsIFrame* aFrame);
-  void DrawSearchField(CGContextRef cgContext, const HIRect& inBoxRect, nsIFrame* aFrame);
+                           PRInt32 inState, nsIFrame* aFrame);
+  void DrawSearchField(CGContextRef cgContext, const HIRect& inBoxRect,
+                       nsIFrame* aFrame, PRInt32 inState);
   void DrawPushButton(CGContextRef cgContext, const HIRect& inBoxRect,
-                      PRBool inDisabled, PRInt32 inState, nsIFrame* aFrame);
+                      PRInt32 inState, nsIFrame* aFrame);
   void DrawButton(CGContextRef context, ThemeButtonKind inKind,
                   const HIRect& inBoxRect, PRBool inIsDefault, 
-                  PRBool inDisabled, ThemeButtonValue inValue,
-                  ThemeButtonAdornment inAdornment, PRInt32 inState, nsIFrame* aFrame);
+                  ThemeButtonValue inValue, ThemeButtonAdornment inAdornment,
+                  PRInt32 inState, nsIFrame* aFrame);
   void DrawDropdown(CGContextRef context, const HIRect& inBoxRect, PRInt32 inState,
                     PRUint8 aWidgetType, nsIFrame* aFrame);
   void DrawSpinButtons(CGContextRef context, ThemeButtonKind inKind,
                        const HIRect& inBoxRect,
-                       PRBool inDisabled, ThemeDrawState inDrawState,
+                       ThemeDrawState inDrawState,
                        ThemeButtonAdornment inAdornment, PRInt32 inState,
                        nsIFrame* aFrame);
   void DrawUnifiedToolbar(CGContextRef cgContext, const HIRect& inBoxRect,
                           NSWindow* aWindow);
   void DrawStatusBar(CGContextRef cgContext, const HIRect& inBoxRect,
                      nsIFrame *aFrame);
   void DrawResizer(CGContextRef cgContext, const HIRect& aRect, nsIFrame *aFrame);
 
--- a/widget/src/cocoa/nsNativeThemeCocoa.mm
+++ b/widget/src/cocoa/nsNativeThemeCocoa.mm
@@ -568,29 +568,28 @@ static const CellRenderSettings checkbox
       {0, 1, 0, 1}      // regular
     }
   }
 };
 
 void
 nsNativeThemeCocoa::DrawCheckboxOrRadio(CGContextRef cgContext, PRBool inCheckbox,
                                         const HIRect& inBoxRect, PRBool inSelected,
-                                        PRBool inDisabled, PRInt32 inState,
-                                        nsIFrame* aFrame)
+                                        PRInt32 inState, nsIFrame* aFrame)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
   NSButtonCell *cell = inCheckbox ? mCheckboxCell : mRadioButtonCell;
   NSCellStateValue state = inSelected ? NSOnState : NSOffState;
 
   // Check if we have an indeterminate checkbox
   if (inCheckbox && GetIndeterminate(aFrame))
     state = NSMixedState;
 
-  [cell setEnabled:!inDisabled];
+  [cell setEnabled:!(inState & NS_EVENT_STATE_DISABLED)];
   [cell setShowsFirstResponder:(inState & NS_EVENT_STATE_FOCUS)];
   [cell setState:state];
   [cell setHighlighted:((inState & NS_EVENT_STATE_ACTIVE) && (inState & NS_EVENT_STATE_HOVER))];
   [cell setControlTint:(FrameIsInActiveWindow(aFrame) ? [NSColor currentControlTint] : NSClearControlTint)];
 
   // Ensure that the control is square.
   float length = PR_MIN(inBoxRect.size.width, inBoxRect.size.height);
   HIRect drawRect = CGRectMake(inBoxRect.origin.x + (int)((inBoxRect.size.width - length) / 2.0f),
@@ -626,22 +625,23 @@ static const CellRenderSettings searchFi
       {0, 0, 0, 0},     // small
       {0, 0, 0, 0}      // regular
     }
   }
 };
 
 void
 nsNativeThemeCocoa::DrawSearchField(CGContextRef cgContext, const HIRect& inBoxRect,
-                                    nsIFrame* aFrame)
+                                    nsIFrame* aFrame, PRInt32 inState)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
   NSSearchFieldCell* cell = mSearchFieldCell;
-  [cell setEnabled:!IsDisabled(aFrame)];
+  [cell setEnabled:!(inState & NS_EVENT_STATE_DISABLED)];
+  // NOTE: this could probably use inState
   [cell setShowsFirstResponder:IsFocused(aFrame)];
 
   DrawCellWithSnapping(cell, cgContext, inBoxRect, searchFieldSettings,
                        VerticalAlignFactor(aFrame), mCellDrawView,
                        IsFrameRTL(aFrame));
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
 }
@@ -673,27 +673,28 @@ static const CellRenderSettings pushButt
 
 // The height at which we start doing square buttons instead of rounded buttons
 // Rounded buttons look bad if drawn at a height greater than 26, so at that point
 // we switch over to doing square buttons which looks fine at any size.
 #define DO_SQUARE_BUTTON_HEIGHT 26
 
 void
 nsNativeThemeCocoa::DrawPushButton(CGContextRef cgContext, const HIRect& inBoxRect,
-                                   PRBool inDisabled, PRInt32 inState, nsIFrame* aFrame)
+                                   PRInt32 inState, nsIFrame* aFrame)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
   BOOL isActive = FrameIsInActiveWindow(aFrame);
+  BOOL isDisabled = inState & NS_EVENT_STATE_DISABLED;
 
-  [mPushButtonCell setEnabled:!inDisabled];
+  [mPushButtonCell setEnabled:!isDisabled];
   [mPushButtonCell setHighlighted:((inState & NS_EVENT_STATE_ACTIVE) &&
                                    (inState & NS_EVENT_STATE_HOVER) && 
                                    isActive)];
-  [mPushButtonCell setShowsFirstResponder:(inState & NS_EVENT_STATE_FOCUS) && !inDisabled && isActive];
+  [mPushButtonCell setShowsFirstResponder:(inState & NS_EVENT_STATE_FOCUS) && !isDisabled && isActive];
 
   // If the button is tall enough, draw the square button style so that buttons with
   // non-standard content look good. Otherwise draw normal rounded aqua buttons.
   if (inBoxRect.size.height > DO_SQUARE_BUTTON_HEIGHT) {
     [mPushButtonCell setBezelStyle:NSShadowlessSquareBezelStyle];
     DrawCellWithScaling(mPushButtonCell, cgContext, inBoxRect, NSRegularControlSize,
                         NSZeroSize, NSMakeSize(14, 0), NULL,
                         mCellDrawView, IsFrameRTL(aFrame));
@@ -786,31 +787,31 @@ static void
 RenderButton(CGContextRef cgContext, const HIRect& aRenderRect, void* aData)
 {
   HIThemeButtonDrawInfo* bdi = (HIThemeButtonDrawInfo*)aData;
   HIThemeDrawButton(&aRenderRect, bdi, cgContext, kHIThemeOrientationNormal, NULL);
 }
 
 void
 nsNativeThemeCocoa::DrawButton(CGContextRef cgContext, ThemeButtonKind inKind,
-                               const HIRect& inBoxRect, PRBool inIsDefault, PRBool inDisabled,
+                               const HIRect& inBoxRect, PRBool inIsDefault,
                                ThemeButtonValue inValue, ThemeButtonAdornment inAdornment,
                                PRInt32 inState, nsIFrame* aFrame)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
   BOOL isActive = FrameIsInActiveWindow(aFrame);
 
   HIThemeButtonDrawInfo bdi;
   bdi.version = 0;
   bdi.kind = inKind;
   bdi.value = inValue;
   bdi.adornment = inAdornment;
 
-  if (inDisabled) {
+  if (inState & NS_EVENT_STATE_DISABLED) {
     bdi.state = kThemeStateUnavailable;
   }
   else if ((inState & NS_EVENT_STATE_ACTIVE) && (inState & NS_EVENT_STATE_HOVER)) {
     bdi.state = kThemeStatePressed;
   }
   else {
     if (inKind == kThemeArrowButton)
       bdi.state = kThemeStateUnavailable; // these are always drawn as unavailable
@@ -818,17 +819,18 @@ nsNativeThemeCocoa::DrawButton(CGContext
       bdi.state = kThemeStateInactive;
     else
       bdi.state = kThemeStateActive;
   }
 
   if (inState & NS_EVENT_STATE_FOCUS && isActive)
     bdi.adornment |= kThemeAdornmentFocus;
 
-  if (inIsDefault && !inDisabled && isActive && !(inState & NS_EVENT_STATE_ACTIVE)) {
+  if (inIsDefault && !(inState & NS_EVENT_STATE_DISABLED) && isActive &&
+      !(inState & NS_EVENT_STATE_ACTIVE)) {
     bdi.adornment |= kThemeAdornmentDefault;
     bdi.animation.time.start = 0;
     bdi.animation.time.current = CFAbsoluteTimeGetCurrent();
   }
 
   HIRect drawFrame = inBoxRect;
 
   if (inKind == kThemePushButton) {
@@ -924,66 +926,66 @@ nsNativeThemeCocoa::DrawDropdown(CGConte
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
   [mDropdownCell setPullsDown:(aWidgetType == NS_THEME_BUTTON)];
 
   BOOL isEditable = (aWidgetType == NS_THEME_DROPDOWN_TEXTFIELD);
   NSCell* cell = isEditable ? (NSCell*)mComboBoxCell : (NSCell*)mDropdownCell;
 
-  [cell setEnabled:!IsDisabled(aFrame)];
+  [cell setEnabled:!(inState & NS_EVENT_STATE_DISABLED)];
   [cell setShowsFirstResponder:(IsFocused(aFrame) || (inState & NS_EVENT_STATE_FOCUS))];
   [cell setHighlighted:IsOpenButton(aFrame)];
   [cell setControlTint:(FrameIsInActiveWindow(aFrame) ? [NSColor currentControlTint] : NSClearControlTint)];
 
   const CellRenderSettings& settings = isEditable ? editableMenulistSettings : dropdownSettings;
   DrawCellWithSnapping(cell, cgContext, inBoxRect, settings,
                        0.5f, mCellDrawView, IsFrameRTL(aFrame));
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 void
 nsNativeThemeCocoa::DrawSpinButtons(CGContextRef cgContext, ThemeButtonKind inKind,
-                                    const HIRect& inBoxRect, PRBool inDisabled,
-                                    ThemeDrawState inDrawState,
+                                    const HIRect& inBoxRect, ThemeDrawState inDrawState,
                                     ThemeButtonAdornment inAdornment,
                                     PRInt32 inState, nsIFrame* aFrame)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
   HIThemeButtonDrawInfo bdi;
   bdi.version = 0;
   bdi.kind = inKind;
   bdi.value = kThemeButtonOff;
   bdi.adornment = inAdornment;
 
-  if (inDisabled)
+  if (inState & NS_EVENT_STATE_DISABLED)
     bdi.state = kThemeStateUnavailable;
   else
     bdi.state = FrameIsInActiveWindow(aFrame) ? inDrawState : kThemeStateActive;
 
   HIThemeDrawButton(&inBoxRect, &bdi, cgContext, HITHEME_ORIENTATION, NULL);
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 void
 nsNativeThemeCocoa::DrawFrame(CGContextRef cgContext, HIThemeFrameKind inKind,
-                              const HIRect& inBoxRect, PRBool inIsDisabled, PRInt32 inState)
+                              const HIRect& inBoxRect, PRBool inReadOnly, PRInt32 inState)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
   HIThemeFrameDrawInfo fdi;
   fdi.version = 0;
   fdi.kind = inKind;
 
   // We don't ever set an inactive state for this because it doesn't
   // look right (see other apps).
-  fdi.state = inIsDisabled ? kThemeStateUnavailable : kThemeStateActive;
+  fdi.state = ((inState & NS_EVENT_STATE_DISABLED) || inReadOnly) ? kThemeStateUnavailable
+                                                                  : kThemeStateActive;
 
   // for some reason focus rings on listboxes draw incorrectly
   if (inKind == kHIThemeFrameListBox)
     fdi.isFocused = 0;
   else
     fdi.isFocused = (inState & NS_EVENT_STATE_FOCUS) != 0;
 
   // HIThemeDrawFrame takes the rect for the content area of the frame, not
@@ -1071,20 +1073,20 @@ nsNativeThemeCocoa::DrawTabPanel(CGConte
 
   HIThemeDrawTabPane(&inBoxRect, &tpdi, cgContext, HITHEME_ORIENTATION);
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 void
 nsNativeThemeCocoa::DrawScale(CGContextRef cgContext, const HIRect& inBoxRect,
-                              PRBool inIsDisabled, PRInt32 inState,
-                              PRBool inIsVertical, PRBool inIsReverse,
-                              PRInt32 inCurrentValue, PRInt32 inMinValue,
-                              PRInt32 inMaxValue, nsIFrame* aFrame)
+                              PRInt32 inState, PRBool inIsVertical,
+                              PRBool inIsReverse, PRInt32 inCurrentValue,
+                              PRInt32 inMinValue, PRInt32 inMaxValue,
+                              nsIFrame* aFrame)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
   HIThemeTrackDrawInfo tdi;
 
   tdi.version = 0;
   tdi.kind = kThemeMediumSlider;
   tdi.bounds = inBoxRect;
@@ -1093,17 +1095,17 @@ nsNativeThemeCocoa::DrawScale(CGContextR
   tdi.value = inCurrentValue;
   tdi.attributes = kThemeTrackShowThumb;
   if (!inIsVertical)
     tdi.attributes |= kThemeTrackHorizontal;
   if (inIsReverse)
     tdi.attributes |= kThemeTrackRightToLeft;
   if (inState & NS_EVENT_STATE_FOCUS)
     tdi.attributes |= kThemeTrackHasFocus;
-  if (inIsDisabled)
+  if (inState & NS_EVENT_STATE_DISABLED)
     tdi.enableState = kThemeTrackDisabled;
   else
     tdi.enableState = FrameIsInActiveWindow(aFrame) ? kThemeTrackActive : kThemeTrackInactive;
   tdi.trackInfo.slider.thumbDir = kThemeThumbPlain;
   tdi.trackInfo.slider.pressState = 0;
 
   HIThemeDrawTrack(&tdi, NULL, cgContext, HITHEME_ORIENTATION);
 
@@ -1120,24 +1122,23 @@ nsNativeThemeCocoa::DrawTab(CGContextRef
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
   HIThemeTabDrawInfo tdi;
   tdi.version = 1;
   tdi.kind = kHIThemeTabKindNormal;
 
   PRBool isSelected = IsSelectedTab(aFrame);
-  PRBool isDisabled = IsDisabled(aFrame);
   if (isSelected) {
-    if (isDisabled) 
+    if (inState & NS_EVENT_STATE_DISABLED)
       tdi.style = kThemeTabFrontUnavailable;
     else
       tdi.style = FrameIsInActiveWindow(aFrame) ? kThemeTabFront : kThemeTabFrontInactive;
   } else {
-    if (isDisabled)
+    if (inState & NS_EVENT_STATE_DISABLED)
       tdi.style = kThemeTabNonFrontUnavailable;
     else if ((inState & NS_EVENT_STATE_ACTIVE) && (inState & NS_EVENT_STATE_HOVER))
       tdi.style = kThemeTabNonFrontPressed;
     else
       tdi.style = FrameIsInActiveWindow(aFrame) ? kThemeTabNonFront : kThemeTabNonFrontInactive;
   }
 
   tdi.direction = kThemeTabNorth;
@@ -1568,17 +1569,18 @@ nsNativeThemeCocoa::DrawWidgetBackground
       HIThemeSetFill(kThemeBrushDialogBackgroundActive, NULL, cgContext, HITHEME_ORIENTATION);
       CGContextFillRect(cgContext, macRect);
     }
       break;
 
     case NS_THEME_MENUPOPUP: {
       HIThemeMenuDrawInfo mdi = {
         version: 0,
-        menuType: IsDisabled(aFrame) ? kThemeMenuTypeInactive : kThemeMenuTypePopUp
+        menuType: (eventState & NS_EVENT_STATE_DISABLED) ? kThemeMenuTypeInactive
+                                                         : kThemeMenuTypePopUp
       };
 
       PRBool isLeftOfParent = PR_FALSE;
       if (IsSubmenu(aFrame, &isLeftOfParent) && !isLeftOfParent) {
         mdi.menuType = kThemeMenuTypeHierarchical;
       }
       
       // The rounded corners draw outside the frame.
@@ -1591,30 +1593,30 @@ nsNativeThemeCocoa::DrawWidgetBackground
     case NS_THEME_MENUITEM: {
       // Clear the background to get correct transparency.
       CGContextClearRect(cgContext, macRect);
 
       // maybe use kThemeMenuItemHierBackground or PopUpBackground instead of just Plain?
       HIThemeMenuItemDrawInfo drawInfo = {
         version: 0,
         itemType: kThemeMenuItemPlain,
-        state: (IsDisabled(aFrame) ? kThemeMenuDisabled :
-                CheckBooleanAttr(aFrame, nsWidgetAtoms::mozmenuactive) ? kThemeMenuSelected :
-                kThemeMenuActive)
+        state: ((eventState & NS_EVENT_STATE_DISABLED) ? kThemeMenuDisabled :
+                 CheckBooleanAttr(aFrame, nsWidgetAtoms::mozmenuactive) ? kThemeMenuSelected :
+                 kThemeMenuActive)
       };
 
       // XXX pass in the menu rect instead of always using the item rect
       HIRect ignored;
       HIThemeDrawMenuItem(&macRect, &macRect, &drawInfo, cgContext, HITHEME_ORIENTATION, &ignored);
     }
       break;
 
     case NS_THEME_MENUSEPARATOR: {
       ThemeMenuState menuState;
-      if (IsDisabled(aFrame)) {
+      if (eventState & NS_EVENT_STATE_DISABLED) {
         menuState = kThemeMenuDisabled;
       }
       else {
         menuState = CheckBooleanAttr(aFrame, nsWidgetAtoms::mozmenuactive) ?
                     kThemeMenuSelected : kThemeMenuActive;
       }
 
       HIThemeMenuItemDrawInfo midi = { 0, kThemeMenuItemPlain, menuState };
@@ -1626,58 +1628,58 @@ nsNativeThemeCocoa::DrawWidgetBackground
       CGContextSetRGBFillColor(cgContext, 0.996, 1.000, 0.792, 0.950);
       CGContextFillRect(cgContext, macRect);
       break;
 
     case NS_THEME_CHECKBOX:
     case NS_THEME_RADIO: {
       PRBool isCheckbox = (aWidgetType == NS_THEME_CHECKBOX);
       DrawCheckboxOrRadio(cgContext, isCheckbox, macRect, GetCheckedOrSelected(aFrame, !isCheckbox),
-                          IsDisabled(aFrame), eventState, aFrame);
+                          eventState, aFrame);
     }
       break;
 
     case NS_THEME_BUTTON:
       if (IsDefaultButton(aFrame)) {
-        DrawButton(cgContext, kThemePushButton, macRect, true, IsDisabled(aFrame), 
+        DrawButton(cgContext, kThemePushButton, macRect, true,
                    kThemeButtonOff, kThemeAdornmentNone, eventState, aFrame);
       } else if (IsButtonTypeMenu(aFrame)) {
         DrawDropdown(cgContext, macRect, eventState, aWidgetType, aFrame);
       } else {
-        DrawPushButton(cgContext, macRect, IsDisabled(aFrame), eventState, aFrame);
+        DrawPushButton(cgContext, macRect, eventState, aFrame);
       }
       break;
 
     case NS_THEME_BUTTON_BEVEL:
       DrawButton(cgContext, kThemeMediumBevelButton, macRect,
-                 IsDefaultButton(aFrame), IsDisabled(aFrame), 
-                 kThemeButtonOff, kThemeAdornmentNone, eventState, aFrame);
+                 IsDefaultButton(aFrame), kThemeButtonOff, kThemeAdornmentNone,
+                 eventState, aFrame);
       break;
 
     case NS_THEME_SPINNER: {
       ThemeDrawState state = kThemeStateActive;
       nsIContent* content = aFrame->GetContent();
       if (content->AttrValueIs(kNameSpaceID_None, nsWidgetAtoms::state,
                                NS_LITERAL_STRING("up"), eCaseMatters)) {
         state = kThemeStatePressedUp;
       }
       else if (content->AttrValueIs(kNameSpaceID_None, nsWidgetAtoms::state,
                                     NS_LITERAL_STRING("down"), eCaseMatters)) {
         state = kThemeStatePressedDown;
       }
 
-      DrawSpinButtons(cgContext, kThemeIncDecButton, macRect, IsDisabled(aFrame),
-                      state, kThemeAdornmentNone, eventState, aFrame);
+      DrawSpinButtons(cgContext, kThemeIncDecButton, macRect, state,
+                      kThemeAdornmentNone, eventState, aFrame);
     }
       break;
 
     case NS_THEME_TOOLBAR_BUTTON:
       DrawButton(cgContext, kThemePushButton, macRect,
-                 IsDefaultButton(aFrame), IsDisabled(aFrame),
-                 kThemeButtonOn, kThemeAdornmentNone, eventState, aFrame);
+                 IsDefaultButton(aFrame), kThemeButtonOn, kThemeAdornmentNone,
+                 eventState, aFrame);
       break;
 
     case NS_THEME_TOOLBAR_SEPARATOR: {
       HIThemeSeparatorDrawInfo sdi = { 0, kThemeStateActive };
       HIThemeDrawSeparator(&macRect, &sdi, cgContext, HITHEME_ORIENTATION);
     }
       break;
 
@@ -1718,18 +1720,17 @@ nsNativeThemeCocoa::DrawWidgetBackground
       break;
 
     case NS_THEME_DROPDOWN:
     case NS_THEME_DROPDOWN_TEXTFIELD:
       DrawDropdown(cgContext, macRect, eventState, aWidgetType, aFrame);
       break;
 
     case NS_THEME_DROPDOWN_BUTTON:
-      DrawButton(cgContext, kThemeArrowButton, macRect, PR_FALSE,
-                 IsDisabled(aFrame), kThemeButtonOn,
+      DrawButton(cgContext, kThemeArrowButton, macRect, PR_FALSE, kThemeButtonOn,
                  kThemeAdornmentArrowDownArrow, eventState, aFrame);
       break;
 
     case NS_THEME_GROUPBOX: {
       HIThemeGroupBoxDrawInfo gdi = { 0, kThemeStateActive, kHIThemeGroupBoxKindPrimary };
       HIThemeDrawGroupBox(&macRect, &gdi, cgContext, HITHEME_ORIENTATION);
       break;
     }
@@ -1743,22 +1744,21 @@ nsNativeThemeCocoa::DrawWidgetBackground
       // concrete focus is set on the html:input element within it. We can
       // though, check the focused attribute of xul textboxes in this case.
       // On Mac, focus rings are always shown for textboxes, so we do not need
       // to check the window's focus ring state here
       if (aFrame->GetContent()->IsXUL() && IsFocused(aFrame)) {
         eventState |= NS_EVENT_STATE_FOCUS;
       }
 
-      DrawFrame(cgContext, kHIThemeFrameTextFieldSquare,
-                macRect, (IsDisabled(aFrame) || IsReadOnly(aFrame)), eventState);
+      DrawFrame(cgContext, kHIThemeFrameTextFieldSquare, macRect, IsReadOnly(aFrame), eventState);
       break;
       
     case NS_THEME_SEARCHFIELD:
-      DrawSearchField(cgContext, macRect, aFrame);
+      DrawSearchField(cgContext, macRect, aFrame, eventState);
       break;
 
     case NS_THEME_PROGRESSBAR:
       DrawProgress(cgContext, macRect, IsIndeterminateProgress(aFrame),
                    PR_TRUE, GetProgressValue(aFrame),
                    GetProgressMaxValue(aFrame), aFrame);
       break;
 
@@ -1769,31 +1769,31 @@ nsNativeThemeCocoa::DrawWidgetBackground
       break;
 
     case NS_THEME_PROGRESSBAR_CHUNK:
     case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL:
       // do nothing, covered by the progress bar cases above
       break;
 
     case NS_THEME_TREEVIEW_TWISTY:
-      DrawButton(cgContext, kThemeDisclosureButton, macRect, PR_FALSE, IsDisabled(aFrame), 
+      DrawButton(cgContext, kThemeDisclosureButton, macRect, PR_FALSE,
                  kThemeDisclosureRight, kThemeAdornmentNone, eventState, aFrame);
       break;
 
     case NS_THEME_TREEVIEW_TWISTY_OPEN:
-      DrawButton(cgContext, kThemeDisclosureButton, macRect, PR_FALSE, IsDisabled(aFrame), 
+      DrawButton(cgContext, kThemeDisclosureButton, macRect, PR_FALSE,
                  kThemeDisclosureDown, kThemeAdornmentNone, eventState, aFrame);
       break;
 
     case NS_THEME_TREEVIEW_HEADER_CELL: {
       TreeSortDirection sortDirection = GetTreeSortDirection(aFrame);
-      DrawButton(cgContext, kThemeListHeaderButton, macRect, PR_FALSE, IsDisabled(aFrame), 
+      DrawButton(cgContext, kThemeListHeaderButton, macRect, PR_FALSE,
                  sortDirection == eTreeSortDirection_Natural ? kThemeButtonOff : kThemeButtonOn,
                  sortDirection == eTreeSortDirection_Ascending ?
-                 kThemeAdornmentHeaderButtonSortUp : kThemeAdornmentNone, eventState, aFrame);      
+                 kThemeAdornmentHeaderButtonSortUp : kThemeAdornmentNone, eventState, aFrame);
     }
       break;
 
     case NS_THEME_TREEVIEW_TREEITEM:
     case NS_THEME_TREEVIEW:
       // HIThemeSetFill is not available on 10.3
       // HIThemeSetFill(kThemeBrushWhite, NULL, cgContext, HITHEME_ORIENTATION);
       CGContextSetRGBFillColor(cgContext, 1.0, 1.0, 1.0, 1.0);
@@ -1814,17 +1814,17 @@ nsNativeThemeCocoa::DrawWidgetBackground
       PRInt32 minpos = CheckIntAttr(aFrame, nsWidgetAtoms::minpos, 0);
       PRInt32 maxpos = CheckIntAttr(aFrame, nsWidgetAtoms::maxpos, 100);
       if (!maxpos)
         maxpos = 100;
 
       PRBool reverse = aFrame->GetContent()->
         AttrValueIs(kNameSpaceID_None, nsWidgetAtoms::dir,
                     NS_LITERAL_STRING("reverse"), eCaseMatters);
-      DrawScale(cgContext, macRect, IsDisabled(aFrame), eventState,
+      DrawScale(cgContext, macRect, eventState,
                 (aWidgetType == NS_THEME_SCALE_VERTICAL), reverse,
                 curpos, minpos, maxpos, aFrame);
     }
       break;
 
     case NS_THEME_SCALE_THUMB_HORIZONTAL:
     case NS_THEME_SCALE_THUMB_VERTICAL:
       // do nothing, drawn by scale
--- a/widget/src/gtk2/nsNativeThemeGTK.cpp
+++ b/widget/src/gtk2/nsNativeThemeGTK.cpp
@@ -252,17 +252,18 @@ nsNativeThemeGTK::GetGtkWidgetAndState(P
                  aWidgetType == NS_THEME_BUTTON_ARROW_UP ||
                  aWidgetType == NS_THEME_BUTTON_ARROW_DOWN) {
         // The state of an arrow comes from its parent.
         stateFrame = aFrame = aFrame->GetParent();
       }
 
       PRInt32 eventState = GetContentState(stateFrame, aWidgetType);
 
-      aState->disabled = (IsDisabled(aFrame) || IsReadOnly(aFrame));
+      aState->disabled = ((eventState & NS_EVENT_STATE_DISABLED) == NS_EVENT_STATE_DISABLED ||
+                          IsReadOnly(aFrame));
       aState->active  = (eventState & NS_EVENT_STATE_ACTIVE) == NS_EVENT_STATE_ACTIVE;
       aState->focused = (eventState & NS_EVENT_STATE_FOCUS) == NS_EVENT_STATE_FOCUS;
       aState->inHover = (eventState & NS_EVENT_STATE_HOVER) == NS_EVENT_STATE_HOVER;
       aState->isDefault = IsDefaultButton(aFrame);
       aState->canDefault = FALSE; // XXX fix me
       aState->depressed = FALSE;
 
       if (IsFrameContentNodeInNamespace(aFrame, kNameSpaceID_XUL)) {
--- a/widget/src/qt/nsNativeThemeQt.cpp
+++ b/widget/src/qt/nsNativeThemeQt.cpp
@@ -307,18 +307,19 @@ nsNativeThemeQt::DrawWidgetBackground(QP
         break;
     }
     case NS_THEME_DROPDOWN_TEXT:
     case NS_THEME_DROPDOWN_TEXTFIELD:
     case NS_THEME_TEXTFIELD:
     case NS_THEME_TEXTFIELD_MULTILINE:
     case NS_THEME_LISTBOX: {
         QStyleOptionFrameV2 frameOpt;
-        
-        if (!IsDisabled(aFrame))
+        PRInt32 eventState = GetContentState(aFrame, aWidgetType);
+
+        if (!(eventState & NS_EVENT_STATE_DISABLED))
             frameOpt.state |= QStyle::State_Enabled;
 
         frameOpt.rect = r;
         frameOpt.features = QStyleOptionFrameV2::Flat;
 
         if (aWidgetType == NS_THEME_TEXTFIELD || aWidgetType == NS_THEME_TEXTFIELD_MULTILINE) {
             QRect contentRect = style->subElementRect(QStyle::SE_LineEditContents, &frameOpt);
             contentRect.adjust(mFrameWidth, mFrameWidth, -mFrameWidth, -mFrameWidth);
@@ -635,25 +636,23 @@ nsNativeThemeQt::InitButtonStyle(PRUint8
                                  QRect rect,
                                  QStyleOptionButton &opt)
 {
     PRInt32 eventState = GetContentState(aFrame, aWidgetType);
 
     opt.rect = rect;
     opt.palette = mNoBackgroundPalette;
 
-    PRBool disabled = IsDisabled(aFrame);
-
-    if (!disabled)
+    if (!(eventState & NS_EVENT_STATE_DISABLED))
         opt.state |= QStyle::State_Enabled;
     if (eventState & NS_EVENT_STATE_HOVER)
         opt.state |= QStyle::State_MouseOver;
     if (eventState & NS_EVENT_STATE_FOCUS)
         opt.state |= QStyle::State_HasFocus;
-    if (!disabled && eventState & NS_EVENT_STATE_ACTIVE)
+    if (!(eventState & NS_EVENT_STATE_DISABLED) && (eventState & NS_EVENT_STATE_ACTIVE))
         // Don't allow sunken when disabled
         opt.state |= QStyle::State_Sunken;
 
     switch (aWidgetType) {
     case NS_THEME_RADIO:
     case NS_THEME_CHECKBOX:
         if (IsChecked(aFrame))
             opt.state |= QStyle::State_On;
@@ -674,17 +673,17 @@ nsNativeThemeQt::InitPlainStyle(PRUint8 
                                 QRect rect,
                                 QStyleOption &opt,
                                 QStyle::State extraFlags)
 {
     PRInt32 eventState = GetContentState(aFrame, aWidgetType);
 
     opt.rect = rect;
 
-    if (!IsDisabled(aFrame))
+    if (!(eventState & NS_EVENT_STATE_DISABLED))
         opt.state |= QStyle::State_Enabled;
     if (eventState & NS_EVENT_STATE_HOVER)
         opt.state |= QStyle::State_MouseOver;
     if (eventState & NS_EVENT_STATE_FOCUS)
         opt.state |= QStyle::State_HasFocus;
 
     opt.state |= extraFlags;
 }
@@ -692,25 +691,23 @@ nsNativeThemeQt::InitPlainStyle(PRUint8 
 void
 nsNativeThemeQt::InitComboStyle(PRUint8 aWidgetType,
                                 nsIFrame* aFrame,
                                 QRect rect,
                                 QStyleOptionComboBox &opt)
 {
     PRInt32 eventState = GetContentState(aFrame, aWidgetType);
 
-    PRBool disabled = IsDisabled(aFrame);
-
-    if (!disabled)
+    if (!(eventState & NS_EVENT_STATE_DISABLED))
         opt.state |= QStyle::State_Enabled;
     if (eventState & NS_EVENT_STATE_HOVER)
         opt.state |= QStyle::State_MouseOver;
     if (eventState & NS_EVENT_STATE_FOCUS)
         opt.state |= QStyle::State_HasFocus;
     if (!(eventState & NS_EVENT_STATE_ACTIVE))
         opt.state |= QStyle::State_Raised;
-    if (!disabled && eventState & NS_EVENT_STATE_ACTIVE)
+    if (!(eventState & NS_EVENT_STATE_DISABLED) && (eventState & NS_EVENT_STATE_ACTIVE))
         // Don't allow sunken when disabled
         opt.state |= QStyle::State_Sunken;
 
     opt.rect = rect;
     opt.palette = mNoBackgroundPalette;
 }
--- a/widget/src/windows/nsNativeThemeWin.cpp
+++ b/widget/src/windows/nsNativeThemeWin.cpp
@@ -480,17 +480,18 @@ nsNativeThemeWin::GetThemePartAndState(n
   switch (aWidgetType) {
     case NS_THEME_BUTTON: {
       aPart = BP_BUTTON;
       if (!aFrame) {
         aState = TS_NORMAL;
         return NS_OK;
       }
 
-      if (IsDisabled(aFrame)) {
+      PRInt32 eventState = GetContentState(aFrame, aWidgetType);
+      if (eventState & NS_EVENT_STATE_DISABLED) {
         aState = TS_DISABLED;
         return NS_OK;
       } else if (IsOpenButton(aFrame) ||
                  IsCheckedButton(aFrame)) {
         aState = TS_ACTIVE;
         return NS_OK;
       }
 
@@ -517,17 +518,20 @@ nsNativeThemeWin::GetThemePartAndState(n
         aState = TS_NORMAL;
       } else {
         if (GetCheckedOrSelected(aFrame, !isCheckbox)) {
           inputState = CHECKED;
         } if (isCheckbox && GetIndeterminate(aFrame)) {
           inputState = INDETERMINATE;
         }
 
-        if (IsDisabled(isXULCheckboxRadio ? aFrame->GetParent() : aFrame)) {
+        PRInt32 eventState = GetContentState(isXULCheckboxRadio ? aFrame->GetParent()
+                                                                : aFrame,
+                                             aWidgetType);
+        if (eventState & NS_EVENT_STATE_DISABLED) {
           aState = TS_DISABLED;
         } else {
           aState = StandardGetState(aFrame, aWidgetType, PR_FALSE);
         }
       }
 
       // 4 unchecked states, 4 checked states, 4 indeterminate states.
       aState += inputState * 4;
@@ -537,36 +541,37 @@ nsNativeThemeWin::GetThemePartAndState(n
       aPart = BP_GROUPBOX;
       aState = TS_NORMAL;
       // Since we don't support groupbox disabled and GBS_DISABLED looks the
       // same as GBS_NORMAL don't bother supporting GBS_DISABLED.
       return NS_OK;
     }
     case NS_THEME_TEXTFIELD:
     case NS_THEME_TEXTFIELD_MULTILINE: {
+      PRInt32 eventState = GetContentState(aFrame, aWidgetType);
+
       if (nsUXThemeData::sIsVistaOrLater) {
         /* Note: the NOSCROLL type has a rounded corner in each
          * corner.  The more specific HSCROLL, VSCROLL, HVSCROLL types
          * have side and/or top/bottom edges rendered as straight
          * horizontal lines with sharp corners to accommodate a
          * scrollbar.  However, the scrollbar gets rendered on top of
          * this for us, so we don't care, and can just use NOSCROLL
          * here.
          */
         aPart = TFP_EDITBORDER_NOSCROLL;
 
         if (!aFrame) {
           aState = TFS_EDITBORDER_NORMAL;
-        } else if (IsDisabled(aFrame)) {
+        } else if (eventState & NS_EVENT_STATE_DISABLED) {
           aState = TFS_EDITBORDER_DISABLED;
         } else if (IsReadOnly(aFrame)) {
           /* no special read-only state */
           aState = TFS_EDITBORDER_NORMAL;
         } else {
-          PRInt32 eventState = GetContentState(aFrame, aWidgetType);
           nsIContent* content = aFrame->GetContent();
 
           /* XUL textboxes don't get focused themselves, because they have child
            * html:input.. but we can check the XUL focused attributes on them
            */
           if (content && content->IsXUL() && IsFocused(aFrame))
             aState = TFS_EDITBORDER_FOCUSED;
           else if (eventState & NS_EVENT_STATE_ACTIVE || eventState & NS_EVENT_STATE_FOCUS)
@@ -576,17 +581,17 @@ nsNativeThemeWin::GetThemePartAndState(n
           else
             aState = TFS_EDITBORDER_NORMAL;
         }
       } else {
         aPart = TFP_TEXTFIELD;
         
         if (!aFrame)
           aState = TS_NORMAL;
-        else if (IsDisabled(aFrame))
+        else if (eventState & NS_EVENT_STATE_DISABLED)
           aState = TS_DISABLED;
         else if (IsReadOnly(aFrame))
           aState = TFS_READONLY;
         else
           aState = StandardGetState(aFrame, aWidgetType, PR_TRUE);
       }
 
       return NS_OK;
@@ -618,25 +623,26 @@ nsNativeThemeWin::GetThemePartAndState(n
     }
     case NS_THEME_TOOLBAR_BUTTON: {
       aPart = BP_BUTTON;
       if (!aFrame) {
         aState = TS_NORMAL;
         return NS_OK;
       }
 
-      if (IsDisabled(aFrame)) {
+      PRInt32 eventState = GetContentState(aFrame, aWidgetType);
+      if (eventState & NS_EVENT_STATE_DISABLED) {
         aState = TS_DISABLED;
         return NS_OK;
       }
       if (IsOpenButton(aFrame)) {
         aState = TS_ACTIVE;
         return NS_OK;
       }
-      PRInt32 eventState = GetContentState(aFrame, aWidgetType);
+
       if (eventState & NS_EVENT_STATE_HOVER && eventState & NS_EVENT_STATE_ACTIVE)
         aState = TS_ACTIVE;
       else if (eventState & NS_EVENT_STATE_HOVER) {
         if (IsCheckedButton(aFrame))
           aState = TB_HOVER_CHECKED;
         else
           aState = TS_HOVER;
       }
@@ -655,22 +661,22 @@ nsNativeThemeWin::GetThemePartAndState(n
       return NS_OK;
     }
     case NS_THEME_SCROLLBAR_BUTTON_UP:
     case NS_THEME_SCROLLBAR_BUTTON_DOWN:
     case NS_THEME_SCROLLBAR_BUTTON_LEFT:
     case NS_THEME_SCROLLBAR_BUTTON_RIGHT: {
       aPart = SP_BUTTON;
       aState = (aWidgetType - NS_THEME_SCROLLBAR_BUTTON_UP)*4;
+      PRInt32 eventState = GetContentState(aFrame, aWidgetType);
       if (!aFrame)
         aState += TS_NORMAL;
-      else if (IsDisabled(aFrame))
+      else if (eventState & NS_EVENT_STATE_DISABLED)
         aState += TS_DISABLED;
       else {
-        PRInt32 eventState = GetContentState(aFrame, aWidgetType);
         nsIFrame *parent = aFrame->GetParent();
         PRInt32 parentState = GetContentState(parent, parent->GetStyleDisplay()->mAppearance);
         if (eventState & NS_EVENT_STATE_HOVER && eventState & NS_EVENT_STATE_ACTIVE)
           aState += TS_ACTIVE;
         else if (eventState & NS_EVENT_STATE_HOVER)
           aState += TS_HOVER;
         else if (nsUXThemeData::sIsVistaOrLater && parentState & NS_EVENT_STATE_HOVER)
           aState = (aWidgetType - NS_THEME_SCROLLBAR_BUTTON_UP) + SP_BUTTON_IMPLICIT_HOVER_BASE;
@@ -685,22 +691,22 @@ nsNativeThemeWin::GetThemePartAndState(n
               SP_TRACKSTARTHOR : SP_TRACKSTARTVERT;
       aState = TS_NORMAL;
       return NS_OK;
     }
     case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL:
     case NS_THEME_SCROLLBAR_THUMB_VERTICAL: {
       aPart = (aWidgetType == NS_THEME_SCROLLBAR_THUMB_HORIZONTAL) ?
               SP_THUMBHOR : SP_THUMBVERT;
+      PRInt32 eventState = GetContentState(aFrame, aWidgetType);
       if (!aFrame)
         aState = TS_NORMAL;
-      else if (IsDisabled(aFrame))
+      else if (eventState & NS_EVENT_STATE_DISABLED)
         aState = TS_DISABLED;
       else {
-        PRInt32 eventState = GetContentState(aFrame, aWidgetType);
         if (eventState & NS_EVENT_STATE_ACTIVE) // Hover is not also a requirement for
                                                 // the thumb, since the drag is not canceled
                                                 // when you move outside the thumb.
           aState = TS_ACTIVE;
         else if (eventState & NS_EVENT_STATE_HOVER)
           aState = TS_HOVER;
         else 
           aState = TS_NORMAL;
@@ -714,23 +720,23 @@ nsNativeThemeWin::GetThemePartAndState(n
 
       aState = TS_NORMAL;
       return NS_OK;
     }
     case NS_THEME_SCALE_THUMB_HORIZONTAL:
     case NS_THEME_SCALE_THUMB_VERTICAL: {
       aPart = (aWidgetType == NS_THEME_SCALE_THUMB_HORIZONTAL) ?
               TKP_THUMB : TKP_THUMBVERT;
+      PRInt32 eventState = GetContentState(aFrame, aWidgetType);
       if (!aFrame)
         aState = TS_NORMAL;
-      else if (IsDisabled(aFrame)) {
+      else if (eventState & NS_EVENT_STATE_DISABLED) {
         aState = TKP_DISABLED;
       }
       else {
-        PRInt32 eventState = GetContentState(aFrame, aWidgetType);
         if (eventState & NS_EVENT_STATE_ACTIVE) // Hover is not also a requirement for
                                                 // the thumb, since the drag is not canceled
                                                 // when you move outside the thumb.
           aState = TS_ACTIVE;
         else if (eventState & NS_EVENT_STATE_FOCUS)
           aState = TKP_FOCUSED;
         else if (eventState & NS_EVENT_STATE_HOVER)
           aState = TS_HOVER;
@@ -738,19 +744,20 @@ nsNativeThemeWin::GetThemePartAndState(n
           aState = TS_NORMAL;
       }
       return NS_OK;
     }
     case NS_THEME_SPINNER_UP_BUTTON:
     case NS_THEME_SPINNER_DOWN_BUTTON: {
       aPart = (aWidgetType == NS_THEME_SPINNER_UP_BUTTON) ?
               SPNP_UP : SPNP_DOWN;
+      PRInt32 eventState = GetContentState(aFrame, aWidgetType);
       if (!aFrame)
         aState = TS_NORMAL;
-      else if (IsDisabled(aFrame))
+      else if (eventState & NS_EVENT_STATE_DISABLED)
         aState = TS_DISABLED;
       else
         aState = StandardGetState(aFrame, aWidgetType, PR_FALSE);
       return NS_OK;    
     }
     case NS_THEME_TOOLBOX:
     case NS_THEME_WIN_MEDIA_TOOLBOX:
     case NS_THEME_WIN_COMMUNICATIONS_TOOLBOX:
@@ -809,18 +816,19 @@ nsNativeThemeWin::GetThemePartAndState(n
       return NS_OK;
     }
     case NS_THEME_TAB: {
       aPart = TABP_TAB;
       if (!aFrame) {
         aState = TS_NORMAL;
         return NS_OK;
       }
-      
-      if (IsDisabled(aFrame)) {
+
+      PRInt32 eventState = GetContentState(aFrame, aWidgetType);
+      if (eventState & NS_EVENT_STATE_DISABLED) {
         aState = TS_DISABLED;
         return NS_OK;
       }
 
       if (IsSelectedTab(aFrame)) {
         aPart = TABP_TAB_SELECTED;
         aState = TS_ACTIVE; // The selected tab is always "pressed".
       }
@@ -844,33 +852,33 @@ nsNativeThemeWin::GetThemePartAndState(n
       
       aState = StandardGetState(aFrame, aWidgetType, PR_TRUE);
       
       return NS_OK;
     }
     case NS_THEME_DROPDOWN: {
       nsIContent* content = aFrame->GetContent();
       PRBool isHTML = content && content->IsHTML();
+      PRInt32 eventState = GetContentState(aFrame, aWidgetType);
 
       /* On vista, in HTML, we use CBP_DROPBORDER instead of DROPFRAME for HTML content;
        * this gives us the thin outline in HTML content, instead of the gradient-filled
        * background */
       if (isHTML)
         aPart = CBP_DROPBORDER;
       else
         aPart = CBP_DROPFRAME;
 
-      if (IsDisabled(aFrame)) {
+      if (eventState & NS_EVENT_STATE_DISABLED) {
         aState = TS_DISABLED;
       } else if (IsReadOnly(aFrame)) {
         aState = TS_NORMAL;
       } else if (IsOpenButton(aFrame)) {
         aState = TS_ACTIVE;
       } else {
-        PRInt32 eventState = GetContentState(aFrame, aWidgetType);
         if (isHTML && eventState & NS_EVENT_STATE_FOCUS)
           aState = TS_ACTIVE;
         else if (eventState & NS_EVENT_STATE_HOVER && eventState & NS_EVENT_STATE_ACTIVE)
           aState = TS_ACTIVE;
         else if (eventState & NS_EVENT_STATE_HOVER)
           aState = TS_HOVER;
         else
           aState = TS_NORMAL;
@@ -883,25 +891,26 @@ nsNativeThemeWin::GetThemePartAndState(n
       nsIFrame* parentFrame = aFrame->GetParent();
       PRBool isMenulist = !isHTML && parentFrame->GetType() == nsWidgetAtoms::menuFrame;
       PRBool isOpen = PR_FALSE;
 
       // HTML select and XUL menulist dropdown buttons get state from the parent.
       if (isHTML || isMenulist)
         aFrame = parentFrame;
 
+      PRInt32 eventState = GetContentState(aFrame, aWidgetType);
       aPart = nsUXThemeData::sIsVistaOrLater ? CBP_DROPMARKER_VISTA : CBP_DROPMARKER;
 
       // For HTML controls with author styling, we should fall
       // back to the old dropmarker style to avoid clashes with
       // author-specified backgrounds and borders (bug #441034)
       if (isHTML && IsWidgetStyled(aFrame->PresContext(), aFrame, NS_THEME_DROPDOWN))
         aPart = CBP_DROPMARKER;
 
-      if (IsDisabled(aFrame)) {
+      if (eventState & NS_EVENT_STATE_DISABLED) {
         aState = TS_DISABLED;
         return NS_OK;
       }
 
       if (isHTML) {
         nsIComboboxControlFrame* ccf = do_QueryFrame(aFrame);
         isOpen = (ccf && ccf->IsDroppedDown());
       }
@@ -928,17 +937,16 @@ nsNativeThemeWin::GetThemePartAndState(n
            * to be normal. (Bug 430434)
            */
           aState = TS_NORMAL;
           return NS_OK;
         }
       }
 
       aState = TS_NORMAL;
-      PRInt32 eventState = GetContentState(aFrame, aWidgetType);
 
       // Dropdown button active state doesn't need :hover.
       if (eventState & NS_EVENT_STATE_ACTIVE) {
         if (isOpen && (isHTML || isMenulist)) {
           // XXX Button should look active until the mouse is released, but
           //     without making it look active when the popup is clicked.
           return NS_OK;
         }
@@ -963,16 +971,17 @@ nsNativeThemeWin::GetThemePartAndState(n
     }
     case NS_THEME_MENUITEM:
     case NS_THEME_CHECKMENUITEM: 
     case NS_THEME_RADIOMENUITEM: {
       PRBool isTopLevel = PR_FALSE;
       PRBool isOpen = PR_FALSE;
       PRBool isHover = PR_FALSE;
       nsIMenuFrame *menuFrame = do_QueryFrame(aFrame);
+      PRInt32 eventState = GetContentState(aFrame, aWidgetType);
 
       isTopLevel = IsTopLevelMenu(aFrame);
 
       if (menuFrame)
         isOpen = menuFrame->IsOpen();
 
       isHover = IsMenuActive(aFrame, aWidgetType);
 
@@ -982,59 +991,62 @@ nsNativeThemeWin::GetThemePartAndState(n
         if (isOpen)
           aState = MBI_PUSHED;
         else if (isHover)
           aState = MBI_HOT;
         else
           aState = MBI_NORMAL;
 
         // the disabled states are offset by 3
-        if (IsDisabled(aFrame))
+        if (eventState & NS_EVENT_STATE_DISABLED)
           aState += 3;
       } else {
         aPart = MENU_POPUPITEM;
 
         if (isHover)
           aState = MPI_HOT;
         else
           aState = MPI_NORMAL;
 
         // the disabled states are offset by 2
-        if (IsDisabled(aFrame))
+        if (eventState & NS_EVENT_STATE_DISABLED)
           aState += 2;
       }
 
       return NS_OK;
     }
     case NS_THEME_MENUSEPARATOR:
       aPart = MENU_POPUPSEPARATOR;
       aState = 0;
       return NS_OK;
     case NS_THEME_MENUARROW:
-      aPart = MENU_POPUPSUBMENU;
-      aState = IsDisabled(aFrame) ? MSM_DISABLED : MSM_NORMAL;
-      return NS_OK;
+      {
+        aPart = MENU_POPUPSUBMENU;
+        PRInt32 eventState = GetContentState(aFrame, aWidgetType);
+        aState = (eventState & NS_EVENT_STATE_DISABLED) ? MSM_DISABLED : MSM_NORMAL;
+        return NS_OK;
+      }
     case NS_THEME_MENUCHECKBOX:
     case NS_THEME_MENURADIO:
       {
         PRBool isChecked;
-        PRBool isDisabled;
-
+        PRInt32 eventState = GetContentState(aFrame, aWidgetType);
+
+        // NOTE: we can probably use NS_EVENT_STATE_CHECKED
         isChecked = CheckBooleanAttr(aFrame, nsWidgetAtoms::checked);
-        isDisabled = CheckBooleanAttr(aFrame, nsWidgetAtoms::disabled);
 
         aPart = MENU_POPUPCHECK;
         aState = MC_CHECKMARKNORMAL;
 
         // Radio states are offset by 2
         if (aWidgetType == NS_THEME_MENURADIO)
           aState += 2;
 
         // the disabled states are offset by 1
-        if (isDisabled)
+        if (eventState & NS_EVENT_STATE_DISABLED)
           aState += 1;
 
         return NS_OK;
       }
     case NS_THEME_MENUITEMTEXT:
     case NS_THEME_MENUIMAGE:
       aPart = -1;
       aState = 0;
@@ -1232,20 +1244,20 @@ RENDER_AGAIN:
   else if (aWidgetType == NS_THEME_MENUCHECKBOX || aWidgetType == NS_THEME_MENURADIO)
   {
       PRBool isChecked = PR_FALSE;
       isChecked = CheckBooleanAttr(aFrame, nsWidgetAtoms::checked);
 
       if (isChecked)
       {
         int bgState = MCB_NORMAL;
-        PRBool isDisabled = IsDisabled(aFrame);
+        PRInt32 eventState = GetContentState(aFrame, aWidgetType);
 
         // the disabled states are offset by 1
-        if (isDisabled)
+        if (eventState & NS_EVENT_STATE_DISABLED)
           bgState += 1;
 
         SIZE checkboxBGSize(GetCheckboxBGSize(theme, hdc));
 
         RECT checkBGRect = widgetRect;
         if (IsFrameRTL(aFrame)) {
           checkBGRect.left = checkBGRect.right-checkboxBGSize.cx;
         } else {
@@ -2413,17 +2425,17 @@ nsresult nsNativeThemeWin::ClassicGetThe
     case NS_THEME_BUTTON: {
       PRInt32 contentState;
 
       aPart = DFC_BUTTON;
       aState = DFCS_BUTTONPUSH;
       aFocused = PR_FALSE;
 
       contentState = GetContentState(aFrame, aWidgetType);
-      if (IsDisabled(aFrame))
+      if (contentState & NS_EVENT_STATE_DISABLED)
         aState |= DFCS_INACTIVE;
       else if (IsOpenButton(aFrame))
         aState |= DFCS_PUSHED;
       else if (IsCheckedButton(aFrame))
         aState |= DFCS_CHECKED;
       else {
         if (contentState & NS_EVENT_STATE_ACTIVE && contentState & NS_EVENT_STATE_HOVER) {
           aState |= DFCS_PUSHED;
@@ -2473,49 +2485,50 @@ nsresult nsNativeThemeWin::ClassicGetThe
       }
 
       contentState = GetContentState(aFrame, aWidgetType);
       if (!content->IsXUL() &&
           (contentState & NS_EVENT_STATE_FOCUS)) {
         aFocused = PR_TRUE;
       }
 
-      if (IsDisabled(aFrame)) {
+      if (contentState & NS_EVENT_STATE_DISABLED) {
         aState |= DFCS_INACTIVE;
       } else if (contentState & NS_EVENT_STATE_ACTIVE &&
                  contentState & NS_EVENT_STATE_HOVER) {
         aState |= DFCS_PUSHED;
       }
 
       return NS_OK;
     }
     case NS_THEME_MENUITEM:
     case NS_THEME_CHECKMENUITEM:
     case NS_THEME_RADIOMENUITEM: {
       PRBool isTopLevel = PR_FALSE;
       PRBool isOpen = PR_FALSE;
       PRBool isContainer = PR_FALSE;
       nsIMenuFrame *menuFrame = do_QueryFrame(aFrame);
+      PRInt32 eventState = GetContentState(aFrame, aWidgetType);
 
       // We indicate top-level-ness using aPart. 0 is a normal menu item,
       // 1 is a top-level menu item. The state of the item is composed of
       // DFCS_* flags only.
       aPart = 0;
       aState = 0;
 
       if (menuFrame) {
         // If this is a real menu item, we should check if it is part of the
         // main menu bar or not, and if it is a container, as these affect
         // rendering.
         isTopLevel = menuFrame->IsOnMenuBar();
         isOpen = menuFrame->IsOpen();
         isContainer = menuFrame->IsMenu();
       }
 
-      if (IsDisabled(aFrame))
+      if (eventState & NS_EVENT_STATE_DISABLED)
         aState |= DFCS_INACTIVE;
 
       if (isTopLevel) {
         aPart = 1;
         if (isOpen)
           aState |= DFCS_PUSHED;
       }
 
@@ -2523,17 +2536,19 @@ nsresult nsNativeThemeWin::ClassicGetThe
         aState |= DFCS_HOT;
 
       return NS_OK;
     }
     case NS_THEME_MENUCHECKBOX:
     case NS_THEME_MENURADIO:
     case NS_THEME_MENUARROW: {
       aState = 0;
-      if (IsDisabled(aFrame))
+      PRInt32 eventState = GetContentState(aFrame, aWidgetType);
+
+      if (eventState & NS_EVENT_STATE_DISABLED)
         aState |= DFCS_INACTIVE;
       if (IsMenuActive(aFrame, aWidgetType))
         aState |= DFCS_HOT;
 
       if (aWidgetType == NS_THEME_MENUCHECKBOX || aWidgetType == NS_THEME_MENURADIO) {
         if (IsCheckedButton(aFrame))
           aState |= DFCS_CHECKED;
       } else if (IsFrameRTL(aFrame)) {
@@ -2580,17 +2595,19 @@ nsresult nsNativeThemeWin::ClassicGetThe
       PRBool isHTML = IsHTMLContent(aFrame);
       PRBool isMenulist = !isHTML && parentFrame->GetType() == nsWidgetAtoms::menuFrame;
       PRBool isOpen = PR_FALSE;
 
       // HTML select and XUL menulist dropdown buttons get state from the parent.
       if (isHTML || isMenulist)
         aFrame = parentFrame;
 
-      if (IsDisabled(aFrame)) {
+      PRInt32 eventState = GetContentState(aFrame, aWidgetType);
+
+      if (eventState & NS_EVENT_STATE_DISABLED) {
         aState |= DFCS_INACTIVE;
         return NS_OK;
       }
 
 #ifndef WINCE
       if (isHTML) {
         nsIComboboxControlFrame* ccf = do_QueryFrame(aFrame);
         isOpen = (ccf && ccf->IsDroppedDown());
@@ -2598,77 +2615,73 @@ nsresult nsNativeThemeWin::ClassicGetThe
       else
         isOpen = IsOpenButton(aFrame);
 
       // XXX Button should look active until the mouse is released, but
       //     without making it look active when the popup is clicked.
       if (isOpen && (isHTML || isMenulist))
         return NS_OK;
 
-      PRInt32 eventState = GetContentState(aFrame, aWidgetType);
-
       // Dropdown button active state doesn't need :hover.
       if (eventState & NS_EVENT_STATE_ACTIVE)
         aState |= DFCS_PUSHED | DFCS_FLAT;
 #endif
 
       return NS_OK;
     }
     case NS_THEME_SCROLLBAR_BUTTON_UP:
     case NS_THEME_SCROLLBAR_BUTTON_DOWN:
     case NS_THEME_SCROLLBAR_BUTTON_LEFT:
     case NS_THEME_SCROLLBAR_BUTTON_RIGHT: {
-      PRInt32 contentState;
+      PRInt32 contentState = GetContentState(aFrame, aWidgetType);
 
       aPart = DFC_SCROLL;
       switch (aWidgetType) {
         case NS_THEME_SCROLLBAR_BUTTON_UP:
           aState = DFCS_SCROLLUP;
           break;
         case NS_THEME_SCROLLBAR_BUTTON_DOWN:
           aState = DFCS_SCROLLDOWN;
           break;
         case NS_THEME_SCROLLBAR_BUTTON_LEFT:
           aState = DFCS_SCROLLLEFT;
           break;
         case NS_THEME_SCROLLBAR_BUTTON_RIGHT:
           aState = DFCS_SCROLLRIGHT;
           break;
-      }      
-      
-      if (IsDisabled(aFrame))
+      }
+
+      if (contentState & NS_EVENT_STATE_DISABLED)
         aState |= DFCS_INACTIVE;
       else {
-        contentState = GetContentState(aFrame, aWidgetType);
 #ifndef WINCE
         if (contentState & NS_EVENT_STATE_HOVER && contentState & NS_EVENT_STATE_ACTIVE)
           aState |= DFCS_PUSHED | DFCS_FLAT;      
 #endif
       }
 
       return NS_OK;
     }
     case NS_THEME_SPINNER_UP_BUTTON:
     case NS_THEME_SPINNER_DOWN_BUTTON: {
-      PRInt32 contentState;
+      PRInt32 contentState = GetContentState(aFrame, aWidgetType);
 
       aPart = DFC_SCROLL;
       switch (aWidgetType) {
         case NS_THEME_SPINNER_UP_BUTTON:
           aState = DFCS_SCROLLUP;
           break;
         case NS_THEME_SPINNER_DOWN_BUTTON:
           aState = DFCS_SCROLLDOWN;
           break;
-      }      
-      
-      if (IsDisabled(aFrame))
+      }
+
+      if (contentState & NS_EVENT_STATE_DISABLED)
         aState |= DFCS_INACTIVE;
       else {
-        contentState = GetContentState(aFrame, aWidgetType);
         if (contentState & NS_EVENT_STATE_HOVER && contentState & NS_EVENT_STATE_ACTIVE)
           aState |= DFCS_PUSHED;
       }
 
       return NS_OK;    
     }
     case NS_THEME_RESIZER:    
       aPart = DFC_SCROLL;
@@ -2988,19 +3001,20 @@ RENDER_AGAIN:
     // Draw controls with 2px 3D inset border
     case NS_THEME_TEXTFIELD:
     case NS_THEME_TEXTFIELD_MULTILINE:
     case NS_THEME_LISTBOX:
     case NS_THEME_DROPDOWN:
     case NS_THEME_DROPDOWN_TEXTFIELD: {
       // Draw inset edge
       ::DrawEdge(hdc, &widgetRect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
+      PRInt32 eventState = GetContentState(aFrame, aWidgetType);
 
       // Fill in background
-      if (IsDisabled(aFrame) ||
+      if ((eventState & NS_EVENT_STATE_DISABLED) ||
           (aFrame->GetContent()->IsXUL() &&
            IsReadOnly(aFrame)))
         ::FillRect(hdc, &widgetRect, (HBRUSH) (COLOR_BTNFACE+1));
       else
         ::FillRect(hdc, &widgetRect, (HBRUSH) (COLOR_WINDOW+1));
 
       break;
     }
@@ -3049,24 +3063,27 @@ RENDER_AGAIN:
     }
     // Draw scrollbar thumb
     case NS_THEME_SCROLLBAR_THUMB_VERTICAL:
     case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL:
       ::DrawEdge(hdc, &widgetRect, EDGE_RAISED, BF_RECT | BF_MIDDLE);
 
       break;
     case NS_THEME_SCALE_THUMB_VERTICAL:
-    case NS_THEME_SCALE_THUMB_HORIZONTAL:
+    case NS_THEME_SCALE_THUMB_HORIZONTAL: {
+      PRInt32 eventState = GetContentState(aFrame, aWidgetType);
+
       ::DrawEdge(hdc, &widgetRect, EDGE_RAISED, BF_RECT | BF_SOFT | BF_MIDDLE | BF_ADJUST);
-      if (IsDisabled(aFrame)) {
+      if (NS_EVENT_STATE_DISABLED) {
         DrawCheckedRect(hdc, widgetRect, COLOR_3DFACE, COLOR_3DHILIGHT,
                         (HBRUSH) COLOR_3DHILIGHT);
       }
 
       break;
+    }
     // Draw scrollbar track background
     case NS_THEME_SCROLLBAR_TRACK_VERTICAL:
     case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL: {
 
       // Windows fills in the scrollbar track differently 
       // depending on whether these are equal
       DWORD color3D, colorScrollbar, colorWindow;
 
--- a/widget/src/xpwidgets/nsNativeTheme.h
+++ b/widget/src/xpwidgets/nsNativeTheme.h
@@ -75,21 +75,16 @@ class nsNativeTheme
   // Returns whether the widget is already styled by content
   // Normally called from ThemeSupportsWidget to turn off native theming
   // for elements that are already styled.
   PRBool IsWidgetStyled(nsPresContext* aPresContext, nsIFrame* aFrame,
                         PRUint8 aWidgetType);                                              
 
   // Accessors to widget-specific state information
 
-  // all widgets:
-  PRBool IsDisabled(nsIFrame* aFrame) {
-    return CheckBooleanAttr(aFrame, nsWidgetAtoms::disabled);
-  }
-
   // RTL chrome direction
   PRBool IsFrameRTL(nsIFrame* aFrame);
 
   // button:
   PRBool IsDefaultButton(nsIFrame* aFrame) {
     return CheckBooleanAttr(aFrame, nsWidgetAtoms::_default);
   }