23587: Make accelerator and menu access keys settable through a pref. r=saari

This commit is contained in:
akkana%netscape.com 2000-08-17 00:09:16 +00:00
parent 86a7443013
commit 6c14f21233
15 changed files with 401 additions and 212 deletions

View File

@ -45,6 +45,10 @@
#include "nsIDOMEventReceiver.h" #include "nsIDOMEventReceiver.h"
#include "nsXBLBinding.h" #include "nsXBLBinding.h"
#include "nsIPrivateDOMEvent.h" #include "nsIPrivateDOMEvent.h"
#include "nsIPref.h"
#include "nsIServiceManager.h"
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
PRUint32 nsXBLEventHandler::gRefCnt = 0; PRUint32 nsXBLEventHandler::gRefCnt = 0;
nsIAtom* nsXBLEventHandler::kKeyCodeAtom = nsnull; nsIAtom* nsXBLEventHandler::kKeyCodeAtom = nsnull;
@ -71,6 +75,7 @@ nsXBLEventHandler::nsXBLEventHandler(nsIContent* aBoundElement, nsIContent* aHan
mEventName.Assign(aEventName); mEventName.Assign(aEventName);
mNextHandler = nsnull; mNextHandler = nsnull;
gRefCnt++; gRefCnt++;
mAccessKey = -1;
if (gRefCnt == 1) { if (gRefCnt == 1) {
kKeyCodeAtom = NS_NewAtom("keycode"); kKeyCodeAtom = NS_NewAtom("keycode");
kKeyAtom = NS_NewAtom("key"); kKeyAtom = NS_NewAtom("key");
@ -371,7 +376,38 @@ nsresult nsXBLEventHandler::Destroy(nsIDOMEvent* aEvent)
return NS_OK; return NS_OK;
} }
/////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Get the menu access key from prefs.
// XXX Eventually pick up using CSS3 key-equivalent property or somesuch
void
nsXBLEventHandler::InitAccessKey()
{
if (mAccessKey >= 0)
return;
// Compiled-in defaults, in case we can't get the pref --
// mac doesn't have menu shortcuts, other platforms use alt.
#ifndef XP_MAC
mAccessKey = nsIDOMKeyEvent::DOM_VK_ALT;
#else
mAccessKey = 0;
#endif
// Get the menu access key value from prefs, overriding the default:
nsresult rv;
NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_PROGID, &rv);
if (NS_SUCCEEDED(rv) && prefs)
{
rv = prefs->GetIntPref("ui.key.menuAccessKey", &mAccessKey);
}
#ifdef DEBUG_akkana
if (NS_FAILED(rv))
{
NS_ASSERTION(PR_FALSE,"XBLEventHandler couldn't get menu access key from prefs!\n");
}
#endif
}
PRBool PRBool
nsXBLEventHandler::KeyEventMatched(nsIDOMKeyEvent* aKeyEvent) nsXBLEventHandler::KeyEventMatched(nsIDOMKeyEvent* aKeyEvent)
@ -409,31 +445,31 @@ nsXBLEventHandler::KeyEventMatched(nsIDOMKeyEvent* aKeyEvent)
// Now check modifier keys // Now check modifier keys
nsAutoString modifier; nsAutoString modifier;
PRBool isModifierPresent;
mHandlerElement->GetAttribute(kNameSpaceID_None, kPrimaryAtom, modifier); mHandlerElement->GetAttribute(kNameSpaceID_None, kPrimaryAtom, modifier);
if (modifier == trueString) {
// The XUL key must be set. Hard code for now.
// XXX Eventually pick up using CSS3 key-equivalent property or somesuch
#ifdef XP_MAC
aKeyEvent->GetMetaKey(&isModifierPresent);
#elif XP_UNIX
aKeyEvent->GetAltKey(&isModifierPresent);
#else
aKeyEvent->GetCtrlKey(&isModifierPresent);
#endif
// Get the xulkey.
InitAccessKey();
PRBool isModifierPresent = PR_FALSE;
switch (mAccessKey)
{
case nsIDOMKeyEvent::DOM_VK_META:
aKeyEvent->GetMetaKey(&isModifierPresent);
break;
case nsIDOMKeyEvent::DOM_VK_ALT:
aKeyEvent->GetAltKey(&isModifierPresent);
break;
case nsIDOMKeyEvent::DOM_VK_CONTROL:
default:
aKeyEvent->GetCtrlKey(&isModifierPresent);
}
if (modifier == trueString) {
if (!isModifierPresent) if (!isModifierPresent)
return PR_FALSE; return PR_FALSE;
} }
else if (modifier == falseString) { else if (modifier == falseString) {
#ifdef XP_MAC
aKeyEvent->GetMetaKey(&isModifierPresent);
#elif XP_UNIX
aKeyEvent->GetAltKey(&isModifierPresent);
#else
aKeyEvent->GetCtrlKey(&isModifierPresent);
#endif
if (isModifierPresent) if (isModifierPresent)
return PR_FALSE; return PR_FALSE;
} }
@ -505,31 +541,30 @@ nsXBLEventHandler::MouseEventMatched(nsIDOMMouseEvent* aMouseEvent)
// XXX Check for button and modifier keys. // XXX Check for button and modifier keys.
// Now check modifier keys // Now check modifier keys
nsAutoString modifier; nsAutoString modifier;
PRBool isModifierPresent;
mHandlerElement->GetAttribute(kNameSpaceID_None, kPrimaryAtom, modifier); mHandlerElement->GetAttribute(kNameSpaceID_None, kPrimaryAtom, modifier);
if (modifier == trueString) {
// The XUL key must be set. Hard code for now.
// XXX Eventually pick up using CSS3 key-equivalent property or somesuch
#ifdef XP_MAC
aMouseEvent->GetMetaKey(&isModifierPresent);
#elif XP_UNIX
aMouseEvent->GetAltKey(&isModifierPresent);
#else
aMouseEvent->GetCtrlKey(&isModifierPresent);
#endif
// Get the xulkey
InitAccessKey();
PRBool isModifierPresent = PR_FALSE;
switch (mAccessKey)
{
case nsIDOMKeyEvent::DOM_VK_META:
aMouseEvent->GetMetaKey(&isModifierPresent);
break;
case nsIDOMKeyEvent::DOM_VK_ALT:
aMouseEvent->GetAltKey(&isModifierPresent);
break;
case nsIDOMKeyEvent::DOM_VK_CONTROL:
default:
aMouseEvent->GetCtrlKey(&isModifierPresent);
}
if (modifier == trueString) {
if (!isModifierPresent) if (!isModifierPresent)
return PR_FALSE; return PR_FALSE;
} }
else if (modifier == falseString) { else if (modifier == falseString) {
#ifdef XP_MAC
aMouseEvent->GetMetaKey(&isModifierPresent);
#elif XP_UNIX
aMouseEvent->GetAltKey(&isModifierPresent);
#else
aMouseEvent->GetCtrlKey(&isModifierPresent);
#endif
if (isModifierPresent) if (isModifierPresent)
return PR_FALSE; return PR_FALSE;
} }

