diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 8328f9914e0f29c84be99a99567f8cc4c856e414..9305f38a29554e106314effe623ea5468c0e1f4c 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -2916,6 +2916,8 @@ void LLPanelPreferenceControls::onRestoreDefaults()
     for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
     {
         mConflictHandler[mEditingMode].resetToDefaults();
+        // Apply changes to viewer as 'temporary'
+        mConflictHandler[mEditingMode].saveToSettings(true);
     }
 }
 
@@ -2930,6 +2932,8 @@ bool LLPanelPreferenceControls::onSetKeyBind(EMouseClickType click, KEY key, MAS
     if ( mEditingColumn > 0)
     {
         mConflictHandler[mEditingMode].registerControl(mEditingControl, mEditingColumn - 1, click, key, mask, true);
+        // Apply changes to viewer as 'temporary'
+        mConflictHandler[mEditingMode].saveToSettings(true);
     }
 
     updateTable();
@@ -2946,6 +2950,8 @@ void LLPanelPreferenceControls::onDefaultKeyBind()
     if (mEditingColumn > 0)
     {
         mConflictHandler[mEditingMode].resetToDefault(mEditingControl, mEditingColumn - 1);
+        // Apply changes to viewer as 'temporary'
+        mConflictHandler[mEditingMode].saveToSettings(true);
     }
     updateTable();
 }
diff --git a/indra/newview/llkeyconflict.cpp b/indra/newview/llkeyconflict.cpp
index fcf1a7953c00d8f6954eed799e921229d16bf878..d88038816bd4966d600c8ac7634cf29f6f4358f4 100644
--- a/indra/newview/llkeyconflict.cpp
+++ b/indra/newview/llkeyconflict.cpp
@@ -40,10 +40,11 @@
 #include "llviewerinput.h"
 #include "llviewermenu.h"
 #include "llxuiparser.h"
-//#include "llstring.h"
 
-static const std::string saved_settings_key_controls[] = { "placeholder" };
+static const std::string saved_settings_key_controls[] = { "placeholder" }; // add settings from gSavedSettings here
 
+static const std::string filename_default = "key_bindings.xml";
+static const std::string filename_temporary = "key_bindings_tmp.xml"; // used to apply uncommited changes on the go.
 
 // LLKeyboard::stringFromMask is meant for UI and is OS dependent,
 // so this class uses it's own version
@@ -128,18 +129,28 @@ EMouseClickType mouse_from_string(const std::string& input)
 
 // LLKeyConflictHandler
 
+S32 LLKeyConflictHandler::sTemporaryFileUseCount = 0;
+
 LLKeyConflictHandler::LLKeyConflictHandler()
-    : mHasUnsavedChanges(false)
+:   mHasUnsavedChanges(false),
+    mUsesTemporaryFile(false),
+    mLoadMode(MODE_COUNT)
 {
 }
 
 LLKeyConflictHandler::LLKeyConflictHandler(ESourceMode mode)
-    : mHasUnsavedChanges(false),
+:   mHasUnsavedChanges(false),
+    mUsesTemporaryFile(false),
     mLoadMode(mode)
 {
     loadFromSettings(mode);
 }
 
+LLKeyConflictHandler::~LLKeyConflictHandler()
+{
+    clearUnsavedChanges();
+}
+
 bool LLKeyConflictHandler::canHandleControl(const std::string &control_name, EMouseClickType mouse_ind, KEY key, MASK mask)
 {
     return mControlsMap[control_name].canHandle(mouse_ind, key, mask);
@@ -355,6 +366,7 @@ bool LLKeyConflictHandler::loadFromSettings(const ESourceMode &load_mode, const
             }
             break;
         default:
+            LL_ERRS() << "Not implememted mode " << load_mode << LL_ENDL;
             break;
         }
     }
@@ -381,7 +393,7 @@ void LLKeyConflictHandler::loadFromSettings(ESourceMode load_mode)
     else
     {
         // load defaults
-        std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "key_bindings.xml");
+        std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, filename_default);
         if (!loadFromSettings(load_mode, filename, &mDefaultsMap))
         {
             LL_WARNS() << "Failed to load default settings, aborting" << LL_ENDL;
@@ -389,7 +401,7 @@ void LLKeyConflictHandler::loadFromSettings(ESourceMode load_mode)
         }
 
         // load user's
-        filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "key_bindings.xml");
+        filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_default);
         if (!gDirUtilp->fileExists(filename) || loadFromSettings(load_mode, filename, &mControlsMap))
         {
             // mind placeholders
@@ -399,7 +411,7 @@ void LLKeyConflictHandler::loadFromSettings(ESourceMode load_mode)
     mLoadMode = load_mode;
 }
 
