Changeset 59043 in vbox for trunk/src/VBox/Frontends/VirtualBox
- Timestamp:
- Dec 7, 2015 7:08:56 PM (9 years ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox/src/widgets
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIHostComboEditor.cpp
r59042 r59043 42 42 43 43 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */ 44 45 /* Qt includes: */ 46 #ifdef Q_WS_WIN 47 # if QT_VERSION >= 0x050000 48 # include <QAbstractNativeEventFilter> 49 # endif /* QT_VERSION >= 0x050000 */ 50 #endif /* Q_WS_WIN */ 44 51 45 52 /* GUI includes: */ … … 75 82 76 83 84 #ifdef Q_WS_WIN 85 # if QT_VERSION >= 0x050000 86 /** QAbstractNativeEventFilter extension 87 * allowing to handle native Windows (MSG) events. 88 * Why do we need it? It's because Qt5 have unhandled 89 * well .. let's call it 'a bug' about native keyboard events 90 * which come to top-level widget (window) instead of focused sub-widget 91 * which actually supposed to get them. The funny thing is that target of 92 * those events (MSG::hwnd) is indeed top-level widget, not the sub-widget 93 * we expect, so that's probably the reason Qt devs haven't fixed that bug. */ 94 class WinEventFilter : public QAbstractNativeEventFilter 95 { 96 public: 97 98 /** Constructor which takes the passed @a pParent to redirect events to. */ 99 WinEventFilter(UIHostComboEditorPrivate *pParent) 100 : m_pParent(pParent) 101 {} 102 103 /** Handles all native events. */ 104 bool nativeEventFilter(const QByteArray &eventType, void *pMessage, long *pResult) 105 { 106 /* Redirect event to parent: */ 107 return m_pParent->nativeEvent(eventType, pMessage, pResult); 108 } 109 110 private: 111 112 /** Holds the passed parent reference. */ 113 UIHostComboEditorPrivate *m_pParent; 114 }; 115 # endif /* QT_VERSION >= 0x050000 */ 116 #endif /* Q_WS_WIN */ 117 118 77 119 /********************************************************************************************************************************* 78 120 * Namespace UINativeHotKey implementation. * … … 428 470 , m_fStartNewSequence(true) 429 471 #ifdef Q_WS_WIN 472 # if QT_VERSION >= 0x050000 473 , m_pWinEventFilter(0) 474 # endif /* QT_VERSION >= 0x050000 */ 430 475 , m_pAltGrMonitor(0) 431 476 #endif /* Q_WS_WIN */ … … 443 488 444 489 #if defined(Q_WS_MAC) 445 446 447 490 m_uDarwinKeyModifiers = 0; 491 UICocoaApplication::instance()->registerForNativeEvents(RT_BIT_32(10) | RT_BIT_32(11) | RT_BIT_32(12) /* NSKeyDown | NSKeyUp | | NSFlagsChanged */, UIHostComboEditorPrivate::darwinEventHandlerProc, this); 492 ::DarwinGrabKeyboard(false /* just modifiers */); 448 493 #elif defined(Q_WS_WIN) 494 # if QT_VERSION >= 0x050000 495 /* Prepare Windows event filter: */ 496 m_pWinEventFilter = new WinEventFilter(this); 497 qApp->installNativeEventFilter(m_pWinEventFilter); 498 # endif /* QT_VERSION >= 0x050000 */ 449 499 /* Prepare AltGR monitor: */ 450 500 m_pAltGrMonitor = new WinAltGrMonitor; 451 501 #elif defined(Q_WS_X11) 452 453 502 /* Initialize the X keyboard subsystem: */ 503 initMappedX11Keyboard(QX11Info::display(), vboxGlobal().settings().publicProperty("GUI/RemapScancodes")); 454 504 #endif /* Q_WS_X11 */ 455 505 } … … 464 514 delete m_pAltGrMonitor; 465 515 m_pAltGrMonitor = 0; 516 # if QT_VERSION >= 0x050000 517 /* Cleanup Windows event filter: */ 518 qApp->removeNativeEventFilter(m_pWinEventFilter); 519 delete m_pWinEventFilter; 520 m_pWinEventFilter = 0; 521 # endif /* QT_VERSION >= 0x050000 */ 466 522 #endif /* Q_WS_WIN */ 467 523 } … … 512 568 bool UIHostComboEditorPrivate::nativeEvent(const QByteArray &eventType, void *pMessage, long *pResult) 513 569 { 514 # if defined(Q_WS_X11) 515 # pragma GCC diagnostic push 516 # pragma GCC diagnostic ignored "-Wdeprecated-declarations" 517 518 /* Make sure it's generic XCB event: */ 519 if (eventType != "xcb_generic_event_t") 570 # if defined(Q_WS_WIN) 571 572 /* Make sure it's generic MSG event: */ 573 if (eventType != "windows_generic_MSG") 520 574 return QLineEdit::nativeEvent(eventType, pMessage, pResult); 521 xcb_generic_event_t *pEvent = static_cast<xcb_generic_event_t*>(pMessage);522 523 /* Check if some XCBevent should be filtered out.575 MSG *pEvent = static_cast<MSG*>(pMessage); 576 577 /* Check if some MSG event should be filtered out. 524 578 * Returning @c true means filtering-out, 525 579 * Returning @c false means passing event to Qt. */ 526 switch (pEvent-> response_type & ~0x80)580 switch (pEvent->message) 527 581 { 528 582 /* Watch for key-events: */ 529 case XCB_KEY_PRESS:530 case XCB_KEY_RELEASE:531 {532 /* Parse key-event: */533 xcb_key_press_event_t *pKeyEvent = static_cast<xcb_key_press_event_t*>(pMessage);534 const KeySym ks = ::XKeycodeToKeysym(QX11Info::display(), pKeyEvent->detail, 0);535 const int iKeySym = static_cast<const int>(ks);536 537 /* Handle key-event: */538 return processKeyEvent(iKeySym, (pEvent->response_type & ~0x80) == XCB_KEY_PRESS);539 }540 default:541 break;542 }543 544 # pragma GCC diagnostic pop545 # endif /* Q_WS_X11 */546 547 /* Call to base-class: */548 return QLineEdit::nativeEvent(eventType, pMessage, pResult);549 }550 551 #else /* QT_VERSION < 0x050000 */552 553 # if defined(Q_WS_MAC)554 555 /* static */556 bool UIHostComboEditorPrivate::darwinEventHandlerProc(const void *pvCocoaEvent, const void *pvCarbonEvent, void *pvUser)557 {558 UIHostComboEditorPrivate *pEditor = static_cast<UIHostComboEditorPrivate*>(pvUser);559 EventRef inEvent = (EventRef)pvCarbonEvent;560 UInt32 EventClass = ::GetEventClass(inEvent);561 if (EventClass == kEventClassKeyboard)562 return pEditor->darwinKeyboardEvent(pvCocoaEvent, inEvent);563 return false;564 }565 566 bool UIHostComboEditorPrivate::darwinKeyboardEvent(const void *pvCocoaEvent, EventRef inEvent)567 {568 /* Ignore key changes unless we're the focus widget: */569 if (!hasFocus())570 return false;571 572 UInt32 eventKind = ::GetEventKind(inEvent);573 switch (eventKind)574 {575 //case kEventRawKeyDown:576 //case kEventRawKeyUp:577 //case kEventRawKeyRepeat:578 case kEventRawKeyModifiersChanged:579 {580 /* Get modifier mask: */581 UInt32 modifierMask = 0;582 ::GetEventParameter(inEvent, kEventParamKeyModifiers, typeUInt32, NULL,583 sizeof(modifierMask), NULL, &modifierMask);584 modifierMask = ::DarwinAdjustModifierMask(modifierMask, pvCocoaEvent);585 UInt32 changed = m_uDarwinKeyModifiers ^ modifierMask;586 587 if (!changed)588 break;589 590 /* Convert to keycode: */591 unsigned uKeyCode = ::DarwinModifierMaskToDarwinKeycode(changed);592 593 if (!uKeyCode || uKeyCode == ~0U)594 return false;595 596 /* Process the key event: */597 if (processKeyEvent(uKeyCode, changed & modifierMask))598 {599 /* Save the new modifier mask state. */600 m_uDarwinKeyModifiers = modifierMask;601 return true;602 }603 break;604 }605 default:606 break;607 }608 return false;609 }610 611 # elif defined(Q_WS_WIN)612 613 bool UIHostComboEditorPrivate::winEvent(MSG *pMsg, long* /* pResult */)614 {615 switch (pMsg->message)616 {617 583 case WM_KEYDOWN: 618 584 case WM_SYSKEYDOWN: … … 620 586 case WM_SYSKEYUP: 621 587 { 622 /* Get key-code: */623 int iKeyCode = UINativeHotKey::distinguishModifierVKey((int)p Msg->wParam, (int)pMsg->lParam);624 unsigned iDownScanCode = (p Msg->lParam >> 16) & 0x7F;625 bool fPressed = !(pMsg->lParam & 0x80000000);626 bool fExtended = pMsg->lParam & 0x1000000;588 /* Parse key-event: */ 589 int iKeyCode = UINativeHotKey::distinguishModifierVKey((int)pEvent->wParam, (int)pEvent->lParam); 590 unsigned iDownScanCode = (pEvent->lParam >> 16) & 0x7F; 591 const bool fPressed = !(pEvent->lParam & 0x80000000); 592 const bool fExtended = pEvent->lParam & 0x1000000; 627 593 628 594 /* If present - why not just assert this? */ … … 643 609 } 644 610 611 /* Handle key-event: */ 612 return processKeyEvent(iKeyCode, (pEvent->message == WM_KEYDOWN || pEvent->message == WM_SYSKEYDOWN)); 613 } 614 default: 615 break; 616 } 617 618 # elif defined(Q_WS_X11) 619 # pragma GCC diagnostic push 620 # pragma GCC diagnostic ignored "-Wdeprecated-declarations" 621 622 /* Make sure it's generic XCB event: */ 623 if (eventType != "xcb_generic_event_t") 624 return QLineEdit::nativeEvent(eventType, pMessage, pResult); 625 xcb_generic_event_t *pEvent = static_cast<xcb_generic_event_t*>(pMessage); 626 627 /* Check if some XCB event should be filtered out. 628 * Returning @c true means filtering-out, 629 * Returning @c false means passing event to Qt. */ 630 switch (pEvent->response_type & ~0x80) 631 { 632 /* Watch for key-events: */ 633 case XCB_KEY_PRESS: 634 case XCB_KEY_RELEASE: 635 { 636 /* Parse key-event: */ 637 xcb_key_press_event_t *pKeyEvent = static_cast<xcb_key_press_event_t*>(pMessage); 638 const KeySym ks = ::XKeycodeToKeysym(QX11Info::display(), pKeyEvent->detail, 0); 639 const int iKeySym = static_cast<const int>(ks); 640 641 /* Handle key-event: */ 642 return processKeyEvent(iKeySym, (pEvent->response_type & ~0x80) == XCB_KEY_PRESS); 643 } 644 default: 645 break; 646 } 647 648 # pragma GCC diagnostic pop 649 # else 650 651 # warning "port me!" 652 653 # endif 654 655 /* Call to base-class: */ 656 return QLineEdit::nativeEvent(eventType, pMessage, pResult); 657 } 658 659 #else /* QT_VERSION < 0x050000 */ 660 661 # if defined(Q_WS_MAC) 662 663 /* static */ 664 bool UIHostComboEditorPrivate::darwinEventHandlerProc(const void *pvCocoaEvent, const void *pvCarbonEvent, void *pvUser) 665 { 666 UIHostComboEditorPrivate *pEditor = static_cast<UIHostComboEditorPrivate*>(pvUser); 667 EventRef inEvent = (EventRef)pvCarbonEvent; 668 UInt32 EventClass = ::GetEventClass(inEvent); 669 if (EventClass == kEventClassKeyboard) 670 return pEditor->darwinKeyboardEvent(pvCocoaEvent, inEvent); 671 return false; 672 } 673 674 bool UIHostComboEditorPrivate::darwinKeyboardEvent(const void *pvCocoaEvent, EventRef inEvent) 675 { 676 /* Ignore key changes unless we're the focus widget: */ 677 if (!hasFocus()) 678 return false; 679 680 UInt32 eventKind = ::GetEventKind(inEvent); 681 switch (eventKind) 682 { 683 //case kEventRawKeyDown: 684 //case kEventRawKeyUp: 685 //case kEventRawKeyRepeat: 686 case kEventRawKeyModifiersChanged: 687 { 688 /* Get modifier mask: */ 689 UInt32 modifierMask = 0; 690 ::GetEventParameter(inEvent, kEventParamKeyModifiers, typeUInt32, NULL, 691 sizeof(modifierMask), NULL, &modifierMask); 692 modifierMask = ::DarwinAdjustModifierMask(modifierMask, pvCocoaEvent); 693 UInt32 changed = m_uDarwinKeyModifiers ^ modifierMask; 694 695 if (!changed) 696 break; 697 698 /* Convert to keycode: */ 699 unsigned uKeyCode = ::DarwinModifierMaskToDarwinKeycode(changed); 700 701 if (!uKeyCode || uKeyCode == ~0U) 702 return false; 703 704 /* Process the key event: */ 705 if (processKeyEvent(uKeyCode, changed & modifierMask)) 706 { 707 /* Save the new modifier mask state. */ 708 m_uDarwinKeyModifiers = modifierMask; 709 return true; 710 } 711 break; 712 } 713 default: 714 break; 715 } 716 return false; 717 } 718 719 # elif defined(Q_WS_WIN) 720 721 bool UIHostComboEditorPrivate::winEvent(MSG *pMsg, long* /* pResult */) 722 { 723 switch (pMsg->message) 724 { 725 case WM_KEYDOWN: 726 case WM_SYSKEYDOWN: 727 case WM_KEYUP: 728 case WM_SYSKEYUP: 729 { 730 /* Get key-code: */ 731 int iKeyCode = UINativeHotKey::distinguishModifierVKey((int)pMsg->wParam, (int)pMsg->lParam); 732 unsigned iDownScanCode = (pMsg->lParam >> 16) & 0x7F; 733 bool fPressed = !(pMsg->lParam & 0x80000000); 734 bool fExtended = pMsg->lParam & 0x1000000; 735 736 /* If present - why not just assert this? */ 737 if (m_pAltGrMonitor) 738 { 739 /* Update AltGR monitor state from key-event: */ 740 m_pAltGrMonitor->updateStateFromKeyEvent(iDownScanCode, fPressed, fExtended); 741 /* And release left Ctrl key early (if required): */ 742 if (m_pAltGrMonitor->isLeftControlReleaseNeeded()) 743 { 744 m_pressedKeys.remove(VK_LCONTROL); 745 m_shownKeys.remove(VK_LCONTROL); 746 } 747 /* Fake LCtrl release events can also end up in the released 748 * key set. Detect them on the immediately following RAlt up. */ 749 if (!m_pressedKeys.contains(VK_LCONTROL)) 750 m_releasedKeys.remove(VK_LCONTROL); 751 } 752 645 753 /* Process the key event: */ 646 754 return processKeyEvent(iKeyCode, pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN); -
trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIHostComboEditor.h
r59042 r59043 32 32 class UIHostComboEditorPrivate; 33 33 #ifdef Q_WS_WIN 34 # if QT_VERSION >= 0x050000 35 class WinEventFilter; 36 # endif /* QT_VERSION >= 0x050000 */ 34 37 class WinAltGrMonitor; 35 38 #endif /* Q_WS_WIN */ … … 187 190 uint32_t m_uDarwinKeyModifiers; 188 191 #elif defined(Q_WS_WIN) 192 # if QT_VERSION >= 0x050000 193 /** Win: Holds the native event filter instance. */ 194 WinEventFilter *m_pWinEventFilter; 195 /** Win: Allows the native event filter to 196 * redirect events directly to nativeEvent handler. */ 197 friend class WinEventFilter; 198 # endif /* QT_VERSION >= 0x050000 */ 189 199 /** Win: Holds the object monitoring key event 190 200 * stream for problematic AltGr events. */
Note:
See TracChangeset
for help on using the changeset viewer.