View File

@ -130,6 +130,9 @@ protected:
nsIContent* mHandlerElement; nsIContent* mHandlerElement;
nsAutoString mEventName; nsAutoString mEventName;
void InitAccessKey();
PRInt32 mAccessKey; // the default access key or "xulkey"
nsXBLEventHandler* mNextHandler; // Handlers are chained for easy unloading later. nsXBLEventHandler* mNextHandler; // Handlers are chained for easy unloading later.
}; };

View File

@ -150,7 +150,8 @@ public:
DOM_VK_OPEN_BRACKET = 219, DOM_VK_OPEN_BRACKET = 219,
DOM_VK_BACK_SLASH = 220, DOM_VK_BACK_SLASH = 220,
DOM_VK_CLOSE_BRACKET = 221, DOM_VK_CLOSE_BRACKET = 221,
DOM_VK_QUOTE = 222 DOM_VK_QUOTE = 222,
DOM_VK_META = 224
}; };
NS_IMETHOD GetCharCode(PRUint32* aCharCode)=0; NS_IMETHOD GetCharCode(PRUint32* aCharCode)=0;

View File

@ -123,6 +123,8 @@
const unsigned long DOM_VK_CLOSE_BRACKET = 0xDD; const unsigned long DOM_VK_CLOSE_BRACKET = 0xDD;
const unsigned long DOM_VK_QUOTE = 0xDE; const unsigned long DOM_VK_QUOTE = 0xDE;
const unsigned long DOM_VK_META = 0xE0;
readonly attribute unsigned long charCode; readonly attribute unsigned long charCode;
readonly attribute unsigned long keyCode; readonly attribute unsigned long keyCode;

View File