-void LLKeyConflictHandler::saveToSettings()
+void LLKeyConflictHandler::saveToSettings(bool temporary)
 {
     if (mControlsMap.empty())
     {
@@ -408,6 +420,8 @@ void LLKeyConflictHandler::saveToSettings()
 
     if (mLoadMode == MODE_SAVED_SETTINGS)
     {
+        // Does not support 'temporary', preferences handle that themself
+        // so in case of saved settings we just do not clear mHasUnsavedChanges
         control_map_t::iterator iter = mControlsMap.begin();
         control_map_t::iterator end = mControlsMap.end();
 
@@ -440,10 +454,24 @@ void LLKeyConflictHandler::saveToSettings()
     }
     else
     {
-        // loaded full copy of original file
-        std::string filename = gDirUtilp->findFile("key_bindings.xml",
-            gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""),
-            gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
+        // Determine what file to load and load full copy of that file
+        std::string filename;
+
+        if (temporary)
+        {
+            filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_temporary);
+            if (!gDirUtilp->fileExists(filename))
+            {
+                filename.clear();
+            }
+        }
+
+        if (filename.empty())
+        {
+            filename = gDirUtilp->findFile(filename_default,
+                gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""),
+                gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
+        }
 
         LLViewerInput::Keys keys;
         LLSimpleXUIParser parser;
@@ -495,7 +523,16 @@ void LLKeyConflictHandler::saveToSettings()
                         binding.key = LLKeyboard::stringFromKey(data.mKey);
                     }
                     binding.mask = string_from_mask(data.mMask);
-                    binding.mouse.set(string_from_mouse(data.mMouse), true); //set() because 'optional', for compatibility purposes
+                    if (data.mMouse == CLICK_NONE)
+                    {
+                        binding.mouse.setProvided(false);
+                    }
+                    else
+                    {
+                        // set() because 'optional', for compatibility purposes
+                        // just copy old keys.xml and rename to key_bindings.xml, it should work
+                        binding.mouse.set(string_from_mouse(data.mMouse), true);
+                    }
                     binding.command = iter->first;
                     mode.bindings.add(binding);
                 }
@@ -534,11 +571,22 @@ void LLKeyConflictHandler::saveToSettings()
                 }
                 break;
             default:
+                LL_ERRS() << "Not implememted mode " << mLoadMode << LL_ENDL;
                 break;
             }
 
-            // write back to user's xml;
-            std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "key_bindings.xml");
+            if (temporary)
+            {
+                // write to temporary xml and use it for gViewerInput
+                filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_temporary);
+                mUsesTemporaryFile = true;
+                sTemporaryFileUseCount++;
+            }
+            else
+            {
+                // write back to user's xml and use it for gViewerInput
+                filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_default);
+            }
 
             LLXMLNodePtr output_node = new LLXMLNode("keys", false);
             LLXUIParser parser;
@@ -562,7 +610,11 @@ void LLKeyConflictHandler::saveToSettings()
             }
         }
     }
-    mHasUnsavedChanges = false;
+
+    if (!temporary)
+    {
+        clearUnsavedChanges();
+    }
 }
 
 LLKeyData LLKeyConflictHandler::getDefaultControl(const std::string &control_name, U32 index)
@@ -702,17 +754,17 @@ void LLKeyConflictHandler::resetToDefaults()
 
 void LLKeyConflictHandler::clear()
 {
-    mHasUnsavedChanges = false;
+    clearUnsavedChanges();
     mControlsMap.clear();
     mDefaultsMap.clear();
 }
 
 void LLKeyConflictHandler::resetKeyboardBindings()
 {
-    std::string filename = gDirUtilp->findFile("key_bindings.xml",
+    std::string filename = gDirUtilp->findFile(filename_default,
         gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""),
         gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
-    
+
     gViewerInput.loadBindingsXML(filename);
 }
 
@@ -773,3 +825,32 @@ void LLKeyConflictHandler::registerTemporaryControl(const std::string &control_n
     type_data->mKeyBind.addKeyData(mouse, key, mask, false);
 }
 
+void LLKeyConflictHandler::clearUnsavedChanges()
+{
+    mHasUnsavedChanges = false;
+
+    if (mUsesTemporaryFile)
+    {
+        mUsesTemporaryFile = false;
+        sTemporaryFileUseCount--;
+        if (!sTemporaryFileUseCount)
+        {
+            clearTemporaryFile();
+        }
+        // else: might be usefull to overwrite content of temp file with defaults
+        // but at the moment there is no such need
+    }
+}
+
+//static
+void LLKeyConflictHandler::clearTemporaryFile()
+{
+    // At the moment single file needs five handlers (one per mode), so doing this
+    // will remove file for all hadlers
+    std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_temporary);
+    if (gDirUtilp->fileExists(filename))
+    {
+        LLFile::remove(filename);
+    }
+}
+
diff --git a/indra/newview/llkeyconflict.h b/indra/newview/llkeyconflict.h
index 5c3b860ec6675b91863313a10af89ac05d7a644d..24843e875fa545877e1b7cbda948e5c36d84a8b0 100644
--- a/indra/newview/llkeyconflict.h
+++ b/indra/newview/llkeyconflict.h
@@ -74,6 +74,7 @@ class LLKeyConflictHandler
 
     LLKeyConflictHandler();
     LLKeyConflictHandler(ESourceMode mode);
+    ~LLKeyConflictHandler();
 
     bool canHandleControl(const std::string &control_name, EMouseClickType mouse_ind, KEY key, MASK mask);
     bool canHandleKey(const std::string &control_name, KEY key, MASK mask);
@@ -93,8 +94,14 @@ class LLKeyConflictHandler
     void loadFromControlSettings(const std::string &name);
     // Drops any changes loads controls with ones from 'saved settings' or from xml
     void loadFromSettings(ESourceMode load_mode);
+
     // Saves settings to 'saved settings' or to xml
-    void saveToSettings();
+    // If 'temporary' is set, function will save settings to temporary
+    // file and reload input 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);
 
     LLKeyData getDefaultControl(const std::string &control_name, U32 data_index);
     // Resets keybinding to default variant from 'saved settings' or xml
@@ -125,10 +132,19 @@ class LLKeyConflictHandler
     // 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();
+
     control_map_t mControlsMap;
     control_map_t mDefaultsMap;
     bool mHasUnsavedChanges;
     ESourceMode mLoadMode;
+
+    // To implement 'apply immediately'+revert on cancel, class applies changes to temporary file
+    // but this only works for settings from keybndings files (key_bindings.xml)
+    // saved setting rely onto external mechanism of preferences floater
+    bool mUsesTemporaryFile;
+    static S32 sTemporaryFileUseCount;
 };