Patch to fix 522 for linux


Subject: Patch to fix 522 for linux
From: Daniel Weber (dweber1@austin.rr.com)
Date: Wed Feb 16 2000 - 12:57:47 CST


This patch should completely fix 522, with one minor cosmetic issue
where the text in the combo boxes can still be selected. The focus
should not be allowed on the combo->entry at all now. Patch was created
from an cvs version updated at 11:40am CST...

This patch:
1) Attaches and detaches "change" and "key-press" events only when the
combo->button is pressed. This prevents spurious calls to "changed" and
prevents any key-press events from coming from anywhere else
2) Uses a somewhat kludgy way of removing the focus after a change has
been made. I call gtk_widget_set_sensitive(w, FALSE) followed by
gtk_widget_set_sensitive(w, TRUE) to force focus off the combo box.
3) A handler was added for the focus in event to force focus off on
mouse clicks. Note this handler is attached using
gtk_signal_connect_after so that the widget has the focus before I get
rid of it (otherwise it won't get rid of it).

Kind of a big patch for my first one.... This bug really irritated me
though - I hoped I squashed it good :-)

? abi/abi
? abi/522_bug.abw
? abi/debug
? abi/deleted.cpp
? abi/src/Linux_2.2.12-20_i386_OBJ
? abi/src/Linux_2.2.12-20_i386_DBG
? expat/xmltok/nametab.h
? wv/config.log
? wv/config.h
? wv/config.cache
? wv/libtool
? wv/config.status
? wv/Makefile
? wv/expat/Makefile
? wv/expat/xmlparse/Makefile
? wv/expat/xmltok/Makefile
? wv/iconv/Makefile
? wv/magick/Makefile
? wv/oledecod/Makefile
Index: abi/src/af/ev/unix/ev_UnixToolbar.cpp
===================================================================
RCS file: /cvsroot/abi/src/af/ev/unix/ev_UnixToolbar.cpp,v
retrieving revision 1.47
diff -u -r1.47 ev_UnixToolbar.cpp
--- abi/src/af/ev/unix/ev_UnixToolbar.cpp 1999/09/20 21:06:23 1.47
+++ abi/src/af/ev/unix/ev_UnixToolbar.cpp 2000/02/16 17:48:02
@@ -42,6 +42,16 @@
 /*****************************************************************/
 #define COMBO_BUF_LEN 256

+enum wd_defined_handlers
+{
+ WD_CHANGED,
+ WD_KEY_PRESS,
+ WD_MAX_HANDLER
+};
+
+#define WD_NUM_HANDLERS WD_MAX_HANDLER
+
+
 class _wd // a private little class to help
 { // us remember all the widgets that
 public: // we create...
@@ -52,6 +62,13 @@
   m_widget = widget;
   m_blockSignal = false;
   m_comboEntryBuffer[0] = 0;
+ for (unsigned k=0; k < WD_NUM_HANDLERS; k++)
+ {
+ m_sigs[k] = 0;
+ m_sig_void_arguments[k] = NULL;
+ m_sig_widget[k] = NULL;
+ m_connected[k] = 0;
+ }
  };

  ~_wd(void)
@@ -72,11 +89,15 @@

  // TODO: should this move out of wd? It's convenient here; maybe I'll
make
  // a microclass for combo boxes.
