1

I have a program which opens a window under a GtkEntry (sscce code here). When the program runs, this is its window:

The window of the program before clicking in "Open"

When I click in the "Open" button, a non-decorated window will open exactly below the entry, and with its left side aligned to the left side of the entry:

Subwindow opened

It is result of the following callback method of the button, which receives the entry as the callback parameter:

bool on_button_clicked(GtkWidget *button, gpointer data) {
    GtkWidget *entry = data,
            *subwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL),
            *sublabel = gtk_label_new("This is a rather long message\n"
                    "with many lines whose mere purpose is\n"
                    "to test some stuff. It will appear in \n"
                    "the RIGHT PLACE.");
    gtk_container_add(GTK_CONTAINER(subwindow), sublabel);
    gtk_window_set_decorated(GTK_WINDOW(subwindow), FALSE);
    gtk_window_set_modal(GTK_WINDOW(subwindow), TRUE);


    GtkWidget *window = gtk_widget_get_toplevel(entry);
    gtk_window_set_transient_for(
            GTK_WINDOW(subwindow), GTK_WINDOW(window));

    gint dx, dy;
    gtk_window_get_position(GTK_WINDOW(window), &dx, &dy);

    GtkAllocation allocation;
    gtk_widget_get_allocation(entry, &allocation);

    gtk_window_move(
            GTK_WINDOW(subwindow), 
            allocation.x+dx, allocation.y+allocation.height*2+dy);

    gtk_widget_show_all(subwindow);
    return false;
}

I want to do something similar when one starts to edit a cell from the table view, specifically if the cell is in the second column. The undecorated window should appear just below the editing cell, aligned to its left side. So I created a callback to the "editing-started" event, assuming that the editable parameter of the callback is a widget:

static bool on_cell_renderer_text_editing_started(
        GtkCellRenderer *renderer, GtkCellEditable *editable, 
        gchar *path, gpointer data) {
    GtkWidget *subwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL),
            *sublabel = gtk_label_new("This is a rather long message\n"
                    "with many lines whose mere purpose is\n"
                    "to test some stuff. It will appear in\n"
                    "the WRONG PLACE!");
    gtk_container_add(GTK_CONTAINER(subwindow), sublabel);
    gtk_window_set_decorated(GTK_WINDOW(subwindow), FALSE);
    gtk_window_set_modal(GTK_WINDOW(subwindow), TRUE);

    GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(editable));
    gtk_window_set_transient_for(
            GTK_WINDOW(subwindow), GTK_WINDOW(window));

    gint dx, dy;
    gtk_window_get_position(GTK_WINDOW(window), &dx, &dy);

    GtkAllocation allocation;
    gtk_widget_get_allocation(GTK_WIDGET(editable), &allocation);

    gtk_window_move(
            GTK_WINDOW(subwindow),
           allocation.x+dx, allocation.y+allocation.height*2+dy);
    gtk_widget_show_all(subwindow);
    return false;
}

The result is not what I expected. The undecorated window appears in various places, usually at the top left of the screen:

The new window appears a the top left of the window

Also, I get this (pretty instructive but dead-end) warning:

(teste-subwindow-under-entry:32300): Gtk-CRITICAL **: IA__gtk_window_get_position: assertion `GTK_IS_WINDOW (window)' failed

I tried some other approaches (e.g. to get the dimensions of the first window with gdk_window_get_geometry()) but none worked (and I'm not surprised, since they are just blind tries).

So, how could I open the undecorated window under a specific cell renderer?

brandizzi
  • 26,083
  • 8
  • 103
  • 158
  • 2
    +1, Nice images :)... few observations, the warning means that the argument you are passing to `gtk_window_get_position` is not a `GtkWindow`. Try printing out the `window` value (`%p`). Also please check values of `dx`, `dy` and `allocation` members in the callback. Another check, could be to pass the main window to `on_cell_renderer_text_editing_started` as data & use that instead of `gtk_widget_get_window`. Please note that `gtk_widget_get_window` returns a `GdkWindow` which may not be what you are looking for. (By passing window to callback you will *at least* have popup close to window) – another.anon.coward Dec 06 '12 at 14:42

0 Answers0