diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 96e77410c3b40c280f37cc628a5681e20b63f421..a4703d1eb158514c0e9f40b1efedb53816d2c290 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1012,7 +1012,7 @@ bool LLAppViewer::init()
 		key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "key_bindings.xml");
 		if (!gViewerInput.loadBindingsXML(key_bindings_file))
 		{
-			LL_ERRS("InitInfo") << "Unable to open default key bindings from" << key_bindings_file << LL_ENDL;
+			LL_ERRS("InitInfo") << "Unable to open default key bindings from " << key_bindings_file << LL_ENDL;
 		}
 	}
 
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 9305f38a29554e106314effe623ea5468c0e1f4c..ffd83a8555b340f5e9f1f17e8b924e466b7b3c51 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -2669,6 +2669,7 @@ LLPanelPreferenceControls::LLPanelPreferenceControls()
     mEditingColumn(-1),
     mEditingMode(0)
 {
+    // MODE_COUNT - 1 because there are currently no settings assigned to 'saved settings'.
     for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
     {
         mConflictHandler[i].setLoadMode((LLKeyConflictHandler::ESourceMode)i);
@@ -2908,17 +2909,25 @@ void LLPanelPreferenceControls::onListCommit()
 
 void LLPanelPreferenceControls::onModeCommit()
 {
-    regenerateControls();
+    mEditingMode = pKeyModeBox->getValue().asInteger();
+    if (mConflictHandler[mEditingMode].empty())
+    {
+        // opening for first time
+        mConflictHandler[mEditingMode].loadFromSettings((LLKeyConflictHandler::ESourceMode)mEditingMode);
+    }
+    populateControlTable();
 }
 
 void LLPanelPreferenceControls::onRestoreDefaults()
 {
     for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
     {
-        mConflictHandler[mEditingMode].resetToDefaults();
+        mConflictHandler[i].resetToDefaults();
         // Apply changes to viewer as 'temporary'
-        mConflictHandler[mEditingMode].saveToSettings(true);
+        mConflictHandler[i].saveToSettings(true);
     }
+
+    updateTable();
 }
 
 // todo: copy onSetKeyBind to interface and inherit from interface
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index f08f2aa2ba7b52d879f181fee466497ebac218f9..112784b83e10e8e56621d73408bd593a4bfdbbc8 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -307,7 +307,9 @@ class LLPanelPreferenceControls : public LLPanelPreference, public LLKeyBindResp
 	/*virtual*/ void onCancelKeyBind();
 
 private:
+	// reloads settings, discards current changes, updates table
 	void regenerateControls();
+
 	void populateControlTable();
 	void addSeparator();
 	void updateTable();
diff --git a/indra/newview/llkeyconflict.cpp b/indra/newview/llkeyconflict.cpp
index d88038816bd4966d600c8ac7634cf29f6f4358f4..d9c2b3d53a9974d62655b98b6c4c3b04322564ab 100644
--- a/indra/newview/llkeyconflict.cpp
+++ b/indra/newview/llkeyconflict.cpp
@@ -149,6 +149,7 @@ LLKeyConflictHandler::LLKeyConflictHandler(ESourceMode mode)
 LLKeyConflictHandler::~LLKeyConflictHandler()
 {
     clearUnsavedChanges();
+    // Note: does not reset bindings if temporary file was used
 }
 
 bool LLKeyConflictHandler::canHandleControl(const std::string &control_name, EMouseClickType mouse_ind, KEY key, MASK mask)
@@ -579,13 +580,17 @@ void LLKeyConflictHandler::saveToSettings(bool temporary)
             {
                 // write to temporary xml and use it for gViewerInput
                 filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_temporary);
-                mUsesTemporaryFile = true;
-                sTemporaryFileUseCount++;
+                if (!mUsesTemporaryFile)
+                {
+                    mUsesTemporaryFile = true;
+                    sTemporaryFileUseCount++;
+                }
             }
             else
             {
                 // write back to user's xml and use it for gViewerInput
                 filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_default);
+                // Don't reset mUsesTemporaryFile, it will be reset at cleanup stage
             }
 
             LLXMLNodePtr output_node = new LLXMLNode("keys", false);
@@ -606,6 +611,10 @@ void LLKeyConflictHandler::saveToSettings(bool temporary)
             // Now force a rebind for keyboard
             if (gDirUtilp->fileExists(filename))
             {
+                // Ideally instead of rebinding immediately we should shedule
+                // the rebind since single file can have multiple handlers,
+                // one per mode, saving simultaneously.
+                // Or whatever uses LLKeyConflictHandler should control the process.
                 gViewerInput.loadBindingsXML(filename);
             }
         }
@@ -613,6 +622,7 @@ void LLKeyConflictHandler::saveToSettings(bool temporary)
 
     if (!temporary)
     {
+        // will remove any temporary file if there were any
         clearUnsavedChanges();
     }
 }
@@ -754,18 +764,29 @@ void LLKeyConflictHandler::resetToDefaults()
 
 void LLKeyConflictHandler::clear()
 {
-    clearUnsavedChanges();
+    if (clearUnsavedChanges())
+    {
+        // temporary file was removed, this means we were using it and need to reload keyboard's bindings
+        resetKeyboardBindings();
+    }
     mControlsMap.clear();
     mDefaultsMap.clear();
 }
 
