summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@digia.com>2014-07-02 15:44:49 +0200
committerAllan Sandfeld Jensen <allan.jensen@digia.com>2014-08-02 03:00:38 +0200
commit985ebe32f2ed9c899b26c98ccad2d1a08fa2326c (patch)
treec970244a3e860812ecb6ff7a7f88b8e945611c9f
parentc0c80f14afba322179ac505816cdc51267b3a6ce (diff)
Support multimedia keys on Windows
We currently do not receive events from most multimedia keys on Windows because they are sent using appcommand events instead of the normal key events. This patchs adds support for parsing appcommand events. Change-Id: I19f568b6fa0d3d136e3a22318df1499a1fab6edb Reviewed-by: Oliver Wolff <oliver.wolff@digia.com>
-rw-r--r--src/corelib/global/qnamespace.h9
-rw-r--r--src/gui/kernel/qkeysequence.cpp32
-rw-r--r--src/plugins/platforms/windows/qtwindowsglobal.h5
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp1
-rw-r--r--src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp3
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.cpp85
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.h1
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp4
8 files changed, 136 insertions, 4 deletions
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index 1b92a0e845..6dfd8e3ab1 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -1014,6 +1014,15 @@ public:
Key_Info = 0x0100011b,
Key_Settings = 0x0100011c,
+ Key_MicVolumeUp = 0x0100011d,
+ Key_MicVolumeDown = 0x0100011e,
+
+ Key_New = 0x01000120,
+ Key_Open = 0x01000121,
+ Key_Find = 0x01000122,
+ Key_Undo = 0x01000123,
+ Key_Redo = 0x01000124,
+
Key_MediaLast = 0x0100ffff,
// Keypad navigation keys
diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp
index 59cdabbc0f..8261ac7208 100644
--- a/src/gui/kernel/qkeysequence.cpp
+++ b/src/gui/kernel/qkeysequence.cpp
@@ -490,7 +490,7 @@ static const struct {
{ Qt::Key_BrightnessAdjust, QT_TRANSLATE_NOOP("QShortcut", "Adjust Brightness") },
{ Qt::Key_Finance, QT_TRANSLATE_NOOP("QShortcut", "Finance") },
{ Qt::Key_Community, QT_TRANSLATE_NOOP("QShortcut", "Community") },
- { Qt::Key_AudioRewind, QT_TRANSLATE_NOOP("QShortcut", "Audio Rewind") },
+ { Qt::Key_AudioRewind, QT_TRANSLATE_NOOP("QShortcut", "Media Rewind") },
{ Qt::Key_BackForward, QT_TRANSLATE_NOOP("QShortcut", "Back Forward") },
{ Qt::Key_ApplicationLeft, QT_TRANSLATE_NOOP("QShortcut", "Application Left") },
{ Qt::Key_ApplicationRight, QT_TRANSLATE_NOOP("QShortcut", "Application Right") },
@@ -550,17 +550,40 @@ static const struct {
{ Qt::Key_Bluetooth, QT_TRANSLATE_NOOP("QShortcut", "Bluetooth") },
{ Qt::Key_WLAN, QT_TRANSLATE_NOOP("QShortcut", "Wireless") },
{ Qt::Key_UWB, QT_TRANSLATE_NOOP("QShortcut", "Ultra Wide Band") },
- { Qt::Key_AudioForward, QT_TRANSLATE_NOOP("QShortcut", "Audio Forward") },
+ { Qt::Key_AudioForward, QT_TRANSLATE_NOOP("QShortcut", "Media Fast Forward") },
{ Qt::Key_AudioRepeat, QT_TRANSLATE_NOOP("QShortcut", "Audio Repeat") },
{ Qt::Key_AudioRandomPlay, QT_TRANSLATE_NOOP("QShortcut", "Audio Random Play") },
{ Qt::Key_Subtitle, QT_TRANSLATE_NOOP("QShortcut", "Subtitle") },
{ Qt::Key_AudioCycleTrack, QT_TRANSLATE_NOOP("QShortcut", "Audio Cycle Track") },
{ Qt::Key_Time, QT_TRANSLATE_NOOP("QShortcut", "Time") },
- { Qt::Key_Select, QT_TRANSLATE_NOOP("QShortcut", "Select") },
+ { Qt::Key_Hibernate, QT_TRANSLATE_NOOP("QShortcut", "Hibernate") },
{ Qt::Key_View, QT_TRANSLATE_NOOP("QShortcut", "View") },
{ Qt::Key_TopMenu, QT_TRANSLATE_NOOP("QShortcut", "Top Menu") },
+ { Qt::Key_PowerDown, QT_TRANSLATE_NOOP("QShortcut", "Power Down") },
{ Qt::Key_Suspend, QT_TRANSLATE_NOOP("QShortcut", "Suspend") },
- { Qt::Key_Hibernate, QT_TRANSLATE_NOOP("QShortcut", "Hibernate") },
+
+ { Qt::Key_MicMute, QT_TRANSLATE_NOOP("QShortcut", "Microphone Mute") },
+
+ { Qt::Key_Red, QT_TRANSLATE_NOOP("QShortcut", "Red") },
+ { Qt::Key_Green, QT_TRANSLATE_NOOP("QShortcut", "Green") },
+ { Qt::Key_Yellow, QT_TRANSLATE_NOOP("QShortcut", "Yellow") },
+ { Qt::Key_Blue, QT_TRANSLATE_NOOP("QShortcut", "Blue") },
+
+ { Qt::Key_ChannelUp, QT_TRANSLATE_NOOP("QShortcut", "Channel Up") },
+ { Qt::Key_ChannelDown, QT_TRANSLATE_NOOP("QShortcut", "Channel Down") },
+
+ { Qt::Key_Guide, QT_TRANSLATE_NOOP("QShortcut", "Guide") },
+ { Qt::Key_Info, QT_TRANSLATE_NOOP("QShortcut", "Info") },
+ { Qt::Key_Settings, QT_TRANSLATE_NOOP("QShortcut", "Settings") },
+
+ { Qt::Key_MicVolumeUp, QT_TRANSLATE_NOOP("QShortcut", "Microphone Volume Up") },
+ { Qt::Key_MicVolumeDown, QT_TRANSLATE_NOOP("QShortcut", "Microphone Volume Down") },
+
+ { Qt::Key_New, QT_TRANSLATE_NOOP("QShortcut", "New") },
+ { Qt::Key_Open, QT_TRANSLATE_NOOP("QShortcut", "Open") },
+ { Qt::Key_Find, QT_TRANSLATE_NOOP("QShortcut", "Find") },
+ { Qt::Key_Undo, QT_TRANSLATE_NOOP("QShortcut", "Undo") },
+ { Qt::Key_Redo, QT_TRANSLATE_NOOP("QShortcut", "Redo") },
// --------------------------------------------------------------
// More consistent namings
@@ -647,6 +670,7 @@ static const struct {
{ Qt::Key_Execute, QT_TRANSLATE_NOOP("QShortcut", "Execute") },
{ Qt::Key_Play, QT_TRANSLATE_NOOP("QShortcut", "Play") },
{ Qt::Key_Zoom, QT_TRANSLATE_NOOP("QShortcut", "Zoom") },
+ { Qt::Key_Exit, QT_TRANSLATE_NOOP("QShortcut", "Exit") },
{ 0, 0 }
};
diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h
index 3992f2d297..1b2502af10 100644
--- a/src/plugins/platforms/windows/qtwindowsglobal.h
+++ b/src/plugins/platforms/windows/qtwindowsglobal.h
@@ -103,6 +103,7 @@ enum WindowsEventType // Simplify event types
AccessibleObjectFromWindowRequest = ApplicationEventFlag + 3,
QueryEndSessionApplicationEvent = ApplicationEventFlag + 4,
EndSessionApplicationEvent = ApplicationEventFlag + 5,
+ AppCommandEvent = ApplicationEventFlag + 6,
InputMethodStartCompositionEvent = InputMethodEventFlag + 1,
InputMethodCompositionEvent = InputMethodEventFlag + 2,
InputMethodEndCompositionEvent = InputMethodEventFlag + 3,
@@ -242,6 +243,10 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI
case WM_ENDSESSION:
return QtWindows::EndSessionApplicationEvent;
#endif
+#if defined(WM_APPCOMMAND)
+ case WM_APPCOMMAND:
+ return QtWindows::AppCommandEvent;
+#endif
default:
break;
}
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 322bae10aa..9706615047 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -962,6 +962,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
case QtWindows::InputMethodKeyEvent:
case QtWindows::InputMethodKeyDownEvent:
case QtWindows::KeyboardLayoutChangeEvent:
+ case QtWindows::AppCommandEvent:
#if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER)
return platformSessionManager()->isInteractionBlocked() ? true : d->m_keyMapper.translateKeyEvent(platformWindow->window(), hwnd, msg, result);
#else
diff --git a/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp b/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp
index 878db7185d..8a8306f01a 100644
--- a/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp
+++ b/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp
@@ -115,6 +115,9 @@ messageDebugEntries[] = {
{WM_SYSCOMMAND, "WM_SYSCOMMAND", true},
{WM_KEYUP, "WM_KEYUP", true},
{WM_SYSKEYUP, "WM_SYSKEYUP", true},
+#if defined(WM_APPCOMMAND)
+ {WM_APPCOMMAND, "WM_APPCOMMAND", true},
+#endif
{WM_IME_CHAR, "WM_IMECHAR", true},
{WM_IME_KEYDOWN, "WM_IMECHAR", true},
{WM_CANCELMODE, "WM_CANCELMODE", true},
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp
index 6bcfe01a18..dc1de047fe 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.cpp
+++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -428,6 +428,63 @@ static const uint KeyTbl[] = { // Keyboard mapping table
0
};
+static const uint CmdTbl[] = { // Multimedia keys mapping table
+ // Dec | Hex | AppCommand
+ Qt::Key_unknown, // 0 0x00
+ Qt::Key_Back, // 1 0x01 APPCOMMAND_BROWSER_BACKWARD
+ Qt::Key_Forward, // 2 0x02 APPCOMMAND_BROWSER_FORWARD
+ Qt::Key_Refresh, // 3 0x03 APPCOMMAND_BROWSER_REFRESH
+ Qt::Key_Stop, // 4 0x04 APPCOMMAND_BROWSER_STOP
+ Qt::Key_Search, // 5 0x05 APPCOMMAND_BROWSER_SEARCH
+ Qt::Key_Favorites, // 6 0x06 APPCOMMAND_BROWSER_FAVORITES
+ Qt::Key_Home, // 7 0x07 APPCOMMAND_BROWSER_HOME
+ Qt::Key_VolumeMute, // 8 0x08 APPCOMMAND_VOLUME_MUTE
+ Qt::Key_VolumeDown, // 9 0x09 APPCOMMAND_VOLUME_DOWN
+ Qt::Key_VolumeUp, // 10 0x0a APPCOMMAND_VOLUME_UP
+ Qt::Key_MediaNext, // 11 0x0b APPCOMMAND_MEDIA_NEXTTRACK
+ Qt::Key_MediaPrevious, // 12 0x0c APPCOMMAND_MEDIA_PREVIOUSTRACK
+ Qt::Key_MediaStop, // 13 0x0d APPCOMMAND_MEDIA_STOP
+ Qt::Key_MediaTogglePlayPause, // 14 0x0e APPCOMMAND_MEDIA_PLAYPAUSE
+ Qt::Key_LaunchMail, // 15 0x0f APPCOMMAND_LAUNCH_MAIL
+ Qt::Key_LaunchMedia, // 16 0x10 APPCOMMAND_LAUNCH_MEDIA_SELECT
+ Qt::Key_Launch0, // 17 0x11 APPCOMMAND_LAUNCH_APP1
+ Qt::Key_Launch1, // 18 0x12 APPCOMMAND_LAUNCH_APP2
+ Qt::Key_BassDown, // 19 0x13 APPCOMMAND_BASS_DOWN
+ Qt::Key_BassBoost, // 20 0x14 APPCOMMAND_BASS_BOOST
+ Qt::Key_BassUp, // 21 0x15 APPCOMMAND_BASS_UP
+ Qt::Key_TrebleDown, // 22 0x16 APPCOMMAND_TREBLE_DOWN
+ Qt::Key_TrebleUp, // 23 0x17 APPCOMMAND_TREBLE_UP
+ Qt::Key_MicMute, // 24 0x18 APPCOMMAND_MICROPHONE_VOLUME_MUTE
+ Qt::Key_MicVolumeDown, // 25 0x19 APPCOMMAND_MICROPHONE_VOLUME_DOWN
+ Qt::Key_MicVolumeUp, // 26 0x1a APPCOMMAND_MICROPHONE_VOLUME_UP
+ Qt::Key_Help, // 27 0x1b APPCOMMAND_HELP
+ Qt::Key_Find, // 28 0x1c APPCOMMAND_FIND
+ Qt::Key_New, // 29 0x1d APPCOMMAND_NEW
+ Qt::Key_Open, // 30 0x1e APPCOMMAND_OPEN
+ Qt::Key_Close, // 31 0x1f APPCOMMAND_CLOSE
+ Qt::Key_Save, // 32 0x20 APPCOMMAND_SAVE
+ Qt::Key_Print, // 33 0x21 APPCOMMAND_PRINT
+ Qt::Key_Undo, // 34 0x22 APPCOMMAND_UNDO
+ Qt::Key_Redo, // 35 0x23 APPCOMMAND_REDO
+ Qt::Key_Copy, // 36 0x24 APPCOMMAND_COPY
+ Qt::Key_Cut, // 37 0x25 APPCOMMAND_CUT
+ Qt::Key_Paste, // 38 0x26 APPCOMMAND_PASTE
+ Qt::Key_Reply, // 39 0x27 APPCOMMAND_REPLY_TO_MAIL
+ Qt::Key_MailForward, // 40 0x28 APPCOMMAND_FORWARD_MAIL
+ Qt::Key_Send, // 41 0x29 APPCOMMAND_SEND_MAIL
+ Qt::Key_Spell, // 42 0x2a APPCOMMAND_SPELL_CHECK
+ Qt::Key_unknown, // 43 0x2b APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE
+ Qt::Key_unknown, // 44 0x2c APPCOMMAND_MIC_ON_OFF_TOGGLE
+ Qt::Key_unknown, // 45 0x2d APPCOMMAND_CORRECTION_LIST
+ Qt::Key_MediaPlay, // 46 0x2e APPCOMMAND_MEDIA_PLAY
+ Qt::Key_MediaPause, // 47 0x2f APPCOMMAND_MEDIA_PAUSE
+ Qt::Key_MediaRecord, // 48 0x30 APPCOMMAND_MEDIA_RECORD
+ Qt::Key_AudioForward, // 49 0x31 APPCOMMAND_MEDIA_FAST_FORWARD
+ Qt::Key_AudioRewind, // 50 0x32 APPCOMMAND_MEDIA_REWIND
+ Qt::Key_ChannelDown, // 51 0x33 APPCOMMAND_MEDIA_CHANNEL_DOWN
+ Qt::Key_ChannelUp // 52 0x34 APPCOMMAND_MEDIA_CHANNEL_UP
+};
+
// Possible modifier states.
// NOTE: The order of these states match the order in QWindowsKeyMapper::updatePossibleKeyCodes()!
static const Qt::KeyboardModifiers ModsTbl[] = {
@@ -747,6 +804,11 @@ bool QWindowsKeyMapper::translateKeyEvent(QWindow *widget, HWND hwnd,
return true;
}
+#if defined(WM_APPCOMMAND)
+ if (msg.message == WM_APPCOMMAND)
+ return translateMultimediaKeyEventInternal(widget, msg);
+#endif
+
// WM_(IME_)CHAR messages already contain the character in question so there is
// no need to fiddle with our key map. In any other case add this key to the
// keymap if it is not present yet.
@@ -761,6 +823,29 @@ bool QWindowsKeyMapper::translateKeyEvent(QWindow *widget, HWND hwnd,
return translateKeyEventInternal(widget, msg, false);
}
+bool QWindowsKeyMapper::translateMultimediaKeyEventInternal(QWindow *window, const MSG &msg)
+{
+#if defined(WM_APPCOMMAND)
+ const int cmd = GET_APPCOMMAND_LPARAM(msg.lParam);
+ const int dwKeys = GET_KEYSTATE_LPARAM(msg.lParam);
+ int state = 0;
+ state |= (dwKeys & MK_SHIFT ? int(Qt::ShiftModifier) : 0);
+ state |= (dwKeys & MK_CONTROL ? int(Qt::ControlModifier) : 0);
+
+ QWindow *receiver = m_keyGrabber ? m_keyGrabber : window;
+
+ if (cmd < 0 || cmd > 52)
+ return false;
+
+ const int qtKey = CmdTbl[cmd];
+ sendExtendedPressRelease(receiver, qtKey, Qt::KeyboardModifier(state), 0, 0, 0);
+ return true;
+#else
+ Q_UNREACHABLE();
+ return false;
+#endif
+}
+
bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &msg, bool /* grab */)
{
const int msgType = msg.message;
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.h b/src/plugins/platforms/windows/qwindowskeymapper.h
index f7d33758a0..247a807af7 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.h
+++ b/src/plugins/platforms/windows/qwindowskeymapper.h
@@ -93,6 +93,7 @@ public:
private:
bool translateKeyEventInternal(QWindow *receiver, const MSG &msg, bool grab);
+ bool translateMultimediaKeyEventInternal(QWindow *receiver, const MSG &msg);
void updateKeyMap(const MSG &msg);
bool m_useRTLExtensions;
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index 4c84b19f82..c52714b456 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -198,8 +198,10 @@
#define XF86XK_MenuKB 0x1008FF65
#define XF86XK_MenuPB 0x1008FF66
#define XF86XK_MySites 0x1008FF67
+#define XF86XK_New 0x1008FF68
#define XF86XK_News 0x1008FF69
#define XF86XK_OfficeHome 0x1008FF6A
+#define XF86XK_Open 0x1008FF6B
#define XF86XK_Option 0x1008FF6C
#define XF86XK_Paste 0x1008FF6D
#define XF86XK_Phone 0x1008FF6E
@@ -497,8 +499,10 @@ static const unsigned int KeyTbl[] = {
XF86XK_MenuKB, Qt::Key_MenuKB,
XF86XK_MenuPB, Qt::Key_MenuPB,
XF86XK_MySites, Qt::Key_MySites,
+ XF86XK_New, Qt::Key_New,
XF86XK_News, Qt::Key_News,
XF86XK_OfficeHome, Qt::Key_OfficeHome,
+ XF86XK_Open, Qt::Key_Open,
XF86XK_Option, Qt::Key_Option,
XF86XK_Paste, Qt::Key_Paste,
XF86XK_Phone, Qt::Key_Phone,