United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-4259272 : Support Notifications of Clipboard Contents Changes

Details
Type:
Enhancement
Submit Date:
1999-08-03
Status:
Resolved
Updated Date:
2003-06-06
Project Name:
JDK
Resolved Date:
2003-06-06
Component:
client-libs
OS:
windows_nt,solaris_7,generic,windows_95
Sub-Component:
java.awt
CPU:
x86,sparc,generic
Priority:
P4
Resolution:
Fixed
Affected Versions:
1.1.6,1.2.2,1.4.0
Fixed Versions:
5.0 (tiger)

Related Reports
Duplicate:
Duplicate:
Relates:
Relates:
Relates:
Relates:
Relates:
Relates:

Sub Tasks

Description

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) 
======================================================================

                                    

Comments
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
======================================================================
                                     
2003-01-18
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


======================================================================
                                     
2003-02-11
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.
======================================================================
                                     
2004-08-24
CONVERTED DATA

BugTraq+ Release Management Values

COMMIT TO FIX:
tiger

FIXED IN:
tiger

INTEGRATED IN:
tiger
tiger-b09


                                     
2004-08-24



Hardware and Software, Engineered to Work Together