summaryrefslogtreecommitdiff
path: root/indra/newview/llkeyconflict.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llkeyconflict.cpp')
-rw-r--r--indra/newview/llkeyconflict.cpp103
1 files changed, 90 insertions, 13 deletions
diff --git a/indra/newview/llkeyconflict.cpp b/indra/newview/llkeyconflict.cpp
index b5ac94b1cd..4c58c9e68c 100644
--- a/indra/newview/llkeyconflict.cpp
+++ b/indra/newview/llkeyconflict.cpp
@@ -376,6 +376,23 @@ bool LLKeyConflictHandler::loadFromSettings(const ESourceMode &load_mode, const
LL_ERRS() << "Not implememted mode " << load_mode << LL_ENDL;
break;
}
+
+ // verify version
+ if (keys.xml_version < 1)
+ {
+ // Updating from a version that was not aware of LMouse bindings.
+ // Assign defaults.
+ //
+ // mDefaultsMap is always going to have correct version so
+ // registerControl is usable, but using 'destination' just in case.
+ LLKeyConflict &type_data = (*destination)[script_mouse_handler_name];
+ LLKeyData data(CLICK_LEFT, KEY_NONE, MASK_NONE, true);
+ type_data.mKeyBind.replaceKeyData(data, 0);
+
+ // Mark this mode for an update, once user clicks 'OK' in preferences
+ // it should get saved
+ mHasUnsavedChanges = true;
+ }
}
return res;
}
@@ -411,8 +428,16 @@ void LLKeyConflictHandler::loadFromSettings(ESourceMode load_mode)
filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_default);
if (!gDirUtilp->fileExists(filename) || !loadFromSettings(load_mode, filename, &mControlsMap))
{
- // mind placeholders
- mControlsMap.insert(mDefaultsMap.begin(), mDefaultsMap.end());
+ // Mind placeholders
+ // Do not use mControlsMap.insert(mDefaultsMap) since mControlsMap has
+ // placeholders that won't be added over(to) by insert.
+ // Or instead move generatePlaceholders call to be after copying
+ control_map_t::iterator iter = mDefaultsMap.begin();
+ while (iter != mDefaultsMap.end())
+ {
+ mControlsMap[iter->first].mKeyBind = iter->second.mKeyBind;
+ iter++;
+ }
}
}
mLoadMode = load_mode;
@@ -575,6 +600,8 @@ void LLKeyConflictHandler::saveToSettings(bool temporary)
break;
}
+ keys.xml_version.set(keybindings_xml_version, true);
+
if (temporary)
{
// write to temporary xml and use it for gViewerInput
@@ -667,13 +694,19 @@ void LLKeyConflictHandler::resetToDefault(const std::string &control_name, U32 i
{
return;
}
+ LLKeyConflict &type_data = mControlsMap[control_name];
+ if (!type_data.mAssignable)
+ {
+ return;
+ }
LLKeyData data = getDefaultControl(control_name, index);
- if (data != mControlsMap[control_name].getKeyData(index))
+ if (data != type_data.getKeyData(index))
{
// reset controls that might have been switched to our current control
removeConflicts(data, mControlsMap[control_name].mConflictMask);
mControlsMap[control_name].setKeyData(data, index);
+ mHasUnsavedChanges = true;
}
}
@@ -730,9 +763,9 @@ void LLKeyConflictHandler::resetToDefault(const std::string &control_name)
resetToDefaultAndResolve(control_name, false);
}
-void LLKeyConflictHandler::resetToDefaults(ESourceMode mode)
+void LLKeyConflictHandler::resetToDefaultsAndResolve()
{
- if (mode == MODE_SAVED_SETTINGS)
+ if (mLoadMode == MODE_SAVED_SETTINGS)
{
control_map_t::iterator iter = mControlsMap.begin();
control_map_t::iterator end = mControlsMap.end();
@@ -745,8 +778,16 @@ void LLKeyConflictHandler::resetToDefaults(ESourceMode mode)
else
{
mControlsMap.clear();
- generatePlaceholders(mode);
+
+ // Set key combinations.
+ // Copy from mDefaultsMap before doing generatePlaceholders, otherwise
+ // insert() will fail to add some keys into pre-existing values from
+ // generatePlaceholders()
mControlsMap.insert(mDefaultsMap.begin(), mDefaultsMap.end());
+
+ // Set conflict masks and mark functions (un)assignable
+ generatePlaceholders(mLoadMode);
+
}
mHasUnsavedChanges = true;
@@ -756,7 +797,7 @@ void LLKeyConflictHandler::resetToDefaults()
{
if (!empty())
{
- resetToDefaults(mLoadMode);
+ resetToDefaultsAndResolve();
}
else
{
@@ -766,7 +807,7 @@ void LLKeyConflictHandler::resetToDefaults()
// 3. We are loading 'current' only to replace it
// but it is reliable and works Todo: consider optimizing.
loadFromSettings(mLoadMode);
- resetToDefaults(mLoadMode);
+ resetToDefaultsAndResolve();
}
}
@@ -799,7 +840,7 @@ void LLKeyConflictHandler::resetKeyboardBindings()
void LLKeyConflictHandler::generatePlaceholders(ESourceMode load_mode)
{
- // These controls are meant to cause conflicts when user tries to assign same control somewhere else
+ // These placeholders are meant to cause conflict resolution when user tries to assign same control somewhere else
// also this can be used to pre-record controls that should not conflict or to assign conflict groups/masks
if (load_mode == MODE_FIRST_PERSON)
@@ -859,24 +900,60 @@ void LLKeyConflictHandler::generatePlaceholders(ESourceMode load_mode)
registerTemporaryControl("spin_around_ccw_sitting");
registerTemporaryControl("spin_around_cw_sitting");
}
+
+
+ // Special case, mouse clicks passed to scripts have 'lowest' piority
+ // thus do not conflict, everything else has a chance before them
+ // also in ML they have highest priority, but only when script-grabbed,
+ // thus do not conflict
+ // (see AGENT_CONTROL_ML_LBUTTON_DOWN and CONTROL_LBUTTON_DOWN_INDEX)
+ LLKeyConflict *type_data = &mControlsMap[script_mouse_handler_name];
+ type_data->mAssignable = true;
+ type_data->mConflictMask = U32_MAX - CONFLICT_LMOUSE;
}
-bool LLKeyConflictHandler::removeConflicts(const LLKeyData &data, const U32 &conlict_mask)
+bool LLKeyConflictHandler::removeConflicts(const LLKeyData &data, U32 conlict_mask)
{
if (conlict_mask == CONFLICT_NOTHING)
{
// Can't conflict
return true;
}
+
+ if (data.mMouse == CLICK_LEFT
+ && data.mMask == MASK_NONE
+ && data.mKey == KEY_NONE)
+ {
+ if ((conlict_mask & CONFLICT_LMOUSE) == 0)
+ {
+ // Can't conflict
+ return true;
+ }
+ else
+ {
+ // simplify conflict mask
+ conlict_mask = CONFLICT_LMOUSE;
+ }
+ }
+ else
+ {
+ // simplify conflict mask
+ conlict_mask &= ~CONFLICT_LMOUSE;
+ }
+
std::map<std::string, S32> conflict_list;
control_map_t::iterator cntrl_iter = mControlsMap.begin();
control_map_t::iterator cntrl_end = mControlsMap.end();
for (; cntrl_iter != cntrl_end; ++cntrl_iter)
{
+ const U32 cmp_mask = cntrl_iter->second.mConflictMask;
+ if ((cmp_mask & conlict_mask) == 0)
+ {
+ // can't conflict
+ continue;
+ }
S32 index = cntrl_iter->second.mKeyBind.findKeyData(data);
- if (index >= 0
- && cntrl_iter->second.mConflictMask != CONFLICT_NOTHING
- && (cntrl_iter->second.mConflictMask & conlict_mask) != 0)
+ if (index >= 0)
{
if (cntrl_iter->second.mAssignable)
{