diff options
author | Jeremy Huddleston <jeremyhu@freedesktop.org> | 2008-10-15 14:11:18 -0700 |
---|---|---|
committer | Jeremy Huddleston <jeremyhu@freedesktop.org> | 2008-10-15 17:31:54 -0700 |
commit | 84ef8ed6fbefd8d6c0aaa3c862879f9804299bd8 (patch) | |
tree | bb710e8d826c0da7c9f91e3abc85eac46c8f64a4 /hw | |
parent | 0195d318465d5a6a9039091bcb252202471df5a4 (diff) |
XQuartz: implemented primary-on-grab and fixed clipboard-to-pasteboard
(cherry picked from commit bcb83eea729a01026d99d1cfc2b77385b5b275fd)
Diffstat (limited to 'hw')
-rw-r--r-- | hw/xquartz/pbproxy/Makefile.am | 2 | ||||
-rw-r--r-- | hw/xquartz/pbproxy/app-main.m | 3 | ||||
-rw-r--r-- | hw/xquartz/pbproxy/main.m | 13 | ||||
-rw-r--r-- | hw/xquartz/pbproxy/pbproxy.h | 4 | ||||
-rw-r--r-- | hw/xquartz/pbproxy/x-input.m | 8 | ||||
-rw-r--r-- | hw/xquartz/pbproxy/x-selection.h | 2 | ||||
-rw-r--r-- | hw/xquartz/pbproxy/x-selection.m | 44 |
7 files changed, 58 insertions, 18 deletions
diff --git a/hw/xquartz/pbproxy/Makefile.am b/hw/xquartz/pbproxy/Makefile.am index fd93ce18d..2eee766ed 100644 --- a/hw/xquartz/pbproxy/Makefile.am +++ b/hw/xquartz/pbproxy/Makefile.am @@ -1,5 +1,5 @@ AM_CPPFLAGS=-F/System/Library/Frameworks/ApplicationServices.framework/Frameworks -AM_LDFLAGS=-L/usr/X11/lib -lX11 -lAppleWM -framework AppKit -framework Foundation -framework ApplicationServices +AM_LDFLAGS=-L/usr/X11/lib -lX11 -lXfixes -lAppleWM -framework AppKit -framework Foundation -framework ApplicationServices SOURCE_FILES = \ trick_autotools.c \ diff --git a/hw/xquartz/pbproxy/app-main.m b/hw/xquartz/pbproxy/app-main.m index 4847851fa..3dfdcb41a 100644 --- a/hw/xquartz/pbproxy/app-main.m +++ b/hw/xquartz/pbproxy/app-main.m @@ -19,7 +19,8 @@ int main (int argc, const char *argv[]) { printf("pid: %u\n", getpid()); #endif - x_init (); + if(x_init () !=0) + return 1; signal (SIGINT, signal_handler); signal (SIGTERM, signal_handler); diff --git a/hw/xquartz/pbproxy/main.m b/hw/xquartz/pbproxy/main.m index 448bec4e0..ded18e1f7 100644 --- a/hw/xquartz/pbproxy/main.m +++ b/hw/xquartz/pbproxy/main.m @@ -8,9 +8,12 @@ #include <pthread.h> #include <X11/extensions/applewm.h> +#include <X11/extensions/xfixes.h> Display *x_dpy; int x_apple_wm_event_base, x_apple_wm_error_base; +int x_xfixes_event_base, x_xfixes_error_base; +BOOL have_xfixes; x_selection *_selection_object; @@ -31,13 +34,13 @@ static int x_error_handler (Display *dpy, XErrorEvent *errevent) { return 0; } -void x_init (void) { +int x_init (void) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; x_dpy = XOpenDisplay (NULL); if (x_dpy == NULL) { fprintf (stderr, "can't open default display\n"); - exit (1); + return 1; } XSetIOErrorHandler (x_io_error_handler); @@ -46,9 +49,11 @@ void x_init (void) { if (!XAppleWMQueryExtension (x_dpy, &x_apple_wm_event_base, &x_apple_wm_error_base)) { fprintf (stderr, "can't open AppleWM server extension\n"); - exit (1); + return 1; } + have_xfixes = XFixesQueryExtension(x_dpy, &x_xfixes_event_base, &x_xfixes_error_base); + XAppleWMSelectInput (x_dpy, AppleWMActivationNotifyMask | AppleWMPasteboardNotifyMask); @@ -58,6 +63,8 @@ void x_init (void) { x_input_run (); [pool release]; + + return 0; } id x_selection_object (void) { diff --git a/hw/xquartz/pbproxy/pbproxy.h b/hw/xquartz/pbproxy/pbproxy.h index bfeb8685a..5d4652bf1 100644 --- a/hw/xquartz/pbproxy/pbproxy.h +++ b/hw/xquartz/pbproxy/pbproxy.h @@ -21,10 +21,12 @@ extern void x_set_is_active (BOOL state); extern BOOL x_get_is_active (void); extern id x_selection_object (void); extern Time x_current_timestamp (void); -extern void x_init (void); +extern int x_init (void); extern Display *x_dpy; extern int x_apple_wm_event_base, x_apple_wm_error_base; +extern int x_xfixes_event_base, x_xfixes_error_base; +extern BOOL have_xfixes; /* from x-input.m */ extern void x_input_register (void); diff --git a/hw/xquartz/pbproxy/x-input.m b/hw/xquartz/pbproxy/x-input.m index 1b2475cb9..b34c39aca 100644 --- a/hw/xquartz/pbproxy/x-input.m +++ b/hw/xquartz/pbproxy/x-input.m @@ -87,9 +87,11 @@ void x_input_run (void) { break; default: - if (e.type - x_apple_wm_event_base >= 0 - && e.type - x_apple_wm_event_base < AppleWMNumberEvents) { - x_event_apple_wm_notify ((XAppleWMNotifyEvent *) &e); + if(e.type >= x_apple_wm_event_base && + e.type < x_apple_wm_event_base + AppleWMNumberEvents) { + x_event_apple_wm_notify((XAppleWMNotifyEvent *) &e); + } else if(e.type == x_xfixes_event_base + XFixesSelectionNotify) { + [x_selection_object() xfixes_selection_notify:(XFixesSelectionNotifyEvent *)&e]; } break; } diff --git a/hw/xquartz/pbproxy/x-selection.h b/hw/xquartz/pbproxy/x-selection.h index c93b6761b..0be8d8130 100644 --- a/hw/xquartz/pbproxy/x-selection.h +++ b/hw/xquartz/pbproxy/x-selection.h @@ -33,6 +33,7 @@ #include "pbproxy.h" #include <AppKit/NSPasteboard.h> +#include <X11/extensions/xfixes.h> /* This stores image data or text. */ struct propdata { @@ -95,6 +96,7 @@ struct atom_list { - (void) request_event:(XSelectionRequestEvent *)e; - (void) notify_event:(XSelectionEvent *)e; - (void) property_event:(XPropertyEvent *)e; +- (void) xfixes_selection_notify:(XFixesSelectionNotifyEvent *)e; - (void) handle_selection:(Atom)selection type:(Atom)type propdata:(struct propdata *)pdata; - (void) claim_clipboard; - (BOOL) set_clipboard_manager_status:(BOOL)value; diff --git a/hw/xquartz/pbproxy/x-selection.m b/hw/xquartz/pbproxy/x-selection.m index 6a1a9fdf2..888c9e878 100644 --- a/hw/xquartz/pbproxy/x-selection.m +++ b/hw/xquartz/pbproxy/x-selection.m @@ -36,6 +36,7 @@ #include <X11/Xutil.h> #import <AppKit/NSBitmapImageRep.h> +#include <X11/extensions/xfixes.h> /* * The basic design of the pbproxy code is as follows. @@ -56,12 +57,10 @@ /* * TODO: - * 1. handle primary_on_grab - * 2. handle MULTIPLE - I need to study the ICCCM further. - * 3. Handle PICT images properly. - * 4. Handle NSPasteboard updates immediately, not on active/inactive + * 1. handle MULTIPLE - I need to study the ICCCM further. + * 2. Handle PICT images properly. + * 3. Handle NSPasteboard updates immediately, not on active/inactive * - Open xterm, run 'cat readme.txt | pbcopy' - * 5. Detect if CLIPBOARD_MANAGER atom belongs to a dead client rather than just None */ static struct { @@ -357,7 +356,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato XSetSelectionOwner (x_dpy, atoms->clipboard, _selection_window, timestamp); - XSetSelectionOwner (x_dpy, XA_PRIMARY, + XSetSelectionOwner (x_dpy, atoms->primary, _selection_window, timestamp); } #endif @@ -421,8 +420,8 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato if(owner == _selection_window) return TRUE; - if(None != _selection_window) { - fprintf (stderr, "A clipboard manager is already running. pbproxy will not sync clipboard to pasteboard.\n"); + if(owner != None) { + fprintf (stderr, "A clipboard manager is already running on window 0x%x. pbproxy will not sync clipboard to pasteboard.\n", (int)owner); return FALSE; } @@ -1008,6 +1007,24 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato } } +- (void) xfixes_selection_notify:(XFixesSelectionNotifyEvent *)e { + if(!pbproxy_prefs.active) + return; + + switch(e->subtype) { + case XFixesSetSelectionOwnerNotify: + if(e->selection == atoms->primary && pbproxy_prefs.primary_on_grab) + [self x_copy:e->timestamp]; + break; + + case XFixesSelectionWindowDestroyNotify: + case XFixesSelectionClientCloseNotify: + default: + fprintf(stderr, "Unhandled XFixesSelectionNotifyEvent: subtype=%d\n", e->subtype); + break; + } +} + - (void) handle_targets: (Atom)selection propdata:(struct propdata *)pdata { /* Find a type we can handle and prefer from the list of ATOMs. */ @@ -1023,7 +1040,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato * This isn't required by the ICCCM, but some apps apparently * don't respond to TARGETS properly. */ - preferred = XA_STRING; + preferred = atoms->string; } DB ("requesting %s\n", XGetAtomName (x_dpy, preferred)); @@ -1260,6 +1277,11 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato pbproxy_prefs.clipboard_to_pasteboard = prefs_get_bool(CFSTR("sync_clibpoard_to_pasteboard"), pbproxy_prefs.clipboard_to_pasteboard); pbproxy_prefs.pasteboard_to_primary = prefs_get_bool(CFSTR("sync_pasteboard_to_primary"), pbproxy_prefs.pasteboard_to_primary); pbproxy_prefs.pasteboard_to_clipboard = prefs_get_bool(CFSTR("sync_pasteboard_to_clipboard"), pbproxy_prefs.pasteboard_to_clipboard); + + if(pbproxy_prefs.active && pbproxy_prefs.primary_on_grab && !have_xfixes) { + fprintf(stderr, "Disabling sync_primary_on_select functionality due to missing XFixes extension.\n"); + pbproxy_prefs.primary_on_grab = NO; + } /* Claim or release the CLIPBOARD_MANAGER atom */ if(![self set_clipboard_manager_status:(pbproxy_prefs.active && pbproxy_prefs.clipboard_to_pasteboard)]) @@ -1335,6 +1357,10 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato pending_copy = 0; pending_clipboard = 0; + if(have_xfixes) + XFixesSelectSelectionInput(x_dpy, _selection_window, atoms->primary, + XFixesSetSelectionOwnerNotifyMask); + [self reload_preferences]; return self; |