summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandreykproductengine <andreykproductengine@lindenlab.com>2019-10-28 18:27:13 +0200
committerAndrey Kleshchev <andreykproductengine@lindenlab.com>2020-06-23 14:50:03 +0300
commit62214b53f09c453dc410465ba6e64a772562e6db (patch)
treeb3f0f8797c7efa3c1f7da0c436dde685e0d9290c
parent6597c7696783ce56f89b34a4b6440363635be6a6 (diff)
SL-6109 Fixed conflict resolution issue caused by menu accelerators
-rw-r--r--indra/llui/llmenugl.cpp53
-rw-r--r--indra/llui/llmenugl.h7
-rw-r--r--indra/newview/llkeyconflict.cpp12
-rw-r--r--indra/newview/llsetkeybinddialog.cpp53
-rw-r--r--indra/newview/llsetkeybinddialog.h9
-rw-r--r--indra/newview/llviewerwindow.cpp9
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