42 #include <private/qt_mac_p.h> 45 #include <private/qevent_p.h> 49 #include <private/qkeymapper_p.h> 50 #include <private/qapplication_p.h> 51 #include <private/qmacinputcontext_p.h> 72 static bool secure =
false;
74 b ? EnableSecureEventInput() : DisableSecureEventInput();
106 static const Qt::KeyboardModifiers
ModsTbl[] = {
130 #if defined(DEBUG_KEY_BINDINGS) 131 # define QT_MAC_MAP_ENUM(x) x, #x 134 # define QT_MAC_MAP_ENUM(x) x 152 #ifdef DEBUG_KEY_BINDINGS_MODIFIERS 153 qDebug(
"Qt: internal: **Mapping modifiers: %d (0x%04x)", keys, keys);
156 for (
int i = 0; qt_mac_modifier_symbols[i].
qt_code; i++) {
157 if (keys & qt_mac_modifier_symbols[i].mac_code) {
158 #ifdef DEBUG_KEY_BINDINGS_MODIFIERS 159 qDebug(
"Qt: internal: got modifier: %s", qt_mac_modifier_symbols[i].desc);
165 Qt::KeyboardModifiers oldModifiers = ret;
176 #ifdef DEBUG_KEY_BINDINGS_MODIFIERS 177 qDebug(
"Qt: internal: **Mapping modifiers: %d (0x%04x)", (
int)keys, (
int)keys);
180 for (
int i = 0; qt_mac_modifier_symbols[i].
qt_code; i++) {
181 if (keys & qt_mac_modifier_symbols[i].qt_code) {
182 #ifdef DEBUG_KEY_BINDINGS_MODIFIERS 183 qDebug(
"Qt: internal: got modifier: %s", qt_mac_modifier_symbols[i].desc);
185 ret |= qt_mac_modifier_symbols[i].
mac_code;
190 int oldModifiers = ret;
191 ret &= ~(controlKeyBit | cmdKeyBit);
192 if (oldModifiers & controlKeyBit)
194 if (oldModifiers & cmdKeyBit)
195 ret |= controlKeyBit;
201 static quint32 cachedModifiers = 0;
202 quint32 lastModifiers = cachedModifiers,
203 changedModifiers = lastModifiers ^ modifiers;
204 cachedModifiers = modifiers;
218 for (
int i = 0; i <= 32; i++) {
219 if (!(changedModifiers & (1 << i)))
222 if (lastModifiers & (1 << i))
225 for (
uint x = 0; modifier_key_symbols[x].
mac_code; x++) {
226 if (modifier_key_symbols[x].mac_code == i) {
227 #ifdef DEBUG_KEY_BINDINGS_MODIFIERS 228 qDebug(
"got modifier changed: %s", modifier_key_symbols[x].desc);
230 key = modifier_key_symbols[x].
qt_code;
235 #ifdef DEBUG_KEY_BINDINGS_MODIFIERS 236 qDebug(
"could not get modifier changed: %d", i);
240 #ifdef DEBUG_KEY_BINDINGS_MODIFIERS 241 qDebug(
"KeyEvent (modif): Sending %s to %s::%s: %d - 0x%08x",
244 object ?
object->objectName().toLatin1().constData() :
"",
245 key, (int)modifiers);
354 #ifdef DEBUG_KEY_BINDINGS 355 qDebug(
"**Mapping key: %d (0x%04x) - %d (0x%04x)", key.
unicode(), key.
unicode(), virtualKey, virtualKey);
358 if (key == kClearCharCode && virtualKey == 0x47)
362 #ifdef DEBUG_KEY_BINDINGS 369 #ifdef DEBUG_KEY_BINDINGS 375 #ifdef DEBUG_KEY_BINDINGS 381 for (
int i = 0; qt_mac_keyboard_symbols[i].
qt_code; i++) {
382 if (qt_mac_keyboard_symbols[i].mac_code == key) {
385 #ifdef DEBUG_KEY_BINDINGS 386 qDebug(
"%d: got key: Qt::Key_Backtab", __LINE__);
391 #ifdef DEBUG_KEY_BINDINGS 392 qDebug(
"%d: got key: %s", __LINE__, qt_mac_keyboard_symbols[i].desc);
394 return qt_mac_keyboard_symbols[i].
qt_code;
399 for (
int i = 0; qt_mac_keyvkey_symbols[i].
qt_code; i++) {
400 if (qt_mac_keyvkey_symbols[i].mac_code == virtualKey) {
401 #ifdef DEBUG_KEY_BINDINGS 402 qDebug(
"%d: got key: %s", __LINE__, qt_mac_keyvkey_symbols[i].desc);
404 return qt_mac_keyvkey_symbols[i].
qt_code;
409 if (key >= 0xf700 && key <= 0xf747) {
410 if (key >= 0xf704 && key <= 0xf726) {
413 for (
int i = 0; qt_mac_private_unicode[i].
qt_code; i++) {
414 if (qt_mac_private_unicode[i].mac_code == key) {
415 return qt_mac_private_unicode[i].
qt_code;
422 #ifdef DEBUG_KEY_BINDINGS 423 qDebug(
"Unknown case.. %s:%d %d[%d] %d", __FILE__, __LINE__, key.
unicode(), key.
toLatin1(), virtualKey);
430 UInt32 ekind = GetEventKind(inEvent),
431 eclass = GetEventClass(inEvent);
432 return (eclass == kEventClassKeyboard && (
void *)ekind == data);
436 QChar *outChar, Qt::KeyboardModifiers *outModifiers,
bool *outHandled)
438 #if !defined(QT_MAC_USE_COCOA) || defined(Q_OS_MAC64) 442 const UInt32 ekind = GetEventKind(keyEvent);
444 UInt32 mac_modifiers = 0;
445 GetEventParameter(keyEvent, kEventParamKeyModifiers, typeUInt32, 0,
446 sizeof(mac_modifiers), 0, &mac_modifiers);
447 #ifdef DEBUG_KEY_BINDINGS_MODIFIERS 448 qDebug(
"************ Mapping modifiers and key ***********");
451 #ifdef DEBUG_KEY_BINDINGS_MODIFIERS 452 qDebug(
"------------ Mapping modifiers and key -----------");
458 GetEventParameter(keyEvent, kEventParamKeyCode, typeUInt32, 0,
sizeof(keyCode), 0, &keyCode);
461 static UInt32 tmp_unused_state = 0L;
462 const UCKeyboardLayout *uchrData = 0;
463 #if defined(Q_OS_MAC32) 464 KeyboardLayoutRef keyLayoutRef = 0;
465 KLGetCurrentKeyboardLayout(&keyLayoutRef);
467 if (keyLayoutRef != 0) {
468 err = KLGetKeyboardLayoutProperty(keyLayoutRef, kKLuchrData,
469 (reinterpret_cast<const void **>(&uchrData)));
471 qWarning(
"Qt::internal::unable to get keyboardlayout %ld %s:%d",
472 long(err), __FILE__, __LINE__);
478 CFDataRef
data =
static_cast<CFDataRef
>(TISGetInputSourceProperty(inputSource,
479 kTISPropertyUnicodeKeyLayoutData));
480 uchrData = data ?
reinterpret_cast<const UCKeyboardLayout *
>(CFDataGetBytePtr(data)) : 0;
486 UniCharCount actualLength;
487 UInt32 currentModifiers = GetCurrentEventKeyModifiers();
488 UInt32 currentModifiersWOAltOrControl = currentModifiers & ~(controlKey | optionKey);
492 case kEventRawKeyDown:
493 keyAction = kUCKeyActionDown;
496 keyAction = kUCKeyActionUp;
498 case kEventRawKeyRepeat:
499 keyAction = kUCKeyActionAutoKey;
502 OSStatus err = UCKeyTranslate(uchrData, keyCode, keyAction,
503 ((currentModifiersWOAltOrControl >> 8) & 0xff), LMGetKbdType(),
504 kUCKeyTranslateNoDeadKeysMask, &tmp_unused_state, 4, &actualLength,
507 *outChar =
QChar(
string[0]);
509 if (currentModifiersWOAltOrControl != currentModifiers) {
511 err = UCKeyTranslate(uchrData, keyCode, keyAction,
512 ((currentModifiers >> 8) & 0xff), LMGetKbdType(),
513 kUCKeyTranslateNoDeadKeysMask, &tmp_unused_state, 4, &actualLength,
516 *outChar =
QChar(
string[0]);
519 qWarning(
"Qt::internal::UCKeyTranslate is returnining %ld %s:%d",
520 long(err), __FILE__, __LINE__);
526 const void *keyboard_layout;
527 KeyboardLayoutRef keyLayoutRef = 0;
528 KLGetCurrentKeyboardLayout(&keyLayoutRef);
529 err = KLGetKeyboardLayoutProperty(keyLayoutRef, kKLKCHRData,
530 reinterpret_cast<const void **>(&keyboard_layout));
532 int translatedChar = KeyTranslate(keyboard_layout, (GetCurrentEventKeyModifiers() &
533 (kEventKeyModifierNumLockMask|shiftKey|cmdKey|
534 rightShiftKey|alphaLock)) | keyCode,
536 if (!translatedChar) {
537 #ifdef QT_MAC_USE_COCOA 541 CallNextEventHandler(er, keyEvent);
551 if (translatedChar & (1 << 7))
555 static UInt32 tmp_state = 0L;
559 tmp_mod |= controlKey;
562 if (GetCurrentEventKeyModifiers() & alphaLock)
563 tmp_mod |= alphaLock;
565 tmp_mod |= optionKey;
567 tmp_mod |= kEventKeyModifierNumLockMask;
568 translatedChar = KeyTranslate(keyboard_layout, tmp_mod | keyCode, &tmp_state);
571 ByteCount unilen = 0;
572 if (GetEventParameter(keyEvent, kEventParamKeyUnicodes, typeUnicodeText, 0, 0, &unilen, 0)
573 == noErr && unilen == 2) {
574 GetEventParameter(keyEvent, kEventParamKeyUnicodes, typeUnicodeText, 0, unilen, 0, outChar);
575 }
else if (translatedChar) {
579 char tmpChar = (char)translatedChar;
594 memset(keyLayout, 0,
sizeof(keyLayout));
595 keyboard_layout_format.unicode = 0;
597 keyboard_mode = NullMode;
599 currentInputSource = 0;
609 QKeyMapperPrivate::updateKeyboard()
611 const UCKeyboardLayout *uchrData = 0;
613 KeyboardLayoutRef keyLayoutRef = 0;
614 KLGetCurrentKeyboardLayout(&keyLayoutRef);
616 if (keyboard_mode != NullMode && currentKeyboardLayout == keyLayoutRef)
620 if (keyLayoutRef != 0) {
621 err = KLGetKeyboardLayoutProperty(keyLayoutRef, kKLuchrData,
622 const_cast<const void **>(reinterpret_cast<const void **>(&uchrData)));
624 qWarning(
"Qt::internal::unable to get unicode keyboardlayout %ld %s:%d",
625 long(err), __FILE__, __LINE__);
630 if (keyboard_mode != NullMode && source == currentInputSource) {
634 CFDataRef
data =
static_cast<CFDataRef
>(TISGetInputSourceProperty(source,
635 kTISPropertyUnicodeKeyLayoutData));
636 uchrData = data ?
reinterpret_cast<const UCKeyboardLayout *
>(CFDataGetBytePtr(data)) : 0;
639 keyboard_kind = LMGetKbdType();
641 keyboard_layout_format.unicode = uchrData;
642 keyboard_mode = UnicodeMode;
647 err = KLGetKeyboardLayoutProperty(keyLayoutRef, kKLKCHRData,
648 const_cast<const void **>(reinterpret_cast<void **>(&happy)));
650 qFatal(
"Qt::internal::unable to get non-unicode layout, cannot procede %ld %s:%d",
651 long(err), __FILE__, __LINE__);
653 keyboard_layout_format.other = happy;
654 keyboard_mode = OtherMode;
657 currentKeyboardLayout = keyLayoutRef;
659 currentInputSource = source;
664 # ifndef kKLLanguageCode 665 # define kKLLanguageCode 9 667 KLGetKeyboardLayoutProperty(currentKeyboardLayout, kKLLanguageCode,
668 reinterpret_cast<const void **>(&iso639Code));
670 CFArrayRef array =
static_cast<CFArrayRef>(TISGetInputSourceProperty(currentInputSource, kTISPropertyInputSourceLanguages));
671 iso639Code =
static_cast<CFStringRef>(CFArrayGetValueAtIndex(array, 0));
675 keyboardInputDirection = keyboardInputLocale.textDirection();
686 keyboard_mode = NullMode;
687 for (
int i = 0; i < 255; ++i) {
711 int baseKey = kbItem->
qtKey[0];
712 Qt::KeyboardModifiers keyMods = e->
modifiers();
713 ret << int(baseKey + keyMods);
715 for (
int i = 1; i < 8; ++i) {
716 Qt::KeyboardModifiers neededMods =
ModsTbl[i];
718 if (key && key != baseKey && ((keyMods & neededMods) == neededMods))
719 ret << int(key + (keyMods & ~neededMods));
726 void *
info,
bool grab)
728 Q_ASSERT(GetEventClass(event) == kEventClassKeyboard);
729 bool handled_event=
true;
730 UInt32 ekind = GetEventKind(event);
734 if (ekind == kEventRawKeyModifiersChanged) {
736 UInt32 modifiers = 0;
737 GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, 0,
738 sizeof(modifiers), 0, &modifiers);
744 if (currentContext && currentContext->
isComposing()) {
745 if (ekind == kEventRawKeyDown) {
754 if (currentContext && ekind == kEventRawKeyDown) {
761 Qt::KeyboardModifiers modifiers;
765 &handled_event) ==
false)
766 return handled_event;
777 #ifndef QT_MAC_USE_COCOA 783 if (!
qApp->activePopupWidget()
784 || (
qApp->activePopupWidget() && !text.
isEmpty())) {
790 CallNextEventHandler(er, event);
799 EventTime lastTime = GetEventTime(event);
801 EventRef releaseEvent = FindSpecificEventInQueue(GetMainEventQueue(),
803 (
void*)kEventRawKeyUp);
806 const EventTime releaseTime = GetEventTime(releaseEvent);
807 if (releaseTime < lastTime)
809 lastTime = releaseTime;
811 EventRef pressEvent = FindSpecificEventInQueue(GetMainEventQueue(),
813 (
void*)kEventRawKeyDown);
816 const EventTime pressTime = GetEventTime(pressEvent);
817 if (pressTime < lastTime)
819 lastTime = pressTime;
821 Qt::KeyboardModifiers compressMod;
822 int compressQtKey = 0;
825 &compressQtKey, &compressChar, &compressMod, 0)
831 bool stopCompression =
840 || (compressQtKey == 0)
844 if (compressMod == modifiers && !compressChar.
isNull() && !stopCompression) {
845 #ifdef DEBUG_KEY_BINDINGS 848 text += compressChar;
850 RemoveEventFromQueue(GetMainEventQueue(), releaseEvent);
851 RemoveEventFromQueue(GetMainEventQueue(), pressEvent);
853 #ifdef DEBUG_KEY_BINDINGS 854 qDebug(
"stoping compression..");
863 UInt32 macScanCode = 1;
864 UInt32 macVirtualKey = 0;
865 GetEventParameter(event, kEventParamKeyCode, typeUInt32, 0,
sizeof(macVirtualKey), 0, &macVirtualKey);
866 UInt32 macModifiers = 0;
867 GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, 0,
868 sizeof(macModifiers), 0, &macModifiers);
869 #ifdef QT_MAC_USE_COCOA 874 unsigned int *unicodeKey = (
unsigned int*)info;
875 if (*unicodeKey >= 0xf700 && *unicodeKey <= 0xf747)
881 qtKey, modifiers, text, ekind == kEventRawKeyRepeat, 0,
882 macScanCode, macVirtualKey, macModifiers
883 #ifdef QT_MAC_USE_COCOA
887 #ifdef QT_MAC_USE_COCOA 888 *unicodeKey = (
unsigned int)isAccepted;
891 return handled_event;
896 #
if defined(QT_MAC_USE_COCOA)
901 UInt32 macVirtualKey = 0;
902 GetEventParameter(event, kEventParamKeyCode, typeUInt32, 0,
sizeof(macVirtualKey), 0, &macVirtualKey);
903 if (updateKeyboard())
905 else if (keyLayout[macVirtualKey])
911 for (
int i = 0; i < 16; ++i) {
912 UniCharCount out_buffer_size = 0;
913 keyLayout[macVirtualKey]->
qtKey[i] = 0;
915 if (keyboard_mode == UnicodeMode) {
918 OSStatus err = UCKeyTranslate(keyboard_layout_format.unicode, macVirtualKey, kUCKeyActionDown, keyModifier,
919 keyboard_kind, 0, &keyboard_dead, buffer_size, &out_buffer_size, buffer);
920 if (err == noErr && out_buffer_size) {
921 const QChar unicode(buffer[0]);
925 keyLayout[macVirtualKey]->qtKey[i] = qtkey;
929 const QChar unicode(*((UniChar *)unicodeKey));
933 keyLayout[macVirtualKey]->qtKey[i] = qtkey;
940 uchar translatedChar = KeyTranslate(keyboard_layout_format.other, keyModifier | macVirtualKey, &keyboard_dead);
941 if (translatedChar) {
948 qtkey = unicode.unicode();
949 keyLayout[macVirtualKey]->qtKey[i] = qtkey;
954 #ifdef DEBUG_KEY_MAPS 955 qDebug(
"updateKeyMap for virtual key = 0x%02x!", (
uint)macVirtualKey);
956 for (
int i = 0; i < 16; ++i) {
957 qDebug(
" [%d] (%d,0x%02x,'%c')", i,
958 keyLayout[macVirtualKey]->
qtKey[i],
959 keyLayout[macVirtualKey]->
qtKey[i],
960 keyLayout[macVirtualKey]->
qtKey[i]);
970 quint32 nativeModifiers,
bool *isAccepted)
974 bool key_event =
true;
975 #if defined(QT3_SUPPORT) && !defined(QT_NO_SHORTCUT) 979 text, autorepeat,
qMax(1,
int(text.
length())),
980 nativeScanCode, nativeVirtualKey, nativeModifiers);
982 #if defined(DEBUG_KEY_BINDINGS) || defined(DEBUG_KEY_BINDINGS_MODIFIERS) 983 qDebug(
"KeyEvent: %s::%s consumed Accel: %s",
990 if (accel_ev.isAccepted()) {
991 #if defined(DEBUG_KEY_BINDINGS) || defined(DEBUG_KEY_BINDINGS_MODIFIERS) 992 qDebug(
"KeyEvent: %s::%s overrode Accel: %s",
1002 #endif // QT3_SUPPORT && !QT_NO_SHORTCUT 1004 #if defined(DEBUG_KEY_BINDINGS) || defined(DEBUG_KEY_BINDINGS_MODIFIERS) 1005 qDebug(
"KeyEvent: Sending %s to %s::%s: %s 0x%08x%s",
1010 autorepeat ?
" Repeat" :
"");
1013 nativeScanCode, nativeVirtualKey, nativeModifiers);
1016 *isAccepted = ke.isAccepted();
T qobject_cast(QObject *object)
static int qt_mac_get_mac_modifiers(Qt::KeyboardModifiers keys)
const struct __CFString * CFStringRef
The QKeyEvent class describes a key event.
bool isLetter() const
Returns true if the character is a letter (Letter_* categories); otherwise returns false...
static mach_timebase_info_data_t info
#define QT_END_NAMESPACE
This macro expands to.
QPointer< QWidget > widget
int digitValue() const
Returns the numeric value of the digit, or -1 if the character is not a digit.
const QChar at(int i) const
Returns the character at the given index position in the string.
static void keyEvent(KeyAction action, QWidget *widget, char ascii, Qt::KeyboardModifiers modifier=Qt::NoModifier, int delay=-1)
ushort unicode() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isNull() const
Returns true if the character is the Unicode character 0x0000 ('\0'); otherwise returns false...
int length() const
Returns the number of characters in this string.
Qt::KeyboardModifiers qt_mac_get_modifiers(int keys)
virtual bool isComposing() const =0
This function indicates whether InputMethodStart event had been sent to the current focus widget...
static QString toQString(CFStringRef cfstr)
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
static QApplicationPrivate * instance()
The QString class provides a Unicode character string.
void updateKeyMap(const MSG &msg)
bool isSymbol() const
Returns true if the character is a symbol (Symbol_* categories); otherwise returns false...
The QObject class is the base class of all Qt objects.
bool qt_sendSpontaneousEvent(QObject *obj, QEvent *event)
static qt_mac_enum_mapper qt_mac_keyboard_symbols[]
The QChar class provides a 16-bit Unicode character.
bool qt_mac_eat_unicode_key
static qt_mac_enum_mapper qt_mac_keyvkey_symbols[]
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Q_CORE_EXPORT void qDebug(const char *,...)
Qt::KeyboardModifiers modifiers() const
Returns the keyboard modifier flags that existed immediately after the event occurred.
QList< int > possibleKeys(QKeyEvent *e)
#define QT_BEGIN_NAMESPACE
This macro expands to.
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Q_CORE_EXPORT void qWarning(const char *,...)
static bool translateKeyEventInternal(EventHandlerCallRef er, EventRef keyEvent, int *qtKey, QChar *outChar, Qt::KeyboardModifiers *outModifiers, bool *outHandled)
static const char * data(const QByteArray &arr)
void setLastKeydownEvent(EventRef)
bool translateKeyEvent(QWidget *receiver, const MSG &msg, bool grab)
QChar toUpper() const
Returns the uppercase equivalent if the character is lowercase or titlecase; otherwise returns the ch...
QByteArray toLatin1() const Q_REQUIRED_RESULT
Returns a Latin-1 representation of the string as a QByteArray.
static int qt_mac_get_key(int modif, const QChar &key, int virtualKey)
struct OpaqueEventRef * EventRef
static qt_mac_enum_mapper qt_mac_private_unicode[]
const char * constData() const
Returns a pointer to the data stored in the byte array.
QString toUnicode(const QByteArray &) const
Converts a from the encoding of this codec to Unicode, and returns the result in a QString...
Q_CORE_EXPORT void qFatal(const char *,...)
static QLocale c()
Returns a QLocale object initialized to the "C" locale.
Type
This enum type defines the valid event types in Qt.
static void changeKeyboard()
Q_GUI_EXPORT void qt_mac_secure_keyboard(bool b)
void qt_mac_send_modifiers_changed(quint32 modifiers, QObject *object)
QString objectName() const
static QTextCodec * codecForName(const QByteArray &name)
Searches all installed QTextCodec objects and returns the one which best matches name; the match is c...
static const int buffer_size
char toLatin1() const
Returns the Latin-1 character equivalent to the QChar, or 0.
#define QT_USE_NAMESPACE
This macro expands to using QT_NAMESPACE if QT_NAMESPACE is defined and nothing otherwise.
static bool sendKeyEvent(QWidget *widget, bool grab, QEvent::Type type, int code, Qt::KeyboardModifiers modifiers, const QString &text, bool autorepeat, int count, quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers, bool *unusedExceptForCocoa=0)
struct OpaqueEventHandlerCallRef * EventHandlerCallRef
static qt_mac_enum_mapper qt_mac_modifier_symbols[]
The QInputContext class abstracts the input method dependent data and composing state.
The QTextCodec class provides conversions between text encodings.
static const Qt::KeyboardModifiers ModsTbl[]
const struct __CFArray * CFArrayRef
The QEvent class is the base class of all event classes.
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
quint32 nativeVirtualKey() const
Returns the native virtual key, or key sym of the key event.
bool isDigit() const
Returns true if the character is a decimal digit (Number_DecimalDigit); otherwise returns false...
static Boolean qt_KeyEventComparatorProc(EventRef inEvent, void *data)
virtual const QMetaObject * metaObject() const
Returns a pointer to the meta-object of this object.
#define QT_MAC_MAP_ENUM(x)