Bug 1333459 - part1: Move methods of EventStateManager which check modifiers of access key to WidgetKeyboardEvent r=smaug

EventStateManager checks if every keypress event's modifiers match with access key modifiers which are in prefs. Moving related methods of this to WidgetKeyboardEvent makes EventStateManager simpler and we can hide the NS_MODIFIER_* constants (they may make developers confused between Modifiers of WidgetInputEvent) into WidgetEventImpl.cpp.

MozReview-Commit-ID: 23NUQ51lJ1M

--HG--
extra : rebase_source : 341f3764ef62575577572d8b349159e2d5512b26
This commit is contained in:
Masayuki Nakano 2017-07-06 17:36:19 +09:00
Родитель a7be68f59a
Коммит 6c68caecd7
10 изменённых файлов: 213 добавлений и 162 удалений

Просмотреть файл

@ -186,13 +186,6 @@ PrintDocTreeAll(nsIDocShellTreeItem* aItem)
} }
#endif #endif
// mask values for ui.key.chromeAccess and ui.key.contentAccess
#define NS_MODIFIER_SHIFT 1
#define NS_MODIFIER_CONTROL 2
#define NS_MODIFIER_ALT 4
#define NS_MODIFIER_META 8
#define NS_MODIFIER_OS 16
/******************************************************************/ /******************************************************************/
/* mozilla::UITimerCallback */ /* mozilla::UITimerCallback */
/******************************************************************/ /******************************************************************/
@ -768,32 +761,13 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext,
case eKeyPress: case eKeyPress:
{ {
WidgetKeyboardEvent* keyEvent = aEvent->AsKeyboardEvent(); WidgetKeyboardEvent* keyEvent = aEvent->AsKeyboardEvent();
if (keyEvent->ModifiersMatchWithAccessKey(AccessKeyType::eChrome) ||
keyEvent->ModifiersMatchWithAccessKey(AccessKeyType::eContent)) {
AutoTArray<uint32_t, 10> accessCharCodes;
keyEvent->GetAccessKeyCandidates(accessCharCodes);
int32_t modifierMask = 0; if (HandleAccessKey(keyEvent, aPresContext, accessCharCodes)) {
if (keyEvent->IsShift()) *aStatus = nsEventStatus_eConsumeNoDefault;
modifierMask |= NS_MODIFIER_SHIFT;
if (keyEvent->IsControl())
modifierMask |= NS_MODIFIER_CONTROL;
if (keyEvent->IsAlt())
modifierMask |= NS_MODIFIER_ALT;
if (keyEvent->IsMeta())
modifierMask |= NS_MODIFIER_META;
if (keyEvent->IsOS())
modifierMask |= NS_MODIFIER_OS;
// Prevent keyboard scrolling while an accesskey modifier is in use.
if (modifierMask) {
bool matchesContentAccessKey = (modifierMask == Prefs::ContentAccessModifierMask());
if (modifierMask == Prefs::ChromeAccessModifierMask() ||
matchesContentAccessKey) {
AutoTArray<uint32_t, 10> accessCharCodes;
keyEvent->GetAccessKeyCandidates(accessCharCodes);
if (HandleAccessKey(keyEvent, aPresContext, accessCharCodes,
modifierMask, matchesContentAccessKey)) {
*aStatus = nsEventStatus_eConsumeNoDefault;
}
} }
} }
} }
@ -924,23 +898,21 @@ EventStateManager::HandleQueryContentEvent(WidgetQueryContentEvent* aEvent)
handler.HandleQueryContentEvent(aEvent); handler.HandleQueryContentEvent(aEvent);
} }
// static static AccessKeyType
int32_t GetAccessKeyTypeFor(nsISupports* aDocShell)
EventStateManager::GetAccessModifierMaskFor(nsISupports* aDocShell)
{ {
nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(aDocShell)); nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(aDocShell));
if (!treeItem) if (!treeItem) {
return -1; // invalid modifier return AccessKeyType::eNone;
}
switch (treeItem->ItemType()) { switch (treeItem->ItemType()) {
case nsIDocShellTreeItem::typeChrome: case nsIDocShellTreeItem::typeChrome:
return Prefs::ChromeAccessModifierMask(); return AccessKeyType::eChrome;
case nsIDocShellTreeItem::typeContent:
case nsIDocShellTreeItem::typeContent: return AccessKeyType::eContent;
return Prefs::ContentAccessModifierMask(); default:
return AccessKeyType::eNone;
default:
return -1; // invalid modifier
} }
} }
@ -1059,30 +1031,33 @@ EventStateManager::GetAccessKeyLabelPrefix(Element* aElement, nsAString& aPrefix
nsAutoString separator, modifierText; nsAutoString separator, modifierText;
nsContentUtils::GetModifierSeparatorText(separator); nsContentUtils::GetModifierSeparatorText(separator);
nsCOMPtr<nsISupports> container = aElement->OwnerDoc()->GetDocShell(); AccessKeyType accessKeyType =
int32_t modifierMask = GetAccessModifierMaskFor(container); GetAccessKeyTypeFor(aElement->OwnerDoc()->GetDocShell());
if (accessKeyType == AccessKeyType::eNone) {
if (modifierMask == -1) { return;
}
Modifiers modifiers = WidgetKeyboardEvent::AccessKeyModifiers(accessKeyType);
if (modifiers == MODIFIER_NONE) {
return; return;
} }
if (modifierMask & NS_MODIFIER_CONTROL) { if (modifiers & MODIFIER_CONTROL) {
nsContentUtils::GetControlText(modifierText); nsContentUtils::GetControlText(modifierText);
aPrefix.Append(modifierText + separator); aPrefix.Append(modifierText + separator);
} }
if (modifierMask & NS_MODIFIER_META) { if (modifiers & MODIFIER_META) {
nsContentUtils::GetMetaText(modifierText); nsContentUtils::GetMetaText(modifierText);
aPrefix.Append(modifierText + separator); aPrefix.Append(modifierText + separator);
} }
if (modifierMask & NS_MODIFIER_OS) { if (modifiers & MODIFIER_OS) {
nsContentUtils::GetOSText(modifierText); nsContentUtils::GetOSText(modifierText);
aPrefix.Append(modifierText + separator); aPrefix.Append(modifierText + separator);
} }
if (modifierMask & NS_MODIFIER_ALT) { if (modifiers & MODIFIER_ALT) {
nsContentUtils::GetAltText(modifierText); nsContentUtils::GetAltText(modifierText);
aPrefix.Append(modifierText + separator); aPrefix.Append(modifierText + separator);
} }
if (modifierMask & NS_MODIFIER_SHIFT) { if (modifiers & MODIFIER_SHIFT) {
nsContentUtils::GetShiftText(modifierText); nsContentUtils::GetShiftText(modifierText);
aPrefix.Append(modifierText + separator); aPrefix.Append(modifierText + separator);
} }
@ -1092,12 +1067,11 @@ struct MOZ_STACK_CLASS AccessKeyInfo
{ {
WidgetKeyboardEvent* event; WidgetKeyboardEvent* event;
nsTArray<uint32_t>& charCodes; nsTArray<uint32_t>& charCodes;
int32_t modifierMask;
AccessKeyInfo(WidgetKeyboardEvent* aEvent, nsTArray<uint32_t>& aCharCodes, int32_t aModifierMask) AccessKeyInfo(WidgetKeyboardEvent* aEvent,
nsTArray<uint32_t>& aCharCodes)
: event(aEvent) : event(aEvent)
, charCodes(aCharCodes) , charCodes(aCharCodes)
, modifierMask(aModifierMask)
{ {
} }
}; };
@ -1113,8 +1087,7 @@ HandleAccessKeyInRemoteChild(TabParent* aTabParent, void* aArg)
if (active) { if (active) {
accessKeyInfo->event->mAccessKeyForwardedToChild = true; accessKeyInfo->event->mAccessKeyForwardedToChild = true;
aTabParent->HandleAccessKey(*accessKeyInfo->event, aTabParent->HandleAccessKey(*accessKeyInfo->event,
accessKeyInfo->charCodes, accessKeyInfo->charCodes);
accessKeyInfo->modifierMask);
return true; return true;
} }
@ -1125,20 +1098,21 @@ bool
EventStateManager::HandleAccessKey(WidgetKeyboardEvent* aEvent, EventStateManager::HandleAccessKey(WidgetKeyboardEvent* aEvent,
nsPresContext* aPresContext, nsPresContext* aPresContext,
nsTArray<uint32_t>& aAccessCharCodes, nsTArray<uint32_t>& aAccessCharCodes,
bool aMatchesContentAccessKey,
nsIDocShellTreeItem* aBubbledFrom, nsIDocShellTreeItem* aBubbledFrom,
ProcessingAccessKeyState aAccessKeyState, ProcessingAccessKeyState aAccessKeyState)
int32_t aModifierMask)
{ {
EnsureDocument(mPresContext); EnsureDocument(mPresContext);
nsCOMPtr<nsIDocShell> docShell = aPresContext->GetDocShell(); nsCOMPtr<nsIDocShell> docShell = aPresContext->GetDocShell();
if (NS_WARN_IF(!docShell) || NS_WARN_IF(!mDocument)) { if (NS_WARN_IF(!docShell) || NS_WARN_IF(!mDocument)) {
return false; return false;
} }
AccessKeyType accessKeyType = GetAccessKeyTypeFor(docShell);
if (accessKeyType == AccessKeyType::eNone) {
return false;
}
// Alt or other accesskey modifier is down, we may need to do an accesskey. // Alt or other accesskey modifier is down, we may need to do an accesskey.
if (mAccessKeys.Count() > 0 && if (mAccessKeys.Count() > 0 &&
aModifierMask == GetAccessModifierMaskFor(docShell)) { aEvent->ModifiersMatchWithAccessKey(accessKeyType)) {
// Someone registered an accesskey. Find and activate it. // Someone registered an accesskey. Find and activate it.
if (ExecuteAccessKey(aAccessCharCodes, aEvent->IsTrusted())) { if (ExecuteAccessKey(aAccessCharCodes, aEvent->IsTrusted())) {
return true; return true;
@ -1174,8 +1148,7 @@ EventStateManager::HandleAccessKey(WidgetKeyboardEvent* aEvent,
if (esm && if (esm &&
esm->HandleAccessKey(aEvent, subPC, aAccessCharCodes, esm->HandleAccessKey(aEvent, subPC, aAccessCharCodes,
aMatchesContentAccessKey, nullptr, nullptr, eAccessKeyProcessingDown)) {
eAccessKeyProcessingDown, aModifierMask)) {
return true; return true;
} }
} }
@ -1197,15 +1170,15 @@ EventStateManager::HandleAccessKey(WidgetKeyboardEvent* aEvent,
static_cast<EventStateManager*>(parentPC->EventStateManager()); static_cast<EventStateManager*>(parentPC->EventStateManager());
if (esm && if (esm &&
esm->HandleAccessKey(aEvent, parentPC, aAccessCharCodes, esm->HandleAccessKey(aEvent, parentPC, aAccessCharCodes,
aMatchesContentAccessKey, docShell, docShell, eAccessKeyProcessingDown)) {
eAccessKeyProcessingDown, aModifierMask)) {
return true; return true;
} }
} }
}// if end. bubble up process }// if end. bubble up process
// If the content access key modifier is pressed, try remote children // If the content access key modifier is pressed, try remote children
if (aMatchesContentAccessKey && mDocument && mDocument->GetWindow()) { if (aEvent->ModifiersMatchWithAccessKey(AccessKeyType::eContent) &&
mDocument && mDocument->GetWindow()) {
// If the focus is currently on a node with a TabParent, the key event will // If the focus is currently on a node with a TabParent, the key event will
// get forwarded to the child process and HandleAccessKey called from there. // get forwarded to the child process and HandleAccessKey called from there.
// If focus is somewhere else, then we need to check the remote children. // If focus is somewhere else, then we need to check the remote children.
@ -1216,9 +1189,10 @@ EventStateManager::HandleAccessKey(WidgetKeyboardEvent* aEvent,
// the child process. // the child process.
aEvent->mAccessKeyForwardedToChild = true; aEvent->mAccessKeyForwardedToChild = true;
} else { } else {
AccessKeyInfo accessKeyInfo(aEvent, aAccessCharCodes, aModifierMask); AccessKeyInfo accessKeyInfo(aEvent, aAccessCharCodes);
nsContentUtils::CallOnAllRemoteChildren(mDocument->GetWindow(), nsContentUtils::CallOnAllRemoteChildren(mDocument->GetWindow(),
HandleAccessKeyInRemoteChild, &accessKeyInfo); HandleAccessKeyInRemoteChild,
&accessKeyInfo);
} }
} }
@ -5819,9 +5793,6 @@ EventStateManager::WheelPrefs::IsOverOnePageScrollAllowedY(
bool EventStateManager::Prefs::sKeyCausesActivation = true; bool EventStateManager::Prefs::sKeyCausesActivation = true;
bool EventStateManager::Prefs::sClickHoldContextMenu = false; bool EventStateManager::Prefs::sClickHoldContextMenu = false;
int32_t EventStateManager::Prefs::sGenericAccessModifierKey = -1;
int32_t EventStateManager::Prefs::sChromeAccessModifierMask = 0;
int32_t EventStateManager::Prefs::sContentAccessModifierMask = 0;
// static // static
void void
@ -5846,21 +5817,6 @@ EventStateManager::Prefs::Init()
sClickHoldContextMenu); sClickHoldContextMenu);
MOZ_ASSERT(NS_SUCCEEDED(rv), MOZ_ASSERT(NS_SUCCEEDED(rv),
"Failed to observe \"ui.click_hold_context_menus\""); "Failed to observe \"ui.click_hold_context_menus\"");
rv = Preferences::AddIntVarCache(&sGenericAccessModifierKey,
"ui.key.generalAccessKey",
sGenericAccessModifierKey);
MOZ_ASSERT(NS_SUCCEEDED(rv),
"Failed to observe \"ui.key.generalAccessKey\"");
rv = Preferences::AddIntVarCache(&sChromeAccessModifierMask,
"ui.key.chromeAccess",
sChromeAccessModifierMask);
MOZ_ASSERT(NS_SUCCEEDED(rv),
"Failed to observe \"ui.key.chromeAccess\"");
rv = Preferences::AddIntVarCache(&sContentAccessModifierMask,
"ui.key.contentAccess",
sContentAccessModifierMask);
MOZ_ASSERT(NS_SUCCEEDED(rv),
"Failed to observe \"ui.key.contentAccess\"");
sPrefsAlreadyCached = true; sPrefsAlreadyCached = true;
} }
@ -5881,44 +5837,6 @@ EventStateManager::Prefs::Shutdown()
Preferences::UnregisterCallback(OnChange, "dom.popup_allowed_events"); Preferences::UnregisterCallback(OnChange, "dom.popup_allowed_events");
} }
// static
int32_t
EventStateManager::Prefs::ChromeAccessModifierMask()
{
return GetAccessModifierMask(nsIDocShellTreeItem::typeChrome);
}
// static
int32_t
EventStateManager::Prefs::ContentAccessModifierMask()
{
return GetAccessModifierMask(nsIDocShellTreeItem::typeContent);
}
// static
int32_t
EventStateManager::Prefs::GetAccessModifierMask(int32_t aItemType)
{
switch (sGenericAccessModifierKey) {
case -1: break; // use the individual prefs
case nsIDOMKeyEvent::DOM_VK_SHIFT: return NS_MODIFIER_SHIFT;
case nsIDOMKeyEvent::DOM_VK_CONTROL: return NS_MODIFIER_CONTROL;
case nsIDOMKeyEvent::DOM_VK_ALT: return NS_MODIFIER_ALT;
case nsIDOMKeyEvent::DOM_VK_META: return NS_MODIFIER_META;
case nsIDOMKeyEvent::DOM_VK_WIN: return NS_MODIFIER_OS;
default: return 0;
}
switch (aItemType) {
case nsIDocShellTreeItem::typeChrome:
return sChromeAccessModifierMask;
case nsIDocShellTreeItem::typeContent:
return sContentAccessModifierMask;
default:
return 0;
}
}
/******************************************************************/ /******************************************************************/
/* mozilla::AutoHandlingUserInputStatePusher */ /* mozilla::AutoHandlingUserInputStatePusher */
/******************************************************************/ /******************************************************************/

