VirtualBox

Ignore:
Timestamp:
Mar 10, 2014 1:54:03 PM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
92721
Message:

DnD: Bugfixes.

File:
1 edited

Legend:

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

    r50724 r50734  
    4545 * their behavior. Don't have this enabled in release builds! */
    4646#ifdef DEBUG
    47 # define VBOX_DND_DEBUG_WND
     47//# define VBOX_DND_DEBUG_WND
    4848#endif
    4949
     
    7676 * the data in the specified mime-type. This data is send back to the host.
    7777 * After that we send a XdndLeave event to the source window.
    78  * Todo:
    79  * - this isn't finished, yet. Currently the mouse isn't correctly released
    80  *   in the guest (both, when the drop was successfully or canceled).
    81  * - cancel (e.g. with the ESC key) doesn't work
     78 *
     79 * To-do:
     80 * - Cancelling (e.g. with ESC key) doesn't work.
    8281 *
    83  * Todo:
    84  * - XdndProxy window support
    85  * - INCR support
    86  * - make this much more robust for crashes of the other party
    87  * - really check for the Xdnd version and the supported features
     82 * To-do:
     83 * - INCR (incremental transfers) support.
     84 * - Make this much more robust for crashes of the other party.
     85 * - Really check for the Xdnd version and the supported features.
    8886 */
    8987
     
    390388    void mouseButtonSet(Window wndDest, int rx, int ry, int iButton, bool fPress) const;
    391389    int proxyWinShow(int *piRootX = NULL, int *piRootY = NULL, bool fMouseMove = false) const;
    392     int proxyWinHide(void) const;
     390    int proxyWinHide(void);
    393391    void registerForEvents(Window w) const;
    394392
     
    569567    m_curVer = -1;
    570568    m_state  = Initialized;
     569    m_eventQueue.clear();
    571570}
    572571
     
    740739        case GH:
    741740        {
    742             //if (m_state == Dropped)
    743             //{
    744                 LogFlowThisFunc(("Enqueuing ClientMessage\n"));
    745 
    746                 m_eventQueue.append(e);
    747                 rc = RTSemEventSignal(m_hEventSem);
    748             //}
    749 
    750             //rc = VINF_SUCCESS;
     741            LogFlowThisFunc(("Enqueuing ClientMessage\n"));
     742
     743            m_eventQueue.append(e);
     744            rc = RTSemEventSignal(m_hEventSem);
    751745            break;
    752746        }
     
    885879                    memcpy(&m_eventHgSelection, &e, sizeof(XEvent));
    886880
    887                     const char *pcszFormat = xAtomToString(e.xselectionrequest.target).c_str();
    888                     AssertPtr(pcszFormat);
    889                     rc = VbglR3DnDHGRequestData(m_uClientID, pcszFormat);
     881                    RTCString strFormat = xAtomToString(e.xselectionrequest.target);
     882                    Assert(strFormat.isNotEmpty());
     883                    rc = VbglR3DnDHGRequestData(m_uClientID, strFormat.c_str());
    890884                    LogFlowThisFunc(("Requesting data from host as \"%s\", rc=%Rrc\n",
    891                                      pcszFormat, rc));
     885                                     strFormat.c_str(), rc));
    892886                }
    893887            }
     
    936930    switch (e.type)
    937931    {
     932        case ButtonPress:
     933            LogFlowThisFunc(("ButtonPress\n"));
     934            rc = VINF_SUCCESS;
     935            break;
     936
     937        case ButtonRelease:
     938            LogFlowThisFunc(("ButtonRelease\n"));
     939            rc = VINF_SUCCESS;
     940            break;
     941
     942        case ClientMessage:   
     943            rc = onX11ClientMessage(e);
     944            break;
     945
     946        case SelectionClear:
     947           LogFlowThisFunc(("SelectionClear\n"));
     948           reset();
     949           rc = VINF_SUCCESS;
     950           break;
     951
    938952        case SelectionNotify:
    939953            rc = onX11SelectionNotify(e);
     
    943957            rc = onX11SelectionRequest(e);
    944958            break;
    945 
    946         case ClientMessage:   
    947             rc = onX11ClientMessage(e);
    948             break;
    949 
    950         case SelectionClear:
    951            LogFlowThisFunc(("SelectionClear\n"));
    952            rc = VINF_SUCCESS;
    953            break;
    954959
    955960        /*case MotionNotify:
     
    11351140                                 0, 2, False, AnyPropertyType,
    11361141                                 &atmp, &fmt, &cItems, &cbRemaining, &pcData);
     1142
    11371143        if (RT_UNLIKELY(xrc != Success))
    11381144            LogFlowThisFunc(("Error in getting the window property: %s\n", gX11->xErrorToString(xrc).c_str()));
     
    11461152                LogFlowThisFunc(("wndCursor=%#x, XdndAware=%u\n", newVer));
    11471153            }
     1154
    11481155            XFree(pcData);
    11491156        }
     
    11531160     * Is the window under the cursor another one than our current one?
    11541161     */
    1155     if (wndCursor != m_wndCur && m_curVer != -1)
     1162    if (   wndCursor != m_wndCur
     1163        && m_curVer != -1)
    11561164    {
    11571165        LogFlowThisFunc(("Leaving window=%#x\n", m_wndCur));
     
    12121220         */
    12131221        Atom pa = toX11Action(uAction);
    1214         LogFlowThisFunc(("strAction='%s' ", xAtomToString(pa).c_str()));
     1222        LogFlowThisFunc(("strAction=%s\n", xAtomToString(pa).c_str()));
    12151223
    12161224        XClientMessageEvent m;
     
    12311239    }
    12321240
    1233     if (wndCursor == None && newVer == -1)
     1241    if (   wndCursor == None
     1242        && newVer    == -1)
    12341243    {
    12351244        /* No window to process, so send a ignore ack event to the host. */
     
    13561365            AssertPtr(pEventClient);
    13571366
    1358             LogFlowThisFunc(("Next X event is: %s\n",
     1367            LogFlowThisFunc(("Received event=%s\n",
    13591368                             gX11->xAtomToString(pEventClient->message_type).c_str()));
    13601369
     
    13701379                m_state = Dragging;
    13711380                m_wndCur = wndSelection;
     1381                Assert(m_wndCur == pEventClient->data.l[0]);
    13721382
    13731383                LogFlowThisFunc(("XA_XdndEnter\n"));
     
    14381448                XClientMessageEvent m;
    14391449                RT_ZERO(m);
    1440 
    14411450                m.type         = ClientMessage;
    14421451                m.display      = m_pDisplay;
    1443                 m.window       = pEventClient->data.l[0];
     1452                m.window       = m_wndCur;
    14441453                m.message_type = xAtom(XA_XdndStatus);
    14451454                m.format       = 32;
    14461455                m.data.l[0]    = m_wndProxy;
    1447                 m.data.l[1]    = 1;
    1448                 m.data.l[4]    = xAtom(XA_XdndActionCopy);
    1449 
    1450                 xRc = XSendEvent(m_pDisplay, pEventClient->data.l[0],
     1456                m.data.l[1]    = RT_BIT(0); /* Accept the drop. */
     1457                m.data.l[4]    = xAtom(XA_XdndActionCopy); /** @todo Make the accepted action configurable. */
     1458
     1459                xRc = XSendEvent(m_pDisplay, m_wndCur,
    14511460                                 False, 0, reinterpret_cast<XEvent*>(&m));
    14521461                if (RT_UNLIKELY(xRc == 0))
     
    14641473                m.type         = ClientMessage;
    14651474                m.display      = m_pDisplay;
    1466                 m.window       = pEventClient->data.l[0];
     1475                m.window       = m_wndCur;
    14671476                m.message_type = xAtom(XA_XdndStatus);
    14681477                m.format       = 32;
    14691478                m.data.l[0]    = m_wndProxy;
    1470                 m.data.l[1]    = 1;
    1471                 m.data.l[4]    = pEventClient->data.l[4];
    1472 
    1473                 xRc = XSendEvent(m_pDisplay, pEventClient->data.l[0],
     1479                m.data.l[1]    = RT_BIT(0); /* Accept the drop. */
     1480                m.data.l[4]    = xAtom(XA_XdndActionCopy); /** @todo Make the accepted action configurable. */
     1481
     1482                xRc = XSendEvent(m_pDisplay, m_wndCur,
    14741483                                 False, 0, reinterpret_cast<XEvent*>(&m));
    14751484                if (RT_UNLIKELY(xRc == 0))
     
    14821491        }
    14831492
    1484         proxyWinHide();
    1485 
    14861493        /* Do we need to acknowledge at least one format to the host? */
    14871494        if (!m_formats.isEmpty())
     
    15271534    /* We send a fake release event to the current window, cause
    15281535     * this should have the grab. */
    1529     mouseButtonSet(m_wndCur, iRootX, iRootY,
     1536    mouseButtonSet(m_wndCur /* Source window */, iRootX, iRootY,
    15301537                   1 /* Button */, false /* Release button */);
    15311538
     
    15421549        /* Request to convert the selection in the specific format and
    15431550         * place it to our proxy window as property. */
    1544         Window srcWin = m_wndCur;//clme->data.l[0];
     1551        Window wndSource = evDnDDrop.data.l[0]; /* Source window which sent the message. */
     1552        Assert(wndSource == m_wndCur);
    15451553        Atom aFormat  = gX11->stringToxAtom(strFormat.c_str());
    15461554
     
    15541562        if (waitForX11Msg(evSelNotify, SelectionNotify))
    15551563        {
     1564            bool fCancel = false;
     1565
    15561566            /* Make some paranoid checks. */
    15571567            if (   evSelNotify.xselection.type      == SelectionNotify
     
    16161626                                     strFormat.c_str(), rc));
    16171627
    1618                     /* Confirm the result of the transfer to the source window. */
    1619                     XClientMessageEvent m;
    1620                     RT_ZERO(m);
    1621                     m.type         = ClientMessage;
    1622                     m.display      = m_pDisplay;
    1623                     m.window       = srcWin;
    1624                     m.message_type = xAtom(XA_XdndFinished);
    1625                     m.format       = 32;
    1626                     m.data.l[0]    = m_wndProxy;
    1627                     m.data.l[1]    = RT_SUCCESS(rc) ? 1 : 0;                       /* Confirm or deny success */
    1628                     m.data.l[2]    = RT_SUCCESS(rc) ? toX11Action(uAction) : None; /* Action used on success */
    1629 
    1630                     int xrc = XSendEvent(m_pDisplay, srcWin, True, NoEventMask, reinterpret_cast<XEvent*>(&m));
    1631                     if (RT_UNLIKELY(xrc == 0))
    1632                         LogFlowThisFunc(("Error sending xEvent\n"));
     1628                    if (RT_SUCCESS(rc))
     1629                    {
     1630                        /* Confirm the result of the transfer to the source window. */
     1631                        XClientMessageEvent m;
     1632                        RT_ZERO(m);
     1633                        m.type         = ClientMessage;
     1634                        m.display      = m_pDisplay;
     1635                        m.window       = m_wndProxy;
     1636                        m.message_type = xAtom(XA_XdndFinished);
     1637                        m.format       = 32;
     1638                        m.data.l[0]    = m_wndProxy; /* Target window. */
     1639                        m.data.l[1]    = 0; /* Don't accept the drop to not make the guest stuck. */
     1640                        m.data.l[2]    = RT_SUCCESS(rc) ? toX11Action(uAction) : None; /* Action used on success */
     1641
     1642                        int xrc = XSendEvent(m_pDisplay, wndSource, True, NoEventMask, reinterpret_cast<XEvent*>(&m));
     1643                        if (RT_UNLIKELY(xrc == 0))
     1644                            LogFlowThisFunc(("Error sending xEvent\n"));
     1645                    }
     1646                    else
     1647                        fCancel = true;
    16331648                }
    16341649                else
     
    16421657                    else
    16431658                    {
    1644                         AssertMsgFailed(("Not supported data type\n"));
     1659                        AssertMsgFailed(("Not supported data type (%s)\n",
     1660                                         gX11->xAtomToString(aPropType).c_str()));
    16451661                        rc = VERR_INVALID_PARAMETER;
    16461662                    }
     1663
     1664                    fCancel = true;
     1665                }
     1666
     1667                if (fCancel)
     1668                {
     1669                    LogFlowFunc(("Cancelling drop ...\n"));
    16471670
    16481671                    /* Cancel this. */
     
    16511674                    m.type         = ClientMessage;
    16521675                    m.display      = m_pDisplay;
    1653                     m.window       = srcWin;
     1676                    m.window       = m_wndProxy;
    16541677                    m.message_type = xAtom(XA_XdndFinished);
    16551678                    m.format       = 32;
    1656                     m.data.l[0]    = m_wndProxy;
    1657                     m.data.l[1]    = 0;
    1658                     m.data.l[2]    = None;
    1659 
    1660                     int xrc = XSendEvent(m_pDisplay, srcWin, False, NoEventMask, reinterpret_cast<XEvent*>(&m));
     1679                    m.data.l[0]    = m_wndProxy; /* Target window. */
     1680                    m.data.l[1]    = 0; /* Don't accept the drop to not make the guest stuck. */
     1681
     1682                    int xrc = XSendEvent(m_pDisplay, wndSource, False, NoEventMask, reinterpret_cast<XEvent*>(&m));
    16611683                    if (RT_UNLIKELY(xrc == 0))
    1662                         LogFlowThisFunc(("Error sending xEvent\n"));
    1663                     m_wndCur = 0;
     1684                        LogFlowThisFunc(("Error sending cancel event\n"));
    16641685                }
    16651686
     
    18481869}
    18491870
    1850 int DragInstance::proxyWinHide(void) const
    1851 {
    1852     LogFlowThisFuncEnter();
    1853     return 0;
     1871int DragInstance::proxyWinHide(void)
     1872{
     1873    LogFlowFuncEnter();
    18541874
    18551875    XUnmapWindow(m_pDisplay, m_wndProxy);
     1876    m_eventQueue.clear();
    18561877
    18571878    return VINF_SUCCESS; /** @todo Add error checking. */
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