@ -45,6 +45,10 @@
#include "nsIDOMEventReceiver.h" #include "nsIDOMEventReceiver.h"
#include "nsXBLBinding.h" #include "nsXBLBinding.h"
#include "nsIPrivateDOMEvent.h" #include "nsIPrivateDOMEvent.h"
#include "nsIPref.h"
#include "nsIServiceManager.h"
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
PRUint32 nsXBLEventHandler::gRefCnt = 0; PRUint32 nsXBLEventHandler::gRefCnt = 0;
nsIAtom* nsXBLEventHandler::kKeyCodeAtom = nsnull; nsIAtom* nsXBLEventHandler::kKeyCodeAtom = nsnull;
@ -71,6 +75,7 @@ nsXBLEventHandler::nsXBLEventHandler(nsIContent* aBoundElement, nsIContent* aHan
mEventName.Assign(aEventName); mEventName.Assign(aEventName);
mNextHandler = nsnull; mNextHandler = nsnull;
gRefCnt++; gRefCnt++;
mAccessKey = -1;
if (gRefCnt == 1) { if (gRefCnt == 1) {
kKeyCodeAtom = NS_NewAtom("keycode"); kKeyCodeAtom = NS_NewAtom("keycode");
kKeyAtom = NS_NewAtom("key"); kKeyAtom = NS_NewAtom("key");
@ -371,7 +376,38 @@ nsresult nsXBLEventHandler::Destroy(nsIDOMEvent* aEvent)
return NS_OK; return NS_OK;
} }
/////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Get the menu access key from prefs.
// XXX Eventually pick up using CSS3 key-equivalent property or somesuch
void
nsXBLEventHandler::InitAccessKey()
{
if (mAccessKey >= 0)
return;
// Compiled-in defaults, in case we can't get the pref --
// mac doesn't have menu shortcuts, other platforms use alt.
#ifndef XP_MAC
mAccessKey = nsIDOMKeyEvent::DOM_VK_ALT;
#else
mAccessKey = 0;
#endif
// Get the menu access key value from prefs, overriding the default:
nsresult rv;
NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_PROGID, &rv);
if (NS_SUCCEEDED(rv) && prefs)
{
rv = prefs->GetIntPref("ui.key.menuAccessKey", &mAccessKey);
}
#ifdef DEBUG_akkana
if (NS_FAILED(rv))
{
NS_ASSERTION(PR_FALSE,"XBLEventHandler couldn't get menu access key from prefs!\n");
}
#endif
}
PRBool PRBool
nsXBLEventHandler::KeyEventMatched(nsIDOMKeyEvent* aKeyEvent) nsXBLEventHandler::KeyEventMatched(nsIDOMKeyEvent* aKeyEvent)
@ -409,31 +445,31 @@ nsXBLEventHandler::KeyEventMatched(nsIDOMKeyEvent* aKeyEvent)
// Now check modifier keys // Now check modifier keys
nsAutoString modifier; nsAutoString modifier;
PRBool isModifierPresent;
mHandlerElement->GetAttribute(kNameSpaceID_None, kPrimaryAtom, modifier); mHandlerElement->GetAttribute(kNameSpaceID_None, kPrimaryAtom, modifier);
if (modifier == trueString) {
// The XUL key must be set. Hard code for now.
// XXX Eventually pick up using CSS3 key-equivalent property or somesuch
#ifdef XP_MAC
aKeyEvent->GetMetaKey(&isModifierPresent);
#elif XP_UNIX
aKeyEvent->GetAltKey(&isModifierPresent);
#else
aKeyEvent->GetCtrlKey(&isModifierPresent);
#endif
// Get the xulkey.
InitAccessKey();
PRBool isModifierPresent = PR_FALSE;
switch (mAccessKey)
{
case nsIDOMKeyEvent::DOM_VK_META:
aKeyEvent->GetMetaKey(&isModifierPresent);
break;
case nsIDOMKeyEvent::DOM_VK_ALT:
aKeyEvent->GetAltKey(&isModifierPresent);
break;
case nsIDOMKeyEvent::DOM_VK_CONTROL:
default:
aKeyEvent->GetCtrlKey(&isModifierPresent);
}
if (modifier == trueString) {
if (!isModifierPresent) if (!isModifierPresent)
return PR_FALSE; return PR_FALSE;
} }
else if (modifier == falseString) { else if (modifier == falseString) {
#ifdef XP_MAC
aKeyEvent->GetMetaKey(&isModifierPresent);
#elif XP_UNIX
aKeyEvent->GetAltKey(&isModifierPresent);
#else
aKeyEvent->GetCtrlKey(&isModifierPresent);
#endif
if (isModifierPresent) if (isModifierPresent)
return PR_FALSE; return PR_FALSE;
} }
@ -505,31 +541,30 @@ nsXBLEventHandler::MouseEventMatched(nsIDOMMouseEvent* aMouseEvent)
// XXX Check for button and modifier keys. // XXX Check for button and modifier keys.
// Now check modifier keys // Now check modifier keys
nsAutoString modifier; nsAutoString modifier;
PRBool isModifierPresent;
mHandlerElement->GetAttribute(kNameSpaceID_None, kPrimaryAtom, modifier); mHandlerElement->GetAttribute(kNameSpaceID_None, kPrimaryAtom, modifier);
if (modifier == trueString) {
// The XUL key must be set. Hard code for now.
// XXX Eventually pick up using CSS3 key-equivalent property or somesuch
#ifdef XP_MAC
aMouseEvent->GetMetaKey(&isModifierPresent);
#elif XP_UNIX
aMouseEvent->GetAltKey(&isModifierPresent);
#else
aMouseEvent->GetCtrlKey(&isModifierPresent);
#endif
// Get the xulkey
InitAccessKey();
PRBool isModifierPresent = PR_FALSE;
switch (mAccessKey)
{
case nsIDOMKeyEvent::DOM_VK_META:
aMouseEvent->GetMetaKey(&isModifierPresent);
break;
case nsIDOMKeyEvent::DOM_VK_ALT:
aMouseEvent->GetAltKey(&isModifierPresent);
break;
case nsIDOMKeyEvent::DOM_VK_CONTROL:
default:
aMouseEvent->GetCtrlKey(&isModifierPresent);
}
if (modifier == trueString) {
if (!isModifierPresent) if (!isModifierPresent)
return PR_FALSE; return PR_FALSE;
} }
else if (modifier == falseString) { else if (modifier == falseString) {
#ifdef XP_MAC
aMouseEvent->GetMetaKey(&isModifierPresent);
#elif XP_UNIX
aMouseEvent->GetAltKey(&isModifierPresent);
#else
aMouseEvent->GetCtrlKey(&isModifierPresent);
#endif
if (isModifierPresent) if (isModifierPresent)
return PR_FALSE; return PR_FALSE;
} }

View File

@ -130,6 +130,9 @@ protected:
nsIContent* mHandlerElement; nsIContent* mHandlerElement;
nsAutoString mEventName; nsAutoString mEventName;
void InitAccessKey();
PRInt32 mAccessKey; // the default access key or "xulkey"
nsXBLEventHandler* mNextHandler; // Handlers are chained for easy unloading later. nsXBLEventHandler* mNextHandler; // Handlers are chained for easy unloading later.
}; };

View File

