After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 141937 - TreeViewColumn context menus are hard to implement
TreeViewColumn context menus are hard to implement
Status: RESOLVED OBSOLETE
Product: gtk+
Classification: Platform
Component: Widget: GtkTreeView
unspecified
Other Linux
: Normal normal
: Small API
Assigned To: gtktreeview-bugs
gtktreeview-bugs
: 148558 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2004-05-05 17:38 UTC by Murray Cumming
Modified: 2018-02-10 03:43 UTC
See Also:
GNOME target: ---
GNOME version: 2.7/2.8



Description Murray Cumming 2004-05-05 17:38:36 UTC
As far as I can tell, the only way to implement a right-click context menu on a
TreeView column header is to use a custom widget with the GtkTreeViewColumn. But
that means you have to reimplement far too much stuff.
Comment 1 Matthias Clasen 2004-12-18 06:02:04 UTC
Connecting to the button_press_event signal on column->button should work fine.
Or you can just use the clicked signal on the column.
Comment 2 Murray Cumming 2004-12-18 12:43:19 UTC
OK. Thanks. If that's public API, then maybe it should be documented.

I don't think the clicked signal will be any good for a right-click context menu.
Comment 3 Ken Harris 2004-12-23 22:15:05 UTC
(See also bug 148558, which looks like a dupe.)

Hmm...  I see problems with this.  ('button-press-event', not 'clicked', because
that's not how popup menus are used.)

1. The field column->button isn't wrapped by the bindings (like PyGTK and
java-gnome) and isn't documented in the C API, so you have to do a dance to get
it (unless you're in C/C++ and don't mind using parts of the API only documented
in the header files).  In languages other than C/C++, you have to call
column.set_widget() with your own label, and then call get_parent() on that
repeatedly until you come to a gtk.Button object.

(Note that get_widget() gives you column->child, which is different, and
connecting signals to it doesn't work.  You need column->button.  And
get_widget() returns NULL if you haven't set a custom widget, so it doesn't help
the bindings: they need to set a custom widget to get at this field.)

Since it's a private field that's required for a fairly common task, it would
seem to make sense to give it a normal accessor (get_button()?) -- this would
also encourage bindings to wrap it.  And that starts to make the API more
complex, which is why simply having a 'popup-menu' event would be nice. 
(Instead of exposing more of the internals, and providing more documentation on
how to assemble them to make a popup menu, just provide popup menus.)

