author | Tom Schuster <evilpies@gmail.com> |
Tue, 22 Jul 2014 18:59:48 +0200 | |
changeset 195527 | 0ad20ad7b70ae9a679af9211c0f7b1b34532b3e3 |
parent 195526 | e740a64c284bb1f227ced27770296d0464944dbe |
child 195540 | 5683746bac22b4b198e6d049742d04b870dfb480 |
child 195580 | 24f3cfb76bf07f8453c24eeaf97622dbcc498d89 |
push id | 27184 |
push user | kwierso@gmail.com |
push date | Wed, 23 Jul 2014 00:39:18 +0000 |
treeherder | mozilla-central@0ad20ad7b70a [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | romaxa |
bugs | 1008732 |
milestone | 34.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/widget/qt/nsWindow.cpp +++ b/widget/qt/nsWindow.cpp @@ -84,18 +84,16 @@ using mozilla::gl::GLContext; // Qt static const int WHEEL_DELTA = 120; static bool gGlobalsInitialized = false; static bool sAltGrModifier = false; static void find_first_visible_parent(QWindow* aItem, QWindow*& aVisibleItem); static bool is_mouse_in_window (MozQWidget* aWindow, double aMouseX, double aMouseY); -static bool isContextMenuKeyEvent(const QKeyEvent *qe); -static void InitKeyEvent(WidgetKeyboardEvent &aEvent, QKeyEvent *aQEvent); nsWindow::nsWindow() { LOG(("%s [%p]\n", __PRETTY_FUNCTION__, (void *)this)); mIsTopLevel = false; mIsDestroyed = false; mIsShown = false; @@ -1073,128 +1071,99 @@ nsWindow::focusOutEvent(QFocusEvent* aEv } DispatchDeactivateEventOnTopLevelWindow(); LOGFOCUS(("Done with container focus out [%p]\n", (void *)this)); return nsEventStatus_eIgnore; } +static bool +IsContextMenuKeyEvent(const QKeyEvent* aQEvent) +{ + if (aQEvent->modifiers() & (Qt::ControlModifier | + Qt::AltModifier | + Qt::MetaModifier)) { + return false; + } + + bool isShift = aQEvent->modifiers() & Qt::ShiftModifier; + uint32_t keyCode = QtKeyCodeToDOMKeyCode(aQEvent->key()); + return (keyCode == NS_VK_F10 && isShift) || + (keyCode == NS_VK_CONTEXT_MENU && !isShift); +} + +static void +InitKeyEvent(WidgetKeyboardEvent& aEvent, QKeyEvent* aQEvent) +{ + aEvent.InitBasicModifiers(aQEvent->modifiers() & Qt::ControlModifier, + aQEvent->modifiers() & Qt::AltModifier, + aQEvent->modifiers() & Qt::ShiftModifier, + aQEvent->modifiers() & Qt::MetaModifier); + + aEvent.mIsRepeat = + (aEvent.message == NS_KEY_DOWN || aEvent.message == NS_KEY_PRESS) && + aQEvent->isAutoRepeat(); + aEvent.time = 0; + + if (sAltGrModifier) { + aEvent.modifiers |= (MODIFIER_CONTROL | MODIFIER_ALT); + } + + if (aQEvent->text().length() && aQEvent->text()[0].isPrint()) { + aEvent.charCode = (int32_t) aQEvent->text()[0].unicode(); + aEvent.keyCode = 0; + aEvent.mKeyNameIndex = KEY_NAME_INDEX_PrintableKey; + } else { + aEvent.charCode = 0; + aEvent.keyCode = QtKeyCodeToDOMKeyCode(aQEvent->key()); + aEvent.mKeyNameIndex = QtKeyCodeToDOMKeyNameIndex(aQEvent->key()); + } + + aEvent.mCodeNameIndex = ScanCodeToDOMCodeNameIndex(aQEvent->nativeScanCode()); + + // The transformations above and in qt for the keyval are not invertible + // so link to the QKeyEvent (which will vanish soon after return from the + // event callback) to give plugins access to hardware_keycode and state. + // (An XEvent would be nice but the QKeyEvent is good enough.) + aEvent.pluginEvent = (void *)aQEvent; +} + nsEventStatus nsWindow::keyPressEvent(QKeyEvent* aEvent) { LOGFOCUS(("OnKeyPressEvent [%p]\n", (void *)this)); // The user has done something. UserActivity(); if (aEvent->key() == Qt::Key_AltGr) { sAltGrModifier = true; } - CodeNameIndex codeNameIndex = - ScanCodeToDOMCodeNameIndex(aEvent->nativeScanCode()); - -#ifdef MOZ_X11 - // before we dispatch a key, check if it's the context menu key. + // Before we dispatch a key, check if it's the context menu key. // If so, send a context menu key event instead. - if (isContextMenuKeyEvent(aEvent)) { + if (IsContextMenuKeyEvent(aEvent)) { WidgetMouseEvent contextMenuEvent(true, NS_CONTEXTMENU, this, WidgetMouseEvent::eReal, WidgetMouseEvent::eContextMenuKey); - //keyEventToContextMenuEvent(&event, &contextMenuEvent); return DispatchEvent(&contextMenuEvent); } - uint32_t domCharCode = 0; + //:TODO: fix shortcuts hebrew for non X11, + //see Bug 562195##51 + uint32_t domKeyCode = QtKeyCodeToDOMKeyCode(aEvent->key()); - // get keymap and modifier map from the Xserver - Display *display = gfxQtPlatform::GetXDisplay(mWidget); - int x_min_keycode = 0, x_max_keycode = 0, xkeysyms_per_keycode; - XDisplayKeycodes(display, &x_min_keycode, &x_max_keycode); - XModifierKeymap *xmodmap = XGetModifierMapping(display); - if (!xmodmap) - return nsEventStatus_eIgnore; - - KeySym *xkeymap = XGetKeyboardMapping(display, x_min_keycode, x_max_keycode - x_min_keycode, - &xkeysyms_per_keycode); - if (!xkeymap) { - XFreeModifiermap(xmodmap); - return nsEventStatus_eIgnore; - } - - // create modifier masks - qint32 shift_mask = 0, shift_lock_mask = 0, caps_lock_mask = 0, num_lock_mask = 0; - - for (int i = 0; i < 8 * xmodmap->max_keypermod; ++i) { - qint32 maskbit = 1 << (i / xmodmap->max_keypermod); - KeyCode modkeycode = xmodmap->modifiermap[i]; - if (modkeycode == NoSymbol) { - continue; - } - - quint32 mapindex = (modkeycode - x_min_keycode) * xkeysyms_per_keycode; - for (int j = 0; j < xkeysyms_per_keycode; ++j) { - KeySym modkeysym = xkeymap[mapindex + j]; - switch (modkeysym) { - case XK_Num_Lock: - num_lock_mask |= maskbit; - break; - case XK_Caps_Lock: - caps_lock_mask |= maskbit; - break; - case XK_Shift_Lock: - shift_lock_mask |= maskbit; - break; - case XK_Shift_L: - case XK_Shift_R: - shift_mask |= maskbit; - break; - } - } - } - // indicate whether is down or not - bool shift_state = ((shift_mask & aEvent->nativeModifiers()) != 0) ^ - (bool)(shift_lock_mask & aEvent->nativeModifiers()); - bool capslock_state = (bool)(caps_lock_mask & aEvent->nativeModifiers()); - - // try to find a keysym that we can translate to a DOMKeyCode - // this is needed because some of Qt's keycodes cannot be translated - // TODO: use US keyboard keymap instead of localised keymap - if (!domKeyCode && - aEvent->nativeScanCode() >= (quint32)x_min_keycode && - aEvent->nativeScanCode() <= (quint32)x_max_keycode) { - int index = (aEvent->nativeScanCode() - x_min_keycode) * xkeysyms_per_keycode; - for(int i = 0; (i < xkeysyms_per_keycode) && (domKeyCode == (quint32)NoSymbol); ++i) { - domKeyCode = QtKeyCodeToDOMKeyCode(xkeymap[index + i]); - } - } - - // store character in domCharCode - if (aEvent->text().length() && aEvent->text()[0].isPrint()) - domCharCode = (int32_t) aEvent->text()[0].unicode(); - - KeyNameIndex keyNameIndex = - domCharCode ? KEY_NAME_INDEX_PrintableKey : - QtKeyCodeToDOMKeyNameIndex(aEvent->key()); - - // If the key isn't autorepeat, we need to send the initial down event if (!aEvent->isAutoRepeat() && !IsKeyDown(domKeyCode)) { - // send the key down event - SetKeyDownFlag(domKeyCode); WidgetKeyboardEvent downEvent(true, NS_KEY_DOWN, this); InitKeyEvent(downEvent, aEvent); - downEvent.keyCode = domKeyCode; - downEvent.mKeyNameIndex = keyNameIndex; - downEvent.mCodeNameIndex = codeNameIndex; - nsEventStatus status = DispatchEvent(&downEvent); // DispatchEvent can Destroy us (bug 378273) if (MOZ_UNLIKELY(mIsDestroyed)) { qWarning() << "Returning[" << __LINE__ << "]: " << "Window destroyed"; return status; } @@ -1209,17 +1178,16 @@ nsWindow::keyPressEvent(QKeyEvent* aEven // we instead selectively include (as per MSDN spec // ( http://msdn.microsoft.com/en-us/library/system.windows.forms.control.keypress%28VS.71%29.aspx ); // no official spec covers KeyPress events). if (aEvent->key() == Qt::Key_Shift || aEvent->key() == Qt::Key_Control || aEvent->key() == Qt::Key_Meta || aEvent->key() == Qt::Key_Alt || aEvent->key() == Qt::Key_AltGr) { - return nsEventStatus_eIgnore; } // Look for specialized app-command keys switch (aEvent->key()) { case Qt::Key_Back: return DispatchCommandEvent(nsGkAtoms::Back); case Qt::Key_Forward: @@ -1253,269 +1221,41 @@ nsWindow::keyPressEvent(QKeyEvent* aEven return DispatchContentCommandEvent(NS_CONTENT_COMMAND_REDO); } if (aEvent->nativeVirtualKey() == 0xff65) { return DispatchContentCommandEvent(NS_CONTENT_COMMAND_UNDO); } WidgetKeyboardEvent event(true, NS_KEY_PRESS, this); InitKeyEvent(event, aEvent); - - // If there is no charcode attainable from the text, try to - // generate it from the keycode. Check shift state for case - // Also replace the charcode if ControlModifier is the only - // pressed Modifier - if ((!domCharCode) && - (QGuiApplication::keyboardModifiers() & - (Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier))) { - - // get a character from X11 key map - KeySym keysym = aEvent->nativeVirtualKey(); - if (keysym) { - domCharCode = (uint32_t) keysym2ucs(keysym); - if (domCharCode == -1 || !QChar((quint32)domCharCode).isPrint()) { - domCharCode = 0; - } - } - - // if Ctrl is pressed and domCharCode is not a ASCII character - if (domCharCode > 0xFF && (QGuiApplication::keyboardModifiers() & Qt::ControlModifier)) { - // replace Unicode character - int index = (aEvent->nativeScanCode() - x_min_keycode) * xkeysyms_per_keycode; - for (int i = 0; i < xkeysyms_per_keycode; ++i) { - if (xkeymap[index + i] <= 0xFF && !shift_state) { - domCharCode = (uint32_t) QChar::toLower((uint) xkeymap[index + i]); - break; - } - } - } - - } else { // The key event should cause a character input. - // At that time, we need to reset the modifiers - // because nsEditor will not accept a key event - // for text input if one or more modifiers are set. - event.modifiers &= ~(MODIFIER_CONTROL | - MODIFIER_ALT | - MODIFIER_META); - } - - KeySym keysym = NoSymbol; - int index = (aEvent->nativeScanCode() - x_min_keycode) * xkeysyms_per_keycode; - for (int i = 0; i < xkeysyms_per_keycode; ++i) { - if (xkeymap[index + i] == aEvent->nativeVirtualKey()) { - if ((i % 2) == 0) { // shifted char - keysym = xkeymap[index + i + 1]; - break; - } else { // unshifted char - keysym = xkeymap[index + i - 1]; - break; - } - } - if (xkeysyms_per_keycode - 1 == i) { - qWarning() << "Symbol '" << aEvent->nativeVirtualKey() << "' not found"; - } - } - QChar unshiftedChar(domCharCode); - long ucs = keysym2ucs(keysym); - ucs = ucs == -1 ? 0 : ucs; - QChar shiftedChar((uint)ucs); - - // append alternativeCharCodes if modifier is pressed - // append an additional alternativeCharCodes if domCharCode is not a Latin character - // and if one of these modifiers is pressed (i.e. Ctrl, Alt, Meta) - if (domCharCode && - (QGuiApplication::keyboardModifiers() & - (Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier))) { - - event.charCode = domCharCode; - event.keyCode = 0; - AlternativeCharCode altCharCode(0, 0); - // if character has a lower and upper representation - if ((unshiftedChar.isUpper() || unshiftedChar.isLower()) && - unshiftedChar.toLower() == shiftedChar.toLower()) { - if (shift_state ^ capslock_state) { - altCharCode.mUnshiftedCharCode = (uint32_t) QChar::toUpper((uint)domCharCode); - altCharCode.mShiftedCharCode = (uint32_t) QChar::toLower((uint)domCharCode); - } else { - altCharCode.mUnshiftedCharCode = (uint32_t) QChar::toLower((uint)domCharCode); - altCharCode.mShiftedCharCode = (uint32_t) QChar::toUpper((uint)domCharCode); - } - } else { - altCharCode.mUnshiftedCharCode = (uint32_t) unshiftedChar.unicode(); - altCharCode.mShiftedCharCode = (uint32_t) shiftedChar.unicode(); - } - - // append alternative char code to event - if ((altCharCode.mUnshiftedCharCode && altCharCode.mUnshiftedCharCode != domCharCode) || - (altCharCode.mShiftedCharCode && altCharCode.mShiftedCharCode != domCharCode)) { - event.alternativeCharCodes.AppendElement(altCharCode); - } - - // check if the alternative char codes are latin-1 - if (altCharCode.mUnshiftedCharCode > 0xFF || altCharCode.mShiftedCharCode > 0xFF) { - altCharCode.mUnshiftedCharCode = altCharCode.mShiftedCharCode = 0; - - // find latin char for keycode - KeySym keysym = NoSymbol; - int index = (aEvent->nativeScanCode() - x_min_keycode) * xkeysyms_per_keycode; - // find first shifted and unshifted Latin-Char in XKeyMap - for (int i = 0; i < xkeysyms_per_keycode; ++i) { - keysym = xkeymap[index + i]; - if (keysym && keysym <= 0xFF) { - if ((shift_state && (i % 2 == 1)) || - (!shift_state && (i % 2 == 0))) { - altCharCode.mUnshiftedCharCode = altCharCode.mUnshiftedCharCode ? - altCharCode.mUnshiftedCharCode : - keysym; - } else { - altCharCode.mShiftedCharCode = altCharCode.mShiftedCharCode ? - altCharCode.mShiftedCharCode : - keysym; - } - if (altCharCode.mUnshiftedCharCode && altCharCode.mShiftedCharCode) { - break; - } - } - } - - if (altCharCode.mUnshiftedCharCode || altCharCode.mShiftedCharCode) { - event.alternativeCharCodes.AppendElement(altCharCode); - } - } - } else { - event.charCode = domCharCode; - } - - if (xmodmap) { - XFreeModifiermap(xmodmap); - } - if (xkeymap) { - XFree(xkeymap); - } - - event.keyCode = domCharCode ? 0 : domKeyCode; - event.mKeyNameIndex = keyNameIndex; - event.mCodeNameIndex = codeNameIndex; - // send the key press event + // Seend the key press event return DispatchEvent(&event); -#else - - //:TODO: fix shortcuts hebrew for non X11, - //see Bug 562195##51 - - // before we dispatch a key, check if it's the context menu key. - // If so, send a context menu key event instead. - if (isContextMenuKeyEvent(aEvent)) { - WidgetMouseEvent contextMenuEvent(true, NS_CONTEXTMENU, this, - WidgetMouseEvent::eReal, - WidgetMouseEvent::eContextMenuKey); - //keyEventToContextMenuEvent(&event, &contextMenuEvent); - return DispatchEvent(&contextMenuEvent); - } - - uint32_t domCharCode = 0; - uint32_t domKeyCode = QtKeyCodeToDOMKeyCode(aEvent->key()); - - if (aEvent->text().length() && aEvent->text()[0].isPrint()) { - domCharCode = (int32_t) aEvent->text()[0].unicode(); - } - - KeyNameIndex keyNameIndex = - domCharCode ? KEY_NAME_INDEX_PrintableKey : - QtKeyCodeToDOMKeyNameIndex(aEvent->key()); - - // If the key isn't autorepeat, we need to send the initial down event - if (!aEvent->isAutoRepeat() && !IsKeyDown(domKeyCode)) { - // send the key down event - - SetKeyDownFlag(domKeyCode); - - WidgetKeyboardEvent downEvent(true, NS_KEY_DOWN, this); - InitKeyEvent(downEvent, aEvent); - - downEvent.keyCode = domKeyCode; - downEvent.mKeyNameIndex = keyNameIndex; - downEvent.mCodeNameIndex = codeNameIndex; - - nsEventStatus status = DispatchEvent(&downEvent); - - // If prevent default on keydown, don't dispatch keypress event - if (status == nsEventStatus_eConsumeNoDefault) { - return nsEventStatus_eConsumeNoDefault; - } - } - - WidgetKeyboardEvent event(true, NS_KEY_PRESS, this); - InitKeyEvent(event, aEvent); - - event.charCode = domCharCode; - - event.keyCode = domCharCode ? 0 : domKeyCode; - event.mKeyNameIndex = keyNameIndex; - event.mCodeNameIndex = codeNameIndex; - - // send the key press event - return DispatchEvent(&event); -#endif } nsEventStatus nsWindow::keyReleaseEvent(QKeyEvent* aEvent) { LOGFOCUS(("OnKeyReleaseEvent [%p]\n", (void *)this)); // The user has done something. UserActivity(); - if (isContextMenuKeyEvent(aEvent)) { + if (IsContextMenuKeyEvent(aEvent)) { // er, what do we do here? DoDefault or NoDefault? return nsEventStatus_eConsumeDoDefault; } - uint32_t domKeyCode = QtKeyCodeToDOMKeyCode(aEvent->key()); - -#ifdef MOZ_X11 - if (!domKeyCode) { - // get keymap from the Xserver - Display *display = gfxQtPlatform::GetXDisplay(mWidget); - int x_min_keycode = 0, x_max_keycode = 0, xkeysyms_per_keycode; - XDisplayKeycodes(display, &x_min_keycode, &x_max_keycode); - KeySym *xkeymap = XGetKeyboardMapping(display, x_min_keycode, x_max_keycode - x_min_keycode, - &xkeysyms_per_keycode); - - if (aEvent->nativeScanCode() >= (quint32)x_min_keycode && - aEvent->nativeScanCode() <= (quint32)x_max_keycode) { - int index = (aEvent->nativeScanCode() - x_min_keycode) * xkeysyms_per_keycode; - for(int i = 0; (i < xkeysyms_per_keycode) && (domKeyCode == (quint32)NoSymbol); ++i) { - domKeyCode = QtKeyCodeToDOMKeyCode(xkeymap[index + i]); - } - } - - if (xkeymap) { - XFree(xkeymap); - } - } -#endif // MOZ_X11 - // send the key event as a key up event WidgetKeyboardEvent event(true, NS_KEY_UP, this); InitKeyEvent(event, aEvent); if (aEvent->key() == Qt::Key_AltGr) { sAltGrModifier = false; } - event.keyCode = domKeyCode; - event.mKeyNameIndex = - (aEvent->text().length() && aEvent->text()[0].isPrint()) ? - KEY_NAME_INDEX_PrintableKey : - QtKeyCodeToDOMKeyNameIndex(aEvent->key()); - event.mCodeNameIndex = - ScanCodeToDOMCodeNameIndex(aEvent->nativeScanCode()); - // unset the key down flag ClearKeyDownFlag(event.keyCode); return DispatchEvent(&event); } nsEventStatus nsWindow::wheelEvent(QWheelEvent* aEvent) @@ -1634,52 +1374,16 @@ nsWindow::DispatchResizeEvent(nsIntRect if (mWidgetListener && mWidgetListener->WindowResized(this, aRect.width, aRect.height)) { aStatus = nsEventStatus_eConsumeNoDefault; } } ///////////////////////////////////// OLD GECKO ECENTS need to Sort /////////////////// -/* static */ bool -isContextMenuKeyEvent(const QKeyEvent *qe) -{ - uint32_t kc = QtKeyCodeToDOMKeyCode(qe->key()); - if (qe->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier)) { - return false; - } - - bool isShift = qe->modifiers() & Qt::ShiftModifier; - return (kc == NS_VK_F10 && isShift) || - (kc == NS_VK_CONTEXT_MENU && !isShift); -} - -/* static */void -InitKeyEvent(WidgetKeyboardEvent &aEvent, QKeyEvent *aQEvent) -{ - aEvent.InitBasicModifiers(aQEvent->modifiers() & Qt::ControlModifier, - aQEvent->modifiers() & Qt::AltModifier, - aQEvent->modifiers() & Qt::ShiftModifier, - aQEvent->modifiers() & Qt::MetaModifier); - aEvent.mIsRepeat = - (aEvent.message == NS_KEY_DOWN || aEvent.message == NS_KEY_PRESS) && - aQEvent->isAutoRepeat(); - aEvent.time = 0; - - if (sAltGrModifier) { - aEvent.modifiers |= (MODIFIER_CONTROL | MODIFIER_ALT); - } - - // The transformations above and in qt for the keyval are not invertible - // so link to the QKeyEvent (which will vanish soon after return from the - // event callback) to give plugins access to hardware_keycode and state. - // (An XEvent would be nice but the QKeyEvent is good enough.) - aEvent.pluginEvent = (void *)aQEvent; -} - NS_IMPL_ISUPPORTS_INHERITED(nsWindow, nsBaseWidget, nsISupportsWeakReference) void nsWindow::ClearCachedResources() { if (mLayerManager &&