49401: alt should not focus menubar in linux

49662: Mnemonics don't work beyond the top level
50046: underlines shouldn't be present when no menu access key
49413: moz grabs keypresses not mean for it
43433: Solaris meta keybindings
  r=saari
This commit is contained in:
akkana%netscape.com 2000-08-24 23:39:39 +00:00
parent 7df4802db4
commit 1cb6380993
5 changed files with 132 additions and 75 deletions

View File

@ -61,8 +61,11 @@ NS_IMPL_QUERY_INTERFACE3(nsMenuBarListener, nsIDOMKeyListener, nsIDOMFocusListen
////////////////////////////////////////////////////////////////////////
nsMenuBarListener::mAccessKey = -1;
nsMenuBarListener::mAccessKeyFocuses = PR_FALSE;
nsMenuBarListener::nsMenuBarListener(nsMenuBarFrame* aMenuBar)
:mAccessKeyDown(PR_FALSE), mAccessKeyFocuses(PR_FALSE), mAccessKey(-1)
:mAccessKeyDown(PR_FALSE)
{
NS_INIT_REFCNT();
mMenuBarFrame = aMenuBar;
@ -73,6 +76,16 @@ nsMenuBarListener::~nsMenuBarListener()
{
}
NS_IMETHODIMP
nsMenuBarListener::GetMenuAccessKey(PRInt32* aAccessKey)
{
if (!aAccessKey)
return NS_ERROR_INVALID_POINTER;
InitAccessKey();
*aAccessKey = mAccessKey;
return NS_OK;
}
void nsMenuBarListener::InitAccessKey()
{
if (mAccessKey >= 0)

View File

@ -60,16 +60,18 @@ public:
virtual nsresult MouseDblClick(nsIDOMEvent* aMouseEvent);
virtual nsresult MouseOver(nsIDOMEvent* aMouseEvent);
virtual nsresult MouseOut(nsIDOMEvent* aMouseEvent);
static nsresult GetMenuAccessKey(PRInt32* aAccessKey);
NS_DECL_ISUPPORTS
protected:
void InitAccessKey();
static void InitAccessKey();
nsMenuBarFrame* mMenuBarFrame; // The menu bar object.
PRBool mAccessKeyDown; // Whether or not the ALT key is currently down.
PRBool mAccessKeyFocuses; // Does the access key by itself focus the menubar?
PRInt32 mAccessKey; // See nsIDOMKeyEvent.h for sample values
static PRBool mAccessKeyFocuses; // Does the access key by itself focus the menubar?
static PRInt32 mAccessKey; // See nsIDOMKeyEvent.h for sample values
};

View File

@ -84,30 +84,58 @@ nsMenuListener::KeyUp(nsIDOMEvent* aKeyEvent)
nsresult
nsMenuListener::KeyDown(nsIDOMEvent* aKeyEvent)
{
#if !defined(XP_UNIX) || defined(NTO)
// See if the ALT key goes down by itself.
// If so, then close up the menu completely.
nsCOMPtr<nsIDOMKeyEvent> keyEvent = do_QueryInterface(aKeyEvent);
PRUint32 theChar;
keyEvent->GetKeyCode(&theChar);
PRBool alt;
keyEvent->GetAltKey(&alt);
if (theChar == NS_VK_ALT && alt) {
// 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,shift,meta;
keyEvent->GetCtrlKey(&ctrl);
keyEvent->GetShiftKey(&shift);
keyEvent->GetMetaKey(&meta);
if (!(ctrl || shift || meta)) {
// The ALT key just went down by itself. This means kill
// the menu.
mMenuParent->DismissChain();
PRInt32 menuAccessKey = -1;
nsMenuBarListener::GetMenuAccessKey(&menuAccessKey);
if (menuAccessKey) {
PRUint32 theChar;
nsCOMPtr<nsIDOMKeyEvent> keyEvent = do_QueryInterface(aKeyEvent);
keyEvent->GetKeyCode(&theChar);
PRBool access = PR_FALSE;
PRBool accessKeyDown = PR_FALSE;
switch (menuAccessKey)
{
case nsIDOMKeyEvent::DOM_VK_CONTROL:
keyEvent->GetCtrlKey(&access);
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 && accessKeyDown) {
accessKeyDown = PR_FALSE;
}
if (theChar == (PRUint32)menuAccessKey || 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 (menuAccessKey != nsIDOMKeyEvent::DOM_VK_CONTROL)
keyEvent->GetCtrlKey(&ctrl);
PRBool alt=PR_FALSE;
if (menuAccessKey != nsIDOMKeyEvent::DOM_VK_ALT)
keyEvent->GetAltKey(&alt);
PRBool shift=PR_FALSE;
if (menuAccessKey != nsIDOMKeyEvent::DOM_VK_SHIFT)
keyEvent->GetShiftKey(&shift);
PRBool meta=PR_FALSE;
if (menuAccessKey != nsIDOMKeyEvent::DOM_VK_META)
keyEvent->GetMetaKey(&meta);
if (!(ctrl || alt || shift || meta)) {
// The access key just went down by itself. Track this.
accessKeyDown = PR_TRUE;
}
}
if (accessKeyDown)
mMenuParent->DismissChain();
}
#endif
aKeyEvent->PreventBubble();
aKeyEvent->PreventCapture();
@ -144,15 +172,17 @@ nsMenuListener::KeyPress(nsIDOMEvent* aKeyEvent)
// Open one level.
mMenuParent->Enter();
}
#if !defined(XP_UNIX) || defined(NTO)
else {
// Do shortcut navigation.
// 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);
mMenuParent->ShortcutNavigation(theChar, handled);
PRInt32 menuAccessKey = -1;
nsMenuBarListener::GetMenuAccessKey(&menuAccessKey);
if (menuAccessKey) {
// Do shortcut navigation.
// 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);
mMenuParent->ShortcutNavigation(theChar, handled);
}
}
#endif
aKeyEvent->PreventBubble();
aKeyEvent->PreventCapture();

View File

@ -39,6 +39,7 @@
#include "nsIContent.h"
#include "nsINameSpaceManager.h"
#include "nsBoxLayoutState.h"
#include "nsMenuBarListener.h"
#define ELIPSIS "..."
@ -134,32 +135,35 @@ nsTextBoxFrame::Init(nsIPresContext* aPresContext,
// the following block is to append the accesskey to to mTitle if there is an accesskey
// but the mTitle doesn't have the character
// XXX Should this code first check to see if there's a menuAccessKey?
nsAutoString accesskey;
mContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::accesskey,
accesskey);
if (!accesskey.IsEmpty()) {
if (!mAccessKeyInfo)
mAccessKeyInfo = new nsAccessKeyInfo();
PRInt32 menuAccessKey;
nsMenuBarListener::GetMenuAccessKey(&menuAccessKey);
if (menuAccessKey) {
nsAutoString accesskey;
mContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::accesskey,
accesskey);
if (!accesskey.IsEmpty()) {
if (!mAccessKeyInfo)
mAccessKeyInfo = new nsAccessKeyInfo();
mAccessKeyInfo->mAccesskeyIndex = -1;
mAccessKeyInfo->mAccesskeyIndex = mTitle.Find(accesskey, PR_TRUE);
mAccessKeyInfo->mAccesskeyIndex = -1;
mAccessKeyInfo->mAccesskeyIndex = mTitle.Find(accesskey, PR_TRUE);
if (mAccessKeyInfo->mAccesskeyIndex == -1) {
nsAutoString tmpstring; tmpstring.AssignWithConversion("(");
accesskey.ToUpperCase();
tmpstring += accesskey;
tmpstring.AppendWithConversion(")");
PRUint32 offset = mTitle.RFind("...");
if ( offset != kNotFound)
mTitle.Insert(tmpstring,offset);
else
mTitle += tmpstring;
nsAutoString tmpstring; tmpstring.AssignWithConversion("(");
accesskey.ToUpperCase();
tmpstring += accesskey;
tmpstring.AppendWithConversion(")");
PRUint32 offset = mTitle.RFind("...");
if ( offset != (PRUint32)kNotFound)
mTitle.Insert(tmpstring,offset);
else
mTitle += tmpstring;
}
} else {
if (mAccessKeyInfo) {
delete mAccessKeyInfo;
mAccessKeyInfo = nsnull;
} else {
if (mAccessKeyInfo) {
delete mAccessKeyInfo;
mAccessKeyInfo = nsnull;
}
}
}
@ -535,7 +539,9 @@ nsTextBoxFrame::CalculateTitleForWidth(nsIPresContext* aPresContext, nsIRenderin
void
nsTextBoxFrame::UpdateAccessUnderline()
{
#ifndef XP_UNIX
PRInt32 menuAccessKey = -1;
nsMenuBarListener::GetMenuAccessKey(&menuAccessKey);
if (menuAccessKey) {
nsAutoString accesskey;
mContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::accesskey,
accesskey);
@ -552,7 +558,7 @@ nsTextBoxFrame::UpdateAccessUnderline()
mAccessKeyInfo->mAccesskeyIndex = -1;
mAccessKeyInfo->mAccesskeyIndex = mCroppedTitle.Find(accesskey, PR_TRUE);
#endif
}
}

View File

@ -73,6 +73,7 @@
#include "nsIStyleSet.h"
#include "nsIStyleContext.h"
#include "nsBoxLayoutState.h"
#include "nsMenuBarListener.h"
#include "nsFormControlHelper.h"
@ -303,27 +304,31 @@ nsTitledButtonFrame::Init(nsIPresContext* aPresContext,
PRBool a,b,c;
UpdateAttributes(aPresContext, nsnull, a, b, c /* all */);
PRInt32 menuAccessKey = -1;
nsMenuBarListener::GetMenuAccessKey(&menuAccessKey);
if (menuAccessKey) {
// the following block is to append the accesskey to to mTitle if there is an accesskey
// but the mTitle doesn't have the character
// XXX Should this code first check to see if there's a menuAccessKey?
mAccesskeyIndex = -1;
nsAutoString accesskey;
mContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::accesskey,
accesskey);
if (!accesskey.IsEmpty()) {
mAccesskeyIndex = -1;
nsAutoString accesskey;
mContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::accesskey,
accesskey);
if (!accesskey.IsEmpty()) {
mAccesskeyIndex = mTitle.Find(accesskey, PR_TRUE);
if (mAccesskeyIndex == -1) {
nsString tmpstring; tmpstring.AssignWithConversion("(");
accesskey.ToUpperCase();
tmpstring += accesskey;
tmpstring.AppendWithConversion(")");
PRUint32 offset = mTitle.RFind("...");
if ( offset != kNotFound)
mTitle.Insert(tmpstring,offset);
else
mTitle += tmpstring;
nsString tmpstring; tmpstring.AssignWithConversion("(");
accesskey.ToUpperCase();
tmpstring += accesskey;
tmpstring.AppendWithConversion(")");
PRUint32 offset = mTitle.RFind("...");
if ( offset != (PRUint32)kNotFound)
mTitle.Insert(tmpstring,offset);
else
mTitle += tmpstring;
}
}
}
return rv;
@ -819,8 +824,9 @@ nsTitledButtonFrame::CalculateTitleForWidth(nsIPresContext* aPresContext, nsIRen
void
nsTitledButtonFrame::UpdateAccessUnderline()
{
mAccesskeyIndex = -1;
#ifndef XP_UNIX
PRInt32 menuAccessKey = -1;
nsMenuBarListener::GetMenuAccessKey(&menuAccessKey);
if (menuAccessKey) {
nsAutoString accesskey;
mContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::accesskey,
accesskey);
@ -829,7 +835,7 @@ nsTitledButtonFrame::UpdateAccessUnderline()
mAccesskeyIndex = mCroppedTitle.Find(accesskey, PR_TRUE);
mNeedsAccessUpdate = PR_TRUE;
#endif
}
}
NS_IMETHODIMP