JDK-4259272 : Support Notifications of Clipboard Contents Changes
  • Type: Enhancement
  • Status: Resolved
  • Resolution: Fixed
  • Component: client-libs
  • Sub-Component: java.awt
  • Priority: P4
  • Affected Version: 1.1.6,1.2.2,1.4.0
  • OS: generic,solaris_7,windows_95,windows_nt
  • CPU: generic,x86,sparc
  • Submit Date: 1999-08-03
  • Updated Date: 2017-05-16
  • Resolved Date: 2003-06-06
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availabitlity Release.

To download the current JDK release, click here.
5.0 tigerResolved
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  

Name: skT88420			Date: 08/03/99

Most Windows applications, and probably those on other platforms,
typically enable "paste" functionality only when there is valid data
on the clipboard ("valid" meaning of an appropriate flavor).
Implementing this behavior requires a mechanism through which changes
to the clipboard can be detected.  That is when the option should be
enabled or disabled -- when the clipboard contents change.  The Java
Clipboard API does not currently support this type of notification,
but it could be added trivially.

I suggest that java.awt.Clipboard be extended to support a set of
listeners (PropertyChangeListener would be adequate) who are notified
when the clipboard contents change.  This would be entirely backward
compatible with the existing API and would provide very useful
functionality that is not currently available.
(Review ID: 93418) 

CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: tiger FIXED IN: tiger INTEGRATED IN: tiger tiger-b09

WORK AROUND Name: skT88420 Date: 08/03/99 I am not aware of any workaround. I tried a hack using ClipboardOwnership. The idea was that if I am always the owner of the clipboard, I will receive a lostOwnership whenever the contents change. However, it is not generally possible (or good) to steal ownership when another application is using the clipboard. ======================================================================

SUGGESTED FIX Name: agR10216 Date: 12/11/2002 Add ContentsListener and ContentsEvent classes to the java.awt.datatransfer package. Add to the Clipboard class methods: public boolean areContentsChangeNotificationsSupported() public void addContentsListener(ContentsListener listener) public void removeContentsListener(ContentsListener listener) public ContentsListener[] getContentsListeners() private void fireContentsChanged() Notify listeners via fireContentsChanged() when Clipboard.setContents() is called. Since WClippboard is shared between AppContexts, override addContentsListener(), removeContentsListener(), getContentsListeners() so that they manage ContentsListeners per AppContext. The native clipboard viewer window (i.e. the window that will receive notifications on clipboard contents changes; in our case it is the AwtToolkit window) is registered by WClipboard.registerClipboardViewer(). To implement clipboard viewer functionality, the messages WM_CHANGECBCHAIN and WM_DRAWCLIPBOARD are processed in AwtToolkit::WndProc() by the new AwtClipboard methods: ProcessWmChangeCbChain() and ProcessWmDrawClipboard(). Listeners are notified when WM_DRAWCLIPBOARD message comes by posting events to the appropriate AppContexts in WClipboard.contentsChanged(). For unregistering the clipboard viewer AwtClipboard::UnregisterClipboardViewer() is called on AwtToolkit disposing. Override areContentsChangeNotificationsSupported() in X11Clipboard so that this method returns false. Add getAppContexts() method to AppContext class. It returns a set containing all AppContexts. This method is used in WClipboard.contentsChanged(). Correct AppContext.stopEventDispatchThreads() by using getAppContexts() to guarantee that only one shutdown event is posted to the AppContext's EventQueue (this is an improvement of the fix 4701990). ###@###.### 2002-12-11 ====================================================================== Name: agR10216 Date: 01/18/2003 According to the evaluation, we chose the approach based on data flavors available on a clipboard. As before, it's simple to implement it for a local clipboard. In the Clipboard.setContents() we get data flavors that just have been set, compare them to the previously set flavors and fire FlavorEvents if necessary. On Windows the same mechanism of clipboard viewers is used. On the WM_DRAWCLIPBOARD message we get clipboard data formats, convert them to the Java data flavors, compare them to the previous flavors and post a PeerEvent to all app contexts (if necessary). FlavorEvents are fired on the EDT of an app context. On X11 platforms we poll a selection. In order not to start a new thread, we register a timeout callback. In this callback we request the section targets. When the selection targets are obtained, we convert them to the Java data flavors and so on. ###@###.### 2002-01-18 ====================================================================== Name: agR10216 Date: 01/18/2003 Sometimes we may not get formats available on a clipboard. (Most likely such a situation happens with the Windows system clipboard if we fail to open it. There may be some other exceptional conditions.) Anyway, we notify listeners so as to give a client a chance to determine whether 'paste option' should be triggered. Thus we send all necessary notifications but some notifications may be redundant. ###@###.### 2002-01-18 ====================================================================== Name: agR10216 Date: 01/22/2003 One should note that prior to thix fix in Clipboard.setContents() lostOwnership() on the clipboard owner was called directly there. Now we are to notify flavor listeners also. If lostOwnership() were called directly within setContents() and setContents() got called in the lostOwnership(), the notifications on flavor changes might be delayed. Almost the same we can say about one of the flavorsChanged() method of flavor listeners registered on the clipboard. The solution is to post requests for invocation of lostOwnership() and each flavorChanged() method to the EDT. ###@###.### 2003-01-22 ====================================================================== Name: agR10216 Date: 01/25/2003 On X11 platforms we request for targets of a selection at regular intervals quite often (in the timer callback). Ordinarily to request for selection targets we call and pass awt_util_getCurrentServerTime() to XtGetSelectionValue(). The call of awt_util_getCurrentServerTime() may block for a while (on the toolkit therad!) depending on the transmission speed beetween a client and the X server. Therefore, some optimization is desired. We suggest changing of awt_root_shell window property in the timer callback, and only when we have got an up-to-date timestamp, requesting for selection targets with that timestamp. ###@###.### 2003-01-25 ====================================================================== Name: agR10216 Date: 02/11/2003 Since on X platforms we request for targets of a selection at regular intervals, we'd better parametrize the interval between two successive requests for selection targets, at least for our internal use. Let it be a system property "awt.datatransfer.clipboard.poll.interval" in milliseconds. The default poll interval on X platforms is 200 ms. ###@###.### 2003-02-10 ====================================================================== Name: agR10216 Date: 02/11/2003 From now lostOwhership() is not called directly from Clipboard and SunClipboard's setContents(). Instead, a request for lostOwnership() invocation is posted to the EDT. The regression tests test/java/awt/Clipboard/LostOwnershipChainTest/PrivateClipboardTest and test/java/awt/Clipboard/LostOwnershipChainTest/SystemClipboardTest assumed that lostOwnership() is called directly in setContents(). So these tests have been updated to reflect the current behaviour. ###@###.### 2003-02-11 ======================================================================