Просмотреть файл

@ -186,13 +186,10 @@ public:
bool HandleAccessKey(WidgetKeyboardEvent* aEvent, bool HandleAccessKey(WidgetKeyboardEvent* aEvent,
nsPresContext* aPresContext, nsPresContext* aPresContext,
nsTArray<uint32_t>& aAccessCharCodes, nsTArray<uint32_t>& aAccessCharCodes)
int32_t aModifierMask,
bool aMatchesContentAccessKey)
{ {
return HandleAccessKey(aEvent, aPresContext, aAccessCharCodes, return HandleAccessKey(aEvent, aPresContext, aAccessCharCodes,
aMatchesContentAccessKey, nullptr, nullptr, eAccessKeyProcessingNormal);
eAccessKeyProcessingNormal, aModifierMask);
} }
nsresult SetCursor(int32_t aCursor, imgIContainer* aContainer, nsresult SetCursor(int32_t aCursor, imgIContainer* aContainer,
@ -316,8 +313,6 @@ protected:
public: public:
static bool KeyCausesActivation() { return sKeyCausesActivation; } static bool KeyCausesActivation() { return sKeyCausesActivation; }
static bool ClickHoldContextMenu() { return sClickHoldContextMenu; } static bool ClickHoldContextMenu() { return sClickHoldContextMenu; }
static int32_t ChromeAccessModifierMask();
static int32_t ContentAccessModifierMask();
static void Init(); static void Init();
static void OnChange(const char* aPrefName, void*); static void OnChange(const char* aPrefName, void*);
@ -326,19 +321,10 @@ protected:
private: private:
static bool sKeyCausesActivation; static bool sKeyCausesActivation;
static bool sClickHoldContextMenu; static bool sClickHoldContextMenu;
static int32_t sGenericAccessModifierKey;
static int32_t sChromeAccessModifierMask;
static int32_t sContentAccessModifierMask;
static int32_t GetAccessModifierMask(int32_t aItemType); static int32_t GetAccessModifierMask(int32_t aItemType);
}; };
/**
* Get appropriate access modifier mask for the aDocShell. Returns -1 if
* access key isn't available.
*/
static int32_t GetAccessModifierMaskFor(nsISupports* aDocShell);
/* /*
* If aTargetFrame's widget has a cached cursor value, resets the cursor * If aTargetFrame's widget has a cached cursor value, resets the cursor
* such that the next call to SetCursor on the widget will force an update * such that the next call to SetCursor on the widget will force an update
@ -449,7 +435,6 @@ protected:
* @param aEvent the keyboard event triggering the acccess key * @param aEvent the keyboard event triggering the acccess key
* @param aPresContext the presentation context * @param aPresContext the presentation context
* @param aAccessCharCodes list of charcode candidates * @param aAccessCharCodes list of charcode candidates
* @param aMatchesContentAccessKey true if the content accesskey modifier is pressed
* @param aBubbledFrom is used by an ancestor to avoid calling HandleAccessKey() * @param aBubbledFrom is used by an ancestor to avoid calling HandleAccessKey()
* on the child the call originally came from, i.e. this is the child * on the child the call originally came from, i.e. this is the child
* that recursively called us in its Up phase. The initial caller * that recursively called us in its Up phase. The initial caller
@ -457,15 +442,12 @@ protected:
* @param aAccessKeyState Normal, Down or Up processing phase (see enums * @param aAccessKeyState Normal, Down or Up processing phase (see enums
* above). The initial event receiver uses 'normal', then 'down' when * above). The initial event receiver uses 'normal', then 'down' when
* processing children and Up when recursively calling its ancestor. * processing children and Up when recursively calling its ancestor.
* @param aModifierMask modifier mask for the key event
*/ */
bool HandleAccessKey(WidgetKeyboardEvent* aEvent, bool HandleAccessKey(WidgetKeyboardEvent* aEvent,
nsPresContext* aPresContext, nsPresContext* aPresContext,
nsTArray<uint32_t>& aAccessCharCodes, nsTArray<uint32_t>& aAccessCharCodes,
bool aMatchesContentAccessKey,
nsIDocShellTreeItem* aBubbledFrom, nsIDocShellTreeItem* aBubbledFrom,
ProcessingAccessKeyState aAccessKeyState, ProcessingAccessKeyState aAccessKeyState);
int32_t aModifierMask);
bool ExecuteAccessKey(nsTArray<uint32_t>& aAccessCharCodes, bool ExecuteAccessKey(nsTArray<uint32_t>& aAccessCharCodes,
bool aIsTrustedEvent); bool aIsTrustedEvent);

