VirtualBox

Changeset 55846 in vbox for trunk/src/VBox/Additions


Ignore:
Timestamp:
May 13, 2015 1:39:39 PM (10 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
100297
Message:

DnD: State machine fixes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp

    r55820 r55846  
    389389    /* H->G */
    390390    int  hgEnter(const RTCList<RTCString> &formats, uint32_t actions);
     391    int  hgLeave(void);
    391392    int  hgMove(uint32_t u32xPos, uint32_t u32yPos, uint32_t action);
    392393    int  hgDrop();
     
    401402    /* X11 helpers. */
    402403    int  mouseCursorMove(int iPosX, int iPosY) const;
    403     void mouseButtonSet(Window wndDest, int rx, int ry, int iButton, bool fPress) const;
     404    void mouseButtonSet(Window wndDest, int rx, int ry, int iButton, bool fPress);
    404405    int proxyWinShow(int *piRootX = NULL, int *piRootY = NULL, bool fMouseMove = false) const;
    405406    int proxyWinHide(void);
     
    830831            rc = VINF_SUCCESS;
    831832
     833#ifdef DEBUG
     834            XTextProperty propName;
     835            XGetWMName(m_pDisplay, e.xselectionrequest.requestor, &propName);
     836#endif
    832837            /*
    833838             * A window is asking for some data. Normally here the data would be copied
     
    841846            if (e.xselectionrequest.target == xAtom(XA_TARGETS))
    842847            {
    843                 LogFlowThisFunc(("wnd=%#x asking for target list\n", e.xselectionrequest.requestor));
     848                LogFlowThisFunc(("wnd=%#x '%s' asking for target list\n",
     849                                 e.xselectionrequest.requestor, propName.value));
    844850
    845851                /* If so, set the window property with the formats on the requestor
     
    857863            else if (m_lstFormats.contains(e.xselectionrequest.target))
    858864            {
    859                 LogFlowThisFunc(("wnd=%#x asking for data, format=%s\n",
    860                                  e.xselectionrequest.requestor, xAtomToString(e.xselectionrequest.target).c_str()));
     865                LogFlowThisFunc(("wnd=%#x '%s' asking for data, format=%s\n",
     866                                 e.xselectionrequest.requestor, propName.value,
     867                                 xAtomToString(e.xselectionrequest.target).c_str()));
    861868
    862869                /* If so, we need to inform the host about this request. Save the
     
    873880                else
    874881                {
    875                     LogFlowThisFunc(("Saving selection notify message\n"));
     882                    LogFlowThisFunc(("Saving selection notify message of wnd=%#x '%s'\n",
     883                                     e.xselectionrequest.requestor, propName.value));
    876884
    877885                    memcpy(&m_eventHgSelection, &e, sizeof(XEvent));
     
    887895            else
    888896            {
    889                 LogFlowThisFunc(("Refusing unknown command\n"));
     897                LogFlowThisFunc(("Refusing unknown command of wnd=%#x '%s'\n", e.xselectionrequest.requestor, propName.value));
    890898
    891899                /* We don't understand this request message and therefore answer with an
     
    913921            }
    914922
     923#ifdef DEBUG
     924            if (propName.value)
     925                XFree(propName.value);
     926#endif
    915927            break;
    916928        }
     
    11331145}
    11341146
     1147int DragInstance::hgLeave(void)
     1148{
     1149    if (m_enmMode == HG)
     1150        reset();
     1151
     1152    return VINF_SUCCESS;
     1153}
     1154
    11351155int DragInstance::hgMove(uint32_t u32xPos, uint32_t u32yPos, uint32_t uAction)
    11361156{
     
    11771197            {
    11781198                newVer = reinterpret_cast<long*>(pcData)[0];
    1179 
    1180                 LogFlowThisFunc(("Current: wndCursor=%#x, XdndAware=%ld\n", wndCursor, newVer));               
    11811199#ifdef DEBUG
    11821200                XTextProperty propName;
    11831201                if (XGetWMName(m_pDisplay, wndCursor, &propName))
    11841202                {
    1185                     LogFlowThisFunc(("\tTitle: %s\n", propName.value));
     1203                    LogFlowThisFunc(("Current: wndCursor=%#x '%s', XdndAware=%ld\n", wndCursor, propName.value, newVer));
    11861204                    XFree(propName.value);
    11871205                }
     
    15511569    XWindowAttributes xwa;
    15521570    XGetWindowAttributes(m_pDisplay, m_wndCur, &xwa);
    1553     LogFlowThisFunc(("m_wndCur=%#x, x=%d, y=%d, width=%d, height=%d\n",
    1554                      m_wndCur, xwa.x, xwa.y, xwa.width, xwa.height));
    1555 
    1556     iRootX = xwa.x;
    1557     iRootY = xwa.y;
     1571    LogFlowThisFunc(("wndCur=%#x, x=%d, y=%d, width=%d, height=%d\n", m_wndCur, xwa.x, xwa.y, xwa.width, xwa.height));
    15581572#endif
    15591573
    15601574    /* We send a fake release event to the current window, cause
    15611575     * this should have the grab. */
    1562     mouseButtonSet(m_wndCur /* Source window */, iRootX, iRootY,
    1563                    1 /* Button */, false /* Release button */);
     1576    mouseButtonSet(m_wndCur /* Destination window */, iRootX, iRootY,
     1577                   1 /* Button */, false /* fPress */);
    15641578
    15651579    /**
     
    16561670                    if (RT_SUCCESS(rc))
    16571671                    {
    1658                         /* Confirm the result of the transfer to the source window. */
     1672                        /* Confirm the result of the transfer to the target window. */
    16591673                        XClientMessageEvent m;
    16601674                        RT_ZERO(m);
    16611675                        m.type         = ClientMessage;
    16621676                        m.display      = m_pDisplay;
    1663                         m.window       = m_wndProxy;
     1677                        m.window       = wndSource;
    16641678                        m.message_type = xAtom(XA_XdndFinished);
    16651679                        m.format       = 32;
    1666                         m.data.l[0]    = m_wndProxy; /* Target window. */
    1667                         m.data.l[1]    = 0; /* Don't accept the drop to not make the guest stuck. */
    1668                         m.data.l[2]    = RT_SUCCESS(rc) ? toAtomAction(uAction) : None; /* Action used on success */
     1680                        m.data.l[0]    = m_wndProxy;                   /* Target window. */
     1681                        m.data.l[1]    = 0;                            /* Don't accept the drop to not make the guest stuck. */
     1682                        m.data.l[2]    = RT_SUCCESS(rc)
     1683                                       ? toAtomAction(uAction) : None; /* Action used on success */
    16691684
    16701685                        xRc = XSendEvent(m_pDisplay, wndSource, True, NoEventMask, reinterpret_cast<XEvent*>(&m));
     
    16971712                    LogFlowFunc(("Cancelling drop ...\n"));
    16981713
    1699                     /* Cancel this. */
     1714                    /* Cancel the operation -- inform the source window. */
    17001715                    XClientMessageEvent m;
    17011716                    RT_ZERO(m);
     
    17031718                    m.display      = m_pDisplay;
    17041719                    m.window       = m_wndProxy;
    1705                     m.message_type = xAtom(XA_XdndFinished);
     1720                    m.message_type = xAtom(XA_XdndLeave);
    17061721                    m.format       = 32;
    1707                     m.data.l[0]    = m_wndProxy; /* Target window. */
    1708                     m.data.l[1]    = 0; /* Don't accept the drop to not make the guest stuck. */
     1722                    m.data.l[0]    = wndSource;         /* Source window. */
    17091723
    17101724                    xRc = XSendEvent(m_pDisplay, wndSource, False, NoEventMask, reinterpret_cast<XEvent*>(&m));
    17111725                    if (RT_UNLIKELY(xRc == 0))
    17121726                    {
    1713                         logError("Error sending XA_XdndFinished event to proxy window=%#x: %s\n",
     1727                        logError("Error sending XA_XdndLeave event to proxy window=%#x: %s\n",
    17141728                                  m_wndProxy, gX11->xErrorToString(xRc).c_str());
    17151729                    }
     
    17511765int DragInstance::mouseCursorMove(int iPosX, int iPosY) const
    17521766{
     1767    int iScreenID = XDefaultScreen(m_pDisplay);
     1768    /** @todo What about multiple screens? Test this! */
     1769
     1770    const int iScrX = DisplayWidth(m_pDisplay, iScreenID);
     1771    const int iScrY = XDisplayHeight(m_pDisplay, iScreenID);
     1772
     1773    iPosX = RT_CLAMP(iPosX, 0, iScrX);
     1774    iPosY = RT_CLAMP(iPosY, 0, iScrY);
     1775
    17531776    LogFlowThisFunc(("iPosX=%d, iPosY=%d\n", iPosX, iPosY));
    17541777
    17551778    /* Move the guest pointer to the DnD position, so we can find the window
    17561779     * below that position. */
    1757     XWarpPointer(m_pDisplay, None, m_wndRoot, 0, 0, 0, 0, RT_MAX(0, iPosX), RT_MAX(0, iPosY));
     1780    XWarpPointer(m_pDisplay, None, m_wndRoot, 0, 0, 0, 0, iPosX, iPosY);
    17581781    return VINF_SUCCESS;
    17591782}
    17601783
    1761 void DragInstance::mouseButtonSet(Window wndDest, int rx, int ry, int iButton, bool fPress) const
     1784void DragInstance::mouseButtonSet(Window wndDest, int rx, int ry, int iButton, bool fPress)
    17621785{
    17631786    LogFlowThisFunc(("wndDest=%#x, rx=%d, ry=%d, iBtn=%d, fPress=%RTbool\n",
    17641787                     wndDest, rx, ry, iButton, fPress));
    1765 #if 0
    1766  // Create and setting up the event
    1767     XEvent event;
    1768     memset (&event, 0, sizeof (event));
    1769     event.xbutton.button = iButton;
    1770     event.xbutton.same_screen = True;
    1771     event.xbutton.subwindow = DefaultRootWindow (m_pDisplay);
    1772 
    1773     while (event.xbutton.subwindow)
    1774     {
    1775         event.xbutton.window = event.xbutton.subwindow;
    1776         XQueryPointer (m_pDisplay, event.xbutton.window,
    1777                         &event.xbutton.root, &event.xbutton.subwindow,
    1778                         &event.xbutton.x_root, &event.xbutton.y_root,
    1779                         &event.xbutton.x, &event.xbutton.y,
    1780                         &event.xbutton.state);
    1781     }
    1782     // Press
    1783     event.type = ButtonPress;
    1784     if (XSendEvent (m_pDisplay, PointerWindow, True, ButtonPressMask, &event) == 0)
    1785         LogFlowThisFunc(("Error sending XTestFakeButtonEvent event\n"));
    1786     XFlush (m_pDisplay);
    1787 
    1788     // Release
    1789     event.type = ButtonRelease;
    1790     if (XSendEvent (m_pDisplay, PointerWindow, True, ButtonReleaseMask, &event) == 0)
    1791         LogFlowThisFunc(("Error sending XTestFakeButtonEvent event\n"));
    1792     XFlush (m_pDisplay);
    1793 
    1794 #else
     1788
    17951789#ifdef VBOX_DND_WITH_XTEST
    17961790    /** @todo Make this check run only once. */
     
    18021796        int xRc = XTestFakeButtonEvent(m_pDisplay, 1, fPress ? True : False, CurrentTime);
    18031797        if (RT_UNLIKELY(xRc == 0))
    1804             LogFlowThisFunc(("Error sending XTestFakeButtonEvent event: %s\n", gX11->xErrorToString(xRc).c_str()));
     1798            logError("Error sending XTestFakeButtonEvent event: %s\n", gX11->xErrorToString(xRc).c_str());
    18051799        XFlush(m_pDisplay);
    18061800    }
     
    18391833        int xRc = XSendEvent(m_pDisplay, eBtn.window, False /* fPropagate */,
    18401834                             0 /* Mask */, reinterpret_cast<XEvent*>(&eBtn));
     1835        if (RT_UNLIKELY(xRc == 0))
     1836            logError("Error sending XButtonEvent event to window=%#x: %s\n", wndDest, gX11->xErrorToString(xRc).c_str());
    18411837#endif
    1842         if (RT_UNLIKELY(xRc == 0))
    1843             LogFlowThisFunc(("Error sending XButtonEvent event to window=%#x: %s\n", wndDest, gX11->xErrorToString(xRc).c_str()));
    18441838
    18451839#ifdef DEBUG
     
    18471841        int wx, wy; unsigned int mask;
    18481842        XQueryPointer(m_pDisplay, m_wndRoot, &wndTemp, &wndChild, &rx, &ry, &wx, &wy, &mask);
    1849         LogFlowFunc(("cursorRootX=%d, cursorRootY=%d\n", rx, ry));
     1843        LogFlowThisFunc(("cursorRootX=%d, cursorRootY=%d\n", rx, ry));
    18501844#endif
    18511845
    18521846#ifdef VBOX_DND_WITH_XTEST
    18531847    }
    1854 #endif
    18551848#endif
    18561849}
     
    18651858    LogFlowThisFuncEnter();
    18661859
     1860    int rc = VINF_SUCCESS;
     1861
    18671862#if 0
    18681863    XTestGrabControl(m_pDisplay, False);
     
    18701865
    18711866    /* Get the mouse pointer position and determine if we're on the same screen as the root window
    1872      * and returns the current child window beneath our mouse pointer, if any. */
     1867     * and return the current child window beneath our mouse pointer, if any. */
    18731868    int iRootX, iRootY;
    18741869    int iChildX, iChildY;
     
    18991894
    19001895    if (fMouseMove)
    1901         XWarpPointer(m_pDisplay, None, m_wndRoot, 0, 0, 0, 0, iRootX, iRootY);
     1896        rc = mouseCursorMove(iRootX, iRootY);
    19021897
    19031898    XSynchronize(m_pDisplay, False /* Disable sync */);
     
    19071902#endif
    19081903
    1909     return VINF_SUCCESS; /** @todo Add error checking. */
     1904    return rc;
    19101905}
    19111906
     
    22412236                    case DragAndDropSvc::HOST_DND_HG_EVT_LEAVE:
    22422237                    {
    2243                         m_pCurDnD->reset();
     2238                        rc = m_pCurDnD->hgLeave();
    22442239                        break;
    22452240                    }
     
    22742269                }
    22752270
    2276                 if (RT_FAILURE(rc))
     2271                LogFlowFunc(("Message %RU32 processed with %Rrc\n", e.hgcm.uType, rc));
     2272                if (   RT_FAILURE(rc)
     2273                    /*
     2274                     * Note: The hgXXX and ghXXX functions of the DnD instance above may return
     2275                     *       VERR_INVALID_STATE in case we're not in the expected state they want
     2276                     *       to operate in. As the user might drag content back and forth to/from
     2277                     *       the host/guest we don't want to reset the overall state here in case
     2278                     *       a VERR_INVALID_STATE occurs. Just continue in our initially set mode.
     2279                     */
     2280                    && rc != VERR_INVALID_STATE)
    22772281                {
    22782282                    m_pCurDnD->logError("Error: Processing message %RU32 failed with %Rrc\n", e.hgcm.uType, rc);
Note: See TracChangeset for help on using the changeset viewer.

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