+
+ // This can be called via callback from the ->entry
+ // or from the hide event of the ->list
  static void s_combo_changed(GtkWidget * widget, gpointer user_data)
  {
+
   _wd * wd = (_wd *) user_data;
   UT_ASSERT(wd);
-
+
   // only act if the widget has been shown and embedded in the toolbar
   if (wd->m_widget)
   {
@@ -87,9 +108,10 @@
     if (!wd->m_blockSignal)
     {
      gchar * buffer = gtk_entry_get_text(GTK_ENTRY(widget));
- UT_uint32 length = strlen(buffer);
- UT_ASSERT(length > 0);
- UT_ASSERT(length < 1024);
+ // UT_uint32 length = strlen(buffer);
+ // UT_ASSERT(length > 0);
+ UT_ASSERT(strlen(buffer) > 0);
+ UT_ASSERT(strlen(buffer) < 1024);
      strcpy(wd->m_comboEntryBuffer, buffer);
     }
    }
@@ -104,9 +126,22 @@
     {
      UT_UCSChar * text = (UT_UCSChar *) wd->m_comboEntryBuffer;
      UT_ASSERT(text);
+
+ // kludgy way to ditch the focus ...
+ gtk_widget_set_sensitive(GTK_WIDGET(wd->m_widget), FALSE);
+ gtk_widget_set_sensitive(GTK_WIDGET(wd->m_widget), TRUE);

+ wd->s_unregister_signals();
+
      wd->m_pUnixToolbar->toolbarEvent(wd, text, size);
     }
+ else
+ {
+ // Need to kill off the focus...
+ gtk_widget_set_sensitive(GTK_WIDGET(wd->m_widget), FALSE);
+ gtk_widget_set_sensitive(GTK_WIDGET(wd->m_widget), TRUE);
+
+ }
    }
   }

@@ -116,20 +151,98 @@
  static void s_combo_hide(GtkWidget * widget, gpointer user_data)
  {
   _wd * wd = (_wd *) user_data;
- UT_ASSERT(wd);
+ UT_ASSERT(user_data);

   // manually force an update
   s_combo_changed(widget, user_data);
  }

+
  EV_UnixToolbar * m_pUnixToolbar;
  XAP_Toolbar_Id m_id;
- GtkWidget * m_widget;
+ GtkWidget * m_widget; //top-level widget
  bool m_blockSignal;

  char m_comboEntryBuffer[1024];
-};
+
+ // Store all signals as they are connected so we can release them when
focus shifts
+
+ guint m_sigs[WD_NUM_HANDLERS];
+ gboolean m_connected[WD_NUM_HANDLERS];
+ void * m_sig_void_arguments[WD_NUM_HANDLERS];
+ GtkWidget * m_sig_widget[WD_NUM_HANDLERS];
+
+ static gboolean s_combo_focus_in(GtkWidget *widget, GdkEventFocus
*event, gpointer user_data)
+ {
+ // Drop the focus...
+ _wd * wd = (_wd * ) user_data;
+ UT_ASSERT(wd);
+
+ // HACK to send focus off
+ gtk_widget_set_sensitive(GTK_WIDGET(GTK_COMBO(wd->m_widget)->entry),
FALSE);
+ gtk_widget_set_sensitive(GTK_WIDGET(GTK_COMBO(wd->m_widget)->entry),
TRUE);
+
+ return(TRUE);
+ }
+
+ static void s_callback_bpress(GtkEditable *editable, gpointer
user_data)
+ //Only connect signals when button press to prevent spurious calls
+ {
+ _wd * wd = (_wd *) user_data;
+ UT_ASSERT(wd);
+ wd->s_re_register_signals();
+
+ }
+
+ void s_register_signal(GtkWidget *widget, enum wd_defined_handlers
req_handler, void * user_data)
+ // Save registered signals so we can remove them later, as needed
+ {
+
+ // Save necessary info to connect and reconnect later
+ m_sig_void_arguments[req_handler] = user_data;
+ m_sig_widget[req_handler] = widget;
+ m_connected[req_handler] = TRUE;
+
+ //Connect the handlers
+
+ switch (req_handler)
+ {
+ case WD_CHANGED:
+ m_sigs[WD_CHANGED] = gtk_signal_connect(GTK_OBJECT(widget),
+ "changed",
+ GTK_SIGNAL_FUNC(_wd::s_combo_changed),
+ user_data);
+ break;
+ case WD_KEY_PRESS:
+ break;
+ default:
+ break;
+ }
+ }

