void UIMultiScreenLayout::update()
{
    LogRelFlow(("UIMultiScreenLayout::update: Started...\n"));

    /* Clear screen-map initially: */
    m_screenMap.clear();

    /* Make a pool of available host screens: */
    QList<int> availableScreens;
    for (int i = 0; i < m_cHostScreens; ++i)
        availableScreens << i;

    /* Load all combinations stored in the settings file.
     * We have to make sure they are valid, which means there have to be unique combinations
     * and all guests screens need there own host screen. */
    CDisplay display = m_pMachineLogic->session().GetConsole().GetDisplay();
    bool fShouldWeAutoMountGuestScreens = gEDataManager->autoMountGuestScreensEnabled(vboxGlobal().managedVMUuid());
    LogRel(("GUI: UIMultiScreenLayout::update: GUI/AutomountGuestScreens is %s\n", fShouldWeAutoMountGuestScreens ? "enabled" : "disabled"));
    foreach (int iGuestScreen, m_guestScreens)
    {
        /* Initialize variables: */
        bool fValid = false;
        int iHostScreen = -1;

        if (!fValid)
        {
            /* If the user ever selected a combination in the view menu, we have the following entry: */
            iHostScreen = gEDataManager->hostScreenForPassedGuestScreen(iGuestScreen, vboxGlobal().managedVMUuid());
            /* Revalidate: */
            fValid =    iHostScreen >= 0 && iHostScreen < m_cHostScreens /* In the host screen bounds? */
                     && m_screenMap.key(iHostScreen, -1) == -1; /* Not taken already? */
        }

        if (!fValid)
        {
            /* Check the position of the guest window in normal mode.
             * This makes sure that on first use fullscreen/seamless window opens on the same host-screen as the normal window was before.
             * This even works with multi-screen. The user just have to move all the normal windows to the target host-screens
             * and they will magically open there in fullscreen/seamless also. */
            QRect geo = gEDataManager->machineWindowGeometry(UIVisualStateType_Normal, iGuestScreen, vboxGlobal().managedVMUuid());
            /* If geometry is valid: */
            if (!geo.isNull())
            {
                /* Get top-left corner position: */
                QPoint topLeftPosition(geo.topLeft());
                /* Check which host-screen the position belongs to: */
                iHostScreen = vboxGlobal().screenNumber(topLeftPosition);
                /* Revalidate: */
                fValid =    iHostScreen >= 0 && iHostScreen < m_cHostScreens /* In the host screen bounds? */
                         && m_screenMap.key(iHostScreen, -1) == -1; /* Not taken already? */
            }
        }

        if (!fValid)
        {
            /* If still not valid, pick the next one
             * if there is still available host screen: */
            if (!availableScreens.isEmpty())
            {
                iHostScreen = availableScreens.first();
                fValid = true;
            }
        }

        if (fValid)
        {
            /* Register host screen for the guest screen: */
            m_screenMap.insert(iGuestScreen, iHostScreen);
            /* Remove it from the list of available host screens: */
            availableScreens.removeOne(iHostScreen);
        }
        /* Do we have opinion about what to do with excessive guest-screen? */
        else if (fShouldWeAutoMountGuestScreens)
        {
            /* Then we have to disable excessive guest-screen: */
            LogRel(("GUI: UIMultiScreenLayout::update: Disabling excessive guest-screen %d\n", iGuestScreen));
            display.SetVideoModeHint(iGuestScreen, false, false, 0, 0, 0, 0, 0);
        }
    }
Exemplo n.º 2
0
void UIMultiScreenLayout::update()
{
    LogRelFlow(("UIMultiScreenLayout::update: Started...\n"));

    /* Clear screen-map initially: */
    m_screenMap.clear();

    /* Make a pool of available host screens: */
    QList<int> availableScreens;
    for (int i = 0; i < m_cHostScreens; ++i)
        availableScreens << i;

    /* Load all combinations stored in the settings file.
     * We have to make sure they are valid, which means there have to be unique combinations
     * and all guests screens need there own host screen. */
    CMachine machine = m_pMachineLogic->session().GetMachine();
    CDisplay display = m_pMachineLogic->session().GetConsole().GetDisplay();
    bool fShouldWeAutoMountGuestScreens = VBoxGlobal::shouldWeAutoMountGuestScreens(machine, false);
    LogRelFlow(("UIMultiScreenLayout::update: GUI/AutomountGuestScreens is %s.\n", fShouldWeAutoMountGuestScreens ? "enabled" : "disabled"));
    QDesktopWidget *pDW = QApplication::desktop();
    foreach (int iGuestScreen, m_guestScreens)
    {
        /* Initialize variables: */
        bool fValid = false;
        int iHostScreen = -1;

        if (!fValid)
        {
            /* If the user ever selected a combination in the view menu, we have the following entry: */
            QString strTest = machine.GetExtraData(QString("%1%2").arg(GUI_VirtualScreenToHostScreen).arg(iGuestScreen));
            bool fOk;
            /* Check is this value can be converted: */
            iHostScreen = strTest.toInt(&fOk);
            /* Revalidate: */
            fValid =    fOk /* Valid data */
                     && iHostScreen >= 0 && iHostScreen < m_cHostScreens /* In the host screen bounds? */
                     && m_screenMap.key(iHostScreen, -1) == -1; /* Not taken already? */
        }

        if (!fValid)
        {
            /* Check the position of the guest window in normal mode.
             * This makes sure that on first use the window opens on the same screen as the normal window was before.
             * This even works with multi-screen. The user just have to move all the normal windows to the target screens
             * and they will magically open there in seamless/fullscreen also. */
            QString strTest1 = machine.GetExtraData(GUI_LastNormalWindowPosition + (iGuestScreen > 0 ? QString::number(iGuestScreen): ""));
            QRegExp posParser("(-?\\d+),(-?\\d+),(-?\\d+),(-?\\d+)");
            if (posParser.exactMatch(strTest1))
            {
                /* If parsing was successfully, convert it to a position: */
                bool fOk1, fOk2;
                QPoint p(posParser.cap(1).toInt(&fOk1), posParser.cap(2).toInt(&fOk2));
                /* Check to which screen the position belongs: */
                iHostScreen = pDW->screenNumber(p);
                /* Revalidate: */
                fValid =    fOk1 && fOk2 /* Valid data */
                         && iHostScreen >= 0 && iHostScreen < m_cHostScreens /* In the host screen bounds? */
                         && m_screenMap.key(iHostScreen, -1) == -1; /* Not taken already? */
            }
        }

        if (!fValid)
        {
            /* If still not valid, pick the next one
             * if there is still available host screen: */
            if (!availableScreens.isEmpty())
            {
                iHostScreen = availableScreens.first();
                fValid = true;
            }
        }

        if (fValid)
        {
            /* Register host screen for the guest screen: */
            m_screenMap.insert(iGuestScreen, iHostScreen);
            /* Remove it from the list of available host screens: */
            availableScreens.removeOne(iHostScreen);
        }
        /* Do we have opinion about what to do with excessive guest-screen? */
        else if (fShouldWeAutoMountGuestScreens)
        {
            /* Then we have to disable excessive guest-screen: */
            LogRelFlow(("UIMultiScreenLayout::update: Disabling excessive guest-screen %d.\n", iGuestScreen));
            display.SetVideoModeHint(iGuestScreen, false, false, 0, 0, 0, 0, 0);
        }
    }