SL-6109 Fixed conflict resolution issue caused by menu accelerators
parent
317dd0e405
commit
8ccf79735e
|
|
@ -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()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue