Package: iceweasel
Version: 15.0-1
Severity: normal
Tags: patch
Dear Maintainer,
Since version 13, iceweasel don't allow use the Win/Super/Meta key for
keyboard shortcuts. This problem is present only on gnu/linux because of
changes made by Mozilla, which were described by the developer Masayuki
Nakano (masayuki) in the same error repoted [1]. I have applied patchs
proposed by masayuki to iceweasel from experimental branch and after
fix some conflict in nsMenuBarListener.cpp and nsXBLPrototypeHandler.cpp
in my iceweasel Win/Super/Meta key works again.
I've attached the patch with the adjustments I made to the version 15.
[1] https://bugzilla.mozilla.org/show_bug.cgi?id=751749
-- Package-specific info:
Name: Adblock Plus
Location:
${PROFILE_EXTENSIONS}/{d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d}.xpi
Status: user-disabled
Name: CacheViewer
Location:
/usr/share/mozilla/extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}/{71328583-3CA7-4809-B4BA-570A85818FBB}
Package: xul-ext-cacheviewer
Status: app-disabled
Name: Default theme
Location: /usr/lib/iceweasel/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}
Package: iceweasel
Status: user-disabled
Name: Diccionario de Español/España
Location: ${PROFILE_EXTENSIONS}/es...@dictionaries.addons.mozilla.org
Status: enabled
Name: DownThemAll!
Location:
${PROFILE_EXTENSIONS}/{DDC359D1-844A-42a7-9AA1-88A850A938A8}.xpi
Status: enabled
Name: Elementary Style userstyle
Status: user-disabled
Name: Find & Add-on bar transparent userstyle
Status: enabled
Name: Firebug
Location:
/usr/share/mozilla/extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}/fire...@software.joehewitt.com
Package: xul-ext-firebug
Status: user-disabled
Name: Flashblock
Location:
${PROFILE_EXTENSIONS}/{3d7eb24f-2740-49df-8937-200b1cc08f8a}.xpi
Status: enabled
Name: FlashGot
Location:
${PROFILE_EXTENSIONS}/{19503e42-ca3c-4c27-b1e2-9cdb2170ee34}.xpi
Status: enabled
Name: gTranslate
Location:
${PROFILE_EXTENSIONS}/{aff87fa2-a58e-4edd-b852-0a20203c1e17}.xpi
Status: enabled
Name: ImgLikeOpera
Location: ${PROFILE_EXTENSIONS}/imglikeop...@imfo.ru.xpi
Status: enabled
Name: keyconfig
Location: ${PROFILE_EXTENSIONS}/keycon...@dorando.xpi
Status: enabled
Name: Live HTTP headers
Location: ${PROFILE_EXTENSIONS}/{8f8fe09b-0bd3-4470-bc1b-8cad42b8203a}
Status: user-disabled
Name: PhZilla
Location: ${PROFILE_EXTENSIONS}/amin.eft_phpr...@gmail.com
Status: enabled
Name: Proxy Selector
Location: ${PROFILE_EXTENSIONS}/proxyselec...@mozilla.org.xpi
Status: enabled
Name: RSS Icon
Location: ${PROFILE_EXTENSIONS}/kitsune...@gmail.com.xpi
Status: enabled
Name: Silvermel theme
Location: ${PROFILE_EXTENSIONS}/silver...@pardal.de.xpi
Status: enabled
Name: Silvermel and Charamel XT
Location: ${PROFILE_EXTENSIONS}/silverme...@pardal.de.xpi
Status: enabled
Name: Stylish
Location:
${PROFILE_EXTENSIONS}/{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}.xpi
Status: enabled
Name: Undo Closed Tabs Button
Location: ${PROFILE_EXTENSIONS}/undoclosedtabsbut...@supernova00.biz.xpi
Status: enabled
Name: United States English Spellchecker
Location: ${PROFILE_EXTENSIONS}/en...@dictionaries.addons.mozilla.org
Status: enabled
Name: UnMHT
Location:
${PROFILE_EXTENSIONS}/{f759ca51-3a91-4dd1-ae78-9db5eee9ebf0}.xpi
Status: user-disabled
Name: User Agent Switcher
Location:
${PROFILE_EXTENSIONS}/{e968fc70-8f95-4ab9-9e79-304de2a71ee1}.xpi
Status: user-disabled
Name: Zotero
Location:
/usr/share/mozilla/extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}/zot...@chnm.gmu.edu
Package: xul-ext-zotero
Status: enabled
-- Plugins information
Name: DivX Browser Plug-In
Location: /usr/lib/mozilla/plugins/gecko-mediaplayer-dvx.so
Package: gecko-mediaplayer
Status: enabled
Name: Gnome Shell Integration
Location: /usr/lib/mozilla/plugins/libgnome-shell-browser-plugin.so
Package: gnome-shell
Status: enabled
Name: iTunes Application Detector
Location: /usr/lib/mozilla/plugins/librhythmbox-itms-detection-plugin.so
Package: rhythmbox-plugins
Status: enabled
Name: Java(TM) Plug-in 1.6.0_25
Location: /usr/lib/jvm/jdk1.6.0_25/jre/lib/i386/libnpjp2.so
Status: disabled
Name: mplayerplug-in is now gecko-mediaplayer 1.0.6
Location: /usr/lib/mozilla/plugins/gecko-mediaplayer.so
Package: gecko-mediaplayer
Status: enabled
Name: QuickTime Plug-in 7.6.9
Location: /usr/lib/mozilla/plugins/gecko-mediaplayer-qt.so
Package: gecko-mediaplayer
Status: enabled
Name: RealPlayer 9
Location: /usr/lib/mozilla/plugins/gecko-mediaplayer-rm.so
Package: gecko-mediaplayer
Status: enabled
Name: Shockwave Flash
Location: /usr/lib/flashplayer-mozilla/libflashplayer.so
Package: flashplayer-mozilla
Status: enabled
Name: Windows Media Player Plug-in
Location: /usr/lib/mozilla/plugins/gecko-mediaplayer-wmp.so
Package: gecko-mediaplayer
Status: enabled
-- Addons package information
ii flashplayer-mo 3:11.2.202.2 i386 Macromedia Flash Player.
ii gecko-mediapla 1.0.6-1 i386 Multimedia plug-in for
Gecko brow
ii gnome-shell 3.4.2-1 i386 graphical shell for the
GNOME des
ii iceweasel 15.0-1~msg+2 i386 Web browser based on
Firefox
ii rhythmbox-plug 2.97-2.1 i386 plugins for rhythmbox music
playe
ii xul-ext-cachev 0.6.3-1 all this extenion is GUI
Front-end of
ii xul-ext-firebu 1.9.2~b2-1 all web development plugin for
Icewea
ii xul-ext-zotero 3.0.7-1 all Iceweasel extension to
organize a
-- System Information:
Debian Release: wheezy/sid
APT prefers testing
APT policy: (800, 'testing')
Architecture: i386 (i686)
Kernel: Linux 3.2.0-3-686-pae (SMP w/2 CPU cores)
Locale: LANG=en_US.utf8, LC_CTYPE=en_US.utf8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Versions of packages iceweasel depends on:
ii debianutils 4.3.2
ii fontconfig 2.9.0-7
ii libc6 2.13-35
ii libgdk-pixbuf2.0-0 2.26.1-1
ii libglib2.0-0 2.32.3-1
ii libgtk2.0-0 2.24.10-2
ii libnspr4 2:4.9.1-1
ii libnspr4-0d 2:4.9.1-1
ii libsqlite3-0 3.7.13-1
ii libstdc++6 4.7.1-2
ii procps 1:3.3.3-2
ii xulrunner-15.0 15.0-1~msg+2
iceweasel recommends no packages.
Versions of packages iceweasel suggests:
pn fonts-stix | otf-stix <none>
ii libgssapi-krb5-2 1.10.1+dfsg-2
pn mozplugger <none>
Versions of packages xulrunner-15.0 depends on:
ii libasound2 1.0.25-4
ii libatk1.0-0 2.4.0-2
ii libbz2-1.0 1.0.6-4
ii libc6 2.13-35
ii libcairo2 1.12.2-2
ii libdbus-1-3 1.6.0-1
ii libdbus-glib-1-2 0.100-1
ii libevent-2.0-5 2.0.19-stable-3
ii libfontconfig1 2.9.0-7
ii libfreetype6 2.4.9-1
ii libgcc1 1:4.7.1-2
ii libgdk-pixbuf2.0-0 2.26.1-1
ii libglib2.0-0 2.32.3-1
ii libgtk2.0-0 2.24.10-2
ii libhunspell-1.3-0 1.3.2-4
ii libjpeg8 8d-1
ii libmozjs15d 15.0-1~msg+2
ii libnotify4 0.7.5-1
ii libnspr4 2:4.9.1-1
ii libnspr4-0d 2:4.9.1-1
ii libnss3 2:3.13.5-1
ii libnss3-1d 2:3.13.5-1
ii libpango1.0-0 1.30.0-1
ii libpixman-1-0 0.26.0-3
ii libsqlite3-0 3.7.13-1
ii libstartup-notification0 0.12-1
ii libstdc++6 4.7.1-2
ii libvpx1 1.1.0-1
ii libx11-6 2:1.5.0-1
ii libxext6 2:1.3.1-2
ii libxrender1 1:0.9.7-1
ii libxt6 1:1.1.3-1
ii zlib1g 1:1.2.7.dfsg-13
Versions of packages xulrunner-15.0 suggests:
ii libcanberra0 0.28-4
ii libgnomeui-0 2.24.5-2
-- no debconf information
--
Ing. Marcel Sánchez Góngora
Dpto Gestión Documental - CENIA/UCI
I think... I think it's in my basement... Let me go upstairs and check.
** Escher
10mo. ANIVERSARIO DE LA CREACION DE LA UNIVERSIDAD DE LAS CIENCIAS
INFORMATICAS...
CONECTADOS AL FUTURO, CONECTADOS A LA REVOLUCION
http://www.uci.cu
http://www.facebook.com/universidad.uci
http://www.flickr.com/photos/universidad_uci
From: Masayuki Nakano <masay...@d-toybox.com>
Date: Mon, 25 Jun 2012 16:49:21 +0900
Subject: Bug 751749 - cannot configure keyboard shortcuts to use Meta modifier
instead of Alt
---
--- a/accessible/src/generic/Accessible.h
+++ b/accessible/src/generic/Accessible.h
@@ -904,6 +904,7 @@
static const PRUint32 kControl = 2;
static const PRUint32 kAlt = 4;
static const PRUint32 kMeta = 8;
+ static const PRUint32 kOS = 16;
KeyBinding() : mKey(0), mModifierMask(0) {}
KeyBinding(PRUint32 aKey, PRUint32 aModifierMask) :
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -1859,6 +1859,7 @@
static void GetShiftText(nsAString& text);
static void GetControlText(nsAString& text);
static void GetMetaText(nsAString& text);
+ static void GetOSText(nsAString& text);
static void GetAltText(nsAString& text);
static void GetModifierSeparatorText(nsAString& text);
@@ -2131,6 +2132,7 @@
static nsString* sShiftText;
static nsString* sControlText;
static nsString* sMetaText;
+ static nsString* sOSText;
static nsString* sAltText;
static nsString* sModifierSeparator;
};
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -235,6 +235,7 @@
nsString* nsContentUtils::sShiftText = nsnull;
nsString* nsContentUtils::sControlText = nsnull;
nsString* nsContentUtils::sMetaText = nsnull;
+nsString* nsContentUtils::sOSText = nsnull;
nsString* nsContentUtils::sAltText = nsnull;
nsString* nsContentUtils::sModifierSeparator = nsnull;
@@ -452,6 +453,15 @@
}
void
+nsContentUtils::GetOSText(nsAString& text)
+{
+ if (!sOSText) {
+ InitializeModifierStrings();
+ }
+ text.Assign(*sOSText);
+}
+
+void
nsContentUtils::GetAltText(nsAString& text)
{
if (!sAltText)
@@ -483,6 +493,7 @@
NS_ASSERTION(NS_SUCCEEDED(rv) && bundle, "chrome://global/locale/platformKeys.properties could not be loaded");
nsXPIDLString shiftModifier;
nsXPIDLString metaModifier;
+ nsXPIDLString osModifier;
nsXPIDLString altModifier;
nsXPIDLString controlModifier;
nsXPIDLString modifierSeparator;
@@ -490,6 +501,7 @@
//macs use symbols for each modifier key, so fetch each from the bundle, which also covers i18n
bundle->GetStringFromName(NS_LITERAL_STRING("VK_SHIFT").get(), getter_Copies(shiftModifier));
bundle->GetStringFromName(NS_LITERAL_STRING("VK_META").get(), getter_Copies(metaModifier));
+ bundle->GetStringFromName(NS_LITERAL_STRING("VK_WIN").get(), getter_Copies(osModifier));
bundle->GetStringFromName(NS_LITERAL_STRING("VK_ALT").get(), getter_Copies(altModifier));
bundle->GetStringFromName(NS_LITERAL_STRING("VK_CONTROL").get(), getter_Copies(controlModifier));
bundle->GetStringFromName(NS_LITERAL_STRING("MODIFIER_SEPARATOR").get(), getter_Copies(modifierSeparator));
@@ -497,6 +509,7 @@
//if any of these don't exist, we get an empty string
sShiftText = new nsString(shiftModifier);
sMetaText = new nsString(metaModifier);
+ sOSText = new nsString(osModifier);
sAltText = new nsString(altModifier);
sControlText = new nsString(controlModifier);
sModifierSeparator = new nsString(modifierSeparator);
@@ -1453,6 +1466,8 @@
sControlText = nsnull;
delete sMetaText;
sMetaText = nsnull;
+ delete sOSText;
+ sOSText = nsnull;
delete sAltText;
sAltText = nsnull;
delete sModifierSeparator;
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -267,6 +267,7 @@
#define NS_MODIFIER_CONTROL 2
#define NS_MODIFIER_ALT 4
#define NS_MODIFIER_META 8
+#define NS_MODIFIER_OS 16
static nsIDocument *
GetDocumentFromWindow(nsIDOMWindow *aWindow)
@@ -291,6 +292,7 @@
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;
}
@@ -1168,6 +1170,8 @@
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 && (modifierMask == sChromeAccessModifier ||
@@ -1525,6 +1529,10 @@
nsContentUtils::GetMetaText(modifierText);
aPrefix.Append(modifierText + separator);
}
+ if (modifier & NS_MODIFIER_OS) {
+ nsContentUtils::GetOSText(modifierText);
+ aPrefix.Append(modifierText + separator);
+ }
if (modifier & NS_MODIFIER_ALT) {
nsContentUtils::GetAltText(modifierText);
aPrefix.Append(modifierText + separator);
--- a/content/xbl/src/nsXBLPrototypeHandler.cpp
+++ b/content/xbl/src/nsXBLPrototypeHandler.cpp
@@ -63,13 +63,16 @@
const PRInt32 nsXBLPrototypeHandler::cAlt = (1<<1);
const PRInt32 nsXBLPrototypeHandler::cControl = (1<<2);
const PRInt32 nsXBLPrototypeHandler::cMeta = (1<<3);
+const PRInt32 nsXBLPrototypeHandler::cOS = (1<<4);
-const PRInt32 nsXBLPrototypeHandler::cShiftMask = (1<<4);
-const PRInt32 nsXBLPrototypeHandler::cAltMask = (1<<5);
-const PRInt32 nsXBLPrototypeHandler::cControlMask = (1<<6);
-const PRInt32 nsXBLPrototypeHandler::cMetaMask = (1<<7);
+const PRInt32 nsXBLPrototypeHandler::cShiftMask = (1<<5);
+const PRInt32 nsXBLPrototypeHandler::cAltMask = (1<<6);
+const PRInt32 nsXBLPrototypeHandler::cControlMask = (1<<7);
+const PRInt32 nsXBLPrototypeHandler::cMetaMask = (1<<8);
+const PRInt32 nsXBLPrototypeHandler::cOSMask = (1<<9);
-const PRInt32 nsXBLPrototypeHandler::cAllModifiers = cShiftMask | cAltMask | cControlMask | cMetaMask;
+const PRInt32 nsXBLPrototypeHandler::cAllModifiers =
+ cShiftMask | cAltMask | cControlMask | cMetaMask | cOSMask;
nsXBLPrototypeHandler::nsXBLPrototypeHandler(const PRUnichar* aEvent,
const PRUnichar* aPhase,
@@ -493,6 +496,8 @@
return NS_ERROR_FAILURE;
}
+ // XXX We should use widget::Modifiers for supporting all modifiers.
+
bool isAlt = false;
bool isControl = false;
bool isShift = false;
@@ -643,11 +648,12 @@
{
case nsIDOMKeyEvent::DOM_VK_META:
return cMeta | cMetaMask;
- break;
+
+ case nsIDOMKeyEvent::DOM_VK_WIN:
+ return cOS | cOSMask;
case nsIDOMKeyEvent::DOM_VK_ALT:
return cAlt | cAltMask;
- break;
case nsIDOMKeyEvent::DOM_VK_CONTROL:
default:
@@ -754,6 +760,8 @@
mKeyMask |= cAlt | cAltMask;
else if (PL_strcmp(token, "meta") == 0)
mKeyMask |= cMeta | cMetaMask;
+ else if (PL_strcmp(token, "os") == 0)
+ mKeyMask |= cOS | cOSMask;
else if (PL_strcmp(token, "control") == 0)
mKeyMask |= cControl | cControlMask;
else if (PL_strcmp(token, "accel") == 0)
@@ -761,7 +769,7 @@
else if (PL_strcmp(token, "access") == 0)
mKeyMask |= KeyToMask(kMenuAccessKey);
else if (PL_strcmp(token, "any") == 0)
- mKeyMask &= ~(mKeyMask << 4);
+ mKeyMask &= ~(mKeyMask << 5);
token = nsCRT::strtok( newStr, ", \t", &newStr );
}
@@ -850,32 +858,39 @@
nsXBLPrototypeHandler::ModifiersMatchMask(nsIDOMUIEvent* aEvent,
bool aIgnoreShiftKey)
{
- nsCOMPtr<nsIDOMKeyEvent> key(do_QueryInterface(aEvent));
- nsCOMPtr<nsIDOMMouseEvent> mouse(do_QueryInterface(aEvent));
+ nsCOMPtr<nsIPrivateDOMEvent> pEvent = do_QueryInterface(aEvent);
+ nsEvent* event = pEvent->GetInternalNSEvent();
+ NS_ENSURE_TRUE(event && NS_IS_INPUT_EVENT(event), false);
+ nsInputEvent* inputEvent = static_cast<nsInputEvent*>(event);
- bool keyPresent;
if (mKeyMask & cMetaMask) {
- key ? key->GetMetaKey(&keyPresent) : mouse->GetMetaKey(&keyPresent);
- if (keyPresent != ((mKeyMask & cMeta) != 0))
+ if (inputEvent->IsMeta() != ((mKeyMask & cMeta) != 0)) {
return false;
+ }
+ }
+
+ if (mKeyMask & cOSMask) {
+ if (inputEvent->IsOS() != ((mKeyMask & cOS) != 0)) {
+ return false;
+ }
}
if (mKeyMask & cShiftMask && !aIgnoreShiftKey) {
- key ? key->GetShiftKey(&keyPresent) : mouse->GetShiftKey(&keyPresent);
- if (keyPresent != ((mKeyMask & cShift) != 0))
+ if (inputEvent->IsShift() != ((mKeyMask & cShift) != 0)) {
return false;
+ }
}
if (mKeyMask & cAltMask) {
- key ? key->GetAltKey(&keyPresent) : mouse->GetAltKey(&keyPresent);
- if (keyPresent != ((mKeyMask & cAlt) != 0))
+ if (inputEvent->IsAlt() != ((mKeyMask & cAlt) != 0)) {
return false;
+ }
}
if (mKeyMask & cControlMask) {
- key ? key->GetCtrlKey(&keyPresent) : mouse->GetCtrlKey(&keyPresent);
- if (keyPresent != ((mKeyMask & cControl) != 0))
+ if (inputEvent->IsControl() != ((mKeyMask & cControl) != 0)) {
return false;
+ }
}
return true;
@@ -886,13 +901,13 @@
{
nsresult rv = aStream->Read8(&mPhase);
NS_ENSURE_SUCCESS(rv, rv);
- rv = aStream->Read8(&mKeyMask);
- NS_ENSURE_SUCCESS(rv, rv);
rv = aStream->Read8(&mType);
NS_ENSURE_SUCCESS(rv, rv);
rv = aStream->Read8(&mMisc);
NS_ENSURE_SUCCESS(rv, rv);
+ rv = aStream->Read32(reinterpret_cast<PRUint32*>(&mKeyMask));
+ NS_ENSURE_SUCCESS(rv, rv);
PRUint32 detail;
rv = aStream->Read32(&detail);
NS_ENSURE_SUCCESS(rv, rv);
@@ -928,12 +943,12 @@
nsresult rv = aStream->Write8(type);
rv = aStream->Write8(mPhase);
NS_ENSURE_SUCCESS(rv, rv);
- rv = aStream->Write8(mKeyMask);
- NS_ENSURE_SUCCESS(rv, rv);
rv = aStream->Write8(mType);
NS_ENSURE_SUCCESS(rv, rv);
rv = aStream->Write8(mMisc);
NS_ENSURE_SUCCESS(rv, rv);
+ rv = aStream->Write32(static_cast<PRUint32>(mKeyMask));
+ NS_ENSURE_SUCCESS(rv, rv);
rv = aStream->Write32(mDetail);
NS_ENSURE_SUCCESS(rv, rv);
--- a/content/xbl/src/nsXBLPrototypeHandler.h
+++ b/content/xbl/src/nsXBLPrototypeHandler.h
@@ -172,11 +172,13 @@
static const PRInt32 cAlt;
static const PRInt32 cControl;
static const PRInt32 cMeta;
+ static const PRInt32 cOS;
static const PRInt32 cShiftMask;
static const PRInt32 cAltMask;
static const PRInt32 cControlMask;
static const PRInt32 cMetaMask;
+ static const PRInt32 cOSMask;
static const PRInt32 cAllModifiers;
@@ -193,8 +195,6 @@
// The following four values make up 32 bits.
PRUint8 mPhase; // The phase (capturing, bubbling)
- PRUint8 mKeyMask; // Which modifier keys this event handler expects to have down
- // in order to be matched.
PRUint8 mType; // The type of the handler. The handler is either a XUL key
// handler, an XBL "command" event, or a normal XBL event with
// accompanying JavaScript. The high bit is used to indicate
@@ -203,6 +203,9 @@
// stores whether or not we're a key code or char code.
// For mouse events, stores the clickCount.
+ PRInt32 mKeyMask; // Which modifier keys this event handler expects to have down
+ // in order to be matched.
+
// The primary filter information for mouse/key events.
PRInt32 mDetail; // For key events, contains a charcode or keycode. For
// mouse events, stores the button info.
--- a/editor/libeditor/base/nsEditor.cpp
+++ b/editor/libeditor/base/nsEditor.cpp
@@ -5099,6 +5099,7 @@
switch (nativeKeyEvent->keyCode) {
case nsIDOMKeyEvent::DOM_VK_META:
+ case nsIDOMKeyEvent::DOM_VK_WIN:
case nsIDOMKeyEvent::DOM_VK_SHIFT:
case nsIDOMKeyEvent::DOM_VK_CONTROL:
case nsIDOMKeyEvent::DOM_VK_ALT:
@@ -5106,7 +5107,7 @@
return NS_OK;
case nsIDOMKeyEvent::DOM_VK_BACK_SPACE:
if (nativeKeyEvent->IsControl() || nativeKeyEvent->IsAlt() ||
- nativeKeyEvent->IsMeta()) {
+ nativeKeyEvent->IsMeta() || nativeKeyEvent->IsOS()) {
return NS_OK;
}
DeleteSelection(nsIEditor::ePrevious, nsIEditor::eStrip);
@@ -5117,7 +5118,8 @@
// modifies what delete does (cmd_cut in this case).
// bailing here to allow the keybindings to do the cut.
if (nativeKeyEvent->IsShift() || nativeKeyEvent->IsControl() ||
- nativeKeyEvent->IsAlt() || nativeKeyEvent->IsMeta()) {
+ nativeKeyEvent->IsAlt() || nativeKeyEvent->IsMeta() ||
+ nativeKeyEvent->IsOS()) {
return NS_OK;
}
DeleteSelection(nsIEditor::eNext, nsIEditor::eStrip);
--- a/editor/libeditor/html/nsHTMLEditor.cpp
+++ b/editor/libeditor/html/nsHTMLEditor.cpp
@@ -598,6 +598,7 @@
switch (nativeKeyEvent->keyCode) {
case nsIDOMKeyEvent::DOM_VK_META:
+ case nsIDOMKeyEvent::DOM_VK_WIN:
case nsIDOMKeyEvent::DOM_VK_SHIFT:
case nsIDOMKeyEvent::DOM_VK_CONTROL:
case nsIDOMKeyEvent::DOM_VK_ALT:
@@ -618,7 +619,7 @@
}
if (nativeKeyEvent->IsControl() || nativeKeyEvent->IsAlt() ||
- nativeKeyEvent->IsMeta()) {
+ nativeKeyEvent->IsMeta() || nativeKeyEvent->IsOS()) {
return NS_OK;
}
@@ -668,7 +669,7 @@
case nsIDOMKeyEvent::DOM_VK_RETURN:
case nsIDOMKeyEvent::DOM_VK_ENTER:
if (nativeKeyEvent->IsControl() || nativeKeyEvent->IsAlt() ||
- nativeKeyEvent->IsMeta()) {
+ nativeKeyEvent->IsMeta() || nativeKeyEvent->IsOS()) {
return NS_OK;
}
aKeyEvent->PreventDefault(); // consumed
@@ -683,7 +684,8 @@
// NOTE: On some keyboard layout, some characters are inputted with Control
// key or Alt key, but at that time, widget sets FALSE to these keys.
if (nativeKeyEvent->charCode == 0 || nativeKeyEvent->IsControl() ||
- nativeKeyEvent->IsAlt() || nativeKeyEvent->IsMeta()) {
+ nativeKeyEvent->IsAlt() || nativeKeyEvent->IsMeta() ||
+ nativeKeyEvent->IsOS()) {
// we don't PreventDefault() here or keybindings like control-x won't work
return NS_OK;
}
--- a/editor/libeditor/html/tests/test_htmleditor_keyevent_handling.html
+++ b/editor/libeditor/html/tests/test_htmleditor_keyevent_handling.html
@@ -137,6 +137,10 @@
check(aDescription + "Meta", true, true, !aIsReadonly);
reset("");
+ synthesizeKey("VK_WIN", { type: "keypress" });
+ check(aDescription + "OS", true, true, !aIsReadonly);
+
+ reset("");
synthesizeKey("VK_SHIFT", { type: "keypress" });
check(aDescription + "Shift", true, true, !aIsReadonly);
@@ -176,6 +180,10 @@
synthesizeKey("VK_BACK_SPACE", { metaKey: true });
check(aDescription + "Meta+Backspace", true, true, aIsReadonly);
+ reset("");
+ synthesizeKey("VK_BACK_SPACE", { osKey: true });
+ check(aDescription + "OS+Backspace", true, true, aIsReadonly);
+
// Delete key:
// If editor is readonly, it doesn't consume.
// If editor is editable, delete is consumed.
@@ -200,6 +208,10 @@
synthesizeKey("VK_DELETE", { metaKey: true });
check(aDescription + "Meta+Delete", true, true, false);
+ reset("");
+ synthesizeKey("VK_DELETE", { osKey: true });
+ check(aDescription + "OS+Delete", true, true, false);
+
// Return key:
// If editor is readonly, it doesn't consume.
// If editor is editable and not single line editor, it consumes Return
@@ -234,6 +246,11 @@
check(aDescription + "Meta+Return", true, true, false);
is(aElement.innerHTML, "a", aDescription + "Meta+Return");
+ reset("a");
+ synthesizeKey("VK_RETURN", { osKey: true });
+ check(aDescription + "OS+Return", true, true, false);
+ is(aElement.innerHTML, "a", aDescription + "OS+Return");
+
// Enter key (same as Return key):
// If editor is readonly, it doesn't consume.
// If editor is editable and not single line editor, it consumes Return
@@ -268,6 +285,11 @@
check(aDescription + "Meta+Enter", true, true, false);
is(aElement.innerHTML, "a", aDescription + "Meta+Enter");
+ reset("a");
+ synthesizeKey("VK_ENTER", { osKey: true });
+ check(aDescription + "OS+Enter", true, true, false);
+ is(aElement.innerHTML, "a", aDescription + "OS+Enter");
+
// Tab key:
// If editor is tabbable, editor doesn't consume all tab key events.
// Otherwise, editor consumes tab key event without any modifier keys.
@@ -311,6 +333,13 @@
is(fm.focusedElement, aElement,
aDescription + "focus moved unexpectedly (Meta+Tab)");
+ reset("a");
+ synthesizeKey("VK_TAB", { osKey: true });
+ check(aDescription + "OS+Tab", true, true, false);
+ is(aElement.innerHTML, "a", aDescription + "OS+Tab");
+ is(fm.focusedElement, aElement,
+ aDescription + "focus moved unexpectedly (OS+Tab)");
+
// Indent/Outdent tests:
// UL
resetForIndent("<ul><li id=\"target\">ul list item</li></ul>");
@@ -372,6 +401,14 @@
is(fm.focusedElement, aElement,
aDescription + "focus moved unexpectedly (Meta+Tab on UL)");
+ resetForIndent("<ul><li id=\"target\">ul list item</li></ul>");
+ synthesizeKey("VK_TAB", { osKey: true });
+ check(aDescription + "OS+Tab on UL", true, true, false);
+ is(aElement.innerHTML, "<ul><li id=\"target\">ul list item</li></ul>",
+ aDescription + "OS+Tab on UL");
+ is(fm.focusedElement, aElement,
+ aDescription + "focus moved unexpectedly (OS+Tab on UL)");
+
// OL
resetForIndent("<ol><li id=\"target\">ol list item</li></ol>");
synthesizeKey("VK_TAB", { });
@@ -432,6 +469,14 @@
is(fm.focusedElement, aElement,
aDescription + "focus moved unexpectedly (Meta+Tab on OL)");
+ resetForIndent("<ol><li id=\"target\">ol list item</li></ol>");
+ synthesizeKey("VK_TAB", { osKey: true });
+ check(aDescription + "OS+Tab on OL", true, true, false);
+ is(aElement.innerHTML, "<ol><li id=\"target\">ol list item</li></ol>",
+ aDescription + "OS+Tab on OL");
+ is(fm.focusedElement, aElement,
+ aDescription + "focus moved unexpectedly (OS+Tab on OL)");
+
// TD
resetForIndent("<table><tr><td id=\"target\">td</td></tr></table>");
synthesizeKey("VK_TAB", { });
@@ -494,6 +539,15 @@
is(fm.focusedElement, aElement,
aDescription + "focus moved unexpectedly (Meta+Tab on TD)");
+ resetForIndent("<table><tr><td id=\"target\">td</td></tr></table>");
+ synthesizeKey("VK_TAB", { osKey: true });
+ check(aDescription + "OS+Tab on TD", true, true, false);
+ is(aElement.innerHTML,
+ "<table><tbody><tr><td id=\"target\">td</td></tr></tbody></table>",
+ aDescription + "OS+Tab on TD");
+ is(fm.focusedElement, aElement,
+ aDescription + "focus moved unexpectedly (OS+Tab on TD)");
+
// TH
resetForIndent("<table><tr><th id=\"target\">th</th></tr></table>");
synthesizeKey("VK_TAB", { });
@@ -556,6 +610,15 @@
is(fm.focusedElement, aElement,
aDescription + "focus moved unexpectedly (Meta+Tab on TH)");
+ resetForIndent("<table><tr><th id=\"target\">th</th></tr></table>");
+ synthesizeKey("VK_TAB", { osKey: true });
+ check(aDescription + "OS+Tab on TH", true, true, false);
+ is(aElement.innerHTML,
+ "<table><tbody><tr><th id=\"target\">th</th></tr></tbody></table>",
+ aDescription + "OS+Tab on TH");
+ is(fm.focusedElement, aElement,
+ aDescription + "focus moved unexpectedly (OS+Tab on TH)");
+
// Esc key:
// In all cases, esc key events are not consumed
reset("abc");
@@ -578,6 +641,10 @@
synthesizeKey("VK_ESCAPE", { metaKey: true });
check(aDescription + "Meta+Esc", true, true, false);
+ reset("abc");
+ synthesizeKey("VK_ESCAPE", { osKey: true });
+ check(aDescription + "OS+Esc", true, true, false);
+
// typical typing tests:
reset("");
synthesizeKey("M", { shiftKey: true });
--- a/editor/libeditor/text/nsPlaintextEditor.cpp
+++ b/editor/libeditor/text/nsPlaintextEditor.cpp
@@ -344,6 +344,7 @@
switch (nativeKeyEvent->keyCode) {
case nsIDOMKeyEvent::DOM_VK_META:
+ case nsIDOMKeyEvent::DOM_VK_WIN:
case nsIDOMKeyEvent::DOM_VK_SHIFT:
case nsIDOMKeyEvent::DOM_VK_CONTROL:
case nsIDOMKeyEvent::DOM_VK_ALT:
@@ -357,7 +358,8 @@
}
if (nativeKeyEvent->IsShift() || nativeKeyEvent->IsControl() ||
- nativeKeyEvent->IsAlt() || nativeKeyEvent->IsMeta()) {
+ nativeKeyEvent->IsAlt() || nativeKeyEvent->IsMeta() ||
+ nativeKeyEvent->IsOS()) {
return NS_OK;
}
@@ -368,7 +370,8 @@
case nsIDOMKeyEvent::DOM_VK_RETURN:
case nsIDOMKeyEvent::DOM_VK_ENTER:
if (IsSingleLineEditor() || nativeKeyEvent->IsControl() ||
- nativeKeyEvent->IsAlt() || nativeKeyEvent->IsMeta()) {
+ nativeKeyEvent->IsAlt() || nativeKeyEvent->IsMeta() ||
+ nativeKeyEvent->IsOS()) {
return NS_OK;
}
aKeyEvent->PreventDefault();
@@ -378,7 +381,8 @@
// NOTE: On some keyboard layout, some characters are inputted with Control
// key or Alt key, but at that time, widget sets FALSE to these keys.
if (nativeKeyEvent->charCode == 0 || nativeKeyEvent->IsControl() ||
- nativeKeyEvent->IsAlt() || nativeKeyEvent->IsMeta()) {
+ nativeKeyEvent->IsAlt() || nativeKeyEvent->IsMeta() ||
+ nativeKeyEvent->IsOS()) {
// we don't PreventDefault() here or keybindings like control-x won't work
return NS_OK;
}
--- a/editor/libeditor/text/tests/test_texteditor_keyevent_handling.html
+++ b/editor/libeditor/text/tests/test_texteditor_keyevent_handling.html
@@ -124,6 +124,10 @@
check(aDescription + "Meta", true, true, !aIsReadonly);
reset("");
+ synthesizeKey("VK_WIN", { type: "keypress" });
+ check(aDescription + "OS", true, true, !aIsReadonly);
+
+ reset("");
synthesizeKey("VK_SHIFT", { type: "keypress" });
check(aDescription + "Shift", true, true, !aIsReadonly);
@@ -169,6 +173,10 @@
synthesizeKey("VK_BACK_SPACE", { metaKey: true });
check(aDescription + "Meta+Backspace", true, true, aIsReadonly);
+ reset("");
+ synthesizeKey("VK_BACK_SPACE", { osKey: true });
+ check(aDescription + "OS+Backspace", true, true, aIsReadonly);
+
// Delete key:
// If editor is readonly, it doesn't consume.
// If editor is editable, delete is consumed.
@@ -206,6 +214,11 @@
check(aDescription + "Meta+Delete",
true, true, kIsLinux);
+ reset("");
+ synthesizeKey("VK_DELETE", { osKey: true });
+ check(aDescription + "OS+Delete",
+ true, true, false);
+
// XXX input.value returns "\n" when it's empty, so, we should use dummy
// value ("a") for the following tests.
@@ -243,6 +256,11 @@
check(aDescription + "Meta+Return", true, true, false);
is(aElement.value, "a", aDescription + "Meta+Return");
+ reset("a");
+ synthesizeKey("VK_RETURN", { osKey: true });
+ check(aDescription + "OS+Return", true, true, false);
+ is(aElement.value, "a", aDescription + "OS+Return");
+
// Enter key (same as Return key):
// If editor is readonly, it doesn't consume.
// If editor is editable and not single line editor, it consumes Return
@@ -277,6 +295,11 @@
check(aDescription + "Meta+Enter", true, true, false);
is(aElement.value, "a", aDescription + "Meta+Enter");
+ reset("a");
+ synthesizeKey("VK_ENTER", { osKey: true });
+ check(aDescription + "OS+Enter", true, true, false);
+ is(aElement.value, "a", aDescription + "OS+Enter");
+
// Tab key:
// If editor is tabbable, editor doesn't consume all tab key events.
// Otherwise, editor consumes tab key event without any modifier keys.
@@ -330,6 +353,13 @@
is(fm.focusedElement, aElement,
aDescription + "focus moved unexpectedly (Meta+Tab)");
+ reset("a");
+ synthesizeKey("VK_TAB", { osKey: true });
+ check(aDescription + "OS+Tab", true, true, false);
+ is(aElement.value, "a", aDescription + "OS+Tab");
+ is(fm.focusedElement, aElement,
+ aDescription + "focus moved unexpectedly (OS+Tab)");
+
// Esc key:
// In all cases, esc key events are not consumed
reset("abc");
@@ -352,6 +382,10 @@
synthesizeKey("VK_ESCAPE", { metaKey: true });
check(aDescription + "Meta+Esc", true, true, false);
+ reset("abc");
+ synthesizeKey("VK_ESCAPE", { osKey: true });
+ check(aDescription + "OS+Esc", true, true, false);
+
// typical typing tests:
reset("");
synthesizeKey("M", { shiftKey: true });
--- a/layout/xul/base/src/nsMenuBarListener.cpp
+++ b/layout/xul/base/src/nsMenuBarListener.cpp
@@ -8,6 +8,7 @@
#include "nsMenuPopupFrame.h"
#include "nsIDOMNSEvent.h"
#include "nsGUIEvent.h"
+#include "nsIPrivateDOMEvent.h"
// Drag & Drop, Clipboard
#include "nsIServiceManager.h"
@@ -33,6 +34,7 @@
#define MODIFIER_CONTROL 2
#define MODIFIER_ALT 4
#define MODIFIER_META 8
+#define MODIFIER_OS 16
////////////////////////////////////////////////////////////////////////
@@ -86,6 +88,8 @@
mAccessKeyMask = MODIFIER_ALT;
else if (mAccessKey == nsIDOMKeyEvent::DOM_VK_META)
mAccessKeyMask = MODIFIER_META;
+ else if (mAccessKey == nsIDOMKeyEvent::DOM_VK_WIN)
+ mAccessKeyMask = MODIFIER_OS;
mAccessKeyFocuses = Preferences::GetBool("ui.key.menuAccessKeyFocuses");
}
@@ -270,23 +274,30 @@
nsMenuBarListener::GetModifiers(nsIDOMKeyEvent* aKeyEvent)
{
PRUint32 modifiers = 0;
- bool modifier;
+ nsCOMPtr<nsIPrivateDOMEvent> privDOMEvent = do_QueryInterface(aKeyEvent);
+ nsInputEvent* inputEvent =
+ static_cast<nsInputEvent*>(privDOMEvent->GetInternalNSEvent());
+ MOZ_ASSERT(inputEvent);
- aKeyEvent->GetShiftKey(&modifier);
- if (modifier)
+ if (inputEvent->IsShift()) {
modifiers |= MODIFIER_SHIFT;
+ }
- aKeyEvent->GetCtrlKey(&modifier);
- if (modifier)
+ if (inputEvent->IsControl()) {
modifiers |= MODIFIER_CONTROL;
+ }
- aKeyEvent->GetAltKey(&modifier);
- if (modifier)
+ if (inputEvent->IsAlt()) {
modifiers |= MODIFIER_ALT;
+ }
- aKeyEvent->GetMetaKey(&modifier);
- if (modifier)
+ if (inputEvent->IsMeta()) {
modifiers |= MODIFIER_META;
+ }
+
+ if (inputEvent->IsOS()) {
+ modifiers |= MODIFIER_OS;
+ }
return modifiers;
}
--- a/layout/xul/base/src/nsMenuFrame.cpp
+++ b/layout/xul/base/src/nsMenuFrame.cpp
@@ -1095,12 +1095,14 @@
nsAutoString altText;
nsAutoString metaText;
nsAutoString controlText;
+ nsAutoString osText;
nsAutoString modifierSeparator;
nsContentUtils::GetShiftText(shiftText);
nsContentUtils::GetAltText(altText);
nsContentUtils::GetMetaText(metaText);
nsContentUtils::GetControlText(controlText);
+ nsContentUtils::GetOSText(osText);
nsContentUtils::GetModifierSeparatorText(modifierSeparator);
while (token) {
@@ -1111,6 +1113,8 @@
accelText += altText;
else if (PL_strcmp(token, "meta") == 0)
accelText += metaText;
+ else if (PL_strcmp(token, "os") == 0)
+ accelText += osText;
else if (PL_strcmp(token, "control") == 0)
accelText += controlText;
else if (PL_strcmp(token, "accel") == 0) {
@@ -1120,6 +1124,10 @@
accelText += metaText;
break;
+ case nsIDOMKeyEvent::DOM_VK_WIN:
+ accelText += osText;
+ break;
+
case nsIDOMKeyEvent::DOM_VK_ALT:
accelText += altText;
break;
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -1282,13 +1282,13 @@
// Modifier key prefs: default to Windows settings,
// menu access key = alt, accelerator key = control.
-// Use 17 for Ctrl, 18 for Alt, 224 for Meta, 0 for none. Mac settings in macprefs.js
+// Use 17 for Ctrl, 18 for Alt, 224 for Meta, 91 for Win, 0 for none. Mac settings in macprefs.js
pref("ui.key.accelKey", 17);
pref("ui.key.menuAccessKey", 18);
pref("ui.key.generalAccessKey", -1);
// If generalAccessKey is -1, use the following two prefs instead.
-// Use 0 for disabled, 1 for Shift, 2 for Ctrl, 4 for Alt, 8 for Meta
+// Use 0 for disabled, 1 for Shift, 2 for Ctrl, 4 for Alt, 8 for Meta, 16 for Win
// (values can be combined, e.g. 5 for Alt+Shift)
pref("ui.key.chromeAccess", 4);
pref("ui.key.contentAccess", 5);
--- a/toolkit/content/tests/chrome/window_keys.xul
+++ b/toolkit/content/tests/chrome/window_keys.xul
@@ -23,6 +23,7 @@
["k-v-scy", "V", { ctrlKey: true } ],
["", "V", { altKey: true } ],
["", "V", { metaKey: true } ],
+ ["", "V", { osKey: true } ],
["k-v-scy", "V", { shiftKey: true, ctrlKey: true } ],
["", "V", { shiftKey: true, ctrlKey: true, altKey: true } ],
["k-e-y", "E", { } ],
@@ -30,8 +31,16 @@
["", "E", { ctrlKey: true } ],
["", "E", { altKey: true } ],
["", "E", { metaKey: true } ],
+ ["", "E", { osKey: true } ],
["k-d-a", "D", { altKey: true } ],
["k-8-m", "8", { metaKey: true } ],
+ ["", "8", { metaKey: true, osKey: true } ],
+ ["k-a-o", "A", { osKey: true } ],
+ ["", "A", { osKey: true, metaKey: true } ],
+ ["k-b-myo", "B", { osKey: true } ],
+ ["k-b-myo", "B", { osKey: true, metaKey: true } ],
+ ["k-f-oym", "F", { metaKey: true } ],
+ ["k-f-oym", "F", { metaKey: true, osKey: true } ],
["k-c-scaym", "C", { metaKey: true } ],
["k-c-scaym", "C", { shiftKey: true, ctrlKey: true, altKey: true, metaKey: true } ],
["", "V", { shiftKey: true, ctrlKey: true, altKey: true } ],
@@ -148,6 +157,9 @@
<key id="k-v-scy" key="v" modifiers="shift any control" oncommand="checkKey(event)"/>
<key id="k-e-y" key="e" modifiers="any" oncommand="checkKey(event)"/>
<key id="k-8-m" key="8" modifiers="meta" oncommand="checkKey(event)"/>
+ <key id="k-a-o" key="a" modifiers="os" oncommand="checkKey(event)"/>
+ <key id="k-b-myo" key="b" modifiers="meta any os" oncommand="checkKey(event)"/>
+ <key id="k-f-oym" key="f" modifiers="os any meta" oncommand="checkKey(event)"/>
<key id="k-c-scaym" key="c" modifiers="shift control alt any meta" oncommand="checkKey(event)"/>
<key id="k-h-l" key="h" modifiers="accel" oncommand="checkKey(event)"/>
<key id="k-j-s" key="j" modifiers="access" oncommand="checkKey(event)"/>
--- a/toolkit/locales/en-US/chrome/global-platform/mac/platformKeys.properties
+++ b/toolkit/locales/en-US/chrome/global-platform/mac/platformKeys.properties
@@ -12,6 +12,9 @@
#the command key - clover leaf symbol (ctrl-q)
VK_META=\u2318
+#the win key - never generated by native key event
+VK_WIN=win
+
#the option/alt key - splitting tracks symbol (ctrl-g)
VK_ALT=\u2325
--- a/toolkit/locales/en-US/chrome/global-platform/unix/platformKeys.properties
+++ b/toolkit/locales/en-US/chrome/global-platform/unix/platformKeys.properties
@@ -12,6 +12,9 @@
#the command key
VK_META=Meta
+#the win key (Super key and Hyper keys are mapped to DOM Win key)
+VK_WIN=Win
+
#the alt key
VK_ALT=Alt
--- a/toolkit/locales/en-US/chrome/global-platform/win/platformKeys.properties
+++ b/toolkit/locales/en-US/chrome/global-platform/win/platformKeys.properties
@@ -12,6 +12,9 @@
#the command key
VK_META=Meta
+#the win key
+VK_WIN=Win
+
#the alt key
VK_ALT=Alt
--- a/widget/gtk2/nsGtkKeyUtils.cpp
+++ b/widget/gtk2/nsGtkKeyUtils.cpp
@@ -56,12 +56,8 @@
{ NS_VK_CONTROL, GDK_Control_R },
{ NS_VK_ALT, GDK_Alt_L },
{ NS_VK_ALT, GDK_Alt_R },
-
- // NS_VK_META is used for Command key of Mac. It's a modifier key for
- // shortcut keys like Ctrl key on GTK or Windows. So, it's really different
- // from GTK's META key, we shouldn't use it on GTK.
- // { NS_VK_META, GDK_Meta_L },
- // { NS_VK_META, GDK_Meta_R },
+ { NS_VK_META, GDK_Meta_L },
+ { NS_VK_META, GDK_Meta_R },
// Assume that Super or Hyper is always mapped to physical Win key.
{ NS_VK_WIN, GDK_Super_L },
@@ -378,8 +374,16 @@
// Note that two or more modifiers may use one modifier flag. E.g.,
// on Ubuntu 10.10, Alt and Meta share the Mod1 in default settings.
- // And also Super and Hyper share the Mod4.
+ // And also Super and Hyper share the Mod4. In such cases, we need to
+ // decide which modifier flag means one of DOM modifiers.
+ // mod[0] is Modifier introduced by Mod1.
+ Modifier mod[5];
+ PRInt32 foundLevel[5];
+ for (PRUint32 i = 0; i < ArrayLength(mod); i++) {
+ mod[i] = NOT_MODIFIER;
+ foundLevel[i] = PR_INT32_MAX;
+ }
const PRUint32 map_size = 8 * xmodmap->max_keypermod;
for (PRUint32 i = 0; i < map_size; i++) {
KeyCode keycode = xmodmap->modifiermap[i];
@@ -400,44 +404,85 @@
xkeymap + (keycode - min_keycode) * keysyms_per_keycode;
const PRUint32 bit = i / xmodmap->max_keypermod;
modifierKey->mMask |= 1 << bit;
+
+ // We need to know the meaning of Mod1, Mod2, Mod3, Mod4 and Mod5.
+ // Let's skip if current map is for others.
+ if (bit < 3) {
+ continue;
+ }
+
+ const PRInt32 modIndex = bit - 3;
for (PRInt32 j = 0; j < keysyms_per_keycode; j++) {
Modifier modifier = GetModifierForGDKKeyval(syms[j]);
PR_LOG(gKeymapWrapperLog, PR_LOG_ALWAYS,
("KeymapWrapper(%p): InitBySystemSettings, "
- " bit=%d, j=%d, syms[j]=%s(0x%X), modifier=%s",
- this, bit, j, gdk_keyval_name(syms[j]), syms[j],
+ " Mod%d, j=%d, syms[j]=%s(0x%X), modifier=%s",
+ this, modIndex + 1, j, gdk_keyval_name(syms[j]), syms[j],
GetModifierName(modifier)));
- ModifierIndex index;
switch (modifier) {
- case NUM_LOCK:
- index = INDEX_NUM_LOCK;
- break;
- case SCROLL_LOCK:
- index = INDEX_SCROLL_LOCK;
+ case NOT_MODIFIER:
+ // Don't overwrite the stored information with
+ // NOT_MODIFIER.
break;
- case ALT:
- index = INDEX_ALT;
- break;
- case SUPER:
- index = INDEX_SUPER;
- break;
- case HYPER:
- index = INDEX_HYPER;
- break;
- case META:
- index = INDEX_META;
- break;
- case ALTGR:
- index = INDEX_ALTGR;
+ case CAPS_LOCK:
+ case SHIFT:
+ case CTRL:
+ // Ignore the modifiers defined in GDK spec. They shouldn't
+ // be mapped to Mod1-5 because they must not work on native
+ // GTK applications.
break;
default:
- // NOTE: We always use GDK_SHIFT_MASK, GDK_CONTROL_MASK and
- // GDK_LOCK_MASK for SHIFT, CTRL and CAPS_LOCK.
- // This is standard manners of GTK application.
- continue;
+ // If new modifier is found in higher level than stored
+ // value, we don't need to overwrite it.
+ if (j > foundLevel[modIndex]) {
+ break;
+ }
+ // If new modifier is more important than stored value,
+ // we should overwrite it with new modifier.
+ if (j == foundLevel[modIndex]) {
+ mod[modIndex] = NS_MIN(modifier, mod[modIndex]);
+ break;
+ }
+ foundLevel[modIndex] = j;
+ mod[modIndex] = modifier;
+ break;
+ }
+ }
+ }
+
+ for (PRUint32 i = 0; i < COUNT_OF_MODIFIER_INDEX; i++) {
+ Modifier modifier;
+ switch (i) {
+ case INDEX_NUM_LOCK:
+ modifier = NUM_LOCK;
+ break;
+ case INDEX_SCROLL_LOCK:
+ modifier = SCROLL_LOCK;
+ break;
+ case INDEX_ALT:
+ modifier = ALT;
+ break;
+ case INDEX_META:
+ modifier = META;
+ break;
+ case INDEX_SUPER:
+ modifier = SUPER;
+ break;
+ case INDEX_HYPER:
+ modifier = HYPER;
+ break;
+ case INDEX_ALTGR:
+ modifier = ALTGR;
+ break;
+ default:
+ MOZ_NOT_REACHED("All indexes must be handled here");
+ break;
+ }
+ for (PRUint32 j = 0; j < ArrayLength(mod); j++) {
+ if (modifier == mod[j]) {
+ mModifierMasks[i] |= 1 << (j + 3);
}
- mModifierMasks[index] |= 1 << bit;
}
}
@@ -534,6 +579,9 @@
if (keymapWrapper->AreModifiersActive(ALT, aModifierState)) {
aInputEvent.modifiers |= MODIFIER_ALT;
}
+ if (keymapWrapper->AreModifiersActive(META, aModifierState)) {
+ aInputEvent.modifiers |= MODIFIER_META;
+ }
if (keymapWrapper->AreModifiersActive(SUPER, aModifierState) ||
keymapWrapper->AreModifiersActive(HYPER, aModifierState)) {
aInputEvent.modifiers |= MODIFIER_OS;
@@ -554,11 +602,13 @@
PR_LOG(gKeymapWrapperLog, PR_LOG_DEBUG,
("KeymapWrapper(%p): InitInputEvent, aModifierState=0x%08X, "
"aInputEvent.modifiers=0x%04X (Shift: %s, Control: %s, Alt: %s, "
- "OS: %s, AltGr: %s, CapsLock: %s, NumLock: %s, ScrollLock: %s)",
+ "Meta: %s, OS: %s, AltGr: %s, "
+ "CapsLock: %s, NumLock: %s, ScrollLock: %s)",
keymapWrapper, aModifierState, aInputEvent.modifiers,
GetBoolName(aInputEvent.modifiers & MODIFIER_SHIFT),
GetBoolName(aInputEvent.modifiers & MODIFIER_CONTROL),
GetBoolName(aInputEvent.modifiers & MODIFIER_ALT),
+ GetBoolName(aInputEvent.modifiers & MODIFIER_META),
GetBoolName(aInputEvent.modifiers & MODIFIER_OS),
GetBoolName(aInputEvent.modifiers & MODIFIER_ALTGRAPH),
GetBoolName(aInputEvent.modifiers & MODIFIER_CAPSLOCK),
@@ -616,7 +666,17 @@
if (GetModifierForGDKKeyval(keyvalWithoutModifier)) {
keyval = keyvalWithoutModifier;
}
- return GetDOMKeyCodeFromKeyPairs(keyval);
+ // Note that the modifier keycode and activating or deactivating
+ // modifier flag may be mismatched, but it's okay. If a DOM key
+ // event handler is testing a keydown event, it's more likely being
+ // used to test which key is being pressed than to test which
+ // modifier will become active. So, if we computed DOM keycode
+ // from modifier flag which were changing by the physical key, then
+ // there would be no other way for the user to generate the original
+ // keycode.
+ PRUint32 DOMKeyCode = GetDOMKeyCodeFromKeyPairs(keyval);
+ NS_ASSERTION(DOMKeyCode, "All modifier keys must have a DOM keycode");
+ return DOMKeyCode;
}
// If the key isn't printable, let's look at the key pairs.
@@ -1126,9 +1186,11 @@
// If the event causes inputting a character, keyCode must be zero.
aKeyEvent.keyCode = 0;
- // If Ctrl or Alt or Meta is pressed, we need to append the key details
- // for handling shortcut key. Otherwise, we have no additional work.
- if (!aKeyEvent.IsControl() && !aKeyEvent.IsAlt() && !aKeyEvent.IsMeta()) {
+ // If Ctrl or Alt or Meta or OS is pressed, we need to append the key
+ // details for handling shortcut key. Otherwise, we have no additional
+ // work.
+ if (!aKeyEvent.IsControl() && !aKeyEvent.IsAlt() &&
+ !aKeyEvent.IsMeta() && !aKeyEvent.IsOS()) {
PR_LOG(gKeymapWrapperLog, PR_LOG_ALWAYS,
("KeymapWrapper(%p): InitKeypressEvent, "
"keyCode=0x%02X, charCode=0x%08X",
--- a/widget/gtk2/nsGtkKeyUtils.h
+++ b/widget/gtk2/nsGtkKeyUtils.h
@@ -53,9 +53,9 @@
SHIFT = 0x0008,
CTRL = 0x0010,
ALT = 0x0020,
- SUPER = 0x0040,
- HYPER = 0x0080,
- META = 0x0100,
+ META = 0x0040,
+ SUPER = 0x0080,
+ HYPER = 0x0100,
ALTGR = 0x0200
};
@@ -170,9 +170,9 @@
INDEX_NUM_LOCK,
INDEX_SCROLL_LOCK,
INDEX_ALT,
+ INDEX_META,
INDEX_SUPER,
INDEX_HYPER,
- INDEX_META,
INDEX_ALTGR,
COUNT_OF_MODIFIER_INDEX
};
--- a/widget/nsGUIEvent.h
+++ b/widget/nsGUIEvent.h
@@ -1786,6 +1786,17 @@
nsDragDropEventStatus_eDrop
};
+#define NS_IS_INPUT_EVENT(evnt) \
+ (((evnt)->eventStructType == NS_INPUT_EVENT) || \
+ ((evnt)->eventStructType == NS_ACCESSIBLE_EVENT) || \
+ ((evnt)->eventStructType == NS_MOUSE_EVENT) || \
+ ((evnt)->eventStructType == NS_KEY_EVENT) || \
+ ((evnt)->eventStructType == NS_TEXT_EVENT) || \
+ ((evnt)->eventStructType == NS_TOUCH_EVENT) || \
+ ((evnt)->eventStructType == NS_DRAG_EVENT) || \
+ ((evnt)->eventStructType == NS_MOUSE_SCROLL_EVENT) || \
+ ((evnt)->eventStructType == NS_MOZTOUCH_EVENT) || \
+ ((evnt)->eventStructType == NS_SIMPLE_GESTURE_EVENT))
#define NS_IS_MOUSE_EVENT(evnt) \
(((evnt)->message == NS_MOUSE_BUTTON_DOWN) || \
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -6324,7 +6324,7 @@
// Enter and backspace are always handled here to avoid for example the
// confusion between ctrl-enter and ctrl-J.
if (DOMKeyCode == NS_VK_RETURN || DOMKeyCode == NS_VK_BACK ||
- ((aModKeyState.mIsControlDown || aModKeyState.mIsAltDown)
+ ((aModKeyState.mIsControlDown || aModKeyState.mIsAltDown || aModKeyState.mIsWinDown)
&& !gKbdLayout.IsDeadKey() && KeyboardLayout::IsPrintableCharKey(virtualKeyCode)))
{
// Remove a possible WM_CHAR or WM_SYSCHAR messages from the message queue.
@@ -6391,6 +6391,7 @@
return result;
}
else if (!aModKeyState.mIsControlDown && !aModKeyState.mIsAltDown &&
+ !aModKeyState.mIsWinDown &&
(KeyboardLayout::IsPrintableCharKey(virtualKeyCode) ||
KeyboardLayout::IsNumpadKey(virtualKeyCode)))
{