XQuartz: pbproxy: The greedy CLIPBOARD handling now works for text.

This change adds some [self own_clipboard] calls in the necessary places to get the proper greedy behavior.

UTF8_STRING and STRING properties seem to work well now with the test cases (PRIMARY, and CLIPBOARD).  I can copy from several different X apps, and have the behavior be correct when pasting.  I also verified that quartz-wm isn't doing the copying, by disabling the quartz-wm paths.
(cherry picked from commit 934669f732)
This commit is contained in:
George Peter Staplin 2008-09-16 21:09:22 -06:00 committed by Jeremy Huddleston
parent 7c2eb3d41a
commit 23ec8261b6
2 changed files with 57 additions and 27 deletions

View File

@ -21,12 +21,7 @@ CFRunLoopSourceRef x_dpy_source;
/* Timestamp when the X server last told us it's active */
static Time last_activation_time;
static FILE *getSelectionLog(void) {
return fopen("/tmp/selection.log", "a");
}
static void x_event_apple_wm_notify(XAppleWMNotifyEvent *e) {
FILE *fp = getSelectionLog();
switch (e->type - x_apple_wm_event_base) {
case AppleWMActivationNotify:
@ -45,19 +40,15 @@ static void x_event_apple_wm_notify(XAppleWMNotifyEvent *e) {
break;
case AppleWMPasteboardNotify:
fprintf(fp, "AppleWMPasteboardNotify\n");
switch (e->kind) {
case AppleWMCopyToPasteboard:
[x_selection_object () x_copy:e->time];
}
break;
}
fclose(fp);
}
void x_input_run (void) {
FILE *fp = getSelectionLog();
while (XPending (x_dpy) != 0) {
XEvent e;
@ -66,23 +57,18 @@ void x_input_run (void) {
switch (e.type) {
case SelectionClear:
fprintf(fp, "SelectionClear\n");
[x_selection_object () clear_event:&e.xselectionclear];
break;
case SelectionRequest:
fprintf(fp, "SelectionRequest\n");
[x_selection_object () request_event:&e.xselectionrequest];
break;
case SelectionNotify:
fprintf(fp, "SelectionNotify\n");
[x_selection_object () notify_event:&e.xselection];
break;
case PropertyNotify:
fprintf(fp, "PropertyNotify\n");
[x_selection_object () property_event:&e.xproperty];
break;
@ -96,7 +82,6 @@ void x_input_run (void) {
XFlush(x_dpy);
}
fclose(fp);
}
static int add_input_socket (int sock, CFOptionFlags callback_types,

View File

@ -619,6 +619,9 @@ convert_1 (XSelectionRequestEvent *e, NSString *data, Atom target, Atom prop)
/* Someone's asking us for the data on the pasteboard */
TRACE ();
/*NOT YET*/
return;
/* TODO We should also keep track of the time of the selection, and
* according to the ICCCM "refuse the request" if the event timestamp
* is before we owned it.
@ -628,7 +631,9 @@ convert_1 (XSelectionRequestEvent *e, NSString *data, Atom target, Atom prop)
* may be set to CurrentTime or a time, so that makes it a bit different.
* Perhaps we should just punt and ignore races.
*/
DB ("e->target %s\n", XGetAtomName (x_dpy, e->target));
if (e->target == atoms->targets)
{
/* The paste requestor wants to know what TARGETS we support. */
@ -661,14 +666,20 @@ convert_1 (XSelectionRequestEvent *e, NSString *data, Atom target, Atom prop)
TRACE ();
[self release_pending];
DB ("notify_event\n");
if (None == e->property) {
DB ("e->property is None.\n");
if (pbproxy_clipboard_to_pasteboard && e->selection == atoms->clipboard)
[self own_clipboard];
/* Nothing is selected. */
return;
}
DB ("e->selection %s\n", XGetAtomName (x_dpy, e->selection));
DB ("e->property %s\n", XGetAtomName (x_dpy, e->property));
if (is_incr_type (e))
{
/*
@ -679,6 +690,14 @@ convert_1 (XSelectionRequestEvent *e, NSString *data, Atom target, Atom prop)
if (get_property (e->requestor, e->property, &pdata, /*Delete*/ True, &type))
{
/*
* The get_property error could have occured with the clipboard atom.
* Greedily own the clipboard again.
*/
if (pbproxy_clipboard_to_pasteboard && e->selection == atoms->clipboard)
[self own_clipboard];
return;
}
@ -697,18 +716,30 @@ convert_1 (XSelectionRequestEvent *e, NSString *data, Atom target, Atom prop)
/* We have the complete selection data.*/
[self handle_selection: e->selection type:type propdata:&pdata];
DB ("handled selection with the first notify_event\n");
/*
* This may have been the end of the clipboard request from [self claim_clipboard].
* If so, then we should own the contents now.
*/
if (pbproxy_clipboard_to_pasteboard && e->selection == atoms->clipboard)
[self own_clipboard];
}
}
/* This is used for INCR transfers. See the ICCCM for the details. */
/* This is used to retrieve PRIMARY and CLIPBOARD selections. */
- (void) property_event:(XPropertyEvent *)e
{
struct propdata pdata;
Atom type;
TRACE ();
if (None != e->atom)
DB ("e->atom %s\n", XGetAtomName (x_dpy, e->atom));
if (None != pending.requestor && PropertyNewValue == e->state)
{
@ -726,10 +757,11 @@ convert_1 (XSelectionRequestEvent *e, NSString *data, Atom target, Atom prop)
if (0 == pdata.length)
{
/* We completed the transfer. */
[self handle_selection: pending.selection type: type propdata: &pending.propdata];
[self handle_selection:pending.selection type:type propdata:&pending.propdata];
if (pbproxy_clipboard_to_pasteboard && pending.selection == atoms->clipboard)
[self own_clipboard];
pending.propdata = null_propdata;
pending.requestor = None;
pending.selection = None;
@ -738,7 +770,7 @@ convert_1 (XSelectionRequestEvent *e, NSString *data, Atom target, Atom prop)
{
[self append_to_pending: &pdata requestor: e->window];
}
}
}
}
- (void) handle_targets: (Atom)selection propdata:(struct propdata *)pdata
@ -786,7 +818,7 @@ convert_1 (XSelectionRequestEvent *e, NSString *data, Atom target, Atom prop)
DB ("%s\n", [pbtype cStringUsingEncoding:NSISOLatin1StringEncoding]);
pbtypes = [NSArray arrayWithObject: pbtype];
pbtypes = [NSArray arrayWithObjects: pbtype, nil];
if (nil == pbtypes)
{
DB ("error creating NSArray\n");
@ -823,22 +855,26 @@ convert_1 (XSelectionRequestEvent *e, NSString *data, Atom target, Atom prop)
NSArray *pbtypes;
TRACE ();
string = [[NSString alloc] initWithBytes:pdata->data length:pdata->length encoding:NSUTF8StringEncoding];
if (nil == string)
return;
pbtypes = [NSArray arrayWithObject:NSStringPboardType];
pbtypes = [NSArray arrayWithObjects:NSStringPboardType, nil];
if (nil != pbtypes)
{
[_pasteboard declareTypes:pbtypes owner:self];
[_pasteboard setString:string forType:NSStringPboardType];
if (YES != [_pasteboard setString:string forType:NSStringPboardType]) {
DB ("_pasteboard setString:forType: failed!\n");
}
[pbtypes release];
}
[string release];
DB ("done handling utf8 string\n");
}
/* This handles the XA_STRING type, which should be in Latin-1. */
@ -852,7 +888,7 @@ convert_1 (XSelectionRequestEvent *e, NSString *data, Atom target, Atom prop)
if (nil == string)
return;
pbtypes = [NSArray arrayWithObject:NSStringPboardType];
pbtypes = [NSArray arrayWithObjects:NSStringPboardType, nil];
if (nil != pbtypes)
{
@ -915,6 +951,16 @@ convert_1 (XSelectionRequestEvent *e, NSString *data, Atom target, Atom prop)
/* NSPasteboard-required methods */
- (void)paste:(id)sender
{
TRACE ();
}
- (void)pasteboard:(NSPasteboard *)pb provideDataForType:(NSString *)type
{
TRACE ();
}
- (void) pasteboardChangedOwner:(NSPasteboard *)sender
{
TRACE ();
@ -978,4 +1024,3 @@ convert_1 (XSelectionRequestEvent *e, NSString *data, Atom target, Atom prop)
}
@end