Re: GtkLayout's "set_scroll_adjustments", test.c



On 2 May 2000, Havoc Pennington wrote:

> 
> "Matias Mutchinick" <matias@seul.org> writes:
> > Hi,
> > Ok, here is a small example which returns this error message
> > 
> > ----
> > Gtk-WARNING **: gtk_signal_connect_by_type(): could not find signal id (64)
> > in the `GtkLayout' class ancestry
> > ----
> > 
> 
> The problem is that gtk_layout_class_init() doesn't call
> gtk_object_class_add_signals ().

uh oh! thanks for spotting.
the obvious bug is that no widgets which introduce set_scroll_adjustments
do an actuall gtk_object_class_add_signals() for this signal id, this
affects gtkclist.c, gtklayout.c, gtktext.c and gtkviewport.c.
thus the signal ids don't get registered in the GtkObjectClass's
  guint *signals;
  guint nsignals;
array. the signal system on the other hand does know that this signal
exists for the respecting class, but some ancient code relicts are still
in place that check GtkObjectClass's guint *signals, nsignals; and
produce this warning:

static guint gtk_signal_connect_by_type (...)
{
  [...]
  /* Search through the signals for this object and make
   *  sure the one we are adding is valid. We need to perform
   *  the lookup on the objects parents as well. If it isn't
   *  valid then issue a warning and return.
   * As of now (1998-05-27) this lookup shouldn't be neccessarry
   *  anymore since gtk_signal_lookup() has been reworked to only
   *  return correct signal ids per class-branch.
   */
  found_it = FALSE;
  class = object->klass;
  while (class)
    {
      GtkType parent;
      guint *object_signals;
      guint nsignals;
      guint i;

      object_signals = class->signals;
      nsignals = class->nsignals;

      for (i = 0; i < nsignals; i++)
        if (object_signals[i] == signal_id)
          {
            found_it = TRUE;
            break;
          }

      parent = gtk_type_parent (class->type);
      if (parent)
        class = gtk_type_class (parent);
      else
        class = NULL;
    }
  if (!found_it)
    {
      g_warning ("gtk_signal_connect_by_type(): could not find signal id (%u) in the `%s' class ancestry",
                 signal_id,
                 gtk_type_name (object->klass->type));
  [...]
}

for Gtk+ 1.4 i want to get rid of the GtkObjectClass
  guint *signals;
  guint nsignals;
array, since we just duplicate knowledge of the signal system
there and are better off with making gtk_object_class_add_signals()
a noop and provide an accessor function to return the signal ids per
class (which is why i'm CC:-ing gtk-devel).

for 1.2.7, i don't have a good work-around at hand (see below), we
will fix this in 1.2.8 though, if we make such a release.

> This could be deliberate (maybe
> set_scroll_adjustments isn't a public signal), or it could be a bug,
> Owen or Tim would have to say.

no, its not deliberate. it doesn't make sense to duplicate part of the
signal system internals in the object classes and then leave it
inconsistent.

> 
> Havoc
> 


ok, i said i don't have a _good_ workaround for 1.2.7, here's an ugly
one. matias, just cut and paste the gtk_fixup_set_scroll_adjustments()
function into your gtk program and call it after gtk_init () (it'll
work with 1.2.8+ as well):

#include <gtk/gtk.h>

static void
gtk_fixup_set_scroll_adjustments (void)
{
#if !GTK_CHECK_VERSION (1, 3, 1)
  GtkType (*type_funcs[]) (void) = {
    gtk_clist_get_type,
    gtk_layout_get_type,
    gtk_text_get_type,
    gtk_viewport_get_type,
  };
  guint n;
  
  for (n = 0; n < sizeof (type_funcs) / sizeof (type_funcs[0]); n++)
    {
      GtkType type = type_funcs[n] ();
      GtkObjectClass *class = gtk_type_class (type);
      guint sid = gtk_signal_lookup ("set_scroll_adjustments", type);
      guint i;
      
      for (i = 0; i < class->nsignals; i++)
        if (class->signals[i] == sid)
          break;
      if (i >= class->nsignals)
        gtk_object_class_add_signals (class, &sid, 1);
    }
#endif /* !GTK_CHECK_VERSION (1, 3, 1) */
}

int
main (int argc, char* argv[])
{
  GtkWidget *text, *scwin;
  
  gtk_init (&argc, &argv);
  gtk_fixup_set_scroll_adjustments ();
  
  text = gtk_widget_new (GTK_TYPE_TEXT,
                         "visible", TRUE,
                         "editable", TRUE,
                         "object_signal::set_scroll_adjustments",
                         g_print, "scroll_adjustments connection worked\n",
                         NULL);
  scwin = gtk_widget_new (GTK_TYPE_SCROLLED_WINDOW,
                          "visible", TRUE,
                          NULL);
  gtk_container_add (GTK_CONTAINER (scwin), text);                          
  gtk_widget_new (GTK_TYPE_WINDOW,
                  "child", scwin,
                  "visible", TRUE,
                  "signal::destroy", gtk_main_quit, NULL,
                  NULL);
  gtk_main ();
  
  return 0;
}

---
ciaoTJ



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]