Index: headers/os/interface/Window.h
===================================================================
--- headers/os/interface/Window.h	(revision 40140)
+++ headers/os/interface/Window.h	(working copy)
@@ -334,6 +334,7 @@
 									bool notifyIputServer = false);
 			void				_SetName(const char* title);
 
+			void				_AddShortcut(uint32 key, uint32 modifiers, Shortcut* shortcut);
 			Shortcut*			_FindShortcut(uint32 key, uint32 modifiers);
 			BView*				_FindView(BView* view, BPoint point) const;
 			BView*				_FindView(int32 token);
Index: headers/os/interface/MenuItem.h
===================================================================
--- headers/os/interface/MenuItem.h	(revision 40140)
+++ headers/os/interface/MenuItem.h	(working copy)
@@ -85,6 +85,8 @@
 			void				_DrawSubmenuSymbol(rgb_color backgroundColor);
 			void				_DrawControlChar(char shortcut, BPoint where);
 
+			bool				_IsValidShortcut(char shortcut, uint32 modifiers);
+
 private:
 			char*				fLabel;
 			BMenu*				fSubmenu;
Index: headers/os/interface/InterfaceDefs.h
===================================================================
--- headers/os/interface/InterfaceDefs.h	(revision 40140)
+++ headers/os/interface/InterfaceDefs.h	(working copy)
@@ -151,7 +151,8 @@
 	B_LEFT_CONTROL_KEY	= 0x00001000,
 	B_RIGHT_CONTROL_KEY	= 0x00002000,
 	B_LEFT_OPTION_KEY	= 0x00004000,
-	B_RIGHT_OPTION_KEY	= 0x00008000
+	B_RIGHT_OPTION_KEY	= 0x00008000,
+	B_NO_MODIFIERS		= 0x00010000
 };
 
 
Index: src/kits/interface/Window.cpp
===================================================================
--- src/kits/interface/Window.cpp	(revision 40140)
+++ src/kits/interface/Window.cpp	(working copy)
@@ -103,6 +103,8 @@
 	static	uint32			PrepareModifiers(uint32 modifiers);
 
 private:
+			uint32			_InitializeModifiers(uint32 modifiers);
+
 			uint32			fKey;
 			uint32			fModifiers;
 			BMenuItem*		fMenuItem;
@@ -237,7 +239,7 @@
 BWindow::Shortcut::Shortcut(uint32 key, uint32 modifiers, BMenuItem* item)
 	:
 	fKey(PrepareKey(key)),
-	fModifiers(PrepareModifiers(modifiers)),
+	fModifiers(_InitializeModifiers(modifiers)),
 	fMenuItem(item),
 	fMessage(NULL),
 	fTarget(NULL)
@@ -249,7 +251,7 @@
 	BHandler* target)
 	:
 	fKey(PrepareKey(key)),
-	fModifiers(PrepareModifiers(modifiers)),
+	fModifiers(_InitializeModifiers(modifiers)),
 	fMenuItem(NULL),
 	fMessage(message),
 	fTarget(target)
@@ -267,10 +269,23 @@
 bool
 BWindow::Shortcut::Matches(uint32 key, uint32 modifiers) const
 {
-	return fKey == key && fModifiers == modifiers;
+	if (fModifiers == B_NO_MODIFIERS && modifiers == 0)
+		return fKey == key;
+	else
+		return fKey == key && fModifiers == modifiers;
 }
 
 
+uint32
+BWindow::Shortcut::_InitializeModifiers(uint32 modifiers)
+{
+	if (modifiers == B_NO_MODIFIERS)
+		return modifiers;
+	else
+		return PrepareModifiers(modifiers) | B_COMMAND_KEY;
+}
+
+
 /*static*/
 uint32
 BWindow::Shortcut::AllowedModifiers()
@@ -284,7 +299,7 @@
 uint32
 BWindow::Shortcut::PrepareModifiers(uint32 modifiers)
 {
-	return (modifiers & AllowedModifiers()) | B_COMMAND_KEY;
+	return modifiers & AllowedModifiers();
 }
 
 
@@ -1785,13 +1800,7 @@
 BWindow::AddShortcut(uint32 key, uint32 modifiers, BMenuItem* item)
 {
 	Shortcut* shortcut = new(std::nothrow) Shortcut(key, modifiers, item);
-	if (shortcut == NULL)
-		return;
-
-	// removes the shortcut if it already exists!
-	RemoveShortcut(key, modifiers);
-
-	fShortcuts.AddItem(shortcut);
+	_AddShortcut(key, modifiers, shortcut);
 }
 
 
@@ -1811,13 +1820,7 @@
 
 	Shortcut* shortcut = new(std::nothrow) Shortcut(key, modifiers, message,
 		target);
-	if (shortcut == NULL)
-		return;
-
-	// removes the shortcut if it already exists!
-	RemoveShortcut(key, modifiers);
-
-	fShortcuts.AddItem(shortcut);
+	_AddShortcut(key, modifiers, shortcut);
 }
 
 
