--- a/widget/gtk/nsNativeThemeGTK.cpp
+++ b/widget/gtk/nsNativeThemeGTK.cpp
@@ -188,217 +188,211 @@ static bool ShouldScrollbarButtonBeDisab
bool
nsNativeThemeGTK::GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame,
WidgetNodeType& aGtkWidgetType,
GtkWidgetState* aState,
gint* aWidgetFlags)
{
if (aState) {
- if (!aFrame) {
- // reset the entire struct to zero
- memset(aState, 0, sizeof(GtkWidgetState));
- } else {
-
- // For XUL checkboxes and radio buttons, the state of the parent
- // determines our state.
- nsIFrame *stateFrame = aFrame;
- if (aFrame && ((aWidgetFlags && (aWidgetType == NS_THEME_CHECKBOX ||
- aWidgetType == NS_THEME_RADIO)) ||
- aWidgetType == NS_THEME_CHECKBOX_LABEL ||
- aWidgetType == NS_THEME_RADIO_LABEL)) {
+ // For XUL checkboxes and radio buttons, the state of the parent
+ // determines our state.
+ nsIFrame *stateFrame = aFrame;
+ if (aFrame && ((aWidgetFlags && (aWidgetType == NS_THEME_CHECKBOX ||
+ aWidgetType == NS_THEME_RADIO)) ||
+ aWidgetType == NS_THEME_CHECKBOX_LABEL ||
+ aWidgetType == NS_THEME_RADIO_LABEL)) {
- nsIAtom* atom = nullptr;
- if (IsFrameContentNodeInNamespace(aFrame, kNameSpaceID_XUL)) {
- if (aWidgetType == NS_THEME_CHECKBOX_LABEL ||
- aWidgetType == NS_THEME_RADIO_LABEL) {
- // Adjust stateFrame so GetContentState finds the correct state.
- stateFrame = aFrame = aFrame->GetParent()->GetParent();
- } else {
- // GetContentState knows to look one frame up for radio/checkbox
- // widgets, so don't adjust stateFrame here.
- aFrame = aFrame->GetParent();
- }
- if (aWidgetFlags) {
- if (!atom) {
- atom = (aWidgetType == NS_THEME_CHECKBOX ||
- aWidgetType == NS_THEME_CHECKBOX_LABEL) ? nsGkAtoms::checked
- : nsGkAtoms::selected;
- }
- *aWidgetFlags = CheckBooleanAttr(aFrame, atom);
- }
+ nsIAtom* atom = nullptr;
+ if (IsFrameContentNodeInNamespace(aFrame, kNameSpaceID_XUL)) {
+ if (aWidgetType == NS_THEME_CHECKBOX_LABEL ||
+ aWidgetType == NS_THEME_RADIO_LABEL) {
+ // Adjust stateFrame so GetContentState finds the correct state.
+ stateFrame = aFrame = aFrame->GetParent()->GetParent();
} else {
- if (aWidgetFlags) {
- nsCOMPtr<nsIDOMHTMLInputElement> inputElt(do_QueryInterface(aFrame->GetContent()));
- *aWidgetFlags = 0;
- if (inputElt) {
- bool isHTMLChecked;
- inputElt->GetChecked(&isHTMLChecked);
- if (isHTMLChecked)
- *aWidgetFlags |= MOZ_GTK_WIDGET_CHECKED;
- }
+ // GetContentState knows to look one frame up for radio/checkbox
+ // widgets, so don't adjust stateFrame here.
+ aFrame = aFrame->GetParent();
+ }
+ if (aWidgetFlags) {
+ if (!atom) {
+ atom = (aWidgetType == NS_THEME_CHECKBOX ||
+ aWidgetType == NS_THEME_CHECKBOX_LABEL) ? nsGkAtoms::checked
+ : nsGkAtoms::selected;
+ }
+ *aWidgetFlags = CheckBooleanAttr(aFrame, atom);
+ }
+ } else {
+ if (aWidgetFlags) {
+ nsCOMPtr<nsIDOMHTMLInputElement> inputElt(do_QueryInterface(aFrame->GetContent()));
+ *aWidgetFlags = 0;
+ if (inputElt) {
+ bool isHTMLChecked;
+ inputElt->GetChecked(&isHTMLChecked);
+ if (isHTMLChecked)
+ *aWidgetFlags |= MOZ_GTK_WIDGET_CHECKED;
+ }
- if (GetIndeterminate(aFrame))
- *aWidgetFlags |= MOZ_GTK_WIDGET_INCONSISTENT;
- }
+ if (GetIndeterminate(aFrame))
+ *aWidgetFlags |= MOZ_GTK_WIDGET_INCONSISTENT;
}
- } else if (aWidgetType == NS_THEME_TOOLBAR_BUTTON_DROPDOWN ||
- aWidgetType == NS_THEME_TREEVIEW_HEADER_SORTARROW ||
- aWidgetType == NS_THEME_BUTTON_ARROW_PREVIOUS ||
- aWidgetType == NS_THEME_BUTTON_ARROW_NEXT ||
- 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();
}
+ } else if (aWidgetType == NS_THEME_TOOLBAR_BUTTON_DROPDOWN ||
+ aWidgetType == NS_THEME_TREEVIEW_HEADER_SORTARROW ||
+ aWidgetType == NS_THEME_BUTTON_ARROW_PREVIOUS ||
+ aWidgetType == NS_THEME_BUTTON_ARROW_NEXT ||
+ 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();
+ }
+
+ EventStates eventState = GetContentState(stateFrame, aWidgetType);
- EventStates eventState = GetContentState(stateFrame, aWidgetType);
+ aState->disabled = IsDisabled(aFrame, eventState) || IsReadOnly(aFrame);
+ aState->active = eventState.HasState(NS_EVENT_STATE_ACTIVE);
+ aState->focused = eventState.HasState(NS_EVENT_STATE_FOCUS);
+ aState->inHover = eventState.HasState(NS_EVENT_STATE_HOVER);
+ aState->isDefault = IsDefaultButton(aFrame);
+ aState->canDefault = FALSE; // XXX fix me
+ aState->depressed = FALSE;
- aState->disabled = IsDisabled(aFrame, eventState) || IsReadOnly(aFrame);
- aState->active = eventState.HasState(NS_EVENT_STATE_ACTIVE);
- aState->focused = eventState.HasState(NS_EVENT_STATE_FOCUS);
- aState->inHover = eventState.HasState(NS_EVENT_STATE_HOVER);
- aState->isDefault = IsDefaultButton(aFrame);
- aState->canDefault = FALSE; // XXX fix me
- aState->depressed = FALSE;
+ if (aWidgetType == NS_THEME_FOCUS_OUTLINE) {
+ aState->disabled = FALSE;
+ aState->active = FALSE;
+ aState->inHover = FALSE;
+ aState->isDefault = FALSE;
+ aState->canDefault = FALSE;
- if (aWidgetType == NS_THEME_FOCUS_OUTLINE) {
- aState->disabled = FALSE;
- aState->active = FALSE;
- aState->inHover = FALSE;
- aState->isDefault = FALSE;
- aState->canDefault = FALSE;
+ aState->focused = TRUE;
+ aState->depressed = TRUE; // see moz_gtk_entry_paint()
+ } else if (aWidgetType == NS_THEME_BUTTON ||
+ aWidgetType == NS_THEME_TOOLBAR_BUTTON ||
+ aWidgetType == NS_THEME_TOOLBAR_DUAL_BUTTON ||
+ aWidgetType == NS_THEME_TOOLBAR_BUTTON_DROPDOWN ||
+ aWidgetType == NS_THEME_DROPDOWN ||
+ aWidgetType == NS_THEME_DROPDOWN_BUTTON) {
+ aState->active &= aState->inHover;
+ }
- aState->focused = TRUE;
- aState->depressed = TRUE; // see moz_gtk_entry_paint()
- } else if (aWidgetType == NS_THEME_BUTTON ||
- aWidgetType == NS_THEME_TOOLBAR_BUTTON ||
- aWidgetType == NS_THEME_TOOLBAR_DUAL_BUTTON ||
- aWidgetType == NS_THEME_TOOLBAR_BUTTON_DROPDOWN ||
- aWidgetType == NS_THEME_DROPDOWN ||
- aWidgetType == NS_THEME_DROPDOWN_BUTTON) {
- aState->active &= aState->inHover;
+ if (IsFrameContentNodeInNamespace(aFrame, kNameSpaceID_XUL)) {
+ // For these widget types, some element (either a child or parent)
+ // actually has element focus, so we check the focused attribute
+ // to see whether to draw in the focused state.
+ if (aWidgetType == NS_THEME_NUMBER_INPUT ||
+ aWidgetType == NS_THEME_TEXTFIELD ||
+ aWidgetType == NS_THEME_TEXTFIELD_MULTILINE ||
+ aWidgetType == NS_THEME_DROPDOWN_TEXTFIELD ||
+ aWidgetType == NS_THEME_SPINNER_TEXTFIELD ||
+ aWidgetType == NS_THEME_RADIO_CONTAINER ||
+ aWidgetType == NS_THEME_RADIO_LABEL) {
+ aState->focused = IsFocused(aFrame);
+ } else if (aWidgetType == NS_THEME_RADIO ||
+ aWidgetType == NS_THEME_CHECKBOX) {
+ // In XUL, checkboxes and radios shouldn't have focus rings, their labels do
+ aState->focused = FALSE;
}
- if (IsFrameContentNodeInNamespace(aFrame, kNameSpaceID_XUL)) {
- // For these widget types, some element (either a child or parent)
- // actually has element focus, so we check the focused attribute
- // to see whether to draw in the focused state.
- if (aWidgetType == NS_THEME_NUMBER_INPUT ||
- aWidgetType == NS_THEME_TEXTFIELD ||
- aWidgetType == NS_THEME_TEXTFIELD_MULTILINE ||
- aWidgetType == NS_THEME_DROPDOWN_TEXTFIELD ||
- aWidgetType == NS_THEME_SPINNER_TEXTFIELD ||
- aWidgetType == NS_THEME_RADIO_CONTAINER ||
- aWidgetType == NS_THEME_RADIO_LABEL) {
- aState->focused = IsFocused(aFrame);
- } else if (aWidgetType == NS_THEME_RADIO ||
- aWidgetType == NS_THEME_CHECKBOX) {
- // In XUL, checkboxes and radios shouldn't have focus rings, their labels do
- aState->focused = FALSE;
- }
+ if (aWidgetType == NS_THEME_SCROLLBAR_THUMB_VERTICAL ||
+ aWidgetType == NS_THEME_SCROLLBAR_THUMB_HORIZONTAL) {
+ // for scrollbars we need to go up two to go from the thumb to
+ // the slider to the actual scrollbar object
+ nsIFrame *tmpFrame = aFrame->GetParent()->GetParent();
- if (aWidgetType == NS_THEME_SCROLLBAR_THUMB_VERTICAL ||
- aWidgetType == NS_THEME_SCROLLBAR_THUMB_HORIZONTAL) {
- // for scrollbars we need to go up two to go from the thumb to
- // the slider to the actual scrollbar object
- nsIFrame *tmpFrame = aFrame->GetParent()->GetParent();
-
- aState->curpos = CheckIntAttr(tmpFrame, nsGkAtoms::curpos, 0);
- aState->maxpos = CheckIntAttr(tmpFrame, nsGkAtoms::maxpos, 100);
+ aState->curpos = CheckIntAttr(tmpFrame, nsGkAtoms::curpos, 0);
+ aState->maxpos = CheckIntAttr(tmpFrame, nsGkAtoms::maxpos, 100);
- if (CheckBooleanAttr(aFrame, nsGkAtoms::active)) {
- aState->active = TRUE;
- }
+ if (CheckBooleanAttr(aFrame, nsGkAtoms::active)) {
+ aState->active = TRUE;
}
+ }
- if (aWidgetType == NS_THEME_SCROLLBAR_BUTTON_UP ||
- aWidgetType == NS_THEME_SCROLLBAR_BUTTON_DOWN ||
- aWidgetType == NS_THEME_SCROLLBAR_BUTTON_LEFT ||
- aWidgetType == NS_THEME_SCROLLBAR_BUTTON_RIGHT) {
- // set the state to disabled when the scrollbar is scrolled to
- // the beginning or the end, depending on the button type.
- int32_t curpos = CheckIntAttr(aFrame, nsGkAtoms::curpos, 0);
- int32_t maxpos = CheckIntAttr(aFrame, nsGkAtoms::maxpos, 100);
- if (ShouldScrollbarButtonBeDisabled(curpos, maxpos, aWidgetType)) {
- aState->disabled = true;
- }
-
- // In order to simulate native GTK scrollbar click behavior,
- // we set the active attribute on the element to true if it's
- // pressed with any mouse button.
- // This allows us to show that it's active without setting :active
- else if (CheckBooleanAttr(aFrame, nsGkAtoms::active))
- aState->active = true;
-
- if (aWidgetFlags) {
- *aWidgetFlags = GetScrollbarButtonType(aFrame);
- if (aWidgetType - NS_THEME_SCROLLBAR_BUTTON_UP < 2)
- *aWidgetFlags |= MOZ_GTK_STEPPER_VERTICAL;
- }
+ if (aWidgetType == NS_THEME_SCROLLBAR_BUTTON_UP ||
+ aWidgetType == NS_THEME_SCROLLBAR_BUTTON_DOWN ||
+ aWidgetType == NS_THEME_SCROLLBAR_BUTTON_LEFT ||
+ aWidgetType == NS_THEME_SCROLLBAR_BUTTON_RIGHT) {
+ // set the state to disabled when the scrollbar is scrolled to
+ // the beginning or the end, depending on the button type.
+ int32_t curpos = CheckIntAttr(aFrame, nsGkAtoms::curpos, 0);
+ int32_t maxpos = CheckIntAttr(aFrame, nsGkAtoms::maxpos, 100);
+ if (ShouldScrollbarButtonBeDisabled(curpos, maxpos, aWidgetType)) {
+ aState->disabled = true;
}
- // menu item state is determined by the attribute "_moz-menuactive",
- // and not by the mouse hovering (accessibility). as a special case,
- // menus which are children of a menu bar are only marked as prelight
- // if they are open, not on normal hover.
+ // In order to simulate native GTK scrollbar click behavior,
+ // we set the active attribute on the element to true if it's
+ // pressed with any mouse button.
+ // This allows us to show that it's active without setting :active
+ else if (CheckBooleanAttr(aFrame, nsGkAtoms::active))
+ aState->active = true;
- if (aWidgetType == NS_THEME_MENUITEM ||
- aWidgetType == NS_THEME_CHECKMENUITEM ||
- aWidgetType == NS_THEME_RADIOMENUITEM ||
- aWidgetType == NS_THEME_MENUSEPARATOR ||
- aWidgetType == NS_THEME_MENUARROW) {
- bool isTopLevel = false;
- nsMenuFrame *menuFrame = do_QueryFrame(aFrame);
- if (menuFrame) {
- isTopLevel = menuFrame->IsOnMenuBar();
- }
+ if (aWidgetFlags) {
+ *aWidgetFlags = GetScrollbarButtonType(aFrame);
+ if (aWidgetType - NS_THEME_SCROLLBAR_BUTTON_UP < 2)
+ *aWidgetFlags |= MOZ_GTK_STEPPER_VERTICAL;
+ }
+ }
+
+ // menu item state is determined by the attribute "_moz-menuactive",
+ // and not by the mouse hovering (accessibility). as a special case,
+ // menus which are children of a menu bar are only marked as prelight
+ // if they are open, not on normal hover.
- if (isTopLevel) {
- aState->inHover = menuFrame->IsOpen();
- *aWidgetFlags |= MOZ_TOPLEVEL_MENU_ITEM;
- } else {
- aState->inHover = CheckBooleanAttr(aFrame, nsGkAtoms::menuactive);
- *aWidgetFlags &= ~MOZ_TOPLEVEL_MENU_ITEM;
- }
+ if (aWidgetType == NS_THEME_MENUITEM ||
+ aWidgetType == NS_THEME_CHECKMENUITEM ||
+ aWidgetType == NS_THEME_RADIOMENUITEM ||
+ aWidgetType == NS_THEME_MENUSEPARATOR ||
+ aWidgetType == NS_THEME_MENUARROW) {
+ bool isTopLevel = false;
+ nsMenuFrame *menuFrame = do_QueryFrame(aFrame);
+ if (menuFrame) {
+ isTopLevel = menuFrame->IsOnMenuBar();
+ }
- aState->active = FALSE;
+ if (isTopLevel) {
+ aState->inHover = menuFrame->IsOpen();
+ *aWidgetFlags |= MOZ_TOPLEVEL_MENU_ITEM;
+ } else {
+ aState->inHover = CheckBooleanAttr(aFrame, nsGkAtoms::menuactive);
+ *aWidgetFlags &= ~MOZ_TOPLEVEL_MENU_ITEM;
+ }
+
+ aState->active = FALSE;
- if (aWidgetType == NS_THEME_CHECKMENUITEM ||
- aWidgetType == NS_THEME_RADIOMENUITEM) {
- *aWidgetFlags = 0;
- if (aFrame && aFrame->GetContent()) {
- *aWidgetFlags = aFrame->GetContent()->
- AttrValueIs(kNameSpaceID_None, nsGkAtoms::checked,
- nsGkAtoms::_true, eIgnoreCase);
- }
+ if (aWidgetType == NS_THEME_CHECKMENUITEM ||
+ aWidgetType == NS_THEME_RADIOMENUITEM) {
+ *aWidgetFlags = 0;
+ if (aFrame && aFrame->GetContent()) {
+ *aWidgetFlags = aFrame->GetContent()->
+ AttrValueIs(kNameSpaceID_None, nsGkAtoms::checked,
+ nsGkAtoms::_true, eIgnoreCase);
}
}
+ }
- // A button with drop down menu open or an activated toggle button
- // should always appear depressed.
- if (aWidgetType == NS_THEME_BUTTON ||
- aWidgetType == NS_THEME_TOOLBAR_BUTTON ||
- aWidgetType == NS_THEME_TOOLBAR_DUAL_BUTTON ||
- aWidgetType == NS_THEME_TOOLBAR_BUTTON_DROPDOWN ||
- aWidgetType == NS_THEME_DROPDOWN ||
- aWidgetType == NS_THEME_DROPDOWN_BUTTON) {
- bool menuOpen = IsOpenButton(aFrame);
- aState->depressed = IsCheckedButton(aFrame) || menuOpen;
- // we must not highlight buttons with open drop down menus on hover.
- aState->inHover = aState->inHover && !menuOpen;
- }
+ // A button with drop down menu open or an activated toggle button
+ // should always appear depressed.
+ if (aWidgetType == NS_THEME_BUTTON ||
+ aWidgetType == NS_THEME_TOOLBAR_BUTTON ||
+ aWidgetType == NS_THEME_TOOLBAR_DUAL_BUTTON ||
+ aWidgetType == NS_THEME_TOOLBAR_BUTTON_DROPDOWN ||
+ aWidgetType == NS_THEME_DROPDOWN ||
+ aWidgetType == NS_THEME_DROPDOWN_BUTTON) {
+ bool menuOpen = IsOpenButton(aFrame);
+ aState->depressed = IsCheckedButton(aFrame) || menuOpen;
+ // we must not highlight buttons with open drop down menus on hover.
+ aState->inHover = aState->inHover && !menuOpen;
+ }
- // When the input field of the drop down button has focus, some themes
- // should draw focus for the drop down button as well.
- if (aWidgetType == NS_THEME_DROPDOWN_BUTTON && aWidgetFlags) {
- *aWidgetFlags = CheckBooleanAttr(aFrame, nsGkAtoms::parentfocused);
- }
+ // When the input field of the drop down button has focus, some themes
+ // should draw focus for the drop down button as well.
+ if (aWidgetType == NS_THEME_DROPDOWN_BUTTON && aWidgetFlags) {
+ *aWidgetFlags = CheckBooleanAttr(aFrame, nsGkAtoms::parentfocused);
}
- }
+ }
}
switch (aWidgetType) {
case NS_THEME_BUTTON:
if (aWidgetFlags)
*aWidgetFlags = GTK_RELIEF_NORMAL;
aGtkWidgetType = MOZ_GTK_BUTTON;
break;