I have a program which opens a window under a GtkEntry
(sscce code here). When the program runs, this is its window:
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:
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:
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?