From 2d7ab61c6e496fbee7fd03d015da37c9338c4174 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Fri, 8 Feb 2013 18:40:14 +0100 Subject: [PATCH] Make keyboard focus more robust under closed floaters. --- indra/llui/llfloater.cpp | 2 ++ indra/llui/llfocusmgr.cpp | 35 +++++++++++++++++++++++++++-- indra/llui/llfocusmgr.h | 5 ++++- indra/newview/llfloatersnapshot.cpp | 5 +---- 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 1cbb52dab..b91b0df43 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -911,6 +911,8 @@ void LLFloater::setMinimized(BOOL minimize) // Lose keyboard focus when minimized releaseFocus(); + // Also reset mLockedView and mLastKeyboardFocus, to avoid that we get focus back somehow. + gFocusMgr.removeKeyboardFocusWithoutCallback(this); for (S32 i = 0; i < 4; i++) { diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp index 66834a6a1..7817fd0d5 100644 --- a/indra/llui/llfocusmgr.cpp +++ b/indra/llui/llfocusmgr.cpp @@ -55,6 +55,8 @@ BOOL LLFocusableElement::handleUnicodeChar(llwchar uni_char, BOOL called_from_pa // virtual LLFocusableElement::~LLFocusableElement() { + // Make sure nothing is pointing to us anymore! + gFocusMgr.removeKeyboardFocusWithoutCallback(this); delete mFocusLostCallback; delete mFocusReceivedCallback; delete mFocusChangedCallback; @@ -131,6 +133,7 @@ LLFocusMgr::LLFocusMgr() mKeyboardFocus( NULL ), mLastKeyboardFocus( NULL ), mDefaultKeyboardFocus( NULL ), + mLastDefaultKeyboardFocus( NULL ), mKeystrokesOnly(FALSE), mTopCtrl( NULL ), mAppHasFocus(TRUE), // Macs don't seem to notify us that we've gotten focus, so default to true @@ -171,6 +174,23 @@ void LLFocusMgr::releaseFocusIfNeeded( const LLView* view ) } } +void LLFocusMgr::restoreDefaultKeyboardFocus(LLFocusableElement* current_default_focus) +{ + if (current_default_focus && mDefaultKeyboardFocus == current_default_focus) + { + setDefaultKeyboardFocus(mLastDefaultKeyboardFocus); + mLastDefaultKeyboardFocus = NULL; + } +} + +void LLFocusMgr::restoreKeyboardFocus(LLFocusableElement* current_focus) +{ + if (current_focus && mKeyboardFocus == current_focus) + { + setKeyboardFocus(mLastKeyboardFocus); + mLastKeyboardFocus = NULL; + } +} void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL keystrokes_only) { @@ -328,11 +348,22 @@ void LLFocusMgr::removeKeyboardFocusWithoutCallback( const LLFocusableElement* f { mLockedView = NULL; } - - if( mKeyboardFocus == focus ) + if (mKeyboardFocus == focus) { mKeyboardFocus = NULL; } + if (mLastKeyboardFocus == focus) + { + mLastKeyboardFocus = NULL; + } + if (mDefaultKeyboardFocus == focus) + { + mDefaultKeyboardFocus = NULL; + } + if (mLastDefaultKeyboardFocus == focus) + { + mLastDefaultKeyboardFocus = NULL; + } } diff --git a/indra/llui/llfocusmgr.h b/indra/llui/llfocusmgr.h index 14c711b5e..5f1466f5d 100644 --- a/indra/llui/llfocusmgr.h +++ b/indra/llui/llfocusmgr.h @@ -84,6 +84,7 @@ public: // Keyboard Focus void setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock = FALSE, BOOL keystrokes_only = FALSE); // new_focus = NULL to release the focus. + void restoreKeyboardFocus(LLFocusableElement* current_focus); LLFocusableElement* getKeyboardFocus() const { return mKeyboardFocus; } LLFocusableElement* getLastKeyboardFocus() const { return mLastKeyboardFocus; } BOOL childHasKeyboardFocus( const LLView* parent ) const; @@ -103,7 +104,8 @@ public: // If setKeyboardFocus(NULL) is called, and there is a non-NULL default // keyboard focus view, focus goes there. JC - void setDefaultKeyboardFocus(LLFocusableElement* default_focus) { mDefaultKeyboardFocus = default_focus; } + void setDefaultKeyboardFocus(LLFocusableElement* default_focus) { mLastDefaultKeyboardFocus = mDefaultKeyboardFocus; mDefaultKeyboardFocus = default_focus; } + void restoreDefaultKeyboardFocus(LLFocusableElement* current_default_focus); LLFocusableElement* getDefaultKeyboardFocus() const { return mDefaultKeyboardFocus; } @@ -132,6 +134,7 @@ private: LLFocusableElement* mKeyboardFocus; // Keyboard events are preemptively routed to this object LLFocusableElement* mLastKeyboardFocus; // who last had focus LLFocusableElement* mDefaultKeyboardFocus; + LLFocusableElement* mLastDefaultKeyboardFocus; BOOL mKeystrokesOnly; // Top View diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index 735b033b1..d3f4ed3f6 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -345,7 +345,6 @@ public: LLToolset* mLastToolset; boost::signals2::connection mQualityMouseUpConnection; - LLFocusableElement* mPrevDefaultKeyboardFocus; }; //---------------------------------------------------------------------------- @@ -1716,14 +1715,12 @@ void LLFloaterSnapshot::Impl::freezeTime(bool on) } // Make sure the floater keeps focus so that pressing ESC stops Freeze Time mode. - sInstance->impl.mPrevDefaultKeyboardFocus = gFocusMgr.getDefaultKeyboardFocus(); gFocusMgr.setDefaultKeyboardFocus(sInstance); } else if (gSavedSettings.getBOOL("FreezeTime")) // turning off freeze frame mode { // Restore default keyboard focus. - gFocusMgr.setDefaultKeyboardFocus(sInstance->impl.mPrevDefaultKeyboardFocus); - sInstance->impl.mPrevDefaultKeyboardFocus = NULL; + gFocusMgr.restoreDefaultKeyboardFocus(sInstance); gSnapshotFloaterView->setMouseOpaque(FALSE);