@@ -3669,62 +3672,66 @@
 	}
 
 	// Handle shortcuts
-	if ((modifiers & B_COMMAND_KEY) != 0) {
-		// Command+q has been pressed, so, we will quit
-		// the shortcut mechanism doesn't allow handlers outside the window
-		if (!fNoQuitShortcut && (key == 'Q' || key == 'q')) {
-			BMessage message(B_QUIT_REQUESTED);
-			message.AddBool("shortcut", true);
+	bool shortcutCalled = false;
+	// Command+q has been pressed, so, we will quit
+	// the shortcut mechanism doesn't allow handlers outside the window
+	if (!fNoQuitShortcut && (key == 'Q' || key == 'q') && (modifiers & B_COMMAND_KEY) != 0) {
+		BMessage message(B_QUIT_REQUESTED);
+		message.AddBool("shortcut", true);
 
-			be_app->PostMessage(&message);
-			return true;
-		}
+		be_app->PostMessage(&message);
+		return true;
+	}
 
-		// Pretend that the user opened a menu, to give the subclass a
-		// chance to update it's menus. This may install new shortcuts,
-		// which is why we have to call it here, before trying to find
-		// a shortcut for the given key.
-		MenusBeginning();
+	// Pretend that the user opened a menu, to give the subclass a
+	// chance to update it's menus. This may install new shortcuts,
+	// which is why we have to call it here, before trying to find
+	// a shortcut for the given key.
+	MenusBeginning();
 
-		Shortcut* shortcut = _FindShortcut(key, modifiers);
-		if (shortcut != NULL) {
-			// TODO: would be nice to move this functionality to
-			//	a Shortcut::Invoke() method - but since BMenu::InvokeItem()
-			//	(and BMenuItem::Invoke()) are private, I didn't want
-			//	to mess with them (BMenuItem::Invoke() is public in
-			//	Dano/Zeta, though, maybe we should just follow their
-			//	example)
-			if (shortcut->MenuItem() != NULL) {
-				BMenu* menu = shortcut->MenuItem()->Menu();
-				if (menu != NULL)
-					MenuPrivate(menu).InvokeItem(shortcut->MenuItem(), true);
-			} else {
-				BHandler* target = shortcut->Target();
-				if (target == NULL)
-					target = CurrentFocus();
+	Shortcut* shortcut = NULL;
+	// Handle function keys
+	if (key == B_FUNCTION_KEY && rawKey >= B_F1_KEY && rawKey <= B_F12_KEY)
+		shortcut = _FindShortcut(rawKey, modifiers);
+	else
+		shortcut = _FindShortcut(key, modifiers);
 
-				if (shortcut->Message() != NULL) {
-					BMessage message(*shortcut->Message());
+	if (shortcut != NULL) {
+		shortcutCalled = true;
+		// TODO: would be nice to move this functionality to
+		//	a Shortcut::Invoke() method - but since BMenu::InvokeItem()
+		//	(and BMenuItem::Invoke()) are private, I didn't want
+		//	to mess with them (BMenuItem::Invoke() is public in
+		//	Dano/Zeta, though, maybe we should just follow their
+		//	example)
+		if (shortcut->MenuItem() != NULL) {
+			BMenu* menu = shortcut->MenuItem()->Menu();
+			if (menu != NULL)
+				MenuPrivate(menu).InvokeItem(shortcut->MenuItem(), true);
+		} else {
+			BHandler* target = shortcut->Target();
+			if (target == NULL)
+				target = CurrentFocus();
 
-					if (message.ReplaceInt64("when", system_time()) != B_OK)
-						message.AddInt64("when", system_time());
-					if (message.ReplaceBool("shortcut", true) != B_OK)
-						message.AddBool("shortcut", true);
+			if (shortcut->Message() != NULL) {
+				BMessage message(*shortcut->Message());
 
-					PostMessage(&message, target);
-				}
+				if (message.ReplaceInt64("when", system_time()) != B_OK)
+					message.AddInt64("when", system_time());
+				if (message.ReplaceBool("shortcut", true) != B_OK)
+					message.AddBool("shortcut", true);
+
+				PostMessage(&message, target);
 			}
 		}
+	}
 
-		MenusEnded();
+	MenusEnded();
 
-		// we always eat the event if the command key was pressed
-		return true;
-	}
-
 	// TODO: convert keys to the encoding of the target view
 
-	return false;
+	// we always eat the event if a shortcut handled it
+	return shortcutCalled;
 }
 
 
@@ -3788,6 +3795,19 @@
 }
 
 
