#include static gboolean clicked_icon (GtkTreeView *tv, gint x, gint y, GtkTreePath **path) { GtkTreeViewColumn *col; gint cell_x, cell_y; gint cell_pos, cell_width; GList *cells, *l; gint depth; gint level_indentation; gint expander_size; gint indent; if (gtk_tree_view_get_path_at_pos (tv, x, y, path, &col, &cell_x, &cell_y)) { cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (col)); #if 1 /* ugly workaround to fix the problem: * manually calculate the indent for the row */ depth = gtk_tree_path_get_depth (*path); level_indentation = gtk_tree_view_get_level_indentation (tv); expander_size = 16; /* Hardcoded in gtktreeview.c */ expander_size += 4; indent = (depth - 1) * level_indentation + depth * expander_size; #else indent = 0; #endif for (l = cells; l; l = l->next) { gtk_tree_view_column_cell_get_position (col, l->data, &cell_pos, &cell_width); if (cell_pos + indent <= cell_x && cell_x <= cell_pos + indent + cell_width) { g_print ("clicked in %s\n", g_type_name_from_instance (l->data)); if (GTK_IS_CELL_RENDERER_PIXBUF (l->data)) { g_list_free (cells); return TRUE; } } } g_list_free (cells); } return FALSE; } static void release_event (GtkGestureClick *gesture, guint n_press, gdouble x, gdouble y, GtkTreeView *tv) { GtkTreePath *path; gint tx, ty; gtk_tree_view_convert_widget_to_tree_coords (tv, x, y, &tx, &ty); if (clicked_icon (tv, tx, ty, &path)) { GtkTreeModel *model; GtkTreeIter iter; gchar *text; model = gtk_tree_view_get_model (tv); gtk_tree_model_get_iter (model, &iter, path); gtk_tree_model_get (model, &iter, 0, &text, -1); g_print ("text was: %s\n", text); g_free (text); gtk_tree_path_free (path); } } int main (int argc, char *argv[]) { GtkWidget *window; GtkWidget *sw; GtkWidget *tv; GtkTreeViewColumn *col; GtkCellRenderer *cell; GtkTreeStore *store; GtkTreeIter iter; GtkGesture *gesture; gtk_init (); window = gtk_window_new (); sw = gtk_scrolled_window_new (NULL, NULL); gtk_window_set_child (GTK_WINDOW (window), sw); tv = gtk_tree_view_new (); gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), tv); col = gtk_tree_view_column_new (); cell = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (col, cell, TRUE); gtk_tree_view_column_add_attribute (col, cell, "text", 0); cell = gtk_cell_renderer_toggle_new (); gtk_tree_view_column_pack_start (col, cell, FALSE); gtk_tree_view_column_add_attribute (col, cell, "active", 1); cell = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (col, cell, TRUE); gtk_tree_view_column_add_attribute (col, cell, "text", 0); cell = gtk_cell_renderer_pixbuf_new (); gtk_tree_view_column_pack_start (col, cell, FALSE); gtk_tree_view_column_add_attribute (col, cell, "icon-name", 2); cell = gtk_cell_renderer_toggle_new (); gtk_tree_view_column_pack_start (col, cell, FALSE); gtk_tree_view_column_add_attribute (col, cell, "active", 1); gtk_tree_view_append_column (GTK_TREE_VIEW (tv), col); store = gtk_tree_store_new (3, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_STRING); gtk_tree_store_insert_with_values (store, NULL, NULL, 0, 0, "One row", 1, FALSE, 2, "document-open", -1); gtk_tree_store_insert_with_values (store, &iter, NULL, 1, 0, "Two row", 1, FALSE, 2, "dialog-warning", -1); gtk_tree_store_insert_with_values (store, NULL, &iter, 0, 0, "Three row", 1, FALSE, 2, "dialog-error", -1); gtk_tree_view_set_model (GTK_TREE_VIEW (tv), GTK_TREE_MODEL (store)); gesture = gtk_gesture_click_new (); gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture), GTK_PHASE_CAPTURE); g_signal_connect (gesture, "released", G_CALLBACK (release_event), tv); gtk_widget_add_controller (tv, GTK_EVENT_CONTROLLER (gesture)); gtk_widget_show (window); while (TRUE) g_main_context_iteration (NULL, TRUE); return 0; }