GNOME Bugzilla – Bug 438318
Deprecate and remove hide_all()
Last modified: 2011-02-04 16:12:22 UTC
I have this on PyGTK 2.10.2 on Windows XP. It works correctly on RHEL4 linux and PyGTK 2.6.3, though I haven't isolated whether this is an OS or PyGTK-version related difference. I have a gtk.Notebook, the current page is at the start as it should be. I do hide_all() on it at some point. When I do show_all() again the current page is suddenly the last one. This is a bit unexpected, to say the least. Sample code follows: the expected behaviour is that the current page should not change here (i.e. it should show the first page) #!/usr/bin/env python import gtk class NotebookTest: def createTopWindow(self): win = gtk.Window(gtk.WINDOW_TOPLEVEL) win.connect("delete_event", self.quit) notebook = self.getNotebook() win.add(notebook) win.show_all() # Hiding the notebook and then showing it again causes the current page to flip to the end! notebook.hide_all() notebook.show_all() return win def getNotebook(self): notebook = gtk.Notebook() notebook.append_page(self.getTextView("First text"), gtk.Label("first tab")) notebook.append_page(self.getTextView("Second text"), gtk.Label("second tab")) return notebook def getTextView(self, text): textview = gtk.TextView() textbuffer = textview.get_buffer() textbuffer.set_text(text) return textview def run(self): topWindow = self.createTopWindow() gtk.main() def quit(self, *args): gtk.main_quit() if __name__ == "__main__": program = NotebookTest() program.run()
Dou you really need to use notebook.hide_all() instead of notebook.hide()? The problem of the hide_all function is, that it recursively hides all child widgets, too. And from the GtkNotebook docs: "Note that due to historical reasons, GtkNotebook refuses to switch to a page unless the child widget is visible. Therefore, it is recommended to show child widgets before adding them to a notebook."
Well, I don't know about "really need" but it's convenient. If I just do hide() on the notebook it's difficult to tell if a given child (or child-of-child) widget is hidden without separately storing this information myself. The note from the GtkNotebook docs hasn't made it into the PyGTK docs for gtk.Notebook, maybe it should be there. In any case, I don't think it's the cause. In my real code I do show the child widgets before adding them to the notebook. I think I can probably produce a version of the test code that does so reasonably easily if you want me to. In this case, the Notebook has clearly changed page - in an undesirable way - while the child widgets are hidden.
Hiding the child widget of the current selected page in a notebook will change the current page to the next (or previous) page. If a child widget is hidden the page is not visible hence it cannot be the current page. notebook.hide_all() hides the child widgets of all pages therefore the current page changes.
I guessed something like that was happening. But it seems wrong to me. "hide_all" is an internal operation to GTK, so GTK knows that it isn't worth changing the current page, or correct to do so. To be consistent with the behaviour of hidden children it seems to me that all changes of page could profitably be disabled when the notebook is hidden. In any case, I'd like to be able to hide widgets when their use is not appropriate and re-show them when it becomes appropriate again, without their state being mangled in the meantime. And as I said, this doesn't occur when I test on Linux with PyGTK 2.6 so something has changed somewhere. To me, the Linux / 2.6 behaviour is far more sensible.
We should deprecate hide_all(), it's useless and a trap for programmers, as this bug shows.
Created attachment 88218 [details] [review] Don't change current page while the notebook is hidden.
Not sure if we want to change the behaviour of hide_all, or just do as owen recommended and deprecate it, or at least add a strong warning to the docs.
It looks like deprecating gtk_widget_hide_all() is the sensible option? May I do that in svn trunk?
Patch has a compile error on the call to gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (next), -1); but otherwise applies and works as advertised. Even if hide_all() is deprecated, wouldn't it still be a good idea to fix this problem since it is a regression from 2.6?
(In reply to comment #8) > It looks like deprecating gtk_widget_hide_all() is the sensible option? May I > do that in svn trunk? Sounds like a good idea to me. I don't recall when I wanted to use that function for the last time, and it looks like a hack to me anyway, unless you are damn sure what you are doing.
I guess we can do this in GTK+ 2.22 and remove it from GTK+ 3.0
Created attachment 162123 [details] [review] Deprecate gtk_widget_hide_all
Created attachment 162137 [details] [review] Deprecate gtk_widget_hide_all and remove internal uses
Created attachment 170313 [details] [review] Deprecate gtk_widget_hide_all and remove internal uses.v2 Updated patch against current gtk-2-22
Review of attachment 170313 [details] [review]: ::: gtk/gtkwidget.c @@ +3357,2 @@ void +_gtk_widget_hide_all (GtkWidget *widget) Why is this extra function introduced here ? We can keep using gtk_widget_hide_all just fine, regardless whether it is deprecated. ::: gtk/gtkwidget.h @@ +642,2 @@ void (* hide_all) (GtkWidget *widget); +#endif I don't think this is going to work. If you hide parts of the class struct from the compiler, it will get the struct size wrong, and bad things will happen.
I've removed it altogether in master
Created attachment 172747 [details] [review] Deprecate in 2-22
Review of attachment 172747 [details] [review]: ::: gtk/gtkcontainer.c @@ +2620,3 @@ gtk_widget_hide (widget); gtk_container_foreach (GTK_CONTAINER (widget), + (GtkCallback) gtk_widget_hide, Hmm, doesn't this break the semantics of hide_all, though ? I would have expected to just do an #if !defined(GTK_DISABLE_DEPRECATED) || defined (GTK_COMPILATION) in the header, and leave the implementations alone.
Also, this should be deprecated in the 2-24 branch, not 2-22
Okay, just pushed deprecation to gtk-2-24
Yeah, that was a typo. I meant gtk-2-24. :)