GNOME Bugzilla – Bug 340203
[patch] Support "prelight state" in menu bars and notebooks. (with patch files)
Last modified: 2015-03-08 20:51:31 UTC
Original gtk+ doesn't support "prelight state" of menu bar items and notebook tabs, but these features exists on native Win32 GUI. Since Windows 98, items in menu bars are highlighted when hovered by mouse cursor, and tabs have this feature, too. So, for Win32 port, I suggest this feature be added to gtk+ win32 to make gtk+ apps looks much more native. Here are my patches, enable prelight state of menu bar items and tabs. Screenshots can be found here: http://pcman.sayya.org/gtk_win32/ Please take a look at menu bars and tabs of notebook. Some explaination on the patch files: gtknotebook.patch: Add prelight state of tabs for Windows. When a tab is hovered by mouse cursor, its will be highlighted. This is required by Windows xp theme. gtkmenubar.patch: Add prelight state of menubar items for Windows. When an item in menu bar is hovered by mouse cursor, its will be highlighted on Windows. (This feature exists since Windows 98)
Created attachment 64572 [details] [review] Patch for GtkMenuBar
Created attachment 64573 [details] [review] Patch for GtkNotebook
Created attachment 66696 [details] [review] Patch for GtkMenuBar adding a style property called "prelight-item" Instead of conditional compilation for different platforms, I add a new boolean style property called "prelight-item" for GtkMenuBar. When this property is TRUE, the item hovered by mouse cursor will be in prelight state. Currently this behavior exists in all Windows applications and some of KDE/Qt themes. Adding this support is not only beneficial for Wimp theme engine, but all other gtk+ themes also get improved, especially those ported from KDE themes. Adding this behavior make unified GUI look & feel for GTK+ & Qt themes possible.
Created attachment 66697 [details] [review] Patch for GtkNotebook adding a style property called "prelight-tab" Instead of conditional compilation for different platforms, I add a new boolean style property called "prelight-tab" for GtkNotebook. When this property is TRUE, the tab hovered by mouse cursor will be in prelight state. Currently this behavior exists in all Windows applications and some of KDE/Qt themes. Adding this support is not only beneficial for Wimp theme engine, but all other gtk+ themes also get improved, especially those ported from KDE themes. Adding this behavior make unified GUI look & feel for GTK+ & Qt themes possible.
*** Bug 347684 has been marked as a duplicate of this bug. ***
There are two bugs about this already that contain some more information. The notebook one is bug 153966 and the menuitem one is 97878.
Why should these be style options? Surely they should be the default behaviour.
Hi!, wanted to add some comments on the prelight-tab patch: + { + /* Support prelight state of tabs */ + children = notebook->children; + while (children) + { + page = children->data; + if (GTK_WIDGET_VISIBLE (page->child) && + page->tab_label && GTK_WIDGET_MAPPED (page->tab_label) && + (x >= page->allocation.x) && + (y >= page->allocation.y) && + (x <= (page->allocation.x + page->allocation.width)) && + (y <= (page->allocation.y + page->allocation.height))) + { + prelight_page = page; + break; + } + children = children->next; + } There's already a get_tab_at_pos() function @ -2021,7 +2084,10 @@ notebook->in_child = arrow; gtk_notebook_redraw_arrows (notebook); } + else + { + } return TRUE; } I guess you forgot to remove that :) +++ gtk+-2.8.17/gtk/gtknotebook.h 2006-06-03 06:35:02.000000000 +0800 @@ -85,6 +85,8 @@ guint has_before_next : 1; guint has_after_previous : 1; guint has_after_next : 1; + + GtkNotebookPage *prelight_page; }; There's already a private struct, I don't think adding fields to the public struct should be good Besides that, I tend to think like Thomas, I think that prelight for tabs is not only for prettiness, but it's useful, it should be enabled by default. What I'm seeing as a showstopper with this patch is that prelight doesn't work fine with tab widgets with their own GdkWindows, sadly this is pretty common (gedit, ephy, gnome-terminal, ...). I've been thinking in the possible solutions and the best way would be to modify how GdkWindows are layered/related and don't unhighlight the tab if ::leave-notify-event happens towards an inferior window. Currently the window where the event happens and the window of the tab widget hierarchies are unrelated, so we can't do that safely. Will keep thinking on the issue.
Thanks to the comment from Carlos Garnacho Parro. I also agree this should be the default behavior, but the problem is, will this impair backward compatibility? Will adding this unconditionally break any theme engine previously written? How can people turn off this effect if they don't like it? Although I personally like this to be the defult, I think the best solution should be adding a new style property. The problem caused by tabs owning their own GdkWindow do exist, as Carlos Garnacho Parro said. However, there is no real solution to this. Please let me explain the idea. Even you can change the perlight state correctly by doing some hack on child GdkWindows, the authors of theme engines cannot utilize this. What a theme engine can do, is drawing on the GtkNotebook widget. But now the tab of the notebook is covered by another child window hanlding it's own drawing in its own GdkWindow, and what the theme engine draws on the underlying tab cannot be showed. For example, if you add a GtkEventBox as the tab of a notebook page, no matter what the theme engine draws on that tab, a gray box will always be shown in the tab instead of the original background. So the tab will always be gray regardless of the prelight state of that tab and what the theme engine draws. This is unfortunately the most frequently seen cases. AFAIK, GIMP uses event boxes in notebook tabs. So, since this is really inevitable, we don't need to take it into consideration. Otherwise, the underlying mechanism GTK+ used to handle notebooks should be completely re-designed. Though my approach don't solve all problems, at least it won't cause any new problems.
Carlos for short :), the problem you mention can be solved with gtk_event_box_set_visible_window(). Maybe I was a bit vague, the problem I referred to is about "leave-event-notify" event being emitted when the pointer enters inside the tab widget, unprelighting the tab. This is an undesirable effect, and given that lots of apps wrap tab widgets in event boxes, quite visible...
This is not going to land in 2.12 at this point.
*** Bug 547651 has been marked as a duplicate of this bug. ***
Prelighting for notebook tabs is supported now
I believe this is all possible now.
Does this bug apply to GTK 3 too? Is this bug fixed only in GTK 2?