From 58ae8aabeabb5b32e01b701c3ec9e48870fa5f78 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 4 Apr 2021 21:39:54 +0200 Subject: SystemMonitor: Show process-specific details in a separate window When double-clicking a process in the process list, we now open the detailed information in a new window instead of showing it in a view below the process list. This declutters the main UI, and allows you to view details for multiple processes at the same time. This is just a first cut, there are many refinements possible here. :^) --- Userland/Applications/SystemMonitor/main.cpp | 73 ++++++++++++++++++---------- 1 file changed, 47 insertions(+), 26 deletions(-) (limited to 'Userland') diff --git a/Userland/Applications/SystemMonitor/main.cpp b/Userland/Applications/SystemMonitor/main.cpp index d0a3655c06..cb4f99791a 100644 --- a/Userland/Applications/SystemMonitor/main.cpp +++ b/Userland/Applications/SystemMonitor/main.cpp @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -65,6 +66,7 @@ #include #include +static NonnullRefPtr build_process_window(pid_t); static NonnullRefPtr build_file_systems_tab(); static NonnullRefPtr build_pci_devices_tab(); static NonnullRefPtr build_devices_tab(); @@ -333,38 +335,25 @@ int main(int argc, char** argv) window->set_menubar(move(menubar)); - auto& process_tab_unused_widget = process_container_splitter->add("No process selected"); - process_tab_unused_widget.set_visible(true); + HashMap> process_windows; - auto& process_tab_widget = process_container_splitter->add(); - process_tab_widget.set_tab_position(GUI::TabWidget::TabPosition::Bottom); - process_tab_widget.set_visible(false); - - auto& memory_map_widget = process_tab_widget.add_tab("Memory map"); - auto& open_files_widget = process_tab_widget.add_tab("Open files"); - auto& unveiled_paths_widget = process_tab_widget.add_tab("Unveiled paths"); - auto& stack_widget = process_tab_widget.add_tab("Stack"); - - process_table_view.on_selection = [&](auto&) { + process_table_view.on_activation = [&](auto&) { auto pid = selected_id(ProcessModel::Column::PID); - auto tid = selected_id(ProcessModel::Column::TID); - if (!can_access_pid(pid)) { - process_tab_widget.set_visible(false); - process_tab_unused_widget.set_text("Process cannot be accessed"); - process_tab_unused_widget.set_visible(true); - return; - } - process_tab_widget.set_visible(true); - process_tab_unused_widget.set_visible(false); - open_files_widget.set_pid(pid); - stack_widget.set_ids(pid, tid); - memory_map_widget.set_pid(pid); - unveiled_paths_widget.set_pid(pid); + RefPtr process_window; + if (!process_windows.contains(pid)) { + process_window = build_process_window(pid); + process_window->on_close_request = [pid, &process_windows] { + process_windows.remove(pid); + return GUI::Window::CloseRequestDecision::Close; + }; + process_windows.set(pid, *process_window); + } + process_window->show(); + process_window->move_to_front(); }; window->show(); - window->set_icon(app_icon.bitmap_for_size(16)); if (args_tab_view == "processes") @@ -405,6 +394,38 @@ public: } }; +NonnullRefPtr build_process_window(pid_t pid) +{ + auto window = GUI::Window::construct(); + window->resize(480, 360); + window->set_title(String::formatted("PID {} - SystemMonitor", pid)); + + auto& main_widget = window->set_main_widget(); + main_widget.set_fill_with_background_color(true); + main_widget.set_layout(); + + auto& widget_stack = main_widget.add(); + auto& unavailable_process_widget = widget_stack.add(String::formatted("Unable to access PID {}", pid)); + + auto& process_tab_widget = widget_stack.add(); + auto& memory_map_widget = process_tab_widget.add_tab("Memory map"); + auto& open_files_widget = process_tab_widget.add_tab("Open files"); + auto& unveiled_paths_widget = process_tab_widget.add_tab("Unveiled paths"); + auto& thread_stack_widget = process_tab_widget.add_tab("Stack"); + + open_files_widget.set_pid(pid); + thread_stack_widget.set_ids(pid, pid); + memory_map_widget.set_pid(pid); + unveiled_paths_widget.set_pid(pid); + + if (can_access_pid(pid)) + widget_stack.set_active_widget(&process_tab_widget); + else + widget_stack.set_active_widget(&unavailable_process_widget); + + return window; +} + NonnullRefPtr build_file_systems_tab() { auto fs_widget = GUI::LazyWidget::construct(); -- cgit v1.2.3