@ -46,6 +46,10 @@
#include "nsIView.h" #include "nsIView.h"
#include "nsISupportsArray.h" #include "nsISupportsArray.h"
#include "nsIPref.h"
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
/* /*
* nsMenuBarListener implementation * nsMenuBarListener implementation
*/ */
@ -58,7 +62,7 @@ NS_IMPL_QUERY_INTERFACE3(nsMenuBarListener, nsIDOMKeyListener, nsIDOMFocusListen
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
nsMenuBarListener::nsMenuBarListener(nsMenuBarFrame* aMenuBar) nsMenuBarListener::nsMenuBarListener(nsMenuBarFrame* aMenuBar)
:mAltKeyDown(PR_FALSE) :mAccessKeyDown(PR_FALSE), mAccessKey(-1)
{ {
NS_INIT_REFCNT(); NS_INIT_REFCNT();
mMenuBarFrame = aMenuBar; mMenuBarFrame = aMenuBar;
@ -69,34 +73,64 @@ nsMenuBarListener::~nsMenuBarListener()
{ {
} }
void nsMenuBarListener::InitAccessKey()
{
if (mAccessKey >= 0)
return;
// Compiled-in defaults, in case we can't get LookAndFeel --
// mac doesn't have menu shortcuts, other platforms use alt.
#ifndef XP_MAC
mAccessKey = nsIDOMKeyEvent::DOM_VK_ALT;
#else
mAccessKey = 0;
#endif
// Get the menu access key value from prefs, overriding the default:
nsresult rv;
NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_PROGID, &rv);
if (NS_SUCCEEDED(rv) && prefs)
{
rv = prefs->GetIntPref("ui.key.menuAccessKey", &mAccessKey);
}
#ifdef DEBUG_akkana
if (NS_FAILED(rv))
{
NS_ASSERTION(PR_FALSE,"Menubar listener couldn't get accel key from prefs!\n");
}
#endif
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
nsresult nsresult
nsMenuBarListener::KeyUp(nsIDOMEvent* aKeyEvent) nsMenuBarListener::KeyUp(nsIDOMEvent* aKeyEvent)
{ {
// On a press of the ALT key by itself, we toggle the menu's InitAccessKey();
// active/inactive state.
// Get the ascii key code.
nsCOMPtr<nsIDOMKeyEvent> keyEvent = do_QueryInterface(aKeyEvent);
PRUint32 theChar;
keyEvent->GetKeyCode(&theChar);
#if !defined(XP_UNIX) || defined(NTO) if (mAccessKey)
if (theChar == NS_VK_ALT && mAltKeyDown) { {
// The ALT key was down and is now up. // On a press of the ALT key by itself, we toggle the menu's
mMenuBarFrame->ToggleMenuActiveState(); // active/inactive state.
// Get the ascii key code.
nsCOMPtr<nsIDOMKeyEvent> keyEvent = do_QueryInterface(aKeyEvent);
PRUint32 theChar;
keyEvent->GetKeyCode(&theChar);
if (mAccessKeyDown && (PRInt32)theChar == mAccessKey)
{
// The access key was down and is now up.
mMenuBarFrame->ToggleMenuActiveState();
}
mAccessKeyDown = PR_FALSE;
PRBool active = mMenuBarFrame->IsActive();
if (active) {
aKeyEvent->PreventBubble();
aKeyEvent->PreventCapture();
aKeyEvent->PreventDefault();
return NS_ERROR_BASE; // I am consuming event
}
} }
mAltKeyDown = PR_FALSE;
#endif
PRBool active = mMenuBarFrame->IsActive();
if (active) {
aKeyEvent->PreventBubble();
aKeyEvent->PreventCapture();
aKeyEvent->PreventDefault();
return NS_ERROR_BASE; // I am consuming event
}
return NS_OK; // means I am NOT consuming event return NS_OK; // means I am NOT consuming event
} }
@ -105,36 +139,39 @@ nsMenuBarListener::KeyUp(nsIDOMEvent* aKeyEvent)
nsresult nsresult
nsMenuBarListener::KeyPress(nsIDOMEvent* aKeyEvent) nsMenuBarListener::KeyPress(nsIDOMEvent* aKeyEvent)
{ {
#if !defined(XP_UNIX) || defined(NTO) InitAccessKey();
nsCOMPtr<nsIDOMNSUIEvent> nsUIEvent = do_QueryInterface(aKeyEvent);
PRBool preventDefault;
nsUIEvent->GetPreventDefault(&preventDefault); if (mAccessKey)
if (!preventDefault) { {
nsCOMPtr<nsIDOMKeyEvent> keyEvent = do_QueryInterface(aKeyEvent); nsCOMPtr<nsIDOMNSUIEvent> nsUIEvent = do_QueryInterface(aKeyEvent);
PRUint32 theChar; PRBool preventDefault;
keyEvent->GetKeyCode(&theChar);
if (mAltKeyDown && (theChar != NS_VK_ALT)) { nsUIEvent->GetPreventDefault(&preventDefault);
mAltKeyDown = PR_FALSE; if (!preventDefault) {
nsCOMPtr<nsIDOMKeyEvent> keyEvent = do_QueryInterface(aKeyEvent);
PRUint32 theChar;
keyEvent->GetKeyCode(&theChar);
// Do shortcut navigation. if (mAccessKeyDown && ((PRInt32)theChar != mAccessKey)) {
// A letter was pressed. We want to see if a shortcut gets matched. If mAccessKeyDown = PR_FALSE;
// so, we'll know the menu got activated.
keyEvent->GetCharCode(&theChar);
PRBool active = PR_FALSE; // Do shortcut navigation.
mMenuBarFrame->ShortcutNavigation(theChar, active); // A letter was pressed. We want to see if a shortcut gets matched. If
// so, we'll know the menu got activated.
keyEvent->GetCharCode(&theChar);
if (active) { PRBool active = PR_FALSE;
aKeyEvent->PreventBubble(); mMenuBarFrame->ShortcutNavigation(theChar, active);
aKeyEvent->PreventCapture();
aKeyEvent->PreventDefault(); if (active) {
} aKeyEvent->PreventBubble();
return NS_ERROR_BASE; // I am consuming event aKeyEvent->PreventCapture();
} aKeyEvent->PreventDefault();
} }
#endif return NS_ERROR_BASE; // I am consuming event
}
}
}
return NS_OK; return NS_OK;
} }
@ -142,31 +179,56 @@ nsMenuBarListener::KeyPress(nsIDOMEvent* aKeyEvent)
nsresult nsresult
nsMenuBarListener::KeyDown(nsIDOMEvent* aKeyEvent) nsMenuBarListener::KeyDown(nsIDOMEvent* aKeyEvent)
{ {
#if !defined(XP_UNIX) || defined(NTO) InitAccessKey();
nsCOMPtr<nsIDOMKeyEvent> keyEvent = do_QueryInterface(aKeyEvent);
PRUint32 theChar;
keyEvent->GetKeyCode(&theChar);
PRBool alt;
keyEvent->GetAltKey(&alt);
if (theChar == NS_VK_TAB && mAltKeyDown) {
mAltKeyDown = PR_FALSE;
}
if (theChar == NS_VK_ALT && alt) { if (mAccessKey)
// No other modifiers can be down. {
// Especially CTRL. CTRL+ALT == AltGR, and nsCOMPtr<nsIDOMKeyEvent> keyEvent = do_QueryInterface(aKeyEvent);
// we'll fuck up on non-US enhanced 102-key PRUint32 theChar;
// keyboards if we don't check this. keyEvent->GetKeyCode(&theChar);
PRBool ctrl,shift,meta;
keyEvent->GetCtrlKey(&ctrl); PRBool access;
keyEvent->GetShiftKey(&shift); switch (mAccessKey)
keyEvent->GetMetaKey(&meta); {
if (!(ctrl || shift || meta)) { case nsIDOMKeyEvent::DOM_VK_CONTROL:
// The ALT key just went down by itself. Track this. keyEvent->GetCtrlKey(&access);
mAltKeyDown = PR_TRUE; break;
case nsIDOMKeyEvent::DOM_VK_ALT:
keyEvent->GetAltKey(&access);
break;
case nsIDOMKeyEvent::DOM_VK_META:
keyEvent->GetMetaKey(&access);
break;
default:
access = 0;
}
if (theChar == nsIDOMKeyEvent::DOM_VK_TAB && mAccessKeyDown) {
mAccessKeyDown = PR_FALSE;
}
if (theChar == mAccessKey || access) {
// No other modifiers can be down.
// Especially CTRL. CTRL+ALT == AltGR, and
// we'll fuck up on non-US enhanced 102-key
// keyboards if we don't check this.
PRBool ctrl = PR_FALSE;
if (mAccessKey != nsIDOMKeyEvent::DOM_VK_CONTROL)
keyEvent->GetCtrlKey(&ctrl);
PRBool alt=PR_FALSE;
if (mAccessKey != nsIDOMKeyEvent::DOM_VK_ALT)
keyEvent->GetAltKey(&alt);
PRBool shift=PR_FALSE;
if (mAccessKey != nsIDOMKeyEvent::DOM_VK_SHIFT)
keyEvent->GetShiftKey(&shift);
PRBool meta=PR_FALSE;
if (mAccessKey != nsIDOMKeyEvent::DOM_VK_META)
keyEvent->GetMetaKey(&meta);
if (!(ctrl || alt || shift || meta)) {
// The access key just went down by itself. Track this.
mAccessKeyDown = PR_TRUE;
}
} }
} }
#endif
return NS_OK; // means I am NOT consuming event return NS_OK; // means I am NOT consuming event
} }
@ -187,7 +249,7 @@ nsMenuBarListener::Blur(nsIDOMEvent* aEvent)
mMenuBarFrame->ToggleMenuActiveState(); mMenuBarFrame->ToggleMenuActiveState();
PRBool handled; PRBool handled;
mMenuBarFrame->Escape(handled); mMenuBarFrame->Escape(handled);
mAltKeyDown = PR_FALSE; mAccessKeyDown = PR_FALSE;
} }
return NS_OK; // means I am NOT consuming event return NS_OK; // means I am NOT consuming event
} }
@ -200,7 +262,7 @@ nsMenuBarListener::MouseDown(nsIDOMEvent* aMouseEvent)
mMenuBarFrame->ToggleMenuActiveState(); mMenuBarFrame->ToggleMenuActiveState();
PRBool handled; PRBool handled;
mMenuBarFrame->Escape(handled); mMenuBarFrame->Escape(handled);
mAltKeyDown = PR_FALSE; mAccessKeyDown = PR_FALSE;
} }
return NS_OK; // means I am NOT consuming event return NS_OK; // means I am NOT consuming event
} }

