Q: custom GtkOverlay's child (GtkRevealer) position

Hi everyone,

that’s about positioning GtkRevealer child with in GtkOvelay at some custom position:
is there any function in user space that indicate necessity for gtk_widget_measure() calls?
(something like gtk_widget_get_resize_needed())

example of code with that:

g_signal_connect(overlay, "get-child-position", G_CALLBACK(nt_legend_pos_cb), nt);
...

static gboolean nt_legend_pos_cb(GtkOverlay *overlay, GtkWidget *widget, GdkRectangle *r, t_notifier *nt) {
  if (GTK_IS_OVERLAY(overlay) && r && nt) {
    if (GTK_IS_WIDGET(widget) /* && gtk_widget_get_resize_needed(widget) */) {
      int unused;
      gtk_widget_measure(widget, GTK_ORIENTATION_HORIZONTAL, -1, &unused, NULL, NULL, NULL);
      gtk_widget_measure(widget, GTK_ORIENTATION_VERTICAL,   -1, &unused, NULL, NULL, NULL);
    }
    r->x = nt->x; r->y = nt->y;
    return true;
  }
  return false;
}

What are you trying to achieve? :slight_smile:

  • callback from g_signal_connect(, “get-child-position”,) is used to put a child widget in custom x,y position

  • gtk_widget_measure() is used to get rid of “Allocating size to GtkRevealer 0x… without calling gtk_widget_measure(). How does the code know the size to allocate?” messages

Hmm… looks like the underlying issue is that the callback nt_legend_pos_cb is supposed to return a valid allocation, but here I don’t see any width or height returned, so that’s probably why gtk complains the measurement was missing (the resulting allocation is basically null).

I don’t think you need to call gtk_widget_measure(), instead try to do something like

r->width  = gtk_widget_get_width (widget);
r->height = gtk_widget_get_height (widget);

(of course, adapt to what you want the widget to look like)

Width and height are not supposed to be changed by shifting x,y position, and it’s already valid at the time of callback call. The only reason of gtk_widget_measure call there is to get rid of annoying “Allocating size to … without calling gtk_widget_measure()” message.

For example with

static gboolean nt_legend_pos_cb(GtkOverlay *overlay, GtkWidget *widget, GdkRectangle *r, t_notifier *nt) {
  if (GTK_IS_OVERLAY(overlay) && r && nt) {
    if (GTK_IS_WIDGET(widget) /* && gtk_widget_get_resize_needed(widget) */) {
//      int unused;
//      gtk_widget_measure(widget, GTK_ORIENTATION_HORIZONTAL, -1, &unused, NULL, NULL, NULL);
//      gtk_widget_measure(widget, GTK_ORIENTATION_VERTICAL,   -1, &unused, NULL, NULL, NULL);
      g_print(">>> at %d,%d size of %dx%d\n", r->x, r->y, r->width, r->height);
      gtk_widget_get_width(widget);
      gtk_widget_get_height(widget);
    }
    r->x = nt->x; r->y = nt->y;
    return true;
  }
  return false;
}

there's still that message offering to call `gtk_widget_measure()` beforehand
>>> at 0,0 size of 1022x613

(pingpath:202688): Gtk-WARNING **: 02:31:08.811: Allocating size to GtkRevealer 0x55bb96152df0 without calling gtk_widget_measure(). How does the code know the size to allocate?
>>> at 0,0 size of 1022x613
>>> at 0,0 size of 1022x613
>>> at 0,0 size of 1022x613
>>> at 0,0 size of 1022x613
>>> at 0,0 size of 1022x613
>>> at 0,0 size of 1022x613
>>> at 0,0 size of 1022x613
>>> at 0,0 size of 1022x613

With uncommented back `gtk_widget_measure()` call, that warning message is gone. And it's the reason why `gtk_widget_get_resize_needed` is asked for.

Is there any other ways (except of "get-child-position" callback) to put a revealing widget at x,y without changing its size?

p.s.
will that be okay to use gtk_widget_get_width()/_height() instead of gtk_widget_get_resize_needed()
as an indicator to call gtk_widget_measure() there?

static gboolean nt_legend_pos_cb(GtkOverlay *overlay, GtkWidget *widget, GdkRectangle *r, t_notifier *nt) {
  if (GTK_IS_OVERLAY(overlay) && r && nt) {
    if (GTK_IS_WIDGET(widget)) {
      if (!gtk_widget_get_width(widget))
        gtk_widget_measure(widget, GTK_ORIENTATION_HORIZONTAL, -1, NULL, NULL, NULL, NULL);
      if (!gtk_widget_get_height(widget))
        gtk_widget_measure(widget, GTK_ORIENTATION_VERTICAL,   -1, NULL, NULL, NULL, NULL);
    }
    r->x = nt->x; r->y = nt->y;
    return true;
  }
  return false;
}

OK, I see, now I’m confused too…

Let’s see if someone else has a better idea about what’s going on here.