VirtualBox

Changeset 27427 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Mar 16, 2010 9:28:13 PM (15 years ago)
Author:
vboxsync
Message:

FE/Qt4: New running VM core: fixing x11 bug determining available geometry for seamless desktops of one virtual desktop (xinerama).

Location:
trunk/src/VBox/Frontends/VirtualBox
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk

    r27374 r27427  
    241241# Necessary for the hdd backend enumeration
    242242VirtualBox_LIBS = $(LIB_DDU)
     243
     244# This library is required for multi-monitor support
     245VirtualBox_LIBS.linux += Xinerama
     246VirtualBox_LIBS.solaris += Xinerama
    243247
    244248ifdef VBOX_WITH_VIDEOHWACCEL
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp

    r27411 r27427  
    9494#include <X11/Xlib.h>
    9595#include <X11/Xatom.h>
     96#include <X11/extensions/Xinerama.h>
    9697#define BOOL PRBool
    9798#endif
     
    966967
    967968#endif
     969
     970#ifdef Q_WS_X11
     971QList<QRect> XGetDesktopList()
     972{
     973    /* Prepare empty resulting list: */
     974    QList<QRect> result;
     975
     976    /* Get current display: */
     977    Display* pDisplay = QX11Info::display();
     978
     979    /* If thats Xinerama desktop: */
     980    if (XineramaIsActive(pDisplay))
     981    {
     982        /* Reading Xinerama data: */
     983        int iScreens = 0;
     984        XineramaScreenInfo *pScreensData = XineramaQueryScreens(pDisplay, &iScreens);
     985
     986        /* Fill resulting list: */
     987        for (int i = 0; i < iScreens; ++ i)
     988            result << QRect(pScreensData[i].x_org, pScreensData[i].y_org,
     989                            pScreensData[i].width, pScreensData[i].height);
     990
     991        /* Free screens data: */
     992        XFree(pScreensData);
     993    }
     994
     995    /* Return resulting list: */
     996    return result;
     997}
     998
     999QList<Window> XGetWindowIDList()
     1000{
     1001    /* Get current display: */
     1002    Display *pDisplay = QX11Info::display();
     1003
     1004    /* Get virtual desktop window: */
     1005    Window window = QX11Info::appRootWindow();
     1006
     1007    /* Get 'client list' atom: */
     1008    Atom propNameAtom = XInternAtom(pDisplay, "_NET_CLIENT_LIST", True /* only if exists */);
     1009
     1010    /* Prepare empty resulting list: */
     1011    QList<Window> result;
     1012
     1013    /* If atom does not exists return empty list: */
     1014    if (propNameAtom == None)
     1015        return result;
     1016
     1017    /* Get atom value: */
     1018    Atom realAtomType = None;
     1019    int iRealFormat = 0;
     1020    unsigned long uItemsCount = 0;
     1021    unsigned long uBytesAfter = 0;
     1022    unsigned char *pData = 0;
     1023    int rc = XGetWindowProperty(pDisplay, window, propNameAtom,
     1024                                0, 0x7fffffff /*LONG_MAX*/, False /* delete */,
     1025                                XA_WINDOW, &realAtomType, &iRealFormat,
     1026                                &uItemsCount, &uBytesAfter, &pData);
     1027
     1028    /* If get property is failed return empty list: */
     1029    if (rc != Success)
     1030        return result;
     1031
     1032    /* Fill resulting list with win ids: */
     1033    Window *pWindowData = reinterpret_cast<Window*>(pData);
     1034    for (ulong i = 0; i < uItemsCount; ++ i)
     1035        result << pWindowData[i];
     1036
     1037    /* Releasing resources: */
     1038    XFree(pData);
     1039
     1040    /* Return resulting list: */
     1041    return result;
     1042}
     1043
     1044QList<ulong> XGetStrut(Window window)
     1045{
     1046    /* Get current display: */
     1047    Display *pDisplay = QX11Info::display();
     1048
     1049    /* Get 'strut' atom: */
     1050    Atom propNameAtom = XInternAtom(pDisplay, "_NET_WM_STRUT_PARTIAL", True /* only if exists */);
     1051
     1052    /* Prepare empty resulting list: */
     1053    QList<ulong> result;
     1054
     1055    /* If atom does not exists return empty list: */
     1056    if (propNameAtom == None)
     1057        return result;
     1058
     1059    /* Get atom value: */
     1060    Atom realAtomType = None;
     1061    int iRealFormat = 0;
     1062    ulong uItemsCount = 0;
     1063    ulong uBytesAfter = 0;
     1064    unsigned char *pData = 0;
     1065    int rc = XGetWindowProperty(pDisplay, window, propNameAtom,
     1066                                0, LONG_MAX, False /* delete */,
     1067                                XA_CARDINAL, &realAtomType, &iRealFormat,
     1068                                &uItemsCount, &uBytesAfter, &pData);
     1069
     1070    /* If get property is failed return empty list: */
     1071    if (rc != Success)
     1072        return result;
     1073
     1074    /* Fill resulting list with strut shifts: */
     1075    ulong *pStrutsData = reinterpret_cast<ulong*>(pData);
     1076    for (ulong i = 0; i < uItemsCount; ++ i)
     1077        result << pStrutsData[i];
     1078
     1079    /* Releasing resources: */
     1080    XFree(pData);
     1081
     1082    /* Return resulting list: */
     1083    return result;
     1084}
     1085#endif /* ifdef Q_WS_X11 */
     1086
     1087const QRect VBoxGlobal::availableGeometry(int iScreen) const
     1088{
     1089    /* Prepare empty result: */
     1090    QRect result;
     1091
     1092#ifdef Q_WS_X11
     1093
     1094    /* Get current display: */
     1095    Display* pDisplay = QX11Info::display();
     1096
     1097    /* Get current application desktop: */
     1098    QDesktopWidget *pDesktopWidget = QApplication::desktop();
     1099
     1100    /* If thats virtual desktop: */
     1101    if (pDesktopWidget->isVirtualDesktop())
     1102    {
     1103        /* If thats Xinerama desktop: */
     1104        if (XineramaIsActive(pDisplay))
     1105        {
     1106            /* Get desktops list: */
     1107            QList<QRect> desktops = XGetDesktopList();
     1108
     1109            /* Combine to get full virtual region: */
     1110            QRegion virtualRegion;
     1111            foreach (QRect desktop, desktops)
     1112                virtualRegion += desktop;
     1113            virtualRegion = virtualRegion.boundingRect();
     1114
     1115            /* Remember initial virtual desktop: */
     1116            QRect virtualDesktop = virtualRegion.boundingRect();
     1117            //AssertMsgFailed(("LOG... Virtual desktop is: %dx%dx%dx%d\n", virtualDesktop.x(), virtualDesktop.y(),
     1118            //                                                             virtualDesktop.width(), virtualDesktop.height()));
     1119
     1120            /* Set available geometry to screen geometry initially: */
     1121            result = desktops[iScreen];
     1122
     1123            /* Feat available geometry of virtual desktop to respect all the struts: */
     1124            QList<Window> list = XGetWindowIDList();
     1125            for (int i = 0; i < list.size(); ++ i)
     1126            {
     1127                /* Get window: */
     1128                Window wid = list[i];
     1129                QList<ulong> struts = XGetStrut(wid);
     1130
     1131                /* If window has strut: */
     1132                if (struts.size())
     1133                {
     1134                    ulong uLeftShift = struts[0];
     1135                    ulong uLeftFromY = struts[4];
     1136                    ulong uLeftToY = struts[5];
     1137
     1138                    ulong uRightShift = struts[1];
     1139                    ulong uRightFromY = struts[6];
     1140                    ulong uRightToY = struts[7];
     1141
     1142                    ulong uTopShift = struts[2];
     1143                    ulong uTopFromX = struts[8];
     1144                    ulong uTopToX = struts[9];
     1145
     1146                    ulong uBottomShift = struts[3];
     1147                    ulong uBottomFromX = struts[10];
     1148                    ulong uBottomToX = struts[11];
     1149
     1150                    if (uLeftShift)
     1151                    {
     1152                        QRect sr(QPoint(0, uLeftFromY),
     1153                                 QSize(uLeftShift, uLeftToY - uLeftFromY + 1));
     1154
     1155                        //AssertMsgFailed(("LOG... Subtract left strut: top-left: %dx%d, size: %dx%d\n", sr.x(), sr.y(), sr.width(), sr.height()));
     1156                        virtualRegion -= sr;
     1157                    }
     1158
     1159                    if (uRightShift)
     1160                    {
     1161                        QRect sr(QPoint(virtualDesktop.x() + virtualDesktop.width() - uRightShift, uRightFromY),
     1162                                 QSize(virtualDesktop.x() + virtualDesktop.width(), uRightToY - uRightFromY + 1));
     1163
     1164                        //AssertMsgFailed(("LOG... Subtract right strut: top-left: %dx%d, size: %dx%d\n", sr.x(), sr.y(), sr.width(), sr.height()));
     1165                        virtualRegion -= sr;
     1166                    }
     1167
     1168                    if (uTopShift)
     1169                    {
     1170                        QRect sr(QPoint(uTopFromX, 0),
     1171                                 QSize(uTopToX - uTopFromX + 1, uTopShift));
     1172
     1173                        //AssertMsgFailed(("LOG... Subtract top strut: top-left: %dx%d, size: %dx%d\n", sr.x(), sr.y(), sr.width(), sr.height()));
     1174                        virtualRegion -= sr;
     1175                    }
     1176
     1177                    if (uBottomShift)
     1178                    {
     1179                        QRect sr(QPoint(uBottomFromX, virtualDesktop.y() + virtualDesktop.height() - uBottomShift),
     1180                                 QSize(uBottomToX - uBottomFromX + 1, uBottomShift));
     1181
     1182                        //AssertMsgFailed(("LOG... Subtract bottom strut: top-left: %dx%d, size: %dx%d\n", sr.x(), sr.y(), sr.width(), sr.height()));
     1183                        virtualRegion -= sr;
     1184                    }
     1185                }
     1186            }
     1187
     1188            /* Get final available geometry: */
     1189            result = (virtualRegion & result).boundingRect();
     1190        }
     1191    }
     1192
     1193    /* If result is still NULL: */
     1194    if (result.isNull())
     1195    {
     1196        /* Use QT default functionality: */
     1197        result = pDesktopWidget->availableGeometry(iScreen);
     1198    }
     1199
     1200    //AssertMsgFailed(("LOG... Final geometry: %dx%dx%dx%d\n", result.x(), result.y(), result.width(), result.height()));
     1201
     1202#else /* ifdef Q_WS_X11 */
     1203
     1204    result = QApplication::desktop()->availableGeometry(iScreen);
     1205
     1206#endif /* ifndef Q_WS_X11 */
     1207
     1208    return result;
     1209}
    9681210
    9691211/**
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h

    r27411 r27427  
    336336    const char *vmRenderModeStr() const { return vm_render_mode_str; }
    337337    bool isKWinManaged() const { return mIsKWinManaged; }
     338
     339    const QRect availableGeometry(int iScreen = 0) const;
    338340
    339341#ifdef VBOX_WITH_DEBUGGER_GUI
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineLogicSeamless.h

    r27335 r27427  
    6363    friend class UIMachineLogic;
    6464    friend class UIMachineWindowSeamless;
     65    friend class UIMachineViewSeamless;
    6566};
    6667
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineViewSeamless.cpp

    r27424 r27427  
    3535
    3636/* Local includes */
     37#include "VBoxGlobal.h"
    3738#include "UISession.h"
    3839#include "UIMachineWindow.h"
    3940#include "UIMachineLogic.h"
    4041#include "UIFrameBuffer.h"
     42#include "UIMachineLogicSeamless.h"
    4143#include "UIMachineViewSeamless.h"
    4244
     
    293295QRect UIMachineViewSeamless::workingArea()
    294296{
    295     return QApplication::desktop()->availableGeometry(this);
     297    /* Get corresponding screen: */
     298    int iScreen = static_cast<UIMachineLogicSeamless*>(machineLogic())->hostScreenForGuestScreen(screenId());
     299    /* Return available geometry for that screen: */
     300    return vboxGlobal().availableGeometry(iScreen);
    296301}
    297302
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineWindowSeamless.cpp

    r27425 r27427  
    106106void UIMachineWindowSeamless::sltPlaceOnScreen()
    107107{
    108     QRect r = QApplication::desktop()->availableGeometry(static_cast<UIMachineLogicSeamless*>(machineLogic())->hostScreenForGuestScreen(m_uScreenId));
    109     move(r.topLeft());
    110     resize(r.size());
     108    /* Get corresponding screen: */
     109    int iScreen = static_cast<UIMachineLogicSeamless*>(machineLogic())->hostScreenForGuestScreen(m_uScreenId);
     110    /* Calculate working area: */
     111    QRect workingArea = vboxGlobal().availableGeometry(iScreen);
     112    /* Move & resize to the appropriate values: */
     113    move(workingArea.topLeft());
     114    resize(workingArea.size());
    111115}
    112116
     
    195199{
    196200#ifdef Q_WS_WIN
    197     m_prevRegion = QApplication::desktop()->availableGeometry(static_cast<UIMachineLogicSeamless*>(machineLogic())->hostScreenForGuestScreen(m_uScreenId));
     201    /* Get corresponding screen: */
     202    int iScreen = static_cast<UIMachineLogicSeamless*>(machineLogic())->hostScreenForGuestScreen(m_uScreenId);
     203    /* Prepare previous region: */
     204    m_prevRegion = vboxGlobal().availableGeometry(iScreen);
    198205#endif
    199206
     
    345352
    346353#ifdef Q_WS_MAC
    347     /* Make sure it is really on the right place (especially on the Mac) */
    348     QRect r = QApplication::desktop()->availableGeometry(static_cast<UIMachineLogicSeamless*>(machineLogic())->hostScreenForGuestScreen(m_uScreenId));
     354    /* Make sure it is really on the right place (especially on the Mac): */
     355    int iScreen = static_cast<UIMachineLogicSeamless*>(machineLogic())->hostScreenForGuestScreen(m_uScreenId);
     356    QRect r = vboxGlobal().availableGeometry(iScreen);
    349357    move(r.topLeft());
    350358#endif /* Q_WS_MAC */
  • trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxMiniToolBar.cpp

    r26715 r27427  
    217217    if (aEvent->timerId() == mScrollTimer.timerId())
    218218    {
    219         QRect screen = mSeamless ? QApplication::desktop()->availableGeometry (window()) :
     219        QRect screen = mSeamless ? vboxGlobal().availableGeometry (QApplication::desktop()->screenNumber(window())) :
    220220                                   QApplication::desktop()->screenGeometry (window());
    221221        switch (mAlignment)
     
    383383void VBoxMiniToolBar::moveToBase()
    384384{
    385     QRect screen = mSeamless ? QApplication::desktop()->availableGeometry (window()) :
     385    QRect screen = mSeamless ? vboxGlobal().availableGeometry (QApplication::desktop()->screenNumber(window())) :
    386386                               QApplication::desktop()->screenGeometry (window());
    387387    mPositionX = screen.x() + screen.width() / 2 - width() / 2;
     
    411411    QPoint globalPosition = parentWidget()->mapFromGlobal (aPoint);
    412412    QRect fullArea = QApplication::desktop()->screenGeometry (window());
    413     QRect realArea = mSeamless ? QApplication::desktop()->availableGeometry (window()) :
     413    QRect realArea = mSeamless ? vboxGlobal().availableGeometry (QApplication::desktop()->screenNumber(window())) :
    414414                                 QApplication::desktop()->screenGeometry (window());
    415415    QPoint shiftToReal (realArea.topLeft() - fullArea.topLeft());
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