View File

@ -64,8 +64,11 @@ public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
protected: protected:
void InitAccessKey();
nsMenuBarFrame* mMenuBarFrame; // The menu bar object. nsMenuBarFrame* mMenuBarFrame; // The menu bar object.
PRBool mAltKeyDown; // Whether or not the ALT key is currently down. PRBool mAccessKeyDown; // Whether or not the ALT key is currently down.
PRInt32 mAccessKey; // See nsIDOMKeyEvent.h for sample values
}; };

View File

@ -63,7 +63,9 @@
#include "nsIServiceManager.h" #include "nsIServiceManager.h"
#include "nsIXBLService.h" #include "nsIXBLService.h"
#include "nsCSSFrameConstructor.h" #include "nsCSSFrameConstructor.h"
#include "nsIDOMKeyEvent.h"
#include "nsIPref.h"
#define NS_MENU_POPUP_LIST_INDEX 0 #define NS_MENU_POPUP_LIST_INDEX 0
static PRInt32 gEatMouseMove = PR_FALSE; static PRInt32 gEatMouseMove = PR_FALSE;
@ -72,7 +74,7 @@ nsMenuDismissalListener* nsMenuFrame::mDismissalListener = nsnull;
static NS_DEFINE_IID(kLookAndFeelCID, NS_LOOKANDFEEL_CID); static NS_DEFINE_IID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
static NS_DEFINE_IID(kILookAndFeelIID, NS_ILOOKANDFEEL_IID); static NS_DEFINE_IID(kILookAndFeelIID, NS_ILOOKANDFEEL_IID);
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
// //
// NS_NewMenuFrame // NS_NewMenuFrame
@ -135,7 +137,7 @@ nsMenuFrame::nsMenuFrame(nsIPresShell* aShell):nsBoxFrame(aShell),
NS_IMETHODIMP NS_IMETHODIMP
nsMenuFrame::SetParent(const nsIFrame* aParent) nsMenuFrame::SetParent(const nsIFrame* aParent)
{ {
nsresult rv = nsBoxFrame::SetParent(aParent); nsBoxFrame::SetParent(aParent);
nsIFrame* currFrame = (nsIFrame*)aParent; nsIFrame* currFrame = (nsIFrame*)aParent;
while (!mMenuParent && currFrame) { while (!mMenuParent && currFrame) {
// Set our menu parent. // Set our menu parent.
@ -1363,61 +1365,79 @@ nsMenuFrame::BuildAcceleratorText(nsString& aAccelString)
nsAutoString keyAtom; keyAtom.AssignWithConversion("key"); nsAutoString keyAtom; keyAtom.AssignWithConversion("key");
nsAutoString shiftAtom; shiftAtom.AssignWithConversion("shift"); nsAutoString shiftAtom; shiftAtom.AssignWithConversion("shift");
nsAutoString altAtom; altAtom.AssignWithConversion("alt"); nsAutoString altAtom; altAtom.AssignWithConversion("alt");
nsAutoString commandAtom; commandAtom.AssignWithConversion("command"); nsAutoString commandAtom; commandAtom.AssignWithConversion("command");
nsAutoString controlAtom; controlAtom.AssignWithConversion("control"); nsAutoString controlAtom; controlAtom.AssignWithConversion("control");
nsAutoString shiftValue; nsAutoString shiftValue;
nsAutoString altValue; nsAutoString altValue;
nsAutoString commandValue; nsAutoString commandValue;
nsAutoString controlValue; nsAutoString controlValue;
nsAutoString keyChar; keyChar.AssignWithConversion(" "); nsAutoString keyChar; keyChar.AssignWithConversion(" ");
keyElement->GetAttribute(keyAtom, keyChar); keyElement->GetAttribute(keyAtom, keyChar);
keyElement->GetAttribute(shiftAtom, shiftValue); keyElement->GetAttribute(shiftAtom, shiftValue);
keyElement->GetAttribute(altAtom, altValue); keyElement->GetAttribute(altAtom, altValue);
keyElement->GetAttribute(commandAtom, commandValue); keyElement->GetAttribute(commandAtom, commandValue);
keyElement->GetAttribute(controlAtom, controlValue); keyElement->GetAttribute(controlAtom, controlValue);
nsAutoString xulkey; PRInt32 accelKey = 0;
keyElement->GetAttribute(NS_ConvertASCIItoUCS2("xulkey"), xulkey);
if (xulkey.EqualsWithConversion("true")) {
// Set the default for the xul key modifier
#ifdef XP_MAC
commandValue.AssignWithConversion("true");
#elif defined(XP_PC) || defined(NTO)
controlValue.AssignWithConversion("true");
#else
altValue.AssignWithConversion("true");
#endif
}
PRBool prependPlus = PR_FALSE; PRBool prependPlus = PR_FALSE;
if(!commandValue.IsEmpty() && !commandValue.EqualsWithConversion("false")) { nsAutoString xulkey;
prependPlus = PR_TRUE; keyElement->GetAttribute(NS_ConvertASCIItoUCS2("xulkey"), xulkey);
aAccelString.AppendWithConversion("Ctrl"); // Hmmm. Kinda defeats the point of having an abstraction. if (xulkey.EqualsWithConversion("true"))
{
// Compiled-in defaults, in case we can't get LookAndFeel --
// command for mac, control for all other platforms.
#ifdef XP_MAC
accelKey = nsIDOMKeyEvent::DOM_VK_META;
#else
accelKey = nsIDOMKeyEvent::DOM_VK_CONTROL;
#endif
// Get the accelerator key value from prefs, overriding the default:
nsresult rv;
NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_PROGID, &rv);
if (NS_SUCCEEDED(rv) && prefs)
{
rv = prefs->GetIntPref("ui.key.acceleratorKey", &accelKey);
}
#ifdef DEBUG_akkana
else
{
NS_ASSERTION(PR_FALSE,"Menu couldn't get accel key from prefs!\n");
}
#endif
switch (accelKey)
{
case nsIDOMKeyEvent::DOM_VK_META:
prependPlus = PR_TRUE;
aAccelString.AppendWithConversion("Ctrl"); // Hmmm. Kinda defeats the point of having an abstraction.
break;
case nsIDOMKeyEvent::DOM_VK_ALT:
prependPlus = PR_TRUE;
aAccelString.AppendWithConversion("Alt");
break;
case nsIDOMKeyEvent::DOM_VK_CONTROL:
default:
prependPlus = PR_TRUE;
aAccelString.AppendWithConversion("Ctrl");
break;
}
} }
if(!controlValue.IsEmpty() && !controlValue.EqualsWithConversion("false")) { if (!shiftValue.IsEmpty() && !shiftValue.EqualsWithConversion("false")) {
prependPlus = PR_TRUE;
aAccelString.AppendWithConversion("Ctrl");
}
if(!shiftValue.IsEmpty() && !shiftValue.EqualsWithConversion("false")) {
if (prependPlus) if (prependPlus)
aAccelString.AppendWithConversion("+"); aAccelString.AppendWithConversion("+");
prependPlus = PR_TRUE; prependPlus = PR_TRUE;
aAccelString.AppendWithConversion("Shift"); aAccelString.AppendWithConversion("Shift");
} }
if (!altValue.IsEmpty() && !altValue.EqualsWithConversion("false")) {
if (prependPlus)
aAccelString.AppendWithConversion("+");
prependPlus = PR_TRUE;
aAccelString.AppendWithConversion("Alt");
}
keyChar.ToUpperCase(); keyChar.ToUpperCase();
if (!keyChar.IsEmpty()) { if (!keyChar.IsEmpty()) {
if (prependPlus) if (prependPlus)

View File

@ -133,10 +133,9 @@ nsTextBoxFrame::Init(nsIPresContext* aPresContext,
UpdateAttributes(aPresContext, nsnull, a, b, c /* all */); UpdateAttributes(aPresContext, nsnull, a, b, c /* all */);
// the following block is to append the accesskey to to mTitle if there is an accesskey // the following block is to append the accesskey to to mTitle if there is an accesskey
// but the mTitle doesn't have the character // but the mTitle doesn't have the character
// XXX Should this code first check to see if there's a menuAccessKey?
#ifndef XP_UNIX
nsAutoString accesskey; nsAutoString accesskey;
mContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::accesskey, mContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::accesskey,
accesskey); accesskey);
@ -163,7 +162,6 @@ nsTextBoxFrame::Init(nsIPresContext* aPresContext,
mAccessKeyInfo = nsnull; mAccessKeyInfo = nsnull;
} }
} }
#endif
return rv; return rv;
} }

