Changeset 57283 in vbox for trunk/src/VBox/Additions/x11/VBoxClient
- Timestamp:
- Aug 12, 2015 10:31:53 AM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp
r56781 r57283 571 571 /** List of allowed formats. */ 572 572 RTCList<RTCString> m_lstAllowedFormats; 573 /** Number of failed attempts by the host 574 * to query for an active drag and drop operation on the guest. */ 575 uint16_t m_cFailedPendingAttempts; 573 576 }; 574 577 … … 692 695 m_enmMode = Unknown; 693 696 m_eventQueueList.clear(); 697 m_cFailedPendingAttempts = 0; 694 698 695 699 /* Reset the selection request buffer. */ … … 1054 1058 && m_wndCur == static_cast<Window>(e.xclient.data.l[XdndPositionWindow])) 1055 1059 { 1060 if (m_enmState != Dragging) /* Wrong mode? Bail out. */ 1061 { 1062 reset(); 1063 break; 1064 } 1065 1056 1066 int32_t lPos = e.xclient.data.l[XdndPositionXY]; 1057 1067 Atom atmAction = m_curVer >= 2 /* Actions other than "copy" or only supported since protocol version 2. */ … … 1103 1113 { 1104 1114 LogFlowThisFunc(("XA_XdndDrop\n")); 1105 /* Can occur when dragging from guest->host, but then back in to the guest again. */ 1106 logInfo("Could not drop on own proxy window\n"); /* Not fatal. */ 1107 1108 /* Let the source know. */ 1109 rc = m_wndProxy.sendFinished(m_wndCur, DND_IGNORE_ACTION); 1110 1111 /* Start over. */ 1112 reset(); 1115 1116 if (m_enmState != Dropped) /* Wrong mode? Bail out. */ 1117 { 1118 /* Can occur when dragging from guest->host, but then back in to the guest again. */ 1119 logInfo("Could not drop on own proxy window\n"); /* Not fatal. */ 1120 1121 /* Let the source know. */ 1122 rc = m_wndProxy.sendFinished(m_wndCur, DND_IGNORE_ACTION); 1123 1124 /* Start over. */ 1125 reset(); 1126 break; 1127 } 1128 1129 m_eventQueueList.append(e); 1130 rc = RTSemEventSignal(m_eventQueueEvent); 1113 1131 } 1114 else if ( e.xclient.message_type == xAtom(XA_XdndFinished) 1115 && m_wndCur == static_cast<Window>(e.xclient.data.l[XdndFinishedWindow])) 1132 else 1116 1133 { 1117 LogFlowThisFunc(("XA_XdndFinished\n")); 1118 logInfo("Finished drop on own proxy window\n"); /* Not fatal. */ 1134 logInfo("Unhandled event from wnd=%#x, msg=%s\n", e.xclient.window, xAtomToString(e.xclient.message_type).c_str()); 1119 1135 1120 1136 /* Let the source know. */ … … 1354 1370 switch (e.type) 1355 1371 { 1372 /* 1373 * This can happen if a guest->host drag operation 1374 * goes back from the host to the guest. This is not what 1375 * we want and thus resetting everything. 1376 */ 1356 1377 case ButtonPress: 1357 LogFlowThisFunc(("ButtonPress\n")); 1378 case ButtonRelease: 1379 LogFlowThisFunc(("Mouse button press/release\n")); 1358 1380 rc = VINF_SUCCESS; 1359 break; 1360 1361 case ButtonRelease: 1362 LogFlowThisFunc(("ButtonRelease\n")); 1363 rc = VINF_SUCCESS; 1381 1382 reset(); 1364 1383 break; 1365 1384 … … 1963 1982 ) 1964 1983 { 1965 rc = VERR_INVALID_STATE; 1984 /* No need to query for the source window again. */ 1985 rc = VINF_SUCCESS; 1966 1986 } 1967 1987 else … … 1984 2004 /* Map the window on the current cursor position, which should provoke 1985 2005 * an XdndEnter event. */ 1986 rc = proxyWinShow( NULL, NULL);2006 rc = proxyWinShow(); 1987 2007 if (RT_SUCCESS(rc)) 1988 2008 { … … 1990 2010 if (RT_SUCCESS(rc)) 1991 2011 { 2012 bool fWaitFailed = false; /* Waiting for status changed failed? */ 2013 1992 2014 /* Wait until we're in "Dragging" state. */ 1993 rc = waitForStatusChange(Dragging, 1000 /* 1s timeout */); 2015 rc = waitForStatusChange(Dragging, 100 /* 100ms timeout */); 2016 2017 /* 2018 * Note: Don't wait too long here, as this mostly will make 2019 * the drag and drop experience on the host being laggy 2020 * and unresponsive. 2021 * 2022 * Instead, let the host query multiple times with 100ms 2023 * timeout each (see above) and only report an error if 2024 * the overall querying time has been exceeded.< 2025 */ 2026 if (RT_SUCCESS(rc)) 2027 { 2028 m_enmMode = GH; 2029 } 2030 else if (rc == VERR_TIMEOUT) 2031 { 2032 /** @todo Make m_cFailedPendingAttempts configurable. For slower window managers? */ 2033 if (m_cFailedPendingAttempts++ > 50) /* Tolerate up to 5s total (100ms for each slot). */ 2034 fWaitFailed = true; 2035 else 2036 rc = VINF_SUCCESS; 2037 } 2038 else if (RT_FAILURE(rc)) 2039 fWaitFailed = true; 2040 2041 if (fWaitFailed) 2042 { 2043 logError("Error mapping proxy window to guest source window %#x ('%s'), rc=%Rrc\n", 2044 wndSelection, pszWndName, rc); 2045 2046 /* Reset the counter in any case. */ 2047 m_cFailedPendingAttempts = 0; 2048 } 1994 2049 } 1995 if (RT_SUCCESS(rc))1996 {1997 m_enmMode = GH;1998 }1999 else2000 logError("Error mapping proxy window to guest source window %#x ('%s'), rc=%Rrc\n",2001 wndSelection, pszWndName, rc);2002 2050 } 2003 2051 … … 2070 2118 m_enmState = Dropped; 2071 2119 2072 /* Show the proxy window, so that the current source window will find it. */2073 int iRootX, iRootY;2074 proxyWinShow(&iRootX, &iRootY);2075 2076 2120 #ifdef DEBUG 2077 2121 XWindowAttributes xwa; … … 2079 2123 LogFlowThisFunc(("wndProxy=%#x, wndCur=%#x, x=%d, y=%d, width=%d, height=%d\n", 2080 2124 m_wndProxy.hWnd, m_wndCur, xwa.x, xwa.y, xwa.width, xwa.height)); 2125 2126 Window wndSelection = XGetSelectionOwner(m_pDisplay, xAtom(XA_XdndSelection)); 2127 LogFlowThisFunc(("wndSelection=%#x\n", wndSelection)); 2081 2128 #endif 2082 2129 2083 /* We send a fake release event to the current window, cause2130 /* We send a fake mouse move event to the current window, cause 2084 2131 * this should have the grab. */ 2085 #if 0 2086 //mouseButtonSet(m_wndCur /* Destination window */, xwa.x + (xwa.width / 2), xwa.y + (xwa.height / 2), 1 /* Button */, false /* fPress */); 2087 #else 2088 mouseButtonSet(m_wndCur /* Destination window */, -1 /* Root X */, -1 /* Root Y */, 1 /* Button */, false /* fPress */); 2089 #endif 2132 mouseCursorFakeMove(); 2090 2133 2091 2134 /** … … 2366 2409 LogFlowThisFunc(("Note: XText extension not available or disabled\n")); 2367 2410 2411 unsigned int mask; 2412 2368 2413 if ( rx == -1 2369 2414 && ry == -1) 2370 2415 { 2371 Window wnd Temp, wndChild;2372 int wx, wy; unsigned int mask;2373 XQueryPointer(m_pDisplay, m_wndRoot, &wnd Temp, &wndChild, &rx, &ry, &wx, &wy, &mask);2374 LogFlowThisFunc((" cursorRootX=%d, cursorRootY=%d\n", rx, ry));2416 Window wndRoot, wndChild; 2417 int wx, wy; 2418 XQueryPointer(m_pDisplay, m_wndRoot, &wndRoot, &wndChild, &rx, &ry, &wx, &wy, &mask); 2419 LogFlowThisFunc(("Mouse pointer is at root x=%d, y=%d\n", rx, ry)); 2375 2420 } 2376 2421 … … 2385 2430 eBtn.time = CurrentTime; 2386 2431 eBtn.button = iButton; 2387 eBtn.state |= iButton == 1 ? Button1Mask /*:2388 iButton == 2 ? Button2MotionMask :2389 iButton == 3 ? Button3MotionMask :2390 iButton == 4 ? Button4MotionMask :2391 iButton == 5 ? Button5MotionMask*/ : 0;2432 eBtn.state = mask | (iButton == 1 ? Button1MotionMask : 2433 iButton == 2 ? Button2MotionMask : 2434 iButton == 3 ? Button3MotionMask : 2435 iButton == 4 ? Button4MotionMask : 2436 iButton == 5 ? Button5MotionMask : 0); 2392 2437 eBtn.type = fPress ? ButtonPress : ButtonRelease; 2393 2438 eBtn.send_event = False; … … 2396 2441 2397 2442 XTranslateCoordinates(m_pDisplay, eBtn.root, eBtn.window, eBtn.x_root, eBtn.y_root, &eBtn.x, &eBtn.y, &eBtn.subwindow); 2398 LogFlowThisFunc((" x=%d, y=%d\n", eBtn.x, eBtn.y));2399 #if 1 2443 LogFlowThisFunc(("state=0x%x, x=%d, y=%d\n", eBtn.state, eBtn.x, eBtn.y)); 2444 2400 2445 int xRc = XSendEvent(m_pDisplay, wndDest, True /* fPropagate */, 2401 fPress 2402 ? ButtonPressMask : ButtonReleaseMask, 2446 ButtonPressMask, 2403 2447 reinterpret_cast<XEvent*>(&eBtn)); 2404 2448 if (xRc == 0) 2405 2449 logError("Error sending XButtonEvent event to window=%#x: %s\n", wndDest, gX11->xErrorToString(xRc).c_str()); 2406 #else 2407 int xRc = XSendEvent(m_pDisplay, eBtn.window, False /* fPropagate */, 2408 0 /* Mask */, reinterpret_cast<XEvent*>(&eBtn)); 2409 if (xRc == 0) 2410 logError("Error sending XButtonEvent event to window=%#x: %s\n", wndDest, gX11->xErrorToString(xRc).c_str()); 2411 #endif 2450 2451 XFlush(m_pDisplay); 2412 2452 2413 2453 #ifdef VBOX_DND_WITH_XTEST … … 2860 2900 /* Was the drop accepted by the host? That is, anything than ignoring. */ 2861 2901 bool fDropAccepted = uAction > DND_IGNORE_ACTION; 2902 2903 LogFlowFunc(("uAction=%RU32\n", uAction)); 2862 2904 2863 2905 /* Confirm the result of the transfer to the target window. */ … … 2877 2919 { 2878 2920 LogRel(("DnD: Error sending XA_XdndFinished event to source window=%#x: %s\n", 2879 hWndSource, gX11->xErrorToString(xRc).c_str()));2921 hWndSource, gX11->xErrorToString(xRc).c_str())); 2880 2922 2881 2923 return VERR_GENERAL_FAILURE; /** @todo Fudge. */
Note:
See TracChangeset
for help on using the changeset viewer.