perf hists browser: Fix handling of TAB/UNTAB for multiple events
authorArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 13 Oct 2011 15:22:28 +0000 (12:22 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 13 Oct 2011 15:22:28 +0000 (12:22 -0300)
When using multiple events the 'top' and 'report' tools will first
present the user with a menu to choose the event to browse.

After that the user can either press <- to go back to the menu and
choose another event or instead press TAB to go the next event without
having to go back to the menu or shift-TAB (UNTAB) to go the previous
event, useful to quickly visually see if multiple events are correlated.

The handling of each hists browser return was broken by the ed7e566,
that combined both switches, the first that was for choosing the event
and the second that was for checking if switching to the next event
without passing thru the events menu.

Repeat with me: Don't be clever like that.

Fix it by moving the switch to right after the call to the hists
browser, making abundantly clear that the two switches are unrelated.

This also fixes a compiler warning about the 'pos' variable being
possibly used unitialized.

Reported-by: Ingo Molnar <mingo@elte.hu>
[ committer note: the line above is for the compiler warning ]
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-ujxkbvj9vy8w6xe2op5m51tb@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/ui/browsers/hists.c

index 662b721..4a3a7c9 100644 (file)
@@ -1074,30 +1074,44 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu,
                        if (!menu->selection)
                                continue;
                        pos = menu->selection;
-                       perf_evlist__set_selected(evlist, pos);
 browse_hists:
+                       perf_evlist__set_selected(evlist, pos);
+                       /*
+                        * Give the calling tool a chance to populate the non
+                        * default evsel resorted hists tree.
+                        */
+                       if (timer)
+                               timer(arg);
                        ev_name = event_name(pos);
                        key = perf_evsel__hists_browse(pos, nr_events, help,
                                                       ev_name, true, timer,
                                                       arg, delay_secs);
                        ui_browser__show_title(&menu->b, title);
-                       break;
+                       switch (key) {
+                       case NEWT_KEY_TAB:
+                               if (pos->node.next == &evlist->entries)
+                                       pos = list_entry(evlist->entries.next, struct perf_evsel, node);
+                               else
+                                       pos = list_entry(pos->node.next, struct perf_evsel, node);
+                               goto browse_hists;
+                       case NEWT_KEY_UNTAB:
+                               if (pos->node.prev == &evlist->entries)
+                                       pos = list_entry(evlist->entries.prev, struct perf_evsel, node);
+                               else
+                                       pos = list_entry(pos->node.prev, struct perf_evsel, node);
+                               goto browse_hists;
+                       case NEWT_KEY_ESCAPE:
+                               if (!ui__dialog_yesno("Do you really want to exit?"))
+                                       continue;
+                               /* Fall thru */
+                       case 'q':
+                       case CTRL('c'):
+                               goto out;
+                       default:
+                               continue;
+                       }
                case NEWT_KEY_LEFT:
                        continue;
-               case NEWT_KEY_TAB:
-                       if (pos->node.next == &evlist->entries)
-                               pos = list_entry(evlist->entries.next, struct perf_evsel, node);
-                       else
-                               pos = list_entry(pos->node.next, struct perf_evsel, node);
-                       perf_evlist__set_selected(evlist, pos);
-                       goto browse_hists;
-               case NEWT_KEY_UNTAB:
-                       if (pos->node.prev == &evlist->entries)
-                               pos = list_entry(evlist->entries.prev, struct perf_evsel, node);
-                       else
-                               pos = list_entry(pos->node.prev, struct perf_evsel, node);
-                       perf_evlist__set_selected(evlist, pos);
-                       goto browse_hists;
                case NEWT_KEY_ESCAPE:
                        if (!ui__dialog_yesno("Do you really want to exit?"))
                                continue;
@@ -1106,7 +1120,7 @@ browse_hists:
                case CTRL('c'):
                        goto out;
                default:
-                       break;
+                       continue;
                }
        }