View File

@ -305,9 +305,9 @@ nsTitledButtonFrame::Init(nsIPresContext* aPresContext,
// the following block is to append the accesskey to to mTitle if there is an accesskey // the following block is to append the accesskey to to mTitle if there is an accesskey
// but the mTitle doesn't have the character // but the mTitle doesn't have the character
// XXX Should this code first check to see if there's a menuAccessKey?
mAccesskeyIndex = -1; mAccesskeyIndex = -1;
#ifndef XP_UNIX
nsAutoString accesskey; nsAutoString accesskey;
mContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::accesskey, mContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::accesskey,
accesskey); accesskey);
@ -325,7 +325,6 @@ nsTitledButtonFrame::Init(nsIPresContext* aPresContext,
mTitle += tmpstring; mTitle += tmpstring;
} }
} }
#endif
return rv; return rv;
} }

View File

@ -414,6 +414,11 @@ pref("signed.applets.codebase_principal_support", false);
pref("security.checkloaduri", true); pref("security.checkloaduri", true);
pref("security.xpconnect.plugin.unrestricted", true); pref("security.xpconnect.plugin.unrestricted", true);
// Modifier key prefs: default to Windows settings,
// menu access key = alt, accelerator key = control.
pref("ui.key.acceleratorKey", 17);
pref("ui.key.menuAccessKey", 18);
// Middle-mouse handling // Middle-mouse handling
pref("middlemouse.paste", false); pref("middlemouse.paste", false);
pref("middlemouse.openNewWindow", false); pref("middlemouse.openNewWindow", false);