+// static
 void LLKeyConflictHandler::resetKeyboardBindings()
 {
-    std::string filename = gDirUtilp->findFile(filename_default,
-        gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""),
-        gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
-
-    gViewerInput.loadBindingsXML(filename);
+    // Try to load User's bindings first
+    std::string key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_default);
+    if (!gDirUtilp->fileExists(key_bindings_file) || !gViewerInput.loadBindingsXML(key_bindings_file))
+    {
+        // Failed to load custom bindings, try default ones
+        key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, filename_default);
+        if (!gViewerInput.loadBindingsXML(key_bindings_file))
+        {
+            LL_ERRS("InitInfo") << "Unable to open default key bindings from " << key_bindings_file << LL_ENDL;
+        }
+    }
 }
 
 void LLKeyConflictHandler::generatePlaceholders(ESourceMode load_mode)
@@ -825,8 +846,9 @@ void LLKeyConflictHandler::registerTemporaryControl(const std::string &control_n
     type_data->mKeyBind.addKeyData(mouse, key, mask, false);
 }
 
-void LLKeyConflictHandler::clearUnsavedChanges()
+bool LLKeyConflictHandler::clearUnsavedChanges()
 {
+    bool result = false;
     mHasUnsavedChanges = false;
 
     if (mUsesTemporaryFile)
@@ -835,15 +857,16 @@ void LLKeyConflictHandler::clearUnsavedChanges()
         sTemporaryFileUseCount--;
         if (!sTemporaryFileUseCount)
         {
-            clearTemporaryFile();
+            result = clearTemporaryFile();
         }
         // else: might be usefull to overwrite content of temp file with defaults
         // but at the moment there is no such need
     }
+    return result;
 }
 
 //static
-void LLKeyConflictHandler::clearTemporaryFile()
+bool LLKeyConflictHandler::clearTemporaryFile()
 {
     // At the moment single file needs five handlers (one per mode), so doing this
     // will remove file for all hadlers
@@ -851,6 +874,8 @@ void LLKeyConflictHandler::clearTemporaryFile()
     if (gDirUtilp->fileExists(filename))
     {
         LLFile::remove(filename);
+        return true;
     }
+    return false;
 }
 
diff --git a/indra/newview/llkeyconflict.h b/indra/newview/llkeyconflict.h
index 24843e875fa545877e1b7cbda948e5c36d84a8b0..4ebe054f223899171c8bd2a3c3a7381ddb0213a3 100644
--- a/indra/newview/llkeyconflict.h
+++ b/indra/newview/llkeyconflict.h
@@ -97,11 +97,11 @@ class LLKeyConflictHandler
 
     // Saves settings to 'saved settings' or to xml
     // If 'temporary' is set, function will save settings to temporary
-    // file and reload input from temporary file.
+    // file and reload input bindings from temporary file.
     // 'temporary' does not support gSavedSettings, those are handled
     // by preferences, so 'temporary' is such case will simply not
     // reset mHasUnsavedChanges
-    void saveToSettings(bool temporary = false);
+    void saveToSettings(bool apply_temporary = false);
 
     LLKeyData getDefaultControl(const std::string &control_name, U32 data_index);
     // Resets keybinding to default variant from 'saved settings' or xml
@@ -113,6 +113,10 @@ class LLKeyConflictHandler
     bool empty() { return mControlsMap.empty(); }
     void clear();
 
+    // reloads bindings from last valid user's xml or from default xml
+    // to keyboard's handler
+    static void resetKeyboardBindings();
+
     bool hasUnsavedChanges() { return mHasUnsavedChanges; }
     void setLoadMode(ESourceMode mode) { mLoadMode = mode; }
     ESourceMode getLoadMode() { return mLoadMode; }
@@ -127,13 +131,14 @@ class LLKeyConflictHandler
     typedef std::map<std::string, LLKeyConflict> control_map_t;
     void loadFromSettings(const LLViewerInput::KeyMode& keymode, control_map_t *destination);
     bool loadFromSettings(const ESourceMode &load_mode, const std::string &filename, control_map_t *destination);
-    void resetKeyboardBindings();
     void generatePlaceholders(ESourceMode load_mode); //E.x. non-assignable values
     // returns false in case user is trying to reuse control that can't be reassigned
     bool removeConflicts(const LLKeyData &data, const U32 &conlict_mask);
 
-    void clearUnsavedChanges();
-    static void clearTemporaryFile();
+    // removes flags and removes temporary file, returns 'true' if file was removed
+    bool clearUnsavedChanges();
+    // return true if there was a file to remove
+    static bool clearTemporaryFile();
 
     control_map_t mControlsMap;
     control_map_t mDefaultsMap;
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_controls.xml b/indra/newview/skins/default/xui/en/panel_preferences_controls.xml
index eca3c550d5e6448ec859ed5c0ad1f0514d92be6a..bd3934309363f831fca568f38e244eae23e51a84 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_controls.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_controls.xml
@@ -47,6 +47,7 @@
    height="23"
    width="110"
    label="Restore Default"
+   tooltip="Restores default values for all control modes."
    name="restore_defaults"/>
 
   <scroll_list