diff options
| author | simon <none@none> | 2014-02-26 12:49:29 -0800 | 
|---|---|---|
| committer | simon <none@none> | 2014-02-26 12:49:29 -0800 | 
| commit | 100b9154dd00187079529dab7b4076bdac92c027 (patch) | |
| tree | 2c566ee79a5d358b94fb1d99e00dae9941858417 | |
| parent | 6f1df3172ebf377ac0f303022c930a0a1da2ed43 (diff) | |
MAINT-3555 : crash in LLPanel::~LLPanel() on shutdown.  Fixes to be paranoid
about the return type for calls to LLView::getParent(): never assume a down
cast is possible.
| -rwxr-xr-x | indra/llui/lldraghandle.cpp | 5 | ||||
| -rwxr-xr-x | indra/llui/llfloater.cpp | 29 | ||||
| -rwxr-xr-x | indra/llui/llmenugl.cpp | 99 | 
3 files changed, 99 insertions, 34 deletions
| diff --git a/indra/llui/lldraghandle.cpp b/indra/llui/lldraghandle.cpp index 5f69c6af31..304d21d0df 100755 --- a/indra/llui/lldraghandle.cpp +++ b/indra/llui/lldraghandle.cpp @@ -315,14 +315,15 @@ BOOL LLDragHandle::handleHover(S32 x, S32 y, MASK mask)  		S32 delta_y = screen_y - mDragLastScreenY;  		// if dragging a docked floater we want to undock -		if (((LLFloater*)getParent())->isDocked()) +		LLFloater * parent = dynamic_cast<LLFloater *>(getParent()); +		if (parent && parent->isDocked())  		{  			const S32 SLOP = 12;  			if (delta_y <= -SLOP ||   				delta_y >= SLOP)  			{ -				((LLFloater*)getParent())->setDocked(false, false); +				parent->setDocked(false, false);  				return TRUE;  			}  			else diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index cc25bfcfeb..e6db65916e 100755 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -1146,7 +1146,11 @@ void LLFloater::handleReshape(const LLRect& new_rect, bool by_user)  	if (by_user && !getHost())  	{ -		static_cast<LLFloaterView*>(getParent())->adjustToFitScreen(this, !isMinimized()); +		LLFloaterView * floaterVp = dynamic_cast<LLFloaterView*>(getParent()); +		if (floaterVp) +		{ +			floaterVp->adjustToFitScreen(this, !isMinimized()); +		}  	}  	// if not minimized, adjust all snapped dependents to new shape @@ -1357,7 +1361,8 @@ void LLFloater::setFocus( BOOL b )  	if (b)  	{  		// only push focused floaters to front of stack if not in midst of ctrl-tab cycle -		if (!getHost() && !((LLFloaterView*)getParent())->getCycleMode()) +		LLFloaterView * parent = dynamic_cast<LLFloaterView *>(getParent()); +		if (!getHost() && parent && !parent->getCycleMode())  		{  			if (!isFrontmost())  			{ @@ -1627,7 +1632,7 @@ void LLFloater::bringToFront( S32 x, S32 y )  		}  		else  		{ -			LLFloaterView* parent = (LLFloaterView*) getParent(); +			LLFloaterView* parent = dynamic_cast<LLFloaterView*>( getParent() );  			if (parent)  			{  				parent->bringToFront( this ); @@ -1666,7 +1671,11 @@ void LLFloater::setFrontmost(BOOL take_focus)  	{  		// there are more than one floater view  		// so we need to query our parent directly -		((LLFloaterView*)getParent())->bringToFront(this, take_focus); +		LLFloaterView * parent = dynamic_cast<LLFloaterView*>( getParent() ); +		if (parent) +		{ +			parent->bringToFront(this, take_focus); +		}  		// Make sure to set the appropriate transparency type (STORM-732).  		updateTransparency(hasFocus() || getIsChrome() ? TT_ACTIVE : TT_INACTIVE); @@ -2396,6 +2405,9 @@ LLRect LLFloaterView::findNeighboringPosition( LLFloater* reference_floater, LLF  void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)  { +	if (!child) +		return; +  	if (mFrontChild == child)  	{  		if (give_focus && !gFocusMgr.childHasKeyboardFocus(child)) @@ -2874,10 +2886,13 @@ LLFloater *LLFloaterView::getFocusedFloater() const  {  	for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)  	{ -		LLUICtrl* ctrlp = (*child_it)->isCtrl() ? static_cast<LLUICtrl*>(*child_it) : NULL; -		if ( ctrlp && ctrlp->hasFocus() ) +		if ((*child_it)->isCtrl())  		{ -			return static_cast<LLFloater *>(ctrlp); +			LLFloater* ctrlp = dynamic_cast<LLFloater*>(*child_it); +			if ( ctrlp && ctrlp->hasFocus() ) +			{ +				return ctrlp; +			}  		}  	}  	return NULL; diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index f854e1785d..6a57158eaa 100755 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -693,8 +693,11 @@ void LLMenuItemTearOffGL::onCommit()  {  	if (getMenu()->getTornOff())  	{ -		LLTearOffMenu* torn_off_menu = (LLTearOffMenu*)(getMenu()->getParent()); -		torn_off_menu->closeFloater(); +		LLTearOffMenu * torn_off_menu = dynamic_cast<LLTearOffMenu*>(getMenu()->getParent()); +		if (torn_off_menu) +		{ +			torn_off_menu->closeFloater(); +		}  	}  	else  	{ @@ -1097,7 +1100,8 @@ void LLMenuItemBranchGL::setHighlight( BOOL highlight )  	BOOL auto_open = getEnabled() && (!branch->getVisible() || branch->getTornOff());  	// torn off menus don't open sub menus on hover unless they have focus -	if (getMenu()->getTornOff() && !((LLFloater*)getMenu()->getParent())->hasFocus()) +	LLFloater * menu_parent = dynamic_cast<LLFloater *>(getMenu()->getParent()); +	if (getMenu()->getTornOff() && menu_parent && !menu_parent->hasFocus())  	{  		auto_open = FALSE;  	} @@ -1118,7 +1122,11 @@ void LLMenuItemBranchGL::setHighlight( BOOL highlight )  	{  		if (branch->getTornOff())  		{ -			((LLFloater*)branch->getParent())->setFocus(FALSE); +			LLFloater * branch_parent = dynamic_cast<LLFloater *>(branch->getParent()); +			if (branch_parent) +			{ +				branch_parent->setFocus(FALSE); +			}  			branch->clearHoverItem();  		}  		else @@ -1175,11 +1183,19 @@ BOOL LLMenuItemBranchGL::handleKeyHere( KEY key, MASK mask )  			BOOL handled = branch->clearHoverItem();  			if (branch->getTornOff())  			{ -				((LLFloater*)branch->getParent())->setFocus(FALSE); +				LLFloater * branch_parent = dynamic_cast<LLFloater *>(branch->getParent()); +				if (branch_parent) +				{ +					branch_parent->setFocus(FALSE); +				}  			}  			if (handled && getMenu()->getTornOff())  			{ -				((LLFloater*)getMenu()->getParent())->setFocus(TRUE); +				LLFloater * menu_parent = dynamic_cast<LLFloater *>(getMenu()->getParent()); +				if (menu_parent) +				{ +					menu_parent->setFocus(TRUE); +				}  			}  			return handled;  		} @@ -1219,9 +1235,13 @@ void LLMenuItemBranchGL::openMenu()  	if (branch->getTornOff())  	{ -		gFloaterView->bringToFront((LLFloater*)branch->getParent()); -		// this might not be necessary, as torn off branches don't get focus and hence no highligth -		branch->highlightNextItem(NULL); +		LLFloater * branch_parent = dynamic_cast<LLFloater *>(branch->getParent()); +		if (branch_parent) +		{ +			gFloaterView->bringToFront(branch_parent); +			// this might not be necessary, as torn off branches don't get focus and hence no highligth +			branch->highlightNextItem(NULL); +		}  	}  	else if( !branch->getVisible() )  	{ @@ -1348,7 +1368,11 @@ void LLMenuItemBranchDownGL::openMenu( void )  	{  		if (branch->getTornOff())  		{ -			gFloaterView->bringToFront((LLFloater*)branch->getParent()); +			LLFloater * branch_parent = dynamic_cast<LLFloater *>(branch->getParent()); +			if (branch_parent) +			{ +				gFloaterView->bringToFront(branch_parent); +			}  		}  		else  		{ @@ -1403,7 +1427,11 @@ void LLMenuItemBranchDownGL::setHighlight( BOOL highlight )  	{  		if (branch->getTornOff())  		{ -			((LLFloater*)branch->getParent())->setFocus(FALSE); +			LLFloater * branch_parent = dynamic_cast<LLFloater *>(branch->getParent()); +			if (branch_parent) +			{ +				branch_parent->setFocus(FALSE); +			}  			branch->clearHoverItem();  		}  		else @@ -1826,20 +1854,28 @@ BOOL LLMenuGL::jumpKeysActive()  {  	LLMenuItemGL* highlighted_item = getHighlightedItem();  	BOOL active = getVisible() && getEnabled(); -	if (getTornOff()) -	{ -		// activation of jump keys on torn off menus controlled by keyboard focus -		active = active && ((LLFloater*)getParent())->hasFocus(); -	} -	else +	if (active)  	{ -		// Are we the terminal active menu? -		// Yes, if parent menu item deems us to be active (just being visible is sufficient for top-level menus) -		// and we don't have a highlighted menu item pointing to an active sub-menu -		active = active && (!getParentMenuItem() || getParentMenuItem()->isActive()) // I have a parent that is active... -		                && (!highlighted_item || !highlighted_item->isActive()); //... but no child that is active +		if (getTornOff()) +		{ +			// activation of jump keys on torn off menus controlled by keyboard focus +			LLFloater * parent = dynamic_cast<LLFloater *>(getParent()); +			if (parent) +			{ +				active = parent->hasFocus(); +			} +		} +		else +		{ +			// Are we the terminal active menu? +			// Yes, if parent menu item deems us to be active (just being visible is sufficient for top-level menus) +			// and we don't have a highlighted menu item pointing to an active sub-menu +			active = (!getParentMenuItem() || getParentMenuItem()->isActive()) // I have a parent that is active... +					&& (!highlighted_item || !highlighted_item->isActive()); //... but no child that is active +		}  	} +  	return active;  } @@ -1855,7 +1891,12 @@ BOOL LLMenuGL::isOpen()  			return TRUE;  		}  		// otherwise we are only active if we have keyboard focus -		return ((LLFloater*)getParent())->hasFocus(); +		LLFloater * parent = dynamic_cast<LLFloater *>(getParent()); +		if (parent) +		{ +			return parent->hasFocus(); +		} +		return FALSE;  	}  	else  	{ @@ -2714,7 +2755,11 @@ LLMenuItemGL* LLMenuGL::highlightNextItem(LLMenuItemGL* cur_item, BOOL skip_disa  	// same as giving focus to it  	if (!cur_item && getTornOff())  	{ -		((LLFloater*)getParent())->setFocus(TRUE); +		LLFloater * parent = dynamic_cast<LLFloater *>(getParent()); +		if (parent) +		{ +			parent->setFocus(TRUE); +		}  	}  	// Current item position in the items list @@ -2816,7 +2861,11 @@ LLMenuItemGL* LLMenuGL::highlightPrevItem(LLMenuItemGL* cur_item, BOOL skip_disa  	// same as giving focus to it  	if (!cur_item && getTornOff())  	{ -		((LLFloater*)getParent())->setFocus(TRUE); +		LLFloater * parent = dynamic_cast<LLFloater *>(getParent()); +		if (parent) +		{ +			parent->setFocus(TRUE); +		}  	}  	// Current item reverse position from the end of the list | 