+void
+BWindow::_AddShortcut(uint32 key, uint32 modifiers, Shortcut* shortcut)
+{
+	if (shortcut == NULL)
+		return;
+
+	// removes the shortcut if it already exists!
+	RemoveShortcut(key, modifiers);
+
+	fShortcuts.AddItem(shortcut);
+}
+
+
 BWindow::Shortcut*
 BWindow::_FindShortcut(uint32 key, uint32 modifiers)
 {
Index: src/kits/interface/MenuItem.cpp
===================================================================
--- src/kits/interface/MenuItem.cpp	(revision 40140)
+++ src/kits/interface/MenuItem.cpp	(working copy)
@@ -12,6 +12,7 @@
 //!	Display item for BMenu class
 
 #include <ctype.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -63,13 +64,7 @@
 		fLabel = strdup(label);
 
 	SetMessage(message);
-
-	fShortcutChar = shortcut;
-
-	if (shortcut != 0)
-		fModifiers = modifiers | B_COMMAND_KEY;
-	else
-		fModifiers = 0;
+	SetShortcut(shortcut, modifiers);
 }
 
 
@@ -266,19 +261,22 @@
 
 
 void
-BMenuItem::SetShortcut(char ch, uint32 modifiers)
+BMenuItem::SetShortcut(char shortcut, uint32 modifiers)
 {
-	if (fShortcutChar != 0 && (fModifiers & B_COMMAND_KEY) && fWindow)
+	if (_IsValidShortcut(fShortcutChar, fModifiers) && fWindow)
 		fWindow->RemoveShortcut(fShortcutChar, fModifiers);
 
-	fShortcutChar = ch;
+	fShortcutChar = shortcut;
 
-	if (ch != 0)
-		fModifiers = modifiers | B_COMMAND_KEY;
-	else
+	if (shortcut != 0) {
+		if (modifiers != B_NO_MODIFIERS)
+			fModifiers = modifiers | B_COMMAND_KEY;
+		else
+			fModifiers = B_NO_MODIFIERS;
+	} else
 		fModifiers = 0;
 
-	if (fShortcutChar != 0 && (fModifiers & B_COMMAND_KEY) && fWindow)
+	if (_IsValidShortcut(fShortcutChar, fModifiers) && fWindow)
 		fWindow->AddShortcut(fShortcutChar, fModifiers, this);
 
 	if (fSuper) {
@@ -583,13 +581,12 @@
 void
 BMenuItem::Install(BWindow *window)
 {
-	if (fSubmenu) {
+	if (fSubmenu)
 		MenuPrivate(fSubmenu).Install(window);
-	}
 
 	fWindow = window;
 
-	if (fShortcutChar != 0 && (fModifiers & B_COMMAND_KEY) && fWindow)
+	if (_IsValidShortcut(fShortcutChar, fModifiers) && fWindow)
 		window->AddShortcut(fShortcutChar, fModifiers, this);
 
 	if (!Messenger().IsValid())
@@ -646,8 +643,7 @@
 	if (Target() == fWindow)
 		SetTarget(BMessenger());
 
-	if (fShortcutChar != 0 && (fModifiers & B_COMMAND_KEY) != 0
-		&& fWindow != NULL)
+	if (_IsValidShortcut(fShortcutChar, fModifiers) && fWindow != NULL)
 		fWindow->RemoveShortcut(fShortcutChar, fModifiers);
 
 	fWindow = NULL;
@@ -734,7 +730,7 @@
 		where.x -= fBounds.Height() - 3;
 
 	const float ascent = MenuPrivate(fSuper).Ascent();
-	if (fShortcutChar < B_SPACE && kUTF8ControlMap[(int)fShortcutChar])
+	if (fShortcutChar < B_SPACE)
 		_DrawControlChar(fShortcutChar, where + BPoint(0, ascent));
 	else
 		fSuper->DrawChar(fShortcutChar, where + BPoint(0, ascent));
@@ -818,11 +814,33 @@
 {
 	// TODO: If needed, take another font for the control characters
 	//	(or have font overlays in the app_server!)
-	const char* symbol = " ";
-	if (kUTF8ControlMap[(int)fShortcutChar])
-		symbol = kUTF8ControlMap[(int)fShortcutChar];
+	if (kUTF8ControlMap[(int)fShortcutChar]) {
+		const char* symbol = kUTF8ControlMap[(int)fShortcutChar];
+		fSuper->DrawString(symbol, where);
+	} else if (shortcut >= B_F1_KEY && shortcut <= B_F12_KEY) {
+		int number = 1 + (shortcut - B_F1_KEY);
+		char shortcutString[10];
+		snprintf(shortcutString, sizeof(shortcutString), "F%d", number);
+		// Account for this being longer that one character. Subtracting two
+		// times the size of space seems to align this nicely.
+		where.x -= (fSuper->StringWidth(shortcutString) - (2 * fSuper->StringWidth(" ")));
+		fSuper->DrawString(shortcutString, where);
+	}
+}
 
-	fSuper->DrawString(symbol, where);
+
+bool
+BMenuItem::_IsValidShortcut(char shortcut, uint32 modifiers)
+{
+	if (shortcut != 0) {
+		// Either explicitly ask for no modifiers or must have at least
+		// B_COMMAND_KEY
+		if (modifiers == B_NO_MODIFIERS)
+			return true;
+		else
+			return (modifiers & B_COMMAND_KEY) != 0;
+	}
+	return false;
 }
 
 
