From 7b478eced25af1d3143d232e503723aaf86dfe8a Mon Sep 17 00:00:00 2001
From: Siri Hansen <siri@erlang.org>
Date: Fri, 29 Apr 2016 10:02:37 +0200
Subject: [observer] Make right click menu act on the "expected pid"

If multiple processes were selcted, "Process Info" and "Kill Process"
menu choices would pick the first pid in the selection list, i.e. the
last selected process. This is now changed so the process under the
mouse pointer is used instead.
---
 lib/observer/src/observer_pro_wx.erl | 55 ++++++++++++++++++++++++------------
 1 file changed, 37 insertions(+), 18 deletions(-)

diff --git a/lib/observer/src/observer_pro_wx.erl b/lib/observer/src/observer_pro_wx.erl
index ca0ddab657..6296f89e7f 100644
--- a/lib/observer/src/observer_pro_wx.erl
+++ b/lib/observer/src/observer_pro_wx.erl
@@ -83,6 +83,7 @@
 		timer,
 		procinfo_menu_pids=[],
 		sel={[], []},
+		right_clicked_pid,
 		holder}).
 
 start_link(Notebook, Parent) ->
@@ -303,13 +304,14 @@ handle_event(#wx{id=?ID_REFRESH_INTERVAL},
     Timer = observer_lib:interval_dialog(Panel, Timer0, 1, 5*60),
     {noreply, State#state{timer=Timer}};
 
-handle_event(#wx{id=?ID_KILL}, #state{sel={[_|Ids], [ToKill|Pids]}}=State) ->
-    exit(ToKill, kill),
-    {noreply, State#state{sel={Ids,Pids}}};
+handle_event(#wx{id=?ID_KILL}, #state{right_clicked_pid=Pid, sel=Sel0}=State) ->
+    exit(Pid, kill),
+    Sel = rm_selected(Pid,Sel0),
+    {noreply, State#state{sel=Sel}};
 
 
 handle_event(#wx{id=?ID_PROC},
-	     #state{panel=Panel, sel={_, [Pid|_]},procinfo_menu_pids=Opened}=State) ->
+	     #state{panel=Panel, right_clicked_pid=Pid, procinfo_menu_pids=Opened}=State) ->
     Opened2 = start_procinfo(Pid, Panel, Opened),
     {noreply, State#state{procinfo_menu_pids=Opened2}};
 
@@ -347,20 +349,26 @@ handle_event(#wx{event=#wxList{type=command_list_item_right_click,
 			       itemIndex=Row}},
 	     #state{panel=Panel, holder=Holder}=State) ->
 
-    case call(Holder, {get_row, self(), Row, pid}) of
-	{error, undefined} ->
-	    undefined;
-	{ok, _} ->
-	    Menu = wxMenu:new(),
-	    wxMenu:append(Menu, ?ID_PROC, "Process info"),
-	    wxMenu:append(Menu, ?ID_TRACE_PIDS, "Trace processes", [{help, ?TRACE_PIDS_STR}]),
-	    wxMenu:append(Menu, ?ID_TRACE_NAMES, "Trace named processes (all nodes)",
-			  [{help, ?TRACE_NAMES_STR}]),
-	    wxMenu:append(Menu, ?ID_KILL, "Kill Process"),
-	    wxWindow:popupMenu(Panel, Menu),
-	    wxMenu:destroy(Menu)
-    end,
-    {noreply, State};
+    Pid =
+	case call(Holder, {get_row, self(), Row, pid}) of
+	    {error, undefined} ->
+		undefined;
+	    {ok, P} ->
+		Menu = wxMenu:new(),
+		wxMenu:append(Menu, ?ID_PROC,
+			      "Process info for " ++ pid_to_list(P)),
+		wxMenu:append(Menu, ?ID_TRACE_PIDS,
+			      "Trace selected processes",
+			      [{help, ?TRACE_PIDS_STR}]),
+		wxMenu:append(Menu, ?ID_TRACE_NAMES,
+			      "Trace selected processes by name (all nodes)",
+			      [{help, ?TRACE_NAMES_STR}]),
+		wxMenu:append(Menu, ?ID_KILL, "Kill process " ++ pid_to_list(P)),
+		wxWindow:popupMenu(Panel, Menu),
+		wxMenu:destroy(Menu),
+		P
+	end,
+    {noreply, State#state{right_clicked_pid=Pid}};
 
 handle_event(#wx{event=#wxList{type=command_list_item_focused,
 			       itemIndex=Row}},
@@ -432,6 +440,17 @@ set_focus([Old|_], [New|_], Grid) ->
     wxListCtrl:setItemState(Grid, Old, 0, ?wxLIST_STATE_FOCUSED),
     wxListCtrl:setItemState(Grid, New, 16#FFFF, ?wxLIST_STATE_FOCUSED).
 
+rm_selected(Pid, {Ids, Pids}) ->
+    rm_selected(Pid, Ids, Pids, [], []).
+
+rm_selected(Pid, [_Id|Ids], [Pid|Pids], AccIds, AccPids) ->
+    {lists:reverse(AccIds)++Ids,lists:reverse(AccPids)++Pids};
+rm_selected(Pid, [Id|Ids], [OtherPid|Pids], AccIds, AccPids) ->
+    rm_selected(Pid, Ids, Pids, [Id|AccIds], [OtherPid|AccPids]);
+rm_selected(_, [], [], AccIds, AccPids) ->
+    {lists:reverse(AccIds), lists:reverse(AccPids)}.
+
+
 %%%%%%%%%%%%%%%%%%%%%%%%%%%TABLE HOLDER%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 init_table_holder(Parent, Attrs) ->
-- 
cgit v1.2.3