diff options
| author | Euclid Linden <euclid@lindenlab.com> | 2022-04-18 22:19:14 +0000 | 
|---|---|---|
| committer | Euclid Linden <euclid@lindenlab.com> | 2022-04-18 22:19:14 +0000 | 
| commit | 030d61ac58be38f9f8aafeb68b383d88d670080b (patch) | |
| tree | 79af0678906bf9e05316614d52b4cf5e97d1adc2 /indra/newview/llviewerinput.cpp | |
| parent | 6ca09a94554ec01f5c94ec60fffd01d7e33f3546 (diff) | |
| parent | d031662435d97101411ae990ed85d6e001ab668a (diff) | |
Merged in D559-merge-6.5.5 (pull request #946)
DRTVWR-559 merge up to 6.5.5
Diffstat (limited to 'indra/newview/llviewerinput.cpp')
| -rw-r--r-- | indra/newview/llviewerinput.cpp | 171 | 
1 files changed, 145 insertions, 26 deletions
| diff --git a/indra/newview/llviewerinput.cpp b/indra/newview/llviewerinput.cpp index 94ec534732..43b9cd90bd 100644 --- a/indra/newview/llviewerinput.cpp +++ b/indra/newview/llviewerinput.cpp @@ -816,13 +816,20 @@ bool toggle_enable_media(EKeystate s)  bool walk_to(EKeystate s)  { -    if (KEYSTATE_DOWN != s) return true; +    if (KEYSTATE_DOWN != s) +    { +        // teleport/walk is usually on mouseclick, mouseclick needs +        // to let AGENT_CONTROL_LBUTTON_UP happen if teleport didn't, +        // so return false, but if it causes issues, do some kind of +        // "return !has_teleported" +        return false; +    }      return LLToolPie::getInstance()->walkToClickedLocation();  }  bool teleport_to(EKeystate s)  { -    if (KEYSTATE_DOWN != s) return true; +    if (KEYSTATE_DOWN != s) return false;      return LLToolPie::getInstance()->teleportToClickedLocation();  } @@ -850,7 +857,47 @@ bool voice_follow_key(EKeystate s)      return false;  } -bool agen_control_lbutton_handle(EKeystate s) +bool script_trigger_lbutton(EKeystate s) +{ +    // Check for script overriding/expecting left mouse button. +    // Note that this does not pass event further and depends onto mouselook. +    // Checks CONTROL_ML_LBUTTON_DOWN_INDEX for mouselook, +    // CONTROL_LBUTTON_DOWN_INDEX for normal camera +    if (gAgent.leftButtonGrabbed()) +    { +        bool mouselook = gAgentCamera.cameraMouselook(); +        switch (s) +        { +        case KEYSTATE_DOWN: +            if (mouselook) +            { +                gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN); +            } +            else +            { +                gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_DOWN); +            } +            return true; +        case KEYSTATE_UP: +            if (mouselook) +            { +                gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_UP); +            } +            else +            { +                gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_UP); +            } +            return true; +        default: +            break; +        } +    } +    return false; +} + +// Used by scripts, for overriding/handling left mouse button +// see mControlsTakenCount +bool agent_control_lbutton_handle(EKeystate s)  {      switch (s)      { @@ -922,6 +969,7 @@ REGISTER_KEYBOARD_ACTION("teleport_to", teleport_to);  REGISTER_KEYBOARD_ACTION("walk_to", walk_to);  REGISTER_KEYBOARD_GLOBAL_ACTION("toggle_voice", toggle_voice);  REGISTER_KEYBOARD_GLOBAL_ACTION("voice_follow_key", voice_follow_key); +REGISTER_KEYBOARD_ACTION(script_mouse_handler_name, script_trigger_lbutton);  #undef REGISTER_KEYBOARD_ACTION  LLViewerInput::LLViewerInput() @@ -1193,6 +1241,20 @@ BOOL LLViewerInput::bindMouse(const S32 mode, const EMouseClickType mouse, const      typedef boost::function<bool(EKeystate)> function_t;      function_t function = NULL; +    if (mouse == CLICK_LEFT +        && mask == MASK_NONE +        && function_name == script_mouse_handler_name) +    { +        // Special case +        // Left click has script overrides and by default +        // is handled via agent_control_lbutton as last option +        // In case of mouselook and present overrides it has highest +        // priority even over UI and is handled in LLToolCompGun::handleMouseDown +        // so just mark it as having default handler +        mLMouseDefaultHandling[mode] = true; +        return TRUE; +    } +      LLKeybindFunctionData* result = LLKeyboardActionRegistry::getValue(function_name);      if (result)      { @@ -1269,7 +1331,8 @@ LLViewerInput::Keys::Keys()  :	first_person("first_person"),  	third_person("third_person"),  	sitting("sitting"), -	edit_avatar("edit_avatar") +	edit_avatar("edit_avatar"), +	xml_version("xml_version", 0)  {}  void LLViewerInput::resetBindings() @@ -1280,6 +1343,7 @@ void LLViewerInput::resetBindings()          mGlobalMouseBindings[i].clear();          mKeyBindings[i].clear();          mMouseBindings[i].clear(); +        mLMouseDefaultHandling[i] = false;      }  } @@ -1298,6 +1362,65 @@ S32 LLViewerInput::loadBindingsXML(const std::string& filename)  		binding_count += loadBindingMode(keys.third_person, MODE_THIRD_PERSON);  		binding_count += loadBindingMode(keys.sitting, MODE_SITTING);  		binding_count += loadBindingMode(keys.edit_avatar, MODE_EDIT_AVATAR); + +        // verify version +        if (keys.xml_version < 1) +        { +            // updating from a version that was not aware of LMouse bindings +            for (S32 i = 0; i < MODE_COUNT; i++) +            { +                mLMouseDefaultHandling[i] = true; +            } + +            // fix missing values +            KeyBinding mouse_binding; +            mouse_binding.key = ""; +            mouse_binding.mask = "NONE"; +            mouse_binding.mouse = "LMB"; +            mouse_binding.command = script_mouse_handler_name; + +            if (keys.third_person.isProvided()) +            { +                keys.third_person.bindings.add(mouse_binding); +            } + +            if (keys.first_person.isProvided()) +            { +                keys.first_person.bindings.add(mouse_binding); +            } + +            if (keys.sitting.isProvided()) +            { +                keys.sitting.bindings.add(mouse_binding); +            } + +            if (keys.edit_avatar.isProvided()) +            { +                keys.edit_avatar.bindings.add(mouse_binding); +            } + +            // fix version +            keys.xml_version.set(keybindings_xml_version, true); + +            // Write the resulting XML to file +            LLXMLNodePtr output_node = new LLXMLNode("keys", false); +            LLXUIParser write_parser; +            write_parser.writeXUI(output_node, keys); + +            if (!output_node->isNull()) +            { +                // file in app_settings is supposed to be up to date +                // this is only for the file from user_settings +                LL_INFOS("ViewerInput") << "Updating file " << filename << " to a newer version" << LL_ENDL; +                LLFILE *fp = LLFile::fopen(filename, "w"); +                if (fp != NULL) +                { +                    LLXMLNode::writeHeaderToFile(fp); +                    output_node->writeToFile(fp); +                    fclose(fp); +                } +            } +        }  	}  	return binding_count;  } @@ -1469,17 +1592,6 @@ bool LLViewerInput::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level)      bool res = scanKey(mKeyBindings[mode], mKeyBindings[mode].size(), key, mask, key_down, key_up, key_level, repeat); -    if (!res && agent_control_lbutton.canHandle(CLICK_NONE, key, mask)) -    { -        if (key_down && !repeat) -        { -            res = agen_control_lbutton_handle(KEYSTATE_DOWN); -        } -        if (key_up) -        { -            res = agen_control_lbutton_handle(KEYSTATE_UP); -        } -    }      return res;  } @@ -1603,29 +1715,36 @@ bool LLViewerInput::scanMouse(EMouseClickType click, EMouseState state) const      bool res = false;      S32 mode = getMode();      MASK mask = gKeyboard->currentMask(TRUE); - -    // By default mouse clicks require exact mask -    // Todo: support for mIgnoreMasks because some functions like teleports -    // expect to be canceled, but for voice it's prefered to ignore mask.      res = scanMouse(mMouseBindings[mode], mMouseBindings[mode].size(), click, mask, state, false); -    // no user defined actions found or those actions can't handle the key/button, handle control if nessesary -    if (!res && agent_control_lbutton.canHandle(click, KEY_NONE, mask)) + +    // No user defined actions found or those actions can't handle the key/button, +    // so handle CONTROL_LBUTTON if nessesary. +    // +    // Default handling for MODE_FIRST_PERSON is in LLToolCompGun::handleMouseDown, +    // and sends AGENT_CONTROL_ML_LBUTTON_DOWN, but it only applies if ML controls +    // are leftButtonGrabbed(), send a normal click otherwise. + +    if (!res +        && mLMouseDefaultHandling[mode] +        && (mode != MODE_FIRST_PERSON || !gAgent.leftButtonGrabbed()) +        && (click == CLICK_LEFT || click == CLICK_DOUBLELEFT) +        )      {          switch (state)          {          case MOUSE_STATE_DOWN: -            agen_control_lbutton_handle(KEYSTATE_DOWN); +            agent_control_lbutton_handle(KEYSTATE_DOWN);              res = true;              break;          case MOUSE_STATE_CLICK:              // might not work best with some functions,              // but some function need specific states too specifically -            agen_control_lbutton_handle(KEYSTATE_DOWN); -            agen_control_lbutton_handle(KEYSTATE_UP); +            agent_control_lbutton_handle(KEYSTATE_DOWN); +            agent_control_lbutton_handle(KEYSTATE_UP);              res = true;              break;          case MOUSE_STATE_UP: -            agen_control_lbutton_handle(KEYSTATE_UP); +            agent_control_lbutton_handle(KEYSTATE_UP);              res = true;              break;          default: @@ -1655,7 +1774,7 @@ void LLViewerInput::scanMouse()      }  } -bool LLViewerInput::isMouseBindUsed(const EMouseClickType mouse, const MASK mask, const S32 mode) +bool LLViewerInput::isMouseBindUsed(const EMouseClickType mouse, const MASK mask, const S32 mode) const  {      S32 size = mMouseBindings[mode].size();      for (S32 index = 0; index < size; index++) | 