Просмотреть файл

@ -806,10 +806,9 @@ child:
* *
* @param event keyboard event * @param event keyboard event
* @param isTrusted true if triggered by a trusted key event * @param isTrusted true if triggered by a trusted key event
* @param modifierMask indicates which accesskey modifiers are pressed
*/ */
async HandleAccessKey(WidgetKeyboardEvent event, async HandleAccessKey(WidgetKeyboardEvent event,
uint32_t[] charCodes, int32_t modifierMask); uint32_t[] charCodes);
/** /**
* Tells the root child docShell whether or not to use * Tells the root child docShell whether or not to use

Просмотреть файл

@ -2244,8 +2244,7 @@ TabChild::RecvSwappedWithOtherRemoteLoader(const IPCTabContext& aContext)
mozilla::ipc::IPCResult mozilla::ipc::IPCResult
TabChild::RecvHandleAccessKey(const WidgetKeyboardEvent& aEvent, TabChild::RecvHandleAccessKey(const WidgetKeyboardEvent& aEvent,
nsTArray<uint32_t>&& aCharCodes, nsTArray<uint32_t>&& aCharCodes)
const int32_t& aModifierMask)
{ {
nsCOMPtr<nsIDocument> document(GetDocument()); nsCOMPtr<nsIDocument> document(GetDocument());
nsCOMPtr<nsIPresShell> presShell = document->GetShell(); nsCOMPtr<nsIPresShell> presShell = document->GetShell();
@ -2254,8 +2253,7 @@ TabChild::RecvHandleAccessKey(const WidgetKeyboardEvent& aEvent,
if (pc) { if (pc) {
if (!pc->EventStateManager()-> if (!pc->EventStateManager()->
HandleAccessKey(&(const_cast<WidgetKeyboardEvent&>(aEvent)), HandleAccessKey(&(const_cast<WidgetKeyboardEvent&>(aEvent)),
pc, aCharCodes, pc, aCharCodes)) {
aModifierMask, true)) {
// If no accesskey was found, inform the parent so that accesskeys on // If no accesskey was found, inform the parent so that accesskeys on
// menus can be handled. // menus can be handled.
WidgetKeyboardEvent localEvent(aEvent); WidgetKeyboardEvent localEvent(aEvent);

Просмотреть файл

@ -595,9 +595,9 @@ public:
virtual mozilla::ipc::IPCResult virtual mozilla::ipc::IPCResult
RecvThemeChanged(nsTArray<LookAndFeelInt>&& aLookAndFeelIntCache) override; RecvThemeChanged(nsTArray<LookAndFeelInt>&& aLookAndFeelIntCache) override;
virtual mozilla::ipc::IPCResult RecvHandleAccessKey(const WidgetKeyboardEvent& aEvent, virtual mozilla::ipc::IPCResult
nsTArray<uint32_t>&& aCharCodes, RecvHandleAccessKey(const WidgetKeyboardEvent& aEvent,
const int32_t& aModifierMask) override; nsTArray<uint32_t>&& aCharCodes) override;
virtual mozilla::ipc::IPCResult RecvSetUseGlobalHistory(const bool& aUse) override; virtual mozilla::ipc::IPCResult RecvSetUseGlobalHistory(const bool& aUse) override;

Просмотреть файл

@ -817,15 +817,14 @@ TabParent::ThemeChanged()
void void
TabParent::HandleAccessKey(const WidgetKeyboardEvent& aEvent, TabParent::HandleAccessKey(const WidgetKeyboardEvent& aEvent,
nsTArray<uint32_t>& aCharCodes, nsTArray<uint32_t>& aCharCodes)
const int32_t& aModifierMask)
{ {
if (!mIsDestroyed) { if (!mIsDestroyed) {
// Note that we don't need to mark aEvent is posted to a remote process // Note that we don't need to mark aEvent is posted to a remote process
// because the event may be dispatched to it as normal keyboard event. // because the event may be dispatched to it as normal keyboard event.
// Therefore, we should use local copy to send it. // Therefore, we should use local copy to send it.
WidgetKeyboardEvent localEvent(aEvent); WidgetKeyboardEvent localEvent(aEvent);
Unused << SendHandleAccessKey(localEvent, aCharCodes, aModifierMask); Unused << SendHandleAccessKey(localEvent, aCharCodes);
} }
} }

Просмотреть файл

@ -361,8 +361,7 @@ public:
void ThemeChanged(); void ThemeChanged();
void HandleAccessKey(const WidgetKeyboardEvent& aEvent, void HandleAccessKey(const WidgetKeyboardEvent& aEvent,
nsTArray<uint32_t>& aCharCodes, nsTArray<uint32_t>& aCharCodes);
const int32_t& aModifierMask);
void Activate(); void Activate();

Просмотреть файл

@ -150,6 +150,8 @@ class WidgetEventTime;
class NativeEventData; class NativeEventData;
// TextEvents.h // TextEvents.h
enum class AccessKeyType;
struct AlternativeCharCode; struct AlternativeCharCode;
struct ShortcutKeyCandidate; struct ShortcutKeyCandidate;

Просмотреть файл

@ -59,6 +59,16 @@ namespace plugins {
class PPluginInstanceChild; class PPluginInstanceChild;
} // namespace plugins } // namespace plugins
enum class AccessKeyType
{
// Handle access key for chrome.
eChrome,
// Handle access key for content.
eContent,
// Don't handle access key.
eNone
};
/****************************************************************************** /******************************************************************************
* mozilla::AlternativeCharCode * mozilla::AlternativeCharCode
* *
@ -431,6 +441,24 @@ public:
*/ */
void GetAccessKeyCandidates(nsTArray<uint32_t>& aCandidates) const; void GetAccessKeyCandidates(nsTArray<uint32_t>& aCandidates) const;
/**
* Check whether the modifiers match with chrome access key or
* content access key.
*/
bool ModifiersMatchWithAccessKey(AccessKeyType aType) const;
/**
* Return active modifiers which may match with access key.
* For example, even if Alt is access key modifier, then, when Control,
* CapseLock and NumLock are active, this returns only MODIFIER_CONTROL.
*/
Modifiers ModifiersForAccessKeyMatching() const;
/**
* Return access key modifiers.
*/
static Modifiers AccessKeyModifiers(AccessKeyType aType);
static void Shutdown(); static void Shutdown();
/** /**
@ -565,6 +593,10 @@ private:
"Invalid native key binding type"); "Invalid native key binding type");
} }
} }
static int32_t GenericAccessModifierKeyPref();
static int32_t ChromeAccessModifierMaskPref();
static int32_t ContentAccessModifierMaskPref();
}; };
/****************************************************************************** /******************************************************************************

Просмотреть файл

@ -869,6 +869,128 @@ WidgetKeyboardEvent::GetAccessKeyCandidates(nsTArray<uint32_t>& aCandidates) con
} }
} }
// mask values for ui.key.chromeAccess and ui.key.contentAccess
#define NS_MODIFIER_SHIFT 1
#define NS_MODIFIER_CONTROL 2
#define NS_MODIFIER_ALT 4
#define NS_MODIFIER_META 8
#define NS_MODIFIER_OS 16
static Modifiers PrefFlagsToModifiers(int32_t aPrefFlags)
{
Modifiers result = 0;
if (aPrefFlags & NS_MODIFIER_SHIFT) {
result |= MODIFIER_SHIFT;
}
if (aPrefFlags & NS_MODIFIER_CONTROL) {
result |= MODIFIER_CONTROL;
}
if (aPrefFlags & NS_MODIFIER_ALT) {
result |= MODIFIER_ALT;
}
if (aPrefFlags & NS_MODIFIER_META) {
result |= MODIFIER_META;
}
if (aPrefFlags & NS_MODIFIER_OS) {
result |= MODIFIER_OS;
}
return result;
}
bool
WidgetKeyboardEvent::ModifiersMatchWithAccessKey(AccessKeyType aType) const
{
if (!ModifiersForAccessKeyMatching()) {
return false;
}
return ModifiersForAccessKeyMatching() == AccessKeyModifiers(aType);
}
Modifiers
WidgetKeyboardEvent::ModifiersForAccessKeyMatching() const
{
static const Modifiers kModifierMask =
MODIFIER_SHIFT | MODIFIER_CONTROL |
MODIFIER_ALT | MODIFIER_META | MODIFIER_OS;
return mModifiers & kModifierMask;
}
/* static */
Modifiers
WidgetKeyboardEvent::AccessKeyModifiers(AccessKeyType aType)
{
switch (GenericAccessModifierKeyPref()) {
case -1:
break; // use the individual prefs
case NS_VK_SHIFT:
return MODIFIER_SHIFT;
case NS_VK_CONTROL:
return MODIFIER_CONTROL;
case NS_VK_ALT:
return MODIFIER_ALT;
case NS_VK_META:
return MODIFIER_META;
case NS_VK_WIN:
return MODIFIER_OS;
default:
return MODIFIER_NONE;
}
switch (aType) {
case AccessKeyType::eChrome:
return PrefFlagsToModifiers(ChromeAccessModifierMaskPref());
case AccessKeyType::eContent:
return PrefFlagsToModifiers(ContentAccessModifierMaskPref());
default:
return MODIFIER_NONE;
}
}
/* static */
int32_t
WidgetKeyboardEvent::GenericAccessModifierKeyPref()
{
static bool sInitialized = false;
static int32_t sValue = -1;
if (!sInitialized) {
nsresult rv =
Preferences::AddIntVarCache(&sValue, "ui.key.generalAccessKey", sValue);
sInitialized = NS_SUCCEEDED(rv);
MOZ_ASSERT(sInitialized);
}
return sValue;
}
/* static */
int32_t
WidgetKeyboardEvent::ChromeAccessModifierMaskPref()
{
static bool sInitialized = false;
static int32_t sValue = 0;
if (!sInitialized) {
nsresult rv =
Preferences::AddIntVarCache(&sValue, "ui.key.chromeAccess", sValue);
sInitialized = NS_SUCCEEDED(rv);
MOZ_ASSERT(sInitialized);
}
return sValue;
}
/* static */
int32_t
WidgetKeyboardEvent::ContentAccessModifierMaskPref()
{
static bool sInitialized = false;
static int32_t sValue = 0;
if (!sInitialized) {
nsresult rv =
Preferences::AddIntVarCache(&sValue, "ui.key.contentAccess", sValue);
sInitialized = NS_SUCCEEDED(rv);
MOZ_ASSERT(sInitialized);
}
return sValue;
}
/* static */ void /* static */ void
WidgetKeyboardEvent::Shutdown() WidgetKeyboardEvent::Shutdown()
{ {