Vadim ProductEngine avatar Vadim ProductEngine committed a8f13b3

STORM-1016 FIXED Crash after pressing ctrl-shift-w while there is an undocked sidepanel.

Reason: The shortcut closes all floaters, including those wrapping undocked sidepanels.
The sidepanels get destroyed as well, while they are still referenced by the side tray.

Fix: Dock (i.e. move to side tray) the sidepanel before its floater gets destroyed.

Comments (0)

Files changed (3)


 	// close callback 
 	if (p.close_callback.isProvided())
-		mCloseSignal.connect(initCommitCallback(p.close_callback));
+		setCloseCallback(initCommitCallback(p.close_callback));
 	return mMinimizeSignal->connect(cb); 
+boost::signals2::connection LLFloater::setCloseCallback( const commit_signal_t::slot_type& cb )
+	return mCloseSignal.connect(cb);
 LLFastTimer::DeclareTimer POST_BUILD("Floater Post Build");
 bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::string& filename, LLXMLNodePtr output_node)


 	bool buildFromFile(const std::string &filename, LLXMLNodePtr output_node = NULL);
 	boost::signals2::connection setMinimizeCallback( const commit_signal_t::slot_type& cb );
+	boost::signals2::connection setCloseCallback( const commit_signal_t::slot_type& cb );
 	void initFromParams(const LLFloater::Params& p);
 	bool initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::string& filename, LLXMLNodePtr output_node = NULL);


 class LLSideTrayTab: public LLPanel
+	LOG_CLASS(LLSideTrayTab);
 	friend class LLUICtrlFactory;
 	friend class LLSideTray;
 	void			undock(LLFloater* floater_tab);
 	LLSideTray*		getSideTray();
+	void			onFloaterClose(LLSD::Boolean app_quitting);
 	virtual ~LLSideTrayTab();
 	void			onOpen		(const LLSD& key);
 	void			toggleTabDocked();
+	void			setDocked(bool dock);
+	bool			isDocked() const;
 	BOOL			handleScrollWheel(S32 x, S32 y, S32 clicks);
 	std::string	mDescription;
 	LLView*	mMainPanel;
+	boost::signals2::connection mFloaterCloseConn;
 LLSideTrayTab::LLSideTrayTab(const Params& p)
 	LLFloaterReg::toggleInstance("side_bar_tab", tab_name);
+// Same as toggleTabDocked() apart from making sure that we do exactly what we want.
+void LLSideTrayTab::setDocked(bool dock)
+	if (isDocked() == dock)
+	{
+		llwarns << "Tab " << getName() << " is already " << (dock ? "docked" : "undocked") << llendl;
+		return;
+	}
+	toggleTabDocked();
+bool LLSideTrayTab::isDocked() const
+	return dynamic_cast<LLSideTray*>(getParent()) != NULL;
+void LLSideTrayTab::onFloaterClose(LLSD::Boolean app_quitting)
+	// If user presses Ctrl-Shift-W, handle that gracefully by docking all
+	// undocked tabs before their floaters get destroyed (STORM-1016).
+	// Don't dock on quit for the current dock state to be correctly saved.
+	if (app_quitting) return;
+	lldebugs << "Forcibly docking tab " << getName() << llendl;
+	setDocked(true);
 BOOL LLSideTrayTab::handleScrollWheel(S32 x, S32 y, S32 clicks)
 	// Let children handle the event
+	mFloaterCloseConn.disconnect();
 	reshape(getRect().getWidth(), getRect().getHeight());
+	mFloaterCloseConn = floater_tab->setCloseCallback(boost::bind(&LLSideTrayTab::onFloaterClose, this, _2));
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.