View File

@ -138,6 +138,9 @@ pref("font.name.monospace.zh-TW", "Apple LiGothic Medium");
pref("font.name.cursive.zh-TW", "XXX.cursive"); pref("font.name.cursive.zh-TW", "XXX.cursive");
pref("font.name.fantasy.zh-TW", "XXX.fantasy"); pref("font.name.fantasy.zh-TW", "XXX.fantasy");
// Override the Windows settings: no menu key, meta accelerator key.
pref("ui.key.menuAccessKey", 0);
pref("ui.key.acceleratorKey", 224);
// This overrides the setting in config.js (which points to the Windows page) // This overrides the setting in config.js (which points to the Windows page)
config("menu.help.item_0.label","Help Contents"); config("menu.help.item_0.label","Help Contents");

View File

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* *
* The contents of this file are subject to the Netscape Public * The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file * License Version 1.1 (the "License"); you may not use this file
@ -63,6 +63,8 @@
#include "nsIDocumentViewer.h" #include "nsIDocumentViewer.h"
#include "nsIPresContext.h" #include "nsIPresContext.h"
#include "nsIDOMEventTarget.h" #include "nsIDOMEventTarget.h"
#include "nsIPref.h"
#include "nsIServiceManager.h"
#include "nsIObserver.h" #include "nsIObserver.h"
#include "nsIObserverService.h" #include "nsIObserverService.h"
@ -196,6 +198,8 @@ static NS_DEFINE_IID(kIDomNodeIID, NS_IDOMNODE_IID);
static NS_DEFINE_IID(kIDomElementIID, NS_IDOMELEMENT_IID); static NS_DEFINE_IID(kIDomElementIID, NS_IDOMELEMENT_IID);
static NS_DEFINE_IID(kIDomEventListenerIID, NS_IDOMEVENTLISTENER_IID); static NS_DEFINE_IID(kIDomEventListenerIID, NS_IDOMEVENTLISTENER_IID);
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
enum eEventType { enum eEventType {
eKeyPress, eKeyPress,
eKeyDown, eKeyDown,
@ -308,10 +312,9 @@ private:
static nsSupportsHashtable* mKeyBindingTable; static nsSupportsHashtable* mKeyBindingTable;
// The "xul key" modifier can be any of the known modifiers: // The "xul key" modifier is a key code from nsIDOMKeyEvent,
enum { // e.g. nsIDOMKeyEvent::DOM_VK_CONTROL
xulKeyNone, xulKeyShift, xulKeyControl, xulKeyAlt, xulKeyMeta PRUint32 mXULKeyModifier;
} mXULKeyModifier;
}; };
nsSupportsHashtable* nsXULKeyListenerImpl::mKeyBindingTable = nsnull; nsSupportsHashtable* nsXULKeyListenerImpl::mKeyBindingTable = nsnull;
@ -461,14 +464,29 @@ nsXULKeyListenerImpl::Init(
mDOMDocument = xulDoc; // Weak reference. mDOMDocument = xulDoc; // Weak reference.
// Set the default for the xul key modifier // Compiled-in defaults, in case we can't get LookAndFeel --
// command for mac, control for all other platforms.
#ifdef XP_MAC #ifdef XP_MAC
mXULKeyModifier = xulKeyMeta; mXULKeyModifier = nsIDOMKeyEvent::DOM_VK_META;
#elif XP_UNIX
mXULKeyModifier = xulKeyAlt;
#else #else
mXULKeyModifier = xulKeyControl; mXULKeyModifier = nsIDOMKeyEvent::DOM_VK_CONTROL;
#endif #endif
// Get the accelerator key value from prefs, overriding the default:
nsresult rv;
NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_PROGID, &rv);
if (NS_SUCCEEDED(rv) && prefs)
{
rv = prefs->GetIntPref("ui.key.acceleratorKey",
(PRInt32*)&mXULKeyModifier);
}
#ifdef DEBUG_akkana
else
{
NS_ASSERTION(PR_FALSE, "XULKeyListener couldn't get accel key from prefs!\n");
}
#endif
return NS_OK; return NS_OK;
} }
@ -1478,7 +1496,7 @@ nsXULKeyListenerImpl::HandleEventUsingKeyset(nsIDOMElement* aKeysetElement, nsID
|| (property == falseString && isModKey)) || (property == falseString && isModKey))
break; break;
// and also the xul key, if it's specified to be shift: // and also the xul key, if it's specified to be shift:
if (xulKeyShift == mXULKeyModifier && if (nsIDOMKeyEvent::DOM_VK_SHIFT == mXULKeyModifier &&
((xproperty == trueString && !isModKey) ((xproperty == trueString && !isModKey)
|| (xproperty == falseString && isModKey))) || (xproperty == falseString && isModKey)))
break; break;
@ -1491,7 +1509,7 @@ nsXULKeyListenerImpl::HandleEventUsingKeyset(nsIDOMElement* aKeysetElement, nsID
|| (property == falseString && isModKey)) || (property == falseString && isModKey))
break; break;
// and if xul is control: // and if xul is control:
if (xulKeyControl == mXULKeyModifier && if (nsIDOMKeyEvent::DOM_VK_CONTROL == mXULKeyModifier &&
((xproperty == trueString && !isModKey) ((xproperty == trueString && !isModKey)
|| (xproperty == falseString && isModKey))) || (xproperty == falseString && isModKey)))
break; break;
@ -1504,7 +1522,7 @@ nsXULKeyListenerImpl::HandleEventUsingKeyset(nsIDOMElement* aKeysetElement, nsID
|| (property == falseString && isModKey)) || (property == falseString && isModKey))
break; break;
// and if xul is alt: // and if xul is alt:
if (xulKeyAlt == mXULKeyModifier && if (nsIDOMKeyEvent::DOM_VK_ALT == mXULKeyModifier &&
((xproperty == trueString && !isModKey) ((xproperty == trueString && !isModKey)
|| (xproperty == falseString && isModKey))) || (xproperty == falseString && isModKey)))
break; break;
@ -1517,7 +1535,7 @@ nsXULKeyListenerImpl::HandleEventUsingKeyset(nsIDOMElement* aKeysetElement, nsID
|| (property == falseString && isModKey)) || (property == falseString && isModKey))
break; break;
// and if xul is meta: // and if xul is meta:
if (xulKeyMeta == mXULKeyModifier && if (nsIDOMKeyEvent::DOM_VK_META == mXULKeyModifier &&
((xproperty == trueString && !isModKey) ((xproperty == trueString && !isModKey)
|| (xproperty == falseString && isModKey))) || (xproperty == falseString && isModKey)))
break; break;

View File

@ -601,6 +601,8 @@ enum nsDragDropEventStatus {
#define NS_VK_CLOSE_BRACKET 0xDD #define NS_VK_CLOSE_BRACKET 0xDD
#define NS_VK_QUOTE 0xDE #define NS_VK_QUOTE 0xDE
#define NS_VK_META 0xE0
#define NS_EVENT_FLAG_NONE 0x0000 #define NS_EVENT_FLAG_NONE 0x0000
#define NS_EVENT_FLAG_INIT 0x0001 #define NS_EVENT_FLAG_INIT 0x0001
#define NS_EVENT_FLAG_BUBBLE 0x0002 #define NS_EVENT_FLAG_BUBBLE 0x0002