2. It has bugs that make it unusable.  If your columns have
set_reorderable(True), then after your popup menu goes away, when you mouse over
the column header, it starts moving (as if you were dragging it, even though you
aren't pressing the mouse button).  So you have to choose between being able to
drag your columns, and being able to right-click them.  (Or you could connect to
button-release-event, but that's as bad as 'clicked'.)

It's also not obvious to me that this can easily be solved with the current API.
 The mouse event seems to get to the treeview immediately, and there's no way
(AFAICT) for a column or popup to stop that.  (Add another function to the
treeview to tell it a popup has been shown?  You could, I guess, but again,
that's more API complexity.  All you really want is to just tell the column to
handle right-clicks, give you popup events, and deal with all the details for you.)

3. It has unnecessary and undocumented restrictions.  You have to
set_clickable(True), even if you don't otherwise want them to be clickable. 
(Though this is probably relatively easy to fix.)


If this is the "official" Gtk+ way to do it, I'll file bugs for these issues
(accessor/bindings/documentation, bugs/restrictions), but it seems to me that a
better solution would be to make the interface simpler and easier on programmers
by adding another signal to GtkTreeViewColumn.  Even if the current scheme was
documented and worked 100% today, it's still a lot more work to add a popup to a
column header than anywhere else.

(Another way to look at it: You can probably implement its 'clicked' signal by
using column->button, too, but we don't make programmers do that.)

If this is still the plan, just give the word, and I'll file a bunch of bugs to
fix it so it's actually usable.  Or maybe I'm completely missing something, and
it is easy to do and get working; if that's the case, hit me over the head and
let me know that, too.  Thanks.  :-)
Comment 4 Murray Cumming 2004-12-24 22:39:09 UTC
Reopening.
Comment 5 Billy Biggs 2004-12-26 13:57:31 UTC
The behaviour mentioned in point 2 is because when you pop up a context menu,
you perform an X pointer grab.  This means that the column header never gets the
button release event it is expecting.  One fix would be to send a fake button
release event to the column header, or to not propagate the button press event
after you handle it.  You often need to perform this dance when popping up a
menu on button press, or anything else that requires an X pointer grab.
Comment 6 Ken Harris 2004-12-27 02:11:14 UTC
Billy: Yeah, that makes sense, but (a) Gtk+ doesn't require this sort of dance
for other popup menus (in the content area of a TreeView, for example), and (b)
I've never gotten it to work, or seen any program which has.

Have you gotten this to work?  I'd love to see how.  I tried:
- emitting button-release-event on tree, column, widget, button
- stopping (by_name) button-press-event on tree, column, widget, button
- returning TRUE from my button-press-event handler with ("stop other handlers
from being invoked for the event") -- I always did this, anyway
I couldn't get any of these to work, but it's quite possible I'm missing something.

I also asked on #pygtk, and only got some workarounds that changed the behavior
(show menu on mouse-up, disallow column dragging, etc.).

I can attach a fairly short PyGTK program that demonstrates the problem, if you
(or anybody else) want to play with it but don't have such a program handy.

(If I learn how to do this, I'll gladly write up some documentation for the
manual.  :-)
Comment 7 Jonathan Blandford 2005-01-04 22:14:36 UTC
I've fixed it so that it no longer reorders on buttons other than 1.  We should
probably add a gtk_tree_view_column_get_button() API call, as context menus on
the button seems legitimate.
Comment 8 Tomas Junnonen 2005-04-02 13:22:23 UTC
Found this bug after wrestling with the exact same issues as comment #3. A
gtk_tree_view_column_get_button call just dumps the guts onto the developer in
my opinion, and doesn't correct a fundamental inconsistency. 

The GtkTreeView is a container, however GtkTreeViewColumn is not a widget you
pack inside it but is instead derived from GtkObject. However if you think about
it, unlike any of its peer GtkObject classes, the column shows all the signs of
being a widget. It's therefore disappointing to notice you can't do a whole lot
with it as you're limited to the small number of functions in the
GtkTreeViewColumn API that wraps the user visible widget. So while you can
control simple things like spacing and visibility, if you want to change the
sensitivity, focus behavior, add a tooltip etc. you're out of luck.

If it was made a widget it would be a lot simpler from a developer's point of
view. For example, you could simply bind a handler to the "popup-menu" signal,
which is *not* the same as merely popping up a menu on a right-click event from
an accessibility point of view. You could also remove all of the API that simply
maps properties to the internal button.
Comment 9 Kristian Rietveld 2005-07-13 12:04:28 UTC
*** Bug 148558 has been marked as a duplicate of this bug. ***
Comment 10 Steven Sheehy 2006-03-03 21:08:59 UTC
I have also wrestled with this problem. I ended up connecting to the column->button with the button-release-event as Matthias Clasen suggested. You can see my code at:

http://cvs.berlios.de/cgi-bin/viewcvs.cgi/linuxdcpp/linuxdcpp/linux/treeview.cc

In my opinion, using column->button is not the proper solution. There should be a way to connect to the entire header of a GtkTreeView. Besides the fact that it breaks API, there are number of reasons why connecting to column->button should be avoided. If you just connect to the column headers, then when the gap between the column headers is clicked, the event for the body of the treeview is triggered instead of the desired header-triggered event. Also, I use an extra padding column so that there's a gap between the last column and the end of the treeview. If this area is clicked, the desired event isn't triggered either.

This is why it is my belief that a function like gtk_tree_view_get_header() should be implemented so that events can be registered with it to occur when any part of it is clicked. Unfortunately, I couldn't even find a way to get the header by breaking API like I did with column->button, so I don't know how easy this is. It seems to be saved in a GdkWindow, whereas I need it in a form I can connect events to.

Obviously, connecting to individual column headers may be appropriate for some cases, so maybe there should be both a way to get the entire header and individual column buttons.
Comment 11 Fabio Durán Verdugo 2010-12-13 02:29:01 UTC
Thanks for taking the time to report this bug.

However, you are using a version that is too old and not supported anymore.
GNOME developers are no longer working on that version, so unfortunately there
will not be any bug fixes for the version that you use.

By upgrading to a newer version of GNOME you could receive bug fixes and new
functionality. You may need to upgrade your Linux distribution to obtain a
newer version of GNOME.

Please feel free to reopen this bug if the problem still occurs with a newer
version of GNOME.
Comment 12 Murray Cumming 2010-12-13 10:58:20 UTC
I believe that this problem still exists.
Comment 13 Matthias Clasen 2018-02-10 03:43:17 UTC
We're moving to gitlab! As part of this move, we are closing bugs that haven't seen activity in more than 5 years. If this issue is still imporant to you and
still relevant with GTK+ 3.22 or master, please consider creating a gitlab issue
for it.