This is the mail archive of the cygwin-xfree@cygwin.com mailing list for the Cygwin XFree86 project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix - Occasional Paste Problem


I've just recently started using Cygwin/X but occasionally paste from Win32
to X fails.  I'm using -multiwindow and -clipboard.  I tracked down one
source of the failures: XP's remote desktop.  Remote desktop does not
properly restore the clipboard chain when it shuts down.  Result is that
XWin no longer sees clipboard messages when you copy in a Win32 app.

The fix is rather simple although a bit forceful.  Just reinitialize the
clipboard chain each time the app is activated or deactivated - on each
WM_ACTIVATEAPP message.

Here's a proposed patch.  Sorry, not from CVS since I can't get external cvs
access from work at the moment.  They are from the most recent install from
cygwin.com though (6.7.0.0-7).

If not obvious this is the first time I've sent in a patch so please let me
know if there's anything you'd like done differently (other than using the
CVS sources - sorry).

Dan

ChangeLog

2004-04-21 Dan Wilks <dan_wilks@intuit.com>

* win.h: Add prototype for winFixClipboardChain
* winclipboard.h: Add definition WM_WM_REINIT a private windows message that
the clipboard window uses to reinitialize the clipboard viewer chain. 
* winwndproc.c (winWindowProc): Call winFixClipboardChain on application
activation/deactivation to ensure that XWin is still in the clipboard chain.
* winclipboardinit.c: Added references to g_fClipboard and g_hwndClipboard
for winFixClipboardChain to use.
(winFixClipboardChain): New function.  Ensures that XWin is still in the
Windows clipboard chain if we're using the internal clipboard.
* winclipboardwndproc.c (winClipboardWindowProc): Process WM_WM_REINIT and
force ourselves back into the clipboard chain.

Patches

--- win.h.save  2004-04-09 23:12:32.001000000 -0700
+++ win.h       2004-04-21 16:44:29.421875000 -0700
@@ -756,6 +756,9 @@ winPixmapToRegionNativeGDI (PixmapPtr pP
 
 Bool
 winInitClipboard (void);
+
+void
+winFixClipboardChain (void);
 #endif


--- winclipboard.h.save 2004-03-30 07:00:09.001000000 -0800
+++ winclipboard.h      2004-04-21 16:25:57.140625000 -0700
@@ -76,6 +76,7 @@
 #define WIN_XEVENTS_CONVERT                    2
 #define WIN_XEVENTS_NOTIFY                     3
 
+#define WM_WM_REINIT                           (WM_USER + 1)
 
 /*
  * References to external symbols

--- winwndproc.c.save   2004-04-03 12:36:33.001000000 -0800
+++ winwndproc.c        2004-04-21 16:47:18.656250000 -0700
@@ -1110,6 +1110,9 @@ winWindowProc (HWND hwnd, UINT message, 
          ShowCursor (TRUE);
        }
 
+      /* Make sure the clipboard chain is ok. */
+      winFixClipboardChain ();
+
       /* Call engine specific screen activation/deactivation function */
       (*s_pScreenPriv->pwinActivateApp) (s_pScreen);
       return 0;

--- winclipboardinit.c.save     2004-03-26 11:43:15.001000000 -0800
+++ winclipboardinit.c  2004-04-21 16:56:35.453125000 -0700
@@ -47,6 +47,8 @@ DISPATCH_PROC(winProcSetSelectionOwner);
 
 extern pthread_t               g_ptClipboardProc;
 extern winDispatchProcPtr      winProcSetSelectionOwnerOrig;
+extern Bool                    g_fClipboard;
+extern HWND                    g_hwndClipboard;
 
 
 /*
@@ -126,3 +128,13 @@ winClipboardCreateMessagingWindow ()
 
   return hwnd;
 }
+
+void
+winFixClipboardChain (void)
+{
+   if (g_fClipboard
+       && g_hwndClipboard)
+     {
+       SendMessage (g_hwndClipboard, WM_WM_REINIT, 0, 0);
+     }
+}


--- winclipboardwndproc.c.save  2004-03-30 06:56:01.001000000 -0800
+++ winclipboardwndproc.c       2004-04-21 17:08:17.156250000 -0700
@@ -181,6 +181,32 @@ winClipboardWindowProc (HWND hwnd, UINT 
       }
       return 0;
 
+    case WM_WM_REINIT:
+      {
+        /* Ensure that we're in the clipboard chain.  Some apps,
+           WinXP's remote desktop for one, don't play nice with
+           the chain.  This message is called whenever we receive
+           a WM_ACTIVATEAPP message to ensure that we continue to
+           receive clipboard messages.
+     
+           It might be possible to detect if we're still in the
+           chain by calling
+              SendMessage (GetClipboardViewer(), WM_DRAWCLIPBOARD, 0, 0);
+           and then seeing if we get the WM_DRAWCLIPBOARD message.
+           That, however, might be more expensive than just putting
+           ourselves back into the chain.
+        */
+
+        s_fCBCInitialized = FALSE;
+        ChangeClipboardChain (hwnd, s_hwndNextViewer);
+        s_hwndNextViewer = NULL;
+        s_fCBCInitialized = FALSE;
+        s_hwndNextViewer = SetClipboardViewer (hwnd);
+      }
+      return 0;
+
 
     case WM_DRAWCLIPBOARD:
       {



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]