diff options
| author | andreykproductengine <andreykproductengine@lindenlab.com> | 2019-10-28 18:27:13 +0200 | 
|---|---|---|
| committer | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2020-06-23 14:50:03 +0300 | 
| commit | 62214b53f09c453dc410465ba6e64a772562e6db (patch) | |
| tree | b3f0f8797c7efa3c1f7da0c436dde685e0d9290c /indra | |
| parent | 6597c7696783ce56f89b34a4b6440363635be6a6 (diff) | |
SL-6109 Fixed conflict resolution issue caused by menu accelerators
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llui/llmenugl.cpp | 53 | ||||
| -rw-r--r-- | indra/llui/llmenugl.h | 7 | ||||
| -rw-r--r-- | indra/newview/llkeyconflict.cpp | 12 | ||||
| -rw-r--r-- | indra/newview/llsetkeybinddialog.cpp | 53 | ||||
| -rw-r--r-- | indra/newview/llsetkeybinddialog.h | 9 | ||||
| -rw-r--r-- | indra/newview/llviewerwindow.cpp | 9 | 
6 files changed, 104 insertions, 39 deletions
| diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index d97bf2d674..b87819102b 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -213,6 +213,12 @@ LLSD LLMenuItemGL::getValue() const  }  //virtual +bool LLMenuItemGL::hasAccelerator(const KEY &key, const MASK &mask) const +{ +	return (mAcceleratorKey == key) && (mAcceleratorMask == mask); +} + +//virtual  BOOL LLMenuItemGL::handleAcceleratorKey(KEY key, MASK mask)  {  	if( getEnabled() && (!gKeyboard->getKeyRepeated(key) || mAllowKeyRepeat) && (key == mAcceleratorKey) && (mask == (mAcceleratorMask & MASK_NORMALKEYS)) ) @@ -1017,6 +1023,11 @@ BOOL LLMenuItemBranchGL::handleMouseUp(S32 x, S32 y, MASK mask)  	return TRUE;  } +bool LLMenuItemBranchGL::hasAccelerator(const KEY &key, const MASK &mask) const +{ +	return getBranch() && getBranch()->hasAccelerator(key, mask); +} +  BOOL LLMenuItemBranchGL::handleAcceleratorKey(KEY key, MASK mask)  {  	return getBranch() && getBranch()->handleAcceleratorKey(key, mask); @@ -3023,6 +3034,27 @@ void LLMenuGL::updateParent(LLView* parentp)  	}  } +bool LLMenuGL::hasAccelerator(const KEY &key, const MASK &mask) const +{ +	if (key == KEY_NONE) +	{ +		return false; +	} +	// Note: checking this way because mAccelerators seems to be broken +	// mAccelerators probably needs to be cleaned up or fixed +	// It was used for dupplicate accelerator avoidance. +	item_list_t::const_iterator item_iter; +	for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter) +	{ +		LLMenuItemGL* itemp = *item_iter; +		if (itemp->hasAccelerator(key, mask)) +		{ +			return true; +		} +	} +	return false; +} +  BOOL LLMenuGL::handleAcceleratorKey(KEY key, MASK mask)  {  	// don't handle if not enabled @@ -3536,27 +3568,6 @@ S32 LLMenuBarGL::getRightmostMenuEdge()  	return (*item_iter)->getRect().mRight;  } -bool LLMenuBarGL::hasAccelerator(const KEY &key, const MASK &mask) const -{ -    if (key == KEY_NONE) -    { -        return false; -    } - -    LLMenuKeyboardBinding *accelerator = NULL; -    std::list<LLMenuKeyboardBinding*>::const_iterator list_it; -    for (list_it = mAccelerators.begin(); list_it != mAccelerators.end(); ++list_it) -    { -        accelerator = *list_it; -        if ((accelerator->mKey == key) && (accelerator->mMask == (mask & MASK_NORMALKEYS))) -        { -            return true; -        } -    } - -    return false; -} -  // add a vertical separator to this menu  BOOL LLMenuBarGL::addSeparator()  { diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index adcb2ca2f9..8cef9c6463 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -98,6 +98,7 @@ public:  	/*virtual*/ void setValue(const LLSD& value);  	/*virtual*/ LLSD getValue() const; +	virtual bool hasAccelerator(const KEY &key, const MASK &mask) const;  	virtual BOOL handleAcceleratorKey(KEY key, MASK mask);  	LLColor4 getHighlightBgColor() { return mHighlightBackground.get(); } @@ -443,7 +444,8 @@ public:  	/*virtual*/ bool addChild(LLView* view, S32 tab_group = 0);  	/*virtual*/ void removeChild( LLView* ctrl);  	/*virtual*/ BOOL postBuild(); - +	 +	virtual bool hasAccelerator(const KEY &key, const MASK &mask) const;  	virtual BOOL handleAcceleratorKey(KEY key, MASK mask);  	LLMenuGL* findChildMenuByName(const std::string& name, BOOL recurse) const; @@ -635,6 +637,7 @@ public:  	virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); +	virtual bool hasAccelerator(const KEY &key, const MASK &mask) const;  	virtual BOOL handleAcceleratorKey(KEY key, MASK mask);  	// check if we've used these accelerators already @@ -795,8 +798,6 @@ public:  	void resetMenuTrigger() { mAltKeyTrigger = FALSE; } -	bool hasAccelerator(const KEY &key, const MASK &mask) const; -  private:  	// add a menu - this will create a drop down menu.  	virtual BOOL appendMenu( LLMenuGL* menu ); diff --git a/indra/newview/llkeyconflict.cpp b/indra/newview/llkeyconflict.cpp index 71ba0d37b3..fcf1a7953c 100644 --- a/indra/newview/llkeyconflict.cpp +++ b/indra/newview/llkeyconflict.cpp @@ -174,17 +174,23 @@ bool LLKeyConflictHandler::canAssignControl(const std::string &control_name)  // static  bool LLKeyConflictHandler::isReservedByMenu(const KEY &key, const MASK &mask)  { -    return gMenuBarView->hasAccelerator(key, mask) || gLoginMenuBarView->hasAccelerator(key, mask); +    if (key == KEY_NONE) +    { +        return false; +    } +    return (gMenuBarView && gMenuBarView->hasAccelerator(key, mask)) +           || (gLoginMenuBarView && gLoginMenuBarView->hasAccelerator(key, mask));  }  // static  bool LLKeyConflictHandler::isReservedByMenu(const LLKeyData &data)  { -    if (data.mMouse != CLICK_NONE) +    if (data.mMouse != CLICK_NONE || data.mKey == KEY_NONE)      {          return false;      } -    return gMenuBarView->hasAccelerator(data.mKey, data.mMask) || gLoginMenuBarView->hasAccelerator(data.mKey, data.mMask); +    return (gMenuBarView && gMenuBarView->hasAccelerator(data.mKey, data.mMask)) +           || (gLoginMenuBarView && gLoginMenuBarView->hasAccelerator(data.mKey, data.mMask));  }  bool LLKeyConflictHandler::registerControl(const std::string &control_name, U32 index, EMouseClickType mouse, KEY key, MASK mask, bool ignore_mask) diff --git a/indra/newview/llsetkeybinddialog.cpp b/indra/newview/llsetkeybinddialog.cpp index 320f1f297d..806c70aa03 100644 --- a/indra/newview/llsetkeybinddialog.cpp +++ b/indra/newview/llsetkeybinddialog.cpp @@ -28,11 +28,10 @@  #include "llsetkeybinddialog.h" -//#include "llkeyboard.h" -  #include "llbutton.h"  #include "llcheckboxctrl.h"  #include "lleventtimer.h" +#include "llfloaterreg.h"  #include "llfocusmgr.h"  #include "llkeyconflict.h" @@ -65,6 +64,8 @@ private:      callback_t mCallback;  }; +bool LLSetKeyBindDialog::sRecordKeys = false; +  LLSetKeyBindDialog::LLSetKeyBindDialog(const LLSD& key)      : LLModalDialog(key),      pParent(NULL), @@ -94,8 +95,16 @@ BOOL LLSetKeyBindDialog::postBuild()  }  //virtual +void LLSetKeyBindDialog::onOpen(const LLSD& data) +{ +     sRecordKeys = true; +     LLModalDialog::onOpen(data); +} + +//virtual  void LLSetKeyBindDialog::onClose(bool app_quiting)  { +    sRecordKeys = false;      if (pParent)      {          pParent->onCancelKeyBind(); @@ -145,20 +154,41 @@ void LLSetKeyBindDialog::setParent(LLKeyBindResponderInterface* parent, LLView*      pCheckBox->setValue(false);  } -BOOL LLSetKeyBindDialog::handleKeyHere(KEY key, MASK mask) +// static +bool LLSetKeyBindDialog::recordKey(KEY key, MASK mask) +{ +    if (sRecordKeys) +    { +        LLSetKeyBindDialog* dialog = LLFloaterReg::getTypedInstance<LLSetKeyBindDialog>("keybind_dialog", LLSD()); +        if (dialog && dialog->getVisible()) +        { +            return dialog->recordAndHandleKey(key, mask); +        } +        else +        { +            LL_WARNS() << "Key recording was set despite no open dialog" << LL_ENDL; +            sRecordKeys = false; +        } +    } +    return false; +} + +bool LLSetKeyBindDialog::recordAndHandleKey(KEY key, MASK mask)  {      if ((key == 'Q' && mask == MASK_CONTROL)          || key == KEY_ESCAPE)      { +        sRecordKeys = false;          closeFloater(); -        return TRUE; +        return true;      }      if (key == KEY_DELETE)      {          setKeyBind(CLICK_NONE, KEY_NONE, MASK_NONE, false); +        sRecordKeys = false;          closeFloater(); -        return FALSE; +        return false;      }      // forbidden keys @@ -166,36 +196,37 @@ BOOL LLSetKeyBindDialog::handleKeyHere(KEY key, MASK mask)          || key == KEY_RETURN          || key == KEY_BACKSPACE)      { -        return FALSE; +        return false;      }      if ((mKeyFilterMask & ALLOW_MASKS) == 0          && (key == KEY_CONTROL || key == KEY_SHIFT || key == KEY_ALT))      {          // mask by themself are not allowed -        return FALSE; +        return false;      }      else if ((mKeyFilterMask & ALLOW_KEYS) == 0)      {          // basic keys not allowed -        return FALSE; +        return false;      }      else if ((mKeyFilterMask & ALLOW_MASK_KEYS) == 0 && mask != 0)      {          // masked keys not allowed -        return FALSE; +        return false;      }      if (LLKeyConflictHandler::isReservedByMenu(key, mask))      {          pDesription->setText(getString("reserved_by_menu"));          pDesription->setTextArg("[KEYSTR]", LLKeyboard::stringFromAccelerator(mask,key)); -        return TRUE; +        return true;      }      setKeyBind(CLICK_NONE, key, mask, pCheckBox->getValue().asBoolean()); +    sRecordKeys = false;      closeFloater(); -    return TRUE; +    return true;  }  BOOL LLSetKeyBindDialog::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down) diff --git a/indra/newview/llsetkeybinddialog.h b/indra/newview/llsetkeybinddialog.h index 8faa2cc363..16a2d768e4 100644 --- a/indra/newview/llsetkeybinddialog.h +++ b/indra/newview/llsetkeybinddialog.h @@ -62,12 +62,16 @@ public:      ~LLSetKeyBindDialog();      /*virtual*/ BOOL postBuild(); +    /*virtual*/ void onOpen(const LLSD& data);      /*virtual*/ void onClose(bool app_quiting);      /*virtual*/ void draw();      void setParent(LLKeyBindResponderInterface* parent, LLView* frustum_origin, U32 key_mask = DEFAULT_KEY_FILTER); -    BOOL handleKeyHere(KEY key, MASK mask); +    // Wrapper around recordAndHandleKey +    // It does not record, it handles, but handleKey function is already in use +    static bool recordKey(KEY key, MASK mask); +      BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down);      static void onCancel(void* user_data);      static void onBlank(void* user_data); @@ -77,6 +81,7 @@ public:      class Updater;  private: +    bool recordAndHandleKey(KEY key, MASK mask);      void setKeyBind(EMouseClickType click, KEY key, MASK mask, bool ignore);      LLKeyBindResponderInterface *pParent;      LLCheckBoxCtrl *pCheckBox; @@ -84,6 +89,8 @@ private:      U32 mKeyFilterMask;      Updater *pUpdater; + +    static bool sRecordKeys; // for convinience and not to check instance each time  }; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 091fc720c1..a6bc3373e2 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -45,6 +45,7 @@  #include "llmeshrepository.h"  #include "llnotificationhandler.h"  #include "llpanellogin.h" +#include "llsetkeybinddialog.h"  #include "llviewerinput.h"  #include "llviewermenu.h" @@ -2730,6 +2731,14 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)  	// hide tooltips on keypress  	LLToolTipMgr::instance().blockToolTips(); +    // let menus handle navigation keys for navigation +    if (LLSetKeyBindDialog::recordKey(key, mask)) +    { +        LL_DEBUGS() << "Key handled by LLSetKeyBindDialog" << LL_ENDL; +        LLViewerEventRecorder::instance().logKeyEvent(key,mask); +        return TRUE; +    } +      LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();      if (keyboard_focus | 