+ void s_unregister_signals(void)
+ {
+ for (unsigned k = 0; k < WD_NUM_HANDLERS; k++)
+ if (m_sigs[k] != 0)
+ {
+ gtk_signal_disconnect(GTK_OBJECT(m_sig_widget[k]), m_sigs[k]);
+ m_sigs[k] = 0;
+ }
+ }
+
+ void s_re_register_signals(void)
+ {
+ for (unsigned k = 0; k < WD_NUM_HANDLERS; k++)
+ // if (supposed to be connected) && (not currently connected)
+ if ( (m_connected[k]) && (m_sigs[k] == 0))
+ {
+ s_register_signal(m_sig_widget[k], (enum wd_defined_handlers) k,
+ m_sig_void_arguments[k]);
+ }
+
+ }
+}; // End _wd class definition
+
 /*****************************************************************/

 EV_UnixToolbar::EV_UnixToolbar(XAP_UnixApp * pUnixApp, XAP_UnixFrame *
pUnixFrame,
@@ -330,7 +443,7 @@
    {
     EV_Toolbar_Control * pControl = pFactory->getControl(this, id);
     UT_ASSERT(pControl);
-
+
     // default, shouldn't be used for well-defined controls
     int iWidth = 100;

@@ -341,7 +454,9 @@

     GtkWidget * comboBox = gtk_combo_new();
     UT_ASSERT(comboBox);
+ wd->m_widget = comboBox;

+
     // Combo boxes flash on 8-bit displays unless you set its colormap
     // to agree with what we're using elsewhere (gdk_rgb's version)
     gtk_widget_set_colormap(comboBox, gdk_rgb_get_cmap());
@@ -357,6 +472,7 @@
     UT_ASSERT(button);
     GtkWidget * popwin = GTK_WIDGET(GTK_COMBO(comboBox)->popwin);
     UT_ASSERT(popwin);
+
 // we don't use this
 #if 0
     gtk_signal_connect(GTK_OBJECT(popwin),
@@ -369,27 +485,32 @@
            GTK_SIGNAL_FUNC(_wd::s_combo_hide),
            wd);

- // take away the ability to gain focus
-// gtk_signal_connect(GTK_OBJECT(GTK_COMBO(comboBox)->entry),
-// "focus_in_event",
-// GTK_SIGNAL_FUNC(_wd::s_combo_focus_in),
-// wd);
-// gtk_signal_connect(GTK_OBJECT(comboBox),
-// "key_press_event",
-// GTK_SIGNAL_FUNC(_wd::s_combo_key_press),
-// wd);
-// gtk_signal_connect(GTK_OBJECT(GTK_COMBO(comboBox)->entry),
-// "key_press_event",
-// GTK_SIGNAL_FUNC(_wd::s_combo_key_press),
-// wd);
+
+ gtk_signal_connect(GTK_OBJECT(button),
+ "pressed",
+ GTK_SIGNAL_FUNC(_wd::s_callback_bpress),
+ wd);
+
+ //Register focus in so we can ditch it
+ // We need to connect after the default focus handler to ensure we

+ // disconnect properly
+ gtk_signal_connect_after(GTK_OBJECT(GTK_COMBO(comboBox)->entry),
+ "focus_in_event",
+ GTK_SIGNAL_FUNC(_wd::s_combo_focus_in),
+ wd);
+
+
+ // Will need this when we add combo type functionality
+ //wd->s_register_signal(GTK_COMBO(comboBox)->entry, WD_KEY_PRESS,
wd);

     // handle changes in content
     GtkEntry * blah = GTK_ENTRY(GTK_COMBO(comboBox)->entry);
     GtkEditable * yuck = GTK_EDITABLE(blah);
- gtk_signal_connect(GTK_OBJECT(&yuck->widget),
- "changed",
- GTK_SIGNAL_FUNC(_wd::s_combo_changed),
- wd);
+
+ wd->s_register_signal(GTK_WIDGET(&yuck->widget), WD_CHANGED, wd);
+
+ //Disable signals for now, we'll enable them as focus changes
+ wd->s_unregister_signals();

     // populate it
     if (pControl)
@@ -411,6 +532,7 @@
       }
      }
     }
+

     // give a final show
     gtk_widget_show(comboBox);
@@ -420,7 +542,6 @@
             comboBox,
             szToolTip,
             (const char *) NULL);
- wd->m_widget = comboBox;

     // for now, we never repopulate, so can just toss it
     DELETEP(pControl);



This archive was generated by hypermail 2b25 : Wed Feb 16 2000 - 11:56:06 CST