VirtualBox

Changeset 49121 in vbox for trunk/src


Ignore:
Timestamp:
Oct 15, 2013 3:12:35 PM (11 years ago)
Author:
vboxsync
Message:

FE/Qt: 6982: Runtime UI: Multi-screen auto-pilot feature: MacOS X: Using watchdog to determine the moment when Qt received new display geometry.

Location:
trunk/src/VBox/Frontends/VirtualBox/src/runtime
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp

    r49025 r49121  
    8383 * MacOS X: Application Services: Core Graphics: Display reconfiguration callback.
    8484 *
    85  * Notifies about @a display configuration change.
    86  * Corresponding change described by CoreGraphics @a flags.
    87  * Calls for corresponding UISession slots through @a pHandlerObject to handle this callback.
     85 * Notifies UISession about @a display configuration change.
     86 * Corresponding change described by Core Graphics @a flags.
     87 * Uses UISession @a pHandler to process this change.
    8888 *
    89  * @note Last argument (@a pHandlerObject) must always be valid pointer to UISession object.
    90  * @note Calls for UISession::sltHandleHostScreenCountChange() if display count was changed.
    91  * @note Calls for UISession::sltHandleHostScreenGeometryChange() if display mode was changed.
     89 * @note Last argument (@a pHandler) must always be valid pointer to UISession object.
     90 * @note Calls for UISession::sltHandleHostDisplayAboutToChange() slot if display configuration changed.
    9291 */
    93 void cgDisplayReconfigurationCallback(CGDirectDisplayID display, CGDisplayChangeSummaryFlags flags, void *pHandlerObject)
    94 {
     92void cgDisplayReconfigurationCallback(CGDirectDisplayID display, CGDisplayChangeSummaryFlags flags, void *pHandler)
     93{
     94    /* Which flags we are handling? */
     95    int iHandledFlags = kCGDisplayAddFlag     /* display added */
     96                      | kCGDisplayRemoveFlag  /* display removed */
     97                      | kCGDisplaySetModeFlag /* display mode changed */;
     98
    9599    /* Handle 'display-add' case: */
    96100    if (flags & kCGDisplayAddFlag)
    97     {
    98101        LogRelFlow(("UISession::cgDisplayReconfigurationCallback: Display added.\n"));
    99 
    100         /* Ask receiver to handle our callback, can't believe I'm using r_c here... */
    101         UISession *pReceiver = reinterpret_cast<UISession*>(pHandlerObject);
    102         QTimer::singleShot(0, pReceiver, SLOT(sltHandleHostScreenCountChange()));
    103     }
    104102    /* Handle 'display-remove' case: */
    105103    else if (flags & kCGDisplayRemoveFlag)
    106     {
    107104        LogRelFlow(("UISession::cgDisplayReconfigurationCallback: Display removed.\n"));
    108 
    109         /* Ask receiver to handle our callback, can't believe I'm using r_c here... */
    110         UISession *pReceiver = reinterpret_cast<UISession*>(pHandlerObject);
    111         QTimer::singleShot(0, pReceiver, SLOT(sltHandleHostScreenCountChange()));
    112     }
    113105    /* Handle 'mode-set' case: */
    114106    else if (flags & kCGDisplaySetModeFlag)
    115     {
    116107        LogRelFlow(("UISession::cgDisplayReconfigurationCallback: Display mode changed.\n"));
    117108
    118         /* Ask receiver to handle our callback, can't believe I'm using r_c here... */
    119         UISession *pReceiver = reinterpret_cast<UISession*>(pHandlerObject);
    120         QTimer::singleShot(0, pReceiver, SLOT(sltHandleHostScreenGeometryChange()));
    121     }
     109    /* Ask handler to process our callback: */
     110    if (flags & iHandledFlags)
     111        QTimer::singleShot(0, static_cast<UISession*>(pHandler),
     112                           SLOT(sltHandleHostDisplayAboutToChange()));
     113
    122114    Q_UNUSED(display);
    123115}
     
    136128    , m_alphaCursor(0)
    137129#endif /* Q_WS_WIN */
     130#ifdef Q_WS_MAC
     131    , m_pWatchdogDisplayChange(0)
     132#endif /* Q_WS_MAC */
    138133    /* Common flags: */
    139134    , m_fIsFirstTimeStarted(false)
     
    838833}
    839834
     835#ifdef RT_OS_DARWIN
     836/**
     837 * MacOS X: Restarts display-reconfiguration watchdog timer from the beginning.
     838 * @note Watchdog is trying to determine display reconfiguration in
     839 *       UISession::sltCheckIfHostDisplayChanged() slot every 500ms for 40 tries.
     840 */
     841void UISession::sltHandleHostDisplayAboutToChange()
     842{
     843    LogRelFlow(("UISession::sltHandleHostDisplayAboutToChange()\n"));
     844
     845    if (m_pWatchdogDisplayChange->isActive())
     846        m_pWatchdogDisplayChange->stop();
     847    m_pWatchdogDisplayChange->setProperty("tryNumber", 1);
     848    m_pWatchdogDisplayChange->start();
     849}
     850
     851/**
     852 * MacOS X: Determines display reconfiguration.
     853 * @note Calls for UISession::sltHandleHostScreenCountChange() if screen count changed.
     854 * @note Calls for UISession::sltHandleHostScreenGeometryChange() if screen geometry changed.
     855 */
     856void UISession::sltCheckIfHostDisplayChanged()
     857{
     858    LogRelFlow(("UISession::sltCheckIfHostDisplayChanged()\n"));
     859
     860    /* Acquire desktop wrapper: */
     861    QDesktopWidget *pDesktop = QApplication::desktop();
     862
     863    /* Check if display count changed: */
     864    if (pDesktop->screenCount() != m_screens.size())
     865    {
     866        /* Recache display data: */
     867        recacheDisplayData();
     868        /* Reset watchdog: */
     869        m_pWatchdogDisplayChange->setProperty("tryNumber", 0);
     870        /* Notify listeners about screen-count changed: */
     871        return sltHandleHostScreenCountChange();
     872    }
     873    else
     874    {
     875        /* Check if at least one display geometry changed: */
     876        for (int iScreenIndex = 0; iScreenIndex < pDesktop->screenCount(); ++iScreenIndex)
     877        {
     878            if (pDesktop->screenGeometry(iScreenIndex) != m_screens.at(iScreenIndex))
     879            {
     880                /* Recache display data: */
     881                recacheDisplayData();
     882                /* Reset watchdog: */
     883                m_pWatchdogDisplayChange->setProperty("tryNumber", 0);
     884                /* Notify listeners about screen-geometry changed: */
     885                return sltHandleHostScreenGeometryChange();
     886            }
     887        }
     888    }
     889
     890    /* Check if watchdog expired, restart if not: */
     891    int cTryNumber = m_pWatchdogDisplayChange->property("tryNumber").toInt();
     892    if (cTryNumber > 0 && cTryNumber < 40)
     893    {
     894        /* Restart watchdog again: */
     895        m_pWatchdogDisplayChange->setProperty("tryNumber", ++cTryNumber);
     896        m_pWatchdogDisplayChange->start();
     897    }
     898    else
     899    {
     900        /* Reset watchdog: */
     901        m_pWatchdogDisplayChange->setProperty("tryNumber", 0);
     902    }
     903}
     904#endif /* RT_OS_DARWIN */
     905
    840906void UISession::sltHandleHostScreenCountChange()
    841907{
     
    9421008    connect(this, SIGNAL(sigCloseRuntimeUI()), this, SLOT(sltCloseRuntimeUI()));
    9431009
     1010#ifdef Q_WS_MAC
     1011    /* Install native display reconfiguration callback: */
     1012    CGDisplayRegisterReconfigurationCallback(cgDisplayReconfigurationCallback, this);
     1013#else /* !Q_WS_MAC */
    9441014    /* Install Qt display reconfiguration callbacks: */
    9451015    connect(QApplication::desktop(), SIGNAL(screenCountChanged(int)),
     
    9491019    connect(QApplication::desktop(), SIGNAL(workAreaResized(int)),
    9501020            this, SLOT(sltHandleHostScreenGeometryChange()));
    951 
     1021#endif /* !Q_WS_MAC */
     1022}
     1023
     1024void UISession::prepareScreens()
     1025{
    9521026#ifdef Q_WS_MAC
    953     /* Install display reconfiguration callback: */
    954     CGDisplayRegisterReconfigurationCallback(cgDisplayReconfigurationCallback, this);
     1027    /* Recache display data: */
     1028    recacheDisplayData();
     1029    /* Prepare display-change watchdog: */
     1030    m_pWatchdogDisplayChange = new QTimer(this);
     1031    {
     1032        m_pWatchdogDisplayChange->setInterval(500);
     1033        m_pWatchdogDisplayChange->setSingleShot(true);
     1034        connect(m_pWatchdogDisplayChange, SIGNAL(timeout()),
     1035                this, SLOT(sltCheckIfHostDisplayChanged()));
     1036    }
    9551037#endif /* Q_WS_MAC */
    956 }
    957 
    958 void UISession::prepareScreens()
    959 {
     1038
    9601039    /* Get machine: */
    9611040    CMachine machine = m_session.GetMachine();
     
    15331612}
    15341613
     1614#ifdef Q_WS_MAC
     1615/** MacOS X: Recaches display-configuration data. */
     1616void UISession::recacheDisplayData()
     1617{
     1618    /* Recache display data: */
     1619    m_screens.clear();
     1620    QDesktopWidget *pDesktop = QApplication::desktop();
     1621    for (int iScreenIndex = 0; iScreenIndex < pDesktop->screenCount(); ++iScreenIndex)
     1622        m_screens << pDesktop->screenGeometry(iScreenIndex);
     1623}
     1624#endif /* Q_WS_MAC */
     1625
    15351626#ifdef VBOX_GUI_WITH_KEYS_RESET_HANDLER
    15361627/**
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.h

    r49025 r49121  
    234234    void sltGuestMonitorChange(KGuestMonitorChangedEventType changeType, ulong uScreenId, QRect screenGeo);
    235235
    236     /* Handlers: Host callback stuff: */
     236    /* Handlers: Display reconfiguration stuff: */
     237#ifdef RT_OS_DARWIN
     238    void sltHandleHostDisplayAboutToChange();
     239    void sltCheckIfHostDisplayChanged();
     240#endif /* RT_OS_DARWIN */
    237241    void sltHandleHostScreenCountChange();
    238242    void sltHandleHostScreenGeometryChange();
     
    270274    int countOfVisibleWindows();
    271275
     276#ifdef Q_WS_MAC
     277    /* Helper: Display reconfiguration stuff: */
     278    void recacheDisplayData();
     279#endif /* Q_WS_MAC */
     280
    272281#ifdef VBOX_GUI_WITH_KEYS_RESET_HANDLER
    273282    static void signalHandlerSIGUSR1(int sig, siginfo_t *pInfo, void *pSecret);
     
    293302    HCURSOR m_alphaCursor;
    294303#endif
     304#ifdef Q_WS_MAC
     305    /** @name MacOS X: Display reconfiguration variables.
     306     * @{ */
     307    /** MacOS X: Watchdog timer looking for display reconfiguration. */
     308    QTimer *m_pWatchdogDisplayChange;
     309    /** MacOS X: A list of display geometries we currently have. */
     310    QList<QRect> m_screens;
     311    /** @} */
     312#endif /* Q_WS_MAC */
    295313
    296314    /* Common flags: */
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette