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 | |
parent | 6597c7696783ce56f89b34a4b6440363635be6a6 (diff) |
SL-6109 Fixed conflict resolution issue caused by menu accelerators
-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 |