diff -up fltk-1.3.x-r9671/configh.in.clipboard-xfixes fltk-1.3.x-r9671/configh.in --- fltk-1.3.x-r9671/configh.in.clipboard-xfixes 2011-10-04 04:21:47.000000000 -0500 +++ fltk-1.3.x-r9671/configh.in 2013-08-21 15:35:08.441966345 -0500 @@ -108,6 +108,14 @@ #define USE_XDBE HAVE_XDBE /* + * HAVE_XFIXES: + * + * Do we have the X fixes extension? + */ + +#define HAVE_XFIXES 0 + +/* * __APPLE_QUARTZ__: * * All Apple implementations are now based on Quartz and Cocoa, diff -up fltk-1.3.x-r9671/configure.in.clipboard-xfixes fltk-1.3.x-r9671/configure.in --- fltk-1.3.x-r9671/configure.in.clipboard-xfixes 2012-04-21 21:45:09.000000000 -0500 +++ fltk-1.3.x-r9671/configure.in 2013-08-21 15:35:08.442966335 -0500 @@ -997,6 +997,16 @@ case $uname_GUI in LIBS="-lXext $LIBS") fi + dnl Check for the Xfixes extension unless disabled... + AC_ARG_ENABLE(xfixes, [ --enable-xfixes turn on Xfixes support [default=yes]]) + + if test x$enable_xfixes != xno; then + AC_CHECK_HEADER(X11/extensions/Xfixes.h, AC_DEFINE(HAVE_XFIXES),, + [#include ]) + AC_CHECK_LIB(Xfixes, XFixesQueryExtension, + LIBS="-lXfixes $LIBS") + fi + dnl Check for overlay visuals... AC_PATH_PROG(XPROP, xprop) AC_CACHE_CHECK(for X overlay visuals, ac_cv_have_overlay, diff -up fltk-1.3.x-r9671/src/Fl_x.cxx.clipboard-xfixes fltk-1.3.x-r9671/src/Fl_x.cxx --- fltk-1.3.x-r9671/src/Fl_x.cxx.clipboard-xfixes 2013-08-21 15:35:08.437966386 -0500 +++ fltk-1.3.x-r9671/src/Fl_x.cxx 2013-08-21 15:35:08.442966335 -0500 @@ -53,6 +53,12 @@ static XRRUpdateConfiguration_type XRRUp static int randrEventBase; // base of RandR-defined events #endif +# ifdef HAVE_XFIXES +# include +static int xfixes_event_base = 0; +static bool have_xfixes = false; +# endif + static Fl_Xlib_Graphics_Driver fl_xlib_driver; static Fl_Display_Device fl_xlib_display(&fl_xlib_driver); Fl_Display_Device *Fl_Display_Device::_display = &fl_xlib_display;// the platform display @@ -197,6 +203,14 @@ static void do_queued_events() { Fl::handle(FL_MOVE, fl_xmousewin); } #endif + +#ifdef HAVE_XFIXES + int error_base; + if (XFixesQueryExtension(fl_display, &xfixes_event_base, &error_base)) + have_xfixes = true; + else + have_xfixes = false; +#endif } // these pointers are set by the Fl::lock() function: @@ -917,6 +931,10 @@ extern void fl_trigger_clipboard_notify( static void poll_clipboard_owner(void) { Window xid; + // No polling needed with Xfixes + if (have_xfixes) + return; + // No one is interested, so no point polling if (fl_clipboard_notify_empty()) return; @@ -955,10 +973,12 @@ static void handle_clipboard_timestamp(i timestamp = clipboard ? &clipboard_timestamp : &primary_timestamp; - // Initial scan, just store the value - if (*timestamp == (Time)-1) { - *timestamp = time; - return; + if (!have_xfixes) { + // Initial scan, just store the value + if (*timestamp == (Time)-1) { + *timestamp = time; + return; + } } // Same selection @@ -978,10 +998,12 @@ void fl_clipboard_notify_change() { primary_timestamp = -1; clipboard_timestamp = -1; } else { - poll_clipboard_owner(); + if (!have_xfixes) { + poll_clipboard_owner(); - if (!Fl::has_timeout(clipboard_timeout)) - Fl::add_timeout(0.5, clipboard_timeout); + if (!Fl::has_timeout(clipboard_timeout)) + Fl::add_timeout(0.5, clipboard_timeout); + } } } @@ -1780,6 +1802,25 @@ int fl_handle(const XEvent& thisevent) } } +#ifdef HAVE_XFIXES + switch (xevent.type - xfixes_event_base) { + case XFixesSelectionNotify: { + // Someone feeding us bogus events? + if (!have_xfixes) + return true; + + XFixesSelectionNotifyEvent *selection_notify = (XFixesSelectionNotifyEvent *)&xevent; + + if ((selection_notify->selection == XA_PRIMARY) && !fl_i_own_selection[0]) + handle_clipboard_timestamp(0, selection_notify->selection_timestamp); + else if ((selection_notify->selection == CLIPBOARD) && !fl_i_own_selection[1]) + handle_clipboard_timestamp(1, selection_notify->selection_timestamp); + + return true; + } + } +#endif + return Fl::handle(event, window); } @@ -2100,6 +2141,16 @@ void Fl_X::make_xid(Fl_Window* win, XVis XChangeProperty(fl_display, xp->xid, net_wm_type, XA_ATOM, 32, PropModeReplace, (unsigned char*)&net_wm_type_kind, 1); } +#ifdef HAVE_XFIXES + // register for clipboard change notifications + if (have_xfixes && !win->parent()) { + XFixesSelectSelectionInput(fl_display, xp->xid, XA_PRIMARY, + XFixesSetSelectionOwnerNotifyMask); + XFixesSelectSelectionInput(fl_display, xp->xid, CLIPBOARD, + XFixesSetSelectionOwnerNotifyMask); + } +#endif + XMapWindow(fl_display, xp->xid); if (showit) { win->set_visible();