SL-6109 Fixed conflict resolution issue caused by menu accelerators

master
andreykproductengine 2019-10-28 18:27:13 +02:00
parent 317dd0e405
commit 8ccf79735e
6 changed files with 104 additions and 39 deletions

View File

@ -212,6 +212,12 @@ LLSD LLMenuItemGL::getValue() const
return getLabel();
}
//virtual
bool LLMenuItemGL::hasAccelerator(const KEY &key, const MASK &mask) const
{
return (mAcceleratorKey == key) && (mAcceleratorMask == mask);
}
//virtual
BOOL LLMenuItemGL::handleAcceleratorKey(KEY key, MASK mask)
{
@ -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);
@ -3001,6 +3012,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
@ -3514,27 +3546,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()
{

View File

@ -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;
@ -632,6 +634,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
@ -792,8 +795,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 );

View File

@ -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)

View File

@ -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),
@ -93,9 +94,17 @@ BOOL LLSetKeyBindDialog::postBuild()
return TRUE;
}
//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)

View File

@ -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
};

View File

@ -45,6 +45,7 @@
#include "llmeshrepository.h"
#include "llnotificationhandler.h"
#include "llpanellogin.h"
#include "llsetkeybinddialog.h"
#include "llviewerinput.h"
#include "llviewermenu.h"
@ -2716,6 +2717,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