hclip.c
authorteodor <teodor>
Thu, 28 Dec 2006 14:32:10 +0000 (14:32 +0000)
committerteodor <teodor>
Thu, 28 Dec 2006 14:32:10 +0000 (14:32 +0000)
hclip.c

diff --git a/hclip.c b/hclip.c
index f5c2b99..7554316 100644 (file)
--- a/hclip.c
+++ b/hclip.c
@@ -92,6 +92,7 @@ typedef struct ClipboardDescr {
        GtkStyle                        *style_locked;          /* style for locked item */
 } ClipboardDescr;
 
+
 /*
  * Assign menu's popup to hotkey
  */
@@ -331,6 +332,7 @@ addMenuItem( ClipboardDescr *descr, gchar *buffer )
        if ( (i=existMenuItem(descr, buffer)) >= 0 )
        {
                moveMenuItemFirst( descr, i );
+               g_free( buffer ); /* free buffer if is not needed */
                return;
        }
 
@@ -507,53 +509,93 @@ initHistMenu( ClipboardDescr *descr )
 /*
  * Receive text content of buffer
  *
- * it seems to me, that there is some problem in gtk+
- * when targets MULTIPLE and TARGETS are set (at least with russian 
- * characters in OO ). So just ignore such cases...
+ * Some applications ( OpenOffice at least ) sets owner at
+ * begining of selection instead of after finishing selection. And
+ * gtk_clipboard_wait_for_text() will fix state of X-Selection. So,
+ * GTK clipboard will see only small part of real selection. For preventing
+ * from this misbehaviour we will not try to get contents of selection -
+ * just skip it as image etc. However, it's possible to delay
+ * request of contents - but I don't know way to count correct
+ * timeout or to get finalizing event (may be yet :) )
  */
 static void
 receiveTarget(GtkClipboard *clipboard, GdkAtom *atoms, gint n_atoms, gpointer data)
 {
-       gint i;
-       gboolean has_text = FALSE,
-                        has_multiple = FALSE,
-                        has_targets = FALSE;
+       gint                    i;
+       gchar                   *text;
+       static struct   /* just an unnamed struct */ 
+       {               
+               gchar   *target_prefix;
+               gint     target_prefix_len;
+       }                               ignore_targets[] = {
+                                               { "application/x-openoffice", -1 },
+                                               { NULL, 0 } /* mark end */
+                                       },
+                                       *ptr ;
+
 
        /*
-        * checks all avaliable targets
+        * If there is not text in targets then return
         */
-       for(i=0;i<n_atoms;i++)
+       if ( gtk_targets_include_text( atoms, n_atoms ) == FALSE )
+               return;
+
+       /*
+        * init ignore target if it's needed 
+        */
+       if ( ignore_targets->target_prefix_len < 0 )
        {
-               if ( atoms[i] == gdk_atom_intern_static_string("UTF8_STRING") ||
-                         atoms[i] == gdk_atom_intern_static_string("COMPOUND_TEXT") )
+               ptr = ignore_targets;
+
+               while( ptr->target_prefix )
                {
-                       has_text = TRUE;
+                       ptr->target_prefix_len = strlen( ptr->target_prefix );
+                       ptr++;
                }
-               else if ( atoms[i] == gdk_atom_intern_static_string("MULTIPLE") )
-               {
-                       has_multiple = TRUE;
-               } 
-               else if ( atoms[i] == gdk_atom_intern_static_string("TARGETS") )
-               {
-                       has_targets = TRUE;
-               } 
        }
 
        /*
-        * check for workaround
+        * checks all avaliable targets for presence of ignorable
+        * targets ( which come from "wrong" applications )
         */
-       if ( has_text == TRUE && ( has_multiple==FALSE || has_targets == TRUE ) )
+       for(i=0;i<n_atoms;i++)
        {
-               gchar *text = gtk_clipboard_wait_for_text(clipboard);
+               gchar   *target_name = gdk_atom_name( atoms[i] );
+
+               if (!target_name)
+                       continue;
 
-               if (text)
-                       addMenuItem( (ClipboardDescr*)data, text );
+               ptr = ignore_targets;
+
+               while( ptr->target_prefix )
+               {
+                       if ( strncmp( target_name, ptr->target_prefix, ptr->target_prefix_len ) == 0 )
+                       {
+                               /*
+                                * It's found a ignorable targets - we will not accept text to
+                                * prevent unexpected and surprised behaviour of X-selection
+                                */
+                                g_free(target_name);
+                                return;
+                       }
+
+                       g_free(target_name);
+                       ptr++;
+               }
        }
+
+       /*
+        * Ok - selection has text, selection is not owned to strange application -
+        * request contents
+        */
+       text = gtk_clipboard_wait_for_text(clipboard);
+       if (text) /* be carefull - world has a lot of unexpected events :) */ 
+               addMenuItem( (ClipboardDescr*)data, text );
 }
 
 /*
- * Clipboard change signal handler. It requests new content of
- * clipboard in a text form
+ * Clipboard change signal handler. It requests avaliable 
+ * targets to make checks about contents of selection
  */
 static void
 ClipboardChange(GtkClipboard *clipboard, GdkEvent *event, gpointer data)