EVALUATION Will consider along with other Clipboard RFEs for merlin. david.mendenhall@eng 1999-12-14 We didn't have time to get this in for merlin. Will have to wait for tiger. david.mendenhall@east 2000-12-14 Name: agR10216 Date: 12/11/2002 Notifications on clipboard contents changes can be implemented for a local clipboard and the Windows system clipboard, but not for selections on Solaris/Linux, since Xlib does not provide any means for doing that. To determine whether notifications on contents changes are supported for the clipboard, the method Clipboard.areContentsChangeNotificationsSupported() has been added. In order to be notified on a clipboard contents changes the ContentsListener should be added to the clipboard by means of Clipboard.addContentsListener() method. Also public two methods for managing listeners were added: Clipboard.getContentsListeners() and Clipboard.removeContentsListener(). ###@###.### 2002-12-11 ====================================================================== Name: agR10216 Date: 12/11/2002 I should mention that first I have tried to implement notifications on clipboard contents changes using PropertyChangeListeners. In that case old and new contents of a clipboard must be passed to listeners. It is trivial to implement it for a local clipboard. As for Windows system clipboard, it could be implemented, but a great care should be taken to synchronize contents updates (this is not that problematically), also new clipboard contents can not be reliably retrieved. If some application opened the system clipboard and did not close it, an attempt to fetch clipboard contents would fail, and the failure would manifest in our code, where it could not be handled properly. So the decision not to provide clipboard contents directly to the listeners and to use a new interface for listeners (java.awt.datatransfer.ContentsListener) and a new class for events (java.awt.datatransfer.ContentsEvent) was taken. ###@###.### 2002-12-11 ====================================================================== Name: agR10216 Date: 01/18/2003 The described above implementation of the feature isn't really cross-platform: the feature wasn't implemented for the system clipboard and system selection on X11 platforms. All that we could do on X11 platforms was polling a selection, retrieving its contents and comparing that contents with the previous one. It isn't acceptable since it is very expensive. So in order to properly implement this feature on all supported platforms we decided to redesign the current implementation. To implement the functionality defined in the description (enabling/disabling paste option in a Java application depending on what flavors clipboard data are available) it's sufficient to track the changes of data flavors available on the clipboard. The following new API are to be introduced in the package java.awt.datatransfer: a listener interface FlavorListener, an event FlavorEvent that is delivered to the FlavorListeners whenever clipboard flavors change, and the following Clipboard methods: void Clipboard.addFlavorListener(FlavorListener listener), void Clipboard.removeFlavorListener(FlavorListener listener), FlavorListener[] Clipboard.getFlavorListeners(). ###@###.### 2003-01-18 ======================================================================